tollkit-wallet 0.0.0-stage → 0.1.0

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.
Files changed (79) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +102 -2
  3. package/THIRD_PARTY_NOTICES.md +13 -0
  4. package/dist/actions.d.ts +141 -0
  5. package/dist/actions.js +80 -0
  6. package/dist/actions.js.map +1 -0
  7. package/dist/agentkit.d.ts +24 -0
  8. package/dist/agentkit.js +40 -0
  9. package/dist/agentkit.js.map +1 -0
  10. package/dist/approvals.d.ts +21 -0
  11. package/dist/approvals.js +71 -0
  12. package/dist/approvals.js.map +1 -0
  13. package/dist/chains.d.ts +16 -0
  14. package/dist/chains.js +26 -0
  15. package/dist/chains.js.map +1 -0
  16. package/dist/cli.d.ts +2 -0
  17. package/dist/cli.js +206 -0
  18. package/dist/cli.js.map +1 -0
  19. package/dist/coin-icons.d.ts +9 -0
  20. package/dist/coin-icons.js +7 -0
  21. package/dist/coin-icons.js.map +1 -0
  22. package/dist/dashboard.d.ts +15 -0
  23. package/dist/dashboard.js +158 -0
  24. package/dist/dashboard.js.map +1 -0
  25. package/dist/elizaos.d.ts +45 -0
  26. package/dist/elizaos.js +134 -0
  27. package/dist/elizaos.js.map +1 -0
  28. package/dist/index.d.ts +10 -0
  29. package/dist/index.js +7 -0
  30. package/dist/index.js.map +1 -0
  31. package/dist/keystore.d.ts +53 -0
  32. package/dist/keystore.js +87 -0
  33. package/dist/keystore.js.map +1 -0
  34. package/dist/ledger.d.ts +40 -0
  35. package/dist/ledger.js +115 -0
  36. package/dist/ledger.js.map +1 -0
  37. package/dist/mcp.d.ts +8 -0
  38. package/dist/mcp.js +40 -0
  39. package/dist/mcp.js.map +1 -0
  40. package/dist/paths.d.ts +9 -0
  41. package/dist/paths.js +18 -0
  42. package/dist/paths.js.map +1 -0
  43. package/dist/pay.d.ts +85 -0
  44. package/dist/pay.js +310 -0
  45. package/dist/pay.js.map +1 -0
  46. package/dist/policy.d.ts +63 -0
  47. package/dist/policy.js +69 -0
  48. package/dist/policy.js.map +1 -0
  49. package/dist/prices.d.ts +28 -0
  50. package/dist/prices.js +41 -0
  51. package/dist/prices.js.map +1 -0
  52. package/dist/sanctions.d.ts +22 -0
  53. package/dist/sanctions.js +76 -0
  54. package/dist/sanctions.js.map +1 -0
  55. package/dist/seller.d.ts +21 -0
  56. package/dist/seller.js +21 -0
  57. package/dist/seller.js.map +1 -0
  58. package/dist/send.d.ts +23 -0
  59. package/dist/send.js +71 -0
  60. package/dist/send.js.map +1 -0
  61. package/dist/swap.d.ts +54 -0
  62. package/dist/swap.js +120 -0
  63. package/dist/swap.js.map +1 -0
  64. package/dist/telegram.d.ts +12 -0
  65. package/dist/telegram.js +58 -0
  66. package/dist/telegram.js.map +1 -0
  67. package/dist/tokens.d.ts +11 -0
  68. package/dist/tokens.js +62 -0
  69. package/dist/tokens.js.map +1 -0
  70. package/dist/ui.d.ts +1 -0
  71. package/dist/ui.js +247 -0
  72. package/dist/ui.js.map +1 -0
  73. package/dist/wallet.d.ts +131 -0
  74. package/dist/wallet.js +329 -0
  75. package/dist/wallet.js.map +1 -0
  76. package/dist/watch.d.ts +66 -0
  77. package/dist/watch.js +234 -0
  78. package/dist/watch.js.map +1 -0
  79. package/package.json +91 -4
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Tollkit LLC
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md CHANGED
@@ -1,3 +1,103 @@
1
- # Temporary Holding Version
1
+ # Tollkit Wallet
2
2
 
3
- This version is a temporary placeholder for this package. An operational version to replace this has been submitted for review and is awaiting a staged release.
3
+ A wallet for AI trading agents. It holds its keys on your computer, encrypted with your password, and lets an agent:
4
+
5
+ - swap tokens on Base and Ethereum (via 0x) and Solana (via Jupiter)
6
+ - pay for APIs that charge per call (x402 and MPP, in USDC or USDT)
7
+
8
+ All of it happens inside limits that you set and the agent can't change.
9
+
10
+ ## What it checks before spending
11
+
12
+ - **Limits:** per trade, per day, per payment, and per seller per day. These are counted under a lock, so parallel calls can't overspend.
13
+ - **Approval:** anything over your threshold waits for you to tap Approve in Telegram. No answer means no.
14
+ - **Sanctions:** every payment recipient is screened against the OFAC list.
15
+ - **Seller check:** the seller's price and pay-to address are compared with its public listing (Tollkit Weigh Station).
16
+ - **Swap safety:** the fee must be no more than 0.5%, the only contract ever approved is 0x AllowanceHolder (for exact amounts), and a minimum output is always set.
17
+ - **Receipts:** every trade and payment is logged, and you can export them as CSV.
18
+
19
+ ## Fees
20
+
21
+ Swaps cost a flat 0.5%, shown before every trade. On some Base and Ethereum pairs, 0x charges its own 0.15% on top, and this is shown separately. Payments for APIs carry no Tollkit fee.
22
+
23
+ ## Setup
24
+
25
+ ```
26
+ npm install -g tollkit-wallet
27
+ tollkit-wallet init # choose a password; prints your Base/Ethereum and Solana addresses
28
+ tollkit-wallet budget # see limits; change with e.g. budget per_trade_usd=100
29
+ tollkit-wallet telegram <bot-token> <chat-id> # optional: approvals in Telegram
30
+ ```
31
+
32
+ Then fund the addresses. Base and Solana are on by default; turn Ethereum on with `tollkit-wallet budget chains=base,solana,ethereum` (its network fees are higher).
33
+
34
+ ## Withdrawals
35
+
36
+ Funds can only be withdrawn to addresses you've saved, and saving one needs your password:
37
+
38
+ ```
39
+ tollkit-wallet addresses add base 0xYourAddress "my coinbase"
40
+ tollkit-wallet withdraw base 25 USDC 0xYourAddress
41
+ ```
42
+
43
+ The agent has no tool for this.
44
+
45
+ ## Use with an agent (MCP)
46
+
47
+ ```json
48
+ {
49
+ "mcpServers": {
50
+ "tollkit-wallet": {
51
+ "command": "tollkit-wallet",
52
+ "args": ["mcp"],
53
+ "env": { "TOLLKIT_WALLET_PASSWORD_FILE": "/path/to/a/file/with/your/password" }
54
+ }
55
+ }
56
+ }
57
+ ```
58
+
59
+ Tools: `wallet_status`, `wallet_balances`, `swap_quote`, `swap`, `pay_fetch`, `seller_check`, `receipts`. There is no tool for changing limits, approvals or keys.
60
+
61
+ ## Use with Coinbase AgentKit
62
+
63
+ ```ts
64
+ import { AgentKit } from "@coinbase/agentkit";
65
+ import { TollkitWallet } from "tollkit-wallet";
66
+ import { tollkitWalletActionProvider } from "tollkit-wallet/agentkit";
67
+
68
+ const wallet = await TollkitWallet.open(process.env.TOLLKIT_WALLET_PASSWORD!);
69
+ const agentkit = await AgentKit.from({ walletProvider, actionProviders: [tollkitWalletActionProvider(wallet)] });
70
+ ```
71
+
72
+ This adds `tollkit_swap`, `tollkit_swap_quote`, `tollkit_pay_fetch`, `tollkit_wallet_balances`, `tollkit_wallet_status`, `tollkit_seller_check` and `tollkit_receipts`. They use the Tollkit wallet's own keys and limits, whatever AgentKit wallet provider you use.
73
+
74
+ ## Use with ElizaOS
75
+
76
+ ```ts
77
+ import { tollkitWalletPlugin } from "tollkit-wallet/elizaos";
78
+ // in your character or project: plugins: [tollkitWalletPlugin]
79
+ ```
80
+
81
+ Set `TOLLKIT_WALLET_PASSWORD` (or `TOLLKIT_WALLET_PASSWORD_FILE`) in the agent's settings or environment. The agent's model reads the request ("swap 25 USDC to SOL"), and the wallet checks it against your limits before anything is signed.
82
+
83
+ ## Use from code
84
+
85
+ ```ts
86
+ import { TollkitWallet } from "tollkit-wallet";
87
+ const w = await TollkitWallet.open(process.env.TOLLKIT_WALLET_PASSWORD!);
88
+ const r = await w.pay("https://api.example.com/paid-endpoint");
89
+ ```
90
+
91
+ ## Where things live
92
+
93
+ `~/.tollkit-wallet/` (or `TOLLKIT_WALLET_HOME`) holds:
94
+
95
+ - `keystore.json` (encrypted)
96
+ - `policy.json` (sealed with your password; editing it by hand pauses spending)
97
+ - `ledger.jsonl` (receipts)
98
+ - `telegram.json`
99
+ - the cached sanctions list
100
+
101
+ Swap quotes come through api.tollkit.dev. It holds the 0x and Jupiter API keys and adds the fee, and it only ever sees public data and signed transactions.
102
+
103
+ If you lose the password, the funds can't be recovered.
@@ -0,0 +1,13 @@
1
+ # Third-party notices
2
+
3
+ ## web3icons
4
+
5
+ Coin and chain logos in `src/coin-icons.ts` come from web3icons (`@web3icons/core` 4.0.58, https://web3icons.io), by 0xa3k5, released under the MIT License:
6
+
7
+ > Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
8
+ >
9
+ > The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
10
+ >
11
+ > THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
12
+
13
+ The coin and network names and logos are trademarks of their owners and are used only to identify the assets and networks the wallet supports.
@@ -0,0 +1,141 @@
1
+ /**
2
+ * The wallet's agent-facing actions, defined once and shared by the MCP
3
+ * server, the AgentKit provider and the ElizaOS plugin. Spending stays inside
4
+ * the owner's policy; nothing here can change limits, keys or withdrawal
5
+ * addresses.
6
+ */
7
+ import { z } from "zod";
8
+ import type { TollkitWallet } from "./wallet.js";
9
+ export declare const SwapArgs: z.ZodObject<{
10
+ chain: z.ZodEnum<["base", "ethereum", "solana"]>;
11
+ sell: z.ZodString;
12
+ buy: z.ZodString;
13
+ amount: z.ZodString;
14
+ slippage_bps: z.ZodOptional<z.ZodNumber>;
15
+ }, "strip", z.ZodTypeAny, {
16
+ chain: "base" | "ethereum" | "solana";
17
+ amount: string;
18
+ sell: string;
19
+ buy: string;
20
+ slippage_bps?: number | undefined;
21
+ }, {
22
+ chain: "base" | "ethereum" | "solana";
23
+ amount: string;
24
+ sell: string;
25
+ buy: string;
26
+ slippage_bps?: number | undefined;
27
+ }>;
28
+ export declare const PayArgs: z.ZodObject<{
29
+ url: z.ZodString;
30
+ method: z.ZodOptional<z.ZodEnum<["GET", "POST", "PUT", "PATCH", "DELETE"]>>;
31
+ headers: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
32
+ body: z.ZodOptional<z.ZodString>;
33
+ }, "strip", z.ZodTypeAny, {
34
+ url: string;
35
+ method?: "POST" | "GET" | "PUT" | "PATCH" | "DELETE" | undefined;
36
+ headers?: Record<string, string> | undefined;
37
+ body?: string | undefined;
38
+ }, {
39
+ url: string;
40
+ method?: "POST" | "GET" | "PUT" | "PATCH" | "DELETE" | undefined;
41
+ headers?: Record<string, string> | undefined;
42
+ body?: string | undefined;
43
+ }>;
44
+ export declare const SellerArgs: z.ZodObject<{
45
+ url: z.ZodString;
46
+ pay_to: z.ZodOptional<z.ZodString>;
47
+ }, "strip", z.ZodTypeAny, {
48
+ url: string;
49
+ pay_to?: string | undefined;
50
+ }, {
51
+ url: string;
52
+ pay_to?: string | undefined;
53
+ }>;
54
+ export declare const ReceiptArgs: z.ZodObject<{
55
+ since: z.ZodOptional<z.ZodString>;
56
+ limit: z.ZodOptional<z.ZodNumber>;
57
+ }, "strip", z.ZodTypeAny, {
58
+ since?: string | undefined;
59
+ limit?: number | undefined;
60
+ }, {
61
+ since?: string | undefined;
62
+ limit?: number | undefined;
63
+ }>;
64
+ export declare const NoArgs: z.ZodObject<{}, "strip", z.ZodTypeAny, {}, {}>;
65
+ export interface WalletAction<S extends z.ZodTypeAny = z.ZodTypeAny> {
66
+ name: string;
67
+ description: string;
68
+ schema: S;
69
+ spends: boolean;
70
+ run: (w: TollkitWallet, args: z.infer<S>) => Promise<unknown>;
71
+ }
72
+ export declare const ACTIONS: readonly [WalletAction<z.ZodObject<{}, "strip", z.ZodTypeAny, {}, {}>>, WalletAction<z.ZodObject<{}, "strip", z.ZodTypeAny, {}, {}>>, WalletAction<z.ZodObject<{
73
+ chain: z.ZodEnum<["base", "ethereum", "solana"]>;
74
+ sell: z.ZodString;
75
+ buy: z.ZodString;
76
+ amount: z.ZodString;
77
+ slippage_bps: z.ZodOptional<z.ZodNumber>;
78
+ }, "strip", z.ZodTypeAny, {
79
+ chain: "base" | "ethereum" | "solana";
80
+ amount: string;
81
+ sell: string;
82
+ buy: string;
83
+ slippage_bps?: number | undefined;
84
+ }, {
85
+ chain: "base" | "ethereum" | "solana";
86
+ amount: string;
87
+ sell: string;
88
+ buy: string;
89
+ slippage_bps?: number | undefined;
90
+ }>>, WalletAction<z.ZodObject<{
91
+ chain: z.ZodEnum<["base", "ethereum", "solana"]>;
92
+ sell: z.ZodString;
93
+ buy: z.ZodString;
94
+ amount: z.ZodString;
95
+ slippage_bps: z.ZodOptional<z.ZodNumber>;
96
+ }, "strip", z.ZodTypeAny, {
97
+ chain: "base" | "ethereum" | "solana";
98
+ amount: string;
99
+ sell: string;
100
+ buy: string;
101
+ slippage_bps?: number | undefined;
102
+ }, {
103
+ chain: "base" | "ethereum" | "solana";
104
+ amount: string;
105
+ sell: string;
106
+ buy: string;
107
+ slippage_bps?: number | undefined;
108
+ }>>, WalletAction<z.ZodObject<{
109
+ url: z.ZodString;
110
+ method: z.ZodOptional<z.ZodEnum<["GET", "POST", "PUT", "PATCH", "DELETE"]>>;
111
+ headers: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
112
+ body: z.ZodOptional<z.ZodString>;
113
+ }, "strip", z.ZodTypeAny, {
114
+ url: string;
115
+ method?: "POST" | "GET" | "PUT" | "PATCH" | "DELETE" | undefined;
116
+ headers?: Record<string, string> | undefined;
117
+ body?: string | undefined;
118
+ }, {
119
+ url: string;
120
+ method?: "POST" | "GET" | "PUT" | "PATCH" | "DELETE" | undefined;
121
+ headers?: Record<string, string> | undefined;
122
+ body?: string | undefined;
123
+ }>>, WalletAction<z.ZodObject<{
124
+ url: z.ZodString;
125
+ pay_to: z.ZodOptional<z.ZodString>;
126
+ }, "strip", z.ZodTypeAny, {
127
+ url: string;
128
+ pay_to?: string | undefined;
129
+ }, {
130
+ url: string;
131
+ pay_to?: string | undefined;
132
+ }>>, WalletAction<z.ZodObject<{
133
+ since: z.ZodOptional<z.ZodString>;
134
+ limit: z.ZodOptional<z.ZodNumber>;
135
+ }, "strip", z.ZodTypeAny, {
136
+ since?: string | undefined;
137
+ limit?: number | undefined;
138
+ }, {
139
+ since?: string | undefined;
140
+ limit?: number | undefined;
141
+ }>>];
@@ -0,0 +1,80 @@
1
+ /**
2
+ * The wallet's agent-facing actions, defined once and shared by the MCP
3
+ * server, the AgentKit provider and the ElizaOS plugin. Spending stays inside
4
+ * the owner's policy; nothing here can change limits, keys or withdrawal
5
+ * addresses.
6
+ */
7
+ import { z } from "zod";
8
+ import { resolveToken, toAtomic } from "./tokens.js";
9
+ import { checkSeller } from "./seller.js";
10
+ const MAX_BODY = 50_000;
11
+ export const SwapArgs = z.object({
12
+ chain: z.enum(["base", "ethereum", "solana"]).describe("Chain to trade on"),
13
+ sell: z.string().describe("Token to sell: symbol (USDC, USDT, ETH, WETH, SOL) or contract/mint address"),
14
+ buy: z.string().describe("Token to buy: symbol or contract/mint address"),
15
+ amount: z.string().describe('Amount of the sell token in normal units, e.g. "25" or "0.01"'),
16
+ slippage_bps: z.number().int().min(1).max(1000).optional().describe("Max slippage in basis points (default 50, capped by the owner's limit)"),
17
+ });
18
+ export const PayArgs = z.object({
19
+ url: z.string().url().describe("The paid endpoint"),
20
+ method: z.enum(["GET", "POST", "PUT", "PATCH", "DELETE"]).optional(),
21
+ headers: z.record(z.string()).optional(),
22
+ body: z.string().optional().describe("Request body, e.g. JSON text"),
23
+ });
24
+ export const SellerArgs = z.object({ url: z.string().url(), pay_to: z.string().optional() });
25
+ export const ReceiptArgs = z.object({
26
+ since: z.string().optional().describe("ISO date, e.g. 2026-10-01"),
27
+ limit: z.number().int().min(1).max(500).optional(),
28
+ });
29
+ export const NoArgs = z.object({});
30
+ async function swapRequest(w, a) {
31
+ const chain = a.chain;
32
+ const [sell, buy] = await Promise.all([resolveToken(chain, a.sell), resolveToken(chain, a.buy)]);
33
+ return { req: { chain, sell_token: sell.address, buy_token: buy.address, sell_amount: toAtomic(a.amount, sell.decimals), slippage_bps: a.slippage_bps ?? Math.min(50, w.policy.max_slippage_bps) }, sell, buy };
34
+ }
35
+ const bad = (e) => ({ ok: false, refused: { code: "bad_request", reason: e.message } });
36
+ const def = (a) => a;
37
+ export const ACTIONS = [
38
+ def({ name: "wallet_status", spends: false, schema: NoArgs,
39
+ description: "Wallet addresses, the owner's spending limits, what has been spent today, and whether approvals are on.",
40
+ run: async (w) => w.status() }),
41
+ def({ name: "wallet_balances", spends: false, schema: NoArgs,
42
+ description: "Balances of the native coin and USDC/USDT on each enabled chain.",
43
+ run: async (w) => w.balances() }),
44
+ def({ name: "swap_quote", spends: false, schema: SwapArgs,
45
+ description: "Get a checked quote for a spot swap without trading: dollar value, minimum received, Tollkit's 0.5% fee and any venue fee.",
46
+ run: async (w, a) => { try {
47
+ const { req, sell, buy } = await swapRequest(w, a);
48
+ return { ...(await w.quote(req)), sell, buy };
49
+ }
50
+ catch (e) {
51
+ return bad(e);
52
+ } } }),
53
+ def({ name: "swap", spends: true, schema: SwapArgs,
54
+ description: "Swap tokens (Base/Ethereum via 0x, Solana via Jupiter) within the owner's limits. Larger trades wait for the owner's approval. Flat 0.5% fee, shown in the result.",
55
+ run: async (w, a) => { try {
56
+ const { req, sell, buy } = await swapRequest(w, a);
57
+ return { ...(await w.swap(req)), sell, buy };
58
+ }
59
+ catch (e) {
60
+ return bad(e);
61
+ } } }),
62
+ def({ name: "pay_fetch", spends: true, schema: PayArgs,
63
+ description: "Fetch a URL and pay for it if it asks (x402 or MPP, USDC/USDT on Base, Ethereum or Solana). Checks the seller, screens the recipient against OFAC, stays within the owner's limits. Returns the response body.",
64
+ run: async (w, a) => {
65
+ const r = await w.pay(a.url, { method: a.method ?? (a.body ? "POST" : "GET"), headers: a.headers, body: a.body });
66
+ let body;
67
+ if (r.response) {
68
+ const t = await r.response.text();
69
+ body = t.length > MAX_BODY ? t.slice(0, MAX_BODY) + `\n…[truncated ${t.length - MAX_BODY} chars]` : t;
70
+ }
71
+ return { paid: r.paid, status: r.status, cost_usd: r.offer?.usd, protocol: r.offer?.protocol, chain: r.offer?.chain, tx: r.tx, refused: r.refused, content_type: r.response?.headers.get("content-type"), body };
72
+ } }),
73
+ def({ name: "seller_check", spends: false, schema: SellerArgs,
74
+ description: "Check a paid endpoint before buying: is it up, does its live price match its listing, does it pay where it says (Tollkit Weigh Station).",
75
+ run: async (_w, a) => checkSeller(a.url, a.pay_to ?? "") }),
76
+ def({ name: "receipts", spends: false, schema: ReceiptArgs,
77
+ description: "Recent trades, payments and withdrawals with amounts, fees and transaction hashes.",
78
+ run: async (w, a) => w.receipts(a.since).slice(-(a.limit ?? 50)) }),
79
+ ];
80
+ //# sourceMappingURL=actions.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"actions.js","sourceRoot":"","sources":["../src/actions.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,24 @@
1
+ /**
2
+ * Coinbase AgentKit action provider.
3
+ *
4
+ * import { AgentKit } from "@coinbase/agentkit";
5
+ * import { TollkitWallet } from "tollkit-wallet";
6
+ * import { tollkitWalletActionProvider } from "tollkit-wallet/agentkit";
7
+ * const w = await TollkitWallet.open(process.env.TOLLKIT_WALLET_PASSWORD!);
8
+ * const agentkit = await AgentKit.from({ walletProvider, actionProviders: [tollkitWalletActionProvider(w)] });
9
+ *
10
+ * Trades and payments use the Tollkit wallet's own keys and limits, not the
11
+ * AgentKit wallet provider, so they work the same whatever provider you use.
12
+ * Actions are returned directly (no decorators), so no per-call analytics
13
+ * events are sent from this provider.
14
+ */
15
+ import { ActionProvider, type Action, type Network, type WalletProvider } from "@coinbase/agentkit";
16
+ import type { TollkitWallet } from "./wallet.js";
17
+ export declare class TollkitWalletActionProvider extends ActionProvider<WalletProvider> {
18
+ private readonly wallet;
19
+ constructor(wallet: TollkitWallet);
20
+ getActions(_walletProvider: WalletProvider): Action[];
21
+ /** Works on any network AgentKit is set to; the chain is chosen per action. */
22
+ supportsNetwork(_network: Network): boolean;
23
+ }
24
+ export declare const tollkitWalletActionProvider: (wallet: TollkitWallet) => TollkitWalletActionProvider;
@@ -0,0 +1,40 @@
1
+ /**
2
+ * Coinbase AgentKit action provider.
3
+ *
4
+ * import { AgentKit } from "@coinbase/agentkit";
5
+ * import { TollkitWallet } from "tollkit-wallet";
6
+ * import { tollkitWalletActionProvider } from "tollkit-wallet/agentkit";
7
+ * const w = await TollkitWallet.open(process.env.TOLLKIT_WALLET_PASSWORD!);
8
+ * const agentkit = await AgentKit.from({ walletProvider, actionProviders: [tollkitWalletActionProvider(w)] });
9
+ *
10
+ * Trades and payments use the Tollkit wallet's own keys and limits, not the
11
+ * AgentKit wallet provider, so they work the same whatever provider you use.
12
+ * Actions are returned directly (no decorators), so no per-call analytics
13
+ * events are sent from this provider.
14
+ */
15
+ import { ActionProvider } from "@coinbase/agentkit";
16
+ import { ACTIONS } from "./actions.js";
17
+ export class TollkitWalletActionProvider extends ActionProvider {
18
+ wallet;
19
+ constructor(wallet) {
20
+ super("tollkit_wallet", []);
21
+ this.wallet = wallet;
22
+ }
23
+ getActions(_walletProvider) {
24
+ return ACTIONS.map((a) => ({
25
+ name: `tollkit_${a.name}`,
26
+ description: a.description,
27
+ schema: a.schema,
28
+ invoke: async (args) => {
29
+ const parsed = a.schema.safeParse(args ?? {});
30
+ if (!parsed.success)
31
+ return JSON.stringify({ ok: false, refused: { code: "bad_request", reason: parsed.error.issues.map((i) => `${i.path.join(".")}: ${i.message}`).join("; ") } });
32
+ return JSON.stringify(await a.run(this.wallet, parsed.data));
33
+ },
34
+ }));
35
+ }
36
+ /** Works on any network AgentKit is set to; the chain is chosen per action. */
37
+ supportsNetwork(_network) { return true; }
38
+ }
39
+ export const tollkitWalletActionProvider = (wallet) => new TollkitWalletActionProvider(wallet);
40
+ //# sourceMappingURL=agentkit.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"agentkit.js","sourceRoot":"","sources":["../src/agentkit.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AACH,OAAO,EAAE,cAAc,EAAkD,MAAM,oBAAoB,CAAC;AACpG,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AAGvC,MAAM,OAAO,2BAA4B,SAAQ,cAA8B;IAChD;IAA7B,YAA6B,MAAqB;QAAI,KAAK,CAAC,gBAAgB,EAAE,EAAE,CAAC,CAAC;QAArD,WAAM,GAAN,MAAM,CAAe;IAAiC,CAAC;IAE3E,UAAU,CAAC,eAA+B;QACjD,OAAO,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;YACzB,IAAI,EAAE,WAAW,CAAC,CAAC,IAAI,EAAE;YACzB,WAAW,EAAE,CAAC,CAAC,WAAW;YAC1B,MAAM,EAAE,CAAC,CAAC,MAAa;YACvB,MAAM,EAAE,KAAK,EAAE,IAAS,EAAE,EAAE;gBAC1B,MAAM,MAAM,GAAG,CAAC,CAAC,MAAM,CAAC,SAAS,CAAC,IAAI,IAAI,EAAE,CAAC,CAAC;gBAC9C,IAAI,CAAC,MAAM,CAAC,OAAO;oBAAE,OAAO,IAAI,CAAC,SAAS,CAAC,EAAE,EAAE,EAAE,KAAK,EAAE,OAAO,EAAE,EAAE,IAAI,EAAE,aAAa,EAAE,MAAM,EAAE,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,EAAE,CAAC,CAAC;gBACpL,OAAO,IAAI,CAAC,SAAS,CAAC,MAAO,CAAC,CAAC,GAAW,CAAC,IAAI,CAAC,MAAM,EAAE,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC;YACxE,CAAC;SACF,CAAC,CAAC,CAAC;IACN,CAAC;IAED,+EAA+E;IAC/E,eAAe,CAAC,QAAiB,IAAa,OAAO,IAAI,CAAC,CAAC,CAAC;CAC7D;AAED,MAAM,CAAC,MAAM,2BAA2B,GAAG,CAAC,MAAqB,EAAE,EAAE,CAAC,IAAI,2BAA2B,CAAC,MAAM,CAAC,CAAC"}
@@ -0,0 +1,21 @@
1
+ import type { Decision } from "./telegram.js";
2
+ export interface ApprovalRequest {
3
+ id: string;
4
+ text: string;
5
+ created: string;
6
+ expires: string;
7
+ status: "pending" | "approved" | "denied" | "timeout";
8
+ answered_by?: string;
9
+ }
10
+ /** The dashboard calls this every few seconds while it's open. */
11
+ export declare function heartbeat(dir?: string): void;
12
+ export declare function dashboardOpen(dir?: string, now?: number): boolean;
13
+ export declare function pending(dir?: string, now?: number): ApprovalRequest[];
14
+ /** Answer a pending request. Returns false if it was already answered or expired. */
15
+ export declare function decide(dir: string | undefined, id: string, d: "approved" | "denied", by?: string): boolean;
16
+ /** Wait for an answer from the dashboard. `signal` lets another channel (Telegram) win. */
17
+ export declare function requestLocal(dir: string | undefined, text: string, o?: {
18
+ timeoutMs?: number;
19
+ signal?: AbortSignal;
20
+ pollMs?: number;
21
+ }): Promise<Decision>;
@@ -0,0 +1,71 @@
1
+ /**
2
+ * Approvals on this computer, answered from the dashboard. Each request is a
3
+ * small file in <wallet>/approvals/; the process that wants to spend waits
4
+ * for the dashboard to mark it approved or denied. Used alongside Telegram:
5
+ * whichever answers first wins. Only used while the dashboard is open
6
+ * (it writes a heartbeat), so an agent never waits on a page nobody has open.
7
+ */
8
+ import { existsSync, mkdirSync, readdirSync, readFileSync, renameSync, statSync, writeFileSync } from "node:fs";
9
+ import { randomBytes } from "node:crypto";
10
+ import path from "node:path";
11
+ import { walletHome } from "./paths.js";
12
+ const dirOf = (dir) => { const d = path.join(walletHome(dir), "approvals"); mkdirSync(d, { recursive: true, mode: 0o700 }); return d; };
13
+ const fileOf = (dir, id) => path.join(dirOf(dir), `${id}.json`);
14
+ const sleep = (ms) => new Promise((r) => setTimeout(r, ms));
15
+ function writeAtomic(f, v) { const t = `${f}.${process.pid}.tmp`; writeFileSync(t, JSON.stringify(v), { mode: 0o600 }); renameSync(t, f); }
16
+ function read(f) { try {
17
+ return JSON.parse(readFileSync(f, "utf8"));
18
+ }
19
+ catch {
20
+ return null;
21
+ } }
22
+ /** The dashboard calls this every few seconds while it's open. */
23
+ export function heartbeat(dir) { writeFileSync(path.join(dirOf(dir), ".heartbeat"), new Date().toISOString(), { mode: 0o600 }); }
24
+ export function dashboardOpen(dir, now = Date.now()) {
25
+ try {
26
+ return now - statSync(path.join(dirOf(dir), ".heartbeat")).mtimeMs < 15_000;
27
+ }
28
+ catch {
29
+ return false;
30
+ }
31
+ }
32
+ export function pending(dir, now = Date.now()) {
33
+ return readdirSync(dirOf(dir)).filter((n) => n.endsWith(".json"))
34
+ .map((n) => read(path.join(dirOf(dir), n))).filter((r) => !!r && r.status === "pending" && Date.parse(r.expires) > now)
35
+ .sort((a, b) => a.created.localeCompare(b.created));
36
+ }
37
+ /** Answer a pending request. Returns false if it was already answered or expired. */
38
+ export function decide(dir, id, d, by = "dashboard") {
39
+ if (!/^[0-9a-f]{16}$/.test(id))
40
+ return false;
41
+ const f = fileOf(dir, id);
42
+ const r = existsSync(f) ? read(f) : null;
43
+ if (!r || r.status !== "pending" || Date.parse(r.expires) <= Date.now())
44
+ return false;
45
+ writeAtomic(f, { ...r, status: d, answered_by: by });
46
+ return true;
47
+ }
48
+ /** Wait for an answer from the dashboard. `signal` lets another channel (Telegram) win. */
49
+ export async function requestLocal(dir, text, o = {}) {
50
+ const id = randomBytes(8).toString("hex");
51
+ const now = Date.now(), timeout = o.timeoutMs ?? 5 * 60_000;
52
+ const f = fileOf(dir, id);
53
+ writeAtomic(f, { id, text, created: new Date(now).toISOString(), expires: new Date(now + timeout).toISOString(), status: "pending" });
54
+ while (Date.now() - now < timeout) {
55
+ const r = read(f);
56
+ if (r?.status === "approved" || r?.status === "denied")
57
+ return r.status;
58
+ if (o.signal?.aborted) {
59
+ const cur = read(f);
60
+ if (cur?.status === "pending")
61
+ writeAtomic(f, { ...cur, status: "timeout", answered_by: "other channel" });
62
+ return "timeout";
63
+ }
64
+ await sleep(o.pollMs ?? 400);
65
+ }
66
+ const r = read(f);
67
+ if (r?.status === "pending")
68
+ writeAtomic(f, { ...r, status: "timeout" });
69
+ return r?.status === "approved" || r?.status === "denied" ? r.status : "timeout";
70
+ }
71
+ //# sourceMappingURL=approvals.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"approvals.js","sourceRoot":"","sources":["../src/approvals.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,16 @@
1
+ /** Chains, tokens and the fixed addresses the wallet trusts. */
2
+ export type Chain = "base" | "ethereum" | "solana";
3
+ export declare const EVM_CHAIN_ID: Record<Exclude<Chain, "solana">, number>;
4
+ /** 0x AllowanceHolder (Cancun chains incl. Ethereum and Base). The only contract we ever approve. docs.0x.org cheat sheet. */
5
+ export declare const ALLOWANCE_HOLDER = "0x0000000000001fF3684f28c67538d4D072C22734";
6
+ export declare const DEFAULT_RPC: Record<Chain, string>;
7
+ /** Dollar stablecoins, valued at $1 for budgets. */
8
+ export declare const STABLES: Record<Chain, Record<string, {
9
+ symbol: string;
10
+ decimals: number;
11
+ }>>;
12
+ export declare const NATIVE_EVM = "0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE";
13
+ export declare const WSOL = "So11111111111111111111111111111111111111112";
14
+ export declare const isStable: (chain: Chain, token: string) => boolean;
15
+ /** Tollkit's fee on swaps: flat, the same everywhere, shown before every trade. */
16
+ export declare const SWAP_FEE_BPS = 50;
package/dist/chains.js ADDED
@@ -0,0 +1,26 @@
1
+ export const EVM_CHAIN_ID = { ethereum: 1, base: 8453 };
2
+ /** 0x AllowanceHolder (Cancun chains incl. Ethereum and Base). The only contract we ever approve. docs.0x.org cheat sheet. */
3
+ export const ALLOWANCE_HOLDER = "0x0000000000001fF3684f28c67538d4D072C22734";
4
+ export const DEFAULT_RPC = {
5
+ base: "https://mainnet.base.org",
6
+ ethereum: "https://ethereum-rpc.publicnode.com",
7
+ solana: "https://api.mainnet-beta.solana.com",
8
+ };
9
+ /** Dollar stablecoins, valued at $1 for budgets. */
10
+ export const STABLES = {
11
+ base: { "0x833589fcd6edb6e08f4c7c32d4f71b54bda02913": { symbol: "USDC", decimals: 6 } },
12
+ ethereum: {
13
+ "0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48": { symbol: "USDC", decimals: 6 },
14
+ "0xdac17f958d2ee523a2206206994597c13d831ec7": { symbol: "USDT", decimals: 6 },
15
+ },
16
+ solana: {
17
+ EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v: { symbol: "USDC", decimals: 6 },
18
+ Es9vMFrzaCERmJfrF4H2FYD4KCoNkY11McCe8BenwNYB: { symbol: "USDT", decimals: 6 },
19
+ },
20
+ };
21
+ export const NATIVE_EVM = "0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE";
22
+ export const WSOL = "So11111111111111111111111111111111111111112";
23
+ export const isStable = (chain, token) => chain === "solana" ? token in STABLES.solana : token.toLowerCase() in STABLES[chain];
24
+ /** Tollkit's fee on swaps: flat, the same everywhere, shown before every trade. */
25
+ export const SWAP_FEE_BPS = 50;
26
+ //# sourceMappingURL=chains.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"chains.js","sourceRoot":"","sources":["../src/chains.ts"],"names":[],"mappings":"AAEA,MAAM,CAAC,MAAM,YAAY,GAA6C,EAAE,QAAQ,EAAE,CAAC,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC;AAElG,8HAA8H;AAC9H,MAAM,CAAC,MAAM,gBAAgB,GAAG,4CAA4C,CAAC;AAE7E,MAAM,CAAC,MAAM,WAAW,GAA0B;IAChD,IAAI,EAAE,0BAA0B;IAChC,QAAQ,EAAE,qCAAqC;IAC/C,MAAM,EAAE,qCAAqC;CAC9C,CAAC;AAEF,oDAAoD;AACpD,MAAM,CAAC,MAAM,OAAO,GAAwE;IAC1F,IAAI,EAAE,EAAE,4CAA4C,EAAE,EAAE,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,CAAC,EAAE,EAAE;IACvF,QAAQ,EAAE;QACR,4CAA4C,EAAE,EAAE,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,CAAC,EAAE;QAC7E,4CAA4C,EAAE,EAAE,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,CAAC,EAAE;KAC9E;IACD,MAAM,EAAE;QACN,4CAA4C,EAAE,EAAE,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,CAAC,EAAE;QAC7E,4CAA4C,EAAE,EAAE,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,CAAC,EAAE;KAC9E;CACF,CAAC;AAEF,MAAM,CAAC,MAAM,UAAU,GAAG,4CAA4C,CAAC;AACvE,MAAM,CAAC,MAAM,IAAI,GAAG,6CAA6C,CAAC;AAElE,MAAM,CAAC,MAAM,QAAQ,GAAG,CAAC,KAAY,EAAE,KAAa,EAAE,EAAE,CACtD,KAAK,KAAK,QAAQ,CAAC,CAAC,CAAC,KAAK,IAAI,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,KAAK,CAAC,WAAW,EAAE,IAAI,OAAO,CAAC,KAAK,CAAC,CAAC;AAEvF,mFAAmF;AACnF,MAAM,CAAC,MAAM,YAAY,GAAG,EAAE,CAAC"}
package/dist/cli.d.ts ADDED
@@ -0,0 +1,2 @@
1
+ #!/usr/bin/env node
2
+ export {};