nano_rpc 0.2.0 → 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 5505de736e20d672bed90df3856fef48148882a3726f27bb10fa03eb2db5e4b0
4
- data.tar.gz: 20a28a63f524ecc1af9a2a94f91b724b5996b767ba35202a7416841ffd98aac8
3
+ metadata.gz: 0d161d743c5ec1f860437f0c90189ed939280bc090f135cbacd7f9c442404000
4
+ data.tar.gz: ff48c6fdd7cbf214ff0d967e5fdf924ad6c51aa5a803dfbe3f92c343d453a19e
5
5
  SHA512:
6
- metadata.gz: 61056e815bf6a31ccb9dbacc4581b4fd99ee9769fba6251c5f84da884f1bb9d430604a09fb053b4a21613e9b318b81f40c9950f1fc718d5bd4ff2656cf60f703
7
- data.tar.gz: 03e4d60c84c306ebe878c527d00a3084b083de0e788795995dc0f0d2459f6a48b6e6c49f7a0e4474baaa2f81f9d727bbf9cad9ac0c170b3a03ef004e933d1cf8
6
+ metadata.gz: a71a9d9558fb9abdca9484158761567edb522cf29322e36a764811c5b669e3eeb086f3d3125ca94d3de862e45b8cf071a1bd3fb48f1534c6251ccd0f0f4f32b4
7
+ data.tar.gz: c928cd95666dd0e84e67f71275e6d475947c90da9c89a82cfb1ae6f4193c87a9686c1dec3ba004c722373f20f3dca857c4c285c7fc652c64d61792d8552a4e41
data/README.md CHANGED
@@ -1,6 +1,8 @@
1
1
  # Nano RPC
2
2
 
3
- An RPC wrapper for Nano digitial currency nodes. Arbitrary RPC access is provided along with proxy objects that expose helper methods ([Wiki](https://github.com/jcraigk/ruby_nano_rpc/wiki/Proxy-Object-Reference)).
3
+ ![Ruby Logo](https://i.imgur.com/pTKxwQq.png)
4
+
5
+ An RPC wrapper for Nano digitial currency nodes written in Ruby. Arbitrary RPC access is provided along with proxy objects that expose helper methods ([Wiki](https://github.com/jcraigk/ruby_nano_rpc/wiki/Proxy-Object-Reference)).
4
6
 
5
7
  To run a Nano node locally, see [Nano Docker Docs](https://github.com/clemahieu/raiblocks/wiki/Docker-node).
6
8
 
@@ -33,10 +35,10 @@ Every method requires an `action`, which is passed as the first argument to `cal
33
35
  First setup the client:
34
36
 
35
37
  ```ruby
36
- # Connect to localhost:7076
38
+ # Connect to the default node (localhost:7076)
37
39
  client = Nano.client
38
40
 
39
- # Connect to custom host
41
+ # or connect to a custom node
40
42
  client = Nano::Client.new(host: 'mynanonode', port: 1234)
41
43
  ```
42
44
 
@@ -60,72 +62,43 @@ Response data are provided as [Hashie](https://github.com/intridea/hashie) objec
60
62
  # => 100
61
63
  ````
62
64
 
63
- ### Proxy Objects
65
+ ### Proxy Objects / Helper Methods
64
66
 
65
67
  Proxy objects are provided to ease interaction with the API by providing logically grouped helper methods. Here we do not strictly follow the grouping as expressed in the [Nano RPC Docs](https://github.com/clemahieu/raiblocks/wiki/RPC-protocol). Instead, the following objects are provided:
66
68
 
67
- ```ruby
68
- Nano::Account
69
- Nano::Accounts
70
- Nano::Node
71
- Nano::Wallet
72
- ```
69
+ * [Nano::Account](https://github.com/jcraigk/ruby_nano_rpc/wiki/Nano::Account)
70
+ * [Nano::Accounts](https://github.com/jcraigk/ruby_nano_rpc/wiki/Nano::Accounts)
71
+ * [Nano::Node](https://github.com/jcraigk/ruby_nano_rpc/wiki/Nano::Node)
72
+ * [Nano::Wallet](https://github.com/jcraigk/ruby_nano_rpc/wiki/Nano::Wallet)
73
73
 
74
- `Account`, `Accounts`, and `Wallet` each require a single parameter to be passed during initialization. This parameter is persisted for subsequent calls. All RPC methods are provided directly as methods.
74
+ `Account`, `Accounts`, and `Wallet` each require a single parameter to be passed during initialization (`address`, `addresses`, and `seed`, respectively). This parameter is persisted for subsequent calls. All RPC methods are provided directly as methods.
75
75
 
76
76
  ```ruby
77
77
  account = Nano::Account.new('xrb_someaddress1234')
78
78
 
79
79
  account.account_balance
80
- # => {"balance"=>100, "pending"=>0}
80
+ # => {"balance"=>100, "pending"=>5}
81
81
  account.account_balance.balance
82
- # 100
83
- ```
84
-
85
- You can ask an object what raw RPC methods it provides using `proxy_methods`:
86
-
87
- ```ruby
88
- account.proxy_methods
89
- # => [:account_balance, :account_block_count, :account_create, ...]
82
+ # => 100
90
83
  ```
91
84
 
92
- There are also helper methods for terser code:
85
+ There are also helper methods to bypass repetitive nested calls:
93
86
 
94
87
  ```ruby
95
- account = Nano::Account.new('xrb_someaddress1234')
96
88
  account.balance
97
- # 100
89
+ # => 100
98
90
  account.pending_balance
99
- # 0
100
- ```
101
-
102
- `Node` methods are provided at both the instance and class levels:
103
-
104
- ```ruby
105
- Nano::Node.version
106
- # => {"rpc_version"=>1, "store_version"=>10, "node_vendor"=>"RaiBlocks 9.0"}
107
-
108
- node = Nano::Node.new
109
- node.version.rpc_version
110
- # => 1
111
- node.peers
112
- # => {"[::ffff:2.80.5.202]:64317"=>"5", "[::ffff:2.249.74.58]:7075"=>"5", "[::ffff:5.9.31.82]:7077"=>"4", ... }
113
- node.available_supply
114
- # => {"available"=>132596127030666124778600855847014518457}
115
- node.available
116
- # => 132596127030666124778600855847014518457
117
- node.block_count.unchecked
118
- # => 4868605
91
+ # => 5
119
92
  ```
120
93
 
121
- You can point each proxy object at its own node by passing a custom client in:
94
+ You can point each proxy object at its own node by passing in a client instance:
122
95
 
123
96
  ```ruby
124
97
  client = Nano::Client.new(host: 'mynanonode', port: 1234)
125
98
  account = Nano::Account.new('xrb_someaddress1234', client: client)
126
99
  ```
127
100
 
128
- For a more comprehensive guide, see the [Wiki](https://github.com/jcraigk/ruby_nano_rpc/wiki/Proxy-Object-Reference).
101
+ For a comprehensive guide, see the [Wiki](https://github.com/jcraigk/ruby_nano_rpc/wiki).
129
102
 
130
103
  ## License
131
104
 
File without changes
@@ -5,7 +5,6 @@ module Nano
5
5
  class NodeConnectionFailure < Error; end
6
6
  class BadRequest < Error; end
7
7
  class InvalidRequest < Error; end
8
- class InvalidParameterType < Error; end
9
8
  class ForbiddenParameter < Error; end
10
9
  class MissingParameters < Error; end
11
10
  end
@@ -26,15 +26,15 @@ module Nano::AccountProxyHelper
26
26
 
27
27
  def move(from:, to:)
28
28
  account_move(
29
- wallet: to,
30
- source: from,
29
+ wallet: wallet_seed(to),
30
+ source: wallet_seed(from),
31
31
  accounts: [address]
32
32
  ).moved == 1
33
33
  end
34
34
 
35
35
  def wallet_work_set(wallet:, work:)
36
36
  work_set(
37
- wallet: wallet,
37
+ wallet: wallet_seed(wallet),
38
38
  work: work
39
39
  ).success == ''
40
40
  end
@@ -55,7 +55,7 @@ module Nano::AccountProxyHelper
55
55
 
56
56
  def remove(opts)
57
57
  account_remove(
58
- wallet: opts_pluck(opts, :wallet)
58
+ wallet: wallet_seed(opts_pluck(opts, :wallet))
59
59
  ).removed == 1
60
60
  end
61
61
 
@@ -65,7 +65,7 @@ module Nano::AccountProxyHelper
65
65
 
66
66
  def representative_set(wallet:, representative:)
67
67
  account_representative_set(
68
- wallet: wallet,
68
+ wallet: wallet_seed(wallet),
69
69
  representative: representative
70
70
  ).set == 1
71
71
  end
@@ -1,5 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
  module Nano::AccountsProxyHelper
3
+ include Nano::ApplicationHelper
4
+
3
5
  def balances
4
6
  accounts_balances
5
7
  .balances
@@ -22,7 +24,10 @@ module Nano::AccountsProxyHelper
22
24
  end
23
25
 
24
26
  def move(from:, to:)
25
- account_move(wallet: to, source: from).moved == 1
27
+ account_move(
28
+ source: wallet_seed(from),
29
+ wallet: wallet_seed(to)
30
+ ).moved == 1
26
31
  end
27
32
 
28
33
  def pending(count:, threshold: nil, source: nil)
@@ -60,4 +65,12 @@ module Nano::AccountsProxyHelper
60
65
  def third
61
66
  self[2]
62
67
  end
68
+
69
+ def last
70
+ self[-1]
71
+ end
72
+
73
+ def size
74
+ addresses.size
75
+ end
63
76
  end
@@ -0,0 +1,20 @@
1
+ # frozen_string_literal: true
2
+ module Nano::ApplicationHelper
3
+ private
4
+
5
+ def opts_pluck(opts, key)
6
+ opts.is_a?(Hash) ? opts[key] : opts
7
+ end
8
+
9
+ def wallet_seed(wallet)
10
+ wallet.is_a?(Nano::Wallet) ? wallet.seed : wallet
11
+ end
12
+
13
+ def account_address(account)
14
+ account.is_a?(Nano::Account) ? account.address : account
15
+ end
16
+
17
+ def accounts_addresses(accounts)
18
+ accounts.is_a?(Nano::Accounts) ? accounts.addresses : accounts
19
+ end
20
+ end
@@ -6,7 +6,7 @@ module Nano::NodeProxyHelper
6
6
  block_account(opts_hash(opts)).account
7
7
  end
8
8
 
9
- def available
9
+ def available_nano
10
10
  available_supply.available
11
11
  end
12
12
 
@@ -14,44 +14,16 @@ module Nano::NodeProxyHelper
14
14
  Nano::Wallet.new(wallet_create.wallet)
15
15
  end
16
16
 
17
- def krai_from(opts)
18
- krai_from_raw(opts_amount(opts)).amount
19
- end
20
-
21
- def krai_to(opts)
22
- krai_to_raw(opts_amount(opts)).amount
23
- end
24
-
25
- def mrai_from(opts)
26
- mrai_from_raw(opts_amount(opts)).amount
27
- end
28
-
29
- def mrai_to(opts)
30
- mrai_to_raw(opts_amount(opts)).amount
31
- end
32
-
33
17
  def pending_exists?(opts)
34
18
  pending_exists(opts_hash(opts)).exists == 1
35
19
  end
36
20
 
37
- def rai_from(opts)
38
- rai_from_raw(opts_amount(opts)).amount
39
- end
40
-
41
- def rai_to(opts)
42
- rai_to_raw(opts_amount(opts)).amount
43
- end
44
-
45
21
  def work_valid?(work:, hash:)
46
22
  work_validate(work: work, hash: hash).valid == 1
47
23
  end
48
24
 
49
25
  private
50
26
 
51
- def opts_amount(opts)
52
- { amount: opts_pluck(opts, :amount) }
53
- end
54
-
55
27
  def opts_hash(opts)
56
28
  { hash: opts_pluck(opts, :hash) }
57
29
  end
@@ -3,7 +3,13 @@ module Nano::WalletProxyHelper
3
3
  include Nano::ApplicationHelper
4
4
 
5
5
  def account_work(opts)
6
- work_get(opts_account(opts)).work
6
+ work_get(
7
+ account: account_address(opts_pluck(opts, :account))
8
+ ).work
9
+ end
10
+
11
+ def accounts
12
+ Nano::Accounts.new(account_list.accounts)
7
13
  end
8
14
 
9
15
  def add_key(key:, work: true)
@@ -39,15 +45,17 @@ module Nano::WalletProxyHelper
39
45
  end
40
46
 
41
47
  def contains?(opts)
42
- wallet_contains(opts_account(opts)).exists == 1
48
+ wallet_contains(
49
+ account: account_address(opts_pluck(opts, :account))
50
+ ).exists == 1
43
51
  end
44
52
 
45
53
  def create_account(work: true)
46
- account_create(work: work).account
54
+ Nano::Account.new(account_create(work: work).account)
47
55
  end
48
56
 
49
57
  def create_accounts(count:, work: true)
50
- accounts_create(count: count, work: work).accounts
58
+ Nano::Accounts.new(accounts_create(count: count, work: work).accounts)
51
59
  end
52
60
 
53
61
  def destroy
@@ -78,9 +86,9 @@ module Nano::WalletProxyHelper
78
86
 
79
87
  def move_accounts(to:, accounts:)
80
88
  account_move(
81
- wallet: to,
89
+ wallet: wallet_seed(to),
82
90
  source: seed,
83
- accounts: accounts
91
+ accounts: accounts_addresses(accounts)
84
92
  ).moved == 1
85
93
  end
86
94
 
@@ -114,11 +122,16 @@ module Nano::WalletProxyHelper
114
122
  alias blocks_pending pending_blocks
115
123
 
116
124
  def receive_block(account:, block:)
117
- receive(account: account, block: block).block
125
+ receive(
126
+ account: account_address(account),
127
+ block: block
128
+ ).block
118
129
  end
119
130
 
120
131
  def remove_account(opts)
121
- account_remove(opts_account(opts)).removed == 1
132
+ account_remove(
133
+ account: account_address(opts_pluck(opts, :account))
134
+ ).removed == 1
122
135
  end
123
136
 
124
137
  def representative
@@ -130,7 +143,10 @@ module Nano::WalletProxyHelper
130
143
  end
131
144
 
132
145
  def account_work_set(account:, work:)
133
- work_set(account: account, work: work).success == ''
146
+ work_set(
147
+ account: account_address(account),
148
+ work: work
149
+ ).success == ''
134
150
  end
135
151
  alias set_account_work account_work_set
136
152
 
@@ -143,8 +159,8 @@ module Nano::WalletProxyHelper
143
159
 
144
160
  def send_nano(from:, to:, amount:, work: nil)
145
161
  send_currency(
146
- source: from,
147
- destination: to,
162
+ source: wallet_seed(from),
163
+ destination: wallet_seed(to),
148
164
  amount: amount,
149
165
  work: work
150
166
  ).block
@@ -154,10 +170,4 @@ module Nano::WalletProxyHelper
154
170
  def work
155
171
  wallet_work_get.works
156
172
  end
157
-
158
- private
159
-
160
- def opts_account(opts)
161
- { account: opts_pluck(opts, :account) }
162
- end
163
173
  end
File without changes
File without changes
File without changes
File without changes
@@ -0,0 +1,153 @@
1
+ # frozen_string_literal: true
2
+ module Nano::Proxy
3
+ attr_accessor :client
4
+
5
+ def initialize(opts = {})
6
+ @client = opts[:client] || Nano.client
7
+ end
8
+
9
+ def self.included(base)
10
+ base.extend(ClassMethods)
11
+ end
12
+ module ClassMethods
13
+ attr_reader :proxy_method_def, :proxy_param_def
14
+
15
+ def proxy_params(param_def = nil)
16
+ @proxy_param_def = param_def
17
+ end
18
+
19
+ def proxy_method(name, signature = nil)
20
+ @proxy_method_def ||= {}
21
+ @proxy_method_def[name] = signature
22
+ end
23
+
24
+ def proxy_methods
25
+ proxy_method_def.keys.sort
26
+ end
27
+
28
+ def methods
29
+ (super + proxy_methods).sort
30
+ end
31
+ end
32
+
33
+ def proxy_methods
34
+ self.class.proxy_methods
35
+ end
36
+
37
+ def methods
38
+ (super + proxy_methods).sort
39
+ end
40
+
41
+ private
42
+
43
+ def method_missing(m, *args, &_block)
44
+ return super unless methods.include?(m)
45
+ define_proxy_method(m)
46
+ send(m, args.first)
47
+ end
48
+
49
+ def respond_to_missing?(m, include_private = false)
50
+ methods.include?(m) || super
51
+ end
52
+
53
+ def define_proxy_method(m)
54
+ self.class.send(:define_method, method_alias(m)) do |call_args = {}|
55
+ @m = m
56
+ @call_args = call_args
57
+
58
+ validate_params!
59
+ execute_call
60
+ end
61
+ end
62
+
63
+ def execute_call
64
+ expose_nested_data(@client.call(@m, @call_args))
65
+ end
66
+
67
+ def base_params
68
+ @base_params ||= begin
69
+ return if self.class.proxy_param_def.nil?
70
+ self.class
71
+ .proxy_param_def
72
+ .each_with_object({}) do |(k, v), params|
73
+ params[k] ||= send(v)
74
+ end
75
+ end
76
+ end
77
+
78
+ # Nano `send` action is also the method caller in Ruby ;)
79
+ def method_alias(m)
80
+ m == :send ? :send_currency : m
81
+ end
82
+
83
+ # If single-key response matches method name, expose nested data
84
+ def expose_nested_data(data)
85
+ data.is_a?(Hash) && data.keys.map(&:to_s) == [@m.to_s] ? data[@m] : data
86
+ end
87
+
88
+ def validate_params!
89
+ prepare_params
90
+ ensure_required_params!
91
+ prevent_forbidden_params!
92
+ drop_nil_params
93
+ end
94
+
95
+ def prepare_params
96
+ # Allow non-Hash literal argument if this method requires single param
97
+ # Ex `create('new')` vs `create(name: 'new')`
98
+ @call_args = if required_params.size == 1 && !@call_args.is_a?(Hash)
99
+ { required_params.first => @call_args }
100
+ else
101
+ @call_args.is_a?(Hash) ? @call_args : {}
102
+ end
103
+ @call_args.merge!(base_params) if base_params
104
+ end
105
+
106
+ def ensure_required_params!
107
+ missing_params = required_params - opts_keys
108
+ return unless missing_params.any?
109
+ raise Nano::MissingParameters,
110
+ "Missing required parameter(s): #{missing_params.join(', ')}"
111
+ end
112
+
113
+ def prevent_forbidden_params!
114
+ forbidden_params = base_param_keys + opts_keys - allowed_params
115
+ return unless forbidden_params.any?
116
+ raise Nano::ForbiddenParameter,
117
+ "Forbidden parameter(s) passed: #{forbidden_params.join(', ')}"
118
+ end
119
+
120
+ def drop_nil_params
121
+ @call_args.delete_if { |_k, v| v.nil? }
122
+ end
123
+
124
+ def opts_keys
125
+ @call_args.is_a?(Hash) ? @call_args.keys : []
126
+ end
127
+
128
+ def allowed_params
129
+ base_param_keys + required_params + optional_params
130
+ end
131
+
132
+ def required_params
133
+ return [] unless method_def && method_def[@m]
134
+ method_def[@m][:required] || []
135
+ end
136
+
137
+ def optional_params
138
+ return [] unless method_def && method_def[@m]
139
+ method_def[@m][:optional] || []
140
+ end
141
+
142
+ def base_param_keys
143
+ param_def.is_a?(Hash) ? param_def.keys : []
144
+ end
145
+
146
+ def method_def
147
+ self.class.proxy_method_def
148
+ end
149
+
150
+ def param_def
151
+ self.class.proxy_param_def
152
+ end
153
+ end
File without changes
@@ -1,4 +1,4 @@
1
1
  # frozen_string_literal: true
2
2
  module Nano
3
- VERSION = '0.2.0'
3
+ VERSION = '0.3.0'
4
4
  end
data/lib/nano_rpc.rb CHANGED
@@ -1,16 +1,15 @@
1
1
  # frozen_string_literal: true
2
- require 'nano/version'
3
- require 'nano/client'
4
- require 'nano/errors'
5
- require 'nano/proxy'
6
- require 'nano/proxy_context'
7
- require 'nano/response'
8
- require 'nano/helpers/application_helper'
9
- require 'nano/helpers/account_proxy_helper'
10
- require 'nano/helpers/accounts_proxy_helper'
11
- require 'nano/helpers/node_proxy_helper'
12
- require 'nano/helpers/wallet_proxy_helper'
13
- require 'nano/proxies/account'
14
- require 'nano/proxies/accounts'
15
- require 'nano/proxies/node'
16
- require 'nano/proxies/wallet'
2
+ require 'nano_rpc/version'
3
+ require 'nano_rpc/client'
4
+ require 'nano_rpc/errors'
5
+ require 'nano_rpc/proxy'
6
+ require 'nano_rpc/response'
7
+ require 'nano_rpc/helpers/application_helper'
8
+ require 'nano_rpc/helpers/account_proxy_helper'
9
+ require 'nano_rpc/helpers/accounts_proxy_helper'
10
+ require 'nano_rpc/helpers/node_proxy_helper'
11
+ require 'nano_rpc/helpers/wallet_proxy_helper'
12
+ require 'nano_rpc/proxies/account'
13
+ require 'nano_rpc/proxies/accounts'
14
+ require 'nano_rpc/proxies/node'
15
+ require 'nano_rpc/proxies/wallet'
data/nano_rpc.gemspec CHANGED
@@ -1,7 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
  lib = File.expand_path('../lib', __FILE__)
3
3
  $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
- require 'nano/version'
4
+ require 'nano_rpc/version'
5
5
 
6
6
  Gem::Specification.new do |spec|
7
7
  spec.name = 'nano_rpc'
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: nano_rpc
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.0
4
+ version: 0.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Justin Craig-Kuhn (JCK)
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2018-02-04 00:00:00.000000000 Z
11
+ date: 2018-02-05 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -151,22 +151,21 @@ files:
151
151
  - Rakefile
152
152
  - bin/console
153
153
  - bin/setup
154
- - lib/nano/client.rb
155
- - lib/nano/errors.rb
156
- - lib/nano/helpers/account_proxy_helper.rb
157
- - lib/nano/helpers/accounts_proxy_helper.rb
158
- - lib/nano/helpers/application_helper.rb
159
- - lib/nano/helpers/node_proxy_helper.rb
160
- - lib/nano/helpers/wallet_proxy_helper.rb
161
- - lib/nano/proxies/account.rb
162
- - lib/nano/proxies/accounts.rb
163
- - lib/nano/proxies/node.rb
164
- - lib/nano/proxies/wallet.rb
165
- - lib/nano/proxy.rb
166
- - lib/nano/proxy_context.rb
167
- - lib/nano/response.rb
168
- - lib/nano/version.rb
169
154
  - lib/nano_rpc.rb
155
+ - lib/nano_rpc/client.rb
156
+ - lib/nano_rpc/errors.rb
157
+ - lib/nano_rpc/helpers/account_proxy_helper.rb
158
+ - lib/nano_rpc/helpers/accounts_proxy_helper.rb
159
+ - lib/nano_rpc/helpers/application_helper.rb
160
+ - lib/nano_rpc/helpers/node_proxy_helper.rb
161
+ - lib/nano_rpc/helpers/wallet_proxy_helper.rb
162
+ - lib/nano_rpc/proxies/account.rb
163
+ - lib/nano_rpc/proxies/accounts.rb
164
+ - lib/nano_rpc/proxies/node.rb
165
+ - lib/nano_rpc/proxies/wallet.rb
166
+ - lib/nano_rpc/proxy.rb
167
+ - lib/nano_rpc/response.rb
168
+ - lib/nano_rpc/version.rb
170
169
  - nano_rpc.gemspec
171
170
  homepage: https://github.com/jcraigk/ruby_nano_rpc
172
171
  licenses:
@@ -1,8 +0,0 @@
1
- # frozen_string_literal: true
2
- module Nano::ApplicationHelper
3
- private
4
-
5
- def opts_pluck(opts, key)
6
- opts.is_a?(Hash) ? opts[key] : opts
7
- end
8
- end
data/lib/nano/proxy.rb DELETED
@@ -1,97 +0,0 @@
1
- # frozen_string_literal: true
2
- module Nano::Proxy
3
- attr_accessor :client
4
-
5
- def initialize(opts = {})
6
- @client = opts[:client] || Nano.client
7
- end
8
-
9
- def self.included(base)
10
- base.extend(ClassMethods)
11
- end
12
- module ClassMethods
13
- attr_reader :proxy_method_def, :proxy_param_def
14
-
15
- def proxy_params(param_def = nil)
16
- @proxy_param_def = param_def
17
- end
18
-
19
- def proxy_method(name, signature = nil)
20
- @proxy_method_def ||= {}
21
- @proxy_method_def[name] = signature
22
- end
23
-
24
- def proxy_methods
25
- proxy_method_def.keys.sort
26
- end
27
-
28
- def methods
29
- (super + proxy_methods).sort
30
- end
31
-
32
- def define_proxy_method(m, singleton = false)
33
- send(method_style(singleton), method_alias(m)) do |opts = {}|
34
- params = Nano::ProxyContext.new(
35
- singleton ? self : self.class, m, opts
36
- ).populate_params(singleton ? nil : base_params)
37
- data = (singleton ? Nano.client : @client).call(m, params)
38
- # If single-key response matches method name, expose nested data
39
- data.is_a?(Hash) && data.keys.map(&:to_s) == [m.to_s] ? data[m] : data
40
- end
41
- end
42
-
43
- private
44
-
45
- def method_style(singleton)
46
- singleton ? :define_singleton_method : :define_method
47
- end
48
-
49
- # Nano `send` action is also the method caller in Ruby ;)
50
- def method_alias(m)
51
- m == :send ? :send_currency : m
52
- end
53
-
54
- def method_missing(m, *args, &_block)
55
- return super unless valid_method?(m)
56
- define_proxy_method(m, true)
57
- send(m, args.first)
58
- end
59
-
60
- def respond_to_missing?(m, include_private = false)
61
- valid_method?(m) || super
62
- end
63
-
64
- def valid_method?(m)
65
- proxy_param_def.nil? && methods.include?(m)
66
- end
67
- end
68
-
69
- def proxy_methods
70
- self.class.proxy_methods
71
- end
72
-
73
- def methods
74
- (super + proxy_methods).sort
75
- end
76
-
77
- private
78
-
79
- def base_params
80
- return if self.class.proxy_param_def.nil?
81
- self.class
82
- .proxy_param_def
83
- .each_with_object({}) do |(k, v), params|
84
- params[k] ||= send(v)
85
- end
86
- end
87
-
88
- def method_missing(m, *args, &_block)
89
- return super unless methods.include?(m)
90
- self.class.define_proxy_method(m)
91
- send(m, args.first)
92
- end
93
-
94
- def respond_to_missing?(m, include_private = false)
95
- methods.include?(m) || super
96
- end
97
- end
@@ -1,68 +0,0 @@
1
- # frozen_string_literal: true
2
- class Nano::ProxyContext
3
- def initialize(klass, m, opts = {})
4
- @klass = klass
5
- @method_def = klass.proxy_method_def
6
- @param_def = klass.proxy_param_def
7
- @m = m
8
- @opts = opts
9
- end
10
-
11
- def populate_params(params)
12
- opts = validate_opts!
13
- opts.merge!(params) if params
14
- validate_params!
15
- opts.delete_if { |_k, v| v.nil? }
16
- opts
17
- end
18
-
19
- def validate_opts!
20
- return @opts if @opts.is_a?(Hash)
21
- return {} if @opts.nil?
22
- raise Nano::InvalidParameterType,
23
- 'You must pass a hash to an action method'
24
- end
25
-
26
- def validate_params!
27
- ensure_required_params!
28
- ensure_no_forbidden_params!
29
- end
30
-
31
- def ensure_required_params!
32
- missing_params = required_params - opts_keys
33
- return unless missing_params.any?
34
- raise Nano::MissingParameters,
35
- "Missing required parameter(s): #{missing_params.join(', ')}"
36
- end
37
-
38
- def ensure_no_forbidden_params!
39
- forbidden_params = base_param_keys + opts_keys - allowed_params
40
- return unless forbidden_params.any?
41
- raise Nano::ForbiddenParameter,
42
- "Forbidden parameter(s) passed: #{forbidden_params.join(', ')}"
43
- end
44
-
45
- private
46
-
47
- def opts_keys
48
- @opts.nil? ? [] : @opts.keys
49
- end
50
-
51
- def allowed_params
52
- base_param_keys + required_params + optional_params
53
- end
54
-
55
- def required_params
56
- return [] unless @method_def && @method_def[@m]
57
- @method_def[@m][:required]
58
- end
59
-
60
- def optional_params
61
- return [] unless @method_def && @method_def[@m]
62
- @method_def[@m][:optional]
63
- end
64
-
65
- def base_param_keys
66
- @param_def.is_a?(Hash) ? @param_def.keys : []
67
- end
68
- end