txcatcher 0.1.4 → 0.1.5
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/README.md +111 -6
- data/VERSION +1 -1
- data/lib/txcatcher/models/transaction.rb +5 -1
- data/lib/txcatcher/server.rb +7 -6
- data/spec/config/{config.yml → config.yml.sample} +2 -2
- data/spec/config/txcatcher_test.db +0 -0
- data/spec/models/transaction_spec.rb +3 -0
- data/templates/config.yml +4 -3
- data/txcatcher.gemspec +4 -4
- metadata +3 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 909ad770012c2bacccbb1e9f7438bf97e4c92d15
|
4
|
+
data.tar.gz: ec40ed49c4f006e30f4ff07be84fce1d2f05523f
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: f12b5d7ef16ba43904ec6cebc3ab77a3f1c8fad8588a67b5ad17d1f5076260dee01f21d20928a5f6ae287955ab6c5a83233a05402d8350bd79523e0700095b02
|
7
|
+
data.tar.gz: 3f737f4a9d32f9ae4c8f9011a3a03856cd55cf9dd4af3e517e0ded3d0dfd656d938bcf8a59008b6a32b9cfc37379ef90e1e0f78317be7f7e8d2b8ca438a3b061
|
data/README.md
CHANGED
@@ -1,11 +1,116 @@
|
|
1
|
-
|
1
|
+
TxCatcher
|
2
|
+
========
|
2
3
|
|
3
|
-
|
4
|
+
*TxCatcher* is a lightweight alternative to Bitpay's Insight (bitcoin and litecoin compatible)
|
5
|
+
The purpose of this software is to receive all incoming unconfirmed transactions,
|
6
|
+
store them in the DB along with addresses (outputs) and provide a simple API to check whether
|
7
|
+
a certain address received a deposit.
|
8
|
+
|
9
|
+
However, it doesn't rely on having full blockchain with either bitcoind or litecoind.
|
10
|
+
You can have pruning enabled (in fact, it's recommended) and the txcatcher's DB
|
11
|
+
is regularly cleaned, so it doesn't grow.
|
12
|
+
|
13
|
+
The point is to detect new transactions to an address and store them for at least a while,
|
14
|
+
but then get rid of them. It's ideal for lightweight payment processing.
|
15
|
+
|
16
|
+
API requests:
|
17
|
+
-------------
|
18
|
+
request: `/addr/2N8Xdi8FiWAT3Vuo2mzcCETnrBjeAtBiqiA`
|
19
|
+
response (JSON):
|
20
|
+
|
21
|
+
{
|
22
|
+
"address":"2N8Xdi8FiWAT3Vuo2mzcCETnrBjeAtBiqiA","received":2000000
|
23
|
+
"deposits":[
|
24
|
+
{
|
25
|
+
"txid":"4e6e1e491108b8302da8885b7e57b8809385d206346b3d287b6300408efe551c",
|
26
|
+
"amount":0.01,
|
27
|
+
"satoshis":1000000,
|
28
|
+
"confirmations":0,
|
29
|
+
"block_height":null
|
30
|
+
}
|
31
|
+
}
|
32
|
+
|
33
|
+
request: `/addr/2N8Xdi8FiWAT3Vuo2mzcCETnrBjeAtBiqiA/utxo`
|
34
|
+
response (JSON):
|
35
|
+
|
36
|
+
[{
|
37
|
+
"value":0.01,
|
38
|
+
"n":0,
|
39
|
+
"scriptPubKey":{"asm":"OP_HASH160 a7a458022e92dd04935c849ab2ea3b07373b7e4b OP_EQUAL","hex":"a914a7a458022e92dd04935c849ab2ea3b07373b7e4b87","reqSigs":1,"type":"scripthash","addresses":["2N8Xdi8FiWAT3Vuo2mzcCETnrBjeAtBiqiA"]},
|
40
|
+
"confirmations":5,
|
41
|
+
"txid":"4e6e1e491108b8302da8885b7e57b8809385d206346b3d287b6300408efe551c"
|
42
|
+
}]
|
43
|
+
|
44
|
+
You can also broadcast transactions by sending requests to `/tx/send` passing transaction in `rawtx` param.
|
45
|
+
|
46
|
+
|
47
|
+
Is that all?
|
48
|
+
-----------
|
49
|
+
For now - yes. It allows you to do basic stuff like checking what an address has received.
|
50
|
+
|
51
|
+
TODO:
|
52
|
+
* websockets for instant update notifications
|
53
|
+
* better configuration through command line args
|
54
|
+
|
55
|
+
|
56
|
+
What it does under the hood
|
57
|
+
---------------------------
|
58
|
+
* it uses bitcoind or litecoind with ZeroMQ to receive new transactions from the mempool
|
59
|
+
* it receives newly mined blocks so that we can tell how many confirmations a transaction to a certain
|
60
|
+
address has.
|
61
|
+
* regularly cleans the DB
|
62
|
+
|
63
|
+
Installation
|
4
64
|
------------
|
5
65
|
|
6
|
-
|
7
|
-
|
66
|
+
Install dependencies:
|
67
|
+
* zeromq
|
68
|
+
* rvm, ruby & rubygems
|
69
|
+
* sqlite3 or postgresql
|
70
|
+
* bitcoind or litecoind or both
|
71
|
+
|
72
|
+
Install txcatcher: `gem install txcatcher`
|
73
|
+
|
74
|
+
Configuring & Runing
|
75
|
+
--------------------
|
76
|
+
You're going to need a simple config file. By default, txcatcher looks in `~/.txcatcher` dir,
|
77
|
+
so create the dir and the file there: `mkdir ~/.txcatcher && touch ~/.txcatcher/config.yml`
|
78
|
+
Example config file can be found in [templates/config.yml](templates/config.yml), you might want
|
79
|
+
to copy the contents and edit it.
|
80
|
+
|
81
|
+
Once your bitcoin/litecoind finished syncing, you can start txcatcher with a simple command: `txcatcher`.
|
82
|
+
You can srart multiple instances of txcatcher, when, for example, you want instances of it
|
83
|
+
tracking both litecoin and bitcoin transactions:
|
84
|
+
|
85
|
+
txcatcher -c ~/.txcatcher/litecoin_config.yml
|
86
|
+
txcatcher -c ~/.txcatcher/bitcoin_config.yml
|
87
|
+
|
88
|
+
Upstart script
|
89
|
+
-------------
|
90
|
+
If running on Ubuntu, you may also want to create an upstart script, so here's an example (`/etc/init/txcatcher_btc.conf`):
|
91
|
+
|
92
|
+
start on started bitcoind
|
93
|
+
stop on shutdown
|
94
|
+
setuid deploy
|
95
|
+
respawn
|
96
|
+
respawn limit 10 90
|
97
|
+
|
98
|
+
env HOME="/home/deploy"
|
99
|
+
env RVM_WRAPPERS_PATH="/usr/local/rvm/gems/ruby-2.3.4/wrappers"
|
100
|
+
env TXCATCHER_CONFIG="/home/deploy/.txcatcher/config.yml"
|
8
101
|
|
9
|
-
|
102
|
+
exec ${RVM_WRAPPERS_PATH}/txcatcher -c ${TXCATCHER_CONFIG}
|
103
|
+
|
104
|
+
For this to work, you need a number of prerequisites:
|
105
|
+
* create a `deploy` user, make sure rvm works with this user (rvm multi-user installation)
|
106
|
+
* DO NOT daemonize the process in config.yml, set `daemonize: false` in `/home/deploy/.txcatcher/config.yml`
|
107
|
+
* Generate rvm wrapper for txcatcher: https://rvm.io/deployment/init-d
|
108
|
+
* Make sure your bitcoind or litecoind are also started with an upstart script: https://github.com/bitcoin/bitcoin/blob/0.13/contrib/init/bitcoind.conf
|
109
|
+
|
110
|
+
You can then start and stop txcatcher with `start txcatcher_btc` and `stop txcatcher_btc`.
|
10
111
|
|
11
|
-
|
112
|
+
Running unit tests
|
113
|
+
------------------
|
114
|
+
Before running unit tests, make sure you have bitcoind running in mainnet mode,
|
115
|
+
with RPC enabled and blockchain synced. Copy the `spec/config/config.yml.sample` file
|
116
|
+
and change the RPC username/password to match your bitcoind settings.
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.1.
|
1
|
+
0.1.5
|
@@ -1,6 +1,8 @@
|
|
1
1
|
module TxCatcher
|
2
2
|
|
3
3
|
class Transaction < Sequel::Model
|
4
|
+
|
5
|
+
plugin :validation_helpers
|
4
6
|
one_to_many :deposits
|
5
7
|
|
6
8
|
def before_validation
|
@@ -17,7 +19,7 @@ module TxCatcher
|
|
17
19
|
end
|
18
20
|
end
|
19
21
|
|
20
|
-
def
|
22
|
+
def after_create
|
21
23
|
self.deposits.each do |d|
|
22
24
|
d.transaction = self
|
23
25
|
d.save
|
@@ -47,6 +49,8 @@ module TxCatcher
|
|
47
49
|
end
|
48
50
|
|
49
51
|
def validate
|
52
|
+
super
|
53
|
+
validates_unique :txid
|
50
54
|
errors.add(:base, "No outputs for this transactions") if self.deposits.empty?
|
51
55
|
end
|
52
56
|
|
data/lib/txcatcher/server.rb
CHANGED
@@ -28,19 +28,20 @@ module TxCatcher
|
|
28
28
|
path = path.split("/").delete_if { |i| i.empty? }
|
29
29
|
addr = path.last
|
30
30
|
|
31
|
-
|
32
|
-
if
|
33
|
-
transactions_ids =
|
34
|
-
deposits =
|
31
|
+
address = Address.where(address: addr).eager(deposits: :transactions).first
|
32
|
+
if address
|
33
|
+
transactions_ids = address.deposits.map { |d| d.transaction.txid }
|
34
|
+
deposits = address.deposits.map do |d|
|
35
35
|
t = d.transaction
|
36
36
|
{
|
37
37
|
txid: t.txid,
|
38
38
|
amount: d.amount_in_btc,
|
39
39
|
satoshis: d.amount,
|
40
|
-
confirmations:
|
40
|
+
confirmations: t.confirmations,
|
41
|
+
block_height: t.block_height
|
41
42
|
}
|
42
43
|
end
|
43
|
-
[200, {}, { address:
|
44
|
+
[200, {}, { address: address.address, received: address.received, deposits: deposits }.to_json]
|
44
45
|
else
|
45
46
|
[200, {}, { address: addr, received: 0, deposits: [] }.to_json]
|
46
47
|
end
|
Binary file
|
@@ -17,10 +17,13 @@ RSpec.describe TxCatcher::Transaction do
|
|
17
17
|
end
|
18
18
|
|
19
19
|
it "doesn't create duplicate deposits if valid? called manually before save" do
|
20
|
+
TxCatcher::Transaction.select_all.delete
|
20
21
|
transaction = TxCatcher::Transaction.new(hex: @hextx)
|
21
22
|
transaction.valid?
|
22
23
|
transaction.save
|
23
24
|
expect(transaction.deposits.size).to eq(2)
|
25
|
+
transaction.update(block_height: 1)
|
26
|
+
expect(TxCatcher::Transaction.where(txid: transaction.txid).count).to eq(1)
|
24
27
|
end
|
25
28
|
|
26
29
|
end
|
data/templates/config.yml
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
db:
|
2
2
|
adapter: sqlite
|
3
|
-
db_path:
|
3
|
+
db_path: txcatcher.db
|
4
4
|
|
5
5
|
# No need to set these options for sqlite,
|
6
6
|
# but other DBs may require them.
|
@@ -12,8 +12,8 @@ db:
|
|
12
12
|
|
13
13
|
rpcnode:
|
14
14
|
name: bitcoind
|
15
|
-
user:
|
16
|
-
password:
|
15
|
+
user: user
|
16
|
+
password: password
|
17
17
|
host: 127.0.0.1
|
18
18
|
port: 8332
|
19
19
|
|
@@ -21,3 +21,4 @@ zeromq: bitcoind
|
|
21
21
|
max_db_transactions_stored: 100000
|
22
22
|
db_clean_period_seconds: 300
|
23
23
|
server_port: 9498
|
24
|
+
daemonize: false
|
data/txcatcher.gemspec
CHANGED
@@ -2,16 +2,16 @@
|
|
2
2
|
# DO NOT EDIT THIS FILE DIRECTLY
|
3
3
|
# Instead, edit Jeweler::Tasks in Rakefile, and run 'rake gemspec'
|
4
4
|
# -*- encoding: utf-8 -*-
|
5
|
-
# stub: txcatcher 0.1.
|
5
|
+
# stub: txcatcher 0.1.5 ruby lib
|
6
6
|
|
7
7
|
Gem::Specification.new do |s|
|
8
8
|
s.name = "txcatcher"
|
9
|
-
s.version = "0.1.
|
9
|
+
s.version = "0.1.5"
|
10
10
|
|
11
11
|
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
12
12
|
s.require_paths = ["lib"]
|
13
13
|
s.authors = ["Roman Snitko"]
|
14
|
-
s.date = "2017-09-
|
14
|
+
s.date = "2017-09-25"
|
15
15
|
s.description = "Ccurrently, the only job of this gem is to collect all new Bitcoin/Litecoin transactions, store them in a DB, index addresses."
|
16
16
|
s.email = "roman.snitko@gmail.com"
|
17
17
|
s.executables = ["goliath.log", "goliath_stdout.log", "txcatcher"]
|
@@ -49,7 +49,7 @@ Gem::Specification.new do |s|
|
|
49
49
|
"lib/txcatcher/utils/hash_string_to_sym_keys.rb",
|
50
50
|
"spec/catcher_spec.rb",
|
51
51
|
"spec/cleaner_spec.rb",
|
52
|
-
"spec/config/config.yml",
|
52
|
+
"spec/config/config.yml.sample",
|
53
53
|
"spec/config/txcatcher_test.db",
|
54
54
|
"spec/fixtures/transaction.txt",
|
55
55
|
"spec/fixtures/transaction_decoded_no_outputs.txt",
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: txcatcher
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.5
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Roman Snitko
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2017-09-
|
11
|
+
date: 2017-09-25 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: goliath
|
@@ -135,7 +135,7 @@ files:
|
|
135
135
|
- lib/txcatcher/utils/hash_string_to_sym_keys.rb
|
136
136
|
- spec/catcher_spec.rb
|
137
137
|
- spec/cleaner_spec.rb
|
138
|
-
- spec/config/config.yml
|
138
|
+
- spec/config/config.yml.sample
|
139
139
|
- spec/config/txcatcher_test.db
|
140
140
|
- spec/fixtures/transaction.txt
|
141
141
|
- spec/fixtures/transaction_decoded_no_outputs.txt
|