ton-sdk-ruby 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.
@@ -0,0 +1,188 @@
1
+ require 'bigdecimal'
2
+
3
+ module TonSdkRuby
4
+
5
+ class Coins
6
+ attr_reader :value, :decimals, :multiplier
7
+ private :value, :decimals, :multiplier
8
+
9
+ def initialize(value, options = {})
10
+ is_nano = options[:is_nano] || false
11
+ decimals = options[:decimals] || 9
12
+
13
+ value = value.to_s
14
+ Coins.check_coins_type(value)
15
+ Coins.check_coins_decimals(decimals)
16
+
17
+ decimal = BigDecimal(value)
18
+
19
+ if decimal.dp > decimals
20
+ raise "Invalid Coins value, decimals places \"#{decimal.dp}\" can't be greater than selected \"#{decimals}\""
21
+ end
22
+
23
+ @decimals = decimals
24
+ @multiplier = (1 * 10) ** @decimals
25
+ @value = is_nano ? decimal : decimal * @multiplier
26
+ end
27
+
28
+ def self.from_nano(value, decimals = 9)
29
+ check_coins_type(value)
30
+ check_coins_decimals(decimals)
31
+
32
+ Coins.new(value, is_nano: true, decimals: decimals)
33
+ end
34
+
35
+ def add(coins)
36
+ Coins.check_coins(coins)
37
+ Coins.compare_coins_decimals(self, coins)
38
+
39
+ @value += coins.value
40
+
41
+ self
42
+ end
43
+
44
+ def sub(coins)
45
+ Coins.check_coins(coins)
46
+ Coins.compare_coins_decimals(self, coins)
47
+
48
+ @value -= coins.value
49
+
50
+ self
51
+ end
52
+
53
+ def mul(value)
54
+ Coins.check_value(value)
55
+ Coins.check_convertability(value)
56
+
57
+ multiplier = value.to_s
58
+
59
+ @value *= multiplier.to_i
60
+
61
+ self
62
+ end
63
+
64
+ def div(value)
65
+ Coins.check_value(value)
66
+ Coins.check_convertibility(value)
67
+
68
+ divider = value.to_s
69
+
70
+ @value /= divider.to_i
71
+
72
+ self
73
+ end
74
+
75
+ def eq(coins)
76
+ Coins.check_coins(coins)
77
+ Coins.compare_coins_decimals(self, coins)
78
+
79
+ @value == coins.value
80
+ end
81
+
82
+ def gt(coins)
83
+ Coins.check_coins(coins)
84
+ Coins.compare_coins_decimals(self, coins)
85
+
86
+ @value > coins.value
87
+ end
88
+
89
+ def gte(coins)
90
+ Coins.check_coins(coins)
91
+ Coins.compare_coins_decimals(self, coins)
92
+
93
+ @value >= coins.value
94
+ end
95
+
96
+ def lt(coins)
97
+ Coins.check_coins(coins)
98
+ Coins.compare_coins_decimals(self, coins)
99
+
100
+ @value < coins.value
101
+ end
102
+
103
+ def lte(coins)
104
+ Coins.check_coins(coins)
105
+ Coins.compare_coins_decimals(self, coins)
106
+
107
+ @value <= coins.value
108
+ end
109
+
110
+ def negative?
111
+ @value.negative?
112
+ end
113
+
114
+ def positive?
115
+ @value.positive?
116
+ end
117
+
118
+ def zero?
119
+ @value.zero?
120
+ end
121
+
122
+ def to_s
123
+ value = (@value / @multiplier.to_f).round(@decimals).to_s
124
+
125
+ # Remove all trailing zeroes
126
+ coins = value.sub(/\.0{#{@decimals}}$/, '').sub(/(\.[0-9]*?[0-9])0+$/, '\1')
127
+
128
+ coins
129
+ end
130
+
131
+ def to_nano
132
+ @value.to_i
133
+ end
134
+
135
+
136
+ private
137
+
138
+ def self.check_coins_type(value)
139
+ raise 'Invalid Coins value' unless valid?(value) && convertable?(value)
140
+ raise 'Invalid Coins value' if coins?(value)
141
+ end
142
+
143
+ def self.check_coins_decimals(decimals)
144
+ raise 'Invalid decimals value, must be 0-18' if decimals < 0 || decimals > 18
145
+ end
146
+
147
+ def self.compare_coins_decimals(a, b)
148
+ raise "Can't perform mathematical operation of Coins with different decimals" if a.decimals != b.decimals
149
+ end
150
+
151
+ def self.check_value(value)
152
+ raise 'Invalid value' unless valid?(value)
153
+ end
154
+
155
+ def self.check_coins(value)
156
+ raise 'Invalid value' unless coins?(value)
157
+ end
158
+
159
+ def self.check_convertability(value)
160
+ raise 'Invalid value' unless convertable?(value)
161
+ end
162
+
163
+ def self.valid?(value)
164
+ value.class == String || value.class == Integer
165
+ end
166
+
167
+ def self.coins?(value)
168
+ value.is_a?(Coins)
169
+ end
170
+
171
+ def self.convertable?(value)
172
+ begin
173
+ BigDecimal(value.to_s)
174
+ true
175
+ rescue StandardError
176
+ false
177
+ end
178
+ end
179
+ end
180
+ end
181
+
182
+ class BigDecimal
183
+ def dp
184
+ digits_after_comma = self.to_s("F").split(".").last
185
+ return 0 if digits_after_comma == '0'
186
+ digits_after_comma.size
187
+ end
188
+ end
@@ -0,0 +1,25 @@
1
+ module TonSdkRuby
2
+
3
+ def augment(bits, divider = 8)
4
+ bits = Array.new(bits)
5
+ amount = divider - (bits.size % divider)
6
+ overage = Array.new(amount, 0)
7
+ overage[0] = 1
8
+
9
+ if overage.size != 0 && overage.size != divider
10
+ return bits.concat(overage)
11
+ end
12
+
13
+ bits
14
+ end
15
+
16
+ def rollback(bits)
17
+ index = bits.last(7).reverse.index(1)
18
+
19
+ if index.nil?
20
+ raise StandardError.new('Incorrectly augmented bits.')
21
+ end
22
+
23
+ bits[0, bits.length - (index + 1)]
24
+ end
25
+ end
@@ -0,0 +1,46 @@
1
+ module TonSdkRuby
2
+
3
+ def crc16(data)
4
+ poly = 0x1021
5
+ bytes = data.is_a?(String) ? data.unpack('C*') : Array.new(data)
6
+ int16 = bytes.reduce(0) do |acc, el|
7
+ crc = acc ^ (el << 8)
8
+
9
+ 8.times do
10
+ crc = (crc & 0x8000) == 0x8000 ? (crc << 1) ^ poly : crc << 1
11
+ end
12
+
13
+ crc
14
+ end & 0xffff
15
+
16
+ [int16].pack("S").unpack1("S")
17
+ end
18
+
19
+ def crc16_bytes_be(data)
20
+ crc = crc16(data)
21
+ [crc].pack("S>").bytes
22
+ end
23
+
24
+ def crc32c(data)
25
+ poly = 0x82f63b78
26
+ bytes = data.is_a?(String) ? data.unpack('C*') : Array.new(data)
27
+
28
+ int32 = bytes.reduce(0 ^ 0xffffffff) do |acc, el|
29
+ crc = acc ^ el
30
+
31
+ 8.times do
32
+ crc = crc & 1 == 1 ? (crc >> 1) ^ poly : crc >> 1
33
+ end
34
+
35
+ crc
36
+ end ^ 0xffffffff
37
+
38
+ [int32].pack("L>").unpack1("L>")
39
+ end
40
+
41
+ def crc32c_bytes_le(data)
42
+ crc = crc32c(data)
43
+ [crc].pack("L<").bytes
44
+ end
45
+
46
+ end
@@ -0,0 +1,15 @@
1
+ require 'digest'
2
+ require_relative 'helpers.rb'
3
+
4
+ module TonSdkRuby
5
+
6
+ def sha256(bytes)
7
+ digest = Digest::SHA256.digest(bytes.pack('C*'))
8
+ bytes_to_hex(digest)
9
+ end
10
+
11
+ def sha512(bytes)
12
+ digest = Digest::SHA512.digest(bytes.pack('C*'))
13
+ bytes_to_hex(digest)
14
+ end
15
+ end
@@ -0,0 +1,161 @@
1
+ require 'base64'
2
+ require 'ed25519'
3
+ require "json"
4
+ require 'net/http'
5
+ require 'uri'
6
+
7
+ module TonSdkRuby
8
+
9
+
10
+ INT32_MAX = 2147483647
11
+ INT32_MIN = -2147483648
12
+
13
+ def uint_to_hex(uint)
14
+ hex = sprintf("%#x", uint)
15
+ hex[-(hex.length / 2 * 2)..-1]
16
+ end
17
+
18
+ def hex_to_bits(hex)
19
+ result = hex.split('').flat_map do |val|
20
+ chunk = val.to_i(16)
21
+ .to_s(2)
22
+ .rjust(4, '0')
23
+ .split('')
24
+ .map(&:to_i)
25
+
26
+ chunk
27
+ end
28
+
29
+ result
30
+ end
31
+
32
+ def bytes_to_uint(bytes)
33
+ uint = bytes.each_with_index.inject(0) do |acc, (byte, i)|
34
+ acc *= 256
35
+ acc += byte
36
+ acc
37
+ end
38
+ uint
39
+ end
40
+
41
+ def bytes_compare(a, b)
42
+ return false if a.length != b.length
43
+
44
+ a.each_with_index.all? { |uint, i| uint == b[i] }
45
+ end
46
+
47
+ def hex_to_bytes(hex)
48
+ hex.scan(/.{1,2}/).map { |byte| byte.to_i(16) }
49
+ end
50
+
51
+ def bytes_to_bits(data)
52
+ bytes = data.is_a?(Array) ? data : data.unpack("C*")
53
+
54
+ result = bytes.reduce([]) do |acc, uint|
55
+ chunk = uint.to_s(2)
56
+ .rjust(8, '0')
57
+ .split('')
58
+ .map(&:to_i)
59
+
60
+ acc.concat(chunk)
61
+ end
62
+ result
63
+ end
64
+
65
+ def bits_to_hex(bits)
66
+ bitstring = bits.join('')
67
+ hex = bitstring.scan(/.{1,4}/).map { |el| el.rjust(4, '0').to_i(2).to_s(16) }
68
+ hex.join('')
69
+ end
70
+
71
+ def bits_to_bytes(bits)
72
+ return [].pack("C*") if bits.empty?
73
+
74
+ hex_to_bytes(bits_to_hex(bits))
75
+ end
76
+
77
+ def bytes_to_hex(bytes)
78
+ if bytes.is_a?(Array)
79
+ bytes.pack('C*').unpack('H*').first
80
+ else
81
+ bytes.unpack('H*').first
82
+ end
83
+ end
84
+
85
+ def bytes_to_string(bytes)
86
+ bytes.pack("C*").force_encoding('utf-8')
87
+ end
88
+
89
+ def bytes_to_data_string(bytes)
90
+ raise 'Only byte array' unless bytes.is_a?(Array)
91
+ bytes.pack('C*')
92
+ end
93
+
94
+ def hex_to_data_string(hex)
95
+ bytes_to_data_string(hex_to_bytes(hex))
96
+ end
97
+
98
+ def string_to_bytes(value)
99
+ value.bytes
100
+ end
101
+
102
+ def bytes_to_base64(data)
103
+ bytes = data.is_a?(String) ? data.unpack("C*") : data
104
+ str = bytes.map(&:chr).join
105
+
106
+ Base64.strict_encode64(str)
107
+ end
108
+
109
+ def base64_to_bytes(base64)
110
+ binary = Base64.strict_decode64(base64)
111
+ binary.bytes
112
+ end
113
+
114
+ def slice_into_chunks(arr, chunk_size)
115
+ res = []
116
+
117
+ (0...arr.length).step(chunk_size) do |i|
118
+ chunk = arr[i, chunk_size]
119
+ res.push(chunk)
120
+ end
121
+
122
+ res
123
+ end
124
+
125
+ def sign_cell(cell, private_key)
126
+ hash = hex_to_data_string(cell.hash)
127
+ data_key = hex_to_data_string(private_key)
128
+ Ed25519::SigningKey.new(data_key).sign(hash)
129
+ end
130
+
131
+ def read_json_from_link(link)
132
+ uri = URI.parse("#{link}")
133
+ request = Net::HTTP::Get.new(uri)
134
+
135
+ request.content_type = "application/json"
136
+ req_options = { use_ssl: uri.scheme == "https" }
137
+ response = Net::HTTP.start(uri.hostname, uri.port, req_options) do |http|
138
+ http.request(request)
139
+ end
140
+ JSON.parse(response.body)
141
+ end
142
+
143
+ def read_post_json_from_link(url, body, headers)
144
+ uri = URI.parse(url)
145
+ request = Net::HTTP::Post.new(uri)
146
+ request.content_type = "application/json"
147
+ headers.each do |name, value|
148
+ request[name.to_s] = value
149
+ end
150
+ request.body = JSON.generate(body)
151
+ req_options = { use_ssl: uri.scheme == "https" }
152
+ response = Net::HTTP.start(uri.hostname, uri.port, req_options) do |http|
153
+ http.request(request)
154
+ end
155
+ JSON.parse(response.body)
156
+ end
157
+
158
+ def require_type(name, value, type)
159
+ raise "#{name} must be #{type}" unless value.is_a?(type)
160
+ end
161
+ end
@@ -0,0 +1,42 @@
1
+ module TonSdkRuby
2
+
3
+ def bits_to_big_uint(bits)
4
+ return { value: 0, is_safe: true } if bits.empty?
5
+
6
+ value = bits.reverse.each_with_index.inject(0) { |acc, (bit, i)| bit.to_i * (2 ** i) + acc }
7
+
8
+ is_safe = value <= Float::MAX.to_i
9
+
10
+ {
11
+ value: value,
12
+ is_safe: is_safe
13
+ }
14
+ end
15
+
16
+ def bits_to_big_int(bits)
17
+ return { value: 0, is_safe: true } if bits.empty?
18
+
19
+ uint_result = bits_to_big_uint(bits)
20
+ uint = uint_result[:value]
21
+ size = bits.size
22
+ int = 1 << (size - 1)
23
+ value = uint >= int ? (uint - (int * 2)) : uint
24
+ is_safe = value >= Float::MIN.to_i && value <= Float::MAX.to_i
25
+
26
+ {
27
+ value: value,
28
+ is_safe: is_safe
29
+ }
30
+ end
31
+
32
+ def bits_to_int_uint(bits, options = { type: 'int' })
33
+ type = options[:type].to_s || 'uint'
34
+ result = if type == 'uint'
35
+ bits_to_big_uint(bits)
36
+ else
37
+ bits_to_big_int(bits)
38
+ end
39
+
40
+ result[:value]
41
+ end
42
+ end
@@ -0,0 +1,4 @@
1
+ module TonSdkRuby
2
+ VERSION = "0.0.1"
3
+ end
4
+
@@ -0,0 +1,29 @@
1
+ require_relative './ton-sdk-ruby/version'
2
+ require_relative './ton-sdk-ruby/bit_array/bit_array'
3
+
4
+ require_relative './ton-sdk-ruby/utils/helpers'
5
+ require_relative './ton-sdk-ruby/utils/bits'
6
+ require_relative './ton-sdk-ruby/utils/checksum'
7
+ require_relative './ton-sdk-ruby/utils/hash'
8
+ require_relative './ton-sdk-ruby/utils/numbers'
9
+
10
+ require_relative './ton-sdk-ruby/types/Address'
11
+ require_relative './ton-sdk-ruby/types/Block'
12
+ require_relative './ton-sdk-ruby/types/Coins'
13
+
14
+ require_relative './ton-sdk-ruby/boc/mask'
15
+ require_relative './ton-sdk-ruby/boc/cell'
16
+ require_relative './ton-sdk-ruby/boc/hashmap'
17
+ require_relative './ton-sdk-ruby/boc/slice'
18
+ require_relative './ton-sdk-ruby/boc/builder'
19
+ require_relative './ton-sdk-ruby/boc/serializer'
20
+
21
+ require_relative './ton-sdk-ruby/johnny_mnemonic/utils'
22
+ require_relative './ton-sdk-ruby/johnny_mnemonic/ton_mnemonic'
23
+
24
+ require_relative './ton-sdk-ruby/providers/toncenter'
25
+ require_relative './ton-sdk-ruby/providers/provider'
26
+
27
+
28
+ module TonSdkRuby
29
+ end
metadata ADDED
@@ -0,0 +1,137 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: ton-sdk-ruby
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - nerzh
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2023-08-25 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: ed25519
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: 1.3.0
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: 1.3.0
27
+ - !ruby/object:Gem::Dependency
28
+ name: bundler
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '2.0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '2.0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: byebug
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ">="
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ">="
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: rspec
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'
69
+ - !ruby/object:Gem::Dependency
70
+ name: rake
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - ">="
74
+ - !ruby/object:Gem::Version
75
+ version: '0'
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - ">="
81
+ - !ruby/object:Gem::Version
82
+ version: '0'
83
+ description: Gem Ton SDK Ruby for all TVM ruby projects
84
+ email:
85
+ - emptystamp@gmail.com
86
+ executables:
87
+ - ton-sdk-ruby
88
+ extensions: []
89
+ extra_rdoc_files: []
90
+ files:
91
+ - bin/ton-sdk-ruby
92
+ - lib/ton-sdk-ruby.rb
93
+ - lib/ton-sdk-ruby/bit_array/bit_array.rb
94
+ - lib/ton-sdk-ruby/boc/builder.rb
95
+ - lib/ton-sdk-ruby/boc/cell.rb
96
+ - lib/ton-sdk-ruby/boc/hashmap.rb
97
+ - lib/ton-sdk-ruby/boc/mask.rb
98
+ - lib/ton-sdk-ruby/boc/serializer.rb
99
+ - lib/ton-sdk-ruby/boc/slice.rb
100
+ - lib/ton-sdk-ruby/johnny_mnemonic/ton_mnemonic.rb
101
+ - lib/ton-sdk-ruby/johnny_mnemonic/utils.rb
102
+ - lib/ton-sdk-ruby/johnny_mnemonic/words/english.json
103
+ - lib/ton-sdk-ruby/providers/provider.rb
104
+ - lib/ton-sdk-ruby/providers/toncenter.rb
105
+ - lib/ton-sdk-ruby/types/address.rb
106
+ - lib/ton-sdk-ruby/types/block.rb
107
+ - lib/ton-sdk-ruby/types/coins.rb
108
+ - lib/ton-sdk-ruby/utils/bits.rb
109
+ - lib/ton-sdk-ruby/utils/checksum.rb
110
+ - lib/ton-sdk-ruby/utils/hash.rb
111
+ - lib/ton-sdk-ruby/utils/helpers.rb
112
+ - lib/ton-sdk-ruby/utils/numbers.rb
113
+ - lib/ton-sdk-ruby/version.rb
114
+ homepage: https://github.com/nerzh/ton-sdk-ruby
115
+ licenses:
116
+ - MIT
117
+ metadata: {}
118
+ post_install_message:
119
+ rdoc_options: []
120
+ require_paths:
121
+ - lib
122
+ required_ruby_version: !ruby/object:Gem::Requirement
123
+ requirements:
124
+ - - ">="
125
+ - !ruby/object:Gem::Version
126
+ version: '0'
127
+ required_rubygems_version: !ruby/object:Gem::Requirement
128
+ requirements:
129
+ - - ">="
130
+ - !ruby/object:Gem::Version
131
+ version: '0'
132
+ requirements: []
133
+ rubygems_version: 3.4.19
134
+ signing_key:
135
+ specification_version: 4
136
+ summary: This is gem ton-sdk-ruby
137
+ test_files: []