@vleap/warps-adapter-evm 0.2.0-alpha.10
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/dist/index.d.mts +140 -0
- package/dist/index.d.ts +140 -0
- package/dist/index.js +1110 -0
- package/dist/index.js.map +1 -0
- package/dist/index.mjs +1073 -0
- package/dist/index.mjs.map +1 -0
- package/package.json +36 -0
package/dist/index.mjs
ADDED
|
@@ -0,0 +1,1073 @@
|
|
|
1
|
+
// src/WarpEvmDataLoader.ts
|
|
2
|
+
import { ethers } from "ethers";
|
|
3
|
+
|
|
4
|
+
// src/config.ts
|
|
5
|
+
var EVM_CHAIN_CONFIGS = {
|
|
6
|
+
ethereum: {
|
|
7
|
+
mainnet: {
|
|
8
|
+
apiUrl: "https://eth-mainnet.g.alchemy.com/v2/demo",
|
|
9
|
+
explorerUrl: "https://etherscan.io",
|
|
10
|
+
chainId: "1",
|
|
11
|
+
registryAddress: "0x0000000000000000000000000000000000000000",
|
|
12
|
+
nativeToken: "ETH",
|
|
13
|
+
blockTime: 12e3
|
|
14
|
+
},
|
|
15
|
+
testnet: {
|
|
16
|
+
apiUrl: "https://eth-sepolia.g.alchemy.com/v2/demo",
|
|
17
|
+
explorerUrl: "https://sepolia.etherscan.io",
|
|
18
|
+
chainId: "11155111",
|
|
19
|
+
registryAddress: "0x0000000000000000000000000000000000000000",
|
|
20
|
+
nativeToken: "ETH",
|
|
21
|
+
blockTime: 12e3
|
|
22
|
+
},
|
|
23
|
+
devnet: {
|
|
24
|
+
apiUrl: "http://localhost:8545",
|
|
25
|
+
explorerUrl: "http://localhost:4000",
|
|
26
|
+
chainId: "1337",
|
|
27
|
+
registryAddress: "0x0000000000000000000000000000000000000000",
|
|
28
|
+
nativeToken: "ETH",
|
|
29
|
+
blockTime: 12e3
|
|
30
|
+
}
|
|
31
|
+
},
|
|
32
|
+
arbitrum: {
|
|
33
|
+
mainnet: {
|
|
34
|
+
apiUrl: "https://arb-mainnet.g.alchemy.com/v2/demo",
|
|
35
|
+
explorerUrl: "https://arbiscan.io",
|
|
36
|
+
chainId: "42161",
|
|
37
|
+
registryAddress: "0x0000000000000000000000000000000000000000",
|
|
38
|
+
nativeToken: "ETH",
|
|
39
|
+
blockTime: 1e3
|
|
40
|
+
},
|
|
41
|
+
testnet: {
|
|
42
|
+
apiUrl: "https://arb-sepolia.g.alchemy.com/v2/demo",
|
|
43
|
+
explorerUrl: "https://sepolia.arbiscan.io",
|
|
44
|
+
chainId: "421614",
|
|
45
|
+
registryAddress: "0x0000000000000000000000000000000000000000",
|
|
46
|
+
nativeToken: "ETH",
|
|
47
|
+
blockTime: 1e3
|
|
48
|
+
},
|
|
49
|
+
devnet: {
|
|
50
|
+
apiUrl: "http://localhost:8545",
|
|
51
|
+
explorerUrl: "http://localhost:4000",
|
|
52
|
+
chainId: "1337",
|
|
53
|
+
registryAddress: "0x0000000000000000000000000000000000000000",
|
|
54
|
+
nativeToken: "ETH",
|
|
55
|
+
blockTime: 1e3
|
|
56
|
+
}
|
|
57
|
+
},
|
|
58
|
+
base: {
|
|
59
|
+
mainnet: {
|
|
60
|
+
apiUrl: "https://mainnet.base.org",
|
|
61
|
+
explorerUrl: "https://basescan.org",
|
|
62
|
+
chainId: "8453",
|
|
63
|
+
registryAddress: "0x0000000000000000000000000000000000000000",
|
|
64
|
+
nativeToken: "ETH",
|
|
65
|
+
blockTime: 2e3
|
|
66
|
+
},
|
|
67
|
+
testnet: {
|
|
68
|
+
apiUrl: "https://sepolia.base.org",
|
|
69
|
+
explorerUrl: "https://sepolia.basescan.org",
|
|
70
|
+
chainId: "84532",
|
|
71
|
+
registryAddress: "0x0000000000000000000000000000000000000000",
|
|
72
|
+
nativeToken: "ETH",
|
|
73
|
+
blockTime: 2e3
|
|
74
|
+
},
|
|
75
|
+
devnet: {
|
|
76
|
+
apiUrl: "http://localhost:8545",
|
|
77
|
+
explorerUrl: "http://localhost:4000",
|
|
78
|
+
chainId: "1337",
|
|
79
|
+
registryAddress: "0x0000000000000000000000000000000000000000",
|
|
80
|
+
nativeToken: "ETH",
|
|
81
|
+
blockTime: 2e3
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
};
|
|
85
|
+
var DEFAULT_CHAIN = "ethereum";
|
|
86
|
+
var getEvmChainConfig = (chain = DEFAULT_CHAIN, env) => {
|
|
87
|
+
const chainConfigs = EVM_CHAIN_CONFIGS[chain];
|
|
88
|
+
if (!chainConfigs) {
|
|
89
|
+
throw new Error(`Unsupported EVM chain: ${chain}`);
|
|
90
|
+
}
|
|
91
|
+
const config = chainConfigs[env];
|
|
92
|
+
if (!config) {
|
|
93
|
+
throw new Error(`Unsupported environment ${env} for chain ${chain}`);
|
|
94
|
+
}
|
|
95
|
+
return config;
|
|
96
|
+
};
|
|
97
|
+
var getEvmApiUrl = (env, chain = DEFAULT_CHAIN) => {
|
|
98
|
+
return getEvmChainConfig(chain, env).apiUrl;
|
|
99
|
+
};
|
|
100
|
+
var getEvmExplorerUrl = (env, chain = DEFAULT_CHAIN) => {
|
|
101
|
+
return getEvmChainConfig(chain, env).explorerUrl;
|
|
102
|
+
};
|
|
103
|
+
|
|
104
|
+
// src/WarpEvmDataLoader.ts
|
|
105
|
+
var ERC20_ABI = [
|
|
106
|
+
"function balanceOf(address owner) view returns (uint256)",
|
|
107
|
+
"function decimals() view returns (uint8)",
|
|
108
|
+
"function name() view returns (string)",
|
|
109
|
+
"function symbol() view returns (string)",
|
|
110
|
+
"function totalSupply() view returns (uint256)"
|
|
111
|
+
];
|
|
112
|
+
var KNOWN_TOKENS = {
|
|
113
|
+
ethereum: {
|
|
114
|
+
"0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48": {
|
|
115
|
+
name: "USD Coin",
|
|
116
|
+
symbol: "USDC",
|
|
117
|
+
decimals: 6,
|
|
118
|
+
logoUrl: "https://assets.coingecko.com/coins/images/6319/small/USD_Coin_icon.png"
|
|
119
|
+
},
|
|
120
|
+
"0xdAC17F958D2ee523a2206206994597C13D831ec7": {
|
|
121
|
+
name: "Tether USD",
|
|
122
|
+
symbol: "USDT",
|
|
123
|
+
decimals: 6,
|
|
124
|
+
logoUrl: "https://assets.coingecko.com/coins/images/325/small/Tether.png"
|
|
125
|
+
},
|
|
126
|
+
"0x2260FAC5E5542a773Aa44fBCfeDf7C193bc2C599": {
|
|
127
|
+
name: "Wrapped Bitcoin",
|
|
128
|
+
symbol: "WBTC",
|
|
129
|
+
decimals: 8,
|
|
130
|
+
logoUrl: "https://assets.coingecko.com/coins/images/7598/small/wrapped_bitcoin_wbtc.png"
|
|
131
|
+
},
|
|
132
|
+
"0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2": {
|
|
133
|
+
name: "Wrapped Ether",
|
|
134
|
+
symbol: "WETH",
|
|
135
|
+
decimals: 18,
|
|
136
|
+
logoUrl: "https://assets.coingecko.com/coins/images/2518/small/weth.png"
|
|
137
|
+
},
|
|
138
|
+
"0x6B175474E89094C44Da98b954EedeAC495271d0F": {
|
|
139
|
+
name: "Dai Stablecoin",
|
|
140
|
+
symbol: "DAI",
|
|
141
|
+
decimals: 18,
|
|
142
|
+
logoUrl: "https://assets.coingecko.com/coins/images/9956/small/4943.png"
|
|
143
|
+
}
|
|
144
|
+
},
|
|
145
|
+
arbitrum: {
|
|
146
|
+
"0xFF970A61A04b1cA14834A43f5dE4533eBDDB5CC8": {
|
|
147
|
+
name: "USD Coin",
|
|
148
|
+
symbol: "USDC",
|
|
149
|
+
decimals: 6,
|
|
150
|
+
logoUrl: "https://assets.coingecko.com/coins/images/6319/small/USD_Coin_icon.png"
|
|
151
|
+
},
|
|
152
|
+
"0xFd086bC7CD5C481DCC9C85ebE478A1C0b69FCbb9": {
|
|
153
|
+
name: "Tether USD",
|
|
154
|
+
symbol: "USDT",
|
|
155
|
+
decimals: 6,
|
|
156
|
+
logoUrl: "https://assets.coingecko.com/coins/images/325/small/Tether.png"
|
|
157
|
+
},
|
|
158
|
+
"0x82aF49447D8a07e3bd95BD0d56f35241523fBab1": {
|
|
159
|
+
name: "Wrapped Ether",
|
|
160
|
+
symbol: "WETH",
|
|
161
|
+
decimals: 18,
|
|
162
|
+
logoUrl: "https://assets.coingecko.com/coins/images/2518/small/weth.png"
|
|
163
|
+
}
|
|
164
|
+
},
|
|
165
|
+
base: {
|
|
166
|
+
"0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913": {
|
|
167
|
+
name: "USD Coin",
|
|
168
|
+
symbol: "USDC",
|
|
169
|
+
decimals: 6,
|
|
170
|
+
logoUrl: "https://assets.coingecko.com/coins/images/6319/small/USD_Coin_icon.png"
|
|
171
|
+
},
|
|
172
|
+
"0x4200000000000000000000000000000000000006": {
|
|
173
|
+
name: "Wrapped Ether",
|
|
174
|
+
symbol: "WETH",
|
|
175
|
+
decimals: 18,
|
|
176
|
+
logoUrl: "https://assets.coingecko.com/coins/images/2518/small/weth.png"
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
};
|
|
180
|
+
var WarpEvmDataLoader = class {
|
|
181
|
+
constructor(config, chain) {
|
|
182
|
+
this.config = config;
|
|
183
|
+
this.chain = chain;
|
|
184
|
+
this.provider = new ethers.JsonRpcProvider(getEvmApiUrl(this.config.env, this.chain.name));
|
|
185
|
+
this.chainConfig = getEvmChainConfig(this.chain.name, this.config.env);
|
|
186
|
+
}
|
|
187
|
+
async getAccount(address) {
|
|
188
|
+
try {
|
|
189
|
+
const balance = await this.provider.getBalance(address);
|
|
190
|
+
return {
|
|
191
|
+
address,
|
|
192
|
+
balance
|
|
193
|
+
};
|
|
194
|
+
} catch (error) {
|
|
195
|
+
throw new Error(`Failed to get account balance for ${address}: ${error}`);
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
async getAccountAssets(address) {
|
|
199
|
+
try {
|
|
200
|
+
const assets = [];
|
|
201
|
+
const tokenBalances = await this.getERC20TokenBalances(address);
|
|
202
|
+
for (const tokenBalance of tokenBalances) {
|
|
203
|
+
if (tokenBalance.balance > 0n) {
|
|
204
|
+
assets.push({
|
|
205
|
+
identifier: tokenBalance.tokenAddress,
|
|
206
|
+
name: tokenBalance.metadata.name,
|
|
207
|
+
amount: tokenBalance.balance,
|
|
208
|
+
decimals: tokenBalance.metadata.decimals,
|
|
209
|
+
logoUrl: tokenBalance.metadata.logoUrl || ""
|
|
210
|
+
});
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
return assets;
|
|
214
|
+
} catch (error) {
|
|
215
|
+
throw new Error(`Failed to get account assets for ${address}: ${error}`);
|
|
216
|
+
}
|
|
217
|
+
}
|
|
218
|
+
async getERC20TokenBalances(address) {
|
|
219
|
+
const tokenBalances = [];
|
|
220
|
+
const knownTokens = KNOWN_TOKENS[this.chain.name] || {};
|
|
221
|
+
for (const [tokenAddress, metadata] of Object.entries(knownTokens)) {
|
|
222
|
+
try {
|
|
223
|
+
const balance = await this.getTokenBalance(address, tokenAddress);
|
|
224
|
+
if (balance > 0n) {
|
|
225
|
+
tokenBalances.push({
|
|
226
|
+
tokenAddress,
|
|
227
|
+
balance,
|
|
228
|
+
metadata
|
|
229
|
+
});
|
|
230
|
+
}
|
|
231
|
+
} catch (error) {
|
|
232
|
+
console.warn(`Failed to get balance for token ${tokenAddress}: ${error}`);
|
|
233
|
+
}
|
|
234
|
+
}
|
|
235
|
+
const additionalTokens = await this.detectTokensFromEvents(address);
|
|
236
|
+
for (const tokenAddress of additionalTokens) {
|
|
237
|
+
if (!knownTokens[tokenAddress]) {
|
|
238
|
+
try {
|
|
239
|
+
const metadata = await this.getTokenMetadata(tokenAddress);
|
|
240
|
+
const balance = await this.getTokenBalance(address, tokenAddress);
|
|
241
|
+
if (balance > 0n) {
|
|
242
|
+
tokenBalances.push({
|
|
243
|
+
tokenAddress,
|
|
244
|
+
balance,
|
|
245
|
+
metadata
|
|
246
|
+
});
|
|
247
|
+
}
|
|
248
|
+
} catch (error) {
|
|
249
|
+
console.warn(`Failed to get metadata/balance for detected token ${tokenAddress}: ${error}`);
|
|
250
|
+
}
|
|
251
|
+
}
|
|
252
|
+
}
|
|
253
|
+
return tokenBalances;
|
|
254
|
+
}
|
|
255
|
+
async getTokenBalance(address, tokenAddress) {
|
|
256
|
+
try {
|
|
257
|
+
const contract = new ethers.Contract(tokenAddress, ERC20_ABI, this.provider);
|
|
258
|
+
const balance = await contract.balanceOf(address);
|
|
259
|
+
return balance;
|
|
260
|
+
} catch (error) {
|
|
261
|
+
throw new Error(`Failed to get token balance: ${error}`);
|
|
262
|
+
}
|
|
263
|
+
}
|
|
264
|
+
async getTokenMetadata(tokenAddress) {
|
|
265
|
+
try {
|
|
266
|
+
const contract = new ethers.Contract(tokenAddress, ERC20_ABI, this.provider);
|
|
267
|
+
const [name, symbol, decimals] = await Promise.all([contract.name(), contract.symbol(), contract.decimals()]);
|
|
268
|
+
return {
|
|
269
|
+
name: name || "Unknown Token",
|
|
270
|
+
symbol: symbol || "UNKNOWN",
|
|
271
|
+
decimals: decimals || 18
|
|
272
|
+
};
|
|
273
|
+
} catch (error) {
|
|
274
|
+
throw new Error(`Failed to get token metadata: ${error}`);
|
|
275
|
+
}
|
|
276
|
+
}
|
|
277
|
+
async detectTokensFromEvents(address) {
|
|
278
|
+
try {
|
|
279
|
+
const currentBlock = await this.provider.getBlockNumber();
|
|
280
|
+
const fromBlock = Math.max(0, currentBlock - 1e4);
|
|
281
|
+
const filter = {
|
|
282
|
+
fromBlock,
|
|
283
|
+
toBlock: currentBlock,
|
|
284
|
+
topics: [
|
|
285
|
+
ethers.id("Transfer(address,address,uint256)"),
|
|
286
|
+
null,
|
|
287
|
+
// from address (any)
|
|
288
|
+
ethers.zeroPadValue(address, 32)
|
|
289
|
+
// to address (our target)
|
|
290
|
+
]
|
|
291
|
+
};
|
|
292
|
+
const logs = await this.provider.getLogs(filter);
|
|
293
|
+
const tokenAddresses = /* @__PURE__ */ new Set();
|
|
294
|
+
for (const log of logs) {
|
|
295
|
+
tokenAddresses.add(log.address);
|
|
296
|
+
}
|
|
297
|
+
return Array.from(tokenAddresses);
|
|
298
|
+
} catch (error) {
|
|
299
|
+
console.warn(`Failed to detect tokens from events: ${error}`);
|
|
300
|
+
return [];
|
|
301
|
+
}
|
|
302
|
+
}
|
|
303
|
+
// Additional utility methods for enhanced token support
|
|
304
|
+
async getTokenInfo(tokenAddress) {
|
|
305
|
+
try {
|
|
306
|
+
return await this.getTokenMetadata(tokenAddress);
|
|
307
|
+
} catch (error) {
|
|
308
|
+
console.warn(`Failed to get token info for ${tokenAddress}: ${error}`);
|
|
309
|
+
return null;
|
|
310
|
+
}
|
|
311
|
+
}
|
|
312
|
+
async getTokenBalanceForAddress(address, tokenAddress) {
|
|
313
|
+
try {
|
|
314
|
+
return await this.getTokenBalance(address, tokenAddress);
|
|
315
|
+
} catch (error) {
|
|
316
|
+
throw new Error(`Failed to get token balance for ${tokenAddress}: ${error}`);
|
|
317
|
+
}
|
|
318
|
+
}
|
|
319
|
+
async getMultipleTokenBalances(address, tokenAddresses) {
|
|
320
|
+
const balances = /* @__PURE__ */ new Map();
|
|
321
|
+
await Promise.all(
|
|
322
|
+
tokenAddresses.map(async (tokenAddress) => {
|
|
323
|
+
try {
|
|
324
|
+
const balance = await this.getTokenBalance(address, tokenAddress);
|
|
325
|
+
balances.set(tokenAddress, balance);
|
|
326
|
+
} catch (error) {
|
|
327
|
+
console.warn(`Failed to get balance for token ${tokenAddress}: ${error}`);
|
|
328
|
+
balances.set(tokenAddress, 0n);
|
|
329
|
+
}
|
|
330
|
+
})
|
|
331
|
+
);
|
|
332
|
+
return balances;
|
|
333
|
+
}
|
|
334
|
+
};
|
|
335
|
+
|
|
336
|
+
// src/WarpEvmExecutor.ts
|
|
337
|
+
import {
|
|
338
|
+
applyResultsToMessages,
|
|
339
|
+
getNextInfo,
|
|
340
|
+
getWarpActionByIndex
|
|
341
|
+
} from "@vleap/warps";
|
|
342
|
+
import { ethers as ethers3 } from "ethers";
|
|
343
|
+
|
|
344
|
+
// src/constants.ts
|
|
345
|
+
var WarpEvmConstants = {
|
|
346
|
+
GasLimit: {
|
|
347
|
+
Default: 21e3,
|
|
348
|
+
ContractCall: 1e5,
|
|
349
|
+
ContractDeploy: 5e5,
|
|
350
|
+
Transfer: 21e3,
|
|
351
|
+
Approve: 46e3,
|
|
352
|
+
Swap: 2e5
|
|
353
|
+
},
|
|
354
|
+
GasPrice: {
|
|
355
|
+
Default: "20000000000"
|
|
356
|
+
},
|
|
357
|
+
Validation: {
|
|
358
|
+
MinGasLimit: 21e3,
|
|
359
|
+
MaxGasLimit: 3e7
|
|
360
|
+
}
|
|
361
|
+
};
|
|
362
|
+
var EthereumExplorers = /* @__PURE__ */ ((EthereumExplorers2) => {
|
|
363
|
+
EthereumExplorers2["Etherscan"] = "etherscan";
|
|
364
|
+
EthereumExplorers2["EtherscanSepolia"] = "etherscan_sepolia";
|
|
365
|
+
EthereumExplorers2["Ethplorer"] = "ethplorer";
|
|
366
|
+
EthereumExplorers2["Blockscout"] = "blockscout";
|
|
367
|
+
EthereumExplorers2["BlockscoutSepolia"] = "blockscout_sepolia";
|
|
368
|
+
return EthereumExplorers2;
|
|
369
|
+
})(EthereumExplorers || {});
|
|
370
|
+
var ArbitrumExplorers = /* @__PURE__ */ ((ArbitrumExplorers2) => {
|
|
371
|
+
ArbitrumExplorers2["Arbiscan"] = "arbiscan";
|
|
372
|
+
ArbitrumExplorers2["ArbiscanSepolia"] = "arbiscan_sepolia";
|
|
373
|
+
ArbitrumExplorers2["BlockscoutArbitrum"] = "blockscout_arbitrum";
|
|
374
|
+
ArbitrumExplorers2["BlockscoutArbitrumSepolia"] = "blockscout_arbitrum_sepolia";
|
|
375
|
+
return ArbitrumExplorers2;
|
|
376
|
+
})(ArbitrumExplorers || {});
|
|
377
|
+
var BaseExplorers = /* @__PURE__ */ ((BaseExplorers2) => {
|
|
378
|
+
BaseExplorers2["Basescan"] = "basescan";
|
|
379
|
+
BaseExplorers2["BasescanSepolia"] = "basescan_sepolia";
|
|
380
|
+
BaseExplorers2["BlockscoutBase"] = "blockscout_base";
|
|
381
|
+
BaseExplorers2["BlockscoutBaseSepolia"] = "blockscout_base_sepolia";
|
|
382
|
+
return BaseExplorers2;
|
|
383
|
+
})(BaseExplorers || {});
|
|
384
|
+
var EvmExplorers = {
|
|
385
|
+
ethereum: {
|
|
386
|
+
mainnet: ["etherscan" /* Etherscan */, "ethplorer" /* Ethplorer */, "blockscout" /* Blockscout */],
|
|
387
|
+
testnet: ["etherscan_sepolia" /* EtherscanSepolia */, "blockscout_sepolia" /* BlockscoutSepolia */],
|
|
388
|
+
devnet: ["etherscan_sepolia" /* EtherscanSepolia */, "blockscout_sepolia" /* BlockscoutSepolia */]
|
|
389
|
+
},
|
|
390
|
+
arbitrum: {
|
|
391
|
+
mainnet: ["arbiscan" /* Arbiscan */, "blockscout_arbitrum" /* BlockscoutArbitrum */],
|
|
392
|
+
testnet: ["arbiscan_sepolia" /* ArbiscanSepolia */, "blockscout_arbitrum_sepolia" /* BlockscoutArbitrumSepolia */],
|
|
393
|
+
devnet: ["arbiscan_sepolia" /* ArbiscanSepolia */, "blockscout_arbitrum_sepolia" /* BlockscoutArbitrumSepolia */]
|
|
394
|
+
},
|
|
395
|
+
base: {
|
|
396
|
+
mainnet: ["basescan" /* Basescan */, "blockscout_base" /* BlockscoutBase */],
|
|
397
|
+
testnet: ["basescan_sepolia" /* BasescanSepolia */, "blockscout_base_sepolia" /* BlockscoutBaseSepolia */],
|
|
398
|
+
devnet: ["basescan_sepolia" /* BasescanSepolia */, "blockscout_base_sepolia" /* BlockscoutBaseSepolia */]
|
|
399
|
+
}
|
|
400
|
+
};
|
|
401
|
+
var ExplorerUrls = {
|
|
402
|
+
["etherscan" /* Etherscan */]: "https://etherscan.io",
|
|
403
|
+
["etherscan_sepolia" /* EtherscanSepolia */]: "https://sepolia.etherscan.io",
|
|
404
|
+
["ethplorer" /* Ethplorer */]: "https://ethplorer.io",
|
|
405
|
+
["blockscout" /* Blockscout */]: "https://eth.blockscout.com",
|
|
406
|
+
["blockscout_sepolia" /* BlockscoutSepolia */]: "https://sepolia.blockscout.com",
|
|
407
|
+
["arbiscan" /* Arbiscan */]: "https://arbiscan.io",
|
|
408
|
+
["arbiscan_sepolia" /* ArbiscanSepolia */]: "https://sepolia.arbiscan.io",
|
|
409
|
+
["blockscout_arbitrum" /* BlockscoutArbitrum */]: "https://arbitrum.blockscout.com",
|
|
410
|
+
["blockscout_arbitrum_sepolia" /* BlockscoutArbitrumSepolia */]: "https://sepolia.blockscout.com",
|
|
411
|
+
["basescan" /* Basescan */]: "https://basescan.org",
|
|
412
|
+
["basescan_sepolia" /* BasescanSepolia */]: "https://sepolia.basescan.org",
|
|
413
|
+
["blockscout_base" /* BlockscoutBase */]: "https://base.blockscout.com",
|
|
414
|
+
["blockscout_base_sepolia" /* BlockscoutBaseSepolia */]: "https://sepolia.blockscout.com"
|
|
415
|
+
};
|
|
416
|
+
|
|
417
|
+
// src/WarpEvmResults.ts
|
|
418
|
+
import {
|
|
419
|
+
evaluateResultsCommon,
|
|
420
|
+
parseResultsOutIndex,
|
|
421
|
+
WarpConstants as WarpConstants2
|
|
422
|
+
} from "@vleap/warps";
|
|
423
|
+
|
|
424
|
+
// src/WarpEvmSerializer.ts
|
|
425
|
+
import {
|
|
426
|
+
WarpConstants,
|
|
427
|
+
WarpSerializer
|
|
428
|
+
} from "@vleap/warps";
|
|
429
|
+
import { ethers as ethers2 } from "ethers";
|
|
430
|
+
var SplitParamsRegex = new RegExp(`${WarpConstants.ArgParamsSeparator}(.*)`);
|
|
431
|
+
var WarpEvmSerializer = class {
|
|
432
|
+
constructor() {
|
|
433
|
+
this.coreSerializer = new WarpSerializer();
|
|
434
|
+
}
|
|
435
|
+
typedToString(value) {
|
|
436
|
+
if (typeof value === "string") {
|
|
437
|
+
if (ethers2.isAddress(value)) {
|
|
438
|
+
return `address:${value}`;
|
|
439
|
+
}
|
|
440
|
+
if (ethers2.isHexString(value) && !ethers2.isAddress(value)) {
|
|
441
|
+
return `hex:${value}`;
|
|
442
|
+
}
|
|
443
|
+
return `string:${value}`;
|
|
444
|
+
}
|
|
445
|
+
if (typeof value === "number") {
|
|
446
|
+
if (Number.isInteger(value)) {
|
|
447
|
+
if (value >= 0 && value <= 255) return `uint8:${value}`;
|
|
448
|
+
if (value >= 0 && value <= 65535) return `uint16:${value}`;
|
|
449
|
+
if (value >= 0 && value <= 4294967295) return `uint32:${value}`;
|
|
450
|
+
return `uint64:${value}`;
|
|
451
|
+
}
|
|
452
|
+
return `string:${value}`;
|
|
453
|
+
}
|
|
454
|
+
if (typeof value === "bigint") {
|
|
455
|
+
return `biguint:${value.toString()}`;
|
|
456
|
+
}
|
|
457
|
+
if (typeof value === "boolean") {
|
|
458
|
+
return `boolean:${value}`;
|
|
459
|
+
}
|
|
460
|
+
if (Array.isArray(value)) {
|
|
461
|
+
if (value.length === 0) return `list:string:`;
|
|
462
|
+
const types = value.map((item) => this.typedToString(item).split(WarpConstants.ArgParamsSeparator)[0]);
|
|
463
|
+
const type = types[0];
|
|
464
|
+
const values = value.map((item) => this.typedToString(item).split(WarpConstants.ArgParamsSeparator)[1]);
|
|
465
|
+
return `list:${type}:${values.join(",")}`;
|
|
466
|
+
}
|
|
467
|
+
if (value === null || value === void 0) {
|
|
468
|
+
return `string:null`;
|
|
469
|
+
}
|
|
470
|
+
return `string:${String(value)}`;
|
|
471
|
+
}
|
|
472
|
+
typedToNative(value) {
|
|
473
|
+
const stringValue = this.typedToString(value);
|
|
474
|
+
const [type, ...valueParts] = stringValue.split(WarpConstants.ArgParamsSeparator);
|
|
475
|
+
const nativeValue = valueParts.join(WarpConstants.ArgParamsSeparator);
|
|
476
|
+
return [type, this.parseNativeValue(type, nativeValue)];
|
|
477
|
+
}
|
|
478
|
+
nativeToTyped(type, value) {
|
|
479
|
+
switch (type) {
|
|
480
|
+
case "string":
|
|
481
|
+
return String(value);
|
|
482
|
+
case "uint8":
|
|
483
|
+
case "uint16":
|
|
484
|
+
case "uint32":
|
|
485
|
+
case "uint64":
|
|
486
|
+
return BigInt(value);
|
|
487
|
+
case "biguint":
|
|
488
|
+
return BigInt(value);
|
|
489
|
+
case "boolean":
|
|
490
|
+
return Boolean(value);
|
|
491
|
+
case "address":
|
|
492
|
+
return String(value);
|
|
493
|
+
case "hex":
|
|
494
|
+
return String(value);
|
|
495
|
+
default:
|
|
496
|
+
if (type.startsWith("list:")) {
|
|
497
|
+
const [, itemType, itemsStr] = type.split(":");
|
|
498
|
+
if (!itemsStr) return [];
|
|
499
|
+
const items = itemsStr.split(",");
|
|
500
|
+
return items.map((item) => this.nativeToTyped(itemType, item));
|
|
501
|
+
}
|
|
502
|
+
return String(value);
|
|
503
|
+
}
|
|
504
|
+
}
|
|
505
|
+
nativeToType(type) {
|
|
506
|
+
switch (type) {
|
|
507
|
+
case "string":
|
|
508
|
+
return "string";
|
|
509
|
+
case "uint8":
|
|
510
|
+
case "uint16":
|
|
511
|
+
case "uint32":
|
|
512
|
+
case "uint64":
|
|
513
|
+
case "biguint":
|
|
514
|
+
return "bigint";
|
|
515
|
+
case "boolean":
|
|
516
|
+
return "boolean";
|
|
517
|
+
case "address":
|
|
518
|
+
return "string";
|
|
519
|
+
case "hex":
|
|
520
|
+
return "string";
|
|
521
|
+
default:
|
|
522
|
+
return "string";
|
|
523
|
+
}
|
|
524
|
+
}
|
|
525
|
+
stringToTyped(value) {
|
|
526
|
+
const parts = value.split(WarpConstants.ArgParamsSeparator, 2);
|
|
527
|
+
if (parts.length < 2) {
|
|
528
|
+
return value;
|
|
529
|
+
}
|
|
530
|
+
const [type, stringValue] = parts;
|
|
531
|
+
switch (type) {
|
|
532
|
+
case "string":
|
|
533
|
+
return stringValue;
|
|
534
|
+
case "uint8":
|
|
535
|
+
case "uint16":
|
|
536
|
+
case "uint32":
|
|
537
|
+
case "uint64":
|
|
538
|
+
return BigInt(stringValue);
|
|
539
|
+
case "biguint":
|
|
540
|
+
return BigInt(stringValue);
|
|
541
|
+
case "boolean":
|
|
542
|
+
return stringValue === "true";
|
|
543
|
+
case "address":
|
|
544
|
+
return stringValue;
|
|
545
|
+
case "hex":
|
|
546
|
+
return stringValue;
|
|
547
|
+
default:
|
|
548
|
+
if (type.startsWith("list:")) {
|
|
549
|
+
const [, itemType, itemsStr] = type.split(":");
|
|
550
|
+
if (!itemsStr) return [];
|
|
551
|
+
const items = itemsStr.split(",");
|
|
552
|
+
return items.map((item) => this.stringToTyped(`${itemType}:${item}`));
|
|
553
|
+
}
|
|
554
|
+
return stringValue;
|
|
555
|
+
}
|
|
556
|
+
}
|
|
557
|
+
parseNativeValue(type, value) {
|
|
558
|
+
switch (type) {
|
|
559
|
+
case "string":
|
|
560
|
+
return value;
|
|
561
|
+
case "uint8":
|
|
562
|
+
case "uint16":
|
|
563
|
+
case "uint32":
|
|
564
|
+
case "uint64":
|
|
565
|
+
case "biguint":
|
|
566
|
+
return BigInt(value);
|
|
567
|
+
case "boolean":
|
|
568
|
+
return value === "true";
|
|
569
|
+
case "address":
|
|
570
|
+
return value;
|
|
571
|
+
case "hex":
|
|
572
|
+
return value;
|
|
573
|
+
default:
|
|
574
|
+
return value;
|
|
575
|
+
}
|
|
576
|
+
}
|
|
577
|
+
};
|
|
578
|
+
|
|
579
|
+
// src/WarpEvmResults.ts
|
|
580
|
+
var WarpEvmResults = class {
|
|
581
|
+
constructor(config) {
|
|
582
|
+
this.config = config;
|
|
583
|
+
this.serializer = new WarpEvmSerializer();
|
|
584
|
+
}
|
|
585
|
+
async getTransactionExecutionResults(warp, tx) {
|
|
586
|
+
const success = tx.status === 1;
|
|
587
|
+
const gasUsed = tx.gasUsed?.toString() || "0";
|
|
588
|
+
const gasPrice = tx.gasPrice?.toString() || "0";
|
|
589
|
+
const blockNumber = tx.blockNumber?.toString() || "0";
|
|
590
|
+
const transactionHash = tx.hash;
|
|
591
|
+
const logs = tx.logs.map((log) => ({
|
|
592
|
+
address: log.address,
|
|
593
|
+
topics: log.topics,
|
|
594
|
+
data: log.data,
|
|
595
|
+
blockNumber: log.blockNumber?.toString() || "0",
|
|
596
|
+
transactionHash: log.transactionHash,
|
|
597
|
+
index: log.index?.toString() || "0"
|
|
598
|
+
}));
|
|
599
|
+
return {
|
|
600
|
+
success,
|
|
601
|
+
warp,
|
|
602
|
+
action: 0,
|
|
603
|
+
user: this.config.user?.wallets?.evm || null,
|
|
604
|
+
txHash: transactionHash,
|
|
605
|
+
next: null,
|
|
606
|
+
values: [transactionHash, blockNumber, gasUsed, gasPrice, ...logs.length > 0 ? logs : []],
|
|
607
|
+
results: {},
|
|
608
|
+
messages: {}
|
|
609
|
+
};
|
|
610
|
+
}
|
|
611
|
+
async extractQueryResults(warp, typedValues, actionIndex, inputs) {
|
|
612
|
+
const values = typedValues.map((t) => this.serializer.typedToString(t));
|
|
613
|
+
const valuesRaw = typedValues.map((t) => this.serializer.typedToNative(t)[1]);
|
|
614
|
+
let results = {};
|
|
615
|
+
if (!warp.results) return { values, results };
|
|
616
|
+
const getNestedValue = (path) => {
|
|
617
|
+
const indices = path.split(".").slice(1).map((i) => parseInt(i) - 1);
|
|
618
|
+
if (indices.length === 0) return void 0;
|
|
619
|
+
let value = valuesRaw[indices[0]];
|
|
620
|
+
for (let i = 1; i < indices.length; i++) {
|
|
621
|
+
if (value === void 0 || value === null) return void 0;
|
|
622
|
+
value = value[indices[i]];
|
|
623
|
+
}
|
|
624
|
+
return value;
|
|
625
|
+
};
|
|
626
|
+
for (const [key, path] of Object.entries(warp.results)) {
|
|
627
|
+
if (path.startsWith(WarpConstants2.Transform.Prefix)) continue;
|
|
628
|
+
const currentActionIndex = parseResultsOutIndex(path);
|
|
629
|
+
if (currentActionIndex !== null && currentActionIndex !== actionIndex) {
|
|
630
|
+
results[key] = null;
|
|
631
|
+
continue;
|
|
632
|
+
}
|
|
633
|
+
if (path.startsWith("out.") || path === "out" || path.startsWith("out[")) {
|
|
634
|
+
results[key] = getNestedValue(path) || null;
|
|
635
|
+
} else {
|
|
636
|
+
results[key] = path;
|
|
637
|
+
}
|
|
638
|
+
}
|
|
639
|
+
return { values, results: await evaluateResultsCommon(warp, results, actionIndex, inputs) };
|
|
640
|
+
}
|
|
641
|
+
};
|
|
642
|
+
|
|
643
|
+
// src/WarpEvmExecutor.ts
|
|
644
|
+
var WarpEvmExecutor = class {
|
|
645
|
+
constructor(config) {
|
|
646
|
+
this.config = config;
|
|
647
|
+
this.serializer = new WarpEvmSerializer();
|
|
648
|
+
this.provider = new ethers3.JsonRpcProvider(getEvmApiUrl(config.env));
|
|
649
|
+
this.results = new WarpEvmResults(config);
|
|
650
|
+
}
|
|
651
|
+
async createTransaction(executable) {
|
|
652
|
+
const action = getWarpActionByIndex(executable.warp, executable.action);
|
|
653
|
+
let tx = null;
|
|
654
|
+
if (action.type === "transfer") {
|
|
655
|
+
tx = await this.createTransferTransaction(executable);
|
|
656
|
+
} else if (action.type === "contract") {
|
|
657
|
+
tx = await this.createContractCallTransaction(executable);
|
|
658
|
+
} else if (action.type === "query") {
|
|
659
|
+
throw new Error("WarpEvmExecutor: Invalid action type for createTransaction; Use executeQuery instead");
|
|
660
|
+
} else if (action.type === "collect") {
|
|
661
|
+
throw new Error("WarpEvmExecutor: Invalid action type for createTransaction; Use executeCollect instead");
|
|
662
|
+
}
|
|
663
|
+
if (!tx) throw new Error(`WarpEvmExecutor: Invalid action type (${action.type})`);
|
|
664
|
+
return tx;
|
|
665
|
+
}
|
|
666
|
+
async createTransferTransaction(executable) {
|
|
667
|
+
const userWallet = this.config.user?.wallets?.[executable.chain.name];
|
|
668
|
+
if (!userWallet) throw new Error("WarpEvmExecutor: createTransfer - user address not set");
|
|
669
|
+
if (!ethers3.isAddress(executable.destination)) {
|
|
670
|
+
throw new Error(`WarpEvmExecutor: Invalid destination address: ${executable.destination}`);
|
|
671
|
+
}
|
|
672
|
+
if (executable.value < 0) {
|
|
673
|
+
throw new Error(`WarpEvmExecutor: Transfer value cannot be negative: ${executable.value}`);
|
|
674
|
+
}
|
|
675
|
+
const tx = {
|
|
676
|
+
to: executable.destination,
|
|
677
|
+
value: executable.value,
|
|
678
|
+
data: executable.data ? this.serializer.stringToTyped(executable.data) : "0x"
|
|
679
|
+
};
|
|
680
|
+
return this.estimateGasAndSetDefaults(tx, userWallet);
|
|
681
|
+
}
|
|
682
|
+
async createContractCallTransaction(executable) {
|
|
683
|
+
const userWallet = this.config.user?.wallets?.[executable.chain.name];
|
|
684
|
+
if (!userWallet) throw new Error("WarpEvmExecutor: createContractCall - user address not set");
|
|
685
|
+
const action = getWarpActionByIndex(executable.warp, executable.action);
|
|
686
|
+
if (!action || !("func" in action) || !action.func) {
|
|
687
|
+
throw new Error("WarpEvmExecutor: Contract action must have a function name");
|
|
688
|
+
}
|
|
689
|
+
if (!ethers3.isAddress(executable.destination)) {
|
|
690
|
+
throw new Error(`WarpEvmExecutor: Invalid contract address: ${executable.destination}`);
|
|
691
|
+
}
|
|
692
|
+
if (executable.value < 0) {
|
|
693
|
+
throw new Error(`WarpEvmExecutor: Contract call value cannot be negative: ${executable.value}`);
|
|
694
|
+
}
|
|
695
|
+
try {
|
|
696
|
+
const iface = new ethers3.Interface([`function ${action.func}`]);
|
|
697
|
+
const encodedData = iface.encodeFunctionData(action.func, executable.args);
|
|
698
|
+
const tx = {
|
|
699
|
+
to: executable.destination,
|
|
700
|
+
value: executable.value,
|
|
701
|
+
data: encodedData
|
|
702
|
+
};
|
|
703
|
+
return this.estimateGasAndSetDefaults(tx, userWallet);
|
|
704
|
+
} catch (error) {
|
|
705
|
+
throw new Error(`WarpEvmExecutor: Failed to encode function data for ${action.func}: ${error}`);
|
|
706
|
+
}
|
|
707
|
+
}
|
|
708
|
+
async executeQuery(executable) {
|
|
709
|
+
const action = getWarpActionByIndex(executable.warp, executable.action);
|
|
710
|
+
if (action.type !== "query") {
|
|
711
|
+
throw new Error(`WarpEvmExecutor: Invalid action type for executeQuery: ${action.type}`);
|
|
712
|
+
}
|
|
713
|
+
if (!action.func) {
|
|
714
|
+
throw new Error("WarpEvmExecutor: Query action must have a function name");
|
|
715
|
+
}
|
|
716
|
+
if (!ethers3.isAddress(executable.destination)) {
|
|
717
|
+
throw new Error(`WarpEvmExecutor: Invalid contract address for query: ${executable.destination}`);
|
|
718
|
+
}
|
|
719
|
+
try {
|
|
720
|
+
const iface = new ethers3.Interface([`function ${action.func}`]);
|
|
721
|
+
const encodedData = iface.encodeFunctionData(action.func, executable.args);
|
|
722
|
+
const result = await this.provider.call({
|
|
723
|
+
to: executable.destination,
|
|
724
|
+
data: encodedData
|
|
725
|
+
});
|
|
726
|
+
const decodedResult = iface.decodeFunctionResult(action.func, result);
|
|
727
|
+
const isSuccess = true;
|
|
728
|
+
const { values, results } = await this.results.extractQueryResults(
|
|
729
|
+
executable.warp,
|
|
730
|
+
decodedResult,
|
|
731
|
+
executable.action,
|
|
732
|
+
executable.resolvedInputs
|
|
733
|
+
);
|
|
734
|
+
const next = getNextInfo(this.config, [], executable.warp, executable.action, results);
|
|
735
|
+
return {
|
|
736
|
+
success: isSuccess,
|
|
737
|
+
warp: executable.warp,
|
|
738
|
+
action: executable.action,
|
|
739
|
+
user: this.config.user?.wallets?.[executable.chain.name] || null,
|
|
740
|
+
txHash: null,
|
|
741
|
+
next,
|
|
742
|
+
values,
|
|
743
|
+
results,
|
|
744
|
+
messages: applyResultsToMessages(executable.warp, results)
|
|
745
|
+
};
|
|
746
|
+
} catch (error) {
|
|
747
|
+
return {
|
|
748
|
+
success: false,
|
|
749
|
+
warp: executable.warp,
|
|
750
|
+
action: executable.action,
|
|
751
|
+
user: this.config.user?.wallets?.[executable.chain.name] || null,
|
|
752
|
+
txHash: null,
|
|
753
|
+
next: null,
|
|
754
|
+
values: [],
|
|
755
|
+
results: {},
|
|
756
|
+
messages: {}
|
|
757
|
+
};
|
|
758
|
+
}
|
|
759
|
+
}
|
|
760
|
+
async preprocessInput(chain, input, type, value) {
|
|
761
|
+
const typedValue = this.serializer.stringToTyped(value);
|
|
762
|
+
switch (type) {
|
|
763
|
+
case "address":
|
|
764
|
+
if (!ethers3.isAddress(typedValue)) {
|
|
765
|
+
throw new Error(`Invalid address format: ${typedValue}`);
|
|
766
|
+
}
|
|
767
|
+
return ethers3.getAddress(typedValue);
|
|
768
|
+
case "hex":
|
|
769
|
+
if (!ethers3.isHexString(typedValue)) {
|
|
770
|
+
throw new Error(`Invalid hex format: ${typedValue}`);
|
|
771
|
+
}
|
|
772
|
+
return typedValue;
|
|
773
|
+
case "uint8":
|
|
774
|
+
case "uint16":
|
|
775
|
+
case "uint32":
|
|
776
|
+
case "uint64":
|
|
777
|
+
case "biguint":
|
|
778
|
+
const bigIntValue = BigInt(typedValue);
|
|
779
|
+
if (bigIntValue < 0) {
|
|
780
|
+
throw new Error(`Negative value not allowed for type ${type}: ${typedValue}`);
|
|
781
|
+
}
|
|
782
|
+
return bigIntValue.toString();
|
|
783
|
+
default:
|
|
784
|
+
return String(typedValue);
|
|
785
|
+
}
|
|
786
|
+
}
|
|
787
|
+
async estimateGasAndSetDefaults(tx, from) {
|
|
788
|
+
try {
|
|
789
|
+
const gasEstimate = await this.provider.estimateGas({
|
|
790
|
+
...tx,
|
|
791
|
+
from
|
|
792
|
+
});
|
|
793
|
+
if (gasEstimate < BigInt(WarpEvmConstants.Validation.MinGasLimit)) {
|
|
794
|
+
throw new Error(`Gas estimate too low: ${gasEstimate}`);
|
|
795
|
+
}
|
|
796
|
+
if (gasEstimate > BigInt(WarpEvmConstants.Validation.MaxGasLimit)) {
|
|
797
|
+
throw new Error(`Gas estimate too high: ${gasEstimate}`);
|
|
798
|
+
}
|
|
799
|
+
const feeData = await this.provider.getFeeData();
|
|
800
|
+
if (feeData.maxFeePerGas && feeData.maxPriorityFeePerGas) {
|
|
801
|
+
return {
|
|
802
|
+
...tx,
|
|
803
|
+
gasLimit: gasEstimate,
|
|
804
|
+
maxFeePerGas: feeData.maxFeePerGas,
|
|
805
|
+
maxPriorityFeePerGas: feeData.maxPriorityFeePerGas
|
|
806
|
+
};
|
|
807
|
+
} else if (feeData.gasPrice) {
|
|
808
|
+
return {
|
|
809
|
+
...tx,
|
|
810
|
+
gasLimit: gasEstimate,
|
|
811
|
+
gasPrice: feeData.gasPrice
|
|
812
|
+
};
|
|
813
|
+
} else {
|
|
814
|
+
return {
|
|
815
|
+
...tx,
|
|
816
|
+
gasLimit: gasEstimate,
|
|
817
|
+
gasPrice: ethers3.parseUnits(WarpEvmConstants.GasPrice.Default, "wei")
|
|
818
|
+
};
|
|
819
|
+
}
|
|
820
|
+
} catch (error) {
|
|
821
|
+
let defaultGasLimit = BigInt(WarpEvmConstants.GasLimit.Default);
|
|
822
|
+
if (tx.data && tx.data !== "0x") {
|
|
823
|
+
defaultGasLimit = BigInt(WarpEvmConstants.GasLimit.ContractCall);
|
|
824
|
+
} else {
|
|
825
|
+
defaultGasLimit = BigInt(WarpEvmConstants.GasLimit.Transfer);
|
|
826
|
+
}
|
|
827
|
+
return {
|
|
828
|
+
...tx,
|
|
829
|
+
gasLimit: defaultGasLimit,
|
|
830
|
+
gasPrice: ethers3.parseUnits(WarpEvmConstants.GasPrice.Default, "wei")
|
|
831
|
+
};
|
|
832
|
+
}
|
|
833
|
+
}
|
|
834
|
+
async signMessage(message, privateKey) {
|
|
835
|
+
throw new Error("Not implemented");
|
|
836
|
+
}
|
|
837
|
+
};
|
|
838
|
+
|
|
839
|
+
// src/WarpEvmExplorer.ts
|
|
840
|
+
var WarpEvmExplorer = class {
|
|
841
|
+
constructor(chain, config) {
|
|
842
|
+
this.chain = chain;
|
|
843
|
+
this.config = config;
|
|
844
|
+
}
|
|
845
|
+
getExplorers() {
|
|
846
|
+
const chainExplorers = EvmExplorers[this.chain.name];
|
|
847
|
+
if (!chainExplorers) {
|
|
848
|
+
return ["Default"];
|
|
849
|
+
}
|
|
850
|
+
const explorers = chainExplorers[this.config.env];
|
|
851
|
+
if (!explorers) {
|
|
852
|
+
return ["Default"];
|
|
853
|
+
}
|
|
854
|
+
return explorers;
|
|
855
|
+
}
|
|
856
|
+
getPrimaryExplorer() {
|
|
857
|
+
const explorers = this.getExplorers();
|
|
858
|
+
return explorers[0];
|
|
859
|
+
}
|
|
860
|
+
getExplorerUrlByName(explorer) {
|
|
861
|
+
const userPreference = this.config.preferences?.explorers?.[this.chain.name];
|
|
862
|
+
if (userPreference && !explorer) {
|
|
863
|
+
const url2 = ExplorerUrls[userPreference];
|
|
864
|
+
if (url2) return url2;
|
|
865
|
+
}
|
|
866
|
+
if (explorer) {
|
|
867
|
+
const url2 = ExplorerUrls[explorer];
|
|
868
|
+
if (url2) return url2;
|
|
869
|
+
}
|
|
870
|
+
const primaryExplorer = this.getPrimaryExplorer();
|
|
871
|
+
const url = ExplorerUrls[primaryExplorer];
|
|
872
|
+
return url || ExplorerUrls[primaryExplorer];
|
|
873
|
+
}
|
|
874
|
+
getAccountUrl(address, explorer) {
|
|
875
|
+
const baseUrl = this.getExplorerUrlByName(explorer);
|
|
876
|
+
return `${baseUrl}/address/${address}`;
|
|
877
|
+
}
|
|
878
|
+
getTransactionUrl(hash, explorer) {
|
|
879
|
+
const baseUrl = this.getExplorerUrlByName(explorer);
|
|
880
|
+
return `${baseUrl}/tx/${hash}`;
|
|
881
|
+
}
|
|
882
|
+
getBlockUrl(blockNumber, explorer) {
|
|
883
|
+
const baseUrl = this.getExplorerUrlByName(explorer);
|
|
884
|
+
return `${baseUrl}/block/${blockNumber}`;
|
|
885
|
+
}
|
|
886
|
+
getAssetUrl(identifier, explorer) {
|
|
887
|
+
const baseUrl = this.getExplorerUrlByName(explorer);
|
|
888
|
+
return `${baseUrl}/token/${identifier}`;
|
|
889
|
+
}
|
|
890
|
+
getContractUrl(address, explorer) {
|
|
891
|
+
const baseUrl = this.getExplorerUrlByName(explorer);
|
|
892
|
+
return `${baseUrl}/address/${address}`;
|
|
893
|
+
}
|
|
894
|
+
getAllExplorers() {
|
|
895
|
+
return this.getExplorers();
|
|
896
|
+
}
|
|
897
|
+
getExplorerByName(name) {
|
|
898
|
+
const explorers = this.getExplorers();
|
|
899
|
+
return explorers.find((explorer) => explorer.toLowerCase() === name.toLowerCase());
|
|
900
|
+
}
|
|
901
|
+
getAccountUrls(address) {
|
|
902
|
+
const explorers = this.getAllExplorers();
|
|
903
|
+
const urls = {};
|
|
904
|
+
explorers.forEach((explorer) => {
|
|
905
|
+
const url = ExplorerUrls[explorer];
|
|
906
|
+
if (url) {
|
|
907
|
+
urls[explorer] = `${url}/address/${address}`;
|
|
908
|
+
}
|
|
909
|
+
});
|
|
910
|
+
return urls;
|
|
911
|
+
}
|
|
912
|
+
getTransactionUrls(hash) {
|
|
913
|
+
const explorers = this.getAllExplorers();
|
|
914
|
+
const urls = {};
|
|
915
|
+
explorers.forEach((explorer) => {
|
|
916
|
+
const url = ExplorerUrls[explorer];
|
|
917
|
+
if (url) {
|
|
918
|
+
urls[explorer] = `${url}/tx/${hash}`;
|
|
919
|
+
}
|
|
920
|
+
});
|
|
921
|
+
return urls;
|
|
922
|
+
}
|
|
923
|
+
};
|
|
924
|
+
|
|
925
|
+
// src/chains/common.ts
|
|
926
|
+
var createEvmAdapter = (chainName, chainPrefix, chainInfos) => {
|
|
927
|
+
return (config, fallback) => {
|
|
928
|
+
if (!fallback) throw new Error(`${chainName} adapter requires a fallback adapter`);
|
|
929
|
+
return {
|
|
930
|
+
chain: chainName,
|
|
931
|
+
chainInfo: chainInfos[config.env],
|
|
932
|
+
prefix: chainPrefix,
|
|
933
|
+
builder: () => fallback.builder(),
|
|
934
|
+
executor: new WarpEvmExecutor(config),
|
|
935
|
+
results: new WarpEvmResults(config),
|
|
936
|
+
serializer: new WarpEvmSerializer(),
|
|
937
|
+
registry: fallback.registry,
|
|
938
|
+
explorer: new WarpEvmExplorer(chainInfos[config.env], config),
|
|
939
|
+
abiBuilder: () => fallback.abiBuilder(),
|
|
940
|
+
brandBuilder: () => fallback.brandBuilder(),
|
|
941
|
+
dataLoader: new WarpEvmDataLoader(config, chainInfos[config.env])
|
|
942
|
+
};
|
|
943
|
+
};
|
|
944
|
+
};
|
|
945
|
+
|
|
946
|
+
// src/chains/arbitrum.ts
|
|
947
|
+
var ChainNameArbitrum = "arbitrum";
|
|
948
|
+
var getArbitrumAdapter = createEvmAdapter(ChainNameArbitrum, "arb", {
|
|
949
|
+
devnet: {
|
|
950
|
+
name: ChainNameArbitrum,
|
|
951
|
+
displayName: "Arbitrum Devnet",
|
|
952
|
+
chainId: "421614",
|
|
953
|
+
blockTime: 1e3,
|
|
954
|
+
addressHrp: "0x",
|
|
955
|
+
apiUrl: "https://sepolia-rollup.arbitrum.io/rpc",
|
|
956
|
+
nativeToken: "ETH"
|
|
957
|
+
},
|
|
958
|
+
testnet: {
|
|
959
|
+
name: ChainNameArbitrum,
|
|
960
|
+
displayName: "Arbitrum Testnet",
|
|
961
|
+
chainId: "421613",
|
|
962
|
+
blockTime: 1e3,
|
|
963
|
+
addressHrp: "0x",
|
|
964
|
+
apiUrl: "https://goerli-rollup.arbitrum.io/rpc",
|
|
965
|
+
nativeToken: "ETH"
|
|
966
|
+
},
|
|
967
|
+
mainnet: {
|
|
968
|
+
name: ChainNameArbitrum,
|
|
969
|
+
displayName: "Arbitrum",
|
|
970
|
+
chainId: "42161",
|
|
971
|
+
blockTime: 1e3,
|
|
972
|
+
addressHrp: "0x",
|
|
973
|
+
apiUrl: "https://arb1.arbitrum.io/rpc",
|
|
974
|
+
nativeToken: "ETH"
|
|
975
|
+
}
|
|
976
|
+
});
|
|
977
|
+
|
|
978
|
+
// src/chains/base.ts
|
|
979
|
+
var ChainNameBase = "base";
|
|
980
|
+
var getBaseAdapter = createEvmAdapter(ChainNameBase, "base", {
|
|
981
|
+
mainnet: {
|
|
982
|
+
name: ChainNameBase,
|
|
983
|
+
displayName: "Base",
|
|
984
|
+
chainId: "8453",
|
|
985
|
+
blockTime: 2e3,
|
|
986
|
+
addressHrp: "0x",
|
|
987
|
+
apiUrl: "https://mainnet.base.org",
|
|
988
|
+
nativeToken: "ETH"
|
|
989
|
+
},
|
|
990
|
+
testnet: {
|
|
991
|
+
name: ChainNameBase,
|
|
992
|
+
displayName: "Base Testnet",
|
|
993
|
+
chainId: "84531",
|
|
994
|
+
blockTime: 2e3,
|
|
995
|
+
addressHrp: "0x",
|
|
996
|
+
apiUrl: "https://goerli.base.org",
|
|
997
|
+
nativeToken: "ETH"
|
|
998
|
+
},
|
|
999
|
+
devnet: {
|
|
1000
|
+
name: ChainNameBase,
|
|
1001
|
+
displayName: "Base Devnet",
|
|
1002
|
+
chainId: "84532",
|
|
1003
|
+
blockTime: 2e3,
|
|
1004
|
+
addressHrp: "0x",
|
|
1005
|
+
apiUrl: "https://sepolia.base.org",
|
|
1006
|
+
nativeToken: "ETH"
|
|
1007
|
+
}
|
|
1008
|
+
});
|
|
1009
|
+
|
|
1010
|
+
// src/chains/ethereum.ts
|
|
1011
|
+
var ChainNameEthereum = "ethereum";
|
|
1012
|
+
var getEthereumAdapter = createEvmAdapter(ChainNameEthereum, "eth", {
|
|
1013
|
+
devnet: {
|
|
1014
|
+
name: ChainNameEthereum,
|
|
1015
|
+
displayName: "Ethereum Devnet",
|
|
1016
|
+
chainId: "11155111",
|
|
1017
|
+
blockTime: 12e3,
|
|
1018
|
+
addressHrp: "0x",
|
|
1019
|
+
apiUrl: "https://eth-sepolia.g.alchemy.com/v2/YOUR_API_KEY",
|
|
1020
|
+
nativeToken: "ETH"
|
|
1021
|
+
},
|
|
1022
|
+
testnet: {
|
|
1023
|
+
name: ChainNameEthereum,
|
|
1024
|
+
displayName: "Ethereum Testnet",
|
|
1025
|
+
chainId: "5",
|
|
1026
|
+
blockTime: 12e3,
|
|
1027
|
+
addressHrp: "0x",
|
|
1028
|
+
apiUrl: "https://eth-goerli.g.alchemy.com/v2/YOUR_API_KEY",
|
|
1029
|
+
nativeToken: "ETH"
|
|
1030
|
+
},
|
|
1031
|
+
mainnet: {
|
|
1032
|
+
name: ChainNameEthereum,
|
|
1033
|
+
displayName: "Ethereum Mainnet",
|
|
1034
|
+
chainId: "1",
|
|
1035
|
+
blockTime: 12e3,
|
|
1036
|
+
addressHrp: "0x",
|
|
1037
|
+
apiUrl: "https://eth-mainnet.g.alchemy.com/v2/YOUR_API_KEY",
|
|
1038
|
+
nativeToken: "ETH"
|
|
1039
|
+
}
|
|
1040
|
+
});
|
|
1041
|
+
|
|
1042
|
+
// src/chains/combined.ts
|
|
1043
|
+
var getAllEvmAdapters = (config, fallback) => [
|
|
1044
|
+
getEthereumAdapter(config, fallback),
|
|
1045
|
+
getArbitrumAdapter(config, fallback),
|
|
1046
|
+
getBaseAdapter(config, fallback)
|
|
1047
|
+
];
|
|
1048
|
+
var getAllEvmChainNames = () => [ChainNameArbitrum, ChainNameBase, ChainNameEthereum];
|
|
1049
|
+
export {
|
|
1050
|
+
ArbitrumExplorers,
|
|
1051
|
+
BaseExplorers,
|
|
1052
|
+
ChainNameArbitrum,
|
|
1053
|
+
ChainNameBase,
|
|
1054
|
+
ChainNameEthereum,
|
|
1055
|
+
EVM_CHAIN_CONFIGS,
|
|
1056
|
+
EthereumExplorers,
|
|
1057
|
+
EvmExplorers,
|
|
1058
|
+
ExplorerUrls,
|
|
1059
|
+
WarpEvmConstants,
|
|
1060
|
+
WarpEvmExecutor,
|
|
1061
|
+
WarpEvmExplorer,
|
|
1062
|
+
WarpEvmResults,
|
|
1063
|
+
WarpEvmSerializer,
|
|
1064
|
+
getAllEvmAdapters,
|
|
1065
|
+
getAllEvmChainNames,
|
|
1066
|
+
getArbitrumAdapter,
|
|
1067
|
+
getBaseAdapter,
|
|
1068
|
+
getEthereumAdapter,
|
|
1069
|
+
getEvmApiUrl,
|
|
1070
|
+
getEvmChainConfig,
|
|
1071
|
+
getEvmExplorerUrl
|
|
1072
|
+
};
|
|
1073
|
+
//# sourceMappingURL=index.mjs.map
|