@waiaas/actions 2.6.0-rc.6 → 2.6.0-rc.8

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md ADDED
@@ -0,0 +1,158 @@
1
+ # WAIaaS
2
+
3
+ **Wallet-as-a-Service for AI Agents**
4
+
5
+ [![License: MIT](https://img.shields.io/badge/License-MIT-blue.svg)](LICENSE)
6
+ [![Node.js](https://img.shields.io/badge/Node.js-22_LTS-green.svg)](https://nodejs.org/)
7
+ [![Tests](https://img.shields.io/badge/Tests-3%2C599_passing-brightgreen.svg)](#)
8
+
9
+ A self-hosted wallet daemon that lets AI agents perform on-chain transactions securely -- while the owner keeps full control of funds.
10
+
11
+ ## The Problem
12
+
13
+ AI agents that need to transact on-chain face an impossible choice: hold private keys (and risk total loss if compromised) or depend on a centralized custodian (single point of failure, trust dependency).
14
+
15
+ WAIaaS bridges the gap -- agents handle small transactions instantly, large amounts require owner approval, and everything runs on your machine with no third-party dependency.
16
+
17
+ ## How It Works
18
+
19
+ WAIaaS is a local daemon that sits between your AI agent and the blockchain:
20
+
21
+ - **3-tier authentication** -- Separate roles for the daemon operator (masterAuth), fund owner (ownerAuth), and AI agent (sessionAuth)
22
+ - **4-tier policy engine** -- Transactions are auto-classified by USD value into INSTANT / NOTIFY / DELAY / APPROVAL tiers
23
+ - **12 policy types** -- Cumulative spend limits, token allowlists, contract whitelists, approved spenders, and more
24
+ - **Defense in depth** -- Kill Switch, AutoStop engine, audit logging, 4-channel notifications
25
+
26
+ See [Security Model](docs/security-model.md) for full details.
27
+
28
+ ## Quick Start
29
+
30
+ ```bash
31
+ npm install -g @waiaas/cli
32
+ waiaas init # Create data directory + config.toml
33
+ waiaas start # Start daemon (sets master password on first run)
34
+ waiaas quickset --mode testnet # Create wallets + MCP sessions in one step
35
+ ```
36
+
37
+ The `quickset` command does everything you need to get started:
38
+
39
+ 1. Creates **Solana Devnet + EVM Sepolia** wallets automatically
40
+ 2. Issues **MCP session tokens** for each wallet
41
+ 3. Outputs a **Claude Desktop MCP config** snippet -- just copy and paste
42
+
43
+ > Starting with mainnet? Use `waiaas quickset --mode mainnet` to create Solana Mainnet + EVM Ethereum Mainnet wallets instead. Mainnet mode recommends configuring spending limits and registering an owner wallet for high-value transaction approval.
44
+
45
+ ### Admin UI
46
+
47
+ After starting the daemon, manage everything from the admin panel at `http://127.0.0.1:3100/admin` (masterAuth required).
48
+
49
+ ## Connect Your AI Agent
50
+
51
+ After quickset, choose one of two integration paths:
52
+
53
+ ### Path A: MCP (Claude Desktop / Claude Code)
54
+
55
+ For AI agents that support the [Model Context Protocol](https://modelcontextprotocol.io):
56
+
57
+ ```bash
58
+ # quickset already printed the MCP config JSON -- paste it into
59
+ # ~/Library/Application Support/Claude/claude_desktop_config.json
60
+ # Or auto-register with all wallets:
61
+ waiaas mcp setup --all
62
+ ```
63
+
64
+ The daemon runs as an MCP server. Your agent calls wallet tools directly -- send tokens, check balances, manage policies -- all through the MCP protocol.
65
+
66
+ ### Path B: Skill Files (Any AI Agent)
67
+
68
+ For agents that don't support MCP, or when you prefer REST API integration:
69
+
70
+ ```bash
71
+ npx @waiaas/skills add all
72
+ ```
73
+
74
+ This adds `.skill.md` instruction files to your project. Include them in your agent's context and it learns the WAIaaS API automatically. Available skills: `quickstart`, `wallet`, `transactions`, `policies`, `admin`, `actions`, `x402`.
75
+
76
+ ## Alternative: Docker
77
+
78
+ ```bash
79
+ git clone https://github.com/minho-yoo/waiaas.git && cd waiaas
80
+ docker compose up -d
81
+ ```
82
+
83
+ The daemon listens on `http://127.0.0.1:3100`.
84
+
85
+ ## Using the SDK
86
+
87
+ ```typescript
88
+ import { WAIaaSClient } from '@waiaas/sdk';
89
+
90
+ const client = new WAIaaSClient({
91
+ baseUrl: 'http://127.0.0.1:3100',
92
+ sessionToken: process.env.WAIAAS_SESSION_TOKEN,
93
+ });
94
+
95
+ const balance = await client.getBalance();
96
+ console.log(`Balance: ${balance.balance} ${balance.symbol}`);
97
+
98
+ const tx = await client.sendToken({
99
+ to: 'recipient-address...',
100
+ amount: '0.1',
101
+ });
102
+ console.log(`Transaction: ${tx.id}`);
103
+ ```
104
+
105
+ ## Admin UI
106
+
107
+ Access the admin panel at `http://127.0.0.1:3100/admin` with your master password:
108
+
109
+ - **Dashboard** -- System overview, wallet balances, recent transactions
110
+ - **Wallets** -- Create, manage, and monitor wallets across chains; RPC endpoints, balance monitoring, and WalletConnect settings
111
+ - **Sessions** -- Issue and revoke agent session tokens; session lifetime and rate limit settings
112
+ - **Policies** -- Configure 12 policy types with visual form editors; default deny and tier settings
113
+ - **Notifications** -- Channel status and delivery logs; Telegram, Discord, ntfy, and Slack settings
114
+ - **Security** -- Kill Switch emergency controls, AutoStop protection rules, JWT rotation
115
+ - **System** -- API keys, display currency, price oracle, rate limits, log level, and daemon shutdown
116
+
117
+ Features include settings search (Ctrl+K / Cmd+K) and unsaved changes protection.
118
+
119
+ Enabled by default (`admin_ui = true` in config.toml).
120
+
121
+ ## Supported Networks
122
+
123
+ | Chain | Environment | Networks |
124
+ |-------|-------------|----------|
125
+ | Solana | mainnet | mainnet |
126
+ | Solana | testnet | devnet, testnet |
127
+ | EVM | mainnet | ethereum-mainnet, polygon-mainnet, arbitrum-mainnet, optimism-mainnet, base-mainnet |
128
+ | EVM | testnet | ethereum-sepolia, polygon-amoy, arbitrum-sepolia, optimism-sepolia, base-sepolia |
129
+
130
+ 13 networks total (Solana 3 + EVM 10).
131
+
132
+ ## Features
133
+
134
+ - **Self-hosted local daemon** -- No central server; keys never leave your machine
135
+ - **Multi-chain** -- Solana (SPL / Token-2022) and EVM (ERC-20) via `IChainAdapter`
136
+ - **Token, contract, and DeFi** -- Native transfers, token transfers, contract calls, approve, batch transactions, Action Provider plugins (Jupiter Swap, etc.)
137
+ - **USD policy evaluation** -- Price oracles (CoinGecko / Pyth / Chainlink) evaluate all transactions in USD
138
+ - **x402 payments** -- Automatic HTTP 402 payment handling with EIP-3009 signatures
139
+ - **Multiple interfaces** -- REST API, TypeScript SDK, Python SDK, MCP server, CLI, Admin Web UI, Tauri Desktop, Telegram Bot
140
+ - **Skill files** -- Pre-built instruction files that teach AI agents how to use the API
141
+
142
+ ## Documentation
143
+
144
+ | Document | Description |
145
+ |----------|-------------|
146
+ | [Security Model](docs/security-model.md) | Authentication, policy engine, Kill Switch, AutoStop |
147
+ | [Deployment Guide](docs/deployment.md) | Docker, npm, configuration reference |
148
+ | [API Reference](docs/api-reference.md) | REST API endpoints and authentication |
149
+ | [Agent Skills Integration](docs/guides/agent-skills-integration.md) | Universal guide for 27+ AI agent platforms |
150
+ | [Claude Code Integration](docs/guides/claude-code-integration.md) | Skill files + MCP server setup for Claude Code |
151
+ | [OpenClaw Integration](docs/guides/openclaw-integration.md) | Quick setup for OpenClaw bot |
152
+ | [Wallet SDK Integration](docs/wallet-sdk-integration.md) | Integration guide for wallet developers |
153
+ | [Why WAIaaS?](docs/why-waiaas/) | Background on AI agent wallet security |
154
+ | [Contributing](CONTRIBUTING.md) | Development setup, code style, testing, PR guidelines |
155
+
156
+ ## License
157
+
158
+ [MIT](LICENSE) -- Copyright (c) 2026 WAIaaS Contributors
package/dist/index.d.ts CHANGED
@@ -8,17 +8,26 @@ import type { IActionProvider } from '@waiaas/core';
8
8
  export { JupiterSwapActionProvider } from './providers/jupiter-swap/index.js';
9
9
  export { JUPITER_PROGRAM_ID, JUPITER_SWAP_DEFAULTS } from './providers/jupiter-swap/config.js';
10
10
  export type { JupiterSwapConfig } from './providers/jupiter-swap/config.js';
11
+ export { ZeroExSwapActionProvider } from './providers/zerox-swap/index.js';
12
+ export { ALLOWANCE_HOLDER_ADDRESSES, ZEROX_SWAP_DEFAULTS, CHAIN_ID_MAP, getAllowanceHolderAddress } from './providers/zerox-swap/config.js';
13
+ export type { ZeroExSwapConfig } from './providers/zerox-swap/config.js';
11
14
  export { ActionApiClient } from './common/action-api-client.js';
12
15
  export { asBps, asPct, clampSlippageBps, bpsToPct, pctToBps } from './common/slippage.js';
13
16
  export type { SlippageBps, SlippagePct } from './common/slippage.js';
14
- interface ActionsConfig {
15
- jupiter_swap?: Partial<import('./providers/jupiter-swap/config.js').JupiterSwapConfig>;
16
- [key: string]: unknown;
17
+ /** Minimal settings reader interface compatible with SettingsService.get(). */
18
+ export interface SettingsReader {
19
+ get(key: string): string;
17
20
  }
18
21
  interface ProviderRegistry {
19
22
  register(provider: IActionProvider): void;
20
23
  }
21
- export declare function registerBuiltInProviders(registry: ProviderRegistry, actionsConfig?: ActionsConfig): {
24
+ /**
25
+ * Register built-in DeFi action providers from Admin Settings.
26
+ *
27
+ * Reads provider config from SettingsReader (DB > config.toml > default fallback chain).
28
+ * Each provider is registered when its `actions.{name}_enabled` setting is 'true'.
29
+ */
30
+ export declare function registerBuiltInProviders(registry: ProviderRegistry, settingsReader: SettingsReader): {
22
31
  loaded: string[];
23
32
  skipped: string[];
24
33
  };
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC;AAIpD,OAAO,EAAE,yBAAyB,EAAE,MAAM,mCAAmC,CAAC;AAC9E,OAAO,EAAE,kBAAkB,EAAE,qBAAqB,EAAE,MAAM,oCAAoC,CAAC;AAC/F,YAAY,EAAE,iBAAiB,EAAE,MAAM,oCAAoC,CAAC;AAG5E,OAAO,EAAE,eAAe,EAAE,MAAM,+BAA+B,CAAC;AAChE,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,gBAAgB,EAAE,QAAQ,EAAE,QAAQ,EAAE,MAAM,sBAAsB,CAAC;AAC1F,YAAY,EAAE,WAAW,EAAE,WAAW,EAAE,MAAM,sBAAsB,CAAC;AAMrE,UAAU,aAAa;IACrB,YAAY,CAAC,EAAE,OAAO,CAAC,OAAO,oCAAoC,EAAE,iBAAiB,CAAC,CAAC;IACvF,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;CACxB;AAED,UAAU,gBAAgB;IACxB,QAAQ,CAAC,QAAQ,EAAE,eAAe,GAAG,IAAI,CAAC;CAC3C;AAED,wBAAgB,wBAAwB,CACtC,QAAQ,EAAE,gBAAgB,EAC1B,aAAa,CAAC,EAAE,aAAa,GAC5B;IAAE,MAAM,EAAE,MAAM,EAAE,CAAC;IAAC,OAAO,EAAE,MAAM,EAAE,CAAA;CAAE,CA2BzC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC;AAKpD,OAAO,EAAE,yBAAyB,EAAE,MAAM,mCAAmC,CAAC;AAC9E,OAAO,EAAE,kBAAkB,EAAE,qBAAqB,EAAE,MAAM,oCAAoC,CAAC;AAC/F,YAAY,EAAE,iBAAiB,EAAE,MAAM,oCAAoC,CAAC;AAE5E,OAAO,EAAE,wBAAwB,EAAE,MAAM,iCAAiC,CAAC;AAC3E,OAAO,EAAE,0BAA0B,EAAE,mBAAmB,EAAE,YAAY,EAAE,yBAAyB,EAAE,MAAM,kCAAkC,CAAC;AAC5I,YAAY,EAAE,gBAAgB,EAAE,MAAM,kCAAkC,CAAC;AAGzE,OAAO,EAAE,eAAe,EAAE,MAAM,+BAA+B,CAAC;AAChE,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,gBAAgB,EAAE,QAAQ,EAAE,QAAQ,EAAE,MAAM,sBAAsB,CAAC;AAC1F,YAAY,EAAE,WAAW,EAAE,WAAW,EAAE,MAAM,sBAAsB,CAAC;AAMrE,+EAA+E;AAC/E,MAAM,WAAW,cAAc;IAC7B,GAAG,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAAC;CAC1B;AAED,UAAU,gBAAgB;IACxB,QAAQ,CAAC,QAAQ,EAAE,eAAe,GAAG,IAAI,CAAC;CAC3C;AAED;;;;;GAKG;AACH,wBAAgB,wBAAwB,CACtC,QAAQ,EAAE,gBAAgB,EAC1B,cAAc,EAAE,cAAc,GAC7B;IAAE,MAAM,EAAE,MAAM,EAAE,CAAC;IAAC,OAAO,EAAE,MAAM,EAAE,CAAA;CAAE,CA8DzC"}
package/dist/index.js CHANGED
@@ -1,25 +1,66 @@
1
1
  import { JupiterSwapActionProvider } from './providers/jupiter-swap/index.js';
2
+ import { ZeroExSwapActionProvider } from './providers/zerox-swap/index.js';
2
3
  // Re-export provider classes
3
4
  export { JupiterSwapActionProvider } from './providers/jupiter-swap/index.js';
4
5
  export { JUPITER_PROGRAM_ID, JUPITER_SWAP_DEFAULTS } from './providers/jupiter-swap/config.js';
6
+ export { ZeroExSwapActionProvider } from './providers/zerox-swap/index.js';
7
+ export { ALLOWANCE_HOLDER_ADDRESSES, ZEROX_SWAP_DEFAULTS, CHAIN_ID_MAP, getAllowanceHolderAddress } from './providers/zerox-swap/config.js';
5
8
  // Re-export common utilities
6
9
  export { ActionApiClient } from './common/action-api-client.js';
7
10
  export { asBps, asPct, clampSlippageBps, bpsToPct, pctToBps } from './common/slippage.js';
8
- export function registerBuiltInProviders(registry, actionsConfig) {
11
+ /**
12
+ * Register built-in DeFi action providers from Admin Settings.
13
+ *
14
+ * Reads provider config from SettingsReader (DB > config.toml > default fallback chain).
15
+ * Each provider is registered when its `actions.{name}_enabled` setting is 'true'.
16
+ */
17
+ export function registerBuiltInProviders(registry, settingsReader) {
9
18
  const loaded = [];
10
19
  const skipped = [];
11
20
  const providers = [
12
21
  {
13
22
  key: 'jupiter_swap',
14
- factory: () => new JupiterSwapActionProvider(actionsConfig?.jupiter_swap),
23
+ enabledKey: 'actions.jupiter_swap_enabled',
24
+ factory: () => {
25
+ const config = {
26
+ enabled: true,
27
+ apiBaseUrl: settingsReader.get('actions.jupiter_swap_api_base_url'),
28
+ apiKey: settingsReader.get('actions.jupiter_swap_api_key'),
29
+ defaultSlippageBps: Number(settingsReader.get('actions.jupiter_swap_default_slippage_bps')),
30
+ maxSlippageBps: Number(settingsReader.get('actions.jupiter_swap_max_slippage_bps')),
31
+ maxPriceImpactPct: Number(settingsReader.get('actions.jupiter_swap_max_price_impact_pct')),
32
+ jitoTipLamports: Number(settingsReader.get('actions.jupiter_swap_jito_tip_lamports')),
33
+ requestTimeoutMs: Number(settingsReader.get('actions.jupiter_swap_request_timeout_ms')),
34
+ };
35
+ return new JupiterSwapActionProvider(config);
36
+ },
37
+ },
38
+ {
39
+ key: 'zerox_swap',
40
+ enabledKey: 'actions.zerox_swap_enabled',
41
+ factory: () => {
42
+ const config = {
43
+ enabled: true,
44
+ apiKey: settingsReader.get('actions.zerox_swap_api_key'),
45
+ defaultSlippageBps: Number(settingsReader.get('actions.zerox_swap_default_slippage_bps')),
46
+ maxSlippageBps: Number(settingsReader.get('actions.zerox_swap_max_slippage_bps')),
47
+ requestTimeoutMs: Number(settingsReader.get('actions.zerox_swap_request_timeout_ms')),
48
+ };
49
+ return new ZeroExSwapActionProvider(config);
50
+ },
15
51
  },
16
52
  ];
17
- for (const { key, factory } of providers) {
18
- const cfg = actionsConfig?.[key];
19
- if (cfg?.enabled) {
53
+ for (const { key, enabledKey, factory } of providers) {
54
+ if (settingsReader.get(enabledKey) === 'true') {
20
55
  try {
21
- registry.register(factory());
22
- loaded.push(key);
56
+ const provider = factory();
57
+ if (provider) {
58
+ registry.register(provider);
59
+ loaded.push(key);
60
+ }
61
+ else {
62
+ skipped.push(key);
63
+ }
23
64
  }
24
65
  catch (err) {
25
66
  console.warn(`Built-in provider '${key}' registration failed:`, err);
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAOA,OAAO,EAAE,yBAAyB,EAAE,MAAM,mCAAmC,CAAC;AAE9E,6BAA6B;AAC7B,OAAO,EAAE,yBAAyB,EAAE,MAAM,mCAAmC,CAAC;AAC9E,OAAO,EAAE,kBAAkB,EAAE,qBAAqB,EAAE,MAAM,oCAAoC,CAAC;AAG/F,6BAA6B;AAC7B,OAAO,EAAE,eAAe,EAAE,MAAM,+BAA+B,CAAC;AAChE,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,gBAAgB,EAAE,QAAQ,EAAE,QAAQ,EAAE,MAAM,sBAAsB,CAAC;AAgB1F,MAAM,UAAU,wBAAwB,CACtC,QAA0B,EAC1B,aAA6B;IAE7B,MAAM,MAAM,GAAa,EAAE,CAAC;IAC5B,MAAM,OAAO,GAAa,EAAE,CAAC;IAE7B,MAAM,SAAS,GAA2D;QACxE;YACE,GAAG,EAAE,cAAc;YACnB,OAAO,EAAE,GAAG,EAAE,CAAC,IAAI,yBAAyB,CAAC,aAAa,EAAE,YAAY,CAAC;SAC1E;KACF,CAAC;IAEF,KAAK,MAAM,EAAE,GAAG,EAAE,OAAO,EAAE,IAAI,SAAS,EAAE,CAAC;QACzC,MAAM,GAAG,GAAG,aAAa,EAAE,CAAC,GAAG,CAAsC,CAAC;QACtE,IAAI,GAAG,EAAE,OAAO,EAAE,CAAC;YACjB,IAAI,CAAC;gBACH,QAAQ,CAAC,QAAQ,CAAC,OAAO,EAAE,CAAC,CAAC;gBAC7B,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;YACnB,CAAC;YAAC,OAAO,GAAG,EAAE,CAAC;gBACb,OAAO,CAAC,IAAI,CAAC,sBAAsB,GAAG,wBAAwB,EAAE,GAAG,CAAC,CAAC;gBACrE,OAAO,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;YACpB,CAAC;QACH,CAAC;aAAM,CAAC;YACN,OAAO,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QACpB,CAAC;IACH,CAAC;IAED,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,CAAC;AAC7B,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,31 @@
1
+ /**
2
+ * 0x Swap configuration type, defaults, and AllowanceHolder address mapping.
3
+ *
4
+ * Uses 0x Swap API v2 with the AllowanceHolder flow (not Permit2).
5
+ * See: https://0x.org/docs/api#tag/Swap
6
+ */
7
+ export interface ZeroExSwapConfig {
8
+ enabled: boolean;
9
+ apiBaseUrl: string;
10
+ apiKey: string;
11
+ defaultSlippageBps: number;
12
+ maxSlippageBps: number;
13
+ requestTimeoutMs: number;
14
+ }
15
+ export declare const ZEROX_SWAP_DEFAULTS: ZeroExSwapConfig;
16
+ /**
17
+ * Supported chain IDs for 0x Swap API v2 AllowanceHolder flow.
18
+ * Cancun 19 chains + Mantle = 20 total.
19
+ */
20
+ export declare const ALLOWANCE_HOLDER_ADDRESSES: ReadonlyMap<number, string>;
21
+ /**
22
+ * Get AllowanceHolder contract address for a given chain ID.
23
+ * @throws Error if chain ID is not supported by 0x Swap API.
24
+ */
25
+ export declare function getAllowanceHolderAddress(chainId: number): string;
26
+ /**
27
+ * Maps WAIaaS network type names to EVM chain IDs.
28
+ * Only includes mainnet networks that are supported by both WAIaaS and 0x API.
29
+ */
30
+ export declare const CHAIN_ID_MAP: Record<string, number>;
31
+ //# sourceMappingURL=config.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../../src/providers/zerox-swap/config.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,MAAM,WAAW,gBAAgB;IAC/B,OAAO,EAAE,OAAO,CAAC;IACjB,UAAU,EAAE,MAAM,CAAC;IACnB,MAAM,EAAE,MAAM,CAAC;IACf,kBAAkB,EAAE,MAAM,CAAC;IAC3B,cAAc,EAAE,MAAM,CAAC;IACvB,gBAAgB,EAAE,MAAM,CAAC;CAC1B;AAED,eAAO,MAAM,mBAAmB,EAAE,gBAOjC,CAAC;AAQF;;;GAGG;AACH,eAAO,MAAM,0BAA0B,EAAE,WAAW,CAAC,MAAM,EAAE,MAAM,CAqBjE,CAAC;AAEH;;;GAGG;AACH,wBAAgB,yBAAyB,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAQjE;AAMD;;;GAGG;AACH,eAAO,MAAM,YAAY,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAM/C,CAAC"}
@@ -0,0 +1,70 @@
1
+ /**
2
+ * 0x Swap configuration type, defaults, and AllowanceHolder address mapping.
3
+ *
4
+ * Uses 0x Swap API v2 with the AllowanceHolder flow (not Permit2).
5
+ * See: https://0x.org/docs/api#tag/Swap
6
+ */
7
+ export const ZEROX_SWAP_DEFAULTS = {
8
+ enabled: false,
9
+ apiBaseUrl: 'https://api.0x.org',
10
+ apiKey: '',
11
+ defaultSlippageBps: 100, // 1% (ZXSW-06)
12
+ maxSlippageBps: 500, // 5% (ZXSW-06)
13
+ requestTimeoutMs: 10_000, // (ZXSW-10)
14
+ };
15
+ // ---------------------------------------------------------------------------
16
+ // AllowanceHolder contract address (same on all supported chains) (ZXSW-09)
17
+ // ---------------------------------------------------------------------------
18
+ const ALLOWANCE_HOLDER_ADDRESS = '0x0000000000001fF3684f28c67538d4D072C22734';
19
+ /**
20
+ * Supported chain IDs for 0x Swap API v2 AllowanceHolder flow.
21
+ * Cancun 19 chains + Mantle = 20 total.
22
+ */
23
+ export const ALLOWANCE_HOLDER_ADDRESSES = new Map([
24
+ [1, ALLOWANCE_HOLDER_ADDRESS], // Ethereum
25
+ [10, ALLOWANCE_HOLDER_ADDRESS], // Optimism
26
+ [56, ALLOWANCE_HOLDER_ADDRESS], // BNB Chain
27
+ [130, ALLOWANCE_HOLDER_ADDRESS], // Unichain
28
+ [137, ALLOWANCE_HOLDER_ADDRESS], // Polygon
29
+ [1329, ALLOWANCE_HOLDER_ADDRESS], // SEI
30
+ [1868, ALLOWANCE_HOLDER_ADDRESS], // Soneium
31
+ [2741, ALLOWANCE_HOLDER_ADDRESS], // Abstract
32
+ [5000, ALLOWANCE_HOLDER_ADDRESS], // Mantle
33
+ [8453, ALLOWANCE_HOLDER_ADDRESS], // Base
34
+ [33139, ALLOWANCE_HOLDER_ADDRESS], // Apechain
35
+ [34443, ALLOWANCE_HOLDER_ADDRESS], // Mode
36
+ [42161, ALLOWANCE_HOLDER_ADDRESS], // Arbitrum
37
+ [42220, ALLOWANCE_HOLDER_ADDRESS], // Celo
38
+ [43114, ALLOWANCE_HOLDER_ADDRESS], // Avalanche
39
+ [57073, ALLOWANCE_HOLDER_ADDRESS], // Ink
40
+ [59144, ALLOWANCE_HOLDER_ADDRESS], // Linea
41
+ [80084, ALLOWANCE_HOLDER_ADDRESS], // Berachain
42
+ [81457, ALLOWANCE_HOLDER_ADDRESS], // Blast
43
+ [534352, ALLOWANCE_HOLDER_ADDRESS], // Scroll
44
+ ]);
45
+ /**
46
+ * Get AllowanceHolder contract address for a given chain ID.
47
+ * @throws Error if chain ID is not supported by 0x Swap API.
48
+ */
49
+ export function getAllowanceHolderAddress(chainId) {
50
+ const address = ALLOWANCE_HOLDER_ADDRESSES.get(chainId);
51
+ if (!address) {
52
+ throw new Error(`Unsupported chain ID ${chainId} for 0x Swap. Supported: ${[...ALLOWANCE_HOLDER_ADDRESSES.keys()].join(', ')}`);
53
+ }
54
+ return address;
55
+ }
56
+ // ---------------------------------------------------------------------------
57
+ // Network name -> Chain ID mapping (only networks in NETWORK_TYPES)
58
+ // ---------------------------------------------------------------------------
59
+ /**
60
+ * Maps WAIaaS network type names to EVM chain IDs.
61
+ * Only includes mainnet networks that are supported by both WAIaaS and 0x API.
62
+ */
63
+ export const CHAIN_ID_MAP = {
64
+ 'ethereum-mainnet': 1,
65
+ 'polygon-mainnet': 137,
66
+ 'arbitrum-mainnet': 42161,
67
+ 'optimism-mainnet': 10,
68
+ 'base-mainnet': 8453,
69
+ };
70
+ //# sourceMappingURL=config.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.js","sourceRoot":"","sources":["../../../src/providers/zerox-swap/config.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAWH,MAAM,CAAC,MAAM,mBAAmB,GAAqB;IACnD,OAAO,EAAE,KAAK;IACd,UAAU,EAAE,oBAAoB;IAChC,MAAM,EAAE,EAAE;IACV,kBAAkB,EAAE,GAAG,EAAI,eAAe;IAC1C,cAAc,EAAE,GAAG,EAAQ,eAAe;IAC1C,gBAAgB,EAAE,MAAM,EAAG,YAAY;CACxC,CAAC;AAEF,8EAA8E;AAC9E,4EAA4E;AAC5E,8EAA8E;AAE9E,MAAM,wBAAwB,GAAG,4CAA4C,CAAC;AAE9E;;;GAGG;AACH,MAAM,CAAC,MAAM,0BAA0B,GAAgC,IAAI,GAAG,CAAC;IAC7E,CAAC,CAAC,EAAE,wBAAwB,CAAC,EAAQ,WAAW;IAChD,CAAC,EAAE,EAAE,wBAAwB,CAAC,EAAO,WAAW;IAChD,CAAC,EAAE,EAAE,wBAAwB,CAAC,EAAO,YAAY;IACjD,CAAC,GAAG,EAAE,wBAAwB,CAAC,EAAM,WAAW;IAChD,CAAC,GAAG,EAAE,wBAAwB,CAAC,EAAM,UAAU;IAC/C,CAAC,IAAI,EAAE,wBAAwB,CAAC,EAAK,MAAM;IAC3C,CAAC,IAAI,EAAE,wBAAwB,CAAC,EAAK,UAAU;IAC/C,CAAC,IAAI,EAAE,wBAAwB,CAAC,EAAK,WAAW;IAChD,CAAC,IAAI,EAAE,wBAAwB,CAAC,EAAK,SAAS;IAC9C,CAAC,IAAI,EAAE,wBAAwB,CAAC,EAAK,OAAO;IAC5C,CAAC,KAAK,EAAE,wBAAwB,CAAC,EAAI,WAAW;IAChD,CAAC,KAAK,EAAE,wBAAwB,CAAC,EAAI,OAAO;IAC5C,CAAC,KAAK,EAAE,wBAAwB,CAAC,EAAI,WAAW;IAChD,CAAC,KAAK,EAAE,wBAAwB,CAAC,EAAI,OAAO;IAC5C,CAAC,KAAK,EAAE,wBAAwB,CAAC,EAAI,YAAY;IACjD,CAAC,KAAK,EAAE,wBAAwB,CAAC,EAAI,MAAM;IAC3C,CAAC,KAAK,EAAE,wBAAwB,CAAC,EAAI,QAAQ;IAC7C,CAAC,KAAK,EAAE,wBAAwB,CAAC,EAAI,YAAY;IACjD,CAAC,KAAK,EAAE,wBAAwB,CAAC,EAAI,QAAQ;IAC7C,CAAC,MAAM,EAAE,wBAAwB,CAAC,EAAG,SAAS;CAC/C,CAAC,CAAC;AAEH;;;GAGG;AACH,MAAM,UAAU,yBAAyB,CAAC,OAAe;IACvD,MAAM,OAAO,GAAG,0BAA0B,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;IACxD,IAAI,CAAC,OAAO,EAAE,CAAC;QACb,MAAM,IAAI,KAAK,CACb,wBAAwB,OAAO,4BAA4B,CAAC,GAAG,0BAA0B,CAAC,IAAI,EAAE,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAC/G,CAAC;IACJ,CAAC;IACD,OAAO,OAAO,CAAC;AACjB,CAAC;AAED,8EAA8E;AAC9E,oEAAoE;AACpE,8EAA8E;AAE9E;;;GAGG;AACH,MAAM,CAAC,MAAM,YAAY,GAA2B;IAClD,kBAAkB,EAAE,CAAC;IACrB,iBAAiB,EAAE,GAAG;IACtB,kBAAkB,EAAE,KAAK;IACzB,kBAAkB,EAAE,EAAE;IACtB,cAAc,EAAE,IAAI;CACrB,CAAC"}
@@ -0,0 +1,10 @@
1
+ import type { IActionProvider, ActionProviderMetadata, ActionDefinition, ActionContext, ContractCallRequest } from '@waiaas/core';
2
+ import { type ZeroExSwapConfig } from './config.js';
3
+ export declare class ZeroExSwapActionProvider implements IActionProvider {
4
+ readonly metadata: ActionProviderMetadata;
5
+ readonly actions: readonly ActionDefinition[];
6
+ private readonly config;
7
+ constructor(config?: Partial<ZeroExSwapConfig>);
8
+ resolve(actionName: string, params: Record<string, unknown>, context: ActionContext): Promise<ContractCallRequest[]>;
9
+ }
10
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/providers/zerox-swap/index.ts"],"names":[],"mappings":"AAWA,OAAO,KAAK,EACV,eAAe,EACf,sBAAsB,EACtB,gBAAgB,EAChB,aAAa,EACb,mBAAmB,EACpB,MAAM,cAAc,CAAC;AAEtB,OAAO,EACL,KAAK,gBAAgB,EAItB,MAAM,aAAa,CAAC;AAwCrB,qBAAa,wBAAyB,YAAW,eAAe;IAC9D,QAAQ,CAAC,QAAQ,EAAE,sBAAsB,CAAC;IAC1C,QAAQ,CAAC,OAAO,EAAE,SAAS,gBAAgB,EAAE,CAAC;IAE9C,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAmB;gBAE9B,MAAM,CAAC,EAAE,OAAO,CAAC,gBAAgB,CAAC;IAyBxC,OAAO,CACX,UAAU,EAAE,MAAM,EAClB,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC/B,OAAO,EAAE,aAAa,GACrB,OAAO,CAAC,mBAAmB,EAAE,CAAC;CA4ElC"}
@@ -0,0 +1,131 @@
1
+ /**
2
+ * 0x Swap Action Provider.
3
+ *
4
+ * Implements IActionProvider to resolve 0x DEX swap requests
5
+ * into ContractCallRequest arrays for the sequential pipeline.
6
+ *
7
+ * ERC-20 sells produce [approve, swap] (2 elements).
8
+ * Native ETH sells produce [swap] (1 element).
9
+ */
10
+ import { z } from 'zod';
11
+ import { ChainError } from '@waiaas/core';
12
+ import { ZeroExApiClient } from './zerox-api-client.js';
13
+ import { ZEROX_SWAP_DEFAULTS, getAllowanceHolderAddress, CHAIN_ID_MAP, } from './config.js';
14
+ import { clampSlippageBps, asBps } from '../../common/slippage.js';
15
+ // ---------------------------------------------------------------------------
16
+ // Native ETH placeholder address used by 0x API
17
+ // ---------------------------------------------------------------------------
18
+ const NATIVE_ETH_ADDRESS = '0xeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee';
19
+ // ---------------------------------------------------------------------------
20
+ // ERC-20 approve calldata encoder
21
+ // ---------------------------------------------------------------------------
22
+ /**
23
+ * Encode ERC-20 approve(address spender, uint256 amount) calldata.
24
+ * Function selector: 0x095ea7b3
25
+ */
26
+ function encodeApproveCalldata(spender, amount) {
27
+ const selector = '0x095ea7b3';
28
+ const paddedSpender = spender.slice(2).toLowerCase().padStart(64, '0');
29
+ const paddedAmount = BigInt(amount).toString(16).padStart(64, '0');
30
+ return `${selector}${paddedSpender}${paddedAmount}`;
31
+ }
32
+ // ---------------------------------------------------------------------------
33
+ // Input schema for the swap action
34
+ // ---------------------------------------------------------------------------
35
+ const SwapInputSchema = z.object({
36
+ sellToken: z.string().min(1, 'sellToken is required'),
37
+ buyToken: z.string().min(1, 'buyToken is required'),
38
+ sellAmount: z.string().min(1, 'sellAmount is required (in smallest units)'),
39
+ slippageBps: z.number().int().optional(),
40
+ chainId: z.number().int().optional(),
41
+ });
42
+ // ---------------------------------------------------------------------------
43
+ // Provider implementation
44
+ // ---------------------------------------------------------------------------
45
+ export class ZeroExSwapActionProvider {
46
+ metadata;
47
+ actions;
48
+ config;
49
+ constructor(config) {
50
+ this.config = { ...ZEROX_SWAP_DEFAULTS, ...config };
51
+ this.metadata = {
52
+ name: 'zerox_swap',
53
+ description: '0x DEX aggregator for EVM token swaps via AllowanceHolder flow',
54
+ version: '1.0.0',
55
+ chains: ['ethereum'],
56
+ mcpExpose: true,
57
+ requiresApiKey: true,
58
+ requiredApis: ['0x'],
59
+ };
60
+ this.actions = [
61
+ {
62
+ name: 'swap',
63
+ description: 'Swap tokens on EVM chains via 0x aggregator with slippage protection and AllowanceHolder approval',
64
+ chain: 'ethereum',
65
+ inputSchema: SwapInputSchema,
66
+ riskLevel: 'medium',
67
+ defaultTier: 'DELAY',
68
+ },
69
+ ];
70
+ }
71
+ async resolve(actionName, params, context) {
72
+ // Validate action name
73
+ if (actionName !== 'swap') {
74
+ throw new ChainError('INVALID_INSTRUCTION', 'ethereum', { message: `Unknown action: ${actionName}` });
75
+ }
76
+ // Parse and validate input
77
+ const input = SwapInputSchema.parse(params);
78
+ // SAFE-05: Block same-token swap
79
+ if (input.sellToken.toLowerCase() === input.buyToken.toLowerCase()) {
80
+ throw new ChainError('INVALID_INSTRUCTION', 'ethereum', { message: 'Cannot swap a token for itself' });
81
+ }
82
+ // Resolve chainId: explicit input > CHAIN_ID_MAP lookup > default 1 (Ethereum mainnet)
83
+ const chainId = input.chainId ?? CHAIN_ID_MAP['ethereum-mainnet'] ?? 1;
84
+ // ZXSW-06: Clamp slippage -- default 100bps (1%), max 500bps (5%)
85
+ const slippageBps = clampSlippageBps(input.slippageBps ?? 0, asBps(this.config.defaultSlippageBps), asBps(this.config.maxSlippageBps));
86
+ // Create API client with resolved chainId
87
+ const apiClient = new ZeroExApiClient(this.config, chainId);
88
+ // Get quote from 0x API
89
+ const quote = await apiClient.getQuote({
90
+ sellToken: input.sellToken,
91
+ buyToken: input.buyToken,
92
+ sellAmount: input.sellAmount,
93
+ taker: context.walletAddress,
94
+ slippageBps,
95
+ });
96
+ // ZXSW-07: Check liquidity availability
97
+ if (!quote.liquidityAvailable) {
98
+ throw new ChainError('INVALID_INSTRUCTION', 'ethereum', {
99
+ message: 'No liquidity available for this swap pair',
100
+ });
101
+ }
102
+ // ZXSW-09: Validate AllowanceHolder address
103
+ const expectedAllowanceHolder = getAllowanceHolderAddress(chainId);
104
+ if (quote.transaction.to.toLowerCase() !== expectedAllowanceHolder.toLowerCase()) {
105
+ throw new ChainError('INVALID_INSTRUCTION', 'ethereum', {
106
+ message: `AllowanceHolder address mismatch: expected ${expectedAllowanceHolder}, got ${quote.transaction.to}`,
107
+ });
108
+ }
109
+ // Build result array
110
+ const isNativeEthSell = input.sellToken.toLowerCase() === NATIVE_ETH_ADDRESS;
111
+ const swapRequest = {
112
+ type: 'CONTRACT_CALL',
113
+ to: quote.transaction.to,
114
+ calldata: quote.transaction.data,
115
+ value: quote.transaction.value,
116
+ };
117
+ if (isNativeEthSell) {
118
+ // Native ETH sell: single swap element
119
+ return [swapRequest];
120
+ }
121
+ // ERC-20 sell: approve + swap (ZXSW-04)
122
+ const approveRequest = {
123
+ type: 'CONTRACT_CALL',
124
+ to: input.sellToken,
125
+ calldata: encodeApproveCalldata(expectedAllowanceHolder, input.sellAmount),
126
+ value: '0',
127
+ };
128
+ return [approveRequest, swapRequest];
129
+ }
130
+ }
131
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/providers/zerox-swap/index.ts"],"names":[],"mappings":"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"}