straight-server 0.1.2 → 0.2.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 +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
|
+
[](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
|