@moltbankhq/openclaw 0.1.2 → 0.1.4
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 +32 -13
- package/bin/moltbank.mjs +19 -0
- package/cli.ts +203 -0
- package/index.ts +26 -16
- package/package.json +8 -2
package/README.md
CHANGED
|
@@ -1,20 +1,30 @@
|
|
|
1
1
|
# @moltbankhq/openclaw
|
|
2
2
|
|
|
3
|
-
OpenClaw plugin for [MoltBank](https://moltbank.bot) — stablecoin treasury controls, approvals, and audit trails for agent fleets.
|
|
3
|
+
Standalone CLI and optional OpenClaw plugin for [MoltBank](https://moltbank.bot) — stablecoin treasury controls, approvals, and audit trails for agent fleets.
|
|
4
4
|
|
|
5
5
|
## Install
|
|
6
6
|
|
|
7
7
|
```bash
|
|
8
|
-
|
|
8
|
+
npm install -g @moltbankhq/openclaw
|
|
9
9
|
```
|
|
10
10
|
|
|
11
|
-
|
|
11
|
+
You can also run it without a global install:
|
|
12
|
+
|
|
13
|
+
```bash
|
|
14
|
+
npx @moltbankhq/openclaw setup
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
OpenClaw plugin mode still exists in this pass for compatibility:
|
|
18
|
+
|
|
19
|
+
```bash
|
|
20
|
+
openclaw plugins install @moltbankhq/openclaw
|
|
21
|
+
```
|
|
12
22
|
|
|
13
23
|
## What it does
|
|
14
24
|
|
|
15
|
-
This
|
|
25
|
+
This package connects your OpenClaw agent to MoltBank's stablecoin treasury infrastructure. During setup, it:
|
|
16
26
|
|
|
17
|
-
- Downloads and configures the MoltBank skill (
|
|
27
|
+
- Downloads and configures the MoltBank skill (`skill.md` + scripts)
|
|
18
28
|
- Installs and registers [mcporter](https://www.npmjs.com/package/mcporter) for MCP server connectivity
|
|
19
29
|
- Handles OAuth device-code authentication to link your agent to your MoltBank account
|
|
20
30
|
- Configures sandbox (Docker) or host mode automatically based on your OpenClaw setup
|
|
@@ -27,24 +37,33 @@ Once set up, your agent can manage treasury operations, set per-agent spending l
|
|
|
27
37
|
After installing, run:
|
|
28
38
|
|
|
29
39
|
```bash
|
|
30
|
-
|
|
40
|
+
moltbank setup
|
|
31
41
|
```
|
|
32
42
|
|
|
33
|
-
The
|
|
43
|
+
The CLI will guide you through linking your MoltBank account via browser-based OAuth. Once approved, setup finalizes automatically.
|
|
34
44
|
|
|
35
45
|
## CLI Commands
|
|
36
46
|
|
|
37
47
|
| Command | Description |
|
|
38
48
|
|---------|-------------|
|
|
39
|
-
| `
|
|
40
|
-
| `
|
|
41
|
-
| `
|
|
42
|
-
| `
|
|
43
|
-
| `
|
|
44
|
-
| `
|
|
49
|
+
| `moltbank setup` | Run full setup (nonblocking auth by default) |
|
|
50
|
+
| `moltbank setup --blocking` | Run setup and wait for OAuth approval |
|
|
51
|
+
| `moltbank setup-blocking` | Run setup and wait for OAuth approval |
|
|
52
|
+
| `moltbank auth-status` | Check current auth state |
|
|
53
|
+
| `moltbank sandbox-setup` | Reconfigure sandbox Docker settings |
|
|
54
|
+
| `moltbank inject-key` | Re-inject env vars from credentials |
|
|
55
|
+
| `moltbank register` | Re-register mcporter MCP server |
|
|
45
56
|
|
|
46
57
|
## Configuration
|
|
47
58
|
|
|
59
|
+
CLI flags:
|
|
60
|
+
|
|
61
|
+
```bash
|
|
62
|
+
moltbank setup --app-base-url https://app.moltbank.bot --skill-name MoltBank
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
Plugin mode can still read optional config from your `openclaw.json`:
|
|
66
|
+
|
|
48
67
|
Optional config in your `openclaw.json`:
|
|
49
68
|
|
|
50
69
|
```json
|
package/bin/moltbank.mjs
ADDED
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
import { spawnSync } from 'child_process';
|
|
4
|
+
import { dirname, resolve } from 'path';
|
|
5
|
+
import { fileURLToPath } from 'url';
|
|
6
|
+
|
|
7
|
+
const binDir = dirname(fileURLToPath(import.meta.url));
|
|
8
|
+
const cliPath = resolve(binDir, '../cli.ts');
|
|
9
|
+
const result = spawnSync(process.execPath, ['--import', 'tsx/esm', cliPath, ...process.argv.slice(2)], {
|
|
10
|
+
stdio: 'inherit',
|
|
11
|
+
env: process.env
|
|
12
|
+
});
|
|
13
|
+
|
|
14
|
+
if (result.error) {
|
|
15
|
+
console.error(`[moltbank] failed to start CLI: ${result.error.message}`);
|
|
16
|
+
process.exit(1);
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
process.exit(result.status ?? 1);
|
package/cli.ts
ADDED
|
@@ -0,0 +1,203 @@
|
|
|
1
|
+
import { readFileSync } from 'fs';
|
|
2
|
+
import process from 'process';
|
|
3
|
+
import {
|
|
4
|
+
configureSandbox,
|
|
5
|
+
ensureMcporterConfig,
|
|
6
|
+
getAppBaseUrl,
|
|
7
|
+
getSetupAuthWaitMode,
|
|
8
|
+
getSkillDir,
|
|
9
|
+
injectSandboxEnv,
|
|
10
|
+
printAuthStatus,
|
|
11
|
+
recreateSandboxAndRestart,
|
|
12
|
+
runSetup
|
|
13
|
+
} from './index.ts';
|
|
14
|
+
|
|
15
|
+
type CliConfig = {
|
|
16
|
+
appBaseUrl?: string;
|
|
17
|
+
skillName?: string;
|
|
18
|
+
};
|
|
19
|
+
|
|
20
|
+
type ParsedArgs = {
|
|
21
|
+
command?: string;
|
|
22
|
+
config: CliConfig;
|
|
23
|
+
help: boolean;
|
|
24
|
+
version: boolean;
|
|
25
|
+
blocking: boolean;
|
|
26
|
+
};
|
|
27
|
+
|
|
28
|
+
const HELP_TEXT = `MoltBank CLI
|
|
29
|
+
|
|
30
|
+
Usage:
|
|
31
|
+
moltbank <command> [options]
|
|
32
|
+
|
|
33
|
+
Commands:
|
|
34
|
+
setup Run MoltBank setup (nonblocking auth by default)
|
|
35
|
+
setup-blocking Run MoltBank setup and wait for OAuth approval
|
|
36
|
+
auth-status Show current MoltBank auth state
|
|
37
|
+
sandbox-setup Reconfigure sandbox Docker settings in openclaw.json
|
|
38
|
+
inject-key Re-inject sandbox env vars from credentials.json
|
|
39
|
+
register Re-register mcporter MCP config
|
|
40
|
+
|
|
41
|
+
Options:
|
|
42
|
+
--app-base-url <url> Override MoltBank deployment URL
|
|
43
|
+
--skill-name <name> Override skill folder name
|
|
44
|
+
--blocking Alias for blocking auth mode with setup
|
|
45
|
+
-h, --help Show help
|
|
46
|
+
-v, --version Show package version
|
|
47
|
+
|
|
48
|
+
Examples:
|
|
49
|
+
moltbank setup
|
|
50
|
+
moltbank setup --blocking
|
|
51
|
+
moltbank auth-status
|
|
52
|
+
moltbank register --app-base-url https://app.moltbank.bot
|
|
53
|
+
`;
|
|
54
|
+
|
|
55
|
+
function readVersion(): string {
|
|
56
|
+
const packageUrl = new URL('./package.json', import.meta.url);
|
|
57
|
+
const packageJson = JSON.parse(readFileSync(packageUrl, 'utf8')) as { version?: string };
|
|
58
|
+
return packageJson.version ?? '0.0.0';
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
function parseArgs(argv: string[]): ParsedArgs {
|
|
62
|
+
const config: CliConfig = {};
|
|
63
|
+
const positional: string[] = [];
|
|
64
|
+
let help = false;
|
|
65
|
+
let version = false;
|
|
66
|
+
let blocking = false;
|
|
67
|
+
|
|
68
|
+
for (let index = 0; index < argv.length; index += 1) {
|
|
69
|
+
const arg = argv[index];
|
|
70
|
+
|
|
71
|
+
if (arg === '-h' || arg === '--help') {
|
|
72
|
+
help = true;
|
|
73
|
+
continue;
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
if (arg === '-v' || arg === '--version') {
|
|
77
|
+
version = true;
|
|
78
|
+
continue;
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
if (arg === '--blocking') {
|
|
82
|
+
blocking = true;
|
|
83
|
+
continue;
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
if (arg === '--app-base-url') {
|
|
87
|
+
const value = argv[index + 1];
|
|
88
|
+
if (!value) {
|
|
89
|
+
throw new Error('missing value for --app-base-url');
|
|
90
|
+
}
|
|
91
|
+
config.appBaseUrl = value;
|
|
92
|
+
index += 1;
|
|
93
|
+
continue;
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
if (arg.startsWith('--app-base-url=')) {
|
|
97
|
+
config.appBaseUrl = arg.slice('--app-base-url='.length);
|
|
98
|
+
continue;
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
if (arg === '--skill-name') {
|
|
102
|
+
const value = argv[index + 1];
|
|
103
|
+
if (!value) {
|
|
104
|
+
throw new Error('missing value for --skill-name');
|
|
105
|
+
}
|
|
106
|
+
config.skillName = value;
|
|
107
|
+
index += 1;
|
|
108
|
+
continue;
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
if (arg.startsWith('--skill-name=')) {
|
|
112
|
+
config.skillName = arg.slice('--skill-name='.length);
|
|
113
|
+
continue;
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
if (arg.startsWith('-')) {
|
|
117
|
+
throw new Error(`unknown option: ${arg}`);
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
positional.push(arg);
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
return {
|
|
124
|
+
command: positional[0],
|
|
125
|
+
config,
|
|
126
|
+
help,
|
|
127
|
+
version,
|
|
128
|
+
blocking
|
|
129
|
+
};
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
async function runCommand(parsed: ParsedArgs): Promise<void> {
|
|
133
|
+
const cfg = parsed.config;
|
|
134
|
+
const logger = { logger: console };
|
|
135
|
+
|
|
136
|
+
switch (parsed.command) {
|
|
137
|
+
case 'setup': {
|
|
138
|
+
const authWaitMode = parsed.blocking ? 'blocking' : getSetupAuthWaitMode('nonblocking');
|
|
139
|
+
await runSetup(cfg, logger, { authWaitMode });
|
|
140
|
+
return;
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
case 'setup-blocking': {
|
|
144
|
+
await runSetup(cfg, logger, { authWaitMode: 'blocking' });
|
|
145
|
+
return;
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
case 'auth-status': {
|
|
149
|
+
printAuthStatus(getSkillDir(cfg), getAppBaseUrl(cfg), logger);
|
|
150
|
+
return;
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
case 'sandbox-setup': {
|
|
154
|
+
const changed = configureSandbox(logger);
|
|
155
|
+
if (changed) {
|
|
156
|
+
recreateSandboxAndRestart(logger);
|
|
157
|
+
} else {
|
|
158
|
+
console.log('[moltbank] No sandbox docker changes — not scheduling teardown');
|
|
159
|
+
}
|
|
160
|
+
return;
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
case 'inject-key': {
|
|
164
|
+
const changed = injectSandboxEnv(getSkillDir(cfg), logger);
|
|
165
|
+
if (changed) {
|
|
166
|
+
recreateSandboxAndRestart(logger);
|
|
167
|
+
} else {
|
|
168
|
+
console.log('[moltbank] No env changes — not scheduling teardown');
|
|
169
|
+
}
|
|
170
|
+
return;
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
case 'register': {
|
|
174
|
+
ensureMcporterConfig(getSkillDir(cfg), getAppBaseUrl(cfg), logger);
|
|
175
|
+
return;
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
default:
|
|
179
|
+
throw new Error(`unknown command: ${parsed.command}`);
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
async function main(): Promise<void> {
|
|
184
|
+
const parsed = parseArgs(process.argv.slice(2));
|
|
185
|
+
|
|
186
|
+
if (parsed.version) {
|
|
187
|
+
console.log(readVersion());
|
|
188
|
+
return;
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
if (parsed.help || !parsed.command) {
|
|
192
|
+
console.log(HELP_TEXT);
|
|
193
|
+
return;
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
await runCommand(parsed);
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
main().catch((error: unknown) => {
|
|
200
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
201
|
+
console.error(`[moltbank] ${message}`);
|
|
202
|
+
process.exit(1);
|
|
203
|
+
});
|
package/index.ts
CHANGED
|
@@ -7,7 +7,7 @@ const IS_WIN = process.platform === 'win32';
|
|
|
7
7
|
type OpenclawConfig = Record<string, unknown>;
|
|
8
8
|
type ParsedJsonObject = Record<string, unknown>;
|
|
9
9
|
|
|
10
|
-
interface MoltbankPluginConfig {
|
|
10
|
+
export interface MoltbankPluginConfig {
|
|
11
11
|
skillName?: string;
|
|
12
12
|
appBaseUrl?: string;
|
|
13
13
|
}
|
|
@@ -62,7 +62,7 @@ interface PluginApi extends LoggerApi {
|
|
|
62
62
|
registerCli(handler: (args: { program: CliCommandLike }) => void, options: { commands: string[] }): void;
|
|
63
63
|
}
|
|
64
64
|
|
|
65
|
-
type AuthWaitMode = 'blocking' | 'nonblocking';
|
|
65
|
+
export type AuthWaitMode = 'blocking' | 'nonblocking';
|
|
66
66
|
const oauthPollers = new Map<string, ReturnType<typeof spawn>>();
|
|
67
67
|
const backgroundFinalizers = new Map<string, ReturnType<typeof spawn>>();
|
|
68
68
|
|
|
@@ -86,7 +86,7 @@ function asStringRecord(value: unknown): Record<string, string> {
|
|
|
86
86
|
return out;
|
|
87
87
|
}
|
|
88
88
|
|
|
89
|
-
function getSetupAuthWaitMode(defaultMode: AuthWaitMode): AuthWaitMode {
|
|
89
|
+
export function getSetupAuthWaitMode(defaultMode: AuthWaitMode): AuthWaitMode {
|
|
90
90
|
const raw = asString(process.env.MOLTBANK_SETUP_AUTH_WAIT_MODE).trim().toLowerCase();
|
|
91
91
|
if (raw === 'blocking' || raw === 'wait') return 'blocking';
|
|
92
92
|
if (raw === 'nonblocking' || raw === 'nowait') return 'nonblocking';
|
|
@@ -133,14 +133,19 @@ function getWorkspace(): string {
|
|
|
133
133
|
return process.env.OPENCLAW_WORKSPACE || join(homedir(), '.openclaw', 'workspace');
|
|
134
134
|
}
|
|
135
135
|
|
|
136
|
-
function getSkillName(cfg: MoltbankPluginConfig): string {
|
|
136
|
+
export function getSkillName(cfg: MoltbankPluginConfig): string {
|
|
137
137
|
return cfg?.skillName || process.env.MOLTBANK_SKILL_NAME || 'MoltBank';
|
|
138
138
|
}
|
|
139
139
|
|
|
140
|
-
function getAppBaseUrl(cfg: MoltbankPluginConfig): string {
|
|
140
|
+
export 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
|
+
export 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');
|
|
@@ -152,7 +157,7 @@ function isSandboxEnabled(): boolean {
|
|
|
152
157
|
}
|
|
153
158
|
}
|
|
154
159
|
|
|
155
|
-
function getSkillDir(cfg: MoltbankPluginConfig): string {
|
|
160
|
+
export function getSkillDir(cfg: MoltbankPluginConfig): string {
|
|
156
161
|
const skillName = getSkillName(cfg);
|
|
157
162
|
return join(getWorkspace(), 'skills', skillName);
|
|
158
163
|
}
|
|
@@ -850,7 +855,7 @@ function ensureMoltbankAuth(skillDir: string, appBaseUrl: string, api: LoggerApi
|
|
|
850
855
|
return true;
|
|
851
856
|
}
|
|
852
857
|
|
|
853
|
-
function printAuthStatus(skillDir: string, appBaseUrl: string, api: LoggerApi): void {
|
|
858
|
+
export function printAuthStatus(skillDir: string, appBaseUrl: string, api: LoggerApi): void {
|
|
854
859
|
const now = Math.floor(Date.now() / 1000);
|
|
855
860
|
const existing = parseActiveTokenFromCredentials();
|
|
856
861
|
const pending = readPendingOauthCode(skillDir);
|
|
@@ -878,11 +883,11 @@ function printAuthStatus(skillDir: string, appBaseUrl: string, api: LoggerApi):
|
|
|
878
883
|
api.logger.info(`[moltbank] background poll: ${pollerRunning ? 'running' : 'idle'}`);
|
|
879
884
|
api.logger.info(`[moltbank] background finalize: ${finalizerRunning ? 'running' : 'idle'}`);
|
|
880
885
|
if (!existing.ok && !pending) {
|
|
881
|
-
api.logger.info('[moltbank] hint: run `
|
|
886
|
+
api.logger.info('[moltbank] hint: run `moltbank setup` to start onboarding');
|
|
882
887
|
}
|
|
883
888
|
}
|
|
884
889
|
|
|
885
|
-
function ensureMcporterConfig(skillDir: string, appBaseUrl: string, api: LoggerApi) {
|
|
890
|
+
export function ensureMcporterConfig(skillDir: string, appBaseUrl: string, api: LoggerApi) {
|
|
886
891
|
const cfgPath = join(skillDir, 'assets', 'mcporter.json');
|
|
887
892
|
mkdirSync(join(skillDir, 'assets'), { recursive: true });
|
|
888
893
|
|
|
@@ -937,7 +942,7 @@ function ensureMcporterConfig(skillDir: string, appBaseUrl: string, api: LoggerA
|
|
|
937
942
|
|
|
938
943
|
// ─── sandbox env vars ────────────────────────────────────────────────────────
|
|
939
944
|
|
|
940
|
-
function injectSandboxEnv(skillDir: string, api: LoggerApi): boolean {
|
|
945
|
+
export function injectSandboxEnv(skillDir: string, api: LoggerApi): boolean {
|
|
941
946
|
const credsPath = getCredentialsPath();
|
|
942
947
|
|
|
943
948
|
if (!existsSync(credsPath)) {
|
|
@@ -1035,7 +1040,7 @@ function injectSandboxEnv(skillDir: string, api: LoggerApi): boolean {
|
|
|
1035
1040
|
|
|
1036
1041
|
// ─── sandbox docker config ────────────────────────────────────────────────────
|
|
1037
1042
|
|
|
1038
|
-
function configureSandbox(api: LoggerApi): boolean {
|
|
1043
|
+
export function configureSandbox(api: LoggerApi): boolean {
|
|
1039
1044
|
const SETUP_CMD =
|
|
1040
1045
|
'echo \'APT::Sandbox::User "root";\' > /etc/apt/apt.conf.d/99sandbox && ' +
|
|
1041
1046
|
'apt-get update -qq && ' +
|
|
@@ -1107,7 +1112,7 @@ function configureSandbox(api: LoggerApi): boolean {
|
|
|
1107
1112
|
|
|
1108
1113
|
// ─── sandbox recreate + gateway restart ──────────────────────────────────────
|
|
1109
1114
|
|
|
1110
|
-
function recreateSandboxAndRestart(api: LoggerApi) {
|
|
1115
|
+
export function recreateSandboxAndRestart(api: LoggerApi) {
|
|
1111
1116
|
api.logger.info('[moltbank] recreating sandbox containers...');
|
|
1112
1117
|
api.logger.info('[moltbank] ⏳ waiting 8s before recreate (hot container protection)...');
|
|
1113
1118
|
setTimeout(() => {
|
|
@@ -1142,16 +1147,21 @@ function recreateSandboxAndRestart(api: LoggerApi) {
|
|
|
1142
1147
|
|
|
1143
1148
|
// ─── main setup ───────────────────────────────────────────────────────────────
|
|
1144
1149
|
|
|
1145
|
-
async function runSetup(
|
|
1150
|
+
export async function runSetup(
|
|
1151
|
+
cfg: MoltbankPluginConfig,
|
|
1152
|
+
api: LoggerApi,
|
|
1153
|
+
options: { authWaitMode?: AuthWaitMode } = {}
|
|
1154
|
+
) {
|
|
1146
1155
|
let hostReady = false;
|
|
1147
1156
|
const appBaseUrl = getAppBaseUrl(cfg);
|
|
1157
|
+
const skillBundleBaseUrl = getSkillBundleBaseUrl(cfg);
|
|
1148
1158
|
const skillName = getSkillName(cfg);
|
|
1149
1159
|
const sandbox = isSandboxEnabled();
|
|
1150
1160
|
const skillDir = getSkillDir(cfg);
|
|
1151
1161
|
const waitForAuth = (options.authWaitMode ?? 'blocking') === 'blocking';
|
|
1152
1162
|
|
|
1153
1163
|
api.logger.info(`[moltbank] ══════════════════════════════════════`);
|
|
1154
|
-
api.logger.info(`[moltbank] MoltBank
|
|
1164
|
+
api.logger.info(`[moltbank] MoltBank setup starting`);
|
|
1155
1165
|
api.logger.info(`[moltbank] mode: ${sandbox ? 'sandbox (Docker)' : 'host (direct)'}`);
|
|
1156
1166
|
api.logger.info(`[moltbank] skill dir: ${skillDir}`);
|
|
1157
1167
|
api.logger.info(`[moltbank] base url: ${appBaseUrl}`);
|
|
@@ -1166,7 +1176,7 @@ async function runSetup(cfg: MoltbankPluginConfig, api: LoggerApi, options: { au
|
|
|
1166
1176
|
ensureMcporter(api);
|
|
1167
1177
|
|
|
1168
1178
|
api.logger.info('[moltbank] [sandbox 1/10] installing skill files...');
|
|
1169
|
-
const skillInstalled = ensureSkillInstalled(skillDir,
|
|
1179
|
+
const skillInstalled = ensureSkillInstalled(skillDir, skillBundleBaseUrl, skillName, api, 'sandbox');
|
|
1170
1180
|
if (!skillInstalled) {
|
|
1171
1181
|
api.logger.warn('[moltbank] skill install failed — aborting sandbox setup');
|
|
1172
1182
|
return;
|
|
@@ -1223,7 +1233,7 @@ async function runSetup(cfg: MoltbankPluginConfig, api: LoggerApi, options: { au
|
|
|
1223
1233
|
ensureMcporter(api);
|
|
1224
1234
|
|
|
1225
1235
|
api.logger.info('[moltbank] [host 2/8] installing skill files...');
|
|
1226
|
-
const installed = ensureSkillInstalled(skillDir,
|
|
1236
|
+
const installed = ensureSkillInstalled(skillDir, skillBundleBaseUrl, skillName, api, 'host');
|
|
1227
1237
|
if (!installed) {
|
|
1228
1238
|
api.logger.warn('[moltbank] host setup aborted: skill install failed. Verify install.sh/base URL and retry.');
|
|
1229
1239
|
return;
|
package/package.json
CHANGED
|
@@ -1,8 +1,11 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@moltbankhq/openclaw",
|
|
3
|
-
"version": "0.1.
|
|
4
|
-
"description": "MoltBank stablecoin treasury OpenClaw plugin",
|
|
3
|
+
"version": "0.1.4",
|
|
4
|
+
"description": "MoltBank stablecoin treasury CLI and OpenClaw plugin",
|
|
5
5
|
"main": "index.ts",
|
|
6
|
+
"bin": {
|
|
7
|
+
"moltbank": "./bin/moltbank.mjs"
|
|
8
|
+
},
|
|
6
9
|
"openclaw": {
|
|
7
10
|
"extensions": [
|
|
8
11
|
"./index.ts"
|
|
@@ -12,6 +15,9 @@
|
|
|
12
15
|
"author": "",
|
|
13
16
|
"license": "ISC",
|
|
14
17
|
"type": "module",
|
|
18
|
+
"dependencies": {
|
|
19
|
+
"tsx": "^4.20.6"
|
|
20
|
+
},
|
|
15
21
|
"devDependencies": {
|
|
16
22
|
"@types/node": "^25.5.0"
|
|
17
23
|
}
|