import type { BigNumberish, BytesLike, HexAddress, HexString, HexString32, ProofRef, ProofSequence, ProofSequenceV1, Provider } from './types.js';
import { type Unwrappable } from './wrap.js';
import { fetchBlock } from './utils.js';
import { CachedMap, LRU } from './cached.js';
import { GATEWAY_OP as OP } from './ops.js';
import { ProgramReader } from './reader.js';
type HexFuture = Unwrappable<number, HexString>;
export declare function solidityArraySlots(slot: BigNumberish, length: number): bigint[];
export declare function solidityFollowSlot(slot: BigNumberish, key: BytesLike): bigint;
export declare function pow256(base: bigint, exp: bigint): bigint;
export declare class GatewayProgram {
    readonly ops: number[];
    static readonly Opcode: {
        readonly PUSH_0: 0;
        readonly PUSH_1: 1;
        readonly PUSH_2: 2;
        readonly PUSH_3: 3;
        readonly PUSH_4: 4;
        readonly PUSH_5: 5;
        readonly PUSH_6: 6;
        readonly PUSH_7: 7;
        readonly PUSH_8: 8;
        readonly PUSH_9: 9;
        readonly PUSH_10: 10;
        readonly PUSH_11: 11;
        readonly PUSH_12: 12;
        readonly PUSH_13: 13;
        readonly PUSH_14: 14;
        readonly PUSH_15: 15;
        readonly PUSH_16: 16;
        readonly PUSH_17: 17;
        readonly PUSH_18: 18;
        readonly PUSH_19: 19;
        readonly PUSH_20: 20;
        readonly PUSH_21: 21;
        readonly PUSH_22: 22;
        readonly PUSH_23: 23;
        readonly PUSH_24: 24;
        readonly PUSH_25: 25;
        readonly PUSH_26: 26;
        readonly PUSH_27: 27;
        readonly PUSH_28: 28;
        readonly PUSH_29: 29;
        readonly PUSH_30: 30;
        readonly PUSH_31: 31;
        readonly PUSH_32: 32;
        readonly GET_SLOT: 33;
        readonly GET_TARGET: 34;
        readonly STACK_SIZE: 35;
        readonly IS_CONTRACT: 36;
        readonly PUSH_BYTES: 40;
        readonly PUSH_STACK: 41;
        readonly PUSH_OUTPUT: 42;
        readonly SET_TARGET: 50;
        readonly SET_OUTPUT: 51;
        readonly EVAL_LOOP: 52;
        readonly EVAL: 53;
        readonly ASSERT: 54;
        readonly READ_SLOT: 60;
        readonly READ_BYTES: 61;
        readonly READ_ARRAY: 62;
        readonly READ_HASHED_BYTES: 63;
        readonly READ_SLOTS: 64;
        readonly SET_SLOT: 70;
        readonly ADD_SLOT: 71;
        readonly FOLLOW: 72;
        readonly DUP: 80;
        readonly POP: 81;
        readonly SWAP: 82;
        readonly KECCAK: 90;
        readonly CONCAT: 91;
        readonly SLICE: 92;
        readonly LENGTH: 93;
        readonly PLUS: 100;
        readonly TIMES: 101;
        readonly DIVIDE: 102;
        readonly MOD: 103;
        readonly POW: 104;
        readonly AND: 110;
        readonly OR: 111;
        readonly XOR: 112;
        readonly SHIFT_LEFT: 113;
        readonly SHIFT_RIGHT: 114;
        readonly NOT: 115;
        readonly IS_ZERO: 120;
        readonly EQ: 121;
        readonly LT: 122;
        readonly GT: 123;
        readonly DEBUG: 255;
    };
    constructor(ops?: number[]);
    clone(): GatewayProgram;
    op(key: keyof typeof OP): this;
    protected addByte(x: number): this;
    protected addBytes(v: Uint8Array): this;
    toTuple(): Uint8Array[];
    encode(): Uint8Array;
    debug(label?: string): this;
    read(n?: number): this;
    readBytes(): this;
    readHashedBytes(): this;
    readArray(step: number): this;
    setTarget(x: HexString): this;
    target(): this;
    setOutput(i: number): this;
    output(): this;
    eval(): this;
    evalIf(): this;
    evalLoop(opts?: {
        success?: boolean;
        failure?: boolean;
        acquire?: boolean;
        keep?: boolean;
        count?: number;
    }): this;
    exit(exitCode: number): this;
    assertNonzero(exitCode: number): this;
    requireContract(exitCode?: number): this;
    requireNonzero(exitCode?: number): this;
    setSlot(x: BigNumberish): this;
    offset(x: BigNumberish): this;
    addSlot(): this;
    slot(): this;
    follow(): this;
    followIndex(): this;
    pop(): this;
    dup(back?: number): this;
    swap(back?: number): this;
    pushOutput(i: number): this;
    pushStack(i: number): this;
    push(x: BigNumberish | boolean): this;
    pushStr(s: string): this;
    pushBytes(v: BytesLike): this;
    pushProgram(program: GatewayProgram): this;
    getSlot(): this;
    getTarget(): this;
    stackSize(): this;
    isContract(): this;
    concat(): this;
    keccak(): this;
    slice(x: number, n: number): this;
    length(): this;
    plus(): this;
    twosComplement(): this;
    subtract(): this;
    times(): this;
    divide(): this;
    mod(): this;
    pow(): this;
    and(): this;
    or(): this;
    xor(): this;
    isZero(): this;
    not(): this;
    shl(shift: BigNumberish): this;
    shr(shift: BigNumberish): this;
    eq(): this;
    lt(): this;
    gt(): this;
    neq(): this;
    lte(): this;
    gte(): this;
    dup2(): this;
    min(): this;
    max(): this;
}
export declare class GatewayRequest extends GatewayProgram {
    constructor(outputCount?: number);
    clone(): GatewayRequest;
    get outputCount(): number;
    private ensureCapacity;
    addOutput(): this;
    drain(count: number): this;
}
export type TargetNeed = {
    target: HexAddress;
    required: boolean;
};
export type HashedNeed = {
    hash: HexFuture;
    value: HexFuture;
};
export type Need = TargetNeed | bigint | HashedNeed;
export declare function isTargetNeed(need: Need): need is TargetNeed;
export declare function requireV1Needs(needs: Need[]): {
    slots: bigint[];
    target: HexAddress;
    required: boolean;
};
export declare class GatewayVM {
    readonly outputs: HexFuture[];
    readonly maxStack: number;
    allocBudget: number;
    readonly needs: Need[];
    readonly targets: Map<string, TargetNeed>;
    static create(outputCount: number, maxStackSize?: number, allocBudget?: number): GatewayVM;
    target: any;
    slot: bigint;
    stack: HexFuture[];
    exitCode: number;
    constructor(outputs: HexFuture[], maxStack: number, allocBudget: number, needs?: Need[], targets?: Map<string, TargetNeed>);
    checkAlloc(size: number): void;
    checkOutputIndex(i: number): number;
    checkStackIndex(i: number): number;
    checkBack(back: number): number;
    resolveOutputs(): Promise<string[]>;
    resolveStack(): Promise<string[]>;
    push(x: HexFuture): void;
    pushUint256(x: BigNumberish | boolean): void;
    pop(): HexFuture;
    popSlice(n: number): HexFuture[];
    popNumber(): Promise<number>;
    binaryOp(fn: (a: bigint, b: bigint) => bigint | boolean): Promise<void>;
}
export declare function makeStorageKey(target: HexAddress, slot: bigint): string;
export declare abstract class AbstractProver {
    readonly provider: Provider;
    readonly proofLRU: LRU<string, any>;
    readonly cache: CachedMap<string, any>;
    readonly readBytesAtSupported: Map<string, boolean>;
    maxStackSize: number;
    maxUniqueProofs: number;
    maxUniqueTargets: number;
    proofBatchSize: number;
    maxSuppliedBytes: number;
    maxProvableBytes: number;
    maxAllocBytes: number;
    maxEvalDepth: number;
    fast: boolean;
    printDebug: boolean;
    constructor(provider: Provider);
    abstract get context(): Record<string, any>;
    checkProofCount(size: number): void;
    checkStorageProofs(isContract: boolean, slots: bigint[], proofs: any[]): void;
    proofMap(): Map<string, bigint[]>;
    abstract isContract(target: HexAddress): Promise<boolean>;
    abstract getStorage(target: HexAddress, slot: bigint, fast?: boolean): Promise<HexString>;
    abstract prove(needs: Need[]): Promise<ProofSequence>;
    proveV1(needs: Need[]): Promise<ProofSequenceV1>;
    abstract fetchStateRoot(): Promise<HexString32>;
    abstract fetchTimestamp(): Promise<number>;
    evalDecoded(v: BytesLike): Promise<GatewayVM>;
    evalRequest(req: GatewayRequest): Promise<GatewayVM>;
    evalReader(reader: ProgramReader): Promise<GatewayVM>;
    private eval;
    fetchUnprovenStorageBytes(target: HexAddress, slot: bigint): HexFuture;
    getStorageBytes(target: HexAddress, slot: bigint, fast?: boolean): Promise<{
        value: HexFuture;
        size: number;
        slots: bigint[];
    }>;
}
export interface LatestProverFactory<P extends AbstractProver> {
    latest(provider: Provider, relative?: BigNumberish): Promise<P>;
}
export declare abstract class BlockProver extends AbstractProver {
    protected static _createLatest<P extends BlockProver>(this: new (...a: ConstructorParameters<typeof BlockProver>) => P): (provider: Provider, relBlockTag?: BigNumberish) => Promise<P>;
    readonly block: HexString;
    constructor(provider: Provider, block: BigNumberish);
    get context(): {
        block: bigint;
    };
    get blockNumber(): bigint;
    fetchBlock(): Promise<ReturnType<typeof fetchBlock>>;
    fetchStateRoot(): Promise<string>;
    fetchTimestamp(): Promise<number>;
    protected abstract _proveNeed(need: TargetNeed, accountRef: ProofRef, storageRefs: Map<bigint, ProofRef>): Promise<void>;
    prove(needs: Need[]): Promise<ProofSequence>;
}
export {};
//# sourceMappingURL=vm.d.ts.map