Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Migrating to nano rpc v23.0+ #14

Open
wants to merge 4 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 10 additions & 10 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ Sends an amount of Nano from one account to another. The source account (supplie

gonano receive -w0

Receives all pending amounts for wallet #0. To receive pending amounts for a single account,
Receives all receivable amounts for wallet #0. To receive receivable amounts for a single account,

gonano receive -a <account>

Expand All @@ -62,7 +62,7 @@ Main entrypoint to the package. The first function creates a wallet using a trad

func (w *Wallet) ScanForAccounts() (err error)

Scans the wallet for non-empty accounts, including not yet opened accounts with pending amounts.
Scans the wallet for non-empty accounts, including not yet opened accounts with receivable amounts.

func (w *Wallet) NewAccount(index *uint32) (a *Account, err error)

Expand All @@ -73,9 +73,9 @@ Creates a new account within the wallet. If `index` is non-`nil`, derives the ac

Gets the account with the given `address`, or all the accounts known to the wallet.

func (w *Wallet) ReceivePendings() (err error)
func (w *Wallet) ReceiveReceivables() (err error)

Receives all pending amounts to the wallet.
Receives all receivable amounts to the wallet.

func (a *Account) Address() string

Expand All @@ -85,17 +85,17 @@ Get the address of the account.

Get the derivation index of the account.

func (a *Account) Balance() (balance, pending *big.Int, err error)
func (a *Account) Balance() (balance, receivable *big.Int, err error)

Get the owned balance and pending balance of the account. Amounts are in raws.
Get the owned balance and receivable balance of the account. Amounts are in raws.

func (a *Account) Send(account string, amount *big.Int) (hash rpc.BlockHash, err error)

Send `amount` Nano from this to another `account`. The block hash is returned.

func (a *Account) ReceivePendings() (err error)
func (a *Account) ReceiveReceivables() (err error)

Receives all pending amounts to the account.
Receives all receivable amounts to the account.

func (a *Account) ChangeRep(representative string) (hash rpc.BlockHash, err error)

Expand All @@ -114,7 +114,7 @@ Create an RPC client with URL.

Not all RPCs are supported. The following methods are available:

func (c *Client) AccountBalance(account string) (balance, pending *RawAmount, err error)
func (c *Client) AccountBalance(account string) (balance, receivable *RawAmount, err error)
func (c *Client) AccountBlockCount(account string) (blockCount uint64, err error)
func (c *Client) AccountHistory(account string, count int64, head BlockHash) (history []AccountHistory, previous BlockHash, err error)
func (c *Client) AccountHistoryRaw(account string, count int64, head BlockHash) (history []AccountHistoryRaw, previous BlockHash, err error)
Expand All @@ -123,7 +123,7 @@ Not all RPCs are supported. The following methods are available:
func (c *Client) AccountWeight(account string) (weight *RawAmount, err error)
func (c *Client) AccountsBalances(accounts []string) (balances map[string]*AccountBalance, err error)
func (c *Client) AccountsFrontiers(accounts []string) (frontiers map[string]BlockHash, err error)
func (c *Client) AccountsPending(accounts []string, count int64) (pending map[string]HashToPendingMap, err error)
func (c *Client) AccountsReceivable(accounts []string, count int64) (receivable map[string]HashToReceivableMap, err error)
func (c *Client) AvailableSupply() (available *RawAmount, err error)
func (c *Client) BlockAccount(hash BlockHash) (account string, err error)
func (c *Client) BlockConfirm(hash BlockHash) (started bool, err error)
Expand Down
22 changes: 11 additions & 11 deletions cmd/list.go
Original file line number Diff line number Diff line change
Expand Up @@ -38,35 +38,35 @@ var listCmd = &cobra.Command{
accounts = append(accounts, address)
}
sort.Strings(accounts)
var balanceSum, pendingSum big.Int
var balanceSum, receivableSum big.Int
for _, address := range accounts {
balance, pending := getBalanceAndPrint(address)
balance, receivable := getBalanceAndPrint(address)
balanceSum.Add(&balanceSum, &balance.Int)
pendingSum.Add(&pendingSum, &pending.Int)
receivableSum.Add(&receivableSum, &receivable.Int)
}
if len(accounts) > 1 {
fmt.Print(strings.Repeat(" ", 61), "Sum:")
printAmounts(&balanceSum, &pendingSum)
printAmounts(&balanceSum, &receivableSum)
}
}
},
}

func getBalanceAndPrint(account string) (balance, pending *rpc.RawAmount) {
func getBalanceAndPrint(account string) (balance, receivable *rpc.RawAmount) {
rpcClient := rpc.Client{URL: rpcURL}
balance, pending, err := rpcClient.AccountBalance(account)
balance, receivable, err := rpcClient.AccountBalance(account)
fatalIf(err)
fmt.Print(account)
printAmounts(&balance.Int, &pending.Int)
return balance, pending
printAmounts(&balance.Int, &receivable.Int)
return balance, receivable
}

func printAmounts(balance, pending *big.Int) {
func printAmounts(balance, receivable *big.Int) {
if balance.Sign() > 0 {
fmt.Printf(" %s", util.NanoAmount{Raw: balance})
}
if pending.Sign() > 0 {
fmt.Printf(" (+ %s pending)", util.NanoAmount{Raw: pending})
if receivable.Sign() > 0 {
fmt.Printf(" (+ %s receivable)", util.NanoAmount{Raw: receivable})
}
fmt.Println()
}
Expand Down
6 changes: 3 additions & 3 deletions cmd/receive.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import (

var receiveCmd = &cobra.Command{
Use: "receive",
Short: "Receive all pending amounts for a wallet or account",
Short: "Receive all receivable amounts for a wallet or account",
Run: func(cmd *cobra.Command, args []string) {
if walletAccount == "" {
checkWalletIndex()
Expand All @@ -16,10 +16,10 @@ var receiveCmd = &cobra.Command{
_, err := wi.w.NewAccount(&index)
fatalIf(err)
}
err := wi.w.ReceivePendings()
err := wi.w.ReceiveReceivables()
fatalIf(err)
} else {
err := getAccount().ReceivePendings()
err := getAccount().ReceiveReceivables()
fatalIf(err)
}
},
Expand Down
4 changes: 2 additions & 2 deletions cmd/root.go
Original file line number Diff line number Diff line change
Expand Up @@ -43,9 +43,9 @@ func init() {
rootCmd.PersistentFlags().StringVar(&cfgFile, "config", "", "config file (default is $HOME/.gonano.yaml)")
rootCmd.PersistentFlags().IntVarP(&walletIndex, "wallet", "w", -1, "Index of the wallet to use")
rootCmd.PersistentFlags().StringVarP(&walletAccount, "account", "a", "", "Account to operate on")
rootCmd.PersistentFlags().StringVarP(&rpcURL, "rpc", "r", "https://mynano.ninja/api/node", "RPC endpoint URL")
rootCmd.PersistentFlags().StringVarP(&rpcURL, "rpc", "r", "https://app.natrium.io/api", "RPC endpoint URL")
rootCmd.PersistentFlags().StringVarP(&rpcWorkURL, "rpc-work", "s", "http://[::1]:7076", "RPC endpoint URL for work generation")
rootCmd.PersistentFlags().IntVarP(&walletAccountIndex, "account-index", "i", -1, "Index of the account within the wallet to use. Not all operations support it yet")
rootCmd.PersistentFlags().IntVarP(&walletAccountIndex, "account-index", "i", -1, "Index of the account within the wallet to use. Not all operations support it yet")
}

// initConfig reads in config file and ENV variables if set.
Expand Down
69 changes: 53 additions & 16 deletions rpc/account.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,14 @@ import (
)

// AccountBalance returns how many RAW is owned and how many have not yet been received by account.
func (c *Client) AccountBalance(account string) (balance, pending *RawAmount, err error) {
func (c *Client) AccountBalance(account string) (balance, receivable *RawAmount, err error) {
resp, err := c.send(map[string]interface{}{"action": "account_balance", "account": account})
if err != nil {
return
}
var v struct{ Balance, Pending *RawAmount }
var v struct{ Balance, Receivable *RawAmount }
err = json.Unmarshal(resp, &v)
return v.Balance, v.Pending, err
return v.Balance, v.Receivable, err
}

// AccountBlockCount gets the number of blocks for a specific account.
Expand Down Expand Up @@ -75,7 +75,7 @@ func (c *Client) AccountInfo(account string) (info AccountInfo, err error) {
"account": account,
"representative": true,
"weight": true,
"pending": true,
"receivable": true,
})
if err != nil {
return
Expand Down Expand Up @@ -108,7 +108,7 @@ func (c *Client) AccountWeight(account string) (weight *RawAmount, err error) {

// AccountBalance returns how many RAW is owned and how many have not yet been received.
type AccountBalance struct {
Balance, Pending *RawAmount
Balance, Receivable *RawAmount
}

// AccountsBalances returns how many RAW is owned and how many have not yet been received by accounts list.
Expand Down Expand Up @@ -137,31 +137,31 @@ func (c *Client) AccountsFrontiers(accounts []string) (frontiers map[string]Bloc
return v.Frontiers, err
}

// AccountPending returns amount and source account.
type AccountPending struct {
// AccountReceivable returns amount and source account.
type AccountReceivable struct {
Amount *RawAmount
Source string
}

// HashToPendingMap maps pending block hashes to amount and source account.
type HashToPendingMap map[string]AccountPending
// HashToReceivableMap maps receivable block hashes to amount and source account.
type HashToReceivableMap map[string]AccountReceivable

// UnmarshalJSON sets *h to a copy of data.
func (h *HashToPendingMap) UnmarshalJSON(data []byte) (err error) {
func (h *HashToReceivableMap) UnmarshalJSON(data []byte) (err error) {
var s string
if err = json.Unmarshal(data, &s); err == nil && s == "" {
return
}
var v map[string]AccountPending
var v map[string]AccountReceivable
err = json.Unmarshal(data, &v)
*h = v
return
}

// AccountsPending returns a list of pending block hashes with amount and source accounts.
func (c *Client) AccountsPending(accounts []string, count int64) (pending map[string]HashToPendingMap, err error) {
// AccountsReceivable returns a list of receivable block hashes with amount and source accounts.
func (c *Client) AccountsReceivable(accounts []string, count int64) (receivable map[string]HashToReceivableMap, err error) {
resp, err := c.send(map[string]interface{}{
"action": "accounts_pending",
"action": "accounts_receivable",
"accounts": accounts,
"count": count,
"include_only_confirmed": true,
Expand All @@ -175,7 +175,7 @@ func (c *Client) AccountsPending(accounts []string, count int64) (pending map[st
return
}
var v struct {
Blocks map[string]HashToPendingMap
Blocks map[string]HashToReceivableMap
}
err = json.Unmarshal(resp, &v)
return v.Blocks, err
Expand Down Expand Up @@ -243,7 +243,7 @@ func (c *Client) Ledger(account string, count int64, modifiedSince time.Time) (a
"modified_since": modifiedSince.Unix(),
"representative": true,
"weight": true,
"pending": true,
"receivable": true,
})
if err != nil {
return
Expand Down Expand Up @@ -281,3 +281,40 @@ func (c *Client) RepresentativesOnline() (representatives map[string]Representat
err = json.Unmarshal(resp, &v)
return v.Representatives, err
}

// V23.0+ methods

// Receivable returns a list of block hashes which have not yet been received by this account.
func (c *Client) Receivable(
account string, count int64, includeActive bool, threshold string,
) (receivable HashToReceivableMap, err error) {
body := map[string]interface{}{
"action": "receivable",
"account": account,
"include_only_confirmed": true, // it defaults to false for v22.0 and below
"source": true,
}
if count != 0 {
body["count"] = count
}
// include_active defaults to false
if includeActive != false {
body["include_active"] = true
}
if threshold != "" {
body["threshold"] = threshold
}
resp, err := c.send(body)
if err != nil {
return
}
var u struct{ Blocks string }
if err = json.Unmarshal(resp, &u); err == nil && u.Blocks == "" {
return
}
var v struct {
Blocks HashToReceivableMap
}
err = json.Unmarshal(resp, &v)
return v.Blocks, err
}
22 changes: 11 additions & 11 deletions rpc/account_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ import (
const testAccount = "nano_1zcffp784drsmz4oksufxfjut1nb5yh6pg43a6h6bkos39zz19ed6a4r36ny"

func getClient() *rpc.Client {
return &rpc.Client{URL: "https://mynano.ninja/api/node"}
return &rpc.Client{URL: "https://app.natrium.io/api"}
}

func assertEqualBig(t *testing.T, s string, z *big.Int) {
Expand All @@ -28,10 +28,10 @@ func assertEqualBytes(t *testing.T, s string, b []byte) {
}

func TestAccountBalance(t *testing.T) {
balance, pending, err := getClient().AccountBalance(testAccount)
balance, receivable, err := getClient().AccountBalance(testAccount)
require.Nil(t, err)
assertEqualBig(t, "134000000000000000000000000", &balance.Int)
assertEqualBig(t, "0", &pending.Int)
assertEqualBig(t, "0", &receivable.Int)
}

func TestAccountHistory(t *testing.T) {
Expand Down Expand Up @@ -100,7 +100,7 @@ func TestAccountsBalances(t *testing.T) {
require.Nil(t, err)
require.Len(t, balances, 1)
assertEqualBig(t, "134000000000000000000000000", &balances[testAccount].Balance.Int)
assertEqualBig(t, "0", &balances[testAccount].Pending.Int)
assertEqualBig(t, "0", &balances[testAccount].Receivable.Int)
}

func TestAccountsFrontiers(t *testing.T) {
Expand All @@ -110,16 +110,16 @@ func TestAccountsFrontiers(t *testing.T) {
assertEqualBytes(t, "8C1B5D4BBE27F05C7A888D1E691A07C550A81AFEE16D913EE21E1093888B82FD", frontiers[testAccount])
}

func TestAccountsPending(t *testing.T) {
pendings, err := getClient().AccountsPending([]string{
func TestAccountsReceivable(t *testing.T) {
receivables, err := getClient().AccountsReceivable([]string{
testAccount, "nano_159m8t4iedstzcaacikb9hdkhbcxcqzfbw56dutay8ceqagq9wxpsk9ftfq9"}, 1)
require.Nil(t, err)
require.Len(t, pendings, 1)
blocks := pendings["nano_159m8t4iedstzcaacikb9hdkhbcxcqzfbw56dutay8ceqagq9wxpsk9ftfq9"]
require.Len(t, receivables, 1)
blocks := receivables["nano_159m8t4iedstzcaacikb9hdkhbcxcqzfbw56dutay8ceqagq9wxpsk9ftfq9"]
require.Len(t, blocks, 1)
pending := blocks["96D8422D1CB676EF1B62A313865626A7725C3B9BB5B875601A1460ACF30B5322"]
assertEqualBig(t, "123000000000000000000000000", &pending.Amount.Int)
assert.Equal(t, "nano_3kwppxjcggzs65fjh771ch6dbuic3xthsn5wsg6i5537jacw7m493ra8574x", pending.Source)
receivable := blocks["96D8422D1CB676EF1B62A313865626A7725C3B9BB5B875601A1460ACF30B5322"]
assertEqualBig(t, "123000000000000000000000000", &receivable.Amount.Int)
assert.Equal(t, "nano_3kwppxjcggzs65fjh771ch6dbuic3xthsn5wsg6i5537jacw7m493ra8574x", receivable.Source)
}

func TestFrontierCount(t *testing.T) {
Expand Down
2 changes: 1 addition & 1 deletion rpc/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ type AccountInfo struct {
AccountVersion uint64 `json:"account_version,string"`
Representative string `json:"representative"`
Weight *RawAmount `json:"weight"`
Pending *RawAmount `json:"pending"`
Receivable *RawAmount `json:"receivable"`
}

// Block corresponds to the JSON representation of a block.
Expand Down
Loading