banano 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/CHANGELOG.md +2 -0
- data/LICENSE.txt +21 -0
- data/README.md +183 -0
- data/bin/console +14 -0
- data/bin/setup +8 -0
- data/lib/banano.rb +46 -0
- data/lib/banano/account.rb +202 -0
- data/lib/banano/client.rb +33 -0
- data/lib/banano/error.rb +7 -0
- data/lib/banano/key.rb +47 -0
- data/lib/banano/node.rb +115 -0
- data/lib/banano/unit.rb +41 -0
- data/lib/banano/util.rb +25 -0
- data/lib/banano/version.rb +5 -0
- data/lib/banano/wallet.rb +430 -0
- data/lib/banano/wallet_account.rb +227 -0
- metadata +161 -0
@@ -0,0 +1,227 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'forwardable'
|
4
|
+
|
5
|
+
# The <tt>Banano::WalletAccount</tt> class lets you manage
|
6
|
+
# your banano accounts, including making and receiving payments.
|
7
|
+
#
|
8
|
+
module Banano
|
9
|
+
class WalletAccount
|
10
|
+
extend Forwardable
|
11
|
+
# @!method balance(raw: true)
|
12
|
+
# (see Banano::Account#balance)
|
13
|
+
# @!method block_count
|
14
|
+
# (see Banano::Account#block_count)
|
15
|
+
# @!method delegators(raw: true)
|
16
|
+
# (see Banano::Account#delegators)
|
17
|
+
# @!method exists?
|
18
|
+
# (see Banano::Account#exists?)
|
19
|
+
# @!method id
|
20
|
+
# (see Banano::Account#id)
|
21
|
+
# @!method info((detailed: false, raw: true)
|
22
|
+
# (see Banano::Account#info)
|
23
|
+
# @!method last_modified_at
|
24
|
+
# (see Banano::Account#last_modified_at)
|
25
|
+
# @!method pending(limit: 1000, detailed: false, raw: true)
|
26
|
+
# (see Banano::Account#pending)
|
27
|
+
# @!method public_key
|
28
|
+
# (see Banano::Account#public_key)
|
29
|
+
# @!method history(limit: 1000, raw: true)
|
30
|
+
# (see Banano::Account#history)
|
31
|
+
# @!method representative
|
32
|
+
# (see Banano::Account#representative)
|
33
|
+
def_delegators :@banano_account_instance,
|
34
|
+
:balance,
|
35
|
+
:delegators,
|
36
|
+
:exists?,
|
37
|
+
:id,
|
38
|
+
:info,
|
39
|
+
:last_modified_at,
|
40
|
+
:pending,
|
41
|
+
:public_key,
|
42
|
+
:history,
|
43
|
+
:representative
|
44
|
+
alias open? exists?
|
45
|
+
|
46
|
+
def initialize(node:, wallet:, account: nil)
|
47
|
+
@node = node
|
48
|
+
@wallet = wallet
|
49
|
+
@account = account
|
50
|
+
@banano_account_instance = nil
|
51
|
+
|
52
|
+
unless @account.nil?
|
53
|
+
# Wallet must contain the account
|
54
|
+
unless Banano::Wallet.new(node: @node, wallet: @wallet).contains?(@account)
|
55
|
+
raise ArgumentError, "Account does not exist in wallet. Account: #{@account}, wallet: #{@wallet}"
|
56
|
+
end
|
57
|
+
|
58
|
+
# An object to delegate account methods that don't
|
59
|
+
# expect a wallet param in the RPC call, to allow this
|
60
|
+
# class to support all methods that can be called on Banano::Account
|
61
|
+
@banano_account_instance = Banano::Account.new(node: @node, address: @account)
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
# Creates a new account, or multiple new accounts, in this wallet.
|
66
|
+
#
|
67
|
+
# ==== Examples:
|
68
|
+
#
|
69
|
+
# wallet_account.create # => Banano::WalletAccount
|
70
|
+
# wallet_account.create(2) # => [Banano::WalletAccount, Banano::WalletAccount]
|
71
|
+
#
|
72
|
+
# @param count [Integer] number of accounts to create
|
73
|
+
#
|
74
|
+
# @return [Banano::WalletAccount] returns a single {Banano::WalletAccount}
|
75
|
+
# if invoked with no argument
|
76
|
+
# @return [Array<Banano::WalletAccount>] returns an Array of {Banano::WalletAccount}
|
77
|
+
# if method was called with argument +n+ > 1
|
78
|
+
# @raise [ArgumentError] if +n+ is less than 1
|
79
|
+
def create(count = 1)
|
80
|
+
raise ArgumentError, "number of accounts must be greater than 0" if count < 1
|
81
|
+
|
82
|
+
if count == 1
|
83
|
+
Banano::WalletAccount.new(node: @node,
|
84
|
+
wallet: @wallet,
|
85
|
+
account: rpc(action: :account_create)[:account])
|
86
|
+
else
|
87
|
+
Array(rpc(action: :accounts_create, params: {count: count})[:accounts]).map do |account|
|
88
|
+
Banano::WalletAccount.new(node: @node,
|
89
|
+
wallet: @wallet,
|
90
|
+
account: account)
|
91
|
+
end
|
92
|
+
end
|
93
|
+
end
|
94
|
+
|
95
|
+
# Unlinks the account from the wallet.
|
96
|
+
#
|
97
|
+
# ==== Example:
|
98
|
+
#
|
99
|
+
# wallet_account.destroy # => true
|
100
|
+
#
|
101
|
+
# @return [Boolean] +true+ if action was successful, otherwise +false+
|
102
|
+
def destroy
|
103
|
+
rpc(action: :account_remove)[:removed] == '1'
|
104
|
+
end
|
105
|
+
|
106
|
+
# Makes a payment from this account to another account
|
107
|
+
# on the banano network. Returns a <i>send</i> block hash
|
108
|
+
# if successful, or a {Banano::Error} if unsuccessful.
|
109
|
+
#
|
110
|
+
# Note, there may be a delay in receiving a response due to Proof
|
111
|
+
# of Work being done. <i>Proof of Work is precomputed for one transaction
|
112
|
+
# in the background. If it has been a while since your last transaction
|
113
|
+
# it will send instantly, the next one will need to wait for
|
114
|
+
# Proof of Work to be generated.</i>
|
115
|
+
#
|
116
|
+
# @param to [String] account id of the recipient of your payment
|
117
|
+
# @param amount [Integer|Float]
|
118
|
+
# @param raw [Boolean] raw or banano units
|
119
|
+
# @param id [String] must be unique per payment. It serves an important
|
120
|
+
# purpose; it allows you to make the same call multiple times with
|
121
|
+
# the same +id+ and be reassured that you will only ever send this
|
122
|
+
# nano payment once
|
123
|
+
#
|
124
|
+
# @return [String] the send block id for the payment
|
125
|
+
# @raise [Banano::Error] if unsuccessful
|
126
|
+
def pay(to:, amount:, raw: true, id:)
|
127
|
+
# Check that to account is a valid address
|
128
|
+
response = rpc(action: :validate_account_number, params: {account: to})
|
129
|
+
raise ArgumentError, "Account address is invalid: #{to}" unless response[:valid] == '1'
|
130
|
+
|
131
|
+
raw_amount = raw ? amount : Banano::Unit.ban_to_raw(amount)
|
132
|
+
# account is called source, so don't use the normal rpc method
|
133
|
+
p = {
|
134
|
+
wallet: @wallet,
|
135
|
+
source: @account,
|
136
|
+
destination: to,
|
137
|
+
amount: raw_amount,
|
138
|
+
id: id
|
139
|
+
}
|
140
|
+
response = rpc(action: :send, params: p)
|
141
|
+
return Banano::Error.new(response[:error]) if response.key?(:error)
|
142
|
+
|
143
|
+
response[:block]
|
144
|
+
end
|
145
|
+
|
146
|
+
# Receives a pending payment for this account.
|
147
|
+
#
|
148
|
+
# When called with no +block+ argument, the latest pending payment
|
149
|
+
# for the account will be received.
|
150
|
+
#
|
151
|
+
# Returns a <i>receive</i> block id
|
152
|
+
# if a receive was successful, or +false+ if there were no pending
|
153
|
+
# payments to receive.
|
154
|
+
#
|
155
|
+
# You can receive a specific pending block if you know it by
|
156
|
+
# passing the block in as an argument.
|
157
|
+
#
|
158
|
+
# ==== Examples:
|
159
|
+
#
|
160
|
+
# account.receive # => "9AE2311..."
|
161
|
+
# account.receive("718CC21...") # => "9AE2311..."
|
162
|
+
#
|
163
|
+
# @param block [String] optional block id of pending payment. If
|
164
|
+
# not provided, the latest pending payment will be received
|
165
|
+
#
|
166
|
+
# @return [String] the receive block id
|
167
|
+
# @return [false] if there was no block to receive
|
168
|
+
def receive(block = nil)
|
169
|
+
if block.nil?
|
170
|
+
_receive_without_block
|
171
|
+
else
|
172
|
+
_receive_with_block(block)
|
173
|
+
end
|
174
|
+
end
|
175
|
+
|
176
|
+
# Sets the representative for the account.
|
177
|
+
#
|
178
|
+
# A representative is an account that will vote on your account's
|
179
|
+
# behalf on the nano network if your account is offline and there is
|
180
|
+
# a fork of the network that requires voting on.
|
181
|
+
#
|
182
|
+
# Returns the <em>change block</em> that was
|
183
|
+
# broadcast to the nano network. The block contains the information
|
184
|
+
# about the representative change for your account.
|
185
|
+
#
|
186
|
+
# @param [String] representative the id of the representative account
|
187
|
+
# to set as this account's representative
|
188
|
+
# @return [String] id of the <i>change</i> block created
|
189
|
+
# @raise [ArgumentError] if the representative account does not exist
|
190
|
+
def change_representative(representative)
|
191
|
+
unless Banano::Account.new(node: @node, address: representative).exists?
|
192
|
+
raise ArgumentError, "Representative account does not exist: #{representative}"
|
193
|
+
end
|
194
|
+
|
195
|
+
rpc(action: :account_representative_set,
|
196
|
+
params: {representative: representative})[:block]
|
197
|
+
end
|
198
|
+
|
199
|
+
private
|
200
|
+
|
201
|
+
def _receive_without_block
|
202
|
+
# Discover the first pending block
|
203
|
+
pending_blocks = rpc(action: :pending, params: {account: @account, count: 1})
|
204
|
+
|
205
|
+
return false if pending_blocks[:blocks].empty?
|
206
|
+
|
207
|
+
# Then call receive_with_block as normal
|
208
|
+
_receive_with_block(pending_blocks[:blocks][0])
|
209
|
+
end
|
210
|
+
|
211
|
+
# Returns block if successful, otherwise false
|
212
|
+
def _receive_with_block(block)
|
213
|
+
response = rpc(action: :receive, params: {block: block})[:block]
|
214
|
+
response.nil? ? false : response
|
215
|
+
end
|
216
|
+
|
217
|
+
def rpc(action:, params: {})
|
218
|
+
p = {}
|
219
|
+
return p unless @wallet
|
220
|
+
|
221
|
+
p[:wallet] = @wallet
|
222
|
+
p[:account] = @account unless @account.nil?
|
223
|
+
|
224
|
+
@node.rpc(action: action, params: p.merge(params))
|
225
|
+
end
|
226
|
+
end
|
227
|
+
end
|
metadata
ADDED
@@ -0,0 +1,161 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: banano
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Stoyan Zhekov
|
8
|
+
autorequire:
|
9
|
+
bindir: exe
|
10
|
+
cert_chain: []
|
11
|
+
date: 2020-06-21 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: faraday
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '1.0'
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '1.0'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: faraday_middleware
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - "~>"
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '1.0'
|
34
|
+
type: :runtime
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - "~>"
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '1.0'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: pry
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - "~>"
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '0'
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - "~>"
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '0'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: rake
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - "~>"
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '12.3'
|
62
|
+
type: :development
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - "~>"
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '12.3'
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: rspec
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - "~>"
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: '3.9'
|
76
|
+
type: :development
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - "~>"
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: '3.9'
|
83
|
+
- !ruby/object:Gem::Dependency
|
84
|
+
name: rubocop
|
85
|
+
requirement: !ruby/object:Gem::Requirement
|
86
|
+
requirements:
|
87
|
+
- - "~>"
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
version: '0.85'
|
90
|
+
type: :development
|
91
|
+
prerelease: false
|
92
|
+
version_requirements: !ruby/object:Gem::Requirement
|
93
|
+
requirements:
|
94
|
+
- - "~>"
|
95
|
+
- !ruby/object:Gem::Version
|
96
|
+
version: '0.85'
|
97
|
+
- !ruby/object:Gem::Dependency
|
98
|
+
name: webmock
|
99
|
+
requirement: !ruby/object:Gem::Requirement
|
100
|
+
requirements:
|
101
|
+
- - "~>"
|
102
|
+
- !ruby/object:Gem::Version
|
103
|
+
version: '3.8'
|
104
|
+
type: :development
|
105
|
+
prerelease: false
|
106
|
+
version_requirements: !ruby/object:Gem::Requirement
|
107
|
+
requirements:
|
108
|
+
- - "~>"
|
109
|
+
- !ruby/object:Gem::Version
|
110
|
+
version: '3.8'
|
111
|
+
description: Library for working with Banano currency. Implements parts of the RPC
|
112
|
+
protocol for access to Banano node. Convertion between raw and banano units etc.
|
113
|
+
email:
|
114
|
+
- zh@zhware.net
|
115
|
+
executables: []
|
116
|
+
extensions: []
|
117
|
+
extra_rdoc_files: []
|
118
|
+
files:
|
119
|
+
- CHANGELOG.md
|
120
|
+
- LICENSE.txt
|
121
|
+
- README.md
|
122
|
+
- bin/console
|
123
|
+
- bin/setup
|
124
|
+
- lib/banano.rb
|
125
|
+
- lib/banano/account.rb
|
126
|
+
- lib/banano/client.rb
|
127
|
+
- lib/banano/error.rb
|
128
|
+
- lib/banano/key.rb
|
129
|
+
- lib/banano/node.rb
|
130
|
+
- lib/banano/unit.rb
|
131
|
+
- lib/banano/util.rb
|
132
|
+
- lib/banano/version.rb
|
133
|
+
- lib/banano/wallet.rb
|
134
|
+
- lib/banano/wallet_account.rb
|
135
|
+
homepage: http://github.com/zh/rbanano
|
136
|
+
licenses:
|
137
|
+
- MIT
|
138
|
+
metadata:
|
139
|
+
homepage_uri: http://github.com/zh/rbanano
|
140
|
+
source_code_uri: http://github.com/zh/rbanano
|
141
|
+
changelog_uri: http://github.com/zh/rbanano/CHANGELOG.md
|
142
|
+
post_install_message:
|
143
|
+
rdoc_options: []
|
144
|
+
require_paths:
|
145
|
+
- lib
|
146
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
147
|
+
requirements:
|
148
|
+
- - ">="
|
149
|
+
- !ruby/object:Gem::Version
|
150
|
+
version: 2.3.0
|
151
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
152
|
+
requirements:
|
153
|
+
- - ">="
|
154
|
+
- !ruby/object:Gem::Version
|
155
|
+
version: '0'
|
156
|
+
requirements: []
|
157
|
+
rubygems_version: 3.0.3
|
158
|
+
signing_key:
|
159
|
+
specification_version: 4
|
160
|
+
summary: Library for working with Banano currency.
|
161
|
+
test_files: []
|