# Disable Master Key Pair This page describes how to disable the [master key pair](/es-es/docs/concepts/accounts/cryptographic-keys) 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](/es-es/docs/concepts/accounts/multi-signing) the *only* way to submit transactions from your account. Disabling the master key pair removes the default method of [authorizing transactions](/es-es/docs/concepts/transactions#authorizing-transactions). Before doing this, it's best to double-check that you can successfully send transactions using your regular key pair or multi-signing list. Due to the decentralized nature of the XRP Ledger, there is no one who can restore access to your account if something goes wrong. ## Goals 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. ## Prerequisites To complete this tutorial, you should: - Have a basic understanding of the XRP Ledger. - Have an [XRP Ledger client library](/es-es/docs/references/client-libraries), such as **xrpl.js**, installed. - Have a basic understanding of [Cryptographic Keys](/es-es/docs/concepts/accounts/cryptographic-keys). - Know how to [assign a regular key pair](/es-es/docs/tutorials/best-practices/key-management/assign-a-regular-key-pair) or [set up multi-signing](/es-es/docs/tutorials/best-practices/key-management/set-up-multi-signing) for an account. ## Source Code You can find the complete source code for this tutorial's examples in the code samples section of this website's repository. ## Steps ### 1. Install dependencies JavaScript From the code sample folder, use `npm` to install dependencies: ```sh npm i ``` Python From the code sample folder, set up a virtual environment and use `pip` to install dependencies: ```sh python -m venv .venv source .venv/bin/activate pip install -r requirements.txt ``` ### 2. Connect and get account(s) To 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. JavaScript 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} `) Python import json from xrpl.clients import JsonRpcClient from xrpl.wallet import generate_faucet_wallet, Wallet from xrpl.models.transactions import SetRegularKey, AccountSet, AccountSetAsfFlag from xrpl.models.requests import AccountInfo from xrpl.transaction import submit_and_wait client = JsonRpcClient("https://s.altnet.rippletest.net:51234") print("Funding new wallet from faucet...") wallet = generate_faucet_wallet(client) print(f"""Funded. Master key pair: Address: {wallet.address} Seed: {wallet.seed} """) ### 3. Set up another way of authorizing transactions 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](/es-es/docs/tutorials/best-practices/key-management/assign-a-regular-key-pair). **Skip this step if you are using an existing account that already has a regular key pair or multi-signing list set up.** JavaScript // 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) } Python # 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. algorithm = "ed25519" regular_key_pair = Wallet.create(algorithm) print(f"""Generated regular key pair: Address: {regular_key_pair.address} Seed: {regular_key_pair.seed} Algorithm: {algorithm} """) regular_key_tx = SetRegularKey( account=wallet.address, regular_key=regular_key_pair.address ) print("Assigning regular key to the account...") try: response = submit_and_wait(regular_key_tx, client, wallet) except Exception as err: print("Submitting SetRegularKey transaction failed with error", err) exit(1) set_regular_key_result_code = response.result["meta"]["TransactionResult"] if set_regular_key_result_code == "tesSUCCESS": print("Regular Key set successfully.") else: print(f"SetRegularKey failed with code {set_regular_key_result_code}.") exit(1) If your goal is to make the account a [black hole](/docs/concepts/accounts/addresses#special-addresses) that cannot send transactions at all, you still need to set a regular key. Instead of generating a key pair, use a known black hole address such as **rrrrrrrrrrrrrrrrrrrrrhoLvTp**. ### 4. Disable the master key pair To disable the master key pair, send an [AccountSet transaction](/docs/references/protocol/transactions/types/accountset) 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. JavaScript // 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) } Python # Disable master key pair ------------------------------------------------------ disable_master_key_tx = AccountSet( account=wallet.address, set_flag=AccountSetAsfFlag.ASF_DISABLE_MASTER ) print("Disabling master key pair...") response2 = submit_and_wait( disable_master_key_tx, client, wallet ) # only the master key pair can disable itself disable_master_result_code = response2.result["meta"]["TransactionResult"] if disable_master_result_code == "tesSUCCESS": print("Master key disabled successfully.") else: print(f"AccountSet failed with code {disable_master_result_code}.") 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](/es-es/docs/tutorials/best-practices/key-management/assign-a-regular-key-pair) or [set up multi-signing](/es-es/docs/tutorials/best-practices/key-management/set-up-multi-signing), then try again to disable the master key pair. Tip 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 `ClearFlag` field instead of the `SetFlag` field. - 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. ### 5. Confirm account flags 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](/docs/references/http-websocket-apis/public-api-methods/account-methods/account_info) and checking the `disableMasterKey` field of `account_flags` in the result. JavaScript // 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() Python # Confirm account flags -------------------------------------------------------- account_info_request = AccountInfo(account=wallet.address, ledger_index="validated") try: account_info_resp = client.request(account_info_request) except Exception as e: print(f"Error requesting account_info: {e}") exit(1) if not account_info_resp.is_successful(): print(f"Error looking up account: {account_info_resp.result}") exit(1) account_flags = account_info_resp.result["account_flags"] print(f"Flags for account {wallet.address}:") print(json.dumps(account_flags, indent=2)) if account_flags["disableMasterKey"]: print("Master key pair is DISABLED") else: print("Master key pair is ENABLED") 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](/es-es/docs/references/protocol/transactions/transaction-results), 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](https://testnet.xrpl.org/) to see if its master key pair is disabled in the most recent ledger version. ## See Also For more information about this and related topics, see: - **Concepts:** - [Cryptographic Keys](/es-es/docs/concepts/accounts/cryptographic-keys) - [Multi-Signing](/es-es/docs/concepts/accounts/multi-signing) - [Account Types](/es-es/docs/concepts/accounts/account-types) - **Tutorials:** - [Assign a Regular Key Pair](/es-es/docs/tutorials/best-practices/key-management/assign-a-regular-key-pair) - [Remove a Regular Key Pair](/es-es/docs/tutorials/best-practices/key-management/remove-a-regular-key-pair) - [Set Up Multi-Signing](/es-es/docs/tutorials/best-practices/key-management/set-up-multi-signing) - **References:** - [account_info method](/docs/references/http-websocket-apis/public-api-methods/account-methods/account_info) - [AccountSet transaction](/docs/references/protocol/transactions/types/accountset)