@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
@@ -17990,8 +17990,8 @@
17990
17990
  function getBuiltinVersions() {
17991
17991
  return {
17992
17992
  FUEL_CORE: "0.43.1",
17993
- FORC: "0.68.1",
17994
- FUELS: "0.101.1"
17993
+ FORC: "0.68.7",
17994
+ FUELS: "0.101.3"
17995
17995
  };
17996
17996
  }
17997
17997
  __name(getBuiltinVersions, "getBuiltinVersions");
@@ -18104,6 +18104,7 @@ This unreleased fuel-core build may include features and updates not yet support
18104
18104
  ErrorCode2["CONNECTION_REFUSED"] = "connection-refused";
18105
18105
  ErrorCode2["INVALID_URL"] = "invalid-url";
18106
18106
  ErrorCode2["UNSUPPORTED_FEATURE"] = "unsupported-feature";
18107
+ ErrorCode2["RESPONSE_BODY_EMPTY"] = "response-body-empty";
18107
18108
  ErrorCode2["INVALID_PUBLIC_KEY"] = "invalid-public-key";
18108
18109
  ErrorCode2["WALLET_MANAGER_ERROR"] = "wallet-manager-error";
18109
18110
  ErrorCode2["HD_WALLET_ERROR"] = "hd-wallet-error";
@@ -18122,6 +18123,8 @@ This unreleased fuel-core build may include features and updates not yet support
18122
18123
  ErrorCode2["INVALID_REQUEST"] = "invalid-request";
18123
18124
  ErrorCode2["INVALID_TRANSFER_AMOUNT"] = "invalid-transfer-amount";
18124
18125
  ErrorCode2["INSUFFICIENT_FUNDS_OR_MAX_COINS"] = "not-enough-funds-or-max-coins-reached";
18126
+ ErrorCode2["INSUFFICIENT_FUNDS"] = "not-enough-funds";
18127
+ ErrorCode2["MAX_COINS_REACHED"] = "max-coins-reached";
18125
18128
  ErrorCode2["INVALID_CREDENTIALS"] = "invalid-credentials";
18126
18129
  ErrorCode2["HASHER_LOCKED"] = "hasher-locked";
18127
18130
  ErrorCode2["GAS_PRICE_TOO_LOW"] = "gas-price-too-low";
@@ -18155,6 +18158,7 @@ This unreleased fuel-core build may include features and updates not yet support
18155
18158
  ErrorCode2["INVALID_PASSWORD"] = "invalid-password";
18156
18159
  ErrorCode2["ACCOUNT_REQUIRED"] = "account-required";
18157
18160
  ErrorCode2["UNLOCKED_WALLET_REQUIRED"] = "unlocked-wallet-required";
18161
+ ErrorCode2["UNABLE_TO_CONSOLIDATE_COINS"] = "unable-to-consolidate-coins";
18158
18162
  ErrorCode2["NO_COINS_TO_CONSOLIDATE"] = "no-coins-to-consolidate";
18159
18163
  ErrorCode2["COINS_ASSET_ID_MISMATCH"] = "coins-asset-id-mismatch";
18160
18164
  ErrorCode2["ASSET_NOT_FOUND"] = "asset-not-found";
@@ -18196,7 +18200,7 @@ This unreleased fuel-core build may include features and updates not yet support
18196
18200
  `Unknown error code: ${error2.code}. Accepted codes: ${enumValues.join(", ")}.`
18197
18201
  );
18198
18202
  }
18199
- return new _FuelError(error2.code, error2.message);
18203
+ return new _FuelError(error2.code, error2.message, error2.metadata, error2.rawError);
18200
18204
  }
18201
18205
  code;
18202
18206
  constructor(code, message, metadata = {}, rawError = null) {
@@ -21301,7 +21305,8 @@ If you are attempting to transform a hex value, please make sure it is being pas
21301
21305
  functions,
21302
21306
  loggedTypes,
21303
21307
  messagesTypes: abi.messagesTypes,
21304
- configurables
21308
+ configurables,
21309
+ errorCodes: abi.errorCodes
21305
21310
  };
21306
21311
  return transpiled;
21307
21312
  }
@@ -23126,6 +23131,69 @@ If you are attempting to transform a hex value, please make sure it is being pas
23126
23131
  }
23127
23132
  __name(_curry1, "_curry1");
23128
23133
 
23134
+ // ../../node_modules/.pnpm/ramda@0.30.1/node_modules/ramda/es/internal/_curry2.js
23135
+ function _curry2(fn) {
23136
+ return /* @__PURE__ */ __name(function f2(a, b) {
23137
+ switch (arguments.length) {
23138
+ case 0:
23139
+ return f2;
23140
+ case 1:
23141
+ return _isPlaceholder(a) ? f2 : _curry1(function(_b) {
23142
+ return fn(a, _b);
23143
+ });
23144
+ default:
23145
+ return _isPlaceholder(a) && _isPlaceholder(b) ? f2 : _isPlaceholder(a) ? _curry1(function(_a) {
23146
+ return fn(_a, b);
23147
+ }) : _isPlaceholder(b) ? _curry1(function(_b) {
23148
+ return fn(a, _b);
23149
+ }) : fn(a, b);
23150
+ }
23151
+ }, "f2");
23152
+ }
23153
+ __name(_curry2, "_curry2");
23154
+
23155
+ // ../../node_modules/.pnpm/ramda@0.30.1/node_modules/ramda/es/internal/_curry3.js
23156
+ function _curry3(fn) {
23157
+ return /* @__PURE__ */ __name(function f3(a, b, c) {
23158
+ switch (arguments.length) {
23159
+ case 0:
23160
+ return f3;
23161
+ case 1:
23162
+ return _isPlaceholder(a) ? f3 : _curry2(function(_b, _c) {
23163
+ return fn(a, _b, _c);
23164
+ });
23165
+ case 2:
23166
+ return _isPlaceholder(a) && _isPlaceholder(b) ? f3 : _isPlaceholder(a) ? _curry2(function(_a, _c) {
23167
+ return fn(_a, b, _c);
23168
+ }) : _isPlaceholder(b) ? _curry2(function(_b, _c) {
23169
+ return fn(a, _b, _c);
23170
+ }) : _curry1(function(_c) {
23171
+ return fn(a, b, _c);
23172
+ });
23173
+ default:
23174
+ return _isPlaceholder(a) && _isPlaceholder(b) && _isPlaceholder(c) ? f3 : _isPlaceholder(a) && _isPlaceholder(b) ? _curry2(function(_a, _b) {
23175
+ return fn(_a, _b, c);
23176
+ }) : _isPlaceholder(a) && _isPlaceholder(c) ? _curry2(function(_a, _c) {
23177
+ return fn(_a, b, _c);
23178
+ }) : _isPlaceholder(b) && _isPlaceholder(c) ? _curry2(function(_b, _c) {
23179
+ return fn(a, _b, _c);
23180
+ }) : _isPlaceholder(a) ? _curry1(function(_a) {
23181
+ return fn(_a, b, c);
23182
+ }) : _isPlaceholder(b) ? _curry1(function(_b) {
23183
+ return fn(a, _b, c);
23184
+ }) : _isPlaceholder(c) ? _curry1(function(_c) {
23185
+ return fn(a, b, _c);
23186
+ }) : fn(a, b, c);
23187
+ }
23188
+ }, "f3");
23189
+ }
23190
+ __name(_curry3, "_curry3");
23191
+
23192
+ // ../../node_modules/.pnpm/ramda@0.30.1/node_modules/ramda/es/internal/_isArray.js
23193
+ var isArray_default = Array.isArray || /* @__PURE__ */ __name(function _isArray(val) {
23194
+ return val != null && val.length >= 0 && Object.prototype.toString.call(val) === "[object Array]";
23195
+ }, "_isArray");
23196
+
23129
23197
  // ../../node_modules/.pnpm/ramda@0.30.1/node_modules/ramda/es/type.js
23130
23198
  var type = /* @__PURE__ */ _curry1(/* @__PURE__ */ __name(function type2(val) {
23131
23199
  return val === null ? "Null" : val === void 0 ? "Undefined" : Object.prototype.toString.call(val).slice(8, -1);
@@ -23244,6 +23312,39 @@ If you are attempting to transform a hex value, please make sure it is being pas
23244
23312
  }, "clone"));
23245
23313
  var clone_default = clone;
23246
23314
 
23315
+ // ../../node_modules/.pnpm/ramda@0.30.1/node_modules/ramda/es/internal/_checkForMethod.js
23316
+ function _checkForMethod(methodname, fn) {
23317
+ return function() {
23318
+ var length = arguments.length;
23319
+ if (length === 0) {
23320
+ return fn();
23321
+ }
23322
+ var obj = arguments[length - 1];
23323
+ return isArray_default(obj) || typeof obj[methodname] !== "function" ? fn.apply(this, arguments) : obj[methodname].apply(obj, Array.prototype.slice.call(arguments, 0, length - 1));
23324
+ };
23325
+ }
23326
+ __name(_checkForMethod, "_checkForMethod");
23327
+
23328
+ // ../../node_modules/.pnpm/ramda@0.30.1/node_modules/ramda/es/slice.js
23329
+ var slice = /* @__PURE__ */ _curry3(/* @__PURE__ */ _checkForMethod("slice", /* @__PURE__ */ __name(function slice2(fromIndex, toIndex, list) {
23330
+ return Array.prototype.slice.call(list, fromIndex, toIndex);
23331
+ }, "slice")));
23332
+ var slice_default = slice;
23333
+
23334
+ // ../../node_modules/.pnpm/ramda@0.30.1/node_modules/ramda/es/splitEvery.js
23335
+ var splitEvery = /* @__PURE__ */ _curry2(/* @__PURE__ */ __name(function splitEvery2(n, list) {
23336
+ if (n <= 0) {
23337
+ throw new Error("First argument to splitEvery must be a positive integer");
23338
+ }
23339
+ var result = [];
23340
+ var idx = 0;
23341
+ while (idx < list.length) {
23342
+ result.push(slice_default(idx, idx += n, list));
23343
+ }
23344
+ return result;
23345
+ }, "splitEvery"));
23346
+ var splitEvery_default = splitEvery;
23347
+
23247
23348
  // src/providers/coin-quantity.ts
23248
23349
  var coinQuantityfy = /* @__PURE__ */ __name((coinQuantityLike) => {
23249
23350
  let assetId;
@@ -28502,8 +28603,11 @@ ${DryRunSuccessAssembleTxFragmentDoc}`;
28502
28603
  }, "setAndValidateGasAndFeeForAssembledTx");
28503
28604
 
28504
28605
  // src/providers/utils/handle-gql-error-message.ts
28606
+ var ASSET_ID_REGEX = /[0-9a-fA-F]{32,64}/g;
28505
28607
  var gqlErrorMessage = {
28506
28608
  RPC_CONSISTENCY: /The required fuel block height is higher than the current block height. Required: \d+, Current: \d+/,
28609
+ INSUFFICIENT_FUNDS: /the target cannot be met due to insufficient coins available for [0-9a-fA-F]{32,64}. Collected: \d+/,
28610
+ MAX_COINS_REACHED: /the target for [0-9a-fA-F]{32,64} cannot be met due to exceeding the \d+ coin limit. Collected: \d+./,
28507
28611
  NOT_ENOUGH_COINS_MAX_COINS: /the target cannot be met due to no coins available or exceeding the \d+ coin limit./,
28508
28612
  ASSET_NOT_FOUND: /resource was not found in table/,
28509
28613
  MULTIPLE_CHANGE_POLICIES: /The asset ([a-fA-F0-9]{64}) has multiple change policies/,
@@ -28519,6 +28623,46 @@ ${DryRunSuccessAssembleTxFragmentDoc}`;
28519
28623
  error2
28520
28624
  );
28521
28625
  }
28626
+ if (gqlErrorMessage.MAX_COINS_REACHED.test(error2.message)) {
28627
+ const matches = error2.message.match(ASSET_ID_REGEX);
28628
+ const assetId = matches ? `0x${matches[0]}` : null;
28629
+ const owner = matches ? `0x${matches[1]}` : null;
28630
+ let suffix = "";
28631
+ if (assetId) {
28632
+ suffix += `
28633
+ Asset ID: '${assetId}'.`;
28634
+ }
28635
+ if (owner) {
28636
+ suffix += `
28637
+ Owner: '${owner}'.`;
28638
+ }
28639
+ return new FuelError(
28640
+ ErrorCode.MAX_COINS_REACHED,
28641
+ `You have too many small value coins - consider combining UTXOs.${suffix}`,
28642
+ { assetId, owner },
28643
+ error2
28644
+ );
28645
+ }
28646
+ if (gqlErrorMessage.INSUFFICIENT_FUNDS.test(error2.message)) {
28647
+ const matches = error2.message.match(ASSET_ID_REGEX);
28648
+ const assetId = matches ? `0x${matches[0]}` : null;
28649
+ const owner = matches ? `0x${matches[1]}` : null;
28650
+ let suffix = "";
28651
+ if (assetId) {
28652
+ suffix += `
28653
+ Asset ID: '${assetId}'.`;
28654
+ }
28655
+ if (owner) {
28656
+ suffix += `
28657
+ Owner: '${owner}'.`;
28658
+ }
28659
+ return new FuelError(
28660
+ ErrorCode.INSUFFICIENT_FUNDS,
28661
+ `Insufficient funds.${suffix}`,
28662
+ { assetId, owner },
28663
+ error2
28664
+ );
28665
+ }
28522
28666
  if (gqlErrorMessage.MULTIPLE_CHANGE_POLICIES.test(error2.message)) {
28523
28667
  const match = error2.message.match(/asset ([a-fA-F0-9]{64})/);
28524
28668
  const assetId = match?.[1] || "";
@@ -28831,6 +28975,7 @@ ${incompatibleNodeVersionMessage}`,
28831
28975
  var FAILED_ASSERT_EQ_SIGNAL = "0xffffffffffff0003";
28832
28976
  var FAILED_ASSERT_SIGNAL = "0xffffffffffff0004";
28833
28977
  var FAILED_ASSERT_NE_SIGNAL = "0xffffffffffff0005";
28978
+ var REVERT_WITH_LOG_SIGNAL = "0xffffffffffff0006";
28834
28979
  var PANIC_REASONS = [
28835
28980
  "ArithmeticError",
28836
28981
  "ArithmeticOverflow",
@@ -28899,6 +29044,14 @@ ${incompatibleNodeVersionMessage}`,
28899
29044
  "WitnessNotFound"
28900
29045
  ];
28901
29046
  var PANIC_DOC_URL = "https://docs.rs/fuel-asm/latest/fuel_asm/enum.PanicReason.html";
29047
+ var SwaySignalErrors = {
29048
+ FAILED_REQUIRE_SIGNAL,
29049
+ FAILED_TRANSFER_TO_ADDRESS_SIGNAL,
29050
+ FAILED_ASSERT_EQ_SIGNAL,
29051
+ FAILED_ASSERT_SIGNAL,
29052
+ FAILED_ASSERT_NE_SIGNAL,
29053
+ REVERT_WITH_LOG_SIGNAL
29054
+ };
28902
29055
 
28903
29056
  // src/providers/utils/serialization.ts
28904
29057
  var deserializeChain = /* @__PURE__ */ __name((chain) => {
@@ -29648,58 +29801,98 @@ ${PANIC_DOC_URL}#variant.${statusReason}`;
29648
29801
  });
29649
29802
  }, "assemblePanicError");
29650
29803
  var stringify = /* @__PURE__ */ __name((obj) => JSON.stringify(obj, null, 2), "stringify");
29651
- var assembleRevertError = /* @__PURE__ */ __name((receipts, logs, metadata) => {
29804
+ var assembleSignalErrorMessage = /* @__PURE__ */ __name((reasonHex, logs, metadata) => {
29652
29805
  let errorMessage = "The transaction reverted with an unknown reason.";
29653
- const revertReceipt = receipts.find(({ type: type3 }) => type3 === ReceiptType.Revert);
29654
29806
  let reason = "";
29655
- if (revertReceipt) {
29656
- const reasonHex = bn(revertReceipt.val).toHex();
29657
- const lastLog = logs[logs.length - 1];
29658
- const lastButOneLog = logs[logs.length - 2];
29659
- switch (reasonHex) {
29660
- case FAILED_REQUIRE_SIGNAL: {
29661
- reason = "require";
29662
- errorMessage = `The transaction reverted because a "require" statement has thrown ${logs.length ? stringify(lastLog) : "an error."}.`;
29663
- break;
29664
- }
29665
- case FAILED_ASSERT_EQ_SIGNAL: {
29666
- const suffix = logs.length >= 2 ? ` comparing ${stringify(lastLog)} and ${stringify(lastButOneLog)}.` : ".";
29667
- reason = "assert_eq";
29668
- errorMessage = `The transaction reverted because of an "assert_eq" statement${suffix}`;
29669
- break;
29670
- }
29671
- case FAILED_ASSERT_NE_SIGNAL: {
29672
- const suffix = logs.length >= 2 ? ` comparing ${stringify(lastButOneLog)} and ${stringify(lastLog)}.` : ".";
29673
- reason = "assert_ne";
29674
- errorMessage = `The transaction reverted because of an "assert_ne" statement${suffix}`;
29675
- break;
29676
- }
29677
- case FAILED_ASSERT_SIGNAL:
29678
- reason = "assert";
29679
- errorMessage = `The transaction reverted because an "assert" statement failed to evaluate to true.`;
29680
- break;
29681
- case FAILED_TRANSFER_TO_ADDRESS_SIGNAL:
29682
- reason = "MissingOutputVariable";
29683
- errorMessage = `The transaction reverted because it's missing an "OutputVariable".`;
29684
- break;
29685
- default:
29686
- throw new FuelError(
29687
- ErrorCode.UNKNOWN,
29688
- `The transaction reverted with an unknown reason: ${revertReceipt.val}`,
29689
- {
29690
- ...metadata,
29691
- reason: "unknown"
29692
- }
29693
- );
29807
+ const lastLog = logs[logs.length - 1];
29808
+ const lastButOneLog = logs[logs.length - 2];
29809
+ switch (reasonHex) {
29810
+ case FAILED_REQUIRE_SIGNAL: {
29811
+ reason = "require";
29812
+ errorMessage = `The transaction reverted because a "require" statement has thrown ${logs.length ? stringify(lastLog) : "an error."}.`;
29813
+ break;
29814
+ }
29815
+ case FAILED_ASSERT_EQ_SIGNAL: {
29816
+ const suffix = logs.length >= 2 ? ` comparing ${stringify(lastLog)} and ${stringify(lastButOneLog)}.` : ".";
29817
+ reason = "assert_eq";
29818
+ errorMessage = `The transaction reverted because of an "assert_eq" statement${suffix}`;
29819
+ break;
29820
+ }
29821
+ case FAILED_ASSERT_NE_SIGNAL: {
29822
+ const suffix = logs.length >= 2 ? ` comparing ${stringify(lastButOneLog)} and ${stringify(lastLog)}.` : ".";
29823
+ reason = "assert_ne";
29824
+ errorMessage = `The transaction reverted because of an "assert_ne" statement${suffix}`;
29825
+ break;
29826
+ }
29827
+ case FAILED_ASSERT_SIGNAL:
29828
+ reason = "assert";
29829
+ errorMessage = `The transaction reverted because an "assert" statement failed to evaluate to true.`;
29830
+ break;
29831
+ case FAILED_TRANSFER_TO_ADDRESS_SIGNAL:
29832
+ reason = "MissingOutputVariable";
29833
+ errorMessage = `The transaction reverted because it's missing an "OutputVariable".`;
29834
+ break;
29835
+ default:
29836
+ reason = `revert_with_log`;
29837
+ errorMessage = `The transaction reverted because a "revert_with_log" statement has thrown ${logs.length ? stringify(lastLog) : "an error."}.`;
29838
+ break;
29839
+ }
29840
+ return new FuelError(ErrorCode.SCRIPT_REVERTED, errorMessage, {
29841
+ ...metadata,
29842
+ reason
29843
+ });
29844
+ }, "assembleSignalErrorMessage");
29845
+ function buildAbiErrorMessage(abiError, logs, metadata, reason) {
29846
+ const { pos, msg } = abiError;
29847
+ let errorMessage = "";
29848
+ const positionMessage = pos ? `
29849
+
29850
+ This error originated at ${JSON.stringify(pos, null, 2)}` : "";
29851
+ if (msg) {
29852
+ errorMessage = `A sway "panic" expression was invoked with the message: "${msg}".${positionMessage}`;
29853
+ } else {
29854
+ const value = logs[logs.length - 1];
29855
+ errorMessage = `A sway "panic" expression was invoked with the value: ${JSON.stringify(value)}.${positionMessage}`;
29856
+ }
29857
+ return new FuelError(ErrorCode.SCRIPT_REVERTED, errorMessage, {
29858
+ ...metadata,
29859
+ abiError,
29860
+ reason
29861
+ });
29862
+ }
29863
+ __name(buildAbiErrorMessage, "buildAbiErrorMessage");
29864
+ function findErrorInAbis(statusReason, abis = []) {
29865
+ for (const abi of abis) {
29866
+ if (abi.errorCodes?.[statusReason]) {
29867
+ return abi.errorCodes[statusReason];
29694
29868
  }
29695
29869
  }
29870
+ return void 0;
29871
+ }
29872
+ __name(findErrorInAbis, "findErrorInAbis");
29873
+ var assembleRevertError = /* @__PURE__ */ __name((_receipts, logs, metadata, statusReason, abis) => {
29874
+ const match = statusReason.match(/Revert\((\d+)\)/);
29875
+ const reason = match?.[1] ?? statusReason;
29876
+ const reasonHex = bn(reason).toHex();
29877
+ if (Object.values(SwaySignalErrors).includes(reasonHex)) {
29878
+ return assembleSignalErrorMessage(reasonHex, logs, metadata);
29879
+ }
29880
+ let abiError;
29881
+ if (abis) {
29882
+ const abisArr = [abis.main, ...Object.values(abis.otherContractsAbis)];
29883
+ abiError = findErrorInAbis(reason, abisArr);
29884
+ }
29885
+ if (abiError) {
29886
+ return buildAbiErrorMessage(abiError, logs, metadata, reason);
29887
+ }
29888
+ const errorMessage = `The transaction reverted with reason: ${reason}.`;
29696
29889
  return new FuelError(ErrorCode.SCRIPT_REVERTED, errorMessage, {
29697
29890
  ...metadata,
29698
29891
  reason
29699
29892
  });
29700
29893
  }, "assembleRevertError");
29701
29894
  var extractTxError = /* @__PURE__ */ __name((params) => {
29702
- const { receipts, statusReason, logs, groupedLogs } = params;
29895
+ const { receipts, statusReason, logs, groupedLogs, abis } = params;
29703
29896
  const isPanic = receipts.some(({ type: type3 }) => type3 === ReceiptType.Panic);
29704
29897
  const isRevert = receipts.some(({ type: type3 }) => type3 === ReceiptType.Revert);
29705
29898
  const metadata = {
@@ -29713,7 +29906,7 @@ ${PANIC_DOC_URL}#variant.${statusReason}`;
29713
29906
  if (isPanic) {
29714
29907
  return assemblePanicError(statusReason, metadata);
29715
29908
  }
29716
- return assembleRevertError(receipts, logs, metadata);
29909
+ return assembleRevertError(receipts, logs, metadata, statusReason, abis);
29717
29910
  }, "extractTxError");
29718
29911
 
29719
29912
  // src/providers/utils/merge-quantities.ts
@@ -30686,11 +30879,15 @@ ${PANIC_DOC_URL}#variant.${statusReason}`;
30686
30879
  * @deprecated Use `provider.assembleTx` instead.
30687
30880
  * Check the migration guide https://docs.fuel.network/guide/assembling-transactions/migration-guide.html for more information.
30688
30881
  */
30689
- async estimateAndFund(account, { signatureCallback, quantities = [] } = {}) {
30882
+ async estimateAndFund(account, {
30883
+ signatureCallback,
30884
+ quantities = [],
30885
+ skipAutoConsolidation
30886
+ } = {}) {
30690
30887
  const txCost = await account.getTransactionCost(this, { signatureCallback, quantities });
30691
30888
  this.maxFee = txCost.maxFee;
30692
30889
  this.gasLimit = txCost.gasUsed;
30693
- await account.fund(this, txCost);
30890
+ await account.fund(this, txCost, { skipAutoConsolidation });
30694
30891
  return this;
30695
30892
  }
30696
30893
  /**
@@ -31315,6 +31512,42 @@ ${PANIC_DOC_URL}#variant.${statusReason}`;
31315
31512
  return maxFee;
31316
31513
  }, "calculateTXFeeForSummary");
31317
31514
 
31515
+ // src/providers/transaction-summary/call.ts
31516
+ var getFunctionCall = /* @__PURE__ */ __name(({
31517
+ abi,
31518
+ receipt,
31519
+ offset,
31520
+ scriptData
31521
+ }) => {
31522
+ const [functionSelector, argumentsOffset] = new StdStringCoder().decode(scriptData, offset);
31523
+ const abiInterface = new Interface(abi);
31524
+ const functionFragment = abiInterface.getFunction(functionSelector);
31525
+ const inputs = functionFragment.jsonFn.inputs;
31526
+ let argumentsProvided;
31527
+ if (inputs.length) {
31528
+ const functionArgsBytes = scriptData.slice(argumentsOffset);
31529
+ const decodedArguments = functionFragment.decodeArguments(functionArgsBytes);
31530
+ argumentsProvided = inputs.reduce((prev, input, index) => {
31531
+ const value = decodedArguments?.[index];
31532
+ const name = input.name;
31533
+ if (name) {
31534
+ return {
31535
+ ...prev,
31536
+ // reparse to remove bn
31537
+ [name]: JSON.parse(JSON.stringify(value))
31538
+ };
31539
+ }
31540
+ return prev;
31541
+ }, {});
31542
+ }
31543
+ return {
31544
+ functionSignature: functionFragment.signature,
31545
+ functionName: functionFragment.name,
31546
+ argumentsProvided,
31547
+ ...receipt.amount?.isZero() ? {} : { amount: receipt.amount, assetId: receipt.assetId }
31548
+ };
31549
+ }, "getFunctionCall");
31550
+
31318
31551
  // src/providers/transaction-summary/input.ts
31319
31552
  function getInputsByTypes(inputs, types) {
31320
31553
  return inputs.filter((i) => types.includes(i.type));
@@ -31644,12 +31877,45 @@ ${PANIC_DOC_URL}#variant.${statusReason}`;
31644
31877
  return withdrawFromFuelOperations;
31645
31878
  }
31646
31879
  __name(getWithdrawFromFuelOperations, "getWithdrawFromFuelOperations");
31647
- function getContractCalls(contractInput, abiMap, _receipt, _rawPayload, _maxInputs) {
31880
+ function findBytesSegmentIndex(whole, segment) {
31881
+ for (let i = 0; i <= whole.length - segment.length; i++) {
31882
+ let match = true;
31883
+ for (let j = 0; j < segment.length; j++) {
31884
+ if (whole[i + j] !== segment[j]) {
31885
+ match = false;
31886
+ break;
31887
+ }
31888
+ }
31889
+ if (match) {
31890
+ return i;
31891
+ }
31892
+ }
31893
+ return -1;
31894
+ }
31895
+ __name(findBytesSegmentIndex, "findBytesSegmentIndex");
31896
+ function getContractCalls(contractInput, abiMap, receipt, scriptData) {
31897
+ const calls = [];
31648
31898
  const abi = abiMap?.[contractInput.contractID];
31649
- if (!abi) {
31650
- return [];
31899
+ if (!abi || !scriptData) {
31900
+ return calls;
31901
+ }
31902
+ const bytesSegment = concat([
31903
+ arrayify(receipt.to),
31904
+ // Contract ID (32 bytes)
31905
+ toBytes(receipt.param1.toHex(), 8),
31906
+ // Function selector offset (8 bytes)
31907
+ toBytes(receipt.param2.toHex(), 8)
31908
+ // Function args offset (8 bytes)
31909
+ ]);
31910
+ const segmentIndex = findBytesSegmentIndex(scriptData, bytesSegment);
31911
+ const canDecodeFunctionCall = segmentIndex !== -1;
31912
+ if (!canDecodeFunctionCall) {
31913
+ return calls;
31651
31914
  }
31652
- return [];
31915
+ const offset = segmentIndex + bytesSegment.length;
31916
+ const call = getFunctionCall({ abi, receipt, offset, scriptData });
31917
+ calls.push(call);
31918
+ return calls;
31653
31919
  }
31654
31920
  __name(getContractCalls, "getContractCalls");
31655
31921
  function getAssetsSent(receipt) {
@@ -31661,14 +31927,14 @@ ${PANIC_DOC_URL}#variant.${statusReason}`;
31661
31927
  ];
31662
31928
  }
31663
31929
  __name(getAssetsSent, "getAssetsSent");
31664
- function processCallReceipt(receipt, contractInput, inputs, abiMap, rawPayload, maxInputs, baseAssetId) {
31930
+ function processCallReceipt(receipt, contractInput, inputs, abiMap, scriptData, baseAssetId) {
31665
31931
  const assetId = receipt.assetId === ZeroBytes32 ? baseAssetId : receipt.assetId;
31666
31932
  const input = getInputFromAssetId(inputs, assetId, assetId === baseAssetId);
31667
31933
  if (!input) {
31668
31934
  return [];
31669
31935
  }
31670
31936
  const inputAddress = getInputAccountAddress(input);
31671
- const calls = getContractCalls(contractInput, abiMap, receipt, rawPayload, maxInputs);
31937
+ const calls = getContractCalls(contractInput, abiMap, receipt, scriptData);
31672
31938
  return [
31673
31939
  {
31674
31940
  name: "Contract call" /* contractCall */,
@@ -31693,7 +31959,6 @@ ${PANIC_DOC_URL}#variant.${statusReason}`;
31693
31959
  receipts,
31694
31960
  abiMap,
31695
31961
  rawPayload,
31696
- maxInputs,
31697
31962
  baseAssetId
31698
31963
  }) {
31699
31964
  const contractCallReceipts = getReceiptsCall(receipts);
@@ -31703,16 +31968,15 @@ ${PANIC_DOC_URL}#variant.${statusReason}`;
31703
31968
  if (!contractInput) {
31704
31969
  return [];
31705
31970
  }
31971
+ let scriptData;
31972
+ if (rawPayload) {
31973
+ const [transaction] = new TransactionCoder().decode(arrayify(rawPayload), 0);
31974
+ if (transaction.type === TransactionType.Script) {
31975
+ scriptData = arrayify(transaction.scriptData);
31976
+ }
31977
+ }
31706
31978
  return contractCallReceipts.filter((receipt) => receipt.to === contractInput.contractID).flatMap(
31707
- (receipt) => processCallReceipt(
31708
- receipt,
31709
- contractInput,
31710
- inputs,
31711
- abiMap,
31712
- rawPayload,
31713
- maxInputs,
31714
- baseAssetId
31715
- )
31979
+ (receipt) => processCallReceipt(receipt, contractInput, inputs, abiMap, scriptData, baseAssetId)
31716
31980
  );
31717
31981
  });
31718
31982
  }
@@ -32205,25 +32469,6 @@ ${PANIC_DOC_URL}#variant.${statusReason}`;
32205
32469
 
32206
32470
  // src/providers/transaction-response/transaction-response.ts
32207
32471
  var TransactionResponse = class _TransactionResponse {
32208
- /**
32209
- * Constructor for `TransactionResponse`.
32210
- *
32211
- * @param tx - The transaction ID or TransactionRequest.
32212
- * @param provider - The provider.
32213
- */
32214
- constructor(tx, provider, chainId, abis, submitTxSubscription) {
32215
- this.submitTxSubscription = submitTxSubscription;
32216
- if (typeof tx === "string") {
32217
- this.id = tx;
32218
- } else {
32219
- this.id = tx.getTransactionId(chainId);
32220
- this.request = tx;
32221
- }
32222
- this.provider = provider;
32223
- this.abis = abis;
32224
- this.waitForResult = this.waitForResult.bind(this);
32225
- this.waitForPreConfirmation = this.waitForPreConfirmation.bind(this);
32226
- }
32227
32472
  static {
32228
32473
  __name(this, "TransactionResponse");
32229
32474
  }
@@ -32238,9 +32483,42 @@ ${PANIC_DOC_URL}#variant.${statusReason}`;
32238
32483
  request;
32239
32484
  status;
32240
32485
  abis;
32486
+ submitTxSubscription;
32241
32487
  preConfirmationStatus;
32242
32488
  waitingForStreamData = false;
32243
32489
  statusResolvers = /* @__PURE__ */ new Map();
32490
+ /**
32491
+ * Constructor for `TransactionResponse`.
32492
+ */
32493
+ constructor(constructorParams, provider, chainId, abis, submitTxSubscription) {
32494
+ let tx;
32495
+ let _provider;
32496
+ let _chainId;
32497
+ let _abis;
32498
+ if (typeof constructorParams === "object" && "provider" in constructorParams && arguments.length === 1) {
32499
+ tx = constructorParams.transactionRequestOrId;
32500
+ _provider = constructorParams.provider;
32501
+ _chainId = constructorParams.chainId;
32502
+ _abis = constructorParams.abis;
32503
+ this.submitTxSubscription = constructorParams.submitAndAwaitSubscription;
32504
+ } else {
32505
+ tx = constructorParams;
32506
+ _provider = provider;
32507
+ _chainId = chainId;
32508
+ _abis = abis;
32509
+ this.submitTxSubscription = submitTxSubscription;
32510
+ }
32511
+ if (typeof tx === "string") {
32512
+ this.id = tx;
32513
+ } else {
32514
+ this.id = tx.getTransactionId(_chainId);
32515
+ this.request = tx;
32516
+ }
32517
+ this.provider = _provider;
32518
+ this.abis = _abis;
32519
+ this.waitForResult = this.waitForResult.bind(this);
32520
+ this.waitForPreConfirmation = this.waitForPreConfirmation.bind(this);
32521
+ }
32244
32522
  /**
32245
32523
  * Async constructor for `TransactionResponse`. This method can be used to create
32246
32524
  * an instance of `TransactionResponse` and wait for the transaction to be fetched
@@ -32477,6 +32755,7 @@ ${PANIC_DOC_URL}#variant.${statusReason}`;
32477
32755
  ...transactionSummary
32478
32756
  };
32479
32757
  let { logs, groupedLogs } = { logs: [], groupedLogs: {} };
32758
+ let abis;
32480
32759
  if (this.abis) {
32481
32760
  ({ logs, groupedLogs } = getAllDecodedLogs({
32482
32761
  receipts: transactionSummary.receipts,
@@ -32485,6 +32764,7 @@ ${PANIC_DOC_URL}#variant.${statusReason}`;
32485
32764
  }));
32486
32765
  transactionResult.logs = logs;
32487
32766
  transactionResult.groupedLogs = groupedLogs;
32767
+ abis = this.abis;
32488
32768
  }
32489
32769
  const { receipts } = transactionResult;
32490
32770
  const status = this.getTransactionStatus();
@@ -32494,7 +32774,8 @@ ${PANIC_DOC_URL}#variant.${statusReason}`;
32494
32774
  receipts,
32495
32775
  statusReason: reason,
32496
32776
  logs,
32497
- groupedLogs
32777
+ groupedLogs,
32778
+ abis
32498
32779
  });
32499
32780
  }
32500
32781
  return transactionResult;
@@ -32772,7 +33053,15 @@ ${PANIC_DOC_URL}#variant.${statusReason}`;
32772
33053
  if (_Provider.ENABLE_RPC_CONSISTENCY && _Provider.hasWriteOperationHappened(url)) {
32773
33054
  _Provider.applyBlockHeight(fullRequest, url);
32774
33055
  }
32775
- return _Provider.fetchAndProcessBlockHeight(url, fullRequest, options);
33056
+ const response = await _Provider.fetchAndProcessBlockHeight(url, fullRequest, options);
33057
+ if (response.body === null) {
33058
+ throw new FuelError(
33059
+ ErrorCode.RESPONSE_BODY_EMPTY,
33060
+ "The response from the server is missing the body",
33061
+ { timestamp: (/* @__PURE__ */ new Date()).toISOString(), request: request2, response }
33062
+ );
33063
+ }
33064
+ return response;
32776
33065
  }, retryOptions);
32777
33066
  }
32778
33067
  static applyBlockHeight(request2, url) {
@@ -32795,13 +33084,15 @@ ${PANIC_DOC_URL}#variant.${statusReason}`;
32795
33084
  baseDelay: 500
32796
33085
  };
32797
33086
  for (let retriesLeft = retryOptions.maxRetries; retriesLeft > 0; --retriesLeft) {
32798
- const { extensions } = await parseGraphqlResponse({
32799
- response,
32800
- isSubscription: url.endsWith("-sub")
32801
- });
32802
- _Provider.setCurrentBlockHeight(url, extensions?.current_fuel_block_height);
32803
- if (!extensions?.fuel_block_height_precondition_failed) {
32804
- break;
33087
+ if (response.body) {
33088
+ const { extensions } = await parseGraphqlResponse({
33089
+ response,
33090
+ isSubscription: url.endsWith("-sub")
33091
+ });
33092
+ _Provider.setCurrentBlockHeight(url, extensions?.current_fuel_block_height);
33093
+ if (!extensions?.fuel_block_height_precondition_failed) {
33094
+ break;
33095
+ }
32805
33096
  }
32806
33097
  const retryAttempt = retryOptions.maxRetries - retriesLeft + 1;
32807
33098
  const sleepTime = getWaitDelay(retryOptions, retryAttempt);
@@ -33224,7 +33515,13 @@ ${PANIC_DOC_URL}#variant.${statusReason}`;
33224
33515
  transactionRequest.getTransactionId(await this.getChainId())
33225
33516
  );
33226
33517
  const chainId = await this.getChainId();
33227
- return new TransactionResponse(transactionRequest, this, chainId, abis, subscription);
33518
+ return new TransactionResponse({
33519
+ transactionRequestOrId: transactionRequest,
33520
+ provider: this,
33521
+ chainId,
33522
+ abis,
33523
+ submitAndAwaitSubscription: subscription
33524
+ });
33228
33525
  }
33229
33526
  /**
33230
33527
  * Executes a transaction without actually submitting it to the chain.
@@ -34319,7 +34616,11 @@ ${PANIC_DOC_URL}#variant.${statusReason}`;
34319
34616
  */
34320
34617
  async getTransactionResponse(transactionId) {
34321
34618
  const chainId = await this.getChainId();
34322
- return new TransactionResponse(transactionId, this, chainId);
34619
+ return new TransactionResponse({
34620
+ transactionRequestOrId: transactionId,
34621
+ provider: this,
34622
+ chainId
34623
+ });
34323
34624
  }
34324
34625
  /**
34325
34626
  * Returns Message for given nonce.
@@ -34370,18 +34671,21 @@ ${PANIC_DOC_URL}#variant.${statusReason}`;
34370
34671
  extractDryRunError(transactionRequest, receipts, reason) {
34371
34672
  let logs = [];
34372
34673
  let groupedLogs = {};
34674
+ let abis;
34373
34675
  if (transactionRequest.type === TransactionType.Script && transactionRequest.abis) {
34374
34676
  ({ logs, groupedLogs } = getAllDecodedLogs({
34375
34677
  receipts,
34376
34678
  mainAbi: transactionRequest.abis.main,
34377
34679
  externalAbis: transactionRequest.abis.otherContractsAbis
34378
34680
  }));
34681
+ abis = transactionRequest.abis;
34379
34682
  }
34380
34683
  return extractTxError({
34381
34684
  logs,
34382
34685
  groupedLogs,
34383
34686
  receipts,
34384
- statusReason: reason
34687
+ statusReason: reason,
34688
+ abis
34385
34689
  });
34386
34690
  }
34387
34691
  /**
@@ -34640,7 +34944,12 @@ ${PANIC_DOC_URL}#variant.${statusReason}`;
34640
34944
  } = json;
34641
34945
  const provider = new Provider(providerUrl, { cache: providerCache });
34642
34946
  const { chainId } = providerCache.chain.consensusParameters;
34643
- const response = new TransactionResponse(id, provider, Number(chainId), abis);
34947
+ const response = new TransactionResponse({
34948
+ transactionRequestOrId: id,
34949
+ provider,
34950
+ chainId: Number(chainId),
34951
+ abis
34952
+ });
34644
34953
  if (requestJson) {
34645
34954
  response.request = transactionRequestify(JSON.parse(requestJson));
34646
34955
  }
@@ -34657,6 +34966,149 @@ ${PANIC_DOC_URL}#variant.${statusReason}`;
34657
34966
  }
34658
34967
  };
34659
34968
 
34969
+ // src/utils/consolidate-coins.ts
34970
+ var CONSOLIDATABLE_ERROR_CODES = [ErrorCode.MAX_COINS_REACHED];
34971
+ var consolidateCoinsIfRequired = /* @__PURE__ */ __name(async (opts) => {
34972
+ const { error: errorUnknown, account, skipAutoConsolidation = false } = opts;
34973
+ if (skipAutoConsolidation) {
34974
+ return false;
34975
+ }
34976
+ const error2 = FuelError.parse(errorUnknown);
34977
+ if (CONSOLIDATABLE_ERROR_CODES.includes(error2.code)) {
34978
+ const { assetId, owner } = error2.metadata;
34979
+ return account.startConsolidation({
34980
+ owner,
34981
+ assetId
34982
+ });
34983
+ }
34984
+ return false;
34985
+ }, "consolidateCoinsIfRequired");
34986
+ var getAllCoins = /* @__PURE__ */ __name(async (account, assetId) => {
34987
+ const all = [];
34988
+ let hasNextPage = true;
34989
+ let after;
34990
+ while (hasNextPage) {
34991
+ const { coins, pageInfo } = await account.getCoins(assetId, { after });
34992
+ all.push(...coins);
34993
+ after = coins.pop()?.id;
34994
+ hasNextPage = pageInfo.hasNextPage;
34995
+ }
34996
+ return { coins: all };
34997
+ }, "getAllCoins");
34998
+ var sortCoins = /* @__PURE__ */ __name(({ coins }) => coins.sort((a, b) => b.amount.cmp(a.amount)), "sortCoins");
34999
+ var createOuputCoin = /* @__PURE__ */ __name((opts) => {
35000
+ const { transactionId, outputs, baseAssetId } = opts;
35001
+ const outputChangeIndex = outputs.findIndex(
35002
+ (output) => output.type === OutputType.Change && output.assetId === baseAssetId
35003
+ );
35004
+ if (outputChangeIndex === -1) {
35005
+ throw new FuelError(ErrorCode.UNKNOWN, "No change output found");
35006
+ }
35007
+ const outputCoin = outputs[outputChangeIndex];
35008
+ const outputIndexPadded = Number(outputChangeIndex).toString().padStart(4, "0");
35009
+ return {
35010
+ id: `${transactionId}${outputIndexPadded}`,
35011
+ assetId: outputCoin.assetId,
35012
+ amount: outputCoin.amount,
35013
+ owner: new Address(outputCoin.to),
35014
+ blockCreated: bn(0),
35015
+ txCreatedIdx: bn(0)
35016
+ };
35017
+ }, "createOuputCoin");
35018
+ var consolidateCoins = /* @__PURE__ */ __name(async ({
35019
+ account,
35020
+ assetId
35021
+ }) => {
35022
+ const chainInfo = await account.provider.getChain();
35023
+ const chainId = chainInfo.consensusParameters.chainId.toNumber();
35024
+ const gasPrice = await account.provider.estimateGasPrice(10);
35025
+ const maxInputs = chainInfo.consensusParameters.txParameters.maxInputs.toNumber();
35026
+ const baseAssetId = await account.provider.getBaseAssetId();
35027
+ const isBaseAsset = assetId === baseAssetId;
35028
+ const batchSize = maxInputs;
35029
+ const numberOfFundingCoins = maxInputs;
35030
+ let funding = [];
35031
+ let dust = [];
35032
+ if (isBaseAsset) {
35033
+ const coins = await getAllCoins(account, baseAssetId).then(sortCoins);
35034
+ funding = coins.slice(0, numberOfFundingCoins);
35035
+ dust = coins.slice(numberOfFundingCoins);
35036
+ } else {
35037
+ funding = await getAllCoins(account, baseAssetId).then(sortCoins).then((coins) => coins.slice(0, numberOfFundingCoins));
35038
+ dust = await getAllCoins(account, assetId).then(({ coins }) => coins);
35039
+ }
35040
+ if (funding.length === 0) {
35041
+ throw new FuelError(
35042
+ ErrorCode.INSUFFICIENT_FUNDS,
35043
+ `Insufficient funds to consolidate.
35044
+ Asset ID: ${baseAssetId}
35045
+ Owner: ${account.address.toB256()}`
35046
+ );
35047
+ }
35048
+ const batches = [
35049
+ ...splitEvery_default(batchSize, funding),
35050
+ // We leave one coin for the funding coin
35051
+ ...splitEvery_default(batchSize - 1, dust)
35052
+ ];
35053
+ const txs = batches.map((batch) => {
35054
+ const request2 = new ScriptTransactionRequest({
35055
+ scriptData: "0x"
35056
+ });
35057
+ request2.addResources(batch);
35058
+ return request2;
35059
+ });
35060
+ const submitAll = /* @__PURE__ */ __name(async (opts = {}) => {
35061
+ const txResponses = [];
35062
+ let previousTx;
35063
+ for (let i = 0; i < txs.length; i++) {
35064
+ let currentTx = txs[i];
35065
+ const step = i + 1;
35066
+ if (previousTx) {
35067
+ const coin = createOuputCoin({
35068
+ transactionId: previousTx.transactionId,
35069
+ outputs: previousTx.outputs,
35070
+ baseAssetId
35071
+ });
35072
+ currentTx.addResource(coin);
35073
+ }
35074
+ if ("populateTransactionPredicateData" in account && typeof account.populateTransactionPredicateData === "function") {
35075
+ currentTx = account.populateTransactionPredicateData(currentTx);
35076
+ currentTx = await account.provider.estimatePredicates(currentTx);
35077
+ }
35078
+ const fee = calculateGasFee({
35079
+ gasPrice,
35080
+ gas: currentTx.calculateMinGas(chainInfo),
35081
+ priceFactor: chainInfo.consensusParameters.feeParameters.gasPriceFactor,
35082
+ tip: currentTx.tip
35083
+ });
35084
+ currentTx.maxFee = fee;
35085
+ currentTx.gasLimit = bn(1e3);
35086
+ opts.onTransactionStart?.({
35087
+ tx: currentTx,
35088
+ step,
35089
+ assetId,
35090
+ transactionId: currentTx.getTransactionId(chainId)
35091
+ });
35092
+ const response = await account.sendTransaction(currentTx);
35093
+ const result = await response.waitForResult();
35094
+ txResponses.push(result);
35095
+ previousTx = {
35096
+ transactionId: response.id,
35097
+ outputs: result.transaction.outputs
35098
+ };
35099
+ }
35100
+ return {
35101
+ txResponses,
35102
+ errors: []
35103
+ };
35104
+ }, "submitAll");
35105
+ return {
35106
+ txs,
35107
+ totalFeeCost: txs.reduce((acc, request2) => acc.add(request2.maxFee), bn(0)),
35108
+ submitAll
35109
+ };
35110
+ }, "consolidateCoins");
35111
+
34660
35112
  // src/utils/formatTransferToContractScriptData.ts
34661
35113
  var asm = __toESM(require_node());
34662
35114
  var formatTransferToContractScriptData = /* @__PURE__ */ __name((transferParams) => {
@@ -34773,10 +35225,24 @@ ${PANIC_DOC_URL}#variant.${statusReason}`;
34773
35225
  *
34774
35226
  * @param quantities - Quantities of resources to be obtained.
34775
35227
  * @param resourcesIdsToIgnore - IDs of resources to be excluded from the query (optional).
35228
+ * @param skipAutoConsolidation - Whether to skip the automatic consolidatation of coins process (optional).
34776
35229
  * @returns A promise that resolves to an array of Resources.
34777
35230
  */
34778
- async getResourcesToSpend(quantities, resourcesIdsToIgnore) {
34779
- return this.provider.getResourcesToSpend(this.address, quantities, resourcesIdsToIgnore);
35231
+ async getResourcesToSpend(quantities, resourcesIdsToIgnore, { skipAutoConsolidation } = {}) {
35232
+ const getResourcesToSpend = /* @__PURE__ */ __name(() => this.provider.getResourcesToSpend(this.address, quantities, resourcesIdsToIgnore), "getResourcesToSpend");
35233
+ try {
35234
+ return await getResourcesToSpend();
35235
+ } catch (error2) {
35236
+ const shouldRetry = await consolidateCoinsIfRequired({
35237
+ error: error2,
35238
+ account: this,
35239
+ skipAutoConsolidation
35240
+ });
35241
+ if (!shouldRetry) {
35242
+ throw error2;
35243
+ }
35244
+ return await getResourcesToSpend();
35245
+ }
34780
35246
  }
34781
35247
  /**
34782
35248
  * Retrieves coins owned by the account.
@@ -34825,7 +35291,7 @@ ${PANIC_DOC_URL}#variant.${statusReason}`;
34825
35291
  * @deprecated Use provider.assembleTx instead
34826
35292
  * Check the migration guide https://docs.fuel.network/docs/fuels-ts/transactions/assemble-tx-migration-guide/ for more information.
34827
35293
  */
34828
- async fund(request2, params) {
35294
+ async fund(request2, params, { skipAutoConsolidation } = {}) {
34829
35295
  const {
34830
35296
  addedSignatures,
34831
35297
  estimatedPredicates,
@@ -34871,7 +35337,8 @@ ${PANIC_DOC_URL}#variant.${statusReason}`;
34871
35337
  while (needsToBeFunded && fundingAttempts < MAX_FUNDING_ATTEMPTS) {
34872
35338
  const resources = await this.getResourcesToSpend(
34873
35339
  missingQuantities,
34874
- cacheRequestInputsResourcesFromOwner(request2.inputs, this.address)
35340
+ cacheRequestInputsResourcesFromOwner(request2.inputs, this.address),
35341
+ { skipAutoConsolidation }
34875
35342
  );
34876
35343
  request2.addResources(resources);
34877
35344
  request2.updatePredicateGasUsed(estimatedPredicates);
@@ -34909,7 +35376,7 @@ ${PANIC_DOC_URL}#variant.${statusReason}`;
34909
35376
  }
34910
35377
  if (needsToBeFunded) {
34911
35378
  throw new FuelError(
34912
- ErrorCode.INSUFFICIENT_FUNDS_OR_MAX_COINS,
35379
+ ErrorCode.INSUFFICIENT_FUNDS,
34913
35380
  `The account ${this.address} does not have enough base asset funds to cover the transaction execution.`
34914
35381
  );
34915
35382
  }
@@ -34937,16 +35404,20 @@ ${PANIC_DOC_URL}#variant.${statusReason}`;
34937
35404
  * @param amount - The amount of coins to transfer.
34938
35405
  * @param assetId - The asset ID of the coins to transfer (optional).
34939
35406
  * @param txParams - The transaction parameters (optional).
35407
+ * @param skipAutoConsolidation - Whether to skip the automatic consolidatation of coins process (optional).
34940
35408
  * @returns A promise that resolves to the prepared transaction request.
34941
35409
  */
34942
- async createTransfer(destination, amount, assetId, txParams = {}) {
35410
+ async createTransfer(destination, amount, assetId, txParams = {}, { skipAutoConsolidation } = {}) {
34943
35411
  let request2 = new ScriptTransactionRequest(txParams);
34944
35412
  request2 = this.addTransfer(request2, {
34945
35413
  destination,
34946
35414
  amount,
34947
35415
  assetId: assetId || await this.provider.getBaseAssetId()
34948
35416
  });
34949
- const { gasPrice, transactionRequest } = await this.assembleTx(request2);
35417
+ const { gasPrice, transactionRequest } = await this.assembleTx({
35418
+ transactionRequest: request2,
35419
+ skipAutoConsolidation
35420
+ });
34950
35421
  request2 = await setAndValidateGasAndFeeForAssembledTx({
34951
35422
  gasPrice,
34952
35423
  provider: this.provider,
@@ -34963,10 +35434,13 @@ ${PANIC_DOC_URL}#variant.${statusReason}`;
34963
35434
  * @param amount - The amount of coins to transfer.
34964
35435
  * @param assetId - The asset ID of the coins to transfer (optional).
34965
35436
  * @param txParams - The transaction parameters (optional).
35437
+ * @param skipAutoConsolidation - Whether to skip the automatic consolidatation of coins process (optional).
34966
35438
  * @returns A promise that resolves to the transaction response.
34967
35439
  */
34968
- async transfer(destination, amount, assetId, txParams = {}) {
34969
- const request2 = await this.createTransfer(destination, amount, assetId, txParams);
35440
+ async transfer(destination, amount, assetId, txParams = {}, { skipAutoConsolidation } = {}) {
35441
+ const request2 = await this.createTransfer(destination, amount, assetId, txParams, {
35442
+ skipAutoConsolidation
35443
+ });
34970
35444
  return this.sendTransaction(request2, { estimateTxDependencies: false });
34971
35445
  }
34972
35446
  /**
@@ -34974,12 +35448,16 @@ ${PANIC_DOC_URL}#variant.${statusReason}`;
34974
35448
  *
34975
35449
  * @param transferParams - An array of `TransferParams` objects representing the transfers to be made.
34976
35450
  * @param txParams - Optional transaction parameters.
35451
+ * @param skipAutoConsolidation - Whether to skip the automatic consolidatation of coins process (optional).
34977
35452
  * @returns A promise that resolves to a `TransactionResponse` object representing the transaction result.
34978
35453
  */
34979
- async batchTransfer(transferParams, txParams = {}) {
35454
+ async batchTransfer(transferParams, txParams = {}, { skipAutoConsolidation } = {}) {
34980
35455
  let request2 = new ScriptTransactionRequest(txParams);
34981
35456
  request2 = this.addBatchTransfer(request2, transferParams);
34982
- const { gasPrice, transactionRequest } = await this.assembleTx(request2);
35457
+ const { gasPrice, transactionRequest } = await this.assembleTx({
35458
+ transactionRequest: request2,
35459
+ skipAutoConsolidation
35460
+ });
34983
35461
  request2 = await setAndValidateGasAndFeeForAssembledTx({
34984
35462
  gasPrice,
34985
35463
  provider: this.provider,
@@ -35026,12 +35504,15 @@ ${PANIC_DOC_URL}#variant.${statusReason}`;
35026
35504
  * @param amount - The amount of coins to transfer.
35027
35505
  * @param assetId - The asset ID of the coins to transfer (optional).
35028
35506
  * @param txParams - The transaction parameters (optional).
35507
+ * @param skipAutoConsolidation - Whether to skip the automatic consolidatation of coins process (optional).
35029
35508
  * @returns A promise that resolves to the transaction response.
35030
35509
  */
35031
- async transferToContract(contractId, amount, assetId, txParams = {}) {
35032
- return this.batchTransferToContracts([{ amount, assetId, contractId }], txParams);
35510
+ async transferToContract(contractId, amount, assetId, txParams = {}, { skipAutoConsolidation } = {}) {
35511
+ return this.batchTransferToContracts([{ amount, assetId, contractId }], txParams, {
35512
+ skipAutoConsolidation
35513
+ });
35033
35514
  }
35034
- async batchTransferToContracts(contractTransferParams, txParams = {}) {
35515
+ async batchTransferToContracts(contractTransferParams, txParams = {}, { skipAutoConsolidation } = {}) {
35035
35516
  let request2 = new ScriptTransactionRequest({
35036
35517
  ...txParams
35037
35518
  });
@@ -35058,7 +35539,11 @@ ${PANIC_DOC_URL}#variant.${statusReason}`;
35058
35539
  const { script, scriptData } = await assembleTransferToContractScript(transferParams);
35059
35540
  request2.script = script;
35060
35541
  request2.scriptData = scriptData;
35061
- const { gasPrice, transactionRequest } = await this.assembleTx(request2, quantities);
35542
+ const { gasPrice, transactionRequest } = await this.assembleTx({
35543
+ transactionRequest: request2,
35544
+ quantities,
35545
+ skipAutoConsolidation
35546
+ });
35062
35547
  request2 = await setAndValidateGasAndFeeForAssembledTx({
35063
35548
  gasPrice,
35064
35549
  provider: this.provider,
@@ -35074,9 +35559,10 @@ ${PANIC_DOC_URL}#variant.${statusReason}`;
35074
35559
  * @param recipient - Address of the recipient on the base chain.
35075
35560
  * @param amount - Amount of base asset.
35076
35561
  * @param txParams - The transaction parameters (optional).
35562
+ * @param skipAutoConsolidation - Whether to skip the automatic consolidatation of coins process (optional).
35077
35563
  * @returns A promise that resolves to the transaction response.
35078
35564
  */
35079
- async withdrawToBaseLayer(recipient, amount, txParams = {}) {
35565
+ async withdrawToBaseLayer(recipient, amount, txParams = {}, { skipAutoConsolidation } = {}) {
35080
35566
  const recipientAddress = new Address(recipient);
35081
35567
  const recipientDataArray = arrayify(
35082
35568
  "0x".concat(recipientAddress.toHexString().substring(2).padStart(64, "0"))
@@ -35093,7 +35579,11 @@ ${PANIC_DOC_URL}#variant.${statusReason}`;
35093
35579
  const baseAssetId = await this.provider.getBaseAssetId();
35094
35580
  let request2 = new ScriptTransactionRequest(params);
35095
35581
  const quantities = [{ amount: bn(amount), assetId: baseAssetId }];
35096
- const { gasPrice, transactionRequest } = await this.assembleTx(request2, quantities);
35582
+ const { gasPrice, transactionRequest } = await this.assembleTx({
35583
+ transactionRequest: request2,
35584
+ quantities,
35585
+ skipAutoConsolidation
35586
+ });
35097
35587
  request2 = await setAndValidateGasAndFeeForAssembledTx({
35098
35588
  gasPrice,
35099
35589
  provider: this.provider,
@@ -35103,6 +35593,25 @@ ${PANIC_DOC_URL}#variant.${statusReason}`;
35103
35593
  });
35104
35594
  return this.sendTransaction(request2);
35105
35595
  }
35596
+ /**
35597
+ * Start the consolidation process
35598
+ *
35599
+ * @param owner - The B256 address of the owner.
35600
+ * @param assetId - The asset ID that requires consolidation.
35601
+ */
35602
+ async startConsolidation(opts) {
35603
+ if (this._connector) {
35604
+ await this._connector.startConsolidation(opts);
35605
+ return false;
35606
+ }
35607
+ const { owner, assetId } = opts;
35608
+ if (owner !== this.address.toB256()) {
35609
+ return false;
35610
+ }
35611
+ const { submitAll } = await consolidateCoins({ account: this, assetId });
35612
+ await submitAll();
35613
+ return true;
35614
+ }
35106
35615
  /**
35107
35616
  * Consolidates base asset UTXOs into fewer, larger ones.
35108
35617
  *
@@ -35122,6 +35631,7 @@ ${PANIC_DOC_URL}#variant.${statusReason}`;
35122
35631
  const isBaseAsset = baseAssetId === assetId;
35123
35632
  let submitAll;
35124
35633
  const consolidationParams = {
35634
+ assetId,
35125
35635
  coins,
35126
35636
  mode: params.mode,
35127
35637
  outputNum: params.outputNum
@@ -35129,10 +35639,7 @@ ${PANIC_DOC_URL}#variant.${statusReason}`;
35129
35639
  if (isBaseAsset) {
35130
35640
  ({ submitAll } = await this.assembleBaseAssetConsolidationTxs(consolidationParams));
35131
35641
  } else {
35132
- throw new FuelError(
35133
- ErrorCode.UNSUPPORTED_FEATURE,
35134
- "Consolidation for non-base assets is not supported yet."
35135
- );
35642
+ ({ submitAll } = await this.assembleNonBaseAssetConsolidationTxs(consolidationParams));
35136
35643
  }
35137
35644
  return submitAll();
35138
35645
  }
@@ -35191,6 +35698,70 @@ ${PANIC_DOC_URL}#variant.${statusReason}`;
35191
35698
  const submitAll = this.prepareSubmitAll({ txs, mode });
35192
35699
  return { txs, totalFeeCost, submitAll };
35193
35700
  }
35701
+ async assembleNonBaseAssetConsolidationTxs(params) {
35702
+ const { assetId, coins, mode = "parallel", outputNum = 1 } = params;
35703
+ this.validateConsolidationTxsCoins(coins, assetId);
35704
+ const chainInfo = await this.provider.getChain();
35705
+ const maxInputsNumber = chainInfo.consensusParameters.txParameters.maxInputs.toNumber();
35706
+ const baseAssetId = chainInfo.consensusParameters.baseAssetId;
35707
+ const { coins: baseAssetCoins } = await this.provider.getCoins(this.address, baseAssetId);
35708
+ let totalFeeCost = bn(0);
35709
+ const txs = [];
35710
+ const gasPrice = await this.provider.estimateGasPrice(10);
35711
+ const consolidateMoreThanOneCoin = outputNum > 1;
35712
+ const assetCoinBatches = splitCoinsIntoBatches(coins, maxInputsNumber);
35713
+ assetCoinBatches.filter((batch) => batch.length > 1).forEach((coinBatch) => {
35714
+ const request2 = new ScriptTransactionRequest({
35715
+ script: "0x"
35716
+ });
35717
+ request2.addResources(coinBatch);
35718
+ if (consolidateMoreThanOneCoin) {
35719
+ Array.from({ length: outputNum - 1 }).forEach(() => {
35720
+ request2.addCoinOutput(this.address, 0, assetId);
35721
+ });
35722
+ }
35723
+ const minGas = request2.calculateMinGas(chainInfo);
35724
+ const fee = calculateGasFee({
35725
+ gasPrice,
35726
+ gas: minGas,
35727
+ priceFactor: chainInfo.consensusParameters.feeParameters.gasPriceFactor,
35728
+ tip: request2.tip
35729
+ });
35730
+ request2.maxFee = fee;
35731
+ if (consolidateMoreThanOneCoin) {
35732
+ const total = request2.inputs.filter(isRequestInputCoin).reduce((acc, input) => acc.add(input.amount), bn(0));
35733
+ const amountPerNewUtxo = total.div(outputNum + 1);
35734
+ request2.outputs.forEach((output) => {
35735
+ if (output.type === OutputType.Coin) {
35736
+ output.amount = amountPerNewUtxo;
35737
+ }
35738
+ });
35739
+ }
35740
+ totalFeeCost = totalFeeCost.add(fee);
35741
+ const baseAssetResources = [];
35742
+ let fundingFeeTotal = bn(0);
35743
+ while (fundingFeeTotal.lt(fee)) {
35744
+ const baseAssetCoin = baseAssetCoins.pop();
35745
+ if (!baseAssetCoin) {
35746
+ break;
35747
+ }
35748
+ baseAssetResources.push(baseAssetCoin);
35749
+ fundingFeeTotal = fundingFeeTotal.add(baseAssetCoin.amount);
35750
+ }
35751
+ const { inputs } = request2;
35752
+ request2.inputs = inputs.slice(0, maxInputsNumber - baseAssetResources.length);
35753
+ const removedCoins = coinBatch.slice(maxInputsNumber - baseAssetResources.length);
35754
+ request2.addResources(baseAssetResources);
35755
+ const lastCoinBatch = assetCoinBatches[assetCoinBatches.length - 1];
35756
+ lastCoinBatch.push(...removedCoins);
35757
+ if (lastCoinBatch.length > maxInputsNumber) {
35758
+ assetCoinBatches.push(lastCoinBatch.slice(maxInputsNumber));
35759
+ }
35760
+ txs.push(request2);
35761
+ });
35762
+ const submitAll = this.prepareSubmitAll({ txs, mode });
35763
+ return { txs, totalFeeCost, submitAll };
35764
+ }
35194
35765
  /**
35195
35766
  * Prepares a function to submit all transactions either sequentially or in parallel.
35196
35767
  *
@@ -35405,16 +35976,32 @@ ${PANIC_DOC_URL}#variant.${statusReason}`;
35405
35976
  } : void 0;
35406
35977
  }
35407
35978
  /** @hidden * */
35408
- async assembleTx(transactionRequest, quantities = []) {
35979
+ async assembleTx(opts) {
35980
+ const { transactionRequest, quantities = [], skipAutoConsolidation } = opts;
35409
35981
  const outputQuantities = transactionRequest.outputs.filter((o) => o.type === OutputType.Coin).map(({ amount, assetId }) => ({ assetId: String(assetId), amount: bn(amount) }));
35410
35982
  transactionRequest.gasLimit = bn(0);
35411
35983
  transactionRequest.maxFee = bn(0);
35412
- const { assembledRequest, gasPrice } = await this.provider.assembleTx({
35413
- request: transactionRequest,
35414
- accountCoinQuantities: mergeQuantities(outputQuantities, quantities),
35415
- feePayerAccount: this
35416
- });
35417
- return { transactionRequest: assembledRequest, gasPrice };
35984
+ const assembleTx = /* @__PURE__ */ __name(async () => {
35985
+ const { assembledRequest, gasPrice } = await this.provider.assembleTx({
35986
+ request: transactionRequest,
35987
+ accountCoinQuantities: mergeQuantities(outputQuantities, quantities),
35988
+ feePayerAccount: this
35989
+ });
35990
+ return { transactionRequest: assembledRequest, gasPrice };
35991
+ }, "assembleTx");
35992
+ try {
35993
+ return await assembleTx();
35994
+ } catch (error2) {
35995
+ const shouldRetry = await consolidateCoinsIfRequired({
35996
+ error: error2,
35997
+ account: this,
35998
+ skipAutoConsolidation
35999
+ });
36000
+ if (!shouldRetry) {
36001
+ throw error2;
36002
+ }
36003
+ return await assembleTx();
36004
+ }
35418
36005
  }
35419
36006
  /** @hidden * */
35420
36007
  validateTransferAmount(amount) {
@@ -35426,45 +36013,6 @@ ${PANIC_DOC_URL}#variant.${statusReason}`;
35426
36013
  }
35427
36014
  }
35428
36015
  /** @hidden * */
35429
- async estimateAndFundTransaction(transactionRequest, txParams, costParams) {
35430
- let request2 = transactionRequest;
35431
- const txCost = await this.getTransactionCost(request2, costParams);
35432
- request2 = this.validateGasLimitAndMaxFee({
35433
- transactionRequest: request2,
35434
- gasUsed: txCost.gasUsed,
35435
- maxFee: txCost.maxFee,
35436
- txParams
35437
- });
35438
- request2 = await this.fund(request2, txCost);
35439
- return request2;
35440
- }
35441
- /** @hidden * */
35442
- validateGasLimitAndMaxFee({
35443
- gasUsed,
35444
- maxFee,
35445
- transactionRequest,
35446
- txParams: { gasLimit: setGasLimit, maxFee: setMaxFee }
35447
- }) {
35448
- const request2 = transactionRequestify(transactionRequest);
35449
- if (!isDefined(setGasLimit)) {
35450
- request2.gasLimit = gasUsed;
35451
- } else if (gasUsed.gt(setGasLimit)) {
35452
- throw new FuelError(
35453
- ErrorCode.GAS_LIMIT_TOO_LOW,
35454
- `Gas limit '${setGasLimit}' is lower than the required: '${gasUsed}'.`
35455
- );
35456
- }
35457
- if (!isDefined(setMaxFee)) {
35458
- request2.maxFee = maxFee;
35459
- } else if (maxFee.gt(setMaxFee)) {
35460
- throw new FuelError(
35461
- ErrorCode.MAX_FEE_TOO_LOW,
35462
- `Max fee '${setMaxFee}' is lower than the required: '${maxFee}'.`
35463
- );
35464
- }
35465
- return request2;
35466
- }
35467
- /** @hidden * */
35468
36016
  validateConsolidationTxsCoins(coins, assetId) {
35469
36017
  if (coins.length <= 1) {
35470
36018
  throw new FuelError(ErrorCode.NO_COINS_TO_CONSOLIDATE, "No coins to consolidate.");
@@ -41705,6 +42253,7 @@ ${PANIC_DOC_URL}#variant.${statusReason}`;
41705
42253
  FuelConnectorMethods2["addABI"] = "addABI";
41706
42254
  FuelConnectorMethods2["getABI"] = "getABI";
41707
42255
  FuelConnectorMethods2["hasABI"] = "hasABI";
42256
+ FuelConnectorMethods2["startConsolidation"] = "startConsolidation";
41708
42257
  return FuelConnectorMethods2;
41709
42258
  })(FuelConnectorMethods || {});
41710
42259
  var FuelConnectorEventTypes = /* @__PURE__ */ ((FuelConnectorEventTypes2) => {
@@ -41717,6 +42266,7 @@ ${PANIC_DOC_URL}#variant.${statusReason}`;
41717
42266
  FuelConnectorEventTypes2["currentNetwork"] = "currentNetwork";
41718
42267
  FuelConnectorEventTypes2["assets"] = "assets";
41719
42268
  FuelConnectorEventTypes2["abis"] = "abis";
42269
+ FuelConnectorEventTypes2["consolidateCoins"] = "consolidateCoins";
41720
42270
  return FuelConnectorEventTypes2;
41721
42271
  })(FuelConnectorEventTypes || {});
41722
42272
  var FuelConnectorEventType = "FuelConnector";
@@ -41966,6 +42516,15 @@ ${PANIC_DOC_URL}#variant.${statusReason}`;
41966
42516
  async hasABI(_id) {
41967
42517
  throw new FuelError(FuelError.CODES.NOT_IMPLEMENTED, "Method not implemented.");
41968
42518
  }
42519
+ /**
42520
+ * Start the consolidation of coins process
42521
+ *
42522
+ * @param owner - The B256 address of the owner.
42523
+ * @param assetId - The asset ID that requires consolidation.
42524
+ */
42525
+ async startConsolidation(_opts) {
42526
+ throw new FuelError(FuelError.CODES.NOT_IMPLEMENTED, "Method not implemented.");
42527
+ }
41969
42528
  /**
41970
42529
  * Event listener for the connector.
41971
42530
  *