Aleo is a privacy-focused, zero-knowledge chain. An Aleo wallet has a single
address (aleo1...) — the public key and the address are the same value —
but balances come in two forms:
| Balance | What it is |
|---|
| Public | Transparent, on-chain balance (e.g. public credits.aleo). |
| Shielded | Private balances held as encrypted records only the owner can decrypt. |
Unlike some privacy chains, there is one address for both — deposits always
go to wallet.address. The public/shielded distinction is about balance state,
not separate addresses.
Dynamic supports Aleo as both an embedded wallet (created via social auth /
email, MPC-backed) and an external wallet (the Shield browser extension via
the Aleo Wallet Standard). Both are wired up by AleoWalletConnectors.
Enabling Aleo
Enable Aleo in the dashboard
Add the connector to DynamicContextProvider
import { DynamicContextProvider, DynamicWidget } from '@dynamic-labs/sdk-react-core';
import { AleoWalletConnectors } from '@dynamic-labs/aleo';
const App = () => (
<DynamicContextProvider
settings={{
environmentId: 'YOUR_ENVIRONMENT_ID',
walletConnectors: [AleoWalletConnectors],
}}
>
<DynamicWidget />
</DynamicContextProvider>
);
export default App;
Checking if a Wallet is an Aleo Wallet
import { isAleoWallet } from '@dynamic-labs/aleo';
if (!isAleoWallet(wallet)) {
throw new Error('This wallet is not an Aleo wallet');
}
Address and Public Key
import { useDynamicContext } from '@dynamic-labs/sdk-react-core';
import { isAleoWallet } from '@dynamic-labs/aleo';
const { primaryWallet } = useDynamicContext();
if (!primaryWallet || !isAleoWallet(primaryWallet)) {
throw new Error('This wallet is not an Aleo wallet');
}
// Single aleo1... address — use it for deposits
const address = primaryWallet.address;
// Public key (identical to the address on Aleo)
const publicKey = primaryWallet.getPublicKey();
Reading Balances
Public balance via the standard balance APIs:
const publicBalance = await primaryWallet.getBalance(); // public credits, e.g. "12.5"
Shielded balances via usePrivateTokenBalances — on Aleo this resolves the
private record balances (native ALEO plus supported tokens/stablecoins):
import { usePrivateTokenBalances } from '@dynamic-labs/sdk-react-core';
const { tokenBalances, isLoading } = usePrivateTokenBalances();
Sending
sendBalance submits a transfer. By default it sends native credits
(credits.aleo); pass token to send a token/stablecoin program.
// Send native ALEO
await primaryWallet.sendBalance({
amount: '1.5',
toAddress: 'aleo1...',
});
// Send a token program (e.g. a stablecoin)
await primaryWallet.sendBalance({
amount: '10',
toAddress: 'aleo1...',
token: { address: 'usad_stablecoin.aleo', decimals: 6 },
});
You can sign messages and submit raw transactions as well:
const signature = await primaryWallet.signMessage('hello aleo');
const txId = await primaryWallet.requestTransaction(aleoTransaction);
Shielding (Embedded Wallets)
Embedded (Dynamic WaaS) Aleo wallets can move public balances into private
records and work with those records directly. These methods are only
available on embedded wallets — Wallet Adapter (Shield) wallets should use
requestTransaction / requestRecords instead.
// Shield a token's public balance into a private record
const txId = await primaryWallet.shieldToken({
tokenAddress: 'credits.aleo',
isNative: true,
amount: 1_000_000n, // atomic units
});
// Inspect owned private records
const { records } = await primaryWallet.listOwnedRecords();
Where the network fee is sponsored (Feemaster), Dynamic can auto-shield supported
tokens and auto-merge records — the built-in DynamicWidget balance view does
this for you and exposes Shielded / Unshielded tabs out of the box.
Ownership Boundaries
- Dynamic — connection lifecycle,
AleoWalletConnectors, the AleoWallet
object, balance/address accessors, send + shielding helpers, and (for embedded
wallets) MPC key management.
- External wallet (Shield) — key custody and signing for injected wallets,
via the Aleo Wallet Standard.
- Your app — how you present public vs shielded balances and any shielding UX
beyond the default widget.
Resources