bitsy-bitcoin 0.0.1
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 +7 -0
- data/MIT-LICENSE +20 -0
- data/Rakefile +23 -0
- data/app/assets/javascripts/bitsy/application.js +13 -0
- data/app/assets/stylesheets/bitsy/application.css +15 -0
- data/app/controllers/bitsy/application_controller.rb +4 -0
- data/app/controllers/bitsy/v1/payment_depots_controller.rb +29 -0
- data/app/controllers/bitsy/v1/syncs_controller.rb +11 -0
- data/app/controllers/bitsy/v1/truncations_controller.rb +11 -0
- data/app/helpers/bitsy/application_helper.rb +4 -0
- data/app/jobs/bitsy/payment_job.rb +14 -0
- data/app/models/bitsy/payment_depot.rb +125 -0
- data/app/models/bitsy/payment_transaction.rb +51 -0
- data/app/serializers/bitsy/payment_depot_serializer.rb +16 -0
- data/app/services/bitsy/amount_for_initial_tax_calculator.rb +18 -0
- data/app/services/bitsy/associates_transactions.rb +13 -0
- data/app/services/bitsy/builds_send_many_hash.rb +35 -0
- data/app/services/bitsy/creates_transaction.rb +25 -0
- data/app/services/bitsy/forward_tax_calculator.rb +17 -0
- data/app/services/bitsy/forwards_payments.rb +31 -0
- data/app/services/bitsy/processes_payments.rb +20 -0
- data/app/services/bitsy/selects_transactions_for_sync.rb +13 -0
- data/app/services/bitsy/sends_payments.rb +14 -0
- data/app/services/bitsy/stockpiles_transaction.rb +24 -0
- data/app/services/bitsy/syncs_transaction.rb +26 -0
- data/app/services/bitsy/syncs_transactions.rb +17 -0
- data/app/services/bitsy/updates_transaction.rb +13 -0
- data/app/views/layouts/bitsy/application.html.erb +14 -0
- data/config/bitsy.yml +19 -0
- data/config/initializers/bitsy.rb +16 -0
- data/config/routes.rb +11 -0
- data/db/migrate/20140607015614_create_bitsy_payment_depots.rb +18 -0
- data/db/migrate/20140607015859_create_bitsy_payment_transactions.rb +17 -0
- data/lib/bitsy.rb +39 -0
- data/lib/bitsy/config.rb +28 -0
- data/lib/bitsy/engine.rb +8 -0
- data/lib/bitsy/version.rb +3 -0
- data/lib/clock.rb +10 -0
- data/lib/generators/bitsy/config/templates/bitsy.yml +19 -0
- data/lib/generators/bitsy/config/templates/initializer.rb +16 -0
- data/lib/generators/bitsy/config_generator.rb +33 -0
- data/lib/tasks/bitsy_tasks.rake +4 -0
- metadata +344 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 44f785dde6fd7ae7af5ce67976e67b1e353f8d55
|
4
|
+
data.tar.gz: 7fefa972daa9873c6c5c008903c05f8cc24f14dc
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: fa0e5593e0c381e21eeeccb82a696d1bc24614310dcb49627e70d9ed06df471e21ec2a68538ad11874ea4b2ede49e963781c8126148f16a5422694ae09b36109
|
7
|
+
data.tar.gz: ceaf5517db9d04d0cd137cc28c69ec86dabb3de056cf5c23926a2ff2a39c5e431c7843503e50d9c28112166204407a66fd95f7bb106f1a4db15307b6879453c6
|
data/MIT-LICENSE
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright 2014 YOURNAME
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
4
|
+
a copy of this software and associated documentation files (the
|
5
|
+
"Software"), to deal in the Software without restriction, including
|
6
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
7
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
8
|
+
permit persons to whom the Software is furnished to do so, subject to
|
9
|
+
the following conditions:
|
10
|
+
|
11
|
+
The above copyright notice and this permission notice shall be
|
12
|
+
included in all copies or substantial portions of the Software.
|
13
|
+
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
15
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
16
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
17
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
18
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
19
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
20
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/Rakefile
ADDED
@@ -0,0 +1,23 @@
|
|
1
|
+
begin
|
2
|
+
require 'bundler/setup'
|
3
|
+
rescue LoadError
|
4
|
+
puts 'You must `gem install bundler` and `bundle install` to run rake tasks'
|
5
|
+
end
|
6
|
+
|
7
|
+
require 'rdoc/task'
|
8
|
+
|
9
|
+
RDoc::Task.new(:rdoc) do |rdoc|
|
10
|
+
rdoc.rdoc_dir = 'rdoc'
|
11
|
+
rdoc.title = 'Bitsy'
|
12
|
+
rdoc.options << '--line-numbers'
|
13
|
+
rdoc.rdoc_files.include('README.rdoc')
|
14
|
+
rdoc.rdoc_files.include('lib/**/*.rb')
|
15
|
+
end
|
16
|
+
|
17
|
+
APP_RAKEFILE = File.expand_path("../spec/dummy/Rakefile", __FILE__)
|
18
|
+
load 'rails/tasks/engine.rake'
|
19
|
+
|
20
|
+
|
21
|
+
|
22
|
+
Bundler::GemHelper.install_tasks
|
23
|
+
|
@@ -0,0 +1,13 @@
|
|
1
|
+
// This is a manifest file that'll be compiled into application.js, which will include all the files
|
2
|
+
// listed below.
|
3
|
+
//
|
4
|
+
// Any JavaScript/Coffee file within this directory, lib/assets/javascripts, vendor/assets/javascripts,
|
5
|
+
// or vendor/assets/javascripts of plugins, if any, can be referenced here using a relative path.
|
6
|
+
//
|
7
|
+
// It's not advisable to add code directly here, but if you do, it'll appear at the bottom of the
|
8
|
+
// compiled file.
|
9
|
+
//
|
10
|
+
// Read Sprockets README (https://github.com/sstephenson/sprockets#sprockets-directives) for details
|
11
|
+
// about supported directives.
|
12
|
+
//
|
13
|
+
//= require_tree .
|
@@ -0,0 +1,15 @@
|
|
1
|
+
/*
|
2
|
+
* This is a manifest file that'll be compiled into application.css, which will include all the files
|
3
|
+
* listed below.
|
4
|
+
*
|
5
|
+
* Any CSS and SCSS file within this directory, lib/assets/stylesheets, vendor/assets/stylesheets,
|
6
|
+
* or vendor/assets/stylesheets of plugins, if any, can be referenced here using a relative path.
|
7
|
+
*
|
8
|
+
* You're free to add application-wide styles to this file and they'll appear at the bottom of the
|
9
|
+
* compiled file so the styles you add here take precedence over styles defined in any styles
|
10
|
+
* defined in the other CSS/SCSS files in this directory. It is generally better to create a new
|
11
|
+
* file per style scope.
|
12
|
+
*
|
13
|
+
*= require_tree .
|
14
|
+
*= require_self
|
15
|
+
*/
|
@@ -0,0 +1,29 @@
|
|
1
|
+
module Bitsy
|
2
|
+
module V1
|
3
|
+
class PaymentDepotsController < ApplicationController
|
4
|
+
|
5
|
+
def show
|
6
|
+
@payment_depot = PaymentDepot.find(params[:id])
|
7
|
+
render json: @payment_depot
|
8
|
+
end
|
9
|
+
|
10
|
+
def create
|
11
|
+
@payment_depot = PaymentDepot.create(payment_depot_params)
|
12
|
+
render json: @payment_depot
|
13
|
+
end
|
14
|
+
|
15
|
+
private
|
16
|
+
|
17
|
+
def payment_depot_params
|
18
|
+
params.require(:payment_depot).permit(
|
19
|
+
:min_payment,
|
20
|
+
:initial_tax_rate,
|
21
|
+
:added_tax_rate,
|
22
|
+
:owner_address,
|
23
|
+
:tax_address,
|
24
|
+
)
|
25
|
+
end
|
26
|
+
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
@@ -0,0 +1,125 @@
|
|
1
|
+
require 'securerandom'
|
2
|
+
|
3
|
+
module Bitsy
|
4
|
+
class PaymentDepot < ActiveRecord::Base
|
5
|
+
has_many :transactions, class_name: 'PaymentTransaction'
|
6
|
+
|
7
|
+
alias_attribute :balance, :balance_cache
|
8
|
+
after_initialize :set_uuid
|
9
|
+
before_create :set_bitcoin_address
|
10
|
+
before_create :set_balance_cache
|
11
|
+
delegate :balance, to: :bit_wallet_account
|
12
|
+
scope :with_balance, -> { where('balance_cache > 0.0') }
|
13
|
+
validate(
|
14
|
+
:initial_tax_rate,
|
15
|
+
inclusion: {
|
16
|
+
in: [0.0..1.0],
|
17
|
+
message: 'must be a value within 0.0 and 1.0'
|
18
|
+
}
|
19
|
+
)
|
20
|
+
validate :address, uniqueness: true
|
21
|
+
validate :owner_address, presence: true
|
22
|
+
validate :tax_address, presence: true
|
23
|
+
validate :uuid, uniqueness: true, presence: true
|
24
|
+
|
25
|
+
delegate :bit_wallet, to: :Bitsy
|
26
|
+
|
27
|
+
def initial_owner_rate
|
28
|
+
self.min_payment * (1 - self.initial_tax_rate)
|
29
|
+
end
|
30
|
+
|
31
|
+
def balance_tax_amount
|
32
|
+
ForwardTaxCalculator.calculate(self.balance,
|
33
|
+
self.min_payment,
|
34
|
+
self.total_received_amount,
|
35
|
+
self.initial_tax_rate,
|
36
|
+
self.added_tax_rate)
|
37
|
+
end
|
38
|
+
|
39
|
+
def total_received_amount
|
40
|
+
self.transactions.credits.sum(:amount)
|
41
|
+
end
|
42
|
+
|
43
|
+
def total_tax_sent
|
44
|
+
tax_transactions.sum(:amount).abs
|
45
|
+
end
|
46
|
+
|
47
|
+
def total_owner_sent
|
48
|
+
owner_transactions.sum(:amount).abs
|
49
|
+
end
|
50
|
+
|
51
|
+
def min_payment_received?
|
52
|
+
self.total_received_amount >= self.min_payment
|
53
|
+
end
|
54
|
+
|
55
|
+
def initial_fee_received
|
56
|
+
if min_payment_received?
|
57
|
+
self.min_payment
|
58
|
+
else
|
59
|
+
self.total_received_amount
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
def added_fee_received
|
64
|
+
if min_payment_received?
|
65
|
+
self.total_received_amount - self.min_payment
|
66
|
+
else
|
67
|
+
0.0
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
def initial_tax_amount
|
72
|
+
initial_fee_received * self.initial_tax_fee
|
73
|
+
end
|
74
|
+
|
75
|
+
def added_tax_amount
|
76
|
+
added_fee_received * self.added_tax_fee
|
77
|
+
end
|
78
|
+
|
79
|
+
def balance
|
80
|
+
self.balance_cache = bit_wallet_account_balance
|
81
|
+
end
|
82
|
+
|
83
|
+
def has_balance?
|
84
|
+
self.balance > 0
|
85
|
+
end
|
86
|
+
|
87
|
+
def bitcoin_account_name
|
88
|
+
self.uuid
|
89
|
+
end
|
90
|
+
|
91
|
+
private
|
92
|
+
|
93
|
+
def set_bitcoin_address
|
94
|
+
if self.address.blank?
|
95
|
+
self.address = bit_wallet_account.addresses.new.address
|
96
|
+
end
|
97
|
+
end
|
98
|
+
|
99
|
+
def set_balance_cache
|
100
|
+
self.balance_cache = bit_wallet_account.balance
|
101
|
+
end
|
102
|
+
|
103
|
+
def tax_transactions
|
104
|
+
self.transactions.debit.tax
|
105
|
+
end
|
106
|
+
|
107
|
+
def owner_transactions
|
108
|
+
self.transactions.debit.non_tax
|
109
|
+
end
|
110
|
+
|
111
|
+
def bit_wallet_account
|
112
|
+
return @bit_wallet_account if @bit_wallet_account
|
113
|
+
@bit_wallet_account = bit_wallet.accounts.new(self.bitcoin_account_name)
|
114
|
+
end
|
115
|
+
|
116
|
+
def bit_wallet_account_balance
|
117
|
+
bit_wallet_account.balance
|
118
|
+
end
|
119
|
+
|
120
|
+
def set_uuid
|
121
|
+
self.uuid ||= UUIDTools::UUID.random_create.to_s
|
122
|
+
end
|
123
|
+
|
124
|
+
end
|
125
|
+
end
|
@@ -0,0 +1,51 @@
|
|
1
|
+
module Bitsy
|
2
|
+
class PaymentTransaction < ActiveRecord::Base
|
3
|
+
|
4
|
+
belongs_to :payment_depot
|
5
|
+
|
6
|
+
scope :safely_confirmed, -> {
|
7
|
+
column_name = "#{self.table_name}.confirmations"
|
8
|
+
where("#{column_name} >= #{Bitsy.config.safe_confirmation_threshold}")
|
9
|
+
}
|
10
|
+
scope :forwarded, -> {
|
11
|
+
where("#{self.table_name}.forwarding_transaction_id IS NOT NULL")
|
12
|
+
}
|
13
|
+
scope :not_forwarded, -> {
|
14
|
+
where("#{self.table_name}.forwarding_transaction_id IS NULL")
|
15
|
+
}
|
16
|
+
scope :received, -> { where(payment_type: 'receive') }
|
17
|
+
scope :received_by, lambda { |address| where(receiving_address: address) }
|
18
|
+
scope :sent_by, lambda { |address| where(sending_address: address) }
|
19
|
+
scope :tax, lambda { where(payment_type: 'tax') }
|
20
|
+
scope :non_tax, lambda { where('payment_type != ?', 'tax') }
|
21
|
+
scope :matching_bit_wallet_transaction, lambda { |bw_tx|
|
22
|
+
where(
|
23
|
+
transaction_id: bw_tx.id,
|
24
|
+
receiving_address: bw_tx.address_str,
|
25
|
+
amount: bw_tx.amount,
|
26
|
+
occurred_at: bw_tx.occurred_at,
|
27
|
+
received_at: bw_tx.received_at
|
28
|
+
)
|
29
|
+
}
|
30
|
+
scope :for_forwarding, -> { safely_confirmed.not_forwarded.received }
|
31
|
+
scope :credits, -> { received }
|
32
|
+
|
33
|
+
delegate :min_payment, to: :payment_depot, prefix: true
|
34
|
+
delegate :balance, to: :payment_depot, prefix: true
|
35
|
+
delegate :initial_tax_rate, to: :payment_depot, prefix: true
|
36
|
+
delegate :added_tax_rate, to: :payment_depot, prefix: true
|
37
|
+
delegate :total_received_amount, to: :payment_depot, prefix: true
|
38
|
+
|
39
|
+
def forward_tax_fee
|
40
|
+
ForwardTaxCalculator.calculate(self.amount,
|
41
|
+
self.payment_depot_min_payment,
|
42
|
+
self.payment_depot_total_received_amount,
|
43
|
+
self.payment_depot_initial_tax_rate,
|
44
|
+
self.payment_depot_added_tax_rate)
|
45
|
+
end
|
46
|
+
|
47
|
+
def owner_fee
|
48
|
+
self.amount - self.forward_tax_fee
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
module Bitsy
|
2
|
+
class AmountForInitialTaxCalculator
|
3
|
+
|
4
|
+
def self.calculate(payment, min_payment, total_received_amount)
|
5
|
+
if total_received_amount < payment
|
6
|
+
fail ArgumentError, "total amount recieved (#{total_received_amount}) cannot possibly be lower than the payment (#{payment}))"
|
7
|
+
elsif total_received_amount > min_payment
|
8
|
+
total_received_prior_to_payment = total_received_amount - payment
|
9
|
+
amount = min_payment - total_received_prior_to_payment
|
10
|
+
return 0 if amount < 0
|
11
|
+
amount
|
12
|
+
else
|
13
|
+
payment
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
end
|
18
|
+
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
module Bitsy
|
2
|
+
class AssociatesTransactions
|
3
|
+
|
4
|
+
include LightService::Action
|
5
|
+
|
6
|
+
executed do |ctx|
|
7
|
+
payment_txs = ctx.fetch(:payment_transactions)
|
8
|
+
forwarding_transaction_id = ctx.fetch(:forwarding_transaction_id)
|
9
|
+
payment_txs.update_all(forwarding_transaction_id: forwarding_transaction_id)
|
10
|
+
end
|
11
|
+
|
12
|
+
end
|
13
|
+
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
module Bitsy
|
2
|
+
class BuildsSendManyHash
|
3
|
+
|
4
|
+
include LightService::Action
|
5
|
+
|
6
|
+
executed do |ctx|
|
7
|
+
payment_txs = ctx.fetch(:payment_transactions)
|
8
|
+
send_many_hash = {}
|
9
|
+
|
10
|
+
payment_txs.each do |payment_tx|
|
11
|
+
tx_hash = for_transaction(payment_tx)
|
12
|
+
tx_hash.each do |address, value|
|
13
|
+
if send_many_hash.has_key?(address)
|
14
|
+
send_many_hash[address] = send_many_hash[address] + value
|
15
|
+
else
|
16
|
+
send_many_hash[address] = value
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
ctx[:send_many_hash] = send_many_hash
|
22
|
+
end
|
23
|
+
|
24
|
+
def self.for_transaction(payment_transaction)
|
25
|
+
payment_depot = payment_transaction.payment_depot
|
26
|
+
owner_address = payment_depot.owner_address
|
27
|
+
tax_address = payment_depot.tax_address
|
28
|
+
{
|
29
|
+
tax_address => payment_transaction.forward_tax_fee.to_f,
|
30
|
+
owner_address => payment_transaction.owner_fee.to_f
|
31
|
+
}
|
32
|
+
end
|
33
|
+
|
34
|
+
end
|
35
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
module Bitsy
|
2
|
+
class CreatesTransaction
|
3
|
+
|
4
|
+
include LightService::Action
|
5
|
+
|
6
|
+
executed do |ctx|
|
7
|
+
bit_wallet_tx = ctx.fetch(:bit_wallet_transaction)
|
8
|
+
payment_depot = PaymentDepot.find_by_address(bit_wallet_tx.address_str)
|
9
|
+
if payment_depot
|
10
|
+
payment_tx = PaymentTransaction.create(
|
11
|
+
payment_depot_id: payment_depot.id,
|
12
|
+
amount: bit_wallet_tx.amount,
|
13
|
+
receiving_address: bit_wallet_tx.address_str,
|
14
|
+
transaction_id: bit_wallet_tx.id,
|
15
|
+
confirmations: bit_wallet_tx.confirmations,
|
16
|
+
payment_type: bit_wallet_tx.category,
|
17
|
+
occurred_at: bit_wallet_tx.occurred_at,
|
18
|
+
received_at: bit_wallet_tx.received_at
|
19
|
+
)
|
20
|
+
ctx[:payment_transaction] = payment_tx
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
end
|
25
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
module Bitsy
|
2
|
+
class ForwardTaxCalculator
|
3
|
+
|
4
|
+
def self.calculate(payment, min_payment, total_received_amount, initial_tax_rate, added_tax_rate)
|
5
|
+
initial_tax_amount = AmountForInitialTaxCalculator.calculate(
|
6
|
+
payment,
|
7
|
+
min_payment,
|
8
|
+
total_received_amount,
|
9
|
+
)
|
10
|
+
initial_tax_fee = initial_tax_amount * initial_tax_rate
|
11
|
+
amount_for_added_tax = payment - initial_tax_amount
|
12
|
+
added_tax_fee = amount_for_added_tax * added_tax_rate
|
13
|
+
initial_tax_fee + added_tax_fee
|
14
|
+
end
|
15
|
+
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
module Bitsy
|
2
|
+
class ForwardsPayments
|
3
|
+
|
4
|
+
include LightService::Organizer
|
5
|
+
include LightService::Action
|
6
|
+
|
7
|
+
executed do |ctx|
|
8
|
+
payment_transactions = PaymentTransaction.for_forwarding
|
9
|
+
|
10
|
+
if past_threshold?(payment_transactions)
|
11
|
+
bit_wallet_master_account = ctx.fetch(:bit_wallet_master_account)
|
12
|
+
context = {
|
13
|
+
bit_wallet_master_account: bit_wallet_master_account,
|
14
|
+
payment_transactions: payment_transactions
|
15
|
+
}
|
16
|
+
with(context).reduce([
|
17
|
+
BuildsSendManyHash,
|
18
|
+
SendsPayments,
|
19
|
+
AssociatesTransactions
|
20
|
+
])
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
private
|
25
|
+
|
26
|
+
def self.past_threshold?(payment_txs)
|
27
|
+
payment_txs.sum(:amount) >= Bitsy.config.forward_threshold
|
28
|
+
end
|
29
|
+
|
30
|
+
end
|
31
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
module Bitsy
|
2
|
+
class ProcessesPayments
|
3
|
+
|
4
|
+
include LightService::Organizer
|
5
|
+
|
6
|
+
def self.for(args={})
|
7
|
+
bit_wallet = args.fetch(:bit_wallet)
|
8
|
+
bit_wallet_master_account = args.fetch(:bit_wallet_master_account)
|
9
|
+
|
10
|
+
ctx = { bit_wallet: bit_wallet,
|
11
|
+
bit_wallet_master_account: bit_wallet_master_account }
|
12
|
+
with(ctx).reduce([
|
13
|
+
SelectsTransactionsForSync,
|
14
|
+
SyncsTransactions,
|
15
|
+
ForwardsPayments
|
16
|
+
])
|
17
|
+
end
|
18
|
+
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
module Bitsy
|
2
|
+
class SelectsTransactionsForSync
|
3
|
+
|
4
|
+
include LightService::Action
|
5
|
+
|
6
|
+
executed do |ctx|
|
7
|
+
bit_wallet = ctx.fetch(:bit_wallet)
|
8
|
+
txs = bit_wallet.recent_transactions.select {|tx| tx.category == "receive"}
|
9
|
+
ctx[:bit_wallet_transactions] = txs
|
10
|
+
end
|
11
|
+
|
12
|
+
end
|
13
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
module Bitsy
|
2
|
+
class SendsPayments
|
3
|
+
|
4
|
+
include LightService::Action
|
5
|
+
|
6
|
+
executed do |ctx|
|
7
|
+
bit_wallet_master_account = ctx.fetch(:bit_wallet_master_account)
|
8
|
+
send_many_hash = ctx.fetch(:send_many_hash)
|
9
|
+
tx_id = bit_wallet_master_account.send_many(send_many_hash)
|
10
|
+
ctx[:forwarding_transaction_id] = tx_id
|
11
|
+
end
|
12
|
+
|
13
|
+
end
|
14
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
module Bitsy
|
2
|
+
class StockpilesTransaction
|
3
|
+
|
4
|
+
include LightService::Action
|
5
|
+
|
6
|
+
executed do |ctx|
|
7
|
+
payment_tx = ctx.fetch(:payment_transaction)
|
8
|
+
|
9
|
+
if payment_tx && payment_tx.payment_type == "receive"
|
10
|
+
bit_wallet_tx = ctx.fetch(:bit_wallet_transaction)
|
11
|
+
bit_wallet_master_account = ctx.fetch(:bit_wallet_master_account)
|
12
|
+
bit_wallet = bit_wallet_tx.account.wallet
|
13
|
+
payment_depot = payment_tx.payment_depot
|
14
|
+
|
15
|
+
bit_wallet.move(
|
16
|
+
payment_depot.bitcoin_account_name,
|
17
|
+
bit_wallet_master_account.name,
|
18
|
+
payment_tx.amount.to_f
|
19
|
+
)
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
module Bitsy
|
2
|
+
class SyncsTransaction
|
3
|
+
|
4
|
+
include LightService::Organizer
|
5
|
+
|
6
|
+
def self.for(args={})
|
7
|
+
bit_wallet_tx = args.fetch(:bit_wallet_transaction)
|
8
|
+
|
9
|
+
payment_tx = PaymentTransaction.
|
10
|
+
matching_bit_wallet_transaction(bit_wallet_tx).first
|
11
|
+
ctx = { payment_transaction: payment_tx,
|
12
|
+
bit_wallet_transaction: bit_wallet_tx }
|
13
|
+
|
14
|
+
actions = []
|
15
|
+
if payment_tx
|
16
|
+
actions << UpdatesTransaction
|
17
|
+
else
|
18
|
+
ctx[:bit_wallet_master_account] = args.fetch(:bit_wallet_master_account)
|
19
|
+
actions += [CreatesTransaction, StockpilesTransaction]
|
20
|
+
end
|
21
|
+
|
22
|
+
with(ctx).reduce(actions)
|
23
|
+
end
|
24
|
+
|
25
|
+
end
|
26
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
module Bitsy
|
2
|
+
class SyncsTransactions
|
3
|
+
|
4
|
+
include LightService::Action
|
5
|
+
|
6
|
+
executed do |ctx|
|
7
|
+
bit_wallet_txs = ctx.fetch(:bit_wallet_transactions)
|
8
|
+
bit_wallet_master_account = ctx.fetch(:bit_wallet_master_account)
|
9
|
+
|
10
|
+
bit_wallet_txs.each do |bit_wallet_tx|
|
11
|
+
SyncsTransaction.for(bit_wallet_transaction: bit_wallet_tx,
|
12
|
+
bit_wallet_master_account: bit_wallet_master_account)
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
module Bitsy
|
2
|
+
class UpdatesTransaction
|
3
|
+
|
4
|
+
include LightService::Action
|
5
|
+
|
6
|
+
executed do |ctx|
|
7
|
+
bit_wallet_tx = ctx.fetch(:bit_wallet_transaction)
|
8
|
+
payment_tx = ctx.fetch(:payment_transaction)
|
9
|
+
payment_tx.update_attributes(confirmations: bit_wallet_tx.confirmations)
|
10
|
+
end
|
11
|
+
|
12
|
+
end
|
13
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
<!DOCTYPE html>
|
2
|
+
<html>
|
3
|
+
<head>
|
4
|
+
<title>Bitsy</title>
|
5
|
+
<%= stylesheet_link_tag "bitsy/application", media: "all" %>
|
6
|
+
<%= javascript_include_tag "bitsy/application" %>
|
7
|
+
<%= csrf_meta_tags %>
|
8
|
+
</head>
|
9
|
+
<body>
|
10
|
+
|
11
|
+
<%= yield %>
|
12
|
+
|
13
|
+
</body>
|
14
|
+
</html>
|
data/config/bitsy.yml
ADDED
@@ -0,0 +1,19 @@
|
|
1
|
+
defaults: &defaults
|
2
|
+
bitcoind:
|
3
|
+
host: "localhost"
|
4
|
+
username: "admin1"
|
5
|
+
password: "123"
|
6
|
+
port: "19001"
|
7
|
+
ssl: false
|
8
|
+
|
9
|
+
development:
|
10
|
+
<<: *defaults
|
11
|
+
|
12
|
+
test:
|
13
|
+
<<: *defaults
|
14
|
+
|
15
|
+
staging:
|
16
|
+
<<: *defaults
|
17
|
+
|
18
|
+
production:
|
19
|
+
<<: *defaults
|
@@ -0,0 +1,16 @@
|
|
1
|
+
Bitsy.load_config Rails.root.join("config", "bitsy.yml")
|
2
|
+
|
3
|
+
Bitsy.configure do |c|
|
4
|
+
# How much of a transaction fee to pay to the network
|
5
|
+
c.transaction_fee = 0.0001
|
6
|
+
|
7
|
+
# How much Bitcoin to accumulate before forwarding the money out
|
8
|
+
c.transaction_fee_threshold_multiplier = 200
|
9
|
+
|
10
|
+
# How many confirmations are needed to consider a transaction as complete
|
11
|
+
c.safe_confirmation_threshold = 0
|
12
|
+
|
13
|
+
# The name where all money is pooled before sending out. You will likely not
|
14
|
+
# need to change this value.
|
15
|
+
c.master_account_name = ""
|
16
|
+
end
|
data/config/routes.rb
ADDED
@@ -0,0 +1,18 @@
|
|
1
|
+
class CreateBitsyPaymentDepots < ActiveRecord::Migration
|
2
|
+
def change
|
3
|
+
create_table :bitsy_payment_depots do |t|
|
4
|
+
t.decimal :min_payment, null: false
|
5
|
+
t.decimal :initial_tax_rate, null: false
|
6
|
+
t.decimal :added_tax_rate, null: false
|
7
|
+
t.decimal :balance_cache, null: false
|
8
|
+
t.string :owner_address
|
9
|
+
t.string :address, null: false
|
10
|
+
t.datetime :created_at, null: false
|
11
|
+
t.datetime :updated_at, null: false
|
12
|
+
t.string :tax_address
|
13
|
+
t.string :uuid, null: false
|
14
|
+
end
|
15
|
+
|
16
|
+
add_index :bitsy_payment_depots, :uuid
|
17
|
+
end
|
18
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
class CreateBitsyPaymentTransactions < ActiveRecord::Migration
|
2
|
+
def change
|
3
|
+
create_table :bitsy_payment_transactions do |t|
|
4
|
+
t.references :payment_depot, null: false
|
5
|
+
t.decimal :amount, null: false
|
6
|
+
t.string :receiving_address, null: false
|
7
|
+
t.string :payment_type, null: false
|
8
|
+
t.integer :confirmations, null: false
|
9
|
+
t.string :transaction_id, null: false
|
10
|
+
t.string :forwarding_transaction_id
|
11
|
+
t.datetime :occurred_at, null: false
|
12
|
+
t.datetime :received_at, null: false
|
13
|
+
t.integer :confirmations, null: false, default: 0
|
14
|
+
t.timestamps
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
data/lib/bitsy.rb
ADDED
@@ -0,0 +1,39 @@
|
|
1
|
+
require "rails-api"
|
2
|
+
require "sidekiq"
|
3
|
+
require "active_model_serializers"
|
4
|
+
require "bit_wallet"
|
5
|
+
require "clockwork"
|
6
|
+
require "daemons"
|
7
|
+
require "light-service"
|
8
|
+
require "uuidtools"
|
9
|
+
require "bitsy/engine"
|
10
|
+
require "bitsy/config"
|
11
|
+
|
12
|
+
module Bitsy
|
13
|
+
require "bitsy/engine" if defined?(Rails)
|
14
|
+
|
15
|
+
mattr_accessor :config
|
16
|
+
|
17
|
+
def self.load_config(path)
|
18
|
+
self.config ||= Config.new(path)
|
19
|
+
end
|
20
|
+
|
21
|
+
def self.configure
|
22
|
+
yield self.config
|
23
|
+
end
|
24
|
+
|
25
|
+
def self.master_account
|
26
|
+
bit_wallet.accounts.new(self.config.master_account_name)
|
27
|
+
end
|
28
|
+
|
29
|
+
def self.bit_wallet
|
30
|
+
BitWallet.at(
|
31
|
+
host: Bitsy.config.bitcoind.fetch(:host),
|
32
|
+
port: Bitsy.config.bitcoind.fetch(:port),
|
33
|
+
username: Bitsy.config.bitcoind.fetch(:username),
|
34
|
+
password: Bitsy.config.bitcoind.fetch(:password),
|
35
|
+
ssl: Bitsy.config.bitcoind.fetch(:ssl),
|
36
|
+
)
|
37
|
+
end
|
38
|
+
|
39
|
+
end
|
data/lib/bitsy/config.rb
ADDED
@@ -0,0 +1,28 @@
|
|
1
|
+
module Bitsy
|
2
|
+
class Config
|
3
|
+
|
4
|
+
attr_accessor(
|
5
|
+
:transaction_fee,
|
6
|
+
:transaction_fee_threshold_multiplier,
|
7
|
+
:safe_confirmation_threshold,
|
8
|
+
:master_account_name,
|
9
|
+
)
|
10
|
+
|
11
|
+
def initialize(file_path)
|
12
|
+
@config ||= YAML.load_file(file_path).
|
13
|
+
with_indifferent_access.
|
14
|
+
fetch(Rails.env.to_s)
|
15
|
+
|
16
|
+
@config.each do |k, v|
|
17
|
+
self.class.send :define_method, k do
|
18
|
+
@config.fetch(k)
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
def forward_threshold
|
24
|
+
transaction_fee * transaction_fee_threshold_multiplier
|
25
|
+
end
|
26
|
+
|
27
|
+
end
|
28
|
+
end
|
data/lib/bitsy/engine.rb
ADDED
data/lib/clock.rb
ADDED
@@ -0,0 +1,19 @@
|
|
1
|
+
defaults: &defaults
|
2
|
+
bitcoind:
|
3
|
+
host: "localhost"
|
4
|
+
username: "admin1"
|
5
|
+
password: "123"
|
6
|
+
port: "19001"
|
7
|
+
ssl: false
|
8
|
+
|
9
|
+
development:
|
10
|
+
<<: *defaults
|
11
|
+
|
12
|
+
test:
|
13
|
+
<<: *defaults
|
14
|
+
|
15
|
+
staging:
|
16
|
+
<<: *defaults
|
17
|
+
|
18
|
+
production:
|
19
|
+
<<: *defaults
|
@@ -0,0 +1,16 @@
|
|
1
|
+
Bitsy.load_config Rails.root.join("config", "bitsy.yml")
|
2
|
+
|
3
|
+
Bitsy.configure do |c|
|
4
|
+
# How much of a transaction fee to pay to the network
|
5
|
+
c.transaction_fee = 0.0001
|
6
|
+
|
7
|
+
# How much Bitcoin to accumulate before forwarding the money out
|
8
|
+
c.transaction_fee_threshold_multiplier = 200
|
9
|
+
|
10
|
+
# How many confirmations are needed to consider a transaction as complete
|
11
|
+
c.safe_confirmation_threshold = 0
|
12
|
+
|
13
|
+
# The name where all money is pooled before sending out. You will likely not
|
14
|
+
# need to change this value.
|
15
|
+
c.master_account_name = ""
|
16
|
+
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
require "bitsy/engine"
|
2
|
+
|
3
|
+
module Bitsy
|
4
|
+
class ConfigGenerator < Rails::Generators::Base
|
5
|
+
|
6
|
+
desc "Creates a Bitsy config file in config/bitsy.yml, and initializer that loads the file"
|
7
|
+
source_root File.expand_path("../config/templates", __FILE__)
|
8
|
+
|
9
|
+
def create_config_file
|
10
|
+
copy_file "bitsy.yml", File.join("config", "bitsy.yml")
|
11
|
+
end
|
12
|
+
|
13
|
+
def create_initializer_file
|
14
|
+
copy_file(
|
15
|
+
"initializer.rb",
|
16
|
+
File.join("config", "initializers", "bitsy.rb"),
|
17
|
+
)
|
18
|
+
end
|
19
|
+
|
20
|
+
def ignore_bitsy_yml
|
21
|
+
append_file ".gitignore", "config/bitsy.yml"
|
22
|
+
end
|
23
|
+
|
24
|
+
def mount_on_routes
|
25
|
+
inject_into_file(
|
26
|
+
"config/routes.rb",
|
27
|
+
%Q( mount Bitsy::Engine, at: "bitsy"\n),
|
28
|
+
before: /^end/
|
29
|
+
)
|
30
|
+
end
|
31
|
+
|
32
|
+
end
|
33
|
+
end
|
metadata
ADDED
@@ -0,0 +1,344 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: bitsy-bitcoin
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Ramon Tayag
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2014-06-21 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: rails
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '4.0'
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '4.0'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: rails-api
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - '='
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: 0.2.1
|
34
|
+
type: :runtime
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - '='
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: 0.2.1
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: sidekiq
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - "~>"
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '2.8'
|
48
|
+
type: :runtime
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - "~>"
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '2.8'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: active_model_serializers
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - ">="
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0'
|
62
|
+
type: :runtime
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - ">="
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '0'
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: bit_wallet
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - '='
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: 0.7.1
|
76
|
+
type: :runtime
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - '='
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: 0.7.1
|
83
|
+
- !ruby/object:Gem::Dependency
|
84
|
+
name: clockwork
|
85
|
+
requirement: !ruby/object:Gem::Requirement
|
86
|
+
requirements:
|
87
|
+
- - '='
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
version: 0.7.2
|
90
|
+
type: :runtime
|
91
|
+
prerelease: false
|
92
|
+
version_requirements: !ruby/object:Gem::Requirement
|
93
|
+
requirements:
|
94
|
+
- - '='
|
95
|
+
- !ruby/object:Gem::Version
|
96
|
+
version: 0.7.2
|
97
|
+
- !ruby/object:Gem::Dependency
|
98
|
+
name: daemons
|
99
|
+
requirement: !ruby/object:Gem::Requirement
|
100
|
+
requirements:
|
101
|
+
- - "~>"
|
102
|
+
- !ruby/object:Gem::Version
|
103
|
+
version: '1.1'
|
104
|
+
type: :runtime
|
105
|
+
prerelease: false
|
106
|
+
version_requirements: !ruby/object:Gem::Requirement
|
107
|
+
requirements:
|
108
|
+
- - "~>"
|
109
|
+
- !ruby/object:Gem::Version
|
110
|
+
version: '1.1'
|
111
|
+
- !ruby/object:Gem::Dependency
|
112
|
+
name: light-service
|
113
|
+
requirement: !ruby/object:Gem::Requirement
|
114
|
+
requirements:
|
115
|
+
- - '='
|
116
|
+
- !ruby/object:Gem::Version
|
117
|
+
version: 0.2.1
|
118
|
+
type: :runtime
|
119
|
+
prerelease: false
|
120
|
+
version_requirements: !ruby/object:Gem::Requirement
|
121
|
+
requirements:
|
122
|
+
- - '='
|
123
|
+
- !ruby/object:Gem::Version
|
124
|
+
version: 0.2.1
|
125
|
+
- !ruby/object:Gem::Dependency
|
126
|
+
name: uuidtools
|
127
|
+
requirement: !ruby/object:Gem::Requirement
|
128
|
+
requirements:
|
129
|
+
- - "~>"
|
130
|
+
- !ruby/object:Gem::Version
|
131
|
+
version: '2.1'
|
132
|
+
type: :runtime
|
133
|
+
prerelease: false
|
134
|
+
version_requirements: !ruby/object:Gem::Requirement
|
135
|
+
requirements:
|
136
|
+
- - "~>"
|
137
|
+
- !ruby/object:Gem::Version
|
138
|
+
version: '2.1'
|
139
|
+
- !ruby/object:Gem::Dependency
|
140
|
+
name: sqlite3
|
141
|
+
requirement: !ruby/object:Gem::Requirement
|
142
|
+
requirements:
|
143
|
+
- - ">="
|
144
|
+
- !ruby/object:Gem::Version
|
145
|
+
version: '0'
|
146
|
+
type: :development
|
147
|
+
prerelease: false
|
148
|
+
version_requirements: !ruby/object:Gem::Requirement
|
149
|
+
requirements:
|
150
|
+
- - ">="
|
151
|
+
- !ruby/object:Gem::Version
|
152
|
+
version: '0'
|
153
|
+
- !ruby/object:Gem::Dependency
|
154
|
+
name: rspec-rails
|
155
|
+
requirement: !ruby/object:Gem::Requirement
|
156
|
+
requirements:
|
157
|
+
- - "~>"
|
158
|
+
- !ruby/object:Gem::Version
|
159
|
+
version: 2.14.2
|
160
|
+
type: :development
|
161
|
+
prerelease: false
|
162
|
+
version_requirements: !ruby/object:Gem::Requirement
|
163
|
+
requirements:
|
164
|
+
- - "~>"
|
165
|
+
- !ruby/object:Gem::Version
|
166
|
+
version: 2.14.2
|
167
|
+
- !ruby/object:Gem::Dependency
|
168
|
+
name: capybara
|
169
|
+
requirement: !ruby/object:Gem::Requirement
|
170
|
+
requirements:
|
171
|
+
- - "~>"
|
172
|
+
- !ruby/object:Gem::Version
|
173
|
+
version: '2.0'
|
174
|
+
type: :development
|
175
|
+
prerelease: false
|
176
|
+
version_requirements: !ruby/object:Gem::Requirement
|
177
|
+
requirements:
|
178
|
+
- - "~>"
|
179
|
+
- !ruby/object:Gem::Version
|
180
|
+
version: '2.0'
|
181
|
+
- !ruby/object:Gem::Dependency
|
182
|
+
name: vcr
|
183
|
+
requirement: !ruby/object:Gem::Requirement
|
184
|
+
requirements:
|
185
|
+
- - "~>"
|
186
|
+
- !ruby/object:Gem::Version
|
187
|
+
version: '2.4'
|
188
|
+
type: :development
|
189
|
+
prerelease: false
|
190
|
+
version_requirements: !ruby/object:Gem::Requirement
|
191
|
+
requirements:
|
192
|
+
- - "~>"
|
193
|
+
- !ruby/object:Gem::Version
|
194
|
+
version: '2.4'
|
195
|
+
- !ruby/object:Gem::Dependency
|
196
|
+
name: webmock
|
197
|
+
requirement: !ruby/object:Gem::Requirement
|
198
|
+
requirements:
|
199
|
+
- - ">="
|
200
|
+
- !ruby/object:Gem::Version
|
201
|
+
version: 1.8.0
|
202
|
+
- - "<"
|
203
|
+
- !ruby/object:Gem::Version
|
204
|
+
version: '1.16'
|
205
|
+
type: :development
|
206
|
+
prerelease: false
|
207
|
+
version_requirements: !ruby/object:Gem::Requirement
|
208
|
+
requirements:
|
209
|
+
- - ">="
|
210
|
+
- !ruby/object:Gem::Version
|
211
|
+
version: 1.8.0
|
212
|
+
- - "<"
|
213
|
+
- !ruby/object:Gem::Version
|
214
|
+
version: '1.16'
|
215
|
+
- !ruby/object:Gem::Dependency
|
216
|
+
name: bitcoin_testnet
|
217
|
+
requirement: !ruby/object:Gem::Requirement
|
218
|
+
requirements:
|
219
|
+
- - '='
|
220
|
+
- !ruby/object:Gem::Version
|
221
|
+
version: 0.5.1
|
222
|
+
type: :development
|
223
|
+
prerelease: false
|
224
|
+
version_requirements: !ruby/object:Gem::Requirement
|
225
|
+
requirements:
|
226
|
+
- - '='
|
227
|
+
- !ruby/object:Gem::Version
|
228
|
+
version: 0.5.1
|
229
|
+
- !ruby/object:Gem::Dependency
|
230
|
+
name: factory_girl_rails
|
231
|
+
requirement: !ruby/object:Gem::Requirement
|
232
|
+
requirements:
|
233
|
+
- - "~>"
|
234
|
+
- !ruby/object:Gem::Version
|
235
|
+
version: '4.2'
|
236
|
+
type: :development
|
237
|
+
prerelease: false
|
238
|
+
version_requirements: !ruby/object:Gem::Requirement
|
239
|
+
requirements:
|
240
|
+
- - "~>"
|
241
|
+
- !ruby/object:Gem::Version
|
242
|
+
version: '4.2'
|
243
|
+
- !ruby/object:Gem::Dependency
|
244
|
+
name: database_cleaner
|
245
|
+
requirement: !ruby/object:Gem::Requirement
|
246
|
+
requirements:
|
247
|
+
- - ">="
|
248
|
+
- !ruby/object:Gem::Version
|
249
|
+
version: '0'
|
250
|
+
type: :development
|
251
|
+
prerelease: false
|
252
|
+
version_requirements: !ruby/object:Gem::Requirement
|
253
|
+
requirements:
|
254
|
+
- - ">="
|
255
|
+
- !ruby/object:Gem::Version
|
256
|
+
version: '0'
|
257
|
+
- !ruby/object:Gem::Dependency
|
258
|
+
name: standalone_migrations
|
259
|
+
requirement: !ruby/object:Gem::Requirement
|
260
|
+
requirements:
|
261
|
+
- - ">="
|
262
|
+
- !ruby/object:Gem::Version
|
263
|
+
version: '0'
|
264
|
+
type: :development
|
265
|
+
prerelease: false
|
266
|
+
version_requirements: !ruby/object:Gem::Requirement
|
267
|
+
requirements:
|
268
|
+
- - ">="
|
269
|
+
- !ruby/object:Gem::Version
|
270
|
+
version: '0'
|
271
|
+
description: A mountable Rails engine to create a payment server that can handle the
|
272
|
+
money in your Bitcoin ecosystem
|
273
|
+
email:
|
274
|
+
- ramon.tayag@gmail.com
|
275
|
+
executables: []
|
276
|
+
extensions: []
|
277
|
+
extra_rdoc_files: []
|
278
|
+
files:
|
279
|
+
- MIT-LICENSE
|
280
|
+
- Rakefile
|
281
|
+
- app/assets/javascripts/bitsy/application.js
|
282
|
+
- app/assets/stylesheets/bitsy/application.css
|
283
|
+
- app/controllers/bitsy/application_controller.rb
|
284
|
+
- app/controllers/bitsy/v1/payment_depots_controller.rb
|
285
|
+
- app/controllers/bitsy/v1/syncs_controller.rb
|
286
|
+
- app/controllers/bitsy/v1/truncations_controller.rb
|
287
|
+
- app/helpers/bitsy/application_helper.rb
|
288
|
+
- app/jobs/bitsy/payment_job.rb
|
289
|
+
- app/models/bitsy/payment_depot.rb
|
290
|
+
- app/models/bitsy/payment_transaction.rb
|
291
|
+
- app/serializers/bitsy/payment_depot_serializer.rb
|
292
|
+
- app/services/bitsy/amount_for_initial_tax_calculator.rb
|
293
|
+
- app/services/bitsy/associates_transactions.rb
|
294
|
+
- app/services/bitsy/builds_send_many_hash.rb
|
295
|
+
- app/services/bitsy/creates_transaction.rb
|
296
|
+
- app/services/bitsy/forward_tax_calculator.rb
|
297
|
+
- app/services/bitsy/forwards_payments.rb
|
298
|
+
- app/services/bitsy/processes_payments.rb
|
299
|
+
- app/services/bitsy/selects_transactions_for_sync.rb
|
300
|
+
- app/services/bitsy/sends_payments.rb
|
301
|
+
- app/services/bitsy/stockpiles_transaction.rb
|
302
|
+
- app/services/bitsy/syncs_transaction.rb
|
303
|
+
- app/services/bitsy/syncs_transactions.rb
|
304
|
+
- app/services/bitsy/updates_transaction.rb
|
305
|
+
- app/views/layouts/bitsy/application.html.erb
|
306
|
+
- config/bitsy.yml
|
307
|
+
- config/initializers/bitsy.rb
|
308
|
+
- config/routes.rb
|
309
|
+
- db/migrate/20140607015614_create_bitsy_payment_depots.rb
|
310
|
+
- db/migrate/20140607015859_create_bitsy_payment_transactions.rb
|
311
|
+
- lib/bitsy.rb
|
312
|
+
- lib/bitsy/config.rb
|
313
|
+
- lib/bitsy/engine.rb
|
314
|
+
- lib/bitsy/version.rb
|
315
|
+
- lib/clock.rb
|
316
|
+
- lib/generators/bitsy/config/templates/bitsy.yml
|
317
|
+
- lib/generators/bitsy/config/templates/initializer.rb
|
318
|
+
- lib/generators/bitsy/config_generator.rb
|
319
|
+
- lib/tasks/bitsy_tasks.rake
|
320
|
+
homepage: https://github.com/ramontayag/bitsy
|
321
|
+
licenses:
|
322
|
+
- MIT
|
323
|
+
metadata: {}
|
324
|
+
post_install_message:
|
325
|
+
rdoc_options: []
|
326
|
+
require_paths:
|
327
|
+
- lib
|
328
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
329
|
+
requirements:
|
330
|
+
- - ">="
|
331
|
+
- !ruby/object:Gem::Version
|
332
|
+
version: '0'
|
333
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
334
|
+
requirements:
|
335
|
+
- - ">="
|
336
|
+
- !ruby/object:Gem::Version
|
337
|
+
version: '0'
|
338
|
+
requirements: []
|
339
|
+
rubyforge_project:
|
340
|
+
rubygems_version: 2.2.2
|
341
|
+
signing_key:
|
342
|
+
specification_version: 4
|
343
|
+
summary: A mountable Rails engine to create a Bitcoin payment server
|
344
|
+
test_files: []
|