14 KiB
RabbitMQ Peatio Event API
Overview of RabbitMQ details
Peatio submits all events into three exchanges depending on event category (read next).
The exchange name consists of three parts:
-
application name, like
peatio,barong. -
fixed keyword
events. -
category of event, like
system(generic system event),model(the attributes of some record were updated),market(trading events).
The routing key looks like deposit.updated, btcusd.new_order.
The event name matches the routing key but with event category appended at the beginning, like model.deposit.updated, market.btcusd.new_order.
Overview of RabbitMQ message
Each produced message in Event API is JWT (complete format).
This is very similar to Management API.
The example below demonstrates both generation and verification of JWT:
require "jwt-multisig"
require "securerandom"
jwt_payload = {
iss: "peatio",
jti: SecureRandom.uuid,
iat: Time.now.to_i,
exp: Time.now.to_i + 60,
event: {}
}
require "openssl"
private_key = OpenSSL::PKey::RSA.generate(2048)
public_key = private_key.public_key
generated_jwt = JWT::Multisig.generate_jwt(jwt_payload, { peatio: private_key }, { peatio: "RS256" })
Kernel.puts "GENERATED JWT", generated_jwt.to_json, "\n"
verification_result = JWT::Multisig.verify_jwt generated_jwt.deep_stringify_keys, \
{ peatio: public_key }, { verify_iss: true, iss: "peatio", verify_jti: true }
decoded_jwt_payload = verification_result[:payload]
Kernel.puts "MATCH AFTER VERIFICATION: #{jwt_payload == decoded_jwt_payload}."
The RabbitMQ message is stored in JWT field called event.
Overview of Event API message
The typical event looks like (JSON):
event: {
name: "model.deposit.updated",
foo: "...",
bar: "...",
qux: "..."
}
The field event[:name] contains event name (same as routing key).
The fields foo, bar, qux (just for example) are fields which carry useful information.
Format of model.deposit.created event
event: {
name: "model.deposit.created",
record: {
tid: "TID9493F6CD41",
user: {
uid: "ID092B2AF8E87",
email: "john@doe.com"
},
uid: "ID092B2AF8E87",
currency: "btc",
amount: "0.0855",
state: "submitted",
created_at: "2018-04-12T17:16:06+03:00",
updated_at: "2018-04-12T17:16:06+03:00",
completed_at: nil,
blockchain_address: "n1Ytj6Hy57YpfueA2vtmnwJQs583bpYn7W",
blockchain_txid: "c37ae1677c4c989dbde9ac22be1f3ff3ac67ed24732a9fa8c9258fdff0232d72",
blockchain_confirmations: 1
}
}
| Field | Description |
|---|---|
record |
The up-to-date deposit attributes. |
Format of model.deposit.updated event
event: {
name: "model.deposit.updated",
record: {
tid: "TID9493F6CD41",
user: {
uid: "ID092B2AF8E87",
email: "john@doe.com"
},
uid: "ID092B2AF8E87",
currency: "btc",
amount: "0.0855",
state: "accepted",
created_at: "2018-04-12T17:16:06+03:00",
updated_at: "2018-04-12T18:46:57+03:00",
completed_at: "2018-04-12T18:46:57+03:00",
blockchain_address: "n1Ytj6Hy57YpfueA2vtmnwJQs583bpYn7W",
blockchain_txid: "c37ae1677c4c989dbde9ac22be1f3ff3ac67ed24732a9fa8c9258fdff0232d72",
blockchain_confirmations: 7
},
changes: {
state: "submitted",
completed_at: nil,
blockchain_confirmations: 1,
updated_at: "2018-04-12T17:16:06+03:00"
}
}
| Field | Description |
|---|---|
record |
The up-to-date deposit attributes. |
changes |
The changed deposit attributes and their values. |
Format of model.withdraw.created event
event: {
name: "model.withdraw.created",
record: {
tid: "TID892F29F094",
user: {
uid: "ID092B2AF8E87",
email: "john@doe.com"
},
uid: "ID092B2AF8E87",
rid: "0xdA35deE8EDDeAA556e4c26268463e26FB91ff74f",
currency: "eth",
amount: "4.5485",
fee: "0.0015",
state: "prepared",
created_at: "2018-04-12T18:52:16+03:00",
updated_at: "2018-04-12T18:52:16+03:00",
completed_at: nil,
blockchain_txid: nil
}
}
| Field | Description |
|---|---|
record |
The up-to-date withdraw attributes. |
Format of model.withdraw.updated event
event: {
name: "model.withdraw.updated",
record: {
tid: "TID892F29F094",
user: {
uid: "ID092B2AF8E87",
email: "john@doe.com"
},
uid: "ID092B2AF8E87",
rid: "0xdA35deE8EDDeAA556e4c26268463e26FB91ff74f",
currency: "eth",
amount: "4.5485",
fee: "0.0015",
state: "succeed",
created_at: "2018-04-12T18:52:16+03:00",
updated_at: "2018-04-12T18:56:23+03:00",
completed_at: "2018-04-12T18:56:23+03:00",
blockchain_txid: "0x9c34d1750e225a95938f9884e857ab6f55eedda43b159d13abf773fe6a916164"
},
changes: {
state: "processing",
updated_at: "2018-04-12T18:55:39+03:00",
completed_at: "2018-04-12T18:55:39+03:00",
blockchain_txid: nil
}
}
| Field | Description |
|---|---|
record |
The up-to-date withdraw attributes. |
changes |
The changed withdraw attributes and their values. |
Format of model.account.created event
event: {
name: "model.account.created",
record: {
id: "1",
member_id: "2",
currency_id: "btc",
balance: "0",
locked: "0",
created_at: "2018-04-12T17:16:06+03:00",
updated_at: "2018-04-12T17:16:06+03:00",
}
}
| Field | Description |
|---|---|
record |
The up-to-date account attributes. |
Format of model.account.updated event
event: {
name: "model.account.updated",
record: {
id: "1",
member_id: "2",
currency_id: "btc",
balance: "1",
locked: "0",
created_at: "2018-04-12T17:16:06+03:00",
updated_at: "2018-04-12T17:17:06+03:00",
},
changes: {
balance: "0",
updated_at: "2018-04-12T17:16:06+03:00"
}
}
| Field | Description |
|---|---|
record |
The up-to-date account attributes. |
changes |
The changed account attributes and their values. |
Format of system.low_hot_wallet_balance event
event: {
name: "system.system.low_hot_wallet_balance",
currency: "btc",
balance: "2.82480099"
}
| Field | Description |
|---|---|
currency |
The currency code. |
balance |
The up-to-date balance. |
Format of market.btcusd.order_created event
Buy 14 BTC for 0.42 USD (0.03 USD per BTC).
event: {
name: "market.btcusd.order_created",
market: "btcusd",
type: "buy",
trader_uid: "ID022H2NF6E87",
income_unit: "btc",
income_fee_type: "relative",
income_fee_value: "0.0015",
outcome_unit: "usd",
outcome_fee_type: "relative",
outcome_fee_value: "0.0",
initial_income_amount: "14.0",
current_income_amount: "14.0",
initial_outcome_amount: "0.42",
current_outcome_amount: "0.42",
strategy: "limit",
price: "0.03",
state: "open",
trades_count: 0,
created_at: "2018-05-07T02:12:28Z"
}
Format of market.btcusd.order_updated event
Sell 100 BTC for 3 USD (0.03 USD per BTC).
event: {
name: "market.btcusd.order_updated",
market: "btcusd",
type: "sell",
trader_uid: "ID092B2AF8E87",
income_unit: "usd",
income_fee_type: "relative",
income_fee_value: "0.0015",
outcome_unit: "btc",
outcome_fee_type: "relative",
outcome_fee_value: "0.0",
initial_income_amount: "3.0",
current_income_amount: "2.4",
previous_income_amount: "3.0",
initial_outcome_amount: "100.0",
current_outcome_amount: "80.0",
previous_outcome_amount: "100.0",
strategy: "limit",
price: "0.03",
state: "open",
trades_count: 1,
created_at: "2018-05-07T02:12:28Z",
updated_at: "2018-05-08T10:13:13Z"
}
Format of market.btcusd.order_canceled event
Sell 100 BTC for 3 USD (0.03 USD per BTC).
event: {
name: "market.btcusd.order_canceled",
market: "btcusd",
type: "sell",
trader_uid: "ID092B2AF8E87",
income_unit: "usd",
income_fee_type: "relative",
income_fee_value: "0.0015",
outcome_unit: "btc",
outcome_fee_type: "relative",
outcome_fee_value: "0.0",
initial_income_amount: "3.0",
current_income_amount: "3.0",
initial_outcome_amount: "100.0",
current_outcome_amount: "100.0",
strategy: "limit",
price: "0.03",
state: "canceled",
trades_count: 0,
created_at: "2018-05-07T02:12:28Z",
canceled_at: "2018-05-08T10:13:13Z"
}
Format of market.btcusd.order_completed event
Sell 100 BTC for 3 USD (0.03 USD per BTC).
event: {
name: "market.btcusd.order_completed",
market: "btcusd",
type: "sell",
trader_uid: "ID092B2AF8E87",
income_unit: "usd",
income_fee_type: "relative",
income_fee_value: "0.0015",
outcome_unit: "btc",
outcome_fee_type: "relative",
outcome_fee_value: "0.0",
initial_income_amount: "3.0",
current_income_amount: "0.0",
previous_income_amount: "3.0",
initial_outcome_amount: "100.0",
current_outcome_amount: "0.0",
previous_outcome_amount: "100.0",
strategy: "limit",
price: "0.03",
state: "completed",
trades_count: 1,
created_at: "2018-05-07T02:12:28Z",
completed_at: "2018-05-07T17:32:09Z"
}
Format of market.btcusd.trade_completed event
event: {
name: "market.btcusd.trade_completed",
market: "btcusd",
price: "0.03",
buyer_uid: "ID022H2NF6E87",
buyer_income_unit: "btc",
buyer_income_amount: "14",
buyer_income_fee: "0.021",
buyer_outcome_unit: "usd",
buyer_outcome_amount: "0.42",
buyer_outcome_fee: "0.0",
seller_uid: "ID092B2AF8E87",
seller_income_unit: "usd",
seller_income_amount: "0.42",
seller_income_fee: "0.00063",
seller_outcome_unit: "btc",
seller_outcome_amount: "14.0",
seller_outcome_fee: "0.0",
completed_at: "2018-05-07T17:32:09Z"
}
Producing events using Ruby
require "bunny"
def generate_jwt(jwt_payload)
Kernel.abort "Please, see «Overview of RabbitMQ message» for implementation guide."
end
Bunny.run host: "localhost", port: 5672, username: "guest", password: "guest" do |session|
channel = session.channel
exchange = channel.direct("peatio.events.model")
jwt_payload = {
iss: "peatio",
jti: SecureRandom.uuid,
iat: Time.now.to_i,
exp: Time.now.to_i + 60,
event: {
name: "model.deposit.created",
record: {
tid: "TID9493F6CD41",
user: {
uid: "ID092B2AF8E87",
email: "john@doe.com"
},
uid: "ID092B2AF8E87",
currency: "btc",
amount: "0.0855",
state: "submitted",
created_at: "2018-04-12T17:16:06+03:00",
updated_at: "2018-04-12T17:16:06+03:00",
completed_at: nil,
blockchain_address: "n1Ytj6Hy57YpfueA2vtmnwJQs583bpYn7W",
blockchain_txid: "c37ae1677c4c989dbde9ac22be1f3ff3ac67ed24732a9fa8c9258fdff0232d72",
blockchain_confirmations: 1
}
}
}
exchange.publish(generate_jwt(jwt_payload), routing_key: "deposit.created")
end
IMPORTANT: Don't forget to implement the logic for JWT exception handling!
Producing events using rabbitmqadmin
rabbitmqadmin publish routing_key=deposit.created payload=JWT exchange=peatio.events.model
Don't forget to pass environment variable JWT.
Consuming events using Ruby
require "bunny"
def verify_jwt(jwt_payload)
Kernel.abort "Please, see «Overview of RabbitMQ message» for implementation guide."
end
Bunny.run host: "localhost", port: 5672, username: "guest", password: "guest" do |session|
channel = session.channel
exchange = channel.direct("peatio.events.model")
queue = channel.queue("", auto_delete: true, durable: true, exclusive: true)
.bind(exchange, routing_key: "deposit.updated")
queue.subscribe manual_ack: true, block: true do |delivery_info, metadata, payload|
Kernel.puts verify_jwt(JSON.parse(payload)).fetch(:event)
channel.ack(delivery_info.delivery_tag)
rescue => e
channel.nack(delivery_info.delivery_tag, false, true)
end
end
IMPORTANT: Don't forget to implement the logic for JWT exception handling!