genlayer-js 0.15.1 → 0.17.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,19 @@
1
1
 
2
2
 
3
+ ## 0.17.0 (2025-09-03)
4
+
5
+
6
+ ### Features
7
+
8
+ * allow gen_call write through `simulateWriteContract` ([#112](https://github.com/genlayerlabs/genlayer-js/issues/112)) ([734c0e6](https://github.com/genlayerlabs/genlayer-js/commit/734c0e61d9ddd13678f424ca6bd754ad1f4df3bb))
9
+
10
+ ## 0.16.0 (2025-09-03)
11
+
12
+
13
+ ### Features
14
+
15
+ * **contracts,types:** add getContractCode via gen_getContractCode RPC ([#109](https://github.com/genlayerlabs/genlayer-js/issues/109)) ([3fcc934](https://github.com/genlayerlabs/genlayer-js/commit/3fcc934a73b312747d53831f63d8c2e903534b3f))
16
+
3
17
  ## 0.15.1 (2025-09-02)
4
18
 
5
19
 
@@ -304,6 +304,9 @@ type GenLayerMethod = {
304
304
  } | {
305
305
  method: "gen_getContractSchemaForCode";
306
306
  params: [contractCode: string];
307
+ } | {
308
+ method: "gen_getContractCode";
309
+ params: [address: Address];
307
310
  } | {
308
311
  method: "sim_getTransactionsForAddress";
309
312
  params: [address: Address, filter?: "all" | "from" | "to"];
@@ -343,6 +346,18 @@ type GenLayerClient<TGenLayerChain extends GenLayerChain> = Omit<Client<Transpor
343
346
  leaderOnly?: boolean;
344
347
  consensusMaxRotations?: number;
345
348
  }) => Promise<any>;
349
+ simulateWriteContract: <RawReturn extends boolean | undefined>(args: {
350
+ account?: Account;
351
+ address: Address;
352
+ functionName: string;
353
+ args?: CalldataEncodable[];
354
+ kwargs?: Map<string, CalldataEncodable> | {
355
+ [key: string]: CalldataEncodable;
356
+ };
357
+ rawReturn?: RawReturn;
358
+ leaderOnly?: boolean;
359
+ transactionHashVariant?: TransactionHashVariant;
360
+ }) => Promise<RawReturn extends true ? `0x${string}` : CalldataEncodable>;
346
361
  deployContract: (args: {
347
362
  account?: Account;
348
363
  code: string | Uint8Array;
@@ -367,6 +382,7 @@ type GenLayerClient<TGenLayerChain extends GenLayerChain> = Omit<Client<Transpor
367
382
  }) => Promise<GenLayerTransaction>;
368
383
  getContractSchema: (address: Address) => Promise<ContractSchema>;
369
384
  getContractSchemaForCode: (contractCode: string | Uint8Array) => Promise<ContractSchema>;
385
+ getContractCode: (address: Address) => Promise<string>;
370
386
  initializeConsensusSmartContract: (forceReset?: boolean) => Promise<void>;
371
387
  connect: (network?: Network, snapSource?: SnapSource) => Promise<void>;
372
388
  metamaskClient: (snapSource?: SnapSource) => Promise<MetaMaskClientResult>;
@@ -304,6 +304,9 @@ type GenLayerMethod = {
304
304
  } | {
305
305
  method: "gen_getContractSchemaForCode";
306
306
  params: [contractCode: string];
307
+ } | {
308
+ method: "gen_getContractCode";
309
+ params: [address: Address];
307
310
  } | {
308
311
  method: "sim_getTransactionsForAddress";
309
312
  params: [address: Address, filter?: "all" | "from" | "to"];
@@ -343,6 +346,18 @@ type GenLayerClient<TGenLayerChain extends GenLayerChain> = Omit<Client<Transpor
343
346
  leaderOnly?: boolean;
344
347
  consensusMaxRotations?: number;
345
348
  }) => Promise<any>;
349
+ simulateWriteContract: <RawReturn extends boolean | undefined>(args: {
350
+ account?: Account;
351
+ address: Address;
352
+ functionName: string;
353
+ args?: CalldataEncodable[];
354
+ kwargs?: Map<string, CalldataEncodable> | {
355
+ [key: string]: CalldataEncodable;
356
+ };
357
+ rawReturn?: RawReturn;
358
+ leaderOnly?: boolean;
359
+ transactionHashVariant?: TransactionHashVariant;
360
+ }) => Promise<RawReturn extends true ? `0x${string}` : CalldataEncodable>;
346
361
  deployContract: (args: {
347
362
  account?: Account;
348
363
  code: string | Uint8Array;
@@ -367,6 +382,7 @@ type GenLayerClient<TGenLayerChain extends GenLayerChain> = Omit<Client<Transpor
367
382
  }) => Promise<GenLayerTransaction>;
368
383
  getContractSchema: (address: Address) => Promise<ContractSchema>;
369
384
  getContractSchemaForCode: (contractCode: string | Uint8Array) => Promise<ContractSchema>;
385
+ getContractCode: (address: Address) => Promise<string>;
370
386
  initializeConsensusSmartContract: (forceReset?: boolean) => Promise<void>;
371
387
  connect: (network?: Network, snapSource?: SnapSource) => Promise<void>;
372
388
  metamaskClient: (snapSource?: SnapSource) => Promise<MetaMaskClientResult>;
package/dist/index.cjs CHANGED
@@ -408,8 +408,70 @@ function serialize(data) {
408
408
 
409
409
  // src/contracts/actions.ts
410
410
 
411
+
412
+ // src/abi/index.ts
413
+ var abi_exports = {};
414
+ _chunk75ZPJI57cjs.__export.call(void 0, abi_exports, {
415
+ calldata: () => calldata,
416
+ transactions: () => transactions
417
+ });
418
+ var calldata = calldata_exports;
419
+ var transactions = transactions_exports;
420
+
421
+ // src/utils/jsonifier.ts
422
+ function b64ToArray(b64) {
423
+ return Uint8Array.from(atob(b64), (c) => c.charCodeAt(0));
424
+ }
425
+ function calldataToUserFriendlyJson(cd) {
426
+ return {
427
+ raw: Array.from(cd),
428
+ readable: calldata.toString(calldata.decode(cd))
429
+ };
430
+ }
431
+ var RESULT_CODES = /* @__PURE__ */ new Map([
432
+ [0, "return"],
433
+ [1, "rollback"],
434
+ [2, "contract_error"],
435
+ [3, "error"],
436
+ [4, "none"],
437
+ [5, "no_leaders"]
438
+ ]);
439
+ function resultToUserFriendlyJson(cd64) {
440
+ const raw = b64ToArray(cd64);
441
+ const code = RESULT_CODES.get(raw[0]);
442
+ let status;
443
+ let payload = null;
444
+ if (code === void 0) {
445
+ status = "<unknown>";
446
+ } else {
447
+ status = code;
448
+ if ([1, 2].includes(raw[0])) {
449
+ payload = new TextDecoder("utf-8").decode(raw.slice(1));
450
+ } else if (raw[0] == 0) {
451
+ payload = calldataToUserFriendlyJson(raw.slice(1));
452
+ }
453
+ }
454
+ return {
455
+ raw: cd64,
456
+ status,
457
+ payload
458
+ };
459
+ }
460
+
461
+ // src/contracts/actions.ts
411
462
  var contractActions = (client, publicClient) => {
412
463
  return {
464
+ getContractCode: async (address) => {
465
+ if (client.chain.id !== _chunkZKBMABRAcjs.localnet.id) {
466
+ throw new Error("Getting contract code is not supported on this network");
467
+ }
468
+ const result = await client.request({
469
+ method: "gen_getContractCode",
470
+ params: [address]
471
+ });
472
+ const codeBytes = b64ToArray(result);
473
+ return new TextDecoder().decode(codeBytes);
474
+ },
413
475
  getContractSchema: async (address) => {
414
476
  if (client.chain.id !== _chunkZKBMABRAcjs.localnet.id) {
415
477
  throw new Error("Contract schema is not supported on this network");
@@ -461,6 +523,37 @@ var contractActions = (client, publicClient) => {
461
523
  const resultBinary = _viem.fromHex.call(void 0, prefixedResult, "bytes");
462
524
  return decode(resultBinary);
463
525
  },
526
+ simulateWriteContract: async (args) => {
527
+ const {
528
+ account,
529
+ address,
530
+ functionName,
531
+ args: callArgs,
532
+ kwargs,
533
+ leaderOnly = false,
534
+ transactionHashVariant = "latest-nonfinal" /* LATEST_NONFINAL */
535
+ } = args;
536
+ const encodedData = [encode(makeCalldataObject(functionName, callArgs, kwargs)), leaderOnly];
537
+ const serializedData = serialize(encodedData);
538
+ const senderAddress = _nullishCoalesce(_optionalChain([account, 'optionalAccess', _8 => _8.address]), () => ( _optionalChain([client, 'access', _9 => _9.account, 'optionalAccess', _10 => _10.address])));
539
+ const requestParams = {
540
+ type: "write",
541
+ to: address,
542
+ from: senderAddress,
543
+ data: serializedData,
544
+ transaction_hash_variant: transactionHashVariant
545
+ };
546
+ const result = await client.request({
547
+ method: "gen_call",
548
+ params: [requestParams]
549
+ });
550
+ const prefixedResult = `0x${result}`;
551
+ if (args.rawReturn) {
552
+ return prefixedResult;
553
+ }
554
+ const resultBinary = _viem.fromHex.call(void 0, prefixedResult, "bytes");
555
+ return decode(resultBinary);
556
+ },
464
557
  writeContract: async (args) => {
465
558
  const {
466
559
  account,
@@ -550,7 +643,7 @@ var _encodeAddTransactionData = ({
550
643
  }) => {
551
644
  const validatedSenderAccount = validateAccount(senderAccount);
552
645
  return _viem.encodeFunctionData.call(void 0, {
553
- abi: _optionalChain([client, 'access', _8 => _8.chain, 'access', _9 => _9.consensusMainContract, 'optionalAccess', _10 => _10.abi]),
646
+ abi: _optionalChain([client, 'access', _11 => _11.chain, 'access', _12 => _12.consensusMainContract, 'optionalAccess', _13 => _13.abi]),
554
647
  functionName: "addTransaction",
555
648
  args: [
556
649
  validatedSenderAccount.address,
@@ -566,7 +659,7 @@ var _encodeSubmitAppealData = ({
566
659
  txId
567
660
  }) => {
568
661
  return _viem.encodeFunctionData.call(void 0, {
569
- abi: _optionalChain([client, 'access', _11 => _11.chain, 'access', _12 => _12.consensusMainContract, 'optionalAccess', _13 => _13.abi]),
662
+ abi: _optionalChain([client, 'access', _14 => _14.chain, 'access', _15 => _15.consensusMainContract, 'optionalAccess', _16 => _16.abi]),
570
663
  functionName: "submitAppeal",
571
664
  args: [txId]
572
665
  });
@@ -578,21 +671,21 @@ var _sendTransaction = async ({
578
671
  senderAccount,
579
672
  value = 0n
580
673
  }) => {
581
- if (!_optionalChain([client, 'access', _14 => _14.chain, 'access', _15 => _15.consensusMainContract, 'optionalAccess', _16 => _16.address])) {
674
+ if (!_optionalChain([client, 'access', _17 => _17.chain, 'access', _18 => _18.consensusMainContract, 'optionalAccess', _19 => _19.address])) {
582
675
  throw new Error("Consensus main contract not initialized. Please ensure client is properly initialized.");
583
676
  }
584
677
  const validatedSenderAccount = validateAccount(senderAccount);
585
678
  const nonce = await client.getCurrentNonce({ address: validatedSenderAccount.address });
586
679
  const transactionRequest = await client.prepareTransactionRequest({
587
680
  account: validatedSenderAccount,
588
- to: _optionalChain([client, 'access', _17 => _17.chain, 'access', _18 => _18.consensusMainContract, 'optionalAccess', _19 => _19.address]),
681
+ to: _optionalChain([client, 'access', _20 => _20.chain, 'access', _21 => _21.consensusMainContract, 'optionalAccess', _22 => _22.address]),
589
682
  data: encodedData,
590
683
  type: "legacy",
591
684
  nonce: Number(nonce),
592
685
  value,
593
686
  gas: 21000n
594
687
  });
595
- if (_optionalChain([validatedSenderAccount, 'optionalAccess', _20 => _20.type]) !== "local") {
688
+ if (_optionalChain([validatedSenderAccount, 'optionalAccess', _23 => _23.type]) !== "local") {
596
689
  const formattedRequest = {
597
690
  from: transactionRequest.from,
598
691
  to: transactionRequest.to,
@@ -605,7 +698,7 @@ var _sendTransaction = async ({
605
698
  params: [formattedRequest]
606
699
  });
607
700
  }
608
- if (!_optionalChain([validatedSenderAccount, 'optionalAccess', _21 => _21.signTransaction])) {
701
+ if (!_optionalChain([validatedSenderAccount, 'optionalAccess', _24 => _24.signTransaction])) {
609
702
  throw new Error("Account does not support signTransaction");
610
703
  }
611
704
  const serializedTransaction = await validatedSenderAccount.signTransaction(transactionRequest);
@@ -615,7 +708,7 @@ var _sendTransaction = async ({
615
708
  throw new Error("Transaction reverted");
616
709
  }
617
710
  const newTxEvents = _viem.parseEventLogs.call(void 0, {
618
- abi: _optionalChain([client, 'access', _22 => _22.chain, 'access', _23 => _23.consensusMainContract, 'optionalAccess', _24 => _24.abi]),
711
+ abi: _optionalChain([client, 'access', _25 => _25.chain, 'access', _26 => _26.consensusMainContract, 'optionalAccess', _27 => _27.abi]),
619
712
  eventName: "NewTransaction",
620
713
  logs: receipt.logs
621
714
  });
@@ -636,55 +729,6 @@ async function sleep(ms) {
636
729
  return new Promise((resolve) => setTimeout(resolve, ms));
637
730
  }
638
731
 
639
- // src/abi/index.ts
640
- var abi_exports = {};
641
- _chunk75ZPJI57cjs.__export.call(void 0, abi_exports, {
642
- calldata: () => calldata,
643
- transactions: () => transactions
644
- });
645
- var calldata = calldata_exports;
646
- var transactions = transactions_exports;
647
-
648
- // src/utils/jsonifier.ts
649
- function b64ToArray(b64) {
650
- return Uint8Array.from(atob(b64), (c) => c.charCodeAt(0));
651
- }
652
- function calldataToUserFriendlyJson(cd) {
653
- return {
654
- raw: Array.from(cd),
655
- readable: calldata.toString(calldata.decode(cd))
656
- };
657
- }
658
- var RESULT_CODES = /* @__PURE__ */ new Map([
659
- [0, "return"],
660
- [1, "rollback"],
661
- [2, "contract_error"],
662
- [3, "error"],
663
- [4, "none"],
664
- [5, "no_leaders"]
665
- ]);
666
- function resultToUserFriendlyJson(cd64) {
667
- const raw = b64ToArray(cd64);
668
- const code = RESULT_CODES.get(raw[0]);
669
- let status;
670
- let payload = null;
671
- if (code === void 0) {
672
- status = "<unknown>";
673
- } else {
674
- status = code;
675
- if ([1, 2].includes(raw[0])) {
676
- payload = new TextDecoder("utf-8").decode(raw.slice(1));
677
- } else if (raw[0] == 0) {
678
- payload = calldataToUserFriendlyJson(raw.slice(1));
679
- }
680
- }
681
- return {
682
- raw: cd64,
683
- status,
684
- payload
685
- };
686
- }
687
-
688
732
  // src/transactions/decoders.ts
689
733
 
690
734
  var FIELDS_TO_REMOVE = [
@@ -877,7 +921,7 @@ var simplifyTransactionReceipt = (tx) => {
877
921
  var decodeLocalnetTransaction = (tx) => {
878
922
  if (!tx.data) return tx;
879
923
  try {
880
- const leaderReceipt = _optionalChain([tx, 'access', _25 => _25.consensus_data, 'optionalAccess', _26 => _26.leader_receipt]);
924
+ const leaderReceipt = _optionalChain([tx, 'access', _28 => _28.consensus_data, 'optionalAccess', _29 => _29.leader_receipt]);
881
925
  if (leaderReceipt) {
882
926
  const receipts = Array.isArray(leaderReceipt) ? leaderReceipt : [leaderReceipt];
883
927
  receipts.forEach((receipt) => {
@@ -908,7 +952,7 @@ var decodeLocalnetTransaction = (tx) => {
908
952
  }
909
953
  });
910
954
  }
911
- if (_optionalChain([tx, 'access', _27 => _27.data, 'optionalAccess', _28 => _28.calldata]) && typeof tx.data.calldata === "string") {
955
+ if (_optionalChain([tx, 'access', _30 => _30.data, 'optionalAccess', _31 => _31.calldata]) && typeof tx.data.calldata === "string") {
912
956
  tx.data.calldata = {
913
957
  base64: tx.data.calldata,
914
958
  ...calldataToUserFriendlyJson(b64ToArray(tx.data.calldata))
@@ -971,8 +1015,8 @@ var transactionActions = (client, publicClient) => ({
971
1015
  return decodeLocalnetTransaction(transaction2);
972
1016
  }
973
1017
  const transaction = await publicClient.readContract({
974
- address: _optionalChain([client, 'access', _29 => _29.chain, 'access', _30 => _30.consensusDataContract, 'optionalAccess', _31 => _31.address]),
975
- abi: _optionalChain([client, 'access', _32 => _32.chain, 'access', _33 => _33.consensusDataContract, 'optionalAccess', _34 => _34.abi]),
1018
+ address: _optionalChain([client, 'access', _32 => _32.chain, 'access', _33 => _33.consensusDataContract, 'optionalAccess', _34 => _34.address]),
1019
+ abi: _optionalChain([client, 'access', _35 => _35.chain, 'access', _36 => _36.consensusDataContract, 'optionalAccess', _37 => _37.abi]),
976
1020
  functionName: "getTransactionData",
977
1021
  args: [
978
1022
  hash,
@@ -1013,7 +1057,7 @@ var connect = async (client, network = "studionet", snapSource = "npm") => {
1013
1057
  chainName: selectedNetwork.name,
1014
1058
  rpcUrls: selectedNetwork.rpcUrls.default.http,
1015
1059
  nativeCurrency: selectedNetwork.nativeCurrency,
1016
- blockExplorerUrls: [_optionalChain([selectedNetwork, 'access', _35 => _35.blockExplorers, 'optionalAccess', _36 => _36.default, 'access', _37 => _37.url])]
1060
+ blockExplorerUrls: [_optionalChain([selectedNetwork, 'access', _38 => _38.blockExplorers, 'optionalAccess', _39 => _39.default, 'access', _40 => _40.url])]
1017
1061
  };
1018
1062
  const currentChainId = await window.ethereum.request({ method: "eth_chainId" });
1019
1063
  if (currentChainId !== chainIdHex) {
@@ -1047,10 +1091,10 @@ var metamaskClient = async (snapSource = "npm") => {
1047
1091
  }
1048
1092
  const isFlask = async () => {
1049
1093
  try {
1050
- const clientVersion = await _optionalChain([window, 'access', _38 => _38.ethereum, 'optionalAccess', _39 => _39.request, 'call', _40 => _40({
1094
+ const clientVersion = await _optionalChain([window, 'access', _41 => _41.ethereum, 'optionalAccess', _42 => _42.request, 'call', _43 => _43({
1051
1095
  method: "web3_clientVersion"
1052
1096
  })]);
1053
- return _optionalChain([clientVersion, 'optionalAccess', _41 => _41.includes, 'call', _42 => _42("flask")]);
1097
+ return _optionalChain([clientVersion, 'optionalAccess', _44 => _44.includes, 'call', _45 => _45("flask")]);
1054
1098
  } catch (error) {
1055
1099
  console.error("Error detecting Flask:", error);
1056
1100
  return false;
@@ -1058,7 +1102,7 @@ var metamaskClient = async (snapSource = "npm") => {
1058
1102
  };
1059
1103
  const installedSnaps = async () => {
1060
1104
  try {
1061
- return await _optionalChain([window, 'access', _43 => _43.ethereum, 'optionalAccess', _44 => _44.request, 'call', _45 => _45({
1105
+ return await _optionalChain([window, 'access', _46 => _46.ethereum, 'optionalAccess', _47 => _47.request, 'call', _48 => _48({
1062
1106
  method: "wallet_getSnaps"
1063
1107
  })]);
1064
1108
  } catch (error) {
@@ -1093,10 +1137,10 @@ function walletActions(client) {
1093
1137
  function chainActions(client) {
1094
1138
  return {
1095
1139
  initializeConsensusSmartContract: async (forceReset = false) => {
1096
- if (_optionalChain([client, 'access', _46 => _46.chain, 'optionalAccess', _47 => _47.id]) === _chunkZKBMABRAcjs.testnetAsimov.id) {
1140
+ if (_optionalChain([client, 'access', _49 => _49.chain, 'optionalAccess', _50 => _50.id]) === _chunkZKBMABRAcjs.testnetAsimov.id) {
1097
1141
  return;
1098
1142
  }
1099
- if (!forceReset && _optionalChain([client, 'access', _48 => _48.chain, 'access', _49 => _49.consensusMainContract, 'optionalAccess', _50 => _50.address]) && _optionalChain([client, 'access', _51 => _51.chain, 'access', _52 => _52.consensusMainContract, 'optionalAccess', _53 => _53.abi])) {
1143
+ 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])) {
1100
1144
  return;
1101
1145
  }
1102
1146
  const contractsResponse = await fetch(client.chain.rpcUrls.default.http[0], {
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-IViMPpkl.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-DrEvzYFA.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-CgHl4W-5.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-BIyk5Fv7.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
@@ -408,8 +408,70 @@ function serialize(data) {
408
408
 
409
409
  // src/contracts/actions.ts
410
410
  import { fromHex, toHex as toHex2, zeroAddress, encodeFunctionData, parseEventLogs } from "viem";
411
+
412
+ // src/abi/index.ts
413
+ var abi_exports = {};
414
+ __export(abi_exports, {
415
+ calldata: () => calldata,
416
+ transactions: () => transactions
417
+ });
418
+ var calldata = calldata_exports;
419
+ var transactions = transactions_exports;
420
+
421
+ // src/utils/jsonifier.ts
422
+ function b64ToArray(b64) {
423
+ return Uint8Array.from(atob(b64), (c) => c.charCodeAt(0));
424
+ }
425
+ function calldataToUserFriendlyJson(cd) {
426
+ return {
427
+ raw: Array.from(cd),
428
+ readable: calldata.toString(calldata.decode(cd))
429
+ };
430
+ }
431
+ var RESULT_CODES = /* @__PURE__ */ new Map([
432
+ [0, "return"],
433
+ [1, "rollback"],
434
+ [2, "contract_error"],
435
+ [3, "error"],
436
+ [4, "none"],
437
+ [5, "no_leaders"]
438
+ ]);
439
+ function resultToUserFriendlyJson(cd64) {
440
+ const raw = b64ToArray(cd64);
441
+ const code = RESULT_CODES.get(raw[0]);
442
+ let status;
443
+ let payload = null;
444
+ if (code === void 0) {
445
+ status = "<unknown>";
446
+ } else {
447
+ status = code;
448
+ if ([1, 2].includes(raw[0])) {
449
+ payload = new TextDecoder("utf-8").decode(raw.slice(1));
450
+ } else if (raw[0] == 0) {
451
+ payload = calldataToUserFriendlyJson(raw.slice(1));
452
+ }
453
+ }
454
+ return {
455
+ raw: cd64,
456
+ status,
457
+ payload
458
+ };
459
+ }
460
+
461
+ // src/contracts/actions.ts
411
462
  var contractActions = (client, publicClient) => {
412
463
  return {
464
+ getContractCode: async (address) => {
465
+ if (client.chain.id !== localnet.id) {
466
+ throw new Error("Getting contract code is not supported on this network");
467
+ }
468
+ const result = await client.request({
469
+ method: "gen_getContractCode",
470
+ params: [address]
471
+ });
472
+ const codeBytes = b64ToArray(result);
473
+ return new TextDecoder().decode(codeBytes);
474
+ },
413
475
  getContractSchema: async (address) => {
414
476
  if (client.chain.id !== localnet.id) {
415
477
  throw new Error("Contract schema is not supported on this network");
@@ -461,6 +523,37 @@ var contractActions = (client, publicClient) => {
461
523
  const resultBinary = fromHex(prefixedResult, "bytes");
462
524
  return decode(resultBinary);
463
525
  },
526
+ simulateWriteContract: async (args) => {
527
+ const {
528
+ account,
529
+ address,
530
+ functionName,
531
+ args: callArgs,
532
+ kwargs,
533
+ leaderOnly = false,
534
+ transactionHashVariant = "latest-nonfinal" /* LATEST_NONFINAL */
535
+ } = args;
536
+ const encodedData = [encode(makeCalldataObject(functionName, callArgs, kwargs)), leaderOnly];
537
+ const serializedData = serialize(encodedData);
538
+ const senderAddress = account?.address ?? client.account?.address;
539
+ const requestParams = {
540
+ type: "write",
541
+ to: address,
542
+ from: senderAddress,
543
+ data: serializedData,
544
+ transaction_hash_variant: transactionHashVariant
545
+ };
546
+ const result = await client.request({
547
+ method: "gen_call",
548
+ params: [requestParams]
549
+ });
550
+ const prefixedResult = `0x${result}`;
551
+ if (args.rawReturn) {
552
+ return prefixedResult;
553
+ }
554
+ const resultBinary = fromHex(prefixedResult, "bytes");
555
+ return decode(resultBinary);
556
+ },
464
557
  writeContract: async (args) => {
465
558
  const {
466
559
  account,
@@ -636,55 +729,6 @@ async function sleep(ms) {
636
729
  return new Promise((resolve) => setTimeout(resolve, ms));
637
730
  }
638
731
 
639
- // src/abi/index.ts
640
- var abi_exports = {};
641
- __export(abi_exports, {
642
- calldata: () => calldata,
643
- transactions: () => transactions
644
- });
645
- var calldata = calldata_exports;
646
- var transactions = transactions_exports;
647
-
648
- // src/utils/jsonifier.ts
649
- function b64ToArray(b64) {
650
- return Uint8Array.from(atob(b64), (c) => c.charCodeAt(0));
651
- }
652
- function calldataToUserFriendlyJson(cd) {
653
- return {
654
- raw: Array.from(cd),
655
- readable: calldata.toString(calldata.decode(cd))
656
- };
657
- }
658
- var RESULT_CODES = /* @__PURE__ */ new Map([
659
- [0, "return"],
660
- [1, "rollback"],
661
- [2, "contract_error"],
662
- [3, "error"],
663
- [4, "none"],
664
- [5, "no_leaders"]
665
- ]);
666
- function resultToUserFriendlyJson(cd64) {
667
- const raw = b64ToArray(cd64);
668
- const code = RESULT_CODES.get(raw[0]);
669
- let status;
670
- let payload = null;
671
- if (code === void 0) {
672
- status = "<unknown>";
673
- } else {
674
- status = code;
675
- if ([1, 2].includes(raw[0])) {
676
- payload = new TextDecoder("utf-8").decode(raw.slice(1));
677
- } else if (raw[0] == 0) {
678
- payload = calldataToUserFriendlyJson(raw.slice(1));
679
- }
680
- }
681
- return {
682
- raw: cd64,
683
- status,
684
- payload
685
- };
686
- }
687
-
688
732
  // src/transactions/decoders.ts
689
733
  import { fromRlp, fromHex as fromHex2 } from "viem";
690
734
  var FIELDS_TO_REMOVE = [
@@ -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-IViMPpkl.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-DrEvzYFA.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-CgHl4W-5.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-BIyk5Fv7.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.15.1",
4
+ "version": "0.17.0",
5
5
  "description": "GenLayer JavaScript SDK",
6
6
  "main": "dist/index.js",
7
7
  "types": "dist/index.d.ts",
@@ -11,9 +11,21 @@ import {
11
11
  TransactionHashVariant,
12
12
  } from "@/types";
13
13
  import {fromHex, toHex, zeroAddress, encodeFunctionData, PublicClient, parseEventLogs} from "viem";
14
+ import {b64ToArray} from "@/utils/jsonifier";
14
15
 
15
16
  export const contractActions = (client: GenLayerClient<GenLayerChain>, publicClient: PublicClient) => {
16
17
  return {
18
+ getContractCode: async (address: Address): Promise<string> => {
19
+ if (client.chain.id !== localnet.id) {
20
+ throw new Error("Getting contract code is not supported on this network");
21
+ }
22
+ const result = (await client.request({
23
+ method: "gen_getContractCode",
24
+ params: [address],
25
+ })) as string;
26
+ const codeBytes = b64ToArray(result);
27
+ return new TextDecoder().decode(codeBytes);
28
+ },
17
29
  getContractSchema: async (address: Address): Promise<ContractSchema> => {
18
30
  if (client.chain.id !== localnet.id) {
19
31
  throw new Error("Contract schema is not supported on this network");
@@ -78,6 +90,50 @@ export const contractActions = (client: GenLayerClient<GenLayerChain>, publicCli
78
90
  const resultBinary = fromHex(prefixedResult, "bytes");
79
91
  return calldata.decode(resultBinary) as any;
80
92
  },
93
+ simulateWriteContract: async <RawReturn extends boolean | undefined>(args: {
94
+ account?: Account;
95
+ address: Address;
96
+ functionName: string;
97
+ args?: CalldataEncodable[];
98
+ kwargs?: Map<string, CalldataEncodable> | {[key: string]: CalldataEncodable};
99
+ rawReturn?: RawReturn;
100
+ leaderOnly?: boolean;
101
+ transactionHashVariant?: TransactionHashVariant;
102
+ }): Promise<RawReturn extends true ? `0x${string}` : CalldataEncodable> => {
103
+ const {
104
+ account,
105
+ address,
106
+ functionName,
107
+ args: callArgs,
108
+ kwargs,
109
+ leaderOnly = false,
110
+ transactionHashVariant = TransactionHashVariant.LATEST_NONFINAL,
111
+ } = args;
112
+
113
+ const encodedData = [calldata.encode(calldata.makeCalldataObject(functionName, callArgs, kwargs)), leaderOnly];
114
+ const serializedData = serialize(encodedData);
115
+
116
+ const senderAddress = account?.address ?? client.account?.address;
117
+
118
+ const requestParams = {
119
+ type: "write",
120
+ to: address,
121
+ from: senderAddress,
122
+ data: serializedData,
123
+ transaction_hash_variant: transactionHashVariant,
124
+ };
125
+ const result = await client.request({
126
+ method: "gen_call",
127
+ params: [requestParams],
128
+ });
129
+ const prefixedResult = `0x${result}` as `0x${string}`;
130
+
131
+ if (args.rawReturn) {
132
+ return prefixedResult;
133
+ }
134
+ const resultBinary = fromHex(prefixedResult, "bytes");
135
+ return calldata.decode(resultBinary) as any;
136
+ },
81
137
  writeContract: async (args: {
82
138
  account?: Account;
83
139
  address: Address;
@@ -15,6 +15,7 @@ export type GenLayerMethod =
15
15
  | {method: "eth_sendRawTransaction"; params: [signedTransaction: string]}
16
16
  | {method: "gen_getContractSchema"; params: [address: Address]}
17
17
  | {method: "gen_getContractSchemaForCode"; params: [contractCode: string]}
18
+ | {method: "gen_getContractCode"; params: [address: Address]}
18
19
  | {method: "sim_getTransactionsForAddress"; params: [address: Address, filter?: "all" | "from" | "to"]}
19
20
  | {method: "eth_getTransactionCount"; params: [address: Address, block: string]}
20
21
  | {method: "gen_call"; params: [requestParams: any]};
@@ -58,6 +59,16 @@ export type GenLayerClient<TGenLayerChain extends GenLayerChain> = Omit<
58
59
  leaderOnly?: boolean;
59
60
  consensusMaxRotations?: number;
60
61
  }) => Promise<any>;
62
+ simulateWriteContract: <RawReturn extends boolean | undefined>(args: {
63
+ account?: Account;
64
+ address: Address;
65
+ functionName: string;
66
+ args?: CalldataEncodable[];
67
+ kwargs?: Map<string, CalldataEncodable> | { [key: string]: CalldataEncodable };
68
+ rawReturn?: RawReturn;
69
+ leaderOnly?: boolean;
70
+ transactionHashVariant?: TransactionHashVariant;
71
+ }) => Promise<RawReturn extends true ? `0x${string}` : CalldataEncodable>;
61
72
  deployContract: (args: {
62
73
  account?: Account;
63
74
  code: string | Uint8Array;
@@ -76,6 +87,7 @@ export type GenLayerClient<TGenLayerChain extends GenLayerChain> = Omit<
76
87
  }) => Promise<GenLayerTransaction>;
77
88
  getContractSchema: (address: Address) => Promise<ContractSchema>;
78
89
  getContractSchemaForCode: (contractCode: string | Uint8Array) => Promise<ContractSchema>;
90
+ getContractCode: (address: Address) => Promise<string>;
79
91
  initializeConsensusSmartContract: (forceReset?: boolean) => Promise<void>;
80
92
  connect: (network?: Network, snapSource?: SnapSource) => Promise<void>;
81
93
  metamaskClient: (snapSource?: SnapSource) => Promise<MetaMaskClientResult>;