Skip to content

Instantly share code, notes, and snippets.

@ysv
Created November 4, 2020 15:20
Show Gist options
  • Select an option

  • Save ysv/a19214d452c80b542660577f610bb63d to your computer and use it in GitHub Desktop.

Select an option

Save ysv/a19214d452c80b542660577f610bb63d to your computer and use it in GitHub Desktop.
require "singleton"
require "faraday"
require "better-faraday"
require "execjs"
require "pry-byebug"
require "bigdecimal"
require "bigdecimal/util"
require "hash-tweaks"
GENESIS_ADDRESS = "rBVi9Lgh5ceGuvKvDtJRhHHN7ASaLaxBja"
SENDER_ADDRESS = "rGCzSxYdgcWGNWGmprdMxfC9oexaYUhAtD"
SENDER_SECRET = "snPCeTZJHsQiFg4smcnfP52CgFM4b"
# @options should include :asset_id.
def xrp_issued_tx(destination, amount, options = {})
sequence_validated = json_rpc(:account_info, [account: SENDER_ADDRESS, strict: true, ledger_index: :validated]).dig(:result, :account_data, :Sequence)
sequence_current = json_rpc(:account_info, [account: SENDER_ADDRESS, strict: true, ledger_index: :current]).dig(:result, :account_data, :Sequence)
ledger = json_rpc(:ledger, [ledger_index: :validated]).dig(:result, :ledger_index)
tx = {
TransactionType: :Payment,
Account: SENDER_ADDRESS,
Destination: destination.sub(/\?dt=\d+\z/, ""),
DestinationTag: destination.scan(/\?dt=(0|[1-9]\d*)\z/).flatten[0]&.to_i,
SendMax: {
currency: options.fetch(:asset_id),
issuer: GENESIS_ADDRESS,
value: amount.to_s("F").sub(/\.0+\z/, "")
},
Amount: {
currency: options.fetch(:asset_id),
issuer: GENESIS_ADDRESS,
value: (amount * "0.9999".to_d).floor(15).to_s("F").sub(/\.0+\z/, "")
},
Fee: "25",
Sequence: [sequence_validated, sequence_current].max,
LastLedgerSequence: ledger + 10
}.compact
snippet = <<-JAVASCRIPT
new ripple.RippleAPI().sign('#{tx.to_json}', '#{SENDER_SECRET}')
JAVASCRIPT
signed_tx = RippleJS.call(snippet).deep_transform_keys { |k| k.to_s.underscore.to_sym }[:signed_transaction]
data = json_rpc(:submit, [tx_blob: signed_tx])
result = data.dig(:result, :engine_result)
return nil if %w[tefPAST_SEQ tecDST_TAG_NEEDED].include?(result)
if %w[tesSUCCESS terQUEUED].include?(result) && data.dig(:result, :status) == "success" && !data.dig(:result, :tx_json, :hash).nil?
data.dig(:result, :tx_json, :hash)
else
nil
end
end
def json_rpc(method, params = [])
response = connection.post \
"/",
{ jsonrpc: "2.0", id: 1, method: method, params: params }.to_json,
{ "Accept" => "application/json", "Content-Type" => "application/json" }
response.ok!
JSON.parse(response.body).deep_symbolize_keys
end
def connection
json_rpc_endpoint = "https://s.altnet.rippletest.net:51234"
Faraday.new(json_rpc_endpoint)
end
class RippleJS
include Singleton
def initialize
<<-JAVASCRIPT.tap { |js| @js = ExecJS.compile(js) }
#{File.read(File.join(__dir__, "lodash.js"))}
#{File.read(File.join(__dir__, "ripple-lib.js"))}
JAVASCRIPT
end
def call(snippet)
@js.eval(snippet)
end
class << self
def call(snippet)
instance.call(snippet)
end
end
end
pp xrp_issued_tx("r4fCw4QyjNdXQF1rYUo71EbZ13Gq8TwNuS?dt=1195", 1.to_d, {asset_id: '786E617375733030373234663130313230303031'})
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment