@chainvue/verus-sdk 0.9.0 → 0.11.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +6 -0
- package/dist/VerusSDK.d.ts +28 -0
- package/dist/VerusSDK.d.ts.map +1 -1
- package/dist/VerusSDK.js +47 -0
- package/dist/VerusSDK.js.map +1 -1
- package/dist/assemble/assembler.d.ts +66 -0
- package/dist/assemble/assembler.d.ts.map +1 -0
- package/dist/assemble/assembler.js +155 -0
- package/dist/assemble/assembler.js.map +1 -0
- package/dist/assemble/fundedIdentityUpdate.d.ts +35 -0
- package/dist/assemble/fundedIdentityUpdate.d.ts.map +1 -0
- package/dist/assemble/fundedIdentityUpdate.js +114 -0
- package/dist/assemble/fundedIdentityUpdate.js.map +1 -0
- package/dist/bundle.js +29599 -29208
- package/dist/currency/index.d.ts.map +1 -1
- package/dist/currency/index.js +32 -66
- package/dist/currency/index.js.map +1 -1
- package/dist/fork/boundary.d.ts +19 -0
- package/dist/fork/boundary.d.ts.map +1 -0
- package/dist/fork/boundary.js +54 -0
- package/dist/fork/boundary.js.map +1 -0
- package/dist/fork-shims.d.ts +7 -0
- package/dist/identity/index.d.ts +12 -2
- package/dist/identity/index.d.ts.map +1 -1
- package/dist/identity/index.js +211 -296
- package/dist/identity/index.js.map +1 -1
- package/dist/identity/public.d.ts +21 -0
- package/dist/identity/public.d.ts.map +1 -0
- package/dist/identity/public.js +38 -0
- package/dist/identity/public.js.map +1 -0
- package/dist/index.d.ts +4 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +5 -2
- package/dist/index.js.map +1 -1
- package/dist/message/index.js +7 -7
- package/dist/message/index.js.map +1 -1
- package/dist/offers/identity.d.ts +193 -0
- package/dist/offers/identity.d.ts.map +1 -0
- package/dist/offers/identity.js +314 -0
- package/dist/offers/identity.js.map +1 -0
- package/dist/offers/maker.d.ts +67 -0
- package/dist/offers/maker.d.ts.map +1 -0
- package/dist/offers/maker.js +132 -0
- package/dist/offers/maker.js.map +1 -0
- package/dist/offers/public.d.ts +30 -0
- package/dist/offers/public.d.ts.map +1 -0
- package/dist/offers/public.js +42 -0
- package/dist/offers/public.js.map +1 -0
- package/dist/offers/sign.d.ts +42 -0
- package/dist/offers/sign.d.ts.map +1 -0
- package/dist/offers/sign.js +98 -0
- package/dist/offers/sign.js.map +1 -0
- package/dist/offers/taker.d.ts +33 -0
- package/dist/offers/taker.d.ts.map +1 -0
- package/dist/offers/taker.js +113 -0
- package/dist/offers/taker.js.map +1 -0
- package/dist/signing/index.d.ts +1 -1
- package/dist/signing/index.d.ts.map +1 -1
- package/dist/signing/index.js +10 -10
- package/dist/signing/index.js.map +1 -1
- package/dist/transfer/index.d.ts.map +1 -1
- package/dist/transfer/index.js +40 -62
- package/dist/transfer/index.js.map +1 -1
- package/dist/types/index.d.ts +0 -47
- package/dist/types/index.d.ts.map +1 -1
- package/dist/types/index.js +6 -0
- package/dist/types/index.js.map +1 -1
- package/dist/utils/index.d.ts.map +1 -1
- package/dist/utils/index.js +6 -11
- package/dist/utils/index.js.map +1 -1
- package/dist/utxo/index.d.ts +7 -0
- package/dist/utxo/index.d.ts.map +1 -1
- package/dist/utxo/index.js +5 -4
- package/dist/utxo/index.js.map +1 -1
- package/package.json +1 -1
package/dist/identity/index.js
CHANGED
|
@@ -21,6 +21,7 @@ exports.serializeAdvancedNameReservation = serializeAdvancedNameReservation;
|
|
|
21
21
|
exports.calculateCommitmentHash = calculateCommitmentHash;
|
|
22
22
|
exports.serializeCommitmentHash = serializeCommitmentHash;
|
|
23
23
|
exports.buildCommitmentScript = buildCommitmentScript;
|
|
24
|
+
exports.buildTokenCommitmentScript = buildTokenCommitmentScript;
|
|
24
25
|
exports.buildReservationScript = buildReservationScript;
|
|
25
26
|
exports.buildIdentityScript = buildIdentityScript;
|
|
26
27
|
exports.deriveIdentityAddress = deriveIdentityAddress;
|
|
@@ -38,19 +39,20 @@ exports.buildAndSignRegistration = buildAndSignRegistration;
|
|
|
38
39
|
exports.buildAndSignIdentityUpdate = buildAndSignIdentityUpdate;
|
|
39
40
|
const crypto_1 = require("crypto");
|
|
40
41
|
const bn_js_1 = __importDefault(require("bn.js"));
|
|
41
|
-
const
|
|
42
|
-
const
|
|
43
|
-
const
|
|
44
|
-
Object.defineProperty(exports, "nameAndParentAddrToIAddr", { enumerable: true, get: function () { return
|
|
45
|
-
const
|
|
42
|
+
const boundary_js_1 = require("../fork/boundary.js");
|
|
43
|
+
const boundary_js_2 = require("../fork/boundary.js");
|
|
44
|
+
const boundary_js_3 = require("../fork/boundary.js");
|
|
45
|
+
Object.defineProperty(exports, "nameAndParentAddrToIAddr", { enumerable: true, get: function () { return boundary_js_3.nameAndParentAddrToIAddr; } });
|
|
46
|
+
const boundary_js_4 = require("../fork/boundary.js");
|
|
46
47
|
const index_js_1 = require("../constants/index.js");
|
|
47
48
|
const index_js_2 = require("../utils/index.js");
|
|
48
49
|
const index_js_3 = require("../signing/index.js");
|
|
49
|
-
const
|
|
50
|
+
const assembler_js_1 = require("../assemble/assembler.js");
|
|
51
|
+
const fundedIdentityUpdate_js_1 = require("../assemble/fundedIdentityUpdate.js");
|
|
50
52
|
const brands_js_1 = require("../core/brands.js");
|
|
51
53
|
const errors_js_1 = require("../errors.js");
|
|
52
|
-
const
|
|
53
|
-
const { createUnfundedIdentityUpdate
|
|
54
|
+
const index_js_4 = require("../keys/index.js");
|
|
55
|
+
const { createUnfundedIdentityUpdate } = boundary_js_4.smarttxs;
|
|
54
56
|
const HASH160_BYTE_LENGTH = 20;
|
|
55
57
|
const HASH256_BYTE_LENGTH = 32;
|
|
56
58
|
/** Null identity hash (20 zero bytes) */
|
|
@@ -75,7 +77,7 @@ const LOCK_DELAY_SANITY_BLOCKS = 525600;
|
|
|
75
77
|
function assertAddressVersion(address, expectedVersion, label) {
|
|
76
78
|
let version;
|
|
77
79
|
try {
|
|
78
|
-
version = (0,
|
|
80
|
+
version = (0, boundary_js_3.fromBase58Check)(address).version;
|
|
79
81
|
}
|
|
80
82
|
catch {
|
|
81
83
|
throw new errors_js_1.TransactionBuildError(`${label} is not a valid base58check address: ${JSON.stringify(address)}`);
|
|
@@ -93,7 +95,7 @@ function assertAddressVersion(address, expectedVersion, label) {
|
|
|
93
95
|
* primary authority (currency define; update/lock/unlock check inline).
|
|
94
96
|
*/
|
|
95
97
|
function assertWifIsPrimary(wif, identity, network) {
|
|
96
|
-
const signerAddress =
|
|
98
|
+
const signerAddress = boundary_js_4.ECPair.fromWIF(wif, network).getAddress();
|
|
97
99
|
const currentPrimaries = (identity.primary_addresses ?? []).map((k) => k.toAddress());
|
|
98
100
|
if (!currentPrimaries.includes(signerAddress)) {
|
|
99
101
|
throw new errors_js_1.TransactionBuildError(`the provided WIF (${signerAddress}) is not among the identity's primary addresses ` +
|
|
@@ -150,9 +152,9 @@ function calculateCommitmentHash(serializedReservation) {
|
|
|
150
152
|
* Serialize a CCommitmentHash
|
|
151
153
|
*/
|
|
152
154
|
function serializeCommitmentHash(hash) {
|
|
153
|
-
const tokenOutput = new
|
|
155
|
+
const tokenOutput = new boundary_js_1.TokenOutput({
|
|
154
156
|
version: new bn_js_1.default(0),
|
|
155
|
-
values: new
|
|
157
|
+
values: new boundary_js_1.CurrencyValueMap(),
|
|
156
158
|
});
|
|
157
159
|
const tokenBuf = tokenOutput.toBuffer();
|
|
158
160
|
return Buffer.concat([tokenBuf, hash]);
|
|
@@ -161,43 +163,73 @@ function serializeCommitmentHash(hash) {
|
|
|
161
163
|
* Build the commitment output script
|
|
162
164
|
*/
|
|
163
165
|
function buildCommitmentScript(commitmentHashBuf, controlAddress) {
|
|
164
|
-
const controlDest = new
|
|
165
|
-
const master = new
|
|
166
|
+
const controlDest = new boundary_js_1.TxDestination(boundary_js_1.KeyID.fromAddress(controlAddress));
|
|
167
|
+
const master = new boundary_js_1.OptCCParams({
|
|
166
168
|
version: new bn_js_1.default(3),
|
|
167
|
-
eval_code: new bn_js_1.default(
|
|
169
|
+
eval_code: new bn_js_1.default(boundary_js_2.EVALS.EVAL_NONE),
|
|
168
170
|
m: new bn_js_1.default(1),
|
|
169
171
|
n: new bn_js_1.default(1),
|
|
170
172
|
destinations: [controlDest],
|
|
171
173
|
vdata: [],
|
|
172
174
|
});
|
|
173
|
-
const params = new
|
|
175
|
+
const params = new boundary_js_1.OptCCParams({
|
|
174
176
|
version: new bn_js_1.default(3),
|
|
175
|
-
eval_code: new bn_js_1.default(
|
|
177
|
+
eval_code: new bn_js_1.default(boundary_js_2.EVALS.EVAL_IDENTITY_COMMITMENT),
|
|
176
178
|
m: new bn_js_1.default(1),
|
|
177
179
|
n: new bn_js_1.default(1),
|
|
178
180
|
destinations: [controlDest],
|
|
179
181
|
vdata: [commitmentHashBuf],
|
|
180
182
|
});
|
|
181
|
-
const script = new
|
|
183
|
+
const script = new boundary_js_1.SmartTransactionScript(master, params);
|
|
182
184
|
return script.toBuffer();
|
|
183
185
|
}
|
|
186
|
+
/**
|
|
187
|
+
* The daemon's fixed marker occupying the CCommitmentHash `hash` field of an
|
|
188
|
+
* offer-funding commitment that locks a TOKEN (not the native coin). It is the
|
|
189
|
+
* hash160 of the constant VDXF key `i74sHfYTqdfd5ZSmQSLHug4GuX2XHKwA7Y`,
|
|
190
|
+
* zero-extended to a uint256. Captured byte-identical from `makeoffer` on
|
|
191
|
+
* VRSCTEST across different offered currencies, amounts, and wanted sides — it
|
|
192
|
+
* is a protocol constant, independent of the offer's contents.
|
|
193
|
+
*/
|
|
194
|
+
const OFFER_TOKEN_COMMITMENT_MARKER = Buffer.concat([
|
|
195
|
+
Buffer.from('2767181a4f6abe2090a7dca2c689477d163900f6', 'hex'),
|
|
196
|
+
Buffer.alloc(12, 0),
|
|
197
|
+
]);
|
|
198
|
+
/**
|
|
199
|
+
* Build the offer-funding commitment output that locks an offered TOKEN.
|
|
200
|
+
*
|
|
201
|
+
* Mirrors the daemon's `makeoffer` funding output for a token: an
|
|
202
|
+
* EVAL_IDENTITY_COMMITMENT (eval-17) CC whose vData is the constant marker
|
|
203
|
+
* followed by a TokenOutput carrying the offered currency and amount. The
|
|
204
|
+
* output's native value is 0; it carries the token as reserve value. The native
|
|
205
|
+
* counterpart is {@link buildCommitmentScript} with a 32-zero hash.
|
|
206
|
+
*/
|
|
207
|
+
function buildTokenCommitmentScript(offeredCurrency, amountSat, controlAddress) {
|
|
208
|
+
const values = new boundary_js_1.CurrencyValueMap({
|
|
209
|
+
value_map: new Map([[offeredCurrency, new bn_js_1.default(amountSat.toString(10))]]),
|
|
210
|
+
multivalue: false,
|
|
211
|
+
});
|
|
212
|
+
const tokenOutput = new boundary_js_1.TokenOutput({ version: new bn_js_1.default(1), values });
|
|
213
|
+
const vdata = Buffer.concat([OFFER_TOKEN_COMMITMENT_MARKER, tokenOutput.toBuffer()]);
|
|
214
|
+
return buildCommitmentScript(vdata, controlAddress);
|
|
215
|
+
}
|
|
184
216
|
/**
|
|
185
217
|
* Build the name reservation output script
|
|
186
218
|
*/
|
|
187
219
|
function buildReservationScript(newIdentityIAddress, serializedReservation, isAdvanced = false) {
|
|
188
|
-
const identityDest = new
|
|
220
|
+
const identityDest = new boundary_js_1.TxDestination(boundary_js_1.IdentityID.fromAddress(newIdentityIAddress));
|
|
189
221
|
const evalCode = isAdvanced
|
|
190
222
|
? EVAL_IDENTITY_ADVANCEDRESERVATION
|
|
191
|
-
:
|
|
192
|
-
const master = new
|
|
223
|
+
: boundary_js_2.EVALS.EVAL_IDENTITY_RESERVATION;
|
|
224
|
+
const master = new boundary_js_1.OptCCParams({
|
|
193
225
|
version: new bn_js_1.default(3),
|
|
194
|
-
eval_code: new bn_js_1.default(
|
|
226
|
+
eval_code: new bn_js_1.default(boundary_js_2.EVALS.EVAL_NONE),
|
|
195
227
|
m: new bn_js_1.default(1),
|
|
196
228
|
n: new bn_js_1.default(1),
|
|
197
229
|
destinations: [identityDest],
|
|
198
230
|
vdata: [],
|
|
199
231
|
});
|
|
200
|
-
const params = new
|
|
232
|
+
const params = new boundary_js_1.OptCCParams({
|
|
201
233
|
version: new bn_js_1.default(3),
|
|
202
234
|
eval_code: new bn_js_1.default(evalCode),
|
|
203
235
|
m: new bn_js_1.default(1),
|
|
@@ -205,14 +237,14 @@ function buildReservationScript(newIdentityIAddress, serializedReservation, isAd
|
|
|
205
237
|
destinations: [identityDest],
|
|
206
238
|
vdata: [serializedReservation],
|
|
207
239
|
});
|
|
208
|
-
const script = new
|
|
240
|
+
const script = new boundary_js_1.SmartTransactionScript(master, params);
|
|
209
241
|
return script.toBuffer();
|
|
210
242
|
}
|
|
211
243
|
/**
|
|
212
244
|
* Build an identity definition output script from an Identity object
|
|
213
245
|
*/
|
|
214
246
|
function buildIdentityScript(identity) {
|
|
215
|
-
const identityScript =
|
|
247
|
+
const identityScript = boundary_js_1.IdentityScript.fromIdentity(identity);
|
|
216
248
|
return identityScript.toBuffer();
|
|
217
249
|
}
|
|
218
250
|
/**
|
|
@@ -227,7 +259,7 @@ function deriveIdentityAddress(name, parentIAddress) {
|
|
|
227
259
|
if (parentIAddress) {
|
|
228
260
|
assertAddressVersion(parentIAddress, index_js_1.I_ADDR_VERSION, 'parent');
|
|
229
261
|
}
|
|
230
|
-
return (0,
|
|
262
|
+
return (0, boundary_js_3.nameAndParentAddrToIAddr)(name, parentIAddress || undefined);
|
|
231
263
|
}
|
|
232
264
|
/**
|
|
233
265
|
* Determine if a parent is the VRSC root system
|
|
@@ -322,26 +354,26 @@ function identityPaymentScript(iAddress) {
|
|
|
322
354
|
* raw string here is exactly the hole that let a wrong-kind address through.
|
|
323
355
|
*/
|
|
324
356
|
function buildReferralPaymentScript(iAddress) {
|
|
325
|
-
const identityDest = new
|
|
357
|
+
const identityDest = new boundary_js_1.TxDestination(boundary_js_1.IdentityID.fromAddress(iAddress));
|
|
326
358
|
// Master: EVAL_NONE outputs have empty master (no index destinations)
|
|
327
359
|
// This matches the daemon's MakeMofNCCScript for EVAL_NONE condition objects
|
|
328
|
-
const master = new
|
|
360
|
+
const master = new boundary_js_1.OptCCParams({
|
|
329
361
|
version: new bn_js_1.default(3),
|
|
330
|
-
eval_code: new bn_js_1.default(
|
|
362
|
+
eval_code: new bn_js_1.default(boundary_js_2.EVALS.EVAL_NONE),
|
|
331
363
|
m: new bn_js_1.default(0),
|
|
332
364
|
n: new bn_js_1.default(0),
|
|
333
365
|
destinations: [],
|
|
334
366
|
vdata: [],
|
|
335
367
|
});
|
|
336
|
-
const params = new
|
|
368
|
+
const params = new boundary_js_1.OptCCParams({
|
|
337
369
|
version: new bn_js_1.default(3),
|
|
338
|
-
eval_code: new bn_js_1.default(
|
|
370
|
+
eval_code: new bn_js_1.default(boundary_js_2.EVALS.EVAL_NONE),
|
|
339
371
|
m: new bn_js_1.default(1),
|
|
340
372
|
n: new bn_js_1.default(1),
|
|
341
373
|
destinations: [identityDest],
|
|
342
374
|
vdata: [],
|
|
343
375
|
});
|
|
344
|
-
const script = new
|
|
376
|
+
const script = new boundary_js_1.SmartTransactionScript(master, params);
|
|
345
377
|
return script.toBuffer();
|
|
346
378
|
}
|
|
347
379
|
/**
|
|
@@ -364,17 +396,17 @@ function createIdentityObject(params) {
|
|
|
364
396
|
// R-address primary or an i-address authority is now a compile error at the
|
|
365
397
|
// call site, where the raw string is parsed.
|
|
366
398
|
validateMinSigs(params.minSigs ?? 1, params.primaryAddresses.length);
|
|
367
|
-
const primaryKeys = params.primaryAddresses.map(addr =>
|
|
368
|
-
const identity = new
|
|
369
|
-
version:
|
|
399
|
+
const primaryKeys = params.primaryAddresses.map(addr => boundary_js_1.KeyID.fromAddress(addr));
|
|
400
|
+
const identity = new boundary_js_1.Identity({
|
|
401
|
+
version: boundary_js_1.Identity.VERSION_CURRENT,
|
|
370
402
|
flags: new bn_js_1.default(0),
|
|
371
403
|
min_sigs: new bn_js_1.default(params.minSigs || 1),
|
|
372
404
|
primary_addresses: primaryKeys,
|
|
373
|
-
parent:
|
|
374
|
-
system_id:
|
|
405
|
+
parent: boundary_js_1.IdentityID.fromAddress(params.parentIAddress),
|
|
406
|
+
system_id: boundary_js_1.IdentityID.fromAddress(params.systemId),
|
|
375
407
|
name: params.name,
|
|
376
|
-
revocation_authority:
|
|
377
|
-
recovery_authority:
|
|
408
|
+
revocation_authority: boundary_js_1.IdentityID.fromAddress(params.revocationAuthority),
|
|
409
|
+
recovery_authority: boundary_js_1.IdentityID.fromAddress(params.recoveryAuthority),
|
|
378
410
|
private_addresses: [],
|
|
379
411
|
unlock_after: new bn_js_1.default(0),
|
|
380
412
|
});
|
|
@@ -411,15 +443,15 @@ function buildRegistrationFeeOutput(parentCurrencyId, feeAmount, systemId, _cont
|
|
|
411
443
|
* RESERVE_TRANSFER_FEE native.
|
|
412
444
|
*/
|
|
413
445
|
function buildRegistrationFeeReserveTransfer(parentCurrencyId, feeAmount, systemId) {
|
|
414
|
-
const destination = new
|
|
415
|
-
const values = new
|
|
446
|
+
const destination = new boundary_js_1.TxDestination(boundary_js_1.KeyID.fromAddress(index_js_1.RESERVE_TRANSFER_EVAL_PKH));
|
|
447
|
+
const values = new boundary_js_1.CurrencyValueMap({
|
|
416
448
|
value_map: new Map([[parentCurrencyId, new bn_js_1.default(feeAmount.toString(10))]]),
|
|
417
449
|
multivalue: false,
|
|
418
450
|
});
|
|
419
|
-
const parentHash = (0,
|
|
420
|
-
const transferDest = new
|
|
421
|
-
const flags =
|
|
422
|
-
const resTransfer = new
|
|
451
|
+
const parentHash = (0, boundary_js_3.fromBase58Check)(parentCurrencyId).hash;
|
|
452
|
+
const transferDest = new boundary_js_1.TransferDestination({ type: boundary_js_1.DEST_ID, destination_bytes: Buffer.from(parentHash) });
|
|
453
|
+
const flags = boundary_js_1.RESERVE_TRANSFER_VALID.or(boundary_js_1.RESERVE_TRANSFER_BURN_CHANGE_PRICE);
|
|
454
|
+
const resTransfer = new boundary_js_1.ReserveTransfer({
|
|
423
455
|
values,
|
|
424
456
|
version: new bn_js_1.default(1),
|
|
425
457
|
flags,
|
|
@@ -428,15 +460,15 @@ function buildRegistrationFeeReserveTransfer(parentCurrencyId, feeAmount, system
|
|
|
428
460
|
transfer_destination: transferDest,
|
|
429
461
|
dest_currency_id: parentCurrencyId,
|
|
430
462
|
});
|
|
431
|
-
const master = new
|
|
432
|
-
version: new bn_js_1.default(3), eval_code: new bn_js_1.default(
|
|
463
|
+
const master = new boundary_js_1.OptCCParams({
|
|
464
|
+
version: new bn_js_1.default(3), eval_code: new bn_js_1.default(boundary_js_2.EVALS.EVAL_NONE), m: new bn_js_1.default(1), n: new bn_js_1.default(1),
|
|
433
465
|
destinations: [destination], vdata: [],
|
|
434
466
|
});
|
|
435
|
-
const params = new
|
|
436
|
-
version: new bn_js_1.default(3), eval_code: new bn_js_1.default(
|
|
467
|
+
const params = new boundary_js_1.OptCCParams({
|
|
468
|
+
version: new bn_js_1.default(3), eval_code: new bn_js_1.default(boundary_js_2.EVALS.EVAL_RESERVE_TRANSFER), m: new bn_js_1.default(1), n: new bn_js_1.default(1),
|
|
437
469
|
destinations: [destination], vdata: [resTransfer.toBuffer()],
|
|
438
470
|
});
|
|
439
|
-
const script = new
|
|
471
|
+
const script = new boundary_js_1.SmartTransactionScript(master, params);
|
|
440
472
|
return { script: script.toBuffer(), nativeValue: index_js_1.RESERVE_TRANSFER_FEE };
|
|
441
473
|
}
|
|
442
474
|
/**
|
|
@@ -449,10 +481,10 @@ function buildTokenChangeOutput(changeAddress, currencyChanges) {
|
|
|
449
481
|
// R-addresses, and reject a P2SH address (not a valid reserve destination).
|
|
450
482
|
let destination;
|
|
451
483
|
if ((0, brands_js_1.isIAddress)(changeAddress)) {
|
|
452
|
-
destination = new
|
|
484
|
+
destination = new boundary_js_1.TxDestination(boundary_js_1.IdentityID.fromAddress(changeAddress));
|
|
453
485
|
}
|
|
454
486
|
else if ((0, brands_js_1.isRAddress)(changeAddress)) {
|
|
455
|
-
destination = new
|
|
487
|
+
destination = new boundary_js_1.TxDestination(boundary_js_1.KeyID.fromAddress(changeAddress));
|
|
456
488
|
}
|
|
457
489
|
else {
|
|
458
490
|
throw new errors_js_1.TransactionBuildError(`token change address must be an R-address or identity i-address, got: ${changeAddress}`);
|
|
@@ -463,28 +495,28 @@ function buildTokenChangeOutput(changeAddress, currencyChanges) {
|
|
|
463
495
|
valueMap.set(currency, new bn_js_1.default(amount.toString(10)));
|
|
464
496
|
}
|
|
465
497
|
}
|
|
466
|
-
const values = new
|
|
498
|
+
const values = new boundary_js_1.CurrencyValueMap({
|
|
467
499
|
value_map: valueMap,
|
|
468
500
|
multivalue: false,
|
|
469
501
|
});
|
|
470
|
-
const tokenOutput = new
|
|
471
|
-
const master = new
|
|
502
|
+
const tokenOutput = new boundary_js_1.TokenOutput({ version: new bn_js_1.default(1), values });
|
|
503
|
+
const master = new boundary_js_1.OptCCParams({
|
|
472
504
|
version: new bn_js_1.default(3),
|
|
473
|
-
eval_code: new bn_js_1.default(
|
|
505
|
+
eval_code: new bn_js_1.default(boundary_js_2.EVALS.EVAL_NONE),
|
|
474
506
|
m: new bn_js_1.default(1),
|
|
475
507
|
n: new bn_js_1.default(1),
|
|
476
508
|
destinations: [destination],
|
|
477
509
|
vdata: [],
|
|
478
510
|
});
|
|
479
|
-
const params = new
|
|
511
|
+
const params = new boundary_js_1.OptCCParams({
|
|
480
512
|
version: new bn_js_1.default(3),
|
|
481
|
-
eval_code: new bn_js_1.default(
|
|
513
|
+
eval_code: new bn_js_1.default(boundary_js_2.EVALS.EVAL_RESERVE_OUTPUT),
|
|
482
514
|
m: new bn_js_1.default(1),
|
|
483
515
|
n: new bn_js_1.default(1),
|
|
484
516
|
destinations: [destination],
|
|
485
517
|
vdata: [tokenOutput.toBuffer()],
|
|
486
518
|
});
|
|
487
|
-
const script = new
|
|
519
|
+
const script = new boundary_js_1.SmartTransactionScript(master, params);
|
|
488
520
|
return { script: script.toBuffer(), nativeValue: 0n };
|
|
489
521
|
}
|
|
490
522
|
// ─── Validation ──────────────────────────────────────────────────
|
|
@@ -493,7 +525,7 @@ function validateIdentityWif(wif) {
|
|
|
493
525
|
if (!wif || typeof wif !== 'string') {
|
|
494
526
|
throw new errors_js_1.InvalidWifError('WIF is required');
|
|
495
527
|
}
|
|
496
|
-
const check = (0,
|
|
528
|
+
const check = (0, index_js_4.validateWif)(wif);
|
|
497
529
|
if (!check.valid) {
|
|
498
530
|
throw new errors_js_1.InvalidWifError(check.error);
|
|
499
531
|
}
|
|
@@ -517,59 +549,30 @@ function buildAndSignCommitment(params, network) {
|
|
|
517
549
|
throw new errors_js_1.TransactionBuildError('At least one UTXO is required');
|
|
518
550
|
}
|
|
519
551
|
const verusNetwork = (0, index_js_3.getNetwork)(network === 'testnet');
|
|
520
|
-
const networkConfig = index_js_1.NETWORK_CONFIG[network];
|
|
521
552
|
// The commitment output is controlled by, and must be spent by, the key that
|
|
522
553
|
// completes the registration in step 2 — which signs with this same WIF. Using
|
|
523
554
|
// changeAddress as the control address broke that when changeAddress differed
|
|
524
555
|
// from the WIF's address (unsignable commitment), or was an i-address
|
|
525
556
|
// (KeyID.fromAddress laundered it to an uncontrollable key — permanently
|
|
526
557
|
// unspendable, wasting the commitment fee). Derive it from the WIF instead.
|
|
527
|
-
const controlAddress =
|
|
558
|
+
const controlAddress = boundary_js_4.ECPair.fromWIF(params.wif, verusNetwork).getAddress();
|
|
528
559
|
const commitment = prepareNameCommitment(params.name, controlAddress, params.referral, params.parent, network, params.salt);
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
const
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
// as a reserve-output change (bundled with the native change) — otherwise
|
|
542
|
-
// that token value is silently forfeited to the miner.
|
|
543
|
-
const hasTokenChange = selection.currencyChanges.size > 0;
|
|
544
|
-
if (hasTokenChange || selection.nativeChange > 0n) {
|
|
545
|
-
if (hasTokenChange) {
|
|
546
|
-
const tokenChangeScript = buildTokenChangeOutput((0, brands_js_1.parseAddress)(params.changeAddress, 'changeAddress'), selection.currencyChanges);
|
|
547
|
-
txb.addOutput(tokenChangeScript.script, (0, index_js_2.toSafeNumber)(selection.nativeChange));
|
|
548
|
-
}
|
|
549
|
-
else if (params.changeAddress.startsWith('i')) {
|
|
550
|
-
// utxo-lib's addOutput only resolves base58 R-addresses; an i-address
|
|
551
|
-
// changeAddress needs the explicit P2ID script (matching sendCurrency), or
|
|
552
|
-
// it throws an untyped "no matching Script".
|
|
553
|
-
txb.addOutput(identityPaymentScript((0, brands_js_1.parseIAddress)(params.changeAddress, 'changeAddress')), (0, index_js_2.toSafeNumber)(selection.nativeChange));
|
|
554
|
-
}
|
|
555
|
-
else {
|
|
556
|
-
txb.addOutput(params.changeAddress, (0, index_js_2.toSafeNumber)(selection.nativeChange));
|
|
557
|
-
}
|
|
558
|
-
}
|
|
559
|
-
// No token is paid out here (the commitment output carries none), so every
|
|
560
|
-
// token in the selected inputs must return as change.
|
|
561
|
-
(0, index_js_4.assertTokenConservation)(selection.selected, new Map(), selection.currencyChanges, networkConfig.chainId, 'name commitment');
|
|
562
|
-
const unsignedTx = txb.buildIncomplete();
|
|
563
|
-
// Native value conservation: the commitment output is 0 and change is native,
|
|
564
|
-
// so the assembled native fee must equal selection.fee. The fork's absurd-fee
|
|
565
|
-
// guard is blind for inputs > 2^32 sats (it truncates input value mod 2^32),
|
|
566
|
-
// so this bigint check is the real backstop against a change-accounting slip.
|
|
567
|
-
(0, index_js_3.assertNativeConservation)(selection.selected, unsignedTx.outs, selection.fee, 'name commitment');
|
|
568
|
-
const { signedTx, txid } = (0, index_js_3.signTransactionSmart)(unsignedTx.toHex(), params.wif, selection.selected, verusNetwork);
|
|
560
|
+
// The commitment output carries no token and no native value; the assembler
|
|
561
|
+
// selects funding, emits change, and enforces conservation by construction.
|
|
562
|
+
const assembled = (0, assembler_js_1.assembleAndSign)({
|
|
563
|
+
network,
|
|
564
|
+
wif: params.wif,
|
|
565
|
+
expiryHeight: params.expiryHeight,
|
|
566
|
+
funding: params.utxos,
|
|
567
|
+
outputs: [{ script: commitment.commitmentScript, nativeSat: 0n }],
|
|
568
|
+
changeAddress: params.changeAddress,
|
|
569
|
+
fee: { policy: 'estimate' },
|
|
570
|
+
label: 'name commitment',
|
|
571
|
+
});
|
|
569
572
|
return {
|
|
570
|
-
signedTx,
|
|
571
|
-
txid,
|
|
572
|
-
fee:
|
|
573
|
+
signedTx: assembled.signedTx,
|
|
574
|
+
txid: assembled.txid,
|
|
575
|
+
fee: assembled.fee,
|
|
573
576
|
identityAddress: commitment.identityAddress,
|
|
574
577
|
commitmentData: {
|
|
575
578
|
name: params.name,
|
|
@@ -600,7 +603,7 @@ function buildAndSignRegistration(params, network) {
|
|
|
600
603
|
// is handed, so a mismatched WIF produces a tx the daemon rejects at broadcast
|
|
601
604
|
// (and the commitment fee is wasted). Verify the WIF's hash is the commitment's
|
|
602
605
|
// control hash up front. (The 20-byte control hash is embedded in the CC script.)
|
|
603
|
-
const signerAddr =
|
|
606
|
+
const signerAddr = boundary_js_4.ECPair.fromWIF(params.wif, verusNetwork).getAddress();
|
|
604
607
|
const signerHash = (0, index_js_2.addressToScriptPubKey)(signerAddr).subarray(3, 23).toString('hex');
|
|
605
608
|
if (!params.commitmentUtxo.script.toLowerCase().includes(signerHash)) {
|
|
606
609
|
throw new errors_js_1.TransactionBuildError(`the provided WIF (${signerAddr}) does not control the name-commitment output; step 2 must be ` +
|
|
@@ -623,11 +626,11 @@ function buildAndSignRegistration(params, network) {
|
|
|
623
626
|
const identityScript = buildIdentityScript(identity);
|
|
624
627
|
const reservationScript = buildReservationScript((0, brands_js_1.parseIAddress)(identityAddress, 'identityAddress'), Buffer.from(commitData.namereservationHex, 'hex'), isSubId);
|
|
625
628
|
if (isSubId) {
|
|
626
|
-
return _buildSubIdRegistration(params,
|
|
629
|
+
return _buildSubIdRegistration(params, identityScript, reservationScript, identityAddress, parentIAddress, systemId, network);
|
|
627
630
|
}
|
|
628
|
-
return _buildVrscRegistration(params, identityScript, reservationScript, identityAddress, parentIAddress,
|
|
631
|
+
return _buildVrscRegistration(params, identityScript, reservationScript, identityAddress, parentIAddress, network);
|
|
629
632
|
}
|
|
630
|
-
function _buildVrscRegistration(params, identityScript, reservationScript, identityAddress, parentIAddress,
|
|
633
|
+
function _buildVrscRegistration(params, identityScript, reservationScript, identityAddress, parentIAddress, network) {
|
|
631
634
|
const commitData = params.commitmentData;
|
|
632
635
|
const hasReferral = !!commitData.referral;
|
|
633
636
|
const fees = calculateRegistrationFees(hasReferral, params.registrationFee, params.referralLevels);
|
|
@@ -661,84 +664,52 @@ function _buildVrscRegistration(params, identityScript, reservationScript, ident
|
|
|
661
664
|
// exactly (totalFee - issuerFee) every referred registration.
|
|
662
665
|
const totalFee = params.registrationFee ?? index_js_1.DEFAULT_REGISTRATION_FEE;
|
|
663
666
|
const totalReferralPayments = referralOutputs.reduce((sum, o) => sum + o.value, 0n);
|
|
664
|
-
|
|
665
|
-
|
|
666
|
-
|
|
667
|
-
const
|
|
668
|
-
|
|
669
|
-
|
|
670
|
-
|
|
671
|
-
const
|
|
672
|
-
|
|
673
|
-
|
|
674
|
-
|
|
675
|
-
|
|
676
|
-
|
|
677
|
-
|
|
678
|
-
|
|
679
|
-
|
|
680
|
-
|
|
681
|
-
|
|
682
|
-
|
|
683
|
-
|
|
684
|
-
|
|
685
|
-
|
|
686
|
-
|
|
687
|
-
|
|
688
|
-
|
|
689
|
-
|
|
690
|
-
|
|
691
|
-
|
|
692
|
-
|
|
693
|
-
|
|
694
|
-
// it throws an untyped "no matching Script".
|
|
695
|
-
txb.addOutput(identityPaymentScript((0, brands_js_1.parseIAddress)(params.changeAddress, 'changeAddress')), (0, index_js_2.toSafeNumber)(selection.nativeChange));
|
|
696
|
-
}
|
|
697
|
-
else {
|
|
698
|
-
txb.addOutput(params.changeAddress, (0, index_js_2.toSafeNumber)(selection.nativeChange));
|
|
699
|
-
}
|
|
700
|
-
}
|
|
701
|
-
// Referral payouts are native; no token is paid out, so all token value in the
|
|
702
|
-
// selected inputs must return as change.
|
|
703
|
-
(0, index_js_4.assertTokenConservation)(selection.selected, new Map(), selection.currencyChanges, systemId, 'identity registration');
|
|
704
|
-
const unsignedTx = txb.buildIncomplete();
|
|
705
|
-
const allUtxos = [commitUtxo, ...selection.selected];
|
|
706
|
-
// The registration fee is burned as an IMPLICIT miner fee (identity and
|
|
707
|
-
// reservation outputs carry 0; referral payouts come out of the total) —
|
|
708
|
-
// this matches on-chain registrations, and the daemon exempts recognized
|
|
709
|
-
// identity definitions from its absurd-fee check (IS_HIGH_FEE). utxo-lib's
|
|
710
|
-
// client-side fee-rate cap (default 2500 sat/vbyte) must be told the
|
|
711
|
-
// intended absolute fee or build() throws "Transaction has absurd fees".
|
|
712
|
-
const expectedImplicitFee = commitUtxo.satoshis + requiredNative - totalReferralPayments + selection.fee;
|
|
713
|
-
// Independent value-conservation check on the assembled transaction: recompute
|
|
714
|
-
// the native fee straight from inputs and outputs and require it to equal the
|
|
715
|
-
// fee this path intends to pay. buildAndSign has the same guard; registration
|
|
716
|
-
// moves the largest amounts (the registration fee is burned as implicit fee),
|
|
717
|
-
// so a selection/accounting slip must fail loudly here instead of being paid
|
|
718
|
-
// to miners.
|
|
719
|
-
const assembledNativeFee = allUtxos.reduce((sum, u) => sum + u.satoshis, 0n) -
|
|
720
|
-
unsignedTx.outs.reduce((sum, o) => sum + BigInt(o.value), 0n);
|
|
721
|
-
if (assembledNativeFee !== expectedImplicitFee) {
|
|
722
|
-
throw new errors_js_1.TransactionBuildError(`identity registration value conservation failed: assembled native fee ${assembledNativeFee} sat ` +
|
|
723
|
-
`!= intended ${expectedImplicitFee} sat`);
|
|
724
|
-
}
|
|
725
|
-
const { signedTx, txid } = (0, index_js_3.signTransactionSmart)(unsignedTx.toHex(), params.wif, allUtxos, network, expectedImplicitFee);
|
|
667
|
+
// With a referral the registrant pays the discounted issuer fee, otherwise the
|
|
668
|
+
// full registration fee. Either way the referral payouts come OUT OF that
|
|
669
|
+
// outlay; the remainder is burned as the implicit miner fee.
|
|
670
|
+
const registrationOutlay = hasReferral ? fees.issuerFee : totalFee;
|
|
671
|
+
// The identity and reservation outputs carry 0 native; the referral payouts are
|
|
672
|
+
// the only value-bearing outputs. The rest of the outlay is a DECLARED burn, so
|
|
673
|
+
// the assembler funds it, sizes the fee cap for it, and enforces conservation.
|
|
674
|
+
const assembled = (0, assembler_js_1.assembleAndSign)({
|
|
675
|
+
network,
|
|
676
|
+
wif: params.wif,
|
|
677
|
+
expiryHeight: params.expiryHeight,
|
|
678
|
+
funding: params.utxos,
|
|
679
|
+
// The name-commitment output is spent as input 0 (it carries no currency).
|
|
680
|
+
leadingInputs: [params.commitmentUtxo],
|
|
681
|
+
outputs: [
|
|
682
|
+
{ script: identityScript, nativeSat: 0n },
|
|
683
|
+
...referralOutputs.map((o) => ({ script: o.script, nativeSat: o.value })),
|
|
684
|
+
{ script: reservationScript, nativeSat: 0n },
|
|
685
|
+
],
|
|
686
|
+
changeAddress: params.changeAddress,
|
|
687
|
+
// Legacy fee estimate: identity + referrals + reservation, plus the one extra
|
|
688
|
+
// change slot the original path counted on top of selectUtxos' own reserve.
|
|
689
|
+
feeOutputCount: 2 + referralOutputs.length + 1,
|
|
690
|
+
fee: {
|
|
691
|
+
policy: 'declared',
|
|
692
|
+
burnSat: registrationOutlay - totalReferralPayments,
|
|
693
|
+
reason: 'identity registration fee (burned as implicit miner fee)',
|
|
694
|
+
},
|
|
695
|
+
label: 'identity registration',
|
|
696
|
+
});
|
|
726
697
|
return {
|
|
727
|
-
signedTx,
|
|
728
|
-
txid,
|
|
729
|
-
fee:
|
|
698
|
+
signedTx: assembled.signedTx,
|
|
699
|
+
txid: assembled.txid,
|
|
700
|
+
fee: assembled.fee,
|
|
730
701
|
identityAddress,
|
|
731
702
|
// The registrant's registration outlay: the discounted issuer fee when
|
|
732
703
|
// referred, the full fee otherwise. (Of this, referralPayments go to the
|
|
733
704
|
// referrers and the remainder is the implicit miner fee.)
|
|
734
|
-
registrationFee:
|
|
705
|
+
registrationFee: registrationOutlay,
|
|
735
706
|
referralPayments: referralOutputs.length,
|
|
736
707
|
referralAmountEach: fees.referralAmount,
|
|
737
|
-
inputsUsed:
|
|
738
|
-
nativeChange:
|
|
708
|
+
inputsUsed: assembled.inputsUsed,
|
|
709
|
+
nativeChange: assembled.nativeChange,
|
|
739
710
|
};
|
|
740
711
|
}
|
|
741
|
-
function _buildSubIdRegistration(params,
|
|
712
|
+
function _buildSubIdRegistration(params, identityScript, reservationScript, identityAddress, parentIAddress, systemId, network) {
|
|
742
713
|
const registrationFeeAmount = params.registrationFeeAmount;
|
|
743
714
|
if (!registrationFeeAmount || registrationFeeAmount <= 0n) {
|
|
744
715
|
throw new errors_js_1.TransactionBuildError('registrationFeeAmount is required for sub-ID registration. ' +
|
|
@@ -764,67 +735,48 @@ function _buildSubIdRegistration(params, identity, identityScript, reservationSc
|
|
|
764
735
|
'(from `getcurrency <parent>`), or 0n if it charges none.');
|
|
765
736
|
}
|
|
766
737
|
const nativeImportFee = params.nativeImportFee;
|
|
767
|
-
|
|
768
|
-
|
|
769
|
-
|
|
770
|
-
//
|
|
771
|
-
//
|
|
772
|
-
//
|
|
773
|
-
//
|
|
774
|
-
//
|
|
775
|
-
|
|
776
|
-
|
|
777
|
-
|
|
778
|
-
|
|
779
|
-
|
|
780
|
-
|
|
781
|
-
|
|
782
|
-
|
|
783
|
-
|
|
784
|
-
|
|
785
|
-
|
|
786
|
-
|
|
787
|
-
|
|
788
|
-
|
|
789
|
-
|
|
790
|
-
|
|
791
|
-
|
|
792
|
-
|
|
793
|
-
|
|
794
|
-
|
|
795
|
-
|
|
796
|
-
}
|
|
797
|
-
|
|
798
|
-
|
|
799
|
-
// changeAddress needs the explicit P2ID script (matching sendCurrency), or
|
|
800
|
-
// it throws an untyped "no matching Script".
|
|
801
|
-
if (params.changeAddress.startsWith('i')) {
|
|
802
|
-
txb.addOutput(identityPaymentScript((0, brands_js_1.parseIAddress)(params.changeAddress, 'changeAddress')), (0, index_js_2.toSafeNumber)(selection.nativeChange));
|
|
803
|
-
}
|
|
804
|
-
else {
|
|
805
|
-
txb.addOutput(params.changeAddress, (0, index_js_2.toSafeNumber)(selection.nativeChange));
|
|
806
|
-
}
|
|
807
|
-
}
|
|
808
|
-
}
|
|
809
|
-
const unsignedTx = txb.buildIncomplete();
|
|
810
|
-
const allUtxos = [commitUtxo, ...selection.selected];
|
|
811
|
-
// Native value conservation. The parent-currency registration fee is a token
|
|
812
|
-
// reserve-transfer (selection returns any excess as token change), so the
|
|
813
|
-
// NATIVE fee this path pays is the commitment input's value (folded to fee,
|
|
814
|
-
// like VRSC registration) + the native import fee + the miner fee. Verified
|
|
815
|
-
// live on VRSCTEST: a sub-ID under `ownora` (1.0 token fee) paid 0.02 native.
|
|
816
|
-
(0, index_js_3.assertNativeConservation)(allUtxos, unsignedTx.outs, commitUtxo.satoshis + nativeImportFee + selection.fee, 'sub-ID registration');
|
|
817
|
-
const { signedTx, txid } = (0, index_js_3.signTransactionSmart)(unsignedTx.toHex(), params.wif, allUtxos, network);
|
|
738
|
+
// The identity + reservation outputs carry 0 native but embed the full
|
|
739
|
+
// serialized identity / advanced name reservation (a large contentMultimap
|
|
740
|
+
// makes them multi-KB), so the fee is sized from their real bytes — matching
|
|
741
|
+
// the VRSC/update/define paths — instead of the fixed smart-output estimate.
|
|
742
|
+
// The fee output carries the parent-currency registration fee (a reserve output
|
|
743
|
+
// for pp2, a reserve transfer for pp1); the parent's idimportfees leaves as a
|
|
744
|
+
// DECLARED native burn. Verified live on VRSCTEST: a sub-ID under `ownora`
|
|
745
|
+
// (1.0 token fee) paid 0.02 native.
|
|
746
|
+
const assembled = (0, assembler_js_1.assembleAndSign)({
|
|
747
|
+
network,
|
|
748
|
+
wif: params.wif,
|
|
749
|
+
expiryHeight: params.expiryHeight,
|
|
750
|
+
funding: params.utxos,
|
|
751
|
+
// The name-commitment output is spent as input 0 (it carries no currency).
|
|
752
|
+
leadingInputs: [params.commitmentUtxo],
|
|
753
|
+
outputs: [
|
|
754
|
+
{ script: identityScript, nativeSat: 0n },
|
|
755
|
+
{ script: feeOutput.script, nativeSat: feeOutput.nativeValue, carries: requiredCurrencies },
|
|
756
|
+
{ script: reservationScript, nativeSat: 0n },
|
|
757
|
+
],
|
|
758
|
+
changeAddress: params.changeAddress,
|
|
759
|
+
// Legacy fee estimate: identity + fee + reservation, plus the one extra change
|
|
760
|
+
// slot the original path counted on top of selectUtxos' own reserve.
|
|
761
|
+
feeOutputCount: 4,
|
|
762
|
+
extraOutputBytes: identityScript.length + reservationScript.length + feeOutput.script.length,
|
|
763
|
+
fee: {
|
|
764
|
+
policy: 'declared',
|
|
765
|
+
burnSat: nativeImportFee,
|
|
766
|
+
reason: "parent currency's idimportfees (leaves as native import fee)",
|
|
767
|
+
},
|
|
768
|
+
label: 'sub-ID registration',
|
|
769
|
+
});
|
|
818
770
|
return {
|
|
819
|
-
signedTx,
|
|
820
|
-
txid,
|
|
821
|
-
fee:
|
|
771
|
+
signedTx: assembled.signedTx,
|
|
772
|
+
txid: assembled.txid,
|
|
773
|
+
fee: assembled.fee,
|
|
822
774
|
identityAddress,
|
|
823
775
|
registrationFee: registrationFeeAmount,
|
|
824
776
|
referralPayments: 0,
|
|
825
777
|
referralAmountEach: 0n,
|
|
826
|
-
inputsUsed:
|
|
827
|
-
nativeChange:
|
|
778
|
+
inputsUsed: assembled.inputsUsed,
|
|
779
|
+
nativeChange: assembled.nativeChange,
|
|
828
780
|
};
|
|
829
781
|
}
|
|
830
782
|
/**
|
|
@@ -839,9 +791,7 @@ function buildAndSignIdentityUpdate(params, network, operation = 'update', lockU
|
|
|
839
791
|
throw new errors_js_1.TransactionBuildError('At least one funding UTXO is required');
|
|
840
792
|
}
|
|
841
793
|
const verusNetwork = (0, index_js_3.getNetwork)(network === 'testnet');
|
|
842
|
-
const
|
|
843
|
-
const systemId = networkConfig.chainId;
|
|
844
|
-
const identity = new verus_typescript_primitives_1.Identity();
|
|
794
|
+
const identity = new boundary_js_1.Identity();
|
|
845
795
|
identity.fromBuffer(Buffer.from(params.identityHex, 'hex'));
|
|
846
796
|
// update/lock/unlock are authorized by the identity's primary key(s). The fork
|
|
847
797
|
// signs CC inputs with whatever key it is given, so a WIF that does not control
|
|
@@ -863,7 +813,7 @@ function buildAndSignIdentityUpdate(params, network, operation = 'update', lockU
|
|
|
863
813
|
requiresPrimary = authority === self;
|
|
864
814
|
}
|
|
865
815
|
if (requiresPrimary) {
|
|
866
|
-
const signerAddress =
|
|
816
|
+
const signerAddress = boundary_js_4.ECPair.fromWIF(params.wif, verusNetwork).getAddress();
|
|
867
817
|
const currentPrimaries = (identity.primary_addresses ?? []).map((k) => k.toAddress());
|
|
868
818
|
if (!currentPrimaries.includes(signerAddress)) {
|
|
869
819
|
throw new errors_js_1.TransactionBuildError(`the provided WIF (${signerAddress}) is not among the identity's primary addresses ` +
|
|
@@ -934,7 +884,7 @@ function buildAndSignIdentityUpdate(params, network, operation = 'update', lockU
|
|
|
934
884
|
}
|
|
935
885
|
jsonObj[key] = items;
|
|
936
886
|
}
|
|
937
|
-
identity.content_multimap =
|
|
887
|
+
identity.content_multimap = boundary_js_1.ContentMultiMap.fromJson(jsonObj);
|
|
938
888
|
}
|
|
939
889
|
break;
|
|
940
890
|
}
|
|
@@ -1007,67 +957,32 @@ function buildAndSignIdentityUpdate(params, network, operation = 'update', lockU
|
|
|
1007
957
|
}
|
|
1008
958
|
const identityBuf = identity.toBuffer();
|
|
1009
959
|
const unfundedHex = createUnfundedIdentityUpdate(identityBuf.toString('hex'), verusNetwork, (0, index_js_3.resolveExpiryHeight)(params.expiryHeight));
|
|
1010
|
-
const
|
|
1011
|
-
//
|
|
1012
|
-
//
|
|
1013
|
-
//
|
|
1014
|
-
|
|
1015
|
-
|
|
1016
|
-
|
|
1017
|
-
|
|
1018
|
-
|
|
1019
|
-
|
|
1020
|
-
|
|
1021
|
-
|
|
1022
|
-
|
|
1023
|
-
|
|
1024
|
-
|
|
1025
|
-
|
|
1026
|
-
|
|
1027
|
-
for (const out of unfundedTx.outs) {
|
|
1028
|
-
txb.addOutput(out.script, out.value);
|
|
1029
|
-
}
|
|
1030
|
-
if (selection.nativeChange > 0n) {
|
|
1031
|
-
// utxo-lib's addOutput only resolves base58 R-addresses; an i-address
|
|
1032
|
-
// changeAddress needs the explicit P2ID script (matching sendCurrency), or
|
|
1033
|
-
// it throws an untyped "no matching Script".
|
|
1034
|
-
if (params.changeAddress.startsWith('i')) {
|
|
1035
|
-
txb.addOutput(identityPaymentScript((0, brands_js_1.parseIAddress)(params.changeAddress, 'changeAddress')), (0, index_js_2.toSafeNumber)(selection.nativeChange));
|
|
1036
|
-
}
|
|
1037
|
-
else {
|
|
1038
|
-
txb.addOutput(params.changeAddress, (0, index_js_2.toSafeNumber)(selection.nativeChange));
|
|
1039
|
-
}
|
|
1040
|
-
}
|
|
1041
|
-
const fundedTx = txb.buildIncomplete();
|
|
1042
|
-
const fundedHex = fundedTx.toHex();
|
|
1043
|
-
const prevOutScripts = selection.selected.map(u => Buffer.from(u.script, 'hex'));
|
|
1044
|
-
const idUtxo = params.identityUtxo;
|
|
1045
|
-
// The identity input is spent and its definition output is recreated with
|
|
1046
|
-
// value 0, so any native value riding on identityUtxo would be silently
|
|
1047
|
-
// burned to miner fee. Identity outputs normally carry 0; fail closed if not.
|
|
1048
|
-
if (idUtxo.satoshis !== 0n) {
|
|
1049
|
-
throw new errors_js_1.TransactionBuildError(`identityUtxo carries ${idUtxo.satoshis} native satoshis, which would be burned to miner fee ` +
|
|
1050
|
-
`(the recreated identity output is value 0). Spend that value separately before updating.`);
|
|
1051
|
-
}
|
|
1052
|
-
const completedHex = completeFundedIdentityUpdate(fundedHex, verusNetwork, prevOutScripts, {
|
|
1053
|
-
hash: Buffer.from(idUtxo.txid, 'hex').reverse(),
|
|
1054
|
-
index: idUtxo.outputIndex,
|
|
1055
|
-
sequence: 0xffffffff,
|
|
1056
|
-
script: Buffer.from(idUtxo.script, 'hex'),
|
|
960
|
+
const unfundedTx = boundary_js_4.Transaction.fromHex(unfundedHex, verusNetwork);
|
|
961
|
+
// Respend the identity UTXO and recreate its (value-0) definition output; the
|
|
962
|
+
// shared assembler funds it, emits native change, grafts on the identity input
|
|
963
|
+
// (re-signed last by the fork), and enforces native + token conservation.
|
|
964
|
+
const assembled = (0, fundedIdentityUpdate_js_1.assembleFundedIdentityUpdate)({
|
|
965
|
+
network,
|
|
966
|
+
wif: params.wif,
|
|
967
|
+
expiryHeight: params.expiryHeight,
|
|
968
|
+
funding: params.utxos,
|
|
969
|
+
identityUtxo: params.identityUtxo,
|
|
970
|
+
outputs: unfundedTx.outs.map((o) => ({ script: o.script, nativeSat: BigInt(o.value) })),
|
|
971
|
+
changeAddress: params.changeAddress,
|
|
972
|
+
// The identity output embeds the full serialized identity (a large
|
|
973
|
+
// contentMultimap can make it multi-KB); size the fee from the unfunded tx's
|
|
974
|
+
// real bytes so a big update isn't fee-estimated below the relay minimum.
|
|
975
|
+
extraOutputBytes: unfundedHex.length / 2,
|
|
976
|
+
label: `identity ${operation}`,
|
|
1057
977
|
});
|
|
1058
|
-
const allUtxos = [...selection.selected, idUtxo];
|
|
1059
|
-
// The identity input and its recreated output are both value 0, so the
|
|
1060
|
-
// assembled native fee must equal selection.fee. Fail loudly on any slip.
|
|
1061
|
-
(0, index_js_3.assertNativeConservation)(allUtxos, utxo_lib_1.Transaction.fromHex(completedHex, verusNetwork).outs, selection.fee, `identity ${operation}`);
|
|
1062
|
-
const { signedTx, txid } = (0, index_js_3.signTransactionSmart)(completedHex, params.wif, allUtxos, verusNetwork);
|
|
1063
978
|
return {
|
|
1064
|
-
signedTx,
|
|
1065
|
-
txid,
|
|
1066
|
-
fee:
|
|
979
|
+
signedTx: assembled.signedTx,
|
|
980
|
+
txid: assembled.txid,
|
|
981
|
+
fee: assembled.fee,
|
|
1067
982
|
identityAddress: identity.getIdentityAddress(),
|
|
1068
983
|
operation,
|
|
1069
|
-
inputsUsed:
|
|
1070
|
-
nativeChange:
|
|
984
|
+
inputsUsed: assembled.inputsUsed,
|
|
985
|
+
nativeChange: assembled.nativeChange,
|
|
1071
986
|
};
|
|
1072
987
|
}
|
|
1073
988
|
//# sourceMappingURL=index.js.map
|