@swapkit/toolboxes 1.0.0-beta.9 → 4.0.0-beta.35
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/{chunk-fjfxga2v.js → chunk-5yxc1e69.js} +1 -1
- package/dist/{chunk-fjfxga2v.js.map → chunk-5yxc1e69.js.map} +1 -1
- package/dist/chunk-6f98phv2.js +4 -0
- package/dist/{chunk-0h4xdrwz.js.map → chunk-6f98phv2.js.map} +2 -2
- package/dist/{chunk-0f0249b1.js → chunk-9bqegm61.js} +1 -1
- package/dist/{chunk-p1kdg37m.js → chunk-s47y8512.js} +2 -2
- package/dist/{chunk-p1kdg37m.js.map → chunk-s47y8512.js.map} +1 -1
- package/dist/chunk-vtd17cje.js +3 -0
- package/dist/chunk-vtd17cje.js.map +10 -0
- package/dist/chunk-zcdeg6h9.js +4 -0
- package/dist/chunk-zcdeg6h9.js.map +10 -0
- package/dist/src/cosmos/index.cjs +3 -0
- package/dist/src/cosmos/index.cjs.map +16 -0
- package/dist/src/cosmos/index.js +3 -0
- package/dist/src/cosmos/index.js.map +16 -0
- package/dist/src/evm/index.cjs +3 -0
- package/dist/src/evm/index.cjs.map +18 -0
- package/dist/src/evm/index.js +3 -0
- package/dist/src/evm/index.js.map +18 -0
- package/dist/src/index.cjs +3 -0
- package/dist/src/index.cjs.map +10 -0
- package/dist/src/index.js +3 -0
- package/dist/src/index.js.map +10 -0
- package/dist/src/near/index.cjs +3 -0
- package/dist/src/near/index.cjs.map +13 -0
- package/dist/src/near/index.js +3 -0
- package/dist/src/near/index.js.map +13 -0
- package/dist/{radix → src/radix}/index.cjs +2 -2
- package/dist/src/radix/index.cjs.map +10 -0
- package/dist/src/radix/index.js +3 -0
- package/dist/src/radix/index.js.map +10 -0
- package/dist/src/ripple/index.cjs +3 -0
- package/dist/src/ripple/index.cjs.map +10 -0
- package/dist/src/ripple/index.js +3 -0
- package/dist/src/ripple/index.js.map +10 -0
- package/dist/src/solana/index.cjs +3 -0
- package/dist/src/solana/index.cjs.map +10 -0
- package/dist/src/solana/index.js +3 -0
- package/dist/src/solana/index.js.map +10 -0
- package/dist/src/substrate/index.cjs +3 -0
- package/dist/src/substrate/index.cjs.map +12 -0
- package/dist/src/substrate/index.js +3 -0
- package/dist/src/substrate/index.js.map +12 -0
- package/dist/src/tron/index.cjs +3 -0
- package/dist/src/tron/index.cjs.map +11 -0
- package/dist/src/tron/index.js +3 -0
- package/dist/src/tron/index.js.map +11 -0
- package/dist/src/utxo/index.cjs +5 -0
- package/dist/src/utxo/index.cjs.map +17 -0
- package/dist/src/utxo/index.js +5 -0
- package/dist/src/utxo/index.js.map +17 -0
- package/package.json +92 -43
- package/src/cosmos/thorchainUtils/addressFormat.ts +4 -1
- package/src/cosmos/thorchainUtils/messages.ts +2 -2
- package/src/cosmos/thorchainUtils/registry.ts +3 -3
- package/src/cosmos/toolbox/cosmos.ts +35 -16
- package/src/cosmos/toolbox/index.ts +2 -2
- package/src/cosmos/toolbox/thorchain.ts +11 -9
- package/src/cosmos/util.ts +87 -7
- package/src/evm/__tests__/address-validation.test.ts +86 -0
- package/src/evm/__tests__/ethereum.test.ts +1 -1
- package/src/evm/helpers.ts +4 -3
- package/src/evm/toolbox/baseEVMToolbox.ts +34 -24
- package/src/evm/toolbox/index.ts +2 -2
- package/src/evm/toolbox/op.ts +21 -7
- package/src/index.ts +118 -100
- package/src/near/__tests__/core.test.ts +80 -0
- package/src/near/helpers/contractFactory.ts +22 -0
- package/src/near/helpers/core.ts +89 -0
- package/src/near/helpers/gasEstimation.ts +110 -0
- package/src/near/helpers/index.ts +5 -0
- package/src/near/helpers/nep141.ts +110 -0
- package/src/near/index.ts +24 -0
- package/src/near/toolbox.ts +498 -0
- package/src/near/types/contract.ts +48 -0
- package/src/near/types/nep141.ts +66 -0
- package/src/near/types.ts +57 -0
- package/src/radix/index.ts +8 -2
- package/src/ripple/index.ts +14 -21
- package/src/solana/toolbox.ts +73 -2
- package/src/substrate/balance.ts +92 -0
- package/src/substrate/substrate.ts +7 -5
- package/src/tron/__tests__/toolbox.test.ts +147 -0
- package/src/tron/helpers/trc20.abi.ts +40 -0
- package/src/tron/index.ts +16 -0
- package/src/tron/toolbox.ts +336 -0
- package/src/tron/types.ts +31 -0
- package/src/utxo/__tests__/zcash-integration.test.ts +114 -0
- package/src/utxo/helpers/api.ts +66 -16
- package/src/utxo/helpers/bchaddrjs.ts +8 -8
- package/src/utxo/helpers/coinselect.ts +4 -2
- package/src/utxo/helpers/txSize.ts +4 -3
- package/src/utxo/index.ts +1 -0
- package/src/utxo/toolbox/bitcoinCash.ts +21 -13
- package/src/utxo/toolbox/index.ts +16 -4
- package/src/utxo/toolbox/utxo.ts +42 -27
- package/src/utxo/toolbox/zcash.ts +208 -0
- package/dist/chunk-0h4xdrwz.js +0 -4
- package/dist/cosmos/index.cjs +0 -3
- package/dist/cosmos/index.cjs.map +0 -16
- package/dist/cosmos/index.js +0 -3
- package/dist/cosmos/index.js.map +0 -16
- package/dist/evm/index.cjs +0 -3
- package/dist/evm/index.cjs.map +0 -18
- package/dist/evm/index.js +0 -3
- package/dist/evm/index.js.map +0 -18
- package/dist/index.cjs +0 -3
- package/dist/index.cjs.map +0 -10
- package/dist/index.js +0 -3
- package/dist/index.js.map +0 -10
- package/dist/radix/index.cjs.map +0 -10
- package/dist/radix/index.js +0 -3
- package/dist/radix/index.js.map +0 -10
- package/dist/ripple/index.cjs +0 -3
- package/dist/ripple/index.cjs.map +0 -10
- package/dist/ripple/index.js +0 -3
- package/dist/ripple/index.js.map +0 -10
- package/dist/solana/index.cjs +0 -3
- package/dist/solana/index.cjs.map +0 -10
- package/dist/solana/index.js +0 -3
- package/dist/solana/index.js.map +0 -10
- package/dist/substrate/index.cjs +0 -3
- package/dist/substrate/index.cjs.map +0 -11
- package/dist/substrate/index.js +0 -3
- package/dist/substrate/index.js.map +0 -11
- package/dist/utxo/index.cjs +0 -3
- package/dist/utxo/index.cjs.map +0 -16
- package/dist/utxo/index.js +0 -3
- package/dist/utxo/index.js.map +0 -16
- /package/dist/{chunk-0f0249b1.js.map → chunk-9bqegm61.js.map} +0 -0
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
import { beforeAll, describe, expect, test } from "bun:test";
|
|
2
|
+
import { Chain } from "@swapkit/helpers";
|
|
3
|
+
import { getEvmToolbox } from "../toolbox";
|
|
4
|
+
|
|
5
|
+
const context: {
|
|
6
|
+
validateAddress: (address: string) => boolean;
|
|
7
|
+
} = {} as any;
|
|
8
|
+
|
|
9
|
+
beforeAll(async () => {
|
|
10
|
+
// Get EVM toolbox for address validation
|
|
11
|
+
const toolbox = await getEvmToolbox(Chain.Ethereum);
|
|
12
|
+
context.validateAddress = toolbox.validateAddress;
|
|
13
|
+
});
|
|
14
|
+
|
|
15
|
+
describe("EVM Address Validation", () => {
|
|
16
|
+
test("should validate valid EVM addresses", () => {
|
|
17
|
+
const validAddresses = [
|
|
18
|
+
"0xa052Ddf1c1739419B90FB7bf722843AD3e63114B", // User provided address
|
|
19
|
+
"0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48", // USDC contract
|
|
20
|
+
"0x6d6e022eE439C8aB8B7a7dBb0576f8090319CDc6", // Test address
|
|
21
|
+
"0xE29E61479420Dd1029A9946710Ac31A0d140e77F", // Another valid address
|
|
22
|
+
"0x0000000000000000000000000000000000000000", // Zero address
|
|
23
|
+
"0xFFfFfFffFFfffFFfFFfFFFFFffFFFffffFfFFFfF", // Max address
|
|
24
|
+
"0x1234567890123456789012345678901234567890", // Mixed case
|
|
25
|
+
];
|
|
26
|
+
|
|
27
|
+
for (const address of validAddresses) {
|
|
28
|
+
expect(context.validateAddress(address)).toBe(true);
|
|
29
|
+
}
|
|
30
|
+
});
|
|
31
|
+
|
|
32
|
+
test("should reject invalid EVM addresses", () => {
|
|
33
|
+
const invalidAddresses = [
|
|
34
|
+
"", // Empty string
|
|
35
|
+
"invalid", // Random string
|
|
36
|
+
"TR7NHqjeKQxGTCi8q8ZY4pL8otSzgjLj6t", // TRON address
|
|
37
|
+
"1A1zP1eP5QGefi2DMPTfTL5SLmv7DivfNa", // Bitcoin address
|
|
38
|
+
"cosmos1abc123", // Cosmos address
|
|
39
|
+
"0xa052Ddf1c1739419B90FB7bf722843AD3e63114", // Too short (missing 1 char)
|
|
40
|
+
"0xa052Ddf1c1739419B90FB7bf722843AD3e63114BB", // Too long (extra char)
|
|
41
|
+
"0XA052DDF1C1739419B90FB7BF722843AD3E63114B", // Uppercase 0X prefix
|
|
42
|
+
"0xG052Ddf1c1739419B90FB7bf722843AD3e63114B", // Invalid hex character
|
|
43
|
+
"0x", // Only prefix
|
|
44
|
+
];
|
|
45
|
+
|
|
46
|
+
for (const address of invalidAddresses) {
|
|
47
|
+
expect(context.validateAddress(address)).toBe(false);
|
|
48
|
+
}
|
|
49
|
+
});
|
|
50
|
+
|
|
51
|
+
test("should handle case normalization properly", () => {
|
|
52
|
+
const address = "0xa052Ddf1c1739419B90FB7bf722843AD3e63114B"; // Proper checksum
|
|
53
|
+
const lowerCase = address.toLowerCase();
|
|
54
|
+
|
|
55
|
+
// Valid case variations should be accepted
|
|
56
|
+
expect(context.validateAddress(address)).toBe(true);
|
|
57
|
+
expect(context.validateAddress(lowerCase)).toBe(true);
|
|
58
|
+
});
|
|
59
|
+
|
|
60
|
+
test("should reject invalid checksum addresses", () => {
|
|
61
|
+
const invalidChecksumAddress = "0xA052dDF1C1739419b90fb7BF722843ad3E63114b"; // Invalid checksum
|
|
62
|
+
|
|
63
|
+
// Should reject mixed case with invalid checksum
|
|
64
|
+
expect(context.validateAddress(invalidChecksumAddress)).toBe(false);
|
|
65
|
+
});
|
|
66
|
+
|
|
67
|
+
test("should handle edge cases", () => {
|
|
68
|
+
const edgeCases = [null, undefined, 123, {}, [], true, false];
|
|
69
|
+
|
|
70
|
+
for (const testCase of edgeCases) {
|
|
71
|
+
// Should not throw but return false for invalid inputs
|
|
72
|
+
expect(context.validateAddress(testCase as any)).toBe(false);
|
|
73
|
+
}
|
|
74
|
+
});
|
|
75
|
+
|
|
76
|
+
test("should validate checksummed addresses", () => {
|
|
77
|
+
const checksummedAddresses = [
|
|
78
|
+
"0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48", // USDC with proper checksum
|
|
79
|
+
"0x6d6e022eE439C8aB8B7a7dBb0576f8090319CDc6", // Another checksummed address
|
|
80
|
+
];
|
|
81
|
+
|
|
82
|
+
for (const address of checksummedAddresses) {
|
|
83
|
+
expect(context.validateAddress(address)).toBe(true);
|
|
84
|
+
}
|
|
85
|
+
});
|
|
86
|
+
});
|
|
@@ -35,7 +35,7 @@ beforeEach(async () => {
|
|
|
35
35
|
},
|
|
36
36
|
});
|
|
37
37
|
context.provider = provider;
|
|
38
|
-
context.toolbox = await getEvmToolbox(Chain.Ethereum, { provider, signer });
|
|
38
|
+
context.toolbox = await getEvmToolbox(Chain.Ethereum, { provider, signer: signer as any });
|
|
39
39
|
});
|
|
40
40
|
|
|
41
41
|
afterEach(async () => {
|
package/src/evm/helpers.ts
CHANGED
|
@@ -8,6 +8,7 @@ import {
|
|
|
8
8
|
FeeOption,
|
|
9
9
|
type NetworkParams,
|
|
10
10
|
SKConfig,
|
|
11
|
+
SwapKitError,
|
|
11
12
|
SwapKitNumber,
|
|
12
13
|
} from "@swapkit/helpers";
|
|
13
14
|
import type { BrowserProvider, Provider } from "ethers";
|
|
@@ -71,7 +72,7 @@ export const estimateMaxSendableAmount = async ({
|
|
|
71
72
|
const isFeeEVMLegacyCompatible = "gasPrice" in gasRate && gasRate.gasPrice !== undefined;
|
|
72
73
|
|
|
73
74
|
if (!(gasRate && (isFeeEVMLegacyCompatible || isFeeEIP1559Compatible))) {
|
|
74
|
-
throw new
|
|
75
|
+
throw new SwapKitError("toolbox_evm_no_fee_data");
|
|
75
76
|
}
|
|
76
77
|
|
|
77
78
|
const gasPrice = isFeeEIP1559Compatible
|
|
@@ -116,7 +117,7 @@ export function getEstimateTransactionFee({
|
|
|
116
117
|
return assetValue.set(SwapKitNumber.fromBigInt(fee, assetValue.decimal));
|
|
117
118
|
}
|
|
118
119
|
|
|
119
|
-
throw new
|
|
120
|
+
throw new SwapKitError("toolbox_evm_no_gas_price");
|
|
120
121
|
};
|
|
121
122
|
}
|
|
122
123
|
|
|
@@ -168,6 +169,6 @@ function getNetworkInfo<C extends EVMChain>({ chain }: { chain: C }) {
|
|
|
168
169
|
nativeCurrency: { name: "Polygon", symbol: Chain.Polygon, decimals },
|
|
169
170
|
};
|
|
170
171
|
default:
|
|
171
|
-
throw new
|
|
172
|
+
throw new SwapKitError("toolbox_evm_not_supported", { chain });
|
|
172
173
|
}
|
|
173
174
|
}
|
|
@@ -8,6 +8,7 @@ import {
|
|
|
8
8
|
FeeOption,
|
|
9
9
|
SwapKitError,
|
|
10
10
|
SwapKitNumber,
|
|
11
|
+
applyFeeMultiplierToBigInt,
|
|
11
12
|
isGasAsset,
|
|
12
13
|
} from "@swapkit/helpers";
|
|
13
14
|
import { erc20ABI } from "@swapkit/helpers/contracts";
|
|
@@ -208,7 +209,7 @@ export function getEstimateGasPrices({
|
|
|
208
209
|
try {
|
|
209
210
|
const { gasPrice } = await provider.getFeeData();
|
|
210
211
|
|
|
211
|
-
if (!gasPrice) throw new
|
|
212
|
+
if (!gasPrice) throw new SwapKitError("toolbox_evm_no_fee_data");
|
|
212
213
|
|
|
213
214
|
return {
|
|
214
215
|
[FeeOption.Average]: { gasPrice },
|
|
@@ -216,9 +217,9 @@ export function getEstimateGasPrices({
|
|
|
216
217
|
[FeeOption.Fastest]: { gasPrice },
|
|
217
218
|
};
|
|
218
219
|
} catch (error) {
|
|
219
|
-
throw new
|
|
220
|
-
|
|
221
|
-
);
|
|
220
|
+
throw new SwapKitError("toolbox_evm_gas_estimation_error", {
|
|
221
|
+
error: (error as any).msg ?? (error as any).toString(),
|
|
222
|
+
});
|
|
222
223
|
}
|
|
223
224
|
};
|
|
224
225
|
}
|
|
@@ -231,7 +232,7 @@ export function getEstimateGasPrices({
|
|
|
231
232
|
const price = gasPrice as bigint;
|
|
232
233
|
|
|
233
234
|
if (!(maxFeePerGas && maxPriorityFeePerGas)) {
|
|
234
|
-
throw new
|
|
235
|
+
throw new SwapKitError("toolbox_evm_no_fee_data");
|
|
235
236
|
}
|
|
236
237
|
|
|
237
238
|
return {
|
|
@@ -242,22 +243,25 @@ export function getEstimateGasPrices({
|
|
|
242
243
|
maxPriorityFeePerGas,
|
|
243
244
|
},
|
|
244
245
|
[FeeOption.Fast]: {
|
|
245
|
-
l1GasPrice: (
|
|
246
|
-
gasPrice: (price
|
|
246
|
+
l1GasPrice: applyFeeMultiplierToBigInt(l1GasPrice || 0n, FeeOption.Fast),
|
|
247
|
+
gasPrice: applyFeeMultiplierToBigInt(price, FeeOption.Fast),
|
|
247
248
|
maxFeePerGas,
|
|
248
|
-
maxPriorityFeePerGas: (maxPriorityFeePerGas
|
|
249
|
+
maxPriorityFeePerGas: applyFeeMultiplierToBigInt(maxPriorityFeePerGas, FeeOption.Fast),
|
|
249
250
|
},
|
|
250
251
|
[FeeOption.Fastest]: {
|
|
251
|
-
l1GasPrice: (l1GasPrice || 0n)
|
|
252
|
-
gasPrice: price
|
|
252
|
+
l1GasPrice: applyFeeMultiplierToBigInt(l1GasPrice || 0n, FeeOption.Fastest),
|
|
253
|
+
gasPrice: applyFeeMultiplierToBigInt(price, FeeOption.Fastest),
|
|
253
254
|
maxFeePerGas,
|
|
254
|
-
maxPriorityFeePerGas:
|
|
255
|
+
maxPriorityFeePerGas: applyFeeMultiplierToBigInt(
|
|
256
|
+
maxPriorityFeePerGas,
|
|
257
|
+
FeeOption.Fastest,
|
|
258
|
+
),
|
|
255
259
|
},
|
|
256
260
|
};
|
|
257
261
|
} catch (error) {
|
|
258
|
-
throw new
|
|
259
|
-
|
|
260
|
-
);
|
|
262
|
+
throw new SwapKitError("toolbox_evm_gas_estimation_error", {
|
|
263
|
+
error: (error as any).msg ?? (error as any).toString(),
|
|
264
|
+
});
|
|
261
265
|
}
|
|
262
266
|
};
|
|
263
267
|
}
|
|
@@ -273,12 +277,15 @@ export function getEstimateGasPrices({
|
|
|
273
277
|
return {
|
|
274
278
|
[FeeOption.Average]: { maxFeePerGas, maxPriorityFeePerGas },
|
|
275
279
|
[FeeOption.Fast]: {
|
|
276
|
-
maxFeePerGas: (maxFeePerGas
|
|
277
|
-
maxPriorityFeePerGas: (maxPriorityFeePerGas
|
|
280
|
+
maxFeePerGas: applyFeeMultiplierToBigInt(maxFeePerGas, FeeOption.Fast),
|
|
281
|
+
maxPriorityFeePerGas: applyFeeMultiplierToBigInt(maxPriorityFeePerGas, FeeOption.Fast),
|
|
278
282
|
},
|
|
279
283
|
[FeeOption.Fastest]: {
|
|
280
|
-
maxFeePerGas: maxFeePerGas
|
|
281
|
-
maxPriorityFeePerGas:
|
|
284
|
+
maxFeePerGas: applyFeeMultiplierToBigInt(maxFeePerGas, FeeOption.Fastest),
|
|
285
|
+
maxPriorityFeePerGas: applyFeeMultiplierToBigInt(
|
|
286
|
+
maxPriorityFeePerGas,
|
|
287
|
+
FeeOption.Fastest,
|
|
288
|
+
),
|
|
282
289
|
},
|
|
283
290
|
};
|
|
284
291
|
}
|
|
@@ -286,13 +293,13 @@ export function getEstimateGasPrices({
|
|
|
286
293
|
|
|
287
294
|
return {
|
|
288
295
|
[FeeOption.Average]: { gasPrice },
|
|
289
|
-
[FeeOption.Fast]: { gasPrice: (gasPrice
|
|
290
|
-
[FeeOption.Fastest]: { gasPrice: gasPrice
|
|
296
|
+
[FeeOption.Fast]: { gasPrice: applyFeeMultiplierToBigInt(gasPrice, FeeOption.Fast) },
|
|
297
|
+
[FeeOption.Fastest]: { gasPrice: applyFeeMultiplierToBigInt(gasPrice, FeeOption.Fastest) },
|
|
291
298
|
};
|
|
292
299
|
} catch (error) {
|
|
293
|
-
throw new
|
|
294
|
-
|
|
295
|
-
);
|
|
300
|
+
throw new SwapKitError("toolbox_evm_gas_estimation_error", {
|
|
301
|
+
error: (error as any).msg ?? (error as any).toString(),
|
|
302
|
+
});
|
|
296
303
|
}
|
|
297
304
|
};
|
|
298
305
|
}
|
|
@@ -314,7 +321,10 @@ function getCall({ provider, isEIP1559Compatible, signer, chain }: ToolboxWrapPa
|
|
|
314
321
|
feeOption = FeeOption.Fast,
|
|
315
322
|
}: CallParams): Promise<T> {
|
|
316
323
|
const contractProvider = callProvider || provider;
|
|
317
|
-
if (!contractAddress)
|
|
324
|
+
if (!contractAddress)
|
|
325
|
+
throw new SwapKitError("toolbox_evm_invalid_params", {
|
|
326
|
+
error: "contractAddress must be provided",
|
|
327
|
+
});
|
|
318
328
|
|
|
319
329
|
const isStateChanging = isStateChangingCall({ abi, funcName });
|
|
320
330
|
|
package/src/evm/toolbox/index.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { Chain, type EVMChain } from "@swapkit/helpers";
|
|
1
|
+
import { Chain, type EVMChain, SwapKitError } from "@swapkit/helpers";
|
|
2
2
|
|
|
3
3
|
import { getProvider } from "../helpers";
|
|
4
4
|
import type { EVMToolboxParams } from "../types";
|
|
@@ -27,7 +27,7 @@ export async function getEvmToolbox<T extends EVMChain>(chain: T, params?: EVMTo
|
|
|
27
27
|
case Chain.Ethereum:
|
|
28
28
|
return ETHToolbox(toolboxParams);
|
|
29
29
|
default:
|
|
30
|
-
throw new
|
|
30
|
+
throw new SwapKitError("toolbox_evm_not_supported", { chain });
|
|
31
31
|
}
|
|
32
32
|
}
|
|
33
33
|
|
package/src/evm/toolbox/op.ts
CHANGED
|
@@ -1,5 +1,18 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
1
|
+
import {
|
|
2
|
+
BaseDecimal,
|
|
3
|
+
Chain,
|
|
4
|
+
ChainId,
|
|
5
|
+
ChainToExplorerUrl,
|
|
6
|
+
SKConfig,
|
|
7
|
+
SwapKitError,
|
|
8
|
+
} from "@swapkit/helpers";
|
|
9
|
+
import type {
|
|
10
|
+
Authorization,
|
|
11
|
+
BrowserProvider,
|
|
12
|
+
JsonRpcProvider,
|
|
13
|
+
Provider,
|
|
14
|
+
TransactionRequest,
|
|
15
|
+
} from "ethers";
|
|
3
16
|
import { Contract, HDNodeWallet } from "ethers";
|
|
4
17
|
|
|
5
18
|
import { P } from "ts-pattern";
|
|
@@ -32,14 +45,15 @@ function serializeTx<P extends JsonRpcProvider | BrowserProvider>(provider: P) {
|
|
|
32
45
|
return async function serializeTx({ from, to, nonce, ...tx }: TransactionRequest) {
|
|
33
46
|
const { Transaction } = await import("ethers");
|
|
34
47
|
|
|
35
|
-
if (!to)
|
|
36
|
-
|
|
48
|
+
if (!to)
|
|
49
|
+
throw new SwapKitError("toolbox_evm_invalid_transaction", { error: "Missing to address" });
|
|
50
|
+
|
|
51
|
+
return Transaction.from({
|
|
37
52
|
...tx,
|
|
53
|
+
authorizationList: tx.authorizationList as Authorization[],
|
|
38
54
|
to: to as string,
|
|
39
55
|
nonce: nonce ? nonce : from ? await provider.getTransactionCount(from) : 0,
|
|
40
|
-
};
|
|
41
|
-
|
|
42
|
-
return Transaction.from(txParams).serialized;
|
|
56
|
+
}).serialized;
|
|
43
57
|
};
|
|
44
58
|
}
|
|
45
59
|
|
package/src/index.ts
CHANGED
|
@@ -6,15 +6,18 @@ import {
|
|
|
6
6
|
FeeOption,
|
|
7
7
|
type GenericCreateTransactionParams,
|
|
8
8
|
type SubstrateChain,
|
|
9
|
+
SwapKitError,
|
|
9
10
|
type UTXOChain,
|
|
10
11
|
} from "@swapkit/helpers";
|
|
11
12
|
import type { getCosmosToolbox } from "@swapkit/toolboxes/cosmos";
|
|
12
13
|
|
|
13
14
|
import type { ETHToolbox, EVMCreateTransactionParams, getEvmToolbox } from "@swapkit/toolboxes/evm";
|
|
15
|
+
import type { getNearToolbox } from "@swapkit/toolboxes/near";
|
|
14
16
|
import type { RadixToolbox } from "@swapkit/toolboxes/radix";
|
|
15
17
|
import type { getRippleToolbox } from "@swapkit/toolboxes/ripple";
|
|
16
18
|
import type { SolanaCreateTransactionParams, getSolanaToolbox } from "@swapkit/toolboxes/solana";
|
|
17
19
|
import type { getSubstrateToolbox } from "@swapkit/toolboxes/substrate";
|
|
20
|
+
import type { createTronToolbox } from "@swapkit/toolboxes/tron";
|
|
18
21
|
import type { getUtxoToolbox } from "@swapkit/toolboxes/utxo";
|
|
19
22
|
|
|
20
23
|
export async function getAddressValidator() {
|
|
@@ -24,11 +27,14 @@ export async function getAddressValidator() {
|
|
|
24
27
|
const { substrateValidateAddress } = await import("@swapkit/toolboxes/substrate");
|
|
25
28
|
const { getUTXOAddressValidator } = await import("@swapkit/toolboxes/utxo");
|
|
26
29
|
const { getSolanaAddressValidator } = await import("@swapkit/toolboxes/solana");
|
|
30
|
+
const { validateNearAddress } = await import("@swapkit/toolboxes/near");
|
|
27
31
|
const { rippleValidateAddress } = await import("@swapkit/toolboxes/ripple");
|
|
28
32
|
const { radixValidateAddress } = await import("@swapkit/toolboxes/radix");
|
|
33
|
+
const { getTronAddressValidator } = await import("@swapkit/toolboxes/tron");
|
|
29
34
|
|
|
30
35
|
const solanaValidateAddress = await getSolanaAddressValidator();
|
|
31
36
|
const utxoValidateAddress = await getUTXOAddressValidator();
|
|
37
|
+
const tronValidateAddress = await getTronAddressValidator();
|
|
32
38
|
|
|
33
39
|
return function validateAddress({ address, chain }: { address: string; chain: Chain }) {
|
|
34
40
|
const isValid = match(chain)
|
|
@@ -52,68 +58,62 @@ export async function getAddressValidator() {
|
|
|
52
58
|
substrateValidateAddress({ address, chain: chain as SubstrateChain }),
|
|
53
59
|
)
|
|
54
60
|
.with(Chain.Radix, () => radixValidateAddress(address))
|
|
61
|
+
.with(Chain.Near, () => validateNearAddress(address))
|
|
55
62
|
.with(Chain.Ripple, () => rippleValidateAddress(address))
|
|
56
63
|
.with(Chain.Solana, () => solanaValidateAddress(address))
|
|
64
|
+
.with(Chain.Tron, () => tronValidateAddress(address))
|
|
57
65
|
.otherwise(() => false);
|
|
58
66
|
|
|
59
67
|
return isValid;
|
|
60
68
|
};
|
|
61
69
|
}
|
|
62
70
|
|
|
63
|
-
export
|
|
64
|
-
const toolbox = await getToolbox(chain);
|
|
65
|
-
|
|
71
|
+
export function getFeeEstimator<T extends keyof CreateTransactionParams>(chain: T) {
|
|
66
72
|
return async function estimateFee(params: CreateTransactionParams[T]) {
|
|
67
|
-
|
|
68
|
-
case Chain.Arbitrum:
|
|
69
|
-
case Chain.Avalanche:
|
|
70
|
-
case Chain.Optimism:
|
|
71
|
-
case Chain.BinanceSmartChain:
|
|
72
|
-
case Chain.Base:
|
|
73
|
-
case Chain.Polygon:
|
|
74
|
-
case Chain.Ethereum: {
|
|
75
|
-
const txObject = await (
|
|
76
|
-
toolbox as Awaited<ReturnType<typeof ETHToolbox>>
|
|
77
|
-
).createTransaction(params as EVMCreateTransactionParams);
|
|
78
|
-
return (toolbox as Awaited<ReturnType<typeof ETHToolbox>>).estimateTransactionFee({
|
|
79
|
-
...txObject,
|
|
80
|
-
feeOption: params.feeOptionKey || FeeOption.Fast,
|
|
81
|
-
chain,
|
|
82
|
-
});
|
|
83
|
-
}
|
|
84
|
-
case Chain.Bitcoin:
|
|
85
|
-
case Chain.BitcoinCash:
|
|
86
|
-
case Chain.Dogecoin:
|
|
87
|
-
case Chain.Dash:
|
|
88
|
-
case Chain.Litecoin: {
|
|
89
|
-
return (toolbox as Awaited<ReturnType<typeof getUtxoToolbox>>).estimateTransactionFee(
|
|
90
|
-
params as CreateTransactionParams[Chain.Bitcoin],
|
|
91
|
-
);
|
|
92
|
-
}
|
|
73
|
+
const { match } = await import("ts-pattern");
|
|
93
74
|
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
75
|
+
return match(chain as Chain)
|
|
76
|
+
.returnType<Promise<AssetValue>>()
|
|
77
|
+
.with(
|
|
78
|
+
Chain.Arbitrum,
|
|
79
|
+
Chain.Avalanche,
|
|
80
|
+
Chain.Optimism,
|
|
81
|
+
Chain.BinanceSmartChain,
|
|
82
|
+
Chain.Base,
|
|
83
|
+
Chain.Polygon,
|
|
84
|
+
Chain.Ethereum,
|
|
85
|
+
async (chain) => {
|
|
86
|
+
const toolbox = await getToolbox(chain);
|
|
87
|
+
const txObject = await toolbox.createTransaction(params);
|
|
88
|
+
|
|
89
|
+
return (toolbox as Awaited<ReturnType<typeof ETHToolbox>>).estimateTransactionFee({
|
|
90
|
+
...txObject,
|
|
91
|
+
feeOption: params.feeOptionKey || FeeOption.Fast,
|
|
92
|
+
chain,
|
|
93
|
+
});
|
|
94
|
+
},
|
|
95
|
+
)
|
|
96
|
+
.with(
|
|
97
|
+
Chain.Bitcoin,
|
|
98
|
+
Chain.BitcoinCash,
|
|
99
|
+
Chain.Dogecoin,
|
|
100
|
+
Chain.Dash,
|
|
101
|
+
Chain.Litecoin,
|
|
102
|
+
Chain.Polkadot,
|
|
103
|
+
Chain.Solana,
|
|
104
|
+
Chain.Ripple,
|
|
105
|
+
Chain.Tron,
|
|
106
|
+
Chain.Near,
|
|
107
|
+
async (chain) => {
|
|
108
|
+
const toolbox = await getToolbox(chain);
|
|
109
|
+
return toolbox.estimateTransactionFee(params) as Promise<AssetValue>;
|
|
110
|
+
},
|
|
111
|
+
)
|
|
112
|
+
.with(Chain.THORChain, Chain.Maya, Chain.Kujira, Chain.Cosmos, async () => {
|
|
98
113
|
const { estimateTransactionFee } = await import("@swapkit/toolboxes/cosmos");
|
|
99
114
|
return estimateTransactionFee(params);
|
|
100
|
-
}
|
|
101
|
-
|
|
102
|
-
case Chain.Polkadot: {
|
|
103
|
-
return (
|
|
104
|
-
toolbox as Awaited<ReturnType<typeof getSubstrateToolbox<Chain.Polkadot>>>
|
|
105
|
-
).estimateTransactionFee(params);
|
|
106
|
-
}
|
|
107
|
-
|
|
108
|
-
case Chain.Solana: {
|
|
109
|
-
return (toolbox as Awaited<ReturnType<typeof getSolanaToolbox>>).estimateTransactionFee(
|
|
110
|
-
params as CreateTransactionParams[Chain.Solana],
|
|
111
|
-
);
|
|
112
|
-
}
|
|
113
|
-
|
|
114
|
-
default:
|
|
115
|
-
return AssetValue.from({ chain });
|
|
116
|
-
}
|
|
115
|
+
})
|
|
116
|
+
.otherwise(async () => AssetValue.from({ chain }));
|
|
117
117
|
};
|
|
118
118
|
}
|
|
119
119
|
|
|
@@ -127,8 +127,10 @@ type Toolboxes = {
|
|
|
127
127
|
[key in SubstrateChain]: Awaited<ReturnType<typeof getSubstrateToolbox>>;
|
|
128
128
|
} & {
|
|
129
129
|
[Chain.Radix]: Awaited<ReturnType<typeof RadixToolbox>>;
|
|
130
|
+
[Chain.Near]: Awaited<ReturnType<typeof getNearToolbox>>;
|
|
130
131
|
[Chain.Ripple]: Awaited<ReturnType<typeof getRippleToolbox>>;
|
|
131
132
|
[Chain.Solana]: Awaited<ReturnType<typeof getSolanaToolbox>>;
|
|
133
|
+
[Chain.Tron]: Awaited<ReturnType<typeof createTronToolbox>>;
|
|
132
134
|
};
|
|
133
135
|
|
|
134
136
|
type ToolboxParams = { [key in EVMChain]: Parameters<typeof getEvmToolbox>[1] } & {
|
|
@@ -139,8 +141,10 @@ type ToolboxParams = { [key in EVMChain]: Parameters<typeof getEvmToolbox>[1] }
|
|
|
139
141
|
[key in SubstrateChain]: Parameters<typeof getSubstrateToolbox>[1];
|
|
140
142
|
} & {
|
|
141
143
|
[Chain.Radix]: Parameters<typeof RadixToolbox>[0];
|
|
144
|
+
[Chain.Near]: Parameters<typeof getNearToolbox>[0];
|
|
142
145
|
[Chain.Ripple]: Parameters<typeof getRippleToolbox>[0];
|
|
143
146
|
[Chain.Solana]: Parameters<typeof getSolanaToolbox>[0];
|
|
147
|
+
[Chain.Tron]: Parameters<typeof createTronToolbox>[0];
|
|
144
148
|
};
|
|
145
149
|
|
|
146
150
|
type CreateTransactionParams = { [key in EVMChain]: EVMCreateTransactionParams } & {
|
|
@@ -151,85 +155,99 @@ type CreateTransactionParams = { [key in EVMChain]: EVMCreateTransactionParams }
|
|
|
151
155
|
[key in SubstrateChain]: GenericCreateTransactionParams;
|
|
152
156
|
} & {
|
|
153
157
|
[Chain.Radix]: GenericCreateTransactionParams;
|
|
158
|
+
[Chain.Ripple]: GenericCreateTransactionParams;
|
|
159
|
+
[Chain.Near]: GenericCreateTransactionParams;
|
|
154
160
|
[Chain.Solana]: SolanaCreateTransactionParams;
|
|
161
|
+
[Chain.Tron]: GenericCreateTransactionParams;
|
|
155
162
|
};
|
|
156
163
|
|
|
157
164
|
export async function getToolbox<T extends keyof Toolboxes>(
|
|
158
165
|
chain: T,
|
|
159
166
|
params?: ToolboxParams[T],
|
|
160
167
|
): Promise<Toolboxes[T]> {
|
|
161
|
-
|
|
162
|
-
case Chain.Arbitrum:
|
|
163
|
-
case Chain.Avalanche:
|
|
164
|
-
case Chain.Optimism:
|
|
165
|
-
case Chain.BinanceSmartChain:
|
|
166
|
-
case Chain.Base:
|
|
167
|
-
case Chain.Polygon:
|
|
168
|
-
case Chain.Ethereum: {
|
|
169
|
-
const { getEvmToolbox } = await import("@swapkit/toolboxes/evm");
|
|
170
|
-
const evmToolbox = await getEvmToolbox(chain, params as Parameters<typeof getEvmToolbox>[1]);
|
|
171
|
-
return evmToolbox as Toolboxes[T];
|
|
172
|
-
}
|
|
173
|
-
|
|
174
|
-
case Chain.Litecoin:
|
|
175
|
-
case Chain.Dash:
|
|
176
|
-
case Chain.Dogecoin:
|
|
177
|
-
case Chain.BitcoinCash:
|
|
178
|
-
case Chain.Bitcoin: {
|
|
179
|
-
const { getUtxoToolbox } = await import("@swapkit/toolboxes/utxo");
|
|
180
|
-
const utxoToolbox = await getUtxoToolbox(
|
|
181
|
-
chain,
|
|
182
|
-
params as Parameters<typeof getUtxoToolbox>[1],
|
|
183
|
-
);
|
|
184
|
-
return utxoToolbox as Toolboxes[T];
|
|
185
|
-
}
|
|
168
|
+
const { match } = await import("ts-pattern");
|
|
186
169
|
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
170
|
+
return match(chain as Chain)
|
|
171
|
+
.returnType<Promise<Toolboxes[T]>>()
|
|
172
|
+
.with(
|
|
173
|
+
Chain.Arbitrum,
|
|
174
|
+
Chain.Avalanche,
|
|
175
|
+
Chain.Optimism,
|
|
176
|
+
Chain.BinanceSmartChain,
|
|
177
|
+
Chain.Base,
|
|
178
|
+
Chain.Polygon,
|
|
179
|
+
Chain.Ethereum,
|
|
180
|
+
async () => {
|
|
181
|
+
const { getEvmToolbox } = await import("@swapkit/toolboxes/evm");
|
|
182
|
+
const evmToolbox = await getEvmToolbox(
|
|
183
|
+
chain as EVMChain,
|
|
184
|
+
params as Parameters<typeof getEvmToolbox>[1],
|
|
185
|
+
);
|
|
186
|
+
return evmToolbox as Toolboxes[T];
|
|
187
|
+
},
|
|
188
|
+
)
|
|
189
|
+
.with(
|
|
190
|
+
Chain.Litecoin,
|
|
191
|
+
Chain.Dash,
|
|
192
|
+
Chain.Dogecoin,
|
|
193
|
+
Chain.BitcoinCash,
|
|
194
|
+
Chain.Bitcoin,
|
|
195
|
+
Chain.Zcash,
|
|
196
|
+
async () => {
|
|
197
|
+
const { getUtxoToolbox } = await import("@swapkit/toolboxes/utxo");
|
|
198
|
+
const utxoToolbox = await getUtxoToolbox(
|
|
199
|
+
chain as UTXOChain,
|
|
200
|
+
params as Parameters<typeof getUtxoToolbox>[1],
|
|
201
|
+
);
|
|
202
|
+
return utxoToolbox as Toolboxes[T];
|
|
203
|
+
},
|
|
204
|
+
)
|
|
205
|
+
.with(Chain.Cosmos, Chain.Kujira, Chain.Maya, Chain.THORChain, async () => {
|
|
191
206
|
const { getCosmosToolbox } = await import("@swapkit/toolboxes/cosmos");
|
|
192
207
|
const cosmosToolbox = await getCosmosToolbox(
|
|
193
|
-
chain,
|
|
208
|
+
chain as CosmosChain,
|
|
194
209
|
params as Parameters<typeof getCosmosToolbox>[1],
|
|
195
210
|
);
|
|
196
|
-
|
|
197
211
|
return cosmosToolbox as Toolboxes[T];
|
|
198
|
-
}
|
|
199
|
-
|
|
200
|
-
case Chain.Chainflip:
|
|
201
|
-
case Chain.Polkadot: {
|
|
212
|
+
})
|
|
213
|
+
.with(Chain.Chainflip, Chain.Polkadot, async () => {
|
|
202
214
|
const { getSubstrateToolbox } = await import("@swapkit/toolboxes/substrate");
|
|
203
215
|
const substrateToolbox = await getSubstrateToolbox(
|
|
204
|
-
chain,
|
|
216
|
+
chain as SubstrateChain,
|
|
205
217
|
params as Parameters<typeof getSubstrateToolbox>[1],
|
|
206
218
|
);
|
|
207
219
|
return substrateToolbox as Toolboxes[T];
|
|
208
|
-
}
|
|
209
|
-
|
|
210
|
-
case Chain.Radix: {
|
|
220
|
+
})
|
|
221
|
+
.with(Chain.Radix, async () => {
|
|
211
222
|
const { RadixToolbox } = await import("@swapkit/toolboxes/radix");
|
|
212
223
|
const radixToolbox = await RadixToolbox(params as Parameters<typeof RadixToolbox>[0]);
|
|
213
224
|
return radixToolbox as Toolboxes[T];
|
|
214
|
-
}
|
|
215
|
-
|
|
216
|
-
case Chain.Ripple: {
|
|
225
|
+
})
|
|
226
|
+
.with(Chain.Ripple, async () => {
|
|
217
227
|
const { getRippleToolbox } = await import("@swapkit/toolboxes/ripple");
|
|
218
228
|
const rippleToolbox = await getRippleToolbox(
|
|
219
229
|
params as Parameters<typeof getRippleToolbox>[0],
|
|
220
230
|
);
|
|
221
231
|
return rippleToolbox as Toolboxes[T];
|
|
222
|
-
}
|
|
223
|
-
|
|
224
|
-
case Chain.Solana: {
|
|
232
|
+
})
|
|
233
|
+
.with(Chain.Solana, async () => {
|
|
225
234
|
const { getSolanaToolbox } = await import("@swapkit/toolboxes/solana");
|
|
226
235
|
const solanaToolbox = await getSolanaToolbox(
|
|
227
236
|
params as Parameters<typeof getSolanaToolbox>[0],
|
|
228
237
|
);
|
|
229
238
|
return solanaToolbox as Toolboxes[T];
|
|
230
|
-
}
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
239
|
+
})
|
|
240
|
+
.with(Chain.Tron, async () => {
|
|
241
|
+
const { createTronToolbox } = await import("@swapkit/toolboxes/tron");
|
|
242
|
+
const tronToolbox = await createTronToolbox(params);
|
|
243
|
+
return tronToolbox as Toolboxes[T];
|
|
244
|
+
})
|
|
245
|
+
.with(Chain.Near, async () => {
|
|
246
|
+
const { getNearToolbox } = await import("@swapkit/toolboxes/near");
|
|
247
|
+
const nearToolbox = await getNearToolbox(params as Parameters<typeof getNearToolbox>[0]);
|
|
248
|
+
return nearToolbox as Toolboxes[T];
|
|
249
|
+
})
|
|
250
|
+
.otherwise(() => {
|
|
251
|
+
throw new SwapKitError("toolbox_not_supported", { chain });
|
|
252
|
+
});
|
|
235
253
|
}
|