diff --git a/_code-samples/modular-tutorials/send-currency.html b/_code-samples/modular-tutorials/send-currency.html
deleted file mode 100644
index 6ff900a599a..00000000000
--- a/_code-samples/modular-tutorials/send-currency.html
+++ /dev/null
@@ -1,229 +0,0 @@
-
-
- Send Currency
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Send Currency
-
-
-
-
\ No newline at end of file
diff --git a/_code-samples/modular-tutorials/send-currency.js b/_code-samples/modular-tutorials/send-currency.js
deleted file mode 100644
index aba9fbab80f..00000000000
--- a/_code-samples/modular-tutorials/send-currency.js
+++ /dev/null
@@ -1,96 +0,0 @@
-// *******************************************************
-// ***************** Create TrustLine ********************
-// *******************************************************
-
-async function createTrustLine() {
- const net = getNet()
- const client = new xrpl.Client(net)
- await client.connect()
- let results = "\nConnected. Creating trust line.\n"
- resultField.value = results
- try {
- const wallet = xrpl.Wallet.fromSeed(accountSeedField.value)
- const trustSet_tx = {
- "TransactionType": "TrustSet",
- "Account": accountAddressField.value,
- "LimitAmount": {
- "currency": currencyField.value,
- "issuer": issuerField.value,
- "value": amountField.value
- }
- }
- const ts_prepared = await client.autofill(trustSet_tx)
- const ts_signed = wallet.sign(ts_prepared)
- resultField.value = results
- const ts_result = await client.submitAndWait(ts_signed.tx_blob)
- if (ts_result.result.meta.TransactionResult == "tesSUCCESS") {
- results += '\n===Trustline established between account\n' +
- accountAddressField.value + "\nand account\n" + issuerField.value + '.'
- resultField.value = results
- } else {
- results += `\n===Transaction failed: ${ts_result.result.meta.TransactionResult}`
- resultField.value = results
- }
- }
- catch (error) {
- console.error('Error creating trust line:', error);
- results += `\n===Error: ${error.message}\n`
- resultField.value = results
- throw error; // Re-throw the error to be handled by the caller
- }
- finally {
- // Disconnect from the client
- await client.disconnect();
- }
-} //End of createTrustline()
-
-// *******************************************************
-// *************** Send Issued Currency ******************
-// *******************************************************
-
-async function sendCurrency() {
- let net = getNet()
- const client = new xrpl.Client(net)
- results = 'Connecting to ' + getNet() + '....'
- resultField.value = results
- await client.connect()
- results += '\nConnected.'
- resultField.value = results
- try {
- const wallet = xrpl.Wallet.fromSeed(accountSeedField.value)
- const send_currency_tx = {
- "TransactionType": "Payment",
- "Account": wallet.address,
- "Amount": {
- "currency": currencyField.value,
- "value": amountField.value,
- "issuer": issuerField.value
- },
- "Destination": destinationField.value
- }
- const pay_prepared = await client.autofill(send_currency_tx)
- const pay_signed = wallet.sign(pay_prepared)
- results += `\n\n===Sending ${amountField.value} ${currencyField.value} to ${destinationField.value} ...`
- resultField.value = results
- const pay_result = await client.submitAndWait(pay_signed.tx_blob)
- if (pay_result.result.meta.TransactionResult == "tesSUCCESS") {
- results += '\n===Transaction succeeded.'
- resultField.value = results
- getTokenBalance()
- } else {
- results += `\n===Transaction failed: ${pay_result.result.meta.TransactionResult}\n`
- resultField.value = results
- }
- xrpBalanceField.value = (await client.getXrpBalance(wallet.address))
-}
- catch (error) {
- console.error('Error sending transaction:', error);
- results += `\nError: ${error.message}\n`
- resultField.value = results
- throw error; // Re-throw the error to be handled by the caller
- }
- finally {
- // Disconnect from the client
- await client.disconnect();
- }
-} // end of sendCurrency()
diff --git a/_code-samples/send-a-trust-line-token/README.md b/_code-samples/send-a-trust-line-token/README.md
new file mode 100644
index 00000000000..956fce7c68f
--- /dev/null
+++ b/_code-samples/send-a-trust-line-token/README.md
@@ -0,0 +1,3 @@
+# Send a Trust Line Token Examples
+
+Send a trust line token payment between two accounts and compare balances before and after to confirm the transfer.
diff --git a/_code-samples/send-a-trust-line-token/go/README.md b/_code-samples/send-a-trust-line-token/go/README.md
new file mode 100644
index 00000000000..998f1f81944
--- /dev/null
+++ b/_code-samples/send-a-trust-line-token/go/README.md
@@ -0,0 +1,72 @@
+# Send a Trust Line Token (Go)
+
+Example code for sending a trust line token between two accounts on Testnet with [xrpl-go](https://github.com/Peersyst/xrpl-go).
+
+All commands should be run from this `go/` directory.
+
+## Setup
+
+```sh
+go mod tidy
+```
+
+## Send a Trust Line Token
+
+```sh
+go run ./send-trust-line-token
+```
+
+You should see output like the following:
+
+```sh
+Issuer address: r33kXgFnMTP7eVhr7YuZNyPnkz1wyfwVmg
+Sender address: rHAcF3ViMQHqjLvLT9GtM34jJyfK9Lq4En
+Receiver address: rHEfDbBxc5RmJdPzvi47p37P3XssTA3jB9
+
+=== Creating trust line from receiver to issuer... ===
+
+{
+ "Account": "rHEfDbBxc5RmJdPzvi47p37P3XssTA3jB9",
+ "LimitAmount": {
+ "currency": "FOO",
+ "issuer": "r33kXgFnMTP7eVhr7YuZNyPnkz1wyfwVmg",
+ "value": "1000000000"
+ },
+ "TransactionType": "TrustSet"
+}
+Trust line created from receiver to issuer!
+Explorer link: https://testnet.xrpl.org/transactions/835367A47F7D3B466A0BE94A95394AF4D4C46FD17397F3AC4A20964695D73F71
+
+=== Checking initial FOO balances... ===
+
+Holders' perspective:
+ Sender's balance: 900
+ Receiver's balance: 100
+Issuer's perspective:
+ Owed to sender: -900
+ Owed to receiver: -100
+
+=== Sending FOO payment... ===
+
+{
+ "Account": "rHAcF3ViMQHqjLvLT9GtM34jJyfK9Lq4En",
+ "Amount": {
+ "currency": "FOO",
+ "issuer": "r33kXgFnMTP7eVhr7YuZNyPnkz1wyfwVmg",
+ "value": "100"
+ },
+ "Destination": "rHEfDbBxc5RmJdPzvi47p37P3XssTA3jB9",
+ "TransactionType": "Payment"
+}
+Payment successful!
+Explorer link: https://testnet.xrpl.org/transactions/3FD2EDE570FADFBB129C6E4703CFBB80BC2BF5D843808F61C30F5041F46A7998
+
+=== Checking final FOO balances... ===
+
+Holders' perspective:
+ Sender's balance: 800
+ Receiver's balance: 200
+Issuer's perspective:
+ Owed to sender: -800
+ Owed to receiver: -200
+```
diff --git a/_code-samples/send-a-trust-line-token/go/go.mod b/_code-samples/send-a-trust-line-token/go/go.mod
new file mode 100644
index 00000000000..86cb990ea19
--- /dev/null
+++ b/_code-samples/send-a-trust-line-token/go/go.mod
@@ -0,0 +1,19 @@
+module github.com/XRPLF/send-a-trust-line-token
+
+go 1.24.3
+
+require github.com/Peersyst/xrpl-go v0.2.0
+
+require (
+ github.com/bsv-blockchain/go-sdk v1.2.9 // indirect
+ github.com/decred/dcrd/crypto/ripemd160 v1.0.2 // indirect
+ github.com/decred/dcrd/dcrec/secp256k1/v4 v4.4.1 // indirect
+ github.com/go-viper/mapstructure/v2 v2.5.0 // indirect
+ github.com/gorilla/websocket v1.5.3 // indirect
+ github.com/json-iterator/go v1.1.12 // indirect
+ github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421 // indirect
+ github.com/modern-go/reflect2 v1.0.2 // indirect
+ github.com/pkg/errors v0.9.1 // indirect
+ github.com/ugorji/go/codec v1.2.11 // indirect
+ golang.org/x/crypto v0.44.0 // indirect
+)
diff --git a/_code-samples/send-a-trust-line-token/go/send-trust-line-token-setup/main.go b/_code-samples/send-a-trust-line-token/go/send-trust-line-token-setup/main.go
new file mode 100644
index 00000000000..d40538aff6a
--- /dev/null
+++ b/_code-samples/send-a-trust-line-token/go/send-trust-line-token-setup/main.go
@@ -0,0 +1,168 @@
+package main
+
+import (
+ "encoding/json"
+ "fmt"
+ "os"
+ "time"
+
+ "github.com/Peersyst/xrpl-go/pkg/crypto"
+ "github.com/Peersyst/xrpl-go/xrpl/faucet"
+ "github.com/Peersyst/xrpl-go/xrpl/queries/account"
+ "github.com/Peersyst/xrpl-go/xrpl/queries/common"
+ "github.com/Peersyst/xrpl-go/xrpl/rpc"
+ rpctypes "github.com/Peersyst/xrpl-go/xrpl/rpc/types"
+ "github.com/Peersyst/xrpl-go/xrpl/transaction"
+ "github.com/Peersyst/xrpl-go/xrpl/transaction/types"
+ "github.com/Peersyst/xrpl-go/xrpl/wallet"
+)
+
+const (
+ currencyCode = "FOO"
+ totalSteps = 4
+)
+
+func main() {
+ cfg, err := rpc.NewClientConfig(
+ "https://s.altnet.rippletest.net:51234",
+ rpc.WithFaucetProvider(faucet.NewTestnetFaucetProvider()),
+ )
+ if err != nil {
+ panic(err)
+ }
+ client := rpc.NewClient(cfg)
+
+ submitOpts := func(w *wallet.Wallet) *rpctypes.SubmitOptions {
+ return &rpctypes.SubmitOptions{Autofill: true, Wallet: w}
+ }
+
+ step := 1
+
+ // Fund issuer, sender, and receiver concurrently
+ fmt.Printf("Setting up tutorial: %d/%d\r", step, totalSteps)
+ step++
+
+ ch := make(chan wallet.Wallet, 3)
+ createAndFund := func() {
+ w, err := wallet.New(crypto.ED25519())
+ if err != nil {
+ panic(err)
+ }
+ if err := client.FundWallet(&w); err != nil {
+ panic(err)
+ }
+ // Poll until account is validated on ledger
+ funded := false
+ for range 20 {
+ _, err := client.Request(&account.InfoRequest{
+ Account: w.GetAddress(),
+ LedgerIndex: common.Validated,
+ })
+ if err == nil {
+ funded = true
+ break
+ }
+ time.Sleep(time.Second)
+ }
+ if !funded {
+ panic("Issue funding account: " + w.GetAddress().String())
+ }
+ ch <- w
+ }
+ go createAndFund()
+ go createAndFund()
+ go createAndFund()
+ issuer := <-ch
+ sender := <-ch
+ receiver := <-ch
+
+ fmt.Printf("Setting up tutorial: %d/%d\r", step, totalSteps)
+ step++
+
+ accountSetTx := transaction.AccountSet{
+ BaseTx: transaction.BaseTx{Account: issuer.ClassicAddress},
+ }
+ // Enable Default Ripple on the issuer
+ accountSetTx.SetAsfDefaultRipple()
+
+ flatAccountSet := accountSetTx.Flatten()
+ accountSetResp, err := client.SubmitTxAndWait(flatAccountSet, submitOpts(&issuer))
+ if err != nil {
+ panic(err)
+ }
+ if accountSetResp.Meta.TransactionResult != "tesSUCCESS" {
+ panic("AccountSet failed: " + accountSetResp.Meta.TransactionResult)
+ }
+
+ // Create sender trust line to issuer
+ fmt.Printf("Setting up tutorial: %d/%d\r", step, totalSteps)
+ step++
+
+ trustSetTx := transaction.TrustSet{
+ BaseTx: transaction.BaseTx{Account: sender.ClassicAddress},
+ LimitAmount: types.IssuedCurrencyAmount{
+ Currency: currencyCode,
+ Issuer: issuer.ClassicAddress,
+ Value: "1000000000",
+ },
+ }
+ flatTrustSet := trustSetTx.Flatten()
+ trustSetResp, err := client.SubmitTxAndWait(flatTrustSet, submitOpts(&sender))
+ if err != nil {
+ panic(err)
+ }
+ if trustSetResp.Meta.TransactionResult != "tesSUCCESS" {
+ panic("TrustSet failed: " + trustSetResp.Meta.TransactionResult)
+ }
+
+ // Issuer sends sender tokens
+ fmt.Printf("Setting up tutorial: %d/%d\r", step, totalSteps)
+
+ seedTx := transaction.Payment{
+ BaseTx: transaction.BaseTx{Account: issuer.ClassicAddress},
+ Destination: sender.ClassicAddress,
+ Amount: types.IssuedCurrencyAmount{
+ Currency: currencyCode,
+ Issuer: issuer.ClassicAddress,
+ Value: "1000",
+ },
+ }
+ flatSeed := seedTx.Flatten()
+ seedResp, err := client.SubmitTxAndWait(flatSeed, submitOpts(&issuer))
+ if err != nil {
+ panic(err)
+ }
+ if seedResp.Meta.TransactionResult != "tesSUCCESS" {
+ panic("Issuer seed payment failed: " + seedResp.Meta.TransactionResult)
+ }
+
+ // Write setup data
+ setupData := struct {
+ Description string `json:"description"`
+ Issuer any `json:"issuer"`
+ Sender any `json:"sender"`
+ Receiver any `json:"receiver"`
+ }{
+ Description: "This file is auto-generated by go/send-trust-line-token-setup/main.go. It stores XRPL account info for the send-a-trust-line-token tutorial.",
+ Issuer: map[string]string{
+ "address": issuer.ClassicAddress.String(),
+ "seed": issuer.Seed,
+ },
+ Sender: map[string]string{
+ "address": sender.ClassicAddress.String(),
+ "seed": sender.Seed,
+ },
+ Receiver: map[string]string{
+ "address": receiver.ClassicAddress.String(),
+ "seed": receiver.Seed,
+ },
+ }
+
+ jsonData, err := json.MarshalIndent(setupData, "", " ")
+ if err != nil {
+ panic(err)
+ }
+ if err := os.WriteFile("send-trust-line-token-setup.json", jsonData, 0644); err != nil {
+ panic(err)
+ }
+}
diff --git a/_code-samples/send-a-trust-line-token/go/send-trust-line-token/main.go b/_code-samples/send-a-trust-line-token/go/send-trust-line-token/main.go
new file mode 100644
index 00000000000..4fbfc63c3dc
--- /dev/null
+++ b/_code-samples/send-a-trust-line-token/go/send-trust-line-token/main.go
@@ -0,0 +1,216 @@
+package main
+
+import (
+ "encoding/json"
+ "fmt"
+ "os"
+ "os/exec"
+
+ "github.com/Peersyst/xrpl-go/xrpl/queries/account"
+ "github.com/Peersyst/xrpl-go/xrpl/queries/common"
+ "github.com/Peersyst/xrpl-go/xrpl/transaction"
+ "github.com/Peersyst/xrpl-go/xrpl/transaction/types"
+ "github.com/Peersyst/xrpl-go/xrpl/wallet"
+ "github.com/Peersyst/xrpl-go/xrpl/websocket"
+ wstypes "github.com/Peersyst/xrpl-go/xrpl/websocket/types"
+)
+
+const currencyCode = "FOO"
+
+func main() {
+ // Connect to the network ----------------------
+ client := websocket.NewClient(
+ websocket.NewClientConfig().
+ WithHost("wss://s.altnet.rippletest.net:51233"),
+ )
+ defer client.Disconnect()
+
+ if err := client.Connect(); err != nil {
+ panic(err)
+ }
+
+ // This step checks for the necessary setup data to run the tutorial.
+ // If missing, send-trust-line-token-setup will generate it.
+ if _, err := os.Stat("send-trust-line-token-setup.json"); os.IsNotExist(err) {
+ fmt.Printf("\n=== Tutorial setup data doesn't exist. Running setup script... ===\n\n")
+ cmd := exec.Command("go", "run", "./send-trust-line-token-setup")
+ cmd.Stdout = os.Stdout
+ cmd.Stderr = os.Stderr
+ if err := cmd.Run(); err != nil {
+ panic(err)
+ }
+ }
+
+ // Load preconfigured issuer, sender, and receiver accounts.
+ data, err := os.ReadFile("send-trust-line-token-setup.json")
+ if err != nil {
+ panic(err)
+ }
+ var setup map[string]any
+ if err := json.Unmarshal(data, &setup); err != nil {
+ panic(err)
+ }
+ issuer, err := wallet.FromSecret(setup["issuer"].(map[string]any)["seed"].(string))
+ if err != nil {
+ panic(err)
+ }
+ sender, err := wallet.FromSecret(setup["sender"].(map[string]any)["seed"].(string))
+ if err != nil {
+ panic(err)
+ }
+ receiver, err := wallet.FromSecret(setup["receiver"].(map[string]any)["seed"].(string))
+ if err != nil {
+ panic(err)
+ }
+
+ fmt.Printf("Issuer address: %s\n", issuer.ClassicAddress)
+ fmt.Printf("Sender address: %s\n", sender.ClassicAddress)
+ fmt.Printf("Receiver address: %s\n", receiver.ClassicAddress)
+
+ // Create trust line ----------------------
+ // The receiver opts in to the token by creating a trust line to the issuer.
+ // The LimitAmount sets the maximum amount of the token the receiver will hold.
+ fmt.Printf("\n=== Creating trust line from receiver to issuer... ===\n\n")
+ trustSetTx := transaction.TrustSet{
+ BaseTx: transaction.BaseTx{
+ Account: receiver.ClassicAddress,
+ },
+ LimitAmount: types.IssuedCurrencyAmount{
+ Currency: currencyCode,
+ Issuer: issuer.ClassicAddress,
+ Value: "1000000000",
+ },
+ }
+
+ flatTrustSet := trustSetTx.Flatten()
+ trustSetJSON, _ := json.MarshalIndent(flatTrustSet, "", " ")
+ fmt.Printf("%s\n", string(trustSetJSON))
+
+ trustSetResponse, err := client.SubmitTxAndWait(flatTrustSet, &wstypes.SubmitOptions{
+ Autofill: true,
+ Wallet: &receiver,
+ })
+ if err != nil {
+ panic(err)
+ }
+ if trustSetResponse.Meta.TransactionResult != "tesSUCCESS" {
+ fmt.Printf("Error: Unable to create trust line: %s\n", trustSetResponse.Meta.TransactionResult)
+ os.Exit(1)
+ }
+ fmt.Printf("Trust line created from receiver to issuer!\n")
+ fmt.Printf("Explorer link: https://testnet.xrpl.org/transactions/%s\n", trustSetResponse.Hash.String())
+
+ // Check initial balances ----------------------
+ // getTrustLineBalance returns the trust line balance between `addr` and
+ // `peer` for the given currency.
+ getTrustLineBalance := func(addr, currency, peer types.Address) (string, error) {
+ resp, err := client.Request(&account.LinesRequest{
+ Account: addr,
+ Peer: peer,
+ LedgerIndex: common.Validated,
+ })
+ if err != nil {
+ return "", err
+ }
+ lines, ok := resp.Result["lines"].([]any)
+ if !ok {
+ return "0", nil
+ }
+ for _, l := range lines {
+ line, ok := l.(map[string]any)
+ if !ok {
+ continue
+ }
+ if line["currency"] == string(currency) {
+ if bal, ok := line["balance"].(string); ok {
+ return bal, nil
+ }
+ }
+ }
+ return "0", nil
+ }
+
+ fmt.Printf("\n=== Checking initial %s balances... ===\n\n", currencyCode)
+ senderView, err := getTrustLineBalance(sender.ClassicAddress, currencyCode, issuer.ClassicAddress)
+ if err != nil {
+ panic(err)
+ }
+ receiverView, err := getTrustLineBalance(receiver.ClassicAddress, currencyCode, issuer.ClassicAddress)
+ if err != nil {
+ panic(err)
+ }
+ issuerToSender, err := getTrustLineBalance(issuer.ClassicAddress, currencyCode, sender.ClassicAddress)
+ if err != nil {
+ panic(err)
+ }
+ issuerToReceiver, err := getTrustLineBalance(issuer.ClassicAddress, currencyCode, receiver.ClassicAddress)
+ if err != nil {
+ panic(err)
+ }
+ fmt.Println("Holders' perspective:")
+ fmt.Printf(" Sender's balance: %s\n", senderView)
+ fmt.Printf(" Receiver's balance: %s\n", receiverView)
+ fmt.Println("Issuer's perspective:")
+ fmt.Printf(" Owed to sender: %s\n", issuerToSender)
+ fmt.Printf(" Owed to receiver: %s\n", issuerToReceiver)
+
+ // Send issued token ----------------------
+ // The sender pays the receiver with the issued currency.
+ const sendQuantity = "100"
+ fmt.Printf("\n=== Sending %s payment... ===\n\n", currencyCode)
+ paymentTx := transaction.Payment{
+ BaseTx: transaction.BaseTx{
+ Account: sender.ClassicAddress,
+ },
+ Destination: receiver.ClassicAddress,
+ Amount: types.IssuedCurrencyAmount{
+ Currency: currencyCode,
+ Issuer: issuer.ClassicAddress,
+ Value: sendQuantity,
+ },
+ }
+
+ flatPayment := paymentTx.Flatten()
+ paymentJSON, _ := json.MarshalIndent(flatPayment, "", " ")
+ fmt.Printf("%s\n", string(paymentJSON))
+
+ paymentResponse, err := client.SubmitTxAndWait(flatPayment, &wstypes.SubmitOptions{
+ Autofill: true,
+ Wallet: &sender,
+ })
+ if err != nil {
+ panic(err)
+ }
+ if paymentResponse.Meta.TransactionResult != "tesSUCCESS" {
+ fmt.Printf("Error: Unable to send token: %s\n", paymentResponse.Meta.TransactionResult)
+ os.Exit(1)
+ }
+ fmt.Printf("Payment successful!\n")
+ fmt.Printf("Explorer link: https://testnet.xrpl.org/transactions/%s\n", paymentResponse.Hash.String())
+
+ // Verify balances ----------------------
+ // Check account balances after the payment.
+ fmt.Printf("\n=== Checking final %s balances... ===\n\n", currencyCode)
+ senderView, err = getTrustLineBalance(sender.ClassicAddress, currencyCode, issuer.ClassicAddress)
+ if err != nil {
+ panic(err)
+ }
+ receiverView, err = getTrustLineBalance(receiver.ClassicAddress, currencyCode, issuer.ClassicAddress)
+ if err != nil {
+ panic(err)
+ }
+ issuerToSender, err = getTrustLineBalance(issuer.ClassicAddress, currencyCode, sender.ClassicAddress)
+ if err != nil {
+ panic(err)
+ }
+ issuerToReceiver, err = getTrustLineBalance(issuer.ClassicAddress, currencyCode, receiver.ClassicAddress)
+ if err != nil {
+ panic(err)
+ }
+ fmt.Println("Holders' perspective:")
+ fmt.Printf(" Sender's balance: %s\n", senderView)
+ fmt.Printf(" Receiver's balance: %s\n", receiverView)
+ fmt.Println("Issuer's perspective:")
+ fmt.Printf(" Owed to sender: %s\n", issuerToSender)
+ fmt.Printf(" Owed to receiver: %s\n", issuerToReceiver)
+}
diff --git a/_code-samples/send-a-trust-line-token/js/.claude/settings.local.json b/_code-samples/send-a-trust-line-token/js/.claude/settings.local.json
new file mode 100644
index 00000000000..a6ca3a601bb
--- /dev/null
+++ b/_code-samples/send-a-trust-line-token/js/.claude/settings.local.json
@@ -0,0 +1,19 @@
+{
+ "permissions": {
+ "allow": [
+ "Bash(gh api *)",
+ "Bash(python scripts/diagnose.py --network testnet account r9hubmAsLytrAiAF9oN6rNHdqPitkRCoQv)",
+ "Bash(python3 scripts/diagnose.py --network testnet account r9hubmAsLytrAiAF9oN6rNHdqPitkRCoQv)",
+ "Bash(python3 -c \"import xrpl; print\\('xrpl-py', xrpl.__version__\\)\")",
+ "Bash(curl -s -X POST https://s.altnet.rippletest.net:51234/ -H 'Content-Type: application/json' -d '{\"method\":\"account_info\",\"params\":[{\"account\":\"r9hubmAsLytrAiAF9oN6rNHdqPitkRCoQv\",\"ledger_index\":\"validated\"}]}')",
+ "Bash(python3 -m json.tool)",
+ "Bash(curl -s -X POST https://s.altnet.rippletest.net:51234/ -H 'Content-Type: application/json' -d '{\"method\":\"account_tx\",\"params\":[{\"account\":\"r9hubmAsLytrAiAF9oN6rNHdqPitkRCoQv\",\"ledger_index_min\":-1,\"ledger_index_max\":-1,\"limit\":10,\"binary\":false}]}')",
+ "Bash(python3 -c ' *)",
+ "Bash(python3 -c \"import json;d=json.load\\(open\\('setup.json'\\)\\);print\\('issuer ',d['issuer']['address']\\);print\\('sender ',d['sender']['address']\\);print\\('receiver',d['receiver']['address']\\)\")"
+ ]
+ },
+ "enabledMcpjsonServers": [
+ "context7",
+ "xrpl-dev-portal"
+ ]
+}
diff --git a/_code-samples/send-a-trust-line-token/js/README.md b/_code-samples/send-a-trust-line-token/js/README.md
new file mode 100644
index 00000000000..356451af091
--- /dev/null
+++ b/_code-samples/send-a-trust-line-token/js/README.md
@@ -0,0 +1,70 @@
+# Send a Trust Line Token (JavaScript)
+
+Example code for sending a trust line token between two accounts on Testnet with [xrpl.js](https://github.com/XRPLF/xrpl.js).
+
+## Setup
+
+```sh
+npm install
+```
+
+## Send a Trust Line Token
+
+```sh
+node sendTrustLineToken.js
+```
+
+You should see output like the following:
+
+```sh
+Issuer address: rUrWYSHAX8kVwwPRxgVzhYQg9Ko3kxoqoy
+Sender address: rEx369HEEn1S2Cg2WC6Wi66awc45KzNBfV
+Receiver address: rE1LWiuCAB7VogxWAAymFegbB7t1WKsD6v
+
+=== Creating trust line from receiver to issuer... ===
+
+{
+ "TransactionType": "TrustSet",
+ "Account": "rE1LWiuCAB7VogxWAAymFegbB7t1WKsD6v",
+ "LimitAmount": {
+ "currency": "FOO",
+ "issuer": "rUrWYSHAX8kVwwPRxgVzhYQg9Ko3kxoqoy",
+ "value": "1000000000"
+ }
+}
+Trust line created from receiver to issuer!
+Explorer link: https://testnet.xrpl.org/transactions/76AE546380FFA6CBDD3967FFECF2F75093D0EEC9925DE7969CF63FCFC71A439E
+
+=== Checking initial FOO balances... ===
+
+Holders' perspective:
+ Sender's balance: 600
+ Receiver's balance: 400
+Issuer's perspective:
+ Owed to sender: -600
+ Owed to receiver: -400
+
+=== Sending FOO payment... ===
+
+{
+ "TransactionType": "Payment",
+ "Account": "rEx369HEEn1S2Cg2WC6Wi66awc45KzNBfV",
+ "Destination": "rE1LWiuCAB7VogxWAAymFegbB7t1WKsD6v",
+ "Amount": {
+ "currency": "FOO",
+ "issuer": "rUrWYSHAX8kVwwPRxgVzhYQg9Ko3kxoqoy",
+ "value": "100"
+ }
+}
+Payment successful!
+Explorer link: https://testnet.xrpl.org/transactions/E6313B9CEA42C45EA1047790BCF1DC5B8D49A35AEAC5735288ABBD252C56D1AD
+
+=== Checking final FOO balances... ===
+
+Holders' perspective:
+ Sender's balance: 500
+ Receiver's balance: 500
+Issuer's perspective:
+ Owed to sender: -500
+ Owed to receiver: -500
+```
diff --git a/_code-samples/send-a-trust-line-token/js/package.json b/_code-samples/send-a-trust-line-token/js/package.json
new file mode 100644
index 00000000000..16ac149e536
--- /dev/null
+++ b/_code-samples/send-a-trust-line-token/js/package.json
@@ -0,0 +1,8 @@
+{
+ "name": "send-a-trust-line-token-examples",
+ "description": "Example code for sending a trust line token on the XRP Ledger.",
+ "dependencies": {
+ "xrpl": "^4.6.0"
+ },
+ "type": "module"
+}
diff --git a/_code-samples/send-a-trust-line-token/js/sendTrustLineToken.js b/_code-samples/send-a-trust-line-token/js/sendTrustLineToken.js
new file mode 100644
index 00000000000..6f0fae323aa
--- /dev/null
+++ b/_code-samples/send-a-trust-line-token/js/sendTrustLineToken.js
@@ -0,0 +1,118 @@
+import xrpl from 'xrpl'
+import fs from 'fs'
+import { setup } from './sendTrustLineTokenSetup.js'
+
+// Set up client ----------------------
+const client = new xrpl.Client('wss://s.altnet.rippletest.net:51233')
+await client.connect()
+
+// This step checks for the necessary setup data to run the tutorial.
+// If missing, sendTrustLineTokenSetup.js will generate it.
+if (!fs.existsSync('sendTrustLineTokenSetup.json')) {
+ console.log(`\n=== Tutorial setup data doesn't exist. Running setup script... ===\n`)
+ await setup()
+}
+
+// Load preconfigured issuer, sender, and receiver accounts.
+const setupData = JSON.parse(fs.readFileSync('sendTrustLineTokenSetup.json', 'utf8'))
+const issuer = xrpl.Wallet.fromSeed(setupData.issuer.seed)
+const sender = xrpl.Wallet.fromSeed(setupData.sender.seed)
+const receiver = xrpl.Wallet.fromSeed(setupData.receiver.seed)
+const currencyCode = 'FOO'
+
+console.log(`Issuer address: ${issuer.address}`)
+console.log(`Sender address: ${sender.address}`)
+console.log(`Receiver address: ${receiver.address}`)
+
+// Create trust line ----------------------
+// The receiver opts in to the token by creating a trust line to the issuer.
+// The LimitAmount sets the maximum amount of the token the receiver will hold.
+console.log(`\n=== Creating trust line from receiver to issuer... ===\n`)
+const trustSetTx = {
+ TransactionType: 'TrustSet',
+ Account: receiver.address,
+ LimitAmount: {
+ currency: currencyCode,
+ issuer: issuer.address,
+ value: '1000000000'
+ }
+}
+xrpl.validate(trustSetTx)
+console.log(JSON.stringify(trustSetTx, null, 2))
+
+const trustSetResponse = await client.submitAndWait(trustSetTx, {
+ wallet: receiver,
+ autofill: true
+})
+if (trustSetResponse.result.meta?.TransactionResult !== 'tesSUCCESS') {
+ const resultCode = trustSetResponse.result.meta?.TransactionResult
+ console.error('Error: Unable to create trust line:', resultCode)
+ await client.disconnect()
+ process.exit(1)
+}
+console.log('Trust line created from receiver to issuer!')
+console.log(`Explorer link: https://testnet.xrpl.org/transactions/${trustSetResponse.result.hash}`)
+
+// Check initial balances ----------------------
+// getTrustLineBalance returns the trust line balance between `account` and
+// `peer` for the given currency.
+async function getTrustLineBalance(account, currency, peer) {
+ const response = await client.request({
+ command: 'account_lines',
+ account,
+ peer,
+ ledger_index: 'validated'
+ })
+ const line = response.result.lines.find(l => l.currency === currency)
+ return line?.balance ?? '0'
+}
+
+console.log(`\n=== Checking initial ${currencyCode} balances... ===\n`)
+console.log("Holders' perspective:")
+console.log(` Sender's balance: ${await getTrustLineBalance(sender.address, currencyCode, issuer.address)}`)
+console.log(` Receiver's balance: ${await getTrustLineBalance(receiver.address, currencyCode, issuer.address)}`)
+console.log("Issuer's perspective:")
+console.log(` Owed to sender: ${await getTrustLineBalance(issuer.address, currencyCode, sender.address)}`)
+console.log(` Owed to receiver: ${await getTrustLineBalance(issuer.address, currencyCode, receiver.address)}`)
+
+// Send issued token ----------------------
+// The sender pays the receiver with the issued currency.
+const sendQuantity = '100'
+console.log(`\n=== Sending ${currencyCode} payment... ===\n`)
+const paymentTx = {
+ TransactionType: 'Payment',
+ Account: sender.address,
+ Destination: receiver.address,
+ Amount: {
+ currency: currencyCode,
+ issuer: issuer.address,
+ value: sendQuantity
+ }
+}
+xrpl.validate(paymentTx)
+console.log(JSON.stringify(paymentTx, null, 2))
+
+const paymentResponse = await client.submitAndWait(paymentTx, {
+ wallet: sender,
+ autofill: true
+})
+if (paymentResponse.result.meta?.TransactionResult !== 'tesSUCCESS') {
+ const resultCode = paymentResponse.result.meta?.TransactionResult
+ console.error('Error: Unable to send token:', resultCode)
+ await client.disconnect()
+ process.exit(1)
+}
+console.log('Payment successful!')
+console.log(`Explorer link: https://testnet.xrpl.org/transactions/${paymentResponse.result.hash}`)
+
+// Verify balances ----------------------
+// Check account balances after the payment.
+console.log(`\n=== Checking final ${currencyCode} balances... ===\n`)
+console.log("Holders' perspective:")
+console.log(` Sender's balance: ${await getTrustLineBalance(sender.address, currencyCode, issuer.address)}`)
+console.log(` Receiver's balance: ${await getTrustLineBalance(receiver.address, currencyCode, issuer.address)}`)
+console.log("Issuer's perspective:")
+console.log(` Owed to sender: ${await getTrustLineBalance(issuer.address, currencyCode, sender.address)}`)
+console.log(` Owed to receiver: ${await getTrustLineBalance(issuer.address, currencyCode, receiver.address)}`)
+
+await client.disconnect()
diff --git a/_code-samples/send-a-trust-line-token/js/sendTrustLineTokenSetup.js b/_code-samples/send-a-trust-line-token/js/sendTrustLineTokenSetup.js
new file mode 100644
index 00000000000..55364e6bd48
--- /dev/null
+++ b/_code-samples/send-a-trust-line-token/js/sendTrustLineTokenSetup.js
@@ -0,0 +1,106 @@
+import xrpl from 'xrpl'
+import fs from 'fs'
+import { fileURLToPath } from 'url'
+
+const currencyCode = 'FOO'
+const TOTAL_STEPS = 4
+
+export async function setup() {
+ process.stdout.write(`Setting up tutorial: 0/${TOTAL_STEPS}\r`)
+
+ const client = new xrpl.Client('wss://s.altnet.rippletest.net:51233')
+ await client.connect()
+
+ // Fund issuer, sender, and receiver wallets from the Testnet faucet.
+ const [
+ { wallet: issuer },
+ { wallet: sender },
+ { wallet: receiver }
+ ] = await Promise.all([
+ client.fundWallet(),
+ client.fundWallet(),
+ client.fundWallet()
+ ])
+
+ process.stdout.write(`Setting up tutorial: 1/${TOTAL_STEPS}\r`)
+
+ // Enable Default Ripple on the issuer so the token can ripple through the
+ // issuer's trust lines when holders send it between each other.
+ const accountSetResponse = await client.submitAndWait({
+ TransactionType: 'AccountSet',
+ Account: issuer.address,
+ SetFlag: xrpl.AccountSetAsfFlags.asfDefaultRipple
+ }, { wallet: issuer, autofill: true })
+
+ if (accountSetResponse.result.meta?.TransactionResult !== 'tesSUCCESS') {
+ await client.disconnect()
+ throw new Error(`AccountSet failed: ${accountSetResponse.result.meta?.TransactionResult}`)
+ }
+
+ process.stdout.write(`Setting up tutorial: 2/${TOTAL_STEPS}\r`)
+
+ // Create a trust line from the sender to the issuer so the sender can hold the token.
+ const senderTrustResponse = await client.submitAndWait({
+ TransactionType: 'TrustSet',
+ Account: sender.address,
+ LimitAmount: {
+ currency: currencyCode,
+ issuer: issuer.address,
+ value: '1000000000'
+ }
+ }, { wallet: sender, autofill: true })
+
+ if (senderTrustResponse.result.meta?.TransactionResult !== 'tesSUCCESS') {
+ await client.disconnect()
+ throw new Error(`Sender TrustSet failed: ${senderTrustResponse.result.meta?.TransactionResult}`)
+ }
+
+ process.stdout.write(`Setting up tutorial: 3/${TOTAL_STEPS}\r`)
+
+ // Issue the token from the issuer to the sender so the sender has a balance to send.
+ const issueResponse = await client.submitAndWait({
+ TransactionType: 'Payment',
+ Account: issuer.address,
+ Destination: sender.address,
+ Amount: {
+ currency: currencyCode,
+ issuer: issuer.address,
+ value: '1000'
+ }
+ }, { wallet: issuer, autofill: true })
+
+ if (issueResponse.result.meta?.TransactionResult !== 'tesSUCCESS') {
+ await client.disconnect()
+ throw new Error(`Issuer Payment failed: ${issueResponse.result.meta?.TransactionResult}`)
+ }
+
+ process.stdout.write(`Setting up tutorial: 4/${TOTAL_STEPS}\r`)
+
+ // Write setup data to JSON file.
+ const setupData = {
+ description: 'This file is auto-generated by sendTrustLineTokenSetup.js. It stores XRPL account info for use in the Send a Trust Line Token tutorial.',
+ issuer: {
+ address: issuer.address,
+ seed: issuer.seed
+ },
+ sender: {
+ address: sender.address,
+ seed: sender.seed
+ },
+ receiver: {
+ address: receiver.address,
+ seed: receiver.seed
+ }
+ }
+
+ fs.writeFileSync('sendTrustLineTokenSetup.json', JSON.stringify(setupData, null, 2))
+
+ process.stdout.write('Setting up tutorial: Complete!\n')
+
+ await client.disconnect()
+}
+
+// Allow running this file directly: `node sendTrustLineTokenSetup.js`
+if (process.argv[1] === fileURLToPath(import.meta.url)) {
+ await setup()
+}
diff --git a/_code-samples/send-a-trust-line-token/py/README.md b/_code-samples/send-a-trust-line-token/py/README.md
new file mode 100644
index 00000000000..81c8e8d3092
--- /dev/null
+++ b/_code-samples/send-a-trust-line-token/py/README.md
@@ -0,0 +1,74 @@
+# Send a Trust Line Token (Python)
+
+Example code for sending a trust line token between two accounts on Testnet with [xrpl-py](https://github.com/XRPLF/xrpl-py).
+
+## Setup
+
+```sh
+python -m venv .venv
+source .venv/bin/activate
+pip install -r requirements.txt
+```
+
+## Send a Trust Line Token
+
+```sh
+python send_trust_line_token.py
+```
+
+You should see output like the following:
+
+```sh
+Issuer address: rpQrTB7Zko3i8QTZa1jn3MqTjFFtjvnpDD
+Sender address: rNXVfWdMs8oScEDBUfZgv5Auds6ahWvgMS
+Receiver address: rQpATksgqj3XNatYZ89mnxPrCXgSvuWKkN
+
+=== Creating trust line from receiver to issuer... ===
+
+{
+ "Account": "rQpATksgqj3XNatYZ89mnxPrCXgSvuWKkN",
+ "TransactionType": "TrustSet",
+ "SigningPubKey": "",
+ "LimitAmount": {
+ "currency": "FOO",
+ "issuer": "rpQrTB7Zko3i8QTZa1jn3MqTjFFtjvnpDD",
+ "value": "1000000000"
+ }
+}
+Trust line created from receiver to issuer!
+Explorer link: https://testnet.xrpl.org/transactions/9DA16FEE0B361C96BAD6F341E15E4FD6A6601BC4DD6227EC7EF655C29A1A412D
+
+=== Checking initial FOO balances... ===
+
+Holders' perspective:
+ Sender's balance: 900
+ Receiver's balance: 100
+Issuer's perspective:
+ Owed to sender: -900
+ Owed to receiver: -100
+
+=== Sending FOO payment... ===
+
+{
+ "Account": "rNXVfWdMs8oScEDBUfZgv5Auds6ahWvgMS",
+ "TransactionType": "Payment",
+ "SigningPubKey": "",
+ "Amount": {
+ "currency": "FOO",
+ "issuer": "rpQrTB7Zko3i8QTZa1jn3MqTjFFtjvnpDD",
+ "value": "100"
+ },
+ "Destination": "rQpATksgqj3XNatYZ89mnxPrCXgSvuWKkN"
+}
+Payment successful!
+Explorer link: https://testnet.xrpl.org/transactions/7779331C8AE458A8342A36CCCD53CA5ED03219C61B8F159EDC36A1BBD6FC85EC
+
+=== Checking final FOO balances... ===
+
+Holders' perspective:
+ Sender's balance: 800
+ Receiver's balance: 200
+Issuer's perspective:
+ Owed to sender: -800
+ Owed to receiver: -200
+```
diff --git a/_code-samples/send-a-trust-line-token/py/requirements.txt b/_code-samples/send-a-trust-line-token/py/requirements.txt
new file mode 100644
index 00000000000..6550f9202ad
--- /dev/null
+++ b/_code-samples/send-a-trust-line-token/py/requirements.txt
@@ -0,0 +1 @@
+xrpl-py>=4.5.0
diff --git a/_code-samples/send-a-trust-line-token/py/send_trust_line_token.py b/_code-samples/send-a-trust-line-token/py/send_trust_line_token.py
new file mode 100644
index 00000000000..114ad42cc4f
--- /dev/null
+++ b/_code-samples/send-a-trust-line-token/py/send_trust_line_token.py
@@ -0,0 +1,112 @@
+import asyncio
+import json
+import os
+import sys
+
+from xrpl.clients import JsonRpcClient
+from xrpl.models import AccountLines
+from xrpl.models.amounts import IssuedCurrencyAmount
+from xrpl.models.transactions import Payment, TrustSet
+from xrpl.transaction import submit_and_wait
+from xrpl.wallet import Wallet
+
+from send_trust_line_token_setup import main as run_setup
+
+# Set up client ----------------------
+client = JsonRpcClient("https://s.altnet.rippletest.net:51234")
+
+# This step checks for the necessary setup data to run the tutorial.
+# If missing, send_trust_line_token_setup.py will generate it.
+if not os.path.exists("send_trust_line_token_setup.json"):
+ print("\n=== Tutorial setup data doesn't exist. Running setup script... ===\n")
+ asyncio.run(run_setup())
+
+# Load preconfigured issuer, sender, and receiver accounts.
+with open("send_trust_line_token_setup.json") as f:
+ setup_data = json.load(f)
+
+issuer = Wallet.from_seed(setup_data["issuer"]["seed"])
+sender = Wallet.from_seed(setup_data["sender"]["seed"])
+receiver = Wallet.from_seed(setup_data["receiver"]["seed"])
+currency_code = "FOO"
+
+print(f"Issuer address: {issuer.address}")
+print(f"Sender address: {sender.address}")
+print(f"Receiver address: {receiver.address}")
+
+# Create trust line ----------------------
+# The receiver opts in to the token by creating a trust line to the issuer.
+# The limit_amount sets the maximum amount of the token the receiver will hold.
+print("\n=== Creating trust line from receiver to issuer... ===\n")
+trust_set_tx = TrustSet(
+ account=receiver.address,
+ limit_amount=IssuedCurrencyAmount(
+ currency=currency_code,
+ issuer=issuer.address,
+ value="1000000000",
+ ),
+)
+print(json.dumps(trust_set_tx.to_xrpl(), indent=2))
+
+trust_set_response = submit_and_wait(trust_set_tx, client, receiver)
+result_code = trust_set_response.result["meta"]["TransactionResult"]
+if result_code != "tesSUCCESS":
+ print(f"Error: Unable to create trust line: {result_code}")
+ sys.exit(1)
+print("Trust line created from receiver to issuer!")
+print(f"Explorer link: https://testnet.xrpl.org/transactions/{trust_set_response.result['hash']}")
+
+# Check initial balances ----------------------
+# get_trust_line_balance returns the trust line balance between `account` and
+# `peer` for the given currency.
+def get_trust_line_balance(account, currency, peer):
+ response = client.request(AccountLines(
+ account=account,
+ peer=peer,
+ ledger_index="validated",
+ ))
+ for line in response.result.get("lines", []):
+ if line["currency"] == currency:
+ return line["balance"]
+ return "0"
+
+print(f"\n=== Checking initial {currency_code} balances... ===\n")
+print("Holders' perspective:")
+print(f" Sender's balance: {get_trust_line_balance(sender.address, currency_code, issuer.address)}")
+print(f" Receiver's balance: {get_trust_line_balance(receiver.address, currency_code, issuer.address)}")
+print("Issuer's perspective:")
+print(f" Owed to sender: {get_trust_line_balance(issuer.address, currency_code, sender.address)}")
+print(f" Owed to receiver: {get_trust_line_balance(issuer.address, currency_code, receiver.address)}")
+
+# Send issued token ----------------------
+# The sender pays the receiver with the issued currency.
+send_quantity = "100"
+print(f"\n=== Sending {currency_code} payment... ===\n")
+payment_tx = Payment(
+ account=sender.address,
+ destination=receiver.address,
+ amount=IssuedCurrencyAmount(
+ currency=currency_code,
+ issuer=issuer.address,
+ value=send_quantity,
+ ),
+)
+print(json.dumps(payment_tx.to_xrpl(), indent=2))
+
+payment_response = submit_and_wait(payment_tx, client, sender)
+result_code = payment_response.result["meta"]["TransactionResult"]
+if result_code != "tesSUCCESS":
+ print(f"Error: Unable to send token: {result_code}")
+ sys.exit(1)
+print("Payment successful!")
+print(f"Explorer link: https://testnet.xrpl.org/transactions/{payment_response.result['hash']}")
+
+# Verify balances ----------------------
+# Check account balances after the payment.
+print(f"\n=== Checking final {currency_code} balances... ===\n")
+print("Holders' perspective:")
+print(f" Sender's balance: {get_trust_line_balance(sender.address, currency_code, issuer.address)}")
+print(f" Receiver's balance: {get_trust_line_balance(receiver.address, currency_code, issuer.address)}")
+print("Issuer's perspective:")
+print(f" Owed to sender: {get_trust_line_balance(issuer.address, currency_code, sender.address)}")
+print(f" Owed to receiver: {get_trust_line_balance(issuer.address, currency_code, receiver.address)}")
diff --git a/_code-samples/send-a-trust-line-token/py/send_trust_line_token_setup.py b/_code-samples/send-a-trust-line-token/py/send_trust_line_token_setup.py
new file mode 100644
index 00000000000..3609bbfa1f2
--- /dev/null
+++ b/_code-samples/send-a-trust-line-token/py/send_trust_line_token_setup.py
@@ -0,0 +1,108 @@
+import asyncio
+import json
+
+from xrpl.asyncio.clients import AsyncWebsocketClient
+from xrpl.asyncio.transaction import submit_and_wait
+from xrpl.asyncio.wallet import generate_faucet_wallet
+from xrpl.models.amounts import IssuedCurrencyAmount
+from xrpl.models.transactions import AccountSet, Payment, TrustSet
+from xrpl.models.transactions.account_set import AccountSetAsfFlag
+
+WSS_URL = "wss://s.altnet.rippletest.net:51233"
+CURRENCY_CODE = "FOO"
+TOTAL_STEPS = 4
+
+
+async def main():
+ async with AsyncWebsocketClient(WSS_URL) as client:
+ print(f"Setting up tutorial: 0/{TOTAL_STEPS}", end="\r")
+
+ # Fund issuer, sender, and receiver wallets from the Testnet faucet in parallel.
+ issuer, sender, receiver = await asyncio.gather(
+ generate_faucet_wallet(client),
+ generate_faucet_wallet(client),
+ generate_faucet_wallet(client),
+ )
+
+ print(f"Setting up tutorial: 1/{TOTAL_STEPS}", end="\r")
+
+ # Enable Default Ripple on the issuer so holders can send
+ # the token to each other.
+ account_set_response = await submit_and_wait(
+ AccountSet(
+ account=issuer.address,
+ set_flag=AccountSetAsfFlag.ASF_DEFAULT_RIPPLE,
+ ),
+ client,
+ issuer,
+ )
+ result_code = account_set_response.result["meta"]["TransactionResult"]
+ if result_code != "tesSUCCESS":
+ raise RuntimeError(f"AccountSet failed: {result_code}")
+
+ print(f"Setting up tutorial: 2/{TOTAL_STEPS}", end="\r")
+
+ # Create a trust line from the sender to the issuer so the sender can hold the token.
+ sender_trust_response = await submit_and_wait(
+ TrustSet(
+ account=sender.address,
+ limit_amount=IssuedCurrencyAmount(
+ currency=CURRENCY_CODE,
+ issuer=issuer.address,
+ value="1000000000",
+ ),
+ ),
+ client,
+ sender,
+ )
+ result_code = sender_trust_response.result["meta"]["TransactionResult"]
+ if result_code != "tesSUCCESS":
+ raise RuntimeError(f"Sender TrustSet failed: {result_code}")
+
+ print(f"Setting up tutorial: 3/{TOTAL_STEPS}", end="\r")
+
+ # Issue the token from the issuer to the sender so the sender has a balance to send.
+ issue_response = await submit_and_wait(
+ Payment(
+ account=issuer.address,
+ destination=sender.address,
+ amount=IssuedCurrencyAmount(
+ currency=CURRENCY_CODE,
+ issuer=issuer.address,
+ value="1000",
+ ),
+ ),
+ client,
+ issuer,
+ )
+ result_code = issue_response.result["meta"]["TransactionResult"]
+ if result_code != "tesSUCCESS":
+ raise RuntimeError(f"Issuer Payment failed: {result_code}")
+
+ print(f"Setting up tutorial: 4/{TOTAL_STEPS}", end="\r")
+
+ # Write setup data to JSON file.
+ setup_data = {
+ "description": "This file is auto-generated by send_trust_line_token_setup.py. It stores XRPL account info for use in the Send a Trust Line Token tutorial.",
+ "issuer": {
+ "address": issuer.address,
+ "seed": issuer.seed,
+ },
+ "sender": {
+ "address": sender.address,
+ "seed": sender.seed,
+ },
+ "receiver": {
+ "address": receiver.address,
+ "seed": receiver.seed,
+ },
+ }
+
+ with open("send_trust_line_token_setup.json", "w") as f:
+ json.dump(setup_data, f, indent=2)
+
+ print("Setting up tutorial: Complete!")
+
+
+if __name__ == "__main__":
+ asyncio.run(main())
diff --git a/_code-samples/send-an-mpt/go/README.md b/_code-samples/send-an-mpt/go/README.md
index 45ceffa4594..d5f1f5cb874 100644
--- a/_code-samples/send-an-mpt/go/README.md
+++ b/_code-samples/send-an-mpt/go/README.md
@@ -1,4 +1,4 @@
-# Send an MPT (Go)
+# Send an MPT (Go)
Example code for sending a Multi-Purpose Token (MPT) between non-issuer holders on testnet with [xrpl-go](https://github.com/Peersyst/xrpl-go).
diff --git a/_code-samples/send-an-mpt/py/send_mpt_setup.py b/_code-samples/send-an-mpt/py/send_mpt_setup.py
index 2ecc93ef188..f17ad1f2c81 100644
--- a/_code-samples/send-an-mpt/py/send_mpt_setup.py
+++ b/_code-samples/send-an-mpt/py/send_mpt_setup.py
@@ -46,7 +46,7 @@ async def main():
account=issuer.address,
asset_scale=2,
maximum_amount="1000000",
- transfer_fee=30,
+ transfer_fee=0,
flags=MPTokenIssuanceCreateFlag.TF_MPT_CAN_TRANSFER,
mptoken_metadata=encode_mptoken_metadata(metadata),
),
diff --git a/docs/img/mt-send-currency-1-empty-form-info.png b/docs/img/mt-send-currency-1-empty-form-info.png
deleted file mode 100644
index 745906dc34d..00000000000
Binary files a/docs/img/mt-send-currency-1-empty-form-info.png and /dev/null differ
diff --git a/docs/img/mt-send-currency-2-distribute-accounts.png b/docs/img/mt-send-currency-2-distribute-accounts.png
deleted file mode 100644
index a5de8f3dd3c..00000000000
Binary files a/docs/img/mt-send-currency-2-distribute-accounts.png and /dev/null differ
diff --git a/docs/img/mt-send-currency-3-create-trustline.png b/docs/img/mt-send-currency-3-create-trustline.png
deleted file mode 100644
index b82411ad3b9..00000000000
Binary files a/docs/img/mt-send-currency-3-create-trustline.png and /dev/null differ
diff --git a/docs/img/mt-send-currency-4-send-currency.png b/docs/img/mt-send-currency-4-send-currency.png
deleted file mode 100644
index ff4190f9a53..00000000000
Binary files a/docs/img/mt-send-currency-4-send-currency.png and /dev/null differ
diff --git a/docs/img/mt-send-currency-5-issuer-token-balance.png b/docs/img/mt-send-currency-5-issuer-token-balance.png
deleted file mode 100644
index efd31358d12..00000000000
Binary files a/docs/img/mt-send-currency-5-issuer-token-balance.png and /dev/null differ
diff --git a/docs/img/mt-send-currency-6-holder-token-balance.png b/docs/img/mt-send-currency-6-holder-token-balance.png
deleted file mode 100644
index f7bca2cb91b..00000000000
Binary files a/docs/img/mt-send-currency-6-holder-token-balance.png and /dev/null differ
diff --git a/docs/tutorials/index.page.tsx b/docs/tutorials/index.page.tsx
index 36317306b1b..53719588834 100644
--- a/docs/tutorials/index.page.tsx
+++ b/docs/tutorials/index.page.tsx
@@ -106,6 +106,7 @@ const sectionConfig: Record
-
- Send Currency
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Send Currency
-
-
-
-