CardanoSolutions / ogmios

❇️ A WebSocket JSON/RPC bridge for Cardano
https://ogmios.dev
Mozilla Public License 2.0
304 stars 90 forks source link

Ogmios capabilities #16

Closed tapiocapool closed 3 years ago

tapiocapool commented 3 years ago

Hi KtorZ! First I want to compliment you for you great work! I've been playing around using the testnet with your docker docker image + the documentation, maybe it's my fault but I couldn't manage to ask the ledger precise info inside a block. So I'll cut to the chase.

I would like to do the following:

Is this possible to achieve with this project?

Ps: I love your documentation

Thank you very much!

KtorZ commented 3 years ago

Hey @tapiocapool, thanks for the kind words.

So... I am a bit confused as I started to draft an answer to your question only to notice while testing it that.. I completely forgot to implement one of the query from the local-state-query protocol :scream: ... There's a query which given some stake credentials, returns the delegation settings and rewards associated with the given credentials. It's missing from Ogmios for some reasons! Good catch I guess :sweat_smile: ...

I'll add that one soon and bundle it with the upcoming 3.1.0 release which also introduce another missing query (though that latter one was introduced in the Mary era and I was on the roadmap for a while). Still, I'll the draft answer to your question below and will edit this message / re-post once the missing query is implemented :grimacing: ...

This answer will be valid only in 3.1.0 once the 'delegationsAndRewards' query is implemented #### Given a wallet address, obtain the bech32 stake address where this wallet is delegating its ada to About your first inquiry, you'll first need to extract the stake key hash from the address. You can do this using a library for manipulating Cardano addresses, or using the `cardano-addresses` command-line: ```console $ cardano-address address inspect <<< addr_test1qr74swevhjhczkt0mavvl5z0f3klljtqsvxf4nnw4uzg7rc2f73zc39z4s2stc60792rdgrtnh3kju90jay3d4vzn0sqh7g74n { "stake_reference": "by value", "stake_key_hash": "0a4fa22c44a2ac1505e34ff15436a06b9de36970af974916d5829be0", "address_style": "Shelley", "spending_key_hash": "fd583b2cbcaf81596fdf58cfd04f4c6dffc960830c9ace6eaf048f0f", "network_tag": 0 } ``` From there, you can use the [Local State Query protocol](https://ktorz.github.io/cardano-ogmios/mini-protocols/local-state-query/) from Ogmios and retrieve some delegation information using the `delegationsAndRewards` as follows (assuming Node.js): ```js const WebSocket = require('ws'); const client = new WebSocket("ws://localhost:1337"); const fs = require('fs'); function wsp(methodname, args) { return JSON.stringify({ type: "jsonwsp/request", version: "1.0", servicename: "ogmios", methodname, args }); } client.once('open', () => { const stakeKeyHash = "0a4fa22c44a2ac1505e34ff15436a06b9de36970af974916d5829be0"; client.send(wsp("Query", { query: { delegationsAndRewards: [stakeKeyHash] } })); }); client.on('message', function(msg) { const response = JSON.parse(msg); console.log(JSON.stringify(response, null, 4)); client.close(); }); ``` This returns the current delegation choices corresponding to the account, as well as the current rewards value.
KtorZ commented 3 years ago

The missing query has been added in e5162987924e3f94d5860216ca821babf88a2c18 ! The example from above now returns:

{
    "type": "jsonwsp/response",
    "version": "1.0",
    "servicename": "ogmios",
    "methodname": "Query",
    "result": {
        "delegations": {
            "0a4fa22c44a2ac1505e34ff15436a06b9de36970af974916d5829be0": "pool1yapr2kdt8n56fun703pcm3jyvmaxw244x6kya0d9n7h97sywr00"
        },
        "rewards": {
            "0a4fa22c44a2ac1505e34ff15436a06b9de36970af974916d5829be0": 0
        }
    },
    "reflection": null
}

:tada:

KtorZ commented 3 years ago

I am not sure that I'll keep this as such for 3.1.0 however. The schema here is a direct mapping of how the query looks like in ouroboros-network but I find it a bit awkward. It could be better to group both responses by account and have something more like:

{
    "type": "jsonwsp/response",
    "version": "1.0",
    "servicename": "ogmios",
    "methodname": "Query",
    "result": {
        "0a4fa22c44a2ac1505e34ff15436a06b9de36970af974916d5829be0": {
            "delegate": "pool1yapr2kdt8n56fun703pcm3jyvmaxw244x6kya0d9n7h97sywr00",
            "rewards": 0
        },
    },
    "reflection": null
}

This is somewhat nicer / more consistent with the query itself.

tapiocapool commented 3 years ago

Awesome!!! Thanks a lot! I'll download the new changes and try to compile them and build an image based on your docker image (if you haven't already done it) to start the testing. I love this approach of yours to query the ledger, not to diminish other projects such as cardano-db-sync, but I didn't like to have an already big ledger plus a huge postgres DB, four docker images running, etc, too much of infrastructure just to ask the ledger some simple questions, and infrastructure like this costs if you plan to put it in the cloud. Instead, this is the most feasible, reachable and easy to entry Cardano Ledger project I found out there.

I run a very small pool and I'm part of a coalition of small pools (F2LB https://www.f2lb.org) where we support each other with our delegation and technical support. Everything is being managed manually, using an excel sheet. I would like to create a tool (restful API) that we can use to check to whom of all of the participants are delegating to what pool, so the group manager can notify as fast as possible the pool that is not delegating to the right pool in the queue, without the need of manually check on cardanoscan.io verify the addresses and verify that the amount of ada the pools say they have delegated is true as they claimed. When I started experimenting with your project I got impressed, it's lightweight, fast, and easy to entry, and I would like to use it to develop this tool.

Thanks again KtorZ!

tapiocapool commented 3 years ago

I did a test using the hash16 you provided here in you message, and it worked! You also built the docker image and updated the documentation, cool!

I need to learn how to get the hash16 from addr_test1qr74swevhjhczkt0mavvl5z0f3klljtqsvxf4nnw4uzg7rc2f73zc39z4s2stc60792rdgrtnh3kju90jay3d4vzn0sqh7g74n and viceversa.

But is not the scope of this question channel. Thanks for your support.

KtorZ commented 3 years ago

@tapiocapool I love this approach of yours to query the ledger [..] I didn't like to have [..] too much of infrastructure just to ask the ledger some simple questions.

That's indeed the entire point about Ogmios. If you squint hard enough, Ogmios is "nothing more" than a set of buttons for interacting with the node / ledger. There are use-cases for other services such as cardano-db-sync or cardano-graphql; but if your application needs low-level interactions with the node, Ogmios is likely a good choice.

I've seen other attempts from the community at solving similar problem, but they took the path of writing clients library for the mini-protocols in a different language (not haskell). As far as I could see, they're just getting started and the library only support a subset of the mini-protocols.

@tapiocapool I need to learn how to get the hash16 from addr_test1qr74swevhjhczkt0mavvl5z0f3klljtqsvxf4nnw4uzg7rc2f73zc39z4s2stc60792rdgrtnh3kju90jay3d4vzn0sqh7g74n

Have a look at BIP-0173 which describes this encoding format called "bech32". There are libraries in various languages nowadays (Python, JavaScript, Go, Rust ...) for encoding and decoding binary data to and from bech32.

IOG has also developed a small command-line tool for manipulating bech32 strings.

You can then find details about the binary structure of addresses in Shelley here. You'll that addresses are mostly comprised of 3 parts, the 3rd one being optional:

Network tag | Payment credentials | Stake credentials 

The stake credentials is usually a hash of a stake key and likely what you're looking for.

tapiocapool commented 3 years ago

Wow, thanks! I'm taking a look at the BIP-0173 document right now, I need to study a lot!

@KtorZ _"I've seen other attempts from the community at solving similar problem, but they took the path of writing clients library for the mini-protocols in a different language (not haskell)."

I can't blame them, I'm not a Haskell dev, in fact I know nothing about it, I just have decent Linux skills and years of having a bad time while trying to compile stuff and in troubleshooting😂

I'll start using your reference, I'll let you know of my progress!

KtorZ commented 3 years ago

@tapiocapool is there still an issue or do you mind if I now close this ticket :no_mouth: ?

tapiocapool commented 3 years ago

Hey @KtorZ ! Today I could experiment with Ogmios (the docker version) and found out how to convert from Hash16 to Bech32 thanks to your guidelines. I'm loving this project! It's a pity that I don't know Haskell. I have many questions but I won't burden you with those question yet. So feel free to close the ticket.

KtorZ commented 3 years ago

If you don't know Haskell but do know a bit of Javascript and wants to get started with FP, start here: https://github.com/MostlyAdequate/mostly-adequate-guide