@1sat/cli 0.0.117 → 0.0.119
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 +66 -6
- package/package.json +4 -4
- package/src/commands/serve.ts +108 -1
- package/src/config.ts +11 -0
- package/src/help.ts +8 -3
package/dist/cli.js
CHANGED
|
@@ -825,12 +825,12 @@ var init_help = __esm(() => {
|
|
|
825
825
|
{ name: "balance", description: "Show wallet balance in satoshis" },
|
|
826
826
|
{
|
|
827
827
|
name: "address",
|
|
828
|
-
description: "Show
|
|
828
|
+
description: "Show P1SAT deposit address(es)",
|
|
829
829
|
args: [
|
|
830
830
|
{
|
|
831
831
|
flag: "--prefix",
|
|
832
832
|
values: "<p>",
|
|
833
|
-
description: "
|
|
833
|
+
description: "Deposit keyID prefix (default: 1sat)"
|
|
834
834
|
},
|
|
835
835
|
{ flag: "--start-index", values: "<n>" },
|
|
836
836
|
{ flag: "--count", values: "<n>" }
|
|
@@ -857,7 +857,7 @@ var init_help = __esm(() => {
|
|
|
857
857
|
},
|
|
858
858
|
{
|
|
859
859
|
name: "sync",
|
|
860
|
-
description: "Sync inbound payments at
|
|
860
|
+
description: "Sync inbound payments at P1SAT deposit addresses",
|
|
861
861
|
args: [
|
|
862
862
|
{ flag: "--prefix", values: "<p>" },
|
|
863
863
|
{ flag: "--start-index", values: "<n>" },
|
|
@@ -1387,7 +1387,11 @@ var init_help = __esm(() => {
|
|
|
1387
1387
|
name: "wallet",
|
|
1388
1388
|
description: "Wallet storage server only (BRC-100 HTTP)"
|
|
1389
1389
|
},
|
|
1390
|
-
{ name: "monitor", description: "Monitor daemon only" }
|
|
1390
|
+
{ name: "monitor", description: "Monitor daemon only" },
|
|
1391
|
+
{
|
|
1392
|
+
name: "wallet-api",
|
|
1393
|
+
description: "App-facing BRC-100 wallet endpoint only (headless, default port 3321)"
|
|
1394
|
+
}
|
|
1391
1395
|
]
|
|
1392
1396
|
},
|
|
1393
1397
|
{
|
|
@@ -3539,7 +3543,8 @@ import {
|
|
|
3539
3543
|
KnexHandleCertStore,
|
|
3540
3544
|
KnexPendingStore,
|
|
3541
3545
|
createHostServer,
|
|
3542
|
-
createWalletServer
|
|
3546
|
+
createWalletServer,
|
|
3547
|
+
startBRC100Server
|
|
3543
3548
|
} from "@1sat/wallet-server";
|
|
3544
3549
|
import { initLogger as initLogger2 } from "evlog";
|
|
3545
3550
|
import knexLib from "knex";
|
|
@@ -3574,6 +3579,7 @@ function resolveMode(subcommand) {
|
|
|
3574
3579
|
switch (subcommand) {
|
|
3575
3580
|
case "wallet":
|
|
3576
3581
|
case "monitor":
|
|
3582
|
+
case "wallet-api":
|
|
3577
3583
|
return subcommand;
|
|
3578
3584
|
default:
|
|
3579
3585
|
return null;
|
|
@@ -3667,6 +3673,15 @@ async function runWithStorage(resolved, mode) {
|
|
|
3667
3673
|
backups: resolved.backups,
|
|
3668
3674
|
skipInitialMonitor: true
|
|
3669
3675
|
});
|
|
3676
|
+
if (mode === "wallet-api") {
|
|
3677
|
+
const dapp = await startDappEndpoint(walletResult);
|
|
3678
|
+
return {
|
|
3679
|
+
stop: async () => {
|
|
3680
|
+
await dapp.close();
|
|
3681
|
+
await walletResult.destroy();
|
|
3682
|
+
}
|
|
3683
|
+
};
|
|
3684
|
+
}
|
|
3670
3685
|
const runMonitor = mode === "monitor" || mode === "all" && resolved.monitorEnabled;
|
|
3671
3686
|
const accounts = mode === "monitor" ? undefined : await buildAccountsForServer(resolved, walletResult);
|
|
3672
3687
|
const serverHandle = mode === "monitor" ? undefined : await startWalletServer(resolved, walletResult, accounts, mode);
|
|
@@ -3855,7 +3870,52 @@ function waitForShutdown() {
|
|
|
3855
3870
|
process.once("SIGTERM", () => handler("SIGTERM"));
|
|
3856
3871
|
});
|
|
3857
3872
|
}
|
|
3858
|
-
|
|
3873
|
+
function walletApiHandle(wallet) {
|
|
3874
|
+
return {
|
|
3875
|
+
async call(method, args, origin) {
|
|
3876
|
+
const iface = wallet;
|
|
3877
|
+
const fn = iface[method];
|
|
3878
|
+
if (typeof fn !== "function") {
|
|
3879
|
+
throw new Error(`Method not available: ${method}`);
|
|
3880
|
+
}
|
|
3881
|
+
return await fn.call(iface, args, origin);
|
|
3882
|
+
}
|
|
3883
|
+
};
|
|
3884
|
+
}
|
|
3885
|
+
async function startDappEndpoint(walletResult) {
|
|
3886
|
+
const config = loadConfig();
|
|
3887
|
+
const dapp = config.server?.dapp ?? {};
|
|
3888
|
+
const host = dapp.host ?? DEFAULT_DAPP_HOST;
|
|
3889
|
+
const port = dapp.port ?? (process.env.ONESAT_DAPP_PORT ? Number(process.env.ONESAT_DAPP_PORT) : DEFAULT_DAPP_PORT);
|
|
3890
|
+
const approve = dapp.approve === true;
|
|
3891
|
+
const handle = await startBRC100Server({
|
|
3892
|
+
host,
|
|
3893
|
+
port,
|
|
3894
|
+
wallet: walletApiHandle(walletResult.wallet),
|
|
3895
|
+
approvalPolicy: approve ? async ({ method, origin, args }) => {
|
|
3896
|
+
const { confirm, isCancel } = await import("@clack/prompts");
|
|
3897
|
+
console.log(`
|
|
3898
|
+
[brc-100] ${method} requested by ${origin}`);
|
|
3899
|
+
console.log(` ${JSON.stringify(args).slice(0, 400)}`);
|
|
3900
|
+
const ok = await confirm({
|
|
3901
|
+
message: `Approve ${method}?`
|
|
3902
|
+
});
|
|
3903
|
+
if (isCancel(ok) || !ok) {
|
|
3904
|
+
throw new Error("User denied permission");
|
|
3905
|
+
}
|
|
3906
|
+
} : undefined,
|
|
3907
|
+
onEvent: (event) => {
|
|
3908
|
+
if (event.event === "brc100_sensitive") {
|
|
3909
|
+
const trustNote = event.trusted ? " (trusted)" : approve ? "" : " (auto-approved)";
|
|
3910
|
+
console.log(`[brc-100] sensitive ${event.method} from ${event.origin}${trustNote}`);
|
|
3911
|
+
}
|
|
3912
|
+
}
|
|
3913
|
+
});
|
|
3914
|
+
console.log(`[wallet-api] BRC-100 app endpoint on http://${host}:${port}`);
|
|
3915
|
+
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.");
|
|
3916
|
+
return { close: async () => await handle.close() };
|
|
3917
|
+
}
|
|
3918
|
+
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;
|
|
3859
3919
|
var init_serve = __esm(() => {
|
|
3860
3920
|
init_config();
|
|
3861
3921
|
init_config();
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@1sat/cli",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.119",
|
|
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.
|
|
30
|
+
"@1sat/actions": "0.0.223",
|
|
31
31
|
"@1sat/client": "0.0.55",
|
|
32
32
|
"@1sat/types": "0.0.48",
|
|
33
|
-
"@1sat/wallet-node": "0.0.
|
|
34
|
-
"@1sat/wallet-server": "0.0.
|
|
33
|
+
"@1sat/wallet-node": "0.0.78",
|
|
34
|
+
"@1sat/wallet-server": "0.0.55",
|
|
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",
|
package/src/commands/serve.ts
CHANGED
|
@@ -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
|
|
166
|
+
description: 'Show P1SAT deposit address(es)',
|
|
167
167
|
args: [
|
|
168
168
|
{
|
|
169
169
|
flag: '--prefix',
|
|
170
170
|
values: '<p>',
|
|
171
|
-
description: '
|
|
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
|
|
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>' },
|
|
@@ -754,6 +754,11 @@ export const COMMANDS: CommandSpec[] = [
|
|
|
754
754
|
description: 'Wallet storage server only (BRC-100 HTTP)',
|
|
755
755
|
},
|
|
756
756
|
{ name: 'monitor', description: 'Monitor daemon only' },
|
|
757
|
+
{
|
|
758
|
+
name: 'wallet-api',
|
|
759
|
+
description:
|
|
760
|
+
'App-facing BRC-100 wallet endpoint only (headless, default port 3321)',
|
|
761
|
+
},
|
|
757
762
|
],
|
|
758
763
|
},
|
|
759
764
|
{
|