Developer guide

Identity, users and wallets

3 min read

How a person in a Partner's product becomes an account that can hold and move value.

Tenant and user

The unit of isolation is the tenant. A user is a TenantUser, identified by tenant_id plus user_id.

  • tenant_id sets the administrative and data scope. Every read and write carries it.
  • user_id is an internal identifier: opaque and stable. It does not change when the person changes their phone number.
  • external_user_id correlates the user with the Partner's own identifier, so the Partner does not have to store a second identity.
  • Phone, email and other contact details are aliases, and aliases are replaceable.

The tenant is derived from the authenticated credential. A tenant_id sent freely by the caller is never trusted to decide isolation, because that would make tenant isolation a request parameter.

WalletProfile and ChainAccount

WalletProfile is the logical wallet the product shows. It groups the ChainAccount records that are specific to each network family.

flowchart TB
    TU[TenantUser] -->|1| WP[WalletProfile]
    WP -->|2| E1[ChainAccount EVM]
    WP -->|4| BTC[ChainAccount Bitcoin]
    WP -->|4| ADA[ChainAccount Cardano]
    WP -->|4| SOL[ChainAccount Solana]
    WP -->|4| TRON[ChainAccount Tron]
    E1 -->|3| BASE[Base]
    E1 -->|3| ARB[Arbitrum]

What each level means

  1. TenantUser → WalletProfile. One user has one logical wallet. That is the object a product screen or a conversation talks about.
  2. WalletProfile → ChainAccount. One account per network family. This is where the differences live, so they do not leak upward.
  3. ChainAccount EVM → Base, Arbitrum. EVM networks can share the same address when they use the same EVM identity, but each chain keeps its own balances, nonces, delegation, contracts and finality. Same address, different state.
  4. Bitcoin, Cardano, Solana and Tron use their own cryptographic and accounting models, so they keep their own accounts and addresses. Cardano and Solana sign with a different curve; Bitcoin has no account balance at all, only spendable outputs.

The address exists before anything is written on chain

An EIP-7702 account can expose its address before any delegation exists on chain. That order matters, because it means a user can be given an address and receive funds before the platform has spent any gas on them:

  1. Provision the EVM identity.
  2. Show or resolve the address.
  3. Receive funds at that address.
  4. Activate the programmable logic during the first authorized outgoing transfer.
  5. Keep the same address afterwards — through activation, validator rotation, recovery and upgrades of the account core.

The address a user was given on day one is the address they still have after every one of those events. See Accounts, wallets and authorities.

From a phone number to an address

Aliases are scoped to a tenant, and a phone number is normalized before it is compared. Its lifecycle has to survive being changed, unlinked, recycled and claimed, without silently reassigning a wallet that already exists. That path is documented in Recipient resolution.