create-stylus 0.1.4 → 0.1.6
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 -5
- package/dist/cli.js.map +1 -1
- package/package.json +11 -2
- package/src/main.ts +11 -2
- package/src/tasks/config-to-sepolia.ts +25 -0
- package/src/tasks/copy-template-files.ts +7 -4
- package/src/tasks/index.ts +1 -0
- package/src/utils/prompt-for-missing-options.ts +1 -1
- package/templates/base/package.json +10 -1
- package/templates/base/packages/nextjs/app/debug/_components/DebugContracts.tsx +15 -5
- package/templates/base/packages/nextjs/app/debug/_components/contract/ContractInput.tsx +3 -3
- package/templates/base/packages/nextjs/app/debug/_components/contract/ContractUI.tsx +104 -28
- package/templates/base/packages/nextjs/app/debug/_components/contract/DisplayVariable.tsx +15 -2
- package/templates/base/packages/nextjs/app/debug/_components/contract/ReadOnlyFunctionForm.tsx +11 -4
- package/templates/base/packages/nextjs/app/debug/_components/contract/TxReceipt.tsx +37 -21
- package/templates/base/packages/nextjs/app/debug/_components/contract/WriteOnlyFunctionForm.tsx +26 -20
- package/templates/base/packages/nextjs/app/layout.tsx +10 -4
- package/templates/base/packages/nextjs/components/AngularBorder.tsx +41 -0
- package/templates/base/packages/nextjs/components/Footer.tsx +153 -44
- package/templates/base/packages/nextjs/components/Header.tsx +73 -10
- package/templates/base/packages/nextjs/components/SwitchTheme.tsx +34 -3
- package/templates/base/packages/nextjs/components/scaffold-eth/Faucet.tsx +40 -5
- package/templates/base/packages/nextjs/components/scaffold-eth/Input/AddressInput.tsx +1 -9
- package/templates/base/packages/nextjs/components/scaffold-eth/Input/InputBase.tsx +1 -1
- package/templates/base/packages/nextjs/components/scaffold-eth/Input/IntegerInput.tsx +35 -25
- package/templates/base/packages/nextjs/components/scaffold-eth/RainbowKitCustomConnectButton/AddressInfoDropdown.tsx +138 -24
- package/templates/base/packages/nextjs/components/scaffold-eth/RainbowKitCustomConnectButton/RevealBurnerPKModal.tsx +59 -0
- package/templates/base/packages/nextjs/components/scaffold-eth/RainbowKitCustomConnectButton/index.tsx +2 -0
- package/templates/base/packages/nextjs/contracts/deployedContracts.ts +117 -1
- package/templates/base/packages/nextjs/hooks/scaffold-eth/useScaffoldEventHistory.ts +107 -28
- package/templates/base/packages/nextjs/hooks/scaffold-eth/useScaffoldWriteContract.ts +5 -1
- package/templates/base/packages/nextjs/hooks/scaffold-eth/useTransactor.tsx +7 -5
- package/templates/base/packages/nextjs/icons/EthIcon.tsx +28 -0
- package/templates/base/packages/nextjs/icons/LightBugAntIcon.tsx +7 -7
- package/templates/base/packages/nextjs/package.json +13 -5
- package/templates/base/packages/nextjs/public/logo.svg +20 -7
- package/templates/base/packages/nextjs/services/web3/wagmiConnectors.tsx +1 -0
- package/templates/base/packages/nextjs/styles/globals.css +339 -2
- package/templates/base/packages/nextjs/tailwind.config.js +2 -1
- package/templates/base/packages/nextjs/utils/scaffold-eth/contract.ts +74 -2
- package/templates/base/packages/nextjs/utils/scaffold-stylus/supportedChains.ts +1 -1
- package/templates/base/packages/stylus/package.json +9 -0
- package/templates/base/packages/stylus/scripts/deploy.ts +0 -8
- package/templates/base/packages/stylus/scripts/deploy_contract.ts +1 -0
- package/templates/base/packages/stylus/scripts/test_network.ts +6 -7
- package/templates/base/packages/stylus/scripts/utils/contract.ts +6 -2
- package/templates/base/packages/stylus/scripts/utils/deployment.ts +1 -0
- package/templates/base/packages/stylus/scripts/utils/network.ts +23 -5
- package/templates/base/packages/stylus/your-contract/Cargo.lock +4 -4
- package/templates/base/packages/stylus/your-contract/Cargo.toml +1 -1
- package/templates/base/packages/stylus/your-contract/src/lib.rs +3 -7
- package/templates/base/readme.md +55 -169
- package/templates/base/yarn.lock +1058 -1128
- package/templates/base/packages/stylus/counter/.cargo/config.toml +0 -18
- package/templates/base/packages/stylus/counter/Cargo.lock +0 -5788
- package/templates/base/packages/stylus/counter/Cargo.toml +0 -46
- package/templates/base/packages/stylus/counter/rust-toolchain.toml +0 -2
- package/templates/base/packages/stylus/counter/src/lib.rs +0 -121
- package/templates/base/packages/stylus/counter/src/main.rs +0 -10
|
@@ -24,11 +24,13 @@ p {
|
|
|
24
24
|
}
|
|
25
25
|
|
|
26
26
|
.btn {
|
|
27
|
-
|
|
27
|
+
box-shadow:
|
|
28
|
+
0 4px 6px -1px rgb(0 0 0 / 0.1),
|
|
29
|
+
0 2px 4px -2px rgb(0 0 0 / 0.1);
|
|
28
30
|
}
|
|
29
31
|
|
|
30
32
|
.btn.btn-ghost {
|
|
31
|
-
|
|
33
|
+
box-shadow: none;
|
|
32
34
|
}
|
|
33
35
|
|
|
34
36
|
.border-color {
|
|
@@ -87,3 +89,338 @@ p {
|
|
|
87
89
|
linear-gradient(270deg, #e3066e 0%, #203147 108.63%) padding-box,
|
|
88
90
|
linear-gradient(90deg, var(--gradient-start) 0%, var(--gradient-end) 100%) border-box;
|
|
89
91
|
}
|
|
92
|
+
|
|
93
|
+
/* Figma Design Variables */
|
|
94
|
+
:root {
|
|
95
|
+
--spacing-md: 8px;
|
|
96
|
+
--spacing-lg: 12px;
|
|
97
|
+
--spacing-xl: 16px;
|
|
98
|
+
--spacing-2xl: 16px;
|
|
99
|
+
--spacing-4xl: 24px;
|
|
100
|
+
--spacing-7xl: 40px;
|
|
101
|
+
--stroke-sub-20: rgba(255, 255, 255, 0.2);
|
|
102
|
+
--bg-surface-surface-40: rgba(2, 2, 2, 0.4);
|
|
103
|
+
--bg-surface-input-20: rgba(255, 255, 255, 0.04);
|
|
104
|
+
--text-sub-600: rgba(255, 255, 255, 0.6);
|
|
105
|
+
--text-soft-400: rgba(255, 255, 255, 0.4);
|
|
106
|
+
--text-strong-950: #ffffff;
|
|
107
|
+
--figma-pink: #ff50a2;
|
|
108
|
+
--figma-sky-blue: #30b4ed;
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
/* Contract Card Styles */
|
|
112
|
+
.contract-card {
|
|
113
|
+
display: flex;
|
|
114
|
+
padding: var(--spacing-4xl, 24px);
|
|
115
|
+
flex-direction: column;
|
|
116
|
+
justify-content: center;
|
|
117
|
+
align-items: center;
|
|
118
|
+
gap: var(--spacing-4xl, 24px);
|
|
119
|
+
align-self: stretch;
|
|
120
|
+
border-radius: var(--spacing-2xl, 16px);
|
|
121
|
+
border: 1px solid var(--stroke-sub-20, rgba(255, 255, 255, 0.2));
|
|
122
|
+
background: var(--bg-surface-surface-40, rgba(2, 2, 2, 0.4));
|
|
123
|
+
backdrop-filter: blur(25px);
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
.contract-title {
|
|
127
|
+
color: var(--figma-sky-blue);
|
|
128
|
+
font-size: 1.25rem;
|
|
129
|
+
font-weight: bold;
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
.contract-address {
|
|
133
|
+
color: white;
|
|
134
|
+
font-size: 0.875rem;
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
.contract-label {
|
|
138
|
+
color: white;
|
|
139
|
+
font-weight: bold;
|
|
140
|
+
font-size: 0.875rem;
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
.contract-value {
|
|
144
|
+
color: var(--figma-pink);
|
|
145
|
+
font-size: 0.875rem;
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
.variable-name {
|
|
149
|
+
color: var(--figma-sky-blue);
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
[data-theme="light"] .variable-name {
|
|
153
|
+
color: rgba(24, 24, 24, 1);
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
/* Reusable Typography */
|
|
157
|
+
.typography-uppercase {
|
|
158
|
+
color: var(--text-sub-600, rgba(255, 255, 255, 0.6));
|
|
159
|
+
text-align: center;
|
|
160
|
+
font-family: var(--font-orbitron), sans-serif;
|
|
161
|
+
font-size: 14px;
|
|
162
|
+
font-style: normal;
|
|
163
|
+
font-weight: 700;
|
|
164
|
+
line-height: normal;
|
|
165
|
+
letter-spacing: -0.28px;
|
|
166
|
+
text-transform: uppercase;
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
/* Tab Container */
|
|
170
|
+
.tab-container {
|
|
171
|
+
border-radius: var(--spacing-md, 8px);
|
|
172
|
+
background: var(--bg-surface-input-20, rgba(255, 255, 255, 0.04));
|
|
173
|
+
backdrop-filter: blur(25px);
|
|
174
|
+
padding: 4px;
|
|
175
|
+
display: flex;
|
|
176
|
+
gap: 4px;
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
/* Tab Button */
|
|
180
|
+
.tab-button {
|
|
181
|
+
flex: 1;
|
|
182
|
+
padding: 8px 16px;
|
|
183
|
+
border-radius: var(--spacing-md, 8px);
|
|
184
|
+
background: transparent;
|
|
185
|
+
border: none;
|
|
186
|
+
cursor: pointer;
|
|
187
|
+
transition: all 0.2s ease;
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
.tab-button.active {
|
|
191
|
+
background: white;
|
|
192
|
+
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
[data-theme="light"] .tab-button.active {
|
|
196
|
+
background: linear-gradient(180deg, rgba(255, 255, 255, 1) 0%, rgba(213, 213, 213, 1) 100%);
|
|
197
|
+
box-shadow: 0 2px 4px rgba(171, 171, 171, 1);
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
.tab-button.active .tab-text {
|
|
201
|
+
color: #333;
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
.tab-button:not(.active) .tab-text {
|
|
205
|
+
color: var(--text-sub-600, rgba(255, 255, 255, 0.6));
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
/* Function Styling */
|
|
209
|
+
.function-name {
|
|
210
|
+
color: var(--figma-sky-blue);
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
.param-type {
|
|
214
|
+
color: var(--text-sub-600, rgba(255, 255, 255, 0.6));
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
[data-theme="light"] .param-name {
|
|
218
|
+
color: rgba(24, 24, 24, 1);
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
/* Input Styling */
|
|
222
|
+
.input-container {
|
|
223
|
+
padding: var(--spacing-lg, 12px) var(--spacing-xl, 16px);
|
|
224
|
+
align-items: center;
|
|
225
|
+
gap: 8px;
|
|
226
|
+
align-self: stretch;
|
|
227
|
+
border-radius: var(--spacing-md, 8px);
|
|
228
|
+
background: var(--bg-surface-input-20, rgba(255, 255, 255, 0.04));
|
|
229
|
+
backdrop-filter: blur(25px);
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
/* Light mode input styling */
|
|
233
|
+
[data-theme="light"] .input-container {
|
|
234
|
+
background: rgba(0, 0, 0, 0.04);
|
|
235
|
+
backdrop-filter: none;
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
.input-text {
|
|
239
|
+
color: var(--text-soft-400, rgba(255, 255, 255, 0.4));
|
|
240
|
+
text-align: center;
|
|
241
|
+
font-family: Inter, sans-serif;
|
|
242
|
+
font-size: 14px;
|
|
243
|
+
font-style: normal;
|
|
244
|
+
font-weight: 500;
|
|
245
|
+
line-height: 20px;
|
|
246
|
+
letter-spacing: -0.14px;
|
|
247
|
+
}
|
|
248
|
+
|
|
249
|
+
/* Light mode input text styling */
|
|
250
|
+
[data-theme="light"] .input-text {
|
|
251
|
+
color: rgba(24, 24, 24, 0.4);
|
|
252
|
+
}
|
|
253
|
+
|
|
254
|
+
/* Input field overrides */
|
|
255
|
+
.input-container .flex.border-2.border-base-300.bg-base-200.rounded-full {
|
|
256
|
+
border-radius: var(--spacing-md, 8px) !important;
|
|
257
|
+
background: var(--bg-surface-input-20, rgba(255, 255, 255, 0.04)) !important;
|
|
258
|
+
backdrop-filter: blur(25px) !important;
|
|
259
|
+
border: none !important;
|
|
260
|
+
padding: var(--spacing-lg, 12px) var(--spacing-xl, 16px) !important;
|
|
261
|
+
gap: 8px !important;
|
|
262
|
+
align-items: center !important;
|
|
263
|
+
align-self: stretch !important;
|
|
264
|
+
}
|
|
265
|
+
|
|
266
|
+
/* Light mode input field overrides */
|
|
267
|
+
[data-theme="light"] .input-container .flex.border-2.border-base-300.bg-base-200.rounded-full {
|
|
268
|
+
background: rgba(0, 0, 0, 0.04) !important;
|
|
269
|
+
backdrop-filter: none !important;
|
|
270
|
+
}
|
|
271
|
+
|
|
272
|
+
.input-container .input.input-ghost {
|
|
273
|
+
background: transparent !important;
|
|
274
|
+
border: none !important;
|
|
275
|
+
color: white !important;
|
|
276
|
+
font-family: Inter, sans-serif !important;
|
|
277
|
+
font-size: 14px !important;
|
|
278
|
+
font-weight: 500 !important;
|
|
279
|
+
line-height: 20px !important;
|
|
280
|
+
letter-spacing: -0.14px !important;
|
|
281
|
+
text-align: left !important;
|
|
282
|
+
padding: 0 !important;
|
|
283
|
+
height: auto !important;
|
|
284
|
+
min-height: auto !important;
|
|
285
|
+
flex: 1 !important;
|
|
286
|
+
box-shadow: none !important;
|
|
287
|
+
outline: none !important;
|
|
288
|
+
}
|
|
289
|
+
|
|
290
|
+
/* Light mode input text color */
|
|
291
|
+
[data-theme="light"] .input-container .input.input-ghost {
|
|
292
|
+
color: rgba(24, 24, 24, 0.4) !important;
|
|
293
|
+
}
|
|
294
|
+
|
|
295
|
+
.input-container .input.input-ghost:focus,
|
|
296
|
+
.input-container .input.input-ghost::placeholder {
|
|
297
|
+
background: transparent !important;
|
|
298
|
+
border: none !important;
|
|
299
|
+
box-shadow: none !important;
|
|
300
|
+
outline: none !important;
|
|
301
|
+
color: var(--text-soft-400, rgba(255, 255, 255, 0.4)) !important;
|
|
302
|
+
font-family: Inter, sans-serif !important;
|
|
303
|
+
font-size: 14px !important;
|
|
304
|
+
font-weight: 500 !important;
|
|
305
|
+
line-height: 20px !important;
|
|
306
|
+
letter-spacing: -0.14px !important;
|
|
307
|
+
}
|
|
308
|
+
|
|
309
|
+
/* Light mode input placeholder and focus color */
|
|
310
|
+
[data-theme="light"] .input-container .input.input-ghost::placeholder {
|
|
311
|
+
color: rgba(24, 24, 24, 0.4) !important;
|
|
312
|
+
}
|
|
313
|
+
|
|
314
|
+
/* Input text color when typing - light mode */
|
|
315
|
+
[data-theme="light"] .input-container .input.input-ghost:focus,
|
|
316
|
+
[data-theme="light"] .input-container .input.input-ghost:not(:placeholder-shown) {
|
|
317
|
+
color: rgba(24, 24, 24, 1) !important;
|
|
318
|
+
}
|
|
319
|
+
|
|
320
|
+
/* Input text color when typing - dark mode */
|
|
321
|
+
[data-theme="dark"] .input-container .input.input-ghost:focus,
|
|
322
|
+
[data-theme="dark"] .input-container .input.input-ghost:not(:placeholder-shown) {
|
|
323
|
+
color: white !important;
|
|
324
|
+
}
|
|
325
|
+
|
|
326
|
+
/* Button Styles */
|
|
327
|
+
.send-button {
|
|
328
|
+
display: flex;
|
|
329
|
+
padding: 8px var(--spacing-7xl, 40px);
|
|
330
|
+
justify-content: center;
|
|
331
|
+
align-items: center;
|
|
332
|
+
gap: 10px;
|
|
333
|
+
border-radius: var(--spacing-md, 8px);
|
|
334
|
+
background: linear-gradient(180deg, #fc3592 0%, #e3066e 100%);
|
|
335
|
+
color: var(--text-strong-950, #fff);
|
|
336
|
+
text-align: center;
|
|
337
|
+
font-family: var(--font-orbitron), sans-serif;
|
|
338
|
+
font-size: 14px;
|
|
339
|
+
font-style: normal;
|
|
340
|
+
font-weight: 700;
|
|
341
|
+
line-height: normal;
|
|
342
|
+
letter-spacing: -0.28px;
|
|
343
|
+
text-transform: uppercase;
|
|
344
|
+
border: none;
|
|
345
|
+
cursor: pointer;
|
|
346
|
+
transition: all 0.2s ease;
|
|
347
|
+
position: relative;
|
|
348
|
+
box-shadow:
|
|
349
|
+
0 2px 0 #ff9ccb,
|
|
350
|
+
0 4px 8px rgba(255, 156, 203, 0.3);
|
|
351
|
+
}
|
|
352
|
+
|
|
353
|
+
.send-button:hover {
|
|
354
|
+
opacity: 0.9;
|
|
355
|
+
transform: translateY(-1px);
|
|
356
|
+
}
|
|
357
|
+
|
|
358
|
+
.send-button:disabled {
|
|
359
|
+
opacity: 0.6;
|
|
360
|
+
cursor: not-allowed;
|
|
361
|
+
transform: none;
|
|
362
|
+
}
|
|
363
|
+
|
|
364
|
+
.read-button {
|
|
365
|
+
display: flex;
|
|
366
|
+
padding: 8px var(--spacing-7xl, 40px);
|
|
367
|
+
justify-content: center;
|
|
368
|
+
align-items: center;
|
|
369
|
+
gap: 10px;
|
|
370
|
+
border-radius: var(--spacing-md, 8px);
|
|
371
|
+
background: linear-gradient(180deg, #fc3592 0%, #e3066e 100%);
|
|
372
|
+
color: var(--text-strong-950, #fff);
|
|
373
|
+
text-align: center;
|
|
374
|
+
font-family: var(--font-orbitron), sans-serif;
|
|
375
|
+
font-size: 14px;
|
|
376
|
+
font-style: normal;
|
|
377
|
+
font-weight: 700;
|
|
378
|
+
line-height: normal;
|
|
379
|
+
letter-spacing: -0.28px;
|
|
380
|
+
text-transform: uppercase;
|
|
381
|
+
border: none;
|
|
382
|
+
cursor: pointer;
|
|
383
|
+
transition: all 0.2s ease;
|
|
384
|
+
position: relative;
|
|
385
|
+
box-shadow:
|
|
386
|
+
0 2px 0 #ff9ccb,
|
|
387
|
+
0 4px 8px rgba(255, 156, 203, 0.3);
|
|
388
|
+
margin-left: auto;
|
|
389
|
+
}
|
|
390
|
+
|
|
391
|
+
.read-button:hover {
|
|
392
|
+
opacity: 0.9;
|
|
393
|
+
transform: translateY(-1px);
|
|
394
|
+
}
|
|
395
|
+
|
|
396
|
+
.read-button:disabled {
|
|
397
|
+
opacity: 0.6;
|
|
398
|
+
cursor: not-allowed;
|
|
399
|
+
transform: none;
|
|
400
|
+
}
|
|
401
|
+
|
|
402
|
+
/* Typography Utilities */
|
|
403
|
+
.text-inter {
|
|
404
|
+
font-family: Inter, sans-serif;
|
|
405
|
+
}
|
|
406
|
+
|
|
407
|
+
.text-inter-14 {
|
|
408
|
+
font-family: Inter, sans-serif;
|
|
409
|
+
font-size: 14px;
|
|
410
|
+
font-weight: 500;
|
|
411
|
+
line-height: 20px;
|
|
412
|
+
letter-spacing: -0.14px;
|
|
413
|
+
}
|
|
414
|
+
|
|
415
|
+
/* Contract Tab Button Styles */
|
|
416
|
+
.contract-tab-button {
|
|
417
|
+
padding: 8px 16px;
|
|
418
|
+
border-radius: 9999px;
|
|
419
|
+
font-family: Inter, sans-serif;
|
|
420
|
+
font-weight: 500;
|
|
421
|
+
transition: all 0.2s ease;
|
|
422
|
+
cursor: pointer;
|
|
423
|
+
display: flex;
|
|
424
|
+
align-items: center;
|
|
425
|
+
gap: 8px;
|
|
426
|
+
}
|
|
@@ -88,7 +88,8 @@ module.exports = {
|
|
|
88
88
|
theme: {
|
|
89
89
|
extend: {
|
|
90
90
|
fontFamily: {
|
|
91
|
-
sans: ["var(--font-
|
|
91
|
+
sans: ["var(--font-inter)", "system-ui", "sans-serif"],
|
|
92
|
+
orbitron: ["var(--font-orbitron)", "sans-serif"],
|
|
92
93
|
},
|
|
93
94
|
boxShadow: {
|
|
94
95
|
center: "0 0 12px -2px rgb(0 0 0 / 0.05)",
|
|
@@ -23,6 +23,8 @@ import {
|
|
|
23
23
|
Log,
|
|
24
24
|
TransactionReceipt,
|
|
25
25
|
WriteContractErrorType,
|
|
26
|
+
keccak256,
|
|
27
|
+
toHex,
|
|
26
28
|
} from "viem";
|
|
27
29
|
import { Config, UseReadContractParameters, UseWatchContractEventParameters, UseWriteContractParameters } from "wagmi";
|
|
28
30
|
import { WriteContractParameters, WriteContractReturnType, simulateContract } from "wagmi/actions";
|
|
@@ -292,7 +294,7 @@ export type UseScaffoldEventHistoryConfig<
|
|
|
292
294
|
> = {
|
|
293
295
|
contractName: TContractName;
|
|
294
296
|
eventName: IsContractDeclarationMissing<string, TEventName>;
|
|
295
|
-
fromBlock
|
|
297
|
+
fromBlock?: bigint;
|
|
296
298
|
toBlock?: bigint;
|
|
297
299
|
chainId?: AllowedChainIds;
|
|
298
300
|
filters?: EventFilters<TContractName, TEventName>;
|
|
@@ -335,17 +337,87 @@ export type UseScaffoldEventHistoryData<
|
|
|
335
337
|
|
|
336
338
|
export type AbiParameterTuple = Extract<AbiParameter, { type: "tuple" | `tuple[${string}]` }>;
|
|
337
339
|
|
|
340
|
+
/**
|
|
341
|
+
* Enhanced error parsing that creates a lookup table from all deployed contracts
|
|
342
|
+
* to decode error signatures from any contract in the system
|
|
343
|
+
*/
|
|
344
|
+
export const getParsedErrorWithAllAbis = (error: any, chainId: AllowedChainIds): string => {
|
|
345
|
+
const originalParsedError = getParsedError(error);
|
|
346
|
+
|
|
347
|
+
// Check if this is an unrecognized error signature
|
|
348
|
+
if (/Encoded error signature.*not found on ABI/i.test(originalParsedError)) {
|
|
349
|
+
const signatureMatch = originalParsedError.match(/0x[a-fA-F0-9]{8}/);
|
|
350
|
+
const signature = signatureMatch ? signatureMatch[0] : "";
|
|
351
|
+
|
|
352
|
+
if (!signature) {
|
|
353
|
+
return originalParsedError;
|
|
354
|
+
}
|
|
355
|
+
|
|
356
|
+
try {
|
|
357
|
+
// Get all deployed contracts for the current chain
|
|
358
|
+
const chainContracts = (deployedContractsData as GenericContractsDeclaration)[chainId];
|
|
359
|
+
|
|
360
|
+
if (!chainContracts) {
|
|
361
|
+
return originalParsedError;
|
|
362
|
+
}
|
|
363
|
+
|
|
364
|
+
// Build a lookup table of error signatures to error names
|
|
365
|
+
const errorLookup: Record<string, { name: string; contract: string; signature: string }> = {};
|
|
366
|
+
|
|
367
|
+
Object.entries(chainContracts).forEach(([contractName, contract]: [string, any]) => {
|
|
368
|
+
if (contract.abi) {
|
|
369
|
+
contract.abi.forEach((item: any) => {
|
|
370
|
+
if (item.type === "error") {
|
|
371
|
+
// Create the proper error signature like Solidity does
|
|
372
|
+
const errorName = item.name;
|
|
373
|
+
const inputs = item.inputs || [];
|
|
374
|
+
const inputTypes = inputs.map((input: any) => input.type).join(",");
|
|
375
|
+
const errorSignature = `${errorName}(${inputTypes})`;
|
|
376
|
+
|
|
377
|
+
// Hash the signature and take the first 4 bytes (8 hex chars)
|
|
378
|
+
const hash = keccak256(toHex(errorSignature));
|
|
379
|
+
const errorSelector = hash.slice(0, 10); // 0x + 8 chars = 10 total
|
|
380
|
+
|
|
381
|
+
errorLookup[errorSelector] = {
|
|
382
|
+
name: errorName,
|
|
383
|
+
contract: contractName,
|
|
384
|
+
signature: errorSignature,
|
|
385
|
+
};
|
|
386
|
+
}
|
|
387
|
+
});
|
|
388
|
+
}
|
|
389
|
+
});
|
|
390
|
+
|
|
391
|
+
// Check if we can find the error in our lookup
|
|
392
|
+
const errorInfo = errorLookup[signature];
|
|
393
|
+
if (errorInfo) {
|
|
394
|
+
return `Contract function execution reverted with the following reason:\n${errorInfo.signature} from ${errorInfo.contract} contract`;
|
|
395
|
+
}
|
|
396
|
+
|
|
397
|
+
// If not found in simple lookup, provide a helpful message with context
|
|
398
|
+
return `${originalParsedError}\n\nThis error occurred when calling a function that internally calls another contract. Check the contract that your function calls internally for more details.`;
|
|
399
|
+
} catch (lookupError) {
|
|
400
|
+
console.log("Failed to create error lookup table:", lookupError);
|
|
401
|
+
}
|
|
402
|
+
}
|
|
403
|
+
|
|
404
|
+
return originalParsedError;
|
|
405
|
+
};
|
|
406
|
+
|
|
338
407
|
export const simulateContractWriteAndNotifyError = async ({
|
|
339
408
|
wagmiConfig,
|
|
340
409
|
writeContractParams: params,
|
|
410
|
+
chainId,
|
|
341
411
|
}: {
|
|
342
412
|
wagmiConfig: Config;
|
|
343
413
|
writeContractParams: WriteContractVariables<Abi, string, any[], Config, number>;
|
|
414
|
+
chainId: AllowedChainIds;
|
|
344
415
|
}) => {
|
|
345
416
|
try {
|
|
346
417
|
await simulateContract(wagmiConfig, params);
|
|
347
418
|
} catch (error) {
|
|
348
|
-
const parsedError =
|
|
419
|
+
const parsedError = getParsedErrorWithAllAbis(error, chainId);
|
|
420
|
+
|
|
349
421
|
notification.error(parsedError);
|
|
350
422
|
throw error;
|
|
351
423
|
}
|
|
@@ -25,6 +25,15 @@
|
|
|
25
25
|
],
|
|
26
26
|
"author": "",
|
|
27
27
|
"license": "MIT",
|
|
28
|
+
"overrides": {
|
|
29
|
+
"chalk": "5.3.0",
|
|
30
|
+
"strip-ansi": "7.1.0",
|
|
31
|
+
"color-convert": "2.0.1",
|
|
32
|
+
"color-name": "1.1.4",
|
|
33
|
+
"is-core-module": "2.13.1",
|
|
34
|
+
"error-ex": "1.3.2",
|
|
35
|
+
"has-ansi": "5.0.1"
|
|
36
|
+
},
|
|
28
37
|
"devDependencies": {
|
|
29
38
|
"@types/node": "^20.0.0",
|
|
30
39
|
"@types/yargs": "^17.0.32",
|
|
@@ -36,14 +36,6 @@ export default async function deployScript(deployOptions: DeployOptions) {
|
|
|
36
36
|
...deployOptions,
|
|
37
37
|
});
|
|
38
38
|
|
|
39
|
-
// EXAMPLE: Deploy to Orbit Chains, uncomment to try
|
|
40
|
-
// await deployStylusContract({
|
|
41
|
-
// contract: "counter",
|
|
42
|
-
// constructorArgs: [100],
|
|
43
|
-
// isOrbit: true,
|
|
44
|
-
// ...deployOptions,
|
|
45
|
-
// });
|
|
46
|
-
|
|
47
39
|
// EXAMPLE: Deploy your contract with a custom name, uncomment to try
|
|
48
40
|
// await deployStylusContract({
|
|
49
41
|
// contract: "your-contract",
|
|
@@ -110,6 +110,7 @@ export default async function deployStylusContract(
|
|
|
110
110
|
address: deploymentInfo.address,
|
|
111
111
|
abi: contractData.abi as Abi,
|
|
112
112
|
functionName: "initialize",
|
|
113
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
113
114
|
args: deployOptions.constructorArgs as any[],
|
|
114
115
|
});
|
|
115
116
|
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { getChain, getRpcUrlFromChain } from "./utils/";
|
|
1
|
+
import { getChain, getRpcUrlFromChain, ALIASES } from "./utils/";
|
|
2
2
|
import { SUPPORTED_NETWORKS } from "./utils/";
|
|
3
3
|
|
|
4
4
|
function testNetworkFunctionality() {
|
|
@@ -18,14 +18,13 @@ function testNetworkFunctionality() {
|
|
|
18
18
|
console.log("\n📝 Usage examples:");
|
|
19
19
|
Object.keys(SUPPORTED_NETWORKS).forEach((network) => {
|
|
20
20
|
const chain = getChain(network);
|
|
21
|
+
// Find the alias for this network (reverse lookup)
|
|
22
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
23
|
+
const alias = Object.entries(ALIASES).find(([_, value]) => value === network)?.[0];
|
|
24
|
+
const networkName = alias || network;
|
|
21
25
|
console.log(
|
|
22
|
-
` yarn deploy --network ${
|
|
26
|
+
` yarn deploy --network ${networkName}\t# Deploy to ${chain?.name}`,
|
|
23
27
|
);
|
|
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
|
-
// );
|
|
29
28
|
});
|
|
30
29
|
}
|
|
31
30
|
|
|
@@ -27,6 +27,7 @@ export function getContractNameFromCargoToml(contractFolder: string): string {
|
|
|
27
27
|
);
|
|
28
28
|
}
|
|
29
29
|
const tomlContent = fs.readFileSync(cargoTomlPath, "utf8");
|
|
30
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
30
31
|
let parsed: any;
|
|
31
32
|
try {
|
|
32
33
|
parsed = toml.parse(tomlContent);
|
|
@@ -163,6 +164,7 @@ export async function generateTsAbi(
|
|
|
163
164
|
abi: abiJson,
|
|
164
165
|
};
|
|
165
166
|
|
|
167
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
166
168
|
let deployedContractsObj: any = {};
|
|
167
169
|
const fileHeader = generatedContractComment + "\n\n";
|
|
168
170
|
|
|
@@ -240,7 +242,7 @@ export function handleSolcError(
|
|
|
240
242
|
* This is useful when the file has been updated during runtime
|
|
241
243
|
* @returns The deployed contracts object
|
|
242
244
|
*/
|
|
243
|
-
export function loadDeployedContracts()
|
|
245
|
+
export function loadDeployedContracts() {
|
|
244
246
|
const deployedContractsPath = "../nextjs/contracts/deployedContracts.ts";
|
|
245
247
|
|
|
246
248
|
if (!fs.existsSync(deployedContractsPath)) {
|
|
@@ -266,7 +268,7 @@ export function loadDeployedContracts(): any {
|
|
|
266
268
|
* @param contractName - The contract name
|
|
267
269
|
* @returns The contract data with address, txHash, and abi
|
|
268
270
|
*/
|
|
269
|
-
export function getContractData(chainId: string, contractName: string)
|
|
271
|
+
export function getContractData(chainId: string, contractName: string) {
|
|
270
272
|
const deployedContracts = loadDeployedContracts();
|
|
271
273
|
|
|
272
274
|
if (
|
|
@@ -289,6 +291,8 @@ export function getContractData(chainId: string, contractName: string): any {
|
|
|
289
291
|
return contractData;
|
|
290
292
|
}
|
|
291
293
|
|
|
294
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
292
295
|
export function contractHasInitializeFunction(contractData: any): boolean {
|
|
296
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
293
297
|
return contractData.abi.some((abi: any) => abi.name === "initialize");
|
|
294
298
|
}
|
|
@@ -104,6 +104,7 @@ export function saveDeployment(
|
|
|
104
104
|
}
|
|
105
105
|
|
|
106
106
|
// Read existing deployments or start fresh
|
|
107
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
107
108
|
let deployments: Record<string, any> = {};
|
|
108
109
|
if (fs.existsSync(networkPath)) {
|
|
109
110
|
const content = fs.readFileSync(networkPath, "utf8");
|
|
@@ -32,10 +32,10 @@ export const ALIASES: Record<string, string> = {
|
|
|
32
32
|
sepolia: "arbitrumSepolia",
|
|
33
33
|
devnet: "arbitrumNitro",
|
|
34
34
|
nova: "arbitrumNova",
|
|
35
|
-
|
|
35
|
+
educhainTesnet: "eduChainTestnet",
|
|
36
36
|
educhain: "eduChain",
|
|
37
37
|
superposition: "superposition",
|
|
38
|
-
|
|
38
|
+
superpositionTestnet: "superpositionTestnet",
|
|
39
39
|
};
|
|
40
40
|
|
|
41
41
|
// TODO: add more compatible Orbit Chains here
|
|
@@ -48,7 +48,13 @@ export const ORBIT_CHAINS: Chain[] = [
|
|
|
48
48
|
|
|
49
49
|
export function getChain(networkName: string): Chain | null {
|
|
50
50
|
try {
|
|
51
|
-
|
|
51
|
+
// First try exact match (for camelCase aliases)
|
|
52
|
+
let actualNetworkName = ALIASES[networkName] || networkName;
|
|
53
|
+
|
|
54
|
+
// If no exact match, try lowercase match (for backward compatibility)
|
|
55
|
+
if (actualNetworkName === networkName) {
|
|
56
|
+
actualNetworkName = ALIASES[networkName.toLowerCase()] || networkName;
|
|
57
|
+
}
|
|
52
58
|
|
|
53
59
|
const chainEntry = Object.entries(SUPPORTED_NETWORKS).find(
|
|
54
60
|
([key]) => key.toLowerCase() === actualNetworkName.toLowerCase(),
|
|
@@ -68,7 +74,13 @@ export function getChain(networkName: string): Chain | null {
|
|
|
68
74
|
}
|
|
69
75
|
|
|
70
76
|
export function getPrivateKey(networkName: string): string {
|
|
71
|
-
|
|
77
|
+
// First try exact match (for camelCase aliases)
|
|
78
|
+
let actualNetworkName = ALIASES[networkName] || networkName;
|
|
79
|
+
|
|
80
|
+
// If no exact match, try lowercase match (for backward compatibility)
|
|
81
|
+
if (actualNetworkName === networkName) {
|
|
82
|
+
actualNetworkName = ALIASES[networkName.toLowerCase()] || networkName;
|
|
83
|
+
}
|
|
72
84
|
|
|
73
85
|
switch (actualNetworkName.toLowerCase()) {
|
|
74
86
|
case "arbitrum":
|
|
@@ -122,7 +134,13 @@ export function getPrivateKey(networkName: string): string {
|
|
|
122
134
|
}
|
|
123
135
|
|
|
124
136
|
export const getAccountAddress = (networkName: string): Address | undefined => {
|
|
125
|
-
|
|
137
|
+
// First try exact match (for camelCase aliases)
|
|
138
|
+
let actualNetworkName = ALIASES[networkName] || networkName;
|
|
139
|
+
|
|
140
|
+
// If no exact match, try lowercase match (for backward compatibility)
|
|
141
|
+
if (actualNetworkName === networkName) {
|
|
142
|
+
actualNetworkName = ALIASES[networkName.toLowerCase()] || networkName;
|
|
143
|
+
}
|
|
126
144
|
|
|
127
145
|
switch (actualNetworkName.toLowerCase()) {
|
|
128
146
|
case "arbitrum":
|
|
@@ -3066,9 +3066,9 @@ dependencies = [
|
|
|
3066
3066
|
|
|
3067
3067
|
[[package]]
|
|
3068
3068
|
name = "openzeppelin-stylus"
|
|
3069
|
-
version = "0.
|
|
3069
|
+
version = "0.3.0"
|
|
3070
3070
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
3071
|
-
checksum = "
|
|
3071
|
+
checksum = "cef3971d2d38f992397ed222826d213489f19a4b1936ac482fb5fa23926a4fd4"
|
|
3072
3072
|
dependencies = [
|
|
3073
3073
|
"alloy-primitives",
|
|
3074
3074
|
"alloy-sol-macro",
|
|
@@ -3082,9 +3082,9 @@ dependencies = [
|
|
|
3082
3082
|
|
|
3083
3083
|
[[package]]
|
|
3084
3084
|
name = "openzeppelin-stylus-proc"
|
|
3085
|
-
version = "0.
|
|
3085
|
+
version = "0.3.0"
|
|
3086
3086
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
3087
|
-
checksum = "
|
|
3087
|
+
checksum = "e070fcdfd2bc4cd6dcd32d61797467439277d7cc8e7eea73dd42c7ccd22b0e1d"
|
|
3088
3088
|
dependencies = [
|
|
3089
3089
|
"convert_case",
|
|
3090
3090
|
"proc-macro2",
|
|
@@ -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 = "
|
|
16
|
+
openzeppelin-stylus = "0.3.0"
|
|
17
17
|
|
|
18
18
|
[dev-dependencies]
|
|
19
19
|
alloy-primitives = { version = "=0.8.20", features = ["sha3-keccak"] }
|