openclaw-overlay-plugin 0.8.14 → 0.8.16

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.
Files changed (190) hide show
  1. package/dist/index.js +6705 -326
  2. package/dist/index.js.map +7 -0
  3. package/dist/src/cli.js +7498 -11
  4. package/dist/src/cli.js.map +7 -0
  5. package/index.ts +1 -1
  6. package/openclaw.plugin.json +1 -1
  7. package/package.json +8 -8
  8. package/src/scripts/messaging/handlers.ts +1 -1
  9. package/src/scripts/overlay/advertisement.ts +1 -1
  10. package/src/scripts/overlay/registration.ts +1 -1
  11. package/src/scripts/overlay/services.ts +1 -1
  12. package/src/scripts/overlay/transaction.ts +1 -1
  13. package/src/scripts/payment/build.ts +1 -1
  14. package/src/scripts/payment/commands.ts +1 -1
  15. package/src/scripts/wallet/balance.ts +1 -1
  16. package/src/scripts/wallet/setup.ts +1 -1
  17. package/src/test/identity-consistency.test.ts +1 -1
  18. package/src/test/wallet.test.ts +1 -2
  19. package/dist/index.d.ts +0 -9
  20. package/dist/src/cli-main.d.ts +0 -7
  21. package/dist/src/cli-main.js +0 -202
  22. package/dist/src/cli.d.ts +0 -8
  23. package/dist/src/compatibility.test.d.ts +0 -4
  24. package/dist/src/compatibility.test.js +0 -41
  25. package/dist/src/core/config.d.ts +0 -11
  26. package/dist/src/core/config.js +0 -15
  27. package/dist/src/core/index.d.ts +0 -25
  28. package/dist/src/core/index.js +0 -26
  29. package/dist/src/core/payment.d.ts +0 -16
  30. package/dist/src/core/payment.js +0 -94
  31. package/dist/src/core/types.d.ts +0 -94
  32. package/dist/src/core/types.js +0 -4
  33. package/dist/src/core/verify.d.ts +0 -28
  34. package/dist/src/core/verify.js +0 -104
  35. package/dist/src/core/wallet.d.ts +0 -105
  36. package/dist/src/core/wallet.js +0 -256
  37. package/dist/src/scripts/baemail/commands.d.ts +0 -35
  38. package/dist/src/scripts/baemail/commands.js +0 -282
  39. package/dist/src/scripts/baemail/handler.d.ts +0 -36
  40. package/dist/src/scripts/baemail/handler.js +0 -284
  41. package/dist/src/scripts/baemail/index.d.ts +0 -5
  42. package/dist/src/scripts/baemail/index.js +0 -5
  43. package/dist/src/scripts/config.d.ts +0 -52
  44. package/dist/src/scripts/config.js +0 -75
  45. package/dist/src/scripts/index.d.ts +0 -7
  46. package/dist/src/scripts/index.js +0 -7
  47. package/dist/src/scripts/messaging/connect.d.ts +0 -8
  48. package/dist/src/scripts/messaging/connect.js +0 -168
  49. package/dist/src/scripts/messaging/handlers.d.ts +0 -21
  50. package/dist/src/scripts/messaging/handlers.js +0 -334
  51. package/dist/src/scripts/messaging/inbox.d.ts +0 -11
  52. package/dist/src/scripts/messaging/inbox.js +0 -51
  53. package/dist/src/scripts/messaging/index.d.ts +0 -8
  54. package/dist/src/scripts/messaging/index.js +0 -8
  55. package/dist/src/scripts/messaging/poll.d.ts +0 -7
  56. package/dist/src/scripts/messaging/poll.js +0 -52
  57. package/dist/src/scripts/messaging/send.d.ts +0 -7
  58. package/dist/src/scripts/messaging/send.js +0 -43
  59. package/dist/src/scripts/output.d.ts +0 -13
  60. package/dist/src/scripts/output.js +0 -28
  61. package/dist/src/scripts/overlay/advertisement.d.ts +0 -16
  62. package/dist/src/scripts/overlay/advertisement.js +0 -122
  63. package/dist/src/scripts/overlay/discover.d.ts +0 -7
  64. package/dist/src/scripts/overlay/discover.js +0 -74
  65. package/dist/src/scripts/overlay/index.d.ts +0 -7
  66. package/dist/src/scripts/overlay/index.js +0 -7
  67. package/dist/src/scripts/overlay/registration.d.ts +0 -19
  68. package/dist/src/scripts/overlay/registration.js +0 -176
  69. package/dist/src/scripts/overlay/services.d.ts +0 -29
  70. package/dist/src/scripts/overlay/services.js +0 -167
  71. package/dist/src/scripts/overlay/transaction.d.ts +0 -42
  72. package/dist/src/scripts/overlay/transaction.js +0 -103
  73. package/dist/src/scripts/payment/build.d.ts +0 -24
  74. package/dist/src/scripts/payment/build.js +0 -54
  75. package/dist/src/scripts/payment/commands.d.ts +0 -15
  76. package/dist/src/scripts/payment/commands.js +0 -73
  77. package/dist/src/scripts/payment/index.d.ts +0 -6
  78. package/dist/src/scripts/payment/index.js +0 -6
  79. package/dist/src/scripts/payment/types.d.ts +0 -56
  80. package/dist/src/scripts/payment/types.js +0 -4
  81. package/dist/src/scripts/services/index.d.ts +0 -6
  82. package/dist/src/scripts/services/index.js +0 -6
  83. package/dist/src/scripts/services/queue.d.ts +0 -11
  84. package/dist/src/scripts/services/queue.js +0 -28
  85. package/dist/src/scripts/services/request.d.ts +0 -7
  86. package/dist/src/scripts/services/request.js +0 -82
  87. package/dist/src/scripts/services/respond.d.ts +0 -11
  88. package/dist/src/scripts/services/respond.js +0 -132
  89. package/dist/src/scripts/types.d.ts +0 -107
  90. package/dist/src/scripts/types.js +0 -4
  91. package/dist/src/scripts/utils/index.d.ts +0 -6
  92. package/dist/src/scripts/utils/index.js +0 -6
  93. package/dist/src/scripts/utils/merkle.d.ts +0 -12
  94. package/dist/src/scripts/utils/merkle.js +0 -47
  95. package/dist/src/scripts/utils/storage.d.ts +0 -66
  96. package/dist/src/scripts/utils/storage.js +0 -211
  97. package/dist/src/scripts/utils/woc.d.ts +0 -26
  98. package/dist/src/scripts/utils/woc.js +0 -91
  99. package/dist/src/scripts/wallet/balance.d.ts +0 -22
  100. package/dist/src/scripts/wallet/balance.js +0 -240
  101. package/dist/src/scripts/wallet/identity.d.ts +0 -71
  102. package/dist/src/scripts/wallet/identity.js +0 -152
  103. package/dist/src/scripts/wallet/index.d.ts +0 -6
  104. package/dist/src/scripts/wallet/index.js +0 -6
  105. package/dist/src/scripts/wallet/setup.d.ts +0 -19
  106. package/dist/src/scripts/wallet/setup.js +0 -119
  107. package/dist/src/scripts/x-verification/commands.d.ts +0 -27
  108. package/dist/src/scripts/x-verification/commands.js +0 -222
  109. package/dist/src/scripts/x-verification/index.d.ts +0 -4
  110. package/dist/src/scripts/x-verification/index.js +0 -4
  111. package/dist/src/services/built-in/api-proxy/index.d.ts +0 -6
  112. package/dist/src/services/built-in/api-proxy/index.js +0 -23
  113. package/dist/src/services/built-in/code-develop/index.d.ts +0 -6
  114. package/dist/src/services/built-in/code-develop/index.js +0 -23
  115. package/dist/src/services/built-in/code-review/index.d.ts +0 -10
  116. package/dist/src/services/built-in/code-review/index.js +0 -51
  117. package/dist/src/services/built-in/image-analysis/index.d.ts +0 -6
  118. package/dist/src/services/built-in/image-analysis/index.js +0 -33
  119. package/dist/src/services/built-in/memory-store/index.d.ts +0 -6
  120. package/dist/src/services/built-in/memory-store/index.js +0 -22
  121. package/dist/src/services/built-in/roulette/index.d.ts +0 -6
  122. package/dist/src/services/built-in/roulette/index.js +0 -27
  123. package/dist/src/services/built-in/summarize/index.d.ts +0 -6
  124. package/dist/src/services/built-in/summarize/index.js +0 -21
  125. package/dist/src/services/built-in/tell-joke/handler.d.ts +0 -7
  126. package/dist/src/services/built-in/tell-joke/handler.js +0 -122
  127. package/dist/src/services/built-in/tell-joke/index.d.ts +0 -9
  128. package/dist/src/services/built-in/tell-joke/index.js +0 -31
  129. package/dist/src/services/built-in/translate/index.d.ts +0 -6
  130. package/dist/src/services/built-in/translate/index.js +0 -21
  131. package/dist/src/services/built-in/web-research/index.d.ts +0 -9
  132. package/dist/src/services/built-in/web-research/index.js +0 -51
  133. package/dist/src/services/index.d.ts +0 -13
  134. package/dist/src/services/index.js +0 -14
  135. package/dist/src/services/loader.d.ts +0 -77
  136. package/dist/src/services/loader.js +0 -292
  137. package/dist/src/services/manager.d.ts +0 -86
  138. package/dist/src/services/manager.js +0 -255
  139. package/dist/src/services/registry.d.ts +0 -98
  140. package/dist/src/services/registry.js +0 -204
  141. package/dist/src/services/types.d.ts +0 -230
  142. package/dist/src/services/types.js +0 -30
  143. package/dist/src/test/cli.test.d.ts +0 -7
  144. package/dist/src/test/cli.test.js +0 -330
  145. package/dist/src/test/comprehensive-overlay.test.d.ts +0 -13
  146. package/dist/src/test/comprehensive-overlay.test.js +0 -593
  147. package/dist/src/test/identity-consistency.test.d.ts +0 -6
  148. package/dist/src/test/identity-consistency.test.js +0 -60
  149. package/dist/src/test/key-derivation.test.d.ts +0 -12
  150. package/dist/src/test/key-derivation.test.js +0 -86
  151. package/dist/src/test/network-address.test.d.ts +0 -9
  152. package/dist/src/test/network-address.test.js +0 -37
  153. package/dist/src/test/overlay-submit.test.d.ts +0 -10
  154. package/dist/src/test/overlay-submit.test.js +0 -460
  155. package/dist/src/test/request-response-flow.test.d.ts +0 -5
  156. package/dist/src/test/request-response-flow.test.js +0 -210
  157. package/dist/src/test/service-system.test.d.ts +0 -5
  158. package/dist/src/test/service-system.test.js +0 -190
  159. package/dist/src/test/taskflow.test.d.ts +0 -7
  160. package/dist/src/test/taskflow.test.js +0 -82
  161. package/dist/src/test/utils/server-logic.d.ts +0 -98
  162. package/dist/src/test/utils/server-logic.js +0 -286
  163. package/dist/src/test/wallet.test.d.ts +0 -7
  164. package/dist/src/test/wallet.test.js +0 -146
  165. package/src/core/README.md +0 -246
  166. package/src/core/config.d.ts +0 -12
  167. package/src/core/config.d.ts.map +0 -1
  168. package/src/core/config.js +0 -14
  169. package/src/core/config.js.map +0 -1
  170. package/src/core/config.ts +0 -22
  171. package/src/core/index.ts +0 -42
  172. package/src/core/payment.d.ts +0 -17
  173. package/src/core/payment.d.ts.map +0 -1
  174. package/src/core/payment.js +0 -95
  175. package/src/core/payment.js.map +0 -1
  176. package/src/core/payment.ts +0 -111
  177. package/src/core/types.d.ts +0 -95
  178. package/src/core/types.d.ts.map +0 -1
  179. package/src/core/types.js +0 -5
  180. package/src/core/types.js.map +0 -1
  181. package/src/core/types.ts +0 -102
  182. package/src/core/verify.d.ts +0 -29
  183. package/src/core/verify.d.ts.map +0 -1
  184. package/src/core/verify.js +0 -105
  185. package/src/core/verify.js.map +0 -1
  186. package/src/core/verify.ts +0 -119
  187. package/src/core/wallet.d.ts +0 -100
  188. package/src/core/wallet.d.ts.map +0 -1
  189. package/src/core/wallet.js.map +0 -1
  190. package/src/core/wallet.ts +0 -323
@@ -1,593 +0,0 @@
1
- /**
2
- * Comprehensive Overlay Submission Tests
3
- *
4
- * Tests all aspects of overlay submission:
5
- * - BEEF format and construction
6
- * - Payload validation (identity, service, revocation)
7
- * - PushDrop script format
8
- * - Transaction chain validation
9
- * - Server response handling
10
- *
11
- * Run with: npx tsx src/test/comprehensive-overlay.test.ts
12
- */
13
- import { Beef, Transaction, PrivateKey, P2PKH, LockingScript, OP } from '@bsv/sdk';
14
- import { PROTOCOL_ID, extractPushDropFields, parseIdentityOutput, parseRevocationOutput, parseServiceOutput, identifyIdentityOutputs, identifyServiceOutputs, validateBeef, validateBeefAncestry, } from './utils/server-logic.js';
15
- const results = [];
16
- function test(name, fn) {
17
- try {
18
- const result = fn();
19
- if (result instanceof Promise) {
20
- result
21
- .then(() => {
22
- results.push({ name, passed: true });
23
- console.log(`✅ ${name}`);
24
- })
25
- .catch((e) => {
26
- results.push({ name, passed: false, error: e.message });
27
- console.log(`❌ ${name}: ${e.message}`);
28
- });
29
- }
30
- else {
31
- results.push({ name, passed: true });
32
- console.log(`✅ ${name}`);
33
- }
34
- }
35
- catch (e) {
36
- const errorMessage = e instanceof Error ? e.message : String(e);
37
- results.push({ name, passed: false, error: errorMessage });
38
- console.log(`❌ ${name}: ${errorMessage}`);
39
- }
40
- }
41
- function assert(condition, message) {
42
- if (!condition)
43
- throw new Error(message);
44
- }
45
- function assertEqual(actual, expected, message) {
46
- if (actual !== expected) {
47
- throw new Error(`${message}: expected ${expected}, got ${actual}`);
48
- }
49
- }
50
- // ============================================================================
51
- // Helper Functions - PushDrop Script Building
52
- // ============================================================================
53
- /**
54
- * Create a minimally encoded push chunk for script building.
55
- */
56
- function createPushChunk(data) {
57
- if (data.length === 0) {
58
- return { op: 0 };
59
- }
60
- if (data.length === 1 && data[0] === 0) {
61
- return { op: 0 };
62
- }
63
- if (data.length === 1 && data[0] > 0 && data[0] <= 16) {
64
- return { op: 0x50 + data[0] };
65
- }
66
- if (data.length <= 75) {
67
- return { op: data.length, data };
68
- }
69
- if (data.length <= 255) {
70
- return { op: 0x4c, data };
71
- }
72
- if (data.length <= 65535) {
73
- return { op: 0x4d, data };
74
- }
75
- return { op: 0x4e, data };
76
- }
77
- /**
78
- * Build a PushDrop-style locking script with JSON payload.
79
- * Format: <pubkey> OP_CHECKSIG <jsonBytes> OP_DROP
80
- *
81
- * This mimics what PushDrop.lock() produces for testing purposes.
82
- */
83
- function buildPushDropScript(privKey, payload) {
84
- const pubKey = privKey.toPublicKey();
85
- const pubKeyBytes = pubKey.toDER();
86
- const jsonBytes = Array.from(new TextEncoder().encode(JSON.stringify(payload)));
87
- const chunks = [];
88
- // P2PK lock: <pubkey> OP_CHECKSIG
89
- chunks.push({ op: pubKeyBytes.length, data: pubKeyBytes });
90
- chunks.push({ op: OP.OP_CHECKSIG });
91
- // Data field: <jsonBytes>
92
- chunks.push(createPushChunk(jsonBytes));
93
- // OP_DROP to clean stack
94
- chunks.push({ op: OP.OP_DROP });
95
- return new LockingScript(chunks);
96
- }
97
- async function createSignedTransaction(privKey, sourceTx, sourceVout, pushDropPayload, changeSats = 9900) {
98
- const tx = new Transaction();
99
- const pubKeyHash = privKey.toPublicKey().toHash();
100
- tx.addInput({
101
- sourceTransaction: sourceTx,
102
- sourceOutputIndex: sourceVout,
103
- unlockingScriptTemplate: new P2PKH().unlock(privKey),
104
- });
105
- tx.addOutput({
106
- lockingScript: buildPushDropScript(privKey, pushDropPayload),
107
- satoshis: 1, // PushDrop outputs need at least 1 sat
108
- });
109
- if (changeSats > 0) {
110
- tx.addOutput({
111
- lockingScript: new P2PKH().lock(pubKeyHash),
112
- satoshis: changeSats,
113
- });
114
- }
115
- await tx.sign();
116
- return tx;
117
- }
118
- function createSourceTransaction(privKey, satoshis = 10000) {
119
- const pubKeyHash = privKey.toPublicKey().toHash();
120
- const tx = new Transaction();
121
- tx.addOutput({
122
- lockingScript: new P2PKH().lock(pubKeyHash),
123
- satoshis,
124
- });
125
- return tx;
126
- }
127
- // ============================================================================
128
- // BEEF Format Tests
129
- // ============================================================================
130
- console.log('\n=== BEEF Format Tests ===\n');
131
- test('BEEF: valid v2 magic bytes', async () => {
132
- const privKey = PrivateKey.fromRandom();
133
- const sourceTx = createSourceTransaction(privKey);
134
- const tx = await createSignedTransaction(privKey, sourceTx, 0, { test: true });
135
- const beef = new Beef();
136
- beef.mergeTransaction(tx);
137
- const binary = beef.toBinary();
138
- const result = validateBeef(binary);
139
- assert(result.valid, result.error || 'BEEF should be valid');
140
- assertEqual(result.version, 2, 'Should be BEEF v2');
141
- });
142
- test('BEEF: contains multiple transactions', async () => {
143
- const privKey = PrivateKey.fromRandom();
144
- const sourceTx = createSourceTransaction(privKey);
145
- const tx = await createSignedTransaction(privKey, sourceTx, 0, { test: true });
146
- const beef = new Beef();
147
- beef.mergeTransaction(tx);
148
- const binary = beef.toBinary();
149
- const result = validateBeef(binary);
150
- assert(result.txCount >= 2, `Should have at least 2 txs, got ${result.txCount}`);
151
- });
152
- test('BEEF: invalid magic bytes rejected', () => {
153
- const garbage = [0xDE, 0xAD, 0xBE, 0xEF, 0, 0, 0, 0];
154
- const result = validateBeef(garbage);
155
- assert(!result.valid, 'Should reject invalid magic');
156
- });
157
- test('BEEF: empty BEEF rejected', () => {
158
- const emptyBeef = new Beef();
159
- const binary = emptyBeef.toBinary();
160
- const result = validateBeef(binary);
161
- assert(!result.valid, 'Should reject empty BEEF');
162
- });
163
- // ============================================================================
164
- // Identity Payload Tests
165
- // ============================================================================
166
- console.log('\n=== Identity Payload Tests ===\n');
167
- test('Identity: valid payload accepted', () => {
168
- const privKey = PrivateKey.fromRandom();
169
- const identityKey = privKey.toPublicKey().toString();
170
- const payload = {
171
- protocol: PROTOCOL_ID,
172
- type: 'identity',
173
- identityKey,
174
- name: 'test-agent',
175
- description: 'A test agent',
176
- channels: { overlay: 'https://example.com' },
177
- capabilities: ['testing'],
178
- timestamp: new Date().toISOString(),
179
- };
180
- const script = buildPushDropScript(privKey, payload);
181
- const parsed = parseIdentityOutput(script);
182
- assert(parsed !== null, 'Should parse valid identity');
183
- assertEqual(parsed.identityKey, identityKey, 'Identity key should match');
184
- assertEqual(parsed.name, 'test-agent', 'Name should match');
185
- });
186
- test('Identity: wrong protocol rejected', () => {
187
- const privKey = PrivateKey.fromRandom();
188
- const payload = {
189
- protocol: 'wrong-protocol',
190
- type: 'identity',
191
- identityKey: privKey.toPublicKey().toString(),
192
- name: 'test',
193
- description: '',
194
- channels: {},
195
- capabilities: [],
196
- timestamp: new Date().toISOString(),
197
- };
198
- const script = buildPushDropScript(privKey, payload);
199
- assert(parseIdentityOutput(script) === null, 'Should reject wrong protocol');
200
- });
201
- test('Identity: wrong type rejected', () => {
202
- const privKey = PrivateKey.fromRandom();
203
- const payload = {
204
- protocol: PROTOCOL_ID,
205
- type: 'service', // Wrong type
206
- identityKey: privKey.toPublicKey().toString(),
207
- name: 'test',
208
- description: '',
209
- channels: {},
210
- capabilities: [],
211
- timestamp: new Date().toISOString(),
212
- };
213
- const script = buildPushDropScript(privKey, payload);
214
- assert(parseIdentityOutput(script) === null, 'Should reject wrong type');
215
- });
216
- test('Identity: invalid identity key rejected', () => {
217
- const privKey = PrivateKey.fromRandom();
218
- const payload = {
219
- protocol: PROTOCOL_ID,
220
- type: 'identity',
221
- identityKey: 'not-a-valid-key',
222
- name: 'test',
223
- description: '',
224
- channels: {},
225
- capabilities: [],
226
- timestamp: new Date().toISOString(),
227
- };
228
- const script = buildPushDropScript(privKey, payload);
229
- assert(parseIdentityOutput(script) === null, 'Should reject invalid identity key');
230
- });
231
- test('Identity: short identity key rejected', () => {
232
- const privKey = PrivateKey.fromRandom();
233
- const payload = {
234
- protocol: PROTOCOL_ID,
235
- type: 'identity',
236
- identityKey: '02abcd', // Too short
237
- name: 'test',
238
- description: '',
239
- channels: {},
240
- capabilities: [],
241
- timestamp: new Date().toISOString(),
242
- };
243
- const script = buildPushDropScript(privKey, payload);
244
- assert(parseIdentityOutput(script) === null, 'Should reject short identity key');
245
- });
246
- test('Identity: empty name rejected', () => {
247
- const privKey = PrivateKey.fromRandom();
248
- const payload = {
249
- protocol: PROTOCOL_ID,
250
- type: 'identity',
251
- identityKey: privKey.toPublicKey().toString(),
252
- name: '',
253
- description: '',
254
- channels: {},
255
- capabilities: [],
256
- timestamp: new Date().toISOString(),
257
- };
258
- const script = buildPushDropScript(privKey, payload);
259
- assert(parseIdentityOutput(script) === null, 'Should reject empty name');
260
- });
261
- test('Identity: non-array capabilities rejected', () => {
262
- const privKey = PrivateKey.fromRandom();
263
- const payload = {
264
- protocol: PROTOCOL_ID,
265
- type: 'identity',
266
- identityKey: privKey.toPublicKey().toString(),
267
- name: 'test',
268
- description: '',
269
- channels: {},
270
- capabilities: 'not-an-array',
271
- timestamp: new Date().toISOString(),
272
- };
273
- const script = buildPushDropScript(privKey, payload);
274
- assert(parseIdentityOutput(script) === null, 'Should reject non-array capabilities');
275
- });
276
- // ============================================================================
277
- // Service Payload Tests
278
- // ============================================================================
279
- console.log('\n=== Service Payload Tests ===\n');
280
- test('Service: valid payload accepted', () => {
281
- const privKey = PrivateKey.fromRandom();
282
- const identityKey = privKey.toPublicKey().toString();
283
- const payload = {
284
- protocol: PROTOCOL_ID,
285
- type: 'service',
286
- identityKey,
287
- serviceId: 'test-service',
288
- name: 'Test Service',
289
- description: 'A test service',
290
- pricing: { model: 'per-task', amountSats: 100 },
291
- timestamp: new Date().toISOString(),
292
- };
293
- const script = buildPushDropScript(privKey, payload);
294
- const parsed = parseServiceOutput(script);
295
- assert(parsed !== null, 'Should parse valid service');
296
- assertEqual(parsed.serviceId, 'test-service', 'Service ID should match');
297
- assertEqual(parsed.pricing.amountSats, 100, 'Price should match');
298
- });
299
- test('Service: empty serviceId rejected', () => {
300
- const privKey = PrivateKey.fromRandom();
301
- const payload = {
302
- protocol: PROTOCOL_ID,
303
- type: 'service',
304
- identityKey: privKey.toPublicKey().toString(),
305
- serviceId: '',
306
- name: 'Test',
307
- description: '',
308
- pricing: { model: 'per-task', amountSats: 100 },
309
- timestamp: new Date().toISOString(),
310
- };
311
- const script = buildPushDropScript(privKey, payload);
312
- assert(parseServiceOutput(script) === null, 'Should reject empty serviceId');
313
- });
314
- test('Service: missing pricing rejected', () => {
315
- const privKey = PrivateKey.fromRandom();
316
- const payload = {
317
- protocol: PROTOCOL_ID,
318
- type: 'service',
319
- identityKey: privKey.toPublicKey().toString(),
320
- serviceId: 'test',
321
- name: 'Test',
322
- description: '',
323
- timestamp: new Date().toISOString(),
324
- };
325
- const script = buildPushDropScript(privKey, payload);
326
- assert(parseServiceOutput(script) === null, 'Should reject missing pricing');
327
- });
328
- test('Service: invalid pricing rejected', () => {
329
- const privKey = PrivateKey.fromRandom();
330
- const payload = {
331
- protocol: PROTOCOL_ID,
332
- type: 'service',
333
- identityKey: privKey.toPublicKey().toString(),
334
- serviceId: 'test',
335
- name: 'Test',
336
- description: '',
337
- pricing: { model: 'per-task', amountSats: 'not-a-number' },
338
- timestamp: new Date().toISOString(),
339
- };
340
- const script = buildPushDropScript(privKey, payload);
341
- assert(parseServiceOutput(script) === null, 'Should reject invalid pricing');
342
- });
343
- // ============================================================================
344
- // Revocation Payload Tests
345
- // ============================================================================
346
- console.log('\n=== Revocation Payload Tests ===\n');
347
- test('Revocation: valid payload accepted', () => {
348
- const privKey = PrivateKey.fromRandom();
349
- const identityKey = privKey.toPublicKey().toString();
350
- const payload = {
351
- protocol: PROTOCOL_ID,
352
- type: 'identity-revocation',
353
- identityKey,
354
- reason: 'Test revocation',
355
- timestamp: new Date().toISOString(),
356
- };
357
- const script = buildPushDropScript(privKey, payload);
358
- const parsed = parseRevocationOutput(script);
359
- assert(parsed !== null, 'Should parse valid revocation');
360
- assertEqual(parsed.identityKey, identityKey, 'Identity key should match');
361
- });
362
- test('Revocation: invalid identity key rejected', () => {
363
- const privKey = PrivateKey.fromRandom();
364
- const payload = {
365
- protocol: PROTOCOL_ID,
366
- type: 'identity-revocation',
367
- identityKey: 'invalid',
368
- timestamp: new Date().toISOString(),
369
- };
370
- const script = buildPushDropScript(privKey, payload);
371
- assert(parseRevocationOutput(script) === null, 'Should reject invalid identity key');
372
- });
373
- // ============================================================================
374
- // Topic Manager Simulation Tests
375
- // ============================================================================
376
- console.log('\n=== Topic Manager Simulation Tests ===\n');
377
- test('TopicManager: identity output admitted', async () => {
378
- const privKey = PrivateKey.fromRandom();
379
- const identityKey = privKey.toPublicKey().toString();
380
- const sourceTx = createSourceTransaction(privKey);
381
- const payload = {
382
- protocol: PROTOCOL_ID,
383
- type: 'identity',
384
- identityKey,
385
- name: 'test-agent',
386
- description: 'Test',
387
- channels: {},
388
- capabilities: [],
389
- timestamp: new Date().toISOString(),
390
- };
391
- const tx = await createSignedTransaction(privKey, sourceTx, 0, payload);
392
- const beef = new Beef();
393
- beef.mergeTransaction(tx);
394
- const binary = beef.toBinary();
395
- const result = identifyIdentityOutputs(binary);
396
- assertEqual(result.outputsToAdmit.length, 1, 'Should admit 1 output');
397
- assertEqual(result.outputsToAdmit[0], 0, 'Should admit output 0');
398
- });
399
- test('TopicManager: revocation output admitted', async () => {
400
- const privKey = PrivateKey.fromRandom();
401
- const identityKey = privKey.toPublicKey().toString();
402
- const sourceTx = createSourceTransaction(privKey);
403
- const payload = {
404
- protocol: PROTOCOL_ID,
405
- type: 'identity-revocation',
406
- identityKey,
407
- timestamp: new Date().toISOString(),
408
- };
409
- const tx = await createSignedTransaction(privKey, sourceTx, 0, payload);
410
- const beef = new Beef();
411
- beef.mergeTransaction(tx);
412
- const binary = beef.toBinary();
413
- const result = identifyIdentityOutputs(binary);
414
- assertEqual(result.outputsToAdmit.length, 1, 'Should admit revocation');
415
- });
416
- test('TopicManager: service output admitted', async () => {
417
- const privKey = PrivateKey.fromRandom();
418
- const identityKey = privKey.toPublicKey().toString();
419
- const sourceTx = createSourceTransaction(privKey);
420
- const payload = {
421
- protocol: PROTOCOL_ID,
422
- type: 'service',
423
- identityKey,
424
- serviceId: 'test-svc',
425
- name: 'Test Service',
426
- description: 'Test',
427
- pricing: { model: 'per-task', amountSats: 50 },
428
- timestamp: new Date().toISOString(),
429
- };
430
- const tx = await createSignedTransaction(privKey, sourceTx, 0, payload);
431
- const beef = new Beef();
432
- beef.mergeTransaction(tx);
433
- const binary = beef.toBinary();
434
- const result = identifyServiceOutputs(binary);
435
- assertEqual(result.outputsToAdmit.length, 1, 'Should admit service');
436
- });
437
- test('TopicManager: invalid payload not admitted', async () => {
438
- const privKey = PrivateKey.fromRandom();
439
- const sourceTx = createSourceTransaction(privKey);
440
- // Invalid payload (wrong protocol)
441
- const payload = {
442
- protocol: 'wrong',
443
- type: 'identity',
444
- identityKey: privKey.toPublicKey().toString(),
445
- name: 'test',
446
- description: '',
447
- channels: {},
448
- capabilities: [],
449
- timestamp: new Date().toISOString(),
450
- };
451
- const tx = await createSignedTransaction(privKey, sourceTx, 0, payload);
452
- const beef = new Beef();
453
- beef.mergeTransaction(tx);
454
- const binary = beef.toBinary();
455
- const result = identifyIdentityOutputs(binary);
456
- assertEqual(result.outputsToAdmit.length, 0, 'Should not admit invalid payload');
457
- });
458
- // ============================================================================
459
- // Transaction Chain Tests
460
- // ============================================================================
461
- console.log('\n=== Transaction Chain Tests ===\n');
462
- test('Chain: two unconfirmed transactions', async () => {
463
- const privKey = PrivateKey.fromRandom();
464
- const identityKey = privKey.toPublicKey().toString();
465
- const pubKeyHash = privKey.toPublicKey().toHash();
466
- // Grandparent (simulating mined)
467
- const grandparentTx = createSourceTransaction(privKey, 100000);
468
- // Parent (first overlay tx)
469
- const parentPayload = {
470
- protocol: PROTOCOL_ID,
471
- type: 'identity',
472
- identityKey,
473
- name: 'parent-tx',
474
- description: 'First',
475
- channels: {},
476
- capabilities: [],
477
- timestamp: new Date().toISOString(),
478
- };
479
- const parentTx = await createSignedTransaction(privKey, grandparentTx, 0, parentPayload, 99900);
480
- // Child (second overlay tx, spending parent's change)
481
- const childPayload = {
482
- protocol: PROTOCOL_ID,
483
- type: 'service',
484
- identityKey,
485
- serviceId: 'child-svc',
486
- name: 'Child Service',
487
- description: 'Second',
488
- pricing: { model: 'per-task', amountSats: 25 },
489
- timestamp: new Date().toISOString(),
490
- };
491
- const childTx = new Transaction();
492
- childTx.addInput({
493
- sourceTransaction: parentTx,
494
- sourceOutputIndex: 1, // Change output
495
- unlockingScriptTemplate: new P2PKH().unlock(privKey),
496
- });
497
- childTx.addOutput({
498
- lockingScript: buildPushDropScript(privKey, childPayload),
499
- satoshis: 1,
500
- });
501
- childTx.addOutput({
502
- lockingScript: new P2PKH().lock(pubKeyHash),
503
- satoshis: 99800,
504
- });
505
- await childTx.sign();
506
- // Build BEEF
507
- const beef = new Beef();
508
- beef.mergeTransaction(childTx);
509
- const binary = beef.toBinary();
510
- const validation = validateBeef(binary);
511
- assert(validation.valid, validation.error || 'BEEF should be valid');
512
- assert(validation.txCount >= 3, `Should have at least 3 txs, got ${validation.txCount}`);
513
- // Verify service output is admitted
514
- const result = identifyServiceOutputs(binary);
515
- assertEqual(result.outputsToAdmit.length, 1, 'Should admit service output');
516
- });
517
- test('Chain: BEEF ancestry validation', async () => {
518
- const privKey = PrivateKey.fromRandom();
519
- const sourceTx = createSourceTransaction(privKey);
520
- const tx = await createSignedTransaction(privKey, sourceTx, 0, { test: true });
521
- const beef = new Beef();
522
- beef.mergeTransaction(tx);
523
- const binary = beef.toBinary();
524
- const result = validateBeefAncestry(binary);
525
- assert(result.valid, result.error || 'Ancestry should be valid');
526
- assert(result.chain.length >= 2, 'Chain should have at least 2 txids');
527
- });
528
- // ============================================================================
529
- // PushDrop Script Format Tests
530
- // ============================================================================
531
- console.log('\n=== PushDrop Script Format Tests ===\n');
532
- test('Script: PushDrop format with P2PK lock', () => {
533
- const privKey = PrivateKey.fromRandom();
534
- const payload = { test: 'data' };
535
- const script = buildPushDropScript(privKey, payload);
536
- const chunks = script.chunks;
537
- // First chunk should be pubkey push (33 bytes)
538
- assertEqual(chunks[0].op, 33, 'First op should push 33 bytes (pubkey)');
539
- assert(chunks[0].data !== undefined, 'Should have pubkey data');
540
- assertEqual(chunks[0].data.length, 33, 'Pubkey should be 33 bytes');
541
- // Second chunk should be OP_CHECKSIG
542
- assertEqual(chunks[1].op, OP.OP_CHECKSIG, 'Second op should be OP_CHECKSIG');
543
- // Should have data field and OP_DROP
544
- assert(chunks.length >= 4, 'Should have at least 4 chunks');
545
- });
546
- test('Script: JSON payload extraction', () => {
547
- const privKey = PrivateKey.fromRandom();
548
- const payload = { foo: 'bar', num: 42 };
549
- const script = buildPushDropScript(privKey, payload);
550
- const fields = extractPushDropFields(script);
551
- assert(fields !== null, 'Should extract fields');
552
- assert(fields.length >= 1, 'Should have at least 1 field');
553
- const jsonStr = new TextDecoder().decode(new Uint8Array(fields[0]));
554
- const parsed = JSON.parse(jsonStr);
555
- assertEqual(parsed.foo, 'bar', 'Foo should match');
556
- assertEqual(parsed.num, 42, 'Num should match');
557
- });
558
- test('Script: large payload handling', () => {
559
- const privKey = PrivateKey.fromRandom();
560
- const largePayload = {
561
- protocol: PROTOCOL_ID,
562
- type: 'identity',
563
- identityKey: privKey.toPublicKey().toString(),
564
- name: 'test',
565
- description: 'A'.repeat(500), // Large description
566
- channels: {},
567
- capabilities: Array(50).fill('cap'), // Many capabilities
568
- timestamp: new Date().toISOString(),
569
- };
570
- const script = buildPushDropScript(privKey, largePayload);
571
- const fields = extractPushDropFields(script);
572
- assert(fields !== null, 'Should handle large payload');
573
- const parsed = JSON.parse(new TextDecoder().decode(new Uint8Array(fields[0])));
574
- assertEqual(parsed.description.length, 500, 'Description should be preserved');
575
- });
576
- // ============================================================================
577
- // Summary
578
- // ============================================================================
579
- // Give async tests time to complete
580
- setTimeout(() => {
581
- console.log('\n========================================');
582
- const passed = results.filter(r => r.passed).length;
583
- const failed = results.filter(r => !r.passed).length;
584
- console.log(`Tests completed: ${passed} passed, ${failed} failed`);
585
- console.log('========================================\n');
586
- if (failed > 0) {
587
- console.log('Failed tests:');
588
- results.filter(r => !r.passed).forEach(r => {
589
- console.log(` - ${r.name}: ${r.error}`);
590
- });
591
- process.exit(1);
592
- }
593
- }, 2000);
@@ -1,6 +0,0 @@
1
- /**
2
- * Identity Consistency tests
3
- *
4
- * Verifies that all plugins produce the exact same identityKey from the same root secret.
5
- */
6
- export {};
@@ -1,60 +0,0 @@
1
- /**
2
- * Identity Consistency tests
3
- *
4
- * Verifies that all plugins produce the exact same identityKey from the same root secret.
5
- */
6
- import { BSVAgentWallet } from '../core/wallet.js';
7
- import * as fs from 'node:fs';
8
- import * as path from 'node:path';
9
- import * as os from 'node:os';
10
- // Simple test runner
11
- let passed = 0;
12
- let failed = 0;
13
- async function test(name, fn) {
14
- try {
15
- await fn();
16
- console.log(` ✓ ${name}`);
17
- passed++;
18
- }
19
- catch (err) {
20
- console.log(` ✗ ${name}`);
21
- console.log(err);
22
- failed++;
23
- }
24
- }
25
- function assert(condition, message) {
26
- if (!condition)
27
- throw new Error(`Assertion failed: ${message}`);
28
- }
29
- async function run() {
30
- console.log('Identity Consistency tests\n');
31
- const SHARED_ROOT_KEY = '0000000000000000000000000000000000000000000000000000000000000001';
32
- const EXPECTED_IDENTITY = '0279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798';
33
- await test('Overlay plugin derives correct compressed pubkey', async () => {
34
- const tmpDir = fs.mkdtempSync(path.join(os.tmpdir(), 'identity-test-'));
35
- try {
36
- const wallet = await BSVAgentWallet.load({
37
- network: 'mainnet',
38
- storageDir: tmpDir,
39
- rootKeyHex: SHARED_ROOT_KEY,
40
- enableMonitor: false
41
- });
42
- const identity = await wallet.getIdentityKey();
43
- assert(identity === EXPECTED_IDENTITY, `Should match expected identity. Got: ${identity}`);
44
- assert(identity.length === 66, `Should be 66 chars (compressed hex). Got: ${identity.length}`);
45
- await wallet.destroy();
46
- }
47
- finally {
48
- fs.rmSync(tmpDir, { recursive: true, force: true });
49
- }
50
- });
51
- // Since both use the same core logic (copied or shared), we verify the logic here
52
- // against the known secp256k1 base point G (compressed).
53
- console.log(`\n${passed} passed, ${failed} failed`);
54
- if (failed > 0)
55
- process.exit(1);
56
- }
57
- run().catch(err => {
58
- console.error(err);
59
- process.exit(1);
60
- });
@@ -1,12 +0,0 @@
1
- /**
2
- * Unit tests for key derivation consistency.
3
- *
4
- * CRITICAL: These tests ensure that transaction signing uses the correct
5
- * child private key that matches the derived address.
6
- *
7
- * Bug history: Initially, code was deriving a child address using BRC-29
8
- * but signing with the root private key, causing OP_EQUALVERIFY failures.
9
- *
10
- * Run: node dist/test/key-derivation.test.js
11
- */
12
- export {};