diff --git a/packages/api-contract/src/base/Code.ts b/packages/api-contract/src/base/Code.ts index ef5a34691302..ecfe2f8ab5f2 100644 --- a/packages/api-contract/src/base/Code.ts +++ b/packages/api-contract/src/base/Code.ts @@ -12,7 +12,7 @@ import type { AbiConstructor, BlueprintOptions } from '../types.js'; import type { MapConstructorExec } from './types.js'; import { SubmittableResult } from '@polkadot/api'; -import { BN_ZERO, compactAddLength, isUndefined, isWasm, u8aToU8a } from '@polkadot/util'; +import { BN_ZERO, compactAddLength, isU8a, isUndefined, isWasm, u8aEq, u8aToU8a } from '@polkadot/util'; import { applyOnEvent } from '../util.js'; import { Base } from './Base.js'; @@ -34,6 +34,16 @@ export class CodeSubmittableResult extends Submittable } } +function isRiscV (bytes: unknown): bytes is Uint8Array { + const ELF_MAGIC = new Uint8Array([0x7f, 0x45, 0x4c, 0x46]); // ELF magic bytes: 0x7f, 'E', 'L', 'F' + + return isU8a(bytes) && u8aEq(bytes.subarray(0, 4), ELF_MAGIC); +} + +function isValidCode (code: Uint8Array): boolean { + return isWasm(code) || isRiscV(code); +} + export class Code extends Base { readonly code: Uint8Array; @@ -42,12 +52,12 @@ export class Code extends Base { constructor (api: ApiBase, abi: string | Record | Abi, wasm: Uint8Array | string | Buffer | null | undefined, decorateMethod: DecorateMethod) { super(api, abi, decorateMethod); - this.code = isWasm(this.abi.info.source.wasm) + this.code = isValidCode(this.abi.info.source.wasm) ? this.abi.info.source.wasm : u8aToU8a(wasm); - if (!isWasm(this.code)) { - throw new Error('No WASM code provided'); + if (!isValidCode(this.code)) { + throw new Error('Invalid code provided'); } this.abi.constructors.forEach((c): void => {