taproot 0.1.0

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 ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 7cd789482e4c1053a87ebce20b53faf67eae60f6
4
+ data.tar.gz: dd3158d834b090e7dcf54536c4c103e03958050a
5
+ SHA512:
6
+ metadata.gz: 669edbfb9cd11cdd762b6682f9f5b46bc8686d15a94fd185ddd0f54ac1584b0853c4f0627b57d340cc4c8485c95530f658c6e40613724bd0181f3007e1167bd1
7
+ data.tar.gz: 47fab4bc960ec0e8e1b2b5dd8f67b6f7fea48d5248ac1cc648b32b9f6f0ce0c1f3f0343e84be1ce8b767aa9f1aa2a697cb1476d31c0641e6bc557a718a929134
data/.gitignore ADDED
@@ -0,0 +1 @@
1
+ *.gem
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ # A sample Gemfile
2
+ source "https://rubygems.org"
3
+
4
+ gemspec
data/Gemfile.lock ADDED
@@ -0,0 +1,66 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ taproot (0.1.0)
5
+ activesupport (~> 4.1.1)
6
+ awesome_print (~> 1.2.0)
7
+ braintree (~> 2.30.2)
8
+ pry (~> 0.9.12.6)
9
+ sinatra (~> 1.4.5)
10
+ sinatra-contrib (~> 1.4.2)
11
+ term-ansicolor (~> 1.3.0)
12
+
13
+ GEM
14
+ remote: https://rubygems.org/
15
+ specs:
16
+ activesupport (4.1.1)
17
+ i18n (~> 0.6, >= 0.6.9)
18
+ json (~> 1.7, >= 1.7.7)
19
+ minitest (~> 5.1)
20
+ thread_safe (~> 0.1)
21
+ tzinfo (~> 1.1)
22
+ awesome_print (1.2.0)
23
+ backports (3.6.0)
24
+ braintree (2.30.2)
25
+ builder (>= 2.0.0)
26
+ builder (3.2.2)
27
+ coderay (1.1.0)
28
+ i18n (0.6.9)
29
+ json (1.8.1)
30
+ method_source (0.8.2)
31
+ minitest (5.3.4)
32
+ multi_json (1.10.1)
33
+ pry (0.9.12.6)
34
+ coderay (~> 1.0)
35
+ method_source (~> 0.8)
36
+ slop (~> 3.4)
37
+ rack (1.5.2)
38
+ rack-protection (1.5.3)
39
+ rack
40
+ rack-test (0.6.2)
41
+ rack (>= 1.0)
42
+ sinatra (1.4.5)
43
+ rack (~> 1.4)
44
+ rack-protection (~> 1.4)
45
+ tilt (~> 1.3, >= 1.3.4)
46
+ sinatra-contrib (1.4.2)
47
+ backports (>= 2.0)
48
+ multi_json
49
+ rack-protection
50
+ rack-test
51
+ sinatra (~> 1.4.0)
52
+ tilt (~> 1.3)
53
+ slop (3.5.0)
54
+ term-ansicolor (1.3.0)
55
+ tins (~> 1.0)
56
+ thread_safe (0.3.3)
57
+ tilt (1.4.1)
58
+ tins (1.3.0)
59
+ tzinfo (1.1.0)
60
+ thread_safe (~> 0.1)
61
+
62
+ PLATFORMS
63
+ ruby
64
+
65
+ DEPENDENCIES
66
+ taproot!
data/README.md ADDED
@@ -0,0 +1,8 @@
1
+ # Taproot
2
+
3
+ A test server for Braintree client SDK integrations.
4
+
5
+ ## Features
6
+
7
+ * Switch between multiple Braintree accounts
8
+ * Interactive console
data/bin/taproot ADDED
@@ -0,0 +1,13 @@
1
+ #!/usr/bin/env ruby
2
+ require "awesome_print"
3
+ require "cli"
4
+
5
+ if ARGV.first.nil?
6
+ ARGV[0] = "index"
7
+ end
8
+
9
+ ARGV[0] = ARGV[0].gsub("/", "_").gsub(":", "_")
10
+
11
+ if TaprootCLI.respond_to?(ARGV.first.to_sym)
12
+ ap TaprootCLI.send(ARGV.first.to_sym)
13
+ end
data/bin/taprootd ADDED
@@ -0,0 +1,69 @@
1
+ #!/usr/bin/env ruby
2
+ require "taproot"
3
+ require "optparse"
4
+ require "rack"
5
+ require "yaml"
6
+ require "pry"
7
+ require "config_manager"
8
+ require "exception_handler"
9
+
10
+ options = {}
11
+ OptionParser.new do |opts|
12
+ opts.banner = "Usage: taproot [options]"
13
+
14
+ opts.on("--merchant-id [id]", "Braintree Merchant ID") do |v|
15
+ options[:merchant_id] = v
16
+ end
17
+
18
+ opts.on("--environment [env]", "Braintree Environment") do |v|
19
+ options[:environment] = v.to_sym
20
+ end
21
+
22
+ opts.on("--public-key [key]", "Braintree Public Key") do |v|
23
+ options[:public_key] = v
24
+ end
25
+
26
+ opts.on("--private-key [key]", "Braintree Private Key") do |v|
27
+ options[:private_key] = v
28
+ end
29
+
30
+ opts.on("-c [config file]", "--config [config file]", "Taproot YAML config") do |v|
31
+ options[:config_file] = v
32
+ end
33
+
34
+ opts.on("-p [port]", "--port [port]", "Port") do |v|
35
+ options[:port] = v
36
+ end
37
+ end.parse!
38
+
39
+ CONFIG_MANAGER = ConfigManager.new
40
+ config_file = options.fetch(:config_file, "taproot.yml")
41
+
42
+ if File.exists?(config_file)
43
+ config_file = File.read(config_file)
44
+ YAML.load(config_file).fetch("BraintreeAccounts", {}).each do |name, braintree_account_args|
45
+ CONFIG_MANAGER.add(name, braintree_account_args)
46
+ end
47
+ end
48
+
49
+ if ([:merchant_id, :environment, :public_key, :private_key] - options.keys).length == 0
50
+ CONFIG_MANAGER.add(
51
+ "commandline",
52
+ :environment => options[:environment],
53
+ :merchant_id => options[:merchant_id],
54
+ :public_key => options[:public_key],
55
+ :private_key => options[:private_key]
56
+ )
57
+ end
58
+
59
+ unless CONFIG_MANAGER.valid?
60
+ puts "Need at least one Braintree account."
61
+ puts "taproot --help"
62
+ exit 1
63
+ end
64
+
65
+ CONFIG_MANAGER.activate_first!
66
+
67
+ Rack::Handler::WEBrick.run(Taproot, {:Port => options.fetch(:port, "3132")}) do |server|
68
+ [:INT, :TERM].each { |sig| trap(sig) { server.stop } }
69
+ end
data/config.ru ADDED
@@ -0,0 +1,3 @@
1
+ require './app'
2
+ run Taproot
3
+
@@ -0,0 +1,6 @@
1
+ BraintreeAccounts:
2
+ example:
3
+ merchant_id: myid
4
+ environment: sandbox
5
+ public_key: mykey
6
+ private_key: myprikey
@@ -0,0 +1,29 @@
1
+ class BraintreeAccount
2
+ attr_reader :environment, :merchant_id, :public_key, :private_key
3
+
4
+ RequiredOptions = [:environment, :merchant_id, :public_key, :private_key]
5
+
6
+ def initialize(options)
7
+ @environment = options[:environment]
8
+ @merchant_id = options[:merchant_id]
9
+ @public_key = options[:public_key]
10
+ @private_key = options[:private_key]
11
+ end
12
+
13
+ def activate!
14
+ Braintree::Configuration.environment = @environment.to_sym
15
+ Braintree::Configuration.merchant_id = @merchant_id
16
+ Braintree::Configuration.public_key = @public_key
17
+ Braintree::Configuration.private_key = @private_key
18
+ Braintree::Configuration.logger = Logger.new("/dev/null")
19
+ end
20
+
21
+ def as_json
22
+ {
23
+ :environment => @environment,
24
+ :merchant_id => @merchant_id,
25
+ :public_key => @public_key,
26
+ :private_key => @private_key
27
+ }
28
+ end
29
+ end
data/lib/cli.rb ADDED
@@ -0,0 +1,29 @@
1
+ require "net/http"
2
+ require "open-uri"
3
+ require "json"
4
+
5
+ module TaprootCLI
6
+ def self.url(path="")
7
+ URI.join("http://localhost:3132", path)
8
+ end
9
+
10
+ def self.index
11
+ JSON.parse(open(url).read)
12
+ end
13
+
14
+ def self.client_token
15
+ JSON.parse(open(url("client_token")).read)
16
+ end
17
+
18
+ def self.config
19
+ JSON.parse(open(url("config")).read)
20
+ end
21
+
22
+ def self.config_current
23
+ JSON.parse(open(url("config/current")).read)
24
+ end
25
+
26
+ def self.config_merchant_account
27
+ JSON.parse(open(url("config/merchant_account")).read)
28
+ end
29
+ end
@@ -0,0 +1,91 @@
1
+ require "active_support/all"
2
+ require "braintree_account"
3
+ require "open-uri"
4
+ require "timeout"
5
+
6
+
7
+ class ConfigManager
8
+ attr_reader :current, :current_account, :current_merchant_account
9
+ attr_accessor :current_merchant_account
10
+
11
+ def initialize
12
+ @configs = {}.with_indifferent_access
13
+ @current = nil
14
+ @current_account = nil
15
+ @current_merchant_account = nil
16
+ end
17
+
18
+ def as_json
19
+ @configs.inject({}) do |json, (name, config)|
20
+ json[name] = config.as_json
21
+ json
22
+ end
23
+ end
24
+
25
+ def has_config?(name)
26
+ @configs.has_key?(name)
27
+ end
28
+
29
+ def add(name, braintree_account_args)
30
+ @configs[name] = BraintreeAccount.new(braintree_account_args.with_indifferent_access)
31
+ end
32
+
33
+ def valid?
34
+ @configs.any?
35
+ end
36
+
37
+ def activate_first!
38
+ raise "No accounts" unless valid?
39
+ name, braintree_account = @configs.first
40
+ activate!(name)
41
+ end
42
+
43
+ def activate!(name)
44
+ @configs.fetch(name).activate!
45
+ @current = name
46
+ @current_account = @configs.fetch(name)
47
+ end
48
+
49
+ def test_environment!(name)
50
+ original_config = current
51
+ activate!(name)
52
+ rescue Exception => e
53
+ @configs.delete(name)
54
+ raise e
55
+ ensure
56
+ activate!(original_config)
57
+ end
58
+
59
+ def validate_environment!
60
+ old = ::OpenSSL::SSL::VERIFY_PEER
61
+ silence_warnings{ ::OpenSSL::SSL.const_set :VERIFY_PEER, OpenSSL::SSL::VERIFY_NONE }
62
+
63
+ puts "--- [#{current}] Getting client token for validation of environment"
64
+ begin
65
+ client_token = JSON.parse(Braintree::ClientToken.generate)
66
+ rescue Errno::ECONNRESET => e
67
+ return "The gateway is down for URL #{Braintree::Configuration.instantiate.base_merchant_url}"
68
+ rescue Braintree::AuthenticationError => e
69
+ return "Unable to authenticate to Braintree while getteing client token. Your keys or merchant ID may be wrong or the gateway is down."
70
+ end
71
+
72
+ if client_token["paypal"].nil? == false
73
+ puts "--- [#{current}] Trying to connect to paypal"
74
+ begin
75
+ Timeout::timeout(5) { open("#{client_token["paypal"]["baseUrl"]}/paypal") }
76
+ rescue OpenURI::HTTPError => e
77
+ if e.message != "401 Unauthorized"
78
+ return "Error opening #{"#{client_token["paypal"]["baseUrl"]}/paypal"}: #{e.message}"
79
+ end
80
+ rescue Errno::ECONNREFUSED => e
81
+ return "Can't connect to paypal base url #{client_token["paypal"]["baseUrl"]}"
82
+ end
83
+ end
84
+
85
+ "Valid"
86
+ rescue Timeout::Error => e
87
+ "Timed out connecting to paypal at #{"#{client_token["paypal"]["baseUrl"]}/paypal"}"
88
+ ensure
89
+ silence_warnings{ ::OpenSSL::SSL.const_set :VERIFY_PEER, old }
90
+ end
91
+ end
@@ -0,0 +1,20 @@
1
+ class ExceptionHandling
2
+ def initialize(app)
3
+ @app = app
4
+ end
5
+
6
+ def call(env)
7
+ begin
8
+ @app.call env
9
+ rescue => ex
10
+ env['rack.errors'].puts ex
11
+ env['rack.errors'].puts ex.backtrace.join("\n")
12
+ env['rack.errors'].flush
13
+
14
+ hash = { :message => ex.to_s }
15
+ hash[:backtrace] = ex.backtrace[0..5]
16
+
17
+ [500, {'Content-Type' => 'application/json'}, [JSON.pretty_generate(hash)]]
18
+ end
19
+ end
20
+ end
data/lib/taproot.rb ADDED
@@ -0,0 +1,204 @@
1
+ require "rubygems"
2
+ require "sinatra"
3
+ require "sinatra/contrib/all"
4
+ require "braintree"
5
+ require "term/ansicolor"
6
+ require "exception_handler"
7
+ require "config_manager"
8
+
9
+ class Taproot < Sinatra::Base
10
+ use ExceptionHandling
11
+ register Sinatra::Decompile
12
+ include Term::ANSIColor
13
+
14
+ get "/" do
15
+ content_type :json
16
+
17
+ routes = {}
18
+ routes["DELETE"] = Taproot.routes["DELETE"].map { |r| Taproot.decompile(r[0], r[1]) }
19
+ routes["GET"] = Taproot.routes["GET"].map { |r| Taproot.decompile(r[0], r[1]) }
20
+ routes["POST"] = Taproot.routes["POST"].map { |r| Taproot.decompile(r[0], r[1]) }
21
+ routes["PUT"] = Taproot.routes["PUT"].map { |r| Taproot.decompile(r[0], r[1]) }
22
+
23
+ JSON.pretty_generate(:message => "Taproot UP", :config => CONFIG_MANAGER.current, :routes => routes)
24
+ end
25
+
26
+ get "/client_token" do
27
+ content_type :json
28
+ begin
29
+ JSON.pretty_generate(JSON.parse(Braintree::ClientToken.generate(params)))
30
+ rescue Exception => e
31
+ status 422
32
+ JSON.pretty_generate(:message => e.message)
33
+ end
34
+ end
35
+
36
+ put "/customers/:customer_id" do
37
+ result = Braintree::Customer.create(
38
+ :id => params[:customer_id]
39
+ )
40
+
41
+ if result.success?
42
+ status 201
43
+ JSON.pretty_generate(:message => "Customer #{params[:customer_id]} created")
44
+ else
45
+ status 422
46
+ JSON.pretty_generate(:message => result.message)
47
+ end
48
+ end
49
+
50
+ post "/nonce/customer" do
51
+ nonce = nonce_from_params
52
+
53
+ content_type :json
54
+ if nonce
55
+ JSON.pretty_generate(sale(nonce, params.fetch(:amount, 10)))
56
+ else
57
+ JSON.pretty_generate(
58
+ :message => "Required params: #{server_config[:nonce_param_names].join(", or ")}"
59
+ )
60
+ end
61
+ end
62
+
63
+ post "/nonce/transaction" do
64
+ nonce = nonce_from_params
65
+
66
+ content_type :json
67
+ if nonce
68
+ JSON.pretty_generate(sale(nonce, params.fetch(:amount, 10)))
69
+ else
70
+ JSON.pretty_generate(
71
+ :message => "Required params: #{server_config[:nonce_param_names].join(", or ")}"
72
+ )
73
+ end
74
+ end
75
+
76
+ get "/config" do
77
+ content_type :json
78
+ JSON.pretty_generate(CONFIG_MANAGER.as_json)
79
+ end
80
+
81
+ get "/config/current" do
82
+ content_type :json
83
+ JSON.pretty_generate(CONFIG_MANAGER.current_account.as_json)
84
+ end
85
+
86
+ post "/config/:name/activate" do
87
+ content_type :json
88
+
89
+ if CONFIG_MANAGER.has_config?(params[:name])
90
+ status 200
91
+ CONFIG_MANAGER.activate!(params[:name])
92
+ JSON.pretty_generate(:message => "#{params[:name]} activated")
93
+ else
94
+ status 404
95
+ JSON.pretty_generate(:message => "#{params[:name]} not found")
96
+ end
97
+ end
98
+
99
+ put "/config/:name" do
100
+ content_type :json
101
+
102
+ if CONFIG_MANAGER.has_config?(params[:name])
103
+ status 422
104
+ JSON.pretty_generate(:message => "#{params[:name]} already exists")
105
+ else
106
+ begin
107
+ CONFIG_MANAGER.add(
108
+ params[:name],
109
+ :environment => params[:environment],
110
+ :merchant_id => params[:merchant_id],
111
+ :public_key => params[:public_key],
112
+ :private_key => params[:private_key]
113
+ )
114
+ CONFIG_MANAGER.test_environment!(params[:name])
115
+
116
+ status 201
117
+ JSON.pretty_generate(:message => "#{params[:name]} created")
118
+ rescue Exception => e
119
+ status 422
120
+ JSON.pretty_generate(:message => e.message)
121
+ end
122
+ end
123
+ end
124
+
125
+ get "/config/merchant_account" do
126
+ content_type :json
127
+ JSON.pretty_generate(:merchant_account => CONFIG_MANAGER.current_merchant_account)
128
+ end
129
+
130
+ put "/config/merchant_account/:merchant_account" do
131
+ content_type :json
132
+ CONFIG_MANAGER.current_merchant_account = params[:merchant_account]
133
+ JSON.pretty_generate(:merchant_account => CONFIG_MANAGER.current_merchant_account)
134
+ end
135
+
136
+ delete "/config/merchant_account" do
137
+ content_type :json
138
+ CONFIG_MANAGER.current_merchant_account = nil
139
+ JSON.pretty_generate(:merchant_account => CONFIG_MANAGER.current_merchant_account)
140
+ end
141
+
142
+ get "/config/validate" do
143
+ JSON.pretty_generate(:message => CONFIG_MANAGER.validate_environment!)
144
+ end
145
+
146
+ after do
147
+ puts "#{bold ">>>"} #{request.env["REQUEST_METHOD"]} #{request.path} #{params.inspect}"
148
+ puts "#{green bold "<<<"} #{_color_status(response.status.to_i)}"
149
+ response.body.first.split("\n").each do |line|
150
+ puts "#{green bold "<<<"} #{line}"
151
+ end
152
+ end
153
+
154
+ def server_config
155
+ {
156
+ :nonce_param_names => ["nonce", "payment_method_nonce", "paymentMethodNonce"]
157
+ }
158
+ end
159
+
160
+ def log(message)
161
+ puts "--- [#{CONFIG_MANAGER.current}] #{message}"
162
+ end
163
+
164
+ def nonce_from_params
165
+ server_config[:nonce_param_names].find do |nonce_param_name|
166
+ if params[nonce_param_name]
167
+ return params[nonce_param_name]
168
+ end
169
+ end
170
+ end
171
+
172
+ def sale(nonce, amount)
173
+ transaction_params = {
174
+ :amount => amount,
175
+ :payment_method_nonce => nonce,
176
+ }
177
+
178
+ if CONFIG_MANAGER.current_merchant_account
179
+ transaction_params[:merchant_account_id] = CONFIG_MANAGER.current_merchant_account
180
+ end
181
+
182
+ log("Creating transaction #{transaction_params.inspect}")
183
+
184
+ result = Braintree::Transaction.sale(transaction_params)
185
+
186
+ if result.success?
187
+ {:message => "created #{result.transaction.id} #{result.transaction.status}"}
188
+ else
189
+ {:message => result.message}
190
+ end
191
+ rescue Exception => e
192
+ {:message => e.message}
193
+ end
194
+
195
+ def _color_status(status)
196
+ if status >= 400
197
+ yellow status.to_s
198
+ elsif status >= 500
199
+ red status.to_s
200
+ else
201
+ green status.to_s
202
+ end
203
+ end
204
+ end
data/taproot.gemspec ADDED
@@ -0,0 +1,24 @@
1
+ # -*- encoding: utf-8 -*-
2
+
3
+ Gem::Specification.new do |gem|
4
+ gem.authors = ["Ben Mills"]
5
+ gem.email = ["ben@benmills.org"]
6
+ gem.description = %q{Braintree test server}
7
+ gem.summary = %q{Taproot makes it easy to develop Braintree client SDKs without a server}
8
+ gem.homepage = "https://github.com/benmills/taproot"
9
+
10
+ gem.files = `git ls-files`.split($\)
11
+ gem.executables = ["taprootd", "taproot"]
12
+ gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
13
+ gem.name = "taproot"
14
+ gem.require_paths = ["lib"]
15
+ gem.version = "0.1.0"
16
+
17
+ gem.add_dependency "sinatra", "~> 1.4.5"
18
+ gem.add_dependency "braintree", "~> 2.30.2"
19
+ gem.add_dependency "pry", "~> 0.9.12.6"
20
+ gem.add_dependency "activesupport", "~> 4.1.1"
21
+ gem.add_dependency "term-ansicolor", "~> 1.3.0"
22
+ gem.add_dependency "awesome_print", "~> 1.2.0"
23
+ gem.add_dependency "sinatra-contrib", "~> 1.4.2"
24
+ end
metadata ADDED
@@ -0,0 +1,157 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: taproot
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Ben Mills
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2014-05-20 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: sinatra
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ~>
18
+ - !ruby/object:Gem::Version
19
+ version: 1.4.5
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ~>
25
+ - !ruby/object:Gem::Version
26
+ version: 1.4.5
27
+ - !ruby/object:Gem::Dependency
28
+ name: braintree
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ~>
32
+ - !ruby/object:Gem::Version
33
+ version: 2.30.2
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ~>
39
+ - !ruby/object:Gem::Version
40
+ version: 2.30.2
41
+ - !ruby/object:Gem::Dependency
42
+ name: pry
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ~>
46
+ - !ruby/object:Gem::Version
47
+ version: 0.9.12.6
48
+ type: :runtime
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ~>
53
+ - !ruby/object:Gem::Version
54
+ version: 0.9.12.6
55
+ - !ruby/object:Gem::Dependency
56
+ name: activesupport
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ~>
60
+ - !ruby/object:Gem::Version
61
+ version: 4.1.1
62
+ type: :runtime
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ~>
67
+ - !ruby/object:Gem::Version
68
+ version: 4.1.1
69
+ - !ruby/object:Gem::Dependency
70
+ name: term-ansicolor
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - ~>
74
+ - !ruby/object:Gem::Version
75
+ version: 1.3.0
76
+ type: :runtime
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - ~>
81
+ - !ruby/object:Gem::Version
82
+ version: 1.3.0
83
+ - !ruby/object:Gem::Dependency
84
+ name: awesome_print
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - ~>
88
+ - !ruby/object:Gem::Version
89
+ version: 1.2.0
90
+ type: :runtime
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - ~>
95
+ - !ruby/object:Gem::Version
96
+ version: 1.2.0
97
+ - !ruby/object:Gem::Dependency
98
+ name: sinatra-contrib
99
+ requirement: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - ~>
102
+ - !ruby/object:Gem::Version
103
+ version: 1.4.2
104
+ type: :runtime
105
+ prerelease: false
106
+ version_requirements: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - ~>
109
+ - !ruby/object:Gem::Version
110
+ version: 1.4.2
111
+ description: Braintree test server
112
+ email:
113
+ - ben@benmills.org
114
+ executables:
115
+ - taprootd
116
+ - taproot
117
+ extensions: []
118
+ extra_rdoc_files: []
119
+ files:
120
+ - .gitignore
121
+ - Gemfile
122
+ - Gemfile.lock
123
+ - README.md
124
+ - bin/taproot
125
+ - bin/taprootd
126
+ - config.ru
127
+ - example_taproot.yml
128
+ - lib/braintree_account.rb
129
+ - lib/cli.rb
130
+ - lib/config_manager.rb
131
+ - lib/exception_handler.rb
132
+ - lib/taproot.rb
133
+ - taproot.gemspec
134
+ homepage: https://github.com/benmills/taproot
135
+ licenses: []
136
+ metadata: {}
137
+ post_install_message:
138
+ rdoc_options: []
139
+ require_paths:
140
+ - lib
141
+ required_ruby_version: !ruby/object:Gem::Requirement
142
+ requirements:
143
+ - - '>='
144
+ - !ruby/object:Gem::Version
145
+ version: '0'
146
+ required_rubygems_version: !ruby/object:Gem::Requirement
147
+ requirements:
148
+ - - '>='
149
+ - !ruby/object:Gem::Version
150
+ version: '0'
151
+ requirements: []
152
+ rubyforge_project:
153
+ rubygems_version: 2.0.6
154
+ signing_key:
155
+ specification_version: 4
156
+ summary: Taproot makes it easy to develop Braintree client SDKs without a server
157
+ test_files: []