near_api 0.1.0 → 0.1.1

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: 4d9a8146bb7d005f8f833531892e9ba17f44545dd30da6b15d86f2343cc1f9d5
4
- data.tar.gz: d7e51a87f8f3a9c36fa45c85327985c0fd56cc6c1df32dab18cac84dad3f9ded
3
+ metadata.gz: f3329e91efbd5b305744e92c0edd739a7fbdada5a40f412bc75594ea04d463d1
4
+ data.tar.gz: 5e3543eda45e4d65ae1014beb90152708ed697df3c5896aa4d2aa49b22004d83
5
5
  SHA512:
6
- metadata.gz: 7f6030857da43b0b2b039d6f2f82155a57d5743e0287e376ce7d30181812f885b925282429c2afe3595dca6505e89f97128790dc4a974263a2b65c1f14f2b297
7
- data.tar.gz: f0b7b6d68bd0038ccc90635f935d804fcb19de534a00dc9275e9aa920c2e7516a7f89d02af2f6b15f75454b83b3c8cfaeade9edb0dc500f5e61f77dda2f9e10b
6
+ metadata.gz: 2eb64ba5ecb1cfaacb14ded64a31d2605dc8fa14cd7d8fd7388840e5227a99732a6bb8edf6e83f759c3ee3eb1e39b722565d6f34bbd0353c54b5ce2eb9fa7d95
7
+ data.tar.gz: dcca8c7e39e47f4b111f22371fc384fd194625bfae3c333a69039ad9bb56ae9f3cb9d7119e3ff4771af61e1db387b76476ed7c427b6d88600067ccf6fc350d12
data/Gemfile CHANGED
@@ -6,5 +6,3 @@ source "https://rubygems.org"
6
6
  gemspec
7
7
 
8
8
  gem "rake", "~> 13.0"
9
-
10
- gem "rspec", "~> 3.0"
@@ -0,0 +1,26 @@
1
+ # frozen_string_literal: true
2
+
3
+ class NearApi::Action::FunctionCall
4
+ include Borsh
5
+
6
+ borsh action_code: :u8,
7
+ method_name: :string,
8
+ args: :string,
9
+ gas: :u64,
10
+ amount: :u128
11
+
12
+ def initialize(method_name, args, gas: 100000000000000, amount: 0)
13
+ @method_name = method_name
14
+ @args = args
15
+ @gas = gas
16
+ @amount = amount
17
+ end
18
+
19
+ private
20
+
21
+ attr_reader :method_name, :args, :gas, :amount
22
+
23
+ def action_code
24
+ 2
25
+ end
26
+ end
@@ -0,0 +1,65 @@
1
+ # frozen_string_literal: true
2
+
3
+ class NearApi::Action
4
+ include Borsh
5
+
6
+ borsh signer_id: :string,
7
+ key_pair: { key_type: :u8, public_key: 32 },
8
+ nonce: :u64,
9
+ receiver_id: :string,
10
+ block_hash: 32,
11
+ actions: [:borsh]
12
+
13
+ def self.call(*args)
14
+ new(*args).call
15
+ end
16
+
17
+ def self.async(*args)
18
+ new(*args).async
19
+ end
20
+
21
+ def initialize(receiver_id, actions, config: NearApi.config)
22
+ @receiver_id = receiver_id
23
+ @actions = Array[actions]
24
+ @config = config
25
+ @api = NearApi::Api.new(config)
26
+ end
27
+
28
+ def call
29
+ call_api('broadcast_tx_commit')
30
+ end
31
+
32
+ def async
33
+ call_api('broadcast_tx_commit')
34
+ end
35
+
36
+ private
37
+
38
+
39
+ def call_api(method)
40
+ msg = to_borsh
41
+ digest = Digest::SHA256.digest(msg)
42
+ signature = key_pair.sign(digest)
43
+
44
+ signed_transaction = msg + Borsh::Integer.new(key_pair.key_type, :u8).to_borsh + signature
45
+ api.json_rpc(method, [Base64.strict_encode64(signed_transaction)])
46
+ end
47
+
48
+ def signer_id
49
+ config.signer_id
50
+ end
51
+
52
+ def key_pair
53
+ config.key_pair
54
+ end
55
+
56
+ def nonce
57
+ api.nonce + 1
58
+ end
59
+
60
+ def block_hash
61
+ api.block_hash
62
+ end
63
+
64
+ attr_reader :receiver_id, :actions, :config, :api
65
+ end
@@ -0,0 +1,58 @@
1
+ # frozen_string_literal: true
2
+
3
+ class NearApi::Api
4
+ def initialize(config = Config.new)
5
+ @config = config
6
+ end
7
+
8
+ def call(method, payload)
9
+ json_rpc(method, payload)
10
+ end
11
+
12
+ def status
13
+ uri = URI("#{config.node_url}/status")
14
+ JSON.parse(Net::HTTP.get(uri))
15
+ end
16
+
17
+ def view_access_key
18
+ call(
19
+ 'query',
20
+ {
21
+ "request_type": "view_access_key",
22
+ "account_id": config.signer_id,
23
+ "public_key": NearApi::Base58.encode(config.key_pair.public_key),
24
+ "finality": 'optimistic'
25
+ }
26
+ )
27
+ end
28
+
29
+ def nonce
30
+ view_access_key['result']['nonce']
31
+ end
32
+
33
+ def block_hash
34
+ NearApi::Base58.decode(status['sync_info']['latest_block_hash'])
35
+ end
36
+
37
+ def json_rpc(method, payload)
38
+ json_rpc_payload = {
39
+ id: 'dontcare',
40
+ jsonrpc: "2.0",
41
+ method: method,
42
+ params: payload
43
+ }
44
+
45
+ uri = URI.parse(config.node_url)
46
+ req = Net::HTTP::Post.new(uri.to_s)
47
+ req.body = json_rpc_payload.to_json
48
+ req['Content-Type'] = 'application/json'
49
+ response = Net::HTTP.new(uri.host, uri.port).tap { |http| http.use_ssl = true }.request(req)
50
+
51
+ JSON.parse(response.body)
52
+ end
53
+
54
+ private
55
+
56
+ attr_reader :config
57
+ end
58
+
@@ -0,0 +1,49 @@
1
+ # frozen_string_literal: true
2
+
3
+ class NearApi::Base58
4
+ BASE = '123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz'
5
+
6
+ def self.encode(bytestring)
7
+ number = bytestring.unpack("C*").reverse.each_with_index.inject(0) do |sum, (byte, index)|
8
+ sum + byte * (256 ** index)
9
+ end
10
+ tos number
11
+ end
12
+
13
+ def self.decode(encoded_string)
14
+ integer = toi encoded_string
15
+ to_bytestring(integer)
16
+ end
17
+
18
+ def self.toi(string=to_s, base=58, digits=BASE)
19
+ return nil if string.empty?
20
+
21
+ integer = 0
22
+ string.each_char do |c|
23
+ index = digits.index(c)
24
+ integer = integer * base + index
25
+ end
26
+ integer
27
+ end
28
+
29
+ def self.tos(integer=to_i, base=58, digits=BASE)
30
+ return '' if integer.nil?
31
+ return digits[0] if integer == 0
32
+ string = ''
33
+ while integer > 0
34
+ integer, index = integer.divmod(base)
35
+ string = digits[index] + string
36
+ end
37
+ string
38
+ end
39
+
40
+ def self.to_bytestring(number)
41
+ integer = number
42
+ result = ''
43
+ while integer > 0
44
+ integer, remain = integer.divmod(256)
45
+ result = remain.chr + result
46
+ end
47
+ result
48
+ end
49
+ end
@@ -0,0 +1,15 @@
1
+ # frozen_string_literal: true
2
+
3
+ class NearApi::Config
4
+ def initialize(
5
+ signer_id: ENV.fetch('NEAR_SIGNER_ID'),
6
+ key_pair: ENV.fetch('NEAR_KEYPAIR'),
7
+ node_url: ENV.fetch('NEAR_NODE_URL')
8
+ )
9
+ @signer_id = signer_id
10
+ @key_pair = NearApi::KeyPair.new(key_pair)
11
+ @node_url = node_url
12
+ end
13
+
14
+ attr_reader :signer_id, :key_pair, :node_url
15
+ end
@@ -0,0 +1,30 @@
1
+ # frozen_string_literal: true
2
+ require 'ed25519'
3
+
4
+ class NearApi::KeyPair
5
+ def initialize(value)
6
+ key_value = if value.include?(':')
7
+ value.split(':').last
8
+ else
9
+ value
10
+ end
11
+ bytestring = NearApi::Base58.decode(key_value)
12
+ @key_pair = Ed25519::SigningKey.from_keypair(bytestring)
13
+ end
14
+
15
+ def public_key
16
+ key_pair.verify_key.to_bytes
17
+ end
18
+
19
+ def key_type
20
+ 0
21
+ end
22
+
23
+ def sign(msg)
24
+ key_pair.sign(msg)
25
+ end
26
+
27
+ private
28
+
29
+ attr_reader :key_pair
30
+ end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module NearApi
4
- VERSION = "0.1.0"
4
+ VERSION = "0.1.1"
5
5
  end
data/lib/near_api.rb CHANGED
@@ -1,6 +1,17 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require 'uri'
4
+ require 'net/https'
5
+ require 'json'
6
+ require "base64"
7
+ require 'borsh'
3
8
  require_relative "near_api/version"
9
+ require_relative "near_api/key_pair"
10
+ require_relative "near_api/action"
11
+ require_relative "near_api/action/function_call"
12
+ require_relative "near_api/config"
13
+ require_relative "near_api/api"
14
+ require_relative "near_api/base58"
4
15
 
5
16
  module NearApi
6
17
  class Error < StandardError; end
data/near_api.gemspec CHANGED
@@ -26,6 +26,12 @@ Gem::Specification.new do |spec|
26
26
  spec.executables = spec.files.grep(%r{\Aexe/}) { |f| File.basename(f) }
27
27
  spec.require_paths = ["lib"]
28
28
 
29
+ spec.add_dependency "borsh-rb"
30
+ spec.add_dependency "ed25519"
31
+
32
+ spec.add_development_dependency "rspec", "~> 3.10"
33
+ spec.add_development_dependency "pry"
34
+
29
35
  # Uncomment to register a new dependency of your gem
30
36
  # spec.add_dependency "example-gem", "~> 1.0"
31
37
 
metadata CHANGED
@@ -1,15 +1,71 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: near_api
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.1.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Serg Tyatin
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2021-12-13 00:00:00.000000000 Z
12
- dependencies: []
11
+ date: 2021-12-16 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: borsh-rb
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: '0'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ">="
25
+ - !ruby/object:Gem::Version
26
+ version: '0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: ed25519
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: rspec
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '3.10'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '3.10'
55
+ - !ruby/object:Gem::Dependency
56
+ name: pry
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ">="
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ">="
67
+ - !ruby/object:Gem::Version
68
+ version: '0'
13
69
  description:
14
70
  email:
15
71
  - 700@2rba.com
@@ -26,6 +82,12 @@ files:
26
82
  - bin/console
27
83
  - bin/setup
28
84
  - lib/near_api.rb
85
+ - lib/near_api/action.rb
86
+ - lib/near_api/action/function_call.rb
87
+ - lib/near_api/api.rb
88
+ - lib/near_api/base58.rb
89
+ - lib/near_api/config.rb
90
+ - lib/near_api/key_pair.rb
29
91
  - lib/near_api/version.rb
30
92
  - near_api.gemspec
31
93
  homepage: https://github.com/2rba/near_api