@1sat/cli 0.0.22 → 0.0.24
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 +40 -33
- package/src/args.ts +1 -1
- package/src/commands/config.ts +3 -1
- package/src/commands/identity.ts +37 -1
- package/src/commands/mcp-proxy.ts +49 -16
- package/src/commands/remote.ts +11 -17
- package/src/commands/sweep.ts +7 -5
- package/src/commands/wallet.ts +45 -15
- package/src/context.ts +14 -1
- package/src/help.ts +1 -0
package/package.json
CHANGED
|
@@ -1,34 +1,41 @@
|
|
|
1
1
|
{
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
2
|
+
"name": "@1sat/cli",
|
|
3
|
+
"version": "0.0.24",
|
|
4
|
+
"description": "CLI for 1Sat Ordinals SDK",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"main": "./src/cli.ts",
|
|
7
|
+
"bin": {
|
|
8
|
+
"1sat": "./src/cli.ts"
|
|
9
|
+
},
|
|
10
|
+
"files": [
|
|
11
|
+
"src"
|
|
12
|
+
],
|
|
13
|
+
"scripts": {
|
|
14
|
+
"build": "bun build ./src/cli.ts --compile --outfile=bin/1sat --external pg --external pg-native --external pg-query-stream --external tedious --external oracledb --external mysql",
|
|
15
|
+
"dev": "bun run src/cli.ts",
|
|
16
|
+
"lint": "biome check src"
|
|
17
|
+
},
|
|
18
|
+
"keywords": [
|
|
19
|
+
"1sat",
|
|
20
|
+
"bsv",
|
|
21
|
+
"ordinals",
|
|
22
|
+
"cli"
|
|
23
|
+
],
|
|
24
|
+
"license": "MIT",
|
|
25
|
+
"dependencies": {
|
|
26
|
+
"@1sat/actions": "0.0.85",
|
|
27
|
+
"@1sat/client": "0.0.20",
|
|
28
|
+
"@1sat/types": "0.0.16",
|
|
29
|
+
"@1sat/wallet-node": "0.0.23",
|
|
30
|
+
"@bsv/sdk": "^2.0.6",
|
|
31
|
+
"chalk": "^5.0.0",
|
|
32
|
+
"@clack/prompts": "^0.8.0",
|
|
33
|
+
"bitcoin-backup": "^0.0.11",
|
|
34
|
+
"dotenv": "^17.0.0",
|
|
35
|
+
"evlog": "^2.10.0"
|
|
36
|
+
},
|
|
37
|
+
"devDependencies": {
|
|
38
|
+
"@types/bun": "^1.3.9",
|
|
39
|
+
"typescript": "^5.9.3"
|
|
40
|
+
}
|
|
41
|
+
}
|
package/src/args.ts
CHANGED
|
@@ -93,7 +93,7 @@ export function extractFlags(args: string[], flag: string): string[] {
|
|
|
93
93
|
const value = args[i + 1]
|
|
94
94
|
if (value && !value.startsWith('--')) {
|
|
95
95
|
// Split comma-delimited values
|
|
96
|
-
values.push(...value.split(',').filter(v => v.length > 0))
|
|
96
|
+
values.push(...value.split(',').filter((v) => v.length > 0))
|
|
97
97
|
}
|
|
98
98
|
}
|
|
99
99
|
}
|
package/src/commands/config.ts
CHANGED
|
@@ -105,7 +105,9 @@ function configSet(args: string[], opts: GlobalFlags): void {
|
|
|
105
105
|
if (key === 'monitorIntervalMinutes') {
|
|
106
106
|
const n = Number(value)
|
|
107
107
|
if (!Number.isFinite(n) || n < 0) {
|
|
108
|
-
fatal(
|
|
108
|
+
fatal(
|
|
109
|
+
'monitorIntervalMinutes must be a non-negative number (0 to disable)',
|
|
110
|
+
)
|
|
109
111
|
}
|
|
110
112
|
}
|
|
111
113
|
|
package/src/commands/identity.ts
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
* BAP (Bitcoin Attestation Protocol) identity management.
|
|
5
5
|
*/
|
|
6
6
|
|
|
7
|
-
import { publishIdentity, signBsm } from '@1sat/actions'
|
|
7
|
+
import { publishIdentity, signBsm, updateProfile } from '@1sat/actions'
|
|
8
8
|
import type { GlobalFlags } from '../args'
|
|
9
9
|
import { extractFlag } from '../args'
|
|
10
10
|
import { loadContext } from '../context'
|
|
@@ -21,6 +21,8 @@ export async function handleIdentityCommand(
|
|
|
21
21
|
switch (subcommand) {
|
|
22
22
|
case 'create':
|
|
23
23
|
return identityCreate(rest, opts)
|
|
24
|
+
case 'update-profile':
|
|
25
|
+
return identityUpdateProfile(rest, opts)
|
|
24
26
|
case 'info':
|
|
25
27
|
return identityInfo(rest, opts)
|
|
26
28
|
case 'sign':
|
|
@@ -30,6 +32,7 @@ export async function handleIdentityCommand(
|
|
|
30
32
|
default:
|
|
31
33
|
printCommandHelp('identity', {
|
|
32
34
|
create: 'Create/publish a BAP identity',
|
|
35
|
+
'update-profile': 'Update BAP identity profile (--profile <json>)',
|
|
33
36
|
info: 'Show BAP identity information',
|
|
34
37
|
sign: 'Sign a message with identity key (--message <text>)',
|
|
35
38
|
verify:
|
|
@@ -128,3 +131,36 @@ async function identityVerify(
|
|
|
128
131
|
'identity verify is not yet implemented (needs direct BSM.verify integration)',
|
|
129
132
|
)
|
|
130
133
|
}
|
|
134
|
+
|
|
135
|
+
async function identityUpdateProfile(
|
|
136
|
+
args: string[],
|
|
137
|
+
opts: GlobalFlags,
|
|
138
|
+
): Promise<void> {
|
|
139
|
+
const profileStr = extractFlag(args, '--profile')
|
|
140
|
+
|
|
141
|
+
if (!profileStr) fatal('Missing --profile <json>')
|
|
142
|
+
|
|
143
|
+
let profile: Record<string, unknown>
|
|
144
|
+
try {
|
|
145
|
+
profile = JSON.parse(profileStr)
|
|
146
|
+
} catch {
|
|
147
|
+
fatal(`Invalid JSON in --profile: ${profileStr}`)
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
const privateKey = await loadKey(resolvePassword())
|
|
151
|
+
const { ctx, destroy } = await loadContext(privateKey, {
|
|
152
|
+
chain: opts.chain,
|
|
153
|
+
})
|
|
154
|
+
|
|
155
|
+
try {
|
|
156
|
+
const result = await updateProfile.execute(ctx, { profile })
|
|
157
|
+
|
|
158
|
+
if (result.error) {
|
|
159
|
+
fatal(result.error)
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
output(result, opts)
|
|
163
|
+
} finally {
|
|
164
|
+
await destroy()
|
|
165
|
+
}
|
|
166
|
+
}
|
|
@@ -61,33 +61,54 @@ async function handshake(key: PrivateKey): Promise<Session> {
|
|
|
61
61
|
if (!res.ok) throw new Error(`Handshake failed: HTTP ${res.status}`)
|
|
62
62
|
|
|
63
63
|
const data = await res.json()
|
|
64
|
-
if (data.messageType !== 'initialResponse')
|
|
64
|
+
if (data.messageType !== 'initialResponse')
|
|
65
|
+
throw new Error(`Unexpected: ${data.messageType}`)
|
|
65
66
|
|
|
66
67
|
const serverNonce = data.nonce as string
|
|
67
68
|
const deriver = new KeyDeriver(key)
|
|
68
69
|
const serverPub = deriver.derivePublicKey(
|
|
69
|
-
AUTH_PROTOCOL_ID,
|
|
70
|
+
AUTH_PROTOCOL_ID,
|
|
71
|
+
`${serverNonce} ${clientNonce}`,
|
|
72
|
+
data.identityKey as string,
|
|
73
|
+
false,
|
|
70
74
|
)
|
|
71
75
|
|
|
72
76
|
const clientNonceBytes = toArray(clientNonce, 'base64')
|
|
73
77
|
const serverNonceBytes = toArray(serverNonce, 'base64')
|
|
74
|
-
const msgHash = Hash.sha256(
|
|
78
|
+
const msgHash = Hash.sha256(
|
|
79
|
+
Array.from(new Uint8Array([...clientNonceBytes, ...serverNonceBytes])),
|
|
80
|
+
)
|
|
75
81
|
|
|
76
82
|
const sig = Signature.fromDER(data.signature as string, 'hex')
|
|
77
|
-
if (!serverPub.verify(Array.from(msgHash), sig))
|
|
83
|
+
if (!serverPub.verify(Array.from(msgHash), sig))
|
|
84
|
+
throw new Error('Server signature verification failed')
|
|
78
85
|
|
|
79
86
|
const log = createLogger({ context: 'auth' })
|
|
80
|
-
log.set({
|
|
87
|
+
log.set({
|
|
88
|
+
event: 'handshake_complete',
|
|
89
|
+
serverIdentityKey: (data.identityKey as string).slice(0, 16),
|
|
90
|
+
})
|
|
81
91
|
log.emit()
|
|
82
92
|
|
|
83
|
-
return {
|
|
93
|
+
return {
|
|
94
|
+
serverIdentityKey: data.identityKey as string,
|
|
95
|
+
serverNonce,
|
|
96
|
+
clientKey: key,
|
|
97
|
+
}
|
|
84
98
|
}
|
|
85
99
|
|
|
86
|
-
function signHeaders(
|
|
100
|
+
function signHeaders(
|
|
101
|
+
session: Session,
|
|
102
|
+
pathname: string,
|
|
103
|
+
): Record<string, string> {
|
|
87
104
|
const { serverIdentityKey, serverNonce, clientKey: key } = session
|
|
88
105
|
const nonce = generateNonce()
|
|
89
106
|
const deriver = new KeyDeriver(key)
|
|
90
|
-
const derivedKey = deriver.derivePrivateKey(
|
|
107
|
+
const derivedKey = deriver.derivePrivateKey(
|
|
108
|
+
AUTH_PROTOCOL_ID,
|
|
109
|
+
`${nonce} ${serverNonce}`,
|
|
110
|
+
serverIdentityKey,
|
|
111
|
+
)
|
|
91
112
|
const payload = new TextEncoder().encode(pathname)
|
|
92
113
|
const msgHash = Hash.sha256(Array.from(payload))
|
|
93
114
|
const sig = derivedKey.sign(Array.from(msgHash))
|
|
@@ -109,7 +130,9 @@ export async function handleMcpProxyCommand(): Promise<void> {
|
|
|
109
130
|
} catch {
|
|
110
131
|
startLog.set({ event: 'server_unreachable', url: MCP_URL })
|
|
111
132
|
startLog.emit()
|
|
112
|
-
process.stderr.write(
|
|
133
|
+
process.stderr.write(
|
|
134
|
+
`[1sat mcp-proxy] Server not reachable at ${MCP_URL} — is 1Sat wallet running?\n`,
|
|
135
|
+
)
|
|
113
136
|
process.exit(1)
|
|
114
137
|
}
|
|
115
138
|
|
|
@@ -156,7 +179,11 @@ export async function handleMcpProxyCommand(): Promise<void> {
|
|
|
156
179
|
method = JSON.parse(line).method
|
|
157
180
|
} catch {}
|
|
158
181
|
|
|
159
|
-
const res = await fetch(`${MCP_URL}/mcp`, {
|
|
182
|
+
const res = await fetch(`${MCP_URL}/mcp`, {
|
|
183
|
+
method: 'POST',
|
|
184
|
+
headers,
|
|
185
|
+
body: line,
|
|
186
|
+
})
|
|
160
187
|
|
|
161
188
|
const sessionHeader = res.headers.get('mcp-session-id')
|
|
162
189
|
if (sessionHeader) mcpSessionId = sessionHeader
|
|
@@ -202,13 +229,19 @@ export async function handleMcpProxyCommand(): Promise<void> {
|
|
|
202
229
|
}
|
|
203
230
|
} catch (err) {
|
|
204
231
|
const msg = err instanceof Error ? err.message : String(err)
|
|
205
|
-
reqLog.set({
|
|
232
|
+
reqLog.set({
|
|
233
|
+
event: 'request_failed',
|
|
234
|
+
requestNum: requestCount,
|
|
235
|
+
error: msg,
|
|
236
|
+
})
|
|
206
237
|
reqLog.emit()
|
|
207
|
-
process.stdout.write(
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
238
|
+
process.stdout.write(
|
|
239
|
+
`${JSON.stringify({
|
|
240
|
+
jsonrpc: '2.0',
|
|
241
|
+
error: { code: -32000, message: `MCP proxy error: ${msg}` },
|
|
242
|
+
id: null,
|
|
243
|
+
})}\n`,
|
|
244
|
+
)
|
|
212
245
|
}
|
|
213
246
|
}
|
|
214
247
|
}
|
package/src/commands/remote.ts
CHANGED
|
@@ -133,9 +133,11 @@ async function remoteList(_args: string[], opts: GlobalFlags): Promise<void> {
|
|
|
133
133
|
})
|
|
134
134
|
|
|
135
135
|
try {
|
|
136
|
-
const backups = walletResult.storage.getBackupStores?.() ?? []
|
|
137
136
|
const config = loadConfig()
|
|
138
137
|
|
|
138
|
+
// Use config.backups for display (remoteClients only populated for active connections)
|
|
139
|
+
const backupUrls = config.backups ?? []
|
|
140
|
+
|
|
139
141
|
// Use config for active determination — WalletStorageManager internal state
|
|
140
142
|
// can be misleading (a backup may appear as active after addWalletStorageProvider)
|
|
141
143
|
const isRemoteActive = Boolean(config.activeRemote)
|
|
@@ -144,7 +146,7 @@ async function remoteList(_args: string[], opts: GlobalFlags): Promise<void> {
|
|
|
144
146
|
output(
|
|
145
147
|
{
|
|
146
148
|
activeStorage: isRemoteActive ? 'remote' : 'local',
|
|
147
|
-
backups:
|
|
149
|
+
backups: backupUrls,
|
|
148
150
|
config: {
|
|
149
151
|
activeRemote: config.activeRemote ?? null,
|
|
150
152
|
backups: config.backups ?? [],
|
|
@@ -156,27 +158,19 @@ async function remoteList(_args: string[], opts: GlobalFlags): Promise<void> {
|
|
|
156
158
|
}
|
|
157
159
|
|
|
158
160
|
console.log()
|
|
159
|
-
console.log(
|
|
161
|
+
console.log(
|
|
162
|
+
` ${bold('Active Storage:')} ${isRemoteActive ? 'remote' : 'local'}`,
|
|
163
|
+
)
|
|
160
164
|
if (isRemoteActive) {
|
|
161
|
-
console.log(
|
|
162
|
-
` ${bold('Active Remote:')} ${config.activeRemote}`,
|
|
163
|
-
)
|
|
165
|
+
console.log(` ${bold('Active Remote:')} ${config.activeRemote}`)
|
|
164
166
|
}
|
|
165
167
|
console.log()
|
|
166
|
-
if (
|
|
168
|
+
if (backupUrls.length === 0 && !config.backups?.length) {
|
|
167
169
|
console.log(' No remote storages configured')
|
|
168
170
|
} else {
|
|
169
171
|
console.log(` ${bold('Backups:')}`)
|
|
170
|
-
const
|
|
171
|
-
|
|
172
|
-
const isKnown = known.has(b)
|
|
173
|
-
console.log(` ${isKnown ? '●' : '○'} ${b}`)
|
|
174
|
-
}
|
|
175
|
-
// Show configured but not yet connected
|
|
176
|
-
for (const url of config.backups ?? []) {
|
|
177
|
-
if (!backups.includes(url)) {
|
|
178
|
-
console.log(` ? ${url} (not connected)`)
|
|
179
|
-
}
|
|
172
|
+
for (const url of backupUrls) {
|
|
173
|
+
console.log(` ● ${url}`)
|
|
180
174
|
}
|
|
181
175
|
}
|
|
182
176
|
console.log()
|
package/src/commands/sweep.ts
CHANGED
|
@@ -106,9 +106,7 @@ async function sweepScan(args: string[], opts: GlobalFlags): Promise<void> {
|
|
|
106
106
|
}
|
|
107
107
|
}
|
|
108
108
|
|
|
109
|
-
console.log(
|
|
110
|
-
`\n ${formatLabel('RUN Tokens:')} ${result.run.length}`,
|
|
111
|
-
)
|
|
109
|
+
console.log(`\n ${formatLabel('RUN Tokens:')} ${result.run.length}`)
|
|
112
110
|
if (result.run.length > 0) {
|
|
113
111
|
const runSats = result.run.reduce((sum, r) => sum + (r.satoshis ?? 0), 0)
|
|
114
112
|
console.log(
|
|
@@ -161,11 +159,15 @@ async function sweepImport(args: string[], opts: GlobalFlags): Promise<void> {
|
|
|
161
159
|
|
|
162
160
|
const hasFunding = scan.funding.length > 0
|
|
163
161
|
const hasOrdinals = scan.ordinals.length > 0
|
|
164
|
-
const hasTokens = scan.bsv21Tokens.some(
|
|
162
|
+
const hasTokens = scan.bsv21Tokens.some(
|
|
163
|
+
(t) => t.isActive && t.outputs.length > 0,
|
|
164
|
+
)
|
|
165
165
|
|
|
166
166
|
if (!hasFunding && !hasOrdinals && !hasTokens) {
|
|
167
167
|
if (scan.run.length > 0) {
|
|
168
|
-
fatal(
|
|
168
|
+
fatal(
|
|
169
|
+
`No sweepable UTXOs found at ${address} (${scan.run.length} RUN token output(s) excluded)`,
|
|
170
|
+
)
|
|
169
171
|
}
|
|
170
172
|
fatal(`No UTXOs found at ${address}`)
|
|
171
173
|
}
|
package/src/commands/wallet.ts
CHANGED
|
@@ -52,14 +52,17 @@ export async function handleWalletCommand(
|
|
|
52
52
|
send: 'Send BSV to an address (--to <addr> --sats <amount>)',
|
|
53
53
|
'send-all': 'Send all BSV to an address (--to <addr>)',
|
|
54
54
|
info: 'Show wallet info (address, balance, network)',
|
|
55
|
-
'list-outputs':
|
|
56
|
-
|
|
55
|
+
'list-outputs':
|
|
56
|
+
'List wallet outputs (--basket <name> [--tags <t1,t2>] [--limit N] [--include-tags] [--include <val>])',
|
|
57
|
+
'relinquish-output':
|
|
58
|
+
'Remove output from basket (--basket <name> --output <txid.vout>)',
|
|
57
59
|
'list-actions': 'List wallet actions [--labels <l1,l2>] [--limit N]',
|
|
58
60
|
'create-action': 'Create action (JSON args)',
|
|
59
61
|
'sign-action': 'Sign action (JSON args)',
|
|
60
62
|
'abort-action': 'Abort action (--reference <ref>)',
|
|
61
63
|
'list-certificates': 'List certificates',
|
|
62
|
-
'relinquish-certificate':
|
|
64
|
+
'relinquish-certificate':
|
|
65
|
+
'Relinquish certificate (--type <t> --serialNumber <s> --certifier <c>)',
|
|
63
66
|
})
|
|
64
67
|
if (subcommand && subcommand !== 'help') {
|
|
65
68
|
process.exit(1)
|
|
@@ -244,17 +247,23 @@ async function walletInfo(_args: string[], opts: GlobalFlags): Promise<void> {
|
|
|
244
247
|
|
|
245
248
|
// BRC-100 Interface Commands
|
|
246
249
|
|
|
247
|
-
async function walletListOutputs(
|
|
250
|
+
async function walletListOutputs(
|
|
251
|
+
args: string[],
|
|
252
|
+
opts: GlobalFlags,
|
|
253
|
+
): Promise<void> {
|
|
248
254
|
const basket = extractFlag(args, '--basket')
|
|
249
255
|
if (!basket) fatal('Missing required --basket <name>')
|
|
250
256
|
|
|
251
257
|
const tags = extractFlags(args, '--tags')
|
|
252
258
|
const limitStr = extractFlag(args, '--limit')
|
|
253
|
-
const limit = limitStr ? parseInt(limitStr, 10) : 10
|
|
259
|
+
const limit = limitStr ? Number.parseInt(limitStr, 10) : 10
|
|
254
260
|
if (!Number.isFinite(limit) || limit < 1 || limit > 10000) {
|
|
255
261
|
fatal('--limit must be between 1 and 10000')
|
|
256
262
|
}
|
|
257
263
|
|
|
264
|
+
const includeTags = args.includes('--include-tags')
|
|
265
|
+
const include = extractFlag(args, '--include')
|
|
266
|
+
|
|
258
267
|
const privateKey = await loadKey(resolvePassword())
|
|
259
268
|
const { ctx, destroy } = await loadContext(privateKey, {
|
|
260
269
|
chain: opts.chain,
|
|
@@ -264,6 +273,8 @@ async function walletListOutputs(args: string[], opts: GlobalFlags): Promise<voi
|
|
|
264
273
|
const listArgs: Parameters<typeof ctx.wallet.listOutputs>[0] = {
|
|
265
274
|
basket,
|
|
266
275
|
limit,
|
|
276
|
+
includeTags,
|
|
277
|
+
include,
|
|
267
278
|
}
|
|
268
279
|
if (tags.length > 0) {
|
|
269
280
|
listArgs.tags = tags
|
|
@@ -274,7 +285,9 @@ async function walletListOutputs(args: string[], opts: GlobalFlags): Promise<voi
|
|
|
274
285
|
if (opts.json) {
|
|
275
286
|
output(result, opts)
|
|
276
287
|
} else {
|
|
277
|
-
console.log(
|
|
288
|
+
console.log(
|
|
289
|
+
`\n${result.totalOutputs} total outputs in basket '${basket}':\n`,
|
|
290
|
+
)
|
|
278
291
|
for (const out of result.outputs) {
|
|
279
292
|
const tags = out.tags?.join(', ') || 'none'
|
|
280
293
|
console.log(` ${out.outpoint} | ${out.satoshis} sats | tags: ${tags}`)
|
|
@@ -307,7 +320,10 @@ async function walletRelinquishOutput(
|
|
|
307
320
|
})
|
|
308
321
|
|
|
309
322
|
try {
|
|
310
|
-
const result = await ctx.wallet.relinquishOutput({
|
|
323
|
+
const result = await ctx.wallet.relinquishOutput({
|
|
324
|
+
basket,
|
|
325
|
+
output: outpoint,
|
|
326
|
+
})
|
|
311
327
|
|
|
312
328
|
if (opts.json) {
|
|
313
329
|
output(result, opts)
|
|
@@ -319,10 +335,13 @@ async function walletRelinquishOutput(
|
|
|
319
335
|
}
|
|
320
336
|
}
|
|
321
337
|
|
|
322
|
-
async function walletListActions(
|
|
338
|
+
async function walletListActions(
|
|
339
|
+
args: string[],
|
|
340
|
+
opts: GlobalFlags,
|
|
341
|
+
): Promise<void> {
|
|
323
342
|
const labels = extractFlags(args, '--labels')
|
|
324
343
|
const limitStr = extractFlag(args, '--limit')
|
|
325
|
-
const limit = limitStr ? parseInt(limitStr, 10) : 10
|
|
344
|
+
const limit = limitStr ? Number.parseInt(limitStr, 10) : 10
|
|
326
345
|
if (!Number.isFinite(limit) || limit < 1 || limit > 10000) {
|
|
327
346
|
fatal('--limit must be between 1 and 10000')
|
|
328
347
|
}
|
|
@@ -354,10 +373,14 @@ async function walletListActions(args: string[], opts: GlobalFlags): Promise<voi
|
|
|
354
373
|
}
|
|
355
374
|
}
|
|
356
375
|
|
|
357
|
-
async function walletCreateAction(
|
|
376
|
+
async function walletCreateAction(
|
|
377
|
+
args: string[],
|
|
378
|
+
opts: GlobalFlags,
|
|
379
|
+
): Promise<void> {
|
|
358
380
|
const jsonInput = args[0]
|
|
359
381
|
|
|
360
|
-
if (!jsonInput)
|
|
382
|
+
if (!jsonInput)
|
|
383
|
+
fatal("Missing JSON arguments. Usage: wallet create-action '{...}'")
|
|
361
384
|
|
|
362
385
|
let actionArgs: Parameters<typeof ctx.wallet.createAction>[0]
|
|
363
386
|
try {
|
|
@@ -379,10 +402,14 @@ async function walletCreateAction(args: string[], opts: GlobalFlags): Promise<vo
|
|
|
379
402
|
}
|
|
380
403
|
}
|
|
381
404
|
|
|
382
|
-
async function walletSignAction(
|
|
405
|
+
async function walletSignAction(
|
|
406
|
+
args: string[],
|
|
407
|
+
opts: GlobalFlags,
|
|
408
|
+
): Promise<void> {
|
|
383
409
|
const jsonInput = args[0]
|
|
384
410
|
|
|
385
|
-
if (!jsonInput)
|
|
411
|
+
if (!jsonInput)
|
|
412
|
+
fatal("Missing JSON arguments. Usage: wallet sign-action '{...}'")
|
|
386
413
|
|
|
387
414
|
let signArgs: Parameters<typeof ctx.wallet.signAction>[0]
|
|
388
415
|
try {
|
|
@@ -404,7 +431,10 @@ async function walletSignAction(args: string[], opts: GlobalFlags): Promise<void
|
|
|
404
431
|
}
|
|
405
432
|
}
|
|
406
433
|
|
|
407
|
-
async function walletAbortAction(
|
|
434
|
+
async function walletAbortAction(
|
|
435
|
+
args: string[],
|
|
436
|
+
opts: GlobalFlags,
|
|
437
|
+
): Promise<void> {
|
|
408
438
|
const reference = extractFlag(args, '--reference')
|
|
409
439
|
|
|
410
440
|
if (!reference) fatal('Missing required --reference <ref>')
|
|
@@ -429,7 +459,7 @@ async function walletListCertificates(
|
|
|
429
459
|
const certifiers = extractFlags(args, '--certifiers')
|
|
430
460
|
const types = extractFlags(args, '--types')
|
|
431
461
|
const limitStr = extractFlag(args, '--limit')
|
|
432
|
-
const limit = limitStr ? parseInt(limitStr, 10) : 10
|
|
462
|
+
const limit = limitStr ? Number.parseInt(limitStr, 10) : 10
|
|
433
463
|
|
|
434
464
|
if (!Number.isFinite(limit) || limit < 1 || limit > 10000) {
|
|
435
465
|
fatal('--limit must be between 1 and 10000')
|
package/src/context.ts
CHANGED
|
@@ -38,7 +38,20 @@ async function runMonitorIfStale(
|
|
|
38
38
|
const intervalMs = intervalMinutes * 60 * 1000
|
|
39
39
|
|
|
40
40
|
if (elapsed >= intervalMs) {
|
|
41
|
-
|
|
41
|
+
const originalLog = console.log
|
|
42
|
+
const originalInfo = console.info
|
|
43
|
+
const originalWarn = console.warn
|
|
44
|
+
console.log = () => {}
|
|
45
|
+
console.info = () => {}
|
|
46
|
+
console.warn = () => {}
|
|
47
|
+
|
|
48
|
+
try {
|
|
49
|
+
await walletResult.monitor.runOnce()
|
|
50
|
+
} finally {
|
|
51
|
+
console.log = originalLog
|
|
52
|
+
console.info = originalInfo
|
|
53
|
+
console.warn = originalWarn
|
|
54
|
+
}
|
|
42
55
|
saveMonitorState({ lastMonitorRun: Date.now() })
|
|
43
56
|
}
|
|
44
57
|
}
|
package/src/help.ts
CHANGED
|
@@ -85,6 +85,7 @@ ${bold('Locks:')}
|
|
|
85
85
|
|
|
86
86
|
${bold('Identity (BAP):')}
|
|
87
87
|
${cyan('identity create')} Create a new BAP identity
|
|
88
|
+
${cyan('identity update-profile')} Update BAP identity profile (--profile <json>)
|
|
88
89
|
${cyan('identity info')} Show identity information
|
|
89
90
|
${cyan('identity sign')} Sign a message with identity key
|
|
90
91
|
${cyan('identity verify')} Verify a signed message
|