| name | ark-sdk-client-init |
| description | SDK client initialization and configuration - client types, wallet types, stores, and connection setup |
SDK Client Initialization for Ark
When to Use
Use this skill when:
- Setting up a new Ark client (ArkClient)
- Configuring wallet types (SingleKey)
- Choosing transport types (gRPC, REST)
- Setting up storage backends (File, InMemory, KV, SQL)
- Managing wallet lifecycle (init, lock, unlock)
- Connecting to an Ark server (arkd)
Key Concepts
1. ArkClient Interface
The main entry point for all SDK operations:
type ArkClient interface {
Init(ctx context.Context, args InitArgs) error
InitWithWallet(ctx context.Context, args InitWithWalletArgs) error
IsLocked(ctx context.Context) bool
Unlock(ctx context.Context, password string) error
Lock(ctx context.Context) error
Balance(ctx context.Context) (*Balance, error)
Receive(ctx context.Context) (onchainAddr, offchainAddr, boardingAddr string, err error)
SendOffChain(ctx context.Context, receivers []types.Receiver, opt ...Option) (string, error)
Settle(ctx context.Context, opts ...Option) (string, error)
CollaborativeExit(ctx context.Context, addr string, amount uint64, opts ...Option) (string, error)
}
2. Client Types
| Type | Constant | Use Case |
|---|
| gRPC | GrpcClient | Recommended, better performance, streaming |
| REST | RestClient | Simpler, HTTP-based, easier debugging |
3. Wallet Types
| Type | Constant | Description |
|---|
| SingleKey | SingleKeyWallet | Single private key for all operations |
4. Store Types
| Type | Constant | Description |
|---|
| InMemory | InMemoryStore | Ephemeral, lost on restart |
| File | FileStore | Persistent, file-based storage |
| KV | KVStore | Key-value database |
| SQL | SQLStore | SQL database backend |
Code Patterns
Pattern 1: InitArgs Structure
type InitArgs struct {
ClientType string
WalletType string
ServerUrl string
Seed string
Password string
ExplorerURL string
ExplorerPollInterval time.Duration
WithTransactionFeed bool
}
Source: go-sdk/types.go:24-33
Pattern 2: InitWithWalletArgs Structure
type InitWithWalletArgs struct {
ClientType string
Wallet wallet.WalletService
ServerUrl string
Seed string
Password string
ExplorerURL string
ExplorerPollInterval time.Duration
ExplorerBatchSize uint32
ExplorerBatchDelay time.Duration
WithTransactionFeed bool
}
Source: go-sdk/types.go:66-77
Pattern 3: Creating a New Client with File Store
import (
arksdk "github.com/arkade-os/go-sdk"
filestore "github.com/arkade-os/go-sdk/store/file"
)
func createClient(datadir string) (arksdk.ArkClient, error) {
store, err := filestore.NewStore(datadir)
if err != nil {
return nil, err
}
client, err := arksdk.New(store)
if err != nil {
return nil, err
}
return client, nil
}
Pattern 4: Initializing the Client
func initClient(client arksdk.ArkClient, serverUrl, password string) error {
ctx := context.Background()
cfg, _ := client.GetConfigData(ctx)
if cfg != nil {
return arksdk.ErrAlreadyInitialized
}
err := client.Init(ctx, arksdk.InitArgs{
ClientType: arksdk.GrpcClient,
WalletType: arksdk.SingleKeyWallet,
ServerUrl: serverUrl,
Password: password,
WithTransactionFeed: true,
})
if err != nil {
return err
}
return client.Unlock(ctx, password)
}
Pattern 5: Restoring from Seed
func restoreFromSeed(client arksdk.ArkClient, serverUrl, password, seed string) error {
ctx := context.Background()
err := client.Init(ctx, arksdk.InitArgs{
ClientType: arksdk.GrpcClient,
WalletType: arksdk.SingleKeyWallet,
ServerUrl: serverUrl,
Password: password,
Seed: seed,
WithTransactionFeed: true,
})
if err != nil {
return err
}
return client.Unlock(ctx, password)
}
Pattern 6: Available Constants
const (
GrpcClient = client.GrpcClient
RestClient = client.RestClient
SingleKeyWallet = wallet.SingleKeyWallet
FileStore = types.FileStore
InMemoryStore = types.InMemoryStore
BitcoinExplorer = mempool_explorer.BitcoinExplorer
)
Source: go-sdk/base_client.go:28-39
Pattern 7: Client Options
type ClientOption func(*arkClient)
func WithVerbose() ClientOption
func WithRefreshDb(interval time.Duration) ClientOption
func WithoutFinalizePendingTxs() ClientOption
Source: go-sdk/base_client.go:46-67
Pattern 8: Creating Client with Options
store, _ := filestore.NewStore(datadir)
client, _ := arksdk.New(store,
arksdk.WithVerbose(),
arksdk.WithRefreshDb(30*time.Second),
)
Pattern 9: Wallet Lock/Unlock Flow
func manageWallet(client arksdk.ArkClient, password string) error {
ctx := context.Background()
if client.IsLocked(ctx) {
if err := client.Unlock(ctx, password); err != nil {
return err
}
}
syncCh := client.IsSynced(ctx)
if syncCh != nil {
event := <-syncCh
if event.Err != nil {
return event.Err
}
}
return client.Lock(ctx)
}
Source: go-sdk/base_client.go:106-203
Pattern 10: Getting Config After Init
func checkConfig(client arksdk.ArkClient) error {
ctx := context.Background()
cfg, err := client.GetConfigData(ctx)
if err != nil {
return err
}
fmt.Printf("Server: %s\n", cfg.ServerUrl)
fmt.Printf("Network: %s\n", cfg.Network.Name)
fmt.Printf("Signer PubKey: %x\n", cfg.SignerPubKey.SerializeCompressed())
fmt.Printf("Exit Delay: %d blocks\n", cfg.UnilateralExitDelay.Value)
fmt.Printf("Dust: %d sats\n", cfg.Dust)
return nil
}
Source: go-sdk/base_client.go:99-104
Pattern 11: Transaction Feed Channels
func subscribeToEvents(client arksdk.ArkClient) {
ctx := context.Background()
vtxoCh := client.GetVtxoEventChannel(ctx)
go func() {
for event := range vtxoCh {
switch event.Type {
case types.VtxosAdded:
fmt.Println("New VTXOs received")
case types.VtxosSpent:
fmt.Println("VTXOs spent")
case types.VtxosUpdated:
fmt.Println("VTXOs updated")
}
}
}()
utxoCh := client.GetUtxoEventChannel(ctx)
go func() {
for event := range utxoCh {
}
}()
txCh := client.GetTransactionEventChannel(ctx)
go func() {
for event := range txCh {
}
}()
}
Source: go-sdk/base_client.go:279-304
Pattern 12: Cleanup and Stop
func cleanup(client arksdk.ArkClient) {
ctx := context.Background()
client.Reset(ctx)
client.Stop()
}
Source: go-sdk/base_client.go:313-358
File References
| Purpose | File | Key Types/Functions |
|---|
| Client interface | go-sdk/ark_sdk.go | ArkClient interface |
| Client implementation | go-sdk/base_client.go | arkClient, Init, Unlock, Lock |
| Init args | go-sdk/types.go | InitArgs, InitWithWalletArgs, Balance |
| SDK types | go-sdk/types/types.go | Config, Vtxo, Utxo, Receiver |
| Wallet interface | go-sdk/wallet/wallet.go | WalletService |
| SingleKey wallet | go-sdk/wallet/singlekey/bitcoin_wallet.go | bitcoinWallet |
| File store | go-sdk/store/file/store.go | NewStore |
| gRPC client | go-sdk/client/grpc/client.go | NewClient |
| REST client | go-sdk/client/rest/client.go | NewClient |
Common Operations
Operation 1: Full Initialization Flow
store, _ := filestore.NewStore("~/.ark-wallet")
client, _ := arksdk.New(store, arksdk.WithVerbose())
client.Init(ctx, arksdk.InitArgs{
ClientType: arksdk.GrpcClient,
WalletType: arksdk.SingleKeyWallet,
ServerUrl: "localhost:7070",
Password: "secure-password",
WithTransactionFeed: true,
})
client.Unlock(ctx, "secure-password")
<-client.IsSynced(ctx)
balance, _ := client.Balance(ctx)
Operation 2: Check and Resume Existing Wallet
cfg, err := client.GetConfigData(ctx)
if err != nil {
return client.Init(ctx, args)
}
if client.IsLocked(ctx) {
return client.Unlock(ctx, password)
}
return nil
Operation 3: Export Wallet Seed
if !client.IsLocked(ctx) {
seed, err := client.Dump(ctx)
if err != nil {
return err
}
fmt.Printf("Backup your seed: %s\n", seed)
}
Balance Structure
type Balance struct {
OnchainBalance OnchainBalance
OffchainBalance OffchainBalance
}
type OnchainBalance struct {
SpendableAmount uint64
LockedAmount []LockedOnchainBalance
}
type OffchainBalance struct {
Total uint64
NextExpiration string
Details []VtxoDetails
}
Source: go-sdk/types.go:100-124
Gotchas & Edge Cases
-
Always Unlock After Init: The wallet is locked after Init(). You must call Unlock() before using other methods.
-
Wait for Sync: If WithTransactionFeed: true, wait for IsSynced() before querying balance. Otherwise you get stale data.
-
Password Required: Password cannot be empty. It's used to encrypt the wallet data.
-
Server Info: Client fetches server info (signer key, fees, delays) during Init(). Changing server requires re-init.
-
Store Persistence: InMemoryStore loses all data on restart. Use FileStore for production.
-
Transaction Feed: Without WithTransactionFeed, balance queries hit the server each time (slower but no background sync).
-
Reset vs Stop: Reset() cleans data, Stop() preserves it. Use Reset() for fresh start, Stop() for temporary shutdown.
-
Seed Format: Seed is hex-encoded private key (64 chars). Don't confuse with BIP39 mnemonic.
-
Lock Before Exit: Always call Lock() or Stop() before exiting to ensure clean shutdown.
-
Multiple Clients: Don't create multiple clients with same datadir - they'll conflict. Use single instance.
Skill Owner: ark-developer
Repos: go-sdk