fabric-gateway 0.0.2 → 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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 26b462c9b71e8dc9e2926e0c24b7b626cb40e13358fb36418d3ce121692aa579
4
- data.tar.gz: aff70180d2bdb947f0107cb3627fb7b95a4bde69068a8dc91acabb742dc78604
3
+ metadata.gz: 4ebf0356b3eb18ce6a114639e36b2a2c444a3aa527b63e5678eea7fd86322f33
4
+ data.tar.gz: 3578f40c92ee6828b7f82361bc2cd2480f385c956b03e936aec1ab85d004e1f1
5
5
  SHA512:
6
- metadata.gz: fb8ad49f7dd5e04c6b4c125fdb19e7b61927c0f622770c85added66ccd4cbcbea36df5a7922de0a0f8fbb1c73b31ebae31ed160e500a8fd601a085c2f2444168
7
- data.tar.gz: 9cf3a1b4f2ce340052a31fcfc00f622326f885f833b0b158c5f4d2fc64a85557848c6573f47ce7690369d74d6ef8cc6521992ebe4f47b46bdfb2c8184d94d8ac
6
+ metadata.gz: c213fa67cf1838f4aaf0d64b82e73f1c3c267dff9d61a622e877e3458072a46e455a4c90302130a35dab0f528eea6e398afa166aad1c7d6435681ef1fac36609
7
+ data.tar.gz: 99b60025222f359a922a449df21310c4ebc575d4d2453825c376754c24303a8f9fbda2dc9c265c549fd6ee77bf42dff89aa433a1b91948c6a9b2005fc2a51d52
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- fabric-gateway (0.0.1)
4
+ fabric-gateway (0.0.2)
5
5
  google-protobuf (>= 3.19.1)
6
6
  grpc (~> 1.42)
7
7
 
@@ -15,6 +15,7 @@ GEM
15
15
  grpc (1.42.0)
16
16
  google-protobuf (~> 3.18)
17
17
  googleapis-common-protos-types (~> 1.0)
18
+ grpc-tools (1.42.0)
18
19
  rake (12.3.2)
19
20
  rspec (3.10.0)
20
21
  rspec-core (~> 3.10.0)
@@ -35,6 +36,7 @@ PLATFORMS
35
36
 
36
37
  DEPENDENCIES
37
38
  fabric-gateway!
39
+ grpc-tools (~> 1.42)
38
40
  rake (~> 12.0)
39
41
  rspec (~> 3.0)
40
42
 
data/LICENSE.txt CHANGED
@@ -1,6 +1,6 @@
1
1
  The MIT License (MIT)
2
2
 
3
- Copyright (c) 2021 TODO: Write your name
3
+ Copyright (c) 2021 The Ethical Identity Company
4
4
 
5
5
  Permission is hereby granted, free of charge, to any person obtaining a copy
6
6
  of this software and associated documentation files (the "Software"), to deal
data/README.md CHANGED
@@ -18,20 +18,56 @@ Or install it yourself as:
18
18
 
19
19
  $ gem install fabric-gateway
20
20
 
21
- ## Usage
21
+ ### ISSUES
22
+
23
+ Note, there is an issue with the grpc library for MacOS (https://github.com/grpc/grpc/issues/28271). It results in a segfault in ruby when trying to make a connection.
22
24
 
23
- This is a pre-alpha library. None of the code has been tested or confirmed working yet.
25
+ Workaround: Either run on linux or use a docker container as a workaround.
24
26
 
27
+ Will update to new version of grpc when fix is released.
25
28
 
26
- non-working notes...
29
+ ## Usage
30
+
31
+ This is a alpha stage library. This library is barely working.
27
32
 
28
33
  ```
29
34
  $ bin/console
30
35
 
31
- # how in the world do we grab a certificate and connect to the peer properly?
32
- stub=Gateway::Gateway::Stub.new('localhost:7051', :this_channel_is_insecure)
33
- stub.submit(Gateway::SubmitRequest.new(transaction_id: "123", channel_id: "2", prepared_transaction: Common::Envelope.new()))
34
36
 
37
+ def load_certs
38
+ data_dir ='/your/certs/directory' # aka test-network/organizations
39
+ files = [
40
+ 'peerOrganizations/org1.example.com/ca/ca.org1.example.com-cert.pem',
41
+ 'peerOrganizations/org1.example.com/users/Admin\@org1.example.com/msp/keystore/9f7c67dd4dd6562d258593c0d5011a3bff9121e65e67ff7fd3212919ae400a88_sk',
42
+ 'peerOrganizations/org1.example.com/users/Admin\@org1.example.com/msp/signcerts/cert.pem'
43
+ ]
44
+ files.map { |f| File.open(File.join(data_dir, f)).read }
45
+ end
46
+
47
+ # needed if you are connecting via a different dns name or IP address
48
+ client_opts = {
49
+ channel_args: {
50
+ GRPC::Core::Channel::SSL_TARGET => 'peer0.org1.example.com'
51
+ }
52
+ }
53
+
54
+ user_identity = Fabric::Gateway::Identity.new(
55
+ {
56
+ username: "admin",
57
+ affiliation: "org1.department1",
58
+ mspid: 'Org1MSP',
59
+ private_key: Fabric::Gateway.crypto_suite.key_from_pem(load_certs[1]),
60
+ pem_certificate: load_certs[2],
61
+ }
62
+ )
63
+
64
+ creds = GRPC::Core::ChannelCredentials.new(load_certs[0])
65
+ client=Gateway::Gateway::Stub.new('localhost:7051', creds, **client_opts)
66
+ proposal = Fabric::Gateway::Proposal.new(user_identity, {channel_id: 'your_channel', chaincode_id: 'basic', args: [ 'GetAllAssets' ]})
67
+
68
+ response = client.evaluate(Gateway::EvaluateRequest.new(channel_id: "your_channel", proposed_transaction: proposal.signed_proposal))
69
+
70
+ pp response
35
71
  ```
36
72
 
37
73
  ## Development
@@ -56,8 +92,9 @@ Bug reports and pull requests are welcome on GitHub at https://github.com/ethica
56
92
 
57
93
  - [x] Add license
58
94
  - [x] Add ChangeLog
59
- - [ ] Create Gem
95
+ - [x] Create Gem
60
96
  - [ ] Add usage instructions
97
+ - [ ] Abstract connection and calls such that the protos aren't being interacted directly
61
98
  - [ ] Add testing?
62
99
 
63
100
 
@@ -65,6 +102,8 @@ Bug reports and pull requests are welcome on GitHub at https://github.com/ethica
65
102
 
66
103
  The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
67
104
 
105
+ Portions of the code was utilized from https://github.com/kirshin/hyperledger-fabric-sdk.
106
+
68
107
  ## Code of Conduct
69
108
 
70
109
  Everyone interacting in the Fabric::Gateway project's codebases, issue trackers, chat rooms and mailing lists is expected to follow the [code of conduct](https://github.com/ethicalidentity/fabric-gateway/blob/master/CODE_OF_CONDUCT.md).
data/bin/regenerate CHANGED
@@ -16,3 +16,4 @@ grpc_tools_ruby_protoc -I ./fabric-protos --ruby_out=./lib --grpc_out=./lib ./fa
16
16
  grpc_tools_ruby_protoc -I ./fabric-protos --ruby_out=./lib --grpc_out=./lib ./fabric-protos/orderer/ab.proto
17
17
  grpc_tools_ruby_protoc -I ./fabric-protos --ruby_out=./lib --grpc_out=./lib ./fabric-protos/gossip/message.proto
18
18
  grpc_tools_ruby_protoc -I ./fabric-protos --ruby_out=./lib --grpc_out=./lib ./fabric-protos/msp/msp_principal.proto
19
+ grpc_tools_ruby_protoc -I ./fabric-protos --ruby_out=./lib --grpc_out=./lib ./fabric-protos/msp/identities.proto
@@ -28,4 +28,5 @@ Gem::Specification.new do |spec|
28
28
  spec.require_paths = ["lib"]
29
29
  spec.add_dependency('google-protobuf', '>= 3.19.1')
30
30
  spec.add_dependency('grpc', '~> 1.42')
31
+ spec.add_development_dependency('grpc-tools','~> 1.42')
31
32
  end
@@ -0,0 +1,13 @@
1
+ module Fabric
2
+ module Gateway
3
+ class Client
4
+ attr_accessor :identity
5
+ attr_accessor :connection
6
+
7
+ def initialize(connection, identity)
8
+ self.identity = identity
9
+ self.connection = connection
10
+ end
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,20 @@
1
+ module Fabric
2
+ module Gateway
3
+ module Constants
4
+ ## System Chaincodes
5
+ LSCC = 'lscc'.freeze
6
+ QSCC = 'qscc'.freeze
7
+ CSCC = 'cscc'.freeze
8
+
9
+ ## System Channels
10
+ SYSTEM_CHANNEL_NAME = 'testchainid'.freeze
11
+
12
+ ## System Functions
13
+ FUNC_GET_CHANNELS = 'GetChannels'.freeze
14
+ FUNC_GET_CONFIG_BLOCK = 'GetConfigBlock'.freeze
15
+
16
+ ## Variables
17
+ CHANNEL_HEADER_VERSION = 1
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,172 @@
1
+ require 'openssl'
2
+
3
+ module Fabric
4
+ module Gateway
5
+ # Elliptic-curve Crypto Suite using OpenSSL
6
+ class ECCryptoSuite
7
+ DEFAULT_KEY_SIZE = 256
8
+ DEFAULT_DIGEST_ALGORITHM = 'SHA256'.freeze
9
+ DEFAULT_AES_KEY_SIZE = 128
10
+
11
+ EC_CURVES = { 256 => 'prime256v1', 384 => 'secp384r1' }.freeze
12
+
13
+ CIPHER = 'aes-256-cbc'.freeze
14
+
15
+ attr_reader :key_size, :digest_algorithm, :digest, :curve, :cipher
16
+
17
+ def initialize(opts = {})
18
+ @key_size = opts[:key_size] || DEFAULT_KEY_SIZE
19
+ @digest_algorithm = opts[:digest_algorithm] || DEFAULT_DIGEST_ALGORITHM
20
+ @digest = OpenSSL::Digest.new digest_algorithm
21
+ @curve = EC_CURVES[key_size]
22
+ @cipher = opts[:cipher] || CIPHER
23
+ end
24
+
25
+ def sign(private_key, message)
26
+ digest = digest message
27
+ key = pkey_from_private_key private_key
28
+ signature = key.dsa_sign_asn1 digest
29
+ sequence = OpenSSL::ASN1.decode signature
30
+ sequence = prevent_malleability sequence, key.group.order
31
+
32
+ sequence.to_der
33
+ end
34
+
35
+ def generate_private_key
36
+ key = OpenSSL::PKey::EC.new curve
37
+ key.generate_key!
38
+
39
+ key.private_key.to_s(16).downcase
40
+ end
41
+
42
+ def generate_csr(private_key, attrs = [])
43
+ key = pkey_from_private_key private_key
44
+
45
+ req = OpenSSL::X509::Request.new
46
+ req.public_key = key
47
+ req.subject = OpenSSL::X509::Name.new attrs
48
+ req.sign key, @digest
49
+
50
+ req
51
+ end
52
+
53
+ def generate_nonce(length = 24)
54
+ OpenSSL::Random.random_bytes length
55
+ end
56
+
57
+ def hexdigest(message)
58
+ @digest.hexdigest message
59
+ end
60
+
61
+ def digest(message)
62
+ @digest.digest message
63
+ end
64
+
65
+ def encode_hex(bytes)
66
+ bytes.unpack('H*').first
67
+ end
68
+
69
+ def decode_hex(string)
70
+ [string].pack('H*')
71
+ end
72
+
73
+ def keccak256(bytes)
74
+ OpenSSL::Digest.new('SHA3-256').digest bytes
75
+ end
76
+
77
+
78
+ def restore_public_key(private_key)
79
+ private_bn = OpenSSL::BN.new private_key, 16
80
+ group = OpenSSL::PKey::EC::Group.new curve
81
+ public_bn = group.generator.mul(private_bn).to_bn
82
+ public_bn = OpenSSL::PKey::EC::Point.new(group, public_bn).to_bn
83
+
84
+ public_bn.to_s(16).downcase
85
+ end
86
+
87
+ def address_from_public_key(public_key)
88
+ bytes = decode_hex public_key
89
+ address_bytes = keccak256(bytes[1..-1])[-20..-1]
90
+
91
+ encode_hex address_bytes
92
+ end
93
+
94
+ def build_shared_key(private_key, public_key)
95
+ pkey = pkey_from_private_key private_key
96
+ public_bn = OpenSSL::BN.new public_key, 16
97
+ group = OpenSSL::PKey::EC::Group.new curve
98
+ public_point = OpenSSL::PKey::EC::Point.new group, public_bn
99
+
100
+ encode_hex pkey.dh_compute_key(public_point)
101
+ end
102
+
103
+ def encrypt(secret, data)
104
+ aes = OpenSSL::Cipher.new cipher
105
+ aes.encrypt
106
+ aes.key = decode_hex(secret)
107
+ iv = aes.random_iv
108
+ aes.iv = iv
109
+
110
+ Base64.strict_encode64(iv + aes.update(data) + aes.final)
111
+ end
112
+
113
+ def decrypt(secret, data)
114
+ return unless data
115
+
116
+ encrypted_data = Base64.strict_decode64 data
117
+ aes = OpenSSL::Cipher.new cipher
118
+ aes.decrypt
119
+ aes.key = decode_hex(secret)
120
+ aes.iv = encrypted_data[0..15]
121
+ encrypted_data = encrypted_data[16..-1]
122
+
123
+ aes.update(encrypted_data) + aes.final
124
+ end
125
+
126
+ def pkey_pem_from_private_key(private_key)
127
+ public_key = restore_public_key private_key
128
+ key = OpenSSL::PKey::EC.new curve
129
+ key.private_key = OpenSSL::BN.new private_key, 16
130
+ key.public_key = OpenSSL::PKey::EC::Point.new key.group,
131
+ OpenSSL::BN.new(public_key, 16)
132
+
133
+ pkey = OpenSSL::PKey::EC.new(key.public_key.group)
134
+ pkey.public_key = key.public_key
135
+
136
+ pkey.to_pem
137
+ end
138
+
139
+ def key_from_pem(pem)
140
+ key = OpenSSL::PKey::EC.new(pem)
141
+ key.private_key.to_s(16)
142
+ end
143
+
144
+ def pkey_from_x509_certificate(certificate)
145
+ cert = OpenSSL::X509::Certificate.new(certificate)
146
+ cert.public_key.public_key.to_bn.to_s(16)
147
+ end
148
+
149
+ private
150
+
151
+ def pkey_from_private_key(private_key)
152
+ public_key = restore_public_key private_key
153
+ key = OpenSSL::PKey::EC.new curve
154
+ key.private_key = OpenSSL::BN.new private_key, 16
155
+ key.public_key = OpenSSL::PKey::EC::Point.new key.group,
156
+ OpenSSL::BN.new(public_key, 16)
157
+
158
+ key
159
+ end
160
+
161
+ def prevent_malleability(sequence, order)
162
+ half_order = order >> 1
163
+
164
+ if (half_key = sequence.value[1].value) > half_order
165
+ sequence.value[1].value = order - half_key
166
+ end
167
+
168
+ sequence
169
+ end
170
+ end
171
+ end
172
+ end
@@ -0,0 +1,47 @@
1
+ require 'msp/identities_pb'
2
+ require 'base64'
3
+
4
+ module Fabric
5
+ module Gateway
6
+ class Identity
7
+ attr_reader :private_key,
8
+ :public_key,
9
+ :address,
10
+ :crypto_suite
11
+
12
+ attr_accessor :pem_certificate, :certificate, :mspid
13
+
14
+ def initialize(opts = {})
15
+ @crypto_suite = opts[:crypto_suite] || Fabric::Gateway.crypto_suite
16
+
17
+ @private_key = opts[:private_key] || @crypto_suite.generate_private_key
18
+ @public_key = opts[:public_key] || @crypto_suite.restore_public_key(private_key)
19
+ @certificate = opts[:certificate]
20
+ @pem_certificate = opts[:pem_certificate]
21
+ @mspid = opts[:mspid]
22
+
23
+ @address = @crypto_suite.address_from_public_key public_key
24
+ end
25
+
26
+ def generate_csr(attrs = [])
27
+ @crypto_suite.generate_csr private_key, attrs
28
+ end
29
+
30
+ def sign(message)
31
+ @crypto_suite.sign(private_key, message)
32
+ end
33
+
34
+ def shared_secret_by(public_key)
35
+ @crypto_suite.build_shared_key private_key, public_key
36
+ end
37
+
38
+ def decoded_certificate
39
+ Base64.strict_decode64 certificate
40
+ end
41
+
42
+ def serialize
43
+ Msp::SerializedIdentity.new(mspid: mspid, id_bytes: pem_certificate).to_proto
44
+ end
45
+ end
46
+ end
47
+ end
@@ -0,0 +1,105 @@
1
+ module Fabric
2
+ module Gateway
3
+ class Proposal
4
+ attr_reader :identity, :request
5
+
6
+ def initialize(identity, request = {})
7
+ @identity = identity
8
+ @request = request
9
+
10
+ assign_tx request[:transaction_info] if request[:transaction_info]
11
+ end
12
+
13
+ def crypto_suite
14
+ identity.crypto_suite
15
+ end
16
+
17
+ def nonce
18
+ @nonce ||= crypto_suite.generate_nonce
19
+ end
20
+
21
+ def channel_id
22
+ request[:channel_id]
23
+ end
24
+
25
+ def chaincode_id
26
+ request[:chaincode_id]
27
+ end
28
+
29
+ def args
30
+ request[:args].compact.map &:to_s
31
+ end
32
+
33
+ def transient
34
+ request[:transient] || {}
35
+ end
36
+
37
+ def transaction_id
38
+ request[:transaction_id]
39
+ end
40
+
41
+ def tx_id
42
+ @tx_id ||= crypto_suite.hexdigest(nonce + identity.serialize)
43
+ end
44
+
45
+ def proposal
46
+ @proposal ||= Protos::Proposal.new header: header.to_proto,
47
+ payload: chaincode_proposal.to_proto
48
+ end
49
+
50
+ def signed_proposal
51
+ proposal_bytes = proposal.to_proto
52
+ signature = identity.sign proposal_bytes
53
+
54
+ Protos::SignedProposal.new proposal_bytes: proposal_bytes, signature: signature
55
+ end
56
+
57
+ def header
58
+ Common::Header.new channel_header: channel_header.to_proto,
59
+ signature_header: signature_header.to_proto
60
+ end
61
+
62
+ def channel_header
63
+ Common::ChannelHeader.new type: Common::HeaderType::ENDORSER_TRANSACTION,
64
+ channel_id: channel_id, tx_id: tx_id,
65
+ extension: channel_header_extension.to_proto,
66
+ timestamp: tx_timestamp,
67
+ version: Constants::CHANNEL_HEADER_VERSION
68
+ end
69
+
70
+ def channel_header_extension
71
+ id = Protos::ChaincodeID.new name: chaincode_id
72
+
73
+ Protos::ChaincodeHeaderExtension.new chaincode_id: id
74
+ end
75
+
76
+ def tx_timestamp
77
+ now = Time.now
78
+
79
+ @tx_timestamp ||= Google::Protobuf::Timestamp.new seconds: now.to_i, nanos: now.nsec
80
+ end
81
+
82
+ def signature_header
83
+ Common::SignatureHeader.new creator: identity.serialize, nonce: nonce
84
+ end
85
+
86
+ def chaincode_proposal
87
+ id = Protos::ChaincodeID.new name: chaincode_id
88
+ chaincode_input = Protos::ChaincodeInput.new args: args
89
+ chaincode_spec = Protos::ChaincodeSpec.new type: Protos::ChaincodeSpec::Type::NODE,
90
+ chaincode_id: id,
91
+ input: chaincode_input
92
+ input = Protos::ChaincodeInvocationSpec.new chaincode_spec: chaincode_spec
93
+
94
+ Protos::ChaincodeProposalPayload.new input: input.to_proto, TransientMap: transient
95
+ end
96
+
97
+ private
98
+
99
+ def assign_tx(transaction_info)
100
+ @tx_id = transaction_info[:tx_id]
101
+ @nonce = crypto_suite.decode_hex transaction_info[:nonce_hex]
102
+ end
103
+ end
104
+ end
105
+ end
@@ -1,5 +1,5 @@
1
1
  module Fabric
2
2
  module Gateway
3
- VERSION = "0.0.2"
3
+ VERSION = "0.1.0"
4
4
  end
5
5
  end
@@ -1,10 +1,21 @@
1
+ require "fabric/gateway/client"
2
+ require "fabric/gateway/constants"
3
+ require 'fabric/gateway/ec_crypto_suite'
4
+ require 'fabric/gateway/identity'
5
+ require "fabric/gateway/proposal"
1
6
  require "fabric/gateway/version"
7
+
8
+
2
9
  require "gateway/gateway_pb"
3
10
  require "gateway/gateway_services_pb"
4
11
 
5
12
  module Fabric
6
13
  module Gateway
7
14
  class Error < StandardError; end
8
- # Your code goes here...
15
+
16
+
17
+ def self.crypto_suite(opts = {})
18
+ @crypto_suite ||= Fabric::Gateway::ECCryptoSuite.new opts
19
+ end
9
20
  end
10
21
  end
@@ -0,0 +1,25 @@
1
+ # Generated by the protocol buffer compiler. DO NOT EDIT!
2
+ # source: msp/identities.proto
3
+
4
+ require 'google/protobuf'
5
+
6
+ Google::Protobuf::DescriptorPool.generated_pool.build do
7
+ add_file("msp/identities.proto", :syntax => :proto3) do
8
+ add_message "msp.SerializedIdentity" do
9
+ optional :mspid, :string, 1
10
+ optional :id_bytes, :bytes, 2
11
+ end
12
+ add_message "msp.SerializedIdemixIdentity" do
13
+ optional :nym_x, :bytes, 1
14
+ optional :nym_y, :bytes, 2
15
+ optional :ou, :bytes, 3
16
+ optional :role, :bytes, 4
17
+ optional :proof, :bytes, 5
18
+ end
19
+ end
20
+ end
21
+
22
+ module Msp
23
+ SerializedIdentity = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("msp.SerializedIdentity").msgclass
24
+ SerializedIdemixIdentity = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("msp.SerializedIdemixIdentity").msgclass
25
+ end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: fabric-gateway
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.2
4
+ version: 0.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jonathan Chan
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2021-12-15 00:00:00.000000000 Z
11
+ date: 2021-12-17 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: google-protobuf
@@ -38,6 +38,20 @@ dependencies:
38
38
  - - "~>"
39
39
  - !ruby/object:Gem::Version
40
40
  version: '1.42'
41
+ - !ruby/object:Gem::Dependency
42
+ name: grpc-tools
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '1.42'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '1.42'
41
55
  description: 'Hyperledger Fabric Gateway gRPC SDK generated directly from protos found
42
56
  at: https://github.com/hyperledger/fabric-protos.'
43
57
  email:
@@ -67,11 +81,17 @@ files:
67
81
  - lib/common/policies_pb.rb
68
82
  - lib/fabric/.DS_Store
69
83
  - lib/fabric/gateway.rb
84
+ - lib/fabric/gateway/client.rb
85
+ - lib/fabric/gateway/constants.rb
86
+ - lib/fabric/gateway/ec_crypto_suite.rb
87
+ - lib/fabric/gateway/identity.rb
88
+ - lib/fabric/gateway/proposal.rb
70
89
  - lib/fabric/gateway/version.rb
71
90
  - lib/gateway/gateway_pb.rb
72
91
  - lib/gateway/gateway_services_pb.rb
73
92
  - lib/gossip/message_pb.rb
74
93
  - lib/gossip/message_services_pb.rb
94
+ - lib/msp/identities_pb.rb
75
95
  - lib/msp/msp_principal_pb.rb
76
96
  - lib/orderer/ab_pb.rb
77
97
  - lib/orderer/ab_services_pb.rb
@@ -103,7 +123,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
103
123
  - !ruby/object:Gem::Version
104
124
  version: '0'
105
125
  requirements: []
106
- rubygems_version: 3.0.3
126
+ rubygems_version: 3.1.6
107
127
  signing_key:
108
128
  specification_version: 4
109
129
  summary: Hyperledger Fabric Gateway gRPC SDK