@joai/warps-adapter-evm 1.0.0-beta.74
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 +64 -0
- package/dist/index.d.cts +296 -0
- package/dist/index.d.ts +296 -0
- package/dist/index.js +2329 -0
- package/dist/index.js.map +1 -0
- package/dist/index.mjs +2301 -0
- package/dist/index.mjs.map +1 -0
- package/package.json +44 -0
package/dist/index.mjs
ADDED
|
@@ -0,0 +1,2301 @@
|
|
|
1
|
+
// src/chains/arbitrum.ts
|
|
2
|
+
import { WarpChainName as WarpChainName10 } from "@joai/warps";
|
|
3
|
+
|
|
4
|
+
// src/WarpEvmDataLoader.ts
|
|
5
|
+
import {
|
|
6
|
+
CacheTtl as CacheTtl2,
|
|
7
|
+
getProviderConfig,
|
|
8
|
+
getWarpChainAssetLogoUrl,
|
|
9
|
+
WarpCache as WarpCache2,
|
|
10
|
+
WarpCacheKey
|
|
11
|
+
} from "@joai/warps";
|
|
12
|
+
import { ethers as ethers3 } from "ethers";
|
|
13
|
+
|
|
14
|
+
// src/providers/UniswapService.ts
|
|
15
|
+
import { CacheTtl } from "@joai/warps";
|
|
16
|
+
var _UniswapService = class _UniswapService {
|
|
17
|
+
constructor(cache, chainId) {
|
|
18
|
+
this.cache = cache;
|
|
19
|
+
this.chainId = chainId;
|
|
20
|
+
}
|
|
21
|
+
async getTokenList() {
|
|
22
|
+
try {
|
|
23
|
+
const response = await fetch(_UniswapService.UNISWAP_TOKEN_LIST_URL);
|
|
24
|
+
if (!response.ok) {
|
|
25
|
+
throw new Error(`Failed to fetch Uniswap token list: ${response.status}`);
|
|
26
|
+
}
|
|
27
|
+
const tokenList = await response.json();
|
|
28
|
+
return tokenList;
|
|
29
|
+
} catch (error) {
|
|
30
|
+
throw new Error(`Failed to fetch Uniswap token list: ${error}`);
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
async findToken(address) {
|
|
34
|
+
const normalizedAddress = address.toLowerCase();
|
|
35
|
+
const cacheKey = `uniswap:token:${this.chainId}:${normalizedAddress}`;
|
|
36
|
+
const cachedToken = this.cache.get(cacheKey);
|
|
37
|
+
if (cachedToken) {
|
|
38
|
+
return cachedToken;
|
|
39
|
+
}
|
|
40
|
+
try {
|
|
41
|
+
const tokenList = await this.getTokenList();
|
|
42
|
+
const token = tokenList.tokens.find((token2) => token2.address.toLowerCase() === normalizedAddress) || null;
|
|
43
|
+
if (token && token.chainId !== this.chainId) {
|
|
44
|
+
return null;
|
|
45
|
+
}
|
|
46
|
+
if (token) {
|
|
47
|
+
this.cache.set(cacheKey, token, CacheTtl.OneHour);
|
|
48
|
+
} else {
|
|
49
|
+
this.cache.set(cacheKey, null, CacheTtl.OneMinute * 5);
|
|
50
|
+
}
|
|
51
|
+
return token;
|
|
52
|
+
} catch (error) {
|
|
53
|
+
return null;
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
async getTokenMetadata(address) {
|
|
57
|
+
const normalizedAddress = address.toLowerCase();
|
|
58
|
+
const cacheKey = `uniswap:metadata:${this.chainId}:${normalizedAddress}`;
|
|
59
|
+
const cachedMetadata = this.cache.get(cacheKey);
|
|
60
|
+
if (cachedMetadata !== null) {
|
|
61
|
+
return cachedMetadata;
|
|
62
|
+
}
|
|
63
|
+
const token = await this.findToken(address);
|
|
64
|
+
if (!token) {
|
|
65
|
+
this.cache.set(cacheKey, null, CacheTtl.OneMinute * 5);
|
|
66
|
+
return null;
|
|
67
|
+
}
|
|
68
|
+
const metadata = {
|
|
69
|
+
name: token.name,
|
|
70
|
+
symbol: token.symbol,
|
|
71
|
+
decimals: token.decimals,
|
|
72
|
+
logoUrl: token.logoURI
|
|
73
|
+
};
|
|
74
|
+
this.cache.set(cacheKey, metadata, CacheTtl.OneHour);
|
|
75
|
+
return metadata;
|
|
76
|
+
}
|
|
77
|
+
async getBridgeInfo(address) {
|
|
78
|
+
const normalizedAddress = address.toLowerCase();
|
|
79
|
+
const cacheKey = `uniswap:bridge:${this.chainId}:${normalizedAddress}`;
|
|
80
|
+
const cachedBridgeInfo = this.cache.get(cacheKey);
|
|
81
|
+
if (cachedBridgeInfo !== null) {
|
|
82
|
+
return cachedBridgeInfo;
|
|
83
|
+
}
|
|
84
|
+
const token = await this.findToken(address);
|
|
85
|
+
if (!token?.extensions?.bridgeInfo) {
|
|
86
|
+
this.cache.set(cacheKey, null, CacheTtl.OneMinute * 5);
|
|
87
|
+
return null;
|
|
88
|
+
}
|
|
89
|
+
const bridgeInfo = {};
|
|
90
|
+
for (const [chainId, info] of Object.entries(token.extensions.bridgeInfo)) {
|
|
91
|
+
bridgeInfo[chainId] = info.tokenAddress;
|
|
92
|
+
}
|
|
93
|
+
this.cache.set(cacheKey, bridgeInfo, CacheTtl.OneHour);
|
|
94
|
+
return bridgeInfo;
|
|
95
|
+
}
|
|
96
|
+
};
|
|
97
|
+
_UniswapService.UNISWAP_TOKEN_LIST_URL = "https://tokens.uniswap.org";
|
|
98
|
+
var UniswapService = _UniswapService;
|
|
99
|
+
|
|
100
|
+
// src/providers/PrivateKeyWalletProvider.ts
|
|
101
|
+
import { ethers } from "ethers";
|
|
102
|
+
import {
|
|
103
|
+
getWarpWalletMnemonicFromConfig,
|
|
104
|
+
getWarpWalletPrivateKeyFromConfig,
|
|
105
|
+
setWarpWalletInConfig
|
|
106
|
+
} from "@joai/warps";
|
|
107
|
+
var _PrivateKeyWalletProvider = class _PrivateKeyWalletProvider {
|
|
108
|
+
constructor(config, chain) {
|
|
109
|
+
this.config = config;
|
|
110
|
+
this.chain = chain;
|
|
111
|
+
this.wallet = null;
|
|
112
|
+
}
|
|
113
|
+
async getAddress() {
|
|
114
|
+
try {
|
|
115
|
+
const wallet = this.getWallet();
|
|
116
|
+
return wallet.address;
|
|
117
|
+
} catch {
|
|
118
|
+
return null;
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
async getPublicKey() {
|
|
122
|
+
try {
|
|
123
|
+
const wallet = this.getWallet();
|
|
124
|
+
const publicKey = wallet.signingKey.publicKey;
|
|
125
|
+
return publicKey.startsWith("0x") ? publicKey.slice(2) : publicKey;
|
|
126
|
+
} catch {
|
|
127
|
+
return null;
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
async signTransaction(tx) {
|
|
131
|
+
const wallet = this.getWallet();
|
|
132
|
+
const txRequest = {
|
|
133
|
+
to: tx.to,
|
|
134
|
+
data: tx.data,
|
|
135
|
+
value: tx.value || 0,
|
|
136
|
+
gasLimit: tx.gasLimit,
|
|
137
|
+
maxFeePerGas: tx.maxFeePerGas,
|
|
138
|
+
maxPriorityFeePerGas: tx.maxPriorityFeePerGas,
|
|
139
|
+
nonce: tx.nonce,
|
|
140
|
+
chainId: tx.chainId
|
|
141
|
+
};
|
|
142
|
+
const signedTx = await wallet.signTransaction(txRequest);
|
|
143
|
+
return { ...tx, signature: signedTx };
|
|
144
|
+
}
|
|
145
|
+
async signMessage(message) {
|
|
146
|
+
const wallet = this.getWallet();
|
|
147
|
+
return await wallet.signMessage(message);
|
|
148
|
+
}
|
|
149
|
+
getWalletInstance() {
|
|
150
|
+
return this.getWallet();
|
|
151
|
+
}
|
|
152
|
+
async importFromMnemonic(mnemonic) {
|
|
153
|
+
const wallet = ethers.Wallet.fromPhrase(mnemonic);
|
|
154
|
+
const walletDetails = {
|
|
155
|
+
provider: _PrivateKeyWalletProvider.PROVIDER_NAME,
|
|
156
|
+
address: wallet.address,
|
|
157
|
+
privateKey: wallet.privateKey,
|
|
158
|
+
mnemonic
|
|
159
|
+
};
|
|
160
|
+
setWarpWalletInConfig(this.config, this.chain.name, walletDetails);
|
|
161
|
+
return walletDetails;
|
|
162
|
+
}
|
|
163
|
+
async importFromPrivateKey(privateKey) {
|
|
164
|
+
const wallet = new ethers.Wallet(privateKey);
|
|
165
|
+
const walletDetails = {
|
|
166
|
+
provider: _PrivateKeyWalletProvider.PROVIDER_NAME,
|
|
167
|
+
address: wallet.address,
|
|
168
|
+
privateKey: wallet.privateKey,
|
|
169
|
+
mnemonic: null
|
|
170
|
+
};
|
|
171
|
+
setWarpWalletInConfig(this.config, this.chain.name, walletDetails);
|
|
172
|
+
return walletDetails;
|
|
173
|
+
}
|
|
174
|
+
async export() {
|
|
175
|
+
const wallet = this.getWallet();
|
|
176
|
+
const mnemonic = getWarpWalletMnemonicFromConfig(this.config, this.chain.name);
|
|
177
|
+
return {
|
|
178
|
+
provider: _PrivateKeyWalletProvider.PROVIDER_NAME,
|
|
179
|
+
address: wallet.address,
|
|
180
|
+
privateKey: wallet.privateKey,
|
|
181
|
+
mnemonic: mnemonic || null
|
|
182
|
+
};
|
|
183
|
+
}
|
|
184
|
+
async generate() {
|
|
185
|
+
const wallet = ethers.Wallet.createRandom();
|
|
186
|
+
return {
|
|
187
|
+
provider: _PrivateKeyWalletProvider.PROVIDER_NAME,
|
|
188
|
+
address: wallet.address,
|
|
189
|
+
privateKey: wallet.privateKey,
|
|
190
|
+
mnemonic: null
|
|
191
|
+
};
|
|
192
|
+
}
|
|
193
|
+
getWallet() {
|
|
194
|
+
if (this.wallet) return this.wallet;
|
|
195
|
+
const privateKey = getWarpWalletPrivateKeyFromConfig(this.config, this.chain.name);
|
|
196
|
+
if (!privateKey) throw new Error("No private key provided");
|
|
197
|
+
this.wallet = new ethers.Wallet(privateKey);
|
|
198
|
+
return this.wallet;
|
|
199
|
+
}
|
|
200
|
+
};
|
|
201
|
+
_PrivateKeyWalletProvider.PROVIDER_NAME = "privateKey";
|
|
202
|
+
var PrivateKeyWalletProvider = _PrivateKeyWalletProvider;
|
|
203
|
+
|
|
204
|
+
// src/providers/MnemonicWalletProvider.ts
|
|
205
|
+
import { ethers as ethers2, HDNodeWallet } from "ethers";
|
|
206
|
+
import * as bip39 from "@scure/bip39";
|
|
207
|
+
import { wordlist } from "@scure/bip39/wordlists/english.js";
|
|
208
|
+
import {
|
|
209
|
+
getWarpWalletMnemonicFromConfig as getWarpWalletMnemonicFromConfig2,
|
|
210
|
+
getWarpWalletPrivateKeyFromConfig as getWarpWalletPrivateKeyFromConfig2,
|
|
211
|
+
normalizeAndValidateMnemonic,
|
|
212
|
+
normalizeMnemonic,
|
|
213
|
+
setWarpWalletInConfig as setWarpWalletInConfig2,
|
|
214
|
+
validateMnemonicLength
|
|
215
|
+
} from "@joai/warps";
|
|
216
|
+
var _MnemonicWalletProvider = class _MnemonicWalletProvider {
|
|
217
|
+
constructor(config, chain) {
|
|
218
|
+
this.config = config;
|
|
219
|
+
this.chain = chain;
|
|
220
|
+
this.wallet = null;
|
|
221
|
+
}
|
|
222
|
+
async getAddress() {
|
|
223
|
+
try {
|
|
224
|
+
const wallet = this.getWallet();
|
|
225
|
+
return wallet.address;
|
|
226
|
+
} catch {
|
|
227
|
+
return null;
|
|
228
|
+
}
|
|
229
|
+
}
|
|
230
|
+
async getPublicKey() {
|
|
231
|
+
try {
|
|
232
|
+
const wallet = this.getWallet();
|
|
233
|
+
const publicKey = wallet.signingKey.publicKey;
|
|
234
|
+
return publicKey.startsWith("0x") ? publicKey.slice(2) : publicKey;
|
|
235
|
+
} catch {
|
|
236
|
+
return null;
|
|
237
|
+
}
|
|
238
|
+
}
|
|
239
|
+
async signTransaction(tx) {
|
|
240
|
+
const wallet = this.getWallet();
|
|
241
|
+
const txRequest = {
|
|
242
|
+
to: tx.to,
|
|
243
|
+
data: tx.data,
|
|
244
|
+
value: tx.value || 0,
|
|
245
|
+
gasLimit: tx.gasLimit,
|
|
246
|
+
maxFeePerGas: tx.maxFeePerGas,
|
|
247
|
+
maxPriorityFeePerGas: tx.maxPriorityFeePerGas,
|
|
248
|
+
nonce: tx.nonce,
|
|
249
|
+
chainId: tx.chainId
|
|
250
|
+
};
|
|
251
|
+
const signedTx = await wallet.signTransaction(txRequest);
|
|
252
|
+
return { ...tx, signature: signedTx };
|
|
253
|
+
}
|
|
254
|
+
async signMessage(message) {
|
|
255
|
+
const wallet = this.getWallet();
|
|
256
|
+
return await wallet.signMessage(message);
|
|
257
|
+
}
|
|
258
|
+
getWalletInstance() {
|
|
259
|
+
return this.getWallet();
|
|
260
|
+
}
|
|
261
|
+
async importFromMnemonic(mnemonic) {
|
|
262
|
+
const trimmedMnemonic = normalizeAndValidateMnemonic(mnemonic);
|
|
263
|
+
const wallet = HDNodeWallet.fromPhrase(trimmedMnemonic);
|
|
264
|
+
const walletDetails = {
|
|
265
|
+
provider: _MnemonicWalletProvider.PROVIDER_NAME,
|
|
266
|
+
address: wallet.address,
|
|
267
|
+
privateKey: wallet.privateKey,
|
|
268
|
+
mnemonic: trimmedMnemonic
|
|
269
|
+
};
|
|
270
|
+
setWarpWalletInConfig2(this.config, this.chain.name, walletDetails);
|
|
271
|
+
return walletDetails;
|
|
272
|
+
}
|
|
273
|
+
async importFromPrivateKey(privateKey) {
|
|
274
|
+
const wallet = new ethers2.Wallet(privateKey);
|
|
275
|
+
const walletDetails = {
|
|
276
|
+
provider: _MnemonicWalletProvider.PROVIDER_NAME,
|
|
277
|
+
address: wallet.address,
|
|
278
|
+
privateKey: wallet.privateKey,
|
|
279
|
+
mnemonic: null
|
|
280
|
+
};
|
|
281
|
+
setWarpWalletInConfig2(this.config, this.chain.name, walletDetails);
|
|
282
|
+
return walletDetails;
|
|
283
|
+
}
|
|
284
|
+
async export() {
|
|
285
|
+
const wallet = this.getWallet();
|
|
286
|
+
const mnemonic = getWarpWalletMnemonicFromConfig2(this.config, this.chain.name);
|
|
287
|
+
const privateKey = getWarpWalletPrivateKeyFromConfig2(this.config, this.chain.name);
|
|
288
|
+
return {
|
|
289
|
+
provider: _MnemonicWalletProvider.PROVIDER_NAME,
|
|
290
|
+
address: wallet.address,
|
|
291
|
+
privateKey: privateKey || null,
|
|
292
|
+
mnemonic: mnemonic || null
|
|
293
|
+
};
|
|
294
|
+
}
|
|
295
|
+
async generate() {
|
|
296
|
+
const mnemonicRaw = bip39.generateMnemonic(wordlist, 256);
|
|
297
|
+
const mnemonic = normalizeMnemonic(mnemonicRaw);
|
|
298
|
+
validateMnemonicLength(mnemonic);
|
|
299
|
+
const wallet = HDNodeWallet.fromPhrase(mnemonic);
|
|
300
|
+
return {
|
|
301
|
+
provider: _MnemonicWalletProvider.PROVIDER_NAME,
|
|
302
|
+
address: wallet.address,
|
|
303
|
+
privateKey: null,
|
|
304
|
+
mnemonic
|
|
305
|
+
};
|
|
306
|
+
}
|
|
307
|
+
getWallet() {
|
|
308
|
+
if (this.wallet) return this.wallet;
|
|
309
|
+
const mnemonic = getWarpWalletMnemonicFromConfig2(this.config, this.chain.name);
|
|
310
|
+
if (!mnemonic) throw new Error("No mnemonic provided");
|
|
311
|
+
this.wallet = HDNodeWallet.fromPhrase(mnemonic.trim());
|
|
312
|
+
return this.wallet;
|
|
313
|
+
}
|
|
314
|
+
};
|
|
315
|
+
_MnemonicWalletProvider.PROVIDER_NAME = "mnemonic";
|
|
316
|
+
var MnemonicWalletProvider = _MnemonicWalletProvider;
|
|
317
|
+
|
|
318
|
+
// src/providers/ReadOnlyWalletProvider.ts
|
|
319
|
+
import { getWarpWalletAddressFromConfig } from "@joai/warps";
|
|
320
|
+
var ReadOnlyWalletProvider = class {
|
|
321
|
+
constructor(config, chain) {
|
|
322
|
+
this.config = config;
|
|
323
|
+
this.chain = chain;
|
|
324
|
+
}
|
|
325
|
+
async getAddress() {
|
|
326
|
+
return getWarpWalletAddressFromConfig(this.config, this.chain.name);
|
|
327
|
+
}
|
|
328
|
+
async getPublicKey() {
|
|
329
|
+
return null;
|
|
330
|
+
}
|
|
331
|
+
async signTransaction(tx) {
|
|
332
|
+
const address = await this.getAddress();
|
|
333
|
+
throw new Error(`Wallet can not be used for signing: ${address}`);
|
|
334
|
+
}
|
|
335
|
+
async signMessage(message) {
|
|
336
|
+
const address = await this.getAddress();
|
|
337
|
+
throw new Error(`Wallet can not be used for signing: ${address}`);
|
|
338
|
+
}
|
|
339
|
+
async importFromMnemonic(mnemonic) {
|
|
340
|
+
const address = getWarpWalletAddressFromConfig(this.config, this.chain.name);
|
|
341
|
+
throw new Error(`Wallet can not be used for signing: ${address}`);
|
|
342
|
+
}
|
|
343
|
+
async importFromPrivateKey(privateKey) {
|
|
344
|
+
const address = getWarpWalletAddressFromConfig(this.config, this.chain.name);
|
|
345
|
+
throw new Error(`Wallet can not be used for signing: ${address}`);
|
|
346
|
+
}
|
|
347
|
+
async export() {
|
|
348
|
+
const address = getWarpWalletAddressFromConfig(this.config, this.chain.name);
|
|
349
|
+
throw new Error(`Wallet can not be used for signing: ${address}`);
|
|
350
|
+
}
|
|
351
|
+
async generate() {
|
|
352
|
+
const address = getWarpWalletAddressFromConfig(this.config, this.chain.name);
|
|
353
|
+
throw new Error(`Wallet can not be used for signing: ${address}`);
|
|
354
|
+
}
|
|
355
|
+
};
|
|
356
|
+
|
|
357
|
+
// src/tokens.ts
|
|
358
|
+
import { WarpChainName as WarpChainName9 } from "@joai/warps";
|
|
359
|
+
|
|
360
|
+
// src/tokens/arbitrum.ts
|
|
361
|
+
import { WarpChainName } from "@joai/warps";
|
|
362
|
+
var ArbitrumChain = WarpChainName.Arbitrum;
|
|
363
|
+
var ArbitrumTokens = [
|
|
364
|
+
{
|
|
365
|
+
chain: ArbitrumChain,
|
|
366
|
+
identifier: "0x0000000000000000000000000000000000000000",
|
|
367
|
+
name: "Ether",
|
|
368
|
+
symbol: "ETH",
|
|
369
|
+
decimals: 18,
|
|
370
|
+
logoUrl: "https://assets.coingecko.com/coins/images/279/small/ethereum.png"
|
|
371
|
+
},
|
|
372
|
+
{
|
|
373
|
+
chain: ArbitrumChain,
|
|
374
|
+
identifier: "0xFF970A61A04b1cA14834A43f5dE4533eBDDB5CC8",
|
|
375
|
+
name: "USD Coin",
|
|
376
|
+
symbol: "USDC",
|
|
377
|
+
decimals: 6,
|
|
378
|
+
logoUrl: "https://assets.coingecko.com/coins/images/6319/small/USD_Coin_icon.png"
|
|
379
|
+
},
|
|
380
|
+
{
|
|
381
|
+
chain: ArbitrumChain,
|
|
382
|
+
identifier: "0xFd086bC7CD5C481DCC9C85ebE478A1C0b69FCbb9",
|
|
383
|
+
name: "Tether USD",
|
|
384
|
+
symbol: "USDT",
|
|
385
|
+
decimals: 6,
|
|
386
|
+
logoUrl: "https://assets.coingecko.com/coins/images/325/small/Tether.png"
|
|
387
|
+
},
|
|
388
|
+
{
|
|
389
|
+
chain: ArbitrumChain,
|
|
390
|
+
identifier: "0x82aF49447D8a07e3bd95BD0d56f35241523fBab1",
|
|
391
|
+
name: "Wrapped Ether",
|
|
392
|
+
symbol: "WETH",
|
|
393
|
+
decimals: 18,
|
|
394
|
+
logoUrl: "https://assets.coingecko.com/coins/images/2518/small/weth.png"
|
|
395
|
+
}
|
|
396
|
+
];
|
|
397
|
+
|
|
398
|
+
// src/tokens/arbitrum-sepolia.ts
|
|
399
|
+
import { WarpChainName as WarpChainName2 } from "@joai/warps";
|
|
400
|
+
var ArbitrumChain2 = WarpChainName2.Arbitrum;
|
|
401
|
+
var ArbitrumSepoliaTokens = [
|
|
402
|
+
{
|
|
403
|
+
chain: ArbitrumChain2,
|
|
404
|
+
identifier: "0x0000000000000000000000000000000000000000",
|
|
405
|
+
name: "Ether",
|
|
406
|
+
symbol: "ETH",
|
|
407
|
+
decimals: 18,
|
|
408
|
+
logoUrl: "https://assets.coingecko.com/coins/images/279/small/ethereum.png"
|
|
409
|
+
},
|
|
410
|
+
{
|
|
411
|
+
chain: ArbitrumChain2,
|
|
412
|
+
identifier: "0x980B62Da83eFf3D4576C647993b0c1D7faf17c73",
|
|
413
|
+
name: "Wrapped Ether",
|
|
414
|
+
symbol: "WETH",
|
|
415
|
+
decimals: 18,
|
|
416
|
+
logoUrl: "https://assets.coingecko.com/coins/images/2518/small/weth.png"
|
|
417
|
+
},
|
|
418
|
+
{
|
|
419
|
+
chain: ArbitrumChain2,
|
|
420
|
+
identifier: "0xC6d2Bd6437655FBc6689Bfc987E09846aC4367Ed",
|
|
421
|
+
name: "Wrapped SET",
|
|
422
|
+
symbol: "WSET",
|
|
423
|
+
decimals: 18,
|
|
424
|
+
logoUrl: "https://raw.githubusercontent.com/JoAiHQ/assets/refs/heads/main/tokens/logos/set-black.svg"
|
|
425
|
+
}
|
|
426
|
+
];
|
|
427
|
+
|
|
428
|
+
// src/tokens/base.ts
|
|
429
|
+
import { WarpChainName as WarpChainName3 } from "@joai/warps";
|
|
430
|
+
var BaseChain = WarpChainName3.Base;
|
|
431
|
+
var BaseTokens = [
|
|
432
|
+
{
|
|
433
|
+
chain: BaseChain,
|
|
434
|
+
identifier: "0x0000000000000000000000000000000000000000",
|
|
435
|
+
name: "Ether",
|
|
436
|
+
symbol: "ETH",
|
|
437
|
+
decimals: 18,
|
|
438
|
+
logoUrl: "https://assets.coingecko.com/coins/images/279/small/ethereum.png"
|
|
439
|
+
},
|
|
440
|
+
{
|
|
441
|
+
chain: BaseChain,
|
|
442
|
+
identifier: "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913",
|
|
443
|
+
name: "USD Coin",
|
|
444
|
+
symbol: "USDC",
|
|
445
|
+
decimals: 6,
|
|
446
|
+
logoUrl: "https://assets.coingecko.com/coins/images/6319/small/USD_Coin_icon.png"
|
|
447
|
+
},
|
|
448
|
+
{
|
|
449
|
+
chain: BaseChain,
|
|
450
|
+
identifier: "0x4200000000000000000000000000000000000006",
|
|
451
|
+
name: "Wrapped Ether",
|
|
452
|
+
symbol: "WETH",
|
|
453
|
+
decimals: 18,
|
|
454
|
+
logoUrl: "https://assets.coingecko.com/coins/images/2518/small/weth.png"
|
|
455
|
+
},
|
|
456
|
+
{
|
|
457
|
+
chain: BaseChain,
|
|
458
|
+
identifier: "0x808456652fdb597867f38412077A9182bf77359F",
|
|
459
|
+
name: "Euro",
|
|
460
|
+
symbol: "EURC",
|
|
461
|
+
decimals: 6,
|
|
462
|
+
logoUrl: "https://assets.coingecko.com/coins/images/26045/standard/euro.png"
|
|
463
|
+
},
|
|
464
|
+
{
|
|
465
|
+
chain: BaseChain,
|
|
466
|
+
identifier: "0xcbB7C0006F23900c38EB856149F799620fcb8A4a",
|
|
467
|
+
name: "Coinbase Wrapped BTC",
|
|
468
|
+
symbol: "CBETH",
|
|
469
|
+
decimals: 8,
|
|
470
|
+
logoUrl: "https://assets.coingecko.com/coins/images/7598/small/wrapped_bitcoin_wbtc.png"
|
|
471
|
+
}
|
|
472
|
+
];
|
|
473
|
+
|
|
474
|
+
// src/tokens/base-sepolia.ts
|
|
475
|
+
import { WarpChainName as WarpChainName4 } from "@joai/warps";
|
|
476
|
+
var BaseChain2 = WarpChainName4.Base;
|
|
477
|
+
var BaseSepoliaTokens = [
|
|
478
|
+
{
|
|
479
|
+
chain: BaseChain2,
|
|
480
|
+
identifier: "0x0000000000000000000000000000000000000000",
|
|
481
|
+
name: "Ether",
|
|
482
|
+
symbol: "ETH",
|
|
483
|
+
decimals: 18,
|
|
484
|
+
logoUrl: "https://assets.coingecko.com/coins/images/279/small/ethereum.png"
|
|
485
|
+
},
|
|
486
|
+
{
|
|
487
|
+
chain: BaseChain2,
|
|
488
|
+
identifier: "0x036CbD53842c5426634e7929541eC2318f3dCF7e",
|
|
489
|
+
name: "USD",
|
|
490
|
+
symbol: "USDC",
|
|
491
|
+
decimals: 6,
|
|
492
|
+
logoUrl: "https://assets.coingecko.com/coins/images/6319/small/USD_Coin_icon.png"
|
|
493
|
+
},
|
|
494
|
+
{
|
|
495
|
+
chain: BaseChain2,
|
|
496
|
+
identifier: "0x808456652fdb597867f38412077A9182bf77359F",
|
|
497
|
+
name: "Euro",
|
|
498
|
+
symbol: "EURC",
|
|
499
|
+
decimals: 6,
|
|
500
|
+
logoUrl: "https://assets.coingecko.com/coins/images/26045/thumb/euro-coin.png?1655394420"
|
|
501
|
+
},
|
|
502
|
+
{
|
|
503
|
+
chain: BaseChain2,
|
|
504
|
+
identifier: "0xcbB7C0006F23900c38EB856149F799620fcb8A4a",
|
|
505
|
+
name: "Wrapped Bitcoin",
|
|
506
|
+
symbol: "WBTC",
|
|
507
|
+
decimals: 8,
|
|
508
|
+
logoUrl: "https://assets.coingecko.com/coins/images/7598/small/wrapped_bitcoin_wbtc.png"
|
|
509
|
+
}
|
|
510
|
+
];
|
|
511
|
+
|
|
512
|
+
// src/tokens/ethereum.ts
|
|
513
|
+
import { WarpChainName as WarpChainName5 } from "@joai/warps";
|
|
514
|
+
var EthereumChain = WarpChainName5.Ethereum;
|
|
515
|
+
var EthereumTokens = [
|
|
516
|
+
{
|
|
517
|
+
chain: EthereumChain,
|
|
518
|
+
identifier: "0x0000000000000000000000000000000000000000",
|
|
519
|
+
name: "Ether",
|
|
520
|
+
symbol: "ETH",
|
|
521
|
+
decimals: 18,
|
|
522
|
+
logoUrl: "https://assets.coingecko.com/coins/images/279/small/ethereum.png"
|
|
523
|
+
},
|
|
524
|
+
{
|
|
525
|
+
chain: EthereumChain,
|
|
526
|
+
identifier: "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48",
|
|
527
|
+
name: "USD Coin",
|
|
528
|
+
symbol: "USDC",
|
|
529
|
+
decimals: 6,
|
|
530
|
+
logoUrl: "https://assets.coingecko.com/coins/images/6319/small/USD_Coin_icon.png"
|
|
531
|
+
},
|
|
532
|
+
{
|
|
533
|
+
chain: EthereumChain,
|
|
534
|
+
identifier: "0xdAC17F958D2ee523a2206206994597C13D831ec7",
|
|
535
|
+
name: "Tether USD",
|
|
536
|
+
symbol: "USDT",
|
|
537
|
+
decimals: 6,
|
|
538
|
+
logoUrl: "https://assets.coingecko.com/coins/images/325/small/Tether.png"
|
|
539
|
+
},
|
|
540
|
+
{
|
|
541
|
+
chain: EthereumChain,
|
|
542
|
+
identifier: "0x2260FAC5E5542a773Aa44fBCfeDf7C193bc2C599",
|
|
543
|
+
name: "Wrapped Bitcoin",
|
|
544
|
+
symbol: "WBTC",
|
|
545
|
+
decimals: 8,
|
|
546
|
+
logoUrl: "https://assets.coingecko.com/coins/images/7598/small/wrapped_bitcoin_wbtc.png"
|
|
547
|
+
},
|
|
548
|
+
{
|
|
549
|
+
chain: EthereumChain,
|
|
550
|
+
identifier: "0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2",
|
|
551
|
+
name: "Wrapped Ether",
|
|
552
|
+
symbol: "WETH",
|
|
553
|
+
decimals: 18,
|
|
554
|
+
logoUrl: "https://assets.coingecko.com/coins/images/2518/small/weth.png"
|
|
555
|
+
},
|
|
556
|
+
{
|
|
557
|
+
chain: EthereumChain,
|
|
558
|
+
identifier: "0x6B175474E89094C44Da98b954EedeAC495271d0F",
|
|
559
|
+
name: "Dai Stablecoin",
|
|
560
|
+
symbol: "DAI",
|
|
561
|
+
decimals: 18,
|
|
562
|
+
logoUrl: "https://assets.coingecko.com/coins/images/9956/small/4943.png"
|
|
563
|
+
}
|
|
564
|
+
];
|
|
565
|
+
|
|
566
|
+
// src/tokens/ethereum-sepolia.ts
|
|
567
|
+
import { WarpChainName as WarpChainName6 } from "@joai/warps";
|
|
568
|
+
var EthereumChain2 = WarpChainName6.Ethereum;
|
|
569
|
+
var EthereumSepoliaTokens = [
|
|
570
|
+
{
|
|
571
|
+
chain: EthereumChain2,
|
|
572
|
+
identifier: "0x0000000000000000000000000000000000000000",
|
|
573
|
+
name: "Ether",
|
|
574
|
+
symbol: "ETH",
|
|
575
|
+
decimals: 18,
|
|
576
|
+
logoUrl: "https://assets.coingecko.com/coins/images/279/small/ethereum.png"
|
|
577
|
+
},
|
|
578
|
+
{
|
|
579
|
+
chain: EthereumChain2,
|
|
580
|
+
identifier: "0x1c7D4B196Cb0C7B01d743Fbc6116a902379C7238",
|
|
581
|
+
name: "USD Coin",
|
|
582
|
+
symbol: "USDC",
|
|
583
|
+
decimals: 6,
|
|
584
|
+
logoUrl: "https://assets.coingecko.com/coins/images/6319/small/USD_Coin_icon.png"
|
|
585
|
+
},
|
|
586
|
+
{
|
|
587
|
+
chain: EthereumChain2,
|
|
588
|
+
identifier: "0x7169D38820dfd117C3FA1f22a697dBA58d90BA06",
|
|
589
|
+
name: "Tether USD",
|
|
590
|
+
symbol: "USDT",
|
|
591
|
+
decimals: 6,
|
|
592
|
+
logoUrl: "https://assets.coingecko.com/coins/images/325/small/Tether.png"
|
|
593
|
+
},
|
|
594
|
+
{
|
|
595
|
+
chain: EthereumChain2,
|
|
596
|
+
identifier: "0xfFf9976782d46CC05630D1f6eBAb18b2324d6B14",
|
|
597
|
+
name: "Wrapped Ether",
|
|
598
|
+
symbol: "WETH",
|
|
599
|
+
decimals: 18,
|
|
600
|
+
logoUrl: "https://assets.coingecko.com/coins/images/2518/small/weth.png"
|
|
601
|
+
},
|
|
602
|
+
{
|
|
603
|
+
chain: EthereumChain2,
|
|
604
|
+
identifier: "0xC6d2Bd6437655FBc6689Bfc987E09846aC4367Ed",
|
|
605
|
+
name: "Wrapped SET",
|
|
606
|
+
symbol: "WSET",
|
|
607
|
+
decimals: 18,
|
|
608
|
+
logoUrl: "https://raw.githubusercontent.com/JoAiHQ/assets/refs/heads/main/tokens/logos/set-black.svg"
|
|
609
|
+
}
|
|
610
|
+
];
|
|
611
|
+
|
|
612
|
+
// src/tokens/polygon.ts
|
|
613
|
+
import { WarpChainName as WarpChainName7 } from "@joai/warps";
|
|
614
|
+
var PolygonChain = WarpChainName7.Polygon;
|
|
615
|
+
var PolygonTokens = [
|
|
616
|
+
{
|
|
617
|
+
chain: PolygonChain,
|
|
618
|
+
identifier: "0x0000000000000000000000000000000000000000",
|
|
619
|
+
name: "Polygon",
|
|
620
|
+
symbol: "MATIC",
|
|
621
|
+
decimals: 18,
|
|
622
|
+
logoUrl: "https://assets.coingecko.com/coins/images/4713/small/matic-token-icon.png"
|
|
623
|
+
},
|
|
624
|
+
{
|
|
625
|
+
chain: PolygonChain,
|
|
626
|
+
identifier: "0x2791Bca1f2de4661ED88A30C99A7a9449Aa84174",
|
|
627
|
+
name: "USD Coin",
|
|
628
|
+
symbol: "USDC",
|
|
629
|
+
decimals: 6,
|
|
630
|
+
logoUrl: "https://assets.coingecko.com/coins/images/6319/small/USD_Coin_icon.png"
|
|
631
|
+
},
|
|
632
|
+
{
|
|
633
|
+
chain: PolygonChain,
|
|
634
|
+
identifier: "0xc2132D05D31c914a87C6611C10748AEb04B58e8F",
|
|
635
|
+
name: "Tether USD",
|
|
636
|
+
symbol: "USDT",
|
|
637
|
+
decimals: 6,
|
|
638
|
+
logoUrl: "https://assets.coingecko.com/coins/images/325/small/Tether.png"
|
|
639
|
+
},
|
|
640
|
+
{
|
|
641
|
+
chain: PolygonChain,
|
|
642
|
+
identifier: "0x1BFD67037B42Cf73acF2047067bd4F2C47D9BfD6",
|
|
643
|
+
name: "Wrapped Bitcoin",
|
|
644
|
+
symbol: "WBTC",
|
|
645
|
+
decimals: 8,
|
|
646
|
+
logoUrl: "https://assets.coingecko.com/coins/images/7598/small/wrapped_bitcoin_wbtc.png"
|
|
647
|
+
},
|
|
648
|
+
{
|
|
649
|
+
chain: PolygonChain,
|
|
650
|
+
identifier: "0x7ceB23fD6bC0adD59E62ac25578270cFf1b9f619",
|
|
651
|
+
name: "Wrapped Ether",
|
|
652
|
+
symbol: "WETH",
|
|
653
|
+
decimals: 18,
|
|
654
|
+
logoUrl: "https://assets.coingecko.com/coins/images/2518/small/weth.png"
|
|
655
|
+
},
|
|
656
|
+
{
|
|
657
|
+
chain: PolygonChain,
|
|
658
|
+
identifier: "0x8f3Cf7ad23Cd3CaDbD9735AFf958023239c6A063",
|
|
659
|
+
name: "Dai Stablecoin",
|
|
660
|
+
symbol: "DAI",
|
|
661
|
+
decimals: 18,
|
|
662
|
+
logoUrl: "https://assets.coingecko.com/coins/images/9956/small/4943.png"
|
|
663
|
+
}
|
|
664
|
+
];
|
|
665
|
+
|
|
666
|
+
// src/tokens/polygon-mumbai.ts
|
|
667
|
+
import { WarpChainName as WarpChainName8 } from "@joai/warps";
|
|
668
|
+
var PolygonChain2 = WarpChainName8.Polygon;
|
|
669
|
+
var PolygonMumbaiTokens = [
|
|
670
|
+
{
|
|
671
|
+
chain: PolygonChain2,
|
|
672
|
+
identifier: "0x0000000000000000000000000000000000000000",
|
|
673
|
+
name: "Polygon",
|
|
674
|
+
symbol: "MATIC",
|
|
675
|
+
decimals: 18,
|
|
676
|
+
logoUrl: "https://assets.coingecko.com/coins/images/4713/small/matic-token-icon.png"
|
|
677
|
+
},
|
|
678
|
+
{
|
|
679
|
+
chain: PolygonChain2,
|
|
680
|
+
identifier: "0x0FA8781a83E46826621b3BC094Ea2Aea2Cdd993B",
|
|
681
|
+
name: "USD Coin",
|
|
682
|
+
symbol: "USDC",
|
|
683
|
+
decimals: 6,
|
|
684
|
+
logoUrl: "https://assets.coingecko.com/coins/images/6319/small/USD_Coin_icon.png"
|
|
685
|
+
}
|
|
686
|
+
];
|
|
687
|
+
|
|
688
|
+
// src/tokens.ts
|
|
689
|
+
var KnownTokens = {
|
|
690
|
+
[WarpChainName9.Ethereum]: {
|
|
691
|
+
mainnet: EthereumTokens,
|
|
692
|
+
testnet: EthereumSepoliaTokens,
|
|
693
|
+
devnet: EthereumSepoliaTokens
|
|
694
|
+
},
|
|
695
|
+
[WarpChainName9.Base]: {
|
|
696
|
+
mainnet: BaseTokens,
|
|
697
|
+
testnet: BaseSepoliaTokens,
|
|
698
|
+
devnet: BaseSepoliaTokens
|
|
699
|
+
},
|
|
700
|
+
[WarpChainName9.Arbitrum]: {
|
|
701
|
+
mainnet: ArbitrumTokens,
|
|
702
|
+
testnet: ArbitrumSepoliaTokens,
|
|
703
|
+
devnet: ArbitrumSepoliaTokens
|
|
704
|
+
},
|
|
705
|
+
[WarpChainName9.Polygon]: {
|
|
706
|
+
mainnet: PolygonTokens,
|
|
707
|
+
testnet: PolygonMumbaiTokens,
|
|
708
|
+
devnet: PolygonMumbaiTokens
|
|
709
|
+
}
|
|
710
|
+
};
|
|
711
|
+
var findKnownTokenById = (chain, env, id) => {
|
|
712
|
+
const chainTokens = KnownTokens[chain]?.[env] || [];
|
|
713
|
+
return chainTokens.find((token) => token.identifier === id) || null;
|
|
714
|
+
};
|
|
715
|
+
var getKnownTokensForChain = (chainName, env = "mainnet") => {
|
|
716
|
+
return KnownTokens[chainName]?.[env] || [];
|
|
717
|
+
};
|
|
718
|
+
|
|
719
|
+
// src/WarpEvmDataLoader.ts
|
|
720
|
+
var ERC20_ABI = [
|
|
721
|
+
"function balanceOf(address owner) view returns (uint256)",
|
|
722
|
+
"function decimals() view returns (uint8)",
|
|
723
|
+
"function name() view returns (string)",
|
|
724
|
+
"function symbol() view returns (string)",
|
|
725
|
+
"function totalSupply() view returns (uint256)"
|
|
726
|
+
];
|
|
727
|
+
var WarpEvmDataLoader = class {
|
|
728
|
+
constructor(config, chain) {
|
|
729
|
+
this.config = config;
|
|
730
|
+
this.chain = chain;
|
|
731
|
+
const providerConfig = getProviderConfig(this.config, this.chain.name, this.config.env, this.chain.defaultApiUrl);
|
|
732
|
+
const network = new ethers3.Network(this.chain.name, parseInt(this.chain.chainId));
|
|
733
|
+
this.provider = new ethers3.JsonRpcProvider(providerConfig.url, network);
|
|
734
|
+
this.cache = new WarpCache2(config.env, config.cache);
|
|
735
|
+
this.uniswapService = new UniswapService(this.cache, parseInt(this.chain.chainId));
|
|
736
|
+
}
|
|
737
|
+
getRequiredConfirmations() {
|
|
738
|
+
if (this.config.env === "mainnet") {
|
|
739
|
+
return 12;
|
|
740
|
+
}
|
|
741
|
+
return 1;
|
|
742
|
+
}
|
|
743
|
+
async getAccount(address) {
|
|
744
|
+
const balance = await this.provider.getBalance(address);
|
|
745
|
+
return {
|
|
746
|
+
chain: this.chain.name,
|
|
747
|
+
address,
|
|
748
|
+
balance
|
|
749
|
+
};
|
|
750
|
+
}
|
|
751
|
+
async getAccountAssets(address) {
|
|
752
|
+
const account = await this.getAccount(address);
|
|
753
|
+
const tokenBalances = await this.getERC20TokenBalances(address);
|
|
754
|
+
let assets = account.balance > 0 ? [{ ...this.chain.nativeToken, amount: account.balance }] : [];
|
|
755
|
+
for (const tokenBalance of tokenBalances) {
|
|
756
|
+
if (tokenBalance.balance > 0n) {
|
|
757
|
+
assets.push({
|
|
758
|
+
chain: this.chain.name,
|
|
759
|
+
identifier: tokenBalance.tokenAddress,
|
|
760
|
+
name: tokenBalance.name,
|
|
761
|
+
symbol: tokenBalance.symbol,
|
|
762
|
+
amount: tokenBalance.balance,
|
|
763
|
+
decimals: tokenBalance.decimals,
|
|
764
|
+
logoUrl: tokenBalance.logoUrl || ""
|
|
765
|
+
});
|
|
766
|
+
}
|
|
767
|
+
}
|
|
768
|
+
return assets;
|
|
769
|
+
}
|
|
770
|
+
async getAsset(identifier) {
|
|
771
|
+
try {
|
|
772
|
+
console.log("WarpEvmDataLoader.getAsset", identifier);
|
|
773
|
+
if (identifier === this.chain.nativeToken.identifier) {
|
|
774
|
+
return this.chain.nativeToken;
|
|
775
|
+
}
|
|
776
|
+
const cacheKey = WarpCacheKey.Asset(this.config.env, this.chain.name, identifier);
|
|
777
|
+
const cachedAsset = this.cache.get(cacheKey);
|
|
778
|
+
if (cachedAsset) {
|
|
779
|
+
return cachedAsset;
|
|
780
|
+
}
|
|
781
|
+
console.log("WarpEvmDataLoader.getAsset: findKnownTokenById", this.chain.name, this.config.env, identifier);
|
|
782
|
+
const knownToken = findKnownTokenById(this.chain.name, this.config.env, identifier);
|
|
783
|
+
if (knownToken) {
|
|
784
|
+
return {
|
|
785
|
+
chain: this.chain.name,
|
|
786
|
+
identifier,
|
|
787
|
+
name: knownToken.name,
|
|
788
|
+
symbol: knownToken.symbol,
|
|
789
|
+
amount: 0n,
|
|
790
|
+
decimals: knownToken.decimals,
|
|
791
|
+
logoUrl: knownToken.logoUrl
|
|
792
|
+
};
|
|
793
|
+
}
|
|
794
|
+
const metadata = await this.getTokenMetadata(identifier);
|
|
795
|
+
const asset = {
|
|
796
|
+
chain: this.chain.name,
|
|
797
|
+
identifier,
|
|
798
|
+
name: metadata.name,
|
|
799
|
+
symbol: metadata.symbol,
|
|
800
|
+
amount: 0n,
|
|
801
|
+
decimals: metadata.decimals,
|
|
802
|
+
logoUrl: metadata.logoUrl
|
|
803
|
+
};
|
|
804
|
+
this.cache.set(cacheKey, asset, CacheTtl2.OneHour);
|
|
805
|
+
return asset;
|
|
806
|
+
} catch (error) {
|
|
807
|
+
return null;
|
|
808
|
+
}
|
|
809
|
+
}
|
|
810
|
+
async getAction(identifier, awaitCompleted = false) {
|
|
811
|
+
try {
|
|
812
|
+
const tx = await this.provider.getTransaction(identifier);
|
|
813
|
+
if (!tx) return null;
|
|
814
|
+
let receipt = await this.provider.getTransactionReceipt(identifier);
|
|
815
|
+
if (awaitCompleted) {
|
|
816
|
+
if (!receipt) {
|
|
817
|
+
receipt = await tx.wait();
|
|
818
|
+
} else {
|
|
819
|
+
const confirmations = this.getRequiredConfirmations();
|
|
820
|
+
const currentBlock = await this.provider.getBlockNumber();
|
|
821
|
+
const receiptBlock = receipt.blockNumber;
|
|
822
|
+
const confirmationsCount = currentBlock - receiptBlock;
|
|
823
|
+
if (confirmationsCount < confirmations) {
|
|
824
|
+
await tx.wait(confirmations);
|
|
825
|
+
receipt = await this.provider.getTransactionReceipt(identifier);
|
|
826
|
+
}
|
|
827
|
+
}
|
|
828
|
+
}
|
|
829
|
+
const block = await this.provider.getBlock(receipt?.blockNumber || tx.blockNumber || "latest");
|
|
830
|
+
const status = receipt ? receipt.status === 1 ? "success" : receipt.status === 0 ? "failed" : "pending" : "pending";
|
|
831
|
+
const error = receipt?.status === 0 ? "Transaction failed" : null;
|
|
832
|
+
return {
|
|
833
|
+
chain: this.chain.name,
|
|
834
|
+
id: tx.hash || identifier,
|
|
835
|
+
receiver: tx.to || "",
|
|
836
|
+
sender: tx.from,
|
|
837
|
+
value: tx.value,
|
|
838
|
+
function: tx.data && tx.data !== "0x" ? "contract_call" : "",
|
|
839
|
+
status,
|
|
840
|
+
createdAt: block?.timestamp ? new Date(Number(block.timestamp) * 1e3).toISOString() : (/* @__PURE__ */ new Date()).toISOString(),
|
|
841
|
+
error,
|
|
842
|
+
tx: {
|
|
843
|
+
hash: tx.hash || "",
|
|
844
|
+
from: tx.from,
|
|
845
|
+
to: tx.to || "",
|
|
846
|
+
value: tx.value.toString(),
|
|
847
|
+
data: tx.data || "0x",
|
|
848
|
+
gasLimit: tx.gasLimit?.toString() || "0",
|
|
849
|
+
gasPrice: tx.gasPrice?.toString() || "0",
|
|
850
|
+
blockNumber: tx.blockNumber || 0,
|
|
851
|
+
blockHash: tx.blockHash || "",
|
|
852
|
+
transactionIndex: tx.index || 0,
|
|
853
|
+
status: receipt?.status
|
|
854
|
+
}
|
|
855
|
+
};
|
|
856
|
+
} catch (error) {
|
|
857
|
+
return null;
|
|
858
|
+
}
|
|
859
|
+
}
|
|
860
|
+
async getAccountActions(address, options) {
|
|
861
|
+
return [];
|
|
862
|
+
}
|
|
863
|
+
async getERC20TokenBalances(address) {
|
|
864
|
+
const env = this.config.env === "mainnet" ? "mainnet" : "testnet";
|
|
865
|
+
const tokens = getKnownTokensForChain(this.chain.name, env);
|
|
866
|
+
const balanceReqs = tokens.map((token) => this.getTokenBalance(address, token.identifier).catch(() => 0n));
|
|
867
|
+
const balances = await Promise.all(balanceReqs);
|
|
868
|
+
return balances.map((balance, index) => ({ balance, token: tokens[index] })).filter(({ balance }) => balance > 0n).map(({ balance, token }) => ({
|
|
869
|
+
tokenAddress: token.identifier,
|
|
870
|
+
balance,
|
|
871
|
+
name: token.name,
|
|
872
|
+
symbol: token.symbol,
|
|
873
|
+
decimals: token.decimals || 18,
|
|
874
|
+
logoUrl: getWarpChainAssetLogoUrl(token, this.config) || ""
|
|
875
|
+
}));
|
|
876
|
+
}
|
|
877
|
+
async getTokenBalance(address, tokenAddress) {
|
|
878
|
+
const contract = new ethers3.Contract(tokenAddress, ERC20_ABI, this.provider);
|
|
879
|
+
const balance = await contract.balanceOf(address);
|
|
880
|
+
return balance;
|
|
881
|
+
}
|
|
882
|
+
async getTokenMetadata(tokenAddress) {
|
|
883
|
+
const uniswapMetadata = await this.uniswapService.getTokenMetadata(tokenAddress);
|
|
884
|
+
if (uniswapMetadata) {
|
|
885
|
+
return uniswapMetadata;
|
|
886
|
+
}
|
|
887
|
+
const contract = new ethers3.Contract(tokenAddress, ERC20_ABI, this.provider);
|
|
888
|
+
const [name, symbol, decimals] = await Promise.all([
|
|
889
|
+
contract.name().catch(() => "Unknown Token"),
|
|
890
|
+
contract.symbol().catch(() => "UNKNOWN"),
|
|
891
|
+
contract.decimals().catch(() => 18)
|
|
892
|
+
]);
|
|
893
|
+
return {
|
|
894
|
+
name: name || "Unknown Token",
|
|
895
|
+
symbol: symbol || "UNKNOWN",
|
|
896
|
+
decimals: decimals || 18,
|
|
897
|
+
logoUrl: ""
|
|
898
|
+
};
|
|
899
|
+
}
|
|
900
|
+
};
|
|
901
|
+
|
|
902
|
+
// src/WarpEvmExecutor.ts
|
|
903
|
+
import {
|
|
904
|
+
applyOutputToMessages,
|
|
905
|
+
extractResolvedInputValues as extractResolvedInputValues2,
|
|
906
|
+
getNextInfo,
|
|
907
|
+
getProviderConfig as getProviderConfig3,
|
|
908
|
+
getWarpActionByIndex,
|
|
909
|
+
getWarpWalletAddressFromConfig as getWarpWalletAddressFromConfig3
|
|
910
|
+
} from "@joai/warps";
|
|
911
|
+
import { ethers as ethers6 } from "ethers";
|
|
912
|
+
|
|
913
|
+
// src/constants.ts
|
|
914
|
+
var WarpEvmConstants = {
|
|
915
|
+
GasLimit: {
|
|
916
|
+
Default: 21e3,
|
|
917
|
+
ContractCall: 1e5,
|
|
918
|
+
ContractDeploy: 5e5,
|
|
919
|
+
Transfer: 21e3,
|
|
920
|
+
TokenTransfer: 65e3,
|
|
921
|
+
// ERC-20 transfer gas limit
|
|
922
|
+
Approve: 46e3,
|
|
923
|
+
Swap: 2e5
|
|
924
|
+
},
|
|
925
|
+
GasPrice: {
|
|
926
|
+
Default: "1200010"
|
|
927
|
+
},
|
|
928
|
+
Validation: {
|
|
929
|
+
MinGasLimit: 21e3,
|
|
930
|
+
MaxGasLimit: 3e7
|
|
931
|
+
}
|
|
932
|
+
};
|
|
933
|
+
var EthereumExplorers = /* @__PURE__ */ ((EthereumExplorers2) => {
|
|
934
|
+
EthereumExplorers2["Etherscan"] = "etherscan";
|
|
935
|
+
EthereumExplorers2["EtherscanSepolia"] = "etherscan_sepolia";
|
|
936
|
+
EthereumExplorers2["Ethplorer"] = "ethplorer";
|
|
937
|
+
EthereumExplorers2["Blockscout"] = "blockscout";
|
|
938
|
+
EthereumExplorers2["BlockscoutSepolia"] = "blockscout_sepolia";
|
|
939
|
+
return EthereumExplorers2;
|
|
940
|
+
})(EthereumExplorers || {});
|
|
941
|
+
var ArbitrumExplorers = /* @__PURE__ */ ((ArbitrumExplorers2) => {
|
|
942
|
+
ArbitrumExplorers2["Arbiscan"] = "arbiscan";
|
|
943
|
+
ArbitrumExplorers2["ArbiscanSepolia"] = "arbiscan_sepolia";
|
|
944
|
+
ArbitrumExplorers2["BlockscoutArbitrum"] = "blockscout_arbitrum";
|
|
945
|
+
ArbitrumExplorers2["BlockscoutArbitrumSepolia"] = "blockscout_arbitrum_sepolia";
|
|
946
|
+
return ArbitrumExplorers2;
|
|
947
|
+
})(ArbitrumExplorers || {});
|
|
948
|
+
var BaseExplorers = /* @__PURE__ */ ((BaseExplorers2) => {
|
|
949
|
+
BaseExplorers2["Basescan"] = "basescan";
|
|
950
|
+
BaseExplorers2["BasescanSepolia"] = "basescan_sepolia";
|
|
951
|
+
BaseExplorers2["BlockscoutBase"] = "blockscout_base";
|
|
952
|
+
BaseExplorers2["BlockscoutBaseSepolia"] = "blockscout_base_sepolia";
|
|
953
|
+
return BaseExplorers2;
|
|
954
|
+
})(BaseExplorers || {});
|
|
955
|
+
var PolygonExplorers = /* @__PURE__ */ ((PolygonExplorers2) => {
|
|
956
|
+
PolygonExplorers2["Polygonscan"] = "polygonscan";
|
|
957
|
+
PolygonExplorers2["PolygonscanMumbai"] = "polygonscan_mumbai";
|
|
958
|
+
PolygonExplorers2["BlockscoutPolygon"] = "blockscout_polygon";
|
|
959
|
+
PolygonExplorers2["BlockscoutPolygonMumbai"] = "blockscout_polygon_mumbai";
|
|
960
|
+
return PolygonExplorers2;
|
|
961
|
+
})(PolygonExplorers || {});
|
|
962
|
+
var EvmExplorers = {
|
|
963
|
+
ethereum: {
|
|
964
|
+
mainnet: ["etherscan" /* Etherscan */, "ethplorer" /* Ethplorer */, "blockscout" /* Blockscout */],
|
|
965
|
+
testnet: ["etherscan_sepolia" /* EtherscanSepolia */, "blockscout_sepolia" /* BlockscoutSepolia */],
|
|
966
|
+
devnet: ["etherscan_sepolia" /* EtherscanSepolia */, "blockscout_sepolia" /* BlockscoutSepolia */]
|
|
967
|
+
},
|
|
968
|
+
arbitrum: {
|
|
969
|
+
mainnet: ["arbiscan" /* Arbiscan */, "blockscout_arbitrum" /* BlockscoutArbitrum */],
|
|
970
|
+
testnet: ["arbiscan_sepolia" /* ArbiscanSepolia */, "blockscout_arbitrum_sepolia" /* BlockscoutArbitrumSepolia */],
|
|
971
|
+
devnet: ["arbiscan_sepolia" /* ArbiscanSepolia */, "blockscout_arbitrum_sepolia" /* BlockscoutArbitrumSepolia */]
|
|
972
|
+
},
|
|
973
|
+
base: {
|
|
974
|
+
mainnet: ["basescan" /* Basescan */, "blockscout_base" /* BlockscoutBase */],
|
|
975
|
+
testnet: ["basescan_sepolia" /* BasescanSepolia */, "blockscout_base_sepolia" /* BlockscoutBaseSepolia */],
|
|
976
|
+
devnet: ["basescan_sepolia" /* BasescanSepolia */, "blockscout_base_sepolia" /* BlockscoutBaseSepolia */]
|
|
977
|
+
},
|
|
978
|
+
polygon: {
|
|
979
|
+
mainnet: ["polygonscan" /* Polygonscan */, "blockscout_polygon" /* BlockscoutPolygon */],
|
|
980
|
+
testnet: ["polygonscan_mumbai" /* PolygonscanMumbai */, "blockscout_polygon_mumbai" /* BlockscoutPolygonMumbai */],
|
|
981
|
+
devnet: ["polygonscan_mumbai" /* PolygonscanMumbai */, "blockscout_polygon_mumbai" /* BlockscoutPolygonMumbai */]
|
|
982
|
+
}
|
|
983
|
+
};
|
|
984
|
+
var ExplorerUrls = {
|
|
985
|
+
["etherscan" /* Etherscan */]: "https://etherscan.io",
|
|
986
|
+
["etherscan_sepolia" /* EtherscanSepolia */]: "https://sepolia.etherscan.io",
|
|
987
|
+
["ethplorer" /* Ethplorer */]: "https://ethplorer.io",
|
|
988
|
+
["blockscout" /* Blockscout */]: "https://eth.blockscout.com",
|
|
989
|
+
["blockscout_sepolia" /* BlockscoutSepolia */]: "https://sepolia.blockscout.com",
|
|
990
|
+
["arbiscan" /* Arbiscan */]: "https://arbiscan.io",
|
|
991
|
+
["arbiscan_sepolia" /* ArbiscanSepolia */]: "https://sepolia.arbiscan.io",
|
|
992
|
+
["blockscout_arbitrum" /* BlockscoutArbitrum */]: "https://arbitrum.blockscout.com",
|
|
993
|
+
["blockscout_arbitrum_sepolia" /* BlockscoutArbitrumSepolia */]: "https://sepolia.blockscout.com",
|
|
994
|
+
["basescan" /* Basescan */]: "https://basescan.org",
|
|
995
|
+
["basescan_sepolia" /* BasescanSepolia */]: "https://sepolia.basescan.org",
|
|
996
|
+
["blockscout_base" /* BlockscoutBase */]: "https://base.blockscout.com",
|
|
997
|
+
["blockscout_base_sepolia" /* BlockscoutBaseSepolia */]: "https://sepolia.blockscout.com",
|
|
998
|
+
["polygonscan" /* Polygonscan */]: "https://polygonscan.com",
|
|
999
|
+
["polygonscan_mumbai" /* PolygonscanMumbai */]: "https://mumbai.polygonscan.com",
|
|
1000
|
+
["blockscout_polygon" /* BlockscoutPolygon */]: "https://polygon.blockscout.com",
|
|
1001
|
+
["blockscout_polygon_mumbai" /* BlockscoutPolygonMumbai */]: "https://mumbai.blockscout.com"
|
|
1002
|
+
};
|
|
1003
|
+
var EvmChainIds = {
|
|
1004
|
+
Ethereum: {
|
|
1005
|
+
Mainnet: 1,
|
|
1006
|
+
Goerli: 5,
|
|
1007
|
+
Sepolia: 11155111
|
|
1008
|
+
},
|
|
1009
|
+
Polygon: {
|
|
1010
|
+
Mainnet: 137,
|
|
1011
|
+
Mumbai: 80001
|
|
1012
|
+
},
|
|
1013
|
+
Arbitrum: {
|
|
1014
|
+
Mainnet: 42161,
|
|
1015
|
+
Sepolia: 421614
|
|
1016
|
+
},
|
|
1017
|
+
Base: {
|
|
1018
|
+
Mainnet: 8453,
|
|
1019
|
+
Sepolia: 84532
|
|
1020
|
+
},
|
|
1021
|
+
Optimism: {
|
|
1022
|
+
Mainnet: 10,
|
|
1023
|
+
Sepolia: 11155420
|
|
1024
|
+
}
|
|
1025
|
+
};
|
|
1026
|
+
var EvmChainIdMap = {
|
|
1027
|
+
"ethereum:mainnet": EvmChainIds.Ethereum.Mainnet,
|
|
1028
|
+
"ethereum:goerli": EvmChainIds.Ethereum.Goerli,
|
|
1029
|
+
"ethereum:sepolia": EvmChainIds.Ethereum.Sepolia,
|
|
1030
|
+
"polygon:mainnet": EvmChainIds.Polygon.Mainnet,
|
|
1031
|
+
"polygon:mumbai": EvmChainIds.Polygon.Mumbai,
|
|
1032
|
+
"arbitrum:mainnet": EvmChainIds.Arbitrum.Mainnet,
|
|
1033
|
+
"arbitrum:sepolia": EvmChainIds.Arbitrum.Sepolia,
|
|
1034
|
+
"base:mainnet": EvmChainIds.Base.Mainnet,
|
|
1035
|
+
"base:sepolia": EvmChainIds.Base.Sepolia,
|
|
1036
|
+
"optimism:mainnet": EvmChainIds.Optimism.Mainnet,
|
|
1037
|
+
"optimism:sepolia": EvmChainIds.Optimism.Sepolia
|
|
1038
|
+
};
|
|
1039
|
+
var SupportedEvmChainIds = [
|
|
1040
|
+
EvmChainIds.Ethereum.Mainnet,
|
|
1041
|
+
EvmChainIds.Ethereum.Goerli,
|
|
1042
|
+
EvmChainIds.Ethereum.Sepolia,
|
|
1043
|
+
EvmChainIds.Polygon.Mainnet,
|
|
1044
|
+
EvmChainIds.Polygon.Mumbai,
|
|
1045
|
+
EvmChainIds.Arbitrum.Mainnet,
|
|
1046
|
+
EvmChainIds.Arbitrum.Sepolia,
|
|
1047
|
+
EvmChainIds.Base.Mainnet,
|
|
1048
|
+
EvmChainIds.Base.Sepolia,
|
|
1049
|
+
EvmChainIds.Optimism.Mainnet,
|
|
1050
|
+
EvmChainIds.Optimism.Sepolia
|
|
1051
|
+
];
|
|
1052
|
+
|
|
1053
|
+
// src/WarpEvmOutput.ts
|
|
1054
|
+
import {
|
|
1055
|
+
evaluateOutputCommon,
|
|
1056
|
+
extractResolvedInputValues,
|
|
1057
|
+
getProviderConfig as getProviderConfig2,
|
|
1058
|
+
getWarpWalletAddressFromConfig as getWarpWalletAddressFromConfig2,
|
|
1059
|
+
parseOutputOutIndex,
|
|
1060
|
+
WarpConstants as WarpConstants2,
|
|
1061
|
+
WarpCache as WarpCache3,
|
|
1062
|
+
WarpCacheKey as WarpCacheKey2
|
|
1063
|
+
} from "@joai/warps";
|
|
1064
|
+
import { ethers as ethers5 } from "ethers";
|
|
1065
|
+
|
|
1066
|
+
// src/WarpEvmSerializer.ts
|
|
1067
|
+
import {
|
|
1068
|
+
WarpConstants,
|
|
1069
|
+
WarpSerializer
|
|
1070
|
+
} from "@joai/warps";
|
|
1071
|
+
import { ethers as ethers4 } from "ethers";
|
|
1072
|
+
var SplitParamsRegex = new RegExp(`${WarpConstants.ArgParamsSeparator}(.*)`);
|
|
1073
|
+
var WarpEvmSerializer = class {
|
|
1074
|
+
constructor() {
|
|
1075
|
+
this.coreSerializer = new WarpSerializer();
|
|
1076
|
+
}
|
|
1077
|
+
typedToString(value) {
|
|
1078
|
+
if (typeof value === "string") {
|
|
1079
|
+
if (ethers4.isAddress(value)) {
|
|
1080
|
+
return `address:${value}`;
|
|
1081
|
+
}
|
|
1082
|
+
if (ethers4.isHexString(value) && !ethers4.isAddress(value)) {
|
|
1083
|
+
return `hex:${value}`;
|
|
1084
|
+
}
|
|
1085
|
+
return `string:${value}`;
|
|
1086
|
+
}
|
|
1087
|
+
if (typeof value === "number") {
|
|
1088
|
+
if (Number.isInteger(value)) {
|
|
1089
|
+
if (value >= 0 && value <= 255) return `uint8:${value}`;
|
|
1090
|
+
if (value >= 0 && value <= 65535) return `uint16:${value}`;
|
|
1091
|
+
if (value >= 0 && value <= 4294967295) return `uint32:${value}`;
|
|
1092
|
+
return `uint64:${value}`;
|
|
1093
|
+
}
|
|
1094
|
+
return `string:${value}`;
|
|
1095
|
+
}
|
|
1096
|
+
if (typeof value === "bigint") {
|
|
1097
|
+
return `biguint:${value.toString()}`;
|
|
1098
|
+
}
|
|
1099
|
+
if (typeof value === "boolean") {
|
|
1100
|
+
return `boolean:${value}`;
|
|
1101
|
+
}
|
|
1102
|
+
if (Array.isArray(value)) {
|
|
1103
|
+
if (value.length === 0) return `list:string:`;
|
|
1104
|
+
const types = value.map((item) => this.typedToString(item).split(WarpConstants.ArgParamsSeparator)[0]);
|
|
1105
|
+
const type = types[0];
|
|
1106
|
+
const values = value.map((item) => this.typedToString(item).split(WarpConstants.ArgParamsSeparator)[1]);
|
|
1107
|
+
return `list:${type}:${values.join(",")}`;
|
|
1108
|
+
}
|
|
1109
|
+
if (value === null || value === void 0) {
|
|
1110
|
+
return `string:null`;
|
|
1111
|
+
}
|
|
1112
|
+
return `string:${String(value)}`;
|
|
1113
|
+
}
|
|
1114
|
+
typedToNative(value) {
|
|
1115
|
+
const stringValue = this.typedToString(value);
|
|
1116
|
+
const [type, ...valueParts] = stringValue.split(WarpConstants.ArgParamsSeparator);
|
|
1117
|
+
const nativeValue = valueParts.join(WarpConstants.ArgParamsSeparator);
|
|
1118
|
+
return [type, this.parseNativeValue(type, nativeValue)];
|
|
1119
|
+
}
|
|
1120
|
+
nativeToTyped(type, value) {
|
|
1121
|
+
switch (type) {
|
|
1122
|
+
case "string":
|
|
1123
|
+
return String(value);
|
|
1124
|
+
case "uint8":
|
|
1125
|
+
case "uint16":
|
|
1126
|
+
case "uint32":
|
|
1127
|
+
case "uint64":
|
|
1128
|
+
return BigInt(value);
|
|
1129
|
+
case "biguint":
|
|
1130
|
+
return BigInt(value);
|
|
1131
|
+
case "boolean":
|
|
1132
|
+
return Boolean(value);
|
|
1133
|
+
case "address":
|
|
1134
|
+
return String(value);
|
|
1135
|
+
case "hex":
|
|
1136
|
+
const hexValue = String(value);
|
|
1137
|
+
return hexValue.startsWith("0x") ? hexValue : `0x${hexValue}`;
|
|
1138
|
+
default:
|
|
1139
|
+
if (type.startsWith("list:")) {
|
|
1140
|
+
const [, itemType, itemsStr] = type.split(":");
|
|
1141
|
+
if (!itemsStr) return [];
|
|
1142
|
+
const items = itemsStr.split(",");
|
|
1143
|
+
return items.map((item) => this.nativeToTyped(itemType, item));
|
|
1144
|
+
}
|
|
1145
|
+
return String(value);
|
|
1146
|
+
}
|
|
1147
|
+
}
|
|
1148
|
+
nativeToType(type) {
|
|
1149
|
+
switch (type) {
|
|
1150
|
+
case "string":
|
|
1151
|
+
return "string";
|
|
1152
|
+
case "uint8":
|
|
1153
|
+
case "uint16":
|
|
1154
|
+
case "uint32":
|
|
1155
|
+
case "uint64":
|
|
1156
|
+
case "biguint":
|
|
1157
|
+
return "bigint";
|
|
1158
|
+
case "boolean":
|
|
1159
|
+
return "boolean";
|
|
1160
|
+
case "address":
|
|
1161
|
+
return "string";
|
|
1162
|
+
case "hex":
|
|
1163
|
+
return "string";
|
|
1164
|
+
default:
|
|
1165
|
+
return "string";
|
|
1166
|
+
}
|
|
1167
|
+
}
|
|
1168
|
+
stringToTyped(value) {
|
|
1169
|
+
const parts = value.split(WarpConstants.ArgParamsSeparator, 2);
|
|
1170
|
+
if (parts.length < 2) {
|
|
1171
|
+
return value;
|
|
1172
|
+
}
|
|
1173
|
+
const [type, stringValue] = parts;
|
|
1174
|
+
switch (type) {
|
|
1175
|
+
case "string":
|
|
1176
|
+
return stringValue;
|
|
1177
|
+
case "uint8":
|
|
1178
|
+
case "uint16":
|
|
1179
|
+
case "uint32":
|
|
1180
|
+
case "uint64":
|
|
1181
|
+
return BigInt(stringValue);
|
|
1182
|
+
case "biguint":
|
|
1183
|
+
return BigInt(stringValue);
|
|
1184
|
+
case "boolean":
|
|
1185
|
+
return stringValue === "true";
|
|
1186
|
+
case "address":
|
|
1187
|
+
return stringValue;
|
|
1188
|
+
case "hex":
|
|
1189
|
+
return stringValue.startsWith("0x") ? stringValue : `0x${stringValue}`;
|
|
1190
|
+
default:
|
|
1191
|
+
if (type.startsWith("list:")) {
|
|
1192
|
+
const [, itemType, itemsStr] = type.split(":");
|
|
1193
|
+
if (!itemsStr) return [];
|
|
1194
|
+
const items = itemsStr.split(",");
|
|
1195
|
+
return items.map((item) => this.stringToTyped(`${itemType}:${item}`));
|
|
1196
|
+
}
|
|
1197
|
+
return stringValue;
|
|
1198
|
+
}
|
|
1199
|
+
}
|
|
1200
|
+
parseNativeValue(type, value) {
|
|
1201
|
+
switch (type) {
|
|
1202
|
+
case "string":
|
|
1203
|
+
return value;
|
|
1204
|
+
case "uint8":
|
|
1205
|
+
case "uint16":
|
|
1206
|
+
case "uint32":
|
|
1207
|
+
case "uint64":
|
|
1208
|
+
case "biguint":
|
|
1209
|
+
return BigInt(value);
|
|
1210
|
+
case "boolean":
|
|
1211
|
+
return value === "true";
|
|
1212
|
+
case "address":
|
|
1213
|
+
return value;
|
|
1214
|
+
case "hex":
|
|
1215
|
+
return value;
|
|
1216
|
+
default:
|
|
1217
|
+
return value;
|
|
1218
|
+
}
|
|
1219
|
+
}
|
|
1220
|
+
};
|
|
1221
|
+
|
|
1222
|
+
// src/WarpEvmOutput.ts
|
|
1223
|
+
var WarpEvmOutput = class {
|
|
1224
|
+
constructor(config, chain) {
|
|
1225
|
+
this.config = config;
|
|
1226
|
+
this.chain = chain;
|
|
1227
|
+
this.serializer = new WarpEvmSerializer();
|
|
1228
|
+
const providerConfig = getProviderConfig2(this.config, this.chain.name, this.config.env, this.chain.defaultApiUrl);
|
|
1229
|
+
const network = new ethers5.Network(this.chain.name, parseInt(this.chain.chainId));
|
|
1230
|
+
this.provider = new ethers5.JsonRpcProvider(providerConfig.url, network);
|
|
1231
|
+
this.cache = new WarpCache3(config.env, config.cache);
|
|
1232
|
+
}
|
|
1233
|
+
async getActionExecution(warp, actionIndex, tx) {
|
|
1234
|
+
const inputs = this.cache.get(WarpCacheKey2.WarpExecutable(this.config.env, warp.meta?.hash || "", actionIndex)) ?? [];
|
|
1235
|
+
const resolvedInputs = extractResolvedInputValues(inputs);
|
|
1236
|
+
if (!tx) {
|
|
1237
|
+
return this.createFailedExecution(warp, actionIndex, resolvedInputs);
|
|
1238
|
+
}
|
|
1239
|
+
if ("status" in tx && typeof tx.status === "string") {
|
|
1240
|
+
return this.handleWarpChainAction(warp, actionIndex, tx, resolvedInputs);
|
|
1241
|
+
}
|
|
1242
|
+
return this.handleTransactionReceipt(warp, actionIndex, tx, resolvedInputs);
|
|
1243
|
+
}
|
|
1244
|
+
createFailedExecution(warp, actionIndex, resolvedInputs = []) {
|
|
1245
|
+
return {
|
|
1246
|
+
status: "error",
|
|
1247
|
+
warp,
|
|
1248
|
+
action: actionIndex,
|
|
1249
|
+
user: getWarpWalletAddressFromConfig2(this.config, this.chain.name),
|
|
1250
|
+
txHash: "",
|
|
1251
|
+
tx: null,
|
|
1252
|
+
next: null,
|
|
1253
|
+
values: { string: [], native: [], mapped: {} },
|
|
1254
|
+
output: {},
|
|
1255
|
+
messages: {},
|
|
1256
|
+
destination: null,
|
|
1257
|
+
resolvedInputs
|
|
1258
|
+
};
|
|
1259
|
+
}
|
|
1260
|
+
handleWarpChainAction(warp, actionIndex, tx, resolvedInputs = []) {
|
|
1261
|
+
const success = tx.status === "success";
|
|
1262
|
+
const transactionHash = tx.id || tx.tx?.hash || "";
|
|
1263
|
+
const gasUsed = tx.tx?.gasLimit || "0";
|
|
1264
|
+
const gasPrice = tx.tx?.gasPrice || "0";
|
|
1265
|
+
const blockNumber = tx.tx?.blockNumber || "0";
|
|
1266
|
+
const rawValues = [transactionHash, blockNumber, gasUsed, gasPrice];
|
|
1267
|
+
const stringValues = rawValues.map(String);
|
|
1268
|
+
return {
|
|
1269
|
+
status: success ? "success" : "error",
|
|
1270
|
+
warp,
|
|
1271
|
+
action: actionIndex,
|
|
1272
|
+
user: getWarpWalletAddressFromConfig2(this.config, this.chain.name),
|
|
1273
|
+
txHash: transactionHash,
|
|
1274
|
+
tx,
|
|
1275
|
+
next: null,
|
|
1276
|
+
values: { string: stringValues, native: rawValues, mapped: {} },
|
|
1277
|
+
output: {},
|
|
1278
|
+
messages: {},
|
|
1279
|
+
destination: null,
|
|
1280
|
+
resolvedInputs
|
|
1281
|
+
};
|
|
1282
|
+
}
|
|
1283
|
+
handleTransactionReceipt(warp, actionIndex, tx, resolvedInputs = []) {
|
|
1284
|
+
const success = tx.status === 1;
|
|
1285
|
+
const gasUsed = tx.gasUsed?.toString() || "0";
|
|
1286
|
+
const gasPrice = tx.gasPrice?.toString() || "0";
|
|
1287
|
+
const blockNumber = tx.blockNumber?.toString() || "0";
|
|
1288
|
+
const transactionHash = tx.hash;
|
|
1289
|
+
const logs = tx.logs.map((log) => ({
|
|
1290
|
+
address: log.address,
|
|
1291
|
+
topics: [...log.topics],
|
|
1292
|
+
data: log.data,
|
|
1293
|
+
blockNumber: log.blockNumber?.toString() || "0",
|
|
1294
|
+
transactionHash: log.transactionHash,
|
|
1295
|
+
index: log.index?.toString() || "0"
|
|
1296
|
+
}));
|
|
1297
|
+
const rawValues = [transactionHash, blockNumber, gasUsed, gasPrice, ...logs.length > 0 ? logs : []];
|
|
1298
|
+
const stringValues = rawValues.map(String);
|
|
1299
|
+
return {
|
|
1300
|
+
status: success ? "success" : "error",
|
|
1301
|
+
warp,
|
|
1302
|
+
action: actionIndex,
|
|
1303
|
+
user: getWarpWalletAddressFromConfig2(this.config, this.chain.name),
|
|
1304
|
+
txHash: transactionHash,
|
|
1305
|
+
tx: {
|
|
1306
|
+
...tx,
|
|
1307
|
+
status: tx.status
|
|
1308
|
+
},
|
|
1309
|
+
next: null,
|
|
1310
|
+
values: { string: stringValues, native: rawValues, mapped: {} },
|
|
1311
|
+
output: {},
|
|
1312
|
+
messages: {},
|
|
1313
|
+
destination: null,
|
|
1314
|
+
resolvedInputs
|
|
1315
|
+
};
|
|
1316
|
+
}
|
|
1317
|
+
async extractQueryOutput(warp, typedValues, actionIndex, inputs) {
|
|
1318
|
+
const stringValues = typedValues.map((t) => this.serializer.typedToString(t));
|
|
1319
|
+
const nativeValues = typedValues.map((t) => this.serializer.typedToNative(t)[1]);
|
|
1320
|
+
const values = { string: stringValues, native: nativeValues, mapped: {} };
|
|
1321
|
+
let output = {};
|
|
1322
|
+
if (!warp.output) return { values, output };
|
|
1323
|
+
const getNestedValue = (path) => {
|
|
1324
|
+
const indices = path.split(".").slice(1).map((i) => parseInt(i) - 1);
|
|
1325
|
+
if (indices.length === 0) return void 0;
|
|
1326
|
+
let value = nativeValues[indices[0]];
|
|
1327
|
+
for (let i = 1; i < indices.length; i++) {
|
|
1328
|
+
if (value === void 0 || value === null) return void 0;
|
|
1329
|
+
value = value[indices[i]];
|
|
1330
|
+
}
|
|
1331
|
+
return value;
|
|
1332
|
+
};
|
|
1333
|
+
for (const [key, path] of Object.entries(warp.output)) {
|
|
1334
|
+
if (path.startsWith(WarpConstants2.Transform.Prefix)) continue;
|
|
1335
|
+
const currentActionIndex = parseOutputOutIndex(path);
|
|
1336
|
+
if (currentActionIndex !== null && currentActionIndex !== actionIndex) {
|
|
1337
|
+
output[key] = null;
|
|
1338
|
+
continue;
|
|
1339
|
+
}
|
|
1340
|
+
if (path.startsWith("out.") || path === "out" || path.startsWith("out[")) {
|
|
1341
|
+
output[key] = getNestedValue(path) || null;
|
|
1342
|
+
} else {
|
|
1343
|
+
output[key] = path;
|
|
1344
|
+
}
|
|
1345
|
+
}
|
|
1346
|
+
return { values, output: await evaluateOutputCommon(warp, output, actionIndex, inputs, this.serializer.coreSerializer, this.config) };
|
|
1347
|
+
}
|
|
1348
|
+
async getTransactionStatus(txHash) {
|
|
1349
|
+
try {
|
|
1350
|
+
const receipt = await this.provider.getTransactionReceipt(txHash);
|
|
1351
|
+
if (!receipt) {
|
|
1352
|
+
return { status: "pending" };
|
|
1353
|
+
}
|
|
1354
|
+
return {
|
|
1355
|
+
status: receipt.status === 1 ? "confirmed" : "failed",
|
|
1356
|
+
blockNumber: receipt.blockNumber,
|
|
1357
|
+
gasUsed: receipt.gasUsed
|
|
1358
|
+
};
|
|
1359
|
+
} catch (error) {
|
|
1360
|
+
throw new Error(`Failed to get transaction status: ${error}`);
|
|
1361
|
+
}
|
|
1362
|
+
}
|
|
1363
|
+
async getTransactionReceipt(txHash) {
|
|
1364
|
+
try {
|
|
1365
|
+
return await this.provider.getTransactionReceipt(txHash);
|
|
1366
|
+
} catch (error) {
|
|
1367
|
+
return null;
|
|
1368
|
+
}
|
|
1369
|
+
}
|
|
1370
|
+
};
|
|
1371
|
+
|
|
1372
|
+
// src/WarpEvmExecutor.ts
|
|
1373
|
+
var WarpEvmExecutor = class {
|
|
1374
|
+
constructor(config, chain) {
|
|
1375
|
+
this.config = config;
|
|
1376
|
+
this.chain = chain;
|
|
1377
|
+
this.serializer = new WarpEvmSerializer();
|
|
1378
|
+
const providerConfig = getProviderConfig3(this.config, chain.name, this.config.env, this.chain.defaultApiUrl);
|
|
1379
|
+
const network = new ethers6.Network(this.chain.name, parseInt(this.chain.chainId));
|
|
1380
|
+
this.provider = new ethers6.JsonRpcProvider(providerConfig.url, network);
|
|
1381
|
+
this.output = new WarpEvmOutput(config, this.chain);
|
|
1382
|
+
}
|
|
1383
|
+
async createTransaction(executable) {
|
|
1384
|
+
const action = getWarpActionByIndex(executable.warp, executable.action);
|
|
1385
|
+
let tx = null;
|
|
1386
|
+
if (action.type === "transfer") {
|
|
1387
|
+
tx = await this.createTransferTransaction(executable);
|
|
1388
|
+
} else if (action.type === "contract") {
|
|
1389
|
+
tx = await this.createContractCallTransaction(executable);
|
|
1390
|
+
} else if (action.type === "query") {
|
|
1391
|
+
throw new Error("WarpEvmExecutor: Invalid action type for createTransaction; Use executeQuery instead");
|
|
1392
|
+
} else if (action.type === "collect") {
|
|
1393
|
+
throw new Error("WarpEvmExecutor: Invalid action type for createTransaction; Use executeCollect instead");
|
|
1394
|
+
}
|
|
1395
|
+
if (!tx) throw new Error(`WarpEvmExecutor: Invalid action type (${action.type})`);
|
|
1396
|
+
return tx;
|
|
1397
|
+
}
|
|
1398
|
+
async createTransferTransaction(executable) {
|
|
1399
|
+
const userWallet = getWarpWalletAddressFromConfig3(this.config, executable.chain.name);
|
|
1400
|
+
if (!userWallet) throw new Error("WarpEvmExecutor: createTransfer - user address not set");
|
|
1401
|
+
if (!ethers6.isAddress(executable.destination)) {
|
|
1402
|
+
throw new Error(`WarpEvmExecutor: Invalid destination address: ${executable.destination}`);
|
|
1403
|
+
}
|
|
1404
|
+
if (executable.transfers && executable.transfers.length > 0) {
|
|
1405
|
+
return this.createTokenTransferTransaction(executable, userWallet);
|
|
1406
|
+
}
|
|
1407
|
+
const tx = {
|
|
1408
|
+
to: executable.destination,
|
|
1409
|
+
value: executable.value,
|
|
1410
|
+
data: executable.data ? this.serializer.stringToTyped(executable.data) : "0x"
|
|
1411
|
+
};
|
|
1412
|
+
return this.estimateGasAndSetDefaults(tx, userWallet);
|
|
1413
|
+
}
|
|
1414
|
+
async createContractCallTransaction(executable) {
|
|
1415
|
+
const userWallet = getWarpWalletAddressFromConfig3(this.config, executable.chain.name);
|
|
1416
|
+
if (!userWallet) throw new Error("WarpEvmExecutor: createContractCall - user address not set");
|
|
1417
|
+
const action = getWarpActionByIndex(executable.warp, executable.action);
|
|
1418
|
+
if (!action || !("func" in action) || !action.func) throw new Error("WarpEvmExecutor: Contract action must have a function name");
|
|
1419
|
+
if (!ethers6.isAddress(executable.destination)) throw new Error(`WarpEvmExecutor: Invalid contract address: ${executable.destination}`);
|
|
1420
|
+
try {
|
|
1421
|
+
let iface;
|
|
1422
|
+
try {
|
|
1423
|
+
iface = new ethers6.Interface(JSON.parse(action.abi));
|
|
1424
|
+
} catch {
|
|
1425
|
+
iface = new ethers6.Interface([action.abi]);
|
|
1426
|
+
}
|
|
1427
|
+
const funcFragment = iface.getFunction(action.func);
|
|
1428
|
+
if (!funcFragment) throw new Error(`WarpEvmExecutor: Function ${action.func} not found in ABI`);
|
|
1429
|
+
const nativeArgs = this.prepareNativeArgs(executable.args, funcFragment);
|
|
1430
|
+
console.log("Native args:", nativeArgs);
|
|
1431
|
+
const encodedData = iface.encodeFunctionData(action.func, nativeArgs);
|
|
1432
|
+
const value = this.getPayableValue(executable, funcFragment);
|
|
1433
|
+
console.log("Encoded data:", encodedData);
|
|
1434
|
+
console.log("Value:", value);
|
|
1435
|
+
const tx = {
|
|
1436
|
+
to: executable.destination,
|
|
1437
|
+
value,
|
|
1438
|
+
data: encodedData
|
|
1439
|
+
};
|
|
1440
|
+
return this.estimateGasAndSetDefaults(tx, userWallet);
|
|
1441
|
+
} catch (error) {
|
|
1442
|
+
throw new Error(`WarpEvmExecutor: Failed to encode function data for ${action.func}: ${error}`);
|
|
1443
|
+
}
|
|
1444
|
+
}
|
|
1445
|
+
async createTokenTransferTransaction(executable, userWallet) {
|
|
1446
|
+
if (executable.transfers.length === 0) throw new Error("WarpEvmExecutor: No transfers provided");
|
|
1447
|
+
if (!this.chain.nativeToken?.identifier) throw new Error("WarpEvmExecutor: No native token defined for this chain");
|
|
1448
|
+
const nativeTokenTransfers = executable.transfers.filter((transfer) => transfer.identifier === this.chain.nativeToken.identifier);
|
|
1449
|
+
const erc20Transfers = executable.transfers.filter((transfer) => transfer.identifier !== this.chain.nativeToken.identifier);
|
|
1450
|
+
if (nativeTokenTransfers.length === 1 && erc20Transfers.length === 0) {
|
|
1451
|
+
const transfer = nativeTokenTransfers[0];
|
|
1452
|
+
if (transfer.amount <= 0n) throw new Error("WarpEvmExecutor: Native token transfer amount must be positive");
|
|
1453
|
+
const tx = {
|
|
1454
|
+
to: executable.destination,
|
|
1455
|
+
value: transfer.amount,
|
|
1456
|
+
data: "0x"
|
|
1457
|
+
};
|
|
1458
|
+
return this.estimateGasAndSetDefaults(tx, userWallet);
|
|
1459
|
+
}
|
|
1460
|
+
if (nativeTokenTransfers.length === 0 && erc20Transfers.length === 1) {
|
|
1461
|
+
return this.createSingleTokenTransfer(executable, erc20Transfers[0], userWallet);
|
|
1462
|
+
}
|
|
1463
|
+
if (executable.transfers.length > 1) throw new Error("WarpEvmExecutor: Multiple token transfers not yet supported");
|
|
1464
|
+
throw new Error("WarpEvmExecutor: Invalid transfer configuration");
|
|
1465
|
+
}
|
|
1466
|
+
async createSingleTokenTransfer(executable, transfer, userWallet) {
|
|
1467
|
+
if (!ethers6.isAddress(transfer.identifier)) {
|
|
1468
|
+
throw new Error(`WarpEvmExecutor: Invalid token address: ${transfer.identifier}`);
|
|
1469
|
+
}
|
|
1470
|
+
const transferInterface = new ethers6.Interface(["function transfer(address to, uint256 amount) returns (bool)"]);
|
|
1471
|
+
const encodedData = transferInterface.encodeFunctionData("transfer", [executable.destination, transfer.amount]);
|
|
1472
|
+
const tx = {
|
|
1473
|
+
to: transfer.identifier,
|
|
1474
|
+
value: 0n,
|
|
1475
|
+
data: encodedData
|
|
1476
|
+
};
|
|
1477
|
+
return this.estimateGasAndSetDefaults(tx, userWallet);
|
|
1478
|
+
}
|
|
1479
|
+
async executeQuery(executable) {
|
|
1480
|
+
const action = getWarpActionByIndex(executable.warp, executable.action);
|
|
1481
|
+
if (action.type !== "query") throw new Error(`WarpEvmExecutor: Invalid action type for executeQuery: ${action.type}`);
|
|
1482
|
+
if (!action.func) throw new Error("WarpEvmExecutor: Query action must have a function name");
|
|
1483
|
+
if (!ethers6.isAddress(executable.destination)) throw new Error(`WarpEvmExecutor: Invalid address for query: ${executable.destination}`);
|
|
1484
|
+
try {
|
|
1485
|
+
let iface;
|
|
1486
|
+
try {
|
|
1487
|
+
iface = new ethers6.Interface(JSON.parse(action.abi));
|
|
1488
|
+
} catch {
|
|
1489
|
+
iface = new ethers6.Interface([action.abi]);
|
|
1490
|
+
}
|
|
1491
|
+
const funcFragment = iface.getFunction(action.func);
|
|
1492
|
+
if (!funcFragment) throw new Error(`WarpEvmExecutor: Function ${action.func} not found in ABI`);
|
|
1493
|
+
const nativeArgs = this.prepareNativeArgs(executable.args, funcFragment);
|
|
1494
|
+
const encodedData = iface.encodeFunctionData(action.func, nativeArgs);
|
|
1495
|
+
const result = await this.provider.call({
|
|
1496
|
+
to: executable.destination,
|
|
1497
|
+
data: encodedData
|
|
1498
|
+
});
|
|
1499
|
+
const decodedResult = iface.decodeFunctionResult(action.func, result);
|
|
1500
|
+
const isSuccess = true;
|
|
1501
|
+
const { values, output } = await this.output.extractQueryOutput(
|
|
1502
|
+
executable.warp,
|
|
1503
|
+
decodedResult,
|
|
1504
|
+
executable.action,
|
|
1505
|
+
executable.resolvedInputs
|
|
1506
|
+
);
|
|
1507
|
+
const next = getNextInfo(this.config, [], executable.warp, executable.action, output);
|
|
1508
|
+
const destinationInput = executable.resolvedInputs.find((i) => i.input.position === "receiver" || i.input.position === "destination");
|
|
1509
|
+
const destination = destinationInput?.value || executable.destination;
|
|
1510
|
+
const resolvedInputs = extractResolvedInputValues2(executable.resolvedInputs);
|
|
1511
|
+
return {
|
|
1512
|
+
status: isSuccess ? "success" : "error",
|
|
1513
|
+
warp: executable.warp,
|
|
1514
|
+
action: executable.action,
|
|
1515
|
+
user: getWarpWalletAddressFromConfig3(this.config, executable.chain.name),
|
|
1516
|
+
txHash: null,
|
|
1517
|
+
tx: null,
|
|
1518
|
+
next,
|
|
1519
|
+
values,
|
|
1520
|
+
output: { ...output, _DATA: decodedResult },
|
|
1521
|
+
messages: applyOutputToMessages(executable.warp, output, this.config),
|
|
1522
|
+
destination,
|
|
1523
|
+
resolvedInputs
|
|
1524
|
+
};
|
|
1525
|
+
} catch (error) {
|
|
1526
|
+
const destinationInput = executable.resolvedInputs.find((i) => i.input.position === "receiver" || i.input.position === "destination");
|
|
1527
|
+
const destination = destinationInput?.value || executable.destination;
|
|
1528
|
+
const resolvedInputs = extractResolvedInputValues2(executable.resolvedInputs);
|
|
1529
|
+
return {
|
|
1530
|
+
status: "error",
|
|
1531
|
+
warp: executable.warp,
|
|
1532
|
+
action: executable.action,
|
|
1533
|
+
user: getWarpWalletAddressFromConfig3(this.config, executable.chain.name),
|
|
1534
|
+
txHash: null,
|
|
1535
|
+
tx: null,
|
|
1536
|
+
next: null,
|
|
1537
|
+
values: { string: [], native: [], mapped: {} },
|
|
1538
|
+
output: { _DATA: error },
|
|
1539
|
+
messages: {},
|
|
1540
|
+
destination,
|
|
1541
|
+
resolvedInputs
|
|
1542
|
+
};
|
|
1543
|
+
}
|
|
1544
|
+
}
|
|
1545
|
+
async estimateGasAndSetDefaults(tx, from) {
|
|
1546
|
+
try {
|
|
1547
|
+
const gasEstimate = await this.provider.estimateGas({
|
|
1548
|
+
...tx,
|
|
1549
|
+
from
|
|
1550
|
+
});
|
|
1551
|
+
if (gasEstimate < BigInt(WarpEvmConstants.Validation.MinGasLimit)) throw new Error(`Gas estimate too low: ${gasEstimate}`);
|
|
1552
|
+
if (gasEstimate > BigInt(WarpEvmConstants.Validation.MaxGasLimit)) throw new Error(`Gas estimate too high: ${gasEstimate}`);
|
|
1553
|
+
const feeData = await this.provider.getFeeData();
|
|
1554
|
+
if (feeData.maxFeePerGas && feeData.maxPriorityFeePerGas) {
|
|
1555
|
+
return {
|
|
1556
|
+
...tx,
|
|
1557
|
+
chainId: parseInt(this.chain.chainId),
|
|
1558
|
+
gasLimit: gasEstimate,
|
|
1559
|
+
maxFeePerGas: feeData.maxFeePerGas,
|
|
1560
|
+
maxPriorityFeePerGas: feeData.maxPriorityFeePerGas
|
|
1561
|
+
};
|
|
1562
|
+
} else if (feeData.gasPrice) {
|
|
1563
|
+
return {
|
|
1564
|
+
...tx,
|
|
1565
|
+
chainId: parseInt(this.chain.chainId),
|
|
1566
|
+
gasLimit: gasEstimate,
|
|
1567
|
+
gasPrice: feeData.gasPrice
|
|
1568
|
+
};
|
|
1569
|
+
} else {
|
|
1570
|
+
return {
|
|
1571
|
+
...tx,
|
|
1572
|
+
chainId: parseInt(this.chain.chainId),
|
|
1573
|
+
gasLimit: gasEstimate,
|
|
1574
|
+
gasPrice: ethers6.parseUnits(WarpEvmConstants.GasPrice.Default, "wei")
|
|
1575
|
+
};
|
|
1576
|
+
}
|
|
1577
|
+
} catch (error) {
|
|
1578
|
+
let defaultGasLimit = BigInt(WarpEvmConstants.GasLimit.Default);
|
|
1579
|
+
if (tx.data && tx.data !== "0x") {
|
|
1580
|
+
if (tx.data.startsWith("0xa9059cbb")) {
|
|
1581
|
+
defaultGasLimit = BigInt(WarpEvmConstants.GasLimit.TokenTransfer);
|
|
1582
|
+
} else {
|
|
1583
|
+
defaultGasLimit = BigInt(WarpEvmConstants.GasLimit.ContractCall);
|
|
1584
|
+
}
|
|
1585
|
+
} else {
|
|
1586
|
+
defaultGasLimit = BigInt(WarpEvmConstants.GasLimit.Transfer);
|
|
1587
|
+
}
|
|
1588
|
+
return {
|
|
1589
|
+
...tx,
|
|
1590
|
+
chainId: parseInt(this.chain.chainId),
|
|
1591
|
+
gasLimit: defaultGasLimit,
|
|
1592
|
+
gasPrice: ethers6.parseUnits(WarpEvmConstants.GasPrice.Default, "wei")
|
|
1593
|
+
};
|
|
1594
|
+
}
|
|
1595
|
+
}
|
|
1596
|
+
async verifyMessage(message, signature) {
|
|
1597
|
+
try {
|
|
1598
|
+
const recoveredAddress = ethers6.verifyMessage(message, signature);
|
|
1599
|
+
return recoveredAddress;
|
|
1600
|
+
} catch (error) {
|
|
1601
|
+
throw new Error(`Failed to verify message: ${error}`);
|
|
1602
|
+
}
|
|
1603
|
+
}
|
|
1604
|
+
getPayableValue(executable, funcFragment) {
|
|
1605
|
+
if (funcFragment.stateMutability !== "payable") {
|
|
1606
|
+
return executable.value;
|
|
1607
|
+
}
|
|
1608
|
+
const nativeTokenId = this.chain.nativeToken?.identifier;
|
|
1609
|
+
const zeroAddress = "0x0000000000000000000000000000000000000000";
|
|
1610
|
+
const nativeTokenTransfer = nativeTokenId ? executable.transfers.find((transfer) => transfer.identifier === nativeTokenId || transfer.identifier === zeroAddress) : void 0;
|
|
1611
|
+
if (nativeTokenTransfer) {
|
|
1612
|
+
return nativeTokenTransfer.amount;
|
|
1613
|
+
}
|
|
1614
|
+
const nativeTokenAsset = this.findNativeTokenAsset(executable.resolvedInputs, nativeTokenId, zeroAddress);
|
|
1615
|
+
if (nativeTokenAsset) {
|
|
1616
|
+
return nativeTokenAsset.amount;
|
|
1617
|
+
}
|
|
1618
|
+
return executable.value;
|
|
1619
|
+
}
|
|
1620
|
+
findNativeTokenAsset(resolvedInputs, nativeTokenId, zeroAddress) {
|
|
1621
|
+
for (const input of resolvedInputs) {
|
|
1622
|
+
if (input.input.type === "asset" && input.value) {
|
|
1623
|
+
const [, assetValue] = this.serializer.coreSerializer.stringToNative(input.value);
|
|
1624
|
+
const asset = assetValue;
|
|
1625
|
+
if (asset && "amount" in asset) {
|
|
1626
|
+
if (asset.identifier === nativeTokenId || asset.identifier === zeroAddress) {
|
|
1627
|
+
return asset;
|
|
1628
|
+
}
|
|
1629
|
+
}
|
|
1630
|
+
}
|
|
1631
|
+
}
|
|
1632
|
+
return null;
|
|
1633
|
+
}
|
|
1634
|
+
prepareNativeArgs(args, funcFragment) {
|
|
1635
|
+
return args.map((arg, index) => {
|
|
1636
|
+
const nativeValue = this.serializer.coreSerializer.stringToNative(arg)[1];
|
|
1637
|
+
const paramType = funcFragment.inputs[index]?.type;
|
|
1638
|
+
if (paramType === "bytes32" && typeof nativeValue === "string") {
|
|
1639
|
+
let hexValue = nativeValue;
|
|
1640
|
+
if (!hexValue.startsWith("0x")) {
|
|
1641
|
+
hexValue = "0x" + hexValue;
|
|
1642
|
+
}
|
|
1643
|
+
if (hexValue.length !== 66) {
|
|
1644
|
+
hexValue = ethers6.zeroPadValue(hexValue, 32);
|
|
1645
|
+
}
|
|
1646
|
+
return hexValue;
|
|
1647
|
+
}
|
|
1648
|
+
return nativeValue;
|
|
1649
|
+
});
|
|
1650
|
+
}
|
|
1651
|
+
};
|
|
1652
|
+
|
|
1653
|
+
// src/WarpEvmExplorer.ts
|
|
1654
|
+
var WarpEvmExplorer = class {
|
|
1655
|
+
constructor(chain, config) {
|
|
1656
|
+
this.chain = chain;
|
|
1657
|
+
this.config = config;
|
|
1658
|
+
}
|
|
1659
|
+
getExplorers() {
|
|
1660
|
+
const chainExplorers = EvmExplorers[this.chain.name];
|
|
1661
|
+
if (!chainExplorers) {
|
|
1662
|
+
return ["Default"];
|
|
1663
|
+
}
|
|
1664
|
+
const explorers = chainExplorers[this.config.env];
|
|
1665
|
+
if (!explorers) {
|
|
1666
|
+
return ["Default"];
|
|
1667
|
+
}
|
|
1668
|
+
return explorers;
|
|
1669
|
+
}
|
|
1670
|
+
getPrimaryExplorer() {
|
|
1671
|
+
const explorers = this.getExplorers();
|
|
1672
|
+
return explorers[0];
|
|
1673
|
+
}
|
|
1674
|
+
getExplorerUrlByName(explorer) {
|
|
1675
|
+
const userPreference = this.config.preferences?.explorers?.[this.chain.name];
|
|
1676
|
+
if (userPreference && !explorer) {
|
|
1677
|
+
const url2 = ExplorerUrls[userPreference];
|
|
1678
|
+
if (url2) return url2;
|
|
1679
|
+
}
|
|
1680
|
+
if (explorer) {
|
|
1681
|
+
const url2 = ExplorerUrls[explorer];
|
|
1682
|
+
if (url2) return url2;
|
|
1683
|
+
}
|
|
1684
|
+
const primaryExplorer = this.getPrimaryExplorer();
|
|
1685
|
+
const url = ExplorerUrls[primaryExplorer];
|
|
1686
|
+
return url || ExplorerUrls[primaryExplorer];
|
|
1687
|
+
}
|
|
1688
|
+
getAccountUrl(address, explorer) {
|
|
1689
|
+
const baseUrl = this.getExplorerUrlByName(explorer);
|
|
1690
|
+
return `${baseUrl}/address/${address}`;
|
|
1691
|
+
}
|
|
1692
|
+
getTransactionUrl(hash, explorer) {
|
|
1693
|
+
const baseUrl = this.getExplorerUrlByName(explorer);
|
|
1694
|
+
return `${baseUrl}/tx/${hash}`;
|
|
1695
|
+
}
|
|
1696
|
+
getBlockUrl(blockNumber, explorer) {
|
|
1697
|
+
const baseUrl = this.getExplorerUrlByName(explorer);
|
|
1698
|
+
return `${baseUrl}/block/${blockNumber}`;
|
|
1699
|
+
}
|
|
1700
|
+
getAssetUrl(identifier, explorer) {
|
|
1701
|
+
const baseUrl = this.getExplorerUrlByName(explorer);
|
|
1702
|
+
return `${baseUrl}/token/${identifier}`;
|
|
1703
|
+
}
|
|
1704
|
+
getContractUrl(address, explorer) {
|
|
1705
|
+
const baseUrl = this.getExplorerUrlByName(explorer);
|
|
1706
|
+
return `${baseUrl}/address/${address}`;
|
|
1707
|
+
}
|
|
1708
|
+
getAllExplorers() {
|
|
1709
|
+
return this.getExplorers();
|
|
1710
|
+
}
|
|
1711
|
+
getExplorerByName(name) {
|
|
1712
|
+
const explorers = this.getExplorers();
|
|
1713
|
+
return explorers.find((explorer) => explorer.toLowerCase() === name.toLowerCase());
|
|
1714
|
+
}
|
|
1715
|
+
getAccountUrls(address) {
|
|
1716
|
+
const explorers = this.getAllExplorers();
|
|
1717
|
+
const urls = {};
|
|
1718
|
+
explorers.forEach((explorer) => {
|
|
1719
|
+
const url = ExplorerUrls[explorer];
|
|
1720
|
+
if (url) {
|
|
1721
|
+
urls[explorer] = `${url}/address/${address}`;
|
|
1722
|
+
}
|
|
1723
|
+
});
|
|
1724
|
+
return urls;
|
|
1725
|
+
}
|
|
1726
|
+
getTransactionUrls(hash) {
|
|
1727
|
+
const explorers = this.getAllExplorers();
|
|
1728
|
+
const urls = {};
|
|
1729
|
+
explorers.forEach((explorer) => {
|
|
1730
|
+
const url = ExplorerUrls[explorer];
|
|
1731
|
+
if (url) {
|
|
1732
|
+
urls[explorer] = `${url}/tx/${hash}`;
|
|
1733
|
+
}
|
|
1734
|
+
});
|
|
1735
|
+
return urls;
|
|
1736
|
+
}
|
|
1737
|
+
getAssetUrls(identifier) {
|
|
1738
|
+
const explorers = this.getAllExplorers();
|
|
1739
|
+
const urls = {};
|
|
1740
|
+
explorers.forEach((explorer) => {
|
|
1741
|
+
const url = ExplorerUrls[explorer];
|
|
1742
|
+
if (url) {
|
|
1743
|
+
urls[explorer] = `${url}/token/${identifier}`;
|
|
1744
|
+
}
|
|
1745
|
+
});
|
|
1746
|
+
return urls;
|
|
1747
|
+
}
|
|
1748
|
+
getContractUrls(address) {
|
|
1749
|
+
const explorers = this.getAllExplorers();
|
|
1750
|
+
const urls = {};
|
|
1751
|
+
explorers.forEach((explorer) => {
|
|
1752
|
+
const url = ExplorerUrls[explorer];
|
|
1753
|
+
if (url) {
|
|
1754
|
+
urls[explorer] = `${url}/address/${address}`;
|
|
1755
|
+
}
|
|
1756
|
+
});
|
|
1757
|
+
return urls;
|
|
1758
|
+
}
|
|
1759
|
+
getBlockUrls(blockNumber) {
|
|
1760
|
+
const explorers = this.getAllExplorers();
|
|
1761
|
+
const urls = {};
|
|
1762
|
+
explorers.forEach((explorer) => {
|
|
1763
|
+
const url = ExplorerUrls[explorer];
|
|
1764
|
+
if (url) {
|
|
1765
|
+
urls[explorer] = `${url}/block/${blockNumber}`;
|
|
1766
|
+
}
|
|
1767
|
+
});
|
|
1768
|
+
return urls;
|
|
1769
|
+
}
|
|
1770
|
+
};
|
|
1771
|
+
|
|
1772
|
+
// src/WarpEvmWallet.ts
|
|
1773
|
+
import {
|
|
1774
|
+
getProviderConfig as getProviderConfig4
|
|
1775
|
+
} from "@joai/warps";
|
|
1776
|
+
import { registerExactEvmScheme } from "@x402/evm/exact/client";
|
|
1777
|
+
import { ethers as ethers7 } from "ethers";
|
|
1778
|
+
import { privateKeyToAccount } from "viem/accounts";
|
|
1779
|
+
var WarpEvmWallet = class {
|
|
1780
|
+
constructor(config, chain) {
|
|
1781
|
+
this.config = config;
|
|
1782
|
+
this.chain = chain;
|
|
1783
|
+
this.cachedAddress = null;
|
|
1784
|
+
this.cachedPublicKey = null;
|
|
1785
|
+
const providerConfig = getProviderConfig4(config, chain.name, config.env, chain.defaultApiUrl);
|
|
1786
|
+
this.provider = new ethers7.JsonRpcProvider(providerConfig.url);
|
|
1787
|
+
this.walletProvider = this.createProvider();
|
|
1788
|
+
const wallet = config.user?.wallets?.[chain.name];
|
|
1789
|
+
if (typeof wallet === "string") {
|
|
1790
|
+
this.cachedAddress = wallet;
|
|
1791
|
+
} else if (this.walletProvider instanceof PrivateKeyWalletProvider || this.walletProvider instanceof MnemonicWalletProvider) {
|
|
1792
|
+
try {
|
|
1793
|
+
const w = this.walletProvider.getWalletInstance();
|
|
1794
|
+
this.cachedAddress = w.address;
|
|
1795
|
+
const pk = w.signingKey.publicKey;
|
|
1796
|
+
this.cachedPublicKey = pk.startsWith("0x") ? pk.slice(2) : pk;
|
|
1797
|
+
} catch {
|
|
1798
|
+
}
|
|
1799
|
+
}
|
|
1800
|
+
}
|
|
1801
|
+
async signTransaction(tx) {
|
|
1802
|
+
if (!tx || typeof tx !== "object") throw new Error("Invalid transaction object");
|
|
1803
|
+
if (!this.walletProvider) throw new Error("No wallet provider available");
|
|
1804
|
+
if (this.walletProvider instanceof ReadOnlyWalletProvider) throw new Error(`Wallet (${this.chain.name}) is read-only`);
|
|
1805
|
+
if (tx.nonce === void 0) {
|
|
1806
|
+
const address = await this.getAddressAsync();
|
|
1807
|
+
if (address) {
|
|
1808
|
+
tx.nonce = await this.provider.getTransactionCount(address, "pending");
|
|
1809
|
+
}
|
|
1810
|
+
}
|
|
1811
|
+
this.normalizeFees(tx);
|
|
1812
|
+
return await this.walletProvider.signTransaction(tx);
|
|
1813
|
+
}
|
|
1814
|
+
async signTransactions(txs) {
|
|
1815
|
+
if (txs.length === 0) return [];
|
|
1816
|
+
if (!this.walletProvider) throw new Error("No wallet provider available");
|
|
1817
|
+
const address = await this.getAddressAsync();
|
|
1818
|
+
if (!address) throw new Error("No wallet address available");
|
|
1819
|
+
const currentNonce = await this.provider.getTransactionCount(address, "pending");
|
|
1820
|
+
const signedTxs = [];
|
|
1821
|
+
for (let i = 0; i < txs.length; i++) {
|
|
1822
|
+
const tx = { ...txs[i] };
|
|
1823
|
+
if (tx.nonce === void 0) {
|
|
1824
|
+
tx.nonce = currentNonce + i;
|
|
1825
|
+
}
|
|
1826
|
+
if (i > 0 && (this.walletProvider instanceof PrivateKeyWalletProvider || this.walletProvider instanceof MnemonicWalletProvider)) {
|
|
1827
|
+
this.adjustFeesForMultipleTransactions(tx, i);
|
|
1828
|
+
}
|
|
1829
|
+
this.normalizeFees(tx);
|
|
1830
|
+
signedTxs.push(await this.walletProvider.signTransaction(tx));
|
|
1831
|
+
}
|
|
1832
|
+
return signedTxs;
|
|
1833
|
+
}
|
|
1834
|
+
async signMessage(message) {
|
|
1835
|
+
if (!this.walletProvider) throw new Error("No wallet provider available");
|
|
1836
|
+
if (this.walletProvider instanceof ReadOnlyWalletProvider) throw new Error(`Wallet (${this.chain.name}) is read-only`);
|
|
1837
|
+
return await this.walletProvider.signMessage(message);
|
|
1838
|
+
}
|
|
1839
|
+
async sendTransaction(tx) {
|
|
1840
|
+
if (!tx || typeof tx !== "object") throw new Error("Invalid transaction object");
|
|
1841
|
+
if (!tx.signature) throw new Error("Transaction must be signed before sending");
|
|
1842
|
+
if (!this.walletProvider) throw new Error("No wallet provider available");
|
|
1843
|
+
if (typeof tx.signature === "string" && tx.signature.startsWith("0x")) {
|
|
1844
|
+
const txResponse = await this.provider.broadcastTransaction(tx.signature);
|
|
1845
|
+
return txResponse.hash;
|
|
1846
|
+
}
|
|
1847
|
+
if (this.walletProvider instanceof PrivateKeyWalletProvider || this.walletProvider instanceof MnemonicWalletProvider) {
|
|
1848
|
+
const wallet = this.walletProvider.getWalletInstance();
|
|
1849
|
+
const connectedWallet = wallet.connect(this.provider);
|
|
1850
|
+
const txResponse = await connectedWallet.sendTransaction(tx);
|
|
1851
|
+
return txResponse.hash;
|
|
1852
|
+
}
|
|
1853
|
+
throw new Error("Wallet provider does not support sending transactions");
|
|
1854
|
+
}
|
|
1855
|
+
async sendTransactions(txs) {
|
|
1856
|
+
return Promise.all(txs.map(async (tx) => this.sendTransaction(tx)));
|
|
1857
|
+
}
|
|
1858
|
+
async importFromMnemonic(mnemonic) {
|
|
1859
|
+
const walletProvider = this.createProviderForOperation("mnemonic");
|
|
1860
|
+
return await walletProvider.importFromMnemonic(mnemonic);
|
|
1861
|
+
}
|
|
1862
|
+
async importFromPrivateKey(privateKey) {
|
|
1863
|
+
const walletProvider = this.createProviderForOperation("privateKey");
|
|
1864
|
+
return await walletProvider.importFromPrivateKey(privateKey);
|
|
1865
|
+
}
|
|
1866
|
+
async export(provider) {
|
|
1867
|
+
const walletProvider = this.createProviderForOperation(provider);
|
|
1868
|
+
return await walletProvider.export();
|
|
1869
|
+
}
|
|
1870
|
+
async generate(provider) {
|
|
1871
|
+
const walletProvider = this.createProviderForOperation(provider);
|
|
1872
|
+
return await walletProvider.generate();
|
|
1873
|
+
}
|
|
1874
|
+
getAddress() {
|
|
1875
|
+
return this.cachedAddress;
|
|
1876
|
+
}
|
|
1877
|
+
getPublicKey() {
|
|
1878
|
+
return this.cachedPublicKey;
|
|
1879
|
+
}
|
|
1880
|
+
async registerX402Handlers(client) {
|
|
1881
|
+
if (!this.walletProvider) throw new Error("No wallet provider available");
|
|
1882
|
+
const provider = this.walletProvider;
|
|
1883
|
+
const getInstance = provider.getWalletInstance;
|
|
1884
|
+
if (typeof getInstance !== "function") throw new Error("Wallet provider does not have getWalletInstance method");
|
|
1885
|
+
const wallet = getInstance();
|
|
1886
|
+
if (!wallet || !wallet.privateKey) throw new Error("Wallet instance does not have private key");
|
|
1887
|
+
const signer = privateKeyToAccount(wallet.privateKey);
|
|
1888
|
+
const handlers = {};
|
|
1889
|
+
for (const chainId of SupportedEvmChainIds) {
|
|
1890
|
+
handlers[`eip155:${chainId}`] = () => {
|
|
1891
|
+
registerExactEvmScheme(client, { signer });
|
|
1892
|
+
};
|
|
1893
|
+
}
|
|
1894
|
+
return handlers;
|
|
1895
|
+
}
|
|
1896
|
+
createProvider() {
|
|
1897
|
+
const wallet = this.config.user?.wallets?.[this.chain.name];
|
|
1898
|
+
if (!wallet) return null;
|
|
1899
|
+
if (typeof wallet === "string") return new ReadOnlyWalletProvider(this.config, this.chain);
|
|
1900
|
+
return this.createProviderForOperation(wallet.provider);
|
|
1901
|
+
}
|
|
1902
|
+
async getAddressAsync() {
|
|
1903
|
+
if (this.cachedAddress !== null) return this.cachedAddress;
|
|
1904
|
+
if (!this.walletProvider) return null;
|
|
1905
|
+
this.cachedAddress = await this.walletProvider.getAddress();
|
|
1906
|
+
if (!this.cachedPublicKey) this.cachedPublicKey = await this.walletProvider.getPublicKey();
|
|
1907
|
+
return this.cachedAddress;
|
|
1908
|
+
}
|
|
1909
|
+
createProviderForOperation(provider) {
|
|
1910
|
+
const customWalletProviders = this.config.walletProviders?.[this.chain.name];
|
|
1911
|
+
const providerFactory = customWalletProviders?.[provider];
|
|
1912
|
+
if (providerFactory) {
|
|
1913
|
+
const walletProvider = providerFactory(this.config, this.chain);
|
|
1914
|
+
if (!walletProvider) throw new Error(`Custom wallet provider factory returned null for ${provider}`);
|
|
1915
|
+
return walletProvider;
|
|
1916
|
+
}
|
|
1917
|
+
if (provider === "privateKey") return new PrivateKeyWalletProvider(this.config, this.chain);
|
|
1918
|
+
if (provider === "mnemonic") return new MnemonicWalletProvider(this.config, this.chain);
|
|
1919
|
+
throw new Error(`Unsupported wallet provider for ${this.chain.name}: ${provider}`);
|
|
1920
|
+
}
|
|
1921
|
+
normalizeFees(tx) {
|
|
1922
|
+
const hasEip1559Fields = tx.maxFeePerGas !== void 0 && tx.maxPriorityFeePerGas !== void 0;
|
|
1923
|
+
const hasLegacyFields = tx.gasPrice !== void 0 && !hasEip1559Fields;
|
|
1924
|
+
if (hasEip1559Fields) {
|
|
1925
|
+
const maxFee = this.parseBigInt(tx.maxFeePerGas);
|
|
1926
|
+
const maxPriorityFee = this.parseBigInt(tx.maxPriorityFeePerGas);
|
|
1927
|
+
tx.maxFeePerGas = maxFee;
|
|
1928
|
+
tx.maxPriorityFeePerGas = this.normalizePriorityFee(maxFee, maxPriorityFee);
|
|
1929
|
+
} else if (hasLegacyFields) {
|
|
1930
|
+
const gasPrice = this.parseBigInt(tx.gasPrice);
|
|
1931
|
+
tx.maxFeePerGas = gasPrice;
|
|
1932
|
+
tx.maxPriorityFeePerGas = this.normalizePriorityFee(gasPrice, gasPrice * 9n / 10n);
|
|
1933
|
+
delete tx.gasPrice;
|
|
1934
|
+
} else {
|
|
1935
|
+
const defaultMaxFee = 1000000000n;
|
|
1936
|
+
tx.maxFeePerGas = defaultMaxFee;
|
|
1937
|
+
tx.maxPriorityFeePerGas = defaultMaxFee / 10n;
|
|
1938
|
+
}
|
|
1939
|
+
}
|
|
1940
|
+
parseBigInt(value) {
|
|
1941
|
+
if (value === void 0 || value === null) return void 0;
|
|
1942
|
+
if (typeof value === "bigint") return value;
|
|
1943
|
+
return BigInt(value);
|
|
1944
|
+
}
|
|
1945
|
+
adjustFeesForMultipleTransactions(tx, index) {
|
|
1946
|
+
const priorityReduction = BigInt(index * 1e9);
|
|
1947
|
+
const minGasPrice = BigInt(1e9);
|
|
1948
|
+
if (tx.maxFeePerGas && tx.maxPriorityFeePerGas) {
|
|
1949
|
+
const maxFee = this.parseBigInt(tx.maxFeePerGas);
|
|
1950
|
+
const maxPriorityFee = this.parseBigInt(tx.maxPriorityFeePerGas);
|
|
1951
|
+
const reducedMaxFee = maxFee > priorityReduction ? maxFee - priorityReduction : minGasPrice;
|
|
1952
|
+
const reducedMaxPriorityFee = maxPriorityFee > priorityReduction ? maxPriorityFee - priorityReduction : minGasPrice;
|
|
1953
|
+
tx.maxFeePerGas = reducedMaxFee;
|
|
1954
|
+
tx.maxPriorityFeePerGas = this.normalizePriorityFee(reducedMaxFee, reducedMaxPriorityFee);
|
|
1955
|
+
delete tx.gasPrice;
|
|
1956
|
+
} else if (tx.gasPrice) {
|
|
1957
|
+
tx.gasPrice = tx.gasPrice > priorityReduction ? tx.gasPrice - priorityReduction : minGasPrice;
|
|
1958
|
+
delete tx.maxFeePerGas;
|
|
1959
|
+
delete tx.maxPriorityFeePerGas;
|
|
1960
|
+
}
|
|
1961
|
+
}
|
|
1962
|
+
normalizePriorityFee(maxFee, maxPriorityFee) {
|
|
1963
|
+
if (maxFee <= 0n) return 1n;
|
|
1964
|
+
if (maxPriorityFee <= maxFee) return maxPriorityFee;
|
|
1965
|
+
const safeFee = maxFee / 10n;
|
|
1966
|
+
return safeFee < 1n ? 1n : safeFee;
|
|
1967
|
+
}
|
|
1968
|
+
};
|
|
1969
|
+
|
|
1970
|
+
// src/chains/common.ts
|
|
1971
|
+
var createEvmAdapter = (chainName, chainInfos) => {
|
|
1972
|
+
return (config, fallback) => {
|
|
1973
|
+
if (!fallback) throw new Error(`${chainName} adapter requires a fallback adapter`);
|
|
1974
|
+
return {
|
|
1975
|
+
chainInfo: chainInfos[config.env],
|
|
1976
|
+
builder: () => fallback.builder(),
|
|
1977
|
+
executor: new WarpEvmExecutor(config, chainInfos[config.env]),
|
|
1978
|
+
output: new WarpEvmOutput(config, chainInfos[config.env]),
|
|
1979
|
+
serializer: new WarpEvmSerializer(),
|
|
1980
|
+
registry: fallback.registry,
|
|
1981
|
+
explorer: new WarpEvmExplorer(chainInfos[config.env], config),
|
|
1982
|
+
abiBuilder: () => fallback.abiBuilder(),
|
|
1983
|
+
brandBuilder: () => fallback.brandBuilder(),
|
|
1984
|
+
dataLoader: new WarpEvmDataLoader(config, chainInfos[config.env]),
|
|
1985
|
+
wallet: new WarpEvmWallet(config, chainInfos[config.env])
|
|
1986
|
+
};
|
|
1987
|
+
};
|
|
1988
|
+
};
|
|
1989
|
+
|
|
1990
|
+
// src/chains/arbitrum.ts
|
|
1991
|
+
var NativeTokenArb = {
|
|
1992
|
+
chain: WarpChainName10.Arbitrum,
|
|
1993
|
+
identifier: "ARB",
|
|
1994
|
+
symbol: "ARB",
|
|
1995
|
+
name: "Arbitrum",
|
|
1996
|
+
decimals: 18,
|
|
1997
|
+
logoUrl: "https://raw.githubusercontent.com/JoAiHQ/assets/refs/heads/main/tokens/logos/arb.svg"
|
|
1998
|
+
};
|
|
1999
|
+
var ArbitrumAdapter = createEvmAdapter(WarpChainName10.Arbitrum, {
|
|
2000
|
+
mainnet: {
|
|
2001
|
+
name: WarpChainName10.Arbitrum,
|
|
2002
|
+
displayName: "Arbitrum",
|
|
2003
|
+
chainId: "42161",
|
|
2004
|
+
blockTime: 1e3,
|
|
2005
|
+
addressHrp: "0x",
|
|
2006
|
+
defaultApiUrl: "https://arb1.arbitrum.io/rpc",
|
|
2007
|
+
logoUrl: "https://raw.githubusercontent.com/JoAiHQ/assets/refs/heads/main/chains/logos/arbitrum.svg",
|
|
2008
|
+
nativeToken: NativeTokenArb
|
|
2009
|
+
},
|
|
2010
|
+
testnet: {
|
|
2011
|
+
name: WarpChainName10.Arbitrum,
|
|
2012
|
+
displayName: "Arbitrum Sepolia",
|
|
2013
|
+
chainId: "421614",
|
|
2014
|
+
blockTime: 1e3,
|
|
2015
|
+
addressHrp: "0x",
|
|
2016
|
+
defaultApiUrl: "https://sepolia-rollup.arbitrum.io/rpc",
|
|
2017
|
+
logoUrl: "https://raw.githubusercontent.com/JoAiHQ/assets/refs/heads/main/chains/logos/arbitrum.svg",
|
|
2018
|
+
nativeToken: NativeTokenArb
|
|
2019
|
+
},
|
|
2020
|
+
devnet: {
|
|
2021
|
+
name: WarpChainName10.Arbitrum,
|
|
2022
|
+
displayName: "Arbitrum Sepolia",
|
|
2023
|
+
chainId: "421614",
|
|
2024
|
+
blockTime: 1e3,
|
|
2025
|
+
addressHrp: "0x",
|
|
2026
|
+
defaultApiUrl: "https://sepolia-rollup.arbitrum.io/rpc",
|
|
2027
|
+
logoUrl: "https://raw.githubusercontent.com/JoAiHQ/assets/refs/heads/main/chains/logos/arbitrum.svg",
|
|
2028
|
+
nativeToken: NativeTokenArb
|
|
2029
|
+
}
|
|
2030
|
+
});
|
|
2031
|
+
|
|
2032
|
+
// src/chains/base.ts
|
|
2033
|
+
import { WarpChainName as WarpChainName11 } from "@joai/warps";
|
|
2034
|
+
var NativeTokenBase = {
|
|
2035
|
+
chain: WarpChainName11.Base,
|
|
2036
|
+
identifier: "ETH",
|
|
2037
|
+
name: "Ether",
|
|
2038
|
+
symbol: "ETH",
|
|
2039
|
+
decimals: 18,
|
|
2040
|
+
logoUrl: {
|
|
2041
|
+
light: "https://raw.githubusercontent.com/JoAiHQ/assets/refs/heads/main/tokens/logos/eth-white.svg",
|
|
2042
|
+
dark: "https://raw.githubusercontent.com/JoAiHQ/assets/refs/heads/main/tokens/logos/eth-black.svg"
|
|
2043
|
+
}
|
|
2044
|
+
};
|
|
2045
|
+
var BaseAdapter = createEvmAdapter(WarpChainName11.Base, {
|
|
2046
|
+
mainnet: {
|
|
2047
|
+
name: WarpChainName11.Base,
|
|
2048
|
+
displayName: "Base",
|
|
2049
|
+
chainId: "8453",
|
|
2050
|
+
blockTime: 2e3,
|
|
2051
|
+
addressHrp: "0x",
|
|
2052
|
+
defaultApiUrl: "https://mainnet.base.org",
|
|
2053
|
+
logoUrl: {
|
|
2054
|
+
light: "https://raw.githubusercontent.com/JoAiHQ/assets/refs/heads/main/chains/logos/base-white.svg",
|
|
2055
|
+
dark: "https://raw.githubusercontent.com/JoAiHQ/assets/refs/heads/main/chains/logos/base-black.svg"
|
|
2056
|
+
},
|
|
2057
|
+
nativeToken: NativeTokenBase
|
|
2058
|
+
},
|
|
2059
|
+
testnet: {
|
|
2060
|
+
name: WarpChainName11.Base,
|
|
2061
|
+
displayName: "Base Sepolia",
|
|
2062
|
+
chainId: "84532",
|
|
2063
|
+
blockTime: 2e3,
|
|
2064
|
+
addressHrp: "0x",
|
|
2065
|
+
defaultApiUrl: "https://sepolia.base.org",
|
|
2066
|
+
logoUrl: {
|
|
2067
|
+
light: "https://raw.githubusercontent.com/JoAiHQ/assets/refs/heads/main/chains/logos/base-white.svg",
|
|
2068
|
+
dark: "https://raw.githubusercontent.com/JoAiHQ/assets/refs/heads/main/chains/logos/base-black.svg"
|
|
2069
|
+
},
|
|
2070
|
+
nativeToken: NativeTokenBase
|
|
2071
|
+
},
|
|
2072
|
+
devnet: {
|
|
2073
|
+
name: WarpChainName11.Base,
|
|
2074
|
+
displayName: "Base Sepolia",
|
|
2075
|
+
chainId: "84532",
|
|
2076
|
+
blockTime: 2e3,
|
|
2077
|
+
addressHrp: "0x",
|
|
2078
|
+
defaultApiUrl: "https://sepolia.base.org",
|
|
2079
|
+
logoUrl: {
|
|
2080
|
+
light: "https://raw.githubusercontent.com/JoAiHQ/assets/refs/heads/main/chains/logos/base-white.svg",
|
|
2081
|
+
dark: "https://raw.githubusercontent.com/JoAiHQ/assets/refs/heads/main/chains/logos/base-black.svg"
|
|
2082
|
+
},
|
|
2083
|
+
nativeToken: NativeTokenBase
|
|
2084
|
+
}
|
|
2085
|
+
});
|
|
2086
|
+
|
|
2087
|
+
// src/chains/combined.ts
|
|
2088
|
+
import { WarpChainName as WarpChainName12 } from "@joai/warps";
|
|
2089
|
+
var getAllEvmChainNames = () => [
|
|
2090
|
+
WarpChainName12.Ethereum,
|
|
2091
|
+
WarpChainName12.Base,
|
|
2092
|
+
WarpChainName12.Arbitrum,
|
|
2093
|
+
WarpChainName12.Polygon,
|
|
2094
|
+
WarpChainName12.Somnia
|
|
2095
|
+
];
|
|
2096
|
+
|
|
2097
|
+
// src/chains/ethereum.ts
|
|
2098
|
+
import { WarpChainName as WarpChainName13 } from "@joai/warps";
|
|
2099
|
+
var NativeTokenEth = {
|
|
2100
|
+
chain: WarpChainName13.Ethereum,
|
|
2101
|
+
identifier: "ETH",
|
|
2102
|
+
symbol: "ETH",
|
|
2103
|
+
name: "Ether",
|
|
2104
|
+
decimals: 18,
|
|
2105
|
+
logoUrl: {
|
|
2106
|
+
light: "https://raw.githubusercontent.com/JoAiHQ/assets/refs/heads/main/tokens/logos/eth-white.svg",
|
|
2107
|
+
dark: "https://raw.githubusercontent.com/JoAiHQ/assets/refs/heads/main/tokens/logos/eth-black.svg"
|
|
2108
|
+
}
|
|
2109
|
+
};
|
|
2110
|
+
var EthereumAdapter = createEvmAdapter(WarpChainName13.Ethereum, {
|
|
2111
|
+
mainnet: {
|
|
2112
|
+
name: WarpChainName13.Ethereum,
|
|
2113
|
+
displayName: "Ethereum Mainnet",
|
|
2114
|
+
chainId: "1",
|
|
2115
|
+
blockTime: 12e3,
|
|
2116
|
+
addressHrp: "0x",
|
|
2117
|
+
defaultApiUrl: "https://ethereum-rpc.publicnode.com",
|
|
2118
|
+
logoUrl: {
|
|
2119
|
+
light: "https://raw.githubusercontent.com/JoAiHQ/assets/refs/heads/main/chains/logos/ethereum-white.svg",
|
|
2120
|
+
dark: "https://raw.githubusercontent.com/JoAiHQ/assets/refs/heads/main/chains/logos/ethereum-black.svg"
|
|
2121
|
+
},
|
|
2122
|
+
nativeToken: NativeTokenEth
|
|
2123
|
+
},
|
|
2124
|
+
testnet: {
|
|
2125
|
+
name: WarpChainName13.Ethereum,
|
|
2126
|
+
displayName: "Ethereum Sepolia",
|
|
2127
|
+
chainId: "11155111",
|
|
2128
|
+
blockTime: 12e3,
|
|
2129
|
+
addressHrp: "0x",
|
|
2130
|
+
defaultApiUrl: "https://ethereum-sepolia-rpc.publicnode.com",
|
|
2131
|
+
logoUrl: {
|
|
2132
|
+
light: "https://raw.githubusercontent.com/JoAiHQ/assets/refs/heads/main/chains/logos/ethereum-white.svg",
|
|
2133
|
+
dark: "https://raw.githubusercontent.com/JoAiHQ/assets/refs/heads/main/chains/logos/ethereum-black.svg"
|
|
2134
|
+
},
|
|
2135
|
+
nativeToken: NativeTokenEth
|
|
2136
|
+
},
|
|
2137
|
+
devnet: {
|
|
2138
|
+
name: WarpChainName13.Ethereum,
|
|
2139
|
+
displayName: "Ethereum Sepolia",
|
|
2140
|
+
chainId: "11155111",
|
|
2141
|
+
blockTime: 12e3,
|
|
2142
|
+
addressHrp: "0x",
|
|
2143
|
+
defaultApiUrl: "https://ethereum-sepolia-rpc.publicnode.com",
|
|
2144
|
+
logoUrl: {
|
|
2145
|
+
light: "https://raw.githubusercontent.com/JoAiHQ/assets/refs/heads/main/chains/logos/ethereum-white.svg",
|
|
2146
|
+
dark: "https://raw.githubusercontent.com/JoAiHQ/assets/refs/heads/main/chains/logos/ethereum-black.svg"
|
|
2147
|
+
},
|
|
2148
|
+
nativeToken: NativeTokenEth
|
|
2149
|
+
}
|
|
2150
|
+
});
|
|
2151
|
+
|
|
2152
|
+
// src/chains/polygon.ts
|
|
2153
|
+
import { WarpChainName as WarpChainName14 } from "@joai/warps";
|
|
2154
|
+
var NativeTokenPolygon = {
|
|
2155
|
+
chain: WarpChainName14.Polygon,
|
|
2156
|
+
identifier: "MATIC",
|
|
2157
|
+
symbol: "MATIC",
|
|
2158
|
+
name: "Polygon",
|
|
2159
|
+
decimals: 18,
|
|
2160
|
+
logoUrl: {
|
|
2161
|
+
light: "https://raw.githubusercontent.com/JoAiHQ/assets/refs/heads/main/tokens/logos/matic-white.svg",
|
|
2162
|
+
dark: "https://raw.githubusercontent.com/JoAiHQ/assets/refs/heads/main/tokens/logos/matic-black.svg"
|
|
2163
|
+
}
|
|
2164
|
+
};
|
|
2165
|
+
var PolygonAdapter = createEvmAdapter(WarpChainName14.Polygon, {
|
|
2166
|
+
mainnet: {
|
|
2167
|
+
name: WarpChainName14.Polygon,
|
|
2168
|
+
displayName: "Polygon",
|
|
2169
|
+
chainId: "137",
|
|
2170
|
+
blockTime: 2e3,
|
|
2171
|
+
addressHrp: "0x",
|
|
2172
|
+
defaultApiUrl: "https://polygon-rpc.com",
|
|
2173
|
+
logoUrl: {
|
|
2174
|
+
light: "https://raw.githubusercontent.com/JoAiHQ/assets/refs/heads/main/chains/logos/polygon-white.svg",
|
|
2175
|
+
dark: "https://raw.githubusercontent.com/JoAiHQ/assets/refs/heads/main/chains/logos/polygon-black.svg"
|
|
2176
|
+
},
|
|
2177
|
+
nativeToken: NativeTokenPolygon
|
|
2178
|
+
},
|
|
2179
|
+
testnet: {
|
|
2180
|
+
name: WarpChainName14.Polygon,
|
|
2181
|
+
displayName: "Polygon Mumbai",
|
|
2182
|
+
chainId: "80001",
|
|
2183
|
+
blockTime: 2e3,
|
|
2184
|
+
addressHrp: "0x",
|
|
2185
|
+
defaultApiUrl: "https://rpc.ankr.com/polygon_mumbai",
|
|
2186
|
+
logoUrl: {
|
|
2187
|
+
light: "https://raw.githubusercontent.com/JoAiHQ/assets/refs/heads/main/chains/logos/polygon-white.svg",
|
|
2188
|
+
dark: "https://raw.githubusercontent.com/JoAiHQ/assets/refs/heads/main/chains/logos/polygon-black.svg"
|
|
2189
|
+
},
|
|
2190
|
+
nativeToken: NativeTokenPolygon
|
|
2191
|
+
},
|
|
2192
|
+
devnet: {
|
|
2193
|
+
name: WarpChainName14.Polygon,
|
|
2194
|
+
displayName: "Polygon Mumbai",
|
|
2195
|
+
chainId: "80001",
|
|
2196
|
+
blockTime: 2e3,
|
|
2197
|
+
addressHrp: "0x",
|
|
2198
|
+
defaultApiUrl: "https://rpc.ankr.com/polygon_mumbai",
|
|
2199
|
+
logoUrl: {
|
|
2200
|
+
light: "https://raw.githubusercontent.com/JoAiHQ/assets/refs/heads/main/chains/logos/polygon-white.svg",
|
|
2201
|
+
dark: "https://raw.githubusercontent.com/JoAiHQ/assets/refs/heads/main/chains/logos/polygon-black.svg"
|
|
2202
|
+
},
|
|
2203
|
+
nativeToken: NativeTokenPolygon
|
|
2204
|
+
}
|
|
2205
|
+
});
|
|
2206
|
+
|
|
2207
|
+
// src/adapters.ts
|
|
2208
|
+
import { withAdapterFallback } from "@joai/warps";
|
|
2209
|
+
|
|
2210
|
+
// src/chains/somnia.ts
|
|
2211
|
+
import { WarpChainName as WarpChainName15 } from "@joai/warps";
|
|
2212
|
+
var NativeTokenSomi = {
|
|
2213
|
+
chain: WarpChainName15.Somnia,
|
|
2214
|
+
identifier: "SOMI",
|
|
2215
|
+
symbol: "SOMI",
|
|
2216
|
+
name: "Somnia",
|
|
2217
|
+
decimals: 18,
|
|
2218
|
+
logoUrl: "https://assets.coingecko.com/coins/images/68061/standard/somniacg.png?1754641117"
|
|
2219
|
+
};
|
|
2220
|
+
var NativeTokenStt = {
|
|
2221
|
+
chain: WarpChainName15.Somnia,
|
|
2222
|
+
identifier: "STT",
|
|
2223
|
+
symbol: "STT",
|
|
2224
|
+
name: "Somnia Testnet Token",
|
|
2225
|
+
decimals: 18,
|
|
2226
|
+
logoUrl: "https://assets.coingecko.com/coins/images/68061/standard/somniacg.png?1754641117"
|
|
2227
|
+
};
|
|
2228
|
+
var SomniaAdapter = createEvmAdapter(WarpChainName15.Somnia, {
|
|
2229
|
+
mainnet: {
|
|
2230
|
+
name: WarpChainName15.Somnia,
|
|
2231
|
+
displayName: "Somnia Mainnet",
|
|
2232
|
+
chainId: "5031",
|
|
2233
|
+
blockTime: 100,
|
|
2234
|
+
addressHrp: "0x",
|
|
2235
|
+
defaultApiUrl: "https://api.infra.mainnet.somnia.network/",
|
|
2236
|
+
logoUrl: "https://raw.githubusercontent.com/JoAiHQ/assets/refs/heads/main/chains/logos/somnia.png",
|
|
2237
|
+
nativeToken: NativeTokenSomi
|
|
2238
|
+
},
|
|
2239
|
+
testnet: {
|
|
2240
|
+
name: WarpChainName15.Somnia,
|
|
2241
|
+
displayName: "Somnia Testnet",
|
|
2242
|
+
chainId: "50312",
|
|
2243
|
+
blockTime: 100,
|
|
2244
|
+
addressHrp: "0x",
|
|
2245
|
+
defaultApiUrl: "https://dream-rpc.somnia.network/",
|
|
2246
|
+
logoUrl: "https://raw.githubusercontent.com/JoAiHQ/assets/refs/heads/main/chains/logos/somnia.png",
|
|
2247
|
+
nativeToken: NativeTokenStt
|
|
2248
|
+
},
|
|
2249
|
+
devnet: {
|
|
2250
|
+
name: WarpChainName15.Somnia,
|
|
2251
|
+
displayName: "Somnia Testnet",
|
|
2252
|
+
chainId: "50312",
|
|
2253
|
+
blockTime: 100,
|
|
2254
|
+
addressHrp: "0x",
|
|
2255
|
+
defaultApiUrl: "https://dream-rpc.somnia.network",
|
|
2256
|
+
logoUrl: "https://raw.githubusercontent.com/JoAiHQ/assets/refs/heads/main/chains/logos/somnia.png",
|
|
2257
|
+
nativeToken: NativeTokenStt
|
|
2258
|
+
}
|
|
2259
|
+
});
|
|
2260
|
+
|
|
2261
|
+
// src/adapters.ts
|
|
2262
|
+
var getAllEvmAdapters = (fallbackFactory) => [
|
|
2263
|
+
withAdapterFallback(EthereumAdapter, fallbackFactory),
|
|
2264
|
+
withAdapterFallback(BaseAdapter, fallbackFactory),
|
|
2265
|
+
withAdapterFallback(ArbitrumAdapter, fallbackFactory),
|
|
2266
|
+
withAdapterFallback(PolygonAdapter, fallbackFactory),
|
|
2267
|
+
withAdapterFallback(SomniaAdapter, fallbackFactory)
|
|
2268
|
+
];
|
|
2269
|
+
export {
|
|
2270
|
+
ArbitrumAdapter,
|
|
2271
|
+
ArbitrumExplorers,
|
|
2272
|
+
BaseAdapter,
|
|
2273
|
+
BaseExplorers,
|
|
2274
|
+
EthereumAdapter,
|
|
2275
|
+
EthereumExplorers,
|
|
2276
|
+
EvmChainIdMap,
|
|
2277
|
+
EvmChainIds,
|
|
2278
|
+
EvmExplorers,
|
|
2279
|
+
ExplorerUrls,
|
|
2280
|
+
KnownTokens,
|
|
2281
|
+
NativeTokenArb,
|
|
2282
|
+
NativeTokenBase,
|
|
2283
|
+
NativeTokenEth,
|
|
2284
|
+
NativeTokenPolygon,
|
|
2285
|
+
PolygonAdapter,
|
|
2286
|
+
PolygonExplorers,
|
|
2287
|
+
SupportedEvmChainIds,
|
|
2288
|
+
WarpEvmConstants,
|
|
2289
|
+
WarpEvmDataLoader,
|
|
2290
|
+
WarpEvmExecutor,
|
|
2291
|
+
WarpEvmExplorer,
|
|
2292
|
+
WarpEvmOutput,
|
|
2293
|
+
WarpEvmSerializer,
|
|
2294
|
+
WarpEvmWallet,
|
|
2295
|
+
createEvmAdapter,
|
|
2296
|
+
findKnownTokenById,
|
|
2297
|
+
getAllEvmAdapters,
|
|
2298
|
+
getAllEvmChainNames,
|
|
2299
|
+
getKnownTokensForChain
|
|
2300
|
+
};
|
|
2301
|
+
//# sourceMappingURL=index.mjs.map
|