@agentlayer.tech/wallet 0.1.28 → 0.1.32
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/.openclaw/extensions/agent-wallet/README.md +5 -7
- package/.openclaw/extensions/agent-wallet/dist/index.js +35 -360
- package/.openclaw/extensions/agent-wallet/index.ts +35 -360
- package/.openclaw/extensions/agent-wallet/openclaw.plugin.json +2 -45
- package/.openclaw/extensions/agent-wallet/package.json +1 -1
- package/.openclaw/extensions/agent-wallet/skills/wallet-operator/SKILL.md +1 -3
- package/CHANGELOG.md +73 -0
- package/README.md +4 -0
- package/agent-wallet/.env.example +0 -12
- package/agent-wallet/README.md +18 -57
- package/agent-wallet/agent_wallet/bootstrap.py +28 -12
- package/agent-wallet/agent_wallet/btc_user_wallets.py +33 -7
- package/agent-wallet/agent_wallet/config.py +110 -29
- package/agent-wallet/agent_wallet/evm_user_wallets.py +4 -14
- package/agent-wallet/agent_wallet/openclaw_adapter.py +29 -687
- package/agent-wallet/agent_wallet/openclaw_cli.py +0 -7
- package/agent-wallet/agent_wallet/openclaw_runtime.py +3 -12
- package/agent-wallet/agent_wallet/providers/evm_portfolio.py +18 -42
- package/agent-wallet/agent_wallet/providers/jupiter.py +1 -307
- package/agent-wallet/agent_wallet/providers/kamino.py +21 -4
- package/agent-wallet/agent_wallet/providers/solana_rpc.py +0 -23
- package/agent-wallet/agent_wallet/providers/wdk_btc_local.py +31 -3
- package/agent-wallet/agent_wallet/providers/wdk_evm_local.py +37 -3
- package/agent-wallet/agent_wallet/providers/x402.py +4 -9
- package/agent-wallet/agent_wallet/transaction_policy.py +0 -262
- package/agent-wallet/agent_wallet/user_wallets.py +4 -3
- package/agent-wallet/agent_wallet/wallet_layer/base.py +3 -103
- package/agent-wallet/agent_wallet/wallet_layer/factory.py +8 -5
- package/agent-wallet/agent_wallet/wallet_layer/solana.py +453 -1177
- package/agent-wallet/agent_wallet/wallet_layer/wdk_btc.py +2 -8
- package/agent-wallet/agent_wallet/wallet_layer/wdk_evm.py +2 -12
- package/agent-wallet/examples/openclaw_runtime_onboarding.py +1 -1
- package/agent-wallet/examples/openclaw_user_wallet_example.py +1 -1
- package/agent-wallet/openclaw.plugin.json +1 -5
- package/agent-wallet/pyproject.toml +2 -1
- package/agent-wallet/scripts/bootstrap_openclaw_btc.py +3 -5
- package/agent-wallet/scripts/bootstrap_openclaw_evm.py +2 -12
- package/agent-wallet/scripts/build_release_bundle.py +1 -0
- package/agent-wallet/scripts/flash-sdk-bridge/bridge.mjs +1 -4
- package/agent-wallet/scripts/install_agent_wallet.py +114 -6
- package/agent-wallet/scripts/install_openclaw_local_config.py +10 -10
- package/agent-wallet/scripts/manage_openclaw_btc_wallet.py +2 -4
- package/agent-wallet/scripts/manage_openclaw_evm_wallet.py +2 -15
- package/agent-wallet/scripts/reveal_btc_seed.sh +7 -16
- package/agent-wallet/scripts/setup_btc_wallet.sh +7 -16
- package/agent-wallet/scripts/setup_evm_wallet.sh +1 -11
- package/agent-wallet/scripts/switch_openclaw_wallet_network.py +4 -1
- package/agent-wallet/skills/wallet-operator/SKILL.md +1 -6
- package/bin/openclaw-agent-wallet.mjs +356 -0
- package/claude-code/plugins/agent-wallet/.claude-plugin/plugin.json +20 -0
- package/claude-code/plugins/agent-wallet/.mcp.json +14 -0
- package/claude-code/plugins/agent-wallet/README.md +65 -0
- package/claude-code/plugins/agent-wallet/scripts/run_mcp.sh +39 -0
- package/claude-code/plugins/agent-wallet/skills/wallet-operator/SKILL.md +18 -0
- package/codex/plugins/agent-wallet/.codex-plugin/plugin.json +38 -0
- package/codex/plugins/agent-wallet/.mcp.json +15 -0
- package/codex/plugins/agent-wallet/README.md +39 -0
- package/codex/plugins/agent-wallet/scripts/run_mcp.sh +21 -0
- package/codex/plugins/agent-wallet/server.py +961 -0
- package/codex/plugins/agent-wallet/skills/wallet-operator/SKILL.md +18 -0
- package/hermes/plugins/agent_wallet/schemas.py +2 -2
- package/hermes/plugins/agent_wallet/tools.py +18 -4
- package/package.json +6 -1
- package/setup.sh +2 -0
- package/wdk-btc-wallet/src/local_vault.js +45 -68
- package/wdk-btc-wallet/src/server.js +1 -0
- package/wdk-evm-wallet/README.md +4 -3
- package/wdk-evm-wallet/src/config.js +15 -0
- package/wdk-evm-wallet/src/local_vault.js +45 -68
- package/wdk-evm-wallet/src/server.js +1 -0
- package/agent-wallet/agent_wallet/providers/houdini.py +0 -539
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: wallet-operator
|
|
3
|
-
description: Use when operating OpenClaw wallet tools: balances, transfers, swaps, LI.FI cross-chain swaps, Jupiter swaps, Velora EVM swaps, BTC transfers, staking,
|
|
3
|
+
description: Use when operating OpenClaw wallet tools: balances, transfers, swaps, LI.FI cross-chain swaps, Jupiter swaps, Velora EVM swaps, BTC transfers, staking, Kamino lending, Bags claims/launches, and wallet execution safety.
|
|
4
4
|
---
|
|
5
5
|
|
|
6
6
|
# Wallet Operator
|
|
@@ -29,7 +29,6 @@ Use this skill before calling OpenClaw wallet tools. It is the routing guide for
|
|
|
29
29
|
- EVM transfers: `transfer_evm_native`, `transfer_evm_token`.
|
|
30
30
|
- BTC transfer: `transfer_btc`.
|
|
31
31
|
- Solana staking: `stake_sol_native`, `deactivate_solana_stake`, `withdraw_solana_stake`.
|
|
32
|
-
- Jupiter Earn: `jupiter_earn_deposit`, `jupiter_earn_withdraw`.
|
|
33
32
|
- Kamino: `kamino_lend_deposit`, `kamino_lend_withdraw`, `kamino_lend_borrow`, `kamino_lend_repay`.
|
|
34
33
|
- Bags: `claim_bags_fees`, `launch_bags_token`.
|
|
35
34
|
|
|
@@ -107,16 +106,12 @@ Use this skill before calling OpenClaw wallet tools. It is the routing guide for
|
|
|
107
106
|
- `stake_sol_native`: `vote_account`, `amount` in SOL, `mode`, `purpose`.
|
|
108
107
|
- `deactivate_solana_stake`: `stake_account`, `mode`, `purpose`.
|
|
109
108
|
- `withdraw_solana_stake`: `stake_account`, `amount` in SOL, optional `recipient`, `mode`, `purpose`.
|
|
110
|
-
- Before Jupiter Earn writes, use `get_jupiter_earn_tokens`, `get_jupiter_earn_positions`, and `get_jupiter_earn_earnings`.
|
|
111
|
-
- `jupiter_earn_deposit`: `asset` mint, `amount_raw`, `mode`, `purpose`.
|
|
112
|
-
- `jupiter_earn_withdraw`: `asset` mint, `amount_raw`, `mode`, `purpose`.
|
|
113
109
|
- Before Kamino writes, use `get_kamino_lend_markets`, `get_kamino_lend_market_reserves`, `get_kamino_lend_user_obligations`, and `get_kamino_lend_user_rewards`.
|
|
114
110
|
- Kamino write params: `market`, `reserve`, `amount_ui` decimal string, `mode`, `purpose`.
|
|
115
111
|
- Bags reads: `get_bags_claimable_positions`, `get_bags_fee_analytics`.
|
|
116
112
|
- `claim_bags_fees`: `token_mint`, `mode`, `purpose`.
|
|
117
113
|
- `launch_bags_token`: `name`, `symbol`, `description`, `base_mint`, `claimers`, `basis_points`, `initial_buy_sol`, `mode`, `purpose`; optional socials/image/config type.
|
|
118
114
|
- `close_empty_token_accounts`: `limit`, `mode` (`preview` or `execute`), `purpose`.
|
|
119
|
-
- `request_devnet_airdrop`: `amount`; only outside mainnet.
|
|
120
115
|
|
|
121
116
|
## Approval Flow Template
|
|
122
117
|
|
|
@@ -22,6 +22,8 @@ function printHelp() {
|
|
|
22
22
|
Usage:
|
|
23
23
|
openclaw-agent-wallet install [options]
|
|
24
24
|
openclaw-agent-wallet hermes install [options]
|
|
25
|
+
openclaw-agent-wallet codex install [options]
|
|
26
|
+
openclaw-agent-wallet claude-code install [options]
|
|
25
27
|
openclaw-agent-wallet update [options]
|
|
26
28
|
openclaw-agent-wallet status
|
|
27
29
|
openclaw-agent-wallet rollback [--to <version>]
|
|
@@ -37,6 +39,8 @@ Common install options:
|
|
|
37
39
|
Examples:
|
|
38
40
|
npx @agentlayer.tech/wallet install --yes
|
|
39
41
|
npx @agentlayer.tech/wallet hermes install --yes
|
|
42
|
+
npx @agentlayer.tech/wallet codex install --yes
|
|
43
|
+
npx @agentlayer.tech/wallet claude-code install --yes
|
|
40
44
|
npx @agentlayer.tech/wallet install --backend none
|
|
41
45
|
npx @agentlayer.tech/wallet update --yes
|
|
42
46
|
npx @agentlayer.tech/wallet update --yes --dry-run
|
|
@@ -90,6 +94,10 @@ function resolveHermesHome(env = process.env) {
|
|
|
90
94
|
return path.resolve(expandHome(env.HERMES_HOME || "~/.hermes"));
|
|
91
95
|
}
|
|
92
96
|
|
|
97
|
+
function resolveCodexHome(env = process.env) {
|
|
98
|
+
return path.resolve(expandHome(env.CODEX_HOME || "~/.codex"));
|
|
99
|
+
}
|
|
100
|
+
|
|
93
101
|
function releaseRootFor(version, env = process.env) {
|
|
94
102
|
return path.join(resolveRuntimeBase(env), "releases", version);
|
|
95
103
|
}
|
|
@@ -545,6 +553,20 @@ function readEnvFile(pathname) {
|
|
|
545
553
|
}
|
|
546
554
|
}
|
|
547
555
|
|
|
556
|
+
function readJsonFile(pathname) {
|
|
557
|
+
try {
|
|
558
|
+
return JSON.parse(fs.readFileSync(pathname, "utf8"));
|
|
559
|
+
} catch (error) {
|
|
560
|
+
if (error?.code === "ENOENT") return null;
|
|
561
|
+
throw error;
|
|
562
|
+
}
|
|
563
|
+
}
|
|
564
|
+
|
|
565
|
+
function writeJsonFile(pathname, value) {
|
|
566
|
+
fs.mkdirSync(path.dirname(pathname), { recursive: true });
|
|
567
|
+
fs.writeFileSync(pathname, `${JSON.stringify(value, null, 2)}\n`);
|
|
568
|
+
}
|
|
569
|
+
|
|
548
570
|
function currentBootKey(env = process.env) {
|
|
549
571
|
const currentRoot = resolvedCurrentRuntimeRoot(env);
|
|
550
572
|
if (!currentRoot) return "";
|
|
@@ -600,6 +622,8 @@ function runDoctor() {
|
|
|
600
622
|
["setup.sh", setupPath],
|
|
601
623
|
["agent-wallet", path.join(packageRoot, "agent-wallet")],
|
|
602
624
|
["OpenClaw extension", path.join(packageRoot, ".openclaw", "extensions", "agent-wallet")],
|
|
625
|
+
["Codex plugin", path.join(packageRoot, "codex", "plugins", "agent-wallet", ".codex-plugin", "plugin.json")],
|
|
626
|
+
["Claude Code plugin", path.join(packageRoot, "claude-code", "plugins", "agent-wallet", ".claude-plugin", "plugin.json")],
|
|
603
627
|
["wdk-btc-wallet", path.join(packageRoot, "wdk-btc-wallet", "package.json")],
|
|
604
628
|
["wdk-evm-wallet", path.join(packageRoot, "wdk-evm-wallet", "package.json")],
|
|
605
629
|
];
|
|
@@ -961,6 +985,97 @@ function resolveHermesPluginSource() {
|
|
|
961
985
|
throw new Error(`Missing Hermes plugin bundle. Checked: ${candidates.join(", ")}`);
|
|
962
986
|
}
|
|
963
987
|
|
|
988
|
+
function resolveCodexPluginSource() {
|
|
989
|
+
const currentRoot = resolvedCurrentRuntimeRoot();
|
|
990
|
+
const candidates = [];
|
|
991
|
+
if (currentRoot) {
|
|
992
|
+
candidates.push(path.join(currentRoot, "codex", "plugins", "agent-wallet"));
|
|
993
|
+
}
|
|
994
|
+
candidates.push(path.join(packageRoot, "codex", "plugins", "agent-wallet"));
|
|
995
|
+
for (const source of candidates) {
|
|
996
|
+
if (fs.existsSync(path.join(source, ".codex-plugin", "plugin.json"))) {
|
|
997
|
+
return source;
|
|
998
|
+
}
|
|
999
|
+
}
|
|
1000
|
+
throw new Error(`Missing Codex plugin bundle. Checked: ${candidates.join(", ")}`);
|
|
1001
|
+
}
|
|
1002
|
+
|
|
1003
|
+
function resolveClaudeCodePluginSource() {
|
|
1004
|
+
const currentRoot = resolvedCurrentRuntimeRoot();
|
|
1005
|
+
const candidates = [];
|
|
1006
|
+
if (currentRoot) {
|
|
1007
|
+
candidates.push(path.join(currentRoot, "claude-code", "plugins", "agent-wallet"));
|
|
1008
|
+
}
|
|
1009
|
+
candidates.push(path.join(packageRoot, "claude-code", "plugins", "agent-wallet"));
|
|
1010
|
+
for (const source of candidates) {
|
|
1011
|
+
if (fs.existsSync(path.join(source, ".claude-plugin", "plugin.json"))) {
|
|
1012
|
+
return source;
|
|
1013
|
+
}
|
|
1014
|
+
}
|
|
1015
|
+
throw new Error(`Missing Claude Code plugin bundle. Checked: ${candidates.join(", ")}`);
|
|
1016
|
+
}
|
|
1017
|
+
|
|
1018
|
+
function resolveCodexPluginInstallRoot(env = process.env) {
|
|
1019
|
+
return path.resolve(expandHome(env.AGENT_WALLET_CODEX_PLUGIN_ROOT || "~/plugins"));
|
|
1020
|
+
}
|
|
1021
|
+
|
|
1022
|
+
function resolveCodexMarketplacePath(env = process.env) {
|
|
1023
|
+
return path.resolve(
|
|
1024
|
+
expandHome(env.AGENT_WALLET_CODEX_MARKETPLACE_PATH || "~/.agents/plugins/marketplace.json"),
|
|
1025
|
+
);
|
|
1026
|
+
}
|
|
1027
|
+
|
|
1028
|
+
function ensureCodexMarketplaceEntry({ marketplacePath, pluginName }) {
|
|
1029
|
+
const existing = readJsonFile(marketplacePath);
|
|
1030
|
+
const payload = existing && typeof existing === "object"
|
|
1031
|
+
? existing
|
|
1032
|
+
: {
|
|
1033
|
+
name: "local",
|
|
1034
|
+
interface: {
|
|
1035
|
+
displayName: "Local Plugins",
|
|
1036
|
+
},
|
|
1037
|
+
plugins: [],
|
|
1038
|
+
};
|
|
1039
|
+
|
|
1040
|
+
if (typeof payload.name !== "string" || !payload.name.trim()) {
|
|
1041
|
+
payload.name = "local";
|
|
1042
|
+
}
|
|
1043
|
+
if (!payload.interface || typeof payload.interface !== "object") {
|
|
1044
|
+
payload.interface = { displayName: "Local Plugins" };
|
|
1045
|
+
}
|
|
1046
|
+
if (typeof payload.interface.displayName !== "string" || !payload.interface.displayName.trim()) {
|
|
1047
|
+
payload.interface.displayName = "Local Plugins";
|
|
1048
|
+
}
|
|
1049
|
+
if (!Array.isArray(payload.plugins)) {
|
|
1050
|
+
payload.plugins = [];
|
|
1051
|
+
}
|
|
1052
|
+
|
|
1053
|
+
const entry = {
|
|
1054
|
+
name: pluginName,
|
|
1055
|
+
source: {
|
|
1056
|
+
source: "local",
|
|
1057
|
+
path: `./plugins/${pluginName}`,
|
|
1058
|
+
},
|
|
1059
|
+
policy: {
|
|
1060
|
+
installation: "AVAILABLE",
|
|
1061
|
+
authentication: "ON_INSTALL",
|
|
1062
|
+
},
|
|
1063
|
+
category: "Coding",
|
|
1064
|
+
};
|
|
1065
|
+
const index = payload.plugins.findIndex((item) => item && item.name === pluginName);
|
|
1066
|
+
if (index >= 0) {
|
|
1067
|
+
payload.plugins[index] = entry;
|
|
1068
|
+
} else {
|
|
1069
|
+
payload.plugins.push(entry);
|
|
1070
|
+
}
|
|
1071
|
+
writeJsonFile(marketplacePath, payload);
|
|
1072
|
+
return {
|
|
1073
|
+
marketplace_name: payload.name,
|
|
1074
|
+
marketplace_path: marketplacePath,
|
|
1075
|
+
entry,
|
|
1076
|
+
};
|
|
1077
|
+
}
|
|
1078
|
+
|
|
964
1079
|
function resolveAgentWalletPackageRoot(env = process.env) {
|
|
965
1080
|
const currentRoot = resolvedCurrentRuntimeRoot(env);
|
|
966
1081
|
if (currentRoot) {
|
|
@@ -1072,6 +1187,227 @@ function runHermesInstall(args) {
|
|
|
1072
1187
|
return enable.skipped || enable.ok ? 0 : 1;
|
|
1073
1188
|
}
|
|
1074
1189
|
|
|
1190
|
+
function runCodexInstall(args) {
|
|
1191
|
+
const codexHome = resolveCodexHome();
|
|
1192
|
+
const pluginSource = resolveCodexPluginSource();
|
|
1193
|
+
const pluginRoot = resolveCodexPluginInstallRoot();
|
|
1194
|
+
const pluginTarget = path.join(pluginRoot, "agent-wallet");
|
|
1195
|
+
const marketplacePath = resolveCodexMarketplacePath();
|
|
1196
|
+
const force = hasFlag(args, "--force");
|
|
1197
|
+
const skipEnable = hasFlag(args, "--skip-enable");
|
|
1198
|
+
const codexBin = commandPath("codex");
|
|
1199
|
+
|
|
1200
|
+
fs.mkdirSync(pluginRoot, { recursive: true });
|
|
1201
|
+
try {
|
|
1202
|
+
const existing = fs.lstatSync(pluginTarget);
|
|
1203
|
+
if (!existing.isSymbolicLink()) {
|
|
1204
|
+
if (!force) {
|
|
1205
|
+
throw new Error(`${pluginTarget} exists and is not a symlink. Pass --force to replace it.`);
|
|
1206
|
+
}
|
|
1207
|
+
fs.rmSync(pluginTarget, { recursive: true, force: true });
|
|
1208
|
+
} else {
|
|
1209
|
+
fs.unlinkSync(pluginTarget);
|
|
1210
|
+
}
|
|
1211
|
+
} catch (error) {
|
|
1212
|
+
if (error?.code !== "ENOENT") throw error;
|
|
1213
|
+
}
|
|
1214
|
+
fs.symlinkSync(pluginSource, pluginTarget, "dir");
|
|
1215
|
+
|
|
1216
|
+
const marketplace = ensureCodexMarketplaceEntry({
|
|
1217
|
+
marketplacePath,
|
|
1218
|
+
pluginName: "agent-wallet",
|
|
1219
|
+
});
|
|
1220
|
+
|
|
1221
|
+
let add = { attempted: false, ok: false, skipped: skipEnable, error: "" };
|
|
1222
|
+
if (!skipEnable) {
|
|
1223
|
+
if (!codexBin) {
|
|
1224
|
+
add = {
|
|
1225
|
+
attempted: false,
|
|
1226
|
+
ok: false,
|
|
1227
|
+
skipped: false,
|
|
1228
|
+
error: "Codex CLI was not found on PATH. Run `codex plugin add agent-wallet@local` after installing Codex.",
|
|
1229
|
+
};
|
|
1230
|
+
} else {
|
|
1231
|
+
const result = spawnSync(
|
|
1232
|
+
codexBin,
|
|
1233
|
+
["plugin", "add", `agent-wallet@${marketplace.marketplace_name}`],
|
|
1234
|
+
{
|
|
1235
|
+
cwd: packageRoot,
|
|
1236
|
+
encoding: "utf8",
|
|
1237
|
+
env: {
|
|
1238
|
+
...process.env,
|
|
1239
|
+
CODEX_HOME: codexHome,
|
|
1240
|
+
},
|
|
1241
|
+
},
|
|
1242
|
+
);
|
|
1243
|
+
add = {
|
|
1244
|
+
attempted: true,
|
|
1245
|
+
ok: result.status === 0,
|
|
1246
|
+
skipped: false,
|
|
1247
|
+
error: result.status === 0 ? "" : (result.stderr || result.stdout || "").trim(),
|
|
1248
|
+
};
|
|
1249
|
+
}
|
|
1250
|
+
}
|
|
1251
|
+
|
|
1252
|
+
console.log(
|
|
1253
|
+
JSON.stringify(
|
|
1254
|
+
{
|
|
1255
|
+
ok: add.skipped || add.ok,
|
|
1256
|
+
codex_home: codexHome,
|
|
1257
|
+
plugin_source: pluginSource,
|
|
1258
|
+
plugin_target: pluginTarget,
|
|
1259
|
+
marketplace_path: marketplace.marketplace_path,
|
|
1260
|
+
marketplace_name: marketplace.marketplace_name,
|
|
1261
|
+
codex_add: add,
|
|
1262
|
+
restart_required: true,
|
|
1263
|
+
},
|
|
1264
|
+
null,
|
|
1265
|
+
2,
|
|
1266
|
+
),
|
|
1267
|
+
);
|
|
1268
|
+
return add.skipped || add.ok ? 0 : 1;
|
|
1269
|
+
}
|
|
1270
|
+
|
|
1271
|
+
const CLAUDE_CODE_MARKETPLACE_NAME = "agentlayer-local";
|
|
1272
|
+
|
|
1273
|
+
function resolveClaudeCodeMarketplaceDir(env = process.env) {
|
|
1274
|
+
return path.resolve(
|
|
1275
|
+
expandHome(env.AGENT_WALLET_CLAUDE_CODE_MARKETPLACE_DIR || "~/.claude/agentlayer-local"),
|
|
1276
|
+
);
|
|
1277
|
+
}
|
|
1278
|
+
|
|
1279
|
+
function ensureClaudeCodeMarketplace(marketplaceDir, pluginSource, force) {
|
|
1280
|
+
const pluginsDir = path.join(marketplaceDir, "plugins");
|
|
1281
|
+
const pluginLink = path.join(pluginsDir, "agent-wallet");
|
|
1282
|
+
const manifestDir = path.join(marketplaceDir, ".claude-plugin");
|
|
1283
|
+
const manifestPath = path.join(manifestDir, "marketplace.json");
|
|
1284
|
+
|
|
1285
|
+
fs.mkdirSync(pluginsDir, { recursive: true });
|
|
1286
|
+
fs.mkdirSync(manifestDir, { recursive: true });
|
|
1287
|
+
|
|
1288
|
+
// Symlink plugin source into marketplace plugins dir.
|
|
1289
|
+
try {
|
|
1290
|
+
const existing = fs.lstatSync(pluginLink);
|
|
1291
|
+
if (!existing.isSymbolicLink()) {
|
|
1292
|
+
if (!force) {
|
|
1293
|
+
throw new Error(
|
|
1294
|
+
`${pluginLink} exists and is not a symlink. Pass --force to replace it.`,
|
|
1295
|
+
);
|
|
1296
|
+
}
|
|
1297
|
+
fs.rmSync(pluginLink, { recursive: true, force: true });
|
|
1298
|
+
} else {
|
|
1299
|
+
fs.unlinkSync(pluginLink);
|
|
1300
|
+
}
|
|
1301
|
+
} catch (error) {
|
|
1302
|
+
if (error?.code !== "ENOENT") throw error;
|
|
1303
|
+
}
|
|
1304
|
+
fs.symlinkSync(pluginSource, pluginLink, "dir");
|
|
1305
|
+
|
|
1306
|
+
// Write marketplace manifest (Claude Code requires owner + plugins[].source as relative path).
|
|
1307
|
+
const manifest = {
|
|
1308
|
+
name: CLAUDE_CODE_MARKETPLACE_NAME,
|
|
1309
|
+
description: "Local AgentLayer plugins",
|
|
1310
|
+
owner: { name: "AgentLayer" },
|
|
1311
|
+
plugins: [
|
|
1312
|
+
{
|
|
1313
|
+
name: "agent-wallet",
|
|
1314
|
+
displayName: "Agent Wallet",
|
|
1315
|
+
description:
|
|
1316
|
+
"Bridge to the existing local AgentLayer wallet runtime (Solana, Bitcoin, EVM).",
|
|
1317
|
+
category: "development",
|
|
1318
|
+
source: "./plugins/agent-wallet",
|
|
1319
|
+
},
|
|
1320
|
+
],
|
|
1321
|
+
};
|
|
1322
|
+
writeJsonFile(manifestPath, manifest);
|
|
1323
|
+
return { pluginLink, manifestPath };
|
|
1324
|
+
}
|
|
1325
|
+
|
|
1326
|
+
function runClaudeCodeInstall(args) {
|
|
1327
|
+
const pluginSource = resolveClaudeCodePluginSource();
|
|
1328
|
+
const force = hasFlag(args, "--force");
|
|
1329
|
+
const skipEnable = hasFlag(args, "--skip-enable");
|
|
1330
|
+
const claudeBin = commandPath("claude");
|
|
1331
|
+
const marketplaceDir = resolveClaudeCodeMarketplaceDir();
|
|
1332
|
+
|
|
1333
|
+
const { pluginLink } = ensureClaudeCodeMarketplace(marketplaceDir, pluginSource, force);
|
|
1334
|
+
|
|
1335
|
+
const pluginDirFlag = `claude --plugin-dir ${pluginLink}`;
|
|
1336
|
+
|
|
1337
|
+
// Without the Claude CLI we can only set up the files; the user must register manually.
|
|
1338
|
+
let marketplaceAdd = { attempted: false, ok: false, skipped: skipEnable, error: "" };
|
|
1339
|
+
let enable = { attempted: false, ok: false, skipped: skipEnable, error: "" };
|
|
1340
|
+
|
|
1341
|
+
if (!skipEnable) {
|
|
1342
|
+
if (!claudeBin) {
|
|
1343
|
+
const msg =
|
|
1344
|
+
"Claude Code CLI was not found on PATH. Load the plugin manually with: " + pluginDirFlag;
|
|
1345
|
+
marketplaceAdd = { attempted: false, ok: false, skipped: false, error: msg };
|
|
1346
|
+
enable = { attempted: false, ok: false, skipped: false, error: msg };
|
|
1347
|
+
} else {
|
|
1348
|
+
// Register the local marketplace (idempotent — safe to re-run).
|
|
1349
|
+
const addResult = spawnSync(
|
|
1350
|
+
claudeBin,
|
|
1351
|
+
["plugin", "marketplace", "add", marketplaceDir, "--scope", "user"],
|
|
1352
|
+
{ encoding: "utf8", stdio: "pipe" },
|
|
1353
|
+
);
|
|
1354
|
+
marketplaceAdd = {
|
|
1355
|
+
attempted: true,
|
|
1356
|
+
ok: addResult.status === 0,
|
|
1357
|
+
skipped: false,
|
|
1358
|
+
error: addResult.status === 0 ? "" : (addResult.stderr || addResult.stdout || "").trim(),
|
|
1359
|
+
};
|
|
1360
|
+
|
|
1361
|
+
if (marketplaceAdd.ok) {
|
|
1362
|
+
// Install plugin from the now-registered local marketplace.
|
|
1363
|
+
const installResult = spawnSync(
|
|
1364
|
+
claudeBin,
|
|
1365
|
+
["plugin", "install", `agent-wallet@${CLAUDE_CODE_MARKETPLACE_NAME}`, "--scope", "user"],
|
|
1366
|
+
{ encoding: "utf8", stdio: "pipe" },
|
|
1367
|
+
);
|
|
1368
|
+
enable = {
|
|
1369
|
+
attempted: true,
|
|
1370
|
+
ok: installResult.status === 0,
|
|
1371
|
+
skipped: false,
|
|
1372
|
+
error:
|
|
1373
|
+
installResult.status === 0
|
|
1374
|
+
? ""
|
|
1375
|
+
: (installResult.stderr || installResult.stdout || "").trim(),
|
|
1376
|
+
};
|
|
1377
|
+
} else {
|
|
1378
|
+
enable = {
|
|
1379
|
+
attempted: false,
|
|
1380
|
+
ok: false,
|
|
1381
|
+
skipped: false,
|
|
1382
|
+
error: "Skipped plugin install because marketplace registration failed.",
|
|
1383
|
+
};
|
|
1384
|
+
}
|
|
1385
|
+
}
|
|
1386
|
+
}
|
|
1387
|
+
|
|
1388
|
+
const ok = enable.skipped || enable.ok;
|
|
1389
|
+
const pluginDirFlagFull = `claude --plugin-dir ${pluginSource}`;
|
|
1390
|
+
console.log(
|
|
1391
|
+
JSON.stringify(
|
|
1392
|
+
{
|
|
1393
|
+
ok,
|
|
1394
|
+
plugin_source: pluginSource,
|
|
1395
|
+
marketplace_dir: marketplaceDir,
|
|
1396
|
+
marketplace_add: marketplaceAdd,
|
|
1397
|
+
claude_code_install: enable,
|
|
1398
|
+
manual_load: pluginDirFlagFull,
|
|
1399
|
+
restart_required: true,
|
|
1400
|
+
note: ok
|
|
1401
|
+
? "Plugin registered. Restart Claude Code to activate."
|
|
1402
|
+
: `If automatic registration failed, load the plugin with: ${pluginDirFlagFull}`,
|
|
1403
|
+
},
|
|
1404
|
+
null,
|
|
1405
|
+
2,
|
|
1406
|
+
),
|
|
1407
|
+
);
|
|
1408
|
+
return enable.skipped || enable.ok ? 0 : 1;
|
|
1409
|
+
}
|
|
1410
|
+
|
|
1075
1411
|
const args = process.argv.slice(2);
|
|
1076
1412
|
const command = args[0] || "install";
|
|
1077
1413
|
|
|
@@ -1115,6 +1451,26 @@ if (command === "hermes") {
|
|
|
1115
1451
|
process.exit(2);
|
|
1116
1452
|
}
|
|
1117
1453
|
|
|
1454
|
+
if (command === "codex") {
|
|
1455
|
+
const subcommand = args[1] || "install";
|
|
1456
|
+
if (subcommand === "install" || subcommand === "setup") {
|
|
1457
|
+
process.exit(runCodexInstall(args.slice(2)));
|
|
1458
|
+
}
|
|
1459
|
+
console.error(`Unknown codex command: ${subcommand}`);
|
|
1460
|
+
console.error("Run `openclaw-agent-wallet codex install --yes` to connect Codex.");
|
|
1461
|
+
process.exit(2);
|
|
1462
|
+
}
|
|
1463
|
+
|
|
1464
|
+
if (command === "claude-code") {
|
|
1465
|
+
const subcommand = args[1] || "install";
|
|
1466
|
+
if (subcommand === "install" || subcommand === "setup") {
|
|
1467
|
+
process.exit(runClaudeCodeInstall(args.slice(2)));
|
|
1468
|
+
}
|
|
1469
|
+
console.error(`Unknown claude-code command: ${subcommand}`);
|
|
1470
|
+
console.error("Run `openclaw-agent-wallet claude-code install --yes` to connect Claude Code.");
|
|
1471
|
+
process.exit(2);
|
|
1472
|
+
}
|
|
1473
|
+
|
|
1118
1474
|
if (command.startsWith("-")) {
|
|
1119
1475
|
process.exit(runInstall(args, { commandName: "install" }));
|
|
1120
1476
|
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "agent-wallet",
|
|
3
|
+
"displayName": "Agent Wallet",
|
|
4
|
+
"version": "0.1.0",
|
|
5
|
+
"description": "Claude Code bridge for the existing AgentLayer wallet runtime. Connects to Solana, Bitcoin, and EVM wallets without creating a new one.",
|
|
6
|
+
"author": {
|
|
7
|
+
"name": "AgentLayer"
|
|
8
|
+
},
|
|
9
|
+
"homepage": "https://github.com/lopushok9/Agent-Layer",
|
|
10
|
+
"repository": "https://github.com/lopushok9/Agent-Layer",
|
|
11
|
+
"license": "SEE LICENSE IN ../../../LICENSE",
|
|
12
|
+
"keywords": [
|
|
13
|
+
"claude-code",
|
|
14
|
+
"wallet",
|
|
15
|
+
"solana",
|
|
16
|
+
"bitcoin",
|
|
17
|
+
"evm",
|
|
18
|
+
"agentlayer"
|
|
19
|
+
]
|
|
20
|
+
}
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
# Agent Wallet Claude Code Plugin
|
|
2
|
+
|
|
3
|
+
This plugin adds the existing local AgentLayer wallet runtime to Claude Code.
|
|
4
|
+
|
|
5
|
+
It does not create a new wallet. It reuses the current runtime under:
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
~/.openclaw/agent-wallet-runtime/current/agent-wallet
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
Primary design rules:
|
|
12
|
+
|
|
13
|
+
- keep wallet policy, approvals, and signing in `agent-wallet/`
|
|
14
|
+
- keep this plugin as a thin MCP bridge for Claude Code
|
|
15
|
+
- reuse the same wallets, networks, and tool surface already used by OpenClaw, Hermes, and Codex
|
|
16
|
+
- avoid secrets in plugin config or marketplace metadata
|
|
17
|
+
|
|
18
|
+
## What it exposes
|
|
19
|
+
|
|
20
|
+
- direct wallet tools for Solana, Bitcoin, and EVM (same surface as OpenClaw and Codex)
|
|
21
|
+
- session wallet selection with `set_wallet_backend`
|
|
22
|
+
- EVM network selection with `set_evm_network`
|
|
23
|
+
- auto-managed approval binding for `preview -> execute` write flows
|
|
24
|
+
|
|
25
|
+
## Runtime requirements
|
|
26
|
+
|
|
27
|
+
- install the AgentLayer runtime first with `npx @agentlayer.tech/wallet install --yes`
|
|
28
|
+
- keep the local wallet files and `~/.openclaw/sealed_keys.json` in place
|
|
29
|
+
- run `npx @agentlayer.tech/wallet claude-code install --yes` to register this plugin
|
|
30
|
+
|
|
31
|
+
## Installation
|
|
32
|
+
|
|
33
|
+
### Automated (recommended)
|
|
34
|
+
|
|
35
|
+
```bash
|
|
36
|
+
npx @agentlayer.tech/wallet install --yes
|
|
37
|
+
npx @agentlayer.tech/wallet claude-code install --yes
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
### Manual
|
|
41
|
+
|
|
42
|
+
```bash
|
|
43
|
+
# Load for a single session (dev / testing)
|
|
44
|
+
claude --plugin-dir /path/to/claude-code/plugins/agent-wallet
|
|
45
|
+
|
|
46
|
+
# Or install permanently via Claude Code:
|
|
47
|
+
# 1. Open Claude Code
|
|
48
|
+
# 2. Run /plugin and point it at this directory
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
## Path resolution
|
|
52
|
+
|
|
53
|
+
The bridge resolves the wallet runtime from:
|
|
54
|
+
|
|
55
|
+
1. `AGENT_WALLET_PACKAGE_ROOT`
|
|
56
|
+
2. `OPENCLAW_AGENT_WALLET_PACKAGE_ROOT`
|
|
57
|
+
3. `~/.openclaw/agent-wallet-runtime/current/agent-wallet`
|
|
58
|
+
|
|
59
|
+
If the runtime lives elsewhere, set one of the env overrides before starting Claude Code.
|
|
60
|
+
|
|
61
|
+
## MCP server
|
|
62
|
+
|
|
63
|
+
The plugin launches an MCP server via `scripts/run_mcp.sh`, which runs the same
|
|
64
|
+
`server.py` FastMCP bridge used by the Codex plugin. `${CLAUDE_PLUGIN_ROOT}` is
|
|
65
|
+
substituted by Claude Code at plugin load time.
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
#!/bin/sh
|
|
2
|
+
set -eu
|
|
3
|
+
|
|
4
|
+
SCRIPT_DIR=$(CDPATH= cd -- "$(dirname -- "$0")" && pwd)
|
|
5
|
+
PLUGIN_ROOT=$(CDPATH= cd -- "$SCRIPT_DIR/.." && pwd)
|
|
6
|
+
OPENCLAW_HOME=${OPENCLAW_HOME:-"$HOME/.openclaw"}
|
|
7
|
+
PACKAGE_ROOT=${AGENT_WALLET_PACKAGE_ROOT:-${OPENCLAW_AGENT_WALLET_PACKAGE_ROOT:-"$OPENCLAW_HOME/agent-wallet-runtime/current/agent-wallet"}}
|
|
8
|
+
|
|
9
|
+
# Resolve server.py. When Claude Code copies this plugin into its cache, the
|
|
10
|
+
# relative sibling paths below no longer resolve, so fall back to the codex
|
|
11
|
+
# plugin copy inside the installed runtime package, which is always present.
|
|
12
|
+
LOCAL_SERVER="$PLUGIN_ROOT/server.py"
|
|
13
|
+
CODEX_SERVER="$PLUGIN_ROOT/../../codex/plugins/agent-wallet/server.py"
|
|
14
|
+
RUNTIME_CODEX_DIR="$OPENCLAW_HOME/agent-wallet-runtime/current/codex/plugins/agent-wallet"
|
|
15
|
+
|
|
16
|
+
if [ -f "$LOCAL_SERVER" ]; then
|
|
17
|
+
SERVER_PY="$LOCAL_SERVER"
|
|
18
|
+
elif [ -f "$CODEX_SERVER" ]; then
|
|
19
|
+
SERVER_PY=$(CDPATH= cd -- "$PLUGIN_ROOT/../../codex/plugins/agent-wallet" && pwd)/server.py
|
|
20
|
+
elif [ -f "$RUNTIME_CODEX_DIR/server.py" ]; then
|
|
21
|
+
SERVER_PY=$(CDPATH= cd -- "$RUNTIME_CODEX_DIR" && pwd)/server.py
|
|
22
|
+
else
|
|
23
|
+
printf '{"error":"agent-wallet server.py not found. Run: npx @agentlayer.tech/wallet install --yes"}\n' >&2
|
|
24
|
+
exit 1
|
|
25
|
+
fi
|
|
26
|
+
|
|
27
|
+
if [ -n "${AGENT_WALLET_PYTHON:-}" ]; then
|
|
28
|
+
PYTHON_BIN=$AGENT_WALLET_PYTHON
|
|
29
|
+
elif [ -n "${OPENCLAW_AGENT_WALLET_PYTHON:-}" ]; then
|
|
30
|
+
PYTHON_BIN=$OPENCLAW_AGENT_WALLET_PYTHON
|
|
31
|
+
elif [ -x "$PACKAGE_ROOT/.venv/bin/python" ]; then
|
|
32
|
+
PYTHON_BIN=$PACKAGE_ROOT/.venv/bin/python
|
|
33
|
+
elif [ -x "$PACKAGE_ROOT/.runtime-venv/bin/python" ]; then
|
|
34
|
+
PYTHON_BIN=$PACKAGE_ROOT/.runtime-venv/bin/python
|
|
35
|
+
else
|
|
36
|
+
PYTHON_BIN=python3
|
|
37
|
+
fi
|
|
38
|
+
|
|
39
|
+
exec "$PYTHON_BIN" "$SERVER_PY"
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: "Use when the user asks Claude Code to interact with the local AgentLayer wallet runtime: check balances, transfer tokens, swap, DeFi operations, or x402 payments. Prefer wallet tools over shell commands. Preview writes first and execute only after explicit user confirmation."
|
|
3
|
+
---
|
|
4
|
+
|
|
5
|
+
# Agent Wallet Operator
|
|
6
|
+
|
|
7
|
+
Use this skill when the user wants Claude Code to work with the existing local AgentLayer wallet.
|
|
8
|
+
|
|
9
|
+
Rules:
|
|
10
|
+
|
|
11
|
+
- Do not create a new wallet unless the user explicitly requests wallet provisioning.
|
|
12
|
+
- Prefer wallet tools over shelling out to chain CLIs, curl, or ad hoc scripts.
|
|
13
|
+
- For writes, start with `preview` or `intent_preview` when the tool supports it.
|
|
14
|
+
- Execute only after the user explicitly confirms the shown summary.
|
|
15
|
+
- On mainnet, restate the network, asset, amount, and destination before execute.
|
|
16
|
+
- Do not ask the user for `approval_token`. The bridge manages approval binding internally.
|
|
17
|
+
- If approval context is missing or stale, repeat preview instead of improvising.
|
|
18
|
+
- Use `set_wallet_backend` to switch between Solana, EVM, and Bitcoin wallets within a session.
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "agent-wallet",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "Codex plugin bridge for the AgentLayer wallet runtime.",
|
|
5
|
+
"author": {
|
|
6
|
+
"name": "AgentLayer"
|
|
7
|
+
},
|
|
8
|
+
"homepage": "https://github.com/lopushok9/Agent-Layer",
|
|
9
|
+
"repository": "https://github.com/lopushok9/Agent-Layer",
|
|
10
|
+
"license": "SEE LICENSE IN ../../../LICENSE",
|
|
11
|
+
"keywords": [
|
|
12
|
+
"codex",
|
|
13
|
+
"wallet",
|
|
14
|
+
"solana",
|
|
15
|
+
"bitcoin",
|
|
16
|
+
"evm",
|
|
17
|
+
"agentlayer"
|
|
18
|
+
],
|
|
19
|
+
"skills": "./skills/",
|
|
20
|
+
"mcpServers": "./.mcp.json",
|
|
21
|
+
"interface": {
|
|
22
|
+
"displayName": "Agent Wallet",
|
|
23
|
+
"shortDescription": "Use the local AgentLayer wallet runtime directly in Codex",
|
|
24
|
+
"longDescription": "Agent Wallet adds the existing local AgentLayer wallet runtime to Codex without creating a new wallet. It reuses the current OpenClaw runtime, keeps secrets local, and exposes the same Solana, Bitcoin, EVM, x402, Jupiter, Kamino, LI.FI, Bags, and Flash Trade tool surface through a Codex-native MCP bridge.",
|
|
25
|
+
"developerName": "AgentLayer",
|
|
26
|
+
"category": "Coding",
|
|
27
|
+
"capabilities": [
|
|
28
|
+
"Interactive",
|
|
29
|
+
"Read",
|
|
30
|
+
"Write"
|
|
31
|
+
],
|
|
32
|
+
"websiteURL": "https://github.com/lopushok9/Agent-Layer",
|
|
33
|
+
"privacyPolicyURL": "https://openai.com/policies/privacy-policy/",
|
|
34
|
+
"termsOfServiceURL": "https://openai.com/policies/terms-of-use/",
|
|
35
|
+
"defaultPrompt": "Use my existing AgentLayer wallet here in Codex, preview wallet writes first, and execute only after explicit confirmation.",
|
|
36
|
+
"brandColor": "#0F766E"
|
|
37
|
+
}
|
|
38
|
+
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
{
|
|
2
|
+
"mcpServers": {
|
|
3
|
+
"agent-wallet": {
|
|
4
|
+
"command": "sh",
|
|
5
|
+
"args": [
|
|
6
|
+
"-lc",
|
|
7
|
+
"exec \"${AGENT_WALLET_CODEX_PLUGIN_ROOT:-$HOME/plugins}/agent-wallet/scripts/run_mcp.sh\""
|
|
8
|
+
],
|
|
9
|
+
"env": {
|
|
10
|
+
"FASTMCP_SHOW_SERVER_BANNER": "false",
|
|
11
|
+
"FASTMCP_LOG_LEVEL": "ERROR"
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
}
|