mirror of
				https://github.com/XRPLF/xrpl-dev-portal.git
				synced 2025-11-04 11:55:50 +00:00 
			
		
		
		
	Compare commits
	
		
			1 Commits
		
	
	
		
			fdcbc6c747
			...
			payment-ch
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| 
						 | 
					36083f247a | 
@@ -12,13 +12,11 @@ import {
 | 
			
		||||
 | 
			
		||||
const client = new Client('wss://s.altnet.rippletest.net:51233')
 | 
			
		||||
 | 
			
		||||
void claimPayChannel()
 | 
			
		||||
 | 
			
		||||
// The snippet walks us through creating and claiming a Payment Channel.
 | 
			
		||||
async function claimPayChannel(): Promise<void> {
 | 
			
		||||
  await client.connect()
 | 
			
		||||
 | 
			
		||||
  // creating wallets as prerequisite
 | 
			
		||||
  // Creating wallets as prerequisite
 | 
			
		||||
  const { wallet: wallet1 } = await client.fundWallet()
 | 
			
		||||
  const { wallet: wallet2 } = await client.fundWallet()
 | 
			
		||||
 | 
			
		||||
@@ -26,16 +24,17 @@ async function claimPayChannel(): Promise<void> {
 | 
			
		||||
  console.log(`Balance of ${wallet1.address} is ${await client.getXrpBalance(wallet1.address)} XRP`)
 | 
			
		||||
  console.log(`Balance of ${wallet2.address} is ${await client.getXrpBalance(wallet2.address)} XRP`)
 | 
			
		||||
 | 
			
		||||
  // create a Payment Channel and submit and wait for tx to be validated
 | 
			
		||||
  // Create a Payment Channel transaction
 | 
			
		||||
  const paymentChannelCreate: PaymentChannelCreate = {
 | 
			
		||||
    TransactionType: 'PaymentChannelCreate',
 | 
			
		||||
    Account: wallet1.classicAddress,
 | 
			
		||||
    Amount: '100',
 | 
			
		||||
    Amount: '3000000',  // 3 XRP in drops
 | 
			
		||||
    Destination: wallet2.classicAddress,
 | 
			
		||||
    SettleDelay: 86400,
 | 
			
		||||
    SettleDelay: 86400, // 1 day in seconds
 | 
			
		||||
    PublicKey: wallet1.publicKey,
 | 
			
		||||
  }
 | 
			
		||||
  
 | 
			
		||||
 | 
			
		||||
  // Submit and wait for the transaction to be validated
 | 
			
		||||
  console.log("Submitting a PaymentChannelCreate transaction...")
 | 
			
		||||
  const paymentChannelResponse = await client.submitAndWait(
 | 
			
		||||
    paymentChannelCreate,
 | 
			
		||||
@@ -44,7 +43,7 @@ async function claimPayChannel(): Promise<void> {
 | 
			
		||||
  console.log("PaymentChannelCreate transaction response:")
 | 
			
		||||
  console.log(paymentChannelResponse)
 | 
			
		||||
 | 
			
		||||
  // check that the object was actually created
 | 
			
		||||
  // Check that the object was actually created
 | 
			
		||||
  const accountObjectsRequest: AccountObjectsRequest = {
 | 
			
		||||
    command: 'account_objects',
 | 
			
		||||
    account: wallet1.classicAddress,
 | 
			
		||||
@@ -55,14 +54,14 @@ async function claimPayChannel(): Promise<void> {
 | 
			
		||||
 | 
			
		||||
  console.log("Account Objects:", accountObjects)
 | 
			
		||||
 | 
			
		||||
  // destination claims the Payment Channel and we see the balances to verify.
 | 
			
		||||
  // Destination claims the Payment Channel and we see the balances to verify.
 | 
			
		||||
  const paymentChannelClaim: PaymentChannelClaim = {
 | 
			
		||||
    Account: wallet2.classicAddress,
 | 
			
		||||
    TransactionType: 'PaymentChannelClaim',
 | 
			
		||||
    Channel: hashes.hashPaymentChannel(
 | 
			
		||||
      wallet1.classicAddress,
 | 
			
		||||
      wallet2.classicAddress,
 | 
			
		||||
      paymentChannelResponse.result.Sequence ?? 0,
 | 
			
		||||
      paymentChannelResponse.result.tx_json.Sequence ?? 0,
 | 
			
		||||
    ),
 | 
			
		||||
    Amount: '100',
 | 
			
		||||
  }
 | 
			
		||||
@@ -70,7 +69,7 @@ async function claimPayChannel(): Promise<void> {
 | 
			
		||||
  console.log("Submitting a PaymentChannelClaim transaction...")
 | 
			
		||||
 | 
			
		||||
  const channelClaimResponse = await client.submit(paymentChannelClaim, {
 | 
			
		||||
    wallet: wallet1,
 | 
			
		||||
    wallet: wallet2,
 | 
			
		||||
  })
 | 
			
		||||
  console.log("PaymentChannelClaim transaction response:")
 | 
			
		||||
  console.log(channelClaimResponse)
 | 
			
		||||
@@ -81,3 +80,5 @@ async function claimPayChannel(): Promise<void> {
 | 
			
		||||
 | 
			
		||||
  await client.disconnect()
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void claimPayChannel()
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										97
									
								
								_code-samples/claim-payment-channel/py/claim_pay_channel.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										97
									
								
								_code-samples/claim-payment-channel/py/claim_pay_channel.py
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,97 @@
 | 
			
		||||
"""
 | 
			
		||||
Create, claim and verify a Payment Channel.
 | 
			
		||||
Reference: https://xrpl.org/paychannel.html 
 | 
			
		||||
"""
 | 
			
		||||
from xrpl.clients import JsonRpcClient
 | 
			
		||||
from xrpl.models import (
 | 
			
		||||
    AccountObjects,
 | 
			
		||||
    PaymentChannelCreate,
 | 
			
		||||
    PaymentChannelClaim,
 | 
			
		||||
)
 | 
			
		||||
from xrpl.wallet import generate_faucet_wallet
 | 
			
		||||
from xrpl.transaction import submit_and_wait, submit
 | 
			
		||||
from xrpl.account import get_balance
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def claim_pay_channel():
 | 
			
		||||
    """The snippet walks us through creating and claiming a Payment Channel."""
 | 
			
		||||
    
 | 
			
		||||
    client = JsonRpcClient("https://s.altnet.rippletest.net:51234")
 | 
			
		||||
    
 | 
			
		||||
    try:
 | 
			
		||||
        # Creating wallets as prerequisite
 | 
			
		||||
        print("Creating and funding wallets...")
 | 
			
		||||
        wallet1 = generate_faucet_wallet(client, debug=True)
 | 
			
		||||
        wallet2 = generate_faucet_wallet(client, debug=True)
 | 
			
		||||
        
 | 
			
		||||
        print("Balances of wallets before Payment Channel is claimed:")
 | 
			
		||||
        balance1 = get_balance(wallet1.address, client)
 | 
			
		||||
        balance2 = get_balance(wallet2.address, client)
 | 
			
		||||
        print(f"Balance of {wallet1.address} is {balance1} XRP")
 | 
			
		||||
        print(f"Balance of {wallet2.address} is {balance2} XRP")
 | 
			
		||||
        
 | 
			
		||||
        # Create a Payment Channel transaction
 | 
			
		||||
        payment_channel_create = PaymentChannelCreate(
 | 
			
		||||
            account=wallet1.address,
 | 
			
		||||
            amount="3000000",  # 3 XRP in drops
 | 
			
		||||
            destination=wallet2.address,
 | 
			
		||||
            settle_delay=86400,
 | 
			
		||||
            public_key=wallet1.public_key,
 | 
			
		||||
        )
 | 
			
		||||
        
 | 
			
		||||
        # Submit and wait for the transaction to be validated
 | 
			
		||||
        print("Submitting a PaymentChannelCreate transaction...")
 | 
			
		||||
        payment_channel_response = submit_and_wait(
 | 
			
		||||
            payment_channel_create, 
 | 
			
		||||
            client, 
 | 
			
		||||
            wallet1
 | 
			
		||||
        )
 | 
			
		||||
        print("PaymentChannelCreate transaction response:")
 | 
			
		||||
        print(payment_channel_response)
 | 
			
		||||
 | 
			
		||||
        # Check that the object was actually created and get the channel ID
 | 
			
		||||
        account_objects_request = AccountObjects(
 | 
			
		||||
            account=wallet1.address,
 | 
			
		||||
        )
 | 
			
		||||
        account_objects_response = client.request(account_objects_request)
 | 
			
		||||
        account_objects = account_objects_response.result["account_objects"]
 | 
			
		||||
        
 | 
			
		||||
        # Find the payment channel from account objects and get its ID
 | 
			
		||||
        channel_id = None
 | 
			
		||||
        for obj in account_objects:
 | 
			
		||||
            if obj.get("LedgerEntryType") == "PayChannel":
 | 
			
		||||
                channel_id = obj["index"]
 | 
			
		||||
                break
 | 
			
		||||
        
 | 
			
		||||
        if not channel_id:
 | 
			
		||||
            raise Exception("Could not find PayChannel in account objects")
 | 
			
		||||
            
 | 
			
		||||
        print(f"Payment Channel ID: {channel_id}")
 | 
			
		||||
        
 | 
			
		||||
        # Destination claims the Payment Channel
 | 
			
		||||
        payment_channel_claim = PaymentChannelClaim(
 | 
			
		||||
            account=wallet2.address,
 | 
			
		||||
            channel=channel_id,
 | 
			
		||||
            amount="100",
 | 
			
		||||
            sequence=payment_channel_response.result["tx_json"]["Sequence"],
 | 
			
		||||
            fee="12",  # Fee in drops (0.000012 XRP)
 | 
			
		||||
        )
 | 
			
		||||
 | 
			
		||||
        print("Submitting a PaymentChannelClaim transaction...")
 | 
			
		||||
        channel_claim_response = submit(
 | 
			
		||||
            payment_channel_claim, 
 | 
			
		||||
            wallet2,
 | 
			
		||||
        )
 | 
			
		||||
        print("PaymentChannelClaim transaction response:")
 | 
			
		||||
        print(channel_claim_response)
 | 
			
		||||
        
 | 
			
		||||
        print("Balances of wallets after Payment Channel is claimed:")
 | 
			
		||||
        print(f"Balance of {wallet1.address} is {get_balance(wallet1.address, client)} XRP")
 | 
			
		||||
        print(f"Balance of {wallet2.address} is {get_balance(wallet2.address, client)} XRP")
 | 
			
		||||
        
 | 
			
		||||
    except Exception as e:
 | 
			
		||||
        print(f"An error occurred: {e}")
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
if __name__ == "__main__":
 | 
			
		||||
    claim_pay_channel()
 | 
			
		||||
							
								
								
									
										1
									
								
								_code-samples/claim-payment-channel/py/requirements.txt
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								_code-samples/claim-payment-channel/py/requirements.txt
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1 @@
 | 
			
		||||
xrpl-py>=2.0.0
 | 
			
		||||
@@ -0,0 +1,136 @@
 | 
			
		||||
---
 | 
			
		||||
seo:
 | 
			
		||||
    description: Learn how to create and claim a payment channel using the XRP Ledger SDKs.
 | 
			
		||||
cta_text: Create and Claim a Payment Channel with the XRPL SDKs
 | 
			
		||||
labels:
 | 
			
		||||
  - Payment Channels
 | 
			
		||||
---
 | 
			
		||||
# Create and Claim a Payment Channel with the SDK Libraries
 | 
			
		||||
 | 
			
		||||
This tutorial explains how to create, verify, and claim a payment channel using `xrpl.js` for JavaScript, and `xrpl-py` for Python.
 | 
			
		||||
 | 
			
		||||
{% admonition type="success" name="Tip" %}Check out the [Code Samples](https://github.com/XRPLF/xrpl-dev-portal/tree/master/_code-samples/claim-payment-channel) for a complete version of the code used in this tutorial.{% /admonition %}
 | 
			
		||||
 | 
			
		||||
## Prerequisites
 | 
			
		||||
 | 
			
		||||
<!-- Source for this specific tutorial's interactive bits: -->
 | 
			
		||||
<!-- <script type="application/javascript" src="/js/interactive-tutorial.js"></script> -->
 | 
			
		||||
<!-- <script type="application/javascript" src="/js/tutorials/send-xrp.js"></script> -->
 | 
			
		||||
 | 
			
		||||
To interact with the XRP Ledger, you need to set up a dev environment with the necessary tools. This tutorial provides examples using the following options:
 | 
			
		||||
 | 
			
		||||
- **JavaScript** with the [`xrpl.js` library](https://github.com/XRPLF/xrpl.js/). See [Get Started Using JavaScript](../../../javascript/build-apps/get-started.md) for setup steps.
 | 
			
		||||
- **Python** with the [`xrpl-py` library](https://xrpl-py.readthedocs.io/). See [Get Started using Python](../../../python/build-apps/get-started.md) for setup steps.
 | 
			
		||||
 | 
			
		||||
## 1. Connect to a Testnet Server
 | 
			
		||||
 | 
			
		||||
First, you must connect to an XRP Ledger server. The following code initializes the XRP Ledger client and connects to a public Testnet server:
 | 
			
		||||
 | 
			
		||||
{% tabs %}
 | 
			
		||||
 | 
			
		||||
{% tab label="JavaScript" %}
 | 
			
		||||
{% code-snippet file="/_code-samples/claim-payment-channel/js/claimPayChannel.ts" from="import" before="// Creating wallets" language="js" /%}
 | 
			
		||||
{% /tab %}
 | 
			
		||||
 | 
			
		||||
{% tab label="Python" %}
 | 
			
		||||
{% code-snippet file="/_code-samples/claim-payment-channel/py/claim_pay_channel.py" from="xrpl.clients" before="try:" language="py" /%}
 | 
			
		||||
{% /tab %}
 | 
			
		||||
 | 
			
		||||
{% /tabs %}
 | 
			
		||||
 | 
			
		||||
<!-- For this tutorial, click the following button to connect:
 | 
			
		||||
 | 
			
		||||
{% partial file="/docs/_snippets/interactive-tutorials/connect-step.md" /%} -->
 | 
			
		||||
 | 
			
		||||
## 2. Create Testnet Wallets
 | 
			
		||||
 | 
			
		||||
Create two Testnet wallets and log their initial XRP balances:
 | 
			
		||||
 | 
			
		||||
{% tabs %}
 | 
			
		||||
 | 
			
		||||
{% tab label="JavaScript" %}
 | 
			
		||||
{% code-snippet file="/_code-samples/claim-payment-channel/js/claimPayChannel.ts" from="// Creating wallets" before="// Create a Payment Channel" language="js" /%}
 | 
			
		||||
{% /tab %}
 | 
			
		||||
 | 
			
		||||
{% /tabs %}
 | 
			
		||||
 | 
			
		||||
For this example, `wallet1` represents the _payer_, and `wallet2` is the _payee_.
 | 
			
		||||
 | 
			
		||||
The payer can be an individual person or institution using the XRP Ledger who is a customer of the payee. The payee is a person or business who receives XRP or fungible tokens as payment for goods or services.
 | 
			
		||||
 | 
			
		||||
## 3. Create and Submit the Payment Channel Transaction
 | 
			
		||||
 | 
			
		||||
Next, prepare the [`PaymentChannelCreate`](../../../../references/protocol/transactions/types/paymentchannelcreate) transaction.
 | 
			
		||||
 | 
			
		||||
{% tabs %}
 | 
			
		||||
 | 
			
		||||
{% tab label="JavaScript" %}
 | 
			
		||||
{% code-snippet file="/_code-samples/claim-payment-channel/js/claimPayChannel.ts" from="// Create a Payment Channel" before="// Submit and wait for the transaction" language="js" /%}
 | 
			
		||||
{% /tab %}
 | 
			
		||||
 | 
			
		||||
{% /tabs %}
 | 
			
		||||
 | 
			
		||||
The key fields in this transaction are:
 | 
			
		||||
 | 
			
		||||
| Field                   | Description |
 | 
			
		||||
| :---------------------- | :---------- |
 | 
			
		||||
| `TransactionType`       | The type of transaction to be submitted (i.e., `PaymentChannelCreate`). |
 | 
			
		||||
| `Account`               | The _payer_ (source) address of the transaction, which in this example is `wallet1`. |
 | 
			
		||||
| `Amount`                | The amount of XRP, in drops, to deduct from the sender's balance and set aside in the payment channel. For this example, we are setting this to 3 XRP. |
 | 
			
		||||
| `SettleDelay`           | The amount of time the source address must wait before closing the channel if it has unclaimed XRP. This is set to 1 day (in seconds). |
 | 
			
		||||
| `PublicKey`             | The public key of the key pair used to sign claims against the payment channel. |
 | 
			
		||||
| `Destination`           | The _payee_ (destination) address to receive claims against this channel, which in this example is `wallet2`. |
 | 
			
		||||
 | 
			
		||||
Submit and wait for the transaction to be validated on the ledger:
 | 
			
		||||
 | 
			
		||||
{% tabs %}
 | 
			
		||||
 | 
			
		||||
{% tab label="JavaScript" %}
 | 
			
		||||
{% code-snippet file="/_code-samples/claim-payment-channel/js/claimPayChannel.ts" from="// Submit and wait for the transaction" before="// Check that the object " language="js" /%}
 | 
			
		||||
{% /tab %}
 | 
			
		||||
 | 
			
		||||
{% /tabs %}
 | 
			
		||||
 | 
			
		||||
## 4. Verify the Payment Channel is Created
 | 
			
		||||
 | 
			
		||||
{% tabs %}
 | 
			
		||||
 | 
			
		||||
{% tab label="JavaScript" %}
 | 
			
		||||
{% code-snippet file="/_code-samples/claim-payment-channel/js/claimPayChannel.ts" from="// Check that the object" before="// Destination claims" language="js" /%}
 | 
			
		||||
{% /tab %}
 | 
			
		||||
 | 
			
		||||
{% /tabs %}
 | 
			
		||||
 | 
			
		||||
## 5. Claim the Payment Channel
 | 
			
		||||
 | 
			
		||||
Create a `PaymentChannelClaim` transaction:
 | 
			
		||||
 | 
			
		||||
{% tabs %}
 | 
			
		||||
 | 
			
		||||
{% tab label="JavaScript" %}
 | 
			
		||||
{% code-snippet file="/_code-samples/claim-payment-channel/js/claimPayChannel.ts" from="// Destination claims" before="" language="js" /%}
 | 
			
		||||
{% /tab %}
 | 
			
		||||
 | 
			
		||||
{% /tabs %}
 | 
			
		||||
 | 
			
		||||
Submit and wait for the transaction to be validated:
 | 
			
		||||
 | 
			
		||||
{% tabs %}
 | 
			
		||||
 | 
			
		||||
{% tab label="JavaScript" %}
 | 
			
		||||
{% code-snippet file="/_code-samples/claim-payment-channel/js/claimPayChannel.ts" from="console.log(\"Submitting" before="console.log('Balances" language="js" /%}
 | 
			
		||||
{% /tab %}
 | 
			
		||||
 | 
			
		||||
{% /tabs %}
 | 
			
		||||
 | 
			
		||||
## 6. Check Balances after Payment Channel is Claimed
 | 
			
		||||
 | 
			
		||||
Finally, we check the balance of both `wallet1` and `wallet2`, after the claiming the payment channel. Then, we close the client connection.
 | 
			
		||||
 | 
			
		||||
{% tabs %}
 | 
			
		||||
 | 
			
		||||
{% tab label="JavaScript" %}
 | 
			
		||||
{% code-snippet file="/_code-samples/claim-payment-channel/js/claimPayChannel.ts" from="console.log('Balances" language="js" /%}
 | 
			
		||||
{% /tab %}
 | 
			
		||||
 | 
			
		||||
{% /tabs %}
 | 
			
		||||
@@ -84,7 +84,7 @@ Content-Type: application/json
 | 
			
		||||
        "fee_mult_max": 1000
 | 
			
		||||
    }]
 | 
			
		||||
}
 | 
			
		||||
```json
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
Response:
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -299,6 +299,7 @@
 | 
			
		||||
                  expanded: false
 | 
			
		||||
                  items:
 | 
			
		||||
                    - page: docs/tutorials/how-tos/use-specialized-payment-types/use-payment-channels/open-a-payment-channel-to-enable-an-inter-exchange-network.md
 | 
			
		||||
                    - page: docs/tutorials/how-tos/use-specialized-payment-types/use-payment-channels/create-and-claim-payment-channel.md
 | 
			
		||||
                - page: docs/tutorials/how-tos/use-specialized-payment-types/use-checks/index.md
 | 
			
		||||
                  expanded: false
 | 
			
		||||
                  items:
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user