@arkade-os/sdk 0.4.22 → 0.4.24
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 +116 -13
- package/dist/cjs/contracts/arkcontract.js +2 -1
- package/dist/cjs/contracts/contractManager.js +29 -4
- package/dist/cjs/contracts/contractWatcher.js +9 -3
- package/dist/cjs/contracts/handlers/default.js +3 -2
- package/dist/cjs/contracts/handlers/delegate.js +3 -2
- package/dist/cjs/contracts/handlers/helpers.js +2 -58
- package/dist/cjs/contracts/handlers/vhtlc.js +7 -6
- package/dist/cjs/contracts/vtxoOwnership.js +60 -0
- package/dist/cjs/identity/descriptor.js +75 -4
- package/dist/cjs/identity/hdCapableIdentity.js +2 -0
- package/dist/cjs/identity/seedIdentity.js +225 -103
- package/dist/cjs/identity/serialize.js +5 -0
- package/dist/cjs/identity/staticDescriptorProvider.js +1 -1
- package/dist/cjs/index.js +12 -3
- package/dist/cjs/providers/electrum.js +285 -79
- package/dist/cjs/providers/expoIndexer.js +1 -1
- package/dist/cjs/providers/indexer.js +2 -2
- package/dist/cjs/providers/onchain.js +9 -3
- package/dist/cjs/repositories/migrations/walletRepositoryImpl.js +6 -2
- package/dist/cjs/repositories/realm/walletRepository.js +2 -2
- package/dist/cjs/repositories/serialization.js +34 -1
- package/dist/cjs/repositories/sqlite/walletRepository.js +4 -2
- package/dist/cjs/script/address.js +2 -1
- package/dist/cjs/script/base.js +12 -47
- package/dist/cjs/script/tapscript.js +97 -73
- package/dist/cjs/utils/timelock.js +59 -0
- package/dist/cjs/utils/transactionHistory.js +4 -4
- package/dist/cjs/utils/unknownFields.js +2 -39
- package/dist/cjs/wallet/asset-manager.js +18 -18
- package/dist/cjs/wallet/asset.js +10 -8
- package/dist/cjs/wallet/delegator.js +2 -2
- package/dist/cjs/wallet/hdDescriptorProvider.js +159 -0
- package/dist/cjs/wallet/index.js +5 -1
- package/dist/cjs/wallet/onchain.js +2 -1
- package/dist/cjs/wallet/serviceWorker/wallet-message-handler.js +60 -10
- package/dist/cjs/wallet/serviceWorker/wallet.js +5 -4
- package/dist/cjs/wallet/unroll.js +79 -67
- package/dist/cjs/wallet/validation.js +2 -3
- package/dist/cjs/wallet/wallet.js +91 -22
- package/dist/cjs/worker/expo/processors/contractPollProcessor.js +7 -2
- package/dist/esm/contracts/arkcontract.js +2 -1
- package/dist/esm/contracts/contractManager.js +29 -4
- package/dist/esm/contracts/contractWatcher.js +9 -3
- package/dist/esm/contracts/handlers/default.js +2 -1
- package/dist/esm/contracts/handlers/delegate.js +2 -1
- package/dist/esm/contracts/handlers/helpers.js +1 -22
- package/dist/esm/contracts/handlers/vhtlc.js +2 -1
- package/dist/esm/contracts/vtxoOwnership.js +53 -0
- package/dist/esm/identity/descriptor.js +74 -5
- package/dist/esm/identity/hdCapableIdentity.js +1 -0
- package/dist/esm/identity/seedIdentity.js +225 -103
- package/dist/esm/identity/serialize.js +5 -0
- package/dist/esm/identity/staticDescriptorProvider.js +1 -1
- package/dist/esm/index.js +7 -4
- package/dist/esm/providers/electrum.js +284 -78
- package/dist/esm/providers/expoIndexer.js +1 -1
- package/dist/esm/providers/indexer.js +2 -2
- package/dist/esm/providers/onchain.js +9 -3
- package/dist/esm/repositories/migrations/walletRepositoryImpl.js +6 -2
- package/dist/esm/repositories/realm/walletRepository.js +3 -3
- package/dist/esm/repositories/serialization.js +27 -0
- package/dist/esm/repositories/sqlite/walletRepository.js +5 -3
- package/dist/esm/script/address.js +2 -1
- package/dist/esm/script/base.js +12 -14
- package/dist/esm/script/tapscript.js +97 -40
- package/dist/esm/utils/timelock.js +22 -0
- package/dist/esm/utils/transactionHistory.js +4 -4
- package/dist/esm/utils/unknownFields.js +2 -6
- package/dist/esm/wallet/asset-manager.js +18 -18
- package/dist/esm/wallet/asset.js +10 -8
- package/dist/esm/wallet/delegator.js +2 -2
- package/dist/esm/wallet/hdDescriptorProvider.js +155 -0
- package/dist/esm/wallet/index.js +4 -0
- package/dist/esm/wallet/onchain.js +2 -1
- package/dist/esm/wallet/serviceWorker/wallet-message-handler.js +60 -10
- package/dist/esm/wallet/serviceWorker/wallet.js +5 -4
- package/dist/esm/wallet/unroll.js +78 -67
- package/dist/esm/wallet/validation.js +2 -3
- package/dist/esm/wallet/wallet.js +88 -20
- package/dist/esm/worker/expo/processors/contractPollProcessor.js +7 -2
- package/dist/types/contracts/arkcontract.d.ts +1 -1
- package/dist/types/contracts/handlers/helpers.d.ts +0 -9
- package/dist/types/contracts/vtxoOwnership.d.ts +25 -0
- package/dist/types/identity/descriptor.d.ts +26 -0
- package/dist/types/identity/descriptorProvider.d.ts +11 -4
- package/dist/types/identity/hdCapableIdentity.d.ts +44 -0
- package/dist/types/identity/index.d.ts +1 -0
- package/dist/types/identity/seedIdentity.d.ts +113 -29
- package/dist/types/identity/serialize.d.ts +12 -0
- package/dist/types/identity/staticDescriptorProvider.d.ts +1 -1
- package/dist/types/index.d.ts +6 -3
- package/dist/types/providers/electrum.d.ts +115 -15
- package/dist/types/providers/onchain.d.ts +6 -0
- package/dist/types/repositories/serialization.d.ts +26 -2
- package/dist/types/script/address.d.ts +1 -1
- package/dist/types/script/tapscript.d.ts +4 -0
- package/dist/types/utils/timelock.d.ts +9 -0
- package/dist/types/wallet/hdDescriptorProvider.d.ts +93 -0
- package/dist/types/wallet/index.d.ts +19 -10
- package/dist/types/wallet/onchain.d.ts +1 -1
- package/dist/types/wallet/serviceWorker/wallet.d.ts +1 -1
- package/dist/types/wallet/unroll.d.ts +10 -0
- package/dist/types/wallet/wallet.d.ts +4 -1
- package/package.json +1 -1
|
@@ -302,7 +302,9 @@ class SQLiteWalletRepository {
|
|
|
302
302
|
tx.amount,
|
|
303
303
|
tx.settled ? 1 : 0,
|
|
304
304
|
tx.createdAt,
|
|
305
|
-
tx.assets
|
|
305
|
+
tx.assets
|
|
306
|
+
? JSON.stringify((0, serialization_1.serializeAssets)(tx.assets))
|
|
307
|
+
: null,
|
|
306
308
|
]);
|
|
307
309
|
}
|
|
308
310
|
}
|
|
@@ -410,7 +412,7 @@ function txRowToDomain(row) {
|
|
|
410
412
|
createdAt: row.created_at,
|
|
411
413
|
};
|
|
412
414
|
if (row.assets_json) {
|
|
413
|
-
tx.assets = JSON.parse(row.assets_json);
|
|
415
|
+
tx.assets = (0, serialization_1.deserializeAssets)(JSON.parse(row.assets_json));
|
|
414
416
|
}
|
|
415
417
|
return tx;
|
|
416
418
|
}
|
|
@@ -3,6 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.ArkAddress = void 0;
|
|
4
4
|
const base_1 = require("@scure/base");
|
|
5
5
|
const script_js_1 = require("@scure/btc-signer/script.js");
|
|
6
|
+
const wallet_1 = require("../wallet");
|
|
6
7
|
/**
|
|
7
8
|
* ArkAddress allows creating and decoding bech32m-encoded Arkade addresses.
|
|
8
9
|
*
|
|
@@ -43,7 +44,7 @@ class ArkAddress {
|
|
|
43
44
|
* @defaultValue `version = 0`
|
|
44
45
|
* @throws Error if either public key is not 32 bytes long
|
|
45
46
|
*/
|
|
46
|
-
constructor(serverPubKey, vtxoTaprootKey, hrp, version = 0) {
|
|
47
|
+
constructor(serverPubKey, vtxoTaprootKey, hrp = wallet_1.DEFAULT_ARKADE_HRP, version = 0) {
|
|
47
48
|
this.serverPubKey = serverPubKey;
|
|
48
49
|
this.vtxoTaprootKey = vtxoTaprootKey;
|
|
49
50
|
this.hrp = hrp;
|
package/dist/cjs/script/base.js
CHANGED
|
@@ -1,47 +1,14 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
-
if (k2 === undefined) k2 = k;
|
|
4
|
-
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
-
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
-
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
-
}
|
|
8
|
-
Object.defineProperty(o, k2, desc);
|
|
9
|
-
}) : (function(o, m, k, k2) {
|
|
10
|
-
if (k2 === undefined) k2 = k;
|
|
11
|
-
o[k2] = m[k];
|
|
12
|
-
}));
|
|
13
|
-
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
-
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
-
}) : function(o, v) {
|
|
16
|
-
o["default"] = v;
|
|
17
|
-
});
|
|
18
|
-
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
-
var ownKeys = function(o) {
|
|
20
|
-
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
-
var ar = [];
|
|
22
|
-
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
-
return ar;
|
|
24
|
-
};
|
|
25
|
-
return ownKeys(o);
|
|
26
|
-
};
|
|
27
|
-
return function (mod) {
|
|
28
|
-
if (mod && mod.__esModule) return mod;
|
|
29
|
-
var result = {};
|
|
30
|
-
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
-
__setModuleDefault(result, mod);
|
|
32
|
-
return result;
|
|
33
|
-
};
|
|
34
|
-
})();
|
|
35
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
3
|
exports.VtxoScript = exports.TapTreeCoder = void 0;
|
|
37
4
|
exports.scriptFromTapLeafScript = scriptFromTapLeafScript;
|
|
38
5
|
exports.getSequence = getSequence;
|
|
39
6
|
const btc_signer_1 = require("@scure/btc-signer");
|
|
40
|
-
const bip68 = __importStar(require("bip68"));
|
|
41
7
|
const payment_js_1 = require("@scure/btc-signer/payment.js");
|
|
42
8
|
const psbt_js_1 = require("@scure/btc-signer/psbt.js");
|
|
43
9
|
const base_1 = require("@scure/base");
|
|
44
10
|
const address_1 = require("./address");
|
|
11
|
+
const timelock_1 = require("../utils/timelock");
|
|
45
12
|
const tapscript_1 = require("./tapscript");
|
|
46
13
|
exports.TapTreeCoder = psbt_js_1.PSBTOutput.tapTree[2];
|
|
47
14
|
function scriptFromTapLeafScript(leaf) {
|
|
@@ -163,19 +130,19 @@ class VtxoScript {
|
|
|
163
130
|
const paths = [];
|
|
164
131
|
for (const leaf of this.leaves) {
|
|
165
132
|
try {
|
|
166
|
-
const
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
catch (e) {
|
|
171
|
-
try {
|
|
172
|
-
const tapscript = tapscript_1.ConditionCSVMultisigTapscript.decode(scriptFromTapLeafScript(leaf));
|
|
173
|
-
paths.push(tapscript);
|
|
133
|
+
const script = scriptFromTapLeafScript(leaf);
|
|
134
|
+
if (tapscript_1.CSVMultisigTapscript.isScriptValid(script) === true) {
|
|
135
|
+
const tapScript = tapscript_1.CSVMultisigTapscript.decode(script);
|
|
136
|
+
paths.push(tapScript);
|
|
174
137
|
}
|
|
175
|
-
|
|
176
|
-
|
|
138
|
+
else if (tapscript_1.ConditionCSVMultisigTapscript.isScriptValid(script) === true) {
|
|
139
|
+
const tapScript = tapscript_1.ConditionCSVMultisigTapscript.decode(script);
|
|
140
|
+
paths.push(tapScript);
|
|
177
141
|
}
|
|
178
142
|
}
|
|
143
|
+
catch (e) {
|
|
144
|
+
console.debug("Failed to decode script", e);
|
|
145
|
+
}
|
|
179
146
|
}
|
|
180
147
|
return paths;
|
|
181
148
|
}
|
|
@@ -206,9 +173,7 @@ function getSequence(tapLeafScript) {
|
|
|
206
173
|
const script = scriptWithLeafVersion.subarray(0, scriptWithLeafVersion.length - 1);
|
|
207
174
|
try {
|
|
208
175
|
const params = tapscript_1.CSVMultisigTapscript.decode(script).params;
|
|
209
|
-
sequence =
|
|
210
|
-
? { blocks: Number(params.timelock.value) }
|
|
211
|
-
: { seconds: Number(params.timelock.value) });
|
|
176
|
+
sequence = (0, timelock_1.timelockToSequence)(params.timelock);
|
|
212
177
|
}
|
|
213
178
|
catch {
|
|
214
179
|
const params = tapscript_1.CLTVMultisigTapscript.decode(script).params;
|
|
@@ -1,43 +1,10 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
-
if (k2 === undefined) k2 = k;
|
|
4
|
-
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
-
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
-
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
-
}
|
|
8
|
-
Object.defineProperty(o, k2, desc);
|
|
9
|
-
}) : (function(o, m, k, k2) {
|
|
10
|
-
if (k2 === undefined) k2 = k;
|
|
11
|
-
o[k2] = m[k];
|
|
12
|
-
}));
|
|
13
|
-
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
-
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
-
}) : function(o, v) {
|
|
16
|
-
o["default"] = v;
|
|
17
|
-
});
|
|
18
|
-
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
-
var ownKeys = function(o) {
|
|
20
|
-
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
-
var ar = [];
|
|
22
|
-
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
-
return ar;
|
|
24
|
-
};
|
|
25
|
-
return ownKeys(o);
|
|
26
|
-
};
|
|
27
|
-
return function (mod) {
|
|
28
|
-
if (mod && mod.__esModule) return mod;
|
|
29
|
-
var result = {};
|
|
30
|
-
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
-
__setModuleDefault(result, mod);
|
|
32
|
-
return result;
|
|
33
|
-
};
|
|
34
|
-
})();
|
|
35
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
3
|
exports.CLTVMultisigTapscript = exports.ConditionMultisigTapscript = exports.ConditionCSVMultisigTapscript = exports.CSVMultisigTapscript = exports.MultisigTapscript = exports.TapscriptType = void 0;
|
|
37
4
|
exports.decodeTapscript = decodeTapscript;
|
|
38
|
-
const bip68 = __importStar(require("bip68"));
|
|
39
5
|
const btc_signer_1 = require("@scure/btc-signer");
|
|
40
6
|
const base_1 = require("@scure/base");
|
|
7
|
+
const timelock_1 = require("../utils/timelock");
|
|
41
8
|
const MinimalScriptNum = (0, btc_signer_1.ScriptNum)(undefined, true);
|
|
42
9
|
var TapscriptType;
|
|
43
10
|
(function (TapscriptType) {
|
|
@@ -271,9 +238,7 @@ var CSVMultisigTapscript;
|
|
|
271
238
|
throw new Error(`Invalid pubkey length: expected 32, got ${pubkey.length}`);
|
|
272
239
|
}
|
|
273
240
|
}
|
|
274
|
-
const sequence = MinimalScriptNum.encode(BigInt(
|
|
275
|
-
? { blocks: Number(params.timelock.value) }
|
|
276
|
-
: { seconds: Number(params.timelock.value) })));
|
|
241
|
+
const sequence = MinimalScriptNum.encode(BigInt((0, timelock_1.timelockToSequence)(params.timelock)));
|
|
277
242
|
const asm = [
|
|
278
243
|
sequence.length === 1 ? sequence[0] : sequence,
|
|
279
244
|
"CHECKSEQUENCEVERIFY",
|
|
@@ -296,17 +261,12 @@ var CSVMultisigTapscript;
|
|
|
296
261
|
if (script.length === 0) {
|
|
297
262
|
throw new Error("Failed to decode: script is empty");
|
|
298
263
|
}
|
|
299
|
-
const
|
|
300
|
-
if (
|
|
301
|
-
throw
|
|
264
|
+
const isValid = isScriptValid(script);
|
|
265
|
+
if (isValid instanceof Error) {
|
|
266
|
+
throw isValid;
|
|
302
267
|
}
|
|
268
|
+
const asm = btc_signer_1.Script.decode(script);
|
|
303
269
|
const sequence = asm[0];
|
|
304
|
-
if (typeof sequence === "string") {
|
|
305
|
-
throw new Error("Invalid script: expected sequence number");
|
|
306
|
-
}
|
|
307
|
-
if (asm[1] !== "CHECKSEQUENCEVERIFY" || asm[2] !== "DROP") {
|
|
308
|
-
throw new Error("Invalid script: expected CHECKSEQUENCEVERIFY DROP");
|
|
309
|
-
}
|
|
310
270
|
const multisigScript = new Uint8Array(btc_signer_1.Script.encode(asm.slice(3)));
|
|
311
271
|
let multisig;
|
|
312
272
|
try {
|
|
@@ -322,10 +282,7 @@ var CSVMultisigTapscript;
|
|
|
322
282
|
else {
|
|
323
283
|
sequenceNum = Number(MinimalScriptNum.decode(sequence));
|
|
324
284
|
}
|
|
325
|
-
const
|
|
326
|
-
const timelock = decodedTimelock.blocks !== undefined
|
|
327
|
-
? { type: "blocks", value: BigInt(decodedTimelock.blocks) }
|
|
328
|
-
: { type: "seconds", value: BigInt(decodedTimelock.seconds) };
|
|
285
|
+
const timelock = (0, timelock_1.sequenceToTimelock)(sequenceNum);
|
|
329
286
|
const reconstructed = encode({
|
|
330
287
|
timelock,
|
|
331
288
|
...multisig.params,
|
|
@@ -348,6 +305,21 @@ var CSVMultisigTapscript;
|
|
|
348
305
|
return tapscript.type === TapscriptType.CSVMultisig;
|
|
349
306
|
}
|
|
350
307
|
CSVMultisigTapscript.is = is;
|
|
308
|
+
function isScriptValid(script) {
|
|
309
|
+
const asm = btc_signer_1.Script.decode(script);
|
|
310
|
+
if (asm.length < 3) {
|
|
311
|
+
return new Error(`Invalid script: too short (expected at least 3)`);
|
|
312
|
+
}
|
|
313
|
+
const sequence = asm[0];
|
|
314
|
+
if (typeof sequence === "string") {
|
|
315
|
+
return new Error("Invalid script: expected sequence number");
|
|
316
|
+
}
|
|
317
|
+
if (asm[1] !== "CHECKSEQUENCEVERIFY" || asm[2] !== "DROP") {
|
|
318
|
+
return new Error("Invalid script: expected CHECKSEQUENCEVERIFY DROP");
|
|
319
|
+
}
|
|
320
|
+
return true;
|
|
321
|
+
}
|
|
322
|
+
CSVMultisigTapscript.isScriptValid = isScriptValid;
|
|
351
323
|
})(CSVMultisigTapscript || (exports.CSVMultisigTapscript = CSVMultisigTapscript = {}));
|
|
352
324
|
/**
|
|
353
325
|
* Combines a condition script with an exit closure. The resulting script requires
|
|
@@ -382,18 +354,14 @@ var ConditionCSVMultisigTapscript;
|
|
|
382
354
|
if (script.length === 0) {
|
|
383
355
|
throw new Error("Failed to decode: script is empty");
|
|
384
356
|
}
|
|
385
|
-
const
|
|
386
|
-
if (
|
|
387
|
-
throw
|
|
388
|
-
}
|
|
389
|
-
let verifyIndex = -1;
|
|
390
|
-
for (let i = asm.length - 1; i >= 0; i--) {
|
|
391
|
-
if (asm[i] === "VERIFY") {
|
|
392
|
-
verifyIndex = i;
|
|
393
|
-
}
|
|
357
|
+
const isValid = isScriptValid(script);
|
|
358
|
+
if (isValid instanceof Error) {
|
|
359
|
+
throw isValid;
|
|
394
360
|
}
|
|
361
|
+
const asm = btc_signer_1.Script.decode(script);
|
|
362
|
+
let verifyIndex = getVerifyIndex(asm);
|
|
395
363
|
if (verifyIndex === -1) {
|
|
396
|
-
throw
|
|
364
|
+
throw Error("Invalid script: missing VERIFY operation");
|
|
397
365
|
}
|
|
398
366
|
const conditionScript = new Uint8Array(btc_signer_1.Script.encode(asm.slice(0, verifyIndex)));
|
|
399
367
|
const csvMultisigScript = new Uint8Array(btc_signer_1.Script.encode(asm.slice(verifyIndex + 1)));
|
|
@@ -426,6 +394,28 @@ var ConditionCSVMultisigTapscript;
|
|
|
426
394
|
return tapscript.type === TapscriptType.ConditionCSVMultisig;
|
|
427
395
|
}
|
|
428
396
|
ConditionCSVMultisigTapscript.is = is;
|
|
397
|
+
function getVerifyIndex(asm) {
|
|
398
|
+
let verifyIndex = -1;
|
|
399
|
+
for (let i = asm.length - 1; i >= 0; i--) {
|
|
400
|
+
if (asm[i] === "VERIFY") {
|
|
401
|
+
verifyIndex = i;
|
|
402
|
+
return verifyIndex;
|
|
403
|
+
}
|
|
404
|
+
}
|
|
405
|
+
return verifyIndex;
|
|
406
|
+
}
|
|
407
|
+
function isScriptValid(script) {
|
|
408
|
+
const asm = btc_signer_1.Script.decode(script);
|
|
409
|
+
if (asm.length < 1) {
|
|
410
|
+
return new Error(`Invalid script: too short (expected at least 1)`);
|
|
411
|
+
}
|
|
412
|
+
let verifyIndex = getVerifyIndex(asm);
|
|
413
|
+
if (verifyIndex === -1) {
|
|
414
|
+
return new Error("Invalid script: missing VERIFY operation");
|
|
415
|
+
}
|
|
416
|
+
return true;
|
|
417
|
+
}
|
|
418
|
+
ConditionCSVMultisigTapscript.isScriptValid = isScriptValid;
|
|
429
419
|
})(ConditionCSVMultisigTapscript || (exports.ConditionCSVMultisigTapscript = ConditionCSVMultisigTapscript = {}));
|
|
430
420
|
/**
|
|
431
421
|
* Combines a condition script with a forfeit closure. The resulting script requires
|
|
@@ -460,18 +450,14 @@ var ConditionMultisigTapscript;
|
|
|
460
450
|
if (script.length === 0) {
|
|
461
451
|
throw new Error("Failed to decode: script is empty");
|
|
462
452
|
}
|
|
463
|
-
const
|
|
464
|
-
if (
|
|
465
|
-
throw
|
|
466
|
-
}
|
|
467
|
-
let verifyIndex = -1;
|
|
468
|
-
for (let i = asm.length - 1; i >= 0; i--) {
|
|
469
|
-
if (asm[i] === "VERIFY") {
|
|
470
|
-
verifyIndex = i;
|
|
471
|
-
}
|
|
453
|
+
const isValid = isScriptValid(script);
|
|
454
|
+
if (isValid instanceof Error) {
|
|
455
|
+
throw isValid;
|
|
472
456
|
}
|
|
457
|
+
const asm = btc_signer_1.Script.decode(script);
|
|
458
|
+
let verifyIndex = getVerifyIndex(asm);
|
|
473
459
|
if (verifyIndex === -1) {
|
|
474
|
-
throw
|
|
460
|
+
throw Error("Invalid script: missing VERIFY operation");
|
|
475
461
|
}
|
|
476
462
|
const conditionScript = new Uint8Array(btc_signer_1.Script.encode(asm.slice(0, verifyIndex)));
|
|
477
463
|
const multisigScript = new Uint8Array(btc_signer_1.Script.encode(asm.slice(verifyIndex + 1)));
|
|
@@ -504,6 +490,28 @@ var ConditionMultisigTapscript;
|
|
|
504
490
|
return tapscript.type === TapscriptType.ConditionMultisig;
|
|
505
491
|
}
|
|
506
492
|
ConditionMultisigTapscript.is = is;
|
|
493
|
+
function getVerifyIndex(asm) {
|
|
494
|
+
let verifyIndex = -1;
|
|
495
|
+
for (let i = asm.length - 1; i >= 0; i--) {
|
|
496
|
+
if (asm[i] === "VERIFY") {
|
|
497
|
+
verifyIndex = i;
|
|
498
|
+
return verifyIndex;
|
|
499
|
+
}
|
|
500
|
+
}
|
|
501
|
+
return verifyIndex;
|
|
502
|
+
}
|
|
503
|
+
function isScriptValid(script) {
|
|
504
|
+
const asm = btc_signer_1.Script.decode(script);
|
|
505
|
+
if (asm.length < 1) {
|
|
506
|
+
return new Error(`Invalid script: too short (expected at least 1)`);
|
|
507
|
+
}
|
|
508
|
+
let verifyIndex = getVerifyIndex(asm);
|
|
509
|
+
if (verifyIndex === -1) {
|
|
510
|
+
return new Error("Invalid script: missing VERIFY operation");
|
|
511
|
+
}
|
|
512
|
+
return true;
|
|
513
|
+
}
|
|
514
|
+
ConditionMultisigTapscript.isScriptValid = isScriptValid;
|
|
507
515
|
})(ConditionMultisigTapscript || (exports.ConditionMultisigTapscript = ConditionMultisigTapscript = {}));
|
|
508
516
|
/**
|
|
509
517
|
* Implements an absolute timelock (CLTV) script combined with a forfeit closure.
|
|
@@ -544,10 +552,11 @@ var CLTVMultisigTapscript;
|
|
|
544
552
|
if (script.length === 0) {
|
|
545
553
|
throw new Error("Failed to decode: script is empty");
|
|
546
554
|
}
|
|
547
|
-
const
|
|
548
|
-
if (
|
|
549
|
-
throw
|
|
555
|
+
const isValid = isScriptValid(script);
|
|
556
|
+
if (isValid instanceof Error) {
|
|
557
|
+
throw isValid;
|
|
550
558
|
}
|
|
559
|
+
const asm = btc_signer_1.Script.decode(script);
|
|
551
560
|
const locktime = asm[0];
|
|
552
561
|
if (typeof locktime === "string") {
|
|
553
562
|
throw new Error("Invalid script: expected locktime number");
|
|
@@ -592,4 +601,19 @@ var CLTVMultisigTapscript;
|
|
|
592
601
|
return tapscript.type === TapscriptType.CLTVMultisig;
|
|
593
602
|
}
|
|
594
603
|
CLTVMultisigTapscript.is = is;
|
|
604
|
+
function isScriptValid(script) {
|
|
605
|
+
const asm = btc_signer_1.Script.decode(script);
|
|
606
|
+
if (asm.length < 3) {
|
|
607
|
+
return new Error(`Invalid script: too short (expected at least 3)`);
|
|
608
|
+
}
|
|
609
|
+
const locktime = asm[0];
|
|
610
|
+
if (typeof locktime === "string") {
|
|
611
|
+
return new Error("Invalid script: expected locktime as number or bytes");
|
|
612
|
+
}
|
|
613
|
+
if (asm[1] !== "CHECKLOCKTIMEVERIFY" || asm[2] !== "DROP") {
|
|
614
|
+
return new Error("Invalid script: expected CHECKLOCKTIMEVERIFY DROP");
|
|
615
|
+
}
|
|
616
|
+
return true;
|
|
617
|
+
}
|
|
618
|
+
CLTVMultisigTapscript.isScriptValid = isScriptValid;
|
|
595
619
|
})(CLTVMultisigTapscript || (exports.CLTVMultisigTapscript = CLTVMultisigTapscript = {}));
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
+
exports.timelockToSequence = timelockToSequence;
|
|
37
|
+
exports.sequenceToTimelock = sequenceToTimelock;
|
|
38
|
+
const bip68 = __importStar(require("bip68"));
|
|
39
|
+
/**
|
|
40
|
+
* Convert RelativeTimelock to BIP68 sequence number.
|
|
41
|
+
*/
|
|
42
|
+
function timelockToSequence(timelock) {
|
|
43
|
+
return bip68.encode(timelock.type === "blocks"
|
|
44
|
+
? { blocks: Number(timelock.value) }
|
|
45
|
+
: { seconds: Number(timelock.value) });
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* Convert BIP68 sequence number back to RelativeTimelock.
|
|
49
|
+
*/
|
|
50
|
+
function sequenceToTimelock(sequence) {
|
|
51
|
+
const decoded = bip68.decode(sequence);
|
|
52
|
+
if ("blocks" in decoded && decoded.blocks !== undefined) {
|
|
53
|
+
return { type: "blocks", value: BigInt(decoded.blocks) };
|
|
54
|
+
}
|
|
55
|
+
if ("seconds" in decoded && decoded.seconds !== undefined) {
|
|
56
|
+
return { type: "seconds", value: BigInt(decoded.seconds) };
|
|
57
|
+
}
|
|
58
|
+
throw new Error(`Invalid BIP68 sequence: ${sequence}`);
|
|
59
|
+
}
|
|
@@ -12,7 +12,7 @@ function collectAssets(vtxos) {
|
|
|
12
12
|
for (const vtxo of vtxos) {
|
|
13
13
|
if (vtxo.assets) {
|
|
14
14
|
for (const a of vtxo.assets) {
|
|
15
|
-
map.set(a.assetId, (map.get(a.assetId) ??
|
|
15
|
+
map.set(a.assetId, (map.get(a.assetId) ?? 0n) + a.amount);
|
|
16
16
|
}
|
|
17
17
|
}
|
|
18
18
|
}
|
|
@@ -25,16 +25,16 @@ function subtractAssets(spent, change) {
|
|
|
25
25
|
for (const vtxo of change) {
|
|
26
26
|
if (vtxo.assets) {
|
|
27
27
|
for (const a of vtxo.assets) {
|
|
28
|
-
map.set(a.assetId, (map.get(a.assetId) ??
|
|
28
|
+
map.set(a.assetId, (map.get(a.assetId) ?? 0n) + a.amount);
|
|
29
29
|
}
|
|
30
30
|
}
|
|
31
31
|
}
|
|
32
32
|
for (const vtxo of spent) {
|
|
33
33
|
if (vtxo.assets) {
|
|
34
34
|
for (const a of vtxo.assets) {
|
|
35
|
-
const current = map.get(a.assetId) ??
|
|
35
|
+
const current = map.get(a.assetId) ?? 0n;
|
|
36
36
|
const remaining = current - a.amount;
|
|
37
|
-
if (remaining !==
|
|
37
|
+
if (remaining !== 0n) {
|
|
38
38
|
map.set(a.assetId, remaining);
|
|
39
39
|
}
|
|
40
40
|
else {
|
|
@@ -1,44 +1,11 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
-
if (k2 === undefined) k2 = k;
|
|
4
|
-
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
-
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
-
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
-
}
|
|
8
|
-
Object.defineProperty(o, k2, desc);
|
|
9
|
-
}) : (function(o, m, k, k2) {
|
|
10
|
-
if (k2 === undefined) k2 = k;
|
|
11
|
-
o[k2] = m[k];
|
|
12
|
-
}));
|
|
13
|
-
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
-
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
-
}) : function(o, v) {
|
|
16
|
-
o["default"] = v;
|
|
17
|
-
});
|
|
18
|
-
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
-
var ownKeys = function(o) {
|
|
20
|
-
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
-
var ar = [];
|
|
22
|
-
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
-
return ar;
|
|
24
|
-
};
|
|
25
|
-
return ownKeys(o);
|
|
26
|
-
};
|
|
27
|
-
return function (mod) {
|
|
28
|
-
if (mod && mod.__esModule) return mod;
|
|
29
|
-
var result = {};
|
|
30
|
-
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
-
__setModuleDefault(result, mod);
|
|
32
|
-
return result;
|
|
33
|
-
};
|
|
34
|
-
})();
|
|
35
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
3
|
exports.VtxoTreeExpiry = exports.CosignerPublicKey = exports.ConditionWitness = exports.VtxoTaprootTree = exports.ArkPsbtFieldKeyType = exports.ArkPsbtFieldKey = void 0;
|
|
37
4
|
exports.setArkPsbtField = setArkPsbtField;
|
|
38
5
|
exports.getArkPsbtFields = getArkPsbtFields;
|
|
39
|
-
const bip68 = __importStar(require("bip68"));
|
|
40
6
|
const btc_signer_1 = require("@scure/btc-signer");
|
|
41
7
|
const base_1 = require("@scure/base");
|
|
8
|
+
const timelock_1 = require("./timelock");
|
|
42
9
|
/**
|
|
43
10
|
* ArkPsbtFieldKey are the available key names for the Arkade PSBT custom fields.
|
|
44
11
|
*/
|
|
@@ -184,11 +151,7 @@ exports.VtxoTreeExpiry = {
|
|
|
184
151
|
const v = (0, btc_signer_1.ScriptNum)(6, true).decode(unknown[1]);
|
|
185
152
|
if (!v)
|
|
186
153
|
return null;
|
|
187
|
-
|
|
188
|
-
return {
|
|
189
|
-
type: blocks ? "blocks" : "seconds",
|
|
190
|
-
value: BigInt(blocks ?? seconds ?? 0),
|
|
191
|
-
};
|
|
154
|
+
return (0, timelock_1.sequenceToTimelock)(Number(v));
|
|
192
155
|
}),
|
|
193
156
|
};
|
|
194
157
|
const encodedPsbtFieldKey = Object.fromEntries(Object.values(ArkPsbtFieldKey).map((key) => [
|
|
@@ -44,7 +44,7 @@ class AssetManager extends ReadonlyAssetManager {
|
|
|
44
44
|
* ```
|
|
45
45
|
*/
|
|
46
46
|
async issue(params) {
|
|
47
|
-
if (params.amount <=
|
|
47
|
+
if (params.amount <= 0n) {
|
|
48
48
|
throw new Error(`Issue amount must be greater than 0, got ${params.amount}`);
|
|
49
49
|
}
|
|
50
50
|
const metadata = castMetadata(params.metadata);
|
|
@@ -64,12 +64,12 @@ class AssetManager extends ReadonlyAssetManager {
|
|
|
64
64
|
continue;
|
|
65
65
|
for (const { assetId, amount } of coin.assets) {
|
|
66
66
|
const existing = assetChanges.get(assetId) ?? 0n;
|
|
67
|
-
assetChanges.set(assetId, existing +
|
|
67
|
+
assetChanges.set(assetId, existing + amount);
|
|
68
68
|
}
|
|
69
69
|
}
|
|
70
70
|
const groups = [];
|
|
71
71
|
// issued asset group
|
|
72
|
-
const issuedAssetOutput = asset_1.AssetOutput.create(0,
|
|
72
|
+
const issuedAssetOutput = asset_1.AssetOutput.create(0, params.amount);
|
|
73
73
|
const issuedAssetGroup = asset_1.AssetGroup.create(null, controlAssetRef, [], [issuedAssetOutput], metadata);
|
|
74
74
|
groups.push(issuedAssetGroup);
|
|
75
75
|
// add asset groups for each asset change
|
|
@@ -82,7 +82,7 @@ class AssetManager extends ReadonlyAssetManager {
|
|
|
82
82
|
for (const asset of assets) {
|
|
83
83
|
if (asset.assetId !== assetId)
|
|
84
84
|
continue;
|
|
85
|
-
changeInputs.push(asset_1.AssetInput.create(inputIndex,
|
|
85
|
+
changeInputs.push(asset_1.AssetInput.create(inputIndex, asset.amount));
|
|
86
86
|
}
|
|
87
87
|
}
|
|
88
88
|
// add the change asset group
|
|
@@ -123,7 +123,7 @@ class AssetManager extends ReadonlyAssetManager {
|
|
|
123
123
|
* ```
|
|
124
124
|
*/
|
|
125
125
|
async reissue(params) {
|
|
126
|
-
if (params.amount <=
|
|
126
|
+
if (params.amount <= 0n) {
|
|
127
127
|
throw new Error(`Reissuance amount must be greater than 0, got ${params.amount}`);
|
|
128
128
|
}
|
|
129
129
|
const { controlAssetId } = await this.getAssetDetails(params.assetId);
|
|
@@ -144,11 +144,11 @@ class AssetManager extends ReadonlyAssetManager {
|
|
|
144
144
|
continue;
|
|
145
145
|
for (const { assetId, amount } of coin.assets) {
|
|
146
146
|
if (assetId === params.assetId) {
|
|
147
|
-
assetToReissueAmount +=
|
|
147
|
+
assetToReissueAmount += amount;
|
|
148
148
|
continue;
|
|
149
149
|
}
|
|
150
150
|
const existing = assetChanges.get(assetId) ?? 0n;
|
|
151
|
-
assetChanges.set(assetId, existing +
|
|
151
|
+
assetChanges.set(assetId, existing + amount);
|
|
152
152
|
}
|
|
153
153
|
}
|
|
154
154
|
// select at least dust amount
|
|
@@ -163,11 +163,11 @@ class AssetManager extends ReadonlyAssetManager {
|
|
|
163
163
|
continue;
|
|
164
164
|
for (const { assetId, amount } of coin.assets) {
|
|
165
165
|
if (assetId === params.assetId) {
|
|
166
|
-
assetToReissueAmount +=
|
|
166
|
+
assetToReissueAmount += amount;
|
|
167
167
|
continue;
|
|
168
168
|
}
|
|
169
169
|
const existing = assetChanges.get(assetId) ?? 0n;
|
|
170
|
-
assetChanges.set(assetId, existing +
|
|
170
|
+
assetChanges.set(assetId, existing + amount);
|
|
171
171
|
}
|
|
172
172
|
}
|
|
173
173
|
selectedCoins = [...selectedCoins, ...additional.inputs];
|
|
@@ -180,11 +180,11 @@ class AssetManager extends ReadonlyAssetManager {
|
|
|
180
180
|
for (const asset of assets) {
|
|
181
181
|
if (asset.assetId !== params.assetId)
|
|
182
182
|
continue;
|
|
183
|
-
reissueInputs.push(asset_1.AssetInput.create(inputIndex,
|
|
183
|
+
reissueInputs.push(asset_1.AssetInput.create(inputIndex, asset.amount));
|
|
184
184
|
}
|
|
185
185
|
}
|
|
186
186
|
// the total output amount of the asset to reissue = new + (optional) selected amount
|
|
187
|
-
const totalAssetAmount = assetToReissueAmount +
|
|
187
|
+
const totalAssetAmount = assetToReissueAmount + params.amount;
|
|
188
188
|
const reissueAssetIdObj = asset_1.AssetId.fromString(params.assetId);
|
|
189
189
|
// create the reissuance asset group
|
|
190
190
|
const reissueAssetGroup = asset_1.AssetGroup.create(reissueAssetIdObj, null, reissueInputs, [asset_1.AssetOutput.create(0, totalAssetAmount)], []);
|
|
@@ -196,7 +196,7 @@ class AssetManager extends ReadonlyAssetManager {
|
|
|
196
196
|
for (const asset of assets) {
|
|
197
197
|
if (asset.assetId !== assetId)
|
|
198
198
|
continue;
|
|
199
|
-
changeInputs.push(asset_1.AssetInput.create(inputIndex,
|
|
199
|
+
changeInputs.push(asset_1.AssetInput.create(inputIndex, asset.amount));
|
|
200
200
|
}
|
|
201
201
|
}
|
|
202
202
|
groups.push(asset_1.AssetGroup.create(asset_1.AssetId.fromString(assetId), null, changeInputs, [asset_1.AssetOutput.create(0, amount)], []));
|
|
@@ -230,7 +230,7 @@ class AssetManager extends ReadonlyAssetManager {
|
|
|
230
230
|
* ```
|
|
231
231
|
*/
|
|
232
232
|
async burn(params) {
|
|
233
|
-
if (params.amount <=
|
|
233
|
+
if (params.amount <= 0n) {
|
|
234
234
|
throw new Error(`Burn amount must be greater than 0, got ${params.amount}`);
|
|
235
235
|
}
|
|
236
236
|
const virtualCoins = await this.wallet.getVtxos({
|
|
@@ -238,7 +238,7 @@ class AssetManager extends ReadonlyAssetManager {
|
|
|
238
238
|
});
|
|
239
239
|
const assetChanges = new Map();
|
|
240
240
|
// select virtual outputs with the asset to burn
|
|
241
|
-
const { selected: assetCoins } = (0, asset_2.selectCoinsWithAsset)(virtualCoins, params.assetId,
|
|
241
|
+
const { selected: assetCoins } = (0, asset_2.selectCoinsWithAsset)(virtualCoins, params.assetId, params.amount);
|
|
242
242
|
const selectedCoins = [...assetCoins];
|
|
243
243
|
let totalBtcSelected = 0;
|
|
244
244
|
// add the selected coins to asset changes, including the asset to burn
|
|
@@ -248,11 +248,11 @@ class AssetManager extends ReadonlyAssetManager {
|
|
|
248
248
|
continue;
|
|
249
249
|
for (const { assetId, amount } of coin.assets) {
|
|
250
250
|
const existing = assetChanges.get(assetId) ?? 0n;
|
|
251
|
-
assetChanges.set(assetId, existing +
|
|
251
|
+
assetChanges.set(assetId, existing + amount);
|
|
252
252
|
}
|
|
253
253
|
}
|
|
254
254
|
// subtract the amount to burn from the asset change
|
|
255
|
-
assetChanges.set(params.assetId, (assetChanges.get(params.assetId) ?? 0n) -
|
|
255
|
+
assetChanges.set(params.assetId, (assetChanges.get(params.assetId) ?? 0n) - params.amount);
|
|
256
256
|
const minBtcNeeded = Number(this.wallet.dustAmount);
|
|
257
257
|
// we need to ensure at least dust amount is selected
|
|
258
258
|
// if not, select additional coins
|
|
@@ -266,7 +266,7 @@ class AssetManager extends ReadonlyAssetManager {
|
|
|
266
266
|
continue;
|
|
267
267
|
for (const { assetId, amount } of coin.assets) {
|
|
268
268
|
const existing = assetChanges.get(assetId) ?? 0n;
|
|
269
|
-
assetChanges.set(assetId, existing +
|
|
269
|
+
assetChanges.set(assetId, existing + amount);
|
|
270
270
|
}
|
|
271
271
|
}
|
|
272
272
|
selectedCoins.push(...additional.inputs);
|
|
@@ -280,7 +280,7 @@ class AssetManager extends ReadonlyAssetManager {
|
|
|
280
280
|
for (const asset of assets) {
|
|
281
281
|
if (asset.assetId !== assetId)
|
|
282
282
|
continue;
|
|
283
|
-
changeInputs.push(asset_1.AssetInput.create(inputIndex,
|
|
283
|
+
changeInputs.push(asset_1.AssetInput.create(inputIndex, asset.amount));
|
|
284
284
|
}
|
|
285
285
|
}
|
|
286
286
|
groups.push(asset_1.AssetGroup.create(asset_1.AssetId.fromString(assetId), null, changeInputs, amount > 0n ? [asset_1.AssetOutput.create(0, amount)] : [], []));
|