bitsy-bitcoin 0.1.0 → 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.
Files changed (47) hide show
  1. checksums.yaml +4 -4
  2. data/app/controllers/bitsy/v1/blockchain_notifications_controller.rb +29 -0
  3. data/app/controllers/bitsy/v1/payment_depots_controller.rb +3 -1
  4. data/app/controllers/bitsy/v1/syncs_controller.rb +1 -1
  5. data/app/jobs/bitsy/blockchain_notification_job.rb +14 -0
  6. data/app/jobs/bitsy/forward_job.rb +11 -0
  7. data/app/jobs/bitsy/transactions_sync_job.rb +11 -0
  8. data/app/models/bitsy/blockchain_notification.rb +15 -0
  9. data/app/models/bitsy/payment_depot.rb +7 -34
  10. data/app/models/bitsy/payment_transaction.rb +0 -9
  11. data/app/services/bitsy/associates_transactions.rb +3 -3
  12. data/app/services/bitsy/{builds_send_many_hash.rb → build_send_many_hash.rb} +3 -3
  13. data/app/services/bitsy/create_payment_depot.rb +19 -0
  14. data/app/services/bitsy/forward_payments.rb +28 -0
  15. data/app/services/bitsy/instantiate_blockchain_wallet.rb +18 -0
  16. data/app/services/bitsy/process_blockchain_notification.rb +22 -0
  17. data/app/services/bitsy/send_payments.rb +14 -0
  18. data/app/services/bitsy/updating/get_latest_block.rb +14 -0
  19. data/app/services/bitsy/updating/select_transactions.rb +14 -0
  20. data/app/services/bitsy/updating/sync_transactions.rb +17 -0
  21. data/app/services/bitsy/updating/update_transaction.rb +24 -0
  22. data/app/services/bitsy/updating/update_transactions.rb +19 -0
  23. data/config/bitsy.yml +5 -6
  24. data/config/database.yml +25 -0
  25. data/config/initializers/bitsy.rb +3 -3
  26. data/config/routes.rb +1 -0
  27. data/db/development.sqlite3 +0 -0
  28. data/db/migrate/20141106123922_create_bitsy_blockchain_notifications.rb +11 -0
  29. data/db/migrate/20141108002656_drop_occurred_at_and_received_at_from_payment_transactions.rb +11 -0
  30. data/db/migrate/20141109072242_change_payment_depot_balance_cache_default.rb +5 -0
  31. data/lib/bitsy.rb +1 -14
  32. data/lib/bitsy/config.rb +3 -2
  33. data/lib/bitsy/version.rb +1 -1
  34. data/lib/generators/bitsy/config/templates/bitsy.yml +5 -6
  35. data/lib/generators/bitsy/config/templates/clock.rb +1 -1
  36. data/lib/generators/bitsy/config/templates/initializer.rb +0 -5
  37. metadata +45 -21
  38. data/app/jobs/bitsy/payment_job.rb +0 -15
  39. data/app/services/bitsy/creates_transaction.rb +0 -25
  40. data/app/services/bitsy/forwards_payments.rb +0 -31
  41. data/app/services/bitsy/processes_payments.rb +0 -20
  42. data/app/services/bitsy/selects_transactions_for_sync.rb +0 -13
  43. data/app/services/bitsy/sends_payments.rb +0 -14
  44. data/app/services/bitsy/stockpiles_transaction.rb +0 -24
  45. data/app/services/bitsy/syncs_transaction.rb +0 -26
  46. data/app/services/bitsy/syncs_transactions.rb +0 -17
  47. data/app/services/bitsy/updates_transaction.rb +0 -13
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 48c7d3458982b26baf51b399176c16f7d9746efa
4
- data.tar.gz: d24ef9b6dc9dba8787541c44212cfadb07656fcd
3
+ metadata.gz: 69731136aaba219d6340e7c69b9fccb67ae105a3
4
+ data.tar.gz: 5ca72a140e548a493509c90132a677ea46efce9f
5
5
  SHA512:
6
- metadata.gz: 3f0053a723a93a65fbaca090ea2df6296cb666da3ecf0ae79872a174326df513702ea41704fe63b81952ce0de380225e3543f4dca9347d9a000f67441e09d7d5
7
- data.tar.gz: 8148decc5dd0a541580d53fe4d3d62eb0817abdf96820db8955cfd8e8c2a297ed8cbc61bda5d1e202274e798daa47772f3076bec7b88c40bcbe73d514e4d6830
6
+ metadata.gz: a67445e06d2b25e68c53a18f6b279ba0b6a1dafd253a2cdab3f87c1074e6301a2694f7546e144fef7a04095a624ed2ca615503d182e4079c012b5ac6680ee1fd
7
+ data.tar.gz: e85fe799479da643660a294f8bd83e16271a515e465dbef7aa464bcbc3ecfb301b2a1fbc3a1fa419f6e55b476c6e769d3f8686339e7b315e0a4d51525f37a477
@@ -0,0 +1,29 @@
1
+ module Bitsy
2
+ module V1
3
+ class BlockchainNotificationsController < ApplicationController
4
+
5
+ def index
6
+ bn = BlockchainNotification.new(blockchain_notification_params)
7
+ if bn.save
8
+ BlockchainNotificationJob.perform_async(bn.id)
9
+ render nothing: true, status: 200
10
+ else
11
+ render nothing: true, status: 422
12
+ end
13
+ end
14
+
15
+ protected
16
+
17
+ def blockchain_notification_params
18
+ params.permit(
19
+ :value,
20
+ :transaction_hash,
21
+ :input_address,
22
+ :confirmations,
23
+ :secret,
24
+ )
25
+ end
26
+
27
+ end
28
+ end
29
+ end
@@ -13,7 +13,9 @@ module Bitsy
13
13
  end
14
14
 
15
15
  def create
16
- @payment_depot = PaymentDepot.create(payment_depot_params)
16
+ @payment_depot = CreatePaymentDepot.
17
+ execute(params: payment_depot_params).
18
+ payment_depot
17
19
  render json: @payment_depot
18
20
  end
19
21
 
@@ -3,7 +3,7 @@ module Bitsy
3
3
  class SyncsController < ApplicationController
4
4
 
5
5
  def create
6
- PaymentJob.new.perform
6
+ TransactionsSyncJob.new.perform
7
7
  end
8
8
 
9
9
  end
@@ -0,0 +1,14 @@
1
+ module Bitsy
2
+ class BlockchainNotificationJob
3
+
4
+ include Sidekiq::Worker
5
+
6
+ def perform(blockchain_notification_id)
7
+ blockchain_notification = BlockchainNotification.
8
+ find(blockchain_notification_id)
9
+ ProcessBlockchainNotification.
10
+ execute(blockchain_notification: blockchain_notification)
11
+ end
12
+
13
+ end
14
+ end
@@ -0,0 +1,11 @@
1
+ module Bitsy
2
+ class ForwardJob
3
+
4
+ include Sidekiq::Worker
5
+
6
+ def perform
7
+ ForwardPayments.execute
8
+ end
9
+
10
+ end
11
+ end
@@ -0,0 +1,11 @@
1
+ module Bitsy
2
+ class TransactionsSyncJob
3
+
4
+ include Sidekiq::Worker
5
+
6
+ def perform
7
+ Updating::SyncTransactions.execute
8
+ end
9
+
10
+ end
11
+ end
@@ -0,0 +1,15 @@
1
+ module Bitsy
2
+ class BlockchainNotification < ActiveRecord::Base
3
+
4
+ validates(
5
+ :value,
6
+ :transaction_hash,
7
+ :input_address,
8
+ :confirmations,
9
+ presence: true
10
+ )
11
+
12
+ validates(:secret, inclusion: {in: Bitsy.config.blockchain_secrets})
13
+
14
+ end
15
+ end
@@ -6,23 +6,19 @@ module Bitsy
6
6
 
7
7
  alias_attribute :balance, :balance_cache
8
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
9
  scope :with_balance, -> { where('balance_cache > 0.0') }
13
- validate(
10
+ validates(
14
11
  :initial_tax_rate,
15
12
  inclusion: {
16
- in: [0.0..1.0],
13
+ in: 0.0..1.0,
17
14
  message: 'must be a value within 0.0 and 1.0'
18
15
  }
19
16
  )
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
17
+ validates :address, presence: true, uniqueness: true
18
+ validates :balance_cache, presence: true
19
+ validates :owner_address, presence: true
20
+ validates :tax_address, presence: true
21
+ validates :uuid, uniqueness: true, presence: true
26
22
 
27
23
  def initial_owner_rate
28
24
  self.min_payment * (1 - self.initial_tax_rate)
@@ -76,10 +72,6 @@ module Bitsy
76
72
  added_fee_received * self.added_tax_fee
77
73
  end
78
74
 
79
- def balance
80
- self.balance_cache = bit_wallet_account_balance
81
- end
82
-
83
75
  def has_balance?
84
76
  self.balance > 0
85
77
  end
@@ -90,16 +82,6 @@ module Bitsy
90
82
 
91
83
  private
92
84
 
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
85
  def tax_transactions
104
86
  self.transactions.debit.tax
105
87
  end
@@ -108,15 +90,6 @@ module Bitsy
108
90
  self.transactions.debit.non_tax
109
91
  end
110
92
 
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
93
  def set_uuid
121
94
  self.uuid ||= UUIDTools::UUID.random_create.to_s
122
95
  end
@@ -18,15 +18,6 @@ module Bitsy
18
18
  scope :sent_by, lambda { |address| where(sending_address: address) }
19
19
  scope :tax, lambda { where(payment_type: 'tax') }
20
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
21
  scope :for_forwarding, -> { safely_confirmed.not_forwarded.received }
31
22
  scope :credits, -> { received }
32
23
 
@@ -2,11 +2,11 @@ module Bitsy
2
2
  class AssociatesTransactions
3
3
 
4
4
  include LightService::Action
5
+ expects :forwarding_transaction_id, :payment_transactions
5
6
 
6
7
  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)
8
+ ctx.payment_transactions.
9
+ update_all(forwarding_transaction_id: ctx.forwarding_transaction_id)
10
10
  end
11
11
 
12
12
  end
@@ -1,5 +1,5 @@
1
1
  module Bitsy
2
- class BuildsSendManyHash
2
+ class BuildSendManyHash
3
3
 
4
4
  include LightService::Action
5
5
 
@@ -26,8 +26,8 @@ module Bitsy
26
26
  owner_address = payment_depot.owner_address
27
27
  tax_address = payment_depot.tax_address
28
28
  {
29
- tax_address => payment_transaction.forward_tax_fee.to_f,
30
- owner_address => payment_transaction.owner_fee.to_f
29
+ tax_address => payment_transaction.forward_tax_fee.to_f * 100_000_000,
30
+ owner_address => payment_transaction.owner_fee.to_f * 100_000_000,
31
31
  }
32
32
  end
33
33
 
@@ -0,0 +1,19 @@
1
+ module Bitsy
2
+ class CreatePaymentDepot
3
+
4
+ include LightService::Action
5
+ expects :params
6
+ promises :payment_depot
7
+
8
+ executed do |ctx|
9
+ wallet = InstantiateBlockchainWallet.execute.wallet
10
+
11
+ params = ctx.params
12
+ params[:address] = address = wallet.new_address.address
13
+ params[:balance] = wallet.get_address(address)
14
+
15
+ ctx.payment_depot = PaymentDepot.create(params)
16
+ end
17
+
18
+ end
19
+ end
@@ -0,0 +1,28 @@
1
+ module Bitsy
2
+ class ForwardPayments
3
+
4
+ include LightService::Organizer
5
+ include LightService::Action
6
+
7
+ def self.execute
8
+ payment_transactions = PaymentTransaction.for_forwarding
9
+
10
+ return unless past_threshold?(payment_transactions)
11
+ with(
12
+ payment_transactions: payment_transactions
13
+ ).reduce([
14
+ InstantiateBlockchainWallet,
15
+ BuildSendManyHash,
16
+ SendPayments,
17
+ AssociatesTransactions
18
+ ])
19
+ end
20
+
21
+ private
22
+
23
+ def self.past_threshold?(payment_txs)
24
+ payment_txs.sum(:amount) >= Bitsy.config.forward_threshold_amount
25
+ end
26
+
27
+ end
28
+ end
@@ -0,0 +1,18 @@
1
+ module Bitsy
2
+ class InstantiateBlockchainWallet
3
+
4
+ include LightService::Action
5
+ promises :wallet
6
+
7
+ executed do |ctx|
8
+ config = Bitsy.config.blockchain
9
+ ctx.wallet = Blockchain::Wallet.new(
10
+ config[:identifier],
11
+ config[:password],
12
+ config[:second_password],
13
+ config[:api_code],
14
+ )
15
+ end
16
+
17
+ end
18
+ end
@@ -0,0 +1,22 @@
1
+ module Bitsy
2
+ class ProcessBlockchainNotification
3
+
4
+ include LightService::Action
5
+ expects :blockchain_notification
6
+ promises :payment_transaction
7
+
8
+ executed do |ctx|
9
+ bn = ctx.blockchain_notification
10
+ payment_depot = PaymentDepot.find_by(address: bn.input_address)
11
+ ctx.payment_transaction = PaymentTransaction.create!(
12
+ payment_depot_id: payment_depot.id,
13
+ amount: bn.value / 100_000_000.0,
14
+ receiving_address: bn.input_address,
15
+ payment_type: "receive",
16
+ confirmations: bn.confirmations,
17
+ transaction_id: bn.transaction_hash,
18
+ )
19
+ end
20
+
21
+ end
22
+ end
@@ -0,0 +1,14 @@
1
+ module Bitsy
2
+ class SendPayments
3
+
4
+ include LightService::Action
5
+ expects :send_many_hash, :wallet
6
+ promises :forwarding_transaction_id
7
+
8
+ executed do |ctx|
9
+ payment_response = ctx.wallet.send_many(ctx.send_many_hash)
10
+ ctx.forwarding_transaction_id = payment_response.tx_hash
11
+ end
12
+
13
+ end
14
+ end
@@ -0,0 +1,14 @@
1
+ module Bitsy
2
+ module Updating
3
+ class GetLatestBlock
4
+
5
+ include LightService::Action
6
+ promises :latest_block
7
+
8
+ executed do |ctx|
9
+ ctx.latest_block = Blockchain.get_latest_block
10
+ end
11
+
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,14 @@
1
+ module Bitsy
2
+ module Updating
3
+ class SelectTransactions
4
+
5
+ include LightService::Action
6
+ promises :payment_transactions
7
+
8
+ executed do |ctx|
9
+ ctx.payment_transactions = PaymentTransaction.not_forwarded
10
+ end
11
+
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,17 @@
1
+ module Bitsy
2
+ module Updating
3
+ class SyncTransactions
4
+
5
+ include LightService::Organizer
6
+
7
+ def self.execute
8
+ reduce(
9
+ GetLatestBlock,
10
+ SelectTransactions,
11
+ UpdateTransactions,
12
+ )
13
+ end
14
+
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,24 @@
1
+ module Bitsy
2
+ module Updating
3
+ class UpdateTransaction
4
+
5
+ include LightService::Action
6
+ expects :latest_block, :payment_transaction
7
+
8
+ executed do |ctx|
9
+ blockchain_tx = Blockchain.
10
+ get_tx(ctx.payment_transaction.transaction_id)
11
+ confirmations = if blockchain_tx.block_height
12
+ blockchain_tx.block_height + 1 -
13
+ ctx.latest_block.height
14
+ else
15
+ 0
16
+ end
17
+ ctx.payment_transaction.update_attributes(
18
+ confirmations: confirmations
19
+ )
20
+ end
21
+
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,19 @@
1
+ module Bitsy
2
+ module Updating
3
+ class UpdateTransactions
4
+
5
+ include LightService::Action
6
+ expects :payment_transactions, :latest_block
7
+
8
+ executed do |ctx|
9
+ ctx.payment_transactions.each do |tx|
10
+ UpdateTransaction.execute(
11
+ payment_transaction: tx,
12
+ latest_block: ctx.latest_block,
13
+ )
14
+ end
15
+ end
16
+
17
+ end
18
+ end
19
+ end
@@ -1,10 +1,9 @@
1
1
  defaults: &defaults
2
- bitcoind:
3
- host: "localhost"
4
- username: "bitcoinrpc"
5
- password: "thisisjustapasswordfortesting"
6
- port: "19001"
7
- ssl: false
2
+ blockchain:
3
+ identifier: eeadf652-e1c3-414e-bd3b-c4aef10756c4
4
+ password: Ye054oH96zSueHnVHLAAWwwM9
5
+ second_password:
6
+ api_code:
8
7
 
9
8
  development:
10
9
  <<: *defaults
@@ -0,0 +1,25 @@
1
+ # SQLite version 3.x
2
+ # gem install sqlite3
3
+ #
4
+ # Ensure the SQLite 3 gem is defined in your Gemfile
5
+ # gem 'sqlite3'
6
+ #
7
+ default: &default
8
+ adapter: sqlite3
9
+ pool: 5
10
+ timeout: 5000
11
+
12
+ development:
13
+ <<: *default
14
+ database: db/development.sqlite3
15
+
16
+ # Warning: The database defined as "test" will be erased and
17
+ # re-generated from your development database when you run "rake".
18
+ # Do not set this db to the same as development or production.
19
+ test:
20
+ <<: *default
21
+ database: db/test.sqlite3
22
+
23
+ production:
24
+ <<: *default
25
+ database: db/production.sqlite3
@@ -10,7 +10,7 @@ Bitsy.configure do |c|
10
10
  # How many confirmations are needed to consider a transaction as complete
11
11
  c.safe_confirmation_threshold = 0
12
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 = ""
13
+ # List of allowed secrets from Blockchain.info. The callback URL should look
14
+ # like this http://app.com/bitsy/v1/blockchain_notifications?secret=mysecret
15
+ c.blockchain_secrets = %w(secret)
16
16
  end
@@ -2,6 +2,7 @@ Bitsy::Engine.routes.draw do
2
2
 
3
3
  namespace :v1 do
4
4
  resources :payment_depots
5
+ resources :blockchain_notifications
5
6
  unless Rails.env.production?
6
7
  resources :syncs
7
8
  resources :truncations
File without changes
@@ -0,0 +1,11 @@
1
+ class CreateBitsyBlockchainNotifications < ActiveRecord::Migration
2
+ def change
3
+ create_table :bitsy_blockchain_notifications do |t|
4
+ t.integer :value, null: false
5
+ t.string :transaction_hash, null: false
6
+ t.string :input_address, null: false
7
+ t.integer :confirmations, null: false, default: 0
8
+ t.string :secret, null: false
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,11 @@
1
+ class DropOccurredAtAndReceivedAtFromPaymentTransactions < ActiveRecord::Migration
2
+ def up
3
+ remove_column :bitsy_payment_transactions, :occurred_at
4
+ remove_column :bitsy_payment_transactions, :received_at
5
+ end
6
+
7
+ def down
8
+ add_column :bitsy_payment_transactions, :occurred_at, :datetime, null: false
9
+ add_column :bitsy_payment_transactions, :received_at, :datetime, null: false
10
+ end
11
+ end
@@ -0,0 +1,5 @@
1
+ class ChangePaymentDepotBalanceCacheDefault < ActiveRecord::Migration
2
+ def change
3
+ change_column :bitsy_payment_depots, :balance_cache, :decimal, null: false, default: 0
4
+ end
5
+ end
@@ -6,6 +6,7 @@ require "clockwork"
6
6
  require "daemons"
7
7
  require "light-service"
8
8
  require "uuidtools"
9
+ require "blockchain"
9
10
  require "bitsy/engine"
10
11
  require "bitsy/config"
11
12
 
@@ -22,18 +23,4 @@ module Bitsy
22
23
  yield self.config
23
24
  end
24
25
 
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
26
  end
@@ -5,7 +5,8 @@ module Bitsy
5
5
  :transaction_fee,
6
6
  :transaction_fee_threshold_multiplier,
7
7
  :safe_confirmation_threshold,
8
- :master_account_name,
8
+ :blockchain_secrets,
9
+ :blockchain,
9
10
  )
10
11
 
11
12
  def initialize(file_path)
@@ -20,7 +21,7 @@ module Bitsy
20
21
  end
21
22
  end
22
23
 
23
- def forward_threshold
24
+ def forward_threshold_amount
24
25
  transaction_fee * transaction_fee_threshold_multiplier
25
26
  end
26
27
 
@@ -1,3 +1,3 @@
1
1
  module Bitsy
2
- VERSION = "0.1.0"
2
+ VERSION = "0.2.0"
3
3
  end
@@ -1,10 +1,9 @@
1
1
  defaults: &defaults
2
- bitcoind:
3
- host: "localhost"
4
- username: "admin1"
5
- password: "123"
6
- port: "19001"
7
- ssl: false
2
+ blockchain:
3
+ identifier: ada4e4b6-3c9f-11e4-baad-164230d1df67
4
+ password: password123
5
+ second_password: if any
6
+ api_code: if any
8
7
 
9
8
  development:
10
9
  <<: *defaults
@@ -6,5 +6,5 @@ module Clockwork
6
6
  Sidekiq::Client.push('class' => job, 'args' => [])
7
7
  end
8
8
 
9
- every(5.seconds, 'Bitsy::PaymentJob')
9
+ every(10.minutes, 'Bitsy::TransactionsUpdateJob')
10
10
  end
@@ -10,9 +10,4 @@ Bitsy.configure do |c|
10
10
 
11
11
  # How many confirmations are needed to consider a transaction as complete
12
12
  c.safe_confirmation_threshold = 0
13
-
14
- # The name where all money is pooled before sending out. You will likely not
15
- # need to change this value. Note that blockchain.info only accepts master
16
- # account names between 0 and 255 characters.
17
- c.master_account_name = "master"
18
13
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: bitsy-bitcoin
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ramon Tayag
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-09-14 00:00:00.000000000 Z
11
+ date: 2014-11-10 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rails
@@ -114,14 +114,14 @@ dependencies:
114
114
  requirements:
115
115
  - - '='
116
116
  - !ruby/object:Gem::Version
117
- version: 0.2.1
117
+ version: 0.5.0
118
118
  type: :runtime
119
119
  prerelease: false
120
120
  version_requirements: !ruby/object:Gem::Requirement
121
121
  requirements:
122
122
  - - '='
123
123
  - !ruby/object:Gem::Version
124
- version: 0.2.1
124
+ version: 0.5.0
125
125
  - !ruby/object:Gem::Dependency
126
126
  name: uuidtools
127
127
  requirement: !ruby/object:Gem::Requirement
@@ -136,6 +136,20 @@ dependencies:
136
136
  - - "~>"
137
137
  - !ruby/object:Gem::Version
138
138
  version: '2.1'
139
+ - !ruby/object:Gem::Dependency
140
+ name: blockchain
141
+ requirement: !ruby/object:Gem::Requirement
142
+ requirements:
143
+ - - "~>"
144
+ - !ruby/object:Gem::Version
145
+ version: '1.0'
146
+ type: :runtime
147
+ prerelease: false
148
+ version_requirements: !ruby/object:Gem::Requirement
149
+ requirements:
150
+ - - "~>"
151
+ - !ruby/object:Gem::Version
152
+ version: '1.0'
139
153
  - !ruby/object:Gem::Dependency
140
154
  name: sqlite3
141
155
  requirement: !ruby/object:Gem::Requirement
@@ -241,21 +255,21 @@ dependencies:
241
255
  - !ruby/object:Gem::Version
242
256
  version: '0'
243
257
  - !ruby/object:Gem::Dependency
244
- name: bitcoin_cleaner
258
+ name: standalone_migrations
245
259
  requirement: !ruby/object:Gem::Requirement
246
260
  requirements:
247
- - - '='
261
+ - - ">="
248
262
  - !ruby/object:Gem::Version
249
- version: 1.0.0.beta.1
263
+ version: '0'
250
264
  type: :development
251
265
  prerelease: false
252
266
  version_requirements: !ruby/object:Gem::Requirement
253
267
  requirements:
254
- - - '='
268
+ - - ">="
255
269
  - !ruby/object:Gem::Version
256
- version: 1.0.0.beta.1
270
+ version: '0'
257
271
  - !ruby/object:Gem::Dependency
258
- name: standalone_migrations
272
+ name: shoulda-matchers
259
273
  requirement: !ruby/object:Gem::Requirement
260
274
  requirements:
261
275
  - - ">="
@@ -281,33 +295,43 @@ files:
281
295
  - app/assets/javascripts/bitsy/application.js
282
296
  - app/assets/stylesheets/bitsy/application.css
283
297
  - app/controllers/bitsy/application_controller.rb
298
+ - app/controllers/bitsy/v1/blockchain_notifications_controller.rb
284
299
  - app/controllers/bitsy/v1/payment_depots_controller.rb
285
300
  - app/controllers/bitsy/v1/syncs_controller.rb
286
301
  - app/controllers/bitsy/v1/truncations_controller.rb
287
302
  - app/helpers/bitsy/application_helper.rb
288
- - app/jobs/bitsy/payment_job.rb
303
+ - app/jobs/bitsy/blockchain_notification_job.rb
304
+ - app/jobs/bitsy/forward_job.rb
305
+ - app/jobs/bitsy/transactions_sync_job.rb
306
+ - app/models/bitsy/blockchain_notification.rb
289
307
  - app/models/bitsy/payment_depot.rb
290
308
  - app/models/bitsy/payment_transaction.rb
291
309
  - app/serializers/bitsy/payment_depot_serializer.rb
292
310
  - app/services/bitsy/amount_for_initial_tax_calculator.rb
293
311
  - app/services/bitsy/associates_transactions.rb
294
- - app/services/bitsy/builds_send_many_hash.rb
295
- - app/services/bitsy/creates_transaction.rb
312
+ - app/services/bitsy/build_send_many_hash.rb
313
+ - app/services/bitsy/create_payment_depot.rb
314
+ - app/services/bitsy/forward_payments.rb
296
315
  - 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
316
+ - app/services/bitsy/instantiate_blockchain_wallet.rb
317
+ - app/services/bitsy/process_blockchain_notification.rb
318
+ - app/services/bitsy/send_payments.rb
319
+ - app/services/bitsy/updating/get_latest_block.rb
320
+ - app/services/bitsy/updating/select_transactions.rb
321
+ - app/services/bitsy/updating/sync_transactions.rb
322
+ - app/services/bitsy/updating/update_transaction.rb
323
+ - app/services/bitsy/updating/update_transactions.rb
305
324
  - app/views/layouts/bitsy/application.html.erb
306
325
  - config/bitsy.yml
326
+ - config/database.yml
307
327
  - config/initializers/bitsy.rb
308
328
  - config/routes.rb
329
+ - db/development.sqlite3
309
330
  - db/migrate/20140607015614_create_bitsy_payment_depots.rb
310
331
  - db/migrate/20140607015859_create_bitsy_payment_transactions.rb
332
+ - db/migrate/20141106123922_create_bitsy_blockchain_notifications.rb
333
+ - db/migrate/20141108002656_drop_occurred_at_and_received_at_from_payment_transactions.rb
334
+ - db/migrate/20141109072242_change_payment_depot_balance_cache_default.rb
311
335
  - lib/bitsy-bitcoin.rb
312
336
  - lib/bitsy.rb
313
337
  - lib/bitsy/config.rb
@@ -1,15 +0,0 @@
1
- module Bitsy
2
- class PaymentJob
3
-
4
- include Sidekiq::Worker
5
- sidekiq_options retry: false
6
-
7
- def perform
8
- ProcessesPayments.for(
9
- bit_wallet: Bitsy.bit_wallet,
10
- bit_wallet_master_account: Bitsy.master_account
11
- )
12
- end
13
-
14
- end
15
- end
@@ -1,25 +0,0 @@
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
@@ -1,31 +0,0 @@
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
@@ -1,20 +0,0 @@
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
@@ -1,13 +0,0 @@
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
@@ -1,14 +0,0 @@
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
@@ -1,24 +0,0 @@
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
@@ -1,26 +0,0 @@
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
@@ -1,17 +0,0 @@
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
@@ -1,13 +0,0 @@
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