{"templateId":"markdown","sharedDataIds":{},"props":{"metadata":{"markdoc":{"tagList":[]},"type":"markdown"},"seo":{"title":"XRPL Go Code Sample Conventions","siteUrl":"https://xrpl.org/","llmstxt":{"hide":false,"title":"XRPL Developer Portal & Documentation","description":"Explore XRP Ledger documentation, blogs, and other blockchain developer resources needed to start building and integrating with the ledger.","details":{"content":"XRP Ledger concepts, use cases, tutorials, references, and other blockchain developer resources. Also, stay up to date with release announcements and more through the XRPL Blog."},"sections":[{"title":"Introduction","description":"A high-level introduction to the XRP Ledger.","includeFiles":["docs/introduction/**/*.*","about/faq.md"],"excludeFiles":["docs/introduction/index.md"]},{"title":"Use Cases","description":"Real-world applications and business scenarios for the XRP Ledger.","includeFiles":["docs/use-cases/**/*.*"],"excludeFiles":["docs/use-cases/index.md","docs/use-cases/defi/index.md"]},{"title":"Concepts","description":"Core concepts including accounts, tokens, transactions, consensus, and more.","includeFiles":["docs/concepts/**/*.*"],"excludeFiles":["docs/concepts/index.md","docs/concepts/decentralized-storage/index.md","docs/concepts/payment-types/index.md"]},{"title":"Tutorials","description":"Step-by-step guides for building on the XRP Ledger in JavaScript, Python, Go, and more.","includeFiles":["docs/tutorials/**/*.*"],"excludeFiles":[]},{"title":"References","description":"Protocol specification, transaction types, ledger entries, and API methods.","includeFiles":["docs/references/**/*.*"],"excludeFiles":["docs/references/xrp-api.md","docs/references/data-api.md","docs/references/protocol/index.md","docs/references/protocol/ledger-data/ledger-entry-types/index.md","docs/references/protocol/transactions/index.md","docs/references/protocol/transactions/types/index.md","docs/references/http-websocket-apis/api-conventions/index.md","docs/references/http-websocket-apis/public-api-methods/*/index.md","docs/references/http-websocket-apis/admin-api-methods/*/index.md"]},{"title":"Infrastructure","description":"Install, configure, and troubleshoot rippled and Clio servers.","includeFiles":["docs/infrastructure/**/*.*"],"excludeFiles":["docs/infrastructure/index.md","docs/infrastructure/*/index.md","docs/infrastructure/installation/build-run-rippled-in-reporting-mode.md","docs/infrastructure/configuration/data-retention/index.md","docs/infrastructure/configuration/server-modes/index.md"]},{"title":"Blog (2023+)","description":"Recent XRPL Blog posts (showing 2023 and newer).","includeFiles":["blog/2023/**/*.*","blog/2024/**/*.*","blog/2025/**/*.*","blog/2026/**/*.*"],"excludeFiles":[]},{"title":"Resources","description":"Developer resources and contribution guidelines.","includeFiles":["resources/**/*.*"],"excludeFiles":["resources/index.md"]}],"excludeFiles":[]}},"dynamicMarkdocComponents":[],"compilationErrors":[],"ast":{"$$mdtype":"Tag","name":"article","attributes":{},"children":[{"$$mdtype":"Tag","name":"Heading","attributes":{"level":1,"id":"xrpl-go-code-sample-conventions","__idx":0},"children":["XRPL Go Code Sample Conventions"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Code samples come in ",{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["two flavors"]}," with very different conventions. Identify which you're writing first."]},{"$$mdtype":"Tag","name":"div","attributes":{"className":"md-table-wrapper"},"children":[{"$$mdtype":"Tag","name":"table","attributes":{"className":"md"},"children":[{"$$mdtype":"Tag","name":"thead","attributes":{},"children":[{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"th","attributes":{"data-label":"Flavor"},"children":["Flavor"]},{"$$mdtype":"Tag","name":"th","attributes":{"data-label":"Folder pattern"},"children":["Folder pattern"]},{"$$mdtype":"Tag","name":"th","attributes":{"data-label":"Audience"},"children":["Audience"]},{"$$mdtype":"Tag","name":"th","attributes":{"data-label":"Priority"},"children":["Priority"]}]}]},{"$$mdtype":"Tag","name":"tbody","attributes":{},"children":[{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Tutorial"]}]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["<verb>-<thing>/main.go"]}," (e.g., ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["create-loan-broker/main.go"]},")"]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":["A dev reading & learning the protocol"]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":["Clarity over speed"]}]},{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Setup"]}]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["<topic>-setup/main.go"]}," (e.g., ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["lending-setup/main.go"]},")"]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":["A dev who never opens this file — runs to prep network data (accounts, tokens, etc.) for all tutorials in the subject folder"]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":["Speed over clarity"]}]}]}]}]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["If a file isn't clearly one or the other, prompt the user for clarity."]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":2,"id":"style","__idx":1},"children":["Style"]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":3,"id":"formatting","__idx":2},"children":["Formatting"]},{"$$mdtype":"Tag","name":"ul","attributes":{},"children":[{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["gofmt"]},"-formatted (tabs, standard layout)"]}]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":3,"id":"naming","__idx":3},"children":["Naming"]},{"$$mdtype":"Tag","name":"ul","attributes":{},"children":[{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Folder/binary names: ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["kebab-case"]}," (e.g., ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["create-loan-broker/"]},")"]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Variables: ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["camelCase"]}," with acronyms uppercased — ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["loanBrokerWallet"]},", ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["mptID"]},", ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["vaultID"]},", ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["loanBrokerID"]},", ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["credIssuerWallet"]}]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Transaction struct fields: native XRPL ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["PascalCase"]}," (",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["Account"]},", ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["VaultID"]},", ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["ManagementFeeRate"]},") — matches both Go's exported-field rule and the XRPL wire format. Common fields (",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["Account"]},", ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["Sequence"]},", ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["Fee"]},", ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["TicketSequence"]},") go in the embedded ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["BaseTx"]}," substruct."]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Setup JSON keys: ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["camelCase"]}," (",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["loanBroker"]},", ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["credentialIssuer"]},", ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["mptID"]},", ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["vaultID"]},", ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["loanBrokerID"]},")"]}]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":2,"id":"structure","__idx":4},"children":["Structure"]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":3,"id":"folder-layout","__idx":5},"children":["Folder layout"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Each code sample lives at ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["_code-samples/<topic>/go/"]},". Every command is its own ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["kebab-case"]}," subdir containing one ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["main.go"]},":"]},{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"header":{"controls":{"copy":{}}},"source":"_code-samples/<topic>/go/\n├── README.md\n├── go.mod\n├── go.sum                       # Auto-generated by `go mod tidy`; gitignored\n├── <topic>-setup/\n│   └── main.go                  # Optional — runs once to prep network state\n├── <topic>-setup.json           # Auto-generated by the setup script; gitignored\n└── <verb>-<thing>/\n    └── main.go                  # Tutorial commands (one per user action)\n"},"children":[]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Run any command with ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["go run ./<verb>-<thing>"]}," from the language root directory."]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":3,"id":"readme","__idx":6},"children":["README"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["README.md"]}," is the entry point for a reader running the samples."]},{"$$mdtype":"Tag","name":"ol","attributes":{},"children":[{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Title: ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["# <Topic> Examples (Go)"]}]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["One-sentence description listing what the directory demonstrates"]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["## Setup"]}," section with the note \"All commands should be run from this ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["go/"]}," directory.\" and a ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["go mod tidy"]}," fenced block"]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["One ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["##"]}," section per tutorial command, in the order a reader should run them:"]}]},{"$$mdtype":"Tag","name":"ul","attributes":{},"children":[{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Heading describes the action (e.g., ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["## Create a Loan Broker"]},"), not the folder name"]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Fenced ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["sh"]}," block with ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["go run ./<verb>-<thing>"]}]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["One-sentence summary of what the command will output"]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Fenced ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["sh"]}," block showing actual expected console output (real addresses, tx IDs, JSON dumps — captured from a successful sample code run)"]}]},{"$$mdtype":"Tag","name":"ol","attributes":{"start":5},"children":[{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["---"]}," separator between tutorial sections"]}]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["The expected-output blocks document the golden path. Update them when a command's output format changes."]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":3,"id":"gomod","__idx":7},"children":["go.mod"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["One ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["go.mod"]}," per sample at the language root. Pin the xrpl-go version:"]},{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"header":{"controls":{"copy":{}}},"source":"module github.com/XRPLF\n\ngo 1.24.3\n\nrequire github.com/Peersyst/xrpl-go v<latest-stable>\n"},"children":[]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["go mod tidy"]}," populates the indirect dependency block at the bottom — that block is auto-managed and shouldn't be hand-edited."]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":3,"id":"pointer-helper","__idx":8},"children":["Pointer helper"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Any ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["main.go"]}," that sets optional pointer fields includes this helper near the top of the file:"]},{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"go","header":{"controls":{"copy":{}}},"source":"// ptr is a helper that returns a pointer to the given value,\n// used for setting optional transaction fields in Go.\nfunc ptr[T any](v T) *T { return &v }\n","lang":"go"},"children":[]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":2,"id":"tutorial-files","__idx":9},"children":["Tutorial files"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["WebSocket client"]}," — ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["github.com/Peersyst/xrpl-go/xrpl/websocket"]},". Always wrap with ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["defer client.Disconnect()"]}," right after ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["NewClient"]}," so the connection closes on any exit path."]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":3,"id":"structure-1","__idx":10},"children":["Structure"]},{"$$mdtype":"Tag","name":"ol","attributes":{},"children":[{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Multi-line ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["// IMPORTANT:"]}," header explaining what the command demonstrates and any preconditions (e.g., \"uses an existing account that has a PRIVATE vault\")"]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["package main"]}," + imports"]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Connect to the network:"]}]},{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"go","header":{"controls":{"copy":{}}},"source":"// Connect to the network ----------------------\nclient := websocket.NewClient(\n\twebsocket.NewClientConfig().\n\t\tWithHost(\"wss://s.devnet.rippletest.net:51233\"),\n)\ndefer client.Disconnect()\n\nif err := client.Connect(); err != nil {\n\tpanic(err)\n}\n","lang":"go"},"children":[]},{"$$mdtype":"Tag","name":"ol","attributes":{"start":4},"children":[{"$$mdtype":"Tag","name":"li","attributes":{},"children":["(Optional) If the tutorial is using setup data:"]}]},{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"go","header":{"controls":{"copy":{}}},"source":"// Check for setup data; run lending-setup if missing\nif _, err := os.Stat(\"lending-setup.json\"); os.IsNotExist(err) {\n\tfmt.Printf(\"\\n=== Lending tutorial data doesn't exist. Running setup script... ===\\n\\n\")\n\tcmd := exec.Command(\"go\", \"run\", \"./lending-setup\")\n\tcmd.Stdout = os.Stdout\n\tcmd.Stderr = os.Stderr\n\tif err := cmd.Run(); err != nil {\n\t\tpanic(err)\n\t}\n}\n\n// Load preconfigured accounts and VaultID\ndata, err := os.ReadFile(\"lending-setup.json\")\nif err != nil {\n\tpanic(err)\n}\nvar setup map[string]any\nif err := json.Unmarshal(data, &setup); err != nil {\n\tpanic(err)\n}\n\n// You can replace these values with your own\nloanBrokerWallet, err := wallet.FromSecret(setup[\"loanBroker\"].(map[string]any)[\"seed\"].(string))\nif err != nil {\n\tpanic(err)\n}\nvaultID := setup[\"vaultID\"].(string)\n","lang":"go"},"children":[]},{"$$mdtype":"Tag","name":"ol","attributes":{"start":5},"children":[{"$$mdtype":"Tag","name":"li","attributes":{},"children":["(Optional) If the tutorial funds its own wallets instead of loading them from setup data, add ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["WithFaucetProvider"]}," to the client config in step 3 and fund wallets after ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["client.Connect()"]},":"]}]},{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"go","header":{"controls":{"copy":{}}},"source":"// In step 3, extend the client config chain:\nclient := websocket.NewClient(\n\twebsocket.NewClientConfig().\n\t\tWithHost(\"wss://s.devnet.rippletest.net:51233\").\n\t\tWithFaucetProvider(faucet.NewDevnetFaucetProvider()),\n)\n\n// After client.Connect():\ntestWallet, err := wallet.New(crypto.ED25519())\nif err != nil {\n\tpanic(err)\n}\nif err := client.FundWallet(&testWallet); err != nil {\n\tpanic(err)\n}\n","lang":"go"},"children":[]},{"$$mdtype":"Tag","name":"ol","attributes":{"start":6},"children":[{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Tutorial code steps."]}]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":3,"id":"tutorial-code-step-guide","__idx":11},"children":["Tutorial code step guide"]},{"$$mdtype":"Tag","name":"ul","attributes":{},"children":[{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Before each major step, add a comment and print a section banner."]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Build transactions as model structs, call ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":[".Flatten()"]},", and print before submitting:",{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"go","header":{"controls":{"copy":{}}},"source":"// Prepare LoanBrokerSet transaction ----------------------\nfmt.Printf(\"\\n=== Preparing LoanBrokerSet transaction ===\\n\\n\")\nmgmtFeeRate := types.InterestRate(1000)\nloanBrokerSetTx := transaction.LoanBrokerSet{\n\tBaseTx: transaction.BaseTx{\n\t\tAccount: loanBrokerWallet.ClassicAddress,\n\t},\n\tVaultID:           vaultID,\n\tManagementFeeRate: &mgmtFeeRate,\n}\n\n// Flatten() converts the struct to a map and adds the TransactionType field\nflatLoanBrokerSetTx := loanBrokerSetTx.Flatten()\nloanBrokerSetTxJSON, _ := json.MarshalIndent(flatLoanBrokerSetTx, \"\", \"  \")\nfmt.Printf(\"%s\\n\", string(loanBrokerSetTxJSON))\n","lang":"go"},"children":[]}]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Submit with ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["SubmitTxAndWait"]}," and handle results by checking for ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["tesSUCCESS"]}," and exiting on failure:",{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"go","header":{"controls":{"copy":{}}},"source":"// Submit, sign, and wait for validation ----------------------\nfmt.Printf(\"\\n=== Submitting LoanBrokerSet transaction ===\\n\\n\")\nloanBrokerSetResponse, err := client.SubmitTxAndWait(flatLoanBrokerSetTx, &wstypes.SubmitOptions{\n\tAutofill: true,\n\tWallet:   &loanBrokerWallet,\n})\nif err != nil {\n\tpanic(err)\n}\n\nif loanBrokerSetResponse.Meta.TransactionResult != \"tesSUCCESS\" {\n\tfmt.Printf(\"Error: Unable to create loan broker: %s\\n\", loanBrokerSetResponse.Meta.TransactionResult)\n\tos.Exit(1)\n}\nfmt.Printf(\"Loan broker created successfully!\\n\")\n","lang":"go"},"children":[]}]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Extract metadata relevant to the tutorial:",{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"go","header":{"controls":{"copy":{}}},"source":"// Extract loan broker information from the transaction result\nfmt.Printf(\"\\n=== Loan Broker Information ===\\n\\n\")\nfor _, node := range loanBrokerSetResponse.Meta.AffectedNodes {\n\tif node.CreatedNode != nil && node.CreatedNode.LedgerEntryType == \"LoanBroker\" {\n\t\tfmt.Printf(\"LoanBroker ID: %s\\n\", node.CreatedNode.LedgerIndex)\n\t\tfmt.Printf(\"LoanBroker Pseudo-Account Address: %s\\n\", node.CreatedNode.NewFields[\"Account\"])\n\t\tbreak\n\t}\n}\n","lang":"go"},"children":[]}]}]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":2,"id":"setup-files","__idx":12},"children":["Setup files"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["RPC client"]}," — ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["github.com/Peersyst/xrpl-go/xrpl/rpc"]}," with a faucet provider. Setup uses RPC, not WebSocket: xrpl-go's WS client is built on ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["gorilla/websocket"]},", which doesn't allow concurrent writes on a single connection."]},{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"go","header":{"controls":{"copy":{}}},"source":"cfg, err := rpc.NewClientConfig(\n\t\"https://s.devnet.rippletest.net:51234\",\n\trpc.WithFaucetProvider(faucet.NewDevnetFaucetProvider()),\n)\nif err != nil {\n\tpanic(err)\n}\nclient := rpc.NewClient(cfg)\n\nsubmitOpts := func(w *wallet.Wallet) *rpctypes.SubmitOptions {\n\treturn &rpctypes.SubmitOptions{Autofill: true, Wallet: w}\n}\n","lang":"go"},"children":[]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["RPC endpoints: Devnet (",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["https://s.devnet.rippletest.net:51234"]},") or Testnet (",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["https://s.altnet.rippletest.net:51234"]},")."]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":3,"id":"speed-first-patterns-when-possible","__idx":13},"children":["Speed-first patterns when possible"]},{"$$mdtype":"Tag","name":"ul","attributes":{},"children":[{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Use goroutines + buffered channels for fan-out parallelism (not ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["errgroup"]}," or ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["sync.WaitGroup"]},")"]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Each goroutine handles one independent task — often a single transaction, sometimes a multi-step pipeline wrapped in a helper closure"]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["When fanning out parallel transactions from the same account, create tickets first via ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["TicketCreate"]}," with ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["TicketCount: N"]},", then set ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["Sequence: 0"]}," and ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["TicketSequence: ..."]}," on the ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["BaseTx"]}," of each parallel tx"]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["xrpl-go doesn't include a fund-and-wait helper, use this:",{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"go","header":{"controls":{"copy":{}}},"source":"// Create and fund wallets concurrently\ncreateAndFund := func(ch chan<- wallet.Wallet) {\n\tw, err := wallet.New(crypto.ED25519())\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\tif err := client.FundWallet(&w); err != nil {\n\t\tpanic(err)\n\t}\n\t// Poll until account is validated on ledger\n\tfunded := false\n\tfor range 20 {\n\t\t_, err := client.Request(&account.InfoRequest{\n\t\t\tAccount:     w.GetAddress(),\n\t\t\tLedgerIndex: common.Validated,\n\t\t})\n\t\tif err == nil {\n\t\t\tfunded = true\n\t\t\tbreak\n\t\t}\n\t\ttime.Sleep(time.Second)\n\t}\n\tif !funded {\n\t\tpanic(\"Issue funding account: \" + w.GetAddress().String())\n\t}\n\tch <- w\n}\n","lang":"go"},"children":[]}]}]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":3,"id":"setup-code-guide","__idx":14},"children":["Setup code guide"]},{"$$mdtype":"Tag","name":"ul","attributes":{},"children":[{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Top comment: single line, ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["// Setup script for <topic> tutorials"]}," above ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["package main"]}]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Only output is a carriage-return progress indicator: ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["fmt.Print(\"Setting up tutorial: N/D\\r\")"]}," between phases, where N is the step number and D is the total steps"]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["No ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["=== Section ==="]}," banners, no transaction dumps — the reader never sees this file's output beyond the progress counter"]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Section comments in code are short: ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["// Section description"]}," (no dash visual)"]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Use ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["panic(err)"]}," on every error path — setup is fail-fast, and a panic surfaces the failing line clearly. Don't silently ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["continue"]}," or ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["_ = err"]},"."]}]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":3,"id":"output-file","__idx":15},"children":["Output file"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["At the end, write all data the tutorials will need. Use an anonymous struct with ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["json:\"camelCase\""]}," tags so field order is preserved:"]},{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"go","header":{"controls":{"copy":{}}},"source":"setupData := struct {\n\tDescription  string `json:\"description\"`\n\tLoanBroker   any    `json:\"loanBroker\"`\n\tDomainID     string `json:\"domainID\"`\n\tMptID        string `json:\"mptID\"`\n\tVaultID      string `json:\"vaultID\"`\n\tLoanBrokerID string `json:\"loanBrokerID\"`\n}{ ... }\n\njsonData, err := json.MarshalIndent(setupData, \"\", \"  \")\nif err != nil {\n\tpanic(err)\n}\nif err := os.WriteFile(\"lending-setup.json\", jsonData, 0644); err != nil {\n\tpanic(err)\n}\n","lang":"go"},"children":[]}]},"headings":[{"value":"XRPL Go Code Sample Conventions","id":"xrpl-go-code-sample-conventions","depth":1},{"value":"Style","id":"style","depth":2},{"value":"Formatting","id":"formatting","depth":3},{"value":"Naming","id":"naming","depth":3},{"value":"Structure","id":"structure","depth":2},{"value":"Folder layout","id":"folder-layout","depth":3},{"value":"README","id":"readme","depth":3},{"value":"go.mod","id":"gomod","depth":3},{"value":"Pointer helper","id":"pointer-helper","depth":3},{"value":"Tutorial files","id":"tutorial-files","depth":2},{"value":"Structure","id":"structure-1","depth":3},{"value":"Tutorial code step guide","id":"tutorial-code-step-guide","depth":3},{"value":"Setup files","id":"setup-files","depth":2},{"value":"Speed-first patterns when possible","id":"speed-first-patterns-when-possible","depth":3},{"value":"Setup code guide","id":"setup-code-guide","depth":3},{"value":"Output file","id":"output-file","depth":3}],"frontmatter":{"paths":["_code-samples/**/*.go"],"seo":{"title":"XRPL Go Code Sample Conventions"}},"editPage":{"to":"https://github.com/XRPLF/xrpl-dev-portal/tree/master/.claude/rules/go-code-samples.md"},"lastModified":"2026-06-05T19:13:01.000Z","pagePropGetterError":{"message":"","name":""}},"slug":"/.claude/rules/go-code-samples","userData":{"isAuthenticated":false,"teams":["anonymous"]},"isPublic":true}