2023-04-25 12:00:17 +00:00
package wallet
import (
"context"
"database/sql"
"math/big"
"github.com/ethereum/go-ethereum/common"
)
type Persistence struct {
db * sql . DB
}
func NewPersistence ( db * sql . DB ) * Persistence {
return & Persistence { db : db }
}
func ( p * Persistence ) SaveTokens ( tokens map [ common . Address ] [ ] Token ) ( err error ) {
tx , err := p . db . BeginTx ( context . Background ( ) , & sql . TxOptions { } )
if err != nil {
return
}
defer func ( ) {
if err == nil {
err = tx . Commit ( )
return
}
// don't shadow original error
_ = tx . Rollback ( )
} ( )
for address , addressTokens := range tokens {
for _ , t := range addressTokens {
for chainID , b := range t . BalancesPerChain {
if b . HasError || b . Balance . Cmp ( big . NewFloat ( 0 ) ) == 0 {
continue
}
2023-10-17 15:05:05 +00:00
_ , err = tx . Exec ( ` INSERT INTO token_balances(user_address,token_name,token_symbol,token_address,token_decimals,token_description,token_url,balance,raw_balance,chain_id) VALUES (?,?,?,?,?,?,?,?,?,?) ` , address . Hex ( ) , t . Name , t . Symbol , b . Address . Hex ( ) , t . Decimals , t . Description , t . AssetWebsiteURL , b . Balance . String ( ) , b . RawBalance , chainID )
2023-04-25 12:00:17 +00:00
if err != nil {
return err
}
}
}
}
return nil
}
func ( p * Persistence ) GetTokens ( ) ( map [ common . Address ] [ ] Token , error ) {
2023-10-17 15:05:05 +00:00
rows , err := p . db . Query ( ` SELECT user_address, token_name, token_symbol, token_address, token_decimals, token_description, token_url, balance, raw_balance, chain_id FROM token_balances ` )
2023-04-25 12:00:17 +00:00
if err != nil {
return nil , err
}
defer rows . Close ( )
acc := make ( map [ common . Address ] map [ string ] Token )
for rows . Next ( ) {
2023-09-20 10:48:08 +00:00
var addressStr , balance , rawBalance , tokenAddress string
2023-04-25 12:00:17 +00:00
token := Token { }
var chainID uint64
2023-10-17 15:05:05 +00:00
err := rows . Scan ( & addressStr , & token . Name , & token . Symbol , & tokenAddress , & token . Decimals , & token . Description , & token . AssetWebsiteURL , & balance , & rawBalance , & chainID )
2023-04-25 12:00:17 +00:00
if err != nil {
return nil , err
}
address := common . HexToAddress ( addressStr )
if acc [ address ] == nil {
acc [ address ] = make ( map [ string ] Token )
}
if acc [ address ] [ token . Name ] . Name == "" {
token . BalancesPerChain = make ( map [ uint64 ] ChainBalance )
acc [ address ] [ token . Name ] = token
}
tokenAcc := acc [ address ] [ token . Name ]
balanceFloat := new ( big . Float )
_ , _ , err = balanceFloat . Parse ( balance , 10 )
if err != nil {
return nil , err
}
tokenAcc . BalancesPerChain [ chainID ] = ChainBalance {
2023-09-20 10:48:08 +00:00
RawBalance : rawBalance ,
Balance : balanceFloat ,
Address : common . HexToAddress ( tokenAddress ) ,
ChainID : chainID ,
2023-04-25 12:00:17 +00:00
}
}
result := make ( map [ common . Address ] [ ] Token )
for address , tks := range acc {
for _ , t := range tks {
result [ address ] = append ( result [ address ] , t )
}
}
return result , nil
}