genlayer-js 0.18.0 → 0.18.1

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/CHANGELOG.md CHANGED
@@ -1,5 +1,12 @@
1
1
 
2
2
 
3
+ ## 0.18.1 (2025-09-11)
4
+
5
+
6
+ ### Bug Fixes
7
+
8
+ * replace hardcoded gas 21000 ([#115](https://github.com/genlayerlabs/genlayer-js/issues/115)) ([8eacd5d](https://github.com/genlayerlabs/genlayer-js/commit/8eacd5dbba9ae85f0232ec525076582ea8b6b045))
9
+
3
10
  ## 0.18.0 (2025-09-04)
4
11
 
5
12
 
@@ -313,6 +313,9 @@ type GenLayerMethod = {
313
313
  } | {
314
314
  method: "eth_getTransactionCount";
315
315
  params: [address: Address, block: string];
316
+ } | {
317
+ method: "eth_estimateGas";
318
+ params: [transactionParams: any];
316
319
  } | {
317
320
  method: "gen_call";
318
321
  params: [requestParams: any];
@@ -375,6 +378,12 @@ type GenLayerClient<TGenLayerChain extends GenLayerChain> = Omit<Client<Transpor
375
378
  getCurrentNonce: (args: {
376
379
  address: Address;
377
380
  }) => Promise<number>;
381
+ estimateTransactionGas: (transactionParams: {
382
+ from?: Address;
383
+ to: Address;
384
+ data?: `0x${string}`;
385
+ value?: bigint;
386
+ }) => Promise<bigint>;
378
387
  waitForTransactionReceipt: (args: {
379
388
  hash: TransactionHash;
380
389
  status?: TransactionStatus;
@@ -313,6 +313,9 @@ type GenLayerMethod = {
313
313
  } | {
314
314
  method: "eth_getTransactionCount";
315
315
  params: [address: Address, block: string];
316
+ } | {
317
+ method: "eth_estimateGas";
318
+ params: [transactionParams: any];
316
319
  } | {
317
320
  method: "gen_call";
318
321
  params: [requestParams: any];
@@ -375,6 +378,12 @@ type GenLayerClient<TGenLayerChain extends GenLayerChain> = Omit<Client<Transpor
375
378
  getCurrentNonce: (args: {
376
379
  address: Address;
377
380
  }) => Promise<number>;
381
+ estimateTransactionGas: (transactionParams: {
382
+ from?: Address;
383
+ to: Address;
384
+ data?: `0x${string}`;
385
+ value?: bigint;
386
+ }) => Promise<bigint>;
378
387
  waitForTransactionReceipt: (args: {
379
388
  hash: TransactionHash;
380
389
  status?: TransactionStatus;
package/dist/index.cjs CHANGED
@@ -730,16 +730,28 @@ var _sendTransaction = async ({
730
730
  }
731
731
  const validatedSenderAccount = validateAccount(senderAccount);
732
732
  const nonce = await client.getCurrentNonce({ address: validatedSenderAccount.address });
733
+ let estimatedGas;
734
+ try {
735
+ estimatedGas = await client.estimateTransactionGas({
736
+ from: validatedSenderAccount.address,
737
+ to: _optionalChain([client, 'access', _20 => _20.chain, 'access', _21 => _21.consensusMainContract, 'optionalAccess', _22 => _22.address]),
738
+ data: encodedData,
739
+ value
740
+ });
741
+ } catch (error) {
742
+ console.warn("Gas estimation failed, using fallback value:", error);
743
+ estimatedGas = 200000n;
744
+ }
733
745
  const transactionRequest = await client.prepareTransactionRequest({
734
746
  account: validatedSenderAccount,
735
- to: _optionalChain([client, 'access', _20 => _20.chain, 'access', _21 => _21.consensusMainContract, 'optionalAccess', _22 => _22.address]),
747
+ to: _optionalChain([client, 'access', _23 => _23.chain, 'access', _24 => _24.consensusMainContract, 'optionalAccess', _25 => _25.address]),
736
748
  data: encodedData,
737
749
  type: "legacy",
738
750
  nonce: Number(nonce),
739
751
  value,
740
- gas: 21000n
752
+ gas: estimatedGas
741
753
  });
742
- if (_optionalChain([validatedSenderAccount, 'optionalAccess', _23 => _23.type]) !== "local") {
754
+ if (_optionalChain([validatedSenderAccount, 'optionalAccess', _26 => _26.type]) !== "local") {
743
755
  const formattedRequest = {
744
756
  from: transactionRequest.from,
745
757
  to: transactionRequest.to,
@@ -752,7 +764,7 @@ var _sendTransaction = async ({
752
764
  params: [formattedRequest]
753
765
  });
754
766
  }
755
- if (!_optionalChain([validatedSenderAccount, 'optionalAccess', _24 => _24.signTransaction])) {
767
+ if (!_optionalChain([validatedSenderAccount, 'optionalAccess', _27 => _27.signTransaction])) {
756
768
  throw new Error("Account does not support signTransaction");
757
769
  }
758
770
  const serializedTransaction = await validatedSenderAccount.signTransaction(transactionRequest);
@@ -762,7 +774,7 @@ var _sendTransaction = async ({
762
774
  throw new Error("Transaction reverted");
763
775
  }
764
776
  const newTxEvents = _viem.parseEventLogs.call(void 0, {
765
- abi: _optionalChain([client, 'access', _25 => _25.chain, 'access', _26 => _26.consensusMainContract, 'optionalAccess', _27 => _27.abi]),
777
+ abi: _optionalChain([client, 'access', _28 => _28.chain, 'access', _29 => _29.consensusMainContract, 'optionalAccess', _30 => _30.abi]),
766
778
  eventName: "NewTransaction",
767
779
  logs: receipt.logs
768
780
  });
@@ -975,7 +987,7 @@ var simplifyTransactionReceipt = (tx) => {
975
987
  var decodeLocalnetTransaction = (tx) => {
976
988
  if (!tx.data) return tx;
977
989
  try {
978
- const leaderReceipt = _optionalChain([tx, 'access', _28 => _28.consensus_data, 'optionalAccess', _29 => _29.leader_receipt]);
990
+ const leaderReceipt = _optionalChain([tx, 'access', _31 => _31.consensus_data, 'optionalAccess', _32 => _32.leader_receipt]);
979
991
  if (leaderReceipt) {
980
992
  const receipts = Array.isArray(leaderReceipt) ? leaderReceipt : [leaderReceipt];
981
993
  receipts.forEach((receipt) => {
@@ -1006,7 +1018,7 @@ var decodeLocalnetTransaction = (tx) => {
1006
1018
  }
1007
1019
  });
1008
1020
  }
1009
- if (_optionalChain([tx, 'access', _30 => _30.data, 'optionalAccess', _31 => _31.calldata]) && typeof tx.data.calldata === "string") {
1021
+ if (_optionalChain([tx, 'access', _33 => _33.data, 'optionalAccess', _34 => _34.calldata]) && typeof tx.data.calldata === "string") {
1010
1022
  tx.data.calldata = {
1011
1023
  base64: tx.data.calldata,
1012
1024
  ...calldataToUserFriendlyJson(b64ToArray(tx.data.calldata))
@@ -1069,8 +1081,8 @@ var transactionActions = (client, publicClient) => ({
1069
1081
  return decodeLocalnetTransaction(transaction2);
1070
1082
  }
1071
1083
  const transaction = await publicClient.readContract({
1072
- address: _optionalChain([client, 'access', _32 => _32.chain, 'access', _33 => _33.consensusDataContract, 'optionalAccess', _34 => _34.address]),
1073
- abi: _optionalChain([client, 'access', _35 => _35.chain, 'access', _36 => _36.consensusDataContract, 'optionalAccess', _37 => _37.abi]),
1084
+ address: _optionalChain([client, 'access', _35 => _35.chain, 'access', _36 => _36.consensusDataContract, 'optionalAccess', _37 => _37.address]),
1085
+ abi: _optionalChain([client, 'access', _38 => _38.chain, 'access', _39 => _39.consensusDataContract, 'optionalAccess', _40 => _40.abi]),
1074
1086
  functionName: "getTransactionData",
1075
1087
  args: [
1076
1088
  hash,
@@ -1079,6 +1091,19 @@ var transactionActions = (client, publicClient) => ({
1079
1091
  ]
1080
1092
  });
1081
1093
  return decodeTransaction(transaction);
1094
+ },
1095
+ estimateTransactionGas: async (transactionParams) => {
1096
+ const formattedParams = {
1097
+ from: transactionParams.from || _optionalChain([client, 'access', _41 => _41.account, 'optionalAccess', _42 => _42.address]),
1098
+ to: transactionParams.to,
1099
+ data: transactionParams.data || "0x",
1100
+ value: transactionParams.value ? `0x${transactionParams.value.toString(16)}` : "0x0"
1101
+ };
1102
+ const gasHex = await client.request({
1103
+ method: "eth_estimateGas",
1104
+ params: [formattedParams]
1105
+ });
1106
+ return BigInt(gasHex);
1082
1107
  }
1083
1108
  });
1084
1109
 
@@ -1111,7 +1136,7 @@ var connect = async (client, network = "studionet", snapSource = "npm") => {
1111
1136
  chainName: selectedNetwork.name,
1112
1137
  rpcUrls: selectedNetwork.rpcUrls.default.http,
1113
1138
  nativeCurrency: selectedNetwork.nativeCurrency,
1114
- blockExplorerUrls: [_optionalChain([selectedNetwork, 'access', _38 => _38.blockExplorers, 'optionalAccess', _39 => _39.default, 'access', _40 => _40.url])]
1139
+ blockExplorerUrls: [_optionalChain([selectedNetwork, 'access', _43 => _43.blockExplorers, 'optionalAccess', _44 => _44.default, 'access', _45 => _45.url])]
1115
1140
  };
1116
1141
  const currentChainId = await window.ethereum.request({ method: "eth_chainId" });
1117
1142
  if (currentChainId !== chainIdHex) {
@@ -1145,10 +1170,10 @@ var metamaskClient = async (snapSource = "npm") => {
1145
1170
  }
1146
1171
  const isFlask = async () => {
1147
1172
  try {
1148
- const clientVersion = await _optionalChain([window, 'access', _41 => _41.ethereum, 'optionalAccess', _42 => _42.request, 'call', _43 => _43({
1173
+ const clientVersion = await _optionalChain([window, 'access', _46 => _46.ethereum, 'optionalAccess', _47 => _47.request, 'call', _48 => _48({
1149
1174
  method: "web3_clientVersion"
1150
1175
  })]);
1151
- return _optionalChain([clientVersion, 'optionalAccess', _44 => _44.includes, 'call', _45 => _45("flask")]);
1176
+ return _optionalChain([clientVersion, 'optionalAccess', _49 => _49.includes, 'call', _50 => _50("flask")]);
1152
1177
  } catch (error) {
1153
1178
  console.error("Error detecting Flask:", error);
1154
1179
  return false;
@@ -1156,7 +1181,7 @@ var metamaskClient = async (snapSource = "npm") => {
1156
1181
  };
1157
1182
  const installedSnaps = async () => {
1158
1183
  try {
1159
- return await _optionalChain([window, 'access', _46 => _46.ethereum, 'optionalAccess', _47 => _47.request, 'call', _48 => _48({
1184
+ return await _optionalChain([window, 'access', _51 => _51.ethereum, 'optionalAccess', _52 => _52.request, 'call', _53 => _53({
1160
1185
  method: "wallet_getSnaps"
1161
1186
  })]);
1162
1187
  } catch (error) {
@@ -1191,10 +1216,10 @@ function walletActions(client) {
1191
1216
  function chainActions(client) {
1192
1217
  return {
1193
1218
  initializeConsensusSmartContract: async (forceReset = false) => {
1194
- if (_optionalChain([client, 'access', _49 => _49.chain, 'optionalAccess', _50 => _50.id]) === _chunkZKBMABRAcjs.testnetAsimov.id) {
1219
+ if (_optionalChain([client, 'access', _54 => _54.chain, 'optionalAccess', _55 => _55.id]) === _chunkZKBMABRAcjs.testnetAsimov.id) {
1195
1220
  return;
1196
1221
  }
1197
- if (!forceReset && _optionalChain([client, 'access', _51 => _51.chain, 'access', _52 => _52.consensusMainContract, 'optionalAccess', _53 => _53.address]) && _optionalChain([client, 'access', _54 => _54.chain, 'access', _55 => _55.consensusMainContract, 'optionalAccess', _56 => _56.abi])) {
1222
+ if (!forceReset && _optionalChain([client, 'access', _56 => _56.chain, 'access', _57 => _57.consensusMainContract, 'optionalAccess', _58 => _58.address]) && _optionalChain([client, 'access', _59 => _59.chain, 'access', _60 => _60.consensusMainContract, 'optionalAccess', _61 => _61.abi])) {
1198
1223
  return;
1199
1224
  }
1200
1225
  const contractsResponse = await fetch(client.chain.rpcUrls.default.http[0], {
@@ -1279,12 +1304,15 @@ var createClient = (config = { chain: _chunkZKBMABRAcjs.localnet }) => {
1279
1304
  ...config.account ? { account: config.account } : {}
1280
1305
  });
1281
1306
  const clientWithBasicActions = baseClient.extend(_viem.publicActions).extend(_viem.walletActions).extend((client) => accountActions(client));
1282
- const clientWithAllActions = {
1307
+ const clientWithTransactionActions = {
1283
1308
  ...clientWithBasicActions,
1284
- ...contractActions(clientWithBasicActions, publicClient),
1309
+ ...transactionActions(clientWithBasicActions, publicClient),
1285
1310
  ...chainActions(clientWithBasicActions),
1286
- ...walletActions(clientWithBasicActions),
1287
- ...transactionActions(clientWithBasicActions, publicClient)
1311
+ ...walletActions(clientWithBasicActions)
1312
+ };
1313
+ const clientWithAllActions = {
1314
+ ...clientWithTransactionActions,
1315
+ ...contractActions(clientWithTransactionActions, publicClient)
1288
1316
  };
1289
1317
  const finalClient = {
1290
1318
  ...clientWithAllActions,
package/dist/index.d.cts CHANGED
@@ -1,7 +1,7 @@
1
1
  import * as viem from 'viem';
2
2
  import { Account, Address, Hex } from 'viem';
3
3
  import { G as GenLayerChain } from './chains-BYSCF33g.cjs';
4
- import { G as GenLayerClient, D as DecodedDeployData, a as DecodedCallData, b as GenLayerRawTransaction, c as GenLayerTransaction, C as CalldataEncodable, T as TransactionDataElement } from './index-CxNl4CK5.cjs';
4
+ import { G as GenLayerClient, D as DecodedDeployData, a as DecodedCallData, b as GenLayerRawTransaction, c as GenLayerTransaction, C as CalldataEncodable, T as TransactionDataElement } from './index-C_GfhvDJ.cjs';
5
5
  import * as abitype from 'abitype';
6
6
  import * as viem__types_types_authorization from 'viem/_types/types/authorization';
7
7
  import * as viem_accounts from 'viem/accounts';
package/dist/index.d.ts CHANGED
@@ -1,7 +1,7 @@
1
1
  import * as viem from 'viem';
2
2
  import { Account, Address, Hex } from 'viem';
3
3
  import { G as GenLayerChain } from './chains-BYSCF33g.js';
4
- import { G as GenLayerClient, D as DecodedDeployData, a as DecodedCallData, b as GenLayerRawTransaction, c as GenLayerTransaction, C as CalldataEncodable, T as TransactionDataElement } from './index-BnFbqUhu.js';
4
+ import { G as GenLayerClient, D as DecodedDeployData, a as DecodedCallData, b as GenLayerRawTransaction, c as GenLayerTransaction, C as CalldataEncodable, T as TransactionDataElement } from './index-BJebZa37.js';
5
5
  import * as abitype from 'abitype';
6
6
  import * as viem__types_types_authorization from 'viem/_types/types/authorization';
7
7
  import * as viem_accounts from 'viem/accounts';
package/dist/index.js CHANGED
@@ -730,6 +730,18 @@ var _sendTransaction = async ({
730
730
  }
731
731
  const validatedSenderAccount = validateAccount(senderAccount);
732
732
  const nonce = await client.getCurrentNonce({ address: validatedSenderAccount.address });
733
+ let estimatedGas;
734
+ try {
735
+ estimatedGas = await client.estimateTransactionGas({
736
+ from: validatedSenderAccount.address,
737
+ to: client.chain.consensusMainContract?.address,
738
+ data: encodedData,
739
+ value
740
+ });
741
+ } catch (error) {
742
+ console.warn("Gas estimation failed, using fallback value:", error);
743
+ estimatedGas = 200000n;
744
+ }
733
745
  const transactionRequest = await client.prepareTransactionRequest({
734
746
  account: validatedSenderAccount,
735
747
  to: client.chain.consensusMainContract?.address,
@@ -737,7 +749,7 @@ var _sendTransaction = async ({
737
749
  type: "legacy",
738
750
  nonce: Number(nonce),
739
751
  value,
740
- gas: 21000n
752
+ gas: estimatedGas
741
753
  });
742
754
  if (validatedSenderAccount?.type !== "local") {
743
755
  const formattedRequest = {
@@ -1079,6 +1091,19 @@ var transactionActions = (client, publicClient) => ({
1079
1091
  ]
1080
1092
  });
1081
1093
  return decodeTransaction(transaction);
1094
+ },
1095
+ estimateTransactionGas: async (transactionParams) => {
1096
+ const formattedParams = {
1097
+ from: transactionParams.from || client.account?.address,
1098
+ to: transactionParams.to,
1099
+ data: transactionParams.data || "0x",
1100
+ value: transactionParams.value ? `0x${transactionParams.value.toString(16)}` : "0x0"
1101
+ };
1102
+ const gasHex = await client.request({
1103
+ method: "eth_estimateGas",
1104
+ params: [formattedParams]
1105
+ });
1106
+ return BigInt(gasHex);
1082
1107
  }
1083
1108
  });
1084
1109
 
@@ -1279,12 +1304,15 @@ var createClient = (config = { chain: localnet }) => {
1279
1304
  ...config.account ? { account: config.account } : {}
1280
1305
  });
1281
1306
  const clientWithBasicActions = baseClient.extend(publicActions).extend(walletActions2).extend((client) => accountActions(client));
1282
- const clientWithAllActions = {
1307
+ const clientWithTransactionActions = {
1283
1308
  ...clientWithBasicActions,
1284
- ...contractActions(clientWithBasicActions, publicClient),
1309
+ ...transactionActions(clientWithBasicActions, publicClient),
1285
1310
  ...chainActions(clientWithBasicActions),
1286
- ...walletActions(clientWithBasicActions),
1287
- ...transactionActions(clientWithBasicActions, publicClient)
1311
+ ...walletActions(clientWithBasicActions)
1312
+ };
1313
+ const clientWithAllActions = {
1314
+ ...clientWithTransactionActions,
1315
+ ...contractActions(clientWithTransactionActions, publicClient)
1288
1316
  };
1289
1317
  const finalClient = {
1290
1318
  ...clientWithAllActions,
@@ -1,3 +1,3 @@
1
1
  export { Account, Address } from 'viem';
2
- export { d as CalldataAddress, C as CalldataEncodable, i as ContractMethod, h as ContractMethodBase, f as ContractParamsArraySchemaElement, g as ContractParamsSchema, j as ContractSchema, a as DecodedCallData, D as DecodedDeployData, G as GenLayerClient, e as GenLayerMethod, b as GenLayerRawTransaction, c as GenLayerTransaction, H as Hash, M as MethodDescription, N as Network, S as SnapSource, k as TransactionHash, s as TransactionHashVariant, m as TransactionResult, p as TransactionResultNameToNumber, l as TransactionStatus, r as TransactionType, V as VoteType, o as transactionResultNumberToName, n as transactionsStatusNameToNumber, t as transactionsStatusNumberToName, q as voteTypeNameToNumber, v as voteTypeNumberToName } from '../index-CxNl4CK5.cjs';
2
+ export { d as CalldataAddress, C as CalldataEncodable, i as ContractMethod, h as ContractMethodBase, f as ContractParamsArraySchemaElement, g as ContractParamsSchema, j as ContractSchema, a as DecodedCallData, D as DecodedDeployData, G as GenLayerClient, e as GenLayerMethod, b as GenLayerRawTransaction, c as GenLayerTransaction, H as Hash, M as MethodDescription, N as Network, S as SnapSource, k as TransactionHash, s as TransactionHashVariant, m as TransactionResult, p as TransactionResultNameToNumber, l as TransactionStatus, r as TransactionType, V as VoteType, o as transactionResultNumberToName, n as transactionsStatusNameToNumber, t as transactionsStatusNumberToName, q as voteTypeNameToNumber, v as voteTypeNumberToName } from '../index-C_GfhvDJ.cjs';
3
3
  export { G as GenLayerChain } from '../chains-BYSCF33g.cjs';
@@ -1,3 +1,3 @@
1
1
  export { Account, Address } from 'viem';
2
- export { d as CalldataAddress, C as CalldataEncodable, i as ContractMethod, h as ContractMethodBase, f as ContractParamsArraySchemaElement, g as ContractParamsSchema, j as ContractSchema, a as DecodedCallData, D as DecodedDeployData, G as GenLayerClient, e as GenLayerMethod, b as GenLayerRawTransaction, c as GenLayerTransaction, H as Hash, M as MethodDescription, N as Network, S as SnapSource, k as TransactionHash, s as TransactionHashVariant, m as TransactionResult, p as TransactionResultNameToNumber, l as TransactionStatus, r as TransactionType, V as VoteType, o as transactionResultNumberToName, n as transactionsStatusNameToNumber, t as transactionsStatusNumberToName, q as voteTypeNameToNumber, v as voteTypeNumberToName } from '../index-BnFbqUhu.js';
2
+ export { d as CalldataAddress, C as CalldataEncodable, i as ContractMethod, h as ContractMethodBase, f as ContractParamsArraySchemaElement, g as ContractParamsSchema, j as ContractSchema, a as DecodedCallData, D as DecodedDeployData, G as GenLayerClient, e as GenLayerMethod, b as GenLayerRawTransaction, c as GenLayerTransaction, H as Hash, M as MethodDescription, N as Network, S as SnapSource, k as TransactionHash, s as TransactionHashVariant, m as TransactionResult, p as TransactionResultNameToNumber, l as TransactionStatus, r as TransactionType, V as VoteType, o as transactionResultNumberToName, n as transactionsStatusNameToNumber, t as transactionsStatusNumberToName, q as voteTypeNameToNumber, v as voteTypeNumberToName } from '../index-BJebZa37.js';
3
3
  export { G as GenLayerChain } from '../chains-BYSCF33g.js';
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "genlayer-js",
3
3
  "type": "module",
4
- "version": "0.18.0",
4
+ "version": "0.18.1",
5
5
  "description": "GenLayer JavaScript SDK",
6
6
  "main": "dist/index.js",
7
7
  "types": "dist/index.d.ts",
@@ -106,13 +106,18 @@ export const createClient = (config: ClientConfig = {chain: localnet}): GenLayer
106
106
  .extend(walletActions)
107
107
  .extend(client => accountActions(client as unknown as GenLayerClient<GenLayerChain>));
108
108
 
109
- // Create a client with all actions except transaction actions
110
- const clientWithAllActions = {
109
+ // First add transaction actions, then contract actions that depend on them
110
+ const clientWithTransactionActions = {
111
111
  ...clientWithBasicActions,
112
- ...contractActions(clientWithBasicActions as unknown as GenLayerClient<GenLayerChain>, publicClient),
112
+ ...transactionActions(clientWithBasicActions as unknown as GenLayerClient<GenLayerChain>, publicClient),
113
113
  ...chainActions(clientWithBasicActions as unknown as GenLayerClient<GenLayerChain>),
114
114
  ...genlayerWalletActions(clientWithBasicActions as unknown as GenLayerClient<GenLayerChain>),
115
- ...transactionActions(clientWithBasicActions as unknown as GenLayerClient<GenLayerChain>, publicClient),
115
+ } as unknown as GenLayerClient<GenLayerChain>;
116
+
117
+ // Then add contract actions that can now access transaction actions
118
+ const clientWithAllActions = {
119
+ ...clientWithTransactionActions,
120
+ ...contractActions(clientWithTransactionActions as unknown as GenLayerClient<GenLayerChain>, publicClient),
116
121
  } as unknown as GenLayerClient<GenLayerChain>;
117
122
 
118
123
  // Add transaction actions last, after all other actions are in place
@@ -303,6 +303,18 @@ const _sendTransaction = async ({
303
303
  const validatedSenderAccount = validateAccount(senderAccount);
304
304
 
305
305
  const nonce = await client.getCurrentNonce({address: validatedSenderAccount.address});
306
+ let estimatedGas: bigint;
307
+ try {
308
+ estimatedGas = await client.estimateTransactionGas({
309
+ from: validatedSenderAccount.address,
310
+ to: client.chain.consensusMainContract?.address as Address,
311
+ data: encodedData,
312
+ value: value,
313
+ });
314
+ } catch (error) {
315
+ console.warn("Gas estimation failed, using fallback value:", error);
316
+ estimatedGas = 200_000n;
317
+ }
306
318
  const transactionRequest = await client.prepareTransactionRequest({
307
319
  account: validatedSenderAccount,
308
320
  to: client.chain.consensusMainContract?.address as Address,
@@ -310,7 +322,7 @@ const _sendTransaction = async ({
310
322
  type: "legacy",
311
323
  nonce: Number(nonce),
312
324
  value: value,
313
- gas: 21000n,
325
+ gas: estimatedGas,
314
326
  });
315
327
 
316
328
  if (validatedSenderAccount?.type !== "local") {
@@ -90,6 +90,26 @@ export const transactionActions = (client: GenLayerClient<GenLayerChain>, public
90
90
  })) as unknown as GenLayerRawTransaction;
91
91
  return decodeTransaction(transaction);
92
92
  },
93
+ estimateTransactionGas: async (transactionParams: {
94
+ from?: Address;
95
+ to: Address;
96
+ data?: `0x${string}`;
97
+ value?: bigint;
98
+ }): Promise<bigint> => {
99
+ const formattedParams = {
100
+ from: transactionParams.from || client.account?.address,
101
+ to: transactionParams.to,
102
+ data: transactionParams.data || "0x",
103
+ value: transactionParams.value ? `0x${transactionParams.value.toString(16)}` as `0x${string}` : "0x0" as `0x${string}`,
104
+ };
105
+
106
+ const gasHex = await client.request({
107
+ method: "eth_estimateGas",
108
+ params: [formattedParams],
109
+ }) as string;
110
+
111
+ return BigInt(gasHex);
112
+ },
93
113
  });
94
114
 
95
115
 
@@ -1,5 +1,4 @@
1
- import {GenLayerTransaction, GenLayerRawTransaction, DecodedCallData, DecodedDeployData} from "../types/transactions";
2
- import {transactionsStatusNumberToName, transactionResultNumberToName, voteTypeNumberToName, VoteType} from "../types/transactions";
1
+ import {GenLayerTransaction, GenLayerRawTransaction, DecodedCallData, DecodedDeployData,transactionsStatusNumberToName, transactionResultNumberToName, voteTypeNumberToName, VoteType} from "../types/transactions";
3
2
  import {b64ToArray, calldataToUserFriendlyJson, resultToUserFriendlyJson} from "../utils/jsonifier";
4
3
  import {fromRlp, fromHex, Hex, Address} from "viem";
5
4
  import * as calldataAbi from "../abi/calldata";
@@ -18,6 +18,7 @@ export type GenLayerMethod =
18
18
  | {method: "gen_getContractCode"; params: [address: Address]}
19
19
  | {method: "sim_getTransactionsForAddress"; params: [address: Address, filter?: "all" | "from" | "to"]}
20
20
  | {method: "eth_getTransactionCount"; params: [address: Address, block: string]}
21
+ | {method: "eth_estimateGas"; params: [transactionParams: any]}
21
22
  | {method: "gen_call"; params: [requestParams: any]};
22
23
 
23
24
  /*
@@ -80,6 +81,12 @@ export type GenLayerClient<TGenLayerChain extends GenLayerChain> = Omit<
80
81
  }) => Promise<`0x${string}`>;
81
82
  getTransaction: (args: {hash: TransactionHash}) => Promise<GenLayerTransaction>;
82
83
  getCurrentNonce: (args: {address: Address}) => Promise<number>;
84
+ estimateTransactionGas: (transactionParams: {
85
+ from?: Address;
86
+ to: Address;
87
+ data?: `0x${string}`;
88
+ value?: bigint;
89
+ }) => Promise<bigint>;
83
90
  waitForTransactionReceipt: (args: {
84
91
  hash: TransactionHash;
85
92
  status?: TransactionStatus;