@swapkit/toolboxes 1.0.0-beta.0 → 1.0.0-beta.2
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-0f0249b1.js +3 -0
- package/dist/chunk-0f0249b1.js.map +10 -0
- package/dist/chunk-0h4xdrwz.js +4 -0
- package/dist/chunk-0h4xdrwz.js.map +10 -0
- package/dist/chunk-4yap1fvd.js +3 -0
- package/dist/chunk-4yap1fvd.js.map +10 -0
- package/dist/chunk-fjfxga2v.js +3 -0
- package/dist/chunk-fjfxga2v.js.map +10 -0
- package/dist/{chunk-tvrdndbw.js → chunk-p1kdg37m.js} +2 -2
- package/dist/{chunk-tvrdndbw.js.map → chunk-p1kdg37m.js.map} +1 -1
- package/dist/cosmos/index.cjs +2 -2
- package/dist/cosmos/index.cjs.map +10 -13
- package/dist/cosmos/index.js +2 -2
- package/dist/cosmos/index.js.map +10 -13
- package/dist/evm/index.cjs +2 -2
- package/dist/evm/index.cjs.map +10 -16
- package/dist/evm/index.js +2 -2
- package/dist/evm/index.js.map +10 -16
- package/dist/index.cjs +2 -2
- package/dist/index.cjs.map +4 -3
- package/dist/index.js +2 -2
- package/dist/index.js.map +4 -3
- package/dist/radix/index.cjs +2 -2
- package/dist/radix/index.cjs.map +3 -3
- package/dist/radix/index.js +2 -2
- package/dist/radix/index.js.map +3 -3
- package/dist/ripple/index.cjs +3 -0
- package/dist/ripple/index.cjs.map +10 -0
- package/dist/ripple/index.js +3 -0
- package/dist/ripple/index.js.map +10 -0
- package/dist/solana/index.cjs +2 -2
- package/dist/solana/index.cjs.map +3 -3
- package/dist/solana/index.js +2 -2
- package/dist/solana/index.js.map +3 -3
- package/dist/substrate/index.cjs +2 -2
- package/dist/substrate/index.cjs.map +5 -6
- package/dist/substrate/index.js +2 -2
- package/dist/substrate/index.js.map +5 -6
- package/dist/utxo/index.cjs +2 -2
- package/dist/utxo/index.cjs.map +9 -11
- package/dist/utxo/index.js +2 -2
- package/dist/utxo/index.js.map +9 -11
- package/package.json +30 -24
- package/src/cosmos/index.ts +2 -9
- package/src/cosmos/thorchainUtils/addressFormat.ts +1 -2
- package/src/cosmos/thorchainUtils/index.ts +1 -1
- package/src/cosmos/thorchainUtils/messages.ts +74 -56
- package/src/cosmos/thorchainUtils/registry.ts +16 -23
- package/src/cosmos/thorchainUtils/types/{proto/MsgCompiled.ts → MsgCompiled.ts} +1 -3
- package/src/cosmos/thorchainUtils/types/client-types.ts +16 -23
- package/src/cosmos/toolbox/cosmos.ts +334 -0
- package/src/cosmos/toolbox/index.ts +33 -0
- package/src/cosmos/toolbox/thorchain.ts +118 -131
- package/src/cosmos/types.ts +37 -18
- package/src/cosmos/util.ts +21 -71
- package/src/evm/__tests__/ethereum.test.ts +110 -116
- package/src/evm/api.ts +11 -147
- package/src/evm/helpers.ts +111 -83
- package/src/evm/index.ts +1 -17
- package/src/evm/toolbox/baseEVMToolbox.ts +742 -0
- package/src/evm/toolbox/evm.ts +69 -0
- package/src/evm/toolbox/index.ts +36 -0
- package/src/evm/toolbox/op.ts +97 -143
- package/src/evm/types.ts +50 -28
- package/src/index.ts +235 -0
- package/src/radix/index.ts +18 -19
- package/src/ripple/index.ts +203 -0
- package/src/solana/index.ts +11 -5
- package/src/solana/toolbox.ts +223 -133
- package/src/substrate/index.ts +2 -3
- package/src/substrate/{toolbox/baseSubstrateToolbox.ts → substrate.ts} +104 -72
- package/src/substrate/types.ts +120 -0
- package/src/utils.ts +27 -0
- package/src/utxo/helpers/api.ts +27 -23
- package/src/utxo/helpers/bchaddrjs.ts +21 -21
- package/src/utxo/helpers/index.ts +0 -1
- package/src/utxo/helpers/txSize.ts +3 -4
- package/src/utxo/index.ts +3 -7
- package/src/utxo/toolbox/bitcoinCash.ts +164 -154
- package/src/utxo/toolbox/index.ts +63 -24
- package/src/utxo/toolbox/utxo.ts +376 -229
- package/src/utxo/types.ts +24 -39
- package/src/cosmos/thorchainUtils/types/proto/MsgCompiled.js +0 -2806
- package/src/cosmos/thorchainUtils/util.ts +0 -46
- package/src/cosmos/toolbox/BaseCosmosToolbox.ts +0 -254
- package/src/cosmos/toolbox/gaia.ts +0 -39
- package/src/cosmos/toolbox/getToolboxByChain.ts +0 -29
- package/src/cosmos/toolbox/kujira.ts +0 -61
- package/src/evm/provider.ts +0 -6
- package/src/evm/toolbox/EVMToolbox.ts +0 -662
- package/src/evm/toolbox/arb.ts +0 -61
- package/src/evm/toolbox/avax.ts +0 -36
- package/src/evm/toolbox/base.ts +0 -42
- package/src/evm/toolbox/bsc.ts +0 -34
- package/src/evm/toolbox/eth.ts +0 -44
- package/src/evm/toolbox/getToolboxByChain.ts +0 -42
- package/src/evm/toolbox/matic.ts +0 -42
- package/src/radix/toolbox.ts +0 -693
- package/src/substrate/toolbox/index.ts +0 -40
- package/src/substrate/types/index.ts +0 -2
- package/src/substrate/types/network.ts +0 -42
- package/src/substrate/types/wallet.ts +0 -78
- package/src/utxo/helpers/utils.ts +0 -45
|
@@ -1,60 +1,75 @@
|
|
|
1
|
-
import { ApiPromise
|
|
1
|
+
import type { ApiPromise } from "@polkadot/api";
|
|
2
2
|
import type { SubmittableExtrinsic } from "@polkadot/api/types";
|
|
3
3
|
import type { KeyringPair } from "@polkadot/keyring/types";
|
|
4
4
|
import type { Callback, IKeyringPair, ISubmittableResult, Signer } from "@polkadot/types/types";
|
|
5
5
|
import { hexToU8a, isHex, u8aToHex } from "@polkadot/util";
|
|
6
6
|
import {
|
|
7
|
-
cryptoWaitReady,
|
|
8
7
|
decodeAddress as decodePolkadotAddress,
|
|
9
8
|
encodeAddress as encodePolkadotAddress,
|
|
10
9
|
} from "@polkadot/util-crypto";
|
|
11
10
|
import {
|
|
12
11
|
AssetValue,
|
|
13
12
|
Chain,
|
|
13
|
+
type DerivationPathArray,
|
|
14
|
+
type GenericCreateTransactionParams,
|
|
14
15
|
SKConfig,
|
|
15
16
|
type SubstrateChain,
|
|
16
17
|
SwapKitError,
|
|
17
18
|
SwapKitNumber,
|
|
18
19
|
} from "@swapkit/helpers";
|
|
19
20
|
|
|
20
|
-
import {
|
|
21
|
+
import { P, match } from "ts-pattern";
|
|
22
|
+
import { getBalance } from "../utils";
|
|
23
|
+
import { SubstrateNetwork, type SubstrateTransferParams } from "./types";
|
|
21
24
|
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
recipient: string;
|
|
25
|
-
assetValue: AssetValue;
|
|
26
|
-
from?: string;
|
|
25
|
+
export const PolkadotToolbox = ({ generic = false, ...signerParams }: ToolboxParams = {}) => {
|
|
26
|
+
return createSubstrateToolbox({ chain: Chain.Polkadot, generic, ...signerParams });
|
|
27
27
|
};
|
|
28
28
|
|
|
29
|
-
export const
|
|
30
|
-
|
|
31
|
-
|
|
29
|
+
export const ChainflipToolbox = async ({
|
|
30
|
+
generic = false,
|
|
31
|
+
...signerParams
|
|
32
|
+
}: ToolboxParams = {}) => {
|
|
33
|
+
const toolbox = await createSubstrateToolbox({
|
|
34
|
+
chain: Chain.Chainflip,
|
|
35
|
+
generic,
|
|
36
|
+
...signerParams,
|
|
37
|
+
});
|
|
32
38
|
|
|
33
|
-
|
|
34
|
-
|
|
39
|
+
return { ...toolbox, getBalance: getBalance(Chain.Chainflip) };
|
|
40
|
+
};
|
|
35
41
|
|
|
36
|
-
|
|
42
|
+
export type SubstrateToolboxes = {
|
|
43
|
+
DOT: Awaited<ReturnType<typeof PolkadotToolbox>>;
|
|
44
|
+
FLIP: Awaited<ReturnType<typeof ChainflipToolbox>>;
|
|
37
45
|
};
|
|
38
46
|
|
|
39
|
-
|
|
47
|
+
export function getSubstrateToolbox<T extends SubstrateChain>(chain: T, params?: ToolboxParams) {
|
|
48
|
+
switch (chain) {
|
|
49
|
+
case Chain.Chainflip: {
|
|
50
|
+
return ChainflipToolbox(params);
|
|
51
|
+
}
|
|
52
|
+
case Chain.Polkadot: {
|
|
53
|
+
return PolkadotToolbox(params);
|
|
54
|
+
}
|
|
55
|
+
default:
|
|
56
|
+
throw new Error(`Chain ${chain} is not supported`);
|
|
57
|
+
}
|
|
58
|
+
}
|
|
40
59
|
|
|
41
|
-
|
|
42
|
-
|
|
60
|
+
export function isKeyringPair(account: IKeyringPair | Signer): account is IKeyringPair {
|
|
61
|
+
return "address" in account;
|
|
62
|
+
}
|
|
43
63
|
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
64
|
+
export async function createKeyring(phrase: string, networkPrefix: number) {
|
|
65
|
+
const { Keyring } = await import("@polkadot/api");
|
|
66
|
+
const { cryptoWaitReady } = await import("@polkadot/util-crypto");
|
|
67
|
+
await cryptoWaitReady();
|
|
48
68
|
|
|
49
|
-
return
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
"string",
|
|
54
|
-
),
|
|
55
|
-
),
|
|
56
|
-
];
|
|
57
|
-
};
|
|
69
|
+
return new Keyring({ type: "sr25519", ss58Format: networkPrefix }).addFromUri(phrase);
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
const getNonce = (api: ApiPromise, address: string) => api.rpc.system.accountNextIndex(address);
|
|
58
73
|
|
|
59
74
|
const validateAddress = (address: string, networkPrefix: number) => {
|
|
60
75
|
try {
|
|
@@ -68,26 +83,24 @@ const validateAddress = (address: string, networkPrefix: number) => {
|
|
|
68
83
|
}
|
|
69
84
|
};
|
|
70
85
|
|
|
71
|
-
const
|
|
72
|
-
api
|
|
73
|
-
{ recipient, amount }: { recipient: string; amount: number },
|
|
74
|
-
) => api.tx.balances?.transferAllowDeath?.(recipient, amount);
|
|
86
|
+
const createTransaction = (api: ApiPromise, { recipient, assetValue }: SubstrateTransferParams) =>
|
|
87
|
+
api.tx.balances?.transferAllowDeath?.(recipient, assetValue.getBaseValue("number"));
|
|
75
88
|
|
|
76
89
|
const transfer = async (
|
|
77
90
|
api: ApiPromise,
|
|
78
91
|
signer: IKeyringPair | Signer,
|
|
79
|
-
{ recipient, assetValue,
|
|
92
|
+
{ recipient, assetValue, sender }: SubstrateTransferParams,
|
|
80
93
|
) => {
|
|
81
|
-
const transfer =
|
|
94
|
+
const transfer = createTransaction(api, {
|
|
82
95
|
recipient,
|
|
83
|
-
|
|
96
|
+
assetValue,
|
|
84
97
|
});
|
|
85
98
|
|
|
86
99
|
const isKeyring = isKeyringPair(signer);
|
|
87
100
|
|
|
88
101
|
if (!transfer) return;
|
|
89
102
|
|
|
90
|
-
const address =
|
|
103
|
+
const address = isKeyring ? (signer as IKeyringPair).address : sender;
|
|
91
104
|
if (!address) throw new SwapKitError("core_transaction_invalid_sender_address");
|
|
92
105
|
|
|
93
106
|
const nonce = await getNonce(api, address);
|
|
@@ -104,11 +117,11 @@ const estimateTransactionFee = async (
|
|
|
104
117
|
api: ApiPromise,
|
|
105
118
|
signer: IKeyringPair | Signer,
|
|
106
119
|
gasAsset: AssetValue,
|
|
107
|
-
{ recipient, assetValue,
|
|
120
|
+
{ recipient, assetValue, sender }: SubstrateTransferParams,
|
|
108
121
|
) => {
|
|
109
|
-
const transfer =
|
|
122
|
+
const transfer = createTransaction(api, { recipient, assetValue });
|
|
110
123
|
|
|
111
|
-
const address =
|
|
124
|
+
const address = isKeyringPair(signer) ? signer.address : sender;
|
|
112
125
|
if (!address) return;
|
|
113
126
|
|
|
114
127
|
const paymentInfo = (await transfer?.paymentInfo(address, {
|
|
@@ -199,7 +212,7 @@ export const BaseSubstrateToolbox = ({
|
|
|
199
212
|
api: ApiPromise;
|
|
200
213
|
network: SubstrateNetwork;
|
|
201
214
|
gasAsset: AssetValue;
|
|
202
|
-
signer
|
|
215
|
+
signer?: IKeyringPair | Signer;
|
|
203
216
|
}) => ({
|
|
204
217
|
api,
|
|
205
218
|
network,
|
|
@@ -207,27 +220,34 @@ export const BaseSubstrateToolbox = ({
|
|
|
207
220
|
decodeAddress,
|
|
208
221
|
encodeAddress,
|
|
209
222
|
convertAddress,
|
|
223
|
+
getBalance: getBalance(Chain.Polkadot),
|
|
210
224
|
createKeyring: (phrase: string) => createKeyring(phrase, network.prefix),
|
|
211
|
-
getAddress: (keyring
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
225
|
+
getAddress: (keyring?: IKeyringPair | Signer) => {
|
|
226
|
+
const keyringPair = keyring || signer;
|
|
227
|
+
if (!keyringPair) throw new SwapKitError("core_wallet_not_keypair_wallet");
|
|
228
|
+
|
|
229
|
+
return isKeyringPair(keyringPair) ? keyringPair.address : undefined;
|
|
230
|
+
},
|
|
231
|
+
createTransaction: (params: GenericCreateTransactionParams) => createTransaction(api, params),
|
|
216
232
|
validateAddress: (address: string) => validateAddress(address, network.prefix),
|
|
217
|
-
transfer: (params: SubstrateTransferParams) =>
|
|
218
|
-
|
|
219
|
-
|
|
233
|
+
transfer: (params: SubstrateTransferParams) => {
|
|
234
|
+
if (!signer) throw new SwapKitError("core_wallet_not_keypair_wallet");
|
|
235
|
+
return transfer(api, signer, params);
|
|
236
|
+
},
|
|
237
|
+
estimateTransactionFee: (params: SubstrateTransferParams) => {
|
|
238
|
+
if (!signer) throw new SwapKitError("core_wallet_not_keypair_wallet");
|
|
239
|
+
return estimateTransactionFee(api, signer, gasAsset, params);
|
|
240
|
+
},
|
|
220
241
|
sign: (tx: SubmittableExtrinsic<"promise">) => {
|
|
221
|
-
if (
|
|
222
|
-
|
|
223
|
-
|
|
242
|
+
if (!signer) throw new SwapKitError("core_wallet_not_keypair_wallet");
|
|
243
|
+
if (isKeyringPair(signer)) return sign(signer, tx);
|
|
244
|
+
|
|
224
245
|
throw new SwapKitError(
|
|
225
246
|
"core_wallet_not_keypair_wallet",
|
|
226
247
|
"Signer does not have keyring pair capabilities required for signing.",
|
|
227
248
|
);
|
|
228
249
|
},
|
|
229
|
-
broadcast
|
|
230
|
-
broadcast(tx, callback),
|
|
250
|
+
broadcast,
|
|
231
251
|
signAndBroadcast: ({
|
|
232
252
|
tx,
|
|
233
253
|
callback,
|
|
@@ -237,9 +257,8 @@ export const BaseSubstrateToolbox = ({
|
|
|
237
257
|
callback?: Callback<ISubmittableResult>;
|
|
238
258
|
address?: string;
|
|
239
259
|
}) => {
|
|
240
|
-
if (
|
|
241
|
-
|
|
242
|
-
}
|
|
260
|
+
if (!signer) throw new SwapKitError("core_wallet_not_keypair_wallet");
|
|
261
|
+
if (isKeyringPair(signer)) return signAndBroadcastKeyring(signer, tx, callback);
|
|
243
262
|
|
|
244
263
|
if (address) {
|
|
245
264
|
return signAndBroadcast({ signer, address, tx, callback, api });
|
|
@@ -256,31 +275,44 @@ export const substrateValidateAddress = ({
|
|
|
256
275
|
address,
|
|
257
276
|
chain,
|
|
258
277
|
}: { address: string; chain: Chain.Polkadot | Chain.Chainflip }) => {
|
|
259
|
-
const { prefix } = chain === Chain.Polkadot ?
|
|
278
|
+
const { prefix } = chain === Chain.Polkadot ? SubstrateNetwork.DOT : SubstrateNetwork.FLIP;
|
|
260
279
|
|
|
261
|
-
return
|
|
280
|
+
return (
|
|
281
|
+
validateAddress(address, prefix) || validateAddress(address, SubstrateNetwork.GENERIC.prefix)
|
|
282
|
+
);
|
|
262
283
|
};
|
|
263
284
|
|
|
264
|
-
export async function
|
|
285
|
+
export async function createSubstrateToolbox({
|
|
265
286
|
generic,
|
|
266
287
|
chain,
|
|
267
|
-
|
|
288
|
+
...signerParams
|
|
268
289
|
}: ToolboxParams & { chain: SubstrateChain }) {
|
|
269
|
-
const
|
|
270
|
-
|
|
290
|
+
const { ApiPromise, WsProvider } = await import("@polkadot/api");
|
|
291
|
+
|
|
292
|
+
const provider = new WsProvider(SKConfig.get("rpcUrls")[chain]);
|
|
271
293
|
const api = await ApiPromise.create({ provider });
|
|
272
294
|
const gasAsset = AssetValue.from({ chain });
|
|
273
|
-
const network = generic ?
|
|
295
|
+
const network = generic ? SubstrateNetwork.GENERIC : SubstrateNetwork[chain];
|
|
296
|
+
|
|
297
|
+
const signer = await match(signerParams)
|
|
298
|
+
.with({ phrase: P.string }, ({ phrase }) =>
|
|
299
|
+
createKeyring(phrase, SubstrateNetwork[chain].prefix),
|
|
300
|
+
)
|
|
301
|
+
.with({ signer: P.any }, ({ signer }) => signer)
|
|
302
|
+
.otherwise(() => undefined);
|
|
274
303
|
|
|
275
304
|
return BaseSubstrateToolbox({ api, signer, gasAsset, network });
|
|
276
305
|
}
|
|
277
306
|
|
|
278
307
|
export type ToolboxParams = {
|
|
279
308
|
generic?: boolean;
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
309
|
+
} & (
|
|
310
|
+
| {
|
|
311
|
+
signer?: KeyringPair | Signer;
|
|
312
|
+
}
|
|
313
|
+
| {
|
|
314
|
+
phrase?: string;
|
|
315
|
+
derivationPath?: DerivationPathArray;
|
|
316
|
+
index?: number;
|
|
317
|
+
}
|
|
318
|
+
);
|
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
import type { Signer as InjectedSigner } from "@polkadot/api/types";
|
|
2
|
+
import type { ProviderInterface } from "@polkadot/rpc-provider/types";
|
|
3
|
+
import type { ExtDef } from "@polkadot/types/extrinsic/signedExtensions/types";
|
|
4
|
+
import type { KeypairType } from "@polkadot/util-crypto/types";
|
|
5
|
+
import type { GenericTransferParams, SubstrateChain } from "@swapkit/helpers";
|
|
6
|
+
|
|
7
|
+
const polkadotNetwork = {
|
|
8
|
+
prefix: 0,
|
|
9
|
+
network: "polkadot",
|
|
10
|
+
displayName: "Polkadot Relay Chain",
|
|
11
|
+
symbols: ["DOT"],
|
|
12
|
+
decimals: [10],
|
|
13
|
+
standardAccount: "*25519",
|
|
14
|
+
website: "https://polkadot.network",
|
|
15
|
+
};
|
|
16
|
+
|
|
17
|
+
const chainflipNetwork = {
|
|
18
|
+
prefix: 2112,
|
|
19
|
+
network: "chainflip",
|
|
20
|
+
displayName: "Chainflip",
|
|
21
|
+
symbols: ["FLIP"],
|
|
22
|
+
decimals: [18],
|
|
23
|
+
standardAccount: "*25519",
|
|
24
|
+
website: "https://chainflip.io/",
|
|
25
|
+
};
|
|
26
|
+
|
|
27
|
+
const subtrateNetwork = {
|
|
28
|
+
prefix: 42,
|
|
29
|
+
network: "substrate",
|
|
30
|
+
displayName: "Substrate",
|
|
31
|
+
symbols: [],
|
|
32
|
+
decimals: [],
|
|
33
|
+
standardAccount: "*25519",
|
|
34
|
+
website: "https://substrate.io/",
|
|
35
|
+
};
|
|
36
|
+
|
|
37
|
+
export const SubstrateNetwork: Record<SubstrateChain | "GENERIC", SubstrateNetwork> = {
|
|
38
|
+
DOT: polkadotNetwork,
|
|
39
|
+
FLIP: chainflipNetwork,
|
|
40
|
+
GENERIC: subtrateNetwork,
|
|
41
|
+
};
|
|
42
|
+
|
|
43
|
+
export type SubstrateNetwork =
|
|
44
|
+
| typeof polkadotNetwork
|
|
45
|
+
| typeof chainflipNetwork
|
|
46
|
+
| typeof subtrateNetwork;
|
|
47
|
+
|
|
48
|
+
export type SubstrateTransferParams = GenericTransferParams & {
|
|
49
|
+
sender?: string;
|
|
50
|
+
};
|
|
51
|
+
|
|
52
|
+
type Unsubcall = () => void;
|
|
53
|
+
|
|
54
|
+
interface InjectedAccount {
|
|
55
|
+
address: string;
|
|
56
|
+
genesisHash?: string | null;
|
|
57
|
+
name?: string;
|
|
58
|
+
type?: KeypairType;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
interface InjectedAccounts {
|
|
62
|
+
get: (anyType?: boolean) => Promise<InjectedAccount[]>;
|
|
63
|
+
subscribe: (cb: (accounts: InjectedAccount[]) => void | Promise<void>) => Unsubcall;
|
|
64
|
+
}
|
|
65
|
+
interface InjectedExtensionInfo {
|
|
66
|
+
name: string;
|
|
67
|
+
version: string;
|
|
68
|
+
}
|
|
69
|
+
interface ProviderMeta {
|
|
70
|
+
network: string;
|
|
71
|
+
node: "full" | "light";
|
|
72
|
+
source: string;
|
|
73
|
+
transport: string;
|
|
74
|
+
}
|
|
75
|
+
interface MetadataDefBase {
|
|
76
|
+
chain: string;
|
|
77
|
+
genesisHash: string;
|
|
78
|
+
icon: string;
|
|
79
|
+
ss58Format: number;
|
|
80
|
+
chainType?: "substrate" | "ethereum";
|
|
81
|
+
}
|
|
82
|
+
interface MetadataDef extends MetadataDefBase {
|
|
83
|
+
color?: string;
|
|
84
|
+
specVersion: number;
|
|
85
|
+
tokenDecimals: number;
|
|
86
|
+
tokenSymbol: string;
|
|
87
|
+
types: Record<string, Record<string, string> | string>;
|
|
88
|
+
metaCalls?: string;
|
|
89
|
+
userExtensions?: ExtDef;
|
|
90
|
+
}
|
|
91
|
+
interface InjectedMetadataKnown {
|
|
92
|
+
genesisHash: string;
|
|
93
|
+
specVersion: number;
|
|
94
|
+
}
|
|
95
|
+
interface InjectedMetadata {
|
|
96
|
+
get: () => Promise<InjectedMetadataKnown[]>;
|
|
97
|
+
provide: (definition: MetadataDef) => Promise<boolean>;
|
|
98
|
+
}
|
|
99
|
+
type ProviderList = Record<string, ProviderMeta>;
|
|
100
|
+
|
|
101
|
+
interface InjectedProvider extends ProviderInterface {
|
|
102
|
+
listProviders: () => Promise<ProviderList>;
|
|
103
|
+
startProvider: (key: string) => Promise<ProviderMeta>;
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
type InjectedWalletData = {
|
|
107
|
+
accounts: InjectedAccounts;
|
|
108
|
+
metadata?: InjectedMetadata;
|
|
109
|
+
provider?: InjectedProvider;
|
|
110
|
+
signer: InjectedSigner;
|
|
111
|
+
};
|
|
112
|
+
|
|
113
|
+
export type SubstrateInjectedExtension = Record<
|
|
114
|
+
string,
|
|
115
|
+
{
|
|
116
|
+
connect?: (origin: string) => Promise<InjectedExtensionInfo & InjectedWalletData>;
|
|
117
|
+
enable?: (origin: string) => Promise<InjectedWalletData>;
|
|
118
|
+
version?: string;
|
|
119
|
+
}
|
|
120
|
+
>;
|
package/src/utils.ts
ADDED
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { AssetValue, BaseDecimal, type Chain } from "@swapkit/helpers";
|
|
2
|
+
import { SwapKitApi } from "@swapkit/helpers/api";
|
|
3
|
+
|
|
4
|
+
const pid = typeof process !== "undefined" && process.pid ? process.pid.toString(36) : "";
|
|
5
|
+
|
|
6
|
+
let last = 0;
|
|
7
|
+
export function uniqid() {
|
|
8
|
+
function now() {
|
|
9
|
+
const time = Date.now();
|
|
10
|
+
const lastTime = last || time;
|
|
11
|
+
last = lastTime;
|
|
12
|
+
|
|
13
|
+
return time > last ? time : lastTime + 1;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
return pid + now().toString(36);
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
export function getBalance<T extends Chain>(chain: T) {
|
|
20
|
+
return async function getBalance(address: string, scamFilter = true) {
|
|
21
|
+
const balances = await SwapKitApi.getChainBalance({ chain, address, scamFilter });
|
|
22
|
+
|
|
23
|
+
return balances.map(({ identifier, value, decimal }) => {
|
|
24
|
+
return new AssetValue({ decimal: decimal || BaseDecimal[chain], value, identifier });
|
|
25
|
+
});
|
|
26
|
+
};
|
|
27
|
+
}
|
package/src/utxo/helpers/api.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { Chain, RequestClient, SKConfig, type UTXOChain, warnOnce } from "@swapkit/helpers";
|
|
2
|
-
import { uniqid } from "
|
|
2
|
+
import { uniqid } from "../../utils";
|
|
3
3
|
|
|
4
4
|
type BlockchairParams<T> = T & { chain: Chain; apiKey?: string };
|
|
5
5
|
type BlockchairFetchUnspentUtxoParams = BlockchairParams<{
|
|
@@ -129,25 +129,6 @@ async function getUnconfirmedBalance({
|
|
|
129
129
|
return response?.address.balance || 0;
|
|
130
130
|
}
|
|
131
131
|
|
|
132
|
-
async function getConfirmedBalance({
|
|
133
|
-
chain,
|
|
134
|
-
address,
|
|
135
|
-
apiKey,
|
|
136
|
-
}: BlockchairParams<{ address?: string }>) {
|
|
137
|
-
if (!address) throw new Error("address is required");
|
|
138
|
-
|
|
139
|
-
try {
|
|
140
|
-
const response = await blockchairRequest<BlockchairMultipleBalancesResponse>(
|
|
141
|
-
`${baseUrl(chain)}/addresses/balances?addresses=${address}`,
|
|
142
|
-
apiKey,
|
|
143
|
-
);
|
|
144
|
-
|
|
145
|
-
return response[address] || 0;
|
|
146
|
-
} catch (_error) {
|
|
147
|
-
return 0;
|
|
148
|
-
}
|
|
149
|
-
}
|
|
150
|
-
|
|
151
132
|
async function getRawTx({ chain, apiKey, txHash }: BlockchairParams<{ txHash?: string }>) {
|
|
152
133
|
if (!txHash) throw new Error("txHash is required");
|
|
153
134
|
|
|
@@ -251,7 +232,6 @@ function utxoApi(chain: UTXOChain) {
|
|
|
251
232
|
|
|
252
233
|
return {
|
|
253
234
|
broadcastTx: (txHash: string) => broadcastUTXOTx({ txHash, chain }),
|
|
254
|
-
getConfirmedBalance: (address: string) => getConfirmedBalance({ chain, address, apiKey }),
|
|
255
235
|
getRawTx: (txHash: string) => getRawTx({ txHash, chain, apiKey }),
|
|
256
236
|
getSuggestedTxFee: () => getSuggestedTxFee(chain),
|
|
257
237
|
getBalance: (address: string) => getUnconfirmedBalance({ address, chain, apiKey }),
|
|
@@ -279,8 +259,32 @@ export function getUtxoApi(chain: UTXOChain) {
|
|
|
279
259
|
return utxoApi(chain);
|
|
280
260
|
}
|
|
281
261
|
|
|
282
|
-
|
|
283
|
-
|
|
262
|
+
export async function getUtxoNetwork() {
|
|
263
|
+
// @ts-ignore
|
|
264
|
+
const coininfo = await import("coininfo");
|
|
265
|
+
const { networks } = await import("bitcoinjs-lib");
|
|
266
|
+
|
|
267
|
+
return function getNetwork(chain: Chain) {
|
|
268
|
+
switch (chain) {
|
|
269
|
+
case Chain.Bitcoin:
|
|
270
|
+
return networks.bitcoin;
|
|
271
|
+
case Chain.BitcoinCash:
|
|
272
|
+
return coininfo.bitcoincash.main.toBitcoinJS();
|
|
273
|
+
case Chain.Dash:
|
|
274
|
+
return coininfo.dash.main.toBitcoinJS();
|
|
275
|
+
case Chain.Litecoin:
|
|
276
|
+
return coininfo.litecoin.main.toBitcoinJS();
|
|
277
|
+
|
|
278
|
+
case Chain.Dogecoin: {
|
|
279
|
+
const bip32 = { private: 0x04358394, public: 0x043587cf };
|
|
280
|
+
const test = coininfo.dogecoin.test;
|
|
281
|
+
test.versions.bip32 = bip32;
|
|
282
|
+
return coininfo.dogecoin.main.toBitcoinJS();
|
|
283
|
+
}
|
|
284
|
+
default:
|
|
285
|
+
throw new Error("Invalid chain");
|
|
286
|
+
}
|
|
287
|
+
};
|
|
284
288
|
}
|
|
285
289
|
|
|
286
290
|
interface BlockchairVin {
|
|
@@ -7,7 +7,7 @@ enum Format {
|
|
|
7
7
|
Bitpay = "bitpay",
|
|
8
8
|
Cashaddr = "cashaddr",
|
|
9
9
|
}
|
|
10
|
-
enum
|
|
10
|
+
enum UtxoNetwork {
|
|
11
11
|
Mainnet = "mainnet",
|
|
12
12
|
Testnet = "testnet",
|
|
13
13
|
}
|
|
@@ -18,21 +18,21 @@ enum Type {
|
|
|
18
18
|
|
|
19
19
|
const VERSION_BYTE = {
|
|
20
20
|
[Format.Legacy]: {
|
|
21
|
-
[
|
|
21
|
+
[UtxoNetwork.Mainnet]: {
|
|
22
22
|
[Type.P2PKH]: 0,
|
|
23
23
|
[Type.P2SH]: 5,
|
|
24
24
|
},
|
|
25
|
-
[
|
|
25
|
+
[UtxoNetwork.Testnet]: {
|
|
26
26
|
[Type.P2PKH]: 111,
|
|
27
27
|
[Type.P2SH]: 196,
|
|
28
28
|
},
|
|
29
29
|
},
|
|
30
30
|
[Format.Bitpay]: {
|
|
31
|
-
[
|
|
31
|
+
[UtxoNetwork.Mainnet]: {
|
|
32
32
|
[Type.P2PKH]: 28,
|
|
33
33
|
[Type.P2SH]: 40,
|
|
34
34
|
},
|
|
35
|
-
[
|
|
35
|
+
[UtxoNetwork.Testnet]: {
|
|
36
36
|
[Type.P2PKH]: 111,
|
|
37
37
|
[Type.P2SH]: 196,
|
|
38
38
|
},
|
|
@@ -41,7 +41,7 @@ const VERSION_BYTE = {
|
|
|
41
41
|
|
|
42
42
|
type DecodedType = {
|
|
43
43
|
format: Format;
|
|
44
|
-
network:
|
|
44
|
+
network: UtxoNetwork;
|
|
45
45
|
type: Type;
|
|
46
46
|
hash: any;
|
|
47
47
|
};
|
|
@@ -97,23 +97,23 @@ function decodeBase58Address(address: string) {
|
|
|
97
97
|
const hash = Array.prototype.slice.call(payload, 1);
|
|
98
98
|
|
|
99
99
|
switch (versionByte) {
|
|
100
|
-
case VERSION_BYTE[Format.Legacy][
|
|
101
|
-
return { hash, format: Format.Legacy, network:
|
|
100
|
+
case VERSION_BYTE[Format.Legacy][UtxoNetwork.Mainnet][Type.P2PKH]:
|
|
101
|
+
return { hash, format: Format.Legacy, network: UtxoNetwork.Mainnet, type: Type.P2PKH };
|
|
102
102
|
|
|
103
|
-
case VERSION_BYTE[Format.Legacy][
|
|
104
|
-
return { hash, format: Format.Legacy, network:
|
|
103
|
+
case VERSION_BYTE[Format.Legacy][UtxoNetwork.Mainnet][Type.P2SH]:
|
|
104
|
+
return { hash, format: Format.Legacy, network: UtxoNetwork.Mainnet, type: Type.P2SH };
|
|
105
105
|
|
|
106
|
-
case VERSION_BYTE[Format.Legacy][
|
|
107
|
-
return { hash, format: Format.Legacy, network:
|
|
106
|
+
case VERSION_BYTE[Format.Legacy][UtxoNetwork.Testnet][Type.P2PKH]:
|
|
107
|
+
return { hash, format: Format.Legacy, network: UtxoNetwork.Testnet, type: Type.P2PKH };
|
|
108
108
|
|
|
109
|
-
case VERSION_BYTE[Format.Legacy][
|
|
110
|
-
return { hash, format: Format.Legacy, network:
|
|
109
|
+
case VERSION_BYTE[Format.Legacy][UtxoNetwork.Testnet][Type.P2SH]:
|
|
110
|
+
return { hash, format: Format.Legacy, network: UtxoNetwork.Testnet, type: Type.P2SH };
|
|
111
111
|
|
|
112
|
-
case VERSION_BYTE[Format.Bitpay][
|
|
113
|
-
return { hash, format: Format.Bitpay, network:
|
|
112
|
+
case VERSION_BYTE[Format.Bitpay][UtxoNetwork.Mainnet][Type.P2PKH]:
|
|
113
|
+
return { hash, format: Format.Bitpay, network: UtxoNetwork.Mainnet, type: Type.P2PKH };
|
|
114
114
|
|
|
115
|
-
case VERSION_BYTE[Format.Bitpay][
|
|
116
|
-
return { hash, format: Format.Bitpay, network:
|
|
115
|
+
case VERSION_BYTE[Format.Bitpay][UtxoNetwork.Mainnet][Type.P2SH]:
|
|
116
|
+
return { hash, format: Format.Bitpay, network: UtxoNetwork.Mainnet, type: Type.P2SH };
|
|
117
117
|
|
|
118
118
|
default:
|
|
119
119
|
throw new Error("Received an invalid Bitcoin Cash address as input.");
|
|
@@ -151,7 +151,7 @@ function decodeCashAddressWithPrefix(address: string): DecodedType {
|
|
|
151
151
|
return {
|
|
152
152
|
format: Format.Cashaddr,
|
|
153
153
|
hash: Array.prototype.slice.call(hash, 0),
|
|
154
|
-
network: prefix === "bitcoincash" ?
|
|
154
|
+
network: prefix === "bitcoincash" ? UtxoNetwork.Mainnet : UtxoNetwork.Testnet,
|
|
155
155
|
type: type === "P2PKH" ? Type.P2PKH : Type.P2SH,
|
|
156
156
|
};
|
|
157
157
|
} catch (_error) {
|
|
@@ -168,10 +168,10 @@ function encodeAsLegacy(decoded: DecodedType) {
|
|
|
168
168
|
}
|
|
169
169
|
|
|
170
170
|
function encodeAsCashaddr(decoded: DecodedType) {
|
|
171
|
-
const prefix = decoded.network ===
|
|
171
|
+
const prefix = decoded.network === UtxoNetwork.Mainnet ? "bitcoincash" : "bchtest";
|
|
172
172
|
const type = decoded.type === Type.P2PKH ? "P2PKH" : "P2SH";
|
|
173
173
|
const hash = new Uint8Array(decoded.hash);
|
|
174
174
|
return cashaddr.encode(prefix, type, hash);
|
|
175
175
|
}
|
|
176
176
|
|
|
177
|
-
export { detectAddressNetwork, isValidAddress,
|
|
177
|
+
export { detectAddressNetwork, isValidAddress, UtxoNetwork, toCashAddress, toLegacyAddress };
|
|
@@ -1,5 +1,3 @@
|
|
|
1
|
-
import { opcodes, script } from "bitcoinjs-lib";
|
|
2
|
-
|
|
3
1
|
import type {
|
|
4
2
|
TargetOutput,
|
|
5
3
|
UTXOCalculateTxSizeParams,
|
|
@@ -18,10 +16,11 @@ export const OP_RETURN_OVERHEAD = 1 + 8 + 1; //10
|
|
|
18
16
|
const TX_INPUT_BASE = 32 + 4 + 1 + 4; // 41
|
|
19
17
|
const TX_INPUT_PUBKEYHASH = 107;
|
|
20
18
|
|
|
21
|
-
export
|
|
19
|
+
export async function compileMemo(memo: string) {
|
|
20
|
+
const { script, opcodes } = await import("bitcoinjs-lib");
|
|
22
21
|
const data = Buffer.from(memo, "utf8"); // converts MEMO to buffer
|
|
23
22
|
return script.compile([opcodes.OP_RETURN as number, data]); // Compile OP_RETURN script
|
|
24
|
-
}
|
|
23
|
+
}
|
|
25
24
|
|
|
26
25
|
export enum UTXOScriptType {
|
|
27
26
|
P2PKH = "P2PKH", // legacy
|
package/src/utxo/index.ts
CHANGED
|
@@ -1,9 +1,5 @@
|
|
|
1
|
-
export
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* Package
|
|
5
|
-
*/
|
|
6
|
-
export * from "./toolbox/index";
|
|
1
|
+
export * from "./toolbox";
|
|
2
|
+
export * from "./toolbox/bitcoinCash";
|
|
7
3
|
export * from "./toolbox/utxo";
|
|
8
|
-
export * from "./helpers
|
|
4
|
+
export * from "./helpers";
|
|
9
5
|
export * from "./types";
|