wallet
Overview
The wallet package contains the types and functions to work and manage your XRPL accounts. Either you want to create a new account, or you want to sign transactions, this package has you covered.
This package enables you to do the following actions:
- Generate new wallets using a seed, mnemonic or random.
- Sign and multisign transactions.
- Authorize payment channel redemptions.
- Access to wallet's public and private keys and address.
Generating a wallet
In order to generate a new wallet, you can either use a seed, a mnemonic or generate a random one. Here are the constructors available:
// Wallet constructors
func New(alg interfaces.CryptoImplementation) (Wallet, error)
func FromSeed(seed string, masterAddress string) (Wallet, error)
func FromSecret(seed string) (Wallet, error)
func FromMnemonic(mnemonic string) (*Wallet, error)
When generating a random wallet, you will need to specify the algorithm you want to use.
xrpl-go library provides the package crypto that exports ed25519 and secp256k1 algorithms which satisfy the CryptoImplementation interface.
You can use the crypto package by importing it in your project:
import "github.com/xrpl-go/pkg/crypto"
When initializing a wallet from a seed, remember that only seeds generated by ed25519 and secp256k1 algorithms are supported. Learn more about XRPL cryptographic keys in the official documentation.
Signing and multisigning transactions
A wallet lets the developer sign and multisign transactions easily. The Wallet type exposes the following signing methods:
// Signing methods
func (w *Wallet) Sign(tx map[string]interface{}) (string, string, error)
func (w *Wallet) Multisign(tx map[string]interface{}) (string, string, error)
The Sign method signs a flat transaction and returns the signed transaction blob and the signature.
On the other hand, the Multisign method multisigns a flat transaction by adding the wallet's signature to the transaction and returning the resulting transaction blob and the blob hash. Learn more about how multisigns work in the official documentation.
Signing a batch transaction
There's also the SignMultiBatch package function that signs each RawTransaction of a Batch transaction, signed by every account involved, excluding the account that's signing the overall transaction.
func SignMultiBatch(wallet Wallet, tx *transaction.FlatTransaction, opts *SignMultiBatchOptions) error
Authorizing payment channel redemptions
The AuthorizeChannel function allows you to create a signature that authorizes the redemption of a specific amount of XRP from a payment channel. This is useful for payment channels where the source account needs to authorize claims before they can be redeemed.
func AuthorizeChannel(channelID, amount string, wallet Wallet) (string, error)
channelIDidentifies the payment channel (hex-encoded string).amountis the amount to redeem, expressed in drops (XRP's smallest unit).- Returns the signature string that can be used to authorize the channel claim.
Payment channels allow for off-ledger transactions between two parties. The AuthorizeChannel function creates a signature that authorizes a specific amount to be claimed from the channel. Learn more about payment channels in the official documentation.
Example
package main
import (
"fmt"
"log"
"github.com/Peersyst/xrpl-go/xrpl/wallet"
)
func main() {
// Create a wallet from a seed
wallet, err := wallet.FromSeed("snGHNrPbHrdUcszeuDEigMdC1Lyyd", "")
if err != nil {
log.Fatal(err)
}
// Authorize redemption of 1 XRP (1,000,000 drops) from a payment channel
channelID := "5DB01B7FFED6B67E6B0414DED11E051D2EE2B7619CE0EAA6286D67A3A4D5BDB3"
amount := "1000000" // 1 XRP in drops
signature, err := wallet.AuthorizeChannel(channelID, amount, wallet)
if err != nil {
log.Fatal(err)
}
fmt.Println("Authorization signature:", signature)
}
Usage
In this section, we will see how to generate a Wallet, call the faucet to get XRP, and send the XRP to another account.
First step is to generate a Wallet using the New constructor (in this case, we will use the ed25519 algorithm):
wallet, err := wallet.New(crypto.ED25519())
if err != nil {
// ...
}
Once we have the Wallet, we can call the faucet to get XRP. For this example, we will use the DevnetFaucetProvider to get XRP on the devnet ledger:
devnetFaucet := faucet.NewDevnetFaucetProvider()
err := devnetFaucet.FundWallet(wallet.ClassicAddress)
if err != nil {
// ...
}
Once we have the XRP, we can create a Payment transaction. For this example, we will send the XRP to the rJ96831v5JXxna35JYvsW9VRmENwq23ib9 account.
payment := transaction.Payment{
BaseTx: transaction.BaseTx{
Account: wallet.ClassicAddress,
},
Destination: "rJ96831v5JXxna35JYvsW9VRmENwq23ib9",
Amount: types.XRPCurrencyAmount(10000000),
DeliverMax: types.XRPCurrencyAmount(10000000),
}
Finally, we can sign the flat payment transaction:
blob, hash, err := wallet.Sign(payment.Flatten())
if err != nil {
// ...
}
Summarizing, the complete code to generate a wallet, call the faucet to get XRP, create a payment transaction and sign it is the following:
package main
import (
"fmt"
"log"
"github.com/Peersyst/xrpl-go/pkg/crypto"
"github.com/Peersyst/xrpl-go/xrpl/transaction"
"github.com/Peersyst/xrpl-go/xrpl/transaction/types"
"github.com/Peersyst/xrpl-go/xrpl/wallet"
)
func main() {
wallet, err := wallet.New(crypto.ED25519())
if err != nil {
log.Fatal(err)
}
payment := transaction.Payment{
BaseTx: transaction.BaseTx{
Account: wallet.ClassicAddress,
},
Destination: "rJ96831v5JXxna35JYvsW9VRmENwq23ib9",
Amount: types.XRPCurrencyAmount(10000000),
DeliverMax: types.XRPCurrencyAmount(10000000),
}
blob, hash, err := wallet.Sign(payment.Flatten())
if err != nil {
log.Fatal(err)
}
fmt.Println("Tx blob: ", blob)
fmt.Println("Tx hash: ", hash)
}