---
title: "Smart Accounts"
url: "https://radix-wiki.miow.me/contents/tech/core-protocols/smart-accounts"
updated: 2026-10-03
description: "On Radix, every account is a smart account – a programmable component on the ledger with configurable access rules, deposit preferences, and recovery…"
---

# Smart Accounts

|  |  |
| --- | --- |
| **Type** | Account Architecture |
| **Key Feature** | Programmable by default |
| **Enhanced By** | MFA Security Shield |

# Smart Accounts

## Overview

On Radix, every account is a **smart account** – a programmable [component](/contents/tech/core-concepts/components) on the ledger with configurable [access rules](https://docs.radixdlt.com/docs/auth), deposit preferences, and recovery mechanisms. This is not an add-on feature; it's the default account type.

Each smart account can:

- **Control access** – Define which keys or [badges](https://docs.radixdlt.com/docs/user-badge-pattern) can withdraw, deposit, or modify the account via [access rules](/contents/tech/core-concepts/access-rules-and-auth-zones)
- **Filter deposits** – Accept or reject specific [resource](/contents/tech/core-concepts/resources) types (spam token prevention)
- **Multi-factor security** – Combine multiple keys via the MFA Security Shield
- **Social recovery** – Designate trusted contacts who can help recover access

Compare to [Ethereum](https://ethereum.org)'s EOA (externally owned account), which is just a private key with no on-chain logic. Ethereum's "smart accounts" (ERC-4337) are a retrofitted workaround; on Radix, they're native.

## Who Can Call What

An account is a component of the native Account blueprint, and its authorisation template says which of its methods the owner reserves and which anyone may call. The owner holds `withdraw`, `lock_fee`, `create_proof_of_amount`, `burn`, the deposit-rule setters, and – against expectation – `deposit` and `deposit_batch`.

Four methods are public, and they are the four a stranger sending you tokens actually uses: `try_deposit_or_refund`, `try_deposit_or_abort`, and the batch form of each. The difference between the pair is what happens when the account declines: a refund returns the resources to the sender and lets the transaction carry on, an abort fails the transaction outright. Making the unconditional `deposit` owner-only is what gives the deposit rules below any force – a sender cannot route around them, because the method that ignores them is not one they are allowed to call.

## Deposit Rules

An account carries one default and a list of exceptions. The default is `Accept`, `Reject`, or `AllowExisting`, which takes a [resource](/contents/tech/core-concepts/resources) only if the account already holds some of it. Each exception sets a resource to `Allowed` or `Disallowed`, and which list is consulted follows from the default: under `Accept` the deny list applies, under `Reject` the allow list applies, and under `AllowExisting` both do.

`AllowExisting` is the setting that answers airdrop spam. An account holding XRD and two tokens it chose keeps receiving all three without maintaining any list, and nothing else reaches it. Separately, an account can name **authorized depositors** – badges whose holder may deposit regardless of the rules – which is how an exchange or a payroll contract keeps paying an account that otherwise rejects unknown resources.

## From a Key to a Badge

An account created by a wallet is not written to the ledger first. Its address is derived from the hash of a public key – the entity types are `GlobalPreallocatedEd25519Account` and `GlobalPreallocatedSecp256k1Account` – so the address exists, and can receive tokens, before any transaction creates the component. The engine instantiates it on first use, with its owner role set to the signature of that key.

`securify` is the one-way door out of that arrangement. Calling it mints a non-fungible named "Account Owner Badge", whose local id is the account’s own address bytes, hands the badge to the caller, sets the account’s owner role to whoever holds it, and sets the `securify` role itself to `DenyAll` so the call cannot be made a second time. Control has moved from a key to a transferable badge, and a badge is a resource like any other: it can sit in a vault, be held by a multi-signature component, or be governed by an [access controller](/contents/tech/core-concepts/access-controller). That is the mechanism behind the MFA Security Shield and behind social recovery, and neither needed a change to the account blueprint to become possible.

## External Links

- [account/blueprint.rs](https://github.com/radixdlt/radixdlt-scrypto/blob/main/radix-engine/src/blueprints/account/blueprint.rs) – the role template, securify, and preallocated-account instantiation
- [account/invocations.rs](https://github.com/radixdlt/radixdlt-scrypto/blob/main/radix-engine-interface/src/blueprints/account/invocations.rs) – every account method, DefaultDepositRule and ResourcePreference
- [Accounts (Radix Docs)](https://docs.radixdlt.com/docs/account)
- [Access Controller](/contents/tech/core-concepts/access-controller) – multi-factor control and recovery over the owner badge
- [Radix Wallet](/contents/tech/core-protocols/radix-wallet)
