bitgo 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (4) hide show
  1. checksums.yaml +7 -0
  2. data/lib/bitgo.rb +4 -0
  3. data/lib/bitgo/v1/api.rb +381 -0
  4. metadata +46 -0
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: eacf7a690a88c6efe13a5e613563fc335606d579
4
+ data.tar.gz: 286fab1ff4120545d9d2df678e0f981a06afd83a
5
+ SHA512:
6
+ metadata.gz: fb4021f533f9ed0b254a8f03fb883f323e1d96811ff609048d9702e03e811da335a45729620cfd08a5d2d97e173f207fcaf56848707b7c278620f9705fb1cbe6
7
+ data.tar.gz: dd437af6975095809f7a22718947d906890f1437afc266a9b0108efc93da88e509f62cca791bb90886b38cb941589a07d16b204ccc809491f61747802627f60b
@@ -0,0 +1,4 @@
1
+ require 'bitgo/v1/api'
2
+ require 'uri'
3
+ require 'net/http'
4
+ require 'json'
@@ -0,0 +1,381 @@
1
+ module Bitgo
2
+ module V1
3
+
4
+ class ApiError < RuntimeError; end
5
+
6
+ class Api
7
+
8
+ attr_accessor :session_token
9
+
10
+ TEST = 'https://test.bitgo.com/api/v1'
11
+ LIVE = 'https://bitgo.com/api/v1'
12
+ EXPRESS = 'http://127.0.0.1:3080/api/v1'
13
+
14
+ def initialize(end_point)
15
+ @end_point = end_point
16
+ end
17
+
18
+ ###############
19
+ # User APIs
20
+ ###############
21
+
22
+ def session_info
23
+ call :get, '/user/session'
24
+ end
25
+
26
+ # Get a token for first-party access to the BitGo API. First-party access is only intended for users accessing their own BitGo accounts.
27
+ # For 3rd party access to the BitGo API on behalf of another user, please see Partner Authentication.
28
+ def login(email: email, password: password, otp: otp)
29
+ login_params = {
30
+ email: email,
31
+ password: password,
32
+ otp: otp
33
+ }
34
+
35
+ with_auth_token = false
36
+ parse_response_as_json = true
37
+
38
+ call :post, '/user/login', login_params, parse_response_as_json, with_auth_token
39
+ end
40
+
41
+ # Get a token for first-party access to the BitGo API. First-party access is only intended for users accessing their own BitGo accounts.
42
+ # For 3rd party access to the BitGo API on behalf of another user, please see Partner Authentication.
43
+ def logout
44
+ call :get, '/user/logout'
45
+ end
46
+
47
+ def send_otp(force_sms: false)
48
+ call :post, '/user/sendotp', forceSMS: force_sms
49
+ end
50
+
51
+ def session_information
52
+ call :get, '/user/session'
53
+ end
54
+
55
+ def unlock(otp: otp, duration_seconds: duration_seconds)
56
+ unlock_params = {
57
+ otp: otp,
58
+ duration: duration_seconds
59
+ }
60
+ call :post, '/user/unlock', unlock_params
61
+ end
62
+
63
+ def lock
64
+ call :post, '/user/lock'
65
+ end
66
+
67
+ ###############
68
+ # Keychains API
69
+ ###############
70
+
71
+ def list_keychains
72
+ call :get, '/keychain'
73
+ end
74
+
75
+ # Bitgo express function
76
+ # Client-side function to create a new keychain.
77
+ # Optionally, a single parameter, 'seed’, may be provided which uses a deterministic seed to create your keychain. The seed should be an array of numbers at least 32 elements long. Calling this function with the same seed will generate the same BIP32 keychain.
78
+ def create_keychain(seed: nil)
79
+
80
+ if seed.present?
81
+ seed.scan(/../).map(&:hex)
82
+ [seed].pack('H*').unpack('C*')
83
+ seed_arr = [seed].pack('H*').bytes.to_a
84
+ call :post, '/keychain/local', { seed: seed_arr }
85
+ else
86
+ call :post, '/keychain/local'
87
+ end
88
+ end
89
+
90
+ def add_keychain(xpub: xpub, encrypted_xprv: encrypted_xprv)
91
+ call :post, '/keychain', { xpub: xpub, encrypted_xprv: encrypted_xprv }
92
+ end
93
+
94
+ def create_bitgo_keychain
95
+ call :post, '/keychain/bitgo'
96
+ end
97
+
98
+ ###############
99
+ # Address Labels API
100
+ ###############
101
+
102
+ def list_labels
103
+ call :get, '/labels'
104
+ end
105
+
106
+ def list_labels_for_wallet(wallet_id: wallet_id)
107
+ call :get, '/labels/' + wallet_id
108
+ end
109
+
110
+ def set_label(wallet_id: wallet_id, address: address, label: label)
111
+ call :put, '/labels/' + wallet_id + '/' + address, { label: label }
112
+ end
113
+
114
+ def delete_label(wallet_id: wallet_id, address: address)
115
+ call :delete, '/labels/' + wallet_id + '/' + address
116
+ end
117
+
118
+ ###############
119
+ # Wallets API
120
+ ###############
121
+
122
+ def list_wallets
123
+ call :get, '/wallet'
124
+ end
125
+
126
+ # wallet_simple_create
127
+ #
128
+ # Note: Bitcoin Express API, will only work on Bitcoin Express Endpoint
129
+ # This method is available on the client SDK as an easy way to create a wallet. It performs the following:
130
+ #
131
+ # 1. Creates the user keychain and the backup keychain locally on the client
132
+ # 2. Encrypts the user keychain and backup keychain with the provided passphrase
133
+ # 3. Uploads the encrypted user and backup keychains to BitGo
134
+ # 4. Creates the BitGo key on the service
135
+ # 5. Creates the wallet on BitGo with the 3 public keys above
136
+ #
137
+ # Example:
138
+ # api = Bitgo::Api.new
139
+ # api.simple_create(passphrase: '12345', label: 'label')
140
+ #
141
+ # {
142
+ # "wallet" => {
143
+ # "id" => "2N2ovVLDjYpUr3RSR4Z5UiXFzBkQ1hRyNSR",
144
+ # "label" => "test wallet 1",
145
+ # "isActive" => true,
146
+ # "type" => "safehd",
147
+ # "freeze" => {},
148
+ # "adminCount" => 1,
149
+ # "private" => {
150
+ # "keychains" => [
151
+ # [0] {
152
+ # "xpub" => "xpub661MyMwAqRbcF5jq3P7NkbMfFK9HDEYppZXxzmAsid5AvAPF1UyN1vsuePn9HNy3ZgYgUaANt1tkpxtZ2NLxUp1qeiPApMNu2uCJivmEDob", # user key chain
153
+ # "path" => "/0/0"
154
+ # },
155
+ # [1] {
156
+ # "xpub" => "xpub661MyMwAqRbcGPnMoA7wCWnY1K2NGHUEMzaJQsjpv83mVTsodjKJDUjZEwEegztrf1uSokHDKpBMFLR79YSnH7zvgGN18EHVNMbKFVbk8rv", # user backupkey
157
+ # "path" => "/0/0"
158
+ # },
159
+ # [2] {
160
+ # "xpub" => "xpub661MyMwAqRbcEruwFJWcXjHkgTPW5cg5ZBMg9dRQyjrL49szFdrCuGvGDGpcXHWEdsj2NY4o6QxsvzfvorsZ5VH9ha3pGD8SJgATbEo7jbp", # bitgo keychain
161
+ # "path" => "/0/0"
162
+ # }
163
+ # ]
164
+ # },
165
+ # "permissions" => "admin,spend,view",
166
+ # "admin" => {
167
+ # "users" => [
168
+ # [0] {
169
+ # "user" => "552489e5c8e05d177800a5b1bf066af4",
170
+ # "permissions" => "admin,spend,view"
171
+ # }
172
+ # ]
173
+ # },
174
+ # "spendingAccount" => true,
175
+ # "confirmedBalance" => 0,
176
+ # "balance" => 0,
177
+ # "unconfirmedSends" => 0,
178
+ # "unconfirmedReceives" => 0,
179
+ # "pendingApprovals" => []
180
+ # },
181
+ # "userKeychain" => {
182
+ # "xpub" => "xpub661MyMwAqRbcF5jq3P7NkbMfFK9HDEYppZXxzmAsid5AvAPF1UyN1vsuePn9HNy3ZgYgUaANt1tkpxtZ2NLxUp1qeiPApMNu2uCJivmEDob",
183
+ # "xprv" => "xprv9s21ZrQH143K2bfMwMaNPTQvhHJnompyTLcNCNmGAHYC3N46Twf7U8ZRo7isyYM7c5KriFYPdMnpB3CL9sKWyJYjQNri6mVNEvFXFZGx8J8",
184
+ # "encryptedXprv" => "{\"iv\":\"EnVDttt82SOMdk5+nxl6Yg==\",\"v\":1,\"iter\":10000,\"ks\":256,\"ts\":64,\"mode\":\"ccm\",\"adata\":\"\",\"cipher\":\"aes\",\"salt\":\"6E6KxZSKJ1U=\",\"ct\":\"PPIBVErcWkBUTl5ceqUulvDLsbZl17fhLt1CFnsA6Ay9R9NU6utNxst9SvcaeMEwItdSTUOfWvg7rokpR+0g8yHsqouf3qCiqk9RZLy0jKReje5/SC2J5SPp6yIsfT8q0y8QwKjVNx2FULLpJeHQ9yv/+TE+lvo=\"}"
185
+ # },
186
+ # "backupKeychain" => {
187
+ # "xpub" => "xpub661MyMwAqRbcGPnMoA7wCWnY1K2NGHUEMzaJQsjpv83mVTsodjKJDUjZEwEegztrf1uSokHDKpBMFLR79YSnH7zvgGN18EHVNMbKFVbk8rv",
188
+ # "xprv" => "xprv9s21ZrQH143K3uhth8avqNqoTHBsrpkNzmehcVLDMnWncfYf6C13fgR5PfKkFukcGF2vjopkDXEaYxKoxb6c9WXtbJga7aR3C8cgCr1v8vh"
189
+ # },
190
+ # "bitgoKeychain" => {
191
+ # "xpub" => "xpub661MyMwAqRbcEruwFJWcXjHkgTPW5cg5ZBMg9dRQyjrL49szFdrCuGvGDGpcXHWEdsj2NY4o6QxsvzfvorsZ5VH9ha3pGD8SJgATbEo7jbp",
192
+ # "isBitGo" => true,
193
+ # "path" => "m"
194
+ # },
195
+ # "warning" => "Be sure to backup the backup keychain -- it is not stored anywhere else!"
196
+ # }
197
+ def simple_create_wallet(passphrase: passphrase, label: label)
198
+ call :post, '/wallets/simplecreate', {passphrase: passphrase, label: label}
199
+ end
200
+
201
+ # This API creates a new wallet for the user. The keychains to use with the new wallet must be registered with BitGo prior to using this API.
202
+ # BitGo currently only supports 2-of-3 (e.g. m=2 and n=3) wallets. The third keychain, and only the third keychain, must be a BitGo key.
203
+ # The first keychain is by convention the user key, with it’s encrypted xpriv is stored on BitGo.
204
+ # BitGo wallets currently are hard-coded with their root at m/0/0 across all 3 keychains (however, older legacy wallets may use different key paths). Below the root, the wallet supports two chains of addresses, 0 and 1. The 0-chain is for external receiving addresses, while the 1-chain is for internal (change) addresses.
205
+ # The first receiving address of a wallet is at the BIP32 path m/0/0/0/0, which is also the ID used to refer to a wallet in BitGo’s system. The first change address of a wallet is at m/0/0/1/0.
206
+ #
207
+ # label: string (Required) A label for this wallet
208
+ # m: number (Required) The number of signatures required to redeem (must be 2)
209
+ # n: number (Required) The number of keys in the wallet (must be 3)
210
+ # keychains: array (Required) An array of n keychain xpubs to use with this wallet; last must be a BitGo key
211
+ # enterprise :string (Optional) Enterprise ID to create this wallet under.
212
+ def add_wallet(label: label, m: m, n: n, keychains: keychains, enterprise: nil)
213
+ wallet_params = { label: label, m: m, n: n, keychains: keychains }
214
+ if enterprise.present?
215
+ wallet_params[:enterprise] = enterprise
216
+ end
217
+
218
+ call :post, '/wallet', wallet_params
219
+ end
220
+
221
+ # Lookup wallet information, returning the wallet model including balances, permissions etc. The ID of a wallet is its first receiving address (/0/0)
222
+ #
223
+ # Response:
224
+ # id id of the wallet (also the first receiving address)
225
+ # label the wallet label, as shown in the UI
226
+ # index the index of the address within the chain (0, 1, 2, …)
227
+ # private contains summarised version of keychains
228
+ # permissions user’s permissions on this wallet
229
+ # admin policy information on the wallet’s administrators
230
+ # pendingApprovals pending transaction approvals on the wallet
231
+ # confirmedBalance the confirmed balance
232
+ # balance the balance, including transactions with 0 confirmations
233
+ def get_wallet(wallet_id: wallet_id)
234
+ call :get, '/wallet/' + wallet_id
235
+ end
236
+
237
+ # Gets a list of addresses which have been instantiated for a wallet using the New Address API.
238
+ def list_wallet_addresses(wallet_id: wallet_id)
239
+ call :get, '/wallet/' + wallet_id + '/addresses'
240
+ end
241
+
242
+ # Creates a new address for an existing wallet. BitGo wallets consist of two independent chains of addresses, designated 0 and 1.
243
+ # The 0-chain is typically used for receiving funds, while the 1-chain is used internally for creating change when spending from a wallet.
244
+ # It is considered best practice to generate a new receiving address for each new incoming transaction, in order to help maximize privacy.
245
+ def create_address(wallet_id: wallet_id, chain: chain)
246
+ call :post, '/wallet/' + wallet_id + '/address/' + chain
247
+ end
248
+
249
+ def send_coins_to_address(address: address, amount: amount, wallet_passphrase: wallet_passphrase, min_confirmations: min_confirmations, fee: fee)
250
+ call :post, '/sendcoins', {
251
+ address: address,
252
+ amount: amount,
253
+ wallet_passphrase: wallet_passphrase,
254
+ min_confirmations: min_confirmations,
255
+ fee: fee
256
+ }
257
+ end
258
+
259
+ def send_coins_to_multiple_addresses()
260
+
261
+ end
262
+
263
+ ###############
264
+ # Webhook APIs
265
+ ###############
266
+ # Adds a Webhook that will result in a HTTP callback at the specified URL from BitGo when events are triggered. There is a limit of 5 Webhooks of each type per wallet.
267
+ #
268
+ # type string (Required) type of Webhook, e.g. transaction
269
+ # url string (Required) valid http/https url for callback requests
270
+ # numConfirmations integer (Optional) number of confirmations before triggering the webhook. If 0 or unspecified, requests will be sent to the callback endpoint will be called when the transaction is first seen and when it is confirmed.
271
+ def add_webhook(wallet_id: wallet_id, type: type, url: url, confirmations: confirmations)
272
+ add_webhook_params = {
273
+ type: type,
274
+ url: url,
275
+ confirmations: confirmations
276
+ }
277
+ call :post, '/wallet/' + wallet_id + '/webhooks', add_webhook_params
278
+ end
279
+
280
+
281
+ def remove_webhook(wallet_id: wallet_id, type: type, url: url)
282
+ remove_webhook_params = {
283
+ type: type,
284
+ url: url
285
+ }
286
+ call :delete, '/wallet/' + wallet_id + '/webhooks', remove_webhook_params
287
+ end
288
+
289
+ def list_webhooks(wallet_id: wallet_id)
290
+ call :get, '/wallet/' + wallet_id + '/webhooks'
291
+ end
292
+
293
+ ###############
294
+ # Utilities (Via Bitgo Express API)
295
+ ###############
296
+
297
+ def encrypt(input: input, password: password)
298
+ call :post, '/encrypt', { input: input, password: password }
299
+ end
300
+
301
+ def decrypt(input: input, password: password)
302
+ call :post, '/decrypt', { input: input, password: password }
303
+ end
304
+
305
+ # Client-side function to verify that a given string is a valid Bitcoin Address. Supports both v1 addresses (e.g. “1…”) and P2SH addresses (e.g. “3…”).
306
+ def verify_address(address: address)
307
+ verify_address_params = {
308
+ address: address
309
+ }
310
+ call :post, '/verifyaddress', verify_address_params
311
+ end
312
+
313
+
314
+ private
315
+
316
+ ###############
317
+ # HTTP call
318
+ ###############
319
+
320
+ # Perform HTTP call
321
+ # path parameter must being with a /
322
+ def call(method, path, params = {}, parse_response_as_json = true, with_auth_token = true)
323
+
324
+ # path must begin with slash
325
+ uri = URI(@end_point + path)
326
+
327
+ # Build the connection
328
+ http = Net::HTTP.new(uri.host, uri.port)
329
+
330
+ if uri.scheme == 'https'
331
+ http.use_ssl = true
332
+ end
333
+
334
+ request = nil
335
+ if method == :get
336
+ request = Net::HTTP::Get.new(uri.request_uri)
337
+
338
+ elsif method == :post
339
+ request = Net::HTTP::Post.new(uri.request_uri)
340
+ elsif method == :delete
341
+ request = Net::HTTP::Delete.new(uri.request_uri)
342
+ elsif method == :put
343
+ request = Net::HTTP::Put.new(uri.request_uri)
344
+ else
345
+ raise 'Unsupported request method'
346
+ end
347
+
348
+ request.body = params.to_json
349
+
350
+ # Set JSON body
351
+ request.add_field('Content-Type', 'application/json')
352
+
353
+ # Add authentication header
354
+ if with_auth_token == true && @session_token.nil? == false
355
+ request.add_field('Authorization', 'Bearer ' + @session_token)
356
+ end
357
+
358
+ response = http.request(request)
359
+
360
+ if parse_response_as_json == true
361
+ json_resp = nil
362
+ begin
363
+ json_resp = JSON.parse(response.body)
364
+ rescue => e
365
+ raise ApiError.new("Error Parsing Bitgo's response as JSON: #{e} , Bitgo response: #{response.body}")
366
+ end
367
+
368
+ if json_resp.kind_of?(Hash) && json_resp["error"].nil? == false
369
+ raise ApiError.new(json_resp["error"])
370
+ end
371
+
372
+ return json_resp
373
+ else
374
+ return response.body
375
+ end
376
+ end
377
+
378
+ end
379
+
380
+ end
381
+ end
metadata ADDED
@@ -0,0 +1,46 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: bitgo
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Gerry Eng
8
+ - Pramodh Rai
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2015-04-09 00:00:00.000000000 Z
13
+ dependencies: []
14
+ description: Ruby wrapper for Bitgo and Bitgo Express API
15
+ email: gerry@coinhako.com
16
+ executables: []
17
+ extensions: []
18
+ extra_rdoc_files: []
19
+ files:
20
+ - lib/bitgo.rb
21
+ - lib/bitgo/v1/api.rb
22
+ homepage: https://www.bitgo.com/api/
23
+ licenses:
24
+ - MIT
25
+ metadata: {}
26
+ post_install_message:
27
+ rdoc_options: []
28
+ require_paths:
29
+ - lib
30
+ required_ruby_version: !ruby/object:Gem::Requirement
31
+ requirements:
32
+ - - ">="
33
+ - !ruby/object:Gem::Version
34
+ version: '0'
35
+ required_rubygems_version: !ruby/object:Gem::Requirement
36
+ requirements:
37
+ - - ">="
38
+ - !ruby/object:Gem::Version
39
+ version: '0'
40
+ requirements: []
41
+ rubyforge_project:
42
+ rubygems_version: 2.2.2
43
+ signing_key:
44
+ specification_version: 4
45
+ summary: Ruby wrapper for Bitgo and Bitgo Express API
46
+ test_files: []