@agentlayer.tech/wallet 0.1.33 → 0.1.34
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/dist/index.js +2 -59
- package/.openclaw/extensions/agent-wallet/index.ts +2 -59
- package/.openclaw/extensions/agent-wallet/openclaw.plugin.json +1 -4
- package/.openclaw/extensions/agent-wallet/package.json +1 -1
- package/CHANGELOG.md +41 -0
- package/README.md +2 -5
- package/RELEASING.md +56 -29
- package/VERSION +1 -0
- package/agent-wallet/.env.example +0 -1
- package/agent-wallet/README.md +0 -8
- package/agent-wallet/agent_wallet/__init__.py +5 -0
- package/agent-wallet/agent_wallet/config.py +0 -1
- package/agent-wallet/agent_wallet/openclaw_adapter.py +25 -324
- package/agent-wallet/agent_wallet/openclaw_cli.py +0 -5
- package/agent-wallet/agent_wallet/providers/bags.py +1 -58
- package/agent-wallet/agent_wallet/providers/jupiter.py +1 -64
- package/agent-wallet/agent_wallet/update_check.py +191 -0
- package/agent-wallet/agent_wallet/wallet_layer/base.py +0 -44
- package/agent-wallet/agent_wallet/wallet_layer/solana.py +0 -236
- package/agent-wallet/openclaw.plugin.json +1 -5
- package/agent-wallet/pyproject.toml +1 -1
- package/agent-wallet/skills/wallet-operator/SKILL.md +2 -5
- package/bin/openclaw-agent-wallet.mjs +88 -1
- package/claude-code/plugins/agent-wallet/.claude-plugin/plugin.json +1 -1
- package/codex/plugins/agent-wallet/.codex-plugin/plugin.json +1 -1
- package/codex/plugins/agent-wallet/server.py +39 -5
- package/hermes/plugins/agent_wallet/plugin.yaml +1 -1
- package/package.json +5 -1
- package/scripts/check_release_version.mjs +50 -20
- package/scripts/version_targets.mjs +60 -0
- package/wdk-btc-wallet/package.json +1 -1
- package/wdk-evm-wallet/README.md +3 -3
- package/wdk-evm-wallet/package.json +1 -1
- package/wdk-evm-wallet/src/wdk_evm_wallet.js +17 -2
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "agent-wallet",
|
|
3
3
|
"displayName": "Agent Wallet",
|
|
4
|
-
"version": "0.1.
|
|
4
|
+
"version": "0.1.34",
|
|
5
5
|
"description": "Claude Code bridge for the existing AgentLayer wallet runtime. Connects to Solana, Bitcoin, and EVM wallets without creating a new one.",
|
|
6
6
|
"author": {
|
|
7
7
|
"name": "AgentLayer"
|
|
@@ -906,17 +906,51 @@ async def _handle_wallet_tool(tool_name: str, params: dict[str, Any]) -> dict[st
|
|
|
906
906
|
return payload.get("data", {})
|
|
907
907
|
|
|
908
908
|
|
|
909
|
+
BASE_INSTRUCTIONS = (
|
|
910
|
+
"Use the local AgentLayer wallet runtime through explicit wallet tools. Keep wallet "
|
|
911
|
+
"secrets local. Preview writes first when supported, and execute only after explicit "
|
|
912
|
+
"user confirmation."
|
|
913
|
+
)
|
|
914
|
+
|
|
915
|
+
|
|
916
|
+
def _update_notice_instructions(base: str) -> str:
|
|
917
|
+
"""Append a one-time update notice to ``base`` when a newer version exists.
|
|
918
|
+
|
|
919
|
+
Fully fail-open: any error (package not importable, malformed cache, etc.)
|
|
920
|
+
returns ``base`` unchanged so the server always starts. The network refresh
|
|
921
|
+
runs in a background daemon thread and only affects the *next* start; the
|
|
922
|
+
notice itself is decided synchronously from the cache.
|
|
923
|
+
"""
|
|
924
|
+
try:
|
|
925
|
+
package_root_text = str(_resolve_package_root())
|
|
926
|
+
inserted = package_root_text not in sys.path
|
|
927
|
+
if inserted:
|
|
928
|
+
sys.path.insert(0, package_root_text)
|
|
929
|
+
try:
|
|
930
|
+
from agent_wallet import update_check
|
|
931
|
+
|
|
932
|
+
update_check.maybe_refresh_in_background()
|
|
933
|
+
notice = update_check.pending_notice(mark_shown=True)
|
|
934
|
+
finally:
|
|
935
|
+
if inserted:
|
|
936
|
+
try:
|
|
937
|
+
sys.path.remove(package_root_text)
|
|
938
|
+
except ValueError:
|
|
939
|
+
pass
|
|
940
|
+
if notice:
|
|
941
|
+
return f"{base}\n\n⚠️ UPDATE AVAILABLE: {notice}"
|
|
942
|
+
except Exception:
|
|
943
|
+
pass
|
|
944
|
+
return base
|
|
945
|
+
|
|
946
|
+
|
|
909
947
|
def build_server():
|
|
910
948
|
from fastmcp import FastMCP
|
|
911
949
|
from fastmcp.tools import FunctionTool
|
|
912
950
|
|
|
913
951
|
mcp = FastMCP(
|
|
914
952
|
"Agent Wallet",
|
|
915
|
-
instructions=(
|
|
916
|
-
"Use the local AgentLayer wallet runtime through explicit wallet tools. Keep wallet "
|
|
917
|
-
"secrets local. Preview writes first when supported, and execute only after explicit "
|
|
918
|
-
"user confirmation."
|
|
919
|
-
),
|
|
953
|
+
instructions=_update_notice_instructions(BASE_INSTRUCTIONS),
|
|
920
954
|
)
|
|
921
955
|
|
|
922
956
|
async def _dispatch(tool_name: str, params: dict[str, Any] | None = None) -> dict[str, Any]:
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@agentlayer.tech/wallet",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.34",
|
|
4
4
|
"description": "NPM installer for the OpenClaw Agent Wallet local runtime.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"repository": {
|
|
@@ -19,12 +19,16 @@
|
|
|
19
19
|
"build:openclaw-plugins": "node scripts/manage_openclaw_plugin_packages.mjs build",
|
|
20
20
|
"check:openclaw-plugins": "node scripts/manage_openclaw_plugin_packages.mjs check",
|
|
21
21
|
"check:release-version": "node scripts/check_release_version.mjs",
|
|
22
|
+
"version:sync": "node scripts/sync_version.mjs",
|
|
23
|
+
"release:local": "node scripts/release_local.mjs",
|
|
22
24
|
"test:npm-installer": "python3 agent-wallet/tests/smoke_npm_installer.py",
|
|
23
25
|
"pack:dry-run": "npm pack --dry-run"
|
|
24
26
|
},
|
|
25
27
|
"files": [
|
|
26
28
|
"bin/",
|
|
29
|
+
"VERSION",
|
|
27
30
|
"scripts/check_release_version.mjs",
|
|
31
|
+
"scripts/version_targets.mjs",
|
|
28
32
|
"setup.sh",
|
|
29
33
|
"install-from-github.sh",
|
|
30
34
|
"README.md",
|
|
@@ -1,26 +1,59 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
+
// Verify the project version is consistent across every framework manifest and,
|
|
3
|
+
// when run on a release tag, that the tag matches the canonical VERSION.
|
|
4
|
+
//
|
|
5
|
+
// Canonical source: the root VERSION file. All derived manifests (see
|
|
6
|
+
// scripts/version_targets.mjs) must equal it — stamp them with
|
|
7
|
+
// scripts/sync_version.mjs if this fails. Emits the resolved version and npm
|
|
8
|
+
// dist-tag for the publish workflow.
|
|
2
9
|
|
|
3
10
|
import fs from "node:fs";
|
|
4
11
|
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
12
|
+
import {
|
|
13
|
+
TARGETS,
|
|
14
|
+
VERSION_FILE,
|
|
15
|
+
npmTagFor,
|
|
16
|
+
readCanonicalVersion,
|
|
17
|
+
readTargetVersion,
|
|
18
|
+
} from "./version_targets.mjs";
|
|
19
|
+
|
|
20
|
+
const root = process.cwd();
|
|
11
21
|
const errors = [];
|
|
12
22
|
|
|
13
|
-
|
|
14
|
-
|
|
23
|
+
let canonical = "";
|
|
24
|
+
try {
|
|
25
|
+
canonical = readCanonicalVersion(root);
|
|
26
|
+
} catch {
|
|
27
|
+
errors.push(`${VERSION_FILE} is missing`);
|
|
15
28
|
}
|
|
16
|
-
if (
|
|
17
|
-
errors.push(
|
|
29
|
+
if (canonical === "") {
|
|
30
|
+
errors.push(`${VERSION_FILE} is empty`);
|
|
18
31
|
}
|
|
19
|
-
|
|
20
|
-
|
|
32
|
+
|
|
33
|
+
if (canonical) {
|
|
34
|
+
for (const target of TARGETS) {
|
|
35
|
+
let actual = null;
|
|
36
|
+
try {
|
|
37
|
+
actual = readTargetVersion(root, target);
|
|
38
|
+
} catch {
|
|
39
|
+
errors.push(`${target.file} is missing`);
|
|
40
|
+
continue;
|
|
41
|
+
}
|
|
42
|
+
if (!actual) {
|
|
43
|
+
errors.push(`${target.file}: version field not found`);
|
|
44
|
+
} else if (actual !== canonical) {
|
|
45
|
+
errors.push(
|
|
46
|
+
`version mismatch: ${target.file}=${actual}, ${VERSION_FILE}=${canonical} ` +
|
|
47
|
+
`(run: npm run version:sync)`,
|
|
48
|
+
);
|
|
49
|
+
}
|
|
50
|
+
}
|
|
21
51
|
}
|
|
22
|
-
|
|
23
|
-
|
|
52
|
+
|
|
53
|
+
const refName = process.env.GITHUB_REF_NAME || process.argv[2] || "";
|
|
54
|
+
const expectedFromTag = refName.startsWith("v") ? refName.slice(1) : "";
|
|
55
|
+
if (expectedFromTag && canonical && canonical !== expectedFromTag) {
|
|
56
|
+
errors.push(`tag/version mismatch: tag=${refName}, ${VERSION_FILE}=${canonical}`);
|
|
24
57
|
}
|
|
25
58
|
|
|
26
59
|
if (errors.length > 0) {
|
|
@@ -30,13 +63,10 @@ if (errors.length > 0) {
|
|
|
30
63
|
process.exit(1);
|
|
31
64
|
}
|
|
32
65
|
|
|
33
|
-
const npmTag =
|
|
34
|
-
console.log(`release_version=${
|
|
66
|
+
const npmTag = npmTagFor(canonical);
|
|
67
|
+
console.log(`release_version=${canonical}`);
|
|
35
68
|
console.log(`npm_tag=${npmTag}`);
|
|
36
69
|
|
|
37
70
|
if (process.env.GITHUB_OUTPUT) {
|
|
38
|
-
fs.appendFileSync(
|
|
39
|
-
process.env.GITHUB_OUTPUT,
|
|
40
|
-
`release_version=${packageVersion}\nnpm_tag=${npmTag}\n`,
|
|
41
|
-
);
|
|
71
|
+
fs.appendFileSync(process.env.GITHUB_OUTPUT, `release_version=${canonical}\nnpm_tag=${npmTag}\n`);
|
|
42
72
|
}
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
// Single source of truth for the project version.
|
|
2
|
+
//
|
|
3
|
+
// The root VERSION file is canonical. Every other manifest below is a *derived*
|
|
4
|
+
// target that must carry the exact same version. These targets are stamped by
|
|
5
|
+
// scripts/sync_version.mjs and verified by scripts/check_release_version.mjs, so
|
|
6
|
+
// they should never be edited by hand.
|
|
7
|
+
|
|
8
|
+
import fs from "node:fs";
|
|
9
|
+
import path from "node:path";
|
|
10
|
+
|
|
11
|
+
export const VERSION_FILE = "VERSION";
|
|
12
|
+
|
|
13
|
+
// kind -> regex capturing (prefix)(version)(suffix). Non-global on purpose: we
|
|
14
|
+
// only ever replace the first (top-level) occurrence in each file.
|
|
15
|
+
const PATTERNS = {
|
|
16
|
+
json: /("version"\s*:\s*")([^"]*)(")/,
|
|
17
|
+
toml: /^(version\s*=\s*")([^"]*)(")/m,
|
|
18
|
+
pyinit: /^(__version__\s*=\s*")([^"]*)(")/m,
|
|
19
|
+
yaml: /^(version:\s*)(\S+)(.*)$/m,
|
|
20
|
+
};
|
|
21
|
+
|
|
22
|
+
// Every place the version lives, across all agent frameworks and packages.
|
|
23
|
+
export const TARGETS = [
|
|
24
|
+
{ file: "package.json", kind: "json" },
|
|
25
|
+
{ file: "agent-wallet/pyproject.toml", kind: "toml" },
|
|
26
|
+
{ file: "agent-wallet/agent_wallet/__init__.py", kind: "pyinit" },
|
|
27
|
+
{ file: ".openclaw/extensions/agent-wallet/package.json", kind: "json" },
|
|
28
|
+
{ file: "agent-wallet/openclaw.plugin.json", kind: "json" },
|
|
29
|
+
{ file: ".openclaw/extensions/agent-wallet/openclaw.plugin.json", kind: "json" },
|
|
30
|
+
{ file: "codex/plugins/agent-wallet/.codex-plugin/plugin.json", kind: "json" },
|
|
31
|
+
{ file: "claude-code/plugins/agent-wallet/.claude-plugin/plugin.json", kind: "json" },
|
|
32
|
+
{ file: "hermes/plugins/agent_wallet/plugin.yaml", kind: "yaml" },
|
|
33
|
+
{ file: "wdk-btc-wallet/package.json", kind: "json" },
|
|
34
|
+
{ file: "wdk-evm-wallet/package.json", kind: "json" },
|
|
35
|
+
];
|
|
36
|
+
|
|
37
|
+
export function readCanonicalVersion(root) {
|
|
38
|
+
return fs.readFileSync(path.join(root, VERSION_FILE), "utf8").trim();
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
export function readTargetVersion(root, target) {
|
|
42
|
+
const content = fs.readFileSync(path.join(root, target.file), "utf8");
|
|
43
|
+
const match = content.match(PATTERNS[target.kind]);
|
|
44
|
+
return match ? match[2] : null;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
export function stampTarget(root, target, version) {
|
|
48
|
+
const filePath = path.join(root, target.file);
|
|
49
|
+
const content = fs.readFileSync(filePath, "utf8");
|
|
50
|
+
const pattern = PATTERNS[target.kind];
|
|
51
|
+
if (!pattern.test(content)) {
|
|
52
|
+
throw new Error(`No version field found in ${target.file}`);
|
|
53
|
+
}
|
|
54
|
+
const updated = content.replace(pattern, (_m, prefix, _old, suffix) => `${prefix}${version}${suffix}`);
|
|
55
|
+
fs.writeFileSync(filePath, updated);
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
export function npmTagFor(version) {
|
|
59
|
+
return version.includes("-") ? "beta" : "latest";
|
|
60
|
+
}
|
package/wdk-evm-wallet/README.md
CHANGED
|
@@ -18,8 +18,8 @@ Current scope:
|
|
|
18
18
|
- fetch ERC-20 balances
|
|
19
19
|
- fetch ERC-20 token metadata (`name`, `symbol`, `decimals`)
|
|
20
20
|
- fetch fee-rate suggestions
|
|
21
|
-
- fetch read-only Velora swap quotes for supported mainnet ERC-20 pairs
|
|
22
|
-
- execute Velora ERC-20 swaps on supported mainnet networks through the local wallet account
|
|
21
|
+
- fetch read-only Velora swap quotes for supported mainnet ERC-20 and native ETH pairs
|
|
22
|
+
- execute Velora ERC-20 and native ETH swaps on supported mainnet networks through the local wallet account
|
|
23
23
|
- fetch Aave V3 account data on supported mainnet networks
|
|
24
24
|
- fetch Aave V3 reserve catalog on supported mainnet networks
|
|
25
25
|
- fetch Aave V3 per-reserve user positions on supported mainnet networks
|
|
@@ -177,7 +177,7 @@ Local security note:
|
|
|
177
177
|
- unlocked seed phrases live only in memory
|
|
178
178
|
- explicit `lock` or process restart clears the in-memory unlocked state
|
|
179
179
|
- seed reveal is password-gated and separate from normal agent operations
|
|
180
|
-
- Velora swap support is currently limited to `ethereum` and `base` ERC-20 pairs
|
|
180
|
+
- Velora swap support is currently limited to `ethereum` and `base` ERC-20 and native ETH pairs
|
|
181
181
|
- the underlying WDK Velora package is still beta; test swap execution carefully before relying on it
|
|
182
182
|
- Aave V3 support is currently limited to `ethereum` and `base`
|
|
183
183
|
- Aave `supply` and `repay` may perform pool-scoped ERC-20 approvals; if a send fails after approval, the service attempts to restore the original allowance
|
|
@@ -246,6 +246,21 @@ function normalizeEvmTokenAddressAllowingNative(value, fieldName) {
|
|
|
246
246
|
return normalizeAddress(address, fieldName).toLowerCase();
|
|
247
247
|
}
|
|
248
248
|
|
|
249
|
+
function normalizeVeloraTokenAddress(value, fieldName) {
|
|
250
|
+
const raw = assertNonEmptyString(value, fieldName);
|
|
251
|
+
const alias = raw.toLowerCase();
|
|
252
|
+
if (
|
|
253
|
+
alias === "native" ||
|
|
254
|
+
alias === "eth" ||
|
|
255
|
+
alias === "ethereum" ||
|
|
256
|
+
isZeroAddress(raw) ||
|
|
257
|
+
isVeloraNativeTokenAddress(raw)
|
|
258
|
+
) {
|
|
259
|
+
return VELORA_NATIVE_TOKEN_ADDRESS;
|
|
260
|
+
}
|
|
261
|
+
return normalizeAddress(raw, fieldName);
|
|
262
|
+
}
|
|
263
|
+
|
|
249
264
|
function normalizeLifiOutputTokenAddress(value, destinationChainId, fieldName) {
|
|
250
265
|
const raw = assertNonEmptyString(value, fieldName);
|
|
251
266
|
const alias = raw.toLowerCase();
|
|
@@ -380,8 +395,8 @@ function normalizeX402ExactTypedData({ domain, types, primaryType, message }, ru
|
|
|
380
395
|
|
|
381
396
|
function buildSwapRequest({ tokenIn, tokenOut, tokenInAmount }) {
|
|
382
397
|
const swapRequest = {
|
|
383
|
-
tokenIn:
|
|
384
|
-
tokenOut:
|
|
398
|
+
tokenIn: normalizeVeloraTokenAddress(tokenIn, "tokenIn"),
|
|
399
|
+
tokenOut: normalizeVeloraTokenAddress(tokenOut, "tokenOut"),
|
|
385
400
|
tokenInAmount: assertPositiveBigIntString(tokenInAmount, "tokenInAmount"),
|
|
386
401
|
};
|
|
387
402
|
assertDistinctAddresses(swapRequest.tokenIn, "tokenIn", swapRequest.tokenOut, "tokenOut");
|