genlayer 0.14.1 → 0.16.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,17 @@
1
1
  # Changelog
2
2
 
3
+ ## 0.16.0 (2025-05-02)
4
+
5
+ ### Features
6
+
7
+ * update studios compatible version ([#220](https://github.com/yeagerai/genlayer-cli/issues/220)) ([cedf568](https://github.com/yeagerai/genlayer-cli/commit/cedf56888c81098ef83647bff4ad55dd7d697fb8))
8
+
9
+ ## 0.15.0 (2025-04-29)
10
+
11
+ ### Features
12
+
13
+ * custom rpc for interacting with contracts ([#218](https://github.com/yeagerai/genlayer-cli/issues/218)) ([138babd](https://github.com/yeagerai/genlayer-cli/commit/138babd76b24d2333356ec64cfdb712add312585))
14
+
3
15
  ## 0.14.1 (2025-04-25)
4
16
 
5
17
  ## 0.14.0 (2025-04-25)
package/dist/index.js CHANGED
@@ -16853,7 +16853,7 @@ var require_semver2 = __commonJS({
16853
16853
  import { program } from "commander";
16854
16854
 
16855
16855
  // package.json
16856
- var version = "0.14.1";
16856
+ var version = "0.16.0";
16857
16857
  var package_default = {
16858
16858
  name: "genlayer",
16859
16859
  version,
@@ -16944,7 +16944,7 @@ var CLI_DESCRIPTION = "GenLayer CLI is a development environment for the GenLaye
16944
16944
  import inquirer2 from "inquirer";
16945
16945
 
16946
16946
  // src/lib/config/simulator.ts
16947
- var localnetCompatibleVersion = "v0.51.0";
16947
+ var localnetCompatibleVersion = "v0.51.1";
16948
16948
  var DEFAULT_JSON_RPC_URL = "http://localhost:4000/api";
16949
16949
  var CONTAINERS_NAME_PREFIX = "/genlayer-";
16950
16950
  var IMAGES_NAME_PREFIX = "yeagerai";
@@ -27755,11 +27755,11 @@ var BaseAction = class extends ConfigFileManager {
27755
27755
  this.spinner = ora({ text: "", spinner: "dots" });
27756
27756
  this.keypairManager = new KeypairManager();
27757
27757
  }
27758
- async getClient() {
27758
+ async getClient(rpcUrl) {
27759
27759
  if (!this._genlayerClient) {
27760
27760
  this._genlayerClient = createClient2({
27761
27761
  chain: localnet,
27762
- endpoint: process.env.VITE_JSON_RPC_SERVER_URL,
27762
+ endpoint: rpcUrl,
27763
27763
  account: createAccount(await this.getPrivateKey())
27764
27764
  });
27765
27765
  }
@@ -28952,7 +28952,7 @@ var DeployAction = class extends BaseAction {
28952
28952
  }
28953
28953
  return fs8.readFileSync(contractPath, "utf-8");
28954
28954
  }
28955
- async executeTsScript(filePath) {
28955
+ async executeTsScript(filePath, rpcUrl) {
28956
28956
  const outFile = filePath.replace(/\.ts$/, ".compiled.js");
28957
28957
  this.startSpinner(`Transpiling TypeScript file: ${filePath}`);
28958
28958
  try {
@@ -28965,14 +28965,14 @@ var DeployAction = class extends BaseAction {
28965
28965
  target: "es2020",
28966
28966
  sourcemap: false
28967
28967
  });
28968
- await this.executeJsScript(filePath, outFile);
28968
+ await this.executeJsScript(filePath, outFile, rpcUrl);
28969
28969
  } catch (error) {
28970
28970
  this.failSpinner(`Error executing: ${filePath}`, error);
28971
28971
  } finally {
28972
28972
  fs8.unlinkSync(outFile);
28973
28973
  }
28974
28974
  }
28975
- async executeJsScript(filePath, transpiledFilePath) {
28975
+ async executeJsScript(filePath, transpiledFilePath, rpcUrl) {
28976
28976
  this.startSpinner(`Executing file: ${filePath}`);
28977
28977
  try {
28978
28978
  const module = await import(pathToFileURL(transpiledFilePath || filePath).href);
@@ -28980,14 +28980,14 @@ var DeployAction = class extends BaseAction {
28980
28980
  this.failSpinner(`No "default" function found in: ${filePath}`);
28981
28981
  return;
28982
28982
  }
28983
- const client = await this.getClient();
28983
+ const client = await this.getClient(rpcUrl);
28984
28984
  await module.default(client);
28985
28985
  this.succeedSpinner(`Successfully executed: ${filePath}`);
28986
28986
  } catch (error) {
28987
28987
  this.failSpinner(`Error executing: ${filePath}`, error);
28988
28988
  }
28989
28989
  }
28990
- async deployScripts() {
28990
+ async deployScripts(options) {
28991
28991
  this.startSpinner("Searching for deploy scripts...");
28992
28992
  if (!fs8.existsSync(this.deployDir)) {
28993
28993
  this.failSpinner("No deploy folder found.");
@@ -29011,9 +29011,9 @@ var DeployAction = class extends BaseAction {
29011
29011
  this.setSpinnerText(`Executing script: ${filePath}`);
29012
29012
  try {
29013
29013
  if (file.endsWith(".ts")) {
29014
- await this.executeTsScript(filePath);
29014
+ await this.executeTsScript(filePath, options?.rpc);
29015
29015
  } else {
29016
- await this.executeJsScript(filePath);
29016
+ await this.executeJsScript(filePath, void 0, options?.rpc);
29017
29017
  }
29018
29018
  } catch (error) {
29019
29019
  this.failSpinner(`Error executing script: ${filePath}`, error);
@@ -29022,7 +29022,7 @@ var DeployAction = class extends BaseAction {
29022
29022
  }
29023
29023
  async deploy(options) {
29024
29024
  try {
29025
- const client = await this.getClient();
29025
+ const client = await this.getClient(options.rpc);
29026
29026
  this.startSpinner("Setting up the deployment environment...");
29027
29027
  await client.initializeConsensusSmartContract();
29028
29028
  if (!options.contract) {
@@ -29065,9 +29065,11 @@ var CallAction = class extends BaseAction {
29065
29065
  async call({
29066
29066
  contractAddress,
29067
29067
  method,
29068
- args
29068
+ args,
29069
+ rpc
29069
29070
  }) {
29070
- const client = await this.getClient();
29071
+ const client = await this.getClient(rpc);
29072
+ await client.initializeConsensusSmartContract();
29071
29073
  this.startSpinner(`Calling method ${method} on contract at ${contractAddress}...`);
29072
29074
  const contractSchema = await client.getContractSchema(contractAddress);
29073
29075
  if (!contractSchema.methods.hasOwnProperty(method)) {
@@ -29124,15 +29126,16 @@ function parseArg(value, previous = []) {
29124
29126
  return [...previous, value];
29125
29127
  }
29126
29128
  function initializeContractsCommands(program2) {
29127
- program2.command("deploy").description("Deploy intelligent contracts").option("--contract <contractPath>", "Path to the smart contract to deploy").option("--args <args...>", "Positional arguments for the contract (space-separated, use quotes for multi-word arguments)", parseArg, []).action(async (options) => {
29129
+ program2.command("deploy").description("Deploy intelligent contracts").option("--contract <contractPath>", "Path to the smart contract to deploy").option("--rpc <rpcUrl>", "RPC URL for the network").option("--args <args...>", "Positional arguments for the contract (space-separated, use quotes for multi-word arguments)", parseArg, []).action(async (options) => {
29128
29130
  const deployer = new DeployAction();
29129
29131
  if (options.contract) {
29130
29132
  await deployer.deploy(options);
29131
29133
  } else {
29132
- await deployer.deployScripts();
29134
+ const deployScriptsOptions = { rpc: options.rpc };
29135
+ await deployer.deployScripts(deployScriptsOptions);
29133
29136
  }
29134
29137
  });
29135
- program2.command("call <contractAddress> <method>").description("Call a contract method").option("--args <args...>", "Positional arguments for the method (space-separated, use quotes for multi-word arguments)", parseArg, []).action(async (contractAddress, method, options) => {
29138
+ program2.command("call <contractAddress> <method>").description("Call a contract method").option("--rpc <rpcUrl>", "RPC URL for the network").option("--args <args...>", "Positional arguments for the method (space-separated, use quotes for multi-word arguments)", parseArg, []).action(async (contractAddress, method, options) => {
29136
29139
  const caller = new CallAction();
29137
29140
  await caller.call({ contractAddress, method, ...options });
29138
29141
  });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "genlayer",
3
- "version": "0.14.1",
3
+ "version": "0.16.0",
4
4
  "description": "GenLayer Command Line Tool",
5
5
  "main": "src/index.ts",
6
6
  "type": "module",
@@ -4,6 +4,7 @@ import { BaseAction } from "../../lib/actions/BaseAction";
4
4
 
5
5
  export interface CallOptions {
6
6
  args: any[];
7
+ rpc?: string;
7
8
  }
8
9
 
9
10
  export class CallAction extends BaseAction{
@@ -15,12 +16,15 @@ export class CallAction extends BaseAction{
15
16
  contractAddress,
16
17
  method,
17
18
  args,
19
+ rpc,
18
20
  }: {
19
21
  contractAddress: string;
20
22
  method: string;
21
23
  args: any[];
24
+ rpc?: string;
22
25
  }): Promise<void> {
23
- const client = await this.getClient();
26
+ const client = await this.getClient(rpc);
27
+ await client.initializeConsensusSmartContract();
24
28
  this.startSpinner(`Calling method ${method} on contract at ${contractAddress}...`);
25
29
 
26
30
  const contractSchema = await client.getContractSchema(contractAddress);
@@ -10,6 +10,11 @@ import { buildSync } from "esbuild";
10
10
  export interface DeployOptions {
11
11
  contract?: string;
12
12
  args?: any[];
13
+ rpc?: string;
14
+ }
15
+
16
+ export interface DeployScriptsOptions {
17
+ rpc?: string;
13
18
  }
14
19
 
15
20
  export class DeployAction extends BaseAction {
@@ -26,7 +31,7 @@ export class DeployAction extends BaseAction {
26
31
  return fs.readFileSync(contractPath, "utf-8");
27
32
  }
28
33
 
29
- private async executeTsScript(filePath: string): Promise<void> {
34
+ private async executeTsScript(filePath: string, rpcUrl?: string): Promise<void> {
30
35
  const outFile = filePath.replace(/\.ts$/, ".compiled.js");
31
36
  this.startSpinner(`Transpiling TypeScript file: ${filePath}`);
32
37
  try {
@@ -39,7 +44,7 @@ export class DeployAction extends BaseAction {
39
44
  target: "es2020",
40
45
  sourcemap: false,
41
46
  });
42
- await this.executeJsScript(filePath, outFile);
47
+ await this.executeJsScript(filePath, outFile, rpcUrl);
43
48
  } catch (error) {
44
49
  this.failSpinner(`Error executing: ${filePath}`, error);
45
50
  } finally {
@@ -47,7 +52,7 @@ export class DeployAction extends BaseAction {
47
52
  }
48
53
  }
49
54
 
50
- private async executeJsScript(filePath: string, transpiledFilePath?: string): Promise<void> {
55
+ private async executeJsScript(filePath: string, transpiledFilePath?: string, rpcUrl?: string): Promise<void> {
51
56
  this.startSpinner(`Executing file: ${filePath}`);
52
57
  try {
53
58
  const module = await import(pathToFileURL(transpiledFilePath || filePath).href);
@@ -55,7 +60,7 @@ export class DeployAction extends BaseAction {
55
60
  this.failSpinner(`No "default" function found in: ${filePath}`);
56
61
  return
57
62
  }
58
- const client = await this.getClient();
63
+ const client = await this.getClient(rpcUrl);
59
64
  await module.default(client);
60
65
  this.succeedSpinner(`Successfully executed: ${filePath}`);
61
66
  } catch (error) {
@@ -63,7 +68,7 @@ export class DeployAction extends BaseAction {
63
68
  }
64
69
  }
65
70
 
66
- async deployScripts() {
71
+ async deployScripts(options?: DeployScriptsOptions) {
67
72
  this.startSpinner("Searching for deploy scripts...");
68
73
  if (!fs.existsSync(this.deployDir)) {
69
74
  this.failSpinner("No deploy folder found.");
@@ -93,9 +98,9 @@ export class DeployAction extends BaseAction {
93
98
  this.setSpinnerText(`Executing script: ${filePath}`);
94
99
  try {
95
100
  if (file.endsWith(".ts")) {
96
- await this.executeTsScript(filePath);
101
+ await this.executeTsScript(filePath, options?.rpc);
97
102
  } else {
98
- await this.executeJsScript(filePath);
103
+ await this.executeJsScript(filePath, undefined, options?.rpc);
99
104
  }
100
105
  } catch (error) {
101
106
  this.failSpinner(`Error executing script: ${filePath}`, error);
@@ -105,7 +110,7 @@ export class DeployAction extends BaseAction {
105
110
 
106
111
  async deploy(options: DeployOptions): Promise<void> {
107
112
  try {
108
- const client = await this.getClient();
113
+ const client = await this.getClient(options.rpc);
109
114
  this.startSpinner("Setting up the deployment environment...");
110
115
  await client.initializeConsensusSmartContract();
111
116
 
@@ -1,5 +1,5 @@
1
1
  import { Command } from "commander";
2
- import { DeployAction, DeployOptions } from "./deploy";
2
+ import { DeployAction, DeployOptions, DeployScriptsOptions } from "./deploy";
3
3
  import { CallAction, CallOptions } from "./call";
4
4
 
5
5
  function parseArg(value: string, previous: any[] = []): any[] {
@@ -15,20 +15,22 @@ export function initializeContractsCommands(program: Command) {
15
15
  .command("deploy")
16
16
  .description("Deploy intelligent contracts")
17
17
  .option("--contract <contractPath>", "Path to the smart contract to deploy")
18
- // .option("--network <networkName>", "Specify the network (e.g., testnet)", "localnet")
18
+ .option("--rpc <rpcUrl>", "RPC URL for the network")
19
19
  .option("--args <args...>", "Positional arguments for the contract (space-separated, use quotes for multi-word arguments)", parseArg, [])
20
20
  .action(async (options: DeployOptions) => {
21
21
  const deployer = new DeployAction();
22
22
  if(options.contract){
23
23
  await deployer.deploy(options);
24
24
  }else {
25
- await deployer.deployScripts();
25
+ const deployScriptsOptions: DeployScriptsOptions = { rpc: options.rpc };
26
+ await deployer.deployScripts(deployScriptsOptions);
26
27
  }
27
28
  });
28
29
 
29
30
  program
30
31
  .command("call <contractAddress> <method>")
31
32
  .description("Call a contract method")
33
+ .option("--rpc <rpcUrl>", "RPC URL for the network")
32
34
  .option("--args <args...>", "Positional arguments for the method (space-separated, use quotes for multi-word arguments)", parseArg, [])
33
35
  .action(async (contractAddress: string, method: string, options: CallOptions) => {
34
36
  const caller = new CallAction();
@@ -18,11 +18,11 @@ export class BaseAction extends ConfigFileManager {
18
18
  this.keypairManager = new KeypairManager();
19
19
  }
20
20
 
21
- protected async getClient(): Promise<GenLayerClient<typeof localnet>> {
21
+ protected async getClient(rpcUrl?: string): Promise<GenLayerClient<typeof localnet>> {
22
22
  if (!this._genlayerClient) {
23
23
  this._genlayerClient = createClient({
24
24
  chain: localnet,
25
- endpoint: process.env.VITE_JSON_RPC_SERVER_URL,
25
+ endpoint: rpcUrl,
26
26
  account: createAccount(await this.getPrivateKey() as any),
27
27
  });
28
28
  }
@@ -1,4 +1,4 @@
1
- export const localnetCompatibleVersion = "v0.51.0";
1
+ export const localnetCompatibleVersion = "v0.51.1";
2
2
  export const DEFAULT_JSON_RPC_URL = "http://localhost:4000/api";
3
3
  export const CONTAINERS_NAME_PREFIX = "/genlayer-";
4
4
  export const IMAGES_NAME_PREFIX = "yeagerai";
@@ -11,6 +11,7 @@ describe("CallAction", () => {
11
11
  writeContract: vi.fn(),
12
12
  waitForTransactionReceipt: vi.fn(),
13
13
  getContractSchema: vi.fn(),
14
+ initializeConsensusSmartContract: vi.fn()
14
15
  };
15
16
 
16
17
  const mockPrivateKey = "mocked_private_key";
@@ -103,4 +104,55 @@ describe("CallAction", () => {
103
104
 
104
105
  expect(callActions["failSpinner"]).toHaveBeenCalledWith("Error during write operation", expect.any(Error));
105
106
  });
107
+
108
+ test("uses custom RPC URL when provided", async () => {
109
+ const options = { args: [1, 2, "Hello"], rpc: "https://custom-rpc-url.com" };
110
+ const mockResult = "mocked_result";
111
+
112
+ vi.mocked(mockClient.getContractSchema).mockResolvedValue({ methods: { getData: { readonly: true } } });
113
+ vi.mocked(mockClient.readContract).mockResolvedValue(mockResult);
114
+
115
+ await callActions.call({
116
+ contractAddress: "0xMockedContract",
117
+ method: "getData",
118
+ ...options,
119
+ });
120
+
121
+ expect(createClient).toHaveBeenCalledWith(expect.objectContaining({
122
+ endpoint: "https://custom-rpc-url.com"
123
+ }));
124
+ expect(mockClient.readContract).toHaveBeenCalledWith({
125
+ address: "0xMockedContract",
126
+ functionName: "getData",
127
+ args: [1, 2, "Hello"],
128
+ });
129
+ expect(callActions["succeedSpinner"]).toHaveBeenCalledWith("Read operation successfully executed", "mocked_result");
130
+ });
131
+
132
+ test("uses custom RPC URL for write operations", async () => {
133
+ const options = { args: [42, "Update"], rpc: "https://custom-rpc-url.com" };
134
+ const mockHash = "0xMockedTransactionHash";
135
+ const mockReceipt = { status: "success" };
136
+
137
+ vi.mocked(mockClient.getContractSchema).mockResolvedValue({ methods: { updateData: { readonly: false } } });
138
+ vi.mocked(mockClient.writeContract).mockResolvedValue(mockHash);
139
+ vi.mocked(mockClient.waitForTransactionReceipt).mockResolvedValue(mockReceipt);
140
+
141
+ await callActions.call({
142
+ contractAddress: "0xMockedContract",
143
+ method: "updateData",
144
+ ...options,
145
+ });
146
+
147
+ expect(createClient).toHaveBeenCalledWith(expect.objectContaining({
148
+ endpoint: "https://custom-rpc-url.com"
149
+ }));
150
+ expect(mockClient.writeContract).toHaveBeenCalledWith({
151
+ address: "0xMockedContract",
152
+ functionName: "updateData",
153
+ args: [42, "Update"],
154
+ value: 0n,
155
+ });
156
+ expect(callActions["succeedSpinner"]).toHaveBeenCalledWith("Write operation successfully executed", mockReceipt);
157
+ });
106
158
  });
@@ -143,9 +143,9 @@ describe("DeployAction", () => {
143
143
  await deployer.deployScripts();
144
144
 
145
145
  expect(deployer["setSpinnerText"]).toHaveBeenCalledWith("Found 3 deploy scripts. Executing...");
146
- expect(deployer["executeTsScript"]).toHaveBeenCalledWith(expect.stringMatching(/1_first.ts/));
147
- expect(deployer["executeJsScript"]).toHaveBeenCalledWith(expect.stringMatching(/2_second.js/));
148
- expect(deployer["executeTsScript"]).toHaveBeenCalledWith(expect.stringMatching(/10_last.ts/));
146
+ expect(deployer["executeTsScript"]).toHaveBeenCalledWith(expect.stringMatching(/1_first.ts/), undefined);
147
+ expect(deployer["executeJsScript"]).toHaveBeenCalledWith(expect.stringMatching(/2_second.js/), undefined, undefined);
148
+ expect(deployer["executeTsScript"]).toHaveBeenCalledWith(expect.stringMatching(/10_last.ts/), undefined);
149
149
  });
150
150
 
151
151
  test("executeTsScript transpiles and executes TypeScript", async () => {
@@ -168,7 +168,7 @@ describe("DeployAction", () => {
168
168
  sourcemap: false,
169
169
  });
170
170
 
171
- expect(deployer["executeJsScript"]).toHaveBeenCalledWith(filePath, outFile);
171
+ expect(deployer["executeJsScript"]).toHaveBeenCalledWith(filePath, outFile, undefined);
172
172
  expect(fs.unlinkSync).toHaveBeenCalledWith(outFile);
173
173
  });
174
174
 
@@ -193,9 +193,9 @@ describe("DeployAction", () => {
193
193
 
194
194
  await deployer.deployScripts();
195
195
 
196
- expect(deployer["executeTsScript"]).toHaveBeenCalledWith(expect.stringContaining("1_first.ts"));
197
- expect(deployer["executeJsScript"]).toHaveBeenCalledWith(expect.stringContaining("2_second.js"));
198
- expect(deployer["executeTsScript"]).toHaveBeenCalledWith(expect.stringContaining("10_last.ts"));
196
+ expect(deployer["executeTsScript"]).toHaveBeenCalledWith(expect.stringContaining("1_first.ts"), undefined);
197
+ expect(deployer["executeJsScript"]).toHaveBeenCalledWith(expect.stringContaining("2_second.js"), undefined, undefined);
198
+ expect(deployer["executeTsScript"]).toHaveBeenCalledWith(expect.stringContaining("10_last.ts"), undefined);
199
199
  });
200
200
 
201
201
  test("deployScripts fails when no scripts are found", async () => {
@@ -257,11 +257,11 @@ describe("DeployAction", () => {
257
257
 
258
258
  await deployer.deployScripts();
259
259
 
260
- expect(deployer["executeTsScript"]).toHaveBeenCalledWith(expect.stringContaining("script.ts"));
261
- expect(deployer["executeTsScript"]).toHaveBeenCalledWith(expect.stringContaining("2alpha_script.ts"));
262
- expect(deployer["executeTsScript"]).toHaveBeenCalledWith(expect.stringContaining("3alpha_script.ts"));
263
- expect(deployer["executeTsScript"]).toHaveBeenCalledWith(expect.stringContaining("blpha_script.ts"));
264
- expect(deployer["executeTsScript"]).toHaveBeenCalledWith(expect.stringContaining("clpha_script.ts"));
260
+ expect(deployer["executeTsScript"]).toHaveBeenCalledWith(expect.stringContaining("script.ts"), undefined);
261
+ expect(deployer["executeTsScript"]).toHaveBeenCalledWith(expect.stringContaining("2alpha_script.ts"), undefined);
262
+ expect(deployer["executeTsScript"]).toHaveBeenCalledWith(expect.stringContaining("3alpha_script.ts"), undefined);
263
+ expect(deployer["executeTsScript"]).toHaveBeenCalledWith(expect.stringContaining("blpha_script.ts"), undefined);
264
+ expect(deployer["executeTsScript"]).toHaveBeenCalledWith(expect.stringContaining("clpha_script.ts"), undefined);
265
265
  });
266
266
 
267
267
  test("executeJsScript fails if module has no default export", async () => {
@@ -304,4 +304,98 @@ describe("DeployAction", () => {
304
304
  error
305
305
  );
306
306
  });
307
+
308
+ test("deploys contract with rpc option", async () => {
309
+ const options: DeployOptions = {
310
+ contract: "/mocked/contract/path",
311
+ args: [1, 2, 3],
312
+ rpc: "https://custom-rpc-url.com"
313
+ };
314
+ const contractContent = "contract code";
315
+
316
+ vi.mocked(fs.existsSync).mockReturnValue(true);
317
+ vi.mocked(fs.readFileSync).mockReturnValue(contractContent);
318
+ vi.mocked(mockClient.deployContract).mockResolvedValue("mocked_tx_hash");
319
+ vi.mocked(mockClient.waitForTransactionReceipt).mockResolvedValue({
320
+ data: { contract_address: "0xdasdsadasdasdada" },
321
+ });
322
+
323
+ await deployer.deploy(options);
324
+
325
+ expect(createClient).toHaveBeenCalledWith(expect.objectContaining({
326
+ endpoint: "https://custom-rpc-url.com"
327
+ }));
328
+ expect(fs.readFileSync).toHaveBeenCalledWith(options.contract, "utf-8");
329
+ expect(mockClient.deployContract).toHaveBeenCalledWith({
330
+ code: contractContent,
331
+ args: [1, 2, 3],
332
+ leaderOnly: false,
333
+ });
334
+ });
335
+
336
+ test("executeJsScript uses rpc url when provided", async () => {
337
+ const filePath = "/mocked/script.js";
338
+ const rpcUrl = "https://custom-rpc-url.com";
339
+ const mockFn = vi.fn();
340
+
341
+ vi.doMock(pathToFileURL(filePath).href, () => ({ default: mockFn }));
342
+
343
+ await deployer["executeJsScript"](filePath, undefined, rpcUrl);
344
+
345
+ expect(createClient).toHaveBeenCalledWith(expect.objectContaining({
346
+ endpoint: rpcUrl
347
+ }));
348
+ expect(mockFn).toHaveBeenCalledWith(mockClient);
349
+ expect(deployer["succeedSpinner"]).toHaveBeenCalledWith(`Successfully executed: ${filePath}`);
350
+ });
351
+
352
+ test("executeTsScript passes rpc url to executeJsScript", async () => {
353
+ const filePath = "/mocked/script.ts";
354
+ const outFile = "/mocked/script.compiled.js";
355
+ const rpcUrl = "https://custom-rpc-url.com";
356
+
357
+ vi.spyOn(deployer as any, "executeJsScript").mockResolvedValue(undefined);
358
+ vi.mocked(buildSync).mockImplementation((() => {}) as any);
359
+
360
+ await deployer["executeTsScript"](filePath, rpcUrl);
361
+
362
+ expect(deployer["startSpinner"]).toHaveBeenCalledWith(`Transpiling TypeScript file: ${filePath}`);
363
+ expect(buildSync).toHaveBeenCalledWith({
364
+ entryPoints: [filePath],
365
+ outfile: outFile,
366
+ bundle: false,
367
+ platform: "node",
368
+ format: "esm",
369
+ target: "es2020",
370
+ sourcemap: false,
371
+ });
372
+
373
+ expect(deployer["executeJsScript"]).toHaveBeenCalledWith(filePath, outFile, rpcUrl);
374
+ expect(fs.unlinkSync).toHaveBeenCalledWith(outFile);
375
+ });
376
+
377
+ test("deployScripts passes rpc url to script execution methods", async () => {
378
+ const rpcUrl = "https://custom-rpc-url.com";
379
+
380
+ vi.mocked(fs.existsSync).mockReturnValue(true);
381
+ vi.mocked(fs.readdirSync).mockReturnValue([
382
+ "1_first.ts",
383
+ "2_second.js",
384
+ ] as any);
385
+
386
+ vi.spyOn(deployer as any, "executeTsScript").mockResolvedValue(undefined);
387
+ vi.spyOn(deployer as any, "executeJsScript").mockResolvedValue(undefined);
388
+
389
+ await deployer.deployScripts({ rpc: rpcUrl });
390
+
391
+ expect(deployer["executeTsScript"]).toHaveBeenCalledWith(
392
+ expect.stringMatching(/1_first.ts/),
393
+ rpcUrl
394
+ );
395
+ expect(deployer["executeJsScript"]).toHaveBeenCalledWith(
396
+ expect.stringMatching(/2_second.js/),
397
+ undefined,
398
+ rpcUrl
399
+ );
400
+ });
307
401
  });
@@ -43,13 +43,16 @@ describe("call command", () => {
43
43
  "2",
44
44
  "Hello",
45
45
  "false",
46
- "true"
46
+ "true",
47
+ "--rpc",
48
+ "https://custom-rpc-url.com"
47
49
  ]);
48
50
  expect(CallAction).toHaveBeenCalledTimes(1);
49
51
  expect(CallAction.prototype.call).toHaveBeenCalledWith({
50
52
  contractAddress: "0xMockedContract",
51
53
  method: "updateData",
52
- args: [1, 2, "Hello", false, true]
54
+ args: [1, 2, "Hello", false, true],
55
+ rpc: "https://custom-rpc-url.com"
53
56
  });
54
57
  });
55
58
 
@@ -41,11 +41,14 @@ describe("deploy command", () => {
41
41
  "1",
42
42
  "2",
43
43
  "3",
44
+ "--rpc",
45
+ "https://custom-rpc-url.com"
44
46
  ]);
45
47
  expect(DeployAction).toHaveBeenCalledTimes(1);
46
48
  expect(DeployAction.prototype.deploy).toHaveBeenCalledWith({
47
49
  contract: "./path/to/contract",
48
- args: [1, 2, 3]
50
+ args: [1, 2, 3],
51
+ rpc: "https://custom-rpc-url.com"
49
52
  });
50
53
  });
51
54