Skip to main content
Associations allow multiple wallets and device installations to be linked to a single inbox. The association system implements XIP-46 for secure identity management.

AssociationState

The AssociationState represents the current state of all associations for an inbox:
See state.rs:57-63 for the struct definition.

Querying State

See state.rs:115-218 for method implementations.

Creating State

Create a new state from a wallet:
Or reconstruct from identity updates:
See state.rs:252-267 for the new method.

MemberIdentifier

MemberIdentifier represents any entity that can be associated with an inbox:
See member.rs:20-26 for the enum definition.

Creating Identifiers

Querying Identifiers

See member.rs:70-112 for accessor methods.

Member

The Member struct contains metadata about an association:
See member.rs:345-382 for the struct definition.

Member Hierarchy

Members form a tree structure:
Query the hierarchy:

Association Rules

The system enforces specific rules for associations:

Allowed Associations

Prohibited: Installation cannot add another installation. See association_log.rs:431-445 for the validation logic.

Signature Requirements

See association_log.rs:448-470 for signature validation.

SignatureRequest Builder

The SignatureRequestBuilder provides a fluent API for creating identity updates:
See builder.rs:48-52 for the struct definition.

Creating Requests

Create Inbox

See builder.rs:64-80 for the create_inbox method.

Add Association

See builder.rs:82-99 for the add_association method.

Revoke Association

See builder.rs:101-117 for the revoke_association method.

Change Recovery Address

See builder.rs:119-135 for the change_recovery_address method.

Chaining Actions

Multiple actions can be combined in a single update:

SignatureRequest

Once built, a SignatureRequest collects signatures before publishing:
See builder.rs:176-183 for the struct definition.

Managing Signatures

See builder.rs:200-312 for the implementation.

Signature Flow

Identity Updates

Update Actions

Each action modifies the association state:

CreateInbox

See association_log.rs:69-75 for the struct definition. Rules:
  • Can only be applied to a non-existent state
  • Signature must match the account identifier
  • Legacy signatures only allowed with nonce 0

AddAssociation

See association_log.rs:116-122 for the struct definition. Rules:
  • Both members must sign
  • Existing member must be in current state or be recovery address
  • New member signature must match new member identifier
  • Installation cannot add installation
  • Legacy signatures only with nonce 0 inboxes

RevokeAssociation

See association_log.rs:220-224 for the struct definition. Rules:
  • Only recovery address can revoke
  • Cannot use legacy signatures
  • Revokes member and all child installations
  • Idempotent (can revoke already-revoked member)

ChangeRecoveryIdentity

See association_log.rs:280-284 for the struct definition. Rules:
  • Only current recovery address can change
  • Cannot use legacy signatures
  • Does not revoke old recovery address (still in state)

Applying Updates

See mod.rs:20-39 for the helper functions.

IdentityUpdate Structure

See association_log.rs:360-366 and association_log.rs:321-328 for the definitions.

AssociationStateDiff

Track changes between two states:
See state.rs:23-55 for the struct definition.

Computing Diffs

See state.rs:220-250 for the diff method.

Convert State to Diff

Replay Protection

The system prevents signature replay attacks:
All signatures in an IdentityUpdate are automatically added to the seen set after successful application. See state.rs:141-150 for the replay protection methods.

Smart Contract Wallets

Smart contract wallets (SCW) require special handling:

Chain ID Binding

SCW signatures are bound to a specific chain ID:
Once a member is added with a chain ID, subsequent signatures from that member must use the same chain ID. See association_log.rs:472-484 for chain ID verification.

Block Number Verification

SCW signatures need the block number for verification:
The system automatically fetches the current block number during verification. See builder.rs:217-245 for SCW signature handling.

Error Handling

See association_log.rs:9-48 for all error types.

Best Practices

  1. Validate before applying - Check signatures and state before publishing updates
  2. Use the builder pattern - SignatureRequestBuilder ensures correct request structure
  3. Collect all signatures - Check is_ready() before publishing
  4. Handle async signatures - Wallet signatures may require user interaction
  5. Respect association rules - Installations cannot add installations
  6. Track state diffs - Use diffs for efficient member change tracking
  7. Verify chain IDs - Ensure SCW signatures use consistent chain IDs
  8. Implement replay protection - Always check has_seen() for signatures

References