# Remove a Regular Key Pair This tutorial shows how to remove a [regular key pair](/es-es/docs/concepts/accounts/cryptographic-keys) from an [account](/es-es/docs/concepts/accounts). You can do this if you suspect your regular key pair is compromised. Tip: Change Regular Key Pair To replace an existing regular key pair with a new regular key pair, follow the exact same process as [assigning a regular key pair](/es-es/docs/tutorials/best-practices/key-management/assign-a-regular-key-pair) for the first time. ## Goals By following this tutorial, you should learn how to: - Look up the regular key pair associated with an account, if any. - Remove the regular key pair from an account. ## 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). ## 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 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} """) Before you can remove the regular key pair from an account, the account has to have a regular key pair assigned in the first place. Since the sample code uses a fresh account from the faucet, it needs to generate and assign a regular key pair. **Skip this part if you are using an existing account that already has a regular key pair assigned.** 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 configured. 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 configured. 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) ### 3. Check regular key pair associated with account Before you disable the regular key, you may want to confirm that the account has a regular key assigned and check which key it is. To do this, use the [account_info method](/docs/references/http-websocket-apis/public-api-methods/account-methods/account_info) and look at for a `RegularKey` field in the account data. If the field is present, it contains the [address](/es-es/docs/concepts/accounts/addresses) of the regular key pair; if the field is absent, the account does not currently have a regular key pair authorized. **This step is optional; you can remove the regular key pair without knowing which key it is.** JavaScript // Check regular key associated with account ----------------------------------- 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(`Account info for ${wallet.address}:`) console.log(JSON.stringify(accountInfoResp.result.account_data, null, 2)) if (accountInfoResp.result.account_data.RegularKey) { console.log('Current regular key:', accountInfoResp.result.account_data.RegularKey ) } else { console.log('No regular key set.') client.disconnect() process.exit(1) } Python # Check regular key associated with account ----------------------------------- account_info_resp = client.request( AccountInfo(account=wallet.address, ledger_index="validated") ) if not account_info_resp.is_successful(): print(f"Error looking up account:", account_info_resp.result) exit(1) account_data = account_info_resp.result["account_data"] print(f"Account info for {wallet.address}:") print(json.dumps(account_data, indent=2)) if "RegularKey" in account_data.keys(): print("Current regular key:", account_data["RegularKey"]) else: print("No regular key set.") exit(1) ### 4. Remove regular key pair To remove the regular key pair, send a [SetRegularKey transaction](/docs/references/protocol/transactions/types/setregularkey) without a `RegularKey` field. You can sign this transaction with the regular key pair itself, with the master key pair, or with a multi-signing list. JavaScript // Remove regular key from account --------------------------------------------- const removeRegularKeyTx = { TransactionType: 'SetRegularKey', Account: wallet.address // Omit RegularKey field to remove existing regular key from account } xrpl.validate(removeRegularKeyTx) console.log('Removing regular key from account...') const removeResp = await client.submitAndWait(removeRegularKeyTx, { wallet: regularKeyPair, // When removing, you can use the regular key or master key autofill: true }) const removeRegularKeyResultCode = removeResp.result.meta.TransactionResult if (removeRegularKeyResultCode === 'tesSUCCESS') { console.log('Regular Key successfully removed.') } else { console.error('SetRegularKey (removing) failed with code', removeRegularKeyResultCode ) client.disconnect() process.exit(1) } Python # Remove regular key from account --------------------------------------------- remove_regular_key_tx = SetRegularKey( account=wallet.address # Omit regular_key field to remove existing regular key from account ) print("Removing regular key from account...") # When removing, you can sign with the regular key or master key remove_resp = submit_and_wait(remove_regular_key_tx, client, regular_key_pair) remove_regular_key_result_code = remove_resp.result["meta"]["TransactionResult"] if remove_regular_key_result_code == "tesSUCCESS": print("Regular Key successfully removed.") else: print("SetRegularKey (removing) failed with code", remove_regular_key_result_code) exit(1) If the transaction fails with the result code `tecNO_ALTERNATIVE_KEY`, you cannot remove the regular key because the account does not have any other method of authorizing transactions: this means the master key pair is disabled and the account does not have a multi-signing list. Before you can remove the regular key pair, you must either re-enable the master key pair or set up a multi-signing list. ### 5. Confirm that the account has no regular key authorized After removing the regular key pair, you can confirm that the account has no regular key pair using the [account_info method](/docs/references/http-websocket-apis/public-api-methods/account-methods/account_info) in the same way as in [step 3](#3-check-regular-key-pair-associated-with-account). If the account data does not have a `RegularKey` field, then no regular key pair is authorized. JavaScript // Confirm that the account has no regular key --------------------------------- const accountInfoResp2 = await client.request({ command: 'account_info', account: wallet.address, ledger_index: 'validated' }) if (accountInfoResp2.error) { console.error('Error looking up account:', accountInfoResp2.error) client.disconnect() process.exit(1) } console.log(`Account info for ${wallet.address}:`) console.log(JSON.stringify(accountInfoResp2.result.account_data, null, 2)) if (accountInfoResp2.result.account_data.RegularKey) { console.log('Regular key address is:', accountInfoResp2.result.account_data.RegularKey ) } else { console.log('No regular key set.') } client.disconnect() Python # Confirm that the account has no regular key --------------------------------- account_info_resp2 = client.request( AccountInfo(account=wallet.address, ledger_index="validated") ) if not account_info_resp2.is_successful(): print("Error looking up account:", account_info_resp2.result) exit(1) account_data2 = account_info_resp2.result["account_data"] print(f"Account info for {wallet.address}:") print(json.dumps(account_data2, indent=2)) if "RegularKey" in account_data2.keys(): print("Regular key address is:", account_data2["RegularKey"]) else: print("No regular key set.") Another way to verify that you succeeded at removing the regular key pair is to attempt to send a transaction signed using the removed key pair. Submitting the transaction should fail with the `badSecret` error and an error message such as `Secret does not match account`. ## See Also - **Concepts:** - [Cryptographic Keys](/es-es/docs/concepts/accounts/cryptographic-keys) - [Multi-Signing](/es-es/docs/concepts/accounts/multi-signing) - [Transaction Cost](/es-es/docs/concepts/transactions/transaction-cost) - [Key Reset Transaction](/es-es/docs/concepts/transactions/transaction-cost#key-reset-transaction): a special case where you can send a SetRegularKey transaction with a transaction cost of 0. - **Tutorials:** - [Set Up Multi-Signing](/es-es/docs/tutorials/best-practices/key-management/set-up-multi-signing) - [Disable Master Key Pair](/es-es/docs/tutorials/best-practices/key-management/disable-master-key-pair) - **References:** - [SetRegularKey transaction](/docs/references/protocol/transactions/types/setregularkey) - [account_info method](/docs/references/http-websocket-apis/public-api-methods/account-methods/account_info) - [AccountRoot entry](/docs/references/protocol/ledger-data/ledger-entry-types/accountroot)