@swapkit/toolboxes 1.0.0-beta.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/chunk-fazw0jvt.js +3 -0
- package/dist/chunk-fazw0jvt.js.map +9 -0
- package/dist/chunk-tvrdndbw.js +4 -0
- package/dist/chunk-tvrdndbw.js.map +9 -0
- package/dist/cosmos/index.cjs +3 -0
- package/dist/cosmos/index.cjs.map +19 -0
- package/dist/cosmos/index.js +3 -0
- package/dist/cosmos/index.js.map +19 -0
- package/dist/evm/index.cjs +3 -0
- package/dist/evm/index.cjs.map +24 -0
- package/dist/evm/index.js +3 -0
- package/dist/evm/index.js.map +24 -0
- package/dist/index.cjs +3 -0
- package/dist/index.cjs.map +9 -0
- package/dist/index.js +3 -0
- package/dist/index.js.map +9 -0
- package/dist/radix/index.cjs +3 -0
- package/dist/radix/index.cjs.map +10 -0
- package/dist/radix/index.js +3 -0
- package/dist/radix/index.js.map +10 -0
- package/dist/solana/index.cjs +3 -0
- package/dist/solana/index.cjs.map +10 -0
- package/dist/solana/index.js +3 -0
- package/dist/solana/index.js.map +10 -0
- package/dist/substrate/index.cjs +3 -0
- package/dist/substrate/index.cjs.map +12 -0
- package/dist/substrate/index.js +3 -0
- package/dist/substrate/index.js.map +12 -0
- package/dist/utxo/index.cjs +3 -0
- package/dist/utxo/index.cjs.map +18 -0
- package/dist/utxo/index.js +3 -0
- package/dist/utxo/index.js.map +18 -0
- package/package.json +105 -0
- package/src/cosmos/index.ts +11 -0
- package/src/cosmos/thorchainUtils/addressFormat.ts +24 -0
- package/src/cosmos/thorchainUtils/index.ts +4 -0
- package/src/cosmos/thorchainUtils/messages.ts +244 -0
- package/src/cosmos/thorchainUtils/registry.ts +47 -0
- package/src/cosmos/thorchainUtils/types/client-types.ts +80 -0
- package/src/cosmos/thorchainUtils/types/index.ts +1 -0
- package/src/cosmos/thorchainUtils/types/proto/MsgCompiled.js +2806 -0
- package/src/cosmos/thorchainUtils/types/proto/MsgCompiled.ts +2802 -0
- package/src/cosmos/thorchainUtils/util.ts +46 -0
- package/src/cosmos/toolbox/BaseCosmosToolbox.ts +254 -0
- package/src/cosmos/toolbox/gaia.ts +39 -0
- package/src/cosmos/toolbox/getToolboxByChain.ts +29 -0
- package/src/cosmos/toolbox/kujira.ts +61 -0
- package/src/cosmos/toolbox/thorchain.ts +321 -0
- package/src/cosmos/types.ts +31 -0
- package/src/cosmos/util.ts +230 -0
- package/src/evm/__tests__/ethereum.test.ts +147 -0
- package/src/evm/api.ts +157 -0
- package/src/evm/contracts/eth/multicall.ts +165 -0
- package/src/evm/contracts/op/gasOracle.ts +151 -0
- package/src/evm/helpers.ts +145 -0
- package/src/evm/index.ts +20 -0
- package/src/evm/provider.ts +6 -0
- package/src/evm/toolbox/EVMToolbox.ts +662 -0
- package/src/evm/toolbox/arb.ts +61 -0
- package/src/evm/toolbox/avax.ts +36 -0
- package/src/evm/toolbox/base.ts +42 -0
- package/src/evm/toolbox/bsc.ts +34 -0
- package/src/evm/toolbox/eth.ts +44 -0
- package/src/evm/toolbox/getToolboxByChain.ts +42 -0
- package/src/evm/toolbox/matic.ts +42 -0
- package/src/evm/toolbox/op.ts +163 -0
- package/src/evm/types.ts +118 -0
- package/src/index.ts +0 -0
- package/src/radix/index.ts +151 -0
- package/src/radix/toolbox.ts +693 -0
- package/src/solana/index.ts +49 -0
- package/src/solana/toolbox.ts +272 -0
- package/src/substrate/index.ts +3 -0
- package/src/substrate/toolbox/baseSubstrateToolbox.ts +286 -0
- package/src/substrate/toolbox/index.ts +40 -0
- package/src/substrate/types/index.ts +2 -0
- package/src/substrate/types/network.ts +42 -0
- package/src/substrate/types/wallet.ts +78 -0
- package/src/utxo/helpers/api.ts +431 -0
- package/src/utxo/helpers/bchaddrjs.ts +177 -0
- package/src/utxo/helpers/coinselect.ts +96 -0
- package/src/utxo/helpers/index.ts +5 -0
- package/src/utxo/helpers/txSize.ts +104 -0
- package/src/utxo/helpers/utils.ts +45 -0
- package/src/utxo/index.ts +9 -0
- package/src/utxo/toolbox/bitcoinCash.ts +281 -0
- package/src/utxo/toolbox/index.ts +37 -0
- package/src/utxo/toolbox/utxo.ts +360 -0
- package/src/utxo/types.ts +70 -0
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { BaseDecimal, Chain, ChainId, ChainToExplorerUrl, type FeeOption } from "@swapkit/helpers";
|
|
2
|
+
import type { BrowserProvider, JsonRpcProvider, Signer } from "ethers";
|
|
3
|
+
|
|
4
|
+
import { type EVMTxBaseParams, estimateTransactionFee, getBalance } from "../index";
|
|
5
|
+
|
|
6
|
+
import { EVMToolbox } from "./EVMToolbox";
|
|
7
|
+
|
|
8
|
+
const getNetworkParams = () => ({
|
|
9
|
+
chainId: ChainId.AvalancheHex,
|
|
10
|
+
chainName: "Avalanche Network",
|
|
11
|
+
nativeCurrency: { name: "Avalanche", symbol: Chain.Avalanche, decimals: BaseDecimal.AVAX },
|
|
12
|
+
// Use external rpc URL so wallets don't throw warning to user
|
|
13
|
+
rpcUrls: ["https://api.avax.network/ext/bc/C/rpc"],
|
|
14
|
+
blockExplorerUrls: [ChainToExplorerUrl[Chain.Avalanche]],
|
|
15
|
+
});
|
|
16
|
+
|
|
17
|
+
export const AVAXToolbox = ({
|
|
18
|
+
provider,
|
|
19
|
+
signer,
|
|
20
|
+
}: { signer?: Signer; provider: JsonRpcProvider | BrowserProvider }) => {
|
|
21
|
+
const evmToolbox = EVMToolbox({ provider, signer });
|
|
22
|
+
const chain = Chain.Avalanche;
|
|
23
|
+
|
|
24
|
+
return {
|
|
25
|
+
...evmToolbox,
|
|
26
|
+
getNetworkParams,
|
|
27
|
+
estimateTransactionFee: (txObject: EVMTxBaseParams, feeOptionKey: FeeOption) =>
|
|
28
|
+
estimateTransactionFee(txObject, feeOptionKey, chain, provider),
|
|
29
|
+
getBalance: (
|
|
30
|
+
address: string,
|
|
31
|
+
potentialScamFilter = true,
|
|
32
|
+
overwriteProvider?: JsonRpcProvider | BrowserProvider,
|
|
33
|
+
) =>
|
|
34
|
+
getBalance({ provider: overwriteProvider || provider, address, chain, potentialScamFilter }),
|
|
35
|
+
};
|
|
36
|
+
};
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import {
|
|
2
|
+
BaseDecimal,
|
|
3
|
+
Chain,
|
|
4
|
+
ChainId,
|
|
5
|
+
ChainToExplorerUrl,
|
|
6
|
+
type FeeOption,
|
|
7
|
+
SKConfig,
|
|
8
|
+
} from "@swapkit/helpers";
|
|
9
|
+
import type { BrowserProvider, JsonRpcProvider, Signer } from "ethers";
|
|
10
|
+
|
|
11
|
+
import { type EVMTxBaseParams, estimateTransactionFee, getBalance } from "../index";
|
|
12
|
+
|
|
13
|
+
import { EVMToolbox } from "./EVMToolbox";
|
|
14
|
+
|
|
15
|
+
const getNetworkParams = () => ({
|
|
16
|
+
chainId: ChainId.BaseHex,
|
|
17
|
+
chainName: "Base Mainnet",
|
|
18
|
+
nativeCurrency: { name: "Ethereum", symbol: Chain.Ethereum, decimals: BaseDecimal.ETH },
|
|
19
|
+
rpcUrls: [SKConfig.get("rpcUrls")[Chain.Base]],
|
|
20
|
+
blockExplorerUrls: [ChainToExplorerUrl[Chain.Base]],
|
|
21
|
+
});
|
|
22
|
+
|
|
23
|
+
export const BASEToolbox = ({
|
|
24
|
+
provider,
|
|
25
|
+
signer,
|
|
26
|
+
}: { signer?: Signer; provider: JsonRpcProvider | BrowserProvider }) => {
|
|
27
|
+
const evmToolbox = EVMToolbox({ provider, signer });
|
|
28
|
+
const chain = Chain.Base;
|
|
29
|
+
|
|
30
|
+
return {
|
|
31
|
+
...evmToolbox,
|
|
32
|
+
getNetworkParams,
|
|
33
|
+
estimateTransactionFee: (txObject: EVMTxBaseParams, feeOptionKey: FeeOption) =>
|
|
34
|
+
estimateTransactionFee(txObject, feeOptionKey, chain, provider),
|
|
35
|
+
getBalance: async (
|
|
36
|
+
address: string,
|
|
37
|
+
potentialScamFilter = true,
|
|
38
|
+
overwriteProvider?: JsonRpcProvider | BrowserProvider,
|
|
39
|
+
) =>
|
|
40
|
+
getBalance({ provider: overwriteProvider || provider, address, chain, potentialScamFilter }),
|
|
41
|
+
};
|
|
42
|
+
};
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { BaseDecimal, Chain, ChainId, ChainToExplorerUrl, type FeeOption } from "@swapkit/helpers";
|
|
2
|
+
import type { BrowserProvider, JsonRpcProvider, Signer } from "ethers";
|
|
3
|
+
|
|
4
|
+
import { type EVMTxBaseParams, estimateTransactionFee, getBalance } from "../index";
|
|
5
|
+
import { EVMToolbox } from "./EVMToolbox";
|
|
6
|
+
|
|
7
|
+
const getNetworkParams = () => ({
|
|
8
|
+
chainId: ChainId.BinanceSmartChainHex,
|
|
9
|
+
chainName: "BNB Chain",
|
|
10
|
+
nativeCurrency: { name: "Binance Coin", symbol: "BNB", decimals: BaseDecimal.BSC },
|
|
11
|
+
rpcUrls: ["https://bsc-dataseed.binance.org"],
|
|
12
|
+
blockExplorerUrls: [ChainToExplorerUrl[Chain.BinanceSmartChain]],
|
|
13
|
+
});
|
|
14
|
+
|
|
15
|
+
export const BSCToolbox = ({
|
|
16
|
+
provider,
|
|
17
|
+
signer,
|
|
18
|
+
}: { signer?: Signer; provider: JsonRpcProvider | BrowserProvider }) => {
|
|
19
|
+
const evmToolbox = EVMToolbox({ provider, signer, isEIP1559Compatible: false });
|
|
20
|
+
const chain = Chain.BinanceSmartChain;
|
|
21
|
+
|
|
22
|
+
return {
|
|
23
|
+
...evmToolbox,
|
|
24
|
+
getNetworkParams,
|
|
25
|
+
estimateTransactionFee: (txObject: EVMTxBaseParams, feeOptionKey: FeeOption) =>
|
|
26
|
+
estimateTransactionFee(txObject, feeOptionKey, chain, provider, false),
|
|
27
|
+
getBalance: (
|
|
28
|
+
address: string,
|
|
29
|
+
potentialScamFilter = true,
|
|
30
|
+
overwriteProvider?: JsonRpcProvider | BrowserProvider,
|
|
31
|
+
) =>
|
|
32
|
+
getBalance({ provider: overwriteProvider || provider, address, chain, potentialScamFilter }),
|
|
33
|
+
};
|
|
34
|
+
};
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import { Chain, FeeOption } from "@swapkit/helpers";
|
|
2
|
+
import type { BrowserProvider, JsonRpcProvider, JsonRpcSigner, Signer } from "ethers";
|
|
3
|
+
|
|
4
|
+
import { type EVMTxBaseParams, estimateTransactionFee, getBalance } from "../index";
|
|
5
|
+
|
|
6
|
+
import { multicallAbi } from "../contracts/eth/multicall";
|
|
7
|
+
import { EVMToolbox } from "./EVMToolbox";
|
|
8
|
+
|
|
9
|
+
export const ETHToolbox = ({
|
|
10
|
+
signer,
|
|
11
|
+
provider,
|
|
12
|
+
}: { signer?: Signer | JsonRpcSigner; provider: JsonRpcProvider | BrowserProvider }) => {
|
|
13
|
+
const evmToolbox = EVMToolbox({ provider, signer });
|
|
14
|
+
const chain = Chain.Ethereum;
|
|
15
|
+
|
|
16
|
+
async function multicall(
|
|
17
|
+
callTuples: { address: string; data: string }[],
|
|
18
|
+
multicallAddress = "0x5ba1e12693dc8f9c48aad8770482f4739beed696",
|
|
19
|
+
funcName = "aggregate",
|
|
20
|
+
feeOptionKey: FeeOption = FeeOption.Fast,
|
|
21
|
+
) {
|
|
22
|
+
const txObject = await evmToolbox.createContractTxObject({
|
|
23
|
+
contractAddress: multicallAddress,
|
|
24
|
+
abi: multicallAbi,
|
|
25
|
+
funcName,
|
|
26
|
+
funcParams: [callTuples],
|
|
27
|
+
});
|
|
28
|
+
|
|
29
|
+
return evmToolbox.sendTransaction(txObject, feeOptionKey);
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
return {
|
|
33
|
+
...evmToolbox,
|
|
34
|
+
multicall,
|
|
35
|
+
estimateTransactionFee: (txObject: EVMTxBaseParams, feeOptionKey?: FeeOption) =>
|
|
36
|
+
estimateTransactionFee(txObject, feeOptionKey, chain, provider),
|
|
37
|
+
getBalance: (
|
|
38
|
+
address: string,
|
|
39
|
+
potentialScamFilter = true,
|
|
40
|
+
overwriteProvider?: JsonRpcProvider | BrowserProvider,
|
|
41
|
+
) =>
|
|
42
|
+
getBalance({ provider: overwriteProvider || provider, address, chain, potentialScamFilter }),
|
|
43
|
+
};
|
|
44
|
+
};
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import { Chain } from "@swapkit/helpers";
|
|
2
|
+
|
|
3
|
+
import { ARBToolbox } from "./arb";
|
|
4
|
+
import { AVAXToolbox } from "./avax";
|
|
5
|
+
import { BASEToolbox } from "./base";
|
|
6
|
+
import { BSCToolbox } from "./bsc";
|
|
7
|
+
import { ETHToolbox } from "./eth";
|
|
8
|
+
import { MATICToolbox } from "./matic";
|
|
9
|
+
import { OPToolbox } from "./op";
|
|
10
|
+
|
|
11
|
+
type ToolboxType = {
|
|
12
|
+
ARB: typeof ARBToolbox;
|
|
13
|
+
AVAX: typeof AVAXToolbox;
|
|
14
|
+
BASE: typeof BASEToolbox;
|
|
15
|
+
BSC: typeof BSCToolbox;
|
|
16
|
+
ETH: typeof ETHToolbox;
|
|
17
|
+
MATIC: typeof MATICToolbox;
|
|
18
|
+
OP: typeof OPToolbox;
|
|
19
|
+
};
|
|
20
|
+
|
|
21
|
+
export const getToolboxByChain = <T extends keyof ToolboxType>(chain: T): ToolboxType[T] => {
|
|
22
|
+
switch (chain) {
|
|
23
|
+
case Chain.Avalanche:
|
|
24
|
+
return AVAXToolbox as ToolboxType[T];
|
|
25
|
+
case Chain.Arbitrum:
|
|
26
|
+
return ARBToolbox as ToolboxType[T];
|
|
27
|
+
case Chain.Base:
|
|
28
|
+
return BASEToolbox as ToolboxType[T];
|
|
29
|
+
case Chain.Optimism:
|
|
30
|
+
return OPToolbox as ToolboxType[T];
|
|
31
|
+
case Chain.Polygon:
|
|
32
|
+
return MATICToolbox as ToolboxType[T];
|
|
33
|
+
case Chain.BinanceSmartChain:
|
|
34
|
+
return BSCToolbox as ToolboxType[T];
|
|
35
|
+
case Chain.Ethereum:
|
|
36
|
+
return ETHToolbox as ToolboxType[T];
|
|
37
|
+
default:
|
|
38
|
+
throw new Error(`Chain ${chain} is not supported`);
|
|
39
|
+
}
|
|
40
|
+
};
|
|
41
|
+
|
|
42
|
+
export { evmValidateAddress } from "./EVMToolbox";
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import {
|
|
2
|
+
BaseDecimal,
|
|
3
|
+
Chain,
|
|
4
|
+
ChainId,
|
|
5
|
+
ChainToExplorerUrl,
|
|
6
|
+
type FeeOption,
|
|
7
|
+
SKConfig,
|
|
8
|
+
} from "@swapkit/helpers";
|
|
9
|
+
import type { BrowserProvider, JsonRpcProvider, Signer } from "ethers";
|
|
10
|
+
|
|
11
|
+
import { type EVMTxBaseParams, estimateTransactionFee, getBalance } from "../index";
|
|
12
|
+
|
|
13
|
+
import { EVMToolbox } from "./EVMToolbox";
|
|
14
|
+
|
|
15
|
+
const getNetworkParams = () => ({
|
|
16
|
+
chainId: ChainId.PolygonHex,
|
|
17
|
+
chainName: "Polygon Mainnet",
|
|
18
|
+
nativeCurrency: { name: "Polygon", symbol: Chain.Polygon, decimals: BaseDecimal.MATIC },
|
|
19
|
+
rpcUrls: [SKConfig.get("rpcUrls")[Chain.Polygon]],
|
|
20
|
+
blockExplorerUrls: [ChainToExplorerUrl[Chain.Polygon]],
|
|
21
|
+
});
|
|
22
|
+
|
|
23
|
+
export const MATICToolbox = ({
|
|
24
|
+
provider,
|
|
25
|
+
signer,
|
|
26
|
+
}: { signer?: Signer; provider: JsonRpcProvider | BrowserProvider }) => {
|
|
27
|
+
const evmToolbox = EVMToolbox({ provider, signer });
|
|
28
|
+
const chain = Chain.Polygon;
|
|
29
|
+
|
|
30
|
+
return {
|
|
31
|
+
...evmToolbox,
|
|
32
|
+
getNetworkParams,
|
|
33
|
+
estimateTransactionFee: (txObject: EVMTxBaseParams, feeOptionKey: FeeOption) =>
|
|
34
|
+
estimateTransactionFee(txObject, feeOptionKey, chain, provider),
|
|
35
|
+
getBalance: (
|
|
36
|
+
address: string,
|
|
37
|
+
potentialScamFilter = true,
|
|
38
|
+
overwriteProvider?: JsonRpcProvider | BrowserProvider,
|
|
39
|
+
) =>
|
|
40
|
+
getBalance({ provider: overwriteProvider || provider, address, chain, potentialScamFilter }),
|
|
41
|
+
};
|
|
42
|
+
};
|
|
@@ -0,0 +1,163 @@
|
|
|
1
|
+
import {
|
|
2
|
+
BaseDecimal,
|
|
3
|
+
Chain,
|
|
4
|
+
ChainId,
|
|
5
|
+
ChainToExplorerUrl,
|
|
6
|
+
FeeOption,
|
|
7
|
+
SKConfig,
|
|
8
|
+
} from "@swapkit/helpers";
|
|
9
|
+
import type { BrowserProvider, JsonRpcProvider, Signer, TransactionRequest } from "ethers";
|
|
10
|
+
import { Contract, Transaction } from "ethers";
|
|
11
|
+
|
|
12
|
+
import { gasOracleAbi } from "../contracts/op/gasOracle";
|
|
13
|
+
import { getBalance } from "../index";
|
|
14
|
+
|
|
15
|
+
import { EVMToolbox } from "./EVMToolbox";
|
|
16
|
+
|
|
17
|
+
const GAS_PRICE_ORACLE_ADDRESS = "0x420000000000000000000000000000000000000f";
|
|
18
|
+
|
|
19
|
+
export const connectGasPriceOracle = (provider: JsonRpcProvider | BrowserProvider) => {
|
|
20
|
+
return new Contract(GAS_PRICE_ORACLE_ADDRESS, gasOracleAbi, provider);
|
|
21
|
+
};
|
|
22
|
+
|
|
23
|
+
export const getL1GasPrice = (provider: JsonRpcProvider | BrowserProvider) => {
|
|
24
|
+
const gasPriceOracle = connectGasPriceOracle(provider);
|
|
25
|
+
|
|
26
|
+
if (gasPriceOracle && "l1BaseFee" in gasPriceOracle) {
|
|
27
|
+
return gasPriceOracle?.l1BaseFee() as unknown as bigint;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
return undefined;
|
|
31
|
+
};
|
|
32
|
+
|
|
33
|
+
const _serializeTx = async (
|
|
34
|
+
provider: JsonRpcProvider | BrowserProvider,
|
|
35
|
+
{ data, from, to, gasPrice, type, gasLimit, nonce }: TransactionRequest,
|
|
36
|
+
) => {
|
|
37
|
+
if (!to) throw new Error("Missing to address");
|
|
38
|
+
|
|
39
|
+
return Transaction.from({
|
|
40
|
+
data,
|
|
41
|
+
to: to as string,
|
|
42
|
+
gasPrice,
|
|
43
|
+
type,
|
|
44
|
+
gasLimit,
|
|
45
|
+
nonce: nonce ? nonce : from ? await provider.getTransactionCount(from) : 0,
|
|
46
|
+
}).serialized;
|
|
47
|
+
};
|
|
48
|
+
|
|
49
|
+
export const estimateL1GasCost = async (
|
|
50
|
+
provider: JsonRpcProvider | BrowserProvider,
|
|
51
|
+
tx: TransactionRequest,
|
|
52
|
+
) => {
|
|
53
|
+
const gasPriceOracle = await connectGasPriceOracle(provider);
|
|
54
|
+
const serializedTx = await _serializeTx(provider, tx);
|
|
55
|
+
|
|
56
|
+
if (gasPriceOracle && "getL1Fee" in gasPriceOracle) {
|
|
57
|
+
return gasPriceOracle.getL1Fee(serializedTx);
|
|
58
|
+
}
|
|
59
|
+
};
|
|
60
|
+
|
|
61
|
+
export const estimateL2GasCost = async (
|
|
62
|
+
provider: JsonRpcProvider | BrowserProvider,
|
|
63
|
+
tx: TransactionRequest,
|
|
64
|
+
) => {
|
|
65
|
+
const l2GasPrice = await provider.send("eth_gasPrice", []);
|
|
66
|
+
const l2GasCost = await provider.estimateGas(tx);
|
|
67
|
+
return l2GasPrice.mul(l2GasCost);
|
|
68
|
+
};
|
|
69
|
+
|
|
70
|
+
export const estimateTotalGasCost = async (
|
|
71
|
+
provider: JsonRpcProvider | BrowserProvider,
|
|
72
|
+
tx: TransactionRequest,
|
|
73
|
+
) => {
|
|
74
|
+
const l1GasCost = await estimateL1GasCost(provider, tx);
|
|
75
|
+
const l2GasCost = await estimateL2GasCost(provider, tx);
|
|
76
|
+
return l1GasCost.add(l2GasCost);
|
|
77
|
+
};
|
|
78
|
+
|
|
79
|
+
export const estimateL1Gas = async (
|
|
80
|
+
provider: JsonRpcProvider | BrowserProvider,
|
|
81
|
+
tx: TransactionRequest,
|
|
82
|
+
) => {
|
|
83
|
+
const gasPriceOracle = connectGasPriceOracle(provider);
|
|
84
|
+
const serializedTx = await _serializeTx(provider, tx);
|
|
85
|
+
|
|
86
|
+
if (gasPriceOracle && "getL1GasUsed" in gasPriceOracle) {
|
|
87
|
+
return gasPriceOracle.getL1GasUsed(serializedTx);
|
|
88
|
+
}
|
|
89
|
+
};
|
|
90
|
+
|
|
91
|
+
const getNetworkParams = () => ({
|
|
92
|
+
chainId: ChainId.OptimismHex,
|
|
93
|
+
chainName: "Optimism",
|
|
94
|
+
nativeCurrency: { name: "Ethereum", symbol: Chain.Ethereum, decimals: BaseDecimal.ETH },
|
|
95
|
+
rpcUrls: [SKConfig.get("rpcUrls")[Chain.Optimism]],
|
|
96
|
+
blockExplorerUrls: [ChainToExplorerUrl[Chain.Optimism]],
|
|
97
|
+
});
|
|
98
|
+
|
|
99
|
+
const estimateGasPrices = async (provider: JsonRpcProvider | BrowserProvider) => {
|
|
100
|
+
try {
|
|
101
|
+
const { maxFeePerGas, maxPriorityFeePerGas, gasPrice } = await provider.getFeeData();
|
|
102
|
+
const l1GasPrice = await getL1GasPrice(provider);
|
|
103
|
+
const price = gasPrice as bigint;
|
|
104
|
+
|
|
105
|
+
if (!(maxFeePerGas && maxPriorityFeePerGas)) {
|
|
106
|
+
throw new Error("No fee data available");
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
return {
|
|
110
|
+
[FeeOption.Average]: {
|
|
111
|
+
l1GasPrice,
|
|
112
|
+
gasPrice,
|
|
113
|
+
maxFeePerGas,
|
|
114
|
+
maxPriorityFeePerGas,
|
|
115
|
+
},
|
|
116
|
+
[FeeOption.Fast]: {
|
|
117
|
+
l1GasPrice: ((l1GasPrice || 0n) * 15n) / 10n,
|
|
118
|
+
gasPrice: (price * 15n) / 10n,
|
|
119
|
+
maxFeePerGas,
|
|
120
|
+
maxPriorityFeePerGas: (maxPriorityFeePerGas * 15n) / 10n,
|
|
121
|
+
},
|
|
122
|
+
[FeeOption.Fastest]: {
|
|
123
|
+
l1GasPrice: (l1GasPrice || 0n) * 2n,
|
|
124
|
+
gasPrice: price * 2n,
|
|
125
|
+
maxFeePerGas,
|
|
126
|
+
maxPriorityFeePerGas: maxPriorityFeePerGas * 2n,
|
|
127
|
+
},
|
|
128
|
+
};
|
|
129
|
+
} catch (error) {
|
|
130
|
+
throw new Error(
|
|
131
|
+
`Failed to estimate gas price: ${(error as any).msg ?? (error as any).toString()}`,
|
|
132
|
+
);
|
|
133
|
+
}
|
|
134
|
+
};
|
|
135
|
+
|
|
136
|
+
export const OPToolbox = ({
|
|
137
|
+
provider,
|
|
138
|
+
signer,
|
|
139
|
+
}: { signer?: Signer; provider: JsonRpcProvider | BrowserProvider }) => {
|
|
140
|
+
const evmToolbox = EVMToolbox({ provider, signer });
|
|
141
|
+
|
|
142
|
+
return {
|
|
143
|
+
...evmToolbox,
|
|
144
|
+
estimateTotalGasCost: (tx: TransactionRequest) => estimateTotalGasCost(provider, tx),
|
|
145
|
+
estimateL1GasCost: (tx: TransactionRequest) => estimateL1GasCost(provider, tx),
|
|
146
|
+
estimateL2GasCost: (tx: TransactionRequest) => estimateL2GasCost(provider, tx),
|
|
147
|
+
getL1GasPrice: () => getL1GasPrice(provider),
|
|
148
|
+
estimateL1Gas: (tx: TransactionRequest) => estimateL1Gas(provider, tx),
|
|
149
|
+
getNetworkParams,
|
|
150
|
+
estimateGasPrices: () => estimateGasPrices(provider),
|
|
151
|
+
getBalance: (
|
|
152
|
+
address: string,
|
|
153
|
+
potentialScamFilter = true,
|
|
154
|
+
overwriteProvider?: JsonRpcProvider | BrowserProvider,
|
|
155
|
+
) =>
|
|
156
|
+
getBalance({
|
|
157
|
+
provider: overwriteProvider || provider,
|
|
158
|
+
address,
|
|
159
|
+
chain: Chain.Optimism,
|
|
160
|
+
potentialScamFilter,
|
|
161
|
+
}),
|
|
162
|
+
};
|
|
163
|
+
};
|
package/src/evm/types.ts
ADDED
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
import type { AssetValue, FeeOption, WalletTxParams } from "@swapkit/helpers";
|
|
2
|
+
import type { BigNumberish, JsonFragment, Transaction } from "ethers";
|
|
3
|
+
|
|
4
|
+
import type {
|
|
5
|
+
ARBToolbox,
|
|
6
|
+
AVAXToolbox,
|
|
7
|
+
BASEToolbox,
|
|
8
|
+
BSCToolbox,
|
|
9
|
+
ETHToolbox,
|
|
10
|
+
MATICToolbox,
|
|
11
|
+
OPToolbox,
|
|
12
|
+
} from "./index";
|
|
13
|
+
import type { getProvider } from "./provider";
|
|
14
|
+
|
|
15
|
+
export enum EthNetwork {
|
|
16
|
+
Test = "goerli",
|
|
17
|
+
Main = "homestead",
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
export type ApproveParams = {
|
|
21
|
+
assetAddress: string;
|
|
22
|
+
spenderAddress: string;
|
|
23
|
+
feeOptionKey?: FeeOption;
|
|
24
|
+
amount?: BigNumberish;
|
|
25
|
+
from: string;
|
|
26
|
+
// Optional fallback in case estimation for gas limit fails
|
|
27
|
+
gasLimitFallback?: BigNumberish;
|
|
28
|
+
nonce?: number;
|
|
29
|
+
};
|
|
30
|
+
|
|
31
|
+
export type ApprovedParams = {
|
|
32
|
+
assetAddress: string;
|
|
33
|
+
spenderAddress: string;
|
|
34
|
+
from: string;
|
|
35
|
+
};
|
|
36
|
+
|
|
37
|
+
export type IsApprovedParams = ApprovedParams & {
|
|
38
|
+
amount?: BigNumberish;
|
|
39
|
+
};
|
|
40
|
+
|
|
41
|
+
export type CallParams = {
|
|
42
|
+
callProvider?: ReturnType<typeof getProvider>;
|
|
43
|
+
contractAddress: string;
|
|
44
|
+
abi: readonly JsonFragment[];
|
|
45
|
+
funcName: string;
|
|
46
|
+
funcParams?: unknown[];
|
|
47
|
+
txOverrides?: Partial<Transaction>;
|
|
48
|
+
feeOption?: FeeOption;
|
|
49
|
+
};
|
|
50
|
+
|
|
51
|
+
export type EstimateCallParams = Pick<
|
|
52
|
+
CallParams,
|
|
53
|
+
"contractAddress" | "abi" | "funcName" | "funcParams" | "txOverrides"
|
|
54
|
+
>;
|
|
55
|
+
|
|
56
|
+
export type TransferParams = WalletTxParams & {
|
|
57
|
+
gasLimit?: bigint;
|
|
58
|
+
gasPrice?: bigint;
|
|
59
|
+
maxFeePerGas?: bigint;
|
|
60
|
+
maxPriorityFeePerGas?: bigint;
|
|
61
|
+
data?: string;
|
|
62
|
+
from: string;
|
|
63
|
+
nonce?: number;
|
|
64
|
+
assetValue: AssetValue;
|
|
65
|
+
};
|
|
66
|
+
|
|
67
|
+
export type EVMToolboxType = ReturnType<
|
|
68
|
+
| typeof ARBToolbox
|
|
69
|
+
| typeof AVAXToolbox
|
|
70
|
+
| typeof BASEToolbox
|
|
71
|
+
| typeof BSCToolbox
|
|
72
|
+
| typeof ETHToolbox
|
|
73
|
+
| typeof MATICToolbox
|
|
74
|
+
| typeof OPToolbox
|
|
75
|
+
>;
|
|
76
|
+
|
|
77
|
+
export type EVMMaxSendableAmountsParams = {
|
|
78
|
+
from: string;
|
|
79
|
+
toolbox: EVMToolboxType;
|
|
80
|
+
assetValue: AssetValue;
|
|
81
|
+
feeOptionKey?: FeeOption;
|
|
82
|
+
memo?: string;
|
|
83
|
+
abi?: readonly JsonFragment[];
|
|
84
|
+
funcName?: string;
|
|
85
|
+
contractAddress?: string;
|
|
86
|
+
funcParams?: unknown[];
|
|
87
|
+
txOverrides?: Partial<Transaction>;
|
|
88
|
+
};
|
|
89
|
+
|
|
90
|
+
export type EVMTxBaseParams<T = bigint> = {
|
|
91
|
+
to?: string;
|
|
92
|
+
from?: string;
|
|
93
|
+
nonce?: number;
|
|
94
|
+
gasLimit?: T;
|
|
95
|
+
data?: string;
|
|
96
|
+
value?: T;
|
|
97
|
+
chainId?: T;
|
|
98
|
+
};
|
|
99
|
+
|
|
100
|
+
export type EIP1559TxParams<T = bigint> = EVMTxBaseParams<T> & {
|
|
101
|
+
type?: number;
|
|
102
|
+
maxFeePerGas?: T;
|
|
103
|
+
maxPriorityFeePerGas?: T;
|
|
104
|
+
};
|
|
105
|
+
|
|
106
|
+
export type LegacyEVMTxParams<T = bigint> = EVMTxBaseParams<T> & {
|
|
107
|
+
gasPrice?: T;
|
|
108
|
+
};
|
|
109
|
+
|
|
110
|
+
export type EVMTxParams = EIP1559TxParams | LegacyEVMTxParams;
|
|
111
|
+
|
|
112
|
+
export type NonETHToolbox =
|
|
113
|
+
| ReturnType<typeof ARBToolbox>
|
|
114
|
+
| ReturnType<typeof AVAXToolbox>
|
|
115
|
+
| ReturnType<typeof BSCToolbox>
|
|
116
|
+
| ReturnType<typeof MATICToolbox>
|
|
117
|
+
| ReturnType<typeof OPToolbox>
|
|
118
|
+
| ReturnType<typeof BASEToolbox>;
|
package/src/index.ts
ADDED
|
File without changes
|
|
@@ -0,0 +1,151 @@
|
|
|
1
|
+
import {
|
|
2
|
+
type FungibleResourcesCollectionItem,
|
|
3
|
+
GatewayApiClient,
|
|
4
|
+
type StateEntityDetailsVaultResponseItem,
|
|
5
|
+
type StateEntityFungiblesPageRequest,
|
|
6
|
+
type StateEntityFungiblesPageResponse,
|
|
7
|
+
} from "@radixdlt/babylon-gateway-api-sdk";
|
|
8
|
+
import { RadixDappToolkit } from "@radixdlt/radix-dapp-toolkit";
|
|
9
|
+
import { AssetValue, Chain, type SKConfigIntegrations } from "@swapkit/helpers";
|
|
10
|
+
|
|
11
|
+
export type RadixWallets = {
|
|
12
|
+
[Chain.Radix]: Awaited<ReturnType<typeof RadixToolbox>>;
|
|
13
|
+
};
|
|
14
|
+
|
|
15
|
+
type RadixGetBalanceParams = {
|
|
16
|
+
address: string;
|
|
17
|
+
networkApi: GatewayApiClient;
|
|
18
|
+
};
|
|
19
|
+
// Could not find anything sync in SDK, ask Radix team
|
|
20
|
+
export function validateAddress(address: string) {
|
|
21
|
+
return address.startsWith("account_rdx1") && address.length === 66;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
function getBalance({ networkApi }: { networkApi: GatewayApiClient }) {
|
|
25
|
+
return async function getBalance(address: string) {
|
|
26
|
+
const fungibleResources = await fetchFungibleResources({ address, networkApi });
|
|
27
|
+
const fungibleBalances = convertResourcesToBalances({
|
|
28
|
+
resources: fungibleResources,
|
|
29
|
+
networkApi,
|
|
30
|
+
});
|
|
31
|
+
return fungibleBalances;
|
|
32
|
+
};
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
async function fetchFungibleResources({
|
|
36
|
+
address,
|
|
37
|
+
networkApi,
|
|
38
|
+
}: RadixGetBalanceParams): Promise<FungibleResourcesCollectionItem[]> {
|
|
39
|
+
let hasNextPage = true;
|
|
40
|
+
let nextCursor: string | undefined;
|
|
41
|
+
let fungibleResources: FungibleResourcesCollectionItem[] = [];
|
|
42
|
+
const stateVersion = await currentStateVersion(networkApi);
|
|
43
|
+
while (hasNextPage) {
|
|
44
|
+
const stateEntityFungiblesPageRequest: StateEntityFungiblesPageRequest = {
|
|
45
|
+
address: address,
|
|
46
|
+
limit_per_page: 100,
|
|
47
|
+
cursor: nextCursor,
|
|
48
|
+
at_ledger_state: {
|
|
49
|
+
state_version: stateVersion,
|
|
50
|
+
},
|
|
51
|
+
};
|
|
52
|
+
|
|
53
|
+
const stateEntityFungiblesPageResponse: StateEntityFungiblesPageResponse =
|
|
54
|
+
await networkApi.state.innerClient.entityFungiblesPage({
|
|
55
|
+
stateEntityFungiblesPageRequest: stateEntityFungiblesPageRequest,
|
|
56
|
+
});
|
|
57
|
+
|
|
58
|
+
fungibleResources = fungibleResources.concat(stateEntityFungiblesPageResponse.items);
|
|
59
|
+
if (stateEntityFungiblesPageResponse.next_cursor) {
|
|
60
|
+
nextCursor = stateEntityFungiblesPageResponse.next_cursor;
|
|
61
|
+
} else {
|
|
62
|
+
hasNextPage = false;
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
return fungibleResources;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
// biome-ignore lint/complexity/noExcessiveCognitiveComplexity: <explanation>
|
|
69
|
+
async function convertResourcesToBalances({
|
|
70
|
+
resources,
|
|
71
|
+
networkApi,
|
|
72
|
+
}: {
|
|
73
|
+
resources: FungibleResourcesCollectionItem[]; //| NonFungibleResourcesCollectionItem[];
|
|
74
|
+
networkApi: GatewayApiClient;
|
|
75
|
+
}): Promise<AssetValue[]> {
|
|
76
|
+
const balances: AssetValue[] = [];
|
|
77
|
+
const BATCH_SIZE = 50;
|
|
78
|
+
|
|
79
|
+
// Split resources into batches of up to 50 items
|
|
80
|
+
const resourceBatches: FungibleResourcesCollectionItem[][] = [];
|
|
81
|
+
for (let i = 0; i < resources.length; i += BATCH_SIZE) {
|
|
82
|
+
resourceBatches.push(resources.slice(i, i + BATCH_SIZE));
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
for (const batch of resourceBatches) {
|
|
86
|
+
const addresses = batch.map((item) => item.resource_address);
|
|
87
|
+
const response: StateEntityDetailsVaultResponseItem[] =
|
|
88
|
+
await networkApi.state.getEntityDetailsVaultAggregated(addresses);
|
|
89
|
+
|
|
90
|
+
const divisibilities = new Map<string, { decimals: number; symbol: string }>();
|
|
91
|
+
|
|
92
|
+
for (const result of response) {
|
|
93
|
+
if (result.details !== undefined) {
|
|
94
|
+
const metaDataSymbol = result.metadata?.items.find((item) => item.key === "symbol");
|
|
95
|
+
const symbol =
|
|
96
|
+
metaDataSymbol?.value.typed.type === "String" ? metaDataSymbol.value.typed.value : "?";
|
|
97
|
+
|
|
98
|
+
if (result.details.type === "FungibleResource") {
|
|
99
|
+
divisibilities.set(result.address, {
|
|
100
|
+
decimals: result.details.divisibility,
|
|
101
|
+
symbol,
|
|
102
|
+
});
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
for (const item of batch) {
|
|
108
|
+
if (item.aggregation_level === "Global") {
|
|
109
|
+
const assetInfo = divisibilities.get(item.resource_address) || { decimals: 0, symbol: "?" };
|
|
110
|
+
|
|
111
|
+
const balance = AssetValue.from({
|
|
112
|
+
asset:
|
|
113
|
+
assetInfo.symbol !== Chain.Radix
|
|
114
|
+
? `${Chain.Radix}.${assetInfo.symbol}-${item.resource_address}`
|
|
115
|
+
: "XRD.XRD",
|
|
116
|
+
value: item.amount,
|
|
117
|
+
});
|
|
118
|
+
balances.push(balance);
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
return balances;
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
async function currentStateVersion(networkApi: GatewayApiClient) {
|
|
127
|
+
return networkApi.status.getCurrent().then((status) => status.ledger_state.state_version);
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
export const RadixToolbox = async ({
|
|
131
|
+
dappConfig,
|
|
132
|
+
}: { dappConfig: SKConfigIntegrations["radix"] }) => {
|
|
133
|
+
const radixToolkit = RadixDappToolkit({
|
|
134
|
+
...dappConfig,
|
|
135
|
+
networkId: dappConfig.network?.networkId || 1,
|
|
136
|
+
});
|
|
137
|
+
|
|
138
|
+
const networkApi = GatewayApiClient.initialize(radixToolkit.gatewayApi.clientConfig);
|
|
139
|
+
|
|
140
|
+
return {
|
|
141
|
+
networkApi,
|
|
142
|
+
getBalance: getBalance({ networkApi }),
|
|
143
|
+
getAddress: () => {
|
|
144
|
+
return "";
|
|
145
|
+
},
|
|
146
|
+
validateAddress,
|
|
147
|
+
signAndBroadcast: (() => {
|
|
148
|
+
throw new Error("Not implemented");
|
|
149
|
+
}) as (params: any) => Promise<string>,
|
|
150
|
+
};
|
|
151
|
+
};
|