@uswap/toolboxes 4.3.6
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/src/cardano/index.cjs +4 -0
- package/dist/src/cardano/index.cjs.map +11 -0
- package/dist/src/cardano/index.js +4 -0
- package/dist/src/cardano/index.js.map +11 -0
- package/dist/src/cosmos/index.cjs +4 -0
- package/dist/src/cosmos/index.cjs.map +20 -0
- package/dist/src/cosmos/index.js +4 -0
- package/dist/src/cosmos/index.js.map +20 -0
- package/dist/src/evm/index.cjs +4 -0
- package/dist/src/evm/index.cjs.map +20 -0
- package/dist/src/evm/index.js +4 -0
- package/dist/src/evm/index.js.map +20 -0
- package/dist/src/index.cjs +5 -0
- package/dist/src/index.cjs.map +67 -0
- package/dist/src/index.js +5 -0
- package/dist/src/index.js.map +67 -0
- package/dist/src/near/index.cjs +4 -0
- package/dist/src/near/index.cjs.map +16 -0
- package/dist/src/near/index.js +4 -0
- package/dist/src/near/index.js.map +16 -0
- package/dist/src/radix/index.cjs +4 -0
- package/dist/src/radix/index.cjs.map +10 -0
- package/dist/src/radix/index.js +4 -0
- package/dist/src/radix/index.js.map +10 -0
- package/dist/src/ripple/index.cjs +4 -0
- package/dist/src/ripple/index.cjs.map +10 -0
- package/dist/src/ripple/index.js +4 -0
- package/dist/src/ripple/index.js.map +10 -0
- package/dist/src/solana/index.cjs +4 -0
- package/dist/src/solana/index.cjs.map +11 -0
- package/dist/src/solana/index.js +4 -0
- package/dist/src/solana/index.js.map +11 -0
- package/dist/src/substrate/index.cjs +4 -0
- package/dist/src/substrate/index.cjs.map +13 -0
- package/dist/src/substrate/index.js +4 -0
- package/dist/src/substrate/index.js.map +13 -0
- package/dist/src/sui/index.cjs +4 -0
- package/dist/src/sui/index.cjs.map +11 -0
- package/dist/src/sui/index.js +4 -0
- package/dist/src/sui/index.js.map +11 -0
- package/dist/src/ton/index.cjs +4 -0
- package/dist/src/ton/index.cjs.map +11 -0
- package/dist/src/ton/index.js +4 -0
- package/dist/src/ton/index.js.map +11 -0
- package/dist/src/tron/index.cjs +4 -0
- package/dist/src/tron/index.cjs.map +13 -0
- package/dist/src/tron/index.js +4 -0
- package/dist/src/tron/index.js.map +13 -0
- package/dist/src/utxo/index.cjs +5 -0
- package/dist/src/utxo/index.cjs.map +21 -0
- package/dist/src/utxo/index.js +5 -0
- package/dist/src/utxo/index.js.map +21 -0
- package/dist/types/cardano/index.d.ts +3 -0
- package/dist/types/cardano/index.d.ts.map +1 -0
- package/dist/types/cardano/toolbox.d.ts +34 -0
- package/dist/types/cardano/toolbox.d.ts.map +1 -0
- package/dist/types/cardano/types.d.ts +11 -0
- package/dist/types/cardano/types.d.ts.map +1 -0
- package/dist/types/cosmos/index.d.ts +5 -0
- package/dist/types/cosmos/index.d.ts.map +1 -0
- package/dist/types/cosmos/thorchainUtils/addressFormat.d.ts +5 -0
- package/dist/types/cosmos/thorchainUtils/addressFormat.d.ts.map +1 -0
- package/dist/types/cosmos/thorchainUtils/index.d.ts +5 -0
- package/dist/types/cosmos/thorchainUtils/index.d.ts.map +1 -0
- package/dist/types/cosmos/thorchainUtils/messages.d.ts +208 -0
- package/dist/types/cosmos/thorchainUtils/messages.d.ts.map +1 -0
- package/dist/types/cosmos/thorchainUtils/registry.d.ts +4 -0
- package/dist/types/cosmos/thorchainUtils/registry.d.ts.map +1 -0
- package/dist/types/cosmos/thorchainUtils/types/MsgCompiled.d.ts +2 -0
- package/dist/types/cosmos/thorchainUtils/types/MsgCompiled.d.ts.map +1 -0
- package/dist/types/cosmos/thorchainUtils/types/client-types.d.ts +63 -0
- package/dist/types/cosmos/thorchainUtils/types/client-types.d.ts.map +1 -0
- package/dist/types/cosmos/thorchainUtils/types/index.d.ts +2 -0
- package/dist/types/cosmos/thorchainUtils/types/index.d.ts.map +1 -0
- package/dist/types/cosmos/toolbox/cosmos.d.ts +62 -0
- package/dist/types/cosmos/toolbox/cosmos.d.ts.map +1 -0
- package/dist/types/cosmos/toolbox/index.d.ts +15 -0
- package/dist/types/cosmos/toolbox/index.d.ts.map +1 -0
- package/dist/types/cosmos/toolbox/thorchain.d.ts +158 -0
- package/dist/types/cosmos/toolbox/thorchain.d.ts.map +1 -0
- package/dist/types/cosmos/types.d.ts +49 -0
- package/dist/types/cosmos/types.d.ts.map +1 -0
- package/dist/types/cosmos/util.d.ts +74 -0
- package/dist/types/cosmos/util.d.ts.map +1 -0
- package/dist/types/evm/api.d.ts +8 -0
- package/dist/types/evm/api.d.ts.map +1 -0
- package/dist/types/evm/contracts/eth/multicall.d.ts +36 -0
- package/dist/types/evm/contracts/eth/multicall.d.ts.map +1 -0
- package/dist/types/evm/contracts/op/gasOracle.d.ts +40 -0
- package/dist/types/evm/contracts/op/gasOracle.d.ts.map +1 -0
- package/dist/types/evm/helpers.d.ts +6 -0
- package/dist/types/evm/helpers.d.ts.map +1 -0
- package/dist/types/evm/index.d.ts +5 -0
- package/dist/types/evm/index.d.ts.map +1 -0
- package/dist/types/evm/toolbox/baseEVMToolbox.d.ts +83 -0
- package/dist/types/evm/toolbox/baseEVMToolbox.d.ts.map +1 -0
- package/dist/types/evm/toolbox/evm.d.ts +767 -0
- package/dist/types/evm/toolbox/evm.d.ts.map +1 -0
- package/dist/types/evm/toolbox/index.d.ts +7 -0
- package/dist/types/evm/toolbox/index.d.ts.map +1 -0
- package/dist/types/evm/toolbox/op.d.ts +76 -0
- package/dist/types/evm/toolbox/op.d.ts.map +1 -0
- package/dist/types/evm/types.d.ts +108 -0
- package/dist/types/evm/types.d.ts.map +1 -0
- package/dist/types/index.d.ts +75 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/near/helpers/core.d.ts +15 -0
- package/dist/types/near/helpers/core.d.ts.map +1 -0
- package/dist/types/near/helpers/gasEstimation.d.ts +41 -0
- package/dist/types/near/helpers/gasEstimation.d.ts.map +1 -0
- package/dist/types/near/helpers/nep141.d.ts +36 -0
- package/dist/types/near/helpers/nep141.d.ts.map +1 -0
- package/dist/types/near/index.d.ts +10 -0
- package/dist/types/near/index.d.ts.map +1 -0
- package/dist/types/near/toolbox.d.ts +32 -0
- package/dist/types/near/toolbox.d.ts.map +1 -0
- package/dist/types/near/types/contract.d.ts +38 -0
- package/dist/types/near/types/contract.d.ts.map +1 -0
- package/dist/types/near/types/nep141.d.ts +29 -0
- package/dist/types/near/types/nep141.d.ts.map +1 -0
- package/dist/types/near/types/toolbox.d.ts +51 -0
- package/dist/types/near/types/toolbox.d.ts.map +1 -0
- package/dist/types/near/types.d.ts +47 -0
- package/dist/types/near/types.d.ts.map +1 -0
- package/dist/types/radix/index.d.ts +14 -0
- package/dist/types/radix/index.d.ts.map +1 -0
- package/dist/types/ripple/index.d.ts +46 -0
- package/dist/types/ripple/index.d.ts.map +1 -0
- package/dist/types/solana/index.d.ts +23 -0
- package/dist/types/solana/index.d.ts.map +1 -0
- package/dist/types/solana/toolbox.d.ts +51 -0
- package/dist/types/solana/toolbox.d.ts.map +1 -0
- package/dist/types/substrate/balance.d.ts +17 -0
- package/dist/types/substrate/balance.d.ts.map +1 -0
- package/dist/types/substrate/index.d.ts +3 -0
- package/dist/types/substrate/index.d.ts.map +1 -0
- package/dist/types/substrate/substrate.d.ts +148 -0
- package/dist/types/substrate/substrate.d.ts.map +1 -0
- package/dist/types/substrate/types.d.ts +100 -0
- package/dist/types/substrate/types.d.ts.map +1 -0
- package/dist/types/sui/index.d.ts +3 -0
- package/dist/types/sui/index.d.ts.map +1 -0
- package/dist/types/sui/toolbox.d.ts +19 -0
- package/dist/types/sui/toolbox.d.ts.map +1 -0
- package/dist/types/sui/types.d.ts +16 -0
- package/dist/types/sui/types.d.ts.map +1 -0
- package/dist/types/ton/index.d.ts +3 -0
- package/dist/types/ton/index.d.ts.map +1 -0
- package/dist/types/ton/toolbox.d.ts +14 -0
- package/dist/types/ton/toolbox.d.ts.map +1 -0
- package/dist/types/ton/types.d.ts +22 -0
- package/dist/types/ton/types.d.ts.map +1 -0
- package/dist/types/tron/helpers/trc20.abi.d.ts +156 -0
- package/dist/types/tron/helpers/trc20.abi.d.ts.map +1 -0
- package/dist/types/tron/helpers/trongrid.d.ts +8 -0
- package/dist/types/tron/helpers/trongrid.d.ts.map +1 -0
- package/dist/types/tron/index.d.ts +6 -0
- package/dist/types/tron/index.d.ts.map +1 -0
- package/dist/types/tron/toolbox.d.ts +26 -0
- package/dist/types/tron/toolbox.d.ts.map +1 -0
- package/dist/types/tron/types.d.ts +103 -0
- package/dist/types/tron/types.d.ts.map +1 -0
- package/dist/types/types.d.ts +26 -0
- package/dist/types/types.d.ts.map +1 -0
- package/dist/types/utils.d.ts +4 -0
- package/dist/types/utils.d.ts.map +1 -0
- package/dist/types/utxo/helpers/api.d.ts +101 -0
- package/dist/types/utxo/helpers/api.d.ts.map +1 -0
- package/dist/types/utxo/helpers/bchaddrjs.d.ts +10 -0
- package/dist/types/utxo/helpers/bchaddrjs.d.ts.map +1 -0
- package/dist/types/utxo/helpers/coinselect.d.ts +17 -0
- package/dist/types/utxo/helpers/coinselect.d.ts.map +1 -0
- package/dist/types/utxo/helpers/index.d.ts +5 -0
- package/dist/types/utxo/helpers/index.d.ts.map +1 -0
- package/dist/types/utxo/helpers/txSize.d.ts +21 -0
- package/dist/types/utxo/helpers/txSize.d.ts.map +1 -0
- package/dist/types/utxo/index.d.ts +7 -0
- package/dist/types/utxo/index.d.ts.map +1 -0
- package/dist/types/utxo/toolbox/bitcoinCash.d.ts +93 -0
- package/dist/types/utxo/toolbox/bitcoinCash.d.ts.map +1 -0
- package/dist/types/utxo/toolbox/index.d.ts +28 -0
- package/dist/types/utxo/toolbox/index.d.ts.map +1 -0
- package/dist/types/utxo/toolbox/params.d.ts +32 -0
- package/dist/types/utxo/toolbox/params.d.ts.map +1 -0
- package/dist/types/utxo/toolbox/utxo.d.ts +103 -0
- package/dist/types/utxo/toolbox/utxo.d.ts.map +1 -0
- package/dist/types/utxo/toolbox/validators.d.ts +4 -0
- package/dist/types/utxo/toolbox/validators.d.ts.map +1 -0
- package/dist/types/utxo/toolbox/zcash.d.ts +72 -0
- package/dist/types/utxo/toolbox/zcash.d.ts.map +1 -0
- package/dist/types/utxo/types.d.ts +46 -0
- package/dist/types/utxo/types.d.ts.map +1 -0
- package/package.json +205 -0
- package/src/__tests__/address-validation-all-chains.test.ts +162 -0
- package/src/__tests__/addressValidator.test.ts +162 -0
- package/src/cardano/__tests__/toolbox.test.ts +48 -0
- package/src/cardano/index.ts +2 -0
- package/src/cardano/toolbox.ts +168 -0
- package/src/cardano/types.ts +10 -0
- package/src/cosmos/__tests__/toolbox.test.ts +91 -0
- package/src/cosmos/index.ts +4 -0
- package/src/cosmos/thorchainUtils/addressFormat.ts +22 -0
- package/src/cosmos/thorchainUtils/index.ts +4 -0
- package/src/cosmos/thorchainUtils/messages.ts +212 -0
- package/src/cosmos/thorchainUtils/registry.ts +43 -0
- package/src/cosmos/thorchainUtils/types/MsgCompiled.ts +2800 -0
- package/src/cosmos/thorchainUtils/types/client-types.ts +54 -0
- package/src/cosmos/thorchainUtils/types/index.ts +1 -0
- package/src/cosmos/toolbox/cosmos.ts +345 -0
- package/src/cosmos/toolbox/index.ts +35 -0
- package/src/cosmos/toolbox/thorchain.ts +249 -0
- package/src/cosmos/types.ts +48 -0
- package/src/cosmos/util.ts +214 -0
- package/src/evm/__tests__/address-validation.test.ts +84 -0
- package/src/evm/__tests__/ethereum.test.ts +137 -0
- package/src/evm/__tests__/signMessage.test.ts +60 -0
- package/src/evm/api.ts +10 -0
- package/src/evm/contracts/eth/multicall.ts +165 -0
- package/src/evm/contracts/op/gasOracle.ts +145 -0
- package/src/evm/helpers.ts +73 -0
- package/src/evm/index.ts +4 -0
- package/src/evm/toolbox/baseEVMToolbox.ts +695 -0
- package/src/evm/toolbox/evm.ts +67 -0
- package/src/evm/toolbox/index.ts +44 -0
- package/src/evm/toolbox/op.ts +156 -0
- package/src/evm/types.ts +146 -0
- package/src/index.ts +260 -0
- package/src/near/__tests__/core.test.ts +70 -0
- package/src/near/helpers/core.ts +85 -0
- package/src/near/helpers/gasEstimation.ts +96 -0
- package/src/near/helpers/nep141.ts +50 -0
- package/src/near/index.ts +21 -0
- package/src/near/toolbox.ts +421 -0
- package/src/near/types/contract.ts +32 -0
- package/src/near/types/nep141.ts +34 -0
- package/src/near/types/toolbox.ts +55 -0
- package/src/near/types.ts +44 -0
- package/src/radix/index.ts +132 -0
- package/src/ripple/index.ts +179 -0
- package/src/solana/index.ts +36 -0
- package/src/solana/toolbox.ts +415 -0
- package/src/substrate/balance.ts +88 -0
- package/src/substrate/index.ts +2 -0
- package/src/substrate/substrate.ts +281 -0
- package/src/substrate/types.ts +115 -0
- package/src/sui/__tests__/toolbox.test.ts +82 -0
- package/src/sui/index.ts +2 -0
- package/src/sui/toolbox.ts +165 -0
- package/src/sui/types.ts +11 -0
- package/src/ton/__tests__/toolbox.test.ts +63 -0
- package/src/ton/index.ts +2 -0
- package/src/ton/toolbox.ts +136 -0
- package/src/ton/types.ts +13 -0
- package/src/tron/__tests__/toolbox.test.ts +221 -0
- package/src/tron/helpers/trc20.abi.ts +107 -0
- package/src/tron/helpers/trongrid.ts +53 -0
- package/src/tron/index.ts +21 -0
- package/src/tron/toolbox.ts +585 -0
- package/src/tron/types.ts +83 -0
- package/src/types.ts +28 -0
- package/src/utils.ts +27 -0
- package/src/utxo/__tests__/zcash-integration.test.ts +97 -0
- package/src/utxo/helpers/api.ts +471 -0
- package/src/utxo/helpers/bchaddrjs.ts +166 -0
- package/src/utxo/helpers/coinselect.ts +92 -0
- package/src/utxo/helpers/index.ts +4 -0
- package/src/utxo/helpers/txSize.ts +137 -0
- package/src/utxo/index.ts +6 -0
- package/src/utxo/toolbox/bitcoinCash.ts +243 -0
- package/src/utxo/toolbox/index.ts +59 -0
- package/src/utxo/toolbox/params.ts +18 -0
- package/src/utxo/toolbox/utxo.ts +439 -0
- package/src/utxo/toolbox/validators.ts +36 -0
- package/src/utxo/toolbox/zcash.ts +245 -0
- package/src/utxo/types.ts +39 -0
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import type { EncodeObject } from "@cosmjs/proto-signing";
|
|
2
|
+
import type { Asset, ChainId, GenericTransferParams } from "@uswap/helpers";
|
|
3
|
+
import type { CosmosCreateTransactionParams } from "../../types";
|
|
4
|
+
|
|
5
|
+
enum TxType {
|
|
6
|
+
Transfer = "transfer",
|
|
7
|
+
Unknown = "unknown",
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
type Tx = {
|
|
11
|
+
asset: Asset; // asset
|
|
12
|
+
from: { from: string }[]; // list of "from" txs. BNC will have one `TxFrom` only, `BTC` might have many transactions going "in" (based on UTXO)
|
|
13
|
+
to: { to: string }[]; // list of "to" transactions. BNC will have one `TxTo` only, `BTC` might have many transactions going "out" (based on UTXO)
|
|
14
|
+
date: Date; // timestamp of tx
|
|
15
|
+
type: TxType; // type
|
|
16
|
+
hash: string; // Tx hash
|
|
17
|
+
};
|
|
18
|
+
|
|
19
|
+
export type NodeUrl = { node: string; rpc: string };
|
|
20
|
+
|
|
21
|
+
export type TxData = Pick<Tx, "from" | "to" | "type">;
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* Response from `thorchain/constants` endpoint
|
|
25
|
+
*/
|
|
26
|
+
export type ThorchainConstantsResponse = {
|
|
27
|
+
int_64_values: {
|
|
28
|
+
// We are in fee interested only - ignore all other values
|
|
29
|
+
NativeTransactionFee: number;
|
|
30
|
+
};
|
|
31
|
+
};
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* Response of `/cosmos/base/tendermint/v1beta1/node_info`
|
|
35
|
+
* Note: We are interested in `network` (aka chain id) only
|
|
36
|
+
*/
|
|
37
|
+
export type NodeInfoResponse = { default_node_info: { network: string } };
|
|
38
|
+
|
|
39
|
+
export type TransferTransaction = {
|
|
40
|
+
memo: string;
|
|
41
|
+
accountNumber: number;
|
|
42
|
+
sequence: number;
|
|
43
|
+
chainId: ChainId;
|
|
44
|
+
msgs: EncodeObject[];
|
|
45
|
+
fee: { amount: { denom: string; amount: string }[]; gas: string };
|
|
46
|
+
};
|
|
47
|
+
|
|
48
|
+
export type ThorchainCreateTransactionParams = Omit<CosmosCreateTransactionParams, "feeRate" | "recipient"> & {
|
|
49
|
+
recipient?: string;
|
|
50
|
+
asSignable?: boolean;
|
|
51
|
+
asAminoMessage?: boolean;
|
|
52
|
+
};
|
|
53
|
+
|
|
54
|
+
export type ThorchainDepositParams = Omit<GenericTransferParams, "recipient">;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from "./client-types";
|
|
@@ -0,0 +1,345 @@
|
|
|
1
|
+
import type { StdFee } from "@cosmjs/amino";
|
|
2
|
+
import type { Account } from "@cosmjs/stargate";
|
|
3
|
+
import { base64, bech32 } from "@scure/base";
|
|
4
|
+
import {
|
|
5
|
+
AssetValue,
|
|
6
|
+
applyFeeMultiplier,
|
|
7
|
+
Chain,
|
|
8
|
+
type ChainId,
|
|
9
|
+
type CosmosChain,
|
|
10
|
+
CosmosChainPrefixes,
|
|
11
|
+
DerivationPath,
|
|
12
|
+
type DerivationPathArray,
|
|
13
|
+
derivationPathToString,
|
|
14
|
+
FeeOption,
|
|
15
|
+
type GenericTransferParams,
|
|
16
|
+
getChainConfig,
|
|
17
|
+
getRPCUrl,
|
|
18
|
+
NetworkDerivationPath,
|
|
19
|
+
SwapKitError,
|
|
20
|
+
SwapKitNumber,
|
|
21
|
+
type TCLikeChain,
|
|
22
|
+
updateDerivationPath,
|
|
23
|
+
} from "@uswap/helpers";
|
|
24
|
+
import { SwapKitApi } from "@uswap/helpers/api";
|
|
25
|
+
import { match, P } from "ts-pattern";
|
|
26
|
+
import type { CosmosToolboxParams } from "../types";
|
|
27
|
+
import {
|
|
28
|
+
cosmosCreateTransaction,
|
|
29
|
+
createSigningStargateClient,
|
|
30
|
+
createStargateClient,
|
|
31
|
+
getAssetFromDenom,
|
|
32
|
+
getDenomWithChain,
|
|
33
|
+
getMsgSendDenom,
|
|
34
|
+
} from "../util";
|
|
35
|
+
|
|
36
|
+
export async function fetchFeeRateFromSwapKit(chainId: ChainId, safeDefault: number) {
|
|
37
|
+
try {
|
|
38
|
+
const response = await SwapKitApi.getGasRate();
|
|
39
|
+
const responseGasRate = response.find((gas) => gas.chainId === chainId)?.value;
|
|
40
|
+
|
|
41
|
+
return responseGasRate ? Number.parseFloat(responseGasRate) : safeDefault;
|
|
42
|
+
} catch {
|
|
43
|
+
return safeDefault;
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
export async function getSignerFromPhrase({
|
|
48
|
+
phrase,
|
|
49
|
+
prefix,
|
|
50
|
+
...derivationParams
|
|
51
|
+
}: { phrase: string; prefix?: string } & ({ chain: Chain; index?: number } | { derivationPath: string })) {
|
|
52
|
+
const importedProtoSigning = await import("@cosmjs/proto-signing");
|
|
53
|
+
const DirectSecp256k1HdWallet =
|
|
54
|
+
importedProtoSigning.DirectSecp256k1HdWallet ?? importedProtoSigning.default?.DirectSecp256k1HdWallet;
|
|
55
|
+
const importedCrypto = await import("@cosmjs/crypto");
|
|
56
|
+
const stringToPath = importedCrypto.stringToPath ?? importedCrypto.default?.stringToPath;
|
|
57
|
+
|
|
58
|
+
const derivationPath =
|
|
59
|
+
"derivationPath" in derivationParams
|
|
60
|
+
? derivationParams.derivationPath
|
|
61
|
+
: `${DerivationPath[derivationParams.chain]}/${derivationParams.index}`;
|
|
62
|
+
|
|
63
|
+
return DirectSecp256k1HdWallet.fromMnemonic(phrase, { hdPaths: [stringToPath(derivationPath)], prefix });
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
export async function getSignerFromPrivateKey({ privateKey, prefix }: { privateKey: Uint8Array; prefix: string }) {
|
|
67
|
+
const importedProtoSigning = await import("@cosmjs/proto-signing");
|
|
68
|
+
const DirectSecp256k1Wallet =
|
|
69
|
+
importedProtoSigning.DirectSecp256k1Wallet ?? importedProtoSigning.default?.DirectSecp256k1Wallet;
|
|
70
|
+
|
|
71
|
+
return DirectSecp256k1Wallet.fromKey(privateKey, prefix);
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
const SafeDefaultFeeValues = {
|
|
75
|
+
[Chain.Cosmos]: 1000,
|
|
76
|
+
[Chain.Kujira]: 1000,
|
|
77
|
+
[Chain.Noble]: 1000,
|
|
78
|
+
[Chain.THORChain]: 5000000,
|
|
79
|
+
[Chain.Maya]: 5000000,
|
|
80
|
+
[Chain.Harbor]: 5000000,
|
|
81
|
+
};
|
|
82
|
+
|
|
83
|
+
export function verifySignature(getAccount: (address: string) => Promise<Account | null>) {
|
|
84
|
+
return async function verifySignature({
|
|
85
|
+
signature,
|
|
86
|
+
message,
|
|
87
|
+
address,
|
|
88
|
+
}: {
|
|
89
|
+
signature: string;
|
|
90
|
+
message: string;
|
|
91
|
+
address: string;
|
|
92
|
+
}) {
|
|
93
|
+
const account = await getAccount(address);
|
|
94
|
+
if (!account?.pubkey) throw new SwapKitError("toolbox_cosmos_verify_signature_no_pubkey");
|
|
95
|
+
|
|
96
|
+
const importedCrypto = await import("@cosmjs/crypto");
|
|
97
|
+
const Secp256k1Signature = importedCrypto.Secp256k1Signature ?? importedCrypto.default?.Secp256k1Signature;
|
|
98
|
+
const Secp256k1 = importedCrypto.Secp256k1 ?? importedCrypto.default?.Secp256k1;
|
|
99
|
+
|
|
100
|
+
const secpSignature = Secp256k1Signature.fromFixedLength(base64.decode(signature));
|
|
101
|
+
return Secp256k1.verifySignature(secpSignature, base64.decode(message), account.pubkey.value);
|
|
102
|
+
};
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
export async function createCosmosToolbox({ chain, ...toolboxParams }: CosmosToolboxParams) {
|
|
106
|
+
const rpcUrl = await getRPCUrl(chain);
|
|
107
|
+
const chainPrefix = CosmosChainPrefixes[chain];
|
|
108
|
+
|
|
109
|
+
const index = "index" in toolboxParams ? toolboxParams.index || 0 : 0;
|
|
110
|
+
const derivationPath = derivationPathToString(
|
|
111
|
+
"derivationPath" in toolboxParams && toolboxParams.derivationPath
|
|
112
|
+
? toolboxParams.derivationPath
|
|
113
|
+
: updateDerivationPath(NetworkDerivationPath[chain], { index }),
|
|
114
|
+
);
|
|
115
|
+
|
|
116
|
+
const signer = await match(toolboxParams)
|
|
117
|
+
.with({ phrase: P.string }, ({ phrase }) => getSignerFromPhrase({ derivationPath, phrase, prefix: chainPrefix }))
|
|
118
|
+
.with({ signer: P.any }, ({ signer }) => signer)
|
|
119
|
+
.otherwise(() => undefined);
|
|
120
|
+
|
|
121
|
+
async function getAccount(address: string) {
|
|
122
|
+
const client = await createStargateClient(rpcUrl);
|
|
123
|
+
return client.getAccount(address);
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
async function getAddress() {
|
|
127
|
+
const [account] = (await signer?.getAccounts()) || [];
|
|
128
|
+
return account?.address;
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
async function getPubKey() {
|
|
132
|
+
const [account] = (await signer?.getAccounts()) || [];
|
|
133
|
+
if (!account?.pubkey) {
|
|
134
|
+
throw new SwapKitError("toolbox_cosmos_signer_not_defined");
|
|
135
|
+
}
|
|
136
|
+
return base64.encode(account?.pubkey);
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
async function signTransaction({
|
|
140
|
+
recipient,
|
|
141
|
+
assetValue,
|
|
142
|
+
memo = "",
|
|
143
|
+
feeRate,
|
|
144
|
+
feeOptionKey = FeeOption.Fast,
|
|
145
|
+
}: GenericTransferParams) {
|
|
146
|
+
const from = await getAddress();
|
|
147
|
+
|
|
148
|
+
if (!(signer && from)) {
|
|
149
|
+
throw new SwapKitError("toolbox_cosmos_signer_not_defined");
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
const feeAssetValue = AssetValue.from({ chain });
|
|
153
|
+
const assetDenom = getDenomWithChain(feeAssetValue);
|
|
154
|
+
const txFee = feeRate || feeToStdFee((await getFees(chain, SafeDefaultFeeValues[chain]))[feeOptionKey], assetDenom);
|
|
155
|
+
|
|
156
|
+
const signingClient = await createSigningStargateClient(rpcUrl, signer);
|
|
157
|
+
const denom = getMsgSendDenom(assetValue.symbol);
|
|
158
|
+
const amount = assetValue.getBaseValue("string");
|
|
159
|
+
|
|
160
|
+
const { TxRaw } = await import("cosmjs-types/cosmos/tx/v1beta1/tx");
|
|
161
|
+
|
|
162
|
+
const msgSend = { amount: [{ amount, denom }], fromAddress: from, toAddress: recipient };
|
|
163
|
+
|
|
164
|
+
const txRaw = await signingClient.sign(
|
|
165
|
+
from,
|
|
166
|
+
[{ typeUrl: "/cosmos.bank.v1beta1.MsgSend", value: msgSend }],
|
|
167
|
+
txFee as StdFee,
|
|
168
|
+
memo,
|
|
169
|
+
);
|
|
170
|
+
|
|
171
|
+
const txBytes = TxRaw.encode(txRaw).finish();
|
|
172
|
+
return Buffer.from(txBytes).toString("hex");
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
async function transfer({
|
|
176
|
+
recipient,
|
|
177
|
+
assetValue,
|
|
178
|
+
memo = "",
|
|
179
|
+
feeRate,
|
|
180
|
+
feeOptionKey = FeeOption.Fast,
|
|
181
|
+
dryRun = false,
|
|
182
|
+
}: GenericTransferParams & { dryRun?: boolean }) {
|
|
183
|
+
if (dryRun) {
|
|
184
|
+
return signTransaction({ assetValue, feeOptionKey, feeRate, memo, recipient });
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
const from = await getAddress();
|
|
188
|
+
|
|
189
|
+
if (!(signer && from)) {
|
|
190
|
+
throw new SwapKitError("toolbox_cosmos_signer_not_defined");
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
const feeAssetValue = AssetValue.from({ chain });
|
|
194
|
+
const assetDenom = getDenomWithChain(feeAssetValue);
|
|
195
|
+
const txFee = feeRate || feeToStdFee((await getFees(chain, SafeDefaultFeeValues[chain]))[feeOptionKey], assetDenom);
|
|
196
|
+
|
|
197
|
+
const signingClient = await createSigningStargateClient(rpcUrl, signer);
|
|
198
|
+
const denom = getMsgSendDenom(assetValue.symbol);
|
|
199
|
+
const message = [{ amount: assetValue.getBaseValue("string"), denom }];
|
|
200
|
+
|
|
201
|
+
const { transactionHash } = await signingClient.sendTokens(from, recipient, message, txFee, memo);
|
|
202
|
+
|
|
203
|
+
return transactionHash;
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
return {
|
|
207
|
+
createPrivateKeyFromPhrase: createPrivateKeyFromPhrase(derivationPath),
|
|
208
|
+
createTransaction: cosmosCreateTransaction,
|
|
209
|
+
fetchFeeRateFromSwapKit,
|
|
210
|
+
getAccount,
|
|
211
|
+
getAddress,
|
|
212
|
+
getBalance: async (address: string, _potentialScamFilter?: boolean) => {
|
|
213
|
+
const denomBalances = await cosmosBalanceDenomsGetter(rpcUrl)(address);
|
|
214
|
+
const balances = await Promise.all(
|
|
215
|
+
denomBalances
|
|
216
|
+
.filter(({ denom }) => denom && !denom.includes("IBC/"))
|
|
217
|
+
.map(({ denom, amount }) => {
|
|
218
|
+
const fullDenom =
|
|
219
|
+
[Chain.THORChain, Chain.Maya].includes(chain as TCLikeChain) &&
|
|
220
|
+
(denom.includes("/") || denom.includes("˜"))
|
|
221
|
+
? `${chain}.${denom}`
|
|
222
|
+
: denom;
|
|
223
|
+
return getAssetFromDenom(fullDenom, amount);
|
|
224
|
+
}),
|
|
225
|
+
);
|
|
226
|
+
|
|
227
|
+
if (balances.length === 0) {
|
|
228
|
+
return [AssetValue.from({ chain })];
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
return balances;
|
|
232
|
+
},
|
|
233
|
+
getBalanceAsDenoms: cosmosBalanceDenomsGetter(rpcUrl),
|
|
234
|
+
getFees: () => getFees(chain, SafeDefaultFeeValues[chain]),
|
|
235
|
+
getPubKey,
|
|
236
|
+
getSignerFromPhrase: async ({ phrase, derivationPath }: { phrase: string; derivationPath: DerivationPathArray }) =>
|
|
237
|
+
getSignerFromPhrase({
|
|
238
|
+
derivationPath: derivationPathToString(derivationPath),
|
|
239
|
+
index,
|
|
240
|
+
phrase,
|
|
241
|
+
prefix: chainPrefix,
|
|
242
|
+
}),
|
|
243
|
+
getSignerFromPrivateKey: async (privateKey: Uint8Array) => {
|
|
244
|
+
const importedSigning = await import("@cosmjs/proto-signing");
|
|
245
|
+
const DirectSecp256k1Wallet =
|
|
246
|
+
importedSigning.DirectSecp256k1Wallet ?? importedSigning.default?.DirectSecp256k1Wallet;
|
|
247
|
+
return DirectSecp256k1Wallet.fromKey(privateKey, chainPrefix);
|
|
248
|
+
},
|
|
249
|
+
signTransaction,
|
|
250
|
+
transfer,
|
|
251
|
+
validateAddress: getCosmosValidateAddress(chain),
|
|
252
|
+
verifySignature: verifySignature(getAccount),
|
|
253
|
+
};
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
export async function getFeeRateFromSwapKit(chainId: ChainId, safeDefault: number) {
|
|
257
|
+
try {
|
|
258
|
+
const response = await SwapKitApi.getGasRate();
|
|
259
|
+
const responseGasRate = response.find((gas) => gas.chainId === chainId)?.value;
|
|
260
|
+
|
|
261
|
+
return responseGasRate ? Number.parseFloat(responseGasRate) : safeDefault;
|
|
262
|
+
} catch {
|
|
263
|
+
return safeDefault;
|
|
264
|
+
}
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
export function estimateTransactionFee({ assetValue: { chain } }: { assetValue: AssetValue }) {
|
|
268
|
+
return AssetValue.from({ chain, value: getMinTransactionFee(chain) });
|
|
269
|
+
}
|
|
270
|
+
|
|
271
|
+
async function getFees(chain: Chain, safeDefault: number) {
|
|
272
|
+
const { chainId, baseDecimal } = getChainConfig(chain);
|
|
273
|
+
|
|
274
|
+
const baseFee = await fetchFeeRateFromSwapKit(chainId, safeDefault);
|
|
275
|
+
return {
|
|
276
|
+
average: SwapKitNumber.fromBigInt(BigInt(baseFee), baseDecimal),
|
|
277
|
+
fast: SwapKitNumber.fromBigInt(BigInt(applyFeeMultiplier(baseFee, FeeOption.Fast, true)), baseDecimal),
|
|
278
|
+
fastest: SwapKitNumber.fromBigInt(BigInt(applyFeeMultiplier(baseFee, FeeOption.Fastest, true)), baseDecimal),
|
|
279
|
+
} as { [key in FeeOption]: SwapKitNumber };
|
|
280
|
+
}
|
|
281
|
+
|
|
282
|
+
function feeToStdFee(fee: SwapKitNumber, denom: string): StdFee {
|
|
283
|
+
return { amount: [{ amount: fee.getBaseValue("string"), denom }], gas: "200000" };
|
|
284
|
+
}
|
|
285
|
+
|
|
286
|
+
function getMinTransactionFee(chain: Chain) {
|
|
287
|
+
return (
|
|
288
|
+
{
|
|
289
|
+
[Chain.Cosmos]: 0.007,
|
|
290
|
+
[Chain.Kujira]: 0.02,
|
|
291
|
+
[Chain.Noble]: 0.01,
|
|
292
|
+
[Chain.THORChain]: 0.02,
|
|
293
|
+
[Chain.Maya]: 0.02,
|
|
294
|
+
[Chain.Harbor]: 0.02,
|
|
295
|
+
}[chain as CosmosChain] || 0
|
|
296
|
+
);
|
|
297
|
+
}
|
|
298
|
+
|
|
299
|
+
export function getCosmosValidateAddress(chain: CosmosChain) {
|
|
300
|
+
const chainPrefix = CosmosChainPrefixes[chain];
|
|
301
|
+
return function validateAddress(address: string) {
|
|
302
|
+
if (!address.startsWith(chainPrefix)) return false;
|
|
303
|
+
|
|
304
|
+
try {
|
|
305
|
+
const { prefix, words } = bech32.decode(address as `${string}1${string}`);
|
|
306
|
+
const normalized = bech32.encode(prefix, words);
|
|
307
|
+
|
|
308
|
+
return normalized === address.toLocaleLowerCase();
|
|
309
|
+
} catch {
|
|
310
|
+
return false;
|
|
311
|
+
}
|
|
312
|
+
};
|
|
313
|
+
}
|
|
314
|
+
|
|
315
|
+
function cosmosBalanceDenomsGetter(rpcUrl: string) {
|
|
316
|
+
return async function getCosmosBalanceDenoms(address: string) {
|
|
317
|
+
const client = await createStargateClient(rpcUrl);
|
|
318
|
+
const allBalances = await client.getAllBalances(address);
|
|
319
|
+
|
|
320
|
+
const balances = allBalances.map((balance) => ({
|
|
321
|
+
...balance,
|
|
322
|
+
denom: balance.denom.includes("/") ? balance.denom.toUpperCase() : balance.denom,
|
|
323
|
+
}));
|
|
324
|
+
|
|
325
|
+
return balances;
|
|
326
|
+
};
|
|
327
|
+
}
|
|
328
|
+
|
|
329
|
+
function createPrivateKeyFromPhrase(derivationPath: string) {
|
|
330
|
+
return async function createPrivateKeyFromPhrase(phrase: string) {
|
|
331
|
+
const importedCrypto = await import("@cosmjs/crypto");
|
|
332
|
+
const stringToPath = importedCrypto.stringToPath ?? importedCrypto.default?.stringToPath;
|
|
333
|
+
const Slip10Curve = importedCrypto.Slip10Curve ?? importedCrypto.default?.Slip10Curve;
|
|
334
|
+
const Slip10 = importedCrypto.Slip10 ?? importedCrypto.default?.Slip10;
|
|
335
|
+
const EnglishMnemonic = importedCrypto.EnglishMnemonic ?? importedCrypto.default?.EnglishMnemonic;
|
|
336
|
+
const Bip39 = importedCrypto.Bip39 ?? importedCrypto.default?.Bip39;
|
|
337
|
+
|
|
338
|
+
const mnemonicChecked = new EnglishMnemonic(phrase);
|
|
339
|
+
const seed = await Bip39.mnemonicToSeed(mnemonicChecked);
|
|
340
|
+
|
|
341
|
+
const { privkey } = Slip10.derivePath(Slip10Curve.Secp256k1, seed, stringToPath(derivationPath));
|
|
342
|
+
|
|
343
|
+
return privkey;
|
|
344
|
+
};
|
|
345
|
+
}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import { Chain, type CosmosChain, SwapKitError } from "@uswap/helpers";
|
|
2
|
+
|
|
3
|
+
import type { CosmosToolboxParams } from "../types";
|
|
4
|
+
import { createCosmosToolbox } from "./cosmos";
|
|
5
|
+
import { createThorchainToolbox } from "./thorchain";
|
|
6
|
+
|
|
7
|
+
export type CosmosToolboxes = {
|
|
8
|
+
GAIA: ReturnType<typeof createCosmosToolbox>;
|
|
9
|
+
KUJI: ReturnType<typeof createCosmosToolbox>;
|
|
10
|
+
MAYA: ReturnType<typeof createThorchainToolbox>;
|
|
11
|
+
NOBLE: ReturnType<typeof createCosmosToolbox>;
|
|
12
|
+
THOR: ReturnType<typeof createThorchainToolbox>;
|
|
13
|
+
};
|
|
14
|
+
|
|
15
|
+
export const getCosmosToolbox = <T extends Exclude<CosmosChain, Chain.Harbor>>(
|
|
16
|
+
chain: T,
|
|
17
|
+
params?: Omit<CosmosToolboxParams, "chain">,
|
|
18
|
+
): CosmosToolboxes[T] => {
|
|
19
|
+
switch (chain) {
|
|
20
|
+
case Chain.Cosmos:
|
|
21
|
+
case Chain.Kujira:
|
|
22
|
+
case Chain.Noble:
|
|
23
|
+
return createCosmosToolbox({ chain, ...params }) as CosmosToolboxes[T];
|
|
24
|
+
|
|
25
|
+
case Chain.Maya:
|
|
26
|
+
case Chain.THORChain:
|
|
27
|
+
return createThorchainToolbox({ chain, ...params }) as CosmosToolboxes[T];
|
|
28
|
+
|
|
29
|
+
default:
|
|
30
|
+
throw new SwapKitError("toolbox_cosmos_not_supported", { chain });
|
|
31
|
+
}
|
|
32
|
+
};
|
|
33
|
+
|
|
34
|
+
export * from "./cosmos";
|
|
35
|
+
export * from "./thorchain";
|
|
@@ -0,0 +1,249 @@
|
|
|
1
|
+
import type { Pubkey, Secp256k1HdWallet } from "@cosmjs/amino";
|
|
2
|
+
import { base64 } from "@scure/base";
|
|
3
|
+
import {
|
|
4
|
+
Chain,
|
|
5
|
+
CosmosChainPrefixes,
|
|
6
|
+
derivationPathToString,
|
|
7
|
+
FeeOption,
|
|
8
|
+
type GenericTransferParams,
|
|
9
|
+
getChainConfig,
|
|
10
|
+
getRPCUrl,
|
|
11
|
+
NetworkDerivationPath,
|
|
12
|
+
RequestClient,
|
|
13
|
+
SKConfig,
|
|
14
|
+
SwapKitError,
|
|
15
|
+
SwapKitNumber,
|
|
16
|
+
type TCLikeChain,
|
|
17
|
+
updateDerivationPath,
|
|
18
|
+
} from "@uswap/helpers";
|
|
19
|
+
|
|
20
|
+
import { match, P } from "ts-pattern";
|
|
21
|
+
import {
|
|
22
|
+
buildAminoMsg,
|
|
23
|
+
buildEncodedTxBody,
|
|
24
|
+
convertToSignable,
|
|
25
|
+
createDefaultAminoTypes,
|
|
26
|
+
createDefaultRegistry,
|
|
27
|
+
getCreateTransaction,
|
|
28
|
+
parseAminoMessageForDirectSigning,
|
|
29
|
+
} from "../thorchainUtils";
|
|
30
|
+
import type { ThorchainConstantsResponse } from "../thorchainUtils/types/client-types";
|
|
31
|
+
import type { CosmosToolboxParams, MultiSigSigner, MultisigTx } from "../types";
|
|
32
|
+
import {
|
|
33
|
+
createOfflineStargateClient,
|
|
34
|
+
createSigningStargateClient,
|
|
35
|
+
createStargateClient,
|
|
36
|
+
getDefaultChainFee,
|
|
37
|
+
} from "../util";
|
|
38
|
+
import { createCosmosToolbox } from "./cosmos";
|
|
39
|
+
|
|
40
|
+
function secp256k1HdWalletFromMnemonic({ prefix, derivationPath }: { prefix: string; derivationPath?: string }) {
|
|
41
|
+
return async function secp256k1HdWalletFromMnemonic(mnemonic: string, index = 0) {
|
|
42
|
+
const importedAmino = await import("@cosmjs/amino");
|
|
43
|
+
const Secp256k1HdWallet = importedAmino.Secp256k1HdWallet ?? importedAmino.default?.Secp256k1HdWallet;
|
|
44
|
+
const importedCrypto = await import("@cosmjs/crypto");
|
|
45
|
+
const stringToPath = importedCrypto.stringToPath ?? importedCrypto.default?.stringToPath;
|
|
46
|
+
|
|
47
|
+
return Secp256k1HdWallet.fromMnemonic(mnemonic, { hdPaths: [stringToPath(`${derivationPath}/${index}`)], prefix });
|
|
48
|
+
};
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
function exportSignature(signature: Uint8Array) {
|
|
52
|
+
return base64.encode(signature);
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
function signMultisigTx(chain: TCLikeChain) {
|
|
56
|
+
return async function signMultisigTx({ wallet, tx }: { wallet: Secp256k1HdWallet; tx: string | MultisigTx }) {
|
|
57
|
+
const { msgs, accountNumber, sequence, chainId, fee, memo } = typeof tx === "string" ? JSON.parse(tx) : tx;
|
|
58
|
+
|
|
59
|
+
const address = (await wallet.getAccounts())?.[0]?.address || "";
|
|
60
|
+
const aminoTypes = await createDefaultAminoTypes(chain);
|
|
61
|
+
const registry = await createDefaultRegistry();
|
|
62
|
+
const signingClient = await createOfflineStargateClient(wallet, { aminoTypes, registry });
|
|
63
|
+
const msgForSigning = [];
|
|
64
|
+
|
|
65
|
+
for (const msg of msgs) {
|
|
66
|
+
const signMsg = await convertToSignable(msg, chain);
|
|
67
|
+
msgForSigning.push(signMsg);
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
const {
|
|
71
|
+
signatures: [signature],
|
|
72
|
+
} = await signingClient.sign(address, msgForSigning, fee, memo, { accountNumber, chainId, sequence });
|
|
73
|
+
|
|
74
|
+
const bodyBytes = await buildEncodedTxBody({ chain, memo, msgs: msgs.map(parseAminoMessageForDirectSigning) });
|
|
75
|
+
|
|
76
|
+
return { bodyBytes, signature: exportSignature(signature as Uint8Array) };
|
|
77
|
+
};
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
function broadcastMultisigTx({ prefix, rpcUrl }: { prefix: string; rpcUrl: string }) {
|
|
81
|
+
return async function broadcastMultisigTx(
|
|
82
|
+
tx: string,
|
|
83
|
+
signers: MultiSigSigner[],
|
|
84
|
+
membersPubKeys: string[],
|
|
85
|
+
threshold: number,
|
|
86
|
+
bodyBytes: Uint8Array,
|
|
87
|
+
) {
|
|
88
|
+
const { encodeSecp256k1Pubkey, pubkeyToAddress } = (await import("@cosmjs/amino")).default;
|
|
89
|
+
const { makeMultisignedTxBytes } = (await import("@cosmjs/stargate")).default;
|
|
90
|
+
|
|
91
|
+
const { sequence, fee } = JSON.parse(tx);
|
|
92
|
+
const multisigPubkey = await createMultisig(membersPubKeys, threshold);
|
|
93
|
+
|
|
94
|
+
const addressesAndSignatures: [string, Uint8Array][] = signers.map((signer) => [
|
|
95
|
+
pubkeyToAddress(encodeSecp256k1Pubkey(base64.decode(signer.pubKey)), prefix),
|
|
96
|
+
base64.decode(signer.signature),
|
|
97
|
+
]);
|
|
98
|
+
|
|
99
|
+
const broadcaster = await createStargateClient(rpcUrl);
|
|
100
|
+
|
|
101
|
+
const { transactionHash } = await broadcaster.broadcastTx(
|
|
102
|
+
makeMultisignedTxBytes(
|
|
103
|
+
multisigPubkey,
|
|
104
|
+
sequence,
|
|
105
|
+
fee,
|
|
106
|
+
bodyBytes,
|
|
107
|
+
new Map<string, Uint8Array>(addressesAndSignatures),
|
|
108
|
+
),
|
|
109
|
+
);
|
|
110
|
+
|
|
111
|
+
return transactionHash;
|
|
112
|
+
};
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
async function createMultisig(pubKeys: string[], threshold: number, noSortPubKeys = true) {
|
|
116
|
+
const { createMultisigThresholdPubkey, encodeSecp256k1Pubkey } = (await import("@cosmjs/amino")).default;
|
|
117
|
+
return createMultisigThresholdPubkey(
|
|
118
|
+
pubKeys.map((pubKey) => encodeSecp256k1Pubkey(base64.decode(pubKey))),
|
|
119
|
+
threshold,
|
|
120
|
+
noSortPubKeys,
|
|
121
|
+
);
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
function importSignature(signature: string) {
|
|
125
|
+
return base64.decode(signature);
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
async function signWithPrivateKey({ privateKey, message }: { privateKey: Uint8Array; message: string }) {
|
|
129
|
+
const { Secp256k1 } = (await import("@cosmjs/crypto")).default;
|
|
130
|
+
|
|
131
|
+
const signature = await Secp256k1.createSignature(base64.decode(message), privateKey);
|
|
132
|
+
return base64.encode(Buffer.concat([signature.r(32), signature.s(32)]));
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
export async function createThorchainToolbox({ chain, ...toolboxParams }: CosmosToolboxParams<TCLikeChain>) {
|
|
136
|
+
const rpcUrl = await getRPCUrl(chain);
|
|
137
|
+
const { nodeUrl } = getChainConfig(chain);
|
|
138
|
+
const { isStagenet } = SKConfig.get("envs");
|
|
139
|
+
const isThorchain = chain === Chain.THORChain;
|
|
140
|
+
const chainPrefix = `${isStagenet ? "s" : ""}${CosmosChainPrefixes[chain]}`;
|
|
141
|
+
|
|
142
|
+
const index = "index" in toolboxParams ? toolboxParams.index || 0 : 0;
|
|
143
|
+
|
|
144
|
+
const derivationPath =
|
|
145
|
+
"derivationPath" in toolboxParams && toolboxParams.derivationPath
|
|
146
|
+
? toolboxParams.derivationPath
|
|
147
|
+
: updateDerivationPath(NetworkDerivationPath[chain], { index });
|
|
148
|
+
|
|
149
|
+
const cosmosToolbox = await createCosmosToolbox({ chain, ...toolboxParams });
|
|
150
|
+
|
|
151
|
+
const signer = await match(toolboxParams)
|
|
152
|
+
.with({ phrase: P.string }, ({ phrase }) => cosmosToolbox.getSignerFromPhrase({ derivationPath, phrase }))
|
|
153
|
+
.with({ signer: P.any }, ({ signer }) => signer)
|
|
154
|
+
.otherwise(() => undefined);
|
|
155
|
+
|
|
156
|
+
const defaultFee = getDefaultChainFee(chain);
|
|
157
|
+
|
|
158
|
+
async function getFees() {
|
|
159
|
+
let fee: SwapKitNumber;
|
|
160
|
+
|
|
161
|
+
const constantsUrl = `${nodeUrl}/${isThorchain ? "thorchain" : "mayachain"}/constants`;
|
|
162
|
+
|
|
163
|
+
try {
|
|
164
|
+
const {
|
|
165
|
+
int_64_values: { NativeTransactionFee: nativeFee },
|
|
166
|
+
} = await RequestClient.get<ThorchainConstantsResponse>(constantsUrl);
|
|
167
|
+
|
|
168
|
+
if (!nativeFee || Number.isNaN(nativeFee) || nativeFee < 0) {
|
|
169
|
+
throw new SwapKitError("toolbox_cosmos_invalid_fee", { nativeFee: nativeFee.toString() });
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
fee = new SwapKitNumber(nativeFee);
|
|
173
|
+
} catch {
|
|
174
|
+
fee = new SwapKitNumber({ decimal: getChainConfig(chain).baseDecimal, value: isThorchain ? 0.02 : 1 });
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
return { [FeeOption.Average]: fee, [FeeOption.Fast]: fee, [FeeOption.Fastest]: fee };
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
async function transfer({
|
|
181
|
+
assetValue,
|
|
182
|
+
memo = "",
|
|
183
|
+
recipient,
|
|
184
|
+
}: Omit<GenericTransferParams, "recipient"> & { recipient?: string }) {
|
|
185
|
+
const { TxRaw } = await import("cosmjs-types/cosmos/tx/v1beta1/tx");
|
|
186
|
+
const sender = (await signer?.getAccounts())?.[0]?.address;
|
|
187
|
+
if (!(sender && signer)) throw new SwapKitError("toolbox_cosmos_no_signer");
|
|
188
|
+
|
|
189
|
+
const isAminoSigner = "signAmino" in signer;
|
|
190
|
+
const registry = await createDefaultRegistry();
|
|
191
|
+
const aminoTypes = await createDefaultAminoTypes(chain);
|
|
192
|
+
const signingClient = await createSigningStargateClient(rpcUrl, signer, { aminoTypes, registry });
|
|
193
|
+
|
|
194
|
+
const aminoMessage = buildAminoMsg({ assetValue, memo, recipient, sender });
|
|
195
|
+
|
|
196
|
+
if (isAminoSigner) {
|
|
197
|
+
const msgSign = await convertToSignable(aminoMessage, chain);
|
|
198
|
+
|
|
199
|
+
const { signatures, authInfoBytes } = await signingClient.sign(sender, [msgSign], defaultFee, memo);
|
|
200
|
+
|
|
201
|
+
const tx = TxRaw.encode({
|
|
202
|
+
authInfoBytes,
|
|
203
|
+
bodyBytes: await buildEncodedTxBody({
|
|
204
|
+
chain,
|
|
205
|
+
memo,
|
|
206
|
+
msgs: [aminoMessage].map(parseAminoMessageForDirectSigning),
|
|
207
|
+
}),
|
|
208
|
+
signatures,
|
|
209
|
+
}).finish();
|
|
210
|
+
|
|
211
|
+
const txResponse = await signingClient.broadcastTx(tx);
|
|
212
|
+
|
|
213
|
+
return txResponse.transactionHash;
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
const preparedMessage = parseAminoMessageForDirectSigning(aminoMessage);
|
|
217
|
+
const msgSign = await convertToSignable(preparedMessage, chain);
|
|
218
|
+
const txResponse = await signingClient.signAndBroadcast(sender, [msgSign], defaultFee, memo);
|
|
219
|
+
|
|
220
|
+
return txResponse.transactionHash;
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
return {
|
|
224
|
+
...cosmosToolbox,
|
|
225
|
+
broadcastMultisigTx: broadcastMultisigTx({ prefix: chainPrefix, rpcUrl }),
|
|
226
|
+
buildAminoMsg,
|
|
227
|
+
buildEncodedTxBody,
|
|
228
|
+
convertToSignable,
|
|
229
|
+
createDefaultAminoTypes: () => createDefaultAminoTypes(chain),
|
|
230
|
+
createDefaultRegistry,
|
|
231
|
+
createMultisig,
|
|
232
|
+
createTransaction: getCreateTransaction(rpcUrl),
|
|
233
|
+
deposit: transfer,
|
|
234
|
+
getFees,
|
|
235
|
+
importSignature,
|
|
236
|
+
parseAminoMessageForDirectSigning,
|
|
237
|
+
pubkeyToAddress: async (pubkey: Pubkey) => {
|
|
238
|
+
const { pubkeyToAddress } = (await import("@cosmjs/amino")).default;
|
|
239
|
+
return pubkeyToAddress(pubkey, chainPrefix);
|
|
240
|
+
},
|
|
241
|
+
secp256k1HdWalletFromMnemonic: secp256k1HdWalletFromMnemonic({
|
|
242
|
+
derivationPath: derivationPathToString(derivationPath),
|
|
243
|
+
prefix: chainPrefix,
|
|
244
|
+
}),
|
|
245
|
+
signMultisigTx: signMultisigTx(chain),
|
|
246
|
+
signWithPrivateKey,
|
|
247
|
+
transfer,
|
|
248
|
+
};
|
|
249
|
+
}
|