# Create Trust Line and Send Currency Using Python

This example shows how to:

1. Configure accounts to allow transfer of funds to third party accounts.
2. Set a currency type for transactions.
3. Create a trust line between the standby account and the operational account.
4. Send issued currency between accounts.
5. Display account balances for all currencies.


[![Test harness with currency transfer](/assets/quickstart-py5.c53644e815df1dcaa773afc307604652e40cf2973b9034b9386d20deaaf863b3.ac57e6ef.png)](/assets/quickstart-py5.c53644e815df1dcaa773afc307604652e40cf2973b9034b9386d20deaaf863b3.ac57e6ef.png)

You can download the [Quickstart Samples](https://github.com/XRPLF/xrpl-dev-portal/tree/master/_code-samples/quickstart/py/) archive to try each of the samples in your own browser.

Without the Quickstart Samples, you will not be able to try the examples that follow. 

## Usage

Open the Quickstart window and get accounts:

1. Open and run `lesson2-send-currency.py`.
2. Get test accounts.
  1. If you have existing account seeds
    1. Paste account seeds in the **Seeds** field.
    2. Click **Get Accounts from Seeds**.
  2. If you do not have account seeds:
    1. Click **Get New Standby Account**.
    2. Click **Get New Operational Account**.


## Create Trust Line

div
iframe
To create a trust line between accounts:

1. Enter a [currency code](https://www.iban.com/currency-codes) in the **Currency** field.
2. Enter the maximum transfer limit in the **Amount** field.
3. Enter the destination account value in the **Destination** field.
4. Click **Create Trust Line**.


[![Trust line results](/assets/quickstart-py6.fa3916acaff8debb7efb08c7466b80c260a342c1edc4f45751534e39f91d0f51.ac57e6ef.png)](/assets/quickstart-py6.fa3916acaff8debb7efb08c7466b80c260a342c1edc4f45751534e39f91d0f51.ac57e6ef.png)

## Send an Issued Currency Token

To transfer an issued currency token, once you have created a trust line:

1. Enter the **Amount**.
2. Enter the **Destination**.
3. Enter the **Currency** type.
4. Click **Send Currency**.


[![Currency transfer](/assets/quickstart-py7.85095e069dadfce2d39909f9ba431d16f91f2a98f54980fd78551e6ea100edbd.ac57e6ef.png)](/assets/quickstart-py7.85095e069dadfce2d39909f9ba431d16f91f2a98f54980fd78551e6ea100edbd.ac57e6ef.png)

### Configure Account

When transferring fiat currency, the actual transfer of funds is not simultaneous, as it is with XRP. If currency is transferred to a third party for a different currency, there can be a devaluation of the currency that impacts the originating account. To avoid this situation, this up and down valuation of currency, known as *rippling*, is not allowed by default. Currency transferred from one account can only be transferred back to the same account. To enable currency transfer to third parties, you need to set the `rippleDefault` value to true. The Token Test Harness provides a checkbox to enable or disable rippling.

To enable rippling:

1. Select the **Allow Rippling** checkbox.
2. Click **Configure Account**.


Verify the setting by looking for the *Set Flag* value in the response, which should show a flag setting of *8*.

[![Configure Account - Enable Rippling](/assets/quickstart-py8.4bc64ed0f56016fd65e328a1c90576183ee2b3bdae896d1c43a8e7fa0fde7f6f.ac57e6ef.png)](/assets/quickstart-py8.4bc64ed0f56016fd65e328a1c90576183ee2b3bdae896d1c43a8e7fa0fde7f6f.ac57e6ef.png)

To disable rippling:

1. Deselect the **Allow Rippling** checkbox.
2. Click **Configure Account**.


Verify the setting by looking for the *Clear Flag* value in the response, which shold show a flag setting of *8*.

[![Configure Account - Disable Rippling](/assets/quickstart-py9.da94bb1ad390bec3a0c897b2f7217295c185f6f464ae548e7277cbf21a8547a1.ac57e6ef.png)](/assets/quickstart-py9.da94bb1ad390bec3a0c897b2f7217295c185f6f464ae548e7277cbf21a8547a1.ac57e6ef.png)

# Code Walkthrough

You can download the [Quickstart Samples](https://github.com/XRPLF/xrpl-dev-portal/tree/master/_code-samples/quickstart/py/) archive to try each of the samples.

## mod2.py

Module 2 provides the logic for creating trust lines and sending issued currency tokens between accounts.

Import dependencies and set the `testnet_url`.


```python
import xrpl
from xrpl.clients import JsonRpcClient
from xrpl.wallet import Wallet

testnet_url = "https://s.altnet.rippletest.net:51234"
```

### Create Trust Line

Pass the wallet seed, the issuer account, the currency code, and the maximum amount of currency to send.


```python
def create_trust_line(seed, issuer, currency, amount):
    """create_trust_line"""
```

Get the wallet and a new client instance.


```python
    receiving_wallet = Wallet.from_seed(seed)
    client = JsonRpcClient(testnet_url)
```

Define the `TrustSet` transaction.


```python
    trustline_tx=xrpl.models.transactions.TrustSet(
        account=receiving_wallet.address,
        limit_amount=xrpl.models.amounts.IssuedCurrencyAmount(
            currency=currency,
            issuer=issuer,
            value=int(amount)
        )
    )
```

Submit the transaction to the XRP Ledger.


```python
    response =  xrpl.transaction.submit_and_wait(trustline_tx,
        client, receiving_wallet)
```

Return the results.


```python
    return response.result
```

## send_currency

Send currency to another account based on the sender wallet, destination account, the currency type, and the amount of the currency.


```python
def send_currency(seed, destination, currency, amount):
    """send_currency"""
```

Get the sending wallet and a client instance on Testnet.


```python
    sending_wallet=Wallet.from_seed(seed)
    client=JsonRpcClient(testnet_url)
```

Define the payment transaction. The amount requires further description to identify the type of currency and issuer.


```python
    send_currency_tx=xrpl.models.transactions.Payment(
        account=sending_wallet.address,
        amount=xrpl.models.amounts.IssuedCurrencyAmount(
            currency=currency,
            value=int(amount),
            issuer=sending_wallet.address
        ),
        destination=destination
    )
```

Submit the transaction and get the response.


```python
    response=xrpl.transaction.submit_and_wait(send_currency_tx, client, sending_wallet)```

Return the results.

```python
    return response.result
```

### get_balance

Update the **XRP Balance** fields and list the balance information for issued currencies in the **Results** text areas.


```python
def get_balance(sb_account_id, op_account_id):
    """get_balance"""
```

Connect to the XRP Ledger and instantiate a client.


```python
    client=JsonRpcClient(testnet_url)
```

Create the `GatewayBalances` request.


```python
    balance=xrpl.models.requests.GatewayBalances(
        account=sb_account_id,
        ledger_index="validated",
        hotwallet=[op_account_id]
    )
```

Return the result.


```python
    response = client.request(balance)
    return response.result
```

### configure_account

This example shows how to set and clear configuration flags using the `AccountSet` method. The `ASF_DEFAULT_RIPPLE` flag is pertinent to experimentation with transfer of issued currencies to third-party accounts, so it is demonstrated here. You can set any of the configuration flags using the same structure, substituting the particular flags you want to set. See [AccountSet Flags](/ja/docs/references/protocol/transactions/types/accountset#accountset-flags).

Send the account seed and a Boolean value for whether to enable or disable rippling.


```python
def configure_account(seed, default_setting):
    """configure_account"
```

Get the account wallet and instantiate a client.


```python
    wallet=Wallet.from_seed(seed)
    client=JsonRpcClient(testnet_url)
```

If  `default_setting` is true, create a `set_flag` transaction to enable rippling. If false, create a `clear_flag` transaction to disable rippling.


```python
    if (default_setting):
        setting_tx=xrpl.models.transactions.AccountSet(
            account=wallet.classic_address,
            set_flag=xrpl.models.transactions.AccountSetAsfFlag.ASF_DEFAULT_RIPPLE
        )
    else:
        setting_tx=xrpl.models.transactions.AccountSet(
            account=wallet.classic_address,
            set_flag=xrpl.models.transactions.AccountSetAsfFlag.ASF_DEFAULT_RIPPLE
        )
```

Submit the transaction and get results.


```python
    response=xrpl.transaction.submit_and_wait(setting_tx,client,wallet)
    return response.result
```

## lesson2-send-currency.py

This module builds on `lesson1-send-xrp.py`. Changes are noted below.


```python
import tkinter as tk
import xrpl
import json
```

Import methods from `mod2.py`.


```python
from mod1 import get_account, get_account_info, send_xrp
from mod2 import (
    create_trust_line,
    send_currency,
    get_balance,
    configure_account,
)
```

Module 2 Handlers.


```python
def standby_create_trust_line():
    results = create_trust_line(ent_standby_seed.get(),
        ent_standby_destination.get(),
        ent_standby_currency.get(),
        ent_standby_amount.get())
    text_standby_results.delete("1.0", tk.END)
    text_standby_results.insert("1.0", json.dumps(results, indent=4))


def standby_send_currency():
    results = send_currency(ent_standby_seed.get(),
        ent_standby_destination.get(),
        ent_standby_currency.get(),
        ent_standby_amount.get())
    text_standby_results.delete("1.0", tk.END)
    text_standby_results.insert("1.0", json.dumps(results, indent=4))


def standby_configure_account():
    results = configure_account(
        ent_standby_seed.get(),
        standbyRippling)
    text_standby_results.delete("1.0", tk.END)
    text_standby_results.insert("1.0", json.dumps(results, indent=4))


def operational_create_trust_line():
    results = create_trust_line(ent_operational_seed.get(),
        ent_operational_destination.get(),
        ent_operational_currency.get(),
        ent_operational_amount.get())
    text_operational_results.delete("1.0", tk.END)
    text_operational_results.insert("1.0", json.dumps(results, indent=4))


def operational_send_currency():
    results = send_currency(ent_operational_seed.get(),
        ent_operational_destination.get(),
        ent_operational_currency.get(),
        ent_operational_amount.get())
    text_operational_results.delete("1.0", tk.END)
    text_operational_results.insert("1.0", json.dumps(results, indent=4))


def operational_configure_account():
    results = configure_account(
        ent_operational_seed.get(),
        operationalRippling)
    text_operational_results.delete("1.0", tk.END)
    text_operational_results.insert("1.0", json.dumps(results, indent=4))


def get_balances():
    results = get_balance(ent_operational_account.get(), ent_standby_account.get())
    text_standby_results.delete("1.0", tk.END)
    text_standby_results.insert("1.0", json.dumps(results, indent=4))
    results = get_balance(ent_standby_account.get(), ent_operational_account.get())
    text_operational_results.delete("1.0", tk.END)
    text_operational_results.insert("1.0", json.dumps(results, indent=4))


# Module 1 Handlers
def get_standby_account():
    new_wallet = get_account(ent_standby_seed.get())
    ent_standby_account.delete(0, tk.END)
    ent_standby_seed.delete(0, tk.END)
    ent_standby_account.insert(0, new_wallet.classic_address)
    ent_standby_seed.insert(0, new_wallet.seed)


def get_standby_account_info():
    accountInfo = get_account_info(ent_standby_account.get())
    ent_standby_balance.delete(0, tk.END)
    ent_standby_balance.insert(0,accountInfo['Balance'])
    text_standby_results.delete("1.0", tk.END)
    text_standby_results.insert("1.0",json.dumps(accountInfo, indent=4))


def standby_send_xrp():
    response = send_xrp(ent_standby_seed.get(),ent_standby_amount.get(),
                       ent_standby_destination.get())
    text_standby_results.delete("1.0", tk.END)
    text_standby_results.insert("1.0",json.dumps(response.result, indent=4))
    get_standby_account_info()
    get_operational_account_info()


def get_operational_account():
    new_wallet = get_account(ent_operational_seed.get())
    ent_operational_account.delete(0, tk.END)
    ent_operational_account.insert(0, new_wallet.classic_address)
    ent_operational_seed.delete(0, tk.END)
    ent_operational_seed.insert(0, new_wallet.seed)


def get_operational_account_info():
    accountInfo = get_account_info(ent_operational_account.get())
    ent_operational_balance.delete(0, tk.END)
    ent_operational_balance.insert(0,accountInfo['Balance'])
    text_operational_results.delete("1.0", tk.END)
    text_operational_results.insert("1.0",json.dumps(accountInfo, indent=4))


def operational_send_xrp():
    response = send_xrp(ent_operational_seed.get(),ent_operational_amount.get(), ent_operational_destination.get())
    text_operational_results.delete("1.0", tk.END)
    text_operational_results.insert("1.0",json.dumps(response.result,indent=4))
    get_standby_account_info()
    get_operational_account_info()

# Create a new window with the title "Quickstart Module 2"

window = tk.Tk()
window.title("Quickstart Module 2")


standbyRippling = tk.BooleanVar()
operationalRippling = tk.BooleanVar()


# Form frame
frm_form = tk.Frame(relief=tk.SUNKEN, borderwidth=3)
frm_form.pack()

# Create the Label and Entry widgets for "Standby Account"
lbl_standy_seed = tk.Label(master=frm_form, text="Standby Seed")
ent_standby_seed = tk.Entry(master=frm_form, width=50)
lbl_standby_account = tk.Label(master=frm_form, text="Standby Account")
ent_standby_account = tk.Entry(master=frm_form, width=50)
lbl_standy_amount = tk.Label(master=frm_form, text="Amount")
ent_standby_amount = tk.Entry(master=frm_form, width=50)
lbl_standby_destination = tk.Label(master=frm_form, text="Destination")
ent_standby_destination = tk.Entry(master=frm_form, width=50)
lbl_standby_balance = tk.Label(master=frm_form, text="XRP Balance")
ent_standby_balance = tk.Entry(master=frm_form, width=50)
```

Add **Currency** field.


```python
lbl_standby_currency = tk.Label(master=frm_form, text="Currency")
ent_standby_currency = tk.Entry(master=frm_form, width=50)
```

Add checkbox to **Allow Rippling**.


```python
cb_standby_allow_rippling = tk.Checkbutton(master=frm_form, text="Allow Rippling", variable=standbyRippling, onvalue=True, offvalue=False)
lbl_standby_results = tk.Label(master=frm_form,text='Results')
text_standby_results = tk.Text(master=frm_form, height = 20, width = 65)

# Place field in a grid.
lbl_standy_seed.grid(row=0, column=0, sticky="w")
ent_standby_seed.grid(row=0, column=1)
lbl_standby_account.grid(row=2, column=0, sticky="e")
ent_standby_account.grid(row=2, column=1)
lbl_standy_amount.grid(row=3, column=0, sticky="e")
ent_standby_amount.grid(row=3, column=1)
lbl_standby_destination.grid(row=4, column=0, sticky="e")
ent_standby_destination.grid(row=4, column=1)
lbl_standby_balance.grid(row=5, column=0, sticky="e")
ent_standby_balance.grid(row=5, column=1)
```

Place new UI elements.


```python
lbl_standby_currency.grid(row=6, column=0, sticky="e")
ent_standby_currency.grid(row=6, column=1)
cb_standby_allow_rippling.grid(row=7,column=1, sticky="w")
lbl_standby_results.grid(row=8, column=0, sticky="ne")
text_standby_results.grid(row=8, column=1, sticky="nw")
cb_standby_allow_rippling.select()

###############################################
## Operational Account ########################
###############################################

# Create the Label and Entry widgets for "Operational Account"
lbl_operational_seed = tk.Label(master=frm_form, text="Operational Seed")
ent_operational_seed = tk.Entry(master=frm_form, width=50)
lbl_operational_account = tk.Label(master=frm_form, text="Operational Account")
ent_operational_account = tk.Entry(master=frm_form, width=50)
lbl_operational_amount = tk.Label(master=frm_form, text="Amount")
ent_operational_amount = tk.Entry(master=frm_form, width=50)
lbl_operational_destination = tk.Label(master=frm_form, text="Destination")
ent_operational_destination = tk.Entry(master=frm_form, width=50)
lbl_operational_balance = tk.Label(master=frm_form, text="XRP Balance")
ent_operational_balance = tk.Entry(master=frm_form, width=50)
```

Add field for **Currency** and checkbox to **Allow Rippling**.


```python
lbl_operational_currency = tk.Label(master=frm_form, text="Currency")
ent_operational_currency = tk.Entry(master=frm_form, width=50)
cb_operational_allow_rippling = tk.Checkbutton(master=frm_form, text="Allow Rippling", variable=operationalRippling, onvalue=True, offvalue=False)
lbl_operational_results = tk.Label(master=frm_form,text='Results')
text_operational_results = tk.Text(master=frm_form, height = 20, width = 65)

#Place the widgets in a grid
lbl_operational_seed.grid(row=0, column=4, sticky="e")
ent_operational_seed.grid(row=0, column=5, sticky="w")
lbl_operational_account.grid(row=2,column=4, sticky="e")
ent_operational_account.grid(row=2,column=5, sticky="w")
lbl_operational_amount.grid(row=3, column=4, sticky="e")
ent_operational_amount.grid(row=3, column=5, sticky="w")
lbl_operational_destination.grid(row=4, column=4, sticky="e")
ent_operational_destination.grid(row=4, column=5, sticky="w")
lbl_operational_balance.grid(row=5, column=4, sticky="e")
ent_operational_balance.grid(row=5, column=5, sticky="w")
```

Add elements to the UI.


```python
lbl_operational_currency.grid(row=6, column=4, sticky="e")
ent_operational_currency.grid(row=6, column=5)
cb_operational_allow_rippling.grid(row=7,column=5, sticky="w")
lbl_operational_results.grid(row=8, column=4, sticky="ne")
text_operational_results.grid(row=8, column=5, sticky="nw")
cb_operational_allow_rippling.select()
```

Create the Standby Account Buttons.


```python
btn_get_standby_account = tk.Button(master=frm_form, text="Get Standby Account",
                                    command = get_standby_account)
btn_get_standby_account.grid(row=0, column=2, sticky = "nsew")
btn_get_standby_account_info = tk.Button(master=frm_form,
                                         text="Get Standby Account Info",
                                         command = get_standby_account_info)
btn_get_standby_account_info.grid(row=1, column=2, sticky = "nsew")
btn_standby_send_xrp = tk.Button(master=frm_form, text="Send XRP >",
                                 command = standby_send_xrp)
btn_standby_send_xrp.grid(row=2, column = 2, sticky = "nsew")
```

Add buttons **Create Trust Line**, **Send Currency**, **Get Balances**, and **Configure Account**.


```python
btn_standby_create_trust_line = tk.Button(master=frm_form,
                                         text="Create Trust Line",
                                         command = standby_create_trust_line)
btn_standby_create_trust_line.grid(row=3, column=2, sticky = "nsew")
btn_standby_send_currency = tk.Button(master=frm_form, text="Send Currency >",
                                      command = standby_send_currency)
btn_standby_send_currency.grid(row=4, column=2, sticky = "nsew")
btn_standby_send_currency = tk.Button(master=frm_form, text="Get Balances",
                                      command = get_balances)
btn_standby_send_currency.grid(row=5, column=2, sticky = "nsew")
btn_standby_configure_account = tk.Button(master=frm_form,
                                          text="Configure Account",
                                          command = standby_configure_account)
btn_standby_configure_account.grid(row=7,column=0, sticky = "nsew")
```

Create the Operational Account buttons.


```python
btn_get_operational_account = tk.Button(master=frm_form,
                                        text="Get Operational Account",
                                        command = get_operational_account)
btn_get_operational_account.grid(row=0, column=3, sticky = "nsew")
btn_get_op_account_info = tk.Button(master=frm_form, text="Get Op Account Info",
                                    command = get_operational_account_info)
btn_get_op_account_info.grid(row=1, column=3, sticky = "nsew")
btn_op_send_xrp = tk.Button(master=frm_form, text="< Send XRP",
                            command = operational_send_xrp)
btn_op_send_xrp.grid(row=2, column = 3, sticky = "nsew")
```

Add operational buttons **Create Trust Line**, **Send Currency**, **Get Balances**, and **Configure Account**.


```python
btn_op_create_trust_line = tk.Button(master=frm_form, text="Create Trust Line",
                                    command = operational_create_trust_line)
btn_op_create_trust_line.grid(row=3, column=3, sticky = "nsew")
btn_op_send_currency = tk.Button(master=frm_form, text="< Send Currency",
                                 command = operational_send_currency)
btn_op_send_currency.grid(row=4, column=3, sticky = "nsew")
btn_op_get_balances = tk.Button(master=frm_form, text="Get Balances",
                                command = get_balances)
btn_op_get_balances.grid(row=5, column=3, sticky = "nsew")
btn_op_configure_account = tk.Button(master=frm_form, text="Configure Account",
                                     command = operational_configure_account)
btn_op_configure_account.grid(row=7,column=4, sticky = "nsew")
```

# Start the application


```python
window.mainloop()
```