@sip-protocol/sdk 0.7.3 → 0.8.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +267 -0
- package/dist/{TransportWebUSB-TQ7WZ4LE.mjs → TransportWebUSB-YQMAGJAJ.mjs} +12 -9
- package/dist/browser.d.mts +10 -4
- package/dist/browser.d.ts +10 -4
- package/dist/browser.js +47556 -19603
- package/dist/browser.mjs +628 -48
- package/dist/chunk-4GRJ5MAW.mjs +152 -0
- package/dist/chunk-5D7A3L3W.mjs +717 -0
- package/dist/chunk-64AYA5F5.mjs +7834 -0
- package/dist/chunk-GMDGB22A.mjs +379 -0
- package/dist/chunk-I534WKN7.mjs +328 -0
- package/dist/chunk-IBZVA5Y7.mjs +1003 -0
- package/dist/chunk-PRRZAWJE.mjs +223 -0
- package/dist/{chunk-UJCSKKID.mjs → chunk-XGB3TDIC.mjs} +13 -1
- package/dist/{chunk-3M3HNQCW.mjs → chunk-YWGJ77A2.mjs} +28656 -13103
- package/dist/{chunk-6WGN57S2.mjs → chunk-Z3K7W5S3.mjs} +48 -0
- package/dist/constants-LHAAUC2T.mjs +51 -0
- package/dist/dist-2OGQ7FED.mjs +3957 -0
- package/dist/dist-IFHPYLDX.mjs +254 -0
- package/dist/fulfillment_proof-ANHVPKTB.mjs +21 -0
- package/dist/funding_proof-ICFZ5LHY.mjs +21 -0
- package/dist/{index-DIBZHOOQ.d.ts → index-DXh2IGkz.d.ts} +21239 -10304
- package/dist/{index-8MQz13eJ.d.mts → index-DeE1ZzA4.d.mts} +21239 -10304
- package/dist/index.d.mts +9 -3
- package/dist/index.d.ts +9 -3
- package/dist/index.js +48396 -19623
- package/dist/index.mjs +537 -19
- package/dist/interface-Bf7w1PLW.d.mts +679 -0
- package/dist/interface-Bf7w1PLW.d.ts +679 -0
- package/dist/{noir-DKfEzWy9.d.mts → noir-kzbLVTei.d.mts} +31 -21
- package/dist/{noir-DKfEzWy9.d.ts → noir-kzbLVTei.d.ts} +31 -21
- package/dist/proofs/halo2.d.mts +151 -0
- package/dist/proofs/halo2.d.ts +151 -0
- package/dist/proofs/halo2.js +350 -0
- package/dist/proofs/halo2.mjs +11 -0
- package/dist/proofs/kimchi.d.mts +160 -0
- package/dist/proofs/kimchi.d.ts +160 -0
- package/dist/proofs/kimchi.js +431 -0
- package/dist/proofs/kimchi.mjs +13 -0
- package/dist/proofs/noir.d.mts +1 -1
- package/dist/proofs/noir.d.ts +1 -1
- package/dist/proofs/noir.js +74 -18
- package/dist/proofs/noir.mjs +84 -24
- package/dist/solana-U3MEGU7W.mjs +280 -0
- package/dist/validity_proof-3POXLPNY.mjs +21 -0
- package/package.json +44 -11
- package/src/adapters/index.ts +41 -0
- package/src/adapters/jupiter.ts +571 -0
- package/src/adapters/near-intents.ts +135 -0
- package/src/advisor/advisor.ts +653 -0
- package/src/advisor/index.ts +54 -0
- package/src/advisor/tools.ts +303 -0
- package/src/advisor/types.ts +164 -0
- package/src/chains/ethereum/announcement.ts +536 -0
- package/src/chains/ethereum/bnb-optimizations.ts +474 -0
- package/src/chains/ethereum/commitment.ts +522 -0
- package/src/chains/ethereum/constants.ts +462 -0
- package/src/chains/ethereum/deployment.ts +596 -0
- package/src/chains/ethereum/gas-estimation.ts +538 -0
- package/src/chains/ethereum/index.ts +268 -0
- package/src/chains/ethereum/optimizations.ts +614 -0
- package/src/chains/ethereum/privacy-adapter.ts +855 -0
- package/src/chains/ethereum/registry.ts +584 -0
- package/src/chains/ethereum/rpc.ts +905 -0
- package/src/chains/ethereum/stealth.ts +491 -0
- package/src/chains/ethereum/token.ts +790 -0
- package/src/chains/ethereum/transfer.ts +637 -0
- package/src/chains/ethereum/types.ts +456 -0
- package/src/chains/ethereum/viewing-key.ts +455 -0
- package/src/chains/near/commitment.ts +608 -0
- package/src/chains/near/constants.ts +284 -0
- package/src/chains/near/function-call.ts +871 -0
- package/src/chains/near/history.ts +654 -0
- package/src/chains/near/implicit-account.ts +840 -0
- package/src/chains/near/index.ts +393 -0
- package/src/chains/near/native-transfer.ts +658 -0
- package/src/chains/near/nep141.ts +775 -0
- package/src/chains/near/privacy-adapter.ts +889 -0
- package/src/chains/near/resolver.ts +971 -0
- package/src/chains/near/rpc.ts +1016 -0
- package/src/chains/near/stealth.ts +419 -0
- package/src/chains/near/types.ts +317 -0
- package/src/chains/near/viewing-key.ts +876 -0
- package/src/chains/solana/anchor-transfer.ts +386 -0
- package/src/chains/solana/commitment.ts +577 -0
- package/src/chains/solana/constants.ts +126 -12
- package/src/chains/solana/ephemeral-keys.ts +543 -0
- package/src/chains/solana/index.ts +252 -1
- package/src/chains/solana/key-derivation.ts +418 -0
- package/src/chains/solana/kit-compat.ts +334 -0
- package/src/chains/solana/optimizations.ts +560 -0
- package/src/chains/solana/privacy-adapter.ts +605 -0
- package/src/chains/solana/providers/generic.ts +47 -6
- package/src/chains/solana/providers/helius-enhanced-types.ts +336 -0
- package/src/chains/solana/providers/helius-enhanced.ts +623 -0
- package/src/chains/solana/providers/helius.ts +186 -33
- package/src/chains/solana/providers/index.ts +31 -0
- package/src/chains/solana/providers/interface.ts +61 -18
- package/src/chains/solana/providers/quicknode.ts +409 -0
- package/src/chains/solana/providers/triton.ts +426 -0
- package/src/chains/solana/providers/webhook.ts +338 -67
- package/src/chains/solana/rpc-client.ts +1150 -0
- package/src/chains/solana/scan.ts +83 -66
- package/src/chains/solana/sol-transfer.ts +732 -0
- package/src/chains/solana/spl-transfer.ts +886 -0
- package/src/chains/solana/stealth-scanner.ts +703 -0
- package/src/chains/solana/sunspot-verifier.ts +453 -0
- package/src/chains/solana/transaction-builder.ts +755 -0
- package/src/chains/solana/transfer.ts +74 -5
- package/src/chains/solana/types.ts +57 -6
- package/src/chains/solana/utils.ts +110 -0
- package/src/chains/solana/viewing-key.ts +807 -0
- package/src/compliance/fireblocks.ts +921 -0
- package/src/compliance/index.ts +23 -0
- package/src/compliance/range-sas.ts +398 -33
- package/src/config/endpoints.ts +100 -0
- package/src/crypto.ts +11 -8
- package/src/errors.ts +82 -0
- package/src/evm/erc4337-relayer.ts +830 -0
- package/src/evm/index.ts +47 -0
- package/src/fees/calculator.ts +396 -0
- package/src/fees/index.ts +87 -0
- package/src/fees/near-contract.ts +429 -0
- package/src/fees/types.ts +268 -0
- package/src/index.ts +686 -1
- package/src/intent.ts +6 -3
- package/src/logger.ts +324 -0
- package/src/network/index.ts +80 -0
- package/src/network/proxy.ts +691 -0
- package/src/optimizations/index.ts +541 -0
- package/src/oracle/types.ts +1 -0
- package/src/privacy-backends/arcium-types.ts +727 -0
- package/src/privacy-backends/arcium.ts +719 -0
- package/src/privacy-backends/combined-privacy.ts +866 -0
- package/src/privacy-backends/cspl-token.ts +595 -0
- package/src/privacy-backends/cspl-types.ts +512 -0
- package/src/privacy-backends/cspl.ts +907 -0
- package/src/privacy-backends/health.ts +488 -0
- package/src/privacy-backends/inco-types.ts +323 -0
- package/src/privacy-backends/inco.ts +616 -0
- package/src/privacy-backends/index.ts +254 -4
- package/src/privacy-backends/interface.ts +649 -6
- package/src/privacy-backends/lru-cache.ts +343 -0
- package/src/privacy-backends/magicblock.ts +458 -0
- package/src/privacy-backends/mock.ts +258 -0
- package/src/privacy-backends/privacycash.ts +13 -17
- package/src/privacy-backends/private-swap.ts +570 -0
- package/src/privacy-backends/rate-limiter.ts +683 -0
- package/src/privacy-backends/registry.ts +414 -2
- package/src/privacy-backends/router.ts +283 -3
- package/src/privacy-backends/shadowwire.ts +449 -0
- package/src/privacy-backends/sip-native.ts +3 -0
- package/src/privacy-logger.ts +191 -0
- package/src/production-safety.ts +373 -0
- package/src/proofs/aggregator.ts +1029 -0
- package/src/proofs/browser-composer.ts +1150 -0
- package/src/proofs/browser.ts +113 -25
- package/src/proofs/cache/index.ts +127 -0
- package/src/proofs/cache/interface.ts +545 -0
- package/src/proofs/cache/key-generator.ts +188 -0
- package/src/proofs/cache/lru-cache.ts +481 -0
- package/src/proofs/cache/multi-tier-cache.ts +575 -0
- package/src/proofs/cache/persistent-cache.ts +788 -0
- package/src/proofs/compliance-proof.ts +872 -0
- package/src/proofs/composer/base.ts +923 -0
- package/src/proofs/composer/index.ts +25 -0
- package/src/proofs/composer/interface.ts +518 -0
- package/src/proofs/composer/types.ts +383 -0
- package/src/proofs/converters/halo2.ts +452 -0
- package/src/proofs/converters/index.ts +208 -0
- package/src/proofs/converters/interface.ts +363 -0
- package/src/proofs/converters/kimchi.ts +462 -0
- package/src/proofs/converters/noir.ts +451 -0
- package/src/proofs/fallback.ts +888 -0
- package/src/proofs/halo2.ts +42 -0
- package/src/proofs/index.ts +471 -0
- package/src/proofs/interface.ts +13 -0
- package/src/proofs/kimchi.ts +42 -0
- package/src/proofs/lazy.ts +1004 -0
- package/src/proofs/mock.ts +25 -1
- package/src/proofs/noir.ts +110 -29
- package/src/proofs/orchestrator.ts +960 -0
- package/src/proofs/parallel/concurrency.ts +297 -0
- package/src/proofs/parallel/dependency-graph.ts +602 -0
- package/src/proofs/parallel/executor.ts +420 -0
- package/src/proofs/parallel/index.ts +131 -0
- package/src/proofs/parallel/interface.ts +685 -0
- package/src/proofs/parallel/worker-pool.ts +644 -0
- package/src/proofs/providers/halo2.ts +560 -0
- package/src/proofs/providers/index.ts +34 -0
- package/src/proofs/providers/kimchi.ts +641 -0
- package/src/proofs/validator.ts +881 -0
- package/src/proofs/verifier.ts +867 -0
- package/src/quantum/index.ts +112 -0
- package/src/quantum/winternitz-vault.ts +639 -0
- package/src/quantum/wots.ts +611 -0
- package/src/settlement/backends/direct-chain.ts +1 -0
- package/src/settlement/index.ts +9 -0
- package/src/settlement/router.ts +732 -46
- package/src/solana/index.ts +72 -0
- package/src/solana/jito-relayer.ts +687 -0
- package/src/solana/noir-verifier-types.ts +430 -0
- package/src/solana/noir-verifier.ts +816 -0
- package/src/stealth/address-derivation.ts +193 -0
- package/src/stealth/ed25519.ts +431 -0
- package/src/stealth/index.ts +233 -0
- package/src/stealth/meta-address.ts +221 -0
- package/src/stealth/secp256k1.ts +368 -0
- package/src/stealth/utils.ts +194 -0
- package/src/stealth.ts +50 -1504
- package/src/sync/index.ts +106 -0
- package/src/sync/manager.ts +504 -0
- package/src/sync/mock-provider.ts +318 -0
- package/src/sync/oblivious.ts +625 -0
- package/src/tokens/index.ts +15 -0
- package/src/tokens/registry.ts +301 -0
- package/src/utils/deprecation.ts +94 -0
- package/src/utils/index.ts +9 -0
- package/src/wallet/ethereum/index.ts +68 -0
- package/src/wallet/ethereum/metamask-privacy.ts +420 -0
- package/src/wallet/ethereum/multi-wallet.ts +646 -0
- package/src/wallet/ethereum/privacy-adapter.ts +700 -0
- package/src/wallet/ethereum/types.ts +3 -1
- package/src/wallet/ethereum/walletconnect-adapter.ts +675 -0
- package/src/wallet/hardware/index.ts +10 -0
- package/src/wallet/hardware/ledger-privacy.ts +414 -0
- package/src/wallet/index.ts +71 -0
- package/src/wallet/near/adapter.ts +626 -0
- package/src/wallet/near/index.ts +86 -0
- package/src/wallet/near/meteor-wallet.ts +1153 -0
- package/src/wallet/near/my-near-wallet.ts +790 -0
- package/src/wallet/near/wallet-selector.ts +702 -0
- package/src/wallet/solana/adapter.ts +6 -4
- package/src/wallet/solana/index.ts +13 -0
- package/src/wallet/solana/privacy-adapter.ts +567 -0
- package/src/wallet/sui/types.ts +6 -4
- package/src/zcash/rpc-client.ts +13 -6
- package/dist/chunk-2XIVXWHA.mjs +0 -1930
- package/dist/chunk-3INS3PR5.mjs +0 -884
- package/dist/chunk-3OVABDRH.mjs +0 -17096
- package/dist/chunk-7RFRWDCW.mjs +0 -1504
- package/dist/chunk-DLDWZFYC.mjs +0 -1495
- package/dist/chunk-E6SZWREQ.mjs +0 -57
- package/dist/chunk-F6F73W35.mjs +0 -16166
- package/dist/chunk-G33LB27A.mjs +0 -16166
- package/dist/chunk-HGU6HZRC.mjs +0 -231
- package/dist/chunk-L2K34JCU.mjs +0 -1496
- package/dist/chunk-OFDBEIEK.mjs +0 -16166
- package/dist/chunk-SF7YSLF5.mjs +0 -1515
- package/dist/chunk-SN4ZDTVW.mjs +0 -16166
- package/dist/chunk-WWUSGOXE.mjs +0 -17129
- package/dist/constants-VOI7BSLK.mjs +0 -27
- package/dist/index-B71aXVzk.d.ts +0 -13264
- package/dist/index-BYZbDjal.d.ts +0 -11390
- package/dist/index-CHB3KuOB.d.mts +0 -11859
- package/dist/index-CzWPI6Le.d.ts +0 -11859
- package/dist/index-pOIIuwfV.d.mts +0 -13264
- package/dist/index-xbWjohNq.d.mts +0 -11390
- package/dist/solana-4O4K45VU.mjs +0 -46
- package/dist/solana-5EMCTPTS.mjs +0 -46
- package/dist/solana-NDABAZ6P.mjs +0 -56
- package/dist/solana-Q4NAVBTS.mjs +0 -46
- package/dist/solana-ZYO63LY5.mjs +0 -46
|
@@ -0,0 +1,596 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Ethereum L2 Deployment Utilities
|
|
3
|
+
*
|
|
4
|
+
* Provides contract deployment and verification helpers for Ethereum L2s.
|
|
5
|
+
* Supports Base, Arbitrum, Optimism, and other EVM-compatible chains.
|
|
6
|
+
*
|
|
7
|
+
* @module chains/ethereum/deployment
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
import type { HexString } from '@sip-protocol/types'
|
|
11
|
+
import {
|
|
12
|
+
type EthereumNetwork,
|
|
13
|
+
EVM_CHAIN_IDS,
|
|
14
|
+
ETHEREUM_RPC_ENDPOINTS,
|
|
15
|
+
ETHEREUM_EXPLORER_URLS,
|
|
16
|
+
} from './constants'
|
|
17
|
+
|
|
18
|
+
// ─── Types ────────────────────────────────────────────────────────────────────
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* L2 network configuration for deployment
|
|
22
|
+
*/
|
|
23
|
+
export interface L2NetworkConfig {
|
|
24
|
+
/** Network identifier */
|
|
25
|
+
network: EthereumNetwork
|
|
26
|
+
/** Chain ID */
|
|
27
|
+
chainId: number
|
|
28
|
+
/** RPC endpoint */
|
|
29
|
+
rpcUrl: string
|
|
30
|
+
/** Block explorer URL */
|
|
31
|
+
explorerUrl: string
|
|
32
|
+
/** Block explorer API URL */
|
|
33
|
+
explorerApiUrl: string
|
|
34
|
+
/** Whether this is a testnet */
|
|
35
|
+
isTestnet: boolean
|
|
36
|
+
/** Average block time in seconds */
|
|
37
|
+
blockTime: number
|
|
38
|
+
/** Required confirmations for finality */
|
|
39
|
+
requiredConfirmations: number
|
|
40
|
+
/** Native token symbol */
|
|
41
|
+
nativeToken: string
|
|
42
|
+
/** Gas multiplier (L2s often have lower fees) */
|
|
43
|
+
gasMultiplier: number
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
/**
|
|
47
|
+
* Contract deployment result
|
|
48
|
+
*/
|
|
49
|
+
export interface DeploymentResult {
|
|
50
|
+
/** Deployed contract address */
|
|
51
|
+
address: HexString
|
|
52
|
+
/** Deployment transaction hash */
|
|
53
|
+
transactionHash: HexString
|
|
54
|
+
/** Block number of deployment */
|
|
55
|
+
blockNumber: number
|
|
56
|
+
/** Gas used */
|
|
57
|
+
gasUsed: bigint
|
|
58
|
+
/** Network deployed to */
|
|
59
|
+
network: EthereumNetwork
|
|
60
|
+
/** Chain ID */
|
|
61
|
+
chainId: number
|
|
62
|
+
/** Timestamp */
|
|
63
|
+
deployedAt: number
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
/**
|
|
67
|
+
* Contract verification request
|
|
68
|
+
*/
|
|
69
|
+
export interface VerificationRequest {
|
|
70
|
+
/** Contract address */
|
|
71
|
+
address: HexString
|
|
72
|
+
/** Network */
|
|
73
|
+
network: EthereumNetwork
|
|
74
|
+
/** Source code (flattened) */
|
|
75
|
+
sourceCode: string
|
|
76
|
+
/** Contract name */
|
|
77
|
+
contractName: string
|
|
78
|
+
/** Compiler version */
|
|
79
|
+
compilerVersion: string
|
|
80
|
+
/** Constructor arguments (ABI-encoded) */
|
|
81
|
+
constructorArguments?: HexString
|
|
82
|
+
/** Optimization enabled */
|
|
83
|
+
optimization?: boolean
|
|
84
|
+
/** Optimization runs */
|
|
85
|
+
runs?: number
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
/**
|
|
89
|
+
* Verification result
|
|
90
|
+
*/
|
|
91
|
+
export interface VerificationResult {
|
|
92
|
+
/** Whether verification was successful */
|
|
93
|
+
success: boolean
|
|
94
|
+
/** Verification GUID for checking status */
|
|
95
|
+
guid?: string
|
|
96
|
+
/** Error message if failed */
|
|
97
|
+
error?: string
|
|
98
|
+
/** Explorer URL to verified contract */
|
|
99
|
+
explorerUrl?: string
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
/**
|
|
103
|
+
* Deployment config for a specific contract
|
|
104
|
+
*/
|
|
105
|
+
export interface DeploymentConfig {
|
|
106
|
+
/** Contract bytecode */
|
|
107
|
+
bytecode: HexString
|
|
108
|
+
/** Constructor arguments (ABI-encoded) */
|
|
109
|
+
constructorArgs?: HexString
|
|
110
|
+
/** Gas limit override */
|
|
111
|
+
gasLimit?: bigint
|
|
112
|
+
/** Value to send (for payable constructors) */
|
|
113
|
+
value?: bigint
|
|
114
|
+
/** Nonce override */
|
|
115
|
+
nonce?: number
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
// ─── L2 Network Configurations ────────────────────────────────────────────────
|
|
119
|
+
|
|
120
|
+
/**
|
|
121
|
+
* Pre-configured L2 networks for SIP deployment
|
|
122
|
+
*/
|
|
123
|
+
export const L2_NETWORK_CONFIGS: Record<string, L2NetworkConfig> = {
|
|
124
|
+
base: {
|
|
125
|
+
network: 'base',
|
|
126
|
+
chainId: EVM_CHAIN_IDS.base,
|
|
127
|
+
rpcUrl: ETHEREUM_RPC_ENDPOINTS.base,
|
|
128
|
+
explorerUrl: ETHEREUM_EXPLORER_URLS.base,
|
|
129
|
+
explorerApiUrl: 'https://api.basescan.org/api',
|
|
130
|
+
isTestnet: false,
|
|
131
|
+
blockTime: 2,
|
|
132
|
+
requiredConfirmations: 1,
|
|
133
|
+
nativeToken: 'ETH',
|
|
134
|
+
gasMultiplier: 0.1,
|
|
135
|
+
},
|
|
136
|
+
'base-sepolia': {
|
|
137
|
+
network: 'base-sepolia',
|
|
138
|
+
chainId: EVM_CHAIN_IDS['base-sepolia'],
|
|
139
|
+
rpcUrl: ETHEREUM_RPC_ENDPOINTS['base-sepolia'],
|
|
140
|
+
explorerUrl: ETHEREUM_EXPLORER_URLS['base-sepolia'],
|
|
141
|
+
explorerApiUrl: 'https://api-sepolia.basescan.org/api',
|
|
142
|
+
isTestnet: true,
|
|
143
|
+
blockTime: 2,
|
|
144
|
+
requiredConfirmations: 1,
|
|
145
|
+
nativeToken: 'ETH',
|
|
146
|
+
gasMultiplier: 0.1,
|
|
147
|
+
},
|
|
148
|
+
arbitrum: {
|
|
149
|
+
network: 'arbitrum',
|
|
150
|
+
chainId: EVM_CHAIN_IDS.arbitrum,
|
|
151
|
+
rpcUrl: ETHEREUM_RPC_ENDPOINTS.arbitrum,
|
|
152
|
+
explorerUrl: ETHEREUM_EXPLORER_URLS.arbitrum,
|
|
153
|
+
explorerApiUrl: 'https://api.arbiscan.io/api',
|
|
154
|
+
isTestnet: false,
|
|
155
|
+
blockTime: 0.25, // ~250ms
|
|
156
|
+
requiredConfirmations: 1,
|
|
157
|
+
nativeToken: 'ETH',
|
|
158
|
+
gasMultiplier: 0.05,
|
|
159
|
+
},
|
|
160
|
+
'arbitrum-sepolia': {
|
|
161
|
+
network: 'arbitrum-sepolia',
|
|
162
|
+
chainId: EVM_CHAIN_IDS['arbitrum-sepolia'],
|
|
163
|
+
rpcUrl: ETHEREUM_RPC_ENDPOINTS['arbitrum-sepolia'],
|
|
164
|
+
explorerUrl: ETHEREUM_EXPLORER_URLS['arbitrum-sepolia'],
|
|
165
|
+
explorerApiUrl: 'https://api-sepolia.arbiscan.io/api',
|
|
166
|
+
isTestnet: true,
|
|
167
|
+
blockTime: 0.25,
|
|
168
|
+
requiredConfirmations: 1,
|
|
169
|
+
nativeToken: 'ETH',
|
|
170
|
+
gasMultiplier: 0.05,
|
|
171
|
+
},
|
|
172
|
+
optimism: {
|
|
173
|
+
network: 'optimism',
|
|
174
|
+
chainId: EVM_CHAIN_IDS.optimism,
|
|
175
|
+
rpcUrl: ETHEREUM_RPC_ENDPOINTS.optimism,
|
|
176
|
+
explorerUrl: ETHEREUM_EXPLORER_URLS.optimism,
|
|
177
|
+
explorerApiUrl: 'https://api-optimistic.etherscan.io/api',
|
|
178
|
+
isTestnet: false,
|
|
179
|
+
blockTime: 2,
|
|
180
|
+
requiredConfirmations: 1,
|
|
181
|
+
nativeToken: 'ETH',
|
|
182
|
+
gasMultiplier: 0.1,
|
|
183
|
+
},
|
|
184
|
+
'optimism-sepolia': {
|
|
185
|
+
network: 'optimism-sepolia',
|
|
186
|
+
chainId: EVM_CHAIN_IDS['optimism-sepolia'],
|
|
187
|
+
rpcUrl: ETHEREUM_RPC_ENDPOINTS['optimism-sepolia'],
|
|
188
|
+
explorerUrl: ETHEREUM_EXPLORER_URLS['optimism-sepolia'],
|
|
189
|
+
explorerApiUrl: 'https://api-sepolia-optimistic.etherscan.io/api',
|
|
190
|
+
isTestnet: true,
|
|
191
|
+
blockTime: 2,
|
|
192
|
+
requiredConfirmations: 1,
|
|
193
|
+
nativeToken: 'ETH',
|
|
194
|
+
gasMultiplier: 0.1,
|
|
195
|
+
},
|
|
196
|
+
polygon: {
|
|
197
|
+
network: 'polygon',
|
|
198
|
+
chainId: EVM_CHAIN_IDS.polygon,
|
|
199
|
+
rpcUrl: ETHEREUM_RPC_ENDPOINTS.polygon,
|
|
200
|
+
explorerUrl: ETHEREUM_EXPLORER_URLS.polygon,
|
|
201
|
+
explorerApiUrl: 'https://api.polygonscan.com/api',
|
|
202
|
+
isTestnet: false,
|
|
203
|
+
blockTime: 2,
|
|
204
|
+
requiredConfirmations: 32,
|
|
205
|
+
nativeToken: 'MATIC',
|
|
206
|
+
gasMultiplier: 1.0,
|
|
207
|
+
},
|
|
208
|
+
zksync: {
|
|
209
|
+
network: 'zksync',
|
|
210
|
+
chainId: EVM_CHAIN_IDS.zksync,
|
|
211
|
+
rpcUrl: ETHEREUM_RPC_ENDPOINTS.zksync,
|
|
212
|
+
explorerUrl: ETHEREUM_EXPLORER_URLS.zksync,
|
|
213
|
+
explorerApiUrl: 'https://api-era.zksync.network/api',
|
|
214
|
+
isTestnet: false,
|
|
215
|
+
blockTime: 1,
|
|
216
|
+
requiredConfirmations: 1,
|
|
217
|
+
nativeToken: 'ETH',
|
|
218
|
+
gasMultiplier: 0.1,
|
|
219
|
+
},
|
|
220
|
+
scroll: {
|
|
221
|
+
network: 'scroll',
|
|
222
|
+
chainId: EVM_CHAIN_IDS.scroll,
|
|
223
|
+
rpcUrl: ETHEREUM_RPC_ENDPOINTS.scroll,
|
|
224
|
+
explorerUrl: ETHEREUM_EXPLORER_URLS.scroll,
|
|
225
|
+
explorerApiUrl: 'https://api.scrollscan.com/api',
|
|
226
|
+
isTestnet: false,
|
|
227
|
+
blockTime: 3,
|
|
228
|
+
requiredConfirmations: 1,
|
|
229
|
+
nativeToken: 'ETH',
|
|
230
|
+
gasMultiplier: 0.1,
|
|
231
|
+
},
|
|
232
|
+
linea: {
|
|
233
|
+
network: 'linea',
|
|
234
|
+
chainId: EVM_CHAIN_IDS.linea,
|
|
235
|
+
rpcUrl: ETHEREUM_RPC_ENDPOINTS.linea,
|
|
236
|
+
explorerUrl: ETHEREUM_EXPLORER_URLS.linea,
|
|
237
|
+
explorerApiUrl: 'https://api.lineascan.build/api',
|
|
238
|
+
isTestnet: false,
|
|
239
|
+
blockTime: 2,
|
|
240
|
+
requiredConfirmations: 1,
|
|
241
|
+
nativeToken: 'ETH',
|
|
242
|
+
gasMultiplier: 0.1,
|
|
243
|
+
},
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
// ─── Utility Functions ────────────────────────────────────────────────────────
|
|
247
|
+
|
|
248
|
+
/**
|
|
249
|
+
* Get L2 network configuration
|
|
250
|
+
*
|
|
251
|
+
* @param network - Network identifier
|
|
252
|
+
* @returns L2 network config or undefined if not found
|
|
253
|
+
*
|
|
254
|
+
* @example
|
|
255
|
+
* ```typescript
|
|
256
|
+
* const config = getL2Config('base')
|
|
257
|
+
* console.log(config.gasMultiplier) // 0.1
|
|
258
|
+
* ```
|
|
259
|
+
*/
|
|
260
|
+
export function getL2Config(network: EthereumNetwork): L2NetworkConfig | undefined {
|
|
261
|
+
return L2_NETWORK_CONFIGS[network]
|
|
262
|
+
}
|
|
263
|
+
|
|
264
|
+
/**
|
|
265
|
+
* Get all supported L2 networks
|
|
266
|
+
*
|
|
267
|
+
* @param includeTestnets - Whether to include testnets
|
|
268
|
+
* @returns Array of L2 network configs
|
|
269
|
+
*/
|
|
270
|
+
export function getSupportedL2s(includeTestnets: boolean = false): L2NetworkConfig[] {
|
|
271
|
+
return Object.values(L2_NETWORK_CONFIGS).filter(
|
|
272
|
+
(config) => includeTestnets || !config.isTestnet
|
|
273
|
+
)
|
|
274
|
+
}
|
|
275
|
+
|
|
276
|
+
/**
|
|
277
|
+
* Get L2 config by chain ID
|
|
278
|
+
*
|
|
279
|
+
* @param chainId - EVM chain ID
|
|
280
|
+
* @returns L2 network config or undefined
|
|
281
|
+
*/
|
|
282
|
+
export function getL2ConfigByChainId(chainId: number): L2NetworkConfig | undefined {
|
|
283
|
+
return Object.values(L2_NETWORK_CONFIGS).find(
|
|
284
|
+
(config) => config.chainId === chainId
|
|
285
|
+
)
|
|
286
|
+
}
|
|
287
|
+
|
|
288
|
+
/**
|
|
289
|
+
* Check if a chain ID is a supported L2
|
|
290
|
+
*
|
|
291
|
+
* @param chainId - EVM chain ID
|
|
292
|
+
* @returns Whether the chain is a supported L2
|
|
293
|
+
*/
|
|
294
|
+
export function isSupportedL2(chainId: number): boolean {
|
|
295
|
+
return getL2ConfigByChainId(chainId) !== undefined
|
|
296
|
+
}
|
|
297
|
+
|
|
298
|
+
// ─── Deployment Helpers ───────────────────────────────────────────────────────
|
|
299
|
+
|
|
300
|
+
/**
|
|
301
|
+
* Generate deployment transaction data
|
|
302
|
+
*
|
|
303
|
+
* @param config - Deployment configuration
|
|
304
|
+
* @returns Transaction data for deployment
|
|
305
|
+
*
|
|
306
|
+
* @example
|
|
307
|
+
* ```typescript
|
|
308
|
+
* const txData = generateDeploymentTx({
|
|
309
|
+
* bytecode: '0x...',
|
|
310
|
+
* constructorArgs: '0x...',
|
|
311
|
+
* })
|
|
312
|
+
* // Sign and send txData with your wallet
|
|
313
|
+
* ```
|
|
314
|
+
*/
|
|
315
|
+
export function generateDeploymentTx(config: DeploymentConfig): {
|
|
316
|
+
data: HexString
|
|
317
|
+
value: bigint
|
|
318
|
+
gasLimit?: bigint
|
|
319
|
+
} {
|
|
320
|
+
// Concatenate bytecode with constructor arguments
|
|
321
|
+
const data = config.constructorArgs
|
|
322
|
+
? `${config.bytecode}${config.constructorArgs.slice(2)}` as HexString
|
|
323
|
+
: config.bytecode
|
|
324
|
+
|
|
325
|
+
return {
|
|
326
|
+
data,
|
|
327
|
+
value: config.value ?? 0n,
|
|
328
|
+
gasLimit: config.gasLimit,
|
|
329
|
+
}
|
|
330
|
+
}
|
|
331
|
+
|
|
332
|
+
/**
|
|
333
|
+
* Estimate deployment gas for an L2
|
|
334
|
+
*
|
|
335
|
+
* @param network - Target L2 network
|
|
336
|
+
* @param bytecodeLength - Length of bytecode in bytes
|
|
337
|
+
* @param hasConstructor - Whether contract has constructor with args
|
|
338
|
+
* @returns Estimated gas limit
|
|
339
|
+
*/
|
|
340
|
+
export function estimateDeploymentGas(
|
|
341
|
+
_network: EthereumNetwork,
|
|
342
|
+
bytecodeLength: number,
|
|
343
|
+
hasConstructor: boolean = false
|
|
344
|
+
): bigint {
|
|
345
|
+
// Base deployment cost: 21000 (tx) + 32000 (create) + 200 per byte
|
|
346
|
+
const baseGas = 21000n + 32000n + BigInt(bytecodeLength * 200)
|
|
347
|
+
|
|
348
|
+
// Add constructor overhead if needed
|
|
349
|
+
const constructorGas = hasConstructor ? 50000n : 0n
|
|
350
|
+
|
|
351
|
+
// L2s have lower gas costs, but we don't reduce the limit
|
|
352
|
+
// Just the price is lower, limit should be safe
|
|
353
|
+
return baseGas + constructorGas
|
|
354
|
+
}
|
|
355
|
+
|
|
356
|
+
/**
|
|
357
|
+
* Get explorer verification URL
|
|
358
|
+
*
|
|
359
|
+
* @param address - Contract address
|
|
360
|
+
* @param network - Network
|
|
361
|
+
* @returns URL to verify contract on explorer
|
|
362
|
+
*/
|
|
363
|
+
export function getVerificationUrl(
|
|
364
|
+
address: HexString,
|
|
365
|
+
network: EthereumNetwork
|
|
366
|
+
): string {
|
|
367
|
+
const config = getL2Config(network)
|
|
368
|
+
if (!config) {
|
|
369
|
+
const explorerUrl = ETHEREUM_EXPLORER_URLS[network] ?? 'https://etherscan.io'
|
|
370
|
+
return `${explorerUrl}/verifyContract?a=${address}`
|
|
371
|
+
}
|
|
372
|
+
return `${config.explorerUrl}/verifyContract?a=${address}`
|
|
373
|
+
}
|
|
374
|
+
|
|
375
|
+
/**
|
|
376
|
+
* Get contract URL on block explorer
|
|
377
|
+
*
|
|
378
|
+
* @param address - Contract address
|
|
379
|
+
* @param network - Network
|
|
380
|
+
* @returns URL to contract on explorer
|
|
381
|
+
*/
|
|
382
|
+
export function getContractUrl(
|
|
383
|
+
address: HexString,
|
|
384
|
+
network: EthereumNetwork
|
|
385
|
+
): string {
|
|
386
|
+
const config = getL2Config(network)
|
|
387
|
+
const explorerUrl = config?.explorerUrl ?? ETHEREUM_EXPLORER_URLS[network]
|
|
388
|
+
return `${explorerUrl}/address/${address}#code`
|
|
389
|
+
}
|
|
390
|
+
|
|
391
|
+
// ─── Verification Helpers ─────────────────────────────────────────────────────
|
|
392
|
+
|
|
393
|
+
/**
|
|
394
|
+
* Build verification request body for Etherscan-compatible API
|
|
395
|
+
*
|
|
396
|
+
* @param request - Verification request details
|
|
397
|
+
* @returns URL-encoded form body
|
|
398
|
+
*/
|
|
399
|
+
export function buildVerificationBody(request: VerificationRequest): string {
|
|
400
|
+
const config = getL2Config(request.network)
|
|
401
|
+
const chainId = config?.chainId ?? EVM_CHAIN_IDS[request.network]
|
|
402
|
+
|
|
403
|
+
const params = new URLSearchParams({
|
|
404
|
+
apikey: '', // User must provide their own API key
|
|
405
|
+
module: 'contract',
|
|
406
|
+
action: 'verifysourcecode',
|
|
407
|
+
chainId: chainId.toString(),
|
|
408
|
+
sourceCode: request.sourceCode,
|
|
409
|
+
codeformat: 'solidity-single-file',
|
|
410
|
+
contractname: request.contractName,
|
|
411
|
+
compilerversion: request.compilerVersion,
|
|
412
|
+
optimizationUsed: request.optimization ? '1' : '0',
|
|
413
|
+
runs: (request.runs ?? 200).toString(),
|
|
414
|
+
constructorArguements: request.constructorArguments?.slice(2) ?? '',
|
|
415
|
+
})
|
|
416
|
+
|
|
417
|
+
return params.toString()
|
|
418
|
+
}
|
|
419
|
+
|
|
420
|
+
/**
|
|
421
|
+
* Check verification status on explorer
|
|
422
|
+
*
|
|
423
|
+
* @param guid - Verification GUID
|
|
424
|
+
* @param network - Network
|
|
425
|
+
* @param apiKey - Explorer API key
|
|
426
|
+
* @returns Verification status
|
|
427
|
+
*/
|
|
428
|
+
export async function checkVerificationStatus(
|
|
429
|
+
guid: string,
|
|
430
|
+
network: EthereumNetwork,
|
|
431
|
+
apiKey: string
|
|
432
|
+
): Promise<{ status: 'pending' | 'success' | 'failed'; message: string }> {
|
|
433
|
+
const config = getL2Config(network)
|
|
434
|
+
const apiUrl = config?.explorerApiUrl ?? 'https://api.etherscan.io/api'
|
|
435
|
+
|
|
436
|
+
const params = new URLSearchParams({
|
|
437
|
+
apikey: apiKey,
|
|
438
|
+
module: 'contract',
|
|
439
|
+
action: 'checkverifystatus',
|
|
440
|
+
guid,
|
|
441
|
+
})
|
|
442
|
+
|
|
443
|
+
const response = await fetch(`${apiUrl}?${params}`)
|
|
444
|
+
const data = await response.json()
|
|
445
|
+
|
|
446
|
+
if (data.status === '1') {
|
|
447
|
+
return { status: 'success', message: data.result }
|
|
448
|
+
} else if (data.result === 'Pending in queue') {
|
|
449
|
+
return { status: 'pending', message: data.result }
|
|
450
|
+
} else {
|
|
451
|
+
return { status: 'failed', message: data.result }
|
|
452
|
+
}
|
|
453
|
+
}
|
|
454
|
+
|
|
455
|
+
// ─── Multi-L2 Deployment ──────────────────────────────────────────────────────
|
|
456
|
+
|
|
457
|
+
/**
|
|
458
|
+
* Deployment status for multi-L2 deployment
|
|
459
|
+
*/
|
|
460
|
+
export interface MultiL2DeploymentStatus {
|
|
461
|
+
/** Network being deployed to */
|
|
462
|
+
network: EthereumNetwork
|
|
463
|
+
/** Deployment status */
|
|
464
|
+
status: 'pending' | 'deploying' | 'verifying' | 'complete' | 'failed'
|
|
465
|
+
/** Deployment result if successful */
|
|
466
|
+
result?: DeploymentResult
|
|
467
|
+
/** Error if failed */
|
|
468
|
+
error?: string
|
|
469
|
+
/** Verification status */
|
|
470
|
+
verified?: boolean
|
|
471
|
+
}
|
|
472
|
+
|
|
473
|
+
/**
|
|
474
|
+
* Create a multi-L2 deployment plan
|
|
475
|
+
*
|
|
476
|
+
* @param networks - Target networks (defaults to Tier 1: Base, Arbitrum, Optimism)
|
|
477
|
+
* @param includeTestnets - Whether to include testnet deployments
|
|
478
|
+
* @returns Deployment plan with network configs
|
|
479
|
+
*
|
|
480
|
+
* @example
|
|
481
|
+
* ```typescript
|
|
482
|
+
* const plan = createDeploymentPlan(['base', 'arbitrum', 'optimism'])
|
|
483
|
+
* // plan.forEach(network => deployTo(network))
|
|
484
|
+
* ```
|
|
485
|
+
*/
|
|
486
|
+
export function createDeploymentPlan(
|
|
487
|
+
networks?: EthereumNetwork[],
|
|
488
|
+
includeTestnets: boolean = true
|
|
489
|
+
): L2NetworkConfig[] {
|
|
490
|
+
// Default Tier 1 L2s (90%+ market share)
|
|
491
|
+
const tier1Networks: EthereumNetwork[] = [
|
|
492
|
+
'base',
|
|
493
|
+
'arbitrum',
|
|
494
|
+
'optimism',
|
|
495
|
+
]
|
|
496
|
+
|
|
497
|
+
const targetNetworks = networks ?? tier1Networks
|
|
498
|
+
const configs: L2NetworkConfig[] = []
|
|
499
|
+
|
|
500
|
+
for (const network of targetNetworks) {
|
|
501
|
+
const config = getL2Config(network)
|
|
502
|
+
if (config) {
|
|
503
|
+
configs.push(config)
|
|
504
|
+
|
|
505
|
+
// Add corresponding testnet if requested
|
|
506
|
+
if (includeTestnets) {
|
|
507
|
+
const testnetNetwork = `${network}-sepolia` as EthereumNetwork
|
|
508
|
+
const testnetConfig = getL2Config(testnetNetwork)
|
|
509
|
+
if (testnetConfig) {
|
|
510
|
+
configs.push(testnetConfig)
|
|
511
|
+
}
|
|
512
|
+
}
|
|
513
|
+
}
|
|
514
|
+
}
|
|
515
|
+
|
|
516
|
+
return configs
|
|
517
|
+
}
|
|
518
|
+
|
|
519
|
+
/**
|
|
520
|
+
* Get recommended deployment order (testnets first)
|
|
521
|
+
*
|
|
522
|
+
* @param networks - Networks to deploy to
|
|
523
|
+
* @returns Ordered array of networks
|
|
524
|
+
*/
|
|
525
|
+
export function getDeploymentOrder(networks: L2NetworkConfig[]): L2NetworkConfig[] {
|
|
526
|
+
// Sort: testnets first, then by gas multiplier (cheapest first)
|
|
527
|
+
return [...networks].sort((a, b) => {
|
|
528
|
+
if (a.isTestnet && !b.isTestnet) return -1
|
|
529
|
+
if (!a.isTestnet && b.isTestnet) return 1
|
|
530
|
+
return a.gasMultiplier - b.gasMultiplier
|
|
531
|
+
})
|
|
532
|
+
}
|
|
533
|
+
|
|
534
|
+
// ─── Gas Price Comparison ─────────────────────────────────────────────────────
|
|
535
|
+
|
|
536
|
+
/**
|
|
537
|
+
* L2 gas price comparison
|
|
538
|
+
*/
|
|
539
|
+
export interface L2GasComparison {
|
|
540
|
+
network: EthereumNetwork
|
|
541
|
+
estimatedGasPrice: bigint
|
|
542
|
+
estimatedDeployCost: bigint
|
|
543
|
+
relativeToMainnet: number // 0.1 = 10% of mainnet cost
|
|
544
|
+
}
|
|
545
|
+
|
|
546
|
+
/**
|
|
547
|
+
* Compare gas prices across L2s
|
|
548
|
+
*
|
|
549
|
+
* @param bytecodeLength - Contract bytecode length
|
|
550
|
+
* @param mainnetGasPrice - Current mainnet gas price in wei
|
|
551
|
+
* @returns Gas price comparison for each L2
|
|
552
|
+
*
|
|
553
|
+
* @example
|
|
554
|
+
* ```typescript
|
|
555
|
+
* const comparison = compareL2GasPrices(10000, 30n * 10n**9n)
|
|
556
|
+
* // Find cheapest L2 for deployment
|
|
557
|
+
* const cheapest = comparison.sort((a, b) =>
|
|
558
|
+
* Number(a.estimatedDeployCost - b.estimatedDeployCost)
|
|
559
|
+
* )[0]
|
|
560
|
+
* ```
|
|
561
|
+
*/
|
|
562
|
+
export function compareL2GasPrices(
|
|
563
|
+
bytecodeLength: number,
|
|
564
|
+
mainnetGasPrice: bigint
|
|
565
|
+
): L2GasComparison[] {
|
|
566
|
+
const gasLimit = estimateDeploymentGas('mainnet', bytecodeLength)
|
|
567
|
+
|
|
568
|
+
return getSupportedL2s(false).map((config) => {
|
|
569
|
+
const l2GasPrice = BigInt(Math.floor(Number(mainnetGasPrice) * config.gasMultiplier))
|
|
570
|
+
const l2Cost = gasLimit * l2GasPrice
|
|
571
|
+
|
|
572
|
+
return {
|
|
573
|
+
network: config.network,
|
|
574
|
+
estimatedGasPrice: l2GasPrice,
|
|
575
|
+
estimatedDeployCost: l2Cost,
|
|
576
|
+
relativeToMainnet: config.gasMultiplier,
|
|
577
|
+
}
|
|
578
|
+
})
|
|
579
|
+
}
|
|
580
|
+
|
|
581
|
+
export default {
|
|
582
|
+
L2_NETWORK_CONFIGS,
|
|
583
|
+
getL2Config,
|
|
584
|
+
getSupportedL2s,
|
|
585
|
+
getL2ConfigByChainId,
|
|
586
|
+
isSupportedL2,
|
|
587
|
+
generateDeploymentTx,
|
|
588
|
+
estimateDeploymentGas,
|
|
589
|
+
getVerificationUrl,
|
|
590
|
+
getContractUrl,
|
|
591
|
+
buildVerificationBody,
|
|
592
|
+
checkVerificationStatus,
|
|
593
|
+
createDeploymentPlan,
|
|
594
|
+
getDeploymentOrder,
|
|
595
|
+
compareL2GasPrices,
|
|
596
|
+
}
|