@swapkit/wallets 3.0.0-beta.3 → 3.0.0-beta.31
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-0qaxr89s.js +3 -0
- package/dist/chunk-0qaxr89s.js.map +10 -0
- package/dist/chunk-2aa1w78q.js +3 -0
- package/dist/chunk-2aa1w78q.js.map +10 -0
- package/dist/chunk-bexr8da2.js +4 -0
- package/dist/chunk-bexr8da2.js.map +10 -0
- package/dist/chunk-dcj9twam.js +3 -0
- package/dist/chunk-dcj9twam.js.map +10 -0
- package/dist/{chunk-p1kdg37m.js → chunk-qwd1kp32.js} +2 -2
- package/dist/{chunk-p1kdg37m.js.map → chunk-qwd1kp32.js.map} +1 -1
- package/dist/chunk-sn6pgje5.js +3 -0
- package/dist/chunk-sn6pgje5.js.map +10 -0
- package/dist/chunk-th8ggrmx.js +4 -0
- package/dist/{chunk-czhtd6cy.js.map → chunk-th8ggrmx.js.map} +3 -3
- package/dist/chunk-wfattb4a.js +3 -0
- package/dist/chunk-wfattb4a.js.map +10 -0
- package/dist/chunk-yah6cf33.js +3 -0
- package/dist/{chunk-qadd75nn.js.map → chunk-yah6cf33.js.map} +3 -3
- package/dist/src/bitget/index.cjs +2 -2
- package/dist/src/bitget/index.cjs.map +3 -3
- package/dist/src/bitget/index.js +2 -2
- package/dist/src/bitget/index.js.map +3 -3
- package/dist/src/coinbase/index.cjs +2 -2
- package/dist/src/coinbase/index.cjs.map +3 -3
- package/dist/src/coinbase/index.js +2 -2
- package/dist/src/coinbase/index.js.map +3 -3
- package/dist/src/cosmostation/index.cjs +3 -0
- package/dist/src/cosmostation/index.cjs.map +10 -0
- package/dist/src/cosmostation/index.js +3 -0
- package/dist/src/cosmostation/index.js.map +10 -0
- package/dist/src/ctrl/index.cjs +2 -2
- package/dist/src/ctrl/index.cjs.map +4 -4
- package/dist/src/ctrl/index.js +2 -2
- package/dist/src/ctrl/index.js.map +4 -4
- package/dist/src/evm-extensions/index.cjs +2 -2
- package/dist/src/evm-extensions/index.cjs.map +3 -3
- package/dist/src/evm-extensions/index.js +2 -2
- package/dist/src/evm-extensions/index.js.map +3 -3
- package/dist/src/exodus/index.cjs +2 -2
- package/dist/src/exodus/index.cjs.map +3 -3
- package/dist/src/exodus/index.js +2 -2
- package/dist/src/exodus/index.js.map +3 -3
- package/dist/src/index.js +2 -2
- package/dist/src/index.js.map +1 -1
- package/dist/src/keepkey/index.cjs +2 -2
- package/dist/src/keepkey/index.cjs.map +9 -9
- package/dist/src/keepkey/index.js +2 -2
- package/dist/src/keepkey/index.js.map +9 -9
- package/dist/src/keepkey-bex/index.cjs +2 -2
- package/dist/src/keepkey-bex/index.cjs.map +4 -4
- package/dist/src/keepkey-bex/index.js +2 -2
- package/dist/src/keepkey-bex/index.js.map +4 -4
- package/dist/src/keplr/index.cjs +2 -2
- package/dist/src/keplr/index.cjs.map +3 -3
- package/dist/src/keplr/index.js +2 -2
- package/dist/src/keplr/index.js.map +3 -3
- package/dist/src/keystore/index.cjs +2 -2
- package/dist/src/keystore/index.cjs.map +4 -4
- package/dist/src/keystore/index.js +2 -2
- package/dist/src/keystore/index.js.map +4 -4
- package/dist/src/ledger/index.cjs +3 -3
- package/dist/src/ledger/index.cjs.map +17 -15
- package/dist/src/ledger/index.js +3 -3
- package/dist/src/ledger/index.js.map +17 -15
- package/dist/src/okx/index.cjs +2 -2
- package/dist/src/okx/index.cjs.map +4 -4
- package/dist/src/okx/index.js +2 -2
- package/dist/src/okx/index.js.map +4 -4
- package/dist/src/onekey/index.cjs +2 -2
- package/dist/src/onekey/index.cjs.map +3 -3
- package/dist/src/onekey/index.js +2 -2
- package/dist/src/onekey/index.js.map +3 -3
- package/dist/src/phantom/index.js +2 -2
- package/dist/src/phantom/index.js.map +2 -2
- package/dist/src/polkadotjs/index.js +2 -2
- package/dist/src/polkadotjs/index.js.map +1 -1
- package/dist/src/radix/index.cjs +2 -2
- package/dist/src/radix/index.cjs.map +3 -3
- package/dist/src/radix/index.js +2 -2
- package/dist/src/radix/index.js.map +3 -3
- package/dist/src/talisman/index.js +2 -2
- package/dist/src/talisman/index.js.map +1 -1
- package/dist/src/trezor/index.cjs +2 -2
- package/dist/src/trezor/index.cjs.map +3 -3
- package/dist/src/trezor/index.js +2 -2
- package/dist/src/trezor/index.js.map +3 -3
- package/dist/src/walletconnect/index.cjs +2 -2
- package/dist/src/walletconnect/index.cjs.map +6 -7
- package/dist/src/walletconnect/index.js +2 -2
- package/dist/src/walletconnect/index.js.map +6 -7
- package/package.json +36 -28
- package/src/bitget/helpers.ts +4 -4
- package/src/coinbase/signer.ts +4 -4
- package/src/cosmostation/index.ts +142 -0
- package/src/ctrl/index.ts +83 -0
- package/src/ctrl/walletHelpers.ts +98 -70
- package/src/evm-extensions/index.ts +4 -3
- package/src/exodus/index.ts +8 -9
- package/src/helpers/near-browser-provider.d.ts +286 -0
- package/src/helpers/near.ts +206 -0
- package/src/keepkey/chains/cosmos.ts +44 -50
- package/src/keepkey/chains/evm.ts +16 -8
- package/src/keepkey/chains/mayachain.ts +3 -2
- package/src/keepkey/chains/thorchain.ts +3 -2
- package/src/keepkey/chains/utxo.ts +14 -3
- package/src/keepkey/coins.ts +10 -4
- package/src/keepkey/index.ts +15 -7
- package/src/keepkey-bex/index.ts +9 -14
- package/src/keepkey-bex/walletHelpers.ts +1 -1
- package/src/keplr/index.ts +4 -3
- package/src/keystore/helpers.ts +2 -4
- package/src/keystore/index.ts +2 -0
- package/src/ledger/clients/cosmos.ts +5 -4
- package/src/ledger/clients/evm.ts +7 -6
- package/src/ledger/clients/near.ts +86 -0
- package/src/ledger/clients/thorchain/helpers.ts +9 -4
- package/src/ledger/clients/thorchain/index.ts +3 -3
- package/src/ledger/clients/thorchain/lib.ts +3 -2
- package/src/ledger/clients/thorchain/utils.ts +20 -9
- package/src/ledger/clients/utxo.ts +3 -5
- package/src/ledger/clients/xrp.ts +66 -0
- package/src/ledger/cosmosTypes.ts +14 -10
- package/src/ledger/helpers/getLedgerAddress.ts +17 -3
- package/src/ledger/helpers/getLedgerClient.ts +63 -45
- package/src/ledger/helpers/getLedgerTransport.ts +5 -3
- package/src/ledger/index.ts +28 -7
- package/src/ledger/interfaces/CosmosLedgerInterface.ts +1 -2
- package/src/okx/helpers.ts +27 -9
- package/src/okx/index.ts +1 -0
- package/src/onekey/index.ts +3 -7
- package/src/radix/index.ts +4 -4
- package/src/trezor/evmSigner.ts +4 -4
- package/src/trezor/index.ts +14 -4
- package/src/types.ts +14 -0
- package/src/utils.ts +4 -0
- package/src/walletconnect/constants.ts +2 -0
- package/src/walletconnect/evmSigner.ts +8 -4
- package/src/walletconnect/helpers.ts +9 -2
- package/src/walletconnect/index.ts +134 -24
- package/dist/chunk-bhfpfqc3.js +0 -3
- package/dist/chunk-bhfpfqc3.js.map +0 -10
- package/dist/chunk-czhtd6cy.js +0 -4
- package/dist/chunk-q81hzyra.js +0 -3
- package/dist/chunk-q81hzyra.js.map +0 -10
- package/dist/chunk-qadd75nn.js +0 -3
package/src/keystore/helpers.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { createCipheriv, createDecipheriv, pbkdf2Sync, randomBytes } from "node:crypto";
|
|
1
2
|
import { generateMnemonic, validateMnemonic } from "@scure/bip39";
|
|
2
3
|
import { wordlist } from "@scure/bip39/wordlists/english";
|
|
3
4
|
|
|
@@ -15,7 +16,7 @@ export type Keystore = {
|
|
|
15
16
|
};
|
|
16
17
|
|
|
17
18
|
async function blake256(initData: Buffer | string) {
|
|
18
|
-
const { blake2bFinal, blake2bInit, blake2bUpdate } = await import("blakejs");
|
|
19
|
+
const { blake2bFinal, blake2bInit, blake2bUpdate } = (await import("blakejs")).default;
|
|
19
20
|
let data = initData;
|
|
20
21
|
|
|
21
22
|
if (!(data instanceof Buffer)) {
|
|
@@ -32,8 +33,6 @@ async function blake256(initData: Buffer | string) {
|
|
|
32
33
|
}
|
|
33
34
|
|
|
34
35
|
export async function encryptToKeyStore(phrase: string, password: string) {
|
|
35
|
-
const { pbkdf2Sync, randomBytes, createCipheriv } = await import("node:crypto");
|
|
36
|
-
|
|
37
36
|
const cipher = "aes-128-ctr";
|
|
38
37
|
const iv = randomBytes(16);
|
|
39
38
|
const salt = randomBytes(32);
|
|
@@ -71,7 +70,6 @@ export function validatePhrase(phrase: string) {
|
|
|
71
70
|
}
|
|
72
71
|
|
|
73
72
|
export async function decryptFromKeystore(keystore: Keystore, password: string) {
|
|
74
|
-
const { createDecipheriv, pbkdf2Sync } = await import("node:crypto");
|
|
75
73
|
const { SwapKitError } = await import("@swapkit/helpers");
|
|
76
74
|
|
|
77
75
|
switch (keystore.version) {
|
package/src/keystore/index.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import {
|
|
2
2
|
type DerivationPathArray,
|
|
3
3
|
NetworkDerivationPath,
|
|
4
|
+
SwapKitError,
|
|
4
5
|
derivationPathToString,
|
|
5
6
|
} from "@swapkit/helpers";
|
|
6
7
|
import { CosmosLedgerInterface } from "../interfaces/CosmosLedgerInterface";
|
|
@@ -41,7 +42,7 @@ export class CosmosLedger extends CosmosLedgerInterface {
|
|
|
41
42
|
rawTx,
|
|
42
43
|
);
|
|
43
44
|
|
|
44
|
-
if (!this.pubKey) throw new
|
|
45
|
+
if (!this.pubKey) throw new SwapKitError("wallet_ledger_pubkey_not_found");
|
|
45
46
|
|
|
46
47
|
this.validateResponse(return_code, error_message);
|
|
47
48
|
|
|
@@ -61,11 +62,11 @@ export class CosmosLedger extends CosmosLedgerInterface {
|
|
|
61
62
|
const accountIndex = accounts.findIndex((account) => account.address === signerAddress);
|
|
62
63
|
|
|
63
64
|
if (accountIndex === -1) {
|
|
64
|
-
throw new
|
|
65
|
+
throw new SwapKitError("wallet_ledger_address_not_found", { address: signerAddress });
|
|
65
66
|
}
|
|
66
67
|
|
|
67
|
-
const { encodeSecp256k1Signature, serializeSignDoc } = await import("@cosmjs/amino");
|
|
68
|
-
const { Secp256k1Signature } = await import("@cosmjs/crypto");
|
|
68
|
+
const { encodeSecp256k1Signature, serializeSignDoc } = (await import("@cosmjs/amino")).default;
|
|
69
|
+
const { Secp256k1Signature } = (await import("@cosmjs/crypto")).default;
|
|
69
70
|
|
|
70
71
|
const message = serializeSignDoc(signDoc);
|
|
71
72
|
const signature = await this.ledgerApp.sign(this.derivationPath, message);
|
|
@@ -3,6 +3,7 @@ import {
|
|
|
3
3
|
ChainId,
|
|
4
4
|
type DerivationPathArray,
|
|
5
5
|
NetworkDerivationPath,
|
|
6
|
+
SwapKitError,
|
|
6
7
|
derivationPathToString,
|
|
7
8
|
} from "@swapkit/helpers";
|
|
8
9
|
import { AbstractSigner, type Provider, type TransactionRequest } from "ethers";
|
|
@@ -51,14 +52,14 @@ class EVMLedgerInterface extends AbstractSigner {
|
|
|
51
52
|
|
|
52
53
|
createTransportAndLedger = async () => {
|
|
53
54
|
const transport = await getLedgerTransport();
|
|
54
|
-
const
|
|
55
|
+
const EthereumApp = (await import("@ledgerhq/hw-app-eth")).default;
|
|
55
56
|
|
|
56
57
|
this.ledgerApp = new EthereumApp(transport);
|
|
57
58
|
};
|
|
58
59
|
|
|
59
60
|
getAddress = async () => {
|
|
60
61
|
const response = await this.getAddressAndPubKey();
|
|
61
|
-
if (!response) throw new
|
|
62
|
+
if (!response) throw new SwapKitError("wallet_ledger_failed_to_get_address");
|
|
62
63
|
return response.address;
|
|
63
64
|
};
|
|
64
65
|
|
|
@@ -78,7 +79,7 @@ class EVMLedgerInterface extends AbstractSigner {
|
|
|
78
79
|
|
|
79
80
|
const sig = await this.ledgerApp?.signPersonalMessage(this.derivationPath, messageHex);
|
|
80
81
|
|
|
81
|
-
if (!sig) throw new
|
|
82
|
+
if (!sig) throw new SwapKitError("wallet_ledger_signing_error");
|
|
82
83
|
|
|
83
84
|
sig.r = `0x${sig.r}`;
|
|
84
85
|
sig.s = `0x${sig.s}`;
|
|
@@ -86,7 +87,7 @@ class EVMLedgerInterface extends AbstractSigner {
|
|
|
86
87
|
};
|
|
87
88
|
|
|
88
89
|
sendTransaction = async (tx: TransactionRequest): Promise<any> => {
|
|
89
|
-
if (!this.provider) throw new
|
|
90
|
+
if (!this.provider) throw new SwapKitError("wallet_ledger_no_provider");
|
|
90
91
|
|
|
91
92
|
const signedTxHex = await this.signTransaction(tx);
|
|
92
93
|
|
|
@@ -94,7 +95,7 @@ class EVMLedgerInterface extends AbstractSigner {
|
|
|
94
95
|
};
|
|
95
96
|
|
|
96
97
|
signTypedData(): Promise<string> {
|
|
97
|
-
throw new
|
|
98
|
+
throw new SwapKitError("wallet_ledger_method_not_supported", { method: "signTypedData" });
|
|
98
99
|
}
|
|
99
100
|
|
|
100
101
|
signTransaction = async (tx: TransactionRequest) => {
|
|
@@ -141,7 +142,7 @@ class EVMLedgerInterface extends AbstractSigner {
|
|
|
141
142
|
resolution,
|
|
142
143
|
);
|
|
143
144
|
|
|
144
|
-
if (!signature) throw new
|
|
145
|
+
if (!signature) throw new SwapKitError("wallet_ledger_signing_error");
|
|
145
146
|
|
|
146
147
|
const { r, s, v } = signature;
|
|
147
148
|
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
import type Transport from "@ledgerhq/hw-transport";
|
|
2
|
+
import type { DerivationPathArray } from "@swapkit/helpers";
|
|
3
|
+
import type { NearSigner } from "@swapkit/toolboxes/near";
|
|
4
|
+
import type { SignedTransaction, Transaction } from "near-api-js/lib/transaction";
|
|
5
|
+
|
|
6
|
+
export async function getNearLedgerClient(
|
|
7
|
+
transport: Transport,
|
|
8
|
+
derivationPath?: DerivationPathArray,
|
|
9
|
+
) {
|
|
10
|
+
const Near = await import("@ledgerhq/hw-app-near");
|
|
11
|
+
const { Chain, DerivationPath, derivationPathToString, SwapKitError } = await import(
|
|
12
|
+
"@swapkit/helpers"
|
|
13
|
+
);
|
|
14
|
+
const nearApp = new Near.default(transport);
|
|
15
|
+
|
|
16
|
+
// NEAR uses m/44'/397'/0'/0'/0' by default
|
|
17
|
+
const path = derivationPath ? derivationPathToString(derivationPath) : DerivationPath[Chain.Near];
|
|
18
|
+
|
|
19
|
+
// Get address and public key from Ledger
|
|
20
|
+
const { address, publicKey: pubKeyHex } = await nearApp.getAddress(path);
|
|
21
|
+
|
|
22
|
+
const signer = {
|
|
23
|
+
async getPublicKey() {
|
|
24
|
+
const { utils } = await import("near-api-js");
|
|
25
|
+
// Convert hex public key to NEAR PublicKey format
|
|
26
|
+
return utils.PublicKey.fromString(`ed25519:${pubKeyHex}`);
|
|
27
|
+
},
|
|
28
|
+
|
|
29
|
+
signNep413Message(
|
|
30
|
+
_message: string,
|
|
31
|
+
_accountId: string,
|
|
32
|
+
_recipient: string,
|
|
33
|
+
_nonce: Uint8Array,
|
|
34
|
+
_callbackUrl?: string,
|
|
35
|
+
) {
|
|
36
|
+
// Most NEAR Ledger apps don't support arbitrary message signing
|
|
37
|
+
return Promise.reject(
|
|
38
|
+
new SwapKitError("wallet_ledger_method_not_supported", {
|
|
39
|
+
wallet: "Ledger",
|
|
40
|
+
method: "signNep413Message",
|
|
41
|
+
}),
|
|
42
|
+
);
|
|
43
|
+
},
|
|
44
|
+
|
|
45
|
+
getAddress() {
|
|
46
|
+
return Promise.resolve(address);
|
|
47
|
+
},
|
|
48
|
+
|
|
49
|
+
async signTransaction(transaction: Transaction) {
|
|
50
|
+
const { Signature, SignedTransaction } = await import("near-api-js/lib/transaction");
|
|
51
|
+
try {
|
|
52
|
+
const signatureArray = await nearApp.signTransaction(transaction.encode(), path);
|
|
53
|
+
if (!signatureArray) {
|
|
54
|
+
throw new Error("Signature undefined");
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
const signature = new Signature({
|
|
58
|
+
keyType: 0,
|
|
59
|
+
data: signatureArray,
|
|
60
|
+
});
|
|
61
|
+
|
|
62
|
+
const signedTransaction = new SignedTransaction({ transaction, signature });
|
|
63
|
+
|
|
64
|
+
return [signatureArray, signedTransaction] as [
|
|
65
|
+
Uint8Array<ArrayBufferLike>,
|
|
66
|
+
SignedTransaction,
|
|
67
|
+
];
|
|
68
|
+
} catch (error) {
|
|
69
|
+
throw new SwapKitError("wallet_ledger_signing_error", {
|
|
70
|
+
error,
|
|
71
|
+
});
|
|
72
|
+
}
|
|
73
|
+
},
|
|
74
|
+
|
|
75
|
+
signDelegateAction(_delegateAction: any) {
|
|
76
|
+
return Promise.reject(
|
|
77
|
+
new SwapKitError("wallet_ledger_method_not_supported", {
|
|
78
|
+
wallet: "Ledger",
|
|
79
|
+
method: "signDelegateAction",
|
|
80
|
+
}),
|
|
81
|
+
);
|
|
82
|
+
},
|
|
83
|
+
};
|
|
84
|
+
|
|
85
|
+
return signer as NearSigner;
|
|
86
|
+
}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { SwapKitError } from "@swapkit/helpers";
|
|
1
2
|
import {
|
|
2
3
|
CLA,
|
|
3
4
|
ERROR_CODE,
|
|
@@ -10,10 +11,10 @@ import {
|
|
|
10
11
|
|
|
11
12
|
export function serializePathv1(path: number[]) {
|
|
12
13
|
if (path == null || path.length < 3) {
|
|
13
|
-
throw new
|
|
14
|
+
throw new SwapKitError("wallet_ledger_invalid_params", { reason: "Path too short" });
|
|
14
15
|
}
|
|
15
16
|
if (path.length > 10) {
|
|
16
|
-
throw new
|
|
17
|
+
throw new SwapKitError("wallet_ledger_invalid_params", { reason: "Path too long" });
|
|
17
18
|
}
|
|
18
19
|
const buf = Buffer.alloc(1 + 4 * path.length);
|
|
19
20
|
buf.writeUInt8(path.length, 0);
|
|
@@ -61,7 +62,9 @@ export async function signSendChunkv1(
|
|
|
61
62
|
|
|
62
63
|
function compressPublicKey(publicKey: Buffer) {
|
|
63
64
|
if (publicKey.length !== 65) {
|
|
64
|
-
throw new
|
|
65
|
+
throw new SwapKitError("wallet_ledger_invalid_params", {
|
|
66
|
+
reason: "decompressed public key length should be 65 bytes",
|
|
67
|
+
});
|
|
65
68
|
}
|
|
66
69
|
const y = publicKey.slice(33, 65);
|
|
67
70
|
|
|
@@ -90,7 +93,9 @@ export async function publicKeyv1(app: any, data: Buffer) {
|
|
|
90
93
|
|
|
91
94
|
export function serializePathv2(path: number[]) {
|
|
92
95
|
if (!path || path.length !== 5) {
|
|
93
|
-
throw new
|
|
96
|
+
throw new SwapKitError("wallet_ledger_invalid_params", {
|
|
97
|
+
reason: "Path must be exactly 5 elements",
|
|
98
|
+
});
|
|
94
99
|
}
|
|
95
100
|
|
|
96
101
|
const buf = Buffer.alloc(20);
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { base64 } from "@scure/base";
|
|
2
|
-
import { type DerivationPathArray, NetworkDerivationPath } from "@swapkit/helpers";
|
|
2
|
+
import { type DerivationPathArray, NetworkDerivationPath, SwapKitError } from "@swapkit/helpers";
|
|
3
3
|
|
|
4
4
|
import { CosmosLedgerInterface } from "../../interfaces/CosmosLedgerInterface";
|
|
5
5
|
import type { GetAddressAndPubKeyResponse } from "../../types";
|
|
@@ -64,7 +64,7 @@ export class THORChainLedger extends CosmosLedgerInterface {
|
|
|
64
64
|
rawTx,
|
|
65
65
|
);
|
|
66
66
|
|
|
67
|
-
if (!this.pubKey) throw new
|
|
67
|
+
if (!this.pubKey) throw new SwapKitError("wallet_ledger_pubkey_not_found");
|
|
68
68
|
|
|
69
69
|
this.validateResponse(return_code, error_message);
|
|
70
70
|
|
|
@@ -85,7 +85,7 @@ export class THORChainLedger extends CosmosLedgerInterface {
|
|
|
85
85
|
message,
|
|
86
86
|
);
|
|
87
87
|
|
|
88
|
-
if (!this.pubKey) throw new
|
|
88
|
+
if (!this.pubKey) throw new SwapKitError("wallet_ledger_pubkey_not_found");
|
|
89
89
|
|
|
90
90
|
this.validateResponse(return_code, error_message);
|
|
91
91
|
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type Transport from "@ledgerhq/hw-transport";
|
|
2
|
+
import { SwapKitError } from "@swapkit/helpers";
|
|
2
3
|
/** ******************************************************************************
|
|
3
4
|
* (c) 2019 ZondaX GmbH
|
|
4
5
|
* (c) 2016-2017 Ledger
|
|
@@ -42,7 +43,7 @@ export class THORChainApp {
|
|
|
42
43
|
|
|
43
44
|
constructor(transport: any) {
|
|
44
45
|
if (!transport) {
|
|
45
|
-
throw new
|
|
46
|
+
throw new SwapKitError("wallet_ledger_transport_not_defined");
|
|
46
47
|
}
|
|
47
48
|
|
|
48
49
|
this.transport = transport;
|
|
@@ -50,7 +51,7 @@ export class THORChainApp {
|
|
|
50
51
|
|
|
51
52
|
static serializeHRP(hrp: string) {
|
|
52
53
|
if (hrp == null || hrp.length < 3 || hrp.length > 83) {
|
|
53
|
-
throw new
|
|
54
|
+
throw new SwapKitError("wallet_ledger_invalid_params", { reason: "Invalid HRP" });
|
|
54
55
|
}
|
|
55
56
|
const buf = Buffer.alloc(1 + hrp.length);
|
|
56
57
|
buf.writeUInt8(hrp.length, 0);
|
|
@@ -1,19 +1,26 @@
|
|
|
1
1
|
import { base64 } from "@scure/base";
|
|
2
|
+
import { SwapKitError } from "@swapkit/helpers";
|
|
2
3
|
|
|
3
4
|
// biome-ignore lint/complexity/noExcessiveCognitiveComplexity: any: refactor
|
|
4
5
|
export const getSignature = (signatureArray: any) => {
|
|
5
6
|
// Check Type Length Value encoding
|
|
6
7
|
if (signatureArray.length < 64) {
|
|
7
|
-
throw new
|
|
8
|
+
throw new SwapKitError("wallet_ledger_invalid_signature", { reason: "Too short" });
|
|
8
9
|
}
|
|
9
10
|
if (signatureArray[0] !== 0x30) {
|
|
10
|
-
throw new
|
|
11
|
+
throw new SwapKitError("wallet_ledger_invalid_signature", {
|
|
12
|
+
reason: "TLV encoding: expected first byte 0x30",
|
|
13
|
+
});
|
|
11
14
|
}
|
|
12
15
|
if (signatureArray[1] + 2 !== signatureArray.length) {
|
|
13
|
-
throw new
|
|
16
|
+
throw new SwapKitError("wallet_ledger_invalid_signature", {
|
|
17
|
+
reason: "signature length does not match TLV",
|
|
18
|
+
});
|
|
14
19
|
}
|
|
15
20
|
if (signatureArray[2] !== 0x02) {
|
|
16
|
-
throw new
|
|
21
|
+
throw new SwapKitError("wallet_ledger_invalid_signature", {
|
|
22
|
+
reason: "TLV encoding: expected length type 0x02",
|
|
23
|
+
});
|
|
17
24
|
}
|
|
18
25
|
|
|
19
26
|
// r signature
|
|
@@ -24,7 +31,7 @@ export const getSignature = (signatureArray: any) => {
|
|
|
24
31
|
if (rSignature.length === 33 && rSignature[0] === 0) {
|
|
25
32
|
rSignature = rSignature.slice(1, 33);
|
|
26
33
|
} else if (rSignature.length === 33) {
|
|
27
|
-
throw new
|
|
34
|
+
throw new SwapKitError("wallet_ledger_invalid_signature", { reason: "r too long" });
|
|
28
35
|
}
|
|
29
36
|
|
|
30
37
|
// add leading zero's to pad to 32 bytes
|
|
@@ -34,13 +41,17 @@ export const getSignature = (signatureArray: any) => {
|
|
|
34
41
|
|
|
35
42
|
// s signature
|
|
36
43
|
if (signatureArray[rLength + 4] !== 0x02) {
|
|
37
|
-
throw new
|
|
44
|
+
throw new SwapKitError("wallet_ledger_invalid_signature", {
|
|
45
|
+
reason: "TLV encoding: expected length type 0x02 for s",
|
|
46
|
+
});
|
|
38
47
|
}
|
|
39
48
|
|
|
40
49
|
const sLength = signatureArray[rLength + 5];
|
|
41
50
|
|
|
42
51
|
if (4 + rLength + 2 + sLength !== signatureArray.length) {
|
|
43
|
-
throw new
|
|
52
|
+
throw new SwapKitError("wallet_ledger_invalid_signature", {
|
|
53
|
+
reason: "TLV byte lengths do not match message length",
|
|
54
|
+
});
|
|
44
55
|
}
|
|
45
56
|
|
|
46
57
|
let sSignature = signatureArray.slice(rLength + 6, signatureArray.length);
|
|
@@ -49,7 +60,7 @@ export const getSignature = (signatureArray: any) => {
|
|
|
49
60
|
if (sSignature.length === 33 && sSignature[0] === 0) {
|
|
50
61
|
sSignature = sSignature.slice(1, 33);
|
|
51
62
|
} else if (sSignature.length === 33) {
|
|
52
|
-
throw new
|
|
63
|
+
throw new SwapKitError("wallet_ledger_invalid_signature", { reason: "s too long" });
|
|
53
64
|
}
|
|
54
65
|
|
|
55
66
|
// add leading zero's to pad to 32 bytes
|
|
@@ -58,7 +69,7 @@ export const getSignature = (signatureArray: any) => {
|
|
|
58
69
|
}
|
|
59
70
|
|
|
60
71
|
if (rSignature.length !== 32 || sSignature.length !== 32) {
|
|
61
|
-
throw new
|
|
72
|
+
throw new SwapKitError("wallet_ledger_invalid_signature", { reason: "must be 32 bytes each" });
|
|
62
73
|
}
|
|
63
74
|
|
|
64
75
|
return base64.encode(Buffer.concat([rSignature, sSignature]));
|
|
@@ -7,7 +7,7 @@ import {
|
|
|
7
7
|
getWalletFormatFor,
|
|
8
8
|
} from "@swapkit/helpers";
|
|
9
9
|
import type { UTXOType } from "@swapkit/toolboxes/utxo";
|
|
10
|
-
import type
|
|
10
|
+
import { type Psbt, Transaction } from "bitcoinjs-lib";
|
|
11
11
|
|
|
12
12
|
import { getLedgerTransport } from "../helpers/getLedgerTransport";
|
|
13
13
|
|
|
@@ -22,8 +22,6 @@ const signUTXOTransaction = async (
|
|
|
22
22
|
{ psbt, inputUtxos, btcApp, derivationPath }: Params,
|
|
23
23
|
options?: Partial<CreateTransactionArg>,
|
|
24
24
|
) => {
|
|
25
|
-
const { Transaction } = await import("bitcoinjs-lib");
|
|
26
|
-
|
|
27
25
|
const inputs = inputUtxos.map((item) => {
|
|
28
26
|
const utxoTx = Transaction.fromHex(item.txHex || "");
|
|
29
27
|
const splitTx = btcApp.splitTransaction(utxoTx.toHex(), utxoTx.hasWitnesses());
|
|
@@ -75,7 +73,7 @@ const BaseLedgerUTXO = ({
|
|
|
75
73
|
|
|
76
74
|
async function createTransportWebUSB() {
|
|
77
75
|
transport = await getLedgerTransport();
|
|
78
|
-
const
|
|
76
|
+
const BitcoinApp = (await import("@ledgerhq/hw-app-btc")).default;
|
|
79
77
|
|
|
80
78
|
btcApp = new BitcoinApp({ transport, currency: chain });
|
|
81
79
|
}
|
|
@@ -91,7 +89,7 @@ const BaseLedgerUTXO = ({
|
|
|
91
89
|
return {
|
|
92
90
|
connect: async () => {
|
|
93
91
|
await checkBtcAppAndCreateTransportWebUSB(false);
|
|
94
|
-
const
|
|
92
|
+
const BitcoinApp = (await import("@ledgerhq/hw-app-btc")).default;
|
|
95
93
|
|
|
96
94
|
btcApp = new BitcoinApp({ transport, currency: chain });
|
|
97
95
|
},
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
import type Xrp from "@ledgerhq/hw-app-xrp";
|
|
2
|
+
import type Transport from "@ledgerhq/hw-transport";
|
|
3
|
+
import {
|
|
4
|
+
Chain,
|
|
5
|
+
type DerivationPathArray,
|
|
6
|
+
NetworkDerivationPath,
|
|
7
|
+
derivationPathToString,
|
|
8
|
+
} from "@swapkit/helpers";
|
|
9
|
+
import type { Transaction } from "@swapkit/toolboxes/ripple";
|
|
10
|
+
import { encode } from "ripple-binary-codec";
|
|
11
|
+
import type { Payment } from "xrpl";
|
|
12
|
+
import { getLedgerTransport } from "../helpers";
|
|
13
|
+
|
|
14
|
+
const TF_FULLY_CANONICAL_SIG = 2147483648;
|
|
15
|
+
|
|
16
|
+
function cleanTransactionObject(obj: Record<string, any>) {
|
|
17
|
+
const cleaned: Record<string, any> = {};
|
|
18
|
+
for (const key in obj) {
|
|
19
|
+
if (obj[key] !== null && obj[key] !== undefined) {
|
|
20
|
+
cleaned[key] = obj[key];
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
return cleaned;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
async function establishConnection(transport: Transport) {
|
|
27
|
+
const { default: Xrp } = await import("@ledgerhq/hw-app-xrp");
|
|
28
|
+
return new Xrp(transport);
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
function fetchAddressAndPublicKey({
|
|
32
|
+
instance,
|
|
33
|
+
derivationPath,
|
|
34
|
+
}: { instance: Xrp; derivationPath: string }) {
|
|
35
|
+
return instance.getAddress(derivationPath);
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
export const XRPLedger = async (derivationPath?: DerivationPathArray) => {
|
|
39
|
+
const path = derivationPathToString(derivationPath || NetworkDerivationPath[Chain.Ripple]);
|
|
40
|
+
const transport = await getLedgerTransport();
|
|
41
|
+
const xrpInstance = await establishConnection(transport);
|
|
42
|
+
|
|
43
|
+
const { address, publicKey } = await fetchAddressAndPublicKey({
|
|
44
|
+
instance: xrpInstance,
|
|
45
|
+
derivationPath: path,
|
|
46
|
+
});
|
|
47
|
+
|
|
48
|
+
async function sign(transaction: Payment | Transaction) {
|
|
49
|
+
const { hashes } = await import("@swapkit/toolboxes/ripple");
|
|
50
|
+
const cleanedTxWithPubKey = cleanTransactionObject(transaction);
|
|
51
|
+
const transactionJSON = {
|
|
52
|
+
...cleanedTxWithPubKey,
|
|
53
|
+
Flags: transaction.Flags || TF_FULLY_CANONICAL_SIG,
|
|
54
|
+
SigningPubKey: publicKey.toUpperCase(),
|
|
55
|
+
};
|
|
56
|
+
|
|
57
|
+
const transactionToSignOnLedger = encode(transactionJSON);
|
|
58
|
+
const txnSignature = await xrpInstance.signTransaction(path, transactionToSignOnLedger);
|
|
59
|
+
const tx_blob = encode({ ...transactionJSON, TxnSignature: txnSignature });
|
|
60
|
+
const hash = hashes.hashSignedTx(tx_blob);
|
|
61
|
+
|
|
62
|
+
return { tx_blob, hash };
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
return { address, sign };
|
|
66
|
+
};
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import { SwapKitError } from "@swapkit/helpers";
|
|
2
|
+
|
|
1
3
|
export interface Coin {
|
|
2
4
|
readonly denom: string;
|
|
3
5
|
readonly amount: string;
|
|
@@ -57,12 +59,14 @@ export class AminoTypes {
|
|
|
57
59
|
toAmino({ typeUrl, value }: EncodeObject): AminoMsg {
|
|
58
60
|
const converter = this.register[typeUrl];
|
|
59
61
|
if (converter === "not_supported_by_chain") {
|
|
60
|
-
throw new
|
|
61
|
-
`The message type '${typeUrl}' cannot be signed using the Amino JSON sign mode because this is not supported by chain.`,
|
|
62
|
-
);
|
|
62
|
+
throw new SwapKitError("wallet_ledger_chain_not_supported", {
|
|
63
|
+
reason: `The message type '${typeUrl}' cannot be signed using the Amino JSON sign mode because this is not supported by chain.`,
|
|
64
|
+
});
|
|
63
65
|
}
|
|
64
66
|
if (!converter) {
|
|
65
|
-
throw new
|
|
67
|
+
throw new SwapKitError("wallet_ledger_invalid_params", {
|
|
68
|
+
reason: `Type URL '${typeUrl}' does not exist in the Amino message type register.`,
|
|
69
|
+
});
|
|
66
70
|
}
|
|
67
71
|
return {
|
|
68
72
|
type: converter.aminoType,
|
|
@@ -76,18 +80,18 @@ export class AminoTypes {
|
|
|
76
80
|
.filter(([_typeUrl, { aminoType }]) => aminoType === type);
|
|
77
81
|
|
|
78
82
|
if (matches.length === 0) {
|
|
79
|
-
throw new
|
|
80
|
-
`Amino type identifier '${type}' does not exist in the Amino message type register.`,
|
|
81
|
-
);
|
|
83
|
+
throw new SwapKitError("wallet_ledger_invalid_params", {
|
|
84
|
+
reason: `Amino type identifier '${type}' does not exist in the Amino message type register.`,
|
|
85
|
+
});
|
|
82
86
|
}
|
|
83
87
|
|
|
84
88
|
if (matches.length > 1) {
|
|
85
|
-
throw new
|
|
86
|
-
`Multiple types are registered with Amino type identifier '${type}': '${matches
|
|
89
|
+
throw new SwapKitError("wallet_ledger_invalid_params", {
|
|
90
|
+
reason: `Multiple types are registered with Amino type identifier '${type}': '${matches
|
|
87
91
|
.map(([key, _value]) => key)
|
|
88
92
|
.sort()
|
|
89
93
|
.join("', '")}'. Thus fromAmino cannot be performed.`,
|
|
90
|
-
);
|
|
94
|
+
});
|
|
91
95
|
}
|
|
92
96
|
|
|
93
97
|
const [typeUrl, converter] = matches[0] as [string, AminoConverter];
|
|
@@ -1,15 +1,20 @@
|
|
|
1
1
|
import { Chain, SwapKitError, WalletOption } from "@swapkit/helpers";
|
|
2
2
|
|
|
3
|
+
import type { getNearLedgerClient } from "../clients/near";
|
|
4
|
+
import type { XRPLedger } from "../clients/xrp";
|
|
3
5
|
import type { LEDGER_SUPPORTED_CHAINS } from "../index";
|
|
4
6
|
import type { CosmosLedgerClients, EVMLedgerClients, UTXOLedgerClients } from "../types";
|
|
5
7
|
import type { getLedgerClient } from "./getLedgerClient";
|
|
6
8
|
|
|
7
|
-
export const getLedgerAddress = async
|
|
9
|
+
export const getLedgerAddress = async <
|
|
10
|
+
T extends (typeof LEDGER_SUPPORTED_CHAINS)[number],
|
|
11
|
+
L extends Awaited<ReturnType<typeof getLedgerClient<T>>>,
|
|
12
|
+
>({
|
|
8
13
|
chain,
|
|
9
14
|
ledgerClient,
|
|
10
15
|
}: {
|
|
11
|
-
chain:
|
|
12
|
-
ledgerClient:
|
|
16
|
+
chain: T;
|
|
17
|
+
ledgerClient: L;
|
|
13
18
|
}) => {
|
|
14
19
|
if (!ledgerClient) return "";
|
|
15
20
|
|
|
@@ -40,6 +45,15 @@ export const getLedgerAddress = async ({
|
|
|
40
45
|
|
|
41
46
|
return chain === Chain.BitcoinCash ? address.replace("bitcoincash:", "") : address;
|
|
42
47
|
}
|
|
48
|
+
|
|
49
|
+
case Chain.Near: {
|
|
50
|
+
return await (ledgerClient as Awaited<ReturnType<typeof getNearLedgerClient>>).getAddress();
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
case Chain.Ripple: {
|
|
54
|
+
return (ledgerClient as Awaited<ReturnType<typeof XRPLedger>>).address;
|
|
55
|
+
}
|
|
56
|
+
|
|
43
57
|
default:
|
|
44
58
|
throw new SwapKitError("wallet_chain_not_supported", { wallet: WalletOption.LEDGER, chain });
|
|
45
59
|
}
|