Wallet EVM Bermuda Usage
Install the pinned Bermuda source and create public EVM and shielded accounts on Plasma testnet.
Community modules are developed and maintained independently by third-party contributors.
Tether and the WDK Team do not endorse or assume responsibility for their code, security, or maintenance. Use your own judgment and proceed at your own risk.
Install the module, create its two account types, and read a shielded address or balance. This setup does not submit a transaction. To move testnet funds, follow Shield, Transfer, and Withdraw.
Prerequisites
Use Node.js 22 and npm 10 for the examples below, with a Plasma testnet RPC endpoint that reports chain ID 9746. The package declares Node.js >=20.19.0; Node 22 is the example runtime and development/test toolchain floor. The example pins are not a claim that every declared peer version behaves identically.
Your application supplies a BIP-39 mnemonic or Uint8Array seed from its secret storage. Keep it out of source code, logs, analytics, and error reports. These examples use seed-backed derivation rather than a hardware or custom signer.
Creating the shielded account reads the wallet provider's chain and requires an SDK pool configuration for it. The wallet provider also supplies SDK chain reads by default. Balance queries and operations still need the SDK's other services; a wallet RPC does not configure relayer, chain-state, policy/compliance, or proof-artifact URLs. See provider precedence.
If upgrading from 0.1.x, read the pool and address migration warning before creating or funding a new account.
Install
The maintainer's command, npm i bermudabay/wdk-wallet-evm-bermuda, installs from GitHub. It does not select a published npm registry version. These examples pin the exact repository revision for source version 0.3.2, plus the WDK peer versions used below. ethers supplies the guide's public RPC and token checks.
With npm 10:
npm install --save-exact \
'git+https://github.com/BermudaBay/wdk-wallet-evm-bermuda.git#59c711af9d5c348db740a37f19d96414fc6750f6' \
@tetherto/wdk-wallet@1.0.0-beta.17 \
@tetherto/wdk-wallet-evm@1.0.0-beta.17 \
ethers@6.17.0Import the installed package as @bermuda/wdk-wallet-evm-bermuda. The source manifest version is 0.3.2, and its SDK dependency is the maintainer-hosted @bermuda/sdk artifact at version 0.3.2.
The module declares both WDK peers in the range >=1.0.0-beta.17 <2.0.0. The command saves exact beta.17 peers for these examples; retain the generated lockfile to reuse that dependency graph. These are example pins, rather than a compatibility guarantee for every version in the declared range.
npm 12 and Later
The upstream installation instructions require admission flags for the Git dependency and its transitive HTTPS SDK dependency:
npm install --save-exact \
'git+https://github.com/BermudaBay/wdk-wallet-evm-bermuda.git#59c711af9d5c348db740a37f19d96414fc6750f6' \
@tetherto/wdk-wallet@1.0.0-beta.17 \
@tetherto/wdk-wallet-evm@1.0.0-beta.17 \
ethers@6.17.0 \
--allow-git=root --allow-remote=all--allow-git=root admits your project's Git dependencies. --allow-remote=all admits remote dependencies throughout installation, including the SDK declared by this module. These flags control dependency admission; they do not verify dependency code or service behavior.
Create the Accounts
Save this factory as wallet.mjs. The application passes its seed and a verified Plasma testnet RPC URL:
import WalletManagerBermuda from '@bermuda/wdk-wallet-evm-bermuda'
export async function createBermudaSession(seed, rpcUrl) {
if (!rpcUrl) throw new Error('A Plasma testnet RPC URL is required')
const wallet = new WalletManagerBermuda(seed, {
provider: rpcUrl
})
try {
const ethereumAccount = await wallet.getAccount(0)
const bermudaAccount = await wallet.getBermudaAccount(0, 0)
return { wallet, ethereumAccount, bermudaAccount }
} catch (error) {
wallet.dispose()
throw error
}
}ethereumAccount is an ordinary public EVM account. bermudaAccount is a separate shielded account derived from the EVM account's private key. The first getBermudaAccount() argument selects the EVM account at relative path 0'/0/index; the second selects a Bermuda subaccount. Both default to 0 and must be non-negative integers.
Unlike the EVM account's asynchronous address getter, bermudaAccount.getAddress() returns its address synchronously. In this source version it is 0x plus 2,496 hex characters, not an EVM recipient address. Its format differs from the address produced by 0.1.x.
For another shielded subaccount under the same EVM account:
const anotherBermudaAccount = await wallet.getBermudaAccount(0, 1)
const recipient = anotherBermudaAccount.getAddress()Repeated calls with the same indices reuse the same live account. See API Reference for disposal and error behavior.
Read a Shielded Balance
Save this reader as read-balance.mjs. The caller supplies the verified token address for Plasma testnet:
import { createBermudaSession } from './wallet.mjs'
export async function readShieldedBalance(seed, rpcUrl, tokenAddress) {
const session = await createBermudaSession(seed, rpcUrl)
try {
const publicAddress = await session.ethereumAccount.getAddress()
const shieldedAddress = session.bermudaAccount.getAddress()
const balance = await session.bermudaAccount.getTokenBalance(tokenAddress)
return { publicAddress, shieldedAddress, balance }
} finally {
session.wallet.dispose()
}
}The balance is a bigint in the token's base units. The testnet operations guide supplies the scoped USD₮0 address and verifies its six decimals. Use bigint base-unit amounts in fund-moving calls.
To read several tokens in an existing session, call getTokenBalances(tokenAddresses). Its result is a record keyed by lowercase token addresses, with bigint values; an empty input returns {} and an absent balance is 0n.
These methods use the SDK balance calculation, including vaulted holdings valued in the underlying token. A displayed balance is not a guarantee that the SDK can select inputs for a particular operation. SDK reads can be cached for a block time, so confirmation does not imply that the next balance query is already fresh. The examples use default storage without enabling file-backed UTXO persistence.
Runtime Requirements
The Bermuda SDK generates proofs and accesses its configured services. Supply outbound network access and writable storage for the prover's common reference string (CRS), its setup data. First use downloads about 38 MB and stores about 105 MB unpacked in ~/.bb-crs, or the directory configured by CRS_PATH.
Keep the wallet RPC and any explicit SDK provider override on the intended Plasma testnet deployment. A successful import, account derivation, or configured pool address does not establish that balance discovery, proof generation, or relay submission is available.
Bare
Bare selects the package's conditional bare entrypoint. It loads bare-node-runtime, supplies stream/worker interfaces, and patches TextDecoder and WebAssembly globals. It also replaces the process-wide Bare HTTP/HTTPS agents to remove an in-flight socket timeout. These effects apply to the process, not just this wallet instance.
Import @bermuda/wdk-wallet-evm-bermuda before anything that loads @bermuda/sdk or @aztec/bb.js, so those dependencies receive the package's import mappings. Under Bare, the prover uses a single-thread WebAssembly backend; under Node it uses the native backend.
WDK worklet bundles are unsupported for this revision. The prover dependencies load WebAssembly files from disk, so a bundle that builds can still fail to load. Bare support alone does not establish support for a browser or React Native worklet integration.
Use with WDK Core
The examples use the standalone manager because its shielded getter is separate from ordinary EVM account retrieval. Registering the manager with WDK core does not turn getAccount() into a Bermuda-account getter.
Do not assume WDK core's registered policies or middleware govern shielded accounts retrieved directly from this manager. The SDK has its own issuer-policy and compliance dependencies for its proof flow. Keep application authorization and confirmation around each fund-moving operation.
Dispose the Session
Call wallet.dispose() to initiate cleanup after all operations have finished, as the reader's finally block does. With the pinned peers, the manager invokes cleanup for its EVM accounts, signers, and cached Bermuda accounts. Shielded-account cleanup nulls its stored spending scalar and zeroes its X-Wing secret-key bytes; disposing that account alone leaves the shared master EVM account available.
Disposal does not delete persisted cache files, stop the SDK provider, erase every JavaScript or caller-held seed copy, or confirm/cancel a submitted transaction. Release application references when the session is finished. See resource lifecycle.
Next Steps
Shield, Transfer, and Withdraw
Verify the testnet contracts, approve a bounded allowance, and confirm operations.
Configuration
Review provider routing, persistent caches, and fee limits.
API Reference
Review the exact method, parameter, and result contracts.