@neuraiproject/neurai-assets 1.2.5 → 1.3.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 +45 -0
- package/dist/NeuraiAssets.global.js +229 -65
- package/dist/NeuraiAssets.global.js.map +1 -1
- package/dist/browser.js +229 -65
- package/dist/browser.js.map +1 -1
- package/dist/index.cjs +229 -65
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +229 -65
- package/dist/index.js.map +1 -1
- package/package.json +2 -1
package/README.md
CHANGED
|
@@ -651,3 +651,48 @@ 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 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`.
|
|
660
|
+
|
|
661
|
+
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.
|
|
662
|
+
|
|
663
|
+
```js
|
|
664
|
+
const {
|
|
665
|
+
VBYTES,
|
|
666
|
+
estimateInputVbytes,
|
|
667
|
+
estimateOutputBytes,
|
|
668
|
+
estimateTransactionVbytes,
|
|
669
|
+
isPQAddress,
|
|
670
|
+
isPQScript,
|
|
671
|
+
} = require('@neuraiproject/neurai-assets/src/utils/feeSizing');
|
|
672
|
+
|
|
673
|
+
VBYTES.legacyInputVbytes; // 148
|
|
674
|
+
VBYTES.pqInputVbytes; // 977
|
|
675
|
+
VBYTES.legacyOutputBytes; // 34
|
|
676
|
+
VBYTES.pqOutputBytes; // 43
|
|
677
|
+
|
|
678
|
+
estimateInputVbytes({ script: '5120…' }); // 977
|
|
679
|
+
estimateInputVbytes({ address: 'nq1…' }); // 977
|
|
680
|
+
estimateInputVbytes({ address: 'mgRYHdMq…' }); // 148
|
|
681
|
+
estimateOutputBytes('tnq1…'); // 43
|
|
682
|
+
|
|
683
|
+
const vbytes = estimateTransactionVbytes(
|
|
684
|
+
[{ script: '5120…' }, { address: 'mgRYHdMq…' }], // 1 PQ + 1 legacy input
|
|
685
|
+
['nq1qchange…', 'mgRYHdMqburn…'], // 1 PQ + 1 legacy output
|
|
686
|
+
);
|
|
687
|
+
```
|
|
688
|
+
|
|
689
|
+
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.
|
|
690
|
+
|
|
691
|
+
### Limitations
|
|
692
|
+
|
|
693
|
+
The estimator assumes the most common spend layout for every input:
|
|
694
|
+
|
|
695
|
+
- legacy inputs → P2PKH `scriptSig` worst case (DER signature + compressed pubkey)
|
|
696
|
+
- PQ inputs → AuthScript v1 with the **default** `OP_TRUE` `witnessScript` and **no** `functionalArgs`
|
|
697
|
+
|
|
698
|
+
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
|
|
@@ -4330,14 +4452,20 @@ var NeuraiAssetsBundle = (function (exports) {
|
|
|
4330
4452
|
}
|
|
4331
4453
|
|
|
4332
4454
|
/**
|
|
4333
|
-
* Estimate transaction fee
|
|
4334
|
-
*
|
|
4335
|
-
*
|
|
4455
|
+
* Estimate transaction fee.
|
|
4456
|
+
*
|
|
4457
|
+
* Both arguments accept either a count (legacy) or an array of descriptors
|
|
4458
|
+
* that lets the underlying estimator distinguish PQ AuthScript inputs/outputs
|
|
4459
|
+
* from legacy P2PKH ones. Pass arrays whenever you have actual UTXOs and
|
|
4460
|
+
* output addresses on hand — counts produce a legacy-only estimate.
|
|
4461
|
+
*
|
|
4462
|
+
* @param {number|Array} inputs - Input count or array of UTXO-like descriptors
|
|
4463
|
+
* @param {number|Array} outputs - Output count or array of address-like descriptors
|
|
4336
4464
|
* @returns {Promise<number>} Estimated fee in XNA
|
|
4337
4465
|
*/
|
|
4338
|
-
async estimateFee(
|
|
4466
|
+
async estimateFee(inputs, outputs) {
|
|
4339
4467
|
const feeRate = await this.utxoSelector.getFeeRate();
|
|
4340
|
-
return this.utxoSelector.estimateFee(
|
|
4468
|
+
return this.utxoSelector.estimateFee(inputs, outputs, feeRate);
|
|
4341
4469
|
}
|
|
4342
4470
|
|
|
4343
4471
|
/**
|
|
@@ -4799,7 +4927,8 @@ var NeuraiAssetsBundle = (function (exports) {
|
|
|
4799
4927
|
const changeAddress = await this.getChangeAddress();
|
|
4800
4928
|
|
|
4801
4929
|
// 5. Estimate fee (rough estimate for initial UTXO selection)
|
|
4802
|
-
const
|
|
4930
|
+
const outputAddresses = [burnInfo.address, changeAddress, toAddress];
|
|
4931
|
+
const estimatedFee = await this.estimateFee(1, outputAddresses);
|
|
4803
4932
|
|
|
4804
4933
|
// 6. Calculate total XNA needed
|
|
4805
4934
|
const totalXNANeeded = burnInfo.amount + estimatedFee;
|
|
@@ -4809,8 +4938,8 @@ var NeuraiAssetsBundle = (function (exports) {
|
|
|
4809
4938
|
const baseCurrencyUTXOs = utxoSelection.xnaUTXOs;
|
|
4810
4939
|
const totalXNAInput = utxoSelection.totalXNA;
|
|
4811
4940
|
|
|
4812
|
-
// 8. Recalculate fee with actual
|
|
4813
|
-
const actualFee = await this.estimateFee(baseCurrencyUTXOs
|
|
4941
|
+
// 8. Recalculate fee with actual inputs (PQ-aware)
|
|
4942
|
+
const actualFee = await this.estimateFee(baseCurrencyUTXOs, outputAddresses);
|
|
4814
4943
|
|
|
4815
4944
|
// 9. Verify we still have enough after fee recalculation
|
|
4816
4945
|
const totalRequired = burnInfo.amount + actualFee;
|
|
@@ -5034,7 +5163,13 @@ var NeuraiAssetsBundle = (function (exports) {
|
|
|
5034
5163
|
// 8. Estimate fee
|
|
5035
5164
|
// Inputs: XNA UTXOs + owner token UTXO
|
|
5036
5165
|
// Outputs: burn + change + owner token return + issue operation
|
|
5037
|
-
const
|
|
5166
|
+
const outputAddresses = [
|
|
5167
|
+
burnInfo.address,
|
|
5168
|
+
changeAddress,
|
|
5169
|
+
changeAddress, // owner token return goes to change address
|
|
5170
|
+
toAddress,
|
|
5171
|
+
];
|
|
5172
|
+
const estimatedFee = await this.estimateFee(2, outputAddresses);
|
|
5038
5173
|
|
|
5039
5174
|
// 9. Calculate total XNA needed
|
|
5040
5175
|
const totalXNANeeded = burnInfo.amount + estimatedFee;
|
|
@@ -5044,9 +5179,9 @@ var NeuraiAssetsBundle = (function (exports) {
|
|
|
5044
5179
|
const baseCurrencyUTXOs = utxoSelection.xnaUTXOs;
|
|
5045
5180
|
const totalXNAInput = utxoSelection.totalXNA;
|
|
5046
5181
|
|
|
5047
|
-
// 11. Recalculate fee with actual
|
|
5048
|
-
const
|
|
5049
|
-
const actualFee = await this.estimateFee(
|
|
5182
|
+
// 11. Recalculate fee with actual inputs (PQ-aware), including owner token UTXO
|
|
5183
|
+
const actualFeeInputs = [...baseCurrencyUTXOs, ownerTokenUTXO];
|
|
5184
|
+
const actualFee = await this.estimateFee(actualFeeInputs, outputAddresses);
|
|
5050
5185
|
|
|
5051
5186
|
// 12. Verify we have enough XNA
|
|
5052
5187
|
const totalRequired = burnInfo.amount + actualFee;
|
|
@@ -5248,14 +5383,15 @@ var NeuraiAssetsBundle = (function (exports) {
|
|
|
5248
5383
|
const toAddress = await this.getToAddress();
|
|
5249
5384
|
const changeAddress = await this.getChangeAddress();
|
|
5250
5385
|
|
|
5251
|
-
const
|
|
5386
|
+
const outputAddresses = [burnInfo.address, changeAddress, toAddress];
|
|
5387
|
+
const estimatedFee = await this.estimateFee(1, outputAddresses);
|
|
5252
5388
|
const totalXNANeeded = burnInfo.amount + estimatedFee;
|
|
5253
5389
|
|
|
5254
5390
|
const utxoSelection = await this.selectUTXOs(totalXNANeeded, null, 0);
|
|
5255
5391
|
const baseCurrencyUTXOs = utxoSelection.xnaUTXOs;
|
|
5256
5392
|
const totalXNAInput = utxoSelection.totalXNA;
|
|
5257
5393
|
|
|
5258
|
-
const actualFee = await this.estimateFee(baseCurrencyUTXOs
|
|
5394
|
+
const actualFee = await this.estimateFee(baseCurrencyUTXOs, outputAddresses);
|
|
5259
5395
|
const totalRequired = burnInfo.amount + actualFee;
|
|
5260
5396
|
|
|
5261
5397
|
if (totalXNAInput < totalRequired) {
|
|
@@ -5470,9 +5606,14 @@ var NeuraiAssetsBundle = (function (exports) {
|
|
|
5470
5606
|
|
|
5471
5607
|
// 8. Estimate fee
|
|
5472
5608
|
// Inputs: XNA UTXOs + owner token UTXO
|
|
5473
|
-
// Outputs: burn + change + reissue operation
|
|
5474
|
-
|
|
5475
|
-
|
|
5609
|
+
// Outputs: burn + change + owner token return + reissue operation
|
|
5610
|
+
const outputAddresses = [
|
|
5611
|
+
burnInfo.address,
|
|
5612
|
+
changeAddress,
|
|
5613
|
+
changeAddress, // owner token return goes to change address
|
|
5614
|
+
toAddress,
|
|
5615
|
+
];
|
|
5616
|
+
const estimatedFee = await this.estimateFee(2, outputAddresses);
|
|
5476
5617
|
|
|
5477
5618
|
// 9. Calculate total XNA needed
|
|
5478
5619
|
const totalXNANeeded = burnInfo.amount + estimatedFee;
|
|
@@ -5482,9 +5623,9 @@ var NeuraiAssetsBundle = (function (exports) {
|
|
|
5482
5623
|
const baseCurrencyUTXOs = utxoSelection.xnaUTXOs;
|
|
5483
5624
|
const totalXNAInput = utxoSelection.totalXNA;
|
|
5484
5625
|
|
|
5485
|
-
// 11. Recalculate fee with actual
|
|
5486
|
-
const
|
|
5487
|
-
const actualFee = await this.estimateFee(
|
|
5626
|
+
// 11. Recalculate fee with actual inputs (PQ-aware), including owner token UTXO
|
|
5627
|
+
const actualFeeInputs = [...baseCurrencyUTXOs, ownerTokenUTXO];
|
|
5628
|
+
const actualFee = await this.estimateFee(actualFeeInputs, outputAddresses);
|
|
5488
5629
|
|
|
5489
5630
|
// 12. Verify we have enough XNA
|
|
5490
5631
|
const totalRequired = burnInfo.amount + actualFee;
|
|
@@ -5745,7 +5886,13 @@ var NeuraiAssetsBundle = (function (exports) {
|
|
|
5745
5886
|
// 7. Estimate fee
|
|
5746
5887
|
// Inputs: XNA UTXOs + owner token UTXO
|
|
5747
5888
|
// Outputs: burn + change + owner token return + issue_unique operation
|
|
5748
|
-
const
|
|
5889
|
+
const outputAddresses = [
|
|
5890
|
+
burnInfo.address,
|
|
5891
|
+
changeAddress,
|
|
5892
|
+
changeAddress, // owner token return goes to change address
|
|
5893
|
+
toAddress,
|
|
5894
|
+
];
|
|
5895
|
+
const estimatedFee = await this.estimateFee(2, outputAddresses);
|
|
5749
5896
|
|
|
5750
5897
|
// 8. Calculate total XNA needed
|
|
5751
5898
|
const totalXNANeeded = burnInfo.amount + estimatedFee;
|
|
@@ -5755,9 +5902,9 @@ var NeuraiAssetsBundle = (function (exports) {
|
|
|
5755
5902
|
const baseCurrencyUTXOs = utxoSelection.xnaUTXOs;
|
|
5756
5903
|
const totalXNAInput = utxoSelection.totalXNA;
|
|
5757
5904
|
|
|
5758
|
-
// 10. Recalculate fee with actual
|
|
5759
|
-
const
|
|
5760
|
-
const actualFee = await this.estimateFee(
|
|
5905
|
+
// 10. Recalculate fee with actual inputs (PQ-aware), including owner token UTXO
|
|
5906
|
+
const actualFeeInputs = [...baseCurrencyUTXOs, ownerTokenUTXO];
|
|
5907
|
+
const actualFee = await this.estimateFee(actualFeeInputs, outputAddresses);
|
|
5761
5908
|
|
|
5762
5909
|
// 11. Verify we have enough XNA
|
|
5763
5910
|
const totalRequired = burnInfo.amount + actualFee;
|
|
@@ -6005,8 +6152,8 @@ var NeuraiAssetsBundle = (function (exports) {
|
|
|
6005
6152
|
const changeAddress = await this.getChangeAddress();
|
|
6006
6153
|
|
|
6007
6154
|
// 7. Estimate fee
|
|
6008
|
-
const
|
|
6009
|
-
const estimatedFee = await this.estimateFee(2,
|
|
6155
|
+
const outputAddresses = [burnInfo.address, changeAddress, toAddress];
|
|
6156
|
+
const estimatedFee = await this.estimateFee(2, outputAddresses);
|
|
6010
6157
|
|
|
6011
6158
|
// 8. Calculate total XNA needed
|
|
6012
6159
|
const totalXNANeeded = burnInfo.amount + estimatedFee;
|
|
@@ -6016,9 +6163,9 @@ var NeuraiAssetsBundle = (function (exports) {
|
|
|
6016
6163
|
const baseCurrencyUTXOs = utxoSelection.xnaUTXOs;
|
|
6017
6164
|
const totalXNAInput = utxoSelection.totalXNA;
|
|
6018
6165
|
|
|
6019
|
-
// 10. Recalculate fee with actual
|
|
6020
|
-
const
|
|
6021
|
-
const actualFee = await this.estimateFee(
|
|
6166
|
+
// 10. Recalculate fee with actual inputs (PQ-aware), including parent qualifier UTXOs
|
|
6167
|
+
const actualFeeInputs = [...baseCurrencyUTXOs, ...parentQualifierUTXOs];
|
|
6168
|
+
const actualFee = await this.estimateFee(actualFeeInputs, outputAddresses);
|
|
6022
6169
|
|
|
6023
6170
|
// 11. Verify we have enough XNA
|
|
6024
6171
|
const totalRequired = burnInfo.amount + actualFee;
|
|
@@ -6257,7 +6404,13 @@ var NeuraiAssetsBundle = (function (exports) {
|
|
|
6257
6404
|
}
|
|
6258
6405
|
|
|
6259
6406
|
// 7. Estimate fee (+1 for owner token input)
|
|
6260
|
-
const
|
|
6407
|
+
const outputAddresses = [
|
|
6408
|
+
burnInfo.address,
|
|
6409
|
+
changeAddress,
|
|
6410
|
+
changeAddress, // owner token return goes to change address
|
|
6411
|
+
toAddress,
|
|
6412
|
+
];
|
|
6413
|
+
const estimatedFee = await this.estimateFee(2, outputAddresses);
|
|
6261
6414
|
|
|
6262
6415
|
// 8. Calculate total XNA needed
|
|
6263
6416
|
const totalXNANeeded = burnInfo.amount + estimatedFee;
|
|
@@ -6267,8 +6420,9 @@ var NeuraiAssetsBundle = (function (exports) {
|
|
|
6267
6420
|
const baseCurrencyUTXOs = utxoSelection.xnaUTXOs;
|
|
6268
6421
|
const totalXNAInput = utxoSelection.totalXNA;
|
|
6269
6422
|
|
|
6270
|
-
// 10. Recalculate fee with actual
|
|
6271
|
-
const
|
|
6423
|
+
// 10. Recalculate fee with actual inputs (PQ-aware), including owner token UTXO
|
|
6424
|
+
const actualFeeInputs = [...baseCurrencyUTXOs, ownerTokenUTXO];
|
|
6425
|
+
const actualFee = await this.estimateFee(actualFeeInputs, outputAddresses);
|
|
6272
6426
|
|
|
6273
6427
|
// 11. Verify we have enough XNA
|
|
6274
6428
|
const totalRequired = burnInfo.amount + actualFee;
|
|
@@ -6525,7 +6679,13 @@ var NeuraiAssetsBundle = (function (exports) {
|
|
|
6525
6679
|
const burnInfo = this.burnManager.getReissueBurn();
|
|
6526
6680
|
|
|
6527
6681
|
// 8. Estimate fee
|
|
6528
|
-
const
|
|
6682
|
+
const outputAddresses = [
|
|
6683
|
+
burnInfo.address,
|
|
6684
|
+
changeAddress,
|
|
6685
|
+
changeAddress, // owner token return goes to change address
|
|
6686
|
+
toAddress,
|
|
6687
|
+
];
|
|
6688
|
+
const estimatedFee = await this.estimateFee(2, outputAddresses);
|
|
6529
6689
|
|
|
6530
6690
|
// 9. Calculate total XNA needed
|
|
6531
6691
|
const totalXNANeeded = burnInfo.amount + estimatedFee;
|
|
@@ -6535,9 +6695,9 @@ var NeuraiAssetsBundle = (function (exports) {
|
|
|
6535
6695
|
const baseCurrencyUTXOs = utxoSelection.xnaUTXOs;
|
|
6536
6696
|
const totalXNAInput = utxoSelection.totalXNA;
|
|
6537
6697
|
|
|
6538
|
-
// 11. Recalculate fee with actual
|
|
6539
|
-
const
|
|
6540
|
-
const actualFee = await this.estimateFee(
|
|
6698
|
+
// 11. Recalculate fee with actual inputs (PQ-aware), including owner token UTXO
|
|
6699
|
+
const actualFeeInputs = [...baseCurrencyUTXOs, ownerTokenUTXO];
|
|
6700
|
+
const actualFee = await this.estimateFee(actualFeeInputs, outputAddresses);
|
|
6541
6701
|
|
|
6542
6702
|
// 12. Verify we have enough XNA
|
|
6543
6703
|
const totalRequired = burnInfo.amount + actualFee;
|
|
@@ -6772,7 +6932,9 @@ var NeuraiAssetsBundle = (function (exports) {
|
|
|
6772
6932
|
: this.burnManager.getTagAddressBurn(addressCount);
|
|
6773
6933
|
|
|
6774
6934
|
// 6. Estimate fee
|
|
6775
|
-
|
|
6935
|
+
// Outputs: burn + XNA change + tag/untag operation (sent to changeAddress)
|
|
6936
|
+
const outputAddresses = [burnInfo.address, changeAddress, changeAddress];
|
|
6937
|
+
const estimatedFee = await this.estimateFee(2, outputAddresses);
|
|
6776
6938
|
|
|
6777
6939
|
// 7. Calculate total XNA needed
|
|
6778
6940
|
const totalXNANeeded = burnInfo.amount + estimatedFee;
|
|
@@ -6782,9 +6944,9 @@ var NeuraiAssetsBundle = (function (exports) {
|
|
|
6782
6944
|
const baseCurrencyUTXOs = utxoSelection.xnaUTXOs;
|
|
6783
6945
|
const totalXNAInput = utxoSelection.totalXNA;
|
|
6784
6946
|
|
|
6785
|
-
// 9. Recalculate fee with actual
|
|
6786
|
-
const
|
|
6787
|
-
const actualFee = await this.estimateFee(
|
|
6947
|
+
// 9. Recalculate fee with actual inputs (PQ-aware), including qualifier UTXOs
|
|
6948
|
+
const actualFeeInputs = [...baseCurrencyUTXOs, ...qualifierUTXOs];
|
|
6949
|
+
const actualFee = await this.estimateFee(actualFeeInputs, outputAddresses);
|
|
6788
6950
|
|
|
6789
6951
|
// 10. Verify we have enough XNA
|
|
6790
6952
|
const totalRequired = burnInfo.amount + actualFee;
|
|
@@ -7019,16 +7181,18 @@ var NeuraiAssetsBundle = (function (exports) {
|
|
|
7019
7181
|
const burnAmount = 0;
|
|
7020
7182
|
|
|
7021
7183
|
// 6. Estimate fee
|
|
7022
|
-
|
|
7184
|
+
// Outputs: XNA change + freeze/unfreeze operation (sent to changeAddress)
|
|
7185
|
+
const outputAddresses = [changeAddress, changeAddress];
|
|
7186
|
+
const estimatedFee = await this.estimateFee(2, outputAddresses);
|
|
7023
7187
|
|
|
7024
7188
|
// 7. Select XNA UTXOs (only for fee, no burn)
|
|
7025
7189
|
const utxoSelection = await this.selectUTXOs(estimatedFee, null, 0);
|
|
7026
7190
|
const baseCurrencyUTXOs = utxoSelection.xnaUTXOs;
|
|
7027
7191
|
const totalXNAInput = utxoSelection.totalXNA;
|
|
7028
7192
|
|
|
7029
|
-
// 8. Recalculate fee with actual
|
|
7030
|
-
const
|
|
7031
|
-
const actualFee = await this.estimateFee(
|
|
7193
|
+
// 8. Recalculate fee with actual inputs (PQ-aware), including owner token UTXO
|
|
7194
|
+
const actualFeeInputs = [...baseCurrencyUTXOs, ownerTokenUTXO];
|
|
7195
|
+
const actualFee = await this.estimateFee(actualFeeInputs, outputAddresses);
|
|
7032
7196
|
|
|
7033
7197
|
// 9. Verify we have enough XNA for fee
|
|
7034
7198
|
if (totalXNAInput < actualFee) {
|