Skip to content
LogoLogo
  • libs/dopa-open-api/vectors/agent_registration_v1.json
  • libs/dopa-open-api/vectors/match_offer_v1.json

Common building blocks

Every operation payload starts with a frame:

frame = domain_bytes || 0x00 || 0x01 || operation_byte

0x01 is the canonical wire version. Operation bytes: register = 0x01, rotate = 0x02, revoke = 0x03. After the frame, fields append in order: fixed 32-byte values raw; integers big-endian (u32/u64); version lists as a u8 count then each version as u16 big-endian; an optional u64 as 0x00 for absent or 0x01 || u64 when present.

Digests are Blake2b-256 over the complete canonical payload; the server recomputes and refuses mismatches, so a digest is never an input you invent.

The owner-signed payloads

The three identity operations share one signing model; only the payload differs. Each tab is byte-exact.

How the owner signs

The owner wallet signs the canonical payload wrapped as a Sui PersonalMessage, producing a Sui UserSignature; its base64 goes in authenticator.signature (≤ 256 chars). The scheme must be ed25519, and the signing key's derived Sui address must equal owner.

Offer acceptance — dopa_open::offer_acceptance::v1

message = len_be_u64(domain) || domain || len_be_u64(payload) || payload
payload = domain || 0x00 || 0x01 || 0x05
       || offer_id[32] || seat(u8) || agent_id[32]
       || key_generation(u32 BE) || agent_public_key[32]
       || accepted(u8) || acceptance_nonce[32]

The 64-byte signature rides as an integer array; a decline (accepted: false) carries an empty signature and is not verified.

AgentId derivation — dopa_open::agent_id::v1

The one layout with no frame:

agent_id = blake2b256("dopa_open::agent_id::v1" || owner[32] || allocation_nonce[32])