@1sat/cli 0.0.116 → 0.0.118

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 CHANGED
@@ -1,7 +1,15 @@
1
1
  #!/usr/bin/env node
2
- import { createRequire } from "node:module";
3
- var __esm = (fn, res) => () => (fn && (res = fn(fn = 0)), res);
4
- var __require = /* @__PURE__ */ createRequire(import.meta.url);
2
+ var __esm = (fn, res, err) => () => {
3
+ if (fn)
4
+ try {
5
+ res = fn(fn = 0);
6
+ } catch (e) {
7
+ err = [e];
8
+ }
9
+ if (err)
10
+ throw err[0];
11
+ return res;
12
+ };
5
13
 
6
14
  // src/args.ts
7
15
  function parseGlobalFlags(args) {
@@ -505,11 +513,11 @@ async function handleActionCommand(args, opts) {
505
513
  Registered actions:
506
514
  `);
507
515
  const grouped = new Map;
508
- for (const action2 of actions) {
509
- const cat = action2.meta.category;
516
+ for (const action of actions) {
517
+ const cat = action.meta.category;
510
518
  if (!grouped.has(cat))
511
519
  grouped.set(cat, []);
512
- grouped.get(cat).push(action2);
520
+ grouped.get(cat).push(action);
513
521
  }
514
522
  for (const [category, categoryActions] of grouped) {
515
523
  console.log(` ${category}:`);
@@ -817,12 +825,12 @@ var init_help = __esm(() => {
817
825
  { name: "balance", description: "Show wallet balance in satoshis" },
818
826
  {
819
827
  name: "address",
820
- description: "Show BRC-29 deposit address(es)",
828
+ description: "Show P1SAT deposit address(es)",
821
829
  args: [
822
830
  {
823
831
  flag: "--prefix",
824
832
  values: "<p>",
825
- description: "BRC-29 prefix (default: 1sat)"
833
+ description: "Deposit keyID prefix (default: 1sat)"
826
834
  },
827
835
  { flag: "--start-index", values: "<n>" },
828
836
  { flag: "--count", values: "<n>" }
@@ -849,7 +857,7 @@ var init_help = __esm(() => {
849
857
  },
850
858
  {
851
859
  name: "sync",
852
- description: "Sync inbound payments at BRC-29 deposit addresses",
860
+ description: "Sync inbound payments at P1SAT deposit addresses",
853
861
  args: [
854
862
  { flag: "--prefix", values: "<p>" },
855
863
  { flag: "--start-index", values: "<n>" },
@@ -1464,7 +1472,7 @@ function createApprovalAuth(wallet) {
1464
1472
  get(target, property) {
1465
1473
  if (property === "createAction")
1466
1474
  return async (...args) => {
1467
- const satoshis = args[0].outputs?.reduce((sum, output2) => sum + output2.satoshis, 0) ?? 0;
1475
+ const satoshis = args[0].outputs?.reduce((sum, output) => sum + output.satoshis, 0) ?? 0;
1468
1476
  if (!Number.isSafeInteger(satoshis) || satoshis <= 0)
1469
1477
  throw new Error("Invalid HTTP payment amount");
1470
1478
  if (approved === false)
@@ -1988,15 +1996,15 @@ async function handleInitCommand(_args, opts) {
1988
1996
  }
1989
1997
  let wif;
1990
1998
  if (keySource === "generate") {
1991
- const pk2 = PrivateKey2.fromRandom();
1992
- wif = pk2.toWif();
1993
- const address2 = pk2.toPublicKey().toAddress();
1999
+ const pk = PrivateKey2.fromRandom();
2000
+ wif = pk.toWif();
2001
+ const address = pk.toPublicKey().toAddress();
1994
2002
  console.log();
1995
2003
  console.log(formatWarning(" IMPORTANT: Back up your private key!"));
1996
2004
  console.log(formatWarning(" If you lose it, your funds are gone forever."));
1997
2005
  console.log();
1998
2006
  console.log(` ${formatValue("WIF:")} ${wif}`);
1999
- console.log(` ${formatValue("Address:")} ${address2}`);
2007
+ console.log(` ${formatValue("Address:")} ${address}`);
2000
2008
  console.log();
2001
2009
  const confirmed = await confirm2({
2002
2010
  message: "Have you saved your private key somewhere safe?"
@@ -3531,7 +3539,8 @@ import {
3531
3539
  KnexHandleCertStore,
3532
3540
  KnexPendingStore,
3533
3541
  createHostServer,
3534
- createWalletServer
3542
+ createWalletServer,
3543
+ startBRC100Server
3535
3544
  } from "@1sat/wallet-server";
3536
3545
  import { initLogger as initLogger2 } from "evlog";
3537
3546
  import knexLib from "knex";
@@ -3566,6 +3575,7 @@ function resolveMode(subcommand) {
3566
3575
  switch (subcommand) {
3567
3576
  case "wallet":
3568
3577
  case "monitor":
3578
+ case "wallet-api":
3569
3579
  return subcommand;
3570
3580
  default:
3571
3581
  return null;
@@ -3659,6 +3669,15 @@ async function runWithStorage(resolved, mode) {
3659
3669
  backups: resolved.backups,
3660
3670
  skipInitialMonitor: true
3661
3671
  });
3672
+ if (mode === "wallet-api") {
3673
+ const dapp = await startDappEndpoint(walletResult);
3674
+ return {
3675
+ stop: async () => {
3676
+ await dapp.close();
3677
+ await walletResult.destroy();
3678
+ }
3679
+ };
3680
+ }
3662
3681
  const runMonitor = mode === "monitor" || mode === "all" && resolved.monitorEnabled;
3663
3682
  const accounts = mode === "monitor" ? undefined : await buildAccountsForServer(resolved, walletResult);
3664
3683
  const serverHandle = mode === "monitor" ? undefined : await startWalletServer(resolved, walletResult, accounts, mode);
@@ -3722,7 +3741,7 @@ async function startWalletServer(resolved, walletResult, accounts, mode) {
3722
3741
  ttlSeconds: sessionStoreCfg.ttlSeconds
3723
3742
  } : undefined;
3724
3743
  if (mode === "wallet") {
3725
- const handle2 = createWalletServer({
3744
+ const handle = createWalletServer({
3726
3745
  wallet: walletResult.wallet,
3727
3746
  storage: walletResult.getActiveStorage(),
3728
3747
  serverIdentityKey: walletResult.wallet.identityKey,
@@ -3732,10 +3751,10 @@ async function startWalletServer(resolved, walletResult, accounts, mode) {
3732
3751
  accounts: accounts?.walletServerAccounts,
3733
3752
  sessionStore
3734
3753
  });
3735
- const port2 = await handle2.start();
3736
- const notes2 = [resolved.accounts.enabled ? "accounts: on" : ""].filter(Boolean).join(", ");
3737
- console.log(`[wallet] listening on ${resolved.host}:${port2}${notes2 ? ` (${notes2})` : ""}`);
3738
- return { stop: () => handle2.stop() };
3754
+ const port = await handle.start();
3755
+ const notes = [resolved.accounts.enabled ? "accounts: on" : ""].filter(Boolean).join(", ");
3756
+ console.log(`[wallet] listening on ${resolved.host}:${port}${notes ? ` (${notes})` : ""}`);
3757
+ return { stop: () => handle.stop() };
3739
3758
  }
3740
3759
  const serverCfg = config.server ?? {};
3741
3760
  const paymailCfg = serverCfg.paymail;
@@ -3847,7 +3866,52 @@ function waitForShutdown() {
3847
3866
  process.once("SIGTERM", () => handler("SIGTERM"));
3848
3867
  });
3849
3868
  }
3850
- var DEFAULT_HOST = "127.0.0.1", DEFAULT_PORT = 8100, DEFAULT_STACK_URL = "https://api.1sat.app", DEFAULT_BASELINE_BYTES, DEFAULT_PURCHASE_UNIT_BYTES = 1073741824, DEFAULT_SATS_PER_UNIT = 1e6, DEFAULT_DURATION_BLOCKS = 4383, DEFAULT_STORAGE_IDENTITY_KEY = "1sat-cli-default", DEFAULT_PG_SCHEMA = "messagebox";
3869
+ function walletApiHandle(wallet) {
3870
+ return {
3871
+ async call(method, args, origin) {
3872
+ const iface = wallet;
3873
+ const fn = iface[method];
3874
+ if (typeof fn !== "function") {
3875
+ throw new Error(`Method not available: ${method}`);
3876
+ }
3877
+ return await fn.call(iface, args, origin);
3878
+ }
3879
+ };
3880
+ }
3881
+ async function startDappEndpoint(walletResult) {
3882
+ const config = loadConfig();
3883
+ const dapp = config.server?.dapp ?? {};
3884
+ const host = dapp.host ?? DEFAULT_DAPP_HOST;
3885
+ const port = dapp.port ?? (process.env.ONESAT_DAPP_PORT ? Number(process.env.ONESAT_DAPP_PORT) : DEFAULT_DAPP_PORT);
3886
+ const approve = dapp.approve === true;
3887
+ const handle = await startBRC100Server({
3888
+ host,
3889
+ port,
3890
+ wallet: walletApiHandle(walletResult.wallet),
3891
+ approvalPolicy: approve ? async ({ method, origin, args }) => {
3892
+ const { confirm, isCancel } = await import("@clack/prompts");
3893
+ console.log(`
3894
+ [brc-100] ${method} requested by ${origin}`);
3895
+ console.log(` ${JSON.stringify(args).slice(0, 400)}`);
3896
+ const ok = await confirm({
3897
+ message: `Approve ${method}?`
3898
+ });
3899
+ if (isCancel(ok) || !ok) {
3900
+ throw new Error("User denied permission");
3901
+ }
3902
+ } : undefined,
3903
+ onEvent: (event) => {
3904
+ if (event.event === "brc100_sensitive") {
3905
+ const trustNote = event.trusted ? " (trusted)" : approve ? "" : " (auto-approved)";
3906
+ console.log(`[brc-100] sensitive ${event.method} from ${event.origin}${trustNote}`);
3907
+ }
3908
+ }
3909
+ });
3910
+ console.log(`[wallet-api] BRC-100 app endpoint on http://${host}:${port}`);
3911
+ console.log(approve ? "[wallet-api] sensitive methods require TTY confirmation" : "[wallet-api] sensitive methods are AUTO-APPROVED (headless). " + "Set server.dapp.approve=true to require confirmation.");
3912
+ return { close: async () => await handle.close() };
3913
+ }
3914
+ var DEFAULT_HOST = "127.0.0.1", DEFAULT_PORT = 8100, DEFAULT_STACK_URL = "https://api.1sat.app", DEFAULT_BASELINE_BYTES, DEFAULT_PURCHASE_UNIT_BYTES = 1073741824, DEFAULT_SATS_PER_UNIT = 1e6, DEFAULT_DURATION_BLOCKS = 4383, DEFAULT_STORAGE_IDENTITY_KEY = "1sat-cli-default", DEFAULT_PG_SCHEMA = "messagebox", DEFAULT_DAPP_HOST = "127.0.0.1", DEFAULT_DAPP_PORT = 3321;
3851
3915
  var init_serve = __esm(() => {
3852
3916
  init_config();
3853
3917
  init_config();
@@ -4013,11 +4077,11 @@ function selectedSweepClasses(only, skip) {
4013
4077
  throw new Error("--only and --skip are mutually exclusive");
4014
4078
  }
4015
4079
  if (only) {
4016
- const selected2 = parseSweepClasses(only, "--only");
4017
- if (selected2.size === 0) {
4080
+ const selected = parseSweepClasses(only, "--only");
4081
+ if (selected.size === 0) {
4018
4082
  throw new Error("--only requires at least one class");
4019
4083
  }
4020
- return selected2;
4084
+ return selected;
4021
4085
  }
4022
4086
  const selected = new Set(SWEEP_CLASSES);
4023
4087
  if (skip) {
@@ -5120,8 +5184,8 @@ async function walletListOutputs(args, opts) {
5120
5184
  ${result.totalOutputs} total outputs in basket '${basket}':
5121
5185
  `);
5122
5186
  for (const out of result.outputs) {
5123
- const tags2 = out.tags?.join(", ") || "none";
5124
- console.log(` ${out.outpoint} | ${out.satoshis} sats | tags: ${tags2}`);
5187
+ const tags = out.tags?.join(", ") || "none";
5188
+ console.log(` ${out.outpoint} | ${out.satoshis} sats | tags: ${tags}`);
5125
5189
  }
5126
5190
  console.log();
5127
5191
  }
@@ -5379,7 +5443,6 @@ var init_wallet = __esm(() => {
5379
5443
  });
5380
5444
 
5381
5445
  // src/main.ts
5382
- var exports_main = {};
5383
5446
  import { existsSync as existsSync4 } from "node:fs";
5384
5447
  import { resolve } from "node:path";
5385
5448
  import { config as loadEnv } from "dotenv";
@@ -5519,4 +5582,4 @@ var init_main = __esm(() => {
5519
5582
 
5520
5583
  // src/cli.ts
5521
5584
  process.env.DOTENV_CONFIG_QUIET = "true";
5522
- await Promise.resolve().then(() => (init_main(), exports_main));
5585
+ await Promise.resolve().then(() => (init_main(), {}));
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@1sat/cli",
3
- "version": "0.0.116",
3
+ "version": "0.0.118",
4
4
  "description": "CLI for 1Sat Ordinals SDK",
5
5
  "type": "module",
6
6
  "main": "./dist/cli.js",
@@ -27,11 +27,11 @@
27
27
  ],
28
28
  "license": "MIT",
29
29
  "dependencies": {
30
- "@1sat/actions": "0.0.220",
31
- "@1sat/client": "0.0.54",
32
- "@1sat/types": "0.0.47",
33
- "@1sat/wallet-node": "0.0.76",
34
- "@1sat/wallet-server": "0.0.52",
30
+ "@1sat/actions": "0.0.222",
31
+ "@1sat/client": "0.0.55",
32
+ "@1sat/types": "0.0.48",
33
+ "@1sat/wallet-node": "0.0.77",
34
+ "@1sat/wallet-server": "0.0.54",
35
35
  "@bopen-io/messagebox-server": "^1.3.2",
36
36
  "@bsv/sdk": "^2.6.0",
37
37
  "@bsv/wallet-toolbox": "npm:@bopen-io/wallet-toolbox@2.6.2-brc153.5",
@@ -25,12 +25,15 @@ import {
25
25
  createNodeWallet,
26
26
  } from '@1sat/wallet-node'
27
27
  import {
28
+ type BRC100WalletHandle,
28
29
  KnexAccountStore,
29
30
  KnexHandleCertStore,
30
31
  KnexPendingStore,
31
32
  createHostServer,
32
33
  createWalletServer,
34
+ startBRC100Server,
33
35
  } from '@1sat/wallet-server'
36
+ import type { Wallet, WalletInterface } from '@bsv/sdk'
34
37
  import type { PrivateKey } from '@bsv/sdk'
35
38
  import { initLogger } from 'evlog'
36
39
  import knexLib from 'knex'
@@ -64,7 +67,7 @@ const DEFAULT_SATS_PER_UNIT = 1_000_000
64
67
  const DEFAULT_DURATION_BLOCKS = 4383
65
68
  const DEFAULT_STORAGE_IDENTITY_KEY = '1sat-cli-default'
66
69
 
67
- type ServeMode = 'all' | 'wallet' | 'monitor'
70
+ type ServeMode = 'all' | 'wallet' | 'monitor' | 'wallet-api'
68
71
 
69
72
  interface ResolvedServe {
70
73
  chain: 'main' | 'test'
@@ -130,6 +133,7 @@ function resolveMode(subcommand: string | undefined): ServeMode | null {
130
133
  switch (subcommand) {
131
134
  case 'wallet':
132
135
  case 'monitor':
136
+ case 'wallet-api':
133
137
  return subcommand
134
138
  default:
135
139
  return null
@@ -269,6 +273,18 @@ async function runWithStorage(
269
273
  skipInitialMonitor: true,
270
274
  })
271
275
 
276
+ // wallet-api serves only the app-facing BRC-100 endpoint: no storage
277
+ // server, no accounts, no monitor.
278
+ if (mode === 'wallet-api') {
279
+ const dapp = await startDappEndpoint(walletResult)
280
+ return {
281
+ stop: async () => {
282
+ await dapp.close()
283
+ await walletResult.destroy()
284
+ },
285
+ }
286
+ }
287
+
272
288
  // One active monitor per deployment: wallet mode never runs it, monitor
273
289
  // mode always does, all mode runs it unless server.monitor.enabled=false
274
290
  // (set on redundant host instances that share a dedicated serve monitor).
@@ -538,3 +554,94 @@ function waitForShutdown(): Promise<void> {
538
554
  process.once('SIGTERM', () => handler('SIGTERM'))
539
555
  })
540
556
  }
557
+
558
+ // ---------------------------------------------------------------------------
559
+ // wallet-api: application-facing BRC-100 endpoint (dApp connectivity)
560
+ // ---------------------------------------------------------------------------
561
+
562
+ const DEFAULT_DAPP_HOST = '127.0.0.1'
563
+ const DEFAULT_DAPP_PORT = 3321
564
+
565
+ /**
566
+ * Wrap the CLI's wallet (wallet-toolbox client) as a BRC100WalletHandle.
567
+ * The toolbox Wallet already implements the 28 BRC-100 methods with the
568
+ * `(args, originator)` signature the dApps send.
569
+ */
570
+ function walletApiHandle(wallet: Wallet): BRC100WalletHandle {
571
+ return {
572
+ async call(method, args, origin) {
573
+ const iface = wallet as unknown as WalletInterface
574
+ const fn = (iface as unknown as Record<string, unknown>)[method] as (
575
+ a: unknown,
576
+ o: string,
577
+ ) => Promise<unknown>
578
+ if (typeof fn !== 'function') {
579
+ throw new Error(`Method not available: ${method}`)
580
+ }
581
+ return await fn.call(iface, args, origin)
582
+ },
583
+ }
584
+ }
585
+
586
+ /**
587
+ * Start the app-facing BRC-100 HTTP endpoint (the interface dApps like
588
+ * wallet-desktop's :3321 server speak; see bitplan and other BRC-100
589
+ * clients). Headless by design: sensitive methods are auto-approved with a
590
+ * console line unless `server.dapp.approve` is set, in which case each one
591
+ * must be confirmed on the TTY.
592
+ */
593
+ async function startDappEndpoint(
594
+ walletResult: NodeWalletResult,
595
+ ): Promise<{ close: () => Promise<void> }> {
596
+ const config = loadConfig()
597
+ const dapp = config.server?.dapp ?? {}
598
+ const host = dapp.host ?? DEFAULT_DAPP_HOST
599
+ const port =
600
+ dapp.port ??
601
+ (process.env.ONESAT_DAPP_PORT
602
+ ? Number(process.env.ONESAT_DAPP_PORT)
603
+ : DEFAULT_DAPP_PORT)
604
+
605
+ const approve = dapp.approve === true
606
+
607
+ const handle = await startBRC100Server({
608
+ host,
609
+ port,
610
+ wallet: walletApiHandle(walletResult.wallet),
611
+ approvalPolicy: approve
612
+ ? async ({ method, origin, args }) => {
613
+ const { confirm, isCancel } = await import('@clack/prompts')
614
+ console.log(`\n[brc-100] ${method} requested by ${origin}`)
615
+ console.log(` ${JSON.stringify(args).slice(0, 400)}`)
616
+ const ok = await confirm({
617
+ message: `Approve ${method}?`,
618
+ })
619
+ if (isCancel(ok) || !ok) {
620
+ throw new Error('User denied permission')
621
+ }
622
+ }
623
+ : undefined,
624
+ onEvent: (event) => {
625
+ if (event.event === 'brc100_sensitive') {
626
+ const trustNote = event.trusted
627
+ ? ' (trusted)'
628
+ : approve
629
+ ? ''
630
+ : ' (auto-approved)'
631
+ console.log(
632
+ `[brc-100] sensitive ${event.method} from ${event.origin}${trustNote}`,
633
+ )
634
+ }
635
+ },
636
+ })
637
+
638
+ console.log(`[wallet-api] BRC-100 app endpoint on http://${host}:${port}`)
639
+ console.log(
640
+ approve
641
+ ? '[wallet-api] sensitive methods require TTY confirmation'
642
+ : '[wallet-api] sensitive methods are AUTO-APPROVED (headless). ' +
643
+ 'Set server.dapp.approve=true to require confirmation.',
644
+ )
645
+
646
+ return { close: async () => await handle.close() }
647
+ }
package/src/config.ts CHANGED
@@ -154,6 +154,17 @@ export interface ServerConfig {
154
154
  accounts?: ServerAccountsConfig
155
155
  /** Messagebox subcommand settings. */
156
156
  messagebox?: ServerMessageboxConfig
157
+ /**
158
+ * Application-facing BRC-100 endpoint (`1sat serve wallet-api`):
159
+ * dApp connectivity for the CLI wallet (encrypt/decrypt/sign/create-action).
160
+ * Defaults: 127.0.0.1:3321, headless auto-approval of sensitive methods.
161
+ */
162
+ dapp?: {
163
+ host?: string
164
+ port?: number
165
+ /** Require TTY confirmation for sensitive methods. Default false. */
166
+ approve?: boolean
167
+ }
157
168
  /** Paymail settings for the unified host. */
158
169
  paymail?: ServerPaymailConfig
159
170
  /** Shared BSV/USD repricer engine for the accounts storage price. */
package/src/help.ts CHANGED
@@ -163,12 +163,12 @@ export const COMMANDS: CommandSpec[] = [
163
163
  { name: 'balance', description: 'Show wallet balance in satoshis' },
164
164
  {
165
165
  name: 'address',
166
- description: 'Show BRC-29 deposit address(es)',
166
+ description: 'Show P1SAT deposit address(es)',
167
167
  args: [
168
168
  {
169
169
  flag: '--prefix',
170
170
  values: '<p>',
171
- description: 'BRC-29 prefix (default: 1sat)',
171
+ description: 'Deposit keyID prefix (default: 1sat)',
172
172
  },
173
173
  { flag: '--start-index', values: '<n>' },
174
174
  { flag: '--count', values: '<n>' },
@@ -196,7 +196,7 @@ export const COMMANDS: CommandSpec[] = [
196
196
  },
197
197
  {
198
198
  name: 'sync',
199
- description: 'Sync inbound payments at BRC-29 deposit addresses',
199
+ description: 'Sync inbound payments at P1SAT deposit addresses',
200
200
  args: [
201
201
  { flag: '--prefix', values: '<p>' },
202
202
  { flag: '--start-index', values: '<n>' },