xrbp 0.0.1 → 0.1.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 (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