straight-server 0.1.2 → 0.2.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.travis.yml +8 -0
- data/Gemfile +3 -1
- data/Gemfile.lock +57 -47
- data/Gemfile.travis +26 -0
- data/README.md +175 -22
- data/Rakefile +7 -0
- data/VERSION +1 -1
- data/benchmark/addons.yml +15 -0
- data/benchmark/config.yml +78 -0
- data/benchmark/default_last_keychain_id +1 -0
- data/benchmark/server_secret +1 -0
- data/bin/goliath.log +6 -0
- data/bin/goliath.log_stdout.log +51 -0
- data/bin/straight-server-benchmark +68 -0
- data/db/migrations/003_add_payment_id_to_orders.rb +13 -0
- data/db/migrations/004_add_description_to_orders.rb +11 -0
- data/db/migrations/005_add_orders_expiration_period_to_gateways.rb +11 -0
- data/db/migrations/006_add_check_order_status_in_db_first_to_gateways.rb +11 -0
- data/db/migrations/007_add_active_switcher_to_gateways.rb +11 -0
- data/db/migrations/008_add_order_counters_to_gateways.rb +11 -0
- data/db/migrations/009_add_hashed_id_to_gateways.rb +18 -0
- data/examples/client/client.dart +5 -0
- data/examples/client/client.html +7 -15
- data/examples/client/client.js +15 -0
- data/lib/straight-server/config.rb +1 -1
- data/lib/straight-server/gateway.rb +241 -59
- data/lib/straight-server/initializer.rb +170 -44
- data/lib/straight-server/logger.rb +1 -1
- data/lib/straight-server/order.rb +74 -9
- data/lib/straight-server/orders_controller.rb +23 -6
- data/lib/straight-server/random_string.rb +18 -0
- data/lib/straight-server/server.rb +44 -17
- data/lib/straight-server/utils/hash_string_to_sym_keys.rb +24 -0
- data/lib/straight-server.rb +6 -3
- data/spec/.straight/config.yml +16 -0
- data/spec/.straight/server_secret +1 -0
- data/spec/fixtures/addons.yml +19 -0
- data/spec/fixtures/test_addon.rb +8 -0
- data/spec/lib/gateway_spec.rb +93 -13
- data/spec/lib/initializer_spec.rb +104 -0
- data/spec/lib/order_spec.rb +59 -0
- data/spec/lib/orders_controller_spec.rb +34 -1
- data/spec/lib/utils/hash_string_to_sym_keys.rb +18 -0
- data/spec/spec_helper.rb +10 -2
- data/straight-server.gemspec +36 -8
- data/templates/addons.yml +15 -0
- data/templates/config.yml +41 -0
- metadata +47 -5
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: f8610bd49c87e428c82c658ecdc0a1f0e2299bfb
|
4
|
+
data.tar.gz: e046d7b179cafead65d803e4fb30e52d11a8bc11
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 0fda4cd1ecb67821380631da86fd6c2d4864c57ed5f0200b1b6d45508190a07b06e8c66e5e72a1b501df477b8da6c7f385ad4c7b059d50c51ce1f1176e570ef8
|
7
|
+
data.tar.gz: edb15d2d84f5de98901a3d0d3e18f7a2fb5279c6a9ed19418c9c8b400a9e6b006a3cf5b9d9d42cbcd82a7ae32861a32644048e2e0e851f32a0c09a5d71b79bae
|
data/.travis.yml
ADDED
data/Gemfile
CHANGED
@@ -5,8 +5,9 @@ gem "satoshi-unit"
|
|
5
5
|
gem "goliath"
|
6
6
|
gem "faye-websocket"
|
7
7
|
gem "sequel"
|
8
|
-
gem "logmaster", '0.1.
|
8
|
+
gem "logmaster", '0.1.5'
|
9
9
|
gem "ruby-hmac"
|
10
|
+
gem "httparty"
|
10
11
|
|
11
12
|
# Add dependencies to develop your gem here.
|
12
13
|
# Include everything needed to run rake, tests, features, etc.
|
@@ -21,4 +22,5 @@ group :test do
|
|
21
22
|
gem 'factory_girl'
|
22
23
|
gem 'sqlite3'
|
23
24
|
gem 'hashie'
|
25
|
+
gem 'redis'
|
24
26
|
end
|
data/Gemfile.lock
CHANGED
@@ -1,34 +1,34 @@
|
|
1
1
|
GEM
|
2
2
|
remote: http://rubygems.org/
|
3
3
|
specs:
|
4
|
-
activesupport (4.1
|
5
|
-
i18n (~> 0.
|
4
|
+
activesupport (4.2.1)
|
5
|
+
i18n (~> 0.7)
|
6
6
|
json (~> 1.7, >= 1.7.7)
|
7
7
|
minitest (~> 5.1)
|
8
|
-
thread_safe (~> 0.
|
8
|
+
thread_safe (~> 0.3, >= 0.3.4)
|
9
9
|
tzinfo (~> 1.1)
|
10
|
-
addressable (2.3.
|
10
|
+
addressable (2.3.8)
|
11
11
|
async-rack (0.5.1)
|
12
12
|
rack (~> 1.1)
|
13
13
|
builder (3.2.2)
|
14
14
|
descendants_tracker (0.0.4)
|
15
15
|
thread_safe (~> 0.3, >= 0.3.1)
|
16
16
|
diff-lcs (1.2.5)
|
17
|
-
em-synchrony (1.0.
|
17
|
+
em-synchrony (1.0.4)
|
18
18
|
eventmachine (>= 1.0.0.beta.1)
|
19
19
|
em-websocket (0.3.8)
|
20
20
|
addressable (>= 2.1.1)
|
21
21
|
eventmachine (>= 0.12.9)
|
22
|
-
eventmachine (1.0.
|
23
|
-
factory_girl (4.
|
22
|
+
eventmachine (1.0.7)
|
23
|
+
factory_girl (4.5.0)
|
24
24
|
activesupport (>= 3.0.0)
|
25
|
-
faraday (0.9.
|
25
|
+
faraday (0.9.1)
|
26
26
|
multipart-post (>= 1.2, < 3)
|
27
|
-
faye-websocket (0.
|
27
|
+
faye-websocket (0.9.2)
|
28
28
|
eventmachine (>= 0.12.0)
|
29
|
-
websocket-driver (>= 0.
|
30
|
-
ffi (1.9.
|
31
|
-
git (1.2.
|
29
|
+
websocket-driver (>= 0.5.1)
|
30
|
+
ffi (1.9.8)
|
31
|
+
git (1.2.9.1)
|
32
32
|
github_api (0.11.3)
|
33
33
|
addressable (~> 2.3)
|
34
34
|
descendants_tracker (~> 0.0.1)
|
@@ -48,10 +48,13 @@ GEM
|
|
48
48
|
rack (>= 1.2.2)
|
49
49
|
rack-contrib
|
50
50
|
rack-respond_to
|
51
|
-
hashie (3.
|
52
|
-
highline (1.
|
51
|
+
hashie (3.4.1)
|
52
|
+
highline (1.7.2)
|
53
53
|
http_parser.rb (0.6.0)
|
54
|
-
|
54
|
+
httparty (0.13.3)
|
55
|
+
json (~> 1.8)
|
56
|
+
multi_xml (>= 0.5.2)
|
57
|
+
i18n (0.7.0)
|
55
58
|
jeweler (2.0.1)
|
56
59
|
builder
|
57
60
|
bundler (>= 1.0)
|
@@ -61,23 +64,23 @@ GEM
|
|
61
64
|
nokogiri (>= 1.5.10)
|
62
65
|
rake
|
63
66
|
rdoc
|
64
|
-
json (1.8.
|
65
|
-
jwt (1.
|
67
|
+
json (1.8.2)
|
68
|
+
jwt (1.4.1)
|
66
69
|
log4r (1.1.10)
|
67
|
-
logmaster (0.1.
|
70
|
+
logmaster (0.1.5)
|
68
71
|
pony
|
69
72
|
mail (2.6.3)
|
70
73
|
mime-types (>= 1.16, < 3)
|
71
|
-
mime-types (2.
|
72
|
-
mini_portile (0.6.
|
73
|
-
minitest (5.
|
74
|
-
money-tree (0.8.
|
74
|
+
mime-types (2.5)
|
75
|
+
mini_portile (0.6.2)
|
76
|
+
minitest (5.6.1)
|
77
|
+
money-tree (0.8.9)
|
75
78
|
ffi
|
76
|
-
multi_json (1.
|
79
|
+
multi_json (1.11.0)
|
77
80
|
multi_xml (0.5.5)
|
78
81
|
multipart-post (2.0.0)
|
79
|
-
nokogiri (1.6.
|
80
|
-
mini_portile (
|
82
|
+
nokogiri (1.6.6.2)
|
83
|
+
mini_portile (~> 0.6.0)
|
81
84
|
oauth2 (1.0.0)
|
82
85
|
faraday (>= 0.8, < 0.10)
|
83
86
|
jwt (~> 1.0)
|
@@ -86,37 +89,42 @@ GEM
|
|
86
89
|
rack (~> 1.2)
|
87
90
|
pony (1.11)
|
88
91
|
mail (>= 2.0)
|
89
|
-
rack (1.
|
92
|
+
rack (1.6.0)
|
90
93
|
rack-accept-media-types (0.9)
|
91
|
-
rack-contrib (1.
|
94
|
+
rack-contrib (1.2.0)
|
92
95
|
rack (>= 0.9.1)
|
93
96
|
rack-respond_to (0.9.8)
|
94
97
|
rack-accept-media-types (>= 0.6)
|
95
|
-
rake (10.
|
96
|
-
rdoc (4.
|
97
|
-
|
98
|
-
rspec (3.
|
99
|
-
rspec-core (~> 3.
|
100
|
-
rspec-expectations (~> 3.
|
101
|
-
rspec-mocks (~> 3.
|
102
|
-
rspec-core (3.
|
103
|
-
rspec-support (~> 3.
|
104
|
-
rspec-expectations (3.1
|
98
|
+
rake (10.4.2)
|
99
|
+
rdoc (4.2.0)
|
100
|
+
redis (3.2.1)
|
101
|
+
rspec (3.2.0)
|
102
|
+
rspec-core (~> 3.2.0)
|
103
|
+
rspec-expectations (~> 3.2.0)
|
104
|
+
rspec-mocks (~> 3.2.0)
|
105
|
+
rspec-core (3.2.3)
|
106
|
+
rspec-support (~> 3.2.0)
|
107
|
+
rspec-expectations (3.2.1)
|
108
|
+
diff-lcs (>= 1.2.0, < 2.0)
|
109
|
+
rspec-support (~> 3.2.0)
|
110
|
+
rspec-mocks (3.2.1)
|
105
111
|
diff-lcs (>= 1.2.0, < 2.0)
|
106
|
-
rspec-support (~> 3.
|
107
|
-
rspec-
|
108
|
-
rspec-support (~> 3.1.0)
|
109
|
-
rspec-support (3.1.0)
|
112
|
+
rspec-support (~> 3.2.0)
|
113
|
+
rspec-support (3.2.2)
|
110
114
|
ruby-hmac (0.4.0)
|
111
|
-
satoshi-unit (0.1.
|
112
|
-
sequel (4.
|
113
|
-
sqlite3 (1.3.
|
115
|
+
satoshi-unit (0.1.7)
|
116
|
+
sequel (4.22.0)
|
117
|
+
sqlite3 (1.3.10)
|
114
118
|
straight (0.1.0)
|
119
|
+
httparty
|
115
120
|
money-tree
|
116
|
-
|
121
|
+
satoshi-unit
|
122
|
+
thread_safe (0.3.5)
|
117
123
|
tzinfo (1.2.2)
|
118
124
|
thread_safe (~> 0.1)
|
119
|
-
websocket-driver (0.
|
125
|
+
websocket-driver (0.5.4)
|
126
|
+
websocket-extensions (>= 0.1.0)
|
127
|
+
websocket-extensions (0.1.2)
|
120
128
|
|
121
129
|
PLATFORMS
|
122
130
|
ruby
|
@@ -128,8 +136,10 @@ DEPENDENCIES
|
|
128
136
|
github_api (= 0.11.3)
|
129
137
|
goliath
|
130
138
|
hashie
|
139
|
+
httparty
|
131
140
|
jeweler (~> 2.0.1)
|
132
|
-
logmaster (= 0.1.
|
141
|
+
logmaster (= 0.1.5)
|
142
|
+
redis
|
133
143
|
rspec
|
134
144
|
ruby-hmac
|
135
145
|
satoshi-unit
|
data/Gemfile.travis
ADDED
@@ -0,0 +1,26 @@
|
|
1
|
+
source "http://rubygems.org"
|
2
|
+
|
3
|
+
gem "straight", git: "https://github.com/snitko/straight.git"
|
4
|
+
gem "satoshi-unit"
|
5
|
+
gem "goliath"
|
6
|
+
gem "faye-websocket"
|
7
|
+
gem "sequel"
|
8
|
+
gem "logmaster", '0.1.5'
|
9
|
+
gem "ruby-hmac"
|
10
|
+
gem "httparty"
|
11
|
+
|
12
|
+
# Add dependencies to develop your gem here.
|
13
|
+
# Include everything needed to run rake, tests, features, etc.
|
14
|
+
group :development do
|
15
|
+
gem "bundler", "~> 1.0"
|
16
|
+
gem "jeweler", "~> 2.0.1"
|
17
|
+
gem "github_api", "0.11.3"
|
18
|
+
end
|
19
|
+
|
20
|
+
group :test do
|
21
|
+
gem 'rspec'
|
22
|
+
gem 'factory_girl'
|
23
|
+
gem 'sqlite3'
|
24
|
+
gem 'hashie'
|
25
|
+
gem 'redis'
|
26
|
+
end
|
data/README.md
CHANGED
@@ -1,9 +1,16 @@
|
|
1
1
|
Straight server
|
2
2
|
===============
|
3
|
-
> A stand-alone Bitcoin payment gateway server
|
3
|
+
> A stand-alone Bitcoin payment gateway server.
|
4
4
|
> Receives bitcoin payments directly into your wallet, holds no private keys
|
5
|
+
>
|
6
|
+
> It is used as a backend for the hosted service http://gear.mycelium.com
|
7
|
+
> Instead of installing the gateway yourself, you can just use
|
8
|
+
> Mycelium Gear and accept payments through it. Of course, straight
|
9
|
+
> into your wallet again - no private key required.
|
5
10
|
|
6
|
-
> Website: http://
|
11
|
+
> Website: http://gear.mycelium.com
|
12
|
+
|
13
|
+
[![Build Status](https://travis-ci.org/snitko/straight-server.svg)](https://travis-ci.org/snitko/straight-server)
|
7
14
|
|
8
15
|
If you'd like to accept Bitcoin payments on your website automatically, but you're not
|
9
16
|
fond of services like Coinbase or Bitpay, which hold your bitcoins for you and require a ton
|
@@ -95,6 +102,22 @@ You can also subscribe to the order status changes using websockets at:
|
|
95
102
|
|
96
103
|
It will send a message to the client upon the status change and close connection afterwards.
|
97
104
|
|
105
|
+
**Order expiration**
|
106
|
+
means that after a certain time has passed, it is no longer possible to pay for it. Each order holds
|
107
|
+
its creation time in `#created_at` field. In turn, each order's gateway has a field called
|
108
|
+
`#orders_expiration_period` (you can set it as an option in config file for each particular gateway or in the DB,
|
109
|
+
depending on what approach to storing gateways you use). After this time has passed, straight-server stops
|
110
|
+
checking whether new transactions appear on the order's bitcoin address and also changes order's status to 5 (expired).
|
111
|
+
|
112
|
+
Implications of restarting the server
|
113
|
+
-------------------------------------
|
114
|
+
|
115
|
+
If you shut the server down and then start it again, all unresolved orders (status < 2 and non-expired)
|
116
|
+
are automatically picked up and the server starts checking on them again until they expire. Please note
|
117
|
+
that you'd need to make sure your client side reconnects to the order's websocket again. This is because
|
118
|
+
on server shutdown, all websocket connections are closed, therefore, there's no way to automatically restore them.
|
119
|
+
It is thus client's responsibility to check when websocket is closed, then periodically try to connect to it again.
|
120
|
+
|
98
121
|
Client Example
|
99
122
|
--------------
|
100
123
|
I've implemented a small client example app written purely in Dart. It creates new orders,
|
@@ -120,7 +143,8 @@ To create an order for the new gateway, simply send this request:
|
|
120
143
|
Notice that the gateway id has changed to 2. Gateway ids are assigned according to the order in
|
121
144
|
which they follow in the config file.
|
122
145
|
|
123
|
-
|
146
|
+
Gateways from DB
|
147
|
+
----------------
|
124
148
|
When you have too many gateways, it is unwise to keep them in the config file. In that case,
|
125
149
|
you can store gateway settings in the DB. To do that, change `~/.straight/config.yml` setting
|
126
150
|
'gateways_source: config` to `gateways_source: db`.
|
@@ -131,8 +155,8 @@ there is no standard way to manage gateways through a web interface. In the futu
|
|
131
155
|
In general, it shouldn't be difficult, and may look like this:
|
132
156
|
|
133
157
|
$ straight-console
|
134
|
-
|
135
|
-
>
|
158
|
+
|
159
|
+
> gateway = Gateway.new
|
136
160
|
> gateway.pubkey = 'xpub1234'
|
137
161
|
> gateway.confirmations_required = 0
|
138
162
|
> gateway.order_class = 'StraightServer::Order'
|
@@ -140,6 +164,25 @@ In general, it shouldn't be difficult, and may look like this:
|
|
140
164
|
> gateway.save
|
141
165
|
> exit
|
142
166
|
|
167
|
+
One important thing to remember when using DB based Gateways is that when you want to issue a request to
|
168
|
+
create a new order, you must use `Gateway#hashed_id` instead of `#id`. This is because otherwise it becomes very easy
|
169
|
+
for a third-party to just go through gateways consecutively.
|
170
|
+
|
171
|
+
For example, suppose you have a DB based gateway with id 23. The incorrect request to create a new order would be
|
172
|
+
|
173
|
+
POST /gateways/23/orders?amount=1 # THIS IS WRONG!
|
174
|
+
|
175
|
+
We first need to find that gateway's hashed id:
|
176
|
+
|
177
|
+
$ straight-console
|
178
|
+
|
179
|
+
> gateway = Gateway[23]
|
180
|
+
> gateway.hashed_id # => '587bb9b74e37f526eac47081ad61998726673760c77415d52a95bf38fba9cbe9'
|
181
|
+
|
182
|
+
And then we can make a correct request:
|
183
|
+
|
184
|
+
POST /gateways/587bb9b74e37f526eac47081ad61998726673760c77415d52a95bf38fba9cbe9/orders?amount=1
|
185
|
+
|
143
186
|
Using signatures
|
144
187
|
----------------
|
145
188
|
If you are running straight-server on a machine separate from your online stores, you
|
@@ -152,38 +195,32 @@ Go to your `~/.straight/config.yml` directory and set two options for each of yo
|
|
152
195
|
check_signature: true
|
153
196
|
|
154
197
|
This will force gateways to check signatures when you try to create a new order. A signature is
|
155
|
-
a HMAC
|
198
|
+
a HMAC SHA256 hash of the secret and an order id. Because you need order id, it means you have
|
156
199
|
to actually provide it manually in the params. It can be any integer > 0, but it's better
|
157
200
|
that it is a consecutive integer, so keep track of order ids in your application. Obviously,
|
158
201
|
if an order with such an id already exists, the request will be rejected. A possible request
|
159
202
|
(assuming secret is the line mentioned above in the sample config) would look like this:
|
160
203
|
|
161
|
-
POST /gateways/1/orders?amount=1&order_id=1&signature=
|
204
|
+
POST /gateways/1/orders?amount=1&order_id=1&signature=aa14c26b2ae892a8719b0c2c57f162b967bfbfbdcc38d8883714a0680cf20467
|
162
205
|
|
163
206
|
An example of obtaining such signature in Ruby:
|
164
207
|
|
165
|
-
require '
|
166
|
-
require 'hmac-sha1'
|
208
|
+
require 'openssl'
|
167
209
|
|
168
210
|
secret = 'a long string of random chars'
|
169
|
-
|
170
|
-
h << '1' # order id
|
171
|
-
h.hexdigest
|
211
|
+
OpenSSL::HMAC.digest('sha256', secret, "1").unpack("H*").first # "1" may be order_id here
|
172
212
|
|
173
213
|
Straight server will also sign the callback url request. However, since the signature may be
|
174
214
|
known to an attacker once it was used for creating a new order, we can no longer use it directly.
|
175
215
|
Thus, Straight server will use a double signature calculated like this:
|
176
216
|
|
177
217
|
secret = 'a long string of random chars'
|
178
|
-
|
179
|
-
|
180
|
-
h2 = HMAC::SHA1.new(secret)
|
181
|
-
h2 << h.hexdigest
|
182
|
-
h2.hexdigest
|
218
|
+
h1 = OpenSSL::HMAC.digest('sha256', secret, "1").unpack("H*").first
|
219
|
+
h2 = OpenSSL::HMAC.digest('sha256', secret, h1).unpack("H*").first
|
183
220
|
|
184
221
|
and then send the request to the callback url with that signature:
|
185
222
|
|
186
|
-
GET http://mystore.com/payment-callback?order_id=1&amount=1&status=2&address=1NZov2nm6gRCGW6r4q1qHtxXurrWNpPr1q&tid=tid1&data=some+random+data?signature=
|
223
|
+
GET http://mystore.com/payment-callback?order_id=1&amount=1&status=2&address=1NZov2nm6gRCGW6r4q1qHtxXurrWNpPr1q&tid=tid1&data=some+random+data?signature=aa14c26b2ae892a8719b0c2c57f162b967bfbfbdcc38d8883714a0680cf20467
|
187
224
|
|
188
225
|
It is now up to your application to calculate that signature, compare it and
|
189
226
|
make sure that only one such request is allowed (that is, if signature was used, it cannot be used again).
|
@@ -192,9 +229,40 @@ Querying the blockchain
|
|
192
229
|
-----------------------
|
193
230
|
Straight currently uses third-party services, such as Blokchain.info and Helloblock.io to track
|
194
231
|
addresses and fetch transaction info. This means, you don't need to install bitcoind and store
|
195
|
-
the whole blockchain on your server. If one service is down, it will automatically switch to another one.
|
232
|
+
the whole blockchain on your server. If one service is down, it will automatically switch to another one.
|
233
|
+
I will be adding more adapters in the future. It will also be possible to implement a cross check where if
|
234
|
+
one service is lying about a transaction, I can check with another. In the future, I will add bitcoind support
|
235
|
+
too for those who do not trust third-party services.
|
236
|
+
|
237
|
+
To sum it up, there is nothing in the architecture of this software that says you should rely on third party services
|
238
|
+
to query the blockchain.
|
239
|
+
|
240
|
+
Counting orders
|
241
|
+
---------------
|
242
|
+
For easy statistics and reports, it is desirable to know how many orders of each particular status each gateway has.
|
243
|
+
For that reason optional order counters are implemented. To enable order counters, you must first install manually *redis-server*
|
244
|
+
and then *redis* rubygem.
|
245
|
+
|
246
|
+
Then edit your config file and make sure the following options are set:
|
196
247
|
|
197
|
-
|
248
|
+
environment: development # name your environment here
|
249
|
+
count_orders: true # enable order counting feature
|
250
|
+
|
251
|
+
redis:
|
252
|
+
host: localhost
|
253
|
+
port: 6379
|
254
|
+
db: null # change to 1, 2, 3 etc. or leave as is
|
255
|
+
password: null # if no password is needed, leave as is
|
256
|
+
|
257
|
+
After restarting the server, you can use `Gateway#order_counters` method which will
|
258
|
+
return a hash of all the counters. Here's an example output:
|
259
|
+
|
260
|
+
{ new: 132, unconfirmed: 0, paid: 34, underpaid: 1, overpaid: 2, expired: 55 }
|
261
|
+
|
262
|
+
The default behaviour is to cache the output, so if you want fresh values, use `reload: true`
|
263
|
+
option on this method:
|
264
|
+
|
265
|
+
Gateway#order_counters(reload: true)
|
198
266
|
|
199
267
|
Running in production
|
200
268
|
---------------------
|
@@ -212,6 +280,93 @@ turn on email notifications, so that when a FATAL errors occurs, an email is sen
|
|
212
280
|
|
213
281
|
I would also recommend you to use something like *monit* daemon to monitor a *straight-server* process.
|
214
282
|
|
283
|
+
Running in different environments
|
284
|
+
---------------------------------
|
285
|
+
Additionally, there is a `--config-dir` (short version is `-c`) option that allows you to set the
|
286
|
+
config directory for the server. It becomes quite convenient if you decide to run, for example, both
|
287
|
+
production and staging instances on one machine. I decided against having config file sections for each environment
|
288
|
+
as this would be more complicated and quite unnatural. Apart from different config files, one might argue you can have
|
289
|
+
a different set of addons and different versions of them in the `~/.straight/addons` dir. So it's better to keep them separate.
|
290
|
+
|
291
|
+
If you think of wrong examples out there, consider Rails: why would I want to have a database.yml file with both
|
292
|
+
development and production sections if I know for sure I'm only running this instance in production env?
|
293
|
+
|
294
|
+
So, with straight, you can simply create a separate config dir for each instance. For example, if I want to run
|
295
|
+
both production and staging on my server, I'd do this:
|
296
|
+
|
297
|
+
1. Create `~/.straight/production` and `~/.straight/staging` dirs
|
298
|
+
2. Run two instances like this:
|
299
|
+
|
300
|
+
straight-server --config-dir=~/.straight/production
|
301
|
+
straight-server --config-dir=~/.straight/staging
|
302
|
+
|
303
|
+
It's worth saying that currently, there is no default settings for production, staging or development.
|
304
|
+
It is you who defines what a production or a staging environment is, by changing the config file. Those words
|
305
|
+
are only used as examples. You may call your environment whatever you like.
|
306
|
+
|
307
|
+
However, environment name is currently used as a prefix for gateway order counters Redis entries
|
308
|
+
(see the respective README section). You can set the current environment name using a config file option, for example:
|
309
|
+
|
310
|
+
environment: development
|
311
|
+
|
312
|
+
Addons
|
313
|
+
------
|
314
|
+
WARNING: this is currently work in progress. The final specification of how addons should be added
|
315
|
+
and how they interact with the server may change.
|
316
|
+
|
317
|
+
Currently there is only one use case for addons and thus only one way in which addons can interact with the server itself:
|
318
|
+
adding controllers and routes for them. Now let's look at how we should do that:
|
319
|
+
|
320
|
+
1. All addons are placed under `~/.straight/addons/` (of course, it is wise to use symlinks).
|
321
|
+
|
322
|
+
2. `./straight/addons.yml` file lists addons and tells straight-server what are the names of the files to be loaded.
|
323
|
+
The format of the file is the following:
|
324
|
+
|
325
|
+
my_addon # <- name doesn't affect anything, just shows up in the log file
|
326
|
+
path: addons/my_addon/lib/my_addon # <- This is unnecessary if addon is already in the LOAD_PATH
|
327
|
+
module: MyAddon # <- actual module should be a submodule of StraightServer::Addon
|
328
|
+
|
329
|
+
3. In `./straight/addons/my_addon/lib/` we will place two files, `my_addon.rb` and 'my_controller.rb'. Below is their contents:
|
330
|
+
|
331
|
+
|
332
|
+
# my_addon.rb
|
333
|
+
|
334
|
+
require_relative 'my_controller'
|
335
|
+
|
336
|
+
module StraightServer
|
337
|
+
module Addon
|
338
|
+
module MyAddon
|
339
|
+
|
340
|
+
def self.extended(obj)
|
341
|
+
obj.add_route /\A\/my_controller/.*\Z/ do |env|
|
342
|
+
controller = MyController.new(env)
|
343
|
+
controller.show
|
344
|
+
end
|
345
|
+
end
|
346
|
+
|
347
|
+
end
|
348
|
+
end
|
349
|
+
end
|
350
|
+
|
351
|
+
As you can guess, `#add_route` is a straight-server's special method for defining routes, very similar to Rails.
|
352
|
+
The piece of code above will force all requests where urls are starting with `/my_controller` to be handled by
|
353
|
+
`MyController#show`:
|
354
|
+
|
355
|
+
|
356
|
+
# my_controller.rb
|
357
|
+
|
358
|
+
module StraightServer
|
359
|
+
class MyController
|
360
|
+
def show
|
361
|
+
[200, {}, "Hello world! This is MyController speaking!"]
|
362
|
+
end
|
363
|
+
end
|
364
|
+
end
|
365
|
+
|
366
|
+
And this in turn will render us the text "Hello world! This is MyController speaking!".
|
367
|
+
Here, we've just created our first addon.
|
368
|
+
|
369
|
+
|
215
370
|
Requirements
|
216
371
|
------------
|
217
372
|
Ruby 2.1 or later.
|
@@ -220,8 +375,6 @@ Donations
|
|
220
375
|
---------
|
221
376
|
To go on with this project and make it truly awesome, I need more time. I can only buy free time with money, so any donation is highly appreciated. Please send bitcoins over to **1D3PknG4Lw1gFuJ9SYenA7pboF9gtXtdcD**
|
222
377
|
|
223
|
-
There are [development plans](http://straight.romansnitko.com/#todo) for this software you might be interested in.
|
224
|
-
|
225
378
|
Credits
|
226
379
|
-------
|
227
380
|
Author: [Roman Snitko](http://romansnitko.com)
|
data/Rakefile
CHANGED
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.
|
1
|
+
0.2.0
|
@@ -0,0 +1,15 @@
|
|
1
|
+
# This is where you put info about your addons.
|
2
|
+
#
|
3
|
+
# Addons are just modules that extend the StraightServer::Server module.
|
4
|
+
#
|
5
|
+
# Addon modules can be both rubygems or files under ~/.straight/addons/.
|
6
|
+
# If ~/.straight/addons.yml contains a 'path' key for a particular addon, then it means
|
7
|
+
# the addon is placed under the ~/.straight/addons/. If not, it is assumed it is
|
8
|
+
# already in the LOAD_PATH somehow, with rubygems for example.
|
9
|
+
#
|
10
|
+
#
|
11
|
+
# Example:
|
12
|
+
#
|
13
|
+
# payment_ui: # <- name doesn't affect anything, just shows up in the log file
|
14
|
+
# path: addons/payment_ui # <- This is unnecessary if addon is already in the LOAD_PATH
|
15
|
+
# module: PaymentUI # <- actual module should be a submodule of StraightServer::Addon
|
@@ -0,0 +1,78 @@
|
|
1
|
+
# If set to db, then use DB table to store gateways,
|
2
|
+
# useful when your run many gateways on the same server.
|
3
|
+
gateways_source: config
|
4
|
+
|
5
|
+
environment: development
|
6
|
+
|
7
|
+
# This enabled order counting using Redis. Please see he README file for details.
|
8
|
+
# You're gonna need to install redis-server and redis rubygem on your system and provide
|
9
|
+
# redis-server connection details below.
|
10
|
+
count_orders: false
|
11
|
+
|
12
|
+
# Uncomment this if you want to use Gateway's order counters feature
|
13
|
+
# It requires redis.
|
14
|
+
#redis:
|
15
|
+
#host: localhost
|
16
|
+
#port: 6380
|
17
|
+
#db: null # change to 1, 2, 3 etc. or leave as is
|
18
|
+
#password: null # if no password is needed, leave as is
|
19
|
+
|
20
|
+
gateways:
|
21
|
+
default:
|
22
|
+
pubkey: xpub6AHA9hZDN11k2ijHMeS5QqHx2KP9aMBRhTDqANMnwVtdyw2TDYRmF8PjpvwUFcL1Et8Hj59S3gTSMcUQ5gAqTz3Wd8EsMTmF3DChhqPQBnU
|
23
|
+
confirmations_required: 0
|
24
|
+
order_class: "StraightServer::Order"
|
25
|
+
secret: 'secret'
|
26
|
+
check_signature: false
|
27
|
+
callback_url: 'http://localhost:3000/my_app/payment_callback'
|
28
|
+
default_currency: 'BTC'
|
29
|
+
orders_expiration_period: 600 # seconds
|
30
|
+
|
31
|
+
# This options decides whether we should also check the DB for status updates first
|
32
|
+
# when we check order status. That is, if we're tracking an order and this option
|
33
|
+
# is set to true, it first fetches the fields from the local DB, sees if the status has changed there,
|
34
|
+
# and if it did - we no longer need to query the blockchain.
|
35
|
+
#
|
36
|
+
# Usecase? Currently mostly debugging (so set it to false for production). For example,
|
37
|
+
# when testing payments, you don't actually want to pay, you can just run the server console,
|
38
|
+
# change order status in the DB and see how your client picks it up, showing you that your
|
39
|
+
# order has been paid for.
|
40
|
+
check_order_status_in_db_first: true # Consider changing to `false` in production.
|
41
|
+
|
42
|
+
# The order matters here, we check for prices with the first adapter,
|
43
|
+
# if it fails, move on to the next
|
44
|
+
exchange_rate_adapters:
|
45
|
+
- Bitpay
|
46
|
+
- Coinbase
|
47
|
+
- Bitstamp
|
48
|
+
|
49
|
+
# This affects whether it is possible to create a new order with the gateway.
|
50
|
+
# If it's set to false, then it won't be possible to create a new order, but
|
51
|
+
# it will keep checking on the existing ones.
|
52
|
+
active: true
|
53
|
+
|
54
|
+
logmaster:
|
55
|
+
log_level: INFO # Wise to change to WARN for production
|
56
|
+
file: straight.log
|
57
|
+
raise_exception: false
|
58
|
+
name: Straight server logger
|
59
|
+
|
60
|
+
# These options bellow send you email whenever a FATAL error occurs.
|
61
|
+
# You probably want to uncomment them for production. See https://github.com/snitko/logmaste
|
62
|
+
# for various email options.
|
63
|
+
#
|
64
|
+
#email_config:
|
65
|
+
#to: 'me@email.foo'
|
66
|
+
#from: "logmaster@yourapp.com"
|
67
|
+
|
68
|
+
db:
|
69
|
+
adapter: sqlite
|
70
|
+
name: straight.db # file is always located in ~/.straight
|
71
|
+
|
72
|
+
# No need to set these options for sqlite,
|
73
|
+
# but other DBs may require them.
|
74
|
+
#
|
75
|
+
#user: username
|
76
|
+
#password: password
|
77
|
+
#host: hostname
|
78
|
+
#port: 1234
|
@@ -0,0 +1 @@
|
|
1
|
+
1520
|
@@ -0,0 +1 @@
|
|
1
|
+
fyjoq0s7c07l7iwk
|
data/bin/goliath.log
ADDED
@@ -0,0 +1,6 @@
|
|
1
|
+
[10084:INFO] 2015-04-16 04:12:10 :: Starting server on 0.0.0.0:9696 in development mode. Watch out for stones.
|
2
|
+
[10084:INFO] 2015-04-16 04:12:21 :: Status: 200, Content-Length: 963, Response Time: 24.10ms
|
3
|
+
[10084:INFO] 2015-04-16 04:12:21 :: Status: 200, Content-Length: 366, Response Time: 3.11ms
|
4
|
+
[10084:INFO] 2015-04-16 04:12:26 :: Status: 200, Content-Length: 963, Response Time: 2.73ms
|
5
|
+
[10084:INFO] 2015-04-16 04:12:26 :: Status: 200, Content-Length: 366, Response Time: 3.25ms
|
6
|
+
[10084:INFO] 2015-04-16 04:12:40 :: Status: 500, Content-Length: 99, Response Time: 3.67ms
|