@fuel-ts/account 0.90.0 → 0.92.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of @fuel-ts/account might be problematic. Click here for more details.

@@ -52,7 +52,6 @@ __export(test_utils_exports, {
52
52
  TestMessage: () => TestMessage,
53
53
  WalletsConfig: () => WalletsConfig,
54
54
  generateTestWallet: () => generateTestWallet,
55
- killNode: () => killNode,
56
55
  launchNode: () => launchNode,
57
56
  launchNodeAndGetWallets: () => launchNodeAndGetWallets,
58
57
  seedTestWallet: () => seedTestWallet,
@@ -547,6 +546,12 @@ var GasCostsFragmentDoc = import_graphql_tag.default`
547
546
  alocDependentCost {
548
547
  ...DependentCostFragment
549
548
  }
549
+ cfe {
550
+ ...DependentCostFragment
551
+ }
552
+ cfeiDependentCost {
553
+ ...DependentCostFragment
554
+ }
550
555
  call {
551
556
  ...DependentCostFragment
552
557
  }
@@ -787,6 +792,9 @@ ${TransactionFragmentDoc}`;
787
792
  var GetBlocksDocument = import_graphql_tag.default`
788
793
  query getBlocks($after: String, $before: String, $first: Int, $last: Int) {
789
794
  blocks(after: $after, before: $before, first: $first, last: $last) {
795
+ pageInfo {
796
+ ...pageInfoFragment
797
+ }
790
798
  edges {
791
799
  node {
792
800
  ...blockFragment
@@ -794,7 +802,8 @@ var GetBlocksDocument = import_graphql_tag.default`
794
802
  }
795
803
  }
796
804
  }
797
- ${BlockFragmentDoc}`;
805
+ ${PageInfoFragmentDoc}
806
+ ${BlockFragmentDoc}`;
798
807
  var GetCoinDocument = import_graphql_tag.default`
799
808
  query getCoin($coinId: UtxoId!) {
800
809
  coin(utxoId: $coinId) {
@@ -811,6 +820,9 @@ var GetCoinsDocument = import_graphql_tag.default`
811
820
  first: $first
812
821
  last: $last
813
822
  ) {
823
+ pageInfo {
824
+ ...pageInfoFragment
825
+ }
814
826
  edges {
815
827
  node {
816
828
  ...coinFragment
@@ -818,7 +830,8 @@ var GetCoinsDocument = import_graphql_tag.default`
818
830
  }
819
831
  }
820
832
  }
821
- ${CoinFragmentDoc}`;
833
+ ${PageInfoFragmentDoc}
834
+ ${CoinFragmentDoc}`;
822
835
  var GetCoinsToSpendDocument = import_graphql_tag.default`
823
836
  query getCoinsToSpend($owner: Address!, $queryPerAsset: [SpendQueryElementInput!]!, $excludedIds: ExcludeInput) {
824
837
  coinsToSpend(
@@ -877,6 +890,9 @@ var GetBalancesDocument = import_graphql_tag.default`
877
890
  first: $first
878
891
  last: $last
879
892
  ) {
893
+ pageInfo {
894
+ ...pageInfoFragment
895
+ }
880
896
  edges {
881
897
  node {
882
898
  ...balanceFragment
@@ -884,7 +900,8 @@ var GetBalancesDocument = import_graphql_tag.default`
884
900
  }
885
901
  }
886
902
  }
887
- ${BalanceFragmentDoc}`;
903
+ ${PageInfoFragmentDoc}
904
+ ${BalanceFragmentDoc}`;
888
905
  var GetMessagesDocument = import_graphql_tag.default`
889
906
  query getMessages($owner: Address!, $after: String, $before: String, $first: Int, $last: Int) {
890
907
  messages(
@@ -894,6 +911,9 @@ var GetMessagesDocument = import_graphql_tag.default`
894
911
  first: $first
895
912
  last: $last
896
913
  ) {
914
+ pageInfo {
915
+ ...pageInfoFragment
916
+ }
897
917
  edges {
898
918
  node {
899
919
  ...messageFragment
@@ -901,7 +921,8 @@ var GetMessagesDocument = import_graphql_tag.default`
901
921
  }
902
922
  }
903
923
  }
904
- ${MessageFragmentDoc}`;
924
+ ${PageInfoFragmentDoc}
925
+ ${MessageFragmentDoc}`;
905
926
  var GetMessageProofDocument = import_graphql_tag.default`
906
927
  query getMessageProof($transactionId: TransactionId!, $nonce: Nonce!, $commitBlockId: BlockId, $commitBlockHeight: U32) {
907
928
  messageProof(
@@ -1693,7 +1714,7 @@ var import_errors7 = require("@fuel-ts/errors");
1693
1714
  var import_math6 = require("@fuel-ts/math");
1694
1715
  var import_transactions5 = require("@fuel-ts/transactions");
1695
1716
  var import_configs5 = require("@fuel-ts/transactions/configs");
1696
- var assemblePanicError = (statusReason) => {
1717
+ var assemblePanicError = (statusReason, metadata) => {
1697
1718
  let errorMessage = `The transaction reverted with reason: "${statusReason}".`;
1698
1719
  if (import_configs5.PANIC_REASONS.includes(statusReason)) {
1699
1720
  errorMessage = `${errorMessage}
@@ -1702,10 +1723,13 @@ You can read more about this error at:
1702
1723
 
1703
1724
  ${import_configs5.PANIC_DOC_URL}#variant.${statusReason}`;
1704
1725
  }
1705
- return { errorMessage, reason: statusReason };
1726
+ return new import_errors7.FuelError(import_errors7.ErrorCode.SCRIPT_REVERTED, errorMessage, {
1727
+ ...metadata,
1728
+ reason: statusReason
1729
+ });
1706
1730
  };
1707
1731
  var stringify = (obj) => JSON.stringify(obj, null, 2);
1708
- var assembleRevertError = (receipts, logs) => {
1732
+ var assembleRevertError = (receipts, logs, metadata) => {
1709
1733
  let errorMessage = "The transaction reverted with an unknown reason.";
1710
1734
  const revertReceipt = receipts.find(({ type }) => type === import_transactions5.ReceiptType.Revert);
1711
1735
  let reason = "";
@@ -1738,25 +1762,36 @@ var assembleRevertError = (receipts, logs) => {
1738
1762
  errorMessage = `The transaction reverted because it's missing an "OutputChange".`;
1739
1763
  break;
1740
1764
  default:
1741
- reason = "unknown";
1742
- errorMessage = `The transaction reverted with an unknown reason: ${revertReceipt.val}`;
1765
+ throw new import_errors7.FuelError(
1766
+ import_errors7.ErrorCode.UNKNOWN,
1767
+ `The transaction reverted with an unknown reason: ${revertReceipt.val}`,
1768
+ {
1769
+ ...metadata,
1770
+ reason: "unknown"
1771
+ }
1772
+ );
1743
1773
  }
1744
1774
  }
1745
- return { errorMessage, reason };
1775
+ return new import_errors7.FuelError(import_errors7.ErrorCode.SCRIPT_REVERTED, errorMessage, {
1776
+ ...metadata,
1777
+ reason
1778
+ });
1746
1779
  };
1747
1780
  var extractTxError = (params) => {
1748
1781
  const { receipts, statusReason, logs } = params;
1749
1782
  const isPanic = receipts.some(({ type }) => type === import_transactions5.ReceiptType.Panic);
1750
1783
  const isRevert = receipts.some(({ type }) => type === import_transactions5.ReceiptType.Revert);
1751
- const { errorMessage, reason } = isPanic ? assemblePanicError(statusReason) : assembleRevertError(receipts, logs);
1752
1784
  const metadata = {
1753
1785
  logs,
1754
1786
  receipts,
1755
1787
  panic: isPanic,
1756
1788
  revert: isRevert,
1757
- reason
1789
+ reason: ""
1758
1790
  };
1759
- return new import_errors7.FuelError(import_errors7.ErrorCode.SCRIPT_REVERTED, errorMessage, metadata);
1791
+ if (isPanic) {
1792
+ return assemblePanicError(statusReason, metadata);
1793
+ }
1794
+ return assembleRevertError(receipts, logs, metadata);
1760
1795
  };
1761
1796
 
1762
1797
  // src/providers/transaction-request/errors.ts
@@ -3592,12 +3627,18 @@ var TransactionResponse = class {
3592
3627
  await this.fetch();
3593
3628
  }
3594
3629
  /**
3595
- * Waits for transaction to complete and returns the result.
3630
+ * Assembles the result of a transaction by retrieving the transaction summary,
3631
+ * decoding logs (if available), and handling transaction failure.
3596
3632
  *
3597
- * @returns The completed transaction result
3633
+ * This method can be used to obtain the result of a transaction that has just
3634
+ * been submitted or one that has already been processed.
3635
+ *
3636
+ * @template TTransactionType - The type of the transaction.
3637
+ * @param contractsAbiMap - The map of contract ABIs.
3638
+ * @returns - The assembled transaction result.
3639
+ * @throws If the transaction status is a failure.
3598
3640
  */
3599
- async waitForResult(contractsAbiMap) {
3600
- await this.waitForStatusChange();
3641
+ async assembleResult(contractsAbiMap) {
3601
3642
  const transactionSummary = await this.getTransactionSummary(contractsAbiMap);
3602
3643
  const transactionResult = {
3603
3644
  gqlTransaction: this.gqlTransaction,
@@ -3623,6 +3664,15 @@ var TransactionResponse = class {
3623
3664
  }
3624
3665
  return transactionResult;
3625
3666
  }
3667
+ /**
3668
+ * Waits for transaction to complete and returns the result.
3669
+ *
3670
+ * @returns The completed transaction result
3671
+ */
3672
+ async waitForResult(contractsAbiMap) {
3673
+ await this.waitForStatusChange();
3674
+ return this.assembleResult(contractsAbiMap);
3675
+ }
3626
3676
  /**
3627
3677
  * Waits for transaction to complete and returns the result.
3628
3678
  *
@@ -3686,6 +3736,8 @@ var mergeQuantities = (...coinQuantities) => {
3686
3736
 
3687
3737
  // src/providers/provider.ts
3688
3738
  var MAX_RETRIES = 10;
3739
+ var RESOURCES_PAGE_SIZE_LIMIT = 512;
3740
+ var BLOCKS_PAGE_SIZE_LIMIT = 5;
3689
3741
  var processGqlChain = (chain) => {
3690
3742
  const { name, daHeight, consensusParameters, latestBlock } = chain;
3691
3743
  const {
@@ -4329,7 +4381,7 @@ Supported fuel-core version: ${supportedVersion}.`
4329
4381
  /**
4330
4382
  * Returns a transaction cost to enable user
4331
4383
  * to set gasLimit and also reserve balance amounts
4332
- * on the the transaction.
4384
+ * on the transaction.
4333
4385
  *
4334
4386
  * @param transactionRequestLike - The transaction request object.
4335
4387
  * @param transactionCostParams - The transaction cost parameters (optional).
@@ -4440,20 +4492,27 @@ Supported fuel-core version: ${supportedVersion}.`
4440
4492
  */
4441
4493
  async getCoins(owner, assetId, paginationArgs) {
4442
4494
  const ownerAddress = import_address3.Address.fromAddressOrString(owner);
4443
- const result = await this.operations.getCoins({
4444
- first: 10,
4445
- ...paginationArgs,
4495
+ const {
4496
+ coins: { edges, pageInfo }
4497
+ } = await this.operations.getCoins({
4498
+ ...this.validatePaginationArgs({
4499
+ paginationLimit: RESOURCES_PAGE_SIZE_LIMIT,
4500
+ inputArgs: paginationArgs
4501
+ }),
4446
4502
  filter: { owner: ownerAddress.toB256(), assetId: assetId && (0, import_utils23.hexlify)(assetId) }
4447
4503
  });
4448
- const coins = result.coins.edges.map((edge) => edge.node);
4449
- return coins.map((coin) => ({
4450
- id: coin.utxoId,
4451
- assetId: coin.assetId,
4452
- amount: (0, import_math17.bn)(coin.amount),
4453
- owner: import_address3.Address.fromAddressOrString(coin.owner),
4454
- blockCreated: (0, import_math17.bn)(coin.blockCreated),
4455
- txCreatedIdx: (0, import_math17.bn)(coin.txCreatedIdx)
4504
+ const coins = edges.map(({ node }) => ({
4505
+ id: node.utxoId,
4506
+ assetId: node.assetId,
4507
+ amount: (0, import_math17.bn)(node.amount),
4508
+ owner: import_address3.Address.fromAddressOrString(node.owner),
4509
+ blockCreated: (0, import_math17.bn)(node.blockCreated),
4510
+ txCreatedIdx: (0, import_math17.bn)(node.txCreatedIdx)
4456
4511
  }));
4512
+ return {
4513
+ coins,
4514
+ pageInfo
4515
+ };
4457
4516
  }
4458
4517
  /**
4459
4518
  * Returns resources for the given owner satisfying the spend query.
@@ -4546,14 +4605,21 @@ Supported fuel-core version: ${supportedVersion}.`
4546
4605
  * @returns A promise that resolves to the blocks.
4547
4606
  */
4548
4607
  async getBlocks(params) {
4549
- const { blocks: fetchedData } = await this.operations.getBlocks(params);
4550
- const blocks = fetchedData.edges.map(({ node: block }) => ({
4608
+ const {
4609
+ blocks: { edges, pageInfo }
4610
+ } = await this.operations.getBlocks({
4611
+ ...this.validatePaginationArgs({
4612
+ paginationLimit: BLOCKS_PAGE_SIZE_LIMIT,
4613
+ inputArgs: params
4614
+ })
4615
+ });
4616
+ const blocks = edges.map(({ node: block }) => ({
4551
4617
  id: block.id,
4552
4618
  height: (0, import_math17.bn)(block.height),
4553
4619
  time: block.header.time,
4554
4620
  transactionIds: block.transactions.map((tx) => tx.id)
4555
4621
  }));
4556
- return blocks;
4622
+ return { blocks, pageInfo };
4557
4623
  }
4558
4624
  /**
4559
4625
  * Returns block matching the given ID or type, including transaction data.
@@ -4663,17 +4729,22 @@ Supported fuel-core version: ${supportedVersion}.`
4663
4729
  * @param paginationArgs - Pagination arguments (optional).
4664
4730
  * @returns A promise that resolves to the balances.
4665
4731
  */
4666
- async getBalances(owner, paginationArgs) {
4667
- const result = await this.operations.getBalances({
4668
- first: 10,
4669
- ...paginationArgs,
4732
+ async getBalances(owner) {
4733
+ const {
4734
+ balances: { edges }
4735
+ } = await this.operations.getBalances({
4736
+ /**
4737
+ * The query parameters for this method were designed to support pagination,
4738
+ * but the current Fuel-Core implementation does not support pagination yet.
4739
+ */
4740
+ first: 1e4,
4670
4741
  filter: { owner: import_address3.Address.fromAddressOrString(owner).toB256() }
4671
4742
  });
4672
- const balances = result.balances.edges.map((edge) => edge.node);
4673
- return balances.map((balance) => ({
4674
- assetId: balance.assetId,
4675
- amount: (0, import_math17.bn)(balance.amount)
4743
+ const balances = edges.map(({ node }) => ({
4744
+ assetId: node.assetId,
4745
+ amount: (0, import_math17.bn)(node.amount)
4676
4746
  }));
4747
+ return { balances };
4677
4748
  }
4678
4749
  /**
4679
4750
  * Returns message for the given address.
@@ -4683,27 +4754,34 @@ Supported fuel-core version: ${supportedVersion}.`
4683
4754
  * @returns A promise that resolves to the messages.
4684
4755
  */
4685
4756
  async getMessages(address, paginationArgs) {
4686
- const result = await this.operations.getMessages({
4687
- first: 10,
4688
- ...paginationArgs,
4757
+ const {
4758
+ messages: { edges, pageInfo }
4759
+ } = await this.operations.getMessages({
4760
+ ...this.validatePaginationArgs({
4761
+ inputArgs: paginationArgs,
4762
+ paginationLimit: RESOURCES_PAGE_SIZE_LIMIT
4763
+ }),
4689
4764
  owner: import_address3.Address.fromAddressOrString(address).toB256()
4690
4765
  });
4691
- const messages = result.messages.edges.map((edge) => edge.node);
4692
- return messages.map((message) => ({
4766
+ const messages = edges.map(({ node }) => ({
4693
4767
  messageId: import_transactions20.InputMessageCoder.getMessageId({
4694
- sender: message.sender,
4695
- recipient: message.recipient,
4696
- nonce: message.nonce,
4697
- amount: (0, import_math17.bn)(message.amount),
4698
- data: message.data
4768
+ sender: node.sender,
4769
+ recipient: node.recipient,
4770
+ nonce: node.nonce,
4771
+ amount: (0, import_math17.bn)(node.amount),
4772
+ data: node.data
4699
4773
  }),
4700
- sender: import_address3.Address.fromAddressOrString(message.sender),
4701
- recipient: import_address3.Address.fromAddressOrString(message.recipient),
4702
- nonce: message.nonce,
4703
- amount: (0, import_math17.bn)(message.amount),
4704
- data: import_transactions20.InputMessageCoder.decodeData(message.data),
4705
- daHeight: (0, import_math17.bn)(message.daHeight)
4774
+ sender: import_address3.Address.fromAddressOrString(node.sender),
4775
+ recipient: import_address3.Address.fromAddressOrString(node.recipient),
4776
+ nonce: node.nonce,
4777
+ amount: (0, import_math17.bn)(node.amount),
4778
+ data: import_transactions20.InputMessageCoder.decodeData(node.data),
4779
+ daHeight: (0, import_math17.bn)(node.daHeight)
4706
4780
  }));
4781
+ return {
4782
+ messages,
4783
+ pageInfo
4784
+ };
4707
4785
  }
4708
4786
  /**
4709
4787
  * Returns Message Proof for given transaction id and the message id from MessageOut receipt.
@@ -4882,6 +4960,41 @@ Supported fuel-core version: ${supportedVersion}.`
4882
4960
  }
4883
4961
  return relayedTransactionStatus;
4884
4962
  }
4963
+ /**
4964
+ * @hidden
4965
+ */
4966
+ validatePaginationArgs(params) {
4967
+ const { paginationLimit, inputArgs = {} } = params;
4968
+ const { first, last, after, before } = inputArgs;
4969
+ if (after && before) {
4970
+ throw new import_errors14.FuelError(
4971
+ import_errors14.ErrorCode.INVALID_INPUT_PARAMETERS,
4972
+ 'Pagination arguments "after" and "before" cannot be used together'
4973
+ );
4974
+ }
4975
+ if ((first || 0) > paginationLimit || (last || 0) > paginationLimit) {
4976
+ throw new import_errors14.FuelError(
4977
+ import_errors14.ErrorCode.INVALID_INPUT_PARAMETERS,
4978
+ `Pagination limit for this query cannot exceed ${paginationLimit} items`
4979
+ );
4980
+ }
4981
+ if (first && before) {
4982
+ throw new import_errors14.FuelError(
4983
+ import_errors14.ErrorCode.INVALID_INPUT_PARAMETERS,
4984
+ 'The use of pagination argument "first" with "before" is not supported'
4985
+ );
4986
+ }
4987
+ if (last && after) {
4988
+ throw new import_errors14.FuelError(
4989
+ import_errors14.ErrorCode.INVALID_INPUT_PARAMETERS,
4990
+ 'The use of pagination argument "last" with "after" is not supported'
4991
+ );
4992
+ }
4993
+ if (!first && !last) {
4994
+ inputArgs.first = paginationLimit;
4995
+ }
4996
+ return inputArgs;
4997
+ }
4885
4998
  /**
4886
4999
  * @hidden
4887
5000
  */
@@ -5107,52 +5220,16 @@ var Account = class extends import_interfaces.AbstractAccount {
5107
5220
  * @param assetId - The asset ID of the coins to retrieve (optional).
5108
5221
  * @returns A promise that resolves to an array of Coins.
5109
5222
  */
5110
- async getCoins(assetId) {
5111
- const coins = [];
5112
- const pageSize = 9999;
5113
- let cursor;
5114
- for (; ; ) {
5115
- const pageCoins = await this.provider.getCoins(this.address, assetId, {
5116
- first: pageSize,
5117
- after: cursor
5118
- });
5119
- coins.push(...pageCoins);
5120
- const hasNextPage = pageCoins.length >= pageSize;
5121
- if (!hasNextPage) {
5122
- break;
5123
- }
5124
- throw new import_errors16.FuelError(
5125
- import_errors16.ErrorCode.NOT_SUPPORTED,
5126
- `Wallets containing more than ${pageSize} coins exceed the current supported limit.`
5127
- );
5128
- }
5129
- return coins;
5223
+ async getCoins(assetId, paginationArgs) {
5224
+ return this.provider.getCoins(this.address, assetId, paginationArgs);
5130
5225
  }
5131
5226
  /**
5132
5227
  * Retrieves messages owned by the account.
5133
5228
  *
5134
5229
  * @returns A promise that resolves to an array of Messages.
5135
5230
  */
5136
- async getMessages() {
5137
- const messages = [];
5138
- const pageSize = 9999;
5139
- let cursor;
5140
- for (; ; ) {
5141
- const pageMessages = await this.provider.getMessages(this.address, {
5142
- first: pageSize,
5143
- after: cursor
5144
- });
5145
- messages.push(...pageMessages);
5146
- const hasNextPage = pageMessages.length >= pageSize;
5147
- if (!hasNextPage) {
5148
- break;
5149
- }
5150
- throw new import_errors16.FuelError(
5151
- import_errors16.ErrorCode.NOT_SUPPORTED,
5152
- `Wallets containing more than ${pageSize} messages exceed the current supported limit.`
5153
- );
5154
- }
5155
- return messages;
5231
+ async getMessages(paginationArgs) {
5232
+ return this.provider.getMessages(this.address, paginationArgs);
5156
5233
  }
5157
5234
  /**
5158
5235
  * Retrieves the balance of the account for the given asset.
@@ -5171,25 +5248,7 @@ var Account = class extends import_interfaces.AbstractAccount {
5171
5248
  * @returns A promise that resolves to an array of Coins and their quantities.
5172
5249
  */
5173
5250
  async getBalances() {
5174
- const balances = [];
5175
- const pageSize = 9999;
5176
- let cursor;
5177
- for (; ; ) {
5178
- const pageBalances = await this.provider.getBalances(this.address, {
5179
- first: pageSize,
5180
- after: cursor
5181
- });
5182
- balances.push(...pageBalances);
5183
- const hasNextPage = pageBalances.length >= pageSize;
5184
- if (!hasNextPage) {
5185
- break;
5186
- }
5187
- throw new import_errors16.FuelError(
5188
- import_errors16.ErrorCode.NOT_SUPPORTED,
5189
- `Wallets containing more than ${pageSize} balances exceed the current supported limit.`
5190
- );
5191
- }
5192
- return balances;
5251
+ return this.provider.getBalances(this.address);
5193
5252
  }
5194
5253
  /**
5195
5254
  * Funds a transaction request by adding the necessary resources.
@@ -8623,14 +8682,13 @@ var generateTestWallet = async (provider, quantities) => {
8623
8682
  // src/test-utils/launchNode.ts
8624
8683
  var import_abi_coder8 = require("@fuel-ts/abi-coder");
8625
8684
  var import_crypto8 = require("@fuel-ts/crypto");
8685
+ var import_errors21 = require("@fuel-ts/errors");
8626
8686
  var import_utils37 = require("@fuel-ts/utils");
8627
- var import_child_process = require("child_process");
8628
8687
  var import_crypto9 = require("crypto");
8629
8688
  var import_fs = require("fs");
8630
8689
  var import_os = __toESM(require("os"));
8631
8690
  var import_path = __toESM(require("path"));
8632
8691
  var import_portfinder = require("portfinder");
8633
- var import_tree_kill = __toESM(require("tree-kill"));
8634
8692
  var getFlagValueFromArgs = (args, flag) => {
8635
8693
  const flagIndex = args.indexOf(flag);
8636
8694
  if (flagIndex === -1) {
@@ -8648,20 +8706,6 @@ var extractRemainingArgs = (args, flagsToRemove) => {
8648
8706
  });
8649
8707
  return newArgs;
8650
8708
  };
8651
- var killNode = (params) => {
8652
- const { child, configPath, state, killFn } = params;
8653
- if (!state.isDead) {
8654
- if (child.pid) {
8655
- state.isDead = true;
8656
- killFn(Number(child.pid));
8657
- }
8658
- child.stdout.removeAllListeners();
8659
- child.stderr.removeAllListeners();
8660
- if ((0, import_fs.existsSync)(configPath)) {
8661
- (0, import_fs.rmSync)(configPath, { recursive: true });
8662
- }
8663
- }
8664
- };
8665
8709
  function getFinalStateConfigJSON({ stateConfig, chainConfig }) {
8666
8710
  const defaultCoins = import_utils37.defaultSnapshotConfigs.stateConfig.coins.map((coin) => ({
8667
8711
  ...coin,
@@ -8700,12 +8744,11 @@ var launchNode = async ({
8700
8744
  ip,
8701
8745
  port,
8702
8746
  args = [],
8703
- fuelCorePath = process.env.FUEL_CORE_PATH ?? void 0,
8747
+ fuelCorePath = process.env.FUEL_CORE_PATH || void 0,
8704
8748
  loggingEnabled = true,
8705
- debugEnabled = false,
8706
8749
  basePath,
8707
8750
  snapshotConfig = import_utils37.defaultSnapshotConfigs
8708
- }) => (
8751
+ } = {}) => (
8709
8752
  // eslint-disable-next-line no-async-promise-executor
8710
8753
  new Promise(async (resolve, reject) => {
8711
8754
  const remainingArgs = extractRemainingArgs(args, [
@@ -8722,7 +8765,7 @@ var launchNode = async ({
8722
8765
  const poaInstant = poaInstantFlagValue === "true" || poaInstantFlagValue === void 0;
8723
8766
  const nativeExecutorVersion = getFlagValueFromArgs(args, "--native-executor-version") || "0";
8724
8767
  const graphQLStartSubstring = "Binding GraphQL provider to";
8725
- const command = fuelCorePath ?? "fuel-core";
8768
+ const command = fuelCorePath || "fuel-core";
8726
8769
  const ipToUse = ip || "0.0.0.0";
8727
8770
  const portToUse = port || (await (0, import_portfinder.getPortPromise)({
8728
8771
  port: 4e3,
@@ -8751,7 +8794,8 @@ var launchNode = async ({
8751
8794
  (0, import_fs.writeFileSync)(stateTransitionPath, JSON.stringify(""));
8752
8795
  snapshotDirToUse = tempDir;
8753
8796
  }
8754
- const child = (0, import_child_process.spawn)(
8797
+ const { spawn } = await import("child_process");
8798
+ const child = spawn(
8755
8799
  command,
8756
8800
  [
8757
8801
  "run",
@@ -8768,22 +8812,45 @@ var launchNode = async ({
8768
8812
  "--debug",
8769
8813
  ...remainingArgs
8770
8814
  ].flat(),
8771
- {
8772
- stdio: "pipe"
8773
- }
8815
+ { stdio: "pipe", detached: true }
8774
8816
  );
8775
8817
  if (loggingEnabled) {
8776
- child.stderr.pipe(process.stderr);
8777
- }
8778
- if (debugEnabled) {
8779
- child.stdout.pipe(process.stdout);
8818
+ child.stderr.on("data", (chunk) => {
8819
+ console.log(chunk.toString());
8820
+ });
8780
8821
  }
8781
- const cleanupConfig = {
8782
- child,
8783
- configPath: tempDir,
8784
- killFn: import_tree_kill.default,
8785
- state: {
8786
- isDead: false
8822
+ const removeSideffects = () => {
8823
+ child.stderr.removeAllListeners();
8824
+ if ((0, import_fs.existsSync)(tempDir)) {
8825
+ (0, import_fs.rmSync)(tempDir, { recursive: true });
8826
+ }
8827
+ };
8828
+ child.on("error", removeSideffects);
8829
+ child.on("exit", removeSideffects);
8830
+ const childState = {
8831
+ isDead: false
8832
+ };
8833
+ const cleanup = () => {
8834
+ if (childState.isDead) {
8835
+ return;
8836
+ }
8837
+ childState.isDead = true;
8838
+ removeSideffects();
8839
+ if (child.pid !== void 0) {
8840
+ try {
8841
+ process.kill(-child.pid);
8842
+ } catch (e) {
8843
+ const error = e;
8844
+ if (error.code === "ESRCH") {
8845
+ console.log(
8846
+ `fuel-core node under pid ${child.pid} does not exist. The node might have been killed before cleanup was called. Exiting cleanly.`
8847
+ );
8848
+ } else {
8849
+ throw e;
8850
+ }
8851
+ }
8852
+ } else {
8853
+ console.error("No PID available for the child process, unable to kill launched node");
8787
8854
  }
8788
8855
  };
8789
8856
  child.stderr.on("data", (chunk) => {
@@ -8793,23 +8860,25 @@ var launchNode = async ({
8793
8860
  const rowWithUrl = rows.find((row) => row.indexOf(graphQLStartSubstring) !== -1);
8794
8861
  const [realIp, realPort] = rowWithUrl.split(" ").at(-1).trim().split(":");
8795
8862
  resolve({
8796
- cleanup: () => killNode(cleanupConfig),
8863
+ cleanup,
8797
8864
  ip: realIp,
8798
8865
  port: realPort,
8799
8866
  url: `http://${realIp}:${realPort}/v1/graphql`,
8800
- snapshotDir: snapshotDirToUse
8867
+ snapshotDir: snapshotDirToUse,
8868
+ pid: child.pid
8801
8869
  });
8802
8870
  }
8803
8871
  if (/error/i.test(text)) {
8804
- reject(text.toString());
8872
+ console.log(text);
8873
+ reject(new import_errors21.FuelError(import_errors21.FuelError.CODES.NODE_LAUNCH_FAILED, text));
8805
8874
  }
8806
8875
  });
8807
- process.on("exit", () => killNode(cleanupConfig));
8808
- process.on("SIGINT", () => killNode(cleanupConfig));
8809
- process.on("SIGUSR1", () => killNode(cleanupConfig));
8810
- process.on("SIGUSR2", () => killNode(cleanupConfig));
8811
- process.on("beforeExit", () => killNode(cleanupConfig));
8812
- process.on("uncaughtException", () => killNode(cleanupConfig));
8876
+ process.on("exit", cleanup);
8877
+ process.on("SIGINT", cleanup);
8878
+ process.on("SIGUSR1", cleanup);
8879
+ process.on("SIGUSR2", cleanup);
8880
+ process.on("beforeExit", cleanup);
8881
+ process.on("uncaughtException", cleanup);
8813
8882
  child.on("error", reject);
8814
8883
  })
8815
8884
  );
@@ -8864,7 +8933,7 @@ __publicField(AssetId, "B", new _AssetId(
8864
8933
 
8865
8934
  // src/test-utils/wallet-config.ts
8866
8935
  var import_crypto11 = require("@fuel-ts/crypto");
8867
- var import_errors21 = require("@fuel-ts/errors");
8936
+ var import_errors22 = require("@fuel-ts/errors");
8868
8937
  var import_utils39 = require("@fuel-ts/utils");
8869
8938
  var WalletsConfig = class {
8870
8939
  initialState;
@@ -8944,26 +9013,26 @@ var WalletsConfig = class {
8944
9013
  amountPerCoin
8945
9014
  }) {
8946
9015
  if (Array.isArray(wallets) && wallets.length === 0 || typeof wallets === "number" && wallets <= 0) {
8947
- throw new import_errors21.FuelError(
8948
- import_errors21.FuelError.CODES.INVALID_INPUT_PARAMETERS,
9016
+ throw new import_errors22.FuelError(
9017
+ import_errors22.FuelError.CODES.INVALID_INPUT_PARAMETERS,
8949
9018
  "Number of wallets must be greater than zero."
8950
9019
  );
8951
9020
  }
8952
9021
  if (Array.isArray(assets2) && assets2.length === 0 || typeof assets2 === "number" && assets2 <= 0) {
8953
- throw new import_errors21.FuelError(
8954
- import_errors21.FuelError.CODES.INVALID_INPUT_PARAMETERS,
9022
+ throw new import_errors22.FuelError(
9023
+ import_errors22.FuelError.CODES.INVALID_INPUT_PARAMETERS,
8955
9024
  "Number of assets per wallet must be greater than zero."
8956
9025
  );
8957
9026
  }
8958
9027
  if (coinsPerAsset <= 0) {
8959
- throw new import_errors21.FuelError(
8960
- import_errors21.FuelError.CODES.INVALID_INPUT_PARAMETERS,
9028
+ throw new import_errors22.FuelError(
9029
+ import_errors22.FuelError.CODES.INVALID_INPUT_PARAMETERS,
8961
9030
  "Number of coins per asset must be greater than zero."
8962
9031
  );
8963
9032
  }
8964
9033
  if (amountPerCoin <= 0) {
8965
- throw new import_errors21.FuelError(
8966
- import_errors21.FuelError.CODES.INVALID_INPUT_PARAMETERS,
9034
+ throw new import_errors22.FuelError(
9035
+ import_errors22.FuelError.CODES.INVALID_INPUT_PARAMETERS,
8967
9036
  "Amount per coin must be greater than zero."
8968
9037
  );
8969
9038
  }
@@ -8981,7 +9050,8 @@ var defaultWalletConfigOptions = {
8981
9050
  async function setupTestProviderAndWallets({
8982
9051
  walletsConfig: walletsConfigOptions = {},
8983
9052
  providerOptions,
8984
- nodeOptions = {}
9053
+ nodeOptions = {},
9054
+ launchNodeServerPort = process.env.LAUNCH_NODE_SERVER_PORT || void 0
8985
9055
  } = {}) {
8986
9056
  Symbol.dispose ??= Symbol("Symbol.dispose");
8987
9057
  const walletsConfig = new WalletsConfig(
@@ -8991,7 +9061,7 @@ async function setupTestProviderAndWallets({
8991
9061
  ...walletsConfigOptions
8992
9062
  }
8993
9063
  );
8994
- const { cleanup, url } = await launchNode({
9064
+ const launchNodeOptions = {
8995
9065
  loggingEnabled: false,
8996
9066
  ...nodeOptions,
8997
9067
  snapshotConfig: (0, import_ramda5.mergeDeepRight)(
@@ -8999,7 +9069,20 @@ async function setupTestProviderAndWallets({
8999
9069
  walletsConfig.apply(nodeOptions?.snapshotConfig)
9000
9070
  ),
9001
9071
  port: "0"
9002
- });
9072
+ };
9073
+ let cleanup;
9074
+ let url;
9075
+ if (launchNodeServerPort) {
9076
+ const serverUrl = `http://localhost:${launchNodeServerPort}`;
9077
+ url = await (await fetch(serverUrl, { method: "POST", body: JSON.stringify(launchNodeOptions) })).text();
9078
+ cleanup = () => {
9079
+ fetch(`${serverUrl}/cleanup/${url}`);
9080
+ };
9081
+ } else {
9082
+ const settings = await launchNode(launchNodeOptions);
9083
+ url = settings.url;
9084
+ cleanup = settings.cleanup;
9085
+ }
9003
9086
  let provider;
9004
9087
  try {
9005
9088
  provider = await Provider.create(url, providerOptions);
@@ -9069,7 +9152,6 @@ var TestMessage = class {
9069
9152
  TestMessage,
9070
9153
  WalletsConfig,
9071
9154
  generateTestWallet,
9072
- killNode,
9073
9155
  launchNode,
9074
9156
  launchNodeAndGetWallets,
9075
9157
  seedTestWallet,