Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion Dockerfile
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
FROM oven/bun:1.2.13
FROM oven/bun:1.2.21

# Install system dependencies
RUN apt-get update && apt-get install -y \
Expand Down
3 changes: 2 additions & 1 deletion alto/alto-config-l1-local.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,5 +13,6 @@
"log-level": "info",
"public-client-log-level": "error",
"wallet-client-log-level": "error",
"polling-interval": 100
"polling-interval": 100,
"deploy-simulations-contract": false
}
3 changes: 2 additions & 1 deletion alto/alto-config-l1.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,5 +13,6 @@
"log-level": "info",
"public-client-log-level": "error",
"wallet-client-log-level": "error",
"polling-interval": 100
"polling-interval": 100,
"deploy-simulations-contract": false
}
3 changes: 2 additions & 1 deletion alto/alto-config-l2-local.json
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I put this port because this changes on devnet.

Original file line number Diff line number Diff line change
Expand Up @@ -13,5 +13,6 @@
"log-level": "info",
"public-client-log-level": "error",
"wallet-client-log-level": "error",
"polling-interval": 100
"polling-interval": 100,
"deploy-simulations-contract": false
}
3 changes: 2 additions & 1 deletion alto/alto-config-l2.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,5 +13,6 @@
"log-level": "info",
"public-client-log-level": "error",
"wallet-client-log-level": "error",
"polling-interval": 100
"polling-interval": 100,
"deploy-simulations-contract": false
}
Binary file modified bun.lockb
Binary file not shown.
2 changes: 1 addition & 1 deletion contracts/deploy/l2/02_PriceOracle.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,4 +33,4 @@ export default execute(
console.log(` - MockDAI (18 decimals): ${tokenAddresses[1]}`);
},
{ tags: ["PriceOracle", "registry", "l2"], dependencies: ["MockTokens"] },
);
);
2 changes: 1 addition & 1 deletion contracts/lib/ens-contracts
Submodule ens-contracts updated 163 files
4 changes: 4 additions & 0 deletions contracts/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,10 @@
"clean": "forge clean && hardhat clean",
"devnet": "bun ./script/runDevnet.ts",
"aakit": "bun ./script/deployAAkit.ts",
"list-names": "bun ./script/listRegisteredNames.ts",
"watch-names": "bun ./script/watchNameRegistrations.ts",
"cors-proxy": "bun ./script/corsProxy.ts",
"mint-tokens": "bun ./script/mintTokensDirect.ts",
"devnet:clean": "bun run test && bun ./script/runDevnet.ts",
"check:types": "tsc --noEmit"
},
Expand Down
68 changes: 68 additions & 0 deletions contracts/script/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
# Scripts Documentation

Quick reference for the available scripts in this project.

## 📋 List Registered Names

**Script:** `listRegisteredNames.ts`
**Command:** `bun run list-names`
**Purpose:** Lists all registered domain names in a table format
**Shows:** Name, Owner, Duration, Total Cost (USD)
**Use case:** Check which names are registered and who owns them

## 🪙 Mint Mock Tokens

**Script:** `mintTokensDirect.ts`
**Command:** `bun run mint-tokens <WALLET_ADDRESS>`
**Purpose:** Mints 1000 MockUSDC and 1000 MockDAI to a specified address
**Use case:** Give test tokens to addresses for testing name registration

## 👀 Watch Name Registrations

**Script:** `watchNameRegistrations.ts`
**Command:** `bun run watch-names`
**Purpose:** Real-time monitoring of new name registrations
**Shows:** New registrations as they happen with owner and cost details
**Use case:** Monitor registration activity during development/testing

## 🌐 CORS Proxy

**Script:** `corsProxy.ts`
**Command:** `bun run cors-proxy`
**Purpose:** Adds CORS headers to Alto bundler responses for frontend access
**Port:** 4339 (proxies to Alto L2 on 4338)
**Use case:** Enable frontend to communicate with AA infrastructure

## 🚀 Development Environment

**Script:** `runDevnet.ts`
**Command:** `bun run devnet`
**Purpose:** Sets up the complete development environment with AA Kit
**Shows:** Contract addresses, endpoints, test accounts
**Use case:** Initialize the local development setup

## 📝 Usage Examples

```bash
# List all registered names
bun run list-names

# Mint tokens to an address
bun run mint-tokens 0x1234...

# Watch for new registrations
bun run watch-names

# Start CORS proxy
bun run cors-proxy

# Setup devnet
bun run devnet
```

## 🔧 Prerequisites

- Running local blockchain (Anvil/Hardhat)
- AA Kit infrastructure (Alto bundlers, mock paymasters)
- Contracts deployed
- Bun package manager
46 changes: 46 additions & 0 deletions contracts/script/corsProxy.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
import express from 'express';
import { createProxyMiddleware } from 'http-proxy-middleware';
import cors from 'cors';

const app = express();
const PORT = 4339;

app.use(cors({
origin: ['http://localhost:3002'],
methods: ['GET', 'POST', 'PUT', 'DELETE', 'OPTIONS'],
allowedHeaders: ['Content-Type', 'Authorization', 'X-Requested-With'],
credentials: true
}));

app.get('/health', (req, res) => {
res.json({ status: 'ok', service: 'cors-proxy', timestamp: new Date().toISOString() });
});

app.use('/', createProxyMiddleware({
target: 'http://localhost:4338',
changeOrigin: true,
pathRewrite: {
'^/': '/'
},
onProxyRes: (proxyRes, req, res) => {
proxyRes.headers['Access-Control-Allow-Origin'] = '*';
proxyRes.headers['Access-Control-Allow-Methods'] = 'GET, POST, PUT, DELETE, OPTIONS';
proxyRes.headers['Access-Control-Allow-Headers'] = 'Content-Type, Authorization, X-Requested-With';
proxyRes.headers['Access-Control-Allow-Credentials'] = 'true';
},
onError: (err, req, res) => {
console.error('Proxy error:', err);
res.status(500).json({ error: 'Proxy error', message: err.message });
}
}));

app.listen(PORT, () => {
console.log(`CORS Proxy running on http://localhost:${PORT}`);
console.log(`Proxying requests to Alto L2 at http://localhost:4338`);
console.log(`CORS enabled for frontend at http://localhost:3002`);
});

process.on('SIGINT', () => {
console.log('\nShutting down CORS Proxy...');
process.exit(0);
});
87 changes: 87 additions & 0 deletions contracts/script/listRegisteredNames.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
import { createPublicClient, http, parseAbiItem, decodeEventLog } from 'viem';
import { localhost } from 'viem/chains';

const RPC_URL = 'http://localhost:8546';
const ETH_REGISTRAR_ADDRESS = '0xa513e6e4b8f2a923d98304ec87f64353c4d5c853';

const client = createPublicClient({
chain: localhost,
transport: http(RPC_URL),
});

const nameRegisteredEvent = parseAbiItem(
'event NameRegistered(string name, address owner, address subregistry, address resolver, uint64 duration, uint256 tokenId, uint256 baseCost, uint256 premium)'
);

function shortenAddress(address: string): string {
return `${address.slice(0, 6)}...${address.slice(-4)}`;
}

async function listRegisteredNames() {
console.log('Fetching all registered names...\n');

try {
const logs = await client.getLogs({
address: ETH_REGISTRAR_ADDRESS as `0x${string}`,
event: nameRegisteredEvent,
fromBlock: 0n,
toBlock: 'latest',
});

console.log(`Found ${logs.length} registered names\n`);

if (logs.length === 0) {
console.log('No names found');
return;
}

const namesData = logs.map((log, index) => {
try {
const decoded = decodeEventLog({
abi: [nameRegisteredEvent],
data: log.data,
topics: log.topics,
});

const { name, owner, duration, baseCost, premium } = decoded.args;
const totalCost = Number(baseCost) + Number(premium);
const durationInDays = Math.floor(Number(duration) / 86400);

return {
'#': index + 1,
'Name': name,
'Owner': shortenAddress(owner),
'Duration (days)': durationInDays,
'Total Cost (USD)': (totalCost / 1e8).toFixed(2),
};
} catch (error) {
return {
'#': index + 1,
'Name': 'Error decoding',
'Owner': 'Error',
'Duration (days)': 'Error',
'Total Cost (USD)': 'Error',
};
}
});

console.table(namesData);

console.log('\nSummary:');
console.log('===========');

const uniqueOwners = new Set(namesData.map(item => item.Owner).filter(owner => owner !== 'Error'));
const totalCost = namesData
.filter(item => item['Total Cost (USD)'] !== 'Error')
.reduce((sum, item) => sum + parseFloat(item['Total Cost (USD)']), 0);

console.log(`Total Names: ${namesData.length}`);
console.log(`Unique Owners: ${uniqueOwners.size}`);
console.log(`Total Value: $${totalCost.toFixed(2)} USD`);

} catch (error) {
console.error('Error fetching names:', error);
}
}

listRegisteredNames().catch(console.error);
126 changes: 126 additions & 0 deletions contracts/script/mintTokensDirect.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,126 @@
#!/usr/bin/env bun
import { createPublicClient, createWalletClient, http, parseEther, parseUnits } from 'viem';
import { privateKeyToAccount } from 'viem/accounts';

const MOCK_USDC_ADDRESS = '0xe7f1725e7734ce288f8367e1bb143e90bb3f0512';
const MOCK_DAI_ADDRESS = '0x9fe46736679d2d9a65f0992f2272de9f3c7fa6e0';

const MOCK_ERC20_ABI = [
{
inputs: [
{ name: 'to', type: 'address' },
{ name: 'amount', type: 'uint256' }
],
name: 'mint',
outputs: [],
stateMutability: 'nonpayable',
type: 'function'
},
{
inputs: [{ name: 'account', type: 'address' }],
name: 'balanceOf',
outputs: [{ name: '', type: 'uint256' }],
stateMutability: 'view',
type: 'function'
}
];

async function main() {
const targetWallet = process.argv[2];

if (!targetWallet) {
console.error('Usage: bun run script/mintTokensDirect.ts <WALLET_ADDRESS>');
console.error('Example: bun run script/mintTokensDirect.ts 0x1234...');
process.exit(1);
}

console.log(`Minting mock tokens to: ${targetWallet}`);
console.log(`MockUSDC: ${MOCK_USDC_ADDRESS}`);
console.log(`MockDAI: ${MOCK_DAI_ADDRESS}`);

const l2Client = createPublicClient({
chain: {
id: 31338,
name: 'L2 Local',
nativeCurrency: { name: 'Ether', symbol: 'ETH', decimals: 18 },
rpcUrls: {
default: { http: ['http://127.0.0.1:8546'] },
public: { http: ['http://127.0.0.1:8546'] },
},
},
transport: http('http://127.0.0.1:8546'),
});

const deployerAccount = privateKeyToAccount('0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80');

const walletClient = createWalletClient({
account: deployerAccount,
chain: {
id: 31338,
name: 'L2 Local',
nativeCurrency: { name: 'Ether', symbol: 'ETH', decimals: 18 },
rpcUrls: {
default: { http: ['http://127.0.0.1:8546'] },
public: { http: ['http://127.0.0.1:8546'] },
},
},
transport: http('http://127.0.0.1:8546'),
});

try {
const usdcAmount = parseUnits('1000', 6);
console.log(`Minting 1000 USDC...`);

const usdcMintTx = await walletClient.writeContract({
address: MOCK_USDC_ADDRESS,
abi: MOCK_ERC20_ABI,
functionName: 'mint',
args: [targetWallet, usdcAmount],
});

console.log(`USDC minted! Transaction: ${usdcMintTx}`);

const daiAmount = parseEther('1000');
console.log(`Minting 1000 DAI...`);

const daiMintTx = await walletClient.writeContract({
address: MOCK_DAI_ADDRESS,
abi: MOCK_ERC20_ABI,
functionName: 'mint',
args: [targetWallet, daiAmount],
});

console.log(`DAI minted! Transaction: ${daiMintTx}`);

console.log('Waiting for transactions to be mined...');
await new Promise(resolve => setTimeout(resolve, 2000));

const usdcBalance = await l2Client.readContract({
address: MOCK_USDC_ADDRESS,
abi: MOCK_ERC20_ABI,
functionName: 'balanceOf',
args: [targetWallet],
});

const daiBalance = await l2Client.readContract({
address: MOCK_DAI_ADDRESS,
abi: MOCK_ERC20_ABI,
functionName: 'balanceOf',
args: [targetWallet],
});

console.log('\nToken minting complete!');
console.log(`${targetWallet} now has:`);
console.log(` - USDC: ${Number(usdcBalance) / 1e6} USDC`);
console.log(` - DAI: ${Number(daiBalance) / 1e18} DAI`);
console.log('\nYou can now use these tokens to register names from your frontend!');
console.log(` - Each name registration costs $10 (in either USDC or DAI)`);
console.log(` - Make sure to approve the ETHRegistrar contract to spend your tokens`);

} catch (error) {
console.error('Error minting tokens:', error);
process.exit(1);
}
}

main().catch(console.error);
Loading