How to derive stake key from wallet address?

Hi guys… I’d like to provide a little tool for our delegators where they can enter their wallet address and I can show them a history of their delegations, rewards and other related info.

I’m going to get the data from cardano-graphql API and I can see that there’s a “Delegation” object type in the schema but it only contains the stake address and not the wallet address.

I can probably just look this up in the transactions table but what if they enter a fresh/unused wallet address? How do I derive the stake address from a wallet address? I know it’s possible as I’ve seen it implemented by sites like Pooltool and CardanoScan. I just don’t know where to look in the docs…

Appreciate any help…

You could use the bech32 binary (https://github.com/input-output-hk/bech32/releases/download/v1.1.0/bech32-v1.1.0-linux64.tar.gz) to convert the address:

echo addr1qxkmuf2gqzsm5ejxm2amrwuq3pcc02cw6tttgsgqgafj46klskg5jjufdyf4znw8sjn37enwn5ge5l66qsx8srrpg3tq8du7us | ./bech32

returning:

01adbe254800a1ba6646dabbb1bb80887187ab0ed2d6b4410047532aeadf8591494b896913514dc784a71f666e9d119a7f5a040c780c614456

ending in the stake key df8591494b896913514dc784a71f666e9d119a7f5a040c780c614456

3 Likes

Thank you!

wait, sorry if this is this going to sound dumb - the data dumped by cardano-db-sync contains the stake addresses in this format:

stake1uyuqtqq84v9jrqm0asptaehtw7srrr7cnwuxyqz38a6e8scm6lcf3

So, how do we arrive in this format from the bech32 format above? Hope you’re still there @Antonio3

You can use the bech32 binary in the same way:

echo stake1uyuqtqq84v9jrqm0asptaehtw7srrr7cnwuxyqz38a6e8scm6lcf3 | ./bech32

returning: e138058007ab0b21836fec02bee6eb77a0318fd89bb86200513f7593c3

which is the stake key if you remove the e1 at the beginning.

If it’s a registered stake key, you could also look it up in the “stake_address” table in db-sync, just remove the “\xe1” part at the beginning of the hash_raw value.

PS. To convert in the other direction, run

echo e138058007ab0b21836fec02bee6eb77a0318fd89bb86200513f7593c3 | ./bech32 stake

and for addresses:

echo 01adbe254800a1ba6646dabbb1bb80887187ab0ed2d6b4410047532aeadf8591494b896913514dc784a71f666e9d119a7f5a040c780c614456 | ./bech32 addr

4 Likes

This is exactly what I need! Thank you very much! :pray:

How do you know from which position you have to substring the stake key?

Hello @nimrod,
we created this github repo which you can use in C# to read the stake key out of an address.
It’s also possible to generate that as a nuget package, for a super simple usage.

If you don’t use C#, we could also create an endpoint in our free Cardano API which allows you to do such toolings:

  • Derive Stake key from addresses
  • Translate to Hex values
  • Derive Assetname from policyId + assetname (utf8

Benefit of this would be that every programming language can call the service and does not have to write an own implementation.

Please let us know if there is still need for the API implementatio or the nuget package.

Best regards
tigrpoolcom

Hi, thanks for this… although my question has long been answered already. I’ve been using my own implementation for almost a year now - the one described by Antonio above, wrapped in JS and run in nodejs.

API solutions are now also available, notably the services provided by blockfrost.io.

But your solution is still a welcome addition to existing choices available today. Let’s keep building! :blush:

Hello nimrod, thanks for that hint.
The topic popped up recently.

God to hear that you already found a working solution.
For those who still search a solution, we added the possibility to derive stake key.
If it’s necessary to derive a stake key, e.g. for an address which was not yet used on the blockchain, you can now use this:
https://mainnet.cutymals.com/api/CardanoTools/GetStakeAddressFromAddress/addr1q9ddf0jxcr82mcsktj6wmqtevkg7jxx8sk8zk67vkr4hhnpcqkqq02ctyxpklmqzhmnwkaaqxx8a3xacvgq9z0m4j0psggr7rj?X-API-KEY=ILoveCutyMals

{
  "address": "addr1q9ddf0jxcr82mcsktj6wmqtevkg7jxx8sk8zk67vkr4hhnpcqkqq02ctyxpklmqzhmnwkaaqxx8a3xacvgq9z0m4j0psggr7rj",
  "stakeAddress": "stake1uyuqtqq84v9jrqm0asptaehtw7srrr7cnwuxyqz38a6e8scm6lcf3"
}

As the example address was already used on the network we can prove the correctness of the key:
https://mainnet.cutymals.com/odata/TransactionsOut?address=addr1q9ddf0jxcr82mcsktj6wmqtevkg7jxx8sk8zk67vkr4hhnpcqkqq02ctyxpklmqzhmnwkaaqxx8a3xacvgq9z0m4j0psggr7rj&X-API-KEY=ILoveCutyMals&%24expand=StakeAddress

"value": [
    {
      "Id": 5967985,
      "TxId": 2426186,
      "Index": 0,
      "Address": "addr1q9ddf0jxcr82mcsktj6wmqtevkg7jxx8sk8zk67vkr4hhnpcqkqq02ctyxpklmqzhmnwkaaqxx8a3xacvgq9z0m4j0psggr7rj",
      "AddressRaw": "015ad4be46c0ceade2165cb4ed81796591e918c7858e2b6bccb0eb7bcc38058007ab0b21836fec02bee6eb77a0318fd89bb86200513f7593c3",
      "PaymentCred": "5ad4be46c0ceade2165cb4ed81796591e918c7858e2b6bccb0eb7bcc",
      "StakeAddressId": 9051,
      "Value": 5115847518,
      "AddressHasScript": false,
      "DataHash": null,
      "StakeAddress": {
        "Id": 9051,
        "HashRaw": "e138058007ab0b21836fec02bee6eb77a0318fd89bb86200513f7593c3",
        "View": "stake1uyuqtqq84v9jrqm0asptaehtw7srrr7cnwuxyqz38a6e8scm6lcf3",
        "RegisteredTxId": 2426128,
        "ScriptHash": null
      }
    }
  ]

As you see the stake keys are identical.

Feel free to use the API as you need it.