Gate-first wallet workflow coordinator for OutLayer.
This service implements the first executable sequential NEAR Intents lane:
OutLayer implicit wallet -> signed NEP-413 Intents payloads -> NEP-366 delegates
-> gate.sequential.near -> ordered receipt evidence.
This is the first production coordinator slice for the mainnet dust proof. It is not a full historical coordinator restoration, and it intentionally leaves direct-user setup/execution for a later lane.
POST /wallet/v1/sequential-batchGET /wallet/v1/sequential-batch/{request_id}POST /wallet/v1/workflows/planPOST /wallet/v1/workflows/executeGET /wallet/v1/workflows/{request_id}POST /wallet/v1/direct-user/function-call-key/prepareGET /wallet/v1/direct-user/function-call-key/statusPOST /wallet/v1/direct-user/function-call/executeGET /wallet/v1/direct-user/function-call/{request_id}
Wallet calls authenticate with either:
X-Wallet-IdplusX-Internal-Wallet-Authfor worker/WASI calls.Authorization: Bearer wk_...for configured wallet API keys.
Planner lanes:
gate_proxy: executable in this service forintents.transfer,intents.swap,intents.execute_raw, and explicit proxy-safe sequential calls.funding_setup: planned but returned asrequires_funding_setup; wrap, storage, deposits, and balance reads still run through existing wallet routes.direct_user: planned but returned asrequires_direct_user_setup; true predecessor execution is a later milestone.reject: ambiguous or predecessor-sensitive gate calls fail before policy checks or signing.
The direct-user counter proof is the only executable direct-user lane in this
branch. It is scoped to mike.near signing count.mike.near::increase with a
FunctionCall access key derived from the mike.sequential.near namespace.
Gate execution:
- Persist the idempotency record before signing or broadcasting.
- Policy-check every gate step.
- Build/sign NEP-413 Intents payloads for
intents.near.execute_intents. - Ask keystore for one NEP-366 delegate per call.
- Submit
gate.submit_intentasynchronously with the relayer. - Poll only outer submit receipts for
intent_submitted. - Call
resume_batch_chained(intent_ids)with the approver and configured fee. - Poll dispatch outcomes and return ordered evidence.
Returned records include proxy_predecessor, predecessor_model,
ordering_model, signed payload/delegate material, submit hashes, ordered intent
IDs, resume hash, dispatch receipts, block heights, final status, and
user-visible errors.
External calls:
- Keystore
/wallet/derive-addressto resolve the OutLayer implicit wallet. - Keystore
/wallet/check-policybefore any signing. - Keystore
/wallet/sign-nep413and/wallet/sign-nep366-delegatefor gate execution. - Keystore
/wallet/direct-user/prepare-function-call-keyand/wallet/direct-user/sign-scoped-function-callsfor the counter proof. - NEAR RPC for block height, async transaction broadcast, outer submit receipt polling, dispatch outcome polling, direct-user access-key checks, counter reads, final transaction evidence, and read-only gate preflight.
The read-only preflight helper queries gate owner, approver, relayer whitelist, pending count, and the 1-3 call fee tier. It does not broadcast.
The database enforces one record per (wallet_id, idempotency_key). A retry with
the same body returns the same request record and evidence. A retry with a
different body for the same key returns conflict. If callers omit an idempotency
key, the service generates a server-side one for a one-shot request.
This service can perform real gate submissions when configured with live relayer and approver keys. Tests do not broadcast. Human operators still handle deployment, service restart, Docker, secrets, account funding, and any mainnet broadcast approval.
Required environment:
DATABASE_URLINTERNAL_WALLET_AUTH_TOKENKEYSTORE_URLKEYSTORE_AUTH_TOKENRELAYER_ACCOUNT_IDRELAYER_SECRET_KEYAPPROVER_ACCOUNT_IDAPPROVER_SECRET_KEY
Optional environment:
BIND_ADDR, default0.0.0.0:8080WALLET_API_KEYS_JSON, JSON object of API key to wallet IDNEAR_RPC_URL, defaulthttps://rpc.mainnet.near.orgSEQUENTIAL_GATE_ID, defaultgate.sequential.nearGATE_FEE_1_TO_3_YOCTO, default30000000000000000000000SUBMIT_INTENT_GAS, default50000000000000RESUME_BATCH_GAS, default100000000000000DELEGATE_VALIDITY_BLOCKS, default180NEAR_POLL_TIMEOUT_SECS, default60NEAR_POLL_INTERVAL_MS, default750INTENTS_DEADLINE_SECS, default300
Run migrations before starting the service:
sqlx migrate runThe first migration creates wallet_workflow_records, keyed by
(wallet_id, idempotency_key), with JSON fields for original request, workflow
spec, plan evidence, signed payloads, delegates, direct signed transactions,
transaction hashes, intent IDs, dispatch evidence, direct-user scope/evidence,
final status, and user-visible errors.
cargo fmt
cargo clippy --all-targets -- -D warnings
cargo test
SQLX_OFFLINE=true cargo check
git diff --check