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 +12 -0
- package/dist/index.js +20 -17
- package/package.json +1 -1
- package/src/commands/contracts/call.ts +5 -1
- package/src/commands/contracts/deploy.ts +13 -8
- package/src/commands/contracts/index.ts +5 -3
- package/src/lib/actions/BaseAction.ts +2 -2
- package/src/lib/config/simulator.ts +1 -1
- package/tests/actions/call.test.ts +52 -0
- package/tests/actions/deploy.test.ts +106 -12
- package/tests/commands/call.test.ts +5 -2
- package/tests/commands/deploy.test.ts +4 -1
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.
|
|
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.
|
|
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:
|
|
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
|
-
|
|
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
|
@@ -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
|
-
|
|
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
|
-
|
|
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:
|
|
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.
|
|
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
|
|