@moltbankhq/openclaw 0.1.12 → 0.1.14
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 +2 -2
- package/index.ts +137 -113
- package/package.json +37 -2
package/README.md
CHANGED
|
@@ -32,11 +32,11 @@ openclaw plugins install @moltbankhq/openclaw
|
|
|
32
32
|
|
|
33
33
|
This package connects your OpenClaw agent to MoltBank's stablecoin treasury infrastructure. During setup, it:
|
|
34
34
|
|
|
35
|
-
- Downloads and configures the MoltBank skill (`
|
|
35
|
+
- Downloads and configures the MoltBank skill (`SKILL.md` + scripts)
|
|
36
36
|
- Installs and registers [mcporter](https://www.npmjs.com/package/mcporter) for MCP server connectivity
|
|
37
37
|
- Handles OAuth device-code authentication to link your agent to your MoltBank account
|
|
38
38
|
- Configures sandbox (Docker) or host mode automatically based on your OpenClaw setup
|
|
39
|
-
- Injects
|
|
39
|
+
- Injects the sandbox auth path (`MOLTBANK_CREDENTIALS_PATH`) plus `ACTIVE_ORG_OVERRIDE`, while keeping tokens and signer keys in a skill-local credentials file
|
|
40
40
|
|
|
41
41
|
Once set up, your agent can manage treasury operations, set per-agent spending limits, handle x402 payments, and interact with MoltBank's MCP server — all within OpenClaw.
|
|
42
42
|
|
package/index.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { spawn, spawnSync } from 'child_process';
|
|
2
2
|
import { chmodSync, chownSync, existsSync, mkdirSync, readdirSync, readFileSync, unlinkSync, writeFileSync, type Dirent } from 'fs';
|
|
3
|
-
import { join, dirname } from 'path';
|
|
3
|
+
import { join, dirname, basename } from 'path';
|
|
4
4
|
import { homedir, userInfo } from 'os';
|
|
5
5
|
const IS_WIN = process.platform === 'win32';
|
|
6
6
|
|
|
@@ -16,6 +16,7 @@ interface CredentialsOrganization {
|
|
|
16
16
|
name?: string;
|
|
17
17
|
access_token?: string;
|
|
18
18
|
x402_signer_private_key?: string;
|
|
19
|
+
x402_wallet?: Record<string, unknown>;
|
|
19
20
|
}
|
|
20
21
|
|
|
21
22
|
interface CredentialsFile {
|
|
@@ -952,6 +953,77 @@ function getCredentialsPath(): string {
|
|
|
952
953
|
return process.env.MOLTBANK_CREDENTIALS_PATH || join(homedir(), '.MoltBank', 'credentials.json');
|
|
953
954
|
}
|
|
954
955
|
|
|
956
|
+
function getSandboxCredentialsHostPath(skillDir: string): string {
|
|
957
|
+
return join(skillDir, '.sandbox', 'credentials.json');
|
|
958
|
+
}
|
|
959
|
+
|
|
960
|
+
function getSandboxCredentialsContainerPath(skillName: string): string {
|
|
961
|
+
return `/workspace/skills/${skillName}/.sandbox/credentials.json`;
|
|
962
|
+
}
|
|
963
|
+
|
|
964
|
+
function writeSandboxCredentialsFile(
|
|
965
|
+
skillDir: string,
|
|
966
|
+
activeOrg: string,
|
|
967
|
+
org: CredentialsOrganization,
|
|
968
|
+
privateKey: string,
|
|
969
|
+
api: LoggerApi
|
|
970
|
+
): boolean {
|
|
971
|
+
const sandboxDir = dirname(getSandboxCredentialsHostPath(skillDir));
|
|
972
|
+
const sandboxCredentialsPath = getSandboxCredentialsHostPath(skillDir);
|
|
973
|
+
const sandboxOrg: Record<string, unknown> = {
|
|
974
|
+
name: activeOrg,
|
|
975
|
+
access_token: org.access_token ?? ''
|
|
976
|
+
};
|
|
977
|
+
|
|
978
|
+
if (privateKey) {
|
|
979
|
+
sandboxOrg.x402_signer_private_key = privateKey;
|
|
980
|
+
}
|
|
981
|
+
if (isRecord(org.x402_wallet)) {
|
|
982
|
+
sandboxOrg.x402_wallet = org.x402_wallet;
|
|
983
|
+
}
|
|
984
|
+
|
|
985
|
+
const sandboxCredentials = {
|
|
986
|
+
active_organization: activeOrg,
|
|
987
|
+
organizations: [sandboxOrg]
|
|
988
|
+
};
|
|
989
|
+
|
|
990
|
+
try {
|
|
991
|
+
mkdirSync(sandboxDir, { recursive: true });
|
|
992
|
+
writeFileSync(sandboxCredentialsPath, JSON.stringify(sandboxCredentials, null, 2) + '\n', 'utf8');
|
|
993
|
+
|
|
994
|
+
if (!IS_WIN) {
|
|
995
|
+
try {
|
|
996
|
+
chmodSync(sandboxDir, 0o700);
|
|
997
|
+
} catch {
|
|
998
|
+
// ignore
|
|
999
|
+
}
|
|
1000
|
+
try {
|
|
1001
|
+
chmodSync(sandboxCredentialsPath, 0o600);
|
|
1002
|
+
} catch {
|
|
1003
|
+
// ignore
|
|
1004
|
+
}
|
|
1005
|
+
}
|
|
1006
|
+
|
|
1007
|
+
api.logger.info('[moltbank] ✓ sandbox credentials file updated');
|
|
1008
|
+
return true;
|
|
1009
|
+
} catch (e) {
|
|
1010
|
+
api.logger.warn('[moltbank] ✗ could not write sandbox credentials file: ' + String(e));
|
|
1011
|
+
return false;
|
|
1012
|
+
}
|
|
1013
|
+
}
|
|
1014
|
+
|
|
1015
|
+
function removeSandboxSecretEnvKeys(envObj: Record<string, string>, api: LoggerApi): boolean {
|
|
1016
|
+
let changed = false;
|
|
1017
|
+
for (const key of ['MOLTBANK', 'SIGNER']) {
|
|
1018
|
+
if (key in envObj) {
|
|
1019
|
+
delete envObj[key];
|
|
1020
|
+
changed = true;
|
|
1021
|
+
api.logger.info(`[moltbank] ✓ removed legacy sandbox secret env key ${key}`);
|
|
1022
|
+
}
|
|
1023
|
+
}
|
|
1024
|
+
return changed;
|
|
1025
|
+
}
|
|
1026
|
+
|
|
955
1027
|
function readOpenclawConfig(): OpenclawConfig {
|
|
956
1028
|
const configPath = join(homedir(), '.openclaw', 'openclaw.json');
|
|
957
1029
|
try {
|
|
@@ -1902,10 +1974,47 @@ export function ensureMcporterConfig(skillDir: string, appBaseUrl: string, api:
|
|
|
1902
1974
|
api.logger.info('[moltbank] ✓ MoltBank will use skill-local mcporter config only');
|
|
1903
1975
|
}
|
|
1904
1976
|
|
|
1977
|
+
function runHostReadinessCheck(skillDir: string, api: LoggerApi): boolean {
|
|
1978
|
+
const active = parseActiveTokenFromCredentials();
|
|
1979
|
+
if (!active.ok || !active.activeOrg) {
|
|
1980
|
+
api.logger.warn('[moltbank] host setup incomplete: active organization could not be resolved for readiness verification');
|
|
1981
|
+
return false;
|
|
1982
|
+
}
|
|
1983
|
+
|
|
1984
|
+
const wrapperPath = IS_WIN ? join(skillDir, 'scripts', 'moltbank.ps1') : join(skillDir, 'scripts', 'moltbank.sh');
|
|
1985
|
+
const readinessArgs = ['call', 'MoltBank.get_balance', `organizationName=${active.activeOrg}`, 'date=today'];
|
|
1986
|
+
const readinessTimeoutMs = IS_WIN ? 30000 : 25000;
|
|
1987
|
+
|
|
1988
|
+
api.logger.info(`[moltbank] verifying readiness with authenticated balance read (org: ${active.activeOrg})...`);
|
|
1989
|
+
|
|
1990
|
+
const readiness = runCommand(wrapperPath, readinessArgs, {
|
|
1991
|
+
cwd: skillDir,
|
|
1992
|
+
silent: true,
|
|
1993
|
+
timeoutMs: readinessTimeoutMs,
|
|
1994
|
+
env: {
|
|
1995
|
+
ACTIVE_ORG_OVERRIDE: active.activeOrg
|
|
1996
|
+
}
|
|
1997
|
+
});
|
|
1998
|
+
|
|
1999
|
+
if (!readiness.ok) {
|
|
2000
|
+
const combined = `${readiness.stderr}\n${readiness.stdout}`.trim();
|
|
2001
|
+
const detail = lastNonEmptyLine(combined);
|
|
2002
|
+
if (detail) {
|
|
2003
|
+
api.logger.warn(`[moltbank] readiness detail: ${detail}`);
|
|
2004
|
+
}
|
|
2005
|
+
api.logger.warn('[moltbank] host setup incomplete: authenticated balance-read verification failed');
|
|
2006
|
+
return false;
|
|
2007
|
+
}
|
|
2008
|
+
|
|
2009
|
+
api.logger.info('[moltbank] host readiness verified (`MoltBank.get_balance`)');
|
|
2010
|
+
return true;
|
|
2011
|
+
}
|
|
2012
|
+
|
|
1905
2013
|
// ─── sandbox env vars ────────────────────────────────────────────────────────
|
|
1906
2014
|
|
|
1907
2015
|
export function injectSandboxEnv(skillDir: string, api: LoggerApi): boolean {
|
|
1908
2016
|
const credsPath = getCredentialsPath();
|
|
2017
|
+
const skillName = basename(skillDir);
|
|
1909
2018
|
|
|
1910
2019
|
if (!existsSync(credsPath)) {
|
|
1911
2020
|
api.logger.info('[moltbank] no credentials.json found — skipping sandbox env injection');
|
|
@@ -1933,14 +2042,7 @@ export function injectSandboxEnv(skillDir: string, api: LoggerApi): boolean {
|
|
|
1933
2042
|
const envPath = ['agents', 'defaults', 'sandbox', 'docker', 'env'];
|
|
1934
2043
|
setNestedValue(config, envPath, getNestedValue(config, envPath) ?? {});
|
|
1935
2044
|
const envObj = getNestedValue(config, envPath) as Record<string, string>;
|
|
1936
|
-
|
|
1937
|
-
if (envObj.MOLTBANK !== org.access_token) {
|
|
1938
|
-
envObj.MOLTBANK = org.access_token;
|
|
1939
|
-
api.logger.info(`[moltbank] ✓ MOLTBANK injected (org: ${activeOrg})`);
|
|
1940
|
-
changed = true;
|
|
1941
|
-
} else {
|
|
1942
|
-
api.logger.info(`[moltbank] ✓ MOLTBANK already injected (org: ${activeOrg})`);
|
|
1943
|
-
}
|
|
2045
|
+
changed = removeSandboxSecretEnvKeys(envObj, api) || changed;
|
|
1944
2046
|
|
|
1945
2047
|
if (envObj.ACTIVE_ORG_OVERRIDE !== activeOrg) {
|
|
1946
2048
|
envObj.ACTIVE_ORG_OVERRIDE = activeOrg;
|
|
@@ -1976,21 +2078,28 @@ export function injectSandboxEnv(skillDir: string, api: LoggerApi): boolean {
|
|
|
1976
2078
|
}
|
|
1977
2079
|
}
|
|
1978
2080
|
|
|
2081
|
+
if (!writeSandboxCredentialsFile(skillDir, activeOrg, org, privateKey, api)) {
|
|
2082
|
+
return false;
|
|
2083
|
+
}
|
|
2084
|
+
|
|
2085
|
+
const sandboxCredentialsContainerPath = getSandboxCredentialsContainerPath(skillName);
|
|
2086
|
+
if (envObj.MOLTBANK_CREDENTIALS_PATH !== sandboxCredentialsContainerPath) {
|
|
2087
|
+
envObj.MOLTBANK_CREDENTIALS_PATH = sandboxCredentialsContainerPath;
|
|
2088
|
+
api.logger.info(`[moltbank] ✓ MOLTBANK_CREDENTIALS_PATH injected (${sandboxCredentialsContainerPath})`);
|
|
2089
|
+
changed = true;
|
|
2090
|
+
} else {
|
|
2091
|
+
api.logger.info(`[moltbank] ✓ MOLTBANK_CREDENTIALS_PATH already set (${sandboxCredentialsContainerPath})`);
|
|
2092
|
+
}
|
|
2093
|
+
|
|
1979
2094
|
if (privateKey) {
|
|
1980
|
-
|
|
1981
|
-
envObj.SIGNER = privateKey;
|
|
1982
|
-
api.logger.info('[moltbank] ✓ SIGNER injected');
|
|
1983
|
-
changed = true;
|
|
1984
|
-
} else {
|
|
1985
|
-
api.logger.info('[moltbank] ✓ SIGNER already injected');
|
|
1986
|
-
}
|
|
2095
|
+
api.logger.info('[moltbank] ✓ sandbox x402 signer available via sandbox credentials file');
|
|
1987
2096
|
} else {
|
|
1988
|
-
api.logger.info('[moltbank] ℹ
|
|
2097
|
+
api.logger.info('[moltbank] ℹ sandbox x402 signer not available yet — helper scripts will use sandbox credentials path if generated later');
|
|
1989
2098
|
}
|
|
1990
2099
|
|
|
1991
2100
|
if (changed) {
|
|
1992
2101
|
writeOpenclawConfig(config);
|
|
1993
|
-
api.logger.info('[moltbank] ✓ openclaw.json updated with sandbox
|
|
2102
|
+
api.logger.info('[moltbank] ✓ openclaw.json updated with sandbox auth path only (no token/private key persisted)');
|
|
1994
2103
|
}
|
|
1995
2104
|
|
|
1996
2105
|
return changed;
|
|
@@ -2212,7 +2321,7 @@ export async function runSetup(
|
|
|
2212
2321
|
api.logger.info('[moltbank] [sandbox 8/10] configuring sandbox docker settings...');
|
|
2213
2322
|
const sandboxChanged = configureSandbox(api);
|
|
2214
2323
|
|
|
2215
|
-
api.logger.info('[moltbank] [sandbox 9/10] injecting sandbox env
|
|
2324
|
+
api.logger.info('[moltbank] [sandbox 9/10] injecting sandbox auth env (MOLTBANK_CREDENTIALS_PATH, ACTIVE_ORG_OVERRIDE)...');
|
|
2216
2325
|
const envChanged = injectSandboxEnv(skillDir, api);
|
|
2217
2326
|
|
|
2218
2327
|
api.logger.info('[moltbank] [sandbox 10/10] apply sandbox changes (recreate + gateway stop)...');
|
|
@@ -2265,98 +2374,8 @@ export async function runSetup(
|
|
|
2265
2374
|
api.logger.info('[moltbank] [host 7/8] writing/registering mcporter config...');
|
|
2266
2375
|
ensureMcporterConfig(skillDir, appBaseUrl, api);
|
|
2267
2376
|
|
|
2268
|
-
api.logger.info('[moltbank] [host 8/8] running
|
|
2269
|
-
|
|
2270
|
-
let smokeOk = false;
|
|
2271
|
-
|
|
2272
|
-
if (IS_WIN) {
|
|
2273
|
-
const mcporterConfigPath = join(skillDir, 'assets', 'mcporter.json');
|
|
2274
|
-
const active = parseActiveTokenFromCredentials();
|
|
2275
|
-
const mcpSmoke = runCommand('mcporter', ['--config', mcporterConfigPath, 'list', 'MoltBank'], {
|
|
2276
|
-
cwd: skillDir,
|
|
2277
|
-
silent: true,
|
|
2278
|
-
timeoutMs: smokeTimeoutMs,
|
|
2279
|
-
env: {
|
|
2280
|
-
MOLTBANK: active.token ?? '__MOLTBANK_PLACEHOLDER__'
|
|
2281
|
-
}
|
|
2282
|
-
});
|
|
2283
|
-
|
|
2284
|
-
if (mcpSmoke.ok) {
|
|
2285
|
-
api.logger.info('[moltbank] host smoke test passed (`mcporter list MoltBank`)');
|
|
2286
|
-
smokeOk = true;
|
|
2287
|
-
} else {
|
|
2288
|
-
const mcpCombined = `${mcpSmoke.stderr}\n${mcpSmoke.stdout}`.trim();
|
|
2289
|
-
const mcpCombinedLower = mcpCombined.toLowerCase();
|
|
2290
|
-
const mcpDetail = lastNonEmptyLine(mcpCombined);
|
|
2291
|
-
if (mcpDetail) {
|
|
2292
|
-
api.logger.warn(`[moltbank] smoke detail: ${mcpDetail}`);
|
|
2293
|
-
}
|
|
2294
|
-
|
|
2295
|
-
const timedOut = mcpSmoke.stderr.includes('ETIMEDOUT') || mcpCombinedLower.includes('timed out');
|
|
2296
|
-
if (timedOut) {
|
|
2297
|
-
api.logger.warn(
|
|
2298
|
-
`[moltbank] host MCP smoke timed out after ${Math.floor(smokeTimeoutMs / 1000)}s; running local fallback checks`
|
|
2299
|
-
);
|
|
2300
|
-
|
|
2301
|
-
const ps1Path = join(skillDir, 'scripts', 'moltbank.ps1');
|
|
2302
|
-
const fallback = runCommand(
|
|
2303
|
-
'powershell',
|
|
2304
|
-
[
|
|
2305
|
-
'-NoProfile',
|
|
2306
|
-
'-NonInteractive',
|
|
2307
|
-
'-ExecutionPolicy',
|
|
2308
|
-
'Bypass',
|
|
2309
|
-
'-Command',
|
|
2310
|
-
"$ErrorActionPreference = 'Stop'; if (-not (Test-Path -LiteralPath $env:MOLTBANK_WRAPPER_PATH)) { throw 'moltbank.ps1 not found' }; if (-not (Get-Command bash -ErrorAction SilentlyContinue)) { throw 'bash is not installed or not on PATH' }; if (-not (Get-Command mcporter -ErrorAction SilentlyContinue)) { throw 'mcporter is not installed or not on PATH' }; Write-Output 'ok'"
|
|
2311
|
-
],
|
|
2312
|
-
{
|
|
2313
|
-
cwd: skillDir,
|
|
2314
|
-
silent: true,
|
|
2315
|
-
timeoutMs: 10000,
|
|
2316
|
-
env: { MOLTBANK_WRAPPER_PATH: ps1Path }
|
|
2317
|
-
}
|
|
2318
|
-
);
|
|
2319
|
-
|
|
2320
|
-
if (fallback.ok) {
|
|
2321
|
-
api.logger.warn('[moltbank] host smoke fallback passed (wrapper prerequisites available), but MCP endpoint was not verified');
|
|
2322
|
-
smokeOk = true;
|
|
2323
|
-
} else {
|
|
2324
|
-
const fallbackCombined = `${fallback.stderr}\n${fallback.stdout}`.trim();
|
|
2325
|
-
const fallbackDetail = lastNonEmptyLine(fallbackCombined);
|
|
2326
|
-
if (fallbackDetail) {
|
|
2327
|
-
api.logger.warn(`[moltbank] fallback detail: ${fallbackDetail}`);
|
|
2328
|
-
}
|
|
2329
|
-
api.logger.warn('[moltbank] host setup incomplete: MCP smoke timed out and fallback checks failed');
|
|
2330
|
-
}
|
|
2331
|
-
} else if (
|
|
2332
|
-
mcpCombinedLower.includes('mcporter') &&
|
|
2333
|
-
(mcpCombinedLower.includes('not recognized') || mcpCombinedLower.includes('not found'))
|
|
2334
|
-
) {
|
|
2335
|
-
api.logger.warn('[moltbank] mcporter binary not found in PATH during smoke test');
|
|
2336
|
-
} else {
|
|
2337
|
-
api.logger.warn('[moltbank] host setup incomplete: smoke test failed (`mcporter list MoltBank`)');
|
|
2338
|
-
}
|
|
2339
|
-
}
|
|
2340
|
-
} else {
|
|
2341
|
-
const smoke = runCommand(join(skillDir, 'scripts', 'moltbank.sh'), ['list', 'MoltBank'], {
|
|
2342
|
-
cwd: skillDir,
|
|
2343
|
-
silent: true,
|
|
2344
|
-
timeoutMs: smokeTimeoutMs
|
|
2345
|
-
});
|
|
2346
|
-
if (!smoke.ok) {
|
|
2347
|
-
const smokeCombined = `${smoke.stderr}\n${smoke.stdout}`.trim();
|
|
2348
|
-
const smokeDetail = lastNonEmptyLine(smokeCombined);
|
|
2349
|
-
if (smokeDetail) {
|
|
2350
|
-
api.logger.warn(`[moltbank] smoke detail: ${smokeDetail}`);
|
|
2351
|
-
}
|
|
2352
|
-
api.logger.warn('[moltbank] host setup incomplete: smoke test failed (`moltbank list MoltBank` via platform script)');
|
|
2353
|
-
} else {
|
|
2354
|
-
api.logger.info('[moltbank] host smoke test passed (`moltbank list MoltBank`)');
|
|
2355
|
-
smokeOk = true;
|
|
2356
|
-
}
|
|
2357
|
-
}
|
|
2358
|
-
|
|
2359
|
-
hostReady = smokeOk;
|
|
2377
|
+
api.logger.info('[moltbank] [host 8/8] running readiness balance check...');
|
|
2378
|
+
hostReady = runHostReadinessCheck(skillDir, api);
|
|
2360
2379
|
|
|
2361
2380
|
api.logger.info('[moltbank] host mode — setup completed with onboarding flow');
|
|
2362
2381
|
|
|
@@ -2379,13 +2398,18 @@ export async function runSetup(
|
|
|
2379
2398
|
const finalEnv = asStringRecord(getNestedValue(finalConfig, ['agents', 'defaults', 'sandbox', 'docker', 'env']));
|
|
2380
2399
|
const finalNetwork = asString(getNestedValue(finalConfig, ['agents', 'defaults', 'sandbox', 'docker', 'network']));
|
|
2381
2400
|
const finalCmd = asString(getNestedValue(finalConfig, ['agents', 'defaults', 'sandbox', 'docker', 'setupCommand']));
|
|
2401
|
+
const sandboxCredentialsPath = getSandboxCredentialsHostPath(skillDir);
|
|
2382
2402
|
|
|
2383
2403
|
api.logger.info(`[moltbank] openclaw.json sandbox env:`);
|
|
2384
|
-
api.logger.info(
|
|
2404
|
+
api.logger.info(
|
|
2405
|
+
`[moltbank] MOLTBANK_CREDENTIALS_PATH: ${finalEnv.MOLTBANK_CREDENTIALS_PATH ? `✓ ${finalEnv.MOLTBANK_CREDENTIALS_PATH}` : '✗ missing'}`
|
|
2406
|
+
);
|
|
2385
2407
|
api.logger.info(
|
|
2386
2408
|
`[moltbank] ACTIVE_ORG_OVERRIDE: ${finalEnv.ACTIVE_ORG_OVERRIDE ? `✓ "${finalEnv.ACTIVE_ORG_OVERRIDE}"` : '✗ missing'}`
|
|
2387
2409
|
);
|
|
2388
|
-
api.logger.info(
|
|
2410
|
+
api.logger.info(
|
|
2411
|
+
`[moltbank] sandbox credentials: ${existsSync(sandboxCredentialsPath) ? '✓ present (skill-local, 600)' : '✗ missing'}`
|
|
2412
|
+
);
|
|
2389
2413
|
api.logger.info(`[moltbank] sandbox docker:`);
|
|
2390
2414
|
api.logger.info(
|
|
2391
2415
|
`[moltbank] network: ${finalNetwork === 'bridge' ? '✓ bridge' : `✗ "${finalNetwork}" (expected bridge)`}`
|
package/package.json
CHANGED
|
@@ -1,20 +1,55 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@moltbankhq/openclaw",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.14",
|
|
4
4
|
"description": "MoltBank stablecoin treasury CLI and OpenClaw plugin",
|
|
5
|
+
"homepage": "https://github.com/moltbankhq/openclaw-plugin#readme",
|
|
6
|
+
"repository": {
|
|
7
|
+
"type": "git",
|
|
8
|
+
"url": "https://github.com/moltbankhq/openclaw-plugin.git"
|
|
9
|
+
},
|
|
10
|
+
"bugs": {
|
|
11
|
+
"url": "https://github.com/moltbankhq/openclaw-plugin/issues"
|
|
12
|
+
},
|
|
5
13
|
"main": "index.ts",
|
|
14
|
+
"types": "index.ts",
|
|
15
|
+
"exports": {
|
|
16
|
+
".": "./index.ts",
|
|
17
|
+
"./cli": "./cli.ts",
|
|
18
|
+
"./package.json": "./package.json"
|
|
19
|
+
},
|
|
6
20
|
"bin": {
|
|
7
21
|
"moltbank": "./bin/moltbank.mjs"
|
|
8
22
|
},
|
|
23
|
+
"files": [
|
|
24
|
+
"README.md",
|
|
25
|
+
"bin/",
|
|
26
|
+
"cli.ts",
|
|
27
|
+
"index.ts",
|
|
28
|
+
"openclaw.plugin.json"
|
|
29
|
+
],
|
|
9
30
|
"openclaw": {
|
|
10
31
|
"extensions": [
|
|
11
32
|
"./index.ts"
|
|
12
33
|
]
|
|
13
34
|
},
|
|
14
|
-
"keywords": [
|
|
35
|
+
"keywords": [
|
|
36
|
+
"moltbank",
|
|
37
|
+
"openclaw",
|
|
38
|
+
"treasury",
|
|
39
|
+
"mcp",
|
|
40
|
+
"cli",
|
|
41
|
+
"stablecoin",
|
|
42
|
+
"x402"
|
|
43
|
+
],
|
|
15
44
|
"author": "",
|
|
16
45
|
"license": "ISC",
|
|
17
46
|
"type": "module",
|
|
47
|
+
"engines": {
|
|
48
|
+
"node": ">=22"
|
|
49
|
+
},
|
|
50
|
+
"publishConfig": {
|
|
51
|
+
"access": "public"
|
|
52
|
+
},
|
|
18
53
|
"dependencies": {
|
|
19
54
|
"tsx": "^4.20.6"
|
|
20
55
|
},
|