Skip to content

Repository files navigation

Arc PayLink v3.1

V3.1 adds creator-managed request lifecycles based on real Arc House feedback: My Requests, settlement visibility, pending revoke, and safe revoke-and-replace. A replacement is a new immutable request with a new obligation ID; settled requests cannot be changed, and old links remain visible with their terminal status.

The Builder-submitted V3 baseline is preserved on release/v3.0.0 at commit 215d3476afe26882b8575cfa26bf90ee56ba9452. The original V3 evidence remains unchanged. See V3.1 lifecycle evidence for the public feedback trace, live browser verification, Arc transaction proof, and security boundary.

V3 foundation

Arc PayLink turns an invoice, milestone, or agent task into a verifiable USDC settlement on Arc Testnet. A payer can fund from Arc or Base Sepolia, a recipient without a wallet can authenticate with Google and claim through a Circle user-controlled smart account, and both sides can privately verify the complete source-to-destination audit trail.

V3 adds controlled recovery planning for exceptional settlement states. Recovery plans are deterministic and explicitly non-executable: they never retry, refund, top up, or move funds. Automatic recovery is intentionally reserved for a separately reviewed V4.

V3 architecture

flowchart TD
  A[Business obligation] --> B[Arc payment link]
  B --> C[Arc payment or Base burn]
  C --> D[CCTP settlement on Arc]
  D --> E[Immutable private audit record]
  E --> F[Controlled recovery plan]
  B --> G[Google + Circle recipient SCA]
  G --> D
Loading

The server validates obligation data, chain evidence, event order, amounts, and correlation IDs before writing a content-addressed record to private Vercel Blob storage. /audit discloses a record only when the exact correlation ID and obligation reference match. Its recovery action also requires the immutable source payment reference and returns only a read-only plan.

V3 safety boundary

  • No custody, private-key handling, or browser-visible server API keys.
  • No raw CCTP message or attestation bytes in shared records.
  • Conflicting immutable records are preserved and sent to manual review.
  • settled and fee-adjusted produce no action; pending waits; partial states the exact outstanding top-up; duplicate is rejected; mismatched requires manual review.
  • Every recovery response has fundMovement: false and executable: false.

Verified testnet and live-service evidence is recorded in docs/v3-demo-evidence.md.

Obligation-aware settlement milestone

Arc PayLink is moving beyond a generic payment link. New requests can carry a validated invoice, milestone, or agent-task obligation ID. The cross-chain settlement adapter classifies destination outcomes as settled, fee-adjusted, pending, partial, duplicate, or mismatched, with an explicit next recovery action. Verified bridge receipts now surface gross amount, recipient net amount, and recorded bridge fees in the payment UI.

This milestone is deliberately deterministic and non-custodial. It does not automatically retry, refund, or top up funds. Shared persistence, source/destination correlation, private audit lookup, and controlled recovery planning are implemented in V3.

Source-to-destination correlation milestone

Completed cross-chain obligations now produce a versioned audit record that binds:

  • the obligation type and ID;
  • the source-chain burn transaction;
  • the CCTP event nonce plus hashes of the message and attestation;
  • the Arc destination mint transaction and block;
  • gross, recipient-net, fee, outstanding amount, settlement state, and read-only recovery action.

Raw CCTP message and attestation bytes are not retained. The immutable correlation record is saved in browser storage, can be downloaded as JSON, and is also submitted to a server-side validator for private, append-only Vercel Blob persistence. The server recomputes the correlation ID, validates the evidence sequence, and preserves conflicting records for manual review instead of overwriting them. If Blob storage is not configured or is temporarily unavailable, settlement still succeeds and the local/downloadable audit path remains available.

Set BLOB_READ_WRITE_TOKEN in Vercel to enable shared settlement persistence. The token is server-only and must never use a NEXT_PUBLIC_ prefix. This milestone records recovery intent only; it does not automatically retry, refund, or top up funds.

The /audit page retrieves a private record only when both the full correlation ID and exact obligation type/ID match. The server reads the private Blob, validates the record again, and returns no record data for missing, mismatched, or conflicting references. Blob URLs are never exposed to the browser.

POST /api/settlements/recover requires the same exact references plus the source burn transaction hash as the payment reference. It returns a deterministic, non-executable recovery plan: completed settlements are no-ops, pending settlements wait for destination verification, partial settlements describe the exact outstanding top-up, duplicates are rejected, and mismatches require manual review. Every response explicitly sets fundMovement: false and executable: false.

Arc PayLink v3 creates shareable USDC payment requests that settle on Arc Testnet and retain a verifiable obligation-aware receipt. A payer can pay with USDC already on Arc or bring USDC from Base Sepolia through Circle App Kit.

This is an Arc project. Base Sepolia is only a supported source network for a payment. This repository must not share files, directories, dependencies, or Git history with any Base builder project.

Experimental claimable escrow

The repository now includes a tested contract foundation for the next Arc PayLink milestone: cross-chain funded payment links that can be claimed by a recipient wallet created after the link is shared.

  • ArcPayLinkFactory creates one deterministic minimal-proxy escrow per payment link and is locked to one configured payment token.
  • Each escrow recognizes USDC delivered directly to its address, including a CCTP destination mint.
  • A recipient authorizes a claim with an address-bound EIP-712 signature. EOA signatures and EIP-1271 smart-account signatures are supported.
  • The link secret alone cannot redirect funds to an attacker because the signed recipient address is part of the claim digest.
  • A link can be claimed once. After expiry, only the original sender can refund it.
  • The implementation contract is locked against direct initialization.

The factory and implementation are deployed on Arc Testnet. Two live payment lifecycles are verified end to end. The latest proof uses Google authentication to recover a Circle user-controlled SCA, deploys the lazy wallet on Arc, signs the address-bound EIP-712 claim, and executes the claim from that wallet. The escrow reached Claimed with a zero balance and the recipient SCA received exactly 1 USDC. Private append-only production persistence is enabled through Vercel Blob.

Arc Testnet deployment:

Verified cross-chain escrow funding:

Verified Circle recipient onboarding and claim:

External recipient testing

The hosted /claim flow accepts a portable, private JSON package for any funded escrow created by the deployed Arc PayLink factory. Before Circle prepares a signature or contract execution, the server verifies the package against Arc Testnet: the payment ID must map to the escrow in the trusted factory, the token must be official Arc Testnet USDC, and the amount, expiry, secret hash, and funded state must all match onchain. The Circle session must also own the selected recipient wallet.

Create a small, isolated test escrow for one invited tester:

ARC_PAYLINK_TEST_AMOUNT_USDC=0.01 npm run contracts:create-fund-circle-escrow

The command writes a gitignored *.private-claim.json recipient package alongside a non-secret encrypted evidence package. Share each private package with exactly one intended tester; never commit or post it publicly. A package is single-use because its escrow can be claimed only once. This flow enables controlled 3–5 person product testing without exposing API keys, a funded sender key, or a reusable public reward pool.

Contract checks:

npm run contracts:compile
npm run contracts:test

Historical same-chain milestone

The implemented milestone is intentionally limited to same-chain Arc Testnet USDC payments. A seller creates a request in the browser, shares the generated URL, and a payer connects an injected EVM wallet to send USDC through Circle App Kit Send. The application then reads the Arc receipt and accepts payment only when the transaction succeeded and the official USDC contract emitted an exact transfer to the requested recipient for the requested base-unit amount.

Base Sepolia bridging, CCTP, and Unified Balance remain documented future work and are not present in the current source code.

Verified Testnet Milestone

  • Successful Arc Testnet USDC payment: 25 USDC
  • Transaction hash: 0x4f7a17dd033ea30628b8f3b5a8ec519920277731a7b8382153dc8c36515db379
  • ArcScan: https://testnet.arcscan.app/tx/0x4f7a17dd033ea30628b8f3b5a8ec519920277731a7b8382153dc8c36515db379
  • Verified result: application reached PAID after checking the successful Arc receipt, official USDC transfer log, exact recipient, and exact requested amount.
  • Negative validation: payer == recipient was correctly rejected.
  • Local verification: lint, 14 unit tests, TypeScript, production build, and local runtime all passed in a normal Windows environment.
  • Full evidence and test details: ARC_PAYLINK_TEST_REPORT.md

This was a manual end-to-end test on Arc Testnet using a browser wallet and testnet funds. This milestone does not claim Base Sepolia bridging, Unified Balance, hosted deployment, or mainnet readiness.

Run Locally

Requirements: Node.js 20.9 or newer and an npm-compatible environment.

npm install
npm run dev

Open http://localhost:3000. No API key, private key, seed phrase, or database is required. The official public Arc Testnet RPC is the default; copy .env.example to .env.local only when an RPC override is needed.

Quality checks:

npm run lint
npm test
npm run build

Demo Flow

  1. On the home page, enter a payment title, USDC amount, and Arc recipient address.
  2. Create the payment link and share the resulting /pay URL.
  3. On the payment page, connect an injected browser wallet such as MetaMask.
  4. Approve adding or switching to Arc Testnet if the wallet requests it.
  5. Submit the App Kit Send transaction and sign it in the wallet.
  6. Wait while Arc PayLink fetches the receipt and checks transaction status, official USDC contract address, recipient, and exact six-decimal amount.
  7. Open the verified transaction on ArcScan from the paid state.

Use only faucet-issued testnet USDC. Arc Testnet uses USDC for gas, while application token transfers use the official six-decimal ERC-20 interface at 0x3600000000000000000000000000000000000000.

Project Goal

Let a freelancer or seller create a fixed-price USDC request, share a link, and receive a payment on Arc Testnet through one of two clear routes:

  1. Same-chain: Arc Testnet USDC is sent directly to the seller with Circle App Kit Send.
  2. Cross-chain: Base Sepolia USDC is moved to the seller on Arc Testnet with Circle App Kit Bridge, which abstracts Circle CCTP.

The final screen is an Arc payment receipt that identifies the request, amount, recipient, source route, and successful destination transaction.

Success means the hosted demo can repeatedly create, pay, and verify one request without custody, manual explorer reconciliation, or custom bridge contracts by August 22, 2026.

Target User

The primary user is a freelancer or small seller who wants to price and receive work in USDC on Arc while allowing a client to pay from either Arc Testnet or Base Sepolia.

The seller should not need to explain networks, copy transaction hashes, or manually determine whether bridged funds arrived. The payer chooses an available source balance; Arc PayLink handles the appropriate supported route.

Core Problem

A payment request is currently fragmented across an amount, recipient address, wallet network, bridge UI, and block explorer. A payer may hold USDC on a different chain from the seller, while the seller still needs a reliable answer to one question: did the requested USDC arrive on Arc?

Arc PayLink turns that coordination into one link and one Arc-denominated result. It uses programmable money infrastructure to select an execution path from the payer's chain, move native USDC when necessary, and verify the destination settlement against the payment request.

MVP Scope

In scope

  • Create an immutable request with a title, USDC amount, Arc recipient address, and unique request ID.
  • Generate a shareable payment URL.
  • Display the amount, Arc destination, supported source networks, and payment status.
  • Connect a browser wallet through a Viem-compatible App Kit adapter.
  • Detect whether the payer is using Arc Testnet or Base Sepolia.
  • For Arc Testnet, call App Kit send to transfer USDC wallet-to-wallet on the same chain.
  • For Base Sepolia, call App Kit bridge to transfer native USDC to the Arc recipient through CCTP.
  • Track a compact state model: ready, awaiting_wallet, processing, paid, and failed.
  • Verify the final Arc-side USDC transfer against the official token contract, expected recipient, and expected base-unit amount.
  • Show an Arc receipt with source network, route, amount, recipient, destination transaction hash, and Arc explorer link.
  • Prepare one funded same-chain demo and one funded Base-Sepolia-to-Arc demo.

Out of scope

  • Production accounts, teams, seller dashboards, notifications, refunds, disputes, or recurring billing.
  • Mainnet deployment, fiat or card entry, swaps, non-USDC assets, or arbitrary source chains.
  • Custodial wallets, private-key handling, custom bridge contracts, or direct low-level CCTP orchestration.
  • Aggregating multiple chains in the primary flow.
  • A production indexer or generalized accounting system.

Arc/Circle Integration Plan

Same-chain Arc USDC payment

Circle App Kit Send supports wallet-to-wallet token transfers on the same blockchain. When the payer is connected to Arc Testnet, Arc PayLink calls kit.send with Arc_Testnet, the seller's Arc address, the request amount, and the USDC token alias.

Arc is an EVM-compatible Layer 1 built for programmable money, uses USDC as its native gas token, and is currently available on testnet. The implementation must load current Arc RPC, explorer, and contract data from official documentation rather than copying unverified constants.

Cross-chain Base Sepolia to Arc Testnet payment

Circle's official App Kit support table lists both Base Sepolia and Arc Testnet for Bridge. When the payer holds USDC on Base Sepolia, Arc PayLink calls App Kit Bridge with Base_Sepolia as the source and Arc_Testnet as the destination.

App Kit Bridge abstracts CCTP's low-level burn, attestation, and mint sequence. CCTP transfers native USDC by burning it on the source chain and minting it on the destination, without wrapped assets or traditional bridge liquidity pools. Circle documents both Base and Arc Testnet as supported CCTP domains; official testnets are included for listed mainnets, while Arc is testnet-only.

The product must present this as one processing flow, while preserving useful route and transaction progress for error recovery. Payment is complete only when the expected USDC is verifiably delivered to the seller on Arc Testnet.

Primary flow: App Kit Bridge backed by CCTP

Bridge/CCTP is the primary cross-chain flow. It is the stronger three-day MVP choice because it maps one payment request to one explicit point-to-point native USDC transfer, App Kit provides a direct bridge method, and the final Arc delivery can be reconciled with a specific request and recipient. It requires no pre-existing Gateway deposit or separate unified-balance lifecycle.

The MVP uses App Kit rather than implementing CCTP contracts and attestation polling directly. This keeps the demo focused on payment execution and Arc receipt verification while retaining real Circle cross-chain infrastructure.

Stretch goal: Unified Balance

App Kit Unified Balance is built on Circle Gateway. It combines deposited USDC from multiple supported chains into a single chain-agnostic balance that can be spent on another supported chain. The official example explicitly includes depositing USDC from Base and spending on Arc, and the support table lists Base Sepolia and Arc Testnet.

Unified Balance is a compelling follow-up for repeat payers or treasury-style users who have already deposited funds and want near-instant cross-chain spending. It is a stretch goal because a first-time PayLink payer must understand and complete a deposit before spending, and the MVP would need to represent deposit state, available unified balance, spend authorization, and recovery or withdrawal considerations. That extra lifecycle is less reliable for a three-day, single-payment demo than Bridge/CCTP.

If the primary flow is finished early, the stretch demo may allow a pre-funded Unified Balance to pay the same Arc request. It must not replace or delay the Bridge flow.

Arc receipt verification

  • Use the current official Arc Testnet network and USDC contract information.
  • Store the payment request amount as integer USDC base units.
  • Treat an SDK success response as progress, not final proof.
  • Confirm the destination transaction succeeded on Arc and match the official USDC transfer to the request recipient and exact amount.
  • Save the destination hash and route metadata, then link the receipt to the Arc Testnet explorer.
  • Make a paid request immutable and reject a second transaction as fulfillment of the same request.

Why This Is Programmable Money

Arc PayLink does more than display an address or embed a generic wallet transfer. The payment request is machine-readable intent: a fixed asset, amount, destination, and fulfillment rule. The application then selects a supported execution program based on where the payer's USDC exists:

  • Arc USDC follows a same-chain Send route.
  • Base Sepolia USDC follows a CCTP-backed Bridge route.
  • Both routes converge on the same verifiable Arc settlement condition.

Money movement, cross-chain routing, and receipt reconciliation are composed into one deterministic product workflow. The seller specifies the economic outcome on Arc; the software executes and verifies the appropriate Circle-powered path without changing the requested unit of account or accepting a wrapped substitute.

Technical Stack

  • TypeScript end to end.
  • Next.js App Router and React for request creation, payment, and receipt pages.
  • Circle App Kit for Send and Bridge capabilities.
  • App Kit's Viem adapter plus viem for browser-wallet access and Arc receipt/event reads.
  • Tailwind CSS for fast interface execution.
  • Zod for environment, request, and SDK-result validation.
  • SQLite with Prisma locally, moving to a small persistent hosted Postgres database only if deployment storage requires it.
  • Vitest for amount conversion, route selection, and receipt matching.
  • Vercel for the hosted demo, after confirming Arc RPC behavior.

Dependencies will be selected only after checking the current App Kit installation and adapter documentation. Chain identifiers, RPC URLs, explorer URLs, USDC addresses, and CCTP contract addresses must not be guessed or stale-copied.

3-day Build Plan

Day 1: Prove both real payment rails

  • Confirm current official Arc Testnet, App Kit, USDC, and Base Sepolia support data.
  • Create the minimal TypeScript/Next.js shell and wallet adapter configuration.
  • Execute one Arc-to-Arc USDC payment with App Kit Send.
  • Execute one Base-Sepolia-to-Arc USDC payment with App Kit Bridge.
  • Capture SDK results and prove that the destination Arc transfer can be verified.

Exit criterion: both funded test wallets can deliver a known USDC amount to the same Arc recipient through the intended route.

Day 2: Build the PayLink flow

  • Add request creation and minimal persistence.
  • Build the shareable request page and source-network detection.
  • Route Arc to Send and Base Sepolia to Bridge.
  • Add progress, wallet rejection, wrong-network, insufficient-balance, and bridge-failure states.
  • Build exact Arc-side fulfillment verification and the receipt page.

Exit criterion: two browser sessions can create and fulfill a request through either source route without manual data changes.

Day 3: Harden and present

  • Refine mobile, loading, processing, failure, and success states.
  • Add focused tests for USDC precision, route choice, and receipt matching.
  • Deploy and repeat both flows against the official testnets.
  • Pre-fund demo wallets and prepare backup evidence for a previously completed same-chain and cross-chain payment.
  • Attempt a pre-funded Unified Balance route only after the primary demo is stable.

Exit criterion: the hosted demo reliably shows that USDC from Arc or Base Sepolia can fulfill one Arc PayLink and produce a verified Arc receipt.

Risks / Unknowns

  • Arc and Circle testnet configuration, SDK behavior, contract addresses, faucets, fees, and support matrices can change. Re-check official docs immediately before implementation and demo day.
  • App Kit package/API signatures may evolve. Implement against the installed version's official reference and lock versions after the first successful flows.
  • The Base Sepolia Bridge flow is asynchronous and may expose separate source, attestation, and destination phases. The UI needs bounded progress and retry guidance.
  • Testnet USDC or Arc gas funding may be rate-limited. Fund both demo routes early; Arc uses USDC for gas.
  • A source-chain transaction is not proof of payment. Only the verified destination Arc transfer fulfills the request.
  • Decimal mistakes can misprice requests. Use integer base units and test conversions.
  • Wallet network switching may fail or be rejected. Preserve the request and offer a clear retry.
  • Unified Balance introduces deposits, spend authorization, and fund-removal considerations. Keep it out of the critical path.
  • Public links expose non-sensitive payment metadata. Do not collect client names, invoices, or personal information in the MVP.
  • Hosted storage must persist across sessions. Confirm the deployment database before final rehearsal.

Official Documentation Used

Technical assumptions in this plan were checked against official Arc and Circle documentation on August 12, 2026:

About

Programmable USDC payment links on Arc — verified on Arc Testnet.

Resources

Stars

4 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages