TypeScript Types
Copy-paste these interfaces to type API responses in your integration.
Response Envelopes
interface ApiSuccess<T> {
ok: true;
data: T;
}
interface ApiPaginated<T> {
ok: true;
data: T[];
meta: {
page: number;
pageSize: number;
total: number;
totalPages: number;
};
}
interface ApiError {
ok: false;
error: {
code: string;
message: string;
};
}
type ApiResponse<T> = ApiSuccess<T> | ApiError;
type ApiPaginatedResponse<T> = ApiPaginated<T> | ApiError;
Domain Models
Vault
interface Vault {
address: string;
asset: string;
assetDecimals: number;
name: string;
symbol: string;
totalAssets: string;
managedAssets: string;
totalSupply: string;
pricePerShare: string;
depositCap: string;
unrealizedFees: string;
omnibusAddress: string | null;
isPaused: boolean;
createdAt: string;
updatedAt: string;
}
interface VaultDetail extends Vault {
stats: {
userCount: number;
pendingWithdrawals: number;
lastSweepAt: string | null;
lastNavAt: string | null;
};
}
Deposit
interface Deposit {
id: number;
txHash: string;
blockNumber: string;
logIndex: number;
timestamp: string;
userAddress: string;
vaultAddress: string;
assetAmount: string;
sharesMinted: string;
partnerId?: number | null; // Set when deposited via the vault's referral overload (partnerId arg)
}
Partner Stats
interface PartnerStats {
partnerId: number;
partnerName: string;
totalDeposits: number;
totalVolume: string;
uniqueUsers: number;
byVault: Array<{
vaultAddress: string;
depositCount: number;
totalVolume: string;
}>;
}
interface RouterInfo {
routerAddress: string | null;
chainId: number;
}
Withdrawal Request
interface WithdrawalRequest {
id: number;
txHash: string;
blockNumber: string;
logIndex: number;
timestamp: string;
userAddress: string;
vaultAddress: string;
requestIndex: number;
shares: string;
assetsEstimate: string; // estimated at request time; recomputed at payout
claimableAt: string | null;
claimed: boolean;
claimedAt: string | null;
claimTxHash: string | null;
cancelled: boolean;
cancelledAt: string | null;
}
type WithdrawalStatus = "queued" | "claimed" | "cancelled";
NAV History
interface NavHistory {
id: number;
txHash: string;
blockNumber: string;
logIndex: number;
vaultAddress: string;
timestamp: string;
managedAssets: string;
pricePerShare: string;
totalAssets: string;
totalShares: string;
}
User
interface User {
address: string;
firstSeen: string;
totalDeposited: string;
totalWithdrawn: string;
partnerSource: string | null; // name of the partner that first referred this user
createdAt: string;
updatedAt: string;
}
Helper: Type-Safe API Client
async function apiGet<T>(path: string, apiKey?: string): Promise<T> {
const headers: Record<string, string> = {};
if (apiKey) headers["x-api-key"] = apiKey;
const res = await fetch(`https://api.emeraldvaults.io${path}`, { headers });
const json = await res.json();
if (!json.ok) {
throw new Error(`API error ${json.error.code}: ${json.error.message}`);
}
return json.data;
}
// Usage
const vaults = await apiGet<Vault[]>("/api/v1/vaults");
const vault = await apiGet<VaultDetail>("/api/v1/vaults/0x...");
Helper: Paginated Fetch
async function apiPaginated<T>(
path: string,
params?: Record<string, string>,
apiKey?: string,
): Promise<{ data: T[]; meta: { page: number; pageSize: number; total: number; totalPages: number } }> {
const url = new URL(`https://api.emeraldvaults.io${path}`);
if (params) {
for (const [k, v] of Object.entries(params)) url.searchParams.set(k, v);
}
const headers: Record<string, string> = {};
if (apiKey) headers["x-api-key"] = apiKey;
const res = await fetch(url, { headers });
const json = await res.json();
if (!json.ok) {
throw new Error(`API error ${json.error.code}: ${json.error.message}`);
}
return { data: json.data, meta: json.meta };
}
// Usage
const { data: deposits, meta } = await apiPaginated<Deposit>(
"/api/v1/users/0x.../deposits",
{ page: "1", pageSize: "50" },
);
console.log(`Page ${meta.page} of ${meta.totalPages}`);