TitleAddress formatting
AuthorDmitry Pimenov (@dpim), Kevin Hurley (@kphfb)


Diem Payment Network wallets benefit from consistent standards for serializing addresses and transaction requests. Such standards will enable an evolving set of interoperable payments scenarios across digital wallet clients. This proposal outlines an initial set of address formats.


  • on-chain account address: Account addresses on the Diem blockchain are 16 bytes in length. The on-chain accounts corresponding to these blockchain addresses are containers that can hold Move resources including coin balances. We expect that many custodial wallets will choose to use a single or small set of on-chain accounts to act as an omnibus for their users. An example of an on-chain account address is 0xf72589b71ff4f8d139674a3f7369c69b.

  • subaddress: Accounts on-chain are represented by an address. To allow multiplexing of a single address into multiple wallets, custodial wallets may use “subaddresses” under the on-chain address for each underlying user. While custodians can keep an internal ledger for mapping subaddresses, these mapping ledgers are not stored as resources on the Diem blockchain. It is a best practice for VASPs on Diem to use subaddresses as a single-use address to remove linkability. In this way, subaddresses serve as a many-to-one mapping between subaddresses and a user - where subaddresses are not re-used for more than one payment.

  • account identifier: An account identifier is a base-32 encoded string that captures 1) the network version the address is intended for, 2) the address type (with or without subaddress) and 3) the underlying address components. This identifier uses the bech32 encoding which consists of a human readable prefix, delimiter, serialized payload (account address, subaddress) and checksum. An example of an account identifier is dm1p7ujcndcl7nudzwt8fglhx6wxn08kgs5tm6mz4us2vfufk.

  • intent identifier: An intent identifier is a URI-serialized string that couples an account identifier with optional query parameters that specify preferences for an on-chain action. Initially, intent identifiers will be used for specifying transaction requests. In the fullness of time, we can expect using intent identifiers for sharing richer transaction metadata or identity information. an example of an intent identifier is diem://dm1p7ujcndcl7nudzwt8fglhx6wxn08kgs5tm6mz4us2vfufk?am=1000000&c=XDX

Abstract / Motivation#

For a range of peer-to-peer and peer-to-merchant use cases, merchants and wallets will need to coordinate an information exchange about the intended recipient and transaction payload. Standardizing the format of this payment envelope promotes interoperability across the client ecosystem. This proposal covers standards for several related identifiers.

A common pattern to a cross-wallet transaction would be:

1) The recipient generates a intent identifier consisting of their account identifier, and payment metadata 2) The recipient shares this information with a would-be sender over some communication channel (e.g., SMS, Email, QR code) 3) The sender's wallet deserializes this information and populates a transaction for the sending user to authorize 4) The sending user authorizes the request and their wallet submits the transaction to the Diem blockchain 5) The recipient wallet monitors on-chain events for its accounts. Upon seeing relevant events, the recipient wallet can filter by the sender information and whether a unique recipient subaddress was passed in the transaction's metadata fields. When such an event is detected, both parties can confirm the funds have been transferred successfully.

Examples of cross-wallet payment scenarios include:

  • A user may want to share a compact identifier over traditional communication channels (e.g., SMS) and receive a payment from a user of a different wallet
    • The recipient user may want to specify a currency preference
    • The recipient user may want to specify a concrete amount they'd like to receive
  • A merchant may want to present a predefined payment request via QR code so that a customer would only need to authorize the funds


Account identifiers#

For communicating account identity, we propose using a compact, versioned and case-insensitive identifier. To meet this criteria, we selected the Bech32 encoding implementation used in Bitcoin Segwit (BIP 0173) excluding the Segwit byte known-length restrictions.

Desired attributes#

  • Consistent - Users can build a muscle memory for identifying and using these account addresses
  • Atomic - The string identifier feels like a single unit. Users shouldn’t try to separate or truncate the string
  • Versioned - The format contains human readable information about how to interpret the payload, preventing subtle errors and reserving space for future identifier schemes
  • Error detecting - Bech32 checksums help clients validate input and reduce risk of bad transactions due to mistypings and truncations

Constraints for subaddresses#

  • Fixed length at 8 bytes (we don’t accept other sizes, strictly 8 bytes).
  • Unique to their custodial wallet/on-chain account: subaddresses must be non-ambiguous (i.e., Recipient VASPs should not issue the same subaddress to multiple users).
  • By convention, 8 zero bytes (0x0000000000000000) is reserved to denote the root (VASP owned) account.
  • Subaddresses should be single-use and should not use personal information, such as name, email address, government-issued identification number, to generate.


The Diem Account Identifier consists of

  • A prefix (also known as hrp (human readable part) which identifies the network version this address is intended for
    • “dm” for Mainnet addresses
    • “tdm” for Testnet addresses
    • "pdm" for Pre-Mainnet addresses
  • A Bech32 delimiter
    • The character “1” (one)
  • A Bech32 version identifier
    • The character “p” (version = 1) for on-chain with subaddress
  • A Bech32 encoded payload
    • For version 1, is Diem account address + subaddress (16 + 8 bytes)
  • The last 6 characters correspond to the Bech32 checksum

The Diem Account Identifier shall not be mixed-cases. It shall be all uppercases, or all lowercases. For example, dm1pptdxvfjck4jyw3rkfnm2mnd2t5qqqqqqqqqqqqq305frg or DM1PPTDXVFJCK4JYW3RKFNM2MND2T5QQQQQQQQQQQQQ305FRG are valid but dm1pptdXVFJCK4JYW3RKFNM2MND2t5qqqqqqqqqqqqq305frg is not.

Overall address format: prefix | delimiter | version | encoded payload | checksum

Example with explicit subaddress#

Identifier information

  • Prefix (string)
    • Network: dm
  • Address type (version prefix): 01 (letter p in Bech32 alphabet)
  • Address payload (in hex)
    • Address: 0xf72589b71ff4f8d139674a3f7369c69b
    • Subaddress: 0xcf64428bdeb62af2
  • Checksum: 2vfufk

Result: dm1p7ujcndcl7nudzwt8fglhx6wxn08kgs5tm6mz4us2vfufk

Example without explicit subaddress (root account)#

Identifier information

  • Prefix (string)
    • Network: dm
  • Address type (version prefix): 01 (letter p in Bech32 alphabet)
  • Address payload (in hex)
    • Address: 0xf72589b71ff4f8d139674a3f7369c69b
    • Subaddress: 0x0000000000000000
  • Checksum: d8p9cq

Result: dm1p7ujcndcl7nudzwt8fglhx6wxnvqqqqqqqqqqqqqd8p9cq

Looking ahead#

In the future, we plan to define additional Account Identifier versions to support other forms of identity, such as more compact subaddress formats. These would leverage a similar overall structure but would have a different version identifier, preventing naming collisions.

Intent identifiers#

In addition to the Account Identifier standard, we propose a common serialization format for denoting specific actions involving an on-chain account. This format is intended to evolve and support a broad range of user-to-user and user-to-merchant scenarios.

Desired attributes#

  • Familiar - define standards that are easy to understand and implement (by merchant, exchange and wallet developers)
  • Interoperable - a single integration can support all wallets without vendor-specific setup
  • Extensible - a versioned protocol with room for supporting new capabilities


The Intent Identifier consists of

  • A prefix
    • diem:// to explicitly specify how the identifier should be interpreted
  • A base URI
    • Defines what resource the requested action is for
    • Initially, these will be account identifiers
  • Query parameters
    • Provides details for how the request should be fulfilled
    • Initially, currency code and amount to specify transaction request preferences
      • currency uses the 'c' key, with the value encoded as a 3-letter currency code (ex. XDX)
      • amount uses the 'am' key, with the value encoded in micro units (10e-6)

Example of request intent#

This intent represents a request to receive funds at a given address. Since neither the amount nor currency are prefilled, the sender will define these fields.

Identifier information

  • Prefix
    • diem://
  • Base URI
    • Account Identifier: dm1p7ujcndcl7nudzwt8fglhx6wxn08kgs5tm6mz4us2vfufk
  • Query parameters
    • none

Result: diem://dm1p7ujcndcl7nudzwt8fglhx6wxn08kgs5tm6mz4us2vfufk

Example of request intent with currency specified#

This intent represents a request to receive funds in a specific currency at a given address. The amount is defined by the sender.

Identifier information

  • Prefix
    • diem://
  • Base URI
    • Account Identifier: dm1p7ujcndcl7nudzwt8fglhx6wxn08kgs5tm6mz4us2vfufk
  • Query parameters
    • c=XDX (currency preference is XDX composite token)

Result: diem://dm1p7ujcndcl7nudzwt8fglhx6wxn08kgs5tm6mz4us2vfufk?c=XDX

Example of request intent with currency and amount specified#

This intent represents a request to receive a specific amount in a specific currency for a given address.

Identifier information

  • Prefix
    • diem://
  • Base URI
    • Address: dm1p7ujcndcl7nudzwt8fglhx6wxn08kgs5tm6mz4us2vfufk
  • Query parameters
    • c=XDX&am=1000000 (request for 1 XDX, currency preference is XDX composite token, amount is 1000000 µ-units)

Result: diem://dm1p7ujcndcl7nudzwt8fglhx6wxn08kgs5tm6mz4us2vfufk?c=XDX&am=1000000

Looking ahead#

We expect to evolve the Intent Identifier to support a broader range of payment and identity scenarios. These may range from sharing stable identity information to supporting richer payment metadata.