Back to Home

Urbanium SDK

The Urbanium SDK provides a production-ready TypeScript interface for interacting with the Urbanium protocol on Solana mainnet. Fully typed, Anchor-compatible, and designed for enterprise applications.

Installation

npm install @urbanium/sdk @solana/web3.js @coral-xyz/anchor
# or
yarn add @urbanium/sdk @solana/web3.js @coral-xyz/anchor
# or
pnpm add @urbanium/sdk @solana/web3.js @coral-xyz/anchor

Wallet Connection

Initialize the SDK with your Solana connection and wallet:

import { Connection, PublicKey } from '@solana/web3.js';
import { AnchorProvider } from '@coral-xyz/anchor';
import { UrbaniumClient } from '@urbanium/sdk';

// Connect to Solana mainnet
const connection = new Connection(
  'https://api.mainnet-beta.solana.com',
  'confirmed'
);

// Initialize provider with wallet
const provider = new AnchorProvider(
  connection,
  wallet, // Your wallet adapter
  { commitment: 'confirmed' }
);

// Create Urbanium client
const urbanium = new UrbaniumClient(provider);

Vault Creation

Create a new vault for a specific token:

import { PublicKey } from '@solana/web3.js';

// Token mint address (e.g., USDC)
const tokenMint = new PublicKey('EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v');

// Create vault
const { vault, vaultAuthority, signature } = await urbanium.createVault({
  tokenMint,
  name: 'USDC Yield Vault',
});

console.log('Vault created:', vault.toString());
console.log('Authority:', vaultAuthority.toString());
console.log('Transaction:', signature);

Deposit to Vault

Deposit tokens into a vault and receive vault tokens:

import { BN } from '@coral-xyz/anchor';

// Vault address
const vaultAddress = new PublicKey('...');

// Amount to deposit (in token decimals, e.g., 1000 USDC = 1000 * 10^6)
const amount = new BN(1000_000_000); // 1000 USDC

// Deposit tokens
const { userPosition, shares, signature } = await urbanium.deposit({
  vault: vaultAddress,
  amount,
});

console.log('Deposited successfully');
console.log('Position:', userPosition.toString());
console.log('Shares received:', shares.toString());
console.log('Transaction:', signature);

Withdraw from Vault

Redeem vault tokens to withdraw underlying assets:

// Shares to redeem
const sharesToRedeem = new BN(500_000_000); // Half of position

// Withdraw assets
const { assets, signature } = await urbanium.withdraw({
  vault: vaultAddress,
  shares: sharesToRedeem,
});

console.log('Withdrawn successfully');
console.log('Assets received:', assets.toString());
console.log('Transaction:', signature);

// Or withdraw all
const { assets: allAssets } = await urbanium.withdrawAll({
  vault: vaultAddress,
});

Fetch Oracle Price

Get current oracle price for a token pair:

// Get price from oracle
const price = await urbanium.getOraclePrice({
  baseMint: new PublicKey('...'), // Token A
  quoteMint: new PublicKey('...'), // Token B
});

console.log('Price:', price.price.toString());
console.log('Confidence:', price.confidence.toString());
console.log('Timestamp:', new Date(price.timestamp * 1000));
console.log('Decimals:', price.decimals);

// Check if price is fresh (< 60 seconds old)
const isFresh = Date.now() / 1000 - price.timestamp < 60;
console.log('Price is fresh:', isFresh);

Execute Yield Routing

Trigger yield routing for a vault (typically called by keepers):

// Analyze available strategies
const strategies = await urbanium.analyzeStrategies({
  vault: vaultAddress,
});

console.log('Available strategies:', strategies);

// Execute optimal rebalancing
const { newAllocations, signature } = await urbanium.rebalanceVault({
  vault: vaultAddress,
  strategies: strategies.slice(0, 3), // Use top 3 strategies
});

console.log('Vault rebalanced');
console.log('New allocations:', newAllocations);
console.log('Transaction:', signature);

PDA Derivation

Understand how Program Derived Addresses are calculated:

// Derive vault PDA
const [vaultPDA, vaultBump] = await PublicKey.findProgramAddress(
  [
    Buffer.from('vault'),
    tokenMint.toBuffer(),
    creator.toBuffer(),
  ],
  urbanium.programId
);

// Derive vault authority PDA
const [authorityPDA, authorityBump] = await PublicKey.findProgramAddress(
  [
    Buffer.from('vault-authority'),
    vaultPDA.toBuffer(),
  ],
  urbanium.programId
);

// Derive user position PDA
const [positionPDA, positionBump] = await PublicKey.findProgramAddress(
  [
    Buffer.from('user-position'),
    vaultPDA.toBuffer(),
    userWallet.toBuffer(),
  ],
  urbanium.programId
);

console.log('Vault PDA:', vaultPDA.toString());
console.log('Authority PDA:', authorityPDA.toString());
console.log('Position PDA:', positionPDA.toString());

Vault Authority Usage

The vault authority is a PDA that signs yield operations:

// Vault authority is derived deterministically
// It has no private key - only the program can sign with it

// The authority is used to:
// 1. Sign yield strategy deposits
// 2. Sign strategy withdrawals
// 3. Execute rebalancing operations
// 4. Approve oracle-based swaps

// Example: The program signs with vault authority internally
await program.methods
  .executeYieldStrategy()
  .accounts({
    vault: vaultPDA,
    vaultAuthority: authorityPDA, // PDA signer
    strategy: strategyAddress,
    // ... other accounts
  })
  .rpc();

// Users CANNOT sign as vault authority
// Only program logic can invoke this PDA as a signer

Error Handling

Handle errors gracefully in production:

import { UrbaniumError } from '@urbanium/sdk';

try {
  await urbanium.deposit({
    vault: vaultAddress,
    amount: depositAmount,
  });
} catch (error) {
  if (error instanceof UrbaniumError) {
    switch (error.code) {
      case 'InsufficientBalance':
        console.error('Not enough tokens to deposit');
        break;
      case 'InvalidVaultAuthority':
        console.error('Vault authority mismatch');
        break;
      case 'StaleOraclePrice':
        console.error('Oracle price too old, try again');
        break;
      case 'SlippageExceeded':
        console.error('Price moved too much, adjust slippage');
        break;
      default:
        console.error('Urbanium error:', error.message);
    }
  } else {
    console.error('Unexpected error:', error);
  }
}

Complete Example

Full workflow from connection to withdrawal:

import { Connection, PublicKey, Keypair } from '@solana/web3.js';
import { AnchorProvider, BN } from '@coral-xyz/anchor';
import { UrbaniumClient } from '@urbanium/sdk';

async function main() {
  // 1. Setup connection
  const connection = new Connection('https://api.mainnet-beta.solana.com');
  const wallet = /* your wallet adapter */;
  const provider = new AnchorProvider(connection, wallet, {});
  const urbanium = new UrbaniumClient(provider);

  // 2. Create vault
  const usdcMint = new PublicKey('EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v');
  const { vault } = await urbanium.createVault({
    tokenMint: usdcMint,
    name: 'My USDC Vault',
  });

  // 3. Deposit funds
  const depositAmount = new BN(1000_000_000); // 1000 USDC
  const { shares } = await urbanium.deposit({
    vault,
    amount: depositAmount,
  });
  
  console.log('Deposited 1000 USDC, received', shares.toString(), 'shares');

  // 4. Wait for yield generation...
  await new Promise(resolve => setTimeout(resolve, 60000));

  // 5. Check position value
  const position = await urbanium.getUserPosition({ vault });
  console.log('Current value:', position.value.toString());

  // 6. Withdraw all
  const { assets } = await urbanium.withdrawAll({ vault });
  console.log('Withdrew', assets.toString(), 'USDC');
}

main().catch(console.error);

Ready to Build?

The Urbanium SDK is production-ready and fully typed. Start integrating today.