Compare commits

..

2 Commits

Author SHA1 Message Date
mDuo13
5bf310d357 Add Python sample code for assign regular key 2026-01-27 12:39:40 -08:00
mDuo13
d127b1aad2 Rewrite 'Assign a Regular Key Pair' tutorial w/ JS code sample 2026-01-22 17:49:38 -08:00
6 changed files with 238 additions and 611 deletions

View File

@@ -0,0 +1,3 @@
# Assign a Regular Key Pair
Generate a regular key pair and associate it with your account.

View File

@@ -0,0 +1,77 @@
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}
`)
// Generate a new key pair to use as the regular key ---------------------------
const algorithm = 'ed25519'
const regularKeyPair = xrpl.Wallet.generate(algorithm)
console.log(`Generated regular key pair:
Address: ${regularKeyPair.address}
Seed: ${regularKeyPair.seed}
Algorithm: ${algorithm}
`)
// Send SetRegularKey transaction ----------------------------------------------
const regularKeyTx = {
TransactionType: 'SetRegularKey',
Account: wallet.address,
RegularKey: regularKeyPair.address
}
xrpl.validate(regularKeyTx)
console.log('Signing and submitting the SetRegularKey transaction:',
JSON.stringify(regularKeyTx, null, 2))
const response = await client.submitAndWait(regularKeyTx, { wallet, autofill: true })
// Check result of the SetRegularKey transaction -------------------------------
console.log(JSON.stringify(response.result, null, 2))
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)
}
// Send a test transaction using the regular key -------------------------------
const testTx = {
TransactionType: 'AccountSet',
Account: wallet.address
}
xrpl.validate(testTx)
console.log('Signing and submitting the test transaction using the regular key')
const testResponse = await client.submitAndWait(testTx, {
wallet: regularKeyPair, // IMPORTANT: use the regular key pair here
autofill: true
})
// Check result of the test transaction ----------------------------------------
console.log(JSON.stringify(testResponse.result, null, 2))
const testResultCode = testResponse.result.meta.TransactionResult
const testSigningPubKey = testResponse.result.tx_json.SigningPubKey
if (testResultCode === 'tesSUCCESS') {
console.log('Test transaction was successful.')
} else {
console.log(`Test transaction failed with code ${testResultCode}`)
}
if (testSigningPubKey === regularKeyPair.publicKey) {
console.log('✅ This transaction was signed with the regular key pair.')
} else if (testSigningPubKey === wallet.publicKey) {
console.warn('❌ This transaction was signed with the master key pair.')
} else {
console.warn(`⚠️ Unexpected signing key mismatch.
Regular key: ${regularKeyPair.publicKey}
Key used: ${testSigningPubKey}`)
}
client.disconnect()

View File

@@ -0,0 +1,9 @@
{
"name": "assign-regular-key",
"version": "2.0.0",
"license": "MIT",
"dependencies": {
"xrpl": "^4.5.0"
},
"type": "module"
}

View File

@@ -0,0 +1,78 @@
import json
from xrpl.clients import JsonRpcClient
from xrpl.wallet import generate_faucet_wallet, Wallet
from xrpl.models.transactions import SetRegularKey, AccountSet
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}
""")
# Generate a new key pair to use as the regular key ----------------------------
algorithm = "ed25519"
regular_key_pair = Wallet.create(algorithm=algorithm)
print(f"""Generated regular key pair:
Address: {regular_key_pair.address}
Seed: {regular_key_pair.seed}
Algorithm: {algorithm}
""")
# Send SetRegularKey transaction -----------------------------------------------
regular_key_tx = SetRegularKey(
account=wallet.address, regular_key=regular_key_pair.address
)
print(
"Signing and submitting the SetRegularKey transaction:",
json.dumps(regular_key_tx.to_xrpl(), indent=2),
)
try:
response = submit_and_wait(regular_key_tx, client, wallet)
except err:
print("Submitting SetRegularKey transaction failed with error", err)
exit(1)
# Check result of the SetRegularKey transaction --------------------------------
print(json.dumps(response.result, indent=2))
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)
# Send a test transaction using the regular key --------------------------------
test_tx = AccountSet(account=wallet.address)
print("Signing and submitting the test transaction using the regular key")
try:
test_response = submit_and_wait(
test_tx, client, regular_key_pair # IMPORTANT: use regular key pair here
)
except err:
print("Submitting test transaction failed with error", err)
exit(1)
# Check result of the test transaction -----------------------------------------
print(json.dumps(test_response.result, indent=2))
test_result_code = test_response.result["meta"]["TransactionResult"]
test_signing_pub_key = test_response.result["tx_json"]["SigningPubKey"]
if test_result_code == "tesSUCCESS":
print("Test transaction was successful.")
else:
print(f"Test transaction failed with code {test_result_code}")
if test_signing_pub_key == regular_key_pair.public_key:
print("✅ This transaction was signed with the regular key pair.")
elif test_signing_pub_key == wallet.public_key:
print("❌ This transaction was signed with the master key pair.")
else:
print(f"""⚠️ Unexpected signing key mismatch.
Regular key: {regular_key_pair.public_key}
Key used: {test_signing_pub_key}""")

View File

@@ -0,0 +1 @@
xrpl-py>=4.4.0

View File

@@ -1,681 +1,140 @@
---
html: assign-a-regular-key-pair.html
parent: manage-account-settings.html
seo:
description: Authorize a second key pair to sign transactions from your account. This key pair can be changed or removed later.
description: Authorize a second key pair to sign transactions from your account. This key pair can be changed or removed later.
labels:
- Security
- Accounts
---
# Assign a Regular Key Pair
The XRP Ledger allows an account to authorize a secondary key pair, called a _[regular key pair](../../../concepts/accounts/cryptographic-keys.md)_, to sign future transactions. If the private key of a regular key pair is compromised, you can remove or replace it without changing the rest of your [account](../../../concepts/accounts/index.md) and re-establishing its relationships to other accounts. You can also rotate a regular key pair proactively. (Neither of those things is possible for the master key pair of an account, which is intrinsically linked to the account's address.)
This tutorial shows how to authorize a secondary key pair, called a _[regular key pair](../../../concepts/accounts/cryptographic-keys.md)_, to sign future transactions. Unlike the master key pair, which is mathematically linked to the account's address, you can remove or replace the regular key pair, which is better for security.
For more information about master and regular key pairs, see [Cryptographic Keys](../../../concepts/accounts/cryptographic-keys.md).
## Goals
This tutorial walks through the steps required to assign a regular key pair to your account:
By following this tutorial, you should learn how to:
1. [Generate a key pair](#1-generate-a-key-pair)
2. [Assign the key pair to your account as a regular key pair](#2-assign-the-key-pair-to-your-account-as-a-regular-key-pair)
3. [Verify the regular key pair](#3-verify-the-regular-key-pair)
4. [Explore next steps](#see-also)
- Securely generate a regular key pair and attach it to your account.
- Submit transactions using a regular key pair.
- Check a transaction to see if the key that was used to sign it matches a known key pair.
## Prerequisites
## 1. Generate a Key Pair
To complete this tutorial, you should:
Generate a key pair that you'll assign to your account as a regular key pair.
- Have a basic understanding of the XRP Ledger.
- Have an [XRP Ledger client library](../../../references/client-libraries.md), such as **xrpl.js**, installed.
- Have a basic understanding of [Cryptographic Keys](../../../concepts/accounts/cryptographic-keys.md).
This key pair is the same data type as a master key pair, so you can generate it the same way: you can use the client library of your choice or use the [wallet_propose method][] of a server you run. This might look as follows:
## Source Code
You can find the complete source code for this tutorial's examples in the {% repo-link path="_code-samples/assign-regular-key/" %}code samples section of this website's repository{% /repo-link %}.
## Steps
### 1. Install dependencies
{% tabs %}
{% tab label="JavaScript" %}
From the code sample folder, use `npm` to install dependencies:
{% tab label="WebSocket" %}
```json
// Request:
{
"command": "wallet_propose"
}
// Response:
{
"result": {
"account_id": "rsprUqu6BHAffAeG4HpSdjBNvnA6gdnZV7",
"key_type": "secp256k1",
"master_key": "KNEW BENT LYNN LED GAD BEN KENT SHAM HOBO RINK WALT ALLY",
"master_seed": "sh8i92YRnEjJy3fpFkL8txQSCVo79",
"master_seed_hex": "966C0F68643EFBA50D58D191D4CA8AA7",
"public_key": "aBRNH5wUurfhZcoyR6nRwDSa95gMBkovBJ8V4cp1C1pM28H7EPL1",
"public_key_hex": "03AEEFE1E8ED4BBC009DE996AC03A8C6B5713B1554794056C66E5B8D1753C7DD0E"
},
"status": "success",
"type": "response"
}
```
{% /tab %}
{% tab label="JSON-RPC" %}
```json
// Request:
{
"method": "wallet_propose"
}
// Response:
{
"result": {
"account_id": "rsprUqu6BHAffAeG4HpSdjBNvnA6gdnZV7",
"key_type": "secp256k1",
"master_key": "KNEW BENT LYNN LED GAD BEN KENT SHAM HOBO RINK WALT ALLY",
"master_seed": "sh8i92YRnEjJy3fpFkL8txQSCVo79",
"master_seed_hex": "966C0F68643EFBA50D58D191D4CA8AA7",
"public_key": "aBRNH5wUurfhZcoyR6nRwDSa95gMBkovBJ8V4cp1C1pM28H7EPL1",
"public_key_hex": "03AEEFE1E8ED4BBC009DE996AC03A8C6B5713B1554794056C66E5B8D1753C7DD0E",
"status": "success"
}
}
```
{% /tab %}
{% tab label="Commandline" %}
```sh
$ rippled wallet_propose
{
"result" : {
"account_id" : "rsprUqu6BHAffAeG4HpSdjBNvnA6gdnZV7",
"key_type" : "secp256k1",
"master_key" : "KNEW BENT LYNN LED GAD BEN KENT SHAM HOBO RINK WALT ALLY",
"master_seed" : "sh8i92YRnEjJy3fpFkL8txQSCVo79",
"master_seed_hex" : "966C0F68643EFBA50D58D191D4CA8AA7",
"public_key" : "aBRNH5wUurfhZcoyR6nRwDSa95gMBkovBJ8V4cp1C1pM28H7EPL1",
"public_key_hex" : "03AEEFE1E8ED4BBC009DE996AC03A8C6B5713B1554794056C66E5B8D1753C7DD0E",
"status" : "success"
}
}
npm i
```
{% /tab %}
{% tab label="Python" %}
```py
keypair = xrpl.wallet.Wallet.create()
print("seed:", keypair.seed)
print("classic address:", keypair.address)
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
```
{% /tab %}
{% /tabs %}
### 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.
{% tabs %}
{% tab label="JavaScript" %}
```js
const keypair = new xrpl.Wallet()
console.log("seed:", keypair.seed)
console.log("classic address:", keypair.classicAddress)
```
{% code-snippet file="/_code-samples/assign-regular-key/js/assign-regular-key.js" language="js" before="// Generate a new key pair" /%}
{% /tab %}
{% tab label="Java" %}
```java
WalletFactory walletFactory = DefaultWalletFactory.getInstance();
Wallet keypair = walletFactory.randomWallet(true).wallet();
System.out.println(keypair);
System.out.println(keypair.privateKey().get());
```
{% tab label="Python" %}
{% code-snippet file="/_code-samples/assign-regular-key/py/assign-regular-key.py" language="py" before="# Generate a new key pair" /%}
{% /tab %}
{% /tabs %}
In the next step, you'll use the address from this response (`account_id` in the API response) to assign the key pair as a regular key pair to your account. Also, save the seed value from this key pair (`master_seed` in the API response) somewhere securely; you'll use that key to sign transactions later. (Everything else, you can forget about.)
### 3. Generate a key pair
Next, generate a key pair to use as the regular key pair. This is the same data type as a master key pair, so you can generate it the same way.
## 2. Assign the Key Pair to Your Account as a Regular Key Pair
{% admonition type="danger" name="Warning" %}
It's important to generate and store the key pair securely; otherwise, it may be possible for malicious actors to gain access to your account and take your money. Common errors include:
Use a [SetRegularKey transaction][] to assign the key pair you generated in step 1 to your account as a regular key pair.
When assigning a regular key pair to your account for the first time, the SetRegularKey transaction requires signing with your account's master private key (secret). There are [several ways of securely signing transactions](../../../concepts/transactions/secure-signing.md), but this tutorial uses a local `rippled` server.
When you send later SetRegularKey transactions, you can sign using the existing regular private key to replace or [remove itself](change-or-remove-a-regular-key-pair.md). Note that you should still not submit your regular private key across the network.
### Sign Your Transaction
{% partial file="/docs/_snippets/tutorial-sign-step.md" /%}
Populate the request fields with the following values:
| Request Field | Value |
|:--------------|:-------------------------------------------------------------|
| `Account` | The address of your account. |
| `RegularKey` | `account_id` generated in step 1. |
| `secret` | `master_key`, `master_seed`, or `master_seed_hex` (master private key) for your account. |
#### Request Format
An example of the request format:
- Getting your secret key from a remote machine, or otherwise sending your secret key in plain text over the internet.
- Generating a key pair using a compromised software library.
- Generating a key pair from a passphrase or other secret value that does not have enough entropy.
{% /admonition %}
{% tabs %}
{% tab label="WebSocket" %}
```json
{
"command": "sign",
"tx_json": {
"TransactionType": "SetRegularKey",
"Account": "rUAi7pipxGpYfPNg3LtPcf2ApiS8aw9A93",
"RegularKey": "rsprUqu6BHAffAeG4HpSdjBNvnA6gdnZV7"
},
"secret": "ssCATR7CBvn4GLd1UuU2bqqQffHki"
}
```
{% tab label="JavaScript" %}
Use the [`Wallet.generate()` class method](https://js.xrpl.org/classes/Wallet.html#generate) to generate a key pair locally on your machine.
{% code-snippet file="/_code-samples/assign-regular-key/js/assign-regular-key.js" language="js" from="// Generate a new key pair" before="// Send SetRegularKey transaction" /%}
{% /tab %}
{% tab label="JSON-RPC" %}
```json
{
"method": "sign",
"params": [
{
"tx_json": {
"TransactionType": "SetRegularKey",
"Account": "rUAi7pipxGpYfPNg3LtPcf2ApiS8aw9A93",
"RegularKey": "rsprUqu6BHAffAeG4HpSdjBNvnA6gdnZV7"
},
"secret": "ssCATR7CBvn4GLd1UuU2bqqQffHki"
}
]
}
```
{% tab label="Python" %}
Use the [`Wallet.create()` class method](https://xrpl-py.readthedocs.io/en/stable/source/xrpl.wallet.html#xrpl.wallet.Wallet.create) to generate a key pair locally on your machine.
{% code-snippet file="/_code-samples/assign-regular-key/py/assign-regular-key.py" language="py" from="# Generate a new key pair" before="# Send SetRegularKey transaction" /%}
{% /tab %}
{% tab label="Commandline" %}
```sh
#Syntax: sign secret tx_json
rippled sign ssCATR7CBvn4GLd1UuU2bqqQffHki '{"TransactionType": "SetRegularKey", "Account": "rUAi7pipxGpYfPNg3LtPcf2ApiS8aw9A93", "RegularKey": "rsprUqu6BHAffAeG4HpSdjBNvnA6gdnZV7"}'
```
{% /tab %}
{% /tabs %}
### 4. Send a SetRegularKey transaction
#### Response Format
Use a [SetRegularKey transaction][] to assign the new key pair to your account as a regular key pair.
An example of a successful response:
{% admonition type="success" name="Tip" %}This example uses the master key pair to assign the regular key pair, but you can also use an existing regular key pair to replace itself, or assign a regular key pair using a [multi-signing list](../../../concepts/accounts/multi-signing.md) if your account has multi-signing set up.{% /admonition %}
{% tabs %}
{% tab label="WebSocket" %}
```json
{
"result": {
"tx_blob": "1200052280000000240000000468400000000000000A73210384CA3C528F10C75F26E0917F001338BD3C9AA1A39B9FBD583DFFFD96CF2E2D7A7446304402204BCD5663F3A2BA02D2CE374439096EC6D27273522CD6E6E0BDBFB518730EAAE402200ECD02D8D2525D6FA4642613E71E395ECCEA01C42C35A668BF092A00EB649C268114830923439D307E642CED308FD91EF701A7BAA74788141620D685FB08D81A70D0B668749CF2E130EA7540",
"tx_json": {
"Account": "rUAi7pipxGpYfPNg3LtPcf2ApiS8aw9A93",
"Fee": "10",
"Flags": 2147483648,
"RegularKey": "rsprUqu6BHAffAeG4HpSdjBNvnA6gdnZV7",
"Sequence": 4,
"SigningPubKey": "0384CA3C528F10C75F26E0917F001338BD3C9AA1A39B9FBD583DFFFD96CF2E2D7A",
"TransactionType": "SetRegularKey",
"TxnSignature": "304402204BCD5663F3A2BA02D2CE374439096EC6D27273522CD6E6E0BDBFB518730EAAE402200ECD02D8D2525D6FA4642613E71E395ECCEA01C42C35A668BF092A00EB649C26",
"hash": "AB73BBF7C99061678B59FB48D72CA0F5FC6DD2815B6736C6E9EB94439EC236CE"
}
},
"status": "success",
"type": "response"
}
```
{% tab label="JavaScript" %}
{% code-snippet file="/_code-samples/assign-regular-key/js/assign-regular-key.js" language="js" from="// Send SetRegularKey transaction" before="// Send a test transaction" /%}
{% /tab %}
{% tab label="JSON-RPC" %}
```json
{
"result": {
"status": "success",
"tx_blob": "1200052280000000240000000768400000000000000A73210384CA3C528F10C75F26E0917F001338BD3C9AA1A39B9FBD583DFFFD96CF2E2D7A7446304402201453CA3D4D17F0EE3828B9E3D6ACF65327F5D4FC2BA30953CACF6CBCB4145E3502202F2154BED1D7462CAC1E3DBB31864E48C3BA0B3133ACA5E37EC54F0D0C339E2D8114830923439D307E642CED308FD91EF701A7BAA74788141620D685FB08D81A70D0B668749CF2E130EA7540",
"tx_json": {
"Account": "rUAi7pipxGpYfPNg3LtPcf2ApiS8aw9A93",
"Fee": "10",
"Flags": 2147483648,
"RegularKey": "rsprUqu6BHAffAeG4HpSdjBNvnA6gdnZV7",
"Sequence": 4,
"SigningPubKey": "0384CA3C528F10C75F26E0917F001338BD3C9AA1A39B9FBD583DFFFD96CF2E2D7A",
"TransactionType": "SetRegularKey",
"TxnSignature": "304402201453CA3D4D17F0EE3828B9E3D6ACF65327F5D4FC2BA30953CACF6CBCB4145E3502202F2154BED1D7462CAC1E3DBB31864E48C3BA0B3133ACA5E37EC54F0D0C339E2D",
"hash": "AB73BBF7C99061678B59FB48D72CA0F5FC6DD2815B6736C6E9EB94439EC236CE"
}
}
}
```
{% tab label="Python" %}
{% code-snippet file="/_code-samples/assign-regular-key/py/assign-regular-key.py" language="py" from="# Send SetRegularKey transaction" before="# Send a test transaction" /%}
{% /tab %}
{% tab label="Commandline" %}
```json
{
"result" : {
"status" : "success",
"tx_blob" : "1200052280000000240000000768400000000000000A73210384CA3C528F10C75F26E0917F001338BD3C9AA1A39B9FBD583DFFFD96CF2E2D7A7446304402201453CA3D4D17F0EE3828B9E3D6ACF65327F5D4FC2BA30953CACF6CBCB4145E3502202F2154BED1D7462CAC1E3DBB31864E48C3BA0B3133ACA5E37EC54F0D0C339E2D8114830923439D307E642CED308FD91EF701A7BAA74788141620D685FB08D81A70D0B668749CF2E130EA7540",
"tx_json" : {
"Account" : "rUAi7pipxGpYfPNg3LtPcf2ApiS8aw9A93",
"Fee" : "10",
"Flags" : 2147483648,
"RegularKey" : "rsprUqu6BHAffAeG4HpSdjBNvnA6gdnZV7",
"Sequence" : 4,
"SigningPubKey" : "0384CA3C528F10C75F26E0917F001338BD3C9AA1A39B9FBD583DFFFD96CF2E2D7A",
"TransactionType" : "SetRegularKey",
"TxnSignature" : "304402201453CA3D4D17F0EE3828B9E3D6ACF65327F5D4FC2BA30953CACF6CBCB4145E3502202F2154BED1D7462CAC1E3DBB31864E48C3BA0B3133ACA5E37EC54F0D0C339E2D",
"hash" : "AB73BBF7C99061678B59FB48D72CA0F5FC6DD2815B6736C6E9EB94439EC236CE"
}
}
}
```
{% /tab %}
{% /tabs %}
The `sign` command response contains a `tx_blob` value, as shown above. The offline signing response contains a `signedTransaction` value. Both are signed binary representations (blobs) of the transaction.
### 5. Send a test transaction using the regular key
Next, use the `submit` command to send the transaction blob (`tx_blob` or `signedTransaction`) to the network.
After the SetRegularKey transaction succeeds, the regular key pair is assigned to your account and you should be able to send transactions using the regular key pair. **To avoid losing control of your account,** it is important that you test your regular key before you take any additional steps such as [disabling the master key pair](disable-master-key-pair.md). If you make a mistake and lose access to your account, no one can restore it for you.
### Submit Your Transaction
Take the `signedTransaction` value from the offline signing response or the `tx_blob` value from the `sign` command response and submit it as the `tx_blob` value using the [submit method][].
#### Request Format
An example of the request format:
To test the key, send any type of transaction, signing it using the regular key pair. The sample code sends an [AccountSet transaction][] with no parameters, which is a "no-op" that does nothing besides use a sequence number and burn the transaction cost.
{% tabs %}
{% tab label="WebSocket" %}
```json
{
"command": "submit",
"tx_blob": "1200052280000000240000000468400000000000000A73210384CA3C528F10C75F26E0917F001338BD3C9AA1A39B9FBD583DFFFD96CF2E2D7A7446304402204BCD5663F3A2BA02D2CE374439096EC6D27273522CD6E6E0BDBFB518730EAAE402200ECD02D8D2525D6FA4642613E71E395ECCEA01C42C35A668BF092A00EB649C268114830923439D307E642CED308FD91EF701A7BAA74788141620D685FB08D81A70D0B668749CF2E130EA7540"
}
```
{% tab label="JavaScript" %}
{% code-snippet file="/_code-samples/assign-regular-key/js/assign-regular-key.js" language="js" from="// Send a test transaction" before="// Check result of the test" /%}
{% /tab %}
{% tab label="JSON-RPC" %}
```json
{
"method":"submit",
"params": [
{
"tx_blob": "1200052280000000240000000468400000000000000A73210384CA3C528F10C75F26E0917F001338BD3C9AA1A39B9FBD583DFFFD96CF2E2D7A7446304402204BCD5663F3A2BA02D2CE374439096EC6D27273522CD6E6E0BDBFB518730EAAE402200ECD02D8D2525D6FA4642613E71E395ECCEA01C42C35A668BF092A00EB649C268114830923439D307E642CED308FD91EF701A7BAA74788141620D685FB08D81A70D0B668749CF2E130EA7540"
}
]
}
```
{% tab label="Python" %}
{% code-snippet file="/_code-samples/assign-regular-key/py/assign-regular-key.py" language="py" from="# Send a test transaction" before="# Check result of the test" /%}
{% /tab %}
{% tab label="Commandline" %}
```sh
#Syntax: submit tx_blob
rippled submit 1200052280000000240000000468400000000000000A73210384CA3C528F10C75F26E0917F001338BD3C9AA1A39B9FBD583DFFFD96CF2E2D7A7446304402204BCD5663F3A2BA02D2CE374439096EC6D27273522CD6E6E0BDBFB518730EAAE402200ECD02D8D2525D6FA4642613E71E395ECCEA01C42C35A668BF092A00EB649C268114830923439D307E642CED308FD91EF701A7BAA74788141620D685FB08D81A70D0B668749CF2E130EA7540
```
{% /tab %}
{% /tabs %}
### 6. Confirm that the test transaction succeeded as expected
#### Response Format
An example of a successful response:
If the test transaction succeeds, your regular key pair works as expected. For further confirmation, you can look at the `SigningPubKey` field which is automatically added to a transaction during signing; this field contains the _public key_ of the key pair that was used to sign the transaction, and is what the network uses to validate the transaction signature. When you use your regular key pair to sign a transaction, the `SigningPubKey` field contains the public key from your regular key pair.
{% tabs %}
{% tab label="WebSocket" %}
```json
{
"result": {
"engine_result": "tesSUCCESS",
"engine_result_code": 0,
"engine_result_message": "The transaction was applied. Only final in a validated ledger.",
"tx_blob": "1200052280000000240000000468400000000000000A73210384CA3C528F10C75F26E0917F001338BD3C9AA1A39B9FBD583DFFFD96CF2E2D7A7446304402204BCD5663F3A2BA02D2CE374439096EC6D27273522CD6E6E0BDBFB518730EAAE402200ECD02D8D2525D6FA4642613E71E395ECCEA01C42C35A668BF092A00EB649C268114830923439D307E642CED308FD91EF701A7BAA74788141620D685FB08D81A70D0B668749CF2E130EA7540",
"tx_json": {
"Account": "rUAi7pipxGpYfPNg3LtPcf2ApiS8aw9A93",
"Fee": "10",
"Flags": 2147483648,
"RegularKey": "rsprUqu6BHAffAeG4HpSdjBNvnA6gdnZV7",
"Sequence": 4,
"SigningPubKey": "0384CA3C528F10C75F26E0917F001338BD3C9AA1A39B9FBD583DFFFD96CF2E2D7A",
"TransactionType": "SetRegularKey",
"TxnSignature": "304402204BCD5663F3A2BA02D2CE374439096EC6D27273522CD6E6E0BDBFB518730EAAE402200ECD02D8D2525D6FA4642613E71E395ECCEA01C42C35A668BF092A00EB649C26",
"hash": "AB73BBF7C99061678B59FB48D72CA0F5FC6DD2815B6736C6E9EB94439EC236CE"
}
},
"status": "success",
"type": "response"
}
```
{% tab label="JavaScript" %}
{% code-snippet file="/_code-samples/assign-regular-key/js/assign-regular-key.js" language="js" from="// Check result of the test" /%}
{% /tab %}
{% tab label="JSON-RPC" %}
```json
{
"result": {
"engine_result": "tesSUCCESS",
"engine_result_code": 0,
"engine_result_message": "The transaction was applied. Only final in a validated ledger.",
"status": "success",
"tx_blob": "1200052280000000240000000468400000000000000A73210384CA3C528F10C75F26E0917F001338BD3C9AA1A39B9FBD583DFFFD96CF2E2D7A7446304402204BCD5663F3A2BA02D2CE374439096EC6D27273522CD6E6E0BDBFB518730EAAE402200ECD02D8D2525D6FA4642613E71E395ECCEA01C42C35A668BF092A00EB649C268114830923439D307E642CED308FD91EF701A7BAA74788141620D685FB08D81A70D0B668749CF2E130EA7540",
"tx_json": {
"Account": "rUAi7pipxGpYfPNg3LtPcf2ApiS8aw9A93",
"Fee": "10",
"Flags": 2147483648,
"RegularKey": "rsprUqu6BHAffAeG4HpSdjBNvnA6gdnZV7",
"Sequence": 4,
"SigningPubKey": "0384CA3C528F10C75F26E0917F001338BD3C9AA1A39B9FBD583DFFFD96CF2E2D7A",
"TransactionType": "SetRegularKey",
"TxnSignature": "304402204BCD5663F3A2BA02D2CE374439096EC6D27273522CD6E6E0BDBFB518730EAAE402200ECD02D8D2525D6FA4642613E71E395ECCEA01C42C35A668BF092A00EB649C26",
"hash": "AB73BBF7C99061678B59FB48D72CA0F5FC6DD2815B6736C6E9EB94439EC236CE"
}
}
}
```
{% tab label="Python" %}
{% code-snippet file="/_code-samples/assign-regular-key/py/assign-regular-key.py" language="py" from="# Check result of the test" /%}
{% /tab %}
{% tab label="Commandline" %}
```json
{
"result" : {
"engine_result" : "tesSUCCESS",
"engine_result_code" : 0,
"engine_result_message" : "The transaction was applied. Only final in a validated ledger.",
"status" : "success",
"tx_blob" : "1200052280000000240000000468400000000000000A73210384CA3C528F10C75F26E0917F001338BD3C9AA1A39B9FBD583DFFFD96CF2E2D7A7446304402204BCD5663F3A2BA02D2CE374439096EC6D27273522CD6E6E0BDBFB518730EAAE402200ECD02D8D2525D6FA4642613E71E395ECCEA01C42C35A668BF092A00EB649C268114830923439D307E642CED308FD91EF701A7BAA74788141620D685FB08D81A70D0B668749CF2E130EA7540",
"tx_json" : {
"Account" : "rUAi7pipxGpYfPNg3LtPcf2ApiS8aw9A93",
"Fee" : "10",
"Flags" : 2147483648,
"RegularKey" : "rsprUqu6BHAffAeG4HpSdjBNvnA6gdnZV7",
"Sequence" : 4,
"SigningPubKey" : "0384CA3C528F10C75F26E0917F001338BD3C9AA1A39B9FBD583DFFFD96CF2E2D7A",
"TransactionType" : "SetRegularKey",
"TxnSignature" : "304402204BCD5663F3A2BA02D2CE374439096EC6D27273522CD6E6E0BDBFB518730EAAE402200ECD02D8D2525D6FA4642613E71E395ECCEA01C42C35A668BF092A00EB649C26",
"hash" : "AB73BBF7C99061678B59FB48D72CA0F5FC6DD2815B6736C6E9EB94439EC236CE"
}
}
}
```
{% /tab %}
{% /tabs %}
Note that the response contains a `hash` of the transaction, which you can use to [look up the transaction's final outcome](../../../references/http-websocket-apis/public-api-methods/transaction-methods/tx.md).
## 3. Verify the Regular Key Pair
At this point, the regular key pair is assigned to your account and you should be able to send transactions using the regular key pair. **To avoid losing control of your account,** it is important that you test your regular key before you take any additional steps such as [disabling the master key pair](disable-master-key-pair.md). If you make a mistake and lose access to your account, no one can restore it for you.
To verify that your account has the regular key pair set correctly, submit an [AccountSet transaction][] from your account, signing it with the regular private key you assigned to your account in step 2. As in step 1, this tutorial uses a local `rippled` server as a [way of securely signing transactions](../../../concepts/transactions/secure-signing.md).
### Sign Your Transaction
{% partial file="/docs/_snippets/tutorial-sign-step.md" /%}
Populate the request fields with the following values:
| Request Field | Value |
|:--------------|:-------------------------------------------------------------|
| `Account` | The address of your account. |
| `secret` | `master_key`, `master_seed`, or `master_seed_hex` (regular private key) generated in step 1 and assigned to your account in step 2. |
#### Request Format
Here's an example of the request format. Note that the request does not include any `AccountSet` options. This means that a successful transaction has no effect other than to confirm that the regular key pair is set correctly for your account (and to destroy the transaction cost).
{% tabs %}
{% tab label="WebSocket" %}
```json
{
"command": "sign",
"tx_json": {
"TransactionType": "AccountSet",
"Account": "rUAi7pipxGpYfPNg3LtPcf2ApiS8aw9A93"
},
"secret": "sh8i92YRnEjJy3fpFkL8txQSCVo79"
}
```
{% /tab %}
{% tab label="JSON-RPC" %}
```json
{
"method": "sign",
"params": [
{
"tx_json": {
"TransactionType": "AccountSet",
"Account": "rUAi7pipxGpYfPNg3LtPcf2ApiS8aw9A93"
},
"secret": "sh8i92YRnEjJy3fpFkL8txQSCVo79"
}
]
}
```
{% /tab %}
{% tab label="Commandline" %}
```sh
#Syntax: sign secret tx_json
rippled sign sh8i92YRnEjJy3fpFkL8txQSCVo79 '{"TransactionType": "AccountSet", "Account": "rUAi7pipxGpYfPNg3LtPcf2ApiS8aw9A93"}'
```
{% /tab %}
{% /tabs %}
#### Response Format
An example of a successful response:
{% tabs %}
{% tab label="WebSocket" %}
```json
{
"result": {
"tx_blob": "1200032280000000240000000468400000000000000A73210330E7FC9D56BB25D6893BA3F317AE5BCF33B3291BD63DB32654A313222F7FD02074473045022100A50E867D3B1B5A39F23F1ABCA5C7C3EC755442FDAA357EFD897B865ACA7686DB02206077BF459BCE39BCCBFE1A128DA986D1E00CBEC5F0D6B0E11710F60BE2976FB88114623B8DA4A0BFB3B61AB423391A182DC693DC159E",
"tx_json": {
"Account": "rUAi7pipxGpYfPNg3LtPcf2ApiS8aw9A93",
"Fee": "10",
"Flags": 2147483648,
"Sequence": 4,
"SigningPubKey": "0330E7FC9D56BB25D6893BA3F317AE5BCF33B3291BD63DB32654A313222F7FD020",
"TransactionType": "AccountSet",
"TxnSignature": "3045022100A50E867D3B1B5A39F23F1ABCA5C7C3EC755442FDAA357EFD897B865ACA7686DB02206077BF459BCE39BCCBFE1A128DA986D1E00CBEC5F0D6B0E11710F60BE2976FB8",
"hash": "D9B305CB6E861D0994A5CDD4726129D91AC4277111DC444DE4CEE44AD4674A9F"
}
},
"status": "success",
"type": "response"
}
```
{% /tab %}
{% tab label="JSON-RPC" %}
```json
{
"result": {
"status": "success",
"tx_blob": "1200032280000000240000000468400000000000000A73210330E7FC9D56BB25D6893BA3F317AE5BCF33B3291BD63DB32654A313222F7FD02074473045022100A50E867D3B1B5A39F23F1ABCA5C7C3EC755442FDAA357EFD897B865ACA7686DB02206077BF459BCE39BCCBFE1A128DA986D1E00CBEC5F0D6B0E11710F60BE2976FB88114623B8DA4A0BFB3B61AB423391A182DC693DC159E",
"tx_json": {
"Account": "rUAi7pipxGpYfPNg3LtPcf2ApiS8aw9A93",
"Fee": "10",
"Flags": 2147483648,
"Sequence": 4,
"SigningPubKey": "0330E7FC9D56BB25D6893BA3F317AE5BCF33B3291BD63DB32654A313222F7FD020",
"TransactionType": "AccountSet",
"TxnSignature": "3045022100A50E867D3B1B5A39F23F1ABCA5C7C3EC755442FDAA357EFD897B865ACA7686DB02206077BF459BCE39BCCBFE1A128DA986D1E00CBEC5F0D6B0E11710F60BE2976FB8",
"hash": "D9B305CB6E861D0994A5CDD4726129D91AC4277111DC444DE4CEE44AD4674A9F"
}
}
}
```
{% /tab %}
{% tab label="Commandline" %}
```json
{
"result" : {
"status" : "success",
"tx_blob" : "1200032280000000240000000468400000000000000A73210330E7FC9D56BB25D6893BA3F317AE5BCF33B3291BD63DB32654A313222F7FD02074473045022100A50E867D3B1B5A39F23F1ABCA5C7C3EC755442FDAA357EFD897B865ACA7686DB02206077BF459BCE39BCCBFE1A128DA986D1E00CBEC5F0D6B0E11710F60BE2976FB88114623B8DA4A0BFB3B61AB423391A182DC693DC159E",
"tx_json" : {
"Account" : "rUAi7pipxGpYfPNg3LtPcf2ApiS8aw9A93",
"Fee" : "10",
"Flags" : 2147483648,
"Sequence" : 4,
"SigningPubKey" : "0330E7FC9D56BB25D6893BA3F317AE5BCF33B3291BD63DB32654A313222F7FD020",
"TransactionType" : "AccountSet",
"TxnSignature" : "3045022100A50E867D3B1B5A39F23F1ABCA5C7C3EC755442FDAA357EFD897B865ACA7686DB02206077BF459BCE39BCCBFE1A128DA986D1E00CBEC5F0D6B0E11710F60BE2976FB8",
"hash" : "D9B305CB6E861D0994A5CDD4726129D91AC4277111DC444DE4CEE44AD4674A9F"
}
}
}
```
{% /tab %}
{% /tabs %}
The `sign` command response contains a `tx_blob` value, as shown above. The offline signing response contains a `signedTransaction` value. Both are signed binary representations (blobs) of the transaction.
Next, use the `submit` command to send the transaction blob (`tx_blob` or `signedTransaction`) to the network.
### Submit Your Transaction
Take the `signedTransaction` value from the offline signing response or the `tx_blob` value from the `sign` command response and submit it as the `tx_blob` value using the [submit method][].
#### Request Format
An example of the request format:
{% tabs %}
{% tab label="WebSocket" %}
```json
{
"command": "submit",
"tx_blob": "1200032280000000240000000468400000000000000A73210330E7FC9D56BB25D6893BA3F317AE5BCF33B3291BD63DB32654A313222F7FD02074473045022100A50E867D3B1B5A39F23F1ABCA5C7C3EC755442FDAA357EFD897B865ACA7686DB02206077BF459BCE39BCCBFE1A128DA986D1E00CBEC5F0D6B0E11710F60BE2976FB88114623B8DA4A0BFB3B61AB423391A182DC693DC159E"
}
```
{% /tab %}
{% tab label="JSON-RPC" %}
```json
{
"method":"submit",
"params": [
{
"tx_blob": "1200032280000000240000000468400000000000000A73210330E7FC9D56BB25D6893BA3F317AE5BCF33B3291BD63DB32654A313222F7FD02074473045022100A50E867D3B1B5A39F23F1ABCA5C7C3EC755442FDAA357EFD897B865ACA7686DB02206077BF459BCE39BCCBFE1A128DA986D1E00CBEC5F0D6B0E11710F60BE2976FB88114623B8DA4A0BFB3B61AB423391A182DC693DC159E"
}
]
}
```
{% /tab %}
{% tab label="Commandline" %}
```sh
#Syntax: submit tx_blob
rippled submit 1200032280000000240000000468400000000000000A73210330E7FC9D56BB25D6893BA3F317AE5BCF33B3291BD63DB32654A313222F7FD02074473045022100A50E867D3B1B5A39F23F1ABCA5C7C3EC755442FDAA357EFD897B865ACA7686DB02206077BF459BCE39BCCBFE1A128DA986D1E00CBEC5F0D6B0E11710F60BE2976FB88114623B8DA4A0BFB3B61AB423391A182DC693DC159E
```
{% /tab %}
{% /tabs %}
#### Response Format
An example of a successful response:
{% tabs %}
{% tab label="WebSocket" %}
```json
{
"result": {
"engine_result": "tesSUCCESS",
"engine_result_code": 0,
"engine_result_message": "The transaction was applied. Only final in a validated ledger.",
"tx_blob": "1200032280000000240000000468400000000000000A73210330E7FC9D56BB25D6893BA3F317AE5BCF33B3291BD63DB32654A313222F7FD02074473045022100A50E867D3B1B5A39F23F1ABCA5C7C3EC755442FDAA357EFD897B865ACA7686DB02206077BF459BCE39BCCBFE1A128DA986D1E00CBEC5F0D6B0E11710F60BE2976FB88114623B8DA4A0BFB3B61AB423391A182DC693DC159E",
"tx_json": {
"Account": "rUAi7pipxGpYfPNg3LtPcf2ApiS8aw9A93",
"Fee": "10",
"Flags": 2147483648,
"Sequence": 4,
"SigningPubKey": "0330E7FC9D56BB25D6893BA3F317AE5BCF33B3291BD63DB32654A313222F7FD020",
"TransactionType": "AccountSet",
"TxnSignature": "3045022100A50E867D3B1B5A39F23F1ABCA5C7C3EC755442FDAA357EFD897B865ACA7686DB02206077BF459BCE39BCCBFE1A128DA986D1E00CBEC5F0D6B0E11710F60BE2976FB8",
"hash": "D9B305CB6E861D0994A5CDD4726129D91AC4277111DC444DE4CEE44AD4674A9F"
}
},
"status": "success",
"type": "response"
}
```
{% /tab %}
{% tab label="JSON-RPC" %}
```json
{
"result": {
"engine_result": "tesSUCCESS",
"engine_result_code": 0,
"engine_result_message": "The transaction was applied. Only final in a validated ledger.",
"status": "success",
"tx_blob": "1200032280000000240000000468400000000000000A73210330E7FC9D56BB25D6893BA3F317AE5BCF33B3291BD63DB32654A313222F7FD02074473045022100A50E867D3B1B5A39F23F1ABCA5C7C3EC755442FDAA357EFD897B865ACA7686DB02206077BF459BCE39BCCBFE1A128DA986D1E00CBEC5F0D6B0E11710F60BE2976FB88114623B8DA4A0BFB3B61AB423391A182DC693DC159E",
"tx_json": {
"Account": "rUAi7pipxGpYfPNg3LtPcf2ApiS8aw9A93",
"Fee": "10",
"Flags": 2147483648,
"Sequence": 4,
"SigningPubKey": "0330E7FC9D56BB25D6893BA3F317AE5BCF33B3291BD63DB32654A313222F7FD020",
"TransactionType": "AccountSet",
"TxnSignature": "3045022100A50E867D3B1B5A39F23F1ABCA5C7C3EC755442FDAA357EFD897B865ACA7686DB02206077BF459BCE39BCCBFE1A128DA986D1E00CBEC5F0D6B0E11710F60BE2976FB8",
"hash": "D9B305CB6E861D0994A5CDD4726129D91AC4277111DC444DE4CEE44AD4674A9F"
}
}
}
```
{% /tab %}
{% tab label="Commandline" %}
```json
{
"result" : {
"engine_result" : "tesSUCCESS",
"engine_result_code" : 0,
"engine_result_message" : "The transaction was applied. Only final in a validated ledger.",
"status" : "success",
"tx_blob" : "1200032280000000240000000468400000000000000A73210330E7FC9D56BB25D6893BA3F317AE5BCF33B3291BD63DB32654A313222F7FD02074473045022100A50E867D3B1B5A39F23F1ABCA5C7C3EC755442FDAA357EFD897B865ACA7686DB02206077BF459BCE39BCCBFE1A128DA986D1E00CBEC5F0D6B0E11710F60BE2976FB88114623B8DA4A0BFB3B61AB423391A182DC693DC159E",
"tx_json" : {
"Account" : "rUAi7pipxGpYfPNg3LtPcf2ApiS8aw9A93",
"Fee" : "10",
"Flags" : 2147483648,
"Sequence" : 4,
"SigningPubKey" : "0330E7FC9D56BB25D6893BA3F317AE5BCF33B3291BD63DB32654A313222F7FD020",
"TransactionType" : "AccountSet",
"TxnSignature" : "3045022100A50E867D3B1B5A39F23F1ABCA5C7C3EC755442FDAA357EFD897B865ACA7686DB02206077BF459BCE39BCCBFE1A128DA986D1E00CBEC5F0D6B0E11710F60BE2976FB8",
"hash" : "D9B305CB6E861D0994A5CDD4726129D91AC4277111DC444DE4CEE44AD4674A9F"
}
}
}
```
{% /tab %}
{% /tabs %}
If the transaction fails with the following [result codes](../../../references/protocol/transactions/transaction-results/index.md), here are some things to check: