@bitgo-beta/abstract-lightning 1.0.0-alpha.31 → 1.0.0-alpha.310
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/src/abstractLightningCoin.d.ts +3 -2
- package/dist/src/abstractLightningCoin.d.ts.map +1 -1
- package/dist/src/abstractLightningCoin.js +7 -2
- package/dist/src/codecs/api/backup.d.ts +15 -0
- package/dist/src/codecs/api/backup.d.ts.map +1 -0
- package/dist/src/codecs/api/backup.js +47 -0
- package/dist/src/codecs/api/balance.d.ts +156 -0
- package/dist/src/codecs/api/balance.d.ts.map +1 -0
- package/dist/src/codecs/api/balance.js +107 -0
- package/dist/src/codecs/api/index.d.ts +8 -0
- package/dist/src/codecs/api/index.d.ts.map +1 -0
- package/dist/src/codecs/api/index.js +24 -0
- package/dist/src/codecs/api/invoice.d.ts +66 -0
- package/dist/src/codecs/api/invoice.d.ts.map +1 -0
- package/dist/src/codecs/api/invoice.js +102 -0
- package/dist/src/codecs/api/payment.d.ts +107 -0
- package/dist/src/codecs/api/payment.d.ts.map +1 -0
- package/dist/src/codecs/api/payment.js +153 -0
- package/dist/src/codecs/api/transaction.d.ts +138 -0
- package/dist/src/codecs/api/transaction.d.ts.map +1 -0
- package/dist/src/codecs/api/transaction.js +122 -0
- package/dist/src/codecs/api/wallet.d.ts +99 -0
- package/dist/src/codecs/api/wallet.d.ts.map +1 -0
- package/dist/src/codecs/api/wallet.js +103 -0
- package/dist/src/codecs/api/withdraw.d.ts +92 -0
- package/dist/src/codecs/api/withdraw.d.ts.map +1 -0
- package/dist/src/codecs/api/withdraw.js +92 -0
- package/dist/src/codecs/index.d.ts +3 -0
- package/dist/src/codecs/index.d.ts.map +1 -0
- package/dist/src/codecs/index.js +19 -0
- package/dist/src/codecs/shared.d.ts +7 -0
- package/dist/src/codecs/shared.d.ts.map +1 -0
- package/dist/src/codecs/shared.js +42 -0
- package/dist/src/index.d.ts +3 -0
- package/dist/src/index.d.ts.map +1 -1
- package/dist/src/index.js +4 -1
- package/dist/src/lightning/index.d.ts +5 -0
- package/dist/src/lightning/index.d.ts.map +1 -0
- package/dist/src/lightning/index.js +21 -0
- package/dist/src/lightning/lightningUtils.d.ts +90 -0
- package/dist/src/lightning/lightningUtils.d.ts.map +1 -0
- package/dist/src/lightning/lightningUtils.js +290 -0
- package/dist/src/lightning/parseWithdrawPsbt.d.ts +11 -0
- package/dist/src/lightning/parseWithdrawPsbt.d.ts.map +1 -0
- package/dist/src/lightning/parseWithdrawPsbt.js +159 -0
- package/dist/src/lightning/signableJson.d.ts +17 -0
- package/dist/src/lightning/signableJson.d.ts.map +1 -0
- package/dist/src/lightning/signableJson.js +29 -0
- package/dist/src/lightning/signature.d.ts +22 -0
- package/dist/src/lightning/signature.d.ts.map +1 -0
- package/dist/src/lightning/signature.js +69 -0
- package/dist/src/wallet/custodialLightning.d.ts +7 -0
- package/dist/src/wallet/custodialLightning.d.ts.map +1 -0
- package/dist/src/wallet/custodialLightning.js +14 -0
- package/dist/src/wallet/index.d.ts +5 -0
- package/dist/src/wallet/index.d.ts.map +1 -0
- package/dist/src/wallet/index.js +21 -0
- package/dist/src/wallet/lightning.d.ts +141 -0
- package/dist/src/wallet/lightning.d.ts.map +1 -0
- package/dist/src/wallet/lightning.js +288 -0
- package/dist/src/wallet/selfCustodialLightning.d.ts +32 -0
- package/dist/src/wallet/selfCustodialLightning.d.ts.map +1 -0
- package/dist/src/wallet/selfCustodialLightning.js +131 -0
- package/dist/src/wallet/wallet.d.ts +7 -0
- package/dist/src/wallet/wallet.d.ts.map +1 -0
- package/dist/src/wallet/wallet.js +22 -0
- package/dist/test/unit/lightning/codecs.d.ts +2 -0
- package/dist/test/unit/lightning/codecs.d.ts.map +1 -0
- package/dist/test/unit/lightning/codecs.js +151 -0
- package/dist/test/unit/lightning/createPsbt.d.ts +27 -0
- package/dist/test/unit/lightning/createPsbt.d.ts.map +1 -0
- package/dist/test/unit/lightning/createPsbt.js +162 -0
- package/dist/test/unit/lightning/createWatchOnlyFixture.d.ts +4 -0
- package/dist/test/unit/lightning/createWatchOnlyFixture.d.ts.map +1 -0
- package/dist/test/unit/lightning/createWatchOnlyFixture.js +1561 -0
- package/dist/test/unit/lightning/lightningUtils.d.ts +2 -0
- package/dist/test/unit/lightning/lightningUtils.d.ts.map +1 -0
- package/dist/test/unit/lightning/lightningUtils.js +123 -0
- package/dist/test/unit/lightning/parseWithdrawPsbt.d.ts +2 -0
- package/dist/test/unit/lightning/parseWithdrawPsbt.d.ts.map +1 -0
- package/dist/test/unit/lightning/parseWithdrawPsbt.js +441 -0
- package/dist/test/unit/lightning/signableJson.d.ts +2 -0
- package/dist/test/unit/lightning/signableJson.d.ts.map +1 -0
- package/dist/test/unit/lightning/signableJson.js +52 -0
- package/dist/test/unit/lightning/signature.d.ts +2 -0
- package/dist/test/unit/lightning/signature.d.ts.map +1 -0
- package/dist/test/unit/lightning/signature.js +91 -0
- package/dist/tsconfig.tsbuildinfo +1 -0
- package/package.json +19 -6
- package/.eslintignore +0 -5
- package/.mocharc.yml +0 -8
- package/CHANGELOG.md +0 -40
|
@@ -0,0 +1,290 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
+
exports.PURPOSE_ALL_OTHERS = exports.PURPOSE_P2TR = exports.PURPOSE_P2WKH = exports.PURPOSE_WRAPPED_P2WKH = exports.lightningNetworkName = exports.signerMacaroonPermissions = void 0;
|
|
37
|
+
exports.isLightningCoinName = isLightningCoinName;
|
|
38
|
+
exports.getLightningNetwork = getLightningNetwork;
|
|
39
|
+
exports.getLightningCoinName = getLightningCoinName;
|
|
40
|
+
exports.isValidLightningNetworkName = isValidLightningNetworkName;
|
|
41
|
+
exports.isValidLightningNetwork = isValidLightningNetwork;
|
|
42
|
+
exports.getStaticsLightningNetwork = getStaticsLightningNetwork;
|
|
43
|
+
exports.getUtxolibNetwork = getUtxolibNetwork;
|
|
44
|
+
exports.unwrapLightningCoinSpecific = unwrapLightningCoinSpecific;
|
|
45
|
+
exports.addIPCaveatToMacaroon = addIPCaveatToMacaroon;
|
|
46
|
+
exports.revertXpubPrefix = revertXpubPrefix;
|
|
47
|
+
exports.deriveWatchOnlyAccounts = deriveWatchOnlyAccounts;
|
|
48
|
+
exports.createWatchOnly = createWatchOnly;
|
|
49
|
+
exports.deriveLightningServiceSharedSecret = deriveLightningServiceSharedSecret;
|
|
50
|
+
exports.deriveMiddlewareSharedSecret = deriveMiddlewareSharedSecret;
|
|
51
|
+
exports.deriveTatSharedSecret = deriveTatSharedSecret;
|
|
52
|
+
exports.computeBip32DerivationIndexFromSeed = computeBip32DerivationIndexFromSeed;
|
|
53
|
+
const statics = __importStar(require("@bitgo-beta/statics"));
|
|
54
|
+
const utxolib = __importStar(require("@bitgo-beta/utxo-lib"));
|
|
55
|
+
const crypto_1 = require("crypto");
|
|
56
|
+
const macaroon_1 = require("macaroon");
|
|
57
|
+
const bs58check = __importStar(require("bs58check"));
|
|
58
|
+
const sdkcore = __importStar(require("@bitgo-beta/sdk-core"));
|
|
59
|
+
// https://github.com/lightningnetwork/lnd/blob/master/docs/remote-signing.md#the-signer-node
|
|
60
|
+
exports.signerMacaroonPermissions = [
|
|
61
|
+
{
|
|
62
|
+
entity: 'message',
|
|
63
|
+
action: 'write',
|
|
64
|
+
},
|
|
65
|
+
{
|
|
66
|
+
entity: 'signer',
|
|
67
|
+
action: 'generate',
|
|
68
|
+
},
|
|
69
|
+
{
|
|
70
|
+
entity: 'address',
|
|
71
|
+
action: 'read',
|
|
72
|
+
},
|
|
73
|
+
{
|
|
74
|
+
entity: 'onchain',
|
|
75
|
+
action: 'write',
|
|
76
|
+
},
|
|
77
|
+
];
|
|
78
|
+
exports.lightningNetworkName = ['bitcoin', 'testnet'];
|
|
79
|
+
/**
|
|
80
|
+
* Checks if the coin name is a lightning coin name.
|
|
81
|
+
*/
|
|
82
|
+
function isLightningCoinName(coinName) {
|
|
83
|
+
return coinName === 'lnbtc' || coinName === 'tlnbtc';
|
|
84
|
+
}
|
|
85
|
+
/**
|
|
86
|
+
* Get the utxolib network for a lightning network.
|
|
87
|
+
*/
|
|
88
|
+
function getLightningNetwork(networkName) {
|
|
89
|
+
return utxolib.networks[networkName];
|
|
90
|
+
}
|
|
91
|
+
/**
|
|
92
|
+
* Get the lightning coin name for a utxolib network.
|
|
93
|
+
*/
|
|
94
|
+
function getLightningCoinName(network) {
|
|
95
|
+
return network === utxolib.networks.bitcoin ? 'lnbtc' : 'tlnbtc';
|
|
96
|
+
}
|
|
97
|
+
/**
|
|
98
|
+
* Checks if the network name is a valid lightning network name.
|
|
99
|
+
*/
|
|
100
|
+
function isValidLightningNetworkName(networkName) {
|
|
101
|
+
return exports.lightningNetworkName.includes(networkName);
|
|
102
|
+
}
|
|
103
|
+
/**
|
|
104
|
+
* Checks if the network is a valid lightning network.
|
|
105
|
+
*/
|
|
106
|
+
function isValidLightningNetwork(network) {
|
|
107
|
+
return utxolib.isValidNetwork(network) && isValidLightningNetworkName(utxolib.getNetworkName(network));
|
|
108
|
+
}
|
|
109
|
+
/**
|
|
110
|
+
* Returns the statics network data for a lightning coin.
|
|
111
|
+
*/
|
|
112
|
+
function getStaticsLightningNetwork(coinName) {
|
|
113
|
+
if (!isLightningCoinName(coinName)) {
|
|
114
|
+
throw new Error(`${coinName} is not a lightning coin`);
|
|
115
|
+
}
|
|
116
|
+
const coin = statics.coins.get(coinName);
|
|
117
|
+
if (!(coin instanceof statics.LightningCoin)) {
|
|
118
|
+
throw new Error('coin is not a lightning coin');
|
|
119
|
+
}
|
|
120
|
+
return coin.network;
|
|
121
|
+
}
|
|
122
|
+
/**
|
|
123
|
+
* Returns the utxolib network for a lightning coin.
|
|
124
|
+
*/
|
|
125
|
+
function getUtxolibNetwork(coinName) {
|
|
126
|
+
const networkName = getStaticsLightningNetwork(coinName).utxolibName;
|
|
127
|
+
if (!isValidLightningNetworkName(networkName)) {
|
|
128
|
+
throw new Error('invalid lightning network');
|
|
129
|
+
}
|
|
130
|
+
return getLightningNetwork(networkName);
|
|
131
|
+
}
|
|
132
|
+
/**
|
|
133
|
+
* Returns coin specific data for a lightning coin.
|
|
134
|
+
*/
|
|
135
|
+
function unwrapLightningCoinSpecific(obj, coinSpecificPath) {
|
|
136
|
+
if (coinSpecificPath !== 'lnbtc' && coinSpecificPath !== 'tlnbtc') {
|
|
137
|
+
throw new Error(`invalid coinSpecificPath ${coinSpecificPath} for lightning coin`);
|
|
138
|
+
}
|
|
139
|
+
if (coinSpecificPath === 'lnbtc' && 'lnbtc' in obj) {
|
|
140
|
+
return obj.lnbtc;
|
|
141
|
+
}
|
|
142
|
+
if (coinSpecificPath === 'tlnbtc' && 'tlnbtc' in obj) {
|
|
143
|
+
return obj.tlnbtc;
|
|
144
|
+
}
|
|
145
|
+
throw new Error('invalid lightning coin specific');
|
|
146
|
+
}
|
|
147
|
+
/**
|
|
148
|
+
* Adds an IP caveat to a macaroon and returns the modified macaroon as a Base64 string.
|
|
149
|
+
*/
|
|
150
|
+
function addIPCaveatToMacaroon(macaroonBase64, ip) {
|
|
151
|
+
const macaroon = (0, macaroon_1.importMacaroon)(macaroonBase64);
|
|
152
|
+
macaroon.addFirstPartyCaveat(`ipaddr ${ip}`);
|
|
153
|
+
return (0, macaroon_1.bytesToBase64)(macaroon.exportBinary());
|
|
154
|
+
}
|
|
155
|
+
exports.PURPOSE_WRAPPED_P2WKH = 49;
|
|
156
|
+
exports.PURPOSE_P2WKH = 84;
|
|
157
|
+
exports.PURPOSE_P2TR = 86;
|
|
158
|
+
exports.PURPOSE_ALL_OTHERS = 1017;
|
|
159
|
+
/**
|
|
160
|
+
* Converts an extended public key (xpub) to the appropriate prefix (ypub, vpub, etc.) based on its purpose and network.
|
|
161
|
+
*/
|
|
162
|
+
function convertXpubPrefix(xpub, purpose, isMainnet) {
|
|
163
|
+
if (purpose === exports.PURPOSE_P2TR || purpose === exports.PURPOSE_ALL_OTHERS) {
|
|
164
|
+
return xpub;
|
|
165
|
+
}
|
|
166
|
+
const data = bs58check.decode(xpub);
|
|
167
|
+
let versionBytes;
|
|
168
|
+
switch (purpose) {
|
|
169
|
+
case exports.PURPOSE_WRAPPED_P2WKH:
|
|
170
|
+
versionBytes = isMainnet ? Buffer.from([0x04, 0x9d, 0x7c, 0xb2]) : Buffer.from([0x04, 0x4a, 0x52, 0x62]); // ypub/upub for p2sh-p2wpkh
|
|
171
|
+
break;
|
|
172
|
+
case exports.PURPOSE_P2WKH:
|
|
173
|
+
versionBytes = isMainnet ? Buffer.from([0x04, 0xb2, 0x47, 0x46]) : Buffer.from([0x04, 0x5f, 0x1c, 0xf6]); // zpub/vpub for p2wpkh
|
|
174
|
+
break;
|
|
175
|
+
default:
|
|
176
|
+
throw new Error('Unsupported purpose');
|
|
177
|
+
}
|
|
178
|
+
versionBytes.copy(data, 0, 0, 4);
|
|
179
|
+
return bs58check.encode(data);
|
|
180
|
+
}
|
|
181
|
+
/**
|
|
182
|
+
* Converts a prefix related to purpose and network (ypub, vpub, etc.) to extended public key (xpub).
|
|
183
|
+
*/
|
|
184
|
+
function revertXpubPrefix(xpub, purpose, isMainnet) {
|
|
185
|
+
// If the purpose is P2TR or ALL_OTHERS, the key is already in the standard format (xpub/tpub),
|
|
186
|
+
// so we return it unmodified. This is the same bypass condition.
|
|
187
|
+
if (purpose === exports.PURPOSE_P2TR || purpose === exports.PURPOSE_ALL_OTHERS) {
|
|
188
|
+
return xpub;
|
|
189
|
+
}
|
|
190
|
+
// 1. Decode the extended public key to get the raw bytes
|
|
191
|
+
const data = bs58check.decode(xpub);
|
|
192
|
+
let versionBytes;
|
|
193
|
+
// 2. Determine the standard prefix (xpub/tpub) based on the network
|
|
194
|
+
switch (purpose) {
|
|
195
|
+
case exports.PURPOSE_WRAPPED_P2WKH:
|
|
196
|
+
case exports.PURPOSE_P2WKH:
|
|
197
|
+
// All standard, non-SegWit-specific keys use the same prefix (xpub for mainnet, tpub for testnet)
|
|
198
|
+
versionBytes = isMainnet
|
|
199
|
+
? Buffer.from([0x04, 0x88, 0xb2, 0x1e]) // xpub
|
|
200
|
+
: Buffer.from([0x04, 0x35, 0x87, 0xcf]); // tpub
|
|
201
|
+
break;
|
|
202
|
+
default:
|
|
203
|
+
// This case should ideally not be hit if the input key is one of the converted types
|
|
204
|
+
throw new Error('Unsupported purpose for reversal');
|
|
205
|
+
}
|
|
206
|
+
// 3. Overwrite the existing prefix (ypub, zpub, upub, or vpub)
|
|
207
|
+
// with the standard xpub or tpub prefix.
|
|
208
|
+
versionBytes.copy(data, 0, 0, 4);
|
|
209
|
+
// 4. Encode the modified byte data back to a Base58Check string
|
|
210
|
+
return bs58check.encode(data);
|
|
211
|
+
}
|
|
212
|
+
/**
|
|
213
|
+
* Derives watch-only accounts from the master HD node for the given purposes and network.
|
|
214
|
+
*/
|
|
215
|
+
function deriveWatchOnlyAccounts(masterHDNode, isMainnet, params = { onlyAddressCreationAccounts: false }) {
|
|
216
|
+
// https://github.com/lightningnetwork/lnd/blob/master/docs/remote-signing.md#required-accounts
|
|
217
|
+
if (masterHDNode.isNeutered()) {
|
|
218
|
+
throw new Error('masterHDNode must not be neutered');
|
|
219
|
+
}
|
|
220
|
+
const purposes = params.onlyAddressCreationAccounts
|
|
221
|
+
? [exports.PURPOSE_WRAPPED_P2WKH, exports.PURPOSE_P2WKH, exports.PURPOSE_P2TR]
|
|
222
|
+
: [exports.PURPOSE_WRAPPED_P2WKH, exports.PURPOSE_P2WKH, exports.PURPOSE_P2TR, exports.PURPOSE_ALL_OTHERS];
|
|
223
|
+
return purposes.flatMap((purpose) => {
|
|
224
|
+
const maxAccount = purpose === exports.PURPOSE_ALL_OTHERS ? 255 : 0;
|
|
225
|
+
const coinType = purpose !== exports.PURPOSE_ALL_OTHERS || isMainnet ? 0 : 1;
|
|
226
|
+
return Array.from({ length: maxAccount + 1 }, (_, account) => {
|
|
227
|
+
const path = `m/${purpose}'/${coinType}'/${account}'`;
|
|
228
|
+
const derivedNode = masterHDNode.derivePath(path);
|
|
229
|
+
// Ensure the node is neutered (i.e., converted to public key only)
|
|
230
|
+
const neuteredNode = derivedNode.neutered();
|
|
231
|
+
const xpub = convertXpubPrefix(neuteredNode.toBase58(), purpose, isMainnet);
|
|
232
|
+
return {
|
|
233
|
+
purpose,
|
|
234
|
+
coin_type: coinType,
|
|
235
|
+
account,
|
|
236
|
+
xpub,
|
|
237
|
+
};
|
|
238
|
+
});
|
|
239
|
+
});
|
|
240
|
+
}
|
|
241
|
+
/**
|
|
242
|
+
* Creates a watch-only wallet init data from the provided signer root key and network.
|
|
243
|
+
*/
|
|
244
|
+
function createWatchOnly(signerRootKey, network) {
|
|
245
|
+
const masterHDNode = utxolib.bip32.fromBase58(signerRootKey, network);
|
|
246
|
+
const getCurrentUnixTimestamp = () => {
|
|
247
|
+
return Math.floor(Date.now() / 1000);
|
|
248
|
+
};
|
|
249
|
+
const master_key_birthday_timestamp = getCurrentUnixTimestamp().toString();
|
|
250
|
+
const master_key_fingerprint = masterHDNode.fingerprint.toString('hex');
|
|
251
|
+
const accounts = deriveWatchOnlyAccounts(masterHDNode, utxolib.isMainnet(network));
|
|
252
|
+
return { master_key_birthday_timestamp, master_key_fingerprint, accounts };
|
|
253
|
+
}
|
|
254
|
+
/**
|
|
255
|
+
* Derives the shared Elliptic Curve Diffie-Hellman (ECDH) secret between the user's auth extended private key
|
|
256
|
+
* and the Lightning service's public key for secure communication.
|
|
257
|
+
*/
|
|
258
|
+
function deriveLightningServiceSharedSecret(coinName, userAuthXprv) {
|
|
259
|
+
const publicKey = Buffer.from(getStaticsLightningNetwork(coinName).lightningServicePubKey, 'hex');
|
|
260
|
+
const userAuthHdNode = utxolib.bip32.fromBase58(userAuthXprv);
|
|
261
|
+
return sdkcore.getSharedSecret(userAuthHdNode, publicKey);
|
|
262
|
+
}
|
|
263
|
+
/**
|
|
264
|
+
* Derives the shared secret for the middleware using a private key and the middleware's public key.
|
|
265
|
+
*/
|
|
266
|
+
function deriveMiddlewareSharedSecret(coinName, xprv) {
|
|
267
|
+
const publicKey = Buffer.from(getStaticsLightningNetwork(coinName).middlewarePubKey, 'hex');
|
|
268
|
+
const userAuthHdNode = utxolib.bip32.fromBase58(xprv);
|
|
269
|
+
return sdkcore.getSharedSecret(userAuthHdNode, publicKey);
|
|
270
|
+
}
|
|
271
|
+
/**
|
|
272
|
+
* Derives the shared secret for TAT service using ta private key and the TAT public key.
|
|
273
|
+
*/
|
|
274
|
+
function deriveTatSharedSecret(coinName, xprv) {
|
|
275
|
+
const publicKey = Buffer.from(getStaticsLightningNetwork(coinName).tatPubKey, 'hex');
|
|
276
|
+
const userAuthHdNode = utxolib.bip32.fromBase58(xprv);
|
|
277
|
+
return sdkcore.getSharedSecret(userAuthHdNode, publicKey);
|
|
278
|
+
}
|
|
279
|
+
/**
|
|
280
|
+
* Given a seed, compute a BIP32 derivation index.
|
|
281
|
+
* 0 <= index < 2147483648 (largest 31 bit number). This needs to be 2^31 - 1 so that the bip32 library
|
|
282
|
+
* can derive the hardened key.
|
|
283
|
+
* @param seed (optional) If nothing provided, we will generate one randomly
|
|
284
|
+
*/
|
|
285
|
+
function computeBip32DerivationIndexFromSeed(seed) {
|
|
286
|
+
return ((Buffer.from(utxolib.crypto.sha256(Buffer.from(seed ?? (0, crypto_1.randomBytes)(32).toString('hex'), 'utf8'))).readUint32BE(0) %
|
|
287
|
+
Math.pow(2, 31)) -
|
|
288
|
+
1);
|
|
289
|
+
}
|
|
290
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibGlnaHRuaW5nVXRpbHMuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi9zcmMvbGlnaHRuaW5nL2xpZ2h0bmluZ1V0aWxzLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztBQWtDQSxrREFFQztBQUtELGtEQUVDO0FBS0Qsb0RBRUM7QUFLRCxrRUFFQztBQUtELDBEQUVDO0FBS0QsZ0VBU0M7QUFLRCw4Q0FNQztBQUtELGtFQVdDO0FBS0Qsc0RBSUM7QUE0Q0QsNENBZ0NDO0FBS0QsMERBZ0NDO0FBS0QsMENBU0M7QUFNRCxnRkFJQztBQUtELG9FQUlDO0FBS0Qsc0RBSUM7QUFRRCxrRkFNQztBQTNSRCw2REFBK0M7QUFDL0MsOERBQWdEO0FBQ2hELG1DQUFxQztBQUNyQyx1Q0FBeUQ7QUFDekQscURBQXVDO0FBQ3ZDLDhEQUFnRDtBQUdoRCw2RkFBNkY7QUFDaEYsUUFBQSx5QkFBeUIsR0FBRztJQUN2QztRQUNFLE1BQU0sRUFBRSxTQUFTO1FBQ2pCLE1BQU0sRUFBRSxPQUFPO0tBQ2hCO0lBQ0Q7UUFDRSxNQUFNLEVBQUUsUUFBUTtRQUNoQixNQUFNLEVBQUUsVUFBVTtLQUNuQjtJQUNEO1FBQ0UsTUFBTSxFQUFFLFNBQVM7UUFDakIsTUFBTSxFQUFFLE1BQU07S0FDZjtJQUNEO1FBQ0UsTUFBTSxFQUFFLFNBQVM7UUFDakIsTUFBTSxFQUFFLE9BQU87S0FDaEI7Q0FDRixDQUFDO0FBRVcsUUFBQSxvQkFBb0IsR0FBRyxDQUFDLFNBQVMsRUFBRSxTQUFTLENBQVUsQ0FBQztBQUdwRTs7R0FFRztBQUNILFNBQWdCLG1CQUFtQixDQUFDLFFBQWlCO0lBQ25ELE9BQU8sUUFBUSxLQUFLLE9BQU8sSUFBSSxRQUFRLEtBQUssUUFBUSxDQUFDO0FBQ3ZELENBQUM7QUFFRDs7R0FFRztBQUNILFNBQWdCLG1CQUFtQixDQUFDLFdBQWlDO0lBQ25FLE9BQU8sT0FBTyxDQUFDLFFB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Q0YsQ0FBQztBQUNKLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgKiBhcyBzdGF0aWNzIGZyb20gJ0BiaXRnby1iZXRhL3N0YXRpY3MnO1xuaW1wb3J0ICogYXMgdXR4b2xpYiBmcm9tICdAYml0Z28tYmV0YS91dHhvLWxpYic7XG5pbXBvcnQgeyByYW5kb21CeXRlcyB9IGZyb20gJ2NyeXB0byc7XG5pbXBvcnQgeyBpbXBvcnRNYWNhcm9vbiwgYnl0ZXNUb0Jhc2U2NCB9IGZyb20gJ21hY2Fyb29uJztcbmltcG9ydCAqIGFzIGJzNThjaGVjayBmcm9tICdiczU4Y2hlY2snO1xuaW1wb3J0ICogYXMgc2RrY29yZSBmcm9tICdAYml0Z28tYmV0YS9zZGstY29yZSc7XG5pbXBvcnQgeyBXYXRjaE9ubHksIFdhdGNoT25seUFjY291bnQgfSBmcm9tICcuLi9jb2RlY3MnO1xuXG4vLyBodHRwczovL2dpdGh1Yi5jb20vbGlnaHRuaW5nbmV0d29yay9sbmQvYmxvYi9tYXN0ZXIvZG9jcy9yZW1vdGUtc2lnbmluZy5tZCN0aGUtc2lnbmVyLW5vZGVcbmV4cG9ydCBjb25zdCBzaWduZXJNYWNhcm9vblBlcm1pc3Npb25zID0gW1xuICB7XG4gICAgZW50aXR5OiAnbWVzc2FnZScsXG4gICAgYWN0aW9uOiAnd3JpdGUnLFxuICB9LFxuICB7XG4gICAgZW50aXR5OiAnc2lnbmVyJyxcbiAgICBhY3Rpb246ICdnZW5lcmF0ZScsXG4gIH0sXG4gIHtcbiAgICBlbnRpdHk6ICdhZGRyZXNzJyxcbiAgICBhY3Rpb246ICdyZWFkJyxcbiAgfSxcbiAge1xuICAgIGVudGl0eTogJ29uY2hhaW4nLFxuICAgIGFjdGlvbjogJ3dyaXRlJyxcbiAgfSxcbl07XG5cbmV4cG9ydCBjb25zdCBsaWdodG5pbmdOZXR3b3JrTmFtZSA9IFsnYml0Y29pbicsICd0ZXN0bmV0J10gYXMgY29uc3Q7XG5leHBvcnQgdHlwZSBMaWdodG5pbmdOZXR3b3JrTmFtZSA9ICh0eXBlb2YgbGlnaHRuaW5nTmV0d29ya05hbWUpW251bWJlcl07XG5cbi8qKlxuICogQ2hlY2tzIGlmIHRoZSBjb2luIG5hbWUgaXMgYSBsaWdodG5pbmcgY29pbiBuYW1lLlxuICovXG5leHBvcnQgZnVuY3Rpb24gaXNMaWdodG5pbmdDb2luTmFtZShjb2luTmFtZTogdW5rbm93bik6IGNvaW5OYW1lIGlzICdsbmJ0YycgfCAndGxuYnRjJyB7XG4gIHJldHVybiBjb2luTmFtZSA9PT0gJ2xuYnRjJyB8fCBjb2luTmFtZSA9PT0gJ3RsbmJ0Yyc7XG59XG5cbi8qKlxuICogR2V0IHRoZSB1dHhvbGliIG5ldHdvcmsgZm9yIGEgbGlnaHRuaW5nIG5ldHdvcmsuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBnZXRMaWdodG5pbmdOZXR3b3JrKG5ldHdvcmtOYW1lOiBMaWdodG5pbmdOZXR3b3JrTmFtZSk6IHV0eG9saWIuTmV0d29yayB7XG4gIHJldHVybiB1dHhvbGliLm5ldHdvcmtzW25ldHdvcmtOYW1lXTtcbn1cblxuLyoqXG4gKiBHZXQgdGhlIGxpZ2h0bmluZyBjb2luIG5hbWUgZm9yIGEgdXR4b2xpYiBuZXR3b3JrLlxuICovXG5leHBvcnQgZnVuY3Rpb24gZ2V0TGlnaHRuaW5nQ29pbk5hbWUobmV0d29yazogdXR4b2xpYi5OZXR3b3JrKTogc3RyaW5nIHtcbiAgcmV0dXJuIG5ldHdvcmsgPT09IHV0eG9saWIubmV0d29ya3MuYml0Y29pbiA/ICdsbmJ0YycgOiAndGxuYnRjJztcbn1cblxuLyoqXG4gKiBDaGVja3MgaWYgdGhlIG5ldHdvcmsgbmFtZSBpcyBhIHZhbGlkIGxpZ2h0bmluZyBuZXR3b3JrIG5hbWUuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBpc1ZhbGlkTGlnaHRuaW5nTmV0d29ya05hbWUobmV0d29ya05hbWU6IHVua25vd24pOiBuZXR3b3JrTmFtZSBpcyBMaWdodG5pbmdOZXR3b3JrTmFtZSB7XG4gIHJldHVybiBsaWdodG5pbmdOZXR3b3JrTmFtZS5pbmNsdWRlcyhuZXR3b3JrTmFtZSBhcyBMaWdodG5pbmdOZXR3b3JrTmFtZSk7XG59XG5cbi8qKlxuICogQ2hlY2tzIGlmIHRoZSBuZXR3b3JrIGlzIGEgdmFsaWQgbGlnaHRuaW5nIG5ldHdvcmsuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBpc1ZhbGlkTGlnaHRuaW5nTmV0d29yayhuZXR3b3JrOiB1bmtub3duKTogbmV0d29yayBpcyB1dHhvbGliLk5ldHdvcmsge1xuICByZXR1cm4gdXR4b2xpYi5pc1ZhbGlkTmV0d29yayhuZXR3b3JrKSAmJiBpc1ZhbGlkTGlnaHRuaW5nTmV0d29ya05hbWUodXR4b2xpYi5nZXROZXR3b3JrTmFtZShuZXR3b3JrKSk7XG59XG5cbi8qKlxuICogUmV0dXJucyB0aGUgc3RhdGljcyBuZXR3b3JrIGRhdGEgZm9yIGEgbGlnaHRuaW5nIGNvaW4uXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBnZXRTdGF0aWNzTGlnaHRuaW5nTmV0d29yayhjb2luTmFtZTogc3RyaW5nKTogc3RhdGljcy5MaWdodG5pbmdOZXR3b3JrIHtcbiAgaWYgKCFpc0xpZ2h0bmluZ0NvaW5OYW1lKGNvaW5OYW1lKSkge1xuICAgIHRocm93IG5ldyBFcnJvcihgJHtjb2luTmFtZX0gaXMgbm90IGEgbGlnaHRuaW5nIGNvaW5gKTtcbiAgfVxuICBjb25zdCBjb2luID0gc3RhdGljcy5jb2lucy5nZXQoY29pbk5hbWUpO1xuICBpZiAoIShjb2luIGluc3RhbmNlb2Ygc3RhdGljcy5MaWdodG5pbmdDb2luKSkge1xuICAgIHRocm93IG5ldyBFcnJvcignY29pbiBpcyBub3QgYSBsaWdodG5pbmcgY29pbicpO1xuICB9XG4gIHJldHVybiBjb2luLm5ldHdvcms7XG59XG5cbi8qKlxuICogUmV0dXJucyB0aGUgdXR4b2xpYiBuZXR3b3JrIGZvciBhIGxpZ2h0bmluZyBjb2luLlxuICovXG5leHBvcnQgZnVuY3Rpb24gZ2V0VXR4b2xpYk5ldHdvcmsoY29pbk5hbWU6IHN0cmluZyk6IHV0eG9saWIuTmV0d29yayB7XG4gIGNvbnN0IG5ldHdvcmtOYW1lID0gZ2V0U3RhdGljc0xpZ2h0bmluZ05ldHdvcmsoY29pbk5hbWUpLnV0eG9saWJOYW1lO1xuICBpZiAoIWlzVmFsaWRMaWdodG5pbmdOZXR3b3JrTmFtZShuZXR3b3JrTmFtZSkpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ2ludmFsaWQgbGlnaHRuaW5nIG5ldHdvcmsnKTtcbiAgfVxuICByZXR1cm4gZ2V0TGlnaHRuaW5nTmV0d29yayhuZXR3b3JrTmFtZSk7XG59XG5cbi8qKlxuICogUmV0dXJucyBjb2luIHNwZWNpZmljIGRhdGEgZm9yIGEgbGlnaHRuaW5nIGNvaW4uXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiB1bndyYXBMaWdodG5pbmdDb2luU3BlY2lmaWM8Vj4ob2JqOiB7IGxuYnRjOiBWIH0gfCB7IHRsbmJ0YzogViB9LCBjb2luU3BlY2lmaWNQYXRoOiBzdHJpbmcpOiBWIHtcbiAgaWYgKGNvaW5TcGVjaWZpY1BhdGggIT09ICdsbmJ0YycgJiYgY29pblNwZWNpZmljUGF0aCAhPT0gJ3RsbmJ0YycpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoYGludmFsaWQgY29pblNwZWNpZmljUGF0aCAke2NvaW5TcGVjaWZpY1BhdGh9IGZvciBsaWdodG5pbmcgY29pbmApO1xuICB9XG4gIGlmIChjb2luU3BlY2lmaWNQYXRoID09PSAnbG5idGMnICYmICdsbmJ0YycgaW4gb2JqKSB7XG4gICAgcmV0dXJuIG9iai5sbmJ0YztcbiAgfVxuICBpZiAoY29pblNwZWNpZmljUGF0aCA9PT0gJ3RsbmJ0YycgJiYgJ3RsbmJ0YycgaW4gb2JqKSB7XG4gICAgcmV0dXJuIG9iai50bG5idGM7XG4gIH1cbiAgdGhyb3cgbmV3IEVycm9yKCdpbnZhbGlkIGxpZ2h0bmluZyBjb2luIHNwZWNpZmljJyk7XG59XG5cbi8qKlxuICogQWRkcyBhbiBJUCBjYXZlYXQgdG8gYSBtYWNhcm9vbiBhbmQgcmV0dXJucyB0aGUgbW9kaWZpZWQgbWFjYXJvb24gYXMgYSBCYXNlNjQgc3RyaW5nLlxuICovXG5leHBvcnQgZnVuY3Rpb24gYWRkSVBDYXZlYXRUb01hY2Fyb29uKG1hY2Fyb29uQmFzZTY0OiBzdHJpbmcsIGlwOiBzdHJpbmcpOiBzdHJpbmcge1xuICBjb25zdCBtYWNhcm9vbiA9IGltcG9ydE1hY2Fyb29uKG1hY2Fyb29uQmFzZTY0KTtcbiAgbWFjYXJvb24uYWRkRmlyc3RQYXJ0eUNhdmVhdChgaXBhZGRyICR7aXB9YCk7XG4gIHJldHVybiBieXRlc1RvQmFzZTY0KG1hY2Fyb29uLmV4cG9ydEJpbmFyeSgpKTtcbn1cblxuZXhwb3J0IGNvbnN0IFBVUlBPU0VfV1JBUFBFRF9QMldLSCA9IDQ5O1xuZXhwb3J0IGNvbnN0IFBVUlBPU0VfUDJXS0ggPSA4NDtcbmV4cG9ydCBjb25zdCBQVVJQT1NFX1AyVFIgPSA4NjtcbmV4cG9ydCBjb25zdCBQVVJQT1NFX0FMTF9PVEhFUlMgPSAxMDE3O1xuXG5leHBvcnQgdHlwZSBFeHRlbmRlZEtleVB1cnBvc2UgPVxuICB8IHR5cGVvZiBQVVJQT1NFX1dSQVBQRURfUDJXS0hcbiAgfCB0eXBlb2YgUFVSUE9TRV9QMldLSFxuICB8IHR5cGVvZiBQVVJQT1NFX1AyVFJcbiAgfCB0eXBlb2YgUFVSUE9TRV9BTExfT1RIRVJTO1xuXG5leHBvcnQgdHlwZSBFeHRlbmRlZEtleUFkZHJlc3NQdXJwb3NlID0gdHlwZW9mIFBVUlBPU0VfV1JBUFBFRF9QMldLSCB8IHR5cGVvZiBQVVJQT1NFX1AyV0tIIHwgdHlwZW9mIFBVUlBPU0VfUDJUUjtcblxuLyoqXG4gKiBDb252ZXJ0cyBhbiBleHRlbmRlZCBwdWJsaWMga2V5ICh4cHViKSB0byB0aGUgYXBwcm9wcmlhdGUgcHJlZml4ICh5cHViLCB2cHViLCBldGMuKSBiYXNlZCBvbiBpdHMgcHVycG9zZSBhbmQgbmV0d29yay5cbiAqL1xuZnVuY3Rpb24gY29udmVydFhwdWJQcmVmaXgoeHB1Yjogc3RyaW5nLCBwdXJwb3NlOiBFeHRlbmRlZEtleVB1cnBvc2UsIGlzTWFpbm5ldDogYm9vbGVhbik6IHN0cmluZyB7XG4gIGlmIChwdXJwb3NlID09PSBQVVJQT1NFX1AyVFIgfHwgcHVycG9zZSA9PT0gUFVSUE9TRV9BTExfT1RIRVJTKSB7XG4gICAgcmV0dXJuIHhwdWI7XG4gIH1cbiAgY29uc3QgZGF0YSA9IGJzNThjaGVjay5kZWNvZGUoeHB1Yik7XG5cbiAgbGV0IHZlcnNpb25CeXRlczogQnVmZmVyO1xuXG4gIHN3aXRjaCAocHVycG9zZSkge1xuICAgIGNhc2UgUFVSUE9TRV9XUkFQUEVEX1AyV0tIOlxuICAgICAgdmVyc2lvbkJ5dGVzID0gaXNNYWlubmV0ID8gQnVmZmVyLmZyb20oWzB4MDQsIDB4OWQsIDB4N2MsIDB4YjJdKSA6IEJ1ZmZlci5mcm9tKFsweDA0LCAweDRhLCAweDUyLCAweDYyXSk7IC8vIHlwdWIvdXB1YiBmb3IgcDJzaC1wMndwa2hcbiAgICAgIGJyZWFrO1xuICAgIGNhc2UgUFVSUE9TRV9QMldLSDpcbiAgICAgIHZlcnNpb25CeXRlcyA9IGlzTWFpbm5ldCA/IEJ1ZmZlci5mcm9tKFsweDA0LCAweGIyLCAweDQ3LCAweDQ2XSkgOiBCdWZmZXIuZnJvbShbMHgwNCwgMHg1ZiwgMHgxYywgMHhmNl0pOyAvLyB6cHViL3ZwdWIgZm9yIHAyd3BraFxuICAgICAgYnJlYWs7XG4gICAgZGVmYXVsdDpcbiAgICAgIHRocm93IG5ldyBFcnJvcignVW5zdXBwb3J0ZWQgcHVycG9zZScpO1xuICB9XG5cbiAgdmVyc2lvbkJ5dGVzLmNvcHkoZGF0YSwgMCwgMCwgNCk7XG4gIHJldHVybiBiczU4Y2hlY2suZW5jb2RlKGRhdGEpO1xufVxuXG4vKipcbiAqIENvbnZlcnRzIGEgcHJlZml4IHJlbGF0ZWQgdG8gcHVycG9zZSBhbmQgbmV0d29yayAoeXB1YiwgdnB1YiwgZXRjLikgdG8gZXh0ZW5kZWQgcHVibGljIGtleSAoeHB1YikuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiByZXZlcnRYcHViUHJlZml4KHhwdWI6IHN0cmluZywgcHVycG9zZTogRXh0ZW5kZWRLZXlQdXJwb3NlLCBpc01haW5uZXQ6IGJvb2xlYW4pOiBzdHJpbmcge1xuICAvLyBJZiB0aGUgcHVycG9zZSBpcyBQMlRSIG9yIEFMTF9PVEhFUlMsIHRoZSBrZXkgaXMgYWxyZWFkeSBpbiB0aGUgc3RhbmRhcmQgZm9ybWF0ICh4cHViL3RwdWIpLFxuICAvLyBzbyB3ZSByZXR1cm4gaXQgdW5tb2RpZmllZC4gVGhpcyBpcyB0aGUgc2FtZSBieXBhc3MgY29uZGl0aW9uLlxuICBpZiAocHVycG9zZSA9PT0gUFVSUE9TRV9QMlRSIHx8IHB1cnBvc2UgPT09IFBVUlBPU0VfQUxMX09USEVSUykge1xuICAgIHJldHVybiB4cHViO1xuICB9XG5cbiAgLy8gMS4gRGVjb2RlIHRoZSBleHRlbmRlZCBwdWJsaWMga2V5IHRvIGdldCB0aGUgcmF3IGJ5dGVzXG4gIGNvbnN0IGRhdGEgPSBiczU4Y2hlY2suZGVjb2RlKHhwdWIpO1xuXG4gIGxldCB2ZXJzaW9uQnl0ZXM6IEJ1ZmZlcjtcblxuICAvLyAyLiBEZXRlcm1pbmUgdGhlIHN0YW5kYXJkIHByZWZpeCAoeHB1Yi90cHViKSBiYXNlZCBvbiB0aGUgbmV0d29ya1xuICBzd2l0Y2ggKHB1cnBvc2UpIHtcbiAgICBjYXNlIFBVUlBPU0VfV1JBUFBFRF9QMldLSDpcbiAgICBjYXNlIFBVUlBPU0VfUDJXS0g6XG4gICAgICAvLyBBbGwgc3RhbmRhcmQsIG5vbi1TZWdXaXQtc3BlY2lmaWMga2V5cyB1c2UgdGhlIHNhbWUgcHJlZml4ICh4cHViIGZvciBtYWlubmV0LCB0cHViIGZvciB0ZXN0bmV0KVxuICAgICAgdmVyc2lvbkJ5dGVzID0gaXNNYWlubmV0XG4gICAgICAgID8gQnVmZmVyLmZyb20oWzB4MDQsIDB4ODgsIDB4YjIsIDB4MWVdKSAvLyB4cHViXG4gICAgICAgIDogQnVmZmVyLmZyb20oWzB4MDQsIDB4MzUsIDB4ODcsIDB4Y2ZdKTsgLy8gdHB1YlxuICAgICAgYnJlYWs7XG4gICAgZGVmYXVsdDpcbiAgICAgIC8vIFRoaXMgY2FzZSBzaG91bGQgaWRlYWxseSBub3QgYmUgaGl0IGlmIHRoZSBpbnB1dCBrZXkgaXMgb25lIG9mIHRoZSBjb252ZXJ0ZWQgdHlwZXNcbiAgICAgIHRocm93IG5ldyBFcnJvcignVW5zdXBwb3J0ZWQgcHVycG9zZSBmb3IgcmV2ZXJzYWwnKTtcbiAgfVxuXG4gIC8vIDMuIE92ZXJ3cml0ZSB0aGUgZXhpc3RpbmcgcHJlZml4ICh5cHViLCB6cHViLCB1cHViLCBvciB2cHViKVxuICAvLyB3aXRoIHRoZSBzdGFuZGFyZCB4cHViIG9yIHRwdWIgcHJlZml4LlxuICB2ZXJzaW9uQnl0ZXMuY29weShkYXRhLCAwLCAwLCA0KTtcblxuICAvLyA0LiBFbmNvZGUgdGhlIG1vZGlmaWVkIGJ5dGUgZGF0YSBiYWNrIHRvIGEgQmFzZTU4Q2hlY2sgc3RyaW5nXG4gIHJldHVybiBiczU4Y2hlY2suZW5jb2RlKGRhdGEpO1xufVxuXG4vKipcbiAqIERlcml2ZXMgd2F0Y2gtb25seSBhY2NvdW50cyBmcm9tIHRoZSBtYXN0ZXIgSEQgbm9kZSBmb3IgdGhlIGdpdmVuIHB1cnBvc2VzIGFuZCBuZXR3b3JrLlxuICovXG5leHBvcnQgZnVuY3Rpb24gZGVyaXZlV2F0Y2hPbmx5QWNjb3VudHMoXG4gIG1hc3RlckhETm9kZTogdXR4b2xpYi5CSVAzMkludGVyZmFjZSxcbiAgaXNNYWlubmV0OiBib29sZWFuLFxuICBwYXJhbXM6IHsgb25seUFkZHJlc3NDcmVhdGlvbkFjY291bnRzPzogYm9vbGVhbiB9ID0geyBvbmx5QWRkcmVzc0NyZWF0aW9uQWNjb3VudHM6IGZhbHNlIH1cbik6IFdhdGNoT25seUFjY291bnRbXSB7XG4gIC8vIGh0dHBzOi8vZ2l0aHViLmNvbS9saWdodG5pbmduZXR3b3JrL2xuZC9ibG9iL21hc3Rlci9kb2NzL3JlbW90ZS1zaWduaW5nLm1kI3JlcXVpcmVkLWFjY291bnRzXG4gIGlmIChtYXN0ZXJIRE5vZGUuaXNOZXV0ZXJlZCgpKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdtYXN0ZXJIRE5vZGUgbXVzdCBub3QgYmUgbmV1dGVyZWQnKTtcbiAgfVxuICBjb25zdCBwdXJwb3NlcyA9IHBhcmFtcy5vbmx5QWRkcmVzc0NyZWF0aW9uQWNjb3VudHNcbiAgICA/IChbUFVSUE9TRV9XUkFQUEVEX1AyV0tILCBQVVJQT1NFX1AyV0tILCBQVVJQT1NFX1AyVFJdIGFzIGNvbnN0KVxuICAgIDogKFtQVVJQT1NFX1dSQVBQRURfUDJXS0gsIFBVUlBPU0VfUDJXS0gsIFBVUlBPU0VfUDJUUiwgUFVSUE9TRV9BTExfT1RIRVJTXSBhcyBjb25zdCk7XG4gIHJldHVybiBwdXJwb3Nlcy5mbGF0TWFwKChwdXJwb3NlKSA9PiB7XG4gICAgY29uc3QgbWF4QWNjb3VudCA9IHB1cnBvc2UgPT09IFBVUlBPU0VfQUxMX09USEVSUyA/IDI1NSA6IDA7XG4gICAgY29uc3QgY29pblR5cGUgPSBwdXJwb3NlICE9PSBQVVJQT1NFX0FMTF9PVEhFUlMgfHwgaXNNYWlubmV0ID8gMCA6IDE7XG5cbiAgICByZXR1cm4gQXJyYXkuZnJvbSh7IGxlbmd0aDogbWF4QWNjb3VudCArIDEgfSwgKF8sIGFjY291bnQpID0+IHtcbiAgICAgIGNvbnN0IHBhdGggPSBgbS8ke3B1cnBvc2V9Jy8ke2NvaW5UeXBlfScvJHthY2NvdW50fSdgO1xuICAgICAgY29uc3QgZGVyaXZlZE5vZGUgPSBtYXN0ZXJIRE5vZGUuZGVyaXZlUGF0aChwYXRoKTtcblxuICAgICAgLy8gRW5zdXJlIHRoZSBub2RlIGlzIG5ldXRlcmVkIChpLmUuLCBjb252ZXJ0ZWQgdG8gcHVibGljIGtleSBvbmx5KVxuICAgICAgY29uc3QgbmV1dGVyZWROb2RlID0gZGVyaXZlZE5vZGUubmV1dGVyZWQoKTtcbiAgICAgIGNvbnN0IHhwdWIgPSBjb252ZXJ0WHB1YlByZWZpeChuZXV0ZXJlZE5vZGUudG9CYXNlNTgoKSwgcHVycG9zZSwgaXNNYWlubmV0KTtcblxuICAgICAgcmV0dXJuIHtcbiAgICAgICAgcHVycG9zZSxcbiAgICAgICAgY29pbl90eXBlOiBjb2luVHlwZSxcbiAgICAgICAgYWNjb3VudCxcbiAgICAgICAgeHB1YixcbiAgICAgIH07XG4gICAgfSk7XG4gIH0pO1xufVxuXG4vKipcbiAqIENyZWF0ZXMgYSB3YXRjaC1vbmx5IHdhbGxldCBpbml0IGRhdGEgZnJvbSB0aGUgcHJvdmlkZWQgc2lnbmVyIHJvb3Qga2V5IGFuZCBuZXR3b3JrLlxuICovXG5leHBvcnQgZnVuY3Rpb24gY3JlYXRlV2F0Y2hPbmx5KHNpZ25lclJvb3RLZXk6IHN0cmluZywgbmV0d29yazogdXR4b2xpYi5OZXR3b3JrKTogV2F0Y2hPbmx5IHtcbiAgY29uc3QgbWFzdGVySEROb2RlID0gdXR4b2xpYi5iaXAzMi5mcm9tQmFzZTU4KHNpZ25lclJvb3RLZXksIG5ldHdvcmspO1xuICBjb25zdCBnZXRDdXJyZW50VW5peFRpbWVzdGFtcCA9ICgpID0+IHtcbiAgICByZXR1cm4gTWF0aC5mbG9vcihEYXRlLm5vdygpIC8gMTAwMCk7XG4gIH07XG4gIGNvbnN0IG1hc3Rlcl9rZXlfYmlydGhkYXlfdGltZXN0YW1wID0gZ2V0Q3VycmVudFVuaXhUaW1lc3RhbXAoKS50b1N0cmluZygpO1xuICBjb25zdCBtYXN0ZXJfa2V5X2ZpbmdlcnByaW50ID0gbWFzdGVySEROb2RlLmZpbmdlcnByaW50LnRvU3RyaW5nKCdoZXgnKTtcbiAgY29uc3QgYWNjb3VudHMgPSBkZXJpdmVXYXRjaE9ubHlBY2NvdW50cyhtYXN0ZXJIRE5vZGUsIHV0eG9saWIuaXNNYWlubmV0KG5ldHdvcmspKTtcbiAgcmV0dXJuIHsgbWFzdGVyX2tleV9iaXJ0aGRheV90aW1lc3RhbXAsIG1hc3Rlcl9rZXlfZmluZ2VycHJpbnQsIGFjY291bnRzIH07XG59XG5cbi8qKlxuICogRGVyaXZlcyB0aGUgc2hhcmVkIEVsbGlwdGljIEN1cnZlIERpZmZpZS1IZWxsbWFuIChFQ0RIKSBzZWNyZXQgYmV0d2VlbiB0aGUgdXNlcidzIGF1dGggZXh0ZW5kZWQgcHJpdmF0ZSBrZXlcbiAqIGFuZCB0aGUgTGlnaHRuaW5nIHNlcnZpY2UncyBwdWJsaWMga2V5IGZvciBzZWN1cmUgY29tbXVuaWNhdGlvbi5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGRlcml2ZUxpZ2h0bmluZ1NlcnZpY2VTaGFyZWRTZWNyZXQoY29pbk5hbWU6ICdsbmJ0YycgfCAndGxuYnRjJywgdXNlckF1dGhYcHJ2OiBzdHJpbmcpOiBCdWZmZXIge1xuICBjb25zdCBwdWJsaWNLZXkgPSBCdWZmZXIuZnJvbShnZXRTdGF0aWNzTGlnaHRuaW5nTmV0d29yayhjb2luTmFtZSkubGlnaHRuaW5nU2VydmljZVB1YktleSwgJ2hleCcpO1xuICBjb25zdCB1c2VyQXV0aEhkTm9kZSA9IHV0eG9saWIuYmlwMzIuZnJvbUJhc2U1OCh1c2VyQXV0aFhwcnYpO1xuICByZXR1cm4gc2RrY29yZS5nZXRTaGFyZWRTZWNyZXQodXNlckF1dGhIZE5vZGUsIHB1YmxpY0tleSk7XG59XG5cbi8qKlxuICogRGVyaXZlcyB0aGUgc2hhcmVkIHNlY3JldCBmb3IgdGhlIG1pZGRsZXdhcmUgdXNpbmcgYSBwcml2YXRlIGtleSBhbmQgdGhlIG1pZGRsZXdhcmUncyBwdWJsaWMga2V5LlxuICovXG5leHBvcnQgZnVuY3Rpb24gZGVyaXZlTWlkZGxld2FyZVNoYXJlZFNlY3JldChjb2luTmFtZTogJ2xuYnRjJyB8ICd0bG5idGMnLCB4cHJ2OiBzdHJpbmcpOiBCdWZmZXIge1xuICBjb25zdCBwdWJsaWNLZXkgPSBCdWZmZXIuZnJvbShnZXRTdGF0aWNzTGlnaHRuaW5nTmV0d29yayhjb2luTmFtZSkubWlkZGxld2FyZVB1YktleSwgJ2hleCcpO1xuICBjb25zdCB1c2VyQXV0aEhkTm9kZSA9IHV0eG9saWIuYmlwMzIuZnJvbUJhc2U1OCh4cHJ2KTtcbiAgcmV0dXJuIHNka2NvcmUuZ2V0U2hhcmVkU2VjcmV0KHVzZXJBdXRoSGROb2RlLCBwdWJsaWNLZXkpO1xufVxuXG4vKipcbiAqIERlcml2ZXMgdGhlIHNoYXJlZCBzZWNyZXQgZm9yIFRBVCBzZXJ2aWNlIHVzaW5nIHRhIHByaXZhdGUga2V5IGFuZCB0aGUgVEFUIHB1YmxpYyBrZXkuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBkZXJpdmVUYXRTaGFyZWRTZWNyZXQoY29pbk5hbWU6ICdsbmJ0YycgfCAndGxuYnRjJywgeHBydjogc3RyaW5nKTogQnVmZmVyIHtcbiAgY29uc3QgcHVibGljS2V5ID0gQnVmZmVyLmZyb20oZ2V0U3RhdGljc0xpZ2h0bmluZ05ldHdvcmsoY29pbk5hbWUpLnRhdFB1YktleSwgJ2hleCcpO1xuICBjb25zdCB1c2VyQXV0aEhkTm9kZSA9IHV0eG9saWIuYmlwMzIuZnJvbUJhc2U1OCh4cHJ2KTtcbiAgcmV0dXJuIHNka2NvcmUuZ2V0U2hhcmVkU2VjcmV0KHVzZXJBdXRoSGROb2RlLCBwdWJsaWNLZXkpO1xufVxuXG4vKipcbiAqIEdpdmVuIGEgc2VlZCwgY29tcHV0ZSBhIEJJUDMyIGRlcml2YXRpb24gaW5kZXguXG4gKiAwIDw9IGluZGV4IDwgMjE0NzQ4MzY0OCAobGFyZ2VzdCAzMSBiaXQgbnVtYmVyKS4gVGhpcyBuZWVkcyB0byBiZSAyXjMxIC0gMSBzbyB0aGF0IHRoZSBiaXAzMiBsaWJyYXJ5XG4gKiBjYW4gZGVyaXZlIHRoZSBoYXJkZW5lZCBrZXkuXG4gKiBAcGFyYW0gc2VlZCAob3B0aW9uYWwpIElmIG5vdGhpbmcgcHJvdmlkZWQsIHdlIHdpbGwgZ2VuZXJhdGUgb25lIHJhbmRvbWx5XG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBjb21wdXRlQmlwMzJEZXJpdmF0aW9uSW5kZXhGcm9tU2VlZChzZWVkPzogc3RyaW5nKTogbnVtYmVyIHtcbiAgcmV0dXJuIChcbiAgICAoQnVmZmVyLmZyb20odXR4b2xpYi5jcnlwdG8uc2hhMjU2KEJ1ZmZlci5mcm9tKHNlZWQgPz8gcmFuZG9tQnl0ZXMoMzIpLnRvU3RyaW5nKCdoZXgnKSwgJ3V0ZjgnKSkpLnJlYWRVaW50MzJCRSgwKSAlXG4gICAgICBNYXRoLnBvdygyLCAzMSkpIC1cbiAgICAxXG4gICk7XG59XG4iXX0=
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import * as utxolib from '@bitgo-beta/utxo-lib';
|
|
2
|
+
import { Psbt } from '@bitgo-beta/utxo-lib';
|
|
3
|
+
import { WatchOnlyAccount, WithdrawBaseOutputUTXO } from '../codecs';
|
|
4
|
+
import { LightningOnchainRecipient } from '@bitgo/public-types';
|
|
5
|
+
export declare function parsePsbtOutputs(psbt: Psbt, network: utxolib.Network): WithdrawBaseOutputUTXO<bigint>[];
|
|
6
|
+
export declare function verifyChangeAddress(output: WithdrawBaseOutputUTXO<bigint>, accounts: WatchOnlyAccount[], network: utxolib.Network): void;
|
|
7
|
+
/**
|
|
8
|
+
* Validates the funded psbt before creating the signatures for withdraw.
|
|
9
|
+
*/
|
|
10
|
+
export declare function validatePsbtForWithdraw(psbtHex: string, network: utxolib.Network, recipients: LightningOnchainRecipient[], accounts: WatchOnlyAccount[]): void;
|
|
11
|
+
//# sourceMappingURL=parseWithdrawPsbt.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"parseWithdrawPsbt.d.ts","sourceRoot":"","sources":["../../../src/lightning/parseWithdrawPsbt.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,OAAO,MAAM,sBAAsB,CAAC;AAChD,OAAO,EAAa,IAAI,EAAE,MAAM,sBAAsB,CAAC;AACvD,OAAO,EAAE,gBAAgB,EAAE,sBAAsB,EAAE,MAAM,WAAW,CAAC;AACrE,OAAO,EAAE,yBAAyB,EAAE,MAAM,qBAAqB,CAAC;AAyBhE,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,IAAI,EAAE,OAAO,EAAE,OAAO,CAAC,OAAO,GAAG,sBAAsB,CAAC,MAAM,CAAC,EAAE,CA8BvG;AAED,wBAAgB,mBAAmB,CACjC,MAAM,EAAE,sBAAsB,CAAC,MAAM,CAAC,EACtC,QAAQ,EAAE,gBAAgB,EAAE,EAC5B,OAAO,EAAE,OAAO,CAAC,OAAO,GACvB,IAAI,CAiEN;AAED;;GAEG;AACH,wBAAgB,uBAAuB,CACrC,OAAO,EAAE,MAAM,EACf,OAAO,EAAE,OAAO,CAAC,OAAO,EACxB,UAAU,EAAE,yBAAyB,EAAE,EACvC,QAAQ,EAAE,gBAAgB,EAAE,GAC3B,IAAI,CAsBN"}
|
|
@@ -0,0 +1,159 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
+
exports.parsePsbtOutputs = parsePsbtOutputs;
|
|
37
|
+
exports.verifyChangeAddress = verifyChangeAddress;
|
|
38
|
+
exports.validatePsbtForWithdraw = validatePsbtForWithdraw;
|
|
39
|
+
const utxolib = __importStar(require("@bitgo-beta/utxo-lib"));
|
|
40
|
+
const utxo_lib_1 = require("@bitgo-beta/utxo-lib");
|
|
41
|
+
const lightningUtils_1 = require("./lightningUtils");
|
|
42
|
+
function parseDerivationPath(derivationPath) {
|
|
43
|
+
const pathSegments = derivationPath.split('/');
|
|
44
|
+
const purpose = Number(pathSegments[1].replace(/'/g, ''));
|
|
45
|
+
const change = Number(pathSegments[pathSegments.length - 2]);
|
|
46
|
+
const addressIndex = Number(pathSegments[pathSegments.length - 1]);
|
|
47
|
+
if (purpose !== lightningUtils_1.PURPOSE_WRAPPED_P2WKH && purpose !== lightningUtils_1.PURPOSE_P2WKH && purpose !== lightningUtils_1.PURPOSE_P2TR) {
|
|
48
|
+
throw new Error(`Unsupported purpose in derivation path: ${purpose}`);
|
|
49
|
+
}
|
|
50
|
+
return { purpose, change, addressIndex };
|
|
51
|
+
}
|
|
52
|
+
function parsePsbtOutputs(psbt, network) {
|
|
53
|
+
const parsedOutputs = [];
|
|
54
|
+
let bip32Derivation;
|
|
55
|
+
for (let i = 0; i < psbt.data.outputs.length; i++) {
|
|
56
|
+
const output = psbt.data.outputs[i];
|
|
57
|
+
const txOutput = psbt.txOutputs[i];
|
|
58
|
+
let address = '';
|
|
59
|
+
const value = txOutput.value;
|
|
60
|
+
let isChange = false;
|
|
61
|
+
if (output.bip32Derivation && output.bip32Derivation.length > 0) {
|
|
62
|
+
isChange = true;
|
|
63
|
+
bip32Derivation = output.bip32Derivation[0];
|
|
64
|
+
}
|
|
65
|
+
if (txOutput.script) {
|
|
66
|
+
address = utxolib.address.fromOutputScript(txOutput.script, network);
|
|
67
|
+
}
|
|
68
|
+
const valueBigInt = BigInt(value);
|
|
69
|
+
parsedOutputs.push({
|
|
70
|
+
address,
|
|
71
|
+
value: valueBigInt,
|
|
72
|
+
change: isChange,
|
|
73
|
+
bip32Derivation,
|
|
74
|
+
});
|
|
75
|
+
}
|
|
76
|
+
return parsedOutputs;
|
|
77
|
+
}
|
|
78
|
+
function verifyChangeAddress(output, accounts, network) {
|
|
79
|
+
if (!output.bip32Derivation || !output.bip32Derivation.path) {
|
|
80
|
+
throw new Error(`bip32Derivation path not found for change address`);
|
|
81
|
+
}
|
|
82
|
+
// derivation path example: m/84'/0'/0'/1/0
|
|
83
|
+
const { purpose, change, addressIndex } = parseDerivationPath(output.bip32Derivation.path);
|
|
84
|
+
// Find the corresponding account using the purpose
|
|
85
|
+
const account = accounts.find((acc) => acc.purpose === purpose);
|
|
86
|
+
if (!account) {
|
|
87
|
+
throw new Error(`Account not found for purpose: ${purpose}`);
|
|
88
|
+
}
|
|
89
|
+
// convert upub, vpub, etc prefixes to xpub as utxolib doesn't support these
|
|
90
|
+
const convertedXpub = (0, lightningUtils_1.revertXpubPrefix)(account.xpub, purpose, (0, utxo_lib_1.isMainnet)(network));
|
|
91
|
+
// Create a BIP32 node from the xpub
|
|
92
|
+
const xpubNode = utxolib.bip32.fromBase58(convertedXpub, network);
|
|
93
|
+
// Derive the public key from the xpub using the change and address index
|
|
94
|
+
const derivedPubkey = xpubNode.derive(change).derive(addressIndex).publicKey;
|
|
95
|
+
if (derivedPubkey.toString('hex') !== output.bip32Derivation.pubkey.toString('hex')) {
|
|
96
|
+
throw new Error(`Derived pubkey does not match for address: ${output.address}, derived: ${derivedPubkey.toString('hex')}, expected: ${output.bip32Derivation.pubkey.toString('hex')}`);
|
|
97
|
+
}
|
|
98
|
+
// Determine the correct payment type based on the purpose
|
|
99
|
+
let derivedAddress;
|
|
100
|
+
switch (purpose) {
|
|
101
|
+
case 49: // P2SH-P2WPKH (Nested SegWit)
|
|
102
|
+
derivedAddress = utxolib.payments.p2sh({
|
|
103
|
+
redeem: utxolib.payments.p2wpkh({
|
|
104
|
+
pubkey: derivedPubkey,
|
|
105
|
+
network,
|
|
106
|
+
}),
|
|
107
|
+
network,
|
|
108
|
+
}).address;
|
|
109
|
+
break;
|
|
110
|
+
case 84: // P2WPKH (Native SegWit)
|
|
111
|
+
derivedAddress = utxolib.payments.p2wpkh({
|
|
112
|
+
pubkey: derivedPubkey,
|
|
113
|
+
network,
|
|
114
|
+
}).address;
|
|
115
|
+
break;
|
|
116
|
+
case 86: // P2TR (Taproot)
|
|
117
|
+
// P2TR requires x-only pubkey (32 bytes)
|
|
118
|
+
const xOnlyPubkey = derivedPubkey.length === 33 ? derivedPubkey.subarray(1, 33) : derivedPubkey;
|
|
119
|
+
derivedAddress = utxolib.payments.p2tr({
|
|
120
|
+
pubkey: xOnlyPubkey,
|
|
121
|
+
network,
|
|
122
|
+
}, { eccLib: utxolib.ecc }).address;
|
|
123
|
+
break;
|
|
124
|
+
default:
|
|
125
|
+
throw new Error(`Unsupported purpose: ${purpose}`);
|
|
126
|
+
}
|
|
127
|
+
if (derivedAddress !== output.address) {
|
|
128
|
+
throw new Error(`invalid change address: expected ${derivedAddress}, got ${output.address}`);
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
/**
|
|
132
|
+
* Validates the funded psbt before creating the signatures for withdraw.
|
|
133
|
+
*/
|
|
134
|
+
function validatePsbtForWithdraw(psbtHex, network, recipients, accounts) {
|
|
135
|
+
const parsedPsbt = utxo_lib_1.Psbt.fromHex(psbtHex, { network: network });
|
|
136
|
+
const outputs = parsePsbtOutputs(parsedPsbt, network);
|
|
137
|
+
outputs.forEach((output) => {
|
|
138
|
+
if (output.change) {
|
|
139
|
+
try {
|
|
140
|
+
verifyChangeAddress(output, accounts, network);
|
|
141
|
+
}
|
|
142
|
+
catch (e) {
|
|
143
|
+
throw new Error(`Unable to verify change address: ${e}`);
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
else {
|
|
147
|
+
let match = false;
|
|
148
|
+
recipients.forEach((recipient) => {
|
|
149
|
+
if (recipient.address === output.address && BigInt(recipient.amountSat) === output.value) {
|
|
150
|
+
match = true;
|
|
151
|
+
}
|
|
152
|
+
});
|
|
153
|
+
if (!match) {
|
|
154
|
+
throw new Error(`PSBT output ${output.address} with value ${output.value} does not match any recipient`);
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
});
|
|
158
|
+
}
|
|
159
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicGFyc2VXaXRoZHJhd1BzYnQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi9zcmMvbGlnaHRuaW5nL3BhcnNlV2l0aGRyYXdQc2J0LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0FBNEJBLDRDQThCQztBQUVELGtEQXFFQztBQUtELDBEQTJCQztBQWpLRCw4REFBZ0Q7QUFDaEQsbURBQXVEO0FBSXZELHFEQU0wQjtBQUUxQixTQUFTLG1CQUFtQixDQUFDLGNBQXNCO0lBS2pELE1BQU0sWUFBWSxHQUFHLGNBQWMsQ0FBQyxLQUFLLENBQUMsR0FBRyxDQUFDLENBQUM7SUFDL0MsTUFBTSxPQUFPLEdBQUcsTUFBTSxDQUFDLFlBQVksQ0FBQyxDQUFDLENBQUMsQ0FBQyxPQUFPLENBQUMsSUFBSSxFQUFFLEVBQUUsQ0FBQyxDQUFDLENBQUM7SUFDMUQsTUFBTSxNQUFNLEdBQUcsTUFBTSxDQUFDLFlBQVksQ0FBQyxZQUFZLENBQUMsTUFBTSxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUM7SUFDN0QsTUFBTSxZQUFZLEdBQUcsTUFBTSxDQUFDLFlBQVksQ0FBQyxZQUFZLENBQUMsTUFBTSxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUM7SUFDbkUsSUFBSSxPQUFPLEtBQUssc0NBQXFCLElBQUksT0FBTyxLQUFLLDhCQUFhLElBQUksT0FBTyxLQUFLLDZCQUFZLEVBQUUsQ0FBQztRQUMvRixNQUFNLElBQUksS0FBSyxDQUFDLDJDQUEyQyxPQUFPLEVBQUUsQ0FBQyxDQUFDO0lBQ3hFLENBQUM7SUFDRCxPQUFPLEVBQUUsT0FBTyxFQUFFLE1BQU0sRUFBRSxZQUFZLEVBQUUsQ0FBQztBQUMzQyxDQUFDO0FBRUQsU0FBZ0IsZ0JBQWdCLENBQUMsSUFBVSxFQUFFLE9BQXdCO0lBQ25FLE1BQU0sYUFBYSxHQUFxQyxFQUFFLENBQUM7SUFDM0QsSUFBSSxlQUE0QyxDQUFDO0lBRWpELEtB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QkFDWCxNQUFNLElBQUksS0FBSyxDQUFDLGVBQWUsTUFBTSxDQUFDLE9BQU8sZUFBZSxNQUFNLENBQUMsS0FBSywrQkFBK0IsQ0FBQyxDQUFDO1lBQzNHLENBQUM7UUFDSCxDQUFDO0lBQ0gsQ0FBQyxDQUFDLENBQUM7QUFDTCxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0ICogYXMgdXR4b2xpYiBmcm9tICdAYml0Z28tYmV0YS91dHhvLWxpYic7XG5pbXBvcnQgeyBpc01haW5uZXQsIFBzYnQgfSBmcm9tICdAYml0Z28tYmV0YS91dHhvLWxpYic7XG5pbXBvcnQgeyBXYXRjaE9ubHlBY2NvdW50LCBXaXRoZHJhd0Jhc2VPdXRwdXRVVFhPIH0gZnJvbSAnLi4vY29kZWNzJztcbmltcG9ydCB7IExpZ2h0bmluZ09uY2hhaW5SZWNpcGllbnQgfSBmcm9tICdAYml0Z28vcHVibGljLXR5cGVzJztcbmltcG9ydCB7IEJpcDMyRGVyaXZhdGlvbiB9IGZyb20gJ2JpcDE3NC9zcmMvbGliL2ludGVyZmFjZXMnO1xuaW1wb3J0IHtcbiAgRXh0ZW5kZWRLZXlBZGRyZXNzUHVycG9zZSxcbiAgUFVSUE9TRV9QMlRSLFxuICBQVVJQT1NFX1AyV0tILFxuICBQVVJQT1NFX1dSQVBQRURfUDJXS0gsXG4gIHJldmVydFhwdWJQcmVmaXgsXG59IGZyb20gJy4vbGlnaHRuaW5nVXRpbHMnO1xuXG5mdW5jdGlvbiBwYXJzZURlcml2YXRpb25QYXRoKGRlcml2YXRpb25QYXRoOiBzdHJpbmcpOiB7XG4gIHB1cnBvc2U6IEV4dGVuZGVkS2V5QWRkcmVzc1B1cnBvc2U7XG4gIGNoYW5nZTogbnVtYmVyO1xuICBhZGRyZXNzSW5kZXg6IG51bWJlcjtcbn0ge1xuICBjb25zdCBwYXRoU2VnbWVudHMgPSBkZXJpdmF0aW9uUGF0aC5zcGxpdCgnLycpO1xuICBjb25zdCBwdXJwb3NlID0gTnVtYmVyKHBhdGhTZWdtZW50c1sxXS5yZXBsYWNlKC8nL2csICcnKSk7XG4gIGNvbnN0IGNoYW5nZSA9IE51bWJlcihwYXRoU2VnbWVudHNbcGF0aFNlZ21lbnRzLmxlbmd0aCAtIDJdKTtcbiAgY29uc3QgYWRkcmVzc0luZGV4ID0gTnVtYmVyKHBhdGhTZWdtZW50c1twYXRoU2VnbWVudHMubGVuZ3RoIC0gMV0pO1xuICBpZiAocHVycG9zZSAhPT0gUFVSUE9TRV9XUkFQUEVEX1AyV0tIICYmIHB1cnBvc2UgIT09IFBVUlBPU0VfUDJXS0ggJiYgcHVycG9zZSAhPT0gUFVSUE9TRV9QMlRSKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKGBVbnN1cHBvcnRlZCBwdXJwb3NlIGluIGRlcml2YXRpb24gcGF0aDogJHtwdXJwb3NlfWApO1xuICB9XG4gIHJldHVybiB7IHB1cnBvc2UsIGNoYW5nZSwgYWRkcmVzc0luZGV4IH07XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBwYXJzZVBzYnRPdXRwdXRzKHBzYnQ6IFBzYnQsIG5ldHdvcms6IHV0eG9saWIuTmV0d29yayk6IFdpdGhkcmF3QmFzZU91dHB1dFVUWE88YmlnaW50PltdIHtcbiAgY29uc3QgcGFyc2VkT3V0cHV0czogV2l0aGRyYXdCYXNlT3V0cHV0VVRYTzxiaWdpbnQ+W10gPSBbXTtcbiAgbGV0IGJpcDMyRGVyaXZhdGlvbjogQmlwMzJEZXJpdmF0aW9uIHwgdW5kZWZpbmVkO1xuXG4gIGZvciAobGV0IGkgPSAwOyBpIDwgcHNidC5kYXRhLm91dHB1dHMubGVuZ3RoOyBpKyspIHtcbiAgICBjb25zdCBvdXRwdXQgPSBwc2J0LmRhdGEub3V0cHV0c1tpXTtcbiAgICBjb25zdCB0eE91dHB1dCA9IHBzYnQudHhPdXRwdXRzW2ldO1xuXG4gICAgbGV0IGFkZHJlc3MgPSAnJztcbiAgICBjb25zdCB2YWx1ZSA9IHR4T3V0cHV0LnZhbHVlO1xuICAgIGxldCBpc0NoYW5nZSA9IGZhbHNlO1xuXG4gICAgaWYgKG91dHB1dC5iaXAzMkRlcml2YXRpb24gJiYgb3V0cHV0LmJpcDMyRGVyaXZhdGlvbi5sZW5ndGggPiAwKSB7XG4gICAgICBpc0NoYW5nZSA9IHRydWU7XG4gICAgICBiaXAzMkRlcml2YXRpb24gPSBvdXRwdXQuYmlwMzJEZXJpdmF0aW9uWzBdO1xuICAgIH1cbiAgICBpZiAodHhPdXRwdXQuc2NyaXB0KSB7XG4gICAgICBhZGRyZXNzID0gdXR4b2xpYi5hZGRyZXNzLmZyb21PdXRwdXRTY3JpcHQodHhPdXRwdXQuc2NyaXB0LCBuZXR3b3JrKTtcbiAgICB9XG4gICAgY29uc3QgdmFsdWVCaWdJbnQgPSBCaWdJbnQodmFsdWUpO1xuXG4gICAgcGFyc2VkT3V0cHV0cy5wdXNoKHtcbiAgICAgIGFkZHJlc3MsXG4gICAgICB2YWx1ZTogdmFsdWVCaWdJbnQsXG4gICAgICBjaGFuZ2U6IGlzQ2hhbmdlLFxuICAgICAgYmlwMzJEZXJpdmF0aW9uLFxuICAgIH0pO1xuICB9XG5cbiAgcmV0dXJuIHBhcnNlZE91dHB1dHM7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiB2ZXJpZnlDaGFuZ2VBZGRyZXNzKFxuICBvdXRwdXQ6IFdpdGhkcmF3QmFzZU91dHB1dFVUWE88YmlnaW50PixcbiAgYWNjb3VudHM6IFdhdGNoT25seUFjY291bnRbXSxcbiAgbmV0d29yazogdXR4b2xpYi5OZXR3b3JrXG4pOiB2b2lkIHtcbiAgaWYgKCFvdXRwdXQuYmlwMzJEZXJpdmF0aW9uIHx8ICFvdXRwdXQuYmlwMzJEZXJpdmF0aW9uLnBhdGgpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoYGJpcDMyRGVyaXZhdGlvbiBwYXRoIG5vdCBmb3VuZCBmb3IgY2hhbmdlIGFkZHJlc3NgKTtcbiAgfVxuICAvLyBkZXJpdmF0aW9uIHBhdGggZXhhbXBsZTogbS84NCcvMCcvMCcvMS8wXG4gIGNvbnN0IHsgcHVycG9zZSwgY2hhbmdlLCBhZGRyZXNzSW5kZXggfSA9IHBhcnNlRGVyaXZhdGlvblBhdGgob3V0cHV0LmJpcDMyRGVyaXZhdGlvbi5wYXRoKTtcblxuICAvLyBGaW5kIHRoZSBjb3JyZXNwb25kaW5nIGFjY291bnQgdXNpbmcgdGhlIHB1cnBvc2VcbiAgY29uc3QgYWNjb3VudCA9IGFjY291bnRzLmZpbmQoKGFjYykgPT4gYWNjLnB1cnBvc2UgPT09IHB1cnBvc2UpO1xuICBpZiAoIWFjY291bnQpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoYEFjY291bnQgbm90IGZvdW5kIGZvciBwdXJwb3NlOiAke3B1cnBvc2V9YCk7XG4gIH1cblxuICAvLyBjb252ZXJ0IHVwdWIsIHZwdWIsIGV0YyBwcmVmaXhlcyB0byB4cHViIGFzIHV0eG9saWIgZG9lc24ndCBzdXBwb3J0IHRoZXNlXG4gIGNvbnN0IGNvbnZlcnRlZFhwdWIgPSByZXZlcnRYcHViUHJlZml4KGFjY291bnQueHB1YiwgcHVycG9zZSwgaXNNYWlubmV0KG5ldHdvcmspKTtcbiAgLy8gQ3JlYXRlIGEgQklQMzIgbm9kZSBmcm9tIHRoZSB4cHViXG4gIGNvbnN0IHhwdWJOb2RlID0gdXR4b2xpYi5iaXAzMi5mcm9tQmFzZTU4KGNvbnZlcnRlZFhwdWIsIG5ldHdvcmspO1xuXG4gIC8vIERlcml2ZSB0aGUgcHVibGljIGtleSBmcm9tIHRoZSB4cHViIHVzaW5nIHRoZSBjaGFuZ2UgYW5kIGFkZHJlc3MgaW5kZXhcbiAgY29uc3QgZGVyaXZlZFB1YmtleSA9IHhwdWJOb2RlLmRlcml2ZShjaGFuZ2UpLmRlcml2ZShhZGRyZXNzSW5kZXgpLnB1YmxpY0tleTtcblxuICBpZiAoZGVyaXZlZFB1YmtleS50b1N0cmluZygnaGV4JykgIT09IG91dHB1dC5iaXAzMkRlcml2YXRpb24ucHVia2V5LnRvU3RyaW5nKCdoZXgnKSkge1xuICAgIHRocm93IG5ldyBFcnJvcihcbiAgICAgIGBEZXJpdmVkIHB1YmtleSBkb2VzIG5vdCBtYXRjaCBmb3IgYWRkcmVzczogJHtvdXRwdXQuYWRkcmVzc30sIGRlcml2ZWQ6ICR7ZGVyaXZlZFB1YmtleS50b1N0cmluZyhcbiAgICAgICAgJ2hleCdcbiAgICAgICl9LCBleHBlY3RlZDogJHtvdXRwdXQuYmlwMzJEZXJpdmF0aW9uLnB1YmtleS50b1N0cmluZygnaGV4Jyl9YFxuICAgICk7XG4gIH1cblxuICAvLyBEZXRlcm1pbmUgdGhlIGNvcnJlY3QgcGF5bWVudCB0eXBlIGJhc2VkIG9uIHRoZSBwdXJwb3NlXG4gIGxldCBkZXJpdmVkQWRkcmVzczogc3RyaW5nIHwgdW5kZWZpbmVkO1xuICBzd2l0Y2ggKHB1cnBvc2UpIHtcbiAgICBjYXNlIDQ5OiAvLyBQMlNILVAyV1BLSCAoTmVzdGVkIFNlZ1dpdClcbiAgICAgIGRlcml2ZWRBZGRyZXNzID0gdXR4b2xpYi5wYXltZW50cy5wMnNoKHtcbiAgICAgICAgcmVkZWVtOiB1dHhvbGliLnBheW1lbnRzLnAyd3BraCh7XG4gICAgICAgICAgcHVia2V5OiBkZXJpdmVkUHVia2V5LFxuICAgICAgICAgIG5ldHdvcmssXG4gICAgICAgIH0pLFxuICAgICAgICBuZXR3b3JrLFxuICAgICAgfSkuYWRkcmVzcztcbiAgICAgIGJyZWFrO1xuICAgIGNhc2UgODQ6IC8vIFAyV1BLSCAoTmF0aXZlIFNlZ1dpdClcbiAgICAgIGRlcml2ZWRBZGRyZXNzID0gdXR4b2xpYi5wYXltZW50cy5wMndwa2goe1xuICAgICAgICBwdWJrZXk6IGRlcml2ZWRQdWJrZXksXG4gICAgICAgIG5ldHdvcmssXG4gICAgICB9KS5hZGRyZXNzO1xuICAgICAgYnJlYWs7XG4gICAgY2FzZSA4NjogLy8gUDJUUiAoVGFwcm9vdClcbiAgICAgIC8vIFAyVFIgcmVxdWlyZXMgeC1vbmx5IHB1YmtleSAoMzIgYnl0ZXMpXG4gICAgICBjb25zdCB4T25seVB1YmtleSA9IGRlcml2ZWRQdWJrZXkubGVuZ3RoID09PSAzMyA/IGRlcml2ZWRQdWJrZXkuc3ViYXJyYXkoMSwgMzMpIDogZGVyaXZlZFB1YmtleTtcbiAgICAgIGRlcml2ZWRBZGRyZXNzID0gdXR4b2xpYi5wYXltZW50cy5wMnRyKFxuICAgICAgICB7XG4gICAgICAgICAgcHVia2V5OiB4T25seVB1YmtleSxcbiAgICAgICAgICBuZXR3b3JrLFxuICAgICAgICB9LFxuICAgICAgICB7IGVjY0xpYjogdXR4b2xpYi5lY2MgfVxuICAgICAgKS5hZGRyZXNzO1xuICAgICAgYnJlYWs7XG4gICAgZGVmYXVsdDpcbiAgICAgIHRocm93IG5ldyBFcnJvcihgVW5zdXBwb3J0ZWQgcHVycG9zZTogJHtwdXJwb3NlfWApO1xuICB9XG5cbiAgaWYgKGRlcml2ZWRBZGRyZXNzICE9PSBvdXRwdXQuYWRkcmVzcykge1xuICAgIHRocm93IG5ldyBFcnJvcihgaW52YWxpZCBjaGFuZ2UgYWRkcmVzczogZXhwZWN0ZWQgJHtkZXJpdmVkQWRkcmVzc30sIGdvdCAke291dHB1dC5hZGRyZXNzfWApO1xuICB9XG59XG5cbi8qKlxuICogVmFsaWRhdGVzIHRoZSBmdW5kZWQgcHNidCBiZWZvcmUgY3JlYXRpbmcgdGhlIHNpZ25hdHVyZXMgZm9yIHdpdGhkcmF3LlxuICovXG5leHBvcnQgZnVuY3Rpb24gdmFsaWRhdGVQc2J0Rm9yV2l0aGRyYXcoXG4gIHBzYnRIZXg6IHN0cmluZyxcbiAgbmV0d29yazogdXR4b2xpYi5OZXR3b3JrLFxuICByZWNpcGllbnRzOiBMaWdodG5pbmdPbmNoYWluUmVjaXBpZW50W10sXG4gIGFjY291bnRzOiBXYXRjaE9ubHlBY2NvdW50W11cbik6IHZvaWQge1xuICBjb25zdCBwYXJzZWRQc2J0ID0gUHNidC5mcm9tSGV4KHBzYnRIZXgsIHsgbmV0d29yazogbmV0d29yayB9KTtcbiAgY29uc3Qgb3V0cHV0cyA9IHBhcnNlUHNidE91dHB1dHMocGFyc2VkUHNidCwgbmV0d29yayk7XG4gIG91dHB1dHMuZm9yRWFjaCgob3V0cHV0KSA9PiB7XG4gICAgaWYgKG91dHB1dC5jaGFuZ2UpIHtcbiAgICAgIHRyeSB7XG4gICAgICAgIHZlcmlmeUNoYW5nZUFkZHJlc3Mob3V0cHV0LCBhY2NvdW50cywgbmV0d29yayk7XG4gICAgICB9IGNhdGNoIChlOiBhbnkpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBVbmFibGUgdG8gdmVyaWZ5IGNoYW5nZSBhZGRyZXNzOiAke2V9YCk7XG4gICAgICB9XG4gICAgfSBlbHNlIHtcbiAgICAgIGxldCBtYXRjaCA9IGZhbHNlO1xuICAgICAgcmVjaXBpZW50cy5mb3JFYWNoKChyZWNpcGllbnQpID0+IHtcbiAgICAgICAgaWYgKHJlY2lwaWVudC5hZGRyZXNzID09PSBvdXRwdXQuYWRkcmVzcyAmJiBCaWdJbnQocmVjaXBpZW50LmFtb3VudFNhdCkgPT09IG91dHB1dC52YWx1ZSkge1xuICAgICAgICAgIG1hdGNoID0gdHJ1ZTtcbiAgICAgICAgfVxuICAgICAgfSk7XG4gICAgICBpZiAoIW1hdGNoKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihgUFNCVCBvdXRwdXQgJHtvdXRwdXQuYWRkcmVzc30gd2l0aCB2YWx1ZSAke291dHB1dC52YWx1ZX0gZG9lcyBub3QgbWF0Y2ggYW55IHJlY2lwaWVudGApO1xuICAgICAgfVxuICAgIH1cbiAgfSk7XG59XG4iXX0=
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
export type Signable = boolean | number | string | SignableRecord | SignableArray;
|
|
2
|
+
export interface SignableRecord {
|
|
3
|
+
[key: string]: Signable;
|
|
4
|
+
}
|
|
5
|
+
export interface SignableArray {
|
|
6
|
+
[key: number]: Signable;
|
|
7
|
+
}
|
|
8
|
+
/**
|
|
9
|
+
* Recursively canonicalizes an object by sorting its keys.
|
|
10
|
+
*
|
|
11
|
+
* @param obj - The object to be canonicalized. It can be a boolean, number, string,
|
|
12
|
+
* a record of signable values, or an array of signable values.
|
|
13
|
+
* @returns The canonicalized object with sorted keys.
|
|
14
|
+
* @throws Will throw an error if the object type is invalid.
|
|
15
|
+
*/
|
|
16
|
+
export declare function canonicalizeObject(obj: Signable): Signable;
|
|
17
|
+
//# sourceMappingURL=signableJson.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"signableJson.d.ts","sourceRoot":"","sources":["../../../src/lightning/signableJson.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,QAAQ,GAAG,OAAO,GAAG,MAAM,GAAG,MAAM,GAAG,cAAc,GAAG,aAAa,CAAC;AAElF,MAAM,WAAW,cAAc;IAC7B,CAAC,GAAG,EAAE,MAAM,GAAG,QAAQ,CAAC;CACzB;AAED,MAAM,WAAW,aAAa;IAC5B,CAAC,GAAG,EAAE,MAAM,GAAG,QAAQ,CAAC;CACzB;AAED;;;;;;;GAOG;AACH,wBAAgB,kBAAkB,CAAC,GAAG,EAAE,QAAQ,GAAG,QAAQ,CAmB1D"}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.canonicalizeObject = canonicalizeObject;
|
|
4
|
+
/**
|
|
5
|
+
* Recursively canonicalizes an object by sorting its keys.
|
|
6
|
+
*
|
|
7
|
+
* @param obj - The object to be canonicalized. It can be a boolean, number, string,
|
|
8
|
+
* a record of signable values, or an array of signable values.
|
|
9
|
+
* @returns The canonicalized object with sorted keys.
|
|
10
|
+
* @throws Will throw an error if the object type is invalid.
|
|
11
|
+
*/
|
|
12
|
+
function canonicalizeObject(obj) {
|
|
13
|
+
if (typeof obj === 'boolean' || typeof obj === 'number' || typeof obj === 'string') {
|
|
14
|
+
return obj;
|
|
15
|
+
}
|
|
16
|
+
if (Array.isArray(obj)) {
|
|
17
|
+
return obj.map(canonicalizeObject);
|
|
18
|
+
}
|
|
19
|
+
if (obj !== null && typeof obj === 'object') {
|
|
20
|
+
return Object.keys(obj)
|
|
21
|
+
.sort()
|
|
22
|
+
.reduce((result, key) => {
|
|
23
|
+
result[key] = canonicalizeObject(obj[key]);
|
|
24
|
+
return result;
|
|
25
|
+
}, {});
|
|
26
|
+
}
|
|
27
|
+
throw new Error('Invalid object type');
|
|
28
|
+
}
|
|
29
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic2lnbmFibGVKc29uLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vc3JjL2xpZ2h0bmluZy9zaWduYWJsZUpzb24udHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7QUFrQkEsZ0RBbUJDO0FBM0JEOzs7Ozs7O0dBT0c7QUFDSCxTQUFnQixrQkFBa0IsQ0FBQyxHQUFhO0lBQzlDLElBQUksT0FBTyxHQUFHLEtBQUssU0FBUyxJQUFJLE9BQU8sR0FBRyxLQUFLLFFBQVEsSUFBSSxPQUFPLEdBQUcsS0FBSyxRQUFRLEVBQUUsQ0FBQztRQUNuRixPQUFPLEdBQUcsQ0FBQztJQUNiLENBQUM7SUFFRCxJQUFJLEtBQUssQ0FBQyxPQUFPLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQztRQUN2QixPQUFPLEdBQUcsQ0FBQyxHQUFHLENBQUMsa0JBQWtCLENBQUMsQ0FBQztJQUNyQyxDQUFDO0lBRUQsSUFBSSxHQUFHLEtBQUssSUFBSSxJQUFJLE9BQU8sR0FBRyxLQUFLLFFBQVEsRUFBRSxDQUFDO1FBQzVDLE9BQU8sTUFBTSxDQUFDLElBQUksQ0FBQyxHQUFHLENBQUM7YUFDcEIsSUFBSSxFQUFFO2FBQ04sTUFBTSxDQUFDLENBQUMsTUFBZ0MsRUFBRSxHQUFHLEVBQUUsRUFBRTtZQUNoRCxNQUFNLENBQUMsR0FBRyxDQUFDLEdBQUcsa0JBQWtCLENBQUUsR0FBbUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDO1lBQzVFLE9BQU8sTUFBTSxDQUFDO1FBQ2hCLENBQUMsRUFBRSxFQUFFLENBQUMsQ0FBQztJQUNYLENBQUM7SUFFRCxNQUFNLElBQUksS0FBSyxDQUFDLHFCQUFxQixDQUFDLENBQUM7QUFDekMsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbImV4cG9ydCB0eXBlIFNpZ25hYmxlID0gYm9vbGVhbiB8IG51bWJlciB8IHN0cmluZyB8IFNpZ25hYmxlUmVjb3JkIHwgU2lnbmFibGVBcnJheTtcblxuZXhwb3J0IGludGVyZmFjZSBTaWduYWJsZVJlY29yZCB7XG4gIFtrZXk6IHN0cmluZ106IFNpZ25hYmxlO1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIFNpZ25hYmxlQXJyYXkge1xuICBba2V5OiBudW1iZXJdOiBTaWduYWJsZTtcbn1cblxuLyoqXG4gKiBSZWN1cnNpdmVseSBjYW5vbmljYWxpemVzIGFuIG9iamVjdCBieSBzb3J0aW5nIGl0cyBrZXlzLlxuICpcbiAqIEBwYXJhbSBvYmogLSBUaGUgb2JqZWN0IHRvIGJlIGNhbm9uaWNhbGl6ZWQuIEl0IGNhbiBiZSBhIGJvb2xlYW4sIG51bWJlciwgc3RyaW5nLFxuICogICAgICAgICAgICAgIGEgcmVjb3JkIG9mIHNpZ25hYmxlIHZhbHVlcywgb3IgYW4gYXJyYXkgb2Ygc2lnbmFibGUgdmFsdWVzLlxuICogQHJldHVybnMgVGhlIGNhbm9uaWNhbGl6ZWQgb2JqZWN0IHdpdGggc29ydGVkIGtleXMuXG4gKiBAdGhyb3dzIFdpbGwgdGhyb3cgYW4gZXJyb3IgaWYgdGhlIG9iamVjdCB0eXBlIGlzIGludmFsaWQuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBjYW5vbmljYWxpemVPYmplY3Qob2JqOiBTaWduYWJsZSk6IFNpZ25hYmxlIHtcbiAgaWYgKHR5cGVvZiBvYmogPT09ICdib29sZWFuJyB8fCB0eXBlb2Ygb2JqID09PSAnbnVtYmVyJyB8fCB0eXBlb2Ygb2JqID09PSAnc3RyaW5nJykge1xuICAgIHJldHVybiBvYmo7XG4gIH1cblxuICBpZiAoQXJyYXkuaXNBcnJheShvYmopKSB7XG4gICAgcmV0dXJuIG9iai5tYXAoY2Fub25pY2FsaXplT2JqZWN0KTtcbiAgfVxuXG4gIGlmIChvYmogIT09IG51bGwgJiYgdHlwZW9mIG9iaiA9PT0gJ29iamVjdCcpIHtcbiAgICByZXR1cm4gT2JqZWN0LmtleXMob2JqKVxuICAgICAgLnNvcnQoKVxuICAgICAgLnJlZHVjZSgocmVzdWx0OiBSZWNvcmQ8c3RyaW5nLCBTaWduYWJsZT4sIGtleSkgPT4ge1xuICAgICAgICByZXN1bHRba2V5XSA9IGNhbm9uaWNhbGl6ZU9iamVjdCgob2JqIGFzIHsgW2tleTogc3RyaW5nXTogU2lnbmFibGUgfSlba2V5XSk7XG4gICAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgICB9LCB7fSk7XG4gIH1cblxuICB0aHJvdyBuZXcgRXJyb3IoJ0ludmFsaWQgb2JqZWN0IHR5cGUnKTtcbn1cbiJdfQ==
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import * as utxolib from '@bitgo-beta/utxo-lib';
|
|
2
|
+
import { Signable } from './signableJson';
|
|
3
|
+
/**
|
|
4
|
+
* Verifies a signature for a given message.
|
|
5
|
+
*
|
|
6
|
+
* @param {Signable} message - The message to verify.
|
|
7
|
+
* @param {string} signature - The signature to verify, in hexadecimal format.
|
|
8
|
+
* @param {string} pub - The public key in BIP32 format.
|
|
9
|
+
* @param {utxolib.Network} network - The network to use for verification.
|
|
10
|
+
* @returns {boolean} - Returns true if the signature is valid, false otherwise.
|
|
11
|
+
*/
|
|
12
|
+
export declare function verifyMessageSignature(message: Signable, signature: string, pub: string, network?: utxolib.Network): boolean;
|
|
13
|
+
/**
|
|
14
|
+
* Creates a signature for a given message.
|
|
15
|
+
*
|
|
16
|
+
* @param {Signable} message - The message to sign.
|
|
17
|
+
* @param {string} prv - The private key in BIP32 format.
|
|
18
|
+
* @param {utxolib.Network} network - The network to use for signing.
|
|
19
|
+
* @returns {string} - Returns the signature in hexadecimal format.
|
|
20
|
+
*/
|
|
21
|
+
export declare function createMessageSignature(message: Signable, xprv: string, network?: utxolib.Network): string;
|
|
22
|
+
//# sourceMappingURL=signature.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"signature.d.ts","sourceRoot":"","sources":["../../../src/lightning/signature.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,OAAO,MAAM,sBAAsB,CAAC;AAEhD,OAAO,EAAsB,QAAQ,EAAE,MAAM,gBAAgB,CAAC;AAE9D;;;;;;;;GAQG;AACH,wBAAgB,sBAAsB,CACpC,OAAO,EAAE,QAAQ,EACjB,SAAS,EAAE,MAAM,EACjB,GAAG,EAAE,MAAM,EACX,OAAO,GAAE,OAAO,CAAC,OAAkC,GAClD,OAAO,CAKT;AAED;;;;;;;GAOG;AACH,wBAAgB,sBAAsB,CACpC,OAAO,EAAE,QAAQ,EACjB,IAAI,EAAE,MAAM,EACZ,OAAO,GAAE,OAAO,CAAC,OAAkC,GAClD,MAAM,CAIR"}
|