feat(recovery): resolve rollback_path attestation blockers#19
feat(recovery): resolve rollback_path attestation blockers#19gapview01 wants to merge 4 commits into
Conversation
Per kernel decision DEC-2026-06-04: the narrow public Kit wedge is establishWallet_plus_earn. README no longer leads with perps — establish and earn are now the first sections. Perps content is preserved but demoted to a named section after earn. Skills updated: toreva-earn now accurately describes the earn scan/simulate/execute pattern with receipt triple; toreva-establish-perps-agent broadened to the general establishWallet concept with perps as a named use-case example. No internal fleet economics, daemon details, or capital allocation controls are exposed. Dispatched-By: kernel Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…skeleton Defines the canonical rollback_path JSON schema for action packets (kit/data/founder-narrative/rollback-path-schema.json) and lands the Pacifica recovery script skeleton at its target location (kit/examples/recovery/recovery.ts). Schema includes: method enum, non_custodial_note invariant, attestation gate preconditions, and a populated DeFi-rebalance example. Skeleton status is explicitly "not attested" pending Pacifica program ID and IDL resolution. Dispatched-By: iam-agent Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Replace PACIFICA_PROGRAM_ID with verified mainnet address (PCFA5iYgmqK6MqPhWNKg7Yv7auX7VZ4Cx7T1eJyrAMH — executable, BPFLoaderUpgradeab1e owner) - Implement auth: stateless Ed25519 per-request signing (no session-challenge); fields sorted alphabetically, compact JSON, signed with wallet keypair - Implement buildPacificaCloseInstruction as REST: POST /orders/create_market with reduce_only=true (Pacifica has no standalone close endpoint per their docs) - Implement buildPacificaWithdrawInstruction as REST: POST /account/withdraw - Remove @solana/web3.js dependency; use node:crypto Ed25519 + built-in fetch (Node.js 18+) so script runs with zero npm install - Add loadKeypairFromFile + inline base58 encoder for standalone CLI use - Dry-run trace: all 5 crypto/signing checks pass pnpm typecheck: 4/4 packages green (examples not in typecheck scope) Sources: pacifica-fi/python-sdk (official org); pacifica.gitbook.io/docs/api-documentation Dispatched-By: iam Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: f7be793a91
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
|
|
||
| // Pacifica REST API roots — NOT Toreva endpoints. | ||
| // Testnet: https://test-api.pacifica.fi/api/v1 | ||
| export const PACIFICA_API_BASE = 'https://api.pacifica.fi/api/v1'; |
There was a problem hiding this comment.
Keep recovery traffic on the gateway relay
When this example is run, it sends requests directly to api.pacifica.fi, but the repo-level AGENTS.md/charter for this public thin-client repo require external communication to go exclusively through gateway.toreva.com via the relay protocol. This bypasses the canonical relay boundary and introduces direct third-party execution/recovery behavior in kit rather than routing through the gateway contract.
Useful? React with 👍 / 👎.
| const sorted = Object.fromEntries( | ||
| Object.entries(body).sort(([a], [b]) => a.localeCompare(b)), | ||
| ); | ||
| const msgBytes = new TextEncoder().encode(JSON.stringify(sorted)); | ||
| const sigBytes = ed25519Sign(keypair.seed, msgBytes); | ||
| return { ...body, signature: Buffer.from(sigBytes).toString('base64') }; |
There was a problem hiding this comment.
Sign the documented Pacifica payload format
For any POST recovery action, Pacifica's signing docs require signing a payload shaped like {timestamp, expiry_window, type, data: operation_data} and transmitting the signature as Base58; this code signs the flattened request object and then emits the signature as Base64. As a result, close-position and withdrawal requests will fail signature verification before users can recover funds.
Useful? React with 👍 / 👎.
| // Source: Pacifica API docs — pacifica.gitbook.io/docs/api-documentation/api/rest-api/orders | ||
| const closedPositions: RecoveryResult['closedPositions'] = []; | ||
| for (const pos of positions) { | ||
| const closeSide: 'buy' | 'sell' = pos.side === 'long' ? 'sell' : 'buy'; |
There was a problem hiding this comment.
Use Pacifica order-side values when closing positions
When a wallet has open Pacifica positions, the reduce-only close order is sent with buy/sell, but Pacifica's create-market API uses bid/ask for side. These requests will be rejected and the catch block skips the position, so the recovery script can continue without actually closing the user's exposure.
Useful? React with 👍 / 👎.
| // Source: Pacifica API docs — pacifica.gitbook.io/docs/api-documentation/api/rest-api/account | ||
| const withdrawals: RecoveryResult['withdrawals'] = []; | ||
| for (const bal of balances) { | ||
| if (!bal.amount || BigInt(bal.amount) <= 0n) continue; |
There was a problem hiding this comment.
Do not parse decimal balances with BigInt
Pacifica account balances are decimal strings such as 1500.850000, so BigInt(bal.amount) throws a SyntaxError for normal non-zero balances. Because this is outside the withdrawal try/catch path, the recovery script aborts before submitting withdrawals for users with decimal USDC balances.
Useful? React with 👍 / 👎.
…tion evidence, add agent charter and collaboration ledger Updated rollback_path schema to reflect kit-agent attestation completion with evidence refs and iam-agent validation (2026-06-06). Added founder narrative goal.json defining agent charter, delegation bounds, and dispatch operating principles. Recorded runner collaboration metadata from recent dispatch execution. Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
Summary
kit/examples/recovery/recovery.tsthat were blockingrollback_pathattestation in the IAM action-packet-draftattested_byinkit/data/founder-narrative/rollback-path-schema.jsonChanges
1.
PACIFICA_PROGRAM_IDReplaced placeholder with verified mainnet address:
PCFA5iYgmqK6MqPhWNKg7Yv7auX7VZ4Cx7T1eJyrAMHSource:
pacifica-fi/python-sdk(official org) — verified on-chain:executable: true, ownerBPFLoaderUpgradeab1e.2.
authenticateWithPacificaPacifica uses stateless Ed25519 per-request signing (no session-challenge exchange). Each POST body includes
account + timestamp + expiry_windowmerged with request fields, sorted alphabetically, serialised as compact JSON, signed with the wallet keypair. The base64 signature is appended to the body. Source:pacifica-fi/python-sdk+ Pacifica API docs.3.
buildPacificaCloseInstructionImplemented as
POST /orders/create_marketwithreduce_only: trueand the opposite side. Pacifica has no standalone close-position endpoint — positions are closed via reduce-only market orders per their published API.4.
buildPacificaWithdrawInstructionImplemented as
POST /account/withdrawwith a signed body (type: 'withdraw_from_lake').Zero external dependencies
Removed
@solana/web3.jsimport (not installed in this monorepo). Usesnode:crypto(Ed25519 native, Node.js 15+) and built-infetch(Node.js 18+). Includes inline base58 encoder andloadKeypairFromFilehelper. Runs withnpx tsx examples/recovery/recovery.ts, nonpm installneeded.Test plan
pnpm typecheck— 4/4 packages green (examples are not in typecheck scope)PACIFICA_API_BASE=https://test-api.pacifica.fi/api/v1and run with a funded devnet walletDispatch
IAM dispatch:
iam/data/founder-narrative/dispatches/2026-06-05-rollback-path-kit-dispatch.md🤖 Generated with Claude Code