@cygnus-wealth/data-models 0.0.2 → 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +366 -63
- package/dist/enums/AccountType.d.ts +41 -0
- package/dist/enums/AccountType.js +41 -0
- package/dist/enums/AssetType.d.ts +114 -0
- package/dist/enums/AssetType.js +114 -0
- package/dist/enums/Chain.d.ts +57 -0
- package/dist/enums/Chain.js +57 -0
- package/dist/enums/IntegrationSource.d.ts +47 -0
- package/dist/enums/IntegrationSource.js +47 -4
- package/dist/enums/LendingPositionType.d.ts +25 -0
- package/dist/enums/LendingPositionType.js +26 -0
- package/dist/enums/TransactionType.d.ts +50 -0
- package/dist/enums/TransactionType.js +50 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +1 -0
- package/dist/interfaces/Account.d.ts +92 -0
- package/dist/interfaces/ApiError.d.ts +61 -0
- package/dist/interfaces/ApiResponse.d.ts +60 -1
- package/dist/interfaces/Asset.d.ts +59 -0
- package/dist/interfaces/Balance.d.ts +52 -0
- package/dist/interfaces/BaseEntity.d.ts +61 -0
- package/dist/interfaces/FilterOptions.d.ts +68 -0
- package/dist/interfaces/IntegrationCredentials.d.ts +54 -0
- package/dist/interfaces/LendingPosition.d.ts +89 -4
- package/dist/interfaces/LiquidityPosition.d.ts +66 -2
- package/dist/interfaces/MarketData.d.ts +53 -0
- package/dist/interfaces/Metadata.d.ts +86 -0
- package/dist/interfaces/NFT.d.ts +55 -0
- package/dist/interfaces/PaginatedResponse.d.ts +59 -0
- package/dist/interfaces/Portfolio.d.ts +104 -2
- package/dist/interfaces/PortfolioAsset.d.ts +76 -0
- package/dist/interfaces/PortfolioAsset.js +1 -0
- package/dist/interfaces/PortfolioItem.d.ts +13 -0
- package/dist/interfaces/Price.d.ts +45 -2
- package/dist/interfaces/StakedPosition.d.ts +77 -0
- package/dist/interfaces/SyncStatus.d.ts +55 -0
- package/dist/interfaces/Transaction.d.ts +114 -2
- package/dist/types/AssetIdentifier.d.ts +61 -0
- package/dist/types/SortOrder.d.ts +50 -0
- package/dist/types/TimeRange.d.ts +51 -0
- package/package.json +29 -3
|
@@ -1,11 +1,65 @@
|
|
|
1
1
|
import { IntegrationSource } from '../enums/IntegrationSource';
|
|
2
2
|
import { Metadata } from './Metadata';
|
|
3
|
+
/**
|
|
4
|
+
* Encrypted credentials for CEX/brokerage API integration.
|
|
5
|
+
*
|
|
6
|
+
* Stores connection credentials for read-only API access to centralized exchanges,
|
|
7
|
+
* brokerages, and blockchain wallets. Designed for client-side encryption and
|
|
8
|
+
* secure storage patterns.
|
|
9
|
+
*
|
|
10
|
+
* **Security Pattern:** Credentials stored in this interface should be encrypted
|
|
11
|
+
* before persistence using Web Crypto API or similar client-side encryption.
|
|
12
|
+
* NEVER store private keys - only read-only API keys for data fetching.
|
|
13
|
+
*
|
|
14
|
+
* **Design Pattern:** Flexible credential structure supporting both API key-based
|
|
15
|
+
* authentication (CEX) and address-based read-only access (wallets).
|
|
16
|
+
*
|
|
17
|
+
* @example
|
|
18
|
+
* ```typescript
|
|
19
|
+
* import { IntegrationCredentials, IntegrationSource } from '@cygnus-wealth/data-models';
|
|
20
|
+
*
|
|
21
|
+
* // Kraken CEX credentials (API key + secret)
|
|
22
|
+
* const krakenCreds: IntegrationCredentials = {
|
|
23
|
+
* source: IntegrationSource.KRAKEN,
|
|
24
|
+
* apiKey: 'encrypted_api_key_here',
|
|
25
|
+
* apiSecret: 'encrypted_api_secret_here'
|
|
26
|
+
* };
|
|
27
|
+
*
|
|
28
|
+
* // Coinbase Pro credentials (with passphrase)
|
|
29
|
+
* const coinbaseCreds: IntegrationCredentials = {
|
|
30
|
+
* source: IntegrationSource.COINBASE,
|
|
31
|
+
* apiKey: 'encrypted_api_key',
|
|
32
|
+
* apiSecret: 'encrypted_secret',
|
|
33
|
+
* passphrase: 'encrypted_passphrase'
|
|
34
|
+
* };
|
|
35
|
+
*
|
|
36
|
+
* // MetaMask wallet (address-based read-only)
|
|
37
|
+
* const walletCreds: IntegrationCredentials = {
|
|
38
|
+
* source: IntegrationSource.METAMASK,
|
|
39
|
+
* walletAddress: '0x742d35Cc6634C0532925a3b844Bc9e7595f0bEb',
|
|
40
|
+
* chainId: '1' // Ethereum mainnet
|
|
41
|
+
* };
|
|
42
|
+
* ```
|
|
43
|
+
*
|
|
44
|
+
* @since 0.0.1
|
|
45
|
+
* @stability standard
|
|
46
|
+
*
|
|
47
|
+
* @see {@link IntegrationSource} for supported sources
|
|
48
|
+
* @see {@link Account} for credential usage in data fetching
|
|
49
|
+
*/
|
|
3
50
|
export interface IntegrationCredentials {
|
|
51
|
+
/** Integration source requiring these credentials */
|
|
4
52
|
source: IntegrationSource;
|
|
53
|
+
/** API key for CEX/brokerage authentication (should be encrypted) */
|
|
5
54
|
apiKey?: string;
|
|
55
|
+
/** API secret for CEX/brokerage authentication (should be encrypted) */
|
|
6
56
|
apiSecret?: string;
|
|
57
|
+
/** Additional passphrase for some exchanges (Coinbase Pro, etc.) (should be encrypted) */
|
|
7
58
|
passphrase?: string;
|
|
59
|
+
/** Wallet address for read-only blockchain queries (NOT private key) */
|
|
8
60
|
walletAddress?: string;
|
|
61
|
+
/** Blockchain network ID for wallet connections (e.g., '1' for Ethereum mainnet) */
|
|
9
62
|
chainId?: string;
|
|
63
|
+
/** Source-specific metadata (permissions, connection settings, etc.) */
|
|
10
64
|
metadata?: Metadata;
|
|
11
65
|
}
|
|
@@ -1,18 +1,103 @@
|
|
|
1
1
|
import { Chain } from '../enums/Chain';
|
|
2
|
+
import { LendingPositionType } from '../enums/LendingPositionType';
|
|
2
3
|
import { Asset } from './Asset';
|
|
3
4
|
import { Price } from './Price';
|
|
4
5
|
import { Metadata } from './Metadata';
|
|
6
|
+
/**
|
|
7
|
+
* DeFi money market positions for lending and borrowing.
|
|
8
|
+
*
|
|
9
|
+
* Represents user positions in lending protocols (Aave, Compound, etc.) where
|
|
10
|
+
* users can supply assets to earn interest (SUPPLY) or borrow assets against
|
|
11
|
+
* collateral (BORROW). Tracks amounts, interest rates, health factors, and
|
|
12
|
+
* liquidation thresholds critical for position management.
|
|
13
|
+
*
|
|
14
|
+
* **Design Pattern:** DeFi position entity discriminated by type (SUPPLY vs BORROW).
|
|
15
|
+
* Health factor and liquidation threshold are essential for monitoring borrow
|
|
16
|
+
* position safety and preventing liquidations.
|
|
17
|
+
*
|
|
18
|
+
* @example
|
|
19
|
+
* ```typescript
|
|
20
|
+
* import { LendingPosition, LendingPositionType, Chain } from '@cygnus-wealth/data-models';
|
|
21
|
+
*
|
|
22
|
+
* // Aave supply position (earning interest)
|
|
23
|
+
* const supplyPosition: LendingPosition = {
|
|
24
|
+
* id: 'aave-supply-usdc-123',
|
|
25
|
+
* protocol: 'Aave V3',
|
|
26
|
+
* chain: Chain.ETHEREUM,
|
|
27
|
+
* type: LendingPositionType.SUPPLY,
|
|
28
|
+
* asset: {
|
|
29
|
+
* id: 'ethereum-usdc',
|
|
30
|
+
* symbol: 'USDC',
|
|
31
|
+
* name: 'USD Coin',
|
|
32
|
+
* type: AssetType.CRYPTOCURRENCY,
|
|
33
|
+
* decimals: 6
|
|
34
|
+
* },
|
|
35
|
+
* amount: '50000', // $50k supplied
|
|
36
|
+
* apy: 3.5, // 3.5% APY
|
|
37
|
+
* accruedInterest: 125.50,
|
|
38
|
+
* value: {
|
|
39
|
+
* value: 50125.50,
|
|
40
|
+
* currency: 'USD',
|
|
41
|
+
* timestamp: new Date()
|
|
42
|
+
* }
|
|
43
|
+
* };
|
|
44
|
+
*
|
|
45
|
+
* // Aave borrow position (paying interest)
|
|
46
|
+
* const borrowPosition: LendingPosition = {
|
|
47
|
+
* id: 'aave-borrow-dai-456',
|
|
48
|
+
* protocol: 'Aave V3',
|
|
49
|
+
* chain: Chain.ETHEREUM,
|
|
50
|
+
* type: LendingPositionType.BORROW,
|
|
51
|
+
* asset: {
|
|
52
|
+
* id: 'ethereum-dai',
|
|
53
|
+
* symbol: 'DAI',
|
|
54
|
+
* name: 'Dai Stablecoin',
|
|
55
|
+
* type: AssetType.CRYPTOCURRENCY,
|
|
56
|
+
* decimals: 18
|
|
57
|
+
* },
|
|
58
|
+
* amount: '30000', // $30k borrowed
|
|
59
|
+
* apy: 5.2, // 5.2% borrow rate
|
|
60
|
+
* accruedInterest: -85.30, // Interest owed
|
|
61
|
+
* healthFactor: 2.5, // > 1.0 = safe
|
|
62
|
+
* liquidationThreshold: 0.85, // 85% LTV
|
|
63
|
+
* value: {
|
|
64
|
+
* value: -30085.30, // Negative for debt
|
|
65
|
+
* currency: 'USD',
|
|
66
|
+
* timestamp: new Date()
|
|
67
|
+
* }
|
|
68
|
+
* };
|
|
69
|
+
* ```
|
|
70
|
+
*
|
|
71
|
+
* @since 0.0.1
|
|
72
|
+
* @stability extended
|
|
73
|
+
*
|
|
74
|
+
* @see {@link LendingPositionType} for SUPPLY vs BORROW discrimination
|
|
75
|
+
* @see {@link Asset} for lent/borrowed asset definition
|
|
76
|
+
* @see {@link Account} for position aggregation
|
|
77
|
+
*/
|
|
5
78
|
export interface LendingPosition {
|
|
79
|
+
/** Unique identifier for this lending position */
|
|
6
80
|
id: string;
|
|
81
|
+
/** Lending protocol name (e.g., 'Aave V3', 'Compound', 'Venus') */
|
|
7
82
|
protocol: string;
|
|
83
|
+
/** Blockchain network where the lending position exists */
|
|
8
84
|
chain: Chain;
|
|
9
|
-
type:
|
|
85
|
+
/** Position type: SUPPLY (lender) or BORROW (borrower) */
|
|
86
|
+
type: LendingPositionType;
|
|
87
|
+
/** Asset being supplied or borrowed */
|
|
10
88
|
asset: Asset;
|
|
89
|
+
/** Amount supplied or borrowed (as string for precision) */
|
|
11
90
|
amount: string;
|
|
91
|
+
/** Annual Percentage Yield (for supply) or Rate (for borrow) (e.g., 3.5 = 3.5%) */
|
|
12
92
|
apy?: number;
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
93
|
+
/** Interest accrued (positive for supply, negative for borrow) */
|
|
94
|
+
accruedInterest?: number;
|
|
95
|
+
/** Health factor for borrow positions (ratio of collateral to debt, \>1.0 = safe) */
|
|
96
|
+
healthFactor?: number;
|
|
97
|
+
/** Liquidation threshold as ratio (0.0-1.0, e.g., 0.85 = 85% LTV before liquidation) */
|
|
98
|
+
liquidationThreshold?: number;
|
|
99
|
+
/** Current total value of position (positive for supply, negative for borrow debt) */
|
|
16
100
|
value?: Price;
|
|
101
|
+
/** Protocol-specific metadata (collateral assets, liquidation price, etc.) */
|
|
17
102
|
metadata?: Metadata;
|
|
18
103
|
}
|
|
@@ -2,17 +2,81 @@ import { Chain } from '../enums/Chain';
|
|
|
2
2
|
import { Balance } from './Balance';
|
|
3
3
|
import { Price } from './Price';
|
|
4
4
|
import { Metadata } from './Metadata';
|
|
5
|
+
/**
|
|
6
|
+
* DEX liquidity pool position tracking LP tokens and performance.
|
|
7
|
+
*
|
|
8
|
+
* Represents user's position in automated market maker (AMM) liquidity pools
|
|
9
|
+
* across various DEX protocols (Uniswap, Curve, Balancer, etc.). Tracks deposited
|
|
10
|
+
* tokens, LP token ownership, pool share, earned fees, and impermanent loss.
|
|
11
|
+
*
|
|
12
|
+
* **Design Pattern:** DeFi position entity capturing both the underlying tokens
|
|
13
|
+
* deposited and the LP token representation, along with performance metrics
|
|
14
|
+
* specific to liquidity provision.
|
|
15
|
+
*
|
|
16
|
+
* @example
|
|
17
|
+
* ```typescript
|
|
18
|
+
* import { LiquidityPosition, Chain } from '@cygnus-wealth/data-models';
|
|
19
|
+
*
|
|
20
|
+
* // Uniswap V2 ETH/USDC pool position
|
|
21
|
+
* const uniswapPosition: LiquidityPosition = {
|
|
22
|
+
* id: 'uniswap-eth-usdc-123',
|
|
23
|
+
* protocol: 'Uniswap V2',
|
|
24
|
+
* poolAddress: '0xB4e16d0168e52d35CaCD2c6185b44281Ec28C9Dc',
|
|
25
|
+
* poolName: 'ETH/USDC',
|
|
26
|
+
* chain: Chain.ETHEREUM,
|
|
27
|
+
* tokens: [
|
|
28
|
+
* {
|
|
29
|
+
* assetId: 'ethereum-eth',
|
|
30
|
+
* asset: {...},
|
|
31
|
+
* amount: '5.0'
|
|
32
|
+
* },
|
|
33
|
+
* {
|
|
34
|
+
* assetId: 'ethereum-usdc',
|
|
35
|
+
* asset: {...},
|
|
36
|
+
* amount: '10000'
|
|
37
|
+
* }
|
|
38
|
+
* ],
|
|
39
|
+
* lpTokenBalance: '707.106781186548', // LP token amount
|
|
40
|
+
* share: 0.05, // 5% of the pool
|
|
41
|
+
* value: {
|
|
42
|
+
* value: 20000,
|
|
43
|
+
* currency: 'USD',
|
|
44
|
+
* timestamp: new Date()
|
|
45
|
+
* },
|
|
46
|
+
* feesEarned: 150.50, // $150.50 earned in fees
|
|
47
|
+
* impermanentLoss: -25.30 // -$25.30 IL
|
|
48
|
+
* };
|
|
49
|
+
* ```
|
|
50
|
+
*
|
|
51
|
+
* @since 0.0.1
|
|
52
|
+
* @stability extended
|
|
53
|
+
*
|
|
54
|
+
* @see {@link Balance} for token balance structure
|
|
55
|
+
* @see {@link Account} for position aggregation
|
|
56
|
+
*/
|
|
5
57
|
export interface LiquidityPosition {
|
|
58
|
+
/** Unique identifier for this liquidity position */
|
|
6
59
|
id: string;
|
|
60
|
+
/** DEX protocol name (e.g., 'Uniswap V3', 'Curve', 'Balancer V2') */
|
|
7
61
|
protocol: string;
|
|
62
|
+
/** Smart contract address of the liquidity pool */
|
|
8
63
|
poolAddress: string;
|
|
64
|
+
/** Human-readable pool name (e.g., 'ETH/USDC', 'stETH/ETH') */
|
|
9
65
|
poolName: string;
|
|
66
|
+
/** Blockchain network where the pool exists */
|
|
10
67
|
chain: Chain;
|
|
68
|
+
/** Array of token balances deposited in the pool (typically 2-8 tokens) */
|
|
11
69
|
tokens: Balance[];
|
|
70
|
+
/** Amount of LP tokens held (represents pool share) */
|
|
12
71
|
lpTokenBalance?: string;
|
|
72
|
+
/** Percentage of total pool owned (0.0-1.0, e.g., 0.05 = 5%) */
|
|
13
73
|
share?: number;
|
|
74
|
+
/** Current total value of the position (sum of all tokens) */
|
|
14
75
|
value?: Price;
|
|
15
|
-
|
|
16
|
-
|
|
76
|
+
/** Total trading fees earned from this position (in value.currency) */
|
|
77
|
+
feesEarned?: number;
|
|
78
|
+
/** Impermanent loss compared to holding tokens (negative = loss, positive = gain) */
|
|
79
|
+
impermanentLoss?: number;
|
|
80
|
+
/** Protocol-specific metadata (pool version, fee tier, range bounds, etc.) */
|
|
17
81
|
metadata?: Metadata;
|
|
18
82
|
}
|
|
@@ -1,14 +1,67 @@
|
|
|
1
1
|
import { Price } from './Price';
|
|
2
|
+
/**
|
|
3
|
+
* Extended market data for analytics and research features.
|
|
4
|
+
*
|
|
5
|
+
* Comprehensive market information including price, market cap, trading volume,
|
|
6
|
+
* supply metrics, price changes, and 24-hour price range. Used for advanced
|
|
7
|
+
* analytics, market research, and detailed asset views.
|
|
8
|
+
*
|
|
9
|
+
* **Design Pattern:** Extends basic Price with market-specific metrics from
|
|
10
|
+
* CoinGecko, CoinMarketCap, or other market data providers. All fields except
|
|
11
|
+
* assetId, currentPrice, and lastUpdated are optional to handle varying data
|
|
12
|
+
* availability.
|
|
13
|
+
*
|
|
14
|
+
* @example
|
|
15
|
+
* ```typescript
|
|
16
|
+
* import { MarketData } from '@cygnus-wealth/data-models';
|
|
17
|
+
*
|
|
18
|
+
* // Comprehensive market data for analytics
|
|
19
|
+
* const ethMarketData: MarketData = {
|
|
20
|
+
* assetId: 'ethereum-eth',
|
|
21
|
+
* currentPrice: {
|
|
22
|
+
* value: 2000,
|
|
23
|
+
* currency: 'USD',
|
|
24
|
+
* timestamp: new Date()
|
|
25
|
+
* },
|
|
26
|
+
* marketCap: 240000000000, // $240B
|
|
27
|
+
* volume24h: 12000000000, // $12B daily volume
|
|
28
|
+
* priceChange24h: 50,
|
|
29
|
+
* priceChangePercentage24h: 2.5,
|
|
30
|
+
* high24h: 2050,
|
|
31
|
+
* low24h: 1950,
|
|
32
|
+
* circulatingSupply: 120000000,
|
|
33
|
+
* totalSupply: 120000000,
|
|
34
|
+
* lastUpdated: new Date()
|
|
35
|
+
* };
|
|
36
|
+
* ```
|
|
37
|
+
*
|
|
38
|
+
* @since 0.0.1
|
|
39
|
+
* @stability standard
|
|
40
|
+
*
|
|
41
|
+
* @see {@link Price} for base price structure
|
|
42
|
+
* @see {@link Asset} for asset definitions
|
|
43
|
+
*/
|
|
2
44
|
export interface MarketData {
|
|
45
|
+
/** Reference to Asset.id for this market data */
|
|
3
46
|
assetId: string;
|
|
47
|
+
/** Current market price with timestamp */
|
|
4
48
|
currentPrice: Price;
|
|
49
|
+
/** Total market capitalization (price * circulating supply) */
|
|
5
50
|
marketCap?: number;
|
|
51
|
+
/** Trading volume in last 24 hours */
|
|
6
52
|
volume24h?: number;
|
|
53
|
+
/** Absolute price change in last 24 hours (in currentPrice.currency) */
|
|
7
54
|
priceChange24h?: number;
|
|
55
|
+
/** Percentage price change in last 24 hours (e.g., 2.5 = 2.5%) */
|
|
8
56
|
priceChangePercentage24h?: number;
|
|
57
|
+
/** Highest price in last 24 hours */
|
|
9
58
|
high24h?: number;
|
|
59
|
+
/** Lowest price in last 24 hours */
|
|
10
60
|
low24h?: number;
|
|
61
|
+
/** Number of tokens in circulation (available for trading) */
|
|
11
62
|
circulatingSupply?: number;
|
|
63
|
+
/** Total number of tokens that currently exist (including locked) */
|
|
12
64
|
totalSupply?: number;
|
|
65
|
+
/** Timestamp when this market data was last updated */
|
|
13
66
|
lastUpdated: Date;
|
|
14
67
|
}
|
|
@@ -1,3 +1,89 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Extensible metadata container for source-specific and custom data.
|
|
3
|
+
*
|
|
4
|
+
* Metadata provides a flexible mechanism for storing additional information that
|
|
5
|
+
* doesn't fit into standardized model fields. This pattern enables the core data
|
|
6
|
+
* models to remain clean and source-agnostic while allowing integration domains
|
|
7
|
+
* to preserve source-specific details.
|
|
8
|
+
*
|
|
9
|
+
* **Design Pattern: Extension Object**
|
|
10
|
+
* The Metadata interface implements the Extension Object pattern, allowing models
|
|
11
|
+
* to be extended without modifying their core structure. This maintains backward
|
|
12
|
+
* compatibility while enabling forward extensibility.
|
|
13
|
+
*
|
|
14
|
+
* **Use Cases**:
|
|
15
|
+
* - Source-specific identifiers (e.g., Robinhood internal IDs, CEX trade IDs)
|
|
16
|
+
* - Integration-specific flags or configuration
|
|
17
|
+
* - Experimental data during feature development
|
|
18
|
+
* - Custom tags or labels added by consuming domains
|
|
19
|
+
* - Raw response data for debugging
|
|
20
|
+
*
|
|
21
|
+
* **Guidelines**:
|
|
22
|
+
* - Keys should be namespaced to avoid conflicts (e.g., `"robinhood:accountId"`)
|
|
23
|
+
* - Values should be JSON-serializable
|
|
24
|
+
* - Do NOT store sensitive data (API keys, private keys, passwords)
|
|
25
|
+
* - Document custom metadata keys in consuming domain documentation
|
|
26
|
+
*
|
|
27
|
+
* @example
|
|
28
|
+
* ```typescript
|
|
29
|
+
* // Asset with Coinbase-specific metadata
|
|
30
|
+
* const asset: Asset = {
|
|
31
|
+
* id: "btc-bitcoin",
|
|
32
|
+
* symbol: "BTC",
|
|
33
|
+
* name: "Bitcoin",
|
|
34
|
+
* type: AssetType.CRYPTOCURRENCY,
|
|
35
|
+
* metadata: {
|
|
36
|
+
* "coinbase:currencyCode": "BTC",
|
|
37
|
+
* "coinbase:tradingPair": "BTC-USD",
|
|
38
|
+
* "coinbase:minSize": "0.00000001",
|
|
39
|
+
* "tags": ["major", "layer1"],
|
|
40
|
+
* "lastSyncedAt": "2025-01-15T10:30:00Z"
|
|
41
|
+
* }
|
|
42
|
+
* };
|
|
43
|
+
* ```
|
|
44
|
+
*
|
|
45
|
+
* @example
|
|
46
|
+
* ```typescript
|
|
47
|
+
* // Transaction with chain-specific metadata
|
|
48
|
+
* const transaction: Transaction = {
|
|
49
|
+
* id: "txn_123",
|
|
50
|
+
* hash: "0xabc...",
|
|
51
|
+
* type: TransactionType.SWAP,
|
|
52
|
+
* // ... other fields
|
|
53
|
+
* metadata: {
|
|
54
|
+
* "ethereum:gasUsed": "21000",
|
|
55
|
+
* "ethereum:gasPrice": "50000000000",
|
|
56
|
+
* "ethereum:blockNumber": "18500000",
|
|
57
|
+
* "uniswap:poolAddress": "0xdef...",
|
|
58
|
+
* "uniswap:fee": "0.003"
|
|
59
|
+
* }
|
|
60
|
+
* };
|
|
61
|
+
* ```
|
|
62
|
+
*
|
|
63
|
+
* @since 0.0.1
|
|
64
|
+
* @stability core
|
|
65
|
+
*
|
|
66
|
+
* @see {@link Asset} for usage in asset models
|
|
67
|
+
* @see {@link Transaction} for usage in transaction models
|
|
68
|
+
*/
|
|
1
69
|
export interface Metadata {
|
|
70
|
+
/**
|
|
71
|
+
* Arbitrary key-value pairs for extensibility.
|
|
72
|
+
*
|
|
73
|
+
* Keys should follow namespacing convention: `"source:field"` or `"domain:field"`
|
|
74
|
+
* to prevent collisions between different integration sources.
|
|
75
|
+
*
|
|
76
|
+
* Values must be JSON-serializable types (string, number, boolean, object, array, null).
|
|
77
|
+
* Avoid storing functions, circular references, or non-serializable types.
|
|
78
|
+
*
|
|
79
|
+
* @example
|
|
80
|
+
* ```typescript
|
|
81
|
+
* {
|
|
82
|
+
* "robinhood:accountId": "RH_ACC_123",
|
|
83
|
+
* "robinhood:isFractional": true,
|
|
84
|
+
* "custom:tags": ["watchlist", "high-priority"]
|
|
85
|
+
* }
|
|
86
|
+
* ```
|
|
87
|
+
*/
|
|
2
88
|
[key: string]: unknown;
|
|
3
89
|
}
|
package/dist/interfaces/NFT.d.ts
CHANGED
|
@@ -1,14 +1,69 @@
|
|
|
1
1
|
import { Asset } from './Asset';
|
|
2
|
+
/**
|
|
3
|
+
* NFT-specific asset extensions including token IDs and metadata.
|
|
4
|
+
*
|
|
5
|
+
* Extends the base Asset interface with NFT-specific fields for collection
|
|
6
|
+
* information, unique token identification, visual content URIs, and trait
|
|
7
|
+
* attributes. Supports ERC-721, ERC-1155, SPL NFTs, and SUI Move NFTs.
|
|
8
|
+
*
|
|
9
|
+
* **Design Pattern:** Inherits all Asset fields (id, symbol, name, etc.) and
|
|
10
|
+
* adds NFT-specific data. The Asset.type should be AssetType.NFT for proper
|
|
11
|
+
* classification.
|
|
12
|
+
*
|
|
13
|
+
* @example
|
|
14
|
+
* ```typescript
|
|
15
|
+
* import { NFT, AssetType, Chain } from '@cygnus-wealth/data-models';
|
|
16
|
+
*
|
|
17
|
+
* // ERC-721 NFT from OpenSea
|
|
18
|
+
* const nft: NFT = {
|
|
19
|
+
* // Asset base fields
|
|
20
|
+
* id: 'bayc-1234',
|
|
21
|
+
* symbol: 'BAYC',
|
|
22
|
+
* name: 'Bored Ape Yacht Club #1234',
|
|
23
|
+
* type: AssetType.NFT,
|
|
24
|
+
* chain: Chain.ETHEREUM,
|
|
25
|
+
* contractAddress: '0xBC4CA0EdA7647A8aB7C2061c2E118A18a936f13D',
|
|
26
|
+
*
|
|
27
|
+
* // NFT-specific fields
|
|
28
|
+
* tokenId: '1234',
|
|
29
|
+
* collectionAddress: '0xBC4CA0EdA7647A8aB7C2061c2E118A18a936f13D',
|
|
30
|
+
* collectionName: 'Bored Ape Yacht Club',
|
|
31
|
+
* tokenUri: 'ipfs://QmeSjSinHpPnmXmspMjwiXyN6zS4E9zccariGR3jxcaWtq/1234',
|
|
32
|
+
* imageUrl: 'https://example.com/bayc-1234.png',
|
|
33
|
+
* attributes: [
|
|
34
|
+
* { trait_type: 'Background', value: 'Blue' },
|
|
35
|
+
* { trait_type: 'Fur', value: 'Brown' },
|
|
36
|
+
* { trait_type: 'Rarity Score', value: 125.5, display_type: 'number' }
|
|
37
|
+
* ]
|
|
38
|
+
* };
|
|
39
|
+
* ```
|
|
40
|
+
*
|
|
41
|
+
* @since 0.0.1
|
|
42
|
+
* @stability standard
|
|
43
|
+
*
|
|
44
|
+
* @see {@link Asset} for inherited base fields
|
|
45
|
+
* @see {@link AssetType} - use AssetType.NFT for NFTs
|
|
46
|
+
*/
|
|
2
47
|
export interface NFT extends Asset {
|
|
48
|
+
/** Unique token identifier within the collection (e.g., '1234', '0x5f') */
|
|
3
49
|
tokenId: string;
|
|
50
|
+
/** Smart contract address of the NFT collection */
|
|
4
51
|
collectionAddress: string;
|
|
52
|
+
/** Human-readable name of the NFT collection */
|
|
5
53
|
collectionName: string;
|
|
54
|
+
/** URI pointing to token metadata (IPFS, HTTP, or on-chain) */
|
|
6
55
|
tokenUri?: string;
|
|
56
|
+
/** Direct URL to the NFT image for display */
|
|
7
57
|
imageUrl?: string;
|
|
58
|
+
/** URL to animation or video content (MP4, GIF, etc.) */
|
|
8
59
|
animationUrl?: string;
|
|
60
|
+
/** Array of trait attributes defining NFT characteristics and rarity */
|
|
9
61
|
attributes?: Array<{
|
|
62
|
+
/** Category or type of the trait (e.g., 'Background', 'Fur', 'Eyes') */
|
|
10
63
|
trait_type: string;
|
|
64
|
+
/** Value of the trait (can be text or numeric) */
|
|
11
65
|
value: string | number;
|
|
66
|
+
/** Optional display hint for numeric traits (e.g., 'number', 'boost_percentage') */
|
|
12
67
|
display_type?: string;
|
|
13
68
|
}>;
|
|
14
69
|
}
|
|
@@ -1,7 +1,66 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Paginated response wrapper for large datasets.
|
|
3
|
+
*
|
|
4
|
+
* Standard structure for paginated API responses enabling efficient handling
|
|
5
|
+
* of large collections (transactions, assets, etc.). Uses 1-indexed pages and
|
|
6
|
+
* provides hasMore flag for infinite scroll implementations.
|
|
7
|
+
*
|
|
8
|
+
* **Design Pattern:** Cursor-based pagination pattern with metadata for UI
|
|
9
|
+
* pagination controls and infinite scroll detection.
|
|
10
|
+
*
|
|
11
|
+
* @template T - Type of items in the collection
|
|
12
|
+
*
|
|
13
|
+
* @example
|
|
14
|
+
* ```typescript
|
|
15
|
+
* import { PaginatedResponse, Transaction } from '@cygnus-wealth/data-models';
|
|
16
|
+
*
|
|
17
|
+
* // First page of transactions
|
|
18
|
+
* const page1: PaginatedResponse<Transaction> = {
|
|
19
|
+
* items: [
|
|
20
|
+
* { id: 'tx-1', type: TransactionType.BUY, ... },
|
|
21
|
+
* { id: 'tx-2', type: TransactionType.SELL, ... },
|
|
22
|
+
* // ... 48 more items
|
|
23
|
+
* ],
|
|
24
|
+
* total: 523,
|
|
25
|
+
* page: 1,
|
|
26
|
+
* pageSize: 50,
|
|
27
|
+
* hasMore: true // (1 * 50) < 523
|
|
28
|
+
* };
|
|
29
|
+
*
|
|
30
|
+
* // Last page calculation
|
|
31
|
+
* const lastPage: PaginatedResponse<Transaction> = {
|
|
32
|
+
* items: [ ... 23 items ... ],
|
|
33
|
+
* total: 523,
|
|
34
|
+
* page: 11,
|
|
35
|
+
* pageSize: 50,
|
|
36
|
+
* hasMore: false // (11 * 50) >= 523
|
|
37
|
+
* };
|
|
38
|
+
*
|
|
39
|
+
* // Empty result set
|
|
40
|
+
* const emptyPage: PaginatedResponse<Transaction> = {
|
|
41
|
+
* items: [],
|
|
42
|
+
* total: 0,
|
|
43
|
+
* page: 1,
|
|
44
|
+
* pageSize: 50,
|
|
45
|
+
* hasMore: false
|
|
46
|
+
* };
|
|
47
|
+
* ```
|
|
48
|
+
*
|
|
49
|
+
* @since 0.0.1
|
|
50
|
+
* @stability standard
|
|
51
|
+
*
|
|
52
|
+
* @see {@link ApiResponse} for response wrapping
|
|
53
|
+
* @see {@link Transaction} for common paginated type
|
|
54
|
+
*/
|
|
1
55
|
export interface PaginatedResponse<T> {
|
|
56
|
+
/** Array of items for the current page */
|
|
2
57
|
items: T[];
|
|
58
|
+
/** Total number of items across all pages */
|
|
3
59
|
total: number;
|
|
60
|
+
/** Current page number (1-indexed) */
|
|
4
61
|
page: number;
|
|
62
|
+
/** Number of items per page */
|
|
5
63
|
pageSize: number;
|
|
64
|
+
/** Whether more pages exist after the current page (page * pageSize \< total) */
|
|
6
65
|
hasMore: boolean;
|
|
7
66
|
}
|
|
@@ -1,21 +1,123 @@
|
|
|
1
1
|
import { Account } from './Account';
|
|
2
2
|
import { Price } from './Price';
|
|
3
|
+
import { PortfolioAsset } from './PortfolioAsset';
|
|
4
|
+
import { Metadata } from './Metadata';
|
|
5
|
+
/**
|
|
6
|
+
* Complete user portfolio aggregating all accounts and holdings.
|
|
7
|
+
*
|
|
8
|
+
* Top-level aggregate combining all user accounts, positions, and assets into
|
|
9
|
+
* a unified portfolio view. Calculates total value, tracks historical performance,
|
|
10
|
+
* and maintains deduplicated asset lists across accounts.
|
|
11
|
+
*
|
|
12
|
+
* **Design Pattern:** Aggregate root pattern at portfolio level, composing multiple
|
|
13
|
+
* Account aggregates. Supports both account-based view (accounts array) and
|
|
14
|
+
* asset-based view (items array) for flexible UI rendering.
|
|
15
|
+
*
|
|
16
|
+
* **Aggregation Rules:**
|
|
17
|
+
* - totalValue = sum of all Account.totalValue
|
|
18
|
+
* - items = deduplicated PortfolioAssets across all accounts (same asset, different accounts)
|
|
19
|
+
* - performance = calculated from totalValueHistory changes
|
|
20
|
+
*
|
|
21
|
+
* @example
|
|
22
|
+
* ```typescript
|
|
23
|
+
* import { Portfolio } from '@cygnus-wealth/data-models';
|
|
24
|
+
*
|
|
25
|
+
* // Complete portfolio with multiple accounts
|
|
26
|
+
* const userPortfolio: Portfolio = {
|
|
27
|
+
* id: 'portfolio-user-123',
|
|
28
|
+
* userId: 'user-123',
|
|
29
|
+
* name: 'My Portfolio',
|
|
30
|
+
* accounts: [
|
|
31
|
+
* {
|
|
32
|
+
* id: 'metamask-wallet-1',
|
|
33
|
+
* name: 'Main Wallet',
|
|
34
|
+
* type: AccountType.WALLET,
|
|
35
|
+
* source: IntegrationSource.METAMASK,
|
|
36
|
+
* balances: [...],
|
|
37
|
+
* totalValue: { value: 50000, currency: 'USD', timestamp: new Date() }
|
|
38
|
+
* },
|
|
39
|
+
* {
|
|
40
|
+
* id: 'kraken-spot-1',
|
|
41
|
+
* name: 'Kraken Trading',
|
|
42
|
+
* type: AccountType.SPOT,
|
|
43
|
+
* source: IntegrationSource.KRAKEN,
|
|
44
|
+
* balances: [...],
|
|
45
|
+
* totalValue: { value: 30000, currency: 'USD', timestamp: new Date() }
|
|
46
|
+
* }
|
|
47
|
+
* ],
|
|
48
|
+
* items: [
|
|
49
|
+
* {
|
|
50
|
+
* id: 'portfolio-eth',
|
|
51
|
+
* assetId: 'ethereum-eth',
|
|
52
|
+
* asset: { symbol: 'ETH', name: 'Ethereum', ... },
|
|
53
|
+
* balance: { amount: '10.0', ... },
|
|
54
|
+
* value: { value: 20000, currency: 'USD', timestamp: new Date() },
|
|
55
|
+
* allocation: 0.25 // 25% of portfolio
|
|
56
|
+
* },
|
|
57
|
+
* // ... more assets
|
|
58
|
+
* ],
|
|
59
|
+
* totalValue: {
|
|
60
|
+
* value: 80000, // Sum of all accounts
|
|
61
|
+
* currency: 'USD',
|
|
62
|
+
* timestamp: new Date()
|
|
63
|
+
* },
|
|
64
|
+
* totalValueHistory: [
|
|
65
|
+
* { timestamp: new Date('2025-09-11'), value: { value: 75000, currency: 'USD', ... } },
|
|
66
|
+
* { timestamp: new Date('2025-10-11'), value: { value: 80000, currency: 'USD', ... } }
|
|
67
|
+
* ],
|
|
68
|
+
* performance: {
|
|
69
|
+
* day: 2.5, // +2.5% today
|
|
70
|
+
* week: 5.0, // +5.0% this week
|
|
71
|
+
* month: 6.67, // +6.67% this month
|
|
72
|
+
* year: 45.0, // +45% this year
|
|
73
|
+
* all_time: 60.0 // +60% all-time
|
|
74
|
+
* },
|
|
75
|
+
* lastUpdated: new Date()
|
|
76
|
+
* };
|
|
77
|
+
* ```
|
|
78
|
+
*
|
|
79
|
+
* @since 0.0.1
|
|
80
|
+
* @stability standard
|
|
81
|
+
*
|
|
82
|
+
* @see {@link Account} for individual account aggregation
|
|
83
|
+
* @see {@link PortfolioAsset} for asset composition
|
|
84
|
+
* @see {@link Price} for valuation structure
|
|
85
|
+
*/
|
|
3
86
|
export interface Portfolio {
|
|
87
|
+
/** Unique identifier for this portfolio */
|
|
4
88
|
id: string;
|
|
5
|
-
|
|
89
|
+
/** User ID owning this portfolio (for multi-user systems) */
|
|
90
|
+
userId?: string;
|
|
91
|
+
/** User-friendly portfolio name */
|
|
6
92
|
name: string;
|
|
7
|
-
accounts
|
|
93
|
+
/** Array of all accounts in this portfolio */
|
|
94
|
+
accounts?: Account[];
|
|
95
|
+
/** Deduplicated array of all assets across accounts */
|
|
96
|
+
items?: PortfolioAsset[];
|
|
97
|
+
/** Total value of entire portfolio (sum of all account values) */
|
|
8
98
|
totalValue: Price;
|
|
99
|
+
/** Historical value snapshots for performance tracking */
|
|
9
100
|
totalValueHistory?: Array<{
|
|
101
|
+
/** Timestamp of the snapshot */
|
|
10
102
|
timestamp: Date;
|
|
103
|
+
/** Portfolio value at that time */
|
|
11
104
|
value: Price;
|
|
12
105
|
}>;
|
|
106
|
+
/** Performance metrics as percentage changes (positive = gain, negative = loss) */
|
|
13
107
|
performance?: {
|
|
108
|
+
/** 24-hour performance change percentage */
|
|
14
109
|
day: number;
|
|
110
|
+
/** 7-day performance change percentage */
|
|
15
111
|
week: number;
|
|
112
|
+
/** 30-day performance change percentage */
|
|
16
113
|
month: number;
|
|
114
|
+
/** 365-day performance change percentage */
|
|
17
115
|
year: number;
|
|
116
|
+
/** All-time performance change percentage */
|
|
18
117
|
all_time: number;
|
|
19
118
|
};
|
|
119
|
+
/** Timestamp of last portfolio data update */
|
|
20
120
|
lastUpdated: Date;
|
|
121
|
+
/** Portfolio-specific metadata (theme, display preferences, etc.) */
|
|
122
|
+
metadata?: Metadata;
|
|
21
123
|
}
|