genlayer-js 0.19.1 → 0.19.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/index.cjs CHANGED
@@ -628,7 +628,7 @@ var contractActions = (client, publicClient) => {
628
628
  const data = [encode(makeCalldataObject(functionName, callArgs, kwargs)), leaderOnly];
629
629
  const serializedData = serialize(data);
630
630
  const senderAccount = account || client.account;
631
- const encodedData = _encodeAddTransactionData({
631
+ const { primaryEncodedData, fallbackEncodedData } = _encodeAddTransactionData({
632
632
  client,
633
633
  senderAccount,
634
634
  recipient: address,
@@ -638,7 +638,8 @@ var contractActions = (client, publicClient) => {
638
638
  return _sendTransaction({
639
639
  client,
640
640
  publicClient,
641
- encodedData,
641
+ encodedData: primaryEncodedData,
642
+ fallbackEncodedData,
642
643
  senderAccount,
643
644
  value
644
645
  });
@@ -660,7 +661,7 @@ var contractActions = (client, publicClient) => {
660
661
  ];
661
662
  const serializedData = serialize(data);
662
663
  const senderAccount = account || client.account;
663
- const encodedData = _encodeAddTransactionData({
664
+ const { primaryEncodedData, fallbackEncodedData } = _encodeAddTransactionData({
664
665
  client,
665
666
  senderAccount,
666
667
  recipient: _viem.zeroAddress,
@@ -670,7 +671,8 @@ var contractActions = (client, publicClient) => {
670
671
  return _sendTransaction({
671
672
  client,
672
673
  publicClient,
673
- encodedData,
674
+ encodedData: primaryEncodedData,
675
+ fallbackEncodedData,
674
676
  senderAccount
675
677
  });
676
678
  },
@@ -754,18 +756,26 @@ var _encodeAddTransactionData = ({
754
756
  consensusMaxRotations,
755
757
  data
756
758
  ];
757
- if (getAddTransactionInputCount(_optionalChain([client, 'access', _12 => _12.chain, 'access', _13 => _13.consensusMainContract, 'optionalAccess', _14 => _14.abi])) >= 6) {
758
- return _viem.encodeFunctionData.call(void 0, {
759
- abi: ADD_TRANSACTION_ABI_V6,
760
- functionName: "addTransaction",
761
- args: [...addTransactionArgs, 0n]
762
- });
763
- }
764
- return _viem.encodeFunctionData.call(void 0, {
759
+ const encodedDataV5 = _viem.encodeFunctionData.call(void 0, {
765
760
  abi: ADD_TRANSACTION_ABI_V5,
766
761
  functionName: "addTransaction",
767
762
  args: addTransactionArgs
768
763
  });
764
+ const encodedDataV6 = _viem.encodeFunctionData.call(void 0, {
765
+ abi: ADD_TRANSACTION_ABI_V6,
766
+ functionName: "addTransaction",
767
+ args: [...addTransactionArgs, 0n]
768
+ });
769
+ if (getAddTransactionInputCount(_optionalChain([client, 'access', _12 => _12.chain, 'access', _13 => _13.consensusMainContract, 'optionalAccess', _14 => _14.abi])) >= 6) {
770
+ return {
771
+ primaryEncodedData: encodedDataV6,
772
+ fallbackEncodedData: encodedDataV5
773
+ };
774
+ }
775
+ return {
776
+ primaryEncodedData: encodedDataV5,
777
+ fallbackEncodedData: encodedDataV6
778
+ };
769
779
  };
770
780
  var _encodeSubmitAppealData = ({
771
781
  client,
@@ -777,84 +787,105 @@ var _encodeSubmitAppealData = ({
777
787
  args: [txId]
778
788
  });
779
789
  };
790
+ var isAddTransactionAbiMismatchError = (error) => {
791
+ const errorObject = error;
792
+ const errorMessage = [
793
+ _optionalChain([errorObject, 'optionalAccess', _18 => _18.shortMessage]),
794
+ _optionalChain([errorObject, 'optionalAccess', _19 => _19.details]),
795
+ _optionalChain([errorObject, 'optionalAccess', _20 => _20.message]),
796
+ String(_nullishCoalesce(error, () => ( "")))
797
+ ].filter(Boolean).join(" ").toLowerCase();
798
+ return errorMessage.includes("invalid pointer in tuple") || errorMessage.includes("could not decode") || errorMessage.includes("invalid arrayify value") || errorMessage.includes("types/value length mismatch");
799
+ };
780
800
  var _sendTransaction = async ({
781
801
  client,
782
802
  publicClient,
783
803
  encodedData,
804
+ fallbackEncodedData,
784
805
  senderAccount,
785
806
  value = 0n
786
807
  }) => {
787
- if (!_optionalChain([client, 'access', _18 => _18.chain, 'access', _19 => _19.consensusMainContract, 'optionalAccess', _20 => _20.address])) {
808
+ if (!_optionalChain([client, 'access', _21 => _21.chain, 'access', _22 => _22.consensusMainContract, 'optionalAccess', _23 => _23.address])) {
788
809
  throw new Error("Consensus main contract not initialized. Please ensure client is properly initialized.");
789
810
  }
790
811
  const validatedSenderAccount = validateAccount(senderAccount);
791
812
  const nonce = await client.getCurrentNonce({ address: validatedSenderAccount.address });
792
- let estimatedGas;
793
- try {
794
- estimatedGas = await client.estimateTransactionGas({
795
- from: validatedSenderAccount.address,
796
- to: _optionalChain([client, 'access', _21 => _21.chain, 'access', _22 => _22.consensusMainContract, 'optionalAccess', _23 => _23.address]),
797
- data: encodedData,
798
- value
799
- });
800
- } catch (err) {
801
- console.error("Gas estimation failed, using default 200_000:", err);
802
- estimatedGas = 200000n;
803
- }
804
- if (_optionalChain([validatedSenderAccount, 'optionalAccess', _24 => _24.type]) === "local") {
805
- if (!_optionalChain([validatedSenderAccount, 'optionalAccess', _25 => _25.signTransaction])) {
806
- throw new Error("Account does not support signTransaction");
813
+ const sendWithEncodedData = async (encodedDataForSend) => {
814
+ let estimatedGas;
815
+ try {
816
+ estimatedGas = await client.estimateTransactionGas({
817
+ from: validatedSenderAccount.address,
818
+ to: _optionalChain([client, 'access', _24 => _24.chain, 'access', _25 => _25.consensusMainContract, 'optionalAccess', _26 => _26.address]),
819
+ data: encodedDataForSend,
820
+ value
821
+ });
822
+ } catch (err) {
823
+ console.error("Gas estimation failed, using default 200_000:", err);
824
+ estimatedGas = 200000n;
807
825
  }
808
- const gasPriceHex = await client.request({
809
- method: "eth_gasPrice"
810
- });
811
- const transactionRequest2 = {
826
+ if (_optionalChain([validatedSenderAccount, 'optionalAccess', _27 => _27.type]) === "local") {
827
+ if (!_optionalChain([validatedSenderAccount, 'optionalAccess', _28 => _28.signTransaction])) {
828
+ throw new Error("Account does not support signTransaction");
829
+ }
830
+ const gasPriceHex = await client.request({
831
+ method: "eth_gasPrice"
832
+ });
833
+ const transactionRequest2 = {
834
+ account: validatedSenderAccount,
835
+ to: _optionalChain([client, 'access', _29 => _29.chain, 'access', _30 => _30.consensusMainContract, 'optionalAccess', _31 => _31.address]),
836
+ data: encodedDataForSend,
837
+ type: "legacy",
838
+ nonce: Number(nonce),
839
+ value,
840
+ gas: estimatedGas,
841
+ gasPrice: BigInt(gasPriceHex),
842
+ chainId: client.chain.id
843
+ };
844
+ const serializedTransaction = await validatedSenderAccount.signTransaction(transactionRequest2);
845
+ const txHash = await client.sendRawTransaction({ serializedTransaction });
846
+ const receipt = await publicClient.waitForTransactionReceipt({ hash: txHash });
847
+ if (receipt.status === "reverted") {
848
+ throw new Error("Transaction reverted");
849
+ }
850
+ const newTxEvents = _viem.parseEventLogs.call(void 0, {
851
+ abi: _optionalChain([client, 'access', _32 => _32.chain, 'access', _33 => _33.consensusMainContract, 'optionalAccess', _34 => _34.abi]),
852
+ eventName: "NewTransaction",
853
+ logs: receipt.logs
854
+ });
855
+ if (newTxEvents.length === 0) {
856
+ throw new Error("Transaction not processed by consensus");
857
+ }
858
+ return newTxEvents[0].args["txId"];
859
+ }
860
+ const transactionRequest = await client.prepareTransactionRequest({
812
861
  account: validatedSenderAccount,
813
- to: _optionalChain([client, 'access', _26 => _26.chain, 'access', _27 => _27.consensusMainContract, 'optionalAccess', _28 => _28.address]),
814
- data: encodedData,
862
+ to: _optionalChain([client, 'access', _35 => _35.chain, 'access', _36 => _36.consensusMainContract, 'optionalAccess', _37 => _37.address]),
863
+ data: encodedDataForSend,
815
864
  type: "legacy",
816
865
  nonce: Number(nonce),
817
866
  value,
818
- gas: estimatedGas,
819
- gasPrice: BigInt(gasPriceHex),
820
- chainId: client.chain.id
867
+ gas: estimatedGas
868
+ });
869
+ const formattedRequest = {
870
+ from: transactionRequest.from,
871
+ to: transactionRequest.to,
872
+ data: encodedDataForSend,
873
+ value: transactionRequest.value ? `0x${transactionRequest.value.toString(16)}` : "0x0",
874
+ gas: transactionRequest.gas ? `0x${transactionRequest.gas.toString(16)}` : "0x5208"
821
875
  };
822
- const serializedTransaction = await validatedSenderAccount.signTransaction(transactionRequest2);
823
- const txHash = await client.sendRawTransaction({ serializedTransaction });
824
- const receipt = await publicClient.waitForTransactionReceipt({ hash: txHash });
825
- if (receipt.status === "reverted") {
826
- throw new Error("Transaction reverted");
827
- }
828
- const newTxEvents = _viem.parseEventLogs.call(void 0, {
829
- abi: _optionalChain([client, 'access', _29 => _29.chain, 'access', _30 => _30.consensusMainContract, 'optionalAccess', _31 => _31.abi]),
830
- eventName: "NewTransaction",
831
- logs: receipt.logs
876
+ return await client.request({
877
+ method: "eth_sendTransaction",
878
+ params: [formattedRequest]
832
879
  });
833
- if (newTxEvents.length === 0) {
834
- throw new Error("Transaction not processed by consensus");
880
+ };
881
+ try {
882
+ return await sendWithEncodedData(encodedData);
883
+ } catch (error) {
884
+ if (!fallbackEncodedData || !isAddTransactionAbiMismatchError(error)) {
885
+ throw error;
835
886
  }
836
- return newTxEvents[0].args["txId"];
887
+ return await sendWithEncodedData(fallbackEncodedData);
837
888
  }
838
- const transactionRequest = await client.prepareTransactionRequest({
839
- account: validatedSenderAccount,
840
- to: _optionalChain([client, 'access', _32 => _32.chain, 'access', _33 => _33.consensusMainContract, 'optionalAccess', _34 => _34.address]),
841
- data: encodedData,
842
- type: "legacy",
843
- nonce: Number(nonce),
844
- value,
845
- gas: estimatedGas
846
- });
847
- const formattedRequest = {
848
- from: transactionRequest.from,
849
- to: transactionRequest.to,
850
- data: encodedData,
851
- value: transactionRequest.value ? `0x${transactionRequest.value.toString(16)}` : "0x0",
852
- gas: transactionRequest.gas ? `0x${transactionRequest.gas.toString(16)}` : "0x5208"
853
- };
854
- return await client.request({
855
- method: "eth_sendTransaction",
856
- params: [formattedRequest]
857
- });
858
889
  };
859
890
 
860
891
  // src/config/transactions.ts
@@ -1061,7 +1092,7 @@ var simplifyTransactionReceipt = (tx) => {
1061
1092
  var decodeLocalnetTransaction = (tx) => {
1062
1093
  if (!tx.data) return tx;
1063
1094
  try {
1064
- const leaderReceipt = _optionalChain([tx, 'access', _35 => _35.consensus_data, 'optionalAccess', _36 => _36.leader_receipt]);
1095
+ const leaderReceipt = _optionalChain([tx, 'access', _38 => _38.consensus_data, 'optionalAccess', _39 => _39.leader_receipt]);
1065
1096
  if (leaderReceipt) {
1066
1097
  const receipts = Array.isArray(leaderReceipt) ? leaderReceipt : [leaderReceipt];
1067
1098
  receipts.forEach((receipt) => {
@@ -1092,7 +1123,7 @@ var decodeLocalnetTransaction = (tx) => {
1092
1123
  }
1093
1124
  });
1094
1125
  }
1095
- if (_optionalChain([tx, 'access', _37 => _37.data, 'optionalAccess', _38 => _38.calldata]) && typeof tx.data.calldata === "string") {
1126
+ if (_optionalChain([tx, 'access', _40 => _40.data, 'optionalAccess', _41 => _41.calldata]) && typeof tx.data.calldata === "string") {
1096
1127
  tx.data.calldata = {
1097
1128
  base64: tx.data.calldata,
1098
1129
  ...calldataToUserFriendlyJson(b64ToArray(tx.data.calldata))
@@ -1154,8 +1185,8 @@ var transactionActions = (client, publicClient) => ({
1154
1185
  return decodeLocalnetTransaction(transaction2);
1155
1186
  }
1156
1187
  const transaction = await publicClient.readContract({
1157
- address: _optionalChain([client, 'access', _39 => _39.chain, 'access', _40 => _40.consensusDataContract, 'optionalAccess', _41 => _41.address]),
1158
- abi: _optionalChain([client, 'access', _42 => _42.chain, 'access', _43 => _43.consensusDataContract, 'optionalAccess', _44 => _44.abi]),
1188
+ address: _optionalChain([client, 'access', _42 => _42.chain, 'access', _43 => _43.consensusDataContract, 'optionalAccess', _44 => _44.address]),
1189
+ abi: _optionalChain([client, 'access', _45 => _45.chain, 'access', _46 => _46.consensusDataContract, 'optionalAccess', _47 => _47.abi]),
1159
1190
  functionName: "getTransactionData",
1160
1191
  args: [
1161
1192
  hash,
@@ -1167,7 +1198,7 @@ var transactionActions = (client, publicClient) => ({
1167
1198
  },
1168
1199
  estimateTransactionGas: async (transactionParams) => {
1169
1200
  const formattedParams = {
1170
- from: transactionParams.from || _optionalChain([client, 'access', _45 => _45.account, 'optionalAccess', _46 => _46.address]),
1201
+ from: transactionParams.from || _optionalChain([client, 'access', _48 => _48.account, 'optionalAccess', _49 => _49.address]),
1171
1202
  to: transactionParams.to,
1172
1203
  data: transactionParams.data || "0x",
1173
1204
  value: transactionParams.value ? `0x${transactionParams.value.toString(16)}` : "0x0"
@@ -1209,7 +1240,7 @@ var connect = async (client, network = "studionet", snapSource = "npm") => {
1209
1240
  chainName: selectedNetwork.name,
1210
1241
  rpcUrls: selectedNetwork.rpcUrls.default.http,
1211
1242
  nativeCurrency: selectedNetwork.nativeCurrency,
1212
- blockExplorerUrls: [_optionalChain([selectedNetwork, 'access', _47 => _47.blockExplorers, 'optionalAccess', _48 => _48.default, 'access', _49 => _49.url])]
1243
+ blockExplorerUrls: [_optionalChain([selectedNetwork, 'access', _50 => _50.blockExplorers, 'optionalAccess', _51 => _51.default, 'access', _52 => _52.url])]
1213
1244
  };
1214
1245
  const currentChainId = await window.ethereum.request({ method: "eth_chainId" });
1215
1246
  if (currentChainId !== chainIdHex) {
@@ -1243,10 +1274,10 @@ var metamaskClient = async (snapSource = "npm") => {
1243
1274
  }
1244
1275
  const isFlask = async () => {
1245
1276
  try {
1246
- const clientVersion = await _optionalChain([window, 'access', _50 => _50.ethereum, 'optionalAccess', _51 => _51.request, 'call', _52 => _52({
1277
+ const clientVersion = await _optionalChain([window, 'access', _53 => _53.ethereum, 'optionalAccess', _54 => _54.request, 'call', _55 => _55({
1247
1278
  method: "web3_clientVersion"
1248
1279
  })]);
1249
- return _optionalChain([clientVersion, 'optionalAccess', _53 => _53.includes, 'call', _54 => _54("flask")]);
1280
+ return _optionalChain([clientVersion, 'optionalAccess', _56 => _56.includes, 'call', _57 => _57("flask")]);
1250
1281
  } catch (error) {
1251
1282
  console.error("Error detecting Flask:", error);
1252
1283
  return false;
@@ -1254,7 +1285,7 @@ var metamaskClient = async (snapSource = "npm") => {
1254
1285
  };
1255
1286
  const installedSnaps = async () => {
1256
1287
  try {
1257
- return await _optionalChain([window, 'access', _55 => _55.ethereum, 'optionalAccess', _56 => _56.request, 'call', _57 => _57({
1288
+ return await _optionalChain([window, 'access', _58 => _58.ethereum, 'optionalAccess', _59 => _59.request, 'call', _60 => _60({
1258
1289
  method: "wallet_getSnaps"
1259
1290
  })]);
1260
1291
  } catch (error) {
@@ -1341,7 +1372,7 @@ function extractRevertReason(err) {
1341
1372
  }
1342
1373
  const revertError = err.walk((e) => e instanceof _viem.ContractFunctionRevertedError);
1343
1374
  if (revertError instanceof _viem.ContractFunctionRevertedError) {
1344
- if (_optionalChain([revertError, 'access', _58 => _58.data, 'optionalAccess', _59 => _59.errorName])) {
1375
+ if (_optionalChain([revertError, 'access', _61 => _61.data, 'optionalAccess', _62 => _62.errorName])) {
1345
1376
  return revertError.data.errorName;
1346
1377
  }
1347
1378
  return revertError.reason || "Unknown reason";
@@ -1429,7 +1460,7 @@ var stakingActions = (client, publicClient) => {
1429
1460
  };
1430
1461
  const getStakingAddress = () => {
1431
1462
  const stakingConfig = client.chain.stakingContract;
1432
- if (!_optionalChain([stakingConfig, 'optionalAccess', _60 => _60.address]) || stakingConfig.address === "0x0000000000000000000000000000000000000000") {
1463
+ if (!_optionalChain([stakingConfig, 'optionalAccess', _63 => _63.address]) || stakingConfig.address === "0x0000000000000000000000000000000000000000") {
1433
1464
  throw new Error("Staking is not supported on studio-based networks. Use testnet-asimov for staking operations.");
1434
1465
  }
1435
1466
  return stakingConfig.address;
@@ -1510,10 +1541,10 @@ var stakingActions = (client, publicClient) => {
1510
1541
  return executeWrite({ to: getStakingAddress(), data });
1511
1542
  },
1512
1543
  validatorClaim: async (options) => {
1513
- if (!_optionalChain([options, 'optionalAccess', _61 => _61.validator]) && !client.account) {
1544
+ if (!_optionalChain([options, 'optionalAccess', _64 => _64.validator]) && !client.account) {
1514
1545
  throw new Error("Either provide validator address or initialize client with an account");
1515
1546
  }
1516
- const validatorAddress = _optionalChain([options, 'optionalAccess', _62 => _62.validator]) || client.account.address;
1547
+ const validatorAddress = _optionalChain([options, 'optionalAccess', _65 => _65.validator]) || client.account.address;
1517
1548
  const data = _viem.encodeFunctionData.call(void 0, {
1518
1549
  abi: _chunk5TKVNHAOcjs.STAKING_ABI,
1519
1550
  functionName: "validatorClaim",
@@ -1854,11 +1885,11 @@ var stakingActions = (client, publicClient) => {
1854
1885
  function chainActions(client) {
1855
1886
  return {
1856
1887
  initializeConsensusSmartContract: async (forceReset = false) => {
1857
- if (_optionalChain([client, 'access', _63 => _63.chain, 'optionalAccess', _64 => _64.id]) === _chunk5TKVNHAOcjs.testnetAsimov.id) {
1888
+ if (_optionalChain([client, 'access', _66 => _66.chain, 'optionalAccess', _67 => _67.id]) === _chunk5TKVNHAOcjs.testnetAsimov.id) {
1858
1889
  return;
1859
1890
  }
1860
- const hasStaticConsensusContract = !!_optionalChain([client, 'access', _65 => _65.chain, 'access', _66 => _66.consensusMainContract, 'optionalAccess', _67 => _67.address]) && !!_optionalChain([client, 'access', _68 => _68.chain, 'access', _69 => _69.consensusMainContract, 'optionalAccess', _70 => _70.abi]);
1861
- const isLocalOrStudioChain = _optionalChain([client, 'access', _71 => _71.chain, 'optionalAccess', _72 => _72.id]) === _chunk5TKVNHAOcjs.localnet.id || _optionalChain([client, 'access', _73 => _73.chain, 'optionalAccess', _74 => _74.id]) === _chunk5TKVNHAOcjs.studionet.id;
1891
+ const hasStaticConsensusContract = !!_optionalChain([client, 'access', _68 => _68.chain, 'access', _69 => _69.consensusMainContract, 'optionalAccess', _70 => _70.address]) && !!_optionalChain([client, 'access', _71 => _71.chain, 'access', _72 => _72.consensusMainContract, 'optionalAccess', _73 => _73.abi]);
1892
+ const isLocalOrStudioChain = _optionalChain([client, 'access', _74 => _74.chain, 'optionalAccess', _75 => _75.id]) === _chunk5TKVNHAOcjs.localnet.id || _optionalChain([client, 'access', _76 => _76.chain, 'optionalAccess', _77 => _77.id]) === _chunk5TKVNHAOcjs.studionet.id;
1862
1893
  if (!forceReset && hasStaticConsensusContract && !isLocalOrStudioChain) {
1863
1894
  return;
1864
1895
  }
@@ -1879,7 +1910,7 @@ function chainActions(client) {
1879
1910
  throw new Error("Failed to fetch ConsensusMain contract");
1880
1911
  }
1881
1912
  const consensusMainContract = await contractsResponse.json();
1882
- if (_optionalChain([consensusMainContract, 'optionalAccess', _75 => _75.error]) || !_optionalChain([consensusMainContract, 'optionalAccess', _76 => _76.result, 'optionalAccess', _77 => _77.address]) || !_optionalChain([consensusMainContract, 'optionalAccess', _78 => _78.result, 'optionalAccess', _79 => _79.abi])) {
1913
+ if (_optionalChain([consensusMainContract, 'optionalAccess', _78 => _78.error]) || !_optionalChain([consensusMainContract, 'optionalAccess', _79 => _79.result, 'optionalAccess', _80 => _80.address]) || !_optionalChain([consensusMainContract, 'optionalAccess', _81 => _81.result, 'optionalAccess', _82 => _82.abi])) {
1883
1914
  throw new Error("ConsensusMain response did not include a valid contract");
1884
1915
  }
1885
1916
  client.chain.consensusMainContract = consensusMainContract.result;
package/dist/index.js CHANGED
@@ -628,7 +628,7 @@ var contractActions = (client, publicClient) => {
628
628
  const data = [encode(makeCalldataObject(functionName, callArgs, kwargs)), leaderOnly];
629
629
  const serializedData = serialize(data);
630
630
  const senderAccount = account || client.account;
631
- const encodedData = _encodeAddTransactionData({
631
+ const { primaryEncodedData, fallbackEncodedData } = _encodeAddTransactionData({
632
632
  client,
633
633
  senderAccount,
634
634
  recipient: address,
@@ -638,7 +638,8 @@ var contractActions = (client, publicClient) => {
638
638
  return _sendTransaction({
639
639
  client,
640
640
  publicClient,
641
- encodedData,
641
+ encodedData: primaryEncodedData,
642
+ fallbackEncodedData,
642
643
  senderAccount,
643
644
  value
644
645
  });
@@ -660,7 +661,7 @@ var contractActions = (client, publicClient) => {
660
661
  ];
661
662
  const serializedData = serialize(data);
662
663
  const senderAccount = account || client.account;
663
- const encodedData = _encodeAddTransactionData({
664
+ const { primaryEncodedData, fallbackEncodedData } = _encodeAddTransactionData({
664
665
  client,
665
666
  senderAccount,
666
667
  recipient: zeroAddress,
@@ -670,7 +671,8 @@ var contractActions = (client, publicClient) => {
670
671
  return _sendTransaction({
671
672
  client,
672
673
  publicClient,
673
- encodedData,
674
+ encodedData: primaryEncodedData,
675
+ fallbackEncodedData,
674
676
  senderAccount
675
677
  });
676
678
  },
@@ -754,18 +756,26 @@ var _encodeAddTransactionData = ({
754
756
  consensusMaxRotations,
755
757
  data
756
758
  ];
757
- if (getAddTransactionInputCount(client.chain.consensusMainContract?.abi) >= 6) {
758
- return encodeFunctionData({
759
- abi: ADD_TRANSACTION_ABI_V6,
760
- functionName: "addTransaction",
761
- args: [...addTransactionArgs, 0n]
762
- });
763
- }
764
- return encodeFunctionData({
759
+ const encodedDataV5 = encodeFunctionData({
765
760
  abi: ADD_TRANSACTION_ABI_V5,
766
761
  functionName: "addTransaction",
767
762
  args: addTransactionArgs
768
763
  });
764
+ const encodedDataV6 = encodeFunctionData({
765
+ abi: ADD_TRANSACTION_ABI_V6,
766
+ functionName: "addTransaction",
767
+ args: [...addTransactionArgs, 0n]
768
+ });
769
+ if (getAddTransactionInputCount(client.chain.consensusMainContract?.abi) >= 6) {
770
+ return {
771
+ primaryEncodedData: encodedDataV6,
772
+ fallbackEncodedData: encodedDataV5
773
+ };
774
+ }
775
+ return {
776
+ primaryEncodedData: encodedDataV5,
777
+ fallbackEncodedData: encodedDataV6
778
+ };
769
779
  };
770
780
  var _encodeSubmitAppealData = ({
771
781
  client,
@@ -777,10 +787,21 @@ var _encodeSubmitAppealData = ({
777
787
  args: [txId]
778
788
  });
779
789
  };
790
+ var isAddTransactionAbiMismatchError = (error) => {
791
+ const errorObject = error;
792
+ const errorMessage = [
793
+ errorObject?.shortMessage,
794
+ errorObject?.details,
795
+ errorObject?.message,
796
+ String(error ?? "")
797
+ ].filter(Boolean).join(" ").toLowerCase();
798
+ return errorMessage.includes("invalid pointer in tuple") || errorMessage.includes("could not decode") || errorMessage.includes("invalid arrayify value") || errorMessage.includes("types/value length mismatch");
799
+ };
780
800
  var _sendTransaction = async ({
781
801
  client,
782
802
  publicClient,
783
803
  encodedData,
804
+ fallbackEncodedData,
784
805
  senderAccount,
785
806
  value = 0n
786
807
  }) => {
@@ -789,72 +810,82 @@ var _sendTransaction = async ({
789
810
  }
790
811
  const validatedSenderAccount = validateAccount(senderAccount);
791
812
  const nonce = await client.getCurrentNonce({ address: validatedSenderAccount.address });
792
- let estimatedGas;
793
- try {
794
- estimatedGas = await client.estimateTransactionGas({
795
- from: validatedSenderAccount.address,
796
- to: client.chain.consensusMainContract?.address,
797
- data: encodedData,
798
- value
799
- });
800
- } catch (err) {
801
- console.error("Gas estimation failed, using default 200_000:", err);
802
- estimatedGas = 200000n;
803
- }
804
- if (validatedSenderAccount?.type === "local") {
805
- if (!validatedSenderAccount?.signTransaction) {
806
- throw new Error("Account does not support signTransaction");
813
+ const sendWithEncodedData = async (encodedDataForSend) => {
814
+ let estimatedGas;
815
+ try {
816
+ estimatedGas = await client.estimateTransactionGas({
817
+ from: validatedSenderAccount.address,
818
+ to: client.chain.consensusMainContract?.address,
819
+ data: encodedDataForSend,
820
+ value
821
+ });
822
+ } catch (err) {
823
+ console.error("Gas estimation failed, using default 200_000:", err);
824
+ estimatedGas = 200000n;
807
825
  }
808
- const gasPriceHex = await client.request({
809
- method: "eth_gasPrice"
810
- });
811
- const transactionRequest2 = {
826
+ if (validatedSenderAccount?.type === "local") {
827
+ if (!validatedSenderAccount?.signTransaction) {
828
+ throw new Error("Account does not support signTransaction");
829
+ }
830
+ const gasPriceHex = await client.request({
831
+ method: "eth_gasPrice"
832
+ });
833
+ const transactionRequest2 = {
834
+ account: validatedSenderAccount,
835
+ to: client.chain.consensusMainContract?.address,
836
+ data: encodedDataForSend,
837
+ type: "legacy",
838
+ nonce: Number(nonce),
839
+ value,
840
+ gas: estimatedGas,
841
+ gasPrice: BigInt(gasPriceHex),
842
+ chainId: client.chain.id
843
+ };
844
+ const serializedTransaction = await validatedSenderAccount.signTransaction(transactionRequest2);
845
+ const txHash = await client.sendRawTransaction({ serializedTransaction });
846
+ const receipt = await publicClient.waitForTransactionReceipt({ hash: txHash });
847
+ if (receipt.status === "reverted") {
848
+ throw new Error("Transaction reverted");
849
+ }
850
+ const newTxEvents = parseEventLogs({
851
+ abi: client.chain.consensusMainContract?.abi,
852
+ eventName: "NewTransaction",
853
+ logs: receipt.logs
854
+ });
855
+ if (newTxEvents.length === 0) {
856
+ throw new Error("Transaction not processed by consensus");
857
+ }
858
+ return newTxEvents[0].args["txId"];
859
+ }
860
+ const transactionRequest = await client.prepareTransactionRequest({
812
861
  account: validatedSenderAccount,
813
862
  to: client.chain.consensusMainContract?.address,
814
- data: encodedData,
863
+ data: encodedDataForSend,
815
864
  type: "legacy",
816
865
  nonce: Number(nonce),
817
866
  value,
818
- gas: estimatedGas,
819
- gasPrice: BigInt(gasPriceHex),
820
- chainId: client.chain.id
867
+ gas: estimatedGas
868
+ });
869
+ const formattedRequest = {
870
+ from: transactionRequest.from,
871
+ to: transactionRequest.to,
872
+ data: encodedDataForSend,
873
+ value: transactionRequest.value ? `0x${transactionRequest.value.toString(16)}` : "0x0",
874
+ gas: transactionRequest.gas ? `0x${transactionRequest.gas.toString(16)}` : "0x5208"
821
875
  };
822
- const serializedTransaction = await validatedSenderAccount.signTransaction(transactionRequest2);
823
- const txHash = await client.sendRawTransaction({ serializedTransaction });
824
- const receipt = await publicClient.waitForTransactionReceipt({ hash: txHash });
825
- if (receipt.status === "reverted") {
826
- throw new Error("Transaction reverted");
827
- }
828
- const newTxEvents = parseEventLogs({
829
- abi: client.chain.consensusMainContract?.abi,
830
- eventName: "NewTransaction",
831
- logs: receipt.logs
876
+ return await client.request({
877
+ method: "eth_sendTransaction",
878
+ params: [formattedRequest]
832
879
  });
833
- if (newTxEvents.length === 0) {
834
- throw new Error("Transaction not processed by consensus");
880
+ };
881
+ try {
882
+ return await sendWithEncodedData(encodedData);
883
+ } catch (error) {
884
+ if (!fallbackEncodedData || !isAddTransactionAbiMismatchError(error)) {
885
+ throw error;
835
886
  }
836
- return newTxEvents[0].args["txId"];
887
+ return await sendWithEncodedData(fallbackEncodedData);
837
888
  }
838
- const transactionRequest = await client.prepareTransactionRequest({
839
- account: validatedSenderAccount,
840
- to: client.chain.consensusMainContract?.address,
841
- data: encodedData,
842
- type: "legacy",
843
- nonce: Number(nonce),
844
- value,
845
- gas: estimatedGas
846
- });
847
- const formattedRequest = {
848
- from: transactionRequest.from,
849
- to: transactionRequest.to,
850
- data: encodedData,
851
- value: transactionRequest.value ? `0x${transactionRequest.value.toString(16)}` : "0x0",
852
- gas: transactionRequest.gas ? `0x${transactionRequest.gas.toString(16)}` : "0x5208"
853
- };
854
- return await client.request({
855
- method: "eth_sendTransaction",
856
- params: [formattedRequest]
857
- });
858
889
  };
859
890
 
860
891
  // src/config/transactions.ts
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "genlayer-js",
3
3
  "type": "module",
4
- "version": "0.19.1",
4
+ "version": "0.19.3",
5
5
  "description": "GenLayer JavaScript SDK",
6
6
  "main": "dist/index.js",
7
7
  "types": "dist/index.d.ts",