@neuraiproject/neurai-assets 1.2.5 → 1.3.1
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 +47 -0
- package/dist/NeuraiAssets.global.js +238 -66
- package/dist/NeuraiAssets.global.js.map +1 -1
- package/dist/browser.js +238 -66
- package/dist/browser.js.map +1 -1
- package/dist/index.cjs +238 -66
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +238 -66
- package/dist/index.js.map +1 -1
- package/package.json +2 -1
package/README.md
CHANGED
|
@@ -651,3 +651,50 @@ console.log('Transaction ID:', txid);
|
|
|
651
651
|
For AuthScript wallets, derive addresses externally with `neurai-key`, then initialize
|
|
652
652
|
`NeuraiAssets` with those `nq1...` / `tnq1...` addresses. The recommended network labels
|
|
653
653
|
are `xna` and `xna-test`; `xna-pq` and `xna-pq-test` remain available as compatibility aliases.
|
|
654
|
+
|
|
655
|
+
## Fee estimation (PQ-aware)
|
|
656
|
+
|
|
657
|
+
Asset transactions are usually built with one or two XNA inputs plus, depending on the operation, an owner-token or qualifier UTXO. The library estimates the fee twice per build: a rough pre-estimate to size the initial XNA selection, and a final estimate once the actual UTXOs are known.
|
|
658
|
+
|
|
659
|
+
Both estimates share a single `estimatesmartfee` lookup. The fee rate is stable for the lifetime of one build, so it is fetched on the first `estimateFee` call and cached on the builder instance for the second — half as many RPC round trips as before `1.3.1`.
|
|
660
|
+
|
|
661
|
+
Both estimates use the helpers in [`src/utils/feeSizing.js`](src/utils/feeSizing.js) and distinguish PQ AuthScript inputs/outputs from legacy P2PKH ones. PQ inputs spend ~977 vbytes vs ~148 for legacy — without this distinction, transactions built from PQ addresses fall under the node's `min relay fee` and are rejected with `code -26: min relay fee not met`.
|
|
662
|
+
|
|
663
|
+
You should not need to call these helpers directly; they are wired into every builder. They are documented here so you can audit the fee math or use the same constants if you compose transactions outside the standard builder flow.
|
|
664
|
+
|
|
665
|
+
```js
|
|
666
|
+
const {
|
|
667
|
+
VBYTES,
|
|
668
|
+
estimateInputVbytes,
|
|
669
|
+
estimateOutputBytes,
|
|
670
|
+
estimateTransactionVbytes,
|
|
671
|
+
isPQAddress,
|
|
672
|
+
isPQScript,
|
|
673
|
+
} = require('@neuraiproject/neurai-assets/src/utils/feeSizing');
|
|
674
|
+
|
|
675
|
+
VBYTES.legacyInputVbytes; // 148
|
|
676
|
+
VBYTES.pqInputVbytes; // 977
|
|
677
|
+
VBYTES.legacyOutputBytes; // 34
|
|
678
|
+
VBYTES.pqOutputBytes; // 43
|
|
679
|
+
|
|
680
|
+
estimateInputVbytes({ script: '5120…' }); // 977
|
|
681
|
+
estimateInputVbytes({ address: 'nq1…' }); // 977
|
|
682
|
+
estimateInputVbytes({ address: 'mgRYHdMq…' }); // 148
|
|
683
|
+
estimateOutputBytes('tnq1…'); // 43
|
|
684
|
+
|
|
685
|
+
const vbytes = estimateTransactionVbytes(
|
|
686
|
+
[{ script: '5120…' }, { address: 'mgRYHdMq…' }], // 1 PQ + 1 legacy input
|
|
687
|
+
['nq1qchange…', 'mgRYHdMqburn…'], // 1 PQ + 1 legacy output
|
|
688
|
+
);
|
|
689
|
+
```
|
|
690
|
+
|
|
691
|
+
The constants mirror those exported from `@neuraiproject/neurai-sign-transaction` (`VBYTES`). They are inlined here on purpose: depending on the full signer would pull `bitcoinjs-lib` and `@noble/post-quantum` into the IIFE / browser bundles, far more weight than these constants need. The signer remains the source of truth — if it ever bumps a vbytes value, this file must follow.
|
|
692
|
+
|
|
693
|
+
### Limitations
|
|
694
|
+
|
|
695
|
+
The estimator assumes the most common spend layout for every input:
|
|
696
|
+
|
|
697
|
+
- legacy inputs → P2PKH `scriptSig` worst case (DER signature + compressed pubkey)
|
|
698
|
+
- PQ inputs → AuthScript v1 with the **default** `OP_TRUE` `witnessScript` and **no** `functionalArgs`
|
|
699
|
+
|
|
700
|
+
That covers all standard asset operations. If you build transactions whose PQ inputs use covenant `witnessScript`s, NoAuth (`authType=0x00`) or Legacy AuthScript (`authType=0x02`) witnesses, compute the witness size yourself and add it to the result of `estimateTransactionVbytes` (or use `estimateVirtualSize` from `@neuraiproject/neurai-sign-transaction` after building the raw transaction, which fills dummy witnesses of the worst-case size and returns the exact post-signing vsize).
|
|
@@ -2725,6 +2725,118 @@ var NeuraiAssetsBundle = (function (exports) {
|
|
|
2725
2725
|
return OwnerTokenManager_1;
|
|
2726
2726
|
}
|
|
2727
2727
|
|
|
2728
|
+
/**
|
|
2729
|
+
* Fee / size helpers for Neurai transactions.
|
|
2730
|
+
*
|
|
2731
|
+
* These constants and classifiers are the same ones exposed by
|
|
2732
|
+
* `@neuraiproject/neurai-sign-transaction` (`VBYTES`, `isPQAddress`,
|
|
2733
|
+
* `isPQScript`, `estimateInputVbytes`, `estimateOutputBytes`,
|
|
2734
|
+
* `estimateTransactionVbytes`). They are inlined here to keep the assets
|
|
2735
|
+
* package light: depending on the full signer would pull `bitcoinjs-lib`
|
|
2736
|
+
* and `@noble/post-quantum` into the IIFE / browser bundles, which is far
|
|
2737
|
+
* more weight than the few constants we actually need for fee estimation.
|
|
2738
|
+
*
|
|
2739
|
+
* SOURCE OF TRUTH: `@neuraiproject/neurai-sign-transaction` `src/estimate.ts`.
|
|
2740
|
+
* Keep these values in sync with the signer's `VBYTES`. Mismatches surface
|
|
2741
|
+
* immediately as `min relay fee not met` failures from the node.
|
|
2742
|
+
*/
|
|
2743
|
+
|
|
2744
|
+
var feeSizing;
|
|
2745
|
+
var hasRequiredFeeSizing;
|
|
2746
|
+
|
|
2747
|
+
function requireFeeSizing () {
|
|
2748
|
+
if (hasRequiredFeeSizing) return feeSizing;
|
|
2749
|
+
hasRequiredFeeSizing = 1;
|
|
2750
|
+
/** Per-component byte sizes used across the Neurai stack for fee estimation. */
|
|
2751
|
+
const VBYTES = Object.freeze({
|
|
2752
|
+
/** Raw transaction overhead: version (4) + in-count varint (1) + out-count varint (1) + locktime (4). */
|
|
2753
|
+
baseTxOverheadBytes: 10,
|
|
2754
|
+
/** Extra weight contributed by the segwit marker + flag bytes when any input is PQ. */
|
|
2755
|
+
segwitMarkerVbytes: 1,
|
|
2756
|
+
/** vbytes for a typical legacy P2PKH input (worst-case scriptSig). */
|
|
2757
|
+
legacyInputVbytes: 148,
|
|
2758
|
+
/** vbytes for a typical PQ AuthScript input with the default OP_TRUE witnessScript. */
|
|
2759
|
+
pqInputVbytes: 977,
|
|
2760
|
+
/** Bytes of a legacy P2PKH output (8-byte value + 1-byte script length + 25-byte scriptPubKey). */
|
|
2761
|
+
legacyOutputBytes: 34,
|
|
2762
|
+
/** Bytes of an AuthScript-v1 output (8-byte value + 1-byte script length + 34-byte scriptPubKey). */
|
|
2763
|
+
pqOutputBytes: 43,
|
|
2764
|
+
});
|
|
2765
|
+
|
|
2766
|
+
/** True for Neurai PQ AuthScript bech32 destinations (`nq1…` mainnet, `tnq1…` testnet). */
|
|
2767
|
+
function isPQAddress(address) {
|
|
2768
|
+
return (
|
|
2769
|
+
typeof address === 'string' &&
|
|
2770
|
+
(address.startsWith('nq1') || address.startsWith('tnq1'))
|
|
2771
|
+
);
|
|
2772
|
+
}
|
|
2773
|
+
|
|
2774
|
+
/** True for AuthScript-v1 scriptPubKey hex (witness v1, 32-byte program — `5120…`). */
|
|
2775
|
+
function isPQScript(scriptHex) {
|
|
2776
|
+
if (typeof scriptHex !== 'string' || scriptHex.length < 4) return false;
|
|
2777
|
+
return scriptHex.toLowerCase().startsWith('5120');
|
|
2778
|
+
}
|
|
2779
|
+
|
|
2780
|
+
/**
|
|
2781
|
+
* Estimate the vbytes contributed by spending one UTXO. Uses the UTXO's
|
|
2782
|
+
* `script` if available, otherwise falls back to its `address`. Unknown
|
|
2783
|
+
* prevouts are treated as legacy.
|
|
2784
|
+
*/
|
|
2785
|
+
function estimateInputVbytes(utxo) {
|
|
2786
|
+
const script = utxo && utxo.script;
|
|
2787
|
+
if (typeof script === 'string' && script.length > 0) {
|
|
2788
|
+
return isPQScript(script) ? VBYTES.pqInputVbytes : VBYTES.legacyInputVbytes;
|
|
2789
|
+
}
|
|
2790
|
+
const address = utxo && utxo.address;
|
|
2791
|
+
if (typeof address === 'string' && isPQAddress(address)) {
|
|
2792
|
+
return VBYTES.pqInputVbytes;
|
|
2793
|
+
}
|
|
2794
|
+
return VBYTES.legacyInputVbytes;
|
|
2795
|
+
}
|
|
2796
|
+
|
|
2797
|
+
/** Estimate the bytes contributed by an output (address string or `{address}`). */
|
|
2798
|
+
function estimateOutputBytes(target) {
|
|
2799
|
+
const address =
|
|
2800
|
+
typeof target === 'string' ? target : (target && target.address) || '';
|
|
2801
|
+
return isPQAddress(address) ? VBYTES.pqOutputBytes : VBYTES.legacyOutputBytes;
|
|
2802
|
+
}
|
|
2803
|
+
|
|
2804
|
+
/**
|
|
2805
|
+
* Sum the per-input/per-output contributions, plus base overhead and segwit
|
|
2806
|
+
* marker (added once when any input is PQ). Inputs may be partial UTXO-like
|
|
2807
|
+
* objects with `script` and/or `address`. Outputs may be address strings or
|
|
2808
|
+
* `{ address }` descriptors.
|
|
2809
|
+
*/
|
|
2810
|
+
function estimateTransactionVbytes(inputs, outputs) {
|
|
2811
|
+
let vbytes = VBYTES.baseTxOverheadBytes;
|
|
2812
|
+
let hasPQInput = false;
|
|
2813
|
+
|
|
2814
|
+
for (const inp of inputs) {
|
|
2815
|
+
const v = estimateInputVbytes(inp);
|
|
2816
|
+
vbytes += v;
|
|
2817
|
+
if (v === VBYTES.pqInputVbytes) hasPQInput = true;
|
|
2818
|
+
}
|
|
2819
|
+
|
|
2820
|
+
for (const out of outputs) {
|
|
2821
|
+
vbytes += estimateOutputBytes(out);
|
|
2822
|
+
}
|
|
2823
|
+
|
|
2824
|
+
if (hasPQInput) vbytes += VBYTES.segwitMarkerVbytes;
|
|
2825
|
+
|
|
2826
|
+
return vbytes;
|
|
2827
|
+
}
|
|
2828
|
+
|
|
2829
|
+
feeSizing = {
|
|
2830
|
+
VBYTES,
|
|
2831
|
+
isPQAddress,
|
|
2832
|
+
isPQScript,
|
|
2833
|
+
estimateInputVbytes,
|
|
2834
|
+
estimateOutputBytes,
|
|
2835
|
+
estimateTransactionVbytes,
|
|
2836
|
+
};
|
|
2837
|
+
return feeSizing;
|
|
2838
|
+
}
|
|
2839
|
+
|
|
2728
2840
|
/**
|
|
2729
2841
|
* UTXO Selector
|
|
2730
2842
|
* Selects appropriate UTXOs for asset transactions
|
|
@@ -2742,6 +2854,7 @@ var NeuraiAssetsBundle = (function (exports) {
|
|
|
2742
2854
|
if (hasRequiredUTXOSelector) return UTXOSelector_1;
|
|
2743
2855
|
hasRequiredUTXOSelector = 1;
|
|
2744
2856
|
const { InsufficientFundsError } = requireErrors();
|
|
2857
|
+
const { estimateTransactionVbytes } = requireFeeSizing();
|
|
2745
2858
|
|
|
2746
2859
|
class UTXOSelector {
|
|
2747
2860
|
/**
|
|
@@ -2980,35 +3093,44 @@ var NeuraiAssetsBundle = (function (exports) {
|
|
|
2980
3093
|
}
|
|
2981
3094
|
|
|
2982
3095
|
/**
|
|
2983
|
-
* Estimate transaction size in
|
|
2984
|
-
*
|
|
3096
|
+
* Estimate transaction size in vbytes for fee calculation.
|
|
3097
|
+
*
|
|
3098
|
+
* Both arguments accept either a count (legacy callers) or an array of
|
|
3099
|
+
* descriptors that allow the estimator to distinguish PQ AuthScript
|
|
3100
|
+
* inputs/outputs from legacy P2PKH ones — PQ inputs are roughly six
|
|
3101
|
+
* times larger than legacy inputs and would otherwise underflow the
|
|
3102
|
+
* node's `min relay fee`.
|
|
2985
3103
|
*
|
|
2986
|
-
*
|
|
2987
|
-
*
|
|
2988
|
-
*
|
|
3104
|
+
* Input descriptors may be UTXO-like objects with `script` and/or
|
|
3105
|
+
* `address`. Output descriptors may be address strings or `{ address }`.
|
|
3106
|
+
* When a count is provided instead of an array, every input/output is
|
|
3107
|
+
* treated as legacy.
|
|
3108
|
+
*
|
|
3109
|
+
* @param {number|Array} inputs - Input count or array of UTXO-like descriptors
|
|
3110
|
+
* @param {number|Array} outputs - Output count or array of address-like descriptors
|
|
3111
|
+
* @returns {number} Estimated vbytes
|
|
2989
3112
|
*/
|
|
2990
|
-
estimateTransactionSize(
|
|
2991
|
-
|
|
2992
|
-
|
|
2993
|
-
|
|
2994
|
-
|
|
2995
|
-
|
|
2996
|
-
|
|
2997
|
-
|
|
2998
|
-
|
|
2999
|
-
return inputSize + outputSize + overhead;
|
|
3113
|
+
estimateTransactionSize(inputs, outputs) {
|
|
3114
|
+
const inputDescriptors = Array.isArray(inputs)
|
|
3115
|
+
? inputs
|
|
3116
|
+
: new Array(inputs).fill({});
|
|
3117
|
+
const outputDescriptors = Array.isArray(outputs)
|
|
3118
|
+
? outputs
|
|
3119
|
+
: new Array(outputs).fill({});
|
|
3120
|
+
return estimateTransactionVbytes(inputDescriptors, outputDescriptors);
|
|
3000
3121
|
}
|
|
3001
3122
|
|
|
3002
3123
|
/**
|
|
3003
|
-
* Estimate fee for a transaction
|
|
3004
|
-
*
|
|
3005
|
-
* @param {number}
|
|
3124
|
+
* Estimate fee for a transaction.
|
|
3125
|
+
*
|
|
3126
|
+
* @param {number|Array} inputs - Input count or array of UTXO-like descriptors
|
|
3127
|
+
* @param {number|Array} outputs - Output count or array of address-like descriptors
|
|
3006
3128
|
* @param {number} feeRate - Fee rate in XNA per KB (default: 0.015)
|
|
3007
3129
|
* @returns {number} Estimated fee in XNA
|
|
3008
3130
|
*/
|
|
3009
|
-
estimateFee(
|
|
3010
|
-
const
|
|
3011
|
-
const sizeKB =
|
|
3131
|
+
estimateFee(inputs, outputs, feeRate = 0.015) {
|
|
3132
|
+
const sizeVbytes = this.estimateTransactionSize(inputs, outputs);
|
|
3133
|
+
const sizeKB = sizeVbytes / 1000;
|
|
3012
3134
|
const fee = sizeKB * feeRate;
|
|
3013
3135
|
|
|
3014
3136
|
// Round up to 8 decimals
|
|
@@ -4296,6 +4418,11 @@ var NeuraiAssetsBundle = (function (exports) {
|
|
|
4296
4418
|
this.ownerTokenManager = new OwnerTokenManager(rpc);
|
|
4297
4419
|
this.utxoSelector = new UTXOSelector(rpc);
|
|
4298
4420
|
this.outputOrderer = new OutputOrderer();
|
|
4421
|
+
|
|
4422
|
+
// `estimatesmartfee` is called twice per build (pre-selection guess and
|
|
4423
|
+
// post-selection recompute). The fee rate is stable for the duration of
|
|
4424
|
+
// a single build, so cache the first lookup and reuse it.
|
|
4425
|
+
this._feeRatePromise = null;
|
|
4299
4426
|
}
|
|
4300
4427
|
|
|
4301
4428
|
/**
|
|
@@ -4330,14 +4457,23 @@ var NeuraiAssetsBundle = (function (exports) {
|
|
|
4330
4457
|
}
|
|
4331
4458
|
|
|
4332
4459
|
/**
|
|
4333
|
-
* Estimate transaction fee
|
|
4334
|
-
*
|
|
4335
|
-
*
|
|
4460
|
+
* Estimate transaction fee.
|
|
4461
|
+
*
|
|
4462
|
+
* Both arguments accept either a count (legacy) or an array of descriptors
|
|
4463
|
+
* that lets the underlying estimator distinguish PQ AuthScript inputs/outputs
|
|
4464
|
+
* from legacy P2PKH ones. Pass arrays whenever you have actual UTXOs and
|
|
4465
|
+
* output addresses on hand — counts produce a legacy-only estimate.
|
|
4466
|
+
*
|
|
4467
|
+
* @param {number|Array} inputs - Input count or array of UTXO-like descriptors
|
|
4468
|
+
* @param {number|Array} outputs - Output count or array of address-like descriptors
|
|
4336
4469
|
* @returns {Promise<number>} Estimated fee in XNA
|
|
4337
4470
|
*/
|
|
4338
|
-
async estimateFee(
|
|
4339
|
-
|
|
4340
|
-
|
|
4471
|
+
async estimateFee(inputs, outputs) {
|
|
4472
|
+
if (!this._feeRatePromise) {
|
|
4473
|
+
this._feeRatePromise = this.utxoSelector.getFeeRate();
|
|
4474
|
+
}
|
|
4475
|
+
const feeRate = await this._feeRatePromise;
|
|
4476
|
+
return this.utxoSelector.estimateFee(inputs, outputs, feeRate);
|
|
4341
4477
|
}
|
|
4342
4478
|
|
|
4343
4479
|
/**
|
|
@@ -4799,7 +4935,8 @@ var NeuraiAssetsBundle = (function (exports) {
|
|
|
4799
4935
|
const changeAddress = await this.getChangeAddress();
|
|
4800
4936
|
|
|
4801
4937
|
// 5. Estimate fee (rough estimate for initial UTXO selection)
|
|
4802
|
-
const
|
|
4938
|
+
const outputAddresses = [burnInfo.address, changeAddress, toAddress];
|
|
4939
|
+
const estimatedFee = await this.estimateFee(1, outputAddresses);
|
|
4803
4940
|
|
|
4804
4941
|
// 6. Calculate total XNA needed
|
|
4805
4942
|
const totalXNANeeded = burnInfo.amount + estimatedFee;
|
|
@@ -4809,8 +4946,8 @@ var NeuraiAssetsBundle = (function (exports) {
|
|
|
4809
4946
|
const baseCurrencyUTXOs = utxoSelection.xnaUTXOs;
|
|
4810
4947
|
const totalXNAInput = utxoSelection.totalXNA;
|
|
4811
4948
|
|
|
4812
|
-
// 8. Recalculate fee with actual
|
|
4813
|
-
const actualFee = await this.estimateFee(baseCurrencyUTXOs
|
|
4949
|
+
// 8. Recalculate fee with actual inputs (PQ-aware)
|
|
4950
|
+
const actualFee = await this.estimateFee(baseCurrencyUTXOs, outputAddresses);
|
|
4814
4951
|
|
|
4815
4952
|
// 9. Verify we still have enough after fee recalculation
|
|
4816
4953
|
const totalRequired = burnInfo.amount + actualFee;
|
|
@@ -5034,7 +5171,13 @@ var NeuraiAssetsBundle = (function (exports) {
|
|
|
5034
5171
|
// 8. Estimate fee
|
|
5035
5172
|
// Inputs: XNA UTXOs + owner token UTXO
|
|
5036
5173
|
// Outputs: burn + change + owner token return + issue operation
|
|
5037
|
-
const
|
|
5174
|
+
const outputAddresses = [
|
|
5175
|
+
burnInfo.address,
|
|
5176
|
+
changeAddress,
|
|
5177
|
+
changeAddress, // owner token return goes to change address
|
|
5178
|
+
toAddress,
|
|
5179
|
+
];
|
|
5180
|
+
const estimatedFee = await this.estimateFee(2, outputAddresses);
|
|
5038
5181
|
|
|
5039
5182
|
// 9. Calculate total XNA needed
|
|
5040
5183
|
const totalXNANeeded = burnInfo.amount + estimatedFee;
|
|
@@ -5044,9 +5187,9 @@ var NeuraiAssetsBundle = (function (exports) {
|
|
|
5044
5187
|
const baseCurrencyUTXOs = utxoSelection.xnaUTXOs;
|
|
5045
5188
|
const totalXNAInput = utxoSelection.totalXNA;
|
|
5046
5189
|
|
|
5047
|
-
// 11. Recalculate fee with actual
|
|
5048
|
-
const
|
|
5049
|
-
const actualFee = await this.estimateFee(
|
|
5190
|
+
// 11. Recalculate fee with actual inputs (PQ-aware), including owner token UTXO
|
|
5191
|
+
const actualFeeInputs = [...baseCurrencyUTXOs, ownerTokenUTXO];
|
|
5192
|
+
const actualFee = await this.estimateFee(actualFeeInputs, outputAddresses);
|
|
5050
5193
|
|
|
5051
5194
|
// 12. Verify we have enough XNA
|
|
5052
5195
|
const totalRequired = burnInfo.amount + actualFee;
|
|
@@ -5248,14 +5391,15 @@ var NeuraiAssetsBundle = (function (exports) {
|
|
|
5248
5391
|
const toAddress = await this.getToAddress();
|
|
5249
5392
|
const changeAddress = await this.getChangeAddress();
|
|
5250
5393
|
|
|
5251
|
-
const
|
|
5394
|
+
const outputAddresses = [burnInfo.address, changeAddress, toAddress];
|
|
5395
|
+
const estimatedFee = await this.estimateFee(1, outputAddresses);
|
|
5252
5396
|
const totalXNANeeded = burnInfo.amount + estimatedFee;
|
|
5253
5397
|
|
|
5254
5398
|
const utxoSelection = await this.selectUTXOs(totalXNANeeded, null, 0);
|
|
5255
5399
|
const baseCurrencyUTXOs = utxoSelection.xnaUTXOs;
|
|
5256
5400
|
const totalXNAInput = utxoSelection.totalXNA;
|
|
5257
5401
|
|
|
5258
|
-
const actualFee = await this.estimateFee(baseCurrencyUTXOs
|
|
5402
|
+
const actualFee = await this.estimateFee(baseCurrencyUTXOs, outputAddresses);
|
|
5259
5403
|
const totalRequired = burnInfo.amount + actualFee;
|
|
5260
5404
|
|
|
5261
5405
|
if (totalXNAInput < totalRequired) {
|
|
@@ -5470,9 +5614,14 @@ var NeuraiAssetsBundle = (function (exports) {
|
|
|
5470
5614
|
|
|
5471
5615
|
// 8. Estimate fee
|
|
5472
5616
|
// Inputs: XNA UTXOs + owner token UTXO
|
|
5473
|
-
// Outputs: burn + change + reissue operation
|
|
5474
|
-
|
|
5475
|
-
|
|
5617
|
+
// Outputs: burn + change + owner token return + reissue operation
|
|
5618
|
+
const outputAddresses = [
|
|
5619
|
+
burnInfo.address,
|
|
5620
|
+
changeAddress,
|
|
5621
|
+
changeAddress, // owner token return goes to change address
|
|
5622
|
+
toAddress,
|
|
5623
|
+
];
|
|
5624
|
+
const estimatedFee = await this.estimateFee(2, outputAddresses);
|
|
5476
5625
|
|
|
5477
5626
|
// 9. Calculate total XNA needed
|
|
5478
5627
|
const totalXNANeeded = burnInfo.amount + estimatedFee;
|
|
@@ -5482,9 +5631,9 @@ var NeuraiAssetsBundle = (function (exports) {
|
|
|
5482
5631
|
const baseCurrencyUTXOs = utxoSelection.xnaUTXOs;
|
|
5483
5632
|
const totalXNAInput = utxoSelection.totalXNA;
|
|
5484
5633
|
|
|
5485
|
-
// 11. Recalculate fee with actual
|
|
5486
|
-
const
|
|
5487
|
-
const actualFee = await this.estimateFee(
|
|
5634
|
+
// 11. Recalculate fee with actual inputs (PQ-aware), including owner token UTXO
|
|
5635
|
+
const actualFeeInputs = [...baseCurrencyUTXOs, ownerTokenUTXO];
|
|
5636
|
+
const actualFee = await this.estimateFee(actualFeeInputs, outputAddresses);
|
|
5488
5637
|
|
|
5489
5638
|
// 12. Verify we have enough XNA
|
|
5490
5639
|
const totalRequired = burnInfo.amount + actualFee;
|
|
@@ -5745,7 +5894,13 @@ var NeuraiAssetsBundle = (function (exports) {
|
|
|
5745
5894
|
// 7. Estimate fee
|
|
5746
5895
|
// Inputs: XNA UTXOs + owner token UTXO
|
|
5747
5896
|
// Outputs: burn + change + owner token return + issue_unique operation
|
|
5748
|
-
const
|
|
5897
|
+
const outputAddresses = [
|
|
5898
|
+
burnInfo.address,
|
|
5899
|
+
changeAddress,
|
|
5900
|
+
changeAddress, // owner token return goes to change address
|
|
5901
|
+
toAddress,
|
|
5902
|
+
];
|
|
5903
|
+
const estimatedFee = await this.estimateFee(2, outputAddresses);
|
|
5749
5904
|
|
|
5750
5905
|
// 8. Calculate total XNA needed
|
|
5751
5906
|
const totalXNANeeded = burnInfo.amount + estimatedFee;
|
|
@@ -5755,9 +5910,9 @@ var NeuraiAssetsBundle = (function (exports) {
|
|
|
5755
5910
|
const baseCurrencyUTXOs = utxoSelection.xnaUTXOs;
|
|
5756
5911
|
const totalXNAInput = utxoSelection.totalXNA;
|
|
5757
5912
|
|
|
5758
|
-
// 10. Recalculate fee with actual
|
|
5759
|
-
const
|
|
5760
|
-
const actualFee = await this.estimateFee(
|
|
5913
|
+
// 10. Recalculate fee with actual inputs (PQ-aware), including owner token UTXO
|
|
5914
|
+
const actualFeeInputs = [...baseCurrencyUTXOs, ownerTokenUTXO];
|
|
5915
|
+
const actualFee = await this.estimateFee(actualFeeInputs, outputAddresses);
|
|
5761
5916
|
|
|
5762
5917
|
// 11. Verify we have enough XNA
|
|
5763
5918
|
const totalRequired = burnInfo.amount + actualFee;
|
|
@@ -6005,8 +6160,8 @@ var NeuraiAssetsBundle = (function (exports) {
|
|
|
6005
6160
|
const changeAddress = await this.getChangeAddress();
|
|
6006
6161
|
|
|
6007
6162
|
// 7. Estimate fee
|
|
6008
|
-
const
|
|
6009
|
-
const estimatedFee = await this.estimateFee(2,
|
|
6163
|
+
const outputAddresses = [burnInfo.address, changeAddress, toAddress];
|
|
6164
|
+
const estimatedFee = await this.estimateFee(2, outputAddresses);
|
|
6010
6165
|
|
|
6011
6166
|
// 8. Calculate total XNA needed
|
|
6012
6167
|
const totalXNANeeded = burnInfo.amount + estimatedFee;
|
|
@@ -6016,9 +6171,9 @@ var NeuraiAssetsBundle = (function (exports) {
|
|
|
6016
6171
|
const baseCurrencyUTXOs = utxoSelection.xnaUTXOs;
|
|
6017
6172
|
const totalXNAInput = utxoSelection.totalXNA;
|
|
6018
6173
|
|
|
6019
|
-
// 10. Recalculate fee with actual
|
|
6020
|
-
const
|
|
6021
|
-
const actualFee = await this.estimateFee(
|
|
6174
|
+
// 10. Recalculate fee with actual inputs (PQ-aware), including parent qualifier UTXOs
|
|
6175
|
+
const actualFeeInputs = [...baseCurrencyUTXOs, ...parentQualifierUTXOs];
|
|
6176
|
+
const actualFee = await this.estimateFee(actualFeeInputs, outputAddresses);
|
|
6022
6177
|
|
|
6023
6178
|
// 11. Verify we have enough XNA
|
|
6024
6179
|
const totalRequired = burnInfo.amount + actualFee;
|
|
@@ -6257,7 +6412,13 @@ var NeuraiAssetsBundle = (function (exports) {
|
|
|
6257
6412
|
}
|
|
6258
6413
|
|
|
6259
6414
|
// 7. Estimate fee (+1 for owner token input)
|
|
6260
|
-
const
|
|
6415
|
+
const outputAddresses = [
|
|
6416
|
+
burnInfo.address,
|
|
6417
|
+
changeAddress,
|
|
6418
|
+
changeAddress, // owner token return goes to change address
|
|
6419
|
+
toAddress,
|
|
6420
|
+
];
|
|
6421
|
+
const estimatedFee = await this.estimateFee(2, outputAddresses);
|
|
6261
6422
|
|
|
6262
6423
|
// 8. Calculate total XNA needed
|
|
6263
6424
|
const totalXNANeeded = burnInfo.amount + estimatedFee;
|
|
@@ -6267,8 +6428,9 @@ var NeuraiAssetsBundle = (function (exports) {
|
|
|
6267
6428
|
const baseCurrencyUTXOs = utxoSelection.xnaUTXOs;
|
|
6268
6429
|
const totalXNAInput = utxoSelection.totalXNA;
|
|
6269
6430
|
|
|
6270
|
-
// 10. Recalculate fee with actual
|
|
6271
|
-
const
|
|
6431
|
+
// 10. Recalculate fee with actual inputs (PQ-aware), including owner token UTXO
|
|
6432
|
+
const actualFeeInputs = [...baseCurrencyUTXOs, ownerTokenUTXO];
|
|
6433
|
+
const actualFee = await this.estimateFee(actualFeeInputs, outputAddresses);
|
|
6272
6434
|
|
|
6273
6435
|
// 11. Verify we have enough XNA
|
|
6274
6436
|
const totalRequired = burnInfo.amount + actualFee;
|
|
@@ -6525,7 +6687,13 @@ var NeuraiAssetsBundle = (function (exports) {
|
|
|
6525
6687
|
const burnInfo = this.burnManager.getReissueBurn();
|
|
6526
6688
|
|
|
6527
6689
|
// 8. Estimate fee
|
|
6528
|
-
const
|
|
6690
|
+
const outputAddresses = [
|
|
6691
|
+
burnInfo.address,
|
|
6692
|
+
changeAddress,
|
|
6693
|
+
changeAddress, // owner token return goes to change address
|
|
6694
|
+
toAddress,
|
|
6695
|
+
];
|
|
6696
|
+
const estimatedFee = await this.estimateFee(2, outputAddresses);
|
|
6529
6697
|
|
|
6530
6698
|
// 9. Calculate total XNA needed
|
|
6531
6699
|
const totalXNANeeded = burnInfo.amount + estimatedFee;
|
|
@@ -6535,9 +6703,9 @@ var NeuraiAssetsBundle = (function (exports) {
|
|
|
6535
6703
|
const baseCurrencyUTXOs = utxoSelection.xnaUTXOs;
|
|
6536
6704
|
const totalXNAInput = utxoSelection.totalXNA;
|
|
6537
6705
|
|
|
6538
|
-
// 11. Recalculate fee with actual
|
|
6539
|
-
const
|
|
6540
|
-
const actualFee = await this.estimateFee(
|
|
6706
|
+
// 11. Recalculate fee with actual inputs (PQ-aware), including owner token UTXO
|
|
6707
|
+
const actualFeeInputs = [...baseCurrencyUTXOs, ownerTokenUTXO];
|
|
6708
|
+
const actualFee = await this.estimateFee(actualFeeInputs, outputAddresses);
|
|
6541
6709
|
|
|
6542
6710
|
// 12. Verify we have enough XNA
|
|
6543
6711
|
const totalRequired = burnInfo.amount + actualFee;
|
|
@@ -6772,7 +6940,9 @@ var NeuraiAssetsBundle = (function (exports) {
|
|
|
6772
6940
|
: this.burnManager.getTagAddressBurn(addressCount);
|
|
6773
6941
|
|
|
6774
6942
|
// 6. Estimate fee
|
|
6775
|
-
|
|
6943
|
+
// Outputs: burn + XNA change + tag/untag operation (sent to changeAddress)
|
|
6944
|
+
const outputAddresses = [burnInfo.address, changeAddress, changeAddress];
|
|
6945
|
+
const estimatedFee = await this.estimateFee(2, outputAddresses);
|
|
6776
6946
|
|
|
6777
6947
|
// 7. Calculate total XNA needed
|
|
6778
6948
|
const totalXNANeeded = burnInfo.amount + estimatedFee;
|
|
@@ -6782,9 +6952,9 @@ var NeuraiAssetsBundle = (function (exports) {
|
|
|
6782
6952
|
const baseCurrencyUTXOs = utxoSelection.xnaUTXOs;
|
|
6783
6953
|
const totalXNAInput = utxoSelection.totalXNA;
|
|
6784
6954
|
|
|
6785
|
-
// 9. Recalculate fee with actual
|
|
6786
|
-
const
|
|
6787
|
-
const actualFee = await this.estimateFee(
|
|
6955
|
+
// 9. Recalculate fee with actual inputs (PQ-aware), including qualifier UTXOs
|
|
6956
|
+
const actualFeeInputs = [...baseCurrencyUTXOs, ...qualifierUTXOs];
|
|
6957
|
+
const actualFee = await this.estimateFee(actualFeeInputs, outputAddresses);
|
|
6788
6958
|
|
|
6789
6959
|
// 10. Verify we have enough XNA
|
|
6790
6960
|
const totalRequired = burnInfo.amount + actualFee;
|
|
@@ -7019,16 +7189,18 @@ var NeuraiAssetsBundle = (function (exports) {
|
|
|
7019
7189
|
const burnAmount = 0;
|
|
7020
7190
|
|
|
7021
7191
|
// 6. Estimate fee
|
|
7022
|
-
|
|
7192
|
+
// Outputs: XNA change + freeze/unfreeze operation (sent to changeAddress)
|
|
7193
|
+
const outputAddresses = [changeAddress, changeAddress];
|
|
7194
|
+
const estimatedFee = await this.estimateFee(2, outputAddresses);
|
|
7023
7195
|
|
|
7024
7196
|
// 7. Select XNA UTXOs (only for fee, no burn)
|
|
7025
7197
|
const utxoSelection = await this.selectUTXOs(estimatedFee, null, 0);
|
|
7026
7198
|
const baseCurrencyUTXOs = utxoSelection.xnaUTXOs;
|
|
7027
7199
|
const totalXNAInput = utxoSelection.totalXNA;
|
|
7028
7200
|
|
|
7029
|
-
// 8. Recalculate fee with actual
|
|
7030
|
-
const
|
|
7031
|
-
const actualFee = await this.estimateFee(
|
|
7201
|
+
// 8. Recalculate fee with actual inputs (PQ-aware), including owner token UTXO
|
|
7202
|
+
const actualFeeInputs = [...baseCurrencyUTXOs, ownerTokenUTXO];
|
|
7203
|
+
const actualFee = await this.estimateFee(actualFeeInputs, outputAddresses);
|
|
7032
7204
|
|
|
7033
7205
|
// 9. Verify we have enough XNA for fee
|
|
7034
7206
|
if (totalXNAInput < actualFee) {
|