@gear-js/api
Version:
A JavaScript library that provides functionality to connect GEAR Component APIs.
111 lines (108 loc) • 4.51 kB
JavaScript
import { u8aToHex } from '@polkadot/util';
import { SPEC_VERSION } from '../consts.js';
import { CodeDoesNotExistError } from '../errors/program.errors.js';
import '@polkadot/api';
import '@polkadot/types';
import 'node:assert';
import '../metadata/programMetadata.js';
import { generateCodeHash } from '../utils/generate.js';
import { getIdsFromKeys } from '../utils/prefixes.js';
import '../utils/reply-code.js';
import '@polkadot/util-crypto';
import { validateCodeId } from '../utils/validate.js';
import { getGrReply } from '../wasm/reply.js';
import { GearTransaction } from './Transaction.js';
class GearCode extends GearTransaction {
/**
* ### Submit code without initialization
* @param code
* @returns Code hash
*/
async upload(code) {
const codeHash = generateCodeHash(code);
await validateCodeId(codeHash, this._api);
const codeBytes = this._api.createType('Bytes', Array.from(code));
this.extrinsic = this._api.tx.gear.uploadCode(codeBytes);
return { codeHash, submitted: this.extrinsic, extrinsic: this.extrinsic };
}
/**
* ### Check that codeId exists on chain
* @param codeId
*/
async exists(codeId) {
if (this._api.specVersion >= SPEC_VERSION.V1900) {
const codeMetadata = await this._api.query.gearProgram.codeMetadataStorage(codeId);
return codeMetadata.isSome;
}
const codeMetadata = (await this._api.query.gearProgram.metadataStorage(codeId));
return codeMetadata.isSome;
}
_storageV1900(codeId) {
if (this._api.specVersion >= SPEC_VERSION.V1900) {
return this._api.query.gearProgram.codeMetadataStorage(codeId);
}
throw new Error(`Unsupported version ${this._api.specVersion}. Only versions >= 1900 are supported`);
}
_storageBeforeV1900(codeId) {
if (this._api.specVersion < SPEC_VERSION.V1900) {
return this._api.query.gearProgram.codeStorage(codeId);
}
throw new Error(`Unsupported version ${this._api.specVersion}. Only versions < 1900 are supported`);
}
/**
* ### Get code storage
* @param codeId
* @returns ___[CodeMetadata](https://github.com/gear-tech/gear/blob/master/core/src/code/metadata.rs#L52)___ if connected to the node with version >= 1900,
* otherwise ___[InstrumentedCode](https://github.com/gear-tech/gear/blob/290c4953a2fd54270ec34333d8cd3f7b97591635/core/src/code/instrumented.rs#L67)___
*/
async storage(codeId) {
if (this._api.specVersion >= SPEC_VERSION.V1900) {
return this._storageV1900(codeId);
}
return this._storageBeforeV1900(codeId);
}
/**
* ### Get static pages of code
* @param codeId
*/
async staticPages(codeId) {
const storage = await this.storage(codeId);
return storage.isSome ? storage.unwrap().staticPages.toNumber() : null;
}
/**
* ### Get all ids of codes uploaded on connected chain
* @returns array of code ids uploaded on chain
*/
async all(count) {
if (this._api.specVersion >= SPEC_VERSION.V1900) {
const prefix = this._api.query.gearProgram.codeMetadataStorage.keyPrefix();
const keys = await this._api.rpc.state.getKeysPaged(prefix, count || 1000);
if (count === undefined) {
let nextKeysBatch = 1000;
while (nextKeysBatch === 1000) {
const _endKeys = await this._api.rpc.state.getKeysPaged(prefix, nextKeysBatch, keys[keys.length - 1]);
keys.push(..._endKeys);
nextKeysBatch = _endKeys.length;
}
}
return getIdsFromKeys(keys, prefix);
}
const prefix = this._api.query.gearProgram.metadataStorage.keyPrefix();
const keys = await this._api.rpc.state.getKeysPaged(prefix, count || 1000);
const codeIds = getIdsFromKeys(keys, prefix);
return codeIds;
}
async metaHash(codeId) {
const code = (await this._api.query.gearProgram.originalCodeStorage(codeId));
if (code.isNone) {
throw new CodeDoesNotExistError(codeId);
}
const metahash = await getGrReply(code.unwrap().toHex(), 'metahash');
return u8aToHex(metahash);
}
async metaHashFromWasm(wasm) {
const metahash = await getGrReply(wasm, 'metahash');
return u8aToHex(metahash);
}
}
export { GearCode };