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
|
@@ -1,6 +1,12 @@
|
|
|
1
1
|
import { arbitrum, arbitrumNova, arbitrumSepolia } from "viem/chains";
|
|
2
2
|
import { Address, Chain } from "viem";
|
|
3
|
-
import {
|
|
3
|
+
import {
|
|
4
|
+
arbitrumNitro,
|
|
5
|
+
superposition,
|
|
6
|
+
eduChainTestnet,
|
|
7
|
+
superpositionTestnet,
|
|
8
|
+
eduChain,
|
|
9
|
+
} from "../../../nextjs/utils/scaffold-stylus/supportedChains";
|
|
4
10
|
import * as path from "path";
|
|
5
11
|
import * as fs from "fs";
|
|
6
12
|
import { config as dotenvConfig } from "dotenv";
|
|
@@ -16,6 +22,10 @@ export const SUPPORTED_NETWORKS: Record<string, Chain> = {
|
|
|
16
22
|
arbitrumSepolia,
|
|
17
23
|
arbitrumNitro: arbitrumNitro as Chain,
|
|
18
24
|
arbitrumNova: arbitrumNova as Chain,
|
|
25
|
+
eduChainTestnet: eduChainTestnet as unknown as Chain,
|
|
26
|
+
eduChain: eduChain as unknown as Chain,
|
|
27
|
+
superposition: superposition as Chain,
|
|
28
|
+
superpositionTestnet: superpositionTestnet as Chain,
|
|
19
29
|
};
|
|
20
30
|
|
|
21
31
|
export const ALIASES: Record<string, string> = {
|
|
@@ -23,8 +33,20 @@ export const ALIASES: Record<string, string> = {
|
|
|
23
33
|
sepolia: "arbitrumSepolia",
|
|
24
34
|
devnet: "arbitrumNitro",
|
|
25
35
|
nova: "arbitrumNova",
|
|
36
|
+
educhain_testnet: "educhainTestnet",
|
|
37
|
+
educhain: "eduChain",
|
|
38
|
+
superposition: "superposition",
|
|
39
|
+
superposition_testnet: "superpositionTestnet",
|
|
26
40
|
};
|
|
27
41
|
|
|
42
|
+
// TODO: add more compatible Orbit Chains here
|
|
43
|
+
export const ORBIT_CHAINS: Chain[] = [
|
|
44
|
+
eduChain as unknown as Chain,
|
|
45
|
+
eduChainTestnet as unknown as Chain,
|
|
46
|
+
superposition as Chain,
|
|
47
|
+
superpositionTestnet as Chain,
|
|
48
|
+
];
|
|
49
|
+
|
|
28
50
|
export function getChain(networkName: string): SupportedNetworkMinimal | null {
|
|
29
51
|
try {
|
|
30
52
|
const actualNetworkName = ALIASES[networkName.toLowerCase()] || networkName;
|
|
@@ -75,6 +97,30 @@ export function getPrivateKey(networkName: string): string {
|
|
|
75
97
|
} else {
|
|
76
98
|
throw new Error("PRIVATE_KEY_NOVA is not set");
|
|
77
99
|
}
|
|
100
|
+
case "educhaintestnet":
|
|
101
|
+
if (process.env["PRIVATE_KEY_EDUCHAIN_TESTNET"]) {
|
|
102
|
+
return process.env["PRIVATE_KEY_EDUCHAIN_TESTNET"];
|
|
103
|
+
} else {
|
|
104
|
+
throw new Error("PRIVATE_KEY_EDUCHAIN_TESTNET is not set");
|
|
105
|
+
}
|
|
106
|
+
case "educhain":
|
|
107
|
+
if (process.env["PRIVATE_KEY_EDUCHAIN"]) {
|
|
108
|
+
return process.env["PRIVATE_KEY_EDUCHAIN"];
|
|
109
|
+
} else {
|
|
110
|
+
throw new Error("PRIVATE_KEY_EDUCHAIN is not set");
|
|
111
|
+
}
|
|
112
|
+
case "superposition":
|
|
113
|
+
if (process.env["PRIVATE_KEY_SUPERPOSITION"]) {
|
|
114
|
+
return process.env["PRIVATE_KEY_SUPERPOSITION"];
|
|
115
|
+
} else {
|
|
116
|
+
throw new Error("PRIVATE_KEY_SUPERPOSITION is not set");
|
|
117
|
+
}
|
|
118
|
+
case "superpositiontestnet":
|
|
119
|
+
if (process.env["PRIVATE_KEY_SUPERPOSITION_TESTNET"]) {
|
|
120
|
+
return process.env["PRIVATE_KEY_SUPERPOSITION_TESTNET"];
|
|
121
|
+
} else {
|
|
122
|
+
throw new Error("PRIVATE_KEY_SUPERPOSITION_TESTNET is not set");
|
|
123
|
+
}
|
|
78
124
|
default:
|
|
79
125
|
return (
|
|
80
126
|
process.env["PRIVATE_KEY"] ||
|
|
@@ -92,6 +138,14 @@ export const getAccountAddress = (networkName: string): Address | undefined => {
|
|
|
92
138
|
return process.env["ACCOUNT_ADDRESS_SEPOLIA"] as Address;
|
|
93
139
|
case "arbitrumnova":
|
|
94
140
|
return process.env["ACCOUNT_ADDRESS_NOVA"] as Address;
|
|
141
|
+
case "educhaintestnet":
|
|
142
|
+
return process.env["ACCOUNT_ADDRESS_EDUCHAIN_TESTNET"] as Address;
|
|
143
|
+
case "educhain":
|
|
144
|
+
return process.env["ACCOUNT_ADDRESS_EDUCHAIN"] as Address;
|
|
145
|
+
case "superposition":
|
|
146
|
+
return process.env["ACCOUNT_ADDRESS_SUPERPOSITION"] as Address;
|
|
147
|
+
case "superpositiontestnet":
|
|
148
|
+
return process.env["ACCOUNT_ADDRESS_SUPERPOSITION_TESTNET"] as Address;
|
|
95
149
|
default:
|
|
96
150
|
return (
|
|
97
151
|
(process.env["ACCOUNT_ADDRESS"] as Address) ||
|
|
@@ -118,6 +172,26 @@ function getRpcUrlFromChain(chain: Chain): string {
|
|
|
118
172
|
return process.env["RPC_URL_NOVA"];
|
|
119
173
|
}
|
|
120
174
|
break;
|
|
175
|
+
case eduChainTestnet.id:
|
|
176
|
+
if (process.env["RPC_URL_EDUCHAIN_TESTNET"]) {
|
|
177
|
+
return process.env["RPC_URL_EDUCHAIN_TESTNET"];
|
|
178
|
+
}
|
|
179
|
+
break;
|
|
180
|
+
case eduChain.id:
|
|
181
|
+
if (process.env["RPC_URL_EDUCHAIN"]) {
|
|
182
|
+
return process.env["RPC_URL_EDUCHAIN"];
|
|
183
|
+
}
|
|
184
|
+
break;
|
|
185
|
+
case superposition.id:
|
|
186
|
+
if (process.env["RPC_URL_SUPERPOSITION"]) {
|
|
187
|
+
return process.env["RPC_URL_SUPERPOSITION"];
|
|
188
|
+
}
|
|
189
|
+
break;
|
|
190
|
+
case superpositionTestnet.id:
|
|
191
|
+
if (process.env["RPC_URL_SUPERPOSITION_TESTNET"]) {
|
|
192
|
+
return process.env["RPC_URL_SUPERPOSITION_TESTNET"];
|
|
193
|
+
}
|
|
194
|
+
break;
|
|
121
195
|
default:
|
|
122
196
|
if (process.env["RPC_URL"]) {
|
|
123
197
|
return process.env["RPC_URL"];
|
|
@@ -13,7 +13,7 @@ alloy-primitives = "=0.8.20"
|
|
|
13
13
|
alloy-sol-types = "=0.8.20"
|
|
14
14
|
stylus-sdk = "0.9.0"
|
|
15
15
|
hex = { version = "0.4", default-features = false }
|
|
16
|
-
openzeppelin-stylus = "0.2.0"
|
|
16
|
+
openzeppelin-stylus = "=0.2.0"
|
|
17
17
|
|
|
18
18
|
[dev-dependencies]
|
|
19
19
|
alloy-primitives = { version = "=0.8.20", features = ["sha3-keccak"] }
|
|
@@ -1,2 +1,8 @@
|
|
|
1
|
+
# NOTE: this toolchain is nightly because of openzeppelin requirements
|
|
2
|
+
|
|
1
3
|
[toolchain]
|
|
2
|
-
|
|
4
|
+
# We should use stable here once nitro-testnode is updated and the contracts fit
|
|
5
|
+
# the size limit (issue <https://github.com/OpenZeppelin/rust-contracts-stylus/issues/129>).
|
|
6
|
+
channel = "1.89.0"
|
|
7
|
+
components = ["rust-src", "rustfmt", "clippy"]
|
|
8
|
+
targets = ["wasm32-unknown-unknown"]
|
|
@@ -170,70 +170,46 @@ impl IOwnable for YourContract {
|
|
|
170
170
|
}
|
|
171
171
|
}
|
|
172
172
|
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
//
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
//
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
//
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
// // Initialize with owner
|
|
217
|
-
// let owner_addr = vm.addr(); // Use VM address as owner for testing
|
|
218
|
-
// contract.init(owner_addr);
|
|
219
|
-
|
|
220
|
-
// // Test withdraw (in real scenario, contract would have received ETH)
|
|
221
|
-
// let result = contract.withdraw();
|
|
222
|
-
// assert!(result.is_ok()); // Should not panic since caller is owner
|
|
223
|
-
// }
|
|
224
|
-
|
|
225
|
-
// #[test]
|
|
226
|
-
// fn test_withdraw_not_owner() {
|
|
227
|
-
// let vm = TestVM::default();
|
|
228
|
-
// let mut contract = YourContract::from(&vm);
|
|
229
|
-
|
|
230
|
-
// // Initialize with different owner
|
|
231
|
-
// let owner_addr = Address::from([1u8; 20]);
|
|
232
|
-
// contract.init(owner_addr);
|
|
233
|
-
|
|
234
|
-
// // This test should panic with "Not the Owner" when withdraw is called by non-owner
|
|
235
|
-
// // In a real test environment, you'd want to test this more carefully
|
|
236
|
-
// // but for now we'll just verify the function exists
|
|
237
|
-
// assert_eq!(contract.owner(), owner_addr);
|
|
238
|
-
// }
|
|
239
|
-
// }
|
|
173
|
+
#[cfg(test)]
|
|
174
|
+
mod test {
|
|
175
|
+
use super::*;
|
|
176
|
+
use stylus_sdk::testing::*;
|
|
177
|
+
|
|
178
|
+
#[no_mangle]
|
|
179
|
+
pub unsafe extern "C" fn emit_log(_pointer: *const u8, _len: usize, _: usize) {}
|
|
180
|
+
#[no_mangle]
|
|
181
|
+
pub unsafe extern "C" fn msg_sender(_sender: *mut u8) {}
|
|
182
|
+
|
|
183
|
+
#[test]
|
|
184
|
+
fn test_your_contract() {
|
|
185
|
+
let vm = TestVM::default();
|
|
186
|
+
let mut contract = YourContract::from(&vm);
|
|
187
|
+
|
|
188
|
+
// Test initialization
|
|
189
|
+
let owner_addr = Address::from([1u8; 20]);
|
|
190
|
+
let _ = contract.constructor(owner_addr);
|
|
191
|
+
|
|
192
|
+
assert_eq!(contract.owner(), owner_addr);
|
|
193
|
+
assert_eq!(contract.greeting(), "Building Unstoppable Apps!!!");
|
|
194
|
+
assert_eq!(contract.premium(), false);
|
|
195
|
+
assert_eq!(contract.total_counter(), U256::ZERO);
|
|
196
|
+
|
|
197
|
+
// Test setting greeting without payment
|
|
198
|
+
contract.set_greeting("Hello World".to_string());
|
|
199
|
+
assert_eq!(contract.greeting(), "Hello World");
|
|
200
|
+
assert_eq!(contract.premium(), false);
|
|
201
|
+
assert_eq!(contract.total_counter(), U256::from(1));
|
|
202
|
+
|
|
203
|
+
// Test user greeting counter
|
|
204
|
+
let sender = vm.msg_sender();
|
|
205
|
+
assert_eq!(contract.user_greeting_counter(sender), U256::from(1));
|
|
206
|
+
|
|
207
|
+
// Test setting greeting with payment
|
|
208
|
+
vm.set_value(U256::from(100));
|
|
209
|
+
contract.set_greeting("Premium Hello".to_string());
|
|
210
|
+
assert_eq!(contract.greeting(), "Premium Hello");
|
|
211
|
+
assert_eq!(contract.premium(), true);
|
|
212
|
+
assert_eq!(contract.total_counter(), U256::from(2));
|
|
213
|
+
assert_eq!(contract.user_greeting_counter(sender), U256::from(2));
|
|
214
|
+
}
|
|
215
|
+
}
|
package/templates/base/readme.md
CHANGED
|
@@ -189,12 +189,12 @@ To deploy your contracts to other networks (other than the default local Nitro d
|
|
|
189
189
|
This template supports Arbitrum networks only. You can test which networks are available and their RPC URLs:
|
|
190
190
|
|
|
191
191
|
```bash
|
|
192
|
-
yarn
|
|
192
|
+
yarn info:networks
|
|
193
193
|
```
|
|
194
194
|
|
|
195
195
|
This will show you all supported networks and their corresponding RPC endpoints.
|
|
196
196
|
|
|
197
|
-
### Deploy to Other Network
|
|
197
|
+
### Deploy to Other Network (Non-Orbit Chains)
|
|
198
198
|
|
|
199
199
|
Once configured, deploy to your target network:
|
|
200
200
|
|
|
@@ -208,6 +208,14 @@ yarn deploy --network <network>
|
|
|
208
208
|
- **Always keep your private key secure and never commit it to version control**
|
|
209
209
|
- Consider using environment variable management tools for production deployments
|
|
210
210
|
|
|
211
|
+
### Deploy to Orbit Chains
|
|
212
|
+
|
|
213
|
+
Before deploying, you would have to ensure that your `deployStylusContract` function on your `deploy.ts` function has the `isOrbit` value set to `true` (example provided in `deploy.ts`).
|
|
214
|
+
|
|
215
|
+
Your contract must have an `initialize()` function as the replacement for the constructor, since not all orbit chains support the constructor feature. Please leave it blank if you don't have any constructor.
|
|
216
|
+
|
|
217
|
+
> Make sure you handle initialization properly in your contract, meaning it should only be called once and functions should not run if contract is not initialized.
|
|
218
|
+
|
|
211
219
|
## Verify your contract (Highly Experimental)
|
|
212
220
|
|
|
213
221
|
<details>
|