August Digital SDK
TypeScript SDK for interacting with August Digital vaults across EVM, Solana, Stellar, and Sui chains.
Installation
npm install @augustdigital/sdk ethers
# or
pnpm add @augustdigital/sdk ethers
# or
yarn add @augustdigital/sdk ethers
Wagmi/Viem Support
The SDK supports both ethers and wagmi/viem signers. If you're using wagmi in your React app, also install viem:
npm install viem
The SDK automatically converts viem WalletClient to an ethers-compatible signer.
Quick Start
import AugustSDK from '@augustdigital/sdk';
const sdk = new AugustSDK({
// Required: stable kebab-case slug identifying your application.
appName: 'acme-trader',
providers: {
1: 'https://eth-mainnet.g.alchemy.com/v2/YOUR_KEY',
42161: 'https://arb-mainnet.g.alchemy.com/v2/YOUR_KEY',
-1: 'https://api.mainnet-beta.solana.com', // Solana
},
keys: {
august: 'YOUR_API_KEY', // Optional: vault reads, allocations and vault-linked sub-account reads work without it
},
monitoring: {
env: 'DEV', // Optional: 'DEV' enables console logging (defaults to 'PROD')
},
});
// Fetch all vaults
const vaults = await sdk.getVaults();
// Fetch a specific vault with loans and allocations
const vault = await sdk.getVault({
vault: '0x...',
options: { loans: true, allocations: true },
});
// Get user positions
const positions = await sdk.getVaultPositions({
wallet: '0x...',
showAllVaults: true,
});
App Name
appName is required on every AugustSDK constructor call. Pass a stable kebab-case slug
identifying your application (e.g. 'acme-trader', 'my-defi-app'):
- What it's used for. August Digital tags analytics events with
app.name = <yourSlug>to attribute error spikes and prioritize bug fixes by consuming app. - What it is not. Not a secret, not a license key, not a display label. Pick a slug once and reuse it across deployments.
- Constraints. 3–64 characters, only
[a-zA-Z0-9._-]. The SDK throws synchronously from the constructor if the value is missing or invalid.
// Will throw — appName is required.
new AugustSDK({ providers: { /* ... */ } } as any);
// Will throw — spaces not allowed. Use 'acme-trader'.
new AugustSDK({ appName: 'Acme Trader', providers: { /* ... */ } });
// Correct.
new AugustSDK({ appName: 'acme-trader', providers: { /* ... */ } });
Origin-Code Attribution (SwapRouter)
An integrator with an origin (referral / fee-sharing) code registered on the SwapRouter sets it once on the SDK instance. Deposits made through the SDK then carry it on-chain:
const sdk = new AugustSDK({
appName: 'acme-trader',
providers: { 1: 'https://eth-mainnet.g.alchemy.com/v2/YOUR_KEY' },
attribution: {
originCode: '0x…', // bytes32 registered on the SwapRouter with addOrigin
strictOrigin: false, // optional: true throws instead of falling back
},
});
// Check the code before you ship it.
const { registered, originFeeBps, collector } = await sdk.getOriginInfo({
chainId: 1,
originCode: '0x…',
});
-
Ethereum mainnet only. The instance code is sent on chain 1 (
ORIGIN_ATTRIBUTION_CHAINS) and on no other chain, even where a SwapRouter is configured. -
Where it applies.
vaultDepositsends a deposit throughSwapRouter.depositwith the code whensdk.evm.getDepositRoute()returnsvia: 'router': the vault is registered on the router, the vault accepts the asset as-is (its reference asset, or a Tokenized Vault V2 whitelisted asset — never swapped), the router whitelists the asset, the router is not paused, the deposit is not a permit, native-token or adapter deposit, and the code is registered.swapRouterDeposit,swapAndDeposit,depositViaSwapRouteranddepositNativeViaSwapRoutersend it too. -
Precedence. An
originCodepassed to a router method wins, then the instance code, then the all-zero sentinel (no origin fee). Pass the zero sentinel to opt one call out. -
Fallback. When the code cannot be applied — it is not registered, the chain is not mainnet, the router is paused (
router-paused, checked with a 15-second cache) or does not whitelist the asset, the vault does not accept it or is not registered on the router, or it is a permit, native-token or adapter deposit —vaultDeposittakes the vault's native path and logsvaultDeposit:attribution-skippedwith the reason (Sentry tagsdk.attribution.origin=skipped). The router methods send the zero sentinel for an unregistered instance code and log<method>:attribution-skipped. WithstrictOrigin: truean unregistered instance code throwsAugustValidationErrorbefore any approval instead; a paused router falls back to native even then. AnoriginCodepassed to a router method that is not registered always throwsAugustValidationErrorbefore any approval. While the router is paused, the router methods throwAugustSDKError(context.reason: 'router-paused') before any approval. -
Approve
route.spender, not the vault. A routed deposit is pulled by the SwapRouter.vaultDepositandapprovehandle this; if you send approvals yourself, read the spender first:const route = await sdk.evm.getDepositRoute({ target: vault, depositAsset: usdc }); // route.spender is the SwapRouter when route.via === 'router', else the vault (or adapter wrapper) -
Gas. Measured on a mainnet fork (repeat 1,000 USDC deposits into Core USDC): direct deposit 102,067 gas; router with a 0% code 161,744 (+59.7k); router with a 1% code 173,135 (+71.1k). A routed deposit also needs a one-time approval of the router per token.
-
Zero-fee codes. A code registered with a 0 bps fee is valid for attribution only, but the router emits no
OriginFeeAppliedevent for it. Its deposits are attributable only from the transaction calldata and SDK telemetry. -
Process-global.
attributionis process-global: the lastAugustSDKconstructed wins, and one constructed withoutattributionclears it. Run one attribution configuration per process.
Architecture
src.ts/
├── main.ts # Main SDK class (AugustSDK)
├── core/ # Base utilities
│ ├── base.class.ts # Base SDK functionality
│ ├── fetcher.ts # API client with retry logic
│ └── web3.helpers.ts # Blockchain utilities
├── adapters/ # Chain-specific implementations
│ ├── evm/ # EVM adapter (approve, deposit, redeem, read helpers)
│ ├── solana/ # Solana program adapters
│ ├── stellar/ # Stellar vault adapters
│ └── sui/ # Sui (Ember) vault adapters
├── evm/ # EVM cross-chain (LayerZero OVault)
├── modules/ # Feature modules
│ ├── vaults/ # Vault read operations
│ ├── sub-accounts/ # Sub-account queries
│ └── api/ # August backend API integration
├── services/ # External service integrations
│ ├── debank/ # DeFi allocation data
│ ├── coingecko/ # Token pricing
│ └── subgraph/ # Historical transaction data
└── types/ # TypeScript interfaces
Key Concepts
Multi-Chain Support
- EVM Chains: Ethereum, Arbitrum, Base, BSC, Avalanche, and more —
wagmi/viemandetherssigners supported - Solana: Native Solana program support with full vault functionality
- Stellar: Stellar vault deposit, redeem, and position queries
- Sui: Ember vault read operations
- Unified interface across all chains
Vault Versions
evm-0/evm-1: Legacy vault contractsevm-2: Current EVM vault architecture (separate receipt tokens)sol-0: Solana program-based vaultsstellar-0: Stellar-based vaults
Data Enrichment
All vault queries support optional enrichment:
loans: Include active loan dataallocations: DeFi/CeFi/OTC position breakdownswallet: User-specific position data
API Reference
Vault Queries
| Method | Description |
|---|---|
getVaults(options?) | Fetch all vaults across chains |
getVault({ vault, chainId?, options? }) | Get single vault details |
getVaultLoans({ vault, chainId? }) | Fetch active loans |
getVaultAllocations({ vault, chainId? }) | Get allocation breakdown |
getVaultHistoricalTimeseries({ vault, chainId? }) | Historical APY and TVL timeseries |
getVaultApy({ vault, historical? }) | @deprecated — use getVaultHistoricalTimeseries |
getVaultTvl({ vault, historical? }) | Current/historical TVL |
getVaultAnnualizedApy({ vault }) | Annualized APY for a vault |
getVaultSummary({ vault }) | Aggregated vault summary |
getVaultPnl({ vault, chainId? }) | Vault-level PnL |
getVaultUnrealizedPnlHistory({ vault, chainId?, ... }) | Unrealized PnL timeseries |
getLatestUnrealizedPnl() | Latest unrealized PnL snapshot across all vaults |
getYieldLastRealizedOn({ vault, chainId? }) | Timestamp of last yield realization |
getTotalDeposited(options?) | Total deposited across vaults |
User Positions
| Method | Description |
|---|---|
getVaultPositions({ wallet?, vault?, chainId? }) | User vault positions |
getVaultAvailableRedemptions({ vault, wallet?, chainId, verbose? }) | Claimable redemptions |
getVaultRedemptionHistory({ vault, wallet?, chainId? }) | Historical redemptions |
getVaultUserHistory({ wallet, vault?, chainId? }) | Transaction history |
getVaultUserTransfers({ wallet, vault?, chainId? }) | Transfer history |
getVaultUserLifetimePnl({ wallet, vault?, chainId? }) | Lifetime PnL for a wallet |
getVaultStakingPositions({ wallet, chainId }) | Staking positions |
getVaultBorrowerHealthFactor(props?) | Borrower health factor |
getVaultWithdrawals({ vault, chainId? }) | Pending withdrawals |
Points
| Method | Description |
|---|---|
getUserPoints(userAddress) | Points balance for a wallet |
registerUserForPoints({ wallet, referral? }) | Register a wallet for the points program |
fetchPointsLeaderboard(params?) | Points leaderboard |
Write Operations (top-level)
| Method | Description |
|---|---|
vaultDeposit(signer, options) | Deposit into a vault |
previewRedemption(props) | Preview redemption output before broadcasting |
Cross-Chain (LayerZero)
| Method | Description |
|---|---|
getLayerZeroDeposits({ wallet?, chainId? }) | LayerZero deposit history |
getLayerZeroRedeems(props?) | LayerZero redemption history |
Utilities
| Method | Description |
|---|---|
getPrice(symbol) | Token price in USD |
switchNetwork(chainId) | Change active chain |
updateWallet(address) | Set active wallet for tracking |
Sub-Accounts (sdk.subAccountsModule)
| Method | Description |
|---|---|
getSubaccountHealthFactor(address) | Health factor for a sub-account |
getSubaccountLoans(address) | Active loans for a sub-account |
getSubaccountCefiPositions(address) | CeFi positions |
getSubaccountOtcPositions(address) | OTC positions |
getSubaccountSummary(address) | Aggregated sub-account summary |
EVM Adapter (sdk.evm)
Set a signer before calling write methods:
// ethers
import { JsonRpcProvider, Wallet } from 'ethers';
const wallet = new Wallet(process.env.PRIVATE_KEY!, new JsonRpcProvider(rpcUrl));
sdk.evm.setSigner(wallet);
// wagmi/viem (browser)
import { useWalletClient } from 'wagmi';
const { data: walletClient } = useWalletClient();
if (walletClient) sdk.evm.setSigner(walletClient);
Write methods:
| Method | Description |
|---|---|
vaultApprove(options) | Approve token spend for a vault |
approve(options) | Generic ERC-20 approve |
vaultDeposit(options) | Deposit assets into a vault |
vaultRequestRedeem(options) | Request a withdrawal/redemption |
vaultRedeem(signer, options) | Claim an available redemption |
depositNative(options) | Deposit native tokens (ETH, etc.) |
swapAndDeposit(options) | Swap and deposit in one call |
depositViaSwapRouter(options) | Deposit via the swap router |
depositNativeViaSwapRouter(options) | Deposit native via the swap router |
Read helpers (return raw bigint):
| Method | Description |
|---|---|
previewDeposit(options) | Shares minted for a deposit amount |
previewRedeem(options) | Assets returned for a share amount |
allowance(options) | ERC-20 allowance granted to the vault |
balanceOf(options) | ERC-20 balance for any token/owner |
maxDeposit(options) | Maximum deposit accepted by the vault |
vaultAllowance(options) | Vault-specific allowance check |
getDeposited(options) | Current deposited balance |
getRemainingAllocations(options) | Remaining allocation capacity |
isWhitelisted(options) | Check whitelist status |
Solana Adapter (sdk.solana)
| Method | Description |
|---|---|
getVaultState(...) | Vault state from the Solana program |
getVaultStateReadOnly(...) | Read-only vault state |
getToken(mintAddress) | SPL token info |
getTokenSymbol(mintAddress) | Token symbol |
fetchUserTokenBalance(publicKey, mint) | User SPL token balance |
fetchUserShareBalance(publicKey, vault) | User share balance |
fetchUserShareBalanceRaw(publicKey, vault) | Raw share balance (bigint) |
Stellar Adapter (sdk.stellar)
| Method | Description |
|---|---|
vaultDeposit(options) | Deposit into a Stellar vault |
vaultRedeem(options) | Redeem from a Stellar vault |
submitTransaction(signedXdr) | Submit a signed XDR transaction |
getUserPosition(options) | User position in a Stellar vault |
convertToShares(options) | Convert an asset amount to shares |
Sui Adapter (sdk.sui)
| Method | Description |
|---|---|
getEmberVaults() | List all Ember (Sui) vaults |
getEmberTVL(limit?) | Total value locked across Ember vaults |
Code Conventions
Naming Patterns
- Interfaces: Prefixed with
I(e.g.,IVault,IVaultLoan) - ABIs: Prefixed with
ABI_(e.g.,ABI_LENDING_POOL_V2) - Types: Descriptive names (e.g.,
IAddress,IChainId)
Special Comment Tags
Search the codebase for these to find important areas:
@todo: Planned improvements or missing features@hardcoded: Hardcoded values that may need configuration@solana: Solana-specific logic or notes
Error Handling
Every public method throws typed errors that subclass AugustSDKError:
import { AugustValidationError, AugustTimeoutError, AugustSDKError } from '@augustdigital/sdk';
try {
await sdk.evm.vaultDeposit({ target: '0x...', wallet: owner, amount: '1' });
} catch (err) {
if (err instanceof AugustValidationError) showFormError(err.message);
else if (err instanceof AugustTimeoutError) scheduleRetry(err.timeoutMs);
else if (err instanceof AugustSDKError) reportError(err.code, err.cause);
else throw err;
}
- Automatic retry with exponential backoff for network errors
- 90-second request timeout (configurable via
REQUEST_TIMEOUT_MS) - Correlation IDs in errors for debugging
Environment Configuration
// Development mode — enables console logging
const sdk = new AugustSDK({ appName: 'my-app', providers: { /* ... */ }, monitoring: { env: 'DEV' } });
// Production mode — default, no console logs
const sdk = new AugustSDK({ appName: 'my-app', providers: { /* ... */ } });
Development
Running Tests
pnpm test
Building
pnpm build
Support
- Issues: GitHub Issues
- Documentation: docs.augustdigital.io
- Example App: starter.upshift.finance