wallet/pkg/eth/eth_balance.go
Anton Nesterov b19bf34e5f
[init]
2024-08-31 16:54:43 +02:00

108 lines
2.7 KiB
Go

package eth
import (
"context"
"math"
"math/big"
"github.com/ethereum/go-ethereum"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/crypto"
"github.com/ethereum/go-ethereum/ethclient"
"github.com/ethereum/go-ethereum/rpc"
)
type EthAccountBalance struct {
Address string `json:"address"`
USDT string `json:"usdt"`
ETH string `json:"eth"`
USDTRaw int64 `json:"usdtRaw"`
ETHRaw int64 `json:"ethRaw"`
TxFee string `json:"txFee"`
}
type request struct {
To string `json:"to"`
Data string `json:"data"`
}
func EthBalance(address string) (*EthAccountBalance, error) {
client, err := ethclient.Dial(ethNode.rpcNode)
if err != nil {
return nil, err
}
account := common.HexToAddress(address)
balance, err := client.BalanceAt(context.Background(), account, nil)
if err != nil {
return nil, err
}
fbalance := new(big.Float)
fbalance.SetString(balance.String())
ethValue := new(big.Float).Quo(fbalance, big.NewFloat(math.Pow10(18)))
rpcClient, err := rpc.DialHTTP(ethNode.rpcNode)
if err != nil {
return nil, err
}
data := crypto.Keccak256Hash([]byte("balanceOf(address)")).String()[0:10] + "000000000000000000000000" + address[2:]
msg := request{ethNode.usdtContractAddress, data}
var res string
err = rpcClient.Call(&res, "eth_call", msg, "latest")
if err != nil {
return nil, err
}
addr := common.HexToAddress(ethNode.usdtContractAddress)
estimation, _ := client.EstimateGas(context.Background(), ethereum.CallMsg{
To: &addr,
Data: []byte(data + address[2:]),
})
txFeeValue := new(big.Float).Quo(big.NewFloat(float64(estimation)*1.5), big.NewFloat(math.Pow10(8)))
usdtRaw := new(big.Int)
if len(res) > 2 {
usdtRaw.SetString(string(res[2:]), 16)
}
usdtValue := new(big.Float).Quo(big.NewFloat(float64(usdtRaw.Int64())), big.NewFloat(math.Pow10(ethNode.usdtContractDecimals)))
var accountBalance EthAccountBalance = EthAccountBalance{
Address: address,
USDT: usdtValue.String(),
ETH: ethValue.String(),
USDTRaw: usdtRaw.Int64(),
ETHRaw: balance.Int64(),
TxFee: txFeeValue.String(),
}
return &accountBalance, nil
}
func EthAllowance(address string, spender string) (int64, error) {
rpcClient, err := rpc.DialHTTP(ethNode.rpcNode)
if err != nil {
return 0, err
}
data := crypto.Keccak256Hash([]byte("allowance(address,address)")).String()[0:10] + "000000000000000000000000" + address[2:] + "000000000000000000000000" + spender[2:]
msg := request{ethNode.usdtContractAddress, data}
var res string
err = rpcClient.Call(&res, "eth_call", msg, "latest")
if err != nil {
return 0, err
}
usdtRaw := new(big.Int)
if len(res) > 2 {
usdtRaw.SetString(string(res[2:]), 16)
}
return usdtRaw.Int64(), nil
}