Skip to main content

WrapperClient

The WrapperClient manages the x0-USD stablecoin wrapper — 1:1 USDC-backed with a governance timelock system.
import { WrapperClient } from '@x0-protocol/sdk';

const wrapper = new WrapperClient(connection);

Core Operations

Deposit & Mint

Deposit USDC into the reserve and mint equivalent x0-USD:
const ix = wrapper.buildDepositAndMintInstruction(
  userPubkey,
  new BN(100_000_000), // 100 USDC
  usdcMint,
  usdcTokenProgram
);

Burn & Redeem

Burn x0-USD and withdraw USDC (minus redemption fee):
const ix = wrapper.buildBurnAndRedeemInstruction(
  userPubkey,
  new BN(50_000_000), // 50 x0-USD
  usdcMint,
  usdcTokenProgram
);

Fee Calculation

const [fee, payout] = wrapper.calculateRedemptionFee(
  new BN(100_000_000), // amount
  80                    // fee in bps (0.8%)
);
// fee = 800_000, payout = 99_200_000

PDA Derivation

const [configPda] = wrapper.deriveConfigPda();
const [statsPda] = wrapper.deriveStatsPda();
const [reservePda] = wrapper.deriveReservePda(usdcMint);
const [mintPda] = wrapper.deriveWrapperMintPda(usdcMint);
const [mintAuthPda] = wrapper.deriveMintAuthorityPda(wrapperMint);
const [actionPda] = wrapper.deriveAdminActionPda(nonce);

Reserve Health

const ratio = wrapper.calculateReserveRatio(reserveBalance, supply);
// 10000 = 1.0x, 10100 = 1.01x

const healthy = wrapper.isReserveHealthy(reserveBalance, supply);

Governance (Timelock)

All admin operations go through a 48-hour timelock. The flow is:
1

Schedule

Schedule the action. A 48-hour countdown begins.
2

Wait

The community can observe the pending action on-chain.
3

Execute or Cancel

After 48 hours, the admin executes the action. Or cancels it at any time.

Fee Rate Changes

// Schedule
const scheduleIx = wrapper.buildScheduleFeeChangeInstruction(
  adminPubkey,
  new BN(Date.now()), // nonce
  50                   // new fee: 0.5%
);

// Execute (after 48h)
const executeIx = wrapper.buildExecuteFeeChangeInstruction(adminPubkey, actionPda);

Pause/Unpause

// Schedule pause
const pauseIx = wrapper.buildSchedulePauseInstruction(adminPubkey, nonce, true);

// Emergency pause (bypasses timelock)
const emergencyIx = wrapper.buildEmergencyPauseInstruction(adminPubkey);

Emergency Withdrawal

// Schedule
const scheduleIx = wrapper.buildScheduleEmergencyWithdrawInstruction(
  adminPubkey,
  nonce,
  new BN(1_000_000_000), // amount
  destinationPubkey
);

// Execute
const executeIx = wrapper.buildExecuteEmergencyWithdrawInstruction(
  adminPubkey, actionPda, usdcMint, destinationAta, usdcTokenProgram
);

Admin Transfer (2-Step)

// Step 1: Initiate
const initiateIx = wrapper.buildInitiateAdminTransferInstruction(adminPubkey, newAdminPubkey);

// Step 2: Accept (new admin signs)
const acceptIx = wrapper.buildAcceptAdminTransferInstruction(newAdminPubkey);

Cancel

const cancelIx = wrapper.buildCancelAdminActionInstruction(adminPubkey, actionPda);

Querying State

fetchConfig()

const config = await wrapper.fetchConfig();
FieldTypeDescription
adminPublicKeyCurrent admin (multisig)
pendingAdminPublicKey?Pending admin transfer
usdcMintPublicKeyUSDC mint address
wrapperMintPublicKeyx0-USD mint address
reserveAccountPublicKeyReserve token account
redemptionFeeBpsnumberCurrent redemption fee in bps
isPausedbooleanWhether operations are paused

fetchStats()

const stats = await wrapper.fetchStats();
FieldTypeDescription
reserveUsdcBalanceBNUSDC in reserve
outstandingWrapperSupplyBNx0-USD in circulation
totalDepositsBNCumulative deposits
totalRedemptionsBNCumulative redemptions
totalFeesCollectedBNCumulative fees collected
dailyRedemptionVolumeBNToday’s redemption volume
dailyRedemptionResetTimestampnumberWhen daily counter resets
lastUpdatednumberLast update timestamp

AdminActionType Enum

ValueName
0SetFeeRate
1SetPaused
2EmergencyWithdraw
3TransferAdmin
Last modified on February 8, 2026