nis-ruby 0.0.11.1 → 0.0.12
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 +4 -4
- data/.travis.yml +1 -1
- data/LICENSE +21 -0
- data/README.md +23 -43
- data/{samples/request_account.rb → examples/account.rb} +2 -10
- data/{samples/request_block.rb → examples/block.rb} +0 -0
- data/{samples/request_debug.rb → examples/debug.rb} +0 -8
- data/{samples/request_local.rb → examples/local.rb} +0 -5
- data/{samples/request_namespace.rb → examples/namespace.rb} +0 -3
- data/{samples/request_nis.rb → examples/nis.rb} +0 -0
- data/{samples/request_node.rb → examples/node.rb} +0 -9
- data/examples/shutdown.rb +6 -0
- data/examples/transactions/importance_transfer.rb +22 -0
- data/examples/transactions/mosaic_definition_creation.rb +50 -0
- data/examples/transactions/mosaic_supply_change.rb +24 -0
- data/examples/transactions/multisig.rb +26 -0
- data/examples/transactions/multisig_add_cosignatory.rb +31 -0
- data/examples/transactions/multisig_aggregate_modification.rb +28 -0
- data/examples/transactions/multisig_signature.rb +38 -0
- data/examples/transactions/provision_namespace.rb +19 -0
- data/examples/transactions/transfer.rb +22 -0
- data/lib/nis.rb +8 -4
- data/lib/nis/client.rb +2 -1
- data/lib/nis/endpoint/shutdown.rb +7 -0
- data/lib/nis/endpoint/transaction/announce.rb +1 -1
- data/lib/nis/endpoint/transaction/prepareAnnounce.rb +1 -1
- data/lib/nis/fee.rb +1 -0
- data/lib/nis/fee/importance_transfer.rb +22 -0
- data/lib/nis/fee/mosaic_definition_creation.rb +22 -0
- data/lib/nis/fee/mosaic_supply_change_transfer.rb +22 -0
- data/lib/nis/fee/multisig.rb +22 -0
- data/lib/nis/fee/multisig_aggregation_modification.rb +30 -0
- data/lib/nis/fee/provision_namespace.rb +32 -0
- data/lib/nis/fee/transfer.rb +51 -0
- data/lib/nis/keypair.rb +18 -0
- data/lib/nis/mixin/struct.rb +50 -0
- data/lib/nis/request.rb +1 -0
- data/lib/nis/request/announce.rb +10 -0
- data/lib/nis/request/prepare_announce.rb +48 -0
- data/lib/nis/struct/block.rb +1 -1
- data/lib/nis/struct/mosaic_properties.rb +2 -2
- data/lib/nis/transaction/importance_transfer.rb +25 -28
- data/lib/nis/transaction/mosaic_definition_creation.rb +33 -34
- data/lib/nis/transaction/mosaic_supply_change.rb +30 -30
- data/lib/nis/transaction/multisig.rb +17 -36
- data/lib/nis/transaction/multisig_aggregate_modification.rb +29 -31
- data/lib/nis/transaction/multisig_signature.rb +24 -23
- data/lib/nis/transaction/provision_namespace.rb +53 -33
- data/lib/nis/transaction/transfer.rb +22 -52
- data/lib/nis/util.rb +16 -13
- data/lib/nis/version.rb +1 -1
- data/nis.gemspec +2 -0
- metadata +62 -19
- data/lib/nis/mixin/network.rb +0 -20
- data/samples/request_importance_transfer_transaction.rb +0 -34
- data/samples/request_mosaic_definition_creation_transaction.rb +0 -62
- data/samples/request_mosaic_supply_change_transaction.rb +0 -35
- data/samples/request_multisig_add_cosignatory_transaction.rb +0 -58
- data/samples/request_multisig_aggregate_modification_transaction.rb +0 -45
- data/samples/request_multisig_signature_transaction.rb +0 -53
- data/samples/request_multisig_transaction.rb +0 -54
- data/samples/request_provision_namespace_transaction.rb +0 -31
- data/samples/request_transfer_transaction.rb +0 -47
@@ -0,0 +1,31 @@
|
|
1
|
+
require 'nis'
|
2
|
+
|
3
|
+
# Account A (multisig)
|
4
|
+
A_PUBLIC_KEY = '4b26a75313b747985470977a085ae6f840a0b84ebd96ddf17f4a31a2b580d078'
|
5
|
+
|
6
|
+
# Account B (cosignatory1)
|
7
|
+
B_PRIVATE_KEY = '260206d683962350532408e8774fd14870a173b7fba17f6b504da3dbc5f1cc9f'
|
8
|
+
B_PUBLIC_KEY = 'cc63b4dcdec745417043c3fa0992ec3a1695461a26d90264744648abbd5caa0d'
|
9
|
+
|
10
|
+
# Account C (cosignatory2)
|
11
|
+
C_PUBLIC_KEY = '9fd1e5e886c4006efc715a0e183f2a87f198b8d19c44e7c67925b01aa45a7114'
|
12
|
+
|
13
|
+
# TODO: public key calculated from private key in future version.
|
14
|
+
# it will not need to set public key.
|
15
|
+
kp = Nis::Keypair.new(B_PRIVATE_KEY, public_key: B_PUBLIC_KEY)
|
16
|
+
|
17
|
+
mcm = Nis::Struct::MultisigCosignatoryModification.new(
|
18
|
+
modificationType: 1,
|
19
|
+
cosignatoryAccount: C_PUBLIC_KEY
|
20
|
+
)
|
21
|
+
min_cosigs = 2
|
22
|
+
mtx = Nis::Transaction::MultisigAggregateModification.new([mcm], min_cosigs)
|
23
|
+
|
24
|
+
tx = Nis::Transaction::Multisig.new(mtx, A_PUBLIC_KEY)
|
25
|
+
|
26
|
+
nis = Nis.new
|
27
|
+
req = Nis::Request::PrepareAnnounce.new(tx, kp)
|
28
|
+
res = nis.transaction_prepare_announce(req)
|
29
|
+
|
30
|
+
puts "Message: #{res.message}"
|
31
|
+
puts "TransactionHash: #{res.transaction_hash}"
|
@@ -0,0 +1,28 @@
|
|
1
|
+
require 'nis'
|
2
|
+
|
3
|
+
# multisig
|
4
|
+
A_PRIVATE_KEY = '9bf8e6fd1a178a3cce39840cda34f80f55fe075c15f48eefad8506f4a70c2b47'
|
5
|
+
A_PUBLIC_KEY = '4b26a75313b747985470977a085ae6f840a0b84ebd96ddf17f4a31a2b580d078'
|
6
|
+
|
7
|
+
# cosignatory
|
8
|
+
B_PUBLIC_KEY = 'cc63b4dcdec745417043c3fa0992ec3a1695461a26d90264744648abbd5caa0d'
|
9
|
+
|
10
|
+
# TODO: public key calculated from private key in future version.
|
11
|
+
# it will not need to set public key.
|
12
|
+
kp = Nis::Keypair.new(A_PRIVATE_KEY, public_key: A_PUBLIC_KEY)
|
13
|
+
|
14
|
+
mcm = Nis::Struct::MultisigCosignatoryModification.new(
|
15
|
+
modificationType: 1,
|
16
|
+
cosignatoryAccount: B_PUBLIC_KEY
|
17
|
+
)
|
18
|
+
min_cosigs = 1
|
19
|
+
|
20
|
+
tx = Nis::Transaction::MultisigAggregateModification.new([mcm], min_cosigs)
|
21
|
+
puts "Fee: #{tx.fee.to_i}"
|
22
|
+
|
23
|
+
nis = Nis.new
|
24
|
+
req = Nis::Request::PrepareAnnounce.new(tx, kp)
|
25
|
+
res = nis.transaction_prepare_announce(req)
|
26
|
+
|
27
|
+
puts "Message: #{res.message}"
|
28
|
+
puts "TransactionHash: #{res.transaction_hash}"
|
@@ -0,0 +1,38 @@
|
|
1
|
+
require 'nis'
|
2
|
+
|
3
|
+
# multisig
|
4
|
+
A_PUBLIC_KEY = '4b26a75313b747985470977a085ae6f840a0b84ebd96ddf17f4a31a2b580d078'
|
5
|
+
A_ADDRESS = 'TBAOYZS4FGY5XPQ5OD2VL3SY7GQ5FLH66GRCX5DL'
|
6
|
+
|
7
|
+
# cosignatory1
|
8
|
+
# B_PRIVATE_KEY = '260206d683962350532408e8774fd14870a173b7fba17f6b504da3dbc5f1cc9f'
|
9
|
+
# B_PUBLIC_KEY = 'cc63b4dcdec745417043c3fa0992ec3a1695461a26d90264744648abbd5caa0d'
|
10
|
+
# B_ADDRESS = 'TAWKJTUP4DWKLDKKS534TYP6G324CBNMXKBA4X7B'
|
11
|
+
|
12
|
+
# cosignatory2
|
13
|
+
C_PRIVATE_KEY = '2f6bececfaa81e0ce878be6263df29d11412559132743eebde99f695fbc4e288'
|
14
|
+
C_PUBLIC_KEY = '9fd1e5e886c4006efc715a0e183f2a87f198b8d19c44e7c67925b01aa45a7114'
|
15
|
+
C_ADDRESS = 'TAFPFQOTRYEKMKWWKLLLMYA3I5SCFDGYFACCOFWS'
|
16
|
+
|
17
|
+
# TODO: public key calculated from private key in future version.
|
18
|
+
# it will not need to set public key.
|
19
|
+
kp = Nis::Keypair.new(C_PRIVATE_KEY, public_key: C_PUBLIC_KEY)
|
20
|
+
|
21
|
+
nis = Nis.new
|
22
|
+
txes = nis.account_unconfirmed_transactions(address: C_ADDRESS)
|
23
|
+
|
24
|
+
unless txes.size > 0
|
25
|
+
puts 'There are no transactions to sign.'
|
26
|
+
exit
|
27
|
+
end
|
28
|
+
|
29
|
+
hash = txes.first.meta.data
|
30
|
+
puts "Unconfirmed Transaction Hash: #{hash}"
|
31
|
+
|
32
|
+
tx = Nis::Transaction::MultisigSignature.new(hash, A_ADDRESS, C_PUBLIC_KEY)
|
33
|
+
|
34
|
+
req = Nis::Request::PrepareAnnounce.new(tx, kp)
|
35
|
+
res = nis.transaction_prepare_announce(req)
|
36
|
+
|
37
|
+
puts "Message: #{res.message}"
|
38
|
+
puts "TransactionHash: #{res.transaction_hash}"
|
@@ -0,0 +1,19 @@
|
|
1
|
+
require 'nis'
|
2
|
+
|
3
|
+
# owner
|
4
|
+
A_PRIVATE_KEY = '260206d683962350532408e8774fd14870a173b7fba17f6b504da3dbc5f1cc9f'
|
5
|
+
A_PUBLIC_KEY = 'cc63b4dcdec745417043c3fa0992ec3a1695461a26d90264744648abbd5caa0d'
|
6
|
+
|
7
|
+
# TODO: public key calculated from private key in future version.
|
8
|
+
# it will not need to set public key.
|
9
|
+
kp = Nis::Keypair.new(A_PRIVATE_KEY, public_key: A_PUBLIC_KEY)
|
10
|
+
|
11
|
+
tx = Nis::Transaction::ProvisionNamespace.new('sushi')
|
12
|
+
puts "Fee: #{tx.fee.to_i}"
|
13
|
+
|
14
|
+
nis = Nis.new
|
15
|
+
req = Nis::Request::PrepareAnnounce.new(tx, kp)
|
16
|
+
res = nis.transaction_prepare_announce(req)
|
17
|
+
|
18
|
+
puts "Message: #{res.message}"
|
19
|
+
puts "TransactionHash: #{res.transaction_hash}"
|
@@ -0,0 +1,22 @@
|
|
1
|
+
require 'nis'
|
2
|
+
|
3
|
+
# sender
|
4
|
+
A_PRIVATE_KEY = '260206d683962350532408e8774fd14870a173b7fba17f6b504da3dbc5f1cc9f'
|
5
|
+
A_PUBLIC_KEY = 'cc63b4dcdec745417043c3fa0992ec3a1695461a26d90264744648abbd5caa0d'
|
6
|
+
|
7
|
+
# receiver
|
8
|
+
B_ADDRESS = 'TAWKJTUP4DWKLDKKS534TYP6G324CBNMXKBA4X7B'
|
9
|
+
|
10
|
+
# TODO: public key calculated from private key in future version.
|
11
|
+
# it will not need to set public key.
|
12
|
+
kp = Nis::Keypair.new(A_PRIVATE_KEY, public_key: A_PUBLIC_KEY)
|
13
|
+
|
14
|
+
tx = Nis::Transaction::Transfer.new(B_ADDRESS, 1_000_000, 'Good luck!')
|
15
|
+
puts "Fee: #{tx.fee.to_i}"
|
16
|
+
|
17
|
+
nis = Nis.new
|
18
|
+
req = Nis::Request::PrepareAnnounce.new(tx, kp)
|
19
|
+
res = nis.transaction_prepare_announce(req)
|
20
|
+
|
21
|
+
puts "Message: #{res.message}"
|
22
|
+
puts "TransactionHash: #{res.transaction_hash}"
|
data/lib/nis.rb
CHANGED
@@ -1,7 +1,10 @@
|
|
1
1
|
require 'nis/version'
|
2
2
|
require 'nis/mixin'
|
3
3
|
require 'nis/util'
|
4
|
+
require 'nis/keypair'
|
5
|
+
require 'nis/fee'
|
4
6
|
require 'nis/client'
|
7
|
+
require 'nis/request'
|
5
8
|
require 'nis/endpoint'
|
6
9
|
require 'nis/struct'
|
7
10
|
require 'nis/transaction'
|
@@ -15,17 +18,18 @@ class Nis
|
|
15
18
|
def_delegators :@client, :request, :request!
|
16
19
|
|
17
20
|
# @param [hash] options HTTP Client connection information
|
18
|
-
# @option options [
|
19
|
-
# @option options [
|
21
|
+
# @option options [String] :url URL
|
22
|
+
# @option options [String] :scheme default http
|
20
23
|
# @option options [Symbol] :host default 127.0.0.1
|
21
|
-
# @option options [
|
22
|
-
# @option options [
|
24
|
+
# @option options [Integer] :port default 7890
|
25
|
+
# @option options [Integer] :timeout default 5
|
23
26
|
def initialize(options = {})
|
24
27
|
@client = Client.new(options)
|
25
28
|
end
|
26
29
|
|
27
30
|
include Nis::Endpoint::Heartbeat
|
28
31
|
include Nis::Endpoint::Status
|
32
|
+
include Nis::Endpoint::Shutdown
|
29
33
|
|
30
34
|
include Nis::Endpoint::Account::Generate
|
31
35
|
include Nis::Endpoint::Account::Get
|
data/lib/nis/client.rb
CHANGED
@@ -3,7 +3,7 @@ module Nis::Endpoint
|
|
3
3
|
# @param [Nis::Struct::RequestAnnounce] request_announce
|
4
4
|
# @return [Nis::Struct::Node]
|
5
5
|
# @see http://bob.nem.ninja/docs/#sending-the-data-to-NIS
|
6
|
-
def transaction_announce(request_announce
|
6
|
+
def transaction_announce(request_announce)
|
7
7
|
Nis::Struct::NemAnnounceResult.build request!(:post,
|
8
8
|
'/transaction/announce',
|
9
9
|
request_announce
|
@@ -3,7 +3,7 @@ module Nis::Endpoint
|
|
3
3
|
# @param [Nis::Struct::RequestPrepareAnnounce] request_prepare_announce
|
4
4
|
# @return [Nis::Struct::Node]
|
5
5
|
# @see http://bob.nem.ninja/docs/#initiating-a-transaction
|
6
|
-
def transaction_prepare_announce(request_prepare_announce
|
6
|
+
def transaction_prepare_announce(request_prepare_announce)
|
7
7
|
Nis::Struct::NemAnnounceResult.build request!(:post,
|
8
8
|
'/transaction/prepare-announce',
|
9
9
|
request_prepare_announce
|
data/lib/nis/fee.rb
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
Dir[File.expand_path('../fee/*.rb', __FILE__)].each { |f| require f }
|
@@ -0,0 +1,22 @@
|
|
1
|
+
class Nis::Fee
|
2
|
+
class ImportanceTransfer
|
3
|
+
def initialize(transaction)
|
4
|
+
@transaction = transaction
|
5
|
+
end
|
6
|
+
|
7
|
+
# @return [Integer] fee in micro XEM
|
8
|
+
def value
|
9
|
+
testnet? ? 0.15 * 1_000_000 : 6_000_000
|
10
|
+
end
|
11
|
+
|
12
|
+
# @return [Integer] fee in micro XEM
|
13
|
+
def to_i
|
14
|
+
value.to_i
|
15
|
+
end
|
16
|
+
|
17
|
+
# @return [Boolean]
|
18
|
+
def testnet?
|
19
|
+
@transaction.network == :testnet
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
class Nis::Fee
|
2
|
+
class MosaicDefinitionCreation
|
3
|
+
def initialize(transaction)
|
4
|
+
@transaction = transaction
|
5
|
+
end
|
6
|
+
|
7
|
+
# @return [Integer] fee in micro XEM
|
8
|
+
def value
|
9
|
+
(testnet? ? 10 : 500) * 1_000_000
|
10
|
+
end
|
11
|
+
|
12
|
+
# @return [Integer] fee in micro XEM
|
13
|
+
def to_i
|
14
|
+
value.to_i
|
15
|
+
end
|
16
|
+
|
17
|
+
# @return [Boolean]
|
18
|
+
def testnet?
|
19
|
+
@transaction.network == :testnet
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
class Nis::Fee
|
2
|
+
class MosaicSupplyChangeTransfer
|
3
|
+
def initialize(transaction)
|
4
|
+
@transaction = transaction
|
5
|
+
end
|
6
|
+
|
7
|
+
# @return [Integer] fee in micro XEM
|
8
|
+
def value
|
9
|
+
testnet? ? 0.15 * 1_000_000 : 20 * 1_000_000
|
10
|
+
end
|
11
|
+
|
12
|
+
# @return [Integer] fee in micro XEM
|
13
|
+
def to_i
|
14
|
+
value.to_i
|
15
|
+
end
|
16
|
+
|
17
|
+
# @return [Boolean]
|
18
|
+
def testnet?
|
19
|
+
@transaction.network == :testnet
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
class Nis::Fee
|
2
|
+
class Multisig
|
3
|
+
def initialize(transaction)
|
4
|
+
@transaction = transaction
|
5
|
+
end
|
6
|
+
|
7
|
+
# @return [Integer] fee in micro XEM
|
8
|
+
def value
|
9
|
+
testnet? ? 0.15 * 1_000_000 : 6_000_000
|
10
|
+
end
|
11
|
+
|
12
|
+
# @return [Integer] fee in micro XEM
|
13
|
+
def to_i
|
14
|
+
value.to_i
|
15
|
+
end
|
16
|
+
|
17
|
+
# @return [Boolean]
|
18
|
+
def testnet?
|
19
|
+
@transaction.network == :testnet
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
class Nis::Fee
|
2
|
+
class MultisigAggregateModification
|
3
|
+
def initialize(transaction)
|
4
|
+
@transaction = transaction
|
5
|
+
end
|
6
|
+
|
7
|
+
# @return [Integer] fee in micro XEM
|
8
|
+
def value
|
9
|
+
if @transaction.minCosignatories == 0
|
10
|
+
testnet? ?
|
11
|
+
0.5 * 1_000_000 :
|
12
|
+
(10 + 6 * @transaction.modifications.length) * 1_000_000
|
13
|
+
else
|
14
|
+
testnet? ?
|
15
|
+
0.5 * 1_000_000 :
|
16
|
+
(10 + 6 * @transaction.modifications.length + 6) * 1_000_000
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
# @return [Integer] fee in micro XEM
|
21
|
+
def to_i
|
22
|
+
value.to_i
|
23
|
+
end
|
24
|
+
|
25
|
+
# @return [Boolean]
|
26
|
+
def testnet?
|
27
|
+
@transaction.network == :testnet
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
class Nis::Fee
|
2
|
+
class ProvisionNamespace
|
3
|
+
def initialize(transaction)
|
4
|
+
@transaction = transaction
|
5
|
+
end
|
6
|
+
|
7
|
+
# @return [Integer] fee in micro XEM
|
8
|
+
def value
|
9
|
+
@transaction.root? ? root_fee : sub_fee
|
10
|
+
end
|
11
|
+
|
12
|
+
# @return [Integer] fee in micro XEM
|
13
|
+
def to_i
|
14
|
+
value.to_i
|
15
|
+
end
|
16
|
+
|
17
|
+
# @return [Boolean]
|
18
|
+
def testnet?
|
19
|
+
@transaction.network == :testnet
|
20
|
+
end
|
21
|
+
|
22
|
+
private
|
23
|
+
|
24
|
+
def root_fee
|
25
|
+
(testnet? ? 100 : 5_000) * 1_000_000
|
26
|
+
end
|
27
|
+
|
28
|
+
def sub_fee
|
29
|
+
(testnet? ? 10 : 200) * 1_000_000
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
@@ -0,0 +1,51 @@
|
|
1
|
+
class Nis::Fee
|
2
|
+
class Transfer
|
3
|
+
def initialize(transaction)
|
4
|
+
@transaction = transaction
|
5
|
+
end
|
6
|
+
|
7
|
+
# @return [Integer] fee in micro XEM
|
8
|
+
def value
|
9
|
+
tmp = 0
|
10
|
+
|
11
|
+
if @transaction.mosaics.empty?
|
12
|
+
tmp += min_fee
|
13
|
+
else
|
14
|
+
tmp += mosaics_fee
|
15
|
+
end
|
16
|
+
|
17
|
+
if @transaction.message.bytesize > 0
|
18
|
+
tmp += message_fee
|
19
|
+
end
|
20
|
+
|
21
|
+
tmp * 1_000_000
|
22
|
+
end
|
23
|
+
|
24
|
+
# @return [Integer] fee in micro XEM
|
25
|
+
def to_i
|
26
|
+
value.to_i
|
27
|
+
end
|
28
|
+
|
29
|
+
# @return [Boolean]
|
30
|
+
def testnet?
|
31
|
+
@transaction.network == :testnet
|
32
|
+
end
|
33
|
+
|
34
|
+
private
|
35
|
+
|
36
|
+
def min_fee
|
37
|
+
tmp = [1, @transaction.amount / 1_000_000 / 10_000].max
|
38
|
+
tmp = (tmp > 25 ? 25 : tmp)
|
39
|
+
testnet? ? 0.05 * tmp : tmp
|
40
|
+
end
|
41
|
+
|
42
|
+
def message_fee
|
43
|
+
tmp = [1, (@transaction.message.bytesize / 2 / 32) + 1].max
|
44
|
+
testnet? ? 0.05 * tmp : tmp
|
45
|
+
end
|
46
|
+
|
47
|
+
def mosaics_fee
|
48
|
+
raise NotImplementedError, 'not implemented calculation mosaics fee.'
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
data/lib/nis/keypair.rb
ADDED
@@ -0,0 +1,18 @@
|
|
1
|
+
class Nis
|
2
|
+
class Keypair
|
3
|
+
attr_reader :private, :public
|
4
|
+
|
5
|
+
def initialize(private_key, public_key: nil)
|
6
|
+
@private = private_key
|
7
|
+
@public = public_key
|
8
|
+
end
|
9
|
+
|
10
|
+
def fix_private_key(key)
|
11
|
+
"#{'0' * 64}#{key.sub(/^00/i, '')}"[-64, 64]
|
12
|
+
end
|
13
|
+
|
14
|
+
def calc_pubkey
|
15
|
+
# TODO: calculate pubkey from privkey
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|