integrate-reflect
npx skills add https://github.com/palindrome-eng/agent-skills --skill integrate-reflect
Agent 安装分布
Skill 文档
Reflect Money Integration
Single skill for all Reflect Money APIs and SDKs. Yield-bearing stablecoins on Solana.
API Base URL: https://prod.api.reflect.money
Docs: https://docs.reflect.money
GitHub: https://github.com/palindrome-eng
Audit Report: https://alpha.reflect.money/static/Reflect-DeltaNeutral-Sep-2025-OffsideLabs.pdf
Use / Do Not Use
Use when:
- The task involves minting or redeeming USDC+, USDT+, or USTR+.
- The task involves issuing a whitelabel/branded yield-bearing stablecoin (proxy).
- The task involves querying APY, exchange rates, supply caps, or protocol stats.
- The task involves restaking into the Reflect Liquidity Pool (RLP).
- The task involves reading or writing oracle price data via Doppler.
- The user needs to integrate Reflect into a dApp, backend, or DeFi protocol.
- The user is debugging a Reflect SDK or API call.
Do not use when:
- The task is generic Solana setup with no Reflect API or SDK usage.
- The task involves Pyth, Switchboard, or other oracles not built by Reflect/Blueshift.
Triggers: usdc+, usdt+, ustr+, yield stablecoin, capital efficient stablecoin, reflect money, reflect protocol, mint usdc+, redeem usdc+, lending aggregation, cross-margin rate farming, whitelabel stablecoin, branded stablecoin, proxy stablecoin, rlp, restaking reflect, reflect liquidity pool, reflect apy, reflect sdk, stable.ts, proxy.ts, oracle.ts, reflectmoney, insured stablecoin, yield on usdc, yield on usdt, reflect oracle, doppler oracle, treasury stablecoin onchain
Intent Router
| User intent | Path | First action |
|---|---|---|
| Mint USDC+ | Stablecoin SDK or REST | new UsdcPlusStablecoin(connection) â .load() â .mint() |
| Redeem USDC+ | Stablecoin SDK or REST | .load() â .redeem() |
| Get APY | REST | GET /stablecoin/apy |
| Get exchange rate | REST | GET /stablecoin/{index}/exchange-rate |
| Get supply cap | REST | GET /stablecoin/limits |
| Issue branded stablecoin | Whitelabel SDK or REST | Proxy.initialize() or POST /integration/initialize/flow |
| Whitelabel mint | REST | POST /integration/mint (auto-inits user account) |
| Atomic USDC â branded | REST | POST /integration/flow/mint |
| Atomic branded â USDC | REST | POST /integration/flow/redeem |
| Quote for whitelabel | REST | POST /integration/quote/{type} |
| Quote for full flow | REST | POST /integration/quote/flow/{type} |
| Claim integration fees | REST | POST /integration/claim |
| Integration analytics | REST | GET /integration/{id}/stats |
| Restake into RLP | Restaking SDK | new RLP(connection) â rlp.restake() |
| Protocol TVL / analytics | REST | GET /stats |
| Read oracle price | Oracle SDK | new Doppler(connection, admin) â doppler.fetchOracle() |
| Update / create oracle | Oracle SDK | doppler.updateOracle() or doppler.createOracleAccount() (operators only) |
Developer Quickstart
import { Connection, Keypair, TransactionMessage, VersionedTransaction } from "@solana/web3.js";
import { UsdcPlusStablecoin } from "@reflectmoney/stable.ts";
import BN from "bn.js";
const connection = new Connection("https://api.mainnet-beta.solana.com");
const stablecoin = new UsdcPlusStablecoin(connection);
await stablecoin.load(connection); // REQUIRED before every session
const AMOUNT = new BN(1000 * 1_000_000); // 1000 USDC (6 decimals)
const MIN_OUT = new BN(999 * 1_000_000); // 0.1% slippage
const ix = await stablecoin.mint(user.publicKey, AMOUNT, MIN_OUT);
const { blockhash } = await connection.getLatestBlockhash();
const { value: lut } = await connection.getAddressLookupTable(stablecoin.lookupTable);
// ALWAYS VersionedTransaction, ALWAYS include ALT
const tx = new VersionedTransaction(
new TransactionMessage({ instructions: ix, payerKey: user.publicKey, recentBlockhash: blockhash })
.compileToV0Message([lut])
);
tx.sign([keypair]);
await connection.sendRawTransaction(tx.serialize(), { skipPreflight: true, maxRetries: 0 });
REST equivalent:
# Quote
curl -X POST https://prod.api.reflect.money/stablecoin/quote/mint \
-H "Content-Type: application/json" \
-d '{"amount": 1000000, "index": 0}'
# Mint â returns base64 VersionedTransaction, deserialise, sign, send
curl -X POST https://prod.api.reflect.money/stablecoin/mint \
-H "Content-Type: application/json" \
-d '{"amount": 1000000, "index": 0, "feePayer": "<pubkey>"}'
What Is Reflect Money
Reflect Money is credibly-neutral stablecoin infrastructure on Solana. It tokenizes onchain DeFi yield strategies as interest-bearing US Dollar stablecoins. Programs manage all deposits â zero human custody, zero admin keys, minted and redeemed at will with zero fees.
Circle Alliance Member â Reflect is NOT affiliated with or endorsed by Circle Inc. Entirely separate entities. Funding: $3.75M â a16z Crypto CSX, Solana Ventures, Equilibrium, Big Brain VC, Colosseum. Audit: Offside Labs, September 2025 â USD Coin Plus strategy. All findings resolved.
The Strategy â Cross-Margin Rate Farming
USDC+ and USDT+ both use the same strategy:
- User deposits base stablecoin â Reflect program holds it in non-custodial pool.
- Program scans Solana lending markets (Drift, Kamino, Jupiter Lend) for best rates.
- USDC distributed automatically across venues to capture highest available interest.
- User receives USDC+ â which natively appreciates in value in their wallet, no claiming required.
- Convert back to USDC at any time; 1 USDC+ is always worth slightly more than 1 USDC.
Yield source: Interest paid by overcollateralised borrowers on Solana money markets.
Live and Upcoming Stablecoins
| Token | Collateral | Status | Index | SDK Class | Yield |
|---|---|---|---|---|---|
| USDC+ | USDC (Circle) | â Live | 0 | UsdcPlusStablecoin |
Native appreciation |
| USDT+ | USDT (Tether) | â³ Upcoming | TBD | TBD | Native appreciation |
| USTR+ | US Treasury Bills (aggregated) | â³ Upcoming | TBD | TBD | TBD |
Hard rule: Only USDC+ is confirmed live by the protocol team. The SDK docs list
LstStablecoin(Index 2) as “Live” â this is a known discrepancy. Confirm live stablecoins at runtime viaGET /stablecoin/types.
Closed beta: Reflect is currently in closed beta. Users must be whitelisted via
POST /integration/whitelistbefore they can transact.
SDK Packages
yarn add @reflectmoney/stable.ts # mint/redeem stablecoins
yarn add @reflectmoney/proxy.ts # whitelabel branded stablecoins
yarn add @reflectmoney/restaking # RLP restaking (post-beta only)
yarn add @reflectmoney/oracle.ts # Doppler oracle price feeds
Stablecoin SDK
Package: @reflectmoney/stable.ts
Gotchas:
- Always call
.load(connection)before any operation. Never skip or cache across sessions. - Always use
VersionedTransaction(V0). Legacy transactions will fail. - ALTs are required for all stablecoin SDK calls â pass
[lut]tocompileToV0Message(). - ALTs are NOT required for
ReflectTokenizedBondâcompileToV0Message()with no args. - Use
stablecoin.indexâ never hardcode the index number. - USDC+ natively appreciates â no
ReflectTokenizedBondinteraction needed. rebalance()is permissioned â never call from integrations.- On first mint, call
initializeTokenAccounts()before minting. - Slippage for redeem: because USDC+ has appreciated,
MIN_RECEIVEDshould be higher than the USDC+ input amount.
Core Modules (rarely needed for basic integrations)
Reflect â general-purpose protocol setup. Not required for standard flows.
ReflectKeeper â permissioned keeper functions. Admin only, never call from integrations.
import { UsdcPlusStablecoin, ReflectKeeper } from "@reflectmoney/stable.ts";
// Admin only
const initIx = await ReflectKeeper.initializeMain(admin);
const capIx = await stablecoin.updateCap(admin, BigInt(1_000_000_000_000_000));
const freezeIx = await stablecoin.freeze(admin, true, 0);
const unfreezeIx = await stablecoin.freeze(admin, false, 0);
PdaClient â PDA derivation.
import { PdaClient } from "@reflectmoney/stable.ts";
const mainPda = await PdaClient.deriveMain();
const controllerPda = await PdaClient.deriveController(0); // 0 = USDC+
const permissionsPda = await PdaClient.derivePermissions(adminAddress);
Abstract Stablecoin Class
abstract class Stablecoin {
public index: number; // read as property, never hardcode
public name: string;
public connection: Connection;
public controller: PublicKey;
public collaterals: Collateral[];
public stablecoinMint: PublicKey;
public pythClient: HermesClient;
public driftClient?: DriftClient; // only for Drift-powered strategies
abstract initializeTokenAccounts(owner: PublicKey, mints: PublicKey[], signer: PublicKey): Promise<TransactionInstruction[]>;
abstract mint(signer: PublicKey, amount: BN | number, minimumReceived: BN | number, ...args: any[]): Promise<TransactionInstruction[]>;
abstract redeem(signer: PublicKey, amount: BN | number, minimumReceived: BN | number, ...args: any[]): Promise<TransactionInstruction[]>;
abstract rebalance(signer: PublicKey): Promise<TransactionInstruction[]>; // PERMISSIONED â never call
}
Mint
import { UsdcPlusStablecoin } from "@reflectmoney/stable.ts";
import { Connection, Keypair, TransactionMessage, VersionedTransaction } from "@solana/web3.js";
import BN from "bn.js";
const connection = new Connection("https://api.mainnet-beta.solana.com");
const stablecoin = new UsdcPlusStablecoin(connection);
await stablecoin.load(connection);
const AMOUNT = new BN(1000 * Math.pow(10, 6)); // $1000 USDC
const MIN_OUT = new BN(999 * Math.pow(10, 6)); // 0.1% slippage
const ix = await stablecoin.mint(user.publicKey, AMOUNT, MIN_OUT);
const { blockhash } = await connection.getLatestBlockhash();
const { value: lut } = await connection.getAddressLookupTable(stablecoin.lookupTable);
const tx = new VersionedTransaction(
new TransactionMessage({ instructions: ix, payerKey: user.publicKey, recentBlockhash: blockhash })
.compileToV0Message([lut])
);
tx.sign([user]);
await connection.sendRawTransaction(tx.serialize());
Redeem
// USDC+ has appreciated â burn 999 USDC+, expect >= 1000 USDC back
const AMOUNT = new BN(999 * Math.pow(10, 6));
const MIN_OUT = new BN(1000 * Math.pow(10, 6));
const ix = await stablecoin.redeem(user.publicKey, AMOUNT, MIN_OUT);
// Build + send VersionedTransaction identically to mint
First-Time User
const initIx = await stablecoin.initializeTokenAccounts(
user.publicKey,
[stablecoin.stablecoinMint],
user.publicKey
);
// Include initIx in same tx as, or before, the first mint
ReflectTokenizedBond (future stablecoins only)
USDC+ and USDT+ natively appreciate â this is not needed for them. For future stablecoins distributing yield via receipt tokens (e.g. USDJ when live):
import { ReflectTokenizedBond, UsdjStablecoin } from "@reflectmoney/stable.ts";
const stablecoin = new UsdjStablecoin(connection);
const bond = new ReflectTokenizedBond(connection);
const depositIx = bond.deposit(user.publicKey, stablecoin.index, AMOUNT);
const withdrawIx = bond.withdraw(user.publicKey, stablecoin.index, AMOUNT);
// NO ALT â compileToV0Message() with no arguments
const tx = new VersionedTransaction(
new TransactionMessage({ instructions: [depositIx], payerKey: user.publicKey, recentBlockhash: blockhash })
.compileToV0Message()
);
Whitelabel SDK
Package: @reflectmoney/proxy.ts
Gotchas:
Proxy.initialize()is one-time â creates on-chain accounts. Never call twice for the same proxy.- Only use the constructor after on-chain proxy accounts are already initialised.
Proxy.loadFromMint()â preferred load path, derives proxy state from branded mint.new Proxy({ connection, proxyStateAddress })â alternative if you have the state address directly. Note: parameter isproxyStateAddress, notproxyAddress.proxy.load()â lazily loads state; call again to refresh after on-chain changes.claimFees()â authority only.- Uses
@solana/kit(createSolanaRpc,address) not@solana/web3.js.
Exported constants:
USDC_PLUS_MINTâ USDC+ mint address on mainnetUSDC_PLUS_ORACLEâ Oracle tracking real-time USDC+ exchange ratePROXY_STATE_SEEDâ PDA seed for proxy state derivationREFLECT_PROXY_PROGRAM_PROGRAM_ADDRESSâ Proxy program ID
import { Proxy, USDC_PLUS_MINT, PdaClient } from "@reflectmoney/proxy.ts";
import { createSolanaRpc, address } from "@solana/kit";
const connection = createSolanaRpc("https://api.mainnet-beta.solana.com");
// --- ONE-TIME SETUP ---
const createIx = await Proxy.initialize({
signer: myWallet,
authority: address("AuthorityAddress"), // optional, defaults to signer
brandedMint: address("YourBrandedMint"),
feeBps: 50, // 0.5% fee on all flows
stablecoinMint: address(USDC_PLUS_MINT)
});
// --- LOAD BY MINT (preferred) ---
const proxy = await Proxy.loadFromMint({ connection, brandedMint: address("YourBrandedMint") });
// --- LOAD BY STATE ADDRESS ---
const proxy2 = new Proxy({ connection, proxyStateAddress: address("ProxyStateAddress") });
await proxy2.load(); // call again anytime to refresh
// --- OPERATIONS ---
const depositIx = await proxy.deposit({ signer: myWallet, amount: 1_000_000 });
const withdrawIx = await proxy.withdraw({ signer: myWallet, amount: 1_000_000 });
const claimIx = await proxy.claimFees(); // authority only
// --- PDA DERIVATION ---
const [proxyStateAddress, bump] = await PdaClient.deriveProxyState(address("YourBrandedMint"));
Restaking SDK
Package: @reflectmoney/restaking
Status: â ï¸ NOT AVAILABLE until Reflect exits public beta. Do not build production integrations until then.
Gotchas: Withdrawals require a cooldown period â read cooldown state before surfacing to users.
import { RLP } from "@reflectmoney/restaking";
import BN from "bn.js";
const rlp = new RLP(connection);
// Monitoring
const lockups = await rlp.getLockups();
const byAsset = await rlp.getLockupsByAsset(mintPublicKey);
const myDeposits = await rlp.getDepositsByUser(myPublicKey);
const myCooldowns = await rlp.getCooldownsByUser(myPublicKey);
const byCooldown = await rlp.getCooldownsByDeposit(new BN(0));
// PDA derivation
const settings = rlp.deriveSettings();
const lockup = rlp.deriveLockup(new BN(0));
const asset = rlp.deriveAsset(mintPublicKey);
// Actions (post-beta only)
const restakeIx = rlp.restake(signer.publicKey, new BN(1000 * 1_000_000), new BN(0));
const withdrawIx = rlp.withdraw(signer.publicKey, new BN(1000 * 1_000_000), new BN(0));
Oracle SDK
Package: @reflectmoney/oracle.ts
Program ID: PRicevBH6BaeaE8qmrxrwGBZ5hSZ9vjBNue5Ygot1ML
Underlying: Fork of Doppler by Blueshift â 32 CUs per update (base Doppler = 21 CUs; Reflect fork adds a Clock sysvar call)
Gotchas:
Dopplerconstructor requires an admin keypair â oracle writes are permissioned to the oracle creator.- Price payloads are 8 bytes (u64). Always use
createPricePayload()to encode,readPriceFromPayload()to decode. - Always use the same
U8Array8Serializer()acrossupdateOracleandfetchOraclecalls. - Pass
BigInt(Date.now())or the current Solana slot asslotâ used for staleness checks. - Most integrators only need
fetchOracleâ write methods are for oracle operators.
import { Doppler, U8Array8Serializer, createPricePayload, readPriceFromPayload } from "@reflectmoney/oracle.ts";
import { Connection, Keypair, PublicKey } from "@solana/web3.js";
const connection = new Connection("https://api.mainnet-beta.solana.com");
const admin = Keypair.fromSecretKey(/* admin keypair bytes */);
const doppler = new Doppler(connection, admin);
const oraclePublicKey = new PublicKey("ORACLE_ADDRESS");
// READ (most common)
const oracleData = await doppler.fetchOracle(oraclePublicKey, new U8Array8Serializer());
if (oracleData) {
const price = readPriceFromPayload(oracleData.payload);
// price: 1000000n = 1.000000 USDC (6-decimal fixed point)
}
// CREATE oracle account (operators only)
const oracleAccount = await doppler.createOracleAccount(
"my-oracle-seed",
new U8Array8Serializer(),
{ slot: 0n, payload: createPricePayload(BigInt(1_000_000)) }
);
// UPDATE oracle (operators only)
await doppler.updateOracle(
oraclePublicKey,
{ slot: BigInt(Date.now()), payload: createPricePayload(BigInt(1_000_000)) },
new U8Array8Serializer()
);
REST API
Base URL: https://prod.api.reflect.money
All transaction endpoints return { "success": true, "data": { "transaction": "<base64>" } }. Deserialise with VersionedTransaction.deserialize(Buffer.from(b64, 'base64')), sign, and send.
Stablecoin Endpoints
| Method | Endpoint | Description |
|---|---|---|
GET |
/health |
Health check |
GET |
/stablecoin/types |
List available stablecoin types |
GET |
/stablecoin/limits |
Supply caps, current supply, remaining capacity |
GET |
/stablecoin/apy |
Realtime APY for all stablecoins |
GET |
/stablecoin/{index}/apy |
Realtime APY for specific stablecoin |
GET |
/stablecoin/{index}/apy/historical |
Historical APY (days param) |
GET |
/stablecoin/exchange-rates |
Latest exchange rates for all stablecoins |
GET |
/stablecoin/{index}/exchange-rate |
Realtime exchange rate for specific stablecoin |
GET |
/stablecoin/exchange-rates/historical |
Historical rates (index + days params) |
POST |
/stablecoin/quote/{type} |
Quote for mint or redeem (type: mint or redeem) |
POST |
/stablecoin/mint |
Generate mint transaction |
POST |
/stablecoin/burn |
Generate burn (redeem) transaction |
Integration Setup
| Method | Endpoint | Description |
|---|---|---|
POST |
/integration/upload |
Upload brand image + JSON metadata â returns URLs |
POST |
/integration/initialize |
Initialize integration (branded mint + fee config) |
POST |
/integration/initialize-stablecoin |
Create branded token mint with metadata |
POST |
/integration/transfer-authority |
Transfer mint authority to Reflect |
POST |
/integration/initialize/flow |
Complete setup in a single transaction (recommended) |
POST |
/integration/initialize-vault |
Initialize proxy vault (admin only) |
Integration Config & Management
| Method | Endpoint | Description |
|---|---|---|
GET |
/integration/{id}/config |
Get integration configuration |
POST |
/integration/{id}/config/update |
Update fee configuration |
GET |
/integration/{authority}/integrations |
All integrations for an authority address |
GET |
/integration/verified |
All verified integrations (public) |
GET |
/integration/check/{stablecoin} |
Check if branded mint is verified (returns bool) |
POST |
/integration/api-key/reveal |
Reveal API key (60s expiry signature required) |
POST |
/integration/api-key/rotate |
Rotate API key â old key immediately invalidated |
Integration Operations
| Method | Endpoint | Description |
|---|---|---|
POST |
/integration/whitelist |
Whitelist users (closed beta requirement) |
POST |
/integration/initialize-user-account |
Init user branded token account (standalone) |
POST |
/integration/mint |
Whitelabel mint (auto-inits user account if needed) |
POST |
/integration/flow/mint |
Atomic: USDC â USDC+ â branded (single tx) |
POST |
/integration/redeem |
Whitelabel redeem |
POST |
/integration/flow/redeem |
Atomic: branded â USDC+ â USDC (single tx) |
POST |
/integration/claim |
Generate fee claim transaction |
/integration/mintautomatically detects if the user’s branded token account needs initializing and includes the init instruction. SetfeePayerto your address to sponsor account creation costs on behalf of users.
/integration/initialize-user-accountis only needed if you want to init accounts separately from minting. Otherwise/integration/minthandles it.
Integration Quote Endpoints
| Method | Endpoint | Description |
|---|---|---|
POST |
/integration/quote/{type} |
Quote: USDC+ â branded tokens (type: mint or redeem) |
POST |
/integration/quote/flow/{type} |
Quote: full USDC â branded flow (handles both conversions) |
Integration Analytics
| Method | Endpoint | Description |
|---|---|---|
GET |
/integration/{id}/stats |
Integration statistics |
GET |
/integration/{id}/stats/historical |
Historical stats (period param: 7 or 30 days, default 7) |
GET |
/integration/{id}/exchange-rate |
Current exchange rate for the integration |
GET |
/integration/{id}/events |
Recent events for the integration |
Stats & Events
| Method | Endpoint | Description |
|---|---|---|
GET |
/stats |
Protocol statistics (TVL, volume) |
GET |
/stats/historical |
Historical TVL + volume (days param: 1â365) |
GET |
/events/all/{limit} |
Most recent protocol events up to limit |
GET |
/events/{signer} |
Events for a specific signer address |
API Key Auth
Message to sign:
- Reveal:
"Reveal API key for integration {integrationId} at timestamp {timestamp}" - Rotate:
"Rotate API key for integration {integrationId} at timestamp {timestamp}"
curl -X POST https://prod.api.reflect.money/integration/api-key/reveal \
-H "Content-Type: application/json" \
-d '{
"integrationId": "<integration-id>",
"signer": "<authority-pubkey>",
"signature": "<base58-signature>",
"timestamp": 1704067200000
}'
â ï¸ Signatures expire after 60 seconds. Generate timestamp immediately before signing. Rotation is irreversible â old key invalidated with no recovery.
Error Handling Pattern
interface ReflectResult<T> {
ok: boolean;
result?: T;
error?: { code: string | number; message: string; retryable: boolean };
}
async function reflectAction<T>(action: () => Promise<T>): Promise<ReflectResult<T>> {
try {
return { ok: true, result: await action() };
} catch (err: any) {
const code = err?.code ?? err?.status ?? "UNKNOWN";
if (code === 429 || code === "RATE_LIMITED")
return { ok: false, error: { code: "RATE_LIMITED", message: "Rate limited", retryable: true } };
if (typeof code === "number" && code >= 400 && code < 500)
return { ok: false, error: { code, message: err?.message ?? `HTTP_${code}`, retryable: code === 429 || code === 408 } };
if (err?.code === "ECONNRESET" || err?.code === "ETIMEDOUT")
return { ok: false, error: { code: err.code, message: "Network error", retryable: true } };
return { ok: false, error: { code, message: err?.message ?? "UNKNOWN_ERROR", retryable: false } };
}
}
On retryable errors: delay = min(base * 2^attempt + random(0, jitter), maxDelay).
Risk Framework
| Risk | Prevention | Elimination |
|---|---|---|
| Smart contract | Code + Economic Audits | Global Insurance (RLP) |
| Exchange / DEX | Use of insured DEXs | Global Insurance |
| Interest rate | Economic Strategy Audits | Strategy fallbacks |
| Collateral | Asset Classification (S-tier only) | Limitation to S-tier |
Insurance covers principal only. Yield is variable and not guaranteed. Insurance nodes attest every 450ms. Integrators must disclose variable yield to users.
USDC+ risk factors: Smart contract risks compound across all active lending venues. Withdrawal capacity depends on utilisation rates per venue. Yield fluctuates with Solana money market conditions.
Production Hardening
- Decimals: All Reflect tokens use 6 decimal places â multiply by
1_000_000. Never use 10^9. .load()every session: Callstablecoin.load(connection)before every set of operations. Never cache across sessions.- VersionedTransaction always:
compileToV0Message()â legacy transactions fail. - ALTs: Required for stablecoin SDK calls via
stablecoin.lookupTable. Not required forReflectTokenizedBond. - Slippage guardrails: Always pass real
minimumReceived. Never pass zero â exposes users to sandwich attacks. - Redeem slippage direction: For USDC+,
MIN_RECEIVEDshould be greater than input USDC+ amount (token has appreciated). - Closed beta: All users need whitelisting via
POST /integration/whitelistbefore transacting. - Timeouts: 5s for reads, 30s for transaction submission.
- Retries: Only on transient/network/429. Never retry 4xx client errors.
- API key signing: Generate
timestampimmediately before signing â 60s expiry. - Proxy constructor param:
proxyStateAddress(notproxyAddress). - User messaging: Communicate that insurance covers principal only; yield is variable.
- Not Circle: Never describe USDC+ as a Circle product. Reflect is a Circle Alliance member only.
Integration Patterns
Pattern A â REST (Any Backend)
GET /stablecoin/apy â show yield
POST /stablecoin/quote/mint â get quote
POST /stablecoin/mint â generate tx â client signs + sends
POST /stablecoin/burn â generate tx â client signs + sends
Pattern B â TypeScript dApp (Stablecoin SDK)
const { publicKey, signTransaction } = useWallet();
const stablecoin = new UsdcPlusStablecoin(connection);
await stablecoin.load(connection);
const ix = await stablecoin.mint(publicKey, amount, minReceived);
// Build VersionedTransaction with ALT, pass to wallet adapter to sign
Pattern C â Whitelabel Integration
1. POST /integration/upload â upload brand image + metadata
2. POST /integration/initialize/flow â single tx: mint + authority + integration setup
3. POST /integration/whitelist â whitelist your users (closed beta)
4. Users: POST /integration/flow/mint â atomic USDC â USDC+ â branded
5. Users: POST /integration/flow/redeem â atomic branded â USDC+ â USDC
6. You: POST /integration/claim â harvest fee revenue
Pattern D â Analytics Display
GET /stats â protocol TVL + volume
GET /stats/historical?days=30 â 30-day chart data
GET /integration/{id}/stats â your integration's stats
GET /integration/{id}/stats/historical â your integration's historical stats
Fresh Context Policy
- Treat live documentation at
docs.reflect.moneyas source of truth over this file. - If behaviour differs from expectations, fetch the relevant docs page before proceeding.
- If docs cannot be fetched, note that context may be stale and continue with best-known guidance.
- Known discrepancy: SDK docs list
LstStablecoin(Index 2) as “Live” â per the protocol team only USDC+ is currently live. Verify at runtime viaGET /stablecoin/types. - USDT+ and USTR+ launches will add new SDK classes and API parameters. Re-check docs before integrating.
- Closed beta status may change â check whitelist requirements before shipping to users.
Operational References
| Resource | URL |
|---|---|
| Docs home | https://docs.reflect.money |
| Stablecoin SDK | https://docs.reflect.money/api-reference/stablecoin |
| Whitelabel SDK | https://docs.reflect.money/api-reference/proxy |
| Restaking SDK | https://docs.reflect.money/api-reference/restaking |
| Oracle SDK | https://docs.reflect.money/api-reference/oracle |
| USDC+ strategy | https://docs.reflect.money/strategies/USDC |
| Risk overview | https://docs.reflect.money/risk-management/notice |
| Security audit | https://alpha.reflect.money/static/Reflect-DeltaNeutral-Sep-2025-OffsideLabs.pdf |
| GitHub | https://github.com/palindrome-eng |
| Protocol home | https://reflect.money |