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
5 changes: 5 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,11 @@
"import": "./dist/enums/Chain.js",
"require": "./dist/cjs/enums/Chain.js"
},
"./enums/ChainFamily": {
"types": "./dist/enums/ChainFamily.d.ts",
"import": "./dist/enums/ChainFamily.js",
"require": "./dist/cjs/enums/ChainFamily.js"
},
"./enums/IntegrationSource": {
"types": "./dist/enums/IntegrationSource.d.ts",
"import": "./dist/enums/IntegrationSource.js",
Expand Down
55 changes: 55 additions & 0 deletions src/enums/ChainFamily.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
/**
* Classification of blockchain protocol families.
*
* Groups blockchain networks by their underlying protocol family rather than
* individual chain identity. Used for routing (which integration handles which
* addresses), discovery (which standard detects which providers), and display
* (chain family badges in UI).
*
* `ChainFamily` is distinct from `Chain` — a chain family contains multiple
* chains (e.g., EVM family includes Ethereum, Polygon, Arbitrum, etc.).
*
* This is a closed enum. Adding new families requires Enterprise Architecture
* approval, a new integration bounded context, and correlation registry entries.
*
* @example
* ```typescript
* import { ChainFamily } from '@cygnus-wealth/data-models';
*
* // Route address to correct integration
* function getIntegration(family: ChainFamily) {
* switch (family) {
* case ChainFamily.EVM:
* return evmIntegration;
* case ChainFamily.SOLANA:
* return solIntegration;
* default:
* throw new Error(`No integration for ${family}`);
* }
* }
* ```
*
* @since 1.5.0
* @stability extended
*
* @see {@link Chain} for specific chain identification within a family
*/
export enum ChainFamily {
/** EVM-compatible chains (Ethereum, Polygon, Arbitrum, Optimism, Avalanche, BSC, Base) */
EVM = 'evm',

/** Solana mainnet */
SOLANA = 'solana',

/** SUI mainnet (Move-based L1) */
SUI = 'sui',

/** Bitcoin mainnet (UTXO model) */
BITCOIN = 'bitcoin',

/** Cosmos ecosystem chains (Cosmos Hub, Osmosis, etc.) */
COSMOS = 'cosmos',

/** Aptos mainnet (Move-based L1) */
APTOS = 'aptos',
}
12 changes: 12 additions & 0 deletions src/enums/IntegrationSource.ts
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,18 @@ export enum IntegrationSource {
/** Data fetched directly from blockchain via RPC */
BLOCKCHAIN_DIRECT = 'BLOCKCHAIN_DIRECT',

/** SUI blockchain integration */
SUI = 'SUI',

/** Bitcoin blockchain integration */
BITCOIN = 'BITCOIN',

/** Cosmos ecosystem integration */
COSMOS = 'COSMOS',

/** Aptos blockchain integration */
APTOS = 'APTOS',

/** Other or unclassified data source */
OTHER = 'OTHER'
}
2 changes: 2 additions & 0 deletions src/index.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
// Enums
export { AssetType } from './enums/AssetType';
export { Chain } from './enums/Chain';
export { ChainFamily } from './enums/ChainFamily';
export { IntegrationSource } from './enums/IntegrationSource';
export { TransactionType } from './enums/TransactionType';
export { AccountType } from './enums/AccountType';
Expand Down Expand Up @@ -38,6 +39,7 @@ export { PortfolioAsset } from './interfaces/PortfolioAsset';
export type { WalletProviderId } from './types/WalletProviderId';
export type { WalletConnectionId } from './types/WalletConnectionId';
export type { AccountId } from './types/AccountId';
export type { Caip2ChainId } from './types/Caip2ChainId';

// Multi-Wallet Connection Models
export type { WalletConnection } from './interfaces/WalletConnection';
Expand Down
4 changes: 4 additions & 0 deletions src/interfaces/AddressRequest.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { AccountId } from '../types/AccountId';
import { Chain } from '../enums/Chain';
import { ChainFamily } from '../enums/ChainFamily';

/**
* Request to query data for a specific account address.
Expand Down Expand Up @@ -31,6 +32,9 @@ export interface AddressRequest {
/** Checksummed address to query */
address: string;

/** Chain family for routing to the correct integration */
chainFamily: ChainFamily;

/** Chains to query for this address */
chainScope: Chain[];
}
4 changes: 4 additions & 0 deletions src/interfaces/ConnectedAccount.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { AccountId } from '../types/AccountId';
import { Chain } from '../enums/Chain';
import { ChainFamily } from '../enums/ChainFamily';

/**
* A single account within a wallet connection.
Expand Down Expand Up @@ -40,6 +41,9 @@ export interface ConnectedAccount {
/** User-assigned label (default: truncated address) */
accountLabel: string;

/** Chain family this account belongs to */
chainFamily: ChainFamily;

/** Chains to track this account on (default: all supported by the connection) */
chainScope: Chain[];

Expand Down
4 changes: 4 additions & 0 deletions src/interfaces/TrackedAddress.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { AccountId } from '../types/AccountId';
import { WalletConnectionId } from '../types/WalletConnectionId';
import { WalletProviderId } from '../types/WalletProviderId';
import { Chain } from '../enums/Chain';
import { ChainFamily } from '../enums/ChainFamily';

/**
* An address being tracked for portfolio purposes with full account context.
Expand Down Expand Up @@ -49,6 +50,9 @@ export interface TrackedAddress {
/** Label of the parent wallet connection */
connectionLabel: string;

/** Chain family of this tracked address, used for integration routing */
chainFamily: ChainFamily;

/** Chains to query for this address */
chainScope: Chain[];
}
4 changes: 4 additions & 0 deletions src/interfaces/WalletConnection.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { WalletConnectionId } from '../types/WalletConnectionId';
import { WalletProviderId } from '../types/WalletProviderId';
import { Chain } from '../enums/Chain';
import { ChainFamily } from '../enums/ChainFamily';
import { ConnectedAccount } from './ConnectedAccount';

/**
Expand Down Expand Up @@ -64,6 +65,9 @@ export interface WalletConnection {
/** Chains this wallet connection supports */
supportedChains: Chain[];

/** Chain families this wallet connection supports (e.g., EVM, Solana, SUI) */
supportedChainFamilies: ChainFamily[];

/** ISO 8601 timestamp of initial connection */
connectedAt: string;

Expand Down
4 changes: 4 additions & 0 deletions src/interfaces/WatchAddress.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { AccountId } from '../types/AccountId';
import { Chain } from '../enums/Chain';
import { ChainFamily } from '../enums/ChainFamily';

/**
* An address tracked independently of any wallet connection.
Expand Down Expand Up @@ -36,6 +37,9 @@ export interface WatchAddress {
/** User-assigned label */
addressLabel: string;

/** Chain family of this watched address */
chainFamily: ChainFamily;

/** Chains to track this address on */
chainScope: Chain[];

Expand Down
10 changes: 7 additions & 3 deletions src/types/AccountId.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,13 @@
/**
* Unique identifier for a specific account across the system.
*
* Format: `{walletConnectionId}:{checksummedAddress}` for connected accounts
* (e.g., `metamask:a1b2c3d4:0xAbC...123`), or `watch:{checksummedAddress}`
* Format: `{walletConnectionId}:{chainFamily}:{address}` for connected accounts
* (e.g., `metamask:a1b2c3d4:evm:0xAbC...123`), or `watch:{address}`
* for watch addresses.
*
* The `chainFamily` segment (introduced in en-o8w) disambiguates addresses
* from the same wallet connection that span different chain families.
*
* This is the primary key used throughout the system to reference a specific
* account. It disambiguates the same address appearing in different wallet
* connections (e.g., imported into both MetaMask and Rabby).
Expand All @@ -13,7 +16,8 @@
* ```typescript
* import { AccountId } from '@cygnus-wealth/data-models';
*
* const connectedAccountId: AccountId = 'metamask:a1b2c3d4:0xAbCdEf1234567890';
* const evmAccountId: AccountId = 'metamask:a1b2c3d4:evm:0xAbCdEf1234567890';
* const solanaAccountId: AccountId = 'phantom:abc123:solana:7xKXtg2CW87d97TXJSDpbD5jBkheTqA83TZRuJosgAsU';
* const watchAccountId: AccountId = 'watch:0xAbCdEf1234567890';
* ```
*
Expand Down
27 changes: 27 additions & 0 deletions src/types/Caip2ChainId.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
/**
* CAIP-2 chain identifier string type.
*
* Format: `{namespace}:{reference}` as defined by the Chain Agnostic
* Improvement Proposal 2. Used for WalletConnect v2 interoperability.
*
* Common namespace prefixes map to ChainFamily values:
* - `eip155` → ChainFamily.EVM (e.g., `eip155:1` for Ethereum mainnet)
* - `solana` → ChainFamily.SOLANA (e.g., `solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp`)
* - `bip122` → ChainFamily.BITCOIN
* - `cosmos` → ChainFamily.COSMOS
*
* @example
* ```typescript
* import { Caip2ChainId } from '@cygnus-wealth/data-models';
*
* const ethereumMainnet: Caip2ChainId = 'eip155:1';
* const polygon: Caip2ChainId = 'eip155:137';
* const solanaMainnet: Caip2ChainId = 'solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp';
* ```
*
* @since 1.5.0
* @stability extended
*
* @see {@link ChainFamily} for chain family classification
*/
export type Caip2ChainId = string;
Loading
Loading