Skip to main content
The IXO smartaccount module replaces the default Cosmos SDK signature ante handler with an opt-in pluggable system. Each account can register one or more authenticators — signature verifiers, message filters, spend-limit contracts, or composite logic — that execute on every transaction the account opts in to. If no authenticators are selected, transactions fall back to the standard Cosmos SDK signature flow.

Before you start

You need:
npm install @ixo/impactxclient-sdk
import { ixo, createSigningClient } from "@ixo/impactxclient-sdk";

const signingClient = await createSigningClient(RPC_ENDPOINT, offlineSigner);

Add an authenticator

const addAuthenticatorMsg = {
  typeUrl: "/ixo.smartaccount.v1beta1.MsgAddAuthenticator",
  value: ixo.smartaccount.v1beta1.MsgAddAuthenticator.fromPartial({
    sender: signerAddress,
    authenticatorType: "SignatureVerification",
    data: new TextEncoder().encode(JSON.stringify({ pubkey: pubkeyHex })),
  }),
};

await signingClient.signAndBroadcast(signerAddress, [addAuthenticatorMsg], "auto");
The chain assigns an id to each authenticator on success. Read it from transaction events to reference the authenticator in subsequent transactions.

Remove an authenticator

const removeAuthenticatorMsg = {
  typeUrl: "/ixo.smartaccount.v1beta1.MsgRemoveAuthenticator",
  value: ixo.smartaccount.v1beta1.MsgRemoveAuthenticator.fromPartial({
    sender: signerAddress,
    id: 1n,
  }),
};

Pause the module (governance)

MsgSetActiveState is the circuit breaker — only the module’s gov authority can broadcast it.
const setActiveMsg = ixo.smartaccount.v1beta1.MsgSetActiveState.fromPartial({
  authority: govAuthority,
  active: false,
});
When active is false, the smart-account ante handler is skipped and all transactions use the default Cosmos SDK signature path.

Use authenticators on a transaction

A transaction opts in to specific authenticators via the AuthenticatorTxExtension TX extension. The full pattern depends on your signing flow — see the smartaccount module README and the README for the IXO MultiClient SDK for current helpers. The extension carries the list of authenticator IDs to use for each signer.

Composite authenticators

Composite authenticators combine sub-authenticators using boolean logic.
Approves only when every sub-authenticator approves: auth(a) && auth(b) && ....
Approves when at least one sub-authenticator approves: auth(a) || auth(b) || ....
Multi-signature where signatures are split across sub-authenticators (one signer per sub-authenticator).
Example shapes:
// One-click trading: hot key restricted to swap messages with on-chain spend-limit guard
AllOf(
  SignatureVerification(usersPubKey),
  AnyOf(
    MessageFilter(SwapMsg1),
    MessageFilter(SwapMsg2)
  ),
  CosmwasmAuthenticator(spendLimitContract, params)
)

// Multisig (2-of-3): each signer satisfies one branch
PartitionedAllOf(pubkey1, pubkey2, pubkey3)

// Cosigner protection: cosigner approves alongside a user-selected set
AllOf(
  SignatureVerification(cosignerPubKey),
  AnyOf(...userAuthenticators)
)

Authentication phases

Each authenticator runs through a three-phase lifecycle on every transaction:
  1. Authenticate — verify the transaction is authorized.
  2. Track — record any state changes the authenticator needs (committed regardless of transaction outcome).
  3. Confirm execution — validate the post-execution effects.

Verify the result

Query an account’s authenticators through the ixo.smartaccount.v1beta1.Query/AccountAuthenticators endpoint on the gRPC gateway API. Module params (including is_smart_account_active) are read from Query/Params.

Troubleshooting

authenticatorType must match one of the registered types in the chain’s smartaccount module. Check Query/Params.maximum_unauthenticated_gas and the module’s registered types.
MsgRemoveAuthenticator fails when id does not exist for sender. Query AccountAuthenticators to confirm the id.
When is_smart_account_active is false, MsgAddAuthenticator and MsgRemoveAuthenticator are rejected. The module is gated by gov via MsgSetActiveState.
Ensure the TX extension lists the correct authenticator IDs in the order matching the signer set, and that the data payload registered with MsgAddAuthenticator is the canonical encoding for that authenticator type.

Next steps

IXO MultiClient SDK

Module-level features and types.

Smart account proto

Source of truth for smart-account messages.

Session keys

Issue scoped session keys backed by smart-account authenticators.

Manage authorization

Use Cosmos authz alongside smart-account authenticators.