Configuration

Full configuration reference for @ottocode/ai-sdk.

createSetu Options

const setu = createSetu({
  // Auth: private key (default) or external signer
  auth: { privateKey: "..." },
  // OR use an external signer:
  // auth: {
  //   signer: {
  //     walletAddress: "...",
  //     signNonce: async (nonce) => "...",
  //     signTransaction: async (tx) => signedTx, // raw bytes callback
  //   },
  // },

  // Optional: Setu API base URL (default: https://api.setu.ottocode.io)
  baseURL: "https://api.setu.ottocode.io",

  // Optional: Solana RPC URL (default: https://api.mainnet-beta.solana.com)
  rpcURL: "https://api.mainnet-beta.solana.com",

  // Optional: Payment callbacks (see below)
  callbacks: { /* ... */ },

  // Optional: Cache configuration (see Caching docs)
  cache: { /* ... */ },

  // Optional: Payment options (see below)
  payment: { /* ... */ },

  // Optional: Custom model→provider mappings
  modelMap: { "my-custom-model": "openai" },

  // Optional: Register custom providers
  providers: [
    { id: "my-provider", apiFormat: "openai-chat", modelPrefix: "myp-" },
  ],
});

Payment Options

const setu = createSetu({
  auth: { privateKey: "..." },
  payment: {
    // "auto" (default) — pay automatically
    // "approval" — call onPaymentApproval before each payment
    topupApprovalMode: "auto",

    // Auto-pay without approval if wallet USDC balance >= threshold
    autoPayThresholdUsd: 5.0,

    // Max retries for a single API request (default: 3)
    maxRequestAttempts: 3,

    // Max total payment attempts per wallet (default: 20)
    maxPaymentAttempts: 20,
  },
});

Payment Callbacks

Monitor and control the payment lifecycle:

const setu = createSetu({
  auth: { privateKey: "..." },
  callbacks: {
    onPaymentRequired: (amountUsd, currentBalance) => {
      console.log(`Payment required: $${amountUsd}`);
    },
    onPaymentSigning: () => {
      console.log("Signing payment...");
    },
    onPaymentComplete: ({ amountUsd, newBalance, transactionId }) => {
      console.log(`Paid $${amountUsd}, balance: $${newBalance}`);
    },
    onPaymentError: (error) => {
      console.error("Payment failed:", error);
    },
    onBalanceUpdate: ({ costUsd, balanceRemaining, inputTokens, outputTokens }) => {
      console.log(`Cost: $${costUsd}, remaining: $${balanceRemaining}`);
    },
    onPaymentApproval: async ({ amountUsd, currentBalance }) => {
      // return "crypto" to pay, "fiat" for fiat flow, "cancel" to abort
      return "crypto";
    },
  },
});
CallbackWhen
onPaymentRequired(amountUsd, currentBalance)402 received, payment about to start
onPaymentSigning()Building and signing the USDC transaction
onPaymentComplete({ amountUsd, newBalance, transactionId })Payment settled successfully
onPaymentError(error)Payment failed
onPaymentApproval({ amountUsd, currentBalance })Approval mode: asks user to approve/cancel/choose fiat
onBalanceUpdate({ costUsd, balanceRemaining })After each request with cost info (streaming & non-streaming)

Extended Thinking (Anthropic)

const { text } = await generateText({
  model: setu.model("claude-sonnet-4-20250514"),
  prompt: "Solve this complex math problem...",
  providerOptions: {
    anthropic: {
      thinking: { type: "enabled", budgetTokens: 16000 },
    },
  },
});

Environment Variables

VariableRequiredDescription
SETU_PRIVATE_KEYYes*Base58-encoded Solana private key (* not required when using external signer)
SETU_BASE_URLNoOverride API URL (default: https://api.setu.ottocode.io)
SETU_SOLANA_RPC_URLNoCustom Solana RPC (default: https://api.mainnet-beta.solana.com)

Using with otto

otto has built-in Setu support via the AI SDK:

# Login with Setu (generates or imports a Solana wallet)
otto auth login setu

# Or set the private key directly
export SETU_PRIVATE_KEY="your-base58-private-key"

# Use Setu as default provider
otto setup  # select "setu"

# Or per-request
otto ask "hello" --provider setu --model claude-sonnet-4-20250514