silkey-sdk 0.0.1

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.
Files changed (89) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +14 -0
  3. data/.rubocop.yml +59 -0
  4. data/.ruby-version +1 -0
  5. data/CHANGELOG.md +9 -0
  6. data/DEVELOPMENT.md +83 -0
  7. data/Gemfile +13 -0
  8. data/Gemfile.lock +128 -0
  9. data/LICENSE.txt +21 -0
  10. data/README.md +46 -0
  11. data/Rakefile +2 -0
  12. data/bin/console +14 -0
  13. data/bin/setup +8 -0
  14. data/doc/CHANGELOG_md.html +112 -0
  15. data/doc/LICENSE_txt.html +99 -0
  16. data/doc/Object.html +117 -0
  17. data/doc/README_md.html +144 -0
  18. data/doc/Silkey.html +269 -0
  19. data/doc/Silkey/ClientFactory.html +106 -0
  20. data/doc/Silkey/Configuration.html +217 -0
  21. data/doc/Silkey/Contract.html +106 -0
  22. data/doc/Silkey/Contract/FrozenArray.html +106 -0
  23. data/doc/Silkey/ContractFactory.html +106 -0
  24. data/doc/Silkey/LoggerService.html +106 -0
  25. data/doc/Silkey/Models.html +99 -0
  26. data/doc/Silkey/Models/JwtPayload.html +622 -0
  27. data/doc/Silkey/RegistryContract.html +106 -0
  28. data/doc/Silkey/SDK.html +356 -0
  29. data/doc/Silkey/Utils.html +709 -0
  30. data/doc/created.rid +23 -0
  31. data/doc/css/fonts.css +167 -0
  32. data/doc/css/rdoc.css +619 -0
  33. data/doc/fonts/Lato-Light.ttf +0 -0
  34. data/doc/fonts/Lato-LightItalic.ttf +0 -0
  35. data/doc/fonts/Lato-Regular.ttf +0 -0
  36. data/doc/fonts/Lato-RegularItalic.ttf +0 -0
  37. data/doc/fonts/SourceCodePro-Bold.ttf +0 -0
  38. data/doc/fonts/SourceCodePro-Regular.ttf +0 -0
  39. data/doc/images/add.png +0 -0
  40. data/doc/images/arrow_up.png +0 -0
  41. data/doc/images/brick.png +0 -0
  42. data/doc/images/brick_link.png +0 -0
  43. data/doc/images/bug.png +0 -0
  44. data/doc/images/bullet_black.png +0 -0
  45. data/doc/images/bullet_toggle_minus.png +0 -0
  46. data/doc/images/bullet_toggle_plus.png +0 -0
  47. data/doc/images/date.png +0 -0
  48. data/doc/images/delete.png +0 -0
  49. data/doc/images/find.png +0 -0
  50. data/doc/images/loadingAnimation.gif +0 -0
  51. data/doc/images/macFFBgHack.png +0 -0
  52. data/doc/images/package.png +0 -0
  53. data/doc/images/page_green.png +0 -0
  54. data/doc/images/page_white_text.png +0 -0
  55. data/doc/images/page_white_width.png +0 -0
  56. data/doc/images/plugin.png +0 -0
  57. data/doc/images/ruby.png +0 -0
  58. data/doc/images/tag_blue.png +0 -0
  59. data/doc/images/tag_green.png +0 -0
  60. data/doc/images/transparent.png +0 -0
  61. data/doc/images/wrench.png +0 -0
  62. data/doc/images/wrench_orange.png +0 -0
  63. data/doc/images/zoom.png +0 -0
  64. data/doc/index.html +112 -0
  65. data/doc/js/darkfish.js +84 -0
  66. data/doc/js/navigation.js +105 -0
  67. data/doc/js/navigation.js.gz +0 -0
  68. data/doc/js/search.js +110 -0
  69. data/doc/js/search_index.js +1 -0
  70. data/doc/js/search_index.js.gz +0 -0
  71. data/doc/js/searcher.js +229 -0
  72. data/doc/js/searcher.js.gz +0 -0
  73. data/doc/table_of_contents.html +318 -0
  74. data/lib/silkey-sdk.rb +23 -0
  75. data/lib/silkey.rb +22 -0
  76. data/lib/silkey/abi/registry_contract_abi.json +129 -0
  77. data/lib/silkey/configuration.rb +24 -0
  78. data/lib/silkey/contract.rb +38 -0
  79. data/lib/silkey/factories/client_factory.rb +30 -0
  80. data/lib/silkey/factories/contract_factory.rb +47 -0
  81. data/lib/silkey/models/jwt_payload.rb +157 -0
  82. data/lib/silkey/registry_contract/registry_contract.rb +33 -0
  83. data/lib/silkey/sdk.rb +207 -0
  84. data/lib/silkey/services/logger_service.rb +19 -0
  85. data/lib/silkey/utils.rb +107 -0
  86. data/lib/silkey/version.rb +5 -0
  87. data/lib/silkey_sdk.rb +3 -0
  88. data/silkey-sdk.gemspec +48 -0
  89. metadata +332 -0
@@ -0,0 +1,23 @@
1
+ require 'eth'
2
+ require 'ethereum.rb'
3
+ # require 'json'
4
+ require 'jwt'
5
+ require 'logger'
6
+ require 'pry'
7
+ #require 'active_support'
8
+ #require 'active_support/core_ext/module'
9
+ require 'virtus_convert'
10
+ require 'virtus'
11
+ # require 'retriable'
12
+ require 'silkey'
13
+
14
+ require_relative 'silkey/contract'
15
+ require_relative 'silkey/configuration'
16
+ require_relative 'silkey/factories/client_factory'
17
+ require_relative 'silkey/factories/contract_factory'
18
+ require_relative 'silkey/models/jwt_payload'
19
+ require_relative 'silkey/services/logger_service'
20
+ require_relative 'silkey/sdk'
21
+ require_relative 'silkey/utils'
22
+
23
+ require_relative 'silkey/registry_contract/registry_contract'
@@ -0,0 +1,22 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'silkey/version'
4
+ require 'active_support/all'
5
+
6
+ module Silkey
7
+ def self.root_path
8
+ File.dirname __dir__
9
+ end
10
+
11
+ def self.bin_path
12
+ File.join root_path, 'bin'
13
+ end
14
+
15
+ def self.lib_path
16
+ File.join root_path, 'lib'
17
+ end
18
+
19
+ def self.abi_path
20
+ File.join root_path, 'lib/silkey/abi'
21
+ end
22
+ end
@@ -0,0 +1,129 @@
1
+ [
2
+ {
3
+ "anonymous": false,
4
+ "inputs": [
5
+ {
6
+ "indexed": true,
7
+ "internalType": "address",
8
+ "name": "previousOwner",
9
+ "type": "address"
10
+ },
11
+ {
12
+ "indexed": true,
13
+ "internalType": "address",
14
+ "name": "newOwner",
15
+ "type": "address"
16
+ }
17
+ ],
18
+ "name": "OwnershipTransferred",
19
+ "type": "event"
20
+ },
21
+ {
22
+ "inputs": [
23
+ {
24
+ "internalType": "bytes32",
25
+ "name": "name",
26
+ "type": "bytes32"
27
+ }
28
+ ],
29
+ "name": "getAddress",
30
+ "outputs": [
31
+ {
32
+ "internalType": "address",
33
+ "name": "",
34
+ "type": "address"
35
+ }
36
+ ],
37
+ "stateMutability": "view",
38
+ "type": "function"
39
+ },
40
+ {
41
+ "inputs": [
42
+ {
43
+ "internalType": "bytes32[]",
44
+ "name": "names",
45
+ "type": "bytes32[]"
46
+ },
47
+ {
48
+ "internalType": "address[]",
49
+ "name": "destinations",
50
+ "type": "address[]"
51
+ }
52
+ ],
53
+ "name": "importAddresses",
54
+ "outputs": [],
55
+ "stateMutability": "nonpayable",
56
+ "type": "function"
57
+ },
58
+ {
59
+ "inputs": [],
60
+ "name": "owner",
61
+ "outputs": [
62
+ {
63
+ "internalType": "address",
64
+ "name": "",
65
+ "type": "address"
66
+ }
67
+ ],
68
+ "stateMutability": "view",
69
+ "type": "function"
70
+ },
71
+ {
72
+ "inputs": [],
73
+ "name": "renounceOwnership",
74
+ "outputs": [],
75
+ "stateMutability": "nonpayable",
76
+ "type": "function"
77
+ },
78
+ {
79
+ "inputs": [
80
+ {
81
+ "internalType": "bytes32",
82
+ "name": "",
83
+ "type": "bytes32"
84
+ }
85
+ ],
86
+ "name": "repository",
87
+ "outputs": [
88
+ {
89
+ "internalType": "address",
90
+ "name": "",
91
+ "type": "address"
92
+ }
93
+ ],
94
+ "stateMutability": "view",
95
+ "type": "function"
96
+ },
97
+ {
98
+ "inputs": [
99
+ {
100
+ "internalType": "bytes32",
101
+ "name": "name",
102
+ "type": "bytes32"
103
+ }
104
+ ],
105
+ "name": "requireAndGetAddress",
106
+ "outputs": [
107
+ {
108
+ "internalType": "address",
109
+ "name": "",
110
+ "type": "address"
111
+ }
112
+ ],
113
+ "stateMutability": "view",
114
+ "type": "function"
115
+ },
116
+ {
117
+ "inputs": [
118
+ {
119
+ "internalType": "address",
120
+ "name": "newOwner",
121
+ "type": "address"
122
+ }
123
+ ],
124
+ "name": "transferOwnership",
125
+ "outputs": [],
126
+ "stateMutability": "nonpayable",
127
+ "type": "function"
128
+ }
129
+ ]
@@ -0,0 +1,24 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Silkey
4
+ class Configuration
5
+ class << self
6
+ attr_accessor :client_url
7
+ attr_accessor :registry_contract_abi
8
+ attr_accessor :registry_contract_address
9
+ attr_accessor :enable_logs
10
+
11
+ def setup
12
+ yield self
13
+ end
14
+ end
15
+
16
+ self.client_url = 'http://localhost:8545'
17
+ self.enable_logs = false
18
+
19
+ self.registry_contract_abi =
20
+ File.read(File.expand_path('./registry_contract_abi.json', Silkey.abi_path))
21
+
22
+ self.registry_contract_address = ''
23
+ end
24
+ end
@@ -0,0 +1,38 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Silkey # :nodoc: all
4
+ class Contract < SimpleDelegator
5
+ def initialize(contract, client)
6
+ super(contract)
7
+ @contract = contract
8
+ @client = client
9
+ _, @functions, = Ethereum::Abi.parse_abi(contract.abi)
10
+ end
11
+
12
+ def call_func_for_block(func_name, default_block = 'latest', *args)
13
+ fun = @functions.find { |f| f.name == func_name.to_s }
14
+
15
+ raise 'FunctionNotFoundError', func_name unless fun
16
+
17
+ raw_result = @client.send_command('eth_call',
18
+ FrozenArray.new(@contract.call_args(fun, args),
19
+ default_block))['result']
20
+
21
+ output = Ethereum::Decoder.new.decode_arguments(fun.outputs, raw_result)
22
+
23
+ return output[0] if output.length == 1
24
+
25
+ output
26
+ end
27
+
28
+ class FrozenArray < Array
29
+ def initialize(*args)
30
+ super(args)
31
+ end
32
+
33
+ def <<(_)
34
+ self
35
+ end
36
+ end
37
+ end
38
+ end
@@ -0,0 +1,30 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Silkey # :nodoc: all
4
+ class ClientFactory
5
+ def self.call(params = {})
6
+ new(params).call
7
+ end
8
+
9
+ def initialize(params)
10
+ @client_url = params.fetch(:client_url, Configuration.client_url)
11
+ @log = params.fetch(:enable_logs, Configuration.enable_logs)
12
+ end
13
+
14
+ def call
15
+ @client = new_client
16
+
17
+ client
18
+ end
19
+
20
+ private
21
+
22
+ attr_reader :client,
23
+ :log,
24
+ :client_url
25
+
26
+ def new_client
27
+ Ethereum::HttpClient.new(client_url, nil, log)
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,47 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Silkey # :nodoc: all
4
+ class ContractFactory
5
+ def self.call(params)
6
+ new(params).call
7
+ end
8
+
9
+ def initialize(params = {})
10
+ @abi =
11
+ params.fetch(:abi)
12
+ @address =
13
+ params.fetch(:address)
14
+ @client_url =
15
+ params.fetch(:client_url, Configuration.client_url)
16
+ @name =
17
+ params.fetch(:name)
18
+ end
19
+
20
+ def call
21
+ @contract = create_contract
22
+
23
+ contract
24
+ end
25
+
26
+ private
27
+
28
+ attr_reader :abi,
29
+ :address,
30
+ :contract,
31
+ :client_url,
32
+ :name
33
+
34
+ def client
35
+ ClientFactory.call(client_url: client_url)
36
+ end
37
+
38
+ def create_contract
39
+ Silkey::Contract.new(Ethereum::Contract.create(
40
+ name: name,
41
+ address: address,
42
+ abi: abi,
43
+ client: client
44
+ ), client)
45
+ end
46
+ end
47
+ end
@@ -0,0 +1,157 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Silkey
4
+ module Models
5
+ class JwtPayload
6
+ include Virtus.model
7
+
8
+ SCOPE_DIVIDER = ','
9
+
10
+ # rubocop:disable Style/HashSyntax
11
+ attribute :address, String, :writer => :private
12
+ attribute :email, String, :writer => :private
13
+ attribute :silkey_signature, String, :writer => :private
14
+ attribute :silkey_signature_timestamp, Integer
15
+ attribute :user_signature, String, :writer => :private
16
+ attribute :user_signature_timestamp, Integer
17
+ attribute :ref_id, String, :writer => :private
18
+ attribute :_scope, {}, :writer => :private, :reader => :private
19
+ # rubocop:enable Style/HashSyntax
20
+
21
+ def scope
22
+ _scope.keys.sort.join(SCOPE_DIVIDER)
23
+ end
24
+
25
+ def scope_divider
26
+ SCOPE_DIVIDER
27
+ end
28
+
29
+ # rubocop:disable Naming/AccessorMethodName
30
+ def set_scope(scope)
31
+ return self if Silkey::Utils.empty?(scope)
32
+
33
+ _scope[scope] = true
34
+ self
35
+ end
36
+
37
+ def set_address(addr)
38
+ raise "`#{addr}` is not ethereum address" unless Silkey::Utils.ethereum_address?(addr)
39
+
40
+ self.address = addr
41
+ self
42
+ end
43
+
44
+ def set_email(email)
45
+ self.email = email
46
+ self
47
+ end
48
+
49
+ def set_ref_id(ref_id)
50
+ self.ref_id = ref_id
51
+ self
52
+ end
53
+
54
+ def set_user_signature(sig, timestamp)
55
+ raise "user signature invalid: `#{sig}`" unless Silkey::Utils.signature?(sig)
56
+ raise 'empty user signature timestamp' if Silkey::Utils.empty?(timestamp)
57
+
58
+ self.user_signature = sig
59
+ self.user_signature_timestamp = timestamp
60
+ self
61
+ end
62
+
63
+ def set_silkey_signature(sig, timestamp)
64
+ raise "silkey signature invalid: `#{sig}`" unless Silkey::Utils.signature?(sig)
65
+ raise 'empty silkey signature timestamp' if Silkey::Utils.empty?(timestamp)
66
+
67
+ self.silkey_signature = sig
68
+ self.silkey_signature_timestamp = timestamp
69
+ self
70
+ end
71
+
72
+ # rubocop:enable Naming/AccessorMethodName
73
+
74
+ ##
75
+ # Creates message that's need to be sign by user
76
+ def message_to_sign_by_user
77
+ if !Silkey::Utils.empty?(address) && Silkey::Utils.empty?(user_signature_timestamp)
78
+ self.user_signature_timestamp = Silkey::Utils.current_timestamp
79
+ end
80
+
81
+ str1_hex = 'address'.unpack('H*')[0]
82
+ adr_hex = Silkey::Utils.remove0x(address).downcase
83
+
84
+ str2_hex = [
85
+ 'refId', ref_id.to_s,
86
+ 'scope', scope,
87
+ 'userSignatureTimestamp'
88
+ ].map { |str| str.to_s.unpack('H*') }.join('')
89
+
90
+ str_hex = "#{str1_hex}#{adr_hex}#{str2_hex}"
91
+
92
+ return str_hex if Silkey::Utils.empty?(user_signature_timestamp)
93
+
94
+ "#{str_hex}#{Silkey::Utils.int_to_hex(user_signature_timestamp.to_s)}"
95
+ end
96
+
97
+ def message_to_sign_by_silkey
98
+ return '' if Silkey::Utils.empty?(email)
99
+
100
+ if Silkey::Utils.empty?(silkey_signature_timestamp)
101
+ self.silkey_signature_timestamp = Silkey::Utils.current_timestamp
102
+ end
103
+
104
+ str_hex = [
105
+ 'email', email,
106
+ 'silkeySignatureTimestamp'
107
+ ].map { |str| str.to_s.unpack('H*') }.join('')
108
+
109
+ "#{str_hex}#{Silkey::Utils.int_to_hex(silkey_signature_timestamp.to_s)}"
110
+ end
111
+
112
+ def validate
113
+ raise "address is invalid: #{address}" unless Silkey::Utils.ethereum_address?(address)
114
+
115
+ unless Silkey::Utils.signature?(user_signature)
116
+ raise "user_signature is invalid: #{user_signature}"
117
+ end
118
+
119
+ raise 'user_signature_timestamp is empty' if Silkey::Utils.empty?(user_signature_timestamp)
120
+
121
+ return self if Silkey::Utils.empty?(scope) || scope == 'id'
122
+
123
+ validate_scope_email
124
+ end
125
+
126
+ def import(hash)
127
+ hash.each do |k, v|
128
+ var = k.to_s.underscore
129
+
130
+ if k == 'scope'
131
+ set_scope(v)
132
+ else
133
+ self.instance_variable_set("@#{var}", v)
134
+ end
135
+ end
136
+
137
+ self
138
+ end
139
+
140
+ private
141
+
142
+ def validate_scope_email
143
+ raise 'email is empty' if Silkey::Utils.empty?(email)
144
+
145
+ unless Silkey::Utils.signature?(silkey_signature)
146
+ raise "silkey_signature is invalid: #{silkey_signature}"
147
+ end
148
+
149
+ if Silkey::Utils.empty?(silkey_signature_timestamp)
150
+ raise 'silkey_signature_timestamp is empty'
151
+ end
152
+
153
+ self
154
+ end
155
+ end
156
+ end
157
+ end