-
-
Notifications
You must be signed in to change notification settings - Fork 142
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add graphql provider #111
base: main
Are you sure you want to change the base?
Add graphql provider #111
Conversation
This is really cool. I was thinking about this the other day, and would love to try this PR. If you don't mind me asking here, I haven't really been able to wrap my head around how actual transaction processing works. Does the wallets handle this, much like Metamask does on ethereum with Infura, or does the providers do that? And if so, is it possible to do that via the dandelion API? Thanks! :) |
I guess I have couple more things for now @alessandrokonrad 😃, getDatum is sh*t because I can't add condition to filter records where datum bytes are null and just take one. Some time ago datum hash wasn't available in GraphQL scheme even though it was already on-chain, so I guess it just takes time to catch-up and we might get that at some point. I noted that in comments. I could write some test functions to call all methods, set results into some object, then I can deep compare between providers. But changes in graphql scheme etc might be breaking builds too frequently. So maybe there could be a limit, like 70-90% similar key and values pairs means pass? Or maybe test only protocol params from each? I can also totally ignore that, but I am fine getting the test together when I'll be debugging. |
Transaction is built off-chain. For that you need live blockchain data, specifically UTXOs: e.g. Blockfrost, cardano-db-sync with postgress, GraphQL, or alternatives. If it's on website client, you can get them also from wallet and deserialize using cardano-multiplatform-lib, but you might miss some information anyway to build the tx, so data from CIP-30 Dapp connector wallet are usually not enough for whole dapp. When you build the tx, you can submit it using freeloaderz for example, that's free and community run, load balanced. I think dandelion runs submit-api endpoint so that's fine too. If you want higher reliability, paying for blockfrost subscription might be worth it as they will resubmit txs that are dropped because of chain forks (forks are usually like 1-2 blocks, totally normal thing) in higher pay tier. Or again if it's a web client, you can use wallet endpoint to submit. You can also run all of these pieces of infrastructure, Cardano blockchain is still pretty lightweight (even thought GraphQL/db-sync are beasts, if you think about playing with that, you might wanna look into carp, scrolls, kupo or maybe even ogmios ) @GGAlanSmithee |
}; | ||
} | ||
|
||
async getCurrentSlot(): Promise<Slot> { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This endpoint is not necessary and not a part of the provider interface anymore. The current slot can be calculated off-chain.
txHash: r.txHash, | ||
outputIndex: r.index, | ||
assets: (() => { | ||
const a: Assets = {}; | ||
r.tokens.forEach((token: { | ||
asset: { | ||
policyId: string; | ||
assetName: string; | ||
}; | ||
quantity: string; | ||
}) => { | ||
a[token.asset.policyId + token.asset.assetName] = BigInt( | ||
token.quantity, | ||
); | ||
}); | ||
a["lovelace"] = BigInt(r.value); | ||
return a; | ||
})(), | ||
address, | ||
datumHash: r.datum?.hash, | ||
datum: r.datum?.bytes, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
scriptRef is missing :)
In general the Does the GraphQL API have insights into the current state of things? Or is it only historic data? |
@zachyking tyvm for taking your time, very valuable! |
What do you mean by that?
So the datum is not directly available to query even tho it was just exposed by a tx? |
GraphQL API has insights to current state sometimes, querying utxos directly seem to return only unspent ones. I tried withdrawing my staking rewards, and I see the same records in case of Delegation. I'll try again later, maybe there is just some longer delay, but if not, I can just get both delegation and withdrawals to calculate currently available rewards. |
There is a datum object on utxos, which has bytes and hash. I can have |
@zachyking so you think it could be a problem because you also query other utxos where datum is not set and you can't filter them out? But the query you suggested there seems sufficient enough I think. Maybe it's not really a problem with all these outputs, but I'm not a graphql user really. What happens if you do Maybe you want to extend the query to also redeemers and collateralOutputs, just to really capture all datums: query queryDatum {
transactions(
limit: 1
where: {
outputs: {
datum: {
hash: {
_eq: "923918e403bf43c34b4ef6b48eb2ee04babed17320d8d1b9ff9ad086e86f44ec"
}
}
}
}
) {
outputs {
datum {
bytes
}
}
}
redeemers(
limit: 1
where: {
datum: {
hash: {
_eq: "923918e403bf43c34b4ef6b48eb2ee04babed17320d8d1b9ff9ad086e86f44ec"
}
}
}
) {
datum {
bytes
}
}
collateralOutputs(
limit: 1
where: {
datum: {
hash: {
_eq: "923918e403bf43c34b4ef6b48eb2ee04babed17320d8d1b9ff9ad086e86f44ec"
}
}
}
) {
datum {
bytes
}
}
} And it returns this: {
"data": {
"transactions": [
{
"outputs": [
{
"datum": null
},
{
"datum": {
"bytes": "d87980"
}
},
{
"datum": {
"bytes": "d87980"
}
}
]
}
],
"redeemers": [
{
"datum": {
"bytes": "d87980"
}
}
],
"collateralOutputs": []
}
} And then locally in lucid you try to find in any of these a datum where bytes is defined. EDIT: |
Extending to redeemers and collateral outputs is definitely good idea. I don't think limit=1 should be used in transaction query until condition Hash |
draft, I have no idea if it works, needs some debug, but somebody might want to get to it sooner
Allows using Cardano GraphQL instance as data provider in combination with Cardano submit API for submitting txs.
(e.g. dandelion.link for free GraphQL by the community and https://www.freeloaderz.io/ for free load balanced submit api from SPOs)
I have a question though @alessandrokonrad, I am not sure about delegation endpoint, I can get list of records with poolId and reward, so I just return first record rn. Should I count those reward amounts together from all records and return sum with latest poolId?