tollkit-wallet 0.2.2 → 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/actions.d.ts +136 -40
- package/dist/ai.d.ts +13 -1
- package/dist/ai.js +2 -2
- package/dist/ai.js.map +1 -1
- package/dist/autopilot.d.ts +7 -0
- package/dist/autopilot.js +118 -3
- package/dist/autopilot.js.map +1 -1
- package/dist/bots.d.ts +92 -0
- package/dist/bots.js +183 -0
- package/dist/bots.js.map +1 -0
- package/dist/bridge.js +3 -2
- package/dist/bridge.js.map +1 -1
- package/dist/dapp.d.ts +10 -0
- package/dist/dapp.js +80 -13
- package/dist/dapp.js.map +1 -1
- package/dist/dashboard.d.ts +12 -0
- package/dist/dashboard.js +127 -14
- package/dist/dashboard.js.map +1 -1
- package/dist/data/token-list.d.ts +12 -0
- package/dist/data/token-list.js +13 -0
- package/dist/data/token-list.js.map +1 -0
- package/dist/holdings.d.ts +6 -0
- package/dist/holdings.js +41 -8
- package/dist/holdings.js.map +1 -1
- package/dist/mcp.d.ts +1 -1
- package/dist/mcp.js +1 -1
- package/dist/pay.js +1 -1
- package/dist/pay.js.map +1 -1
- package/dist/policy.d.ts +2 -2
- package/dist/rules.d.ts +59 -8
- package/dist/rules.js +45 -3
- package/dist/rules.js.map +1 -1
- package/dist/seller.js +15 -4
- package/dist/seller.js.map +1 -1
- package/dist/send.js +3 -2
- package/dist/send.js.map +1 -1
- package/dist/solconfirm.d.ts +13 -0
- package/dist/solconfirm.js +21 -0
- package/dist/solconfirm.js.map +1 -0
- package/dist/stake.js +3 -2
- package/dist/stake.js.map +1 -1
- package/dist/swap.d.ts +27 -4
- package/dist/swap.js +202 -9
- package/dist/swap.js.map +1 -1
- package/dist/tokenlist.d.ts +70 -0
- package/dist/tokenlist.js +259 -0
- package/dist/tokenlist.js.map +1 -0
- package/dist/ui.js +98 -10
- package/dist/ui.js.map +1 -1
- package/dist/wallet.d.ts +3 -1
- package/dist/wallet.js +22 -1
- package/dist/wallet.js.map +1 -1
- package/extension/background.js +1 -1
- package/extension/popup.js +1 -1
- package/package.json +2 -2
package/dist/swap.js
CHANGED
|
@@ -4,12 +4,17 @@
|
|
|
4
4
|
* quote proxy (api.tollkit.dev/wallet/...), which holds the 0x and Jupiter API
|
|
5
5
|
* keys and adds the flat 0.5% fee; it only ever sees public data and signed
|
|
6
6
|
* transactions, never keys. The wallet checks every quote before signing:
|
|
7
|
-
* fee not above 0.5%, the only approval ever given is to 0x AllowanceHolder
|
|
8
|
-
*
|
|
7
|
+
* fee not above 0.5%, the only approval ever given is to 0x AllowanceHolder
|
|
8
|
+
* (exact amount), and the minimum output is set. It doesn't trust the quote
|
|
9
|
+
* server with what it signs (0.2.3): verifySwapTx decodes 0x calldata (exact
|
|
10
|
+
* token, amount and ETH value; the Settler call must pay this wallet the buy
|
|
11
|
+
* token with the minimum shown; Settler must be listed by 0x's on-chain
|
|
12
|
+
* registry, github.com/0xProject/0x-settler README), and simulates Solana
|
|
13
|
+
* swaps, refusing any that take more than the coin being sold.
|
|
9
14
|
*/
|
|
10
|
-
import { Connection, VersionedTransaction } from "@solana/web3.js";
|
|
11
|
-
import { Contract, JsonRpcProvider } from "ethers";
|
|
12
|
-
import { ALLOWANCE_HOLDER, DEFAULT_RPC, EVM_CHAIN_ID, STABLES, SWAP_FEE_BPS, isStable } from "./chains.js";
|
|
15
|
+
import { Connection, PublicKey, VersionedTransaction } from "@solana/web3.js";
|
|
16
|
+
import { AbiCoder, Contract, Interface, JsonRpcProvider, ZeroAddress } from "ethers";
|
|
17
|
+
import { ALLOWANCE_HOLDER, DEFAULT_RPC, EVM_CHAIN_ID, NATIVE_EVM, STABLES, SWAP_FEE_BPS, WSOL, isStable } from "./chains.js";
|
|
13
18
|
export const DEFAULT_PROXY = "https://api.tollkit.dev/wallet";
|
|
14
19
|
const decimalsOf = (chain, token) => (chain === "solana" ? STABLES.solana[token] : STABLES[chain][token.toLowerCase()])?.decimals;
|
|
15
20
|
async function getJson(f, url, init) {
|
|
@@ -61,7 +66,9 @@ function withUsd(q) {
|
|
|
61
66
|
return { ...q, usd_value: usd, fee_usd: usd === null ? null : (usd * q.fee_bps) / 10000 };
|
|
62
67
|
}
|
|
63
68
|
/** Everything the wallet refuses to sign. Returns a reason, or null if the quote is safe. */
|
|
64
|
-
export function vetQuote(q, req) {
|
|
69
|
+
export function vetQuote(q, req, taker) {
|
|
70
|
+
if (q.sell_amount !== req.sell_amount)
|
|
71
|
+
return "The quote is for a different amount than requested.";
|
|
65
72
|
if (q.fee_bps > SWAP_FEE_BPS)
|
|
66
73
|
return `The quote carries a ${q.fee_bps / 100}% fee; Tollkit's fee is ${SWAP_FEE_BPS / 100}%.`;
|
|
67
74
|
if (!(BigInt(q.min_buy_amount) > 0n))
|
|
@@ -75,8 +82,14 @@ export function vetQuote(q, req) {
|
|
|
75
82
|
const spender = q.raw?.issues?.allowance?.spender;
|
|
76
83
|
if (spender && String(spender).toLowerCase() !== ALLOWANCE_HOLDER.toLowerCase())
|
|
77
84
|
return `The quote asks to approve ${spender}; only 0x AllowanceHolder is ever approved.`;
|
|
78
|
-
if (
|
|
79
|
-
|
|
85
|
+
if (taker && tx.data !== undefined) {
|
|
86
|
+
try {
|
|
87
|
+
checkZeroExTx(q, taker);
|
|
88
|
+
}
|
|
89
|
+
catch (e) {
|
|
90
|
+
return e.message;
|
|
91
|
+
}
|
|
92
|
+
}
|
|
80
93
|
}
|
|
81
94
|
else {
|
|
82
95
|
if (!q.raw?.transaction || !q.raw?.requestId)
|
|
@@ -85,8 +98,188 @@ export function vetQuote(q, req) {
|
|
|
85
98
|
return null;
|
|
86
99
|
}
|
|
87
100
|
const ERC20 = ["function approve(address spender, uint256 amount) returns (bool)", "function allowance(address owner, address spender) view returns (uint256)"];
|
|
101
|
+
/** 0x Settler registry, the same address on every chain; feature 2 = taker-submitted swaps. */
|
|
102
|
+
export const SETTLER_REGISTRY = "0x00000000000004533Fe15556B1E086BB1A72cEae";
|
|
103
|
+
const ALLOWANCE_EXEC = new Interface(["function exec(address operator, address token, uint256 amount, address target, bytes data)"]);
|
|
104
|
+
const SETTLER_EXECUTE = "0x1fff991f"; // execute((address recipient, address buyToken, uint256 minAmountOut), bytes[], bytes32)
|
|
105
|
+
/** Decode a 0x quote's transaction and check it does only the swap shown. Returns the Settler address it uses. */
|
|
106
|
+
export function checkZeroExTx(q, taker) {
|
|
107
|
+
const t = q.raw?.transaction ?? {};
|
|
108
|
+
const native = q.sell_token.toLowerCase() === NATIVE_EVM.toLowerCase();
|
|
109
|
+
const value = BigInt(t.value ?? "0"), sell = BigInt(q.sell_amount);
|
|
110
|
+
if (String(t.to ?? "").toLowerCase() !== ALLOWANCE_HOLDER.toLowerCase())
|
|
111
|
+
throw new Error("The swap isn't sent to 0x AllowanceHolder.");
|
|
112
|
+
if (value !== (native ? sell : 0n))
|
|
113
|
+
throw new Error("The swap would send a different amount of ETH than you're selling.");
|
|
114
|
+
let p = null;
|
|
115
|
+
try {
|
|
116
|
+
p = ALLOWANCE_EXEC.parseTransaction({ data: String(t.data ?? "") });
|
|
117
|
+
}
|
|
118
|
+
catch {
|
|
119
|
+
p = null;
|
|
120
|
+
}
|
|
121
|
+
if (!p || p.name !== "exec")
|
|
122
|
+
throw new Error("The swap transaction isn't a 0x swap.");
|
|
123
|
+
const [operator, token, amount, target, inner] = p.args;
|
|
124
|
+
if (token.toLowerCase() !== (native ? ZeroAddress : q.sell_token).toLowerCase() || amount !== sell)
|
|
125
|
+
throw new Error("The swap would take a different coin or amount than you're selling.");
|
|
126
|
+
if (operator.toLowerCase() !== target.toLowerCase())
|
|
127
|
+
throw new Error("The swap transaction isn't a 0x swap.");
|
|
128
|
+
if (!inner.startsWith(SETTLER_EXECUTE) || inner.length < 10 + 64 * 3)
|
|
129
|
+
throw new Error("The swap transaction isn't a 0x swap.");
|
|
130
|
+
const [recipient, buyToken, minOut] = AbiCoder.defaultAbiCoder().decode(["address", "address", "uint256"], "0x" + inner.slice(10, 10 + 64 * 3));
|
|
131
|
+
if (recipient.toLowerCase() !== taker.toLowerCase())
|
|
132
|
+
throw new Error("The swap would pay someone other than this wallet.");
|
|
133
|
+
if (buyToken.toLowerCase() !== q.buy_token.toLowerCase())
|
|
134
|
+
throw new Error("The swap would buy a different coin.");
|
|
135
|
+
if (minOut !== BigInt(q.min_buy_amount))
|
|
136
|
+
throw new Error("The swap's minimum doesn't match the quote shown.");
|
|
137
|
+
return target;
|
|
138
|
+
}
|
|
139
|
+
const TOKEN_PROGRAMS = ["TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA", "TokenzQdBNbLqP5VEhdkAS6EPFLC1PHnBqCXEpPxuEb"];
|
|
140
|
+
const ATA_PROGRAM = "ATokenGPvbdGVxr1b2hvZbsiqW5xWH25efTNsLJA8knL";
|
|
141
|
+
/** Programs a Solana swap may call directly. JUP6…: Jupiter's router (Metis), as seen in live Ultra orders. */
|
|
142
|
+
export const SWAP_PROGRAMS = new Set(["ComputeBudget111111111111111111111111111111", "11111111111111111111111111111111", ...TOKEN_PROGRAMS, ATA_PROGRAM, "JUP6LkbZbjS1jKKwapdHNy74zcZ3tLUZoi5QNyVTaV4"]);
|
|
143
|
+
/** Before signing: check the quote server's transaction does only the swap that was shown. Throws if not. */
|
|
144
|
+
export async function verifySwapTx(q, me, d = {}) {
|
|
145
|
+
if (q.venue === "0x") {
|
|
146
|
+
const settler = checkZeroExTx(q, me.evm).toLowerCase();
|
|
147
|
+
const call = d.evmCall ?? ((chain, to, data) => new JsonRpcProvider(d.rpc?.[chain] ?? DEFAULT_RPC[chain], EVM_CHAIN_ID[chain], { staticNetwork: true }).call({ to, data }));
|
|
148
|
+
const reg = async (sel) => { try {
|
|
149
|
+
return String(AbiCoder.defaultAbiCoder().decode(["address"], await call(q.chain, SETTLER_REGISTRY, sel + "0".repeat(63) + "2"))[0]).toLowerCase();
|
|
150
|
+
}
|
|
151
|
+
catch {
|
|
152
|
+
return "";
|
|
153
|
+
} };
|
|
154
|
+
// ownerOf(2) is the current Settler; prev(2) the one before, still used while 0x's API catches up.
|
|
155
|
+
if ((await reg("0x6352211e")) !== settler && (await reg("0xe2603dc2")) !== settler)
|
|
156
|
+
throw new Error("The swap goes through a contract 0x's registry doesn't list. Not signing it.");
|
|
157
|
+
return;
|
|
158
|
+
}
|
|
159
|
+
let vtx;
|
|
160
|
+
try {
|
|
161
|
+
vtx = VersionedTransaction.deserialize(Buffer.from(String(q.raw?.transaction ?? ""), "base64"));
|
|
162
|
+
}
|
|
163
|
+
catch {
|
|
164
|
+
throw new Error("The quote's transaction can't be read.");
|
|
165
|
+
}
|
|
166
|
+
const signers = vtx.message.staticAccountKeys.slice(0, vtx.message.header.numRequiredSignatures);
|
|
167
|
+
if (!signers.some((k) => k.equals(me.solana)))
|
|
168
|
+
throw new Error("The quote's transaction isn't for this wallet.");
|
|
169
|
+
const conn = d.conn ?? new Connection(d.rpc?.solana ?? DEFAULT_RPC.solana, "confirmed");
|
|
170
|
+
const fail = () => new Error("Couldn't check this swap before signing. Try again in a moment.");
|
|
171
|
+
// Only programs whose behaviour is known: Jupiter's own router (Metis, seen in live orders 2026-10-14) and the
|
|
172
|
+
// Solana programs a swap needs. A route through anything else is refused rather than trusted.
|
|
173
|
+
const statics = vtx.message.staticAccountKeys;
|
|
174
|
+
for (const ix of vtx.message.compiledInstructions) {
|
|
175
|
+
const prog = statics[ix.programIdIndex]?.toBase58();
|
|
176
|
+
if (!prog || !SWAP_PROGRAMS.has(prog))
|
|
177
|
+
throw new Error("This swap route goes through a program Tollkit doesn't sign for. Try again in a moment or change the amount.");
|
|
178
|
+
if (prog === "TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA" || prog === "TokenzQdBNbLqP5VEhdkAS6EPFLC1PHnBqCXEpPxuEb") {
|
|
179
|
+
// Approve, ApproveChecked, SetAuthority: never part of a swap.
|
|
180
|
+
if ([4, 6, 13].includes(ix.data[0]))
|
|
181
|
+
throw new Error("This swap would change who controls your tokens. Not signing it.");
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
const held = new Map();
|
|
185
|
+
try {
|
|
186
|
+
for (const prog of TOKEN_PROGRAMS) {
|
|
187
|
+
const r = await conn.getParsedTokenAccountsByOwner(me.solana, { programId: new PublicKey(prog) });
|
|
188
|
+
for (const a of r.value) {
|
|
189
|
+
const i = a.account.data.parsed?.info;
|
|
190
|
+
if (i)
|
|
191
|
+
held.set(a.pubkey.toBase58(), { mint: i.mint, amount: BigInt(i.tokenAmount.amount), delegate: i.delegate ?? null, close: i.closeAuthority ?? null });
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
catch {
|
|
196
|
+
throw fail();
|
|
197
|
+
}
|
|
198
|
+
const luts = [];
|
|
199
|
+
for (const l of vtx.message.addressTableLookups ?? []) {
|
|
200
|
+
const t = await conn.getAddressLookupTable?.(l.accountKey).catch(() => null);
|
|
201
|
+
if (!t?.value)
|
|
202
|
+
throw fail();
|
|
203
|
+
luts.push(t.value);
|
|
204
|
+
}
|
|
205
|
+
const keys = vtx.message.getAccountKeys({ addressLookupTableAccounts: luts });
|
|
206
|
+
const watch = [];
|
|
207
|
+
for (let i = 0; i < keys.length; i++) {
|
|
208
|
+
const k = keys.get(i).toBase58();
|
|
209
|
+
if (held.has(k) && vtx.message.isAccountWritable(i))
|
|
210
|
+
watch.push(k);
|
|
211
|
+
}
|
|
212
|
+
// The account the bought coin lands in, even if it doesn't exist yet (then it starts at 0).
|
|
213
|
+
const buyAtas = q.buy_token === WSOL ? [] : TOKEN_PROGRAMS.map((p) => ataOf(me.solana, new PublicKey(q.buy_token), new PublicKey(p))).filter((a) => !watch.includes(a));
|
|
214
|
+
const addresses = [me.solana.toBase58(), ...watch, ...buyAtas];
|
|
215
|
+
if (addresses.length > 128)
|
|
216
|
+
throw fail();
|
|
217
|
+
let sim;
|
|
218
|
+
try {
|
|
219
|
+
sim = await conn.simulateTransaction(vtx, { sigVerify: false, replaceRecentBlockhash: true, accounts: { encoding: "base64", addresses } });
|
|
220
|
+
}
|
|
221
|
+
catch {
|
|
222
|
+
throw fail();
|
|
223
|
+
}
|
|
224
|
+
const accs = sim?.value?.accounts;
|
|
225
|
+
if (sim?.value?.err || !accs?.[0])
|
|
226
|
+
throw fail();
|
|
227
|
+
const before = await conn.getBalance(me.solana);
|
|
228
|
+
if (accs[0].owner && accs[0].owner !== "11111111111111111111111111111111")
|
|
229
|
+
throw new Error("This swap would hand your wallet account to another program. Not signing it.");
|
|
230
|
+
const tokens = new Map();
|
|
231
|
+
const readTok = (a) => { const b = Buffer.from(String(a?.data?.[0] ?? ""), "base64"); return b.length >= 165 ? b : null; };
|
|
232
|
+
watch.forEach((addr, i) => {
|
|
233
|
+
const w = held.get(addr), a = accs[i + 1];
|
|
234
|
+
if (!a) {
|
|
235
|
+
tokens.set(w.mint, (tokens.get(w.mint) ?? 0n) - w.amount);
|
|
236
|
+
return;
|
|
237
|
+
}
|
|
238
|
+
const b = readTok(a);
|
|
239
|
+
if (!b)
|
|
240
|
+
return;
|
|
241
|
+
if (!b.subarray(32, 64).equals(me.solana.toBuffer()))
|
|
242
|
+
throw new Error("This swap would give one of your token accounts to someone else. Not signing it.");
|
|
243
|
+
const delegate = b.readUInt32LE(72) === 1 ? new PublicKey(b.subarray(76, 108)).toBase58() : null;
|
|
244
|
+
if (delegate && delegate !== w.delegate)
|
|
245
|
+
throw new Error("This swap would let another account spend your tokens later. Not signing it.");
|
|
246
|
+
const close = b.readUInt32LE(129) === 1 ? new PublicKey(b.subarray(133, 165)).toBase58() : null;
|
|
247
|
+
if (close && close !== w.close)
|
|
248
|
+
throw new Error("This swap would let another account close one of your token accounts. Not signing it.");
|
|
249
|
+
tokens.set(w.mint, (tokens.get(w.mint) ?? 0n) + b.readBigUInt64LE(64) - w.amount);
|
|
250
|
+
});
|
|
251
|
+
buyAtas.forEach((_addr, i) => {
|
|
252
|
+
const b = readTok(accs[watch.length + 1 + i]);
|
|
253
|
+
if (!b || !b.subarray(32, 64).equals(me.solana.toBuffer()) || new PublicKey(b.subarray(0, 32)).toBase58() !== q.buy_token)
|
|
254
|
+
return;
|
|
255
|
+
tokens.set(q.buy_token, (tokens.get(q.buy_token) ?? 0n) + b.readBigUInt64LE(64));
|
|
256
|
+
});
|
|
257
|
+
const sell = BigInt(q.sell_amount), sellingSol = q.sell_token === WSOL, buyingSol = q.buy_token === WSOL;
|
|
258
|
+
const solDelta = BigInt(accs[0].lamports) - BigInt(before) + (tokens.get(WSOL) ?? 0n);
|
|
259
|
+
// Network fees, priority fees and a new token account's deposit stay under 0.01 SOL.
|
|
260
|
+
const FEES = 10000000n;
|
|
261
|
+
if (sellingSol && -solDelta > sell + FEES)
|
|
262
|
+
throw new Error("This swap would take more SOL than you're selling. Not signing it.");
|
|
263
|
+
if (!sellingSol && !buyingSol && -solDelta > FEES)
|
|
264
|
+
throw new Error("This swap would take more SOL than network fees. Not signing it.");
|
|
265
|
+
for (const [mint, delta] of tokens) {
|
|
266
|
+
if (delta >= 0n || mint === WSOL)
|
|
267
|
+
continue;
|
|
268
|
+
if (mint !== q.sell_token || -delta > sell)
|
|
269
|
+
throw new Error("This swap would take a coin you aren't selling, or more of it. Not signing it.");
|
|
270
|
+
}
|
|
271
|
+
const min = BigInt(q.min_buy_amount);
|
|
272
|
+
const got = buyingSol ? solDelta + FEES : (tokens.get(q.buy_token) ?? 0n);
|
|
273
|
+
if (got < min)
|
|
274
|
+
throw new Error("The checked swap pays less than the minimum shown. Not signing it.");
|
|
275
|
+
}
|
|
276
|
+
/** Associated token account address (the ATA program's seeds: owner, token program, mint). */
|
|
277
|
+
function ataOf(owner, mint, tokenProgram) {
|
|
278
|
+
return PublicKey.findProgramAddressSync([owner.toBuffer(), tokenProgram.toBuffer(), mint.toBuffer()], new PublicKey(ATA_PROGRAM))[0].toBase58();
|
|
279
|
+
}
|
|
88
280
|
/** Sign and send. Returns the transaction hash / signature. */
|
|
89
281
|
export async function executeSwap(q, keys, deps = {}) {
|
|
282
|
+
await verifySwapTx(q, { evm: keys.evm.address, solana: keys.solana.publicKey }, { ...deps, ...deps.verify });
|
|
90
283
|
if (q.venue === "jupiter") {
|
|
91
284
|
const tx = VersionedTransaction.deserialize(Buffer.from(q.raw.transaction, "base64"));
|
|
92
285
|
tx.sign([keys.solana]);
|
|
@@ -103,7 +296,7 @@ export async function executeSwap(q, keys, deps = {}) {
|
|
|
103
296
|
const signer = keys.evm.connect(provider);
|
|
104
297
|
if (q.raw?.issues?.allowance) {
|
|
105
298
|
const token = new Contract(q.sell_token, ERC20, signer);
|
|
106
|
-
const a = await token.approve(ALLOWANCE_HOLDER, BigInt(q.sell_amount)); // exact amount, never unlimited
|
|
299
|
+
const a = await token.getFunction("approve")(ALLOWANCE_HOLDER, BigInt(q.sell_amount)); // exact amount, never unlimited
|
|
107
300
|
await a.wait();
|
|
108
301
|
}
|
|
109
302
|
const t = q.raw.transaction;
|
package/dist/swap.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"swap.js","sourceRoot":"","sources":["../src/swap.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"swap.js","sourceRoot":"","sources":["../src/swap.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
import { type Chain } from "./chains.js";
|
|
2
|
+
type Fetch = typeof fetch;
|
|
3
|
+
export interface ListedToken {
|
|
4
|
+
chain: Chain;
|
|
5
|
+
address: string;
|
|
6
|
+
symbol: string;
|
|
7
|
+
name: string;
|
|
8
|
+
decimals: number;
|
|
9
|
+
logo?: string;
|
|
10
|
+
/** core: always shown; listed: on the bundled list or Jupiter-verified; unlisted: anything else. */
|
|
11
|
+
trust: "core" | "listed" | "unlisted";
|
|
12
|
+
/** Base/Ethereum: which list it's on. */
|
|
13
|
+
source?: "superchain" | "uniswap";
|
|
14
|
+
/** Solana, from Jupiter: its own signals. */
|
|
15
|
+
jupiter?: {
|
|
16
|
+
verified: boolean;
|
|
17
|
+
strict: boolean;
|
|
18
|
+
organic?: number;
|
|
19
|
+
organicLabel?: string;
|
|
20
|
+
suspicious?: boolean;
|
|
21
|
+
mintAuthorityDisabled?: boolean;
|
|
22
|
+
freezeAuthorityDisabled?: boolean;
|
|
23
|
+
topHoldersPct?: number;
|
|
24
|
+
liquidity?: number;
|
|
25
|
+
};
|
|
26
|
+
}
|
|
27
|
+
export declare const UNISWAP_LIST = "https://tokens.uniswap.org";
|
|
28
|
+
/** Adds the Uniswap default list (refreshed at most daily). Failures leave the bundled list as it is. */
|
|
29
|
+
export declare function loadExtraLists(f?: Fetch): Promise<void>;
|
|
30
|
+
/** Core tokens (ETH, USDC...) plus the bundled list and the Uniswap list, for Base or Ethereum. */
|
|
31
|
+
export declare function evmList(chain: Chain): ListedToken[];
|
|
32
|
+
export declare function isCoreToken(chain: Chain, address: string): boolean;
|
|
33
|
+
export declare function findListed(chain: Chain, address: string): ListedToken | undefined;
|
|
34
|
+
/** Search the bundled list by symbol, name or address. Exact symbol matches and the list's own top tier come first. */
|
|
35
|
+
export declare function searchEvm(chain: Chain, q: string, limit?: number): ListedToken[];
|
|
36
|
+
export declare const JUPITER = "https://api.jup.ag/tokens/v2";
|
|
37
|
+
/** Symbol, name or mint search. */
|
|
38
|
+
export declare function searchSolana(q: string, f?: Fetch, limit?: number): Promise<ListedToken[]>;
|
|
39
|
+
export declare function topSolana(f?: Fetch, limit?: number): Promise<ListedToken[]>;
|
|
40
|
+
/** Jupiter's data for up to 100 mints at a time (cached 30 minutes). Mints Jupiter doesn't know come back as null. */
|
|
41
|
+
export declare function solanaInfo(mints: string[], f?: Fetch): Promise<Map<string, ListedToken | null>>;
|
|
42
|
+
export declare const MULTICALL3 = "0xcA11bde05977b3631167028862bE2a173976CA11";
|
|
43
|
+
/** Non-zero balances of the given tokens for one owner. Tokens that fail to answer are skipped. */
|
|
44
|
+
export declare function evmBalances(chain: Chain, owner: string, tokens: string[], rpc?: string, call?: (data: string) => Promise<string>): Promise<Map<string, bigint>>;
|
|
45
|
+
export interface TokenCheck {
|
|
46
|
+
chain: Chain;
|
|
47
|
+
address: string;
|
|
48
|
+
symbol: string | null;
|
|
49
|
+
name: string | null;
|
|
50
|
+
decimals: number | null;
|
|
51
|
+
logo?: string;
|
|
52
|
+
trust: ListedToken["trust"];
|
|
53
|
+
/** Plain warnings. Empty does not mean safe. Any warning means adding the token needs a second tap. */
|
|
54
|
+
warnings: string[];
|
|
55
|
+
/** Contract powers of a listed token (e.g. USDC's issuer can pause or block addresses): shown, not blocking. */
|
|
56
|
+
powers: string[];
|
|
57
|
+
/** Plain facts worth seeing either way. */
|
|
58
|
+
facts: string[];
|
|
59
|
+
checked: boolean;
|
|
60
|
+
}
|
|
61
|
+
/**
|
|
62
|
+
* Tollkit's token check (the same facts as the paid /chain/check tool, free for the wallet), plus the list
|
|
63
|
+
* and Jupiter signals. Warnings are facts, not a verdict.
|
|
64
|
+
*/
|
|
65
|
+
export declare function checkToken(chain: Chain, address: string, o?: {
|
|
66
|
+
fetch?: Fetch;
|
|
67
|
+
proxy?: string;
|
|
68
|
+
}): Promise<TokenCheck>;
|
|
69
|
+
export declare const NATIVE_ADDRESS: Record<Chain, string>;
|
|
70
|
+
export {};
|
|
@@ -0,0 +1,259 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Which tokens the wallet knows: a bundled list for Base and Ethereum, Jupiter's token data for Solana, and
|
|
3
|
+
* the token check (Tollkit's own /chain/check facts, run free for the wallet at api.tollkit.dev/wallet/token/check).
|
|
4
|
+
*
|
|
5
|
+
* Sources (checked 2026-10-15):
|
|
6
|
+
* - Base/Ethereum: the Superchain Token List, src/data/token-list.ts (MIT; Base's docs name it as Base's reference
|
|
7
|
+
* list). Not a safety review: the list itself says tokens on it are not reviewed.
|
|
8
|
+
* - Base/Ethereum, at run time: the Uniswap Labs default token list (tokens.uniswap.org), which adds Base-native
|
|
9
|
+
* tokens the Superchain list lacks (AERO, DEGEN, cbBTC...). Fetched on this device at most daily and kept in
|
|
10
|
+
* memory; not bundled (its licence is GPL-3.0).
|
|
11
|
+
* - Solana: Jupiter Tokens API v2 (developers.jup.ag/docs/tokens): /search (symbol, name or up to 100 mints) and
|
|
12
|
+
* /toptraded/24h. No API key (0.5 requests a second); answers are kept on this device only, never bundled or
|
|
13
|
+
* passed on (Jupiter's API terms), and the wallet shows "Powered by Jupiter" where they appear.
|
|
14
|
+
* - Balances on Base/Ethereum for listed tokens: one Multicall3 aggregate3 call (0xcA11bde05977b3631167028862bE2a173976CA11,
|
|
15
|
+
* github.com/mds1/multicall; bytecode checked on both chains with eth_getCode on 2026-10-15).
|
|
16
|
+
*/
|
|
17
|
+
import { Interface, JsonRpcProvider, getAddress } from "ethers";
|
|
18
|
+
import { DEFAULT_RPC, EVM_CHAIN_ID, NATIVE_EVM, WSOL } from "./chains.js";
|
|
19
|
+
import { KNOWN } from "./tokens.js";
|
|
20
|
+
import { EVM_TOKENS, LOGO_BASE } from "./data/token-list.js";
|
|
21
|
+
import { DEFAULT_PROXY } from "./swap.js";
|
|
22
|
+
const CHAIN_ID = { 1: "ethereum", 8453: "base" };
|
|
23
|
+
const logoUrl = (p) => (!p ? undefined : /^https:\/\//.test(p) ? p : LOGO_BASE + p);
|
|
24
|
+
let evmCache = null;
|
|
25
|
+
const extra = new Map();
|
|
26
|
+
let extraAt = 0, extraLoading = null;
|
|
27
|
+
export const UNISWAP_LIST = "https://tokens.uniswap.org";
|
|
28
|
+
/** Adds the Uniswap default list (refreshed at most daily). Failures leave the bundled list as it is. */
|
|
29
|
+
export function loadExtraLists(f = fetch) {
|
|
30
|
+
if (Date.now() - extraAt < 86_400_000)
|
|
31
|
+
return Promise.resolve();
|
|
32
|
+
return (extraLoading ??= (async () => {
|
|
33
|
+
try {
|
|
34
|
+
const r = await f(UNISWAP_LIST, { headers: { accept: "application/json" }, signal: AbortSignal.timeout(20_000) });
|
|
35
|
+
if (!r.ok)
|
|
36
|
+
return;
|
|
37
|
+
const j = await r.json();
|
|
38
|
+
const next = new Map([["base", []], ["ethereum", []]]);
|
|
39
|
+
for (const t of Array.isArray(j?.tokens) ? j.tokens : []) {
|
|
40
|
+
const c = CHAIN_ID[t?.chainId];
|
|
41
|
+
if (!c || typeof t.address !== "string" || !/^0x[0-9a-fA-F]{40}$/.test(t.address) || typeof t.symbol !== "string" || !Number.isInteger(t.decimals))
|
|
42
|
+
continue;
|
|
43
|
+
next.get(c).push({ chain: c, address: getAddress(t.address), symbol: t.symbol.slice(0, 16), name: String(t.name ?? t.symbol).slice(0, 60), decimals: t.decimals, logo: typeof t.logoURI === "string" && t.logoURI.startsWith("https://") ? t.logoURI : undefined, trust: "listed", source: "uniswap" });
|
|
44
|
+
}
|
|
45
|
+
extra.clear();
|
|
46
|
+
for (const [k, v] of next)
|
|
47
|
+
extra.set(k, v);
|
|
48
|
+
extraAt = Date.now();
|
|
49
|
+
merged.clear();
|
|
50
|
+
}
|
|
51
|
+
catch { /* keep the bundled list */ }
|
|
52
|
+
finally {
|
|
53
|
+
extraLoading = null;
|
|
54
|
+
}
|
|
55
|
+
})());
|
|
56
|
+
}
|
|
57
|
+
const merged = new Map();
|
|
58
|
+
/** Core tokens (ETH, USDC...) plus the bundled list and the Uniswap list, for Base or Ethereum. */
|
|
59
|
+
export function evmList(chain) {
|
|
60
|
+
if (chain === "solana")
|
|
61
|
+
return [];
|
|
62
|
+
const m = merged.get(chain);
|
|
63
|
+
if (m)
|
|
64
|
+
return m;
|
|
65
|
+
const base = bundledList(chain), seen = new Set(base.map((t) => t.address.toLowerCase()));
|
|
66
|
+
const all = [...base, ...(extra.get(chain) ?? []).filter((t) => !seen.has(t.address.toLowerCase()))];
|
|
67
|
+
merged.set(chain, all);
|
|
68
|
+
return all;
|
|
69
|
+
}
|
|
70
|
+
function bundledList(chain) {
|
|
71
|
+
if (chain === "solana")
|
|
72
|
+
return [];
|
|
73
|
+
if (!evmCache) {
|
|
74
|
+
evmCache = new Map([["base", []], ["ethereum", []]]);
|
|
75
|
+
for (const [id, address, symbol, name, decimals, logo] of EVM_TOKENS) {
|
|
76
|
+
const c = CHAIN_ID[id];
|
|
77
|
+
if (!c)
|
|
78
|
+
continue;
|
|
79
|
+
evmCache.get(c).push({ chain: c, address: getAddress(address), symbol, name, decimals, logo: logoUrl(logo), trust: "listed", source: "superchain" });
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
const core = Object.values(KNOWN[chain]).filter((t) => t.address !== NATIVE_EVM).map((t) => ({ chain, address: t.address, symbol: t.symbol, name: t.symbol, decimals: t.decimals, trust: "core" }));
|
|
83
|
+
const listed = evmCache.get(chain).filter((t) => !core.some((k) => k.address.toLowerCase() === t.address.toLowerCase()));
|
|
84
|
+
return [...core.map((k) => ({ ...k, logo: evmCache.get(chain).find((t) => t.address.toLowerCase() === k.address.toLowerCase())?.logo })), ...listed];
|
|
85
|
+
}
|
|
86
|
+
export function isCoreToken(chain, address) {
|
|
87
|
+
return Object.values(KNOWN[chain]).some((k) => k.address.toLowerCase() === address.toLowerCase());
|
|
88
|
+
}
|
|
89
|
+
export function findListed(chain, address) {
|
|
90
|
+
return evmList(chain).find((t) => t.address.toLowerCase() === address.toLowerCase());
|
|
91
|
+
}
|
|
92
|
+
/** Search the bundled list by symbol, name or address. Exact symbol matches and the list's own top tier come first. */
|
|
93
|
+
export function searchEvm(chain, q, limit = 20) {
|
|
94
|
+
const s = q.trim().toLowerCase();
|
|
95
|
+
if (!s)
|
|
96
|
+
return evmList(chain).slice(0, limit);
|
|
97
|
+
const score = (t) => (t.trust === "core" ? 0 : 10) + (t.symbol.toLowerCase() === s ? 0 : t.symbol.toLowerCase().startsWith(s) ? 1 : t.name.toLowerCase().includes(s) ? 2 : 3);
|
|
98
|
+
return evmList(chain).filter((t) => t.address.toLowerCase() === s || t.symbol.toLowerCase().includes(s) || t.name.toLowerCase().includes(s)).sort((a, b) => score(a) - score(b)).slice(0, limit);
|
|
99
|
+
}
|
|
100
|
+
// ---- Solana: Jupiter ---------------------------------------------------------------------------------------
|
|
101
|
+
export const JUPITER = "https://api.jup.ag/tokens/v2";
|
|
102
|
+
const jupCache = new Map();
|
|
103
|
+
function fromJupiter(x) {
|
|
104
|
+
if (!x || typeof x.id !== "string" || typeof x.decimals !== "number")
|
|
105
|
+
return null;
|
|
106
|
+
const tags = Array.isArray(x.tags) ? x.tags.map(String) : [];
|
|
107
|
+
const verified = x.isVerified === true || tags.includes("verified");
|
|
108
|
+
const core = isCoreToken("solana", x.id);
|
|
109
|
+
return {
|
|
110
|
+
chain: "solana", address: x.id, symbol: String(x.symbol ?? "").slice(0, 16), name: String(x.name ?? "").slice(0, 60), decimals: x.decimals,
|
|
111
|
+
logo: typeof x.icon === "string" && /^https:\/\//.test(x.icon) ? x.icon : undefined,
|
|
112
|
+
trust: core ? "core" : verified && !x.audit?.isSus ? "listed" : "unlisted",
|
|
113
|
+
jupiter: {
|
|
114
|
+
verified, strict: tags.includes("strict"), organic: typeof x.organicScore === "number" ? Math.round(x.organicScore) : undefined, organicLabel: x.organicScoreLabel,
|
|
115
|
+
suspicious: x.audit?.isSus === true, mintAuthorityDisabled: x.audit?.mintAuthorityDisabled, freezeAuthorityDisabled: x.audit?.freezeAuthorityDisabled,
|
|
116
|
+
topHoldersPct: typeof x.audit?.topHoldersPercentage === "number" ? Math.round(x.audit.topHoldersPercentage * 10) / 10 : undefined,
|
|
117
|
+
liquidity: typeof x.liquidity === "number" ? Math.round(x.liquidity) : undefined,
|
|
118
|
+
},
|
|
119
|
+
};
|
|
120
|
+
}
|
|
121
|
+
async function jupGet(path, f) {
|
|
122
|
+
const r = await f(`${JUPITER}${path}`, { headers: { accept: "application/json" }, signal: AbortSignal.timeout(12_000) });
|
|
123
|
+
if (!r.ok)
|
|
124
|
+
throw new Error(`Jupiter token data isn't available right now (HTTP ${r.status}).`);
|
|
125
|
+
const j = await r.json();
|
|
126
|
+
return Array.isArray(j) ? j : [];
|
|
127
|
+
}
|
|
128
|
+
/** Symbol, name or mint search. */
|
|
129
|
+
export async function searchSolana(q, f = fetch, limit = 20) {
|
|
130
|
+
const s = q.trim();
|
|
131
|
+
if (!s)
|
|
132
|
+
return topSolana(f, limit);
|
|
133
|
+
const out = (await jupGet(`/search?query=${encodeURIComponent(s.slice(0, 64))}`, f)).map(fromJupiter).filter((t) => !!t);
|
|
134
|
+
for (const t of out)
|
|
135
|
+
jupCache.set(t.address, { at: Date.now(), v: t });
|
|
136
|
+
return out.sort((a, b) => Number(b.trust === "listed") - Number(a.trust === "listed")).slice(0, limit);
|
|
137
|
+
}
|
|
138
|
+
let topCache = null;
|
|
139
|
+
export async function topSolana(f = fetch, limit = 20) {
|
|
140
|
+
if (!topCache || Date.now() - topCache.at > 3600_000)
|
|
141
|
+
topCache = { at: Date.now(), v: (await jupGet("/toptraded/24h?limit=100", f)).map(fromJupiter).filter((t) => !!t && t.trust !== "unlisted") };
|
|
142
|
+
return topCache.v.slice(0, limit);
|
|
143
|
+
}
|
|
144
|
+
/** Jupiter's data for up to 100 mints at a time (cached 30 minutes). Mints Jupiter doesn't know come back as null. */
|
|
145
|
+
export async function solanaInfo(mints, f = fetch) {
|
|
146
|
+
const out = new Map(), want = [];
|
|
147
|
+
for (const m of new Set(mints)) {
|
|
148
|
+
const h = jupCache.get(m);
|
|
149
|
+
if (h && Date.now() - h.at < 1800_000)
|
|
150
|
+
out.set(m, h.v);
|
|
151
|
+
else
|
|
152
|
+
want.push(m);
|
|
153
|
+
}
|
|
154
|
+
for (let i = 0; i < want.length; i += 100) {
|
|
155
|
+
const part = want.slice(i, i + 100);
|
|
156
|
+
try {
|
|
157
|
+
const got = (await jupGet(`/search?query=${part.join(",")}`, f)).map(fromJupiter).filter((t) => !!t);
|
|
158
|
+
for (const m of part) {
|
|
159
|
+
const t = got.find((x) => x.address === m) ?? null;
|
|
160
|
+
jupCache.set(m, { at: Date.now(), v: t });
|
|
161
|
+
out.set(m, t);
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
catch {
|
|
165
|
+
for (const m of part)
|
|
166
|
+
out.set(m, null);
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
return out;
|
|
170
|
+
}
|
|
171
|
+
// ---- Balances of listed EVM tokens in one call --------------------------------------------------------------
|
|
172
|
+
export const MULTICALL3 = "0xcA11bde05977b3631167028862bE2a173976CA11";
|
|
173
|
+
const MC = new Interface(["function aggregate3((address target,bool allowFailure,bytes callData)[] calls) view returns ((bool success,bytes returnData)[])"]);
|
|
174
|
+
const BAL = new Interface(["function balanceOf(address) view returns (uint256)"]);
|
|
175
|
+
/** Non-zero balances of the given tokens for one owner. Tokens that fail to answer are skipped. */
|
|
176
|
+
export async function evmBalances(chain, owner, tokens, rpc = DEFAULT_RPC[chain], call) {
|
|
177
|
+
const out = new Map();
|
|
178
|
+
const p = call ? null : new JsonRpcProvider(rpc, EVM_CHAIN_ID[chain], { staticNetwork: true });
|
|
179
|
+
for (let i = 0; i < tokens.length; i += 400) {
|
|
180
|
+
const part = tokens.slice(i, i + 400);
|
|
181
|
+
const data = MC.encodeFunctionData("aggregate3", [part.map((t) => ({ target: t, allowFailure: true, callData: BAL.encodeFunctionData("balanceOf", [owner]) }))]);
|
|
182
|
+
const raw = call ? await call(data) : await p.call({ to: MULTICALL3, data });
|
|
183
|
+
const [res] = MC.decodeFunctionResult("aggregate3", raw);
|
|
184
|
+
res.forEach((r, j) => { if (r.success && r.returnData && r.returnData.length >= 66) {
|
|
185
|
+
const v = BigInt(r.returnData.slice(0, 66));
|
|
186
|
+
if (v > 0n)
|
|
187
|
+
out.set(part[j], v);
|
|
188
|
+
} });
|
|
189
|
+
}
|
|
190
|
+
return out;
|
|
191
|
+
}
|
|
192
|
+
const checkCache = new Map();
|
|
193
|
+
/**
|
|
194
|
+
* Tollkit's token check (the same facts as the paid /chain/check tool, free for the wallet), plus the list
|
|
195
|
+
* and Jupiter signals. Warnings are facts, not a verdict.
|
|
196
|
+
*/
|
|
197
|
+
export async function checkToken(chain, address, o = {}) {
|
|
198
|
+
const f = o.fetch ?? fetch;
|
|
199
|
+
const key = `${chain}:${address}`, hit = checkCache.get(key);
|
|
200
|
+
if (hit && Date.now() - hit.at < 600_000)
|
|
201
|
+
return hit.v;
|
|
202
|
+
const listed = chain === "solana" ? (await solanaInfo([address], f)).get(address) ?? undefined : findListed(chain, address);
|
|
203
|
+
const warnings = [], facts = [], powers = [];
|
|
204
|
+
// Issuer powers (upgradeable, mint, pause, blacklist) are normal for big listed tokens like USDC; on an unknown
|
|
205
|
+
// token they are warnings. Fee setters, pool and authority problems are warnings either way.
|
|
206
|
+
const POWERS = new Set(["upgradeable", "can_mint", "can_pause", "blacklist"]);
|
|
207
|
+
let srv = null;
|
|
208
|
+
try {
|
|
209
|
+
const r = await f(`${o.proxy ?? DEFAULT_PROXY}/token/check?chain=${chain}&token=${encodeURIComponent(address)}`, { headers: { accept: "application/json" }, signal: AbortSignal.timeout(20_000) });
|
|
210
|
+
const j = await r.json().catch(() => null);
|
|
211
|
+
if (r.ok)
|
|
212
|
+
srv = j;
|
|
213
|
+
else if (r.status === 400 || r.status === 422)
|
|
214
|
+
throw new Error(j?.message ?? j?.error ?? "That address isn't a token on this network.");
|
|
215
|
+
}
|
|
216
|
+
catch (e) {
|
|
217
|
+
if (/isn't a token|not an spl|must include|invalid/i.test(e.message))
|
|
218
|
+
throw e;
|
|
219
|
+
}
|
|
220
|
+
if (srv) {
|
|
221
|
+
for (const w of srv.warnings ?? [])
|
|
222
|
+
if (typeof w?.message === "string")
|
|
223
|
+
(listed && listed.trust !== "unlisted" && POWERS.has(w.code) ? powers : warnings).push(w.message);
|
|
224
|
+
if (srv.price_usd != null)
|
|
225
|
+
facts.push(`Price about $${Number(srv.price_usd).toLocaleString("en-US", { maximumSignificantDigits: 6 })}${srv.pool_depth_usd != null ? `, with about $${Math.round(srv.pool_depth_usd).toLocaleString("en-US")} of pool depth` : ""}.`);
|
|
226
|
+
if (srv.total_supply != null)
|
|
227
|
+
facts.push(`Total supply ${Number(srv.total_supply).toLocaleString("en-US", { maximumFractionDigits: 2 })}.`);
|
|
228
|
+
}
|
|
229
|
+
const j = listed?.jupiter;
|
|
230
|
+
if (j) {
|
|
231
|
+
if (j.suspicious)
|
|
232
|
+
warnings.push("Jupiter flags this token as suspicious.");
|
|
233
|
+
if (!j.verified)
|
|
234
|
+
warnings.push("Jupiter hasn't verified this token.");
|
|
235
|
+
if (j.organicLabel === "low" && !j.verified)
|
|
236
|
+
warnings.push("Little real trading activity (Jupiter's organic score is low).");
|
|
237
|
+
if (j.topHoldersPct !== undefined && j.topHoldersPct > 50)
|
|
238
|
+
warnings.push(`The top holders own about ${j.topHoldersPct}% of the supply.`);
|
|
239
|
+
if (j.organic !== undefined)
|
|
240
|
+
facts.push(`Jupiter organic score ${j.organic} of 100${j.organicLabel ? ` (${j.organicLabel})` : ""}.`);
|
|
241
|
+
}
|
|
242
|
+
if (chain !== "solana")
|
|
243
|
+
facts.push(listed ? (listed.trust === "core" ? "One of the wallet's built-in tokens." : listed.source === "uniswap" ? "On the Uniswap default token list. Being listed isn't a safety review." : "On the Superchain token list (Base's reference list). Being listed isn't a safety review.") : "Not on the wallet's token lists.");
|
|
244
|
+
else if (listed)
|
|
245
|
+
facts.push(j?.verified ? "Verified by Jupiter." : "Known to Jupiter, not verified.");
|
|
246
|
+
else
|
|
247
|
+
warnings.push("Jupiter doesn't know this token.");
|
|
248
|
+
if (!srv)
|
|
249
|
+
warnings.push("Tollkit's token check couldn't run just now, so contract controls and liquidity weren't checked.");
|
|
250
|
+
const v = {
|
|
251
|
+
chain, address, symbol: srv?.symbol ?? listed?.symbol ?? null, name: srv?.name ?? listed?.name ?? null, decimals: srv?.decimals ?? listed?.decimals ?? null, logo: listed?.logo,
|
|
252
|
+
trust: listed?.trust ?? "unlisted", warnings: [...new Set(warnings)], powers, facts, checked: !!srv,
|
|
253
|
+
};
|
|
254
|
+
if (srv)
|
|
255
|
+
checkCache.set(key, { at: Date.now(), v });
|
|
256
|
+
return v;
|
|
257
|
+
}
|
|
258
|
+
export const NATIVE_ADDRESS = { base: NATIVE_EVM, ethereum: NATIVE_EVM, solana: WSOL };
|
|
259
|
+
//# sourceMappingURL=tokenlist.js.map
|