xrbp 0.0.1 → 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (86) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +103 -5
  3. data/examples/accounts.rb +13 -0
  4. data/examples/autoconnect_timeout.rb +5 -1
  5. data/examples/autorety.rb +7 -0
  6. data/examples/crawl_nodes.rb +32 -0
  7. data/examples/dsl/account.rb +16 -0
  8. data/examples/dsl/ledger.rb +7 -0
  9. data/examples/dsl/ledger_subscribe.rb +18 -0
  10. data/examples/dsl/validators.rb +8 -0
  11. data/examples/gateways.rb +8 -0
  12. data/examples/latest_account.rb +4 -0
  13. data/examples/ledger_multi_subscribe.rb +1 -1
  14. data/examples/ledger_subscribe.rb +2 -2
  15. data/examples/market.rb +13 -0
  16. data/examples/username.rb +12 -0
  17. data/examples/validator.rb +8 -0
  18. data/lib/xrbp.rb +5 -1
  19. data/lib/xrbp/common.rb +10 -0
  20. data/lib/xrbp/core_ext.rb +24 -0
  21. data/lib/xrbp/dsl.rb +25 -0
  22. data/lib/xrbp/dsl/accounts.rb +13 -0
  23. data/lib/xrbp/dsl/ledgers.rb +23 -0
  24. data/lib/xrbp/dsl/validators.rb +10 -0
  25. data/lib/xrbp/dsl/webclient.rb +8 -0
  26. data/lib/xrbp/dsl/websocket.rb +28 -0
  27. data/lib/xrbp/model.rb +4 -0
  28. data/lib/xrbp/model/account.rb +142 -1
  29. data/lib/xrbp/model/base.rb +1 -0
  30. data/lib/xrbp/model/gateway.rb +24 -0
  31. data/lib/xrbp/model/ledger.rb +30 -1
  32. data/lib/xrbp/model/market.rb +52 -0
  33. data/lib/xrbp/model/node.rb +131 -0
  34. data/lib/xrbp/model/parsers/account.rb +44 -0
  35. data/lib/xrbp/model/parsers/gateway.rb +40 -0
  36. data/lib/xrbp/model/parsers/market.rb +28 -0
  37. data/lib/xrbp/model/parsers/node.rb +19 -0
  38. data/lib/xrbp/model/parsers/quote.rb +47 -0
  39. data/lib/xrbp/model/parsers/validator.rb +25 -0
  40. data/lib/xrbp/model/validator.rb +24 -0
  41. data/lib/xrbp/plugins.rb +6 -0
  42. data/lib/xrbp/plugins/base.rb +10 -0
  43. data/lib/xrbp/plugins/has_plugin.rb +45 -0
  44. data/lib/xrbp/plugins/has_result_parsers.rb +27 -0
  45. data/lib/xrbp/plugins/plugin_registry.rb +20 -0
  46. data/lib/xrbp/plugins/result_parser.rb +19 -0
  47. data/lib/xrbp/terminatable.rb +19 -0
  48. data/lib/xrbp/thread_registry.rb +22 -0
  49. data/lib/xrbp/version.rb +1 -1
  50. data/lib/xrbp/webclient.rb +2 -0
  51. data/lib/xrbp/webclient/connection.rb +100 -0
  52. data/lib/xrbp/webclient/plugins.rb +8 -0
  53. data/lib/xrbp/webclient/plugins/autoretry.rb +54 -0
  54. data/lib/xrbp/webclient/plugins/result_parser.rb +23 -0
  55. data/lib/xrbp/websocket/client.rb +85 -24
  56. data/lib/xrbp/websocket/cmds/account_info.rb +4 -0
  57. data/lib/xrbp/websocket/cmds/account_lines.rb +5 -0
  58. data/lib/xrbp/websocket/cmds/account_objects.rb +4 -0
  59. data/lib/xrbp/websocket/cmds/account_offers.rb +5 -0
  60. data/lib/xrbp/websocket/cmds/account_tx.rb +4 -0
  61. data/lib/xrbp/websocket/cmds/book_offers.rb +4 -0
  62. data/lib/xrbp/websocket/cmds/ledger.rb +3 -0
  63. data/lib/xrbp/websocket/cmds/ledger_entry.rb +4 -0
  64. data/lib/xrbp/websocket/cmds/paginated.rb +4 -1
  65. data/lib/xrbp/websocket/cmds/server_info.rb +4 -0
  66. data/lib/xrbp/websocket/cmds/subscribe.rb +4 -0
  67. data/lib/xrbp/websocket/command.rb +11 -0
  68. data/lib/xrbp/websocket/connection.rb +75 -22
  69. data/lib/xrbp/websocket/message.rb +5 -2
  70. data/lib/xrbp/websocket/multi/fallback.rb +2 -4
  71. data/lib/xrbp/websocket/multi/multi_connection.rb +37 -2
  72. data/lib/xrbp/websocket/multi/parallel.rb +2 -4
  73. data/lib/xrbp/websocket/multi/prioritized.rb +2 -4
  74. data/lib/xrbp/websocket/multi/round_robin.rb +4 -0
  75. data/lib/xrbp/websocket/plugins.rb +1 -7
  76. data/lib/xrbp/websocket/plugins/autoconnect.rb +25 -5
  77. data/lib/xrbp/websocket/plugins/command_dispatcher.rb +5 -0
  78. data/lib/xrbp/websocket/plugins/command_paginator.rb +9 -8
  79. data/lib/xrbp/websocket/plugins/connection_timeout.rb +27 -16
  80. data/lib/xrbp/websocket/plugins/message_dispatcher.rb +60 -30
  81. data/lib/xrbp/websocket/plugins/result_parser.rb +19 -19
  82. data/lib/xrbp/websocket/socket.rb +23 -6
  83. metadata +118 -8
  84. data/lib/xrbp/network.rb +0 -6
  85. data/lib/xrbp/network/nodes.rb +0 -8
  86. data/lib/xrbp/websocket/has_plugin.rb +0 -30
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: d140a426f073971891c8e8e81f5313112c661703cebaee32719f6b04d6ca86b0
4
- data.tar.gz: 394f8602052b068b2816ddfa4e06621e7537311b26a9d8248c8eaeb44514e510
3
+ metadata.gz: a89c7310e04f3827f8252e3b4954036e6c75a703a21bb91e0a5c57e80817c495
4
+ data.tar.gz: 060e83ec60961220e4f62665a4464a7b7f9da11d96895828a814e7c218025b69
5
5
  SHA512:
6
- metadata.gz: b47922beac1ce4613e1bc4b8953bcdf9368d9fdecdef26b6c489f08ad00db2ce2be9780fa9e3fdcdf3f9b31f5912dd4c54c352e8833c002cef6e5c0c30edbafd
7
- data.tar.gz: '0833467cf31a91d158f78b9b480faaddb4447fc7bd4eeb693b21e93ac91ad9e7fdd7ede68e432d7b4755da81ac6fd46f08abaf97e27e27536eee22a34b0af503'
6
+ metadata.gz: 1cf32ec6375e44970df3612fce1eeede573d1d9501a83927de70643d207027b9e448b3a330522a2264a9b002b1e472d2334f02daadf6bf74814ab0a79c72bee5
7
+ data.tar.gz: 384f666fbfc87b752ef432aa2cbebc9b4819e92f1d627698e37e396083776e7a4aa5bb0846b0749cd1d892289cac1dc9386e205854505e6738028439ddfc596a
data/README.md CHANGED
@@ -1,7 +1,105 @@
1
- XRBP - Ruby XRP Library
2
- Copyright (C) 2019 Dev Null Productions
3
- MIT License
1
+ ### XRBP - Ruby XRP Library
2
+
3
+ <p align="center">
4
+ <img src="https://raw.githubusercontent.com/devnullprod/xrbp/master/logo.png" />
5
+ </p>
6
+
7
+
8
+ XRBP is a rubygem which provides a fault-tolerant interface to the [XRP](https://en.wikipedia.org/wiki/XRP) ledger.
9
+
10
+ With XRP you can connect to one or more [rippled](https://github.com/ripple/rippled) servers and use them to transparently read and write data to/from the XRP Ledger:
11
+
12
+ ```ruby
13
+ require 'xrbp'
14
+
15
+ ws = XRBP::WebSocket::Connection.new "wss://s1.ripple.com:443"
16
+ ws.add_plugin :autoconnect, :command_dispatcher
17
+
18
+ ws.cmd XRBP::WebSocket::Cmds::ServerInfo.new
19
+ ```
20
+
21
+ XRBP provides fully-object-oriented mechanisms to interact with the ledger:
22
+
23
+ ```ruby
24
+ ws.on :ledger do |l|
25
+ puts "Ledger received: "
26
+ puts l
27
+ end
28
+
29
+ XRBP::Model::Ledger.subscribe(:connection => ws)
30
+ ```
31
+
32
+ #### Supported Features:
33
+
34
+ Other data types besides ledgers may be syncronized:
35
+
36
+ ```ruby
37
+ puts XRBP::Model::Account.new("rvYAfWj5gh67oV6fW32ZzP3Aw4Eubs59B").info
38
+ ```
39
+
40
+ Also data from other sources, such as the [Ripple DataV2 API](https://developers.ripple.com/data-api.html)
41
+
42
+ ```ruby
43
+ connection = XRBP::WebClient::Connection.new
44
+ XRBP::Model::Validator.all(:connection => connection)
45
+ .each do |v|
46
+ puts v
47
+ end
48
+ ```
49
+
50
+ XRPB allows easy access to the following data:
51
+
52
+ - XRP ledgers, transactions, account, and objects
53
+ - Network nodes, validators, gateways
54
+ - Markets with quotes
55
+ - & more (see *examples/* for more use cases)
4
56
 
5
- ---
57
+ #### Multiple Connections
58
+
59
+ XRBP facilitates fault-tolerant applications by providing customizable strategies which to leverage multiple rippled servers in communications.
60
+
61
+ ```ruby
62
+ ws = XRBP::WebSocket::RoundRobin.new "wss://s1.ripple.com:443",
63
+ "wss://s2.ripple.com:443"
64
+
65
+ ws.add_plugin :command_dispatcher
66
+ ws.connect
67
+
68
+ puts ws.cmd(XRBP::WebSocket::Cmds::ServerInfo.new)
69
+ puts ws.cmd(XRBP::WebSocket::Cmds::ServerInfo.new)
70
+ ```
71
+
72
+ In this case the first **ServerInfo** command will be sent to *s1.ripple.com* while the second will be sent to *s2.ripple.com*.
73
+
74
+ The following demonstrates prioritized connections:
75
+
76
+ ```ruby
77
+ ws = XRBP::WebSocket::Prioritized.new "wss://s1.ripple.com:443",
78
+ "wss://s2.ripple.com:443"
79
+
80
+ ws.add_plugin :command_dispatcher, :result_parser
81
+ ws.parse_results { |res|
82
+ res["result"]["ledger"]
83
+ }
84
+ ws.connect
85
+
86
+ puts ws.cmd(XRBP::WebSocket::Cmds::Ledger.new(28327070))
87
+ ```
88
+
89
+ *s1.ripple.com* will be queried for the specified ledger. If not present *s2.ripple.com* will be queried.
90
+
91
+ #### Installation / Documentation
92
+
93
+ XRPB may be installed with the following command:
94
+
95
+ ```ruby
96
+ $ gem install xrbp
97
+ ```
98
+
99
+ Documentation is available [online](https://www.rubydoc.info/gems/xrbp)
100
+
101
+ #### License
102
+
103
+ Copyright (C) 2019 Dev Null Productions
6
104
 
7
- XRPB is a rubygem which facilitates reading and writing data to/from the XRP ledger.
105
+ Made available under the MIT License
@@ -0,0 +1,13 @@
1
+ $: << File.expand_path('../../lib', __FILE__)
2
+ require 'xrbp'
3
+
4
+ connection = XRBP::WebClient::Connection.new
5
+ connection.on :account do |acct|
6
+ puts acct
7
+ end
8
+
9
+ Signal.trap("INT") {
10
+ connection.force_quit!
11
+ }
12
+
13
+ XRBP::Model::Account.all(:connection => connection)
@@ -3,6 +3,10 @@ require 'xrbp'
3
3
 
4
4
  ws = XRBP::WebSocket::Connection.new "wss://s1.ripple.com:443"
5
5
 
6
+ ws.on :connecting do
7
+ puts "Connecting"
8
+ end
9
+
6
10
  ws.on :open do
7
11
  puts "Opened"
8
12
  end
@@ -17,4 +21,4 @@ end
17
21
 
18
22
  ws.add_plugin :autoconnect, :connection_timeout
19
23
  ws.connection_timeout = 3
20
- sleep(60)
24
+ sleep(20)
@@ -0,0 +1,7 @@
1
+ $: << File.expand_path('../../lib', __FILE__)
2
+ require 'xrbp'
3
+
4
+ connection = XRBP::WebClient::Connection.new
5
+ connection.add_plugin :autoretry
6
+ connection.url = "https://devnull.network"
7
+ puts connection.perform
@@ -0,0 +1,32 @@
1
+ $: << File.expand_path('../../lib', __FILE__)
2
+ require 'xrbp'
3
+
4
+ connection = XRBP::WebClient::Connection.new
5
+ connection.timeout = 3
6
+
7
+ Signal.trap("INT") {
8
+ connection.force_quit!
9
+ }
10
+
11
+ connection.on :precrawl do |node|
12
+ puts "Crawling: #{node.url}"
13
+ end
14
+
15
+ connection.on :crawlerr do |node|
16
+ puts "Could not Crawl: #{node.url}"
17
+ end
18
+
19
+ connection.on :postcrawl do |node|
20
+ puts "Done Crawling: #{node.url}"
21
+ end
22
+
23
+ connection.on :peers do |node, peers|
24
+ puts "#{node.url}: #{peers.size} peers"
25
+ end
26
+
27
+ connection.on :peer do |node, peer|
28
+ puts " #{peer.url}"
29
+ end
30
+
31
+ XRBP::Model::Node.crawl("wss://s1.ripple.com:51235",
32
+ :connection => connection)
@@ -0,0 +1,16 @@
1
+ $: << File.expand_path('../../../lib', __FILE__)
2
+ require 'xrbp'
3
+
4
+ include XRBP::DSL
5
+
6
+ # override endpoints
7
+ #def websocket_endpoints
8
+ # ["wss://s1.ripple.com:443", "wss://s2.ripple.com:443"]
9
+ #end
10
+
11
+ # override websocket
12
+ #def websocket
13
+ # @websocket ||= WebSocket::Prioritized.new *websocket_endpoints
14
+ #end
15
+
16
+ puts account_info("rhub8VRN55s94qWKDv6jmDy1pUykJzF3wq")
@@ -0,0 +1,7 @@
1
+ $: << File.expand_path('../../../lib', __FILE__)
2
+ require 'xrbp'
3
+
4
+ include XRBP::DSL
5
+
6
+ puts ledger
7
+ puts ledger(45918932)
@@ -0,0 +1,18 @@
1
+ $: << File.expand_path('../../../lib', __FILE__)
2
+ require 'xrbp'
3
+
4
+ include XRBP::DSL
5
+
6
+ Signal.trap("INT") {
7
+ Thread.new {
8
+ websocket.force_quit!
9
+ websocket.close!
10
+ }
11
+ }
12
+
13
+ websocket_msg do |c, msg|
14
+ puts msg
15
+ end
16
+
17
+ subscribe_to_ledgers
18
+ websocket_wait
@@ -0,0 +1,8 @@
1
+ $: << File.expand_path('../../../lib', __FILE__)
2
+ require 'xrbp'
3
+
4
+ include XRBP::DSL
5
+
6
+ validators.each { |v|
7
+ puts v["validation_public_key"] + ": " + v["domain"].to_s
8
+ }
@@ -0,0 +1,8 @@
1
+ $: << File.expand_path('../../lib', __FILE__)
2
+ require 'xrbp'
3
+
4
+ connection = XRBP::WebClient::Connection.new
5
+ XRBP::Model::Gateway.all(:connection => connection)
6
+ .each do |gw|
7
+ puts "#{gw[:id]} #{gw[:names].join(",")} (#{gw[:currencies].join(",")})"
8
+ end
@@ -0,0 +1,4 @@
1
+ $: << File.expand_path('../../lib', __FILE__)
2
+ require 'xrbp'
3
+
4
+ puts XRBP::Model::Account.latest(:connection => XRBP::WebClient::Connection.new)
@@ -7,7 +7,7 @@ ws.add_plugin :command_dispatcher
7
7
  ws.connect
8
8
 
9
9
  l = 0
10
- ws.on :message do |msg|
10
+ ws.on :message do |connection,msg|
11
11
  msg = JSON.parse(msg.data)
12
12
  next unless msg["ledger_index"] && msg["ledger_index"] > l
13
13
  l = msg["ledger_index"]
@@ -6,8 +6,8 @@ ws.add_plugin :command_dispatcher
6
6
  ws.connect
7
7
 
8
8
  i = 0
9
- ws.on :message do |msg|
10
- puts msg
9
+ ws.on :ledger do |ledger|
10
+ puts ledger
11
11
 
12
12
  i += 1
13
13
  ws.close! if i > 5
@@ -0,0 +1,13 @@
1
+ $: << File.expand_path('../../lib', __FILE__)
2
+ require 'xrbp'
3
+
4
+ connection = XRBP::WebClient::Connection.new
5
+ markets = XRBP::Model::Market.all(:connection => connection)
6
+ markets.each do |market|
7
+ puts market.inspect
8
+ end
9
+
10
+ connection = XRBP::WebClient::Connection.new
11
+ puts XRBP::Model::Market.new(:connection => connection,
12
+ :route => markets.sample[:route] + "/ohlc?periods=60")
13
+ .quotes
@@ -0,0 +1,12 @@
1
+ $: << File.expand_path('../../lib', __FILE__)
2
+ require 'xrbp'
3
+
4
+ connection = XRBP::WebClient::Connection.new
5
+ puts XRBP::Model::Account.new(:id => "rJe12wEAmGtRw44bo3jQqQUMTVFSLPewCS",
6
+ :connection => connection)
7
+ .username
8
+
9
+ puts XRBP::Model::Account.new(:id => "rfexLLNpC6dqyLagjV439EyvfqdYNHsWSH",
10
+ :connection => connection)
11
+ .username
12
+
@@ -0,0 +1,8 @@
1
+ $: << File.expand_path('../../lib', __FILE__)
2
+ require 'xrbp'
3
+
4
+ connection = XRBP::WebClient::Connection.new
5
+ XRBP::Model::Validator.all(:connection => connection)
6
+ .each do |v|
7
+ puts v
8
+ end
data/lib/xrbp.rb CHANGED
@@ -1,5 +1,9 @@
1
1
  require 'event_emitter'
2
2
 
3
+ require 'xrbp/common'
4
+ require 'xrbp/terminatable'
5
+ require 'xrbp/plugins'
3
6
  require 'xrbp/websocket'
7
+ require 'xrbp/webclient'
4
8
  require 'xrbp/model'
5
- require 'xrbp/network'
9
+ require 'xrbp/dsl'
@@ -0,0 +1,10 @@
1
+ require 'time'
2
+
3
+ module XRBP
4
+ # Genesis Ledger:
5
+ # https://wiki.ripple.com/Genesis_ledger
6
+ #
7
+ # Created on 2013-01-01
8
+ # https://data.ripple.com/v2/ledgers/32570
9
+ GENESIS_TIME = DateTime.new(2013, 1, 1, 0, 0, 0)
10
+ end # module XRBP
@@ -0,0 +1,24 @@
1
+ # Extend Hash class w/ some methods pulled from activesupport
2
+ # @private
3
+ class Hash
4
+ def except(*keys)
5
+ dup.except!(*keys)
6
+ end
7
+
8
+ def except!(*keys)
9
+ keys.each { |key| delete(key) }
10
+ self
11
+ end
12
+ end
13
+
14
+ # @private
15
+ class Queue
16
+ # Return next queue item or nil
17
+ def pop_or_nil
18
+ begin
19
+ pop(true)
20
+ rescue
21
+ nil
22
+ end
23
+ end
24
+ end
data/lib/xrbp/dsl.rb ADDED
@@ -0,0 +1,25 @@
1
+ module XRBP
2
+ # The DSL namespace can be *included* in client logic to provide
3
+ # an easy-to-use mechanism to read and write XRP data.
4
+ #
5
+ # @example Retrieve ledger, subscribe to updates
6
+ # include XRBP::DSL
7
+ #
8
+ # puts "Genesis ledger: "
9
+ # puts ledger(32570)
10
+ #
11
+ # websocket_msg do |msg|
12
+ # puts "Ledger received:"
13
+ # puts msg
14
+ # end
15
+ #
16
+ # subscribe_to_ledgers
17
+ module DSL
18
+ end # module DSL
19
+ end # module XRBP
20
+
21
+ require_relative './dsl/websocket'
22
+ require_relative './dsl/webclient'
23
+ require_relative './dsl/accounts'
24
+ require_relative './dsl/ledgers'
25
+ require_relative './dsl/validators'
@@ -0,0 +1,13 @@
1
+ module XRBP
2
+ module DSL
3
+ # Return info for the specified account id
4
+ #
5
+ # @param id [String] account id to query
6
+ # @return [Hash, nil] the account info or nil otherwise
7
+ def account_info(id)
8
+ websocket.add_plugin :autoconnect unless websocket.plugin?(:autoconnect)
9
+ websocket.add_plugin :command_dispatcher unless websocket.plugin?(:command_dispatcher)
10
+ websocket.cmd(WebSocket::Cmds::AccountInfo.new(id))
11
+ end
12
+ end # module DSL
13
+ end # module XRBP
@@ -0,0 +1,23 @@
1
+ module XRBP
2
+ module DSL
3
+ # Return ledger object for the specified id
4
+ #
5
+ # @param id [Integer] id of the ledger to query
6
+ # @return [Hash, nil] the ledger object retrieved or nil otherwise
7
+ def ledger(id=nil)
8
+ websocket.add_plugin :autoconnect unless websocket.plugin?(:autoconnect)
9
+ websocket.add_plugin :command_dispatcher unless websocket.plugin?(:command_dispatcher)
10
+ websocket.cmd(WebSocket::Cmds::Ledger.new(id))
11
+ end
12
+
13
+ # Subscribed to the ledger stream.
14
+ #
15
+ # After calling this, :ledger events will be emitted via the
16
+ # websocket connection object.
17
+ def subscribe_to_ledgers
18
+ websocket.add_plugin :autoconnect unless websocket.plugin?(:autoconnect)
19
+ websocket.add_plugin :command_dispatcher unless websocket.plugin?(:command_dispatcher)
20
+ websocket.cmd(WebSocket::Cmds::Subscribe.new(:streams => ["ledger"]))
21
+ end
22
+ end # module DSL
23
+ end # module XRBP