This page describes how to disable the master key pair for an account. You should do this if your account's master key pair may have been compromised, or if you want to make multi-signing the only way to submit transactions from your account.
By following this tutorial, you should learn how to:
- Disable the master key pair for an account.
- Check an account to see if its master key pair is disabled.
To complete this tutorial, you should:
- Have a basic understanding of the XRP Ledger.
- Have an XRP Ledger client library, such as xrpl.js, installed.
- Have a basic understanding of Cryptographic Keys.
- Know how to assign a regular key pair or set up multi-signing for an account.
You can find the complete source code for this tutorial's examples in the code samples section of this website's repository.
From the code sample folder, use npm to install dependencies:
npm iTo get started, import the client library and instantiate an API client. For this tutorial, you need one account, which the sample code funds using the Testnet faucet; you could also use an existing account.
import xrpl from 'xrpl'
const client = new xrpl.Client('wss://s.altnet.rippletest.net:51233')
await client.connect()
console.log('Funding new wallet from faucet...')
const { wallet } = await client.fundWallet()
console.log(`Funded. Master key pair:
Address: ${wallet.address}
Seed: ${wallet.seed}
`)Before you can disable the master key pair, your account must have another way of authorizing transactions, either a regular key pair or a multi-signing list. Since the sample code uses a newly-funded account, it does not yet have either one, so it generates and assigns a regular key the same way as in the Assign a Regular Key Pair tutorial. Skip this step if you are using an existing account that already has a regular key pair or multi-signing list set up.
// Generate a regular key and assign it to the account -------------------------
// Skip this step if you are using a pre-existing account that already has a
// regular key or multi-signing list configured.
// To black-hole an account, set the RegularKey to a well-known blackhole
// address such as rrrrrrrrrrrrrrrrrrrrrhoLvTp instead.
const algorithm = 'ed25519'
const regularKeyPair = xrpl.Wallet.generate(algorithm)
console.log(`Generated regular key pair:
Address: ${regularKeyPair.address}
Seed: ${regularKeyPair.seed}
Algorithm: ${algorithm}
`)
const regularKeyTx = {
TransactionType: 'SetRegularKey',
Account: wallet.address,
RegularKey: regularKeyPair.address
}
xrpl.validate(regularKeyTx)
console.log('Assigning regular key to the account...')
const response = await client.submitAndWait(regularKeyTx, { wallet, autofill: true })
const setRegularKeyResultCode = response.result.meta.TransactionResult
if (setRegularKeyResultCode === 'tesSUCCESS') {
console.log('Regular Key set successfully.')
} else {
console.error(`SetRegularKey failed with code ${setRegularKeyResultCode}.`)
client.disconnect()
process.exit(1)
}To disable the master key pair, send an AccountSet transaction with the SetFlag value set to the asfDisableMaster value (4). Unlike most transactions, this one MUST be signed with the master key pair for the account.
// Disable master key pair -----------------------------------------------------
const disableMasterKeyTx = {
TransactionType: 'AccountSet',
Account: wallet.address,
SetFlag: xrpl.AccountSetAsfFlags.asfDisableMaster
}
xrpl.validate(disableMasterKeyTx)
console.log('Disabling master key pair...')
const response2 = await client.submitAndWait(disableMasterKeyTx, {
wallet, // only the master key pair can disable itself
autofill: true
})
const disableMasterResultCode = response2.result.meta.TransactionResult
if (disableMasterResultCode === 'tesSUCCESS') {
console.log('Master key disabled successfully.')
} else {
console.error(`AccountSet failed with code ${disableMasterResultCode}.`)
client.disconnect()
process.exit(1)
}If the transaction fails with the result tecNO_ALTERNATIVE_KEY, your account does not have another method of authorizing transactions currently enabled. You must assign a regular key pair or set up multi-signing, then try again to disable the master key pair.
If you later want to re-enable the master key pair, you can send an AccountSet transaction almost like this one, except for the following changes:
- Use the
ClearFlagfield instead of theSetFlagfield. - Sign the transaction using a regular key pair or multi-signing list. Naturally, you can't use the master key pair because it's disabled.
At this point the master key pair for the account should be disabled. You can confirm that this is the case using the account_info method and checking the disableMasterKey field of account_flags in the result.
// Confirm account flags -------------------------------------------------------
const accountInfoResp = await client.request({
command: 'account_info',
account: wallet.address,
ledger_index: 'validated'
})
if (accountInfoResp.error) {
console.error('Error looking up account:', accountInfoResp.error)
client.disconnect()
process.exit(1)
}
console.log(`Flags for account ${wallet.address}:`)
console.log(JSON.stringify(accountInfoResp.result.account_flags, null, 2))
if (accountInfoResp.result.account_flags.disableMasterKey) {
console.log('Master key pair is DISABLED')
} else {
console.log('Master key pair is ENABLED')
}
client.disconnect()If the result does not match your expectations, check whether the transaction you sent in the previous steps has executed successfully. It should be the most recent entry in the account's transaction history and it should have the result code tesSUCCESS. If you see any other result code, the transaction was not executed successfully.
Another possibility that may occur is that the account_info response you received was slightly out of date, because it used the validated ledger from just before your transaction was validated. This is especially likely when using public server clusters, where requests may go to different machines, but it can happen any time you request data from the ledger immediately after a transaction is validated. If you wait at least half a second and send the same account_info request again, you should get the updated results.
You can look up the account on the Testnet Explorer to see if its master key pair is disabled in the most recent ledger version.
For more information about this and related topics, see: