0. Prerequisites
This guide assumes the setup guide is complete and a Privy client instance is available.
1. Creating a wallet
First, create a wallet. The wallet’s id is used in future calls to sign messages and send transactions.
wallet, err := client.Wallets.New(context.Background(), privy.WalletNewParams{
ChainType: privy.WalletChainTypeEthereum,
})
if err != nil {
log.Fatalf("failed to create wallet: %v", err)
}
walletID := wallet.ID
wallet, err := client.Wallets.New(context.Background(), privy.WalletNewParams{
ChainType: privy.WalletChainTypeSolana,
})
if err != nil {
log.Fatalf("failed to create wallet: %v", err)
}
walletID := wallet.ID
2. Signing a message
Next, sign a plaintext message with the wallet using chain-specific signing methods.
Specify the wallet ID (not address) from creation in the input.
message := "Hello, Privy!"
response, err := client.Wallets.Ethereum.SignMessage(
context.Background(),
walletID,
message,
)
if err != nil {
log.Fatalf("failed to sign message: %v", err)
}
signature := response.Signature
message := "Hello, Privy!"
response, err := client.Wallets.Solana.SignMessage(
context.Background(),
walletID,
message,
)
if err != nil {
log.Fatalf("failed to sign message: %v", err)
}
signature := response.Signature
3. Sending transactions
The wallet must have funds to send a transaction. Use a testnet
faucet to test transacting on a testnet (e.g. Base Sepolia)
or send funds to the wallet on the network of choice.
To send a transaction from a wallet, use chain-specific transaction methods. The SDK
populates missing network-related values, signs the transaction, broadcasts it to the network, and
returns the transaction hash.
In the request, specify the wallet id from wallet creation above, as well as
the caip2 chain ID for the target network.
caip2 := "eip155:11155111" // Sepolia testnet
response, err := client.Wallets.Ethereum.SendTransaction(
context.Background(),
walletID,
caip2,
privy.EthereumSendTransactionRpcInputParams{
Transaction: privy.EthereumSendTransactionRpcInputParamsTransaction{
To: param.NewOpt(recipientAddress),
Value: privy.EthereumSendTransactionRpcInputParamsTransactionValueUnion{
OfString: param.NewOpt("0x1"), // 1 wei
},
ChainID: privy.EthereumSendTransactionRpcInputParamsTransactionChainIDUnion{
OfInt: privy.Int(11155111), // Sepolia testnet
},
},
},
)
if err != nil {
log.Fatalf("failed to send transaction: %v", err)
}
transactionHash := response.Hash
caip2 := "solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp" // Solana Mainnet
// A base64 encoded serialized transaction
transaction := "insert-base-64-encoded-serialized-transaction"
response, err := client.Wallets.Solana.SignAndSendTransaction(
context.Background(),
walletID,
caip2,
privy.SolanaSignAndSendTransactionRpcInputParams{
Encoding: "base64",
Transaction: transaction,
},
)
if err != nil {
log.Fatalf("failed to send transaction: %v", err)
}
transactionHash := response.Hash
For more control, prepare and broadcast the transaction independently, and use raw signing methods
to sign the transaction with a wallet.
4. Creating a user
To create a user for an application, use the New method. Pass in linked accounts, custom
metadata, and wallets to associate with the user.
user, err := client.Users.New(context.Background(), privy.UserNewParams{
LinkedAccounts: []privy.LinkedAccountInputUnion{
{
OfCustomAuth: &privy.LinkedAccountCustomAuthInput{
Type: privy.LinkedAccountCustomAuthInputTypeCustomAuth,
CustomUserID: "your-subject-id",
},
},
{
OfEmail: &privy.LinkedAccountEmailInput{
Type: privy.LinkedAccountEmailInputTypeEmail,
Address: "[email protected]",
},
},
},
})
if err != nil {
log.Fatalf("failed to create user: %v", err)
}
userID := user.ID
Next steps