On this pageNavigation ▾

Client API (@caatinga/client)

The @caatinga/client package provides a browser-safe, strongly-typed interface for interacting with deployed Soroban contracts and wallet sessions.

1. Client Initialization

import { createCaatingaClient } from "@caatinga/client";
import type { CaatingaArtifacts } from "@caatinga/core/browser";
import * as Counter from "./contracts/generated/counter";
import artifactsJson from "../caatinga.artifacts.json";

const client = createCaatingaClient({
  network: {
    name: "testnet",
    rpcUrl: "https://soroban-testnet.stellar.org",
    networkPassphrase: "Test SDF Network ; September 2015",
  },
  // JSON imports widen `version` to number; the cast restores the artifacts schema type.
  artifacts: artifactsJson as CaatingaArtifacts,
  wallet: myWalletAdapter, // optional since 3.12.0 — needed only for invoke()
  contracts: {
    counter: {
      binding: Counter,
    },
  },
  walletTimeout: 30_000,
});

2. Invocation Methods

read<T>(method, args?, options?)

Read-only call. Simulates execution and returns the parsed value directly without requiring transaction signing.

As of 3.12.0, read() and simulate() work without a connected wallet. The simulation source account is, in order: the per-call sourceAccount option, the connected wallet’s public key, readSourceAccount from the client config, then DEFAULT_READ_SOURCE_ACCOUNT (exported; the Stellar null account, never sent to RPC).

const count = await client.contract("counter").read<number>("get");

simulate<T>(method, args?, options?)

Simulates execution and returns the raw simulation result payload (including cost, events, and raw XDR).

const sim = await client.contract("counter").simulate<number>("get", { debugRaw: true });

invoke<T>(method, args?, options?)

Signs and submits a state-changing transaction via the connected wallet adapter.

const result = await client.contract("counter").invoke<number>("increment");
// Returns { status, contractId, transactionHash, result? }

buildXdr(method, args?)

Builds and prepares the unsigned/prepared XDR transaction payload without signing or submitting to the network.

const tx = await client.contract("counter").buildXdr("increment");
// Returns { unsignedXdr, preparedXdr }

3. Wallet Session & React Integration

Framework-Agnostic Session

import { createWalletSession } from "@caatinga/client";

const session = createWalletSession(adapter, { persist: true });
session.subscribe(() => render(session.getState()));
await session.connect();
await session.restore(); // Silent reconnect on page load

React Hooks (@caatinga/client/react)

import { WalletProvider, useWallet } from "@caatinga/client/react";
// useWalletSession() returns the underlying session (must be inside WalletProvider).

function App() {
  return (
    <WalletProvider adapter={myWalletAdapter} options={{ persist: true }}>
      <CounterComponent />
    </WalletProvider>
  );
}

function CounterComponent() {
  const { publicKey, connected, connect, disconnect } = useWallet();

  return (
    <div>
      {connected ? (
        <button onClick={disconnect}>Connected: {publicKey}</button>
      ) : (
        <button onClick={connect}>Connect Wallet</button>
      )}
    </div>
  );
}