openclaw-overlay-plugin 0.7.22
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/README.md +406 -0
- package/SKILL.md +78 -0
- package/clawdbot.plugin.json +106 -0
- package/dist/cli-main.d.ts +7 -0
- package/dist/cli-main.js +192 -0
- package/dist/cli.d.ts +8 -0
- package/dist/cli.js +14 -0
- package/dist/core/config.d.ts +11 -0
- package/dist/core/config.js +13 -0
- package/dist/core/index.d.ts +25 -0
- package/dist/core/index.js +26 -0
- package/dist/core/payment.d.ts +16 -0
- package/dist/core/payment.js +94 -0
- package/dist/core/types.d.ts +94 -0
- package/dist/core/types.js +4 -0
- package/dist/core/verify.d.ts +28 -0
- package/dist/core/verify.js +104 -0
- package/dist/core/wallet.d.ts +99 -0
- package/dist/core/wallet.js +219 -0
- package/dist/scripts/baemail/commands.d.ts +64 -0
- package/dist/scripts/baemail/commands.js +258 -0
- package/dist/scripts/baemail/handler.d.ts +36 -0
- package/dist/scripts/baemail/handler.js +284 -0
- package/dist/scripts/baemail/index.d.ts +5 -0
- package/dist/scripts/baemail/index.js +5 -0
- package/dist/scripts/config.d.ts +48 -0
- package/dist/scripts/config.js +68 -0
- package/dist/scripts/index.d.ts +7 -0
- package/dist/scripts/index.js +7 -0
- package/dist/scripts/messaging/connect.d.ts +8 -0
- package/dist/scripts/messaging/connect.js +114 -0
- package/dist/scripts/messaging/handlers.d.ts +21 -0
- package/dist/scripts/messaging/handlers.js +334 -0
- package/dist/scripts/messaging/inbox.d.ts +11 -0
- package/dist/scripts/messaging/inbox.js +51 -0
- package/dist/scripts/messaging/index.d.ts +8 -0
- package/dist/scripts/messaging/index.js +8 -0
- package/dist/scripts/messaging/poll.d.ts +7 -0
- package/dist/scripts/messaging/poll.js +52 -0
- package/dist/scripts/messaging/send.d.ts +7 -0
- package/dist/scripts/messaging/send.js +43 -0
- package/dist/scripts/output.d.ts +12 -0
- package/dist/scripts/output.js +19 -0
- package/dist/scripts/overlay/discover.d.ts +7 -0
- package/dist/scripts/overlay/discover.js +72 -0
- package/dist/scripts/overlay/index.d.ts +7 -0
- package/dist/scripts/overlay/index.js +7 -0
- package/dist/scripts/overlay/registration.d.ts +19 -0
- package/dist/scripts/overlay/registration.js +176 -0
- package/dist/scripts/overlay/services.d.ts +29 -0
- package/dist/scripts/overlay/services.js +167 -0
- package/dist/scripts/overlay/transaction.d.ts +42 -0
- package/dist/scripts/overlay/transaction.js +103 -0
- package/dist/scripts/payment/build.d.ts +24 -0
- package/dist/scripts/payment/build.js +54 -0
- package/dist/scripts/payment/commands.d.ts +15 -0
- package/dist/scripts/payment/commands.js +73 -0
- package/dist/scripts/payment/index.d.ts +6 -0
- package/dist/scripts/payment/index.js +6 -0
- package/dist/scripts/payment/types.d.ts +56 -0
- package/dist/scripts/payment/types.js +4 -0
- package/dist/scripts/services/index.d.ts +6 -0
- package/dist/scripts/services/index.js +6 -0
- package/dist/scripts/services/queue.d.ts +11 -0
- package/dist/scripts/services/queue.js +28 -0
- package/dist/scripts/services/request.d.ts +7 -0
- package/dist/scripts/services/request.js +82 -0
- package/dist/scripts/services/respond.d.ts +11 -0
- package/dist/scripts/services/respond.js +132 -0
- package/dist/scripts/types.d.ts +107 -0
- package/dist/scripts/types.js +4 -0
- package/dist/scripts/utils/index.d.ts +6 -0
- package/dist/scripts/utils/index.js +6 -0
- package/dist/scripts/utils/merkle.d.ts +12 -0
- package/dist/scripts/utils/merkle.js +47 -0
- package/dist/scripts/utils/storage.d.ts +66 -0
- package/dist/scripts/utils/storage.js +211 -0
- package/dist/scripts/utils/woc.d.ts +26 -0
- package/dist/scripts/utils/woc.js +91 -0
- package/dist/scripts/wallet/balance.d.ts +22 -0
- package/dist/scripts/wallet/balance.js +240 -0
- package/dist/scripts/wallet/identity.d.ts +70 -0
- package/dist/scripts/wallet/identity.js +151 -0
- package/dist/scripts/wallet/index.d.ts +6 -0
- package/dist/scripts/wallet/index.js +6 -0
- package/dist/scripts/wallet/setup.d.ts +15 -0
- package/dist/scripts/wallet/setup.js +105 -0
- package/dist/scripts/x-verification/commands.d.ts +27 -0
- package/dist/scripts/x-verification/commands.js +222 -0
- package/dist/scripts/x-verification/index.d.ts +4 -0
- package/dist/scripts/x-verification/index.js +4 -0
- package/dist/services/built-in/api-proxy/index.d.ts +6 -0
- package/dist/services/built-in/api-proxy/index.js +23 -0
- package/dist/services/built-in/code-develop/index.d.ts +6 -0
- package/dist/services/built-in/code-develop/index.js +23 -0
- package/dist/services/built-in/code-review/index.d.ts +10 -0
- package/dist/services/built-in/code-review/index.js +51 -0
- package/dist/services/built-in/image-analysis/index.d.ts +6 -0
- package/dist/services/built-in/image-analysis/index.js +33 -0
- package/dist/services/built-in/memory-store/index.d.ts +6 -0
- package/dist/services/built-in/memory-store/index.js +22 -0
- package/dist/services/built-in/roulette/index.d.ts +6 -0
- package/dist/services/built-in/roulette/index.js +27 -0
- package/dist/services/built-in/summarize/index.d.ts +6 -0
- package/dist/services/built-in/summarize/index.js +21 -0
- package/dist/services/built-in/tell-joke/handler.d.ts +7 -0
- package/dist/services/built-in/tell-joke/handler.js +122 -0
- package/dist/services/built-in/tell-joke/index.d.ts +9 -0
- package/dist/services/built-in/tell-joke/index.js +31 -0
- package/dist/services/built-in/translate/index.d.ts +6 -0
- package/dist/services/built-in/translate/index.js +21 -0
- package/dist/services/built-in/web-research/index.d.ts +9 -0
- package/dist/services/built-in/web-research/index.js +51 -0
- package/dist/services/index.d.ts +13 -0
- package/dist/services/index.js +14 -0
- package/dist/services/loader.d.ts +77 -0
- package/dist/services/loader.js +292 -0
- package/dist/services/manager.d.ts +86 -0
- package/dist/services/manager.js +255 -0
- package/dist/services/registry.d.ts +98 -0
- package/dist/services/registry.js +204 -0
- package/dist/services/types.d.ts +230 -0
- package/dist/services/types.js +30 -0
- package/dist/test/cli.test.d.ts +7 -0
- package/dist/test/cli.test.js +329 -0
- package/dist/test/comprehensive-overlay.test.d.ts +13 -0
- package/dist/test/comprehensive-overlay.test.js +593 -0
- package/dist/test/key-derivation.test.d.ts +12 -0
- package/dist/test/key-derivation.test.js +86 -0
- package/dist/test/overlay-submit.test.d.ts +10 -0
- package/dist/test/overlay-submit.test.js +460 -0
- package/dist/test/request-response-flow.test.d.ts +5 -0
- package/dist/test/request-response-flow.test.js +209 -0
- package/dist/test/service-system.test.d.ts +5 -0
- package/dist/test/service-system.test.js +190 -0
- package/dist/test/utils/server-logic.d.ts +98 -0
- package/dist/test/utils/server-logic.js +286 -0
- package/dist/test/wallet.test.d.ts +7 -0
- package/dist/test/wallet.test.js +146 -0
- package/index.ts +1965 -0
- package/openclaw.plugin.json +106 -0
- package/package.json +73 -0
- package/src/cli-main.ts +230 -0
- package/src/cli.ts +16 -0
- package/src/core/README.md +246 -0
- package/src/core/config.ts +21 -0
- package/src/core/index.ts +42 -0
- package/src/core/payment.ts +111 -0
- package/src/core/types.ts +102 -0
- package/src/core/verify.ts +119 -0
- package/src/core/wallet.ts +282 -0
- package/src/scripts/baemail/commands.ts +326 -0
- package/src/scripts/baemail/handler.ts +338 -0
- package/src/scripts/baemail/index.ts +6 -0
- package/src/scripts/config.ts +81 -0
- package/src/scripts/index.ts +8 -0
- package/src/scripts/messaging/connect.ts +121 -0
- package/src/scripts/messaging/handlers.ts +394 -0
- package/src/scripts/messaging/inbox.ts +64 -0
- package/src/scripts/messaging/index.ts +9 -0
- package/src/scripts/messaging/poll.ts +59 -0
- package/src/scripts/messaging/send.ts +54 -0
- package/src/scripts/output.ts +21 -0
- package/src/scripts/overlay/discover.ts +81 -0
- package/src/scripts/overlay/index.ts +8 -0
- package/src/scripts/overlay/registration.ts +199 -0
- package/src/scripts/overlay/services.ts +199 -0
- package/src/scripts/overlay/transaction.ts +124 -0
- package/src/scripts/payment/build.ts +65 -0
- package/src/scripts/payment/commands.ts +92 -0
- package/src/scripts/payment/index.ts +7 -0
- package/src/scripts/payment/types.ts +62 -0
- package/src/scripts/services/index.ts +7 -0
- package/src/scripts/services/queue.ts +35 -0
- package/src/scripts/services/request.ts +98 -0
- package/src/scripts/services/respond.ts +149 -0
- package/src/scripts/types.ts +121 -0
- package/src/scripts/utils/index.ts +7 -0
- package/src/scripts/utils/merkle.ts +57 -0
- package/src/scripts/utils/storage.ts +231 -0
- package/src/scripts/utils/woc.ts +106 -0
- package/src/scripts/wallet/balance.ts +277 -0
- package/src/scripts/wallet/identity.ts +203 -0
- package/src/scripts/wallet/index.ts +7 -0
- package/src/scripts/wallet/setup.ts +121 -0
- package/src/scripts/x-verification/commands.ts +256 -0
- package/src/scripts/x-verification/index.ts +5 -0
- package/src/services/built-in/api-proxy/index.ts +26 -0
- package/src/services/built-in/api-proxy/prompt.md +26 -0
- package/src/services/built-in/code-develop/index.ts +26 -0
- package/src/services/built-in/code-develop/prompt.md +35 -0
- package/src/services/built-in/code-review/index.ts +54 -0
- package/src/services/built-in/code-review/prompt.md +105 -0
- package/src/services/built-in/image-analysis/index.ts +36 -0
- package/src/services/built-in/image-analysis/prompt.md +42 -0
- package/src/services/built-in/memory-store/index.ts +25 -0
- package/src/services/built-in/memory-store/prompt.md +45 -0
- package/src/services/built-in/roulette/index.ts +30 -0
- package/src/services/built-in/roulette/prompt.md +35 -0
- package/src/services/built-in/summarize/index.ts +24 -0
- package/src/services/built-in/summarize/prompt.md +27 -0
- package/src/services/built-in/tell-joke/handler.ts +134 -0
- package/src/services/built-in/tell-joke/index.ts +34 -0
- package/src/services/built-in/tell-joke/prompt.md +59 -0
- package/src/services/built-in/translate/index.ts +24 -0
- package/src/services/built-in/translate/prompt.md +23 -0
- package/src/services/built-in/web-research/index.ts +54 -0
- package/src/services/built-in/web-research/prompt.md +110 -0
- package/src/services/index.ts +16 -0
- package/src/services/loader.ts +344 -0
- package/src/services/manager.ts +304 -0
- package/src/services/registry.ts +246 -0
- package/src/services/types.ts +259 -0
- package/src/test/cli.test.ts +352 -0
- package/src/test/comprehensive-overlay.test.ts +729 -0
- package/src/test/key-derivation.test.ts +102 -0
- package/src/test/overlay-submit.test.ts +570 -0
- package/src/test/request-response-flow.test.ts +252 -0
- package/src/test/service-system.test.ts +241 -0
- package/src/test/utils/server-logic.ts +368 -0
- package/src/test/wallet.test.ts +166 -0
|
@@ -0,0 +1,176 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Overlay registration commands: register, unregister.
|
|
3
|
+
*
|
|
4
|
+
* Registration creates an identity record on the overlay network with:
|
|
5
|
+
* - identityKey: compressed public key (66 hex chars)
|
|
6
|
+
* - name: agent display name
|
|
7
|
+
* - description: what the agent does
|
|
8
|
+
* - channels: contact methods (e.g., { overlay: "https://..." })
|
|
9
|
+
* - capabilities: what the agent can do (e.g., ["services", "jokes"])
|
|
10
|
+
* - timestamp: ISO 8601 registration time
|
|
11
|
+
*/
|
|
12
|
+
import fs from 'node:fs';
|
|
13
|
+
import { NETWORK, WALLET_DIR, OVERLAY_URL, PROTOCOL_ID, TOPICS, PATHS, AGENT_NAME, AGENT_DESCRIPTION } from '../config.js';
|
|
14
|
+
import { ok, fail } from '../output.js';
|
|
15
|
+
import { loadRegistration, saveRegistration, deleteRegistration, loadServices } from '../utils/storage.js';
|
|
16
|
+
import { buildRealOverlayTransaction } from './transaction.js';
|
|
17
|
+
import { Transaction, Beef, Script, PushDrop } from '@bsv/sdk';
|
|
18
|
+
import { BSVAgentWallet } from '../../core/index.js';
|
|
19
|
+
async function getBSVAgentWallet() {
|
|
20
|
+
return BSVAgentWallet;
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* Register command: register this agent on the overlay network.
|
|
24
|
+
*/
|
|
25
|
+
export async function cmdRegister() {
|
|
26
|
+
if (!fs.existsSync(PATHS.walletIdentity)) {
|
|
27
|
+
return fail('Wallet not initialized. Run: setup');
|
|
28
|
+
}
|
|
29
|
+
const BSVAgentWallet = await getBSVAgentWallet();
|
|
30
|
+
const wallet = await BSVAgentWallet.load({ network: NETWORK, storageDir: WALLET_DIR });
|
|
31
|
+
const identityKey = await wallet.getIdentityKey();
|
|
32
|
+
await wallet.destroy();
|
|
33
|
+
const existingReg = loadRegistration();
|
|
34
|
+
if (existingReg && existingReg.identityKey === identityKey) {
|
|
35
|
+
return ok({
|
|
36
|
+
alreadyRegistered: true,
|
|
37
|
+
identityKey,
|
|
38
|
+
identityTxid: existingReg.identityTxid,
|
|
39
|
+
overlayUrl: OVERLAY_URL,
|
|
40
|
+
});
|
|
41
|
+
}
|
|
42
|
+
// Agent metadata from environment/config
|
|
43
|
+
const agentName = AGENT_NAME;
|
|
44
|
+
const agentDescription = AGENT_DESCRIPTION;
|
|
45
|
+
// Build capabilities list based on what services we might offer
|
|
46
|
+
const capabilities = ['services'];
|
|
47
|
+
const services = loadServices();
|
|
48
|
+
if (services.some(s => s.serviceId === 'tell-joke')) {
|
|
49
|
+
capabilities.push('jokes');
|
|
50
|
+
}
|
|
51
|
+
// Create identity record on-chain
|
|
52
|
+
// This payload format matches the clawdbot-overlay server's expected schema
|
|
53
|
+
const identityPayload = {
|
|
54
|
+
protocol: PROTOCOL_ID,
|
|
55
|
+
type: 'identity',
|
|
56
|
+
identityKey,
|
|
57
|
+
name: agentName,
|
|
58
|
+
description: agentDescription,
|
|
59
|
+
channels: {
|
|
60
|
+
overlay: OVERLAY_URL,
|
|
61
|
+
},
|
|
62
|
+
capabilities,
|
|
63
|
+
timestamp: new Date().toISOString(),
|
|
64
|
+
};
|
|
65
|
+
let identityResult;
|
|
66
|
+
try {
|
|
67
|
+
identityResult = await buildRealOverlayTransaction(identityPayload, TOPICS.IDENTITY);
|
|
68
|
+
}
|
|
69
|
+
catch (err) {
|
|
70
|
+
return fail(`Registration failed: ${err.message}`);
|
|
71
|
+
}
|
|
72
|
+
// Optionally register services if pre-configured
|
|
73
|
+
let serviceTxid = null;
|
|
74
|
+
if (services.length > 0) {
|
|
75
|
+
// Register each service individually (server expects 'service' type, not 'service-bundle')
|
|
76
|
+
for (const service of services) {
|
|
77
|
+
const servicePayload = {
|
|
78
|
+
protocol: PROTOCOL_ID,
|
|
79
|
+
type: 'service',
|
|
80
|
+
identityKey,
|
|
81
|
+
serviceId: service.serviceId,
|
|
82
|
+
name: service.name,
|
|
83
|
+
description: service.description,
|
|
84
|
+
pricing: {
|
|
85
|
+
model: 'per-task',
|
|
86
|
+
amountSats: service.priceSats,
|
|
87
|
+
},
|
|
88
|
+
timestamp: new Date().toISOString(),
|
|
89
|
+
};
|
|
90
|
+
try {
|
|
91
|
+
const serviceResult = await buildRealOverlayTransaction(servicePayload, TOPICS.SERVICES);
|
|
92
|
+
serviceTxid = serviceResult.txid; // Keep last one for backward compat
|
|
93
|
+
}
|
|
94
|
+
catch {
|
|
95
|
+
// Non-fatal — identity registered but this service failed
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
// Save registration
|
|
100
|
+
const registration = {
|
|
101
|
+
identityKey,
|
|
102
|
+
agentName,
|
|
103
|
+
agentDescription,
|
|
104
|
+
overlayUrl: OVERLAY_URL,
|
|
105
|
+
identityTxid: identityResult.txid,
|
|
106
|
+
serviceTxid,
|
|
107
|
+
funded: identityResult.funded,
|
|
108
|
+
registeredAt: new Date().toISOString(),
|
|
109
|
+
};
|
|
110
|
+
saveRegistration(registration);
|
|
111
|
+
return ok({
|
|
112
|
+
registered: true,
|
|
113
|
+
identityKey,
|
|
114
|
+
identityTxid: identityResult.txid,
|
|
115
|
+
serviceTxid,
|
|
116
|
+
overlayUrl: OVERLAY_URL,
|
|
117
|
+
funded: identityResult.funded,
|
|
118
|
+
stateFile: PATHS.registration,
|
|
119
|
+
});
|
|
120
|
+
}
|
|
121
|
+
/**
|
|
122
|
+
* Unregister command: submit revocation tx to remove agent from overlay network.
|
|
123
|
+
*/
|
|
124
|
+
export async function cmdUnregister() {
|
|
125
|
+
const wallet = await BSVAgentWallet.load({ network: NETWORK, storageDir: WALLET_DIR });
|
|
126
|
+
const { outputs, BEEF } = await wallet._setup.wallet.listOutputs({ basket: TOPICS.IDENTITY, include: 'entire transactions' });
|
|
127
|
+
const token = new PushDrop(wallet._setup.wallet);
|
|
128
|
+
const unlockingScriptTemplate = await token.unlock([0, PROTOCOL_ID], '1', 'self', 'none', true);
|
|
129
|
+
const tempTx = new Transaction();
|
|
130
|
+
const beef = Beef.fromBinary(BEEF);
|
|
131
|
+
outputs.forEach((o) => {
|
|
132
|
+
const [txid, v] = o.outpoint.split('.');
|
|
133
|
+
const sourceOutputIndex = Number(v);
|
|
134
|
+
const sourceTransaction = beef.findTransactionForSigning(txid);
|
|
135
|
+
tempTx.addInput({
|
|
136
|
+
unlockingScriptTemplate,
|
|
137
|
+
sourceOutputIndex,
|
|
138
|
+
sourceTransaction
|
|
139
|
+
});
|
|
140
|
+
});
|
|
141
|
+
tempTx.addOutput({
|
|
142
|
+
lockingScript: Script.fromASM('OP_FALSE OP_RETURN 330123'),
|
|
143
|
+
satoshis: 0
|
|
144
|
+
});
|
|
145
|
+
await tempTx.sign();
|
|
146
|
+
const response = await wallet._setup.wallet.createAction({
|
|
147
|
+
inputBEEF: BEEF,
|
|
148
|
+
description: 'revoke registration token',
|
|
149
|
+
inputs: tempTx.inputs.map(o => ({
|
|
150
|
+
inputDescription: 'previous registration',
|
|
151
|
+
outpoint: o.sourceTXID + '.' + String(o.sourceOutputIndex),
|
|
152
|
+
unlockingScript: o.unlockingScript?.toHex()
|
|
153
|
+
}))
|
|
154
|
+
});
|
|
155
|
+
const txid = response.txid;
|
|
156
|
+
// --- Submit to overlay ---
|
|
157
|
+
// Use binary BEEF with X-Topics header (matches clawdbot-overlay server API)
|
|
158
|
+
const submitResp = await fetch(`${OVERLAY_URL}/submit`, {
|
|
159
|
+
method: 'POST',
|
|
160
|
+
headers: {
|
|
161
|
+
'Content-Type': 'application/octet-stream',
|
|
162
|
+
'X-Topics': JSON.stringify([TOPICS.IDENTITY]),
|
|
163
|
+
},
|
|
164
|
+
body: new Uint8Array(response.tx),
|
|
165
|
+
});
|
|
166
|
+
if (!submitResp.ok) {
|
|
167
|
+
const errText = await submitResp.text();
|
|
168
|
+
throw new Error(`Overlay submission failed: ${submitResp.status} — ${errText}`);
|
|
169
|
+
}
|
|
170
|
+
// Delete local registration
|
|
171
|
+
deleteRegistration();
|
|
172
|
+
return ok({
|
|
173
|
+
unregistered: true,
|
|
174
|
+
txid
|
|
175
|
+
});
|
|
176
|
+
}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Overlay service commands: services, advertise, remove, readvertise.
|
|
3
|
+
*
|
|
4
|
+
* Service payloads match the clawdbot-overlay server schema:
|
|
5
|
+
* - protocol: "clawdbot-overlay-v1"
|
|
6
|
+
* - type: "service"
|
|
7
|
+
* - identityKey: provider's compressed public key
|
|
8
|
+
* - serviceId: unique service identifier
|
|
9
|
+
* - name: human-readable name
|
|
10
|
+
* - description: what the service does
|
|
11
|
+
* - pricing: { model: "per-task", amountSats: number }
|
|
12
|
+
* - timestamp: ISO 8601 time
|
|
13
|
+
*/
|
|
14
|
+
/**
|
|
15
|
+
* Services command: list currently advertised services.
|
|
16
|
+
*/
|
|
17
|
+
export declare function cmdServices(): Promise<never>;
|
|
18
|
+
/**
|
|
19
|
+
* Advertise command: add a new service advertisement.
|
|
20
|
+
*/
|
|
21
|
+
export declare function cmdAdvertise(serviceId: string | undefined, name: string | undefined, priceSatsStr: string | undefined, description?: string): Promise<never>;
|
|
22
|
+
/**
|
|
23
|
+
* Remove command: remove a service from local registry.
|
|
24
|
+
*/
|
|
25
|
+
export declare function cmdRemove(serviceId: string | undefined): Promise<never>;
|
|
26
|
+
/**
|
|
27
|
+
* Readvertise command: update an existing service advertisement.
|
|
28
|
+
*/
|
|
29
|
+
export declare function cmdReadvertise(serviceId: string | undefined, name?: string, priceSatsStr?: string, description?: string): Promise<never>;
|
|
@@ -0,0 +1,167 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Overlay service commands: services, advertise, remove, readvertise.
|
|
3
|
+
*
|
|
4
|
+
* Service payloads match the clawdbot-overlay server schema:
|
|
5
|
+
* - protocol: "clawdbot-overlay-v1"
|
|
6
|
+
* - type: "service"
|
|
7
|
+
* - identityKey: provider's compressed public key
|
|
8
|
+
* - serviceId: unique service identifier
|
|
9
|
+
* - name: human-readable name
|
|
10
|
+
* - description: what the service does
|
|
11
|
+
* - pricing: { model: "per-task", amountSats: number }
|
|
12
|
+
* - timestamp: ISO 8601 time
|
|
13
|
+
*/
|
|
14
|
+
import { NETWORK, WALLET_DIR, PROTOCOL_ID, TOPICS } from '../config.js';
|
|
15
|
+
import { ok, fail } from '../output.js';
|
|
16
|
+
import { loadServices, saveServices } from '../utils/storage.js';
|
|
17
|
+
import { buildRealOverlayTransaction } from './transaction.js';
|
|
18
|
+
import { BSVAgentWallet } from '../../core/index.js';
|
|
19
|
+
async function getBSVAgentWallet() {
|
|
20
|
+
return BSVAgentWallet;
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* Services command: list currently advertised services.
|
|
24
|
+
*/
|
|
25
|
+
export async function cmdServices() {
|
|
26
|
+
const services = loadServices();
|
|
27
|
+
return ok({ services, count: services.length });
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Advertise command: add a new service advertisement.
|
|
31
|
+
*/
|
|
32
|
+
export async function cmdAdvertise(serviceId, name, priceSatsStr, description) {
|
|
33
|
+
if (!serviceId || !name || !priceSatsStr) {
|
|
34
|
+
return fail('Usage: advertise <serviceId> <name> <priceSats> [description]');
|
|
35
|
+
}
|
|
36
|
+
const priceSats = parseInt(priceSatsStr, 10);
|
|
37
|
+
if (isNaN(priceSats) || priceSats < 0) {
|
|
38
|
+
return fail('priceSats must be a non-negative integer');
|
|
39
|
+
}
|
|
40
|
+
const BSVAgentWallet = await getBSVAgentWallet();
|
|
41
|
+
const wallet = await BSVAgentWallet.load({ network: NETWORK, storageDir: WALLET_DIR });
|
|
42
|
+
const identityKey = await wallet.getIdentityKey();
|
|
43
|
+
await wallet.destroy();
|
|
44
|
+
// Load existing services
|
|
45
|
+
const services = loadServices();
|
|
46
|
+
const existing = services.find(s => s.serviceId === serviceId);
|
|
47
|
+
if (existing) {
|
|
48
|
+
return fail(`Service '${serviceId}' already exists. Use 'readvertise' to update.`);
|
|
49
|
+
}
|
|
50
|
+
// Create service record (local storage format)
|
|
51
|
+
const newService = {
|
|
52
|
+
serviceId,
|
|
53
|
+
name,
|
|
54
|
+
description: description || `${name} service`,
|
|
55
|
+
priceSats,
|
|
56
|
+
registeredAt: new Date().toISOString(),
|
|
57
|
+
};
|
|
58
|
+
// Publish on-chain (matches clawdbot-overlay server schema)
|
|
59
|
+
const servicePayload = {
|
|
60
|
+
protocol: PROTOCOL_ID,
|
|
61
|
+
type: 'service',
|
|
62
|
+
identityKey,
|
|
63
|
+
serviceId,
|
|
64
|
+
name,
|
|
65
|
+
description: newService.description,
|
|
66
|
+
pricing: {
|
|
67
|
+
model: 'per-task',
|
|
68
|
+
amountSats: priceSats,
|
|
69
|
+
},
|
|
70
|
+
timestamp: new Date().toISOString(),
|
|
71
|
+
};
|
|
72
|
+
try {
|
|
73
|
+
const result = await buildRealOverlayTransaction(servicePayload, TOPICS.SERVICES);
|
|
74
|
+
newService.txid = result.txid;
|
|
75
|
+
// Save locally
|
|
76
|
+
services.push(newService);
|
|
77
|
+
saveServices(services);
|
|
78
|
+
return ok({
|
|
79
|
+
advertised: true,
|
|
80
|
+
service: newService,
|
|
81
|
+
txid: result.txid,
|
|
82
|
+
funded: result.funded,
|
|
83
|
+
});
|
|
84
|
+
}
|
|
85
|
+
catch (err) {
|
|
86
|
+
return fail(`Failed to advertise service: ${err.message}`);
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
/**
|
|
90
|
+
* Remove command: remove a service from local registry.
|
|
91
|
+
*/
|
|
92
|
+
export async function cmdRemove(serviceId) {
|
|
93
|
+
if (!serviceId) {
|
|
94
|
+
return fail('Usage: remove <serviceId>');
|
|
95
|
+
}
|
|
96
|
+
const services = loadServices();
|
|
97
|
+
const idx = services.findIndex(s => s.serviceId === serviceId);
|
|
98
|
+
if (idx === -1) {
|
|
99
|
+
return fail(`Service '${serviceId}' not found`);
|
|
100
|
+
}
|
|
101
|
+
const removed = services.splice(idx, 1)[0];
|
|
102
|
+
saveServices(services);
|
|
103
|
+
return ok({
|
|
104
|
+
removed: true,
|
|
105
|
+
service: removed,
|
|
106
|
+
note: 'Removed from local registry. On-chain record remains (blockchain is immutable).',
|
|
107
|
+
});
|
|
108
|
+
}
|
|
109
|
+
/**
|
|
110
|
+
* Readvertise command: update an existing service advertisement.
|
|
111
|
+
*/
|
|
112
|
+
export async function cmdReadvertise(serviceId, name, priceSatsStr, description) {
|
|
113
|
+
if (!serviceId) {
|
|
114
|
+
return fail('Usage: readvertise <serviceId> [name] [priceSats] [description]');
|
|
115
|
+
}
|
|
116
|
+
const services = loadServices();
|
|
117
|
+
const existing = services.find(s => s.serviceId === serviceId);
|
|
118
|
+
if (!existing) {
|
|
119
|
+
return fail(`Service '${serviceId}' not found. Use 'advertise' to create.`);
|
|
120
|
+
}
|
|
121
|
+
const BSVAgentWallet = await getBSVAgentWallet();
|
|
122
|
+
const wallet = await BSVAgentWallet.load({ network: NETWORK, storageDir: WALLET_DIR });
|
|
123
|
+
const identityKey = await wallet.getIdentityKey();
|
|
124
|
+
await wallet.destroy();
|
|
125
|
+
// Update fields if provided
|
|
126
|
+
if (name)
|
|
127
|
+
existing.name = name;
|
|
128
|
+
if (priceSatsStr) {
|
|
129
|
+
const priceSats = parseInt(priceSatsStr, 10);
|
|
130
|
+
if (isNaN(priceSats) || priceSats < 0) {
|
|
131
|
+
return fail('priceSats must be a non-negative integer');
|
|
132
|
+
}
|
|
133
|
+
existing.priceSats = priceSats;
|
|
134
|
+
}
|
|
135
|
+
if (description)
|
|
136
|
+
existing.description = description;
|
|
137
|
+
existing.registeredAt = new Date().toISOString();
|
|
138
|
+
// Publish update on-chain (matches clawdbot-overlay server schema)
|
|
139
|
+
const servicePayload = {
|
|
140
|
+
protocol: PROTOCOL_ID,
|
|
141
|
+
type: 'service',
|
|
142
|
+
identityKey,
|
|
143
|
+
serviceId,
|
|
144
|
+
name: existing.name,
|
|
145
|
+
description: existing.description,
|
|
146
|
+
pricing: {
|
|
147
|
+
model: 'per-task',
|
|
148
|
+
amountSats: existing.priceSats,
|
|
149
|
+
},
|
|
150
|
+
timestamp: existing.registeredAt,
|
|
151
|
+
};
|
|
152
|
+
try {
|
|
153
|
+
const result = await buildRealOverlayTransaction(servicePayload, TOPICS.SERVICES);
|
|
154
|
+
existing.txid = result.txid;
|
|
155
|
+
// Save locally
|
|
156
|
+
saveServices(services);
|
|
157
|
+
return ok({
|
|
158
|
+
readvertised: true,
|
|
159
|
+
service: existing,
|
|
160
|
+
txid: result.txid,
|
|
161
|
+
funded: result.funded,
|
|
162
|
+
});
|
|
163
|
+
}
|
|
164
|
+
catch (err) {
|
|
165
|
+
return fail(`Failed to readvertise service: ${err.message}`);
|
|
166
|
+
}
|
|
167
|
+
}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Overlay transaction building utilities.
|
|
3
|
+
*
|
|
4
|
+
* Follows the clawdbot-overlay server API:
|
|
5
|
+
* - Submit: POST /submit with binary BEEF and X-Topics header
|
|
6
|
+
* - OP_RETURN format: OP_FALSE OP_RETURN <"clawdbot-overlay-v1"> <JSON>
|
|
7
|
+
*/
|
|
8
|
+
import type { OverlayPayload } from '../types.js';
|
|
9
|
+
import { BSVAgentWallet } from '../../core/wallet.js';
|
|
10
|
+
/**
|
|
11
|
+
* Build an PushDrop locking script with JSON payload using SDK's Script class.
|
|
12
|
+
*
|
|
13
|
+
* @param payload - The data to embed in the OP_RETURN
|
|
14
|
+
* @returns A proper Script object that the SDK can serialize
|
|
15
|
+
*/
|
|
16
|
+
export declare function buildPushDropScript(wallet: BSVAgentWallet, payload: OverlayPayload): Promise<string>;
|
|
17
|
+
/**
|
|
18
|
+
* Build and submit an overlay transaction.
|
|
19
|
+
* @param payload - JSON data to store in OP_RETURN
|
|
20
|
+
* @param topic - Topic manager for submission
|
|
21
|
+
* @returns Transaction result with txid and funding info
|
|
22
|
+
*/
|
|
23
|
+
export declare function buildRealOverlayTransaction(payload: OverlayPayload, topic: string): Promise<{
|
|
24
|
+
txid: string;
|
|
25
|
+
funded: string;
|
|
26
|
+
explorer: string;
|
|
27
|
+
}>;
|
|
28
|
+
/**
|
|
29
|
+
* Lookup data from an overlay lookup service.
|
|
30
|
+
*/
|
|
31
|
+
export declare function lookupOverlay(service: string, query: Record<string, unknown>): Promise<any>;
|
|
32
|
+
/**
|
|
33
|
+
* Parse an overlay output from BEEF data.
|
|
34
|
+
*
|
|
35
|
+
* Handles both formats:
|
|
36
|
+
* - OP_FALSE OP_RETURN <protocol> <json> (standard)
|
|
37
|
+
* - OP_RETURN <protocol> <json> (legacy)
|
|
38
|
+
*/
|
|
39
|
+
export declare function parseOverlayOutput(beefData: string | Uint8Array | number[], outputIndex: number): Promise<{
|
|
40
|
+
data: OverlayPayload | null;
|
|
41
|
+
txid: string | null;
|
|
42
|
+
}>;
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Overlay transaction building utilities.
|
|
3
|
+
*
|
|
4
|
+
* Follows the clawdbot-overlay server API:
|
|
5
|
+
* - Submit: POST /submit with binary BEEF and X-Topics header
|
|
6
|
+
* - OP_RETURN format: OP_FALSE OP_RETURN <"clawdbot-overlay-v1"> <JSON>
|
|
7
|
+
*/
|
|
8
|
+
import { NETWORK, OVERLAY_URL, PROTOCOL_ID, WALLET_DIR } from '../config.js';
|
|
9
|
+
import { Utils, PushDrop, Transaction } from '@bsv/sdk';
|
|
10
|
+
import { BSVAgentWallet } from '../../core/wallet.js';
|
|
11
|
+
/**
|
|
12
|
+
* Build an PushDrop locking script with JSON payload using SDK's Script class.
|
|
13
|
+
*
|
|
14
|
+
* @param payload - The data to embed in the OP_RETURN
|
|
15
|
+
* @returns A proper Script object that the SDK can serialize
|
|
16
|
+
*/
|
|
17
|
+
export async function buildPushDropScript(wallet, payload) {
|
|
18
|
+
const jsonBytes = Utils.toArray(JSON.stringify(payload), 'utf8');
|
|
19
|
+
const fields = [jsonBytes];
|
|
20
|
+
const token = new PushDrop(wallet._setup.wallet);
|
|
21
|
+
const script = await token.lock(fields, [0, PROTOCOL_ID], '1', 'self', true, true);
|
|
22
|
+
return script.toHex();
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* Build and submit an overlay transaction.
|
|
26
|
+
* @param payload - JSON data to store in OP_RETURN
|
|
27
|
+
* @param topic - Topic manager for submission
|
|
28
|
+
* @returns Transaction result with txid and funding info
|
|
29
|
+
*/
|
|
30
|
+
export async function buildRealOverlayTransaction(payload, topic) {
|
|
31
|
+
const wallet = await BSVAgentWallet.load({ network: NETWORK, storageDir: WALLET_DIR });
|
|
32
|
+
const lockingScript = await buildPushDropScript(wallet, payload);
|
|
33
|
+
const response = await wallet._setup.wallet.createAction({
|
|
34
|
+
description: 'topic manager submission',
|
|
35
|
+
outputs: [
|
|
36
|
+
{
|
|
37
|
+
lockingScript,
|
|
38
|
+
satoshis: 1,
|
|
39
|
+
outputDescription: 'overlay',
|
|
40
|
+
basket: topic, // basket is the topic manager
|
|
41
|
+
}
|
|
42
|
+
],
|
|
43
|
+
options: {
|
|
44
|
+
acceptDelayedBroadcast: false,
|
|
45
|
+
}
|
|
46
|
+
});
|
|
47
|
+
// --- Submit to overlay ---
|
|
48
|
+
// Use binary BEEF with X-Topics header (matches clawdbot-overlay server API)
|
|
49
|
+
const submitResp = await fetch(`${OVERLAY_URL}/submit`, {
|
|
50
|
+
method: 'POST',
|
|
51
|
+
headers: {
|
|
52
|
+
'Content-Type': 'application/octet-stream',
|
|
53
|
+
'X-Topics': JSON.stringify([topic]),
|
|
54
|
+
},
|
|
55
|
+
body: new Uint8Array(response.tx),
|
|
56
|
+
});
|
|
57
|
+
if (!submitResp.ok) {
|
|
58
|
+
const errText = await submitResp.text();
|
|
59
|
+
throw new Error(`Overlay submission failed: ${submitResp.status} — ${errText}`);
|
|
60
|
+
}
|
|
61
|
+
const wocNet = NETWORK === 'mainnet' ? '' : 'test.';
|
|
62
|
+
return {
|
|
63
|
+
txid: response.txid,
|
|
64
|
+
funded: 'stored-beef',
|
|
65
|
+
explorer: `https://${wocNet}whatsonchain.com/tx/${response.txid}`,
|
|
66
|
+
};
|
|
67
|
+
}
|
|
68
|
+
/**
|
|
69
|
+
* Lookup data from an overlay lookup service.
|
|
70
|
+
*/
|
|
71
|
+
export async function lookupOverlay(service, query) {
|
|
72
|
+
const resp = await fetch(`${OVERLAY_URL}/lookup`, {
|
|
73
|
+
method: 'POST',
|
|
74
|
+
headers: { 'Content-Type': 'application/json' },
|
|
75
|
+
body: JSON.stringify({ service, query }),
|
|
76
|
+
});
|
|
77
|
+
if (!resp.ok) {
|
|
78
|
+
const errText = await resp.text();
|
|
79
|
+
throw new Error(`Lookup failed: ${resp.status} — ${errText}`);
|
|
80
|
+
}
|
|
81
|
+
return resp.json();
|
|
82
|
+
}
|
|
83
|
+
/**
|
|
84
|
+
* Parse an overlay output from BEEF data.
|
|
85
|
+
*
|
|
86
|
+
* Handles both formats:
|
|
87
|
+
* - OP_FALSE OP_RETURN <protocol> <json> (standard)
|
|
88
|
+
* - OP_RETURN <protocol> <json> (legacy)
|
|
89
|
+
*/
|
|
90
|
+
export async function parseOverlayOutput(beefData, outputIndex) {
|
|
91
|
+
try {
|
|
92
|
+
const tx = Transaction.fromBEEF(beefData);
|
|
93
|
+
const txid = tx.id('hex');
|
|
94
|
+
const output = tx.outputs[outputIndex];
|
|
95
|
+
if (!output)
|
|
96
|
+
return { data: null, txid: null };
|
|
97
|
+
const { fields } = PushDrop.decode(output.lockingScript);
|
|
98
|
+
return { data: JSON.parse(Utils.toUTF8(fields[0])), txid };
|
|
99
|
+
}
|
|
100
|
+
catch {
|
|
101
|
+
return { data: null, txid: null };
|
|
102
|
+
}
|
|
103
|
+
}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Payment building using a2a-bsv wallet.createPayment().
|
|
3
|
+
*
|
|
4
|
+
* This replaces the old buildDirectPayment() which used plain P2PKH scripts
|
|
5
|
+
* and manual UTXO management. The new implementation:
|
|
6
|
+
* - Uses proper BRC-29 locking scripts via wallet.createPayment()
|
|
7
|
+
* - Relies on wallet's createAction() for UTXO management
|
|
8
|
+
* - Uses noSend: true (recipient broadcasts via acceptPayment())
|
|
9
|
+
*/
|
|
10
|
+
import type { PaymentResult } from './types.js';
|
|
11
|
+
/**
|
|
12
|
+
* Build a BRC-29 payment using the a2a-bsv wallet.
|
|
13
|
+
*
|
|
14
|
+
* This creates a payment transaction using proper BRC-29 locking scripts.
|
|
15
|
+
* The transaction uses noSend: true, meaning:
|
|
16
|
+
* - The sender does NOT broadcast the transaction
|
|
17
|
+
* - The recipient broadcasts it when they call acceptPayment()
|
|
18
|
+
*
|
|
19
|
+
* @param recipientPubKey - Recipient's compressed public key (66 hex chars, 02/03 prefix)
|
|
20
|
+
* @param sats - Amount to send in satoshis
|
|
21
|
+
* @param desc - Optional description for the payment
|
|
22
|
+
* @returns PaymentResult with BEEF and derivation metadata for the recipient
|
|
23
|
+
*/
|
|
24
|
+
export declare function buildDirectPayment(recipientPubKey: string, sats: number, desc?: string): Promise<PaymentResult>;
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Payment building using a2a-bsv wallet.createPayment().
|
|
3
|
+
*
|
|
4
|
+
* This replaces the old buildDirectPayment() which used plain P2PKH scripts
|
|
5
|
+
* and manual UTXO management. The new implementation:
|
|
6
|
+
* - Uses proper BRC-29 locking scripts via wallet.createPayment()
|
|
7
|
+
* - Relies on wallet's createAction() for UTXO management
|
|
8
|
+
* - Uses noSend: true (recipient broadcasts via acceptPayment())
|
|
9
|
+
*/
|
|
10
|
+
import { NETWORK, WALLET_DIR } from '../config.js';
|
|
11
|
+
import { BSVAgentWallet } from '../../core/index.js';
|
|
12
|
+
async function getBSVAgentWallet() {
|
|
13
|
+
return BSVAgentWallet;
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* Build a BRC-29 payment using the a2a-bsv wallet.
|
|
17
|
+
*
|
|
18
|
+
* This creates a payment transaction using proper BRC-29 locking scripts.
|
|
19
|
+
* The transaction uses noSend: true, meaning:
|
|
20
|
+
* - The sender does NOT broadcast the transaction
|
|
21
|
+
* - The recipient broadcasts it when they call acceptPayment()
|
|
22
|
+
*
|
|
23
|
+
* @param recipientPubKey - Recipient's compressed public key (66 hex chars, 02/03 prefix)
|
|
24
|
+
* @param sats - Amount to send in satoshis
|
|
25
|
+
* @param desc - Optional description for the payment
|
|
26
|
+
* @returns PaymentResult with BEEF and derivation metadata for the recipient
|
|
27
|
+
*/
|
|
28
|
+
export async function buildDirectPayment(recipientPubKey, sats, desc) {
|
|
29
|
+
// Validate recipient pubkey format
|
|
30
|
+
if (!/^0[23][0-9a-fA-F]{64}$/.test(recipientPubKey)) {
|
|
31
|
+
throw new Error('Recipient must be a compressed public key (66 hex chars starting with 02 or 03)');
|
|
32
|
+
}
|
|
33
|
+
const BSVAgentWallet = await getBSVAgentWallet();
|
|
34
|
+
const wallet = await BSVAgentWallet.load({ network: NETWORK, storageDir: WALLET_DIR });
|
|
35
|
+
try {
|
|
36
|
+
const result = await wallet.createPayment({
|
|
37
|
+
to: recipientPubKey,
|
|
38
|
+
satoshis: sats,
|
|
39
|
+
description: desc || 'agent payment',
|
|
40
|
+
});
|
|
41
|
+
// Return format compatible with existing code
|
|
42
|
+
return {
|
|
43
|
+
beef: result.beef,
|
|
44
|
+
txid: result.txid,
|
|
45
|
+
satoshis: result.satoshis,
|
|
46
|
+
derivationPrefix: result.derivationPrefix,
|
|
47
|
+
derivationSuffix: result.derivationSuffix,
|
|
48
|
+
senderIdentityKey: result.senderIdentityKey,
|
|
49
|
+
};
|
|
50
|
+
}
|
|
51
|
+
finally {
|
|
52
|
+
await wallet.destroy();
|
|
53
|
+
}
|
|
54
|
+
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Payment CLI commands: pay, verify, accept.
|
|
3
|
+
*/
|
|
4
|
+
/**
|
|
5
|
+
* Pay command: send satoshis to another agent.
|
|
6
|
+
*/
|
|
7
|
+
export declare function cmdPay(pubkey: string | undefined, satoshis: string | undefined, description?: string): Promise<never>;
|
|
8
|
+
/**
|
|
9
|
+
* Verify command: verify an incoming payment BEEF.
|
|
10
|
+
*/
|
|
11
|
+
export declare function cmdVerify(beefBase64: string | undefined): Promise<never>;
|
|
12
|
+
/**
|
|
13
|
+
* Accept command: accept and internalize a payment.
|
|
14
|
+
*/
|
|
15
|
+
export declare function cmdAccept(beef: string | undefined, derivationPrefix: string | undefined, derivationSuffix: string | undefined, senderIdentityKey: string | undefined, description?: string): Promise<never>;
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Payment CLI commands: pay, verify, accept.
|
|
3
|
+
*/
|
|
4
|
+
import { NETWORK, WALLET_DIR } from '../config.js';
|
|
5
|
+
import { ok, fail } from '../output.js';
|
|
6
|
+
import { buildDirectPayment } from './build.js';
|
|
7
|
+
import { BSVAgentWallet } from '../../core/index.js';
|
|
8
|
+
async function getBSVAgentWallet() {
|
|
9
|
+
return BSVAgentWallet;
|
|
10
|
+
}
|
|
11
|
+
/**
|
|
12
|
+
* Pay command: send satoshis to another agent.
|
|
13
|
+
*/
|
|
14
|
+
export async function cmdPay(pubkey, satoshis, description) {
|
|
15
|
+
if (!pubkey || !satoshis) {
|
|
16
|
+
return fail('Usage: pay <pubkey> <satoshis> [description]');
|
|
17
|
+
}
|
|
18
|
+
const sats = parseInt(satoshis, 10);
|
|
19
|
+
if (isNaN(sats) || sats <= 0) {
|
|
20
|
+
return fail('satoshis must be a positive integer');
|
|
21
|
+
}
|
|
22
|
+
try {
|
|
23
|
+
const payment = await buildDirectPayment(pubkey, sats, description || 'agent payment');
|
|
24
|
+
return ok(payment);
|
|
25
|
+
}
|
|
26
|
+
catch (err) {
|
|
27
|
+
return fail(err instanceof Error ? err.message : String(err));
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* Verify command: verify an incoming payment BEEF.
|
|
32
|
+
*/
|
|
33
|
+
export async function cmdVerify(beefBase64) {
|
|
34
|
+
if (!beefBase64) {
|
|
35
|
+
return fail('Usage: verify <beef_base64>');
|
|
36
|
+
}
|
|
37
|
+
const BSVAgentWallet = await getBSVAgentWallet();
|
|
38
|
+
const wallet = await BSVAgentWallet.load({ network: NETWORK, storageDir: WALLET_DIR });
|
|
39
|
+
try {
|
|
40
|
+
const result = wallet.verifyPayment({ beef: beefBase64 });
|
|
41
|
+
await wallet.destroy();
|
|
42
|
+
return ok(result);
|
|
43
|
+
}
|
|
44
|
+
catch (err) {
|
|
45
|
+
await wallet.destroy();
|
|
46
|
+
return fail(err instanceof Error ? err.message : String(err));
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* Accept command: accept and internalize a payment.
|
|
51
|
+
*/
|
|
52
|
+
export async function cmdAccept(beef, derivationPrefix, derivationSuffix, senderIdentityKey, description) {
|
|
53
|
+
if (!beef || !derivationPrefix || !derivationSuffix || !senderIdentityKey) {
|
|
54
|
+
return fail('Usage: accept <beef> <prefix> <suffix> <senderKey> [description]');
|
|
55
|
+
}
|
|
56
|
+
const BSVAgentWallet = await getBSVAgentWallet();
|
|
57
|
+
const wallet = await BSVAgentWallet.load({ network: NETWORK, storageDir: WALLET_DIR });
|
|
58
|
+
try {
|
|
59
|
+
const receipt = await wallet.acceptPayment({
|
|
60
|
+
beef,
|
|
61
|
+
derivationPrefix,
|
|
62
|
+
derivationSuffix,
|
|
63
|
+
senderIdentityKey,
|
|
64
|
+
description: description || undefined,
|
|
65
|
+
});
|
|
66
|
+
await wallet.destroy();
|
|
67
|
+
return ok(receipt);
|
|
68
|
+
}
|
|
69
|
+
catch (err) {
|
|
70
|
+
await wallet.destroy();
|
|
71
|
+
return fail(err instanceof Error ? err.message : String(err));
|
|
72
|
+
}
|
|
73
|
+
}
|