rippler 0.0.10 → 0.0.11
Sign up to get free protection for your applications and to get access to all the features.
- data/README.md +10 -2
- data/bin/rippler +13 -1
- data/lib/rippler.rb +52 -14
- data/lib/rippler/contacts.rb +18 -3
- data/lib/rippler/money.rb +12 -7
- data/lib/rippler/offer.rb +63 -0
- data/lib/rippler/transaction.rb +1 -4
- data/lib/rippler/utils.rb +4 -0
- data/lib/rippler/version.rb +1 -1
- metadata +3 -2
data/README.md
CHANGED
@@ -32,9 +32,13 @@ Ripple server replies are returned as JSON and printed to stdout. If you want to
|
|
32
32
|
|
33
33
|
## Usage: additional commands
|
34
34
|
|
35
|
-
Rippler also provides additional commands that print out human-readable output
|
35
|
+
Rippler also provides additional commands that print out human-readable output. You can use option -t for text (rather than structural) output.
|
36
36
|
|
37
|
-
$ rippler
|
37
|
+
$ rippler -t order_book buy:BTC/bitstamp sell:XRP
|
38
|
+
|
39
|
+
This one prints current order book for any currency pair.
|
40
|
+
|
41
|
+
$ rippler -t history account:molecular
|
38
42
|
|
39
43
|
This one prints any account history in a human-readable format.
|
40
44
|
|
@@ -46,6 +50,10 @@ This one prints out all outstanding balances (debit/credit IOUs and XRP) for a s
|
|
46
50
|
|
47
51
|
This one monitors Ripple transactions in real-time similar to #ripple-watch, but more interesting since it shows known account names instead of opaque addresses. Ctrl-C to stop it.
|
48
52
|
|
53
|
+
$ rippler path_find source_account:RippleUnion destination_account:singpolyma 'destination_amount:{currency:CAD, value:1}'
|
54
|
+
|
55
|
+
This one finds possible paths for amounts of money between two addresses, and prints out what the source would have to send to get that amount to the destination.
|
56
|
+
|
49
57
|
## Contacts database
|
50
58
|
|
51
59
|
Contacts database is in lib/rippler/contacts.rb, mostly auto-scraped from Bitcointalk. It may be a bit inaccurate, you can modify/extend it as you see fit.
|
data/bin/rippler
CHANGED
@@ -6,4 +6,16 @@ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
|
6
6
|
require 'rippler'
|
7
7
|
require "pp"
|
8
8
|
|
9
|
-
|
9
|
+
if ARGV[0] == '-t'
|
10
|
+
ARGV.shift
|
11
|
+
|
12
|
+
Rippler.process(ARGV).each do |v|
|
13
|
+
if v.is_a?(String)
|
14
|
+
puts v
|
15
|
+
else
|
16
|
+
pp v
|
17
|
+
end
|
18
|
+
end
|
19
|
+
else
|
20
|
+
pp Rippler.process ARGV
|
21
|
+
end
|
data/lib/rippler.rb
CHANGED
@@ -11,6 +11,7 @@ require 'rippler/account'
|
|
11
11
|
require 'rippler/ledger'
|
12
12
|
require 'rippler/transaction'
|
13
13
|
require 'rippler/line'
|
14
|
+
require 'rippler/offer'
|
14
15
|
|
15
16
|
module Rippler
|
16
17
|
extend Rippler::Utils
|
@@ -18,16 +19,23 @@ module Rippler
|
|
18
19
|
RIPPLE_URI = 'wss://s1.ripple.com:51233'
|
19
20
|
DEFAULT_ACCT = Rippler::Contacts["molecular"]
|
20
21
|
|
22
|
+
def self.parse_params command_line
|
23
|
+
params = command_line.map {|p| p.split(':',2)}.flatten. # get json pairs
|
24
|
+
map {|p| p =~ /\[.*\]/ ? p.gsub(/\[|\]/,'').split(',') : p}. # get arrays
|
25
|
+
map {|p| p =~ /\{(.*)\}/ ? self.parse_params($1.split(/\s*,\s*/)) : p} # get objects
|
26
|
+
Hash[*params]
|
27
|
+
end
|
28
|
+
|
21
29
|
# Turn command line arguments into command json
|
22
30
|
def self.process args
|
23
31
|
command_line = args.empty? ? ['account_info'] : args.dup
|
24
32
|
|
25
33
|
command = command_line.shift
|
26
|
-
params =
|
27
|
-
map {|p| p =~ /\[.*\]/ ? p.gsub(/\[|\]/,'').split(',') : p} # get arrays
|
28
|
-
params = Hash[*params]
|
34
|
+
params = self.parse_params command_line
|
29
35
|
|
30
36
|
params['account'] = Account(params['account']).address if params['account']
|
37
|
+
params['destination_account'] = Account(params['destination_account']).address if params['destination_account']
|
38
|
+
params['source_account'] = Account(params['source_account']).address if params['source_account']
|
31
39
|
|
32
40
|
# p command, params
|
33
41
|
|
@@ -86,17 +94,12 @@ module Rippler
|
|
86
94
|
|
87
95
|
### These API commands need some pre/post-process wrappers
|
88
96
|
|
89
|
-
# book_offers
|
90
|
-
#
|
97
|
+
# book_offers should accept "taker_gets" & "taker_pays" params
|
98
|
+
# in both "CUR/issuer" and {"currency":currency, "issuer":address} formats
|
91
99
|
def self.book_offers params
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
reply = request( params.merge('command' => "book_offers",
|
96
|
-
'taker_gets' => taker_gets.to_hash,
|
97
|
-
'taker_pays' => taker_pays.to_hash))
|
98
|
-
|
99
|
-
# lines = reply["result"]["lines"]
|
100
|
+
request( params.merge('command' => "book_offers",
|
101
|
+
'taker_gets' => Money(params['taker_gets']).to_hash,
|
102
|
+
'taker_pays' => Money(params['taker_pays']).to_hash))
|
100
103
|
end
|
101
104
|
|
102
105
|
|
@@ -108,6 +111,22 @@ module Rippler
|
|
108
111
|
|
109
112
|
### These are user-defined methods that post-process Ripple replies
|
110
113
|
|
114
|
+
# Subscibe to event streams, print events out nicely formatted
|
115
|
+
def self.order_book params
|
116
|
+
|
117
|
+
buy = params['buy']
|
118
|
+
sell = params['sell']
|
119
|
+
reply = book_offers('taker_gets' => buy,'taker_pays' => sell)
|
120
|
+
|
121
|
+
asks = reply['result']['offers'].map {|o| Offer.new(o)}
|
122
|
+
|
123
|
+
reply = book_offers('taker_gets' => sell,'taker_pays' => buy)
|
124
|
+
|
125
|
+
bids = reply['result']['offers'].map {|o| Offer.new(o)}
|
126
|
+
|
127
|
+
(asks.reverse + bids.unshift("-"*40) ).map(&:to_s)
|
128
|
+
end
|
129
|
+
|
111
130
|
# Subscibe to event streams, print events out nicely formatted
|
112
131
|
def self.monitor params
|
113
132
|
subscribe(params) do |message|
|
@@ -155,8 +174,27 @@ module Rippler
|
|
155
174
|
'sort_asc' => 1
|
156
175
|
}.merge(params) ) #(optional)
|
157
176
|
txs = reply["result"]["transactions"]
|
158
|
-
txs.map {|t| Transaction.new(t)}.map(&:to_s)
|
177
|
+
txs.map {|t| Transaction.new(t)}.map(&:to_s).reverse
|
159
178
|
.push("Total transactions: #{txs.size}")
|
179
|
+
end
|
160
180
|
|
181
|
+
def self.path_find params
|
182
|
+
params.merge!('command' => 'ripple_path_find')
|
183
|
+
if params['destination_amount'] && ! params['destination_amount']['issuer']
|
184
|
+
params['destination_amount']['issuer'] = params['destination_account']
|
185
|
+
end
|
186
|
+
reply = request(params)
|
187
|
+
reply['result']['alternatives'].map {|alt|
|
188
|
+
if alt['source_amount'].is_a?(String)
|
189
|
+
# XRP as per https://ripple.com/wiki/JSON_API#XRP
|
190
|
+
if alt['source_amount'] =~ /\./
|
191
|
+
alt['source_amount'].to_f
|
192
|
+
else
|
193
|
+
alt['source_amount'].to_i.to_f / 1000000
|
194
|
+
end
|
195
|
+
else
|
196
|
+
"#{alt['source_amount']['value']}/#{alt['source_amount']['currency']}/#{alt['source_amount']['issuer']}"
|
197
|
+
end
|
198
|
+
}
|
161
199
|
end
|
162
200
|
end
|
data/lib/rippler/contacts.rb
CHANGED
@@ -13,7 +13,6 @@ module Rippler
|
|
13
13
|
X.FortKnox.9 rp7gaQch2fiNQHDPrnPk9pG65e9cnv7g6X
|
14
14
|
X.FortKnox.a rstKSeB2Qx7zrwSkyc7X9Xm5nYTJqtL3iM
|
15
15
|
X.FortKnox.b rJYMACXJd1eejwzZA53VncYmiK2kZSBxyD
|
16
|
-
X.FortKnox.c r9ycgvDgXjeiaYmoz4F8sKBNXgHHx1wVFM
|
17
16
|
X.Distributor.1 r8TR1AeB1RDQFabM6i8UoFsRF5basqoHJ
|
18
17
|
X.Veirou rhq5LEZSWHWY6H3raiC2KGe8TVeirou4BS
|
19
18
|
X.Wow rHD7Bs8Zk1oQeUhLjPrsFStFcRE2NWoWpe
|
@@ -43,7 +42,6 @@ module Rippler
|
|
43
42
|
X.16 rUGNvasUuxLiPL5RXvfZXW8HjBtSHZgqgz
|
44
43
|
X.17 rPyuHFYDwYMGJ5xhMbzfYeikx7ARV3ExvF
|
45
44
|
X.18 r4MZrGMPEHfxGNQHR92BJo5hU9BiqMsTej
|
46
|
-
X.19 r3ADD8kXSUKHd6zTCKfnKT3zV9EZHjzp1S
|
47
45
|
X.20 rnW7DHtmZGJk4uhGTSU2BW3iPCPWb2xegg
|
48
46
|
X.21 rUrdFHbrEKWNQQ444zcTLrThjcnHCw2FPu
|
49
47
|
X.22 r49nVgaYSDuU7GEQh4mF1nyjsXSVRcUHsr
|
@@ -82,7 +80,6 @@ module Rippler
|
|
82
80
|
X.56 rDZ8QghKF4C11pmbVAkqumPTehiF8mfHt3
|
83
81
|
X.57 rDGd76GCnZYGhjiAngV3xrPV4Qkfx79qqp
|
84
82
|
X.58 r9Y4Mdhs339CxpCFxgdBVRcuM5i4rMRbu
|
85
|
-
X.59 rPcu8U9dSsK6nHtqgpeSvjuFTmNGq3arPh
|
86
83
|
|
87
84
|
ADDRESS_ONE rrrrrrrrrrrrrrrrrrrrBZbvji
|
88
85
|
OpenCoin rJR7gjNe3DpJ7kpB4CHBxjDKfwVMpTKPpj
|
@@ -95,6 +92,8 @@ module Rippler
|
|
95
92
|
bitstamp rvYAfWj5gh67oV6fW32ZzP3Aw4Eubs59B
|
96
93
|
bitstamp.hotwallet rrpNnNLKrartuEqfJGpqyDwPj1AFPg9vn1
|
97
94
|
bitstamp.NejcKodric rphasxS8Q5p5TLTpScQCBhh5HfJfPbM2M8
|
95
|
+
bitstamp.wholesale r9ycgvDgXjeiaYmoz4F8sKBNXgHHx1wVFM
|
96
|
+
RippleUnion r3ADD8kXSUKHd6zTCKfnKT3zV9EZHjzp1S
|
98
97
|
|
99
98
|
TTBit rGwUWgN5BEg3QGNY3RX2HfYowjUTZdid3E
|
100
99
|
BankOfZed ra88Lr8fyo9cUTuyjVFMTrvTSBU93erjyh
|
@@ -507,6 +506,7 @@ module Rippler
|
|
507
506
|
DrG.1 rJEZjBv27ZHCPAoDtTBJb9r82VnUdkRd77
|
508
507
|
DrG.2 rQNFxWVBxnjeF5gaFKwoj5nr3WansCtR19
|
509
508
|
UnitClick rLKojeESeKi9mdBuPLkiQhCxs4wh8iKy2W
|
509
|
+
UnitClick.1 rJrJuCmNuZ9shGgZvAhM6Xsv8PdghQTokc
|
510
510
|
saddambitcoin rMSEYpzcRtkiA5kkxYEWZtvLr8u3jnn385
|
511
511
|
helloworld111 rwGAnUvzT5yrDz6dXxm6MWVhpV9abm39W3
|
512
512
|
dykast rQfwn3GVHVEfTpjqU2Y3BoMGAGHrw43XnT
|
@@ -577,10 +577,25 @@ module Rippler
|
|
577
577
|
v7znay rGNNQZo3KXaeC8i33FmbddUk43iRELPkKk
|
578
578
|
wannabitcoin rLubad3VQxaeT6qk43jEGPJX7ADkMBkwTM
|
579
579
|
webr3 rnW7DHtmZGJk4uhGTSU2BW3iPCPWb2xegg
|
580
|
+
webr3.1 rPcu8U9dSsK6nHtqgpeSvjuFTmNGq3arPh
|
580
581
|
WikileaksDude rE7QqUJQWFGu7JZU6E9byysF6Qu5UQjQkP
|
582
|
+
WikileaksDude.1 r9nzyxxnnmf2Qg8HjKYdwWSN6YJXJtMpQ
|
581
583
|
LoweryCBS rBiYVjzHRQxMDMdC5ynKsejqoy1qJMQ8zR
|
582
584
|
ScratAcorns rEwNm7FWSy4whunsNRCebPbDktjeoGhdbS
|
583
585
|
Dreamweaver rnt5BahXixR8PeBwsYXynN6Ew8MCn87GUn
|
586
|
+
nomis rUr7cFcUasrhZ234RZKfKHmQNzM5FPQEHi
|
587
|
+
alberthrocks rUaEuoMVzmZNxx3etp8DhEWGD6UeJaoiq4
|
588
|
+
Xenius rfaLKpYas7BLsjnbm2dpPDQRKaNbBLGTgs
|
589
|
+
liamwli rEvjdo5evfU65J9evHZyHFsEVs4t4Mbfqr
|
590
|
+
fghj rHpaEMuN84JR6VT2umSbtSrHJ8JGWyza8f
|
591
|
+
MasonIII rsieHiunKBtHr1JXZZvU98erDkG8MD7R2r
|
592
|
+
macbook-air rp3dmTa3i1aFY1JwsMKc1WVKJtdj3s6cHc
|
593
|
+
Dabs rsAbwKtKaePtmVZhS5H2eT5K4u9UWR7mX5
|
594
|
+
Liquid rsuvuGXuWdoRUJXiLQ7z9kyM4tjuXgrZJs
|
595
|
+
Projects rsjPEDMnjdcKRJhCDm61YbXPNgJN6tjoPc
|
596
|
+
Snowpea rsCmWSczxBpRri57jcMw8duYJETaspFRd9
|
597
|
+
stick rQy7ajMPs2WMmMgLTtZtadLxTEvsXDhRF
|
598
|
+
darkmule r4VfSDJZNX53TRd6nExAmzsPdX7jbRSHf1
|
584
599
|
]]
|
585
600
|
|
586
601
|
Addresses = Contacts.invert
|
data/lib/rippler/money.rb
CHANGED
@@ -18,13 +18,18 @@ module Rippler
|
|
18
18
|
@issuer = data['issuer']
|
19
19
|
when String
|
20
20
|
@value, @currency, @issuer = *data.split('/')
|
21
|
-
|
22
|
-
|
21
|
+
|
22
|
+
if @value.to_f == 0 # No value, must be generic currency: XRP or USD/bitstamp
|
23
|
+
@currency, @issuer = @value, @currency
|
23
24
|
else
|
24
|
-
|
25
|
-
|
25
|
+
if @currency
|
26
|
+
@value = @value.to_f
|
27
|
+
else
|
28
|
+
@value = @value.to_i/1000000.0
|
29
|
+
@currency = "XRP"
|
30
|
+
end
|
26
31
|
end
|
27
|
-
when
|
32
|
+
when Integer
|
28
33
|
@value = data.to_i/1000000.0
|
29
34
|
@currency = "XRP"
|
30
35
|
end
|
@@ -44,8 +49,8 @@ module Rippler
|
|
44
49
|
[self, cross]
|
45
50
|
end
|
46
51
|
r = first.value.to_f/second.value.to_f
|
47
|
-
r = r.to_i == r ? r.to_i : r
|
48
|
-
"#{r}#{first.currency}/#{second.currency}"
|
52
|
+
r = r.to_i == r ? r.to_i : r.round(2)
|
53
|
+
"#{r} #{first.currency}/#{second.currency}"
|
49
54
|
end
|
50
55
|
|
51
56
|
# Allows methods such as xrp? usd? or btc?
|
@@ -0,0 +1,63 @@
|
|
1
|
+
module Rippler
|
2
|
+
class Offer
|
3
|
+
include Rippler::Utils
|
4
|
+
|
5
|
+
# attr_accessor :address, :balance, :flags
|
6
|
+
|
7
|
+
# Hash:
|
8
|
+
# {"Account"=>"rngJ9Co6MPZxJcyepRv2hMPV1HqaeGCdVU",
|
9
|
+
# "BookDirectory"=> "4627DFFCFF8B5A265EDBD8AE8C14A52325DBFEDAF4F5C32E5E03DACD3F94D000",
|
10
|
+
# "BookNode"=>"0000000000000000",
|
11
|
+
# "Flags"=>0,
|
12
|
+
# "LedgerEntryType"=>"Offer",
|
13
|
+
# "OwnerNode"=>"0000000000000000",
|
14
|
+
# "PreviousTxnID"=> "704A6FCC2DD0AEE9B5F420C3641FB86FFE73F4D233E4B9F6A10E5DE79F7DAACF",
|
15
|
+
# "PreviousTxnLgrSeq"=>432517,
|
16
|
+
# "Sequence"=>191,
|
17
|
+
# "TakerGets"=>
|
18
|
+
# {"currency"=>"USD", "issuer"=>"rvYAfWj5gh67oV6fW32ZzP3Aw4Eubs59B", "value"=>"150"},
|
19
|
+
# "TakerPays"=>"449850000000",
|
20
|
+
# "index"=> "D34C841609A12DAF9DF1B59CA7CB930091A1A16C4A400D8AFDF73311CBB2A2C5",
|
21
|
+
# "taker_gets_funded"=>
|
22
|
+
# {"currency"=>"USD", "issuer"=>"rvYAfWj5gh67oV6fW32ZzP3Aw4Eubs59B", "value"=>"51.73532238374231"},
|
23
|
+
# "taker_pays_funded"=>"155154231828"},
|
24
|
+
def initialize data
|
25
|
+
@data = data
|
26
|
+
@take
|
27
|
+
case data
|
28
|
+
when String
|
29
|
+
@address = Rippler::Contacts[data] || data
|
30
|
+
@name = Rippler::Addresses[@address]
|
31
|
+
when Hash
|
32
|
+
@address = data["Account"]
|
33
|
+
@name = Rippler::Addresses[@address]
|
34
|
+
@balance = Money(data["Balance"])
|
35
|
+
@flags = data["Flags"]
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
def gets
|
40
|
+
@get ||= Money(@data['TakerGets'])
|
41
|
+
end
|
42
|
+
|
43
|
+
def pays
|
44
|
+
@pay = Money(@data['TakerPays'])
|
45
|
+
end
|
46
|
+
|
47
|
+
def account
|
48
|
+
@account ||= Account(@data['Account'])
|
49
|
+
end
|
50
|
+
|
51
|
+
def funded
|
52
|
+
if @data['taker_gets_funded'] || @data['taker_pays_funded']
|
53
|
+
funds = Money(@data['taker_gets_funded'])
|
54
|
+
" (#{(funds.value/gets.value*100).round(2)}% funded)"
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
def to_s
|
59
|
+
"OFR at #{gets.rate(pays)}, #{gets} for #{pays}" +
|
60
|
+
"#{funded} by #{account} ##{@data['Sequence']}"
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
data/lib/rippler/transaction.rb
CHANGED
@@ -28,10 +28,7 @@ module Rippler
|
|
28
28
|
when "OfferCancel"
|
29
29
|
"CAN #{Account(tx['Account'])} ##{tx['Sequence']}"
|
30
30
|
when "OfferCreate"
|
31
|
-
|
32
|
-
pay = Money(tx['TakerPays'])
|
33
|
-
"OFR #{Account(tx['Account'])} ##{tx['Sequence']} offers " +
|
34
|
-
"#{get} for #{pay} (#{get.rate(pay)})"
|
31
|
+
Offer(tx).to_s
|
35
32
|
when "TrustSet"
|
36
33
|
"TRS #{Money(tx['LimitAmount'])} #{Account(tx['Account'])}"
|
37
34
|
else
|
data/lib/rippler/utils.rb
CHANGED
data/lib/rippler/version.rb
CHANGED
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: rippler
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.11
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2013-03-
|
12
|
+
date: 2013-03-31 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: faye-websocket
|
@@ -48,6 +48,7 @@ files:
|
|
48
48
|
- lib/rippler/ledger.rb
|
49
49
|
- lib/rippler/line.rb
|
50
50
|
- lib/rippler/money.rb
|
51
|
+
- lib/rippler/offer.rb
|
51
52
|
- lib/rippler/transaction.rb
|
52
53
|
- lib/rippler/utils.rb
|
53
54
|
- lib/rippler/version.rb
|