Documentation: all sections

Saxeo Vault

Saxeo Vault is a private registry for tokenized real-world assets. The principle is tokenize privately, settle publicly: everything sensitive is sealed before it touches storage, every state change is hash-chained, and batch commitments anchor to Solana, so a public observer can verify that history is intact without learning what it contains.

What is private, what is public

Declared value, yield, maturity, notesVisibilitySealed (AES-256-GCM), issuer's session only
Position sizesVisibilitySealed, each holder sees only their own
Transfer amounts and counterpartiesVisibilitySealed, the two parties only
Asset name and typeVisibilityVisible to holders of the asset
Event commitments and chain hashesVisibilityPublic: GET /v1/vault/chain/{id}
Batch anchor roots + Solana signaturesVisibilityPublic: GET /v1/vault/anchors/{id}

The database stores sha256 commitments of the sealed content, so a leaked dump reveals structure, never values. Supporting documents are never uploaded at all: the browser hashes them locally and only the digest is registered.

The ledger

Every asset carries an append-only event chain:

hash(n) = sha256( hash(n-1) ‖ commitment(n) )

Rewriting any event breaks every later hash. The chain is public: anyone holding an asset id can fetch it and recompute every link, no Saxeo account required.

Settlement

The anchor worker batches unanchored event hashes, computes a batch root, and publishes sable-vault:v1:<root> to Solana mainnet as a memo transaction. GET /v1/vault/anchors/{id} returns the root, the ordered event hashes, and the Solana signature, so the root is recomputable and the on-chain memo checkable by anyone. Events not yet covered by a finalized anchor are labeled awaiting anchor: the registry never fabricates settlement.

Distributions: paying holders

Real assets pay: interest, dividends, a principal return. A distribution records a payout the issuer made across current holders, split pro-rata by position. It is not a transfer. It does not move principal; it records that a total was paid and seals each holder's share.

POST /v1/vault/assets/{id}/distribute   { total_usd, kind, note? }

kind is one of yield, interest, dividend, principal, other. The total is split pro-rata across holders by current position, floored per holder with the rounding remainder handed to the largest holder, so the shares sum to the declared total to the micro-dollar. Each share is sealed at rest; the payout appends one hash-chained yield_distribution event, so it anchors to Solana with everything else. The issuer sees the total; each holder sees only their own share (GET /v1/vault/distributions). A distribution fires an amount-free vault_distribution webhook.

Third-party attesters

An issuer can name someone else — an auditor, a custodian, an appraiser, counsel — as an attester on one asset, and that party can then record statements against it.

POST   /v1/vault/assets/{id}/attesters      { wallet, role, label?, expires_in_days? }
GET    /v1/vault/assets/{id}/attesters
DELETE /v1/vault/assets/{id}/attesters/{attester_id}
POST   /v1/vault/assets/{id}/attestations   { kind, statement, role?, document_sha256?, attester_signature? }
GET    /v1/vault/assets/{id}/attestations

role is one of auditor, custodian, appraiser, legal, other. The wallet must already have a Saxeo account (one SIWE sign-in), because a role is a permission on an account. Granting a role is not a statement of fact and Saxeo checks no credentials: the issuer is saying who they have engaged.

An attestation seals its statement at rest, chains an attestation event onto the asset ledger, and carries two signatures, which the API and the UI never blur together:

gateway-signed record of who attestedWhat it provesSaxeo's registry signer over the canonical record: this account, holding this issuer-granted role, recorded this statement hash at this time.
gateway-signed + attester-wallet-signedWhat it provesThe above, plus the attester's own wallet signed the same message — so the statement is provably theirs, not merely something we recorded.

Neither signature says the statement is true. Saxeo does not audit, appraise, or custody anything.

The attester signs this exact string (rebuildable by anyone holding the same facts, which is what makes the signature checkable off-platform):

sable-vault-attestation:v1:{asset_id}:{attester_account}:{role}:{kind}:{statement_sha256}:{document_sha256 or -}

A signature that recovers to a wallet not linked to the attester's account is refused, not stored unverified. The gateway-signed record verifies through the same public POST /v1/receipts/verify as every other Saxeo artifact. Issuers, holders, and active attesters can read an asset's attestations; a regulator can too, through a view key carrying the attestations scope. Revoking a role stops future attestations — ones already recorded stand, because a ledger that can retract history is not a ledger. A new attestation fires an amount-free vault_attestation webhook.

A transfer used to require the recipient to have signed in first. Now it does not: transferring to a wallet with no Saxeo account parks the position as a claim bound to that wallet.

The value leaves the sender immediately (chain event transfer_pending_claim) and the response carries a one-time claim URL — shown once, stored only as a sha256 — of the form https://www.saxeonetwork.tech/vault/claim/{token}. The claim settles (chain event claim_settled) when the recipient signs in with that wallet, whether they open the link or simply sign in: the SIWE signature is the proof the claim was waiting for. The books balance at every step — sender minus the amount, the claim holding it, then the recipient plus it.

GET  /v1/vault/claims          (session)  claims you sent, with amounts
POST /v1/vault/claims/{id}/cancel (session)  refund an unclaimed one
GET  /v1/vault/claims/{token}  (public)   asset name + bound wallet only
POST /v1/vault/claim/{token}   (session)  settle it into your account

The public view is deliberately thin: the asset name and the wallet the claim is bound to, never the amount and never the sender. A claim that is missing, settled, cancelled, or expired answers the same "not available", so probing tokens reveals nothing. Unclaimed claims expire after 30 days and refund to the sender automatically (chain event claim_refunded); the sender can also cancel one at any time. A claim is bound to one wallet — signing in with a different one is refused, never silently redirected.

Sealed document custody

By default the registry stores document digests only: the browser hashes a file locally and the sha256 is registered. That default stands. An issuer who wants Saxeo to actually hold the deed or the audit letter can now store it:

POST   /v1/vault/assets/{id}/documents         { name, content_type, content_b64, holder_visible? }
GET    /v1/vault/assets/{id}/documents
GET    /v1/vault/assets/{id}/documents/{doc_id}
DELETE /v1/vault/assets/{id}/documents/{doc_id}
GET    /v1/vault/view/{token}/documents/{doc_id}   (view key, `documents` scope)

Content is AES-256-GCM-sealed at rest, opened in-frame only to answer an authorized read, and never logged — the same posture as Relay objects. The sha256 is chained (document_added), so what was held is part of the tamper-evident record. Up to 10 MB per document, and per-asset in total by operator configuration (100 MB default); PDF, text, markdown, csv, json, images, Word and Excel — nothing executable, no HTML.

Visibility is issuer-only unless the issuer marks a document holder_visible. Removing one destroys the ciphertext immediately and chains document_removedthe hash stays in the chain, because history that can be quietly deleted is not a ledger.

Note the honest difference from digests: a digest never leaves your device, and a stored document does. Storing is a deliberate choice, disclosed at the point of upload.

Proofs: verify without revealing

An owner mints a signed statement disclosing exactly the fields they choose (POST /v1/vault/proofs). The statement carries the chain head, the latest anchor, and the disclosed values, signed secp256k1/EIP-191 by the same signer as receipts, and verifies through the same public endpoint:

curl https://www.saxeonetwork.tech/__api/v1/receipts/verify \
-H 'content-type: application/json' \
-d '{"receipt": "<proof>", "signature": "<signature>"}'

The trust model, honestly

Every proof embeds its own trust framing: attested (signed by the Saxeo registry over its hash-chained ledger) plus a public anchor when one exists. This is not zero-knowledge cryptography, and we don't call it that. What a verifier gets: the registry's signature is genuine, the ledger it signed over is tamper-evident, and its anchors exist on a public chain. What a verifier is trusting: that Saxeo's registry recorded honestly. Asset entries are issuer-declared. The registry records what an issuer states and proves the record's integrity; it does not appraise assets or verify backing.

What Saxeo Vault is not

Registry infrastructure only: Saxeo does not custody assets, make investment offers, or provide legal enforcement of ownership. Those wrappers belong to issuers and their counsel.

Endpoints

POST / GETPath/v1/vault/assetsAuthsession
GETPath/v1/vault/assets/{id}Authsession
GETPath/v1/vault/portfolioAuthsession
GETPath/v1/vault/assets/{id}/holdersAuthsession, issuer only (the cap table)
POSTPath/v1/vault/assets/{id}/closeAuthsession, issuer only, irreversible
POSTPath/v1/vault/assets/{id}/distributeAuthsession, issuer only (pay holders)
POST / GETPath/v1/vault/transfersAuthsession
GETPath/v1/vault/distributionsAuthsession (your payouts, as issuer or holder)
POSTPath/v1/vault/proofsAuthsession
POST / GETPath/v1/vault/assets/{id}/attestersAuthsession, issuer only (grant / roster)
DELETEPath/v1/vault/assets/{id}/attesters/{attester_id}Authsession, issuer only
POST / GETPath/v1/vault/assets/{id}/attestationsAuthsession (record: role-holders; read: issuer, holders, attesters)
POST / GETPath/v1/vault/assets/{id}/documentsAuthsession (store: issuer only; list: per visibility)
GET / DELETEPath/v1/vault/assets/{id}/documents/{doc_id}Authsession (read: authorized; delete: issuer only)
GETPath/v1/vault/claimsAuthsession (claims you sent)
POSTPath/v1/vault/claims/{id}/cancelAuthsession, sender only
POSTPath/v1/vault/claim/{token}Authsession (settle into your account)
GETPath/v1/vault/claims/{token}Authpublic (asset name + bound wallet only)
GETPath/v1/vault/chain/{id}Authpublic
GETPath/v1/vault/anchors/{id}Authpublic
GETPath/v1/vault/view/{token}/documents/{doc_id}Authpublic (view key, documents scope)

An issuer sees the full holder register (/holders); each holder sees only their own position. Closing an asset chains an asset_closed event and stops transfers permanently, irreversible by design, so recorded history can never quietly change meaning. Transfers fire amount-free vault_transfer_sent / vault_transfer_received webhooks.

Transfers settle straight into the recipient's Saxeo account. If that wallet has no account yet, the position is held as a claim link and settles the moment they sign in — see above — so a position is never unclaimable and never stranded.