openclaw-overlay-plugin 0.7.46 → 0.7.48
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +4 -0
- package/dist/src/core/wallet.js +16 -7
- package/dist/src/test/identity-consistency.test.d.ts +6 -0
- package/dist/src/test/identity-consistency.test.js +60 -0
- package/index.ts +5 -0
- package/package.json +3 -3
- package/src/core/wallet.ts +17 -8
- package/src/test/identity-consistency.test.ts +68 -0
package/dist/index.js
CHANGED
|
@@ -418,7 +418,11 @@ function stopBackgroundService() {
|
|
|
418
418
|
export async function activate(api) {
|
|
419
419
|
return register(api);
|
|
420
420
|
}
|
|
421
|
+
let isInitialized = false;
|
|
421
422
|
export default function register(api) {
|
|
423
|
+
if (isInitialized)
|
|
424
|
+
return;
|
|
425
|
+
isInitialized = true;
|
|
422
426
|
// Capture config at registration time
|
|
423
427
|
// Check all possible IDs for backward compatibility and various installation methods
|
|
424
428
|
const entries = api.getConfig?.()?.plugins?.entries || {};
|
package/dist/src/core/wallet.js
CHANGED
|
@@ -186,18 +186,27 @@ export class BSVAgentWallet {
|
|
|
186
186
|
const serviceOptions = Services.createDefaultOptions(chain);
|
|
187
187
|
const chaintracksUrl = process.env.BSV_CHAINTRACKS_URL || 'https://chaintracks-us-1.bsvb.tech';
|
|
188
188
|
const arcUrl = process.env.BSV_ARC_URL;
|
|
189
|
-
|
|
190
|
-
if (
|
|
191
|
-
serviceOptions.
|
|
189
|
+
const isTestMode = config.enableMonitor === false;
|
|
190
|
+
if (!isTestMode) {
|
|
191
|
+
serviceOptions.chaintracks = new ChaintracksServiceClient(chain, chaintracksUrl);
|
|
192
|
+
if (arcUrl) {
|
|
193
|
+
serviceOptions.arcUrl = arcUrl;
|
|
194
|
+
}
|
|
192
195
|
}
|
|
193
196
|
serviceOptions.taalApiKey = taalApiKey;
|
|
194
197
|
const services = new Services(serviceOptions);
|
|
195
198
|
// 4. Background monitor
|
|
196
199
|
const monopts = Monitor.createDefaultWalletMonitorOptions(chain, storage, services);
|
|
197
200
|
const monitor = new Monitor(monopts);
|
|
198
|
-
|
|
201
|
+
if (!isTestMode) {
|
|
202
|
+
monitor.addDefaultTasks();
|
|
203
|
+
}
|
|
204
|
+
else {
|
|
205
|
+
// In test mode, we clear all tasks to ensure no background activity
|
|
206
|
+
monitor.tasks = [];
|
|
207
|
+
}
|
|
199
208
|
// 5. The BRC-100 Wallet
|
|
200
|
-
const wallet = new Wallet({ chain, keyDeriver, storage, services, monitor });
|
|
209
|
+
const wallet = isTestMode ? undefined : new Wallet({ chain, keyDeriver, storage, services, monitor });
|
|
201
210
|
// 6. SQLite storage via knex
|
|
202
211
|
const filePath = path.join(config.storageDir, `${DEFAULT_DB_NAME}.sqlite`);
|
|
203
212
|
const knex = knexLib({
|
|
@@ -225,8 +234,8 @@ export class BSVAgentWallet {
|
|
|
225
234
|
keyDeriver,
|
|
226
235
|
chain,
|
|
227
236
|
storage,
|
|
228
|
-
services,
|
|
229
|
-
monitor,
|
|
237
|
+
services: isTestMode ? undefined : services,
|
|
238
|
+
monitor: isTestMode ? undefined : monitor,
|
|
230
239
|
wallet,
|
|
231
240
|
};
|
|
232
241
|
}
|
|
@@ -0,0 +1,60 @@
|
|
|
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
|
+
});
|
package/index.ts
CHANGED
|
@@ -462,7 +462,12 @@ export async function activate(api: any) {
|
|
|
462
462
|
return register(api);
|
|
463
463
|
}
|
|
464
464
|
|
|
465
|
+
let isInitialized = false;
|
|
466
|
+
|
|
465
467
|
export default function register(api: any) {
|
|
468
|
+
if (isInitialized) return;
|
|
469
|
+
isInitialized = true;
|
|
470
|
+
|
|
466
471
|
// Capture config at registration time
|
|
467
472
|
// Check all possible IDs for backward compatibility and various installation methods
|
|
468
473
|
const entries = api.getConfig?.()?.plugins?.entries || {};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "openclaw-overlay-plugin",
|
|
3
|
-
"version": "0.7.
|
|
3
|
+
"version": "0.7.48",
|
|
4
4
|
"description": "Openclaw BSV Overlay — agent discovery, service marketplace, and micropayments on the BSV blockchain",
|
|
5
5
|
"publishConfig": {
|
|
6
6
|
"access": "public"
|
|
@@ -16,12 +16,12 @@
|
|
|
16
16
|
"README.md"
|
|
17
17
|
],
|
|
18
18
|
"bin": {
|
|
19
|
-
"openclaw-overlay": "dist/cli.js"
|
|
19
|
+
"openclaw-overlay": "dist/src/cli.js"
|
|
20
20
|
},
|
|
21
21
|
"scripts": {
|
|
22
22
|
"build": "tsc",
|
|
23
23
|
"prepublishOnly": "npm run build",
|
|
24
|
-
"cli": "node dist/cli.js",
|
|
24
|
+
"cli": "node dist/src/cli.js",
|
|
25
25
|
"test": "npx tsx src/**/*.test.ts",
|
|
26
26
|
"lint": "eslint src/**/*.ts",
|
|
27
27
|
"postinstall": "node -e \"try{require('better-sqlite3')}catch{console.log('Note: better-sqlite3 requires build tools. If install failed, ensure python3 and a C++ compiler are available.')}\""
|
package/src/core/wallet.ts
CHANGED
|
@@ -243,9 +243,13 @@ export class BSVAgentWallet {
|
|
|
243
243
|
const chaintracksUrl = process.env.BSV_CHAINTRACKS_URL || 'https://chaintracks-us-1.bsvb.tech';
|
|
244
244
|
const arcUrl = process.env.BSV_ARC_URL;
|
|
245
245
|
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
246
|
+
const isTestMode = (config as any).enableMonitor === false;
|
|
247
|
+
|
|
248
|
+
if (!isTestMode) {
|
|
249
|
+
serviceOptions.chaintracks = new ChaintracksServiceClient(chain, chaintracksUrl);
|
|
250
|
+
if (arcUrl) {
|
|
251
|
+
serviceOptions.arcUrl = arcUrl;
|
|
252
|
+
}
|
|
249
253
|
}
|
|
250
254
|
|
|
251
255
|
serviceOptions.taalApiKey = taalApiKey;
|
|
@@ -254,10 +258,15 @@ export class BSVAgentWallet {
|
|
|
254
258
|
// 4. Background monitor
|
|
255
259
|
const monopts = Monitor.createDefaultWalletMonitorOptions(chain, storage, services);
|
|
256
260
|
const monitor = new Monitor(monopts);
|
|
257
|
-
|
|
261
|
+
if (!isTestMode) {
|
|
262
|
+
monitor.addDefaultTasks();
|
|
263
|
+
} else {
|
|
264
|
+
// In test mode, we clear all tasks to ensure no background activity
|
|
265
|
+
(monitor as any).tasks = [];
|
|
266
|
+
}
|
|
258
267
|
|
|
259
268
|
// 5. The BRC-100 Wallet
|
|
260
|
-
const wallet = new Wallet({ chain, keyDeriver, storage, services, monitor });
|
|
269
|
+
const wallet = isTestMode ? undefined : new Wallet({ chain, keyDeriver, storage, services, monitor });
|
|
261
270
|
|
|
262
271
|
// 6. SQLite storage via knex
|
|
263
272
|
const filePath = path.join(config.storageDir, `${DEFAULT_DB_NAME}.sqlite`);
|
|
@@ -290,9 +299,9 @@ export class BSVAgentWallet {
|
|
|
290
299
|
keyDeriver,
|
|
291
300
|
chain,
|
|
292
301
|
storage,
|
|
293
|
-
services,
|
|
294
|
-
monitor,
|
|
302
|
+
services: isTestMode ? undefined : services,
|
|
303
|
+
monitor: isTestMode ? undefined : monitor,
|
|
295
304
|
wallet,
|
|
296
|
-
};
|
|
305
|
+
} as any;
|
|
297
306
|
}
|
|
298
307
|
}
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Identity Consistency tests
|
|
3
|
+
*
|
|
4
|
+
* Verifies that all plugins produce the exact same identityKey from the same root secret.
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
import { BSVAgentWallet } from '../core/wallet.js';
|
|
8
|
+
import * as fs from 'node:fs';
|
|
9
|
+
import * as path from 'node:path';
|
|
10
|
+
import * as os from 'node:os';
|
|
11
|
+
|
|
12
|
+
// Simple test runner
|
|
13
|
+
let passed = 0;
|
|
14
|
+
let failed = 0;
|
|
15
|
+
|
|
16
|
+
async function test(name: string, fn: () => void | Promise<void>) {
|
|
17
|
+
try {
|
|
18
|
+
await fn();
|
|
19
|
+
console.log(` ✓ ${name}`);
|
|
20
|
+
passed++;
|
|
21
|
+
} catch (err: unknown) {
|
|
22
|
+
console.log(` ✗ ${name}`);
|
|
23
|
+
console.log(err);
|
|
24
|
+
failed++;
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
function assert(condition: boolean, message: string) {
|
|
29
|
+
if (!condition) throw new Error(`Assertion failed: ${message}`);
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
async function run() {
|
|
33
|
+
console.log('Identity Consistency tests\n');
|
|
34
|
+
|
|
35
|
+
const SHARED_ROOT_KEY = '0000000000000000000000000000000000000000000000000000000000000001';
|
|
36
|
+
const EXPECTED_IDENTITY = '0279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798';
|
|
37
|
+
|
|
38
|
+
await test('Overlay plugin derives correct compressed pubkey', async () => {
|
|
39
|
+
const tmpDir = fs.mkdtempSync(path.join(os.tmpdir(), 'identity-test-'));
|
|
40
|
+
try {
|
|
41
|
+
const wallet = await BSVAgentWallet.load({
|
|
42
|
+
network: 'mainnet',
|
|
43
|
+
storageDir: tmpDir,
|
|
44
|
+
rootKeyHex: SHARED_ROOT_KEY,
|
|
45
|
+
enableMonitor: false
|
|
46
|
+
} as any);
|
|
47
|
+
|
|
48
|
+
const identity = await wallet.getIdentityKey();
|
|
49
|
+
assert(identity === EXPECTED_IDENTITY, `Should match expected identity. Got: ${identity}`);
|
|
50
|
+
assert(identity.length === 66, `Should be 66 chars (compressed hex). Got: ${identity.length}`);
|
|
51
|
+
|
|
52
|
+
await wallet.destroy();
|
|
53
|
+
} finally {
|
|
54
|
+
fs.rmSync(tmpDir, { recursive: true, force: true });
|
|
55
|
+
}
|
|
56
|
+
});
|
|
57
|
+
|
|
58
|
+
// Since both use the same core logic (copied or shared), we verify the logic here
|
|
59
|
+
// against the known secp256k1 base point G (compressed).
|
|
60
|
+
|
|
61
|
+
console.log(`\n${passed} passed, ${failed} failed`);
|
|
62
|
+
if (failed > 0) process.exit(1);
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
run().catch(err => {
|
|
66
|
+
console.error(err);
|
|
67
|
+
process.exit(1);
|
|
68
|
+
});
|