Skip to content

Key Listing and Deletion

← Back to KMD Client

This example demonstrates how to list all keys in a wallet and delete specific keys using the KMD listKeysInWallet() and deleteKey() methods.

  • LocalNet running (via algokit localnet start)
  • Covered operations:
  • listKeysInWallet() - List all keys (addresses) in a wallet
  • deleteKey() - Delete a specific key from the wallet

From the repository root:

Terminal window
cd examples
npm run example kmd_client/06-key-listing-deletion.ts

View source on GitHub

06-key-listing-deletion.ts
/**
* Example: Key Listing and Deletion
*
* This example demonstrates how to list all keys in a wallet and delete
* specific keys using the KMD `listKeysInWallet()` and `deleteKey()` methods.
*
* Prerequisites:
* - LocalNet running (via `algokit localnet start`)
*
* Covered operations:
* - listKeysInWallet() - List all keys (addresses) in a wallet
* - deleteKey() - Delete a specific key from the wallet
*/
import type { Address } from '@algorandfoundation/algokit-utils'
import {
cleanupTestWallet,
createKmdClient,
createTestWallet,
printError,
printHeader,
printInfo,
printStep,
printSuccess,
} from '../shared/utils.js'
async function main() {
printHeader('KMD Key Listing and Deletion Example')
const kmd = createKmdClient()
const walletPassword = 'test-password'
let walletHandleToken = ''
try {
// =========================================================================
// Step 1: Create a Test Wallet
// =========================================================================
printStep(1, 'Creating a test wallet')
const testWallet = await createTestWallet(kmd, walletPassword)
walletHandleToken = testWallet.walletHandleToken
printSuccess(`Test wallet created: ${testWallet.walletName}`)
printInfo(`Wallet ID: ${testWallet.walletId}`)
// =========================================================================
// Step 2: Generate Several Keys
// =========================================================================
printStep(2, 'Generating several keys in the wallet')
const generatedAddresses: Address[] = []
printInfo('Generating 5 keys...')
printInfo('')
for (let i = 0; i < 5; i++) {
const result = await kmd.generateKey({
walletHandleToken,
})
generatedAddresses.push(result.address)
printInfo(` Key ${i + 1}: ${result.address}`)
}
printSuccess(`Generated ${generatedAddresses.length} keys`)
// =========================================================================
// Step 3: List All Keys with listKeysInWallet()
// =========================================================================
printStep(3, 'Listing all keys with listKeysInWallet()')
const listResult = await kmd.listKeysInWallet({
walletHandleToken,
})
printSuccess(`Found ${listResult.addresses.length} keys in wallet`)
printInfo('')
printInfo('ListKeysResponse fields:')
printInfo(' addresses: Array of Address objects')
printInfo('')
printInfo('All keys in the wallet:')
listResult.addresses.forEach((address, index) => {
printInfo(` ${index + 1}. ${address}`)
})
// =========================================================================
// Step 4: Delete One Key with deleteKey()
// =========================================================================
printStep(4, 'Deleting the first key with deleteKey()')
const keyToDelete = generatedAddresses[0]
const keyToDeleteStr = keyToDelete.toString()
printInfo(`Key to delete: ${keyToDeleteStr}`)
printInfo('')
await kmd.deleteKey({
walletHandleToken,
address: keyToDelete,
walletPassword,
})
printSuccess('Key deleted successfully!')
printInfo('')
printInfo('deleteKey() parameters:')
printInfo(' walletHandleToken: The handle token from initWalletHandle()')
printInfo(' address: The public address of the key to delete')
printInfo(' walletPassword: The wallet password (required for security)')
printInfo('')
printInfo('Note: deleteKey() returns void on success (no response body).')
// =========================================================================
// Step 5: Verify Deletion by Listing Keys Again
// =========================================================================
printStep(5, 'Verifying deletion by listing keys again')
const listAfterDelete = await kmd.listKeysInWallet({
walletHandleToken,
})
printInfo(`Keys before deletion: ${listResult.addresses.length}`)
printInfo(`Keys after deletion: ${listAfterDelete.addresses.length}`)
printInfo('')
const deletedKeyPresent = listAfterDelete.addresses.some((addr) => addr.toString() === keyToDeleteStr)
if (!deletedKeyPresent) {
printSuccess(`Confirmed: Key ${keyToDeleteStr.slice(0, 8)}... is no longer in the wallet`)
} else {
printError('Key still present in wallet after deletion!')
}
printInfo('')
printInfo('Remaining keys:')
listAfterDelete.addresses.forEach((address, index) => {
printInfo(` ${index + 1}. ${address}`)
})
// =========================================================================
// Step 6: Handle Deleting a Non-Existent Key
// =========================================================================
printStep(6, 'Handling deletion of a non-existent key')
printInfo('Attempting to delete the already-deleted key again...')
printInfo('')
// Note: KMD does NOT throw an error when deleting a non-existent key.
// The operation silently succeeds even if the key doesn't exist.
await kmd.deleteKey({
walletHandleToken,
address: keyToDelete,
walletPassword,
})
printSuccess('deleteKey() completed (no error thrown)')
printInfo('')
printInfo('Important: KMD does NOT throw an error when deleting a non-existent key!')
printInfo('The operation silently succeeds even if:')
printInfo(' - The key does not exist in the wallet')
printInfo(' - The address was never part of this wallet')
printInfo(' - The key was already deleted')
printInfo('')
printInfo('This means you should always verify key existence before deletion')
printInfo('if you need to confirm the key was actually removed.')
// =========================================================================
// Cleanup
// =========================================================================
printStep(7, 'Cleaning up test wallet')
await cleanupTestWallet(kmd, walletHandleToken)
walletHandleToken = '' // Mark as cleaned up
printSuccess('Test wallet handle released')
// =========================================================================
// Summary
// =========================================================================
printHeader('Summary')
printInfo('This example demonstrated key listing and deletion in KMD:')
printInfo('')
printInfo(' 1. listKeysInWallet() - List all keys (addresses) in a wallet')
printInfo(' - Takes: walletHandleToken')
printInfo(' - Returns: { addresses: Address[] }')
printInfo('')
printInfo(' 2. deleteKey() - Delete a specific key from the wallet')
printInfo(' - Takes: walletHandleToken, address, walletPassword')
printInfo(' - Returns: void (no response body)')
printInfo(' - Requires wallet password for security')
printInfo('')
printInfo('Important notes:')
printInfo(' - Deleted keys cannot be recovered unless you have a backup')
printInfo(' - Generated keys can be re-derived from the master derivation key')
printInfo(' - Imported keys are permanently lost if deleted without backup')
printInfo(' - Deleting a non-existent key does NOT throw an error (silent success)')
printInfo('')
printInfo('Note: The test wallet remains in KMD (wallets cannot be deleted via API).')
} catch (error) {
printError(`Error: ${error instanceof Error ? error.message : String(error)}`)
printInfo('')
printInfo('Troubleshooting:')
printInfo(' - Ensure LocalNet is running: algokit localnet start')
printInfo(' - If LocalNet issues occur: algokit localnet reset')
printInfo(' - Check that KMD is accessible on port 4002')
// Cleanup on error
if (walletHandleToken) {
await cleanupTestWallet(kmd, walletHandleToken)
}
process.exit(1)
}
}
main().catch((error) => {
console.error('Fatal error:', error)
process.exit(1)
})