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:
-
Create a new project folder by executing the following command in the terminal:
-
Initialize a
package.jsonfile using the correct command for your package manager: -
Add the TypeScript and Node type definitions to your projects using the correct command for your package manager:
-
Create a
tsconfig.jsonfile in the root of your project and paste the following configuration: -
Initialize the
srcdirectory:
-
-
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¶
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.
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:
// 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:
// 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:
// 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:
Upon successful verification, you'll see a message like:
View complete script
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¶
| Created: November 6, 2025