Skip to content

Verify Storage Request Registration

Use this guide to confirm that a file's storage request has been successfully recorded on-chain. You'll learn how to derive the deterministic file key and query the on-chain storage requests via the Polkadot.js API. A successful check confirms that the request exists and that core fields, such as the bucket ID and content fingerprint, match your local values. If no record is found, the transaction may not have been finalized yet, or one of the inputs used to compute the file key may not exactly match what was used when the request was issued.

Prerequisites

  • Node.js v22+ installed
  • A TypeScript project

    Need a starter project?

    If you don't have an existing project, follow these steps to create a TypeScript project you can use to follow the guides in this section:

    1. Create a new project folder by executing the following command in the terminal:

      mkdir datahaven-project && cd datahaven-project
      
    2. Initialize a package.json file using the correct command for your package manager:

      pnpm init
      
      yarn init
      
      npm init --y
      
    3. Add the TypeScript and Node type definitions to your projects using the correct command for your package manager:

      pnpm add -D typescript ts-node @types/node
      
      yarn add -D typescript ts-node @types/node
      
      npm install -D typescript ts-node @types/node
      
    4. Create a tsconfig.json file in the root of your project and paste the following configuration:

      tsconfig.json
      {
          "compilerOptions": {
              "target": "ES2022",
              "module": "nodenext",
              "moduleResolution": "NodeNext",
              "esModuleInterop": true,
              "strict": true,
              "skipLibCheck": true,
              "outDir": "dist",
              "declaration": true,
              "sourceMap": true
          },
          "include": ["src/**/*.ts"]
      }
      
    5. Initialize the src directory:

      mkdir src && touch src/index.ts
      
  • A bucket created with the ID handy

  • A storage request issued along with the address of the account that issued the request, the file name, and the fingerprint of the file.

Install Dependencies

pnpm add @storagehub-sdk/core @storagehub/types-bundle @polkadot/api @polkadot/types @storagehub/api-augment
yarn add @storagehub-sdk/core @storagehub/types-bundle @polkadot/api @polkadot/types @storagehub/api-augment
npm install @storagehub-sdk/core @storagehub/types-bundle @polkadot/api @polkadot/types @storagehub/api-augment

Initialize Polkadot.js and File Manager

First, you'll need to set up the Polkadot.js API to connect to the DataHaven network, which allows you to read data from the underlying Substrate node. You'll also need to initialize a File Manager instance to compute the file key required to retrieve storage request data.

If you've already followed the Issue a Storage Request guide, the Polkadot.js API and File Manager may already be initialized. In that case, review the placeholders at the bottom of the following snippet to see where you'll add logic in this guide, then skip ahead to Compute the File Key.

Create an index.ts and add the following code:

Note

The code below uses DataHaven Testnet configuration values, which include the Chain ID, RPC URL, WSS URL, MSP URL, and token metadata. If you’re running a local devnet, make sure to replace these with your local configuration parameters. You can find all the relevant local devnet values in the Starter Kit.

index.ts
import '@storagehub/api-augment';
import { ApiPromise, WsProvider } from '@polkadot/api';
import { TypeRegistry } from '@polkadot/types';
import { AccountId20, H256 } from '@polkadot/types/interfaces';
import { types } from '@storagehub/types-bundle';
import { FileManager, initWasm } from '@storagehub-sdk/core';
import { createReadStream, statSync } from 'node:fs';
import { Readable } from 'node:stream';

async function run() {
  // For anything from @storagehub-sdk/core to work, initWasm() is required
  // on top of the file
  await initWasm();

  // --- Polkadot.js API setup ---
  const provider = new WsProvider(
    'wss://services.datahaven-testnet.network/testnet'
  );
  const polkadotApi: ApiPromise = await ApiPromise.create({
    provider,
    typesBundle: types,
    noInitWarn: true,
  });

  // --- File Manager setup ---
  // Specify the file name of the file to be uploaded
  const fileName = 'INSERT_FILE_NAME'; // Example: filename.jpeg

  // Specify the file path of the file to be uploaded relative to the location of your index.ts file
  const filePath = new URL(`./files/${fileName}`, import.meta.url).pathname;
  const fileSize = statSync(filePath).size;

  // Initialize a FileManager instance with file metadata and a readable stream.
  // The stream converts the local file into a Web-compatible ReadableStream,
  // which the SDK uses to handle file uploads to the network
  const fileManager = new FileManager({
    size: fileSize,
    stream: () =>
      Readable.toWeb(createReadStream(filePath)) as ReadableStream<Uint8Array>,
  });
  const fingerprint = await fileManager.getFingerprint();

  // --- Verify storage request logic ---
  // **PLACEHOLDER FOR STEP 1: COMPUTE THE FILE KEY**
  // **PLACEHOLDER FOR STEP 2: RETRIEVE STORAGE REQUEST DATA**
  // **PLACEHOLDER FOR STEP 3: READ STORAGE REQUEST DATA**

  // Disconnect the Polkadot API at the very end
  await polkadotApi.disconnect();
}

await run();

Compute the File Key

To compute the deterministic file key, derive it from the owner (AccountId20), bucket ID, and file name:

// **PLACEHOLDER FOR STEP 1: COMPUTE THE FILE KEY**
// Compute file key
const ownerAccount = 'INSERT_ACCOUNT_AS_HEX_STRING';
const bucketId = 'INSERT_BUCKET_ID';

const registry = new TypeRegistry();
const owner = registry.createType('AccountId20', ownerAccount) as AccountId20;
const bucketIdH256 = registry.createType('H256', bucketId) as H256;
const fileKey = await fileManager.computeFileKey(
  owner,
  bucketIdH256,
  fileName
);
console.log('Computed file key:', fileKey.toHex());

Retrieve Storage Request Data

To retrieve storage request data, query fileSystem.storageRequests and pass in the computed file key:

// **PLACEHOLDER FOR STEP 2: RETRIEVE STORAGE REQUEST DATA**
// Verify storage request on chain
const storageRequest = await polkadotApi.query.fileSystem.storageRequests(
  fileKey
);
if (!storageRequest.isSome) {
  throw new Error('Storage request not found on chain');
}

Read Storage Request Data

To read storage request data, it first must be unwrapped as follows:

// **PLACEHOLDER FOR STEP 3: READ STORAGE REQUEST DATA**
// Read the storage request data
const storageRequestData = storageRequest.unwrap();
console.log('Storage request data:', storageRequestData);
console.log(
  'Storage request bucketId:',
  storageRequestData.bucketId.toString()
);
console.log(
  'Storage request fingerprint should be the same as initial fingerprint',
  storageRequestData.fingerprint.toString() === fingerprint.toString()
);

Run the script:

ts-node index.ts

Upon successful verification, you'll see a message like:

Storage request bucketId: 0x8bb80c024079126ba72150cce1d60665e4d4da038c56f75121471912b036c70a Storage request fingerprint should be the same as initial fingerprint true
View complete script
index.ts
import '@storagehub/api-augment';
import { ApiPromise, WsProvider } from '@polkadot/api';
import { TypeRegistry } from '@polkadot/types';
import { AccountId20, H256 } from '@polkadot/types/interfaces';
import { types } from '@storagehub/types-bundle';
import { FileManager, initWasm } from '@storagehub-sdk/core';
import { createReadStream, statSync } from 'node:fs';
import { Readable } from 'node:stream';

async function run() {
  // For anything from @storagehub-sdk/core to work, initWasm() is required
  // on top of the file
  await initWasm();

  // --- Polkadot.js API setup ---
  const provider = new WsProvider(
    'wss://services.datahaven-testnet.network/testnet'
  );
  const polkadotApi: ApiPromise = await ApiPromise.create({
    provider,
    typesBundle: types,
    noInitWarn: true,
  });

  // --- File Manager setup ---
  // Specify the file name of the file to be uploaded
  const fileName = 'INSERT_FILE_NAME'; // Example: filename.jpeg

  // Specify the file path of the file to be uploaded relative to the location of your index.ts file
  const filePath = new URL(`./files/${fileName}`, import.meta.url).pathname;
  const fileSize = statSync(filePath).size;

  // Initialize a FileManager instance with file metadata and a readable stream.
  // The stream converts the local file into a Web-compatible ReadableStream,
  // which the SDK uses to handle file uploads to the network
  const fileManager = new FileManager({
    size: fileSize,
    stream: () =>
      Readable.toWeb(createReadStream(filePath)) as ReadableStream<Uint8Array>,
  });
  const fingerprint = await fileManager.getFingerprint();

  // --- Verify storage request logic ---
  // Compute file key
  const ownerAccount = 'INSERT_ACCOUNT_AS_HEX_STRING';
  const bucketId = 'INSERT_BUCKET_ID';

  const registry = new TypeRegistry();
  const owner = registry.createType('AccountId20', ownerAccount) as AccountId20;
  const bucketIdH256 = registry.createType('H256', bucketId) as H256;
  const fileKey = await fileManager.computeFileKey(
    owner,
    bucketIdH256,
    fileName
  );
  console.log('Computed file key:', fileKey.toHex());

  // Verify storage request on chain
  const storageRequest = await polkadotApi.query.fileSystem.storageRequests(
    fileKey
  );
  if (!storageRequest.isSome) {
    throw new Error('Storage request not found on chain');
  }

  // Read the storage request data
  const storageRequestData = storageRequest.unwrap();
  console.log('Storage request data:', storageRequestData);
  console.log(
    'Storage request bucketId:',
    storageRequestData.bucketId.toString()
  );
  console.log(
    'Storage request fingerprint should be the same as initial fingerprint',
    storageRequestData.fingerprint.toString() === fingerprint.toString()
  );

  // Disconnect the Polkadot API at the very end
  await polkadotApi.disconnect();
}

await run();

Next Steps

Last update: November 11, 2025
| Created: November 6, 2025