gm gm!!
When it comes to interacting with the external world via blockchain, it's often seen as an impossible task. That's where 0rbit comes into play. 0rbit allows you to bring ANY DATA from both the on-chain and off-chain world to the ao
process through a decentralized network of 0rbit Nodes.
0rbit is a decentralized, permissionless, and censorship-resistant oracle network built on top of Arweave using ao
. It's designed to make accessing and utilizing data on the blockchain easier and more efficient.
Your mission is to create a bot that responds to user queries for token prices, fetching the data using 0rbit's ao process and the CoinGecko API.
Meanwhile, you can meet other builders working on this quest and get help in the 0rbit’s Discord Channel!
aos installed on your system.
Some $0RBT. Learn how to get $0RBT here
Any Code Editor (VSCode, Sublime Text, etc)
Let's jump into the quest tutorial and finish each step one by one
Create a new file named 0rbit-Price-Feed.lua in your project directory.
touch 0rbit-Price-Feed.lua
local json = require("json")
_0RBIT = "BaMK1dfayo75s3q1ow6AO64UDpD9SEFbeE8xYrY2fyQ"
_0RBT_TOKEN = "BUhZLMwQ6yZHguLtJYA5lLUa9LQzLXMXRfaq9FVcPJc"
BASE_URL = "https://api.coingecko.com/api/v3/simple/price"
FEE_AMOUNT = "1000000000000" -- 1 $0RBT
Breakdown of the above code:
json
: This module is required to destruct the stringified JSON data. In this case, you interact with an API (api.coingecko.com) to fetch cryptocurrency prices. The data returned by this API is typically in JSON format. Therefore, you must parse this JSON data to extract the required information..
_0RBIT
: The processId of the 0rbit process.
_0RBT_TOKEN
: The processId of the $0RBT process.
BASE_URL
: The API URL you want to fetch data from. In this case, we are fetching cryptocurrency prices from the CoinGecko API.
FEE_AMOUNT
: The amount of $0RBT you want to send to the 0rbit process for the request.
For more detailed information on how to use the JSON module, you can visit the documentation here
TOKEN_PRICES = TOKEN_PRICES or {
BTC = {
coingecko_id = "bitcoin",
price = 0,
last_update_timestamp = 0
},
ETH = {
coingecko_id = "ethereum",
price = 0,
last_update_timestamp = 0
},
AR = {
coingecko_id = "arweave",
price = 0,
last_update_timestamp = 0
}
}
ID_TOKEN = ID_TOKEN or {
bitcoin = "BTC",
ethereum = "ETH",
arweave = "AR"
}
Breakdown of the above code:
TOKEN_PRICES
: The table stores the latest prices and other details of the tokens you want to fetch. If the table is not already defined, we initialize it with default values for Bitcoin (BTC), Ethereum (ETH), and Solana (SOL).
ID_TOKEN
: The table stores the mapping of the token IDs from the CoinGecko API to the token symbols you want to fetch.
Yayy! Keep Going and remember, every small step counts towards progress! 🚀
The getTokenPrice
function returns the token's price from the TOKEN_PRICES
table.
function getTokenPrice(msg)
local token = msg.Tags.Token
local price = TOKEN_PRICES[token].price
if price == 0 then
Handlers.utils.reply("Price not available!!!")(msg)
else
Handlers.utils.reply(tostring(price))(msg)
end
endg
Breakdown of the above code:
token
: Extract the token from the incoming message.
price
: Get the token's price from the TOKEN_PRICES
table.
If the price is 0, send a message stating that the price is not available.
If the price is not 0, send the price to the sender.
The fetchPrice
function fetches the token's price from the CoinGecko API using 0rbit's Get-Real-Data
handler.
function fetchPrice()
local url;
local token_ids = "";
for _, v in pairs(TOKEN_PRICES) do
token_ids = token_ids .. v.coingecko_id .. ","
end
url = BASE_URL .. "?ids=" .. token_ids .. "&vs_currencies=usd"
Send({
Target = _0RBT_TOKEN,
Action = "Transfer",
Recipient = _0RBIT,
Quantity = FEE_AMOUNT,
["X-Url"] = url,
["X-Action"] = "Get-Real-Data"
})
print(Colors.green .. "GET Request sent to the 0rbit process.")
end
Breakdown of the above code:
for _, v in pairs(TOKEN_PRICES)
: Iterate over the TOKEN_PRICES
table to get a token.
token_ids
: Concatenate all the tokens coingecko_id.
url
: The final URL to fetch the token prices.
Send
: Transfer 1 $0RBT to the 0rbit process and make a GET request. With this, we initiate a transfer of 1 $0RBT to the 0rbit process and execute a GET request.
Target
: This denotes the process to be pinged with the following Action
, specifically the 0rbit Token Process.
Action
: This signifies the task to be carried out, in this case, the transfer of 1 0rbit token from the current process to the 0rbit process ID.
Recipient
: This indicates the receiver of the transfer, which, in this context, is the 0rbit oracle's process.
Quantity
: This denotes the amount intended for transfer.
Additionally:
The ["X-Url"]
tag specifies the URL from which the data is to be fetched.
The ["X-Action"]
tag specifies the action to be performed.
The "X-" prefix in these tags is a convention used to denote forwarded tags. Forwarded tags refer to additional information included in a message that is passed along to subsequent messages or handlers.
The receiveData
function is called when the 0rbit process sends the fetched data to the process.
function receiveData(msg)
local res = json.decode(msg.Data)
for k, v in pairs(res) do
TOKEN_PRICES[ID_TOKEN[k]].price = tonumber(v.usd)
TOKEN_PRICES[ID_TOKEN[k]].last_update_timestamp = msg.Timestamp
end
print(Colors.green .. "Token prices updated.")
end
Breakdown of the above code:
res
: Parse the JSON data received from the 0rbit process.
for k, v in pairs(res)
: Iterate over the parsed data.
Update the token's price and last_update_timestamp in the TOKEN_PRICES
table.
Remember, just like planets in space, you're moving forward on your own journey. Keep taking steps and you'll reach your destination. 🚀
The GetTokenPrice
handler is called when a process wants to get the latest price of a token.
Handlers.add(
"GetTokenPrice",
Handlers.utils.hasMatchingTag("Action", "Get-Token-Price"),
getTokenPrice
)
Breakdown of the above code:
GetTokenPrice: The name of the handler.
Handlers.utils.hasMatchingTag("Action", "Get-Token-Price")
: Checks if the message action tag is Get-Token-Price
getTokenPrice
: The function that sends the latest price of a token from the TOKEN_PRICES
table.
This handler will fetch the token prices by sending request to 0rbit
Handlers.add(
"FetchPrice",
Handlers.utils.hasMatchingTag("Action", "Fetch-Price"),
fetchPrice
)
Breakdown of the above code:
FetchPrice: The name of the handler.
Handlers.utils.hasMatchingTag("Action", "Fetch-Price")
: Checks if the message action tag is Cron
fetchPrice
: The function that sends a GET Request to 0rbit process to fetch the token prices.
The ReceivingData
handler is called when the 0rbit process sends the fetched data to the process.
Handlers.add(
"ReceivingData",
Handlers.utils.hasMatchingTag("Action", "Receive-Response"),
receiveData
)
Breakdown of the above code:
ReceivingData: The name of the handler.
Handlers.utils.hasMatchingTag("Action", "Receive-Response")
: Checks if the message action tag is Receive-Response
receiveData
: The function that updates the token prices in the TOKEN_PRICES
table.
You're almost there! Keep up the great work, and let's tackle the next checkpoint together! 🎉
Open your terminal in the directory that contains 0rbit-Price-Feed.lua
and enter the following command:
aos 0rbitPriceFeed --cron 30-seconds
The above command will create a new process with the name 0rbitPriceFeed and set a cron job every 30 seconds.
Load your script into the process:
aos> .load 0rbit-Price-Feed.lua
Transfer some $0RBT to your processID.
aos> Send({ Target = ao.id, Action="Get-Token-Price", Tags = { Token = "AR" }})
Voila! You have successfully created a Price Feed Process. 🎉
I hope you have learned something today with this quite a long blog. Moreover, you can find the complete code here.
If you have any queries feel free to DM us on Twitter or join our Discord community to know more about 0rbit.
Happy Building!! 🧱💫🚀