create-stylus 0.0.6 โ 0.1.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/dist/cli.js +31 -16
- package/dist/cli.js.map +1 -1
- package/package.json +2 -2
- package/src/extensions.json +6 -0
- package/src/main.ts +50 -36
- package/templates/base/package.json +2 -2
- package/templates/base/packages/nextjs/utils/scaffold-stylus/supportedChains.ts +37 -2
- package/templates/base/packages/stylus/.env.example +20 -0
- package/templates/base/packages/stylus/counter/.cargo/config.toml +18 -0
- package/templates/base/packages/stylus/counter/Cargo.lock +5788 -0
- package/templates/base/packages/stylus/counter/Cargo.toml +46 -0
- package/templates/base/packages/stylus/counter/rust-toolchain.toml +2 -0
- package/templates/base/packages/stylus/counter/src/lib.rs +121 -0
- package/templates/base/packages/stylus/counter/src/main.rs +10 -0
- package/templates/base/packages/stylus/package.json +2 -2
- package/templates/base/packages/stylus/scripts/deploy.ts +9 -1
- package/templates/base/packages/stylus/scripts/deploy_contract.ts +48 -0
- package/templates/base/packages/stylus/scripts/test.ts +236 -0
- package/templates/base/packages/stylus/scripts/test_network.ts +15 -12
- package/templates/base/packages/stylus/scripts/utils/command.ts +2 -1
- package/templates/base/packages/stylus/scripts/utils/contract.ts +2 -4
- package/templates/base/packages/stylus/scripts/utils/network.ts +75 -1
- package/templates/base/packages/stylus/scripts/utils/type.ts +1 -0
- package/templates/base/packages/stylus/your-contract/Cargo.toml +1 -1
- package/templates/base/packages/stylus/your-contract/rust-toolchain.toml +7 -1
- package/templates/base/packages/stylus/your-contract/src/lib.rs +43 -67
- package/templates/base/readme.md +10 -2
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
[package]
|
|
2
|
+
name = "stylus-hello-world"
|
|
3
|
+
version = "0.1.11"
|
|
4
|
+
edition = "2021"
|
|
5
|
+
license = "MIT OR Apache-2.0"
|
|
6
|
+
homepage = "https://github.com/OffchainLabs/stylus-hello-world"
|
|
7
|
+
repository = "https://github.com/OffchainLabs/stylus-hello-world"
|
|
8
|
+
keywords = ["arbitrum", "ethereum", "stylus", "alloy"]
|
|
9
|
+
description = "Stylus hello world example"
|
|
10
|
+
|
|
11
|
+
[dependencies]
|
|
12
|
+
alloy-primitives = "=0.8.20"
|
|
13
|
+
alloy-sol-types = "=0.8.20"
|
|
14
|
+
stylus-sdk = "0.9.0"
|
|
15
|
+
hex = { version = "0.4", default-features = false }
|
|
16
|
+
|
|
17
|
+
[dev-dependencies]
|
|
18
|
+
alloy-primitives = { version = "=0.8.20", features = ["sha3-keccak"] }
|
|
19
|
+
tokio = { version = "1.12.0", features = ["full"] }
|
|
20
|
+
ethers = "2.0"
|
|
21
|
+
eyre = "0.6.8"
|
|
22
|
+
stylus-sdk = { version = "0.9.0", features = ["stylus-test"] }
|
|
23
|
+
dotenv = "0.15.0"
|
|
24
|
+
|
|
25
|
+
[features]
|
|
26
|
+
default = ["mini-alloc"]
|
|
27
|
+
export-abi = ["stylus-sdk/export-abi"]
|
|
28
|
+
debug = ["stylus-sdk/debug"]
|
|
29
|
+
mini-alloc = ["stylus-sdk/mini-alloc"]
|
|
30
|
+
|
|
31
|
+
[[bin]]
|
|
32
|
+
name = "stylus-hello-world"
|
|
33
|
+
path = "src/main.rs"
|
|
34
|
+
|
|
35
|
+
[lib]
|
|
36
|
+
crate-type = ["lib", "cdylib"]
|
|
37
|
+
|
|
38
|
+
[profile.release]
|
|
39
|
+
codegen-units = 1
|
|
40
|
+
strip = true
|
|
41
|
+
lto = true
|
|
42
|
+
panic = "abort"
|
|
43
|
+
|
|
44
|
+
# If you need to reduce the binary size, it is advisable to try other
|
|
45
|
+
# optimization levels, such as "s" and "z"
|
|
46
|
+
opt-level = 3
|
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
//!
|
|
2
|
+
//! Stylus Hello World
|
|
3
|
+
//!
|
|
4
|
+
//! The following contract implements the Counter example from Foundry.
|
|
5
|
+
//!
|
|
6
|
+
//! ```solidity
|
|
7
|
+
//! contract Counter {
|
|
8
|
+
//! uint256 public number;
|
|
9
|
+
//! function setNumber(uint256 newNumber) public {
|
|
10
|
+
//! number = newNumber;
|
|
11
|
+
//! }
|
|
12
|
+
//! function increment() public {
|
|
13
|
+
//! number++;
|
|
14
|
+
//! }
|
|
15
|
+
//! }
|
|
16
|
+
//! ```
|
|
17
|
+
//!
|
|
18
|
+
//! The program is ABI-equivalent with Solidity, which means you can call it from both Solidity and Rust.
|
|
19
|
+
//! To do this, run `cargo stylus export-abi`.
|
|
20
|
+
//!
|
|
21
|
+
//! Note: this code is a template-only and has not been audited.
|
|
22
|
+
//!
|
|
23
|
+
// Allow `cargo stylus export-abi` to generate a main function.
|
|
24
|
+
#![cfg_attr(not(any(test, feature = "export-abi")), no_main)]
|
|
25
|
+
#![cfg_attr(not(any(test, feature = "export-abi")), no_std)]
|
|
26
|
+
|
|
27
|
+
#[macro_use]
|
|
28
|
+
extern crate alloc;
|
|
29
|
+
|
|
30
|
+
use alloc::vec::Vec;
|
|
31
|
+
|
|
32
|
+
/// Import items from the SDK. The prelude contains common traits and macros.
|
|
33
|
+
use stylus_sdk::{alloy_primitives::U256, prelude::*};
|
|
34
|
+
|
|
35
|
+
// Define some persistent storage using the Solidity ABI.
|
|
36
|
+
// `Counter` will be the entrypoint.
|
|
37
|
+
sol_storage! {
|
|
38
|
+
#[entrypoint]
|
|
39
|
+
pub struct Counter {
|
|
40
|
+
uint256 number;
|
|
41
|
+
bool is_initialized;
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
/// Declare that `Counter` is a contract with the following external methods.
|
|
46
|
+
#[public]
|
|
47
|
+
impl Counter {
|
|
48
|
+
pub fn initialize(&mut self, initial_number: U256) {
|
|
49
|
+
if !self.is_initialized.get() {
|
|
50
|
+
self.number.set(initial_number);
|
|
51
|
+
self.is_initialized.set(true);
|
|
52
|
+
} else {
|
|
53
|
+
panic!("Counter already initialized");
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
/// Gets the number from storage.
|
|
58
|
+
pub fn number(&self) -> U256 {
|
|
59
|
+
self.number.get()
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
/// Sets a number in storage to a user-specified value.
|
|
63
|
+
pub fn set_number(&mut self, new_number: U256) {
|
|
64
|
+
self.number.set(new_number);
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
/// Sets a number in storage to a user-specified value.
|
|
68
|
+
pub fn mul_number(&mut self, new_number: U256) {
|
|
69
|
+
self.number.set(new_number * self.number.get());
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
/// Sets a number in storage to a user-specified value.
|
|
73
|
+
pub fn add_number(&mut self, new_number: U256) {
|
|
74
|
+
self.number.set(new_number + self.number.get());
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
/// Increments `number` and updates its value in storage.
|
|
78
|
+
pub fn increment(&mut self) {
|
|
79
|
+
let number = self.number.get();
|
|
80
|
+
self.set_number(number + U256::from(1));
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
/// Adds the wei value from msg_value to the number in storage.
|
|
84
|
+
#[payable]
|
|
85
|
+
pub fn add_from_msg_value(&mut self) {
|
|
86
|
+
let number = self.number.get();
|
|
87
|
+
self.set_number(number + self.vm().msg_value());
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
#[cfg(test)]
|
|
92
|
+
mod test {
|
|
93
|
+
use super::*;
|
|
94
|
+
|
|
95
|
+
#[test]
|
|
96
|
+
fn test_counter() {
|
|
97
|
+
use stylus_sdk::testing::*;
|
|
98
|
+
let vm = TestVM::default();
|
|
99
|
+
let mut contract = Counter::from(&vm);
|
|
100
|
+
|
|
101
|
+
assert_eq!(U256::ZERO, contract.number());
|
|
102
|
+
|
|
103
|
+
contract.increment();
|
|
104
|
+
assert_eq!(U256::from(1), contract.number());
|
|
105
|
+
|
|
106
|
+
contract.add_number(U256::from(3));
|
|
107
|
+
assert_eq!(U256::from(4), contract.number());
|
|
108
|
+
|
|
109
|
+
contract.mul_number(U256::from(2));
|
|
110
|
+
assert_eq!(U256::from(8), contract.number());
|
|
111
|
+
|
|
112
|
+
contract.set_number(U256::from(100));
|
|
113
|
+
assert_eq!(U256::from(100), contract.number());
|
|
114
|
+
|
|
115
|
+
// Override the msg value for future contract method invocations.
|
|
116
|
+
vm.set_value(U256::from(2));
|
|
117
|
+
|
|
118
|
+
contract.add_from_msg_value();
|
|
119
|
+
assert_eq!(U256::from(102), contract.number());
|
|
120
|
+
}
|
|
121
|
+
}
|
|
@@ -9,10 +9,10 @@
|
|
|
9
9
|
"dev": "tsc --watch",
|
|
10
10
|
"start": "node dist/index.js",
|
|
11
11
|
"deploy": "ts-node scripts/deploy_wrapper.ts",
|
|
12
|
-
"
|
|
12
|
+
"info:networks": "ts-node scripts/test_network.ts",
|
|
13
13
|
"export-abi": "ts-node scripts/export_abi.ts",
|
|
14
14
|
"clean-contracts": "git clean -xdf -e .env -e your-contract/ -e node_modules/",
|
|
15
|
-
"test": "
|
|
15
|
+
"test": "ts-node scripts/test.ts",
|
|
16
16
|
"lint": "eslint scripts --ext .ts",
|
|
17
17
|
"lint:fix": "eslint scripts --ext .ts --fix",
|
|
18
18
|
"new-module": "bash scripts/new_module.sh"
|
|
@@ -32,7 +32,15 @@ export default async function deployScript(deployOptions: DeployOptions) {
|
|
|
32
32
|
...deployOptions,
|
|
33
33
|
});
|
|
34
34
|
|
|
35
|
-
|
|
35
|
+
// EXAMPLE: Deploy to Orbit Chains, uncomment to try
|
|
36
|
+
// await deployStylusContract({
|
|
37
|
+
// contract: "counter",
|
|
38
|
+
// constructorArgs: [100],
|
|
39
|
+
// isOrbit: true,
|
|
40
|
+
// ...deployOptions,
|
|
41
|
+
// });
|
|
42
|
+
|
|
43
|
+
// EXAMPLE: Deploy your contract with a custom name, uncomment to try
|
|
36
44
|
// await deployStylusContract({
|
|
37
45
|
// contract: "your-contract",
|
|
38
46
|
// constructorArgs: [config.deployerAddress],
|
|
@@ -4,11 +4,17 @@ import {
|
|
|
4
4
|
executeCommand,
|
|
5
5
|
extractDeploymentInfo,
|
|
6
6
|
saveDeployment,
|
|
7
|
+
ORBIT_CHAINS,
|
|
7
8
|
// estimateGasPrice,
|
|
8
9
|
} from "./utils/";
|
|
9
10
|
import { exportStylusAbi } from "./export_abi";
|
|
10
11
|
import { DeployOptions } from "./utils/type";
|
|
11
12
|
import { buildDeployCommand } from "./utils/command";
|
|
13
|
+
import { Chain, createPublicClient, createWalletClient, http } from "viem";
|
|
14
|
+
import { privateKeyToAccount } from "viem/accounts";
|
|
15
|
+
|
|
16
|
+
import { arbitrumNitro } from "../../nextjs/utils/scaffold-stylus/supportedChains";
|
|
17
|
+
import deployedContracts from "../../nextjs/contracts/deployedContracts";
|
|
12
18
|
|
|
13
19
|
/**
|
|
14
20
|
* Deploy a single contract using cargo stylus
|
|
@@ -61,6 +67,48 @@ export default async function deployStylusContract(
|
|
|
61
67
|
config.chain?.id,
|
|
62
68
|
);
|
|
63
69
|
|
|
70
|
+
// Call the initialize function if orbit deployment
|
|
71
|
+
if (
|
|
72
|
+
!!deployOptions.isOrbit &&
|
|
73
|
+
config.chain?.id !== arbitrumNitro?.id.toString()
|
|
74
|
+
) {
|
|
75
|
+
const orbitChain = ORBIT_CHAINS.find(
|
|
76
|
+
(chain) => chain.id.toString() === config.chain?.id,
|
|
77
|
+
);
|
|
78
|
+
|
|
79
|
+
if (!orbitChain) {
|
|
80
|
+
throw new Error(
|
|
81
|
+
`Chain ${config.chain?.id} is not supported for orbit deployment`,
|
|
82
|
+
);
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
const publicClient = createPublicClient({
|
|
86
|
+
chain: orbitChain as unknown as Chain,
|
|
87
|
+
transport: http(),
|
|
88
|
+
});
|
|
89
|
+
|
|
90
|
+
// need wallet client to sign the transaction
|
|
91
|
+
const walletClient = createWalletClient({
|
|
92
|
+
chain: orbitChain as unknown as Chain,
|
|
93
|
+
transport: http(),
|
|
94
|
+
});
|
|
95
|
+
|
|
96
|
+
const account = privateKeyToAccount(config.privateKey as `0x${string}`);
|
|
97
|
+
|
|
98
|
+
const { request } = await publicClient.simulateContract({
|
|
99
|
+
account,
|
|
100
|
+
address: deploymentInfo.address,
|
|
101
|
+
// @ts-expect-error deployed contract is empty at the beginning
|
|
102
|
+
abi: deployedContracts[config.chain.id][config.contractName].abi,
|
|
103
|
+
functionName: "initialize",
|
|
104
|
+
args: deployOptions.constructorArgs,
|
|
105
|
+
});
|
|
106
|
+
|
|
107
|
+
const initTxHash = await walletClient.writeContract(request);
|
|
108
|
+
|
|
109
|
+
console.log("Initialize transaction hash: ", initTxHash);
|
|
110
|
+
}
|
|
111
|
+
|
|
64
112
|
// Step 3: Verify the contract
|
|
65
113
|
if (deployOptions.verify) {
|
|
66
114
|
try {
|
|
@@ -0,0 +1,236 @@
|
|
|
1
|
+
#!/usr/bin/env ts-node
|
|
2
|
+
/**
|
|
3
|
+
* Stylus Cargo Test Runner
|
|
4
|
+
*
|
|
5
|
+
* This script automatically finds and runs tests for all Cargo projects
|
|
6
|
+
* in the stylus directory that have a Cargo.toml file.
|
|
7
|
+
*
|
|
8
|
+
* Features:
|
|
9
|
+
* - Automatically discovers Cargo projects by looking for Cargo.toml files
|
|
10
|
+
* - Excludes scripts, deployments, and node_modules directories
|
|
11
|
+
* - Runs `cargo test` for each project
|
|
12
|
+
* - Shows real-time output during test execution
|
|
13
|
+
* - Provides a comprehensive summary of test results
|
|
14
|
+
* - Exits with appropriate error codes for CI/CD integration
|
|
15
|
+
*
|
|
16
|
+
* Usage:
|
|
17
|
+
* npm run test
|
|
18
|
+
* or
|
|
19
|
+
* ts-node scripts/test.ts
|
|
20
|
+
*/
|
|
21
|
+
import { spawn } from "child_process";
|
|
22
|
+
import { promises as fs } from "fs";
|
|
23
|
+
import * as path from "path";
|
|
24
|
+
|
|
25
|
+
interface TestResult {
|
|
26
|
+
project: string;
|
|
27
|
+
success: boolean;
|
|
28
|
+
output: string;
|
|
29
|
+
error?: string;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* Execute a command and return a promise with the result
|
|
34
|
+
*/
|
|
35
|
+
function executeCommand(
|
|
36
|
+
command: string,
|
|
37
|
+
cwd: string,
|
|
38
|
+
): Promise<{ success: boolean; output: string; error?: string }> {
|
|
39
|
+
return new Promise((resolve) => {
|
|
40
|
+
console.log(`\n๐ Running tests in ${path.basename(cwd)}...`);
|
|
41
|
+
console.log(`Executing: ${command}`);
|
|
42
|
+
|
|
43
|
+
const childProcess = spawn(command, [], {
|
|
44
|
+
cwd,
|
|
45
|
+
shell: true,
|
|
46
|
+
stdio: ["inherit", "pipe", "pipe"],
|
|
47
|
+
});
|
|
48
|
+
|
|
49
|
+
let output = "";
|
|
50
|
+
let errorOutput = "";
|
|
51
|
+
|
|
52
|
+
// Handle stdout
|
|
53
|
+
if (childProcess.stdout) {
|
|
54
|
+
childProcess.stdout.on("data", (data: Buffer) => {
|
|
55
|
+
const chunk = data.toString();
|
|
56
|
+
output += chunk;
|
|
57
|
+
process.stdout.write(chunk); // Show real-time output
|
|
58
|
+
});
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
// Handle stderr
|
|
62
|
+
if (childProcess.stderr) {
|
|
63
|
+
childProcess.stderr.on("data", (data: Buffer) => {
|
|
64
|
+
const chunk = data.toString();
|
|
65
|
+
errorOutput += chunk;
|
|
66
|
+
process.stderr.write(chunk); // Show real-time errors
|
|
67
|
+
});
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
// Handle process completion
|
|
71
|
+
childProcess.on("close", (code: number | null) => {
|
|
72
|
+
const success = code === 0;
|
|
73
|
+
if (success) {
|
|
74
|
+
console.log(
|
|
75
|
+
`โ
Tests completed successfully in ${path.basename(cwd)}!`,
|
|
76
|
+
);
|
|
77
|
+
} else {
|
|
78
|
+
console.log(
|
|
79
|
+
`โ Tests failed in ${path.basename(cwd)} with exit code ${code}`,
|
|
80
|
+
);
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
resolve({
|
|
84
|
+
success,
|
|
85
|
+
output,
|
|
86
|
+
...(errorOutput && { error: errorOutput }),
|
|
87
|
+
});
|
|
88
|
+
});
|
|
89
|
+
|
|
90
|
+
// Handle process errors
|
|
91
|
+
childProcess.on("error", (error: Error) => {
|
|
92
|
+
console.error(
|
|
93
|
+
`โ Error running tests in ${path.basename(cwd)}:`,
|
|
94
|
+
error.message,
|
|
95
|
+
);
|
|
96
|
+
resolve({
|
|
97
|
+
success: false,
|
|
98
|
+
output: "",
|
|
99
|
+
error: error.message,
|
|
100
|
+
});
|
|
101
|
+
});
|
|
102
|
+
});
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
/**
|
|
106
|
+
* Check if a directory contains a Cargo.toml file
|
|
107
|
+
*/
|
|
108
|
+
async function hasCargoToml(dirPath: string): Promise<boolean> {
|
|
109
|
+
try {
|
|
110
|
+
await fs.access(path.join(dirPath, "Cargo.toml"));
|
|
111
|
+
return true;
|
|
112
|
+
} catch {
|
|
113
|
+
return false;
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
/**
|
|
118
|
+
* Find all Cargo projects in the stylus directory
|
|
119
|
+
*/
|
|
120
|
+
async function findCargoProjects(): Promise<string[]> {
|
|
121
|
+
const stylusDir = path.resolve(__dirname, "..");
|
|
122
|
+
const cargoProjects: string[] = [];
|
|
123
|
+
|
|
124
|
+
try {
|
|
125
|
+
const entries = await fs.readdir(stylusDir, { withFileTypes: true });
|
|
126
|
+
|
|
127
|
+
for (const entry of entries) {
|
|
128
|
+
if (entry.isDirectory()) {
|
|
129
|
+
const dirName = entry.name;
|
|
130
|
+
|
|
131
|
+
// Skip excluded directories
|
|
132
|
+
if (
|
|
133
|
+
dirName === "scripts" ||
|
|
134
|
+
dirName === "deployments" ||
|
|
135
|
+
dirName === "node_modules"
|
|
136
|
+
) {
|
|
137
|
+
continue;
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
const dirPath = path.join(stylusDir, dirName);
|
|
141
|
+
|
|
142
|
+
if (await hasCargoToml(dirPath)) {
|
|
143
|
+
cargoProjects.push(dirPath);
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
} catch (error) {
|
|
148
|
+
console.error("Error scanning for Cargo projects:", error);
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
return cargoProjects;
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
/**
|
|
155
|
+
* Run tests for all Cargo projects
|
|
156
|
+
*/
|
|
157
|
+
async function runAllTests(): Promise<void> {
|
|
158
|
+
console.log("๐ Starting Stylus Cargo Tests...\n");
|
|
159
|
+
|
|
160
|
+
const cargoProjects = await findCargoProjects();
|
|
161
|
+
|
|
162
|
+
if (cargoProjects.length === 0) {
|
|
163
|
+
console.log("โ No Cargo projects found with Cargo.toml files.");
|
|
164
|
+
process.exit(1);
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
console.log(`Found ${cargoProjects.length} Stylus Contract(s):`);
|
|
168
|
+
cargoProjects.forEach((project) => {
|
|
169
|
+
console.log(` - ${path.basename(project)}`);
|
|
170
|
+
});
|
|
171
|
+
console.log("");
|
|
172
|
+
|
|
173
|
+
const results: TestResult[] = [];
|
|
174
|
+
|
|
175
|
+
// Run tests for each project
|
|
176
|
+
for (const projectPath of cargoProjects) {
|
|
177
|
+
const projectName = path.basename(projectPath);
|
|
178
|
+
|
|
179
|
+
const result = await executeCommand("cargo test", projectPath);
|
|
180
|
+
|
|
181
|
+
results.push({
|
|
182
|
+
project: projectName,
|
|
183
|
+
success: result.success,
|
|
184
|
+
output: result.output,
|
|
185
|
+
...(result.error && { error: result.error }),
|
|
186
|
+
});
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
// Print summary
|
|
190
|
+
console.log("\n" + "=".repeat(60));
|
|
191
|
+
console.log("๐ TEST SUMMARY");
|
|
192
|
+
console.log("=".repeat(60));
|
|
193
|
+
|
|
194
|
+
const successful = results.filter((r) => r.success);
|
|
195
|
+
const failed = results.filter((r) => !r.success);
|
|
196
|
+
|
|
197
|
+
console.log(`โ
Successful: ${successful.length}`);
|
|
198
|
+
console.log(`โ Failed: ${failed.length}`);
|
|
199
|
+
console.log(`๐ฆ Total projects: ${results.length}`);
|
|
200
|
+
|
|
201
|
+
if (successful.length > 0) {
|
|
202
|
+
console.log("\nโ
Successful projects:");
|
|
203
|
+
successful.forEach((result) => {
|
|
204
|
+
console.log(` - ${result.project}`);
|
|
205
|
+
});
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
if (failed.length > 0) {
|
|
209
|
+
console.log("\nโ Failed projects:");
|
|
210
|
+
failed.forEach((result) => {
|
|
211
|
+
console.log(` - ${result.project}`);
|
|
212
|
+
if (result.error) {
|
|
213
|
+
console.log(` Error: ${result.error.split("\n")[0]}`);
|
|
214
|
+
}
|
|
215
|
+
});
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
// Exit with error code if any tests failed
|
|
219
|
+
if (failed.length > 0) {
|
|
220
|
+
console.log("\n๐ฅ Some tests failed!");
|
|
221
|
+
process.exit(1);
|
|
222
|
+
} else {
|
|
223
|
+
console.log("\n๐ All tests passed!");
|
|
224
|
+
process.exit(0);
|
|
225
|
+
}
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
// Main execution
|
|
229
|
+
if (require.main === module) {
|
|
230
|
+
runAllTests().catch((error) => {
|
|
231
|
+
console.error("โ Unexpected error:", error);
|
|
232
|
+
process.exit(1);
|
|
233
|
+
});
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
export { runAllTests, findCargoProjects };
|
|
@@ -3,13 +3,10 @@ import { SUPPORTED_NETWORKS } from "./utils/";
|
|
|
3
3
|
|
|
4
4
|
function testNetworkFunctionality() {
|
|
5
5
|
console.log("๐งช Testing network functionality...\n");
|
|
6
|
-
|
|
7
|
-
const testNetworks = [
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
];
|
|
11
|
-
|
|
12
|
-
testNetworks.forEach(network => {
|
|
6
|
+
|
|
7
|
+
const testNetworks = [...Object.keys(SUPPORTED_NETWORKS)];
|
|
8
|
+
|
|
9
|
+
testNetworks.forEach((network) => {
|
|
13
10
|
const chain = getChain(network);
|
|
14
11
|
if (chain) {
|
|
15
12
|
console.log(`โ
${network}: ${chain.rpcUrl}`);
|
|
@@ -17,15 +14,21 @@ function testNetworkFunctionality() {
|
|
|
17
14
|
console.log(`โ ${network}: Not found in viem chains`);
|
|
18
15
|
}
|
|
19
16
|
});
|
|
20
|
-
|
|
17
|
+
|
|
21
18
|
console.log("\n๐ Usage examples:");
|
|
22
|
-
Object.keys(SUPPORTED_NETWORKS).forEach(network => {
|
|
19
|
+
Object.keys(SUPPORTED_NETWORKS).forEach((network) => {
|
|
23
20
|
const chain = getChain(network);
|
|
24
|
-
console.log(
|
|
25
|
-
|
|
21
|
+
console.log(
|
|
22
|
+
` yarn deploy --network ${chain?.name}\t# Deploy to ${chain?.name}`,
|
|
23
|
+
);
|
|
24
|
+
|
|
25
|
+
// TODO: determine which one to use later, for now we use all original names
|
|
26
|
+
// console.log(
|
|
27
|
+
// ` yarn deploy --network ${chain?.alias}\t\t# Deploy to ${chain?.name} (alias)`,
|
|
28
|
+
// );
|
|
26
29
|
});
|
|
27
30
|
}
|
|
28
31
|
|
|
29
32
|
if (require.main === module) {
|
|
30
33
|
testNetworkFunctionality();
|
|
31
|
-
}
|
|
34
|
+
}
|
|
@@ -22,7 +22,8 @@ export async function buildDeployCommand(
|
|
|
22
22
|
|
|
23
23
|
if (
|
|
24
24
|
deployOptions.constructorArgs &&
|
|
25
|
-
deployOptions.constructorArgs.length > 0
|
|
25
|
+
deployOptions.constructorArgs.length > 0 &&
|
|
26
|
+
!deployOptions.isOrbit
|
|
26
27
|
) {
|
|
27
28
|
baseCommand += ` --constructor-args ${deployOptions.constructorArgs.map((arg) => `"${arg}"`).join(" ")} `;
|
|
28
29
|
}
|
|
@@ -154,9 +154,7 @@ export async function generateTsAbi(
|
|
|
154
154
|
};
|
|
155
155
|
|
|
156
156
|
let deployedContractsObj: any = {};
|
|
157
|
-
const fileHeader =
|
|
158
|
-
generatedContractComment +
|
|
159
|
-
'import { GenericContractsDeclaration } from "~~/utils/scaffold-eth/contract";\n\n';
|
|
157
|
+
const fileHeader = generatedContractComment + "\n\n";
|
|
160
158
|
|
|
161
159
|
if (fs.existsSync(TARGET_FILE)) {
|
|
162
160
|
const fileContent = fs.readFileSync(TARGET_FILE, "utf8");
|
|
@@ -177,7 +175,7 @@ export async function generateTsAbi(
|
|
|
177
175
|
|
|
178
176
|
const contractsString = JSON.stringify(deployedContractsObj, null, 2);
|
|
179
177
|
|
|
180
|
-
const output = `${fileHeader}const deployedContracts = ${contractsString} as const;\n\nexport default deployedContracts
|
|
178
|
+
const output = `${fileHeader}const deployedContracts = ${contractsString} as const;\n\nexport default deployedContracts;\n`;
|
|
181
179
|
|
|
182
180
|
if (!fs.existsSync(TARGET_DIR)) {
|
|
183
181
|
fs.mkdirSync(TARGET_DIR);
|