@kaspacom/kcc20-tx-builder 0.8.0-fee.3 → 0.8.0-fee.4

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/CHANGELOG.md CHANGED
@@ -1,5 +1,10 @@
1
1
  # Changelog
2
2
 
3
+ ## 0.8.0-fee.4
4
+
5
+ - Require the fee-account owner key to match the connected Schnorr funding wallet for creation and binding.
6
+ - Exclude the account source outpoint from binding funding and reject duplicate inputs.
7
+
3
8
  ## 0.8.0-fee.3
4
9
 
5
10
  - Build wallet-signable fee-account genesis and one-time market binding PSKTs from the pinned escrow artifact.
package/RELEASING.md CHANGED
@@ -95,9 +95,10 @@ consumer deployment. Record any unverified operation families explicitly.
95
95
 
96
96
  ## Fee integration prerelease
97
97
 
98
- Version `0.8.0-fee.3` adds fee-account creation and binding PSKTs for DEV
98
+ Version `0.8.0-fee.4` adds fee-account creation and binding PSKTs for DEV
99
99
  integration. Run the existing snapshot and example tests against the pinned
100
- WASM before publishing it under `next`. This prerelease does not build
100
+ WASM before publishing it under `next`. This version fixes fee.3's owner and
101
+ funding-source checks. This prerelease does not build
101
102
  fee-market trades, claims or authority rotation. Funded fee-market journeys and
102
103
  signed settlement construction remain required before enabling markets or
103
104
  promoting a stable fee release.
@@ -383,6 +383,7 @@ function createKcc20PsktBuilderEngine(options) {
383
383
  const principalSompi = parseU64(params.principalSompi, "fee account principal");
384
384
  const network = request.network || env.KASPA_NETWORK || "testnet-10";
385
385
  const walletAddress = requireKaspaAddress(request.owner?.walletAddress);
386
+ assertFeeAccountSchnorrWalletOwner(walletAddress, owner);
386
387
  const priorityFee = parseU64(env.KCC20_FEE_ACCOUNT_PRIORITY_FEE_SOMPI || DEFAULT_PRIORITY_FEE.toString(), "priorityFee");
387
388
  const artifactKey = "KCC20FeeEscrowV1.placeholder.json";
388
389
  const supplied = options.artifacts?.[artifactKey] ?? await options.artifactProvider?.(artifactKey);
@@ -500,6 +501,7 @@ function createKcc20PsktBuilderEngine(options) {
500
501
  }
501
502
  const network = request.network || env.KASPA_NETWORK || "testnet-10";
502
503
  const walletAddress = requireKaspaAddress(request.owner?.walletAddress);
504
+ assertFeeAccountSchnorrWalletOwner(walletAddress, owner);
503
505
  const accountAddress = requireKaspaAddress(indexed.address);
504
506
  const priorityFee = parseU64(env.KCC20_FEE_ACCOUNT_PRIORITY_FEE_SOMPI || DEFAULT_PRIORITY_FEE.toString(), "priorityFee");
505
507
  const computeBudget = parsePositiveNumber(env.KCC20_FEE_ACCOUNT_COMPUTE_BUDGET || 500, "computeBudget");
@@ -545,7 +547,7 @@ function createKcc20PsktBuilderEngine(options) {
545
547
  tokenId, accountId, marketId, policyId,
546
548
  });
547
549
  assertScriptAddress(kw, plan.currentRedeemScript, accountAddress, network, "unbound fee account address");
548
- const fundingEntry = (0, sale_common_js_1.selectFundingEntry)(walletUtxos.entries, priorityFee + 10000n, [], params.fundingOutpoint);
550
+ const fundingEntry = (0, sale_common_js_1.selectFundingEntry)(walletUtxos.entries, priorityFee + 10000n, [accountEntry.outpoint], params.fundingOutpoint);
549
551
  const fundingAmount = (0, sale_common_js_1.utxoAmountSompi)(fundingEntry);
550
552
  if (fundingAmount <= priorityFee + 10000n)
551
553
  throw new Error("fee account binding funding change is too small");
@@ -568,6 +570,7 @@ function createKcc20PsktBuilderEngine(options) {
568
570
  });
569
571
  (0, sale_common_js_1.setVersionOneInputMassFields)(unsignedTx, computeBudget);
570
572
  unsignedTx.inputs[1].computeBudget = 30;
573
+ assertUniqueTransactionInputOutpoints(unsignedTx, "fee account binding");
571
574
  const scripts = [{
572
575
  inputIndex: 0,
573
576
  scriptHex: (0, sale_common_js_1.bytesToHex)(plan.currentRedeemScript),
@@ -9341,6 +9344,14 @@ function createKcc20PsktBuilderEngine(options) {
9341
9344
  throw new Error("owner.walletAddress must be a Kaspa address");
9342
9345
  return address;
9343
9346
  }
9347
+ function assertFeeAccountSchnorrWalletOwner(walletAddress, owner) {
9348
+ const script = String(kaspaWasm.payToAddressScript(walletAddress).script)
9349
+ .toLowerCase();
9350
+ const publicKey = /^20([0-9a-f]{64})ac$/.exec(script)?.[1];
9351
+ if (!publicKey || publicKey !== owner) {
9352
+ throw new Error("fee account owner must match the connected Schnorr wallet address");
9353
+ }
9354
+ }
9344
9355
  return {
9345
9356
  build: buildInProcessPskt,
9346
9357
  buildInProcessPskt,