@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.
- package/dist/account.d.ts +45 -14
- package/dist/account.d.ts.map +1 -1
- package/dist/connectors/fuel-connector.d.ts +8 -0
- package/dist/connectors/fuel-connector.d.ts.map +1 -1
- package/dist/connectors/types/connector-types.d.ts +4 -2
- package/dist/connectors/types/connector-types.d.ts.map +1 -1
- package/dist/connectors/types/events.d.ts +6 -1
- package/dist/connectors/types/events.d.ts.map +1 -1
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.global.js +723 -164
- package/dist/index.global.js.map +1 -1
- package/dist/index.js +936 -471
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +856 -394
- package/dist/index.mjs.map +1 -1
- package/dist/providers/provider.d.ts.map +1 -1
- package/dist/providers/transaction-request/script-transaction-request.d.ts +2 -1
- package/dist/providers/transaction-request/script-transaction-request.d.ts.map +1 -1
- package/dist/providers/transaction-response/transaction-response.d.ts +23 -4
- package/dist/providers/transaction-response/transaction-response.d.ts.map +1 -1
- package/dist/providers/transaction-summary/call.d.ts +4 -7
- package/dist/providers/transaction-summary/call.d.ts.map +1 -1
- package/dist/providers/transaction-summary/operations.d.ts +1 -1
- package/dist/providers/transaction-summary/operations.d.ts.map +1 -1
- package/dist/providers/utils/extract-tx-error.d.ts +10 -1
- package/dist/providers/utils/extract-tx-error.d.ts.map +1 -1
- package/dist/providers/utils/handle-gql-error-message.d.ts.map +1 -1
- package/dist/providers/utils/transaction-response-serialization.d.ts.map +1 -1
- package/dist/test-utils/launchNode.d.ts.map +1 -1
- package/dist/test-utils.global.js +650 -164
- package/dist/test-utils.global.js.map +1 -1
- package/dist/test-utils.js +823 -381
- package/dist/test-utils.js.map +1 -1
- package/dist/test-utils.mjs +751 -308
- package/dist/test-utils.mjs.map +1 -1
- package/dist/types.d.ts +1 -1
- package/dist/types.d.ts.map +1 -1
- package/dist/utils/consolidate-coins.d.ts +43 -0
- package/dist/utils/consolidate-coins.d.ts.map +1 -0
- package/package.json +15 -15
package/dist/test-utils.mjs
CHANGED
@@ -217,8 +217,9 @@ var launchNode = /* @__PURE__ */ __name(async ({
|
|
217
217
|
"--consensus-key",
|
218
218
|
"--db-type",
|
219
219
|
"--poa-instant",
|
220
|
+
"--native-executor-version",
|
220
221
|
"--min-gas-price",
|
221
|
-
"--
|
222
|
+
"--starting-gas-price"
|
222
223
|
]);
|
223
224
|
const snapshotDir = getFlagValueFromArgs(args, "--snapshot");
|
224
225
|
const consensusKey = getFlagValueFromArgs(args, "--consensus-key") || defaultConsensusKey;
|
@@ -408,8 +409,8 @@ var addAmountToCoinQuantities = /* @__PURE__ */ __name((params) => {
|
|
408
409
|
import { Address as Address3, isB256 } from "@fuel-ts/address";
|
409
410
|
import { ErrorCode as ErrorCode17, FuelError as FuelError20 } from "@fuel-ts/errors";
|
410
411
|
import { bn as bn18 } from "@fuel-ts/math";
|
411
|
-
import { InputMessageCoder as InputMessageCoder2, TransactionCoder as
|
412
|
-
import { arrayify as
|
412
|
+
import { InputMessageCoder as InputMessageCoder2, TransactionCoder as TransactionCoder7, TransactionType as TransactionType11 } from "@fuel-ts/transactions";
|
413
|
+
import { arrayify as arrayify14, hexlify as hexlify19, DateTime as DateTime2, isDefined as isDefined3, sleep as sleep2 } from "@fuel-ts/utils";
|
413
414
|
import { checkFuelCoreVersionCompatibility, versions } from "@fuel-ts/versions";
|
414
415
|
import { GraphQLClient } from "graphql-request";
|
415
416
|
import gql2 from "graphql-tag";
|
@@ -1809,8 +1810,11 @@ import { print } from "graphql";
|
|
1809
1810
|
|
1810
1811
|
// src/providers/utils/handle-gql-error-message.ts
|
1811
1812
|
import { ErrorCode as ErrorCode2, FuelError as FuelError3 } from "@fuel-ts/errors";
|
1813
|
+
var ASSET_ID_REGEX = /[0-9a-fA-F]{32,64}/g;
|
1812
1814
|
var gqlErrorMessage = {
|
1813
1815
|
RPC_CONSISTENCY: /The required fuel block height is higher than the current block height. Required: \d+, Current: \d+/,
|
1816
|
+
INSUFFICIENT_FUNDS: /the target cannot be met due to insufficient coins available for [0-9a-fA-F]{32,64}. Collected: \d+/,
|
1817
|
+
MAX_COINS_REACHED: /the target for [0-9a-fA-F]{32,64} cannot be met due to exceeding the \d+ coin limit. Collected: \d+./,
|
1814
1818
|
NOT_ENOUGH_COINS_MAX_COINS: /the target cannot be met due to no coins available or exceeding the \d+ coin limit./,
|
1815
1819
|
ASSET_NOT_FOUND: /resource was not found in table/,
|
1816
1820
|
MULTIPLE_CHANGE_POLICIES: /The asset ([a-fA-F0-9]{64}) has multiple change policies/,
|
@@ -1826,6 +1830,46 @@ var mapGqlErrorMessage = /* @__PURE__ */ __name((error) => {
|
|
1826
1830
|
error
|
1827
1831
|
);
|
1828
1832
|
}
|
1833
|
+
if (gqlErrorMessage.MAX_COINS_REACHED.test(error.message)) {
|
1834
|
+
const matches = error.message.match(ASSET_ID_REGEX);
|
1835
|
+
const assetId = matches ? `0x${matches[0]}` : null;
|
1836
|
+
const owner = matches ? `0x${matches[1]}` : null;
|
1837
|
+
let suffix = "";
|
1838
|
+
if (assetId) {
|
1839
|
+
suffix += `
|
1840
|
+
Asset ID: '${assetId}'.`;
|
1841
|
+
}
|
1842
|
+
if (owner) {
|
1843
|
+
suffix += `
|
1844
|
+
Owner: '${owner}'.`;
|
1845
|
+
}
|
1846
|
+
return new FuelError3(
|
1847
|
+
ErrorCode2.MAX_COINS_REACHED,
|
1848
|
+
`You have too many small value coins - consider combining UTXOs.${suffix}`,
|
1849
|
+
{ assetId, owner },
|
1850
|
+
error
|
1851
|
+
);
|
1852
|
+
}
|
1853
|
+
if (gqlErrorMessage.INSUFFICIENT_FUNDS.test(error.message)) {
|
1854
|
+
const matches = error.message.match(ASSET_ID_REGEX);
|
1855
|
+
const assetId = matches ? `0x${matches[0]}` : null;
|
1856
|
+
const owner = matches ? `0x${matches[1]}` : null;
|
1857
|
+
let suffix = "";
|
1858
|
+
if (assetId) {
|
1859
|
+
suffix += `
|
1860
|
+
Asset ID: '${assetId}'.`;
|
1861
|
+
}
|
1862
|
+
if (owner) {
|
1863
|
+
suffix += `
|
1864
|
+
Owner: '${owner}'.`;
|
1865
|
+
}
|
1866
|
+
return new FuelError3(
|
1867
|
+
ErrorCode2.INSUFFICIENT_FUNDS,
|
1868
|
+
`Insufficient funds.${suffix}`,
|
1869
|
+
{ assetId, owner },
|
1870
|
+
error
|
1871
|
+
);
|
1872
|
+
}
|
1829
1873
|
if (gqlErrorMessage.MULTIPLE_CHANGE_POLICIES.test(error.message)) {
|
1830
1874
|
const match = error.message.match(/asset ([a-fA-F0-9]{64})/);
|
1831
1875
|
const assetId = match?.[1] || "";
|
@@ -2856,7 +2900,8 @@ import {
|
|
2856
2900
|
FAILED_ASSERT_SIGNAL,
|
2857
2901
|
FAILED_TRANSFER_TO_ADDRESS_SIGNAL as FAILED_TRANSFER_TO_ADDRESS_SIGNAL2,
|
2858
2902
|
PANIC_REASONS,
|
2859
|
-
PANIC_DOC_URL
|
2903
|
+
PANIC_DOC_URL,
|
2904
|
+
SwaySignalErrors
|
2860
2905
|
} from "@fuel-ts/transactions/configs";
|
2861
2906
|
var assemblePanicError = /* @__PURE__ */ __name((statusReason, metadata) => {
|
2862
2907
|
let errorMessage = `The transaction reverted with reason: "${statusReason}".`;
|
@@ -2873,58 +2918,98 @@ ${PANIC_DOC_URL}#variant.${statusReason}`;
|
|
2873
2918
|
});
|
2874
2919
|
}, "assemblePanicError");
|
2875
2920
|
var stringify = /* @__PURE__ */ __name((obj) => JSON.stringify(obj, null, 2), "stringify");
|
2876
|
-
var
|
2921
|
+
var assembleSignalErrorMessage = /* @__PURE__ */ __name((reasonHex, logs, metadata) => {
|
2877
2922
|
let errorMessage = "The transaction reverted with an unknown reason.";
|
2878
|
-
const revertReceipt = receipts.find(({ type }) => type === ReceiptType4.Revert);
|
2879
2923
|
let reason = "";
|
2880
|
-
|
2881
|
-
|
2882
|
-
|
2883
|
-
|
2884
|
-
|
2885
|
-
|
2886
|
-
|
2887
|
-
|
2888
|
-
|
2889
|
-
}
|
2890
|
-
|
2891
|
-
|
2892
|
-
|
2893
|
-
errorMessage = `The transaction reverted because of an "assert_eq" statement${suffix}`;
|
2894
|
-
break;
|
2895
|
-
}
|
2896
|
-
case FAILED_ASSERT_NE_SIGNAL: {
|
2897
|
-
const suffix = logs.length >= 2 ? ` comparing ${stringify(lastButOneLog)} and ${stringify(lastLog)}.` : ".";
|
2898
|
-
reason = "assert_ne";
|
2899
|
-
errorMessage = `The transaction reverted because of an "assert_ne" statement${suffix}`;
|
2900
|
-
break;
|
2901
|
-
}
|
2902
|
-
case FAILED_ASSERT_SIGNAL:
|
2903
|
-
reason = "assert";
|
2904
|
-
errorMessage = `The transaction reverted because an "assert" statement failed to evaluate to true.`;
|
2905
|
-
break;
|
2906
|
-
case FAILED_TRANSFER_TO_ADDRESS_SIGNAL2:
|
2907
|
-
reason = "MissingOutputVariable";
|
2908
|
-
errorMessage = `The transaction reverted because it's missing an "OutputVariable".`;
|
2909
|
-
break;
|
2910
|
-
default:
|
2911
|
-
throw new FuelError9(
|
2912
|
-
ErrorCode8.UNKNOWN,
|
2913
|
-
`The transaction reverted with an unknown reason: ${revertReceipt.val}`,
|
2914
|
-
{
|
2915
|
-
...metadata,
|
2916
|
-
reason: "unknown"
|
2917
|
-
}
|
2918
|
-
);
|
2924
|
+
const lastLog = logs[logs.length - 1];
|
2925
|
+
const lastButOneLog = logs[logs.length - 2];
|
2926
|
+
switch (reasonHex) {
|
2927
|
+
case FAILED_REQUIRE_SIGNAL: {
|
2928
|
+
reason = "require";
|
2929
|
+
errorMessage = `The transaction reverted because a "require" statement has thrown ${logs.length ? stringify(lastLog) : "an error."}.`;
|
2930
|
+
break;
|
2931
|
+
}
|
2932
|
+
case FAILED_ASSERT_EQ_SIGNAL: {
|
2933
|
+
const suffix = logs.length >= 2 ? ` comparing ${stringify(lastLog)} and ${stringify(lastButOneLog)}.` : ".";
|
2934
|
+
reason = "assert_eq";
|
2935
|
+
errorMessage = `The transaction reverted because of an "assert_eq" statement${suffix}`;
|
2936
|
+
break;
|
2919
2937
|
}
|
2938
|
+
case FAILED_ASSERT_NE_SIGNAL: {
|
2939
|
+
const suffix = logs.length >= 2 ? ` comparing ${stringify(lastButOneLog)} and ${stringify(lastLog)}.` : ".";
|
2940
|
+
reason = "assert_ne";
|
2941
|
+
errorMessage = `The transaction reverted because of an "assert_ne" statement${suffix}`;
|
2942
|
+
break;
|
2943
|
+
}
|
2944
|
+
case FAILED_ASSERT_SIGNAL:
|
2945
|
+
reason = "assert";
|
2946
|
+
errorMessage = `The transaction reverted because an "assert" statement failed to evaluate to true.`;
|
2947
|
+
break;
|
2948
|
+
case FAILED_TRANSFER_TO_ADDRESS_SIGNAL2:
|
2949
|
+
reason = "MissingOutputVariable";
|
2950
|
+
errorMessage = `The transaction reverted because it's missing an "OutputVariable".`;
|
2951
|
+
break;
|
2952
|
+
default:
|
2953
|
+
reason = `revert_with_log`;
|
2954
|
+
errorMessage = `The transaction reverted because a "revert_with_log" statement has thrown ${logs.length ? stringify(lastLog) : "an error."}.`;
|
2955
|
+
break;
|
2920
2956
|
}
|
2921
2957
|
return new FuelError9(ErrorCode8.SCRIPT_REVERTED, errorMessage, {
|
2922
2958
|
...metadata,
|
2923
2959
|
reason
|
2924
2960
|
});
|
2961
|
+
}, "assembleSignalErrorMessage");
|
2962
|
+
function buildAbiErrorMessage(abiError, logs, metadata, reason) {
|
2963
|
+
const { pos, msg } = abiError;
|
2964
|
+
let errorMessage = "";
|
2965
|
+
const positionMessage = pos ? `
|
2966
|
+
|
2967
|
+
This error originated at ${JSON.stringify(pos, null, 2)}` : "";
|
2968
|
+
if (msg) {
|
2969
|
+
errorMessage = `A sway "panic" expression was invoked with the message: "${msg}".${positionMessage}`;
|
2970
|
+
} else {
|
2971
|
+
const value = logs[logs.length - 1];
|
2972
|
+
errorMessage = `A sway "panic" expression was invoked with the value: ${JSON.stringify(value)}.${positionMessage}`;
|
2973
|
+
}
|
2974
|
+
return new FuelError9(ErrorCode8.SCRIPT_REVERTED, errorMessage, {
|
2975
|
+
...metadata,
|
2976
|
+
abiError,
|
2977
|
+
reason
|
2978
|
+
});
|
2979
|
+
}
|
2980
|
+
__name(buildAbiErrorMessage, "buildAbiErrorMessage");
|
2981
|
+
function findErrorInAbis(statusReason, abis = []) {
|
2982
|
+
for (const abi of abis) {
|
2983
|
+
if (abi.errorCodes?.[statusReason]) {
|
2984
|
+
return abi.errorCodes[statusReason];
|
2985
|
+
}
|
2986
|
+
}
|
2987
|
+
return void 0;
|
2988
|
+
}
|
2989
|
+
__name(findErrorInAbis, "findErrorInAbis");
|
2990
|
+
var assembleRevertError = /* @__PURE__ */ __name((_receipts, logs, metadata, statusReason, abis) => {
|
2991
|
+
const match = statusReason.match(/Revert\((\d+)\)/);
|
2992
|
+
const reason = match?.[1] ?? statusReason;
|
2993
|
+
const reasonHex = bn7(reason).toHex();
|
2994
|
+
if (Object.values(SwaySignalErrors).includes(reasonHex)) {
|
2995
|
+
return assembleSignalErrorMessage(reasonHex, logs, metadata);
|
2996
|
+
}
|
2997
|
+
let abiError;
|
2998
|
+
if (abis) {
|
2999
|
+
const abisArr = [abis.main, ...Object.values(abis.otherContractsAbis)];
|
3000
|
+
abiError = findErrorInAbis(reason, abisArr);
|
3001
|
+
}
|
3002
|
+
if (abiError) {
|
3003
|
+
return buildAbiErrorMessage(abiError, logs, metadata, reason);
|
3004
|
+
}
|
3005
|
+
const errorMessage = `The transaction reverted with reason: ${reason}.`;
|
3006
|
+
return new FuelError9(ErrorCode8.SCRIPT_REVERTED, errorMessage, {
|
3007
|
+
...metadata,
|
3008
|
+
reason
|
3009
|
+
});
|
2925
3010
|
}, "assembleRevertError");
|
2926
3011
|
var extractTxError = /* @__PURE__ */ __name((params) => {
|
2927
|
-
const { receipts, statusReason, logs, groupedLogs } = params;
|
3012
|
+
const { receipts, statusReason, logs, groupedLogs, abis } = params;
|
2928
3013
|
const isPanic = receipts.some(({ type }) => type === ReceiptType4.Panic);
|
2929
3014
|
const isRevert = receipts.some(({ type }) => type === ReceiptType4.Revert);
|
2930
3015
|
const metadata = {
|
@@ -2938,7 +3023,7 @@ var extractTxError = /* @__PURE__ */ __name((params) => {
|
|
2938
3023
|
if (isPanic) {
|
2939
3024
|
return assemblePanicError(statusReason, metadata);
|
2940
3025
|
}
|
2941
|
-
return assembleRevertError(receipts, logs, metadata);
|
3026
|
+
return assembleRevertError(receipts, logs, metadata, statusReason, abis);
|
2942
3027
|
}, "extractTxError");
|
2943
3028
|
|
2944
3029
|
// src/providers/utils/merge-quantities.ts
|
@@ -3911,11 +3996,15 @@ var ScriptTransactionRequest = class extends BaseTransactionRequest {
|
|
3911
3996
|
* @deprecated Use `provider.assembleTx` instead.
|
3912
3997
|
* Check the migration guide https://docs.fuel.network/guide/assembling-transactions/migration-guide.html for more information.
|
3913
3998
|
*/
|
3914
|
-
async estimateAndFund(account, {
|
3999
|
+
async estimateAndFund(account, {
|
4000
|
+
signatureCallback,
|
4001
|
+
quantities = [],
|
4002
|
+
skipAutoConsolidation
|
4003
|
+
} = {}) {
|
3915
4004
|
const txCost = await account.getTransactionCost(this, { signatureCallback, quantities });
|
3916
4005
|
this.maxFee = txCost.maxFee;
|
3917
4006
|
this.gasLimit = txCost.gasUsed;
|
3918
|
-
await account.fund(this, txCost);
|
4007
|
+
await account.fund(this, txCost, { skipAutoConsolidation });
|
3919
4008
|
return this;
|
3920
4009
|
}
|
3921
4010
|
/**
|
@@ -4484,12 +4573,12 @@ var ResourceCache = class {
|
|
4484
4573
|
// src/providers/transaction-response/transaction-response.ts
|
4485
4574
|
import { ErrorCode as ErrorCode15, FuelError as FuelError18 } from "@fuel-ts/errors";
|
4486
4575
|
import { bn as bn17 } from "@fuel-ts/math";
|
4487
|
-
import { TransactionCoder as
|
4488
|
-
import { arrayify as
|
4576
|
+
import { TransactionCoder as TransactionCoder6, TxPointerCoder } from "@fuel-ts/transactions";
|
4577
|
+
import { arrayify as arrayify13 } from "@fuel-ts/utils";
|
4489
4578
|
|
4490
4579
|
// src/providers/transaction-summary/assemble-transaction-summary.ts
|
4491
4580
|
import { bn as bn16 } from "@fuel-ts/math";
|
4492
|
-
import { PolicyType as PolicyType3, TransactionCoder as
|
4581
|
+
import { PolicyType as PolicyType3, TransactionCoder as TransactionCoder5 } from "@fuel-ts/transactions";
|
4493
4582
|
import { DateTime, hexlify as hexlify18 } from "@fuel-ts/utils";
|
4494
4583
|
|
4495
4584
|
// src/providers/transaction-summary/calculate-tx-fee-for-summary.ts
|
@@ -4561,8 +4650,47 @@ var calculateTXFeeForSummary = /* @__PURE__ */ __name((params) => {
|
|
4561
4650
|
// src/providers/transaction-summary/operations.ts
|
4562
4651
|
import { ZeroBytes32 as ZeroBytes329 } from "@fuel-ts/address/configs";
|
4563
4652
|
import { ErrorCode as ErrorCode13, FuelError as FuelError16 } from "@fuel-ts/errors";
|
4564
|
-
import { bn as bn14 } from "@fuel-ts/math";
|
4565
|
-
import { ReceiptType as ReceiptType5, TransactionType as TransactionType10 } from "@fuel-ts/transactions";
|
4653
|
+
import { bn as bn14, toBytes as toBytes2 } from "@fuel-ts/math";
|
4654
|
+
import { ReceiptType as ReceiptType5, TransactionCoder as TransactionCoder4, TransactionType as TransactionType10 } from "@fuel-ts/transactions";
|
4655
|
+
import { arrayify as arrayify12, concat as concat4 } from "@fuel-ts/utils";
|
4656
|
+
|
4657
|
+
// src/providers/transaction-summary/call.ts
|
4658
|
+
import { StdStringCoder } from "@fuel-ts/abi-coder";
|
4659
|
+
import { Interface as Interface2 } from "@fuel-ts/abi-coder";
|
4660
|
+
var getFunctionCall = /* @__PURE__ */ __name(({
|
4661
|
+
abi,
|
4662
|
+
receipt,
|
4663
|
+
offset,
|
4664
|
+
scriptData
|
4665
|
+
}) => {
|
4666
|
+
const [functionSelector, argumentsOffset] = new StdStringCoder().decode(scriptData, offset);
|
4667
|
+
const abiInterface = new Interface2(abi);
|
4668
|
+
const functionFragment = abiInterface.getFunction(functionSelector);
|
4669
|
+
const inputs = functionFragment.jsonFn.inputs;
|
4670
|
+
let argumentsProvided;
|
4671
|
+
if (inputs.length) {
|
4672
|
+
const functionArgsBytes = scriptData.slice(argumentsOffset);
|
4673
|
+
const decodedArguments = functionFragment.decodeArguments(functionArgsBytes);
|
4674
|
+
argumentsProvided = inputs.reduce((prev, input, index) => {
|
4675
|
+
const value = decodedArguments?.[index];
|
4676
|
+
const name = input.name;
|
4677
|
+
if (name) {
|
4678
|
+
return {
|
4679
|
+
...prev,
|
4680
|
+
// reparse to remove bn
|
4681
|
+
[name]: JSON.parse(JSON.stringify(value))
|
4682
|
+
};
|
4683
|
+
}
|
4684
|
+
return prev;
|
4685
|
+
}, {});
|
4686
|
+
}
|
4687
|
+
return {
|
4688
|
+
functionSignature: functionFragment.signature,
|
4689
|
+
functionName: functionFragment.name,
|
4690
|
+
argumentsProvided,
|
4691
|
+
...receipt.amount?.isZero() ? {} : { amount: receipt.amount, assetId: receipt.assetId }
|
4692
|
+
};
|
4693
|
+
}, "getFunctionCall");
|
4566
4694
|
|
4567
4695
|
// src/providers/transaction-summary/input.ts
|
4568
4696
|
import { ErrorCode as ErrorCode12, FuelError as FuelError15 } from "@fuel-ts/errors";
|
@@ -4846,12 +4974,45 @@ function getWithdrawFromFuelOperations({
|
|
4846
4974
|
return withdrawFromFuelOperations;
|
4847
4975
|
}
|
4848
4976
|
__name(getWithdrawFromFuelOperations, "getWithdrawFromFuelOperations");
|
4849
|
-
function
|
4850
|
-
|
4851
|
-
|
4852
|
-
|
4977
|
+
function findBytesSegmentIndex(whole, segment) {
|
4978
|
+
for (let i = 0; i <= whole.length - segment.length; i++) {
|
4979
|
+
let match = true;
|
4980
|
+
for (let j = 0; j < segment.length; j++) {
|
4981
|
+
if (whole[i + j] !== segment[j]) {
|
4982
|
+
match = false;
|
4983
|
+
break;
|
4984
|
+
}
|
4985
|
+
}
|
4986
|
+
if (match) {
|
4987
|
+
return i;
|
4988
|
+
}
|
4853
4989
|
}
|
4854
|
-
return
|
4990
|
+
return -1;
|
4991
|
+
}
|
4992
|
+
__name(findBytesSegmentIndex, "findBytesSegmentIndex");
|
4993
|
+
function getContractCalls(contractInput, abiMap, receipt, scriptData) {
|
4994
|
+
const calls = [];
|
4995
|
+
const abi = abiMap?.[contractInput.contractID];
|
4996
|
+
if (!abi || !scriptData) {
|
4997
|
+
return calls;
|
4998
|
+
}
|
4999
|
+
const bytesSegment = concat4([
|
5000
|
+
arrayify12(receipt.to),
|
5001
|
+
// Contract ID (32 bytes)
|
5002
|
+
toBytes2(receipt.param1.toHex(), 8),
|
5003
|
+
// Function selector offset (8 bytes)
|
5004
|
+
toBytes2(receipt.param2.toHex(), 8)
|
5005
|
+
// Function args offset (8 bytes)
|
5006
|
+
]);
|
5007
|
+
const segmentIndex = findBytesSegmentIndex(scriptData, bytesSegment);
|
5008
|
+
const canDecodeFunctionCall = segmentIndex !== -1;
|
5009
|
+
if (!canDecodeFunctionCall) {
|
5010
|
+
return calls;
|
5011
|
+
}
|
5012
|
+
const offset = segmentIndex + bytesSegment.length;
|
5013
|
+
const call = getFunctionCall({ abi, receipt, offset, scriptData });
|
5014
|
+
calls.push(call);
|
5015
|
+
return calls;
|
4855
5016
|
}
|
4856
5017
|
__name(getContractCalls, "getContractCalls");
|
4857
5018
|
function getAssetsSent(receipt) {
|
@@ -4863,14 +5024,14 @@ function getAssetsSent(receipt) {
|
|
4863
5024
|
];
|
4864
5025
|
}
|
4865
5026
|
__name(getAssetsSent, "getAssetsSent");
|
4866
|
-
function processCallReceipt(receipt, contractInput, inputs, abiMap,
|
5027
|
+
function processCallReceipt(receipt, contractInput, inputs, abiMap, scriptData, baseAssetId) {
|
4867
5028
|
const assetId = receipt.assetId === ZeroBytes329 ? baseAssetId : receipt.assetId;
|
4868
5029
|
const input = getInputFromAssetId(inputs, assetId, assetId === baseAssetId);
|
4869
5030
|
if (!input) {
|
4870
5031
|
return [];
|
4871
5032
|
}
|
4872
5033
|
const inputAddress = getInputAccountAddress(input);
|
4873
|
-
const calls = getContractCalls(contractInput, abiMap, receipt,
|
5034
|
+
const calls = getContractCalls(contractInput, abiMap, receipt, scriptData);
|
4874
5035
|
return [
|
4875
5036
|
{
|
4876
5037
|
name: "Contract call" /* contractCall */,
|
@@ -4895,7 +5056,6 @@ function getContractCallOperations({
|
|
4895
5056
|
receipts,
|
4896
5057
|
abiMap,
|
4897
5058
|
rawPayload,
|
4898
|
-
maxInputs,
|
4899
5059
|
baseAssetId
|
4900
5060
|
}) {
|
4901
5061
|
const contractCallReceipts = getReceiptsCall(receipts);
|
@@ -4905,16 +5065,15 @@ function getContractCallOperations({
|
|
4905
5065
|
if (!contractInput) {
|
4906
5066
|
return [];
|
4907
5067
|
}
|
5068
|
+
let scriptData;
|
5069
|
+
if (rawPayload) {
|
5070
|
+
const [transaction] = new TransactionCoder4().decode(arrayify12(rawPayload), 0);
|
5071
|
+
if (transaction.type === TransactionType10.Script) {
|
5072
|
+
scriptData = arrayify12(transaction.scriptData);
|
5073
|
+
}
|
5074
|
+
}
|
4908
5075
|
return contractCallReceipts.filter((receipt) => receipt.to === contractInput.contractID).flatMap(
|
4909
|
-
(receipt) => processCallReceipt(
|
4910
|
-
receipt,
|
4911
|
-
contractInput,
|
4912
|
-
inputs,
|
4913
|
-
abiMap,
|
4914
|
-
rawPayload,
|
4915
|
-
maxInputs,
|
4916
|
-
baseAssetId
|
4917
|
-
)
|
5076
|
+
(receipt) => processCallReceipt(receipt, contractInput, inputs, abiMap, scriptData, baseAssetId)
|
4918
5077
|
);
|
4919
5078
|
});
|
4920
5079
|
}
|
@@ -5330,7 +5489,7 @@ function assemblePreConfirmationTransactionSummary(params) {
|
|
5330
5489
|
type = getTransactionTypeName(transaction.type);
|
5331
5490
|
tip = bn16(transaction.policies?.find((policy) => policy.type === PolicyType3.Tip)?.data);
|
5332
5491
|
if (receipts) {
|
5333
|
-
const rawPayload = hexlify18(new
|
5492
|
+
const rawPayload = hexlify18(new TransactionCoder5().encode(transaction));
|
5334
5493
|
operations = getOperations({
|
5335
5494
|
transactionType: transaction.type,
|
5336
5495
|
inputs: transaction.inputs || [],
|
@@ -5376,7 +5535,7 @@ function assemblePreConfirmationTransactionSummary(params) {
|
|
5376
5535
|
__name(assemblePreConfirmationTransactionSummary, "assemblePreConfirmationTransactionSummary");
|
5377
5536
|
|
5378
5537
|
// src/providers/transaction-response/getAllDecodedLogs.ts
|
5379
|
-
import { Interface as
|
5538
|
+
import { Interface as Interface3, BigNumberCoder } from "@fuel-ts/abi-coder";
|
5380
5539
|
import { ZeroBytes32 as ZeroBytes3210 } from "@fuel-ts/address/configs";
|
5381
5540
|
import { ReceiptType as ReceiptType7 } from "@fuel-ts/transactions";
|
5382
5541
|
function getAllDecodedLogs(opts) {
|
@@ -5396,7 +5555,7 @@ function getAllDecodedLogs(opts) {
|
|
5396
5555
|
const isLogFromMainAbi = receipt.id === ZeroBytes3210 || mainContract === receipt.id;
|
5397
5556
|
const isDecodable = isLogFromMainAbi || externalAbis[receipt.id];
|
5398
5557
|
if (isDecodable) {
|
5399
|
-
const interfaceToUse = isLogFromMainAbi ? new
|
5558
|
+
const interfaceToUse = isLogFromMainAbi ? new Interface3(mainAbi) : new Interface3(externalAbis[receipt.id]);
|
5400
5559
|
const data = receipt.type === ReceiptType7.Log ? new BigNumberCoder("u64").encode(receipt.ra) : receipt.data;
|
5401
5560
|
const [decodedLog] = interfaceToUse.decodeLog(data, receipt.rb.toString());
|
5402
5561
|
logs.push(decodedLog);
|
@@ -5412,25 +5571,6 @@ __name(getAllDecodedLogs, "getAllDecodedLogs");
|
|
5412
5571
|
|
5413
5572
|
// src/providers/transaction-response/transaction-response.ts
|
5414
5573
|
var TransactionResponse = class _TransactionResponse {
|
5415
|
-
/**
|
5416
|
-
* Constructor for `TransactionResponse`.
|
5417
|
-
*
|
5418
|
-
* @param tx - The transaction ID or TransactionRequest.
|
5419
|
-
* @param provider - The provider.
|
5420
|
-
*/
|
5421
|
-
constructor(tx, provider, chainId, abis, submitTxSubscription) {
|
5422
|
-
this.submitTxSubscription = submitTxSubscription;
|
5423
|
-
if (typeof tx === "string") {
|
5424
|
-
this.id = tx;
|
5425
|
-
} else {
|
5426
|
-
this.id = tx.getTransactionId(chainId);
|
5427
|
-
this.request = tx;
|
5428
|
-
}
|
5429
|
-
this.provider = provider;
|
5430
|
-
this.abis = abis;
|
5431
|
-
this.waitForResult = this.waitForResult.bind(this);
|
5432
|
-
this.waitForPreConfirmation = this.waitForPreConfirmation.bind(this);
|
5433
|
-
}
|
5434
5574
|
static {
|
5435
5575
|
__name(this, "TransactionResponse");
|
5436
5576
|
}
|
@@ -5445,9 +5585,42 @@ var TransactionResponse = class _TransactionResponse {
|
|
5445
5585
|
request;
|
5446
5586
|
status;
|
5447
5587
|
abis;
|
5588
|
+
submitTxSubscription;
|
5448
5589
|
preConfirmationStatus;
|
5449
5590
|
waitingForStreamData = false;
|
5450
5591
|
statusResolvers = /* @__PURE__ */ new Map();
|
5592
|
+
/**
|
5593
|
+
* Constructor for `TransactionResponse`.
|
5594
|
+
*/
|
5595
|
+
constructor(constructorParams, provider, chainId, abis, submitTxSubscription) {
|
5596
|
+
let tx;
|
5597
|
+
let _provider;
|
5598
|
+
let _chainId;
|
5599
|
+
let _abis;
|
5600
|
+
if (typeof constructorParams === "object" && "provider" in constructorParams && arguments.length === 1) {
|
5601
|
+
tx = constructorParams.transactionRequestOrId;
|
5602
|
+
_provider = constructorParams.provider;
|
5603
|
+
_chainId = constructorParams.chainId;
|
5604
|
+
_abis = constructorParams.abis;
|
5605
|
+
this.submitTxSubscription = constructorParams.submitAndAwaitSubscription;
|
5606
|
+
} else {
|
5607
|
+
tx = constructorParams;
|
5608
|
+
_provider = provider;
|
5609
|
+
_chainId = chainId;
|
5610
|
+
_abis = abis;
|
5611
|
+
this.submitTxSubscription = submitTxSubscription;
|
5612
|
+
}
|
5613
|
+
if (typeof tx === "string") {
|
5614
|
+
this.id = tx;
|
5615
|
+
} else {
|
5616
|
+
this.id = tx.getTransactionId(_chainId);
|
5617
|
+
this.request = tx;
|
5618
|
+
}
|
5619
|
+
this.provider = _provider;
|
5620
|
+
this.abis = _abis;
|
5621
|
+
this.waitForResult = this.waitForResult.bind(this);
|
5622
|
+
this.waitForPreConfirmation = this.waitForPreConfirmation.bind(this);
|
5623
|
+
}
|
5451
5624
|
/**
|
5452
5625
|
* Async constructor for `TransactionResponse`. This method can be used to create
|
5453
5626
|
* an instance of `TransactionResponse` and wait for the transaction to be fetched
|
@@ -5496,8 +5669,8 @@ var TransactionResponse = class _TransactionResponse {
|
|
5496
5669
|
}
|
5497
5670
|
const gqlTransaction = this.gqlTransaction ?? await this.fetch();
|
5498
5671
|
const { rawPayload } = gqlTransaction;
|
5499
|
-
const bytes =
|
5500
|
-
const [tx] = new
|
5672
|
+
const bytes = arrayify13(rawPayload);
|
5673
|
+
const [tx] = new TransactionCoder6().decode(bytes, 0);
|
5501
5674
|
return {
|
5502
5675
|
tx,
|
5503
5676
|
bytes
|
@@ -5684,6 +5857,7 @@ var TransactionResponse = class _TransactionResponse {
|
|
5684
5857
|
...transactionSummary
|
5685
5858
|
};
|
5686
5859
|
let { logs, groupedLogs } = { logs: [], groupedLogs: {} };
|
5860
|
+
let abis;
|
5687
5861
|
if (this.abis) {
|
5688
5862
|
({ logs, groupedLogs } = getAllDecodedLogs({
|
5689
5863
|
receipts: transactionSummary.receipts,
|
@@ -5692,6 +5866,7 @@ var TransactionResponse = class _TransactionResponse {
|
|
5692
5866
|
}));
|
5693
5867
|
transactionResult.logs = logs;
|
5694
5868
|
transactionResult.groupedLogs = groupedLogs;
|
5869
|
+
abis = this.abis;
|
5695
5870
|
}
|
5696
5871
|
const { receipts } = transactionResult;
|
5697
5872
|
const status = this.getTransactionStatus();
|
@@ -5701,7 +5876,8 @@ var TransactionResponse = class _TransactionResponse {
|
|
5701
5876
|
receipts,
|
5702
5877
|
statusReason: reason,
|
5703
5878
|
logs,
|
5704
|
-
groupedLogs
|
5879
|
+
groupedLogs,
|
5880
|
+
abis
|
5705
5881
|
});
|
5706
5882
|
}
|
5707
5883
|
return transactionResult;
|
@@ -5763,7 +5939,7 @@ var TransactionResponse = class _TransactionResponse {
|
|
5763
5939
|
};
|
5764
5940
|
|
5765
5941
|
// src/providers/transaction-response/getDecodedLogs.ts
|
5766
|
-
import { Interface as
|
5942
|
+
import { Interface as Interface4, BigNumberCoder as BigNumberCoder2 } from "@fuel-ts/abi-coder";
|
5767
5943
|
import { ZeroBytes32 as ZeroBytes3211 } from "@fuel-ts/address/configs";
|
5768
5944
|
import { ReceiptType as ReceiptType8 } from "@fuel-ts/transactions";
|
5769
5945
|
|
@@ -5961,7 +6137,15 @@ var Provider = class _Provider {
|
|
5961
6137
|
if (_Provider.ENABLE_RPC_CONSISTENCY && _Provider.hasWriteOperationHappened(url)) {
|
5962
6138
|
_Provider.applyBlockHeight(fullRequest, url);
|
5963
6139
|
}
|
5964
|
-
|
6140
|
+
const response = await _Provider.fetchAndProcessBlockHeight(url, fullRequest, options);
|
6141
|
+
if (response.body === null) {
|
6142
|
+
throw new FuelError20(
|
6143
|
+
ErrorCode17.RESPONSE_BODY_EMPTY,
|
6144
|
+
"The response from the server is missing the body",
|
6145
|
+
{ timestamp: (/* @__PURE__ */ new Date()).toISOString(), request, response }
|
6146
|
+
);
|
6147
|
+
}
|
6148
|
+
return response;
|
5965
6149
|
}, retryOptions);
|
5966
6150
|
}
|
5967
6151
|
static applyBlockHeight(request, url) {
|
@@ -5984,13 +6168,15 @@ var Provider = class _Provider {
|
|
5984
6168
|
baseDelay: 500
|
5985
6169
|
};
|
5986
6170
|
for (let retriesLeft = retryOptions.maxRetries; retriesLeft > 0; --retriesLeft) {
|
5987
|
-
|
5988
|
-
|
5989
|
-
|
5990
|
-
|
5991
|
-
|
5992
|
-
|
5993
|
-
|
6171
|
+
if (response.body) {
|
6172
|
+
const { extensions } = await parseGraphqlResponse({
|
6173
|
+
response,
|
6174
|
+
isSubscription: url.endsWith("-sub")
|
6175
|
+
});
|
6176
|
+
_Provider.setCurrentBlockHeight(url, extensions?.current_fuel_block_height);
|
6177
|
+
if (!extensions?.fuel_block_height_precondition_failed) {
|
6178
|
+
break;
|
6179
|
+
}
|
5994
6180
|
}
|
5995
6181
|
const retryAttempt = retryOptions.maxRetries - retriesLeft + 1;
|
5996
6182
|
const sleepTime = getWaitDelay(retryOptions, retryAttempt);
|
@@ -6413,7 +6599,13 @@ var Provider = class _Provider {
|
|
6413
6599
|
transactionRequest.getTransactionId(await this.getChainId())
|
6414
6600
|
);
|
6415
6601
|
const chainId = await this.getChainId();
|
6416
|
-
return new TransactionResponse(
|
6602
|
+
return new TransactionResponse({
|
6603
|
+
transactionRequestOrId: transactionRequest,
|
6604
|
+
provider: this,
|
6605
|
+
chainId,
|
6606
|
+
abis,
|
6607
|
+
submitAndAwaitSubscription: subscription
|
6608
|
+
});
|
6417
6609
|
}
|
6418
6610
|
/**
|
6419
6611
|
* Executes a transaction without actually submitting it to the chain.
|
@@ -7143,7 +7335,7 @@ var Provider = class _Provider {
|
|
7143
7335
|
},
|
7144
7336
|
transactionIds: block.transactions.map((tx) => tx.id),
|
7145
7337
|
transactions: block.transactions.map(
|
7146
|
-
(tx) => new
|
7338
|
+
(tx) => new TransactionCoder7().decode(arrayify14(tx.rawPayload), 0)?.[0]
|
7147
7339
|
)
|
7148
7340
|
};
|
7149
7341
|
}
|
@@ -7159,8 +7351,8 @@ var Provider = class _Provider {
|
|
7159
7351
|
return null;
|
7160
7352
|
}
|
7161
7353
|
try {
|
7162
|
-
return new
|
7163
|
-
|
7354
|
+
return new TransactionCoder7().decode(
|
7355
|
+
arrayify14(transaction.rawPayload),
|
7164
7356
|
0
|
7165
7357
|
)?.[0];
|
7166
7358
|
} catch (error) {
|
@@ -7185,10 +7377,10 @@ var Provider = class _Provider {
|
|
7185
7377
|
paginationLimit: TRANSACTIONS_PAGE_SIZE_LIMIT
|
7186
7378
|
})
|
7187
7379
|
});
|
7188
|
-
const coder = new
|
7380
|
+
const coder = new TransactionCoder7();
|
7189
7381
|
const transactions = edges.map(({ node: { rawPayload } }) => {
|
7190
7382
|
try {
|
7191
|
-
return coder.decode(
|
7383
|
+
return coder.decode(arrayify14(rawPayload), 0)[0];
|
7192
7384
|
} catch (error) {
|
7193
7385
|
if (error instanceof FuelError20 && error.code === ErrorCode17.UNSUPPORTED_TRANSACTION_TYPE) {
|
7194
7386
|
console.warn("Unsupported transaction type encountered");
|
@@ -7508,7 +7700,11 @@ var Provider = class _Provider {
|
|
7508
7700
|
*/
|
7509
7701
|
async getTransactionResponse(transactionId) {
|
7510
7702
|
const chainId = await this.getChainId();
|
7511
|
-
return new TransactionResponse(
|
7703
|
+
return new TransactionResponse({
|
7704
|
+
transactionRequestOrId: transactionId,
|
7705
|
+
provider: this,
|
7706
|
+
chainId
|
7707
|
+
});
|
7512
7708
|
}
|
7513
7709
|
/**
|
7514
7710
|
* Returns Message for given nonce.
|
@@ -7559,18 +7755,21 @@ var Provider = class _Provider {
|
|
7559
7755
|
extractDryRunError(transactionRequest, receipts, reason) {
|
7560
7756
|
let logs = [];
|
7561
7757
|
let groupedLogs = {};
|
7758
|
+
let abis;
|
7562
7759
|
if (transactionRequest.type === TransactionType11.Script && transactionRequest.abis) {
|
7563
7760
|
({ logs, groupedLogs } = getAllDecodedLogs({
|
7564
7761
|
receipts,
|
7565
7762
|
mainAbi: transactionRequest.abis.main,
|
7566
7763
|
externalAbis: transactionRequest.abis.otherContractsAbis
|
7567
7764
|
}));
|
7765
|
+
abis = transactionRequest.abis;
|
7568
7766
|
}
|
7569
7767
|
return extractTxError({
|
7570
7768
|
logs,
|
7571
7769
|
groupedLogs,
|
7572
7770
|
receipts,
|
7573
|
-
statusReason: reason
|
7771
|
+
statusReason: reason,
|
7772
|
+
abis
|
7574
7773
|
});
|
7575
7774
|
}
|
7576
7775
|
/**
|
@@ -7641,13 +7840,13 @@ var Provider = class _Provider {
|
|
7641
7840
|
// src/providers/transaction-summary/get-transaction-summary.ts
|
7642
7841
|
import { ErrorCode as ErrorCode18, FuelError as FuelError21 } from "@fuel-ts/errors";
|
7643
7842
|
import { bn as bn19 } from "@fuel-ts/math";
|
7644
|
-
import { TransactionCoder as
|
7645
|
-
import { arrayify as
|
7843
|
+
import { TransactionCoder as TransactionCoder8 } from "@fuel-ts/transactions";
|
7844
|
+
import { arrayify as arrayify15 } from "@fuel-ts/utils";
|
7646
7845
|
|
7647
7846
|
// src/providers/transaction-summary/assemble-transaction-summary-from-serialized.ts
|
7648
7847
|
import { bn as bn20 } from "@fuel-ts/math";
|
7649
|
-
import { TransactionCoder as
|
7650
|
-
import { arrayify as
|
7848
|
+
import { TransactionCoder as TransactionCoder9 } from "@fuel-ts/transactions";
|
7849
|
+
import { arrayify as arrayify16 } from "@fuel-ts/utils";
|
7651
7850
|
|
7652
7851
|
// src/test-utils/test-asset-id.ts
|
7653
7852
|
import { randomBytes as randomBytes4 } from "@fuel-ts/crypto";
|
@@ -7676,8 +7875,8 @@ var TestAssetId = class _TestAssetId {
|
|
7676
7875
|
|
7677
7876
|
// src/test-utils/wallet-config.ts
|
7678
7877
|
import { randomBytes as randomBytes8 } from "@fuel-ts/crypto";
|
7679
|
-
import { FuelError as
|
7680
|
-
import { bn as
|
7878
|
+
import { FuelError as FuelError28 } from "@fuel-ts/errors";
|
7879
|
+
import { bn as bn24 } from "@fuel-ts/math";
|
7681
7880
|
import { defaultSnapshotConfigs as defaultSnapshotConfigs2, hexlify as hexlify26 } from "@fuel-ts/utils";
|
7682
7881
|
|
7683
7882
|
// src/wallet/base-wallet-unlocked.ts
|
@@ -7686,12 +7885,12 @@ import { hexlify as hexlify23 } from "@fuel-ts/utils";
|
|
7686
7885
|
|
7687
7886
|
// src/account.ts
|
7688
7887
|
import { UTXO_ID_LEN as UTXO_ID_LEN3 } from "@fuel-ts/abi-coder";
|
7689
|
-
import { Address as
|
7888
|
+
import { Address as Address6 } from "@fuel-ts/address";
|
7690
7889
|
import { randomBytes as randomBytes5 } from "@fuel-ts/crypto";
|
7691
|
-
import { ErrorCode as
|
7692
|
-
import { bn as
|
7693
|
-
import { InputType as InputType8, OutputType as
|
7694
|
-
import { arrayify as
|
7890
|
+
import { ErrorCode as ErrorCode20, FuelError as FuelError23 } from "@fuel-ts/errors";
|
7891
|
+
import { bn as bn22 } from "@fuel-ts/math";
|
7892
|
+
import { InputType as InputType8, OutputType as OutputType10 } from "@fuel-ts/transactions";
|
7893
|
+
import { arrayify as arrayify18, hexlify as hexlify21, isDefined as isDefined4 } from "@fuel-ts/utils";
|
7695
7894
|
import { clone as clone9 } from "ramda";
|
7696
7895
|
|
7697
7896
|
// src/types.ts
|
@@ -7701,18 +7900,166 @@ var AbstractAccount = class {
|
|
7701
7900
|
}
|
7702
7901
|
};
|
7703
7902
|
|
7903
|
+
// src/utils/consolidate-coins.ts
|
7904
|
+
import { Address as Address4 } from "@fuel-ts/address";
|
7905
|
+
import { ErrorCode as ErrorCode19, FuelError as FuelError22 } from "@fuel-ts/errors";
|
7906
|
+
import { bn as bn21 } from "@fuel-ts/math";
|
7907
|
+
import { OutputType as OutputType9 } from "@fuel-ts/transactions";
|
7908
|
+
import { splitEvery } from "ramda";
|
7909
|
+
var CONSOLIDATABLE_ERROR_CODES = [ErrorCode19.MAX_COINS_REACHED];
|
7910
|
+
var consolidateCoinsIfRequired = /* @__PURE__ */ __name(async (opts) => {
|
7911
|
+
const { error: errorUnknown, account, skipAutoConsolidation = false } = opts;
|
7912
|
+
if (skipAutoConsolidation) {
|
7913
|
+
return false;
|
7914
|
+
}
|
7915
|
+
const error = FuelError22.parse(errorUnknown);
|
7916
|
+
if (CONSOLIDATABLE_ERROR_CODES.includes(error.code)) {
|
7917
|
+
const { assetId, owner } = error.metadata;
|
7918
|
+
return account.startConsolidation({
|
7919
|
+
owner,
|
7920
|
+
assetId
|
7921
|
+
});
|
7922
|
+
}
|
7923
|
+
return false;
|
7924
|
+
}, "consolidateCoinsIfRequired");
|
7925
|
+
var getAllCoins = /* @__PURE__ */ __name(async (account, assetId) => {
|
7926
|
+
const all = [];
|
7927
|
+
let hasNextPage = true;
|
7928
|
+
let after;
|
7929
|
+
while (hasNextPage) {
|
7930
|
+
const { coins, pageInfo } = await account.getCoins(assetId, { after });
|
7931
|
+
all.push(...coins);
|
7932
|
+
after = coins.pop()?.id;
|
7933
|
+
hasNextPage = pageInfo.hasNextPage;
|
7934
|
+
}
|
7935
|
+
return { coins: all };
|
7936
|
+
}, "getAllCoins");
|
7937
|
+
var sortCoins = /* @__PURE__ */ __name(({ coins }) => coins.sort((a, b) => b.amount.cmp(a.amount)), "sortCoins");
|
7938
|
+
var createOuputCoin = /* @__PURE__ */ __name((opts) => {
|
7939
|
+
const { transactionId, outputs, baseAssetId } = opts;
|
7940
|
+
const outputChangeIndex = outputs.findIndex(
|
7941
|
+
(output) => output.type === OutputType9.Change && output.assetId === baseAssetId
|
7942
|
+
);
|
7943
|
+
if (outputChangeIndex === -1) {
|
7944
|
+
throw new FuelError22(ErrorCode19.UNKNOWN, "No change output found");
|
7945
|
+
}
|
7946
|
+
const outputCoin = outputs[outputChangeIndex];
|
7947
|
+
const outputIndexPadded = Number(outputChangeIndex).toString().padStart(4, "0");
|
7948
|
+
return {
|
7949
|
+
id: `${transactionId}${outputIndexPadded}`,
|
7950
|
+
assetId: outputCoin.assetId,
|
7951
|
+
amount: outputCoin.amount,
|
7952
|
+
owner: new Address4(outputCoin.to),
|
7953
|
+
blockCreated: bn21(0),
|
7954
|
+
txCreatedIdx: bn21(0)
|
7955
|
+
};
|
7956
|
+
}, "createOuputCoin");
|
7957
|
+
var consolidateCoins = /* @__PURE__ */ __name(async ({
|
7958
|
+
account,
|
7959
|
+
assetId
|
7960
|
+
}) => {
|
7961
|
+
const chainInfo = await account.provider.getChain();
|
7962
|
+
const chainId = chainInfo.consensusParameters.chainId.toNumber();
|
7963
|
+
const gasPrice = await account.provider.estimateGasPrice(10);
|
7964
|
+
const maxInputs = chainInfo.consensusParameters.txParameters.maxInputs.toNumber();
|
7965
|
+
const baseAssetId = await account.provider.getBaseAssetId();
|
7966
|
+
const isBaseAsset = assetId === baseAssetId;
|
7967
|
+
const batchSize = maxInputs;
|
7968
|
+
const numberOfFundingCoins = maxInputs;
|
7969
|
+
let funding = [];
|
7970
|
+
let dust = [];
|
7971
|
+
if (isBaseAsset) {
|
7972
|
+
const coins = await getAllCoins(account, baseAssetId).then(sortCoins);
|
7973
|
+
funding = coins.slice(0, numberOfFundingCoins);
|
7974
|
+
dust = coins.slice(numberOfFundingCoins);
|
7975
|
+
} else {
|
7976
|
+
funding = await getAllCoins(account, baseAssetId).then(sortCoins).then((coins) => coins.slice(0, numberOfFundingCoins));
|
7977
|
+
dust = await getAllCoins(account, assetId).then(({ coins }) => coins);
|
7978
|
+
}
|
7979
|
+
if (funding.length === 0) {
|
7980
|
+
throw new FuelError22(
|
7981
|
+
ErrorCode19.INSUFFICIENT_FUNDS,
|
7982
|
+
`Insufficient funds to consolidate.
|
7983
|
+
Asset ID: ${baseAssetId}
|
7984
|
+
Owner: ${account.address.toB256()}`
|
7985
|
+
);
|
7986
|
+
}
|
7987
|
+
const batches = [
|
7988
|
+
...splitEvery(batchSize, funding),
|
7989
|
+
// We leave one coin for the funding coin
|
7990
|
+
...splitEvery(batchSize - 1, dust)
|
7991
|
+
];
|
7992
|
+
const txs = batches.map((batch) => {
|
7993
|
+
const request = new ScriptTransactionRequest({
|
7994
|
+
scriptData: "0x"
|
7995
|
+
});
|
7996
|
+
request.addResources(batch);
|
7997
|
+
return request;
|
7998
|
+
});
|
7999
|
+
const submitAll = /* @__PURE__ */ __name(async (opts = {}) => {
|
8000
|
+
const txResponses = [];
|
8001
|
+
let previousTx;
|
8002
|
+
for (let i = 0; i < txs.length; i++) {
|
8003
|
+
let currentTx = txs[i];
|
8004
|
+
const step = i + 1;
|
8005
|
+
if (previousTx) {
|
8006
|
+
const coin = createOuputCoin({
|
8007
|
+
transactionId: previousTx.transactionId,
|
8008
|
+
outputs: previousTx.outputs,
|
8009
|
+
baseAssetId
|
8010
|
+
});
|
8011
|
+
currentTx.addResource(coin);
|
8012
|
+
}
|
8013
|
+
if ("populateTransactionPredicateData" in account && typeof account.populateTransactionPredicateData === "function") {
|
8014
|
+
currentTx = account.populateTransactionPredicateData(currentTx);
|
8015
|
+
currentTx = await account.provider.estimatePredicates(currentTx);
|
8016
|
+
}
|
8017
|
+
const fee = calculateGasFee({
|
8018
|
+
gasPrice,
|
8019
|
+
gas: currentTx.calculateMinGas(chainInfo),
|
8020
|
+
priceFactor: chainInfo.consensusParameters.feeParameters.gasPriceFactor,
|
8021
|
+
tip: currentTx.tip
|
8022
|
+
});
|
8023
|
+
currentTx.maxFee = fee;
|
8024
|
+
currentTx.gasLimit = bn21(1e3);
|
8025
|
+
opts.onTransactionStart?.({
|
8026
|
+
tx: currentTx,
|
8027
|
+
step,
|
8028
|
+
assetId,
|
8029
|
+
transactionId: currentTx.getTransactionId(chainId)
|
8030
|
+
});
|
8031
|
+
const response = await account.sendTransaction(currentTx);
|
8032
|
+
const result = await response.waitForResult();
|
8033
|
+
txResponses.push(result);
|
8034
|
+
previousTx = {
|
8035
|
+
transactionId: response.id,
|
8036
|
+
outputs: result.transaction.outputs
|
8037
|
+
};
|
8038
|
+
}
|
8039
|
+
return {
|
8040
|
+
txResponses,
|
8041
|
+
errors: []
|
8042
|
+
};
|
8043
|
+
}, "submitAll");
|
8044
|
+
return {
|
8045
|
+
txs,
|
8046
|
+
totalFeeCost: txs.reduce((acc, request) => acc.add(request.maxFee), bn21(0)),
|
8047
|
+
submitAll
|
8048
|
+
};
|
8049
|
+
}, "consolidateCoins");
|
8050
|
+
|
7704
8051
|
// src/utils/formatTransferToContractScriptData.ts
|
7705
8052
|
import { ASSET_ID_LEN, BigNumberCoder as BigNumberCoder3, CONTRACT_ID_LEN, WORD_SIZE } from "@fuel-ts/abi-coder";
|
7706
|
-
import { Address as
|
7707
|
-
import { arrayify as
|
8053
|
+
import { Address as Address5 } from "@fuel-ts/address";
|
8054
|
+
import { arrayify as arrayify17, concat as concat5 } from "@fuel-ts/utils";
|
7708
8055
|
import * as asm from "@fuels/vm-asm";
|
7709
8056
|
var formatTransferToContractScriptData = /* @__PURE__ */ __name((transferParams) => {
|
7710
8057
|
const numberCoder = new BigNumberCoder3("u64");
|
7711
8058
|
return transferParams.reduce((acc, transferParam) => {
|
7712
8059
|
const { assetId, amount, contractId } = transferParam;
|
7713
8060
|
const encoded = numberCoder.encode(amount);
|
7714
|
-
const scriptData =
|
7715
|
-
return
|
8061
|
+
const scriptData = concat5([new Address5(contractId).toBytes(), encoded, arrayify17(assetId)]);
|
8062
|
+
return concat5([acc, scriptData]);
|
7716
8063
|
}, new Uint8Array());
|
7717
8064
|
}, "formatTransferToContractScriptData");
|
7718
8065
|
var assembleTransferToContractScript = /* @__PURE__ */ __name(async (transferParams) => {
|
@@ -7721,7 +8068,7 @@ var assembleTransferToContractScript = /* @__PURE__ */ __name(async (transferPar
|
|
7721
8068
|
let script = new Uint8Array();
|
7722
8069
|
transferParams.forEach((_, i) => {
|
7723
8070
|
const offset = (CONTRACT_ID_LEN + WORD_SIZE + ASSET_ID_LEN) * i;
|
7724
|
-
script =
|
8071
|
+
script = concat5([
|
7725
8072
|
script,
|
7726
8073
|
// Load ScriptData into register 0x10.
|
7727
8074
|
asm.gtf(16, 0, asm.GTFArgs.ScriptData).to_bytes(),
|
@@ -7737,7 +8084,7 @@ var assembleTransferToContractScript = /* @__PURE__ */ __name(async (transferPar
|
|
7737
8084
|
asm.tr(17, 19, 20).to_bytes()
|
7738
8085
|
]);
|
7739
8086
|
});
|
7740
|
-
script =
|
8087
|
+
script = concat5([script, asm.ret(1).to_bytes()]);
|
7741
8088
|
return { script, scriptData };
|
7742
8089
|
}, "assembleTransferToContractScript");
|
7743
8090
|
|
@@ -7782,7 +8129,7 @@ var Account = class extends AbstractAccount {
|
|
7782
8129
|
super();
|
7783
8130
|
this._provider = provider;
|
7784
8131
|
this._connector = connector;
|
7785
|
-
this.address = new
|
8132
|
+
this.address = new Address6(address);
|
7786
8133
|
}
|
7787
8134
|
/**
|
7788
8135
|
* The provider used to interact with the network.
|
@@ -7793,7 +8140,7 @@ var Account = class extends AbstractAccount {
|
|
7793
8140
|
*/
|
7794
8141
|
get provider() {
|
7795
8142
|
if (!this._provider) {
|
7796
|
-
throw new
|
8143
|
+
throw new FuelError23(ErrorCode20.MISSING_PROVIDER, "Provider not set");
|
7797
8144
|
}
|
7798
8145
|
return this._provider;
|
7799
8146
|
}
|
@@ -7820,10 +8167,24 @@ var Account = class extends AbstractAccount {
|
|
7820
8167
|
*
|
7821
8168
|
* @param quantities - Quantities of resources to be obtained.
|
7822
8169
|
* @param resourcesIdsToIgnore - IDs of resources to be excluded from the query (optional).
|
8170
|
+
* @param skipAutoConsolidation - Whether to skip the automatic consolidatation of coins process (optional).
|
7823
8171
|
* @returns A promise that resolves to an array of Resources.
|
7824
8172
|
*/
|
7825
|
-
async getResourcesToSpend(quantities, resourcesIdsToIgnore) {
|
7826
|
-
|
8173
|
+
async getResourcesToSpend(quantities, resourcesIdsToIgnore, { skipAutoConsolidation } = {}) {
|
8174
|
+
const getResourcesToSpend = /* @__PURE__ */ __name(() => this.provider.getResourcesToSpend(this.address, quantities, resourcesIdsToIgnore), "getResourcesToSpend");
|
8175
|
+
try {
|
8176
|
+
return await getResourcesToSpend();
|
8177
|
+
} catch (error) {
|
8178
|
+
const shouldRetry = await consolidateCoinsIfRequired({
|
8179
|
+
error,
|
8180
|
+
account: this,
|
8181
|
+
skipAutoConsolidation
|
8182
|
+
});
|
8183
|
+
if (!shouldRetry) {
|
8184
|
+
throw error;
|
8185
|
+
}
|
8186
|
+
return await getResourcesToSpend();
|
8187
|
+
}
|
7827
8188
|
}
|
7828
8189
|
/**
|
7829
8190
|
* Retrieves coins owned by the account.
|
@@ -7872,7 +8233,7 @@ var Account = class extends AbstractAccount {
|
|
7872
8233
|
* @deprecated Use provider.assembleTx instead
|
7873
8234
|
* Check the migration guide https://docs.fuel.network/docs/fuels-ts/transactions/assemble-tx-migration-guide/ for more information.
|
7874
8235
|
*/
|
7875
|
-
async fund(request, params) {
|
8236
|
+
async fund(request, params, { skipAutoConsolidation } = {}) {
|
7876
8237
|
const {
|
7877
8238
|
addedSignatures,
|
7878
8239
|
estimatedPredicates,
|
@@ -7884,9 +8245,9 @@ var Account = class extends AbstractAccount {
|
|
7884
8245
|
const chainId = await this.provider.getChainId();
|
7885
8246
|
const fee = request.maxFee;
|
7886
8247
|
const baseAssetId = await this.provider.getBaseAssetId();
|
7887
|
-
const requiredInBaseAsset = requiredQuantities.find((quantity) => quantity.assetId === baseAssetId)?.amount ||
|
8248
|
+
const requiredInBaseAsset = requiredQuantities.find((quantity) => quantity.assetId === baseAssetId)?.amount || bn22(0);
|
7888
8249
|
const requiredQuantitiesWithFee = addAmountToCoinQuantities({
|
7889
|
-
amount:
|
8250
|
+
amount: bn22(fee),
|
7890
8251
|
assetId: baseAssetId,
|
7891
8252
|
coinQuantities: requiredQuantities
|
7892
8253
|
});
|
@@ -7894,7 +8255,7 @@ var Account = class extends AbstractAccount {
|
|
7894
8255
|
requiredQuantitiesWithFee.forEach(({ amount, assetId }) => {
|
7895
8256
|
quantitiesDict[assetId] = {
|
7896
8257
|
required: amount,
|
7897
|
-
owned:
|
8258
|
+
owned: bn22(0)
|
7898
8259
|
};
|
7899
8260
|
});
|
7900
8261
|
request.inputs.filter(isRequestInputResource).forEach((input) => {
|
@@ -7918,7 +8279,8 @@ var Account = class extends AbstractAccount {
|
|
7918
8279
|
while (needsToBeFunded && fundingAttempts < MAX_FUNDING_ATTEMPTS) {
|
7919
8280
|
const resources = await this.getResourcesToSpend(
|
7920
8281
|
missingQuantities,
|
7921
|
-
cacheRequestInputsResourcesFromOwner(request.inputs, this.address)
|
8282
|
+
cacheRequestInputsResourcesFromOwner(request.inputs, this.address),
|
8283
|
+
{ skipAutoConsolidation }
|
7922
8284
|
);
|
7923
8285
|
request.addResources(resources);
|
7924
8286
|
request.updatePredicateGasUsed(estimatedPredicates);
|
@@ -7955,8 +8317,8 @@ var Account = class extends AbstractAccount {
|
|
7955
8317
|
fundingAttempts += 1;
|
7956
8318
|
}
|
7957
8319
|
if (needsToBeFunded) {
|
7958
|
-
throw new
|
7959
|
-
|
8320
|
+
throw new FuelError23(
|
8321
|
+
ErrorCode20.INSUFFICIENT_FUNDS,
|
7960
8322
|
`The account ${this.address} does not have enough base asset funds to cover the transaction execution.`
|
7961
8323
|
);
|
7962
8324
|
}
|
@@ -7984,16 +8346,20 @@ var Account = class extends AbstractAccount {
|
|
7984
8346
|
* @param amount - The amount of coins to transfer.
|
7985
8347
|
* @param assetId - The asset ID of the coins to transfer (optional).
|
7986
8348
|
* @param txParams - The transaction parameters (optional).
|
8349
|
+
* @param skipAutoConsolidation - Whether to skip the automatic consolidatation of coins process (optional).
|
7987
8350
|
* @returns A promise that resolves to the prepared transaction request.
|
7988
8351
|
*/
|
7989
|
-
async createTransfer(destination, amount, assetId, txParams = {}) {
|
8352
|
+
async createTransfer(destination, amount, assetId, txParams = {}, { skipAutoConsolidation } = {}) {
|
7990
8353
|
let request = new ScriptTransactionRequest(txParams);
|
7991
8354
|
request = this.addTransfer(request, {
|
7992
8355
|
destination,
|
7993
8356
|
amount,
|
7994
8357
|
assetId: assetId || await this.provider.getBaseAssetId()
|
7995
8358
|
});
|
7996
|
-
const { gasPrice, transactionRequest } = await this.assembleTx(
|
8359
|
+
const { gasPrice, transactionRequest } = await this.assembleTx({
|
8360
|
+
transactionRequest: request,
|
8361
|
+
skipAutoConsolidation
|
8362
|
+
});
|
7997
8363
|
request = await setAndValidateGasAndFeeForAssembledTx({
|
7998
8364
|
gasPrice,
|
7999
8365
|
provider: this.provider,
|
@@ -8010,10 +8376,13 @@ var Account = class extends AbstractAccount {
|
|
8010
8376
|
* @param amount - The amount of coins to transfer.
|
8011
8377
|
* @param assetId - The asset ID of the coins to transfer (optional).
|
8012
8378
|
* @param txParams - The transaction parameters (optional).
|
8379
|
+
* @param skipAutoConsolidation - Whether to skip the automatic consolidatation of coins process (optional).
|
8013
8380
|
* @returns A promise that resolves to the transaction response.
|
8014
8381
|
*/
|
8015
|
-
async transfer(destination, amount, assetId, txParams = {}) {
|
8016
|
-
const request = await this.createTransfer(destination, amount, assetId, txParams
|
8382
|
+
async transfer(destination, amount, assetId, txParams = {}, { skipAutoConsolidation } = {}) {
|
8383
|
+
const request = await this.createTransfer(destination, amount, assetId, txParams, {
|
8384
|
+
skipAutoConsolidation
|
8385
|
+
});
|
8017
8386
|
return this.sendTransaction(request, { estimateTxDependencies: false });
|
8018
8387
|
}
|
8019
8388
|
/**
|
@@ -8021,12 +8390,16 @@ var Account = class extends AbstractAccount {
|
|
8021
8390
|
*
|
8022
8391
|
* @param transferParams - An array of `TransferParams` objects representing the transfers to be made.
|
8023
8392
|
* @param txParams - Optional transaction parameters.
|
8393
|
+
* @param skipAutoConsolidation - Whether to skip the automatic consolidatation of coins process (optional).
|
8024
8394
|
* @returns A promise that resolves to a `TransactionResponse` object representing the transaction result.
|
8025
8395
|
*/
|
8026
|
-
async batchTransfer(transferParams, txParams = {}) {
|
8396
|
+
async batchTransfer(transferParams, txParams = {}, { skipAutoConsolidation } = {}) {
|
8027
8397
|
let request = new ScriptTransactionRequest(txParams);
|
8028
8398
|
request = this.addBatchTransfer(request, transferParams);
|
8029
|
-
const { gasPrice, transactionRequest } = await this.assembleTx(
|
8399
|
+
const { gasPrice, transactionRequest } = await this.assembleTx({
|
8400
|
+
transactionRequest: request,
|
8401
|
+
skipAutoConsolidation
|
8402
|
+
});
|
8030
8403
|
request = await setAndValidateGasAndFeeForAssembledTx({
|
8031
8404
|
gasPrice,
|
8032
8405
|
provider: this.provider,
|
@@ -8046,7 +8419,7 @@ var Account = class extends AbstractAccount {
|
|
8046
8419
|
addTransfer(request, transferParams) {
|
8047
8420
|
const { destination, amount, assetId } = transferParams;
|
8048
8421
|
this.validateTransferAmount(amount);
|
8049
|
-
request.addCoinOutput(new
|
8422
|
+
request.addCoinOutput(new Address6(destination), amount, assetId);
|
8050
8423
|
return request;
|
8051
8424
|
}
|
8052
8425
|
/**
|
@@ -8073,24 +8446,27 @@ var Account = class extends AbstractAccount {
|
|
8073
8446
|
* @param amount - The amount of coins to transfer.
|
8074
8447
|
* @param assetId - The asset ID of the coins to transfer (optional).
|
8075
8448
|
* @param txParams - The transaction parameters (optional).
|
8449
|
+
* @param skipAutoConsolidation - Whether to skip the automatic consolidatation of coins process (optional).
|
8076
8450
|
* @returns A promise that resolves to the transaction response.
|
8077
8451
|
*/
|
8078
|
-
async transferToContract(contractId, amount, assetId, txParams = {}) {
|
8079
|
-
return this.batchTransferToContracts([{ amount, assetId, contractId }], txParams
|
8452
|
+
async transferToContract(contractId, amount, assetId, txParams = {}, { skipAutoConsolidation } = {}) {
|
8453
|
+
return this.batchTransferToContracts([{ amount, assetId, contractId }], txParams, {
|
8454
|
+
skipAutoConsolidation
|
8455
|
+
});
|
8080
8456
|
}
|
8081
|
-
async batchTransferToContracts(contractTransferParams, txParams = {}) {
|
8457
|
+
async batchTransferToContracts(contractTransferParams, txParams = {}, { skipAutoConsolidation } = {}) {
|
8082
8458
|
let request = new ScriptTransactionRequest({
|
8083
8459
|
...txParams
|
8084
8460
|
});
|
8085
8461
|
const quantities = [];
|
8086
8462
|
const defaultAssetId = await this.provider.getBaseAssetId();
|
8087
8463
|
const transferParams = contractTransferParams.map((transferParam) => {
|
8088
|
-
const amount =
|
8089
|
-
const contractAddress = new
|
8464
|
+
const amount = bn22(transferParam.amount);
|
8465
|
+
const contractAddress = new Address6(transferParam.contractId);
|
8090
8466
|
const assetId = transferParam.assetId ? hexlify21(transferParam.assetId) : defaultAssetId;
|
8091
8467
|
if (amount.lte(0)) {
|
8092
|
-
throw new
|
8093
|
-
|
8468
|
+
throw new FuelError23(
|
8469
|
+
ErrorCode20.INVALID_TRANSFER_AMOUNT,
|
8094
8470
|
"Transfer amount must be a positive number."
|
8095
8471
|
);
|
8096
8472
|
}
|
@@ -8105,7 +8481,11 @@ var Account = class extends AbstractAccount {
|
|
8105
8481
|
const { script, scriptData } = await assembleTransferToContractScript(transferParams);
|
8106
8482
|
request.script = script;
|
8107
8483
|
request.scriptData = scriptData;
|
8108
|
-
const { gasPrice, transactionRequest } = await this.assembleTx(
|
8484
|
+
const { gasPrice, transactionRequest } = await this.assembleTx({
|
8485
|
+
transactionRequest: request,
|
8486
|
+
quantities,
|
8487
|
+
skipAutoConsolidation
|
8488
|
+
});
|
8109
8489
|
request = await setAndValidateGasAndFeeForAssembledTx({
|
8110
8490
|
gasPrice,
|
8111
8491
|
provider: this.provider,
|
@@ -8121,26 +8501,31 @@ var Account = class extends AbstractAccount {
|
|
8121
8501
|
* @param recipient - Address of the recipient on the base chain.
|
8122
8502
|
* @param amount - Amount of base asset.
|
8123
8503
|
* @param txParams - The transaction parameters (optional).
|
8504
|
+
* @param skipAutoConsolidation - Whether to skip the automatic consolidatation of coins process (optional).
|
8124
8505
|
* @returns A promise that resolves to the transaction response.
|
8125
8506
|
*/
|
8126
|
-
async withdrawToBaseLayer(recipient, amount, txParams = {}) {
|
8127
|
-
const recipientAddress = new
|
8128
|
-
const recipientDataArray =
|
8507
|
+
async withdrawToBaseLayer(recipient, amount, txParams = {}, { skipAutoConsolidation } = {}) {
|
8508
|
+
const recipientAddress = new Address6(recipient);
|
8509
|
+
const recipientDataArray = arrayify18(
|
8129
8510
|
"0x".concat(recipientAddress.toHexString().substring(2).padStart(64, "0"))
|
8130
8511
|
);
|
8131
|
-
const amountDataArray =
|
8132
|
-
"0x".concat(
|
8512
|
+
const amountDataArray = arrayify18(
|
8513
|
+
"0x".concat(bn22(amount).toHex().substring(2).padStart(16, "0"))
|
8133
8514
|
);
|
8134
8515
|
const script = new Uint8Array([
|
8135
|
-
...
|
8516
|
+
...arrayify18(withdrawScript.bytes),
|
8136
8517
|
...recipientDataArray,
|
8137
8518
|
...amountDataArray
|
8138
8519
|
]);
|
8139
8520
|
const params = { script, ...txParams };
|
8140
8521
|
const baseAssetId = await this.provider.getBaseAssetId();
|
8141
8522
|
let request = new ScriptTransactionRequest(params);
|
8142
|
-
const quantities = [{ amount:
|
8143
|
-
const { gasPrice, transactionRequest } = await this.assembleTx(
|
8523
|
+
const quantities = [{ amount: bn22(amount), assetId: baseAssetId }];
|
8524
|
+
const { gasPrice, transactionRequest } = await this.assembleTx({
|
8525
|
+
transactionRequest: request,
|
8526
|
+
quantities,
|
8527
|
+
skipAutoConsolidation
|
8528
|
+
});
|
8144
8529
|
request = await setAndValidateGasAndFeeForAssembledTx({
|
8145
8530
|
gasPrice,
|
8146
8531
|
provider: this.provider,
|
@@ -8150,6 +8535,25 @@ var Account = class extends AbstractAccount {
|
|
8150
8535
|
});
|
8151
8536
|
return this.sendTransaction(request);
|
8152
8537
|
}
|
8538
|
+
/**
|
8539
|
+
* Start the consolidation process
|
8540
|
+
*
|
8541
|
+
* @param owner - The B256 address of the owner.
|
8542
|
+
* @param assetId - The asset ID that requires consolidation.
|
8543
|
+
*/
|
8544
|
+
async startConsolidation(opts) {
|
8545
|
+
if (this._connector) {
|
8546
|
+
await this._connector.startConsolidation(opts);
|
8547
|
+
return false;
|
8548
|
+
}
|
8549
|
+
const { owner, assetId } = opts;
|
8550
|
+
if (owner !== this.address.toB256()) {
|
8551
|
+
return false;
|
8552
|
+
}
|
8553
|
+
const { submitAll } = await consolidateCoins({ account: this, assetId });
|
8554
|
+
await submitAll();
|
8555
|
+
return true;
|
8556
|
+
}
|
8153
8557
|
/**
|
8154
8558
|
* Consolidates base asset UTXOs into fewer, larger ones.
|
8155
8559
|
*
|
@@ -8169,6 +8573,7 @@ var Account = class extends AbstractAccount {
|
|
8169
8573
|
const isBaseAsset = baseAssetId === assetId;
|
8170
8574
|
let submitAll;
|
8171
8575
|
const consolidationParams = {
|
8576
|
+
assetId,
|
8172
8577
|
coins,
|
8173
8578
|
mode: params.mode,
|
8174
8579
|
outputNum: params.outputNum
|
@@ -8176,10 +8581,7 @@ var Account = class extends AbstractAccount {
|
|
8176
8581
|
if (isBaseAsset) {
|
8177
8582
|
({ submitAll } = await this.assembleBaseAssetConsolidationTxs(consolidationParams));
|
8178
8583
|
} else {
|
8179
|
-
|
8180
|
-
ErrorCode19.UNSUPPORTED_FEATURE,
|
8181
|
-
"Consolidation for non-base assets is not supported yet."
|
8182
|
-
);
|
8584
|
+
({ submitAll } = await this.assembleNonBaseAssetConsolidationTxs(consolidationParams));
|
8183
8585
|
}
|
8184
8586
|
return submitAll();
|
8185
8587
|
}
|
@@ -8200,7 +8602,7 @@ var Account = class extends AbstractAccount {
|
|
8200
8602
|
this.validateConsolidationTxsCoins(coins, baseAssetId);
|
8201
8603
|
const chainInfo = await this.provider.getChain();
|
8202
8604
|
const maxInputsNumber = chainInfo.consensusParameters.txParameters.maxInputs.toNumber();
|
8203
|
-
let totalFeeCost =
|
8605
|
+
let totalFeeCost = bn22(0);
|
8204
8606
|
const txs = [];
|
8205
8607
|
const coinsBatches = splitCoinsIntoBatches(coins, maxInputsNumber);
|
8206
8608
|
const gasPrice = await this.provider.estimateGasPrice(10);
|
@@ -8224,15 +8626,79 @@ var Account = class extends AbstractAccount {
|
|
8224
8626
|
});
|
8225
8627
|
request.maxFee = fee;
|
8226
8628
|
if (consolidateMoreThanOneCoin) {
|
8227
|
-
const total = request.inputs.filter(isRequestInputCoin).reduce((acc, input) => acc.add(input.amount),
|
8629
|
+
const total = request.inputs.filter(isRequestInputCoin).reduce((acc, input) => acc.add(input.amount), bn22(0));
|
8630
|
+
const amountPerNewUtxo = total.div(outputNum + 1);
|
8631
|
+
request.outputs.forEach((output) => {
|
8632
|
+
if (output.type === OutputType10.Coin) {
|
8633
|
+
output.amount = amountPerNewUtxo;
|
8634
|
+
}
|
8635
|
+
});
|
8636
|
+
}
|
8637
|
+
totalFeeCost = totalFeeCost.add(fee);
|
8638
|
+
txs.push(request);
|
8639
|
+
});
|
8640
|
+
const submitAll = this.prepareSubmitAll({ txs, mode });
|
8641
|
+
return { txs, totalFeeCost, submitAll };
|
8642
|
+
}
|
8643
|
+
async assembleNonBaseAssetConsolidationTxs(params) {
|
8644
|
+
const { assetId, coins, mode = "parallel", outputNum = 1 } = params;
|
8645
|
+
this.validateConsolidationTxsCoins(coins, assetId);
|
8646
|
+
const chainInfo = await this.provider.getChain();
|
8647
|
+
const maxInputsNumber = chainInfo.consensusParameters.txParameters.maxInputs.toNumber();
|
8648
|
+
const baseAssetId = chainInfo.consensusParameters.baseAssetId;
|
8649
|
+
const { coins: baseAssetCoins } = await this.provider.getCoins(this.address, baseAssetId);
|
8650
|
+
let totalFeeCost = bn22(0);
|
8651
|
+
const txs = [];
|
8652
|
+
const gasPrice = await this.provider.estimateGasPrice(10);
|
8653
|
+
const consolidateMoreThanOneCoin = outputNum > 1;
|
8654
|
+
const assetCoinBatches = splitCoinsIntoBatches(coins, maxInputsNumber);
|
8655
|
+
assetCoinBatches.filter((batch) => batch.length > 1).forEach((coinBatch) => {
|
8656
|
+
const request = new ScriptTransactionRequest({
|
8657
|
+
script: "0x"
|
8658
|
+
});
|
8659
|
+
request.addResources(coinBatch);
|
8660
|
+
if (consolidateMoreThanOneCoin) {
|
8661
|
+
Array.from({ length: outputNum - 1 }).forEach(() => {
|
8662
|
+
request.addCoinOutput(this.address, 0, assetId);
|
8663
|
+
});
|
8664
|
+
}
|
8665
|
+
const minGas = request.calculateMinGas(chainInfo);
|
8666
|
+
const fee = calculateGasFee({
|
8667
|
+
gasPrice,
|
8668
|
+
gas: minGas,
|
8669
|
+
priceFactor: chainInfo.consensusParameters.feeParameters.gasPriceFactor,
|
8670
|
+
tip: request.tip
|
8671
|
+
});
|
8672
|
+
request.maxFee = fee;
|
8673
|
+
if (consolidateMoreThanOneCoin) {
|
8674
|
+
const total = request.inputs.filter(isRequestInputCoin).reduce((acc, input) => acc.add(input.amount), bn22(0));
|
8228
8675
|
const amountPerNewUtxo = total.div(outputNum + 1);
|
8229
8676
|
request.outputs.forEach((output) => {
|
8230
|
-
if (output.type ===
|
8677
|
+
if (output.type === OutputType10.Coin) {
|
8231
8678
|
output.amount = amountPerNewUtxo;
|
8232
8679
|
}
|
8233
8680
|
});
|
8234
8681
|
}
|
8235
8682
|
totalFeeCost = totalFeeCost.add(fee);
|
8683
|
+
const baseAssetResources = [];
|
8684
|
+
let fundingFeeTotal = bn22(0);
|
8685
|
+
while (fundingFeeTotal.lt(fee)) {
|
8686
|
+
const baseAssetCoin = baseAssetCoins.pop();
|
8687
|
+
if (!baseAssetCoin) {
|
8688
|
+
break;
|
8689
|
+
}
|
8690
|
+
baseAssetResources.push(baseAssetCoin);
|
8691
|
+
fundingFeeTotal = fundingFeeTotal.add(baseAssetCoin.amount);
|
8692
|
+
}
|
8693
|
+
const { inputs } = request;
|
8694
|
+
request.inputs = inputs.slice(0, maxInputsNumber - baseAssetResources.length);
|
8695
|
+
const removedCoins = coinBatch.slice(maxInputsNumber - baseAssetResources.length);
|
8696
|
+
request.addResources(baseAssetResources);
|
8697
|
+
const lastCoinBatch = assetCoinBatches[assetCoinBatches.length - 1];
|
8698
|
+
lastCoinBatch.push(...removedCoins);
|
8699
|
+
if (lastCoinBatch.length > maxInputsNumber) {
|
8700
|
+
assetCoinBatches.push(lastCoinBatch.slice(maxInputsNumber));
|
8701
|
+
}
|
8236
8702
|
txs.push(request);
|
8237
8703
|
});
|
8238
8704
|
const submitAll = this.prepareSubmitAll({ txs, mode });
|
@@ -8296,7 +8762,7 @@ var Account = class extends AbstractAccount {
|
|
8296
8762
|
const baseAssetId = await this.provider.getBaseAssetId();
|
8297
8763
|
const coinOutputsQuantities = txRequestClone.getCoinOutputsQuantities();
|
8298
8764
|
const requiredQuantities = mergeQuantities(coinOutputsQuantities, quantities);
|
8299
|
-
const transactionFeeForDryRun = [{ assetId: baseAssetId, amount:
|
8765
|
+
const transactionFeeForDryRun = [{ assetId: baseAssetId, amount: bn22("100000000000000000") }];
|
8300
8766
|
const findAssetInput = /* @__PURE__ */ __name((assetId) => txRequestClone.inputs.find((input) => {
|
8301
8767
|
if (input.type === InputType8.Coin) {
|
8302
8768
|
return input.assetId === assetId;
|
@@ -8344,7 +8810,7 @@ var Account = class extends AbstractAccount {
|
|
8344
8810
|
*/
|
8345
8811
|
async signMessage(message) {
|
8346
8812
|
if (!this._connector) {
|
8347
|
-
throw new
|
8813
|
+
throw new FuelError23(ErrorCode20.MISSING_CONNECTOR, "A connector is required to sign messages.");
|
8348
8814
|
}
|
8349
8815
|
return this._connector.signMessage(this.address.toString(), message);
|
8350
8816
|
}
|
@@ -8356,8 +8822,8 @@ var Account = class extends AbstractAccount {
|
|
8356
8822
|
*/
|
8357
8823
|
async signTransaction(transactionRequestLike, connectorOptions = {}) {
|
8358
8824
|
if (!this._connector) {
|
8359
|
-
throw new
|
8360
|
-
|
8825
|
+
throw new FuelError23(
|
8826
|
+
ErrorCode20.MISSING_CONNECTOR,
|
8361
8827
|
"A connector is required to sign transactions."
|
8362
8828
|
);
|
8363
8829
|
}
|
@@ -8424,8 +8890,8 @@ var Account = class extends AbstractAccount {
|
|
8424
8890
|
return coins.map((coin) => ({
|
8425
8891
|
id: hexlify21(randomBytes5(UTXO_ID_LEN3)),
|
8426
8892
|
owner: this.address,
|
8427
|
-
blockCreated:
|
8428
|
-
txCreatedIdx:
|
8893
|
+
blockCreated: bn22(1),
|
8894
|
+
txCreatedIdx: bn22(1),
|
8429
8895
|
...coin
|
8430
8896
|
}));
|
8431
8897
|
}
|
@@ -8452,73 +8918,50 @@ var Account = class extends AbstractAccount {
|
|
8452
8918
|
} : void 0;
|
8453
8919
|
}
|
8454
8920
|
/** @hidden * */
|
8455
|
-
async assembleTx(
|
8456
|
-
const
|
8457
|
-
transactionRequest.
|
8458
|
-
transactionRequest.
|
8459
|
-
|
8460
|
-
|
8461
|
-
|
8462
|
-
|
8463
|
-
|
8464
|
-
|
8921
|
+
async assembleTx(opts) {
|
8922
|
+
const { transactionRequest, quantities = [], skipAutoConsolidation } = opts;
|
8923
|
+
const outputQuantities = transactionRequest.outputs.filter((o) => o.type === OutputType10.Coin).map(({ amount, assetId }) => ({ assetId: String(assetId), amount: bn22(amount) }));
|
8924
|
+
transactionRequest.gasLimit = bn22(0);
|
8925
|
+
transactionRequest.maxFee = bn22(0);
|
8926
|
+
const assembleTx = /* @__PURE__ */ __name(async () => {
|
8927
|
+
const { assembledRequest, gasPrice } = await this.provider.assembleTx({
|
8928
|
+
request: transactionRequest,
|
8929
|
+
accountCoinQuantities: mergeQuantities(outputQuantities, quantities),
|
8930
|
+
feePayerAccount: this
|
8931
|
+
});
|
8932
|
+
return { transactionRequest: assembledRequest, gasPrice };
|
8933
|
+
}, "assembleTx");
|
8934
|
+
try {
|
8935
|
+
return await assembleTx();
|
8936
|
+
} catch (error) {
|
8937
|
+
const shouldRetry = await consolidateCoinsIfRequired({
|
8938
|
+
error,
|
8939
|
+
account: this,
|
8940
|
+
skipAutoConsolidation
|
8941
|
+
});
|
8942
|
+
if (!shouldRetry) {
|
8943
|
+
throw error;
|
8944
|
+
}
|
8945
|
+
return await assembleTx();
|
8946
|
+
}
|
8465
8947
|
}
|
8466
8948
|
/** @hidden * */
|
8467
8949
|
validateTransferAmount(amount) {
|
8468
|
-
if (
|
8469
|
-
throw new
|
8470
|
-
|
8950
|
+
if (bn22(amount).lte(0)) {
|
8951
|
+
throw new FuelError23(
|
8952
|
+
ErrorCode20.INVALID_TRANSFER_AMOUNT,
|
8471
8953
|
"Transfer amount must be a positive number."
|
8472
8954
|
);
|
8473
8955
|
}
|
8474
8956
|
}
|
8475
8957
|
/** @hidden * */
|
8476
|
-
async estimateAndFundTransaction(transactionRequest, txParams, costParams) {
|
8477
|
-
let request = transactionRequest;
|
8478
|
-
const txCost = await this.getTransactionCost(request, costParams);
|
8479
|
-
request = this.validateGasLimitAndMaxFee({
|
8480
|
-
transactionRequest: request,
|
8481
|
-
gasUsed: txCost.gasUsed,
|
8482
|
-
maxFee: txCost.maxFee,
|
8483
|
-
txParams
|
8484
|
-
});
|
8485
|
-
request = await this.fund(request, txCost);
|
8486
|
-
return request;
|
8487
|
-
}
|
8488
|
-
/** @hidden * */
|
8489
|
-
validateGasLimitAndMaxFee({
|
8490
|
-
gasUsed,
|
8491
|
-
maxFee,
|
8492
|
-
transactionRequest,
|
8493
|
-
txParams: { gasLimit: setGasLimit, maxFee: setMaxFee }
|
8494
|
-
}) {
|
8495
|
-
const request = transactionRequestify(transactionRequest);
|
8496
|
-
if (!isDefined4(setGasLimit)) {
|
8497
|
-
request.gasLimit = gasUsed;
|
8498
|
-
} else if (gasUsed.gt(setGasLimit)) {
|
8499
|
-
throw new FuelError22(
|
8500
|
-
ErrorCode19.GAS_LIMIT_TOO_LOW,
|
8501
|
-
`Gas limit '${setGasLimit}' is lower than the required: '${gasUsed}'.`
|
8502
|
-
);
|
8503
|
-
}
|
8504
|
-
if (!isDefined4(setMaxFee)) {
|
8505
|
-
request.maxFee = maxFee;
|
8506
|
-
} else if (maxFee.gt(setMaxFee)) {
|
8507
|
-
throw new FuelError22(
|
8508
|
-
ErrorCode19.MAX_FEE_TOO_LOW,
|
8509
|
-
`Max fee '${setMaxFee}' is lower than the required: '${maxFee}'.`
|
8510
|
-
);
|
8511
|
-
}
|
8512
|
-
return request;
|
8513
|
-
}
|
8514
|
-
/** @hidden * */
|
8515
8958
|
validateConsolidationTxsCoins(coins, assetId) {
|
8516
8959
|
if (coins.length <= 1) {
|
8517
|
-
throw new
|
8960
|
+
throw new FuelError23(ErrorCode20.NO_COINS_TO_CONSOLIDATE, "No coins to consolidate.");
|
8518
8961
|
}
|
8519
8962
|
if (!coins.every((c) => c.assetId === assetId)) {
|
8520
|
-
throw new
|
8521
|
-
|
8963
|
+
throw new FuelError23(
|
8964
|
+
ErrorCode20.COINS_ASSET_ID_MISMATCH,
|
8522
8965
|
"All coins to consolidate must be from the same asset id."
|
8523
8966
|
);
|
8524
8967
|
}
|
@@ -8543,7 +8986,7 @@ var Account = class extends AbstractAccount {
|
|
8543
8986
|
};
|
8544
8987
|
|
8545
8988
|
// src/wallet/keystore-wallet.ts
|
8546
|
-
import { Address as
|
8989
|
+
import { Address as Address7 } from "@fuel-ts/address";
|
8547
8990
|
import {
|
8548
8991
|
bufferFromString,
|
8549
8992
|
keccak256,
|
@@ -8554,7 +8997,7 @@ import {
|
|
8554
8997
|
encryptJsonWalletData,
|
8555
8998
|
randomUUID as randomUUID2
|
8556
8999
|
} from "@fuel-ts/crypto";
|
8557
|
-
import { ErrorCode as
|
9000
|
+
import { ErrorCode as ErrorCode21, FuelError as FuelError24 } from "@fuel-ts/errors";
|
8558
9001
|
import { hexlify as hexlify22 } from "@fuel-ts/utils";
|
8559
9002
|
var DEFAULT_KDF_PARAMS_LOG_N = 13;
|
8560
9003
|
var DEFAULT_KDF_PARAMS_R = 8;
|
@@ -8569,7 +9012,7 @@ var removeHexPrefix = /* @__PURE__ */ __name((hexString) => {
|
|
8569
9012
|
}, "removeHexPrefix");
|
8570
9013
|
async function encryptKeystoreWallet(privateKey, address, password) {
|
8571
9014
|
const privateKeyBuffer = bufferFromString(removeHexPrefix(privateKey), "hex");
|
8572
|
-
const ownerAddress = new
|
9015
|
+
const ownerAddress = new Address7(address);
|
8573
9016
|
const salt = randomBytes6(DEFAULT_KEY_SIZE);
|
8574
9017
|
const key = scrypt({
|
8575
9018
|
password: bufferFromString(password),
|
@@ -8632,8 +9075,8 @@ async function decryptKeystoreWallet(jsonWallet, password) {
|
|
8632
9075
|
const macHashUint8Array = keccak256(data);
|
8633
9076
|
const macHash = stringFromBuffer(macHashUint8Array, "hex");
|
8634
9077
|
if (mac !== macHash) {
|
8635
|
-
throw new
|
8636
|
-
|
9078
|
+
throw new FuelError24(
|
9079
|
+
ErrorCode21.INVALID_PASSWORD,
|
8637
9080
|
"Failed to decrypt the keystore wallet, the provided password is incorrect."
|
8638
9081
|
);
|
8639
9082
|
}
|
@@ -8772,16 +9215,16 @@ var BaseWalletUnlocked = class extends Account {
|
|
8772
9215
|
|
8773
9216
|
// src/hdwallet/hdwallet.ts
|
8774
9217
|
import { computeHmac as computeHmac2, ripemd160 } from "@fuel-ts/crypto";
|
8775
|
-
import { ErrorCode as
|
9218
|
+
import { ErrorCode as ErrorCode24, FuelError as FuelError27 } from "@fuel-ts/errors";
|
8776
9219
|
import { sha256 as sha2564 } from "@fuel-ts/hasher";
|
8777
|
-
import { bn as
|
8778
|
-
import { arrayify as
|
9220
|
+
import { bn as bn23, toBytes as toBytes3, toHex } from "@fuel-ts/math";
|
9221
|
+
import { arrayify as arrayify21, hexlify as hexlify25, concat as concat7, dataSlice as dataSlice2, encodeBase58 as encodeBase582, decodeBase58 } from "@fuel-ts/utils";
|
8779
9222
|
|
8780
9223
|
// src/mnemonic/mnemonic.ts
|
8781
9224
|
import { randomBytes as randomBytes7, pbkdf2, computeHmac } from "@fuel-ts/crypto";
|
8782
|
-
import { ErrorCode as
|
9225
|
+
import { ErrorCode as ErrorCode23, FuelError as FuelError26 } from "@fuel-ts/errors";
|
8783
9226
|
import { sha256 as sha2563 } from "@fuel-ts/hasher";
|
8784
|
-
import { arrayify as
|
9227
|
+
import { arrayify as arrayify20, hexlify as hexlify24, concat as concat6, dataSlice, encodeBase58, toUtf8Bytes } from "@fuel-ts/utils";
|
8785
9228
|
|
8786
9229
|
// src/wordlists/words/english.ts
|
8787
9230
|
var english = [
|
@@ -10836,9 +11279,9 @@ var english = [
|
|
10836
11279
|
];
|
10837
11280
|
|
10838
11281
|
// src/mnemonic/utils.ts
|
10839
|
-
import { ErrorCode as
|
11282
|
+
import { ErrorCode as ErrorCode22, FuelError as FuelError25 } from "@fuel-ts/errors";
|
10840
11283
|
import { sha256 as sha2562 } from "@fuel-ts/hasher";
|
10841
|
-
import { arrayify as
|
11284
|
+
import { arrayify as arrayify19 } from "@fuel-ts/utils";
|
10842
11285
|
function getLowerMask(bits) {
|
10843
11286
|
return (1 << bits) - 1;
|
10844
11287
|
}
|
@@ -10877,7 +11320,7 @@ function entropyToMnemonicIndices(entropy) {
|
|
10877
11320
|
}
|
10878
11321
|
}
|
10879
11322
|
const checksumBits = entropy.length / 4;
|
10880
|
-
const checksum =
|
11323
|
+
const checksum = arrayify19(sha2562(entropy))[0] & getUpperMask(checksumBits);
|
10881
11324
|
indices[indices.length - 1] <<= checksumBits;
|
10882
11325
|
indices[indices.length - 1] |= checksum >> 8 - checksumBits;
|
10883
11326
|
return indices;
|
@@ -10885,13 +11328,13 @@ function entropyToMnemonicIndices(entropy) {
|
|
10885
11328
|
__name(entropyToMnemonicIndices, "entropyToMnemonicIndices");
|
10886
11329
|
function mnemonicWordsToEntropy(words, wordlist) {
|
10887
11330
|
const size = Math.ceil(11 * words.length / 8);
|
10888
|
-
const entropy =
|
11331
|
+
const entropy = arrayify19(new Uint8Array(size));
|
10889
11332
|
let offset = 0;
|
10890
11333
|
for (let i = 0; i < words.length; i += 1) {
|
10891
11334
|
const index = wordlist.indexOf(words[i].normalize("NFKD"));
|
10892
11335
|
if (index === -1) {
|
10893
|
-
throw new
|
10894
|
-
|
11336
|
+
throw new FuelError25(
|
11337
|
+
ErrorCode22.INVALID_MNEMONIC,
|
10895
11338
|
`Invalid mnemonic: the word '${words[i]}' is not found in the provided wordlist.`
|
10896
11339
|
);
|
10897
11340
|
}
|
@@ -10905,10 +11348,10 @@ function mnemonicWordsToEntropy(words, wordlist) {
|
|
10905
11348
|
const entropyBits = 32 * words.length / 3;
|
10906
11349
|
const checksumBits = words.length / 3;
|
10907
11350
|
const checksumMask = getUpperMask(checksumBits);
|
10908
|
-
const checksum =
|
11351
|
+
const checksum = arrayify19(sha2562(entropy.slice(0, entropyBits / 8)))[0] & checksumMask;
|
10909
11352
|
if (checksum !== (entropy[entropy.length - 1] & checksumMask)) {
|
10910
|
-
throw new
|
10911
|
-
|
11353
|
+
throw new FuelError25(
|
11354
|
+
ErrorCode22.INVALID_CHECKSUM,
|
10912
11355
|
"Checksum validation failed for the provided mnemonic."
|
10913
11356
|
);
|
10914
11357
|
}
|
@@ -10923,8 +11366,8 @@ var TestnetPRV = "0x04358394";
|
|
10923
11366
|
var MNEMONIC_SIZES = [12, 15, 18, 21, 24];
|
10924
11367
|
function assertWordList(wordlist) {
|
10925
11368
|
if (wordlist.length !== 2048) {
|
10926
|
-
throw new
|
10927
|
-
|
11369
|
+
throw new FuelError26(
|
11370
|
+
ErrorCode23.INVALID_WORD_LIST,
|
10928
11371
|
`Expected word list length of 2048, but got ${wordlist.length}.`
|
10929
11372
|
);
|
10930
11373
|
}
|
@@ -10932,8 +11375,8 @@ function assertWordList(wordlist) {
|
|
10932
11375
|
__name(assertWordList, "assertWordList");
|
10933
11376
|
function assertEntropy(entropy) {
|
10934
11377
|
if (entropy.length % 4 !== 0 || entropy.length < 16 || entropy.length > 32) {
|
10935
|
-
throw new
|
10936
|
-
|
11378
|
+
throw new FuelError26(
|
11379
|
+
ErrorCode23.INVALID_ENTROPY,
|
10937
11380
|
`Entropy should be between 16 and 32 bytes and a multiple of 4, but got ${entropy.length} bytes.`
|
10938
11381
|
);
|
10939
11382
|
}
|
@@ -10944,7 +11387,7 @@ function assertMnemonic(words) {
|
|
10944
11387
|
const errorMsg = `Invalid mnemonic size. Expected one of [${MNEMONIC_SIZES.join(
|
10945
11388
|
", "
|
10946
11389
|
)}] words, but got ${words.length}.`;
|
10947
|
-
throw new
|
11390
|
+
throw new FuelError26(ErrorCode23.INVALID_MNEMONIC, errorMsg);
|
10948
11391
|
}
|
10949
11392
|
}
|
10950
11393
|
__name(assertMnemonic, "assertMnemonic");
|
@@ -10995,7 +11438,7 @@ var Mnemonic = class _Mnemonic {
|
|
10995
11438
|
* @returns 64-byte array contains privateKey and chainCode as described on BIP39
|
10996
11439
|
*/
|
10997
11440
|
static entropyToMnemonic(entropy, wordlist = english) {
|
10998
|
-
const entropyBytes =
|
11441
|
+
const entropyBytes = arrayify20(entropy);
|
10999
11442
|
assertWordList(wordlist);
|
11000
11443
|
assertEntropy(entropyBytes);
|
11001
11444
|
return entropyToMnemonicIndices(entropyBytes).map((i) => wordlist[i]).join(" ");
|
@@ -11064,14 +11507,14 @@ var Mnemonic = class _Mnemonic {
|
|
11064
11507
|
* @returns 64-byte array contains privateKey and chainCode as described on BIP39
|
11065
11508
|
*/
|
11066
11509
|
static masterKeysFromSeed(seed) {
|
11067
|
-
const seedArray =
|
11510
|
+
const seedArray = arrayify20(seed);
|
11068
11511
|
if (seedArray.length < 16 || seedArray.length > 64) {
|
11069
|
-
throw new
|
11070
|
-
|
11512
|
+
throw new FuelError26(
|
11513
|
+
ErrorCode23.INVALID_SEED,
|
11071
11514
|
`Seed length should be between 16 and 64 bytes, but received ${seedArray.length} bytes.`
|
11072
11515
|
);
|
11073
11516
|
}
|
11074
|
-
return
|
11517
|
+
return arrayify20(computeHmac("sha512", MasterSecret, seedArray));
|
11075
11518
|
}
|
11076
11519
|
/**
|
11077
11520
|
* Get the extendKey as defined on BIP-32 from the provided seed
|
@@ -11082,22 +11525,22 @@ var Mnemonic = class _Mnemonic {
|
|
11082
11525
|
*/
|
11083
11526
|
static seedToExtendedKey(seed, testnet = false) {
|
11084
11527
|
const masterKey = _Mnemonic.masterKeysFromSeed(seed);
|
11085
|
-
const prefix =
|
11528
|
+
const prefix = arrayify20(testnet ? TestnetPRV : MainnetPRV);
|
11086
11529
|
const depth = "0x00";
|
11087
11530
|
const fingerprint = "0x00000000";
|
11088
11531
|
const index = "0x00000000";
|
11089
11532
|
const chainCode = masterKey.slice(32);
|
11090
11533
|
const privateKey = masterKey.slice(0, 32);
|
11091
|
-
const extendedKey =
|
11534
|
+
const extendedKey = concat6([
|
11092
11535
|
prefix,
|
11093
11536
|
depth,
|
11094
11537
|
fingerprint,
|
11095
11538
|
index,
|
11096
11539
|
chainCode,
|
11097
|
-
|
11540
|
+
concat6(["0x00", privateKey])
|
11098
11541
|
]);
|
11099
11542
|
const checksum = dataSlice(sha2563(sha2563(extendedKey)), 0, 4);
|
11100
|
-
return encodeBase58(
|
11543
|
+
return encodeBase58(concat6([extendedKey, checksum]));
|
11101
11544
|
}
|
11102
11545
|
/**
|
11103
11546
|
* Create a new mnemonic using a randomly generated number as entropy.
|
@@ -11112,7 +11555,7 @@ var Mnemonic = class _Mnemonic {
|
|
11112
11555
|
* @returns A randomly generated mnemonic
|
11113
11556
|
*/
|
11114
11557
|
static generate(size = 32, extraEntropy = "") {
|
11115
|
-
const entropy = extraEntropy ? sha2563(
|
11558
|
+
const entropy = extraEntropy ? sha2563(concat6([randomBytes7(size), arrayify20(extraEntropy)])) : randomBytes7(size);
|
11116
11559
|
return _Mnemonic.entropyToMnemonic(entropy);
|
11117
11560
|
}
|
11118
11561
|
};
|
@@ -11125,7 +11568,7 @@ var MainnetPUB = hexlify25("0x0488b21e");
|
|
11125
11568
|
var TestnetPRV2 = hexlify25("0x04358394");
|
11126
11569
|
var TestnetPUB = hexlify25("0x043587cf");
|
11127
11570
|
function base58check(data) {
|
11128
|
-
return encodeBase582(
|
11571
|
+
return encodeBase582(concat7([data, dataSlice2(sha2564(sha2564(data)), 0, 4)]));
|
11129
11572
|
}
|
11130
11573
|
__name(base58check, "base58check");
|
11131
11574
|
function getExtendedKeyPrefix(isPublic = false, testnet = false) {
|
@@ -11148,7 +11591,7 @@ __name(isValidExtendedKey, "isValidExtendedKey");
|
|
11148
11591
|
function parsePath(path2, depth = 0) {
|
11149
11592
|
const components = path2.split("/");
|
11150
11593
|
if (components.length === 0 || components[0] === "m" && depth !== 0) {
|
11151
|
-
throw new
|
11594
|
+
throw new FuelError27(ErrorCode24.HD_WALLET_ERROR, `invalid path - ${path2}`);
|
11152
11595
|
}
|
11153
11596
|
if (components[0] === "m") {
|
11154
11597
|
components.shift();
|
@@ -11181,8 +11624,8 @@ var HDWallet = class _HDWallet {
|
|
11181
11624
|
this.privateKey = hexlify25(config.privateKey);
|
11182
11625
|
} else {
|
11183
11626
|
if (!config.publicKey) {
|
11184
|
-
throw new
|
11185
|
-
|
11627
|
+
throw new FuelError27(
|
11628
|
+
ErrorCode24.HD_WALLET_ERROR,
|
11186
11629
|
"Both public and private Key cannot be missing. At least one should be provided."
|
11187
11630
|
);
|
11188
11631
|
}
|
@@ -11205,28 +11648,28 @@ var HDWallet = class _HDWallet {
|
|
11205
11648
|
* @returns A new instance of HDWallet on the derived index
|
11206
11649
|
*/
|
11207
11650
|
deriveIndex(index) {
|
11208
|
-
const privateKey = this.privateKey &&
|
11209
|
-
const publicKey =
|
11210
|
-
const chainCode =
|
11651
|
+
const privateKey = this.privateKey && arrayify21(this.privateKey);
|
11652
|
+
const publicKey = arrayify21(this.publicKey);
|
11653
|
+
const chainCode = arrayify21(this.chainCode);
|
11211
11654
|
const data = new Uint8Array(37);
|
11212
11655
|
if (index & HARDENED_INDEX) {
|
11213
11656
|
if (!privateKey) {
|
11214
|
-
throw new
|
11215
|
-
|
11657
|
+
throw new FuelError27(
|
11658
|
+
ErrorCode24.HD_WALLET_ERROR,
|
11216
11659
|
"Cannot derive a hardened index without a private Key."
|
11217
11660
|
);
|
11218
11661
|
}
|
11219
11662
|
data.set(privateKey, 1);
|
11220
11663
|
} else {
|
11221
|
-
data.set(
|
11664
|
+
data.set(arrayify21(this.publicKey));
|
11222
11665
|
}
|
11223
|
-
data.set(
|
11224
|
-
const bytes =
|
11666
|
+
data.set(toBytes3(index, 4), 33);
|
11667
|
+
const bytes = arrayify21(computeHmac2("sha512", chainCode, data));
|
11225
11668
|
const IL = bytes.slice(0, 32);
|
11226
11669
|
const IR = bytes.slice(32);
|
11227
11670
|
if (privateKey) {
|
11228
11671
|
const N = "0xfffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364141";
|
11229
|
-
const ki =
|
11672
|
+
const ki = bn23(IL).add(privateKey).mod(N).toBytes(32);
|
11230
11673
|
return new _HDWallet({
|
11231
11674
|
privateKey: ki,
|
11232
11675
|
chainCode: IR,
|
@@ -11264,8 +11707,8 @@ var HDWallet = class _HDWallet {
|
|
11264
11707
|
*/
|
11265
11708
|
toExtendedKey(isPublic = false, testnet = false) {
|
11266
11709
|
if (this.depth >= 256) {
|
11267
|
-
throw new
|
11268
|
-
|
11710
|
+
throw new FuelError27(
|
11711
|
+
ErrorCode24.HD_WALLET_ERROR,
|
11269
11712
|
`Exceeded max depth of 255. Current depth: ${this.depth}.`
|
11270
11713
|
);
|
11271
11714
|
}
|
@@ -11274,8 +11717,8 @@ var HDWallet = class _HDWallet {
|
|
11274
11717
|
const parentFingerprint = this.parentFingerprint;
|
11275
11718
|
const index = toHex(this.index, 4);
|
11276
11719
|
const chainCode = this.chainCode;
|
11277
|
-
const key = this.privateKey != null && !isPublic ?
|
11278
|
-
const extendedKey =
|
11720
|
+
const key = this.privateKey != null && !isPublic ? concat7(["0x00", this.privateKey]) : this.publicKey;
|
11721
|
+
const extendedKey = arrayify21(concat7([prefix, depth, parentFingerprint, index, chainCode, key]));
|
11279
11722
|
return base58check(extendedKey);
|
11280
11723
|
}
|
11281
11724
|
/**
|
@@ -11287,19 +11730,19 @@ var HDWallet = class _HDWallet {
|
|
11287
11730
|
static fromSeed(seed) {
|
11288
11731
|
const masterKey = mnemonic_default.masterKeysFromSeed(seed);
|
11289
11732
|
return new _HDWallet({
|
11290
|
-
chainCode:
|
11291
|
-
privateKey:
|
11733
|
+
chainCode: arrayify21(masterKey.slice(32)),
|
11734
|
+
privateKey: arrayify21(masterKey.slice(0, 32))
|
11292
11735
|
});
|
11293
11736
|
}
|
11294
11737
|
static fromExtendedKey(extendedKey) {
|
11295
|
-
const decoded = hexlify25(
|
11296
|
-
const bytes =
|
11738
|
+
const decoded = hexlify25(toBytes3(decodeBase58(extendedKey)));
|
11739
|
+
const bytes = arrayify21(decoded);
|
11297
11740
|
const validChecksum = base58check(bytes.slice(0, 78)) === extendedKey;
|
11298
11741
|
if (bytes.length !== 82 || !isValidExtendedKey(bytes)) {
|
11299
|
-
throw new
|
11742
|
+
throw new FuelError27(ErrorCode24.HD_WALLET_ERROR, "Provided key is not a valid extended key.");
|
11300
11743
|
}
|
11301
11744
|
if (!validChecksum) {
|
11302
|
-
throw new
|
11745
|
+
throw new FuelError27(ErrorCode24.HD_WALLET_ERROR, "Provided key has an invalid checksum.");
|
11303
11746
|
}
|
11304
11747
|
const depth = bytes[4];
|
11305
11748
|
const parentFingerprint = hexlify25(bytes.slice(5, 9));
|
@@ -11307,14 +11750,14 @@ var HDWallet = class _HDWallet {
|
|
11307
11750
|
const chainCode = hexlify25(bytes.slice(13, 45));
|
11308
11751
|
const key = bytes.slice(45, 78);
|
11309
11752
|
if (depth === 0 && parentFingerprint !== "0x00000000" || depth === 0 && index !== 0) {
|
11310
|
-
throw new
|
11311
|
-
|
11753
|
+
throw new FuelError27(
|
11754
|
+
ErrorCode24.HD_WALLET_ERROR,
|
11312
11755
|
"Inconsistency detected: Depth is zero but fingerprint/index is non-zero."
|
11313
11756
|
);
|
11314
11757
|
}
|
11315
11758
|
if (isPublicExtendedKey(bytes)) {
|
11316
11759
|
if (key[0] !== 3) {
|
11317
|
-
throw new
|
11760
|
+
throw new FuelError27(ErrorCode24.HD_WALLET_ERROR, "Invalid public extended key.");
|
11318
11761
|
}
|
11319
11762
|
return new _HDWallet({
|
11320
11763
|
publicKey: key,
|
@@ -11325,7 +11768,7 @@ var HDWallet = class _HDWallet {
|
|
11325
11768
|
});
|
11326
11769
|
}
|
11327
11770
|
if (key[0] !== 0) {
|
11328
|
-
throw new
|
11771
|
+
throw new FuelError27(ErrorCode24.HD_WALLET_ERROR, "Invalid private extended key.");
|
11329
11772
|
}
|
11330
11773
|
return new _HDWallet({
|
11331
11774
|
privateKey: key.slice(1),
|
@@ -11561,7 +12004,7 @@ var WalletsConfig = class _WalletsConfig {
|
|
11561
12004
|
assetIds.forEach((assetId) => {
|
11562
12005
|
for (let index = 0; index < coinsPerAsset; index++) {
|
11563
12006
|
coins.push({
|
11564
|
-
amount:
|
12007
|
+
amount: bn24(amountPerCoin).toString(),
|
11565
12008
|
asset_id: assetId,
|
11566
12009
|
owner: walletAddress,
|
11567
12010
|
tx_pointer_block_height: 0,
|
@@ -11581,26 +12024,26 @@ var WalletsConfig = class _WalletsConfig {
|
|
11581
12024
|
amountPerCoin
|
11582
12025
|
}) {
|
11583
12026
|
if (Array.isArray(wallets) && wallets.length === 0 || typeof wallets === "number" && wallets <= 0) {
|
11584
|
-
throw new
|
11585
|
-
|
12027
|
+
throw new FuelError28(
|
12028
|
+
FuelError28.CODES.INVALID_INPUT_PARAMETERS,
|
11586
12029
|
"Number of wallets must be greater than zero."
|
11587
12030
|
);
|
11588
12031
|
}
|
11589
12032
|
if (Array.isArray(assets) && assets.length === 0 || typeof assets === "number" && assets <= 0) {
|
11590
|
-
throw new
|
11591
|
-
|
12033
|
+
throw new FuelError28(
|
12034
|
+
FuelError28.CODES.INVALID_INPUT_PARAMETERS,
|
11592
12035
|
"Number of assets per wallet must be greater than zero."
|
11593
12036
|
);
|
11594
12037
|
}
|
11595
12038
|
if (coinsPerAsset <= 0) {
|
11596
|
-
throw new
|
11597
|
-
|
12039
|
+
throw new FuelError28(
|
12040
|
+
FuelError28.CODES.INVALID_INPUT_PARAMETERS,
|
11598
12041
|
"Number of coins per asset must be greater than zero."
|
11599
12042
|
);
|
11600
12043
|
}
|
11601
|
-
if (
|
11602
|
-
throw new
|
11603
|
-
|
12044
|
+
if (bn24(amountPerCoin).lt(0)) {
|
12045
|
+
throw new FuelError28(
|
12046
|
+
FuelError28.CODES.INVALID_INPUT_PARAMETERS,
|
11604
12047
|
"Amount per coin must be greater than or equal to zero."
|
11605
12048
|
);
|
11606
12049
|
}
|
@@ -11676,9 +12119,9 @@ async function setupTestProviderAndWallets({
|
|
11676
12119
|
__name(setupTestProviderAndWallets, "setupTestProviderAndWallets");
|
11677
12120
|
|
11678
12121
|
// src/test-utils/test-message.ts
|
11679
|
-
import { Address as
|
12122
|
+
import { Address as Address8 } from "@fuel-ts/address";
|
11680
12123
|
import { randomBytes as randomBytes9 } from "@fuel-ts/crypto";
|
11681
|
-
import { bn as
|
12124
|
+
import { bn as bn25 } from "@fuel-ts/math";
|
11682
12125
|
import { hexlify as hexlify27 } from "@fuel-ts/utils";
|
11683
12126
|
var TestMessage = class {
|
11684
12127
|
static {
|
@@ -11697,8 +12140,8 @@ var TestMessage = class {
|
|
11697
12140
|
* It can also be used standalone and passed into the initial state of a chain via the `.toChainMessage` method.
|
11698
12141
|
*/
|
11699
12142
|
constructor({
|
11700
|
-
sender =
|
11701
|
-
recipient =
|
12143
|
+
sender = Address8.fromRandom(),
|
12144
|
+
recipient = Address8.fromRandom(),
|
11702
12145
|
nonce = hexlify27(randomBytes9(32)),
|
11703
12146
|
amount = 1e6,
|
11704
12147
|
data = "",
|
@@ -11718,7 +12161,7 @@ var TestMessage = class {
|
|
11718
12161
|
sender: this.sender.toB256(),
|
11719
12162
|
recipient: recipient?.toB256() ?? this.recipient.toB256(),
|
11720
12163
|
nonce: this.nonce,
|
11721
|
-
amount:
|
12164
|
+
amount: bn25(this.amount).toNumber(),
|
11722
12165
|
data,
|
11723
12166
|
da_height: this.da_height
|
11724
12167
|
};
|