Package Exports
- @reflectmoney/stable.ts
- @reflectmoney/stable.ts/dist/index.js
This package does not declare an exports field, so the exports above have been automatically detected and optimized by JSPM instead. If any package subpath is missing, it is recommended to post an issue to the original package (@reflectmoney/stable.ts) to support the "exports" field. If that is not possible, create a JSPM override to customize the exports field for this package.
Readme
Reflect Money SDK
A TypeScript SDK for interacting with the Reflect protocol on Solana. The SDK provides high-level abstractions for minting, redeeming, and managing stablecoins.
Installation
npm install @reflectmoney/stable.ts
# or
yarn add @reflectmoney/stable.tsOverview
The Reflect SDK enables developers to interact with the protocol's stablecoins:
- USDC+ (Index 0): Yield-bearing stablecoin backed by USDC deployed in money markets
Architecture
Core Classes
Stablecoin (Abstract Base Class)
The foundation for all stablecoin implementations. Provides common interface for:
- Minting stablecoins
- Redemption operations
- Administrative functions (cap updates, freezing)
- Drift protocol integration
Key Properties:
controllerKey- PDA for the stablecoin controller accountstablecoinMint- Address of the stablecoin token mintcollaterals- Array of supported collateral assetslookupTable- Address lookup table for transaction optimization
UsdcPlusStablecoin
USDC+ implementation - a yield-bearing stablecoin backed by USDC in money markets.
- Strategy ID: 0
- Collateral: USDC
- Status: Live on mainnet
ReflectKeeper
Static utility class for protocol-level administrative operations:
initializeMain()- Initialize the main protocol account- Protocol configuration and management
PdaClient
Utility class for deriving Program Derived Addresses:
deriveMain()- Main protocol configuration accountderiveController(index)- Stablecoin controller accountsderivePermissions(admin)- Admin permission accounts
Usage
Setup
import { createSolanaRpc } from "@solana/kit";
import { UsdcPlusStablecoin } from "@reflectmoney/stable.ts";
// Create RPC connection
const rpc = createSolanaRpc("https://api.mainnet-beta.solana.com");
// Initialize the stablecoin client
const usdcPlus = new UsdcPlusStablecoin(rpc);
// Load on-chain state (fetches controller data, mint, exchange rate)
await usdcPlus.load();Minting Stablecoins
import {
createSolanaRpc,
pipe,
createTransactionMessage,
setTransactionMessageFeePayer,
setTransactionMessageLifetimeUsingBlockhash,
appendTransactionMessageInstructions,
signTransactionMessageWithSigners,
sendAndConfirmTransactionFactory,
} from "@solana/kit";
import { UsdcPlusStablecoin } from "@reflectmoney/stable.ts";
// Your wallet signer (from wallet adapter or keypair)
const user = /* your signer */;
// Initialize and load stablecoin state
const rpc = createSolanaRpc("https://api.mainnet-beta.solana.com");
const usdcPlus = new UsdcPlusStablecoin(rpc);
await usdcPlus.load();
// Create mint instruction
// Deposit 1,000 USDC, expect minimum 999 USDC+ (0.1% slippage)
const instructions = await usdcPlus.mint(
user,
BigInt(1000_000_000), // 1,000 USDC (6 decimals)
BigInt(999_000_000), // Minimum USDC+ to receive
);
// Build and send transaction
const { value: latestBlockhash } = await rpc.getLatestBlockhash().send();
const transactionMessage = pipe(
createTransactionMessage({ version: 0 }),
tx => setTransactionMessageFeePayer(user.address, tx),
tx => setTransactionMessageLifetimeUsingBlockhash(latestBlockhash, tx),
tx => appendTransactionMessageInstructions(instructions, tx),
);
const signedTransaction = await signTransactionMessageWithSigners(transactionMessage);
const sendAndConfirm = sendAndConfirmTransactionFactory({ rpc });
const signature = await sendAndConfirm(signedTransaction, { commitment: "confirmed" });
console.log("Mint transaction:", signature);Redeeming Stablecoins
import {
createSolanaRpc,
pipe,
createTransactionMessage,
setTransactionMessageFeePayer,
setTransactionMessageLifetimeUsingBlockhash,
appendTransactionMessageInstructions,
signTransactionMessageWithSigners,
sendAndConfirmTransactionFactory,
} from "@solana/kit";
import { UsdcPlusStablecoin } from "@reflectmoney/stable.ts";
const user = /* your signer */;
const rpc = createSolanaRpc("https://api.mainnet-beta.solana.com");
const usdcPlus = new UsdcPlusStablecoin(rpc);
await usdcPlus.load();
// Create redeem instruction
// Burn 999 USDC+, expect minimum 1,000 USDC (USDC+ accrues yield)
const instructions = await usdcPlus.redeem(
user,
BigInt(999_000_000), // USDC+ to burn
BigInt(1000_000_000), // Minimum USDC to receive
);
// Build and send transaction
const { value: latestBlockhash } = await rpc.getLatestBlockhash().send();
const transactionMessage = pipe(
createTransactionMessage({ version: 0 }),
tx => setTransactionMessageFeePayer(user.address, tx),
tx => setTransactionMessageLifetimeUsingBlockhash(latestBlockhash, tx),
tx => appendTransactionMessageInstructions(instructions, tx),
);
const signedTransaction = await signTransactionMessageWithSigners(transactionMessage);
const sendAndConfirm = sendAndConfirmTransactionFactory({ rpc });
const signature = await sendAndConfirm(signedTransaction, { commitment: "confirmed" });
console.log("Redeem transaction:", signature);Getting Exchange Rate
import { createSolanaRpc } from "@solana/kit";
import { UsdcPlusStablecoin } from "@reflectmoney/stable.ts";
const rpc = createSolanaRpc("https://api.mainnet-beta.solana.com");
const usdcPlus = new UsdcPlusStablecoin(rpc);
await usdcPlus.load();
// Get current exchange rate (USDC per USDC+)
const exchangeRate = await usdcPlus.getExchangeRate();
console.log(`1 USDC+ = ${exchangeRate} USDC`);PDA Derivation
import { PdaClient } from "@reflectmoney/stable.ts";
// Derive main protocol account
const mainPda = await PdaClient.deriveMain();
// Derive controller for strategy index 0 (USDC+)
const controllerPda = await PdaClient.deriveController(0);
// Derive permissions account for an admin
const permissionsPda = await PdaClient.derivePermissions(adminAddress);Administrative Operations
import { UsdcPlusStablecoin, ReflectKeeper } from "@reflectmoney/stable.ts";
const admin = /* admin signer */;
// Initialize main protocol (one-time setup)
const initMainIx = await ReflectKeeper.initializeMain(admin);
// Update supply cap
const usdcPlus = new UsdcPlusStablecoin(rpc);
await usdcPlus.load();
const updateCapIx = await usdcPlus.updateCap(
admin,
BigInt(1_000_000_000_000_000) // New cap
);
// Freeze/unfreeze minting
const freezeIx = await usdcPlus.freeze(admin, true, 0); // Freeze action 0
const unfreezeIx = await usdcPlus.freeze(admin, false, 0); // UnfreezeAPI Reference
UsdcPlusStablecoin
Constructor
constructor(rpc: Rpc<SolanaRpcApi>, mint?: Address)rpc- Solana RPC clientmint- Optional stablecoin mint address (auto-loaded if not provided)
Methods
| Method | Description | Returns |
|---|---|---|
load() |
Load on-chain state (controller, mint, exchange rate) | Promise<void> |
initializeKeys() |
Initialize PDA keys without fetching on-chain data | Promise<void> |
mint(user, amount, minReceived) |
Create mint instruction | Promise<Instruction[]> |
redeem(user, amount, minReceived) |
Create redeem instruction | Promise<Instruction[]> |
getExchangeRate() |
Get current USDC/USDC+ exchange rate | Promise<number> |
updateCap(admin, newCap) |
Update supply cap (admin) | Promise<Instruction> |
freeze(admin, freeze, action) |
Freeze/unfreeze actions (admin) | Promise<Instruction> |
PdaClient
Static Methods
| Method | Description | Returns |
|---|---|---|
deriveMain(devnet?) |
Derive main protocol PDA | Promise<Address> |
deriveController(index, devnet?) |
Derive controller PDA for strategy | Promise<Address> |
derivePermissions(admin, devnet?) |
Derive admin permissions PDA | Promise<Address> |
ReflectKeeper
Static Methods
| Method | Description | Returns |
|---|---|---|
initializeMain(admin) |
Initialize main protocol account | Promise<Instruction> |
Types
// Collateral asset configuration
interface Collateral {
mint: Address;
oracle: string;
decimals: number;
}
// Stablecoin metadata
interface StablecoinMetadata {
name: string;
ticker: string;
uri: string;
}Integration Notes
Drift Protocol
The SDK integrates with Drift Protocol for perpetual futures positions. Admin operations for Drift account management:
// Initialize Drift stats account for the controller
const driftStatsIx = await usdcPlus.initializeStablecoinDriftStatsAccount(admin);
// Initialize Drift sub-account
const driftAccountIx = await usdcPlus.initializeStablecoinDriftAccount(admin);Address Lookup Tables
For transaction optimization, use the stablecoin's lookup table:
const lookupTableAddress = usdcPlus.lookupTable;
// Fetch and use in versioned transactions for reduced transaction sizeNetwork Support
- Mainnet: Default configuration
- Devnet: Pass
devnet: trueto constructor or use devnet RPC
License
MIT License
Support
- Documentation: docs.reflect.money
- GitHub: github.com/palindrome-eng/reflect-delta-neutral