@vleap/warps-adapter-evm 0.2.0-alpha.8 → 0.2.0-beta.43
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 +147 -43
- package/dist/index.js +909 -569
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +902 -551
- package/dist/index.mjs.map +1 -1
- package/package.json +17 -10
- package/dist/index.d.mts +0 -157
package/dist/index.mjs
CHANGED
|
@@ -1,203 +1,300 @@
|
|
|
1
|
-
// src/
|
|
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";
|
|
2
11
|
import { ethers } from "ethers";
|
|
3
12
|
|
|
4
|
-
// src/
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
chainId: "1",
|
|
11
|
-
registryAddress: "0x0000000000000000000000000000000000000000",
|
|
12
|
-
nativeToken: "ETH",
|
|
13
|
-
blockTime: 12e3
|
|
14
|
-
},
|
|
15
|
-
testnet: {
|
|
16
|
-
apiUrl: "https://eth-sepolia.g.alchemy.com/v2/demo",
|
|
17
|
-
explorerUrl: "https://sepolia.etherscan.io",
|
|
18
|
-
chainId: "11155111",
|
|
19
|
-
registryAddress: "0x0000000000000000000000000000000000000000",
|
|
20
|
-
nativeToken: "ETH",
|
|
21
|
-
blockTime: 12e3
|
|
22
|
-
},
|
|
23
|
-
devnet: {
|
|
24
|
-
apiUrl: "http://localhost:8545",
|
|
25
|
-
explorerUrl: "http://localhost:4000",
|
|
26
|
-
chainId: "1337",
|
|
27
|
-
registryAddress: "0x0000000000000000000000000000000000000000",
|
|
28
|
-
nativeToken: "ETH",
|
|
29
|
-
blockTime: 12e3
|
|
30
|
-
}
|
|
31
|
-
},
|
|
32
|
-
arbitrum: {
|
|
33
|
-
mainnet: {
|
|
34
|
-
apiUrl: "https://arb-mainnet.g.alchemy.com/v2/demo",
|
|
35
|
-
explorerUrl: "https://arbiscan.io",
|
|
36
|
-
chainId: "42161",
|
|
37
|
-
registryAddress: "0x0000000000000000000000000000000000000000",
|
|
38
|
-
nativeToken: "ETH",
|
|
39
|
-
blockTime: 1e3
|
|
40
|
-
},
|
|
41
|
-
testnet: {
|
|
42
|
-
apiUrl: "https://arb-sepolia.g.alchemy.com/v2/demo",
|
|
43
|
-
explorerUrl: "https://sepolia.arbiscan.io",
|
|
44
|
-
chainId: "421614",
|
|
45
|
-
registryAddress: "0x0000000000000000000000000000000000000000",
|
|
46
|
-
nativeToken: "ETH",
|
|
47
|
-
blockTime: 1e3
|
|
48
|
-
},
|
|
49
|
-
devnet: {
|
|
50
|
-
apiUrl: "http://localhost:8545",
|
|
51
|
-
explorerUrl: "http://localhost:4000",
|
|
52
|
-
chainId: "1337",
|
|
53
|
-
registryAddress: "0x0000000000000000000000000000000000000000",
|
|
54
|
-
nativeToken: "ETH",
|
|
55
|
-
blockTime: 1e3
|
|
56
|
-
}
|
|
57
|
-
},
|
|
58
|
-
base: {
|
|
59
|
-
mainnet: {
|
|
60
|
-
apiUrl: "https://mainnet.base.org",
|
|
61
|
-
explorerUrl: "https://basescan.org",
|
|
62
|
-
chainId: "8453",
|
|
63
|
-
registryAddress: "0x0000000000000000000000000000000000000000",
|
|
64
|
-
nativeToken: "ETH",
|
|
65
|
-
blockTime: 2e3
|
|
66
|
-
},
|
|
67
|
-
testnet: {
|
|
68
|
-
apiUrl: "https://sepolia.base.org",
|
|
69
|
-
explorerUrl: "https://sepolia.basescan.org",
|
|
70
|
-
chainId: "84532",
|
|
71
|
-
registryAddress: "0x0000000000000000000000000000000000000000",
|
|
72
|
-
nativeToken: "ETH",
|
|
73
|
-
blockTime: 2e3
|
|
74
|
-
},
|
|
75
|
-
devnet: {
|
|
76
|
-
apiUrl: "http://localhost:8545",
|
|
77
|
-
explorerUrl: "http://localhost:4000",
|
|
78
|
-
chainId: "1337",
|
|
79
|
-
registryAddress: "0x0000000000000000000000000000000000000000",
|
|
80
|
-
nativeToken: "ETH",
|
|
81
|
-
blockTime: 2e3
|
|
82
|
-
}
|
|
83
|
-
}
|
|
84
|
-
};
|
|
85
|
-
var DEFAULT_CHAIN = "ethereum";
|
|
86
|
-
var getEvmChainConfig = (chain = DEFAULT_CHAIN, env) => {
|
|
87
|
-
const chainConfigs = EVM_CHAIN_CONFIGS[chain];
|
|
88
|
-
if (!chainConfigs) {
|
|
89
|
-
throw new Error(`Unsupported EVM chain: ${chain}`);
|
|
90
|
-
}
|
|
91
|
-
const config = chainConfigs[env];
|
|
92
|
-
if (!config) {
|
|
93
|
-
throw new Error(`Unsupported environment ${env} for chain ${chain}`);
|
|
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;
|
|
94
19
|
}
|
|
95
|
-
|
|
96
|
-
};
|
|
97
|
-
var getEvmApiUrl = (env, chain = DEFAULT_CHAIN) => {
|
|
98
|
-
return getEvmChainConfig(chain, env).apiUrl;
|
|
99
|
-
};
|
|
100
|
-
var getEvmExplorerUrl = (env, chain = DEFAULT_CHAIN) => {
|
|
101
|
-
return getEvmChainConfig(chain, env).explorerUrl;
|
|
102
|
-
};
|
|
103
|
-
|
|
104
|
-
// src/WarpEvmBuilder.ts
|
|
105
|
-
var WarpEvmBuilder = class {
|
|
106
|
-
constructor(config) {
|
|
107
|
-
this.config = config;
|
|
108
|
-
this.warp = {};
|
|
109
|
-
this.actions = [];
|
|
110
|
-
}
|
|
111
|
-
async createFromRaw(encoded) {
|
|
20
|
+
async getTokenList() {
|
|
112
21
|
try {
|
|
113
|
-
const
|
|
114
|
-
|
|
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;
|
|
115
28
|
} catch (error) {
|
|
116
|
-
throw new Error(`Failed to
|
|
117
|
-
}
|
|
118
|
-
}
|
|
119
|
-
setTitle(title) {
|
|
120
|
-
this.warp.title = title;
|
|
121
|
-
return this;
|
|
122
|
-
}
|
|
123
|
-
setDescription(description) {
|
|
124
|
-
this.warp.description = description;
|
|
125
|
-
return this;
|
|
126
|
-
}
|
|
127
|
-
setPreview(preview) {
|
|
128
|
-
this.warp.preview = preview;
|
|
129
|
-
return this;
|
|
130
|
-
}
|
|
131
|
-
setActions(actions) {
|
|
132
|
-
this.actions = actions;
|
|
133
|
-
return this;
|
|
134
|
-
}
|
|
135
|
-
addAction(action) {
|
|
136
|
-
this.actions.push(action);
|
|
137
|
-
return this;
|
|
138
|
-
}
|
|
139
|
-
async build() {
|
|
140
|
-
if (!this.warp.title) {
|
|
141
|
-
throw new Error("Warp title is required");
|
|
29
|
+
throw new Error(`Failed to fetch Uniswap token list: ${error}`);
|
|
142
30
|
}
|
|
143
|
-
return {
|
|
144
|
-
protocol: "warp",
|
|
145
|
-
name: this.warp.name || "evm-warp",
|
|
146
|
-
title: this.warp.title,
|
|
147
|
-
description: this.warp.description || null,
|
|
148
|
-
preview: this.warp.preview || null,
|
|
149
|
-
actions: this.actions,
|
|
150
|
-
meta: {
|
|
151
|
-
chain: "evm",
|
|
152
|
-
hash: ethers.keccak256(ethers.toUtf8Bytes(this.warp.title)),
|
|
153
|
-
creator: this.config.user?.wallets?.evm || "",
|
|
154
|
-
createdAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
155
|
-
}
|
|
156
|
-
};
|
|
157
|
-
}
|
|
158
|
-
createInscriptionTransaction(warp) {
|
|
159
|
-
const warpData = JSON.stringify(warp);
|
|
160
|
-
const data = ethers.toUtf8Bytes(warpData);
|
|
161
|
-
return {
|
|
162
|
-
data: ethers.hexlify(data)
|
|
163
|
-
};
|
|
164
31
|
}
|
|
165
|
-
async
|
|
166
|
-
|
|
167
|
-
|
|
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;
|
|
168
38
|
}
|
|
169
39
|
try {
|
|
170
|
-
const
|
|
171
|
-
const
|
|
172
|
-
if (
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
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);
|
|
179
49
|
}
|
|
180
|
-
return
|
|
50
|
+
return token;
|
|
181
51
|
} catch (error) {
|
|
182
|
-
|
|
52
|
+
return null;
|
|
183
53
|
}
|
|
184
54
|
}
|
|
185
|
-
async
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
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);
|
|
194
86
|
return null;
|
|
195
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;
|
|
196
94
|
}
|
|
197
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
|
+
};
|
|
198
296
|
|
|
199
297
|
// src/WarpEvmDataLoader.ts
|
|
200
|
-
import { ethers as ethers2 } from "ethers";
|
|
201
298
|
var ERC20_ABI = [
|
|
202
299
|
"function balanceOf(address owner) view returns (uint256)",
|
|
203
300
|
"function decimals() view returns (uint8)",
|
|
@@ -205,235 +302,166 @@ var ERC20_ABI = [
|
|
|
205
302
|
"function symbol() view returns (string)",
|
|
206
303
|
"function totalSupply() view returns (uint256)"
|
|
207
304
|
];
|
|
208
|
-
var KNOWN_TOKENS = {
|
|
209
|
-
ethereum: {
|
|
210
|
-
"0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48": {
|
|
211
|
-
name: "USD Coin",
|
|
212
|
-
symbol: "USDC",
|
|
213
|
-
decimals: 6,
|
|
214
|
-
logoUrl: "https://assets.coingecko.com/coins/images/6319/small/USD_Coin_icon.png"
|
|
215
|
-
},
|
|
216
|
-
"0xdAC17F958D2ee523a2206206994597C13D831ec7": {
|
|
217
|
-
name: "Tether USD",
|
|
218
|
-
symbol: "USDT",
|
|
219
|
-
decimals: 6,
|
|
220
|
-
logoUrl: "https://assets.coingecko.com/coins/images/325/small/Tether.png"
|
|
221
|
-
},
|
|
222
|
-
"0x2260FAC5E5542a773Aa44fBCfeDf7C193bc2C599": {
|
|
223
|
-
name: "Wrapped Bitcoin",
|
|
224
|
-
symbol: "WBTC",
|
|
225
|
-
decimals: 8,
|
|
226
|
-
logoUrl: "https://assets.coingecko.com/coins/images/7598/small/wrapped_bitcoin_wbtc.png"
|
|
227
|
-
},
|
|
228
|
-
"0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2": {
|
|
229
|
-
name: "Wrapped Ether",
|
|
230
|
-
symbol: "WETH",
|
|
231
|
-
decimals: 18,
|
|
232
|
-
logoUrl: "https://assets.coingecko.com/coins/images/2518/small/weth.png"
|
|
233
|
-
},
|
|
234
|
-
"0x6B175474E89094C44Da98b954EedeAC495271d0F": {
|
|
235
|
-
name: "Dai Stablecoin",
|
|
236
|
-
symbol: "DAI",
|
|
237
|
-
decimals: 18,
|
|
238
|
-
logoUrl: "https://assets.coingecko.com/coins/images/9956/small/4943.png"
|
|
239
|
-
}
|
|
240
|
-
},
|
|
241
|
-
arbitrum: {
|
|
242
|
-
"0xFF970A61A04b1cA14834A43f5dE4533eBDDB5CC8": {
|
|
243
|
-
name: "USD Coin",
|
|
244
|
-
symbol: "USDC",
|
|
245
|
-
decimals: 6,
|
|
246
|
-
logoUrl: "https://assets.coingecko.com/coins/images/6319/small/USD_Coin_icon.png"
|
|
247
|
-
},
|
|
248
|
-
"0xFd086bC7CD5C481DCC9C85ebE478A1C0b69FCbb9": {
|
|
249
|
-
name: "Tether USD",
|
|
250
|
-
symbol: "USDT",
|
|
251
|
-
decimals: 6,
|
|
252
|
-
logoUrl: "https://assets.coingecko.com/coins/images/325/small/Tether.png"
|
|
253
|
-
},
|
|
254
|
-
"0x82aF49447D8a07e3bd95BD0d56f35241523fBab1": {
|
|
255
|
-
name: "Wrapped Ether",
|
|
256
|
-
symbol: "WETH",
|
|
257
|
-
decimals: 18,
|
|
258
|
-
logoUrl: "https://assets.coingecko.com/coins/images/2518/small/weth.png"
|
|
259
|
-
}
|
|
260
|
-
},
|
|
261
|
-
base: {
|
|
262
|
-
"0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913": {
|
|
263
|
-
name: "USD Coin",
|
|
264
|
-
symbol: "USDC",
|
|
265
|
-
decimals: 6,
|
|
266
|
-
logoUrl: "https://assets.coingecko.com/coins/images/6319/small/USD_Coin_icon.png"
|
|
267
|
-
},
|
|
268
|
-
"0x4200000000000000000000000000000000000006": {
|
|
269
|
-
name: "Wrapped Ether",
|
|
270
|
-
symbol: "WETH",
|
|
271
|
-
decimals: 18,
|
|
272
|
-
logoUrl: "https://assets.coingecko.com/coins/images/2518/small/weth.png"
|
|
273
|
-
}
|
|
274
|
-
}
|
|
275
|
-
};
|
|
276
305
|
var WarpEvmDataLoader = class {
|
|
277
306
|
constructor(config, chain) {
|
|
278
307
|
this.config = config;
|
|
279
308
|
this.chain = chain;
|
|
280
|
-
|
|
281
|
-
|
|
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));
|
|
282
314
|
}
|
|
283
315
|
async getAccount(address) {
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
} catch (error) {
|
|
291
|
-
throw new Error(`Failed to get account balance for ${address}: ${error}`);
|
|
292
|
-
}
|
|
316
|
+
const balance = await this.provider.getBalance(address);
|
|
317
|
+
return {
|
|
318
|
+
chain: this.chain.name,
|
|
319
|
+
address,
|
|
320
|
+
balance
|
|
321
|
+
};
|
|
293
322
|
}
|
|
294
323
|
async getAccountAssets(address) {
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
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
|
+
});
|
|
308
338
|
}
|
|
309
|
-
return assets;
|
|
310
|
-
} catch (error) {
|
|
311
|
-
throw new Error(`Failed to get account assets for ${address}: ${error}`);
|
|
312
339
|
}
|
|
340
|
+
return assets;
|
|
313
341
|
}
|
|
314
|
-
async
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
try {
|
|
319
|
-
const balance = await this.getTokenBalance(address, tokenAddress);
|
|
320
|
-
if (balance > 0n) {
|
|
321
|
-
tokenBalances.push({
|
|
322
|
-
tokenAddress,
|
|
323
|
-
balance,
|
|
324
|
-
metadata
|
|
325
|
-
});
|
|
326
|
-
}
|
|
327
|
-
} catch (error) {
|
|
328
|
-
console.warn(`Failed to get balance for token ${tokenAddress}: ${error}`);
|
|
342
|
+
async getAsset(identifier) {
|
|
343
|
+
try {
|
|
344
|
+
if (identifier === this.chain.nativeToken.identifier) {
|
|
345
|
+
return this.chain.nativeToken;
|
|
329
346
|
}
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
try {
|
|
335
|
-
const metadata = await this.getTokenMetadata(tokenAddress);
|
|
336
|
-
const balance = await this.getTokenBalance(address, tokenAddress);
|
|
337
|
-
if (balance > 0n) {
|
|
338
|
-
tokenBalances.push({
|
|
339
|
-
tokenAddress,
|
|
340
|
-
balance,
|
|
341
|
-
metadata
|
|
342
|
-
});
|
|
343
|
-
}
|
|
344
|
-
} catch (error) {
|
|
345
|
-
console.warn(`Failed to get metadata/balance for detected token ${tokenAddress}: ${error}`);
|
|
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;
|
|
347
351
|
}
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
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;
|
|
356
376
|
} catch (error) {
|
|
357
|
-
|
|
377
|
+
return null;
|
|
358
378
|
}
|
|
359
379
|
}
|
|
360
|
-
async
|
|
380
|
+
async getAction(identifier, awaitCompleted = false) {
|
|
361
381
|
try {
|
|
362
|
-
const
|
|
363
|
-
|
|
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");
|
|
364
389
|
return {
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
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
|
+
}
|
|
368
411
|
};
|
|
369
412
|
} catch (error) {
|
|
370
|
-
|
|
413
|
+
return null;
|
|
371
414
|
}
|
|
372
415
|
}
|
|
373
|
-
async
|
|
374
|
-
|
|
375
|
-
const currentBlock = await this.provider.getBlockNumber();
|
|
376
|
-
const fromBlock = Math.max(0, currentBlock - 1e4);
|
|
377
|
-
const filter = {
|
|
378
|
-
fromBlock,
|
|
379
|
-
toBlock: currentBlock,
|
|
380
|
-
topics: [
|
|
381
|
-
ethers2.id("Transfer(address,address,uint256)"),
|
|
382
|
-
null,
|
|
383
|
-
// from address (any)
|
|
384
|
-
ethers2.zeroPadValue(address, 32)
|
|
385
|
-
// to address (our target)
|
|
386
|
-
]
|
|
387
|
-
};
|
|
388
|
-
const logs = await this.provider.getLogs(filter);
|
|
389
|
-
const tokenAddresses = /* @__PURE__ */ new Set();
|
|
390
|
-
for (const log of logs) {
|
|
391
|
-
tokenAddresses.add(log.address);
|
|
392
|
-
}
|
|
393
|
-
return Array.from(tokenAddresses);
|
|
394
|
-
} catch (error) {
|
|
395
|
-
console.warn(`Failed to detect tokens from events: ${error}`);
|
|
396
|
-
return [];
|
|
397
|
-
}
|
|
416
|
+
async getAccountActions(address, options) {
|
|
417
|
+
return [];
|
|
398
418
|
}
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
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
|
+
}));
|
|
407
432
|
}
|
|
408
|
-
async
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
throw new Error(`Failed to get token balance for ${tokenAddress}: ${error}`);
|
|
413
|
-
}
|
|
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;
|
|
414
437
|
}
|
|
415
|
-
async
|
|
416
|
-
const
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
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
|
+
};
|
|
429
455
|
}
|
|
430
456
|
};
|
|
431
457
|
|
|
432
458
|
// src/WarpEvmExecutor.ts
|
|
433
459
|
import {
|
|
434
|
-
|
|
460
|
+
applyOutputToMessages,
|
|
435
461
|
getNextInfo,
|
|
436
|
-
|
|
462
|
+
getProviderConfig as getProviderConfig3,
|
|
463
|
+
getWarpActionByIndex,
|
|
464
|
+
getWarpWalletAddressFromConfig as getWarpWalletAddressFromConfig2
|
|
437
465
|
} from "@vleap/warps";
|
|
438
466
|
import { ethers as ethers4 } from "ethers";
|
|
439
467
|
|
|
@@ -444,6 +472,8 @@ var WarpEvmConstants = {
|
|
|
444
472
|
ContractCall: 1e5,
|
|
445
473
|
ContractDeploy: 5e5,
|
|
446
474
|
Transfer: 21e3,
|
|
475
|
+
TokenTransfer: 65e3,
|
|
476
|
+
// ERC-20 transfer gas limit
|
|
447
477
|
Approve: 46e3,
|
|
448
478
|
Swap: 2e5
|
|
449
479
|
},
|
|
@@ -510,19 +540,22 @@ var ExplorerUrls = {
|
|
|
510
540
|
["blockscout_base_sepolia" /* BlockscoutBaseSepolia */]: "https://sepolia.blockscout.com"
|
|
511
541
|
};
|
|
512
542
|
|
|
513
|
-
// src/
|
|
543
|
+
// src/WarpEvmOutput.ts
|
|
514
544
|
import {
|
|
515
|
-
|
|
516
|
-
|
|
545
|
+
evaluateOutputCommon,
|
|
546
|
+
getProviderConfig as getProviderConfig2,
|
|
547
|
+
getWarpWalletAddressFromConfig,
|
|
548
|
+
parseOutputOutIndex,
|
|
517
549
|
WarpConstants as WarpConstants2
|
|
518
550
|
} from "@vleap/warps";
|
|
551
|
+
import { ethers as ethers3 } from "ethers";
|
|
519
552
|
|
|
520
553
|
// src/WarpEvmSerializer.ts
|
|
521
554
|
import {
|
|
522
555
|
WarpConstants,
|
|
523
556
|
WarpSerializer
|
|
524
557
|
} from "@vleap/warps";
|
|
525
|
-
import { ethers as
|
|
558
|
+
import { ethers as ethers2 } from "ethers";
|
|
526
559
|
var SplitParamsRegex = new RegExp(`${WarpConstants.ArgParamsSeparator}(.*)`);
|
|
527
560
|
var WarpEvmSerializer = class {
|
|
528
561
|
constructor() {
|
|
@@ -530,10 +563,10 @@ var WarpEvmSerializer = class {
|
|
|
530
563
|
}
|
|
531
564
|
typedToString(value) {
|
|
532
565
|
if (typeof value === "string") {
|
|
533
|
-
if (
|
|
566
|
+
if (ethers2.isAddress(value)) {
|
|
534
567
|
return `address:${value}`;
|
|
535
568
|
}
|
|
536
|
-
if (
|
|
569
|
+
if (ethers2.isHexString(value) && !ethers2.isAddress(value)) {
|
|
537
570
|
return `hex:${value}`;
|
|
538
571
|
}
|
|
539
572
|
return `string:${value}`;
|
|
@@ -672,13 +705,61 @@ var WarpEvmSerializer = class {
|
|
|
672
705
|
}
|
|
673
706
|
};
|
|
674
707
|
|
|
675
|
-
// src/
|
|
676
|
-
var
|
|
677
|
-
constructor(config) {
|
|
708
|
+
// src/WarpEvmOutput.ts
|
|
709
|
+
var WarpEvmOutput = class {
|
|
710
|
+
constructor(config, chain) {
|
|
678
711
|
this.config = config;
|
|
712
|
+
this.chain = chain;
|
|
679
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);
|
|
680
717
|
}
|
|
681
|
-
async
|
|
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
|
+
status: "error",
|
|
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
|
+
output: {},
|
|
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
|
+
status: success ? "success" : "error",
|
|
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
|
+
output: {},
|
|
759
|
+
messages: {}
|
|
760
|
+
};
|
|
761
|
+
}
|
|
762
|
+
handleTransactionReceipt(warp, actionIndex, tx) {
|
|
682
763
|
const success = tx.status === 1;
|
|
683
764
|
const gasUsed = tx.gasUsed?.toString() || "0";
|
|
684
765
|
const gasPrice = tx.gasPrice?.toString() || "0";
|
|
@@ -686,63 +767,92 @@ var WarpEvmResults = class {
|
|
|
686
767
|
const transactionHash = tx.hash;
|
|
687
768
|
const logs = tx.logs.map((log) => ({
|
|
688
769
|
address: log.address,
|
|
689
|
-
topics: log.topics,
|
|
770
|
+
topics: [...log.topics],
|
|
690
771
|
data: log.data,
|
|
691
772
|
blockNumber: log.blockNumber?.toString() || "0",
|
|
692
773
|
transactionHash: log.transactionHash,
|
|
693
774
|
index: log.index?.toString() || "0"
|
|
694
775
|
}));
|
|
776
|
+
const rawValues = [transactionHash, blockNumber, gasUsed, gasPrice, ...logs.length > 0 ? logs : []];
|
|
777
|
+
const stringValues = rawValues.map(String);
|
|
695
778
|
return {
|
|
696
|
-
success,
|
|
779
|
+
status: success ? "success" : "error",
|
|
697
780
|
warp,
|
|
698
|
-
action:
|
|
699
|
-
user: this.config.
|
|
781
|
+
action: actionIndex,
|
|
782
|
+
user: getWarpWalletAddressFromConfig(this.config, this.chain.name),
|
|
700
783
|
txHash: transactionHash,
|
|
784
|
+
tx,
|
|
701
785
|
next: null,
|
|
702
|
-
values:
|
|
703
|
-
|
|
786
|
+
values: { string: stringValues, native: rawValues },
|
|
787
|
+
output: {},
|
|
704
788
|
messages: {}
|
|
705
789
|
};
|
|
706
790
|
}
|
|
707
|
-
async
|
|
708
|
-
const
|
|
709
|
-
const
|
|
710
|
-
|
|
711
|
-
|
|
791
|
+
async extractQueryOutput(warp, typedValues, actionIndex, inputs) {
|
|
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 };
|
|
795
|
+
let output = {};
|
|
796
|
+
if (!warp.output) return { values, output };
|
|
712
797
|
const getNestedValue = (path) => {
|
|
713
798
|
const indices = path.split(".").slice(1).map((i) => parseInt(i) - 1);
|
|
714
799
|
if (indices.length === 0) return void 0;
|
|
715
|
-
let value =
|
|
800
|
+
let value = nativeValues[indices[0]];
|
|
716
801
|
for (let i = 1; i < indices.length; i++) {
|
|
717
802
|
if (value === void 0 || value === null) return void 0;
|
|
718
803
|
value = value[indices[i]];
|
|
719
804
|
}
|
|
720
805
|
return value;
|
|
721
806
|
};
|
|
722
|
-
for (const [key, path] of Object.entries(warp.
|
|
807
|
+
for (const [key, path] of Object.entries(warp.output)) {
|
|
723
808
|
if (path.startsWith(WarpConstants2.Transform.Prefix)) continue;
|
|
724
|
-
const currentActionIndex =
|
|
809
|
+
const currentActionIndex = parseOutputOutIndex(path);
|
|
725
810
|
if (currentActionIndex !== null && currentActionIndex !== actionIndex) {
|
|
726
|
-
|
|
811
|
+
output[key] = null;
|
|
727
812
|
continue;
|
|
728
813
|
}
|
|
729
814
|
if (path.startsWith("out.") || path === "out" || path.startsWith("out[")) {
|
|
730
|
-
|
|
815
|
+
output[key] = getNestedValue(path) || null;
|
|
731
816
|
} else {
|
|
732
|
-
|
|
817
|
+
output[key] = path;
|
|
818
|
+
}
|
|
819
|
+
}
|
|
820
|
+
return { values, output: await evaluateOutputCommon(warp, output, 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" };
|
|
733
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;
|
|
734
842
|
}
|
|
735
|
-
return { values, results: await evaluateResultsCommon(warp, results, actionIndex, inputs) };
|
|
736
843
|
}
|
|
737
844
|
};
|
|
738
845
|
|
|
739
846
|
// src/WarpEvmExecutor.ts
|
|
740
847
|
var WarpEvmExecutor = class {
|
|
741
|
-
constructor(config) {
|
|
848
|
+
constructor(config, chain) {
|
|
742
849
|
this.config = config;
|
|
850
|
+
this.chain = chain;
|
|
743
851
|
this.serializer = new WarpEvmSerializer();
|
|
744
|
-
|
|
745
|
-
|
|
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.output = new WarpEvmOutput(config, this.chain);
|
|
746
856
|
}
|
|
747
857
|
async createTransaction(executable) {
|
|
748
858
|
const action = getWarpActionByIndex(executable.warp, executable.action);
|
|
@@ -760,13 +870,13 @@ var WarpEvmExecutor = class {
|
|
|
760
870
|
return tx;
|
|
761
871
|
}
|
|
762
872
|
async createTransferTransaction(executable) {
|
|
763
|
-
const userWallet = this.config
|
|
873
|
+
const userWallet = getWarpWalletAddressFromConfig2(this.config, executable.chain.name);
|
|
764
874
|
if (!userWallet) throw new Error("WarpEvmExecutor: createTransfer - user address not set");
|
|
765
875
|
if (!ethers4.isAddress(executable.destination)) {
|
|
766
876
|
throw new Error(`WarpEvmExecutor: Invalid destination address: ${executable.destination}`);
|
|
767
877
|
}
|
|
768
|
-
if (executable.
|
|
769
|
-
|
|
878
|
+
if (executable.transfers && executable.transfers.length > 0) {
|
|
879
|
+
return this.createTokenTransferTransaction(executable, userWallet);
|
|
770
880
|
}
|
|
771
881
|
const tx = {
|
|
772
882
|
to: executable.destination,
|
|
@@ -776,21 +886,20 @@ var WarpEvmExecutor = class {
|
|
|
776
886
|
return this.estimateGasAndSetDefaults(tx, userWallet);
|
|
777
887
|
}
|
|
778
888
|
async createContractCallTransaction(executable) {
|
|
779
|
-
const userWallet = this.config
|
|
889
|
+
const userWallet = getWarpWalletAddressFromConfig2(this.config, executable.chain.name);
|
|
780
890
|
if (!userWallet) throw new Error("WarpEvmExecutor: createContractCall - user address not set");
|
|
781
891
|
const action = getWarpActionByIndex(executable.warp, executable.action);
|
|
782
|
-
if (!action || !("func" in action) || !action.func)
|
|
783
|
-
|
|
784
|
-
}
|
|
785
|
-
if (!ethers4.isAddress(executable.destination)) {
|
|
786
|
-
throw new Error(`WarpEvmExecutor: Invalid contract address: ${executable.destination}`);
|
|
787
|
-
}
|
|
788
|
-
if (executable.value < 0) {
|
|
789
|
-
throw new Error(`WarpEvmExecutor: Contract call value cannot be negative: ${executable.value}`);
|
|
790
|
-
}
|
|
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}`);
|
|
791
894
|
try {
|
|
792
|
-
|
|
793
|
-
|
|
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);
|
|
794
903
|
const tx = {
|
|
795
904
|
to: executable.destination,
|
|
796
905
|
value: executable.value,
|
|
@@ -801,101 +910,107 @@ var WarpEvmExecutor = class {
|
|
|
801
910
|
throw new Error(`WarpEvmExecutor: Failed to encode function data for ${action.func}: ${error}`);
|
|
802
911
|
}
|
|
803
912
|
}
|
|
804
|
-
async
|
|
805
|
-
|
|
806
|
-
if (
|
|
807
|
-
|
|
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);
|
|
808
927
|
}
|
|
809
|
-
if (
|
|
810
|
-
|
|
928
|
+
if (nativeTokenTransfers.length === 0 && erc20Transfers.length === 1) {
|
|
929
|
+
return this.createSingleTokenTransfer(executable, erc20Transfers[0], userWallet);
|
|
811
930
|
}
|
|
812
|
-
if (
|
|
813
|
-
|
|
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}`);
|
|
814
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}`);
|
|
815
952
|
try {
|
|
816
|
-
|
|
817
|
-
|
|
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);
|
|
818
961
|
const result = await this.provider.call({
|
|
819
962
|
to: executable.destination,
|
|
820
963
|
data: encodedData
|
|
821
964
|
});
|
|
822
965
|
const decodedResult = iface.decodeFunctionResult(action.func, result);
|
|
823
966
|
const isSuccess = true;
|
|
824
|
-
const { values,
|
|
967
|
+
const { values, output } = await this.output.extractQueryOutput(
|
|
825
968
|
executable.warp,
|
|
826
969
|
decodedResult,
|
|
827
970
|
executable.action,
|
|
828
971
|
executable.resolvedInputs
|
|
829
972
|
);
|
|
830
|
-
const next = getNextInfo(this.config, [], executable.warp, executable.action,
|
|
973
|
+
const next = getNextInfo(this.config, [], executable.warp, executable.action, output);
|
|
831
974
|
return {
|
|
832
|
-
success:
|
|
975
|
+
status: isSuccess ? "success" : "error",
|
|
833
976
|
warp: executable.warp,
|
|
834
977
|
action: executable.action,
|
|
835
|
-
user: this.config
|
|
978
|
+
user: getWarpWalletAddressFromConfig2(this.config, executable.chain.name),
|
|
836
979
|
txHash: null,
|
|
980
|
+
tx: null,
|
|
837
981
|
next,
|
|
838
982
|
values,
|
|
839
|
-
|
|
840
|
-
messages:
|
|
983
|
+
output: { ...output, _DATA: decodedResult },
|
|
984
|
+
messages: applyOutputToMessages(executable.warp, output, this.config)
|
|
841
985
|
};
|
|
842
986
|
} catch (error) {
|
|
843
987
|
return {
|
|
844
|
-
|
|
988
|
+
status: "error",
|
|
845
989
|
warp: executable.warp,
|
|
846
990
|
action: executable.action,
|
|
847
|
-
user: this.config
|
|
991
|
+
user: getWarpWalletAddressFromConfig2(this.config, executable.chain.name),
|
|
848
992
|
txHash: null,
|
|
993
|
+
tx: null,
|
|
849
994
|
next: null,
|
|
850
|
-
values: [],
|
|
851
|
-
|
|
995
|
+
values: { string: [], native: [] },
|
|
996
|
+
output: { _DATA: error },
|
|
852
997
|
messages: {}
|
|
853
998
|
};
|
|
854
999
|
}
|
|
855
1000
|
}
|
|
856
|
-
async preprocessInput(chain, input, type, value) {
|
|
857
|
-
const typedValue = this.serializer.stringToTyped(value);
|
|
858
|
-
switch (type) {
|
|
859
|
-
case "address":
|
|
860
|
-
if (!ethers4.isAddress(typedValue)) {
|
|
861
|
-
throw new Error(`Invalid address format: ${typedValue}`);
|
|
862
|
-
}
|
|
863
|
-
return ethers4.getAddress(typedValue);
|
|
864
|
-
case "hex":
|
|
865
|
-
if (!ethers4.isHexString(typedValue)) {
|
|
866
|
-
throw new Error(`Invalid hex format: ${typedValue}`);
|
|
867
|
-
}
|
|
868
|
-
return typedValue;
|
|
869
|
-
case "uint8":
|
|
870
|
-
case "uint16":
|
|
871
|
-
case "uint32":
|
|
872
|
-
case "uint64":
|
|
873
|
-
case "biguint":
|
|
874
|
-
const bigIntValue = BigInt(typedValue);
|
|
875
|
-
if (bigIntValue < 0) {
|
|
876
|
-
throw new Error(`Negative value not allowed for type ${type}: ${typedValue}`);
|
|
877
|
-
}
|
|
878
|
-
return bigIntValue.toString();
|
|
879
|
-
default:
|
|
880
|
-
return String(typedValue);
|
|
881
|
-
}
|
|
882
|
-
}
|
|
883
1001
|
async estimateGasAndSetDefaults(tx, from) {
|
|
884
1002
|
try {
|
|
885
1003
|
const gasEstimate = await this.provider.estimateGas({
|
|
886
1004
|
...tx,
|
|
887
1005
|
from
|
|
888
1006
|
});
|
|
889
|
-
if (gasEstimate < BigInt(WarpEvmConstants.Validation.MinGasLimit)) {
|
|
890
|
-
|
|
891
|
-
}
|
|
892
|
-
if (gasEstimate > BigInt(WarpEvmConstants.Validation.MaxGasLimit)) {
|
|
893
|
-
throw new Error(`Gas estimate too high: ${gasEstimate}`);
|
|
894
|
-
}
|
|
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}`);
|
|
895
1009
|
const feeData = await this.provider.getFeeData();
|
|
896
1010
|
if (feeData.maxFeePerGas && feeData.maxPriorityFeePerGas) {
|
|
897
1011
|
return {
|
|
898
1012
|
...tx,
|
|
1013
|
+
chainId: parseInt(this.chain.chainId),
|
|
899
1014
|
gasLimit: gasEstimate,
|
|
900
1015
|
maxFeePerGas: feeData.maxFeePerGas,
|
|
901
1016
|
maxPriorityFeePerGas: feeData.maxPriorityFeePerGas
|
|
@@ -903,12 +1018,14 @@ var WarpEvmExecutor = class {
|
|
|
903
1018
|
} else if (feeData.gasPrice) {
|
|
904
1019
|
return {
|
|
905
1020
|
...tx,
|
|
1021
|
+
chainId: parseInt(this.chain.chainId),
|
|
906
1022
|
gasLimit: gasEstimate,
|
|
907
1023
|
gasPrice: feeData.gasPrice
|
|
908
1024
|
};
|
|
909
1025
|
} else {
|
|
910
1026
|
return {
|
|
911
1027
|
...tx,
|
|
1028
|
+
chainId: parseInt(this.chain.chainId),
|
|
912
1029
|
gasLimit: gasEstimate,
|
|
913
1030
|
gasPrice: ethers4.parseUnits(WarpEvmConstants.GasPrice.Default, "wei")
|
|
914
1031
|
};
|
|
@@ -916,19 +1033,29 @@ var WarpEvmExecutor = class {
|
|
|
916
1033
|
} catch (error) {
|
|
917
1034
|
let defaultGasLimit = BigInt(WarpEvmConstants.GasLimit.Default);
|
|
918
1035
|
if (tx.data && tx.data !== "0x") {
|
|
919
|
-
|
|
1036
|
+
if (tx.data.startsWith("0xa9059cbb")) {
|
|
1037
|
+
defaultGasLimit = BigInt(WarpEvmConstants.GasLimit.TokenTransfer);
|
|
1038
|
+
} else {
|
|
1039
|
+
defaultGasLimit = BigInt(WarpEvmConstants.GasLimit.ContractCall);
|
|
1040
|
+
}
|
|
920
1041
|
} else {
|
|
921
1042
|
defaultGasLimit = BigInt(WarpEvmConstants.GasLimit.Transfer);
|
|
922
1043
|
}
|
|
923
1044
|
return {
|
|
924
1045
|
...tx,
|
|
1046
|
+
chainId: parseInt(this.chain.chainId),
|
|
925
1047
|
gasLimit: defaultGasLimit,
|
|
926
1048
|
gasPrice: ethers4.parseUnits(WarpEvmConstants.GasPrice.Default, "wei")
|
|
927
1049
|
};
|
|
928
1050
|
}
|
|
929
1051
|
}
|
|
930
|
-
async
|
|
931
|
-
|
|
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
|
+
}
|
|
932
1059
|
}
|
|
933
1060
|
};
|
|
934
1061
|
|
|
@@ -1016,155 +1143,379 @@ var WarpEvmExplorer = class {
|
|
|
1016
1143
|
});
|
|
1017
1144
|
return urls;
|
|
1018
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
|
+
}
|
|
1179
|
+
};
|
|
1180
|
+
|
|
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
|
+
}
|
|
1019
1277
|
};
|
|
1020
1278
|
|
|
1021
1279
|
// src/chains/common.ts
|
|
1022
|
-
var createEvmAdapter = (chainName,
|
|
1280
|
+
var createEvmAdapter = (chainName, chainInfos) => {
|
|
1023
1281
|
return (config, fallback) => {
|
|
1024
1282
|
if (!fallback) throw new Error(`${chainName} adapter requires a fallback adapter`);
|
|
1025
1283
|
return {
|
|
1026
|
-
chain: chainName,
|
|
1027
1284
|
chainInfo: chainInfos[config.env],
|
|
1028
|
-
|
|
1029
|
-
|
|
1030
|
-
|
|
1031
|
-
results: new WarpEvmResults(config),
|
|
1285
|
+
builder: () => fallback.builder(),
|
|
1286
|
+
executor: new WarpEvmExecutor(config, chainInfos[config.env]),
|
|
1287
|
+
output: new WarpEvmOutput(config, chainInfos[config.env]),
|
|
1032
1288
|
serializer: new WarpEvmSerializer(),
|
|
1033
1289
|
registry: fallback.registry,
|
|
1034
1290
|
explorer: new WarpEvmExplorer(chainInfos[config.env], config),
|
|
1035
1291
|
abiBuilder: () => fallback.abiBuilder(),
|
|
1036
1292
|
brandBuilder: () => fallback.brandBuilder(),
|
|
1037
|
-
dataLoader: new WarpEvmDataLoader(config, chainInfos[config.env])
|
|
1293
|
+
dataLoader: new WarpEvmDataLoader(config, chainInfos[config.env]),
|
|
1294
|
+
wallet: new WarpEvmWallet(config, chainInfos[config.env])
|
|
1038
1295
|
};
|
|
1039
1296
|
};
|
|
1040
1297
|
};
|
|
1041
1298
|
|
|
1042
1299
|
// src/chains/arbitrum.ts
|
|
1043
|
-
var
|
|
1044
|
-
|
|
1045
|
-
|
|
1046
|
-
|
|
1047
|
-
|
|
1048
|
-
|
|
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",
|
|
1049
1313
|
blockTime: 1e3,
|
|
1050
1314
|
addressHrp: "0x",
|
|
1051
|
-
|
|
1052
|
-
|
|
1315
|
+
defaultApiUrl: "https://arb1.arbitrum.io/rpc",
|
|
1316
|
+
logoUrl: "https://vleap.ai/images/chains/arbitrum.svg",
|
|
1317
|
+
nativeToken: NativeTokenArb
|
|
1053
1318
|
},
|
|
1054
1319
|
testnet: {
|
|
1055
|
-
name:
|
|
1056
|
-
displayName: "Arbitrum
|
|
1057
|
-
chainId: "
|
|
1320
|
+
name: WarpChainName6.Arbitrum,
|
|
1321
|
+
displayName: "Arbitrum Sepolia",
|
|
1322
|
+
chainId: "421614",
|
|
1058
1323
|
blockTime: 1e3,
|
|
1059
1324
|
addressHrp: "0x",
|
|
1060
|
-
|
|
1061
|
-
|
|
1325
|
+
defaultApiUrl: "https://sepolia-rollup.arbitrum.io/rpc",
|
|
1326
|
+
logoUrl: "https://vleap.ai/images/chains/arbitrum.svg",
|
|
1327
|
+
nativeToken: NativeTokenArb
|
|
1062
1328
|
},
|
|
1063
|
-
|
|
1064
|
-
name:
|
|
1065
|
-
displayName: "Arbitrum",
|
|
1066
|
-
chainId: "
|
|
1329
|
+
devnet: {
|
|
1330
|
+
name: WarpChainName6.Arbitrum,
|
|
1331
|
+
displayName: "Arbitrum Sepolia",
|
|
1332
|
+
chainId: "421614",
|
|
1067
1333
|
blockTime: 1e3,
|
|
1068
1334
|
addressHrp: "0x",
|
|
1069
|
-
|
|
1070
|
-
|
|
1335
|
+
defaultApiUrl: "https://sepolia-rollup.arbitrum.io/rpc",
|
|
1336
|
+
logoUrl: "https://vleap.ai/images/chains/arbitrum.svg",
|
|
1337
|
+
nativeToken: NativeTokenArb
|
|
1071
1338
|
}
|
|
1072
1339
|
});
|
|
1073
1340
|
|
|
1074
1341
|
// src/chains/base.ts
|
|
1075
|
-
|
|
1076
|
-
var
|
|
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, {
|
|
1077
1352
|
mainnet: {
|
|
1078
|
-
name:
|
|
1353
|
+
name: WarpChainName7.Base,
|
|
1079
1354
|
displayName: "Base",
|
|
1080
1355
|
chainId: "8453",
|
|
1081
1356
|
blockTime: 2e3,
|
|
1082
1357
|
addressHrp: "0x",
|
|
1083
|
-
|
|
1084
|
-
|
|
1358
|
+
defaultApiUrl: "https://mainnet.base.org",
|
|
1359
|
+
logoUrl: "https://vleap.ai/images/chains/base.svg",
|
|
1360
|
+
nativeToken: NativeTokenBase
|
|
1085
1361
|
},
|
|
1086
1362
|
testnet: {
|
|
1087
|
-
name:
|
|
1088
|
-
displayName: "Base
|
|
1089
|
-
chainId: "
|
|
1363
|
+
name: WarpChainName7.Base,
|
|
1364
|
+
displayName: "Base Sepolia",
|
|
1365
|
+
chainId: "84532",
|
|
1090
1366
|
blockTime: 2e3,
|
|
1091
1367
|
addressHrp: "0x",
|
|
1092
|
-
|
|
1093
|
-
|
|
1368
|
+
defaultApiUrl: "https://sepolia.base.org",
|
|
1369
|
+
logoUrl: "https://vleap.ai/images/chains/base.svg",
|
|
1370
|
+
nativeToken: NativeTokenBase
|
|
1094
1371
|
},
|
|
1095
1372
|
devnet: {
|
|
1096
|
-
name:
|
|
1097
|
-
displayName: "Base
|
|
1373
|
+
name: WarpChainName7.Base,
|
|
1374
|
+
displayName: "Base Sepolia",
|
|
1098
1375
|
chainId: "84532",
|
|
1099
1376
|
blockTime: 2e3,
|
|
1100
1377
|
addressHrp: "0x",
|
|
1101
|
-
|
|
1102
|
-
|
|
1378
|
+
defaultApiUrl: "https://sepolia.base.org",
|
|
1379
|
+
logoUrl: "https://vleap.ai/images/chains/base.svg",
|
|
1380
|
+
nativeToken: NativeTokenBase
|
|
1103
1381
|
}
|
|
1104
1382
|
});
|
|
1105
1383
|
|
|
1384
|
+
// src/chains/combined.ts
|
|
1385
|
+
import { WarpChainName as WarpChainName10 } from "@vleap/warps";
|
|
1386
|
+
|
|
1106
1387
|
// src/chains/ethereum.ts
|
|
1107
|
-
|
|
1108
|
-
var
|
|
1109
|
-
|
|
1110
|
-
|
|
1111
|
-
|
|
1112
|
-
|
|
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",
|
|
1113
1402
|
blockTime: 12e3,
|
|
1114
1403
|
addressHrp: "0x",
|
|
1115
|
-
|
|
1116
|
-
|
|
1404
|
+
defaultApiUrl: "https://ethereum-rpc.publicnode.com",
|
|
1405
|
+
logoUrl: "https://vleap.ai/images/chains/ethereum.svg",
|
|
1406
|
+
nativeToken: NativeTokenEth
|
|
1117
1407
|
},
|
|
1118
1408
|
testnet: {
|
|
1119
|
-
name:
|
|
1120
|
-
displayName: "Ethereum
|
|
1121
|
-
chainId: "
|
|
1409
|
+
name: WarpChainName8.Ethereum,
|
|
1410
|
+
displayName: "Ethereum Sepolia",
|
|
1411
|
+
chainId: "11155111",
|
|
1122
1412
|
blockTime: 12e3,
|
|
1123
1413
|
addressHrp: "0x",
|
|
1124
|
-
|
|
1125
|
-
|
|
1414
|
+
defaultApiUrl: "https://ethereum-sepolia-rpc.publicnode.com",
|
|
1415
|
+
logoUrl: "https://vleap.ai/images/chains/ethereum.svg",
|
|
1416
|
+
nativeToken: NativeTokenEth
|
|
1126
1417
|
},
|
|
1127
|
-
|
|
1128
|
-
name:
|
|
1129
|
-
displayName: "Ethereum
|
|
1130
|
-
chainId: "
|
|
1418
|
+
devnet: {
|
|
1419
|
+
name: WarpChainName8.Ethereum,
|
|
1420
|
+
displayName: "Ethereum Sepolia",
|
|
1421
|
+
chainId: "11155111",
|
|
1131
1422
|
blockTime: 12e3,
|
|
1132
1423
|
addressHrp: "0x",
|
|
1133
|
-
|
|
1134
|
-
|
|
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
|
|
1135
1478
|
}
|
|
1136
1479
|
});
|
|
1137
1480
|
|
|
1138
1481
|
// src/chains/combined.ts
|
|
1139
1482
|
var getAllEvmAdapters = (config, fallback) => [
|
|
1140
1483
|
getEthereumAdapter(config, fallback),
|
|
1484
|
+
getBaseAdapter(config, fallback),
|
|
1141
1485
|
getArbitrumAdapter(config, fallback),
|
|
1142
|
-
|
|
1486
|
+
getSomniaAdapter(config, fallback)
|
|
1487
|
+
];
|
|
1488
|
+
var getAllEvmChainNames = () => [
|
|
1489
|
+
WarpChainName10.Ethereum,
|
|
1490
|
+
WarpChainName10.Base,
|
|
1491
|
+
WarpChainName10.Arbitrum,
|
|
1492
|
+
WarpChainName10.Somnia
|
|
1143
1493
|
];
|
|
1144
|
-
var getAllEvmChainNames = () => [ChainNameArbitrum, ChainNameBase, ChainNameEthereum];
|
|
1145
1494
|
export {
|
|
1146
1495
|
ArbitrumExplorers,
|
|
1147
1496
|
BaseExplorers,
|
|
1148
|
-
ChainNameArbitrum,
|
|
1149
|
-
ChainNameBase,
|
|
1150
|
-
ChainNameEthereum,
|
|
1151
|
-
EVM_CHAIN_CONFIGS,
|
|
1152
1497
|
EthereumExplorers,
|
|
1153
1498
|
EvmExplorers,
|
|
1154
1499
|
ExplorerUrls,
|
|
1155
|
-
|
|
1500
|
+
KnownTokens,
|
|
1501
|
+
NativeTokenArb,
|
|
1502
|
+
NativeTokenBase,
|
|
1503
|
+
NativeTokenEth,
|
|
1504
|
+
UniswapService,
|
|
1156
1505
|
WarpEvmConstants,
|
|
1506
|
+
WarpEvmDataLoader,
|
|
1157
1507
|
WarpEvmExecutor,
|
|
1158
1508
|
WarpEvmExplorer,
|
|
1159
|
-
|
|
1509
|
+
WarpEvmOutput,
|
|
1160
1510
|
WarpEvmSerializer,
|
|
1511
|
+
WarpEvmWallet,
|
|
1512
|
+
createEvmAdapter,
|
|
1513
|
+
findKnownTokenById,
|
|
1161
1514
|
getAllEvmAdapters,
|
|
1162
1515
|
getAllEvmChainNames,
|
|
1163
1516
|
getArbitrumAdapter,
|
|
1164
1517
|
getBaseAdapter,
|
|
1165
1518
|
getEthereumAdapter,
|
|
1166
|
-
|
|
1167
|
-
getEvmChainConfig,
|
|
1168
|
-
getEvmExplorerUrl
|
|
1519
|
+
getKnownTokensForChain
|
|
1169
1520
|
};
|
|
1170
1521
|
//# sourceMappingURL=index.mjs.map
|