EVM Account Abstraction on Algorand via ECDSA signature verification
Algo x EVM enables Ethereum wallets (MetaMask, etc.) to control Algorand accounts using an ECDSA signature verification LogicSig. Sign once with your Ethereum wallet to authorize transactions on Algorand—no seed phrases, no new wallets.
Important
DO NOT PERFORM PUBLIC BETA TESTING YET
The logic sig standard may still evolve, which would impact the ALGO x EVM derived addresses. If you onboard public beta testers, future changes would require you to support them in recovering funds from outdated derivations or migrate to the latest version.
Tools aiding migrations/recovery will not be in scope for this project while it is in alpha/unstable state.
Private testing is fine, so long as you are aware that future versions may derive different Algorand addresses, and you would need to recover your own funds with the corresponding version of this repo.
This monorepo contains:
- Logic Sig - LogicSig that verifies ECDSA (secp256k1) signatures from EVM addresses
- SDK - TypeScript SDK for integrating EVM wallet signing with Algorand
- use-wallet - @txnlab/use-wallet with Algo x EVM / MetaMask support
- use-wallet-ui - @txnlab/use-wallet-ui with Algo x EVM / MetaMask support
- frontend - React demo application with MetaMask integration
- rpc-server - Mock Ethereum JSON-RPC server (Cloudflare Worker) that lets MetaMask Mobile connect to Algorand as a custom network. Responds to standard RPC methods (
eth_chainId,eth_blockNumber,net_version,eth_gasPrice,eth_getBlockByNumber) and serves real ALGO balances viaeth_getBalanceby deriving the Algo x EVM address and querying Algorand mainnet, converting from 6-decimal microAlgos to 18-decimal wei.
- Derive Algorand Address: Each EVM address (20 bytes) maps deterministically to a unique Algorand LogicSig address
- Sign with EVM Wallet: MetaMask signs the transaction/group ID using EIP-712 typed structured data (
eth_signTypedData_v4) - Verify on Algorand: The LogicSig recovers the public key from the signature and verifies it matches the template owner
- Execute Transaction: If verification succeeds, the transaction is approved
The LogicSig contract:
- Uses
ecdsaPkRecover(secp256k1) to recover the signer's public key - Derives the Ethereum address from the recovered public key (last 20 bytes of keccak256)
- Compares the recovered address against the template owner
- Computes an EIP-712 digest over the transaction ID (single txn) or group ID (atomic groups), providing domain separation
The LogicSig uses EIP-712 typed structured data rather than raw personal_sign for two reasons:
- Domain separation: The EIP-712 domain (
name,version) is embedded in the signed digest, preventing signatures from being replayed across different applications or protocols. Network-level replay protection is provided by the Algorand transaction's genesis hash, which is already part of the signed transaction ID/group ID. - Human-readable signing prompts: EVM wallets (MetaMask, etc.) display the structured fields to the user instead of an opaque hex blob, making it clear what is being authorized.
- Node.js 22+
- AlgoKit CLI 2.5+
- Docker (for LocalNet)
- pnpm >= 10.29.3
The recommended way to install pnpm is via Corepack, which ships with Node.js:
corepack enable
corepack prepare pnpm@10.29.3 --activateAlternative: standalone install
npm install -g pnpm@10.29.3
# Clone the repository
git clone https://github.com/algorandfoundation/x-accounts.git
cd x-accounts
# fetch the submodules
git submodule init
git submodule update
# Install dependencies
# Read the output carefully, you may need to approve build scripts.
pnpm i
# Start LocalNet
algokit localnet start
# Build all projects
algokit project run build# Start the frontend (from root directory)
cd projects/frontend
pnpm devOpen http://localhost:5173 and connect MetaMask to see EVM-controlled Algorand accounts in action.
Note: The derived Algorand address must be funded before it can send transactions. New accounts need a minimum balance of 0.1 ALGO to exist on the network. You can fund the account from AlgoKit LocalNet dispenser or use the frontend to display the address and send funds to it.
x-accounts/
├── projects/
│ ├── evm-logicsig/ # Smart contract (Algorand TypeScript)
│ ├── evm-sdk/ # TypeScript SDK
│ ├── frontend/ # React demo application
│ ├── rpc-server/ # Mock Ethereum JSON-RPC (Cloudflare Worker)
│ ├── use-wallet/ # Enhanced @txnlab/use-wallet with Algo x EVM support
│ └── use-wallet-ui/ # Enhanced @txnlab/use-wallet-ui with Algo x EVM support
Install the SDK:
npm install algo-x-evm-sdk
# or
pnpm add algo-x-evm-sdkBasic usage:
import { AlgoXEvmSdk } from 'algo-x-evm-sdk'
import { AlgorandClient } from '@algorandfoundation/algokit-utils'
// Initialize
const algorand = AlgorandClient.fromEnvironment()
const sdk = new AlgoXEvmSdk({ algorand })
// Get Algorand address for an EVM address
const algoAddress = await sdk.getAddress({
evmAddress: '0x742d35Cc6634C0532925a3b844Bc9e7595f0bEb2'
})
// Get a transaction signer (EIP-712 typed data signing)
const evmAddress = '0x742d35Cc6634C0532925a3b844Bc9e7595f0bEb2'
const { addr, signer } = await sdk.getSigner({
evmAddress,
signMessage: async ({ domain, types, primaryType, message }) => {
const data = JSON.stringify({ domain, types, primaryType, message })
return window.ethereum.request({
method: 'eth_signTypedData_v4',
params: [evmAddress, data]
})
}
})
// Use with algokit-utils
await algorand.send.payment({
sender: addr,
signer: signer,
receiver: recipientAddress,
amount: (1).algos()
})The use-wallet fork introduces a base class for Algo x EVM accounts, as well as an implementation for Metamask. This should be a drop-in replacement for Algorand dApps.
Opinionated fork of use-wallet-ui adds "meta-wallet" functionality to dApps:
- transaction transparency, see what you are signing before you sign
- security context: runs in dApp; vulnerable in malicious or compromised dApps
- Initiate transactions for managing assets, sending ALGO, etc
- WIP
- Onboarding guide for Algo x EVM connected accounts with 0 ALGO balance
Integration Effort:
- Drop-in for transaction transparency
- Minor integration needed for wallet management (integrate )
Possible future work:
- Develop optional companion extension for dApp-independent txn verification
- Integrated bridging to bootstrap account w/ USDC without leaving dApp
algokit project run buildThis compiles:
- Logic sig to TEAL
- TypeScript SDK
- Use-wallet packages
- Use-wallet-ui package
- Frontend
cd projects/evm-logicsig
algokit project run testContributions are welcome! Please see individual project READMEs for specific development guidelines:
- The LogicSig verifies signatures using ECDSA secp256k1 curve
- A template variable (owner address) ensures each EVM address has a unique Algorand address
- Signatures are automatically normalized to lower-S form because the AVM only accepts lower-S signatures
- EIP-712 domain separation prevents AVM<>EVM contamination
- The contract binds signatures to specific transaction/group IDs, preventing replay across AVM networks (genesisHash) & time (first/lastRound)
- Always verify the derived Algorand address matches expectations
This project uses GitHub Actions for continuous integration and deployment. Workflows are located in .github/workflows.
On main branch pushes:
- Automated testing and linting
- Smart contract deployment to TestNet via AlgoNode
MIT