This commit is contained in:
Luxferre
2026-09-19 18:26:07 +03:00
parent 8ae332e74d
commit e9826b1ae2
28 changed files with 3417 additions and 1 deletions
+151
View File
@@ -0,0 +1,151 @@
package tron
import (
"strings"
"time"
)
// Client is the subset of tronpy's Tron client used by kisstron.
type Client struct {
provider *HTTPProvider
network string
feeLimit int64
}
// NewClient builds a client for the given network and node endpoint. A zero or
// empty endpoint selects the network default.
func NewClient(network, endpoint string, feeLimit int64, apiKey string) *Client {
return &Client{
provider: NewHTTPProvider(endpoint, 20*time.Second, apiKey),
network: network,
feeLimit: feeLimit,
}
}
// Provider exposes the underlying HTTP provider (used for diagnostics).
func (c *Client) Provider() *HTTPProvider { return c.provider }
func (c *Client) GetAccount(addr string) (map[string]any, error) {
b58, err := ToBase58CheckAddress(addr)
if err != nil {
return nil, err
}
ret, err := c.provider.makeRequest("wallet/getaccount", map[string]any{"address": b58, "visible": true})
if err != nil {
return nil, err
}
if len(ret) == 0 {
return nil, ErrAddressNotFound
}
return ret, nil
}
func (c *Client) GetAccountResource(addr string) (map[string]any, error) {
b58, err := ToBase58CheckAddress(addr)
if err != nil {
return nil, err
}
ret, err := c.provider.makeRequest("wallet/getaccountresource", map[string]any{"address": b58, "visible": true})
if err != nil {
return nil, err
}
if len(ret) == 0 {
return nil, ErrAddressNotFound
}
return ret, nil
}
func (c *Client) getLatestSolidBlockID() (string, error) {
info, err := c.provider.makeRequest("wallet/getnodeinfo", nil)
if err != nil {
return "", err
}
block, _ := info["solidityBlock"].(string)
if block == "" {
return "", ErrAPI
}
return block[strings.LastIndex(block, ",ID:")+4:], nil
}
func (c *Client) broadcast(tx *Transaction) (map[string]any, error) {
payload, err := c.provider.makeRequest("wallet/broadcasttransaction", tx)
if err != nil {
return nil, err
}
if err := handleAPIError(payload); err != nil {
return nil, err
}
if _, ok := payload["txid"]; !ok {
payload["txid"] = tx.TxID
}
return payload, nil
}
func (c *Client) getTransactionInfo(txid string) (map[string]any, error) {
if len(txid) != 64 {
return nil, ErrBadHash
}
ret, err := c.provider.makeRequest("wallet/gettransactioninfobyid", map[string]any{"value": txid, "visible": true})
if err != nil {
return nil, err
}
if err := handleAPIError(ret); err != nil {
return nil, err
}
if len(ret) == 0 {
return nil, ErrTransactionNotFound
}
return ret, nil
}
func (c *Client) GetContract(addr string) (*Contract, error) {
b58, err := ToBase58CheckAddress(addr)
if err != nil {
return nil, err
}
info, err := c.provider.makeRequest("wallet/getcontract", map[string]any{"value": b58, "visible": true})
if err != nil {
return nil, err
}
if err := handleAPIError(info); err != nil {
return nil, wrapErr(ErrContractNotFound, err.Error())
}
return &Contract{Address: b58, client: c}, nil
}
// triggerConstantContract performs a read-only contract call and returns the
// first constant result (hex, without 0x).
func (c *Client) triggerConstantContract(owner, contractAddr, functionSelector, parameter string) (string, error) {
ownerB58, err := ToBase58CheckAddress(owner)
if err != nil {
return "", err
}
contractB58, err := ToBase58CheckAddress(contractAddr)
if err != nil {
return "", err
}
ret, err := c.provider.makeRequest("wallet/triggerconstantcontract", map[string]any{
"owner_address": ownerB58,
"contract_address": contractB58,
"function_selector": functionSelector,
"parameter": parameter,
"visible": true,
})
if err != nil {
return "", err
}
if err := handleAPIError(ret); err != nil {
return "", err
}
if res, ok := ret["result"].(map[string]any); ok {
if _, bad := res["message"]; bad {
return "", ErrTvm
}
}
results, ok := ret["constant_result"].([]any)
if !ok || len(results) == 0 {
return "", ErrTvm
}
first, _ := results[0].(string)
return first, nil
}