@vleap/warps-adapter-evm 0.2.0-alpha.4 → 0.2.0-alpha.41
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.cts +261 -0
- package/dist/index.d.ts +159 -53
- package/dist/index.js +1035 -399
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +1027 -379
- package/dist/index.mjs.map +1 -1
- package/package.json +17 -10
- package/README.md +0 -400
- package/dist/index.d.mts +0 -155
package/dist/index.mjs
CHANGED
|
@@ -1,3 +1,470 @@
|
|
|
1
|
+
// src/chains/arbitrum.ts
|
|
2
|
+
import { WarpChainName as WarpChainName6 } from "@vleap/warps";
|
|
3
|
+
|
|
4
|
+
// src/WarpEvmDataLoader.ts
|
|
5
|
+
import {
|
|
6
|
+
CacheTtl as CacheTtl2,
|
|
7
|
+
getProviderConfig,
|
|
8
|
+
WarpCache as WarpCache2,
|
|
9
|
+
WarpCacheKey
|
|
10
|
+
} from "@vleap/warps";
|
|
11
|
+
import { ethers } from "ethers";
|
|
12
|
+
|
|
13
|
+
// src/providers/UniswapService.ts
|
|
14
|
+
import { CacheTtl } from "@vleap/warps";
|
|
15
|
+
var _UniswapService = class _UniswapService {
|
|
16
|
+
constructor(cache, chainId) {
|
|
17
|
+
this.cache = cache;
|
|
18
|
+
this.chainId = chainId;
|
|
19
|
+
}
|
|
20
|
+
async getTokenList() {
|
|
21
|
+
try {
|
|
22
|
+
const response = await fetch(_UniswapService.UNISWAP_TOKEN_LIST_URL);
|
|
23
|
+
if (!response.ok) {
|
|
24
|
+
throw new Error(`Failed to fetch Uniswap token list: ${response.status}`);
|
|
25
|
+
}
|
|
26
|
+
const tokenList = await response.json();
|
|
27
|
+
return tokenList;
|
|
28
|
+
} catch (error) {
|
|
29
|
+
throw new Error(`Failed to fetch Uniswap token list: ${error}`);
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
async findToken(address) {
|
|
33
|
+
const normalizedAddress = address.toLowerCase();
|
|
34
|
+
const cacheKey = `uniswap:token:${this.chainId}:${normalizedAddress}`;
|
|
35
|
+
const cachedToken = this.cache.get(cacheKey);
|
|
36
|
+
if (cachedToken) {
|
|
37
|
+
return cachedToken;
|
|
38
|
+
}
|
|
39
|
+
try {
|
|
40
|
+
const tokenList = await this.getTokenList();
|
|
41
|
+
const token = tokenList.tokens.find((token2) => token2.address.toLowerCase() === normalizedAddress) || null;
|
|
42
|
+
if (token && token.chainId !== this.chainId) {
|
|
43
|
+
return null;
|
|
44
|
+
}
|
|
45
|
+
if (token) {
|
|
46
|
+
this.cache.set(cacheKey, token, CacheTtl.OneHour);
|
|
47
|
+
} else {
|
|
48
|
+
this.cache.set(cacheKey, null, CacheTtl.OneMinute * 5);
|
|
49
|
+
}
|
|
50
|
+
return token;
|
|
51
|
+
} catch (error) {
|
|
52
|
+
return null;
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
async getTokenMetadata(address) {
|
|
56
|
+
const normalizedAddress = address.toLowerCase();
|
|
57
|
+
const cacheKey = `uniswap:metadata:${this.chainId}:${normalizedAddress}`;
|
|
58
|
+
const cachedMetadata = this.cache.get(cacheKey);
|
|
59
|
+
if (cachedMetadata !== null) {
|
|
60
|
+
return cachedMetadata;
|
|
61
|
+
}
|
|
62
|
+
const token = await this.findToken(address);
|
|
63
|
+
if (!token) {
|
|
64
|
+
this.cache.set(cacheKey, null, CacheTtl.OneMinute * 5);
|
|
65
|
+
return null;
|
|
66
|
+
}
|
|
67
|
+
const metadata = {
|
|
68
|
+
name: token.name,
|
|
69
|
+
symbol: token.symbol,
|
|
70
|
+
decimals: token.decimals,
|
|
71
|
+
logoUrl: token.logoURI
|
|
72
|
+
};
|
|
73
|
+
this.cache.set(cacheKey, metadata, CacheTtl.OneHour);
|
|
74
|
+
return metadata;
|
|
75
|
+
}
|
|
76
|
+
async getBridgeInfo(address) {
|
|
77
|
+
const normalizedAddress = address.toLowerCase();
|
|
78
|
+
const cacheKey = `uniswap:bridge:${this.chainId}:${normalizedAddress}`;
|
|
79
|
+
const cachedBridgeInfo = this.cache.get(cacheKey);
|
|
80
|
+
if (cachedBridgeInfo !== null) {
|
|
81
|
+
return cachedBridgeInfo;
|
|
82
|
+
}
|
|
83
|
+
const token = await this.findToken(address);
|
|
84
|
+
if (!token?.extensions?.bridgeInfo) {
|
|
85
|
+
this.cache.set(cacheKey, null, CacheTtl.OneMinute * 5);
|
|
86
|
+
return null;
|
|
87
|
+
}
|
|
88
|
+
const bridgeInfo = {};
|
|
89
|
+
for (const [chainId, info] of Object.entries(token.extensions.bridgeInfo)) {
|
|
90
|
+
bridgeInfo[chainId] = info.tokenAddress;
|
|
91
|
+
}
|
|
92
|
+
this.cache.set(cacheKey, bridgeInfo, CacheTtl.OneHour);
|
|
93
|
+
return bridgeInfo;
|
|
94
|
+
}
|
|
95
|
+
};
|
|
96
|
+
_UniswapService.UNISWAP_TOKEN_LIST_URL = "https://tokens.uniswap.org";
|
|
97
|
+
var UniswapService = _UniswapService;
|
|
98
|
+
|
|
99
|
+
// src/tokens/arbitrum.ts
|
|
100
|
+
import { WarpChainName } from "@vleap/warps";
|
|
101
|
+
var ArbitrumChain = WarpChainName.Arbitrum;
|
|
102
|
+
var ArbitrumTokens = [
|
|
103
|
+
{
|
|
104
|
+
chain: ArbitrumChain,
|
|
105
|
+
identifier: "0xFF970A61A04b1cA14834A43f5dE4533eBDDB5CC8",
|
|
106
|
+
name: "USD Coin",
|
|
107
|
+
symbol: "USDC",
|
|
108
|
+
decimals: 6,
|
|
109
|
+
logoUrl: "https://assets.coingecko.com/coins/images/6319/small/USD_Coin_icon.png"
|
|
110
|
+
},
|
|
111
|
+
{
|
|
112
|
+
chain: ArbitrumChain,
|
|
113
|
+
identifier: "0xFd086bC7CD5C481DCC9C85ebE478A1C0b69FCbb9",
|
|
114
|
+
name: "Tether USD",
|
|
115
|
+
symbol: "USDT",
|
|
116
|
+
decimals: 6,
|
|
117
|
+
logoUrl: "https://assets.coingecko.com/coins/images/325/small/Tether.png"
|
|
118
|
+
},
|
|
119
|
+
{
|
|
120
|
+
chain: ArbitrumChain,
|
|
121
|
+
identifier: "0x82aF49447D8a07e3bd95BD0d56f35241523fBab1",
|
|
122
|
+
name: "Wrapped Ether",
|
|
123
|
+
symbol: "WETH",
|
|
124
|
+
decimals: 18,
|
|
125
|
+
logoUrl: "https://assets.coingecko.com/coins/images/2518/small/weth.png"
|
|
126
|
+
}
|
|
127
|
+
];
|
|
128
|
+
|
|
129
|
+
// src/tokens/base.ts
|
|
130
|
+
import { WarpChainName as WarpChainName2 } from "@vleap/warps";
|
|
131
|
+
var BaseChain = WarpChainName2.Base;
|
|
132
|
+
var BaseTokens = [
|
|
133
|
+
{
|
|
134
|
+
chain: BaseChain,
|
|
135
|
+
identifier: "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913",
|
|
136
|
+
name: "USD Coin",
|
|
137
|
+
symbol: "USDC",
|
|
138
|
+
decimals: 6,
|
|
139
|
+
logoUrl: "https://assets.coingecko.com/coins/images/6319/small/USD_Coin_icon.png"
|
|
140
|
+
},
|
|
141
|
+
{
|
|
142
|
+
chain: BaseChain,
|
|
143
|
+
identifier: "0x4200000000000000000000000000000000000006",
|
|
144
|
+
name: "Wrapped Ether",
|
|
145
|
+
symbol: "WETH",
|
|
146
|
+
decimals: 18,
|
|
147
|
+
logoUrl: "https://assets.coingecko.com/coins/images/2518/small/weth.png"
|
|
148
|
+
},
|
|
149
|
+
{
|
|
150
|
+
chain: BaseChain,
|
|
151
|
+
identifier: "0x808456652fdb597867f38412077A9182bf77359F",
|
|
152
|
+
name: "Euro",
|
|
153
|
+
symbol: "EURC",
|
|
154
|
+
decimals: 6,
|
|
155
|
+
logoUrl: "https://assets.coingecko.com/coins/images/26045/standard/euro.png"
|
|
156
|
+
},
|
|
157
|
+
{
|
|
158
|
+
chain: BaseChain,
|
|
159
|
+
identifier: "0xcbB7C0006F23900c38EB856149F799620fcb8A4a",
|
|
160
|
+
name: "Coinbase Wrapped BTC",
|
|
161
|
+
symbol: "CBETH",
|
|
162
|
+
decimals: 8,
|
|
163
|
+
logoUrl: "https://assets.coingecko.com/coins/images/7598/small/wrapped_bitcoin_wbtc.png"
|
|
164
|
+
}
|
|
165
|
+
];
|
|
166
|
+
|
|
167
|
+
// src/tokens/base-sepolia.ts
|
|
168
|
+
import { WarpChainName as WarpChainName3 } from "@vleap/warps";
|
|
169
|
+
var BaseChain2 = WarpChainName3.Base;
|
|
170
|
+
var BaseSepoliaTokens = [
|
|
171
|
+
{
|
|
172
|
+
chain: BaseChain2,
|
|
173
|
+
identifier: "0x036CbD53842c5426634e7929541eC2318f3dCF7e",
|
|
174
|
+
name: "USD",
|
|
175
|
+
symbol: "USDC",
|
|
176
|
+
decimals: 6,
|
|
177
|
+
logoUrl: "https://assets.coingecko.com/coins/images/6319/small/USD_Coin_icon.png"
|
|
178
|
+
},
|
|
179
|
+
{
|
|
180
|
+
chain: BaseChain2,
|
|
181
|
+
identifier: "0x808456652fdb597867f38412077A9182bf77359F",
|
|
182
|
+
name: "Euro",
|
|
183
|
+
symbol: "EURC",
|
|
184
|
+
decimals: 6,
|
|
185
|
+
logoUrl: "https://assets.coingecko.com/coins/images/26045/thumb/euro-coin.png?1655394420"
|
|
186
|
+
},
|
|
187
|
+
{
|
|
188
|
+
chain: BaseChain2,
|
|
189
|
+
identifier: "0xcbB7C0006F23900c38EB856149F799620fcb8A4a",
|
|
190
|
+
name: "Wrapped Bitcoin",
|
|
191
|
+
symbol: "WBTC",
|
|
192
|
+
decimals: 8,
|
|
193
|
+
logoUrl: "https://assets.coingecko.com/coins/images/7598/small/wrapped_bitcoin_wbtc.png"
|
|
194
|
+
}
|
|
195
|
+
];
|
|
196
|
+
|
|
197
|
+
// src/tokens/ethereum.ts
|
|
198
|
+
import { WarpChainName as WarpChainName4 } from "@vleap/warps";
|
|
199
|
+
var EthereumChain = WarpChainName4.Ethereum;
|
|
200
|
+
var EthereumTokens = [
|
|
201
|
+
{
|
|
202
|
+
chain: EthereumChain,
|
|
203
|
+
identifier: "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48",
|
|
204
|
+
name: "USD Coin",
|
|
205
|
+
symbol: "USDC",
|
|
206
|
+
decimals: 6,
|
|
207
|
+
logoUrl: "https://assets.coingecko.com/coins/images/6319/small/USD_Coin_icon.png"
|
|
208
|
+
},
|
|
209
|
+
{
|
|
210
|
+
chain: EthereumChain,
|
|
211
|
+
identifier: "0xdAC17F958D2ee523a2206206994597C13D831ec7",
|
|
212
|
+
name: "Tether USD",
|
|
213
|
+
symbol: "USDT",
|
|
214
|
+
decimals: 6,
|
|
215
|
+
logoUrl: "https://assets.coingecko.com/coins/images/325/small/Tether.png"
|
|
216
|
+
},
|
|
217
|
+
{
|
|
218
|
+
chain: EthereumChain,
|
|
219
|
+
identifier: "0x2260FAC5E5542a773Aa44fBCfeDf7C193bc2C599",
|
|
220
|
+
name: "Wrapped Bitcoin",
|
|
221
|
+
symbol: "WBTC",
|
|
222
|
+
decimals: 8,
|
|
223
|
+
logoUrl: "https://assets.coingecko.com/coins/images/7598/small/wrapped_bitcoin_wbtc.png"
|
|
224
|
+
},
|
|
225
|
+
{
|
|
226
|
+
chain: EthereumChain,
|
|
227
|
+
identifier: "0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2",
|
|
228
|
+
name: "Wrapped Ether",
|
|
229
|
+
symbol: "WETH",
|
|
230
|
+
decimals: 18,
|
|
231
|
+
logoUrl: "https://assets.coingecko.com/coins/images/2518/small/weth.png"
|
|
232
|
+
},
|
|
233
|
+
{
|
|
234
|
+
chain: EthereumChain,
|
|
235
|
+
identifier: "0x6B175474E89094C44Da98b954EedeAC495271d0F",
|
|
236
|
+
name: "Dai Stablecoin",
|
|
237
|
+
symbol: "DAI",
|
|
238
|
+
decimals: 18,
|
|
239
|
+
logoUrl: "https://assets.coingecko.com/coins/images/9956/small/4943.png"
|
|
240
|
+
}
|
|
241
|
+
];
|
|
242
|
+
|
|
243
|
+
// src/tokens/ethereum-sepolia.ts
|
|
244
|
+
import { WarpChainName as WarpChainName5 } from "@vleap/warps";
|
|
245
|
+
var EthereumChain2 = WarpChainName5.Ethereum;
|
|
246
|
+
var EthereumSepoliaTokens = [
|
|
247
|
+
{
|
|
248
|
+
chain: EthereumChain2,
|
|
249
|
+
identifier: "0x1c7D4B196Cb0C7B01d743Fbc6116a902379C7238",
|
|
250
|
+
name: "USD Coin",
|
|
251
|
+
symbol: "USDC",
|
|
252
|
+
decimals: 6,
|
|
253
|
+
logoUrl: "https://assets.coingecko.com/coins/images/6319/small/USD_Coin_icon.png"
|
|
254
|
+
},
|
|
255
|
+
{
|
|
256
|
+
chain: EthereumChain2,
|
|
257
|
+
identifier: "0x7169D38820dfd117C3FA1f22a697dBA58d90BA06",
|
|
258
|
+
name: "Tether USD",
|
|
259
|
+
symbol: "USDT",
|
|
260
|
+
decimals: 6,
|
|
261
|
+
logoUrl: "https://assets.coingecko.com/coins/images/325/small/Tether.png"
|
|
262
|
+
},
|
|
263
|
+
{
|
|
264
|
+
chain: EthereumChain2,
|
|
265
|
+
identifier: "0x7b79995e5f793A07Bc00c21412e50Ecae098E7f9",
|
|
266
|
+
name: "Wrapped Ether",
|
|
267
|
+
symbol: "WETH",
|
|
268
|
+
decimals: 18,
|
|
269
|
+
logoUrl: "https://assets.coingecko.com/coins/images/2518/small/weth.png"
|
|
270
|
+
}
|
|
271
|
+
];
|
|
272
|
+
|
|
273
|
+
// src/tokens.ts
|
|
274
|
+
var KnownTokens = {
|
|
275
|
+
ethereum: {
|
|
276
|
+
mainnet: EthereumTokens,
|
|
277
|
+
testnet: EthereumSepoliaTokens,
|
|
278
|
+
devnet: EthereumSepoliaTokens
|
|
279
|
+
},
|
|
280
|
+
base: {
|
|
281
|
+
mainnet: BaseTokens,
|
|
282
|
+
testnet: BaseSepoliaTokens,
|
|
283
|
+
devnet: BaseSepoliaTokens
|
|
284
|
+
},
|
|
285
|
+
arbitrum: {
|
|
286
|
+
mainnet: ArbitrumTokens
|
|
287
|
+
}
|
|
288
|
+
};
|
|
289
|
+
var findKnownTokenById = (chain, env, id) => {
|
|
290
|
+
const chainTokens = KnownTokens[chain]?.[env] || [];
|
|
291
|
+
return chainTokens.find((token) => token.identifier === id) || null;
|
|
292
|
+
};
|
|
293
|
+
var getKnownTokensForChain = (chainName, env = "mainnet") => {
|
|
294
|
+
return KnownTokens[chainName]?.[env] || [];
|
|
295
|
+
};
|
|
296
|
+
|
|
297
|
+
// src/WarpEvmDataLoader.ts
|
|
298
|
+
var ERC20_ABI = [
|
|
299
|
+
"function balanceOf(address owner) view returns (uint256)",
|
|
300
|
+
"function decimals() view returns (uint8)",
|
|
301
|
+
"function name() view returns (string)",
|
|
302
|
+
"function symbol() view returns (string)",
|
|
303
|
+
"function totalSupply() view returns (uint256)"
|
|
304
|
+
];
|
|
305
|
+
var WarpEvmDataLoader = class {
|
|
306
|
+
constructor(config, chain) {
|
|
307
|
+
this.config = config;
|
|
308
|
+
this.chain = chain;
|
|
309
|
+
const providerConfig = getProviderConfig(this.config, this.chain.name, this.config.env, this.chain.defaultApiUrl);
|
|
310
|
+
const network = new ethers.Network(this.chain.name, parseInt(this.chain.chainId));
|
|
311
|
+
this.provider = new ethers.JsonRpcProvider(providerConfig.url, network);
|
|
312
|
+
this.cache = new WarpCache2(config.cache?.type);
|
|
313
|
+
this.uniswapService = new UniswapService(this.cache, parseInt(this.chain.chainId));
|
|
314
|
+
}
|
|
315
|
+
async getAccount(address) {
|
|
316
|
+
const balance = await this.provider.getBalance(address);
|
|
317
|
+
return {
|
|
318
|
+
chain: this.chain.name,
|
|
319
|
+
address,
|
|
320
|
+
balance
|
|
321
|
+
};
|
|
322
|
+
}
|
|
323
|
+
async getAccountAssets(address) {
|
|
324
|
+
const account = await this.getAccount(address);
|
|
325
|
+
const tokenBalances = await this.getERC20TokenBalances(address);
|
|
326
|
+
let assets = account.balance > 0 ? [{ ...this.chain.nativeToken, amount: account.balance }] : [];
|
|
327
|
+
for (const tokenBalance of tokenBalances) {
|
|
328
|
+
if (tokenBalance.balance > 0n) {
|
|
329
|
+
assets.push({
|
|
330
|
+
chain: this.chain.name,
|
|
331
|
+
identifier: tokenBalance.tokenAddress,
|
|
332
|
+
name: tokenBalance.name,
|
|
333
|
+
symbol: tokenBalance.symbol,
|
|
334
|
+
amount: tokenBalance.balance,
|
|
335
|
+
decimals: tokenBalance.decimals,
|
|
336
|
+
logoUrl: tokenBalance.logoUrl || ""
|
|
337
|
+
});
|
|
338
|
+
}
|
|
339
|
+
}
|
|
340
|
+
return assets;
|
|
341
|
+
}
|
|
342
|
+
async getAsset(identifier) {
|
|
343
|
+
try {
|
|
344
|
+
if (identifier === this.chain.nativeToken.identifier) {
|
|
345
|
+
return this.chain.nativeToken;
|
|
346
|
+
}
|
|
347
|
+
const cacheKey = WarpCacheKey.Asset(this.config.env, this.chain.name, identifier);
|
|
348
|
+
const cachedAsset = this.cache.get(cacheKey);
|
|
349
|
+
if (cachedAsset) {
|
|
350
|
+
return cachedAsset;
|
|
351
|
+
}
|
|
352
|
+
const knownToken = findKnownTokenById(this.chain.name, this.config.env, identifier);
|
|
353
|
+
if (knownToken) {
|
|
354
|
+
return {
|
|
355
|
+
chain: this.chain.name,
|
|
356
|
+
identifier,
|
|
357
|
+
name: knownToken.name,
|
|
358
|
+
symbol: knownToken.symbol,
|
|
359
|
+
amount: 0n,
|
|
360
|
+
decimals: knownToken.decimals,
|
|
361
|
+
logoUrl: knownToken.logoUrl
|
|
362
|
+
};
|
|
363
|
+
}
|
|
364
|
+
const metadata = await this.getTokenMetadata(identifier);
|
|
365
|
+
const asset = {
|
|
366
|
+
chain: this.chain.name,
|
|
367
|
+
identifier,
|
|
368
|
+
name: metadata.name,
|
|
369
|
+
symbol: metadata.symbol,
|
|
370
|
+
amount: 0n,
|
|
371
|
+
decimals: metadata.decimals,
|
|
372
|
+
logoUrl: metadata.logoUrl || ""
|
|
373
|
+
};
|
|
374
|
+
this.cache.set(cacheKey, asset, CacheTtl2.OneHour);
|
|
375
|
+
return asset;
|
|
376
|
+
} catch (error) {
|
|
377
|
+
return null;
|
|
378
|
+
}
|
|
379
|
+
}
|
|
380
|
+
async getAction(identifier, awaitCompleted = false) {
|
|
381
|
+
try {
|
|
382
|
+
const tx = await this.provider.getTransaction(identifier);
|
|
383
|
+
if (!tx) return null;
|
|
384
|
+
let receipt = await this.provider.getTransactionReceipt(identifier);
|
|
385
|
+
if (awaitCompleted && !receipt) {
|
|
386
|
+
receipt = await tx.wait();
|
|
387
|
+
}
|
|
388
|
+
const block = await this.provider.getBlock(tx.blockNumber || "latest");
|
|
389
|
+
return {
|
|
390
|
+
chain: this.chain.name,
|
|
391
|
+
id: tx.hash || identifier,
|
|
392
|
+
receiver: tx.to || "",
|
|
393
|
+
sender: tx.from,
|
|
394
|
+
value: tx.value,
|
|
395
|
+
function: tx.data && tx.data !== "0x" ? "contract_call" : "",
|
|
396
|
+
status: receipt?.status === 1 ? "success" : receipt?.status === 0 ? "failed" : "pending",
|
|
397
|
+
createdAt: block?.timestamp ? new Date(Number(block.timestamp) * 1e3).toISOString() : (/* @__PURE__ */ new Date()).toISOString(),
|
|
398
|
+
error: receipt?.status === 0 ? "Transaction failed" : null,
|
|
399
|
+
tx: {
|
|
400
|
+
hash: tx.hash || "",
|
|
401
|
+
from: tx.from,
|
|
402
|
+
to: tx.to || "",
|
|
403
|
+
value: tx.value.toString(),
|
|
404
|
+
data: tx.data || "0x",
|
|
405
|
+
gasLimit: tx.gasLimit?.toString() || "0",
|
|
406
|
+
gasPrice: tx.gasPrice?.toString() || "0",
|
|
407
|
+
blockNumber: tx.blockNumber || 0,
|
|
408
|
+
blockHash: tx.blockHash || "",
|
|
409
|
+
transactionIndex: tx.index || 0
|
|
410
|
+
}
|
|
411
|
+
};
|
|
412
|
+
} catch (error) {
|
|
413
|
+
return null;
|
|
414
|
+
}
|
|
415
|
+
}
|
|
416
|
+
async getAccountActions(address, options) {
|
|
417
|
+
return [];
|
|
418
|
+
}
|
|
419
|
+
async getERC20TokenBalances(address) {
|
|
420
|
+
const env = this.config.env === "mainnet" ? "mainnet" : "testnet";
|
|
421
|
+
const tokens = getKnownTokensForChain(this.chain.name, env);
|
|
422
|
+
const balanceReqs = tokens.map((token) => this.getTokenBalance(address, token.identifier).catch(() => 0n));
|
|
423
|
+
const balances = await Promise.all(balanceReqs);
|
|
424
|
+
return balances.map((balance, index) => ({ balance, token: tokens[index] })).filter(({ balance }) => balance > 0n).map(({ balance, token }) => ({
|
|
425
|
+
tokenAddress: token.identifier,
|
|
426
|
+
balance,
|
|
427
|
+
name: token.name,
|
|
428
|
+
symbol: token.symbol,
|
|
429
|
+
decimals: token.decimals || 18,
|
|
430
|
+
logoUrl: token.logoUrl || ""
|
|
431
|
+
}));
|
|
432
|
+
}
|
|
433
|
+
async getTokenBalance(address, tokenAddress) {
|
|
434
|
+
const contract = new ethers.Contract(tokenAddress, ERC20_ABI, this.provider);
|
|
435
|
+
const balance = await contract.balanceOf(address);
|
|
436
|
+
return balance;
|
|
437
|
+
}
|
|
438
|
+
async getTokenMetadata(tokenAddress) {
|
|
439
|
+
const uniswapMetadata = await this.uniswapService.getTokenMetadata(tokenAddress);
|
|
440
|
+
if (uniswapMetadata) {
|
|
441
|
+
return uniswapMetadata;
|
|
442
|
+
}
|
|
443
|
+
const contract = new ethers.Contract(tokenAddress, ERC20_ABI, this.provider);
|
|
444
|
+
const [name, symbol, decimals] = await Promise.all([
|
|
445
|
+
contract.name().catch(() => "Unknown Token"),
|
|
446
|
+
contract.symbol().catch(() => "UNKNOWN"),
|
|
447
|
+
contract.decimals().catch(() => 18)
|
|
448
|
+
]);
|
|
449
|
+
return {
|
|
450
|
+
name: name || "Unknown Token",
|
|
451
|
+
symbol: symbol || "UNKNOWN",
|
|
452
|
+
decimals: decimals || 18,
|
|
453
|
+
logoUrl: ""
|
|
454
|
+
};
|
|
455
|
+
}
|
|
456
|
+
};
|
|
457
|
+
|
|
458
|
+
// src/WarpEvmExecutor.ts
|
|
459
|
+
import {
|
|
460
|
+
applyResultsToMessages,
|
|
461
|
+
getNextInfo,
|
|
462
|
+
getProviderConfig as getProviderConfig3,
|
|
463
|
+
getWarpActionByIndex,
|
|
464
|
+
getWarpWalletAddressFromConfig as getWarpWalletAddressFromConfig2
|
|
465
|
+
} from "@vleap/warps";
|
|
466
|
+
import { ethers as ethers4 } from "ethers";
|
|
467
|
+
|
|
1
468
|
// src/constants.ts
|
|
2
469
|
var WarpEvmConstants = {
|
|
3
470
|
GasLimit: {
|
|
@@ -5,6 +472,8 @@ var WarpEvmConstants = {
|
|
|
5
472
|
ContractCall: 1e5,
|
|
6
473
|
ContractDeploy: 5e5,
|
|
7
474
|
Transfer: 21e3,
|
|
475
|
+
TokenTransfer: 65e3,
|
|
476
|
+
// ERC-20 transfer gas limit
|
|
8
477
|
Approve: 46e3,
|
|
9
478
|
Swap: 2e5
|
|
10
479
|
},
|
|
@@ -38,25 +507,21 @@ var BaseExplorers = /* @__PURE__ */ ((BaseExplorers2) => {
|
|
|
38
507
|
BaseExplorers2["BlockscoutBaseSepolia"] = "blockscout_base_sepolia";
|
|
39
508
|
return BaseExplorers2;
|
|
40
509
|
})(BaseExplorers || {});
|
|
41
|
-
var LocalExplorers = /* @__PURE__ */ ((LocalExplorers2) => {
|
|
42
|
-
LocalExplorers2["LocalBlockscout"] = "local_blockscout";
|
|
43
|
-
return LocalExplorers2;
|
|
44
|
-
})(LocalExplorers || {});
|
|
45
510
|
var EvmExplorers = {
|
|
46
511
|
ethereum: {
|
|
47
512
|
mainnet: ["etherscan" /* Etherscan */, "ethplorer" /* Ethplorer */, "blockscout" /* Blockscout */],
|
|
48
513
|
testnet: ["etherscan_sepolia" /* EtherscanSepolia */, "blockscout_sepolia" /* BlockscoutSepolia */],
|
|
49
|
-
devnet: ["
|
|
514
|
+
devnet: ["etherscan_sepolia" /* EtherscanSepolia */, "blockscout_sepolia" /* BlockscoutSepolia */]
|
|
50
515
|
},
|
|
51
516
|
arbitrum: {
|
|
52
517
|
mainnet: ["arbiscan" /* Arbiscan */, "blockscout_arbitrum" /* BlockscoutArbitrum */],
|
|
53
518
|
testnet: ["arbiscan_sepolia" /* ArbiscanSepolia */, "blockscout_arbitrum_sepolia" /* BlockscoutArbitrumSepolia */],
|
|
54
|
-
devnet: ["
|
|
519
|
+
devnet: ["arbiscan_sepolia" /* ArbiscanSepolia */, "blockscout_arbitrum_sepolia" /* BlockscoutArbitrumSepolia */]
|
|
55
520
|
},
|
|
56
521
|
base: {
|
|
57
522
|
mainnet: ["basescan" /* Basescan */, "blockscout_base" /* BlockscoutBase */],
|
|
58
523
|
testnet: ["basescan_sepolia" /* BasescanSepolia */, "blockscout_base_sepolia" /* BlockscoutBaseSepolia */],
|
|
59
|
-
devnet: ["
|
|
524
|
+
devnet: ["basescan_sepolia" /* BasescanSepolia */, "blockscout_base_sepolia" /* BlockscoutBaseSepolia */]
|
|
60
525
|
}
|
|
61
526
|
};
|
|
62
527
|
var ExplorerUrls = {
|
|
@@ -72,246 +537,18 @@ var ExplorerUrls = {
|
|
|
72
537
|
["basescan" /* Basescan */]: "https://basescan.org",
|
|
73
538
|
["basescan_sepolia" /* BasescanSepolia */]: "https://sepolia.basescan.org",
|
|
74
539
|
["blockscout_base" /* BlockscoutBase */]: "https://base.blockscout.com",
|
|
75
|
-
["blockscout_base_sepolia" /* BlockscoutBaseSepolia */]: "https://sepolia.blockscout.com"
|
|
76
|
-
["local_blockscout" /* LocalBlockscout */]: "http://localhost:4000"
|
|
77
|
-
};
|
|
78
|
-
|
|
79
|
-
// src/config.ts
|
|
80
|
-
var EVM_CHAIN_CONFIGS = {
|
|
81
|
-
ethereum: {
|
|
82
|
-
mainnet: {
|
|
83
|
-
apiUrl: "https://eth-mainnet.g.alchemy.com/v2/demo",
|
|
84
|
-
explorerUrl: "https://etherscan.io",
|
|
85
|
-
chainId: "1",
|
|
86
|
-
registryAddress: "0x0000000000000000000000000000000000000000",
|
|
87
|
-
nativeToken: "ETH",
|
|
88
|
-
blockTime: 12
|
|
89
|
-
},
|
|
90
|
-
testnet: {
|
|
91
|
-
apiUrl: "https://eth-sepolia.g.alchemy.com/v2/demo",
|
|
92
|
-
explorerUrl: "https://sepolia.etherscan.io",
|
|
93
|
-
chainId: "11155111",
|
|
94
|
-
registryAddress: "0x0000000000000000000000000000000000000000",
|
|
95
|
-
nativeToken: "ETH",
|
|
96
|
-
blockTime: 12
|
|
97
|
-
},
|
|
98
|
-
devnet: {
|
|
99
|
-
apiUrl: "http://localhost:8545",
|
|
100
|
-
explorerUrl: "http://localhost:4000",
|
|
101
|
-
chainId: "1337",
|
|
102
|
-
registryAddress: "0x0000000000000000000000000000000000000000",
|
|
103
|
-
nativeToken: "ETH",
|
|
104
|
-
blockTime: 12
|
|
105
|
-
}
|
|
106
|
-
},
|
|
107
|
-
arbitrum: {
|
|
108
|
-
mainnet: {
|
|
109
|
-
apiUrl: "https://arb-mainnet.g.alchemy.com/v2/demo",
|
|
110
|
-
explorerUrl: "https://arbiscan.io",
|
|
111
|
-
chainId: "42161",
|
|
112
|
-
registryAddress: "0x0000000000000000000000000000000000000000",
|
|
113
|
-
nativeToken: "ETH",
|
|
114
|
-
blockTime: 1
|
|
115
|
-
},
|
|
116
|
-
testnet: {
|
|
117
|
-
apiUrl: "https://arb-sepolia.g.alchemy.com/v2/demo",
|
|
118
|
-
explorerUrl: "https://sepolia.arbiscan.io",
|
|
119
|
-
chainId: "421614",
|
|
120
|
-
registryAddress: "0x0000000000000000000000000000000000000000",
|
|
121
|
-
nativeToken: "ETH",
|
|
122
|
-
blockTime: 1
|
|
123
|
-
},
|
|
124
|
-
devnet: {
|
|
125
|
-
apiUrl: "http://localhost:8545",
|
|
126
|
-
explorerUrl: "http://localhost:4000",
|
|
127
|
-
chainId: "1337",
|
|
128
|
-
registryAddress: "0x0000000000000000000000000000000000000000",
|
|
129
|
-
nativeToken: "ETH",
|
|
130
|
-
blockTime: 1
|
|
131
|
-
}
|
|
132
|
-
},
|
|
133
|
-
base: {
|
|
134
|
-
mainnet: {
|
|
135
|
-
apiUrl: "https://mainnet.base.org",
|
|
136
|
-
explorerUrl: "https://basescan.org",
|
|
137
|
-
chainId: "8453",
|
|
138
|
-
registryAddress: "0x0000000000000000000000000000000000000000",
|
|
139
|
-
nativeToken: "ETH",
|
|
140
|
-
blockTime: 2
|
|
141
|
-
},
|
|
142
|
-
testnet: {
|
|
143
|
-
apiUrl: "https://sepolia.base.org",
|
|
144
|
-
explorerUrl: "https://sepolia.basescan.org",
|
|
145
|
-
chainId: "84532",
|
|
146
|
-
registryAddress: "0x0000000000000000000000000000000000000000",
|
|
147
|
-
nativeToken: "ETH",
|
|
148
|
-
blockTime: 2
|
|
149
|
-
},
|
|
150
|
-
devnet: {
|
|
151
|
-
apiUrl: "http://localhost:8545",
|
|
152
|
-
explorerUrl: "http://localhost:4000",
|
|
153
|
-
chainId: "1337",
|
|
154
|
-
registryAddress: "0x0000000000000000000000000000000000000000",
|
|
155
|
-
nativeToken: "ETH",
|
|
156
|
-
blockTime: 2
|
|
157
|
-
}
|
|
158
|
-
}
|
|
159
|
-
};
|
|
160
|
-
var DEFAULT_CHAIN = "ethereum";
|
|
161
|
-
var getEvmChainConfig = (chain = DEFAULT_CHAIN, env) => {
|
|
162
|
-
const chainConfigs = EVM_CHAIN_CONFIGS[chain];
|
|
163
|
-
if (!chainConfigs) {
|
|
164
|
-
throw new Error(`Unsupported EVM chain: ${chain}`);
|
|
165
|
-
}
|
|
166
|
-
const config = chainConfigs[env];
|
|
167
|
-
if (!config) {
|
|
168
|
-
throw new Error(`Unsupported environment ${env} for chain ${chain}`);
|
|
169
|
-
}
|
|
170
|
-
return config;
|
|
171
|
-
};
|
|
172
|
-
var getEvmApiUrl = (env, chain = DEFAULT_CHAIN) => {
|
|
173
|
-
return getEvmChainConfig(chain, env).apiUrl;
|
|
174
|
-
};
|
|
175
|
-
var getEvmExplorerUrl = (env, chain = DEFAULT_CHAIN) => {
|
|
176
|
-
return getEvmChainConfig(chain, env).explorerUrl;
|
|
177
|
-
};
|
|
178
|
-
var getEvmExplorers = (chain = DEFAULT_CHAIN, env) => {
|
|
179
|
-
const chainExplorers = EvmExplorers[chain];
|
|
180
|
-
if (!chainExplorers) {
|
|
181
|
-
throw new Error(`Unsupported EVM chain: ${chain}`);
|
|
182
|
-
}
|
|
183
|
-
const explorers = chainExplorers[env];
|
|
184
|
-
if (!explorers) {
|
|
185
|
-
throw new Error(`Unsupported environment ${env} for chain ${chain}`);
|
|
186
|
-
}
|
|
187
|
-
return explorers;
|
|
188
|
-
};
|
|
189
|
-
var getPrimaryEvmExplorer = (chain = DEFAULT_CHAIN, env) => {
|
|
190
|
-
const explorers = getEvmExplorers(chain, env);
|
|
191
|
-
return explorers[0];
|
|
192
|
-
};
|
|
193
|
-
var getEvmExplorerUrlByName = (explorerName) => {
|
|
194
|
-
const url = ExplorerUrls[explorerName];
|
|
195
|
-
if (!url) {
|
|
196
|
-
throw new Error(`Unsupported explorer: ${explorerName}`);
|
|
197
|
-
}
|
|
198
|
-
return url;
|
|
199
|
-
};
|
|
200
|
-
var getEvmExplorerByName = (chain = DEFAULT_CHAIN, env, name) => {
|
|
201
|
-
const explorers = getEvmExplorers(chain, env);
|
|
202
|
-
return explorers.find((explorer) => explorer.toLowerCase() === name.toLowerCase());
|
|
203
|
-
};
|
|
204
|
-
|
|
205
|
-
// src/WarpEvmBuilder.ts
|
|
206
|
-
import { ethers } from "ethers";
|
|
207
|
-
var WarpEvmBuilder = class {
|
|
208
|
-
constructor(config) {
|
|
209
|
-
this.config = config;
|
|
210
|
-
this.warp = {};
|
|
211
|
-
this.actions = [];
|
|
212
|
-
}
|
|
213
|
-
async createFromRaw(encoded) {
|
|
214
|
-
try {
|
|
215
|
-
const decoded = JSON.parse(encoded);
|
|
216
|
-
return decoded;
|
|
217
|
-
} catch (error) {
|
|
218
|
-
throw new Error(`Failed to decode warp from raw data: ${error}`);
|
|
219
|
-
}
|
|
220
|
-
}
|
|
221
|
-
setTitle(title) {
|
|
222
|
-
this.warp.title = title;
|
|
223
|
-
return this;
|
|
224
|
-
}
|
|
225
|
-
setDescription(description) {
|
|
226
|
-
this.warp.description = description;
|
|
227
|
-
return this;
|
|
228
|
-
}
|
|
229
|
-
setPreview(preview) {
|
|
230
|
-
this.warp.preview = preview;
|
|
231
|
-
return this;
|
|
232
|
-
}
|
|
233
|
-
setActions(actions) {
|
|
234
|
-
this.actions = actions;
|
|
235
|
-
return this;
|
|
236
|
-
}
|
|
237
|
-
addAction(action) {
|
|
238
|
-
this.actions.push(action);
|
|
239
|
-
return this;
|
|
240
|
-
}
|
|
241
|
-
async build() {
|
|
242
|
-
if (!this.warp.title) {
|
|
243
|
-
throw new Error("Warp title is required");
|
|
244
|
-
}
|
|
245
|
-
return {
|
|
246
|
-
protocol: "warp",
|
|
247
|
-
name: this.warp.name || "evm-warp",
|
|
248
|
-
title: this.warp.title,
|
|
249
|
-
description: this.warp.description || null,
|
|
250
|
-
preview: this.warp.preview || null,
|
|
251
|
-
actions: this.actions,
|
|
252
|
-
meta: {
|
|
253
|
-
chain: "evm",
|
|
254
|
-
hash: ethers.keccak256(ethers.toUtf8Bytes(this.warp.title)),
|
|
255
|
-
creator: this.config.user?.wallets?.evm || "",
|
|
256
|
-
createdAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
257
|
-
}
|
|
258
|
-
};
|
|
259
|
-
}
|
|
260
|
-
createInscriptionTransaction(warp) {
|
|
261
|
-
const warpData = JSON.stringify(warp);
|
|
262
|
-
const data = ethers.toUtf8Bytes(warpData);
|
|
263
|
-
return {
|
|
264
|
-
data: ethers.hexlify(data)
|
|
265
|
-
};
|
|
266
|
-
}
|
|
267
|
-
async createFromTransaction(tx, validate) {
|
|
268
|
-
if (!tx.data || tx.data === "0x") {
|
|
269
|
-
throw new Error("Transaction has no data");
|
|
270
|
-
}
|
|
271
|
-
try {
|
|
272
|
-
const data = ethers.toUtf8String(tx.data);
|
|
273
|
-
const warp = JSON.parse(data);
|
|
274
|
-
if (validate) {
|
|
275
|
-
if (!warp.protocol || warp.protocol !== "warp") {
|
|
276
|
-
throw new Error("Invalid warp protocol");
|
|
277
|
-
}
|
|
278
|
-
if (!warp.title) {
|
|
279
|
-
throw new Error("Warp title is required");
|
|
280
|
-
}
|
|
281
|
-
}
|
|
282
|
-
return warp;
|
|
283
|
-
} catch (error) {
|
|
284
|
-
throw new Error(`Failed to create warp from transaction: ${error}`);
|
|
285
|
-
}
|
|
286
|
-
}
|
|
287
|
-
async createFromTransactionHash(hash, cache) {
|
|
288
|
-
try {
|
|
289
|
-
const provider = new ethers.JsonRpcProvider(getEvmApiUrl(this.config.env));
|
|
290
|
-
const tx = await provider.getTransaction(hash);
|
|
291
|
-
if (!tx) {
|
|
292
|
-
return null;
|
|
293
|
-
}
|
|
294
|
-
return await this.createFromTransaction(tx);
|
|
295
|
-
} catch (error) {
|
|
296
|
-
return null;
|
|
297
|
-
}
|
|
298
|
-
}
|
|
540
|
+
["blockscout_base_sepolia" /* BlockscoutBaseSepolia */]: "https://sepolia.blockscout.com"
|
|
299
541
|
};
|
|
300
542
|
|
|
301
|
-
// src/WarpEvmExecutor.ts
|
|
302
|
-
import {
|
|
303
|
-
applyResultsToMessages,
|
|
304
|
-
getNextInfo,
|
|
305
|
-
getWarpActionByIndex
|
|
306
|
-
} from "@vleap/warps";
|
|
307
|
-
import { ethers as ethers3 } from "ethers";
|
|
308
|
-
|
|
309
543
|
// src/WarpEvmResults.ts
|
|
310
544
|
import {
|
|
311
545
|
evaluateResultsCommon,
|
|
546
|
+
getProviderConfig as getProviderConfig2,
|
|
547
|
+
getWarpWalletAddressFromConfig,
|
|
312
548
|
parseResultsOutIndex,
|
|
313
549
|
WarpConstants as WarpConstants2
|
|
314
550
|
} from "@vleap/warps";
|
|
551
|
+
import { ethers as ethers3 } from "ethers";
|
|
315
552
|
|
|
316
553
|
// src/WarpEvmSerializer.ts
|
|
317
554
|
import {
|
|
@@ -470,11 +707,59 @@ var WarpEvmSerializer = class {
|
|
|
470
707
|
|
|
471
708
|
// src/WarpEvmResults.ts
|
|
472
709
|
var WarpEvmResults = class {
|
|
473
|
-
constructor(config) {
|
|
710
|
+
constructor(config, chain) {
|
|
474
711
|
this.config = config;
|
|
712
|
+
this.chain = chain;
|
|
475
713
|
this.serializer = new WarpEvmSerializer();
|
|
714
|
+
const providerConfig = getProviderConfig2(this.config, this.chain.name, this.config.env, this.chain.defaultApiUrl);
|
|
715
|
+
const network = new ethers3.Network(this.chain.name, parseInt(this.chain.chainId));
|
|
716
|
+
this.provider = new ethers3.JsonRpcProvider(providerConfig.url, network);
|
|
717
|
+
}
|
|
718
|
+
async getActionExecution(warp, actionIndex, tx) {
|
|
719
|
+
if (!tx) {
|
|
720
|
+
return this.createFailedExecution(warp, actionIndex);
|
|
721
|
+
}
|
|
722
|
+
if ("status" in tx && typeof tx.status === "string") {
|
|
723
|
+
return this.handleWarpChainAction(warp, actionIndex, tx);
|
|
724
|
+
}
|
|
725
|
+
return this.handleTransactionReceipt(warp, actionIndex, tx);
|
|
726
|
+
}
|
|
727
|
+
createFailedExecution(warp, actionIndex) {
|
|
728
|
+
return {
|
|
729
|
+
success: false,
|
|
730
|
+
warp,
|
|
731
|
+
action: actionIndex,
|
|
732
|
+
user: getWarpWalletAddressFromConfig(this.config, this.chain.name),
|
|
733
|
+
txHash: "",
|
|
734
|
+
tx: null,
|
|
735
|
+
next: null,
|
|
736
|
+
values: { string: [], native: [] },
|
|
737
|
+
results: {},
|
|
738
|
+
messages: {}
|
|
739
|
+
};
|
|
740
|
+
}
|
|
741
|
+
handleWarpChainAction(warp, actionIndex, tx) {
|
|
742
|
+
const success = tx.status === "success";
|
|
743
|
+
const transactionHash = tx.id || tx.tx?.hash || "";
|
|
744
|
+
const gasUsed = tx.tx?.gasLimit || "0";
|
|
745
|
+
const gasPrice = tx.tx?.gasPrice || "0";
|
|
746
|
+
const blockNumber = tx.tx?.blockNumber || "0";
|
|
747
|
+
const rawValues = [transactionHash, blockNumber, gasUsed, gasPrice];
|
|
748
|
+
const stringValues = rawValues.map(String);
|
|
749
|
+
return {
|
|
750
|
+
success,
|
|
751
|
+
warp,
|
|
752
|
+
action: actionIndex,
|
|
753
|
+
user: getWarpWalletAddressFromConfig(this.config, this.chain.name),
|
|
754
|
+
txHash: transactionHash,
|
|
755
|
+
tx,
|
|
756
|
+
next: null,
|
|
757
|
+
values: { string: stringValues, native: rawValues },
|
|
758
|
+
results: {},
|
|
759
|
+
messages: {}
|
|
760
|
+
};
|
|
476
761
|
}
|
|
477
|
-
|
|
762
|
+
handleTransactionReceipt(warp, actionIndex, tx) {
|
|
478
763
|
const success = tx.status === 1;
|
|
479
764
|
const gasUsed = tx.gasUsed?.toString() || "0";
|
|
480
765
|
const gasPrice = tx.gasPrice?.toString() || "0";
|
|
@@ -482,33 +767,37 @@ var WarpEvmResults = class {
|
|
|
482
767
|
const transactionHash = tx.hash;
|
|
483
768
|
const logs = tx.logs.map((log) => ({
|
|
484
769
|
address: log.address,
|
|
485
|
-
topics: log.topics,
|
|
770
|
+
topics: [...log.topics],
|
|
486
771
|
data: log.data,
|
|
487
772
|
blockNumber: log.blockNumber?.toString() || "0",
|
|
488
773
|
transactionHash: log.transactionHash,
|
|
489
774
|
index: log.index?.toString() || "0"
|
|
490
775
|
}));
|
|
776
|
+
const rawValues = [transactionHash, blockNumber, gasUsed, gasPrice, ...logs.length > 0 ? logs : []];
|
|
777
|
+
const stringValues = rawValues.map(String);
|
|
491
778
|
return {
|
|
492
779
|
success,
|
|
493
780
|
warp,
|
|
494
|
-
action:
|
|
495
|
-
user: this.config.
|
|
781
|
+
action: actionIndex,
|
|
782
|
+
user: getWarpWalletAddressFromConfig(this.config, this.chain.name),
|
|
496
783
|
txHash: transactionHash,
|
|
784
|
+
tx,
|
|
497
785
|
next: null,
|
|
498
|
-
values:
|
|
786
|
+
values: { string: stringValues, native: rawValues },
|
|
499
787
|
results: {},
|
|
500
788
|
messages: {}
|
|
501
789
|
};
|
|
502
790
|
}
|
|
503
791
|
async extractQueryResults(warp, typedValues, actionIndex, inputs) {
|
|
504
|
-
const
|
|
505
|
-
const
|
|
792
|
+
const stringValues = typedValues.map((t) => this.serializer.typedToString(t));
|
|
793
|
+
const nativeValues = typedValues.map((t) => this.serializer.typedToNative(t)[1]);
|
|
794
|
+
const values = { string: stringValues, native: nativeValues };
|
|
506
795
|
let results = {};
|
|
507
796
|
if (!warp.results) return { values, results };
|
|
508
797
|
const getNestedValue = (path) => {
|
|
509
798
|
const indices = path.split(".").slice(1).map((i) => parseInt(i) - 1);
|
|
510
799
|
if (indices.length === 0) return void 0;
|
|
511
|
-
let value =
|
|
800
|
+
let value = nativeValues[indices[0]];
|
|
512
801
|
for (let i = 1; i < indices.length; i++) {
|
|
513
802
|
if (value === void 0 || value === null) return void 0;
|
|
514
803
|
value = value[indices[i]];
|
|
@@ -528,17 +817,42 @@ var WarpEvmResults = class {
|
|
|
528
817
|
results[key] = path;
|
|
529
818
|
}
|
|
530
819
|
}
|
|
531
|
-
return { values, results: await evaluateResultsCommon(warp, results, actionIndex, inputs) };
|
|
820
|
+
return { values, results: await evaluateResultsCommon(warp, results, actionIndex, inputs, this.serializer.coreSerializer, this.config) };
|
|
821
|
+
}
|
|
822
|
+
async getTransactionStatus(txHash) {
|
|
823
|
+
try {
|
|
824
|
+
const receipt = await this.provider.getTransactionReceipt(txHash);
|
|
825
|
+
if (!receipt) {
|
|
826
|
+
return { status: "pending" };
|
|
827
|
+
}
|
|
828
|
+
return {
|
|
829
|
+
status: receipt.status === 1 ? "confirmed" : "failed",
|
|
830
|
+
blockNumber: receipt.blockNumber,
|
|
831
|
+
gasUsed: receipt.gasUsed
|
|
832
|
+
};
|
|
833
|
+
} catch (error) {
|
|
834
|
+
throw new Error(`Failed to get transaction status: ${error}`);
|
|
835
|
+
}
|
|
836
|
+
}
|
|
837
|
+
async getTransactionReceipt(txHash) {
|
|
838
|
+
try {
|
|
839
|
+
return await this.provider.getTransactionReceipt(txHash);
|
|
840
|
+
} catch (error) {
|
|
841
|
+
return null;
|
|
842
|
+
}
|
|
532
843
|
}
|
|
533
844
|
};
|
|
534
845
|
|
|
535
846
|
// src/WarpEvmExecutor.ts
|
|
536
847
|
var WarpEvmExecutor = class {
|
|
537
|
-
constructor(config) {
|
|
848
|
+
constructor(config, chain) {
|
|
538
849
|
this.config = config;
|
|
850
|
+
this.chain = chain;
|
|
539
851
|
this.serializer = new WarpEvmSerializer();
|
|
540
|
-
|
|
541
|
-
|
|
852
|
+
const providerConfig = getProviderConfig3(this.config, chain.name, this.config.env, this.chain.defaultApiUrl);
|
|
853
|
+
const network = new ethers4.Network(this.chain.name, parseInt(this.chain.chainId));
|
|
854
|
+
this.provider = new ethers4.JsonRpcProvider(providerConfig.url, network);
|
|
855
|
+
this.results = new WarpEvmResults(config, this.chain);
|
|
542
856
|
}
|
|
543
857
|
async createTransaction(executable) {
|
|
544
858
|
const action = getWarpActionByIndex(executable.warp, executable.action);
|
|
@@ -556,13 +870,13 @@ var WarpEvmExecutor = class {
|
|
|
556
870
|
return tx;
|
|
557
871
|
}
|
|
558
872
|
async createTransferTransaction(executable) {
|
|
559
|
-
const userWallet = this.config
|
|
873
|
+
const userWallet = getWarpWalletAddressFromConfig2(this.config, executable.chain.name);
|
|
560
874
|
if (!userWallet) throw new Error("WarpEvmExecutor: createTransfer - user address not set");
|
|
561
|
-
if (!
|
|
875
|
+
if (!ethers4.isAddress(executable.destination)) {
|
|
562
876
|
throw new Error(`WarpEvmExecutor: Invalid destination address: ${executable.destination}`);
|
|
563
877
|
}
|
|
564
|
-
if (executable.
|
|
565
|
-
|
|
878
|
+
if (executable.transfers && executable.transfers.length > 0) {
|
|
879
|
+
return this.createTokenTransferTransaction(executable, userWallet);
|
|
566
880
|
}
|
|
567
881
|
const tx = {
|
|
568
882
|
to: executable.destination,
|
|
@@ -572,21 +886,20 @@ var WarpEvmExecutor = class {
|
|
|
572
886
|
return this.estimateGasAndSetDefaults(tx, userWallet);
|
|
573
887
|
}
|
|
574
888
|
async createContractCallTransaction(executable) {
|
|
575
|
-
const userWallet = this.config
|
|
889
|
+
const userWallet = getWarpWalletAddressFromConfig2(this.config, executable.chain.name);
|
|
576
890
|
if (!userWallet) throw new Error("WarpEvmExecutor: createContractCall - user address not set");
|
|
577
891
|
const action = getWarpActionByIndex(executable.warp, executable.action);
|
|
578
|
-
if (!action || !("func" in action) || !action.func)
|
|
579
|
-
|
|
580
|
-
}
|
|
581
|
-
if (!ethers3.isAddress(executable.destination)) {
|
|
582
|
-
throw new Error(`WarpEvmExecutor: Invalid contract address: ${executable.destination}`);
|
|
583
|
-
}
|
|
584
|
-
if (executable.value < 0) {
|
|
585
|
-
throw new Error(`WarpEvmExecutor: Contract call value cannot be negative: ${executable.value}`);
|
|
586
|
-
}
|
|
892
|
+
if (!action || !("func" in action) || !action.func) throw new Error("WarpEvmExecutor: Contract action must have a function name");
|
|
893
|
+
if (!ethers4.isAddress(executable.destination)) throw new Error(`WarpEvmExecutor: Invalid contract address: ${executable.destination}`);
|
|
587
894
|
try {
|
|
588
|
-
|
|
589
|
-
|
|
895
|
+
let iface;
|
|
896
|
+
try {
|
|
897
|
+
iface = new ethers4.Interface(JSON.parse(action.abi));
|
|
898
|
+
} catch {
|
|
899
|
+
iface = new ethers4.Interface([action.abi]);
|
|
900
|
+
}
|
|
901
|
+
const nativeArgs = executable.args.map((arg) => this.serializer.coreSerializer.stringToNative(arg)[1]);
|
|
902
|
+
const encodedData = iface.encodeFunctionData(action.func, nativeArgs);
|
|
590
903
|
const tx = {
|
|
591
904
|
to: executable.destination,
|
|
592
905
|
value: executable.value,
|
|
@@ -597,20 +910,54 @@ var WarpEvmExecutor = class {
|
|
|
597
910
|
throw new Error(`WarpEvmExecutor: Failed to encode function data for ${action.func}: ${error}`);
|
|
598
911
|
}
|
|
599
912
|
}
|
|
600
|
-
async
|
|
601
|
-
|
|
602
|
-
if (
|
|
603
|
-
|
|
913
|
+
async createTokenTransferTransaction(executable, userWallet) {
|
|
914
|
+
if (executable.transfers.length === 0) throw new Error("WarpEvmExecutor: No transfers provided");
|
|
915
|
+
if (!this.chain.nativeToken?.identifier) throw new Error("WarpEvmExecutor: No native token defined for this chain");
|
|
916
|
+
const nativeTokenTransfers = executable.transfers.filter((transfer) => transfer.identifier === this.chain.nativeToken.identifier);
|
|
917
|
+
const erc20Transfers = executable.transfers.filter((transfer) => transfer.identifier !== this.chain.nativeToken.identifier);
|
|
918
|
+
if (nativeTokenTransfers.length === 1 && erc20Transfers.length === 0) {
|
|
919
|
+
const transfer = nativeTokenTransfers[0];
|
|
920
|
+
if (transfer.amount <= 0n) throw new Error("WarpEvmExecutor: Native token transfer amount must be positive");
|
|
921
|
+
const tx = {
|
|
922
|
+
to: executable.destination,
|
|
923
|
+
value: transfer.amount,
|
|
924
|
+
data: "0x"
|
|
925
|
+
};
|
|
926
|
+
return this.estimateGasAndSetDefaults(tx, userWallet);
|
|
604
927
|
}
|
|
605
|
-
if (
|
|
606
|
-
|
|
928
|
+
if (nativeTokenTransfers.length === 0 && erc20Transfers.length === 1) {
|
|
929
|
+
return this.createSingleTokenTransfer(executable, erc20Transfers[0], userWallet);
|
|
607
930
|
}
|
|
608
|
-
if (
|
|
609
|
-
|
|
931
|
+
if (executable.transfers.length > 1) throw new Error("WarpEvmExecutor: Multiple token transfers not yet supported");
|
|
932
|
+
throw new Error("WarpEvmExecutor: Invalid transfer configuration");
|
|
933
|
+
}
|
|
934
|
+
async createSingleTokenTransfer(executable, transfer, userWallet) {
|
|
935
|
+
if (!ethers4.isAddress(transfer.identifier)) {
|
|
936
|
+
throw new Error(`WarpEvmExecutor: Invalid token address: ${transfer.identifier}`);
|
|
610
937
|
}
|
|
938
|
+
const transferInterface = new ethers4.Interface(["function transfer(address to, uint256 amount) returns (bool)"]);
|
|
939
|
+
const encodedData = transferInterface.encodeFunctionData("transfer", [executable.destination, transfer.amount]);
|
|
940
|
+
const tx = {
|
|
941
|
+
to: transfer.identifier,
|
|
942
|
+
value: 0n,
|
|
943
|
+
data: encodedData
|
|
944
|
+
};
|
|
945
|
+
return this.estimateGasAndSetDefaults(tx, userWallet);
|
|
946
|
+
}
|
|
947
|
+
async executeQuery(executable) {
|
|
948
|
+
const action = getWarpActionByIndex(executable.warp, executable.action);
|
|
949
|
+
if (action.type !== "query") throw new Error(`WarpEvmExecutor: Invalid action type for executeQuery: ${action.type}`);
|
|
950
|
+
if (!action.func) throw new Error("WarpEvmExecutor: Query action must have a function name");
|
|
951
|
+
if (!ethers4.isAddress(executable.destination)) throw new Error(`WarpEvmExecutor: Invalid address for query: ${executable.destination}`);
|
|
611
952
|
try {
|
|
612
|
-
|
|
613
|
-
|
|
953
|
+
let iface;
|
|
954
|
+
try {
|
|
955
|
+
iface = new ethers4.Interface(JSON.parse(action.abi));
|
|
956
|
+
} catch {
|
|
957
|
+
iface = new ethers4.Interface([action.abi]);
|
|
958
|
+
}
|
|
959
|
+
const nativeArgs = executable.args.map((arg) => this.serializer.coreSerializer.stringToNative(arg)[1]);
|
|
960
|
+
const encodedData = iface.encodeFunctionData(action.func, nativeArgs);
|
|
614
961
|
const result = await this.provider.call({
|
|
615
962
|
to: executable.destination,
|
|
616
963
|
data: encodedData
|
|
@@ -623,28 +970,17 @@ var WarpEvmExecutor = class {
|
|
|
623
970
|
executable.action,
|
|
624
971
|
executable.resolvedInputs
|
|
625
972
|
);
|
|
626
|
-
const
|
|
627
|
-
chain: "ethereum",
|
|
628
|
-
prefix: "eth",
|
|
629
|
-
builder: () => ({}),
|
|
630
|
-
executor: {},
|
|
631
|
-
results: {},
|
|
632
|
-
serializer: {},
|
|
633
|
-
registry: {},
|
|
634
|
-
explorer: () => ({}),
|
|
635
|
-
abiBuilder: () => ({}),
|
|
636
|
-
brandBuilder: () => ({})
|
|
637
|
-
};
|
|
638
|
-
const next = getNextInfo(this.config, mockAdapter, executable.warp, executable.action, results);
|
|
973
|
+
const next = getNextInfo(this.config, [], executable.warp, executable.action, results);
|
|
639
974
|
return {
|
|
640
975
|
success: isSuccess,
|
|
641
976
|
warp: executable.warp,
|
|
642
977
|
action: executable.action,
|
|
643
|
-
user: this.config
|
|
978
|
+
user: getWarpWalletAddressFromConfig2(this.config, executable.chain.name),
|
|
644
979
|
txHash: null,
|
|
980
|
+
tx: null,
|
|
645
981
|
next,
|
|
646
982
|
values,
|
|
647
|
-
results,
|
|
983
|
+
results: { ...results, _DATA: decodedResult },
|
|
648
984
|
messages: applyResultsToMessages(executable.warp, results)
|
|
649
985
|
};
|
|
650
986
|
} catch (error) {
|
|
@@ -652,58 +988,29 @@ var WarpEvmExecutor = class {
|
|
|
652
988
|
success: false,
|
|
653
989
|
warp: executable.warp,
|
|
654
990
|
action: executable.action,
|
|
655
|
-
user: this.config
|
|
991
|
+
user: getWarpWalletAddressFromConfig2(this.config, executable.chain.name),
|
|
656
992
|
txHash: null,
|
|
993
|
+
tx: null,
|
|
657
994
|
next: null,
|
|
658
|
-
values: [],
|
|
659
|
-
results: {},
|
|
995
|
+
values: { string: [], native: [] },
|
|
996
|
+
results: { _DATA: error },
|
|
660
997
|
messages: {}
|
|
661
998
|
};
|
|
662
999
|
}
|
|
663
1000
|
}
|
|
664
|
-
async preprocessInput(chain, input, type, value) {
|
|
665
|
-
const typedValue = this.serializer.stringToTyped(value);
|
|
666
|
-
switch (type) {
|
|
667
|
-
case "address":
|
|
668
|
-
if (!ethers3.isAddress(typedValue)) {
|
|
669
|
-
throw new Error(`Invalid address format: ${typedValue}`);
|
|
670
|
-
}
|
|
671
|
-
return ethers3.getAddress(typedValue);
|
|
672
|
-
case "hex":
|
|
673
|
-
if (!ethers3.isHexString(typedValue)) {
|
|
674
|
-
throw new Error(`Invalid hex format: ${typedValue}`);
|
|
675
|
-
}
|
|
676
|
-
return typedValue;
|
|
677
|
-
case "uint8":
|
|
678
|
-
case "uint16":
|
|
679
|
-
case "uint32":
|
|
680
|
-
case "uint64":
|
|
681
|
-
case "biguint":
|
|
682
|
-
const bigIntValue = BigInt(typedValue);
|
|
683
|
-
if (bigIntValue < 0) {
|
|
684
|
-
throw new Error(`Negative value not allowed for type ${type}: ${typedValue}`);
|
|
685
|
-
}
|
|
686
|
-
return bigIntValue.toString();
|
|
687
|
-
default:
|
|
688
|
-
return String(typedValue);
|
|
689
|
-
}
|
|
690
|
-
}
|
|
691
1001
|
async estimateGasAndSetDefaults(tx, from) {
|
|
692
1002
|
try {
|
|
693
1003
|
const gasEstimate = await this.provider.estimateGas({
|
|
694
1004
|
...tx,
|
|
695
1005
|
from
|
|
696
1006
|
});
|
|
697
|
-
if (gasEstimate < BigInt(WarpEvmConstants.Validation.MinGasLimit)) {
|
|
698
|
-
|
|
699
|
-
}
|
|
700
|
-
if (gasEstimate > BigInt(WarpEvmConstants.Validation.MaxGasLimit)) {
|
|
701
|
-
throw new Error(`Gas estimate too high: ${gasEstimate}`);
|
|
702
|
-
}
|
|
1007
|
+
if (gasEstimate < BigInt(WarpEvmConstants.Validation.MinGasLimit)) throw new Error(`Gas estimate too low: ${gasEstimate}`);
|
|
1008
|
+
if (gasEstimate > BigInt(WarpEvmConstants.Validation.MaxGasLimit)) throw new Error(`Gas estimate too high: ${gasEstimate}`);
|
|
703
1009
|
const feeData = await this.provider.getFeeData();
|
|
704
1010
|
if (feeData.maxFeePerGas && feeData.maxPriorityFeePerGas) {
|
|
705
1011
|
return {
|
|
706
1012
|
...tx,
|
|
1013
|
+
chainId: parseInt(this.chain.chainId),
|
|
707
1014
|
gasLimit: gasEstimate,
|
|
708
1015
|
maxFeePerGas: feeData.maxFeePerGas,
|
|
709
1016
|
maxPriorityFeePerGas: feeData.maxPriorityFeePerGas
|
|
@@ -711,32 +1018,44 @@ var WarpEvmExecutor = class {
|
|
|
711
1018
|
} else if (feeData.gasPrice) {
|
|
712
1019
|
return {
|
|
713
1020
|
...tx,
|
|
1021
|
+
chainId: parseInt(this.chain.chainId),
|
|
714
1022
|
gasLimit: gasEstimate,
|
|
715
1023
|
gasPrice: feeData.gasPrice
|
|
716
1024
|
};
|
|
717
1025
|
} else {
|
|
718
1026
|
return {
|
|
719
1027
|
...tx,
|
|
1028
|
+
chainId: parseInt(this.chain.chainId),
|
|
720
1029
|
gasLimit: gasEstimate,
|
|
721
|
-
gasPrice:
|
|
1030
|
+
gasPrice: ethers4.parseUnits(WarpEvmConstants.GasPrice.Default, "wei")
|
|
722
1031
|
};
|
|
723
1032
|
}
|
|
724
1033
|
} catch (error) {
|
|
725
1034
|
let defaultGasLimit = BigInt(WarpEvmConstants.GasLimit.Default);
|
|
726
1035
|
if (tx.data && tx.data !== "0x") {
|
|
727
|
-
|
|
1036
|
+
if (tx.data.startsWith("0xa9059cbb")) {
|
|
1037
|
+
defaultGasLimit = BigInt(WarpEvmConstants.GasLimit.TokenTransfer);
|
|
1038
|
+
} else {
|
|
1039
|
+
defaultGasLimit = BigInt(WarpEvmConstants.GasLimit.ContractCall);
|
|
1040
|
+
}
|
|
728
1041
|
} else {
|
|
729
1042
|
defaultGasLimit = BigInt(WarpEvmConstants.GasLimit.Transfer);
|
|
730
1043
|
}
|
|
731
1044
|
return {
|
|
732
1045
|
...tx,
|
|
1046
|
+
chainId: parseInt(this.chain.chainId),
|
|
733
1047
|
gasLimit: defaultGasLimit,
|
|
734
|
-
gasPrice:
|
|
1048
|
+
gasPrice: ethers4.parseUnits(WarpEvmConstants.GasPrice.Default, "wei")
|
|
735
1049
|
};
|
|
736
1050
|
}
|
|
737
1051
|
}
|
|
738
|
-
async
|
|
739
|
-
|
|
1052
|
+
async verifyMessage(message, signature) {
|
|
1053
|
+
try {
|
|
1054
|
+
const recoveredAddress = ethers4.verifyMessage(message, signature);
|
|
1055
|
+
return recoveredAddress;
|
|
1056
|
+
} catch (error) {
|
|
1057
|
+
throw new Error(`Failed to verify message: ${error}`);
|
|
1058
|
+
}
|
|
740
1059
|
}
|
|
741
1060
|
};
|
|
742
1061
|
|
|
@@ -746,8 +1065,23 @@ var WarpEvmExplorer = class {
|
|
|
746
1065
|
this.chain = chain;
|
|
747
1066
|
this.config = config;
|
|
748
1067
|
}
|
|
1068
|
+
getExplorers() {
|
|
1069
|
+
const chainExplorers = EvmExplorers[this.chain.name];
|
|
1070
|
+
if (!chainExplorers) {
|
|
1071
|
+
return ["Default"];
|
|
1072
|
+
}
|
|
1073
|
+
const explorers = chainExplorers[this.config.env];
|
|
1074
|
+
if (!explorers) {
|
|
1075
|
+
return ["Default"];
|
|
1076
|
+
}
|
|
1077
|
+
return explorers;
|
|
1078
|
+
}
|
|
1079
|
+
getPrimaryExplorer() {
|
|
1080
|
+
const explorers = this.getExplorers();
|
|
1081
|
+
return explorers[0];
|
|
1082
|
+
}
|
|
749
1083
|
getExplorerUrlByName(explorer) {
|
|
750
|
-
const userPreference = this.
|
|
1084
|
+
const userPreference = this.config.preferences?.explorers?.[this.chain.name];
|
|
751
1085
|
if (userPreference && !explorer) {
|
|
752
1086
|
const url2 = ExplorerUrls[userPreference];
|
|
753
1087
|
if (url2) return url2;
|
|
@@ -756,9 +1090,9 @@ var WarpEvmExplorer = class {
|
|
|
756
1090
|
const url2 = ExplorerUrls[explorer];
|
|
757
1091
|
if (url2) return url2;
|
|
758
1092
|
}
|
|
759
|
-
const primaryExplorer =
|
|
1093
|
+
const primaryExplorer = this.getPrimaryExplorer();
|
|
760
1094
|
const url = ExplorerUrls[primaryExplorer];
|
|
761
|
-
return url ||
|
|
1095
|
+
return url || ExplorerUrls[primaryExplorer];
|
|
762
1096
|
}
|
|
763
1097
|
getAccountUrl(address, explorer) {
|
|
764
1098
|
const baseUrl = this.getExplorerUrlByName(explorer);
|
|
@@ -772,27 +1106,20 @@ var WarpEvmExplorer = class {
|
|
|
772
1106
|
const baseUrl = this.getExplorerUrlByName(explorer);
|
|
773
1107
|
return `${baseUrl}/block/${blockNumber}`;
|
|
774
1108
|
}
|
|
775
|
-
|
|
1109
|
+
getAssetUrl(identifier, explorer) {
|
|
776
1110
|
const baseUrl = this.getExplorerUrlByName(explorer);
|
|
777
|
-
return `${baseUrl}/token/${
|
|
1111
|
+
return `${baseUrl}/token/${identifier}`;
|
|
778
1112
|
}
|
|
779
|
-
getContractUrl(
|
|
1113
|
+
getContractUrl(address, explorer) {
|
|
780
1114
|
const baseUrl = this.getExplorerUrlByName(explorer);
|
|
781
|
-
return `${baseUrl}/address/${
|
|
1115
|
+
return `${baseUrl}/address/${address}`;
|
|
782
1116
|
}
|
|
783
1117
|
getAllExplorers() {
|
|
784
|
-
|
|
785
|
-
return getEvmExplorers(this.chain.name, this.config.env);
|
|
786
|
-
} catch {
|
|
787
|
-
return ["Default"];
|
|
788
|
-
}
|
|
1118
|
+
return this.getExplorers();
|
|
789
1119
|
}
|
|
790
1120
|
getExplorerByName(name) {
|
|
791
|
-
|
|
792
|
-
|
|
793
|
-
} catch {
|
|
794
|
-
return void 0;
|
|
795
|
-
}
|
|
1121
|
+
const explorers = this.getExplorers();
|
|
1122
|
+
return explorers.find((explorer) => explorer.toLowerCase() === name.toLowerCase());
|
|
796
1123
|
}
|
|
797
1124
|
getAccountUrls(address) {
|
|
798
1125
|
const explorers = this.getAllExplorers();
|
|
@@ -816,58 +1143,379 @@ var WarpEvmExplorer = class {
|
|
|
816
1143
|
});
|
|
817
1144
|
return urls;
|
|
818
1145
|
}
|
|
1146
|
+
getAssetUrls(identifier) {
|
|
1147
|
+
const explorers = this.getAllExplorers();
|
|
1148
|
+
const urls = {};
|
|
1149
|
+
explorers.forEach((explorer) => {
|
|
1150
|
+
const url = ExplorerUrls[explorer];
|
|
1151
|
+
if (url) {
|
|
1152
|
+
urls[explorer] = `${url}/token/${identifier}`;
|
|
1153
|
+
}
|
|
1154
|
+
});
|
|
1155
|
+
return urls;
|
|
1156
|
+
}
|
|
1157
|
+
getContractUrls(address) {
|
|
1158
|
+
const explorers = this.getAllExplorers();
|
|
1159
|
+
const urls = {};
|
|
1160
|
+
explorers.forEach((explorer) => {
|
|
1161
|
+
const url = ExplorerUrls[explorer];
|
|
1162
|
+
if (url) {
|
|
1163
|
+
urls[explorer] = `${url}/address/${address}`;
|
|
1164
|
+
}
|
|
1165
|
+
});
|
|
1166
|
+
return urls;
|
|
1167
|
+
}
|
|
1168
|
+
getBlockUrls(blockNumber) {
|
|
1169
|
+
const explorers = this.getAllExplorers();
|
|
1170
|
+
const urls = {};
|
|
1171
|
+
explorers.forEach((explorer) => {
|
|
1172
|
+
const url = ExplorerUrls[explorer];
|
|
1173
|
+
if (url) {
|
|
1174
|
+
urls[explorer] = `${url}/block/${blockNumber}`;
|
|
1175
|
+
}
|
|
1176
|
+
});
|
|
1177
|
+
return urls;
|
|
1178
|
+
}
|
|
819
1179
|
};
|
|
820
1180
|
|
|
821
|
-
// src/
|
|
822
|
-
|
|
823
|
-
|
|
824
|
-
|
|
825
|
-
|
|
826
|
-
|
|
827
|
-
|
|
828
|
-
|
|
829
|
-
|
|
830
|
-
|
|
1181
|
+
// src/WarpEvmWallet.ts
|
|
1182
|
+
import {
|
|
1183
|
+
getProviderConfig as getProviderConfig4,
|
|
1184
|
+
getWarpWalletMnemonicFromConfig,
|
|
1185
|
+
getWarpWalletPrivateKeyFromConfig
|
|
1186
|
+
} from "@vleap/warps";
|
|
1187
|
+
import { ethers as ethers5 } from "ethers";
|
|
1188
|
+
var WarpEvmWallet = class {
|
|
1189
|
+
constructor(config, chain) {
|
|
1190
|
+
this.config = config;
|
|
1191
|
+
this.chain = chain;
|
|
1192
|
+
const providerConfig = getProviderConfig4(config, chain.name, config.env, chain.defaultApiUrl);
|
|
1193
|
+
this.provider = new ethers5.JsonRpcProvider(providerConfig.url);
|
|
1194
|
+
}
|
|
1195
|
+
async signTransaction(tx) {
|
|
1196
|
+
if (!tx || typeof tx !== "object") throw new Error("Invalid transaction object");
|
|
1197
|
+
const wallet = this.getWallet();
|
|
1198
|
+
const txRequest = {
|
|
1199
|
+
to: tx.to,
|
|
1200
|
+
data: tx.data,
|
|
1201
|
+
value: tx.value || 0,
|
|
1202
|
+
gasLimit: tx.gasLimit,
|
|
1203
|
+
maxFeePerGas: tx.maxFeePerGas,
|
|
1204
|
+
maxPriorityFeePerGas: tx.maxPriorityFeePerGas,
|
|
1205
|
+
nonce: tx.nonce,
|
|
1206
|
+
chainId: tx.chainId
|
|
1207
|
+
};
|
|
1208
|
+
const signedTx = await wallet.signTransaction(txRequest);
|
|
1209
|
+
return { ...tx, signature: signedTx };
|
|
1210
|
+
}
|
|
1211
|
+
async signTransactions(txs) {
|
|
1212
|
+
if (txs.length === 0) return [];
|
|
1213
|
+
if (txs.length > 1) {
|
|
1214
|
+
const wallet = this.getWallet();
|
|
1215
|
+
const address = wallet.address;
|
|
1216
|
+
const currentNonce = await this.provider.getTransactionCount(address, "pending");
|
|
1217
|
+
const signedTxs = [];
|
|
1218
|
+
for (let i = 0; i < txs.length; i++) {
|
|
1219
|
+
const tx = { ...txs[i] };
|
|
1220
|
+
tx.nonce = currentNonce + i;
|
|
1221
|
+
if (i > 0) {
|
|
1222
|
+
const priorityReduction = BigInt(i * 1e9);
|
|
1223
|
+
const minGasPrice = BigInt(1e9);
|
|
1224
|
+
if (tx.maxFeePerGas && tx.maxPriorityFeePerGas) {
|
|
1225
|
+
tx.maxFeePerGas = tx.maxFeePerGas > priorityReduction ? tx.maxFeePerGas - priorityReduction : minGasPrice;
|
|
1226
|
+
tx.maxPriorityFeePerGas = tx.maxPriorityFeePerGas > priorityReduction ? tx.maxPriorityFeePerGas - priorityReduction : minGasPrice;
|
|
1227
|
+
delete tx.gasPrice;
|
|
1228
|
+
} else if (tx.gasPrice) {
|
|
1229
|
+
tx.gasPrice = tx.gasPrice > priorityReduction ? tx.gasPrice - priorityReduction : minGasPrice;
|
|
1230
|
+
delete tx.maxFeePerGas;
|
|
1231
|
+
delete tx.maxPriorityFeePerGas;
|
|
1232
|
+
}
|
|
1233
|
+
}
|
|
1234
|
+
const signedTx = await this.signTransaction(tx);
|
|
1235
|
+
signedTxs.push(signedTx);
|
|
1236
|
+
}
|
|
1237
|
+
return signedTxs;
|
|
1238
|
+
}
|
|
1239
|
+
return Promise.all(txs.map(async (tx) => this.signTransaction(tx)));
|
|
1240
|
+
}
|
|
1241
|
+
async signMessage(message) {
|
|
1242
|
+
const wallet = this.getWallet();
|
|
1243
|
+
const signature = await wallet.signMessage(message);
|
|
1244
|
+
return signature;
|
|
1245
|
+
}
|
|
1246
|
+
async sendTransaction(tx) {
|
|
1247
|
+
if (!tx || typeof tx !== "object") throw new Error("Invalid transaction object");
|
|
1248
|
+
if (!tx.signature) throw new Error("Transaction must be signed before sending");
|
|
1249
|
+
const wallet = this.getWallet();
|
|
1250
|
+
if (!wallet) throw new Error("Wallet not initialized - no private key provided");
|
|
1251
|
+
const connectedWallet = wallet.connect(this.provider);
|
|
1252
|
+
const txResponse = await connectedWallet.sendTransaction(tx);
|
|
1253
|
+
return txResponse.hash;
|
|
1254
|
+
}
|
|
1255
|
+
async sendTransactions(txs) {
|
|
1256
|
+
return Promise.all(txs.map(async (tx) => this.sendTransaction(tx)));
|
|
1257
|
+
}
|
|
1258
|
+
create(mnemonic) {
|
|
1259
|
+
const wallet = ethers5.Wallet.fromPhrase(mnemonic);
|
|
1260
|
+
return { address: wallet.address, privateKey: wallet.privateKey, mnemonic };
|
|
1261
|
+
}
|
|
1262
|
+
generate() {
|
|
1263
|
+
const wallet = ethers5.Wallet.createRandom();
|
|
1264
|
+
return { address: wallet.address, privateKey: wallet.privateKey, mnemonic: wallet.mnemonic?.phrase || "" };
|
|
1265
|
+
}
|
|
1266
|
+
getAddress() {
|
|
1267
|
+
const wallet = this.getWallet();
|
|
1268
|
+
return wallet.address;
|
|
1269
|
+
}
|
|
1270
|
+
getWallet() {
|
|
1271
|
+
const privateKey = getWarpWalletPrivateKeyFromConfig(this.config, this.chain.name);
|
|
1272
|
+
if (privateKey) return new ethers5.Wallet(privateKey);
|
|
1273
|
+
const mnemonic = getWarpWalletMnemonicFromConfig(this.config, this.chain.name);
|
|
1274
|
+
if (mnemonic) return ethers5.Wallet.fromPhrase(mnemonic);
|
|
1275
|
+
throw new Error("No private key or mnemonic provided");
|
|
1276
|
+
}
|
|
1277
|
+
};
|
|
1278
|
+
|
|
1279
|
+
// src/chains/common.ts
|
|
1280
|
+
var createEvmAdapter = (chainName, chainInfos) => {
|
|
831
1281
|
return (config, fallback) => {
|
|
832
1282
|
if (!fallback) throw new Error(`${chainName} adapter requires a fallback adapter`);
|
|
833
1283
|
return {
|
|
834
|
-
|
|
835
|
-
|
|
836
|
-
|
|
837
|
-
|
|
838
|
-
results: new WarpEvmResults(config),
|
|
1284
|
+
chainInfo: chainInfos[config.env],
|
|
1285
|
+
builder: () => fallback.builder(),
|
|
1286
|
+
executor: new WarpEvmExecutor(config, chainInfos[config.env]),
|
|
1287
|
+
results: new WarpEvmResults(config, chainInfos[config.env]),
|
|
839
1288
|
serializer: new WarpEvmSerializer(),
|
|
840
1289
|
registry: fallback.registry,
|
|
841
|
-
explorer:
|
|
1290
|
+
explorer: new WarpEvmExplorer(chainInfos[config.env], config),
|
|
842
1291
|
abiBuilder: () => fallback.abiBuilder(),
|
|
843
|
-
brandBuilder: () => fallback.brandBuilder()
|
|
1292
|
+
brandBuilder: () => fallback.brandBuilder(),
|
|
1293
|
+
dataLoader: new WarpEvmDataLoader(config, chainInfos[config.env]),
|
|
1294
|
+
wallet: new WarpEvmWallet(config, chainInfos[config.env])
|
|
844
1295
|
};
|
|
845
1296
|
};
|
|
846
|
-
}
|
|
1297
|
+
};
|
|
1298
|
+
|
|
1299
|
+
// src/chains/arbitrum.ts
|
|
1300
|
+
var NativeTokenArb = {
|
|
1301
|
+
chain: WarpChainName6.Arbitrum,
|
|
1302
|
+
identifier: "ARB",
|
|
1303
|
+
symbol: "ARB",
|
|
1304
|
+
name: "Arbitrum",
|
|
1305
|
+
decimals: 18,
|
|
1306
|
+
logoUrl: "https://vleap.ai/images/tokens/arb.svg"
|
|
1307
|
+
};
|
|
1308
|
+
var getArbitrumAdapter = createEvmAdapter(WarpChainName6.Arbitrum, {
|
|
1309
|
+
mainnet: {
|
|
1310
|
+
name: WarpChainName6.Arbitrum,
|
|
1311
|
+
displayName: "Arbitrum",
|
|
1312
|
+
chainId: "42161",
|
|
1313
|
+
blockTime: 1e3,
|
|
1314
|
+
addressHrp: "0x",
|
|
1315
|
+
defaultApiUrl: "https://arb1.arbitrum.io/rpc",
|
|
1316
|
+
logoUrl: "https://vleap.ai/images/chains/arbitrum.svg",
|
|
1317
|
+
nativeToken: NativeTokenArb
|
|
1318
|
+
},
|
|
1319
|
+
testnet: {
|
|
1320
|
+
name: WarpChainName6.Arbitrum,
|
|
1321
|
+
displayName: "Arbitrum Sepolia",
|
|
1322
|
+
chainId: "421614",
|
|
1323
|
+
blockTime: 1e3,
|
|
1324
|
+
addressHrp: "0x",
|
|
1325
|
+
defaultApiUrl: "https://sepolia-rollup.arbitrum.io/rpc",
|
|
1326
|
+
logoUrl: "https://vleap.ai/images/chains/arbitrum.svg",
|
|
1327
|
+
nativeToken: NativeTokenArb
|
|
1328
|
+
},
|
|
1329
|
+
devnet: {
|
|
1330
|
+
name: WarpChainName6.Arbitrum,
|
|
1331
|
+
displayName: "Arbitrum Sepolia",
|
|
1332
|
+
chainId: "421614",
|
|
1333
|
+
blockTime: 1e3,
|
|
1334
|
+
addressHrp: "0x",
|
|
1335
|
+
defaultApiUrl: "https://sepolia-rollup.arbitrum.io/rpc",
|
|
1336
|
+
logoUrl: "https://vleap.ai/images/chains/arbitrum.svg",
|
|
1337
|
+
nativeToken: NativeTokenArb
|
|
1338
|
+
}
|
|
1339
|
+
});
|
|
1340
|
+
|
|
1341
|
+
// src/chains/base.ts
|
|
1342
|
+
import { WarpChainName as WarpChainName7 } from "@vleap/warps";
|
|
1343
|
+
var NativeTokenBase = {
|
|
1344
|
+
chain: WarpChainName7.Base,
|
|
1345
|
+
identifier: "ETH",
|
|
1346
|
+
name: "Ether",
|
|
1347
|
+
symbol: "ETH",
|
|
1348
|
+
decimals: 18,
|
|
1349
|
+
logoUrl: "https://vleap.ai/images/tokens/eth.svg"
|
|
1350
|
+
};
|
|
1351
|
+
var getBaseAdapter = createEvmAdapter(WarpChainName7.Base, {
|
|
1352
|
+
mainnet: {
|
|
1353
|
+
name: WarpChainName7.Base,
|
|
1354
|
+
displayName: "Base",
|
|
1355
|
+
chainId: "8453",
|
|
1356
|
+
blockTime: 2e3,
|
|
1357
|
+
addressHrp: "0x",
|
|
1358
|
+
defaultApiUrl: "https://mainnet.base.org",
|
|
1359
|
+
logoUrl: "https://vleap.ai/images/chains/base.svg",
|
|
1360
|
+
nativeToken: NativeTokenBase
|
|
1361
|
+
},
|
|
1362
|
+
testnet: {
|
|
1363
|
+
name: WarpChainName7.Base,
|
|
1364
|
+
displayName: "Base Sepolia",
|
|
1365
|
+
chainId: "84532",
|
|
1366
|
+
blockTime: 2e3,
|
|
1367
|
+
addressHrp: "0x",
|
|
1368
|
+
defaultApiUrl: "https://sepolia.base.org",
|
|
1369
|
+
logoUrl: "https://vleap.ai/images/chains/base.svg",
|
|
1370
|
+
nativeToken: NativeTokenBase
|
|
1371
|
+
},
|
|
1372
|
+
devnet: {
|
|
1373
|
+
name: WarpChainName7.Base,
|
|
1374
|
+
displayName: "Base Sepolia",
|
|
1375
|
+
chainId: "84532",
|
|
1376
|
+
blockTime: 2e3,
|
|
1377
|
+
addressHrp: "0x",
|
|
1378
|
+
defaultApiUrl: "https://sepolia.base.org",
|
|
1379
|
+
logoUrl: "https://vleap.ai/images/chains/base.svg",
|
|
1380
|
+
nativeToken: NativeTokenBase
|
|
1381
|
+
}
|
|
1382
|
+
});
|
|
1383
|
+
|
|
1384
|
+
// src/chains/combined.ts
|
|
1385
|
+
import { WarpChainName as WarpChainName10 } from "@vleap/warps";
|
|
1386
|
+
|
|
1387
|
+
// src/chains/ethereum.ts
|
|
1388
|
+
import { WarpChainName as WarpChainName8 } from "@vleap/warps";
|
|
1389
|
+
var NativeTokenEth = {
|
|
1390
|
+
chain: WarpChainName8.Ethereum,
|
|
1391
|
+
identifier: "ETH",
|
|
1392
|
+
symbol: "ETH",
|
|
1393
|
+
name: "Ether",
|
|
1394
|
+
decimals: 18,
|
|
1395
|
+
logoUrl: "https://vleap.ai/images/tokens/eth.svg"
|
|
1396
|
+
};
|
|
1397
|
+
var getEthereumAdapter = createEvmAdapter(WarpChainName8.Ethereum, {
|
|
1398
|
+
mainnet: {
|
|
1399
|
+
name: WarpChainName8.Ethereum,
|
|
1400
|
+
displayName: "Ethereum Mainnet",
|
|
1401
|
+
chainId: "1",
|
|
1402
|
+
blockTime: 12e3,
|
|
1403
|
+
addressHrp: "0x",
|
|
1404
|
+
defaultApiUrl: "https://ethereum-rpc.publicnode.com",
|
|
1405
|
+
logoUrl: "https://vleap.ai/images/chains/ethereum.svg",
|
|
1406
|
+
nativeToken: NativeTokenEth
|
|
1407
|
+
},
|
|
1408
|
+
testnet: {
|
|
1409
|
+
name: WarpChainName8.Ethereum,
|
|
1410
|
+
displayName: "Ethereum Sepolia",
|
|
1411
|
+
chainId: "11155111",
|
|
1412
|
+
blockTime: 12e3,
|
|
1413
|
+
addressHrp: "0x",
|
|
1414
|
+
defaultApiUrl: "https://ethereum-sepolia-rpc.publicnode.com",
|
|
1415
|
+
logoUrl: "https://vleap.ai/images/chains/ethereum.svg",
|
|
1416
|
+
nativeToken: NativeTokenEth
|
|
1417
|
+
},
|
|
1418
|
+
devnet: {
|
|
1419
|
+
name: WarpChainName8.Ethereum,
|
|
1420
|
+
displayName: "Ethereum Sepolia",
|
|
1421
|
+
chainId: "11155111",
|
|
1422
|
+
blockTime: 12e3,
|
|
1423
|
+
addressHrp: "0x",
|
|
1424
|
+
defaultApiUrl: "https://ethereum-sepolia-rpc.publicnode.com",
|
|
1425
|
+
logoUrl: "https://vleap.ai/images/chains/ethereum.svg",
|
|
1426
|
+
nativeToken: NativeTokenEth
|
|
1427
|
+
}
|
|
1428
|
+
});
|
|
1429
|
+
|
|
1430
|
+
// src/chains/somnia.ts
|
|
1431
|
+
import { WarpChainName as WarpChainName9 } from "@vleap/warps";
|
|
1432
|
+
var NativeTokenSomi = {
|
|
1433
|
+
chain: WarpChainName9.Somnia,
|
|
1434
|
+
identifier: "SOMI",
|
|
1435
|
+
symbol: "SOMI",
|
|
1436
|
+
name: "Somnia",
|
|
1437
|
+
decimals: 18,
|
|
1438
|
+
logoUrl: "https://assets.coingecko.com/coins/images/68061/standard/somniacg.png?1754641117"
|
|
1439
|
+
};
|
|
1440
|
+
var NativeTokenStt = {
|
|
1441
|
+
chain: WarpChainName9.Somnia,
|
|
1442
|
+
identifier: "STT",
|
|
1443
|
+
symbol: "STT",
|
|
1444
|
+
name: "Somnia Testnet Token",
|
|
1445
|
+
decimals: 18,
|
|
1446
|
+
logoUrl: "https://assets.coingecko.com/coins/images/68061/standard/somniacg.png?1754641117"
|
|
1447
|
+
};
|
|
1448
|
+
var getSomniaAdapter = createEvmAdapter(WarpChainName9.Somnia, {
|
|
1449
|
+
mainnet: {
|
|
1450
|
+
name: WarpChainName9.Somnia,
|
|
1451
|
+
displayName: "Somnia Mainnet",
|
|
1452
|
+
chainId: "5031",
|
|
1453
|
+
blockTime: 100,
|
|
1454
|
+
addressHrp: "0x",
|
|
1455
|
+
defaultApiUrl: "https://api.infra.mainnet.somnia.network/",
|
|
1456
|
+
logoUrl: "https://vleap.ai/images/chains/somnia.png",
|
|
1457
|
+
nativeToken: NativeTokenSomi
|
|
1458
|
+
},
|
|
1459
|
+
testnet: {
|
|
1460
|
+
name: WarpChainName9.Somnia,
|
|
1461
|
+
displayName: "Somnia Testnet",
|
|
1462
|
+
chainId: "50312",
|
|
1463
|
+
blockTime: 100,
|
|
1464
|
+
addressHrp: "0x",
|
|
1465
|
+
defaultApiUrl: "https://dream-rpc.somnia.network/",
|
|
1466
|
+
logoUrl: "https://vleap.ai/images/chains/somnia.png",
|
|
1467
|
+
nativeToken: NativeTokenStt
|
|
1468
|
+
},
|
|
1469
|
+
devnet: {
|
|
1470
|
+
name: WarpChainName9.Somnia,
|
|
1471
|
+
displayName: "Somnia Testnet",
|
|
1472
|
+
chainId: "50312",
|
|
1473
|
+
blockTime: 100,
|
|
1474
|
+
addressHrp: "0x",
|
|
1475
|
+
defaultApiUrl: "https://dream-rpc.somnia.network",
|
|
1476
|
+
logoUrl: "https://vleap.ai/images/chains/somnia.png",
|
|
1477
|
+
nativeToken: NativeTokenStt
|
|
1478
|
+
}
|
|
1479
|
+
});
|
|
1480
|
+
|
|
1481
|
+
// src/chains/combined.ts
|
|
1482
|
+
var getAllEvmAdapters = (config, fallback) => [
|
|
1483
|
+
getEthereumAdapter(config, fallback),
|
|
1484
|
+
getBaseAdapter(config, fallback),
|
|
1485
|
+
getArbitrumAdapter(config, fallback),
|
|
1486
|
+
getSomniaAdapter(config, fallback)
|
|
1487
|
+
];
|
|
1488
|
+
var getAllEvmChainNames = () => [
|
|
1489
|
+
WarpChainName10.Ethereum,
|
|
1490
|
+
WarpChainName10.Base,
|
|
1491
|
+
WarpChainName10.Arbitrum,
|
|
1492
|
+
WarpChainName10.Somnia
|
|
1493
|
+
];
|
|
847
1494
|
export {
|
|
848
1495
|
ArbitrumExplorers,
|
|
849
1496
|
BaseExplorers,
|
|
850
|
-
EVM_CHAIN_CONFIGS,
|
|
851
1497
|
EthereumExplorers,
|
|
852
1498
|
EvmExplorers,
|
|
853
1499
|
ExplorerUrls,
|
|
854
|
-
|
|
855
|
-
|
|
1500
|
+
KnownTokens,
|
|
1501
|
+
NativeTokenArb,
|
|
1502
|
+
NativeTokenBase,
|
|
1503
|
+
NativeTokenEth,
|
|
1504
|
+
UniswapService,
|
|
856
1505
|
WarpEvmConstants,
|
|
1506
|
+
WarpEvmDataLoader,
|
|
857
1507
|
WarpEvmExecutor,
|
|
858
1508
|
WarpEvmExplorer,
|
|
859
1509
|
WarpEvmResults,
|
|
860
1510
|
WarpEvmSerializer,
|
|
1511
|
+
WarpEvmWallet,
|
|
1512
|
+
createEvmAdapter,
|
|
1513
|
+
findKnownTokenById,
|
|
861
1514
|
getAllEvmAdapters,
|
|
1515
|
+
getAllEvmChainNames,
|
|
862
1516
|
getArbitrumAdapter,
|
|
863
1517
|
getBaseAdapter,
|
|
864
1518
|
getEthereumAdapter,
|
|
865
|
-
|
|
866
|
-
getEvmChainConfig,
|
|
867
|
-
getEvmExplorerByName,
|
|
868
|
-
getEvmExplorerUrl,
|
|
869
|
-
getEvmExplorerUrlByName,
|
|
870
|
-
getEvmExplorers,
|
|
871
|
-
getPrimaryEvmExplorer
|
|
1519
|
+
getKnownTokensForChain
|
|
872
1520
|
};
|
|
873
1521
|
//# sourceMappingURL=index.mjs.map
|