@arkade-os/sdk 0.5.0-rc.2 → 0.5.0-rc.21
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 +90 -83
- package/dist/adapters/expo.cjs +5 -6
- package/dist/adapters/expo.d.cts +4 -4
- package/dist/adapters/expo.d.ts +4 -4
- package/dist/adapters/expo.js +3 -4
- package/dist/{asyncStorageTaskQueue-C5rBYlru.d.ts → asyncStorageTaskQueue-aL7K14e4.d.ts} +2 -2
- package/dist/{asyncStorageTaskQueue-BuDvgWh6.d.cts → asyncStorageTaskQueue-x8ok3tJy.d.cts} +2 -2
- package/dist/{chunk-ISO4TI5J.js → chunk-4FDNOLBO.js} +566 -459
- package/dist/chunk-4FDNOLBO.js.map +1 -0
- package/dist/{chunk-JZWLXNHV.cjs → chunk-5XBH5SAL.cjs} +574 -464
- package/dist/chunk-5XBH5SAL.cjs.map +1 -0
- package/dist/{chunk-3R476TDV.js → chunk-CXHJGED6.js} +293 -1071
- package/dist/chunk-CXHJGED6.js.map +1 -0
- package/dist/{chunk-ZRNQV6HV.js → chunk-EXFU6MTA.js} +4578 -4396
- package/dist/chunk-EXFU6MTA.js.map +1 -0
- package/dist/{chunk-43FKNLX4.cjs → chunk-GVF4OCTL.cjs} +357 -1114
- package/dist/chunk-GVF4OCTL.cjs.map +1 -0
- package/dist/{chunk-HLCGYOIH.cjs → chunk-HIZNPHB2.cjs} +37 -36
- package/dist/chunk-HIZNPHB2.cjs.map +1 -0
- package/dist/{chunk-4PKLULWT.js → chunk-JZAEFOE4.js} +109 -246
- package/dist/chunk-JZAEFOE4.js.map +1 -0
- package/dist/{chunk-ZOTXDOS5.js → chunk-LNJPVLIC.js} +30 -29
- package/dist/chunk-LNJPVLIC.js.map +1 -0
- package/dist/{chunk-NVZJSKZS.cjs → chunk-Q7PC3NHX.cjs} +121 -257
- package/dist/chunk-Q7PC3NHX.cjs.map +1 -0
- package/dist/{chunk-GMZZQXV5.cjs → chunk-R5OFJ23O.cjs} +4961 -4767
- package/dist/chunk-R5OFJ23O.cjs.map +1 -0
- package/dist/{chunk-6DNR46C7.js → chunk-S2WWOVFC.js} +7 -5
- package/dist/chunk-S2WWOVFC.js.map +1 -0
- package/dist/{chunk-D25O4EGY.cjs → chunk-VZMLADXQ.cjs} +12 -10
- package/dist/chunk-VZMLADXQ.cjs.map +1 -0
- package/dist/contracts/handlers/index.cjs +9 -10
- package/dist/contracts/handlers/index.d.cts +5 -5
- package/dist/contracts/handlers/index.d.ts +5 -5
- package/dist/contracts/handlers/index.js +2 -3
- package/dist/{delegate-BAX5QftB.d.ts → delegate-BT5iON1T.d.ts} +1 -1
- package/dist/{delegate-1yp1HyP7.d.cts → delegate-u6kXTtWY.d.cts} +1 -1
- package/dist/index-BCnhItOQ.d.cts +639 -0
- package/dist/{index-DUxufw76.d.cts → index-CK5QbTmZ.d.cts} +1387 -2404
- package/dist/{index-DUxufw76.d.ts → index-CK5QbTmZ.d.ts} +1387 -2404
- package/dist/index-D1D4cR-G.d.ts +639 -0
- package/dist/index.cjs +375 -340
- package/dist/index.d.cts +784 -1197
- package/dist/index.d.ts +784 -1197
- package/dist/index.js +4 -5
- package/dist/repositories/realm/index.cjs +201 -106
- package/dist/repositories/realm/index.cjs.map +1 -1
- package/dist/repositories/realm/index.d.cts +28 -16
- package/dist/repositories/realm/index.d.ts +28 -16
- package/dist/repositories/realm/index.js +190 -95
- package/dist/repositories/realm/index.js.map +1 -1
- package/dist/repositories/sqlite/index.cjs +301 -189
- package/dist/repositories/sqlite/index.cjs.map +1 -1
- package/dist/repositories/sqlite/index.d.cts +32 -21
- package/dist/repositories/sqlite/index.d.ts +32 -21
- package/dist/repositories/sqlite/index.js +294 -182
- package/dist/repositories/sqlite/index.js.map +1 -1
- package/dist/{taskRunner-D_iPiZIi.d.ts → taskRunner-BeYR6NpQ.d.ts} +2 -2
- package/dist/{taskRunner-Dr3NStc0.d.cts → taskRunner-Csey3EYJ.d.cts} +2 -2
- package/dist/wallet/expo/background.cjs +14 -15
- package/dist/wallet/expo/background.cjs.map +1 -1
- package/dist/wallet/expo/background.d.cts +10 -16
- package/dist/wallet/expo/background.d.ts +10 -16
- package/dist/wallet/expo/background.js +6 -7
- package/dist/wallet/expo/background.js.map +1 -1
- package/dist/wallet/expo/index.cjs +16 -23
- package/dist/wallet/expo/index.cjs.map +1 -1
- package/dist/wallet/expo/index.d.cts +6 -9
- package/dist/wallet/expo/index.d.ts +6 -9
- package/dist/wallet/expo/index.js +8 -15
- package/dist/wallet/expo/index.js.map +1 -1
- package/dist/wallet-DG3Qmbmt.d.cts +1848 -0
- package/dist/wallet-DzSLMxBZ.d.ts +1848 -0
- package/dist/worker/expo/index.cjs +9 -10
- package/dist/worker/expo/index.cjs.map +1 -1
- package/dist/worker/expo/index.d.cts +6 -6
- package/dist/worker/expo/index.d.ts +6 -6
- package/dist/worker/expo/index.js +5 -6
- package/dist/worker/expo/index.js.map +1 -1
- package/package.json +12 -51
- package/dist/adapters/asyncStorage.cjs +0 -48
- package/dist/adapters/asyncStorage.cjs.map +0 -1
- package/dist/adapters/asyncStorage.d.cts +0 -16
- package/dist/adapters/asyncStorage.d.ts +0 -16
- package/dist/adapters/asyncStorage.js +0 -46
- package/dist/adapters/asyncStorage.js.map +0 -1
- package/dist/adapters/fileSystem.cjs +0 -116
- package/dist/adapters/fileSystem.cjs.map +0 -1
- package/dist/adapters/fileSystem.d.cts +0 -17
- package/dist/adapters/fileSystem.d.ts +0 -17
- package/dist/adapters/fileSystem.js +0 -93
- package/dist/adapters/fileSystem.js.map +0 -1
- package/dist/adapters/indexedDB.cjs +0 -103
- package/dist/adapters/indexedDB.cjs.map +0 -1
- package/dist/adapters/indexedDB.d.cts +0 -18
- package/dist/adapters/indexedDB.d.ts +0 -18
- package/dist/adapters/indexedDB.js +0 -101
- package/dist/adapters/indexedDB.js.map +0 -1
- package/dist/adapters/localStorage.cjs +0 -50
- package/dist/adapters/localStorage.cjs.map +0 -1
- package/dist/adapters/localStorage.d.cts +0 -14
- package/dist/adapters/localStorage.d.ts +0 -14
- package/dist/adapters/localStorage.js +0 -48
- package/dist/adapters/localStorage.js.map +0 -1
- package/dist/chunk-3R476TDV.js.map +0 -1
- package/dist/chunk-43FKNLX4.cjs.map +0 -1
- package/dist/chunk-4PKLULWT.js.map +0 -1
- package/dist/chunk-5BLDMQED.cjs +0 -18
- package/dist/chunk-5BLDMQED.cjs.map +0 -1
- package/dist/chunk-6DNR46C7.js.map +0 -1
- package/dist/chunk-D25O4EGY.cjs.map +0 -1
- package/dist/chunk-GMZZQXV5.cjs.map +0 -1
- package/dist/chunk-HLCGYOIH.cjs.map +0 -1
- package/dist/chunk-ISO4TI5J.js.map +0 -1
- package/dist/chunk-JZWLXNHV.cjs.map +0 -1
- package/dist/chunk-NSBPE2FW.js +0 -15
- package/dist/chunk-NSBPE2FW.js.map +0 -1
- package/dist/chunk-NVZJSKZS.cjs.map +0 -1
- package/dist/chunk-ZOTXDOS5.js.map +0 -1
- package/dist/chunk-ZRNQV6HV.js.map +0 -1
- package/dist/hdWalletCapable-CmEU0NP1.d.ts +0 -2232
- package/dist/hdWalletCapable-eJgaT-ec.d.cts +0 -2232
- package/dist/index-Bem5vKzX.d.ts +0 -850
- package/dist/index-C0IanN1m.d.cts +0 -11
- package/dist/index-C0IanN1m.d.ts +0 -11
- package/dist/index-W_oMcOmG.d.cts +0 -850
|
@@ -1,44 +1,47 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
var
|
|
4
|
-
var chunk5BLDMQED_cjs = require('./chunk-5BLDMQED.cjs');
|
|
3
|
+
var chunk5XBH5SAL_cjs = require('./chunk-5XBH5SAL.cjs');
|
|
5
4
|
var base = require('@scure/base');
|
|
6
5
|
var descriptorsScure = require('@bitcoinerlab/descriptors-scure');
|
|
7
6
|
var btcSigner = require('@scure/btc-signer');
|
|
7
|
+
var P = require('micro-packed');
|
|
8
8
|
var secp256k1_js = require('@noble/curves/secp256k1.js');
|
|
9
9
|
var utils_js = require('@noble/curves/utils.js');
|
|
10
10
|
|
|
11
|
+
function _interopNamespace(e) {
|
|
12
|
+
if (e && e.__esModule) return e;
|
|
13
|
+
var n = Object.create(null);
|
|
14
|
+
if (e) {
|
|
15
|
+
Object.keys(e).forEach(function (k) {
|
|
16
|
+
if (k !== 'default') {
|
|
17
|
+
var d = Object.getOwnPropertyDescriptor(e, k);
|
|
18
|
+
Object.defineProperty(n, k, d.get ? d : {
|
|
19
|
+
enumerable: true,
|
|
20
|
+
get: function () { return e[k]; }
|
|
21
|
+
});
|
|
22
|
+
}
|
|
23
|
+
});
|
|
24
|
+
}
|
|
25
|
+
n.default = e;
|
|
26
|
+
return Object.freeze(n);
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
var P__namespace = /*#__PURE__*/_interopNamespace(P);
|
|
30
|
+
|
|
11
31
|
// src/contracts/handlers/registry.ts
|
|
12
32
|
var ContractHandlerRegistry = class {
|
|
13
33
|
handlers = /* @__PURE__ */ new Map();
|
|
14
|
-
/**
|
|
15
|
-
* Register a contract handler.
|
|
16
|
-
*
|
|
17
|
-
* @param handler - The handler to register
|
|
18
|
-
* @throws If a handler for this type is already registered
|
|
19
|
-
*/
|
|
34
|
+
/** @throws If a handler for this type is already registered */
|
|
20
35
|
register(handler) {
|
|
21
36
|
if (this.handlers.has(handler.type)) {
|
|
22
37
|
throw new Error(`Contract handler for type '${handler.type}' is already registered`);
|
|
23
38
|
}
|
|
24
39
|
this.handlers.set(handler.type, handler);
|
|
25
40
|
}
|
|
26
|
-
/**
|
|
27
|
-
* Get a handler by type.
|
|
28
|
-
*
|
|
29
|
-
* @param type - The contract type
|
|
30
|
-
* @returns The handler, or undefined if not found
|
|
31
|
-
*/
|
|
32
41
|
get(type) {
|
|
33
42
|
return this.handlers.get(type);
|
|
34
43
|
}
|
|
35
|
-
/**
|
|
36
|
-
* Get a handler by type, throwing if not found.
|
|
37
|
-
*
|
|
38
|
-
* @param type - The contract type
|
|
39
|
-
* @returns The handler
|
|
40
|
-
* @throws If no handler is registered for this type
|
|
41
|
-
*/
|
|
44
|
+
/** @throws If no handler is registered for this type */
|
|
42
45
|
getOrThrow(type) {
|
|
43
46
|
const handler = this.get(type);
|
|
44
47
|
if (!handler) {
|
|
@@ -46,29 +49,17 @@ var ContractHandlerRegistry = class {
|
|
|
46
49
|
}
|
|
47
50
|
return handler;
|
|
48
51
|
}
|
|
49
|
-
/**
|
|
50
|
-
* Check if a handler is registered.
|
|
51
|
-
*
|
|
52
|
-
* @param type - The contract type
|
|
53
|
-
*/
|
|
54
52
|
has(type) {
|
|
55
53
|
return this.handlers.has(type);
|
|
56
54
|
}
|
|
57
|
-
/**
|
|
58
|
-
* Get all registered types.
|
|
59
|
-
*/
|
|
60
55
|
getRegisteredTypes() {
|
|
61
56
|
return Array.from(this.handlers.keys());
|
|
62
57
|
}
|
|
63
|
-
/**
|
|
64
|
-
* Unregister a handler (mainly for testing).
|
|
65
|
-
*/
|
|
58
|
+
/** Unregister a handler (mainly for testing). */
|
|
66
59
|
unregister(type) {
|
|
67
60
|
return this.handlers.delete(type);
|
|
68
61
|
}
|
|
69
|
-
/**
|
|
70
|
-
* Clear all handlers (mainly for testing).
|
|
71
|
-
*/
|
|
62
|
+
/** Clear all handlers (mainly for testing). */
|
|
72
63
|
clear() {
|
|
73
64
|
this.handlers.clear();
|
|
74
65
|
}
|
|
@@ -76,14 +67,14 @@ var ContractHandlerRegistry = class {
|
|
|
76
67
|
var contractHandlers = new ContractHandlerRegistry();
|
|
77
68
|
exports.DefaultVtxo = void 0;
|
|
78
69
|
((DefaultVtxo2) => {
|
|
79
|
-
class Script3 extends
|
|
70
|
+
class Script3 extends chunk5XBH5SAL_cjs.VtxoScript {
|
|
80
71
|
/** Create the default virtual output script with one forfeit path and one exit path. */
|
|
81
72
|
constructor(options) {
|
|
82
73
|
const { pubKey, serverPubKey, csvTimelock } = options;
|
|
83
|
-
const forfeitScript =
|
|
74
|
+
const forfeitScript = chunk5XBH5SAL_cjs.MultisigTapscript.encode({
|
|
84
75
|
pubkeys: [pubKey, serverPubKey]
|
|
85
76
|
}).script;
|
|
86
|
-
const exitScript =
|
|
77
|
+
const exitScript = chunk5XBH5SAL_cjs.CSVMultisigTapscript.encode({
|
|
87
78
|
timelock: csvTimelock,
|
|
88
79
|
pubkeys: [pubKey]
|
|
89
80
|
}).script;
|
|
@@ -268,27 +259,14 @@ function resolveRole(contract, context) {
|
|
|
268
259
|
}
|
|
269
260
|
return void 0;
|
|
270
261
|
};
|
|
271
|
-
if (context.walletDescriptor)
|
|
272
|
-
|
|
273
|
-
const matchedRole = matchRole(walletDescriptorKey);
|
|
274
|
-
if (matchedRole) {
|
|
275
|
-
return matchedRole;
|
|
276
|
-
}
|
|
277
|
-
if (!walletDescriptorKey && context.walletPubKey) {
|
|
278
|
-
return matchRole(extractRawPubKey(context.walletPubKey));
|
|
279
|
-
}
|
|
280
|
-
return void 0;
|
|
281
|
-
}
|
|
282
|
-
if (context.walletPubKey) {
|
|
283
|
-
return matchRole(extractRawPubKey(context.walletPubKey));
|
|
284
|
-
}
|
|
285
|
-
return void 0;
|
|
262
|
+
if (!context.walletDescriptor) return void 0;
|
|
263
|
+
return matchRole(extractRawPubKey(context.walletDescriptor));
|
|
286
264
|
}
|
|
287
265
|
function extractPubKeyBytes(value) {
|
|
288
266
|
return base.hex.decode(extractPubKey(normalizeToDescriptor(value)));
|
|
289
267
|
}
|
|
290
268
|
function deserializeCsvTimelock(value) {
|
|
291
|
-
return value !== void 0 && value !== "" ?
|
|
269
|
+
return value !== void 0 && value !== "" ? chunk5XBH5SAL_cjs.sequenceToTimelock(Number(value)) : exports.DefaultVtxo.Script.DEFAULT_TIMELOCK;
|
|
292
270
|
}
|
|
293
271
|
var CLTV_HEIGHT_THRESHOLD = 500000000n;
|
|
294
272
|
function isCltvSatisfied(context, locktime) {
|
|
@@ -327,10 +305,139 @@ function assertVhtlcSpendableNow(contract, context) {
|
|
|
327
305
|
`vhtlc ${contract.script} cannot be spent yet: its refund path opens at ${matures}, now ${now}. Until then the lockup is the receiver's to claim, and the server rejects a spend of it. Retry after ${matures}, or wait for the receiver to claim it with the preimage.`
|
|
328
306
|
);
|
|
329
307
|
}
|
|
308
|
+
function selectVhtlcPath(script, contract, context) {
|
|
309
|
+
const role = resolveRole(contract, context);
|
|
310
|
+
const preimage = contract.params?.preimage;
|
|
311
|
+
const refundLocktime = BigInt(contract.params.refundLocktime);
|
|
312
|
+
if (!role) {
|
|
313
|
+
return null;
|
|
314
|
+
}
|
|
315
|
+
if (context.collaborative) {
|
|
316
|
+
if (role === "receiver" && preimage) {
|
|
317
|
+
return {
|
|
318
|
+
leaf: script.claim(),
|
|
319
|
+
extraWitness: [base.hex.decode(preimage)]
|
|
320
|
+
};
|
|
321
|
+
}
|
|
322
|
+
if (role === "sender" && isCltvSatisfied(context, refundLocktime)) {
|
|
323
|
+
return {
|
|
324
|
+
leaf: script.refundWithoutReceiver()
|
|
325
|
+
};
|
|
326
|
+
}
|
|
327
|
+
return null;
|
|
328
|
+
}
|
|
329
|
+
if (role === "receiver" && preimage) {
|
|
330
|
+
const sequence = Number(contract.params.claimDelay);
|
|
331
|
+
if (!isCsvSpendable(context, sequence)) return null;
|
|
332
|
+
return {
|
|
333
|
+
leaf: script.unilateralClaim(),
|
|
334
|
+
extraWitness: [base.hex.decode(preimage)],
|
|
335
|
+
sequence
|
|
336
|
+
};
|
|
337
|
+
}
|
|
338
|
+
if (role === "sender") {
|
|
339
|
+
const sequence = Number(contract.params.refundNoReceiverDelay);
|
|
340
|
+
if (!isCsvSpendable(context, sequence)) return null;
|
|
341
|
+
return {
|
|
342
|
+
leaf: script.unilateralRefundWithoutReceiver(),
|
|
343
|
+
sequence
|
|
344
|
+
};
|
|
345
|
+
}
|
|
346
|
+
return null;
|
|
347
|
+
}
|
|
348
|
+
function vhtlcAllSpendingPaths(script, contract, context) {
|
|
349
|
+
const role = resolveRole(contract, context);
|
|
350
|
+
const paths = [];
|
|
351
|
+
if (!role) {
|
|
352
|
+
return paths;
|
|
353
|
+
}
|
|
354
|
+
const preimage = contract.params?.preimage;
|
|
355
|
+
if (context.collaborative) {
|
|
356
|
+
if (role === "receiver" && preimage) {
|
|
357
|
+
paths.push({
|
|
358
|
+
leaf: script.claim(),
|
|
359
|
+
extraWitness: [base.hex.decode(preimage)]
|
|
360
|
+
});
|
|
361
|
+
}
|
|
362
|
+
if (role === "sender") {
|
|
363
|
+
paths.push({
|
|
364
|
+
leaf: script.refundWithoutReceiver()
|
|
365
|
+
});
|
|
366
|
+
}
|
|
367
|
+
} else {
|
|
368
|
+
if (role === "receiver" && preimage) {
|
|
369
|
+
const sequence = Number(contract.params.claimDelay);
|
|
370
|
+
paths.push({
|
|
371
|
+
leaf: script.unilateralClaim(),
|
|
372
|
+
extraWitness: [base.hex.decode(preimage)],
|
|
373
|
+
sequence
|
|
374
|
+
});
|
|
375
|
+
}
|
|
376
|
+
if (role === "sender") {
|
|
377
|
+
const sequence = Number(contract.params.refundNoReceiverDelay);
|
|
378
|
+
paths.push({
|
|
379
|
+
leaf: script.unilateralRefundWithoutReceiver(),
|
|
380
|
+
sequence
|
|
381
|
+
});
|
|
382
|
+
}
|
|
383
|
+
}
|
|
384
|
+
return paths;
|
|
385
|
+
}
|
|
386
|
+
function vhtlcSpendablePaths(script, contract, context) {
|
|
387
|
+
const role = resolveRole(contract, context);
|
|
388
|
+
const paths = [];
|
|
389
|
+
if (!role) {
|
|
390
|
+
return paths;
|
|
391
|
+
}
|
|
392
|
+
const preimage = contract.params?.preimage;
|
|
393
|
+
const refundLocktime = BigInt(contract.params.refundLocktime);
|
|
394
|
+
if (context.collaborative) {
|
|
395
|
+
if (role === "receiver" && preimage) {
|
|
396
|
+
paths.push({
|
|
397
|
+
leaf: script.claim(),
|
|
398
|
+
extraWitness: [base.hex.decode(preimage)]
|
|
399
|
+
});
|
|
400
|
+
}
|
|
401
|
+
if (role === "sender" && isCltvSatisfied(context, refundLocktime)) {
|
|
402
|
+
paths.push({
|
|
403
|
+
leaf: script.refundWithoutReceiver()
|
|
404
|
+
});
|
|
405
|
+
}
|
|
406
|
+
return paths;
|
|
407
|
+
}
|
|
408
|
+
if (role === "receiver" && preimage) {
|
|
409
|
+
const sequence = Number(contract.params.claimDelay);
|
|
410
|
+
if (isCsvSpendable(context, sequence)) {
|
|
411
|
+
paths.push({
|
|
412
|
+
leaf: script.unilateralClaim(),
|
|
413
|
+
extraWitness: [base.hex.decode(preimage)],
|
|
414
|
+
sequence
|
|
415
|
+
});
|
|
416
|
+
}
|
|
417
|
+
}
|
|
418
|
+
if (role === "sender") {
|
|
419
|
+
const sequence = Number(contract.params.refundNoReceiverDelay);
|
|
420
|
+
if (isCsvSpendable(context, sequence)) {
|
|
421
|
+
paths.push({
|
|
422
|
+
leaf: script.unilateralRefundWithoutReceiver(),
|
|
423
|
+
sequence
|
|
424
|
+
});
|
|
425
|
+
}
|
|
426
|
+
}
|
|
427
|
+
return paths;
|
|
428
|
+
}
|
|
429
|
+
function deriveVhtlcTapscripts(script) {
|
|
430
|
+
const leaf = script.refundWithoutReceiver();
|
|
431
|
+
return {
|
|
432
|
+
forfeitTapLeafScript: leaf,
|
|
433
|
+
intentTapLeafScript: leaf,
|
|
434
|
+
tapTree: script.encode()
|
|
435
|
+
};
|
|
436
|
+
}
|
|
330
437
|
function isCsvSpendable(context, sequence) {
|
|
331
438
|
if (sequence === void 0) return true;
|
|
332
439
|
if (!context.vtxo) return false;
|
|
333
|
-
const timelock =
|
|
440
|
+
const timelock = chunk5XBH5SAL_cjs.sequenceToTimelock(sequence);
|
|
334
441
|
if (timelock.type === "blocks") {
|
|
335
442
|
if (context.blockHeight === void 0 || context.vtxo.status.block_height === void 0) {
|
|
336
443
|
return false;
|
|
@@ -388,21 +495,21 @@ function forfeitExitSpendablePaths(script, contract, context) {
|
|
|
388
495
|
async function detectUsedScripts(indexerProvider, scriptHexes) {
|
|
389
496
|
const used = /* @__PURE__ */ new Set();
|
|
390
497
|
const unique = [...new Set(scriptHexes)];
|
|
391
|
-
for (let offset = 0; offset < unique.length; offset +=
|
|
392
|
-
const scripts = unique.slice(offset, offset +
|
|
498
|
+
for (let offset = 0; offset < unique.length; offset += chunk5XBH5SAL_cjs.SCRIPT_QUERY_CHUNK_SIZE) {
|
|
499
|
+
const scripts = unique.slice(offset, offset + chunk5XBH5SAL_cjs.SCRIPT_QUERY_CHUNK_SIZE);
|
|
393
500
|
const remaining = new Set(scripts);
|
|
394
501
|
let pageIndex = 0;
|
|
395
502
|
let hasMore = true;
|
|
396
503
|
while (hasMore && remaining.size > 0) {
|
|
397
|
-
const { vtxos, page } = await
|
|
504
|
+
const { vtxos, page } = await chunk5XBH5SAL_cjs.getNormalizedVtxos(indexerProvider, {
|
|
398
505
|
scripts,
|
|
399
506
|
pageIndex,
|
|
400
|
-
pageSize:
|
|
507
|
+
pageSize: chunk5XBH5SAL_cjs.DEFAULT_PAGE_SIZE
|
|
401
508
|
});
|
|
402
509
|
for (const vtxo of vtxos) {
|
|
403
510
|
if (remaining.delete(vtxo.script)) used.add(vtxo.script);
|
|
404
511
|
}
|
|
405
|
-
hasMore = page ? vtxos.length ===
|
|
512
|
+
hasMore = page ? vtxos.length === chunk5XBH5SAL_cjs.DEFAULT_PAGE_SIZE : false;
|
|
406
513
|
pageIndex++;
|
|
407
514
|
}
|
|
408
515
|
}
|
|
@@ -463,7 +570,7 @@ var DefaultContractHandler = {
|
|
|
463
570
|
return {
|
|
464
571
|
pubKey: base.hex.encode(params.pubKey),
|
|
465
572
|
serverPubKey: base.hex.encode(params.serverPubKey),
|
|
466
|
-
csvTimelock:
|
|
573
|
+
csvTimelock: chunk5XBH5SAL_cjs.timelockToSequence(params.csvTimelock).toString()
|
|
467
574
|
};
|
|
468
575
|
},
|
|
469
576
|
deserializeParams(params) {
|
|
@@ -495,11 +602,7 @@ function defaultCandidatesAt(_index, descriptor, deps) {
|
|
|
495
602
|
(opts) => new exports.DefaultVtxo.Script(opts)
|
|
496
603
|
).map((c) => ({
|
|
497
604
|
type: "default",
|
|
498
|
-
params:
|
|
499
|
-
pubKey: base.hex.encode(c.pubKey),
|
|
500
|
-
serverPubKey: base.hex.encode(c.serverPubKey),
|
|
501
|
-
csvTimelock: chunkJZWLXNHV_cjs.timelockToSequence(c.csvTimelock).toString()
|
|
502
|
-
},
|
|
605
|
+
params: DefaultContractHandler.serializeParams(c),
|
|
503
606
|
script: c.scriptHex,
|
|
504
607
|
address: c.script.address(deps.network.hrp, c.serverPubKey).encode()
|
|
505
608
|
}));
|
|
@@ -514,12 +617,12 @@ function discoverDefaultRange(entries, deps) {
|
|
|
514
617
|
}
|
|
515
618
|
exports.DelegateVtxo = void 0;
|
|
516
619
|
((DelegateVtxo2) => {
|
|
517
|
-
class Script3 extends
|
|
620
|
+
class Script3 extends chunk5XBH5SAL_cjs.VtxoScript {
|
|
518
621
|
/** Create a delegated virtual output script with forfeit, exit, and delegate paths. */
|
|
519
622
|
constructor(options) {
|
|
520
623
|
const defaultVtxo = new exports.DefaultVtxo.Script(options);
|
|
521
624
|
const { delegatePubKey, pubKey, serverPubKey } = options;
|
|
522
|
-
const delegateScript =
|
|
625
|
+
const delegateScript = chunk5XBH5SAL_cjs.MultisigTapscript.encode({
|
|
523
626
|
pubkeys: [pubKey, delegatePubKey, serverPubKey]
|
|
524
627
|
}).script;
|
|
525
628
|
super([...defaultVtxo.scripts, delegateScript]);
|
|
@@ -558,7 +661,7 @@ var DelegateContractHandler = {
|
|
|
558
661
|
pubKey: base.hex.encode(params.pubKey),
|
|
559
662
|
serverPubKey: base.hex.encode(params.serverPubKey),
|
|
560
663
|
delegatePubKey: base.hex.encode(params.delegatePubKey),
|
|
561
|
-
csvTimelock:
|
|
664
|
+
csvTimelock: chunk5XBH5SAL_cjs.timelockToSequence(params.csvTimelock).toString()
|
|
562
665
|
};
|
|
563
666
|
},
|
|
564
667
|
deserializeParams(params) {
|
|
@@ -598,12 +701,7 @@ function delegateCandidatesAt(_index, descriptor, deps) {
|
|
|
598
701
|
(opts) => new exports.DelegateVtxo.Script({ ...opts, delegatePubKey })
|
|
599
702
|
).map((c) => ({
|
|
600
703
|
type: "delegate",
|
|
601
|
-
params: {
|
|
602
|
-
pubKey: base.hex.encode(c.pubKey),
|
|
603
|
-
serverPubKey: base.hex.encode(c.serverPubKey),
|
|
604
|
-
delegatePubKey: base.hex.encode(delegatePubKey),
|
|
605
|
-
csvTimelock: chunkJZWLXNHV_cjs.timelockToSequence(c.csvTimelock).toString()
|
|
606
|
-
},
|
|
704
|
+
params: DelegateContractHandler.serializeParams({ ...c, delegatePubKey }),
|
|
607
705
|
script: c.scriptHex,
|
|
608
706
|
address: c.script.address(deps.network.hrp, c.serverPubKey).encode()
|
|
609
707
|
}));
|
|
@@ -619,515 +717,10 @@ function discoverDelegateRange(entries, deps) {
|
|
|
619
717
|
(c, index, descriptor) => ({ ...c, ...rotatedReceiveMetadata(index, descriptor) })
|
|
620
718
|
);
|
|
621
719
|
}
|
|
622
|
-
function equalBytes(a, b) {
|
|
623
|
-
if (a.length !== b.length)
|
|
624
|
-
return false;
|
|
625
|
-
for (let i = 0; i < a.length; i++)
|
|
626
|
-
if (a[i] !== b[i])
|
|
627
|
-
return false;
|
|
628
|
-
return true;
|
|
629
|
-
}
|
|
630
|
-
function isBytes(a) {
|
|
631
|
-
return a instanceof Uint8Array || ArrayBuffer.isView(a) && a.constructor.name === "Uint8Array";
|
|
632
|
-
}
|
|
633
|
-
var createView = (arr) => new DataView(arr.buffer, arr.byteOffset, arr.byteLength);
|
|
634
|
-
function isPlainObject(obj) {
|
|
635
|
-
return Object.prototype.toString.call(obj) === "[object Object]";
|
|
636
|
-
}
|
|
637
|
-
function isNum(num) {
|
|
638
|
-
return Number.isSafeInteger(num);
|
|
639
|
-
}
|
|
640
|
-
var Bitset = {
|
|
641
|
-
BITS: 32,
|
|
642
|
-
FULL_MASK: -1 >>> 0,
|
|
643
|
-
// 1<<32 will overflow
|
|
644
|
-
len: (len) => Math.ceil(len / 32),
|
|
645
|
-
create: (len) => new Uint32Array(Bitset.len(len)),
|
|
646
|
-
clean: (bs) => bs.fill(0),
|
|
647
|
-
debug: (bs) => Array.from(bs).map((i) => (i >>> 0).toString(2).padStart(32, "0")),
|
|
648
|
-
checkLen: (bs, len) => {
|
|
649
|
-
if (Bitset.len(len) === bs.length)
|
|
650
|
-
return;
|
|
651
|
-
throw new Error(`wrong length=${bs.length}. Expected: ${Bitset.len(len)}`);
|
|
652
|
-
},
|
|
653
|
-
chunkLen: (bsLen, pos, len) => {
|
|
654
|
-
if (pos < 0)
|
|
655
|
-
throw new Error(`wrong pos=${pos}`);
|
|
656
|
-
if (pos + len > bsLen)
|
|
657
|
-
throw new Error(`wrong range=${pos}/${len} of ${bsLen}`);
|
|
658
|
-
},
|
|
659
|
-
set: (bs, chunk, value, allowRewrite = true) => {
|
|
660
|
-
if (!allowRewrite && (bs[chunk] & value) !== 0)
|
|
661
|
-
return false;
|
|
662
|
-
bs[chunk] |= value;
|
|
663
|
-
return true;
|
|
664
|
-
},
|
|
665
|
-
pos: (pos, i) => ({
|
|
666
|
-
chunk: Math.floor((pos + i) / 32),
|
|
667
|
-
mask: 1 << 32 - (pos + i) % 32 - 1
|
|
668
|
-
}),
|
|
669
|
-
indices: (bs, len, invert = false) => {
|
|
670
|
-
Bitset.checkLen(bs, len);
|
|
671
|
-
const { FULL_MASK, BITS } = Bitset;
|
|
672
|
-
const left = BITS - len % BITS;
|
|
673
|
-
const lastMask = left ? FULL_MASK >>> left << left : FULL_MASK;
|
|
674
|
-
const res = [];
|
|
675
|
-
for (let i = 0; i < bs.length; i++) {
|
|
676
|
-
let c = bs[i];
|
|
677
|
-
if (invert)
|
|
678
|
-
c = ~c;
|
|
679
|
-
if (i === bs.length - 1)
|
|
680
|
-
c &= lastMask;
|
|
681
|
-
if (c === 0)
|
|
682
|
-
continue;
|
|
683
|
-
for (let j = 0; j < BITS; j++) {
|
|
684
|
-
const m = 1 << BITS - j - 1;
|
|
685
|
-
if (c & m)
|
|
686
|
-
res.push(i * BITS + j);
|
|
687
|
-
}
|
|
688
|
-
}
|
|
689
|
-
return res;
|
|
690
|
-
},
|
|
691
|
-
range: (arr) => {
|
|
692
|
-
const res = [];
|
|
693
|
-
let cur;
|
|
694
|
-
for (const i of arr) {
|
|
695
|
-
if (cur === void 0 || i !== cur.pos + cur.length)
|
|
696
|
-
res.push(cur = { pos: i, length: 1 });
|
|
697
|
-
else
|
|
698
|
-
cur.length += 1;
|
|
699
|
-
}
|
|
700
|
-
return res;
|
|
701
|
-
},
|
|
702
|
-
rangeDebug: (bs, len, invert = false) => `[${Bitset.range(Bitset.indices(bs, len, invert)).map((i) => `(${i.pos}/${i.length})`).join(", ")}]`,
|
|
703
|
-
setRange: (bs, bsLen, pos, len, allowRewrite = true) => {
|
|
704
|
-
Bitset.chunkLen(bsLen, pos, len);
|
|
705
|
-
const { FULL_MASK, BITS } = Bitset;
|
|
706
|
-
const first = pos % BITS ? Math.floor(pos / BITS) : void 0;
|
|
707
|
-
const lastPos = pos + len;
|
|
708
|
-
const last = lastPos % BITS ? Math.floor(lastPos / BITS) : void 0;
|
|
709
|
-
if (first !== void 0 && first === last)
|
|
710
|
-
return Bitset.set(bs, first, FULL_MASK >>> BITS - len << BITS - len - pos, allowRewrite);
|
|
711
|
-
if (first !== void 0) {
|
|
712
|
-
if (!Bitset.set(bs, first, FULL_MASK >>> pos % BITS, allowRewrite))
|
|
713
|
-
return false;
|
|
714
|
-
}
|
|
715
|
-
const start = first !== void 0 ? first + 1 : pos / BITS;
|
|
716
|
-
const end = last !== void 0 ? last : lastPos / BITS;
|
|
717
|
-
for (let i = start; i < end; i++)
|
|
718
|
-
if (!Bitset.set(bs, i, FULL_MASK, allowRewrite))
|
|
719
|
-
return false;
|
|
720
|
-
if (last !== void 0 && first !== last) {
|
|
721
|
-
if (!Bitset.set(bs, last, FULL_MASK << BITS - lastPos % BITS, allowRewrite))
|
|
722
|
-
return false;
|
|
723
|
-
}
|
|
724
|
-
return true;
|
|
725
|
-
}
|
|
726
|
-
};
|
|
727
|
-
var Path = {
|
|
728
|
-
/**
|
|
729
|
-
* Internal method for handling stack of paths (debug, errors, dynamic fields via path)
|
|
730
|
-
* This is looks ugly (callback), but allows us to force stack cleaning by construction (.pop always after function).
|
|
731
|
-
* Also, this makes impossible:
|
|
732
|
-
* - pushing field when stack is empty
|
|
733
|
-
* - pushing field inside of field (real bug)
|
|
734
|
-
* NOTE: we don't want to do '.pop' on error!
|
|
735
|
-
*/
|
|
736
|
-
pushObj: (stack, obj, objFn) => {
|
|
737
|
-
const last = { obj };
|
|
738
|
-
stack.push(last);
|
|
739
|
-
objFn((field, fieldFn) => {
|
|
740
|
-
last.field = field;
|
|
741
|
-
fieldFn();
|
|
742
|
-
last.field = void 0;
|
|
743
|
-
});
|
|
744
|
-
stack.pop();
|
|
745
|
-
},
|
|
746
|
-
path: (stack) => {
|
|
747
|
-
const res = [];
|
|
748
|
-
for (const i of stack)
|
|
749
|
-
if (i.field !== void 0)
|
|
750
|
-
res.push(i.field);
|
|
751
|
-
return res.join("/");
|
|
752
|
-
},
|
|
753
|
-
err: (name, stack, msg) => {
|
|
754
|
-
const err = new Error(`${name}(${Path.path(stack)}): ${typeof msg === "string" ? msg : msg.message}`);
|
|
755
|
-
if (msg instanceof Error && msg.stack)
|
|
756
|
-
err.stack = msg.stack;
|
|
757
|
-
return err;
|
|
758
|
-
},
|
|
759
|
-
resolve: (stack, path) => {
|
|
760
|
-
const parts = path.split("/");
|
|
761
|
-
const objPath = stack.map((i2) => i2.obj);
|
|
762
|
-
let i = 0;
|
|
763
|
-
for (; i < parts.length; i++) {
|
|
764
|
-
if (parts[i] === "..")
|
|
765
|
-
objPath.pop();
|
|
766
|
-
else
|
|
767
|
-
break;
|
|
768
|
-
}
|
|
769
|
-
let cur = objPath.pop();
|
|
770
|
-
for (; i < parts.length; i++) {
|
|
771
|
-
if (!cur || cur[parts[i]] === void 0)
|
|
772
|
-
return void 0;
|
|
773
|
-
cur = cur[parts[i]];
|
|
774
|
-
}
|
|
775
|
-
return cur;
|
|
776
|
-
}
|
|
777
|
-
};
|
|
778
|
-
var _Reader = class __Reader {
|
|
779
|
-
pos = 0;
|
|
780
|
-
data;
|
|
781
|
-
opts;
|
|
782
|
-
stack;
|
|
783
|
-
parent;
|
|
784
|
-
parentOffset;
|
|
785
|
-
bitBuf = 0;
|
|
786
|
-
bitPos = 0;
|
|
787
|
-
bs;
|
|
788
|
-
// bitset
|
|
789
|
-
view;
|
|
790
|
-
constructor(data, opts = {}, stack = [], parent = void 0, parentOffset = 0) {
|
|
791
|
-
this.data = data;
|
|
792
|
-
this.opts = opts;
|
|
793
|
-
this.stack = stack;
|
|
794
|
-
this.parent = parent;
|
|
795
|
-
this.parentOffset = parentOffset;
|
|
796
|
-
this.view = createView(data);
|
|
797
|
-
}
|
|
798
|
-
/** Internal method for pointers. */
|
|
799
|
-
_enablePointers() {
|
|
800
|
-
if (this.parent)
|
|
801
|
-
return this.parent._enablePointers();
|
|
802
|
-
if (this.bs)
|
|
803
|
-
return;
|
|
804
|
-
this.bs = Bitset.create(this.data.length);
|
|
805
|
-
Bitset.setRange(this.bs, this.data.length, 0, this.pos, this.opts.allowMultipleReads);
|
|
806
|
-
}
|
|
807
|
-
markBytesBS(pos, len) {
|
|
808
|
-
if (this.parent)
|
|
809
|
-
return this.parent.markBytesBS(this.parentOffset + pos, len);
|
|
810
|
-
if (!len)
|
|
811
|
-
return true;
|
|
812
|
-
if (!this.bs)
|
|
813
|
-
return true;
|
|
814
|
-
return Bitset.setRange(this.bs, this.data.length, pos, len, false);
|
|
815
|
-
}
|
|
816
|
-
markBytes(len) {
|
|
817
|
-
const pos = this.pos;
|
|
818
|
-
this.pos += len;
|
|
819
|
-
const res = this.markBytesBS(pos, len);
|
|
820
|
-
if (!this.opts.allowMultipleReads && !res)
|
|
821
|
-
throw this.err(`multiple read pos=${this.pos} len=${len}`);
|
|
822
|
-
return res;
|
|
823
|
-
}
|
|
824
|
-
pushObj(obj, objFn) {
|
|
825
|
-
return Path.pushObj(this.stack, obj, objFn);
|
|
826
|
-
}
|
|
827
|
-
readView(n, fn) {
|
|
828
|
-
if (!Number.isFinite(n))
|
|
829
|
-
throw this.err(`readView: wrong length=${n}`);
|
|
830
|
-
if (this.pos + n > this.data.length)
|
|
831
|
-
throw this.err("readView: Unexpected end of buffer");
|
|
832
|
-
const res = fn(this.view, this.pos);
|
|
833
|
-
this.markBytes(n);
|
|
834
|
-
return res;
|
|
835
|
-
}
|
|
836
|
-
// read bytes by absolute offset
|
|
837
|
-
absBytes(n) {
|
|
838
|
-
if (n > this.data.length)
|
|
839
|
-
throw new Error("Unexpected end of buffer");
|
|
840
|
-
return this.data.subarray(n);
|
|
841
|
-
}
|
|
842
|
-
finish() {
|
|
843
|
-
if (this.opts.allowUnreadBytes)
|
|
844
|
-
return;
|
|
845
|
-
if (this.bitPos) {
|
|
846
|
-
throw this.err(`${this.bitPos} bits left after unpack: ${base.hex.encode(this.data.slice(this.pos))}`);
|
|
847
|
-
}
|
|
848
|
-
if (this.bs && !this.parent) {
|
|
849
|
-
const notRead = Bitset.indices(this.bs, this.data.length, true);
|
|
850
|
-
if (notRead.length) {
|
|
851
|
-
const formatted = Bitset.range(notRead).map(({ pos, length }) => `(${pos}/${length})[${base.hex.encode(this.data.subarray(pos, pos + length))}]`).join(", ");
|
|
852
|
-
throw this.err(`unread byte ranges: ${formatted} (total=${this.data.length})`);
|
|
853
|
-
} else
|
|
854
|
-
return;
|
|
855
|
-
}
|
|
856
|
-
if (!this.isEnd()) {
|
|
857
|
-
throw this.err(`${this.leftBytes} bytes ${this.bitPos} bits left after unpack: ${base.hex.encode(this.data.slice(this.pos))}`);
|
|
858
|
-
}
|
|
859
|
-
}
|
|
860
|
-
// User methods
|
|
861
|
-
err(msg) {
|
|
862
|
-
return Path.err("Reader", this.stack, msg);
|
|
863
|
-
}
|
|
864
|
-
offsetReader(n) {
|
|
865
|
-
if (n > this.data.length)
|
|
866
|
-
throw this.err("offsetReader: Unexpected end of buffer");
|
|
867
|
-
return new __Reader(this.absBytes(n), this.opts, this.stack, this, n);
|
|
868
|
-
}
|
|
869
|
-
bytes(n, peek = false) {
|
|
870
|
-
if (this.bitPos)
|
|
871
|
-
throw this.err("readBytes: bitPos not empty");
|
|
872
|
-
if (!Number.isFinite(n))
|
|
873
|
-
throw this.err(`readBytes: wrong length=${n}`);
|
|
874
|
-
if (this.pos + n > this.data.length)
|
|
875
|
-
throw this.err("readBytes: Unexpected end of buffer");
|
|
876
|
-
const slice = this.data.subarray(this.pos, this.pos + n);
|
|
877
|
-
if (!peek)
|
|
878
|
-
this.markBytes(n);
|
|
879
|
-
return slice;
|
|
880
|
-
}
|
|
881
|
-
byte(peek = false) {
|
|
882
|
-
if (this.bitPos)
|
|
883
|
-
throw this.err("readByte: bitPos not empty");
|
|
884
|
-
if (this.pos + 1 > this.data.length)
|
|
885
|
-
throw this.err("readBytes: Unexpected end of buffer");
|
|
886
|
-
const data = this.data[this.pos];
|
|
887
|
-
if (!peek)
|
|
888
|
-
this.markBytes(1);
|
|
889
|
-
return data;
|
|
890
|
-
}
|
|
891
|
-
get leftBytes() {
|
|
892
|
-
return this.data.length - this.pos;
|
|
893
|
-
}
|
|
894
|
-
get totalBytes() {
|
|
895
|
-
return this.data.length;
|
|
896
|
-
}
|
|
897
|
-
isEnd() {
|
|
898
|
-
return this.pos >= this.data.length && !this.bitPos;
|
|
899
|
-
}
|
|
900
|
-
// bits are read in BE mode (left to right): (0b1000_0000).readBits(1) == 1
|
|
901
|
-
bits(bits) {
|
|
902
|
-
if (bits > 32)
|
|
903
|
-
throw this.err("BitReader: cannot read more than 32 bits in single call");
|
|
904
|
-
let out = 0;
|
|
905
|
-
while (bits) {
|
|
906
|
-
if (!this.bitPos) {
|
|
907
|
-
this.bitBuf = this.byte();
|
|
908
|
-
this.bitPos = 8;
|
|
909
|
-
}
|
|
910
|
-
const take = Math.min(bits, this.bitPos);
|
|
911
|
-
this.bitPos -= take;
|
|
912
|
-
out = out << take | this.bitBuf >> this.bitPos & 2 ** take - 1;
|
|
913
|
-
this.bitBuf &= 2 ** this.bitPos - 1;
|
|
914
|
-
bits -= take;
|
|
915
|
-
}
|
|
916
|
-
return out >>> 0;
|
|
917
|
-
}
|
|
918
|
-
find(needle, pos = this.pos) {
|
|
919
|
-
if (!isBytes(needle))
|
|
920
|
-
throw this.err(`find: needle is not bytes! ${needle}`);
|
|
921
|
-
if (this.bitPos)
|
|
922
|
-
throw this.err("findByte: bitPos not empty");
|
|
923
|
-
if (!needle.length)
|
|
924
|
-
throw this.err(`find: needle is empty`);
|
|
925
|
-
for (let idx = pos; (idx = this.data.indexOf(needle[0], idx)) !== -1; idx++) {
|
|
926
|
-
if (idx === -1)
|
|
927
|
-
return;
|
|
928
|
-
const leftBytes = this.data.length - idx;
|
|
929
|
-
if (leftBytes < needle.length)
|
|
930
|
-
return;
|
|
931
|
-
if (equalBytes(needle, this.data.subarray(idx, idx + needle.length)))
|
|
932
|
-
return idx;
|
|
933
|
-
}
|
|
934
|
-
return;
|
|
935
|
-
}
|
|
936
|
-
};
|
|
937
|
-
var _Writer = class {
|
|
938
|
-
pos = 0;
|
|
939
|
-
stack;
|
|
940
|
-
// We could have a single buffer here and re-alloc it with
|
|
941
|
-
// x1.5-2 size each time it full, but it will be slower:
|
|
942
|
-
// basic/encode bench: 395ns -> 560ns
|
|
943
|
-
buffers = [];
|
|
944
|
-
ptrs = [];
|
|
945
|
-
bitBuf = 0;
|
|
946
|
-
bitPos = 0;
|
|
947
|
-
viewBuf = new Uint8Array(8);
|
|
948
|
-
view;
|
|
949
|
-
finished = false;
|
|
950
|
-
constructor(stack = []) {
|
|
951
|
-
this.stack = stack;
|
|
952
|
-
this.view = createView(this.viewBuf);
|
|
953
|
-
}
|
|
954
|
-
pushObj(obj, objFn) {
|
|
955
|
-
return Path.pushObj(this.stack, obj, objFn);
|
|
956
|
-
}
|
|
957
|
-
writeView(len, fn) {
|
|
958
|
-
if (this.finished)
|
|
959
|
-
throw this.err("buffer: finished");
|
|
960
|
-
if (!isNum(len) || len > 8)
|
|
961
|
-
throw new Error(`wrong writeView length=${len}`);
|
|
962
|
-
fn(this.view);
|
|
963
|
-
this.bytes(this.viewBuf.slice(0, len));
|
|
964
|
-
this.viewBuf.fill(0);
|
|
965
|
-
}
|
|
966
|
-
// User methods
|
|
967
|
-
err(msg) {
|
|
968
|
-
if (this.finished)
|
|
969
|
-
throw this.err("buffer: finished");
|
|
970
|
-
return Path.err("Reader", this.stack, msg);
|
|
971
|
-
}
|
|
972
|
-
bytes(b) {
|
|
973
|
-
if (this.finished)
|
|
974
|
-
throw this.err("buffer: finished");
|
|
975
|
-
if (this.bitPos)
|
|
976
|
-
throw this.err("writeBytes: ends with non-empty bit buffer");
|
|
977
|
-
this.buffers.push(b);
|
|
978
|
-
this.pos += b.length;
|
|
979
|
-
}
|
|
980
|
-
byte(b) {
|
|
981
|
-
if (this.finished)
|
|
982
|
-
throw this.err("buffer: finished");
|
|
983
|
-
if (this.bitPos)
|
|
984
|
-
throw this.err("writeByte: ends with non-empty bit buffer");
|
|
985
|
-
this.buffers.push(new Uint8Array([b]));
|
|
986
|
-
this.pos++;
|
|
987
|
-
}
|
|
988
|
-
finish(clean = true) {
|
|
989
|
-
if (this.finished)
|
|
990
|
-
throw this.err("buffer: finished");
|
|
991
|
-
if (this.bitPos)
|
|
992
|
-
throw this.err("buffer: ends with non-empty bit buffer");
|
|
993
|
-
const buffers = this.buffers.concat(this.ptrs.map((i) => i.buffer));
|
|
994
|
-
const sum = buffers.map((b) => b.length).reduce((a, b) => a + b, 0);
|
|
995
|
-
const buf = new Uint8Array(sum);
|
|
996
|
-
for (let i = 0, pad = 0; i < buffers.length; i++) {
|
|
997
|
-
const a = buffers[i];
|
|
998
|
-
buf.set(a, pad);
|
|
999
|
-
pad += a.length;
|
|
1000
|
-
}
|
|
1001
|
-
for (let pos = this.pos, i = 0; i < this.ptrs.length; i++) {
|
|
1002
|
-
const ptr = this.ptrs[i];
|
|
1003
|
-
buf.set(ptr.ptr.encode(pos), ptr.pos);
|
|
1004
|
-
pos += ptr.buffer.length;
|
|
1005
|
-
}
|
|
1006
|
-
if (clean) {
|
|
1007
|
-
this.buffers = [];
|
|
1008
|
-
for (const p of this.ptrs)
|
|
1009
|
-
p.buffer.fill(0);
|
|
1010
|
-
this.ptrs = [];
|
|
1011
|
-
this.finished = true;
|
|
1012
|
-
this.bitBuf = 0;
|
|
1013
|
-
}
|
|
1014
|
-
return buf;
|
|
1015
|
-
}
|
|
1016
|
-
bits(value, bits) {
|
|
1017
|
-
if (bits > 32)
|
|
1018
|
-
throw this.err("writeBits: cannot write more than 32 bits in single call");
|
|
1019
|
-
if (value >= 2 ** bits)
|
|
1020
|
-
throw this.err(`writeBits: value (${value}) >= 2**bits (${bits})`);
|
|
1021
|
-
while (bits) {
|
|
1022
|
-
const take = Math.min(bits, 8 - this.bitPos);
|
|
1023
|
-
this.bitBuf = this.bitBuf << take | value >> bits - take;
|
|
1024
|
-
this.bitPos += take;
|
|
1025
|
-
bits -= take;
|
|
1026
|
-
value &= 2 ** bits - 1;
|
|
1027
|
-
if (this.bitPos === 8) {
|
|
1028
|
-
this.bitPos = 0;
|
|
1029
|
-
this.buffers.push(new Uint8Array([this.bitBuf]));
|
|
1030
|
-
this.pos++;
|
|
1031
|
-
}
|
|
1032
|
-
}
|
|
1033
|
-
}
|
|
1034
|
-
};
|
|
1035
|
-
function _wrap(inner) {
|
|
1036
|
-
return {
|
|
1037
|
-
// NOTE: we cannot export validate here, since it is likely mistake.
|
|
1038
|
-
encodeStream: inner.encodeStream,
|
|
1039
|
-
decodeStream: inner.decodeStream,
|
|
1040
|
-
size: inner.size,
|
|
1041
|
-
encode: (value) => {
|
|
1042
|
-
const w = new _Writer();
|
|
1043
|
-
inner.encodeStream(w, value);
|
|
1044
|
-
return w.finish();
|
|
1045
|
-
},
|
|
1046
|
-
decode: (data, opts = {}) => {
|
|
1047
|
-
const r = new _Reader(data, opts);
|
|
1048
|
-
const res = inner.decodeStream(r);
|
|
1049
|
-
r.finish();
|
|
1050
|
-
return res;
|
|
1051
|
-
}
|
|
1052
|
-
};
|
|
1053
|
-
}
|
|
1054
|
-
function validate(inner, fn) {
|
|
1055
|
-
if (!isCoder(inner))
|
|
1056
|
-
throw new Error(`validate: invalid inner value ${inner}`);
|
|
1057
|
-
if (typeof fn !== "function")
|
|
1058
|
-
throw new Error("validate: fn should be function");
|
|
1059
|
-
return _wrap({
|
|
1060
|
-
size: inner.size,
|
|
1061
|
-
encodeStream: (w, value) => {
|
|
1062
|
-
let res;
|
|
1063
|
-
try {
|
|
1064
|
-
res = fn(value);
|
|
1065
|
-
} catch (e) {
|
|
1066
|
-
throw w.err(e);
|
|
1067
|
-
}
|
|
1068
|
-
inner.encodeStream(w, res);
|
|
1069
|
-
},
|
|
1070
|
-
decodeStream: (r) => {
|
|
1071
|
-
const res = inner.decodeStream(r);
|
|
1072
|
-
try {
|
|
1073
|
-
return fn(res);
|
|
1074
|
-
} catch (e) {
|
|
1075
|
-
throw r.err(e);
|
|
1076
|
-
}
|
|
1077
|
-
}
|
|
1078
|
-
});
|
|
1079
|
-
}
|
|
1080
|
-
var wrap = (inner) => {
|
|
1081
|
-
const res = _wrap(inner);
|
|
1082
|
-
return inner.validate ? validate(res, inner.validate) : res;
|
|
1083
|
-
};
|
|
1084
|
-
var isBaseCoder = (elm) => isPlainObject(elm) && typeof elm.decode === "function" && typeof elm.encode === "function";
|
|
1085
|
-
function isCoder(elm) {
|
|
1086
|
-
return isPlainObject(elm) && isBaseCoder(elm) && typeof elm.encodeStream === "function" && typeof elm.decodeStream === "function" && (elm.size === void 0 || isNum(elm.size));
|
|
1087
|
-
}
|
|
1088
|
-
var view = (len, opts) => wrap({
|
|
1089
|
-
size: len,
|
|
1090
|
-
encodeStream: (w, value) => w.writeView(len, (view2) => opts.write(view2, value)),
|
|
1091
|
-
decodeStream: (r) => r.readView(len, opts.read),
|
|
1092
|
-
validate: (value) => {
|
|
1093
|
-
if (typeof value !== "number")
|
|
1094
|
-
throw new Error(`viewCoder: expected number, got ${typeof value}`);
|
|
1095
|
-
if (opts.validate)
|
|
1096
|
-
opts.validate(value);
|
|
1097
|
-
return value;
|
|
1098
|
-
}
|
|
1099
|
-
});
|
|
1100
|
-
var intView = (len, signed, opts) => {
|
|
1101
|
-
const bits = len * 8;
|
|
1102
|
-
const maxVal = 2 ** bits;
|
|
1103
|
-
const validateUnsigned = (value) => {
|
|
1104
|
-
if (!isNum(value))
|
|
1105
|
-
throw new Error(`uintView: value is not safe integer: ${value}`);
|
|
1106
|
-
if (0 > value || value >= maxVal) {
|
|
1107
|
-
throw new Error(`uintView: value out of bounds. Expected 0 <= ${value} < ${maxVal}`);
|
|
1108
|
-
}
|
|
1109
|
-
};
|
|
1110
|
-
return view(len, {
|
|
1111
|
-
write: opts.write,
|
|
1112
|
-
read: opts.read,
|
|
1113
|
-
validate: validateUnsigned
|
|
1114
|
-
});
|
|
1115
|
-
};
|
|
1116
|
-
var U32LE = /* @__PURE__ */ intView(4, false, {
|
|
1117
|
-
read: (view2, pos) => view2.getUint32(pos, true),
|
|
1118
|
-
write: (view2, value) => view2.setUint32(0, value, true)
|
|
1119
|
-
});
|
|
1120
|
-
var U16LE = /* @__PURE__ */ intView(2, false, {
|
|
1121
|
-
read: (view2, pos) => view2.getUint16(pos, true),
|
|
1122
|
-
write: (view2, value) => view2.setUint16(0, value, true)
|
|
1123
|
-
});
|
|
1124
|
-
var U8 = /* @__PURE__ */ intView(1, false, {
|
|
1125
|
-
read: (view2, pos) => view2.getUint8(pos),
|
|
1126
|
-
write: (view2, value) => view2.setUint8(0, value)
|
|
1127
|
-
});
|
|
1128
720
|
var ARKADE_OP = {
|
|
1129
721
|
// Merkle Branch Verification (0xb3 — repurposed NOP4 slot)
|
|
1130
722
|
MERKLEBRANCHVERIFY: 179,
|
|
723
|
+
PUT: 187,
|
|
1131
724
|
// Digest (0xc3)
|
|
1132
725
|
DIGEST: 195,
|
|
1133
726
|
// SHA256 Streaming (0xc4-0xc6)
|
|
@@ -1159,7 +752,10 @@ var ARKADE_OP = {
|
|
|
1159
752
|
BIN2NUM: 216,
|
|
1160
753
|
REVERSEBYTES: 217,
|
|
1161
754
|
MODEXP: 218,
|
|
1162
|
-
//
|
|
755
|
+
// VTXO Expiry & Emulator Clock (0xdb-0xdc)
|
|
756
|
+
PUSHEXPIRY: 219,
|
|
757
|
+
CHECKTIME: 220,
|
|
758
|
+
// 0xdd-0xdf are unassigned (OP_UNKNOWN221-223)
|
|
1163
759
|
// EC Operations (0xe0-0xe2)
|
|
1164
760
|
ECADD: 224,
|
|
1165
761
|
ECMUL: 225,
|
|
@@ -1188,7 +784,10 @@ var ARKADE_OP = {
|
|
|
1188
784
|
INSPECTPACKET: 244,
|
|
1189
785
|
INSPECTINPUTPACKET: 245,
|
|
1190
786
|
// Signature Hash (0xf6)
|
|
1191
|
-
SIGHASH: 246
|
|
787
|
+
SIGHASH: 246,
|
|
788
|
+
// Continuation & Intent Introspection (0xf7-0xf8)
|
|
789
|
+
TUNNEL: 247,
|
|
790
|
+
INSPECTINTENTMESSAGE: 248
|
|
1192
791
|
};
|
|
1193
792
|
var ARKADE_OPCODES = Object.values(ARKADE_OP);
|
|
1194
793
|
var ARKADE_OPCODE_NAMES = Object.fromEntries(
|
|
@@ -1256,7 +855,7 @@ function getOpcodeValue(name) {
|
|
|
1256
855
|
|
|
1257
856
|
// src/arkade/bignum.ts
|
|
1258
857
|
var bignum_exports = {};
|
|
1259
|
-
|
|
858
|
+
chunk5XBH5SAL_cjs.__export(bignum_exports, {
|
|
1260
859
|
BIGNUM_MAX_BYTES: () => BIGNUM_MAX_BYTES,
|
|
1261
860
|
decode: () => decode,
|
|
1262
861
|
encode: () => encode
|
|
@@ -1284,7 +883,7 @@ var ArkadeOPNames = {};
|
|
|
1284
883
|
for (const [k, v] of Object.entries(ARKADE_OPS)) {
|
|
1285
884
|
if (typeof v === "number") ArkadeOPNames[v] = k;
|
|
1286
885
|
}
|
|
1287
|
-
var ArkadeScript = wrap({
|
|
886
|
+
var ArkadeScript = P__namespace.wrap({
|
|
1288
887
|
encodeStream: (w, value) => {
|
|
1289
888
|
for (let o of value) {
|
|
1290
889
|
if (typeof o === "string") {
|
|
@@ -1310,10 +909,10 @@ var ArkadeScript = wrap({
|
|
|
1310
909
|
w.byte(len);
|
|
1311
910
|
} else if (len <= 65535) {
|
|
1312
911
|
w.byte(btcSigner.OP.PUSHDATA2);
|
|
1313
|
-
w.bytes(U16LE.encode(len));
|
|
912
|
+
w.bytes(P__namespace.U16LE.encode(len));
|
|
1314
913
|
} else {
|
|
1315
914
|
w.byte(btcSigner.OP.PUSHDATA4);
|
|
1316
|
-
w.bytes(U32LE.encode(len));
|
|
915
|
+
w.bytes(P__namespace.U32LE.encode(len));
|
|
1317
916
|
}
|
|
1318
917
|
w.bytes(o);
|
|
1319
918
|
}
|
|
@@ -1325,9 +924,9 @@ var ArkadeScript = wrap({
|
|
|
1325
924
|
if (btcSigner.OP.OP_0 < cur && cur <= btcSigner.OP.PUSHDATA4) {
|
|
1326
925
|
let len;
|
|
1327
926
|
if (cur < btcSigner.OP.PUSHDATA1) len = cur;
|
|
1328
|
-
else if (cur === btcSigner.OP.PUSHDATA1) len = U8.decodeStream(r);
|
|
1329
|
-
else if (cur === btcSigner.OP.PUSHDATA2) len = U16LE.decodeStream(r);
|
|
1330
|
-
else if (cur === btcSigner.OP.PUSHDATA4) len = U32LE.decodeStream(r);
|
|
927
|
+
else if (cur === btcSigner.OP.PUSHDATA1) len = P__namespace.U8.decodeStream(r);
|
|
928
|
+
else if (cur === btcSigner.OP.PUSHDATA2) len = P__namespace.U16LE.decodeStream(r);
|
|
929
|
+
else if (cur === btcSigner.OP.PUSHDATA4) len = P__namespace.U32LE.decodeStream(r);
|
|
1331
930
|
else throw new Error("Should be not possible");
|
|
1332
931
|
out.push(r.bytes(len));
|
|
1333
932
|
} else if (cur === 0) {
|
|
@@ -1445,7 +1044,7 @@ function computeArkadeScriptPublicKey(pubKey, script) {
|
|
|
1445
1044
|
// src/script/vhtlc.ts
|
|
1446
1045
|
exports.VHTLC = void 0;
|
|
1447
1046
|
((VHTLC2) => {
|
|
1448
|
-
class BaseScript extends
|
|
1047
|
+
class BaseScript extends chunk5XBH5SAL_cjs.VtxoScript {
|
|
1449
1048
|
options;
|
|
1450
1049
|
claimScript;
|
|
1451
1050
|
refundScript;
|
|
@@ -1472,27 +1071,27 @@ exports.VHTLC = void 0;
|
|
|
1472
1071
|
unilateralRefundWithoutReceiverDelay
|
|
1473
1072
|
} = options;
|
|
1474
1073
|
const conditionScript = preimageCondition(preimageHash);
|
|
1475
|
-
const claimScript =
|
|
1074
|
+
const claimScript = chunk5XBH5SAL_cjs.ConditionMultisigTapscript.encode({
|
|
1476
1075
|
conditionScript,
|
|
1477
1076
|
pubkeys: [receiver, server]
|
|
1478
1077
|
}).script;
|
|
1479
|
-
const refundScript =
|
|
1078
|
+
const refundScript = chunk5XBH5SAL_cjs.MultisigTapscript.encode({
|
|
1480
1079
|
pubkeys: [sender, receiver, server]
|
|
1481
1080
|
}).script;
|
|
1482
|
-
const refundWithoutReceiverScript =
|
|
1081
|
+
const refundWithoutReceiverScript = chunk5XBH5SAL_cjs.CLTVMultisigTapscript.encode({
|
|
1483
1082
|
absoluteTimelock: refundLocktime,
|
|
1484
1083
|
pubkeys: [sender, server]
|
|
1485
1084
|
}).script;
|
|
1486
|
-
const unilateralClaimScript =
|
|
1085
|
+
const unilateralClaimScript = chunk5XBH5SAL_cjs.ConditionCSVMultisigTapscript.encode({
|
|
1487
1086
|
conditionScript,
|
|
1488
1087
|
timelock: unilateralClaimDelay,
|
|
1489
1088
|
pubkeys: [receiver]
|
|
1490
1089
|
}).script;
|
|
1491
|
-
const unilateralRefundScript =
|
|
1090
|
+
const unilateralRefundScript = chunk5XBH5SAL_cjs.CSVMultisigTapscript.encode({
|
|
1492
1091
|
timelock: unilateralRefundDelay,
|
|
1493
1092
|
pubkeys: [sender, receiver]
|
|
1494
1093
|
}).script;
|
|
1495
|
-
const unilateralRefundWithoutReceiverScript =
|
|
1094
|
+
const unilateralRefundWithoutReceiverScript = chunk5XBH5SAL_cjs.CSVMultisigTapscript.encode({
|
|
1496
1095
|
timelock: unilateralRefundWithoutReceiverDelay,
|
|
1497
1096
|
pubkeys: [sender]
|
|
1498
1097
|
}).script;
|
|
@@ -1512,7 +1111,7 @@ exports.VHTLC = void 0;
|
|
|
1512
1111
|
const covenants = options.nonInteractiveParameters;
|
|
1513
1112
|
if (covenants) {
|
|
1514
1113
|
arkadeScriptNic = enforcePayToMaybeAsset(covenants.receiverPkScript, options.asset);
|
|
1515
|
-
nonInteractiveClaimScript =
|
|
1114
|
+
nonInteractiveClaimScript = chunk5XBH5SAL_cjs.ConditionMultisigTapscript.encode({
|
|
1516
1115
|
conditionScript,
|
|
1517
1116
|
pubkeys: [
|
|
1518
1117
|
server,
|
|
@@ -1525,12 +1124,12 @@ exports.VHTLC = void 0;
|
|
|
1525
1124
|
covenants.emulatorPubkey,
|
|
1526
1125
|
arkadeScriptNir
|
|
1527
1126
|
);
|
|
1528
|
-
nonInteractiveRefundScript =
|
|
1127
|
+
nonInteractiveRefundScript = chunk5XBH5SAL_cjs.MultisigTapscript.encode({
|
|
1529
1128
|
pubkeys: [server, receiver, nirCosigner]
|
|
1530
1129
|
}).script;
|
|
1531
1130
|
scripts.push(nonInteractiveRefundScript);
|
|
1532
1131
|
if (covenants.legacy !== "preTimelockedRefund") {
|
|
1533
|
-
nonInteractiveRefundWithoutReceiverScript =
|
|
1132
|
+
nonInteractiveRefundWithoutReceiverScript = chunk5XBH5SAL_cjs.CLTVMultisigTapscript.encode({
|
|
1534
1133
|
absoluteTimelock: refundLocktime,
|
|
1535
1134
|
pubkeys: [server, nirCosigner]
|
|
1536
1135
|
}).script;
|
|
@@ -1609,54 +1208,19 @@ exports.VHTLC = void 0;
|
|
|
1609
1208
|
/**
|
|
1610
1209
|
* Return the timelocked non-interactive refund tapleaf and its ArkadeScript.
|
|
1611
1210
|
*
|
|
1612
|
-
*
|
|
1613
|
-
*
|
|
1614
|
-
*
|
|
1615
|
-
*
|
|
1616
|
-
* the
|
|
1617
|
-
*
|
|
1618
|
-
*
|
|
1619
|
-
*
|
|
1620
|
-
* TapLeafScript} as `tapLeafScript`, this script's {@link
|
|
1621
|
-
* VtxoScript.encode} as `tapTree`), plus its checkpoint tx.
|
|
1622
|
-
* 2. Attach the ArkadeScript this method returns to the spent
|
|
1623
|
-
* input via an `EmulatorPacket` (type 1) — `{ vin, script:
|
|
1624
|
-
* <this ArkadeScript>, witness: <empty> }`, empty because the
|
|
1625
|
-
* script pushes its own input/output index with
|
|
1626
|
-
* `PUSHCURRENTINPUTINDEX` rather than reading one from the
|
|
1627
|
-
* witness — wrapped in an `Extension` OP_RETURN output on the
|
|
1628
|
-
* ark tx.
|
|
1629
|
-
* 3. Attach the spent input's OWN creating ark tx as `PrevArkTx` on
|
|
1630
|
-
* input 0 — required so the emulator can resolve that input's
|
|
1631
|
-
* prevout pkScript/value; it does not otherwise have them.
|
|
1632
|
-
* 4. POST the (base64-PSBT) ark tx and checkpoint(s) as `{ arkTx,
|
|
1633
|
-
* checkpointTxs }` to the emulator's `POST /v1/tx`.
|
|
1211
|
+
* Spent through the generic covenant path ({@link EmulatorProvider},
|
|
1212
|
+
* {@link ArkadeTransactionBuilder}): build the ark tx on this leaf plus its checkpoint;
|
|
1213
|
+
* attach this ArkadeScript to the input in an `EmulatorPacket` (type 1, empty witness:
|
|
1214
|
+
* the script pushes its own index with `PUSHCURRENTINPUTINDEX`) inside an `Extension`
|
|
1215
|
+
* OP_RETURN; attach the input's creating ark tx as `PrevArkTx` (the emulator can't
|
|
1216
|
+
* otherwise resolve its prevout); POST to the emulator's `/v1/tx`. The emulator co-signs
|
|
1217
|
+
* for `nirCosigner` only if `enforcePayTo(senderPkScript)` holds, and finalizes with arkd.
|
|
1218
|
+
* `server`'s signature is still required at consensus level, outside the covenant.
|
|
1634
1219
|
*
|
|
1635
|
-
*
|
|
1636
|
-
*
|
|
1637
|
-
*
|
|
1638
|
-
*
|
|
1639
|
-
* check passing does the emulator sign for `nirCosigner` (the
|
|
1640
|
-
* `emulatorPubkey` tweaked by this ArkadeScript's hash); the
|
|
1641
|
-
* response carries the fully co-signed `signedArkTx` and
|
|
1642
|
-
* `signedCheckpointTxs` — `ArkadeTransactionBuilder.send()`'s own
|
|
1643
|
-
* comment on this path: "the emulator executes the arkade script
|
|
1644
|
-
* and finalizes with arkd" — no separate call to arkd is made by
|
|
1645
|
-
* this SDK for a covenant spend.
|
|
1646
|
-
* Neither `server` nor `receiver` play any part in that check: this
|
|
1647
|
-
* leaf's tapscript still requires `server`'s own signature
|
|
1648
|
-
* alongside `nirCosigner`'s (see the class doc above), but that is
|
|
1649
|
-
* consensus-level multisig, not something the covenant enforces.
|
|
1650
|
-
*
|
|
1651
|
-
* NOT SPENDABLE UNTIL `refundLocktime` MATURES — the tapscript's
|
|
1652
|
-
* `OP_CHECKLOCKTIMEVERIFY` is arkd's concern, not the emulator's;
|
|
1653
|
-
* the emulator will happily co-sign an immature spend and arkd will
|
|
1654
|
-
* then refuse it. A block-height-typed `refundLocktime` (below the
|
|
1655
|
-
* standard height/timestamp boundary this SDK names
|
|
1656
|
-
* `CLTV_HEIGHT_THRESHOLD`, 500,000,000, in
|
|
1657
|
-
* `src/contracts/handlers/helpers.ts`) is refused by arkd for a
|
|
1658
|
-
* forfeit-eligible leaf independent of maturity — use a
|
|
1659
|
-
* seconds-typed (absolute Unix timestamp) value.
|
|
1220
|
+
* The emulator does not check `refundLocktime`: it co-signs an immature spend and arkd's
|
|
1221
|
+
* CLTV refuses it. arkd also refuses a block-height `refundLocktime`
|
|
1222
|
+
* (< `CLTV_HEIGHT_THRESHOLD`, 500,000,000) on a forfeit-eligible leaf regardless of
|
|
1223
|
+
* maturity: use a seconds-typed (Unix timestamp) value.
|
|
1660
1224
|
*/
|
|
1661
1225
|
nonInteractiveRefundWithoutReceiver() {
|
|
1662
1226
|
if (!this.nonInteractiveRefundWithoutReceiverScript || !this.nonInteractiveRefundWithoutReceiverArkadeScript) {
|
|
@@ -1799,10 +1363,7 @@ function enforcePayToAsset(destinationPkScript, asset) {
|
|
|
1799
1363
|
}
|
|
1800
1364
|
const inspectionTxid = Uint8Array.from(asset.txid).reverse();
|
|
1801
1365
|
return ArkadeScript.encode([
|
|
1802
|
-
// The output carries at least
|
|
1803
|
-
// Output index is the input's -- the same index alignment the sat
|
|
1804
|
-
// covenant relies on, and the same liveness obligation on whoever
|
|
1805
|
-
// assembles the spend.
|
|
1366
|
+
// The output at the input's index carries at least the input's amount of the asset.
|
|
1806
1367
|
"PUSHCURRENTINPUTINDEX",
|
|
1807
1368
|
inspectionTxid,
|
|
1808
1369
|
asset.groupIndex,
|
|
@@ -1844,9 +1405,9 @@ var VHTLCContractHandler = {
|
|
|
1844
1405
|
server: base.hex.encode(params.server),
|
|
1845
1406
|
hash: base.hex.encode(params.preimageHash),
|
|
1846
1407
|
refundLocktime: params.refundLocktime.toString(),
|
|
1847
|
-
claimDelay:
|
|
1848
|
-
refundDelay:
|
|
1849
|
-
refundNoReceiverDelay:
|
|
1408
|
+
claimDelay: chunk5XBH5SAL_cjs.timelockToSequence(params.unilateralClaimDelay).toString(),
|
|
1409
|
+
refundDelay: chunk5XBH5SAL_cjs.timelockToSequence(params.unilateralRefundDelay).toString(),
|
|
1410
|
+
refundNoReceiverDelay: chunk5XBH5SAL_cjs.timelockToSequence(
|
|
1850
1411
|
params.unilateralRefundWithoutReceiverDelay
|
|
1851
1412
|
).toString()
|
|
1852
1413
|
};
|
|
@@ -1858,147 +1419,26 @@ var VHTLCContractHandler = {
|
|
|
1858
1419
|
server: base.hex.decode(params.server),
|
|
1859
1420
|
preimageHash: base.hex.decode(params.hash),
|
|
1860
1421
|
refundLocktime: BigInt(params.refundLocktime),
|
|
1861
|
-
unilateralClaimDelay:
|
|
1862
|
-
unilateralRefundDelay:
|
|
1863
|
-
unilateralRefundWithoutReceiverDelay:
|
|
1422
|
+
unilateralClaimDelay: chunk5XBH5SAL_cjs.sequenceToTimelock(Number(params.claimDelay)),
|
|
1423
|
+
unilateralRefundDelay: chunk5XBH5SAL_cjs.sequenceToTimelock(Number(params.refundDelay)),
|
|
1424
|
+
unilateralRefundWithoutReceiverDelay: chunk5XBH5SAL_cjs.sequenceToTimelock(
|
|
1864
1425
|
Number(params.refundNoReceiverDelay)
|
|
1865
1426
|
)
|
|
1866
1427
|
};
|
|
1867
1428
|
},
|
|
1868
1429
|
/**
|
|
1869
|
-
* Select spending path based on context.
|
|
1870
|
-
*
|
|
1871
|
-
* Role is determined from `context.role` or by matching
|
|
1872
|
-
* `context.walletDescriptor` (preferred) / `context.walletPubKey`
|
|
1873
|
-
* against sender/receiver in contract params.
|
|
1430
|
+
* Select spending path based on context. Role comes from `context.role` or from matching
|
|
1431
|
+
* `context.walletDescriptor` against sender/receiver.
|
|
1874
1432
|
*/
|
|
1875
1433
|
selectPath(script, contract, context) {
|
|
1876
|
-
|
|
1877
|
-
const preimage = contract.params?.preimage;
|
|
1878
|
-
const refundLocktime = BigInt(contract.params.refundLocktime);
|
|
1879
|
-
if (!role) {
|
|
1880
|
-
return null;
|
|
1881
|
-
}
|
|
1882
|
-
if (context.collaborative) {
|
|
1883
|
-
if (role === "receiver" && preimage) {
|
|
1884
|
-
return {
|
|
1885
|
-
leaf: script.claim(),
|
|
1886
|
-
extraWitness: [base.hex.decode(preimage)]
|
|
1887
|
-
};
|
|
1888
|
-
}
|
|
1889
|
-
if (role === "sender" && isCltvSatisfied(context, refundLocktime)) {
|
|
1890
|
-
return {
|
|
1891
|
-
leaf: script.refundWithoutReceiver()
|
|
1892
|
-
};
|
|
1893
|
-
}
|
|
1894
|
-
return null;
|
|
1895
|
-
}
|
|
1896
|
-
if (role === "receiver" && preimage) {
|
|
1897
|
-
const sequence = Number(contract.params.claimDelay);
|
|
1898
|
-
if (!isCsvSpendable(context, sequence)) return null;
|
|
1899
|
-
return {
|
|
1900
|
-
leaf: script.unilateralClaim(),
|
|
1901
|
-
extraWitness: [base.hex.decode(preimage)],
|
|
1902
|
-
sequence
|
|
1903
|
-
};
|
|
1904
|
-
}
|
|
1905
|
-
if (role === "sender") {
|
|
1906
|
-
const sequence = Number(contract.params.refundNoReceiverDelay);
|
|
1907
|
-
if (!isCsvSpendable(context, sequence)) return null;
|
|
1908
|
-
return {
|
|
1909
|
-
leaf: script.unilateralRefundWithoutReceiver(),
|
|
1910
|
-
sequence
|
|
1911
|
-
};
|
|
1912
|
-
}
|
|
1913
|
-
return null;
|
|
1434
|
+
return selectVhtlcPath(script, contract, context);
|
|
1914
1435
|
},
|
|
1915
|
-
/**
|
|
1916
|
-
* Get all possible spending paths (no timelock checks).
|
|
1917
|
-
*
|
|
1918
|
-
* Role is determined from `context.role` or by matching
|
|
1919
|
-
* `context.walletDescriptor` (preferred) / `context.walletPubKey`
|
|
1920
|
-
* against sender/receiver in contract params.
|
|
1921
|
-
*/
|
|
1436
|
+
/** All possible spending paths (no timelock checks); role as in {@link selectPath}. */
|
|
1922
1437
|
getAllSpendingPaths(script, contract, context) {
|
|
1923
|
-
|
|
1924
|
-
const paths = [];
|
|
1925
|
-
if (!role) {
|
|
1926
|
-
return paths;
|
|
1927
|
-
}
|
|
1928
|
-
const preimage = contract.params?.preimage;
|
|
1929
|
-
if (context.collaborative) {
|
|
1930
|
-
if (role === "receiver" && preimage) {
|
|
1931
|
-
paths.push({
|
|
1932
|
-
leaf: script.claim(),
|
|
1933
|
-
extraWitness: [base.hex.decode(preimage)]
|
|
1934
|
-
});
|
|
1935
|
-
}
|
|
1936
|
-
if (role === "sender") {
|
|
1937
|
-
paths.push({
|
|
1938
|
-
leaf: script.refundWithoutReceiver()
|
|
1939
|
-
});
|
|
1940
|
-
}
|
|
1941
|
-
} else {
|
|
1942
|
-
if (role === "receiver" && preimage) {
|
|
1943
|
-
const sequence = Number(contract.params.claimDelay);
|
|
1944
|
-
paths.push({
|
|
1945
|
-
leaf: script.unilateralClaim(),
|
|
1946
|
-
extraWitness: [base.hex.decode(preimage)],
|
|
1947
|
-
sequence
|
|
1948
|
-
});
|
|
1949
|
-
}
|
|
1950
|
-
if (role === "sender") {
|
|
1951
|
-
const sequence = Number(contract.params.refundNoReceiverDelay);
|
|
1952
|
-
paths.push({
|
|
1953
|
-
leaf: script.unilateralRefundWithoutReceiver(),
|
|
1954
|
-
sequence
|
|
1955
|
-
});
|
|
1956
|
-
}
|
|
1957
|
-
}
|
|
1958
|
-
return paths;
|
|
1438
|
+
return vhtlcAllSpendingPaths(script, contract, context);
|
|
1959
1439
|
},
|
|
1960
1440
|
getSpendablePaths(script, contract, context) {
|
|
1961
|
-
|
|
1962
|
-
const paths = [];
|
|
1963
|
-
if (!role) {
|
|
1964
|
-
return paths;
|
|
1965
|
-
}
|
|
1966
|
-
const preimage = contract.params?.preimage;
|
|
1967
|
-
const refundLocktime = BigInt(contract.params.refundLocktime);
|
|
1968
|
-
if (context.collaborative) {
|
|
1969
|
-
if (role === "receiver" && preimage) {
|
|
1970
|
-
paths.push({
|
|
1971
|
-
leaf: script.claim(),
|
|
1972
|
-
extraWitness: [base.hex.decode(preimage)]
|
|
1973
|
-
});
|
|
1974
|
-
}
|
|
1975
|
-
if (role === "sender" && isCltvSatisfied(context, refundLocktime)) {
|
|
1976
|
-
paths.push({
|
|
1977
|
-
leaf: script.refundWithoutReceiver()
|
|
1978
|
-
});
|
|
1979
|
-
}
|
|
1980
|
-
return paths;
|
|
1981
|
-
}
|
|
1982
|
-
if (role === "receiver" && preimage) {
|
|
1983
|
-
const sequence = Number(contract.params.claimDelay);
|
|
1984
|
-
if (isCsvSpendable(context, sequence)) {
|
|
1985
|
-
paths.push({
|
|
1986
|
-
leaf: script.unilateralClaim(),
|
|
1987
|
-
extraWitness: [base.hex.decode(preimage)],
|
|
1988
|
-
sequence
|
|
1989
|
-
});
|
|
1990
|
-
}
|
|
1991
|
-
}
|
|
1992
|
-
if (role === "sender") {
|
|
1993
|
-
const sequence = Number(contract.params.refundNoReceiverDelay);
|
|
1994
|
-
if (isCsvSpendable(context, sequence)) {
|
|
1995
|
-
paths.push({
|
|
1996
|
-
leaf: script.unilateralRefundWithoutReceiver(),
|
|
1997
|
-
sequence
|
|
1998
|
-
});
|
|
1999
|
-
}
|
|
2000
|
-
}
|
|
2001
|
-
return paths;
|
|
1441
|
+
return vhtlcSpendablePaths(script, contract, context);
|
|
2002
1442
|
},
|
|
2003
1443
|
/**
|
|
2004
1444
|
* Refuse an explicit spend of a lockup whose refund path has not opened.
|
|
@@ -2009,70 +1449,38 @@ var VHTLCContractHandler = {
|
|
|
2009
1449
|
assertVhtlcSpendableNow(contract, context);
|
|
2010
1450
|
},
|
|
2011
1451
|
/**
|
|
2012
|
-
* Never. A live VHTLC is escrow:
|
|
2013
|
-
*
|
|
2014
|
-
* lockup out from under a swap the counterparty is still entitled to
|
|
2015
|
-
* complete, or race a claim already in flight.
|
|
2016
|
-
*
|
|
2017
|
-
* Two narrow reasons, and neither is "spending this would destroy the
|
|
2018
|
-
* VTXO". It would not: the leaf {@link deriveTapscripts} stamps is
|
|
2019
|
-
* `refundWithoutReceiver` — `CLTV[sender, server]`, the sender's OWN
|
|
2020
|
-
* refund, which the server rejects until `refundLocktime` matures. The
|
|
2021
|
-
* reasons are that an escrowed lockup must not count toward the
|
|
2022
|
-
* `available` balance bucket, and that generic RENEWAL must not silently
|
|
2023
|
-
* execute a refund the caller never asked for — `runPeriodicSettle` selects
|
|
2024
|
-
* through `getSpendableVtxos`, which this gate filters, and it runs
|
|
2025
|
-
* unprompted whenever a wallet is built without an explicit
|
|
2026
|
-
* `settlementConfig`.
|
|
1452
|
+
* Never. A live VHTLC is escrow: generic selection (send, settle, renewal, offboard) would
|
|
1453
|
+
* move the lockup out from under a swap the counterparty may still complete, or race a claim.
|
|
2027
1454
|
*
|
|
2028
|
-
*
|
|
2029
|
-
*
|
|
2030
|
-
*
|
|
2031
|
-
*
|
|
1455
|
+
* The stamped leaf is the sender's own CLTV refund, so this is not about destroying the
|
|
1456
|
+
* VTXO: an escrowed lockup must not count toward the `available` balance, and generic
|
|
1457
|
+
* renewal (`runPeriodicSettle`, unprompted without an explicit `settlementConfig`) must not
|
|
1458
|
+
* silently execute a refund nobody asked for.
|
|
2032
1459
|
*
|
|
2033
|
-
*
|
|
2034
|
-
*
|
|
1460
|
+
* **Inseparable from {@link deriveTapscripts}**: deriving the leaf without closing this gate
|
|
1461
|
+
* hands renewal an escrow. Recovery filters on {@link assertSpendableNow} instead; this
|
|
1462
|
+
* permanent gate would strand a matured lockup.
|
|
2035
1463
|
*/
|
|
2036
1464
|
isGenericallySpendable: () => false,
|
|
2037
1465
|
/**
|
|
2038
1466
|
* The annotation leaf stamped onto every VTXO locked to this contract.
|
|
2039
1467
|
*
|
|
2040
|
-
* **
|
|
2041
|
-
* `
|
|
2042
|
-
*
|
|
2043
|
-
* script version has a `forfeit()` — `VtxoScript` does not define one and
|
|
2044
|
-
* `VHTLC.BaseScript` does not add one. The fallback therefore threw
|
|
2045
|
-
* `legacy.forfeit is not a function`, `annotatableIn` caught it, and
|
|
2046
|
-
* `fetchContractVtxosBulk` dropped this contract's VTXOs before they were
|
|
2047
|
-
* persisted. The row existed and was watched while its balance stayed
|
|
2048
|
-
* permanently invisible, and `getSyncState()` reported `degraded` forever.
|
|
1468
|
+
* **Required, not an optimization.** Without it `deriveContractTapscripts` falls back to
|
|
1469
|
+
* `script.forfeit()`, which no VHTLC script has, so the contract's VTXOs are dropped before
|
|
1470
|
+
* persisting: balance invisible, `getSyncState()` degraded forever.
|
|
2049
1471
|
*
|
|
2050
|
-
* `refundWithoutReceiver` is the
|
|
2051
|
-
*
|
|
2052
|
-
*
|
|
2053
|
-
*
|
|
2054
|
-
* the receiver and need a preimage the sender does not have; `refund` and
|
|
2055
|
-
* `unilateralRefund` both need the counterparty's signature, which this
|
|
2056
|
-
* protocol has no message to ask for. V1 has no covenant leaves at all.
|
|
1472
|
+
* `refundWithoutReceiver` is the only collaborative path this wallet can satisfy as sender
|
|
1473
|
+
* (kept in step with `selectPath`): the claim leaves need the preimage, and `refund` /
|
|
1474
|
+
* `unilateralRefund` need a counterparty signature the protocol can't request. V1 has no
|
|
1475
|
+
* covenant leaves.
|
|
2057
1476
|
*
|
|
2058
|
-
* **It carries a CLTV
|
|
2059
|
-
*
|
|
2060
|
-
*
|
|
2061
|
-
*
|
|
2062
|
-
* derived per contract and knows no clock; `recoverVtxos` filters on
|
|
2063
|
-
* {@link assertSpendableNow} for it.
|
|
2064
|
-
*
|
|
2065
|
-
* **Role-blind.** A receiver's row gets the same leaf, which names keys that
|
|
2066
|
-
* wallet does not hold, so it is satisfiable only by the wallet holding the
|
|
2067
|
-
* lockup's `sender` key and fails at intent registration for anyone else.
|
|
1477
|
+
* **It carries a CLTV**: a settlement on it is rejected until `refundLocktime` matures, and
|
|
1478
|
+
* the per-contract annotation knows no clock, so `recoverVtxos` filters on
|
|
1479
|
+
* {@link assertSpendableNow}. **Role-blind**: a receiver's row gets the same leaf, satisfiable
|
|
1480
|
+
* only by the `sender` key holder; anyone else fails at intent registration.
|
|
2068
1481
|
*/
|
|
2069
1482
|
deriveTapscripts(script) {
|
|
2070
|
-
|
|
2071
|
-
return {
|
|
2072
|
-
forfeitTapLeafScript: leaf,
|
|
2073
|
-
intentTapLeafScript: leaf,
|
|
2074
|
-
tapTree: script.encode()
|
|
2075
|
-
};
|
|
1483
|
+
return deriveVhtlcTapscripts(script);
|
|
2076
1484
|
}
|
|
2077
1485
|
};
|
|
2078
1486
|
var parseGroupIndex = (raw) => {
|
|
@@ -2106,48 +1514,26 @@ var VHTLCV2ContractHandler = {
|
|
|
2106
1514
|
server: base.hex.encode(params.server),
|
|
2107
1515
|
hash: base.hex.encode(params.preimageHash),
|
|
2108
1516
|
refundLocktime: params.refundLocktime.toString(),
|
|
2109
|
-
claimDelay:
|
|
2110
|
-
refundDelay:
|
|
2111
|
-
refundNoReceiverDelay:
|
|
1517
|
+
claimDelay: chunk5XBH5SAL_cjs.timelockToSequence(params.unilateralClaimDelay).toString(),
|
|
1518
|
+
refundDelay: chunk5XBH5SAL_cjs.timelockToSequence(params.unilateralRefundDelay).toString(),
|
|
1519
|
+
refundNoReceiverDelay: chunk5XBH5SAL_cjs.timelockToSequence(
|
|
2112
1520
|
params.unilateralRefundWithoutReceiverDelay
|
|
2113
1521
|
).toString(),
|
|
2114
|
-
//
|
|
2115
|
-
//
|
|
2116
|
-
//
|
|
2117
|
-
// The group maps onto them without loss — one emulator key serves
|
|
2118
|
-
// both covenant destinations by construction (see the option's doc
|
|
2119
|
-
// on VHTLC.Options), so the two emulator-key columns always hold
|
|
2120
|
-
// the same value on a row written from here.
|
|
2121
|
-
//
|
|
2122
|
-
// Spread rather than written as `undefined`: a `Record<string,
|
|
2123
|
-
// string>` round-tripped through a repository must not gain keys
|
|
2124
|
-
// whose value is the string "undefined".
|
|
1522
|
+
// Per-leaf on-disk keys predate the grouped param and older rows carry exactly these;
|
|
1523
|
+
// both emulator columns hold the same key. Spread, not `undefined`, so a repository
|
|
1524
|
+
// round-trip never gains "undefined" string values.
|
|
2125
1525
|
...covenants && {
|
|
2126
1526
|
nonInteractiveClaimReceiverPkScript: base.hex.encode(covenants.receiverPkScript),
|
|
2127
1527
|
nonInteractiveClaimEmulatorPubkey: base.hex.encode(covenants.emulatorPubkey),
|
|
2128
1528
|
nonInteractiveRefundSenderPkScript: base.hex.encode(covenants.senderPkScript),
|
|
2129
1529
|
nonInteractiveRefundEmulatorPubkey: base.hex.encode(covenants.emulatorPubkey),
|
|
2130
|
-
// The legacy marker is
|
|
2131
|
-
// row carrying it re-derives the full suite (nine leaves), a
|
|
2132
|
-
// row lacking it the pre-timelocked-refund eight — the same
|
|
2133
|
-
// encoding older SDKs wrote for eight-leaf rows, so those rows
|
|
2134
|
-
// read back unchanged. Spread rather than a "false"/"undefined"
|
|
2135
|
-
// string: a dropped flag re-derives the EIGHT-leaf script, a
|
|
2136
|
-
// different pkScript, and registration dies at
|
|
2137
|
-
// `upsertContractRow` with an opaque `Script mismatch`.
|
|
1530
|
+
// The legacy (eight-leaf) marker is this key's ABSENCE, as older SDKs wrote it.
|
|
2138
1531
|
...covenants.legacy === void 0 && {
|
|
2139
1532
|
nonInteractiveRefundWithoutReceiver: "1"
|
|
2140
1533
|
}
|
|
2141
1534
|
},
|
|
2142
|
-
//
|
|
2143
|
-
//
|
|
2144
|
-
// these params; dropping the asset derives the SAT-ONLY script, so
|
|
2145
|
-
// registration died at `upsertContractRow` with a `Script mismatch`
|
|
2146
|
-
// naming two hex strings and no cause. Same silent-drop class
|
|
2147
|
-
// `validateOptions` refuses one layer up.
|
|
2148
|
-
//
|
|
2149
|
-
// Two keys rather than one blob, mirroring the script's own view of
|
|
2150
|
-
// an Asset ID as a (txid, groupIndex) pair.
|
|
1535
|
+
// Must round-trip: dropping the asset re-derives the sat-only script and registration
|
|
1536
|
+
// dies at `upsertContractRow` with an opaque `Script mismatch`.
|
|
2151
1537
|
...params.asset && {
|
|
2152
1538
|
assetTxid: base.hex.encode(params.asset.txid),
|
|
2153
1539
|
assetGroupIndex: params.asset.groupIndex.toString()
|
|
@@ -2208,9 +1594,9 @@ var VHTLCV2ContractHandler = {
|
|
|
2208
1594
|
preimageHash: base.hex.decode(params.hash),
|
|
2209
1595
|
refundLocktime: BigInt(params.refundLocktime),
|
|
2210
1596
|
...asset && { asset },
|
|
2211
|
-
unilateralClaimDelay:
|
|
2212
|
-
unilateralRefundDelay:
|
|
2213
|
-
unilateralRefundWithoutReceiverDelay:
|
|
1597
|
+
unilateralClaimDelay: chunk5XBH5SAL_cjs.sequenceToTimelock(Number(params.claimDelay)),
|
|
1598
|
+
unilateralRefundDelay: chunk5XBH5SAL_cjs.sequenceToTimelock(Number(params.refundDelay)),
|
|
1599
|
+
unilateralRefundWithoutReceiverDelay: chunk5XBH5SAL_cjs.sequenceToTimelock(
|
|
2214
1600
|
Number(params.refundNoReceiverDelay)
|
|
2215
1601
|
),
|
|
2216
1602
|
...claim && refund && {
|
|
@@ -2218,8 +1604,6 @@ var VHTLCV2ContractHandler = {
|
|
|
2218
1604
|
receiverPkScript: claim.destination,
|
|
2219
1605
|
senderPkScript: refund.destination,
|
|
2220
1606
|
emulatorPubkey: claim.emulatorPubkey,
|
|
2221
|
-
// Absence of the flag IS the legacy marker — the same
|
|
2222
|
-
// encoding older SDKs wrote for eight-leaf rows.
|
|
2223
1607
|
...params.nonInteractiveRefundWithoutReceiver !== "1" && {
|
|
2224
1608
|
legacy: "preTimelockedRefund"
|
|
2225
1609
|
}
|
|
@@ -2228,139 +1612,18 @@ var VHTLCV2ContractHandler = {
|
|
|
2228
1612
|
};
|
|
2229
1613
|
},
|
|
2230
1614
|
/**
|
|
2231
|
-
* Select spending path based on context.
|
|
2232
|
-
*
|
|
2233
|
-
* Role is determined from `context.role` or by matching
|
|
2234
|
-
* `context.walletDescriptor` (preferred) / `context.walletPubKey`
|
|
2235
|
-
* against sender/receiver in contract params.
|
|
1615
|
+
* Select spending path based on context. Role comes from `context.role` or by matching
|
|
1616
|
+
* `context.walletDescriptor` against sender/receiver.
|
|
2236
1617
|
*/
|
|
2237
1618
|
selectPath(script, contract, context) {
|
|
2238
|
-
|
|
2239
|
-
const preimage = contract.params?.preimage;
|
|
2240
|
-
const refundLocktime = BigInt(contract.params.refundLocktime);
|
|
2241
|
-
if (!role) {
|
|
2242
|
-
return null;
|
|
2243
|
-
}
|
|
2244
|
-
if (context.collaborative) {
|
|
2245
|
-
if (role === "receiver" && preimage) {
|
|
2246
|
-
return {
|
|
2247
|
-
leaf: script.claim(),
|
|
2248
|
-
extraWitness: [base.hex.decode(preimage)]
|
|
2249
|
-
};
|
|
2250
|
-
}
|
|
2251
|
-
if (role === "sender" && isCltvSatisfied(context, refundLocktime)) {
|
|
2252
|
-
return {
|
|
2253
|
-
leaf: script.refundWithoutReceiver()
|
|
2254
|
-
};
|
|
2255
|
-
}
|
|
2256
|
-
return null;
|
|
2257
|
-
}
|
|
2258
|
-
if (role === "receiver" && preimage) {
|
|
2259
|
-
const sequence = Number(contract.params.claimDelay);
|
|
2260
|
-
if (!isCsvSpendable(context, sequence)) return null;
|
|
2261
|
-
return {
|
|
2262
|
-
leaf: script.unilateralClaim(),
|
|
2263
|
-
extraWitness: [base.hex.decode(preimage)],
|
|
2264
|
-
sequence
|
|
2265
|
-
};
|
|
2266
|
-
}
|
|
2267
|
-
if (role === "sender") {
|
|
2268
|
-
const sequence = Number(contract.params.refundNoReceiverDelay);
|
|
2269
|
-
if (!isCsvSpendable(context, sequence)) return null;
|
|
2270
|
-
return {
|
|
2271
|
-
leaf: script.unilateralRefundWithoutReceiver(),
|
|
2272
|
-
sequence
|
|
2273
|
-
};
|
|
2274
|
-
}
|
|
2275
|
-
return null;
|
|
1619
|
+
return selectVhtlcPath(script, contract, context);
|
|
2276
1620
|
},
|
|
2277
|
-
/**
|
|
2278
|
-
* Get all possible spending paths (no timelock checks).
|
|
2279
|
-
*
|
|
2280
|
-
* Role is determined from `context.role` or by matching
|
|
2281
|
-
* `context.walletDescriptor` (preferred) / `context.walletPubKey`
|
|
2282
|
-
* against sender/receiver in contract params.
|
|
2283
|
-
*/
|
|
1621
|
+
/** Get all possible spending paths (no timelock checks); role resolved as in `selectPath`. */
|
|
2284
1622
|
getAllSpendingPaths(script, contract, context) {
|
|
2285
|
-
|
|
2286
|
-
const paths = [];
|
|
2287
|
-
if (!role) {
|
|
2288
|
-
return paths;
|
|
2289
|
-
}
|
|
2290
|
-
const preimage = contract.params?.preimage;
|
|
2291
|
-
if (context.collaborative) {
|
|
2292
|
-
if (role === "receiver" && preimage) {
|
|
2293
|
-
paths.push({
|
|
2294
|
-
leaf: script.claim(),
|
|
2295
|
-
extraWitness: [base.hex.decode(preimage)]
|
|
2296
|
-
});
|
|
2297
|
-
}
|
|
2298
|
-
if (role === "sender") {
|
|
2299
|
-
paths.push({
|
|
2300
|
-
leaf: script.refundWithoutReceiver()
|
|
2301
|
-
});
|
|
2302
|
-
}
|
|
2303
|
-
} else {
|
|
2304
|
-
if (role === "receiver" && preimage) {
|
|
2305
|
-
const sequence = Number(contract.params.claimDelay);
|
|
2306
|
-
paths.push({
|
|
2307
|
-
leaf: script.unilateralClaim(),
|
|
2308
|
-
extraWitness: [base.hex.decode(preimage)],
|
|
2309
|
-
sequence
|
|
2310
|
-
});
|
|
2311
|
-
}
|
|
2312
|
-
if (role === "sender") {
|
|
2313
|
-
const sequence = Number(contract.params.refundNoReceiverDelay);
|
|
2314
|
-
paths.push({
|
|
2315
|
-
leaf: script.unilateralRefundWithoutReceiver(),
|
|
2316
|
-
sequence
|
|
2317
|
-
});
|
|
2318
|
-
}
|
|
2319
|
-
}
|
|
2320
|
-
return paths;
|
|
1623
|
+
return vhtlcAllSpendingPaths(script, contract, context);
|
|
2321
1624
|
},
|
|
2322
1625
|
getSpendablePaths(script, contract, context) {
|
|
2323
|
-
|
|
2324
|
-
const paths = [];
|
|
2325
|
-
if (!role) {
|
|
2326
|
-
return paths;
|
|
2327
|
-
}
|
|
2328
|
-
const preimage = contract.params?.preimage;
|
|
2329
|
-
const refundLocktime = BigInt(contract.params.refundLocktime);
|
|
2330
|
-
if (context.collaborative) {
|
|
2331
|
-
if (role === "receiver" && preimage) {
|
|
2332
|
-
paths.push({
|
|
2333
|
-
leaf: script.claim(),
|
|
2334
|
-
extraWitness: [base.hex.decode(preimage)]
|
|
2335
|
-
});
|
|
2336
|
-
}
|
|
2337
|
-
if (role === "sender" && isCltvSatisfied(context, refundLocktime)) {
|
|
2338
|
-
paths.push({
|
|
2339
|
-
leaf: script.refundWithoutReceiver()
|
|
2340
|
-
});
|
|
2341
|
-
}
|
|
2342
|
-
return paths;
|
|
2343
|
-
}
|
|
2344
|
-
if (role === "receiver" && preimage) {
|
|
2345
|
-
const sequence = Number(contract.params.claimDelay);
|
|
2346
|
-
if (isCsvSpendable(context, sequence)) {
|
|
2347
|
-
paths.push({
|
|
2348
|
-
leaf: script.unilateralClaim(),
|
|
2349
|
-
extraWitness: [base.hex.decode(preimage)],
|
|
2350
|
-
sequence
|
|
2351
|
-
});
|
|
2352
|
-
}
|
|
2353
|
-
}
|
|
2354
|
-
if (role === "sender") {
|
|
2355
|
-
const sequence = Number(contract.params.refundNoReceiverDelay);
|
|
2356
|
-
if (isCsvSpendable(context, sequence)) {
|
|
2357
|
-
paths.push({
|
|
2358
|
-
leaf: script.unilateralRefundWithoutReceiver(),
|
|
2359
|
-
sequence
|
|
2360
|
-
});
|
|
2361
|
-
}
|
|
2362
|
-
}
|
|
2363
|
-
return paths;
|
|
1626
|
+
return vhtlcSpendablePaths(script, contract, context);
|
|
2364
1627
|
},
|
|
2365
1628
|
/**
|
|
2366
1629
|
* Refuse an explicit spend of a lockup whose refund path has not opened.
|
|
@@ -2370,62 +1633,28 @@ var VHTLCV2ContractHandler = {
|
|
|
2370
1633
|
assertVhtlcSpendableNow(contract, context);
|
|
2371
1634
|
},
|
|
2372
1635
|
/**
|
|
2373
|
-
* Never. A live VHTLC is escrow
|
|
2374
|
-
*
|
|
2375
|
-
*
|
|
2376
|
-
*
|
|
2377
|
-
*
|
|
2378
|
-
*
|
|
2379
|
-
* The gate covers `available` and renewal. Recovery is generic and names
|
|
2380
|
-
* nothing, so it is not covered here: `recoverVtxos` filters on
|
|
2381
|
-
* {@link assertSpendableNow} instead, which drops a lockup only while its
|
|
2382
|
-
* refund path is shut rather than forever. The explicit routes out —
|
|
2383
|
-
* `settle({ inputs })`, or `@arkade-os/swap`'s `pushRefundWithoutReceiver`
|
|
2384
|
-
* over `findLockupVtxos`' outpoints — are unaffected either way.
|
|
1636
|
+
* Never. A live VHTLC is escrow with the counterparty's claim leaf armed; generic selection
|
|
1637
|
+
* (send, settle, renewal, offboard) would move it out from under the swap or race a claim.
|
|
1638
|
+
* Recovery isn't covered by this gate: `recoverVtxos` filters on {@link assertSpendableNow},
|
|
1639
|
+
* dropping a lockup only while its refund path is shut. Explicit routes (`settle({ inputs })`,
|
|
1640
|
+
* `pushRefundWithoutReceiver`) are unaffected.
|
|
2385
1641
|
*/
|
|
2386
1642
|
isGenericallySpendable: () => false,
|
|
2387
1643
|
/**
|
|
2388
1644
|
* The annotation leaf stamped onto every VTXO locked to this contract.
|
|
2389
1645
|
*
|
|
2390
|
-
*
|
|
2391
|
-
* `
|
|
2392
|
-
*
|
|
2393
|
-
* script version has a `forfeit()` — `VtxoScript` does not define one and
|
|
2394
|
-
* `VHTLC.BaseScript` does not add one. The fallback therefore throws
|
|
2395
|
-
* `legacy.forfeit is not a function`, `annotatableIn` catches it, and
|
|
2396
|
-
* `fetchContractVtxosBulk` drops this contract's VTXOs before they are
|
|
2397
|
-
* persisted. The row would exist and be watched while its balance stayed
|
|
2398
|
-
* permanently invisible, and `getSyncState()` would report `degraded`
|
|
2399
|
-
* forever. (The `vhtlc` handler had the same gap and now closes it the same
|
|
2400
|
-
* way; nothing registers V1 rows through `ContractManager` in this repo, so
|
|
2401
|
-
* it was never hit here.)
|
|
2402
|
-
*
|
|
2403
|
-
* `refundWithoutReceiver` is the leaf, for both roles the annotation
|
|
2404
|
-
* serves, because it is the only collaborative path this wallet can
|
|
2405
|
-
* actually satisfy as the sender — the same conclusion `selectPath`
|
|
2406
|
-
* reaches, kept in step with it deliberately. The claim leaves belong to
|
|
2407
|
-
* the receiver and need a preimage the sender does not have; `refund` and
|
|
2408
|
-
* `unilateralRefund` need the counterparty; the covenant leaves are the
|
|
2409
|
-
* emulator's.
|
|
2410
|
-
*
|
|
2411
|
-
* **It carries a CLTV, and callers must respect it.** A settlement built on
|
|
2412
|
-
* this leaf is only valid once `refundLocktime` has matured, so a recovery
|
|
2413
|
-
* round that sweeps this VTXO early is rejected by the server. Nothing in
|
|
2414
|
-
* this handler can enforce it, because the annotation is derived per
|
|
2415
|
-
* contract and knows no clock. `recoverVtxos` filters on
|
|
2416
|
-
* {@link assertSpendableNow} for it.
|
|
1646
|
+
* Required, not an optimization: without {@link TapscriptDeriving} the fallback calls
|
|
1647
|
+
* `script.forfeit()`, which no VHTLC version has, so the VTXOs are silently dropped before
|
|
1648
|
+
* persisting and `getSyncState()` stays `degraded`.
|
|
2417
1649
|
*
|
|
2418
|
-
*
|
|
2419
|
-
*
|
|
2420
|
-
*
|
|
1650
|
+
* `refundWithoutReceiver` is used (in step with `selectPath`) as the only collaborative leaf
|
|
1651
|
+
* the sender can satisfy. It carries a CLTV: settling on it before `refundLocktime` matures is
|
|
1652
|
+
* rejected, and this handler has no clock, so `recoverVtxos` filters on
|
|
1653
|
+
* {@link assertSpendableNow}. Role-blind: a receiver's row gets the same leaf and fails at
|
|
1654
|
+
* intent registration.
|
|
2421
1655
|
*/
|
|
2422
1656
|
deriveTapscripts(script) {
|
|
2423
|
-
|
|
2424
|
-
return {
|
|
2425
|
-
forfeitTapLeafScript: leaf,
|
|
2426
|
-
intentTapLeafScript: leaf,
|
|
2427
|
-
tapTree: script.encode()
|
|
2428
|
-
};
|
|
1657
|
+
return deriveVhtlcTapscripts(script);
|
|
2429
1658
|
}
|
|
2430
1659
|
};
|
|
2431
1660
|
var BoardingContractHandler = {
|
|
@@ -2451,24 +1680,10 @@ var BoardingContractHandler = {
|
|
|
2451
1680
|
/** Preserves today's settle/board behaviour. */
|
|
2452
1681
|
isGenericallySpendable: () => true,
|
|
2453
1682
|
/**
|
|
2454
|
-
* Probe the on-chain
|
|
2455
|
-
*
|
|
2456
|
-
*
|
|
2457
|
-
*
|
|
2458
|
-
* boarding output becomes an L2 VTXO at the receive index, so the
|
|
2459
|
-
* indexer probe already keeps the gap window open for it; only an
|
|
2460
|
-
* *unspent* boarding output needs the on-chain probe (see plan §2).
|
|
2461
|
-
*
|
|
2462
|
-
* No-ops (returns `[]`) when boarding discovery is not plumbed — i.e.
|
|
2463
|
-
* `deps.boardingTimelock` or `deps.onchainNetwork` is absent — so the
|
|
2464
|
-
* scanner unit harness (which sets neither) is unaffected.
|
|
2465
|
-
*
|
|
2466
|
-
* Always emits `type: "boarding"`, even in the degenerate equal-delay case
|
|
2467
|
-
* where the boarding script is byte-identical to a `default` script at this
|
|
2468
|
-
* index (`boardingExitDelay === unilateralExitDelay`). The collision is no
|
|
2469
|
-
* longer pre-judged in discovery; it is tolerated FIRST-WINS at the
|
|
2470
|
-
* persistence layer ({@link ContractManager.upsertContract}). `deps.csvTimelocks`
|
|
2471
|
-
* is intentionally not read here.
|
|
1683
|
+
* Probe the **current** on-chain coin set for a boarding output at this HD index. Only an
|
|
1684
|
+
* unspent boarding output needs this: a boarded one became an L2 VTXO at the receive index,
|
|
1685
|
+
* which the indexer probe already covers. Always emits `type: "boarding"` (see the handler
|
|
1686
|
+
* doc on collisions); `deps.csvTimelocks` is intentionally not read.
|
|
2472
1687
|
*/
|
|
2473
1688
|
async discoverAt(index, descriptor, deps) {
|
|
2474
1689
|
if (!deps.boardingTimelock || !deps.onchainNetwork) return [];
|
|
@@ -2482,26 +1697,19 @@ var BoardingContractHandler = {
|
|
|
2482
1697
|
const coins = await deps.onchainProvider.getCoins(onchainAddress);
|
|
2483
1698
|
if (coins.length === 0) return [];
|
|
2484
1699
|
const scriptHex = base.hex.encode(script.pkScript);
|
|
2485
|
-
const boardingSeq = chunkJZWLXNHV_cjs.timelockToSequence(deps.boardingTimelock);
|
|
2486
1700
|
return [
|
|
2487
1701
|
{
|
|
2488
1702
|
type: "boarding",
|
|
2489
|
-
params: {
|
|
2490
|
-
pubKey
|
|
2491
|
-
serverPubKey:
|
|
2492
|
-
csvTimelock:
|
|
2493
|
-
},
|
|
1703
|
+
params: BoardingContractHandler.serializeParams({
|
|
1704
|
+
pubKey,
|
|
1705
|
+
serverPubKey: deps.serverPubKey,
|
|
1706
|
+
csvTimelock: deps.boardingTimelock
|
|
1707
|
+
}),
|
|
2494
1708
|
script: scriptHex,
|
|
2495
|
-
// The
|
|
2496
|
-
//
|
|
2497
|
-
// ContractWatcher keeps monitoring the same L2 script and the
|
|
2498
|
-
// VTXO repository bucket lines up (plan §6-I.4). The P2TR is
|
|
2499
|
-
// recomputed from params only for the `getCoins` probe.
|
|
1709
|
+
// The Ark address, not the P2TR: must match the row registered at init so the
|
|
1710
|
+
// watcher monitors the same L2 script and the VTXO repository bucket lines up.
|
|
2500
1711
|
address: script.address(deps.network.hrp, deps.serverPubKey).encode(),
|
|
2501
|
-
// Tag rotated rows (index > 0)
|
|
2502
|
-
// newest boarding address and descriptor-aware signing can
|
|
2503
|
-
// recover the per-index key (plan §6-II/§6-III.3). The index-0
|
|
2504
|
-
// baseline stays untagged, matching `default`/`delegate`.
|
|
1712
|
+
// Tag rotated rows (index > 0) for boot resolution and per-index signing.
|
|
2505
1713
|
...rotatedReceiveMetadata(index, descriptor)
|
|
2506
1714
|
}
|
|
2507
1715
|
];
|
|
@@ -2528,6 +1736,17 @@ function resolveTimelockValue(value, args) {
|
|
|
2528
1736
|
`invalid timelock value '${value}' \u2014 expected a bigint or a '$param' reference`
|
|
2529
1737
|
);
|
|
2530
1738
|
}
|
|
1739
|
+
function resolveCsvTimelock(csv, args) {
|
|
1740
|
+
const value = resolveTimelockValue(csv.value, args);
|
|
1741
|
+
if (csv.type !== "sequence") return { type: csv.type, value };
|
|
1742
|
+
const timelock = chunk5XBH5SAL_cjs.sequenceToCanonicalTimelock(value);
|
|
1743
|
+
if (!timelock) {
|
|
1744
|
+
throw new Error(
|
|
1745
|
+
`csv '${csv.value}' resolved to ${value}, which is not a canonical BIP68 sequence`
|
|
1746
|
+
);
|
|
1747
|
+
}
|
|
1748
|
+
return timelock;
|
|
1749
|
+
}
|
|
2531
1750
|
function resolveAsm(asm, bind) {
|
|
2532
1751
|
const tokens = asm.map((t) => {
|
|
2533
1752
|
if (typeof t === "string" && t.startsWith("$")) {
|
|
@@ -2576,6 +1795,7 @@ function collectParamRefs(program) {
|
|
|
2576
1795
|
const collect = (items) => {
|
|
2577
1796
|
for (const t of items ?? []) {
|
|
2578
1797
|
if (typeof t === "string" && t.startsWith("$")) refs.add(t.slice(1));
|
|
1798
|
+
else if (isTweakedSigner(t) && t.tweak.startsWith("$")) refs.add(t.tweak.slice(1));
|
|
2579
1799
|
}
|
|
2580
1800
|
};
|
|
2581
1801
|
for (const fn of Object.values(program.functions)) {
|
|
@@ -2628,10 +1848,15 @@ function validateProgram(program, args) {
|
|
|
2628
1848
|
if (typeof p !== "string") validateParamValue(p, args[p.name]);
|
|
2629
1849
|
}
|
|
2630
1850
|
}
|
|
1851
|
+
function isTweakedSigner(ref) {
|
|
1852
|
+
if (typeof ref !== "object" || ref === null || ref instanceof Uint8Array) return false;
|
|
1853
|
+
const { tweak, fn } = ref;
|
|
1854
|
+
return typeof tweak === "string" && typeof fn === "string";
|
|
1855
|
+
}
|
|
2631
1856
|
function resolveSigner(ref, args) {
|
|
2632
1857
|
if (ref instanceof Uint8Array) return ref;
|
|
2633
|
-
if (!ref.startsWith("$")) {
|
|
2634
|
-
throw new Error(`unknown signer reference '${ref}' \u2014 use '
|
|
1858
|
+
if (typeof ref !== "string" || !ref.startsWith("$")) {
|
|
1859
|
+
throw new Error(`unknown signer reference '${ref}' \u2014 use a '$param' or key bytes`);
|
|
2635
1860
|
}
|
|
2636
1861
|
const v = bindValue(args, ref.slice(1));
|
|
2637
1862
|
if (!(v instanceof Uint8Array)) {
|
|
@@ -2641,29 +1866,29 @@ function resolveSigner(ref, args) {
|
|
|
2641
1866
|
}
|
|
2642
1867
|
function encodeTapscriptSegment(seg, pubkeys, args) {
|
|
2643
1868
|
if (seg.csv) {
|
|
2644
|
-
const timelock =
|
|
1869
|
+
const timelock = resolveCsvTimelock(seg.csv, args);
|
|
2645
1870
|
if (seg.asm) {
|
|
2646
|
-
return
|
|
1871
|
+
return chunk5XBH5SAL_cjs.ConditionCSVMultisigTapscript.encode({
|
|
2647
1872
|
conditionScript: resolveAsm(seg.asm, args),
|
|
2648
1873
|
timelock,
|
|
2649
1874
|
pubkeys
|
|
2650
1875
|
});
|
|
2651
1876
|
}
|
|
2652
|
-
return
|
|
1877
|
+
return chunk5XBH5SAL_cjs.CSVMultisigTapscript.encode({ timelock, pubkeys });
|
|
2653
1878
|
}
|
|
2654
1879
|
if (seg.cltv !== void 0) {
|
|
2655
|
-
return
|
|
1880
|
+
return chunk5XBH5SAL_cjs.CLTVMultisigTapscript.encode({
|
|
2656
1881
|
absoluteTimelock: resolveTimelockValue(seg.cltv, args),
|
|
2657
1882
|
pubkeys
|
|
2658
1883
|
});
|
|
2659
1884
|
}
|
|
2660
1885
|
if (seg.asm) {
|
|
2661
|
-
return
|
|
1886
|
+
return chunk5XBH5SAL_cjs.ConditionMultisigTapscript.encode({
|
|
2662
1887
|
conditionScript: resolveAsm(seg.asm, args),
|
|
2663
1888
|
pubkeys
|
|
2664
1889
|
});
|
|
2665
1890
|
}
|
|
2666
|
-
return
|
|
1891
|
+
return chunk5XBH5SAL_cjs.MultisigTapscript.encode({ pubkeys });
|
|
2667
1892
|
}
|
|
2668
1893
|
function compileFunctions(program, args, keys) {
|
|
2669
1894
|
if (program.version !== SUPPORTED_PROGRAM_VERSION) {
|
|
@@ -2686,14 +1911,26 @@ function compileFunctions(program, args, keys) {
|
|
|
2686
1911
|
}
|
|
2687
1912
|
return defs.map((def, i) => {
|
|
2688
1913
|
validateTapscript(def.tapscript);
|
|
2689
|
-
const pubkeys = def.tapscript.signers.map((
|
|
1914
|
+
const pubkeys = def.tapscript.signers.map((signer) => {
|
|
1915
|
+
if (!isTweakedSigner(signer)) return resolveSigner(signer, args);
|
|
1916
|
+
const asm = functions[signer.fn]?.arkadeScript?.asm;
|
|
1917
|
+
if (!asm) {
|
|
1918
|
+
throw new Error(
|
|
1919
|
+
`ArkadeContract: function '${names[i]}' tweaks '${signer.fn}', which has no arkade script`
|
|
1920
|
+
);
|
|
1921
|
+
}
|
|
1922
|
+
return computeArkadeScriptPublicKey(
|
|
1923
|
+
resolveSigner(signer.tweak, args),
|
|
1924
|
+
resolveAsm(asm, args)
|
|
1925
|
+
);
|
|
1926
|
+
});
|
|
2690
1927
|
const arkadeScript = def.arkadeScript ? resolveAsm(def.arkadeScript.asm, args) : void 0;
|
|
2691
|
-
const leafPubkeys = arkadeScript ? [...pubkeys, computeArkadeScriptPublicKey(keys.emulatorKey, arkadeScript)] : pubkeys;
|
|
1928
|
+
const leafPubkeys = arkadeScript && def.tapscript.emulator !== null ? [...pubkeys, computeArkadeScriptPublicKey(keys.emulatorKey, arkadeScript)] : pubkeys;
|
|
2692
1929
|
const leafScript = encodeTapscriptSegment(def.tapscript, leafPubkeys, args).script;
|
|
2693
1930
|
return { name: names[i], def, leafScript, arkadeScript, signerKeys: pubkeys };
|
|
2694
1931
|
});
|
|
2695
1932
|
}
|
|
2696
|
-
var ArkadeProgramScript = class extends
|
|
1933
|
+
var ArkadeProgramScript = class extends chunk5XBH5SAL_cjs.VtxoScript {
|
|
2697
1934
|
constructor(program, args, keys) {
|
|
2698
1935
|
const partial = compileFunctions(program, args, keys);
|
|
2699
1936
|
super(partial.map((p) => p.leafScript));
|
|
@@ -2716,17 +1953,31 @@ var ArkadeProgramScript = class extends chunkJZWLXNHV_cjs.VtxoScript {
|
|
|
2716
1953
|
}
|
|
2717
1954
|
};
|
|
2718
1955
|
function parseArtifact(artifact) {
|
|
1956
|
+
if (Array.isArray(artifact.functions)) {
|
|
1957
|
+
throw new Error(
|
|
1958
|
+
"parseArtifact: `functions` is an array, which is the arkadec artifact shape, not an SDK program \u2014 read it with programFromArtifact instead"
|
|
1959
|
+
);
|
|
1960
|
+
}
|
|
1961
|
+
if (typeof artifact.functions !== "object" || artifact.functions === null) {
|
|
1962
|
+
throw new Error("parseArtifact: `functions` must be an object keyed by function name");
|
|
1963
|
+
}
|
|
2719
1964
|
const hexToken = (t) => typeof t === "string" && t.startsWith("0x") ? base.hex.decode(t.slice(2)) : t;
|
|
1965
|
+
const signerRef = (s) => {
|
|
1966
|
+
if (s instanceof Uint8Array || typeof s === "string") return hexToken(s);
|
|
1967
|
+
if (isTweakedSigner(s)) return { tweak: s.tweak, fn: s.fn };
|
|
1968
|
+
throw new Error("parseArtifact: a tweaked signer needs string `tweak` and `fn`");
|
|
1969
|
+
};
|
|
2720
1970
|
const timelockValue = (v) => typeof v === "string" && v.startsWith("$") ? v : BigInt(v);
|
|
2721
1971
|
const functions = {};
|
|
2722
1972
|
for (const [name, fn] of Object.entries(artifact.functions)) {
|
|
2723
1973
|
const tap = fn.tapscript ?? {};
|
|
2724
1974
|
const tapscript = {
|
|
2725
|
-
signers: (tap.signers ?? []).map(
|
|
1975
|
+
signers: (tap.signers ?? []).map(signerRef),
|
|
2726
1976
|
...tap.asm ? { asm: tap.asm.map(hexToken) } : {},
|
|
2727
1977
|
...tap.witness ? { witness: tap.witness.map(hexToken) } : {},
|
|
2728
1978
|
...tap.csv ? { csv: { type: tap.csv.type, value: timelockValue(tap.csv.value) } } : {},
|
|
2729
|
-
...tap.cltv !== void 0 ? { cltv: timelockValue(tap.cltv) } : {}
|
|
1979
|
+
...tap.cltv !== void 0 ? { cltv: timelockValue(tap.cltv) } : {},
|
|
1980
|
+
..."emulator" in tap ? { emulator: tap.emulator } : {}
|
|
2730
1981
|
};
|
|
2731
1982
|
const arkadeScript = fn.arkadeScript ? {
|
|
2732
1983
|
asm: fn.arkadeScript.asm.map(hexToken),
|
|
@@ -2766,7 +2017,8 @@ function stringifyArtifact(program) {
|
|
|
2766
2017
|
...tap.asm ? { asm: tap.asm.map(token) } : {},
|
|
2767
2018
|
...tap.witness ? { witness: tap.witness.map(token) } : {},
|
|
2768
2019
|
...tap.csv ? { csv: { type: tap.csv.type, value: tap.csv.value.toString() } } : {},
|
|
2769
|
-
...tap.cltv !== void 0 ? { cltv: tap.cltv.toString() } : {}
|
|
2020
|
+
...tap.cltv !== void 0 ? { cltv: tap.cltv.toString() } : {},
|
|
2021
|
+
...tap.emulator !== void 0 ? { emulator: tap.emulator } : {}
|
|
2770
2022
|
},
|
|
2771
2023
|
...fn.arkadeScript ? {
|
|
2772
2024
|
arkadeScript: {
|
|
@@ -2852,22 +2104,12 @@ function deserializeArkadeContractParams(params) {
|
|
|
2852
2104
|
|
|
2853
2105
|
// src/contracts/handlers/arkade.ts
|
|
2854
2106
|
function walletKeyFrom(context) {
|
|
2855
|
-
|
|
2856
|
-
|
|
2857
|
-
|
|
2858
|
-
|
|
2859
|
-
|
|
2860
|
-
return void 0;
|
|
2861
|
-
}
|
|
2862
|
-
};
|
|
2863
|
-
if (context.walletDescriptor) {
|
|
2864
|
-
const key = extract(context.walletDescriptor);
|
|
2865
|
-
if (key) return key;
|
|
2866
|
-
}
|
|
2867
|
-
if (context.walletPubKey) {
|
|
2868
|
-
return extract(context.walletPubKey);
|
|
2107
|
+
if (!context.walletDescriptor) return void 0;
|
|
2108
|
+
try {
|
|
2109
|
+
return extractPubKey(context.walletDescriptor).toLowerCase();
|
|
2110
|
+
} catch {
|
|
2111
|
+
return void 0;
|
|
2869
2112
|
}
|
|
2870
|
-
return void 0;
|
|
2871
2113
|
}
|
|
2872
2114
|
function staticWitness(fn, script) {
|
|
2873
2115
|
const refs = fn.def.tapscript.witness ?? [];
|
|
@@ -2892,7 +2134,7 @@ function pathsFor(script, context, opts) {
|
|
|
2892
2134
|
continue;
|
|
2893
2135
|
}
|
|
2894
2136
|
const csvDef = fn.def.tapscript.csv;
|
|
2895
|
-
const csv = csvDef ?
|
|
2137
|
+
const csv = csvDef ? resolveCsvTimelock(csvDef, script.args) : void 0;
|
|
2896
2138
|
const cltv = fn.def.tapscript.cltv !== void 0 ? resolveTimelockValue(fn.def.tapscript.cltv, script.args) : void 0;
|
|
2897
2139
|
if (context.collaborative) {
|
|
2898
2140
|
if (csv) continue;
|
|
@@ -2906,7 +2148,7 @@ function pathsFor(script, context, opts) {
|
|
|
2906
2148
|
continue;
|
|
2907
2149
|
}
|
|
2908
2150
|
if (requiresServer) continue;
|
|
2909
|
-
const sequence = csv ? Number(
|
|
2151
|
+
const sequence = csv ? Number(chunk5XBH5SAL_cjs.timelockToSequence(csv)) : void 0;
|
|
2910
2152
|
if (opts.checkTimelocks && csv && !isCsvSpendable(context, sequence)) continue;
|
|
2911
2153
|
if (opts.checkTimelocks && cltv !== void 0 && !isCltvSatisfied(context, cltv)) {
|
|
2912
2154
|
continue;
|
|
@@ -3016,6 +2258,7 @@ exports.deriveDescriptorLeafCompressedPubKey = deriveDescriptorLeafCompressedPub
|
|
|
3016
2258
|
exports.deriveDescriptorLeafPubKey = deriveDescriptorLeafPubKey;
|
|
3017
2259
|
exports.descriptorIsOurs = descriptorIsOurs;
|
|
3018
2260
|
exports.deserializeArkadeContractParams = deserializeArkadeContractParams;
|
|
2261
|
+
exports.extractPubKey = extractPubKey;
|
|
3019
2262
|
exports.fromASM = fromASM;
|
|
3020
2263
|
exports.getOpcodeName = getOpcodeName;
|
|
3021
2264
|
exports.getOpcodeValue = getOpcodeValue;
|
|
@@ -3035,5 +2278,5 @@ exports.toASM = toASM;
|
|
|
3035
2278
|
exports.toXOnly = toXOnly;
|
|
3036
2279
|
exports.validateProgram = validateProgram;
|
|
3037
2280
|
exports.witnessRefToBytes = witnessRefToBytes;
|
|
3038
|
-
//# sourceMappingURL=chunk-
|
|
3039
|
-
//# sourceMappingURL=chunk-
|
|
2281
|
+
//# sourceMappingURL=chunk-GVF4OCTL.cjs.map
|
|
2282
|
+
//# sourceMappingURL=chunk-GVF4OCTL.cjs.map
|