UpshiftDocs

Quick Start

Install @augustdigital/sdk, read vault data, and build deposit, withdraw and claim transactions on EVM chains, Solana and Stellar.

SDK Quickstart

@augustdigital/sdk is the TypeScript SDK for Upshift vaults. One client reads vault data on every supported chain and builds the deposit, withdrawal and claim transactions. Your user's wallet signs every transaction. The SDK never holds keys or funds.

This page takes you from install to a first deposit and withdrawal on each chain type. For the full method list, see the SDK API Reference. Code on this page was checked against version 9.9.1.

1. Install

npm install @augustdigital/sdk

The SDK has viem (v2) as a peer dependency. For EVM writes you can pass an ethers signer or a viem / wagmi wallet client.

To call the SDK from a browser on your own domain, ask Upshift to add your origin to the allow-list. Otherwise CORS blocks the requests.

2. Initialize

AugustSDK is the default export. appName is required: a stable kebab-case slug for your app, 3 to 64 characters of [a-zA-Z0-9._-].

import AugustSDK from '@augustdigital/sdk';

const sdk = new AugustSDK({
  appName: 'acme-earn',
  providers: {
    1: 'https://eth-mainnet.g.alchemy.com/v2/YOUR_KEY',     // Ethereum
    42161: 'https://arb-mainnet.g.alchemy.com/v2/YOUR_KEY', // Arbitrum
    -1: 'https://api.mainnet-beta.solana.com',              // Solana (chain ID -1)
  },
});
  • Add one RPC URL per EVM chain you use. The first entry is the chain the SDK starts on.
  • Add chain ID -1 for Solana.
  • Stellar needs no provider entry. sdk.stellar runs against Stellar mainnet by default.

3. Read vault data

// Every vault, all chains
const vaults = await sdk.getVaults();

// One vault
const vault = await sdk.getVault({
  vault: '0x80E1048eDE66ec4c364b4F22C8768fc657FF6A42', // Upshift USDC
  chainId: 1,
});

console.log(vault.name, vault.receipt.symbol);
console.log('APY %:', vault.apy.apy);
console.log('Total assets:', vault.totalAssets.normalized);
console.log('Deposit assets:', vault.depositAssets.map((a) => a.symbol));
console.log('Withdrawal period (s):', vault.lagDuration);
console.log('Paused:', vault.isDepositPaused, vault.isWithdrawalPaused);

Amounts come back as INormalizedNumber: { normalized, raw }. Use raw for math and normalized for display.

Other reads you will use often:

MethodReturns
getVaultApy({ vault, chainId })APY history
getVaultTvl({ vault, chainId })TVL history
getVaultAllocations({ vault, chainId })Where the vault's capital is deployed
getVaultPositions({ wallet, solanaWallet, stellarWallet })A user's positions across chains
getVaultAvailableRedemptions({ vault, chainId, wallet })Pending and claimable redemptions
getVaultUserLifetimePnl({ vault, wallet })A user's lifetime PnL in a vault

APY and performance figures are informational and vary with markets. Check anything you act on against the onchain state.

4. EVM: deposit, withdraw, claim

Connect a signer

import { BrowserProvider } from 'ethers';

const provider = new BrowserProvider(window.ethereum);
const signer = await provider.getSigner();
sdk.evm.setSigner(signer); // also accepts a viem / wagmi WalletClient

const wallet = await signer.getAddress();
const target = '0x80E1048eDE66ec4c364b4F22C8768fc657FF6A42';

Deposit

// Optional: preview the shares (raw units in, raw bigint out)
const shares = await sdk.evm.previewDeposit({ vault: target, amount: 100_000_000n });

const txHash = await sdk.evm.vaultDeposit({
  target,
  wallet,
  amount: '100', // 100 USDC, human units
  wait: true,
});

vaultDeposit detects the vault version and approves the token if needed. On a multi-asset vault, pass depositAsset with the address of the token you deposit:

await sdk.evm.vaultDeposit({
  target: multiAssetVault,
  wallet,
  amount: '100',
  depositAsset: '0xdAC17F958D2ee523a2206206994597C13D831ec7', // USDT
  chainId: 1,
  wait: true,
});

A multi-asset vault accepts several deposit assets but has one reference asset. Every redemption pays out in the reference asset.

Request a withdrawal

// Queued redemption: claimable after the vault's withdrawal period
await sdk.evm.vaultRequestRedeem({
  target,
  wallet,
  amount: '50', // shares
  wait: true,
});

// Instant redemption, on vaults that support it.
// Charges the instant redemption fee and depends on available liquidity.
await sdk.evm.vaultRequestRedeem({
  target,
  wallet,
  amount: '50',
  isInstantRedeem: true,
  wait: true,
});

Claim a matured redemption

Upshift processes claimable redemptions daily. If a request is still claimable, the user can claim it directly. Find the matured batch first:

const { availableRedemptions } = await sdk.getVaultAvailableRedemptions({
  vault: target,
  chainId: 1,
  wallet,
});

const r = availableRedemptions[0];
if (r) {
  if (vault.version === 'evm-2') {
    // Multi-asset (Tokenized Vault V2) vaults
    await sdk.evm.claimWithdrawal({
      target,
      wallet,
      year: r.year.raw,
      month: r.month.raw,
      day: r.day.raw,
      wait: true,
    });
  } else {
    // evm-0 / evm-1 vaults
    await sdk.evm.vaultRedeem({
      target,
      wallet,
      year: r.year.raw,
      month: r.month.raw,
      day: r.day.raw,
      receiverIndex: '0',
      wait: true,
    });
  }
}

5. Solana: deposit and redeem

Solana redemptions settle in the same transaction, so there is no claim step.

import { Solana } from '@augustdigital/sdk';
import { useWallet } from '@solana/wallet-adapter-react';

const { publicKey, signTransaction } = useWallet();
sdk.solana.setWalletProvider(publicKey, signTransaction);

const programId = Solana.constants.programIds['mainnet-beta'].vault;
const idl = Solana.constants.vaultIdl;
const vaultAddress = 'VaultStateAccount...'; // the vault's address from getVaults()

// Deposit 100 tokens (number = UI amount, bigint = raw units)
const depositSig = await sdk.solana.vaultDeposit(
  programId, idl, publicKey, 100,
  undefined,    // deprecated argument: pass undefined, do not delete it
  vaultAddress,
);

// Redeem 50 shares
const redeemSig = await sdk.solana.vaultRedeem(
  programId, idl, publicKey, 50,
  undefined,
  vaultAddress,
);

Keep the undefined in the fifth position. If you delete it, vaultAddress moves into that slot and the SDK targets a different vault. Both calls apply a 50 bps slippage floor by default. Pass { slippageBps } or { minAssetsOut } as the last argument to change it.

6. Stellar: deposit and redeem

Stellar writes follow build, sign, submit. The SDK returns an unsigned XDR string, the user's wallet signs it, and the SDK submits it. Stellar vaults are instant-redeem only, so there is no claim step.

import { signTransaction } from '@stellar/freighter-api';

const contractId = 'C...'; // Stellar vault contract ID
const user = 'G...';       // user's Stellar account

// Deposit 1 USDC (7 decimals on Stellar), in smallest units
const depositXdr = await sdk.stellar.vaultDeposit({
  contractId,
  amount: '10000000',
  senderAddress: user,
});
const { signedTxXdr } = await signTransaction(depositXdr, { networkPassphrase: '...' });
const depositHash = await sdk.stellar.submitTransaction(signedTxXdr);

// Redeem: size the redeem from the onchain position
const position = await sdk.stellar.getUserPosition(contractId, user);
if (!position || position.decimalsFromFallback) {
  throw new Error('Could not read share decimals. Retry before redeeming.');
}
const redeemXdr = await sdk.stellar.vaultRedeem({
  contractId,
  shares: position.shares,
  receiverAddress: user,
});
// sign redeemXdr with the wallet, then:
// await sdk.stellar.submitTransaction(signedRedeemXdr);

To find a Stellar vault's contract ID, list vaults and filter to Stellar. The Stellar Actions page filters on chain_type === 'stellar'.

7. Handle errors

Every public method throws typed errors that extend AugustSDKError.

import { AugustValidationError, AugustTimeoutError, AugustSDKError } from '@augustdigital/sdk';

try {
  await sdk.evm.vaultDeposit({ target, wallet, amount: '1' });
} catch (err) {
  if (err instanceof AugustValidationError) showFormError(err.message);
  else if (err instanceof AugustTimeoutError) scheduleRetry();
  else if (err instanceof AugustSDKError) report(err.code);
  else throw err;
}

See Error Handling.

Next steps