@guveno/wallet-sdk 1.0.1 → 1.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +88 -124
- package/dist/api/client.d.ts.map +1 -1
- package/dist/api/client.js +5 -1
- package/dist/api/client.js.map +1 -1
- package/dist/api/types.d.ts +10 -1
- package/dist/api/types.d.ts.map +1 -1
- package/dist/encryption-session.d.ts +7 -0
- package/dist/encryption-session.d.ts.map +1 -1
- package/dist/encryption-session.js +8 -1
- package/dist/encryption-session.js.map +1 -1
- package/dist/guveno.d.ts +83 -0
- package/dist/guveno.d.ts.map +1 -0
- package/dist/guveno.js +116 -0
- package/dist/guveno.js.map +1 -0
- package/dist/hot-wallet.d.ts +25 -7
- package/dist/hot-wallet.d.ts.map +1 -1
- package/dist/hot-wallet.js +36 -19
- package/dist/hot-wallet.js.map +1 -1
- package/dist/index.d.ts +5 -5
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -3
- package/dist/index.js.map +1 -1
- package/dist/signing/sign-bitcoin.d.ts +8 -7
- package/dist/signing/sign-bitcoin.d.ts.map +1 -1
- package/dist/signing/sign-bitcoin.js +39 -31
- package/dist/signing/sign-bitcoin.js.map +1 -1
- package/dist/signing/sign-withdrawal.d.ts +3 -1
- package/dist/signing/sign-withdrawal.d.ts.map +1 -1
- package/dist/signing/sign-withdrawal.js +5 -2
- package/dist/signing/sign-withdrawal.js.map +1 -1
- package/dist/signing/types.d.ts +8 -0
- package/dist/signing/types.d.ts.map +1 -1
- package/dist/signing/types.js.map +1 -1
- package/dist/wallet.d.ts +63 -0
- package/dist/wallet.d.ts.map +1 -0
- package/dist/wallet.js +84 -0
- package/dist/wallet.js.map +1 -0
- package/package.json +2 -10
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"guveno.d.ts","sourceRoot":"","sources":["../src/guveno.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAC;AAClD,OAAO,KAAK,EACV,gBAAgB,EAEhB,eAAe,EACf,gBAAgB,EAChB,oBAAoB,EACrB,MAAM,gBAAgB,CAAC;AAKxB,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,wBAAwB,CAAC;AAC1D,OAAO,KAAK,EAAE,iBAAiB,EAAE,cAAc,EAAE,gBAAgB,EAAE,yBAAyB,EAAE,MAAM,YAAY,CAAC;AACjH,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AAErC,MAAM,MAAM,aAAa,GAAG,gBAAgB,CAAC;AAE7C,4DAA4D;AAC5D,MAAM,MAAM,eAAe;AACzB,kFAAkF;AAChF,MAAM;AACR,6FAA6F;GAC3F;IAAE,IAAI,EAAE,WAAW,CAAA;CAAE,CAAC;AAE1B,MAAM,WAAW,mBAAmB;IAClC,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,cAAc,CAAC;IACtB,OAAO,EAAE,gBAAgB,CAAC;IAC1B,8CAA8C;IAC9C,KAAK,CAAC,EAAE,iBAAiB,CAAC;IAC1B,2CAA2C;IAC3C,KAAK,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,sFAAsF;IACtF,kBAAkB,EAAE,MAAM,CAAC;CAC5B;AAED,MAAM,WAAW,kBAAkB;IACjC,2DAA2D;IAC3D,MAAM,EAAE,MAAM,CAAC;IACf,YAAY,EAAE,yBAAyB,CAAC;IACxC;;;OAGG;IACH,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,mBAAmB;IAClC,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,cAAc,CAAC;IACtB,OAAO,EAAE,gBAAgB,CAAC;IAC1B,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,kBAAkB,EAAE,MAAM,CAAC;CAC5B;AAUD;;;;;;;;;;;;;;;GAeG;AACH,qBAAa,MAAM;IACjB,uHAAuH;IACvH,QAAQ,CAAC,MAAM,EAAE,eAAe,CAAC;IAGjC,OAAO,CAAC,UAAU,CAAsB;gBAE5B,OAAO,GAAE,aAAkB;IAIvC,iEAAiE;IAC3D,WAAW,CAAC,OAAO,GAAE,oBAAyB,GAAG,OAAO,CAAC,gBAAgB,EAAE,CAAC;IAIlF,+DAA+D;IACzD,SAAS,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,eAAe,CAAC;IAI3D;;;;;OAKG;IACG,UAAU,CAAC,QAAQ,EAAE,MAAM,EAAE,GAAG,EAAE,eAAe,GAAG,OAAO,CAAC,MAAM,CAAC;IASzE,yFAAyF;IACnF,YAAY,CAAC,OAAO,EAAE,mBAAmB,GAAG,OAAO,CAAC,kBAAkB,CAAC;IAkB7E,sEAAsE;IAChE,YAAY,CAAC,OAAO,EAAE,mBAAmB,GAAG,OAAO,CAAC,MAAM,CAAC;YAiBnD,aAAa;YA6Bb,MAAM;CAIrB"}
|
package/dist/guveno.js
ADDED
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
import { GuvenoApiClient } from './api/client.js';
|
|
2
|
+
import { assertSupportedChain, assertSupportedNetwork } from './chains.js';
|
|
3
|
+
import { EncryptionSession } from './encryption-session.js';
|
|
4
|
+
import { assertValidMnemonic, fingerprintMnemonic, generateRandomMnemonic } from './mnemonic.js';
|
|
5
|
+
import { deriveAddress } from './derivation.js';
|
|
6
|
+
import { Wallet } from './wallet.js';
|
|
7
|
+
function normalizeLabel(label) {
|
|
8
|
+
if (label == null) {
|
|
9
|
+
return null;
|
|
10
|
+
}
|
|
11
|
+
const normalized = label.trim();
|
|
12
|
+
return normalized.length === 0 ? null : normalized;
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* The Guveno SDK entry point. Construct it once with your API key, then browse
|
|
16
|
+
* wallets and load the ones you want to use:
|
|
17
|
+
*
|
|
18
|
+
* ```ts
|
|
19
|
+
* const guveno = new Guveno({ apiKey: process.env.GUVENO_API_KEY });
|
|
20
|
+
* const wallets = await guveno.listWallets(); // metadata only, no password
|
|
21
|
+
* const wallet = await guveno.loadWallet(walletId, encryptionPassword);
|
|
22
|
+
* await wallet.withdraw({ addressId, assetId, toAddress, amount });
|
|
23
|
+
* ```
|
|
24
|
+
*
|
|
25
|
+
* Listing and reading wallet metadata only needs the API key. Loading a wallet to
|
|
26
|
+
* sign with it additionally needs your encryption password (or a key provider for
|
|
27
|
+
* headless signers) — that's what decrypts the recovery phrase, which the server
|
|
28
|
+
* only ever stores sealed.
|
|
29
|
+
*/
|
|
30
|
+
export class Guveno {
|
|
31
|
+
/** The underlying low-level HTTP client, for operations not covered by this facade (webhooks, rename/delete, etc.). */
|
|
32
|
+
client;
|
|
33
|
+
// The `/me` encryption-key blob doesn't change within a process; cache it so
|
|
34
|
+
// loading several wallets doesn't re-fetch it (scrypt still runs per unlock).
|
|
35
|
+
cachedUser;
|
|
36
|
+
constructor(options = {}) {
|
|
37
|
+
this.client = new GuvenoApiClient(options);
|
|
38
|
+
}
|
|
39
|
+
/** List wallets stored on the server. Needs only the API key. */
|
|
40
|
+
async listWallets(options = {}) {
|
|
41
|
+
return this.client.listWalletRecords(options);
|
|
42
|
+
}
|
|
43
|
+
/** Fetch a wallet's metadata by id. Needs only the API key. */
|
|
44
|
+
async getWallet(walletId) {
|
|
45
|
+
return this.client.getWalletRecord(walletId);
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* Load a wallet for signing. Fetches the wallet's encrypted secret from the
|
|
49
|
+
* server and unlocks it with your encryption password (or resolves the key from
|
|
50
|
+
* the supplied provider). The returned {@link Wallet} can withdraw, derive
|
|
51
|
+
* addresses, and reveal its recovery phrase.
|
|
52
|
+
*/
|
|
53
|
+
async loadWallet(walletId, key) {
|
|
54
|
+
const detail = await this.client.getWalletRecord(walletId);
|
|
55
|
+
if (typeof key === 'string') {
|
|
56
|
+
const session = await this.unlock(key);
|
|
57
|
+
return new Wallet({ api: this.client, detail, session });
|
|
58
|
+
}
|
|
59
|
+
return new Wallet({ api: this.client, detail, keys: key.keys });
|
|
60
|
+
}
|
|
61
|
+
/** Generate a new wallet, derive its first address, seal the phrase, and register it. */
|
|
62
|
+
async createWallet(options) {
|
|
63
|
+
const chain = assertSupportedChain(options.chain);
|
|
64
|
+
const network = assertSupportedNetwork(options.network);
|
|
65
|
+
const words = options.words ?? 12;
|
|
66
|
+
const mnemonic = generateRandomMnemonic(words);
|
|
67
|
+
const { wallet, firstAddress } = await this.pushNewWallet({
|
|
68
|
+
mnemonic,
|
|
69
|
+
chain,
|
|
70
|
+
network,
|
|
71
|
+
name: options.name,
|
|
72
|
+
label: options.label,
|
|
73
|
+
encryptionPassword: options.encryptionPassword
|
|
74
|
+
});
|
|
75
|
+
return { wallet, firstAddress, mnemonic };
|
|
76
|
+
}
|
|
77
|
+
/** Import an existing recovery phrase as a new server-side wallet. */
|
|
78
|
+
async importWallet(options) {
|
|
79
|
+
const chain = assertSupportedChain(options.chain);
|
|
80
|
+
const network = assertSupportedNetwork(options.network);
|
|
81
|
+
const mnemonic = assertValidMnemonic(options.mnemonic);
|
|
82
|
+
const { wallet } = await this.pushNewWallet({
|
|
83
|
+
mnemonic,
|
|
84
|
+
chain,
|
|
85
|
+
network,
|
|
86
|
+
name: options.name,
|
|
87
|
+
label: options.label,
|
|
88
|
+
encryptionPassword: options.encryptionPassword
|
|
89
|
+
});
|
|
90
|
+
return wallet;
|
|
91
|
+
}
|
|
92
|
+
async pushNewWallet(input) {
|
|
93
|
+
const session = await this.unlock(input.encryptionPassword);
|
|
94
|
+
const derived = await deriveAddress(input.mnemonic, 0, { chain: input.chain, network: input.network });
|
|
95
|
+
const firstAddress = {
|
|
96
|
+
address: derived.address,
|
|
97
|
+
derivationPath: derived.derivationPath,
|
|
98
|
+
accountIndex: derived.index,
|
|
99
|
+
label: normalizeLabel(input.label)
|
|
100
|
+
};
|
|
101
|
+
const detail = await this.client.createWalletRecord({
|
|
102
|
+
name: input.name,
|
|
103
|
+
chain: input.chain,
|
|
104
|
+
network: input.network,
|
|
105
|
+
keyFingerprint: fingerprintMnemonic(input.mnemonic),
|
|
106
|
+
encryptedSecretJson: session.seal(input.mnemonic),
|
|
107
|
+
addresses: [firstAddress]
|
|
108
|
+
});
|
|
109
|
+
return { wallet: new Wallet({ api: this.client, detail, session }), firstAddress };
|
|
110
|
+
}
|
|
111
|
+
async unlock(encryptionPassword) {
|
|
112
|
+
this.cachedUser ??= await this.client.getCurrentUser();
|
|
113
|
+
return EncryptionSession.unlockFromUser(this.cachedUser, encryptionPassword);
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
//# sourceMappingURL=guveno.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"guveno.js","sourceRoot":"","sources":["../src/guveno.ts"],"names":[],"mappings":"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"}
|
package/dist/hot-wallet.d.ts
CHANGED
|
@@ -20,7 +20,20 @@ export interface HotWalletOptions {
|
|
|
20
20
|
keys?: KeyProvider;
|
|
21
21
|
}
|
|
22
22
|
export interface WithdrawInput {
|
|
23
|
-
|
|
23
|
+
/**
|
|
24
|
+
* Explicit source address (advanced). Omit to auto-select: the server picks a
|
|
25
|
+
* source with enough balance — and for Bitcoin aggregates UTXOs across the
|
|
26
|
+
* wallet. When omitted, `walletId` is required.
|
|
27
|
+
*/
|
|
28
|
+
addressId?: number;
|
|
29
|
+
/**
|
|
30
|
+
* Auto source-selection within this wallet (used when `addressId` is omitted),
|
|
31
|
+
* and the wallet whose key signs. Also resolves the signing key without
|
|
32
|
+
* scanning every wallet.
|
|
33
|
+
*/
|
|
34
|
+
walletId?: number;
|
|
35
|
+
/** Bitcoin only: restrict auto UTXO selection to these source addresses (advanced). */
|
|
36
|
+
sourceAddressIds?: number[];
|
|
24
37
|
assetId: number;
|
|
25
38
|
/** Required for Ethereum/XRP/Polkadot; for Bitcoin pass `outputs` instead. */
|
|
26
39
|
toAddress?: string;
|
|
@@ -30,13 +43,13 @@ export interface WithdrawInput {
|
|
|
30
43
|
/** XRP destination tag. */
|
|
31
44
|
destinationTag?: number;
|
|
32
45
|
ethereumGas?: EthereumGasOverrides;
|
|
46
|
+
/** Bitcoin fee rate override (sat/vB); falls back to the server's suggestion. */
|
|
47
|
+
bitcoinFeeRate?: number;
|
|
33
48
|
/** Reused across this call's prepare + broadcast for replay-safe retries; auto-generated when omitted. */
|
|
34
49
|
idempotencyKey?: string;
|
|
35
|
-
/**
|
|
36
|
-
walletId?: number;
|
|
37
|
-
/** Fast path: skip all lookups by supplying the source address's derivation path directly. */
|
|
50
|
+
/** Fast path (explicit `addressId` only): skip lookups by supplying the source address's derivation path directly. */
|
|
38
51
|
derivationPath?: string;
|
|
39
|
-
/** Fast path: the wallet's key fingerprint (also the key provider lookup key). */
|
|
52
|
+
/** Fast path (explicit `addressId` only): the wallet's key fingerprint (also the key provider lookup key). */
|
|
40
53
|
keyFingerprint?: string;
|
|
41
54
|
}
|
|
42
55
|
/**
|
|
@@ -65,10 +78,15 @@ export declare class HotWallet {
|
|
|
65
78
|
* configured key provider. Session mode needs the address's wallet id.
|
|
66
79
|
*/
|
|
67
80
|
private resolveMnemonic;
|
|
68
|
-
|
|
81
|
+
/**
|
|
82
|
+
* Resolves the signing context (derivation path, key fingerprint, wallet) for
|
|
83
|
+
* the address the server prepared. Honors the explicit-address fast path, then
|
|
84
|
+
* a cached context, then indexes the wallet (or all wallets) to find it.
|
|
85
|
+
*/
|
|
86
|
+
private resolveContextForWithdrawal;
|
|
69
87
|
private indexWallet;
|
|
70
88
|
private indexAllWallets;
|
|
71
|
-
/** Chain the per
|
|
89
|
+
/** Chain the per-source tasks so two withdrawals from one source never overlap. */
|
|
72
90
|
private serialize;
|
|
73
91
|
}
|
|
74
92
|
//# sourceMappingURL=hot-wallet.d.ts.map
|
package/dist/hot-wallet.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"hot-wallet.d.ts","sourceRoot":"","sources":["../src/hot-wallet.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAC;AACvD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AACpD,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,yBAAyB,CAAC;AAEjE,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,wBAAwB,CAAC;AAE1D,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,4BAA4B,CAAC;AAGvE,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AAExD,MAAM,WAAW,gBAAgB;IAC/B,+GAA+G;IAC/G,GAAG,EAAE,eAAe,CAAC;IACrB;;;OAGG;IACH,OAAO,CAAC,EAAE,iBAAiB,CAAC;IAC5B;;;;OAIG;IACH,IAAI,CAAC,EAAE,WAAW,CAAC;CACpB;AAED,MAAM,WAAW,aAAa;IAC5B,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,MAAM,CAAC;IAChB,8EAA8E;IAC9E,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,kCAAkC;IAClC,OAAO,CAAC,EAAE,aAAa,EAAE,CAAC;IAC1B,2BAA2B;IAC3B,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,WAAW,CAAC,EAAE,oBAAoB,CAAC;IACnC,
|
|
1
|
+
{"version":3,"file":"hot-wallet.d.ts","sourceRoot":"","sources":["../src/hot-wallet.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAC;AACvD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AACpD,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,yBAAyB,CAAC;AAEjE,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,wBAAwB,CAAC;AAE1D,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,4BAA4B,CAAC;AAGvE,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AAExD,MAAM,WAAW,gBAAgB;IAC/B,+GAA+G;IAC/G,GAAG,EAAE,eAAe,CAAC;IACrB;;;OAGG;IACH,OAAO,CAAC,EAAE,iBAAiB,CAAC;IAC5B;;;;OAIG;IACH,IAAI,CAAC,EAAE,WAAW,CAAC;CACpB;AAED,MAAM,WAAW,aAAa;IAC5B;;;;OAIG;IACH,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB;;;;OAIG;IACH,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,uFAAuF;IACvF,gBAAgB,CAAC,EAAE,MAAM,EAAE,CAAC;IAC5B,OAAO,EAAE,MAAM,CAAC;IAChB,8EAA8E;IAC9E,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,kCAAkC;IAClC,OAAO,CAAC,EAAE,aAAa,EAAE,CAAC;IAC1B,2BAA2B;IAC3B,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,WAAW,CAAC,EAAE,oBAAoB,CAAC;IACnC,iFAAiF;IACjF,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,0GAA0G;IAC1G,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,sHAAsH;IACtH,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,8GAA8G;IAC9G,cAAc,CAAC,EAAE,MAAM,CAAC;CACzB;AAYD;;;;;;GAMG;AACH,qBAAa,SAAS;IACpB,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAkB;IACtC,OAAO,CAAC,QAAQ,CAAC,IAAI,CAA0B;IAC/C,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAgC;IACxD,OAAO,CAAC,QAAQ,CAAC,eAAe,CAAqC;IACrE,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAuC;IAC9D,OAAO,CAAC,YAAY,CAAS;gBAEjB,OAAO,EAAE,gBAAgB;IASrC,8FAA8F;IACxF,QAAQ,CAAC,KAAK,EAAE,aAAa,GAAG,OAAO,CAAC,aAAa,CAAC;IAU5D,+EAA+E;IACzE,aAAa,CAAC,YAAY,EAAE,MAAM,GAAG,OAAO,CAAC,aAAa,CAAC;YAInD,WAAW;IAkDzB;;;;OAIG;YACW,eAAe;IAe7B;;;;OAIG;YACW,2BAA2B;YAkC3B,WAAW;YAsBX,eAAe;IAY7B,mFAAmF;IACnF,OAAO,CAAC,SAAS;CAYlB"}
|
package/dist/hot-wallet.js
CHANGED
|
@@ -26,19 +26,23 @@ export class HotWallet {
|
|
|
26
26
|
}
|
|
27
27
|
/** Prepare, sign, and broadcast a withdrawal. Resolves to the broadcast withdrawal record. */
|
|
28
28
|
async withdraw(input) {
|
|
29
|
-
|
|
29
|
+
if (input.addressId == null && input.walletId == null && input.sourceAddressIds == null) {
|
|
30
|
+
throw new ValidationError('withdraw() needs an addressId (specific source) or a walletId (auto-select).');
|
|
31
|
+
}
|
|
32
|
+
// Serialize per source so concurrent sends can't collide on a nonce/UTXO:
|
|
33
|
+
// by address when explicit, otherwise by the wallet being auto-selected.
|
|
34
|
+
const key = input.addressId != null ? `a:${input.addressId}` : `w:${input.walletId ?? 'auto'}`;
|
|
35
|
+
return this.serialize(key, () => this.runWithdraw(input));
|
|
30
36
|
}
|
|
31
37
|
/** Fetch the current state of a withdrawal (e.g. to poll for confirmation). */
|
|
32
38
|
async getWithdrawal(withdrawalId) {
|
|
33
39
|
return this.api.getWithdrawal(withdrawalId);
|
|
34
40
|
}
|
|
35
41
|
async runWithdraw(input) {
|
|
36
|
-
const context = await this.resolveAddress(input);
|
|
37
|
-
if (context.chain != null && !canSignChain(context.chain)) {
|
|
38
|
-
throw new SigningError(`The hot wallet cannot sign ${context.chain} withdrawals.`);
|
|
39
|
-
}
|
|
40
42
|
const { withdrawal, signingPayload } = await this.api.prepareWithdrawal({
|
|
41
|
-
addressId: input.addressId,
|
|
43
|
+
...(input.addressId !== undefined ? { addressId: input.addressId } : {}),
|
|
44
|
+
...(input.walletId !== undefined ? { walletId: input.walletId } : {}),
|
|
45
|
+
...(input.sourceAddressIds !== undefined ? { sourceAddressIds: input.sourceAddressIds } : {}),
|
|
42
46
|
assetId: input.assetId,
|
|
43
47
|
...(input.toAddress !== undefined ? { toAddress: input.toAddress } : {}),
|
|
44
48
|
...(input.amount !== undefined ? { amount: input.amount } : {}),
|
|
@@ -49,6 +53,10 @@ export class HotWallet {
|
|
|
49
53
|
if (!canSignChain(signingPayload.chain)) {
|
|
50
54
|
throw new SigningError(`The hot wallet cannot sign ${signingPayload.chain} withdrawals.`);
|
|
51
55
|
}
|
|
56
|
+
// Resolve the signing context for the address the server actually prepared
|
|
57
|
+
// (the chosen source for account chains; the change address for Bitcoin,
|
|
58
|
+
// whose per-input keys come from the payload).
|
|
59
|
+
const context = await this.resolveContextForWithdrawal(withdrawal.addressId, input);
|
|
52
60
|
let mnemonic = (await this.resolveMnemonic(context, input)).trim();
|
|
53
61
|
try {
|
|
54
62
|
const actual = fingerprintMnemonic(mnemonic);
|
|
@@ -59,7 +67,8 @@ export class HotWallet {
|
|
|
59
67
|
payload: signingPayload,
|
|
60
68
|
mnemonic,
|
|
61
69
|
derivationPath: context.derivationPath,
|
|
62
|
-
...(input.ethereumGas !== undefined ? { ethereumGas: input.ethereumGas } : {})
|
|
70
|
+
...(input.ethereumGas !== undefined ? { ethereumGas: input.ethereumGas } : {}),
|
|
71
|
+
...(input.bitcoinFeeRate !== undefined ? { bitcoinFeeRate: input.bitcoinFeeRate } : {})
|
|
63
72
|
});
|
|
64
73
|
return await this.api.broadcastWithdrawal({
|
|
65
74
|
withdrawalId: withdrawal.id,
|
|
@@ -88,17 +97,25 @@ export class HotWallet {
|
|
|
88
97
|
const secret = await this.api.getWalletKeySecret(walletId);
|
|
89
98
|
return this.session.unsealRecord(secret.encryptedSecretJson);
|
|
90
99
|
}
|
|
91
|
-
|
|
92
|
-
|
|
100
|
+
/**
|
|
101
|
+
* Resolves the signing context (derivation path, key fingerprint, wallet) for
|
|
102
|
+
* the address the server prepared. Honors the explicit-address fast path, then
|
|
103
|
+
* a cached context, then indexes the wallet (or all wallets) to find it.
|
|
104
|
+
*/
|
|
105
|
+
async resolveContextForWithdrawal(preparedAddressId, input) {
|
|
106
|
+
// Fast path only applies when the caller named the same explicit address.
|
|
107
|
+
if (input.addressId === preparedAddressId &&
|
|
108
|
+
input.derivationPath != null &&
|
|
109
|
+
input.keyFingerprint != null) {
|
|
93
110
|
const context = {
|
|
94
111
|
derivationPath: input.derivationPath,
|
|
95
112
|
keyFingerprint: input.keyFingerprint,
|
|
96
113
|
...(input.walletId != null ? { walletId: input.walletId } : {})
|
|
97
114
|
};
|
|
98
|
-
this.addressContexts.set(
|
|
115
|
+
this.addressContexts.set(preparedAddressId, context);
|
|
99
116
|
return context;
|
|
100
117
|
}
|
|
101
|
-
const cached = this.addressContexts.get(
|
|
118
|
+
const cached = this.addressContexts.get(preparedAddressId);
|
|
102
119
|
if (cached != null) {
|
|
103
120
|
return cached;
|
|
104
121
|
}
|
|
@@ -108,9 +125,9 @@ export class HotWallet {
|
|
|
108
125
|
else if (!this.fullyIndexed) {
|
|
109
126
|
await this.indexAllWallets();
|
|
110
127
|
}
|
|
111
|
-
const resolved = this.addressContexts.get(
|
|
128
|
+
const resolved = this.addressContexts.get(preparedAddressId);
|
|
112
129
|
if (resolved == null) {
|
|
113
|
-
throw new NotFoundError(`
|
|
130
|
+
throw new NotFoundError(`Prepared source address ${preparedAddressId} was not found in any accessible wallet.`);
|
|
114
131
|
}
|
|
115
132
|
return resolved;
|
|
116
133
|
}
|
|
@@ -145,15 +162,15 @@ export class HotWallet {
|
|
|
145
162
|
} while (cursor != null);
|
|
146
163
|
this.fullyIndexed = true;
|
|
147
164
|
}
|
|
148
|
-
/** Chain the per
|
|
149
|
-
serialize(
|
|
150
|
-
const previous = this.queues.get(
|
|
165
|
+
/** Chain the per-source tasks so two withdrawals from one source never overlap. */
|
|
166
|
+
serialize(key, task) {
|
|
167
|
+
const previous = this.queues.get(key) ?? Promise.resolve();
|
|
151
168
|
const run = previous.catch(() => undefined).then(task);
|
|
152
169
|
const tracked = run.catch(() => undefined);
|
|
153
|
-
this.queues.set(
|
|
170
|
+
this.queues.set(key, tracked);
|
|
154
171
|
void tracked.then(() => {
|
|
155
|
-
if (this.queues.get(
|
|
156
|
-
this.queues.delete(
|
|
172
|
+
if (this.queues.get(key) === tracked) {
|
|
173
|
+
this.queues.delete(key);
|
|
157
174
|
}
|
|
158
175
|
});
|
|
159
176
|
return run;
|
package/dist/hot-wallet.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"hot-wallet.js","sourceRoot":"","sources":["../src/hot-wallet.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAIzC,OAAO,EAAE,aAAa,EAAE,YAAY,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAE3E,OAAO,EAAE,mBAAmB,EAAE,MAAM,eAAe,CAAC;AAEpD,OAAO,EAAE,YAAY,EAAE,cAAc,EAAE,MAAM,8BAA8B,CAAC;
|
|
1
|
+
{"version":3,"file":"hot-wallet.js","sourceRoot":"","sources":["../src/hot-wallet.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAIzC,OAAO,EAAE,aAAa,EAAE,YAAY,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAE3E,OAAO,EAAE,mBAAmB,EAAE,MAAM,eAAe,CAAC;AAEpD,OAAO,EAAE,YAAY,EAAE,cAAc,EAAE,MAAM,8BAA8B,CAAC;AAgE5E;;;;;;GAMG;AACH,MAAM,OAAO,SAAS;IACH,GAAG,CAAkB;IACrB,IAAI,CAA0B;IAC9B,OAAO,CAAgC;IACvC,eAAe,GAAG,IAAI,GAAG,EAA0B,CAAC;IACpD,MAAM,GAAG,IAAI,GAAG,EAA4B,CAAC;IACtD,YAAY,GAAG,KAAK,CAAC;IAE7B,YAAY,OAAyB;QACnC,IAAI,OAAO,CAAC,IAAI,IAAI,IAAI,IAAI,OAAO,CAAC,OAAO,IAAI,IAAI,EAAE,CAAC;YACpD,MAAM,IAAI,eAAe,CAAC,mFAAmF,CAAC,CAAC;QACjH,CAAC;QACD,IAAI,CAAC,GAAG,GAAG,OAAO,CAAC,GAAG,CAAC;QACvB,IAAI,CAAC,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC;QACzB,IAAI,CAAC,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC;IACjC,CAAC;IAED,8FAA8F;IAC9F,KAAK,CAAC,QAAQ,CAAC,KAAoB;QACjC,IAAI,KAAK,CAAC,SAAS,IAAI,IAAI,IAAI,KAAK,CAAC,QAAQ,IAAI,IAAI,IAAI,KAAK,CAAC,gBAAgB,IAAI,IAAI,EAAE,CAAC;YACxF,MAAM,IAAI,eAAe,CAAC,8EAA8E,CAAC,CAAC;QAC5G,CAAC;QACD,0EAA0E;QAC1E,yEAAyE;QACzE,MAAM,GAAG,GAAG,KAAK,CAAC,SAAS,IAAI,IAAI,CAAC,CAAC,CAAC,KAAK,KAAK,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,KAAK,KAAK,CAAC,QAAQ,IAAI,MAAM,EAAE,CAAC;QAC/F,OAAO,IAAI,CAAC,SAAS,CAAC,GAAG,EAAE,GAAG,EAAE,CAAC,IAAI,CAAC,WAAW,CAAC,KAAK,CAAC,CAAC,CAAC;IAC5D,CAAC;IAED,+EAA+E;IAC/E,KAAK,CAAC,aAAa,CAAC,YAAoB;QACtC,OAAO,IAAI,CAAC,GAAG,CAAC,aAAa,CAAC,YAAY,CAAC,CAAC;IAC9C,CAAC;IAEO,KAAK,CAAC,WAAW,CAAC,KAAoB;QAC5C,MAAM,EAAE,UAAU,EAAE,cAAc,EAAE,GAAG,MAAM,IAAI,CAAC,GAAG,CAAC,iBAAiB,CAAC;YACtE,GAAG,CAAC,KAAK,CAAC,SAAS,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,SAAS,EAAE,KAAK,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;YACxE,GAAG,CAAC,KAAK,CAAC,QAAQ,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,QAAQ,EAAE,KAAK,CAAC,QAAQ,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;YACrE,GAAG,CAAC,KAAK,CAAC,gBAAgB,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,gBAAgB,EAAE,KAAK,CAAC,gBAAgB,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;YAC7F,OAAO,EAAE,KAAK,CAAC,OAAO;YACtB,GAAG,CAAC,KAAK,CAAC,SAAS,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,SAAS,EAAE,KAAK,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;YACxE,GAAG,CAAC,KAAK,CAAC,MAAM,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,KAAK,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;YAC/D,GAAG,CAAC,KAAK,CAAC,OAAO,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,KAAK,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;YAClE,GAAG,CAAC,KAAK,CAAC,cAAc,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,cAAc,EAAE,KAAK,CAAC,cAAc,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;YACvF,cAAc,EAAE,KAAK,CAAC,cAAc,IAAI,UAAU,EAAE;SACrD,CAAC,CAAC;QAEH,IAAI,CAAC,YAAY,CAAC,cAAc,CAAC,KAAK,CAAC,EAAE,CAAC;YACxC,MAAM,IAAI,YAAY,CAAC,8BAA8B,cAAc,CAAC,KAAK,eAAe,CAAC,CAAC;QAC5F,CAAC;QAED,2EAA2E;QAC3E,yEAAyE;QACzE,+CAA+C;QAC/C,MAAM,OAAO,GAAG,MAAM,IAAI,CAAC,2BAA2B,CAAC,UAAU,CAAC,SAAS,EAAE,KAAK,CAAC,CAAC;QAEpF,IAAI,QAAQ,GAAG,CAAC,MAAM,IAAI,CAAC,eAAe,CAAC,OAAO,EAAE,KAAK,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;QACnE,IAAI,CAAC;YACH,MAAM,MAAM,GAAG,mBAAmB,CAAC,QAAQ,CAAC,CAAC;YAC7C,IAAI,MAAM,KAAK,OAAO,CAAC,cAAc,EAAE,CAAC;gBACtC,MAAM,IAAI,YAAY,CACpB,uDAAuD,MAAM,+BAA+B,OAAO,CAAC,cAAc,GAAG,CACtH,CAAC;YACJ,CAAC;YAED,MAAM,WAAW,GAAG,MAAM,cAAc,CAAC;gBACvC,OAAO,EAAE,cAAc;gBACvB,QAAQ;gBACR,cAAc,EAAE,OAAO,CAAC,cAAc;gBACtC,GAAG,CAAC,KAAK,CAAC,WAAW,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,WAAW,EAAE,KAAK,CAAC,WAAW,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;gBAC9E,GAAG,CAAC,KAAK,CAAC,cAAc,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,cAAc,EAAE,KAAK,CAAC,cAAc,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;aACxF,CAAC,CAAC;YAEH,OAAO,MAAM,IAAI,CAAC,GAAG,CAAC,mBAAmB,CAAC;gBACxC,YAAY,EAAE,UAAU,CAAC,EAAE;gBAC3B,WAAW;gBACX,cAAc,EAAE,KAAK,CAAC,cAAc,IAAI,UAAU,EAAE;aACrD,CAAC,CAAC;QACL,CAAC;gBAAS,CAAC;YACT,8EAA8E;YAC9E,QAAQ,GAAG,EAAE,CAAC;QAChB,CAAC;IACH,CAAC;IAED;;;;OAIG;IACK,KAAK,CAAC,eAAe,CAAC,OAAuB,EAAE,KAAoB;QACzE,IAAI,IAAI,CAAC,IAAI,IAAI,IAAI,EAAE,CAAC;YACtB,OAAO,IAAI,CAAC,IAAI,CAAC,WAAW,CAAC,OAAO,CAAC,cAAc,CAAC,CAAC;QACvD,CAAC;QAED,MAAM,QAAQ,GAAG,OAAO,CAAC,QAAQ,IAAI,KAAK,CAAC,QAAQ,CAAC;QACpD,IAAI,QAAQ,IAAI,IAAI,EAAE,CAAC;YACrB,MAAM,IAAI,YAAY,CACpB,8FAA8F,CAC/F,CAAC;QACJ,CAAC;QACD,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,GAAG,CAAC,kBAAkB,CAAC,QAAQ,CAAC,CAAC;QAC3D,OAAO,IAAI,CAAC,OAAQ,CAAC,YAAY,CAAC,MAAM,CAAC,mBAAmB,CAAC,CAAC;IAChE,CAAC;IAED;;;;OAIG;IACK,KAAK,CAAC,2BAA2B,CAAC,iBAAyB,EAAE,KAAoB;QACvF,0EAA0E;QAC1E,IACE,KAAK,CAAC,SAAS,KAAK,iBAAiB;YACrC,KAAK,CAAC,cAAc,IAAI,IAAI;YAC5B,KAAK,CAAC,cAAc,IAAI,IAAI,EAC5B,CAAC;YACD,MAAM,OAAO,GAAmB;gBAC9B,cAAc,EAAE,KAAK,CAAC,cAAc;gBACpC,cAAc,EAAE,KAAK,CAAC,cAAc;gBACpC,GAAG,CAAC,KAAK,CAAC,QAAQ,IAAI,IAAI,CAAC,CAAC,CAAC,EAAE,QAAQ,EAAE,KAAK,CAAC,QAAQ,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;aAChE,CAAC;YACF,IAAI,CAAC,eAAe,CAAC,GAAG,CAAC,iBAAiB,EAAE,OAAO,CAAC,CAAC;YACrD,OAAO,OAAO,CAAC;QACjB,CAAC;QAED,MAAM,MAAM,GAAG,IAAI,CAAC,eAAe,CAAC,GAAG,CAAC,iBAAiB,CAAC,CAAC;QAC3D,IAAI,MAAM,IAAI,IAAI,EAAE,CAAC;YACnB,OAAO,MAAM,CAAC;QAChB,CAAC;QAED,IAAI,KAAK,CAAC,QAAQ,IAAI,IAAI,EAAE,CAAC;YAC3B,MAAM,IAAI,CAAC,WAAW,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC;QACzC,CAAC;aAAM,IAAI,CAAC,IAAI,CAAC,YAAY,EAAE,CAAC;YAC9B,MAAM,IAAI,CAAC,eAAe,EAAE,CAAC;QAC/B,CAAC;QAED,MAAM,QAAQ,GAAG,IAAI,CAAC,eAAe,CAAC,GAAG,CAAC,iBAAiB,CAAC,CAAC;QAC7D,IAAI,QAAQ,IAAI,IAAI,EAAE,CAAC;YACrB,MAAM,IAAI,aAAa,CAAC,2BAA2B,iBAAiB,0CAA0C,CAAC,CAAC;QAClH,CAAC;QACD,OAAO,QAAQ,CAAC;IAClB,CAAC;IAEO,KAAK,CAAC,WAAW,CAAC,QAAgB;QACxC,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,GAAG,CAAC,eAAe,CAAC,QAAQ,CAAC,CAAC;QACxD,MAAM,cAAc,GAAG,MAAM,CAAC,GAAG,EAAE,WAAW,CAAC;QAC/C,IAAI,cAAc,IAAI,IAAI,EAAE,CAAC;YAC3B,MAAM,IAAI,YAAY,CAAC,UAAU,QAAQ,wDAAwD,CAAC,CAAC;QACrG,CAAC;QAED,IAAI,MAA0B,CAAC;QAC/B,GAAG,CAAC;YACF,MAAM,IAAI,GAAG,MAAM,IAAI,CAAC,GAAG,CAAC,mBAAmB,CAAC,QAAQ,EAAE,MAAM,IAAI,IAAI,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;YAC5F,KAAK,MAAM,OAAO,IAAI,IAAI,CAAC,KAAK,EAAE,CAAC;gBACjC,IAAI,CAAC,eAAe,CAAC,GAAG,CAAC,OAAO,CAAC,EAAE,EAAE;oBACnC,cAAc,EAAE,OAAO,CAAC,cAAc;oBACtC,cAAc;oBACd,QAAQ;oBACR,KAAK,EAAE,OAAO,CAAC,KAAK;iBACrB,CAAC,CAAC;YACL,CAAC;YACD,MAAM,GAAG,IAAI,CAAC,QAAQ,CAAC,WAAW,CAAC,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,UAAU,IAAI,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC;QACzF,CAAC,QAAQ,MAAM,IAAI,IAAI,EAAE;IAC3B,CAAC;IAEO,KAAK,CAAC,eAAe;QAC3B,IAAI,MAA0B,CAAC;QAC/B,GAAG,CAAC;YACF,MAAM,IAAI,GAAG,MAAM,IAAI,CAAC,GAAG,CAAC,oBAAoB,CAAC,MAAM,IAAI,IAAI,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;YACnF,KAAK,MAAM,MAAM,IAAI,IAAI,CAAC,KAAK,EAAE,CAAC;gBAChC,MAAM,IAAI,CAAC,WAAW,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;YACpC,CAAC;YACD,MAAM,GAAG,IAAI,CAAC,QAAQ,CAAC,WAAW,CAAC,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,UAAU,IAAI,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC;QACzF,CAAC,QAAQ,MAAM,IAAI,IAAI,EAAE;QACzB,IAAI,CAAC,YAAY,GAAG,IAAI,CAAC;IAC3B,CAAC;IAED,mFAAmF;IAC3E,SAAS,CAAI,GAAW,EAAE,IAAsB;QACtD,MAAM,QAAQ,GAAG,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,OAAO,CAAC,OAAO,EAAE,CAAC;QAC3D,MAAM,GAAG,GAAG,QAAQ,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,SAAS,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACvD,MAAM,OAAO,GAAG,GAAG,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,SAAS,CAAC,CAAC;QAC3C,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,GAAG,EAAE,OAAO,CAAC,CAAC;QAC9B,KAAK,OAAO,CAAC,IAAI,CAAC,GAAG,EAAE;YACrB,IAAI,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,GAAG,CAAC,KAAK,OAAO,EAAE,CAAC;gBACrC,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;YAC1B,CAAC;QACH,CAAC,CAAC,CAAC;QACH,OAAO,GAAG,CAAC;IACb,CAAC;CACF"}
|
package/dist/index.d.ts
CHANGED
|
@@ -2,9 +2,11 @@ export { GuvenoApiClient } from './api/client.js';
|
|
|
2
2
|
export { WEBHOOK_EVENT_TYPES } from './api/types.js';
|
|
3
3
|
export { FileSystemConfigStore, init, loadConfig, createClientFromConfig } from './config/file-store.js';
|
|
4
4
|
export type { GuvenoConfig } from './config/file-store.js';
|
|
5
|
-
export {
|
|
6
|
-
export type {
|
|
7
|
-
export {
|
|
5
|
+
export { Guveno } from './guveno.js';
|
|
6
|
+
export type { GuvenoOptions, WalletKeySource, CreateWalletOptions, CreateWalletResult, ImportWalletOptions } from './guveno.js';
|
|
7
|
+
export { Wallet } from './wallet.js';
|
|
8
|
+
export type { WalletWithdrawInput, WalletDeps } from './wallet.js';
|
|
9
|
+
export type { DeriveAddressOptions, DeriveAddressResult } from './wallet-service.js';
|
|
8
10
|
export { sealSecret, unsealSecret } from './crypto/sealed-box.js';
|
|
9
11
|
export type { SealedSecretJson } from './crypto/sealed-box.js';
|
|
10
12
|
export { decryptUserPrivateKey } from './crypto/user-keys.js';
|
|
@@ -13,7 +15,6 @@ export { DEFAULT_CHAIN, CHAIN_DEFINITIONS, POLKADOT_SS58_FORMAT, SUPPORTED_CHAIN
|
|
|
13
15
|
export { DEFAULT_API_BASE_URL, DEFAULT_API_BASE_URL_ENV_VAR, DEFAULT_API_KEY_ENV_VAR, resolveStorageDir } from './constants.js';
|
|
14
16
|
export { buildDerivationPath, deriveAddress, deriveBitcoinAddress, deriveEthereumAddress, derivePolkadotAddress, deriveXrpAddress } from './derivation.js';
|
|
15
17
|
export { assertValidMnemonic, fingerprintMnemonic, generateRandomMnemonic, getMnemonicWordCount, normalizeMnemonic } from './mnemonic.js';
|
|
16
|
-
export { HotWallet } from './hot-wallet.js';
|
|
17
18
|
export { FileKeyProvider, KmsKeyProvider } from './keyprovider/index.js';
|
|
18
19
|
export { signWithdrawal, SIGNABLE_CHAINS, canSignChain } from './signing/sign-withdrawal.js';
|
|
19
20
|
export { signEthereumWithdrawal } from './signing/sign-ethereum.js';
|
|
@@ -22,7 +23,6 @@ export { signBitcoinWithdrawal } from './signing/sign-bitcoin.js';
|
|
|
22
23
|
export { signPolkadotWithdrawal } from './signing/sign-polkadot.js';
|
|
23
24
|
export { UnsupportedSigningError, WithdrawalExpiredError } from './signing/types.js';
|
|
24
25
|
export { ApiError, AuthenticationError, ConflictError, EncryptionRequiredError, KeyResolutionError, NotFoundError, RateLimitError, SigningError, StorageError, ValidationError, WalletSdkError, WrongPasswordError, WrongPassphraseError } from './errors.js';
|
|
25
|
-
export type { HotWalletOptions, WithdrawInput } from './hot-wallet.js';
|
|
26
26
|
export type { KeyProvider, KmsKeyProviderOptions, KmsDecryptFn } from './keyprovider/index.js';
|
|
27
27
|
export type { MnemonicMap } from './keyprovider/file-provider.js';
|
|
28
28
|
export type { SignWithdrawalInput } from './signing/sign-withdrawal.js';
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAC;AAClD,OAAO,EAAE,mBAAmB,EAAE,MAAM,gBAAgB,CAAC;AACrD,OAAO,EACL,qBAAqB,EACrB,IAAI,EACJ,UAAU,EACV,sBAAsB,EACvB,MAAM,wBAAwB,CAAC;AAChC,YAAY,EAAE,YAAY,EAAE,MAAM,wBAAwB,CAAC;AAC3D,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
package/dist/index.js
CHANGED
|
@@ -1,15 +1,14 @@
|
|
|
1
1
|
export { GuvenoApiClient } from './api/client.js';
|
|
2
2
|
export { WEBHOOK_EVENT_TYPES } from './api/types.js';
|
|
3
3
|
export { FileSystemConfigStore, init, loadConfig, createClientFromConfig } from './config/file-store.js';
|
|
4
|
-
export {
|
|
5
|
-
export {
|
|
4
|
+
export { Guveno } from './guveno.js';
|
|
5
|
+
export { Wallet } from './wallet.js';
|
|
6
6
|
export { sealSecret, unsealSecret } from './crypto/sealed-box.js';
|
|
7
7
|
export { decryptUserPrivateKey } from './crypto/user-keys.js';
|
|
8
8
|
export { DEFAULT_CHAIN, CHAIN_DEFINITIONS, POLKADOT_SS58_FORMAT, SUPPORTED_CHAINS, SUPPORTED_NETWORKS } from './chains.js';
|
|
9
9
|
export { DEFAULT_API_BASE_URL, DEFAULT_API_BASE_URL_ENV_VAR, DEFAULT_API_KEY_ENV_VAR, resolveStorageDir } from './constants.js';
|
|
10
10
|
export { buildDerivationPath, deriveAddress, deriveBitcoinAddress, deriveEthereumAddress, derivePolkadotAddress, deriveXrpAddress } from './derivation.js';
|
|
11
11
|
export { assertValidMnemonic, fingerprintMnemonic, generateRandomMnemonic, getMnemonicWordCount, normalizeMnemonic } from './mnemonic.js';
|
|
12
|
-
export { HotWallet } from './hot-wallet.js';
|
|
13
12
|
export { FileKeyProvider, KmsKeyProvider } from './keyprovider/index.js';
|
|
14
13
|
export { signWithdrawal, SIGNABLE_CHAINS, canSignChain } from './signing/sign-withdrawal.js';
|
|
15
14
|
export { signEthereumWithdrawal } from './signing/sign-ethereum.js';
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAC;AAClD,OAAO,EAAE,mBAAmB,EAAE,MAAM,gBAAgB,CAAC;AACrD,OAAO,EACL,qBAAqB,EACrB,IAAI,EACJ,UAAU,EACV,sBAAsB,EACvB,MAAM,wBAAwB,CAAC;AAEhC,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAC;AAClD,OAAO,EAAE,mBAAmB,EAAE,MAAM,gBAAgB,CAAC;AACrD,OAAO,EACL,qBAAqB,EACrB,IAAI,EACJ,UAAU,EACV,sBAAsB,EACvB,MAAM,wBAAwB,CAAC;AAEhC,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AAQrC,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AAGrC,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,wBAAwB,CAAC;AAElE,OAAO,EAAE,qBAAqB,EAAE,MAAM,uBAAuB,CAAC;AAE9D,OAAO,EACL,aAAa,EACb,iBAAiB,EACjB,oBAAoB,EACpB,gBAAgB,EAChB,kBAAkB,EACnB,MAAM,aAAa,CAAC;AACrB,OAAO,EACL,oBAAoB,EACpB,4BAA4B,EAC5B,uBAAuB,EACvB,iBAAiB,EAClB,MAAM,gBAAgB,CAAC;AACxB,OAAO,EACL,mBAAmB,EACnB,aAAa,EACb,oBAAoB,EACpB,qBAAqB,EACrB,qBAAqB,EACrB,gBAAgB,EACjB,MAAM,iBAAiB,CAAC;AACzB,OAAO,EACL,mBAAmB,EACnB,mBAAmB,EACnB,sBAAsB,EACtB,oBAAoB,EACpB,iBAAiB,EAClB,MAAM,eAAe,CAAC;AACvB,OAAO,EAAE,eAAe,EAAE,cAAc,EAAE,MAAM,wBAAwB,CAAC;AACzE,OAAO,EAAE,cAAc,EAAE,eAAe,EAAE,YAAY,EAAE,MAAM,8BAA8B,CAAC;AAC7F,OAAO,EAAE,sBAAsB,EAAE,MAAM,4BAA4B,CAAC;AACpE,OAAO,EAAE,iBAAiB,EAAE,MAAM,uBAAuB,CAAC;AAC1D,OAAO,EAAE,qBAAqB,EAAE,MAAM,2BAA2B,CAAC;AAClE,OAAO,EAAE,sBAAsB,EAAE,MAAM,4BAA4B,CAAC;AACpE,OAAO,EAAE,uBAAuB,EAAE,sBAAsB,EAAE,MAAM,oBAAoB,CAAC;AACrF,OAAO,EACL,QAAQ,EACR,mBAAmB,EACnB,aAAa,EACb,uBAAuB,EACvB,kBAAkB,EAClB,aAAa,EACb,cAAc,EACd,YAAY,EACZ,YAAY,EACZ,eAAe,EACf,cAAc,EACd,kBAAkB,EAClB,oBAAoB,EACrB,MAAM,aAAa,CAAC"}
|
|
@@ -3,12 +3,13 @@ import type { SigningPayload } from './types.js';
|
|
|
3
3
|
* Builds and signs a P2WPKH (native SegWit) Bitcoin withdrawal for a prepared
|
|
4
4
|
* payload, returning the signed raw transaction hex the server broadcasts.
|
|
5
5
|
*
|
|
6
|
-
* The server selects the
|
|
7
|
-
*
|
|
8
|
-
*
|
|
9
|
-
*
|
|
10
|
-
*
|
|
11
|
-
*
|
|
6
|
+
* The server coin-selects the inputs — possibly aggregated across several of the
|
|
7
|
+
* wallet's addresses — and supplies the fee rate and change address. This signer
|
|
8
|
+
* spends all of them (deriving a key per input from its own derivation path),
|
|
9
|
+
* pays the requested output(s), computes the fee from the fee rate and the
|
|
10
|
+
* transaction's virtual size, and returns the remainder as change to the wallet's
|
|
11
|
+
* change address (dropping it into the fee when it would be dust). Keys are
|
|
12
|
+
* derived in-process from the mnemonic and never leave the caller.
|
|
12
13
|
*/
|
|
13
|
-
export declare function signBitcoinWithdrawal(payload: SigningPayload, mnemonic: string,
|
|
14
|
+
export declare function signBitcoinWithdrawal(payload: SigningPayload, mnemonic: string, feeRateOverride?: number): string;
|
|
14
15
|
//# sourceMappingURL=sign-bitcoin.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sign-bitcoin.d.ts","sourceRoot":"","sources":["../../src/signing/sign-bitcoin.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAoC,cAAc,EAAE,MAAM,YAAY,CAAC;AA6CnF
|
|
1
|
+
{"version":3,"file":"sign-bitcoin.d.ts","sourceRoot":"","sources":["../../src/signing/sign-bitcoin.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAoC,cAAc,EAAE,MAAM,YAAY,CAAC;AA6CnF;;;;;;;;;;;GAWG;AACH,wBAAgB,qBAAqB,CAAC,OAAO,EAAE,cAAc,EAAE,QAAQ,EAAE,MAAM,EAAE,eAAe,CAAC,EAAE,MAAM,GAAG,MAAM,CAsGjH"}
|
|
@@ -44,34 +44,40 @@ function toBaseUnits(amount, decimals) {
|
|
|
44
44
|
* Builds and signs a P2WPKH (native SegWit) Bitcoin withdrawal for a prepared
|
|
45
45
|
* payload, returning the signed raw transaction hex the server broadcasts.
|
|
46
46
|
*
|
|
47
|
-
* The server selects the
|
|
48
|
-
*
|
|
49
|
-
*
|
|
50
|
-
*
|
|
51
|
-
*
|
|
52
|
-
*
|
|
47
|
+
* The server coin-selects the inputs — possibly aggregated across several of the
|
|
48
|
+
* wallet's addresses — and supplies the fee rate and change address. This signer
|
|
49
|
+
* spends all of them (deriving a key per input from its own derivation path),
|
|
50
|
+
* pays the requested output(s), computes the fee from the fee rate and the
|
|
51
|
+
* transaction's virtual size, and returns the remainder as change to the wallet's
|
|
52
|
+
* change address (dropping it into the fee when it would be dust). Keys are
|
|
53
|
+
* derived in-process from the mnemonic and never leave the caller.
|
|
53
54
|
*/
|
|
54
|
-
export function signBitcoinWithdrawal(payload, mnemonic,
|
|
55
|
+
export function signBitcoinWithdrawal(payload, mnemonic, feeRateOverride) {
|
|
55
56
|
const state = payload.chainState;
|
|
56
57
|
if (state == null) {
|
|
57
58
|
throw new Error('Missing Bitcoin chain state from the server.');
|
|
58
59
|
}
|
|
59
60
|
if (!Array.isArray(state.utxos) || state.utxos.length === 0) {
|
|
60
|
-
throw new Error('No spendable UTXOs are available for this
|
|
61
|
+
throw new Error('No spendable UTXOs are available for this withdrawal.');
|
|
61
62
|
}
|
|
62
63
|
const network = payload.network === 'testnet' ? networks.testnet : networks.bitcoin;
|
|
63
64
|
const seed = mnemonicToSeedSync(mnemonic);
|
|
64
|
-
const
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
65
|
+
const root = bip32.fromSeed(Buffer.from(seed), network);
|
|
66
|
+
// Derive a key + witness script per input from its own derivation path (inputs
|
|
67
|
+
// may span several addresses when aggregated). Each derived address must match
|
|
68
|
+
// the one the server tagged the UTXO with — a mismatch means a wrong
|
|
69
|
+
// path/mnemonic, so fail before signing.
|
|
70
|
+
const inputs = state.utxos.map((utxo) => {
|
|
71
|
+
const node = root.derivePath(utxo.derivationPath);
|
|
72
|
+
const payment = payments.p2wpkh({ pubkey: Buffer.from(node.publicKey), network });
|
|
73
|
+
if (payment.address == null || payment.output == null) {
|
|
74
|
+
throw new Error('Unable to derive the Bitcoin signing key.');
|
|
75
|
+
}
|
|
76
|
+
if (payment.address !== utxo.address) {
|
|
77
|
+
throw new Error(`Derived address ${payment.address} does not match the UTXO's address ${utxo.address}.`);
|
|
78
|
+
}
|
|
79
|
+
return { utxo, node, script: Buffer.from(payment.output) };
|
|
80
|
+
});
|
|
75
81
|
const decimals = payload.asset.decimals;
|
|
76
82
|
const recipients = payload.outputs != null && payload.outputs.length > 0
|
|
77
83
|
? payload.outputs
|
|
@@ -90,12 +96,14 @@ export function signBitcoinWithdrawal(payload, mnemonic, derivationPath) {
|
|
|
90
96
|
}
|
|
91
97
|
return { value, script: btcAddress.toOutputScript(recipient.toAddress, network) };
|
|
92
98
|
});
|
|
93
|
-
const totalIn =
|
|
99
|
+
const totalIn = inputs.reduce((sum, input) => sum + BigInt(input.utxo.value), 0n);
|
|
94
100
|
const totalOut = outputs.reduce((sum, output) => sum + output.value, 0n);
|
|
95
|
-
|
|
101
|
+
// sat/vB: caller's override (>= 1) or the server's suggestion. Inputs are fixed
|
|
102
|
+
// at prepare time, so a much higher rate may exceed what they cover (caught below).
|
|
103
|
+
const feeRate = BigInt(Math.max(1, Math.ceil(feeRateOverride != null && feeRateOverride >= 1 ? feeRateOverride : state.feeRate)));
|
|
96
104
|
const changeScript = btcAddress.toOutputScript(state.changeAddress ?? payload.sourceAddress, network);
|
|
97
105
|
const baseVbytes = TX_OVERHEAD_VBYTES +
|
|
98
|
-
|
|
106
|
+
inputs.length * P2WPKH_INPUT_VBYTES +
|
|
99
107
|
outputs.reduce((sum, output) => sum + outputVbytes(output.script), 0);
|
|
100
108
|
// First assume a change output exists; if the leftover is dust, drop it and let
|
|
101
109
|
// the whole remainder be the fee.
|
|
@@ -112,21 +120,21 @@ export function signBitcoinWithdrawal(payload, mnemonic, derivationPath) {
|
|
|
112
120
|
}
|
|
113
121
|
}
|
|
114
122
|
const psbt = new Psbt({ network });
|
|
115
|
-
for (const
|
|
123
|
+
for (const input of inputs) {
|
|
116
124
|
psbt.addInput({
|
|
117
|
-
hash: utxo.txid,
|
|
118
|
-
index: utxo.vout,
|
|
119
|
-
witnessUtxo: { script:
|
|
125
|
+
hash: input.utxo.txid,
|
|
126
|
+
index: input.utxo.vout,
|
|
127
|
+
witnessUtxo: { script: input.script, value: BigInt(input.utxo.value) },
|
|
120
128
|
});
|
|
121
129
|
}
|
|
122
130
|
for (const output of finalOutputs) {
|
|
123
131
|
psbt.addOutput({ script: output.script, value: output.value });
|
|
124
132
|
}
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
133
|
+
// Sign each input with the key for its own address.
|
|
134
|
+
inputs.forEach((input, i) => psbt.signInput(i, {
|
|
135
|
+
publicKey: Buffer.from(input.node.publicKey),
|
|
136
|
+
sign: (hash) => Buffer.from(input.node.sign(hash)),
|
|
137
|
+
}));
|
|
130
138
|
psbt.finalizeAllInputs();
|
|
131
139
|
return psbt.extractTransaction().toHex();
|
|
132
140
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sign-bitcoin.js","sourceRoot":"","sources":["../../src/signing/sign-bitcoin.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,kBAAkB,EAAE,MAAM,cAAc,CAAC;AAClD,OAAO,EAAE,YAAY,EAAE,MAAM,OAAO,CAAC;AACrC,OAAO,EAAE,OAAO,IAAI,UAAU,EAAE,UAAU,EAAE,QAAQ,EAAE,QAAQ,EAAE,IAAI,EAAE,MAAM,eAAe,CAAC;AAC5F,OAAO,KAAK,GAAG,MAAM,gBAAgB,CAAC;AAGtC,UAAU,CAAC,GAAG,CAAC,CAAC;AAChB,MAAM,KAAK,GAAG,YAAY,CAAC,GAAG,CAAC,CAAC;AAEhC,iFAAiF;AACjF,kFAAkF;AAClF,iEAAiE;AACjE,MAAM,cAAc,GAAG,IAAI,CAAC;AAE5B,kFAAkF;AAClF,4EAA4E;AAC5E,sFAAsF;AACtF,+EAA+E;AAC/E,MAAM,kBAAkB,GAAG,EAAE,CAAC;AAC9B,MAAM,mBAAmB,GAAG,EAAE,CAAC;AAE/B,qFAAqF;AACrF,SAAS,YAAY,CAAC,MAAkB;IACtC,MAAM,MAAM,GAAG,MAAM,CAAC,MAAM,CAAC;IAC7B,MAAM,MAAM,GAAG,MAAM,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IACrC,OAAO,CAAC,GAAG,MAAM,GAAG,MAAM,CAAC;AAC7B,CAAC;AAED;;;GAGG;AACH,SAAS,WAAW,CAAC,MAAc,EAAE,QAAgB;IACnD,MAAM,OAAO,GAAG,MAAM,CAAC,IAAI,EAAE,CAAC;IAC9B,MAAM,KAAK,GAAG,OAAO,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;IACjC,IAAI,KAAK,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACrB,MAAM,IAAI,KAAK,CAAC,2BAA2B,MAAM,IAAI,CAAC,CAAC;IACzD,CAAC;IACD,MAAM,KAAK,GAAG,KAAK,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;IAC7B,MAAM,QAAQ,GAAG,KAAK,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;IAChC,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,QAAQ,KAAK,EAAE,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,EAAE,CAAC;QACzE,MAAM,IAAI,KAAK,CAAC,2BAA2B,MAAM,IAAI,CAAC,CAAC;IACzD,CAAC;IACD,IAAI,QAAQ,CAAC,MAAM,GAAG,QAAQ,EAAE,CAAC;QAC/B,MAAM,IAAI,KAAK,CAAC,WAAW,MAAM,mBAAmB,QAAQ,kBAAkB,CAAC,CAAC;IAClF,CAAC;IACD,OAAO,MAAM,CAAC,KAAK,GAAG,QAAQ,CAAC,MAAM,CAAC,QAAQ,EAAE,GAAG,CAAC,CAAC,CAAC;AACxD,CAAC;AAED
|
|
1
|
+
{"version":3,"file":"sign-bitcoin.js","sourceRoot":"","sources":["../../src/signing/sign-bitcoin.ts"],"names":[],"mappings":"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"}
|