@kaspacom/kcc20-tx-builder 0.8.0-fee.13 → 0.8.0-fee.14
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cjs/engine.js +147 -91
- package/dist/cjs/engine.js.map +1 -1
- package/dist/engine.d.ts.map +1 -1
- package/dist/engine.js +147 -91
- package/dist/engine.js.map +1 -1
- package/docs/COMPATIBILITY.json +1 -1
- package/package.json +1 -1
- package/src/engine.ts +140 -93
package/dist/engine.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"engine.d.ts","sourceRoot":"","sources":["../src/engine.ts"],"names":[],"mappings":"AAiBA,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,qBAAqB,CAAC;AAChE,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAC;AAkFrD,MAAM,WAAW,6BAA6B;IAC5C,IAAI,EAAE,gBAAgB,CAAC;IACvB,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACnC,gBAAgB,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,OAAO,CAAC,OAAO,CAAC,CAAC;IACrD,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;IAC7B,cAAc,CAAC,EAAE;QACf,mBAAmB,CAAC,IAAI,EAAE;YAAE,SAAS,EAAE,MAAM,EAAE,CAAA;SAAE,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;KACtE,CAAC;IACF,gBAAgB,CAAC,EAAE,CAAC,MAAM,EAAE,OAAO,KAAK,GAAG,CAAC;IAC5C,gBAAgB,CAAC,EAAE,OAAO,CAAC;IAC3B,yBAAyB,CAAC,EAAE;QAAE,OAAO,EAAE,OAAO,CAAC;QAAC,KAAK,EAAE,OAAO,CAAA;KAAE,CAAC;IACjE,gFAAgF;IAChF,oBAAoB,CAAC,EAAE;QAAE,QAAQ,EAAE,oBAAoB,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,CAAC;CAC3E;AAED,MAAM,WAAW,8BAA8B;IAC7C,kBAAkB,EAAE,OAAO,CAAC;IAC5B,oBAAoB,EAAE,OAAO,CAAC;IAC9B,sBAAsB,EAAE,MAAM,CAAC;CAChC;AAED;;;;GAIG;AACH,MAAM,WAAW,oBAAoB;IACnC,QAAQ,EAAE,IAAI,EAAE,MAAM,GAAG,GAAG,CAAC;CAC9B;AAED,MAAM,WAAW,sBAAsB;IACrC,KAAK,CAAC,KAAK,EAAE,OAAO,GAAG,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC;IACxD,kBAAkB,CAAC,KAAK,EAAE,OAAO,GAAG,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC;IACrE,qCAAqC,CAAC,KAAK,EAAE;QAC3C,SAAS,EAAE,MAAM,CAAC;QAClB,cAAc,EAAE,MAAM,CAAC;QACvB,kBAAkB,EAAE,MAAM,CAAC;QAC3B,WAAW,EAAE,MAAM,CAAC;QACpB,OAAO,CAAC,EAAE,MAAM,CAAC;KAClB,GAAG,OAAO,CAAC,8BAA8B,CAAC,CAAC;IAC5C,QAAQ,EAAE,oBAAoB,CAAC;CAChC;AAED,wBAAgB,4BAA4B,CAC1C,OAAO,EAAE,6BAA6B,GACrC,sBAAsB,
|
|
1
|
+
{"version":3,"file":"engine.d.ts","sourceRoot":"","sources":["../src/engine.ts"],"names":[],"mappings":"AAiBA,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,qBAAqB,CAAC;AAChE,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAC;AAkFrD,MAAM,WAAW,6BAA6B;IAC5C,IAAI,EAAE,gBAAgB,CAAC;IACvB,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACnC,gBAAgB,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,OAAO,CAAC,OAAO,CAAC,CAAC;IACrD,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;IAC7B,cAAc,CAAC,EAAE;QACf,mBAAmB,CAAC,IAAI,EAAE;YAAE,SAAS,EAAE,MAAM,EAAE,CAAA;SAAE,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;KACtE,CAAC;IACF,gBAAgB,CAAC,EAAE,CAAC,MAAM,EAAE,OAAO,KAAK,GAAG,CAAC;IAC5C,gBAAgB,CAAC,EAAE,OAAO,CAAC;IAC3B,yBAAyB,CAAC,EAAE;QAAE,OAAO,EAAE,OAAO,CAAC;QAAC,KAAK,EAAE,OAAO,CAAA;KAAE,CAAC;IACjE,gFAAgF;IAChF,oBAAoB,CAAC,EAAE;QAAE,QAAQ,EAAE,oBAAoB,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,CAAC;CAC3E;AAED,MAAM,WAAW,8BAA8B;IAC7C,kBAAkB,EAAE,OAAO,CAAC;IAC5B,oBAAoB,EAAE,OAAO,CAAC;IAC9B,sBAAsB,EAAE,MAAM,CAAC;CAChC;AAED;;;;GAIG;AACH,MAAM,WAAW,oBAAoB;IACnC,QAAQ,EAAE,IAAI,EAAE,MAAM,GAAG,GAAG,CAAC;CAC9B;AAED,MAAM,WAAW,sBAAsB;IACrC,KAAK,CAAC,KAAK,EAAE,OAAO,GAAG,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC;IACxD,kBAAkB,CAAC,KAAK,EAAE,OAAO,GAAG,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC;IACrE,qCAAqC,CAAC,KAAK,EAAE;QAC3C,SAAS,EAAE,MAAM,CAAC;QAClB,cAAc,EAAE,MAAM,CAAC;QACvB,kBAAkB,EAAE,MAAM,CAAC;QAC3B,WAAW,EAAE,MAAM,CAAC;QACpB,OAAO,CAAC,EAAE,MAAM,CAAC;KAClB,GAAG,OAAO,CAAC,8BAA8B,CAAC,CAAC;IAC5C,QAAQ,EAAE,oBAAoB,CAAC;CAChC;AAED,wBAAgB,4BAA4B,CAC1C,OAAO,EAAE,6BAA6B,GACrC,sBAAsB,CAqshBxB"}
|
package/dist/engine.js
CHANGED
|
@@ -4326,99 +4326,155 @@ export function createKcc20PsktBuilderEngine(options) {
|
|
|
4326
4326
|
? outputSompi + priorityFee - covenantSompi + 10000n
|
|
4327
4327
|
: priorityFee + 10000n;
|
|
4328
4328
|
const fundingEntry = selectFundingEntry(walletUtxos.entries, fundingNeeded, spentEntries.map(entry => entry.outpoint), params.fundingOutpoint);
|
|
4329
|
-
|
|
4330
|
-
|
|
4331
|
-
|
|
4332
|
-
|
|
4333
|
-
|
|
4334
|
-
|
|
4335
|
-
|
|
4336
|
-
|
|
4337
|
-
|
|
4338
|
-
|
|
4339
|
-
|
|
4340
|
-
|
|
4341
|
-
|
|
4342
|
-
|
|
4343
|
-
|
|
4344
|
-
|
|
4345
|
-
|
|
4346
|
-
|
|
4347
|
-
|
|
4348
|
-
|
|
4349
|
-
|
|
4350
|
-
|
|
4351
|
-
|
|
4352
|
-
|
|
4353
|
-
|
|
4354
|
-
|
|
4355
|
-
|
|
4356
|
-
|
|
4357
|
-
|
|
4358
|
-
|
|
4359
|
-
|
|
4360
|
-
const
|
|
4361
|
-
|
|
4362
|
-
|
|
4363
|
-
indexes
|
|
4364
|
-
|
|
4329
|
+
let estimatedFundingFeeSompi = priorityFee;
|
|
4330
|
+
const buildWithFunding = (fundingEntry) => {
|
|
4331
|
+
const fundingChange = covenantSompi + utxoAmountSompi(fundingEntry) - outputSompi - priorityFee;
|
|
4332
|
+
if (fundingChange <= 10000n)
|
|
4333
|
+
throw new Error("seller group funding change is too small");
|
|
4334
|
+
const fundingChangeIndex = outputs.length;
|
|
4335
|
+
const candidateOutputs = [...outputs,
|
|
4336
|
+
new TransactionOutput(fundingChange, payToAddressScript(walletAddress))];
|
|
4337
|
+
const transaction = new Transaction({ version: 1, lockTime: 0n,
|
|
4338
|
+
inputs: [
|
|
4339
|
+
{ previousOutpoint: holderEntry.outpoint, utxo: holderEntry,
|
|
4340
|
+
sequence: 0n, sigOpCount: 0, computeBudget: 1000 },
|
|
4341
|
+
...bidEntries.map(({ entry }) => ({ previousOutpoint: entry.outpoint, utxo: entry,
|
|
4342
|
+
sequence: 0n, sigOpCount: 0, computeBudget: 100 })),
|
|
4343
|
+
...(ticketEntry ? [{ previousOutpoint: ticketEntry.outpoint, utxo: ticketEntry,
|
|
4344
|
+
sequence: 0n, sigOpCount: 0, computeBudget: 600 }] : []),
|
|
4345
|
+
{ previousOutpoint: fundingEntry.outpoint, utxo: fundingEntry,
|
|
4346
|
+
sequence: 0n, sigOpCount: 0, computeBudget: 30 },
|
|
4347
|
+
], outputs: candidateOutputs, subnetworkId: SUBNETWORK_ID_NATIVE, gas: 0n, payload: "",
|
|
4348
|
+
});
|
|
4349
|
+
// Pinned signed consensus proof uses 394 units for ten-bid leader and
|
|
4350
|
+
// 43 for each bid delegator. Leave more than 2x headroom per role.
|
|
4351
|
+
setVersionOneInputMassFields(transaction, 1000);
|
|
4352
|
+
for (let slot = 0; slot < legs.length; slot++)
|
|
4353
|
+
transaction.inputs[slot + 1].computeBudget = 100;
|
|
4354
|
+
const ticketInputIndex = ticketEntry ? legs.length + 1 : -1;
|
|
4355
|
+
if (ticketEntry)
|
|
4356
|
+
transaction.inputs[ticketInputIndex].computeBudget = 600;
|
|
4357
|
+
const fundingInputIndex = legs.length + 1 + (ticketEntry ? 1 : 0);
|
|
4358
|
+
transaction.inputs[fundingInputIndex].computeBudget = 30;
|
|
4359
|
+
assertUniqueTransactionInputOutpoints(transaction, "fee-market seller group");
|
|
4360
|
+
const legBytes = new Uint8Array(legs.length * 32);
|
|
4361
|
+
const view = new DataView(legBytes.buffer);
|
|
4362
|
+
for (let slot = 0; slot < legs.length; slot++) {
|
|
4363
|
+
const indexes = legIndexes[slot];
|
|
4364
|
+
for (const [field, value] of [legs[slot].fill, indexes.buyerIndex,
|
|
4365
|
+
indexes.continuationIndex < 0 ? 0 : indexes.continuationIndex,
|
|
4366
|
+
indexes.sellerIndex].entries()) {
|
|
4367
|
+
view.setBigInt64(slot * 32 + field * 8, BigInt(value), true);
|
|
4368
|
+
}
|
|
4365
4369
|
}
|
|
4366
|
-
|
|
4367
|
-
|
|
4368
|
-
|
|
4369
|
-
|
|
4370
|
-
|
|
4371
|
-
|
|
4372
|
-
|
|
4373
|
-
|
|
4374
|
-
|
|
4375
|
-
|
|
4376
|
-
|
|
4377
|
-
|
|
4378
|
-
|
|
4379
|
-
|
|
4380
|
-
|
|
4381
|
-
|
|
4382
|
-
|
|
4383
|
-
|
|
4384
|
-
delegate.
|
|
4385
|
-
|
|
4386
|
-
|
|
4387
|
-
|
|
4388
|
-
|
|
4389
|
-
|
|
4390
|
-
|
|
4391
|
-
|
|
4392
|
-
|
|
4393
|
-
|
|
4394
|
-
|
|
4395
|
-
|
|
4396
|
-
|
|
4397
|
-
|
|
4398
|
-
|
|
4399
|
-
|
|
4400
|
-
|
|
4401
|
-
|
|
4402
|
-
|
|
4403
|
-
|
|
4404
|
-
|
|
4405
|
-
|
|
4406
|
-
|
|
4407
|
-
|
|
4408
|
-
|
|
4409
|
-
|
|
4410
|
-
|
|
4411
|
-
|
|
4412
|
-
|
|
4413
|
-
|
|
4414
|
-
|
|
4415
|
-
|
|
4416
|
-
|
|
4417
|
-
|
|
4418
|
-
|
|
4419
|
-
|
|
4420
|
-
|
|
4370
|
+
const receiptParts = templateParts(normalizeSilverScriptArtifact(artifacts.receipt));
|
|
4371
|
+
const scripts = [{ inputIndex: 0,
|
|
4372
|
+
scriptHex: bytesToHex(holderPlan.holder.redeemScript), signType: 1,
|
|
4373
|
+
signatureScript: { mode: "ordered-args", args: [
|
|
4374
|
+
{ type: "signature" }, i64TemplateArg(legs.length), dataTemplateArg(legBytes),
|
|
4375
|
+
dataTemplateArg(vector), i64TemplateArg(ticketInputIndex), i64TemplateArg(receiptOutputIndex),
|
|
4376
|
+
i64TemplateArg(changeIndex), i64TemplateArg(refundIndex), i64TemplateArg(ticketRefundIndex),
|
|
4377
|
+
dataTemplateArg(feeTotal > 0n ? receiptParts.prefix : new Uint8Array()),
|
|
4378
|
+
dataTemplateArg(feeTotal > 0n ? receiptParts.suffix : new Uint8Array()),
|
|
4379
|
+
dataTemplateArg(dispatchTagFor(artifacts.holder, "sellIntoBids")),
|
|
4380
|
+
] } }];
|
|
4381
|
+
if (ticketEntry)
|
|
4382
|
+
scripts.push(feeTicketBurnScriptHint(ticketInputIndex, ticket.script, ticket.burnDispatchTag, ticketRefundIndex, ticket.burnTakesRefundOutput));
|
|
4383
|
+
for (let slot = 0; slot < legs.length; slot++) {
|
|
4384
|
+
const delegate = covenantScriptBuilder(kw);
|
|
4385
|
+
for (const value of [0, slot, legs[slot].remaining,
|
|
4386
|
+
legIndexes[slot].continuationIndex])
|
|
4387
|
+
delegate.addI64(BigInt(value));
|
|
4388
|
+
delegate.addData(dispatchTagFor(artifacts.bid, "delegateSellerGroup"));
|
|
4389
|
+
transaction.inputs[slot + 1].signatureScript = encodeCovenantP2shSignatureScript(delegate.drain(), legs[slot].bidScript.redeemScript);
|
|
4390
|
+
}
|
|
4391
|
+
const feeResult = transactionWithPredictedSignedFeeChange(kw, transaction, fundingChangeIndex, network, "fee-market seller group", candidate => {
|
|
4392
|
+
const serialized = candidate.serializeToSafeJSON();
|
|
4393
|
+
if (typeof serialized !== "string")
|
|
4394
|
+
throw new Error("seller group preflight serialization failed");
|
|
4395
|
+
const predicted = transactionJsonWithScriptHints(kw, JSON.parse(serialized), scripts);
|
|
4396
|
+
predicted.inputs[fundingInputIndex].signatureScript = encodeP2pkSignatureScript(bytesToHex(dummySignatureBytes()));
|
|
4397
|
+
return typeof kw.Transaction.deserializeFromSafeJSON === "function"
|
|
4398
|
+
? kw.Transaction.deserializeFromSafeJSON(JSON.stringify(predicted))
|
|
4399
|
+
: kw.Transaction.deserializeFromJSON(JSON.stringify(predicted));
|
|
4400
|
+
});
|
|
4401
|
+
estimatedFundingFeeSompi = feeResult.requiredFeeSompi;
|
|
4402
|
+
const signedMass = calculateToccataV1NonContextualMass(feeResult.predictedTransaction, "fee-market seller group");
|
|
4403
|
+
const storageMass = calculateToccataStorageMass(feeResult.predictedTransaction, "fee-market seller group");
|
|
4404
|
+
if (signedMass.computeMass > CONSOLIDATION_TARGET_TRANSACTION_MASS ||
|
|
4405
|
+
signedMass.transientMass > CONSOLIDATION_TARGET_TRANSACTION_MASS * 2n ||
|
|
4406
|
+
storageMass > CONSOLIDATION_TARGET_TRANSACTION_MASS) {
|
|
4407
|
+
throw kcc20PsktBuilderError("fee-market seller group exceeds signed mass target", "TRANSACTION_MASS_EXCEEDED", { computeMass: signedMass.computeMass,
|
|
4408
|
+
transientMass: signedMass.transientMass, storageMass });
|
|
4409
|
+
}
|
|
4410
|
+
return { schema: OUTPUT_SCHEMA,
|
|
4411
|
+
psktTransactionJson: feeResult.transaction.serializeToSafeJSON(),
|
|
4412
|
+
signInputs: [{ index: fundingInputIndex, sighashType: 1 }], scripts,
|
|
4413
|
+
submitTransactionSupported: true,
|
|
4414
|
+
metadata: { builderKey: "kcc20fee.sell-into-bids",
|
|
4415
|
+
operation: "fee-market-sell-into-bids", network, walletAddress,
|
|
4416
|
+
tokenId, marketId, policyId, fillCount: legs.length,
|
|
4417
|
+
soldAmount: sold.toString(),
|
|
4418
|
+
grossSompi: legs.reduce((sum, leg) => sum + leg.gross, 0n).toString(),
|
|
4419
|
+
protocolFeeSompi: protocolTotal.toString(),
|
|
4420
|
+
creatorFeeSompi: creatorTotal.toString(), receiptOutputIndex,
|
|
4421
|
+
ticketInputIndex, ticketRefundIndex,
|
|
4422
|
+
sellerChangeIndex: changeIndex, sellerRefundIndex: refundIndex,
|
|
4423
|
+
signedMass: { compute: signedMass.computeMass.toString(),
|
|
4424
|
+
transient: signedMass.transientMass.toString(), storage: storageMass.toString() } },
|
|
4425
|
+
};
|
|
4421
4426
|
};
|
|
4427
|
+
try {
|
|
4428
|
+
return buildWithFunding(fundingEntry);
|
|
4429
|
+
}
|
|
4430
|
+
catch (initialError) {
|
|
4431
|
+
// A large funding input can increase contextual storage mass. Preserve
|
|
4432
|
+
// caller-selected inputs; otherwise try at most seven smaller live
|
|
4433
|
+
// wallet UTXO amounts without changing the trade, fees, or mass limits.
|
|
4434
|
+
const details = initialError?.builderErrorDetails;
|
|
4435
|
+
if (params.fundingOutpoint != null ||
|
|
4436
|
+
initialError?.builderErrorCode !== "TRANSACTION_MASS_EXCEEDED" ||
|
|
4437
|
+
BigInt(details?.computeMass ?? 0) > CONSOLIDATION_TARGET_TRANSACTION_MASS ||
|
|
4438
|
+
BigInt(details?.transientMass ?? 0) > CONSOLIDATION_TARGET_TRANSACTION_MASS * 2n ||
|
|
4439
|
+
BigInt(details?.storageMass ?? 0) <= CONSOLIDATION_TARGET_TRANSACTION_MASS) {
|
|
4440
|
+
throw initialError;
|
|
4441
|
+
}
|
|
4442
|
+
const skipped = [...spentEntries.map(entry => entry.outpoint), fundingEntry.outpoint];
|
|
4443
|
+
const conservativeFundingNeeded = fundingNeeded +
|
|
4444
|
+
(estimatedFundingFeeSompi > priorityFee ? estimatedFundingFeeSompi - priorityFee : 0n);
|
|
4445
|
+
const candidates = walletUtxos.entries.filter(entry => utxoAmountSompi(entry) >= conservativeFundingNeeded &&
|
|
4446
|
+
utxoAmountSompi(entry) < utxoAmountSompi(fundingEntry))
|
|
4447
|
+
.sort((a, b) => utxoAmountSompi(a) < utxoAmountSompi(b) ? -1 :
|
|
4448
|
+
utxoAmountSompi(a) > utxoAmountSompi(b) ? 1 : 0);
|
|
4449
|
+
let attempted = 0;
|
|
4450
|
+
const attemptedAmounts = new Set();
|
|
4451
|
+
for (const candidate of candidates) {
|
|
4452
|
+
if (attempted === 7)
|
|
4453
|
+
break;
|
|
4454
|
+
const amountKey = utxoAmountSompi(candidate).toString();
|
|
4455
|
+
if (attemptedAmounts.has(amountKey))
|
|
4456
|
+
continue;
|
|
4457
|
+
let selected;
|
|
4458
|
+
try {
|
|
4459
|
+
selected = selectFundingEntry([candidate], fundingNeeded, skipped, params.fundingOutpoint);
|
|
4460
|
+
}
|
|
4461
|
+
catch {
|
|
4462
|
+
continue;
|
|
4463
|
+
}
|
|
4464
|
+
skipped.push(selected.outpoint);
|
|
4465
|
+
attemptedAmounts.add(amountKey);
|
|
4466
|
+
attempted++;
|
|
4467
|
+
try {
|
|
4468
|
+
return buildWithFunding(selected);
|
|
4469
|
+
}
|
|
4470
|
+
catch (error) {
|
|
4471
|
+
if (!["TRANSACTION_MASS_EXCEEDED", "KAS_FUNDING_CHANGE_TOO_SMALL",
|
|
4472
|
+
"KAS_FUNDING_FEE_INSUFFICIENT"].includes(error?.builderErrorCode))
|
|
4473
|
+
throw error;
|
|
4474
|
+
}
|
|
4475
|
+
}
|
|
4476
|
+
throw initialError;
|
|
4477
|
+
}
|
|
4422
4478
|
}
|
|
4423
4479
|
finally {
|
|
4424
4480
|
await rpc.disconnect();
|