Skip to content

demo: add acp swap - gasless cross-chain swaps via Geodesics - #76

Open
0x-zeph wants to merge 1 commit into
Virtual-Protocol:mainfrom
0x-zeph:feat/geodesics-swap
Open

demo: add acp swap - gasless cross-chain swaps via Geodesics#76
0x-zeph wants to merge 1 commit into
Virtual-Protocol:mainfrom
0x-zeph:feat/geodesics-swap

Conversation

@0x-zeph

@0x-zeph 0x-zeph commented Jul 30, 2026

Copy link
Copy Markdown

What

acp swap: demo PR for gasless cross-chain swaps for agent wallets via the Geodesics API (docs.geodesics.ai). Complements acp trade with a different execution model: the API quotes and builds the route server-side, the wallet signs one payload (EIP-191 op hash on EVM, the prebuilt v0 tx on Solana), the server submits, the CLI polls to settlement.

  • Gasless on every origin, Solana included: no gas token, no fee float. First swap from a new EVM chain onboards the wallet in-swap (one-time EIP-7702 authorization through the existing signer service, no activation tx).
  • Trade-style flags, --json, --dry-run, --amount-in max. Canonical symbols (usdc, usdt, usdg, weth, virtual, eth, pol, matic, bnb, sol) resolve client-side, exact-or-error, resolved address echoed; raw addresses always work.
  • Quotes carry USD value of both sides plus all-in value change in bps; a high-impact quote is refused unless --accept-impact.
  • Works with existing agents, signers, and policies as-is. Setup is GEODESICS_API_KEY in .env, nothing else.
  • Same-chain Solana swaps need ~0.005 SOL for fees; --confirm-pipe funds that in-line from a basis-chain stable.

Surface

  • New: src/commands/swap.ts, scripts/geodesicsSwap.test.ts
  • Glue: bin/acp.ts (register), src/lib/chains.ts (adds robinhood/polygon/matic/bnb/bsc name aliases), src/lib/errors.ts (3 codes), .env.example, package.json (@geodesics-protocol/sdk ^0.8.2)
  • No changes to existing commands. The signer bridge reaches the adapter's runtime signAuthorization / signTransactionViaPrivy by name, same local-shape pattern as trade.ts's SolanaTradeSigner, with every reply validated field by field.

Try it

npm install
echo GEODESICS_API_KEY=your-key >> .env
npx tsx bin/acp.ts swap --token-in usdc --chain-in base --amount-in 5 --token-out usdg --chain-out robinhood --json

Tests

npx tsx scripts/geodesicsSwap.test.ts

12 assertions: EVM bridge (raw-bytes hash signing, authorization mapping, wrong-target rejection), Solana bridge (whole-tx signing), balance preflights on both origins, SOL pipe, symbol resolution, impact gate, settlement-timeout mapping.


Note

Medium Risk
New wallet-signing path (EVM op hash, EIP-7702 delegation, Solana txs) and optional automatic nested swap for SOL top-up can move funds if misconfigured or policy-bypassed; isolated to a new command with validation and tests, but still touches live mainnet assets.

Overview
Adds acp swap, a new CLI command for gasless cross-chain swaps through the Geodesics API (@geodesics-protocol/sdk), wired in bin/acp.ts alongside existing commands.

The flow mirrors acp trade flags (--token-in, --chain-in, --amount-in, --token-out, --chain-out, --dry-run, --json, etc.) but delegates quoting, routing, and submission to Geodesics: EVM origins sign a single operation hash (plus optional EIP-7702 delegation on first use of a chain); Solana origins sign a server-built transaction. Execution runs behind the existing withApprovalGate and agent signer adapters.

New behavior includes chain-scoped symbol resolution, USD/price-impact reporting with --accept-impact, EVM/Solana balance preflights, and for Solana same-chain fee shortfalls --confirm-pipe to fund SOL via an automatic stable→SOL swap from Base USDC or Robinhood USDG. Mainnet-only (IS_TESTNET rejected). Setup: GEODESICS_API_KEY / optional GEODESICS_API_URL in .env.example.

Supporting changes: chain name aliases (robinhood, polygon, bnb, …) in src/lib/chains.ts, swap-related ErrorCode values, and scripts/geodesicsSwap.test.ts (tsx harness for signer bridges and preflight logic).

Reviewed by Cursor Bugbot for commit 688ec45. Bugbot is set up for automated code reviews on this repo. Configure here.

@cursor cursor Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cursor Bugbot has reviewed your changes using default effort and found 2 potential issues.

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Want higher recall? High effort reviews run extra passes and find more bugs. A team admin can switch effort levels in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit 688ec45. Configure here.

Comment thread src/commands/swap.ts
);
assertImpactAccepted(preflight, Boolean(opts.acceptImpact));
reportQuotedImpact(json, preflight);
return executeSwap(geodesics, solanaSigner, request, json);

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Impact gate uses discarded quote

Medium Severity

assertImpactAccepted runs on a preflight quote() whose result is discarded, then executeSwap calls client.swap(), which quotes again and executes that second quote with no impact check. A route that only becomes high-impact on the executed quote can settle without --accept-impact, contrary to the stated gate.

Additional Locations (1)
Fix in Cursor Fix in Web

Reviewed by Cursor Bugbot for commit 688ec45. Configure here.

Comment thread src/commands/swap.ts
`The SOL pipe failed: ${pipeError instanceof Error ? pipeError.message : String(pipeError)}`
);
return false;
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pipe timeout treated as hard failure

Medium Severity

The SOL fee pipe calls client.swap outside runGeodesics and treats any throw—including GeodesicsTimeoutError—as a failed pipe. Settlement timeouts often still settle, so the CLI can spend the basis stable, report INSUFFICIENT_GAS, and skip retrying the Solana swap even after SOL arrives.

Additional Locations (1)
Fix in Cursor Fix in Web

Reviewed by Cursor Bugbot for commit 688ec45. Configure here.

@0x-zeph 0x-zeph changed the title feat: add acp swap - gasless cross-chain swaps via Geodesics demo: add acp swap - gasless cross-chain swaps via Geodesics Jul 31, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant