@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
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
import { Asset } from './Asset';
|
|
2
|
+
import { Balance } from './Balance';
|
|
3
|
+
import { Price } from './Price';
|
|
4
|
+
/**
|
|
5
|
+
* Asset with balance and market valuation for portfolio display.
|
|
6
|
+
*
|
|
7
|
+
* Composed view combining asset details, quantity held, current market value,
|
|
8
|
+
* and portfolio allocation percentage. Primary interface for displaying assets
|
|
9
|
+
* in portfolio dashboards and aggregation views.
|
|
10
|
+
*
|
|
11
|
+
* **Design Pattern:** Composition of Asset + Balance + Price + allocation metrics
|
|
12
|
+
* to provide a complete, ready-to-render portfolio item. Simplifies UI logic by
|
|
13
|
+
* pre-joining related data.
|
|
14
|
+
*
|
|
15
|
+
* @example
|
|
16
|
+
* ```typescript
|
|
17
|
+
* import { PortfolioAsset } from '@cygnus-wealth/data-models';
|
|
18
|
+
*
|
|
19
|
+
* // Complete portfolio asset ready for display
|
|
20
|
+
* const portfolioAsset: PortfolioAsset = {
|
|
21
|
+
* id: 'portfolio-item-1',
|
|
22
|
+
* accountId: 'metamask-wallet-1',
|
|
23
|
+
* assetId: 'ethereum-usdc',
|
|
24
|
+
* asset: {
|
|
25
|
+
* id: 'ethereum-usdc',
|
|
26
|
+
* symbol: 'USDC',
|
|
27
|
+
* name: 'USD Coin',
|
|
28
|
+
* type: AssetType.CRYPTOCURRENCY,
|
|
29
|
+
* decimals: 6
|
|
30
|
+
* },
|
|
31
|
+
* balance: {
|
|
32
|
+
* assetId: 'ethereum-usdc',
|
|
33
|
+
* asset: {...}, // Same as above
|
|
34
|
+
* amount: '10000',
|
|
35
|
+
* value: {
|
|
36
|
+
* value: 10000,
|
|
37
|
+
* currency: 'USD',
|
|
38
|
+
* timestamp: new Date()
|
|
39
|
+
* }
|
|
40
|
+
* },
|
|
41
|
+
* value: {
|
|
42
|
+
* value: 10000,
|
|
43
|
+
* currency: 'USD',
|
|
44
|
+
* timestamp: new Date()
|
|
45
|
+
* },
|
|
46
|
+
* allocation: 0.25, // 25% of total portfolio
|
|
47
|
+
* lastUpdated: new Date()
|
|
48
|
+
* };
|
|
49
|
+
* ```
|
|
50
|
+
*
|
|
51
|
+
* @since 0.0.1
|
|
52
|
+
* @stability standard
|
|
53
|
+
*
|
|
54
|
+
* @see {@link Asset} for asset details
|
|
55
|
+
* @see {@link Balance} for quantity and P&L
|
|
56
|
+
* @see {@link Price} for valuation
|
|
57
|
+
* @see {@link Portfolio} for aggregated portfolio view
|
|
58
|
+
*/
|
|
59
|
+
export interface PortfolioAsset {
|
|
60
|
+
/** Unique identifier for this portfolio item */
|
|
61
|
+
id: string;
|
|
62
|
+
/** Reference to the account holding this asset */
|
|
63
|
+
accountId: string;
|
|
64
|
+
/** Reference to the Asset.id */
|
|
65
|
+
assetId: string;
|
|
66
|
+
/** Complete asset definition including symbol, name, type, etc. */
|
|
67
|
+
asset: Asset;
|
|
68
|
+
/** Balance details including amount, cost basis, and P&L */
|
|
69
|
+
balance: Balance;
|
|
70
|
+
/** Current total market value of this position */
|
|
71
|
+
value: Price;
|
|
72
|
+
/** Percentage of total portfolio value (0.0-1.0, e.g., 0.25 = 25%) */
|
|
73
|
+
allocation: number;
|
|
74
|
+
/** Timestamp of last data update for this asset */
|
|
75
|
+
lastUpdated: Date;
|
|
76
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -1,4 +1,17 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Legacy portfolio item interface.
|
|
3
|
+
*
|
|
4
|
+
* @deprecated Since v0.2.0. Use {@link PortfolioAsset} instead.
|
|
5
|
+
* Will be removed in v2.0.0.
|
|
6
|
+
*
|
|
7
|
+
* @since 0.0.1
|
|
8
|
+
* @stability core
|
|
9
|
+
*
|
|
10
|
+
* @see {@link PortfolioAsset} for replacement interface
|
|
11
|
+
*/
|
|
1
12
|
export interface PortfolioItem {
|
|
13
|
+
/** Legacy identifier */
|
|
2
14
|
id: string;
|
|
15
|
+
/** Legacy balance field (replaced by Balance.amount) */
|
|
3
16
|
balance: number;
|
|
4
17
|
}
|
|
@@ -1,7 +1,50 @@
|
|
|
1
1
|
import { IntegrationSource } from '../enums/IntegrationSource';
|
|
2
|
+
/**
|
|
3
|
+
* Point-in-time asset price with currency and timestamp.
|
|
4
|
+
*
|
|
5
|
+
* Essential for portfolio valuation, historical tracking, and performance
|
|
6
|
+
* calculations. Supports multiple price representations (value and amount)
|
|
7
|
+
* to accommodate different data sources.
|
|
8
|
+
*
|
|
9
|
+
* **Design Pattern:** Simple value object with timestamp for price history
|
|
10
|
+
* and source attribution for data quality tracking. Either value or amount
|
|
11
|
+
* should be present.
|
|
12
|
+
*
|
|
13
|
+
* @example
|
|
14
|
+
* ```typescript
|
|
15
|
+
* import { Price, IntegrationSource } from '@cygnus-wealth/data-models';
|
|
16
|
+
*
|
|
17
|
+
* // Market price from price feed
|
|
18
|
+
* const currentPrice: Price = {
|
|
19
|
+
* value: 2000.00,
|
|
20
|
+
* currency: 'USD',
|
|
21
|
+
* timestamp: new Date('2025-10-11T10:30:00Z'),
|
|
22
|
+
* source: IntegrationSource.BLOCKCHAIN_DIRECT
|
|
23
|
+
* };
|
|
24
|
+
*
|
|
25
|
+
* // Historical price for performance calculation
|
|
26
|
+
* const historicalPrice: Price = {
|
|
27
|
+
* amount: 1800.00,
|
|
28
|
+
* currency: 'USD',
|
|
29
|
+
* timestamp: new Date('2025-09-11T10:30:00Z')
|
|
30
|
+
* };
|
|
31
|
+
* ```
|
|
32
|
+
*
|
|
33
|
+
* @since 0.0.1
|
|
34
|
+
* @stability standard
|
|
35
|
+
*
|
|
36
|
+
* @see {@link MarketData} for extended market information
|
|
37
|
+
* @see {@link Balance} for asset valuation usage
|
|
38
|
+
*/
|
|
2
39
|
export interface Price {
|
|
3
|
-
value
|
|
40
|
+
/** Price value (primary field for current prices) */
|
|
41
|
+
value?: number;
|
|
42
|
+
/** Alternative price field (used by some data sources) */
|
|
43
|
+
amount?: number;
|
|
44
|
+
/** Currency code (ISO 4217 for fiat, symbol for crypto, e.g., 'USD', 'ETH') */
|
|
4
45
|
currency: string;
|
|
46
|
+
/** Timestamp when this price was recorded or fetched */
|
|
5
47
|
timestamp: Date;
|
|
6
|
-
source
|
|
48
|
+
/** Data source providing this price (for quality tracking) */
|
|
49
|
+
source?: IntegrationSource;
|
|
7
50
|
}
|
|
@@ -3,17 +3,94 @@ import { Asset } from './Asset';
|
|
|
3
3
|
import { Balance } from './Balance';
|
|
4
4
|
import { Price } from './Price';
|
|
5
5
|
import { Metadata } from './Metadata';
|
|
6
|
+
/**
|
|
7
|
+
* Proof-of-stake and staking derivative positions with rewards tracking.
|
|
8
|
+
*
|
|
9
|
+
* Represents staked assets in proof-of-stake networks (direct validation) or
|
|
10
|
+
* liquid staking protocols (derivative tokens). Tracks staked amount, earned
|
|
11
|
+
* rewards, lockup periods, APR, and validator information.
|
|
12
|
+
*
|
|
13
|
+
* **Design Pattern:** DeFi position entity for staking operations, supporting
|
|
14
|
+
* both direct staking (ETH validators) and liquid staking (stETH, rETH).
|
|
15
|
+
* Rewards array handles multiple reward tokens common in DeFi protocols.
|
|
16
|
+
*
|
|
17
|
+
* @example
|
|
18
|
+
* ```typescript
|
|
19
|
+
* import { StakedPosition, Chain, AssetType } from '@cygnus-wealth/data-models';
|
|
20
|
+
*
|
|
21
|
+
* // Lido stETH liquid staking position
|
|
22
|
+
* const lidoPosition: StakedPosition = {
|
|
23
|
+
* id: 'lido-steth-123',
|
|
24
|
+
* protocol: 'Lido',
|
|
25
|
+
* chain: Chain.ETHEREUM,
|
|
26
|
+
* asset: {
|
|
27
|
+
* id: 'ethereum-eth',
|
|
28
|
+
* symbol: 'ETH',
|
|
29
|
+
* name: 'Ethereum',
|
|
30
|
+
* type: AssetType.CRYPTOCURRENCY,
|
|
31
|
+
* decimals: 18
|
|
32
|
+
* },
|
|
33
|
+
* stakedAmount: '32.0', // 32 ETH staked
|
|
34
|
+
* rewards: [
|
|
35
|
+
* {
|
|
36
|
+
* assetId: 'ethereum-steth',
|
|
37
|
+
* asset: {...},
|
|
38
|
+
* amount: '0.45' // Accrued staking rewards
|
|
39
|
+
* }
|
|
40
|
+
* ],
|
|
41
|
+
* apr: 4.2, // 4.2% annual percentage rate
|
|
42
|
+
* value: {
|
|
43
|
+
* value: 64000,
|
|
44
|
+
* currency: 'USD',
|
|
45
|
+
* timestamp: new Date()
|
|
46
|
+
* }
|
|
47
|
+
* };
|
|
48
|
+
*
|
|
49
|
+
* // Direct validator staking with lockup
|
|
50
|
+
* const validatorPosition: StakedPosition = {
|
|
51
|
+
* id: 'validator-eth-456',
|
|
52
|
+
* protocol: 'Ethereum 2.0',
|
|
53
|
+
* validator: '0x123abc...',
|
|
54
|
+
* chain: Chain.ETHEREUM,
|
|
55
|
+
* asset: {...},
|
|
56
|
+
* stakedAmount: '32.0',
|
|
57
|
+
* rewards: [],
|
|
58
|
+
* lockupPeriod: 2592000, // 30 days in seconds
|
|
59
|
+
* unlockDate: new Date('2025-11-10'),
|
|
60
|
+
* apr: 3.8
|
|
61
|
+
* };
|
|
62
|
+
* ```
|
|
63
|
+
*
|
|
64
|
+
* @since 0.0.1
|
|
65
|
+
* @stability extended
|
|
66
|
+
*
|
|
67
|
+
* @see {@link Asset} for staked asset definition
|
|
68
|
+
* @see {@link Balance} for reward balance structure
|
|
69
|
+
* @see {@link Account} for position aggregation
|
|
70
|
+
*/
|
|
6
71
|
export interface StakedPosition {
|
|
72
|
+
/** Unique identifier for this staking position */
|
|
7
73
|
id: string;
|
|
74
|
+
/** Staking protocol or platform name (e.g., 'Lido', 'Rocket Pool', 'Ethereum 2.0') */
|
|
8
75
|
protocol: string;
|
|
76
|
+
/** Validator address or ID (for direct staking, optional for liquid staking) */
|
|
9
77
|
validator?: string;
|
|
78
|
+
/** Blockchain network where assets are staked */
|
|
10
79
|
chain: Chain;
|
|
80
|
+
/** Asset being staked (e.g., ETH, SOL, MATIC) */
|
|
11
81
|
asset: Asset;
|
|
82
|
+
/** Amount of asset staked (as string for precision) */
|
|
12
83
|
stakedAmount: string;
|
|
84
|
+
/** Array of reward balances (can be multiple tokens in some protocols) */
|
|
13
85
|
rewards: Balance[];
|
|
86
|
+
/** Lockup period in seconds before unstaking is allowed */
|
|
14
87
|
lockupPeriod?: number;
|
|
88
|
+
/** Date when the lockup expires and unstaking becomes available */
|
|
15
89
|
unlockDate?: Date;
|
|
90
|
+
/** Annual Percentage Rate for rewards (e.g., 4.2 = 4.2%) */
|
|
16
91
|
apr?: number;
|
|
92
|
+
/** Current total value of staked position plus rewards */
|
|
17
93
|
value?: Price;
|
|
94
|
+
/** Protocol-specific metadata (validator performance, slashing history, etc.) */
|
|
18
95
|
metadata?: Metadata;
|
|
19
96
|
}
|
|
@@ -1,11 +1,66 @@
|
|
|
1
1
|
import { IntegrationSource } from '../enums/IntegrationSource';
|
|
2
2
|
import { Metadata } from './Metadata';
|
|
3
|
+
/**
|
|
4
|
+
* Track data synchronization state for accounts and integrations.
|
|
5
|
+
*
|
|
6
|
+
* Monitors the status and history of data synchronization operations from external
|
|
7
|
+
* sources (CEX, DEX, wallets). Essential for UI loading states, error handling,
|
|
8
|
+
* and determining data freshness.
|
|
9
|
+
*
|
|
10
|
+
* **Design Pattern:** State machine pattern with four states (IDLE, SYNCING, SUCCESS, ERROR)
|
|
11
|
+
* tracking both current status and historical sync information for troubleshooting.
|
|
12
|
+
*
|
|
13
|
+
* @example
|
|
14
|
+
* ```typescript
|
|
15
|
+
* import { SyncStatus, IntegrationSource } from '@cygnus-wealth/data-models';
|
|
16
|
+
*
|
|
17
|
+
* // Successful sync status
|
|
18
|
+
* const successStatus: SyncStatus = {
|
|
19
|
+
* source: IntegrationSource.KRAKEN,
|
|
20
|
+
* accountId: 'kraken-spot-1',
|
|
21
|
+
* status: 'SUCCESS',
|
|
22
|
+
* lastSyncTime: new Date('2025-10-11T10:30:00Z'),
|
|
23
|
+
* itemsSynced: 150 // 150 items fetched
|
|
24
|
+
* };
|
|
25
|
+
*
|
|
26
|
+
* // Active syncing status
|
|
27
|
+
* const syncingStatus: SyncStatus = {
|
|
28
|
+
* source: IntegrationSource.METAMASK,
|
|
29
|
+
* accountId: 'wallet-1',
|
|
30
|
+
* status: 'SYNCING',
|
|
31
|
+
* lastSyncTime: new Date('2025-10-11T10:25:00Z')
|
|
32
|
+
* };
|
|
33
|
+
*
|
|
34
|
+
* // Error status with details
|
|
35
|
+
* const errorStatus: SyncStatus = {
|
|
36
|
+
* source: IntegrationSource.COINBASE,
|
|
37
|
+
* accountId: 'coinbase-spot-1',
|
|
38
|
+
* status: 'ERROR',
|
|
39
|
+
* lastSyncTime: new Date('2025-10-11T10:20:00Z'),
|
|
40
|
+
* lastError: 'Rate limit exceeded. Retry after 60 seconds.',
|
|
41
|
+
* itemsSynced: 0
|
|
42
|
+
* };
|
|
43
|
+
* ```
|
|
44
|
+
*
|
|
45
|
+
* @since 0.0.1
|
|
46
|
+
* @stability standard
|
|
47
|
+
*
|
|
48
|
+
* @see {@link IntegrationSource} for data source identification
|
|
49
|
+
* @see {@link Account} for account synchronization
|
|
50
|
+
*/
|
|
3
51
|
export interface SyncStatus {
|
|
52
|
+
/** Data source being synchronized */
|
|
4
53
|
source: IntegrationSource;
|
|
54
|
+
/** Reference to Account.id being synchronized */
|
|
5
55
|
accountId: string;
|
|
56
|
+
/** Current synchronization status */
|
|
6
57
|
status: 'IDLE' | 'SYNCING' | 'SUCCESS' | 'ERROR';
|
|
58
|
+
/** Timestamp of last sync attempt (successful or failed) */
|
|
7
59
|
lastSyncTime?: Date;
|
|
60
|
+
/** Error message from last failed sync attempt */
|
|
8
61
|
lastError?: string;
|
|
62
|
+
/** Number of items successfully fetched in last sync */
|
|
9
63
|
itemsSynced?: number;
|
|
64
|
+
/** Source-specific metadata (retry count, rate limit info, etc.) */
|
|
10
65
|
metadata?: Metadata;
|
|
11
66
|
}
|
|
@@ -3,33 +3,145 @@ import { Chain } from '../enums/Chain';
|
|
|
3
3
|
import { Asset } from './Asset';
|
|
4
4
|
import { Price } from './Price';
|
|
5
5
|
import { Metadata } from './Metadata';
|
|
6
|
+
/**
|
|
7
|
+
* Universal transaction representation across all sources.
|
|
8
|
+
*
|
|
9
|
+
* Normalized transaction model supporting blockchain transfers, CEX trades,
|
|
10
|
+
* DEX swaps, DeFi operations, and traditional finance transactions. Uses
|
|
11
|
+
* asset flow pattern (assetsIn/assetsOut) to handle complex multi-asset
|
|
12
|
+
* operations like swaps, liquidity provision, and protocol interactions.
|
|
13
|
+
*
|
|
14
|
+
* **Design Pattern:** Event sourcing pattern with asset flow arrays supporting
|
|
15
|
+
* 1:1 transfers, 1:N distributions, N:1 swaps, and N:M complex operations.
|
|
16
|
+
* Status field enables tracking pending and failed transactions.
|
|
17
|
+
*
|
|
18
|
+
* @example
|
|
19
|
+
* ```typescript
|
|
20
|
+
* import { Transaction, TransactionType, Chain } from '@cygnus-wealth/data-models';
|
|
21
|
+
*
|
|
22
|
+
* // Simple blockchain transfer
|
|
23
|
+
* const transfer: Transaction = {
|
|
24
|
+
* id: 'tx-0x123abc',
|
|
25
|
+
* accountId: 'wallet-1',
|
|
26
|
+
* type: TransactionType.TRANSFER_OUT,
|
|
27
|
+
* status: 'COMPLETED',
|
|
28
|
+
* hash: '0x123abc...',
|
|
29
|
+
* chain: Chain.ETHEREUM,
|
|
30
|
+
* from: '0xSender...',
|
|
31
|
+
* to: '0xRecipient...',
|
|
32
|
+
* timestamp: new Date('2025-10-11T10:30:00Z'),
|
|
33
|
+
* blockNumber: 18500000,
|
|
34
|
+
* assetsOut: [{
|
|
35
|
+
* asset: { id: 'ethereum-eth', symbol: 'ETH', ... },
|
|
36
|
+
* amount: '1.5',
|
|
37
|
+
* value: { value: 3000, currency: 'USD', timestamp: new Date() }
|
|
38
|
+
* }],
|
|
39
|
+
* fees: [{
|
|
40
|
+
* asset: { id: 'ethereum-eth', symbol: 'ETH', ... },
|
|
41
|
+
* amount: '0.002',
|
|
42
|
+
* value: { value: 4, currency: 'USD', timestamp: new Date() }
|
|
43
|
+
* }]
|
|
44
|
+
* };
|
|
45
|
+
*
|
|
46
|
+
* // DEX swap (ETH -> USDC)
|
|
47
|
+
* const swap: Transaction = {
|
|
48
|
+
* id: 'tx-0x456def',
|
|
49
|
+
* accountId: 'wallet-1',
|
|
50
|
+
* type: TransactionType.SWAP,
|
|
51
|
+
* status: 'COMPLETED',
|
|
52
|
+
* hash: '0x456def...',
|
|
53
|
+
* chain: Chain.ETHEREUM,
|
|
54
|
+
* timestamp: new Date(),
|
|
55
|
+
* blockNumber: 18500123,
|
|
56
|
+
* assetsOut: [{
|
|
57
|
+
* asset: { id: 'ethereum-eth', symbol: 'ETH', ... },
|
|
58
|
+
* amount: '2.0'
|
|
59
|
+
* }],
|
|
60
|
+
* assetsIn: [{
|
|
61
|
+
* asset: { id: 'ethereum-usdc', symbol: 'USDC', ... },
|
|
62
|
+
* amount: '4000'
|
|
63
|
+
* }],
|
|
64
|
+
* protocol: 'Uniswap V3',
|
|
65
|
+
* method: 'swapExactTokensForTokens'
|
|
66
|
+
* };
|
|
67
|
+
*
|
|
68
|
+
* // CEX trade
|
|
69
|
+
* const trade: Transaction = {
|
|
70
|
+
* id: 'kraken-trade-789',
|
|
71
|
+
* accountId: 'kraken-spot-1',
|
|
72
|
+
* type: TransactionType.BUY,
|
|
73
|
+
* status: 'COMPLETED',
|
|
74
|
+
* timestamp: new Date(),
|
|
75
|
+
* assetsOut: [{
|
|
76
|
+
* asset: { id: 'fiat-usd', symbol: 'USD', ... },
|
|
77
|
+
* amount: '5000'
|
|
78
|
+
* }],
|
|
79
|
+
* assetsIn: [{
|
|
80
|
+
* asset: { id: 'bitcoin-btc', symbol: 'BTC', ... },
|
|
81
|
+
* amount: '0.1'
|
|
82
|
+
* }]
|
|
83
|
+
* };
|
|
84
|
+
* ```
|
|
85
|
+
*
|
|
86
|
+
* @since 0.0.1
|
|
87
|
+
* @stability standard
|
|
88
|
+
*
|
|
89
|
+
* @see {@link TransactionType} for operation classification
|
|
90
|
+
* @see {@link Asset} for asset definitions in flows
|
|
91
|
+
* @see {@link Account} for transaction aggregation
|
|
92
|
+
*/
|
|
6
93
|
export interface Transaction {
|
|
94
|
+
/** Unique transaction identifier (blockchain hash, CEX order ID, etc.) */
|
|
7
95
|
id: string;
|
|
96
|
+
/** Reference to the Account.id where this transaction occurred */
|
|
8
97
|
accountId: string;
|
|
98
|
+
/** Type of transaction operation */
|
|
9
99
|
type: TransactionType;
|
|
100
|
+
/** Transaction status for lifecycle tracking */
|
|
10
101
|
status: 'PENDING' | 'COMPLETED' | 'FAILED' | 'CANCELLED';
|
|
102
|
+
/** Blockchain transaction hash (for on-chain transactions) */
|
|
11
103
|
hash?: string;
|
|
104
|
+
/** Blockchain network where transaction occurred (for on-chain transactions) */
|
|
12
105
|
chain?: Chain;
|
|
106
|
+
/** Sender address (for blockchain transfers) */
|
|
13
107
|
from?: string;
|
|
108
|
+
/** Recipient address (for blockchain transfers) */
|
|
14
109
|
to?: string;
|
|
110
|
+
/** Timestamp when transaction was created or executed */
|
|
15
111
|
timestamp: Date;
|
|
112
|
+
/** Block number where transaction was included (for on-chain transactions) */
|
|
16
113
|
blockNumber?: number;
|
|
17
|
-
|
|
114
|
+
/** Assets received in this transaction */
|
|
115
|
+
assetsIn?: Array<{
|
|
116
|
+
/** Asset received */
|
|
18
117
|
asset: Asset;
|
|
118
|
+
/** Amount received (as string for precision) */
|
|
19
119
|
amount: string;
|
|
120
|
+
/** Value at transaction time (optional) */
|
|
20
121
|
value?: Price;
|
|
21
122
|
}>;
|
|
22
|
-
|
|
123
|
+
/** Assets sent or consumed in this transaction */
|
|
124
|
+
assetsOut?: Array<{
|
|
125
|
+
/** Asset sent */
|
|
23
126
|
asset: Asset;
|
|
127
|
+
/** Amount sent (as string for precision) */
|
|
24
128
|
amount: string;
|
|
129
|
+
/** Value at transaction time (optional) */
|
|
25
130
|
value?: Price;
|
|
26
131
|
}>;
|
|
132
|
+
/** Transaction fees paid (gas, network fees, exchange fees) */
|
|
27
133
|
fees?: Array<{
|
|
134
|
+
/** Fee asset (ETH for gas, native token for network fees) */
|
|
28
135
|
asset: Asset;
|
|
136
|
+
/** Fee amount (as string for precision) */
|
|
29
137
|
amount: string;
|
|
138
|
+
/** Fee value at transaction time (optional) */
|
|
30
139
|
value?: Price;
|
|
31
140
|
}>;
|
|
141
|
+
/** DeFi protocol or platform involved (e.g., 'Uniswap V3', 'Aave V2') */
|
|
32
142
|
protocol?: string;
|
|
143
|
+
/** Smart contract method called (for on-chain transactions) */
|
|
33
144
|
method?: string;
|
|
145
|
+
/** Source-specific additional data (confirmations, memo, etc.) */
|
|
34
146
|
metadata?: Metadata;
|
|
35
147
|
}
|
|
@@ -1,7 +1,68 @@
|
|
|
1
1
|
import { Chain } from '../enums/Chain';
|
|
2
|
+
/**
|
|
3
|
+
* Flexible asset lookup criteria requiring at least one identifier.
|
|
4
|
+
*
|
|
5
|
+
* Used for asset resolution and lookup operations where different identification
|
|
6
|
+
* methods may be available (symbol, contract address, database ID). At least
|
|
7
|
+
* one field must be provided for successful asset identification.
|
|
8
|
+
*
|
|
9
|
+
* **Design Pattern:** Partial type enabling flexible asset lookup based on
|
|
10
|
+
* available information. Useful for user input, API queries, and data normalization.
|
|
11
|
+
*
|
|
12
|
+
* @example
|
|
13
|
+
* ```typescript
|
|
14
|
+
* import { AssetIdentifier, Chain } from '@cygnus-wealth/data-models';
|
|
15
|
+
*
|
|
16
|
+
* // Lookup by symbol only
|
|
17
|
+
* const symbolLookup: AssetIdentifier = {
|
|
18
|
+
* symbol: 'ETH'
|
|
19
|
+
* };
|
|
20
|
+
*
|
|
21
|
+
* // Lookup by contract address (most precise)
|
|
22
|
+
* const contractLookup: AssetIdentifier = {
|
|
23
|
+
* contractAddress: '0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48',
|
|
24
|
+
* chain: Chain.ETHEREUM
|
|
25
|
+
* };
|
|
26
|
+
*
|
|
27
|
+
* // Lookup by symbol + chain (for disambiguation)
|
|
28
|
+
* const chainedLookup: AssetIdentifier = {
|
|
29
|
+
* symbol: 'USDC',
|
|
30
|
+
* chain: Chain.POLYGON // Distinguish from Ethereum USDC
|
|
31
|
+
* };
|
|
32
|
+
*
|
|
33
|
+
* // Lookup by internal ID
|
|
34
|
+
* const idLookup: AssetIdentifier = {
|
|
35
|
+
* assetId: 'ethereum-usdc'
|
|
36
|
+
* };
|
|
37
|
+
*
|
|
38
|
+
* // Asset resolution function example
|
|
39
|
+
* async function findAsset(identifier: AssetIdentifier): Promise<Asset | null> {
|
|
40
|
+
* if (identifier.assetId) {
|
|
41
|
+
* return await db.assets.findById(identifier.assetId);
|
|
42
|
+
* }
|
|
43
|
+
* if (identifier.contractAddress && identifier.chain) {
|
|
44
|
+
* return await db.assets.findByContract(identifier.contractAddress, identifier.chain);
|
|
45
|
+
* }
|
|
46
|
+
* if (identifier.symbol) {
|
|
47
|
+
* return await db.assets.findBySymbol(identifier.symbol, identifier.chain);
|
|
48
|
+
* }
|
|
49
|
+
* return null;
|
|
50
|
+
* }
|
|
51
|
+
* ```
|
|
52
|
+
*
|
|
53
|
+
* @since 0.0.1
|
|
54
|
+
* @stability standard
|
|
55
|
+
*
|
|
56
|
+
* @see {@link Asset} for full asset structure
|
|
57
|
+
* @see {@link Chain} for blockchain identification
|
|
58
|
+
*/
|
|
2
59
|
export type AssetIdentifier = {
|
|
60
|
+
/** Asset trading symbol (e.g., 'ETH', 'USDC', 'BTC') */
|
|
3
61
|
symbol?: string;
|
|
62
|
+
/** Smart contract address for on-chain assets */
|
|
4
63
|
contractAddress?: string;
|
|
64
|
+
/** Blockchain network for contract-based assets */
|
|
5
65
|
chain?: Chain;
|
|
66
|
+
/** Internal database asset ID */
|
|
6
67
|
assetId?: string;
|
|
7
68
|
};
|
|
@@ -1 +1,51 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Sort direction for query results.
|
|
3
|
+
*
|
|
4
|
+
* Standard sort order specification for ordering collections in ascending
|
|
5
|
+
* or descending order. Used in query parameters, API requests, and UI controls.
|
|
6
|
+
*
|
|
7
|
+
* @example
|
|
8
|
+
* ```typescript
|
|
9
|
+
* import { SortOrder, Transaction } from '@cygnus-wealth/data-models';
|
|
10
|
+
*
|
|
11
|
+
* // Sort transactions by timestamp descending (newest first)
|
|
12
|
+
* function sortTransactions(
|
|
13
|
+
* transactions: Transaction[],
|
|
14
|
+
* order: SortOrder = 'DESC'
|
|
15
|
+
* ): Transaction[] {
|
|
16
|
+
* return [...transactions].sort((a, b) => {
|
|
17
|
+
* const comparison = a.timestamp.getTime() - b.timestamp.getTime();
|
|
18
|
+
* return order === 'ASC' ? comparison : -comparison;
|
|
19
|
+
* });
|
|
20
|
+
* }
|
|
21
|
+
*
|
|
22
|
+
* // Sort assets by value ascending (smallest first)
|
|
23
|
+
* function sortAssetsByValue(
|
|
24
|
+
* assets: PortfolioAsset[],
|
|
25
|
+
* order: SortOrder = 'ASC'
|
|
26
|
+
* ): PortfolioAsset[] {
|
|
27
|
+
* return [...assets].sort((a, b) => {
|
|
28
|
+
* const comparison = (a.value.value || 0) - (b.value.value || 0);
|
|
29
|
+
* return order === 'ASC' ? comparison : -comparison;
|
|
30
|
+
* });
|
|
31
|
+
* }
|
|
32
|
+
*
|
|
33
|
+
* // API query with sort order
|
|
34
|
+
* interface QueryParams {
|
|
35
|
+
* sortBy: 'timestamp' | 'value' | 'symbol';
|
|
36
|
+
* order: SortOrder;
|
|
37
|
+
* }
|
|
38
|
+
*
|
|
39
|
+
* const query: QueryParams = {
|
|
40
|
+
* sortBy: 'timestamp',
|
|
41
|
+
* order: 'DESC' // Most recent first
|
|
42
|
+
* };
|
|
43
|
+
* ```
|
|
44
|
+
*
|
|
45
|
+
* @since 0.0.1
|
|
46
|
+
* @stability standard
|
|
47
|
+
*
|
|
48
|
+
* @see {@link PaginatedResponse} for paginated sorting
|
|
49
|
+
* @see {@link FilterOptions} for combined filtering and sorting
|
|
50
|
+
*/
|
|
1
51
|
export type SortOrder = 'ASC' | 'DESC';
|
|
@@ -1,4 +1,55 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Time range specification for filtering and queries.
|
|
3
|
+
*
|
|
4
|
+
* Defines an inclusive time range with start and end boundaries in UTC.
|
|
5
|
+
* Used for filtering transactions, performance calculations, and historical
|
|
6
|
+
* data queries.
|
|
7
|
+
*
|
|
8
|
+
* **Validation:** start must be less than or equal to end.
|
|
9
|
+
* **Timezone:** All timestamps should be in UTC for consistency.
|
|
10
|
+
*
|
|
11
|
+
* @example
|
|
12
|
+
* ```typescript
|
|
13
|
+
* import { TimeRange } from '@cygnus-wealth/data-models';
|
|
14
|
+
*
|
|
15
|
+
* // Last 30 days
|
|
16
|
+
* const last30Days: TimeRange = {
|
|
17
|
+
* start: new Date('2025-09-11T00:00:00Z'),
|
|
18
|
+
* end: new Date('2025-10-11T23:59:59Z')
|
|
19
|
+
* };
|
|
20
|
+
*
|
|
21
|
+
* // Specific month
|
|
22
|
+
* const september2025: TimeRange = {
|
|
23
|
+
* start: new Date('2025-09-01T00:00:00Z'),
|
|
24
|
+
* end: new Date('2025-09-30T23:59:59Z')
|
|
25
|
+
* };
|
|
26
|
+
*
|
|
27
|
+
* // Year to date
|
|
28
|
+
* const ytd: TimeRange = {
|
|
29
|
+
* start: new Date('2025-01-01T00:00:00Z'),
|
|
30
|
+
* end: new Date()
|
|
31
|
+
* };
|
|
32
|
+
*
|
|
33
|
+
* // Usage in filtering
|
|
34
|
+
* function filterTransactionsByTime(
|
|
35
|
+
* transactions: Transaction[],
|
|
36
|
+
* range: TimeRange
|
|
37
|
+
* ): Transaction[] {
|
|
38
|
+
* return transactions.filter(tx =>
|
|
39
|
+
* tx.timestamp >= range.start && tx.timestamp <= range.end
|
|
40
|
+
* );
|
|
41
|
+
* }
|
|
42
|
+
* ```
|
|
43
|
+
*
|
|
44
|
+
* @since 0.0.1
|
|
45
|
+
* @stability standard
|
|
46
|
+
*
|
|
47
|
+
* @see {@link FilterOptions} for usage in filtering
|
|
48
|
+
* @see {@link Portfolio} for performance period calculations
|
|
49
|
+
*/
|
|
1
50
|
export type TimeRange = {
|
|
51
|
+
/** Range start time (inclusive, UTC) */
|
|
2
52
|
start: Date;
|
|
53
|
+
/** Range end time (inclusive, UTC) */
|
|
3
54
|
end: Date;
|
|
4
55
|
};
|