Authentication & Wallet Setup
Keypairs, wallet adapters, and the Invoker type used for signing.
Every composable API function takes an invoker as its second argument. The invoker is the signer - it authorizes stream creation and lifecycle operations.
The Invoker type
type Invoker = Keypair | SignerWalletAdapter | { publicKey: PublicKey };The SDK accepts any of these three shapes and normalizes the invoker internally before signing.
Creating an invoker
Backend (Node.js) - Keypair
import { Keypair } from "@solana/web3.js";
import fs from "node:fs";
const secret = JSON.parse(fs.readFileSync(process.env.KEYPAIR_PATH!, "utf-8"));
const invoker = Keypair.fromSecretKey(Uint8Array.from(secret));import { Keypair } from "@solana/web3.js";
const secret = JSON.parse(process.env.KEYPAIR_JSON!);
const invoker = Keypair.fromSecretKey(Uint8Array.from(secret));Never commit private keys or keypair files. Use environment variables or a secrets manager in production.
Frontend (browser) - Wallet adapter
import { useWallet } from "@solana/wallet-adapter-react";
const { wallet } = useWallet();
const invoker = wallet?.adapter; // SignerWalletAdapterPass the adapter directly as the invoker. The sign() function will call adapter.signTransaction() when executing.
Signature in sign()
import { sign } from "@streamflow/stream/solana/api";
// With a Keypair (backend):
await sign(built.transaction, [invoker, ...(result.signers ?? [])]);
// With a wallet adapter (frontend):
await sign(built.transaction, [walletAdapter]);result.signers contains the metadata keypair required by stream creation transactions. Always spread it alongside the invoker.
Roles
The invoker acts as the stream sender - it funds the escrow and has authority to cancel or topup (if those flags were set at creation). The recipient is a separate wallet address provided in the stream params.