--- title: Getting Started with Golang description: A quick start guide for building applications with Sonr using the Go Client SDK sidebarTitle: Golang Quickstart icon: "golang" --- This guide provides a walkthrough for setting up a Go project to interact with the Sonr network using the official Go Client SDK. You will learn how to configure the client, manage keys, query the blockchain, send transactions, and use advanced features like WebAuthn gasless transactions. ## Prerequisites - A local Sonr network running. See the [Validator Setup Guide](/quickstart/validators) for instructions - Go version 1.24 or higher ## 1. Project Setup ### Initialize a Go Module Create a new directory for your project and initialize a Go module: ```bash mkdir sonr-go-quickstart cd sonr-go-quickstart go mod init github.com/your-username/sonr-go-quickstart ``` ### Add the Sonr Client SDK Dependency Add the Sonr Client SDK to your project's dependencies: ```bash go get github.com/sonr-io/sonr/client ``` ## 2. Client Configuration and Setup Let's set up the Sonr client with proper configuration and key management. ### Create the Main File Create a new file named `main.go`. ### Initialize the Client Add the following code to `main.go` to initialize the Sonr client: ```go package main import ( "context" "fmt" "log" "google.golang.org/grpc" "google.golang.org/grpc/credentials/insecure" "github.com/sonr-io/sonr/client/config" "github.com/sonr-io/sonr/client/keys" "github.com/sonr-io/sonr/client/sonr" "github.com/sonr-io/sonr/client/tx" ) func main() { // Use local network configuration cfg := config.LocalNetwork() // Establish gRPC connection conn, err := grpc.Dial( cfg.GRPC, grpc.WithTransportCredentials(insecure.NewCredentials()), ) if err != nil { log.Fatal("Failed to connect:", err) } defer conn.Close() // Create the Sonr client client, err := sonr.NewClient(&cfg, conn) if err != nil { log.Fatal("Failed to create client:", err) } fmt.Println("Sonr client initialized successfully!") fmt.Printf("Connected to: %s\n", cfg.ChainID) } ``` ### Create a Keyring Manager Add key management to handle wallet operations: ```go // Initialize keyring manager (using test backend for development) keyringManager, err := keys.NewKeyringManager( "test", // backend: test, file, os ".sonr-keys", // directory for keys cfg.ChainID, // chain ID ) if err != nil { log.Fatal("Failed to create keyring:", err) } // Create a new wallet walletIdentity, mnemonic, err := keyringManager.CreateWallet( context.Background(), "my-wallet", // wallet name "", // passphrase (empty for test backend) ) if err != nil { log.Fatal("Failed to create wallet:", err) } fmt.Printf("Wallet created!\n") fmt.Printf("Address: %s\n", walletIdentity.Address) fmt.Printf("DID: %s\n", walletIdentity.DID) fmt.Printf("Mnemonic: %s\n", mnemonic) ``` **Important**: In production, use secure keyring backends like "os" or "file" with proper passphrase protection. Never expose mnemonics in your code. ## 3. Querying the Blockchain Now, let's query the blockchain using the unified query client. ### Create a Query Client Add the query client to your application: ```go import ( "github.com/sonr-io/sonr/client/query" ) // Create query client queryClient, err := query.NewQueryClient(conn, &cfg) if err != nil { log.Fatal("Failed to create query client:", err) } ``` ### Query Account Balance Query an account's balance: ```go // Query account balance address := walletIdentity.Address // or any other address balance, err := queryClient.Balance( context.Background(), address, cfg.StakingDenom, // "usnr" ) if err != nil { log.Printf("Failed to query balance: %v", err) } else { fmt.Printf("Balance for %s: %s %s\n", address, balance.Balance.Amount.String(), balance.Balance.Denom, ) } // Query all balances for an account allBalances, err := queryClient.AllBalances( context.Background(), address, nil, // pagination ) if err != nil { log.Printf("Failed to query all balances: %v", err) } else { fmt.Printf("All balances: %v\n", allBalances.Balances) } ``` ### Query Module-Specific Data Query DID documents and other module data: ```go import ( "github.com/sonr-io/sonr/client/modules/did" ) // Create DID module client didClient := did.NewDIDClient() // Query DID document (if exists) didID := "did:sonr:example123" didDoc, err := queryClient.GetDID(context.Background(), didID) if err != nil { log.Printf("DID not found: %v", err) } else { fmt.Printf("DID Document: %+v\n", didDoc) } // List all DIDs with pagination didList, err := queryClient.ListDIDs( context.Background(), &query.ListOptions{ Limit: 10, Offset: 0, }, ) if err != nil { log.Printf("Failed to list DIDs: %v", err) } else { fmt.Printf("Found %d DIDs\n", len(didList.DIDs)) } ``` ## 4. Building and Broadcasting Transactions Let's build and broadcast transactions using the transaction builder. ### Create a Transaction Builder Initialize the transaction builder with gas estimation: ```go // Create transaction builder txBuilder, err := tx.NewTxBuilder(&cfg, conn) if err != nil { log.Fatal("Failed to create tx builder:", err) } // Create broadcaster broadcaster, err := tx.NewBroadcaster(&cfg, conn) if err != nil { log.Fatal("Failed to create broadcaster:", err) } // Create gas estimator gasEstimator := tx.NewGasEstimator(conn, &cfg) ``` ### Send Tokens Between Accounts Build and broadcast a bank send transaction: ```go import ( sdk "github.com/cosmos/cosmos-sdk/types" banktypes "github.com/cosmos/cosmos-sdk/x/bank/types" ) // Create a second wallet to receive funds receiver, _, err := keyringManager.CreateWallet( context.Background(), "receiver-wallet", "", ) if err != nil { log.Fatal("Failed to create receiver wallet:", err) } // Create send message amount := sdk.NewCoins(sdk.NewInt64Coin("usnr", 1000000)) // 1 SNR sendMsg := &banktypes.MsgSend{ FromAddress: walletIdentity.Address, ToAddress: receiver.Address, Amount: amount, } // Build transaction txBuilder = txBuilder. AddMessage(sendMsg). WithMemo("Test transaction"). WithGasLimit(200000) // Estimate gas gasEstimate, err := gasEstimator.EstimateGas( context.Background(), []sdk.Msg{sendMsg}, ) if err != nil { log.Printf("Gas estimation failed: %v", err) } else { fmt.Printf("Estimated gas: %d\n", gasEstimate.GasLimit) txBuilder = txBuilder.WithGasLimit(gasEstimate.GasLimit) } // Calculate and set fee fee := gasEstimator.CalculateFee( gasEstimate.GasLimit, cfg.GasPrice, cfg.StakingDenom, ) txBuilder = txBuilder.WithFee(fee) // Sign the transaction signedTx, err := txBuilder.Sign(context.Background(), keyringManager) if err != nil { log.Fatal("Failed to sign transaction:", err) } // Broadcast the transaction result, err := broadcaster.BroadcastTx(context.Background(), signedTx) if err != nil { log.Fatal("Failed to broadcast transaction:", err) } fmt.Printf("Transaction successful!\n") fmt.Printf("TxHash: %s\n", result.TxHash) fmt.Printf("Height: %d\n", result.Height) fmt.Printf("Gas Used: %d\n", result.GasUsed) ``` ## 5. WebAuthn Gasless Transactions (Advanced) Sonr supports gasless WebAuthn registration, allowing users to onboard without holding tokens. ### Initialize WebAuthn Client Set up the WebAuthn client for gasless operations: ```go import ( "github.com/sonr-io/sonr/client/auth" ) // Create WebAuthn client webauthnClient := auth.NewWebAuthnClient( keyringManager, "localhost", // Relying Party ID "Sonr Local", // Relying Party Name ) // Create gasless transaction manager gaslessManager := auth.NewGaslessTransactionManager( txBuilder, broadcaster, &cfg, ) // Create WebAuthn gasless client gaslessClient := auth.NewWebAuthnGaslessClient( webauthnClient, gaslessManager, &cfg, ) ``` ### Initiate Gasless Registration Start a gasless WebAuthn registration: ```go // Begin gasless registration registrationResult, err := gaslessClient.RegisterGasless( context.Background(), "alice", // username "Alice Smith", // display name ) if err != nil { log.Fatal("Failed to initiate registration:", err) } fmt.Printf("Registration initiated!\n") fmt.Printf("Gasless eligible: %v\n", registrationResult.GaslessEligible) fmt.Printf("Estimated gas: %d\n", registrationResult.EstimatedGas) // The challenge would be sent to a browser for completion // In a real application, you'd handle the browser response ``` ### Check Gasless Eligibility Verify if a transaction is eligible for gasless processing: ```go // Check if messages are eligible for gasless msgs := []sdk.Msg{ &didtypes.MsgRegisterWebAuthnCredential{ Controller: "sonr1...", Username: "alice", }, } isEligible := gaslessManager.IsEligibleForGasless(msgs) fmt.Printf("Transaction eligible for gasless: %v\n", isEligible) // Estimate gas for gasless transaction gasNeeded := gaslessManager.EstimateGaslessGas( "/did.v1.MsgRegisterWebAuthnCredential", ) fmt.Printf("Gas needed for gasless WebAuthn: %d\n", gasNeeded) ``` ## 6. Working with DID Module Create and manage decentralized identities: ### Create a DID Document ```go import ( didtypes "github.com/sonr-io/sonr/x/did/types" ) // Create DID document didDoc := &didtypes.DidDocument{ Id: "did:sonr:" + walletIdentity.Address, Controller: walletIdentity.Address, VerificationMethod: []*didtypes.VerificationMethod{ { Id: "did:sonr:" + walletIdentity.Address + "#key-1", VerificationMethodKind: didtypes.VerificationMethodKind_Ed25519VerificationKey2020, Controller: "did:sonr:" + walletIdentity.Address, PublicKeyMultibase: "z6MkhaXgBZD...", // Your public key }, }, Service: []*didtypes.Service{ { Id: "did:sonr:" + walletIdentity.Address + "#dwn", ServiceKind: didtypes.ServiceKind_DecentralizedWebNode, SingleEndpoint: "https://dwn.example.com", }, }, } // Create the message createDIDMsg, err := didClient.CreateDID( walletIdentity.Address, didDoc, ) if err != nil { log.Fatal("Failed to create DID message:", err) } // Add to transaction and broadcast txBuilder = txBuilder. ClearMessages(). AddMessage(createDIDMsg). WithMemo("Create DID") // Sign and broadcast as shown earlier ``` ## Next Steps This quickstart has covered the fundamentals of the Sonr Go Client SDK: - **Client Configuration**: Setting up connections and network configurations - **Key Management**: Creating and managing wallets with the keyring - **Querying**: Reading blockchain state and module data - **Transactions**: Building, signing, and broadcasting transactions - **Gas Estimation**: Calculating optimal gas limits and fees - **WebAuthn**: Gasless onboarding with WebAuthn credentials - **DID Module**: Creating decentralized identities ### Advanced Topics to Explore: - **DWN Module**: Manage decentralized web nodes and data records - **Service Module**: Register and verify services with domain verification - **UCAN Integration**: Implement capability-based authorization - **Multi-signature**: Create and manage multi-sig accounts - **IBC Transfers**: Cross-chain token transfers - **Custom Modules**: Interact with your own custom modules ### Useful Resources: - [Client SDK API Reference](https://pkg.go.dev/github.com/sonr-io/sonr/client) - [Cosmos SDK Documentation](https://docs.cosmos.network) - [Sonr GitHub Repository](https://github.com/sonr-io/sonr)