Skip to content

Commit 272151c

Browse files
authored
Adopt defi-positions sim command for a new payload (#44)
* Adopt defi-positions sim command for a new payload * rename fields too
1 parent acea182 commit 272151c

2 files changed

Lines changed: 235 additions & 87 deletions

File tree

cmd/sim/evm/defi_positions.go

Lines changed: 68 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -46,64 +46,67 @@ type defiPositionsResponse struct {
4646
}
4747

4848
type defiAggregations struct {
49-
TotalUSDValue float64 `json:"total_usd_value"`
49+
TotalValueUSD float64 `json:"total_value_usd"`
5050
TotalByChain map[string]float64 `json:"total_by_chain,omitempty"`
5151
}
5252

53-
// defiPosition is a flat struct matching the polymorphic DefiPosition schema.
53+
// defiTokenInfo represents a token object returned by the API with address,
54+
// name, symbol, and optional numeric fields depending on position type.
55+
type defiTokenInfo struct {
56+
Address string `json:"address,omitempty"`
57+
Name string `json:"name,omitempty"`
58+
Symbol string `json:"symbol,omitempty"`
59+
Decimals int `json:"decimals,omitempty"`
60+
Holdings float64 `json:"holdings,omitempty"`
61+
PriceUSD float64 `json:"price_usd,omitempty"`
62+
}
63+
64+
// nftTokenDetails holds per-token data inside an NFT concentrated-liquidity position.
65+
type nftTokenDetails struct {
66+
PriceUSD float64 `json:"price_usd"`
67+
Holdings float64 `json:"holdings,omitempty"`
68+
Rewards float64 `json:"rewards,omitempty"`
69+
}
70+
71+
// defiPosition matches the polymorphic DefiPosition schema returned by the API.
5472
// Fields are optional depending on the `type` discriminator.
5573
type defiPosition struct {
56-
Type string `json:"type"`
57-
ChainID int64 `json:"chain_id"`
58-
USDVal float64 `json:"usd_value"`
59-
Logo *string `json:"logo,omitempty"`
74+
Type string `json:"type"`
75+
Chain string `json:"chain,omitempty"`
76+
ChainID int64 `json:"chain_id"`
77+
ValueUSD float64 `json:"value_usd"`
78+
Logo *string `json:"logo,omitempty"`
6079

6180
// Erc4626 / Tokenized fields
62-
TokenType string `json:"token_type,omitempty"`
63-
Token string `json:"token,omitempty"`
64-
TokenName string `json:"token_name,omitempty"`
65-
TokenSymbol string `json:"token_symbol,omitempty"`
66-
UnderlyingToken string `json:"underlying_token,omitempty"`
67-
UnderlyingTokenName string `json:"underlying_token_name,omitempty"`
68-
UnderlyingTokenSymbol string `json:"underlying_token_symbol,omitempty"`
69-
UnderlyingTokenDecimals int `json:"underlying_token_decimals,omitempty"`
81+
TokenType string `json:"token_type,omitempty"`
82+
Token *defiTokenInfo `json:"token,omitempty"`
83+
UnderlyingToken *defiTokenInfo `json:"underlying_token,omitempty"`
84+
LendingPool string `json:"lending_pool,omitempty"`
7085

7186
// Erc4626 / Tokenized / UniswapV2 fields
72-
CalculatedBalance float64 `json:"calculated_balance,omitempty"`
73-
PriceInUSD float64 `json:"price_in_usd,omitempty"`
87+
Balance float64 `json:"balance,omitempty"`
88+
PriceUSD float64 `json:"price_usd,omitempty"`
7489

7590
// UniswapV2 / Nft / NftV4 fields
76-
Protocol string `json:"protocol,omitempty"`
77-
Pool string `json:"pool,omitempty"`
78-
PoolID []int `json:"pool_id,omitempty"`
79-
PoolManager string `json:"pool_manager,omitempty"`
80-
Salt []int `json:"salt,omitempty"`
81-
Token0 string `json:"token0,omitempty"`
82-
Token0Name string `json:"token0_name,omitempty"`
83-
Token0Symbol string `json:"token0_symbol,omitempty"`
84-
Token0Decimals int `json:"token0_decimals,omitempty"`
85-
Token1 string `json:"token1,omitempty"`
86-
Token1Name string `json:"token1_name,omitempty"`
87-
Token1Symbol string `json:"token1_symbol,omitempty"`
88-
Token1Decimals int `json:"token1_decimals,omitempty"`
89-
LPBalance string `json:"lp_balance,omitempty"`
90-
Token0Price float64 `json:"token0_price,omitempty"`
91-
Token1Price float64 `json:"token1_price,omitempty"`
91+
Protocol string `json:"protocol,omitempty"`
92+
Pool string `json:"pool,omitempty"`
93+
PoolID string `json:"pool_id,omitempty"`
94+
PoolManager string `json:"pool_manager,omitempty"`
95+
Salt string `json:"salt,omitempty"`
96+
Token0 *defiTokenInfo `json:"token0,omitempty"`
97+
Token1 *defiTokenInfo `json:"token1,omitempty"`
98+
LPBalance string `json:"lp_balance,omitempty"`
9299

93100
// Nft / NftV4 concentrated liquidity positions
94101
Positions []nftPositionDetails `json:"positions,omitempty"`
95102
}
96103

97104
type nftPositionDetails struct {
98-
TickLower int `json:"tick_lower"`
99-
TickUpper int `json:"tick_upper"`
100-
TokenID string `json:"token_id"`
101-
Token0Price float64 `json:"token0_price"`
102-
Token0Holdings float64 `json:"token0_holdings,omitempty"`
103-
Token0Rewards float64 `json:"token0_rewards,omitempty"`
104-
Token1Price float64 `json:"token1_price"`
105-
Token1Holdings float64 `json:"token1_holdings,omitempty"`
106-
Token1Rewards float64 `json:"token1_rewards,omitempty"`
105+
TickLower int `json:"tick_lower"`
106+
TickUpper int `json:"tick_upper"`
107+
TokenID string `json:"token_id"`
108+
Token0 *nftTokenDetails `json:"token0,omitempty"`
109+
Token1 *nftTokenDetails `json:"token1,omitempty"`
107110
}
108111

109112
func runDefiPositions(cmd *cobra.Command, args []string) error {
@@ -150,7 +153,7 @@ func runDefiPositions(cmd *cobra.Command, args []string) error {
150153
p.Type,
151154
fmt.Sprintf("%d", p.ChainID),
152155
p.Protocol,
153-
output.FormatUSD(p.USDVal),
156+
output.FormatUSD(p.ValueUSD),
154157
positionDetails(p),
155158
}
156159
}
@@ -165,18 +168,26 @@ func runDefiPositions(cmd *cobra.Command, args []string) error {
165168

166169
// positionDetails returns a human-readable summary for a DeFi position,
167170
// varying by position type.
171+
// tokenSymbol safely extracts the symbol from a token info pointer.
172+
func tokenSymbol(t *defiTokenInfo) string {
173+
if t == nil {
174+
return ""
175+
}
176+
return t.Symbol
177+
}
178+
168179
func positionDetails(p defiPosition) string {
169180
switch p.Type {
170181
case "Erc4626":
171182
parts := []string{}
172-
if p.TokenSymbol != "" {
173-
parts = append(parts, p.TokenSymbol)
183+
if sym := tokenSymbol(p.Token); sym != "" {
184+
parts = append(parts, sym)
174185
}
175-
if p.UnderlyingTokenSymbol != "" {
176-
parts = append(parts, fmt.Sprintf("-> %s", p.UnderlyingTokenSymbol))
186+
if sym := tokenSymbol(p.UnderlyingToken); sym != "" {
187+
parts = append(parts, fmt.Sprintf("-> %s", sym))
177188
}
178-
if p.CalculatedBalance != 0 {
179-
parts = append(parts, fmt.Sprintf("bal=%.6g", p.CalculatedBalance))
189+
if p.Balance != 0 {
190+
parts = append(parts, fmt.Sprintf("bal=%.6g", p.Balance))
180191
}
181192
return strings.Join(parts, " ")
182193

@@ -185,23 +196,23 @@ func positionDetails(p defiPosition) string {
185196
if p.TokenType != "" {
186197
parts = append(parts, p.TokenType)
187198
}
188-
if p.TokenSymbol != "" {
189-
parts = append(parts, p.TokenSymbol)
199+
if sym := tokenSymbol(p.Token); sym != "" {
200+
parts = append(parts, sym)
190201
}
191-
if p.CalculatedBalance != 0 {
192-
parts = append(parts, fmt.Sprintf("bal=%.6g", p.CalculatedBalance))
202+
if p.Balance != 0 {
203+
parts = append(parts, fmt.Sprintf("bal=%.6g", p.Balance))
193204
}
194205
return strings.Join(parts, " ")
195206

196207
case "UniswapV2":
197-
pair := formatPair(p.Token0Symbol, p.Token1Symbol)
198-
if p.CalculatedBalance != 0 {
199-
return fmt.Sprintf("%s bal=%.6g", pair, p.CalculatedBalance)
208+
pair := formatPair(tokenSymbol(p.Token0), tokenSymbol(p.Token1))
209+
if p.Balance != 0 {
210+
return fmt.Sprintf("%s bal=%.6g", pair, p.Balance)
200211
}
201212
return pair
202213

203214
case "Nft", "NftV4":
204-
pair := formatPair(p.Token0Symbol, p.Token1Symbol)
215+
pair := formatPair(tokenSymbol(p.Token0), tokenSymbol(p.Token1))
205216
nPos := len(p.Positions)
206217
if nPos == 1 {
207218
return fmt.Sprintf("%s (1 position)", pair)
@@ -233,7 +244,7 @@ func printAggregations(w io.Writer, agg *defiAggregations) {
233244
return
234245
}
235246

236-
fmt.Fprintf(w, "\nTotal USD Value: %s\n", output.FormatUSD(agg.TotalUSDValue))
247+
fmt.Fprintf(w, "\nTotal USD Value: %s\n", output.FormatUSD(agg.TotalValueUSD))
237248

238249
if len(agg.TotalByChain) > 0 {
239250
fmt.Fprintln(w, "Breakdown by chain:")

0 commit comments

Comments
 (0)