Skip to main content
Aleo is a privacy-focused Layer 1 chain. An Aleo wallet has a single address (aleo1...) but balances come in two forms:
BalanceWhat it is
PublicTransparent, on-chain balance (e.g. public credits.aleo).
ShieldedPrivate balances held as encrypted records only the owner can decrypt.
Dynamic supports Aleo as both an embedded wallet (MPC-backed, created via social auth or email) and an external wallet (browser extensions that implement the Aleo Wallet Standard). Both are wired up by AleoWalletConnectors. This page covers setup and common operations for both wallet types. For the full embedded wallet API (record merging, Feemaster sponsorship, prove transactions), see Aleo embedded wallets.

Enabling Aleo

1

Enable Aleo in the dashboard

Enable Aleo (Mainnet and/or Testnet) under Chains & Networks.
2

Install the connector

npm i @dynamic-labs/aleo
3

Add the connector to DynamicContextProvider

React
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;

Supported Wallets

WalletTypeConnection Standard
ShieldBrowser extensionAleo Wallet Standard
Any wallet that implements the Aleo Wallet Standard can connect through AleoWalletConnectors. The adapter registry is extensible at runtime — see Adding a custom Aleo wallet below.

Supported Networks

NetworkChain IDDescription
Mainnet0Production network
Testnet1Test network
Enable one or both networks in the Chains & Networks dashboard. When multiple networks are enabled, users can switch between them.

Checking if a Wallet is an Aleo Wallet

React
import { isAleoWallet } from '@dynamic-labs/aleo';

if (!isAleoWallet(wallet)) {
  throw new Error('This wallet is not an Aleo wallet');
}

Address and Public Key

On Aleo, the public key and address are the same aleo1... value.
React
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');
}

const address = primaryWallet.address;
const publicKey = primaryWallet.getPublicKey(); // same value as address

Reading Balances

For external wallets, getBalance returns the combined public and private balance in ALEO credits:
React
const balance = await primaryWallet.getBalance(); // e.g. "12.500000"
To read shielded balances separately, use usePrivateTokenBalances:
React
import {
  useTokenBalances,
  usePrivateTokenBalances,
} from '@dynamic-labs/sdk-react-core';

const { tokenBalances: publicBalances } = useTokenBalances();
const { tokenBalances: privateBalances, supportsPrivateBalances } =
  usePrivateTokenBalances();

Sending

sendBalance submits a transfer_public transition. By default it sends native credits (credits.aleo); pass token for a token program.
React
// Send native ALEO credits
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 },
});

Signing Messages

React
const signature = await primaryWallet.signMessage('hello aleo');

Executing Program Transitions

requestTransaction lets you execute any Aleo program transition through the connected external wallet. The wallet handles proving and submission.
React
import { isAleoWallet, type AleoTransaction } from '@dynamic-labs/aleo';

const chainId = (await primaryWallet.getNetworkInfo()) ?? '0';

const transaction: AleoTransaction = {
  address: primaryWallet.address,
  chainId,
  fee: 50_000,
  feePrivate: false,
  transitions: [
    {
      program: 'credits.aleo',
      functionName: 'transfer_public',
      inputs: ['aleo1recipient...', '1000000u64'],
    },
  ],
};

const txId = await primaryWallet.requestTransaction(transaction);

Decrypting Records

If the connected wallet supports decryption, you can decrypt ciphertexts using the wallet’s view key:
React
const plaintext = await primaryWallet.decrypt(ciphertext, {
  tpk: '...',
  programId: 'credits.aleo',
  functionName: 'transfer_private',
  index: 0,
});

Fetching Records

Request owned records for a given program. The wallet uses its view key to scan and return matching records:
React
const records = await primaryWallet.requestRecords('credits.aleo', {
  plaintext: true,
});
Build a Provable explorer URL for any transaction ID:
React
const explorerUrl = await primaryWallet.getExplorerTransactionUrl(txId);
// e.g. "https://explorer.provable.com/transaction/at1..."

Adding a Custom Aleo Wallet

To add support for a new Aleo wallet that uses the adapter interface, register its constructor at runtime before the connector initializes:
React
import { AleoWalletAdapterConnector } from '@dynamic-labs/aleo';
import { YourWalletAdapter } from 'your-wallet-adapter-package';

AleoWalletAdapterConnector.registerAdapter('yourwallet', YourWalletAdapter);
The key ('yourwallet') must match the wallet book entry key.

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 — external wallets (e.g. Shield) should use requestTransaction / requestRecords instead.
React
// 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. For the full embedded wallet API (prove transactions, join records, Feemaster checks), see Aleo embedded wallets.

Embedded vs External Wallet Operations

MethodExternalEmbedded
signMessageYesYes
sendBalanceYesYes
getBalanceYesYes
requestTransactionYesYes
decryptYesYes
requestRecordsYesYes
shieldTokenNoYes
proveTransactionNoYes
joinRecordsNoYes
listOwnedRecordsNoYes

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

Last modified on June 25, 2026