On an OCAP-powered blockchain, an account is fundamentally a state associated with an address, controlled by a pair of cryptographic keys (a public key and a private key). A key concept to understand is that accounts are created implicitly. An account officially exists on-chain as soon as it receives its first incoming transaction, such as a token or asset transfer. There is no explicit createAccount transaction.
This guide covers migration from an old account to a different address controlled by a new key pair. The chain records the migration relationship. Fees, asset rules, and application-specific records must be checked separately; migration does not guarantee an unchanged balance or move every associated object.
Migrate an Account to New Keys
The migrateAccount function submits the target wallet’s address and public key, using the original wallet to sign. The target address must differ from the sender and must not already have an account state in the implementation described below. This is useful in several scenarios, such as:
- Key Compromise: If you suspect your private key has been exposed, you can migrate the account to a new, secure key pair to replace the exposed key’s control after migration takes effect. Until then, an attacker with that key may also act.
- Upgrading Security: You might want to migrate from an older key type to a newer, more secure one.
This operation effectively transfers control of the account while preserving its history and state on the blockchain.
Parameters
- from
WalletObject(required) — The wallet object representing the current account that is being migrated. This wallet must sign the transaction to prove ownership. - to
WalletObject(required) — The new wallet object to which control will be transferred. Its address and matching public key identify the new target account, not a replacement key at the unchanged old address.
Returns
The migrateAccount method returns a Promise that resolves to the transaction hash as a string.
Source correction (September 29, 2026): this address behavior is verified against @ocap/client and @ocap/tx-protocols 1.20.2 in the publicly distributed implementation. The earlier wording incorrectly said the address would stay unchanged. The original key is required; this is not recovery after total key loss. See the migration explanation for old-address resolution and historical signatures.
The following is a historical SDK example. Verify package compatibility and supply a working test-network endpoint and explorer for your deployment; availability of the old example services has not been established.
Example
Here's how to migrate an account from an old wallet to a new one.
Migrating an Account
import Client from '@ocap/client';
import { fromRandom } from '@ocap/wallet';
const client = new Client('https://beta.abtnetwork.io/api');
// Assume oldWallet is the currently authorized wallet for the account
const oldWallet = fromRandom();
// Create a new wallet with a new set of keys
const newWallet = fromRandom();
async function migrate() {
try {
// Before migrating, you would typically fund the oldWallet's address.
// For this example, we'll assume it has enough funds to pay for the transaction fee.
// You can get test tokens from https://faucet.abtnetwork.io/
console.log(`Migrating account from ${oldWallet.address} to target address ${newWallet.address}`);
const hash = await client.migrateAccount({
from: oldWallet,
to: newWallet,
});
console.log('Account migration transaction sent successfully!');
console.log('Transaction Hash:', hash);
console.log(`View transaction at: https://beta.abtnetwork.io/explorer/txs/${hash}`);
} catch (err) {
console.error('Error migrating account:', err);
}
}
migrate();Now that you know how to secure your account by migrating keys, you might want to learn how to grant limited permissions to other accounts without sharing your primary keys. See the Delegate Permissions guide for more details.