Skip to content
Docs

Guides

Use the API and SDK

Sign in, prepare, sign, submit and follow an operation.

Everything the app does runs through the same API and SDK, so an agent or another client can do it too. Actions on the Writ program are prepared by the server, signed by the wallet, and carried to finality by Writ's worker.

  1. DraftWrit prepares the exact transaction with an identity memo. Unsigned drafts expire after 90 seconds.
  2. QueuedYour signed bytes are saved; one signed action per wallet is in flight at a time.
  3. SubmittedThe worker broadcasts the same bytes until a finalized result exists.
  4. FinalizedSuccess or failure on chain is final; the index catches up within seconds.
A Writ action from preparation to finality

Sign in#

  1. POST /api/auth/challenge with { "wallet": "<address>" } returns a message bound to the site's origin, the wallet, the program, the chain's genesis hash, a nonce and an expiry five minutes ahead.

  2. Check those bindings, then sign the exact message with the wallet.

  3. POST /api/auth/verify with { "challengeId", "wallet", "signature" }, the signature in base64. Writ sets an HttpOnly session cookie for 12 hours.

Every POST sends the site's Origin. The SDK's WritClient.authenticate(wallet, genesisHash) does all three steps and checks the message for you.

Prepare, sign, submit#

  1. Prepare. POST the action to its endpoint with an Idempotency-Key of 8 to 100 letters, digits, _ or -. Writ answers with an operation ID and an unsigned transaction: your action plus an SPL Memo writ:v1:<operationId>, paid by your wallet.

  2. Check. Rebuild the expected instructions with the SDK and compare the whole message before signing. WritClient.signAndSubmit does this.

  3. Sign with the wallet, without changing the message.

  4. Submit. POST /api/transactions/submit with { "operationId", "transaction" }, the signed transaction in base64.

  5. Follow. GET /api/operations/<id> until it is FINALIZED or FAILED.

Unsigned preparations expire after 90 seconds. Retrying with the same key and body returns the same operation. A wallet has at most one signed operation in flight; preparing another returns SIGNED_OPERATION_PENDING until the first has a final result.

Actions#

ActionEndpointBody
Create a rule setPOST /api/rulesname, nonce, clauses, maxPassAgeSeconds
Bind a mintPOST /api/mint-bindingsmint, rule, requireSource
Prove a rule setPOST /api/proofsrule, expiresAt, proof
IssuePOST /api/mints/issuemint, destination, amount
TransferPOST /api/transfersmint, source, destination, amount

Amounts, nonces and times are decimal strings. destination and source are token account addresses.

Proving from your own client#

POST /api/proofs/context with { "rule" } returns the credential, rule set, verifier, circuit and chain time the proof must use. Build the proof with the SDK's generateEligibilityProof(buildEligibilityContext(credential, rule, expiresAt), witness, artifacts), which checks the pinned proof artifacts and verifies the proof locally before returning it. Only the proof is posted.

Reading#

  • GET /api/passport: your credential, passes, every rule set with its count of live passes, and bindings, from Writ's finalized index.
  • GET /api/rules: public rule sets.
  • GET /api/network: governance, verifiers and the circuit.
  • GET /api/config: the program, the public RPC, the genesis hash and the proof artifact manifest.

The full list is in the HTTP API reference.