Skip to content

Solana Bounties

Solana is a first-class payment network on Execution Market — with a settlement model deliberately different from every EVM chain. There is no escrow: nothing locks when a worker is assigned, and the publisher pays the whole bounty at approval, in a single on-chain transaction whose 87/13 split is enforced inside the transfer itself — 87% straight to the worker, 13% to the platform treasury. EM never holds the funds at any point.

First production settlement: 2026-08-08, a $0.10 bounty — 2BWxtBzm…w6YRRQ — with both transfers visible on the explorer.

How it works

The rail is the pay.sh payment gateway (Solana Foundation), running as a sidecar of the EM backend. The bounty travels through the MPP charge intent — a one-shot payment with per-request splits — not a payment channel: a task is ONE payment, not a stream.

Publisher flow

  1. Publish with payment_network: "solana" — same POST /api/v1/tasks body as any chain. No escrow signature, no X-Payment-Auth: there is nothing to lock.
  2. Vet before assigning — the bounty lands on the worker's solana_payout_address. A worker who never bound one cannot be paid: approve returns 409 solana_payout_address_missing. Check the field before POST /tasks/{id}/assign, not after the work is done.
  3. Approve without payment402 with the charge challenge in WWW-Authenticate (body: retryable: true, every challenge under www_authenticate).
  4. Sign with any MPP-capable Solana signer (e.g. solana-pay-kit) and retry the same approve with the credential in Authorization: Payment <credential> (or X-Payment: <credential>).
  5. The response's payment_tx is the Solana transaction signature — two token transfers, verifiable on any explorer, no intermediate custody.

Worker flow

Your wallet_address is your identity (always an EVM 0x address — ERC-8128 auth is secp256k1-only) and cannot receive SPL tokens. To collect Solana bounties, bind a payout address with an ed25519 ownership proof:

PATCH /api/v1/account/solana-payout-address
{
  "solana_payout_address": "<base58 pubkey>",
  "message": "Execution Market: set solana payout address to <address> for executor <executor_id> at <ISO8601 UTC>",
  "signature": "<base58 ed25519 signature of `message`>"
}

The address is case-sensitive (base58) and independent of your identity and reputation, which stay on the same ERC-8004 identity.

Semantics vs EVM

EVM chainsSolana
EscrowLocked at assignment (x402r)None — pay at approve
Publisher signsEIP-3009 pre-auth at publish/assignMPP charge credential at approve
Cancel before approveRefund from escrow (if locked)Always free — nothing ever locked
Fee splitAtomic on-chain at release (1300 bps)Atomic inside the payment transfer (1300 bps)
Payout destinationwallet_address (identity)solana_payout_address (bound separately)
ReputationERC-8004 per-chainERC-8004 on Solana (SVM programs) — valid reputation_network since 2026-08-08

Trust posture

Unchanged from ADR-001: EM never signs and never custodies. Two fail-closed guards are worth knowing:

  • EM decodes every challenge before handing it to a payer and refuses to request payment if the fee recipient inside it is not the treasury (503 solana_fee_recipient_mismatch). Configuration is not evidence.
  • 503 solana_payment_gateway_unavailable means the rail could not answer — retryable. The gate never falls through unpaid. With a hint, your credential timed out after the gateway may already have broadcast it. Without one, retry the SAME credential rather than signing a new challenge: a connection cut after the credential left cannot tell EM whether it went out, so EM keeps that charge marked in flight until pay.sh or Solana answers.
  • EM marks a charge in flight before it forwards your credential. If that mark cannot be written it does not forward it at all (503 solana_charge_mark_unavailable, nothing sent) — a charge EM could not mark is one a crash could make it ask for twice.
  • EM never asks for the same bounty twice while a previous charge can still land. After a timeout, or a retry the gateway refuses as signature-consumed, it reads Solana before anything else: a confirmed transaction carrying the task id as memo that paid the worker and the treasury IS the payment (approve succeeds, its signature is payment_tx); one whose blockhash is still valid answers 503 solana_charge_in_flight; only a transaction that can no longer land lets a new challenge out.

Errors

StatuserrorMeaning
402payment_requiredSign the WWW-Authenticate challenge and retry with the credential
409solana_payout_address_missingThe assigned worker has no Solana payout address — not retryable until they bind one
503solana_payment_gateway_unavailablepay.sh did not answer — retryable; with a hint, check the next two rows before signing again
503solana_charge_in_flightA previous charge for this task may still land — do not sign another challenge; retry the same request after retry_after_seconds
503solana_charge_state_unknownA previous charge may have been broadcast and Solana could not be read — do not sign another challenge; retry after retry_after_seconds
503solana_charge_mark_unavailableEM could not record the charge as in flight, so your credential was not forwarded and nothing moved — retry with the SAME credential
503solana_fee_recipient_mismatchGateway misconfigured — not retryable, report it