create-mn-app 0.3.13 → 0.3.14

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "create-mn-app",
3
- "version": "0.3.13",
3
+ "version": "0.3.14",
4
4
  "description": "Create Midnight Network applications with zero configuration",
5
5
  "main": "dist/index.js",
6
6
  "bin": {
@@ -167,16 +167,63 @@ async function main() {
167
167
  const rl = createInterface({ input: stdin, output: stdout });
168
168
 
169
169
  try {
170
+ // Check for existing deployment.json (previous attempt or completed deployment)
171
+ let existingSeed: string | undefined;
172
+ let existingContract: string | undefined;
173
+
174
+ if (fs.existsSync('deployment.json')) {
175
+ try {
176
+ const existing = JSON.parse(fs.readFileSync('deployment.json', 'utf-8'));
177
+ if (existing.seed) existingSeed = existing.seed;
178
+ if (existing.contractAddress) existingContract = existing.contractAddress;
179
+ } catch {
180
+ // Ignore parse errors
181
+ }
182
+ }
183
+
184
+ // If already deployed, ask if they want to redeploy
185
+ if (existingContract) {
186
+ console.log('─── Existing Deployment Found ──────────────────────────────────\n');
187
+ console.log(` Contract: ${existingContract}`);
188
+ const redeploy = await rl.question('\n Deploy a new contract? [y/N] ');
189
+ if (redeploy.toLowerCase() !== 'y') {
190
+ console.log('\n Run `npm run cli` to interact with your existing contract.\n');
191
+ return;
192
+ }
193
+ existingSeed = undefined; // Fresh deployment = fresh wallet
194
+ }
195
+
170
196
  // 1. Wallet setup
171
197
  console.log('─── Step 1: Wallet Setup ───────────────────────────────────────\n');
172
- const choice = await rl.question(' [1] Create new wallet\n [2] Restore from seed\n > ');
173
-
174
- const seed = choice.trim() === '2'
175
- ? await rl.question('\n Enter your 64-character seed: ')
176
- : toHex(Buffer.from(generateRandomSeed()));
177
198
 
178
- if (choice.trim() !== '2') {
179
- console.log(`\n ⚠️ SAVE THIS SEED (you'll need it later):\n ${seed}\n`);
199
+ let seed: string;
200
+
201
+ if (existingSeed) {
202
+ // Resume from previous failed deployment
203
+ console.log(' Found saved seed from previous attempt.');
204
+ const useSaved = await rl.question(' Use saved wallet? [Y/n] ');
205
+ if (useSaved.toLowerCase() !== 'n') {
206
+ seed = existingSeed;
207
+ console.log(' Using saved wallet...\n');
208
+ } else {
209
+ const choice = await rl.question(' [1] Create new wallet\n [2] Restore from seed\n > ');
210
+ seed = choice.trim() === '2'
211
+ ? await rl.question('\n Enter your 64-character seed: ')
212
+ : toHex(Buffer.from(generateRandomSeed()));
213
+
214
+ if (choice.trim() !== '2') {
215
+ console.log(`\n ⚠️ SAVE THIS SEED (you'll need it later):\n ${seed}\n`);
216
+ }
217
+ }
218
+ } else {
219
+ const choice = await rl.question(' [1] Create new wallet\n [2] Restore from seed\n > ');
220
+ seed = choice.trim() === '2'
221
+ ? await rl.question('\n Enter your 64-character seed: ')
222
+ : toHex(Buffer.from(generateRandomSeed()));
223
+
224
+ if (choice.trim() !== '2') {
225
+ console.log(`\n ⚠️ SAVE THIS SEED (you'll need it later):\n ${seed}\n`);
226
+ }
180
227
  }
181
228
 
182
229
  console.log(' Creating wallet...');
@@ -236,12 +283,67 @@ async function main() {
236
283
  console.log(' Setting up providers...');
237
284
  const providers = await createProviders(walletCtx);
238
285
 
239
- console.log(' Deploying contract (this may take 30-60 seconds)...\n');
240
- const deployed = await deployContract(providers, {
241
- compiledContract,
242
- privateStateId: 'helloWorldState',
243
- initialPrivateState: {},
244
- });
286
+ console.log(' Deploying contract...\n');
287
+
288
+ const MAX_RETRIES = 5;
289
+ const RETRY_DELAY_MS = 30000; // 30 seconds between retries
290
+
291
+ let deployed: Awaited<ReturnType<typeof deployContract>> | undefined;
292
+
293
+ for (let attempt = 1; attempt <= MAX_RETRIES; attempt++) {
294
+ try {
295
+ deployed = await deployContract(providers, {
296
+ compiledContract,
297
+ privateStateId: 'helloWorldState',
298
+ initialPrivateState: {},
299
+ });
300
+ break; // Success - exit retry loop
301
+ } catch (err: any) {
302
+ const errMsg = err?.message || err?.toString() || '';
303
+
304
+ // Check if it's a DUST-related error
305
+ if (errMsg.includes('Not enough Dust') || errMsg.includes('Wallet.Transacting')) {
306
+ if (attempt < MAX_RETRIES) {
307
+ console.log(` ⏳ Waiting for more DUST to generate (attempt ${attempt}/${MAX_RETRIES})...`);
308
+ console.log(' DUST generates as blocks are produced (~30s per block)');
309
+ console.log(` Retrying in ${RETRY_DELAY_MS / 1000}s...\n`);
310
+
311
+ // Countdown display
312
+ for (let i = RETRY_DELAY_MS / 1000; i > 0; i -= 5) {
313
+ await new Promise((r) => setTimeout(r, 5000));
314
+ if (i > 5) process.stdout.write(`\r ${i - 5}s remaining... `);
315
+ }
316
+ process.stdout.write('\r \r');
317
+ } else {
318
+ // All retries exhausted
319
+ console.log(' ❌ Not enough DUST generated yet.\n');
320
+ console.log(' DUST is generated over time as blocks are produced.');
321
+ console.log(' Your wallet and funds are saved - just retry later:\n');
322
+ console.log(' $ npm run deploy\n');
323
+
324
+ // Save partial deployment info so user can resume
325
+ const partialInfo = {
326
+ seed,
327
+ network: 'preprod',
328
+ status: 'pending_dust',
329
+ lastAttempt: new Date().toISOString(),
330
+ };
331
+ fs.writeFileSync('deployment.json', JSON.stringify(partialInfo, null, 2));
332
+ console.log(' Seed saved to deployment.json for retry.\n');
333
+
334
+ await walletCtx.wallet.stop();
335
+ process.exit(1);
336
+ }
337
+ } else {
338
+ // Not a DUST error - rethrow
339
+ throw err;
340
+ }
341
+ }
342
+ }
343
+
344
+ if (!deployed) {
345
+ throw new Error('Deployment failed after all retries');
346
+ }
245
347
 
246
348
  const contractAddress = deployed.deployTxData.public.contractAddress;
247
349
  console.log(' ✅ Contract deployed successfully!\n');