Integration
Install the SDK, emit receipts, fund a campaign, verify settlement.
Install
The SDK ships client bindings, a server client and typed contract interfaces. It has no peer dependency on a wallet library.
npm install @investor-tech/sdk# orpnpm add @investor-tech/sdkInitialize the provider
The provider resolves contract addresses from the network registry at runtime. Configure the application id and registry through environment variables so a deployment change never requires a client release.
1import { InvestorProvider, createClient } from "@investor-tech/sdk";23const investor = createClient({4 application: process.env.NEXT_PUBLIC_INVESTOR_APP_ID,5 network: "robinhood-chain",6 registry: process.env.NEXT_PUBLIC_INVESTOR_REGISTRY,7});89export function Providers({ children }: { children: React.ReactNode }) {10 return <InvestorProvider client={investor}>{children}</InvestorProvider>;11}Future Split preview
Show the user what the transaction will contribute before they confirm it. The hook reads the connected account's own rate, the campaign that applies, and the recipe the contribution will land in.
1import { useFutureSplit } from "@investor-tech/sdk/react";23export function TradeFooter({ notional }: { notional: number }) {4 // Reads the connected account's own Future Rate. Never set it yourself.5 const { rate, contribution, match, recipe } = useFutureSplit({ notional });67 return (8 <dl className="split-preview">9 <dt>Future Split</dt>10 <dd>{contribution.formatted}</dd>11 <dt>{match.application} match</dt>12 <dd>{match.formatted}</dd>13 <dt>Destination</dt>14 <dd>{recipe.name}</dd>15 </dl>16 );17}Transaction receipts
One receipt per settled user action. The protocol derives the contribution, applies whatever campaign is funded, and allocates on the next batch. Emit the receipt after your own settlement, never before.
1import { investor } from "@/lib/investor";23// Emit one receipt per settled user action. The protocol derives the4// contribution, applies your campaign, and allocates on the next batch.5export async function onTradeSettled(trade: SettledTrade) {6 await investor.receipts.submit({7 account: trade.account,8 activity: "trade.completed",9 notional: trade.notionalUsd,10 reference: trade.txHash,11 settledAt: trade.settledAt,12 });13}- account
- The address that transacted. The account contract is resolved from it.
- activity
- One of trade.completed, position.closed, swap.routed, payment.settled.
- notional
- The USD value of the action, before any split is deducted.
- reference
- Your own transaction hash. Used for idempotency and verification.
- settledAt
- ISO 8601. Receipts older than 24 hours are rejected.
Match Escrow contract
If you intend to match, fund escrow before publishing. Release is callable only by the settlement contract, against a verified receipt.
1// MatchEscrow.sol2pragma solidity ^0.8.24;34interface IMatchEscrow {5 event CampaignFunded(bytes32 indexed campaign, uint256 amount);6 event MatchReleased(bytes32 indexed campaign, address indexed account, uint256 amount);78 /// @notice Deposit the capital that backs an advertised match rate.9 function fund(bytes32 campaign, uint256 amount) external;1011 /// @notice Released by settlement once a contribution receipt is verified.12 function release(bytes32 campaign, address account, uint256 amount) external;1314 /// @notice Remaining capital behind a published campaign.15 function available(bytes32 campaign) external view returns (uint256);16}Verify a contribution
Reconcile against your own ledger. A receipt reaches settled state once it has been included in a batch; until then it is pending and no match has been released.
1import { investor } from "@/lib/investor";23const { verified, contribution, match, batch } = await investor.receipts.status({4 reference: trade.txHash,5});67if (!verified) {8 // The receipt has not reached a settlement batch yet.9 return { state: "pending" };10}1112return {13 state: "settled",14 contributed: contribution.amount,15 matched: match.amount,16 batch: batch.id,17};Webhooks deliver the same information if you prefer to be pushed rather than to poll.
// POST https://your-app.example/webhooks/investor{ "type": "contribution.settled", "batch": "SB-18442", "account": "0x71F4...9A28", "application": "meridian", "contribution": 10.00, "match": 2.00, "recipe": "2060", "settledAt": "2026-08-30T15:40:00Z"}Publish a campaign
Campaigns can be created in the Console or from the server SDK. Both write to the same registry and both require funded escrow.
1import { investor } from "@/lib/investor";23await investor.campaigns.publish({4 name: "September Future Match",5 kind: "contribution-match",6 trigger: "trade.completed",7 rate: 0.2, // 20% of the user's Future Split8 cap: { amount: 5, period: "day" },9 budget: 100_000,10 window: { start: "2026-09-01", end: "2026-09-30" },11 retentionCheckpointDays: 30,12 funding: "escrow",13});Launch checklist
- Install SDK@investor-tech/sdk v2.4.1
- Initialize Investor providerApplication id and registry configured
- Add Future Split previewRendered in the trade footer
- Pass transaction receipt12,480 receipts in the last 24 hours
- Configure Match EscrowEscrow funded and bonded
- 6Verify contribution eventConfirm settled state in your own ledger