feat(_code-samples): WiP add go tx examples implementation

This commit is contained in:
banasa44
2025-07-17 16:03:19 +02:00
parent 61dd7a8c2d
commit ff5b5ab258
66 changed files with 6555 additions and 12 deletions

View File

@@ -0,0 +1,4 @@
# Batch
Code samples showing how to create and submit a [Batch transaction](../../docs/concepts/transactions/batch-transactions.md).
Both for simple and multi account batch transactions.

View File

@@ -1,5 +1,24 @@
module github.com/XRPLF
go 1.23
go 1.23.0
toolchain go1.23.10
require github.com/Peersyst/xrpl-go v0.1.11
require (
github.com/FactomProject/basen v0.0.0-20150613233007-fe3947df716e // indirect
github.com/FactomProject/btcutilecc v0.0.0-20130527213604-d3a63a5752ec // indirect
github.com/btcsuite/btcd/btcec/v2 v2.3.4 // indirect
github.com/decred/dcrd/crypto/ripemd160 v1.0.2 // indirect
github.com/decred/dcrd/dcrec/secp256k1/v4 v4.3.0 // indirect
github.com/gorilla/websocket v1.5.0 // indirect
github.com/json-iterator/go v1.1.12 // indirect
github.com/mitchellh/mapstructure v1.5.0 // indirect
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421 // indirect
github.com/modern-go/reflect2 v1.0.2 // indirect
github.com/tyler-smith/go-bip32 v1.0.0 // indirect
github.com/tyler-smith/go-bip39 v1.1.0 // indirect
github.com/ugorji/go/codec v1.2.11 // indirect
golang.org/x/crypto v0.23.0 // indirect
)

View File

@@ -0,0 +1,58 @@
github.com/FactomProject/basen v0.0.0-20150613233007-fe3947df716e h1:ahyvB3q25YnZWly5Gq1ekg6jcmWaGj/vG/MhF4aisoc=
github.com/FactomProject/basen v0.0.0-20150613233007-fe3947df716e/go.mod h1:kGUqhHd//musdITWjFvNTHn90WG9bMLBEPQZ17Cmlpw=
github.com/FactomProject/btcutilecc v0.0.0-20130527213604-d3a63a5752ec h1:1Qb69mGp/UtRPn422BH4/Y4Q3SLUrD9KHuDkm8iodFc=
github.com/FactomProject/btcutilecc v0.0.0-20130527213604-d3a63a5752ec/go.mod h1:CD8UlnlLDiqb36L110uqiP2iSflVjx9g/3U9hCI4q2U=
github.com/Peersyst/xrpl-go v0.1.11 h1:P6r/gHxRnbAtAdPmzNHz/7zpsdfvwh0SS+QI2JNT44w=
github.com/Peersyst/xrpl-go v0.1.11/go.mod h1:CBRM3/soqNeeL2Jx6USVUtECqulZVUoq3UxZKMz9hdw=
github.com/btcsuite/btcd/btcec/v2 v2.3.4 h1:3EJjcN70HCu/mwqlUsGK8GcNVyLVxFDlWurTXGPFfiQ=
github.com/btcsuite/btcd/btcec/v2 v2.3.4/go.mod h1:zYzJ8etWJQIv1Ogk7OzpWjowwOdXY1W/17j2MW85J04=
github.com/cmars/basen v0.0.0-20150613233007-fe3947df716e h1:0XBUw73chJ1VYSsfvcPvVT7auykAJce9FpRr10L6Qhw=
github.com/cmars/basen v0.0.0-20150613233007-fe3947df716e/go.mod h1:P13beTBKr5Q18lJe1rIoLUqjM+CB1zYrRg44ZqGuQSA=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/decred/dcrd/crypto/blake256 v1.0.1 h1:7PltbUIQB7u/FfZ39+DGa/ShuMyJ5ilcvdfma9wOH6Y=
github.com/decred/dcrd/crypto/blake256 v1.0.1/go.mod h1:2OfgNZ5wDpcsFmHmCK5gZTPcCXqlm2ArzUIkw9czNJo=
github.com/decred/dcrd/crypto/ripemd160 v1.0.2 h1:TvGTmUBHDU75OHro9ojPLK+Yv7gDl2hnUvRocRCjsys=
github.com/decred/dcrd/crypto/ripemd160 v1.0.2/go.mod h1:uGfjDyePSpa75cSQLzNdVmWlbQMBuiJkvXw/MNKRY4M=
github.com/decred/dcrd/dcrec/secp256k1/v4 v4.3.0 h1:rpfIENRNNilwHwZeG5+P150SMrnNEcHYvcCuK6dPZSg=
github.com/decred/dcrd/dcrec/secp256k1/v4 v4.3.0/go.mod h1:v57UDF4pDQJcEfFUCRop3lJL149eHGSe9Jvczhzjo/0=
github.com/golang/mock v1.6.0 h1:ErTB+efbowRARo13NNdxyJji2egdxLGQhRaY+DUumQc=
github.com/golang/mock v1.6.0/go.mod h1:p6yTPP+5HYm5mzsMV8JkE6ZKdX+/wYM6Hr+LicevLPs=
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
github.com/gorilla/websocket v1.5.0 h1:PPwGk2jz7EePpoHN/+ClbZu8SPxiqlu12wZP/3sWmnc=
github.com/gorilla/websocket v1.5.0/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM=
github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo=
github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyuac5Z2hdY=
github.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo=
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421 h1:ZqeYNhU3OHLH3mGKHDcjJRFFRrJa6eAM5H+CtDdOsPc=
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M=
github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/testify v1.1.5-0.20170601210322-f6abca593680/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk=
github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
github.com/tyler-smith/go-bip32 v1.0.0 h1:sDR9juArbUgX+bO/iblgZnMPeWY1KZMUC2AFUJdv5KE=
github.com/tyler-smith/go-bip32 v1.0.0/go.mod h1:onot+eHknzV4BVPwrzqY5OoVpyCvnwD7lMawL5aQupE=
github.com/tyler-smith/go-bip39 v1.1.0 h1:5eUemwrMargf3BSLRRCalXT93Ns6pQJIjYQN2nyfOP8=
github.com/tyler-smith/go-bip39 v1.1.0/go.mod h1:gUYDtqQw1JS3ZJ8UWVcGTGqqr6YIN3CWg+kkNaLt55U=
github.com/ugorji/go/codec v1.2.11 h1:BMaWp1Bb6fHwEtbplGBGJ498wD+LKlNSl25MjdZY4dU=
github.com/ugorji/go/codec v1.2.11/go.mod h1:UNopzCgEMSXjBc6AOMqYvWC1ktqTAfzJZUZgYf6w6lg=
golang.org/x/crypto v0.0.0-20170613210332-850760c427c5/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/crypto v0.23.0 h1:dIJU/v2J8Mdglj/8rJ6UUOM3Zc9zLZxVZwwxMooUSAI=
golang.org/x/crypto v0.23.0/go.mod h1:CKFgDieR+mRhux2Lsu27y0fO304Db0wZe70UKqHu0v8=
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
launchpad.net/gocheck v0.0.0-20140225173054-000000000087 h1:Izowp2XBH6Ya6rv+hqbceQyw/gSGoXfH/UPoTGduL54=
launchpad.net/gocheck v0.0.0-20140225173054-000000000087/go.mod h1:hj7XX3B/0A+80Vse0e+BUHsHMTEhd0O4cpUHr/e/BUM=

View File

@@ -1 +1,208 @@
package rpc
package main
import (
"fmt"
"github.com/Peersyst/xrpl-go/pkg/crypto"
"github.com/Peersyst/xrpl-go/xrpl/faucet"
"github.com/Peersyst/xrpl-go/xrpl/rpc"
"github.com/Peersyst/xrpl-go/xrpl/rpc/types"
"github.com/Peersyst/xrpl-go/xrpl/transaction"
txnTypes "github.com/Peersyst/xrpl-go/xrpl/transaction/types"
"github.com/Peersyst/xrpl-go/xrpl/wallet"
)
var (
CreatePaymentTx = func(sender, receiver *wallet.Wallet, amount txnTypes.CurrencyAmount) *transaction.Payment {
return &transaction.Payment{
BaseTx: transaction.BaseTx{
Account: sender.GetAddress(),
TransactionType: transaction.PaymentTx,
Flags: txnTypes.TfInnerBatchTxn,
},
Amount: amount,
Destination: receiver.GetAddress(),
}
}
)
func main() {
// Configure the client
cfg, err := rpc.NewClientConfig(
"https://s.devnet.rippletest.net:51234/",
rpc.WithFaucetProvider(faucet.NewDevnetFaucetProvider()),
)
if err != nil {
panic(err)
}
client := rpc.NewClient(cfg)
// Create and fund wallets
userWallet, err := wallet.New(crypto.ED25519())
if err != nil {
fmt.Println(err)
return
}
user2Wallet, err := wallet.New(crypto.ED25519())
if err != nil {
fmt.Println(err)
return
}
receiverWallet, err := wallet.New(crypto.ED25519())
if err != nil {
fmt.Println(err)
return
}
fmt.Println("⏳ Funding wallets...")
if err := client.FundWallet(&userWallet); err != nil {
fmt.Println(err)
return
}
if err := client.FundWallet(&user2Wallet); err != nil {
fmt.Println(err)
return
}
fmt.Println("💸 Wallets funded")
// Check initial balances
userBalance, err := client.GetXrpBalance(userWallet.ClassicAddress)
if err != nil {
userBalance = "0"
}
user2Balance, err := client.GetXrpBalance(user2Wallet.ClassicAddress)
if err != nil {
user2Balance = "0"
}
receiverBalance, err := client.GetXrpBalance(receiverWallet.ClassicAddress)
if err != nil {
receiverBalance = "0"
}
fmt.Printf("💳 User initial balance: %s XRP\n", userBalance)
fmt.Printf("💳 User2 initial balance: %s XRP\n", user2Balance)
fmt.Printf("💳 Receiver initial balance: %s XRP\n", receiverBalance)
fmt.Println()
fmt.Printf("Batch transaction test\n")
// Create test batch transaction
batchTx := &transaction.Batch{
BaseTx: transaction.BaseTx{
Account: txnTypes.Address(userWallet.ClassicAddress),
TransactionType: transaction.BatchTx,
},
RawTransactions: []txnTypes.RawTransaction{
{RawTransaction: CreatePaymentTx(&userWallet, &receiverWallet, txnTypes.XRPCurrencyAmount(5000000)).Flatten()},
{RawTransaction: CreatePaymentTx(&userWallet, &receiverWallet, txnTypes.XRPCurrencyAmount(5000000)).Flatten()},
},
}
batchTx.SetAllOrNothingFlag()
flattenedBatchTx := batchTx.Flatten()
fmt.Println("⏳ Autofilling flattened batch transaction...")
if err := client.Autofill(&flattenedBatchTx); err != nil {
fmt.Println("Autofill error:", err)
return
}
fmt.Println("⏳ Signing batch transaction...")
response, err := client.SubmitTxAndWait(flattenedBatchTx, &types.SubmitOptions{
Autofill: false,
Wallet: &userWallet,
})
if err != nil {
fmt.Println(err)
return
}
fmt.Println("✅ Batch transaction submitted")
fmt.Printf("🌐 Hash: %s\n", response.Hash.String())
fmt.Printf("🌐 Validated: %t\n", response.Validated)
fmt.Println()
// Check final balances
finalUserBalance, err := client.GetXrpBalance(userWallet.ClassicAddress)
if err != nil {
finalUserBalance = "0"
}
finalReceiverBalance, err := client.GetXrpBalance(receiverWallet.ClassicAddress)
if err != nil {
finalReceiverBalance = "0"
}
fmt.Printf("💳 User final balance: %s XRP\n", finalUserBalance)
fmt.Printf("💳 Receiver final balance: %s XRP\n", finalReceiverBalance)
fmt.Println()
fmt.Printf("Multisig Batch transaction test\n")
// Create test batch transaction
multiBatchTx := &transaction.Batch{
BaseTx: transaction.BaseTx{
Account: txnTypes.Address(userWallet.ClassicAddress),
TransactionType: transaction.BatchTx,
},
RawTransactions: []txnTypes.RawTransaction{
{RawTransaction: CreatePaymentTx(&userWallet, &receiverWallet, txnTypes.XRPCurrencyAmount(5000000)).Flatten()},
{RawTransaction: CreatePaymentTx(&user2Wallet, &receiverWallet, txnTypes.XRPCurrencyAmount(5000000)).Flatten()},
},
BatchSigners: []txnTypes.BatchSigner{
{
BatchSigner: txnTypes.BatchSignerData{
Account: txnTypes.Address(user2Wallet.ClassicAddress),
SigningPubKey: user2Wallet.PublicKey,
},
},
},
}
multiBatchTx.SetAllOrNothingFlag()
flattenedMultiBatchTx := multiBatchTx.Flatten()
fmt.Println("⏳ Autofilling flattened multi batch transaction...")
if err := client.AutofillMultisigned(&flattenedMultiBatchTx, 1); err != nil {
fmt.Println("Autofill error:", err)
return
}
fmt.Println("⏳ Signing multi batch transaction...")
if err := wallet.SignMultiBatch(user2Wallet, &flattenedMultiBatchTx, nil); err != nil {
fmt.Println("Signing error:", err)
return
}
response, err = client.SubmitTxAndWait(flattenedMultiBatchTx, &types.SubmitOptions{
Autofill: false,
Wallet: &userWallet,
})
if err != nil {
fmt.Println(err)
return
}
fmt.Println("✅ Multisig Batch transaction submitted")
fmt.Printf("🌐 Hash: %s\n", response.Hash.String())
fmt.Printf("🌐 Validated: %t\n", response.Validated)
fmt.Println()
// Check final balances
finalUser2Balance, err := client.GetXrpBalance(user2Wallet.ClassicAddress)
if err != nil {
finalUser2Balance = "0"
}
finalUserBalance, err = client.GetXrpBalance(userWallet.ClassicAddress)
if err != nil {
finalUserBalance = "0"
}
finalReceiverBalance, err = client.GetXrpBalance(receiverWallet.ClassicAddress)
if err != nil {
finalReceiverBalance = "0"
}
fmt.Printf("💳 User final balance: %s XRP\n", finalUserBalance)
fmt.Printf("💳 User2 final balance: %s XRP\n", finalUser2Balance)
fmt.Printf("💳 Receiver final balance: %s XRP\n", finalReceiverBalance)
}

View File

@@ -1 +1,210 @@
package ws
package main
import (
"fmt"
"github.com/Peersyst/xrpl-go/pkg/crypto"
"github.com/Peersyst/xrpl-go/xrpl/faucet"
"github.com/Peersyst/xrpl-go/xrpl/transaction"
txnTypes "github.com/Peersyst/xrpl-go/xrpl/transaction/types"
"github.com/Peersyst/xrpl-go/xrpl/wallet"
"github.com/Peersyst/xrpl-go/xrpl/websocket"
"github.com/Peersyst/xrpl-go/xrpl/websocket/types"
)
var (
CreatePaymentTx = func(sender, receiver *wallet.Wallet, amount txnTypes.CurrencyAmount) *transaction.Payment {
return &transaction.Payment{
BaseTx: transaction.BaseTx{
Account: sender.GetAddress(),
TransactionType: transaction.PaymentTx,
Flags: txnTypes.TfInnerBatchTxn,
},
Amount: amount,
Destination: receiver.GetAddress(),
}
}
)
func main() {
// Connect to testnet
client := websocket.NewClient(
websocket.NewClientConfig().
WithHost("wss://s.devnet.rippletest.net:51233").
WithFaucetProvider(faucet.NewDevnetFaucetProvider()),
)
defer client.Disconnect()
if err := client.Connect(); err != nil {
fmt.Println(err)
return
}
// Create and fund wallets
userWallet, err := wallet.New(crypto.ED25519())
if err != nil {
fmt.Println(err)
return
}
user2Wallet, err := wallet.New(crypto.ED25519())
if err != nil {
fmt.Println(err)
return
}
receiverWallet, err := wallet.New(crypto.ED25519())
if err != nil {
fmt.Println(err)
return
}
fmt.Println("⏳ Funding wallets...")
if err := client.FundWallet(&userWallet); err != nil {
fmt.Println(err)
return
}
if err := client.FundWallet(&user2Wallet); err != nil {
fmt.Println(err)
return
}
fmt.Println("💸 Wallets funded")
// Check initial balances
userBalance, err := client.GetXrpBalance(userWallet.ClassicAddress)
if err != nil {
userBalance = "0"
}
user2Balance, err := client.GetXrpBalance(user2Wallet.ClassicAddress)
if err != nil {
user2Balance = "0"
}
receiverBalance, err := client.GetXrpBalance(receiverWallet.ClassicAddress)
if err != nil {
receiverBalance = "0"
}
fmt.Printf("💳 User initial balance: %s XRP\n", userBalance)
fmt.Printf("💳 User2 initial balance: %s XRP\n", user2Balance)
fmt.Printf("💳 Receiver initial balance: %s XRP\n", receiverBalance)
fmt.Println()
fmt.Printf("Batch transaction test\n")
// Create test batch transaction
batchTx := &transaction.Batch{
BaseTx: transaction.BaseTx{
Account: txnTypes.Address(userWallet.ClassicAddress),
TransactionType: transaction.BatchTx,
},
RawTransactions: []txnTypes.RawTransaction{
{RawTransaction: CreatePaymentTx(&userWallet, &receiverWallet, txnTypes.XRPCurrencyAmount(5000000)).Flatten()},
{RawTransaction: CreatePaymentTx(&userWallet, &receiverWallet, txnTypes.XRPCurrencyAmount(5000000)).Flatten()},
},
}
batchTx.SetAllOrNothingFlag()
flattenedBatchTx := batchTx.Flatten()
fmt.Println("⏳ Autofilling flattened batch transaction...")
if err := client.Autofill(&flattenedBatchTx); err != nil {
fmt.Println("Autofill error:", err)
return
}
fmt.Println("⏳ Signing batch transaction...")
response, err := client.SubmitTxAndWait(flattenedBatchTx, &types.SubmitOptions{
Autofill: false,
Wallet: &userWallet,
})
if err != nil {
fmt.Println(err)
return
}
fmt.Println("✅ Batch transaction submitted")
fmt.Printf("🌐 Hash: %s\n", response.Hash.String())
fmt.Printf("🌐 Validated: %t\n", response.Validated)
fmt.Println()
// Check final balances
finalUserBalance, err := client.GetXrpBalance(userWallet.ClassicAddress)
if err != nil {
finalUserBalance = "0"
}
finalReceiverBalance, err := client.GetXrpBalance(receiverWallet.ClassicAddress)
if err != nil {
finalReceiverBalance = "0"
}
fmt.Printf("💳 User final balance: %s XRP\n", finalUserBalance)
fmt.Printf("💳 Receiver final balance: %s XRP\n", finalReceiverBalance)
fmt.Println()
fmt.Printf("Multisig Batch transaction test\n")
// Create test batch transaction
multiBatchTx := &transaction.Batch{
BaseTx: transaction.BaseTx{
Account: txnTypes.Address(userWallet.ClassicAddress),
TransactionType: transaction.BatchTx,
},
RawTransactions: []txnTypes.RawTransaction{
{RawTransaction: CreatePaymentTx(&userWallet, &receiverWallet, txnTypes.XRPCurrencyAmount(5000000)).Flatten()},
{RawTransaction: CreatePaymentTx(&user2Wallet, &receiverWallet, txnTypes.XRPCurrencyAmount(5000000)).Flatten()},
},
BatchSigners: []txnTypes.BatchSigner{
{
BatchSigner: txnTypes.BatchSignerData{
Account: txnTypes.Address(user2Wallet.ClassicAddress),
SigningPubKey: user2Wallet.PublicKey,
},
},
},
}
multiBatchTx.SetAllOrNothingFlag()
flattenedMultiBatchTx := multiBatchTx.Flatten()
fmt.Println("⏳ Autofilling flattened multi batch transaction...")
if err := client.AutofillMultisigned(&flattenedMultiBatchTx, 1); err != nil {
fmt.Println("Autofill error:", err)
return
}
fmt.Println("⏳ Signing multi batch transaction...")
if err := wallet.SignMultiBatch(user2Wallet, &flattenedMultiBatchTx, nil); err != nil {
fmt.Println("Signing error:", err)
return
}
response, err = client.SubmitTxAndWait(flattenedMultiBatchTx, &types.SubmitOptions{
Autofill: false,
Wallet: &userWallet,
})
if err != nil {
fmt.Println(err)
return
}
fmt.Println("✅ Multisig Batch transaction submitted")
fmt.Printf("🌐 Hash: %s\n", response.Hash.String())
fmt.Printf("🌐 Validated: %t\n", response.Validated)
fmt.Println()
// Check final balances
finalUser2Balance, err := client.GetXrpBalance(user2Wallet.ClassicAddress)
if err != nil {
finalUser2Balance = "0"
}
finalUserBalance, err = client.GetXrpBalance(userWallet.ClassicAddress)
if err != nil {
finalUserBalance = "0"
}
finalReceiverBalance, err = client.GetXrpBalance(receiverWallet.ClassicAddress)
if err != nil {
finalReceiverBalance = "0"
}
fmt.Printf("💳 User final balance: %s XRP\n", finalUserBalance)
fmt.Printf("💳 User2 final balance: %s XRP\n", finalUser2Balance)
fmt.Printf("💳 Receiver final balance: %s XRP\n", finalReceiverBalance)
}

View File

@@ -1,5 +1,24 @@
module github.com/XRPLF
go 1.23
go 1.23.0
toolchain go1.23.10
require github.com/Peersyst/xrpl-go v0.1.11
require (
github.com/FactomProject/basen v0.0.0-20150613233007-fe3947df716e // indirect
github.com/FactomProject/btcutilecc v0.0.0-20130527213604-d3a63a5752ec // indirect
github.com/btcsuite/btcd/btcec/v2 v2.3.4 // indirect
github.com/decred/dcrd/crypto/ripemd160 v1.0.2 // indirect
github.com/decred/dcrd/dcrec/secp256k1/v4 v4.3.0 // indirect
github.com/gorilla/websocket v1.5.0 // indirect
github.com/json-iterator/go v1.1.12 // indirect
github.com/mitchellh/mapstructure v1.5.0 // indirect
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421 // indirect
github.com/modern-go/reflect2 v1.0.2 // indirect
github.com/tyler-smith/go-bip32 v1.0.0 // indirect
github.com/tyler-smith/go-bip39 v1.1.0 // indirect
github.com/ugorji/go/codec v1.2.11 // indirect
golang.org/x/crypto v0.23.0 // indirect
)

View File

@@ -0,0 +1,58 @@
github.com/FactomProject/basen v0.0.0-20150613233007-fe3947df716e h1:ahyvB3q25YnZWly5Gq1ekg6jcmWaGj/vG/MhF4aisoc=
github.com/FactomProject/basen v0.0.0-20150613233007-fe3947df716e/go.mod h1:kGUqhHd//musdITWjFvNTHn90WG9bMLBEPQZ17Cmlpw=
github.com/FactomProject/btcutilecc v0.0.0-20130527213604-d3a63a5752ec h1:1Qb69mGp/UtRPn422BH4/Y4Q3SLUrD9KHuDkm8iodFc=
github.com/FactomProject/btcutilecc v0.0.0-20130527213604-d3a63a5752ec/go.mod h1:CD8UlnlLDiqb36L110uqiP2iSflVjx9g/3U9hCI4q2U=
github.com/Peersyst/xrpl-go v0.1.11 h1:P6r/gHxRnbAtAdPmzNHz/7zpsdfvwh0SS+QI2JNT44w=
github.com/Peersyst/xrpl-go v0.1.11/go.mod h1:CBRM3/soqNeeL2Jx6USVUtECqulZVUoq3UxZKMz9hdw=
github.com/btcsuite/btcd/btcec/v2 v2.3.4 h1:3EJjcN70HCu/mwqlUsGK8GcNVyLVxFDlWurTXGPFfiQ=
github.com/btcsuite/btcd/btcec/v2 v2.3.4/go.mod h1:zYzJ8etWJQIv1Ogk7OzpWjowwOdXY1W/17j2MW85J04=
github.com/cmars/basen v0.0.0-20150613233007-fe3947df716e h1:0XBUw73chJ1VYSsfvcPvVT7auykAJce9FpRr10L6Qhw=
github.com/cmars/basen v0.0.0-20150613233007-fe3947df716e/go.mod h1:P13beTBKr5Q18lJe1rIoLUqjM+CB1zYrRg44ZqGuQSA=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/decred/dcrd/crypto/blake256 v1.0.1 h1:7PltbUIQB7u/FfZ39+DGa/ShuMyJ5ilcvdfma9wOH6Y=
github.com/decred/dcrd/crypto/blake256 v1.0.1/go.mod h1:2OfgNZ5wDpcsFmHmCK5gZTPcCXqlm2ArzUIkw9czNJo=
github.com/decred/dcrd/crypto/ripemd160 v1.0.2 h1:TvGTmUBHDU75OHro9ojPLK+Yv7gDl2hnUvRocRCjsys=
github.com/decred/dcrd/crypto/ripemd160 v1.0.2/go.mod h1:uGfjDyePSpa75cSQLzNdVmWlbQMBuiJkvXw/MNKRY4M=
github.com/decred/dcrd/dcrec/secp256k1/v4 v4.3.0 h1:rpfIENRNNilwHwZeG5+P150SMrnNEcHYvcCuK6dPZSg=
github.com/decred/dcrd/dcrec/secp256k1/v4 v4.3.0/go.mod h1:v57UDF4pDQJcEfFUCRop3lJL149eHGSe9Jvczhzjo/0=
github.com/golang/mock v1.6.0 h1:ErTB+efbowRARo13NNdxyJji2egdxLGQhRaY+DUumQc=
github.com/golang/mock v1.6.0/go.mod h1:p6yTPP+5HYm5mzsMV8JkE6ZKdX+/wYM6Hr+LicevLPs=
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
github.com/gorilla/websocket v1.5.0 h1:PPwGk2jz7EePpoHN/+ClbZu8SPxiqlu12wZP/3sWmnc=
github.com/gorilla/websocket v1.5.0/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM=
github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo=
github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyuac5Z2hdY=
github.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo=
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421 h1:ZqeYNhU3OHLH3mGKHDcjJRFFRrJa6eAM5H+CtDdOsPc=
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M=
github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/testify v1.1.5-0.20170601210322-f6abca593680/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk=
github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
github.com/tyler-smith/go-bip32 v1.0.0 h1:sDR9juArbUgX+bO/iblgZnMPeWY1KZMUC2AFUJdv5KE=
github.com/tyler-smith/go-bip32 v1.0.0/go.mod h1:onot+eHknzV4BVPwrzqY5OoVpyCvnwD7lMawL5aQupE=
github.com/tyler-smith/go-bip39 v1.1.0 h1:5eUemwrMargf3BSLRRCalXT93Ns6pQJIjYQN2nyfOP8=
github.com/tyler-smith/go-bip39 v1.1.0/go.mod h1:gUYDtqQw1JS3ZJ8UWVcGTGqqr6YIN3CWg+kkNaLt55U=
github.com/ugorji/go/codec v1.2.11 h1:BMaWp1Bb6fHwEtbplGBGJ498wD+LKlNSl25MjdZY4dU=
github.com/ugorji/go/codec v1.2.11/go.mod h1:UNopzCgEMSXjBc6AOMqYvWC1ktqTAfzJZUZgYf6w6lg=
golang.org/x/crypto v0.0.0-20170613210332-850760c427c5/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/crypto v0.23.0 h1:dIJU/v2J8Mdglj/8rJ6UUOM3Zc9zLZxVZwwxMooUSAI=
golang.org/x/crypto v0.23.0/go.mod h1:CKFgDieR+mRhux2Lsu27y0fO304Db0wZe70UKqHu0v8=
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
launchpad.net/gocheck v0.0.0-20140225173054-000000000087 h1:Izowp2XBH6Ya6rv+hqbceQyw/gSGoXfH/UPoTGduL54=
launchpad.net/gocheck v0.0.0-20140225173054-000000000087/go.mod h1:hj7XX3B/0A+80Vse0e+BUHsHMTEhd0O4cpUHr/e/BUM=

View File

@@ -1 +1,162 @@
package rpc
package main
import (
"fmt"
"github.com/Peersyst/xrpl-go/pkg/crypto"
"github.com/Peersyst/xrpl-go/xrpl/faucet"
"github.com/Peersyst/xrpl-go/xrpl/ledger-entry-types"
"github.com/Peersyst/xrpl-go/xrpl/rpc"
"github.com/Peersyst/xrpl-go/xrpl/transaction"
"github.com/Peersyst/xrpl-go/xrpl/transaction/types"
"github.com/Peersyst/xrpl-go/xrpl/wallet"
)
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)
w, err := wallet.New(crypto.ED25519())
if err != nil {
fmt.Println(err)
return
}
receiverWallet, err := wallet.New(crypto.ED25519())
if err != nil {
fmt.Println(err)
return
}
fmt.Println("⏳ Setting up wallets...")
if err := client.FundWallet(&w); err != nil {
fmt.Println(err)
return
}
fmt.Println("💸 Sender wallet funded!")
if err := client.FundWallet(&receiverWallet); err != nil {
fmt.Println(err)
return
}
fmt.Println("💸 Receiver wallet funded!")
fmt.Println()
fmt.Println("✅ Wallets setup complete!")
fmt.Println("💳 Sender wallet:", w.ClassicAddress)
fmt.Println("💳 Receiver wallet:", receiverWallet.ClassicAddress)
fmt.Println()
fmt.Println("⏳ Creating check...")
cc := &transaction.CheckCreate{
BaseTx: transaction.BaseTx{
Account: w.GetAddress(),
},
Destination: receiverWallet.GetAddress(),
SendMax: types.XRPCurrencyAmount(1000000),
InvoiceID: "46060241FABCF692D4D934BA2A6C4427CD4279083E38C77CBE642243E43BE291",
}
flatCc := cc.Flatten()
if err := client.Autofill(&flatCc); err != nil {
fmt.Println(err)
return
}
blob, _, err := w.Sign(flatCc)
if err != nil {
fmt.Println(err)
return
}
res, err := client.SubmitTxBlobAndWait(blob, false)
if err != nil {
fmt.Println(err)
return
}
if !res.Validated {
fmt.Println("❌ Check creation failed!")
fmt.Println("Try again!")
fmt.Println()
return
}
fmt.Println("✅ Check created!")
fmt.Printf("🌐 Hash: %s\n", res.Hash.String())
fmt.Println()
meta, ok := res.Meta.(map[string]interface{})
if !ok {
fmt.Println("❌ Meta is not of type TxObjMeta")
return
}
var checkID string
affectedNodes := meta["AffectedNodes"].([]interface{})
for _, node := range affectedNodes {
affectedNode, ok := node.(map[string]interface{})
if !ok {
fmt.Println("❌ Node is not of type map[string]interface{}")
return
}
createdNode, ok := affectedNode["CreatedNode"].(map[string]interface{})
if !ok {
continue
}
if createdNode["LedgerEntryType"] == string(ledger.CheckEntry) {
checkID = createdNode["LedgerIndex"].(string)
}
}
if checkID == "" {
fmt.Println("Check not found")
return
}
fmt.Println("⏳ Cashing out check...")
checkCash := &transaction.CheckCash{
BaseTx: transaction.BaseTx{
Account: receiverWallet.GetAddress(),
},
CheckID: types.Hash256(checkID),
Amount: types.XRPCurrencyAmount(1000000),
}
flatCheckCash := checkCash.Flatten()
if err := client.Autofill(&flatCheckCash); err != nil {
fmt.Println(err)
return
}
blob, _, err = receiverWallet.Sign(flatCheckCash)
if err != nil {
fmt.Println(err)
return
}
res, err = client.SubmitTxBlobAndWait(blob, false)
if err != nil {
fmt.Println(err)
return
}
fmt.Println("✅ Check cashed out!")
fmt.Printf("🌐 Hash: %s\n", res.Hash.String())
fmt.Println()
}

View File

@@ -1 +1,173 @@
package ws
package main
import (
"fmt"
"github.com/Peersyst/xrpl-go/pkg/crypto"
"github.com/Peersyst/xrpl-go/xrpl/faucet"
"github.com/Peersyst/xrpl-go/xrpl/ledger-entry-types"
"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"
)
func main() {
fmt.Println("⏳ Connecting to testnet...")
client := websocket.NewClient(
websocket.NewClientConfig().
WithHost("wss://s.altnet.rippletest.net:51233").
WithFaucetProvider(faucet.NewTestnetFaucetProvider()),
)
defer client.Disconnect()
if err := client.Connect(); err != nil {
fmt.Println(err)
return
}
if !client.IsConnected() {
fmt.Println("❌ Failed to connect to testnet")
return
}
fmt.Println("✅ Connected to testnet")
fmt.Println()
w, err := wallet.New(crypto.ED25519())
if err != nil {
fmt.Println(err)
return
}
receiverWallet, err := wallet.New(crypto.ED25519())
if err != nil {
fmt.Println(err)
return
}
fmt.Println("⏳ Setting up wallets...")
if err := client.FundWallet(&w); err != nil {
fmt.Println(err)
return
}
fmt.Println("💸 Sender wallet funded!")
if err := client.FundWallet(&receiverWallet); err != nil {
fmt.Println(err)
return
}
fmt.Println("💸 Receiver wallet funded!")
fmt.Println()
fmt.Println("✅ Wallets setup complete!")
fmt.Println("💳 Sender wallet:", w.ClassicAddress)
fmt.Println("💳 Receiver wallet:", receiverWallet.ClassicAddress)
fmt.Println()
fmt.Println("⏳ Creating check...")
cc := &transaction.CheckCreate{
BaseTx: transaction.BaseTx{
Account: w.GetAddress(),
},
Destination: receiverWallet.GetAddress(),
SendMax: types.XRPCurrencyAmount(1000000),
InvoiceID: "46060241FABCF692D4D934BA2A6C4427CD4279083E38C77CBE642243E43BE291",
}
flatCc := cc.Flatten()
if err := client.Autofill(&flatCc); err != nil {
fmt.Println(err)
return
}
blob, _, err := w.Sign(flatCc)
if err != nil {
fmt.Println(err)
return
}
res, err := client.SubmitTxBlobAndWait(blob, false)
if err != nil {
fmt.Println(err)
return
}
if !res.Validated {
fmt.Println("❌ Check creation failed!")
fmt.Println("Try again!")
fmt.Println()
return
}
fmt.Println("✅ Check created!")
fmt.Printf("🌐 Hash: %s\n", res.Hash.String())
fmt.Println()
meta, ok := res.Meta.(map[string]interface{})
if !ok {
fmt.Println("❌ Meta is not of type TxObjMeta")
return
}
var checkID string
affectedNodes := meta["AffectedNodes"].([]interface{})
for _, node := range affectedNodes {
affectedNode, ok := node.(map[string]interface{})
if !ok {
fmt.Println("❌ Node is not of type map[string]interface{}")
return
}
createdNode, ok := affectedNode["CreatedNode"].(map[string]interface{})
if !ok {
continue
}
if createdNode["LedgerEntryType"] == string(ledger.CheckEntry) {
checkID = createdNode["LedgerIndex"].(string)
}
}
if checkID == "" {
fmt.Println("Check not found")
return
}
fmt.Println("⏳ Cashing out check...")
checkCash := &transaction.CheckCash{
BaseTx: transaction.BaseTx{
Account: receiverWallet.GetAddress(),
},
CheckID: types.Hash256(checkID),
Amount: types.XRPCurrencyAmount(1000000),
}
flatCheckCash := checkCash.Flatten()
if err := client.Autofill(&flatCheckCash); err != nil {
fmt.Println(err)
return
}
blob, _, err = receiverWallet.Sign(flatCheckCash)
if err != nil {
fmt.Println(err)
return
}
res, err = client.SubmitTxBlobAndWait(blob, false)
if err != nil {
fmt.Println(err)
return
}
fmt.Println("✅ Check cashed out!")
fmt.Printf("🌐 Hash: %s\n", res.Hash.String())
fmt.Println()
}

View File

@@ -0,0 +1,3 @@
# Clawback
Create, configure, and execute a Clawback transaction to reclaim issued tokens from a trust line on the XRPL.

View File

@@ -1,5 +1,24 @@
module github.com/XRPLF
go 1.23
go 1.23.0
toolchain go1.23.10
require github.com/Peersyst/xrpl-go v0.1.11
require (
github.com/FactomProject/basen v0.0.0-20150613233007-fe3947df716e // indirect
github.com/FactomProject/btcutilecc v0.0.0-20130527213604-d3a63a5752ec // indirect
github.com/btcsuite/btcd/btcec/v2 v2.3.4 // indirect
github.com/decred/dcrd/crypto/ripemd160 v1.0.2 // indirect
github.com/decred/dcrd/dcrec/secp256k1/v4 v4.3.0 // indirect
github.com/gorilla/websocket v1.5.0 // indirect
github.com/json-iterator/go v1.1.12 // indirect
github.com/mitchellh/mapstructure v1.5.0 // indirect
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421 // indirect
github.com/modern-go/reflect2 v1.0.2 // indirect
github.com/tyler-smith/go-bip32 v1.0.0 // indirect
github.com/tyler-smith/go-bip39 v1.1.0 // indirect
github.com/ugorji/go/codec v1.2.11 // indirect
golang.org/x/crypto v0.23.0 // indirect
)

View File

@@ -0,0 +1,58 @@
github.com/FactomProject/basen v0.0.0-20150613233007-fe3947df716e h1:ahyvB3q25YnZWly5Gq1ekg6jcmWaGj/vG/MhF4aisoc=
github.com/FactomProject/basen v0.0.0-20150613233007-fe3947df716e/go.mod h1:kGUqhHd//musdITWjFvNTHn90WG9bMLBEPQZ17Cmlpw=
github.com/FactomProject/btcutilecc v0.0.0-20130527213604-d3a63a5752ec h1:1Qb69mGp/UtRPn422BH4/Y4Q3SLUrD9KHuDkm8iodFc=
github.com/FactomProject/btcutilecc v0.0.0-20130527213604-d3a63a5752ec/go.mod h1:CD8UlnlLDiqb36L110uqiP2iSflVjx9g/3U9hCI4q2U=
github.com/Peersyst/xrpl-go v0.1.11 h1:P6r/gHxRnbAtAdPmzNHz/7zpsdfvwh0SS+QI2JNT44w=
github.com/Peersyst/xrpl-go v0.1.11/go.mod h1:CBRM3/soqNeeL2Jx6USVUtECqulZVUoq3UxZKMz9hdw=
github.com/btcsuite/btcd/btcec/v2 v2.3.4 h1:3EJjcN70HCu/mwqlUsGK8GcNVyLVxFDlWurTXGPFfiQ=
github.com/btcsuite/btcd/btcec/v2 v2.3.4/go.mod h1:zYzJ8etWJQIv1Ogk7OzpWjowwOdXY1W/17j2MW85J04=
github.com/cmars/basen v0.0.0-20150613233007-fe3947df716e h1:0XBUw73chJ1VYSsfvcPvVT7auykAJce9FpRr10L6Qhw=
github.com/cmars/basen v0.0.0-20150613233007-fe3947df716e/go.mod h1:P13beTBKr5Q18lJe1rIoLUqjM+CB1zYrRg44ZqGuQSA=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/decred/dcrd/crypto/blake256 v1.0.1 h1:7PltbUIQB7u/FfZ39+DGa/ShuMyJ5ilcvdfma9wOH6Y=
github.com/decred/dcrd/crypto/blake256 v1.0.1/go.mod h1:2OfgNZ5wDpcsFmHmCK5gZTPcCXqlm2ArzUIkw9czNJo=
github.com/decred/dcrd/crypto/ripemd160 v1.0.2 h1:TvGTmUBHDU75OHro9ojPLK+Yv7gDl2hnUvRocRCjsys=
github.com/decred/dcrd/crypto/ripemd160 v1.0.2/go.mod h1:uGfjDyePSpa75cSQLzNdVmWlbQMBuiJkvXw/MNKRY4M=
github.com/decred/dcrd/dcrec/secp256k1/v4 v4.3.0 h1:rpfIENRNNilwHwZeG5+P150SMrnNEcHYvcCuK6dPZSg=
github.com/decred/dcrd/dcrec/secp256k1/v4 v4.3.0/go.mod h1:v57UDF4pDQJcEfFUCRop3lJL149eHGSe9Jvczhzjo/0=
github.com/golang/mock v1.6.0 h1:ErTB+efbowRARo13NNdxyJji2egdxLGQhRaY+DUumQc=
github.com/golang/mock v1.6.0/go.mod h1:p6yTPP+5HYm5mzsMV8JkE6ZKdX+/wYM6Hr+LicevLPs=
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
github.com/gorilla/websocket v1.5.0 h1:PPwGk2jz7EePpoHN/+ClbZu8SPxiqlu12wZP/3sWmnc=
github.com/gorilla/websocket v1.5.0/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM=
github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo=
github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyuac5Z2hdY=
github.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo=
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421 h1:ZqeYNhU3OHLH3mGKHDcjJRFFRrJa6eAM5H+CtDdOsPc=
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M=
github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/testify v1.1.5-0.20170601210322-f6abca593680/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk=
github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
github.com/tyler-smith/go-bip32 v1.0.0 h1:sDR9juArbUgX+bO/iblgZnMPeWY1KZMUC2AFUJdv5KE=
github.com/tyler-smith/go-bip32 v1.0.0/go.mod h1:onot+eHknzV4BVPwrzqY5OoVpyCvnwD7lMawL5aQupE=
github.com/tyler-smith/go-bip39 v1.1.0 h1:5eUemwrMargf3BSLRRCalXT93Ns6pQJIjYQN2nyfOP8=
github.com/tyler-smith/go-bip39 v1.1.0/go.mod h1:gUYDtqQw1JS3ZJ8UWVcGTGqqr6YIN3CWg+kkNaLt55U=
github.com/ugorji/go/codec v1.2.11 h1:BMaWp1Bb6fHwEtbplGBGJ498wD+LKlNSl25MjdZY4dU=
github.com/ugorji/go/codec v1.2.11/go.mod h1:UNopzCgEMSXjBc6AOMqYvWC1ktqTAfzJZUZgYf6w6lg=
golang.org/x/crypto v0.0.0-20170613210332-850760c427c5/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/crypto v0.23.0 h1:dIJU/v2J8Mdglj/8rJ6UUOM3Zc9zLZxVZwwxMooUSAI=
golang.org/x/crypto v0.23.0/go.mod h1:CKFgDieR+mRhux2Lsu27y0fO304Db0wZe70UKqHu0v8=
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
launchpad.net/gocheck v0.0.0-20140225173054-000000000087 h1:Izowp2XBH6Ya6rv+hqbceQyw/gSGoXfH/UPoTGduL54=
launchpad.net/gocheck v0.0.0-20140225173054-000000000087/go.mod h1:hj7XX3B/0A+80Vse0e+BUHsHMTEhd0O4cpUHr/e/BUM=

View File

@@ -1 +1,251 @@
package rpc
package main
import (
"fmt"
"github.com/Peersyst/xrpl-go/pkg/crypto"
"github.com/Peersyst/xrpl-go/xrpl/faucet"
"github.com/Peersyst/xrpl-go/xrpl/rpc"
transactions "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"
)
func main() {
//
// Configure client
//
cfg, err := rpc.NewClientConfig(
"https://s.altnet.rippletest.net:51234/",
rpc.WithFaucetProvider(faucet.NewTestnetFaucetProvider()),
)
if err != nil {
panic(err)
}
client := rpc.NewClient(cfg)
//
// Configure wallets
//
fmt.Println("⏳ Setting up wallets...")
coldWallet, err := wallet.New(crypto.ED25519())
if err != nil {
fmt.Printf("❌ Error creating cold wallet: %s\n", err)
return
}
err = client.FundWallet(&coldWallet)
if err != nil {
fmt.Printf("❌ Error funding cold wallet: %s\n", err)
return
}
fmt.Println("💸 Cold wallet funded!")
hotWallet, err := wallet.New(crypto.ED25519())
if err != nil {
fmt.Printf("❌ Error creating hot wallet: %s\n", err)
return
}
err = client.FundWallet(&hotWallet)
if err != nil {
fmt.Printf("❌ Error funding hot wallet: %s\n", err)
return
}
fmt.Println("💸 Hot wallet funded!")
fmt.Println()
fmt.Println("✅ Wallets setup complete!")
fmt.Println("💳 Cold wallet:", coldWallet.ClassicAddress)
fmt.Println("💳 Hot wallet:", hotWallet.ClassicAddress)
fmt.Println()
//
// Configure cold address settings
//
fmt.Println("⏳ Configuring cold address settings...")
coldWalletAccountSet := &transactions.AccountSet{
BaseTx: transactions.BaseTx{
Account: types.Address(coldWallet.ClassicAddress),
},
TickSize: types.TickSize(5),
TransferRate: types.TransferRate(0),
Domain: types.Domain("6578616D706C652E636F6D"), // example.com
}
coldWalletAccountSet.SetAsfAllowTrustLineClawback()
coldWalletAccountSet.SetDisallowXRP()
coldWalletAccountSet.SetRequireDestTag()
flattenedTx := coldWalletAccountSet.Flatten()
err = client.Autofill(&flattenedTx)
if err != nil {
fmt.Printf("❌ Error autofilling transaction: %s\n", err)
return
}
txBlob, _, err := coldWallet.Sign(flattenedTx)
if err != nil {
fmt.Printf("❌ Error signing transaction: %s\n", err)
return
}
response, err := client.SubmitTxBlobAndWait(txBlob, false)
if err != nil {
fmt.Printf("❌ Error submitting transaction: %s\n", err)
return
}
if !response.Validated {
fmt.Println("❌ Cold wallet unfreezing failed!")
fmt.Println("Try again!")
fmt.Println()
return
}
fmt.Println("✅ Cold address settings configured!")
fmt.Printf("🌐 Hash: %s\n", response.Hash.String())
fmt.Println()
//
// Create trust line from hot to cold address
//
fmt.Println("⏳ Creating trust line from hot to cold address...")
hotColdTrustSet := &transactions.TrustSet{
BaseTx: transactions.BaseTx{
Account: types.Address(hotWallet.ClassicAddress),
},
LimitAmount: types.IssuedCurrencyAmount{
Currency: currencyCode,
Issuer: types.Address(coldWallet.ClassicAddress),
Value: "100000000000000",
},
}
flattenedTx = hotColdTrustSet.Flatten()
err = client.Autofill(&flattenedTx)
if err != nil {
fmt.Printf("❌ Error autofilling transaction: %s\n", err)
return
}
txBlob, _, err = hotWallet.Sign(flattenedTx)
if err != nil {
fmt.Printf("❌ Error signing transaction: %s\n", err)
return
}
response, err = client.SubmitTxBlobAndWait(txBlob, false)
if err != nil {
fmt.Printf("❌ Error submitting transaction: %s\n", err)
return
}
if !response.Validated {
fmt.Println("❌ Trust line from hot to cold address creation failed!")
fmt.Println("Try again!")
fmt.Println()
return
}
fmt.Println("✅ Trust line from hot to cold address created!")
fmt.Printf("🌐 Hash: %s\n", response.Hash.String())
fmt.Println()
//
// Send tokens from cold wallet to hot wallet
//
fmt.Println("⏳ Sending tokens from cold wallet to hot wallet...")
coldToHotPayment := &transactions.Payment{
BaseTx: transactions.BaseTx{
Account: types.Address(coldWallet.ClassicAddress),
},
Amount: types.IssuedCurrencyAmount{
Currency: currencyCode,
Issuer: types.Address(coldWallet.ClassicAddress),
Value: "3800",
},
Destination: types.Address(hotWallet.ClassicAddress),
DestinationTag: types.DestinationTag(1),
}
flattenedTx = coldToHotPayment.Flatten()
err = client.Autofill(&flattenedTx)
if err != nil {
fmt.Printf("❌ Error autofilling transaction: %s\n", err)
return
}
txBlob, _, err = coldWallet.Sign(flattenedTx)
if err != nil {
fmt.Printf("❌ Error signing transaction: %s\n", err)
return
}
response, err = client.SubmitTxBlobAndWait(txBlob, false)
if err != nil {
fmt.Printf("❌ Error submitting transaction: %s\n", err)
return
}
if !response.Validated {
fmt.Println("❌ Tokens not sent from cold wallet to hot wallet!")
fmt.Println("Try again!")
fmt.Println()
return
}
fmt.Println("✅ Tokens sent from cold wallet to hot wallet!")
fmt.Printf("🌐 Hash: %s\n", response.Hash.String())
fmt.Println()
//
// Claw back tokens from customer one
//
fmt.Println("⏳ Clawing back tokens from hot wallet...")
coldWalletClawback := &transactions.Clawback{
BaseTx: transactions.BaseTx{
Account: types.Address(coldWallet.ClassicAddress),
},
Amount: types.IssuedCurrencyAmount{
Currency: currencyCode,
Issuer: types.Address(hotWallet.ClassicAddress),
Value: "50",
},
}
flattenedTx = coldWalletClawback.Flatten()
err = client.Autofill(&flattenedTx)
if err != nil {
fmt.Printf("❌ Error autofilling transaction: %s\n", err)
return
}
txBlob, _, err = coldWallet.Sign(flattenedTx)
if err != nil {
fmt.Printf("❌ Error signing transaction: %s\n", err)
return
}
response, err = client.SubmitTxBlobAndWait(txBlob, false)
if err != nil {
fmt.Printf("❌ Error submitting transaction: %s\n", err)
return
}
if !response.Validated {
fmt.Println("❌ Tokens not clawed back from customer one!")
fmt.Println("Try again!")
return
}
fmt.Println("✅ Tokens clawed back from customer one!")
fmt.Printf("🌐 Hash: %s\n", response.Hash.String())
fmt.Println()
}

View File

@@ -1 +1,258 @@
package ws
package main
import (
"fmt"
"github.com/Peersyst/xrpl-go/pkg/crypto"
"github.com/Peersyst/xrpl-go/xrpl/faucet"
transactions "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"
)
const (
currencyCode = "FOO"
)
func main() {
//
// Configure client
//
fmt.Println("⏳ Setting up client...")
client := websocket.NewClient(
websocket.NewClientConfig().
WithHost("wss://s.altnet.rippletest.net").
WithFaucetProvider(faucet.NewTestnetFaucetProvider()),
)
fmt.Println("✅ Client configured!")
fmt.Println()
fmt.Println("Connecting to server...")
if err := client.Connect(); err != nil {
fmt.Println(err)
return
}
fmt.Println("Connection: ", client.IsConnected())
//
// Configure wallets
//
fmt.Println("⏳ Setting up wallets...")
coldWallet, err := wallet.New(crypto.ED25519())
if err != nil {
fmt.Printf("❌ Error creating cold wallet: %s\n", err)
return
}
err = client.FundWallet(&coldWallet)
if err != nil {
fmt.Printf("❌ Error funding cold wallet: %s\n", err)
return
}
fmt.Println("💸 Cold wallet funded!")
hotWallet, err := wallet.New(crypto.ED25519())
if err != nil {
fmt.Printf("❌ Error creating hot wallet: %s\n", err)
return
}
err = client.FundWallet(&hotWallet)
if err != nil {
fmt.Printf("❌ Error funding hot wallet: %s\n", err)
return
}
fmt.Println("💸 Hot wallet funded!")
fmt.Println()
fmt.Println("✅ Wallets setup complete!")
fmt.Println("💳 Cold wallet:", coldWallet.ClassicAddress)
fmt.Println("💳 Hot wallet:", hotWallet.ClassicAddress)
fmt.Println()
//
// Configure cold address settings
//
fmt.Println("⏳ Configuring cold address settings...")
coldWalletAccountSet := &transactions.AccountSet{
BaseTx: transactions.BaseTx{
Account: types.Address(coldWallet.ClassicAddress),
},
TickSize: types.TickSize(5),
TransferRate: types.TransferRate(0),
Domain: types.Domain("6578616D706C652E636F6D"), // example.com
}
coldWalletAccountSet.SetAsfAllowTrustLineClawback()
coldWalletAccountSet.SetDisallowXRP()
coldWalletAccountSet.SetRequireDestTag()
flattenedTx := coldWalletAccountSet.Flatten()
err = client.Autofill(&flattenedTx)
if err != nil {
fmt.Printf("❌ Error autofilling transaction: %s\n", err)
return
}
txBlob, _, err := coldWallet.Sign(flattenedTx)
if err != nil {
fmt.Printf("❌ Error signing transaction: %s\n", err)
return
}
response, err := client.SubmitTxBlobAndWait(txBlob, false)
if err != nil {
fmt.Printf("❌ Error submitting transaction: %s\n", err)
return
}
if !response.Validated {
fmt.Println("❌ Cold wallet unfreezing failed!")
fmt.Println("Try again!")
fmt.Println()
return
}
fmt.Println("✅ Cold address settings configured!")
fmt.Printf("🌐 Hash: %s\n", response.Hash.String())
fmt.Println()
//
// Create trust line from hot to cold address
//
fmt.Println("⏳ Creating trust line from hot to cold address...")
hotColdTrustSet := &transactions.TrustSet{
BaseTx: transactions.BaseTx{
Account: types.Address(hotWallet.ClassicAddress),
},
LimitAmount: types.IssuedCurrencyAmount{
Currency: currencyCode,
Issuer: types.Address(coldWallet.ClassicAddress),
Value: "100000000000000",
},
}
flattenedTx = hotColdTrustSet.Flatten()
err = client.Autofill(&flattenedTx)
if err != nil {
fmt.Printf("❌ Error autofilling transaction: %s\n", err)
return
}
txBlob, _, err = hotWallet.Sign(flattenedTx)
if err != nil {
fmt.Printf("❌ Error signing transaction: %s\n", err)
return
}
response, err = client.SubmitTxBlobAndWait(txBlob, false)
if err != nil {
fmt.Printf("❌ Error submitting transaction: %s\n", err)
return
}
if !response.Validated {
fmt.Println("❌ Trust line from hot to cold address creation failed!")
fmt.Println("Try again!")
fmt.Println()
return
}
fmt.Println("✅ Trust line from hot to cold address created!")
fmt.Printf("🌐 Hash: %s\n", response.Hash.String())
fmt.Println()
//
// Send tokens from cold wallet to hot wallet
//
fmt.Println("⏳ Sending tokens from cold wallet to hot wallet...")
coldToHotPayment := &transactions.Payment{
BaseTx: transactions.BaseTx{
Account: types.Address(coldWallet.ClassicAddress),
},
Amount: types.IssuedCurrencyAmount{
Currency: currencyCode,
Issuer: types.Address(coldWallet.ClassicAddress),
Value: "3800",
},
Destination: types.Address(hotWallet.ClassicAddress),
DestinationTag: types.DestinationTag(1),
}
flattenedTx = coldToHotPayment.Flatten()
err = client.Autofill(&flattenedTx)
if err != nil {
fmt.Printf("❌ Error autofilling transaction: %s\n", err)
return
}
txBlob, _, err = coldWallet.Sign(flattenedTx)
if err != nil {
fmt.Printf("❌ Error signing transaction: %s\n", err)
return
}
response, err = client.SubmitTxBlobAndWait(txBlob, false)
if err != nil {
fmt.Printf("❌ Error submitting transaction: %s\n", err)
return
}
if !response.Validated {
fmt.Println("❌ Tokens not sent from cold wallet to hot wallet!")
fmt.Println("Try again!")
fmt.Println()
return
}
fmt.Println("✅ Tokens sent from cold wallet to hot wallet!")
fmt.Printf("🌐 Hash: %s\n", response.Hash.String())
fmt.Println()
//
// Claw back tokens from customer one
//
fmt.Println("⏳ Clawing back tokens from hot wallet...")
coldWalletClawback := &transactions.Clawback{
BaseTx: transactions.BaseTx{
Account: types.Address(coldWallet.ClassicAddress),
},
Amount: types.IssuedCurrencyAmount{
Currency: currencyCode,
Issuer: types.Address(hotWallet.ClassicAddress),
Value: "50",
},
}
flattenedTx = coldWalletClawback.Flatten()
err = client.Autofill(&flattenedTx)
if err != nil {
fmt.Printf("❌ Error autofilling transaction: %s\n", err)
return
}
txBlob, _, err = coldWallet.Sign(flattenedTx)
if err != nil {
fmt.Printf("❌ Error signing transaction: %s\n", err)
return
}
response, err = client.SubmitTxBlobAndWait(txBlob, false)
if err != nil {
fmt.Printf("❌ Error submitting transaction: %s\n", err)
return
}
if !response.Validated {
fmt.Println("❌ Tokens not clawed back from customer one!")
fmt.Println("Try again!")
return
}
fmt.Println("✅ Tokens clawed back from customer one!")
fmt.Printf("🌐 Hash: %s\n", response.Hash.String())
fmt.Println()
}

View File

@@ -0,0 +1,3 @@
# Credential
Create, accept, and delete a credential on the XRPL using dedicated transactions between issuer and subject wallets.

View File

@@ -0,0 +1,24 @@
module github.com/XRPLF
go 1.23.0
toolchain go1.23.10
require github.com/Peersyst/xrpl-go v0.1.11
require (
github.com/FactomProject/basen v0.0.0-20150613233007-fe3947df716e // indirect
github.com/FactomProject/btcutilecc v0.0.0-20130527213604-d3a63a5752ec // indirect
github.com/btcsuite/btcd/btcec/v2 v2.3.4 // indirect
github.com/decred/dcrd/crypto/ripemd160 v1.0.2 // indirect
github.com/decred/dcrd/dcrec/secp256k1/v4 v4.3.0 // indirect
github.com/gorilla/websocket v1.5.0 // indirect
github.com/json-iterator/go v1.1.12 // indirect
github.com/mitchellh/mapstructure v1.5.0 // indirect
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421 // indirect
github.com/modern-go/reflect2 v1.0.2 // indirect
github.com/tyler-smith/go-bip32 v1.0.0 // indirect
github.com/tyler-smith/go-bip39 v1.1.0 // indirect
github.com/ugorji/go/codec v1.2.11 // indirect
golang.org/x/crypto v0.23.0 // indirect
)

View File

@@ -0,0 +1,58 @@
github.com/FactomProject/basen v0.0.0-20150613233007-fe3947df716e h1:ahyvB3q25YnZWly5Gq1ekg6jcmWaGj/vG/MhF4aisoc=
github.com/FactomProject/basen v0.0.0-20150613233007-fe3947df716e/go.mod h1:kGUqhHd//musdITWjFvNTHn90WG9bMLBEPQZ17Cmlpw=
github.com/FactomProject/btcutilecc v0.0.0-20130527213604-d3a63a5752ec h1:1Qb69mGp/UtRPn422BH4/Y4Q3SLUrD9KHuDkm8iodFc=
github.com/FactomProject/btcutilecc v0.0.0-20130527213604-d3a63a5752ec/go.mod h1:CD8UlnlLDiqb36L110uqiP2iSflVjx9g/3U9hCI4q2U=
github.com/Peersyst/xrpl-go v0.1.11 h1:P6r/gHxRnbAtAdPmzNHz/7zpsdfvwh0SS+QI2JNT44w=
github.com/Peersyst/xrpl-go v0.1.11/go.mod h1:CBRM3/soqNeeL2Jx6USVUtECqulZVUoq3UxZKMz9hdw=
github.com/btcsuite/btcd/btcec/v2 v2.3.4 h1:3EJjcN70HCu/mwqlUsGK8GcNVyLVxFDlWurTXGPFfiQ=
github.com/btcsuite/btcd/btcec/v2 v2.3.4/go.mod h1:zYzJ8etWJQIv1Ogk7OzpWjowwOdXY1W/17j2MW85J04=
github.com/cmars/basen v0.0.0-20150613233007-fe3947df716e h1:0XBUw73chJ1VYSsfvcPvVT7auykAJce9FpRr10L6Qhw=
github.com/cmars/basen v0.0.0-20150613233007-fe3947df716e/go.mod h1:P13beTBKr5Q18lJe1rIoLUqjM+CB1zYrRg44ZqGuQSA=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/decred/dcrd/crypto/blake256 v1.0.1 h1:7PltbUIQB7u/FfZ39+DGa/ShuMyJ5ilcvdfma9wOH6Y=
github.com/decred/dcrd/crypto/blake256 v1.0.1/go.mod h1:2OfgNZ5wDpcsFmHmCK5gZTPcCXqlm2ArzUIkw9czNJo=
github.com/decred/dcrd/crypto/ripemd160 v1.0.2 h1:TvGTmUBHDU75OHro9ojPLK+Yv7gDl2hnUvRocRCjsys=
github.com/decred/dcrd/crypto/ripemd160 v1.0.2/go.mod h1:uGfjDyePSpa75cSQLzNdVmWlbQMBuiJkvXw/MNKRY4M=
github.com/decred/dcrd/dcrec/secp256k1/v4 v4.3.0 h1:rpfIENRNNilwHwZeG5+P150SMrnNEcHYvcCuK6dPZSg=
github.com/decred/dcrd/dcrec/secp256k1/v4 v4.3.0/go.mod h1:v57UDF4pDQJcEfFUCRop3lJL149eHGSe9Jvczhzjo/0=
github.com/golang/mock v1.6.0 h1:ErTB+efbowRARo13NNdxyJji2egdxLGQhRaY+DUumQc=
github.com/golang/mock v1.6.0/go.mod h1:p6yTPP+5HYm5mzsMV8JkE6ZKdX+/wYM6Hr+LicevLPs=
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
github.com/gorilla/websocket v1.5.0 h1:PPwGk2jz7EePpoHN/+ClbZu8SPxiqlu12wZP/3sWmnc=
github.com/gorilla/websocket v1.5.0/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM=
github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo=
github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyuac5Z2hdY=
github.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo=
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421 h1:ZqeYNhU3OHLH3mGKHDcjJRFFRrJa6eAM5H+CtDdOsPc=
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M=
github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/testify v1.1.5-0.20170601210322-f6abca593680/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk=
github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
github.com/tyler-smith/go-bip32 v1.0.0 h1:sDR9juArbUgX+bO/iblgZnMPeWY1KZMUC2AFUJdv5KE=
github.com/tyler-smith/go-bip32 v1.0.0/go.mod h1:onot+eHknzV4BVPwrzqY5OoVpyCvnwD7lMawL5aQupE=
github.com/tyler-smith/go-bip39 v1.1.0 h1:5eUemwrMargf3BSLRRCalXT93Ns6pQJIjYQN2nyfOP8=
github.com/tyler-smith/go-bip39 v1.1.0/go.mod h1:gUYDtqQw1JS3ZJ8UWVcGTGqqr6YIN3CWg+kkNaLt55U=
github.com/ugorji/go/codec v1.2.11 h1:BMaWp1Bb6fHwEtbplGBGJ498wD+LKlNSl25MjdZY4dU=
github.com/ugorji/go/codec v1.2.11/go.mod h1:UNopzCgEMSXjBc6AOMqYvWC1ktqTAfzJZUZgYf6w6lg=
golang.org/x/crypto v0.0.0-20170613210332-850760c427c5/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/crypto v0.23.0 h1:dIJU/v2J8Mdglj/8rJ6UUOM3Zc9zLZxVZwwxMooUSAI=
golang.org/x/crypto v0.23.0/go.mod h1:CKFgDieR+mRhux2Lsu27y0fO304Db0wZe70UKqHu0v8=
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
launchpad.net/gocheck v0.0.0-20140225173054-000000000087 h1:Izowp2XBH6Ya6rv+hqbceQyw/gSGoXfH/UPoTGduL54=
launchpad.net/gocheck v0.0.0-20140225173054-000000000087/go.mod h1:hj7XX3B/0A+80Vse0e+BUHsHMTEhd0O4cpUHr/e/BUM=

View File

@@ -0,0 +1,109 @@
package main
import (
"encoding/hex"
"fmt"
"time"
"github.com/Peersyst/xrpl-go/examples/clients"
"github.com/Peersyst/xrpl-go/pkg/crypto"
rippleTime "github.com/Peersyst/xrpl-go/xrpl/time"
"github.com/Peersyst/xrpl-go/xrpl/transaction"
"github.com/Peersyst/xrpl-go/xrpl/transaction/types"
"github.com/Peersyst/xrpl-go/xrpl/wallet"
)
func main() {
// As of February 2025, Credential is only available on Devnet.
client := clients.GetDevnetRpcClient()
// Configure wallets
// Issuer
fmt.Println("⏳ Setting up credential issuer wallet...")
issuer, err := wallet.New(crypto.ED25519())
if err != nil {
fmt.Printf("❌ Error creating issuer wallet: %s\n", err)
return
}
err = client.FundWallet(&issuer)
if err != nil {
fmt.Printf("❌ Error funding issuer wallet: %s\n", err)
return
}
fmt.Printf("✅ Issuer wallet funded: %s\n", issuer.ClassicAddress)
// -----------------------------------------------------
// Subject (destination)
fmt.Println("⏳ Setting up Subject wallet...")
subjectWallet, err := wallet.New(crypto.ED25519())
if err != nil {
fmt.Printf("❌ Error creating subject wallet: %s\n", err)
return
}
err = client.FundWallet(&subjectWallet)
if err != nil {
fmt.Printf("❌ Error funding subject wallet: %s\n", err)
return
}
fmt.Printf("✅ Subject wallet funded: %s\n", subjectWallet.ClassicAddress)
// -----------------------------------------------------
// Creating the CredentialCreate transaction
fmt.Println("⏳ Creating CredentialCreate transaction...")
expiration, err := rippleTime.IsoTimeToRippleTime(time.Now().Add(time.Hour * 24).Format(time.RFC3339))
credentialType := types.CredentialType("6D795F63726564656E7469616C")
if err != nil {
fmt.Printf("❌ Error converting expiration to ripple time: %s\n", err)
return
}
txn := &transaction.CredentialCreate{
BaseTx: transaction.BaseTx{
Account: types.Address(issuer.ClassicAddress),
},
CredentialType: credentialType,
Subject: types.Address(subjectWallet.ClassicAddress),
Expiration: uint32(expiration),
URI: hex.EncodeToString([]byte("https://example.com")),
}
clients.SubmitTxBlobAndWait(client, txn, issuer)
// -----------------------------------------------------
// Creating the CredentialAccept transaction
fmt.Println("⏳ Creating CredentialAccept transaction...")
acceptTxn := &transaction.CredentialAccept{
BaseTx: transaction.BaseTx{
Account: types.Address(subjectWallet.ClassicAddress),
},
CredentialType: credentialType,
Issuer: types.Address(issuer.ClassicAddress),
}
clients.SubmitTxBlobAndWait(client, acceptTxn, subjectWallet)
// -----------------------------------------------------
// Creating the CredentialDelete transaction
fmt.Println("⏳ Creating CredentialDelete transaction...")
deleteTxn := &transaction.CredentialDelete{
BaseTx: transaction.BaseTx{
Account: types.Address(issuer.ClassicAddress),
},
CredentialType: credentialType,
Issuer: types.Address(issuer.ClassicAddress),
Subject: types.Address(subjectWallet.ClassicAddress),
}
clients.SubmitTxBlobAndWait(client, deleteTxn, issuer)
}

View File

@@ -0,0 +1,122 @@
package main
import (
"encoding/hex"
"fmt"
"time"
"github.com/Peersyst/xrpl-go/examples/clients"
"github.com/Peersyst/xrpl-go/pkg/crypto"
rippleTime "github.com/Peersyst/xrpl-go/xrpl/time"
"github.com/Peersyst/xrpl-go/xrpl/transaction"
"github.com/Peersyst/xrpl-go/xrpl/transaction/types"
"github.com/Peersyst/xrpl-go/xrpl/wallet"
)
func main() {
fmt.Println("⏳ Setting up client...")
client := clients.GetDevnetWebsocketClient()
fmt.Println("Connecting to server...")
if err := client.Connect(); err != nil {
fmt.Println(err)
return
}
fmt.Println("✅ Client configured!")
fmt.Println()
fmt.Printf("Connection: %t", client.IsConnected())
fmt.Println()
// Configure wallets
// Issuer
fmt.Println("⏳ Setting up credential issuer wallet...")
issuer, err := wallet.New(crypto.ED25519())
if err != nil {
fmt.Printf("❌ Error creating issuer wallet: %s\n", err)
return
}
err = client.FundWallet(&issuer)
if err != nil {
fmt.Printf("❌ Error funding issuer wallet: %s\n", err)
return
}
fmt.Printf("✅ Issuer wallet funded: %s\n", issuer.ClassicAddress)
// -----------------------------------------------------
// Subject (destination)
fmt.Println("⏳ Setting up Subject wallet...")
subjectWallet, err := wallet.New(crypto.ED25519())
if err != nil {
fmt.Printf("❌ Error creating subject wallet: %s\n", err)
return
}
err = client.FundWallet(&subjectWallet)
if err != nil {
fmt.Printf("❌ Error funding subject wallet: %s\n", err)
return
}
fmt.Printf("✅ Subject wallet funded: %s\n", subjectWallet.ClassicAddress)
// -----------------------------------------------------
// Creating the CredentialCreate transaction
fmt.Println("⏳ Creating CredentialCreate transaction...")
expiration, err := rippleTime.IsoTimeToRippleTime(time.Now().Add(time.Hour * 24).Format(time.RFC3339))
credentialType := types.CredentialType("6D795F63726564656E7469616C")
if err != nil {
fmt.Printf("❌ Error converting expiration to ripple time: %s\n", err)
return
}
txn := &transaction.CredentialCreate{
BaseTx: transaction.BaseTx{
Account: types.Address(issuer.ClassicAddress),
},
CredentialType: credentialType,
Subject: types.Address(subjectWallet.ClassicAddress),
Expiration: uint32(expiration),
URI: hex.EncodeToString([]byte("https://example.com")),
}
clients.SubmitTxBlobAndWait(client, txn, issuer)
// -----------------------------------------------------
// Creating the CredentialAccept transaction
fmt.Println("⏳ Creating CredentialAccept transaction...")
acceptTxn := &transaction.CredentialAccept{
BaseTx: transaction.BaseTx{
Account: types.Address(subjectWallet.ClassicAddress),
},
CredentialType: credentialType,
Issuer: types.Address(issuer.ClassicAddress),
}
clients.SubmitTxBlobAndWait(client, acceptTxn, subjectWallet)
// -----------------------------------------------------
// Creating the CredentialDelete transaction
fmt.Println("⏳ Creating CredentialDelete transaction...")
deleteTxn := &transaction.CredentialDelete{
BaseTx: transaction.BaseTx{
Account: types.Address(issuer.ClassicAddress),
},
CredentialType: credentialType,
Issuer: types.Address(issuer.ClassicAddress),
Subject: types.Address(subjectWallet.ClassicAddress),
}
clients.SubmitTxBlobAndWait(client, deleteTxn, issuer)
}

View File

@@ -0,0 +1,3 @@
# Delegate
Example delegating payment permission to an account and executing on behalf the delegator.

View File

@@ -0,0 +1,24 @@
module github.com/XRPLF
go 1.23.0
toolchain go1.23.10
require github.com/Peersyst/xrpl-go v0.1.11
require (
github.com/FactomProject/basen v0.0.0-20150613233007-fe3947df716e // indirect
github.com/FactomProject/btcutilecc v0.0.0-20130527213604-d3a63a5752ec // indirect
github.com/btcsuite/btcd/btcec/v2 v2.3.4 // indirect
github.com/decred/dcrd/crypto/ripemd160 v1.0.2 // indirect
github.com/decred/dcrd/dcrec/secp256k1/v4 v4.3.0 // indirect
github.com/gorilla/websocket v1.5.0 // indirect
github.com/json-iterator/go v1.1.12 // indirect
github.com/mitchellh/mapstructure v1.5.0 // indirect
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421 // indirect
github.com/modern-go/reflect2 v1.0.2 // indirect
github.com/tyler-smith/go-bip32 v1.0.0 // indirect
github.com/tyler-smith/go-bip39 v1.1.0 // indirect
github.com/ugorji/go/codec v1.2.11 // indirect
golang.org/x/crypto v0.23.0 // indirect
)

View File

@@ -0,0 +1,58 @@
github.com/FactomProject/basen v0.0.0-20150613233007-fe3947df716e h1:ahyvB3q25YnZWly5Gq1ekg6jcmWaGj/vG/MhF4aisoc=
github.com/FactomProject/basen v0.0.0-20150613233007-fe3947df716e/go.mod h1:kGUqhHd//musdITWjFvNTHn90WG9bMLBEPQZ17Cmlpw=
github.com/FactomProject/btcutilecc v0.0.0-20130527213604-d3a63a5752ec h1:1Qb69mGp/UtRPn422BH4/Y4Q3SLUrD9KHuDkm8iodFc=
github.com/FactomProject/btcutilecc v0.0.0-20130527213604-d3a63a5752ec/go.mod h1:CD8UlnlLDiqb36L110uqiP2iSflVjx9g/3U9hCI4q2U=
github.com/Peersyst/xrpl-go v0.1.11 h1:P6r/gHxRnbAtAdPmzNHz/7zpsdfvwh0SS+QI2JNT44w=
github.com/Peersyst/xrpl-go v0.1.11/go.mod h1:CBRM3/soqNeeL2Jx6USVUtECqulZVUoq3UxZKMz9hdw=
github.com/btcsuite/btcd/btcec/v2 v2.3.4 h1:3EJjcN70HCu/mwqlUsGK8GcNVyLVxFDlWurTXGPFfiQ=
github.com/btcsuite/btcd/btcec/v2 v2.3.4/go.mod h1:zYzJ8etWJQIv1Ogk7OzpWjowwOdXY1W/17j2MW85J04=
github.com/cmars/basen v0.0.0-20150613233007-fe3947df716e h1:0XBUw73chJ1VYSsfvcPvVT7auykAJce9FpRr10L6Qhw=
github.com/cmars/basen v0.0.0-20150613233007-fe3947df716e/go.mod h1:P13beTBKr5Q18lJe1rIoLUqjM+CB1zYrRg44ZqGuQSA=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/decred/dcrd/crypto/blake256 v1.0.1 h1:7PltbUIQB7u/FfZ39+DGa/ShuMyJ5ilcvdfma9wOH6Y=
github.com/decred/dcrd/crypto/blake256 v1.0.1/go.mod h1:2OfgNZ5wDpcsFmHmCK5gZTPcCXqlm2ArzUIkw9czNJo=
github.com/decred/dcrd/crypto/ripemd160 v1.0.2 h1:TvGTmUBHDU75OHro9ojPLK+Yv7gDl2hnUvRocRCjsys=
github.com/decred/dcrd/crypto/ripemd160 v1.0.2/go.mod h1:uGfjDyePSpa75cSQLzNdVmWlbQMBuiJkvXw/MNKRY4M=
github.com/decred/dcrd/dcrec/secp256k1/v4 v4.3.0 h1:rpfIENRNNilwHwZeG5+P150SMrnNEcHYvcCuK6dPZSg=
github.com/decred/dcrd/dcrec/secp256k1/v4 v4.3.0/go.mod h1:v57UDF4pDQJcEfFUCRop3lJL149eHGSe9Jvczhzjo/0=
github.com/golang/mock v1.6.0 h1:ErTB+efbowRARo13NNdxyJji2egdxLGQhRaY+DUumQc=
github.com/golang/mock v1.6.0/go.mod h1:p6yTPP+5HYm5mzsMV8JkE6ZKdX+/wYM6Hr+LicevLPs=
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
github.com/gorilla/websocket v1.5.0 h1:PPwGk2jz7EePpoHN/+ClbZu8SPxiqlu12wZP/3sWmnc=
github.com/gorilla/websocket v1.5.0/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM=
github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo=
github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyuac5Z2hdY=
github.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo=
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421 h1:ZqeYNhU3OHLH3mGKHDcjJRFFRrJa6eAM5H+CtDdOsPc=
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M=
github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/testify v1.1.5-0.20170601210322-f6abca593680/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk=
github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
github.com/tyler-smith/go-bip32 v1.0.0 h1:sDR9juArbUgX+bO/iblgZnMPeWY1KZMUC2AFUJdv5KE=
github.com/tyler-smith/go-bip32 v1.0.0/go.mod h1:onot+eHknzV4BVPwrzqY5OoVpyCvnwD7lMawL5aQupE=
github.com/tyler-smith/go-bip39 v1.1.0 h1:5eUemwrMargf3BSLRRCalXT93Ns6pQJIjYQN2nyfOP8=
github.com/tyler-smith/go-bip39 v1.1.0/go.mod h1:gUYDtqQw1JS3ZJ8UWVcGTGqqr6YIN3CWg+kkNaLt55U=
github.com/ugorji/go/codec v1.2.11 h1:BMaWp1Bb6fHwEtbplGBGJ498wD+LKlNSl25MjdZY4dU=
github.com/ugorji/go/codec v1.2.11/go.mod h1:UNopzCgEMSXjBc6AOMqYvWC1ktqTAfzJZUZgYf6w6lg=
golang.org/x/crypto v0.0.0-20170613210332-850760c427c5/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/crypto v0.23.0 h1:dIJU/v2J8Mdglj/8rJ6UUOM3Zc9zLZxVZwwxMooUSAI=
golang.org/x/crypto v0.23.0/go.mod h1:CKFgDieR+mRhux2Lsu27y0fO304Db0wZe70UKqHu0v8=
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
launchpad.net/gocheck v0.0.0-20140225173054-000000000087 h1:Izowp2XBH6Ya6rv+hqbceQyw/gSGoXfH/UPoTGduL54=
launchpad.net/gocheck v0.0.0-20140225173054-000000000087/go.mod h1:hj7XX3B/0A+80Vse0e+BUHsHMTEhd0O4cpUHr/e/BUM=

View File

@@ -0,0 +1,131 @@
package main
import (
"fmt"
"github.com/Peersyst/xrpl-go/pkg/crypto"
"github.com/Peersyst/xrpl-go/xrpl/faucet"
"github.com/Peersyst/xrpl-go/xrpl/rpc"
"github.com/Peersyst/xrpl-go/xrpl/rpc/types"
transactions "github.com/Peersyst/xrpl-go/xrpl/transaction"
txnTypes "github.com/Peersyst/xrpl-go/xrpl/transaction/types"
"github.com/Peersyst/xrpl-go/xrpl/wallet"
)
func main() {
// Configure the client
cfg, err := rpc.NewClientConfig(
"https://s.devnet.rippletest.net:51234/",
rpc.WithFaucetProvider(faucet.NewDevnetFaucetProvider()),
)
if err != nil {
panic(err)
}
client := rpc.NewClient(cfg)
// Create and fund wallets
delegatorWallet, err := wallet.New(crypto.ED25519())
if err != nil {
fmt.Println(err)
return
}
delegateeWallet, err := wallet.New(crypto.ED25519())
if err != nil {
fmt.Println(err)
return
}
fmt.Println("⏳ Funding wallets...")
if err := client.FundWallet(&delegatorWallet); err != nil {
fmt.Println(err)
return
}
if err := client.FundWallet(&delegateeWallet); err != nil {
fmt.Println(err)
return
}
fmt.Println("💸 Wallets funded")
// Check initial balances
delegatorBalance, err := client.GetXrpBalance(delegatorWallet.ClassicAddress)
if err != nil {
delegatorBalance = "0"
}
delegateeBalance, err := client.GetXrpBalance(delegateeWallet.ClassicAddress)
if err != nil {
delegateeBalance = "0"
}
fmt.Printf("💳 Delegator initial balance: %s XRP\n", delegatorBalance)
fmt.Printf("💳 Delegatee initial balance: %s XRP\n", delegateeBalance)
fmt.Println()
// Create DelegateSet transaction
delegateSetTx := &transactions.DelegateSet{
BaseTx: transactions.BaseTx{
Account: txnTypes.Address(delegatorWallet.ClassicAddress),
},
Authorize: txnTypes.Address(delegateeWallet.ClassicAddress),
Permissions: []txnTypes.Permission{
{
Permission: txnTypes.PermissionValue{
PermissionValue: "Payment",
},
},
},
}
// Submit DelegateSet transaction
response, err := client.SubmitTxAndWait(delegateSetTx.Flatten(), &types.SubmitOptions{
Autofill: true,
Wallet: &delegatorWallet,
})
if err != nil {
fmt.Println(err)
return
}
fmt.Println("✅ DelegateSet transaction submitted")
fmt.Printf("🌐 Hash: %s\n", response.Hash)
fmt.Printf("🌐 Validated: %t\n", response.Validated)
fmt.Println()
// Create delegated payment transaction
delegatedPaymentTx := &transactions.Payment{
BaseTx: transactions.BaseTx{
Account: txnTypes.Address(delegatorWallet.ClassicAddress),
Delegate: txnTypes.Address(delegateeWallet.ClassicAddress),
},
Destination: txnTypes.Address(delegateeWallet.ClassicAddress),
Amount: txnTypes.XRPCurrencyAmount(1000000), // 1 XRP
}
// Submit delegated payment
response2, err := client.SubmitTxAndWait(delegatedPaymentTx.Flatten(), &types.SubmitOptions{
Autofill: true,
Wallet: &delegateeWallet,
})
if err != nil {
fmt.Println(err)
return
}
fmt.Println("✅ Delegated payment submitted")
fmt.Printf("🌐 Hash: %s\n", response2.Hash)
fmt.Printf("🌐 Validated: %t\n", response2.Validated)
fmt.Println()
// Check final balances
finalDelegatorBalance, err := client.GetXrpBalance(delegatorWallet.ClassicAddress)
if err != nil {
finalDelegatorBalance = "0"
}
finalDelegateeBalance, err := client.GetXrpBalance(delegateeWallet.ClassicAddress)
if err != nil {
finalDelegateeBalance = "0"
}
fmt.Printf("💳 Delegator final balance: %s XRP\n", finalDelegatorBalance)
fmt.Printf("💳 Delegatee final balance: %s XRP\n", finalDelegateeBalance)
}

View File

@@ -0,0 +1,151 @@
package main
import (
"fmt"
"github.com/Peersyst/xrpl-go/pkg/crypto"
"github.com/Peersyst/xrpl-go/xrpl/faucet"
transactions "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"
)
func main() {
// Connect to testnet
client := websocket.NewClient(
websocket.NewClientConfig().
WithHost("wss://s.devnet.rippletest.net:51233").
WithFaucetProvider(faucet.NewDevnetFaucetProvider()),
)
defer client.Disconnect()
if err := client.Connect(); err != nil {
fmt.Println(err)
return
}
// Create and fund wallets
delegatorWallet, err := wallet.New(crypto.ED25519())
if err != nil {
fmt.Println(err)
return
}
delegateeWallet, err := wallet.New(crypto.ED25519())
if err != nil {
fmt.Println(err)
return
}
fmt.Println("⏳ Funding wallets...")
if err := client.FundWallet(&delegatorWallet); err != nil {
fmt.Println(err)
return
}
if err := client.FundWallet(&delegateeWallet); err != nil {
fmt.Println(err)
return
}
fmt.Println("💸 Wallets funded")
// Check initial balances
delegatorBalance, err := client.GetXrpBalance(delegatorWallet.ClassicAddress)
if err != nil {
delegatorBalance = "0"
}
delegateeBalance, err := client.GetXrpBalance(delegateeWallet.ClassicAddress)
if err != nil {
delegateeBalance = "0"
}
fmt.Printf("💳 Delegator initial balance: %s XRP\n", delegatorBalance)
fmt.Printf("💳 Delegatee initial balance: %s XRP\n", delegateeBalance)
fmt.Println()
// Create DelegateSet transaction
delegateSetTx := &transactions.DelegateSet{
BaseTx: transactions.BaseTx{
Account: types.Address(delegatorWallet.ClassicAddress),
},
Authorize: types.Address(delegateeWallet.ClassicAddress),
Permissions: []types.Permission{
{
Permission: types.PermissionValue{
PermissionValue: "Payment",
},
},
},
}
// Submit DelegateSet transaction
flattenedTx := delegateSetTx.Flatten()
if err := client.Autofill(&flattenedTx); err != nil {
fmt.Println(err)
return
}
txBlob, _, err := delegatorWallet.Sign(flattenedTx)
if err != nil {
fmt.Println(err)
return
}
response, err := client.SubmitTxBlobAndWait(txBlob, false)
if err != nil {
fmt.Println(err)
return
}
fmt.Println("✅ DelegateSet transaction submitted")
fmt.Printf("🌐 Hash: %s\n", response.Hash)
fmt.Printf("🌐 Validated: %t\n", response.Validated)
fmt.Println()
// Create delegated payment transaction
delegatedPaymentTx := &transactions.Payment{
BaseTx: transactions.BaseTx{
Account: types.Address(delegatorWallet.ClassicAddress),
Delegate: types.Address(delegateeWallet.ClassicAddress),
},
Destination: types.Address(delegateeWallet.ClassicAddress),
Amount: types.XRPCurrencyAmount(1000000), // 1 XRP
}
// Submit delegated payment
flatDelegatedPayment := delegatedPaymentTx.Flatten()
if err := client.Autofill(&flatDelegatedPayment); err != nil {
fmt.Println(err)
return
}
txBlob2, _, err := delegateeWallet.Sign(flatDelegatedPayment)
if err != nil {
fmt.Println(err)
return
}
response2, err := client.SubmitTxBlobAndWait(txBlob2, false)
if err != nil {
fmt.Println(err)
return
}
fmt.Println("✅ Delegated payment submitted")
fmt.Printf("🌐 Hash: %s\n", response2.Hash)
fmt.Printf("🌐 Validated: %t\n", response2.Validated)
fmt.Println()
// Check final balances
finalDelegatorBalance, err := client.GetXrpBalance(delegatorWallet.ClassicAddress)
if err != nil {
finalDelegatorBalance = "0"
}
finalDelegateeBalance, err := client.GetXrpBalance(delegateeWallet.ClassicAddress)
if err != nil {
finalDelegateeBalance = "0"
}
fmt.Printf("💳 Delegator final balance: %s XRP\n", finalDelegatorBalance)
fmt.Printf("💳 Delegatee final balance: %s XRP\n", finalDelegateeBalance)
}

View File

@@ -0,0 +1,3 @@
# DepositPreauth
Example of DepositPreauth transaction demonstrating how deposit permissions can be managed.

View File

@@ -0,0 +1,24 @@
module github.com/XRPLF
go 1.23.0
toolchain go1.23.10
require github.com/Peersyst/xrpl-go v0.1.11
require (
github.com/FactomProject/basen v0.0.0-20150613233007-fe3947df716e // indirect
github.com/FactomProject/btcutilecc v0.0.0-20130527213604-d3a63a5752ec // indirect
github.com/btcsuite/btcd/btcec/v2 v2.3.4 // indirect
github.com/decred/dcrd/crypto/ripemd160 v1.0.2 // indirect
github.com/decred/dcrd/dcrec/secp256k1/v4 v4.3.0 // indirect
github.com/gorilla/websocket v1.5.0 // indirect
github.com/json-iterator/go v1.1.12 // indirect
github.com/mitchellh/mapstructure v1.5.0 // indirect
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421 // indirect
github.com/modern-go/reflect2 v1.0.2 // indirect
github.com/tyler-smith/go-bip32 v1.0.0 // indirect
github.com/tyler-smith/go-bip39 v1.1.0 // indirect
github.com/ugorji/go/codec v1.2.11 // indirect
golang.org/x/crypto v0.23.0 // indirect
)

View File

@@ -0,0 +1,58 @@
github.com/FactomProject/basen v0.0.0-20150613233007-fe3947df716e h1:ahyvB3q25YnZWly5Gq1ekg6jcmWaGj/vG/MhF4aisoc=
github.com/FactomProject/basen v0.0.0-20150613233007-fe3947df716e/go.mod h1:kGUqhHd//musdITWjFvNTHn90WG9bMLBEPQZ17Cmlpw=
github.com/FactomProject/btcutilecc v0.0.0-20130527213604-d3a63a5752ec h1:1Qb69mGp/UtRPn422BH4/Y4Q3SLUrD9KHuDkm8iodFc=
github.com/FactomProject/btcutilecc v0.0.0-20130527213604-d3a63a5752ec/go.mod h1:CD8UlnlLDiqb36L110uqiP2iSflVjx9g/3U9hCI4q2U=
github.com/Peersyst/xrpl-go v0.1.11 h1:P6r/gHxRnbAtAdPmzNHz/7zpsdfvwh0SS+QI2JNT44w=
github.com/Peersyst/xrpl-go v0.1.11/go.mod h1:CBRM3/soqNeeL2Jx6USVUtECqulZVUoq3UxZKMz9hdw=
github.com/btcsuite/btcd/btcec/v2 v2.3.4 h1:3EJjcN70HCu/mwqlUsGK8GcNVyLVxFDlWurTXGPFfiQ=
github.com/btcsuite/btcd/btcec/v2 v2.3.4/go.mod h1:zYzJ8etWJQIv1Ogk7OzpWjowwOdXY1W/17j2MW85J04=
github.com/cmars/basen v0.0.0-20150613233007-fe3947df716e h1:0XBUw73chJ1VYSsfvcPvVT7auykAJce9FpRr10L6Qhw=
github.com/cmars/basen v0.0.0-20150613233007-fe3947df716e/go.mod h1:P13beTBKr5Q18lJe1rIoLUqjM+CB1zYrRg44ZqGuQSA=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/decred/dcrd/crypto/blake256 v1.0.1 h1:7PltbUIQB7u/FfZ39+DGa/ShuMyJ5ilcvdfma9wOH6Y=
github.com/decred/dcrd/crypto/blake256 v1.0.1/go.mod h1:2OfgNZ5wDpcsFmHmCK5gZTPcCXqlm2ArzUIkw9czNJo=
github.com/decred/dcrd/crypto/ripemd160 v1.0.2 h1:TvGTmUBHDU75OHro9ojPLK+Yv7gDl2hnUvRocRCjsys=
github.com/decred/dcrd/crypto/ripemd160 v1.0.2/go.mod h1:uGfjDyePSpa75cSQLzNdVmWlbQMBuiJkvXw/MNKRY4M=
github.com/decred/dcrd/dcrec/secp256k1/v4 v4.3.0 h1:rpfIENRNNilwHwZeG5+P150SMrnNEcHYvcCuK6dPZSg=
github.com/decred/dcrd/dcrec/secp256k1/v4 v4.3.0/go.mod h1:v57UDF4pDQJcEfFUCRop3lJL149eHGSe9Jvczhzjo/0=
github.com/golang/mock v1.6.0 h1:ErTB+efbowRARo13NNdxyJji2egdxLGQhRaY+DUumQc=
github.com/golang/mock v1.6.0/go.mod h1:p6yTPP+5HYm5mzsMV8JkE6ZKdX+/wYM6Hr+LicevLPs=
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
github.com/gorilla/websocket v1.5.0 h1:PPwGk2jz7EePpoHN/+ClbZu8SPxiqlu12wZP/3sWmnc=
github.com/gorilla/websocket v1.5.0/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM=
github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo=
github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyuac5Z2hdY=
github.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo=
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421 h1:ZqeYNhU3OHLH3mGKHDcjJRFFRrJa6eAM5H+CtDdOsPc=
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M=
github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/testify v1.1.5-0.20170601210322-f6abca593680/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk=
github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
github.com/tyler-smith/go-bip32 v1.0.0 h1:sDR9juArbUgX+bO/iblgZnMPeWY1KZMUC2AFUJdv5KE=
github.com/tyler-smith/go-bip32 v1.0.0/go.mod h1:onot+eHknzV4BVPwrzqY5OoVpyCvnwD7lMawL5aQupE=
github.com/tyler-smith/go-bip39 v1.1.0 h1:5eUemwrMargf3BSLRRCalXT93Ns6pQJIjYQN2nyfOP8=
github.com/tyler-smith/go-bip39 v1.1.0/go.mod h1:gUYDtqQw1JS3ZJ8UWVcGTGqqr6YIN3CWg+kkNaLt55U=
github.com/ugorji/go/codec v1.2.11 h1:BMaWp1Bb6fHwEtbplGBGJ498wD+LKlNSl25MjdZY4dU=
github.com/ugorji/go/codec v1.2.11/go.mod h1:UNopzCgEMSXjBc6AOMqYvWC1ktqTAfzJZUZgYf6w6lg=
golang.org/x/crypto v0.0.0-20170613210332-850760c427c5/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/crypto v0.23.0 h1:dIJU/v2J8Mdglj/8rJ6UUOM3Zc9zLZxVZwwxMooUSAI=
golang.org/x/crypto v0.23.0/go.mod h1:CKFgDieR+mRhux2Lsu27y0fO304Db0wZe70UKqHu0v8=
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
launchpad.net/gocheck v0.0.0-20140225173054-000000000087 h1:Izowp2XBH6Ya6rv+hqbceQyw/gSGoXfH/UPoTGduL54=
launchpad.net/gocheck v0.0.0-20140225173054-000000000087/go.mod h1:hj7XX3B/0A+80Vse0e+BUHsHMTEhd0O4cpUHr/e/BUM=

View File

@@ -0,0 +1,220 @@
package main
import (
"encoding/hex"
"fmt"
"time"
"github.com/Peersyst/xrpl-go/examples/clients"
"github.com/Peersyst/xrpl-go/pkg/crypto"
"github.com/Peersyst/xrpl-go/xrpl/queries/account"
"github.com/Peersyst/xrpl-go/xrpl/queries/common"
rippletime "github.com/Peersyst/xrpl-go/xrpl/time"
"github.com/Peersyst/xrpl-go/xrpl/transaction"
"github.com/Peersyst/xrpl-go/xrpl/transaction/types"
"github.com/Peersyst/xrpl-go/xrpl/wallet"
)
func main() {
client := clients.GetDevnetRpcClient()
// Configure wallets
// Issuer
fmt.Println("⏳ Setting up credential issuer wallet...")
issuer, err := wallet.New(crypto.ED25519())
if err != nil {
fmt.Printf("❌ Error creating credential issuer wallet: %s\n", err)
return
}
err = client.FundWallet(&issuer)
if err != nil {
fmt.Printf("❌ Error funding credential issuer wallet: %s\n", err)
return
}
fmt.Printf("✅ Credential issuer wallet funded: %s\n", issuer.ClassicAddress)
// -----------------------------------------------------
// Holder 1
fmt.Println("⏳ Setting up holder 1 wallet...")
holderWallet1, err := wallet.New(crypto.ED25519())
if err != nil {
fmt.Printf("❌ Error creating holder 1 wallet: %s\n", err)
return
}
err = client.FundWallet(&holderWallet1)
if err != nil {
fmt.Printf("❌ Error funding holder 1 wallet: %s\n", err)
return
}
fmt.Printf("✅ Holder 1 wallet funded: %s\n", holderWallet1.ClassicAddress)
// -----------------------------------------------------
// Enabling DepositAuth on the issuer account with an AccountSet transaction
fmt.Println("⏳ Enabling DepositAuth on the issuer account...")
accountSetTx := &transaction.AccountSet{
BaseTx: transaction.BaseTx{
Account: issuer.ClassicAddress,
TransactionType: transaction.AccountSetTx,
},
}
accountSetTx.SetAsfDepositAuth()
clients.SubmitTxBlobAndWait(client, accountSetTx, issuer)
// -----------------------------------------------------
// Creating the CredentialCreate transaction
fmt.Println("⏳ Creating the CredentialCreate transaction...")
expiration, err := rippletime.IsoTimeToRippleTime(time.Now().Add(time.Hour * 24).Format(time.RFC3339))
if err != nil {
fmt.Printf("❌ Error converting expiration to ripple time: %s\n", err)
return
}
credentialType := types.CredentialType("6D795F63726564656E7469616C") // my_credential
credentialCreateTx := &transaction.CredentialCreate{
BaseTx: transaction.BaseTx{
Account: issuer.ClassicAddress,
TransactionType: transaction.CredentialCreateTx,
},
Expiration: uint32(expiration),
CredentialType: credentialType,
Subject: types.Address(holderWallet1.ClassicAddress),
URI: hex.EncodeToString([]byte("https://example.com")),
}
clients.SubmitTxBlobAndWait(client, credentialCreateTx, issuer)
// -----------------------------------------------------
// Creating the CredentialAccept transaction
fmt.Println("⏳ Creating the CredentialAccept transaction...")
credentialAcceptTx := &transaction.CredentialAccept{
BaseTx: transaction.BaseTx{
Account: holderWallet1.ClassicAddress,
TransactionType: transaction.CredentialAcceptTx,
},
CredentialType: credentialType,
Issuer: types.Address(issuer.ClassicAddress),
}
clients.SubmitTxBlobAndWait(client, credentialAcceptTx, holderWallet1)
// -----------------------------------------------------
// Creating the DepositPreauth transaction
fmt.Println("⏳ Creating the DepositPreauth transaction using AuthorizeCredentials...")
depositPreauthTx := &transaction.DepositPreauth{
BaseTx: transaction.BaseTx{
Account: issuer.ClassicAddress,
TransactionType: transaction.DepositPreauthTx,
},
AuthorizeCredentials: []types.AuthorizeCredentialsWrapper{
{
Credential: types.AuthorizeCredentials{
Issuer: issuer.ClassicAddress,
CredentialType: credentialType,
},
},
},
}
clients.SubmitTxBlobAndWait(client, depositPreauthTx, issuer)
// -----------------------------------------------------
// Get the credential ID
fmt.Println("⏳ Getting the credential ID from the holder 1 account...")
objectsRequest := &account.ObjectsRequest{
Account: holderWallet1.ClassicAddress,
Type: account.CredentialObject,
LedgerIndex: common.Validated,
}
objectsResponse, err := client.GetAccountObjects(objectsRequest)
if err != nil {
fmt.Printf("❌ Error getting the credential ID: %s\n", err)
return
}
// Check if we have any credential objects
if len(objectsResponse.AccountObjects) == 0 {
fmt.Println("❌ No credential objects found")
return
}
// Extract the credential ID
credentialID, ok := objectsResponse.AccountObjects[0]["index"].(string)
if !ok {
fmt.Println("❌ Could not extract credential ID from response")
return
}
fmt.Printf("✅ Credential ID: %s\n", credentialID)
fmt.Println()
// -----------------------------------------------------
// Sending XRP to the holder 1 account
fmt.Println("⏳ Sending XRP to the issuer account, should succeed...")
sendTx := &transaction.Payment{
BaseTx: transaction.BaseTx{
Account: holderWallet1.ClassicAddress,
TransactionType: transaction.PaymentTx,
},
Amount: types.XRPCurrencyAmount(1000000),
Destination: issuer.ClassicAddress,
CredentialIDs: types.CredentialIDs{credentialID},
}
clients.SubmitTxBlobAndWait(client, sendTx, holderWallet1)
// -----------------------------------------------------
// Unauthorizing the holder 1 account
fmt.Println("⏳ Unauthorizing the holder 1 account with the DepositPreauth transaction and the UnauthorizeCredentials field...")
unauthorizeTx := &transaction.DepositPreauth{
BaseTx: transaction.BaseTx{
Account: issuer.ClassicAddress,
TransactionType: transaction.DepositPreauthTx,
},
UnauthorizeCredentials: []types.AuthorizeCredentialsWrapper{
{
Credential: types.AuthorizeCredentials{
Issuer: issuer.ClassicAddress,
CredentialType: credentialType,
},
},
},
}
clients.SubmitTxBlobAndWait(client, unauthorizeTx, issuer)
// -----------------------------------------------------
// Sending XRP to the holder 1 account again (which should fail)
fmt.Println("⏳ Sending XRP to the issuer account again (which should fail)...")
sendTx2 := &transaction.Payment{
BaseTx: transaction.BaseTx{
Account: holderWallet1.ClassicAddress,
TransactionType: transaction.PaymentTx,
},
Amount: types.XRPCurrencyAmount(1000000),
Destination: issuer.ClassicAddress,
CredentialIDs: types.CredentialIDs{credentialID},
}
clients.SubmitTxBlobAndWait(client, sendTx2, holderWallet1)
}

View File

@@ -0,0 +1,234 @@
package main
import (
"encoding/hex"
"fmt"
"time"
"github.com/Peersyst/xrpl-go/examples/clients"
"github.com/Peersyst/xrpl-go/pkg/crypto"
"github.com/Peersyst/xrpl-go/xrpl/queries/account"
"github.com/Peersyst/xrpl-go/xrpl/queries/common"
rippletime "github.com/Peersyst/xrpl-go/xrpl/time"
"github.com/Peersyst/xrpl-go/xrpl/transaction"
"github.com/Peersyst/xrpl-go/xrpl/transaction/types"
"github.com/Peersyst/xrpl-go/xrpl/wallet"
)
func main() {
fmt.Println("⏳ Setting up client...")
client := clients.GetDevnetWebsocketClient()
fmt.Println("Connecting to server...")
if err := client.Connect(); err != nil {
fmt.Println(err)
return
}
fmt.Println("✅ Client configured!")
fmt.Println()
fmt.Printf("Connection: %t", client.IsConnected())
fmt.Println()
// Configure wallets
// Issuer
fmt.Println("⏳ Setting up credential issuer wallet...")
issuer, err := wallet.New(crypto.ED25519())
if err != nil {
fmt.Printf("❌ Error creating credential issuer wallet: %s\n", err)
return
}
err = client.FundWallet(&issuer)
if err != nil {
fmt.Printf("❌ Error funding credential issuer wallet: %s\n", err)
return
}
fmt.Printf("✅ Credential issuer wallet funded: %s\n", issuer.ClassicAddress)
// -----------------------------------------------------
// Holder 1
fmt.Println("⏳ Setting up holder 1 wallet...")
holderWallet1, err := wallet.New(crypto.ED25519())
if err != nil {
fmt.Printf("❌ Error creating holder 1 wallet: %s\n", err)
return
}
err = client.FundWallet(&holderWallet1)
if err != nil {
fmt.Printf("❌ Error funding holder 1 wallet: %s\n", err)
return
}
fmt.Printf("✅ Holder 1 wallet funded: %s\n", holderWallet1.ClassicAddress)
// -----------------------------------------------------
// Enabling DepositAuth on the issuer account with an AccountSet transaction
fmt.Println("⏳ Enabling DepositAuth on the issuer account...")
accountSetTx := &transaction.AccountSet{
BaseTx: transaction.BaseTx{
Account: issuer.ClassicAddress,
TransactionType: transaction.AccountSetTx,
},
}
accountSetTx.SetAsfDepositAuth()
clients.SubmitTxBlobAndWait(client, accountSetTx, issuer)
// -----------------------------------------------------
// Creating the CredentialCreate transaction
fmt.Println("⏳ Creating the CredentialCreate transaction...")
expiration, err := rippletime.IsoTimeToRippleTime(time.Now().Add(time.Hour * 24).Format(time.RFC3339))
if err != nil {
fmt.Printf("❌ Error converting expiration to ripple time: %s\n", err)
return
}
credentialType := types.CredentialType("6D795F63726564656E7469616C") // my_credential
credentialCreateTx := &transaction.CredentialCreate{
BaseTx: transaction.BaseTx{
Account: issuer.ClassicAddress,
TransactionType: transaction.CredentialCreateTx,
},
Expiration: uint32(expiration),
CredentialType: credentialType,
Subject: types.Address(holderWallet1.ClassicAddress),
URI: hex.EncodeToString([]byte("https://example.com")),
}
clients.SubmitTxBlobAndWait(client, credentialCreateTx, issuer)
// -----------------------------------------------------
// Creating the CredentialAccept transaction
fmt.Println("⏳ Creating the CredentialAccept transaction...")
credentialAcceptTx := &transaction.CredentialAccept{
BaseTx: transaction.BaseTx{
Account: holderWallet1.ClassicAddress,
TransactionType: transaction.CredentialAcceptTx,
},
CredentialType: credentialType,
Issuer: types.Address(issuer.ClassicAddress),
}
clients.SubmitTxBlobAndWait(client, credentialAcceptTx, holderWallet1)
// -----------------------------------------------------
// Creating the DepositPreauth transaction
fmt.Println("⏳ Creating the DepositPreauth transaction using AuthorizeCredentials...")
depositPreauthTx := &transaction.DepositPreauth{
BaseTx: transaction.BaseTx{
Account: issuer.ClassicAddress,
TransactionType: transaction.DepositPreauthTx,
},
AuthorizeCredentials: []types.AuthorizeCredentialsWrapper{
{
Credential: types.AuthorizeCredentials{
Issuer: issuer.ClassicAddress,
CredentialType: credentialType,
},
},
},
}
clients.SubmitTxBlobAndWait(client, depositPreauthTx, issuer)
// -----------------------------------------------------
// Get the credential ID
fmt.Println("⏳ Getting the credential ID from the holder 1 account...")
objectsRequest := &account.ObjectsRequest{
Account: holderWallet1.ClassicAddress,
Type: account.CredentialObject,
LedgerIndex: common.Validated,
}
objectsResponse, err := client.GetAccountObjects(objectsRequest)
if err != nil {
fmt.Printf("❌ Error getting the credential ID: %s\n", err)
return
}
// Check if we have any credential objects
if len(objectsResponse.AccountObjects) == 0 {
fmt.Println("❌ No credential objects found")
return
}
// Extract the credential ID
credentialID, ok := objectsResponse.AccountObjects[0]["index"].(string)
if !ok {
fmt.Println("❌ Could not extract credential ID from response")
return
}
fmt.Printf("✅ Credential ID: %s\n", credentialID)
fmt.Println()
// -----------------------------------------------------
// Sending XRP to the holder 1 account
fmt.Println("⏳ Sending XRP to the issuer account, should succeed...")
sendTx := &transaction.Payment{
BaseTx: transaction.BaseTx{
Account: holderWallet1.ClassicAddress,
TransactionType: transaction.PaymentTx,
},
Amount: types.XRPCurrencyAmount(1000000),
Destination: issuer.ClassicAddress,
CredentialIDs: types.CredentialIDs{credentialID},
}
clients.SubmitTxBlobAndWait(client, sendTx, holderWallet1)
// -----------------------------------------------------
// Unauthorize the holder 1 account
fmt.Println("⏳ Unauthorize the holder 1 account with the DepositPreauth transaction and the UnauthorizeCredentials field...")
unauthorizeTx := &transaction.DepositPreauth{
BaseTx: transaction.BaseTx{
Account: issuer.ClassicAddress,
TransactionType: transaction.DepositPreauthTx,
},
UnauthorizeCredentials: []types.AuthorizeCredentialsWrapper{
{
Credential: types.AuthorizeCredentials{
Issuer: issuer.ClassicAddress,
CredentialType: credentialType,
},
},
},
}
clients.SubmitTxBlobAndWait(client, unauthorizeTx, issuer)
// -----------------------------------------------------
// Sending XRP to the holder 1 account again (which should fail)
fmt.Println("⏳ Sending XRP to the issuer account again (which should fail)...")
sendTx2 := &transaction.Payment{
BaseTx: transaction.BaseTx{
Account: holderWallet1.ClassicAddress,
TransactionType: transaction.PaymentTx,
},
Amount: types.XRPCurrencyAmount(1000000),
Destination: issuer.ClassicAddress,
CredentialIDs: types.CredentialIDs{credentialID},
}
clients.SubmitTxBlobAndWait(client, sendTx2, holderWallet1)
}

View File

@@ -0,0 +1,24 @@
module github.com/XRPLF
go 1.23.0
toolchain go1.23.10
require github.com/Peersyst/xrpl-go v0.1.11
require (
github.com/FactomProject/basen v0.0.0-20150613233007-fe3947df716e // indirect
github.com/FactomProject/btcutilecc v0.0.0-20130527213604-d3a63a5752ec // indirect
github.com/btcsuite/btcd/btcec/v2 v2.3.4 // indirect
github.com/decred/dcrd/crypto/ripemd160 v1.0.2 // indirect
github.com/decred/dcrd/dcrec/secp256k1/v4 v4.3.0 // indirect
github.com/gorilla/websocket v1.5.0 // indirect
github.com/json-iterator/go v1.1.12 // indirect
github.com/mitchellh/mapstructure v1.5.0 // indirect
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421 // indirect
github.com/modern-go/reflect2 v1.0.2 // indirect
github.com/tyler-smith/go-bip32 v1.0.0 // indirect
github.com/tyler-smith/go-bip39 v1.1.0 // indirect
github.com/ugorji/go/codec v1.2.11 // indirect
golang.org/x/crypto v0.23.0 // indirect
)

View File

@@ -0,0 +1,58 @@
github.com/FactomProject/basen v0.0.0-20150613233007-fe3947df716e h1:ahyvB3q25YnZWly5Gq1ekg6jcmWaGj/vG/MhF4aisoc=
github.com/FactomProject/basen v0.0.0-20150613233007-fe3947df716e/go.mod h1:kGUqhHd//musdITWjFvNTHn90WG9bMLBEPQZ17Cmlpw=
github.com/FactomProject/btcutilecc v0.0.0-20130527213604-d3a63a5752ec h1:1Qb69mGp/UtRPn422BH4/Y4Q3SLUrD9KHuDkm8iodFc=
github.com/FactomProject/btcutilecc v0.0.0-20130527213604-d3a63a5752ec/go.mod h1:CD8UlnlLDiqb36L110uqiP2iSflVjx9g/3U9hCI4q2U=
github.com/Peersyst/xrpl-go v0.1.11 h1:P6r/gHxRnbAtAdPmzNHz/7zpsdfvwh0SS+QI2JNT44w=
github.com/Peersyst/xrpl-go v0.1.11/go.mod h1:CBRM3/soqNeeL2Jx6USVUtECqulZVUoq3UxZKMz9hdw=
github.com/btcsuite/btcd/btcec/v2 v2.3.4 h1:3EJjcN70HCu/mwqlUsGK8GcNVyLVxFDlWurTXGPFfiQ=
github.com/btcsuite/btcd/btcec/v2 v2.3.4/go.mod h1:zYzJ8etWJQIv1Ogk7OzpWjowwOdXY1W/17j2MW85J04=
github.com/cmars/basen v0.0.0-20150613233007-fe3947df716e h1:0XBUw73chJ1VYSsfvcPvVT7auykAJce9FpRr10L6Qhw=
github.com/cmars/basen v0.0.0-20150613233007-fe3947df716e/go.mod h1:P13beTBKr5Q18lJe1rIoLUqjM+CB1zYrRg44ZqGuQSA=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/decred/dcrd/crypto/blake256 v1.0.1 h1:7PltbUIQB7u/FfZ39+DGa/ShuMyJ5ilcvdfma9wOH6Y=
github.com/decred/dcrd/crypto/blake256 v1.0.1/go.mod h1:2OfgNZ5wDpcsFmHmCK5gZTPcCXqlm2ArzUIkw9czNJo=
github.com/decred/dcrd/crypto/ripemd160 v1.0.2 h1:TvGTmUBHDU75OHro9ojPLK+Yv7gDl2hnUvRocRCjsys=
github.com/decred/dcrd/crypto/ripemd160 v1.0.2/go.mod h1:uGfjDyePSpa75cSQLzNdVmWlbQMBuiJkvXw/MNKRY4M=
github.com/decred/dcrd/dcrec/secp256k1/v4 v4.3.0 h1:rpfIENRNNilwHwZeG5+P150SMrnNEcHYvcCuK6dPZSg=
github.com/decred/dcrd/dcrec/secp256k1/v4 v4.3.0/go.mod h1:v57UDF4pDQJcEfFUCRop3lJL149eHGSe9Jvczhzjo/0=
github.com/golang/mock v1.6.0 h1:ErTB+efbowRARo13NNdxyJji2egdxLGQhRaY+DUumQc=
github.com/golang/mock v1.6.0/go.mod h1:p6yTPP+5HYm5mzsMV8JkE6ZKdX+/wYM6Hr+LicevLPs=
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
github.com/gorilla/websocket v1.5.0 h1:PPwGk2jz7EePpoHN/+ClbZu8SPxiqlu12wZP/3sWmnc=
github.com/gorilla/websocket v1.5.0/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM=
github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo=
github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyuac5Z2hdY=
github.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo=
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421 h1:ZqeYNhU3OHLH3mGKHDcjJRFFRrJa6eAM5H+CtDdOsPc=
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M=
github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/testify v1.1.5-0.20170601210322-f6abca593680/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk=
github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
github.com/tyler-smith/go-bip32 v1.0.0 h1:sDR9juArbUgX+bO/iblgZnMPeWY1KZMUC2AFUJdv5KE=
github.com/tyler-smith/go-bip32 v1.0.0/go.mod h1:onot+eHknzV4BVPwrzqY5OoVpyCvnwD7lMawL5aQupE=
github.com/tyler-smith/go-bip39 v1.1.0 h1:5eUemwrMargf3BSLRRCalXT93Ns6pQJIjYQN2nyfOP8=
github.com/tyler-smith/go-bip39 v1.1.0/go.mod h1:gUYDtqQw1JS3ZJ8UWVcGTGqqr6YIN3CWg+kkNaLt55U=
github.com/ugorji/go/codec v1.2.11 h1:BMaWp1Bb6fHwEtbplGBGJ498wD+LKlNSl25MjdZY4dU=
github.com/ugorji/go/codec v1.2.11/go.mod h1:UNopzCgEMSXjBc6AOMqYvWC1ktqTAfzJZUZgYf6w6lg=
golang.org/x/crypto v0.0.0-20170613210332-850760c427c5/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/crypto v0.23.0 h1:dIJU/v2J8Mdglj/8rJ6UUOM3Zc9zLZxVZwwxMooUSAI=
golang.org/x/crypto v0.23.0/go.mod h1:CKFgDieR+mRhux2Lsu27y0fO304Db0wZe70UKqHu0v8=
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
launchpad.net/gocheck v0.0.0-20140225173054-000000000087 h1:Izowp2XBH6Ya6rv+hqbceQyw/gSGoXfH/UPoTGduL54=
launchpad.net/gocheck v0.0.0-20140225173054-000000000087/go.mod h1:hj7XX3B/0A+80Vse0e+BUHsHMTEhd0O4cpUHr/e/BUM=

View File

@@ -0,0 +1,347 @@
package main
import (
"fmt"
"github.com/Peersyst/xrpl-go/pkg/crypto"
"github.com/Peersyst/xrpl-go/xrpl/currency"
"github.com/Peersyst/xrpl-go/xrpl/faucet"
"github.com/Peersyst/xrpl-go/xrpl/rpc"
transactions "github.com/Peersyst/xrpl-go/xrpl/transaction"
"github.com/Peersyst/xrpl-go/xrpl/transaction/types"
"github.com/Peersyst/xrpl-go/xrpl/wallet"
)
const (
currencyCode = "USDA"
)
type SubmittableTransaction interface {
TxType() transactions.TxType
Flatten() transactions.FlatTransaction // Ensures all transactions can be flattened
}
func main() {
client := getRpcClient()
// Configure wallets
// Issuer
fmt.Println("⏳ Setting up issuer wallet...")
issuer, err := wallet.New(crypto.ED25519())
if err != nil {
fmt.Printf("❌ Error creating issuer wallet: %s\n", err)
return
}
err = client.FundWallet(&issuer)
if err != nil {
fmt.Printf("❌ Error funding issuer wallet: %s\n", err)
return
}
fmt.Printf("✅ Issuer wallet funded: %s\n", issuer.ClassicAddress)
// -----------------------------------------------------
// Holder 1
fmt.Println("⏳ Setting up holder 1 wallet...")
holderWallet1, err := wallet.New(crypto.ED25519())
if err != nil {
fmt.Printf("❌ Error creating holder wallet 1: %s\n", err)
return
}
err = client.FundWallet(&holderWallet1)
if err != nil {
fmt.Printf("❌ Error funding holder wallet 1: %s\n", err)
return
}
fmt.Printf("✅ Holder wallet 1 funded: %s\n", holderWallet1.ClassicAddress)
// -----------------------------------------------------
// Holder 2
fmt.Println("⏳ Setting up holder 2 wallet...")
holderWallet2, err := wallet.New(crypto.ED25519())
if err != nil {
fmt.Printf("❌ Error creating holder wallet 2: %s\n", err)
return
}
err = client.FundWallet(&holderWallet2)
if err != nil {
fmt.Printf("❌ Error funding holder wallet 2: %s\n", err)
return
}
fmt.Printf("✅ Holder wallet 2 funded: %s\n", holderWallet2.ClassicAddress)
fmt.Println()
fmt.Println("✅ Wallets setup complete!")
fmt.Println()
// -----------------------------------------------------
// Configuring Issuing account
fmt.Println("⏳ Configuring issuer address settings...")
accountSet := &transactions.AccountSet{
BaseTx: transactions.BaseTx{
Account: types.Address(issuer.ClassicAddress),
},
Domain: types.Domain("697373756572"), // issuer
}
accountSet.SetAsfDefaultRipple()
submitAndWait(client, accountSet, issuer)
// -----------------------------------------------------
// Trustline from the holder 1 to the issuer
fmt.Println("⏳ Setting up trustline from holder 1 to the issuer...")
trustSet := &transactions.TrustSet{
BaseTx: transactions.BaseTx{
Account: types.Address(holderWallet1.ClassicAddress),
},
LimitAmount: types.IssuedCurrencyAmount{
Currency: currency.ConvertStringToHex(currencyCode),
Issuer: types.Address(issuer.ClassicAddress),
Value: "1000000000",
}}
trustSet.SetSetNoRippleFlag()
submitAndWait(client, trustSet, holderWallet1)
// -----------------------------------------------------
// Trustline from the holder 2 to the issuer
fmt.Println("⏳ Setting up trustline from holder 2 to the issuer...")
trustSet = &transactions.TrustSet{
BaseTx: transactions.BaseTx{
Account: types.Address(holderWallet2.ClassicAddress),
},
LimitAmount: types.IssuedCurrencyAmount{
Currency: currency.ConvertStringToHex(currencyCode),
Issuer: types.Address(issuer.ClassicAddress),
Value: "1000000000",
},
}
trustSet.SetSetNoRippleFlag()
submitAndWait(client, trustSet, holderWallet2)
// -----------------------------------------------------
// Minting to Holder 1
fmt.Println("⏳ Minting to Holder 1...")
payment := &transactions.Payment{
BaseTx: transactions.BaseTx{
Account: types.Address(issuer.ClassicAddress),
},
Destination: types.Address(holderWallet1.ClassicAddress),
Amount: types.IssuedCurrencyAmount{
Currency: currency.ConvertStringToHex(currencyCode),
Issuer: types.Address(issuer.ClassicAddress),
Value: "50000",
},
}
submitAndWait(client, payment, issuer)
// -----------------------------------------------------
// Minting to Holder 2
fmt.Println("⏳ Minting to Holder 2...")
payment = &transactions.Payment{
BaseTx: transactions.BaseTx{
Account: types.Address(issuer.ClassicAddress),
},
Destination: types.Address(holderWallet2.ClassicAddress),
Amount: types.IssuedCurrencyAmount{
Currency: currency.ConvertStringToHex(currencyCode),
Issuer: types.Address(issuer.ClassicAddress),
Value: "40000",
},
}
submitAndWait(client, payment, issuer)
// -----------------------------------------------------
// Sending payment from Holder 1 to Holder 2
fmt.Println("⏳ Sending payment from Holder 1 to Holder 2...")
payment = &transactions.Payment{
BaseTx: transactions.BaseTx{
Account: types.Address(holderWallet1.ClassicAddress),
},
Destination: types.Address(holderWallet2.ClassicAddress),
Amount: types.IssuedCurrencyAmount{
Currency: currency.ConvertStringToHex(currencyCode),
Issuer: types.Address(issuer.ClassicAddress),
Value: "20",
},
}
submitAndWait(client, payment, holderWallet1)
// -----------------------------------------------------
// Freezing and Deep Freezing holder1
fmt.Println("⏳ Freezing and Deep Freezing holder 1 trustline...")
trustSet = &transactions.TrustSet{
BaseTx: transactions.BaseTx{
Account: types.Address(issuer.ClassicAddress),
},
LimitAmount: types.IssuedCurrencyAmount{
Currency: currency.ConvertStringToHex(currencyCode),
Issuer: types.Address(holderWallet1.ClassicAddress),
Value: "0",
},
}
trustSet.SetSetFreezeFlag()
trustSet.SetSetDeepFreezeFlag()
submitAndWait(client, trustSet, issuer)
// ------------------- SHOULD FAIL ⬇️ ------------------
// Sending payment from Holder 1 to Holder 2 (which should fail), Holder 1 can't decrease its balance
fmt.Println("⏳ Sending payment from Holder 1 to Holder 2 (which should fail). Holder 1 can't decrease its balance...")
payment = &transactions.Payment{
BaseTx: transactions.BaseTx{
Account: types.Address(holderWallet1.ClassicAddress),
},
Destination: types.Address(holderWallet2.ClassicAddress),
Amount: types.IssuedCurrencyAmount{
Currency: currency.ConvertStringToHex(currencyCode),
Issuer: types.Address(issuer.ClassicAddress),
Value: "10",
},
}
submitAndWait(client, payment, holderWallet1)
// ------------------- SHOULD FAIL ⬇️ ------------------
// Sending payment from Holder 2 to Holder 1 (which should fail), Holder 1 can't increase its balance
fmt.Println("⏳ Sending payment from Holder 2 to Holder 1 (which should fail). Holder 1 can't increase its balance...")
payment = &transactions.Payment{
BaseTx: transactions.BaseTx{
Account: types.Address(holderWallet2.ClassicAddress),
},
Destination: types.Address(holderWallet1.ClassicAddress),
Amount: types.IssuedCurrencyAmount{
Currency: currency.ConvertStringToHex(currencyCode),
Issuer: types.Address(issuer.ClassicAddress),
Value: "10",
},
}
submitAndWait(client, payment, holderWallet2)
// ------------------- SHOULD FAIL ⬇️ ------------------
// Creating OfferCreate transaction (which should fail), Holder 1 can't create an offer
fmt.Println("⏳ Creating OfferCreate transaction (which should fail). Holder 1 can't create an offer...")
offerCreate := &transactions.OfferCreate{
BaseTx: transactions.BaseTx{
Account: types.Address(holderWallet1.ClassicAddress),
},
TakerPays: types.IssuedCurrencyAmount{
Currency: currency.ConvertStringToHex(currencyCode),
Issuer: types.Address(issuer.ClassicAddress),
Value: "10",
},
TakerGets: types.XRPCurrencyAmount(10),
}
submitAndWait(client, offerCreate, holderWallet1)
// -----------------------------------------------------
// Unfreezing and Deep Unfreezing holder 1
fmt.Println("⏳ Unfreezing and Deep Unfreezing holder 1 trustline...")
trustSet = &transactions.TrustSet{
BaseTx: transactions.BaseTx{
Account: types.Address(issuer.ClassicAddress),
},
LimitAmount: types.IssuedCurrencyAmount{
Currency: currency.ConvertStringToHex(currencyCode),
Issuer: types.Address(holderWallet1.ClassicAddress),
Value: "0",
},
}
trustSet.SetClearFreezeFlag()
trustSet.SetClearDeepFreezeFlag()
submitAndWait(client, trustSet, issuer)
// -----------------------------------------------------
// Sending payment from Holder 1 to Holder 2 (which should succeed), Holder 1 can decrease its balance
fmt.Println("⏳ Sending payment from Holder 1 to Holder 2 (which should succeed). Holder 1 can decrease its balance...")
payment = &transactions.Payment{
BaseTx: transactions.BaseTx{
Account: types.Address(holderWallet1.ClassicAddress),
},
Destination: types.Address(holderWallet2.ClassicAddress),
Amount: types.IssuedCurrencyAmount{
Currency: currency.ConvertStringToHex(currencyCode),
Issuer: types.Address(issuer.ClassicAddress),
Value: "10",
},
}
submitAndWait(client, payment, holderWallet1)
// -----------------------------------------------------
// Sending payment from Holder 2 to Holder 1 (which should succeed), Holder 1 can increase its balance
fmt.Println("⏳ Sending payment from Holder 2 to Holder 1 (which should succeed). Holder 1 can increase its balance...")
payment = &transactions.Payment{
BaseTx: transactions.BaseTx{
Account: types.Address(holderWallet2.ClassicAddress),
},
Destination: types.Address(holderWallet1.ClassicAddress),
Amount: types.IssuedCurrencyAmount{
Currency: currency.ConvertStringToHex(currencyCode),
Issuer: types.Address(issuer.ClassicAddress),
Value: "10",
},
}
submitAndWait(client, payment, holderWallet2)
}
// getRpcClient returns a new rpc client
func getRpcClient() *rpc.Client {
cfg, err := rpc.NewClientConfig(
// DeepFreeze only available on Devnet as of February 2025, change to testnet/mainnet once the amendment passes.
"https://s.devnet.rippletest.net:51234",
rpc.WithFaucetProvider(faucet.NewDevnetFaucetProvider()),
)
if err != nil {
panic(err)
}
return rpc.NewClient(cfg)
}
// submitAndWait submits a transaction and waits for it to be included in a validated ledger
func submitAndWait(client *rpc.Client, txn SubmittableTransaction, wallet wallet.Wallet) {
fmt.Printf("⏳ Submitting %s transaction...\n", txn.TxType())
flattenedTx := txn.Flatten()
err := client.Autofill(&flattenedTx)
if err != nil {
fmt.Printf("❌ Error autofilling %s transaction: %s\n", txn.TxType(), err)
fmt.Println()
return
}
txBlob, _, err := wallet.Sign(flattenedTx)
if err != nil {
fmt.Printf("❌ Error signing %s transaction: %s\n", txn.TxType(), err)
fmt.Println()
return
}
response, err := client.SubmitTxBlobAndWait(txBlob, false)
if err != nil {
fmt.Printf("❌ Error submitting %s transaction: %s\n", txn.TxType(), err)
fmt.Println()
return
}
fmt.Printf("✅ %s transaction submitted\n", txn.TxType())
fmt.Printf("🌐 Hash: %s\n", response.Hash.String())
fmt.Println()
}

View File

@@ -0,0 +1,357 @@
package main
import (
"fmt"
"github.com/Peersyst/xrpl-go/pkg/crypto"
"github.com/Peersyst/xrpl-go/xrpl/currency"
"github.com/Peersyst/xrpl-go/xrpl/faucet"
transactions "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"
)
const (
currencyCode = "USDA"
)
type SubmittableTransaction interface {
TxType() transactions.TxType
Flatten() transactions.FlatTransaction // Ensures all transactions can be flattened
}
func main() {
fmt.Println("⏳ Setting up client...")
client := getClient()
fmt.Println("Connecting to server...")
if err := client.Connect(); err != nil {
fmt.Println(err)
return
}
fmt.Println("✅ Client configured!")
fmt.Println()
fmt.Printf("Connection: %t", client.IsConnected())
fmt.Println()
// Configure wallets
// Issuer
fmt.Println("⏳ Setting up issuer wallet...")
issuer, err := wallet.New(crypto.ED25519())
if err != nil {
fmt.Printf("❌ Error creating issuer wallet: %s\n", err)
return
}
err = client.FundWallet(&issuer)
if err != nil {
fmt.Printf("❌ Error funding issuer wallet: %s\n", err)
return
}
fmt.Printf("✅ Issuer wallet funded: %s\n", issuer.ClassicAddress)
// -----------------------------------------------------
// Holder 1
fmt.Println("⏳ Setting up holder 1 wallet...")
holderWallet1, err := wallet.New(crypto.ED25519())
if err != nil {
fmt.Printf("❌ Error creating holder wallet 1: %s\n", err)
return
}
err = client.FundWallet(&holderWallet1)
if err != nil {
fmt.Printf("❌ Error funding holder wallet 1: %s\n", err)
return
}
fmt.Printf("✅ Holder wallet 1 funded: %s\n", holderWallet1.ClassicAddress)
// -----------------------------------------------------
// Holder 2
fmt.Println("⏳ Setting up holder 2 wallet...")
holderWallet2, err := wallet.New(crypto.ED25519())
if err != nil {
fmt.Printf("❌ Error creating holder wallet 2: %s\n", err)
return
}
err = client.FundWallet(&holderWallet2)
if err != nil {
fmt.Printf("❌ Error funding holder wallet 2: %s\n", err)
return
}
fmt.Printf("✅ Holder wallet 2 funded: %s\n", holderWallet2.ClassicAddress)
fmt.Println()
fmt.Println("✅ Wallets setup complete!")
fmt.Println()
// -----------------------------------------------------
// Configuring Issuing account
fmt.Println("⏳ Configuring issuer address settings...")
accountSet := &transactions.AccountSet{
BaseTx: transactions.BaseTx{
Account: types.Address(issuer.ClassicAddress),
},
Domain: types.Domain("697373756572"), // issuer
}
accountSet.SetAsfDefaultRipple()
submitAndWait(client, accountSet, issuer)
// -----------------------------------------------------
// Trustline from the holder 1 to the issuer
fmt.Println("⏳ Setting up trustline from holder 1 to the issuer...")
trustSet := &transactions.TrustSet{
BaseTx: transactions.BaseTx{
Account: types.Address(holderWallet1.ClassicAddress),
},
LimitAmount: types.IssuedCurrencyAmount{
Currency: currency.ConvertStringToHex(currencyCode),
Issuer: types.Address(issuer.ClassicAddress),
Value: "1000000000",
}}
trustSet.SetSetNoRippleFlag()
submitAndWait(client, trustSet, holderWallet1)
// -----------------------------------------------------
// Trustline from the holder 2 to the issuer
fmt.Println("⏳ Setting up trustline from holder 2 to the issuer...")
trustSet = &transactions.TrustSet{
BaseTx: transactions.BaseTx{
Account: types.Address(holderWallet2.ClassicAddress),
},
LimitAmount: types.IssuedCurrencyAmount{
Currency: currency.ConvertStringToHex(currencyCode),
Issuer: types.Address(issuer.ClassicAddress),
Value: "1000000000",
},
}
trustSet.SetSetNoRippleFlag()
submitAndWait(client, trustSet, holderWallet2)
// -----------------------------------------------------
// Minting to Holder 1
fmt.Println("⏳ Minting to Holder 1...")
payment := &transactions.Payment{
BaseTx: transactions.BaseTx{
Account: types.Address(issuer.ClassicAddress),
},
Destination: types.Address(holderWallet1.ClassicAddress),
Amount: types.IssuedCurrencyAmount{
Currency: currency.ConvertStringToHex(currencyCode),
Issuer: types.Address(issuer.ClassicAddress),
Value: "50000",
},
}
submitAndWait(client, payment, issuer)
// -----------------------------------------------------
// Minting to Holder 2
fmt.Println("⏳ Minting to Holder 2...")
payment = &transactions.Payment{
BaseTx: transactions.BaseTx{
Account: types.Address(issuer.ClassicAddress),
},
Destination: types.Address(holderWallet2.ClassicAddress),
Amount: types.IssuedCurrencyAmount{
Currency: currency.ConvertStringToHex(currencyCode),
Issuer: types.Address(issuer.ClassicAddress),
Value: "40000",
},
}
submitAndWait(client, payment, issuer)
// -----------------------------------------------------
// Sending payment from Holder 1 to Holder 2
fmt.Println("⏳ Sending payment from Holder 1 to Holder 2...")
payment = &transactions.Payment{
BaseTx: transactions.BaseTx{
Account: types.Address(holderWallet1.ClassicAddress),
},
Destination: types.Address(holderWallet2.ClassicAddress),
Amount: types.IssuedCurrencyAmount{
Currency: currency.ConvertStringToHex(currencyCode),
Issuer: types.Address(issuer.ClassicAddress),
Value: "20",
},
}
submitAndWait(client, payment, holderWallet1)
// -----------------------------------------------------
// Freezing and Deep Freezing holder1
fmt.Println("⏳ Freezing and Deep Freezing holder 1 trustline...")
trustSet = &transactions.TrustSet{
BaseTx: transactions.BaseTx{
Account: types.Address(issuer.ClassicAddress),
},
LimitAmount: types.IssuedCurrencyAmount{
Currency: currency.ConvertStringToHex(currencyCode),
Issuer: types.Address(holderWallet1.ClassicAddress),
Value: "0",
},
}
trustSet.SetSetFreezeFlag()
trustSet.SetSetDeepFreezeFlag()
submitAndWait(client, trustSet, issuer)
// ------------------- SHOULD FAIL ⬇️ ------------------
// Sending payment from Holder 1 to Holder 2 (which should fail), Holder 1 can't decrease its balance
fmt.Println("⏳ Sending payment from Holder 1 to Holder 2 (which should fail). Holder 1 can't decrease its balance...")
payment = &transactions.Payment{
BaseTx: transactions.BaseTx{
Account: types.Address(holderWallet1.ClassicAddress),
},
Destination: types.Address(holderWallet2.ClassicAddress),
Amount: types.IssuedCurrencyAmount{
Currency: currency.ConvertStringToHex(currencyCode),
Issuer: types.Address(issuer.ClassicAddress),
Value: "10",
},
}
submitAndWait(client, payment, holderWallet1)
// ------------------- SHOULD FAIL ⬇️ ------------------
// Sending payment from Holder 2 to Holder 1 (which should fail), Holder 1 can't increase its balance
fmt.Println("⏳ Sending payment from Holder 2 to Holder 1 (which should fail). Holder 1 can't increase its balance...")
payment = &transactions.Payment{
BaseTx: transactions.BaseTx{
Account: types.Address(holderWallet2.ClassicAddress),
},
Destination: types.Address(holderWallet1.ClassicAddress),
Amount: types.IssuedCurrencyAmount{
Currency: currency.ConvertStringToHex(currencyCode),
Issuer: types.Address(issuer.ClassicAddress),
Value: "10",
},
}
submitAndWait(client, payment, holderWallet2)
// ------------------- SHOULD FAIL ⬇️ ------------------
// Creating OfferCreate transaction (which should fail), Holder 1 can't create an offer
fmt.Println("⏳ Creating OfferCreate transaction (which should fail). Holder 1 can't create an offer...")
offerCreate := &transactions.OfferCreate{
BaseTx: transactions.BaseTx{
Account: types.Address(holderWallet1.ClassicAddress),
},
TakerPays: types.IssuedCurrencyAmount{
Currency: currency.ConvertStringToHex(currencyCode),
Issuer: types.Address(issuer.ClassicAddress),
Value: "10",
},
TakerGets: types.XRPCurrencyAmount(10),
}
submitAndWait(client, offerCreate, holderWallet1)
// -----------------------------------------------------
// Unfreezing and Deep Unfreezing holder 1
fmt.Println("⏳ Unfreezing and Deep Unfreezing holder 1 trustline...")
trustSet = &transactions.TrustSet{
BaseTx: transactions.BaseTx{
Account: types.Address(issuer.ClassicAddress),
},
LimitAmount: types.IssuedCurrencyAmount{
Currency: currency.ConvertStringToHex(currencyCode),
Issuer: types.Address(holderWallet1.ClassicAddress),
Value: "0",
},
}
trustSet.SetClearFreezeFlag()
trustSet.SetClearDeepFreezeFlag()
submitAndWait(client, trustSet, issuer)
// -----------------------------------------------------
// Sending payment from Holder 1 to Holder 2 (which should succeed), Holder 1 can decrease its balance
fmt.Println("⏳ Sending payment from Holder 1 to Holder 2 (which should succeed). Holder 1 can decrease its balance...")
payment = &transactions.Payment{
BaseTx: transactions.BaseTx{
Account: types.Address(holderWallet1.ClassicAddress),
},
Destination: types.Address(holderWallet2.ClassicAddress),
Amount: types.IssuedCurrencyAmount{
Currency: currency.ConvertStringToHex(currencyCode),
Issuer: types.Address(issuer.ClassicAddress),
Value: "10",
},
}
submitAndWait(client, payment, holderWallet1)
// -----------------------------------------------------
// Sending payment from Holder 2 to Holder 1 (which should succeed), Holder 1 can increase its balance
fmt.Println("⏳ Sending payment from Holder 2 to Holder 1 (which should succeed). Holder 1 can increase its balance...")
payment = &transactions.Payment{
BaseTx: transactions.BaseTx{
Account: types.Address(holderWallet2.ClassicAddress),
},
Destination: types.Address(holderWallet1.ClassicAddress),
Amount: types.IssuedCurrencyAmount{
Currency: currency.ConvertStringToHex(currencyCode),
Issuer: types.Address(issuer.ClassicAddress),
Value: "10",
},
}
submitAndWait(client, payment, holderWallet2)
}
// getRpcClient returns a new rpc client
func getClient() *websocket.Client {
client := websocket.NewClient(
websocket.NewClientConfig().
WithHost("wss://s.devnet.rippletest.net:51233").
WithFaucetProvider(faucet.NewDevnetFaucetProvider()),
)
return client
}
// submitAndWait submits a transaction and waits for it to be included in a validated ledger
func submitAndWait(client *websocket.Client, txn SubmittableTransaction, wallet wallet.Wallet) {
fmt.Printf("⏳ Submitting %s transaction...\n", txn.TxType())
flattenedTx := txn.Flatten()
err := client.Autofill(&flattenedTx)
if err != nil {
fmt.Printf("❌ Error autofilling %s transaction: %s\n", txn.TxType(), err)
fmt.Println()
return
}
txBlob, _, err := wallet.Sign(flattenedTx)
if err != nil {
fmt.Printf("❌ Error signing %s transaction: %s\n", txn.TxType(), err)
fmt.Println()
return
}
response, err := client.SubmitTxBlobAndWait(txBlob, false)
if err != nil {
fmt.Printf("❌ Error submitting %s transaction: %s\n", txn.TxType(), err)
fmt.Println()
return
}
fmt.Printf("✅ %s transaction submitted\n", txn.TxType())
fmt.Printf("🌐 Hash: %s\n", response.Hash.String())
fmt.Println()
}

View File

@@ -0,0 +1,24 @@
module github.com/XRPLF
go 1.23.0
toolchain go1.23.10
require github.com/Peersyst/xrpl-go v0.1.11
require (
github.com/FactomProject/basen v0.0.0-20150613233007-fe3947df716e // indirect
github.com/FactomProject/btcutilecc v0.0.0-20130527213604-d3a63a5752ec // indirect
github.com/btcsuite/btcd/btcec/v2 v2.3.4 // indirect
github.com/decred/dcrd/crypto/ripemd160 v1.0.2 // indirect
github.com/decred/dcrd/dcrec/secp256k1/v4 v4.3.0 // indirect
github.com/gorilla/websocket v1.5.0 // indirect
github.com/json-iterator/go v1.1.12 // indirect
github.com/mitchellh/mapstructure v1.5.0 // indirect
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421 // indirect
github.com/modern-go/reflect2 v1.0.2 // indirect
github.com/tyler-smith/go-bip32 v1.0.0 // indirect
github.com/tyler-smith/go-bip39 v1.1.0 // indirect
github.com/ugorji/go/codec v1.2.11 // indirect
golang.org/x/crypto v0.23.0 // indirect
)

View File

@@ -0,0 +1,58 @@
github.com/FactomProject/basen v0.0.0-20150613233007-fe3947df716e h1:ahyvB3q25YnZWly5Gq1ekg6jcmWaGj/vG/MhF4aisoc=
github.com/FactomProject/basen v0.0.0-20150613233007-fe3947df716e/go.mod h1:kGUqhHd//musdITWjFvNTHn90WG9bMLBEPQZ17Cmlpw=
github.com/FactomProject/btcutilecc v0.0.0-20130527213604-d3a63a5752ec h1:1Qb69mGp/UtRPn422BH4/Y4Q3SLUrD9KHuDkm8iodFc=
github.com/FactomProject/btcutilecc v0.0.0-20130527213604-d3a63a5752ec/go.mod h1:CD8UlnlLDiqb36L110uqiP2iSflVjx9g/3U9hCI4q2U=
github.com/Peersyst/xrpl-go v0.1.11 h1:P6r/gHxRnbAtAdPmzNHz/7zpsdfvwh0SS+QI2JNT44w=
github.com/Peersyst/xrpl-go v0.1.11/go.mod h1:CBRM3/soqNeeL2Jx6USVUtECqulZVUoq3UxZKMz9hdw=
github.com/btcsuite/btcd/btcec/v2 v2.3.4 h1:3EJjcN70HCu/mwqlUsGK8GcNVyLVxFDlWurTXGPFfiQ=
github.com/btcsuite/btcd/btcec/v2 v2.3.4/go.mod h1:zYzJ8etWJQIv1Ogk7OzpWjowwOdXY1W/17j2MW85J04=
github.com/cmars/basen v0.0.0-20150613233007-fe3947df716e h1:0XBUw73chJ1VYSsfvcPvVT7auykAJce9FpRr10L6Qhw=
github.com/cmars/basen v0.0.0-20150613233007-fe3947df716e/go.mod h1:P13beTBKr5Q18lJe1rIoLUqjM+CB1zYrRg44ZqGuQSA=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/decred/dcrd/crypto/blake256 v1.0.1 h1:7PltbUIQB7u/FfZ39+DGa/ShuMyJ5ilcvdfma9wOH6Y=
github.com/decred/dcrd/crypto/blake256 v1.0.1/go.mod h1:2OfgNZ5wDpcsFmHmCK5gZTPcCXqlm2ArzUIkw9czNJo=
github.com/decred/dcrd/crypto/ripemd160 v1.0.2 h1:TvGTmUBHDU75OHro9ojPLK+Yv7gDl2hnUvRocRCjsys=
github.com/decred/dcrd/crypto/ripemd160 v1.0.2/go.mod h1:uGfjDyePSpa75cSQLzNdVmWlbQMBuiJkvXw/MNKRY4M=
github.com/decred/dcrd/dcrec/secp256k1/v4 v4.3.0 h1:rpfIENRNNilwHwZeG5+P150SMrnNEcHYvcCuK6dPZSg=
github.com/decred/dcrd/dcrec/secp256k1/v4 v4.3.0/go.mod h1:v57UDF4pDQJcEfFUCRop3lJL149eHGSe9Jvczhzjo/0=
github.com/golang/mock v1.6.0 h1:ErTB+efbowRARo13NNdxyJji2egdxLGQhRaY+DUumQc=
github.com/golang/mock v1.6.0/go.mod h1:p6yTPP+5HYm5mzsMV8JkE6ZKdX+/wYM6Hr+LicevLPs=
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
github.com/gorilla/websocket v1.5.0 h1:PPwGk2jz7EePpoHN/+ClbZu8SPxiqlu12wZP/3sWmnc=
github.com/gorilla/websocket v1.5.0/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM=
github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo=
github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyuac5Z2hdY=
github.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo=
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421 h1:ZqeYNhU3OHLH3mGKHDcjJRFFRrJa6eAM5H+CtDdOsPc=
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M=
github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/testify v1.1.5-0.20170601210322-f6abca593680/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk=
github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
github.com/tyler-smith/go-bip32 v1.0.0 h1:sDR9juArbUgX+bO/iblgZnMPeWY1KZMUC2AFUJdv5KE=
github.com/tyler-smith/go-bip32 v1.0.0/go.mod h1:onot+eHknzV4BVPwrzqY5OoVpyCvnwD7lMawL5aQupE=
github.com/tyler-smith/go-bip39 v1.1.0 h1:5eUemwrMargf3BSLRRCalXT93Ns6pQJIjYQN2nyfOP8=
github.com/tyler-smith/go-bip39 v1.1.0/go.mod h1:gUYDtqQw1JS3ZJ8UWVcGTGqqr6YIN3CWg+kkNaLt55U=
github.com/ugorji/go/codec v1.2.11 h1:BMaWp1Bb6fHwEtbplGBGJ498wD+LKlNSl25MjdZY4dU=
github.com/ugorji/go/codec v1.2.11/go.mod h1:UNopzCgEMSXjBc6AOMqYvWC1ktqTAfzJZUZgYf6w6lg=
golang.org/x/crypto v0.0.0-20170613210332-850760c427c5/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/crypto v0.23.0 h1:dIJU/v2J8Mdglj/8rJ6UUOM3Zc9zLZxVZwwxMooUSAI=
golang.org/x/crypto v0.23.0/go.mod h1:CKFgDieR+mRhux2Lsu27y0fO304Db0wZe70UKqHu0v8=
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
launchpad.net/gocheck v0.0.0-20140225173054-000000000087 h1:Izowp2XBH6Ya6rv+hqbceQyw/gSGoXfH/UPoTGduL54=
launchpad.net/gocheck v0.0.0-20140225173054-000000000087/go.mod h1:hj7XX3B/0A+80Vse0e+BUHsHMTEhd0O4cpUHr/e/BUM=

View File

@@ -0,0 +1,166 @@
package main
import (
"encoding/hex"
"fmt"
"maps"
"strings"
"github.com/Peersyst/xrpl-go/xrpl"
"github.com/Peersyst/xrpl-go/xrpl/faucet"
"github.com/Peersyst/xrpl-go/xrpl/ledger-entry-types"
"github.com/Peersyst/xrpl-go/xrpl/rpc"
"github.com/Peersyst/xrpl-go/xrpl/transaction"
"github.com/Peersyst/xrpl-go/xrpl/transaction/types"
"github.com/Peersyst/xrpl-go/xrpl/wallet"
)
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)
w1, err := wallet.FromSeed("sEdTtvLmJmrb7GaivhWoXRkvU4NDjVf", "")
if err != nil {
fmt.Println(err)
return
}
w2, err := wallet.FromSeed("sEdSFiKMQp7RvYLgH7t7FEpwNRWv2Gr", "")
if err != nil {
fmt.Println(err)
return
}
master, err := wallet.FromSeed("sEdTMm2yv8c8Rg8YHFHQA9TxVMFy1ze", "")
if err != nil {
fmt.Println(err)
return
}
fmt.Println("⏳ Funding wallets...")
if err := client.FundWallet(&w1); err != nil {
fmt.Println(err)
return
}
fmt.Println("💸 Wallet 1 funded")
if err := client.FundWallet(&w2); err != nil {
fmt.Println(err)
return
}
fmt.Println("💸 Wallet 2 funded")
if err := client.FundWallet(&master); err != nil {
fmt.Println(err)
return
}
fmt.Println("💸 Master wallet funded")
fmt.Println()
fmt.Println("⏳ Setting up signer list...")
ss := &transaction.SignerListSet{
BaseTx: transaction.BaseTx{
Account: master.GetAddress(),
},
SignerQuorum: uint32(2),
SignerEntries: []ledger.SignerEntryWrapper{
{
SignerEntry: ledger.SignerEntry{
Account: w1.GetAddress(),
SignerWeight: 1,
},
},
{
SignerEntry: ledger.SignerEntry{
Account: w2.GetAddress(),
SignerWeight: 1,
},
},
{
SignerEntry: ledger.SignerEntry{
Account: "XVYRdEocC28DRx94ZFGP3qNJ1D5Ln7ecXFMd3vREB5Pesju",
SignerWeight: 1,
},
},
},
}
flatSs := ss.Flatten()
if err := client.Autofill(&flatSs); err != nil {
fmt.Println(err)
return
}
blob, _, err := master.Sign(flatSs)
if err != nil {
fmt.Println(err)
return
}
res, err := client.SubmitTxBlobAndWait(blob, false)
if err != nil {
fmt.Println(err)
return
}
fmt.Println("✅ SignerListSet transaction submitted!")
fmt.Printf("🌐 Hash: %s\n", res.Hash.String())
fmt.Println()
fmt.Println("⏳ Setting up AccountSet multisign transaction...")
as := &transaction.AccountSet{
BaseTx: transaction.BaseTx{
Account: master.GetAddress(),
},
Domain: types.Domain(strings.ToUpper(hex.EncodeToString([]byte("example.com")))),
}
flatAs := as.Flatten()
if err := client.AutofillMultisigned(&flatAs, 2); err != nil {
fmt.Println(err)
return
}
w1As := maps.Clone(flatAs)
blob1, _, err := w1.Multisign(w1As)
if err != nil {
fmt.Println(err)
return
}
w2As := maps.Clone(flatAs)
blob2, _, err := w2.Multisign(w2As)
if err != nil {
fmt.Println(err)
return
}
blob, err = xrpl.Multisign(blob1, blob2)
if err != nil {
fmt.Println(err)
return
}
mRes, err := client.SubmitMultisigned(blob, false)
if err != nil {
fmt.Println(err)
return
}
fmt.Println("✅ Multisigned transaction submitted!")
fmt.Printf("🌐 Result: %s\n", mRes.EngineResult)
}

View File

@@ -0,0 +1,181 @@
package main
import (
"encoding/hex"
"fmt"
"maps"
"strings"
"github.com/Peersyst/xrpl-go/xrpl"
"github.com/Peersyst/xrpl-go/xrpl/faucet"
"github.com/Peersyst/xrpl-go/xrpl/ledger-entry-types"
"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"
)
func main() {
fmt.Println("⏳ Connecting to testnet...")
client := websocket.NewClient(
websocket.NewClientConfig().
WithHost("wss://s.altnet.rippletest.net:51233").
WithFaucetProvider(faucet.NewTestnetFaucetProvider()),
)
defer client.Disconnect()
if err := client.Connect(); err != nil {
fmt.Println(err)
return
}
if !client.IsConnected() {
fmt.Println("❌ Failed to connect to testnet")
return
}
fmt.Println("✅ Connected to testnet")
fmt.Println()
w1, err := wallet.FromSeed("sEdTtvLmJmrb7GaivhWoXRkvU4NDjVf", "")
if err != nil {
fmt.Println(err)
return
}
w2, err := wallet.FromSeed("sEdSFiKMQp7RvYLgH7t7FEpwNRWv2Gr", "")
if err != nil {
fmt.Println(err)
return
}
master, err := wallet.FromSeed("sEdTMm2yv8c8Rg8YHFHQA9TxVMFy1ze", "")
if err != nil {
fmt.Println(err)
return
}
fmt.Println("⏳ Funding wallets...")
if err := client.FundWallet(&w1); err != nil {
fmt.Println(err)
return
}
fmt.Println("💸 Wallet 1 funded")
if err := client.FundWallet(&w2); err != nil {
fmt.Println(err)
return
}
fmt.Println("💸 Wallet 2 funded")
if err := client.FundWallet(&master); err != nil {
fmt.Println(err)
return
}
fmt.Println("💸 Master wallet funded")
fmt.Println()
fmt.Println("⏳ Setting up signer list...")
ss := &transaction.SignerListSet{
BaseTx: transaction.BaseTx{
Account: master.GetAddress(),
},
SignerQuorum: uint32(2),
SignerEntries: []ledger.SignerEntryWrapper{
{
SignerEntry: ledger.SignerEntry{
Account: w1.GetAddress(),
SignerWeight: 1,
},
},
{
SignerEntry: ledger.SignerEntry{
Account: w2.GetAddress(),
SignerWeight: 1,
},
},
{
SignerEntry: ledger.SignerEntry{
Account: "XVYRdEocC28DRx94ZFGP3qNJ1D5Ln7ecXFMd3vREB5Pesju",
SignerWeight: 1,
},
},
},
}
fmt.Println("⏳ Flattening transaction...")
flatSs := ss.Flatten()
fmt.Println("⏳ Autofilling transaction...")
if err := client.Autofill(&flatSs); err != nil {
fmt.Println(err)
return
}
fmt.Println("⏳ Signing transaction...")
blob, _, err := master.Sign(flatSs)
if err != nil {
fmt.Println(err)
return
}
fmt.Println("⏳ Submitting transaction...")
res, err := client.SubmitTxBlobAndWait(blob, false)
if err != nil {
fmt.Println(err)
return
}
fmt.Println("✅ SignerListSet transaction submitted!")
fmt.Printf("🌐 Hash: %s\n", res.Hash.String())
fmt.Println()
fmt.Println("⏳ Setting up AccountSet multisign transaction...")
as := &transaction.AccountSet{
BaseTx: transaction.BaseTx{
Account: master.GetAddress(),
},
Domain: types.Domain(strings.ToUpper(hex.EncodeToString([]byte("example.com")))),
}
flatAs := as.Flatten()
if err := client.AutofillMultisigned(&flatAs, 2); err != nil {
fmt.Println(err)
return
}
w1As := maps.Clone(flatAs)
blob1, _, err := w1.Multisign(w1As)
if err != nil {
fmt.Println(err)
return
}
w2As := maps.Clone(flatAs)
blob2, _, err := w2.Multisign(w2As)
if err != nil {
fmt.Println(err)
return
}
blob, err = xrpl.Multisign(blob1, blob2)
if err != nil {
fmt.Println(err)
return
}
mRes, err := client.SubmitMultisigned(blob, false)
if err != nil {
fmt.Println(err)
return
}
fmt.Println("✅ Multisigned transaction submitted!")
fmt.Printf("🌐 Result: %s\n", mRes.EngineResult)
}

View File

@@ -0,0 +1,24 @@
module github.com/XRPLF
go 1.23.0
toolchain go1.23.10
require github.com/Peersyst/xrpl-go v0.1.11
require (
github.com/FactomProject/basen v0.0.0-20150613233007-fe3947df716e // indirect
github.com/FactomProject/btcutilecc v0.0.0-20130527213604-d3a63a5752ec // indirect
github.com/btcsuite/btcd/btcec/v2 v2.3.4 // indirect
github.com/decred/dcrd/crypto/ripemd160 v1.0.2 // indirect
github.com/decred/dcrd/dcrec/secp256k1/v4 v4.3.0 // indirect
github.com/gorilla/websocket v1.5.0 // indirect
github.com/json-iterator/go v1.1.12 // indirect
github.com/mitchellh/mapstructure v1.5.0 // indirect
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421 // indirect
github.com/modern-go/reflect2 v1.0.2 // indirect
github.com/tyler-smith/go-bip32 v1.0.0 // indirect
github.com/tyler-smith/go-bip39 v1.1.0 // indirect
github.com/ugorji/go/codec v1.2.11 // indirect
golang.org/x/crypto v0.23.0 // indirect
)

View File

@@ -0,0 +1,58 @@
github.com/FactomProject/basen v0.0.0-20150613233007-fe3947df716e h1:ahyvB3q25YnZWly5Gq1ekg6jcmWaGj/vG/MhF4aisoc=
github.com/FactomProject/basen v0.0.0-20150613233007-fe3947df716e/go.mod h1:kGUqhHd//musdITWjFvNTHn90WG9bMLBEPQZ17Cmlpw=
github.com/FactomProject/btcutilecc v0.0.0-20130527213604-d3a63a5752ec h1:1Qb69mGp/UtRPn422BH4/Y4Q3SLUrD9KHuDkm8iodFc=
github.com/FactomProject/btcutilecc v0.0.0-20130527213604-d3a63a5752ec/go.mod h1:CD8UlnlLDiqb36L110uqiP2iSflVjx9g/3U9hCI4q2U=
github.com/Peersyst/xrpl-go v0.1.11 h1:P6r/gHxRnbAtAdPmzNHz/7zpsdfvwh0SS+QI2JNT44w=
github.com/Peersyst/xrpl-go v0.1.11/go.mod h1:CBRM3/soqNeeL2Jx6USVUtECqulZVUoq3UxZKMz9hdw=
github.com/btcsuite/btcd/btcec/v2 v2.3.4 h1:3EJjcN70HCu/mwqlUsGK8GcNVyLVxFDlWurTXGPFfiQ=
github.com/btcsuite/btcd/btcec/v2 v2.3.4/go.mod h1:zYzJ8etWJQIv1Ogk7OzpWjowwOdXY1W/17j2MW85J04=
github.com/cmars/basen v0.0.0-20150613233007-fe3947df716e h1:0XBUw73chJ1VYSsfvcPvVT7auykAJce9FpRr10L6Qhw=
github.com/cmars/basen v0.0.0-20150613233007-fe3947df716e/go.mod h1:P13beTBKr5Q18lJe1rIoLUqjM+CB1zYrRg44ZqGuQSA=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/decred/dcrd/crypto/blake256 v1.0.1 h1:7PltbUIQB7u/FfZ39+DGa/ShuMyJ5ilcvdfma9wOH6Y=
github.com/decred/dcrd/crypto/blake256 v1.0.1/go.mod h1:2OfgNZ5wDpcsFmHmCK5gZTPcCXqlm2ArzUIkw9czNJo=
github.com/decred/dcrd/crypto/ripemd160 v1.0.2 h1:TvGTmUBHDU75OHro9ojPLK+Yv7gDl2hnUvRocRCjsys=
github.com/decred/dcrd/crypto/ripemd160 v1.0.2/go.mod h1:uGfjDyePSpa75cSQLzNdVmWlbQMBuiJkvXw/MNKRY4M=
github.com/decred/dcrd/dcrec/secp256k1/v4 v4.3.0 h1:rpfIENRNNilwHwZeG5+P150SMrnNEcHYvcCuK6dPZSg=
github.com/decred/dcrd/dcrec/secp256k1/v4 v4.3.0/go.mod h1:v57UDF4pDQJcEfFUCRop3lJL149eHGSe9Jvczhzjo/0=
github.com/golang/mock v1.6.0 h1:ErTB+efbowRARo13NNdxyJji2egdxLGQhRaY+DUumQc=
github.com/golang/mock v1.6.0/go.mod h1:p6yTPP+5HYm5mzsMV8JkE6ZKdX+/wYM6Hr+LicevLPs=
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
github.com/gorilla/websocket v1.5.0 h1:PPwGk2jz7EePpoHN/+ClbZu8SPxiqlu12wZP/3sWmnc=
github.com/gorilla/websocket v1.5.0/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM=
github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo=
github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyuac5Z2hdY=
github.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo=
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421 h1:ZqeYNhU3OHLH3mGKHDcjJRFFRrJa6eAM5H+CtDdOsPc=
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M=
github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/testify v1.1.5-0.20170601210322-f6abca593680/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk=
github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
github.com/tyler-smith/go-bip32 v1.0.0 h1:sDR9juArbUgX+bO/iblgZnMPeWY1KZMUC2AFUJdv5KE=
github.com/tyler-smith/go-bip32 v1.0.0/go.mod h1:onot+eHknzV4BVPwrzqY5OoVpyCvnwD7lMawL5aQupE=
github.com/tyler-smith/go-bip39 v1.1.0 h1:5eUemwrMargf3BSLRRCalXT93Ns6pQJIjYQN2nyfOP8=
github.com/tyler-smith/go-bip39 v1.1.0/go.mod h1:gUYDtqQw1JS3ZJ8UWVcGTGqqr6YIN3CWg+kkNaLt55U=
github.com/ugorji/go/codec v1.2.11 h1:BMaWp1Bb6fHwEtbplGBGJ498wD+LKlNSl25MjdZY4dU=
github.com/ugorji/go/codec v1.2.11/go.mod h1:UNopzCgEMSXjBc6AOMqYvWC1ktqTAfzJZUZgYf6w6lg=
golang.org/x/crypto v0.0.0-20170613210332-850760c427c5/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/crypto v0.23.0 h1:dIJU/v2J8Mdglj/8rJ6UUOM3Zc9zLZxVZwwxMooUSAI=
golang.org/x/crypto v0.23.0/go.mod h1:CKFgDieR+mRhux2Lsu27y0fO304Db0wZe70UKqHu0v8=
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
launchpad.net/gocheck v0.0.0-20140225173054-000000000087 h1:Izowp2XBH6Ya6rv+hqbceQyw/gSGoXfH/UPoTGduL54=
launchpad.net/gocheck v0.0.0-20140225173054-000000000087/go.mod h1:hj7XX3B/0A+80Vse0e+BUHsHMTEhd0O4cpUHr/e/BUM=

View File

@@ -0,0 +1,128 @@
package main
import (
"fmt"
"github.com/Peersyst/xrpl-go/pkg/crypto"
"github.com/Peersyst/xrpl-go/xrpl/faucet"
"github.com/Peersyst/xrpl-go/xrpl/rpc"
"github.com/Peersyst/xrpl-go/xrpl/rpc/types"
"github.com/Peersyst/xrpl-go/xrpl/transaction"
txnTypes "github.com/Peersyst/xrpl-go/xrpl/transaction/types"
"github.com/Peersyst/xrpl-go/xrpl/wallet"
)
func main() {
// Initialize the RPC client configuration
cfg, err := rpc.NewClientConfig(
"https://s.devnet.rippletest.net:51234/",
rpc.WithFaucetProvider(faucet.NewDevnetFaucetProvider()),
)
if err != nil {
panic(err)
}
// Create the RPC client
client := rpc.NewClient(cfg)
// Step 1: Fund wallets
fmt.Println("⏳ Funding wallets...")
// Create and fund the NFT minter wallet
nftMinter, err := wallet.New(crypto.ED25519())
if err != nil {
fmt.Println("❌ Error creating NFT minter wallet:", err)
return
}
if err := client.FundWallet(&nftMinter); err != nil {
fmt.Println("❌ Error funding NFT minter wallet:", err)
return
}
fmt.Println("💸 NFT minter wallet funded!")
// Create and fund the NFT buyer wallet
nftBuyer, err := wallet.New(crypto.ED25519())
if err != nil {
fmt.Println("❌ Error creating NFT buyer wallet:", err)
return
}
if err := client.FundWallet(&nftBuyer); err != nil {
fmt.Println("❌ Error funding NFT buyer wallet:", err)
return
}
fmt.Println("💸 NFT buyer wallet funded!")
fmt.Println()
// Step 2: Mint an NFT
fmt.Println("⏳ Minting NFT...")
nftMint := transaction.NFTokenMint{
BaseTx: transaction.BaseTx{
Account: nftMinter.ClassicAddress,
TransactionType: transaction.NFTokenMintTx,
},
Destination: nftBuyer.ClassicAddress,
Amount: txnTypes.XRPCurrencyAmount(1000000), // 1 XRP
NFTokenTaxon: 0,
URI: txnTypes.NFTokenURI("68747470733A2F2F676F6F676C652E636F6D"), // https://google.com
}
nftMint.SetTransferableFlag()
responseMint, err := client.SubmitTxAndWait(nftMint.Flatten(), &types.SubmitOptions{
Autofill: true,
Wallet: &nftMinter,
})
if err != nil {
fmt.Println("❌ Error minting NFT:", err)
return
}
if !responseMint.Validated {
fmt.Println("❌ NFTokenMint txn is not in a validated ledger", responseMint)
return
}
fmt.Println("✅ NFT minted successfully! - 🌎 Hash: ", responseMint.Hash)
fmt.Println()
// Step 3: Retrieve the NFT token offer ID
fmt.Println("⏳ Retrieving NFT offer ID...")
metaMap, ok := responseMint.Meta.(map[string]any)
if !ok {
fmt.Println("❌ Meta is not a map[string]any")
return
}
offerID, ok := metaMap["offer_id"].(string)
if !ok {
fmt.Println("❌ offer_id not found or not a string")
return
}
fmt.Println("🌎 offer_id:", offerID)
fmt.Println()
// Step 4: Accept the NFT offer
fmt.Println("⏳ Accepting NFT offer...")
nftAccept := transaction.NFTokenAcceptOffer{
BaseTx: transaction.BaseTx{
Account: nftBuyer.ClassicAddress,
TransactionType: transaction.NFTokenAcceptOfferTx,
},
NFTokenSellOffer: txnTypes.Hash256(offerID),
}
response, err := client.SubmitTxAndWait(nftAccept.Flatten(), &types.SubmitOptions{
Autofill: true,
Wallet: &nftBuyer,
})
if err != nil {
fmt.Println("❌ Error accepting NFT offer:", err)
return
}
if !response.Validated {
fmt.Println("❌ NFTokenAcceptOffer txn is not in a validated ledger", response)
return
}
fmt.Println("✅ NFT offer accepted successfully! - 🌎 Hash: ", response.Hash)
}

View File

@@ -0,0 +1,133 @@
package main
import (
"fmt"
"github.com/Peersyst/xrpl-go/pkg/crypto"
"github.com/Peersyst/xrpl-go/xrpl/faucet"
"github.com/Peersyst/xrpl-go/xrpl/transaction"
txnTypes "github.com/Peersyst/xrpl-go/xrpl/transaction/types"
"github.com/Peersyst/xrpl-go/xrpl/wallet"
"github.com/Peersyst/xrpl-go/xrpl/websocket"
"github.com/Peersyst/xrpl-go/xrpl/websocket/types"
)
func main() {
// Connect to the XRPL devnet
fmt.Println("⏳ Connecting to devnet...")
client := websocket.NewClient(
websocket.NewClientConfig().
WithHost("wss://s.devnet.rippletest.net:51233").
WithFaucetProvider(faucet.NewDevnetFaucetProvider()),
)
defer client.Disconnect()
if err := client.Connect(); err != nil {
fmt.Println("❌ Error connecting to devnet:", err)
return
}
if !client.IsConnected() {
fmt.Println("❌ Failed to connect to devnet")
return
}
fmt.Println("✅ Connected to devnet")
fmt.Println()
// Fund wallets
fmt.Println("⏳ Funding wallets...")
// Create and fund the NFT minter wallet
nftMinter, err := wallet.New(crypto.ED25519())
if err != nil {
fmt.Println("❌ Error creating NFT minter wallet:", err)
return
}
if err := client.FundWallet(&nftMinter); err != nil {
fmt.Println("❌ Error funding NFT minter wallet:", err)
return
}
fmt.Println("💸 NFT minter wallet funded!")
// Create and fund the NFT buyer wallet
nftBuyer, err := wallet.New(crypto.ED25519())
if err != nil {
fmt.Println("❌ Error creating NFT buyer wallet:", err)
return
}
if err := client.FundWallet(&nftBuyer); err != nil {
fmt.Println("❌ Error funding NFT buyer wallet:", err)
return
}
fmt.Println("💸 NFT buyer wallet funded!")
fmt.Println()
// Mint an NFT
fmt.Println("⏳ Minting NFT...")
nftMint := transaction.NFTokenMint{
BaseTx: transaction.BaseTx{
Account: nftMinter.ClassicAddress,
TransactionType: transaction.NFTokenMintTx,
},
Destination: nftBuyer.ClassicAddress,
Amount: txnTypes.XRPCurrencyAmount(1000000), // 1 XRP
NFTokenTaxon: 0,
URI: txnTypes.NFTokenURI("68747470733A2F2F676F6F676C652E636F6D"), // https://google.com
}
nftMint.SetTransferableFlag()
responseMint, err := client.SubmitTxAndWait(nftMint.Flatten(), &types.SubmitOptions{
Autofill: true,
Wallet: &nftMinter,
})
if err != nil {
fmt.Println("❌ Error minting NFT:", err)
return
}
if !responseMint.Validated {
fmt.Println("❌ NFTokenMint transaction is not in a validated ledger:", responseMint)
return
}
fmt.Println("✅ NFT minted successfully! - 🌎 Hash:", responseMint.Hash)
fmt.Println()
// Extract the NFT token offer ID from the transaction metadata
fmt.Println("⏳ Extracting offer ID...")
metaMap, ok := responseMint.Meta.(map[string]any)
if !ok {
fmt.Println("❌ Meta is not a map[string]any")
return
}
offerID, ok := metaMap["offer_id"].(string)
if !ok {
fmt.Println("❌ offer_id not found or not a string")
return
}
fmt.Println("🌎 offer_id:", offerID)
fmt.Println()
// Accept the NFT offer
fmt.Println("⏳ Accepting NFT offer...")
nftAccept := transaction.NFTokenAcceptOffer{
BaseTx: transaction.BaseTx{
Account: nftBuyer.ClassicAddress,
TransactionType: transaction.NFTokenAcceptOfferTx,
},
NFTokenSellOffer: txnTypes.Hash256(offerID),
}
response, err := client.SubmitTxAndWait(nftAccept.Flatten(), &types.SubmitOptions{
Autofill: true,
Wallet: &nftBuyer,
})
if err != nil {
fmt.Println("❌ Error accepting NFT offer:", err)
return
}
if !response.Validated {
fmt.Println("❌ NFTokenAcceptOffer transaction is not in a validated ledger:", response)
return
}
fmt.Println("✅ NFT offer accepted successfully! - 🌎 Hash:", response.Hash)
}

View File

@@ -0,0 +1,114 @@
package main
import (
"fmt"
"github.com/Peersyst/xrpl-go/pkg/crypto"
"github.com/Peersyst/xrpl-go/xrpl/faucet"
"github.com/Peersyst/xrpl-go/xrpl/rpc"
"github.com/Peersyst/xrpl-go/xrpl/rpc/types"
"github.com/Peersyst/xrpl-go/xrpl/transaction"
txnTypes "github.com/Peersyst/xrpl-go/xrpl/transaction/types"
"github.com/Peersyst/xrpl-go/xrpl/wallet"
)
func main() {
// Initialize the RPC client configuration
cfg, err := rpc.NewClientConfig(
"https://s.devnet.rippletest.net:51234/",
rpc.WithFaucetProvider(faucet.NewDevnetFaucetProvider()),
)
if err != nil {
panic(err)
}
// Create the RPC client
client := rpc.NewClient(cfg)
// Step 1: Fund wallets
fmt.Println("⏳ Funding wallets...")
// Create and fund the NFT minter wallet
nftMinter, err := wallet.New(crypto.ED25519())
if err != nil {
fmt.Println("❌ Error creating NFT minter wallet:", err)
return
}
if err := client.FundWallet(&nftMinter); err != nil {
fmt.Println("❌ Error funding NFT minter wallet:", err)
return
}
fmt.Println("💸 NFT minter wallet funded!")
fmt.Println()
// Step 2: Mint an NFT
fmt.Println("⏳ Minting NFT...")
nftMint := transaction.NFTokenMint{
BaseTx: transaction.BaseTx{
Account: nftMinter.ClassicAddress,
TransactionType: transaction.NFTokenMintTx,
},
NFTokenTaxon: 0,
URI: txnTypes.NFTokenURI("68747470733A2F2F676F6F676C652E636F6D"), // https://google.com
}
nftMint.SetTransferableFlag()
responseMint, err := client.SubmitTxAndWait(nftMint.Flatten(), &types.SubmitOptions{
Autofill: true,
Wallet: &nftMinter,
})
if err != nil {
fmt.Println("❌ Error minting NFT:", err)
return
}
if !responseMint.Validated {
fmt.Println("❌ NFTokenMint txn is not in a validated ledger", responseMint)
return
}
fmt.Println("✅ NFT minted successfully! - 🌎 Hash: ", responseMint.Hash)
fmt.Println()
// Step 3: Retrieve the token ID
fmt.Println("⏳ Retrieving NFT ID...")
metaMap, ok := responseMint.Meta.(map[string]any)
if !ok {
fmt.Println("❌ Meta is not a map[string]any")
return
}
nftokenID, ok := metaMap["nftoken_id"].(string)
if !ok {
fmt.Println("❌ nftoken_id not found or not a string")
return
}
fmt.Println("🌎 nftoken_id:", nftokenID)
fmt.Println()
// Step 4: Burn the NFT
fmt.Println("⏳ Burn the NFT...")
nftBurn := transaction.NFTokenBurn{
BaseTx: transaction.BaseTx{
Account: nftMinter.ClassicAddress,
TransactionType: transaction.NFTokenAcceptOfferTx,
},
NFTokenID: txnTypes.NFTokenID(nftokenID),
}
responseBurn, err := client.SubmitTxAndWait(nftBurn.Flatten(), &types.SubmitOptions{
Autofill: true,
Wallet: &nftMinter,
})
if err != nil {
fmt.Println("❌ Error burning NFT:", err)
return
}
if !responseBurn.Validated {
fmt.Println("❌ NFTokenBurn transactiob is not in a validated ledger", responseBurn)
return
}
fmt.Println("✅ NFT burned successfully! - 🌎 Hash: ", responseBurn.Hash)
}

View File

@@ -0,0 +1,123 @@
package main
import (
"fmt"
"github.com/Peersyst/xrpl-go/pkg/crypto"
"github.com/Peersyst/xrpl-go/xrpl/faucet"
"github.com/Peersyst/xrpl-go/xrpl/transaction"
txnTypes "github.com/Peersyst/xrpl-go/xrpl/transaction/types"
"github.com/Peersyst/xrpl-go/xrpl/wallet"
"github.com/Peersyst/xrpl-go/xrpl/websocket"
"github.com/Peersyst/xrpl-go/xrpl/websocket/types"
)
func main() {
// Connect to the XRPL devnet
fmt.Println("⏳ Connecting to devnet...")
client := websocket.NewClient(
websocket.NewClientConfig().
WithHost("wss://s.devnet.rippletest.net:51233").
WithFaucetProvider(faucet.NewDevnetFaucetProvider()),
)
defer client.Disconnect()
if err := client.Connect(); err != nil {
fmt.Println("❌ Error connecting to devnet:", err)
return
}
if !client.IsConnected() {
fmt.Println("❌ Failed to connect to devnet")
return
}
fmt.Println("✅ Connected to devnet")
fmt.Println()
// Step 1: Fund wallets
fmt.Println("⏳ Funding wallets...")
// Create and fund the NFT minter wallet
nftMinter, err := wallet.New(crypto.ED25519())
if err != nil {
fmt.Println("❌ Error creating NFT minter wallet:", err)
return
}
if err := client.FundWallet(&nftMinter); err != nil {
fmt.Println("❌ Error funding NFT minter wallet:", err)
return
}
fmt.Println("💸 NFT minter wallet funded!")
fmt.Println()
// Step 2: Mint an NFT
fmt.Println("⏳ Minting NFT...")
nftMint := transaction.NFTokenMint{
BaseTx: transaction.BaseTx{
Account: nftMinter.ClassicAddress,
TransactionType: transaction.NFTokenMintTx,
},
NFTokenTaxon: 0,
URI: txnTypes.NFTokenURI("68747470733A2F2F676F6F676C652E636F6D"), // https://google.com
}
nftMint.SetTransferableFlag()
responseMint, err := client.SubmitTxAndWait(nftMint.Flatten(), &types.SubmitOptions{
Autofill: true,
Wallet: &nftMinter,
})
if err != nil {
fmt.Println("❌ Error minting NFT:", err)
return
}
if !responseMint.Validated {
fmt.Println("❌ NFTokenMint txn is not in a validated ledger", responseMint)
return
}
fmt.Println("✅ NFT minted successfully! - 🌎 Hash: ", responseMint.Hash)
fmt.Println()
// Step 3: Retrieve the token ID
fmt.Println("⏳ Retrieving NFT ID...")
metaMap, ok := responseMint.Meta.(map[string]any)
if !ok {
fmt.Println("❌ Meta is not a map[string]any")
return
}
nftokenID, ok := metaMap["nftoken_id"].(string)
if !ok {
fmt.Println("❌ nftoken_id not found or not a string")
return
}
fmt.Println("🌎 nftoken_id:", nftokenID)
fmt.Println()
// Step 4: Burn the NFT
fmt.Println("⏳ Burn the NFT...")
nftBurn := transaction.NFTokenBurn{
BaseTx: transaction.BaseTx{
Account: nftMinter.ClassicAddress,
TransactionType: transaction.NFTokenAcceptOfferTx,
},
NFTokenID: txnTypes.NFTokenID(nftokenID),
}
responseBurn, err := client.SubmitTxAndWait(nftBurn.Flatten(), &types.SubmitOptions{
Autofill: true,
Wallet: &nftMinter,
})
if err != nil {
fmt.Println("❌ Error burning NFT:", err)
return
}
if !responseBurn.Validated {
fmt.Println("❌ NFTokenBurn transactiob is not in a validated ledger", responseBurn)
return
}
fmt.Println("✅ NFT burned successfully! - 🌎 Hash: ", responseBurn.Hash)
}

View File

@@ -0,0 +1,163 @@
package main
import (
"fmt"
"github.com/Peersyst/xrpl-go/pkg/crypto"
"github.com/Peersyst/xrpl-go/xrpl/faucet"
"github.com/Peersyst/xrpl-go/xrpl/rpc"
"github.com/Peersyst/xrpl-go/xrpl/rpc/types"
"github.com/Peersyst/xrpl-go/xrpl/transaction"
txnTypes "github.com/Peersyst/xrpl-go/xrpl/transaction/types"
"github.com/Peersyst/xrpl-go/xrpl/wallet"
)
func main() {
// Initialize the RPC client configuration
cfg, err := rpc.NewClientConfig(
"https://s.devnet.rippletest.net:51234/",
rpc.WithFaucetProvider(faucet.NewDevnetFaucetProvider()),
)
if err != nil {
panic(err)
}
// Create the RPC client
client := rpc.NewClient(cfg)
// Step 1: Fund wallet
fmt.Println("⏳ Funding wallet...")
// Create and fund the NFT minter wallet
nftMinter, err := wallet.New(crypto.ED25519())
if err != nil {
fmt.Println("❌ Error creating NFT minter wallet:", err)
return
}
if err := client.FundWallet(&nftMinter); err != nil {
fmt.Println("❌ Error funding NFT minter wallet:", err)
return
}
fmt.Println("💸 NFT minter wallet funded!")
// Step 2: Mint two NFTs
fmt.Println("⏳ Minting first NFT...")
nftMint := transaction.NFTokenMint{
BaseTx: transaction.BaseTx{
Account: nftMinter.ClassicAddress,
TransactionType: transaction.NFTokenMintTx,
},
NFTokenTaxon: 0,
URI: txnTypes.NFTokenURI("68747470733A2F2F676F6F676C652E636F6D"), // https://google.com
}
nftMint.SetTransferableFlag()
responseMint, err := client.SubmitTxAndWait(nftMint.Flatten(), &types.SubmitOptions{
Autofill: true,
Wallet: &nftMinter,
})
if err != nil {
fmt.Println("❌ Error minting first NFT:", err)
return
}
if !responseMint.Validated {
fmt.Println("❌ First NFTokenMint transaction is not in a validated ledger", responseMint)
return
}
fmt.Println("✅ First NFT minted successfully! - 🌎 Hash: ", responseMint.Hash)
fmt.Println()
// Step 3: Retrieve the NFT token ID
fmt.Println("⏳ Retrieving NFT ID...")
metaMap, ok := responseMint.Meta.(map[string]any)
if !ok {
fmt.Println("❌ Meta is not a map[string]any")
return
}
nftokenID1, ok := metaMap["nftoken_id"].(string)
if !ok {
fmt.Println("❌ nftoken_id not found or not a string")
return
}
fmt.Println("🌎 nftoken_id:", nftokenID1)
fmt.Println()
// ------
fmt.Println("⏳ Minting second NFT...")
nftMint2 := transaction.NFTokenMint{
BaseTx: transaction.BaseTx{
Account: nftMinter.ClassicAddress,
TransactionType: transaction.NFTokenMintTx,
},
NFTokenTaxon: 0,
URI: txnTypes.NFTokenURI("68747470733A2F2F676F6F676C652E636F6D"), // https://google.com
}
nftMint2.SetTransferableFlag()
responseMint2, err := client.SubmitTxAndWait(nftMint2.Flatten(), &types.SubmitOptions{
Autofill: true,
Wallet: &nftMinter,
})
if err != nil {
fmt.Println("❌ Error minting second NFT:", err)
return
}
if !responseMint.Validated {
fmt.Println("❌ Second NFTokenMint transaction is not in a validated ledger", responseMint)
return
}
fmt.Println("✅ Second NFT minted successfully! - 🌎 Hash: ", responseMint.Hash)
fmt.Println()
// Step 3: Retrieve the second NFT token ID
fmt.Println("⏳ Retrieving second NFT ID...")
metaMap2, ok := responseMint2.Meta.(map[string]any)
if !ok {
fmt.Println("❌ Meta is not a map[string]any")
return
}
nftokenID2, ok := metaMap2["nftoken_id"].(string)
if !ok {
fmt.Println("❌ nftoken_id not found or not a string")
return
}
fmt.Println("🌎 nftoken_id:", nftokenID2)
fmt.Println()
// Step 4: Cancel the NFT offers
fmt.Println("⏳ Canceling NFT offers...")
nftCancel := transaction.NFTokenCancelOffer{
BaseTx: transaction.BaseTx{
Account: nftMinter.ClassicAddress,
TransactionType: transaction.NFTokenAcceptOfferTx,
},
NFTokenOffers: []txnTypes.NFTokenID{
txnTypes.NFTokenID(nftokenID1),
txnTypes.NFTokenID(nftokenID2),
},
}
response, err := client.SubmitTxAndWait(nftCancel.Flatten(), &types.SubmitOptions{
Autofill: true,
Wallet: &nftMinter,
})
if err != nil {
fmt.Println("❌ Error canceling NFT offers:", err)
return
}
if !response.Validated {
fmt.Println("❌ NFTokenCancelOffer transaction is not in a validated ledger", response)
return
}
fmt.Println("✅ NFT offers canceled successfully! - 🌎 Hash: ", response.Hash)
}

View File

@@ -0,0 +1,172 @@
package main
import (
"fmt"
"github.com/Peersyst/xrpl-go/pkg/crypto"
"github.com/Peersyst/xrpl-go/xrpl/faucet"
"github.com/Peersyst/xrpl-go/xrpl/transaction"
txnTypes "github.com/Peersyst/xrpl-go/xrpl/transaction/types"
"github.com/Peersyst/xrpl-go/xrpl/wallet"
"github.com/Peersyst/xrpl-go/xrpl/websocket"
"github.com/Peersyst/xrpl-go/xrpl/websocket/types"
)
func main() {
// Connect to the XRPL devnet
fmt.Println("⏳ Connecting to devnet...")
client := websocket.NewClient(
websocket.NewClientConfig().
WithHost("wss://s.devnet.rippletest.net:51233").
WithFaucetProvider(faucet.NewDevnetFaucetProvider()),
)
defer client.Disconnect()
if err := client.Connect(); err != nil {
fmt.Println("❌ Error connecting to devnet:", err)
return
}
if !client.IsConnected() {
fmt.Println("❌ Failed to connect to devnet")
return
}
fmt.Println("✅ Connected to devnet")
fmt.Println()
// Step 1: Fund wallet
fmt.Println("⏳ Funding wallet...")
// Create and fund the NFT minter wallet
nftMinter, err := wallet.New(crypto.ED25519())
if err != nil {
fmt.Println("❌ Error creating NFT minter wallet:", err)
return
}
if err := client.FundWallet(&nftMinter); err != nil {
fmt.Println("❌ Error funding NFT minter wallet:", err)
return
}
fmt.Println("💸 NFT minter wallet funded!")
// Step 2: Mint two NFTs
fmt.Println("⏳ Minting first NFT...")
nftMint := transaction.NFTokenMint{
BaseTx: transaction.BaseTx{
Account: nftMinter.ClassicAddress,
TransactionType: transaction.NFTokenMintTx,
},
NFTokenTaxon: 0,
URI: txnTypes.NFTokenURI("68747470733A2F2F676F6F676C652E636F6D"), // https://google.com
}
nftMint.SetTransferableFlag()
responseMint, err := client.SubmitTxAndWait(nftMint.Flatten(), &types.SubmitOptions{
Autofill: true,
Wallet: &nftMinter,
})
if err != nil {
fmt.Println("❌ Error minting first NFT:", err)
return
}
if !responseMint.Validated {
fmt.Println("❌ First NFTokenMint transaction is not in a validated ledger", responseMint)
return
}
fmt.Println("✅ First NFT minted successfully! - 🌎 Hash: ", responseMint.Hash)
fmt.Println()
// Step 3: Retrieve the NFT token ID
fmt.Println("⏳ Retrieving NFT ID...")
metaMap, ok := responseMint.Meta.(map[string]any)
if !ok {
fmt.Println("❌ Meta is not a map[string]any")
return
}
nftokenID1, ok := metaMap["nftoken_id"].(string)
if !ok {
fmt.Println("❌ nftoken_id not found or not a string")
return
}
fmt.Println("🌎 nftoken_id:", nftokenID1)
fmt.Println()
// ------
fmt.Println("⏳ Minting second NFT...")
nftMint2 := transaction.NFTokenMint{
BaseTx: transaction.BaseTx{
Account: nftMinter.ClassicAddress,
TransactionType: transaction.NFTokenMintTx,
},
NFTokenTaxon: 0,
URI: txnTypes.NFTokenURI("68747470733A2F2F676F6F676C652E636F6D"), // https://google.com
}
nftMint2.SetTransferableFlag()
responseMint2, err := client.SubmitTxAndWait(nftMint2.Flatten(), &types.SubmitOptions{
Autofill: true,
Wallet: &nftMinter,
})
if err != nil {
fmt.Println("❌ Error minting second NFT:", err)
return
}
if !responseMint.Validated {
fmt.Println("❌ Second NFTokenMint transaction is not in a validated ledger", responseMint)
return
}
fmt.Println("✅ Second NFT minted successfully! - 🌎 Hash: ", responseMint.Hash)
fmt.Println()
// Step 3: Retrieve the second NFT token ID
fmt.Println("⏳ Retrieving second NFT ID...")
metaMap2, ok := responseMint2.Meta.(map[string]any)
if !ok {
fmt.Println("❌ Meta is not a map[string]any")
return
}
nftokenID2, ok := metaMap2["nftoken_id"].(string)
if !ok {
fmt.Println("❌ nftoken_id not found or not a string")
return
}
fmt.Println("🌎 nftoken_id:", nftokenID2)
fmt.Println()
// Step 4: Cancel the NFT offers
fmt.Println("⏳ Canceling NFT offers...")
nftCancel := transaction.NFTokenCancelOffer{
BaseTx: transaction.BaseTx{
Account: nftMinter.ClassicAddress,
TransactionType: transaction.NFTokenAcceptOfferTx,
},
NFTokenOffers: []txnTypes.NFTokenID{
txnTypes.NFTokenID(nftokenID1),
txnTypes.NFTokenID(nftokenID2),
},
}
response, err := client.SubmitTxAndWait(nftCancel.Flatten(), &types.SubmitOptions{
Autofill: true,
Wallet: &nftMinter,
})
if err != nil {
fmt.Println("❌ Error canceling NFT offers:", err)
return
}
if !response.Validated {
fmt.Println("❌ NFTokenCancelOffer transaction is not in a validated ledger", response)
return
}
fmt.Println("✅ NFT offers canceled successfully! - 🌎 Hash: ", response.Hash)
}

View File

@@ -0,0 +1,107 @@
package main
import (
"fmt"
"github.com/Peersyst/xrpl-go/pkg/crypto"
"github.com/Peersyst/xrpl-go/xrpl/faucet"
"github.com/Peersyst/xrpl-go/xrpl/rpc"
"github.com/Peersyst/xrpl-go/xrpl/rpc/types"
"github.com/Peersyst/xrpl-go/xrpl/transaction"
txnTypes "github.com/Peersyst/xrpl-go/xrpl/transaction/types"
"github.com/Peersyst/xrpl-go/xrpl/wallet"
)
func main() {
cfg, err := rpc.NewClientConfig(
"https://s.devnet.rippletest.net:51234/",
rpc.WithFaucetProvider(faucet.NewDevnetFaucetProvider()),
)
if err != nil {
panic(err)
}
client := rpc.NewClient(cfg)
fmt.Println()
fmt.Println("⏳ Funding wallet...")
// Create and fund the nft wallet
nftWallet, err := wallet.New(crypto.ED25519())
if err != nil {
fmt.Println("❌ Error creating nft wallet:", err)
return
}
if err := client.FundWallet(&nftWallet); err != nil {
fmt.Println("❌ Error funding nft wallet:", err)
return
}
fmt.Println("💸 NFT wallet funded! - #️⃣: ", nftWallet.ClassicAddress)
fmt.Println()
// Mint NFT
nftMint := transaction.NFTokenMint{
BaseTx: transaction.BaseTx{
Account: nftWallet.ClassicAddress,
TransactionType: transaction.NFTokenMintTx,
},
NFTokenTaxon: 0,
URI: txnTypes.NFTokenURI("68747470733A2F2F676F6F676C652E636F6D"), // https://google.com
}
nftMint.SetMutableFlag()
nftMint.SetTransferableFlag()
responseMint, err := client.SubmitTxAndWait(nftMint.Flatten(), &types.SubmitOptions{
Autofill: true,
Wallet: &nftWallet,
})
if err != nil {
fmt.Println("❌ Error minting NFT:", err)
return
}
if !responseMint.Validated {
fmt.Println("❌ NFTokenMint txn is not in a validated ledger", responseMint)
return
}
fmt.Println("✅ NFT minted successfully! - 🌎 Hash: ", responseMint.Hash)
fmt.Println()
metaMap, ok := responseMint.Meta.(map[string]any)
if !ok {
fmt.Println("❌ Meta is not a map[string]any")
return
}
nftokenID, ok := metaMap["nftoken_id"].(string)
if !ok {
fmt.Println("❌ nftoken_id not found or not a string")
return
}
fmt.Println("🌎 nftoken_id:", nftokenID)
fmt.Println()
// Update NFT
nftModify := transaction.NFTokenModify{
BaseTx: transaction.BaseTx{
Account: nftWallet.ClassicAddress,
TransactionType: transaction.NFTokenModifyTx,
},
URI: "68747470733A2F2F7961686F6F2E636F6D", // https://yahoo.com
NFTokenID: txnTypes.NFTokenID(nftokenID),
}
// nftoken_id
responseModify, err := client.SubmitTxAndWait(nftModify.Flatten(), &types.SubmitOptions{
Autofill: true,
Wallet: &nftWallet,
})
if err != nil {
fmt.Println("❌ Error modifying NFT:", err)
return
}
if !responseModify.Validated {
fmt.Println("❌ NFTokenModify txn is not in a validated ledger", responseModify)
return
}
fmt.Println("✅ NFT URI modified successfully! - 🌎 Hash: ", responseModify.Hash)
}

View File

@@ -0,0 +1,117 @@
package main
import (
"fmt"
"github.com/Peersyst/xrpl-go/pkg/crypto"
"github.com/Peersyst/xrpl-go/xrpl/faucet"
"github.com/Peersyst/xrpl-go/xrpl/transaction"
txnTypes "github.com/Peersyst/xrpl-go/xrpl/transaction/types"
"github.com/Peersyst/xrpl-go/xrpl/wallet"
"github.com/Peersyst/xrpl-go/xrpl/websocket"
"github.com/Peersyst/xrpl-go/xrpl/websocket/types"
)
func main() {
fmt.Println("⏳ Connecting to devnet...")
client := websocket.NewClient(
websocket.NewClientConfig().
WithHost("wss://s.devnet.rippletest.net:51233").
WithFaucetProvider(faucet.NewDevnetFaucetProvider()),
)
defer client.Disconnect()
if err := client.Connect(); err != nil {
fmt.Println(err)
return
}
if !client.IsConnected() {
fmt.Println("❌ Failed to connect to devnet")
return
}
fmt.Println("✅ Connected to devnet")
fmt.Println()
// Create and fund the nft wallet
fmt.Println("⏳ Funding wallet...")
nftWallet, err := wallet.New(crypto.ED25519())
if err != nil {
fmt.Println("❌ Error creating nft wallet:", err)
return
}
if err := client.FundWallet(&nftWallet); err != nil {
fmt.Println("❌ Error funding nft wallet:", err)
return
}
fmt.Println("💸 NFT wallet funded!")
fmt.Println()
// Mint NFT
nftMint := transaction.NFTokenMint{
BaseTx: transaction.BaseTx{
Account: nftWallet.ClassicAddress,
TransactionType: transaction.NFTokenMintTx,
},
NFTokenTaxon: 0,
URI: txnTypes.NFTokenURI("68747470733A2F2F676F6F676C652E636F6D"), // https://google.com
}
nftMint.SetMutableFlag()
nftMint.SetTransferableFlag()
responseMint, err := client.SubmitTxAndWait(nftMint.Flatten(), &types.SubmitOptions{
Autofill: true,
Wallet: &nftWallet,
})
if err != nil {
fmt.Println("❌ Error minting NFT:", err)
return
}
if !responseMint.Validated {
fmt.Println("❌ NFTokenMint txn is not in a validated ledger", responseMint)
return
}
fmt.Println("✅ NFT minted successfully! - 🌎 Hash: ", responseMint.Hash)
fmt.Println()
metaMap, ok := responseMint.Meta.(map[string]any)
if !ok {
fmt.Println("❌ Meta is not a map[string]any")
return
}
nftokenID, ok := metaMap["nftoken_id"].(string)
if !ok {
fmt.Println("❌ nftoken_id not found or not a string")
return
}
fmt.Println("🌎 nftoken_id:", nftokenID)
fmt.Println()
// Update NFT
nftModify := transaction.NFTokenModify{
BaseTx: transaction.BaseTx{
Account: nftWallet.ClassicAddress,
TransactionType: transaction.NFTokenModifyTx,
},
URI: "68747470733A2F2F7961686F6F2E636F6D", // https://yahoo.com
NFTokenID: txnTypes.NFTokenID(nftokenID),
}
responseModify, err := client.SubmitTxAndWait(nftModify.Flatten(), &types.SubmitOptions{
Autofill: true,
Wallet: &nftWallet,
})
if err != nil {
fmt.Println("❌ Error modifying NFT:", err)
return
}
if !responseModify.Validated {
fmt.Println("❌ NFTokenModify txn is not in a validated ledger", responseModify)
return
}
fmt.Println("✅ NFT URI modified successfully! - 🌎 Hash: ", responseModify.Hash)
}

View File

@@ -0,0 +1,24 @@
module github.com/XRPLF
go 1.23.0
toolchain go1.23.10
require github.com/Peersyst/xrpl-go v0.1.11
require (
github.com/FactomProject/basen v0.0.0-20150613233007-fe3947df716e // indirect
github.com/FactomProject/btcutilecc v0.0.0-20130527213604-d3a63a5752ec // indirect
github.com/btcsuite/btcd/btcec/v2 v2.3.4 // indirect
github.com/decred/dcrd/crypto/ripemd160 v1.0.2 // indirect
github.com/decred/dcrd/dcrec/secp256k1/v4 v4.3.0 // indirect
github.com/gorilla/websocket v1.5.0 // indirect
github.com/json-iterator/go v1.1.12 // indirect
github.com/mitchellh/mapstructure v1.5.0 // indirect
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421 // indirect
github.com/modern-go/reflect2 v1.0.2 // indirect
github.com/tyler-smith/go-bip32 v1.0.0 // indirect
github.com/tyler-smith/go-bip39 v1.1.0 // indirect
github.com/ugorji/go/codec v1.2.11 // indirect
golang.org/x/crypto v0.23.0 // indirect
)

View File

@@ -0,0 +1,58 @@
github.com/FactomProject/basen v0.0.0-20150613233007-fe3947df716e h1:ahyvB3q25YnZWly5Gq1ekg6jcmWaGj/vG/MhF4aisoc=
github.com/FactomProject/basen v0.0.0-20150613233007-fe3947df716e/go.mod h1:kGUqhHd//musdITWjFvNTHn90WG9bMLBEPQZ17Cmlpw=
github.com/FactomProject/btcutilecc v0.0.0-20130527213604-d3a63a5752ec h1:1Qb69mGp/UtRPn422BH4/Y4Q3SLUrD9KHuDkm8iodFc=
github.com/FactomProject/btcutilecc v0.0.0-20130527213604-d3a63a5752ec/go.mod h1:CD8UlnlLDiqb36L110uqiP2iSflVjx9g/3U9hCI4q2U=
github.com/Peersyst/xrpl-go v0.1.11 h1:P6r/gHxRnbAtAdPmzNHz/7zpsdfvwh0SS+QI2JNT44w=
github.com/Peersyst/xrpl-go v0.1.11/go.mod h1:CBRM3/soqNeeL2Jx6USVUtECqulZVUoq3UxZKMz9hdw=
github.com/btcsuite/btcd/btcec/v2 v2.3.4 h1:3EJjcN70HCu/mwqlUsGK8GcNVyLVxFDlWurTXGPFfiQ=
github.com/btcsuite/btcd/btcec/v2 v2.3.4/go.mod h1:zYzJ8etWJQIv1Ogk7OzpWjowwOdXY1W/17j2MW85J04=
github.com/cmars/basen v0.0.0-20150613233007-fe3947df716e h1:0XBUw73chJ1VYSsfvcPvVT7auykAJce9FpRr10L6Qhw=
github.com/cmars/basen v0.0.0-20150613233007-fe3947df716e/go.mod h1:P13beTBKr5Q18lJe1rIoLUqjM+CB1zYrRg44ZqGuQSA=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/decred/dcrd/crypto/blake256 v1.0.1 h1:7PltbUIQB7u/FfZ39+DGa/ShuMyJ5ilcvdfma9wOH6Y=
github.com/decred/dcrd/crypto/blake256 v1.0.1/go.mod h1:2OfgNZ5wDpcsFmHmCK5gZTPcCXqlm2ArzUIkw9czNJo=
github.com/decred/dcrd/crypto/ripemd160 v1.0.2 h1:TvGTmUBHDU75OHro9ojPLK+Yv7gDl2hnUvRocRCjsys=
github.com/decred/dcrd/crypto/ripemd160 v1.0.2/go.mod h1:uGfjDyePSpa75cSQLzNdVmWlbQMBuiJkvXw/MNKRY4M=
github.com/decred/dcrd/dcrec/secp256k1/v4 v4.3.0 h1:rpfIENRNNilwHwZeG5+P150SMrnNEcHYvcCuK6dPZSg=
github.com/decred/dcrd/dcrec/secp256k1/v4 v4.3.0/go.mod h1:v57UDF4pDQJcEfFUCRop3lJL149eHGSe9Jvczhzjo/0=
github.com/golang/mock v1.6.0 h1:ErTB+efbowRARo13NNdxyJji2egdxLGQhRaY+DUumQc=
github.com/golang/mock v1.6.0/go.mod h1:p6yTPP+5HYm5mzsMV8JkE6ZKdX+/wYM6Hr+LicevLPs=
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
github.com/gorilla/websocket v1.5.0 h1:PPwGk2jz7EePpoHN/+ClbZu8SPxiqlu12wZP/3sWmnc=
github.com/gorilla/websocket v1.5.0/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM=
github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo=
github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyuac5Z2hdY=
github.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo=
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421 h1:ZqeYNhU3OHLH3mGKHDcjJRFFRrJa6eAM5H+CtDdOsPc=
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M=
github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/testify v1.1.5-0.20170601210322-f6abca593680/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk=
github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
github.com/tyler-smith/go-bip32 v1.0.0 h1:sDR9juArbUgX+bO/iblgZnMPeWY1KZMUC2AFUJdv5KE=
github.com/tyler-smith/go-bip32 v1.0.0/go.mod h1:onot+eHknzV4BVPwrzqY5OoVpyCvnwD7lMawL5aQupE=
github.com/tyler-smith/go-bip39 v1.1.0 h1:5eUemwrMargf3BSLRRCalXT93Ns6pQJIjYQN2nyfOP8=
github.com/tyler-smith/go-bip39 v1.1.0/go.mod h1:gUYDtqQw1JS3ZJ8UWVcGTGqqr6YIN3CWg+kkNaLt55U=
github.com/ugorji/go/codec v1.2.11 h1:BMaWp1Bb6fHwEtbplGBGJ498wD+LKlNSl25MjdZY4dU=
github.com/ugorji/go/codec v1.2.11/go.mod h1:UNopzCgEMSXjBc6AOMqYvWC1ktqTAfzJZUZgYf6w6lg=
golang.org/x/crypto v0.0.0-20170613210332-850760c427c5/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/crypto v0.23.0 h1:dIJU/v2J8Mdglj/8rJ6UUOM3Zc9zLZxVZwwxMooUSAI=
golang.org/x/crypto v0.23.0/go.mod h1:CKFgDieR+mRhux2Lsu27y0fO304Db0wZe70UKqHu0v8=
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
launchpad.net/gocheck v0.0.0-20140225173054-000000000087 h1:Izowp2XBH6Ya6rv+hqbceQyw/gSGoXfH/UPoTGduL54=
launchpad.net/gocheck v0.0.0-20140225173054-000000000087/go.mod h1:hj7XX3B/0A+80Vse0e+BUHsHMTEhd0O4cpUHr/e/BUM=

View File

@@ -0,0 +1,168 @@
package main
import (
"fmt"
"time"
"github.com/Peersyst/xrpl-go/pkg/crypto"
"github.com/Peersyst/xrpl-go/xrpl/faucet"
"github.com/Peersyst/xrpl-go/xrpl/rpc"
"github.com/Peersyst/xrpl-go/xrpl/transaction"
"github.com/Peersyst/xrpl-go/xrpl/transaction/types"
"github.com/Peersyst/xrpl-go/xrpl/wallet"
)
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)
fmt.Println("⏳ Funding wallets...")
w1, err := wallet.New(crypto.ED25519())
if err != nil {
fmt.Println(err)
return
}
w2, err := wallet.New(crypto.ED25519())
if err != nil {
fmt.Println(err)
return
}
if err := client.FundWallet(&w1); err != nil {
fmt.Println(err)
return
}
fmt.Println("💸 Wallet 1 funded")
if err := client.FundWallet(&w2); err != nil {
fmt.Println(err)
return
}
fmt.Println("💸 Wallet 2 funded")
fmt.Println()
time.Sleep(5 * time.Second)
fmt.Println("⏳ Sending TrustSet transaction...")
ts := &transaction.TrustSet{
BaseTx: transaction.BaseTx{
Account: w2.ClassicAddress,
},
LimitAmount: types.IssuedCurrencyAmount{
Currency: "FOO",
Issuer: w1.ClassicAddress,
Value: "10000000000",
},
}
flatTs := ts.Flatten()
err = client.Autofill(&flatTs)
if err != nil {
fmt.Println(err)
return
}
blob, _, err := w2.Sign(flatTs)
if err != nil {
fmt.Println(err)
return
}
res, err := client.SubmitTxBlobAndWait(blob, false)
if err != nil {
fmt.Println(err)
return
}
fmt.Println("✅ TrustSet transaction submitted!")
fmt.Printf("🌐 Hash: %s\n", res.Hash.String())
fmt.Printf("🌐 Validated: %t\n", res.Validated)
fmt.Println()
fmt.Println("⏳ Issuing tokens for wallet 2...")
p := &transaction.Payment{
BaseTx: transaction.BaseTx{
Account: w1.GetAddress(),
},
Amount: types.IssuedCurrencyAmount{
Currency: "FOO",
Issuer: w1.GetAddress(),
Value: "50",
},
Destination: w2.GetAddress(),
}
flatP := p.Flatten()
err = client.Autofill(&flatP)
if err != nil {
fmt.Println(err)
return
}
blob, _, err = w1.Sign(flatP)
if err != nil {
fmt.Println(err)
return
}
res, err = client.SubmitTxBlobAndWait(blob, false)
if err != nil {
fmt.Println(err)
return
}
fmt.Println("✅ Payment transaction submitted!")
fmt.Printf("🌐 Hash: %s\n", res.Hash.String())
fmt.Printf("🌐 Validated: %t\n", res.Validated)
fmt.Println()
fmt.Println("⏳ Submitting Partial Payment transaction...")
pp := &transaction.Payment{
BaseTx: transaction.BaseTx{
Account: w2.GetAddress(),
},
Amount: types.IssuedCurrencyAmount{
Currency: "FOO",
Issuer: w1.GetAddress(),
Value: "10",
},
Destination: w1.GetAddress(),
}
pp.SetPartialPaymentFlag()
flatPP := pp.Flatten()
err = client.Autofill(&flatPP)
if err != nil {
fmt.Println(err)
return
}
blob, _, err = w2.Sign(flatPP)
if err != nil {
fmt.Println(err)
return
}
res, err = client.SubmitTxBlobAndWait(blob, false)
if err != nil {
fmt.Println(err)
return
}
fmt.Println("✅ Partial Payment transaction submitted!")
fmt.Printf("🌐 Hash: %s\n", res.Hash.String())
fmt.Printf("🌐 Validated: %t\n", res.Validated)
fmt.Println()
}

View File

@@ -0,0 +1,179 @@
package main
import (
"fmt"
"time"
"github.com/Peersyst/xrpl-go/pkg/crypto"
"github.com/Peersyst/xrpl-go/xrpl/faucet"
"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"
)
func main() {
fmt.Println("⏳ Connecting to testnet...")
client := websocket.NewClient(
websocket.NewClientConfig().
WithHost("wss://s.altnet.rippletest.net:51233").
WithFaucetProvider(faucet.NewTestnetFaucetProvider()),
)
defer client.Disconnect()
if err := client.Connect(); err != nil {
fmt.Println(err)
return
}
if !client.IsConnected() {
fmt.Println("❌ Failed to connect to testnet")
return
}
fmt.Println("✅ Connected to testnet")
fmt.Println()
fmt.Println("⏳ Funding wallets...")
w1, err := wallet.New(crypto.ED25519())
if err != nil {
fmt.Println(err)
return
}
w2, err := wallet.New(crypto.ED25519())
if err != nil {
fmt.Println(err)
return
}
if err := client.FundWallet(&w1); err != nil {
fmt.Println(err)
return
}
fmt.Println("💸 Wallet 1 funded")
if err := client.FundWallet(&w2); err != nil {
fmt.Println(err)
return
}
fmt.Println("💸 Wallet 2 funded")
fmt.Println()
time.Sleep(5 * time.Second)
fmt.Println("⏳ Sending TrustSet transaction...")
ts := &transaction.TrustSet{
BaseTx: transaction.BaseTx{
Account: w2.ClassicAddress,
},
LimitAmount: types.IssuedCurrencyAmount{
Currency: "FOO",
Issuer: w1.ClassicAddress,
Value: "10000000000",
},
}
flatTs := ts.Flatten()
err = client.Autofill(&flatTs)
if err != nil {
fmt.Println(err)
return
}
blob, _, err := w2.Sign(flatTs)
if err != nil {
fmt.Println(err)
return
}
res, err := client.SubmitTxBlobAndWait(blob, false)
if err != nil {
fmt.Println(err)
return
}
fmt.Println("✅ TrustSet transaction submitted!")
fmt.Printf("🌐 Hash: %s\n", res.Hash.String())
fmt.Printf("🌐 Validated: %t\n", res.Validated)
fmt.Println()
fmt.Println("⏳ Issuing tokens for wallet 2...")
p := &transaction.Payment{
BaseTx: transaction.BaseTx{
Account: w1.GetAddress(),
},
Amount: types.IssuedCurrencyAmount{
Currency: "FOO",
Issuer: w1.GetAddress(),
Value: "50",
},
Destination: w2.GetAddress(),
}
flatP := p.Flatten()
err = client.Autofill(&flatP)
if err != nil {
fmt.Println(err)
return
}
blob, _, err = w1.Sign(flatP)
if err != nil {
fmt.Println(err)
return
}
res, err = client.SubmitTxBlobAndWait(blob, false)
if err != nil {
fmt.Println(err)
return
}
fmt.Println("✅ Payment transaction submitted!")
fmt.Printf("🌐 Hash: %s\n", res.Hash.String())
fmt.Printf("🌐 Validated: %t\n", res.Validated)
fmt.Println()
fmt.Println("⏳ Submitting Partial Payment transaction...")
pp := &transaction.Payment{
BaseTx: transaction.BaseTx{
Account: w2.GetAddress(),
},
Amount: types.IssuedCurrencyAmount{
Currency: "FOO",
Issuer: w1.GetAddress(),
Value: "10",
},
Destination: w1.GetAddress(),
}
pp.SetPartialPaymentFlag()
flatPP := pp.Flatten()
err = client.Autofill(&flatPP)
if err != nil {
fmt.Println(err)
return
}
blob, _, err = w2.Sign(flatPP)
if err != nil {
fmt.Println(err)
return
}
res, err = client.SubmitTxBlobAndWait(blob, false)
if err != nil {
fmt.Println(err)
return
}
fmt.Println("✅ Partial Payment transaction submitted!")
fmt.Printf("🌐 Hash: %s\n", res.Hash.String())
fmt.Printf("🌐 Validated: %t\n", res.Validated)
fmt.Println()
}

View File

@@ -0,0 +1,24 @@
module github.com/XRPLF
go 1.23.0
toolchain go1.23.10
require github.com/Peersyst/xrpl-go v0.1.11
require (
github.com/FactomProject/basen v0.0.0-20150613233007-fe3947df716e // indirect
github.com/FactomProject/btcutilecc v0.0.0-20130527213604-d3a63a5752ec // indirect
github.com/btcsuite/btcd/btcec/v2 v2.3.4 // indirect
github.com/decred/dcrd/crypto/ripemd160 v1.0.2 // indirect
github.com/decred/dcrd/dcrec/secp256k1/v4 v4.3.0 // indirect
github.com/gorilla/websocket v1.5.0 // indirect
github.com/json-iterator/go v1.1.12 // indirect
github.com/mitchellh/mapstructure v1.5.0 // indirect
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421 // indirect
github.com/modern-go/reflect2 v1.0.2 // indirect
github.com/tyler-smith/go-bip32 v1.0.0 // indirect
github.com/tyler-smith/go-bip39 v1.1.0 // indirect
github.com/ugorji/go/codec v1.2.11 // indirect
golang.org/x/crypto v0.23.0 // indirect
)

View File

@@ -0,0 +1,58 @@
github.com/FactomProject/basen v0.0.0-20150613233007-fe3947df716e h1:ahyvB3q25YnZWly5Gq1ekg6jcmWaGj/vG/MhF4aisoc=
github.com/FactomProject/basen v0.0.0-20150613233007-fe3947df716e/go.mod h1:kGUqhHd//musdITWjFvNTHn90WG9bMLBEPQZ17Cmlpw=
github.com/FactomProject/btcutilecc v0.0.0-20130527213604-d3a63a5752ec h1:1Qb69mGp/UtRPn422BH4/Y4Q3SLUrD9KHuDkm8iodFc=
github.com/FactomProject/btcutilecc v0.0.0-20130527213604-d3a63a5752ec/go.mod h1:CD8UlnlLDiqb36L110uqiP2iSflVjx9g/3U9hCI4q2U=
github.com/Peersyst/xrpl-go v0.1.11 h1:P6r/gHxRnbAtAdPmzNHz/7zpsdfvwh0SS+QI2JNT44w=
github.com/Peersyst/xrpl-go v0.1.11/go.mod h1:CBRM3/soqNeeL2Jx6USVUtECqulZVUoq3UxZKMz9hdw=
github.com/btcsuite/btcd/btcec/v2 v2.3.4 h1:3EJjcN70HCu/mwqlUsGK8GcNVyLVxFDlWurTXGPFfiQ=
github.com/btcsuite/btcd/btcec/v2 v2.3.4/go.mod h1:zYzJ8etWJQIv1Ogk7OzpWjowwOdXY1W/17j2MW85J04=
github.com/cmars/basen v0.0.0-20150613233007-fe3947df716e h1:0XBUw73chJ1VYSsfvcPvVT7auykAJce9FpRr10L6Qhw=
github.com/cmars/basen v0.0.0-20150613233007-fe3947df716e/go.mod h1:P13beTBKr5Q18lJe1rIoLUqjM+CB1zYrRg44ZqGuQSA=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/decred/dcrd/crypto/blake256 v1.0.1 h1:7PltbUIQB7u/FfZ39+DGa/ShuMyJ5ilcvdfma9wOH6Y=
github.com/decred/dcrd/crypto/blake256 v1.0.1/go.mod h1:2OfgNZ5wDpcsFmHmCK5gZTPcCXqlm2ArzUIkw9czNJo=
github.com/decred/dcrd/crypto/ripemd160 v1.0.2 h1:TvGTmUBHDU75OHro9ojPLK+Yv7gDl2hnUvRocRCjsys=
github.com/decred/dcrd/crypto/ripemd160 v1.0.2/go.mod h1:uGfjDyePSpa75cSQLzNdVmWlbQMBuiJkvXw/MNKRY4M=
github.com/decred/dcrd/dcrec/secp256k1/v4 v4.3.0 h1:rpfIENRNNilwHwZeG5+P150SMrnNEcHYvcCuK6dPZSg=
github.com/decred/dcrd/dcrec/secp256k1/v4 v4.3.0/go.mod h1:v57UDF4pDQJcEfFUCRop3lJL149eHGSe9Jvczhzjo/0=
github.com/golang/mock v1.6.0 h1:ErTB+efbowRARo13NNdxyJji2egdxLGQhRaY+DUumQc=
github.com/golang/mock v1.6.0/go.mod h1:p6yTPP+5HYm5mzsMV8JkE6ZKdX+/wYM6Hr+LicevLPs=
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
github.com/gorilla/websocket v1.5.0 h1:PPwGk2jz7EePpoHN/+ClbZu8SPxiqlu12wZP/3sWmnc=
github.com/gorilla/websocket v1.5.0/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM=
github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo=
github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyuac5Z2hdY=
github.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo=
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421 h1:ZqeYNhU3OHLH3mGKHDcjJRFFRrJa6eAM5H+CtDdOsPc=
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M=
github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/testify v1.1.5-0.20170601210322-f6abca593680/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk=
github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
github.com/tyler-smith/go-bip32 v1.0.0 h1:sDR9juArbUgX+bO/iblgZnMPeWY1KZMUC2AFUJdv5KE=
github.com/tyler-smith/go-bip32 v1.0.0/go.mod h1:onot+eHknzV4BVPwrzqY5OoVpyCvnwD7lMawL5aQupE=
github.com/tyler-smith/go-bip39 v1.1.0 h1:5eUemwrMargf3BSLRRCalXT93Ns6pQJIjYQN2nyfOP8=
github.com/tyler-smith/go-bip39 v1.1.0/go.mod h1:gUYDtqQw1JS3ZJ8UWVcGTGqqr6YIN3CWg+kkNaLt55U=
github.com/ugorji/go/codec v1.2.11 h1:BMaWp1Bb6fHwEtbplGBGJ498wD+LKlNSl25MjdZY4dU=
github.com/ugorji/go/codec v1.2.11/go.mod h1:UNopzCgEMSXjBc6AOMqYvWC1ktqTAfzJZUZgYf6w6lg=
golang.org/x/crypto v0.0.0-20170613210332-850760c427c5/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/crypto v0.23.0 h1:dIJU/v2J8Mdglj/8rJ6UUOM3Zc9zLZxVZwwxMooUSAI=
golang.org/x/crypto v0.23.0/go.mod h1:CKFgDieR+mRhux2Lsu27y0fO304Db0wZe70UKqHu0v8=
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
launchpad.net/gocheck v0.0.0-20140225173054-000000000087 h1:Izowp2XBH6Ya6rv+hqbceQyw/gSGoXfH/UPoTGduL54=
launchpad.net/gocheck v0.0.0-20140225173054-000000000087/go.mod h1:hj7XX3B/0A+80Vse0e+BUHsHMTEhd0O4cpUHr/e/BUM=

View File

@@ -0,0 +1,111 @@
package main
import (
"fmt"
"github.com/Peersyst/xrpl-go/pkg/crypto"
"github.com/Peersyst/xrpl-go/xrpl/faucet"
"github.com/Peersyst/xrpl-go/xrpl/queries/path"
"github.com/Peersyst/xrpl-go/xrpl/rpc"
"github.com/Peersyst/xrpl-go/xrpl/transaction"
"github.com/Peersyst/xrpl-go/xrpl/transaction/types"
"github.com/Peersyst/xrpl-go/xrpl/wallet"
pathtypes "github.com/Peersyst/xrpl-go/xrpl/queries/path/types"
)
const (
DestinationAccount = types.Address("rKT4JX4cCof6LcDYRz8o3rGRu7qxzZ2Zwj")
)
var (
DestinationAmount = types.IssuedCurrencyAmount{
Issuer: "rVnYNK9yuxBz4uP8zC8LEFokM2nqH3poc",
Currency: "USD",
Value: "0.001",
}
)
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)
wallet, err := wallet.New(crypto.ED25519())
if err != nil {
fmt.Println(err)
return
}
fmt.Println("⏳ Funding wallet...")
if err := client.FundWallet(&wallet); err != nil {
fmt.Println(err)
return
}
fmt.Println("💸 Wallet funded")
fmt.Println()
fmt.Println("⏳ Getting paths...")
res, err := client.GetRipplePathFind(&path.RipplePathFindRequest{
SourceAccount: wallet.GetAddress(),
SourceCurrencies: []pathtypes.RipplePathFindCurrency{
{
Currency: "XRP",
},
},
DestinationAccount: DestinationAccount,
DestinationAmount: DestinationAmount,
})
if err != nil {
fmt.Println(err)
return
}
fmt.Printf("🌐 Computed paths: %d\n", len(res.Alternatives))
fmt.Println()
if len(res.Alternatives) == 0 {
fmt.Println("❌ No alternatives found")
return
}
fmt.Println("⏳ Submitting Payment through path: ", res.Alternatives[0].PathsComputed)
p := &transaction.Payment{
BaseTx: transaction.BaseTx{
Account: wallet.GetAddress(),
},
Destination: DestinationAccount,
Amount: DestinationAmount,
Paths: res.Alternatives[0].PathsComputed,
}
flatP := p.Flatten()
if err := client.Autofill(&flatP); err != nil {
fmt.Println(err)
return
}
blob, hash, err := wallet.Sign(flatP)
if err != nil {
fmt.Println(err)
return
}
txRes, err := client.SubmitTxBlobAndWait(blob, false)
if err != nil {
fmt.Println(err)
return
}
fmt.Println("✅ Payment submitted")
fmt.Printf("🌐 Hash: %s\n", hash)
fmt.Printf("🌐 Validated: %t\n", txRes.Validated)
}

View File

@@ -0,0 +1,122 @@
package main
import (
"fmt"
"github.com/Peersyst/xrpl-go/pkg/crypto"
"github.com/Peersyst/xrpl-go/xrpl/faucet"
"github.com/Peersyst/xrpl-go/xrpl/queries/path"
"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"
pathtypes "github.com/Peersyst/xrpl-go/xrpl/queries/path/types"
)
const (
DestinationAccount = types.Address("rKT4JX4cCof6LcDYRz8o3rGRu7qxzZ2Zwj")
)
var (
DestinationAmount = types.IssuedCurrencyAmount{
Issuer: "rVnYNK9yuxBz4uP8zC8LEFokM2nqH3poc",
Currency: "USD",
Value: "0.001",
}
)
func main() {
fmt.Println("⏳ Connecting to testnet...")
client := websocket.NewClient(
websocket.NewClientConfig().
WithHost("wss://s.altnet.rippletest.net:51233").
WithFaucetProvider(faucet.NewTestnetFaucetProvider()),
)
defer client.Disconnect()
if err := client.Connect(); err != nil {
fmt.Println(err)
return
}
if !client.IsConnected() {
fmt.Println("❌ Failed to connect to testnet")
return
}
fmt.Println("✅ Connected to testnet")
fmt.Println()
wallet, err := wallet.New(crypto.ED25519())
if err != nil {
fmt.Println(err)
return
}
fmt.Println("⏳ Funding wallet...")
if err := client.FundWallet(&wallet); err != nil {
fmt.Println(err)
return
}
fmt.Println("💸 Wallet funded")
fmt.Println()
fmt.Println("⏳ Getting paths...")
res, err := client.GetRipplePathFind(&path.RipplePathFindRequest{
SourceAccount: wallet.GetAddress(),
SourceCurrencies: []pathtypes.RipplePathFindCurrency{
{
Currency: "XRP",
},
},
DestinationAccount: DestinationAccount,
DestinationAmount: DestinationAmount,
})
if err != nil {
fmt.Println(err)
return
}
fmt.Printf("🌐 Computed paths: %d\n", len(res.Alternatives))
fmt.Println()
if len(res.Alternatives) == 0 {
fmt.Println("❌ No alternatives found")
return
}
fmt.Println("⏳ Submitting Payment through path: ", res.Alternatives[0].PathsComputed)
p := &transaction.Payment{
BaseTx: transaction.BaseTx{
Account: wallet.GetAddress(),
},
Destination: DestinationAccount,
Amount: DestinationAmount,
Paths: res.Alternatives[0].PathsComputed,
}
flatP := p.Flatten()
if err := client.Autofill(&flatP); err != nil {
fmt.Println(err)
return
}
blob, hash, err := wallet.Sign(flatP)
if err != nil {
fmt.Println(err)
return
}
txRes, err := client.SubmitTxBlobAndWait(blob, false)
if err != nil {
fmt.Println(err)
return
}
fmt.Println("✅ Payment submitted")
fmt.Printf("🌐 Hash: %s\n", hash)
fmt.Printf("🌐 Validated: %t\n", txRes.Validated)
}

View File

@@ -0,0 +1,5 @@
module github.com/XRPLF
go 1.23
require github.com/Peersyst/xrpl-go v0.1.11

View File

@@ -0,0 +1 @@
package rpc

View File

@@ -0,0 +1 @@
package ws

View File

@@ -0,0 +1,24 @@
module github.com/XRPLF
go 1.23.0
toolchain go1.23.10
require github.com/Peersyst/xrpl-go v0.1.11
require (
github.com/FactomProject/basen v0.0.0-20150613233007-fe3947df716e // indirect
github.com/FactomProject/btcutilecc v0.0.0-20130527213604-d3a63a5752ec // indirect
github.com/btcsuite/btcd/btcec/v2 v2.3.4 // indirect
github.com/decred/dcrd/crypto/ripemd160 v1.0.2 // indirect
github.com/decred/dcrd/dcrec/secp256k1/v4 v4.3.0 // indirect
github.com/gorilla/websocket v1.5.0 // indirect
github.com/json-iterator/go v1.1.12 // indirect
github.com/mitchellh/mapstructure v1.5.0 // indirect
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421 // indirect
github.com/modern-go/reflect2 v1.0.2 // indirect
github.com/tyler-smith/go-bip32 v1.0.0 // indirect
github.com/tyler-smith/go-bip39 v1.1.0 // indirect
github.com/ugorji/go/codec v1.2.11 // indirect
golang.org/x/crypto v0.23.0 // indirect
)

View File

@@ -0,0 +1,58 @@
github.com/FactomProject/basen v0.0.0-20150613233007-fe3947df716e h1:ahyvB3q25YnZWly5Gq1ekg6jcmWaGj/vG/MhF4aisoc=
github.com/FactomProject/basen v0.0.0-20150613233007-fe3947df716e/go.mod h1:kGUqhHd//musdITWjFvNTHn90WG9bMLBEPQZ17Cmlpw=
github.com/FactomProject/btcutilecc v0.0.0-20130527213604-d3a63a5752ec h1:1Qb69mGp/UtRPn422BH4/Y4Q3SLUrD9KHuDkm8iodFc=
github.com/FactomProject/btcutilecc v0.0.0-20130527213604-d3a63a5752ec/go.mod h1:CD8UlnlLDiqb36L110uqiP2iSflVjx9g/3U9hCI4q2U=
github.com/Peersyst/xrpl-go v0.1.11 h1:P6r/gHxRnbAtAdPmzNHz/7zpsdfvwh0SS+QI2JNT44w=
github.com/Peersyst/xrpl-go v0.1.11/go.mod h1:CBRM3/soqNeeL2Jx6USVUtECqulZVUoq3UxZKMz9hdw=
github.com/btcsuite/btcd/btcec/v2 v2.3.4 h1:3EJjcN70HCu/mwqlUsGK8GcNVyLVxFDlWurTXGPFfiQ=
github.com/btcsuite/btcd/btcec/v2 v2.3.4/go.mod h1:zYzJ8etWJQIv1Ogk7OzpWjowwOdXY1W/17j2MW85J04=
github.com/cmars/basen v0.0.0-20150613233007-fe3947df716e h1:0XBUw73chJ1VYSsfvcPvVT7auykAJce9FpRr10L6Qhw=
github.com/cmars/basen v0.0.0-20150613233007-fe3947df716e/go.mod h1:P13beTBKr5Q18lJe1rIoLUqjM+CB1zYrRg44ZqGuQSA=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/decred/dcrd/crypto/blake256 v1.0.1 h1:7PltbUIQB7u/FfZ39+DGa/ShuMyJ5ilcvdfma9wOH6Y=
github.com/decred/dcrd/crypto/blake256 v1.0.1/go.mod h1:2OfgNZ5wDpcsFmHmCK5gZTPcCXqlm2ArzUIkw9czNJo=
github.com/decred/dcrd/crypto/ripemd160 v1.0.2 h1:TvGTmUBHDU75OHro9ojPLK+Yv7gDl2hnUvRocRCjsys=
github.com/decred/dcrd/crypto/ripemd160 v1.0.2/go.mod h1:uGfjDyePSpa75cSQLzNdVmWlbQMBuiJkvXw/MNKRY4M=
github.com/decred/dcrd/dcrec/secp256k1/v4 v4.3.0 h1:rpfIENRNNilwHwZeG5+P150SMrnNEcHYvcCuK6dPZSg=
github.com/decred/dcrd/dcrec/secp256k1/v4 v4.3.0/go.mod h1:v57UDF4pDQJcEfFUCRop3lJL149eHGSe9Jvczhzjo/0=
github.com/golang/mock v1.6.0 h1:ErTB+efbowRARo13NNdxyJji2egdxLGQhRaY+DUumQc=
github.com/golang/mock v1.6.0/go.mod h1:p6yTPP+5HYm5mzsMV8JkE6ZKdX+/wYM6Hr+LicevLPs=
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
github.com/gorilla/websocket v1.5.0 h1:PPwGk2jz7EePpoHN/+ClbZu8SPxiqlu12wZP/3sWmnc=
github.com/gorilla/websocket v1.5.0/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM=
github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo=
github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyuac5Z2hdY=
github.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo=
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421 h1:ZqeYNhU3OHLH3mGKHDcjJRFFRrJa6eAM5H+CtDdOsPc=
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M=
github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/testify v1.1.5-0.20170601210322-f6abca593680/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk=
github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
github.com/tyler-smith/go-bip32 v1.0.0 h1:sDR9juArbUgX+bO/iblgZnMPeWY1KZMUC2AFUJdv5KE=
github.com/tyler-smith/go-bip32 v1.0.0/go.mod h1:onot+eHknzV4BVPwrzqY5OoVpyCvnwD7lMawL5aQupE=
github.com/tyler-smith/go-bip39 v1.1.0 h1:5eUemwrMargf3BSLRRCalXT93Ns6pQJIjYQN2nyfOP8=
github.com/tyler-smith/go-bip39 v1.1.0/go.mod h1:gUYDtqQw1JS3ZJ8UWVcGTGqqr6YIN3CWg+kkNaLt55U=
github.com/ugorji/go/codec v1.2.11 h1:BMaWp1Bb6fHwEtbplGBGJ498wD+LKlNSl25MjdZY4dU=
github.com/ugorji/go/codec v1.2.11/go.mod h1:UNopzCgEMSXjBc6AOMqYvWC1ktqTAfzJZUZgYf6w6lg=
golang.org/x/crypto v0.0.0-20170613210332-850760c427c5/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/crypto v0.23.0 h1:dIJU/v2J8Mdglj/8rJ6UUOM3Zc9zLZxVZwwxMooUSAI=
golang.org/x/crypto v0.23.0/go.mod h1:CKFgDieR+mRhux2Lsu27y0fO304Db0wZe70UKqHu0v8=
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
launchpad.net/gocheck v0.0.0-20140225173054-000000000087 h1:Izowp2XBH6Ya6rv+hqbceQyw/gSGoXfH/UPoTGduL54=
launchpad.net/gocheck v0.0.0-20140225173054-000000000087/go.mod h1:hj7XX3B/0A+80Vse0e+BUHsHMTEhd0O4cpUHr/e/BUM=

View File

@@ -0,0 +1,131 @@
package main
import (
"fmt"
"github.com/Peersyst/xrpl-go/pkg/crypto"
"github.com/Peersyst/xrpl-go/xrpl/faucet"
"github.com/Peersyst/xrpl-go/xrpl/rpc"
"github.com/Peersyst/xrpl-go/xrpl/transaction"
"github.com/Peersyst/xrpl-go/xrpl/transaction/types"
"github.com/Peersyst/xrpl-go/xrpl/wallet"
)
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)
w1, err := wallet.New(crypto.ED25519())
if err != nil {
fmt.Println(err)
return
}
w2, err := wallet.New(crypto.ED25519())
if err != nil {
fmt.Println(err)
return
}
regularKeyWallet, err := wallet.New(crypto.ED25519())
if err != nil {
fmt.Println(err)
return
}
fmt.Println("⏳ Funding wallets...")
if err := client.FundWallet(&w1); err != nil {
fmt.Println(err)
return
}
fmt.Println("💸 Wallet 1 funded")
if err := client.FundWallet(&w2); err != nil {
fmt.Println(err)
return
}
fmt.Println("💸 Wallet 2 funded")
if err := client.FundWallet(&regularKeyWallet); err != nil {
fmt.Println(err)
return
}
fmt.Println("💸 Regular key wallet funded")
fmt.Println()
fmt.Println("⏳ Setting regular key...")
rk := &transaction.SetRegularKey{
BaseTx: transaction.BaseTx{
Account: w1.GetAddress(),
},
RegularKey: regularKeyWallet.GetAddress(),
}
flatRk := rk.Flatten()
err = client.Autofill(&flatRk)
if err != nil {
fmt.Println(err)
return
}
blob, _, err := w1.Sign(flatRk)
if err != nil {
fmt.Println(err)
return
}
res, err := client.SubmitTxBlobAndWait(blob, false)
if err != nil {
fmt.Println(err)
return
}
fmt.Println("✅ SetRegularKey transaction submitted")
fmt.Printf("🌐 Hash: %s\n", res.Hash)
fmt.Printf("🌐 Validated: %t\n", res.Validated)
fmt.Println()
fmt.Println("⏳ Checking if regular key is set...")
p := &transaction.Payment{
BaseTx: transaction.BaseTx{
Account: w1.GetAddress(),
},
Destination: w2.GetAddress(),
Amount: types.XRPCurrencyAmount(10000),
}
flatP := p.Flatten()
err = client.Autofill(&flatP)
if err != nil {
fmt.Println(err)
return
}
blob, _, err = regularKeyWallet.Sign(flatP)
if err != nil {
fmt.Println(err)
return
}
res, err = client.SubmitTxBlobAndWait(blob, false)
if err != nil {
fmt.Println(err)
return
}
fmt.Println("✅ Payment transaction submitted")
fmt.Printf("🌐 Hash: %s\n", res.Hash)
fmt.Printf("🌐 Validated: %t\n", res.Validated)
}

View File

@@ -0,0 +1,142 @@
package main
import (
"fmt"
"github.com/Peersyst/xrpl-go/pkg/crypto"
"github.com/Peersyst/xrpl-go/xrpl/faucet"
"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"
)
func main() {
fmt.Println("⏳ Connecting to testnet...")
client := websocket.NewClient(
websocket.NewClientConfig().
WithHost("wss://s.altnet.rippletest.net:51233").
WithFaucetProvider(faucet.NewTestnetFaucetProvider()),
)
defer client.Disconnect()
if err := client.Connect(); err != nil {
fmt.Println(err)
return
}
if !client.IsConnected() {
fmt.Println("❌ Failed to connect to testnet")
return
}
fmt.Println("✅ Connected to testnet")
fmt.Println()
w1, err := wallet.New(crypto.ED25519())
if err != nil {
fmt.Println(err)
return
}
w2, err := wallet.New(crypto.ED25519())
if err != nil {
fmt.Println(err)
return
}
regularKeyWallet, err := wallet.New(crypto.ED25519())
if err != nil {
fmt.Println(err)
return
}
fmt.Println("⏳ Funding wallets...")
if err := client.FundWallet(&w1); err != nil {
fmt.Println(err)
return
}
fmt.Println("💸 Wallet 1 funded")
if err := client.FundWallet(&w2); err != nil {
fmt.Println(err)
return
}
fmt.Println("💸 Wallet 2 funded")
if err := client.FundWallet(&regularKeyWallet); err != nil {
fmt.Println(err)
return
}
fmt.Println("💸 Regular key wallet funded")
fmt.Println()
fmt.Println("⏳ Setting regular key...")
rk := &transaction.SetRegularKey{
BaseTx: transaction.BaseTx{
Account: w1.GetAddress(),
},
RegularKey: regularKeyWallet.GetAddress(),
}
flatRk := rk.Flatten()
err = client.Autofill(&flatRk)
if err != nil {
fmt.Println(err)
return
}
blob, _, err := w1.Sign(flatRk)
if err != nil {
fmt.Println(err)
return
}
res, err := client.SubmitTxBlobAndWait(blob, false)
if err != nil {
fmt.Println(err)
return
}
fmt.Println("✅ SetRegularKey transaction submitted")
fmt.Printf("🌐 Hash: %s\n", res.Hash)
fmt.Printf("🌐 Validated: %t\n", res.Validated)
fmt.Println()
fmt.Println("⏳ Checking if regular key is set...")
p := &transaction.Payment{
BaseTx: transaction.BaseTx{
Account: w1.GetAddress(),
},
Destination: w2.GetAddress(),
Amount: types.XRPCurrencyAmount(10000),
}
flatP := p.Flatten()
err = client.Autofill(&flatP)
if err != nil {
fmt.Println(err)
return
}
blob, _, err = regularKeyWallet.Sign(flatP)
if err != nil {
fmt.Println(err)
return
}
res, err = client.SubmitTxBlobAndWait(blob, false)
if err != nil {
fmt.Println(err)
return
}
fmt.Println("✅ Payment transaction submitted")
fmt.Printf("🌐 Hash: %s\n", res.Hash)
fmt.Printf("🌐 Validated: %t\n", res.Validated)
}

View File

@@ -0,0 +1,24 @@
module github.com/XRPLF
go 1.23.0
toolchain go1.23.10
require github.com/Peersyst/xrpl-go v0.1.11
require (
github.com/FactomProject/basen v0.0.0-20150613233007-fe3947df716e // indirect
github.com/FactomProject/btcutilecc v0.0.0-20130527213604-d3a63a5752ec // indirect
github.com/btcsuite/btcd/btcec/v2 v2.3.4 // indirect
github.com/decred/dcrd/crypto/ripemd160 v1.0.2 // indirect
github.com/decred/dcrd/dcrec/secp256k1/v4 v4.3.0 // indirect
github.com/gorilla/websocket v1.5.0 // indirect
github.com/json-iterator/go v1.1.12 // indirect
github.com/mitchellh/mapstructure v1.5.0 // indirect
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421 // indirect
github.com/modern-go/reflect2 v1.0.2 // indirect
github.com/tyler-smith/go-bip32 v1.0.0 // indirect
github.com/tyler-smith/go-bip39 v1.1.0 // indirect
github.com/ugorji/go/codec v1.2.11 // indirect
golang.org/x/crypto v0.23.0 // indirect
)

View File

@@ -0,0 +1,58 @@
github.com/FactomProject/basen v0.0.0-20150613233007-fe3947df716e h1:ahyvB3q25YnZWly5Gq1ekg6jcmWaGj/vG/MhF4aisoc=
github.com/FactomProject/basen v0.0.0-20150613233007-fe3947df716e/go.mod h1:kGUqhHd//musdITWjFvNTHn90WG9bMLBEPQZ17Cmlpw=
github.com/FactomProject/btcutilecc v0.0.0-20130527213604-d3a63a5752ec h1:1Qb69mGp/UtRPn422BH4/Y4Q3SLUrD9KHuDkm8iodFc=
github.com/FactomProject/btcutilecc v0.0.0-20130527213604-d3a63a5752ec/go.mod h1:CD8UlnlLDiqb36L110uqiP2iSflVjx9g/3U9hCI4q2U=
github.com/Peersyst/xrpl-go v0.1.11 h1:P6r/gHxRnbAtAdPmzNHz/7zpsdfvwh0SS+QI2JNT44w=
github.com/Peersyst/xrpl-go v0.1.11/go.mod h1:CBRM3/soqNeeL2Jx6USVUtECqulZVUoq3UxZKMz9hdw=
github.com/btcsuite/btcd/btcec/v2 v2.3.4 h1:3EJjcN70HCu/mwqlUsGK8GcNVyLVxFDlWurTXGPFfiQ=
github.com/btcsuite/btcd/btcec/v2 v2.3.4/go.mod h1:zYzJ8etWJQIv1Ogk7OzpWjowwOdXY1W/17j2MW85J04=
github.com/cmars/basen v0.0.0-20150613233007-fe3947df716e h1:0XBUw73chJ1VYSsfvcPvVT7auykAJce9FpRr10L6Qhw=
github.com/cmars/basen v0.0.0-20150613233007-fe3947df716e/go.mod h1:P13beTBKr5Q18lJe1rIoLUqjM+CB1zYrRg44ZqGuQSA=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/decred/dcrd/crypto/blake256 v1.0.1 h1:7PltbUIQB7u/FfZ39+DGa/ShuMyJ5ilcvdfma9wOH6Y=
github.com/decred/dcrd/crypto/blake256 v1.0.1/go.mod h1:2OfgNZ5wDpcsFmHmCK5gZTPcCXqlm2ArzUIkw9czNJo=
github.com/decred/dcrd/crypto/ripemd160 v1.0.2 h1:TvGTmUBHDU75OHro9ojPLK+Yv7gDl2hnUvRocRCjsys=
github.com/decred/dcrd/crypto/ripemd160 v1.0.2/go.mod h1:uGfjDyePSpa75cSQLzNdVmWlbQMBuiJkvXw/MNKRY4M=
github.com/decred/dcrd/dcrec/secp256k1/v4 v4.3.0 h1:rpfIENRNNilwHwZeG5+P150SMrnNEcHYvcCuK6dPZSg=
github.com/decred/dcrd/dcrec/secp256k1/v4 v4.3.0/go.mod h1:v57UDF4pDQJcEfFUCRop3lJL149eHGSe9Jvczhzjo/0=
github.com/golang/mock v1.6.0 h1:ErTB+efbowRARo13NNdxyJji2egdxLGQhRaY+DUumQc=
github.com/golang/mock v1.6.0/go.mod h1:p6yTPP+5HYm5mzsMV8JkE6ZKdX+/wYM6Hr+LicevLPs=
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
github.com/gorilla/websocket v1.5.0 h1:PPwGk2jz7EePpoHN/+ClbZu8SPxiqlu12wZP/3sWmnc=
github.com/gorilla/websocket v1.5.0/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM=
github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo=
github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyuac5Z2hdY=
github.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo=
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421 h1:ZqeYNhU3OHLH3mGKHDcjJRFFRrJa6eAM5H+CtDdOsPc=
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M=
github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/testify v1.1.5-0.20170601210322-f6abca593680/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk=
github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
github.com/tyler-smith/go-bip32 v1.0.0 h1:sDR9juArbUgX+bO/iblgZnMPeWY1KZMUC2AFUJdv5KE=
github.com/tyler-smith/go-bip32 v1.0.0/go.mod h1:onot+eHknzV4BVPwrzqY5OoVpyCvnwD7lMawL5aQupE=
github.com/tyler-smith/go-bip39 v1.1.0 h1:5eUemwrMargf3BSLRRCalXT93Ns6pQJIjYQN2nyfOP8=
github.com/tyler-smith/go-bip39 v1.1.0/go.mod h1:gUYDtqQw1JS3ZJ8UWVcGTGqqr6YIN3CWg+kkNaLt55U=
github.com/ugorji/go/codec v1.2.11 h1:BMaWp1Bb6fHwEtbplGBGJ498wD+LKlNSl25MjdZY4dU=
github.com/ugorji/go/codec v1.2.11/go.mod h1:UNopzCgEMSXjBc6AOMqYvWC1ktqTAfzJZUZgYf6w6lg=
golang.org/x/crypto v0.0.0-20170613210332-850760c427c5/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/crypto v0.23.0 h1:dIJU/v2J8Mdglj/8rJ6UUOM3Zc9zLZxVZwwxMooUSAI=
golang.org/x/crypto v0.23.0/go.mod h1:CKFgDieR+mRhux2Lsu27y0fO304Db0wZe70UKqHu0v8=
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
launchpad.net/gocheck v0.0.0-20140225173054-000000000087 h1:Izowp2XBH6Ya6rv+hqbceQyw/gSGoXfH/UPoTGduL54=
launchpad.net/gocheck v0.0.0-20140225173054-000000000087/go.mod h1:hj7XX3B/0A+80Vse0e+BUHsHMTEhd0O4cpUHr/e/BUM=

View File

@@ -0,0 +1,137 @@
package main
import (
"encoding/json"
"fmt"
"github.com/Peersyst/xrpl-go/xrpl/faucet"
"github.com/Peersyst/xrpl-go/xrpl/queries/account"
"github.com/Peersyst/xrpl-go/xrpl/rpc"
"github.com/Peersyst/xrpl-go/xrpl/transaction"
"github.com/Peersyst/xrpl-go/xrpl/wallet"
)
const (
WalletSeed = "sn3nxiW7v8KXzPzAqzyHXbSSKNuN9"
)
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)
w, err := wallet.FromSeed(WalletSeed, "")
if err != nil {
fmt.Println(err)
return
}
fmt.Println("⏳ Funding wallet...")
if err := client.FundWallet(&w); err != nil {
fmt.Println(err)
return
}
fmt.Println("💸 Wallet funded")
fmt.Println()
info, err := client.GetAccountInfo(&account.InfoRequest{
Account: w.GetAddress(),
})
if err != nil {
fmt.Println(err)
return
}
fmt.Println("🌐 Current wallet sequence:", info.AccountData.Sequence)
fmt.Println()
fmt.Println("⏳ Submitting TicketCreate transaction...")
tc := &transaction.TicketCreate{
BaseTx: transaction.BaseTx{
Account: w.GetAddress(),
Sequence: info.AccountData.Sequence,
},
TicketCount: 10,
}
flatTc := tc.Flatten()
if err := client.Autofill(&flatTc); err != nil {
fmt.Println(err)
return
}
blob, _, err := w.Sign(flatTc)
if err != nil {
fmt.Println(err)
return
}
res, err := client.SubmitTxBlobAndWait(blob, false)
if err != nil {
fmt.Println(err)
return
}
fmt.Println("✅ TicketCreate transaction submitted")
fmt.Printf("🌐 Hash: %s\n", res.Hash)
fmt.Printf("🌐 Validated: %t\n", res.Validated)
fmt.Println()
objects, err := client.GetAccountObjects(&account.ObjectsRequest{
Account: w.GetAddress(),
})
if err != nil {
fmt.Println(err)
return
}
fmt.Println("🌐 Account objects:", objects.AccountObjects[0]["TicketSequence"])
seq, err := objects.AccountObjects[0]["TicketSequence"].(json.Number).Int64()
if err != nil {
fmt.Println(err)
return
}
fmt.Println("⏳ Submitting AccountSet transaction...")
as := &transaction.AccountSet{
BaseTx: transaction.BaseTx{
Account: w.GetAddress(),
Sequence: 0,
TicketSequence: uint32(seq),
},
}
flatAs := as.Flatten()
if err := client.Autofill(&flatAs); err != nil {
fmt.Println(err)
return
}
flatAs["Sequence"] = uint32(0)
blob, _, err = w.Sign(flatAs)
if err != nil {
fmt.Println(err)
return
}
res, err = client.SubmitTxBlobAndWait(blob, false)
if err != nil {
fmt.Println(err)
return
}
fmt.Println("✅ AccountSet transaction submitted")
fmt.Printf("🌐 Hash: %s\n", res.Hash)
fmt.Printf("🌐 Validated: %t\n", res.Validated)
}

View File

@@ -0,0 +1,148 @@
package main
import (
"encoding/json"
"fmt"
"github.com/Peersyst/xrpl-go/xrpl/faucet"
"github.com/Peersyst/xrpl-go/xrpl/queries/account"
"github.com/Peersyst/xrpl-go/xrpl/transaction"
"github.com/Peersyst/xrpl-go/xrpl/wallet"
"github.com/Peersyst/xrpl-go/xrpl/websocket"
)
const (
WalletSeed = "sn3nxiW7v8KXzPzAqzyHXbSSKNuN9"
)
func main() {
fmt.Println("⏳ Connecting to testnet...")
client := websocket.NewClient(
websocket.NewClientConfig().
WithHost("wss://s.altnet.rippletest.net:51233").
WithFaucetProvider(faucet.NewTestnetFaucetProvider()),
)
defer client.Disconnect()
if err := client.Connect(); err != nil {
fmt.Println(err)
return
}
if !client.IsConnected() {
fmt.Println("❌ Failed to connect to testnet")
return
}
fmt.Println("✅ Connected to testnet")
fmt.Println()
w, err := wallet.FromSeed(WalletSeed, "")
if err != nil {
fmt.Println(err)
return
}
fmt.Println("⏳ Funding wallet...")
if err := client.FundWallet(&w); err != nil {
fmt.Println(err)
return
}
fmt.Println("💸 Wallet funded")
fmt.Println()
info, err := client.GetAccountInfo(&account.InfoRequest{
Account: w.GetAddress(),
})
if err != nil {
fmt.Println(err)
return
}
fmt.Println("🌐 Current wallet sequence:", info.AccountData.Sequence)
fmt.Println()
fmt.Println("⏳ Submitting TicketCreate transaction...")
tc := &transaction.TicketCreate{
BaseTx: transaction.BaseTx{
Account: w.GetAddress(),
Sequence: info.AccountData.Sequence,
},
TicketCount: 10,
}
flatTc := tc.Flatten()
if err := client.Autofill(&flatTc); err != nil {
fmt.Println(err)
return
}
blob, _, err := w.Sign(flatTc)
if err != nil {
fmt.Println(err)
return
}
res, err := client.SubmitTxBlobAndWait(blob, false)
if err != nil {
fmt.Println(err)
return
}
fmt.Println("✅ TicketCreate transaction submitted")
fmt.Printf("🌐 Hash: %s\n", res.Hash)
fmt.Printf("🌐 Validated: %t\n", res.Validated)
fmt.Println()
objects, err := client.GetAccountObjects(&account.ObjectsRequest{
Account: w.GetAddress(),
})
if err != nil {
fmt.Println(err)
return
}
fmt.Println("🌐 Account objects:", objects.AccountObjects[0]["TicketSequence"])
seq, err := objects.AccountObjects[0]["TicketSequence"].(json.Number).Int64()
if err != nil {
fmt.Println(err)
return
}
fmt.Println("⏳ Submitting AccountSet transaction...")
as := &transaction.AccountSet{
BaseTx: transaction.BaseTx{
Account: w.GetAddress(),
Sequence: 0,
TicketSequence: uint32(seq),
},
}
flatAs := as.Flatten()
if err := client.Autofill(&flatAs); err != nil {
fmt.Println(err)
return
}
flatAs["Sequence"] = uint32(0)
blob, _, err = w.Sign(flatAs)
if err != nil {
fmt.Println(err)
return
}
res, err = client.SubmitTxBlobAndWait(blob, false)
if err != nil {
fmt.Println(err)
return
}
fmt.Println("✅ AccountSet transaction submitted")
fmt.Printf("🌐 Hash: %s\n", res.Hash)
fmt.Printf("🌐 Validated: %t\n", res.Validated)
}