web3-wallet-worker Isolate Profile

On-chain wallet isolate: EVM transfers, Uniswap V3 swaps (Ethereum/Arbitrum), Jupiter Swap V2 (Solana), and fail-closed security policy.

This page

The web3-wallet-worker is the on-chain gateway of the Hoox trading ecosystem. It holds EVM and Solana signing material as Workers Secrets, prices mutating txs server-side, and executes Uniswap V3 (Ethereum, Arbitrum) plus Jupiter Swap V2 (Solana). trade-worker calls POST /swap over the WEB3_WALLET_SERVICE binding.


⚡ 1. Declared Wrangler Configurations & Bindings

The web3-wallet-worker does not expose a public URL, communicating internally via V8 Service Bindings. Its wrangler.jsonc specifies:

jsonc
{
  "name": "web3-wallet-worker",
  "main": "src/index.ts",
  "compatibility_date": "2026-06-08",
  "compatibility_flags": ["nodejs_compat"],
  "account_id": "<CLOUDFLARE_ACCOUNT_ID>",
  "placement": {
    "mode": "smart",
  },
  "vars": {
    "RPC_URL_ETHEREUM": "https://eth.llamarpc.com",
    "RPC_URL_ARBITRUM": "https://arbitrum.llamarpc.com",
    "RPC_URL_SOLANA": "https://solana-rpc.publicnode.com",
  },
  "kv_namespaces": [
    {
      "binding": "CONFIG_KV",
      "id": "<KV_NAMESPACE_ID>",
    },
    {
      "binding": "WALLET_CONFIG_KV",
      "id": "<KV_NAMESPACE_ID>",
    },
  ],
  "d1_databases": [
    {
      "binding": "TRANSACTIONS_DB",
      "database_id": "<D1_DATABASE_ID>",
      "database_name": "web3-wallet-transactions",
    },
  ],
  "services": [
    { "binding": "TELEGRAM_SERVICE", "service": "telegram-worker" },
    { "binding": "ANALYTICS_SERVICE", "service": "analytics-worker" },
  ],
}

Secrets (INTERNAL_KEY_BINDING, WALLET_EXECUTE_KEY_BINDING, WALLET_MNEMONIC_SECRET, WALLET_PK_SECRET, SOLANA_PRIVATE_KEY, JUPITER_API_KEY) are set with wrangler secret put. The isolate has no public URL. Operators use the gateway /wallet/* proxy; trade-worker calls POST /swap over WEB3_WALLET_SERVICE.


🔑 2. Environmental Variables & Encrypted Secrets

  • WALLET_PK_SECRET: Encrypted private key used for single-account execution.
  • WALLET_MNEMONIC_SECRET: Encrypted 12 or 24-word HD wallet seed phrase used to derive multiple accounts.
  • INTERNAL_KEY_BINDING: Shared mesh auth. Fallback when WALLET_EXECUTE_KEY_BINDING is unset.
  • WALLET_EXECUTE_KEY_BINDING: Preferred key for /swap (written by hoox setup).
  • SOLANA_PRIVATE_KEY: Base58 32-byte seed or 64-byte Phantom secret. Auto-generated by hoox setup if missing; never logged.
  • JUPITER_API_KEY: x-api-key for https://api.jup.ag/swap/v2 (portal).
  • RPC_URL_*: Per-chain JSON-RPC (RPC_URL_ETHEREUM, RPC_URL_ARBITRUM, RPC_URL_SOLANA) or KV wallet:rpc:&lt;chain&gt;. Empty Arbitrum/Solana URLs are filled by hoox setup.

Local Development Mocking (.dev.vars)

bash
WALLET_PK_SECRET=0x0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef
WALLET_MNEMONIC_SECRET="abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon about"
INTERNAL_KEY_BINDING=dev_shared_internal_security_key
WALLET_EXECUTE_KEY_BINDING=dev_shared_internal_security_key
# SOLANA_PRIVATE_KEY=   # hoox setup generates if unset
# JUPITER_API_KEY=

🔌 3. Internal REST API Specification

Note: For the canonical endpoint directory with full request/response examples across all workers, see /docs/devops/api/endpoints.

All endpoints except GET /health require X-Internal-Auth-Key (fail-closed via createInternalAuthMiddleware).

MethodPathPurpose
GET/Derive wallet address from secrets (identity init)
GET/healthLiveness (unauthenticated)
GET/statusAddress + config summary
GET / PUT/configRead / deep-merge wallet security + DEX config
GET/balance?chain=&address=&token=Native or ERC-20 balance
POST/transferERC-20 transfer (server-side USD pricing + policy)
POST/approveERC-20 approve (spender whitelist + maxApprovalAmount)
GET/quoteDEX quote (read-only)
POST/swapDEX swap: Uniswap V2/V3 (ethereum, arbitrum) or Jupiter Swap V2 (solana)
GET/transactionsList stored tx records (D1)

Swap (POST /swap)

Called by trade-worker over WEB3_WALLET_SERVICE. Prefer WALLET_EXECUTE_KEY_BINDING for X-Internal-Auth-Key. Forward Idempotency-Key.

json
{
  "chain": "ethereum",
  "tokenIn": "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48",
  "tokenOut": "0x0000000000000000000000000000000000000000",
  "amountIn": "100000000",
  "dexVersion": "v3",
  "slippageBps": 50
}
  • chain: "solana" branches before EVM address checks. Mints are base58. Requires SOLANA_PRIVATE_KEY + JUPITER_API_KEY.
  • dexVersion: "v3" uses SwapRouter02 + QuoterV2 (0x68b3…Fc45 / 0x61fF…B21e) and fee tiers 100, 500, 3000, 10000. Native out unwraps via unwrapWETH9.
  • USD notional is priced server-side and fail-closed. SwapRouter02 is treated as a known DEX router for whitelist.

Operator guide: DEX spot swaps.

A. Transfer tokens

  • Endpoint: POST /transfer
  • Headers: X-Internal-Auth-Key: <INTERNAL_KEY_BINDING>
  • JSON Payload:
    json
    {'{'}
      "chain": "ethereum",
      "tokenAddress": "0x6b175474e89094c44da98b954eedeac495271d0f",
      "to": "0x70997970c51812dc3a010c7d01b50e0d17dc79c8",
      "amount": "1000000000000000000"
    {'}'}
    
  • Notes: amount is wei as a non-negative integer string. Zero-address recipients are rejected. Client valueUsd is ignored — USD notional is priced server-side (stablecoin / native oracle / DEX quote) and fail-closed if unpriceable.
  • Success Response (200 OK):
    json
    {'{'}
      "txHash": "0x53a9284739ebfd10482da73cbcfd10482da73cbcfd10482da73cbcfd10482ab",
      "id": "9b1deb4d-3b7d-4bad-9bdd-2b0d7b3dcb6d"
    {'}'}
    

B. Query Token Balance

  • Endpoint: GET /balance?chain=ethereum&address=0x…&token=0x…
  • Headers: X-Internal-Auth-Key: <INTERNAL_KEY_BINDING>
  • Success Response (200 OK):
    json
    {'{'}
      "chain": "polygon",
      "token": {'{'}
        "address": "0xc2132d05d31c914a87c6611c10748aeb04b58e8f",
        "symbol": "USDT",
        "decimals": 6
      {'}'},
      "balance": "1485500000",
      "balanceFormatted": "1485.5"
    {'}'}
    

🛡️ 4. On-Chain Security Best Practices

Operating hot wallets on public blockchain networks introduces extreme security vectors:

  • Harden Private Keys: Never write keys to wrangler config files or print them in telemetry logs. Keys are validated with /^0x?[0-9a-fA-F]{64}$/; mnemonics require 12–24 words. Wallet instances are cached under opaque keys (not the secret material). Error logs use toError(...).message only — never the secret value.
  • Gas Price Limit Trap: Before signing /transfer, /approve, or /swap, the worker reads web3:max_gas_price_gwei from CONFIG_KV. If set to a positive number and current maxFeePerGas/gasPrice exceeds that gwei value, the request is forbidden (fail-closed). Unset / invalid → trap disabled. Fee-data read failures also block when the trap is enabled.
  • USD value caps: Mutating routes enforce security.maxTransactionValueUsd using server-side pricing (resolveEnforcedValueUsd). High-value txs require confirmation when requireConfirmation is true (409 CONFIRMATION_REQUIRED).
  • Whitelist: When whitelistedContractsOnly is true, destinations/tokens must be listed (DEX router addresses for the chain are auto-allowed for swaps).
  • RPC safety: Provider URLs must be https (or http only for localhost/Anvil). Cloud metadata hosts and non-local http are rejected.
  • Amount / address validation: Integer wei strings only; zero-address recipients and spenders rejected (native token zero-address still allowed as swap token sentinel).
  • Isolate Access: All mutating calls require internal auth. Prefer Service Bindings over public exposure.

Tip

Testing on-chain logic locally? Use the Docker runtime stack (hoox dev start --runtime docker) to launch an isolated Hardhat/Anvil node container and test private wallet swaps on a simulated local EVM fork safely!

🔗 Next Steps