import type { SubmittableExtrinsic } from '@polkadot/api/types';
import type { u32, u128 } from '@polkadot/types';
import type { ISubmittableResult } from '@polkadot/types/types';
import type { GearApi } from '../GearApi';
import type { ProgramMetadata } from '../metadata';
import type { HexString, IProgramCreateResult, IProgramUploadResult, ProgramCreateOptions, ProgramUploadOptions } from '../types';
import { GearGas } from './Gas';
import { GearTransaction } from './Transaction';
export declare class GearProgram extends GearTransaction {
    protected _api: GearApi;
    calculateGas: GearGas;
    constructor(_api: GearApi);
    /**
     * ### Upload program with code using program metadata to encode payload
     * @param args Program parameters
     * @param meta (optional) Program metadata obtained using `ProgramMetadata.from` method
     * @param typeIndex (optional) Index of type in the registry. If not specified the type index from `meta.init.input` will be used instead.
     * @returns Object containing program id, generated (or specified) salt, code id, prepared extrinsic
     * @example
     * ```javascript
     * const api = await GearApi.create();
     * const code = fs.readFileSync('path/to/program.opt.wasm');
     * cosnt hexMeta = '0x...';
     * const meta = ProgramMetadata.from(hexMeta);
     * const { programId, codeId, salt, extrinsic } = api.program.upload({
     *   code,
     *   initPayload: { field: 'someValue' },
     *   gasLimit: 20_000_000,
     * }, meta, meta.init.input);
     * api.program.signAndSend(account, (events) => {
     *   events.forEach(({event}) => console.log(event.toHuman()))
     * })
     * ```
     */
    upload(args: ProgramUploadOptions, meta?: ProgramMetadata, typeIndex?: number): IProgramUploadResult;
    /**
     * ### Upload program with code using registry in hex format to encode payload
     * @param args Program parameters
     * @param hexRegistry Registry presented as Hex string
     * @param typeIndex Index of type in the registry.
     * @returns Object containing program id, generated (or specified) salt, code id, prepared extrinsic
     */
    upload(args: ProgramUploadOptions, hexRegistry: HexString, typeIndex: number): IProgramUploadResult;
    /** ### Upload program with code using type name to encode payload
     * @param args
     * @param metaOrHexRegistry (optional) Metadata or hex registry
     * @param typeName type name (one of the default rust types if metadata or registry don't specified)
     */
    upload(args: ProgramUploadOptions, metaOrHexRegistry?: ProgramMetadata | HexString, typeName?: string): IProgramUploadResult;
    /**
     * ### Create program from uploaded on chain code using program metadata to encode payload
     * @param args Program parameters
     * @param meta (optional) Program metadata obtained using `ProgramMetadata.from` method.
     * @param typeIndex (optional) Index of type in the registry. If not specified the type index from `meta.init.input` will be used instead.
     * @returns Object containing program id, generated (or specified) salt, prepared extrinsic
     * @example
     * ```javascript
     * const api = await GearApi.create();
     * const codeId = '0x...';
     * cosnt hexMeta = '0x...';
     * const meta = ProgramMetadata.from(hexMeta);
     * const { programId, codeId, salt, extrinsic } = api.program.create({
     *   code,
     *   initPayload: { field: 'someValue' },
     *   gasLimit: 20_000_000,
     * }, meta, meta.init.input);
     * api.program.signAndSend(account, (events) => {
     *   events.forEach(({event}) => console.log(event.toHuman()))
     * })
     * ```
     */
    create(args: ProgramCreateOptions, meta?: ProgramMetadata, typeIndex?: number | null): IProgramCreateResult;
    /**
     * ### Create program from uploaded on chain code using program metadata to encode payload
     * @param args Program parameters
     * @param hexRegistry Registry presented as Hex string
     * @param typeIndex Index of type in the registry.
     * @returns Object containing program id, generated (or specified) salt, prepared extrinsic
     */
    create(args: ProgramCreateOptions, hexRegistry: HexString, typeIndex: number): IProgramCreateResult;
    /** ## Create program using existed codeId
     * @param args
     * @param metaOrHexRegistry (optional) Metadata or hex registry in hex format
     * @param type name type name (one of the default rust types if metadata or registry don't specified)
     */
    create(args: ProgramCreateOptions, metaOrHexRegistry?: HexString | ProgramMetadata, typeName?: number | string): IProgramCreateResult;
    /**
     * ### Pay program rent
     * @param programId
     * @param blockCount
     * @returns
     * @example
     * ```javascript
     * const tx = await api.program.payRent('0x...', 100_000);
     * tx.signAndSend(account, (events) => {
     *   events.forEach(({event}) => console.log(event.toHuman()))
     * })
     * ```
     */
    payRent(programId: HexString, blockCount: number): Promise<SubmittableExtrinsic<'promise', ISubmittableResult>>;
    /**
     * ### Calculate the cost of rent for a certain number of blocks
     * @param blockCount
     * @returns u128 number
     */
    calcualtePayRent(blockCount: number): u128;
    /**
     * Get ids of all uploaded programs
     * @returns Array of program ids
     */
    allUploadedPrograms(count?: number): Promise<HexString[]>;
    /**
     *
     * @param id A program id
     * @returns `true` if address belongs to program, and `false` otherwise
     */
    exists(id: HexString): Promise<boolean>;
    /**
     * @deprecated use `api.program.codeId` instead
     */
    codeHash(id: HexString): Promise<HexString>;
    /**
     * Get code's id of the program uploaded on chain
     * @param programId
     * @returns codeId of the program code
     */
    codeId(id: string): Promise<HexString>;
    /**
     * ### Get hash of program metadata
     * @param programId
     * @param at (optional) block hash
     * @returns
     */
    metaHash(programId: HexString, at?: HexString): Promise<HexString>;
    get costPerBlock(): u128;
    get rentMinimalResumePeriod(): u32;
    get rentFreePeriod(): u32;
    /**
     * ## Subscribe to Program State Changes
     *
     * Subscribe to real-time notifications when program state changes on the blockchain.
     * This method uses server-side filtering to efficiently track specific programs without polling.
     *
     * The subscription notifies whenever one or more programs undergo state modifications, such as:
     * - Program code updates
     * - Program creation or termination
     * - Program status changes
     *
     * @param programIds - List of program IDs to monitor, or null to listen to all programs.
     *                     When null, the callback will be triggered for any program state change on the blockchain.
     *                     Pass a specific array of HexStrings to filter notifications to only those programs.
     *
     * @param callback - Async or sync function called when monitored program state changes.
     *                   Parameters:
     *                   - blockHash (HexString): Hash of the block where the state change occurred
     *                   - programIds (HexString[]): Array of program IDs that changed state in this block
     *
     *                   The callback can perform async operations (e.g., fetching updated program state).
     *
     * @returns Unsubscribe function. Call this to stop receiving state change notifications.
     *
     * @throws RpcMethodNotSupportedError - If the connected node does not support the subscription method.
     *
     * @example
     * ```typescript
     * // Monitor all program state changes
     * const unsubscribe = await api.program.subscribeToStateChanges(
     *   null, // listen to all programs
     *   (blockHash, programIds) => {
     *     console.log(`Block: ${blockHash}`);
     *     console.log(`Updated programs: ${programIds.join(', ')}`);
     *   }
     * );
     *
     * // Later, stop listening
     * unsubscribe();
     * ```
     *
     * @example
     * ```typescript
     * // Monitor specific programs
     * const myPrograms = ['0x...', '0x...'];
     *
     * const unsubscribe = await api.program.subscribeToStateChanges(
     *   myPrograms,
     *   async (blockHash, changedProgramIds) => {
     *     console.log(`Programs changed in block: ${blockHash}`);
     *
     *     // Perform async operations on updated programs
     *     for (const programId of changedProgramIds) {
     *       // Check if program still exists
     *       const exists = await api.program.exists(programId);
     *       // Get updated code ID
     *       const codeId = await api.program.codeId(programId);
     *       console.log(`Program ${programId} - Exists: ${exists}, Code: ${codeId}`);
     *     }
     *   }
     * );
     * ```
     *
     * @see https://github.com/gear-tech/gear/pull/4895 for implementation details
     */
    subscribeToStateChanges(programIds: HexString[] | null, callback: (blockHash: HexString, programIds: HexString[]) => void | Promise<void>): import("@polkadot/api/types").UnsubscribePromise;
}
