Add Ophis skill: MEV-protected same-chain swaps (CoW Protocol)#563
Open
san-npm wants to merge 2 commits into
Open
Add Ophis skill: MEV-protected same-chain swaps (CoW Protocol)#563san-npm wants to merge 2 commits into
san-npm wants to merge 2 commits into
Conversation
Same-chain token swaps routed through Ophis (CoW intent settlement): batch-auction best execution, surplus returned to the trader, gasless for the user. Executes from a Bankr wallet via the presign scheme — approve the VaultRelayer and authorize the order on-chain with setPreSignature, both through the Bankr Submit API. Complements the bridging skills (same-chain, not cross-chain). Adds ophis/ + README row. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
san-npm
pushed a commit
to ophis-fi/ophis
that referenced
this pull request
Jul 13, 2026
… from, reject reverted submits Addresses PR #815 Codex review: - Sign the GROSS sellAmount with feeAmount 0 (P1): the order echoed the quote's net sellAmount + feeAmount, which the orderbook rejects for a non-zero fee and under-sells otherwise. Bind gross (sellAmount + feeAmount) == requested; require the quote fields present; self-set validTo. - Quote with signingScheme presign (P2) to match the submitted presign order, and send the appData HASH (not the full JSON, which the strict schema 400s). - ophis-quote.py: use a non-zero from (CoW zero-address deny-list); optional trader-address override. - bankr_submit: reject a reverted/failed status instead of treating any returned transactionHash as success (P2). - Document the best-effort enroll_wallet empty except. Deferred (need external verification, not doable from here): migrating off the Bankr /agent/* endpoints to /wallet/* (must be checked against the current Bankr API — same review applies on upstream BankrBot/skills#563), and a USDT-style allowance reset (this presign path has no allowance read; needs an RPC read or a known-nonstandard-token list). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
san-npm
pushed a commit
to ophis-fi/ophis
that referenced
this pull request
Jul 13, 2026
The legacy /agent/balances and /agent/submit endpoints were REMOVED from the Bankr API (confirmed against BankrBot/skills SKILL.md + references/sign-submit-api.md), so the skill could not resolve a wallet or submit a tx on the current API. - bankr_wallet_address: GET /wallet/me (was /agent/balances). Extracts the first 0x EVM address across the plausible keys (evmAddress/address/evm/wallet/ addresses.*) and validates the 0x40-hex shape, so it never picks Bankr's Solana address. Dropped the now-unneeded chain-slug arg + BANKR_SLUG map. - bankr_submit: POST /wallet/submit (was /agent/submit). Identical body. Status handling aligned to the documented values success|reverted|pending: reject reverted, require an explicit success, and refuse an unconfirmed pending (never accept a bare hash when a status is present). - Updated SKILL.md + references/api.md to the /wallet/* endpoints. Verify against a live GET /wallet/me for the exact EVM-address key. Same change must be mirrored to upstream BankrBot/skills#563. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Sync from the ophis-fi/ophis source of truth (reviewed via Codex): - Migrate off the removed /agent/balances + /agent/submit to GET /wallet/me and POST /wallet/submit (identical submit body). Resolve the EVM wallet address by 0x-40-hex format (never a Solana address). Submit status handling rejects reverted, refuses an unconfirmed pending, and only accepts a bare tx hash when no status field is present. - Sign the GROSS sellAmount with feeAmount 0 and bind gross == requested (CoW/ Ophis take the fee from surplus + the appData partner fee; the orderbook rejects a non-zero signed feeAmount). Self-set validTo; require quote fields present. - Quote with signingScheme presign (matches the submitted presign order) and send the appData hash (the strict schema 400s the full doc on a referral'd quote). - ophis-quote.py: non-zero from (CoW zero-address deny-list), optional trader arg. - _http: https scheme guard; validate the 0x address before it enters the enroll URL. 🤖 Generated with [Claude Code](https://claude.com/claude-code)
san-npm
added a commit
to ophis-fi/ophis
that referenced
this pull request
Jul 13, 2026
* feat(integrations): Bankr skill scaffold — Ophis MEV-protected same-chain swap
A plug-and-play Bankr Skill (SKILL.md + catalog.json + scripts + references)
that lets Bankr AI agents execute MEV-protected same-chain swaps through Ophis
(CoW Protocol intent settlement) from a Bankr-managed wallet.
Flow: quote -> build Ophis partner-fee appData -> PUT app_data -> approve the CoW
VaultRelayer via the Bankr Submit API -> POST a presign order -> authorize it
on-chain with setPreSignature via Bankr Submit. Uses the presign scheme so the
Bankr wallet only submits transactions (no raw message-signing). Monetized via the
appData partnerFee (recipient = Ophis Safe; optional ophisReferrer code = rebate).
Endpoints/addresses/appData shape are grounded in @ophis/sdk (see references/).
appData hashing + approve/setPreSignature ABI encoding verified locally. Positioned
as same-chain best execution — complementary to the bridging skills (symbiosis/trails).
Not yet submitted to BankrBot/skills (review first).
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
* fix(bankr-skill): harden per internal security audit (fund-safety + fee-routing)
3-lens adversarial audit (fund-safety / fee-routing / protocol-correctness) of the
Ophis swap skill, all findings remediated + re-verified (PASS):
- HIGH: approve() was sent to the VaultRelayer instead of the ERC-20 sell token
(spender was right, tx target was wrong) → no allowance, order unfillable. Fixed:
tx `to` = sell token; spender stays the relayer.
- HIGH: slippage_bps was unbounded → min_buy could floor to 0 (accept-any-price /
max-sandwich). Fixed: reject slippage outside [0,5000] and refuse min_buy<=0.
- HIGH: a network error to the rebate indexer crashed the whole swap (_http only
caught HTTPError; enroll_wallet only caught SystemExit). Fixed: _http catches
URLError/timeout (fail-closed); enroll_wallet is truly best-effort (except Exception).
- MED: the signed order now echoes the quote's sellAmount/feeAmount (approve covers
both), matching the @ophis/sdk reference, instead of raw input + hardcoded fee 0.
- MED: referral codes are validated against ^[a-z0-9_-]{3,64}$ and fail loudly, so an
unmatchable code can't silently forfeit the rebate.
- MED: bankr_submit also accepts a returned transactionHash as success.
- LOW: exact EIP-7528 native sentinel match (both sell and buy side); SKILL.md step
order fixed (POST order -> setPreSignature); stable-pair fee behavior documented.
Green: py_compile + appData-hash/ABI/referral smoke tests pass. Not pushed to
BankrBot/skills — internal review only.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
* bankr: sign feeAmount 0 + gross, presign quote scheme, non-zero quote from, reject reverted submits
Addresses PR #815 Codex review:
- Sign the GROSS sellAmount with feeAmount 0 (P1): the order echoed the quote's
net sellAmount + feeAmount, which the orderbook rejects for a non-zero fee and
under-sells otherwise. Bind gross (sellAmount + feeAmount) == requested; require
the quote fields present; self-set validTo.
- Quote with signingScheme presign (P2) to match the submitted presign order, and
send the appData HASH (not the full JSON, which the strict schema 400s).
- ophis-quote.py: use a non-zero from (CoW zero-address deny-list); optional
trader-address override.
- bankr_submit: reject a reverted/failed status instead of treating any returned
transactionHash as success (P2).
- Document the best-effort enroll_wallet empty except.
Deferred (need external verification, not doable from here): migrating off the
Bankr /agent/* endpoints to /wallet/* (must be checked against the current Bankr
API — same review applies on upstream BankrBot/skills#563), and a USDT-style
allowance reset (this presign path has no allowance read; needs an RPC read or a
known-nonstandard-token list).
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
* bankr: https scheme-guard in _http + validate wallet in enroll (semgrep)
Add the https:// scheme guard the sibling adapter cores already have (blocks
file://, http://), validate the 0x-address before it enters the enroll URL path,
and annotate the two urllib calls (URLs are scheme-guarded + built from fixed
https maps). Clears the semgrep dynamic-urllib findings.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
* bankr: single explicit return in _http (no implicit None fall-through)
Addresses the Codex PR #815 review: _http is typed -> dict but returned inside the
try while the except branches sys.exit; a naive analyzer that does not model
sys.exit as NoReturn sees a possible implicit return None. Move the parse to a
single trailing return so no path can fall through to None.
* bankr: migrate to the current Wallet API (/wallet/me, /wallet/submit)
The legacy /agent/balances and /agent/submit endpoints were REMOVED from the
Bankr API (confirmed against BankrBot/skills SKILL.md + references/sign-submit-api.md),
so the skill could not resolve a wallet or submit a tx on the current API.
- bankr_wallet_address: GET /wallet/me (was /agent/balances). Extracts the first
0x EVM address across the plausible keys (evmAddress/address/evm/wallet/
addresses.*) and validates the 0x40-hex shape, so it never picks Bankr's Solana
address. Dropped the now-unneeded chain-slug arg + BANKR_SLUG map.
- bankr_submit: POST /wallet/submit (was /agent/submit). Identical body. Status
handling aligned to the documented values success|reverted|pending: reject
reverted, require an explicit success, and refuse an unconfirmed pending
(never accept a bare hash when a status is present).
- Updated SKILL.md + references/api.md to the /wallet/* endpoints.
Verify against a live GET /wallet/me for the exact EVM-address key. Same change
must be mirrored to upstream BankrBot/skills#563.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
* bankr: format-based /wallet/me address + strict submit status (Codex)
- bankr_wallet_address resolves the EVM address by 0x-40-hex FORMAT (named keys
then a top-level scan), guarded on a dict response, so it needs no exact-key
knowledge, never returns a Solana address, and errors cleanly on a non-object
response.
- bankr_submit rejects status 'pending' before any success check (an unconfirmed
approval/presign is refused even if success:true), and only falls back to a
bare transactionHash when NO status/state key is present.
Codex (gpt-5.6-sol): pass. semgrep clean.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
---------
Co-authored-by: Claude <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Ophis — MEV-protected same-chain swaps (CoW Protocol)
Adds the
ophisskill: same-chain token swaps routed through Ophis, a CoW-Protocol intent-settlement layer. Instead of an AMM swap that can be sandwiched, the order settles in a batch auction — uniform clearing price, surplus (price improvement) returned to the trader, and gasless for the user (solvers pay the settlement gas; the wallet only authorizes).Complements the existing bridging skills (
symbiosis,trails) — this is same-chain best execution, not cross-chain.How it executes from a Bankr wallet
CoW orders are off-chain signed intents, so this skill uses the presign scheme — the Bankr wallet only submits transactions, never signs a raw message:
quote→ build Ophis appData →PUT /app_data/{hash}→ approve the CoW VaultRelayer (via Bankr Submit) →POST /orderswithsigningScheme: "presign"(returns the order UID) →setPreSignature(uid, true)on the Settlement contract (via Bankr Submit) → solvers settle it in the next batch.Chains
Base and Unichain are the strongest targets (Bankr-native and a live Ophis stack); also Arbitrum, Polygon, BNB, Ethereum, Optimism. Same-chain only.
Files
ophis/SKILL.md,ophis/catalog.json,ophis/scripts/{ophis_common,ophis-quote,ophis-swap}.py,ophis/references/{api,chains-and-tokens}.md. Requirespython3, a keccak library (pysha3 / pycryptodome / eth-hash), andBANKR_API_KEY.Notes for reviewers
@ophis/sdk); appData hashing and the approve /setPreSignatureABI encoding are unit-verified.references/api.md): (a) the orderbook acceptingsigningScheme: "presign"with an empty signature on each target chain, and (b) Bankr's exact/agent/submitsuccess/response shape. All HTTP failures are fail-closed (the script exits; no partial fund movement).Happy to iterate on anything.