Skip to main content

Address Aliases

Address aliases let you configure the set of keys that can sign transactions for a particular address on the Sui network.

You can use address aliases to:

  • Perform basic key rotation for an address.
  • Grant multiple signers full access to everything owned by an address.
  • Implement more complicated authentication schemes, such as smart wallets with passkeys.
warning

All aliases for a given address have the ability to unilaterally control or take all coins, balances, and other resources owned by the address.

Be extremely careful when making any changes to your aliases. Any new alias you add effectively becomes a joint owner of your address.

How aliases work​

Each address on Sui has a set of aliases. New addresses begin as their own alias. That is, a new address A has the alias set {A}.

An address's aliases are the addresses whose signatures Sui accepts on its behalf. In other words, the alias set is the set of allowed signers for that address.

You can modify aliases for an address using the Move API in the sui::address_alias module. You must invoke these modification functions as top-level programmable transaction block (PTB) commands. You cannot call them from other Move functions.

Some constraints for modifying aliases:

  • An address must always have at least one alias.
  • You can remove an address from its own alias set. For example, you can have an address A which only allows signatures from {B, C}.
  • The maximum number of allowed aliases for an address is 8.

How are transactions with aliased addresses authenticated?​

Each transaction on Sui has two configured addresses: a sender and a gas_owner (which might or might not be the same). For each configured address, the transaction requires a signature from one of the signers in its alias set.

For example, with the following transaction and aliases:

transaction T {
sender: A
gas_owner: X
...
}

aliases[A] = {A, B}
aliases[X] = {Y}

To be valid, the transaction T requires a signature from either A or B, and a signature from Y.

In this example, even if the transaction has signatures from [B, Y] and not from A, during execution it nonetheless has access to everything owned by A, and during Move call execution its TxContext::sender is A.

How do I verify a signature against an address's aliases?​

Signature verification through the RPC services checks the signature against the address itself by default. An offchain service that authenticates users by signature, such as a sign-in flow, rejects a valid signature from an alias unless you turn on alias checking:

  • GraphQL: Pass checkAddressAliases: true to the verifySignature query. The signature must then come from one of author's current aliases instead of from author itself.
  • gRPC: Set check_address_aliases to true in VerifySignatureRequest on SignatureVerificationService, and set address in the same request. The request fails if address is missing. The response sets address_aliases_checked when the server applied the check.

With alias checking on, the address's own key only verifies if the address is still in its own alias set. If the address has no aliases configured, the check falls back to the address itself, so its own key still verifies. This matches how Sui authenticates transactions for the address.

How do I manage aliases with the Sui CLI?​

You can manage address aliases using sui client ptb to call entry functions in the sui::address_alias module. The AddressAliasState singleton object lives at the address 0xa. The enable function takes this object as its argument, so the enable command passes @0xa. The enable call then creates a separate AddressAliases object that holds the alias set for your address.

You must enable aliases for your address first. The add, replace, and remove commands all require the AddressAliases object ID that the enable step creates.

Enable aliases for your address​

Before modifying aliases, you must enable alias configuration for your address. This creates an AddressAliases object initialized with your own address as the sole alias:

$ sui client ptb \
--move-call sui::address_alias::enable @0xa \
--gas-budget 50000000

Record the object ID of the AddressAliases object in the created objects section of the transaction output. You need this ID for all subsequent alias operations.

Add an alias​

Add another address to your alias set, granting it the ability to sign transactions on your behalf. Replace <ADDRESS_ALIASES_OBJECT_ID> with the AddressAliases object ID you noted when you enabled aliases:

$ sui client ptb \
--move-call sui::address_alias::add \
@<ADDRESS_ALIASES_OBJECT_ID> \
@<NEW_ALIAS_ADDRESS> \
--gas-budget 50000000

Replace all aliases​

Overwrite the entire alias set with a new set of addresses using replace_all. For example, to set a single address as the only alias:

$ sui client ptb \
--move-call sui::address_alias::replace_all \
@<ADDRESS_ALIASES_OBJECT_ID> \
vector[@<ALIAS_ADDRESS>] \
--gas-budget 50000000
warning

If you replace your aliases with a set that does not include your own address, you can no longer sign transactions for your address. Only the addresses in the new alias set have that ability.

Remove an alias​

Remove a specific address from your alias set:

$ sui client ptb \
--move-call sui::address_alias::remove \
@<ADDRESS_ALIASES_OBJECT_ID> \
@<ALIAS_TO_REMOVE> \
--gas-budget 50000000

Offline signing​

If you are using a hardware wallet or other external signer, add --serialize-unsigned-transaction to any of the sui client ptb commands on this page. The command then outputs the raw transaction bytes instead of executing. For example, to serialize the enable command:

$ sui client ptb \
--move-call sui::address_alias::enable @0xa \
--gas-budget 50000000 \
--serialize-unsigned-transaction

You can then sign the transaction offline and submit it separately. See Sui Client PTB CLI for details.

Vector arguments in alias commands​

A literal vector passed directly to --move-call becomes a pure Move vector value, so you can pass a list of alias addresses inline without a separate --make-move-vec command. Literal vectors can contain only pure values, such as addresses and numbers. If a literal vector contains an object value, the CLI rejects it. To build a vector of objects, use --make-move-vec instead.