Skip to content

Reference Wallet API & Sync Contract v1

Status: frozen integration contract for TKT-P3-33.

Purpose: provide one implementation-facing contract for wallet teams integrating confidential send/receive tracking without guessing protocol rules.

This file freezes only behavior already established in current specs and code paths. It does not add new proving, consensus, or covenant semantics.

1. Normative anchors

This contract aligns with:

  • spec/protocol-terminology.md
  • spec/recovery-scan-rules-v1.md
  • spec/confidential-transfer-planner-v1.md
  • spec/confidential-transition-boundary-v1.md
  • docs/interop/protocol-interoperability-pack-v1.md

If wording conflicts, spec/protocol-terminology.md is the terminology source of truth.

2. Receiver identity contract

2.1 Normative receiver model

Wallet implementations MUST model receiver identity as (A, B):

  • A: scan key material
  • B: spend key material

Ownership recovery and confidential-note spend authority derive from this pair.

2.2 Derivation-path neutrality

Derivation paths are wallet policy, not protocol validity.

Wallet APIs MUST NOT require one fixed derivation path. Wallet APIs MAY expose derivation metadata for local debugging/recovery UX.

3. Reference wallet API surface (v1 freeze)

The following interface shapes are intentionally minimal and stable. Field naming may vary by language, but semantics MUST remain equivalent.

3.1 Key interfaces

type ReceiverIdentityV1 = {
  scanKeyA: Uint8Array; // 33-byte pubkey or wallet-local key handle
  spendKeyB: Uint8Array; // 33-byte pubkey or wallet-local key handle
  keyLocator?: string; // optional wallet-local locator (non-normative)
};

type PlannerRequestV1 = {
  sourceNoteId: string;
  sourceStateCell: {
    shardId32Hex: string;
    txid: string;
    vout: number;
  };
  sender: ReceiverIdentityV1;
  receiver: ReceiverIdentityV1;
  amountSats: string;
};

type PlannerResultV1 = {
  publicInputsHex: string; // PIv1 bytes
  stateIn32Hex: string;
  stateOut32Hex: string;
  outputFingerprint32Hex: string;
  batchDigest32Hex?: string;
  feeDigest32Hex?: string;
  encryptedPayloadHex: string;
  rre1HintsHex: string;
  nullifier32Hex: string;
  noteLeafHex: string;
  provenance: {
    prevoutTxid: string;
    prevoutVout: number;
  };
};

3.2 Validation entry points

Wallet integrations MUST expose deterministic equivalents of:

  1. parseCandidateTransition(candidateBytes|tx)
  2. validatePublicBoundary(piBytes, txOutputs)
  3. recoverInboundNotes(identityAB, encryptedPayload, rre1Hints, context)
  4. validateRecoveredNote(note, witness, roots, nullifierPolicy)
  5. applySyncEvent(connect|disconnect, eventData)

Any implementation language is acceptable if behavior is equivalent.

4. Deterministic sync and recovery contract

4.1 Chain-first truth model

Wallet sync MUST treat canonical chain/event order as authoritative. Optional indexers/candidate feeds are advisory accelerators only.

4.2 Event ordering and replay

For deterministic replay, wallets MUST process connect events in canonical order:

  • (blockHeight, txIndex, txidHex)

Disconnect events MUST remove prior effects for the disconnected block and replay remaining connect events.

4.3 Recovery convergence rule

Given:

  • the same chain transition/event stream
  • the same wallet key material (A, B)
  • the same canonical helper policies

wallet recovery MUST converge to the same final note/state projection.

5. Stable wallet-note persistence fields (v1)

Implementations MAY store additional local indices, but the following fields are the stable minimum set.

5.1 Required fields

  • noteId (stable local identifier)
  • noteHash32Hex
  • nullifier32Hex
  • shardId32Hex
  • stateCellOutpoint (txid, vout)
  • noteLeafHex (canonical encoding)
  • witness (or deterministic witness reference sufficient for replay)
  • noteRoot32HexAtDiscovery
  • nullRoot32HexAtDiscovery
  • status (unspent or spent)
  • discoveredAt (blockHeight, txIndex, txid)

5.2 Optional fields

  • decrypted note payload cache
  • identity transport metadata (paycode/RPA provenance)
  • local labels, tags, or account grouping
  • derivation/account path hints

Optional fields MUST NOT alter protocol validity decisions.

6. Receiver validation surface

Before persisting an inbound note, wallet logic MUST validate:

  1. candidate transition boundary parses successfully
  2. output fingerprint binding matches real transaction outputs
  3. RRE1/payload parsing succeeds
  4. ownership candidate derivation from (A, B) succeeds
  5. note commitment / root linkage validates against canonical policies
  6. nullifier policy checks pass for local spend-status tracking

If any step fails, wallet MUST reject that candidate note.

7. Candidate-feed neutrality guidance

Candidate feeds/index servers MAY provide:

  • candidate txids
  • block ranges
  • envelope bytes and location hints

They MUST NOT be treated as authority for:

  • ownership
  • note validity
  • spend/nullifier truth
  • final wallet state

Wallet APIs SHOULD make this explicit by separating:

  • candidateSource (advisory input)
  • validatedTransition (locally verified output)

8. Compatibility notes (stealth/paycode transport)

  • Stealth/paycode/RPA are valid identity-distribution transports.
  • Protocol ownership semantics remain (A, B) regardless of transport.
  • The API contract does not require one transport to be present.
  • Derivation policy remains wallet-local and non-normative.

9. Out of scope

  • new prover logic
  • new covenant rules
  • new protocol cryptographic policy
  • mandatory ecosystem-wide transport API standardization