Pair and use an EVM and/or Solana wallet via WalletConnect v2. **No authentication required** — available to every user (including unauthenticated/anonymous). Non-custodial: the server never holds keys and the user approves every signature/transaction in their own wallet. **Pairing proposal** is controlled per request via optional `pairingTarget` on `action: "connect"`: `eth` (default, eip155 only), `solana`, or `both`. Many mobile wallets fail if eip155 and solana are proposed together; prefer `eth` or `solana` unless the user needs both in one session. **Every call must include `action`** (string).
**Connect QR (critical for assistants):** On `action: "connect"`, successful responses return **(1) an MCP `type: "image"` PNG** of the pairing QR (render this even if the host has no `resources/read`), then **(2) optional `resource_link`**, then **(3) text JSON** with `pairingQrResourceUri`, `presentation`, `nextSteps`, `url`, optional `mobileDeeplinks`, etc. **Desktop / scan UX:** show the image content block first. **Mobile / no-camera:** follow `nextSteps`; when present, `mobileDeeplinks` lists HTTPS `url` (+ `nativeUrl`) per curated WalletConnect wallet. Raw `wc:` (`url` / `walletConnectLinkForUser`) remains fallback. **Avoid calling `connect` again while pairing is still in progress** unless the user must reset — pass `walletSessionToken` to resume the same pairing after MCP session rotation.
**Flow:** (1) `connect` as above. (2) User approves in the wallet (EVM only, Solana only, or both). (3) `status` until `kind` is `session` — optional `evm` / `solana` blocks; `address`/`chains` remain legacy EVM when EVM is connected. (4) `sign` / `send_transaction` or swap `execute=true` (swap execute remains EVM unless extended elsewhere). `kind: "pending"` on `status` is success — keep polling.
**Actions (exact JSON shapes):**
- **connect** — `{ "action": "connect", "sessionTtlDays"?: number, "pairingTarget"?: "eth" | "solana" | "both", "walletSessionToken"?: string }`
- **status** — `{ "action": "status" }` (anonymous sessions include a `terms` block showing the connected wallet's 1inch Terms-of-Use acceptance state)
- **sign** — EVM: `personal_sign` / `eth_signTypedData_v4`. Solana: `solana_signMessage` / `solana_signTransaction` (see schema fields `params`, `chainId`, `solanaChainId`).
- **send_transaction** — EVM: `tx.to`, numeric `tx.chainId`. Solana: string `tx.chainId` (`solana:...`), `tx.serializedTransaction` (base64). Set `tx.namespace` when both WC namespaces are active and the payload is ambiguous.
- **accept_terms** — `{ "action": "accept_terms", "address"?: "0x…" }`. When the user has not accepted yet: **write to the user** that they must sign the 1inch Terms of Use in their wallet (one-time, gas-free personal_sign), **then immediately call this action in the same turn** so the signature prompt appears. You trigger the signing — do not only instruct them to sign. Required before anonymous aqua create_position / close_position. Idempotent — already-accepted wallets return immediately without a prompt.
- **disconnect** — `{ "action": "disconnect" }`
**Anonymous durable sessions:** for unauthenticated callers, pairing `connect` (QR) returns a `walletSessionToken`. Store it and pass it back as `walletSessionToken` on later `status` / `sign` / `send_transaction` / `accept_terms` / `disconnect` **and** on a later `connect` to resume the same pairing after MCP session rotation. A tokenless `connect` that resumes an already-approved session does **not** mint a new token — within this MCP session, `status` / `sign` still work via `anon:{sessionId}`. Authenticated callers ignore the token (their WC session is scoped by org/app).
Non-custodial relay; no authentication required.