@@ -7,7 +7,7 @@ import type {
77 StakingPosition ,
88 TokenAmount ,
99} from "./positions.js" ;
10- import type { PortfolioCoverage } from "./portfolio.js" ;
10+ import type { PortfolioCoverage , SolanaPortfolioSlice } from "./portfolio.js" ;
1111
1212export * from "./chains.js" ;
1313
@@ -37,139 +37,6 @@ export interface TronBalance {
3737 priceMissing ?: boolean ;
3838}
3939
40- /**
41- * Solana balance shape — a parallel to TronBalance for SOL + SPL tokens.
42- * `token` is a base58 SPL mint address (~32-44 chars), or "native" for SOL.
43- * SPL balances come from Associated Token Accounts but we surface them by
44- * mint; the ATA is an implementation detail the caller shouldn't care about.
45- */
46- export interface SolanaBalance {
47- chain : "solana" ;
48- /** Base58 SPL mint address, or "native" for SOL. */
49- token : string ;
50- symbol : string ;
51- decimals : number ;
52- amount : string ;
53- formatted : string ;
54- valueUsd ?: number ;
55- priceUsd ?: number ;
56- priceMissing ?: boolean ;
57- }
58-
59- /**
60- * Solana slice of a portfolio summary. Parallel to TronPortfolioSlice.
61- * Phase 1 did not enumerate native validator staking; Phase 3 adds
62- * MarginFi lending.
63- */
64- export interface SolanaPortfolioSlice {
65- /** Base58 Solana address the balances were resolved for. */
66- address : string ;
67- native : SolanaBalance [ ] ;
68- spl : SolanaBalance [ ] ;
69- walletBalancesUsd : number ;
70- /**
71- * MarginFi lending positions (Phase 3). Present only when the wallet has
72- * at least one MarginfiAccount with non-zero balances — probed via the
73- * deterministic PDA at accountIndex 0..3. An empty/missing field means
74- * no MarginFi position, not "reader errored" (errored case is surfaced
75- * through PortfolioCoverage.marginfi).
76- */
77- marginfi ?: SolanaMarginfiPositionSlice [ ] ;
78- /** MarginFi aggregate net USD (sum of netValueUsd across positions). */
79- marginfiNetUsd ?: number ;
80- /**
81- * Kamino lending positions on the main market. Present when the wallet
82- * has Kamino userMetadata + obligation with non-zero deposits or borrows.
83- * Empty/missing means no position; errored case surfaces through
84- * PortfolioCoverage.kamino.
85- */
86- kamino ?: SolanaKaminoPositionSlice [ ] ;
87- /** Kamino aggregate net USD (sum of netValueUsd across positions). */
88- kaminoNetUsd ?: number ;
89- /**
90- * Solana staking positions — Marinade mSOL, Jito jitoSOL, native stake
91- * accounts. Present when any of the three sections is non-empty for
92- * this wallet. Missing means nothing found (errored case surfaces
93- * through PortfolioCoverage.solanaStaking).
94- */
95- staking ?: SolanaStakingPositionSlice ;
96- /** Solana staking aggregate net USD (SOL-equivalent × SOL price). */
97- stakingNetUsd ?: number ;
98- }
99-
100- /**
101- * Thin projection of the three staking readers' output
102- * (`src/modules/positions/solana-staking.ts`). Kept in sync with
103- * `SolanaStakingPositions` but stripped down — the portfolio JSON doesn't
104- * need the per-reader wrapper metadata (wallet duplication, protocol
105- * tags on subtotals).
106- */
107- export interface SolanaStakingPositionSlice {
108- chain : "solana" ;
109- /** mSOL balance + SOL-equivalent via Marinade's on-chain mSolPrice. */
110- marinade : {
111- mSolBalance : number ;
112- solEquivalent : number ;
113- exchangeRate : number ;
114- } ;
115- /** jitoSOL balance + SOL-equivalent via stake-pool's totalLamports/supply. */
116- jito : {
117- jitoSolBalance : number ;
118- solEquivalent : number ;
119- exchangeRate : number ;
120- } ;
121- /** One entry per native stake account (SPL stake-program) with activation status. */
122- nativeStakes : Array < {
123- stakePubkey : string ;
124- validator ?: string ;
125- stakeSol : number ;
126- status : "activating" | "active" | "deactivating" | "inactive" ;
127- activationEpoch ?: number ;
128- deactivationEpoch ?: number ;
129- } > ;
130- /** Sum of SOL-equivalents across Marinade + Jito + native stakes. */
131- totalSolEquivalent : number ;
132- }
133-
134- /**
135- * Thin projection of the full `MarginfiPosition` type exposed by
136- * `src/modules/positions/marginfi.ts`. Kept here so the portfolio types
137- * module doesn't pull in the reader module's internals, matching how
138- * CompoundLendingPosition / MorphoLendingPosition are projections of their
139- * reader modules.
140- */
141- export interface SolanaMarginfiPositionSlice {
142- protocol : "marginfi" ;
143- chain : "solana" ;
144- marginfiAccount : string ;
145- supplied : Array < { symbol : string ; amount : string ; valueUsd : number } > ;
146- borrowed : Array < { symbol : string ; amount : string ; valueUsd : number } > ;
147- totalSuppliedUsd : number ;
148- totalBorrowedUsd : number ;
149- netValueUsd : number ;
150- healthFactor : number ;
151- warnings : string [ ] ;
152- }
153-
154- /**
155- * Thin projection of the full `KaminoPosition` type exposed by
156- * `src/modules/positions/kamino.ts`. Same shape as MarginFi's slice; the
157- * `obligation` field is Kamino's per-(wallet, market, kind) state account
158- * (analogous to `marginfiAccount`).
159- */
160- export interface SolanaKaminoPositionSlice {
161- protocol : "kamino" ;
162- chain : "solana" ;
163- obligation : string ;
164- supplied : Array < { symbol : string ; amount : string ; valueUsd : number } > ;
165- borrowed : Array < { symbol : string ; amount : string ; valueUsd : number } > ;
166- totalSuppliedUsd : number ;
167- totalBorrowedUsd : number ;
168- netValueUsd : number ;
169- healthFactor : number ;
170- warnings : string [ ] ;
171- }
172-
17340/**
17441 * TRON slice of a portfolio summary. Contains the TRON-specific address the
17542 * balances were fetched for (base58, which can't fit into the `wallet:
0 commit comments