Class: Zold::Wallet

Inherits:
Object
  • Object
show all
Defined in:
lib/zold/wallet.rb

Overview

A single wallet

Instance Method Summary collapse

Constructor Details

#initialize(file) ⇒ Wallet

Returns a new instance of Wallet.



31
32
33
# File 'lib/zold/wallet.rb', line 31

def initialize(file)
  @file = file
end

Instance Method Details

#add(txn) ⇒ Object



108
109
110
111
112
113
114
115
116
# File 'lib/zold/wallet.rb', line 108

def add(txn)
  xml = load
  t = xml.xpath('/wallet/ledger')[0].add_child('<txn/>')[0]
  t['id'] = "/#{txn[:id]}"
  t.add_child('<date/>')[0].content = txn[:date].iso8601
  t.add_child('<amount/>')[0].content = txn[:amount].to_i
  t.add_child('<beneficiary/>')[0].content = txn[:beneficiary]
  save(xml).to_s
end

#balanceObject



83
84
85
86
87
88
89
90
# File 'lib/zold/wallet.rb', line 83

def balance
  Amount.new(
    coins: load.xpath('/wallet/ledger/txn/amount/text()')
      .map(&:to_s)
      .map(&:to_i)
      .inject(0) { |sum, n| sum + n }
  )
end

#check(id, amount, beneficiary) ⇒ Object



118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
# File 'lib/zold/wallet.rb', line 118

def check(id, amount, beneficiary)
  xml = load
  txn = xml.xpath("/wallet/ledger/txn[@id='#{id}']")[0]
  xamount = Amount.new(
    coins: txn.xpath('amount/text()')[0].to_s.to_i
  ).mul(-1)
  raise "#{xamount} != #{amount}" if xamount != amount
  xbeneficiary = Id.new(txn.xpath('beneficiary/text()')[0].to_s)
  raise "#{xbeneficiary} != #{beneficiary}" if xbeneficiary != beneficiary
  data = "#{id} #{amount.to_i} #{beneficiary}"
  valid = Key.new(text: xml.xpath('/wallet/pkey/text()')[0].to_s).verify(
    txn.xpath('sign/text()')[0].to_s, data
  )
  raise "Signature is not confirming this data: '#{data}'" unless valid
  true
end

#exists?Boolean

Returns:

  • (Boolean)


39
40
41
# File 'lib/zold/wallet.rb', line 39

def exists?
  File.exist?(@file)
end

#idObject



79
80
81
# File 'lib/zold/wallet.rb', line 79

def id
  Id.new(load.xpath('/wallet/id/text()').to_s)
end

#incomeObject



135
136
137
138
139
140
141
142
143
144
# File 'lib/zold/wallet.rb', line 135

def income
  load.xpath('/wallet/ledger/txn[amount > 0]').each do |txn|
    hash = {
      id: txn['id'][1..-1].to_i,
      beneficiary: Id.new(txn.xpath('beneficiary/text()')[0].to_s),
      amount: Amount.new(coins: txn.xpath('amount/text()')[0].to_s.to_i)
    }
    yield hash
  end
end

#init(id, pubkey) ⇒ Object



47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
# File 'lib/zold/wallet.rb', line 47

def init(id, pubkey)
  raise "File '#{@file}' already exists" if File.exist?(@file)
  File.write(
    @file,
    valid(
      Nokogiri::XML::Builder.new do |xml|
        xml.wallet do
          xml.id_ id.to_s
          xml.pkey pubkey.to_s
          xml.ledger {}
        end
      end.doc
    )
  )
end

#pathObject



43
44
45
# File 'lib/zold/wallet.rb', line 43

def path
  @file
end

#root?Boolean

Returns:

  • (Boolean)


75
76
77
# File 'lib/zold/wallet.rb', line 75

def root?
  id == Id::ROOT
end

#sub(amount, target, pvtkey) ⇒ Object



92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
# File 'lib/zold/wallet.rb', line 92

def sub(amount, target, pvtkey)
  xml = load
  date = Time.now
  txn = version + 1
  t = xml.xpath('/wallet/ledger')[0].add_child('<txn/>')[0]
  t['id'] = txn
  t.add_child('<date/>')[0].content = date.iso8601
  t.add_child('<amount/>')[0].content = -amount.to_i
  t.add_child('<beneficiary/>')[0].content = target
  t.add_child('<sign/>')[0].content = pvtkey.sign(
    "#{txn} #{amount.to_i} #{target}"
  )
  save(xml)
  { id: txn, date: date, amount: amount, beneficiary: id }
end

#to_sObject



35
36
37
# File 'lib/zold/wallet.rb', line 35

def to_s
  id
end

#versionObject



63
64
65
66
67
68
69
70
71
72
73
# File 'lib/zold/wallet.rb', line 63

def version
  xml = load
  ver = 0
  unless xml.xpath('/wallet/ledger[txn]').empty?
    ver = xml.xpath('/wallet/ledger/txn/@id')
      .map(&:to_s)
      .map(&:to_i)
      .max
  end
  ver
end