nem-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.
Files changed (136) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +12 -0
  3. data/.rspec +2 -0
  4. data/.rubocop.yml +119 -0
  5. data/.travis.yml +23 -0
  6. data/CODE_OF_CONDUCT.md +74 -0
  7. data/Gemfile +6 -0
  8. data/README.md +81 -0
  9. data/Rakefile +6 -0
  10. data/examples/apostille_audit.rb +22 -0
  11. data/examples/apostille_create.rb +31 -0
  12. data/examples/endpoint/account.rb +73 -0
  13. data/examples/endpoint/account_local.rb +21 -0
  14. data/examples/endpoint/block.rb +14 -0
  15. data/examples/endpoint/chain.rb +15 -0
  16. data/examples/endpoint/debug.rb +17 -0
  17. data/examples/endpoint/local.rb +17 -0
  18. data/examples/endpoint/mosaic.rb +9 -0
  19. data/examples/endpoint/namespace.rb +13 -0
  20. data/examples/endpoint/node.rb +24 -0
  21. data/examples/endpoint/timesync.rb +9 -0
  22. data/examples/endpoint/transaction.rb +42 -0
  23. data/examples/localnode.rb +0 -0
  24. data/examples/nis.rb +34 -0
  25. data/examples/node_pool.rb +23 -0
  26. data/examples/transaction/importance_transfer.rb +23 -0
  27. data/examples/transaction/mosaic_definition_creation.rb +52 -0
  28. data/examples/transaction/mosaic_supply_change.rb +25 -0
  29. data/examples/transaction/multisig_add_cosignatory.rb +31 -0
  30. data/examples/transaction/multisig_aggregate_modification.rb +29 -0
  31. data/examples/transaction/multisig_signature.rb +41 -0
  32. data/examples/transaction/multisig_transfer.rb +35 -0
  33. data/examples/transaction/provision_namespace.rb +20 -0
  34. data/examples/transaction/transfer.rb +32 -0
  35. data/examples/transaction/transfer_mosaic.rb +72 -0
  36. data/examples/transaction/transfer_with_encrypted_message.rb +40 -0
  37. data/examples/transaction/transfer_with_local.rb +34 -0
  38. data/lib/nem.rb +21 -0
  39. data/lib/nem/apostille.rb +104 -0
  40. data/lib/nem/apostille_audit.rb +47 -0
  41. data/lib/nem/client.rb +170 -0
  42. data/lib/nem/configuration.rb +29 -0
  43. data/lib/nem/endpoint.rb +4 -0
  44. data/lib/nem/endpoint/account.rb +264 -0
  45. data/lib/nem/endpoint/base.rb +45 -0
  46. data/lib/nem/endpoint/block.rb +15 -0
  47. data/lib/nem/endpoint/chain.rb +17 -0
  48. data/lib/nem/endpoint/debug.rb +54 -0
  49. data/lib/nem/endpoint/local/account.rb +54 -0
  50. data/lib/nem/endpoint/local/chain.rb +15 -0
  51. data/lib/nem/endpoint/mosaic.rb +13 -0
  52. data/lib/nem/endpoint/namespace.rb +37 -0
  53. data/lib/nem/endpoint/node.rb +83 -0
  54. data/lib/nem/endpoint/timesync.rb +9 -0
  55. data/lib/nem/endpoint/transaction.rb +34 -0
  56. data/lib/nem/error.rb +6 -0
  57. data/lib/nem/fee.rb +2 -0
  58. data/lib/nem/fee/importance_transfer.rb +24 -0
  59. data/lib/nem/fee/mosaic_definition_creation.rb +24 -0
  60. data/lib/nem/fee/mosaic_supply_change_transfer.rb +24 -0
  61. data/lib/nem/fee/multisig.rb +24 -0
  62. data/lib/nem/fee/multisig_aggregation_modification.rb +28 -0
  63. data/lib/nem/fee/provision_namespace.rb +34 -0
  64. data/lib/nem/fee/transfer.rb +66 -0
  65. data/lib/nem/keypair.rb +44 -0
  66. data/lib/nem/mixin.rb +2 -0
  67. data/lib/nem/mixin/assignable.rb +12 -0
  68. data/lib/nem/model.rb +3 -0
  69. data/lib/nem/model/account.rb +67 -0
  70. data/lib/nem/model/account_historical.rb +19 -0
  71. data/lib/nem/model/block.rb +33 -0
  72. data/lib/nem/model/chain.rb +14 -0
  73. data/lib/nem/model/connection.rb +23 -0
  74. data/lib/nem/model/experience.rb +20 -0
  75. data/lib/nem/model/explorer_block.rb +21 -0
  76. data/lib/nem/model/harvest.rb +23 -0
  77. data/lib/nem/model/heartbeat.rb +21 -0
  78. data/lib/nem/model/importance.rb +29 -0
  79. data/lib/nem/model/importance_transfer_transaction.rb +16 -0
  80. data/lib/nem/model/keypair.rb +19 -0
  81. data/lib/nem/model/message.rb +91 -0
  82. data/lib/nem/model/mosaic.rb +21 -0
  83. data/lib/nem/model/mosaic_attachment.rb +22 -0
  84. data/lib/nem/model/mosaic_definition.rb +65 -0
  85. data/lib/nem/model/mosaic_definition_creation_transaction.rb +18 -0
  86. data/lib/nem/model/mosaic_id.rb +27 -0
  87. data/lib/nem/model/mosaic_levy.rb +32 -0
  88. data/lib/nem/model/mosaic_owned.rb +22 -0
  89. data/lib/nem/model/mosaic_properties.rb +44 -0
  90. data/lib/nem/model/mosaic_supply.rb +21 -0
  91. data/lib/nem/model/mosaic_supply_change_transaction.rb +18 -0
  92. data/lib/nem/model/multisig_aggregate_modification_transaction.rb +21 -0
  93. data/lib/nem/model/multisig_info.rb +16 -0
  94. data/lib/nem/model/multisig_signature_transaction.rb +17 -0
  95. data/lib/nem/model/multisig_transaction.rb +21 -0
  96. data/lib/nem/model/namespace.rb +24 -0
  97. data/lib/nem/model/nem_announce_result.rb +19 -0
  98. data/lib/nem/model/network_time.rb +16 -0
  99. data/lib/nem/model/nis_node_info.rb +26 -0
  100. data/lib/nem/model/node.rb +41 -0
  101. data/lib/nem/model/provision_namespace_transaction.rb +18 -0
  102. data/lib/nem/model/status.rb +21 -0
  103. data/lib/nem/model/timer.rb +31 -0
  104. data/lib/nem/model/timesync.rb +19 -0
  105. data/lib/nem/model/transaction.rb +71 -0
  106. data/lib/nem/model/transfer_transaction.rb +24 -0
  107. data/lib/nem/model/unlocked_info.rb +24 -0
  108. data/lib/nem/mosaic.rb +2 -0
  109. data/lib/nem/mosaic/dim_coin.rb +21 -0
  110. data/lib/nem/mosaic/dim_token.rb +21 -0
  111. data/lib/nem/mosaic/ecobit_eco.rb +21 -0
  112. data/lib/nem/mosaic/xem.rb +21 -0
  113. data/lib/nem/node.rb +29 -0
  114. data/lib/nem/node_pool.rb +31 -0
  115. data/lib/nem/request.rb +2 -0
  116. data/lib/nem/request/announce.rb +76 -0
  117. data/lib/nem/transaction.rb +3 -0
  118. data/lib/nem/transaction/base.rb +45 -0
  119. data/lib/nem/transaction/importance_transfer.rb +42 -0
  120. data/lib/nem/transaction/mosaic_definition_creation.rb +45 -0
  121. data/lib/nem/transaction/mosaic_supply_change.rb +45 -0
  122. data/lib/nem/transaction/multisig.rb +29 -0
  123. data/lib/nem/transaction/multisig_aggregate_modification.rb +30 -0
  124. data/lib/nem/transaction/multisig_cosignatory_modification.rb +33 -0
  125. data/lib/nem/transaction/multisig_signature.rb +31 -0
  126. data/lib/nem/transaction/provision_namespace.rb +65 -0
  127. data/lib/nem/transaction/transfer.rb +63 -0
  128. data/lib/nem/util.rb +44 -0
  129. data/lib/nem/util/assignable.rb +51 -0
  130. data/lib/nem/util/convert.rb +112 -0
  131. data/lib/nem/util/deserializer.rb +158 -0
  132. data/lib/nem/util/ed25519.rb +316 -0
  133. data/lib/nem/util/serializer.rb +260 -0
  134. data/lib/nem/version.rb +3 -0
  135. data/nem-ruby.gemspec +46 -0
  136. metadata +350 -0
@@ -0,0 +1,15 @@
1
+ module Nem
2
+ module Endpoint
3
+ module Local
4
+ class Chain < Nem::Endpoint::Base
5
+ def blocks_after(height)
6
+ request!(:post, '/local/chain/blocks-after', height: height) do |res|
7
+ res[:data].map do |data|
8
+ Nem::Model::ExpelorerBlock.new_from_explorer_block(data)
9
+ end
10
+ end
11
+ end
12
+ end
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,13 @@
1
+ module Nem
2
+ module Endpoint
3
+ class Mosaic < Nem::Endpoint::Base
4
+ # @return <Nem::Model::Namespace>
5
+ # @see https://nemproject.github.io/#
6
+ def supply(mosaic_id)
7
+ request!(:get, '/mosaic/supply', mosaicId: mosaic_id) do |res|
8
+ Nem::Model::MosaicSupply.new_from_mosaic_supply(res)
9
+ end
10
+ end
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,37 @@
1
+ module Nem
2
+ module Endpoint
3
+ class Namespace < Nem::Endpoint::Base
4
+ # @return <Nem::Model::Namespace>
5
+ # @see https://nemproject.github.io/#retrieving-a-specific-namespace
6
+ def find(namespace)
7
+ request!(:get, '/namespace', namespace: namespace) do |res|
8
+ Nem::Model::Namespace.new_from_namespace(res)
9
+ end
10
+ end
11
+
12
+ alias get find
13
+
14
+ # @return [Array <Nem::Model::Namespace>]
15
+ # @see https://nemproject.github.io/#retrieving-root-namespaces
16
+ def root(id, page_size: nil)
17
+ request!(:get, '/namespace/root/page', id: id, pageSize: page_size) do |res|
18
+ res[:data].map do |nsmdp|
19
+ Nem::Model::Namespace.new_from_namespace_meta_data_pair(nsmdp)
20
+ end
21
+ end
22
+ end
23
+
24
+ # @return [Array <Nem::Model::MosaicDefinition>]
25
+ # @see https://nemproject.github.io/#retrieving-mosaic-definitions
26
+ def mosaic_definition(namespace, id: nil, page_size: nil)
27
+ request!(:get, '/namespace/mosaic/definition/page',
28
+ namespace: namespace,
29
+ id: id,
30
+ pageSize: page_size
31
+ ) do |res|
32
+ res[:data].map { |mdmdp| Nem::Model::MosaicDefinition.new_from_mosaic_definition_meta_data_pair(mdmdp) }
33
+ end
34
+ end
35
+ end
36
+ end
37
+ end
@@ -0,0 +1,83 @@
1
+ module Nem
2
+ module Endpoint
3
+ class Node < Nem::Endpoint::Base
4
+ # @return [integer]
5
+ # @see https://nemproject.github.io/#maximum-chain-height-in-the-active-neighborhood
6
+ def max_chain_height
7
+ request!(:get, '/node/active-peers/max-chain-height')[:height]
8
+ end
9
+
10
+ # @return [Nem::Model::Node]
11
+ # @see https://nemproject.github.io/#basic-node-information
12
+ def info
13
+ Nem::Model::Node.new_from_node request!(:get, '/node/info')
14
+ end
15
+
16
+ # @return [Nem::Model::Node]
17
+ # @see https://nemproject.github.io/#extended-node-information
18
+ def extended_info
19
+ Nem::Model::NisNodeInfo.new_from_nis_node_info request!(:get, '/node/extended-info')
20
+ end
21
+
22
+ # @return [Nem::Model::ExtendedNodeExperiencePair]
23
+ # @see https://nemproject.github.io/#requesting-node-experiences
24
+ def experiences
25
+ request!(:get, '/node/experiences') do |res|
26
+ res[:data].map do |struct|
27
+ Nem::Model::Experience.new_from_experience(struct)
28
+ end
29
+ end
30
+ end
31
+
32
+ # @return [Array <Nem::Model::Node>]
33
+ # @see https://nemproject.github.io/#active-neighborhood
34
+ def peerlist_active
35
+ request!(:get, '/node/peer-list/active') do |res|
36
+ res[:data].map do |n|
37
+ Nem::Model::Node.new_from_node(n)
38
+ end
39
+ end
40
+ end
41
+
42
+ # @return [Struct Array <Nem::Model::Node>]
43
+ # @see https://nemproject.github.io/#complete-neighborhood
44
+ PeerlistAll = Struct.new(:inactive, :failure, :busy, :active)
45
+ def peerlist_all
46
+ request!(:get, '/node/peer-list/all') do |res|
47
+ PeerlistAll.new(
48
+ res[:inactive].map { |n| Nem::Model::Node.new_from_node(n) },
49
+ res[:failure].map { |n| Nem::Model::Node.new_from_node(n) },
50
+ res[:busy].map { |n| Nem::Model::Node.new_from_node(n) },
51
+ res[:active].map { |n| Nem::Model::Node.new_from_node(n) }
52
+ )
53
+ end
54
+ end
55
+
56
+ # @return [Array <Nem::Model::Node>]
57
+ # @see https://nemproject.github.io/#reachable-neighborhood
58
+ def peerlist_reachable
59
+ request!(:get, '/node/peer-list/reachable') do |res|
60
+ res[:data].map do |n|
61
+ Nem::Model::Node.new_from_node(n)
62
+ end
63
+ end
64
+ end
65
+
66
+ # @return [Array <Nem::Model::Node>]
67
+ def peerlist(type = :all)
68
+ case type.to_s
69
+ when /\Aactive/ then peerlist_active
70
+ when /\Areach/ then peerlist_reachable
71
+ else peerlist_all
72
+ end
73
+ end
74
+
75
+ # @param boot_node_request [Nem::Model::BootNodeRequest]
76
+ # @return [nil]
77
+ # @see https://nemproject.github.io/#booting-the-local-node
78
+ def boot(boot_node_request)
79
+ request!(:post, '/node/boot', boot_node_request)
80
+ end
81
+ end
82
+ end
83
+ end
@@ -0,0 +1,9 @@
1
+ module Nem
2
+ module Endpoint
3
+ class Timesync < Nem::Endpoint::Base
4
+ def network_time
5
+ Nem::Model::NetworkTime.new_from_network_time request!(:get, '/time-sync/network-time')
6
+ end
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,34 @@
1
+ module Nem
2
+ module Endpoint
3
+ class Transaction < Nem::Endpoint::Base
4
+ def find(hash)
5
+ request!(:get,
6
+ '/transaction/get',
7
+ hash: hash
8
+ ) do |res|
9
+ Nem::Model::Transaction.new_from_account_transaction_meta_data_pair(res)
10
+ end
11
+ end
12
+
13
+ alias get find
14
+
15
+ def announce(req)
16
+ request!(:post,
17
+ '/transaction/announce',
18
+ req.to_entity
19
+ ) do |res|
20
+ Nem::Model::NemAnnounceResult.new_from_nem_announce_result(res)
21
+ end
22
+ end
23
+
24
+ def prepare_announce(req)
25
+ request!(:post,
26
+ '/transaction/prepare-announce',
27
+ req.to_entity(:prepare)
28
+ ) do |res|
29
+ Nem::Model::NemAnnounceResult.new_from_nem_announce_result(res)
30
+ end
31
+ end
32
+ end
33
+ end
34
+ end
@@ -0,0 +1,6 @@
1
+ module Nem
2
+ class Error < StandardError; end
3
+ class NotFoundError < Error; end
4
+ class BadRequestError < Error; end
5
+ class InternalServerError < Error; end
6
+ end
@@ -0,0 +1,2 @@
1
+ # frozen_string_literal: true
2
+ Dir.glob(File.expand_path('fee/*.rb', __dir__)).each { |f| require f }
@@ -0,0 +1,24 @@
1
+ module Nem
2
+ module Fee
3
+ class ImportanceTransfer
4
+ def initialize(transaction)
5
+ @transaction = transaction
6
+ end
7
+
8
+ # @return [Integer] fee in micro XEM
9
+ def value
10
+ 0.15 * 1_000_000
11
+ end
12
+
13
+ # @return [Integer] fee in micro XEM
14
+ def to_i
15
+ value.to_i
16
+ end
17
+
18
+ # @return [Boolean]
19
+ def testnet?
20
+ @transaction.network == :testnet
21
+ end
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,24 @@
1
+ module Nem
2
+ module Fee
3
+ class MosaicDefinitionCreation
4
+ def initialize(transaction)
5
+ @transaction = transaction
6
+ end
7
+
8
+ # @return [Integer] fee in micro XEM
9
+ def value
10
+ 10 * 1_000_000
11
+ end
12
+
13
+ # @return [Integer] fee in micro XEM
14
+ def to_i
15
+ value.to_i
16
+ end
17
+
18
+ # @return [Boolean]
19
+ def testnet?
20
+ @transaction.network == :testnet
21
+ end
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,24 @@
1
+ module Nem
2
+ module Fee
3
+ class MosaicSupplyChangeTransfer
4
+ def initialize(transaction)
5
+ @transaction = transaction
6
+ end
7
+
8
+ # @return [Integer] fee in micro XEM
9
+ def value
10
+ 0.15 * 1_000_000
11
+ end
12
+
13
+ # @return [Integer] fee in micro XEM
14
+ def to_i
15
+ value.to_i
16
+ end
17
+
18
+ # @return [Boolean]
19
+ def testnet?
20
+ @transaction.network == :testnet
21
+ end
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,24 @@
1
+ module Nem
2
+ module Fee
3
+ class Multisig
4
+ def initialize(transaction)
5
+ @transaction = transaction
6
+ end
7
+
8
+ # @return [Integer] fee in micro XEM
9
+ def value
10
+ 0.15 * 1_000_000
11
+ end
12
+
13
+ # @return [Integer] fee in micro XEM
14
+ def to_i
15
+ value.to_i
16
+ end
17
+
18
+ # @return [Boolean]
19
+ def testnet?
20
+ @transaction.network == :testnet
21
+ end
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,28 @@
1
+ module Nem
2
+ module Fee
3
+ class MultisigAggregateModification
4
+ def initialize(transaction)
5
+ @transaction = transaction
6
+ end
7
+
8
+ # @return [Integer] fee in micro XEM
9
+ def value
10
+ if @transaction.min_cosignatories == 0
11
+ 0.5 * 1_000_000
12
+ else
13
+ 0.5 * 1_000_000
14
+ end
15
+ end
16
+
17
+ # @return [Integer] fee in micro XEM
18
+ def to_i
19
+ value.to_i
20
+ end
21
+
22
+ # @return [Boolean]
23
+ def testnet?
24
+ @transaction.network == :testnet
25
+ end
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,34 @@
1
+ module Nem
2
+ module Fee
3
+ class ProvisionNamespace
4
+ def initialize(transaction)
5
+ @transaction = transaction
6
+ end
7
+
8
+ # @return [Integer] fee in micro XEM
9
+ def value
10
+ @transaction.root? ? root_fee : sub_fee
11
+ end
12
+
13
+ # @return [Integer] fee in micro XEM
14
+ def to_i
15
+ value.to_i
16
+ end
17
+
18
+ # @return [Boolean]
19
+ def testnet?
20
+ @transaction.network == :testnet
21
+ end
22
+
23
+ private
24
+
25
+ def root_fee
26
+ 0.15 * 1_000_000
27
+ end
28
+
29
+ def sub_fee
30
+ 0.15 * 1_000_000
31
+ end
32
+ end
33
+ end
34
+ end
@@ -0,0 +1,66 @@
1
+ module Nem
2
+ module Fee
3
+ class Transfer
4
+ FEE_FACTOR = 0.05
5
+
6
+ def initialize(transaction)
7
+ @transaction = transaction
8
+ end
9
+
10
+ # @return [Integer] fee in micro XEM
11
+ def value
12
+ tmp = if @transaction.has_mosaics?
13
+ mosaics_fee
14
+ else
15
+ FEE_FACTOR * minimum_fee(@transaction.amount / 1_000_000)
16
+ end
17
+ tmp += message_fee if @transaction.has_message?
18
+ tmp * 1_000_000
19
+ end
20
+
21
+ # @return [Integer] fee in micro XEM
22
+ def to_i
23
+ value.to_i
24
+ end
25
+
26
+ # @return [Boolean]
27
+ def testnet?
28
+ @transaction.network == :testnet
29
+ end
30
+
31
+ private
32
+
33
+ def minimum_fee(base)
34
+ tmp = [1, base / 10_000].max
35
+ tmp > 25 ? 25 : tmp
36
+ end
37
+
38
+ def message_fee
39
+ FEE_FACTOR * [1, (@transaction.message.bytesize / 2 / 32) + 1].max
40
+ end
41
+
42
+ def mosaics_fee
43
+ FEE_FACTOR * @transaction.mosaics.inject(0) do |sum, moa|
44
+ tmp_fee = 0
45
+ if moa.divisibility == 0 && moa.initial_supply <= 10_000
46
+ # It is called *Small Business Mosaic Fee*
47
+ supply_related_adjustment = 0
48
+ tmp_fee = 1
49
+ else
50
+ # custom mosaic fee, Max is 1.25.
51
+ max_mosaic_quantity = 9_000_000_000_000_000
52
+ total_mosaic_quantity = moa.initial_supply * (10**moa.divisibility)
53
+ supply_related_adjustment = (0.8 * (Math.log(max_mosaic_quantity / total_mosaic_quantity))).floor
54
+ num_nem = if moa.initial_supply == 0
55
+ 0
56
+ else
57
+ 8_999_999_999.to_f * moa.quantity * 1_000_000 / moa.initial_supply / (10**(moa.divisibility + 6))
58
+ end
59
+ tmp_fee = minimum_fee(num_nem.ceil)
60
+ end
61
+ sum + [1, tmp_fee - supply_related_adjustment].max
62
+ end
63
+ end
64
+ end
65
+ end
66
+ end
@@ -0,0 +1,44 @@
1
+ require 'securerandom'
2
+
3
+ module Nem
4
+ class Keypair
5
+ attr_reader :private, :public
6
+
7
+ # @param [String] Hex Private Key
8
+ def initialize(private_key)
9
+ @private = private_key
10
+ @public = calc_public_key
11
+ end
12
+
13
+ # @param [String] Hex string
14
+ # @return [String] Signed hex string
15
+ def sign(data)
16
+ bin_data = Nem::Util::Convert.hex2bin(data)
17
+ bin_signed = Nem::Util::Ed25519.signature_hash_unsafe(bin_data, bin_secret, bin_public)
18
+ bin_signed.unpack('H*').first
19
+ end
20
+
21
+ # https://ryuta46.com/693
22
+ def self.generate(seed = SecureRandom.hex(64))
23
+ new(seed)
24
+ end
25
+
26
+ private
27
+
28
+ def fix_private_key(key)
29
+ "#{'0' * 64}#{key.sub(/^00/i, '')}"[-64, 64]
30
+ end
31
+
32
+ def calc_public_key
33
+ bin_public.unpack('H*').first
34
+ end
35
+
36
+ def bin_secret
37
+ @bin_secret ||= Nem::Util::Convert.hex2bin_rev(fix_private_key(@private))
38
+ end
39
+
40
+ def bin_public
41
+ @bin_public ||= Nem::Util::Ed25519.publickey_hash_unsafe(bin_secret)
42
+ end
43
+ end
44
+ end