RPC Reference

Normative RPC contract for owner-address-native requests and responses. The canonical protocol reference is protocol/SPECIFICATION.md — AccountKeychain custody, ERC-1271 removal, chain wipe.

Write operations

SubmitMessage

Accepts a fully signed Message.

In Makechain, all committed block messages are user-submitted and carry Ed25519 envelopes. Disabled relay-era message families must be rejected.

BatchSubmitMessages

Accepts a bounded list of signed Message values and returns per-message results.

DryRunMessage

Validates a signed Message against current state without mempool admission.

Merge-request reads

GetMergeRequest

Returns one active merge request identified by (project_id, request_id).

FieldTypeDescription
project_idbytes (32)Target project ID
request_idbytes (32)Content-addressed merge request ID

Returns NOT_FOUND if the merge request is absent, removed, or pruned.

ListMergeRequests

Returns active merge requests under a target project prefix with cursor-based pagination and an optional requester_owner_address filter.

FieldTypeDescription
project_idbytes (32)Target project ID
limituint32Page size (max 200)
cursorbytesOpaque pagination cursor
requester_owner_addressbytes (20)Optional requester filter

Results are ordered by forward-key lexicographic order (equivalent to request_id order within a project).

ListMergeRequestsByRequester

Returns active merge requests opened by a specific owner_address, ordered by reverse-key lexicographic order.

FieldTypeDescription
owner_addressbytes (20)Requester owner address
limituint32Page size (max 200)
cursorbytesOpaque pagination cursor

MergeRequestSummary

All three merge-request RPCs return MergeRequestSummary entries with the following fields:

FieldTypeDescription
request_idbytes (32)Content-addressed merge request ID
project_idbytes (32)Target (upstream) project ID
requester_owner_addressbytes (20)Original requester's owner address
source_project_idbytes (32)Source fork-descendant project ID
source_refbytesBranch or ref name in the source project
source_commit_hashbytes (32)Head commit of proposed changes
target_refbytesSuggested target ref in upstream
titlestringShort description
added_atuint32Timestamp from the MERGE_REQUEST_ADD message

Closure attribution is not available from canonical state. To determine whether a merge request was withdrawn by the requester or closed by a maintainer, inspect finalized MERGE_REQUEST_REMOVE messages for the same (project_id, request_id) pair.

Project and account selectors

Selectors are address-native.

MessageField
GetProjectResponseowner_address
GetProjectByNameRequestowner_address
SearchProjectsRequestowner_address
ListProjectsRequestowner_address
GetAccountRequestowner_address
GetAccountResponseowner_address, username
GetKeyRequestowner_address
ListKeysRequestowner_address
GetCustodyKeyRequestowner_address, key_id
ListCustodyKeysRequestowner_address
GetAccountActivityRequestowner_address
ListVerificationsRequestowner_address

GetAccount(owner_address) returns a default-zero account view even when no account row has been materialized.

GetAccountResponse.username is the canonical username when the account has effective active storage and an active reservation. It is the empty string when the account has no effective active username.

Custody key reads

GetCustodyKey and ListCustodyKeys expose the AccountKeychain custody keys authorized under an owner_address. Both are QMDB-direct reads — there is no indexer table behind them.

GetCustodyKey

Returns one custody key identified by (owner_address, key_id).

FieldTypeDescription
owner_addressbytes (20)Account that owns the keychain
key_idbytes (20)EVM-derived custody key id

Returns NOT_FOUND when no custody key with that key_id has ever been authorized for the account. A revoked key is still returned, with status = CUSTODY_KEY_STATUS_REVOKED.

ListCustodyKeys

Returns the custody keys under an owner_address with cursor-based pagination.

FieldTypeDescription
owner_addressbytes (20)Account that owns the keychain
limituint32Page size (max 200)
cursorbytesOpaque pagination cursor

cursor and the returned next_cursor are opaque internal storage keys, not bare key_id values — echo next_cursor verbatim to fetch the next page and stop when it is empty.

CustodyKeyEntry

Both custody-read RPCs, and the GetAccountResponse.custody_keys snapshot, return CustodyKeyEntry records:

FieldTypeDescription
key_idbytes (20)EVM-derived custody key id
signature_typeenum1 secp256k1, 2 P256, 3 WebAuthn P256
public_keybytesExplicit key material — secp256k1 SEC1 65 bytes, or P256 x‖y 64 bytes
adminboolWhether the key can authorize account-level mutations
expires_atuint640 means non-expiring; admin keys are always 0
added_atuint32Timestamp of the authorizing KEYCHAIN_AUTHORIZE
revoked_atuint320 while active; set when revoked
statusenum1 CUSTODY_KEY_STATUS_ACTIVE, 2 CUSTODY_KEY_STATUS_REVOKED

status tracks revocation only — ACTIVE means "not revoked". An expired key is still reported ACTIVE; expiry is enforced separately at authorization time through expires_at. GetAccountResponse carries a custody_keys snapshot for convenience, but ListCustodyKeys is the paginated source of truth.

These transport fields are also address-native:

MessageField
ListLinksRequestowner_address
LinkEntrytarget_owner_address, source_owner_address
ListLinksByTargetRequesttarget_owner_address
ListReactionsRequestowner_address
ReactionEntrysource_owner_address
RefLogEntryowner_address
GetStorageQuotaProofRequestowner_address
GetStorageQuotaProofResponseowner_address

Commit metadata

CommitMeta uses author_address.

Merge request transport

Merge-request transport fields source_ref and target_ref remain raw protobuf bytes fields. REST/OpenAPI surfaces expose them as hex-encoded byte strings so non-UTF-8 ref names are lossless.

Verification transport

Any transport surface that returns verification records exposes the canonical verification identity:

  • verification_type
  • address
  • chain_id

The claim_signature is validated at write time and persisted in state, but it is intentionally not exposed in the VerificationEntry response — transport surfaces return only the canonical identity above. ERC-1271 validation metadata (claim_key_type, claim_block_hash) is removed in Makechain and is not present in responses.

Block and sync transport

The canonical persisted and streamed verification unit is the finalized Block (header + body). The block body carries the committed message set (account_messages + flat user_messages), authenticated by the header's transactions_root.

Relevant responses carry the Block:

  • GetBlockResponse
  • GetSyncTargetResponse
  • SubscribeBlocks

Transports must preserve canonical account-message order directly in the committed block body.