1"use strict";(globalThis.webpackChunksentinel_docs=globalThis.webpackChunksentinel_docs||[]).push([[2537],{60324(e,n,i){i.r(n),i.d(n,{assets:()=>d,contentTitle:()=>c,default:()=>h,frontMatter:()=>o,metadata:()=>r,toc:()=>l});const r=JSON.parse('{"id":"official-sdks/golang","title":"Golang","description":"The Go SDK is the most complete of the three - it covers the full stack from blockchain client operations down to native VPN tunnel management. Built on Cosmos SDK and CometBFT, it provides everything needed to query chain state, sign transactions, communicate with nodes, and run WireGuard, V2Ray, or OpenVPN tunnels. This is the SDK used by node operators and service builders.","source":"@site/docs/sdk/official-sdks/golang.md","sourceDirName":"official-sdks","slug":"/golang","permalink":"/sdk/golang","draft":false,"unlisted":false,"tags":[],"version":"current","sidebarPosition":1,"frontMatter":{"title":"Golang","sidebar_label":"\ud83d\udd27 Golang","sidebar_position":1,"slug":"/golang"},"sidebar":"tutorialSidebar","previous":{"title":"\ud83d\udcd8 Overview","permalink":"/sdk/"},"next":{"title":"\ud83d\udce6 Javascript","permalink":"/sdk/javascript"}}');var s=i(74848),t=i(28453);const o={title:"Golang",sidebar_label:"\ud83d\udd27 Golang",sidebar_position:1,slug:"/golang"},c="Golang SDK",d={},l=[{value:"Architecture",id:"architecture",level:2},{value:"Installation",id:"installation",level:2},{value:"Client",id:"client",level:2},{value:"Builder Configuration",id:"builder-configuration",level:3},{value:"Configuration from File",id:"configuration-from-file",level:3},{value:"Query",id:"query",level:2},{value:"Querying Nodes",id:"querying-nodes",level:3},{value:"Querying Sessions",id:"querying-sessions",level:3},{value:"Querying Subscriptions",id:"querying-subscriptions",level:3},{value:"Transaction",id:"transaction",level:2},{value:"Broadcasting Transactions",id:"broadcasting-transactions",level:3},{value:"Domain-Specific Helpers",id:"domain-specific-helpers",level:3},{value:"Querying a Transaction",id:"querying-a-transaction",level:3},{value:"Node Communication",id:"node-communication",level:2},{value:"Creating a Node Client",id:"creating-a-node-client",level:3},{value:"Node Information",id:"node-information",level:3},{value:"Handshake",id:"handshake",level:3},{value:"VPN Connection",id:"vpn-connection",level:2},{value:"WireGuard",id:"wireguard",level:3},{value:"V2Ray",id:"v2ray",level:3},{value:"OpenVPN",id:"openvpn",level:3},{value:"Process Management",id:"process-management",level:2},{value:"Libraries",id:"libraries",level:2},{value:"Protobuf",id:"protobuf",level:2}];function a(e){const n={a:"a",admonition:"admonition",code:"code",h1:"h1",h2:"h2",h3:"h3",header:"header",li:"li",p:"p",pre:"pre",strong:"strong",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",ul:"ul",...(0,t.R)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(n.header,{children:(0,s.jsx)(n.h1,{id:"golang-sdk",children:"Golang SDK"})}),"\n",(0,s.jsxs)(n.p,{children:["The Go SDK is the most complete of the three - it covers the full stack from blockchain client operations down to native VPN tunnel management. Built on ",(0,s.jsx)(n.a,{href:"https://docs.cosmos.network/",children:"Cosmos SDK"})," and ",(0,s.jsx)(n.a,{href:"https://docs.cometbft.com/",children:"CometBFT"}),", it provides everything needed to query chain state, sign transactions, communicate with nodes, and run WireGuard, V2Ray, or OpenVPN tunnels. This is the SDK used by node operators and service builders."]}),"\n",(0,s.jsx)(n.p,{children:"You can access the Sentinel Go SDK from:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.a,{href:"https://github.com/sentinel-official/sentinel-go-sdk",children:"GitHub repository"})}),"\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.a,{href:"https://pkg.go.dev/github.com/sentinel-official/sentinel-go-sdk",children:"Go Package Reference"})}),"\n"]}),"\n",(0,s.jsx)(n.admonition,{type:"warning",children:(0,s.jsx)(n.p,{children:"Please note that this SDK is still under development."})}),"\n",(0,s.jsx)(n.h2,{id:"architecture",children:"Architecture"}),"\n",(0,s.jsx)(n.p,{children:"The SDK is organized into the following packages:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.strong,{children:(0,s.jsx)(n.code,{children:"core/"})})," - Blockchain client with query, transaction, and domain-specific operations (node, session, subscription, provider, deposit, auth, bank)"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.strong,{children:(0,s.jsx)(n.code,{children:"node/"})})," - Direct node communication, information retrieval, and cryptographic handshake"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.strong,{children:(0,s.jsx)(n.code,{children:"wireguard/"})})," - WireGuard VPN client and server implementation (platform-specific for Unix/Windows)"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.strong,{children:(0,s.jsx)(n.code,{children:"v2ray/"})})," - V2Ray proxy client and server implementation"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.strong,{children:(0,s.jsx)(n.code,{children:"openvpn/"})})," - OpenVPN server implementation with peer management"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.strong,{children:(0,s.jsx)(n.code,{children:"process/"})})," - Process lifecycle management with state machine"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.strong,{children:(0,s.jsx)(n.code,{children:"types/"})})," - Core type definitions, service interfaces, and API structures"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.strong,{children:(0,s.jsx)(n.code,{children:"utils/"})})," - Utility functions for crypto, addresses, events, templates, and encoding"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.strong,{children:(0,s.jsx)(n.code,{children:"libs/"})})," - Standalone library packages (cron, crypto, encoding, geoip, logging, speedtest, and more)"]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"installation",children:"Installation"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"go get github.com/sentinel-official/sentinel-go-sdk\n"})}),"\n",(0,s.jsx)(n.h2,{id:"client",children:"Client"}),"\n",(0,s.jsxs)(n.p,{children:["The ",(0,s.jsx)(n.code,{children:"core"})," package provides the main blockchain client. It uses a builder pattern for configuration, allowing you to chain method calls to set up the client."]}),"\n",(0,s.jsx)(n.h3,{id:"builder-configuration",children:"Builder Configuration"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-go",children:'import (\n "github.com/sentinel-official/sentinel-go-sdk/core"\n)\n\nclient := core.NewClient().\n WithRPCAddr("https://rpc.sentinel.co:443").\n WithRPCChainID("sentinelhub-2").\n WithTxFromName("my-key").\n WithTxGasAdjustment(1.15).\n WithTxFees("100000udvpn").\n WithKeyring(keyring)\n\nclient.Seal() // Prevent further modifications\n'})}),"\n",(0,s.jsx)(n.p,{children:"The full set of builder methods includes:"}),"\n",(0,s.jsxs)(n.table,{children:[(0,s.jsx)(n.thead,{children:(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.th,{children:"Method"}),(0,s.jsx)(n.th,{children:"Description"})]})}),(0,s.jsxs)(n.tbody,{children:[(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"WithRPCAddr"})}),(0,s.jsx)(n.td,{children:"RPC endpoint address"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"WithRPCChainID"})}),(0,s.jsx)(n.td,{children:"Chain identifier"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"WithRPCHeaders"})}),(0,s.jsx)(n.td,{children:"Custom RPC headers"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"WithRPCTimeout"})}),(0,s.jsx)(n.td,{children:"RPC request timeout"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"WithTxFromName"})}),(0,s.jsx)(n.td,{children:"Signing key name"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"WithTxGas"})}),(0,s.jsx)(n.td,{children:"Gas limit"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"WithTxGasAdjustment"})}),(0,s.jsx)(n.td,{children:"Gas estimation multiplier"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"WithTxFees"})}),(0,s.jsx)(n.td,{children:"Transaction fees"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"WithTxMemo"})}),(0,s.jsx)(n.td,{children:"Transaction memo"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"WithTxBroadcastRetryAttempts"})}),(0,s.jsx)(n.td,{children:"Number of broadcast retries"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"WithTxAuthzGranterAddr"})}),(0,s.jsx)(n.td,{children:"Authz granter address"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"WithKeyring"})}),(0,s.jsx)(n.td,{children:"Keyring for signing"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"WithProtoCodec"})}),(0,s.jsx)(n.td,{children:"Protocol buffer codec"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"WithQueryProve"})}),(0,s.jsx)(n.td,{children:"Enable query proofs"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"WithQueryRetryAttempts"})}),(0,s.jsx)(n.td,{children:"Number of query retries"})]})]})]}),"\n",(0,s.jsx)(n.h3,{id:"configuration-from-file",children:"Configuration from File"}),"\n",(0,s.jsxs)(n.p,{children:["Alternatively, you can create a client from a structured configuration object using the ",(0,s.jsx)(n.code,{children:"core/config"})," sub-package:"]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-go",children:'import (\n "github.com/sentinel-official/sentinel-go-sdk/core"\n "github.com/sentinel-official/sentinel-go-sdk/core/config"\n)\n\ncfg := config.DefaultConfig()\n\n// Customize as needed\n// cfg.RPC, cfg.Tx, cfg.Keyring, cfg.Query are sub-configs\n\nif err := cfg.Validate(); err != nil {\n log.Fatal(err)\n}\n\nclient, err := core.NewClientFromConfig(cfg)\nif err != nil {\n log.Fatal(err)\n}\n'})}),"\n",(0,s.jsxs)(n.p,{children:["The ",(0,s.jsx)(n.code,{children:"Config"})," struct is composed of four sub-configurations:"]}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.strong,{children:(0,s.jsx)(n.code,{children:"KeyringConfig"})})," - Key management backend and settings"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.strong,{children:(0,s.jsx)(n.code,{children:"QueryConfig"})})," - Query parameters and retry behavior"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.strong,{children:(0,s.jsx)(n.code,{children:"RPCConfig"})})," - RPC connection settings (addresses, chain ID, timeout)"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.strong,{children:(0,s.jsx)(n.code,{children:"TxConfig"})})," - Transaction parameters (gas, fees, from name, retry logic)"]}),"\n"]}),"\n",(0,s.jsxs)(n.p,{children:["Each sub-config has its own ",(0,s.jsx)(n.code,{children:"SetForFlags(*pflag.FlagSet)"})," method for CLI integration with Cobra."]}),"\n",(0,s.jsx)(n.h2,{id:"query",children:"Query"}),"\n",(0,s.jsxs)(n.p,{children:["The SDK supports querying blockchain state through gRPC. Available query domains include ",(0,s.jsx)(n.strong,{children:"node"}),", ",(0,s.jsx)(n.strong,{children:"session"}),", ",(0,s.jsx)(n.strong,{children:"subscription"}),", ",(0,s.jsx)(n.strong,{children:"provider"}),", ",(0,s.jsx)(n.strong,{children:"deposit"}),", ",(0,s.jsx)(n.strong,{children:"auth"}),", ",(0,s.jsx)(n.strong,{children:"bank"}),", and ",(0,s.jsx)(n.strong,{children:"block"}),"."]}),"\n",(0,s.jsx)(n.h3,{id:"querying-nodes",children:"Querying Nodes"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-go",children:'import (\n "context"\n\n v1 "github.com/sentinel-official/sentinelhub/v12/types/v1"\n "github.com/cosmos/cosmos-sdk/types/query"\n)\n\n// Query active nodes with pagination\nnodes, pageRes, err := client.Nodes(\n context.Backgroun
1d(),\n v1.StatusActive,\n &query.PageRequest{\n Limit: 10,\n CountTotal: true,\n },\n)\nif err != nil {\n log.Fatal(err)\n}\n\nfmt.Printf("Found %d nodes (total: %d)\\n", len(nodes), pageRes.Total)\n\n// Query a specific node by address\nnode, err := client.Node(context.Background(), nodeAddr)\n\n// Query nodes for a specific plan\nnodes, pageRes, err := client.NodesForPlan(context.Background(), planID, v1.StatusActive, pageReq)\n\n// Query node module parameters\nparams, err := client.NodeParams(context.Background())\n'})}),"\n",(0,s.jsx)(n.h3,{id:"querying-sessions",children:"Querying Sessions"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-go",children:"// All sessions for an account\nsessions, pageRes, err := client.SessionsForAccount(context.Background(), accAddr, pageReq)\n\n// Sessions for a specific node\nsessions, pageRes, err := client.SessionsForNode(context.Background(), nodeAddr, pageReq)\n\n// Sessions for a subscription\nsessions, pageRes, err := client.SessionsForSubscription(context.Background(), subscriptionID, pageReq)\n\n// A single session by ID\nsession, err := client.Session(context.Background(), sessionID)\n"})}),"\n",(0,s.jsx)(n.h3,{id:"querying-subscriptions",children:"Querying Subscriptions"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-go",children:"// All subscriptions for an account\nsubs, pageRes, err := client.SubscriptionsForAccount(context.Background(), accAddr, pageReq)\n\n// Subscriptions for a plan\nsubs, pageRes, err := client.SubscriptionsForPlan(context.Background(), planID, pageReq)\n\n// Subscription allocation\nalloc, err := client.SubscriptionAllocation(context.Background(), subscriptionID, accAddr)\n"})}),"\n",(0,s.jsx)(n.p,{children:"For pagination guidance, refer to:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.a,{href:"https://docs.cosmos.network/v0.45/core/proto-docs.html#cosmos-base-query-v1beta1-pagination-proto",children:"https://docs.cosmos.network/v0.45/core/proto-docs.html#cosmos-base-query-v1beta1-pagination-proto"})}),"\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.a,{href:"https://github.com/cosmos/cosmos-sdk/blob/main/types/query/pagination.pb.go#L32-L53",children:"https://github.com/cosmos/cosmos-sdk/blob/main/types/query/pagination.pb.go#L32-L53"})}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"transaction",children:"Transaction"}),"\n",(0,s.jsx)(n.p,{children:"Once you've configured a client with signing capabilities, you can build, sign, and broadcast transactions. The SDK handles fee calculation, gas estimation, and automatic retry logic for deadline exceeded and sequence mismatch errors."}),"\n",(0,s.jsx)(n.h3,{id:"broadcasting-transactions",children:"Broadcasting Transactions"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-go",children:'import (\n "context"\n\n cosmossdk "github.com/cosmos/cosmos-sdk/types"\n)\n\n// Broadcast and return immediately (synchronous broadcast, async confirmation)\nresult, err := client.BroadcastTxSync(context.Background(), msg1, msg2)\nif err != nil {\n log.Fatal(err)\n}\nfmt.Printf("Tx Hash: %s\\n", result.Hash)\n\n// Broadcast and wait for block inclusion\nbroadcastRes, txRes, err := client.BroadcastTxCommit(context.Background(), msg)\nif err != nil {\n log.Fatal(err)\n}\nfmt.Printf("Tx Hash: %s, Height: %d\\n", txRes.Hash, txRes.Height)\n'})}),"\n",(0,s.jsx)(n.h3,{id:"domain-specific-helpers",children:"Domain-Specific Helpers"}),"\n",(0,s.jsx)(n.p,{children:"The SDK provides convenience methods that construct the message, broadcast, and parse the result in a single call:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-go",children:'// Start a session on a node - returns the new session ID\nsessionID, err := client.NodeStartSession(\n context.Background(),\n nodeAddr, // target node address\n 10, // gigabytes\n 24, // hours\n maxPrice, // maximum acceptable price\n)\nif err != nil {\n log.Fatal(err)\n}\nfmt.Printf("Session ID: %d\\n", sessionID)\n\n// Start a session from an existing subscription\nsessionID, err := client.SubscriptionStartSession(\n context.Backgroun
1d(),\n subscriptionID,\n nodeAddr,\n)\n'})}),"\n",(0,s.jsx)(n.h3,{id:"querying-a-transaction",children:"Querying a Transaction"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-go",children:"// Retrieve a transaction by hash\ntxResult, err := client.Tx(context.Background(), txHash)\n"})}),"\n",(0,s.jsx)(n.h2,{id:"node-communication",children:"Node Communication"}),"\n",(0,s.jsxs)(n.p,{children:["The ",(0,s.jsx)(n.code,{children:"node"})," package handles direct communication with Sentinel nodes outside of blockchain transactions. The node client embeds the core blockchain client and adds node-specific configuration."]}),"\n",(0,s.jsx)(n.h3,{id:"creating-a-node-client",children:"Creating a Node Client"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-go",children:'import (\n "time"\n\n "github.com/sentinel-official/sentinel-go-sdk/node"\n)\n\nnodeClient := node.NewClient(coreClient).\n WithAddr(nodeAddr).\n WithFromName("my-key").\n WithInsecure(false).\n WithTimeout(10 * time.Second)\n'})}),"\n",(0,s.jsx)(n.p,{children:"Or from configuration:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-go",children:"nodeClient, err := node.NewClientFromConfig(cfg)\nif err != nil {\n log.Fatal(err)\n}\n"})}),"\n",(0,s.jsx)(n.h3,{id:"node-information",children:"Node Information"}),"\n",(0,s.jsx)(n.p,{children:"Retrieve metadata about a node, including its address, capacity, location, peer count, service type, and version:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-go",children:'info, err := nodeClient.GetInfo()\nif err != nil {\n log.Fatal(err)\n}\n\nfmt.Printf("Service Type: %s\\n", info.GetServiceType())\n'})}),"\n",(0,s.jsx)(n.h3,{id:"handshake",children:"Handshake"}),"\n",(0,s.jsx)(n.p,{children:"After starting a session on-chain, perform a cryptographic handshake with the node to establish a VPN connection. The handshake uses asymmetric signatures to verify identity:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-go",children:'// Prepare session data (e.g., WireGuard public key or V2Ray UUID)\ndata := []byte(`{"public_key": "..."}`)\n\nresult, err := nodeClient.InitHandshake(context.Background(), sessionID, data)\nif err != nil {\n log.Fatal(err)\n}\n\n// result.Addrs contains the node\'s network addresses\n// result.Data contains protocol-specific handshake response\n'})}),"\n",(0,s.jsx)(n.h2,{id:"vpn-connection",children:"VPN Connection"}),"\n",(0,s.jsxs)(n.p,{children:["The SDK includes built-in support for three VPN protocols: ",(0,s.jsx)(n.strong,{children:"WireGuard"}),", ",(0,s.jsx)(n.strong,{children:"V2Ray"}),", and ",(0,s.jsx)(n.strong,{children:"OpenVPN"}),". All VPN clients implement the ",(0,s.jsx)(n.code,{children:"ClientService"})," interface, providing a consistent lifecycle API:"]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-go",children:"type ClientService interface {\n Type() ServiceType\n IsRunning() (bool, error)\n Init(force bool) error\n Setup(ctx context.Context) error\n Start(parent context.Context) (context.Context, error)\n Stop() error\n Wait(ctx context.Context) error\n Cleanup() error\n Statistics(ctx context.Context) (int64, int64, error)\n}\n"})}),"\n",(0,s.jsx)(n.p,{children:"Service types are defined as constants:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-go",children:'types.ServiceTypeWireGuard // "wireguard"\ntypes.ServiceTypeV2Ray // "v2ray"\ntypes.ServiceTypeOpenVPN // "openvpn"\n'})}),"\n",(0,s.jsx)(n.h3,{id:"wireguard",children:"WireGuard"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-go",children:'import (\n "github.com/sentinel-official/sentinel-go-sdk/wireguard"\n)\n\nwgClient := wireguard.NewClient("wg-client", appDir, wgConfig).\n WithDevice("wg0")\n\n// Initialize configuration files\nif err := wgClient.Init(false); err != nil {\n log.Fatal(err)\n}\n\n// Set up the interface\nif err := wgClient.Setup(ctx); err != nil {\n log.Fatal(err)\n}\n\n// Start the VPN tunnel\nctx, err := wgClient.Start(context.Backgroun
1d())\nif err != nil {\n log.Fatal(err)\n}\n\n// Get traffic statistics (rxBytes, txBytes)\nrx, tx, err := wgClient.Statistics(ctx)\nfmt.Printf("RX: %d bytes, TX: %d bytes\\n", rx, tx)\n\n// Stop and clean up\nwgClient.Stop()\nwgClient.Cleanup()\n'})}),"\n",(0,s.jsx)(n.h3,{id:"v2ray",children:"V2Ray"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-go",children:'import (\n "github.com/sentinel-official/sentinel-go-sdk/v2ray"\n)\n\nv2rayClient := v2ray.NewClient("v2ray-client", appDir, v2rayConfig)\n\nif err := v2rayClient.Init(false); err != nil {\n log.Fatal(err)\n}\n\nif err := v2rayClient.Setup(ctx); err != nil {\n log.Fatal(err)\n}\n\nctx, err := v2rayClient.Start(context.Background())\nif err != nil {\n log.Fatal(err)\n}\n\n// Same lifecycle: Stop(), Wait(), Cleanup(), Statistics()\n'})}),"\n",(0,s.jsx)(n.h3,{id:"openvpn",children:"OpenVPN"}),"\n",(0,s.jsxs)(n.p,{children:["The OpenVPN package provides a ",(0,s.jsx)(n.strong,{children:"server-side"})," implementation with peer management, implementing the ",(0,s.jsx)(n.code,{children:"ServerService"})," interface:"]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-go",children:"type ServerService interface {\n BaseService\n AddPeer(ctx context.Context, req any) (id string, res any, err error)\n HasPeer(ctx context.Context, id string) (bool, error)\n RemovePeer(ctx context.Context, id string) error\n PeersLen() int\n PeerStatistics() (map[string]*PeerStatistics, error)\n}\n"})}),"\n",(0,s.jsx)(n.h2,{id:"process-management",children:"Process Management"}),"\n",(0,s.jsxs)(n.p,{children:["The ",(0,s.jsx)(n.code,{children:"process"})," package provides a state machine for managing long-running VPN service lifecycles. It is used internally by the WireGuard, V2Ray, and OpenVPN packages."]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-go",children:'import (\n "github.com/sentinel-official/sentinel-go-sdk/process"\n)\n\nmanager := process.NewManager("my-service")\n'})}),"\n",(0,s.jsx)(n.p,{children:"The manager enforces strict state transitions:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:"Unspecified \u2192 Starting \u2192 Started \u2192 Stopping \u2192 Stopped \u2192 Unspecified\n \u2193 \u2193\n StartError StopError\n"})}),"\n",(0,s.jsxs)(n.p,{children:["Key methods: ",(0,s.jsx)(n.code,{children:"Start"}),", ",(0,s.jsx)(n.code,{children:"Stop"}),", ",(0,s.jsx)(n.code,{children:"Wait"}),", ",(0,s.jsx)(n.code,{children:"Cleanup"}),", ",(0,s.jsx)(n.code,{children:"Reset"}),", ",(0,s.jsx)(n.code,{children:"IsRunning"}),", and ",(0,s.jsx)(n.code,{children:"Go"})," (for launching goroutines within the process context)."]}),"\n",(0,s.jsx)(n.h2,{id:"libraries",children:"Libraries"}),"\n",(0,s.jsxs)(n.p,{children:["The ",(0,s.jsx)(n.code,{children:"libs/"})," directory contains standalone utility packages:"]}),"\n",(0,s.jsxs)(n.table,{children:[(0,s.jsx)(n.thead,{children:(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.th,{children:"Package"}),(0,s.jsx)(n.th,{children:"Description"})]})}),(0,s.jsxs)(n.tbody,{children:[(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"libs/cmux"})}),(0,s.jsx)(n.td,{children:"Connection multiplexing"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"libs/cron"})}),(0,s.jsx)(n.td,{children:"Scheduled task execution"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"libs/crypto"})}),(0,s.jsx)(n.td,{children:"Cryptographic utilities"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"libs/encoding"})}),(0,s.jsx)(n.td,{children:"Data encoding/decoding"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"libs/geoip"})}),(0,s.jsx)(n.td,{children:"Geographic IP lookup"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"libs/gin"})}),(0,s.jsx)(n.td,{children:"Gin web framework extensions"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"libs/log"})}),(0,s.jsx)(n.td,{children:"Structured logging (zerolog)"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"libs/netip"})}),(0,s.jsx)(n.td,{children:"Network/IP utilities"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"libs/oracle"})}),(0,s.jsx)(n.td,{children:"Price oracle integration"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"libs/safe"})}),(0,s.jsx)(n.td,{children:"Safe concurrent operations"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"libs/speedtest"})}),(0,s.jsx)(n.td,{children:"Network speed testing"})]})]})]}),"\n",(0,s.jsx)(n.h2,{id:"protobuf",children:"Protobuf"}),"\n",(0,s.jsxs)(n.p,{children:["The SDK uses Protocol Buffers for all blockchain message types, built on the ",(0,s.jsx)(n.a,{href:"https://github.com/sentinel-official/sentinelhub",children:"Sentinel Hub"})," proto definitions (",(0,s.jsx)(n.code,{children:"sentinelhub/v12"}),"). Proto types are compiled with the standard Go protobuf toolchain (",(0,s.jsx)(n.code,{children:"protoc"})," with ",(0,s.jsx)(n.code,{children:"gogoproto"}),"). The generated types are used throughout the ",(0,s.jsx)(n.code,{children:"core/"})," and ",(0,s.jsx)(n.code,{children:"types/"})," packages for queries and transactions."]})]})}function h(e={}){const{wrapper:n}={...(0,t.R)(),...e.components};return n?(0,s.jsx)(n,{...e,children:(0,s.jsx)(a,{...e})}):a(e)}},28453(e,n,i){i.d(n,{R:()=>o,x:()=>c});var r=i(96540);const s={},t=r.createContext(s);function o(e){const n=r.useContext(t);return r.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function c(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(s):e.components||s:o(e.components),r.createElement(t.Provider,{value:n},e.children)}}}]);
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.