@moltbankhq/openclaw 0.1.1 → 0.1.3
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 +4 -4
- package/index.ts +69 -107
- package/openclaw.plugin.json +1 -1
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# @moltbankhq/openclaw
|
|
2
2
|
|
|
3
|
-
OpenClaw plugin for [MoltBank](https://moltbank.bot) —
|
|
3
|
+
OpenClaw plugin for [MoltBank](https://moltbank.bot) — stablecoin treasury controls, approvals, and audit trails for agent fleets.
|
|
4
4
|
|
|
5
5
|
## Install
|
|
6
6
|
|
|
@@ -8,9 +8,11 @@ OpenClaw plugin for [MoltBank](https://moltbank.bot) — spend control, approval
|
|
|
8
8
|
openclaw plugins install @moltbankhq/openclaw
|
|
9
9
|
```
|
|
10
10
|
|
|
11
|
+
Direct `npm install` can be useful to acquire the package, but by itself it does not complete OpenClaw plugin registration or setup.
|
|
12
|
+
|
|
11
13
|
## What it does
|
|
12
14
|
|
|
13
|
-
This plugin connects your OpenClaw agent to MoltBank's
|
|
15
|
+
This plugin connects your OpenClaw agent to MoltBank's stablecoin treasury infrastructure. On install, it:
|
|
14
16
|
|
|
15
17
|
- Downloads and configures the MoltBank skill (SKILL.md + scripts)
|
|
16
18
|
- Installs and registers [mcporter](https://www.npmjs.com/package/mcporter) for MCP server connectivity
|
|
@@ -78,8 +80,6 @@ The MoltBank skill gives your agent access to:
|
|
|
78
80
|
- **Approval workflows** — human-in-the-loop for spend above thresholds
|
|
79
81
|
- **x402 payments** — agent-to-agent payments via the x402 protocol
|
|
80
82
|
- **Audit trails** — full visibility into which agent spent what, when, and why
|
|
81
|
-
- **Polymarket** — prediction market operations
|
|
82
|
-
- **Pump.Fun** — Solana token operations
|
|
83
83
|
|
|
84
84
|
## Requirements
|
|
85
85
|
|
package/index.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { execSync, spawn } from 'child_process';
|
|
2
|
-
import { chmodSync, existsSync, mkdirSync, readFileSync,
|
|
2
|
+
import { chmodSync, existsSync, mkdirSync, readFileSync, unlinkSync, writeFileSync } from 'fs';
|
|
3
3
|
import { join, dirname } from 'path';
|
|
4
4
|
import { homedir } from 'os';
|
|
5
5
|
const IS_WIN = process.platform === 'win32';
|
|
@@ -141,6 +141,11 @@ function getAppBaseUrl(cfg: MoltbankPluginConfig): string {
|
|
|
141
141
|
return (cfg?.appBaseUrl || process.env.APP_BASE_URL || 'https://app.moltbank.bot').trim();
|
|
142
142
|
}
|
|
143
143
|
|
|
144
|
+
function getSkillBundleBaseUrl(cfg: MoltbankPluginConfig): string {
|
|
145
|
+
const base = getAppBaseUrl(cfg).replace(/\/$/, '');
|
|
146
|
+
return base.endsWith('/skill') ? base : `${base}/skill`;
|
|
147
|
+
}
|
|
148
|
+
|
|
144
149
|
function isSandboxEnabled(): boolean {
|
|
145
150
|
try {
|
|
146
151
|
const configPath = join(homedir(), '.openclaw', 'openclaw.json');
|
|
@@ -276,43 +281,34 @@ function ensureWrapperExecutable(skillDir: string, api: LoggerApi): void {
|
|
|
276
281
|
// ─── skill install ───────────────────────────────────────────────────────────
|
|
277
282
|
|
|
278
283
|
const SKILL_FILES = [
|
|
284
|
+
'README.md',
|
|
279
285
|
'skill.md',
|
|
280
|
-
'setup.md',
|
|
281
|
-
'onboarding.md',
|
|
282
|
-
'multi-org.md',
|
|
283
|
-
'tools-reference.md',
|
|
284
|
-
'x402-workflow.md',
|
|
285
|
-
'heartbeat.md',
|
|
286
|
-
'rules.md',
|
|
287
286
|
'skill.json',
|
|
288
|
-
'
|
|
289
|
-
'
|
|
290
|
-
'
|
|
291
|
-
'
|
|
292
|
-
'openclaw-
|
|
293
|
-
'
|
|
294
|
-
'
|
|
287
|
+
'install.sh',
|
|
288
|
+
'assets/mcporter.json',
|
|
289
|
+
'references/heartbeat.md',
|
|
290
|
+
'references/onboarding.md',
|
|
291
|
+
'references/openclaw-signer-eoa.md',
|
|
292
|
+
'references/rules.md',
|
|
293
|
+
'references/setup.md',
|
|
294
|
+
'references/tools-reference.md',
|
|
295
|
+
'references/x402-workflow.md',
|
|
295
296
|
'scripts/openclaw-runtime-config.mjs',
|
|
296
297
|
'scripts/request-oauth-device-code.mjs',
|
|
297
298
|
'scripts/init-openclaw-signer.mjs',
|
|
298
|
-
'scripts/init-openclaw-solana-signer.mjs',
|
|
299
|
-
'scripts/bootstrap-openclaw-pumpfun-wallet.mjs',
|
|
300
299
|
'scripts/inspect-x402-requirements.mjs',
|
|
301
|
-
'scripts/inspect-solana-wallet.mjs',
|
|
302
|
-
'scripts/inspect-polygon-wallet.mjs',
|
|
303
|
-
'scripts/quote-solana-budget.mjs',
|
|
304
|
-
'scripts/polymarket-execute-lifi-tx.mjs',
|
|
305
|
-
'scripts/polymarket-signer-to-safe.mjs',
|
|
306
300
|
'scripts/poll-oauth-token.mjs',
|
|
307
301
|
'scripts/export-api-key.mjs',
|
|
308
|
-
'scripts/fetch-openrouter-intent.mjs',
|
|
309
302
|
'scripts/x402-pay-and-confirm.mjs',
|
|
310
|
-
'scripts/
|
|
303
|
+
'scripts/setup-sandbox.sh',
|
|
311
304
|
'scripts/moltbank.sh',
|
|
312
|
-
'scripts/moltbank.ps1'
|
|
313
|
-
'scripts/polymarket-service.mjs'
|
|
305
|
+
'scripts/moltbank.ps1'
|
|
314
306
|
];
|
|
315
307
|
|
|
308
|
+
function hasRequiredSkillFiles(skillDir: string): boolean {
|
|
309
|
+
return SKILL_FILES.every((file) => existsSync(join(skillDir, file)));
|
|
310
|
+
}
|
|
311
|
+
|
|
316
312
|
function ensureSkillInstalled(
|
|
317
313
|
skillDir: string,
|
|
318
314
|
appBaseUrl: string,
|
|
@@ -321,12 +317,21 @@ function ensureSkillInstalled(
|
|
|
321
317
|
mode: 'sandbox' | 'host' = 'sandbox'
|
|
322
318
|
) {
|
|
323
319
|
const successFlag = join(skillDir, '.install_success');
|
|
324
|
-
if (existsSync(successFlag)) {
|
|
320
|
+
if (existsSync(successFlag) && hasRequiredSkillFiles(skillDir)) {
|
|
325
321
|
ensureWrapperExecutable(skillDir, api);
|
|
326
322
|
api.logger.info('[moltbank] ✓ skill already installed at ' + skillDir);
|
|
327
323
|
return true;
|
|
328
324
|
}
|
|
329
325
|
|
|
326
|
+
if (existsSync(successFlag)) {
|
|
327
|
+
api.logger.warn('[moltbank] existing skill install is stale or incomplete — reinstalling current bundle');
|
|
328
|
+
try {
|
|
329
|
+
unlinkSync(successFlag);
|
|
330
|
+
} catch {
|
|
331
|
+
// ignore
|
|
332
|
+
}
|
|
333
|
+
}
|
|
334
|
+
|
|
330
335
|
api.logger.info(`[moltbank] installing skill '${skillName}' to ${skillDir} (mode: ${mode})`);
|
|
331
336
|
mkdirSync(skillDir, { recursive: true });
|
|
332
337
|
|
|
@@ -350,66 +355,32 @@ function ensureSkillInstalled(
|
|
|
350
355
|
function ensureSkillFilesUppercase(skillDir: string, api: LoggerApi) {
|
|
351
356
|
const lower = join(skillDir, 'skill.md');
|
|
352
357
|
const upper = join(skillDir, 'SKILL.md');
|
|
353
|
-
if (existsSync(
|
|
354
|
-
api.logger.info('[moltbank] ✓
|
|
358
|
+
if (existsSync(lower)) {
|
|
359
|
+
api.logger.info('[moltbank] ✓ skill entrypoint present (skill.md)');
|
|
355
360
|
return;
|
|
356
361
|
}
|
|
357
|
-
if (existsSync(
|
|
358
|
-
|
|
359
|
-
api.logger.info('[moltbank] ✓ renamed skill.md → SKILL.md');
|
|
362
|
+
if (existsSync(upper)) {
|
|
363
|
+
api.logger.info('[moltbank] ✓ skill entrypoint present (SKILL.md)');
|
|
360
364
|
} else {
|
|
361
365
|
api.logger.warn('[moltbank] ✗ neither skill.md nor SKILL.md found');
|
|
362
366
|
}
|
|
363
367
|
}
|
|
364
368
|
|
|
365
369
|
function fixSkillFrontmatter(skillDir: string, skillName: string, api: LoggerApi) {
|
|
366
|
-
const skillFile = join(skillDir, 'SKILL.md');
|
|
370
|
+
const skillFile = existsSync(join(skillDir, 'skill.md')) ? join(skillDir, 'skill.md') : join(skillDir, 'SKILL.md');
|
|
367
371
|
if (!existsSync(skillFile)) {
|
|
368
|
-
api.logger.warn('[moltbank] ✗
|
|
372
|
+
api.logger.warn('[moltbank] ✗ skill entrypoint not found — skipping frontmatter validation');
|
|
369
373
|
return;
|
|
370
374
|
}
|
|
371
375
|
|
|
372
376
|
const content = readFileSync(skillFile, 'utf8').replace(/\r\n/g, '\n');
|
|
373
377
|
const frontmatterMatch = content.match(/^---\n([\s\S]*?)\n---/);
|
|
374
378
|
if (!frontmatterMatch) {
|
|
375
|
-
api.logger.warn('[moltbank] ✗ no frontmatter in
|
|
379
|
+
api.logger.warn('[moltbank] ✗ no frontmatter in skill entrypoint');
|
|
376
380
|
return;
|
|
377
381
|
}
|
|
378
382
|
|
|
379
|
-
|
|
380
|
-
const newFrontmatter = `---
|
|
381
|
-
name: ${skillName}
|
|
382
|
-
version: 1.5.3
|
|
383
|
-
description: MCP skill for MoltBank business banking workflows (treasury, approvals, allowances, x402, OpenRouter, Polymarket, and Pump.Fun).
|
|
384
|
-
homepage: \${APP_BASE_URL:-https://app.moltbank.bot}
|
|
385
|
-
metadata:
|
|
386
|
-
category: finance
|
|
387
|
-
api_base: \${APP_BASE_URL:-https://app.moltbank.bot}/api/mcp
|
|
388
|
-
install_script: \${APP_BASE_URL:-https://app.moltbank.bot}/install.sh
|
|
389
|
-
openclaw:
|
|
390
|
-
requires:
|
|
391
|
-
bins:
|
|
392
|
-
${binsYaml}
|
|
393
|
-
npm:
|
|
394
|
-
- '@x402/fetch@^2.3.0'
|
|
395
|
-
- '@x402/evm@^2.3.1'
|
|
396
|
-
- 'viem@^2.46.0'
|
|
397
|
-
- '@polymarket/clob-client'
|
|
398
|
-
- 'ethers@5'
|
|
399
|
-
- '@solana/web3.js@^1.98.4'
|
|
400
|
-
- 'bs58@^6.0.0'
|
|
401
|
-
primaryEnv: MOLTBANK
|
|
402
|
-
---`;
|
|
403
|
-
|
|
404
|
-
const body = content.slice(frontmatterMatch[0].length);
|
|
405
|
-
const fixed = newFrontmatter + body;
|
|
406
|
-
|
|
407
|
-
if (fixed !== content) {
|
|
408
|
-
writeFileSync(skillFile, fixed, 'utf8');
|
|
409
|
-
api.logger.info(`[moltbank] ✓ SKILL.md frontmatter fixed → name: ${skillName}`);
|
|
410
|
-
} else {
|
|
411
|
-
api.logger.info('[moltbank] ✓ SKILL.md frontmatter already correct');
|
|
412
|
-
}
|
|
383
|
+
api.logger.info(`[moltbank] ✓ skill frontmatter retained as authored (${skillName})`);
|
|
413
384
|
}
|
|
414
385
|
|
|
415
386
|
function ensureSkillPermissions(skillDir: string, api: LoggerApi) {
|
|
@@ -418,8 +389,9 @@ function ensureSkillPermissions(skillDir: string, api: LoggerApi) {
|
|
|
418
389
|
return;
|
|
419
390
|
}
|
|
420
391
|
|
|
421
|
-
const
|
|
422
|
-
const configFile = join(skillDir, '
|
|
392
|
+
const assetsDir = join(skillDir, 'assets');
|
|
393
|
+
const configFile = join(skillDir, 'assets', 'mcporter.json');
|
|
394
|
+
const referencesDir = join(skillDir, 'references');
|
|
423
395
|
const scriptsDir = join(skillDir, 'scripts');
|
|
424
396
|
|
|
425
397
|
const user = run('whoami', { silent: true }).stdout;
|
|
@@ -428,9 +400,9 @@ function ensureSkillPermissions(skillDir: string, api: LoggerApi) {
|
|
|
428
400
|
api.logger.info(`[moltbank] ✓ ownership corrected to ${user}`);
|
|
429
401
|
}
|
|
430
402
|
|
|
431
|
-
if (existsSync(
|
|
432
|
-
run(`chmod 777 "${
|
|
433
|
-
api.logger.info('[moltbank] ✓
|
|
403
|
+
if (existsSync(assetsDir)) {
|
|
404
|
+
run(`chmod 777 "${assetsDir}"`, { silent: true });
|
|
405
|
+
api.logger.info('[moltbank] ✓ assets/ permissions → 777');
|
|
434
406
|
}
|
|
435
407
|
if (existsSync(configFile)) {
|
|
436
408
|
run(`chmod 666 "${configFile}"`, { silent: true });
|
|
@@ -439,15 +411,20 @@ function ensureSkillPermissions(skillDir: string, api: LoggerApi) {
|
|
|
439
411
|
if (existsSync(scriptsDir)) {
|
|
440
412
|
run(`chmod -R 755 "${scriptsDir}"`, { silent: true });
|
|
441
413
|
api.logger.info('[moltbank] ✓ scripts/ permissions → 755');
|
|
442
|
-
run(`find "${scriptsDir}" -type f
|
|
414
|
+
run(`find "${scriptsDir}" -type f -exec sed -i 's/\r$//' {} +`, {
|
|
443
415
|
silent: true
|
|
444
416
|
});
|
|
445
417
|
api.logger.info('[moltbank] ✓ scripts/ line endings normalized (CRLF → LF)');
|
|
446
418
|
}
|
|
447
419
|
|
|
448
420
|
if (existsSync(skillDir)) {
|
|
449
|
-
run(`find "${skillDir}" -maxdepth 1 -name "*.md"
|
|
450
|
-
|
|
421
|
+
run(`find "${skillDir}" -maxdepth 1 -type f -name "*.md" -exec sed -i 's/\r$//' {} +`, { silent: true });
|
|
422
|
+
}
|
|
423
|
+
if (existsSync(referencesDir)) {
|
|
424
|
+
run(`find "${referencesDir}" -maxdepth 1 -type f -name "*.md" -exec sed -i 's/\r$//' {} +`, { silent: true });
|
|
425
|
+
}
|
|
426
|
+
if (existsSync(skillDir) || existsSync(referencesDir)) {
|
|
427
|
+
api.logger.info('[moltbank] ✓ markdown line endings normalized (CRLF → LF)');
|
|
451
428
|
}
|
|
452
429
|
}
|
|
453
430
|
|
|
@@ -464,28 +441,12 @@ function ensureNpmDeps(skillDir: string, api: LoggerApi, mode: 'sandbox' | 'host
|
|
|
464
441
|
dependencies: {
|
|
465
442
|
'@x402/fetch': '^2.3.0',
|
|
466
443
|
'@x402/evm': '^2.3.1',
|
|
467
|
-
viem: '^2.46.0'
|
|
468
|
-
'@polymarket/clob-client': 'latest',
|
|
469
|
-
ethers: '^5.8.0',
|
|
470
|
-
'@solana/web3.js': '^1.98.4',
|
|
471
|
-
bs58: '^6.0.0'
|
|
444
|
+
viem: '^2.46.0'
|
|
472
445
|
}
|
|
473
446
|
};
|
|
474
447
|
writeFileSync(pkgPath, JSON.stringify(fallbackPkg, null, 2) + '\n', 'utf8');
|
|
475
448
|
api.logger.warn('[moltbank] package.json not found — created fallback package.json for skill runtime deps');
|
|
476
449
|
}
|
|
477
|
-
try {
|
|
478
|
-
const pkg = JSON.parse(readFileSync(pkgPath, 'utf8'));
|
|
479
|
-
pkg.dependencies = pkg.dependencies ?? {};
|
|
480
|
-
const cur = String(pkg.dependencies['@polymarket/clob-client'] ?? '').trim();
|
|
481
|
-
if (!cur || cur === '^6.0.0') {
|
|
482
|
-
pkg.dependencies['@polymarket/clob-client'] = 'latest';
|
|
483
|
-
writeFileSync(pkgPath, JSON.stringify(pkg, null, 2) + '\n', 'utf8');
|
|
484
|
-
api.logger.info('[moltbank] normalized package.json: @polymarket/clob-client -> latest');
|
|
485
|
-
}
|
|
486
|
-
} catch (e) {
|
|
487
|
-
api.logger.warn('[moltbank] could not normalize package.json deps: ' + String(e));
|
|
488
|
-
}
|
|
489
450
|
api.logger.info('[moltbank] installing npm deps...');
|
|
490
451
|
if (mode === 'sandbox') {
|
|
491
452
|
const result = run('npm install --ignore-scripts', { cwd: skillDir });
|
|
@@ -927,13 +888,13 @@ function printAuthStatus(skillDir: string, appBaseUrl: string, api: LoggerApi):
|
|
|
927
888
|
}
|
|
928
889
|
|
|
929
890
|
function ensureMcporterConfig(skillDir: string, appBaseUrl: string, api: LoggerApi) {
|
|
930
|
-
const cfgPath = join(skillDir, '
|
|
931
|
-
mkdirSync(join(skillDir, '
|
|
891
|
+
const cfgPath = join(skillDir, 'assets', 'mcporter.json');
|
|
892
|
+
mkdirSync(join(skillDir, 'assets'), { recursive: true });
|
|
932
893
|
|
|
933
894
|
const cfg = {
|
|
934
895
|
mcpServers: {
|
|
935
896
|
MoltBank: {
|
|
936
|
-
description: 'MoltBank stablecoin
|
|
897
|
+
description: 'MoltBank stablecoin treasury MCP server powered by Fondu',
|
|
937
898
|
transport: 'sse',
|
|
938
899
|
url: `${appBaseUrl}/api/mcp`,
|
|
939
900
|
headers: {
|
|
@@ -965,7 +926,7 @@ function ensureMcporterConfig(skillDir: string, appBaseUrl: string, api: LoggerA
|
|
|
965
926
|
`--transport sse ` +
|
|
966
927
|
`--header "Authorization=Bearer \${MOLTBANK}" ` +
|
|
967
928
|
`--header "Content-Type=application/json" ` +
|
|
968
|
-
`--description "MoltBank stablecoin
|
|
929
|
+
`--description "MoltBank stablecoin treasury MCP server powered by Fondu" ` +
|
|
969
930
|
`--scope home`;
|
|
970
931
|
|
|
971
932
|
const result = run(addCmd, { silent: false });
|
|
@@ -1040,7 +1001,7 @@ function injectSandboxEnv(skillDir: string, api: LoggerApi): boolean {
|
|
|
1040
1001
|
});
|
|
1041
1002
|
if (!initResult.ok) {
|
|
1042
1003
|
api.logger.warn('[moltbank] ✗ could not generate EOA signer: ' + initResult.stderr);
|
|
1043
|
-
api.logger.warn('[moltbank] agent will generate signer on first x402
|
|
1004
|
+
api.logger.warn('[moltbank] agent will generate signer on first x402 use');
|
|
1044
1005
|
} else {
|
|
1045
1006
|
const freshCreds = JSON.parse(readFileSync(credsPath, 'utf8')) as CredentialsFile;
|
|
1046
1007
|
const freshOrg = freshCreds.organizations?.find((o: CredentialsOrganization) => o.name === activeOrg);
|
|
@@ -1100,7 +1061,7 @@ function configureSandbox(api: LoggerApi): boolean {
|
|
|
1100
1061
|
'update-alternatives --set node $NODE22_BIN 2>/dev/null || true && ' +
|
|
1101
1062
|
'node -v && npm -v && ' +
|
|
1102
1063
|
"echo '[moltbank:sandbox] [5/7] installing npm global deps (mcporter + sdk libs)...' && " +
|
|
1103
|
-
'npm install -g mcporter @x402/fetch@2.3.0 @x402/evm@2.3.1 viem@2.46.0
|
|
1064
|
+
'npm install -g mcporter @x402/fetch@2.3.0 @x402/evm@2.3.1 viem@2.46.0 && ' +
|
|
1104
1065
|
"echo '[moltbank:sandbox] [6/7] verifying mcporter binary...' && " +
|
|
1105
1066
|
"NPM_GLOBAL=$(npm root -g 2>/dev/null | sed 's|/node_modules$|/bin|' || true) && " +
|
|
1106
1067
|
'if [ -n "$NPM_GLOBAL" ] && [ -x "$NPM_GLOBAL/mcporter" ]; then ln -sf "$NPM_GLOBAL/mcporter" /usr/local/bin/mcporter || true; fi && ' +
|
|
@@ -1189,6 +1150,7 @@ function recreateSandboxAndRestart(api: LoggerApi) {
|
|
|
1189
1150
|
async function runSetup(cfg: MoltbankPluginConfig, api: LoggerApi, options: { authWaitMode?: AuthWaitMode } = {}) {
|
|
1190
1151
|
let hostReady = false;
|
|
1191
1152
|
const appBaseUrl = getAppBaseUrl(cfg);
|
|
1153
|
+
const skillBundleBaseUrl = getSkillBundleBaseUrl(cfg);
|
|
1192
1154
|
const skillName = getSkillName(cfg);
|
|
1193
1155
|
const sandbox = isSandboxEnabled();
|
|
1194
1156
|
const skillDir = getSkillDir(cfg);
|
|
@@ -1210,13 +1172,13 @@ async function runSetup(cfg: MoltbankPluginConfig, api: LoggerApi, options: { au
|
|
|
1210
1172
|
ensureMcporter(api);
|
|
1211
1173
|
|
|
1212
1174
|
api.logger.info('[moltbank] [sandbox 1/10] installing skill files...');
|
|
1213
|
-
const skillInstalled = ensureSkillInstalled(skillDir,
|
|
1175
|
+
const skillInstalled = ensureSkillInstalled(skillDir, skillBundleBaseUrl, skillName, api, 'sandbox');
|
|
1214
1176
|
if (!skillInstalled) {
|
|
1215
1177
|
api.logger.warn('[moltbank] skill install failed — aborting sandbox setup');
|
|
1216
1178
|
return;
|
|
1217
1179
|
}
|
|
1218
1180
|
|
|
1219
|
-
api.logger.info('[moltbank] [sandbox 2/10]
|
|
1181
|
+
api.logger.info('[moltbank] [sandbox 2/10] verifying skill entrypoint...');
|
|
1220
1182
|
ensureSkillFilesUppercase(skillDir, api);
|
|
1221
1183
|
|
|
1222
1184
|
api.logger.info('[moltbank] [sandbox 3/10] applying permissions (chown + chmod)...');
|
|
@@ -1243,7 +1205,7 @@ async function runSetup(cfg: MoltbankPluginConfig, api: LoggerApi, options: { au
|
|
|
1243
1205
|
api.logger.info('[moltbank] [sandbox 5/10] installing skill npm dependencies...');
|
|
1244
1206
|
ensureNpmDeps(skillDir, api, 'sandbox');
|
|
1245
1207
|
|
|
1246
|
-
api.logger.info('[moltbank] [sandbox 6/10]
|
|
1208
|
+
api.logger.info('[moltbank] [sandbox 6/10] validating skill frontmatter...');
|
|
1247
1209
|
fixSkillFrontmatter(skillDir, skillName, api);
|
|
1248
1210
|
|
|
1249
1211
|
api.logger.info('[moltbank] [sandbox 7/10] writing/registering mcporter config...');
|
|
@@ -1267,13 +1229,13 @@ async function runSetup(cfg: MoltbankPluginConfig, api: LoggerApi, options: { au
|
|
|
1267
1229
|
ensureMcporter(api);
|
|
1268
1230
|
|
|
1269
1231
|
api.logger.info('[moltbank] [host 2/8] installing skill files...');
|
|
1270
|
-
const installed = ensureSkillInstalled(skillDir,
|
|
1232
|
+
const installed = ensureSkillInstalled(skillDir, skillBundleBaseUrl, skillName, api, 'host');
|
|
1271
1233
|
if (!installed) {
|
|
1272
1234
|
api.logger.warn('[moltbank] host setup aborted: skill install failed. Verify install.sh/base URL and retry.');
|
|
1273
1235
|
return;
|
|
1274
1236
|
}
|
|
1275
1237
|
|
|
1276
|
-
api.logger.info('[moltbank] [host 3/8]
|
|
1238
|
+
api.logger.info('[moltbank] [host 3/8] verifying skill entrypoint/frontmatter...');
|
|
1277
1239
|
ensureSkillFilesUppercase(skillDir, api);
|
|
1278
1240
|
fixSkillFrontmatter(skillDir, skillName, api);
|
|
1279
1241
|
|
|
@@ -1328,8 +1290,8 @@ async function runSetup(cfg: MoltbankPluginConfig, api: LoggerApi, options: { au
|
|
|
1328
1290
|
} else if (hostReady) {
|
|
1329
1291
|
api.logger.info('[moltbank] ✓ host ready');
|
|
1330
1292
|
}
|
|
1331
|
-
api.logger.info(`[moltbank] skill: ${skillDir}/
|
|
1332
|
-
api.logger.info(`[moltbank] mcporter: ${skillDir}/
|
|
1293
|
+
api.logger.info(`[moltbank] skill: ${skillDir}/skill.md`);
|
|
1294
|
+
api.logger.info(`[moltbank] mcporter: ${skillDir}/assets/mcporter.json`);
|
|
1333
1295
|
if (sandbox) {
|
|
1334
1296
|
const finalConfig = readOpenclawConfig();
|
|
1335
1297
|
const finalEnv = asStringRecord(getNestedValue(finalConfig, ['agents', 'defaults', 'sandbox', 'docker', 'env']));
|
package/openclaw.plugin.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"id": "moltbank",
|
|
3
3
|
"name": "MoltBank",
|
|
4
|
-
"description": "MoltBank
|
|
4
|
+
"description": "MoltBank stablecoin treasury plugin for OpenClaw — installs mcporter, npm dependencies, sandbox setup, and the MoltBank skill",
|
|
5
5
|
"configSchema": {
|
|
6
6
|
"type": "object",
|
|
7
7
|
"additionalProperties": false,
|
package/package.json
CHANGED