Skip to content

Commit a70ee12

Browse files
authored
Merge pull request #84 from initia-labs/update-asset-denom-unit-display
feat: update asset denom unit display method
2 parents 2adc0b1 + 85e58e1 commit a70ee12

File tree

1 file changed

+153
-1
lines changed

1 file changed

+153
-1
lines changed

cmd/gas_station.go

+153-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,12 @@
11
package cmd
22

33
import (
4+
"context"
5+
"encoding/json"
46
"fmt"
7+
"net/http"
8+
"strings"
9+
"time"
510

611
tea "github.com/charmbracelet/bubbletea"
712
"github.com/spf13/cobra"
@@ -15,6 +20,140 @@ import (
1520
"github.com/initia-labs/weave/registry"
1621
)
1722

23+
// Constants for denomination handling
24+
const (
25+
utiaDenom = "utia"
26+
tiaDenom = "TIA"
27+
tiaExponent = 6
28+
uinitDenom = "uinit"
29+
initDenom = "INIT"
30+
initExponent = 6
31+
32+
testnetRegistryURL = "https://registry.testnet.initia.xyz/initia/assetlist.json"
33+
mainnetRegistryURL = "https://registry.initia.xyz/initia/assetlist.json"
34+
)
35+
36+
type DenomUnit struct {
37+
Denom string `json:"denom"`
38+
Exponent int `json:"exponent"`
39+
}
40+
41+
const (
42+
DefaultTimeout = 3 * time.Second
43+
)
44+
45+
type Asset struct {
46+
DenomUnits []DenomUnit `json:"denom_units"`
47+
Base string `json:"base"`
48+
Display string `json:"display"`
49+
}
50+
51+
type AssetList struct {
52+
Assets []Asset `json:"assets"`
53+
}
54+
55+
// formatAmount formats an amount string with the given exponent
56+
func formatAmount(amount string, exponent int) string {
57+
if len(amount) > exponent {
58+
decimalPos := len(amount) - exponent
59+
amount = amount[:decimalPos] + "." + amount[decimalPos:]
60+
} else {
61+
zeros := strings.Repeat("0", exponent-len(amount))
62+
amount = "0." + zeros + amount
63+
}
64+
65+
// Trim trailing zeros and decimal point if necessary
66+
amount = strings.TrimRight(strings.TrimRight(amount, "0"), ".")
67+
if amount == "" {
68+
amount = "0"
69+
}
70+
return amount
71+
}
72+
73+
func fetchInitiaRegistryAssetList(chainType registry.ChainType) (*AssetList, error) {
74+
ctx, cancel := context.WithTimeout(context.Background(), DefaultTimeout)
75+
defer cancel()
76+
77+
registryURL := testnetRegistryURL
78+
if chainType == registry.InitiaL1Mainnet {
79+
registryURL = mainnetRegistryURL
80+
}
81+
82+
req, err := http.NewRequestWithContext(ctx, "GET", registryURL, nil)
83+
if err != nil {
84+
return nil, fmt.Errorf("failed to create request: %w", err)
85+
}
86+
87+
resp, err := http.DefaultClient.Do(req)
88+
if err != nil {
89+
return nil, fmt.Errorf("failed to fetch asset list: %w", err)
90+
}
91+
defer resp.Body.Close()
92+
93+
if resp.StatusCode != http.StatusOK {
94+
return nil, fmt.Errorf("unexpected status code: %d", resp.StatusCode)
95+
}
96+
97+
var assetList AssetList
98+
if err := json.NewDecoder(resp.Body).Decode(&assetList); err != nil {
99+
return nil, fmt.Errorf("failed to decode asset list: %w", err)
100+
}
101+
return &assetList, nil
102+
}
103+
104+
func convertToDisplayDenom(coins *cosmosutils.Coins, assetList *AssetList) *cosmosutils.Coins {
105+
if coins == nil {
106+
return nil
107+
}
108+
109+
result := make(cosmosutils.Coins, 0, len(*coins))
110+
for _, coin := range *coins {
111+
displayCoin := coin
112+
113+
// Handle special cases first
114+
switch coin.Denom {
115+
case utiaDenom:
116+
displayCoin.Amount = formatAmount(coin.Amount, tiaExponent)
117+
displayCoin.Denom = tiaDenom
118+
result = append(result, displayCoin)
119+
continue
120+
case uinitDenom:
121+
displayCoin.Amount = formatAmount(coin.Amount, initExponent)
122+
displayCoin.Denom = initDenom
123+
result = append(result, displayCoin)
124+
continue
125+
}
126+
127+
// Handle other denoms via asset list
128+
if assetList != nil {
129+
if displayDenom, exponent := findHighestExponentDenom(assetList, coin.Denom); exponent > 0 {
130+
displayCoin.Amount = formatAmount(coin.Amount, exponent)
131+
displayCoin.Denom = displayDenom
132+
}
133+
}
134+
result = append(result, displayCoin)
135+
}
136+
return &result
137+
}
138+
139+
// findHighestExponentDenom finds the denomination with the highest exponent for a given base denom
140+
func findHighestExponentDenom(assetList *AssetList, baseDenom string) (string, int) {
141+
for _, asset := range assetList.Assets {
142+
if asset.Base == baseDenom {
143+
maxExponent := 0
144+
displayDenom := baseDenom
145+
for _, unit := range asset.DenomUnits {
146+
if unit.Exponent > maxExponent {
147+
maxExponent = unit.Exponent
148+
displayDenom = unit.Denom
149+
}
150+
}
151+
return displayDenom, maxExponent
152+
}
153+
}
154+
return baseDenom, 0
155+
}
156+
18157
func GasStationCommand() *cobra.Command {
19158
cmd := &cobra.Command{
20159
Use: "gas-station",
@@ -115,6 +254,19 @@ func showGasStationBalance() error {
115254
return err
116255
}
117256

257+
// Fetch asset list and convert denoms before printing
258+
testnetAssetList, err := fetchInitiaRegistryAssetList(registry.InitiaL1Testnet)
259+
if err != nil {
260+
// Log the error but continue with nil assetList
261+
fmt.Printf("Warning: Failed to fetch asset list: %v. Displaying original denominations.\n", err)
262+
testnetAssetList = nil
263+
}
264+
265+
// Convert balances to display denoms
266+
initiaL1TestnetBalances = convertToDisplayDenom(initiaL1TestnetBalances, testnetAssetList)
267+
celestiaTestnetBalance = convertToDisplayDenom(celestiaTestnetBalance, nil) // nil assetList for Celestia
268+
celestiaMainnetBalance = convertToDisplayDenom(celestiaMainnetBalance, nil) // nil assetList for Celestia
269+
118270
maxWidth := getMaxWidth(initiaL1TestnetBalances, celestiaTestnetBalance, celestiaMainnetBalance)
119271
if maxWidth < len(cosmosutils.NoBalancesText) {
120272
maxWidth = len(cosmosutils.NoBalancesText)
@@ -132,7 +284,7 @@ func gasStationShowCommand() *cobra.Command {
132284
Short: "Show Initia and Celestia Gas Station addresses and balances",
133285
RunE: func(cmd *cobra.Command, args []string) error {
134286
if config.IsFirstTimeSetup() {
135-
fmt.Println("Please setup Gas Station first, by running `gas-station setup`")
287+
fmt.Println("Please setup Gas Station first, by running `weave gas-station setup`")
136288
return nil
137289
}
138290

0 commit comments

Comments
 (0)