@fuel-ts/account 0.101.1 → 0.101.3

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.
Files changed (41) hide show
  1. package/dist/account.d.ts +45 -14
  2. package/dist/account.d.ts.map +1 -1
  3. package/dist/connectors/fuel-connector.d.ts +8 -0
  4. package/dist/connectors/fuel-connector.d.ts.map +1 -1
  5. package/dist/connectors/types/connector-types.d.ts +4 -2
  6. package/dist/connectors/types/connector-types.d.ts.map +1 -1
  7. package/dist/connectors/types/events.d.ts +6 -1
  8. package/dist/connectors/types/events.d.ts.map +1 -1
  9. package/dist/index.d.ts +1 -0
  10. package/dist/index.d.ts.map +1 -1
  11. package/dist/index.global.js +723 -164
  12. package/dist/index.global.js.map +1 -1
  13. package/dist/index.js +936 -471
  14. package/dist/index.js.map +1 -1
  15. package/dist/index.mjs +856 -394
  16. package/dist/index.mjs.map +1 -1
  17. package/dist/providers/provider.d.ts.map +1 -1
  18. package/dist/providers/transaction-request/script-transaction-request.d.ts +2 -1
  19. package/dist/providers/transaction-request/script-transaction-request.d.ts.map +1 -1
  20. package/dist/providers/transaction-response/transaction-response.d.ts +23 -4
  21. package/dist/providers/transaction-response/transaction-response.d.ts.map +1 -1
  22. package/dist/providers/transaction-summary/call.d.ts +4 -7
  23. package/dist/providers/transaction-summary/call.d.ts.map +1 -1
  24. package/dist/providers/transaction-summary/operations.d.ts +1 -1
  25. package/dist/providers/transaction-summary/operations.d.ts.map +1 -1
  26. package/dist/providers/utils/extract-tx-error.d.ts +10 -1
  27. package/dist/providers/utils/extract-tx-error.d.ts.map +1 -1
  28. package/dist/providers/utils/handle-gql-error-message.d.ts.map +1 -1
  29. package/dist/providers/utils/transaction-response-serialization.d.ts.map +1 -1
  30. package/dist/test-utils/launchNode.d.ts.map +1 -1
  31. package/dist/test-utils.global.js +650 -164
  32. package/dist/test-utils.global.js.map +1 -1
  33. package/dist/test-utils.js +823 -381
  34. package/dist/test-utils.js.map +1 -1
  35. package/dist/test-utils.mjs +751 -308
  36. package/dist/test-utils.mjs.map +1 -1
  37. package/dist/types.d.ts +1 -1
  38. package/dist/types.d.ts.map +1 -1
  39. package/dist/utils/consolidate-coins.d.ts +43 -0
  40. package/dist/utils/consolidate-coins.d.ts.map +1 -0
  41. package/package.json +15 -15
@@ -17288,8 +17288,8 @@
17288
17288
  function getBuiltinVersions() {
17289
17289
  return {
17290
17290
  FUEL_CORE: "0.43.1",
17291
- FORC: "0.68.1",
17292
- FUELS: "0.101.1"
17291
+ FORC: "0.68.7",
17292
+ FUELS: "0.101.3"
17293
17293
  };
17294
17294
  }
17295
17295
  __name(getBuiltinVersions, "getBuiltinVersions");
@@ -17402,6 +17402,7 @@ This unreleased fuel-core build may include features and updates not yet support
17402
17402
  ErrorCode2["CONNECTION_REFUSED"] = "connection-refused";
17403
17403
  ErrorCode2["INVALID_URL"] = "invalid-url";
17404
17404
  ErrorCode2["UNSUPPORTED_FEATURE"] = "unsupported-feature";
17405
+ ErrorCode2["RESPONSE_BODY_EMPTY"] = "response-body-empty";
17405
17406
  ErrorCode2["INVALID_PUBLIC_KEY"] = "invalid-public-key";
17406
17407
  ErrorCode2["WALLET_MANAGER_ERROR"] = "wallet-manager-error";
17407
17408
  ErrorCode2["HD_WALLET_ERROR"] = "hd-wallet-error";
@@ -17420,6 +17421,8 @@ This unreleased fuel-core build may include features and updates not yet support
17420
17421
  ErrorCode2["INVALID_REQUEST"] = "invalid-request";
17421
17422
  ErrorCode2["INVALID_TRANSFER_AMOUNT"] = "invalid-transfer-amount";
17422
17423
  ErrorCode2["INSUFFICIENT_FUNDS_OR_MAX_COINS"] = "not-enough-funds-or-max-coins-reached";
17424
+ ErrorCode2["INSUFFICIENT_FUNDS"] = "not-enough-funds";
17425
+ ErrorCode2["MAX_COINS_REACHED"] = "max-coins-reached";
17423
17426
  ErrorCode2["INVALID_CREDENTIALS"] = "invalid-credentials";
17424
17427
  ErrorCode2["HASHER_LOCKED"] = "hasher-locked";
17425
17428
  ErrorCode2["GAS_PRICE_TOO_LOW"] = "gas-price-too-low";
@@ -17453,6 +17456,7 @@ This unreleased fuel-core build may include features and updates not yet support
17453
17456
  ErrorCode2["INVALID_PASSWORD"] = "invalid-password";
17454
17457
  ErrorCode2["ACCOUNT_REQUIRED"] = "account-required";
17455
17458
  ErrorCode2["UNLOCKED_WALLET_REQUIRED"] = "unlocked-wallet-required";
17459
+ ErrorCode2["UNABLE_TO_CONSOLIDATE_COINS"] = "unable-to-consolidate-coins";
17456
17460
  ErrorCode2["NO_COINS_TO_CONSOLIDATE"] = "no-coins-to-consolidate";
17457
17461
  ErrorCode2["COINS_ASSET_ID_MISMATCH"] = "coins-asset-id-mismatch";
17458
17462
  ErrorCode2["ASSET_NOT_FOUND"] = "asset-not-found";
@@ -17494,7 +17498,7 @@ This unreleased fuel-core build may include features and updates not yet support
17494
17498
  `Unknown error code: ${error2.code}. Accepted codes: ${enumValues.join(", ")}.`
17495
17499
  );
17496
17500
  }
17497
- return new _FuelError(error2.code, error2.message);
17501
+ return new _FuelError(error2.code, error2.message, error2.metadata, error2.rawError);
17498
17502
  }
17499
17503
  code;
17500
17504
  constructor(code, message, metadata = {}, rawError = null) {
@@ -20919,7 +20923,8 @@ If you are attempting to transform a hex value, please make sure it is being pas
20919
20923
  functions,
20920
20924
  loggedTypes,
20921
20925
  messagesTypes: abi.messagesTypes,
20922
- configurables
20926
+ configurables,
20927
+ errorCodes: abi.errorCodes
20923
20928
  };
20924
20929
  return transpiled;
20925
20930
  }
@@ -23342,8 +23347,9 @@ If you are attempting to transform a hex value, please make sure it is being pas
23342
23347
  "--consensus-key",
23343
23348
  "--db-type",
23344
23349
  "--poa-instant",
23350
+ "--native-executor-version",
23345
23351
  "--min-gas-price",
23346
- "--native-executor-version"
23352
+ "--starting-gas-price"
23347
23353
  ]);
23348
23354
  const snapshotDir = getFlagValueFromArgs(args, "--snapshot");
23349
23355
  const consensusKey = getFlagValueFromArgs(args, "--consensus-key") || defaultConsensusKey;
@@ -23567,6 +23573,11 @@ If you are attempting to transform a hex value, please make sure it is being pas
23567
23573
  }
23568
23574
  __name(_curry3, "_curry3");
23569
23575
 
23576
+ // ../../node_modules/.pnpm/ramda@0.30.1/node_modules/ramda/es/internal/_isArray.js
23577
+ var isArray_default = Array.isArray || /* @__PURE__ */ __name(function _isArray(val) {
23578
+ return val != null && val.length >= 0 && Object.prototype.toString.call(val) === "[object Array]";
23579
+ }, "_isArray");
23580
+
23570
23581
  // ../../node_modules/.pnpm/ramda@0.30.1/node_modules/ramda/es/internal/_has.js
23571
23582
  function _has(prop, obj) {
23572
23583
  return Object.prototype.hasOwnProperty.call(obj, prop);
@@ -23697,6 +23708,25 @@ If you are attempting to transform a hex value, please make sure it is being pas
23697
23708
  }, "clone"));
23698
23709
  var clone_default = clone;
23699
23710
 
23711
+ // ../../node_modules/.pnpm/ramda@0.30.1/node_modules/ramda/es/internal/_checkForMethod.js
23712
+ function _checkForMethod(methodname, fn) {
23713
+ return function() {
23714
+ var length = arguments.length;
23715
+ if (length === 0) {
23716
+ return fn();
23717
+ }
23718
+ var obj = arguments[length - 1];
23719
+ return isArray_default(obj) || typeof obj[methodname] !== "function" ? fn.apply(this, arguments) : obj[methodname].apply(obj, Array.prototype.slice.call(arguments, 0, length - 1));
23720
+ };
23721
+ }
23722
+ __name(_checkForMethod, "_checkForMethod");
23723
+
23724
+ // ../../node_modules/.pnpm/ramda@0.30.1/node_modules/ramda/es/slice.js
23725
+ var slice = /* @__PURE__ */ _curry3(/* @__PURE__ */ _checkForMethod("slice", /* @__PURE__ */ __name(function slice2(fromIndex, toIndex, list) {
23726
+ return Array.prototype.slice.call(list, fromIndex, toIndex);
23727
+ }, "slice")));
23728
+ var slice_default = slice;
23729
+
23700
23730
  // ../../node_modules/.pnpm/ramda@0.30.1/node_modules/ramda/es/mergeWithKey.js
23701
23731
  var mergeWithKey = /* @__PURE__ */ _curry3(/* @__PURE__ */ __name(function mergeWithKey2(fn, l, r) {
23702
23732
  var result = {};
@@ -23737,6 +23767,20 @@ If you are attempting to transform a hex value, please make sure it is being pas
23737
23767
  }, "mergeDeepRight"));
23738
23768
  var mergeDeepRight_default = mergeDeepRight;
23739
23769
 
23770
+ // ../../node_modules/.pnpm/ramda@0.30.1/node_modules/ramda/es/splitEvery.js
23771
+ var splitEvery = /* @__PURE__ */ _curry2(/* @__PURE__ */ __name(function splitEvery2(n, list) {
23772
+ if (n <= 0) {
23773
+ throw new Error("First argument to splitEvery must be a positive integer");
23774
+ }
23775
+ var result = [];
23776
+ var idx = 0;
23777
+ while (idx < list.length) {
23778
+ result.push(slice_default(idx, idx += n, list));
23779
+ }
23780
+ return result;
23781
+ }, "splitEvery"));
23782
+ var splitEvery_default = splitEvery;
23783
+
23740
23784
  // src/providers/coin-quantity.ts
23741
23785
  var coinQuantityfy = /* @__PURE__ */ __name((coinQuantityLike) => {
23742
23786
  let assetId;
@@ -30393,8 +30437,11 @@ ${DryRunSuccessAssembleTxFragmentDoc}`;
30393
30437
  }, "setAndValidateGasAndFeeForAssembledTx");
30394
30438
 
30395
30439
  // src/providers/utils/handle-gql-error-message.ts
30440
+ var ASSET_ID_REGEX = /[0-9a-fA-F]{32,64}/g;
30396
30441
  var gqlErrorMessage = {
30397
30442
  RPC_CONSISTENCY: /The required fuel block height is higher than the current block height. Required: \d+, Current: \d+/,
30443
+ INSUFFICIENT_FUNDS: /the target cannot be met due to insufficient coins available for [0-9a-fA-F]{32,64}. Collected: \d+/,
30444
+ MAX_COINS_REACHED: /the target for [0-9a-fA-F]{32,64} cannot be met due to exceeding the \d+ coin limit. Collected: \d+./,
30398
30445
  NOT_ENOUGH_COINS_MAX_COINS: /the target cannot be met due to no coins available or exceeding the \d+ coin limit./,
30399
30446
  ASSET_NOT_FOUND: /resource was not found in table/,
30400
30447
  MULTIPLE_CHANGE_POLICIES: /The asset ([a-fA-F0-9]{64}) has multiple change policies/,
@@ -30410,6 +30457,46 @@ ${DryRunSuccessAssembleTxFragmentDoc}`;
30410
30457
  error2
30411
30458
  );
30412
30459
  }
30460
+ if (gqlErrorMessage.MAX_COINS_REACHED.test(error2.message)) {
30461
+ const matches = error2.message.match(ASSET_ID_REGEX);
30462
+ const assetId = matches ? `0x${matches[0]}` : null;
30463
+ const owner = matches ? `0x${matches[1]}` : null;
30464
+ let suffix = "";
30465
+ if (assetId) {
30466
+ suffix += `
30467
+ Asset ID: '${assetId}'.`;
30468
+ }
30469
+ if (owner) {
30470
+ suffix += `
30471
+ Owner: '${owner}'.`;
30472
+ }
30473
+ return new FuelError(
30474
+ ErrorCode.MAX_COINS_REACHED,
30475
+ `You have too many small value coins - consider combining UTXOs.${suffix}`,
30476
+ { assetId, owner },
30477
+ error2
30478
+ );
30479
+ }
30480
+ if (gqlErrorMessage.INSUFFICIENT_FUNDS.test(error2.message)) {
30481
+ const matches = error2.message.match(ASSET_ID_REGEX);
30482
+ const assetId = matches ? `0x${matches[0]}` : null;
30483
+ const owner = matches ? `0x${matches[1]}` : null;
30484
+ let suffix = "";
30485
+ if (assetId) {
30486
+ suffix += `
30487
+ Asset ID: '${assetId}'.`;
30488
+ }
30489
+ if (owner) {
30490
+ suffix += `
30491
+ Owner: '${owner}'.`;
30492
+ }
30493
+ return new FuelError(
30494
+ ErrorCode.INSUFFICIENT_FUNDS,
30495
+ `Insufficient funds.${suffix}`,
30496
+ { assetId, owner },
30497
+ error2
30498
+ );
30499
+ }
30413
30500
  if (gqlErrorMessage.MULTIPLE_CHANGE_POLICIES.test(error2.message)) {
30414
30501
  const match = error2.message.match(/asset ([a-fA-F0-9]{64})/);
30415
30502
  const assetId = match?.[1] || "";
@@ -30719,6 +30806,7 @@ ${incompatibleNodeVersionMessage}`,
30719
30806
  var FAILED_ASSERT_EQ_SIGNAL = "0xffffffffffff0003";
30720
30807
  var FAILED_ASSERT_SIGNAL = "0xffffffffffff0004";
30721
30808
  var FAILED_ASSERT_NE_SIGNAL = "0xffffffffffff0005";
30809
+ var REVERT_WITH_LOG_SIGNAL = "0xffffffffffff0006";
30722
30810
  var PANIC_REASONS = [
30723
30811
  "ArithmeticError",
30724
30812
  "ArithmeticOverflow",
@@ -30787,6 +30875,14 @@ ${incompatibleNodeVersionMessage}`,
30787
30875
  "WitnessNotFound"
30788
30876
  ];
30789
30877
  var PANIC_DOC_URL = "https://docs.rs/fuel-asm/latest/fuel_asm/enum.PanicReason.html";
30878
+ var SwaySignalErrors = {
30879
+ FAILED_REQUIRE_SIGNAL,
30880
+ FAILED_TRANSFER_TO_ADDRESS_SIGNAL,
30881
+ FAILED_ASSERT_EQ_SIGNAL,
30882
+ FAILED_ASSERT_SIGNAL,
30883
+ FAILED_ASSERT_NE_SIGNAL,
30884
+ REVERT_WITH_LOG_SIGNAL
30885
+ };
30790
30886
 
30791
30887
  // src/providers/utils/serialization.ts
30792
30888
  var deserializeChain = /* @__PURE__ */ __name((chain) => {
@@ -31474,58 +31570,98 @@ ${PANIC_DOC_URL}#variant.${statusReason}`;
31474
31570
  });
31475
31571
  }, "assemblePanicError");
31476
31572
  var stringify = /* @__PURE__ */ __name((obj) => JSON.stringify(obj, null, 2), "stringify");
31477
- var assembleRevertError = /* @__PURE__ */ __name((receipts, logs, metadata) => {
31573
+ var assembleSignalErrorMessage = /* @__PURE__ */ __name((reasonHex, logs, metadata) => {
31478
31574
  let errorMessage = "The transaction reverted with an unknown reason.";
31479
- const revertReceipt = receipts.find(({ type: type3 }) => type3 === ReceiptType.Revert);
31480
31575
  let reason = "";
31481
- if (revertReceipt) {
31482
- const reasonHex = bn(revertReceipt.val).toHex();
31483
- const lastLog = logs[logs.length - 1];
31484
- const lastButOneLog = logs[logs.length - 2];
31485
- switch (reasonHex) {
31486
- case FAILED_REQUIRE_SIGNAL: {
31487
- reason = "require";
31488
- errorMessage = `The transaction reverted because a "require" statement has thrown ${logs.length ? stringify(lastLog) : "an error."}.`;
31489
- break;
31490
- }
31491
- case FAILED_ASSERT_EQ_SIGNAL: {
31492
- const suffix = logs.length >= 2 ? ` comparing ${stringify(lastLog)} and ${stringify(lastButOneLog)}.` : ".";
31493
- reason = "assert_eq";
31494
- errorMessage = `The transaction reverted because of an "assert_eq" statement${suffix}`;
31495
- break;
31496
- }
31497
- case FAILED_ASSERT_NE_SIGNAL: {
31498
- const suffix = logs.length >= 2 ? ` comparing ${stringify(lastButOneLog)} and ${stringify(lastLog)}.` : ".";
31499
- reason = "assert_ne";
31500
- errorMessage = `The transaction reverted because of an "assert_ne" statement${suffix}`;
31501
- break;
31502
- }
31503
- case FAILED_ASSERT_SIGNAL:
31504
- reason = "assert";
31505
- errorMessage = `The transaction reverted because an "assert" statement failed to evaluate to true.`;
31506
- break;
31507
- case FAILED_TRANSFER_TO_ADDRESS_SIGNAL:
31508
- reason = "MissingOutputVariable";
31509
- errorMessage = `The transaction reverted because it's missing an "OutputVariable".`;
31510
- break;
31511
- default:
31512
- throw new FuelError(
31513
- ErrorCode.UNKNOWN,
31514
- `The transaction reverted with an unknown reason: ${revertReceipt.val}`,
31515
- {
31516
- ...metadata,
31517
- reason: "unknown"
31518
- }
31519
- );
31576
+ const lastLog = logs[logs.length - 1];
31577
+ const lastButOneLog = logs[logs.length - 2];
31578
+ switch (reasonHex) {
31579
+ case FAILED_REQUIRE_SIGNAL: {
31580
+ reason = "require";
31581
+ errorMessage = `The transaction reverted because a "require" statement has thrown ${logs.length ? stringify(lastLog) : "an error."}.`;
31582
+ break;
31583
+ }
31584
+ case FAILED_ASSERT_EQ_SIGNAL: {
31585
+ const suffix = logs.length >= 2 ? ` comparing ${stringify(lastLog)} and ${stringify(lastButOneLog)}.` : ".";
31586
+ reason = "assert_eq";
31587
+ errorMessage = `The transaction reverted because of an "assert_eq" statement${suffix}`;
31588
+ break;
31520
31589
  }
31590
+ case FAILED_ASSERT_NE_SIGNAL: {
31591
+ const suffix = logs.length >= 2 ? ` comparing ${stringify(lastButOneLog)} and ${stringify(lastLog)}.` : ".";
31592
+ reason = "assert_ne";
31593
+ errorMessage = `The transaction reverted because of an "assert_ne" statement${suffix}`;
31594
+ break;
31595
+ }
31596
+ case FAILED_ASSERT_SIGNAL:
31597
+ reason = "assert";
31598
+ errorMessage = `The transaction reverted because an "assert" statement failed to evaluate to true.`;
31599
+ break;
31600
+ case FAILED_TRANSFER_TO_ADDRESS_SIGNAL:
31601
+ reason = "MissingOutputVariable";
31602
+ errorMessage = `The transaction reverted because it's missing an "OutputVariable".`;
31603
+ break;
31604
+ default:
31605
+ reason = `revert_with_log`;
31606
+ errorMessage = `The transaction reverted because a "revert_with_log" statement has thrown ${logs.length ? stringify(lastLog) : "an error."}.`;
31607
+ break;
31521
31608
  }
31522
31609
  return new FuelError(ErrorCode.SCRIPT_REVERTED, errorMessage, {
31523
31610
  ...metadata,
31524
31611
  reason
31525
31612
  });
31613
+ }, "assembleSignalErrorMessage");
31614
+ function buildAbiErrorMessage(abiError, logs, metadata, reason) {
31615
+ const { pos, msg } = abiError;
31616
+ let errorMessage = "";
31617
+ const positionMessage = pos ? `
31618
+
31619
+ This error originated at ${JSON.stringify(pos, null, 2)}` : "";
31620
+ if (msg) {
31621
+ errorMessage = `A sway "panic" expression was invoked with the message: "${msg}".${positionMessage}`;
31622
+ } else {
31623
+ const value = logs[logs.length - 1];
31624
+ errorMessage = `A sway "panic" expression was invoked with the value: ${JSON.stringify(value)}.${positionMessage}`;
31625
+ }
31626
+ return new FuelError(ErrorCode.SCRIPT_REVERTED, errorMessage, {
31627
+ ...metadata,
31628
+ abiError,
31629
+ reason
31630
+ });
31631
+ }
31632
+ __name(buildAbiErrorMessage, "buildAbiErrorMessage");
31633
+ function findErrorInAbis(statusReason, abis = []) {
31634
+ for (const abi of abis) {
31635
+ if (abi.errorCodes?.[statusReason]) {
31636
+ return abi.errorCodes[statusReason];
31637
+ }
31638
+ }
31639
+ return void 0;
31640
+ }
31641
+ __name(findErrorInAbis, "findErrorInAbis");
31642
+ var assembleRevertError = /* @__PURE__ */ __name((_receipts, logs, metadata, statusReason, abis) => {
31643
+ const match = statusReason.match(/Revert\((\d+)\)/);
31644
+ const reason = match?.[1] ?? statusReason;
31645
+ const reasonHex = bn(reason).toHex();
31646
+ if (Object.values(SwaySignalErrors).includes(reasonHex)) {
31647
+ return assembleSignalErrorMessage(reasonHex, logs, metadata);
31648
+ }
31649
+ let abiError;
31650
+ if (abis) {
31651
+ const abisArr = [abis.main, ...Object.values(abis.otherContractsAbis)];
31652
+ abiError = findErrorInAbis(reason, abisArr);
31653
+ }
31654
+ if (abiError) {
31655
+ return buildAbiErrorMessage(abiError, logs, metadata, reason);
31656
+ }
31657
+ const errorMessage = `The transaction reverted with reason: ${reason}.`;
31658
+ return new FuelError(ErrorCode.SCRIPT_REVERTED, errorMessage, {
31659
+ ...metadata,
31660
+ reason
31661
+ });
31526
31662
  }, "assembleRevertError");
31527
31663
  var extractTxError = /* @__PURE__ */ __name((params) => {
31528
- const { receipts, statusReason, logs, groupedLogs } = params;
31664
+ const { receipts, statusReason, logs, groupedLogs, abis } = params;
31529
31665
  const isPanic = receipts.some(({ type: type3 }) => type3 === ReceiptType.Panic);
31530
31666
  const isRevert = receipts.some(({ type: type3 }) => type3 === ReceiptType.Revert);
31531
31667
  const metadata = {
@@ -31539,7 +31675,7 @@ ${PANIC_DOC_URL}#variant.${statusReason}`;
31539
31675
  if (isPanic) {
31540
31676
  return assemblePanicError(statusReason, metadata);
31541
31677
  }
31542
- return assembleRevertError(receipts, logs, metadata);
31678
+ return assembleRevertError(receipts, logs, metadata, statusReason, abis);
31543
31679
  }, "extractTxError");
31544
31680
 
31545
31681
  // src/providers/utils/merge-quantities.ts
@@ -32480,11 +32616,15 @@ ${PANIC_DOC_URL}#variant.${statusReason}`;
32480
32616
  * @deprecated Use `provider.assembleTx` instead.
32481
32617
  * Check the migration guide https://docs.fuel.network/guide/assembling-transactions/migration-guide.html for more information.
32482
32618
  */
32483
- async estimateAndFund(account, { signatureCallback, quantities = [] } = {}) {
32619
+ async estimateAndFund(account, {
32620
+ signatureCallback,
32621
+ quantities = [],
32622
+ skipAutoConsolidation
32623
+ } = {}) {
32484
32624
  const txCost = await account.getTransactionCost(this, { signatureCallback, quantities });
32485
32625
  this.maxFee = txCost.maxFee;
32486
32626
  this.gasLimit = txCost.gasUsed;
32487
- await account.fund(this, txCost);
32627
+ await account.fund(this, txCost, { skipAutoConsolidation });
32488
32628
  return this;
32489
32629
  }
32490
32630
  /**
@@ -33099,6 +33239,42 @@ ${PANIC_DOC_URL}#variant.${statusReason}`;
33099
33239
  return maxFee;
33100
33240
  }, "calculateTXFeeForSummary");
33101
33241
 
33242
+ // src/providers/transaction-summary/call.ts
33243
+ var getFunctionCall = /* @__PURE__ */ __name(({
33244
+ abi,
33245
+ receipt,
33246
+ offset,
33247
+ scriptData
33248
+ }) => {
33249
+ const [functionSelector, argumentsOffset] = new StdStringCoder().decode(scriptData, offset);
33250
+ const abiInterface = new Interface(abi);
33251
+ const functionFragment = abiInterface.getFunction(functionSelector);
33252
+ const inputs = functionFragment.jsonFn.inputs;
33253
+ let argumentsProvided;
33254
+ if (inputs.length) {
33255
+ const functionArgsBytes = scriptData.slice(argumentsOffset);
33256
+ const decodedArguments = functionFragment.decodeArguments(functionArgsBytes);
33257
+ argumentsProvided = inputs.reduce((prev, input, index) => {
33258
+ const value = decodedArguments?.[index];
33259
+ const name = input.name;
33260
+ if (name) {
33261
+ return {
33262
+ ...prev,
33263
+ // reparse to remove bn
33264
+ [name]: JSON.parse(JSON.stringify(value))
33265
+ };
33266
+ }
33267
+ return prev;
33268
+ }, {});
33269
+ }
33270
+ return {
33271
+ functionSignature: functionFragment.signature,
33272
+ functionName: functionFragment.name,
33273
+ argumentsProvided,
33274
+ ...receipt.amount?.isZero() ? {} : { amount: receipt.amount, assetId: receipt.assetId }
33275
+ };
33276
+ }, "getFunctionCall");
33277
+
33102
33278
  // src/providers/transaction-summary/input.ts
33103
33279
  function getInputsByTypes(inputs, types) {
33104
33280
  return inputs.filter((i) => types.includes(i.type));
@@ -33377,12 +33553,45 @@ ${PANIC_DOC_URL}#variant.${statusReason}`;
33377
33553
  return withdrawFromFuelOperations;
33378
33554
  }
33379
33555
  __name(getWithdrawFromFuelOperations, "getWithdrawFromFuelOperations");
33380
- function getContractCalls(contractInput, abiMap, _receipt, _rawPayload, _maxInputs) {
33556
+ function findBytesSegmentIndex(whole, segment) {
33557
+ for (let i = 0; i <= whole.length - segment.length; i++) {
33558
+ let match = true;
33559
+ for (let j = 0; j < segment.length; j++) {
33560
+ if (whole[i + j] !== segment[j]) {
33561
+ match = false;
33562
+ break;
33563
+ }
33564
+ }
33565
+ if (match) {
33566
+ return i;
33567
+ }
33568
+ }
33569
+ return -1;
33570
+ }
33571
+ __name(findBytesSegmentIndex, "findBytesSegmentIndex");
33572
+ function getContractCalls(contractInput, abiMap, receipt, scriptData) {
33573
+ const calls = [];
33381
33574
  const abi = abiMap?.[contractInput.contractID];
33382
- if (!abi) {
33383
- return [];
33575
+ if (!abi || !scriptData) {
33576
+ return calls;
33577
+ }
33578
+ const bytesSegment = concat([
33579
+ arrayify(receipt.to),
33580
+ // Contract ID (32 bytes)
33581
+ toBytes(receipt.param1.toHex(), 8),
33582
+ // Function selector offset (8 bytes)
33583
+ toBytes(receipt.param2.toHex(), 8)
33584
+ // Function args offset (8 bytes)
33585
+ ]);
33586
+ const segmentIndex = findBytesSegmentIndex(scriptData, bytesSegment);
33587
+ const canDecodeFunctionCall = segmentIndex !== -1;
33588
+ if (!canDecodeFunctionCall) {
33589
+ return calls;
33384
33590
  }
33385
- return [];
33591
+ const offset = segmentIndex + bytesSegment.length;
33592
+ const call = getFunctionCall({ abi, receipt, offset, scriptData });
33593
+ calls.push(call);
33594
+ return calls;
33386
33595
  }
33387
33596
  __name(getContractCalls, "getContractCalls");
33388
33597
  function getAssetsSent(receipt) {
@@ -33394,14 +33603,14 @@ ${PANIC_DOC_URL}#variant.${statusReason}`;
33394
33603
  ];
33395
33604
  }
33396
33605
  __name(getAssetsSent, "getAssetsSent");
33397
- function processCallReceipt(receipt, contractInput, inputs, abiMap, rawPayload, maxInputs, baseAssetId) {
33606
+ function processCallReceipt(receipt, contractInput, inputs, abiMap, scriptData, baseAssetId) {
33398
33607
  const assetId = receipt.assetId === ZeroBytes32 ? baseAssetId : receipt.assetId;
33399
33608
  const input = getInputFromAssetId(inputs, assetId, assetId === baseAssetId);
33400
33609
  if (!input) {
33401
33610
  return [];
33402
33611
  }
33403
33612
  const inputAddress = getInputAccountAddress(input);
33404
- const calls = getContractCalls(contractInput, abiMap, receipt, rawPayload, maxInputs);
33613
+ const calls = getContractCalls(contractInput, abiMap, receipt, scriptData);
33405
33614
  return [
33406
33615
  {
33407
33616
  name: "Contract call" /* contractCall */,
@@ -33426,7 +33635,6 @@ ${PANIC_DOC_URL}#variant.${statusReason}`;
33426
33635
  receipts,
33427
33636
  abiMap,
33428
33637
  rawPayload,
33429
- maxInputs,
33430
33638
  baseAssetId
33431
33639
  }) {
33432
33640
  const contractCallReceipts = getReceiptsCall(receipts);
@@ -33436,16 +33644,15 @@ ${PANIC_DOC_URL}#variant.${statusReason}`;
33436
33644
  if (!contractInput) {
33437
33645
  return [];
33438
33646
  }
33647
+ let scriptData;
33648
+ if (rawPayload) {
33649
+ const [transaction] = new TransactionCoder().decode(arrayify(rawPayload), 0);
33650
+ if (transaction.type === TransactionType.Script) {
33651
+ scriptData = arrayify(transaction.scriptData);
33652
+ }
33653
+ }
33439
33654
  return contractCallReceipts.filter((receipt) => receipt.to === contractInput.contractID).flatMap(
33440
- (receipt) => processCallReceipt(
33441
- receipt,
33442
- contractInput,
33443
- inputs,
33444
- abiMap,
33445
- rawPayload,
33446
- maxInputs,
33447
- baseAssetId
33448
- )
33655
+ (receipt) => processCallReceipt(receipt, contractInput, inputs, abiMap, scriptData, baseAssetId)
33449
33656
  );
33450
33657
  });
33451
33658
  }
@@ -33937,25 +34144,6 @@ ${PANIC_DOC_URL}#variant.${statusReason}`;
33937
34144
 
33938
34145
  // src/providers/transaction-response/transaction-response.ts
33939
34146
  var TransactionResponse = class _TransactionResponse {
33940
- /**
33941
- * Constructor for `TransactionResponse`.
33942
- *
33943
- * @param tx - The transaction ID or TransactionRequest.
33944
- * @param provider - The provider.
33945
- */
33946
- constructor(tx, provider, chainId, abis, submitTxSubscription) {
33947
- this.submitTxSubscription = submitTxSubscription;
33948
- if (typeof tx === "string") {
33949
- this.id = tx;
33950
- } else {
33951
- this.id = tx.getTransactionId(chainId);
33952
- this.request = tx;
33953
- }
33954
- this.provider = provider;
33955
- this.abis = abis;
33956
- this.waitForResult = this.waitForResult.bind(this);
33957
- this.waitForPreConfirmation = this.waitForPreConfirmation.bind(this);
33958
- }
33959
34147
  static {
33960
34148
  __name(this, "TransactionResponse");
33961
34149
  }
@@ -33970,9 +34158,42 @@ ${PANIC_DOC_URL}#variant.${statusReason}`;
33970
34158
  request;
33971
34159
  status;
33972
34160
  abis;
34161
+ submitTxSubscription;
33973
34162
  preConfirmationStatus;
33974
34163
  waitingForStreamData = false;
33975
34164
  statusResolvers = /* @__PURE__ */ new Map();
34165
+ /**
34166
+ * Constructor for `TransactionResponse`.
34167
+ */
34168
+ constructor(constructorParams, provider, chainId, abis, submitTxSubscription) {
34169
+ let tx;
34170
+ let _provider;
34171
+ let _chainId;
34172
+ let _abis;
34173
+ if (typeof constructorParams === "object" && "provider" in constructorParams && arguments.length === 1) {
34174
+ tx = constructorParams.transactionRequestOrId;
34175
+ _provider = constructorParams.provider;
34176
+ _chainId = constructorParams.chainId;
34177
+ _abis = constructorParams.abis;
34178
+ this.submitTxSubscription = constructorParams.submitAndAwaitSubscription;
34179
+ } else {
34180
+ tx = constructorParams;
34181
+ _provider = provider;
34182
+ _chainId = chainId;
34183
+ _abis = abis;
34184
+ this.submitTxSubscription = submitTxSubscription;
34185
+ }
34186
+ if (typeof tx === "string") {
34187
+ this.id = tx;
34188
+ } else {
34189
+ this.id = tx.getTransactionId(_chainId);
34190
+ this.request = tx;
34191
+ }
34192
+ this.provider = _provider;
34193
+ this.abis = _abis;
34194
+ this.waitForResult = this.waitForResult.bind(this);
34195
+ this.waitForPreConfirmation = this.waitForPreConfirmation.bind(this);
34196
+ }
33976
34197
  /**
33977
34198
  * Async constructor for `TransactionResponse`. This method can be used to create
33978
34199
  * an instance of `TransactionResponse` and wait for the transaction to be fetched
@@ -34209,6 +34430,7 @@ ${PANIC_DOC_URL}#variant.${statusReason}`;
34209
34430
  ...transactionSummary
34210
34431
  };
34211
34432
  let { logs, groupedLogs } = { logs: [], groupedLogs: {} };
34433
+ let abis;
34212
34434
  if (this.abis) {
34213
34435
  ({ logs, groupedLogs } = getAllDecodedLogs({
34214
34436
  receipts: transactionSummary.receipts,
@@ -34217,6 +34439,7 @@ ${PANIC_DOC_URL}#variant.${statusReason}`;
34217
34439
  }));
34218
34440
  transactionResult.logs = logs;
34219
34441
  transactionResult.groupedLogs = groupedLogs;
34442
+ abis = this.abis;
34220
34443
  }
34221
34444
  const { receipts } = transactionResult;
34222
34445
  const status = this.getTransactionStatus();
@@ -34226,7 +34449,8 @@ ${PANIC_DOC_URL}#variant.${statusReason}`;
34226
34449
  receipts,
34227
34450
  statusReason: reason,
34228
34451
  logs,
34229
- groupedLogs
34452
+ groupedLogs,
34453
+ abis
34230
34454
  });
34231
34455
  }
34232
34456
  return transactionResult;
@@ -34479,7 +34703,15 @@ ${PANIC_DOC_URL}#variant.${statusReason}`;
34479
34703
  if (_Provider.ENABLE_RPC_CONSISTENCY && _Provider.hasWriteOperationHappened(url)) {
34480
34704
  _Provider.applyBlockHeight(fullRequest, url);
34481
34705
  }
34482
- return _Provider.fetchAndProcessBlockHeight(url, fullRequest, options);
34706
+ const response = await _Provider.fetchAndProcessBlockHeight(url, fullRequest, options);
34707
+ if (response.body === null) {
34708
+ throw new FuelError(
34709
+ ErrorCode.RESPONSE_BODY_EMPTY,
34710
+ "The response from the server is missing the body",
34711
+ { timestamp: (/* @__PURE__ */ new Date()).toISOString(), request, response }
34712
+ );
34713
+ }
34714
+ return response;
34483
34715
  }, retryOptions);
34484
34716
  }
34485
34717
  static applyBlockHeight(request, url) {
@@ -34502,13 +34734,15 @@ ${PANIC_DOC_URL}#variant.${statusReason}`;
34502
34734
  baseDelay: 500
34503
34735
  };
34504
34736
  for (let retriesLeft = retryOptions.maxRetries; retriesLeft > 0; --retriesLeft) {
34505
- const { extensions } = await parseGraphqlResponse({
34506
- response,
34507
- isSubscription: url.endsWith("-sub")
34508
- });
34509
- _Provider.setCurrentBlockHeight(url, extensions?.current_fuel_block_height);
34510
- if (!extensions?.fuel_block_height_precondition_failed) {
34511
- break;
34737
+ if (response.body) {
34738
+ const { extensions } = await parseGraphqlResponse({
34739
+ response,
34740
+ isSubscription: url.endsWith("-sub")
34741
+ });
34742
+ _Provider.setCurrentBlockHeight(url, extensions?.current_fuel_block_height);
34743
+ if (!extensions?.fuel_block_height_precondition_failed) {
34744
+ break;
34745
+ }
34512
34746
  }
34513
34747
  const retryAttempt = retryOptions.maxRetries - retriesLeft + 1;
34514
34748
  const sleepTime = getWaitDelay(retryOptions, retryAttempt);
@@ -34931,7 +35165,13 @@ ${PANIC_DOC_URL}#variant.${statusReason}`;
34931
35165
  transactionRequest.getTransactionId(await this.getChainId())
34932
35166
  );
34933
35167
  const chainId = await this.getChainId();
34934
- return new TransactionResponse(transactionRequest, this, chainId, abis, subscription);
35168
+ return new TransactionResponse({
35169
+ transactionRequestOrId: transactionRequest,
35170
+ provider: this,
35171
+ chainId,
35172
+ abis,
35173
+ submitAndAwaitSubscription: subscription
35174
+ });
34935
35175
  }
34936
35176
  /**
34937
35177
  * Executes a transaction without actually submitting it to the chain.
@@ -36026,7 +36266,11 @@ ${PANIC_DOC_URL}#variant.${statusReason}`;
36026
36266
  */
36027
36267
  async getTransactionResponse(transactionId) {
36028
36268
  const chainId = await this.getChainId();
36029
- return new TransactionResponse(transactionId, this, chainId);
36269
+ return new TransactionResponse({
36270
+ transactionRequestOrId: transactionId,
36271
+ provider: this,
36272
+ chainId
36273
+ });
36030
36274
  }
36031
36275
  /**
36032
36276
  * Returns Message for given nonce.
@@ -36077,18 +36321,21 @@ ${PANIC_DOC_URL}#variant.${statusReason}`;
36077
36321
  extractDryRunError(transactionRequest, receipts, reason) {
36078
36322
  let logs = [];
36079
36323
  let groupedLogs = {};
36324
+ let abis;
36080
36325
  if (transactionRequest.type === TransactionType.Script && transactionRequest.abis) {
36081
36326
  ({ logs, groupedLogs } = getAllDecodedLogs({
36082
36327
  receipts,
36083
36328
  mainAbi: transactionRequest.abis.main,
36084
36329
  externalAbis: transactionRequest.abis.otherContractsAbis
36085
36330
  }));
36331
+ abis = transactionRequest.abis;
36086
36332
  }
36087
36333
  return extractTxError({
36088
36334
  logs,
36089
36335
  groupedLogs,
36090
36336
  receipts,
36091
- statusReason: reason
36337
+ statusReason: reason,
36338
+ abis
36092
36339
  });
36093
36340
  }
36094
36341
  /**
@@ -36186,6 +36433,149 @@ ${PANIC_DOC_URL}#variant.${statusReason}`;
36186
36433
  }
36187
36434
  };
36188
36435
 
36436
+ // src/utils/consolidate-coins.ts
36437
+ var CONSOLIDATABLE_ERROR_CODES = [ErrorCode.MAX_COINS_REACHED];
36438
+ var consolidateCoinsIfRequired = /* @__PURE__ */ __name(async (opts) => {
36439
+ const { error: errorUnknown, account, skipAutoConsolidation = false } = opts;
36440
+ if (skipAutoConsolidation) {
36441
+ return false;
36442
+ }
36443
+ const error2 = FuelError.parse(errorUnknown);
36444
+ if (CONSOLIDATABLE_ERROR_CODES.includes(error2.code)) {
36445
+ const { assetId, owner } = error2.metadata;
36446
+ return account.startConsolidation({
36447
+ owner,
36448
+ assetId
36449
+ });
36450
+ }
36451
+ return false;
36452
+ }, "consolidateCoinsIfRequired");
36453
+ var getAllCoins = /* @__PURE__ */ __name(async (account, assetId) => {
36454
+ const all = [];
36455
+ let hasNextPage = true;
36456
+ let after;
36457
+ while (hasNextPage) {
36458
+ const { coins, pageInfo } = await account.getCoins(assetId, { after });
36459
+ all.push(...coins);
36460
+ after = coins.pop()?.id;
36461
+ hasNextPage = pageInfo.hasNextPage;
36462
+ }
36463
+ return { coins: all };
36464
+ }, "getAllCoins");
36465
+ var sortCoins = /* @__PURE__ */ __name(({ coins }) => coins.sort((a, b) => b.amount.cmp(a.amount)), "sortCoins");
36466
+ var createOuputCoin = /* @__PURE__ */ __name((opts) => {
36467
+ const { transactionId, outputs, baseAssetId } = opts;
36468
+ const outputChangeIndex = outputs.findIndex(
36469
+ (output) => output.type === OutputType.Change && output.assetId === baseAssetId
36470
+ );
36471
+ if (outputChangeIndex === -1) {
36472
+ throw new FuelError(ErrorCode.UNKNOWN, "No change output found");
36473
+ }
36474
+ const outputCoin = outputs[outputChangeIndex];
36475
+ const outputIndexPadded = Number(outputChangeIndex).toString().padStart(4, "0");
36476
+ return {
36477
+ id: `${transactionId}${outputIndexPadded}`,
36478
+ assetId: outputCoin.assetId,
36479
+ amount: outputCoin.amount,
36480
+ owner: new Address(outputCoin.to),
36481
+ blockCreated: bn(0),
36482
+ txCreatedIdx: bn(0)
36483
+ };
36484
+ }, "createOuputCoin");
36485
+ var consolidateCoins = /* @__PURE__ */ __name(async ({
36486
+ account,
36487
+ assetId
36488
+ }) => {
36489
+ const chainInfo = await account.provider.getChain();
36490
+ const chainId = chainInfo.consensusParameters.chainId.toNumber();
36491
+ const gasPrice = await account.provider.estimateGasPrice(10);
36492
+ const maxInputs = chainInfo.consensusParameters.txParameters.maxInputs.toNumber();
36493
+ const baseAssetId = await account.provider.getBaseAssetId();
36494
+ const isBaseAsset = assetId === baseAssetId;
36495
+ const batchSize = maxInputs;
36496
+ const numberOfFundingCoins = maxInputs;
36497
+ let funding = [];
36498
+ let dust = [];
36499
+ if (isBaseAsset) {
36500
+ const coins = await getAllCoins(account, baseAssetId).then(sortCoins);
36501
+ funding = coins.slice(0, numberOfFundingCoins);
36502
+ dust = coins.slice(numberOfFundingCoins);
36503
+ } else {
36504
+ funding = await getAllCoins(account, baseAssetId).then(sortCoins).then((coins) => coins.slice(0, numberOfFundingCoins));
36505
+ dust = await getAllCoins(account, assetId).then(({ coins }) => coins);
36506
+ }
36507
+ if (funding.length === 0) {
36508
+ throw new FuelError(
36509
+ ErrorCode.INSUFFICIENT_FUNDS,
36510
+ `Insufficient funds to consolidate.
36511
+ Asset ID: ${baseAssetId}
36512
+ Owner: ${account.address.toB256()}`
36513
+ );
36514
+ }
36515
+ const batches = [
36516
+ ...splitEvery_default(batchSize, funding),
36517
+ // We leave one coin for the funding coin
36518
+ ...splitEvery_default(batchSize - 1, dust)
36519
+ ];
36520
+ const txs = batches.map((batch) => {
36521
+ const request = new ScriptTransactionRequest({
36522
+ scriptData: "0x"
36523
+ });
36524
+ request.addResources(batch);
36525
+ return request;
36526
+ });
36527
+ const submitAll = /* @__PURE__ */ __name(async (opts = {}) => {
36528
+ const txResponses = [];
36529
+ let previousTx;
36530
+ for (let i = 0; i < txs.length; i++) {
36531
+ let currentTx = txs[i];
36532
+ const step = i + 1;
36533
+ if (previousTx) {
36534
+ const coin = createOuputCoin({
36535
+ transactionId: previousTx.transactionId,
36536
+ outputs: previousTx.outputs,
36537
+ baseAssetId
36538
+ });
36539
+ currentTx.addResource(coin);
36540
+ }
36541
+ if ("populateTransactionPredicateData" in account && typeof account.populateTransactionPredicateData === "function") {
36542
+ currentTx = account.populateTransactionPredicateData(currentTx);
36543
+ currentTx = await account.provider.estimatePredicates(currentTx);
36544
+ }
36545
+ const fee = calculateGasFee({
36546
+ gasPrice,
36547
+ gas: currentTx.calculateMinGas(chainInfo),
36548
+ priceFactor: chainInfo.consensusParameters.feeParameters.gasPriceFactor,
36549
+ tip: currentTx.tip
36550
+ });
36551
+ currentTx.maxFee = fee;
36552
+ currentTx.gasLimit = bn(1e3);
36553
+ opts.onTransactionStart?.({
36554
+ tx: currentTx,
36555
+ step,
36556
+ assetId,
36557
+ transactionId: currentTx.getTransactionId(chainId)
36558
+ });
36559
+ const response = await account.sendTransaction(currentTx);
36560
+ const result = await response.waitForResult();
36561
+ txResponses.push(result);
36562
+ previousTx = {
36563
+ transactionId: response.id,
36564
+ outputs: result.transaction.outputs
36565
+ };
36566
+ }
36567
+ return {
36568
+ txResponses,
36569
+ errors: []
36570
+ };
36571
+ }, "submitAll");
36572
+ return {
36573
+ txs,
36574
+ totalFeeCost: txs.reduce((acc, request) => acc.add(request.maxFee), bn(0)),
36575
+ submitAll
36576
+ };
36577
+ }, "consolidateCoins");
36578
+
36189
36579
  // src/utils/formatTransferToContractScriptData.ts
36190
36580
  var asm = __toESM(require_node());
36191
36581
  var formatTransferToContractScriptData = /* @__PURE__ */ __name((transferParams) => {
@@ -36302,10 +36692,24 @@ ${PANIC_DOC_URL}#variant.${statusReason}`;
36302
36692
  *
36303
36693
  * @param quantities - Quantities of resources to be obtained.
36304
36694
  * @param resourcesIdsToIgnore - IDs of resources to be excluded from the query (optional).
36695
+ * @param skipAutoConsolidation - Whether to skip the automatic consolidatation of coins process (optional).
36305
36696
  * @returns A promise that resolves to an array of Resources.
36306
36697
  */
36307
- async getResourcesToSpend(quantities, resourcesIdsToIgnore) {
36308
- return this.provider.getResourcesToSpend(this.address, quantities, resourcesIdsToIgnore);
36698
+ async getResourcesToSpend(quantities, resourcesIdsToIgnore, { skipAutoConsolidation } = {}) {
36699
+ const getResourcesToSpend = /* @__PURE__ */ __name(() => this.provider.getResourcesToSpend(this.address, quantities, resourcesIdsToIgnore), "getResourcesToSpend");
36700
+ try {
36701
+ return await getResourcesToSpend();
36702
+ } catch (error2) {
36703
+ const shouldRetry = await consolidateCoinsIfRequired({
36704
+ error: error2,
36705
+ account: this,
36706
+ skipAutoConsolidation
36707
+ });
36708
+ if (!shouldRetry) {
36709
+ throw error2;
36710
+ }
36711
+ return await getResourcesToSpend();
36712
+ }
36309
36713
  }
36310
36714
  /**
36311
36715
  * Retrieves coins owned by the account.
@@ -36354,7 +36758,7 @@ ${PANIC_DOC_URL}#variant.${statusReason}`;
36354
36758
  * @deprecated Use provider.assembleTx instead
36355
36759
  * Check the migration guide https://docs.fuel.network/docs/fuels-ts/transactions/assemble-tx-migration-guide/ for more information.
36356
36760
  */
36357
- async fund(request, params) {
36761
+ async fund(request, params, { skipAutoConsolidation } = {}) {
36358
36762
  const {
36359
36763
  addedSignatures,
36360
36764
  estimatedPredicates,
@@ -36400,7 +36804,8 @@ ${PANIC_DOC_URL}#variant.${statusReason}`;
36400
36804
  while (needsToBeFunded && fundingAttempts < MAX_FUNDING_ATTEMPTS) {
36401
36805
  const resources = await this.getResourcesToSpend(
36402
36806
  missingQuantities,
36403
- cacheRequestInputsResourcesFromOwner(request.inputs, this.address)
36807
+ cacheRequestInputsResourcesFromOwner(request.inputs, this.address),
36808
+ { skipAutoConsolidation }
36404
36809
  );
36405
36810
  request.addResources(resources);
36406
36811
  request.updatePredicateGasUsed(estimatedPredicates);
@@ -36438,7 +36843,7 @@ ${PANIC_DOC_URL}#variant.${statusReason}`;
36438
36843
  }
36439
36844
  if (needsToBeFunded) {
36440
36845
  throw new FuelError(
36441
- ErrorCode.INSUFFICIENT_FUNDS_OR_MAX_COINS,
36846
+ ErrorCode.INSUFFICIENT_FUNDS,
36442
36847
  `The account ${this.address} does not have enough base asset funds to cover the transaction execution.`
36443
36848
  );
36444
36849
  }
@@ -36466,16 +36871,20 @@ ${PANIC_DOC_URL}#variant.${statusReason}`;
36466
36871
  * @param amount - The amount of coins to transfer.
36467
36872
  * @param assetId - The asset ID of the coins to transfer (optional).
36468
36873
  * @param txParams - The transaction parameters (optional).
36874
+ * @param skipAutoConsolidation - Whether to skip the automatic consolidatation of coins process (optional).
36469
36875
  * @returns A promise that resolves to the prepared transaction request.
36470
36876
  */
36471
- async createTransfer(destination, amount, assetId, txParams = {}) {
36877
+ async createTransfer(destination, amount, assetId, txParams = {}, { skipAutoConsolidation } = {}) {
36472
36878
  let request = new ScriptTransactionRequest(txParams);
36473
36879
  request = this.addTransfer(request, {
36474
36880
  destination,
36475
36881
  amount,
36476
36882
  assetId: assetId || await this.provider.getBaseAssetId()
36477
36883
  });
36478
- const { gasPrice, transactionRequest } = await this.assembleTx(request);
36884
+ const { gasPrice, transactionRequest } = await this.assembleTx({
36885
+ transactionRequest: request,
36886
+ skipAutoConsolidation
36887
+ });
36479
36888
  request = await setAndValidateGasAndFeeForAssembledTx({
36480
36889
  gasPrice,
36481
36890
  provider: this.provider,
@@ -36492,10 +36901,13 @@ ${PANIC_DOC_URL}#variant.${statusReason}`;
36492
36901
  * @param amount - The amount of coins to transfer.
36493
36902
  * @param assetId - The asset ID of the coins to transfer (optional).
36494
36903
  * @param txParams - The transaction parameters (optional).
36904
+ * @param skipAutoConsolidation - Whether to skip the automatic consolidatation of coins process (optional).
36495
36905
  * @returns A promise that resolves to the transaction response.
36496
36906
  */
36497
- async transfer(destination, amount, assetId, txParams = {}) {
36498
- const request = await this.createTransfer(destination, amount, assetId, txParams);
36907
+ async transfer(destination, amount, assetId, txParams = {}, { skipAutoConsolidation } = {}) {
36908
+ const request = await this.createTransfer(destination, amount, assetId, txParams, {
36909
+ skipAutoConsolidation
36910
+ });
36499
36911
  return this.sendTransaction(request, { estimateTxDependencies: false });
36500
36912
  }
36501
36913
  /**
@@ -36503,12 +36915,16 @@ ${PANIC_DOC_URL}#variant.${statusReason}`;
36503
36915
  *
36504
36916
  * @param transferParams - An array of `TransferParams` objects representing the transfers to be made.
36505
36917
  * @param txParams - Optional transaction parameters.
36918
+ * @param skipAutoConsolidation - Whether to skip the automatic consolidatation of coins process (optional).
36506
36919
  * @returns A promise that resolves to a `TransactionResponse` object representing the transaction result.
36507
36920
  */
36508
- async batchTransfer(transferParams, txParams = {}) {
36921
+ async batchTransfer(transferParams, txParams = {}, { skipAutoConsolidation } = {}) {
36509
36922
  let request = new ScriptTransactionRequest(txParams);
36510
36923
  request = this.addBatchTransfer(request, transferParams);
36511
- const { gasPrice, transactionRequest } = await this.assembleTx(request);
36924
+ const { gasPrice, transactionRequest } = await this.assembleTx({
36925
+ transactionRequest: request,
36926
+ skipAutoConsolidation
36927
+ });
36512
36928
  request = await setAndValidateGasAndFeeForAssembledTx({
36513
36929
  gasPrice,
36514
36930
  provider: this.provider,
@@ -36555,12 +36971,15 @@ ${PANIC_DOC_URL}#variant.${statusReason}`;
36555
36971
  * @param amount - The amount of coins to transfer.
36556
36972
  * @param assetId - The asset ID of the coins to transfer (optional).
36557
36973
  * @param txParams - The transaction parameters (optional).
36974
+ * @param skipAutoConsolidation - Whether to skip the automatic consolidatation of coins process (optional).
36558
36975
  * @returns A promise that resolves to the transaction response.
36559
36976
  */
36560
- async transferToContract(contractId, amount, assetId, txParams = {}) {
36561
- return this.batchTransferToContracts([{ amount, assetId, contractId }], txParams);
36977
+ async transferToContract(contractId, amount, assetId, txParams = {}, { skipAutoConsolidation } = {}) {
36978
+ return this.batchTransferToContracts([{ amount, assetId, contractId }], txParams, {
36979
+ skipAutoConsolidation
36980
+ });
36562
36981
  }
36563
- async batchTransferToContracts(contractTransferParams, txParams = {}) {
36982
+ async batchTransferToContracts(contractTransferParams, txParams = {}, { skipAutoConsolidation } = {}) {
36564
36983
  let request = new ScriptTransactionRequest({
36565
36984
  ...txParams
36566
36985
  });
@@ -36587,7 +37006,11 @@ ${PANIC_DOC_URL}#variant.${statusReason}`;
36587
37006
  const { script, scriptData } = await assembleTransferToContractScript(transferParams);
36588
37007
  request.script = script;
36589
37008
  request.scriptData = scriptData;
36590
- const { gasPrice, transactionRequest } = await this.assembleTx(request, quantities);
37009
+ const { gasPrice, transactionRequest } = await this.assembleTx({
37010
+ transactionRequest: request,
37011
+ quantities,
37012
+ skipAutoConsolidation
37013
+ });
36591
37014
  request = await setAndValidateGasAndFeeForAssembledTx({
36592
37015
  gasPrice,
36593
37016
  provider: this.provider,
@@ -36603,9 +37026,10 @@ ${PANIC_DOC_URL}#variant.${statusReason}`;
36603
37026
  * @param recipient - Address of the recipient on the base chain.
36604
37027
  * @param amount - Amount of base asset.
36605
37028
  * @param txParams - The transaction parameters (optional).
37029
+ * @param skipAutoConsolidation - Whether to skip the automatic consolidatation of coins process (optional).
36606
37030
  * @returns A promise that resolves to the transaction response.
36607
37031
  */
36608
- async withdrawToBaseLayer(recipient, amount, txParams = {}) {
37032
+ async withdrawToBaseLayer(recipient, amount, txParams = {}, { skipAutoConsolidation } = {}) {
36609
37033
  const recipientAddress = new Address(recipient);
36610
37034
  const recipientDataArray = arrayify(
36611
37035
  "0x".concat(recipientAddress.toHexString().substring(2).padStart(64, "0"))
@@ -36622,7 +37046,11 @@ ${PANIC_DOC_URL}#variant.${statusReason}`;
36622
37046
  const baseAssetId = await this.provider.getBaseAssetId();
36623
37047
  let request = new ScriptTransactionRequest(params);
36624
37048
  const quantities = [{ amount: bn(amount), assetId: baseAssetId }];
36625
- const { gasPrice, transactionRequest } = await this.assembleTx(request, quantities);
37049
+ const { gasPrice, transactionRequest } = await this.assembleTx({
37050
+ transactionRequest: request,
37051
+ quantities,
37052
+ skipAutoConsolidation
37053
+ });
36626
37054
  request = await setAndValidateGasAndFeeForAssembledTx({
36627
37055
  gasPrice,
36628
37056
  provider: this.provider,
@@ -36632,6 +37060,25 @@ ${PANIC_DOC_URL}#variant.${statusReason}`;
36632
37060
  });
36633
37061
  return this.sendTransaction(request);
36634
37062
  }
37063
+ /**
37064
+ * Start the consolidation process
37065
+ *
37066
+ * @param owner - The B256 address of the owner.
37067
+ * @param assetId - The asset ID that requires consolidation.
37068
+ */
37069
+ async startConsolidation(opts) {
37070
+ if (this._connector) {
37071
+ await this._connector.startConsolidation(opts);
37072
+ return false;
37073
+ }
37074
+ const { owner, assetId } = opts;
37075
+ if (owner !== this.address.toB256()) {
37076
+ return false;
37077
+ }
37078
+ const { submitAll } = await consolidateCoins({ account: this, assetId });
37079
+ await submitAll();
37080
+ return true;
37081
+ }
36635
37082
  /**
36636
37083
  * Consolidates base asset UTXOs into fewer, larger ones.
36637
37084
  *
@@ -36651,6 +37098,7 @@ ${PANIC_DOC_URL}#variant.${statusReason}`;
36651
37098
  const isBaseAsset = baseAssetId === assetId;
36652
37099
  let submitAll;
36653
37100
  const consolidationParams = {
37101
+ assetId,
36654
37102
  coins,
36655
37103
  mode: params.mode,
36656
37104
  outputNum: params.outputNum
@@ -36658,10 +37106,7 @@ ${PANIC_DOC_URL}#variant.${statusReason}`;
36658
37106
  if (isBaseAsset) {
36659
37107
  ({ submitAll } = await this.assembleBaseAssetConsolidationTxs(consolidationParams));
36660
37108
  } else {
36661
- throw new FuelError(
36662
- ErrorCode.UNSUPPORTED_FEATURE,
36663
- "Consolidation for non-base assets is not supported yet."
36664
- );
37109
+ ({ submitAll } = await this.assembleNonBaseAssetConsolidationTxs(consolidationParams));
36665
37110
  }
36666
37111
  return submitAll();
36667
37112
  }
@@ -36720,6 +37165,70 @@ ${PANIC_DOC_URL}#variant.${statusReason}`;
36720
37165
  const submitAll = this.prepareSubmitAll({ txs, mode });
36721
37166
  return { txs, totalFeeCost, submitAll };
36722
37167
  }
37168
+ async assembleNonBaseAssetConsolidationTxs(params) {
37169
+ const { assetId, coins, mode = "parallel", outputNum = 1 } = params;
37170
+ this.validateConsolidationTxsCoins(coins, assetId);
37171
+ const chainInfo = await this.provider.getChain();
37172
+ const maxInputsNumber = chainInfo.consensusParameters.txParameters.maxInputs.toNumber();
37173
+ const baseAssetId = chainInfo.consensusParameters.baseAssetId;
37174
+ const { coins: baseAssetCoins } = await this.provider.getCoins(this.address, baseAssetId);
37175
+ let totalFeeCost = bn(0);
37176
+ const txs = [];
37177
+ const gasPrice = await this.provider.estimateGasPrice(10);
37178
+ const consolidateMoreThanOneCoin = outputNum > 1;
37179
+ const assetCoinBatches = splitCoinsIntoBatches(coins, maxInputsNumber);
37180
+ assetCoinBatches.filter((batch) => batch.length > 1).forEach((coinBatch) => {
37181
+ const request = new ScriptTransactionRequest({
37182
+ script: "0x"
37183
+ });
37184
+ request.addResources(coinBatch);
37185
+ if (consolidateMoreThanOneCoin) {
37186
+ Array.from({ length: outputNum - 1 }).forEach(() => {
37187
+ request.addCoinOutput(this.address, 0, assetId);
37188
+ });
37189
+ }
37190
+ const minGas = request.calculateMinGas(chainInfo);
37191
+ const fee = calculateGasFee({
37192
+ gasPrice,
37193
+ gas: minGas,
37194
+ priceFactor: chainInfo.consensusParameters.feeParameters.gasPriceFactor,
37195
+ tip: request.tip
37196
+ });
37197
+ request.maxFee = fee;
37198
+ if (consolidateMoreThanOneCoin) {
37199
+ const total = request.inputs.filter(isRequestInputCoin).reduce((acc, input) => acc.add(input.amount), bn(0));
37200
+ const amountPerNewUtxo = total.div(outputNum + 1);
37201
+ request.outputs.forEach((output) => {
37202
+ if (output.type === OutputType.Coin) {
37203
+ output.amount = amountPerNewUtxo;
37204
+ }
37205
+ });
37206
+ }
37207
+ totalFeeCost = totalFeeCost.add(fee);
37208
+ const baseAssetResources = [];
37209
+ let fundingFeeTotal = bn(0);
37210
+ while (fundingFeeTotal.lt(fee)) {
37211
+ const baseAssetCoin = baseAssetCoins.pop();
37212
+ if (!baseAssetCoin) {
37213
+ break;
37214
+ }
37215
+ baseAssetResources.push(baseAssetCoin);
37216
+ fundingFeeTotal = fundingFeeTotal.add(baseAssetCoin.amount);
37217
+ }
37218
+ const { inputs } = request;
37219
+ request.inputs = inputs.slice(0, maxInputsNumber - baseAssetResources.length);
37220
+ const removedCoins = coinBatch.slice(maxInputsNumber - baseAssetResources.length);
37221
+ request.addResources(baseAssetResources);
37222
+ const lastCoinBatch = assetCoinBatches[assetCoinBatches.length - 1];
37223
+ lastCoinBatch.push(...removedCoins);
37224
+ if (lastCoinBatch.length > maxInputsNumber) {
37225
+ assetCoinBatches.push(lastCoinBatch.slice(maxInputsNumber));
37226
+ }
37227
+ txs.push(request);
37228
+ });
37229
+ const submitAll = this.prepareSubmitAll({ txs, mode });
37230
+ return { txs, totalFeeCost, submitAll };
37231
+ }
36723
37232
  /**
36724
37233
  * Prepares a function to submit all transactions either sequentially or in parallel.
36725
37234
  *
@@ -36934,16 +37443,32 @@ ${PANIC_DOC_URL}#variant.${statusReason}`;
36934
37443
  } : void 0;
36935
37444
  }
36936
37445
  /** @hidden * */
36937
- async assembleTx(transactionRequest, quantities = []) {
37446
+ async assembleTx(opts) {
37447
+ const { transactionRequest, quantities = [], skipAutoConsolidation } = opts;
36938
37448
  const outputQuantities = transactionRequest.outputs.filter((o) => o.type === OutputType.Coin).map(({ amount, assetId }) => ({ assetId: String(assetId), amount: bn(amount) }));
36939
37449
  transactionRequest.gasLimit = bn(0);
36940
37450
  transactionRequest.maxFee = bn(0);
36941
- const { assembledRequest, gasPrice } = await this.provider.assembleTx({
36942
- request: transactionRequest,
36943
- accountCoinQuantities: mergeQuantities(outputQuantities, quantities),
36944
- feePayerAccount: this
36945
- });
36946
- return { transactionRequest: assembledRequest, gasPrice };
37451
+ const assembleTx = /* @__PURE__ */ __name(async () => {
37452
+ const { assembledRequest, gasPrice } = await this.provider.assembleTx({
37453
+ request: transactionRequest,
37454
+ accountCoinQuantities: mergeQuantities(outputQuantities, quantities),
37455
+ feePayerAccount: this
37456
+ });
37457
+ return { transactionRequest: assembledRequest, gasPrice };
37458
+ }, "assembleTx");
37459
+ try {
37460
+ return await assembleTx();
37461
+ } catch (error2) {
37462
+ const shouldRetry = await consolidateCoinsIfRequired({
37463
+ error: error2,
37464
+ account: this,
37465
+ skipAutoConsolidation
37466
+ });
37467
+ if (!shouldRetry) {
37468
+ throw error2;
37469
+ }
37470
+ return await assembleTx();
37471
+ }
36947
37472
  }
36948
37473
  /** @hidden * */
36949
37474
  validateTransferAmount(amount) {
@@ -36955,45 +37480,6 @@ ${PANIC_DOC_URL}#variant.${statusReason}`;
36955
37480
  }
36956
37481
  }
36957
37482
  /** @hidden * */
36958
- async estimateAndFundTransaction(transactionRequest, txParams, costParams) {
36959
- let request = transactionRequest;
36960
- const txCost = await this.getTransactionCost(request, costParams);
36961
- request = this.validateGasLimitAndMaxFee({
36962
- transactionRequest: request,
36963
- gasUsed: txCost.gasUsed,
36964
- maxFee: txCost.maxFee,
36965
- txParams
36966
- });
36967
- request = await this.fund(request, txCost);
36968
- return request;
36969
- }
36970
- /** @hidden * */
36971
- validateGasLimitAndMaxFee({
36972
- gasUsed,
36973
- maxFee,
36974
- transactionRequest,
36975
- txParams: { gasLimit: setGasLimit, maxFee: setMaxFee }
36976
- }) {
36977
- const request = transactionRequestify(transactionRequest);
36978
- if (!isDefined(setGasLimit)) {
36979
- request.gasLimit = gasUsed;
36980
- } else if (gasUsed.gt(setGasLimit)) {
36981
- throw new FuelError(
36982
- ErrorCode.GAS_LIMIT_TOO_LOW,
36983
- `Gas limit '${setGasLimit}' is lower than the required: '${gasUsed}'.`
36984
- );
36985
- }
36986
- if (!isDefined(setMaxFee)) {
36987
- request.maxFee = maxFee;
36988
- } else if (maxFee.gt(setMaxFee)) {
36989
- throw new FuelError(
36990
- ErrorCode.MAX_FEE_TOO_LOW,
36991
- `Max fee '${setMaxFee}' is lower than the required: '${maxFee}'.`
36992
- );
36993
- }
36994
- return request;
36995
- }
36996
- /** @hidden * */
36997
37483
  validateConsolidationTxsCoins(coins, assetId) {
36998
37484
  if (coins.length <= 1) {
36999
37485
  throw new FuelError(ErrorCode.NO_COINS_TO_CONSOLIDATE, "No coins to consolidate.");