@nerochain/mpc-sdk 0.1.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/LICENSE +21 -0
- package/README.md +91 -0
- package/dist/aa.d.mts +185 -0
- package/dist/aa.d.ts +185 -0
- package/dist/aa.js +520 -0
- package/dist/aa.js.map +1 -0
- package/dist/aa.mjs +511 -0
- package/dist/aa.mjs.map +1 -0
- package/dist/chain-manager-C3eHsVt9.d.mts +98 -0
- package/dist/chain-manager-C3eHsVt9.d.ts +98 -0
- package/dist/chains.d.mts +17 -0
- package/dist/chains.d.ts +17 -0
- package/dist/chains.js +331 -0
- package/dist/chains.js.map +1 -0
- package/dist/chains.mjs +315 -0
- package/dist/chains.mjs.map +1 -0
- package/dist/index.d.mts +656 -0
- package/dist/index.d.ts +656 -0
- package/dist/index.js +6627 -0
- package/dist/index.js.map +1 -0
- package/dist/index.mjs +6502 -0
- package/dist/index.mjs.map +1 -0
- package/dist/modal.d.mts +68 -0
- package/dist/modal.d.ts +68 -0
- package/dist/modal.js +4867 -0
- package/dist/modal.js.map +1 -0
- package/dist/modal.mjs +4850 -0
- package/dist/modal.mjs.map +1 -0
- package/dist/nero-sdk-Cm8gzHZJ.d.mts +684 -0
- package/dist/nero-sdk-IhuTBrXZ.d.ts +684 -0
- package/dist/no-modal.d.mts +56 -0
- package/dist/no-modal.d.ts +56 -0
- package/dist/no-modal.js +4060 -0
- package/dist/no-modal.js.map +1 -0
- package/dist/no-modal.mjs +4041 -0
- package/dist/no-modal.mjs.map +1 -0
- package/dist/react.d.mts +28 -0
- package/dist/react.d.ts +28 -0
- package/dist/react.js +4033 -0
- package/dist/react.js.map +1 -0
- package/dist/react.mjs +4016 -0
- package/dist/react.mjs.map +1 -0
- package/dist/useNeroWallet-PZh940vV.d.ts +164 -0
- package/dist/useNeroWallet-awIYqM6e.d.mts +164 -0
- package/package.json +126 -0
package/dist/chains.mjs
ADDED
|
@@ -0,0 +1,315 @@
|
|
|
1
|
+
// src/chains/configs.ts
|
|
2
|
+
var NERO_TESTNET = {
|
|
3
|
+
chainId: 689,
|
|
4
|
+
chainName: "nero-testnet",
|
|
5
|
+
displayName: "NERO Testnet",
|
|
6
|
+
nativeCurrency: {
|
|
7
|
+
name: "NERO",
|
|
8
|
+
symbol: "NERO",
|
|
9
|
+
decimals: 18
|
|
10
|
+
},
|
|
11
|
+
rpcUrls: ["https://testnet.nerochain.io"],
|
|
12
|
+
blockExplorerUrls: ["https://testnetscan.nerochain.io"],
|
|
13
|
+
isTestnet: true,
|
|
14
|
+
bundlerUrl: "https://bundler.testnet.nerochain.io",
|
|
15
|
+
paymasterUrl: "https://paymaster.testnet.nerochain.io",
|
|
16
|
+
entryPointAddress: "0x5FF137D4b0FDCD49DcA30c7CF57E578a026d2789",
|
|
17
|
+
simpleAccountFactoryAddress: "0x9406Cc6185a346906296840746125a0E44976454"
|
|
18
|
+
};
|
|
19
|
+
var NERO_MAINNET = {
|
|
20
|
+
chainId: 1689,
|
|
21
|
+
chainName: "nero-mainnet",
|
|
22
|
+
displayName: "NERO Mainnet",
|
|
23
|
+
nativeCurrency: {
|
|
24
|
+
name: "NERO",
|
|
25
|
+
symbol: "NERO",
|
|
26
|
+
decimals: 18
|
|
27
|
+
},
|
|
28
|
+
rpcUrls: ["https://rpc.nerochain.io"],
|
|
29
|
+
blockExplorerUrls: ["https://scan.nerochain.io"],
|
|
30
|
+
isTestnet: false,
|
|
31
|
+
bundlerUrl: "https://bundler.nerochain.io",
|
|
32
|
+
paymasterUrl: "https://paymaster.nerochain.io",
|
|
33
|
+
entryPointAddress: "0x5FF137D4b0FDCD49DcA30c7CF57E578a026d2789",
|
|
34
|
+
simpleAccountFactoryAddress: "0x9406Cc6185a346906296840746125a0E44976454"
|
|
35
|
+
};
|
|
36
|
+
var ETHEREUM_MAINNET = {
|
|
37
|
+
chainId: 1,
|
|
38
|
+
chainName: "ethereum",
|
|
39
|
+
displayName: "Ethereum",
|
|
40
|
+
nativeCurrency: {
|
|
41
|
+
name: "Ether",
|
|
42
|
+
symbol: "ETH",
|
|
43
|
+
decimals: 18
|
|
44
|
+
},
|
|
45
|
+
rpcUrls: ["https://eth.llamarpc.com", "https://rpc.ankr.com/eth"],
|
|
46
|
+
blockExplorerUrls: ["https://etherscan.io"],
|
|
47
|
+
isTestnet: false,
|
|
48
|
+
entryPointAddress: "0x5FF137D4b0FDCD49DcA30c7CF57E578a026d2789"
|
|
49
|
+
};
|
|
50
|
+
var ETHEREUM_SEPOLIA = {
|
|
51
|
+
chainId: 11155111,
|
|
52
|
+
chainName: "sepolia",
|
|
53
|
+
displayName: "Sepolia Testnet",
|
|
54
|
+
nativeCurrency: {
|
|
55
|
+
name: "Sepolia Ether",
|
|
56
|
+
symbol: "ETH",
|
|
57
|
+
decimals: 18
|
|
58
|
+
},
|
|
59
|
+
rpcUrls: ["https://rpc.sepolia.org", "https://rpc.ankr.com/eth_sepolia"],
|
|
60
|
+
blockExplorerUrls: ["https://sepolia.etherscan.io"],
|
|
61
|
+
isTestnet: true,
|
|
62
|
+
entryPointAddress: "0x5FF137D4b0FDCD49DcA30c7CF57E578a026d2789"
|
|
63
|
+
};
|
|
64
|
+
var POLYGON_MAINNET = {
|
|
65
|
+
chainId: 137,
|
|
66
|
+
chainName: "polygon",
|
|
67
|
+
displayName: "Polygon",
|
|
68
|
+
nativeCurrency: {
|
|
69
|
+
name: "MATIC",
|
|
70
|
+
symbol: "MATIC",
|
|
71
|
+
decimals: 18
|
|
72
|
+
},
|
|
73
|
+
rpcUrls: ["https://polygon-rpc.com", "https://rpc.ankr.com/polygon"],
|
|
74
|
+
blockExplorerUrls: ["https://polygonscan.com"],
|
|
75
|
+
isTestnet: false,
|
|
76
|
+
entryPointAddress: "0x5FF137D4b0FDCD49DcA30c7CF57E578a026d2789"
|
|
77
|
+
};
|
|
78
|
+
var ARBITRUM_ONE = {
|
|
79
|
+
chainId: 42161,
|
|
80
|
+
chainName: "arbitrum",
|
|
81
|
+
displayName: "Arbitrum One",
|
|
82
|
+
nativeCurrency: {
|
|
83
|
+
name: "Ether",
|
|
84
|
+
symbol: "ETH",
|
|
85
|
+
decimals: 18
|
|
86
|
+
},
|
|
87
|
+
rpcUrls: ["https://arb1.arbitrum.io/rpc", "https://rpc.ankr.com/arbitrum"],
|
|
88
|
+
blockExplorerUrls: ["https://arbiscan.io"],
|
|
89
|
+
isTestnet: false,
|
|
90
|
+
entryPointAddress: "0x5FF137D4b0FDCD49DcA30c7CF57E578a026d2789"
|
|
91
|
+
};
|
|
92
|
+
var BASE_MAINNET = {
|
|
93
|
+
chainId: 8453,
|
|
94
|
+
chainName: "base",
|
|
95
|
+
displayName: "Base",
|
|
96
|
+
nativeCurrency: {
|
|
97
|
+
name: "Ether",
|
|
98
|
+
symbol: "ETH",
|
|
99
|
+
decimals: 18
|
|
100
|
+
},
|
|
101
|
+
rpcUrls: ["https://mainnet.base.org", "https://base.llamarpc.com"],
|
|
102
|
+
blockExplorerUrls: ["https://basescan.org"],
|
|
103
|
+
isTestnet: false,
|
|
104
|
+
entryPointAddress: "0x5FF137D4b0FDCD49DcA30c7CF57E578a026d2789"
|
|
105
|
+
};
|
|
106
|
+
var BUILTIN_CHAINS = /* @__PURE__ */ new Map([
|
|
107
|
+
[NERO_TESTNET.chainId, NERO_TESTNET],
|
|
108
|
+
[NERO_MAINNET.chainId, NERO_MAINNET],
|
|
109
|
+
[ETHEREUM_MAINNET.chainId, ETHEREUM_MAINNET],
|
|
110
|
+
[ETHEREUM_SEPOLIA.chainId, ETHEREUM_SEPOLIA],
|
|
111
|
+
[POLYGON_MAINNET.chainId, POLYGON_MAINNET],
|
|
112
|
+
[ARBITRUM_ONE.chainId, ARBITRUM_ONE],
|
|
113
|
+
[BASE_MAINNET.chainId, BASE_MAINNET]
|
|
114
|
+
]);
|
|
115
|
+
function getChainConfig(chainId) {
|
|
116
|
+
return BUILTIN_CHAINS.get(chainId);
|
|
117
|
+
}
|
|
118
|
+
function getAllChains() {
|
|
119
|
+
return Array.from(BUILTIN_CHAINS.values());
|
|
120
|
+
}
|
|
121
|
+
function getTestnetChains() {
|
|
122
|
+
return getAllChains().filter((c) => c.isTestnet);
|
|
123
|
+
}
|
|
124
|
+
function getMainnetChains() {
|
|
125
|
+
return getAllChains().filter((c) => !c.isTestnet);
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
// src/chains/chain-manager.ts
|
|
129
|
+
var ChainManager = class {
|
|
130
|
+
constructor(initialChainId = 689) {
|
|
131
|
+
this.customChains = /* @__PURE__ */ new Map();
|
|
132
|
+
this.listeners = /* @__PURE__ */ new Set();
|
|
133
|
+
this.rpcConnections = /* @__PURE__ */ new Map();
|
|
134
|
+
this.currentChainId = initialChainId;
|
|
135
|
+
}
|
|
136
|
+
get chainId() {
|
|
137
|
+
return this.currentChainId;
|
|
138
|
+
}
|
|
139
|
+
get chainConfig() {
|
|
140
|
+
return this.getConfig(this.currentChainId);
|
|
141
|
+
}
|
|
142
|
+
getConfig(chainId) {
|
|
143
|
+
return getChainConfig(chainId) ?? this.customChains.get(chainId);
|
|
144
|
+
}
|
|
145
|
+
getSupportedChains() {
|
|
146
|
+
const builtins = Array.from(BUILTIN_CHAINS.values());
|
|
147
|
+
const custom = Array.from(this.customChains.values());
|
|
148
|
+
return [...builtins, ...custom];
|
|
149
|
+
}
|
|
150
|
+
getSupportedChainIds() {
|
|
151
|
+
return this.getSupportedChains().map((c) => c.chainId);
|
|
152
|
+
}
|
|
153
|
+
isChainSupported(chainId) {
|
|
154
|
+
return this.getConfig(chainId) !== void 0;
|
|
155
|
+
}
|
|
156
|
+
addChain(config) {
|
|
157
|
+
this.customChains.set(config.chainId, config);
|
|
158
|
+
}
|
|
159
|
+
removeChain(chainId) {
|
|
160
|
+
if (BUILTIN_CHAINS.has(chainId)) {
|
|
161
|
+
return false;
|
|
162
|
+
}
|
|
163
|
+
return this.customChains.delete(chainId);
|
|
164
|
+
}
|
|
165
|
+
async switchChain(chainId) {
|
|
166
|
+
const config = this.getConfig(chainId);
|
|
167
|
+
if (!config) {
|
|
168
|
+
throw new Error(`Chain ${chainId} is not supported`);
|
|
169
|
+
}
|
|
170
|
+
const previousChainId = this.currentChainId;
|
|
171
|
+
this.currentChainId = chainId;
|
|
172
|
+
if (previousChainId !== chainId) {
|
|
173
|
+
this.notifyListeners(chainId, config);
|
|
174
|
+
}
|
|
175
|
+
return config;
|
|
176
|
+
}
|
|
177
|
+
onChainChange(listener) {
|
|
178
|
+
this.listeners.add(listener);
|
|
179
|
+
return () => this.listeners.delete(listener);
|
|
180
|
+
}
|
|
181
|
+
notifyListeners(chainId, config) {
|
|
182
|
+
for (const listener of this.listeners) {
|
|
183
|
+
try {
|
|
184
|
+
listener(chainId, config);
|
|
185
|
+
} catch {
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
getRpcConnection(chainId) {
|
|
190
|
+
const targetChainId = chainId ?? this.currentChainId;
|
|
191
|
+
let connection = this.rpcConnections.get(targetChainId);
|
|
192
|
+
if (!connection) {
|
|
193
|
+
const config = this.getConfig(targetChainId);
|
|
194
|
+
if (!config) {
|
|
195
|
+
throw new Error(`Chain ${targetChainId} is not supported`);
|
|
196
|
+
}
|
|
197
|
+
connection = new RpcConnection(config);
|
|
198
|
+
this.rpcConnections.set(targetChainId, connection);
|
|
199
|
+
}
|
|
200
|
+
return connection;
|
|
201
|
+
}
|
|
202
|
+
getTestnets() {
|
|
203
|
+
return this.getSupportedChains().filter((c) => c.isTestnet);
|
|
204
|
+
}
|
|
205
|
+
getMainnets() {
|
|
206
|
+
return this.getSupportedChains().filter((c) => !c.isTestnet);
|
|
207
|
+
}
|
|
208
|
+
};
|
|
209
|
+
var RpcConnection = class {
|
|
210
|
+
constructor(config) {
|
|
211
|
+
this.currentRpcIndex = 0;
|
|
212
|
+
this.config = config;
|
|
213
|
+
}
|
|
214
|
+
get chainId() {
|
|
215
|
+
return this.config.chainId;
|
|
216
|
+
}
|
|
217
|
+
get rpcUrl() {
|
|
218
|
+
return this.config.rpcUrls[this.currentRpcIndex];
|
|
219
|
+
}
|
|
220
|
+
async call(method, params = []) {
|
|
221
|
+
const maxRetries = this.config.rpcUrls.length;
|
|
222
|
+
let lastError = null;
|
|
223
|
+
for (let attempt = 0; attempt < maxRetries; attempt++) {
|
|
224
|
+
try {
|
|
225
|
+
return await this.executeCall(method, params);
|
|
226
|
+
} catch (error) {
|
|
227
|
+
lastError = error;
|
|
228
|
+
this.rotateRpc();
|
|
229
|
+
}
|
|
230
|
+
}
|
|
231
|
+
throw lastError ?? new Error("RPC call failed");
|
|
232
|
+
}
|
|
233
|
+
async executeCall(method, params) {
|
|
234
|
+
const response = await fetch(this.rpcUrl, {
|
|
235
|
+
method: "POST",
|
|
236
|
+
headers: { "Content-Type": "application/json" },
|
|
237
|
+
body: JSON.stringify({
|
|
238
|
+
jsonrpc: "2.0",
|
|
239
|
+
id: Date.now(),
|
|
240
|
+
method,
|
|
241
|
+
params
|
|
242
|
+
})
|
|
243
|
+
});
|
|
244
|
+
if (!response.ok) {
|
|
245
|
+
throw new Error(`RPC request failed: ${response.status}`);
|
|
246
|
+
}
|
|
247
|
+
const data = await response.json();
|
|
248
|
+
if (data.error) {
|
|
249
|
+
throw new Error(data.error.message ?? "RPC error");
|
|
250
|
+
}
|
|
251
|
+
return data.result;
|
|
252
|
+
}
|
|
253
|
+
rotateRpc() {
|
|
254
|
+
this.currentRpcIndex = (this.currentRpcIndex + 1) % this.config.rpcUrls.length;
|
|
255
|
+
}
|
|
256
|
+
async getBlockNumber() {
|
|
257
|
+
const result = await this.call("eth_blockNumber");
|
|
258
|
+
return BigInt(result);
|
|
259
|
+
}
|
|
260
|
+
async getBalance(address) {
|
|
261
|
+
const result = await this.call("eth_getBalance", [
|
|
262
|
+
address,
|
|
263
|
+
"latest"
|
|
264
|
+
]);
|
|
265
|
+
return BigInt(result);
|
|
266
|
+
}
|
|
267
|
+
async getTransactionCount(address) {
|
|
268
|
+
const result = await this.call("eth_getTransactionCount", [
|
|
269
|
+
address,
|
|
270
|
+
"latest"
|
|
271
|
+
]);
|
|
272
|
+
return BigInt(result);
|
|
273
|
+
}
|
|
274
|
+
async getGasPrice() {
|
|
275
|
+
const result = await this.call("eth_gasPrice");
|
|
276
|
+
return BigInt(result);
|
|
277
|
+
}
|
|
278
|
+
async estimateGas(tx) {
|
|
279
|
+
const result = await this.call("eth_estimateGas", [tx]);
|
|
280
|
+
return BigInt(result);
|
|
281
|
+
}
|
|
282
|
+
async getCode(address) {
|
|
283
|
+
return this.call("eth_getCode", [address, "latest"]);
|
|
284
|
+
}
|
|
285
|
+
async sendRawTransaction(signedTx) {
|
|
286
|
+
return this.call("eth_sendRawTransaction", [signedTx]);
|
|
287
|
+
}
|
|
288
|
+
async getTransactionReceipt(hash) {
|
|
289
|
+
return this.call("eth_getTransactionReceipt", [
|
|
290
|
+
hash
|
|
291
|
+
]);
|
|
292
|
+
}
|
|
293
|
+
async waitForTransaction(hash, confirmations = 1, timeout = 6e4) {
|
|
294
|
+
const startTime = Date.now();
|
|
295
|
+
while (Date.now() - startTime < timeout) {
|
|
296
|
+
const receipt = await this.getTransactionReceipt(hash);
|
|
297
|
+
if (receipt?.blockNumber) {
|
|
298
|
+
const currentBlock = await this.getBlockNumber();
|
|
299
|
+
const txBlock = BigInt(receipt.blockNumber);
|
|
300
|
+
if (currentBlock - txBlock >= BigInt(confirmations - 1)) {
|
|
301
|
+
return receipt;
|
|
302
|
+
}
|
|
303
|
+
}
|
|
304
|
+
await new Promise((resolve) => setTimeout(resolve, 2e3));
|
|
305
|
+
}
|
|
306
|
+
throw new Error(`Transaction ${hash} not confirmed within timeout`);
|
|
307
|
+
}
|
|
308
|
+
};
|
|
309
|
+
function createChainManager(initialChainId) {
|
|
310
|
+
return new ChainManager(initialChainId);
|
|
311
|
+
}
|
|
312
|
+
|
|
313
|
+
export { ARBITRUM_ONE, BASE_MAINNET, BUILTIN_CHAINS, ChainManager, ETHEREUM_MAINNET, ETHEREUM_SEPOLIA, NERO_MAINNET, NERO_TESTNET, POLYGON_MAINNET, RpcConnection, createChainManager, getAllChains, getChainConfig, getMainnetChains, getTestnetChains };
|
|
314
|
+
//# sourceMappingURL=chains.mjs.map
|
|
315
|
+
//# sourceMappingURL=chains.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/chains/configs.ts","../src/chains/chain-manager.ts"],"names":[],"mappings":"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","file":"chains.mjs","sourcesContent":["import type { ChainConfig } from \"./types\";\n\nexport const NERO_TESTNET: ChainConfig = {\n\tchainId: 689,\n\tchainName: \"nero-testnet\",\n\tdisplayName: \"NERO Testnet\",\n\tnativeCurrency: {\n\t\tname: \"NERO\",\n\t\tsymbol: \"NERO\",\n\t\tdecimals: 18,\n\t},\n\trpcUrls: [\"https://testnet.nerochain.io\"],\n\tblockExplorerUrls: [\"https://testnetscan.nerochain.io\"],\n\tisTestnet: true,\n\tbundlerUrl: \"https://bundler.testnet.nerochain.io\",\n\tpaymasterUrl: \"https://paymaster.testnet.nerochain.io\",\n\tentryPointAddress: \"0x5FF137D4b0FDCD49DcA30c7CF57E578a026d2789\",\n\tsimpleAccountFactoryAddress: \"0x9406Cc6185a346906296840746125a0E44976454\",\n};\n\nexport const NERO_MAINNET: ChainConfig = {\n\tchainId: 1689,\n\tchainName: \"nero-mainnet\",\n\tdisplayName: \"NERO Mainnet\",\n\tnativeCurrency: {\n\t\tname: \"NERO\",\n\t\tsymbol: \"NERO\",\n\t\tdecimals: 18,\n\t},\n\trpcUrls: [\"https://rpc.nerochain.io\"],\n\tblockExplorerUrls: [\"https://scan.nerochain.io\"],\n\tisTestnet: false,\n\tbundlerUrl: \"https://bundler.nerochain.io\",\n\tpaymasterUrl: \"https://paymaster.nerochain.io\",\n\tentryPointAddress: \"0x5FF137D4b0FDCD49DcA30c7CF57E578a026d2789\",\n\tsimpleAccountFactoryAddress: \"0x9406Cc6185a346906296840746125a0E44976454\",\n};\n\nexport const ETHEREUM_MAINNET: ChainConfig = {\n\tchainId: 1,\n\tchainName: \"ethereum\",\n\tdisplayName: \"Ethereum\",\n\tnativeCurrency: {\n\t\tname: \"Ether\",\n\t\tsymbol: \"ETH\",\n\t\tdecimals: 18,\n\t},\n\trpcUrls: [\"https://eth.llamarpc.com\", \"https://rpc.ankr.com/eth\"],\n\tblockExplorerUrls: [\"https://etherscan.io\"],\n\tisTestnet: false,\n\tentryPointAddress: \"0x5FF137D4b0FDCD49DcA30c7CF57E578a026d2789\",\n};\n\nexport const ETHEREUM_SEPOLIA: ChainConfig = {\n\tchainId: 11155111,\n\tchainName: \"sepolia\",\n\tdisplayName: \"Sepolia Testnet\",\n\tnativeCurrency: {\n\t\tname: \"Sepolia Ether\",\n\t\tsymbol: \"ETH\",\n\t\tdecimals: 18,\n\t},\n\trpcUrls: [\"https://rpc.sepolia.org\", \"https://rpc.ankr.com/eth_sepolia\"],\n\tblockExplorerUrls: [\"https://sepolia.etherscan.io\"],\n\tisTestnet: true,\n\tentryPointAddress: \"0x5FF137D4b0FDCD49DcA30c7CF57E578a026d2789\",\n};\n\nexport const POLYGON_MAINNET: ChainConfig = {\n\tchainId: 137,\n\tchainName: \"polygon\",\n\tdisplayName: \"Polygon\",\n\tnativeCurrency: {\n\t\tname: \"MATIC\",\n\t\tsymbol: \"MATIC\",\n\t\tdecimals: 18,\n\t},\n\trpcUrls: [\"https://polygon-rpc.com\", \"https://rpc.ankr.com/polygon\"],\n\tblockExplorerUrls: [\"https://polygonscan.com\"],\n\tisTestnet: false,\n\tentryPointAddress: \"0x5FF137D4b0FDCD49DcA30c7CF57E578a026d2789\",\n};\n\nexport const ARBITRUM_ONE: ChainConfig = {\n\tchainId: 42161,\n\tchainName: \"arbitrum\",\n\tdisplayName: \"Arbitrum One\",\n\tnativeCurrency: {\n\t\tname: \"Ether\",\n\t\tsymbol: \"ETH\",\n\t\tdecimals: 18,\n\t},\n\trpcUrls: [\"https://arb1.arbitrum.io/rpc\", \"https://rpc.ankr.com/arbitrum\"],\n\tblockExplorerUrls: [\"https://arbiscan.io\"],\n\tisTestnet: false,\n\tentryPointAddress: \"0x5FF137D4b0FDCD49DcA30c7CF57E578a026d2789\",\n};\n\nexport const BASE_MAINNET: ChainConfig = {\n\tchainId: 8453,\n\tchainName: \"base\",\n\tdisplayName: \"Base\",\n\tnativeCurrency: {\n\t\tname: \"Ether\",\n\t\tsymbol: \"ETH\",\n\t\tdecimals: 18,\n\t},\n\trpcUrls: [\"https://mainnet.base.org\", \"https://base.llamarpc.com\"],\n\tblockExplorerUrls: [\"https://basescan.org\"],\n\tisTestnet: false,\n\tentryPointAddress: \"0x5FF137D4b0FDCD49DcA30c7CF57E578a026d2789\",\n};\n\nexport const BUILTIN_CHAINS: Map<number, ChainConfig> = new Map([\n\t[NERO_TESTNET.chainId, NERO_TESTNET],\n\t[NERO_MAINNET.chainId, NERO_MAINNET],\n\t[ETHEREUM_MAINNET.chainId, ETHEREUM_MAINNET],\n\t[ETHEREUM_SEPOLIA.chainId, ETHEREUM_SEPOLIA],\n\t[POLYGON_MAINNET.chainId, POLYGON_MAINNET],\n\t[ARBITRUM_ONE.chainId, ARBITRUM_ONE],\n\t[BASE_MAINNET.chainId, BASE_MAINNET],\n]);\n\nexport function getChainConfig(chainId: number): ChainConfig | undefined {\n\treturn BUILTIN_CHAINS.get(chainId);\n}\n\nexport function getAllChains(): ChainConfig[] {\n\treturn Array.from(BUILTIN_CHAINS.values());\n}\n\nexport function getTestnetChains(): ChainConfig[] {\n\treturn getAllChains().filter((c) => c.isTestnet);\n}\n\nexport function getMainnetChains(): ChainConfig[] {\n\treturn getAllChains().filter((c) => !c.isTestnet);\n}\n","import { BUILTIN_CHAINS, getChainConfig } from \"./configs\";\nimport type { ChainConfig } from \"./types\";\n\ntype ChainChangeListener = (chainId: number, config: ChainConfig) => void;\n\nexport class ChainManager {\n\tprivate currentChainId: number;\n\tprivate customChains: Map<number, ChainConfig> = new Map();\n\tprivate listeners: Set<ChainChangeListener> = new Set();\n\tprivate rpcConnections: Map<number, RpcConnection> = new Map();\n\n\tconstructor(initialChainId = 689) {\n\t\tthis.currentChainId = initialChainId;\n\t}\n\n\tget chainId(): number {\n\t\treturn this.currentChainId;\n\t}\n\n\tget chainConfig(): ChainConfig | undefined {\n\t\treturn this.getConfig(this.currentChainId);\n\t}\n\n\tgetConfig(chainId: number): ChainConfig | undefined {\n\t\treturn getChainConfig(chainId) ?? this.customChains.get(chainId);\n\t}\n\n\tgetSupportedChains(): ChainConfig[] {\n\t\tconst builtins = Array.from(BUILTIN_CHAINS.values());\n\t\tconst custom = Array.from(this.customChains.values());\n\t\treturn [...builtins, ...custom];\n\t}\n\n\tgetSupportedChainIds(): number[] {\n\t\treturn this.getSupportedChains().map((c) => c.chainId);\n\t}\n\n\tisChainSupported(chainId: number): boolean {\n\t\treturn this.getConfig(chainId) !== undefined;\n\t}\n\n\taddChain(config: ChainConfig): void {\n\t\tthis.customChains.set(config.chainId, config);\n\t}\n\n\tremoveChain(chainId: number): boolean {\n\t\tif (BUILTIN_CHAINS.has(chainId)) {\n\t\t\treturn false;\n\t\t}\n\t\treturn this.customChains.delete(chainId);\n\t}\n\n\tasync switchChain(chainId: number): Promise<ChainConfig> {\n\t\tconst config = this.getConfig(chainId);\n\t\tif (!config) {\n\t\t\tthrow new Error(`Chain ${chainId} is not supported`);\n\t\t}\n\n\t\tconst previousChainId = this.currentChainId;\n\t\tthis.currentChainId = chainId;\n\n\t\tif (previousChainId !== chainId) {\n\t\t\tthis.notifyListeners(chainId, config);\n\t\t}\n\n\t\treturn config;\n\t}\n\n\tonChainChange(listener: ChainChangeListener): () => void {\n\t\tthis.listeners.add(listener);\n\t\treturn () => this.listeners.delete(listener);\n\t}\n\n\tprivate notifyListeners(chainId: number, config: ChainConfig): void {\n\t\tfor (const listener of this.listeners) {\n\t\t\ttry {\n\t\t\t\tlistener(chainId, config);\n\t\t\t} catch {\n\t\t\t\t// Ignore listener errors\n\t\t\t}\n\t\t}\n\t}\n\n\tgetRpcConnection(chainId?: number): RpcConnection {\n\t\tconst targetChainId = chainId ?? this.currentChainId;\n\n\t\tlet connection = this.rpcConnections.get(targetChainId);\n\t\tif (!connection) {\n\t\t\tconst config = this.getConfig(targetChainId);\n\t\t\tif (!config) {\n\t\t\t\tthrow new Error(`Chain ${targetChainId} is not supported`);\n\t\t\t}\n\t\t\tconnection = new RpcConnection(config);\n\t\t\tthis.rpcConnections.set(targetChainId, connection);\n\t\t}\n\n\t\treturn connection;\n\t}\n\n\tgetTestnets(): ChainConfig[] {\n\t\treturn this.getSupportedChains().filter((c) => c.isTestnet);\n\t}\n\n\tgetMainnets(): ChainConfig[] {\n\t\treturn this.getSupportedChains().filter((c) => !c.isTestnet);\n\t}\n}\n\nexport class RpcConnection {\n\tprivate config: ChainConfig;\n\tprivate currentRpcIndex = 0;\n\n\tconstructor(config: ChainConfig) {\n\t\tthis.config = config;\n\t}\n\n\tget chainId(): number {\n\t\treturn this.config.chainId;\n\t}\n\n\tget rpcUrl(): string {\n\t\treturn this.config.rpcUrls[this.currentRpcIndex];\n\t}\n\n\tasync call<T>(method: string, params: unknown[] = []): Promise<T> {\n\t\tconst maxRetries = this.config.rpcUrls.length;\n\t\tlet lastError: Error | null = null;\n\n\t\tfor (let attempt = 0; attempt < maxRetries; attempt++) {\n\t\t\ttry {\n\t\t\t\treturn await this.executeCall<T>(method, params);\n\t\t\t} catch (error) {\n\t\t\t\tlastError = error as Error;\n\t\t\t\tthis.rotateRpc();\n\t\t\t}\n\t\t}\n\n\t\tthrow lastError ?? new Error(\"RPC call failed\");\n\t}\n\n\tprivate async executeCall<T>(method: string, params: unknown[]): Promise<T> {\n\t\tconst response = await fetch(this.rpcUrl, {\n\t\t\tmethod: \"POST\",\n\t\t\theaders: { \"Content-Type\": \"application/json\" },\n\t\t\tbody: JSON.stringify({\n\t\t\t\tjsonrpc: \"2.0\",\n\t\t\t\tid: Date.now(),\n\t\t\t\tmethod,\n\t\t\t\tparams,\n\t\t\t}),\n\t\t});\n\n\t\tif (!response.ok) {\n\t\t\tthrow new Error(`RPC request failed: ${response.status}`);\n\t\t}\n\n\t\tconst data = await response.json();\n\n\t\tif (data.error) {\n\t\t\tthrow new Error(data.error.message ?? \"RPC error\");\n\t\t}\n\n\t\treturn data.result;\n\t}\n\n\tprivate rotateRpc(): void {\n\t\tthis.currentRpcIndex =\n\t\t\t(this.currentRpcIndex + 1) % this.config.rpcUrls.length;\n\t}\n\n\tasync getBlockNumber(): Promise<bigint> {\n\t\tconst result = await this.call<string>(\"eth_blockNumber\");\n\t\treturn BigInt(result);\n\t}\n\n\tasync getBalance(address: string): Promise<bigint> {\n\t\tconst result = await this.call<string>(\"eth_getBalance\", [\n\t\t\taddress,\n\t\t\t\"latest\",\n\t\t]);\n\t\treturn BigInt(result);\n\t}\n\n\tasync getTransactionCount(address: string): Promise<bigint> {\n\t\tconst result = await this.call<string>(\"eth_getTransactionCount\", [\n\t\t\taddress,\n\t\t\t\"latest\",\n\t\t]);\n\t\treturn BigInt(result);\n\t}\n\n\tasync getGasPrice(): Promise<bigint> {\n\t\tconst result = await this.call<string>(\"eth_gasPrice\");\n\t\treturn BigInt(result);\n\t}\n\n\tasync estimateGas(tx: {\n\t\tfrom?: string;\n\t\tto?: string;\n\t\tvalue?: string;\n\t\tdata?: string;\n\t}): Promise<bigint> {\n\t\tconst result = await this.call<string>(\"eth_estimateGas\", [tx]);\n\t\treturn BigInt(result);\n\t}\n\n\tasync getCode(address: string): Promise<string> {\n\t\treturn this.call<string>(\"eth_getCode\", [address, \"latest\"]);\n\t}\n\n\tasync sendRawTransaction(signedTx: string): Promise<string> {\n\t\treturn this.call<string>(\"eth_sendRawTransaction\", [signedTx]);\n\t}\n\n\tasync getTransactionReceipt(\n\t\thash: string,\n\t): Promise<TransactionReceipt | null> {\n\t\treturn this.call<TransactionReceipt | null>(\"eth_getTransactionReceipt\", [\n\t\t\thash,\n\t\t]);\n\t}\n\n\tasync waitForTransaction(\n\t\thash: string,\n\t\tconfirmations = 1,\n\t\ttimeout = 60000,\n\t): Promise<TransactionReceipt> {\n\t\tconst startTime = Date.now();\n\n\t\twhile (Date.now() - startTime < timeout) {\n\t\t\tconst receipt = await this.getTransactionReceipt(hash);\n\t\t\tif (receipt?.blockNumber) {\n\t\t\t\tconst currentBlock = await this.getBlockNumber();\n\t\t\t\tconst txBlock = BigInt(receipt.blockNumber);\n\t\t\t\tif (currentBlock - txBlock >= BigInt(confirmations - 1)) {\n\t\t\t\t\treturn receipt;\n\t\t\t\t}\n\t\t\t}\n\t\t\tawait new Promise((resolve) => setTimeout(resolve, 2000));\n\t\t}\n\n\t\tthrow new Error(`Transaction ${hash} not confirmed within timeout`);\n\t}\n}\n\nexport interface TransactionReceipt {\n\ttransactionHash: string;\n\ttransactionIndex: string;\n\tblockHash: string;\n\tblockNumber: string;\n\tfrom: string;\n\tto: string | null;\n\tcumulativeGasUsed: string;\n\tgasUsed: string;\n\tcontractAddress: string | null;\n\tlogs: Array<{\n\t\taddress: string;\n\t\ttopics: string[];\n\t\tdata: string;\n\t\tblockNumber: string;\n\t\ttransactionHash: string;\n\t\ttransactionIndex: string;\n\t\tblockHash: string;\n\t\tlogIndex: string;\n\t\tremoved: boolean;\n\t}>;\n\tlogsBloom: string;\n\tstatus: string;\n\teffectiveGasPrice?: string;\n\ttype?: string;\n}\n\nexport function createChainManager(initialChainId?: number): ChainManager {\n\treturn new ChainManager(initialChainId);\n}\n"]}
|