centrifuge / go-substrate-rpc-client

Substrate RPC client for go aka GSRPC
Apache License 2.0
202 stars 179 forks source link

Retrieving staking balance of nominator #384

Closed Pat-rice closed 5 months ago

Pat-rice commented 5 months ago

I'm trying to retrieve the staking balance of a nominator such as shown in subscan It works fine when using polkadotjs withapi.query.system.accountor api.query.staking.ledger I need to do the same in go, however I do not get the same value at all.

package main

import (
    "encoding/hex"
    "fmt"
    "log"

    gsrpc "github.com/centrifuge/go-substrate-rpc-client/v4"
    "github.com/centrifuge/go-substrate-rpc-client/v4/types"
    "github.com/itering/substrate-api-rpc/util/ss58"
)

type StakingLedger struct {
    Stash     types.AccountID
    Total     types.U128
    Active    types.U128
    Unlocking []any
}

type SystemAccount struct {
    Nonce     types.U32
    Consumers types.U32
    Providers types.U32
    Data      AccountData
}

type AccountData struct {
    Free     types.U128
    Reserved types.U128
    Frozen   types.U128
}

func main() {
    api, err := gsrpc.NewSubstrateAPI("wss://rpc.polkadot.io")
    if err != nil {
        panic(err)
    }

    meta, err := api.RPC.State.GetMetadataLatest()
    if err != nil {
        log.Fatalf("Failed to get latest metadata: %v", err)
    }

    account := "16VPLf7MuJ2anrr6sYAhZyVAoE9TQnixsy4K9zRNtReKv9Po"
    decodedAccount := ss58.Decode(account, 0)
    decodedAccountBytes, err := hex.DecodeString(decodedAccount)
    if err != nil {
        log.Fatalf("Failed to convert decoded address to bytes: %v", err)
    }

    systemAccountKey, err := types.CreateStorageKey(meta, "System", "Account", decodedAccountBytes)
    if err != nil {
        log.Fatalf("Failed to create storage key: %v", err)
    }

    // get storage ?
    var sa SystemAccount
    _, err = api.RPC.State.GetStorageLatest(systemAccountKey, &sa)
    if err != nil {
        log.Fatalf("Failed to get account info: %v", err)
    }
    fmt.Printf("frozen int64: %v\n", sa.Data.Frozen.Int64())
    fmt.Printf("frozen uint64: %v\n", sa.Data.Frozen.Uint64())
    fmt.Printf("free int64: %v\n", sa.Data.Free.Int64())           //
    fmt.Printf("free uint64: %v\n", sa.Data.Free.Uint64())         //
    fmt.Printf("reserved int64: %v\n", sa.Data.Reserved.Int64())   //
    fmt.Printf("reserved uint64: %v\n", sa.Data.Reserved.Uint64()) //

    stakingLedgerKey, err := types.CreateStorageKey(meta, "Staking", "Ledger", decodedAccountBytes)
    if err != nil {
        log.Fatalf("Failed to create storage key: %v", err)
    }

    var sl StakingLedger
    _, err = api.RPC.State.GetStorageLatest(stakingLedgerKey, &sl)
    if err != nil {
        log.Fatalf("Failed to get account info: %v", err)
    }
    fmt.Printf("stash: %v\n", sl.Stash.ToHexString())
    fmt.Printf("total int64: %v\n", sl.Total.Int64())
    fmt.Printf("total uint64: %v\n", sl.Total.Uint64())
    fmt.Printf("active int64: %v\n", sl.Active.Int64())
    fmt.Printf("active uint64: %v\n", sl.Active.Uint64())

}

What am I doing wrong ?

Pat-rice commented 5 months ago

ok just after I posted this, I found the ready to use type AccountInfo and it works 😅

var sa types.AccountInfo
_, err = api.RPC.State.GetStorageLatest(systemAccountKey, &sa)
if err != nil {
log.Fatalf("Failed to get account info: %v", err)
}
fmt.Printf("frozen uint64: %v\n", sa.Data.MiscFrozen.Uint64())