Skip to content

About

Compliance-gated agent job settlement on Solana. USDC-native escrow with optimistic challenge windows, ZK spending-mandate proofs, and DID agent identity.

Resources

Stars

2 stars

Watchers

0 watching

Forks

Latest commit

 

History

625 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Square

Square on Solana

Compliance-gated settlement for autonomous agent work.

Institutions mandate spending privately. Agents do the work.
Escrow releases only against a zero-knowledge proof that the payment fits the mandate.

License Solana Anchor Agave ZK Node pnpm

Protocol · Architecture · Quick start · Devnet · Documentation · Decisions


Why Square

An institution that lets software spend money on its behalf has three problems at once. Its spending policy is private, so it cannot simply publish the rules on chain. Regulated money cannot move without sanctions screening and Travel Rule records. And the agents doing the work need to get paid promptly, without trusting the institution to release funds by hand.

Square resolves all three on Solana:

  • The institution writes its spending mandate to the chain only as a salted Poseidon commitment plus a public daily ceiling. The policy itself never leaves the institution.
  • Registered agents (did:aip) accept and deliver jobs funded in USDC escrow.
  • On a policy-bound job no payment leaves escrow until the institution binds a Groth16 proof that this exact payment (payee, amount, mint, day and running daily total) complies with the committed mandate. A refusing proof is a valid proof: it refunds the institution instead.
  • Before the agent accepts, the institution also proves that the job's own terms (the full amount, paid to the agent's wallet) fit the mandate, so delivered work is never refused on terms the agent was shown up front.
  • After delivery, the agent can sell the receivable at a discount during the challenge window, but only to buyers the institution has approved.

Highlights

Private mandates A salted policy commitment and a buyer allow list (Merkle root) on chain; the policy document stays off chain.
Zero-knowledge release gate A Circom circuit proves compliance with per-transaction and daily ceilings, mint and payee lists, categories and time windows. square_verifier checks the Groth16 proof, once before acceptance and once before payout, and keeps the institution's daily counter.
On-chain screening Wallets are screened against the OFAC SDN list and the Chainalysis sanctions API; a Flagged party can neither fund nor be paid.
Receivables market Delivered work becomes a claim that can be listed and bought at a discount by allow-listed, screened buyers.
M-of-N arbitration Bonded disputes, arbitrator sets of up to seven, approve and reject votes, deadlines and lapse, and payouts that still pass the proof gate.
Travel Rule A salted, job-bound commitment at or above the threshold; IVMS101 records are envelope-encrypted off chain with permissioned reads and an access log.
Agent native did:aip v2 identities, signed agent cards, the A2A v1.0 task protocol, an agent SDK and a hosted agent runtime with per-capability MCP tools.
Every rail USDC on Solana, cross-chain funding through CCTP, a Stripe MPP fiat rail, x402 paid HTTP endpoints, and sponsored transactions through a policy-checked fee payer.
Operable by design Event indexer with reconciliation, permissionless keeper, prover, screener, REST API, CLI and MCP server, with Prometheus metrics, alerts and SLOs.

How it works

Eight steps take a job from mandate to payout (protocol, program interface):

# Actor What happens Instructions
1 Institution Opens its account and commits a spending policy and a public daily ceiling. init_institution, set_policy
2 Agent Registers; the record resolves as a did:aip identifier with the hash of its agent card. register_agent
3 Screener, institution Wallets are screened. The institution creates the job for the agent and funds it, committing Travel Rule data first when the amount requires it. On a policy job its software then binds a pre-acceptance proof that the job itself (the full amount, paid to the agent's wallet) breaks none of the mandate's standing rules (ADR 0028). record_screening, create_job, commit_travel_rule, fund_job, set_preflight_proof
4 Agent Accepts, delivers (SHA-256 and URI of the work) and opens the challenge window. On a policy job acceptance fails with PreflightRequired until the pre-acceptance proof for the agent's current wallet is bound. accept_job, submit_work
5 Agent, buyer The agent may sell the receivable; the buyer must be on the institution's allow list and screened clear. list_claim, buy_claim
6 Keeper After the challenge window anyone can finalize and earn the keeper fee. On a policy job without a proof the release fails with ProofRequired and escrow waits; a final refusal refunds the institution. finalize_payment
7 Institution's software On a policy job, binds a Groth16 proof that the payment complies with the mandate, before finalize. set_compliance_proof
8 Escrow, verifier The payee (the buyer if the claim was sold) is paid; reputation, a validation record and the institution's daily counter are written. finalize_payment with the record_release CPI
stateDiagram-v2
  [*] --> Open: create_job
  Open --> Funded: fund_job
  Funded --> Accepted: accept_job (pre-acceptance proof on a policy job)
  Accepted --> Delivered: submit_work
  Delivered --> Released: finalize_payment (no gate or compliant proof)
  Delivered --> Refunded: finalize_payment (final refusal)
  Delivered --> Disputed: raise_dispute / escalate_missing_proof
  Disputed --> Resolved: resolve_dispute (M approvals)
  Disputed --> Delivered: lapse_dispute (after the deadline)
  Resolved --> Released: execute_resolution (favor agent / split)
  Resolved --> Refunded: execute_resolution (favor institution)
  Open --> Cancelled: cancel_job
  Funded --> Cancelled: cancel_job
  Accepted --> Cancelled: cancel_job (after deadline)
Loading

Funding can also arrive from another chain: USDC burned through CCTP is minted and funds the job in the same transaction (CCTP funding).

A fiat job (create_fiat_job) has no vault, challenge window, dispute or claim sale. After delivery the institution pays by card through Stripe; the payment's attestation is bound together with the compliance proof (verify_mpp_payment_proof) and finalize_fiat_payment releases the job (ADR 0024, ADR 0026).

Architecture

flowchart TB
  subgraph Chain["Solana · one Anchor workspace"]
    REG[[square_registry<br/>agent records · did:aip · screening]]
    POL[[square_policy<br/>institutions · policy commitments · buyer roots]]
    VER[[square_verifier<br/>Groth16 release proofs · daily counters]]
    ESC[[square_escrow<br/>jobs · claim market · disputes · reputation]]
  end
  subgraph Services["Off-chain services · one Postgres"]
    IDX[indexer]
    API[REST API]
    KEEP[keeper]
    PROV[prover]
    SCR[screener]
    FEE[fee payer]
  end
  WEB[web app] -- REST --> API
  WEB -- sponsored txs --> FEE
  I[Institution] -- policy / buyer root --> POL
  A[Agent] -- register --> REG
  I -- create + fund job --> ESC
  A -- accept + submit --> ESC
  B[Buyer] -- buy claim + Merkle proof --> ESC
  I -- pre-acceptance + compliance proofs --> VER
  KEEP -- finalize --> ESC
  ESC -. reads .-> REG & POL & VER
  VER -. reads .-> POL
  SCR -- screening records --> REG
  IDX -. events .-> Chain
  API --- IDX
  API -- prove --> PROV
Loading

Programs integrate by reading each other's accounts rather than through CPI wherever possible (ADR 0003).

On-chain programs

Program Holds Devnet
square_registry Agent records (did:aip), wallet screening records AL5p4aTWrmBmWa4vxJFbBjQG7Xnx2juc15FJRGpwSsA9
square_policy Institutions, policy commitments, buyer allow-list roots 63HKPj2L8a9DGeTa9Eh3NaZXthMrFUEgbs9Y28SNEc4
square_verifier Release proofs (Groth16), institutions' daily counters 8yLdDR5zoAzeEWzkNX19DKy4HfVYXb7VcU3wWStwTFPh
square_escrow Jobs and vaults, claim market, disputes, reputation, validation records 6yBTEVbizMVCWAp4c3jx6Xdsay3CiUmrJmTswY7QRWaX

The IDLs in idl/ are the single source of the program contract; seeds, events and error codes are shared through crates/square-common.

Off-chain services

Service What it does
apps/api REST API: wallet (Ed25519) sessions and API keys, reads from the indexer database, transaction preparation for every step, delivery uploads, dispute evidence and x402 endpoint definitions (OpenAPI).
apps/indexer Event-based indexer: finalized Square transactions into events and mirror tables, with periodic reconciliation against the chain.
apps/keeper Permissionless finalize and lapse crank with a profitability threshold and ProofRequired and screening awareness; optionally the CCTP relayer.
apps/prover Groth16 prover for the release circuit (POST /v1/prove), pinned to the artifact manifest.
apps/screener Sanctions screening (OFAC SDN and Chainalysis) that writes screening records as the screener authority.
apps/fee-payer Sponsored transactions: decodes and policy-checks v0 transactions (allowed programs and instructions, compute budget, per-transaction and daily caps).
apps/compliance-api Proof records and batch attestations, an unattested-payment watcher and an x402-paid compliance report.
apps/web Next.js app: institution and agent flows, jobs, claims, policies, arbitration console, developer portal, did:aip resolver, network status, a public audit view per job (/audit/[job]) and in-app docs (/docs).
apps/demo Demo data and agent: a one-command, idempotent seed (funding, screening, policies, agent registration), a demo agent that does real work over A2A, and a scenario runner that checks every step on chain.

Packages

Package Purpose
@squaresdk/solana-sdk IDLs, generated types, client, PDAs, transaction builders for all eight steps and the REST client.
@squaresdk/solana-types Shared zod types: API envelope, views, agent cards, A2A tasks, event payloads.
@squaresdk/solana-policy Institution side: policy commitments, buyer Merkle trees, release witnesses, proving and binding.
@squaresdk/solana-identity did:aip resolver (v2 Solana profile and v1), DID document and agent card verification.
@squaresdk/solana-agent-sdk Build an agent: card and well-known route, A2A endpoint, job acceptance and delivery, claim listing.
@squaresdk/solana-a2a A2A v1.0 task protocol (JSON-RPC 2.0 and SSE): server, client, durable task store, job mapping.
@squaresdk/solana-hosted Configuration-driven institution agent that runs Claude with a per-capability MCP tool allow list and policy-gated delegation.
@squaresdk/solana-mcp Two-way MCP: a Square MCP server (read tools and signing-flow writes) and a pooled MCP client for agents.
@squaresdk/solana-x402 x402 v2 payment gateway on the official @x402/* stack: Solana exact scheme, own or remote facilitator, replay protection.
@squaresdk/solana-cctp CCTP relayer core: burn records, Circle attestations, delivery and funding on Solana.
@squaresdk/solana-hardening Shared protections: SSRF guard, durable rate limits and idempotency, RPC failover, signed actions, webhook signing.
@squaresdk/solana-observability Redacting structured logger, Prometheus metrics, health checks and alert rules.
@squaresdk/solana-cli squaresdk-solana: the eight steps, disputes and did:aip resolution from the terminal, with JSON output (guide).
@squaresdk/solana-config Shared tsconfig, ESLint and Prettier settings.

Status

Square runs on Solana devnet (deploy record).

  • Programs were deployed, and every upgrade since applied, from a verifiable build (solana-verify); the on-chain hashes match the builds.
  • The latest upgrade (2026-10-09) brought the verifier and escrow to program contract v0.9.0: the pre-acceptance proof and reject votes in disputes (upgrades).
  • The upgrade authority and every config admin is a 2-of-3 Squads v4 vault (ADR 0008).
  • The eight-step smoke test has run on devnet with real transactions (report).
  • There is no mainnet environment (ADR 0027); network-independent code (CAIP-2, did:aip, cluster options) is kept.
  • The web app and the services are hosted on Railway (ADR 0002, deploy).
  • Contracts: program interface and API and SDK contract; the current version is in each document's header.

Quick start

Prerequisites

Tool Version Pinned in
Rust 1.94.1 rust-toolchain.toml
Solana CLI (Agave) 4.1.2 Anchor.toml
Anchor CLI 1.2.0 (avm install 1.2.0) Anchor.toml
Node.js 24 .nvmrc
pnpm 10.34.6 package.json
circom 2.2.3 circuits/payment-compliance
Docker any recent Postgres and S3 test containers
gitleaks 8.30.1 or later scripts/security/gitleaks.env

Build and test

pnpm install        # also installs the git hooks (gitleaks pre-commit)
pnpm build
pnpm lint           # ESLint and Prettier
pnpm test           # vitest across the workspace
cargo test --workspace
mkdir -p target/deploy   # once, before the first anchor build in a fresh clone
anchor build
anchor test --validator legacy --skip-build   # program tests (LiteSVM, tests/programs)

Without target/deploy, the first anchor build generates fresh program keypairs and rewrites declare_id! and Anchor.toml with random IDs; after a build git status should show no changes to those files.

Run the eight steps on a local validator

(cd circuits/payment-compliance && npm ci && CIRCOM=/path/to/circom npm run build)   # wasm for in-process proofs
pnpm --filter @squaresdk/solana-smoke smoke:localnet

The run starts a throwaway solana-test-validator, loads the programs from target/deploy, initializes the configs and runs every step, including the refused-proof, missing-proof and fiat variants (smoke).

Run the whole service stack against localnet

pnpm --filter @squaresdk/solana-services-e2e test:localnet

This brings up the validator, Postgres, an S3-compatible store and the five core services (API, indexer, keeper, prover, screener), runs the eight steps through them and checks that the indexer's reconciliation finds zero drift (services).

Run the demo on localnet

pnpm --filter @squaresdk/solana-demo demo:localnet

This seeds a throwaway validator twice (the second run must change nothing), starts the demo agent and runs the approved, claim-sale and refused scenarios, checking every payout and refund on chain (demo).

Run the web flows in a real browser

pnpm turbo build --filter @squaresdk/solana-api... --filter @squaresdk/solana-web --filter @squaresdk/solana-prover
SQUARE_LOCALNET=1 SQUARE_WEB_E2E=1 pnpm --filter @squaresdk/solana-api exec vitest run test/web-flow.e2e.test.ts

After anchor build and the circuit build, Playwright drives the built web app against localnet, Postgres (Docker), the indexer and the prover: four roles with their own wallets go through the eight steps and the refused-proof case. It uses Playwright's Chromium, or an installed browser through SQUARE_WEB_E2E_CHANNEL=chrome. web-dispute and web-smart-account cover disputes and Squads smart accounts; each test runs in its own process (apps/api).

Deploy

Each service builds from its own Dockerfile (apps/<service>/Dockerfile) with the repository root as the build context, and validates its environment at startup: a missing or invalid variable stops it. The order matters (services runbook):

  1. Database: apply the migrations, then seed the program IDs (pnpm --filter @squaresdk/solana-db migrate:deploy, then seed).
  2. Indexer (backfills the programs' history), prover, then the API, which needs the prover and an S3-compatible store for deliveries and dispute evidence. The keeper runs as a single instance; the fee payer needs a funded sponsor key.
  3. Web: SQUARE_* variables point it at the API, the prover and the fee payer; the API's CORS_ORIGINS and API_AUTH_DOMAIN must match the web app's address.

Variables and secrets per service are in docs/environments.md; devnet values (program IDs, lookup table) are in the deploy record.

Repository layout

Path Contents
programs/ Anchor programs: registry, policy, verifier, escrow
idl/ Program interface contract (IDLs)
crates/ Shared Rust crates (square-common)
circuits/ Circom compliance circuit, artifacts and trusted setup notes
packages/ TypeScript packages (@squaresdk/solana-*)
apps/ Web app, REST API and long-running services
db/ The single Postgres schema and migrations (Prisma)
tests/ Program tests (LiteSVM), localnet and devnet smoke, service integration tests
scripts/ Deploy, init, CI and maintenance scripts
infra/ Monitoring: Prometheus rules and Grafana dashboard
docs/ Protocol, design documents, decisions, runbooks, deploy records, security

Documentation

Design documents, decisions and runbooks are written in Turkish; code, identifiers and APIs are in English.

Topic Where
Protocol overview docs/protocol.md
Program interface, events program-interface.md, events.md
Release circuit release-circuit.md, circuits/payment-compliance
HTTP API openapi.yaml, api-sdk-contract.md
Data model data-model.md
Agents and identity a2a.md, did:aip Solana profile
Funding and fees cctp-funding.md, tx-budget.md
Architecture decisions docs/decisions/
Operations runbooks, environments, SLOs
Deployments devnet, smoke reports
Security threat models, reviews, pentest checklist, audit package
CLI docs/cli.md

Development

  • Work items: every change belongs to an issue (BC- blockchain, BE- backend, FE- frontend) and lands through a pull request.
  • Checks: the CI checks, their local commands and the merge rule are listed in docs/ci.md.
  • Commits and releases: conventional commits; package versions through changesets (ADR 0001).
  • Contract changes: the program interface lives in idl/; an HTTP contract version change moves the OpenAPI spec, the contract document, API_CONTRACT_VERSION and the SDK together (API and SDK contract).
  • Editors: shared settings in .editorconfig.

Security

Threat models, review reports, the pentest checklist and the audit package are in docs/security/. Every commit is scanned for secrets with gitleaks. Please report suspected vulnerabilities privately to the maintainers instead of opening a public issue.

Lineage

Square brings the Solana code of three projects into one Anchor workspace and builds the missing links between them on chain. The product scope follows Square on Arc; no code is carried over from it. Programs were moved with their history and deployed under new program IDs (ADR 0004).

Layer Source In Square
Escrow, challenge window, arbitration, claim market Covenant square_escrow
Policy commitment, Groth16 compliance proof Aperture square_policy, square_verifier, circuits/
Agent identity, did:aip, A2A AIP square_registry, @squaresdk/solana-identity

License

Apache-2.0 (ADR 0005). The origins and original licenses of the source projects are in NOTICE; licensing rules for ported code and dependencies are in docs/licensing.md, and the third-party inventory is in docs/THIRD_PARTY_LICENSES.md.


Wiener Labs
Built by Wiener Labs

About

Compliance-gated agent job settlement on Solana. USDC-native escrow with optimistic challenge windows, ZK spending-mandate proofs, and DID agent identity.

Resources

Stars

2 stars

Watchers

0 watching

Forks

Releases

Packages

Used by

Contributors

Languages