quorum_sdk 0.1.0 → 0.2.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 +4 -4
- data/Gemfile.lock +21 -23
- data/README.md +26 -9
- data/lib/quorum_sdk/api/chain.rb +14 -1
- data/lib/quorum_sdk/api/group.rb +39 -0
- data/lib/quorum_sdk/api/light_node.rb +3 -7
- data/lib/quorum_sdk/api/management.rb +128 -0
- data/lib/quorum_sdk/api.rb +20 -11
- data/lib/quorum_sdk/client.rb +6 -2
- data/lib/quorum_sdk/utils.rb +18 -13
- data/lib/quorum_sdk/version.rb +1 -1
- data/lib/quorum_sdk.rb +2 -0
- metadata +5 -18
- data/activity_stream_pb.rb +0 -146
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 575ecf478b2a506d1370cb46615bfb67c0a96385b9bcce97576172520cf55fa0
|
4
|
+
data.tar.gz: 8dbf6f2cf9ce014419a02a13895320dbfe75d6ef550ae37319025bd566cc8143
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 75e151a940633aa6c2fcdd7ad2005642aa096c3763109ae55b965055973ea09347da4aa2f9fab0228b2809a9a5d49882542327ffbed63422c94fb3f6b006138e
|
7
|
+
data.tar.gz: cfac31d64825054781e16e6dfb9a5fb3cca5bae0598a7114272d574b5750b1695f6e63fcf0a01c76c7ad17be28d080eae2f2bac864598c9f087125b85b4bd002
|
data/Gemfile.lock
CHANGED
@@ -1,20 +1,19 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
quorum_sdk (0.
|
5
|
-
activesupport (
|
4
|
+
quorum_sdk (0.2.0)
|
5
|
+
activesupport (~> 7)
|
6
6
|
addressable (~> 2)
|
7
7
|
bcrypt (~> 3.1)
|
8
8
|
eth (~> 0.5)
|
9
|
-
faraday (
|
10
|
-
faraday-retry (
|
9
|
+
faraday (~> 2)
|
10
|
+
faraday-retry (~> 2)
|
11
11
|
google-protobuf (~> 3)
|
12
|
-
sha3 (~> 1.0)
|
13
12
|
|
14
13
|
GEM
|
15
14
|
remote: https://rubygems.org/
|
16
15
|
specs:
|
17
|
-
activesupport (7.0.4)
|
16
|
+
activesupport (7.0.4.3)
|
18
17
|
concurrent-ruby (~> 1.0, >= 1.0.2)
|
19
18
|
i18n (>= 1.6, < 2)
|
20
19
|
minitest (>= 5.1)
|
@@ -23,34 +22,34 @@ GEM
|
|
23
22
|
public_suffix (>= 2.0.2, < 6.0)
|
24
23
|
ast (2.4.2)
|
25
24
|
bcrypt (3.1.18)
|
26
|
-
concurrent-ruby (1.
|
25
|
+
concurrent-ruby (1.2.2)
|
27
26
|
eth (0.5.10)
|
28
27
|
keccak (~> 1.3)
|
29
28
|
konstructor (~> 1.0)
|
30
29
|
openssl (>= 2.2, < 4.0)
|
31
30
|
rbsecp256k1 (~> 5.1)
|
32
31
|
scrypt (~> 3.0)
|
33
|
-
faraday (2.7.
|
32
|
+
faraday (2.7.4)
|
34
33
|
faraday-net_http (>= 2.0, < 3.1)
|
35
34
|
ruby2_keywords (>= 0.0.4)
|
36
35
|
faraday-net_http (3.0.2)
|
37
|
-
faraday-retry (2.
|
36
|
+
faraday-retry (2.1.0)
|
38
37
|
faraday (~> 2.0)
|
39
38
|
ffi (1.15.5)
|
40
39
|
ffi-compiler (1.0.1)
|
41
40
|
ffi (>= 1.0.0)
|
42
41
|
rake
|
43
|
-
google-protobuf (3.
|
42
|
+
google-protobuf (3.22.2-x86_64-linux)
|
44
43
|
i18n (1.12.0)
|
45
44
|
concurrent-ruby (~> 1.0)
|
46
45
|
json (2.6.3)
|
47
46
|
keccak (1.3.1)
|
48
47
|
konstructor (1.0.2)
|
49
48
|
mini_portile2 (2.8.1)
|
50
|
-
minitest (5.
|
49
|
+
minitest (5.18.0)
|
51
50
|
openssl (3.1.0)
|
52
51
|
parallel (1.22.1)
|
53
|
-
parser (3.2.
|
52
|
+
parser (3.2.1.1)
|
54
53
|
ast (~> 2.4.1)
|
55
54
|
pkg-config (1.5.1)
|
56
55
|
public_suffix (5.0.1)
|
@@ -60,27 +59,26 @@ GEM
|
|
60
59
|
mini_portile2 (~> 2.8)
|
61
60
|
pkg-config (~> 1.5)
|
62
61
|
rubyzip (~> 2.3)
|
63
|
-
regexp_parser (2.
|
62
|
+
regexp_parser (2.7.0)
|
64
63
|
rexml (3.2.5)
|
65
|
-
rubocop (1.
|
64
|
+
rubocop (1.48.1)
|
66
65
|
json (~> 2.3)
|
67
66
|
parallel (~> 1.10)
|
68
|
-
parser (>= 3.
|
67
|
+
parser (>= 3.2.0.0)
|
69
68
|
rainbow (>= 2.2.2, < 4.0)
|
70
69
|
regexp_parser (>= 1.8, < 3.0)
|
71
70
|
rexml (>= 3.2.5, < 4.0)
|
72
|
-
rubocop-ast (>= 1.
|
71
|
+
rubocop-ast (>= 1.26.0, < 2.0)
|
73
72
|
ruby-progressbar (~> 1.7)
|
74
|
-
unicode-display_width (>=
|
75
|
-
rubocop-ast (1.
|
76
|
-
parser (>= 3.
|
77
|
-
ruby-progressbar (1.
|
73
|
+
unicode-display_width (>= 2.4.0, < 3.0)
|
74
|
+
rubocop-ast (1.27.0)
|
75
|
+
parser (>= 3.2.1.0)
|
76
|
+
ruby-progressbar (1.13.0)
|
78
77
|
ruby2_keywords (0.0.5)
|
79
78
|
rubyzip (2.3.2)
|
80
79
|
scrypt (3.0.7)
|
81
80
|
ffi-compiler (>= 1.0, < 2.0)
|
82
|
-
|
83
|
-
tzinfo (2.0.5)
|
81
|
+
tzinfo (2.0.6)
|
84
82
|
concurrent-ruby (~> 1.0)
|
85
83
|
unicode-display_width (2.4.2)
|
86
84
|
|
@@ -94,4 +92,4 @@ DEPENDENCIES
|
|
94
92
|
rubocop (~> 1.21)
|
95
93
|
|
96
94
|
BUNDLED WITH
|
97
|
-
2.4.
|
95
|
+
2.4.8
|
data/README.md
CHANGED
@@ -12,14 +12,30 @@ If bundler is not being used to manage dependencies, install the gem by executin
|
|
12
12
|
|
13
13
|
## Usage
|
14
14
|
|
15
|
-
###
|
15
|
+
### Initilize
|
16
16
|
|
17
17
|
```ruby
|
18
|
-
#
|
19
|
-
rum = QuorumSdk::API.new "rum://...."
|
18
|
+
# Initilize by seed url
|
19
|
+
rum = QuorumSdk::API.new seed_url: "rum://...."
|
20
|
+
|
21
|
+
# Initilize by config
|
22
|
+
rum = QuorumSdk::API.new(
|
23
|
+
gropu_id: '',
|
24
|
+
gropu_name: '',
|
25
|
+
cipher_key: '',
|
26
|
+
chain_urls: ['', '']
|
27
|
+
)
|
28
|
+
```
|
29
|
+
|
30
|
+
### Send a trx
|
20
31
|
|
32
|
+
```ruby
|
21
33
|
# build a message
|
22
|
-
msg =
|
34
|
+
msg = {
|
35
|
+
type: 'Note',
|
36
|
+
name: 'A title',
|
37
|
+
content: 'Something awesome'
|
38
|
+
}
|
23
39
|
|
24
40
|
# prepare an ETH account
|
25
41
|
account = QuorumSdk::Account.new
|
@@ -39,14 +55,15 @@ rum.send_trx trx
|
|
39
55
|
Build a activity message
|
40
56
|
|
41
57
|
```ruby
|
42
|
-
# initilize SDK
|
43
|
-
rum = QuorumSdk::API.new "rum://...."
|
44
|
-
|
45
58
|
# build a Note type object
|
46
|
-
note =
|
59
|
+
note = {
|
60
|
+
type: 'Note',
|
61
|
+
name: 'A title',
|
62
|
+
content: 'Something awesome.'
|
63
|
+
}
|
47
64
|
|
48
65
|
# build Activity object, wrapping Note object
|
49
|
-
activity =
|
66
|
+
activity = { type: 'Create', object: note }
|
50
67
|
|
51
68
|
# build Trx
|
52
69
|
trx = rum.build_trx data: activity, private_key: account.private_hex
|
data/lib/quorum_sdk/api/chain.rb
CHANGED
@@ -6,7 +6,20 @@ module QuorumSdk
|
|
6
6
|
module Chain
|
7
7
|
def trx(trx_id)
|
8
8
|
path = "api/v1/trx/#{group_id}/#{trx_id}"
|
9
|
-
client.get
|
9
|
+
r = client.get(path).body
|
10
|
+
r =
|
11
|
+
begin
|
12
|
+
JSON.parse r
|
13
|
+
rescue JSON::ParserError
|
14
|
+
r
|
15
|
+
end
|
16
|
+
|
17
|
+
if r['Data'].present?
|
18
|
+
data = Base64.strict_decode64 r['Data']
|
19
|
+
r['Data'] = QuorumSdk::Utils.decrypt_trx_data data, key: cipher_key
|
20
|
+
end
|
21
|
+
|
22
|
+
r
|
10
23
|
end
|
11
24
|
end
|
12
25
|
end
|
@@ -0,0 +1,39 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module QuorumSdk
|
4
|
+
class API
|
5
|
+
# Wrapper for HTTP APIs for group
|
6
|
+
module Group
|
7
|
+
ARGUMENTS_FOR_CREATE_GROUP = %i[app_key group_name].freeze
|
8
|
+
def create_group(**kwargs)
|
9
|
+
raise ArgumentError, "Keyword arguments #{ARGUMENTS_FOR_CREATE_GROUP} must be provided" unless ARGUMENTS_FOR_CREATE_GROUP.all?(&->(arg) { arg.in? kwargs.keys })
|
10
|
+
|
11
|
+
consensus_type = kwargs[:consensus_type] || 'poa'
|
12
|
+
raise ArgumentError, 'consensus_type should be poa or pos' unless consensus_type.in?(%w[poa pos])
|
13
|
+
|
14
|
+
encryption_type = kwargs[:encryption_type] || 'public'
|
15
|
+
raise ArgumentError, 'encryption_type should be public or private' unless encryption_type.in?(%w[public private])
|
16
|
+
|
17
|
+
path = 'api/v1/group'
|
18
|
+
|
19
|
+
payload = {
|
20
|
+
consensus_type:,
|
21
|
+
encryption_type:,
|
22
|
+
app_key: kwargs[:app_key],
|
23
|
+
group_name: kwargs[:group_name]
|
24
|
+
}
|
25
|
+
client.post(path, **payload).body
|
26
|
+
end
|
27
|
+
|
28
|
+
def groups
|
29
|
+
path = 'api/v1/groups'
|
30
|
+
client.get(path).body
|
31
|
+
end
|
32
|
+
|
33
|
+
def seed(group_id)
|
34
|
+
path = "api/v1/group/#{group_id}/seed"
|
35
|
+
client.get(path).body
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
@@ -7,7 +7,6 @@ module QuorumSdk
|
|
7
7
|
ARGUMENTS_FOR_BUILD_TRX = %i[private_key data].freeze
|
8
8
|
def build_trx(**kwargs)
|
9
9
|
raise ArgumentError, "Keyword arguments #{ARGUMENTS_FOR_BUILD_TRX} must be provided" unless ARGUMENTS_FOR_BUILD_TRX.all?(&->(arg) { arg.in? kwargs.keys })
|
10
|
-
raise ArgumentError, 'data should be instance of Google::Protobuf::MessageExts' unless kwargs[:data].is_a?(Google::Protobuf::MessageExts)
|
11
10
|
|
12
11
|
kwargs = kwargs.merge(
|
13
12
|
group_id:,
|
@@ -26,8 +25,7 @@ module QuorumSdk
|
|
26
25
|
group_id:,
|
27
26
|
start_trx: kwargs[:start_trx],
|
28
27
|
num: kwargs[:num] || 100,
|
29
|
-
senders: kwargs[:senders].presence || []
|
30
|
-
trx_types: kwargs[:trx_types].presence || []
|
28
|
+
senders: kwargs[:senders].presence || []
|
31
29
|
}.compact
|
32
30
|
params[:reverse] =
|
33
31
|
if kwargs[:reverse]
|
@@ -56,6 +54,8 @@ module QuorumSdk
|
|
56
54
|
return list unless list.is_a?(Array)
|
57
55
|
|
58
56
|
list.each do |trx|
|
57
|
+
next if trx['Data'].blank?
|
58
|
+
|
59
59
|
data = Base64.strict_decode64 trx['Data']
|
60
60
|
trx['Data'] = QuorumSdk::Utils.decrypt_trx_data data, key: cipher_key
|
61
61
|
end
|
@@ -79,10 +79,6 @@ module QuorumSdk
|
|
79
79
|
def group_info
|
80
80
|
chain_data({ GroupId: group_id }, 'group_info')
|
81
81
|
end
|
82
|
-
|
83
|
-
def auth_type(trx_type)
|
84
|
-
chain_data({ GroupId: group_id, TrxType: trx_type }, 'auth_type')
|
85
|
-
end
|
86
82
|
end
|
87
83
|
end
|
88
84
|
end
|
@@ -0,0 +1,128 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module QuorumSdk
|
4
|
+
class API
|
5
|
+
# Wrapper for HTTP APIs for chain
|
6
|
+
module Management
|
7
|
+
def allow_list(group_id: nil)
|
8
|
+
group_id ||= @group_id
|
9
|
+
path = "api/v1/group/#{group_id}/trx/allowlist"
|
10
|
+
client.get(path).body
|
11
|
+
end
|
12
|
+
|
13
|
+
def deny_list(group_id: nil)
|
14
|
+
group_id ||= @group_id
|
15
|
+
path = "api/v1/group/#{group_id}/trx/denylist"
|
16
|
+
client.get(path).body
|
17
|
+
end
|
18
|
+
|
19
|
+
def auth_type(trx_type, group_id: nil)
|
20
|
+
group_id ||= @group_id
|
21
|
+
path = "api/v1/group/#{group_id}/trx/auth/#{trx_type}"
|
22
|
+
client.get(path).body
|
23
|
+
end
|
24
|
+
|
25
|
+
ARGUMENTS_FOR_UPDATE_CHAIN_CONFIG = %i[config type].freeze
|
26
|
+
def update_chain_config(**kwargs)
|
27
|
+
raise ArgumentError, "Keyword arguments #{ARGUMENTS_FOR_UPDATE_CHAIN_CONFIG} must be provided" unless ARGUMENTS_FOR_UPDATE_CHAIN_CONFIG.all?(&->(arg) { arg.in? kwargs.keys })
|
28
|
+
|
29
|
+
type = kwargs[:type]
|
30
|
+
raise ArgumentError, 'type must be one of set_trx_auth_mode/upd_alw_list/upd_dny_list' unless type.in? %w[set_trx_auth_mode upd_alw_list upd_dny_list]
|
31
|
+
|
32
|
+
config = kwargs[:config]
|
33
|
+
config = config.to_json if config.is_a?(Hash)
|
34
|
+
|
35
|
+
group_id = kwargs[:group_id] || @group_id
|
36
|
+
raise ArgumentError, 'group_id must be provided' if group_id.blank?
|
37
|
+
|
38
|
+
path = 'api/v1/group/chainconfig'
|
39
|
+
payload = {
|
40
|
+
type:,
|
41
|
+
config:,
|
42
|
+
group_id:,
|
43
|
+
memo: kwargs[:memo]
|
44
|
+
}.compact
|
45
|
+
client.post(path, **payload).body
|
46
|
+
end
|
47
|
+
|
48
|
+
ARGUMENTS_FOR_UPDATE_AUTH_MODE = %i[trx_auth_mode].freeze
|
49
|
+
def update_trx_auth_mode(**kwargs)
|
50
|
+
raise ArgumentError, "Keyword arguments #{ARGUMENTS_FOR_UPDATE_AUTH_MODE} must be provided" unless ARGUMENTS_FOR_UPDATE_AUTH_MODE.all?(&->(arg) { arg.in? kwargs.keys })
|
51
|
+
|
52
|
+
trx_type = kwargs[:trx_type] || 'POST'
|
53
|
+
raise ArgumentError, 'trx_type must be one of POST/ANNOUNCE/REQ_BLOCK_FORWARD/REQ_BLOCK_FORWARD' unless trx_type.in? %w[POST ANNOUNCE REQ_BLOCK_RESP REQ_BLOCK_BACKWARD]
|
54
|
+
|
55
|
+
trx_auth_mode = kwargs[:trx_auth_mode]
|
56
|
+
raise ArgumentError, 'trx_auth_mode must be one of follow_alw_list/follow_dny_list' unless trx_auth_mode.in? %w[follow_alw_list follow_dny_list]
|
57
|
+
|
58
|
+
update_chain_config(
|
59
|
+
group_id: kwargs[:group_id],
|
60
|
+
type: 'set_trx_auth_mode',
|
61
|
+
config: {
|
62
|
+
trx_type:,
|
63
|
+
trx_auth_mode:
|
64
|
+
},
|
65
|
+
memo: kwargs[:memo]
|
66
|
+
)
|
67
|
+
end
|
68
|
+
|
69
|
+
ARGUMENTS_FOR_UPDATE_ALLOW_LIST = %i[action pubkey].freeze
|
70
|
+
def update_allow_list(**kwargs)
|
71
|
+
raise ArgumentError, "Keyword arguments #{ARGUMENTS_FOR_UPDATE_ALLOW_LIST} must be provided" unless ARGUMENTS_FOR_UPDATE_ALLOW_LIST.all?(&->(arg) { arg.in? kwargs.keys })
|
72
|
+
|
73
|
+
trx_type = kwargs[:trx_type] || ['POST']
|
74
|
+
trx_type = [trx_type] if trx_type.is_a?(String)
|
75
|
+
raise ArgumentError, 'trx type must be one of POST/ANNOUNCE/REQ_BLOCK_FORWARD/REQ_BLOCK_FORWARD' unless trx_type.all?(&->(op) { op.in? %w[POST ANNOUNCE REQ_BLOCK_RESP REQ_BLOCK_BACKWARD] })
|
76
|
+
|
77
|
+
action = kwargs[:action]
|
78
|
+
raise ArgumentError, 'trx_auth_mode must be one of add/remove' unless action.in? %w[add remove]
|
79
|
+
|
80
|
+
pubkey = kwargs[:pubkey]
|
81
|
+
if Eth::Util.hex?(pubkey)
|
82
|
+
pubkey = Secp256k1::PublicKey.from_data([pubkey].pack('H*')).compressed
|
83
|
+
pubkey = Base64.urlsafe_encode64(pubkey)
|
84
|
+
end
|
85
|
+
|
86
|
+
update_chain_config(
|
87
|
+
group_id: kwargs[:group_id],
|
88
|
+
type: 'upd_alw_list',
|
89
|
+
config: {
|
90
|
+
trx_type:,
|
91
|
+
action:,
|
92
|
+
pubkey:
|
93
|
+
},
|
94
|
+
memo: kwargs[:memo]
|
95
|
+
)
|
96
|
+
end
|
97
|
+
|
98
|
+
ARGUMENTS_FOR_UPDATE_DENY_LIST = %i[action pubkey].freeze
|
99
|
+
def update_deny_list(**kwargs)
|
100
|
+
raise ArgumentError, "Keyword arguments #{ARGUMENTS_FOR_UPDATE_DENY_LIST} must be provided" unless ARGUMENTS_FOR_UPDATE_DENY_LIST.all?(&->(arg) { arg.in? kwargs.keys })
|
101
|
+
|
102
|
+
trx_type = kwargs[:trx_type] || ['POST']
|
103
|
+
trx_type = [trx_type] if trx_type.is_a?(String)
|
104
|
+
raise ArgumentError, 'trx type must be one of POST/ANNOUNCE/REQ_BLOCK_FORWARD/REQ_BLOCK_FORWARD' unless trx_type.all?(&->(op) { op.in? %w[POST ANNOUNCE REQ_BLOCK_RESP REQ_BLOCK_BACKWARD] })
|
105
|
+
|
106
|
+
action = kwargs[:action]
|
107
|
+
raise ArgumentError, 'trx_auth_mode must be one of add/remove' unless action.in? %w[add remove]
|
108
|
+
|
109
|
+
pubkey = kwargs[:pubkey]
|
110
|
+
if Eth::Util.hex?(pubkey)
|
111
|
+
pubkey = Secp256k1::PublicKey.from_data([pubkey].pack('H*')).compressed
|
112
|
+
pubkey = Base64.urlsafe_encode64(pubkey)
|
113
|
+
end
|
114
|
+
|
115
|
+
update_chain_config(
|
116
|
+
group_id: kwargs[:group_id],
|
117
|
+
type: 'upd_dny_list',
|
118
|
+
config: {
|
119
|
+
trx_type:,
|
120
|
+
action:,
|
121
|
+
pubkey:
|
122
|
+
},
|
123
|
+
memo: kwargs[:memo]
|
124
|
+
)
|
125
|
+
end
|
126
|
+
end
|
127
|
+
end
|
128
|
+
end
|
data/lib/quorum_sdk/api.rb
CHANGED
@@ -1,7 +1,9 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
require_relative 'api/chain'
|
4
|
+
require_relative 'api/group'
|
4
5
|
require_relative 'api/light_node'
|
6
|
+
require_relative 'api/management'
|
5
7
|
require_relative 'client'
|
6
8
|
|
7
9
|
module QuorumSdk
|
@@ -10,23 +12,30 @@ module QuorumSdk
|
|
10
12
|
attr_reader :group_id, :group_name, :consensus_type, :encryption_type, :app_key, :owner_pubkey, :signature,
|
11
13
|
:cipher_key, :chain_urls, :client
|
12
14
|
|
13
|
-
def initialize(
|
14
|
-
|
15
|
+
def initialize(**kwargs)
|
16
|
+
config =
|
17
|
+
if kwargs[:seed_url].present?
|
18
|
+
QuorumSdk::Utils.parse_seed_url kwargs[:seed_url]
|
19
|
+
else
|
20
|
+
kwargs
|
21
|
+
end
|
15
22
|
|
16
|
-
@group_id =
|
17
|
-
@group_name =
|
18
|
-
@consensus_type =
|
19
|
-
@encryption_type =
|
20
|
-
@app_key =
|
21
|
-
@owner_pubkey =
|
22
|
-
@signature =
|
23
|
-
@cipher_key =
|
24
|
-
@chain_urls =
|
23
|
+
@group_id = config[:group_id]
|
24
|
+
@group_name = config[:group_name]
|
25
|
+
@consensus_type = config[:consensus_type]
|
26
|
+
@encryption_type = config[:encryption_type]
|
27
|
+
@app_key = config[:app_key]
|
28
|
+
@owner_pubkey = config[:owner_pubkey]
|
29
|
+
@signature = config[:signature]
|
30
|
+
@cipher_key = config[:cipher_key]
|
31
|
+
@chain_urls = config[:chain_urls]
|
25
32
|
|
26
33
|
@client = QuorumSdk::Client.new(@chain_urls)
|
27
34
|
end
|
28
35
|
|
29
36
|
include QuorumSdk::API::Chain
|
37
|
+
include QuorumSdk::API::Group
|
30
38
|
include QuorumSdk::API::LightNode
|
39
|
+
include QuorumSdk::API::Management
|
31
40
|
end
|
32
41
|
end
|
data/lib/quorum_sdk/client.rb
CHANGED
@@ -9,7 +9,11 @@ module QuorumSdk
|
|
9
9
|
|
10
10
|
def initialize(domains)
|
11
11
|
@domains = domains || []
|
12
|
-
|
12
|
+
uri = Addressable::URI.parse @domains.first
|
13
|
+
url = Addressable::URI.new(scheme: uri.scheme, host: uri.host, port: uri.port).to_s
|
14
|
+
jwt = uri.query_values['jwt']
|
15
|
+
|
16
|
+
@conn = Faraday.new(url:, headers: { Authorization: "Bearer #{jwt}" }) do |f|
|
13
17
|
f.request :json
|
14
18
|
f.response :json
|
15
19
|
f.response :logger
|
@@ -21,7 +25,7 @@ module QuorumSdk
|
|
21
25
|
end
|
22
26
|
|
23
27
|
def get(path, **params)
|
24
|
-
@conn.
|
28
|
+
@conn.get path, **params
|
25
29
|
end
|
26
30
|
end
|
27
31
|
end
|
data/lib/quorum_sdk/utils.rb
CHANGED
@@ -34,6 +34,8 @@ module QuorumSdk
|
|
34
34
|
end
|
35
35
|
|
36
36
|
def uuid_from_base64(str)
|
37
|
+
return if str.blank?
|
38
|
+
|
37
39
|
hex = Base64.urlsafe_decode64(str).unpack1('H*')
|
38
40
|
format(
|
39
41
|
'%<first>s-%<second>s-%<third>s-%<forth>s-%<fifth>s',
|
@@ -48,12 +50,14 @@ module QuorumSdk
|
|
48
50
|
ARGUMENTS_FOR_ENCRYPT_TRX = %i[private_key group_id cipher_key data].freeze
|
49
51
|
def encrypt_trx(**kwargs)
|
50
52
|
raise ArgumentError, "Keyword arguments #{ARGUMENTS_FOR_ENCRYPT_TRX} must be provided" unless ARGUMENTS_FOR_ENCRYPT_TRX.all?(&->(arg) { arg.in? kwargs.keys })
|
51
|
-
raise ArgumentError, 'data should be instance of Google::Protobuf::MessageExts' unless kwargs[:data].is_a?(Google::Protobuf::MessageExts)
|
52
53
|
|
53
|
-
data =
|
54
|
-
|
55
|
-
|
56
|
-
|
54
|
+
data =
|
55
|
+
case kwargs[:data]
|
56
|
+
when Hash
|
57
|
+
kwargs[:data].to_json
|
58
|
+
else
|
59
|
+
kwargs[:data].to_s
|
60
|
+
end
|
57
61
|
encrypted_data = aes_encrypt data, key: kwargs[:cipher_key]
|
58
62
|
|
59
63
|
account = QuorumSdk::Account.new priv: kwargs[:private_key]
|
@@ -64,9 +68,8 @@ module QuorumSdk
|
|
64
68
|
GroupId: kwargs[:group_id],
|
65
69
|
Data: encrypted_data,
|
66
70
|
TimeStamp: (kwargs[:timestamp].to_i || (Time.now.to_f * 1e9).to_i),
|
67
|
-
Version: (kwargs[:version] ||
|
71
|
+
Version: (kwargs[:version] || TRX_VERSION),
|
68
72
|
Expired: (kwargs[:expired].to_i || (30.seconds.from_now.to_f * 1e9).to_i),
|
69
|
-
Nonce: (kwargs[:nonce] || 1),
|
70
73
|
SenderPubkey: Base64.urlsafe_encode64(account.public_bytes_compressed, padding: false)
|
71
74
|
)
|
72
75
|
|
@@ -91,9 +94,9 @@ module QuorumSdk
|
|
91
94
|
hash = Digest::SHA256.hexdigest Quorum::Pb::Trx.encode(trx_without_sig)
|
92
95
|
|
93
96
|
signature = trx.SenderSign.unpack1('H*')
|
94
|
-
|
95
|
-
|
96
|
-
raise QuorumSdk::Error,
|
97
|
+
public_key = Secp256k1::PublicKey.from_data(Base64.urlsafe_decode64(trx.SenderPubkey)).uncompressed.unpack1('H*')
|
98
|
+
recover_key = Eth::Signature.recover [hash].pack('H*'), signature
|
99
|
+
raise QuorumSdk::Error, "Signature not verified: #{public_key} != #{recover_key}" unless public_key == recover_key
|
97
100
|
|
98
101
|
data = decrypt_trx_data(trx.Data, key:)
|
99
102
|
|
@@ -104,9 +107,11 @@ module QuorumSdk
|
|
104
107
|
|
105
108
|
def decrypt_trx_data(cipher, key:)
|
106
109
|
decrypted_data = aes_decrypt(cipher, key:)
|
107
|
-
|
108
|
-
|
109
|
-
JSON
|
110
|
+
begin
|
111
|
+
JSON.parse(decrypted_data).with_indifferent_access
|
112
|
+
rescue JSON::ParserError
|
113
|
+
decrypted_data
|
114
|
+
end
|
110
115
|
end
|
111
116
|
|
112
117
|
def aes_encrypt(data, key:)
|
data/lib/quorum_sdk/version.rb
CHANGED
data/lib/quorum_sdk.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: quorum_sdk
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- an-lee
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2023-
|
11
|
+
date: 2023-03-24 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activesupport
|
@@ -108,20 +108,6 @@ dependencies:
|
|
108
108
|
- - "~>"
|
109
109
|
- !ruby/object:Gem::Version
|
110
110
|
version: '3'
|
111
|
-
- !ruby/object:Gem::Dependency
|
112
|
-
name: sha3
|
113
|
-
requirement: !ruby/object:Gem::Requirement
|
114
|
-
requirements:
|
115
|
-
- - "~>"
|
116
|
-
- !ruby/object:Gem::Version
|
117
|
-
version: '1.0'
|
118
|
-
type: :runtime
|
119
|
-
prerelease: false
|
120
|
-
version_requirements: !ruby/object:Gem::Requirement
|
121
|
-
requirements:
|
122
|
-
- - "~>"
|
123
|
-
- !ruby/object:Gem::Version
|
124
|
-
version: '1.0'
|
125
111
|
description: A API wrapper for Quorum
|
126
112
|
email:
|
127
113
|
- an.lee.work@gmail.com
|
@@ -137,7 +123,6 @@ files:
|
|
137
123
|
- LICENSE.txt
|
138
124
|
- README.md
|
139
125
|
- Rakefile
|
140
|
-
- activity_stream_pb.rb
|
141
126
|
- lib/proto/activity_stream.proto
|
142
127
|
- lib/proto/activity_stream_pb.rb
|
143
128
|
- lib/proto/chain.proto
|
@@ -146,7 +131,9 @@ files:
|
|
146
131
|
- lib/quorum_sdk/account.rb
|
147
132
|
- lib/quorum_sdk/api.rb
|
148
133
|
- lib/quorum_sdk/api/chain.rb
|
134
|
+
- lib/quorum_sdk/api/group.rb
|
149
135
|
- lib/quorum_sdk/api/light_node.rb
|
136
|
+
- lib/quorum_sdk/api/management.rb
|
150
137
|
- lib/quorum_sdk/client.rb
|
151
138
|
- lib/quorum_sdk/utils.rb
|
152
139
|
- lib/quorum_sdk/version.rb
|
@@ -174,7 +161,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
174
161
|
- !ruby/object:Gem::Version
|
175
162
|
version: '0'
|
176
163
|
requirements: []
|
177
|
-
rubygems_version: 3.4.
|
164
|
+
rubygems_version: 3.4.7
|
178
165
|
signing_key:
|
179
166
|
specification_version: 4
|
180
167
|
summary: A Quorum SDK implemented in Ruby
|
data/activity_stream_pb.rb
DELETED
@@ -1,146 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
# Generated by the protocol buffer compiler. DO NOT EDIT!
|
4
|
-
# source: activity_stream.proto
|
5
|
-
|
6
|
-
require 'google/protobuf'
|
7
|
-
|
8
|
-
require 'google/protobuf/timestamp_pb'
|
9
|
-
require 'google/protobuf/any_pb'
|
10
|
-
|
11
|
-
Google::Protobuf::DescriptorPool.generated_pool.build do
|
12
|
-
add_file('activity_stream.proto', syntax: :proto3) do
|
13
|
-
add_message 'quorum.pb.AnyObj' do
|
14
|
-
optional :any, :message, 1, 'google.protobuf.Any'
|
15
|
-
end
|
16
|
-
add_message 'quorum.pb.Object' do
|
17
|
-
optional :id, :string, 1
|
18
|
-
optional :type, :string, 2
|
19
|
-
repeated :attachments, :message, 3, 'quorum.pb.Object'
|
20
|
-
repeated :attributedTo, :message, 4, 'quorum.pb.Object'
|
21
|
-
optional :audience, :message, 5, 'quorum.pb.Object'
|
22
|
-
optional :content, :string, 6
|
23
|
-
optional :context, :message, 7, 'quorum.pb.Object'
|
24
|
-
optional :name, :string, 8
|
25
|
-
optional :endtime, :message, 9, 'google.protobuf.Timestamp'
|
26
|
-
optional :generator, :message, 10, 'quorum.pb.Object'
|
27
|
-
repeated :icon, :message, 11, 'quorum.pb.Object'
|
28
|
-
repeated :image, :message, 12, 'quorum.pb.Image'
|
29
|
-
optional :inreplyto, :message, 13, 'quorum.pb.Reply'
|
30
|
-
optional :location, :message, 14, 'quorum.pb.Object'
|
31
|
-
optional :preview, :message, 15, 'quorum.pb.Object'
|
32
|
-
optional :published, :message, 16, 'google.protobuf.Timestamp'
|
33
|
-
optional :replies, :message, 17, 'quorum.pb.Object'
|
34
|
-
optional :startTime, :message, 18, 'google.protobuf.Timestamp'
|
35
|
-
optional :summary, :string, 19
|
36
|
-
repeated :tag, :message, 20, 'quorum.pb.Object'
|
37
|
-
optional :updated, :message, 21, 'google.protobuf.Timestamp'
|
38
|
-
repeated :url, :message, 22, 'quorum.pb.Link'
|
39
|
-
repeated :to, :message, 23, 'quorum.pb.Object'
|
40
|
-
repeated :bto, :message, 24, 'quorum.pb.Object'
|
41
|
-
repeated :cc, :message, 25, 'quorum.pb.Object'
|
42
|
-
repeated :bcc, :message, 26, 'quorum.pb.Object'
|
43
|
-
optional :mediaType, :string, 27
|
44
|
-
optional :duration, :string, 28
|
45
|
-
optional :file, :message, 29, 'quorum.pb.File'
|
46
|
-
end
|
47
|
-
add_message 'quorum.pb.Link' do
|
48
|
-
optional :href, :string, 1
|
49
|
-
repeated :rel, :string, 2
|
50
|
-
optional :mediaType, :string, 3
|
51
|
-
optional :name, :string, 4
|
52
|
-
optional :hreflang, :string, 5
|
53
|
-
optional :height, :uint32, 6
|
54
|
-
optional :width, :uint32, 7
|
55
|
-
optional :preview, :message, 8, 'quorum.pb.Object'
|
56
|
-
end
|
57
|
-
add_message 'quorum.pb.Reply' do
|
58
|
-
optional :trxid, :string, 1
|
59
|
-
optional :groupid, :string, 2
|
60
|
-
end
|
61
|
-
add_message 'quorum.pb.Image' do
|
62
|
-
optional :id, :string, 1
|
63
|
-
optional :name, :string, 2
|
64
|
-
optional :mediaType, :string, 3
|
65
|
-
optional :content, :bytes, 4
|
66
|
-
optional :url, :string, 5
|
67
|
-
end
|
68
|
-
add_message 'quorum.pb.File' do
|
69
|
-
optional :id, :string, 1
|
70
|
-
optional :name, :string, 2
|
71
|
-
optional :mediaType, :string, 3
|
72
|
-
optional :compression, :enum, 4, 'quorum.pb.File.Compression'
|
73
|
-
optional :content, :bytes, 5
|
74
|
-
optional :url, :string, 6
|
75
|
-
end
|
76
|
-
add_enum 'quorum.pb.File.Compression' do
|
77
|
-
value :none, 0
|
78
|
-
value :gz, 1
|
79
|
-
value :zip, 2
|
80
|
-
value :zstd, 3
|
81
|
-
end
|
82
|
-
add_message 'quorum.pb.Person' do
|
83
|
-
optional :id, :string, 1
|
84
|
-
optional :name, :string, 2
|
85
|
-
optional :image, :message, 3, 'quorum.pb.Image'
|
86
|
-
repeated :wallet, :message, 11, 'quorum.pb.Payment'
|
87
|
-
end
|
88
|
-
add_message 'quorum.pb.Payment' do
|
89
|
-
optional :id, :string, 1
|
90
|
-
optional :type, :string, 2
|
91
|
-
optional :name, :string, 3
|
92
|
-
end
|
93
|
-
add_message 'quorum.pb.Activity' do
|
94
|
-
optional :id, :string, 1
|
95
|
-
optional :type, :string, 2
|
96
|
-
repeated :attachments, :message, 3, 'quorum.pb.Object'
|
97
|
-
repeated :attributedTo, :message, 4, 'quorum.pb.Object'
|
98
|
-
optional :audience, :message, 5, 'quorum.pb.Object'
|
99
|
-
optional :content, :string, 6
|
100
|
-
optional :context, :message, 7, 'quorum.pb.Object'
|
101
|
-
optional :name, :string, 8
|
102
|
-
optional :endtime, :message, 9, 'google.protobuf.Timestamp'
|
103
|
-
optional :generator, :message, 10, 'quorum.pb.Object'
|
104
|
-
repeated :icon, :message, 11, 'quorum.pb.Object'
|
105
|
-
repeated :image, :message, 12, 'quorum.pb.Object'
|
106
|
-
optional :inReplyTo, :message, 13, 'quorum.pb.Object'
|
107
|
-
optional :location, :message, 14, 'quorum.pb.Object'
|
108
|
-
optional :preview, :message, 15, 'quorum.pb.Object'
|
109
|
-
optional :published, :message, 16, 'google.protobuf.Timestamp'
|
110
|
-
optional :replies, :message, 17, 'quorum.pb.Object'
|
111
|
-
optional :startTime, :message, 18, 'google.protobuf.Timestamp'
|
112
|
-
optional :summary, :string, 19
|
113
|
-
repeated :tag, :message, 20, 'quorum.pb.Object'
|
114
|
-
optional :updated, :message, 21, 'google.protobuf.Timestamp'
|
115
|
-
repeated :url, :message, 22, 'quorum.pb.Link'
|
116
|
-
repeated :to, :message, 23, 'quorum.pb.Object'
|
117
|
-
repeated :bto, :message, 24, 'quorum.pb.Object'
|
118
|
-
repeated :cc, :message, 25, 'quorum.pb.Object'
|
119
|
-
repeated :bcc, :message, 26, 'quorum.pb.Object'
|
120
|
-
optional :mediaType, :string, 27
|
121
|
-
optional :duration, :string, 28
|
122
|
-
optional :actor, :message, 29, 'quorum.pb.Object'
|
123
|
-
optional :object, :message, 30, 'quorum.pb.Object'
|
124
|
-
optional :target, :message, 31, 'quorum.pb.Object'
|
125
|
-
optional :result, :message, 32, 'quorum.pb.Object'
|
126
|
-
optional :origin, :message, 33, 'quorum.pb.Object'
|
127
|
-
optional :instrument, :message, 34, 'quorum.pb.Object'
|
128
|
-
optional :person, :message, 35, 'quorum.pb.Person'
|
129
|
-
end
|
130
|
-
end
|
131
|
-
end
|
132
|
-
|
133
|
-
module Quorum
|
134
|
-
module Pb
|
135
|
-
AnyObj = ::Google::Protobuf::DescriptorPool.generated_pool.lookup('quorum.pb.AnyObj').msgclass
|
136
|
-
Object = ::Google::Protobuf::DescriptorPool.generated_pool.lookup('quorum.pb.Object').msgclass
|
137
|
-
Link = ::Google::Protobuf::DescriptorPool.generated_pool.lookup('quorum.pb.Link').msgclass
|
138
|
-
Reply = ::Google::Protobuf::DescriptorPool.generated_pool.lookup('quorum.pb.Reply').msgclass
|
139
|
-
Image = ::Google::Protobuf::DescriptorPool.generated_pool.lookup('quorum.pb.Image').msgclass
|
140
|
-
File = ::Google::Protobuf::DescriptorPool.generated_pool.lookup('quorum.pb.File').msgclass
|
141
|
-
File::Compression = ::Google::Protobuf::DescriptorPool.generated_pool.lookup('quorum.pb.File.Compression').enummodule
|
142
|
-
Person = ::Google::Protobuf::DescriptorPool.generated_pool.lookup('quorum.pb.Person').msgclass
|
143
|
-
Payment = ::Google::Protobuf::DescriptorPool.generated_pool.lookup('quorum.pb.Payment').msgclass
|
144
|
-
Activity = ::Google::Protobuf::DescriptorPool.generated_pool.lookup('quorum.pb.Activity').msgclass
|
145
|
-
end
|
146
|
-
end
|