# Query\_blocks \<-- ICP ledger Candid 🙌

**URL:** <https://forum.dfinity.org/t/query-blocks-icp-ledger-candid/11948>\
**Category:** Language Support\
**Tags:** Motoko\
**Created:** [April 6, 2022, 12:59am UTC](https://forum.dfinity.org/t/query-blocks-icp-ledger-candid/11948 "2022-04-06T00:59:52Z")\
**Posts on this page:** 16\
**Page:** 1

<div class="post-metadata">

**Author:** ![skilesare](https://sea1.discourse-cdn.com/flex023/user_avatar/forum.dfinity.org/skilesare/32/5609_2.png) [@skilesare](https://forum.dfinity.org/u/skilesare)\
**Post date:** [April 6, 2022, 12:59am UTC](https://forum.dfinity.org/t/query-blocks-icp-ledger-candid/11948/1 "2022-04-06T00:59:52Z")

</div>

query\_blocks for the ICP ledger canister works. It even gives you an index for archive canisters if the record is too old.

Looks like this was added to the repo March 3rd. No idea when it went live on mainnet, but it is there now.

DFINITY folks, you’ve got to shout this kind of stuff from the rooftops. This feature drastically reduces complexity and basically enables all kinds of new functionality. THANK YOU!!!

If I missed the announcement for this please point me to it, I don’t want to miss stuff like this again.

> <https://github.com/dfinity/ic/blob/master/rs/rosetta-api/ledger_canister/ledger.did>

To query the main ledger(last couple thousand blocks or so, if not in range you get the index:

```auto
dfx canister --network ic call ryjl3-tyaaa-aaaaa-aaaba-cai query_blocks '(record {start = 1: nat64; length = 2:nat64})'

```

To query the index:

```auto
dfx canister --network ic call qjdve-lqaaa-aaaaa-aaaeq-cai get_blocks '(record {start = 1: nat64; length = 2:nat64})'

```

---

<div class="post-metadata">

**Author:** ![Jesse](https://sea1.discourse-cdn.com/flex023/user_avatar/forum.dfinity.org/jesse/32/37836_2.png) [@Jesse](https://forum.dfinity.org/u/Jesse)\
**Post date:** [May 3, 2022, 2:44am UTC](https://forum.dfinity.org/t/query-blocks-icp-ledger-candid/11948/2 "2022-05-03T02:44:49Z")

</div>

I’m using the `get_blocks()` method and everything functions without any errors, but I’m only getting empty arrays back, no blocks are being returned. what am I missing? Below is the relevant code.

how I instantiate the ledger index canister:

```auto
private let ledgerIndex : Ledger.InterfaceIndex = actor("qjdve-lqaaa-aaaaa-aaaeq-cai");

```

Where I call the function:

```auto
let tipOfChainIndex = await tipOfChainDetails();
let startIndex : Nat64 = tipOfChainIndex.0 - 1000;
let queryLength : Nat64 = 999;
let queryResult = await ledgerIndex.get_blocks({
    start = startIndex;
    length = queryLength;
});

```

---

<div class="post-metadata">

**Author:** ![skilesare](https://sea1.discourse-cdn.com/flex023/user_avatar/forum.dfinity.org/skilesare/32/5609_2.png) [@skilesare](https://forum.dfinity.org/u/skilesare)\
**Post date:** [May 3, 2022, 3:12am UTC](https://forum.dfinity.org/t/query-blocks-icp-ledger-candid/11948/3 "2022-05-03T03:12:48Z")

</div>

On the main node it is query\_blocks. On the archive nodes it is get\_blocks. Make sure you have your did file right, AccountIdentfiers are blobs in these structures.

---

<div class="post-metadata">

**Author:** ![Jesse](https://sea1.discourse-cdn.com/flex023/user_avatar/forum.dfinity.org/jesse/32/37836_2.png) [@Jesse](https://forum.dfinity.org/u/Jesse)\
**Post date:** [May 3, 2022, 3:40am UTC](https://forum.dfinity.org/t/query-blocks-icp-ledger-candid/11948/4 "2022-05-03T03:40:58Z")

</div>

Are you able to answer any of the following:

how far back on the blockchain we can query?

What’s the maximum range?

How does one go about retrieving the transaction history of a particle principal?

---

<div class="post-metadata">

**Author:** ![skilesare](https://sea1.discourse-cdn.com/flex023/user_avatar/forum.dfinity.org/skilesare/32/5609_2.png) [@skilesare](https://forum.dfinity.org/u/skilesare)\
**Post date:** [May 3, 2022, 3:49am UTC](https://forum.dfinity.org/t/query-blocks-icp-ledger-candid/11948/5 "2022-05-03T03:49:27Z")

</div>

Up to 2000 blocks on the main node, all the way back on the archive.

The maximum size of a response is 2MB, sonic it bigger than that you’ll have to chunk.

Scan the chain and index it so you don’t have to donut a second time. I’d love for dfinity to offer some meta data Canisters for stuff like this. I think the Rosetta server lets you do those queries, but your canister can’t get to them.

---

<div class="post-metadata">

**Author:** ![Dustin](https://avatars.discourse-cdn.com/v4/letter/d/5daacb/32.png) [@Dustin](https://forum.dfinity.org/u/Dustin)\
**Post date:** [May 3, 2022, 2:57pm UTC](https://forum.dfinity.org/t/query-blocks-icp-ledger-candid/11948/6 "2022-05-03T14:57:48Z")

</div>

When I try to use the [web Candid UI](https://a4gq6-oaaaa-aaaab-qaa4q-cai.raw.ic0.app/?id=qjdve-lqaaa-aaaaa-aaaeq-cai) to interact with the ledger archive canister, I get an error that I can’t resolve.

If I enter for example 1 at start and 2 at length (like you did in the example above), I get the response `Not an option type`.

What am I missing here?

---

<div class="post-metadata">

**Author:** ![skilesare](https://sea1.discourse-cdn.com/flex023/user_avatar/forum.dfinity.org/skilesare/32/5609_2.png) [@skilesare](https://forum.dfinity.org/u/skilesare)\
**Post date:** [May 3, 2022, 3:57pm UTC](https://forum.dfinity.org/t/query-blocks-icp-ledger-candid/11948/7 "2022-05-03T15:57:59Z")

</div>

I’m not sure where this candid came from, but in the latest version the to and from is a blob an and not a [Nat8]

---

<div class="post-metadata">

**Author:** ![Ori](https://avatars.discourse-cdn.com/v4/letter/o/ecae2f/32.png) [@Ori](https://forum.dfinity.org/u/Ori)\
**Post date:** [May 3, 2022, 5:51pm UTC](https://forum.dfinity.org/t/query-blocks-icp-ledger-candid/11948/8 "2022-05-03T17:51:35Z")

</div>

Try this one: [https://a4gq6-oaaaa-aaaab-qaa4q-cai.raw.ic0.app/?id=ryjl3-tyaaa-aaaaa-aaaba-cai](https://a4gq6-oaaaa-aaaab-qaa4q-cai.raw.ic0.app/?id=ryjl3-tyaaa-aaaaa-aaaba-cai)

---

<div class="post-metadata">

**Author:** ![Dustin](https://avatars.discourse-cdn.com/v4/letter/d/5daacb/32.png) [@Dustin](https://forum.dfinity.org/u/Dustin)\
**Post date:** [May 3, 2022, 10:33pm UTC](https://forum.dfinity.org/t/query-blocks-icp-ledger-candid/11948/9 "2022-05-03T22:33:31Z")

</div>

Thank you. That’s the ledger canister, it doesn’t store all the blocks but only the latest ones. The one that I was referring to is the archive which stores all ledger transactions. Did you try the candid UI and get the same error? I’m not sure what I’m doing wrong when calling the candid directly with the candid UI.

In any case, I get the same error when calling the query\_blocks method on the ledger canister. It tells me the error `Not an option type`.

---

<div class="post-metadata">

**Author:** ![skilesare](https://sea1.discourse-cdn.com/flex023/user_avatar/forum.dfinity.org/skilesare/32/5609_2.png) [@skilesare](https://forum.dfinity.org/u/skilesare)\
**Post date:** [May 4, 2022, 12:05am UTC](https://forum.dfinity.org/t/query-blocks-icp-ledger-candid/11948/10 "2022-05-04T00:05:10Z")

</div>

Does dfx work? ………………

---

<div class="post-metadata">

**Author:** ![Dustin](https://avatars.discourse-cdn.com/v4/letter/d/5daacb/32.png) [@Dustin](https://forum.dfinity.org/u/Dustin)\
**Post date:** [May 4, 2022, 7:21am UTC](https://forum.dfinity.org/t/query-blocks-icp-ledger-candid/11948/11 "2022-05-04T07:21:54Z")

</div>

Yes, dfx works. That’s why I’m a bit lost about what may be wrong here.

I’m trying query the transaction history via an httpAgent in typescript. See a small example below

```auto
import {Actor, HttpAgent} from '@dfinity/agent';

const {idlFactory: ledgerIDL} = require('../lib/canisters/ledger.did.js');
const {idlFactory: archiveIDL} = require('../lib/canisters/ledger-archive.did.js');

const agent = new HttpAgent({host: 'https://ic0.app'});
const ledger = Actor.createActor(ledgerIDL, {
  agent,
  canisterId: 'ryjl3-tyaaa-aaaaa-aaaba-cai',
});
const ledgerArchive = Actor.createActor(archiveIDL, {
  agent,
  canisterId: 'qjdve-lqaaa-aaaaa-aaaeq-cai',
});

const queryBlocks = async (start: bigint, length: bigint) => {
  const GetBlocksArgs = {
    start: start,
    length: length,
  };
  const res: any = await ledger.query_blocks(GetBlocksArgs);
  console.log(res);
};

const queryArchiveBlocks = async (start: bigint, length: bigint) => {
  const GetBlocksArgs = {
    start: start,
    length: length,
  };
  const res: any = await ledgerArchive.get_blocks(GetBlocksArgs);
  console.log(res);
};

queryBlocks(20000n, 2n); // returns an object with no blocks
queryArchiveBlocks(20000n, 2n); // returns the error "Not an option type"

```

The candid of the ledger and archive canisters are taken from here

- [Ledger canister](https://k7gat-daaaa-aaaae-qaahq-cai.ic0.app/canister/ryjl3-tyaaa-aaaaa-aaaba-cai)
- [Archive canister](https://k7gat-daaaa-aaaae-qaahq-cai.ic0.app/canister/qjdve-lqaaa-aaaaa-aaaeq-cai)

Do you see any issue with the code?

---

<div class="post-metadata">

**Author:** ![Dustin](https://avatars.discourse-cdn.com/v4/letter/d/5daacb/32.png) [@Dustin](https://forum.dfinity.org/u/Dustin)\
**Post date:** [May 9, 2022, 8:51am UTC](https://forum.dfinity.org/t/query-blocks-icp-ledger-candid/11948/12 "2022-05-09T08:51:10Z")

</div>

Is it possible that the candid of the ledger canister on [canlista](https://k7gat-daaaa-aaaae-qaahq-cai.ic0.app/canister/ryjl3-tyaaa-aaaaa-aaaba-cai) and [icscan](https://test.icscan.io/canister/ryjl3-tyaaa-aaaaa-aaaba-cai) are not correct? Does anyone know the latest version?

---

<div class="post-metadata">

**Author:** ![skilesare](https://sea1.discourse-cdn.com/flex023/user_avatar/forum.dfinity.org/skilesare/32/5609_2.png) [@skilesare](https://forum.dfinity.org/u/skilesare)\
**Post date:** [May 11, 2022, 1:20am UTC](https://forum.dfinity.org/t/query-blocks-icp-ledger-candid/11948/13 "2022-05-11T01:20:44Z")

</div>

I got mine from the latest version of the ic repo. [GitHub.com/dfinity/ic/rs/Rosetta-api/somewhereinthere](http://GitHub.com/dfinity/ic/rs/Rosetta-api/somewhereinthere).

---

<div class="post-metadata">

**Author:** ![mbeekman](https://sea1.discourse-cdn.com/flex023/user_avatar/forum.dfinity.org/mbeekman/32/2675_2.png) [@mbeekman](https://forum.dfinity.org/u/mbeekman)\
**Post date:** [May 26, 2022, 1:05am UTC](https://forum.dfinity.org/t/query-blocks-icp-ledger-candid/11948/14 "2022-05-26T01:05:38Z")

</div>

Hello All … found the candid on the ledger canister while trying to verify a block to/from/amount for payment verification … found @quint ’ s comments and his example canister in github and while I was learning what he did I noticed the one you found (query\_blocks) and was off the races … now I am coming back and trying to add a link to the UI to the Internet Computer Dashboard … i.e.:

```auto
https://dashboard.internetcomputer.org/transaction/1a425cde1877bcd72a8be33190c9c395aa2693e42e47823197da59ed1c6d6651

```

that’s a random transaction, but if I have the block can anyone confirm how to get the “Hash” to build this URL … is the “Hash” the “parent\_hash” in the “Block” type?:

```auto

type Block = record {
    parent_hash : opt blob;
    transaction : Transaction;
    timestamp : TimeStamp;
};

```

any confirmation that is correct and/or example converting the blob into hash would be wicked. … or if I am missing something let me know as well, might be an obvious thing …

```auto

```

---

<div class="post-metadata">

**Author:** ![georgemourginakis](https://sea1.discourse-cdn.com/flex023/user_avatar/forum.dfinity.org/georgemourginakis/32/8855_2.png) [@georgemourginakis](https://forum.dfinity.org/u/georgemourginakis)\
**Post date:** [April 13, 2023, 5:46am UTC](https://forum.dfinity.org/t/query-blocks-icp-ledger-candid/11948/15 "2023-04-13T05:46:16Z")

</div>

Running into the same issue

I can do:

```bash
$ dfx canister --network ic call "qjdve-lqaaa-aaaaa-aaaeq-cai" get_blocks '(record {start = 4 : nat64; length = 20 : nat64} )'

```

But I can’t do:

```ts
const ARCHIVE_CANISTER_ID = 'qjdve-lqaaa-aaaaa-aaaeq-cai';

const archiveCanister: ActorSubclass<_SERVICE> = Actor.createActor(idlFactory, {
    agent: new HttpAgent({ host: "https://ic0.app" }),
    canisterId: Principal.fromText(ARCHIVE_CANISTER_ID),
});
const result = await archiveCanister.get_blocks({start: 4n, length: 20n});
console.log(result);

```

```plaintext
Error: Not an option type
 ❯ OptClass.decodeValue node_modules/@dfinity/candid/src/idl.ts:920:13
 ❯ RecordClass.decodeValue node_modules/@dfinity/candid/src/idl.ts:1038:35
 ❯ RecordClass.decodeValue node_modules/@dfinity/candid/src/idl.ts:1038:35
 ❯ VecClass.decodeValue node_modules/@dfinity/candid/src/idl.ts:857:28
 ❯ RecordClass.decodeValue node_modules/@dfinity/candid/src/idl.ts:1038:35
 ❯ VariantClass.decodeValue node_modules/@dfinity/candid/src/idl.ts:1230:34
 ❯ node_modules/@dfinity/candid/src/idl.ts:1805:14
 ❯ Object.decode node_modules/@dfinity/candid/src/idl.ts:1804:27
 ❯ decodeReturnValue node_modules/@dfinity/agent/src/actor.ts:292:28

```

My interface file was downloaded from [Canlista](https://k7gat-daaaa-aaaae-qaahq-cai.ic0.app/canister/qjdve-lqaaa-aaaaa-aaaeq-cai), and the type for both start and length is set to bigint.

It seems to be broken on the [candid interface for the archive canister](https://a4gq6-oaaaa-aaaab-qaa4q-cai.raw.ic0.app/?id=qjdve-lqaaa-aaaaa-aaaeq-cai) as well so my guess is that it’s a bug in the typescript implementation on the decoding result side of things.

Strangely, it seems to be working on the [candid interface for the ledger canister](https://a4gq6-oaaaa-aaaab-qaa4q-cai.raw.ic0.app/?id=ryjl3-tyaaa-aaaaa-aaaba-cai) with the sister function `query_blocks`

EDIT: seems it only works in typescript when `length` is set to `0n`. Which is useless.

---

<div class="post-metadata">

**Author:** ![georgemourginakis](https://sea1.discourse-cdn.com/flex023/user_avatar/forum.dfinity.org/georgemourginakis/32/8855_2.png) [@georgemourginakis](https://forum.dfinity.org/u/georgemourginakis)\
**Post date:** [April 13, 2023, 6:38am UTC](https://forum.dfinity.org/t/query-blocks-icp-ledger-candid/11948/16 "2023-04-13T06:38:57Z")

</div>

Here’s kind of a dirty workaround if you want to stick to typescript and you’re using node

```ts
const getBlocksWorkaround = (start: bigint, length: bigint) => {
    const result: Buffer = execSync(
        `dfx canister --network ic call "qjdve-lqaaa-aaaaa-aaaeq-cai" ` +
        `get_blocks '(record {start = 4 : nat64; length = 20 : nat64} )' ` +
        `--candid ${process.cwd()}/src/nns_interfaces/archive/archive.did`
    );
    return result.toString();
};

```

Unfortunately it looks like you’ll have to parse or serialize this into JSON yourself, unless there’s some feature of DFX I’m unaware of.

[icx](https://github.com/dfinity/agent-rs/tree/main/icx) looks like it could be useful, but i think it only serializes messages that are meant to be sent.

And if you want to use [https://github.com/dfinity/idl2json](https://github.com/dfinity/idl2json):

```ts
const getBlocksWorkaround = (start: bigint, length: bigint) => {
    const path_to_idl2json_binary = '/Users/asdfpath/debug/idl2json';
    const cmd = `dfx canister --network ic call "${ARCHIVE_CANISTER_ID}" ` +
        `get_blocks '(record {start = ${start} : nat64; length = ${length} : nat64} )' ` +
        `--candid ${process.cwd()}/src/nns_interfaces/archive/archive.did` +
        `| ${path_to_idl2json_binary}`;
    const result: Buffer = execSync(cmd);
    const parsed_result = JSON.parse(result.toString());
    return parsed_result.Ok;
};

console.log(getBlocksWorkaround(4n, 20n));
console.log(getBlocksWorkaround(4n, 20n).blocks[0]);

```

Seems as if they ran into the same exact issue in [this thread](https://forum.dfinity.org/t/how-to-use-dfx-to-query-the-balance-of-an-account-identifier/15929/7)
