Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
49 changes: 49 additions & 0 deletions etc/data-models.api.md
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,51 @@ export enum Chain {
SUI = "SUI"
}

// @public
export enum DeFiDiscoverySource {
CONTRACT_QUERY = "CONTRACT_QUERY",
WALLET_TOKEN_SCAN = "WALLET_TOKEN_SCAN"
}

// @public
export interface DeFiPosition {
apy?: number;
chain: Chain;
discoverySource?: DeFiDiscoverySource;
id: string;
metadata?: Metadata;
protocol: DeFiProtocol;
rewards: Balance[];
type: DeFiPositionType;
underlyingAssets: Balance[];
value?: Price;
}

// @public
export enum DeFiPositionType {
FARMING = "FARMING",
LENDING_BORROW = "LENDING_BORROW",
LENDING_SUPPLY = "LENDING_SUPPLY",
LIQUIDITY_POOL = "LIQUIDITY_POOL",
PERP_POSITION = "PERP_POSITION",
STAKING = "STAKING",
VAULT = "VAULT"
}

// @public
export enum DeFiProtocol {
AAVE = "AAVE",
BEEFY = "BEEFY",
COMPOUND = "COMPOUND",
JUPITER = "JUPITER",
LIDO = "LIDO",
MARINADE = "MARINADE",
ORCA = "ORCA",
OTHER = "OTHER",
RAYDIUM = "RAYDIUM",
UNISWAP = "UNISWAP"
}

// @public
export interface EnvironmentConfig {
chain: Chain;
Expand Down Expand Up @@ -184,6 +229,7 @@ export interface LendingPosition {
apy?: number;
asset: Asset;
chain: Chain;
discoverySource?: DeFiDiscoverySource;
healthFactor?: number;
id: string;
liquidationThreshold?: number;
Expand All @@ -202,6 +248,7 @@ export enum LendingPositionType {
// @public
export interface LiquidityPosition {
chain: Chain;
discoverySource?: DeFiDiscoverySource;
feesEarned?: number;
id: string;
impermanentLoss?: number;
Expand Down Expand Up @@ -320,6 +367,7 @@ export interface StakedPosition {
apr?: number;
asset: Asset;
chain: Chain;
discoverySource?: DeFiDiscoverySource;
id: string;
lockupPeriod?: number;
metadata?: Metadata;
Expand Down Expand Up @@ -409,6 +457,7 @@ export interface VaultPosition {
chain: Chain;
depositAsset: Asset;
depositedAmount: string;
discoverySource?: DeFiDiscoverySource;
id: string;
metadata?: Metadata;
pricePerShare?: number;
Expand Down
4 changes: 2 additions & 2 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

20 changes: 20 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,26 @@
"import": "./dist/enums/LendingPositionType.js",
"require": "./dist/cjs/enums/LendingPositionType.js"
},
"./enums/VaultStrategyType": {
"types": "./dist/enums/VaultStrategyType.d.ts",
"import": "./dist/enums/VaultStrategyType.js",
"require": "./dist/cjs/enums/VaultStrategyType.js"
},
"./enums/DeFiPositionType": {
"types": "./dist/enums/DeFiPositionType.d.ts",
"import": "./dist/enums/DeFiPositionType.js",
"require": "./dist/cjs/enums/DeFiPositionType.js"
},
"./enums/DeFiProtocol": {
"types": "./dist/enums/DeFiProtocol.d.ts",
"import": "./dist/enums/DeFiProtocol.js",
"require": "./dist/cjs/enums/DeFiProtocol.js"
},
"./enums/DeFiDiscoverySource": {
"types": "./dist/enums/DeFiDiscoverySource.d.ts",
"import": "./dist/enums/DeFiDiscoverySource.js",
"require": "./dist/cjs/enums/DeFiDiscoverySource.js"
},
"./interfaces/*": {
"types": "./dist/interfaces/*.d.ts",
"import": "./dist/interfaces/*.js",
Expand Down
34 changes: 34 additions & 0 deletions src/enums/DeFiDiscoverySource.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
/**
* How a DeFi position was discovered during portfolio scanning.
*
* Distinguishes between positions found by scanning wallet token balances
* (receipt tokens like aTokens, cTokens, LP tokens) versus positions found
* by querying protocol smart contract state directly.
*
* This distinction matters for reconciliation: wallet-scanned positions are
* inferred from token holdings, while contract-queried positions come from
* authoritative on-chain state.
*
* @example
* ```typescript
* import { DeFiDiscoverySource } from '@cygnus-wealth/data-models';
*
* // Found aUSDC in wallet — infer Aave supply position
* const walletDiscovered = DeFiDiscoverySource.WALLET_TOKEN_SCAN;
*
* // Queried Aave LendingPool.getUserAccountData() directly
* const contractDiscovered = DeFiDiscoverySource.CONTRACT_QUERY;
* ```
*
* @since 1.3.0
* @stability extended
*
* @see {@link DeFiPosition} for usage in position interfaces
*/
export enum DeFiDiscoverySource {
/** Position inferred from receipt/derivative tokens found in wallet balance scan */
WALLET_TOKEN_SCAN = 'WALLET_TOKEN_SCAN',

/** Position discovered by querying protocol smart contract state directly */
CONTRACT_QUERY = 'CONTRACT_QUERY'
}
41 changes: 41 additions & 0 deletions src/enums/DeFiPositionType.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
/**
* Classification of DeFi position types across protocols.
*
* Provides a unified taxonomy for all DeFi position categories, enabling
* consistent categorization regardless of the specific protocol. Used as
* a discriminator on the base {@link DeFiPosition} interface.
*
* @example
* ```typescript
* import { DeFiPositionType } from '@cygnus-wealth/data-models';
*
* const positionType = DeFiPositionType.VAULT;
* ```
*
* @since 1.3.0
* @stability extended
*
* @see {@link DeFiPosition} for usage in the base position interface
*/
export enum DeFiPositionType {
/** Yield vault deposit (Yearn, Beefy, Harvest, Sommelier) */
VAULT = 'VAULT',

/** Lending protocol supply position (Aave, Compound — depositing to earn interest) */
LENDING_SUPPLY = 'LENDING_SUPPLY',

/** Lending protocol borrow position (Aave, Compound — borrowing against collateral) */
LENDING_BORROW = 'LENDING_BORROW',

/** AMM liquidity pool position (Uniswap, Curve, Balancer) */
LIQUIDITY_POOL = 'LIQUIDITY_POOL',

/** Proof-of-stake or liquid staking position (Lido, Rocket Pool, native staking) */
STAKING = 'STAKING',

/** Yield farming / incentive mining position (LP rewards, token emissions) */
FARMING = 'FARMING',

/** Perpetual futures or leveraged position (Jupiter, GMX, dYdX) */
PERP_POSITION = 'PERP_POSITION'
}
51 changes: 51 additions & 0 deletions src/enums/DeFiProtocol.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
/**
* Well-known DeFi protocol identifiers for position attribution.
*
* Provides standardized identifiers for major DeFi protocols across chains.
* Extensible via OTHER for protocols not yet explicitly enumerated.
* Protocol-specific version info (e.g., "Aave V3") should be stored in
* position metadata rather than the enum.
*
* @example
* ```typescript
* import { DeFiProtocol } from '@cygnus-wealth/data-models';
*
* const protocol = DeFiProtocol.AAVE;
* ```
*
* @since 1.3.0
* @stability extended
*
* @see {@link DeFiPosition} for usage in position interfaces
*/
export enum DeFiProtocol {
/** Beefy Finance — multi-chain yield optimizer / auto-compounder */
BEEFY = 'BEEFY',

/** Aave — decentralized lending and borrowing protocol */
AAVE = 'AAVE',

/** Uniswap — Ethereum-native AMM / DEX */
UNISWAP = 'UNISWAP',

/** Compound — algorithmic money market protocol */
COMPOUND = 'COMPOUND',

/** Lido — liquid staking for Ethereum and other PoS chains */
LIDO = 'LIDO',

/** Marinade Finance — liquid staking for Solana */
MARINADE = 'MARINADE',

/** Raydium — Solana AMM and liquidity provider */
RAYDIUM = 'RAYDIUM',

/** Jupiter — Solana DEX aggregator and perps platform */
JUPITER = 'JUPITER',

/** Orca — Solana concentrated liquidity DEX */
ORCA = 'ORCA',

/** Protocol not covered by other values; store name in metadata */
OTHER = 'OTHER'
}
4 changes: 4 additions & 0 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,9 @@ export { TransactionType } from './enums/TransactionType';
export { AccountType } from './enums/AccountType';
export { LendingPositionType } from './enums/LendingPositionType';
export { VaultStrategyType } from './enums/VaultStrategyType';
export { DeFiPositionType } from './enums/DeFiPositionType';
export { DeFiProtocol } from './enums/DeFiProtocol';
export { DeFiDiscoverySource } from './enums/DeFiDiscoverySource';

// Base Interfaces
export { BaseEntity } from './interfaces/BaseEntity';
Expand All @@ -25,6 +28,7 @@ export { LiquidityPosition } from './interfaces/LiquidityPosition';
export { StakedPosition } from './interfaces/StakedPosition';
export { LendingPosition } from './interfaces/LendingPosition';
export { VaultPosition } from './interfaces/VaultPosition';
export { DeFiPosition } from './interfaces/DeFiPosition';

// Account and Portfolio Models
export { Account } from './interfaces/Account';
Expand Down
86 changes: 86 additions & 0 deletions src/interfaces/DeFiPosition.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
import { Chain } from '../enums/Chain';
import { DeFiPositionType } from '../enums/DeFiPositionType';
import { DeFiProtocol } from '../enums/DeFiProtocol';
import { DeFiDiscoverySource } from '../enums/DeFiDiscoverySource';
import { Balance } from './Balance';
import { Price } from './Price';
import { Metadata } from './Metadata';

/**
* Base interface for all DeFi positions across protocols and chains.
*
* Provides a unified shape for any DeFi position — vaults, lending, liquidity
* pools, staking, farming, and perp positions. Concrete subtypes
* ({@link VaultPosition}, {@link LendingPosition}, {@link LiquidityPosition},
* {@link StakedPosition}) add protocol-specific fields.
*
* **Discovery Paths:**
* - `WALLET_TOKEN_SCAN` — position inferred from receipt tokens in wallet
* - `CONTRACT_QUERY` — position read from protocol contract state
*
* @example
* ```typescript
* import {
* DeFiPosition,
* DeFiPositionType,
* DeFiProtocol,
* DeFiDiscoverySource,
* Chain
* } from '@cygnus-wealth/data-models';
*
* const position: DeFiPosition = {
* id: 'aave-supply-usdc-1',
* type: DeFiPositionType.LENDING_SUPPLY,
* protocol: DeFiProtocol.AAVE,
* chain: Chain.ETHEREUM,
* underlyingAssets: [{
* assetId: 'ethereum-usdc',
* asset: { id: 'ethereum-usdc', symbol: 'USDC', name: 'USD Coin', type: 'CRYPTOCURRENCY', decimals: 6 },
* amount: '50000'
* }],
* value: { value: 50125.50, currency: 'USD', timestamp: new Date() },
* apy: 3.5,
* rewards: [],
* discoverySource: DeFiDiscoverySource.CONTRACT_QUERY
* };
* ```
*
* @since 1.3.0
* @stability extended
*
* @see {@link VaultPosition} for vault-specific fields
* @see {@link LendingPosition} for lending-specific fields
* @see {@link LiquidityPosition} for LP-specific fields
* @see {@link StakedPosition} for staking-specific fields
*/
export interface DeFiPosition {
/** Unique identifier for this position */
id: string;

/** Classification of the DeFi position */
type: DeFiPositionType;

/** Protocol where the position exists */
protocol: DeFiProtocol;

/** Blockchain network where the position exists */
chain: Chain;

/** Underlying assets in this position (tokens deposited, staked, or provided) */
underlyingAssets: Balance[];

/** Current total value of the position */
value?: Price;

/** Annual Percentage Yield or Rate (e.g., 8.5 = 8.5%) */
apy?: number;

/** Earned rewards (claimable or accrued incentive tokens) */
rewards: Balance[];

/** How this position was discovered during portfolio scanning */
discoverySource?: DeFiDiscoverySource;

/** Protocol-specific metadata (version, contract addresses, TVL, etc.) */
metadata?: Metadata;
}
4 changes: 4 additions & 0 deletions src/interfaces/LendingPosition.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { Chain } from '../enums/Chain';
import { LendingPositionType } from '../enums/LendingPositionType';
import { DeFiDiscoverySource } from '../enums/DeFiDiscoverySource';
import { Asset } from './Asset';
import { Price } from './Price';
import { Metadata } from './Metadata';
Expand Down Expand Up @@ -110,6 +111,9 @@ export interface LendingPosition {
/** Current total value of position (positive for supply, negative for borrow debt) */
value?: Price;

/** How this position was discovered during portfolio scanning */
discoverySource?: DeFiDiscoverySource;

/** Protocol-specific metadata (collateral assets, liquidation price, etc.) */
metadata?: Metadata;
}
4 changes: 4 additions & 0 deletions src/interfaces/LiquidityPosition.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { Chain } from '../enums/Chain';
import { DeFiDiscoverySource } from '../enums/DeFiDiscoverySource';
import { Balance } from './Balance';
import { Price } from './Price';
import { Metadata } from './Metadata';
Expand Down Expand Up @@ -89,6 +90,9 @@ export interface LiquidityPosition {
/** Impermanent loss compared to holding tokens (negative = loss, positive = gain) */
impermanentLoss?: number;

/** How this position was discovered during portfolio scanning */
discoverySource?: DeFiDiscoverySource;

/** Protocol-specific metadata (pool version, fee tier, range bounds, etc.) */
metadata?: Metadata;
}
Loading