Skip to content

Commit 80bd825

Browse files
jolestarclaude
andcommitted
Add SKALE on Base network support and fix facilitator fee calculation
## Network Configuration - Add SKALE on Base (eip155:1187947933, chainId: 1187947933) - Add SKALE Base Sepolia (eip155:324705682, chainId: 324705682) - Configure USDC (Bridged USDC with EIP-712 verification) - Configure CREDIT token pricing: $0.25 (1 USD = 4 CREDIT) ## Shared Network Configuration - Create networks.json generation script from TypeScript source - Update deploy-contract.sh to support CAIP-2 network identifiers - Add getNetworkAlias import for network name matching ## Facilitator Improvements - Fix native token price matching for SKALE networks - Convert CAIP-2 IDs to aliases before price matching - Add CREDIT token price configuration ## Deployed Contracts (SKALE on Base) - SettlementRouter: 0x1Ae0E196dC18355aF3a19985faf67354213F833D - TransferHook: 0x2f05fe5674aE756E25C26855258B4877E9e021Fd - NFTMintHook: 0x73fc659Cd5494E69852bE8D9D23FE05Aab14b29B - RandomNFT: 0x081258287F692D61575387ee2a4075f34dd7Aef7 - RewardHook: 0xC20634ea518985901e32Fbc1bA27fa673D37601A - RewardToken: 0x9Fc2c199170B039f093ABCd54008038F0C0a31d6 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
1 parent e581557 commit 80bd825

File tree

13 files changed

+1497
-235
lines changed

13 files changed

+1497
-235
lines changed

contracts/deploy-contract.sh

Lines changed: 121 additions & 164 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
#!/bin/bash
22
# Multi-network deployment script for SettlementRouter and Showcase contracts
3-
# Supports: Base Sepolia, Base Mainnet, X-Layer Testnet, X-Layer Mainnet, SKALE Base Sepolia
3+
# Supports: Base Sepolia, Base Mainnet, X-Layer Testnet, X-Layer Mainnet, SKALE Base Sepolia, BSC
4+
# Network configuration is loaded from networks.json (shared with TypeScript)
45

56
set -e
67

@@ -17,18 +18,68 @@ print_success() { echo -e "${GREEN}✓${NC} $1"; }
1718
print_warning() { echo -e "${YELLOW}${NC} $1"; }
1819
print_error() { echo -e "${RED}${NC} $1"; }
1920

21+
# ============================================
22+
# Network Configuration (from networks.json)
23+
# ============================================
24+
25+
NETWORKS_FILE="networks.json"
26+
27+
# Ensure networks.json exists
28+
if [ ! -f "$NETWORKS_FILE" ]; then
29+
print_error "networks.json not found!"
30+
echo ""
31+
echo "Please generate it first:"
32+
echo " pnpm --filter '@x402x/extensions' generate-networks-json"
33+
exit 1
34+
fi
35+
36+
# Get network config by CAIP-2 ID or v1 alias
37+
get_network_config() {
38+
local network=$1
39+
local field=$2
40+
41+
# Try to find by caip2 or v1Alias
42+
jq -r --arg network "$network" --arg field "$field" \
43+
'.networks[] | select(.caip2 == $network or .v1Alias == $network) | .[$field]' \
44+
"$NETWORKS_FILE" 2>/dev/null
45+
}
46+
47+
# Check if network exists
48+
network_exists() {
49+
local network=$1
50+
local count=$(jq -r --arg network "$network" \
51+
'.networks[] | select(.caip2 == $network or .v1Alias == $network) | .caip2' \
52+
"$NETWORKS_FILE" 2>/dev/null | wc -l | tr -d ' ')
53+
[ "$count" -gt 0 ]
54+
}
55+
56+
# Get CAIP-2 ID from v1 alias or CAIP-2
57+
get_caip2_id() {
58+
local network=$1
59+
get_network_config "$network" "caip2"
60+
}
61+
62+
# Normalize network to CAIP-2 format
63+
normalize_network() {
64+
local network=$1
65+
if [[ "$network" =~ ^eip155:[0-9]+$ ]]; then
66+
echo "$network"
67+
else
68+
get_caip2_id "$network"
69+
fi
70+
}
71+
72+
# List all supported networks
73+
list_networks() {
74+
jq -r '.networks[] | "\(.caip2) (\(.v1Alias)): \(.name)"' "$NETWORKS_FILE"
75+
}
76+
2077
# Print usage
2178
usage() {
2279
echo "Usage: $0 [NETWORK] [OPTIONS]"
2380
echo ""
24-
echo "Networks:"
25-
echo " base-sepolia Base Sepolia Testnet (Chain ID: 84532)"
26-
echo " base Base Mainnet (Chain ID: 8453)"
27-
echo " xlayer-testnet X-Layer Testnet (Chain ID: 1952)"
28-
echo " xlayer X-Layer Mainnet (Chain ID: 196)"
29-
echo " skale-base-sepolia SKALE Base Sepolia (Chain ID: 324705682)"
30-
echo " bsc-testnet BSC Testnet (Chain ID: 97)"
31-
echo " bsc BSC Mainnet (Chain ID: 56)"
81+
echo "Networks (CAIP-2 format preferred, v1 aliases also supported):"
82+
list_networks | sed 's/^/ /'
3283
echo ""
3384
echo "Options:"
3485
echo " --settlement Deploy only SettlementRouter"
@@ -45,14 +96,15 @@ usage() {
4596
echo " -h, --help Show this help message"
4697
echo ""
4798
echo "Examples:"
48-
echo " $0 xlayer-testnet # Deploy everything on X-Layer Testnet"
49-
echo " $0 xlayer-testnet --settlement # Deploy only SettlementRouter"
50-
echo " $0 xlayer-testnet --showcase # Deploy all showcase scenarios"
51-
echo " $0 xlayer-testnet --hooks # Deploy all built-in Hooks"
52-
echo " $0 xlayer-testnet --transfer # Deploy only TransferHook"
53-
echo " $0 xlayer-testnet --nft # Deploy only NFT scenario"
54-
echo " $0 base-sepolia --all --with-hooks # Deploy everything including hooks"
55-
echo " $0 base-sepolia --all --verify # Deploy and verify on Base Sepolia"
99+
echo " $0 eip155:1952 # Deploy everything on X-Layer Testnet (CAIP-2)"
100+
echo " $0 xlayer-testnet # Same as above (v1 alias)"
101+
echo " $0 eip155:1952 --settlement # Deploy only SettlementRouter"
102+
echo " $0 eip155:1952 --showcase # Deploy all showcase scenarios"
103+
echo " $0 eip155:1952 --hooks # Deploy all built-in Hooks"
104+
echo " $0 eip155:1952 --transfer # Deploy only TransferHook"
105+
echo " $0 eip155:1952 --nft # Deploy only NFT scenario"
106+
echo " $0 eip155:84532 --all --with-hooks # Deploy everything including hooks"
107+
echo " $0 eip155:84532 --all --verify # Deploy and verify on Base Sepolia"
56108
echo ""
57109
echo "Environment Variables Required:"
58110
echo " DEPLOYER_PRIVATE_KEY Deployer wallet private key"
@@ -76,10 +128,6 @@ WITH_HOOKS=false # Flag for --with-hooks option
76128

77129
while [[ $# -gt 0 ]]; do
78130
case $1 in
79-
base-sepolia|base|xlayer-testnet|xlayer|skale-base-sepolia|bsc-testnet|bsc)
80-
NETWORK=$1
81-
shift
82-
;;
83131
--settlement)
84132
DEPLOY_MODE="settlement"
85133
shift
@@ -127,10 +175,15 @@ while [[ $# -gt 0 ]]; do
127175
-h|--help)
128176
usage
129177
;;
130-
*)
178+
--*)
131179
print_error "Unknown option: $1"
132180
usage
133181
;;
182+
*)
183+
# Anything else is treated as network identifier (CAIP-2 or v1 alias)
184+
NETWORK=$1
185+
shift
186+
;;
134187
esac
135188
done
136189

@@ -141,97 +194,37 @@ if [ -z "$NETWORK" ]; then
141194
usage
142195
fi
143196

197+
# Validate network is supported
198+
if ! network_exists "$NETWORK"; then
199+
print_error "Unknown or unsupported network: $NETWORK"
200+
echo ""
201+
echo "Supported networks:"
202+
list_networks | sed 's/^/ /'
203+
echo ""
204+
exit 1
205+
fi
206+
207+
# Normalize to CAIP-2 format
208+
CAIP2_ID=$(normalize_network "$NETWORK")
209+
if [ -z "$CAIP2_ID" ]; then
210+
print_error "Failed to get CAIP-2 ID for network: $NETWORK"
211+
exit 1
212+
fi
213+
144214
# Header
145215
echo "========================================="
146216
echo " x402-exec Multi-Network Deployment"
147217
echo "========================================="
148218
echo ""
149219

150-
# Map network to environment variable prefixes
151-
get_env_prefix() {
152-
case $1 in
153-
base-sepolia)
154-
echo "BASE_SEPOLIA"
155-
;;
156-
base)
157-
echo "BASE"
158-
;;
159-
xlayer-testnet)
160-
echo "X_LAYER_TESTNET"
161-
;;
162-
xlayer)
163-
echo "X_LAYER"
164-
;;
165-
skale-base-sepolia)
166-
echo "SKALE_BASE_SEPOLIA"
167-
;;
168-
bsc-testnet)
169-
echo "BSC_TESTNET"
170-
;;
171-
bsc)
172-
echo "BSC"
173-
;;
174-
esac
175-
}
176-
177-
# Get network display name and chain ID
178-
get_network_info() {
179-
case $1 in
180-
base-sepolia)
181-
echo "Base Sepolia Testnet|84532"
182-
;;
183-
base)
184-
echo "Base Mainnet|8453"
185-
;;
186-
xlayer-testnet)
187-
echo "X-Layer Testnet|1952"
188-
;;
189-
xlayer)
190-
echo "X-Layer Mainnet|196"
191-
;;
192-
skale-base-sepolia)
193-
echo "SKALE Base Sepolia|324705682"
194-
;;
195-
bsc-testnet)
196-
echo "BSC Testnet|97"
197-
;;
198-
bsc)
199-
echo "BSC Mainnet|56"
200-
;;
201-
esac
202-
}
203-
204-
# Get default RPC URL for network
205-
get_default_rpc_url() {
206-
case $1 in
207-
base-sepolia)
208-
echo "https://sepolia.base.org"
209-
;;
210-
base)
211-
echo "https://mainnet.base.org"
212-
;;
213-
xlayer-testnet)
214-
echo "https://testrpc.xlayer.tech/terigon"
215-
;;
216-
xlayer)
217-
echo "https://rpc.xlayer.tech"
218-
;;
219-
skale-base-sepolia)
220-
echo "https://base-sepolia-testnet.skalenodes.com/v1/jubilant-horrible-ancha"
221-
;;
222-
bsc-testnet)
223-
echo "https://data-seed-prebsc-1-s1.bnbchain.org:8545"
224-
;;
225-
bsc)
226-
echo "https://bsc-dataseed.binance.org"
227-
;;
228-
esac
229-
}
230-
231-
ENV_PREFIX=$(get_env_prefix $NETWORK)
232-
NETWORK_INFO=$(get_network_info $NETWORK)
233-
NETWORK_NAME=$(echo $NETWORK_INFO | cut -d'|' -f1)
234-
CHAIN_ID=$(echo $NETWORK_INFO | cut -d'|' -f2)
220+
# Load network configuration from networks.json
221+
ENV_PREFIX=$(get_network_config "$CAIP2_ID" "envPrefix")
222+
NETWORK_NAME=$(get_network_config "$CAIP2_ID" "name")
223+
CHAIN_ID=$(get_network_config "$CAIP2_ID" "chainId")
224+
DEFAULT_RPC_URL=$(get_network_config "$CAIP2_ID" "rpcUrl")
225+
EXPLORER_URL=$(get_network_config "$CAIP2_ID" "explorerUrl")
226+
GAS_MODEL=$(get_network_config "$CAIP2_ID" "gasModel")
227+
NETWORK_TYPE=$(get_network_config "$CAIP2_ID" "type")
235228

236229
# Try to load .env from project root
237230
if [ -f "../.env" ]; then
@@ -243,13 +236,13 @@ else
243236
print_warning ".env file not found in project root, using shell environment variables"
244237
fi
245238

246-
# Get RPC URL from environment or use default
239+
# Get RPC URL from environment or use default from networks.json
247240
RPC_URL_VAR="${ENV_PREFIX}_RPC_URL"
248241
RPC_URL="${!RPC_URL_VAR}"
249242

250-
# Fallback to default RPC URL if not set in environment
243+
# Fallback to default RPC URL from networks.json if not set in environment
251244
if [ -z "$RPC_URL" ]; then
252-
RPC_URL=$(get_default_rpc_url $NETWORK)
245+
RPC_URL="$DEFAULT_RPC_URL"
253246
print_info "Using default RPC URL for $NETWORK_NAME"
254247
fi
255248

@@ -342,65 +335,51 @@ if [ "$VERIFY" = true ]; then
342335
print_info "Contract verification enabled"
343336
print_warning "Note: Forge's built-in verification may timeout for complex contracts"
344337
print_warning "If verification fails, run: ./verify-contracts.sh $NETWORK"
345-
346-
# Build verification flags based on network
347-
# Use chain ID for --chain and explicitly specify API key and verifier URL
348-
case $NETWORK in
349-
base-sepolia)
350-
if [ -n "$BASESCAN_API_KEY" ]; then
351-
VERIFY_FLAG="--verify --chain $CHAIN_ID --etherscan-api-key $BASESCAN_API_KEY"
352-
else
353-
print_error "BASESCAN_API_KEY not set, skipping verification"
354-
VERIFY_FLAG=""
355-
fi
356-
;;
357-
base)
338+
339+
# Build verification flags based on CAIP-2 ID
340+
case $CAIP2_ID in
341+
eip155:84532|eip155:8453)
342+
# Base networks
358343
if [ -n "$BASESCAN_API_KEY" ]; then
359344
VERIFY_FLAG="--verify --chain $CHAIN_ID --etherscan-api-key $BASESCAN_API_KEY"
360345
else
361346
print_error "BASESCAN_API_KEY not set, skipping verification"
362347
VERIFY_FLAG=""
363348
fi
364349
;;
365-
xlayer-testnet)
366-
OKLINK_KEY="${OKLINK_API_KEY:-not-required}"
367-
VERIFY_FLAG="--verify --chain $CHAIN_ID --verifier-url https://www.oklink.com/api/v5/explorer/contract/verify-source-code-plugin/XLAYER_TESTNET --etherscan-api-key $OKLINK_KEY"
368-
;;
369-
xlayer)
350+
eip155:1952|eip155:196)
351+
# X-Layer networks
370352
OKLINK_KEY="${OKLINK_API_KEY:-not-required}"
371353
VERIFY_FLAG="--verify --chain $CHAIN_ID --verifier-url https://www.oklink.com/api/v5/explorer/contract/verify-source-code-plugin/XLAYER --etherscan-api-key $OKLINK_KEY"
372354
;;
373-
bsc-testnet)
355+
eip155:97|eip155:56)
356+
# BSC networks
374357
if [ -n "$BSCSCAN_API_KEY" ]; then
375358
VERIFY_FLAG="--verify --chain $CHAIN_ID --etherscan-api-key $BSCSCAN_API_KEY"
376359
else
377360
print_error "BSCSCAN_API_KEY not set, skipping verification"
378361
VERIFY_FLAG=""
379362
fi
380363
;;
381-
bsc)
382-
if [ -n "$BSCSCAN_API_KEY" ]; then
383-
VERIFY_FLAG="--verify --chain $CHAIN_ID --etherscan-api-key $BSCSCAN_API_KEY"
384-
else
385-
print_error "BSCSCAN_API_KEY not set, skipping verification"
386-
VERIFY_FLAG=""
387-
fi
388-
;;
389-
skale-base-sepolia)
390-
# SKALE doesn't support automated verification via forge
364+
eip155:324705682)
365+
# SKALE - doesn't support automated verification via forge
391366
print_warning "SKALE Base Sepolia doesn't support automated verification"
392367
print_warning "You'll need to verify manually after deployment"
393368
VERIFY_FLAG=""
394369
;;
370+
*)
371+
print_warning "No verification configuration for $CAIP2_ID"
372+
VERIFY_FLAG=""
373+
;;
395374
esac
396375
fi
397376

398377
# Export environment variables for Forge scripts
399378
export SETTLEMENT_ROUTER_ADDRESS="$SETTLEMENT_ROUTER"
400379

401-
# Determine additional flags based on network
380+
# Determine additional flags based on gas model
402381
LEGACY_FLAG=""
403-
if [ "$NETWORK" = "skale-base-sepolia" ] || [ "$NETWORK" = "bsc-testnet" ] || [ "$NETWORK" = "bsc" ]; then
382+
if [ "$GAS_MODEL" = "legacy" ]; then
404383
LEGACY_FLAG="--legacy"
405384
print_info "Using legacy gas pricing for $NETWORK_NAME"
406385
fi
@@ -561,28 +540,6 @@ fi
561540
echo ""
562541

563542
# Display block explorer link
564-
case $NETWORK in
565-
base-sepolia)
566-
echo "View contracts: https://sepolia.basescan.org/"
567-
;;
568-
base)
569-
echo "View contracts: https://basescan.org/"
570-
;;
571-
xlayer-testnet)
572-
echo "View contracts: https://www.oklink.com/xlayer-test"
573-
;;
574-
xlayer)
575-
echo "View contracts: https://www.oklink.com/xlayer"
576-
;;
577-
skale-base-sepolia)
578-
echo "View contracts: https://base-sepolia-testnet-explorer.skalenodes.com/"
579-
;;
580-
bsc-testnet)
581-
echo "View contracts: https://testnet.bscscan.com/"
582-
;;
583-
bsc)
584-
echo "View contracts: https://bscscan.com/"
585-
;;
586-
esac
543+
echo "View contracts: $EXPLORER_URL"
587544
echo ""
588545

0 commit comments

Comments
 (0)