# Set Up an XRP-XRP Bridge

Setting up an XRP-XRP bridge enables you to move XRP between chains. The set up requires using the genesis account on the issuing chain as a door account to submit attestations and create transaction submission accounts for witnesses.

The code samples on this page illustrate how a bridge was set up between *Devnet* and *Sidechain-Devnet*, using a supported [client library](/docs/references/client-libraries) to query and submit transactions. This bridge is already created, so the process can't be reproduced on these networks.

XChainBridge
## Prerequisites

- The issuing chain is set up and active. Validators must be running and successfully closing ledgers.
- The witnesses' accounts on the locking chain are funded, so they can submit transactions.
- A door account for the bridge exists on the locking chain.


## Steps

### 1. Connect to the locking chain (Devnet) and issuing chain (Sidechain-Devnet).


```javascript
const xrpl = require('xrpl')

const WS_URL_lockingchain = 'wss://s.devnet.rippletest.net:51233/' // Locking chain
const WS_URL_issuingchain = 'wss://example-sidechain.net:12345/' // Issuing chain

// Define the XChainBridge
const xchainbridge = {
  "LockingChainDoor": "rnQAXXWoFNN6PEqwqsdTngCtFPCrmfuqFJ", // Locking chain door account
  "LockingChainIssue": {
    "currency": "XRP"
  },
  "IssuingChainDoor": "rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh", // Use the genesis address hardcoded in rippled
  "IssuingChainIssue": {
    "currency": "XRP"
  }
}

async function main() {
  // Define the network clients.
  const client_lockingchain = new xrpl.Client(WS_URL_lockingchain)
  await client_lockingchain.connect()

  const client_issuingchain = new xrpl.Client(WS_URL_issuingchain)
  await client_issuingchain.connect()

  // ... custom code goes here

  // Disconnect when done (If you omit this, Node.js won't end the process)
  await client_lockingchain.disconnect()
  await client_issuingchain.disconnect()
}

main()
```

### 2. Submit an `XChainCreateBridge` transaction from the door account on the locking chain.


```javascript
  const wallet_lockingchain = xrpl.Wallet.fromSeed('s████████████████████████████') // Locking chain door account
  const xchaincreatebridge_lockingchain = await client_lockingchain.submitAndWait({
    "TransactionType": "XChainCreateBridge",
    "Account": wallet_lockingchain.address,
    "XChainBridge": xchainbridge,
  "SignatureReward": 200,
  "MinAccountCreateAmount": 1000000 // This value should at least be equal to the account reserve on the issuing chain.
  }, {autofill: true, wallet: wallet_lockingchain})
```

### 3. Submit a `SignerListSet` transaction from the door account on the locking chain.


```javascript
  const signerlistset_lockingchain = await client_lockingchain.submitAndWait({
    "TransactionType": "SignerListSet",
    "Account": wallet_lockingchain.address,
    "Fee": "12",
    "SignerQuorum": 2,    
    // Use the witness servers' submitting accounts on the locking chain.
    "SignerEntries": [
        {
            "SignerEntry": {
                "Account": "rsA2LpzuawewSBQXkiju3YQTMzW13pAAdW",
                "SignerWeight": 1
            }
        },
        {
            "SignerEntry": {
                "Account": "rUpy3eEg8rqjqfUoLeBnZkscbKbFsKXC3v",
                "SignerWeight": 1
            }
        }
    ]
  }, {autofill: true, wallet: wallet_lockingchain})
```

### 4. Disable the master key on the locking chain's door account with an `AccountSet` transaction.


```javascript
const disablekey_lockingchain = await client_lockingchain.submitAndWait({
    "TransactionType": "AccountSet",
    "Account": wallet_lockingchain.address,
    "SetFlag": 4
  }, {autofill: true, wallet: wallet_lockingchain})
```

### 5. Submit an `XChainCreateBridge` transaction from the genesis account on the issuing chain.


```javascript
  const wallet_issuingchain = xrpl.Wallet.fromSeed('snoPBrXtMeMyMHUVTgbuqAfg1SUTb') // Use the genesis secret hardcoded in rippled.
  const xchaincreatebridge_issuingchain = await client_issuingchain.submitAndWait({
    "TransactionType": "XChainCreateBridge",
    "Account": wallet_issuingchain.address,
    "XChainBridge": xchainbridge,
  "SignatureReward": 200,
  "MinAccountCreateAmount": 1000000
  }, {autofill: true, wallet: wallet_issuingchain})
```

### 6. Submit `XChainAccountCreateCommit` transactions from the witnesses' locking chain accounts to create corresponding accounts on the issuing chain.


```javascript
  const wallet_witness_1 = xrpl.Wallet.fromSeed('s████████████████████████████') // Witness server 1 from `SignerListSet`: rsA2LpzuawewSBQXkiju3YQTMzW13pAAdW
  const wallet_witness_2 = xrpl.Wallet.fromSeed('s████████████████████████████') // Witness server 2 from `SignerListSet`: rUpy3eEg8rqjqfUoLeBnZkscbKbFsKXC3v

  const xchainaccountcreatecommit_witness_1 = await client_lockingchain.submitAndWait({
    "TransactionType": "XChainAccountCreateCommit",
    "Account": wallet_witness_1.address,
    "Destination": "rD323VyRjgzzhY4bFpo44rmyh2neB5d8Mo", // The account to create and fund for witness 1 on the issuing chain.
    "TransactionType": "XChainAccountCreateCommit",
    "Amount": "20000000",
    "SignatureReward": "100",
    "XChainBridge": xchainbridge
  }, {autofill: true, wallet: wallet_witness_1})

    const xchainaccountcreatecommit_witness_2 = await client_lockingchain.submitAndWait({
    "TransactionType": "XChainAccountCreateCommit",
    "Account": wallet_witness_2.address,
    "Destination": "rJMfWNVbyjcCtds8kpoEjEbYQ41J5B6MUd", // The account to create and fund for witness 2 on the issuing chain.
    "TransactionType": "XChainAccountCreateCommit",
    "Amount": "20000000",
    "SignatureReward": "100",
    "XChainBridge": xchainbridged
  }, {autofill: true, wallet: wallet_witness_1})
```

### 7. Submit attestations for each `XChainAccountCreateCommit` transaction.

Use the `XChainAddAccountCreateAttestation` transaction to submit each attestation on the issuing chain. Sign these transactions with the genesis account on the issuing chain.


```javascript
  // Witness 1 attestation
  const xchainaddaccountcreateattestation_witness_1 = await client_issuingchain.submitAndWait({
    "TransactionType": "XChainAddAccountCreateAttestation",
    "Account": wallet_issuingchain.address,
    "OtherChainSource": wallet_witness_1.address,
    "Destination": "rD323VyRjgzzhY4bFpo44rmyh2neB5d8Mo",
    "Amount": "2000000000",
    "PublicKey": wallet_witness_1.publicKey,
    "Signature": xchainaccountcreatecommit_witness_1.result.TxnSignature,
    "WasLockingChainSend": 1,
    "AttestationRewardAccount": "rD323VyRjgzzhY4bFpo44rmyh2neB5d8Mo",
    "AttestationSignerAccount": wallet_witness_1.address,
    "XChainAccountCreateCount": "1",
    "SignatureReward": "204",
    "XChainBridge": xchainbridge,
    "Fee": "20"
  }, {autofill: true, wallet: wallet_issuingchain})

  // Witness 2 attestation
    const xchainaddaccountcreateattestation_witness_2 = await client_issuingchain.submitAndWait({
    "TransactionType": "XChainAddAccountCreateAttestation",
    "Account": wallet_issuingchain.address,
    "OtherChainSource": wallet_witness_2.address,
    "Destination": "rJMfWNVbyjcCtds8kpoEjEbYQ41J5B6MUd",
    "Amount": "2000000000",
    "PublicKey": wallet_witness_2.publicKey,
    "Signature": xchainaccountcreatecommit_witness_2.result.TxnSignature,
    "WasLockingChainSend": 1,
    "AttestationRewardAccount": "rJMfWNVbyjcCtds8kpoEjEbYQ41J5B6MUd",
    "AttestationSignerAccount": wallet_witness_2.address,
    "XChainAccountCreateCount": "1",
    "SignatureReward": "204",
    "XChainBridge": xchainbridge,
    "Fee": "20"
  }, {autofill: true, wallet: wallet_issuingchain})
```

### 8. Submit a `SignerListSet` transaction from the genesis account on the issuing chain.


```javascript
  const signerlistset_issuingchain = await client_issuingchain.submitAndWait({
    "TransactionType": "SignerListSet",
    "Account": wallet_issuingchain.address,
    "Fee": "12",
    "SignerQuorum": 2,    
    // Use the witness servers' submitting accounts on the issuing chain created in step 7
    "SignerEntries": [
        {
            "SignerEntry": {
                "Account": "rD323VyRjgzzhY4bFpo44rmyh2neB5d8Mo",
                "SignerWeight": 1
            }
        },
        {
            "SignerEntry": {
                "Account": "rJMfWNVbyjcCtds8kpoEjEbYQ41J5B6MUd",
                "SignerWeight": 1
            }
        }
    ]
  }, {autofill: true, wallet: wallet_issuingchain})
```

### 9. Disable the master key on the issuing chain's genesis account with an `AccountSet` transaction.


```javascript
const disablekey_issuingchain = await client_issuingchain.submitAndWait({
    "TransactionType": "AccountSet",
    "Account": wallet_issuingchain.address,
    "SetFlag": 4
  }, {autofill: true, wallet: wallet_issuingchain})
```