nexa-wallet-sdk 0.5.0 → 0.5.2

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/index.cjs CHANGED
@@ -149,7 +149,7 @@ $parcel$export(module.exports, "SighashType", () => $l50U0$libnexats.SighashType
149
149
  $parcel$export(module.exports, "AccountKeysUtils", () => $4d68f29c39c1a3e4$export$94f569bf4eb0f6f6);
150
150
  // @ts-ignore
151
151
  var $2dd241e44b9dc3c2$exports = {};
152
- $2dd241e44b9dc3c2$exports = JSON.parse("{\"name\":\"nexa-wallet-sdk\",\"version\":\"0.5.0\",\"type\":\"module\",\"source\":\"src/index.ts\",\"types\":\"dist/index.d.ts\",\"main\":\"dist/index.cjs\",\"module\":\"dist/index.mjs\",\"browser\":\"dist/index.web.mjs\",\"exports\":{\"types\":\"./dist/index.d.ts\",\"node\":{\"import\":\"./dist/index.mjs\",\"require\":\"./dist/index.cjs\"},\"browser\":\"./dist/index.web.mjs\",\"default\":\"./dist/index.mjs\"},\"scripts\":{\"build\":\"parcel build\",\"lint\":\"eslint .\",\"fix-lint\":\"eslint --fix .\",\"dev\":\"parcel watch\",\"test\":\"vitest run\",\"clean\":\"rm -rf dist .parcel-cache\",\"docs\":\"typedoc\",\"docs:serve\":\"typedoc && npx serve docs -l 8080\",\"docs:mkdocs\":\"typedoc && mkdocs serve\",\"docs:build\":\"typedoc && mkdocs build\",\"docs:setup\":\"./scripts/setup-docs.sh\",\"wallet-cli\":\"node examples/wallet-cli.cjs\"},\"repository\":{\"type\":\"git\",\"url\":\"git+ssh://git@gitlab.com/nexa/wallet-sdk-ts.git\"},\"keywords\":[\"nexa\",\"wallet\",\"web3\",\"crypto\",\"dapp\",\"walletcomms\",\"walletsdk\"],\"contributors\":[{\"name\":\"Dolaned\"},{\"name\":\"Griffith\"},{\"name\":\"Vgrunner\"},{\"name\":\"myendy\"}],\"author\":\"Dolaned\",\"license\":\"MIT\",\"bugs\":{\"url\":\"https://gitlab.com/nexa/wallet-sdk-ts/issues\"},\"homepage\":\"https://gitlab.com/nexa/wallet-sdk-ts#readme\",\"description\":\"Wallet SDK for the Nexa blockchain\",\"devDependencies\":{\"@parcel/packager-ts\":\"^2.15.4\",\"@parcel/transformer-typescript-types\":\"^2.15.4\",\"@types/lodash-es\":\"^4.17.12\",\"@types/node\":\"^22.13.1\",\"eslint\":\"^9.20.1\",\"parcel\":\"^2.15.4\",\"typedoc\":\"^0.28.7\",\"typedoc-plugin-markdown\":\"^4.7.0\",\"typedoc-plugin-rename-defaults\":\"^0.7.3\",\"typescript\":\"^5.8.3\",\"typescript-eslint\":\"^8.24.1\",\"vitest\":\"^3.0.8\"},\"targets\":{\"main\":{\"context\":\"node\",\"outputFormat\":\"commonjs\",\"distDir\":\"dist\",\"isLibrary\":true,\"includeNodeModules\":[\"lodash-es\"]},\"module\":{\"context\":\"node\",\"outputFormat\":\"esmodule\",\"distDir\":\"dist\",\"isLibrary\":true},\"browser\":{\"context\":\"browser\",\"outputFormat\":\"esmodule\",\"distDir\":\"dist\",\"isLibrary\":true}},\"dependencies\":{\"@vgrunner/electrum-cash\":\"^2.0.12\",\"bip39\":\"^3.1.0\",\"js-big-decimal\":\"^2.2.0\",\"libnexa-ts\":\"^1.0.5\",\"lodash-es\":\"^4.17.21\",\"prompt-sync\":\"^4.2.0\",\"wallet-comms-sdk\":\"^0.6.1\"},\"files\":[\"dist\"],\"directories\":{\"test\":\"tests\"},\"@parcel/resolver-default\":{\"packageExports\":true}}");
152
+ $2dd241e44b9dc3c2$exports = JSON.parse("{\"name\":\"nexa-wallet-sdk\",\"version\":\"0.5.2\",\"type\":\"module\",\"source\":\"src/index.ts\",\"types\":\"dist/index.d.ts\",\"main\":\"dist/index.cjs\",\"module\":\"dist/index.mjs\",\"browser\":\"dist/index.web.mjs\",\"exports\":{\"types\":\"./dist/index.d.ts\",\"node\":{\"import\":\"./dist/index.mjs\",\"require\":\"./dist/index.cjs\"},\"browser\":\"./dist/index.web.mjs\",\"default\":\"./dist/index.mjs\"},\"scripts\":{\"build\":\"parcel build\",\"lint\":\"eslint .\",\"fix-lint\":\"eslint --fix .\",\"dev\":\"parcel watch\",\"test\":\"vitest run\",\"clean\":\"rm -rf dist .parcel-cache\",\"docs\":\"typedoc\",\"docs:serve\":\"typedoc && npx serve docs -l 8080\",\"docs:mkdocs\":\"typedoc && mkdocs serve\",\"docs:build\":\"typedoc && mkdocs build\",\"docs:setup\":\"./scripts/setup-docs.sh\",\"wallet-cli\":\"node examples/wallet-cli.cjs\"},\"repository\":{\"type\":\"git\",\"url\":\"git+ssh://git@gitlab.com/nexa/wallet-sdk-ts.git\"},\"keywords\":[\"nexa\",\"wallet\",\"web3\",\"crypto\",\"dapp\",\"walletcomms\",\"walletsdk\"],\"contributors\":[{\"name\":\"Dolaned\"},{\"name\":\"Griffith\"},{\"name\":\"Vgrunner\"},{\"name\":\"myendy\"}],\"author\":\"Dolaned\",\"license\":\"MIT\",\"bugs\":{\"url\":\"https://gitlab.com/nexa/wallet-sdk-ts/issues\"},\"homepage\":\"https://gitlab.com/nexa/wallet-sdk-ts#readme\",\"description\":\"Wallet SDK for the Nexa blockchain\",\"devDependencies\":{\"@parcel/packager-ts\":\"^2.15.4\",\"@parcel/transformer-typescript-types\":\"^2.15.4\",\"@types/lodash-es\":\"^4.17.12\",\"@types/node\":\"^22.13.1\",\"eslint\":\"^9.20.1\",\"parcel\":\"^2.15.4\",\"typedoc\":\"^0.28.7\",\"typedoc-plugin-markdown\":\"^4.7.0\",\"typedoc-plugin-rename-defaults\":\"^0.7.3\",\"typescript\":\"^5.8.3\",\"typescript-eslint\":\"^8.24.1\",\"vitest\":\"^3.0.8\"},\"targets\":{\"main\":{\"context\":\"node\",\"outputFormat\":\"commonjs\",\"distDir\":\"dist\",\"isLibrary\":true,\"includeNodeModules\":[\"lodash-es\"]},\"module\":{\"context\":\"node\",\"outputFormat\":\"esmodule\",\"distDir\":\"dist\",\"isLibrary\":true},\"browser\":{\"context\":\"browser\",\"outputFormat\":\"esmodule\",\"distDir\":\"dist\",\"isLibrary\":true}},\"dependencies\":{\"@vgrunner/electrum-cash\":\"^2.0.12\",\"bip39\":\"^3.1.0\",\"js-big-decimal\":\"^2.2.0\",\"libnexa-ts\":\"^1.0.5\",\"lodash-es\":\"^4.17.21\",\"prompt-sync\":\"^4.2.0\",\"wallet-comms-sdk\":\"^0.6.1\"},\"files\":[\"dist\"],\"directories\":{\"test\":\"tests\"},\"@parcel/resolver-default\":{\"packageExports\":true}}");
153
153
 
154
154
 
155
155
 
@@ -375,6 +375,7 @@ class $f8a48da5c0b6346a$export$c54c8796e94a37a0 {
375
375
  }
376
376
  constructor(_bip44Account){
377
377
  this._tokenBalances = {};
378
+ this._tokenAuthorities = {};
378
379
  this._transactions = new Map();
379
380
  this._bip44Account = _bip44Account;
380
381
  this._balance = {
@@ -382,6 +383,7 @@ class $f8a48da5c0b6346a$export$c54c8796e94a37a0 {
382
383
  unconfirmed: 0
383
384
  };
384
385
  this._tokenBalances = {};
386
+ this._tokenAuthorities = {};
385
387
  }
386
388
  get balance() {
387
389
  return this._balance;
@@ -395,6 +397,12 @@ class $f8a48da5c0b6346a$export$c54c8796e94a37a0 {
395
397
  set tokenBalances(value) {
396
398
  this._tokenBalances = value;
397
399
  }
400
+ get tokenAuthorities() {
401
+ return this._tokenAuthorities;
402
+ }
403
+ set tokenAuthorities(value) {
404
+ this._tokenAuthorities = value;
405
+ }
398
406
  async fetchAndClassifyTransactions(transactionAddress, fromHeight) {
399
407
  const transactions = await (0, $0d59d2bcffd646c5$export$a2ed4b531376a5a4)([
400
408
  transactionAddress
@@ -444,7 +452,7 @@ class $cf960f437fe63027$export$2e2bcd8739ae039 extends (0, $f8a48da5c0b6346a$exp
444
452
  };
445
453
  }
446
454
  async loadBalances() {
447
- let balances = await (0, $0d59d2bcffd646c5$export$9e38d26dbd7c33f4)([
455
+ const { balances: balances, authorities: authorities } = await (0, $0d59d2bcffd646c5$export$e4fb0bc90aacba9e)([
448
456
  this._accountKey
449
457
  ]);
450
458
  let tokenBalances = [
@@ -452,6 +460,7 @@ class $cf960f437fe63027$export$2e2bcd8739ae039 extends (0, $f8a48da5c0b6346a$exp
452
460
  ].map((k)=>k.tokensBalance);
453
461
  super.balance = (0, $0d59d2bcffd646c5$export$a26005fb5b8d1e4a)(balances);
454
462
  super.tokenBalances = (0, $0d59d2bcffd646c5$export$dec515296f176dbe)(tokenBalances);
463
+ super.tokenAuthorities = authorities;
455
464
  }
456
465
  getKeyFromAddress(address) {
457
466
  if (address !== this._accountKey.address) throw new Error(`Address ${address} does not belong to this account`);
@@ -505,10 +514,11 @@ class $1c49a4fffc97409b$export$2e2bcd8739ae039 extends (0, $f8a48da5c0b6346a$exp
505
514
  return this._accountKeys;
506
515
  }
507
516
  async loadBalances() {
508
- let balances = await (0, $0d59d2bcffd646c5$export$9e38d26dbd7c33f4)(this._accountKeys.receiveKeys.concat(this._accountKeys.changeKeys));
517
+ const { balances: balances, authorities: authorities } = await (0, $0d59d2bcffd646c5$export$e4fb0bc90aacba9e)(this._accountKeys.receiveKeys.concat(this._accountKeys.changeKeys));
509
518
  let tokenBalances = this._accountKeys.receiveKeys.concat(this._accountKeys.changeKeys).map((k)=>k.tokensBalance);
510
519
  super.balance = (0, $0d59d2bcffd646c5$export$a26005fb5b8d1e4a)(balances);
511
520
  super.tokenBalances = (0, $0d59d2bcffd646c5$export$dec515296f176dbe)(tokenBalances);
521
+ super.tokenAuthorities = authorities;
512
522
  }
513
523
  getKeyFromAddress(address) {
514
524
  const allKeys = this._accountKeys.receiveKeys.concat(this._accountKeys.changeKeys);
@@ -595,7 +605,7 @@ class $0b557605c0e99621$export$2e2bcd8739ae039 extends (0, $f8a48da5c0b6346a$exp
595
605
  };
596
606
  }
597
607
  async loadBalances() {
598
- let balances = await (0, $0d59d2bcffd646c5$export$9e38d26dbd7c33f4)([
608
+ const { balances: balances, authorities: authorities } = await (0, $0d59d2bcffd646c5$export$e4fb0bc90aacba9e)([
599
609
  this._accountKey
600
610
  ]);
601
611
  let tokenBalances = [
@@ -603,6 +613,7 @@ class $0b557605c0e99621$export$2e2bcd8739ae039 extends (0, $f8a48da5c0b6346a$exp
603
613
  ].map((k)=>k.tokensBalance);
604
614
  super.balance = (0, $0d59d2bcffd646c5$export$a26005fb5b8d1e4a)(balances);
605
615
  super.tokenBalances = (0, $0d59d2bcffd646c5$export$dec515296f176dbe)(tokenBalances);
616
+ super.tokenAuthorities = authorities;
606
617
  }
607
618
  getKeyFromAddress(address) {
608
619
  if (address !== this._accountKey.address) throw new Error(`Address ${address} does not belong to this account`);
@@ -658,6 +669,70 @@ function $bc5ca2c06b1affa3$export$f12d707d2b261fb6(txIdem, outputIndex) {
658
669
  }
659
670
 
660
671
 
672
+
673
+ function $22e282633cad8f97$export$7f7cffd29bf2d96d(authFlags, permission) {
674
+ if (authFlags > 0) return false;
675
+ let flags = BigInt.asUintN(64, BigInt(authFlags));
676
+ switch(permission){
677
+ case 'authorise':
678
+ return (0, $l50U0$libnexats.GroupToken).allowsRenew(flags);
679
+ case 'mint':
680
+ return (0, $l50U0$libnexats.GroupToken).allowsMint(flags);
681
+ case 'melt':
682
+ return (0, $l50U0$libnexats.GroupToken).allowsMelt(flags);
683
+ case 'rescript':
684
+ return (0, $l50U0$libnexats.GroupToken).allowsRescript(flags);
685
+ case 'subgroup':
686
+ return (0, $l50U0$libnexats.GroupToken).allowsSubgroup(flags);
687
+ default:
688
+ return false;
689
+ }
690
+ }
691
+ function $22e282633cad8f97$export$636fb0b03b94ac81(authFlags, withSubgroup = true) {
692
+ if (authFlags > 0) return 0n;
693
+ let flags = BigInt.asUintN(64, BigInt(authFlags));
694
+ let newFlags = (0, $l50U0$libnexats.GroupToken).authFlags.AUTHORITY;
695
+ if ((0, $l50U0$libnexats.GroupToken).allowsRenew(flags)) newFlags |= (0, $l50U0$libnexats.GroupToken).authFlags.BATON;
696
+ if ((0, $l50U0$libnexats.GroupToken).allowsMint(flags)) newFlags |= (0, $l50U0$libnexats.GroupToken).authFlags.MINT;
697
+ if ((0, $l50U0$libnexats.GroupToken).allowsMelt(flags)) newFlags |= (0, $l50U0$libnexats.GroupToken).authFlags.MELT;
698
+ if ((0, $l50U0$libnexats.GroupToken).allowsRescript(flags)) newFlags |= (0, $l50U0$libnexats.GroupToken).authFlags.RESCRIPT;
699
+ if ((0, $l50U0$libnexats.GroupToken).allowsSubgroup(flags) && withSubgroup) newFlags |= (0, $l50U0$libnexats.GroupToken).authFlags.SUBGROUP;
700
+ return newFlags;
701
+ }
702
+ function $22e282633cad8f97$export$e240c810a53c3a0c(perms) {
703
+ let newFlags = (0, $l50U0$libnexats.GroupToken).authFlags.AUTHORITY;
704
+ for (let perm of perms)switch(perm){
705
+ case 'authorise':
706
+ newFlags |= (0, $l50U0$libnexats.GroupToken).authFlags.BATON;
707
+ break;
708
+ case 'mint':
709
+ newFlags |= (0, $l50U0$libnexats.GroupToken).authFlags.MINT;
710
+ break;
711
+ case 'melt':
712
+ newFlags |= (0, $l50U0$libnexats.GroupToken).authFlags.MELT;
713
+ break;
714
+ case 'rescript':
715
+ newFlags |= (0, $l50U0$libnexats.GroupToken).authFlags.RESCRIPT;
716
+ break;
717
+ case 'subgroup':
718
+ newFlags |= (0, $l50U0$libnexats.GroupToken).authFlags.SUBGROUP;
719
+ break;
720
+ }
721
+ return newFlags;
722
+ }
723
+ function $22e282633cad8f97$export$c949c84578b9e236(authFlags) {
724
+ if (authFlags > 0) return [];
725
+ const permissions = [];
726
+ const flags = BigInt.asUintN(64, BigInt(authFlags));
727
+ if ((0, $l50U0$libnexats.GroupToken).allowsRenew(flags)) permissions.push('authorise');
728
+ if ((0, $l50U0$libnexats.GroupToken).allowsMint(flags)) permissions.push('mint');
729
+ if ((0, $l50U0$libnexats.GroupToken).allowsMelt(flags)) permissions.push('melt');
730
+ if ((0, $l50U0$libnexats.GroupToken).allowsRescript(flags)) permissions.push('rescript');
731
+ if ((0, $l50U0$libnexats.GroupToken).allowsSubgroup(flags)) permissions.push('subgroup');
732
+ return permissions;
733
+ }
734
+
735
+
661
736
  var $0d59d2bcffd646c5$export$dcc1fb6ad5308e56 = /*#__PURE__*/ function(TxTokenType) {
662
737
  TxTokenType[TxTokenType["NO_GROUP"] = 0] = "NO_GROUP";
663
738
  TxTokenType[TxTokenType["CREATE"] = 1] = "CREATE";
@@ -860,35 +935,81 @@ async function $0d59d2bcffd646c5$var$isAddressUsed(address) {
860
935
  throw e;
861
936
  }
862
937
  }
863
- async function $0d59d2bcffd646c5$var$getKeyTokenBalance(key) {
864
- let tokensBalance = await (0, $b5bfd17fdf06d231$export$eaa49f0478d81b9d).getTokensBalance(key.address);
865
- let balance = {};
866
- for(const cToken in tokensBalance.confirmed)if (tokensBalance.confirmed[cToken] != 0) balance[cToken] = {
867
- confirmed: BigInt(tokensBalance.confirmed[cToken]).toString(),
868
- unconfirmed: "0"
869
- };
870
- for(const uToken in tokensBalance.unconfirmed)if (tokensBalance.unconfirmed[uToken] != 0) {
871
- if (balance[uToken]) balance[uToken].unconfirmed = BigInt(tokensBalance.unconfirmed[uToken]).toString();
872
- else balance[uToken] = {
873
- confirmed: "0",
874
- unconfirmed: BigInt(tokensBalance.unconfirmed[uToken]).toString()
938
+ async function $0d59d2bcffd646c5$var$getKeyTokenBalanceAndAuthorities(address) {
939
+ const tokensBalance = await (0, $b5bfd17fdf06d231$export$eaa49f0478d81b9d).getTokensBalance(address);
940
+ const balance = {};
941
+ const authorities = {};
942
+ // Get all unique token IDs from both confirmed and unconfirmed
943
+ const allTokenIds = new Set([
944
+ ...Object.keys(tokensBalance.confirmed),
945
+ ...Object.keys(tokensBalance.unconfirmed)
946
+ ]);
947
+ // Process each token to get both balance and check for authorities
948
+ for (const tokenId of allTokenIds){
949
+ const confirmedAmount = tokensBalance.confirmed[tokenId] || 0;
950
+ const unconfirmedAmount = tokensBalance.unconfirmed[tokenId] || 0;
951
+ // Add to balance if non-zero
952
+ if (confirmedAmount !== 0 || unconfirmedAmount !== 0) balance[tokenId] = {
953
+ confirmed: BigInt(confirmedAmount).toString(),
954
+ unconfirmed: BigInt(unconfirmedAmount).toString()
875
955
  };
956
+ // Check for authorities by getting token UTXOs
957
+ try {
958
+ const tokenUtxos = await (0, $b5bfd17fdf06d231$export$eaa49f0478d81b9d).getTokenUtxos(address, tokenId);
959
+ if (tokenUtxos && tokenUtxos.length > 0) {
960
+ // Look for authorities (negative amounts)
961
+ const authUtxos = tokenUtxos.filter((utxo)=>{
962
+ const amount = parseInt(String(utxo.token_amount || '0'));
963
+ return amount < 0;
964
+ });
965
+ // Add permissions and address to each authority UTXO and organize by token ID
966
+ if (authUtxos.length > 0) {
967
+ const authoritiesWithPermissions = authUtxos.map((utxo)=>({
968
+ ...utxo,
969
+ permissions: (0, $22e282633cad8f97$export$c949c84578b9e236)(parseInt(String(utxo.token_amount || '0'))),
970
+ address: address
971
+ }));
972
+ authorities[tokenId] = authoritiesWithPermissions;
973
+ }
974
+ }
975
+ } catch (error) {
976
+ console.warn(`Error checking authorities for token ${tokenId} on address ${address}:`, error);
977
+ }
876
978
  }
877
- return balance;
979
+ return {
980
+ balance: balance,
981
+ authorities: authorities
982
+ };
878
983
  }
879
984
  async function $0d59d2bcffd646c5$var$getAndUpdateAddressKeyBalance(key) {
880
985
  let balance = await (0, $b5bfd17fdf06d231$export$eaa49f0478d81b9d).getBalance(key.address);
881
986
  key.balance = (BigInt(balance.confirmed) + BigInt(balance.unconfirmed)).toString();
882
- key.tokensBalance = await $0d59d2bcffd646c5$var$getKeyTokenBalance(key);
883
- return balance;
987
+ const { balance: tokenBalance, authorities: authorities } = await $0d59d2bcffd646c5$var$getKeyTokenBalanceAndAuthorities(key.address);
988
+ key.tokensBalance = tokenBalance;
989
+ return {
990
+ balance: balance,
991
+ authorities: authorities
992
+ };
884
993
  }
885
- async function $0d59d2bcffd646c5$export$9e38d26dbd7c33f4(keys) {
994
+ async function $0d59d2bcffd646c5$export$e4fb0bc90aacba9e(keys) {
886
995
  let promises = [];
887
996
  keys.forEach((key)=>{
888
- let b = $0d59d2bcffd646c5$var$getAndUpdateAddressKeyBalance(key);
889
- promises.push(b);
997
+ promises.push($0d59d2bcffd646c5$var$getAndUpdateAddressKeyBalance(key));
998
+ });
999
+ const results = await Promise.all(promises);
1000
+ const balances = results.map((r)=>r.balance);
1001
+ // Combine authorities from all addresses, merging by token ID
1002
+ const combinedAuthorities = {};
1003
+ results.forEach((result)=>{
1004
+ Object.keys(result.authorities).forEach((tokenId)=>{
1005
+ if (combinedAuthorities[tokenId]) combinedAuthorities[tokenId] = combinedAuthorities[tokenId].concat(result.authorities[tokenId]);
1006
+ else combinedAuthorities[tokenId] = result.authorities[tokenId];
1007
+ });
890
1008
  });
891
- return await Promise.all(promises);
1009
+ return {
1010
+ balances: balances,
1011
+ authorities: combinedAuthorities
1012
+ };
892
1013
  }
893
1014
  function $0d59d2bcffd646c5$export$a26005fb5b8d1e4a(balances) {
894
1015
  let confirmed = new (0, ($parcel$interopDefault($l50U0$jsbigdecimal)))(0), unconfirmed = new (0, ($parcel$interopDefault($l50U0$jsbigdecimal)))(0);
@@ -1296,7 +1417,6 @@ var $90290c84737dbb50$export$2e2bcd8739ae039 = $90290c84737dbb50$var$isString;
1296
1417
 
1297
1418
 
1298
1419
 
1299
-
1300
1420
  class $4d68f29c39c1a3e4$export$94f569bf4eb0f6f6 {
1301
1421
  static getAllKeys(keys) {
1302
1422
  return keys.receiveKeys.concat(keys.changeKeys);
@@ -1310,60 +1430,8 @@ class $4d68f29c39c1a3e4$export$94f569bf4eb0f6f6 {
1310
1430
 
1311
1431
 
1312
1432
 
1313
- function $22e282633cad8f97$export$7f7cffd29bf2d96d(authFlags, permission) {
1314
- if (authFlags > 0) return false;
1315
- let flags = BigInt.asUintN(64, BigInt(authFlags));
1316
- switch(permission){
1317
- case 'authorise':
1318
- return (0, $l50U0$libnexats.GroupToken).allowsRenew(flags);
1319
- case 'mint':
1320
- return (0, $l50U0$libnexats.GroupToken).allowsMint(flags);
1321
- case 'melt':
1322
- return (0, $l50U0$libnexats.GroupToken).allowsMelt(flags);
1323
- case 'rescript':
1324
- return (0, $l50U0$libnexats.GroupToken).allowsRescript(flags);
1325
- case 'subgroup':
1326
- return (0, $l50U0$libnexats.GroupToken).allowsSubgroup(flags);
1327
- default:
1328
- return false;
1329
- }
1330
- }
1331
- function $22e282633cad8f97$export$636fb0b03b94ac81(authFlags, withSubgroup = true) {
1332
- if (authFlags > 0) return 0n;
1333
- let flags = BigInt.asUintN(64, BigInt(authFlags));
1334
- let newFlags = (0, $l50U0$libnexats.GroupToken).authFlags.AUTHORITY;
1335
- if ((0, $l50U0$libnexats.GroupToken).allowsRenew(flags)) newFlags |= (0, $l50U0$libnexats.GroupToken).authFlags.BATON;
1336
- if ((0, $l50U0$libnexats.GroupToken).allowsMint(flags)) newFlags |= (0, $l50U0$libnexats.GroupToken).authFlags.MINT;
1337
- if ((0, $l50U0$libnexats.GroupToken).allowsMelt(flags)) newFlags |= (0, $l50U0$libnexats.GroupToken).authFlags.MELT;
1338
- if ((0, $l50U0$libnexats.GroupToken).allowsRescript(flags)) newFlags |= (0, $l50U0$libnexats.GroupToken).authFlags.RESCRIPT;
1339
- if ((0, $l50U0$libnexats.GroupToken).allowsSubgroup(flags) && withSubgroup) newFlags |= (0, $l50U0$libnexats.GroupToken).authFlags.SUBGROUP;
1340
- return newFlags;
1341
- }
1342
- function $22e282633cad8f97$export$e240c810a53c3a0c(perms) {
1343
- let newFlags = (0, $l50U0$libnexats.GroupToken).authFlags.AUTHORITY;
1344
- for (let perm of perms)switch(perm){
1345
- case 'authorise':
1346
- newFlags |= (0, $l50U0$libnexats.GroupToken).authFlags.BATON;
1347
- break;
1348
- case 'mint':
1349
- newFlags |= (0, $l50U0$libnexats.GroupToken).authFlags.MINT;
1350
- break;
1351
- case 'melt':
1352
- newFlags |= (0, $l50U0$libnexats.GroupToken).authFlags.MELT;
1353
- break;
1354
- case 'rescript':
1355
- newFlags |= (0, $l50U0$libnexats.GroupToken).authFlags.RESCRIPT;
1356
- break;
1357
- case 'subgroup':
1358
- newFlags |= (0, $l50U0$libnexats.GroupToken).authFlags.SUBGROUP;
1359
- break;
1360
- }
1361
- return newFlags;
1362
- }
1363
-
1364
-
1365
1433
  /** Maximum number of inputs/outputs allowed in a single transaction */ const $b4a043612f1c4089$var$MAX_INPUTS_OUTPUTS = 250;
1366
- async function $b4a043612f1c4089$export$afd979971a55acfc(txBuilder, keys, totalTxValue, options) {
1434
+ async function $b4a043612f1c4089$export$afd979971a55acfc(txBuilder, keys, totalTxValue, options, spentOutpoints) {
1367
1435
  let rKeys = keys.receiveKeys.filter((k)=>BigInt(k.balance) > 0n);
1368
1436
  let cKeys = keys.changeKeys.filter((k)=>BigInt(k.balance) > 0n);
1369
1437
  let allKeys = rKeys.concat(cKeys);
@@ -1373,6 +1441,7 @@ async function $b4a043612f1c4089$export$afd979971a55acfc(txBuilder, keys, totalT
1373
1441
  for (let key of allKeys){
1374
1442
  let utxos = await (0, $b5bfd17fdf06d231$export$eaa49f0478d81b9d).getNexaUtxos(key.address);
1375
1443
  for (let utxo of utxos){
1444
+ if (spentOutpoints && spentOutpoints.has(utxo.outpoint_hash)) continue;
1376
1445
  let input = {
1377
1446
  outpoint: utxo.outpoint_hash,
1378
1447
  address: key.address,
@@ -1380,6 +1449,7 @@ async function $b4a043612f1c4089$export$afd979971a55acfc(txBuilder, keys, totalT
1380
1449
  templateData: options.templateData
1381
1450
  };
1382
1451
  txBuilder.from(input);
1452
+ if (spentOutpoints) spentOutpoints.add(utxo.outpoint_hash);
1383
1453
  if (!usedKeys.has(key.address)) usedKeys.set(key.address, key.key.privateKey);
1384
1454
  if (options.isConsolidate) {
1385
1455
  txBuilder.change(options.toChange ?? keys.receiveKeys[keys.receiveKeys.length - 1].address);
@@ -1423,11 +1493,8 @@ async function $b4a043612f1c4089$export$afd979971a55acfc(txBuilder, keys, totalT
1423
1493
  };
1424
1494
  throw new Error(JSON.stringify(err));
1425
1495
  }
1426
- async function $b4a043612f1c4089$export$931e37acdaa22dcf(txBuilder, keys, token, outTokenAmount) {
1427
- let tokenHex = (0, $bc5ca2c06b1affa3$export$254a5c7330bbfd41)(token);
1428
- let rKeys = keys.receiveKeys.filter((k)=>Object.keys(k.tokensBalance).includes(tokenHex));
1429
- let cKeys = keys.changeKeys.filter((k)=>Object.keys(k.tokensBalance).includes(tokenHex));
1430
- let allKeys = rKeys.concat(cKeys);
1496
+ async function $b4a043612f1c4089$export$931e37acdaa22dcf(txBuilder, keys, token, outTokenAmount, spentOutpoints) {
1497
+ let allKeys = keys.receiveKeys.concat(keys.changeKeys);
1431
1498
  if ((0, $bc5ca2c06b1affa3$export$c8733ae29fb53302)(allKeys)) throw new Error("Not enough token balance.");
1432
1499
  let usedKeys = new Map();
1433
1500
  let inTokenAmount = 0n;
@@ -1435,6 +1502,7 @@ async function $b4a043612f1c4089$export$931e37acdaa22dcf(txBuilder, keys, token,
1435
1502
  let utxos = await (0, $b5bfd17fdf06d231$export$eaa49f0478d81b9d).getTokenUtxos(key.address, token);
1436
1503
  for (let utxo of utxos){
1437
1504
  if (utxo.token_amount < 0) continue;
1505
+ if (spentOutpoints && spentOutpoints.has(utxo.outpoint_hash)) continue;
1438
1506
  txBuilder.from({
1439
1507
  outpoint: utxo.outpoint_hash,
1440
1508
  address: key.address,
@@ -1442,13 +1510,13 @@ async function $b4a043612f1c4089$export$931e37acdaa22dcf(txBuilder, keys, token,
1442
1510
  groupId: utxo.group,
1443
1511
  groupAmount: BigInt(utxo.token_amount)
1444
1512
  });
1513
+ if (spentOutpoints) spentOutpoints.add(utxo.outpoint_hash);
1445
1514
  inTokenAmount = inTokenAmount + BigInt(utxo.token_amount);
1446
1515
  if (!usedKeys.has(key.address)) usedKeys.set(key.address, key.key.privateKey);
1447
1516
  if (inTokenAmount > (0, $bc5ca2c06b1affa3$export$8ba128bc85947a2a)) throw new Error("Token inputs exceeded max amount. Consider sending in small chunks");
1448
1517
  if (txBuilder.transaction.inputs.length > $b4a043612f1c4089$var$MAX_INPUTS_OUTPUTS) throw new Error("Too many inputs. Consider consolidating transactions or reduce the send amount.");
1449
1518
  if (inTokenAmount == outTokenAmount) return Array.from(usedKeys.values());
1450
1519
  if (inTokenAmount > outTokenAmount) {
1451
- // change
1452
1520
  const tokenChangeAddress = keys.changeKeys.length > 0 ? keys.changeKeys[keys.changeKeys.length - 1].address : keys.receiveKeys[keys.receiveKeys.length - 1].address;
1453
1521
  txBuilder.to(tokenChangeAddress, (0, $l50U0$libnexats.Transaction).DUST_AMOUNT, token, inTokenAmount - outTokenAmount);
1454
1522
  return Array.from(usedKeys.values());
@@ -1457,7 +1525,7 @@ async function $b4a043612f1c4089$export$931e37acdaa22dcf(txBuilder, keys, token,
1457
1525
  }
1458
1526
  throw new Error("Not enough token balance");
1459
1527
  }
1460
- async function $b4a043612f1c4089$export$d7f2b844e1d59768(txBuilder, keys, opReturnData, network) {
1528
+ async function $b4a043612f1c4089$export$d7f2b844e1d59768(txBuilder, keys, opReturnData, network, spentOutpoints) {
1461
1529
  // TODO validate opreturn data
1462
1530
  const allKeys = (0, $4d68f29c39c1a3e4$export$94f569bf4eb0f6f6).getAllKeys(keys);
1463
1531
  let outpoint = '';
@@ -1466,11 +1534,13 @@ async function $b4a043612f1c4089$export$d7f2b844e1d59768(txBuilder, keys, opRetu
1466
1534
  for (let key of allKeys){
1467
1535
  let utxos = await (0, $b5bfd17fdf06d231$export$eaa49f0478d81b9d).getNexaUtxos(key.address);
1468
1536
  for (let utxo of utxos){
1537
+ if (spentOutpoints && spentOutpoints.has(utxo.outpoint_hash)) continue;
1469
1538
  txBuilder.from({
1470
1539
  outpoint: utxo.outpoint_hash,
1471
1540
  address: key.address,
1472
1541
  satoshis: utxo.value
1473
1542
  });
1543
+ if (spentOutpoints) spentOutpoints.add(utxo.outpoint_hash);
1474
1544
  if ((0, $bc5ca2c06b1affa3$export$c8733ae29fb53302)(outpoint)) {
1475
1545
  outpoint = utxo.outpoint_hash;
1476
1546
  let id = (0, $l50U0$libnexats.GroupToken).findGroupId(outpoint, Buffer.from(opReturnData, 'hex'), (0, $l50U0$libnexats.GroupToken).authFlags.ACTIVE_FLAG_BITS);
@@ -1499,17 +1569,19 @@ async function $b4a043612f1c4089$export$48a48877d6df17e9(txBuilder, keys, outpoi
1499
1569
  addrKey.key.privateKey
1500
1570
  ];
1501
1571
  }
1502
- async function $b4a043612f1c4089$export$1dfa5d829fc95097(txBuilder, keys, token, perm, subgroup = '', subgroupAddr = '', quantity) {
1572
+ async function $b4a043612f1c4089$export$1dfa5d829fc95097(txBuilder, keys, token, perm, subgroup = '', subgroupAddr = '', quantity, spentOutpoints) {
1503
1573
  let allKeys = (0, $4d68f29c39c1a3e4$export$94f569bf4eb0f6f6).getAllKeys(keys);
1504
1574
  for (let key of allKeys){
1505
1575
  let utxos = await (0, $b5bfd17fdf06d231$export$eaa49f0478d81b9d).getTokenUtxos(key.address, token);
1506
1576
  for (let utxo of utxos){
1507
1577
  if (!(0, $22e282633cad8f97$export$7f7cffd29bf2d96d)(utxo.token_amount, perm)) continue;
1578
+ if (spentOutpoints && spentOutpoints.has(utxo.outpoint_hash)) continue;
1508
1579
  txBuilder.from({
1509
1580
  outpoint: utxo.outpoint_hash,
1510
1581
  address: key.address,
1511
1582
  satoshis: utxo.value
1512
1583
  });
1584
+ if (spentOutpoints) spentOutpoints.add(utxo.outpoint_hash);
1513
1585
  if (perm === 'subgroup') {
1514
1586
  const subgroupQuantity = quantity ?? (0, $22e282633cad8f97$export$636fb0b03b94ac81)(utxo.token_amount, false);
1515
1587
  txBuilder.to(subgroupAddr, (0, $l50U0$libnexats.Transaction).DUST_AMOUNT, subgroup, subgroupQuantity);
@@ -1526,7 +1598,109 @@ async function $b4a043612f1c4089$export$1dfa5d829fc95097(txBuilder, keys, token,
1526
1598
  }
1527
1599
  throw new Error("The requested authority not found");
1528
1600
  }
1529
- async function $b4a043612f1c4089$export$28a843ca046a6b3f(txBuilder, keys, token, perms, toAddr) {
1601
+ async function $b4a043612f1c4089$export$fc6e64edb1452fc7(txBuilder, keys, token, amount, parentToken, spentOutpoints) {
1602
+ const privateKeys = [];
1603
+ const allKeys = (0, $4d68f29c39c1a3e4$export$94f569bf4eb0f6f6).getAllKeys(keys);
1604
+ // Determine which token to look for authority
1605
+ const authTokenId = parentToken || token;
1606
+ const isSubgroupMint = !!parentToken;
1607
+ // Find and add mint authority
1608
+ let mintAuthorityFound = false;
1609
+ for (let key of allKeys){
1610
+ if (mintAuthorityFound) break;
1611
+ let authUtxos = await (0, $b5bfd17fdf06d231$export$eaa49f0478d81b9d).getTokenUtxos(key.address, authTokenId);
1612
+ for (let utxo of authUtxos){
1613
+ if (!(0, $22e282633cad8f97$export$7f7cffd29bf2d96d)(utxo.token_amount, 'mint')) continue;
1614
+ // Skip if already spent
1615
+ if (spentOutpoints && spentOutpoints.has(utxo.outpoint_hash)) continue;
1616
+ // Add mint authority as input
1617
+ txBuilder.from({
1618
+ outpoint: utxo.outpoint_hash,
1619
+ address: key.address,
1620
+ satoshis: utxo.value
1621
+ });
1622
+ if (spentOutpoints) spentOutpoints.add(utxo.outpoint_hash);
1623
+ // Create the minted tokens output
1624
+ const mintAddress = keys.receiveKeys[keys.receiveKeys.length - 1].address;
1625
+ txBuilder.to(mintAddress, (0, $l50U0$libnexats.Transaction).DUST_AMOUNT, token, amount);
1626
+ // Preserve the mint authority for future use
1627
+ if ((0, $l50U0$libnexats.GroupToken).allowsRenew(BigInt.asUintN(64, BigInt(utxo.token_amount)))) {
1628
+ const authChangeAddress = keys.changeKeys.length > 0 ? keys.changeKeys[keys.changeKeys.length - 1].address : keys.receiveKeys[keys.receiveKeys.length - 1].address;
1629
+ txBuilder.to(authChangeAddress, (0, $l50U0$libnexats.Transaction).DUST_AMOUNT, authTokenId, (0, $22e282633cad8f97$export$636fb0b03b94ac81)(utxo.token_amount));
1630
+ }
1631
+ privateKeys.push(key.key.privateKey);
1632
+ mintAuthorityFound = true;
1633
+ break;
1634
+ }
1635
+ }
1636
+ if (!mintAuthorityFound) throw new Error(`Mint authority not found for token ${authTokenId}`);
1637
+ return privateKeys;
1638
+ }
1639
+ async function $b4a043612f1c4089$export$661377a8795b235c(txBuilder, keys, token, amount, parentToken, spentOutpoints) {
1640
+ const privateKeys = [];
1641
+ const allKeys = (0, $4d68f29c39c1a3e4$export$94f569bf4eb0f6f6).getAllKeys(keys);
1642
+ const authTokenId = parentToken || token;
1643
+ // First, find and add melt authority
1644
+ let meltAuthorityFound = false;
1645
+ for (let key of allKeys){
1646
+ if (meltAuthorityFound) break;
1647
+ let authUtxos = await (0, $b5bfd17fdf06d231$export$eaa49f0478d81b9d).getTokenUtxos(key.address, authTokenId);
1648
+ for (let utxo of authUtxos){
1649
+ if (!(0, $22e282633cad8f97$export$7f7cffd29bf2d96d)(utxo.token_amount, 'melt')) continue;
1650
+ // Skip if already spent
1651
+ if (spentOutpoints && spentOutpoints.has(utxo.outpoint_hash)) continue;
1652
+ // Add melt authority as input
1653
+ txBuilder.from({
1654
+ outpoint: utxo.outpoint_hash,
1655
+ address: key.address,
1656
+ satoshis: utxo.value
1657
+ });
1658
+ if (spentOutpoints) spentOutpoints.add(utxo.outpoint_hash);
1659
+ // Preserve the melt authority for future use
1660
+ if ((0, $l50U0$libnexats.GroupToken).allowsRenew(BigInt.asUintN(64, BigInt(utxo.token_amount)))) {
1661
+ const authChangeAddress = keys.changeKeys.length > 0 ? keys.changeKeys[keys.changeKeys.length - 1].address : keys.receiveKeys[keys.receiveKeys.length - 1].address;
1662
+ txBuilder.to(authChangeAddress, (0, $l50U0$libnexats.Transaction).DUST_AMOUNT, token, (0, $22e282633cad8f97$export$636fb0b03b94ac81)(utxo.token_amount));
1663
+ }
1664
+ privateKeys.push(key.key.privateKey);
1665
+ meltAuthorityFound = true;
1666
+ break;
1667
+ }
1668
+ }
1669
+ if (!meltAuthorityFound) throw new Error("Melt authority not found for token");
1670
+ // Now find and add token UTXOs to melt
1671
+ let inTokenAmount = 0n;
1672
+ for (let key of allKeys){
1673
+ let utxos = await (0, $b5bfd17fdf06d231$export$eaa49f0478d81b9d).getTokenUtxos(key.address, token);
1674
+ for (let utxo of utxos){
1675
+ // Skip authorities (negative amounts)
1676
+ if (utxo.token_amount < 0) continue;
1677
+ // Skip if already spent
1678
+ if (spentOutpoints && spentOutpoints.has(utxo.outpoint_hash)) continue;
1679
+ // Add token UTXO as input
1680
+ txBuilder.from({
1681
+ outpoint: utxo.outpoint_hash,
1682
+ address: key.address,
1683
+ satoshis: utxo.value,
1684
+ groupId: utxo.group,
1685
+ groupAmount: BigInt(utxo.token_amount)
1686
+ });
1687
+ if (spentOutpoints) spentOutpoints.add(utxo.outpoint_hash);
1688
+ inTokenAmount += BigInt(utxo.token_amount);
1689
+ if (!privateKeys.includes(key.key.privateKey)) privateKeys.push(key.key.privateKey);
1690
+ // Check if we have enough tokens to melt
1691
+ if (inTokenAmount >= amount) {
1692
+ // Create change output if melting less than full amount
1693
+ if (inTokenAmount > amount) {
1694
+ const changeAddress = keys.changeKeys.length > 0 ? keys.changeKeys[keys.changeKeys.length - 1].address : keys.receiveKeys[keys.receiveKeys.length - 1].address;
1695
+ txBuilder.to(changeAddress, (0, $l50U0$libnexats.Transaction).DUST_AMOUNT, token, inTokenAmount - amount);
1696
+ }
1697
+ return privateKeys;
1698
+ }
1699
+ }
1700
+ }
1701
+ throw new Error(`Not enough token balance to melt. Required: ${amount}, Available: ${inTokenAmount}`);
1702
+ }
1703
+ async function $b4a043612f1c4089$export$28a843ca046a6b3f(txBuilder, keys, token, perms, toAddr, spentOutpoints) {
1530
1704
  let allKeys = (0, $4d68f29c39c1a3e4$export$94f569bf4eb0f6f6).getAllKeys(keys);
1531
1705
  let usedKeys = [];
1532
1706
  let reqiredPerms = new Set(perms);
@@ -1535,6 +1709,7 @@ async function $b4a043612f1c4089$export$28a843ca046a6b3f(txBuilder, keys, token,
1535
1709
  let utxos = await (0, $b5bfd17fdf06d231$export$eaa49f0478d81b9d).getTokenUtxos(key.address, token);
1536
1710
  for (let utxo of utxos){
1537
1711
  if (utxo.token_amount > 0) continue;
1712
+ if (spentOutpoints && spentOutpoints.has(utxo.outpoint_hash)) continue;
1538
1713
  let found = false;
1539
1714
  for (let perm of reqiredPerms)if ((0, $22e282633cad8f97$export$7f7cffd29bf2d96d)(utxo.token_amount, perm)) {
1540
1715
  reqiredPerms.delete(perm);
@@ -1547,6 +1722,7 @@ async function $b4a043612f1c4089$export$28a843ca046a6b3f(txBuilder, keys, token,
1547
1722
  satoshis: utxo.value
1548
1723
  });
1549
1724
  usedKeys.push(key.key.privateKey);
1725
+ if (spentOutpoints) spentOutpoints.add(utxo.outpoint_hash);
1550
1726
  // duplicate
1551
1727
  const duplicateAddress = toAddr != null ? toAddr : keys.changeKeys.length > 0 ? keys.changeKeys[keys.changeKeys.length - 1].address : keys.receiveKeys[keys.receiveKeys.length - 1].address;
1552
1728
  txBuilder.to(duplicateAddress, (0, $l50U0$libnexats.Transaction).DUST_AMOUNT, token, (0, $22e282633cad8f97$export$636fb0b03b94ac81)(utxo.token_amount));
@@ -1555,6 +1731,34 @@ async function $b4a043612f1c4089$export$28a843ca046a6b3f(txBuilder, keys, token,
1555
1731
  }
1556
1732
  throw new Error("The required authorities not found");
1557
1733
  }
1734
+ function $b4a043612f1c4089$export$eabd1dee7adcf71(txHex, network) {
1735
+ const tokenOutputs = [];
1736
+ try {
1737
+ const transaction = new (0, $l50U0$libnexats.Transaction)(txHex);
1738
+ for (const output of transaction.outputs)if (output.type !== 0 && output.scriptPubKey.chunks[0]?.opcodenum >= 32) {
1739
+ const tokenIdHex = output.scriptPubKey.chunks[0].buf?.toString('hex');
1740
+ if (tokenIdHex && output.scriptPubKey.chunks[1]?.buf) {
1741
+ const tokenAddress = (0, $l50U0$libnexats.Address).fromObject({
1742
+ data: tokenIdHex,
1743
+ network: network.toString(),
1744
+ type: (0, $l50U0$libnexats.AddressType).GroupIdAddress
1745
+ });
1746
+ if (tokenAddress !== null) {
1747
+ const tokenAddressStr = tokenAddress.toString();
1748
+ // Extract token amount
1749
+ const tokenAmount = (0, $l50U0$libnexats.BNExtended).fromScriptNumBuffer(output.scriptPubKey.chunks[1].buf, false, 8).toBigInt();
1750
+ tokenOutputs.push({
1751
+ tokenId: tokenAddressStr,
1752
+ amount: tokenAmount.toString()
1753
+ });
1754
+ }
1755
+ }
1756
+ }
1757
+ } catch (error) {
1758
+ console.warn('Failed to extract token data from transaction:', error);
1759
+ }
1760
+ return tokenOutputs;
1761
+ }
1558
1762
 
1559
1763
 
1560
1764
 
@@ -1695,6 +1899,7 @@ class $57b0117fe8233fef$export$bba690fb5c12ba04 {
1695
1899
  /** Total value of NEXA being sent in this transaction */ this._totalValue = BigInt(0);
1696
1900
  /** Network this transaction will be broadcast on */ this._network = (0, $l50U0$libnexats.Networks).mainnet;
1697
1901
  /** Transaction options for customizing behavior */ this._txOptions = {};
1902
+ /** Set of outpoints already spent in this transaction to prevent double-spending */ this._spentOutpoints = new Set();
1698
1903
  if (tx instanceof (0, $l50U0$libnexats.TransactionBuilder)) this.transactionBuilder = tx;
1699
1904
  this.tokens = new Set();
1700
1905
  this.transactionBuilder = new (0, $l50U0$libnexats.TransactionBuilder)();
@@ -1812,15 +2017,27 @@ class $57b0117fe8233fef$export$bba690fb5c12ba04 {
1812
2017
  /** Sets the total NEXA value being sent */ set totalValue(value) {
1813
2018
  this._totalValue = value;
1814
2019
  }
2020
+ /** Gets the set of spent outpoints */ get spentOutpoints() {
2021
+ return this._spentOutpoints;
2022
+ }
2023
+ /**
2024
+ * Updates the spent outpoints set with current transaction inputs
2025
+ * @returns Set of outpoint hashes that are already spent
2026
+ */ updateSpentOutpoints() {
2027
+ this._spentOutpoints.clear();
2028
+ for (const input of this.transactionBuilder.transaction.inputs)this._spentOutpoints.add(input.outpoint.toString('hex'));
2029
+ return this._spentOutpoints;
2030
+ }
1815
2031
  /**
1816
2032
  * Validates and creates a token action
1817
2033
  * @param toAddr Destination address
1818
2034
  * @param amount Amount to send
1819
2035
  * @param token Token ID
1820
2036
  * @param action Action type (mint, melt, send, etc.)
2037
+ * @param parent Optional parent token ID (for NFT/SFT minting)
1821
2038
  * @throws Error if validation fails
1822
- */ tokenAction(toAddr, amount, token, action) {
1823
- // Validate destination address
2039
+ */ tokenAction(toAddr, amount, token, action, parent) {
2040
+ // Validate destokenActiontination address
1824
2041
  if (!(0, $0d59d2bcffd646c5$export$8d986bd2866fe6ab)(toAddr, this.network) && !(0, $0d59d2bcffd646c5$export$8d986bd2866fe6ab)(toAddr, this.network, (0, $l50U0$libnexats.AddressType).PayToPublicKeyHash)) throw new Error('Invalid Address.');
1825
2042
  // Validate amount ranges
1826
2043
  if (token && BigInt(amount) < 1n || !token && (0, $ed110f8656071ee4$export$2e2bcd8739ae039)(amount) < (0, $l50U0$libnexats.Transaction).DUST_AMOUNT) throw new Error("The amount is too low.");
@@ -1829,11 +2046,13 @@ class $57b0117fe8233fef$export$bba690fb5c12ba04 {
1829
2046
  if (!(0, $0d59d2bcffd646c5$export$8d986bd2866fe6ab)(token, this.network, (0, $l50U0$libnexats.AddressType).GroupIdAddress)) throw new Error('Invalid Token ID');
1830
2047
  // Ensure tokens are sent to script template addresses
1831
2048
  if ((0, $l50U0$libnexats.Address).getOutputType(toAddr) === 0) throw new Error('Token must be sent to script template address');
1832
- // Add output to transaction
2049
+ // For mint and melt operations, don't add output here - specialized functions will handle it
2050
+ if (action !== 'mint' && action !== 'melt') // Add output to transaction for regular token operations (send, etc.)
1833
2051
  this.transactionBuilder.to(toAddr, (0, $l50U0$libnexats.Transaction).DUST_AMOUNT, token, BigInt(amount));
1834
2052
  // Record the token action
1835
2053
  this.tokens.add({
1836
2054
  token: token,
2055
+ parentToken: parent,
1837
2056
  amount: BigInt(amount),
1838
2057
  action: action
1839
2058
  });
@@ -2157,17 +2376,17 @@ class $e1896e59040fa3c5$export$2e2bcd8739ae039 extends (0, $57b0117fe8233fef$exp
2157
2376
  if (this._keysToSign.length == 0) this._keysToSign.push(this._account.getPrimaryAddressKey().key.privateKey);
2158
2377
  return this;
2159
2378
  }
2160
- mint(token, amount) {
2379
+ mint(token, amount, parent) {
2161
2380
  this.builder.push(async ()=>{
2162
2381
  let toAddr = this._account.accountKeys.receiveKeys.at(-1).address;
2163
- this.tokenAction(toAddr, amount, token, 'mint');
2382
+ this.tokenAction(toAddr, amount, token, 'mint', parent);
2164
2383
  });
2165
2384
  return this;
2166
2385
  }
2167
- melt(token, amount) {
2386
+ melt(token, amount, parent) {
2168
2387
  this.builder.push(async ()=>{
2169
2388
  let toAddr = this._account.accountKeys.receiveKeys.at(-1).address;
2170
- this.tokenAction(toAddr, amount, token, 'melt');
2389
+ this.tokenAction(toAddr, amount, token, 'melt', parent);
2171
2390
  });
2172
2391
  return this;
2173
2392
  }
@@ -2177,23 +2396,22 @@ class $e1896e59040fa3c5$export$2e2bcd8739ae039 extends (0, $57b0117fe8233fef$exp
2177
2396
  let tK = [];
2178
2397
  let nK = [];
2179
2398
  if (this.tokens.size > 0) for (const tokenAction of this.tokens){
2180
- if (tokenAction.action == 'mint' || tokenAction.action == 'melt') tK = tK.concat(await (0, $b4a043612f1c4089$export$1dfa5d829fc95097)(this.transactionBuilder, this._account.accountKeys, tokenAction.token, tokenAction.action));
2181
- else if (tokenAction.action == 'group') tK = tK.concat(await (0, $b4a043612f1c4089$export$d7f2b844e1d59768)(this.transactionBuilder, this._account.accountKeys, tokenAction.extraData?.opReturnData, this.network));
2182
- else if (tokenAction.action == 'subgroup') tK = tK.concat(await (0, $b4a043612f1c4089$export$1dfa5d829fc95097)(this.transactionBuilder, this._account.accountKeys, tokenAction.parentToken, 'subgroup', tokenAction.token, this._account.accountKeys.receiveKeys.at(-1).address, tokenAction.extraData?.quantity));
2183
- else if (tokenAction.action == 'renew') tK = tK.concat(await (0, $b4a043612f1c4089$export$28a843ca046a6b3f)(this.transactionBuilder, this._account.accountKeys, tokenAction.token, tokenAction.extraData.perms, tokenAction.extraData.address));
2399
+ if (tokenAction.action == 'mint') tK = tK.concat(await (0, $b4a043612f1c4089$export$fc6e64edb1452fc7)(this.transactionBuilder, this._account.accountKeys, tokenAction.token, tokenAction.amount, tokenAction.parentToken, this.spentOutpoints));
2400
+ else if (tokenAction.action == 'melt') tK = tK.concat(await (0, $b4a043612f1c4089$export$661377a8795b235c)(this.transactionBuilder, this._account.accountKeys, tokenAction.token, tokenAction.amount, tokenAction.parentToken, this.spentOutpoints));
2401
+ else if (tokenAction.action == 'group') tK = tK.concat(await (0, $b4a043612f1c4089$export$d7f2b844e1d59768)(this.transactionBuilder, this._account.accountKeys, tokenAction.extraData?.opReturnData, this.network, this.spentOutpoints));
2402
+ else if (tokenAction.action == 'subgroup') tK = tK.concat(await (0, $b4a043612f1c4089$export$1dfa5d829fc95097)(this.transactionBuilder, this._account.accountKeys, tokenAction.parentToken, 'subgroup', tokenAction.token, this._account.accountKeys.receiveKeys.at(-1).address, tokenAction.extraData?.quantity, this.spentOutpoints));
2403
+ else if (tokenAction.action == 'renew') tK = tK.concat(await (0, $b4a043612f1c4089$export$28a843ca046a6b3f)(this.transactionBuilder, this._account.accountKeys, tokenAction.token, tokenAction.extraData.perms, tokenAction.extraData.address, this.spentOutpoints));
2184
2404
  else if (tokenAction.action == 'delete') tK = tK.concat(await (0, $b4a043612f1c4089$export$48a48877d6df17e9)(this.transactionBuilder, this._account.accountKeys, tokenAction.extraData.outpoint));
2185
- else tK = tK.concat(await (0, $b4a043612f1c4089$export$931e37acdaa22dcf)(this.transactionBuilder, this._account.accountKeys, tokenAction.token, tokenAction.amount));
2405
+ else tK = tK.concat(await (0, $b4a043612f1c4089$export$931e37acdaa22dcf)(this.transactionBuilder, this._account.accountKeys, tokenAction.token, tokenAction.amount, this.spentOutpoints));
2186
2406
  this._keysToSign.concat(tK);
2187
2407
  }
2188
- nK = nK.concat(await (0, $b4a043612f1c4089$export$afd979971a55acfc)(this.transactionBuilder, this._account.accountKeys, this.totalValue, this.txOptions));
2408
+ nK = nK.concat(await (0, $b4a043612f1c4089$export$afd979971a55acfc)(this.transactionBuilder, this._account.accountKeys, this.totalValue, this.txOptions, this.spentOutpoints));
2189
2409
  this._keysToSign = tK.concat(nK);
2190
2410
  });
2191
2411
  return this;
2192
2412
  }
2193
2413
  sign() {
2194
2414
  this.builder.push(async ()=>{
2195
- const blockHeight = await (0, $b5bfd17fdf06d231$export$eaa49f0478d81b9d).getBlockTip();
2196
- this.transactionBuilder.lockUntilBlockHeight(blockHeight.height);
2197
2415
  // Process each transaction input using placeholder-based signing
2198
2416
  const inputs = this.transactionBuilder.transaction.inputs;
2199
2417
  for(let inputIndex = 0; inputIndex < inputs.length; inputIndex++){
@@ -2350,7 +2568,7 @@ class $e1896e59040fa3c5$export$2e2bcd8739ae039 extends (0, $57b0117fe8233fef$exp
2350
2568
  // Empty scriptSig - sign with SIGHASH_ALL
2351
2569
  if (chunks.length === 0) return {
2352
2570
  strategy: 'sign_all',
2353
- sighashType: null
2571
+ sighashType: (0, $l50U0$libnexats.SighashType).ALL
2354
2572
  };
2355
2573
  // Single chunk
2356
2574
  if (chunks.length === 1) {
@@ -2383,11 +2601,7 @@ class $e1896e59040fa3c5$export$2e2bcd8739ae039 extends (0, $57b0117fe8233fef$exp
2383
2601
  placeholderIndex = i;
2384
2602
  sighashType = this.extractSighashFromPlaceholder(chunk.buf);
2385
2603
  } else // Non-placeholder satisfier element - preserve it
2386
- satisfierElements.push({
2387
- buf: chunk.buf,
2388
- len: chunk.len || (chunk.buf ? chunk.buf.length : 0),
2389
- opcodenum: chunk.opcodenum
2390
- });
2604
+ satisfierElements.push(chunk);
2391
2605
  }
2392
2606
  if (placeholderIndex !== undefined) return {
2393
2607
  strategy: 'replace_placeholder',
@@ -2462,10 +2676,14 @@ class $7fcf3b163a95e69a$export$2e2bcd8739ae039 {
2462
2676
  * Creates a new account of the specified type
2463
2677
  * @param accountType Type of account to create (DAPP, VAULT, or DEFAULT)
2464
2678
  * @param masterKey Master HD private key for deriving account keys
2679
+ * @param forceNextIndex If true, forces the next sequential index regardless of blockchain usage
2465
2680
  * @returns Promise resolving to the created account
2466
- */ async createAccount(accountType, masterKey) {
2467
- // Get the next available index for this account type
2468
- const nextIndex = await (0, $0d59d2bcffd646c5$export$ef13479e8d3251d7)(accountType, masterKey);
2681
+ */ async createAccount(accountType, masterKey, forceNextIndex = false) {
2682
+ let nextIndex;
2683
+ if (forceNextIndex) // Force next sequential index considering both blockchain and store
2684
+ nextIndex = await this.getNextSequentialIndex(accountType, masterKey);
2685
+ else // Get the next available index for this account type (discovery-based)
2686
+ nextIndex = await (0, $0d59d2bcffd646c5$export$ef13479e8d3251d7)(accountType, masterKey);
2469
2687
  const accountStoreKey = this.getAccountStoreKey(accountType, nextIndex);
2470
2688
  // Check if account already exists
2471
2689
  const indexExists = this._accounts.get(String(accountStoreKey));
@@ -2576,6 +2794,41 @@ class $7fcf3b163a95e69a$export$2e2bcd8739ae039 {
2576
2794
  }
2577
2795
  return accounts;
2578
2796
  }
2797
+ /**
2798
+ * Gets the next sequential index for an account type, considering both blockchain
2799
+ * discovery and accounts already in the store
2800
+ * @param accountType The account type to get the next index for
2801
+ * @param masterKey Master HD private key for blockchain discovery
2802
+ * @returns Promise resolving to the next safe sequential index
2803
+ */ async getNextSequentialIndex(accountType, masterKey) {
2804
+ // First, get the discovery-based index (what exists on blockchain)
2805
+ const discoveryIndex = await (0, $0d59d2bcffd646c5$export$ef13479e8d3251d7)(accountType, masterKey);
2806
+ // Then, check what's the next index based on current store
2807
+ const storeBasedIndex = this.getNextStoreIndex(accountType);
2808
+ // Use whichever is higher to ensure we don't conflict with either
2809
+ return Math.max(discoveryIndex, storeBasedIndex);
2810
+ }
2811
+ /**
2812
+ * Gets the next index based only on accounts currently in the store
2813
+ * @param accountType The account type to check
2814
+ * @returns The next available index in the store
2815
+ */ getNextStoreIndex(accountType) {
2816
+ const indexes = [];
2817
+ for (const [key, _] of this._accounts)switch(accountType){
2818
+ case (0, $0d59d2bcffd646c5$export$b8ca5fa4899cbfc7).DAPP_ACCOUNT:
2819
+ if (key.startsWith('2.')) indexes.push(parseInt(key.split('.')[1]));
2820
+ break;
2821
+ case (0, $0d59d2bcffd646c5$export$b8ca5fa4899cbfc7).VAULT_ACCOUNT:
2822
+ if (key.startsWith('1.')) indexes.push(parseInt(key.split('.')[1]));
2823
+ break;
2824
+ case (0, $0d59d2bcffd646c5$export$b8ca5fa4899cbfc7).NEXA_ACCOUNT:
2825
+ if (!key.includes('.')) indexes.push(parseInt(key));
2826
+ break;
2827
+ }
2828
+ if (indexes.length === 0) return 0; // First account of this type
2829
+ // Return the next sequential index after the highest existing one
2830
+ return Math.max(...indexes) + 1;
2831
+ }
2579
2832
  }
2580
2833
 
2581
2834
 
@@ -2667,6 +2920,7 @@ class $b76d3bd5024ccfc0$export$2e2bcd8739ae039 {
2667
2920
  * const wallet = new Wallet(undefined, 'testnet');
2668
2921
  * ```
2669
2922
  */ constructor(data, network){
2923
+ /** Whether to force sequential account indexing instead of discovery-based indexing */ this._forceSequentialIndexing = false;
2670
2924
  this._network = (0, $l50U0$libnexats.Networks).get(network) ?? (0, $l50U0$libnexats.Networks).mainnet;
2671
2925
  this._accountStore = new (0, $7fcf3b163a95e69a$export$2e2bcd8739ae039)();
2672
2926
  if ((0, $54dde1e65fb8e5b8$export$2e2bcd8739ae039)(data)) {
@@ -2820,7 +3074,7 @@ class $b76d3bd5024ccfc0$export$2e2bcd8739ae039 {
2820
3074
  * const dappAccount = await wallet.newAccount('DappAccount');
2821
3075
  * ```
2822
3076
  */ async newAccount(accountType) {
2823
- return await this.accountStore.createAccount(accountType, this.masterKey);
3077
+ return await this.accountStore.createAccount(accountType, this.masterKey, this._forceSequentialIndexing);
2824
3078
  }
2825
3079
  /**
2826
3080
  * Broadcast a signed transaction to the Nexa network
@@ -3038,6 +3292,47 @@ class $b76d3bd5024ccfc0$export$2e2bcd8739ae039 {
3038
3292
  */ get network() {
3039
3293
  return this._network;
3040
3294
  }
3295
+ /**
3296
+ * Get the current sequential indexing setting
3297
+ *
3298
+ * @returns true if forcing sequential indexing, false if using discovery-based indexing
3299
+ *
3300
+ * @example
3301
+ * ```typescript
3302
+ * const isSequential = wallet.forceSequentialIndexing;
3303
+ * console.log('Sequential indexing:', isSequential);
3304
+ * ```
3305
+ */ get forceSequentialIndexing() {
3306
+ return this._forceSequentialIndexing;
3307
+ }
3308
+ /**
3309
+ * Set whether to force sequential account indexing
3310
+ *
3311
+ * When enabled, new accounts will use sequential indexes (0, 1, 2, ...) regardless
3312
+ * of blockchain activity. This is useful for multi-user wallets where each user
3313
+ * needs a unique account even if they haven't used it yet.
3314
+ *
3315
+ * When disabled (default), account creation uses discovery-based indexing which
3316
+ * scans the blockchain for existing activity before assigning indexes.
3317
+ *
3318
+ * @param force - true to force sequential indexing, false for discovery-based
3319
+ *
3320
+ * @example
3321
+ * ```typescript
3322
+ * // Enable sequential indexing for multi-user scenarios
3323
+ * wallet.forceSequentialIndexing = true;
3324
+ *
3325
+ * // Create accounts - they'll be 2.0, 2.1, 2.2 regardless of usage
3326
+ * const alice = await wallet.newAccount(AccountType.DAPP_ACCOUNT);
3327
+ * const bob = await wallet.newAccount(AccountType.DAPP_ACCOUNT);
3328
+ * const charlie = await wallet.newAccount(AccountType.DAPP_ACCOUNT);
3329
+ *
3330
+ * // Disable for normal discovery-based indexing
3331
+ * wallet.forceSequentialIndexing = false;
3332
+ * ```
3333
+ */ set forceSequentialIndexing(force) {
3334
+ this._forceSequentialIndexing = force;
3335
+ }
3041
3336
  }
3042
3337
 
3043
3338
 
@@ -3049,13 +3344,15 @@ class $b76d3bd5024ccfc0$export$2e2bcd8739ae039 {
3049
3344
 
3050
3345
 
3051
3346
  const $52632971edbdb934$var$MAX_INPUTS_OUTPUTS = 250;
3052
- async function $52632971edbdb934$export$20e004915450ed44(txBuilder, addresses, totalTxValue, options) {
3347
+ async function $52632971edbdb934$export$20e004915450ed44(txBuilder, addresses, totalTxValue, options, spentOutpoints) {
3053
3348
  if ((0, $bc5ca2c06b1affa3$export$c8733ae29fb53302)(addresses)) throw new Error("Not enough Nexa balance.");
3054
3349
  let usedAddresses = new Set();
3055
3350
  let origAmount = options.isConsolidate ? 0 : Number(totalTxValue);
3056
3351
  for (let item of addresses){
3057
3352
  let utxos = await (0, $b5bfd17fdf06d231$export$eaa49f0478d81b9d).getNexaUtxos(item.address);
3058
3353
  for (let utxo of utxos){
3354
+ // Skip if this outpoint is already spent
3355
+ if (spentOutpoints && spentOutpoints.has(utxo.outpoint_hash)) continue;
3059
3356
  let input = {
3060
3357
  outpoint: utxo.outpoint_hash,
3061
3358
  address: item.address,
@@ -3063,6 +3360,8 @@ async function $52632971edbdb934$export$20e004915450ed44(txBuilder, addresses, t
3063
3360
  templateData: options.templateData
3064
3361
  };
3065
3362
  txBuilder.from(input);
3363
+ // Add to spent outpoints set
3364
+ if (spentOutpoints) spentOutpoints.add(utxo.outpoint_hash);
3066
3365
  if (!usedAddresses.has(item.address)) usedAddresses.add(item.address);
3067
3366
  if (options.isConsolidate) {
3068
3367
  // need to handle change
@@ -3106,7 +3405,7 @@ async function $52632971edbdb934$export$20e004915450ed44(txBuilder, addresses, t
3106
3405
  };
3107
3406
  throw new Error(JSON.stringify(err));
3108
3407
  }
3109
- async function $52632971edbdb934$export$49bc96b87058cba4(txBuilder, addresses, token, outTokenAmount) {
3408
+ async function $52632971edbdb934$export$49bc96b87058cba4(txBuilder, addresses, token, outTokenAmount, spentOutpoints) {
3110
3409
  if ((0, $bc5ca2c06b1affa3$export$c8733ae29fb53302)(addresses)) throw new Error("Not enough token balance.");
3111
3410
  let usedKeys = new Set();
3112
3411
  let inTokenAmount = 0n;
@@ -3114,6 +3413,8 @@ async function $52632971edbdb934$export$49bc96b87058cba4(txBuilder, addresses, t
3114
3413
  let utxos = await (0, $b5bfd17fdf06d231$export$eaa49f0478d81b9d).getTokenUtxos(item.address, token);
3115
3414
  for (let utxo of utxos){
3116
3415
  if (utxo.token_amount < 0) continue;
3416
+ // Skip if this outpoint is already spent
3417
+ if (spentOutpoints && spentOutpoints.has(utxo.outpoint_hash)) continue;
3117
3418
  txBuilder.from({
3118
3419
  outpoint: utxo.outpoint_hash,
3119
3420
  address: item.address,
@@ -3121,6 +3422,8 @@ async function $52632971edbdb934$export$49bc96b87058cba4(txBuilder, addresses, t
3121
3422
  groupId: utxo.group,
3122
3423
  groupAmount: BigInt(utxo.token_amount)
3123
3424
  });
3425
+ // Add to spent outpoints set
3426
+ if (spentOutpoints) spentOutpoints.add(utxo.outpoint_hash);
3124
3427
  inTokenAmount = inTokenAmount + BigInt(utxo.token_amount);
3125
3428
  if (!usedKeys.has(item.address)) usedKeys.add(item.address);
3126
3429
  if (inTokenAmount > (0, $bc5ca2c06b1affa3$export$8ba128bc85947a2a)) throw new Error("Token inputs exceeded max amount. Consider sending in small chunks");
@@ -3135,17 +3438,21 @@ async function $52632971edbdb934$export$49bc96b87058cba4(txBuilder, addresses, t
3135
3438
  }
3136
3439
  throw new Error("Not enough token balance");
3137
3440
  }
3138
- async function $52632971edbdb934$export$74e83de914f372c5(txBuilder, addresses, opReturnData, network) {
3441
+ async function $52632971edbdb934$export$74e83de914f372c5(txBuilder, addresses, opReturnData, network, spentOutpoints) {
3139
3442
  let outpoint = '';
3140
3443
  let usedKeys = [];
3141
3444
  for (let item of addresses){
3142
3445
  let utxos = await (0, $b5bfd17fdf06d231$export$eaa49f0478d81b9d).getNexaUtxos(item.address);
3143
3446
  for (let utxo of utxos){
3447
+ // Skip if this outpoint is already spent
3448
+ if (spentOutpoints && spentOutpoints.has(utxo.outpoint_hash)) continue;
3144
3449
  txBuilder.from({
3145
3450
  outpoint: utxo.outpoint_hash,
3146
3451
  address: item.address,
3147
3452
  satoshis: utxo.value
3148
3453
  });
3454
+ // Add to spent outpoints set
3455
+ if (spentOutpoints) spentOutpoints.add(utxo.outpoint_hash);
3149
3456
  if ((0, $bc5ca2c06b1affa3$export$c8733ae29fb53302)(outpoint) && !utxo.has_token) {
3150
3457
  outpoint = utxo.outpoint_hash;
3151
3458
  let id = (0, $l50U0$libnexats.GroupToken).findGroupId(outpoint, Buffer.from(opReturnData, 'hex'), (0, $l50U0$libnexats.GroupToken).authFlags.ACTIVE_FLAG_BITS);
@@ -3172,19 +3479,23 @@ async function $52632971edbdb934$export$1eb54f2f084fd3c6(txBuilder, addresses, o
3172
3479
  addrKey.address
3173
3480
  ];
3174
3481
  }
3175
- async function $52632971edbdb934$export$d7c9c386067a6463(txBuilder, addresses, token, perm, subgroup = '', quantity) {
3482
+ async function $52632971edbdb934$export$d7c9c386067a6463(txBuilder, addresses, token, perm, subgroup = '', subgroupAddr = '', quantity, spentOutpoints) {
3176
3483
  for (let item of addresses){
3177
3484
  let utxos = await (0, $b5bfd17fdf06d231$export$eaa49f0478d81b9d).getTokenUtxos(item.address, token);
3178
3485
  for (let utxo of utxos){
3179
3486
  if (!(0, $22e282633cad8f97$export$7f7cffd29bf2d96d)(utxo.token_amount, perm)) continue;
3487
+ // Skip if this outpoint is already spent
3488
+ if (spentOutpoints && spentOutpoints.has(utxo.outpoint_hash)) continue;
3180
3489
  txBuilder.from({
3181
3490
  outpoint: utxo.outpoint_hash,
3182
3491
  address: item.address,
3183
3492
  satoshis: utxo.value
3184
3493
  });
3494
+ // Add to spent outpoints set
3495
+ if (spentOutpoints) spentOutpoints.add(utxo.outpoint_hash);
3185
3496
  if (perm === 'subgroup') {
3186
3497
  const subgroupQuantity = quantity ?? (0, $22e282633cad8f97$export$636fb0b03b94ac81)(utxo.token_amount, false);
3187
- txBuilder.to(item.address, (0, $l50U0$libnexats.Transaction).DUST_AMOUNT, subgroup, subgroupQuantity);
3498
+ txBuilder.to(subgroupAddr, (0, $l50U0$libnexats.Transaction).DUST_AMOUNT, subgroup, subgroupQuantity);
3188
3499
  }
3189
3500
  // if renew flag included, we don't want to burn it
3190
3501
  if ((0, $l50U0$libnexats.GroupToken).allowsRenew(BigInt.asUintN(64, BigInt(utxo.token_amount)))) txBuilder.to(item.address, (0, $l50U0$libnexats.Transaction).DUST_AMOUNT, token, (0, $22e282633cad8f97$export$636fb0b03b94ac81)(utxo.token_amount));
@@ -3195,7 +3506,95 @@ async function $52632971edbdb934$export$d7c9c386067a6463(txBuilder, addresses, t
3195
3506
  }
3196
3507
  throw new Error("The requested authority not found");
3197
3508
  }
3198
- async function $52632971edbdb934$export$5c44e04d8c04c292(txBuilder, addresses, token, perms, toAddr) {
3509
+ async function $52632971edbdb934$export$91f9f23df90683cc(txBuilder, addresses, token, amount, parentToken, spentOutpoints) {
3510
+ const usedAddresses = [];
3511
+ // Determine which token to look for authority
3512
+ const authTokenId = parentToken || token;
3513
+ // Find and add mint authority
3514
+ let mintAuthorityFound = false;
3515
+ for (let item of addresses){
3516
+ if (mintAuthorityFound) break;
3517
+ let authUtxos = await (0, $b5bfd17fdf06d231$export$eaa49f0478d81b9d).getTokenUtxos(item.address, authTokenId);
3518
+ for (let utxo of authUtxos){
3519
+ if (!(0, $22e282633cad8f97$export$7f7cffd29bf2d96d)(utxo.token_amount, 'mint')) continue;
3520
+ // Skip if already spent
3521
+ if (spentOutpoints && spentOutpoints.has(utxo.outpoint_hash)) continue;
3522
+ // Add mint authority as input
3523
+ txBuilder.from({
3524
+ outpoint: utxo.outpoint_hash,
3525
+ address: item.address,
3526
+ satoshis: utxo.value
3527
+ });
3528
+ if (spentOutpoints) spentOutpoints.add(utxo.outpoint_hash);
3529
+ // Create the minted tokens output
3530
+ txBuilder.to(item.address, (0, $l50U0$libnexats.Transaction).DUST_AMOUNT, token, amount);
3531
+ // Preserve the mint authority for future use if renewable
3532
+ if ((0, $l50U0$libnexats.GroupToken).allowsRenew(BigInt.asUintN(64, BigInt(utxo.token_amount)))) txBuilder.to(item.address, (0, $l50U0$libnexats.Transaction).DUST_AMOUNT, authTokenId, (0, $22e282633cad8f97$export$636fb0b03b94ac81)(utxo.token_amount));
3533
+ usedAddresses.push(item.address);
3534
+ mintAuthorityFound = true;
3535
+ break;
3536
+ }
3537
+ }
3538
+ if (!mintAuthorityFound) throw new Error(`Mint authority not found for token ${authTokenId}`);
3539
+ return usedAddresses;
3540
+ }
3541
+ async function $52632971edbdb934$export$cfda880a425a2203(txBuilder, addresses, token, amount, parentToken, spentOutpoints) {
3542
+ const usedAddresses = [];
3543
+ // Determine which token to look for melt authority
3544
+ const authTokenId = parentToken || token;
3545
+ // Find and add melt authority first
3546
+ let meltAuthorityFound = false;
3547
+ for (let item of addresses){
3548
+ if (meltAuthorityFound) break;
3549
+ let authUtxos = await (0, $b5bfd17fdf06d231$export$eaa49f0478d81b9d).getTokenUtxos(item.address, authTokenId);
3550
+ for (let utxo of authUtxos){
3551
+ if (!(0, $22e282633cad8f97$export$7f7cffd29bf2d96d)(utxo.token_amount, 'melt')) continue;
3552
+ // Skip if already spent
3553
+ if (spentOutpoints && spentOutpoints.has(utxo.outpoint_hash)) continue;
3554
+ // Add melt authority as input
3555
+ txBuilder.from({
3556
+ outpoint: utxo.outpoint_hash,
3557
+ address: item.address,
3558
+ satoshis: utxo.value
3559
+ });
3560
+ if (spentOutpoints) spentOutpoints.add(utxo.outpoint_hash);
3561
+ usedAddresses.push(item.address);
3562
+ meltAuthorityFound = true;
3563
+ break;
3564
+ }
3565
+ }
3566
+ if (!meltAuthorityFound) throw new Error("Melt authority not found for token");
3567
+ // Now find and add token UTXOs to melt
3568
+ let inTokenAmount = 0n;
3569
+ for (let item of addresses){
3570
+ let utxos = await (0, $b5bfd17fdf06d231$export$eaa49f0478d81b9d).getTokenUtxos(item.address, token);
3571
+ for (let utxo of utxos){
3572
+ // Skip authorities (negative amounts)
3573
+ if (utxo.token_amount < 0) continue;
3574
+ // Skip if already spent
3575
+ if (spentOutpoints && spentOutpoints.has(utxo.outpoint_hash)) continue;
3576
+ // Add token UTXO as input
3577
+ txBuilder.from({
3578
+ outpoint: utxo.outpoint_hash,
3579
+ address: item.address,
3580
+ satoshis: utxo.value,
3581
+ groupId: utxo.group,
3582
+ groupAmount: BigInt(utxo.token_amount)
3583
+ });
3584
+ if (spentOutpoints) spentOutpoints.add(utxo.outpoint_hash);
3585
+ inTokenAmount += BigInt(utxo.token_amount);
3586
+ if (!usedAddresses.includes(item.address)) usedAddresses.push(item.address);
3587
+ // Check if we have enough tokens to melt
3588
+ if (inTokenAmount >= amount) {
3589
+ // Create change output if melting less than full amount
3590
+ if (inTokenAmount > amount) txBuilder.to(item.address, (0, $l50U0$libnexats.Transaction).DUST_AMOUNT, token, inTokenAmount - amount);
3591
+ return usedAddresses;
3592
+ }
3593
+ }
3594
+ }
3595
+ throw new Error(`Not enough token balance to melt. Required: ${amount}, Available: ${inTokenAmount}`);
3596
+ }
3597
+ async function $52632971edbdb934$export$5c44e04d8c04c292(txBuilder, addresses, token, perms, toAddr, spentOutpoints) {
3199
3598
  let usedAddresses = [];
3200
3599
  let reqiredPerms = new Set(perms);
3201
3600
  reqiredPerms.add('authorise');
@@ -3203,6 +3602,8 @@ async function $52632971edbdb934$export$5c44e04d8c04c292(txBuilder, addresses, t
3203
3602
  let utxos = await (0, $b5bfd17fdf06d231$export$eaa49f0478d81b9d).getTokenUtxos(item.address, token);
3204
3603
  for (let utxo of utxos){
3205
3604
  if (utxo.token_amount > 0) continue;
3605
+ // Skip if this outpoint is already spent
3606
+ if (spentOutpoints && spentOutpoints.has(utxo.outpoint_hash)) continue;
3206
3607
  let found = false;
3207
3608
  for (let perm of reqiredPerms)if ((0, $22e282633cad8f97$export$7f7cffd29bf2d96d)(utxo.token_amount, perm)) {
3208
3609
  reqiredPerms.delete(perm);
@@ -3215,6 +3616,8 @@ async function $52632971edbdb934$export$5c44e04d8c04c292(txBuilder, addresses, t
3215
3616
  satoshis: utxo.value
3216
3617
  });
3217
3618
  usedAddresses.push(item.address);
3619
+ // Add to spent outpoints set
3620
+ if (spentOutpoints) spentOutpoints.add(utxo.outpoint_hash);
3218
3621
  // duplicate
3219
3622
  txBuilder.to(toAddr != null ? toAddr : item.address, (0, $l50U0$libnexats.Transaction).DUST_AMOUNT, token, (0, $22e282633cad8f97$export$636fb0b03b94ac81)(utxo.token_amount));
3220
3623
  if (reqiredPerms.size === 0) return usedAddresses;
@@ -3264,10 +3667,11 @@ class $2ce5b75d10954bb1$export$2e2bcd8739ae039 extends (0, $57b0117fe8233fef$exp
3264
3667
  * @param token Token ID to mint
3265
3668
  * @param amount Amount to mint
3266
3669
  * @param toAddr Destination address for minted tokens
3670
+ * @param parent Optional parent token ID (for NFT/SFT minting)
3267
3671
  * @returns This instance for chaining
3268
- */ mint(token, amount, toAddr) {
3672
+ */ mint(token, amount, toAddr, parent) {
3269
3673
  this.builder.push(async ()=>{
3270
- this.tokenAction(toAddr, amount, token, 'mint');
3674
+ this.tokenAction(toAddr, amount, token, 'mint', parent);
3271
3675
  });
3272
3676
  return this;
3273
3677
  }
@@ -3276,10 +3680,11 @@ class $2ce5b75d10954bb1$export$2e2bcd8739ae039 extends (0, $57b0117fe8233fef$exp
3276
3680
  * @param token Token ID to melt
3277
3681
  * @param amount Amount to melt
3278
3682
  * @param toAddr Destination address for melted tokens
3683
+ * @param parent Optional parent token ID (for NFT/SFT melting)
3279
3684
  * @returns This instance for chaining
3280
- */ melt(token, amount, toAddr) {
3685
+ */ melt(token, amount, toAddr, parent) {
3281
3686
  this.builder.push(async ()=>{
3282
- this.tokenAction(toAddr, amount, token, 'melt');
3687
+ this.tokenAction(toAddr, amount, token, 'melt', parent);
3283
3688
  });
3284
3689
  return this;
3285
3690
  }
@@ -3294,23 +3699,25 @@ class $2ce5b75d10954bb1$export$2e2bcd8739ae039 extends (0, $57b0117fe8233fef$exp
3294
3699
  let nexaAddresses = [];
3295
3700
  // Process token operations if any are configured
3296
3701
  if (this.tokens.size > 0) for (const tokenAction of this.tokens){
3297
- if (tokenAction.action == 'mint' || tokenAction.action == 'melt') // Handle token minting/melting - requires authority
3298
- tokenAddresses = tokenAddresses.concat(await (0, $52632971edbdb934$export$d7c9c386067a6463)(this.transactionBuilder, this._availableAddresses, tokenAction.token, tokenAction.action));
3702
+ if (tokenAction.action == 'mint') // Use specialized mint function for groups and subgroups
3703
+ tokenAddresses = tokenAddresses.concat(await (0, $52632971edbdb934$export$91f9f23df90683cc)(this.transactionBuilder, this._availableAddresses, tokenAction.token, tokenAction.amount, tokenAction.parentToken, this.spentOutpoints));
3704
+ else if (tokenAction.action == 'melt') // Use specialized melt function for groups and subgroups
3705
+ tokenAddresses = tokenAddresses.concat(await (0, $52632971edbdb934$export$cfda880a425a2203)(this.transactionBuilder, this._availableAddresses, tokenAction.token, tokenAction.amount, tokenAction.parentToken, this.spentOutpoints));
3299
3706
  else if (tokenAction.action == 'group') // Handle group token creation
3300
- tokenAddresses = tokenAddresses.concat(await (0, $52632971edbdb934$export$74e83de914f372c5)(this.transactionBuilder, this._availableAddresses, tokenAction.extraData?.opReturnData, this.network));
3707
+ tokenAddresses = tokenAddresses.concat(await (0, $52632971edbdb934$export$74e83de914f372c5)(this.transactionBuilder, this._availableAddresses, tokenAction.extraData?.opReturnData, this.network, this.spentOutpoints));
3301
3708
  else if (tokenAction.action == 'subgroup') // Handle subgroup token creation
3302
- tokenAddresses = tokenAddresses.concat(await (0, $52632971edbdb934$export$d7c9c386067a6463)(this.transactionBuilder, this._availableAddresses, tokenAction.parentToken, tokenAction.action, tokenAction.token, tokenAction.extraData?.quantity));
3709
+ tokenAddresses = tokenAddresses.concat(await (0, $52632971edbdb934$export$d7c9c386067a6463)(this.transactionBuilder, this._availableAddresses, tokenAction.parentToken, tokenAction.action, tokenAction.token, this._availableAddresses[0]?.address, tokenAction.extraData?.quantity, this.spentOutpoints));
3303
3710
  else if (tokenAction.action == 'renew') // Handle authority renewal
3304
- tokenAddresses = tokenAddresses.concat(await (0, $52632971edbdb934$export$5c44e04d8c04c292)(this.transactionBuilder, this._availableAddresses, tokenAction.token, tokenAction.extraData.perms, tokenAction.extraData?.address));
3711
+ tokenAddresses = tokenAddresses.concat(await (0, $52632971edbdb934$export$5c44e04d8c04c292)(this.transactionBuilder, this._availableAddresses, tokenAction.token, tokenAction.extraData.perms, tokenAction.extraData?.address, this.spentOutpoints));
3305
3712
  else if (tokenAction.action == 'delete') // Handle authority deletion
3306
3713
  tokenAddresses = tokenAddresses.concat(await (0, $52632971edbdb934$export$1eb54f2f084fd3c6)(this.transactionBuilder, this._availableAddresses, tokenAction.extraData.outpoint));
3307
3714
  else // Handle regular token transfers
3308
- tokenAddresses = tokenAddresses.concat(await (0, $52632971edbdb934$export$49bc96b87058cba4)(this.transactionBuilder, this._availableAddresses, tokenAction.token, tokenAction.amount));
3715
+ tokenAddresses = tokenAddresses.concat(await (0, $52632971edbdb934$export$49bc96b87058cba4)(this.transactionBuilder, this._availableAddresses, tokenAction.token, tokenAction.amount, this.spentOutpoints));
3309
3716
  // Accumulate addresses that need signing
3310
3717
  this._addressesToSignWith.concat(tokenAddresses);
3311
3718
  }
3312
3719
  // Populate NEXA inputs for transaction fees and change
3313
- nexaAddresses = nexaAddresses.concat(await (0, $52632971edbdb934$export$20e004915450ed44)(this.transactionBuilder, this._availableAddresses, this.totalValue, this.txOptions));
3720
+ nexaAddresses = nexaAddresses.concat(await (0, $52632971edbdb934$export$20e004915450ed44)(this.transactionBuilder, this._availableAddresses, this.totalValue, this.txOptions, this.spentOutpoints));
3314
3721
  // Combine all addresses that need signing
3315
3722
  this._addressesToSignWith = tokenAddresses.concat(nexaAddresses);
3316
3723
  });
@@ -3885,7 +4292,7 @@ class $4d217697e55d958e$export$80793d8292a1630a {
3885
4292
  */ async sendTransaction(toAddress, amount, opReturnData, broadcast = true) {
3886
4293
  if (!this.watchOnlyWallet || !this.connectedWalletAddress) throw new Error('No wallet connected');
3887
4294
  // Create unsigned transaction using WatchOnlyWallet
3888
- let txBuilder = this.watchOnlyWallet.newTransaction().onNetwork(this.currentNetwork).sendTo(toAddress, amount);
4295
+ let txBuilder = this.watchOnlyWallet.newTransaction().sendTo(toAddress, amount);
3889
4296
  // Add OP_RETURN data if provided
3890
4297
  if (opReturnData) txBuilder = txBuilder.addOpReturn(opReturnData);
3891
4298
  // Populate and build unsigned transaction
@@ -3903,7 +4310,7 @@ class $4d217697e55d958e$export$80793d8292a1630a {
3903
4310
  */ async sendTokenTransaction(toAddress, amount, tokenId, opReturnData, broadcast = true) {
3904
4311
  if (!this.watchOnlyWallet || !this.connectedWalletAddress) throw new Error('No wallet connected');
3905
4312
  // Create unsigned token transaction
3906
- let txBuilder = this.watchOnlyWallet.newTransaction().onNetwork(this.currentNetwork).sendToToken(toAddress, amount, tokenId);
4313
+ let txBuilder = this.watchOnlyWallet.newTransaction().sendToToken(toAddress, amount, tokenId);
3907
4314
  // Add OP_RETURN data if provided
3908
4315
  if (opReturnData) txBuilder = txBuilder.addOpReturn(opReturnData);
3909
4316
  // Populate and build unsigned transaction
@@ -3922,7 +4329,7 @@ class $4d217697e55d958e$export$80793d8292a1630a {
3922
4329
  */ async createToken(name, ticker, decimals, docUrl, docHash, broadcast = true) {
3923
4330
  if (!this.watchOnlyWallet || !this.connectedWalletAddress) throw new Error('No wallet connected');
3924
4331
  // Create token creation transaction
3925
- const unsignedTx = await this.watchOnlyWallet.newTransaction().onNetwork(this.currentNetwork).token(name, ticker, decimals, docUrl, docHash).populate().build();
4332
+ const unsignedTx = await this.watchOnlyWallet.newTransaction().token(name, ticker, decimals, docUrl, docHash).populate().build();
3926
4333
  return await this.provider.signTransaction(this.connectedWalletAddress, unsignedTx, broadcast);
3927
4334
  }
3928
4335
  /**
@@ -3936,7 +4343,7 @@ class $4d217697e55d958e$export$80793d8292a1630a {
3936
4343
  */ async createCollection(name, ticker, docUrl, docHash, broadcast = true) {
3937
4344
  if (!this.watchOnlyWallet || !this.connectedWalletAddress) throw new Error('No wallet connected');
3938
4345
  // Create collection creation transaction
3939
- const unsignedTx = await this.watchOnlyWallet.newTransaction().onNetwork(this.currentNetwork).collection(name, ticker, docUrl, docHash).populate().build();
4346
+ const unsignedTx = await this.watchOnlyWallet.newTransaction().collection(name, ticker, docUrl, docHash).populate().build();
3940
4347
  return await this.provider.signTransaction(this.connectedWalletAddress, unsignedTx, broadcast);
3941
4348
  }
3942
4349
  /**
@@ -3949,7 +4356,7 @@ class $4d217697e55d958e$export$80793d8292a1630a {
3949
4356
  */ async createNFT(parentCollection, zipUrl, zipHash, broadcast = true) {
3950
4357
  if (!this.watchOnlyWallet || !this.connectedWalletAddress) throw new Error('No wallet connected');
3951
4358
  // Create NFT creation transaction
3952
- const unsignedTx = await this.watchOnlyWallet.newTransaction().onNetwork(this.currentNetwork).nft(parentCollection, zipUrl, zipHash).populate().build();
4359
+ const unsignedTx = await this.watchOnlyWallet.newTransaction().nft(parentCollection, zipUrl, zipHash).populate().build();
3953
4360
  return await this.provider.signTransaction(this.connectedWalletAddress, unsignedTx, broadcast);
3954
4361
  }
3955
4362
  /**
@@ -3963,7 +4370,7 @@ class $4d217697e55d958e$export$80793d8292a1630a {
3963
4370
  */ async createSFT(parentCollection, zipUrl, zipHash, quantity, broadcast = true) {
3964
4371
  if (!this.watchOnlyWallet || !this.connectedWalletAddress) throw new Error('No wallet connected');
3965
4372
  // Create SFT creation transaction
3966
- const unsignedTx = await this.watchOnlyWallet.newTransaction().onNetwork(this.currentNetwork).sft(parentCollection, zipUrl, zipHash, quantity).populate().build();
4373
+ const unsignedTx = await this.watchOnlyWallet.newTransaction().sft(parentCollection, zipUrl, zipHash, quantity).populate().build();
3967
4374
  return await this.provider.signTransaction(this.connectedWalletAddress, unsignedTx, broadcast);
3968
4375
  }
3969
4376
  /**
@@ -3985,7 +4392,7 @@ class $4d217697e55d958e$export$80793d8292a1630a {
3985
4392
  * @returns Promise resolving to unsigned transaction hex
3986
4393
  */ async buildTransaction(toAddress, amount, tokenId, opReturnData) {
3987
4394
  if (!this.watchOnlyWallet) throw new Error('No wallet connected');
3988
- let txBuilder = this.watchOnlyWallet.newTransaction().onNetwork(this.currentNetwork);
4395
+ let txBuilder = this.watchOnlyWallet.newTransaction();
3989
4396
  if (tokenId) txBuilder = txBuilder.sendToToken(toAddress, amount, tokenId);
3990
4397
  else txBuilder = txBuilder.sendTo(toAddress, amount);
3991
4398
  if (opReturnData) txBuilder = txBuilder.addOpReturn(opReturnData);
@@ -4001,7 +4408,7 @@ class $4d217697e55d958e$export$80793d8292a1630a {
4001
4408
  * @returns Promise resolving to unsigned transaction hex
4002
4409
  */ async buildTokenCreation(name, ticker, decimals, docUrl, docHash) {
4003
4410
  if (!this.watchOnlyWallet) throw new Error('No wallet connected');
4004
- return await this.watchOnlyWallet.newTransaction().onNetwork(this.currentNetwork).token(name, ticker, decimals, docUrl, docHash).populate().build();
4411
+ return await this.watchOnlyWallet.newTransaction().token(name, ticker, decimals, docUrl, docHash).populate().build();
4005
4412
  }
4006
4413
  /**
4007
4414
  * Build an unsigned collection creation transaction
@@ -4012,7 +4419,7 @@ class $4d217697e55d958e$export$80793d8292a1630a {
4012
4419
  * @returns Promise resolving to unsigned transaction hex
4013
4420
  */ async buildCollectionCreation(name, ticker, docUrl, docHash) {
4014
4421
  if (!this.watchOnlyWallet) throw new Error('No wallet connected');
4015
- return await this.watchOnlyWallet.newTransaction().onNetwork(this.currentNetwork).collection(name, ticker, docUrl, docHash).populate().build();
4422
+ return await this.watchOnlyWallet.newTransaction().collection(name, ticker, docUrl, docHash).populate().build();
4016
4423
  }
4017
4424
  /**
4018
4425
  * Build an unsigned NFT creation transaction
@@ -4022,7 +4429,7 @@ class $4d217697e55d958e$export$80793d8292a1630a {
4022
4429
  * @returns Promise resolving to unsigned transaction hex
4023
4430
  */ async buildNFTCreation(parentCollection, zipUrl, zipHash) {
4024
4431
  if (!this.watchOnlyWallet) throw new Error('No wallet connected');
4025
- return await this.watchOnlyWallet.newTransaction().onNetwork(this.currentNetwork).nft(parentCollection, zipUrl, zipHash).populate().build();
4432
+ return await this.watchOnlyWallet.newTransaction().nft(parentCollection, zipUrl, zipHash).populate().build();
4026
4433
  }
4027
4434
  /**
4028
4435
  * Build an unsigned SFT creation transaction
@@ -4033,7 +4440,7 @@ class $4d217697e55d958e$export$80793d8292a1630a {
4033
4440
  * @returns Promise resolving to unsigned transaction hex
4034
4441
  */ async buildSFTCreation(parentCollection, zipUrl, zipHash, quantity) {
4035
4442
  if (!this.watchOnlyWallet) throw new Error('No wallet connected');
4036
- return await this.watchOnlyWallet.newTransaction().onNetwork(this.currentNetwork).sft(parentCollection, zipUrl, zipHash, quantity).populate().build();
4443
+ return await this.watchOnlyWallet.newTransaction().sft(parentCollection, zipUrl, zipHash, quantity).populate().build();
4037
4444
  }
4038
4445
  /**
4039
4446
  * Initialize WatchOnlyWallet with multiple addresses
@@ -4052,7 +4459,7 @@ class $4d217697e55d958e$export$80793d8292a1630a {
4052
4459
  */ async createCustomTransaction(txBuilder, sighashSpec, broadcast = true) {
4053
4460
  if (!this.watchOnlyWallet || !this.connectedWalletAddress) throw new Error('No wallet connected');
4054
4461
  // Create custom transaction using provided builder function
4055
- const builder = this.watchOnlyWallet.newTransaction().onNetwork(this.currentNetwork);
4462
+ const builder = this.watchOnlyWallet.newTransaction();
4056
4463
  const configuredBuilder = txBuilder(builder);
4057
4464
  const unsignedTx = await configuredBuilder.populate().build();
4058
4465
  return await this.provider.signTransaction(this.connectedWalletAddress, unsignedTx, broadcast);