round 0.7.0 → 0.8.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- checksums.yaml.gz.sig +0 -0
- data.tar.gz.sig +2 -3
- data/README.md +14 -14
- data/lib/round/account.rb +6 -4
- data/lib/round/client.rb +3 -17
- data/lib/round/transaction.rb +3 -2
- data/lib/round/user.rb +2 -3
- data/lib/round/version.rb +2 -2
- data/lib/round/wallet.rb +10 -10
- metadata +10 -10
- metadata.gz.sig +1 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: eb0ea3854098e41908e3d476e21df3ce5165dec2
|
4
|
+
data.tar.gz: f5aac8616931dd4a58c02e3b4f86882e4d716e26
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: ddadccacbd118d36974beb5f899187a7f88999ad2a0302a26bc81a2d031bc3f459f6724453a0a906d548f3d16df21e59706c9a376d222484e260f30d1385b422
|
7
|
+
data.tar.gz: 6d8edb4aed48f73e8d0a6c9c2bd0c724d631310ed03d76ff9d58d949a066b68d417b31de372aaadf9100103d1bfaead79c3d7918ed62fef26c6f048af8a3d6ff
|
checksums.yaml.gz.sig
CHANGED
Binary file
|
data.tar.gz.sig
CHANGED
@@ -1,3 +1,2 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
;��#e�_�j�~+/�ӆ��7�M��BYh���Y�dgt���^�1���
|
1
|
+
V�B�>�2�:
|
2
|
+
�eP����;��V�����yJ�JE�����m_A�=�����iҡ�(�z�^�P�e�ޱn˵ch���]=���{Р~/KG��eU���b�ΜYX{H�8���͉k��.�6~š�`��KDgL���{�/�m�aN����R�i*��b`iݽ�[���Ȥsq��X5�ga3Y������)�����J������17J��K����������|���!I�SU\�l�+�.���n����B����ď3ո
|
data/README.md
CHANGED
@@ -58,23 +58,17 @@ In this step you will learn how to instantiate the API client for the given netw
|
|
58
58
|
> require 'round'
|
59
59
|
```
|
60
60
|
|
61
|
-
1. Create the client object
|
61
|
+
1. Create the client object.
|
62
62
|
|
63
63
|
```ruby
|
64
|
-
|
65
|
-
client = Round.client
|
66
|
-
|
67
|
-
# if you want to configure the client for production mainnet
|
68
|
-
client = Round.client(:mainnet)
|
64
|
+
client = Round.client
|
69
65
|
```
|
70
66
|
|
71
67
|
[[top]](README.md#getting-started-tutorial)
|
72
68
|
|
73
|
-
### 2. Configure your
|
69
|
+
### 2. Configure your application and API Token
|
74
70
|
In this step your application and you will retrieve the API Token for the application and set your applications redirect url. The url is used to push the user back to your app after they complete an out of band challenge.
|
75
71
|
|
76
|
-
1. Set the redirect url by clicking in the options gear and selecting `add redirect url`
|
77
|
-
|
78
72
|
1. In the [console](https://sandbox.gem.co) copy your `api_token` by clicking on show
|
79
73
|
|
80
74
|
1. Go back to your shell session and set a variable for `api_token`
|
@@ -89,6 +83,12 @@ In this step your application and you will retrieve the API Token for the applic
|
|
89
83
|
### 3. Create your User and Wallet
|
90
84
|
In this step you will create your own personal Gem user and wallet authorized on your application. This is an end-user account, which will have a 2-of-3 multisig bitcoin wallet.
|
91
85
|
|
86
|
+
1. Authenticate your client
|
87
|
+
|
88
|
+
```ruby
|
89
|
+
client.authenticate_identify(api_token: api_token)
|
90
|
+
```
|
91
|
+
|
92
92
|
1. Create your user and wallet:
|
93
93
|
|
94
94
|
```ruby
|
@@ -99,12 +99,12 @@ In this step you will create your own personal Gem user and wallet authorized on
|
|
99
99
|
email: 'YOUR EMAIL ADDRESS',
|
100
100
|
passphrase: 'aReallyStrongPassphrase',
|
101
101
|
device_name: 'SOME DEVICE NAME',
|
102
|
-
redirect_uri: 'http://something/user-device-approved')
|
102
|
+
redirect_uri: 'http://something.com/user-device-approved')
|
103
103
|
)
|
104
104
|
```
|
105
105
|
|
106
|
-
|
107
|
-
|
106
|
+
1. Your application should **store the device_token permanently** as this will be required to authenticate from your app as this user.
|
107
|
+
1. You (acting as a user) will receive an email from Gem asking you to confirm your account and finish setup. Please follow the instructions. At the end of the User sign up flow, you'll be redirected to the redirect_uri provided in users.create (if you provided one).
|
108
108
|
|
109
109
|
[[top]](README.md#getting-started-tutorial)
|
110
110
|
|
@@ -161,12 +161,12 @@ In this section you’ll learn how to create a payment a multi-signature payment
|
|
161
161
|
1. Unlock the wallet:
|
162
162
|
|
163
163
|
```ruby
|
164
|
-
wallet.unlock(<YOUR PASSWORD>)
|
164
|
+
my_account.wallet.unlock(<YOUR PASSWORD>)
|
165
165
|
```
|
166
166
|
1. Make a payment
|
167
167
|
|
168
168
|
```ruby
|
169
|
-
transaction =
|
169
|
+
transaction = my_account.pay([{address: 'mxzdT4ShBudVtZbMqPMh9NVM3CS56Fp11s', amount: 25000}], 1, 'http://some-redirect-uri.com/')
|
170
170
|
puts transaction.mfa_uri # redirect your user to this URI to complete payment!
|
171
171
|
```
|
172
172
|
|
data/lib/round/account.rb
CHANGED
@@ -20,11 +20,10 @@ module Round
|
|
20
20
|
end
|
21
21
|
|
22
22
|
def pay(payees, confirmations, redirect_uri = nil, mfa_token: nil)
|
23
|
-
raise ArgumentError, 'Payees must be specified' unless payees
|
24
23
|
raise 'You must unlock the wallet before attempting a transaction' unless @wallet.multiwallet
|
25
24
|
|
26
25
|
payment = self.transactions.create(payees, confirmations, redirect_uri: redirect_uri)
|
27
|
-
signed = payment.sign(@wallet.multiwallet)
|
26
|
+
signed = payment.sign(@wallet.multiwallet, network: network.to_sym)
|
28
27
|
if wallet.application
|
29
28
|
mfa_token = mfa_token || @wallet.application.get_mfa
|
30
29
|
signed.approve(mfa_token)
|
@@ -51,8 +50,11 @@ module Round
|
|
51
50
|
Round::Account
|
52
51
|
end
|
53
52
|
|
54
|
-
def create(name)
|
55
|
-
|
53
|
+
def create(name:, network:)
|
54
|
+
unless [:bitcoin_testnet, :bitcoin, :litecoin, :dogecoin].include?(network)
|
55
|
+
raise ArgumentError, 'Network must be :bitcoin_testnet, :dogecoin, :litecoin, :bitcoin.'
|
56
|
+
end
|
57
|
+
resource = @resource.create(name: name, network: network)
|
56
58
|
account = Round::Account.new(resource: resource, wallet: @wallet, client: @client)
|
57
59
|
add(account)
|
58
60
|
account
|
data/lib/round/client.rb
CHANGED
@@ -7,30 +7,16 @@ module Round
|
|
7
7
|
MAINNET_URL = 'https://api.gem.co'
|
8
8
|
SANDBOX_URL = 'https://api-sandbox.gem.co'
|
9
9
|
|
10
|
-
|
11
|
-
testnet: :bitcoin_testnet,
|
12
|
-
bitcoin_testnet: :bitcoin_testnet,
|
13
|
-
testnet3: :bitcoin_testnet,
|
14
|
-
bitcoin: :bitcoin,
|
15
|
-
mainnet: :bitcoin,
|
16
|
-
}
|
17
|
-
|
18
|
-
def self.client(network = :bitcoin_testnet, url = nil)
|
19
|
-
network = NETWORKS.fetch(network, :bitcoin_testnet)
|
20
|
-
url ||= network == :bitcoin_testnet ? SANDBOX_URL : MAINNET_URL
|
21
|
-
|
10
|
+
def self.client(url = MAINNET_URL)
|
22
11
|
@patchboard ||= ::Patchboard.discover(url) { Client::Context.new }
|
23
|
-
Client.new(@patchboard.spawn
|
12
|
+
Client.new(@patchboard.spawn)
|
24
13
|
end
|
25
14
|
|
26
15
|
class Client
|
27
16
|
include Round::Helpers
|
28
17
|
|
29
|
-
|
30
|
-
|
31
|
-
def initialize(patchboard_client, network)
|
18
|
+
def initialize(patchboard_client)
|
32
19
|
@patchboard_client = patchboard_client
|
33
|
-
@network = network
|
34
20
|
end
|
35
21
|
|
36
22
|
def authenticate_application(api_token:, admin_token:)
|
data/lib/round/transaction.rb
CHANGED
@@ -1,11 +1,12 @@
|
|
1
1
|
module Round
|
2
2
|
class Transaction < Round::Base
|
3
3
|
|
4
|
-
def sign(wallet)
|
4
|
+
def sign(wallet, network:)
|
5
5
|
raise 'transaction is already signed' unless @resource['status'] == 'unsigned'
|
6
6
|
raise 'a wallet is required to sign a transaction' unless wallet
|
7
|
+
network = :testnet3 if network == :bitcoin_testnet
|
7
8
|
|
8
|
-
transaction = CoinOp::Bit::Transaction.data(@resource)
|
9
|
+
transaction = CoinOp::Bit::Transaction.data(@resource, network: network)
|
9
10
|
raise 'bad change address' unless wallet.valid_output?(transaction.outputs.last)
|
10
11
|
|
11
12
|
@resource = @resource.update(
|
data/lib/round/user.rb
CHANGED
@@ -30,13 +30,12 @@ module Round
|
|
30
30
|
|
31
31
|
def create(first_name:, last_name:, email:, passphrase:,
|
32
32
|
device_name:, redirect_uri: nil)
|
33
|
-
multiwallet = CoinOp::Bit::MultiWallet.generate([:primary]
|
33
|
+
multiwallet = CoinOp::Bit::MultiWallet.generate([:primary])
|
34
34
|
primary_seed = CoinOp::Encodings.hex(multiwallet.trees[:primary].seed)
|
35
35
|
encrypted_seed = CoinOp::Crypto::PassphraseBox.encrypt(passphrase, primary_seed)
|
36
36
|
wallet = {
|
37
37
|
name: 'default',
|
38
|
-
|
39
|
-
primary_public_seed: multiwallet.trees[:primary].to_serialized_address,
|
38
|
+
primary_public_seed: multiwallet.trees[:primary].to_bip32,
|
40
39
|
primary_private_seed: encrypted_seed
|
41
40
|
}
|
42
41
|
params = {
|
data/lib/round/version.rb
CHANGED
@@ -1,3 +1,3 @@
|
|
1
1
|
module Round
|
2
|
-
VERSION = "0.
|
3
|
-
end
|
2
|
+
VERSION = "0.8.0"
|
3
|
+
end
|
data/lib/round/wallet.rb
CHANGED
@@ -23,10 +23,6 @@ module Round
|
|
23
23
|
)
|
24
24
|
end
|
25
25
|
|
26
|
-
def backup_key
|
27
|
-
@multiwallet.private_seed(:backup)
|
28
|
-
end
|
29
|
-
|
30
26
|
def accounts
|
31
27
|
Round::AccountCollection.new(
|
32
28
|
resource: @resource.accounts,
|
@@ -53,7 +49,12 @@ module Round
|
|
53
49
|
|
54
50
|
def create(name, passphrase, network: 'bitcoin_testnet',
|
55
51
|
multiwallet: CoinOp::Bit::MultiWallet.generate([:primary, :backup]))
|
56
|
-
|
52
|
+
backup = multiwallet.private_seed(:backup, network: :bitcoin)
|
53
|
+
multiwallet.drop_private(:backup)
|
54
|
+
backup_master = multiwallet.trees[:backup]
|
55
|
+
new_bmaster = MoneyTree::Master.new(public_key: backup_master.public_key, chain_code: backup_master.chain_code)
|
56
|
+
multiwallet.trees[:backup] = new_bmaster
|
57
|
+
wallet_resource = create_wallet_resource(multiwallet, passphrase, name)
|
57
58
|
multiwallet.import(
|
58
59
|
cosigner_public_seed: wallet_resource.cosigner_public_seed
|
59
60
|
)
|
@@ -64,19 +65,18 @@ module Round
|
|
64
65
|
client: @client
|
65
66
|
)
|
66
67
|
add(wallet)
|
67
|
-
wallet
|
68
|
+
[backup, wallet]
|
68
69
|
end
|
69
70
|
|
70
|
-
def create_wallet_resource(multiwallet, passphrase, name
|
71
|
+
def create_wallet_resource(multiwallet, passphrase, name)
|
71
72
|
primary_seed = CoinOp::Encodings.hex(multiwallet.trees[:primary].seed)
|
72
73
|
## Encrypt the primary seed using a passphrase-derived key
|
73
74
|
encrypted_seed = CoinOp::Crypto::PassphraseBox.encrypt(passphrase, primary_seed)
|
74
75
|
|
75
76
|
@resource.create(
|
76
77
|
name: name,
|
77
|
-
|
78
|
-
|
79
|
-
primary_public_seed: multiwallet.trees[:primary].to_serialized_address,
|
78
|
+
backup_public_seed: multiwallet.trees[:backup].to_bip32,
|
79
|
+
primary_public_seed: multiwallet.trees[:primary].to_bip32,
|
80
80
|
primary_private_seed: encrypted_seed
|
81
81
|
)
|
82
82
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: round
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.8.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Matthew King
|
@@ -31,7 +31,7 @@ cert_chain:
|
|
31
31
|
tdc4VS7IlSRxlZ3dBOgiigy9GXpJ+7F831AqjxL39EPwdr7RguTNz+pi//RKaT/U
|
32
32
|
IlpVB+Xfk0vQdP7iYfjGxDzUf0FACMjsR95waJmadKW1Iy6STw2hwPhYIQz1Hu1A
|
33
33
|
-----END CERTIFICATE-----
|
34
|
-
date: 2015-05-
|
34
|
+
date: 2015-05-28 00:00:00.000000000 Z
|
35
35
|
dependencies:
|
36
36
|
- !ruby/object:Gem::Dependency
|
37
37
|
name: patchboard
|
@@ -81,42 +81,42 @@ dependencies:
|
|
81
81
|
requirements:
|
82
82
|
- - "~>"
|
83
83
|
- !ruby/object:Gem::Version
|
84
|
-
version:
|
84
|
+
version: 3.1.0
|
85
85
|
type: :runtime
|
86
86
|
prerelease: false
|
87
87
|
version_requirements: !ruby/object:Gem::Requirement
|
88
88
|
requirements:
|
89
89
|
- - "~>"
|
90
90
|
- !ruby/object:Gem::Version
|
91
|
-
version:
|
91
|
+
version: 3.1.0
|
92
92
|
- !ruby/object:Gem::Dependency
|
93
93
|
name: rbnacl-libsodium
|
94
94
|
requirement: !ruby/object:Gem::Requirement
|
95
95
|
requirements:
|
96
96
|
- - "~>"
|
97
97
|
- !ruby/object:Gem::Version
|
98
|
-
version:
|
98
|
+
version: 1.0.0
|
99
99
|
type: :runtime
|
100
100
|
prerelease: false
|
101
101
|
version_requirements: !ruby/object:Gem::Requirement
|
102
102
|
requirements:
|
103
103
|
- - "~>"
|
104
104
|
- !ruby/object:Gem::Version
|
105
|
-
version:
|
105
|
+
version: 1.0.0
|
106
106
|
- !ruby/object:Gem::Dependency
|
107
107
|
name: coin-op
|
108
108
|
requirement: !ruby/object:Gem::Requirement
|
109
109
|
requirements:
|
110
|
-
- -
|
110
|
+
- - '='
|
111
111
|
- !ruby/object:Gem::Version
|
112
|
-
version:
|
112
|
+
version: 0.4.3
|
113
113
|
type: :runtime
|
114
114
|
prerelease: false
|
115
115
|
version_requirements: !ruby/object:Gem::Requirement
|
116
116
|
requirements:
|
117
|
-
- -
|
117
|
+
- - '='
|
118
118
|
- !ruby/object:Gem::Version
|
119
|
-
version:
|
119
|
+
version: 0.4.3
|
120
120
|
- !ruby/object:Gem::Dependency
|
121
121
|
name: rspec
|
122
122
|
requirement: !ruby/object:Gem::Requirement
|
metadata.gz.sig
CHANGED
@@ -1 +1 @@
|
|
1
|
-
|
1
|
+
�U�R̟�r���]��7�����o�<��Mo�1"��������o0G�5�����,�j�3A3����`l���=��P�a@ ���ZG�����6�=s=���w��f���8��ސ��qe;;��j��#�%��E�pL�_#rW�"�L(�gg����ά�ܗ�]�@sSn��<�����k�Ai6��V��M��)J+�x��|�T_tR��A���O�V�kϲ0
|