@dawnai/cli 1.0.6 → 1.0.8

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/index.js CHANGED
@@ -6,7 +6,7 @@ import path from 'node:path';
6
6
  import process from 'node:process';
7
7
  import { spawn } from 'node:child_process';
8
8
  import { fileURLToPath } from 'node:url';
9
- const CLI_VERSION = '1.0.6';
9
+ const CLI_VERSION = '1.0.8';
10
10
  const DAWN_API_BASE_URL = 'https://api.dawn.ai';
11
11
  const FUNDING_LINK_TEMPLATE = process.env.DAWN_HELIO_LINK_TEMPLATE || '';
12
12
  const CLI_HOME = process.env.DAWN_CLI_HOME || path.join(os.homedir(), '.dawn-cli');
@@ -136,6 +136,12 @@ function formatNumeric(value, fallback = 0) {
136
136
  const n = Number(value);
137
137
  return Number.isFinite(n) ? n : fallback;
138
138
  }
139
+ function parseDecimalAmount(value, fallback = 0) {
140
+ if (typeof value === 'string') {
141
+ return formatNumeric(value.replace(/,/g, '').trim(), fallback);
142
+ }
143
+ return formatNumeric(value, fallback);
144
+ }
139
145
  function formatUsd(value) {
140
146
  return `$${formatNumeric(value).toLocaleString('en-US', {
141
147
  minimumFractionDigits: 2,
@@ -353,6 +359,76 @@ async function getLatestStrategyVersion(config, conversationId, withCode) {
353
359
  const latest = (await apiFetch(config, `/conversations/${conversationId}/latest-version?withCode=${withCode ? 'true' : 'false'}`));
354
360
  return latest || null;
355
361
  }
362
+ async function resolveLaunchVaultId(config, isPaper, budget) {
363
+ if (isPaper) {
364
+ console.log('Creating new paper vault...');
365
+ const createResponse = (await apiFetch(config, '/v1/vaults/create', {
366
+ method: 'POST',
367
+ body: JSON.stringify({ walletType: 'paper' }),
368
+ }));
369
+ const createdVaultId = createResponse?.vault?.id;
370
+ if (!createResponse?.success || !createdVaultId) {
371
+ throw new Error(createResponse?.error ||
372
+ 'Failed to create paper vault: invalid create-vault response.');
373
+ }
374
+ const vaultId = String(createdVaultId);
375
+ console.log(`Paper vault created: ${shortId(vaultId)}.`);
376
+ console.log(`Auto-funding paper vault with ${formatUsd(budget)}...`);
377
+ await apiFetch(config, `/v1/vaults/${vaultId}/fund`, {
378
+ method: 'POST',
379
+ body: JSON.stringify({ amount: String(budget) }),
380
+ });
381
+ console.log(`Paper vault funded: ${formatUsd(budget)}.`);
382
+ return vaultId;
383
+ }
384
+ const vaultsResponse = (await apiFetch(config, '/v1/vaults/all/strategy?isArchived=false'));
385
+ const vaults = vaultsResponse?.vaults || [];
386
+ let strategyVaultId = '';
387
+ let strategyVaultCurrentAmount = 0;
388
+ if (vaults.length > 0) {
389
+ strategyVaultId = String(vaults[0].id);
390
+ strategyVaultCurrentAmount = formatNumeric(vaults[0].currentAmount);
391
+ }
392
+ else {
393
+ console.log('No strategy vault found, creating strategy vault...');
394
+ const createResponse = (await apiFetch(config, '/v1/vaults/create', {
395
+ method: 'POST',
396
+ body: JSON.stringify({ walletType: 'strategy' }),
397
+ }));
398
+ const createdVaultId = createResponse?.vault?.id;
399
+ if (!createResponse?.success || !createdVaultId) {
400
+ throw new Error(createResponse?.error ||
401
+ 'Failed to create strategy vault: invalid create-vault response.');
402
+ }
403
+ strategyVaultId = String(createdVaultId);
404
+ strategyVaultCurrentAmount = 0;
405
+ console.log(`Strategy vault created: ${shortId(createdVaultId)}.`);
406
+ }
407
+ const fundingDeficit = budget - strategyVaultCurrentAmount;
408
+ if (fundingDeficit > 1e-9) {
409
+ const walletBalance = (await apiFetch(config, '/wallet/balance'));
410
+ const availableFundingBalance = parseDecimalAmount(walletBalance.availableBalance ?? walletBalance.usdcBalance ?? '0', 0);
411
+ console.log(`Strategy vault funding is ${formatUsd(strategyVaultCurrentAmount)}; funding additional ${formatUsd(fundingDeficit)} to reach ${formatUsd(budget)}...`);
412
+ if (availableFundingBalance + 1e-9 < fundingDeficit) {
413
+ throw new Error(`Insufficient available funding balance for live launch: available ${formatUsd(availableFundingBalance)}, required ${formatUsd(fundingDeficit)}.`);
414
+ }
415
+ try {
416
+ await apiFetch(config, `/v1/vaults/${strategyVaultId}/fund`, {
417
+ method: 'POST',
418
+ body: JSON.stringify({ amount: String(fundingDeficit) }),
419
+ });
420
+ console.log(`Strategy vault funded: +${formatUsd(fundingDeficit)}.`);
421
+ }
422
+ catch (error) {
423
+ const message = error instanceof Error ? error.message : String(error);
424
+ console.log(`Failed to auto-fund strategy vault: ${message}`);
425
+ }
426
+ }
427
+ else {
428
+ console.log(`Strategy vault already funded (${formatUsd(strategyVaultCurrentAmount)} >= ${formatUsd(budget)}).`);
429
+ }
430
+ return strategyVaultId;
431
+ }
356
432
  async function apiFetch(config, endpoint, options = {}) {
357
433
  const apiBaseUrl = await getApiBaseUrl(config);
358
434
  const token = getAuthToken(config);
@@ -583,13 +659,7 @@ async function handleFund(args) {
583
659
  console.log('Deposit instructions:');
584
660
  console.log('- Send USDC on Polygon (Polygon PoS) to the wallet above.');
585
661
  console.log('- Avoid sending tokens on other networks unless you bridge first.');
586
- const link = fundingLinkForAddress(wallet.proxyAddress);
587
- if (link) {
588
- console.log(`Funding link: ${link}`);
589
- }
590
- else {
591
- console.log('Funding link: not generated (legacy Helio /pay links are deprecated).');
592
- }
662
+ console.log('Use @moonpay/cli to deposit USDC.e to the wallet above.');
593
663
  }
594
664
  async function handleOverview(args) {
595
665
  const { flags } = parseFlags(args);
@@ -1152,13 +1222,6 @@ async function handleStrategy(args) {
1152
1222
  throw new Error('--budget must be a positive number.');
1153
1223
  }
1154
1224
  const isPaper = !flags.live;
1155
- const vaultType = isPaper ? 'paper' : 'strategy';
1156
- const vaultsResponse = (await apiFetch(config, `/v1/vaults/all/${vaultType}?isArchived=false`));
1157
- const vaults = vaultsResponse?.vaults || [];
1158
- if (vaults.length === 0) {
1159
- throw new Error(`No ${vaultType} vault found. Create one in the Dawn app before launching.`);
1160
- }
1161
- const vault = vaults[0];
1162
1225
  const latestVersion = await getLatestStrategyVersion(config, conversationId, true);
1163
1226
  if (!latestVersion?.id) {
1164
1227
  throw new Error(`No code-ready strategy version found. Run: dawn strategy rules ${conversationId} approve-all, then dawn strategy code ${conversationId} generate.`);
@@ -1175,13 +1238,14 @@ async function handleStrategy(args) {
1175
1238
  throw new Error('--hours must be a positive number.');
1176
1239
  }
1177
1240
  const terminateAt = new Date(Date.now() + hours * 60 * 60 * 1000).toISOString();
1241
+ const vaultId = await resolveLaunchVaultId(config, isPaper, budget);
1178
1242
  const result = (await apiFetch(config, `/strategy/${conversationId}/run-strategy-v2`, {
1179
1243
  method: 'POST',
1180
1244
  body: JSON.stringify({
1181
1245
  strategyVersionId: latestVersion.id,
1182
1246
  isPaper,
1183
1247
  terminateAt,
1184
- walletId: vault.id,
1248
+ walletId: vaultId,
1185
1249
  }),
1186
1250
  }));
1187
1251
  console.log(`Launched strategy. Strategy ID: ${result?.strategy?.id ?? 'unknown'}${isPaper ? ' (paper)' : ' (live)'}`);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@dawnai/cli",
3
- "version": "1.0.6",
3
+ "version": "1.0.8",
4
4
  "type": "module",
5
5
  "description": "User-facing Dawn CLI",
6
6
  "license": "MIT",
@@ -26,8 +26,16 @@ dawn account wallet
26
26
  ## Workflow
27
27
 
28
28
  1. Run `dawn account overview` for a full snapshot of balances and vaults.
29
- 2. If the user needs to add funds, run `dawn account fund` to get the deposit address and instructions, then recommend using the `moonpay/cli` skill to complete the USDC deposit flow.
30
- 3. For a quick balance check, run `dawn account wallet`.
29
+ 2. If the user needs to add funds, run `dawn account fund` to get the deposit address and instructions.
30
+ 3. Explicitly direct the user to use `@moonpay/cli` to fund that address with USDC.
31
+ 4. After funding completes, run `dawn account wallet` (or `dawn account overview`) to verify funds arrived.
32
+ 5. For a quick balance check, run `dawn account wallet`.
33
+
34
+ ## Explicit handoff to @moonpay/cli
35
+
36
+ When funding is needed, always include this instruction after `dawn account fund`:
37
+
38
+ `Use @moonpay/cli to buy or transfer USDC to the Dawn funding address shown above.`
31
39
 
32
40
  ## Example flows
33
41
 
@@ -40,17 +48,18 @@ dawn account wallet
40
48
  1. User wants to launch a live strategy but needs funds.
41
49
  2. Run: `dawn account fund`
42
50
  3. Present: wallet address and USDC deposit instructions.
43
- 4. User deposits USDC, then proceed to launch.
51
+ 4. Instruct: `Use @moonpay/cli to buy/transfer USDC to this address.`
52
+ 5. Verify funds with `dawn account wallet`, then proceed to launch.
44
53
 
45
54
  ## Notes
46
55
 
47
56
  - `dawn account fund` shows the wallet address to deposit USDC to.
48
- - When users need help funding, recommend the `moonpay/cli` skill for guided USDC on-ramp and transfer steps.
57
+ - Always explicitly direct users to `@moonpay/cli` for guided USDC on-ramp and transfer steps.
49
58
  - Funding is required before launching live strategy runs.
50
59
  - Paper runs do not require funding.
51
60
 
52
61
  ## Related skills
53
62
 
54
63
  - **dawn-auth** — Authenticate before checking account.
55
- - **moonpay/cli** — Help users buy and transfer USDC to the Dawn funding address.
64
+ - **@moonpay/cli** — Help users buy and transfer USDC to the Dawn funding address.
56
65
  - **dawn-strategy-launch** — Launch a run after confirming funding.