walletcap 0.2.2__tar.gz → 0.2.4__tar.gz
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.
- {walletcap-0.2.2 → walletcap-0.2.4}/.circleci/config.yml +8 -0
- walletcap-0.2.4/.github/workflows/ci.yml +80 -0
- walletcap-0.2.4/.github/workflows/mcp-registry.yml +47 -0
- walletcap-0.2.4/.github/workflows/publish.yml +100 -0
- walletcap-0.2.4/CHANGELOG.md +77 -0
- {walletcap-0.2.2 → walletcap-0.2.4}/PKG-INFO +97 -30
- {walletcap-0.2.2 → walletcap-0.2.4}/README.md +94 -27
- walletcap-0.2.4/crash-test/README.md +124 -0
- walletcap-0.2.4/crash-test/agent.mjs +100 -0
- walletcap-0.2.4/crash-test/agentkit-agent.mjs +83 -0
- walletcap-0.2.4/crash-test/ci/check-agentkit.mjs +16 -0
- walletcap-0.2.4/crash-test/cli.mjs +264 -0
- walletcap-0.2.4/crash-test/contracts/build.mjs +94 -0
- walletcap-0.2.4/crash-test/contracts/coinbase-base-mainnet.json +27 -0
- walletcap-0.2.4/crash-test/contracts/walletcap.json +501 -0
- walletcap-0.2.4/crash-test/package.json +75 -0
- walletcap-0.2.4/crash-test/spend-permissions.mjs +180 -0
- walletcap-0.2.4/crash-test/spend-store.mjs +86 -0
- walletcap-0.2.4/crash-test/test/crash-test.test.mjs +135 -0
- walletcap-0.2.4/docs/_config.yml +19 -0
- walletcap-0.2.4/docs/coinbase-agentic-wallet-budget.md +85 -0
- walletcap-0.2.4/docs/coinbase-agentkit-spending-limit.md +69 -0
- walletcap-0.2.4/docs/coinbase-cdp-spend-controls.md +85 -0
- walletcap-0.2.4/docs/coinbase-spend-permissions-cap.md +79 -0
- walletcap-0.2.4/docs/index.md +92 -0
- walletcap-0.2.4/docs/llms.txt +39 -0
- walletcap-0.2.4/docs/python-agent-spending-limit.md +83 -0
- walletcap-0.2.4/docs/social-preview.png +0 -0
- {walletcap-0.2.2 → walletcap-0.2.4}/docs/vendor-disclosure.md +1 -1
- walletcap-0.2.4/docs/x402-spending-limit.md +80 -0
- walletcap-0.2.4/glama.json +6 -0
- {walletcap-0.2.2 → walletcap-0.2.4}/js/README.md +12 -1
- {walletcap-0.2.2 → walletcap-0.2.4}/js/agentic.mjs +89 -16
- {walletcap-0.2.2 → walletcap-0.2.4}/js/cli.mjs +2 -1
- {walletcap-0.2.2 → walletcap-0.2.4}/js/index.d.ts +7 -2
- {walletcap-0.2.2 → walletcap-0.2.4}/js/index.mjs +4 -1
- {walletcap-0.2.2 → walletcap-0.2.4}/js/package.json +15 -4
- {walletcap-0.2.2 → walletcap-0.2.4}/js/tests/agentic.test.mjs +67 -3
- walletcap-0.2.4/js/tests/agentkit.test.mjs +80 -0
- {walletcap-0.2.2 → walletcap-0.2.4}/js/tests/support/fake-payments-mcp.mjs +4 -1
- walletcap-0.2.4/js/tests/types/agentkit.d.ts +10 -0
- walletcap-0.2.4/js/tests/types/recipe.ts +8 -0
- walletcap-0.2.4/js/tests/types/subclass.ts +13 -0
- {walletcap-0.2.2 → walletcap-0.2.4}/js/x402.mjs +22 -0
- walletcap-0.2.4/llms.txt +39 -0
- {walletcap-0.2.2 → walletcap-0.2.4}/pyproject.toml +15 -3
- {walletcap-0.2.2 → walletcap-0.2.4}/scripts/ci.sh +7 -0
- walletcap-0.2.4/server.json +53 -0
- {walletcap-0.2.2 → walletcap-0.2.4}/solidity/README.md +15 -9
- {walletcap-0.2.2 → walletcap-0.2.4}/solidity/evm/check.mjs +35 -14
- {walletcap-0.2.2 → walletcap-0.2.4}/solidity/evm/package.json +1 -1
- {walletcap-0.2.2 → walletcap-0.2.4}/solidity/src/AccountCapSpender.sol +42 -37
- {walletcap-0.2.2 → walletcap-0.2.4}/solidity/test/AccountCapSpender.t.sol +45 -3
- {walletcap-0.2.2 → walletcap-0.2.4}/src/walletcap/__init__.py +1 -1
- walletcap-0.2.2/.github/workflows/ci.yml +0 -47
- walletcap-0.2.2/.github/workflows/publish.yml +0 -35
- walletcap-0.2.2/CHANGELOG.md +0 -28
- {walletcap-0.2.2 → walletcap-0.2.4}/.gitignore +0 -0
- {walletcap-0.2.2 → walletcap-0.2.4}/LICENSE +0 -0
- {walletcap-0.2.2 → walletcap-0.2.4}/NOTICE +0 -0
- {walletcap-0.2.2 → walletcap-0.2.4}/SECURITY.md +0 -0
- {walletcap-0.2.2 → walletcap-0.2.4}/docs/threat-model.md +0 -0
- {walletcap-0.2.2 → walletcap-0.2.4}/examples/quickstart/README.md +0 -0
- {walletcap-0.2.2 → walletcap-0.2.4}/examples/quickstart/quickstart.mjs +0 -0
- {walletcap-0.2.2 → walletcap-0.2.4}/examples/quickstart/quickstart.py +0 -0
- {walletcap-0.2.2 → walletcap-0.2.4}/js/LICENSE +0 -0
- {walletcap-0.2.2 → walletcap-0.2.4}/js/NOTICE +0 -0
- {walletcap-0.2.2 → walletcap-0.2.4}/js/_keccak.mjs +0 -0
- {walletcap-0.2.2 → walletcap-0.2.4}/js/cdp.mjs +0 -0
- {walletcap-0.2.2 → walletcap-0.2.4}/js/errors.mjs +0 -0
- {walletcap-0.2.2 → walletcap-0.2.4}/js/ledger.mjs +0 -0
- {walletcap-0.2.2 → walletcap-0.2.4}/js/money.mjs +0 -0
- {walletcap-0.2.2 → walletcap-0.2.4}/js/tests/budget.test.mjs +0 -0
- {walletcap-0.2.2 → walletcap-0.2.4}/js/tests/cdp-sdk.test.mjs +0 -0
- {walletcap-0.2.2 → walletcap-0.2.4}/js/tests/cdp.test.mjs +0 -0
- {walletcap-0.2.2 → walletcap-0.2.4}/js/tests/cli.test.mjs +0 -0
- {walletcap-0.2.2 → walletcap-0.2.4}/js/tests/keccak.test.mjs +0 -0
- {walletcap-0.2.2 → walletcap-0.2.4}/js/tests/money.test.mjs +0 -0
- {walletcap-0.2.2 → walletcap-0.2.4}/js/tests/processes.test.mjs +0 -0
- {walletcap-0.2.2 → walletcap-0.2.4}/js/tests/support/fake-awal/dist/index.js +0 -0
- {walletcap-0.2.2 → walletcap-0.2.4}/js/tests/support/fake-awal/dist/ipcClient.js +0 -0
- {walletcap-0.2.2 → walletcap-0.2.4}/js/tests/support/fake-awal/package.json +0 -0
- {walletcap-0.2.2 → walletcap-0.2.4}/js/tests/support/payer.mjs +0 -0
- {walletcap-0.2.2 → walletcap-0.2.4}/js/tests/support/race.mjs +0 -0
- {walletcap-0.2.2 → walletcap-0.2.4}/js/tests/support/x402-kit.mjs +0 -0
- {walletcap-0.2.2 → walletcap-0.2.4}/js/tests/support/x402-payer.mjs +0 -0
- {walletcap-0.2.2 → walletcap-0.2.4}/js/tests/x402-fetch.test.mjs +0 -0
- {walletcap-0.2.2 → walletcap-0.2.4}/js/tests/x402.test.mjs +0 -0
- {walletcap-0.2.2 → walletcap-0.2.4}/pytest.ini +0 -0
- {walletcap-0.2.2 → walletcap-0.2.4}/solidity/foundry.toml +0 -0
- {walletcap-0.2.2 → walletcap-0.2.4}/solidity/test/Mocks.sol +0 -0
- {walletcap-0.2.2 → walletcap-0.2.4}/src/walletcap/__main__.py +0 -0
- {walletcap-0.2.2 → walletcap-0.2.4}/src/walletcap/_keccak.py +0 -0
- {walletcap-0.2.2 → walletcap-0.2.4}/src/walletcap/budget.py +0 -0
- {walletcap-0.2.2 → walletcap-0.2.4}/src/walletcap/errors.py +0 -0
- {walletcap-0.2.2 → walletcap-0.2.4}/src/walletcap/ledger.py +0 -0
- {walletcap-0.2.2 → walletcap-0.2.4}/src/walletcap/money.py +0 -0
- {walletcap-0.2.2 → walletcap-0.2.4}/src/walletcap/py.typed +0 -0
- {walletcap-0.2.2 → walletcap-0.2.4}/tests/test_budget.py +0 -0
- {walletcap-0.2.2 → walletcap-0.2.4}/tests/test_keccak.py +0 -0
- {walletcap-0.2.2 → walletcap-0.2.4}/tests/test_ledger.py +0 -0
- {walletcap-0.2.2 → walletcap-0.2.4}/tests/test_money.py +0 -0
|
@@ -33,6 +33,14 @@ jobs:
|
|
|
33
33
|
cd solidity/evm
|
|
34
34
|
npm install --no-audit --no-fund --no-package-lock
|
|
35
35
|
node check.mjs ..
|
|
36
|
+
- run:
|
|
37
|
+
name: Crash test
|
|
38
|
+
command: |
|
|
39
|
+
cd crash-test
|
|
40
|
+
npm install --no-audit --no-fund --no-package-lock
|
|
41
|
+
npm install --no-save --no-audit --no-fund --no-package-lock ../js
|
|
42
|
+
node contracts/build.mjs --check
|
|
43
|
+
node --test
|
|
36
44
|
|
|
37
45
|
workflows:
|
|
38
46
|
ci:
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
name: CI
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
pull_request:
|
|
5
|
+
push:
|
|
6
|
+
branches: [main]
|
|
7
|
+
|
|
8
|
+
permissions:
|
|
9
|
+
contents: read
|
|
10
|
+
|
|
11
|
+
jobs:
|
|
12
|
+
javascript:
|
|
13
|
+
name: JavaScript
|
|
14
|
+
runs-on: ubuntu-latest
|
|
15
|
+
container: node:22-bookworm
|
|
16
|
+
steps:
|
|
17
|
+
- uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5
|
|
18
|
+
- name: Install the test dependencies
|
|
19
|
+
run: npm install --no-audit --no-fund
|
|
20
|
+
working-directory: js
|
|
21
|
+
- name: Run the suite
|
|
22
|
+
run: node --test
|
|
23
|
+
working-directory: js
|
|
24
|
+
|
|
25
|
+
python:
|
|
26
|
+
name: Python
|
|
27
|
+
runs-on: ubuntu-latest
|
|
28
|
+
container: node:22-bookworm
|
|
29
|
+
steps:
|
|
30
|
+
- uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5
|
|
31
|
+
- uses: astral-sh/setup-uv@d0cc045d04ccac9d8b7881df0226f9e82c39688e
|
|
32
|
+
- name: Run the suite
|
|
33
|
+
# Node is on PATH here, so the cross-language tests run rather than skip.
|
|
34
|
+
run: uv run --with pytest --python 3.12 pytest -q
|
|
35
|
+
|
|
36
|
+
solidity:
|
|
37
|
+
name: Solidity
|
|
38
|
+
runs-on: ubuntu-latest
|
|
39
|
+
container: node:22-bookworm
|
|
40
|
+
steps:
|
|
41
|
+
- uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5
|
|
42
|
+
- name: Install the check's dependencies
|
|
43
|
+
run: npm install --no-audit --no-fund
|
|
44
|
+
working-directory: solidity/evm
|
|
45
|
+
- name: Drive the contract on an EVM
|
|
46
|
+
run: node check.mjs ..
|
|
47
|
+
working-directory: solidity/evm
|
|
48
|
+
|
|
49
|
+
crash-test:
|
|
50
|
+
name: Crash test
|
|
51
|
+
runs-on: ubuntu-latest
|
|
52
|
+
container: node:22-bookworm
|
|
53
|
+
steps:
|
|
54
|
+
- uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5
|
|
55
|
+
- name: Install the crash test, on this checkout's walletcap
|
|
56
|
+
run: |
|
|
57
|
+
npm install --no-audit --no-fund --no-package-lock
|
|
58
|
+
npm install --no-save --no-audit --no-fund --no-package-lock ../js
|
|
59
|
+
working-directory: crash-test
|
|
60
|
+
- name: Check the shipped contracts match their sources
|
|
61
|
+
run: node contracts/build.mjs --check
|
|
62
|
+
working-directory: crash-test
|
|
63
|
+
- name: Run it
|
|
64
|
+
run: node --test
|
|
65
|
+
working-directory: crash-test
|
|
66
|
+
|
|
67
|
+
crash-test-agentkit:
|
|
68
|
+
name: Crash test (AgentKit)
|
|
69
|
+
runs-on: ubuntu-latest
|
|
70
|
+
container: node:22-bookworm
|
|
71
|
+
steps:
|
|
72
|
+
- uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5
|
|
73
|
+
- name: Pack the crash test
|
|
74
|
+
run: npm pack --pack-destination "$RUNNER_TEMP"
|
|
75
|
+
working-directory: crash-test
|
|
76
|
+
# As users run it: AgentKit installed alongside, walletcap from npm.
|
|
77
|
+
- name: Run it with Coinbase AgentKit alongside
|
|
78
|
+
run: npx -y -p "$RUNNER_TEMP"/walletcap-crash-test-*.tgz -p @coinbase/agentkit@0.10.4 walletcap-crash-test --agentkit --json > "$RUNNER_TEMP/agentkit.json"
|
|
79
|
+
- name: Check the AgentKit row
|
|
80
|
+
run: node crash-test/ci/check-agentkit.mjs "$RUNNER_TEMP/agentkit.json"
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
# SPDX-License-Identifier: Apache-2.0
|
|
2
|
+
# Publish server.json to the official MCP Registry (registry.modelcontextprotocol.io), by hand.
|
|
3
|
+
# Run it once the npm release that server.json names is out: the registry checks that
|
|
4
|
+
# walletcap@<version> on npm carries "mcpName": "io.github.coriolislabs/walletcap".
|
|
5
|
+
# GitHub OIDC proves the io.github.coriolislabs namespace, so no token is stored.
|
|
6
|
+
# (mcp-publisher's interactive GitHub login can't publish to an organization namespace.)
|
|
7
|
+
name: MCP Registry
|
|
8
|
+
|
|
9
|
+
on:
|
|
10
|
+
workflow_dispatch:
|
|
11
|
+
|
|
12
|
+
permissions:
|
|
13
|
+
contents: read
|
|
14
|
+
id-token: write
|
|
15
|
+
|
|
16
|
+
jobs:
|
|
17
|
+
publish:
|
|
18
|
+
name: Publish server.json
|
|
19
|
+
runs-on: ubuntu-latest
|
|
20
|
+
env:
|
|
21
|
+
MCP_PUBLISHER_VERSION: v1.8.7
|
|
22
|
+
steps:
|
|
23
|
+
- uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5
|
|
24
|
+
- name: Check server.json names the npm package's version and mcpName
|
|
25
|
+
run: |
|
|
26
|
+
test "$(jq -r .version server.json)" = "$(jq -r .version js/package.json)"
|
|
27
|
+
test "$(jq -r '.packages[0].version' server.json)" = "$(jq -r .version js/package.json)"
|
|
28
|
+
test "$(jq -r .name server.json)" = "$(jq -r .mcpName js/package.json)"
|
|
29
|
+
- uses: sigstore/cosign-installer@6f9f17788090df1f26f669e9d70d6ae9567deba6 # v4.1.2
|
|
30
|
+
- name: Download mcp-publisher and verify its Sigstore bundle
|
|
31
|
+
run: |
|
|
32
|
+
set -euo pipefail
|
|
33
|
+
archive=mcp-publisher_linux_amd64.tar.gz
|
|
34
|
+
base_url="https://github.com/modelcontextprotocol/registry/releases/download/${MCP_PUBLISHER_VERSION}"
|
|
35
|
+
curl --fail --location --silent --show-error --output "$archive" "$base_url/$archive"
|
|
36
|
+
curl --fail --location --silent --show-error --output "$archive.sigstore.json" "$base_url/$archive.sigstore.json"
|
|
37
|
+
cosign verify-blob \
|
|
38
|
+
--bundle "$archive.sigstore.json" \
|
|
39
|
+
--certificate-identity "https://github.com/modelcontextprotocol/registry/.github/workflows/release.yml@refs/tags/${MCP_PUBLISHER_VERSION}" \
|
|
40
|
+
--certificate-oidc-issuer "https://token.actions.githubusercontent.com" \
|
|
41
|
+
"$archive"
|
|
42
|
+
tar xzf "$archive" mcp-publisher
|
|
43
|
+
rm -f "$archive" "$archive.sigstore.json"
|
|
44
|
+
- name: Log in to the registry with GitHub OIDC
|
|
45
|
+
run: ./mcp-publisher login github-oidc
|
|
46
|
+
- name: Publish server.json
|
|
47
|
+
run: ./mcp-publisher publish
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
# SPDX-License-Identifier: Apache-2.0
|
|
2
|
+
# Publish when a GitHub Release is published, or by hand.
|
|
3
|
+
# - A release tagged v<version> publishes walletcap to PyPI and npm.
|
|
4
|
+
# - A release tagged crash-test-v<version> publishes walletcap-crash-test to npm, and nothing else.
|
|
5
|
+
# Everything uses trusted publishing, so no token is stored. PyPI matches this repository,
|
|
6
|
+
# the workflow filename (publish.yml) and the "pypi" environment, and attaches PEP 740
|
|
7
|
+
# attestations. npm matches this repository, publish.yml and the "npm" environment, for
|
|
8
|
+
# each of the two packages, and attaches provenance.
|
|
9
|
+
name: Publish
|
|
10
|
+
|
|
11
|
+
on:
|
|
12
|
+
release:
|
|
13
|
+
types: [published]
|
|
14
|
+
workflow_dispatch:
|
|
15
|
+
|
|
16
|
+
permissions:
|
|
17
|
+
contents: read
|
|
18
|
+
id-token: write
|
|
19
|
+
|
|
20
|
+
jobs:
|
|
21
|
+
pypi:
|
|
22
|
+
name: PyPI
|
|
23
|
+
if: github.event_name != 'release' || !startsWith(github.event.release.tag_name, 'crash-test-v')
|
|
24
|
+
runs-on: ubuntu-latest
|
|
25
|
+
environment: pypi
|
|
26
|
+
steps:
|
|
27
|
+
- uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5
|
|
28
|
+
- uses: actions/setup-python@a26af69be951a213d495a4c3e4e4022e16d87065
|
|
29
|
+
with:
|
|
30
|
+
python-version: "3.12"
|
|
31
|
+
- name: Check the release tag matches the package version
|
|
32
|
+
if: github.event_name == 'release'
|
|
33
|
+
env:
|
|
34
|
+
TAG: ${{ github.event.release.tag_name }}
|
|
35
|
+
run: test "$TAG" = "v$(python -c "import tomllib; print(tomllib.load(open('pyproject.toml', 'rb'))['project']['version'])")"
|
|
36
|
+
- name: Run the Python suite
|
|
37
|
+
run: |
|
|
38
|
+
python -m pip install --upgrade pytest
|
|
39
|
+
python -m pytest -q
|
|
40
|
+
- name: Build the distributions
|
|
41
|
+
run: |
|
|
42
|
+
python -m pip install --upgrade build
|
|
43
|
+
python -m build
|
|
44
|
+
- name: Publish to PyPI
|
|
45
|
+
uses: pypa/gh-action-pypi-publish@7245906fb61fa33a13554f9d5fb856fe61758086 # v1.14.3
|
|
46
|
+
|
|
47
|
+
npm:
|
|
48
|
+
name: npm
|
|
49
|
+
if: github.event_name != 'release' || !startsWith(github.event.release.tag_name, 'crash-test-v')
|
|
50
|
+
runs-on: ubuntu-latest
|
|
51
|
+
environment: npm
|
|
52
|
+
steps:
|
|
53
|
+
- uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5
|
|
54
|
+
- uses: actions/setup-node@949feb2413d6458794dcd2491c4babbbce0c15c1 # v7.1.0
|
|
55
|
+
with:
|
|
56
|
+
node-version: "22"
|
|
57
|
+
registry-url: "https://registry.npmjs.org"
|
|
58
|
+
package-manager-cache: false
|
|
59
|
+
- name: Use an npm that supports trusted publishing (11.5.1 or later)
|
|
60
|
+
run: npm install --global npm@11.21.1
|
|
61
|
+
- name: Check the release tag matches the package version
|
|
62
|
+
if: github.event_name == 'release'
|
|
63
|
+
env:
|
|
64
|
+
TAG: ${{ github.event.release.tag_name }}
|
|
65
|
+
run: test "$TAG" = "v$(node -p "require('./js/package.json').version")"
|
|
66
|
+
- name: Run the JavaScript suite
|
|
67
|
+
working-directory: js
|
|
68
|
+
run: |
|
|
69
|
+
npm install --no-audit --no-fund --no-package-lock
|
|
70
|
+
node --test
|
|
71
|
+
- name: Publish to npm with provenance
|
|
72
|
+
working-directory: js
|
|
73
|
+
run: npm publish --provenance
|
|
74
|
+
|
|
75
|
+
crash-test:
|
|
76
|
+
name: npm (crash test)
|
|
77
|
+
if: github.event_name == 'release' && startsWith(github.event.release.tag_name, 'crash-test-v')
|
|
78
|
+
runs-on: ubuntu-latest
|
|
79
|
+
environment: npm
|
|
80
|
+
steps:
|
|
81
|
+
- uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5
|
|
82
|
+
- uses: actions/setup-node@949feb2413d6458794dcd2491c4babbbce0c15c1 # v7.1.0
|
|
83
|
+
with:
|
|
84
|
+
node-version: "22"
|
|
85
|
+
registry-url: "https://registry.npmjs.org"
|
|
86
|
+
package-manager-cache: false
|
|
87
|
+
- name: Use an npm that supports trusted publishing (11.5.1 or later)
|
|
88
|
+
run: npm install --global npm@11.21.1
|
|
89
|
+
- name: Check the release tag matches the package version
|
|
90
|
+
env:
|
|
91
|
+
TAG: ${{ github.event.release.tag_name }}
|
|
92
|
+
run: test "$TAG" = "crash-test-v$(node -p "require('./crash-test/package.json').version")"
|
|
93
|
+
- name: Run the crash test on the walletcap users get from npm
|
|
94
|
+
working-directory: crash-test
|
|
95
|
+
run: |
|
|
96
|
+
npm install --no-audit --no-fund --no-package-lock
|
|
97
|
+
node --test
|
|
98
|
+
- name: Publish to npm with provenance
|
|
99
|
+
working-directory: crash-test
|
|
100
|
+
run: npm publish --provenance
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
<!-- SPDX-License-Identifier: Apache-2.0 -->
|
|
2
|
+
# Changelog
|
|
3
|
+
|
|
4
|
+
## 0.2.4 — 2026-11-06
|
|
5
|
+
|
|
6
|
+
### Added
|
|
7
|
+
|
|
8
|
+
- `mcpName` in the npm package and a `server.json`, so `walletcap awal-mcp` can be listed in the
|
|
9
|
+
official MCP Registry as `io.github.coriolislabs/walletcap`. `glama.json` names the maintainer
|
|
10
|
+
for Glama.
|
|
11
|
+
- A docs site, https://coriolislabs.github.io/WalletCap/, with one page per integration, and
|
|
12
|
+
`llms.txt`.
|
|
13
|
+
|
|
14
|
+
### Fixed
|
|
15
|
+
|
|
16
|
+
- The `create` doc comment in `index.d.ts` said it defaulted to true. It defaults to false.
|
|
17
|
+
|
|
18
|
+
### Changed
|
|
19
|
+
|
|
20
|
+
- Package descriptions and search keywords on npm and PyPI, and a README that leads with the
|
|
21
|
+
crash test.
|
|
22
|
+
|
|
23
|
+
## 0.2.3 — 2026-11-06
|
|
24
|
+
|
|
25
|
+
### Changed
|
|
26
|
+
|
|
27
|
+
- Releases are published from GitHub Actions with trusted publishing: npm with provenance,
|
|
28
|
+
PyPI with PEP 740 attestations. No token is stored. A GitHub Release whose tag doesn't
|
|
29
|
+
match the package version is refused.
|
|
30
|
+
|
|
31
|
+
### Fixed
|
|
32
|
+
|
|
33
|
+
- `AccountCapSpender` no longer locks an account after a burst of payments. An unbounded log
|
|
34
|
+
made the first payment after 3,000 tiny ones cost about 17.7M gas, past the 2^24
|
|
35
|
+
per-transaction cap. The window is now counted in 24 buckets in a fixed ring of 25 slots, so
|
|
36
|
+
every `pay` costs the same gas. A payment counts for up to one bucket (window/24) past its
|
|
37
|
+
window, never less. The window must be a multiple of 24 seconds.
|
|
38
|
+
- `walletcap awal-mcp` ran `npx -y @coinbase/payments-mcp`, which is Coinbase's installer, not
|
|
39
|
+
the MCP server. It now runs the installed server, `~/.payments-mcp/bundle.js`, and says how to
|
|
40
|
+
install it when it is missing.
|
|
41
|
+
- `walletcap awal-mcp` forwarded every tool it didn't count. It now passes through only the
|
|
42
|
+
tools that move no money, and counts `send` and `make_http_request_with_x402`. It refuses
|
|
43
|
+
everything else, `trade` included, and leaves those tools out of `tools/list`, unless the
|
|
44
|
+
owner names one with `--allow-tool`. JSON-RPC batches and lines that aren't JSON are refused.
|
|
45
|
+
|
|
46
|
+
### Added
|
|
47
|
+
|
|
48
|
+
- `budget.guardAgentKit(provider)` puts the budget on every x402 client an AgentKit
|
|
49
|
+
`X402ActionProvider` builds. The README's subclass recipe didn't compile in TypeScript,
|
|
50
|
+
where `createX402Client` is private. `tsc` now checks the recipe against AgentKit's declared
|
|
51
|
+
types in the test suite.
|
|
52
|
+
|
|
53
|
+
## 0.2.2 — 2026-11-05
|
|
54
|
+
|
|
55
|
+
### Changed
|
|
56
|
+
|
|
57
|
+
- A mixed-case EVM address is checked against EIP-55 before it is accepted. A bad
|
|
58
|
+
checksum is refused; all-lowercase and all-uppercase hex are still accepted.
|
|
59
|
+
- A Solana CAIP-10 address is reduced to its address, so it and the bare address
|
|
60
|
+
share one budget.
|
|
61
|
+
- Numeric `window` values are milliseconds in Python too, matching JavaScript.
|
|
62
|
+
|
|
63
|
+
### Fixed
|
|
64
|
+
|
|
65
|
+
- The rolling window cannot be shortened once the budget has spend. An edit can
|
|
66
|
+
change the cap and the per-payment limit, but it cannot reset the count by
|
|
67
|
+
shrinking the window.
|
|
68
|
+
|
|
69
|
+
### Added
|
|
70
|
+
|
|
71
|
+
- `SECURITY.md`, `docs/threat-model.md`, `docs/vendor-disclosure.md`, and the
|
|
72
|
+
Solidity audit status in `solidity/README.md`.
|
|
73
|
+
- `examples/quickstart/` in JavaScript and Python, run in CI. No wallet, chain,
|
|
74
|
+
keys or network.
|
|
75
|
+
- EIP-55, Solana CAIP-10, and window-freeze tests in both languages.
|
|
76
|
+
|
|
77
|
+
## 0.2.1 — 2026-11-05
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
Metadata-Version: 2.5
|
|
2
2
|
Name: walletcap
|
|
3
|
-
Version: 0.2.
|
|
4
|
-
Summary:
|
|
3
|
+
Version: 0.2.4
|
|
4
|
+
Summary: Spend limits for AI agent wallets: a per-payment cap and rolling 24-hour budget that holds across restarts, kept in a SQLite file every process and the npm package share.
|
|
5
5
|
Project-URL: Homepage, https://github.com/coriolislabs/WalletCap
|
|
6
6
|
Project-URL: Repository, https://github.com/coriolislabs/WalletCap
|
|
7
7
|
Project-URL: Issues, https://github.com/coriolislabs/WalletCap/issues
|
|
@@ -9,7 +9,7 @@ Author: Coriolis Labs Inc.
|
|
|
9
9
|
License-Expression: Apache-2.0
|
|
10
10
|
License-File: LICENSE
|
|
11
11
|
License-File: NOTICE
|
|
12
|
-
Keywords: agent-payments,ai-agents,budget,guardrails,spend-limit,stablecoin,usdc,x402
|
|
12
|
+
Keywords: agent-payments,agent-wallet,ai-agent,ai-agents,budget,guardrails,spend-limit,spending-limit,stablecoin,usdc,x402
|
|
13
13
|
Classifier: Development Status :: 4 - Beta
|
|
14
14
|
Classifier: Intended Audience :: Developers
|
|
15
15
|
Classifier: Programming Language :: Python :: 3
|
|
@@ -22,19 +22,63 @@ Requires-Python: >=3.11
|
|
|
22
22
|
Description-Content-Type: text/markdown
|
|
23
23
|
|
|
24
24
|
<!-- SPDX-License-Identifier: Apache-2.0 -->
|
|
25
|
-
# walletcap
|
|
25
|
+
# walletcap: spend limits for AI agent wallets
|
|
26
26
|
|
|
27
|
-
[](https://www.npmjs.com/package/walletcap)
|
|
28
|
+
[](https://pypi.org/project/walletcap/)
|
|
29
|
+
[](https://github.com/coriolislabs/WalletCap/actions/workflows/ci.yml)
|
|
30
|
+
[](https://github.com/coriolislabs/WalletCap/blob/main/LICENSE)
|
|
28
31
|
|
|
29
|
-
**
|
|
32
|
+
**Spend limits for AI agent wallets that pay in USDC: a per-payment cap and a rolling 24-hour
|
|
33
|
+
budget that holds across restarts, replicas and payment rails.** walletcap plugs into x402
|
|
34
|
+
clients, Coinbase CDP's x402 spend controls, Coinbase AgentKit, the Coinbase Agentic Wallet CLI
|
|
35
|
+
and payments MCP server, and Coinbase Spend Permissions. By ShadowPath.
|
|
30
36
|
|
|
31
|
-
|
|
32
|
-
period. So a restart, a second replica, one more key, or the next period hands the agent a
|
|
33
|
-
fresh budget. walletcap counts **per wallet**: one budget that every process,
|
|
34
|
-
replica, key, permission and payment rail spends from.
|
|
37
|
+
## Crash test: CDP's controls let $1,600–$1,700 past a $150 cap, walletcap lets $0
|
|
35
38
|
|
|
36
|
-
|
|
37
|
-
|
|
39
|
+
`npx walletcap-crash-test` puts Coinbase's agent spend controls through four ordinary events (a
|
|
40
|
+
restart, 10 replicas, 10 replicas on a shared store, and a payee who asks for EURC), then puts
|
|
41
|
+
walletcap through the same events. CDP's x402 controls are set as Coinbase's README shows, then
|
|
42
|
+
run again on walletcap's `cdpStore` as this README shows. Spend Permissions run Coinbase's
|
|
43
|
+
deployed contract code on a local EVM. Every agent is held to $50 a payment and $150 in any 24
|
|
44
|
+
hours, in USDC on Base. It runs offline in about 15 seconds and sends nothing.
|
|
45
|
+
|
|
46
|
+
```console
|
|
47
|
+
$ npx walletcap-crash-test
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
| CDP x402 spend controls | CDP's controls | walletcap guard | walletcap cdpStore |
|
|
51
|
+
|---|---|---|---|
|
|
52
|
+
| restart, then pay again | $300 signed · $150 over | $150 signed · $0 over | $150 signed · $0 over |
|
|
53
|
+
| 10 replicas | $1,500 signed · $1,350 over | $150 signed · $0 over | $150 signed · $0 over |
|
|
54
|
+
| 10 replicas, shared store 1 ms away | $350 signed · $200 over | $150 signed · $0 over | $150 signed · $0 over |
|
|
55
|
+
| payee asks for EURC, not USDC | 1,000 EURC signed, counted as $0 | refused before signing | refused before signing |
|
|
56
|
+
|
|
57
|
+
| Spend Permissions | SpendPermissionManager | AccountCapSpender |
|
|
58
|
+
|---|---|---|
|
|
59
|
+
| a second permission | $300 pulled · $150 over | $150 pulled · $0 over |
|
|
60
|
+
| across a period boundary, 1 second apart | $300 pulled · $150 over | $150 pulled · $0 over |
|
|
61
|
+
|
|
62
|
+
Past the $150 cap: $1,700 and 1,000 EURC with CDP's controls, $300 with Spend Permissions; $0
|
|
63
|
+
with walletcap's guard, its cdpStore and AccountCapSpender. The shared-store row varies from
|
|
64
|
+
run to run: in eight runs on 6 November 2026 it was $100 over five times and $200 over three
|
|
65
|
+
times. Those runs used `@coinbase/cdp-sdk` 1.61.0, `@x402/core` 2.30.0, SpendPermissionManager
|
|
66
|
+
1.0.0 and walletcap 0.2.3.
|
|
67
|
+
|
|
68
|
+
Add `--agentkit` for Coinbase AgentKit's row: the agent approves a 1¢ offer, and AgentKit signs
|
|
69
|
+
the merchant's first-listed $1.00 on Base mainnet. walletcap, at 2¢ a payment, refuses it before
|
|
70
|
+
signing. [The crash test's README](https://github.com/coriolislabs/WalletCap/tree/main/crash-test)
|
|
71
|
+
says exactly what runs.
|
|
72
|
+
|
|
73
|
+
## Install and use
|
|
74
|
+
|
|
75
|
+
```console
|
|
76
|
+
$ npm install walletcap # Node 22.13+, no dependencies
|
|
77
|
+
$ pip install walletcap # Python 3.11+, no dependencies
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
The owner creates the budget once. Opening it never creates one; pass `create: true` only for a
|
|
81
|
+
demo or first-run setup:
|
|
38
82
|
|
|
39
83
|
```console
|
|
40
84
|
$ npx walletcap set --wallet 0xYourAgentWallet --per-payment 50 --per-day 150
|
|
@@ -57,8 +101,18 @@ with budget.pay("$12.50"):
|
|
|
57
101
|
send_usdc(payee, "12.50")
|
|
58
102
|
```
|
|
59
103
|
|
|
60
|
-
|
|
61
|
-
|
|
104
|
+
| Integration | Install | Use |
|
|
105
|
+
|---|---|---|
|
|
106
|
+
| [Any x402 client](https://github.com/coriolislabs/WalletCap/blob/main/docs/x402-spending-limit.md) (`@x402/core`, `@x402/fetch`) | `npm install walletcap` | `budget.guard(client)` |
|
|
107
|
+
| [Coinbase CDP x402 spend controls](https://github.com/coriolislabs/WalletCap/blob/main/docs/coinbase-cdp-spend-controls.md) | `npm install walletcap @coinbase/cdp-sdk` | `store: budget.cdpStore({ asset: USDC })` in `applySpendControls` |
|
|
108
|
+
| [Coinbase AgentKit](https://github.com/coriolislabs/WalletCap/blob/main/docs/coinbase-agentkit-spending-limit.md) | `npm install walletcap @coinbase/agentkit` | `budget.guardAgentKit(new X402ActionProvider())` |
|
|
109
|
+
| [Coinbase Agentic Wallet CLI](https://github.com/coriolislabs/WalletCap/blob/main/docs/coinbase-agentic-wallet-budget.md) | `npm install walletcap awal` | `npx walletcap awal x402 pay <url>` |
|
|
110
|
+
| [Coinbase payments MCP server](https://github.com/coriolislabs/WalletCap/blob/main/docs/coinbase-agentic-wallet-budget.md#the-mcp-server-one-entry-in-the-clients-config) | `npx @coinbase/payments-mcp install --client other --no-auto-config` | MCP server command: `npx walletcap awal-mcp --wallet 0x…` |
|
|
111
|
+
| [Coinbase Spend Permissions](https://github.com/coriolislabs/WalletCap/blob/main/docs/coinbase-spend-permissions-cap.md) | deploy `solidity/src/AccountCapSpender.sol` (testnet only, unaudited) | the agent calls `pay(permission, amount, payee)` |
|
|
112
|
+
| [Python](https://github.com/coriolislabs/WalletCap/blob/main/docs/python-agent-spending-limit.md) | `pip install walletcap` | `with budget.pay("$12.50"):` |
|
|
113
|
+
|
|
114
|
+
Each link opens a page with a full snippet. The [Use it](#use-it) section below covers every
|
|
115
|
+
integration too.
|
|
62
116
|
|
|
63
117
|
## Try it without a wallet
|
|
64
118
|
|
|
@@ -209,16 +263,23 @@ $ npx walletcap awal x402 pay https://api.example.com/data # instead of: npx a
|
|
|
209
263
|
$ npx walletcap awal send 0.05 0xRecipient --chain base # instead of: npx awal send …
|
|
210
264
|
```
|
|
211
265
|
|
|
212
|
-
For an MCP client such as Claude Desktop, start Coinbase's server behind walletcap.
|
|
213
|
-
`npx
|
|
266
|
+
For an MCP client such as Claude Desktop, start Coinbase's server behind walletcap. Install the
|
|
267
|
+
server once: `npx @coinbase/payments-mcp install --client other --no-auto-config` puts it in
|
|
268
|
+
`~/.payments-mcp`, and walletcap runs `~/.payments-mcp/bundle.js` from there. (`npx
|
|
269
|
+
@coinbase/payments-mcp` is the installer, not the server.) To run another server, put its
|
|
270
|
+
command after `--`.
|
|
214
271
|
|
|
215
272
|
```json
|
|
216
273
|
{ "mcpServers": { "payments": { "command": "npx", "args": ["walletcap", "awal-mcp", "--wallet", "0xYourAgentWallet"] } } }
|
|
217
274
|
```
|
|
218
275
|
|
|
219
276
|
- `send` and `x402 pay` (over MCP, `send` and `make_http_request_with_x402`) are checked against
|
|
220
|
-
the wallet's budget before the wallet signs anything, and counted. Every other command
|
|
221
|
-
|
|
277
|
+
the wallet's budget before the wallet signs anything, and counted. Every other CLI command is
|
|
278
|
+
the wallet's own.
|
|
279
|
+
- Over MCP, the tools that move no money (balance, address, sign-in, bazaar search, payment
|
|
280
|
+
discovery) pass through. Any other tool, `trade` or one the server adds later, is refused and
|
|
281
|
+
left out of the tool list: walletcap can't count it. `--allow-tool <name>` lets one through,
|
|
282
|
+
uncounted. JSON-RPC batches are refused.
|
|
222
283
|
- An x402 payment is priced from the endpoint's own 402 answer, and the wallet is capped at exactly
|
|
223
284
|
that amount, so it refuses to sign for more.
|
|
224
285
|
- A payment the payee confirms as settled counts for one window. One it doesn't confirm keeps
|
|
@@ -234,21 +295,20 @@ For an MCP client such as Claude Desktop, start Coinbase's server behind walletc
|
|
|
234
295
|
|
|
235
296
|
### Coinbase AgentKit
|
|
236
297
|
|
|
237
|
-
AgentKit's x402 actions build their own x402 client on every call.
|
|
238
|
-
|
|
239
|
-
is signed, whatever terms the merchant sends:
|
|
298
|
+
AgentKit's x402 actions build their own x402 client on every call. `budget.guardAgentKit()` puts
|
|
299
|
+
the budget on every client the provider builds, so each payment is checked against the wallet's
|
|
300
|
+
budget before it is signed, whatever terms the merchant sends:
|
|
240
301
|
|
|
241
302
|
```js
|
|
242
303
|
import { X402ActionProvider } from '@coinbase/agentkit';
|
|
243
304
|
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
return budget.guard(await super.createX402Client(walletProvider));
|
|
247
|
-
}
|
|
248
|
-
}
|
|
249
|
-
// AgentKit.from({ walletProvider, actionProviders: [new BudgetedX402ActionProvider()] })
|
|
305
|
+
const x402 = budget.guardAgentKit(new X402ActionProvider());
|
|
306
|
+
// AgentKit.from({ walletProvider, actionProviders: [x402] })
|
|
250
307
|
```
|
|
251
308
|
|
|
309
|
+
It compiles in TypeScript, where a subclass can't override AgentKit's private
|
|
310
|
+
`createX402Client`. Tested against the shape of AgentKit 0.10.4.
|
|
311
|
+
|
|
252
312
|
### Coinbase Spend Permissions, on chain
|
|
253
313
|
|
|
254
314
|
For a limit the agent's own code can't go around, `solidity/src/AccountCapSpender.sol` is the
|
|
@@ -256,7 +316,9 @@ spender for Spend Permissions. Deploy it with the SpendPermissionManager, the ag
|
|
|
256
316
|
address, the cap, the window, the per-payment max and the payees allowed. Grant Spend
|
|
257
317
|
Permissions to the contract instead of the agent; the agent calls
|
|
258
318
|
`pay(permission, amount, payee)`. Every permission the account grants it then shares one
|
|
259
|
-
rolling cap.
|
|
319
|
+
rolling cap. The window is counted in 24 buckets, so every payment costs the same gas however
|
|
320
|
+
many came before it; a payment counts for up to one bucket (window/24) past its window, never
|
|
321
|
+
less.
|
|
260
322
|
|
|
261
323
|
## The owner's controls
|
|
262
324
|
|
|
@@ -313,10 +375,13 @@ only for a demo or a first-run setup.
|
|
|
313
375
|
| `js/` | the npm package `walletcap`: the budget, the x402 guard, the CDP store, the CLI, and the Agentic Wallet CLI wrapper and MCP proxy |
|
|
314
376
|
| `src/walletcap/` | the PyPI package `walletcap`, on the same file format |
|
|
315
377
|
| `solidity/` | `AccountCapSpender`, the on-chain cap for Coinbase Spend Permissions |
|
|
378
|
+
| `crash-test/` | the crash test: CDP's spend controls and walletcap through the same events, in dollars |
|
|
316
379
|
| `tests/` | the Python suite, including the tests that drive both languages against one budget file |
|
|
380
|
+
| `docs/` | the docs site for GitHub Pages: one page per integration, each with a full snippet, plus the threat model |
|
|
381
|
+
| `llms.txt` | a summary of the package and links to the docs, for language models |
|
|
317
382
|
|
|
318
383
|
```console
|
|
319
|
-
$ cd js && npm install && node --test #
|
|
384
|
+
$ cd js && npm install && node --test # 65 tests
|
|
320
385
|
$ uv run --with pytest pytest -q # 59 tests, from the repository root
|
|
321
386
|
$ cd solidity/evm && npm install && node check.mjs .. # the contract on an EVM, no Foundry needed
|
|
322
387
|
$ cd solidity && forge test # the contract's canonical tests, if you have Foundry
|
|
@@ -324,7 +389,9 @@ $ cd solidity && forge test # the contract's canonical test
|
|
|
324
389
|
|
|
325
390
|
The JavaScript suite runs the x402 guard against x402's own client and fetch wrapper, and runs
|
|
326
391
|
restarts and racing replicas as separate processes, and drives the Agentic Wallet wrapper and
|
|
327
|
-
MCP proxy against stand-ins for Coinbase's wallet and MCP server.
|
|
392
|
+
MCP proxy against stand-ins for Coinbase's wallet and MCP server. It builds AgentKit's x402
|
|
393
|
+
client the way AgentKit 0.10.4 does, and type-checks the AgentKit recipe with `tsc` against
|
|
394
|
+
AgentKit's declared types. The Python suite covers the ledger, the API,
|
|
328
395
|
the CLI and one budget shared between both languages. `solidity/evm/check.mjs` compiles the
|
|
329
396
|
contract with solc-js and drives it on an in-process EVM, covering what the Foundry tests cover.
|
|
330
397
|
|