// AUTO-GENERATED from manifest.json — do not edit by hand.
// Regenerate with: yarn workspace @lifi/composer-sdk generate

import type {
  AnyBindable,
  FlowBuilderInternal,
} from '../authoring/FlowBuilderCore.js';
import type { Bindable, OutputHandle } from '../authoring/handles.js';
import type {
  CoreCallResult,
  SignatureBind,
  StaticCallResult,
} from '../authoring/signatureArgs.js';
import {
  buildCallWireFormat,
  buildStaticCallWireFormat,
} from '../authoring/signatureArgs.js';
import type { TypedGuard } from '../types.js';

import type {
  AaveBorrowConfig,
  AaveClaimRewardsConfig,
  AaveRepayConfig,
  AaveRepayWithATokensConfig,
  AaveSetEModeConfig,
  CoreApproveConfig,
  CoreAsResourceConfig,
  CoreBalanceOfConfig,
  CoreBpsDownConfig,
  CoreBpsUpConfig,
  CoreCallConfig,
  CoreEmitEvent1Config,
  CoreEmitEvent2Config,
  CoreEmitEvent3Config,
  CoreEmitEvent4Config,
  CorePeekConfig,
  CoreRawCallConfig,
  CoreSplitConfig,
  CoreStaticCallConfig,
  CoreTransferConfig,
  InvariantNumericConfig,
  InvariantNumericInRangeConfig,
  LifiSwapConfig,
  LifiZapConfig,
  MorphoBlueSupplyCollateralConfig,
  MorphoBlueWithdrawCollateralConfig,
  ParaswapBuyConfig,
} from './config.generated.js';

/** Split a resource into two outputs by basis-point ratio */
export interface CoreSplitArgs {
  readonly bind: {
    readonly source: Bindable<'resource'>;
  };
  readonly config: CoreSplitConfig;
  readonly guards?: readonly TypedGuard<'a' | 'b'>[];
}

/** Merge two same-token resources into one by addition */
export interface CoreMergeArgs {
  readonly bind: {
    readonly a: Bindable<'resource'>;
    readonly b: Bindable<'resource'>;
  };
  readonly guards?: readonly TypedGuard<'merged'>[];
}

/** Swap tokens via the LI.FI aggregator API */
export interface LifiSwapArgs {
  readonly bind: {
    readonly amountIn: Bindable<'resource'>;
  };
  readonly config: LifiSwapConfig;
  readonly guards?: readonly TypedGuard<'unspentIn'>[];
}

/** Assert that an account holds at least a minimum token balance */
export interface InvariantBalanceAtLeastArgs {
  readonly bind: {
    readonly minimumAmount: Bindable<'resource'>;
    readonly account: Bindable<'address'>;
  };
  readonly guards?: readonly TypedGuard<never>[];
}

/** Assert that an account holds exactly an expected token balance */
export interface InvariantBalanceEqualsArgs {
  readonly bind: {
    readonly expectedAmount: Bindable<'resource'>;
    readonly account: Bindable<'address'>;
  };
  readonly guards?: readonly TypedGuard<never>[];
}

/** Assert that an account holds at most a maximum token balance */
export interface InvariantBalanceAtMostArgs {
  readonly bind: {
    readonly maximumAmount: Bindable<'resource'>;
    readonly account: Bindable<'address'>;
  };
  readonly guards?: readonly TypedGuard<never>[];
}

/** Assert that an account's token balance is between a minimum and a maximum (inclusive) */
export interface InvariantBalanceInRangeArgs {
  readonly bind: {
    readonly minimumAmount: Bindable<'resource'>;
    readonly maximumAmount: Bindable<'uint256'>;
    readonly account: Bindable<'address'>;
  };
  readonly guards?: readonly TypedGuard<never>[];
}

/** Assert that a spender is permitted to move at least a minimum allowance on behalf of an owner */
export interface InvariantAllowanceAtLeastArgs {
  readonly bind: {
    readonly minimumAmount: Bindable<'resource'>;
    readonly owner: Bindable<'address'>;
    readonly spender: Bindable<'address'>;
  };
  readonly guards?: readonly TypedGuard<never>[];
}

/** Assert that a spender's allowance on behalf of an owner exactly equals an expected amount */
export interface InvariantAllowanceEqualsArgs {
  readonly bind: {
    readonly expectedAmount: Bindable<'resource'>;
    readonly owner: Bindable<'address'>;
    readonly spender: Bindable<'address'>;
  };
  readonly guards?: readonly TypedGuard<never>[];
}

/** Assert that a spender is permitted to move at most a maximum allowance on behalf of an owner */
export interface InvariantAllowanceAtMostArgs {
  readonly bind: {
    readonly maximumAmount: Bindable<'resource'>;
    readonly owner: Bindable<'address'>;
    readonly spender: Bindable<'address'>;
  };
  readonly guards?: readonly TypedGuard<never>[];
}

/** Assert that a spender's allowance on behalf of an owner is between a minimum and a maximum (inclusive) */
export interface InvariantAllowanceInRangeArgs {
  readonly bind: {
    readonly minimumAmount: Bindable<'resource'>;
    readonly maximumAmount: Bindable<'uint256'>;
    readonly owner: Bindable<'address'>;
    readonly spender: Bindable<'address'>;
  };
  readonly guards?: readonly TypedGuard<never>[];
}

/** Assert a uint256 value satisfies a comparison against a constant threshold; reverts on violation */
export interface InvariantNumericArgs {
  readonly bind: {
    readonly value: Bindable<'uint256'>;
  };
  readonly config: InvariantNumericConfig;
  readonly guards?: readonly TypedGuard<never>[];
}

/** Assert min <= value <= max against constant bounds; reverts if outside the range */
export interface InvariantNumericInRangeArgs {
  readonly bind: {
    readonly value: Bindable<'uint256'>;
  };
  readonly config: InvariantNumericInRangeConfig;
  readonly guards?: readonly TypedGuard<never>[];
}

/** Add two unsigned integers (a + b) */
export interface CoreAddArgs {
  readonly bind: {
    readonly a: Bindable<'uint256'>;
    readonly b: Bindable<'uint256'>;
  };
  readonly guards?: readonly TypedGuard<'result'>[];
}

/** Subtract b from a (a - b); reverts on underflow */
export interface CoreSubtractArgs {
  readonly bind: {
    readonly a: Bindable<'uint256'>;
    readonly b: Bindable<'uint256'>;
  };
  readonly guards?: readonly TypedGuard<'result'>[];
}

/** Multiply two unsigned integers (a * b) */
export interface CoreMultiplyArgs {
  readonly bind: {
    readonly a: Bindable<'uint256'>;
    readonly b: Bindable<'uint256'>;
  };
  readonly guards?: readonly TypedGuard<'result'>[];
}

/** Divide a by b, rounding toward zero */
export interface CoreDivideDownArgs {
  readonly bind: {
    readonly a: Bindable<'uint256'>;
    readonly b: Bindable<'uint256'>;
  };
  readonly guards?: readonly TypedGuard<'result'>[];
}

/** Divide a by b, rounding away from zero */
export interface CoreDivideUpArgs {
  readonly bind: {
    readonly a: Bindable<'uint256'>;
    readonly b: Bindable<'uint256'>;
  };
  readonly guards?: readonly TypedGuard<'result'>[];
}

/** Multiply value by basis points and divide by 10000, rounding down */
export interface CoreBpsDownArgs {
  readonly bind: {
    readonly value: Bindable<'uint256'>;
  };
  readonly config: CoreBpsDownConfig;
  readonly guards?: readonly TypedGuard<'result'>[];
}

/** Multiply value by basis points and divide by 10000, rounding up */
export interface CoreBpsUpArgs {
  readonly bind: {
    readonly value: Bindable<'uint256'>;
  };
  readonly config: CoreBpsUpConfig;
  readonly guards?: readonly TypedGuard<'result'>[];
}

/** Assert a == b; reverts if not equal */
export interface CoreAssertEqualArgs {
  readonly bind: {
    readonly a: Bindable<'uint256'>;
    readonly b: Bindable<'uint256'>;
  };
  readonly guards?: readonly TypedGuard<never>[];
}

/** Assert a != b; reverts if equal */
export interface CoreAssertNotEqualArgs {
  readonly bind: {
    readonly a: Bindable<'uint256'>;
    readonly b: Bindable<'uint256'>;
  };
  readonly guards?: readonly TypedGuard<never>[];
}

/** Assert a > b; reverts if a <= b */
export interface CoreAssertGtArgs {
  readonly bind: {
    readonly a: Bindable<'uint256'>;
    readonly b: Bindable<'uint256'>;
  };
  readonly guards?: readonly TypedGuard<never>[];
}

/** Assert a >= b; reverts if a < b */
export interface CoreAssertGteArgs {
  readonly bind: {
    readonly a: Bindable<'uint256'>;
    readonly b: Bindable<'uint256'>;
  };
  readonly guards?: readonly TypedGuard<never>[];
}

/** Assert a < b; reverts if a >= b */
export interface CoreAssertLtArgs {
  readonly bind: {
    readonly a: Bindable<'uint256'>;
    readonly b: Bindable<'uint256'>;
  };
  readonly guards?: readonly TypedGuard<never>[];
}

/** Assert a <= b; reverts if a > b */
export interface CoreAssertLteArgs {
  readonly bind: {
    readonly a: Bindable<'uint256'>;
    readonly b: Bindable<'uint256'>;
  };
  readonly guards?: readonly TypedGuard<never>[];
}

/** Assert min <= value <= max; reverts if value is outside the range */
export interface CoreAssertInRangeArgs {
  readonly bind: {
    readonly value: Bindable<'uint256'>;
    readonly min: Bindable<'uint256'>;
    readonly max: Bindable<'uint256'>;
  };
  readonly guards?: readonly TypedGuard<never>[];
}

/** Approve an ERC20 spender for the given token and amount */
export interface CoreApproveArgs {
  readonly bind: {
    readonly amount: Bindable<'resource'>;
  };
  readonly config: CoreApproveConfig;
  readonly guards?: readonly TypedGuard<never>[];
}

/** Read an ERC20 balance, producing a resource */
export interface CoreBalanceOfArgs {
  readonly bind: Record<string, never>;
  readonly config: CoreBalanceOfConfig;
  readonly guards?: readonly TypedGuard<'balance'>[];
}

/** Transfer tokens to a recipient address, optionally specifying a partial amount */
export interface CoreTransferArgs {
  readonly bind: {
    readonly amount: Bindable<'resource'>;
    readonly recipient: Bindable<'address'>;
  };
  readonly config: CoreTransferConfig;
  readonly guards?: readonly TypedGuard<'transferred' | 'remainder'>[];
}

/** Emit a custom on-chain event carrying 1 32-byte payload value. The value becomes a non-indexed data word in a fixed VM log event; the signature is hashed into a discriminator word (it is NOT an indexed EVM topic). */
export interface CoreEmitEvent1Args {
  readonly bind: {
    readonly value0: Bindable<'bytes32'>;
  };
  readonly config: CoreEmitEvent1Config;
  readonly guards?: readonly TypedGuard<never>[];
}

/** Emit a custom on-chain event carrying 2 32-byte payload values. The values become non-indexed data words in a fixed VM log event; the signature is hashed into a discriminator word (it is NOT an indexed EVM topic). */
export interface CoreEmitEvent2Args {
  readonly bind: {
    readonly value0: Bindable<'bytes32'>;
    readonly value1: Bindable<'bytes32'>;
  };
  readonly config: CoreEmitEvent2Config;
  readonly guards?: readonly TypedGuard<never>[];
}

/** Emit a custom on-chain event carrying 3 32-byte payload values. The values become non-indexed data words in a fixed VM log event; the signature is hashed into a discriminator word (it is NOT an indexed EVM topic). */
export interface CoreEmitEvent3Args {
  readonly bind: {
    readonly value0: Bindable<'bytes32'>;
    readonly value1: Bindable<'bytes32'>;
    readonly value2: Bindable<'bytes32'>;
  };
  readonly config: CoreEmitEvent3Config;
  readonly guards?: readonly TypedGuard<never>[];
}

/** Emit a custom on-chain event carrying 4 32-byte payload values. The values become non-indexed data words in a fixed VM log event; the signature is hashed into a discriminator word (it is NOT an indexed EVM topic). */
export interface CoreEmitEvent4Args {
  readonly bind: {
    readonly value0: Bindable<'bytes32'>;
    readonly value1: Bindable<'bytes32'>;
    readonly value2: Bindable<'bytes32'>;
    readonly value3: Bindable<'bytes32'>;
  };
  readonly config: CoreEmitEvent4Config;
  readonly guards?: readonly TypedGuard<never>[];
}

/** Invoke a smart contract function, optionally spending a token resource */
export interface CoreCallArgs<TSig extends string = string> {
  readonly resource?: Bindable<'resource'>;
  readonly bind: SignatureBind<TSig>;
  readonly config: Omit<CoreCallConfig, 'args' | 'functionSignature'> & {
    readonly functionSignature: TSig;
  };
  readonly guards?: readonly TypedGuard<'result'>[];
}

/** Read from a smart contract at runtime (StaticCall); result is fresh at execution time */
export interface CoreStaticCallArgs<TSig extends string = string> {
  readonly bind: SignatureBind<TSig>;
  readonly config: Omit<CoreStaticCallConfig, 'args' | 'functionSignature'> & {
    readonly functionSignature: TSig;
  };
  readonly guards?: readonly TypedGuard<'result'>[];
}

/** Invoke a contract with pre-encoded calldata */
export interface CoreRawCallArgs {
  readonly bind: Record<string, never>;
  readonly config: CoreRawCallConfig;
  readonly guards?: readonly TypedGuard<'result'>[];
}

/** Graduate a raw handle to a resource, enabling slippage surfacing and linearity tracking */
export interface CoreAsResourceArgs {
  readonly bind: {
    readonly handle: Bindable<'uint256'>;
  };
  readonly config: CoreAsResourceConfig;
  readonly guards?: readonly TypedGuard<'resource'>[];
}

/** Borrow an asset from an Aave v3 pool against existing collateral, exposing the borrowed asset as a Resource */
export interface AaveBorrowArgs {
  readonly bind: Record<string, never>;
  readonly config: AaveBorrowConfig;
  readonly guards?: readonly TypedGuard<'debtBalance'>[];
}

/** Repay an Aave v3 variable-rate debt position with the supplied asset. mode: 'exact' passes the input handle amount; mode: 'max' passes type(uint256).max so Aave's Pool clamps paybackAmount to userVariableDebt exactly. Any unspent input is returned through the residual port. */
export interface AaveRepayArgs {
  readonly bind: {
    readonly assetIn: Bindable<'resource'>;
    readonly onBehalfOf: Bindable<'address'>;
  };
  readonly config: AaveRepayConfig;
  readonly guards?: readonly TypedGuard<'actualRepaid' | 'residual'>[];
}

/** Repay an Aave v3 variable-rate debt by burning the caller's aToken balance, returning any unspent residual */
export interface AaveRepayWithATokensArgs {
  readonly bind: {
    readonly aTokenIn: Bindable<'resource'>;
  };
  readonly config: AaveRepayWithATokensConfig;
  readonly guards?: readonly TypedGuard<'actualRepaid' | 'residual'>[];
}

/** Claim a specific Aave v3 incentives reward token against a set of receipt-token positions, exposing the claimed amount as a Resource */
export interface AaveClaimRewardsArgs {
  readonly bind: Record<string, never>;
  readonly config: AaveClaimRewardsConfig;
  readonly guards?: readonly TypedGuard<'claimedAmount'>[];
}

/** Switch the executionAddress's Aave v3 eMode category. 0 disables eMode. The pool reverts if the switch would make the position unhealthy or if any open borrow is for an asset outside the target category. */
export interface AaveSetEModeArgs {
  readonly bind: Record<string, never>;
  readonly config: AaveSetEModeConfig;
  readonly guards?: readonly TypedGuard<never>[];
}

/** Deposit the collateral asset of a Morpho Blue market on behalf of the execution proxy. mode: 'exact' pulls the input handle's amount. mode: 'all' reads the proxy's current ERC20 balance of the market's collateral token and pulls that amount, ignoring the input handle's literal value — note this pulls the proxy's total balance (including unrelated upstream residuals), not just the input port's delivery. Credits Position.collateral on the Morpho singleton; emits no return value and exposes no resource output (the collateral is non-transferable accounting state). */
export interface MorphoBlueSupplyCollateralArgs {
  readonly bind: {
    readonly assetIn: Bindable<'resource'>;
  };
  readonly config: MorphoBlueSupplyCollateralConfig;
  readonly guards?: readonly TypedGuard<never>[];
}

/** Withdraw collateral from a Morpho Blue market position to the receiver address. Exposes the withdrawn ERC20 amount as a Resource output. */
export interface MorphoBlueWithdrawCollateralArgs {
  readonly bind: Record<string, never>;
  readonly config: MorphoBlueWithdrawCollateralConfig;
  readonly guards?: readonly TypedGuard<'collateralWithdrawn'>[];
}

/** Route tokens into a DeFi protocol position via the edge catalog */
export interface LifiZapArgs {
  readonly bind: {
    readonly amountIn: Bindable<'resource'>;
  };
  readonly config: LifiZapConfig;
  readonly guards?: readonly TypedGuard<'amountOut'>[];
}

/** Exact-output (BUY) swap via the Paraswap/Velora Market API: produce exactly `exactAmountOut` of the destination token, pulling only the source needed and exposing the genuinely-unspent source as `unspentIn`. */
export interface ParaswapBuyArgs {
  readonly bind: {
    readonly amountIn: Bindable<'resource'>;
  };
  readonly config: ParaswapBuyConfig;
  readonly guards?: readonly TypedGuard<'unspentIn'>[];
}

/** Read a smart contract value at compile time (off-chain eth_call); result is baked as a literal */
export interface CorePeekArgs {
  readonly bind: Record<string, never>;
  readonly config: CorePeekConfig;
  readonly guards?: readonly TypedGuard<'result'>[];
}

export interface CoreSplitOutputs {
  readonly a: OutputHandle<'resource'>;
  readonly b: OutputHandle<'resource'>;
}

export interface CoreMergeOutputs {
  readonly merged: OutputHandle<'resource'>;
}

export interface LifiSwapOutputs {
  readonly amountOut: OutputHandle<'resource'>;
  readonly unspentIn: OutputHandle<'resource'>;
}

export interface CoreAddOutputs {
  readonly result: OutputHandle<'uint256'>;
}

export interface CoreSubtractOutputs {
  readonly result: OutputHandle<'uint256'>;
}

export interface CoreMultiplyOutputs {
  readonly result: OutputHandle<'uint256'>;
}

export interface CoreDivideDownOutputs {
  readonly result: OutputHandle<'uint256'>;
}

export interface CoreDivideUpOutputs {
  readonly result: OutputHandle<'uint256'>;
}

export interface CoreBpsDownOutputs {
  readonly result: OutputHandle<'uint256'>;
}

export interface CoreBpsUpOutputs {
  readonly result: OutputHandle<'uint256'>;
}

export interface CoreBalanceOfOutputs {
  readonly balance: OutputHandle<'resource'>;
}

export interface CoreTransferOutputs {
  readonly transferred: OutputHandle<'resource'>;
  readonly remainder: OutputHandle<'resource'>;
}

export interface CoreRawCallOutputs {
  readonly result: OutputHandle<'uint256'>;
}

export interface CoreAsResourceOutputs {
  readonly resource: OutputHandle<'resource'>;
}

export interface AaveBorrowOutputs {
  readonly borrowed: OutputHandle<'resource'>;
  readonly debtBalance: OutputHandle<'uint256'>;
}

export interface AaveRepayOutputs {
  readonly actualRepaid: OutputHandle<'uint256'>;
  readonly residual: OutputHandle<'resource'>;
}

export interface AaveRepayWithATokensOutputs {
  readonly actualRepaid: OutputHandle<'uint256'>;
  readonly residual: OutputHandle<'resource'>;
}

export interface AaveClaimRewardsOutputs {
  readonly claimed: OutputHandle<'resource'>;
  readonly claimedAmount: OutputHandle<'uint256'>;
}

export interface MorphoBlueWithdrawCollateralOutputs {
  readonly withdrawn: OutputHandle<'resource'>;
  readonly collateralWithdrawn: OutputHandle<'uint256'>;
}

export interface LifiZapOutputs {
  readonly amountOut: OutputHandle<'resource'>;
}

export interface ParaswapBuyOutputs {
  readonly amountOut: OutputHandle<'resource'>;
  readonly unspentIn: OutputHandle<'resource'>;
}

export interface CorePeekOutputs {
  readonly result: OutputHandle<'uint256'>;
}

export type GeneratedOps = {
  readonly core: {
    /** Split a resource into two outputs by basis-point ratio — original id: "core.split" */
    readonly split: (nodeId: string, args: CoreSplitArgs) => CoreSplitOutputs;
    /** Merge two same-token resources into one by addition — original id: "core.merge" */
    readonly merge: (nodeId: string, args: CoreMergeArgs) => CoreMergeOutputs;
    /** Add two unsigned integers (a + b) — original id: "core.add" */
    readonly add: (nodeId: string, args: CoreAddArgs) => CoreAddOutputs;
    /** Subtract b from a (a - b); reverts on underflow — original id: "core.subtract" */
    readonly subtract: (
      nodeId: string,
      args: CoreSubtractArgs,
    ) => CoreSubtractOutputs;
    /** Multiply two unsigned integers (a * b) — original id: "core.multiply" */
    readonly multiply: (
      nodeId: string,
      args: CoreMultiplyArgs,
    ) => CoreMultiplyOutputs;
    /** Divide a by b, rounding toward zero — original id: "core.divideDown" */
    readonly divideDown: (
      nodeId: string,
      args: CoreDivideDownArgs,
    ) => CoreDivideDownOutputs;
    /** Divide a by b, rounding away from zero — original id: "core.divideUp" */
    readonly divideUp: (
      nodeId: string,
      args: CoreDivideUpArgs,
    ) => CoreDivideUpOutputs;
    /** Multiply value by basis points and divide by 10000, rounding down — original id: "core.bpsDown" */
    readonly bpsDown: (
      nodeId: string,
      args: CoreBpsDownArgs,
    ) => CoreBpsDownOutputs;
    /** Multiply value by basis points and divide by 10000, rounding up — original id: "core.bpsUp" */
    readonly bpsUp: (nodeId: string, args: CoreBpsUpArgs) => CoreBpsUpOutputs;
    /** Assert a == b; reverts if not equal — original id: "core.assertEqual" */
    readonly assertEqual: (nodeId: string, args: CoreAssertEqualArgs) => void;
    /** Assert a != b; reverts if equal — original id: "core.assertNotEqual" */
    readonly assertNotEqual: (
      nodeId: string,
      args: CoreAssertNotEqualArgs,
    ) => void;
    /** Assert a > b; reverts if a <= b — original id: "core.assertGt" */
    readonly assertGt: (nodeId: string, args: CoreAssertGtArgs) => void;
    /** Assert a >= b; reverts if a < b — original id: "core.assertGte" */
    readonly assertGte: (nodeId: string, args: CoreAssertGteArgs) => void;
    /** Assert a < b; reverts if a >= b — original id: "core.assertLt" */
    readonly assertLt: (nodeId: string, args: CoreAssertLtArgs) => void;
    /** Assert a <= b; reverts if a > b — original id: "core.assertLte" */
    readonly assertLte: (nodeId: string, args: CoreAssertLteArgs) => void;
    /** Assert min <= value <= max; reverts if value is outside the range — original id: "core.assertInRange" */
    readonly assertInRange: (
      nodeId: string,
      args: CoreAssertInRangeArgs,
    ) => void;
    /** Approve an ERC20 spender for the given token and amount — original id: "core.approve" */
    readonly approve: (nodeId: string, args: CoreApproveArgs) => void;
    /** Read an ERC20 balance, producing a resource — original id: "core.balanceOf" */
    readonly balanceOf: (
      nodeId: string,
      args: CoreBalanceOfArgs,
    ) => CoreBalanceOfOutputs;
    /** Transfer tokens to a recipient address, optionally specifying a partial amount — original id: "core.transfer" */
    readonly transfer: (
      nodeId: string,
      args: CoreTransferArgs,
    ) => CoreTransferOutputs;
    /** Emit a custom on-chain event carrying 1 32-byte payload value. The value becomes a non-indexed data word in a fixed VM log event; the signature is hashed into a discriminator word (it is NOT an indexed EVM topic). — original id: "core.emitEvent1" */
    readonly emitEvent1: (nodeId: string, args: CoreEmitEvent1Args) => void;
    /** Emit a custom on-chain event carrying 2 32-byte payload values. The values become non-indexed data words in a fixed VM log event; the signature is hashed into a discriminator word (it is NOT an indexed EVM topic). — original id: "core.emitEvent2" */
    readonly emitEvent2: (nodeId: string, args: CoreEmitEvent2Args) => void;
    /** Emit a custom on-chain event carrying 3 32-byte payload values. The values become non-indexed data words in a fixed VM log event; the signature is hashed into a discriminator word (it is NOT an indexed EVM topic). — original id: "core.emitEvent3" */
    readonly emitEvent3: (nodeId: string, args: CoreEmitEvent3Args) => void;
    /** Emit a custom on-chain event carrying 4 32-byte payload values. The values become non-indexed data words in a fixed VM log event; the signature is hashed into a discriminator word (it is NOT an indexed EVM topic). — original id: "core.emitEvent4" */
    readonly emitEvent4: (nodeId: string, args: CoreEmitEvent4Args) => void;
    /** Invoke a smart contract function, optionally spending a token resource — original id: "core.call" */
    readonly call: <TSig extends string>(
      nodeId: string,
      args: CoreCallArgs<TSig>,
    ) => CoreCallResult<TSig>;
    /** Read from a smart contract at runtime (StaticCall); result is fresh at execution time — original id: "core.staticCall" */
    readonly staticCall: <TSig extends string>(
      nodeId: string,
      args: CoreStaticCallArgs<TSig>,
    ) => StaticCallResult<TSig>;
    /** Invoke a contract with pre-encoded calldata — original id: "core.rawCall" */
    readonly rawCall: (
      nodeId: string,
      args: CoreRawCallArgs,
    ) => CoreRawCallOutputs;
    /** Graduate a raw handle to a resource, enabling slippage surfacing and linearity tracking — original id: "core.asResource" */
    readonly asResource: (
      nodeId: string,
      args: CoreAsResourceArgs,
    ) => CoreAsResourceOutputs;
    /** Read a smart contract value at compile time (off-chain eth_call); result is baked as a literal — original id: "core.peek" */
    readonly peek: (nodeId: string, args: CorePeekArgs) => CorePeekOutputs;
  };
  readonly lifi: {
    /** Swap tokens via the LI.FI aggregator API — original id: "lifi.swap" */
    readonly swap: (nodeId: string, args: LifiSwapArgs) => LifiSwapOutputs;
    /** Route tokens into a DeFi protocol position via the edge catalog — original id: "lifi.zap" */
    readonly zap: (nodeId: string, args: LifiZapArgs) => LifiZapOutputs;
  };
  readonly invariant: {
    /** Assert that an account holds at least a minimum token balance — original id: "invariant.balanceAtLeast" */
    readonly balanceAtLeast: (
      nodeId: string,
      args: InvariantBalanceAtLeastArgs,
    ) => void;
    /** Assert that an account holds exactly an expected token balance — original id: "invariant.balanceEquals" */
    readonly balanceEquals: (
      nodeId: string,
      args: InvariantBalanceEqualsArgs,
    ) => void;
    /** Assert that an account holds at most a maximum token balance — original id: "invariant.balanceAtMost" */
    readonly balanceAtMost: (
      nodeId: string,
      args: InvariantBalanceAtMostArgs,
    ) => void;
    /** Assert that an account's token balance is between a minimum and a maximum (inclusive) — original id: "invariant.balanceInRange" */
    readonly balanceInRange: (
      nodeId: string,
      args: InvariantBalanceInRangeArgs,
    ) => void;
    /** Assert that a spender is permitted to move at least a minimum allowance on behalf of an owner — original id: "invariant.allowanceAtLeast" */
    readonly allowanceAtLeast: (
      nodeId: string,
      args: InvariantAllowanceAtLeastArgs,
    ) => void;
    /** Assert that a spender's allowance on behalf of an owner exactly equals an expected amount — original id: "invariant.allowanceEquals" */
    readonly allowanceEquals: (
      nodeId: string,
      args: InvariantAllowanceEqualsArgs,
    ) => void;
    /** Assert that a spender is permitted to move at most a maximum allowance on behalf of an owner — original id: "invariant.allowanceAtMost" */
    readonly allowanceAtMost: (
      nodeId: string,
      args: InvariantAllowanceAtMostArgs,
    ) => void;
    /** Assert that a spender's allowance on behalf of an owner is between a minimum and a maximum (inclusive) — original id: "invariant.allowanceInRange" */
    readonly allowanceInRange: (
      nodeId: string,
      args: InvariantAllowanceInRangeArgs,
    ) => void;
    /** Assert a uint256 value satisfies a comparison against a constant threshold; reverts on violation — original id: "invariant.numeric" */
    readonly numeric: (nodeId: string, args: InvariantNumericArgs) => void;
    /** Assert min <= value <= max against constant bounds; reverts if outside the range — original id: "invariant.numericInRange" */
    readonly numericInRange: (
      nodeId: string,
      args: InvariantNumericInRangeArgs,
    ) => void;
  };
  readonly aave: {
    /** Borrow an asset from an Aave v3 pool against existing collateral, exposing the borrowed asset as a Resource — original id: "aave.borrow" */
    readonly borrow: (
      nodeId: string,
      args: AaveBorrowArgs,
    ) => AaveBorrowOutputs;
    /** Repay an Aave v3 variable-rate debt position with the supplied asset. mode: 'exact' passes the input handle amount; mode: 'max' passes type(uint256).max so Aave's Pool clamps paybackAmount to userVariableDebt exactly. Any unspent input is returned through the residual port. — original id: "aave.repay" */
    readonly repay: (nodeId: string, args: AaveRepayArgs) => AaveRepayOutputs;
    /** Repay an Aave v3 variable-rate debt by burning the caller's aToken balance, returning any unspent residual — original id: "aave.repayWithATokens" */
    readonly repayWithATokens: (
      nodeId: string,
      args: AaveRepayWithATokensArgs,
    ) => AaveRepayWithATokensOutputs;
    /** Claim a specific Aave v3 incentives reward token against a set of receipt-token positions, exposing the claimed amount as a Resource — original id: "aave.claimRewards" */
    readonly claimRewards: (
      nodeId: string,
      args: AaveClaimRewardsArgs,
    ) => AaveClaimRewardsOutputs;
    /** Switch the executionAddress's Aave v3 eMode category. 0 disables eMode. The pool reverts if the switch would make the position unhealthy or if any open borrow is for an asset outside the target category. — original id: "aave.setEMode" */
    readonly setEMode: (nodeId: string, args: AaveSetEModeArgs) => void;
  };
  readonly morphoBlue: {
    /** Deposit the collateral asset of a Morpho Blue market on behalf of the execution proxy. mode: 'exact' pulls the input handle's amount. mode: 'all' reads the proxy's current ERC20 balance of the market's collateral token and pulls that amount, ignoring the input handle's literal value — note this pulls the proxy's total balance (including unrelated upstream residuals), not just the input port's delivery. Credits Position.collateral on the Morpho singleton; emits no return value and exposes no resource output (the collateral is non-transferable accounting state). — original id: "morphoBlue.supplyCollateral" */
    readonly supplyCollateral: (
      nodeId: string,
      args: MorphoBlueSupplyCollateralArgs,
    ) => void;
    /** Withdraw collateral from a Morpho Blue market position to the receiver address. Exposes the withdrawn ERC20 amount as a Resource output. — original id: "morphoBlue.withdrawCollateral" */
    readonly withdrawCollateral: (
      nodeId: string,
      args: MorphoBlueWithdrawCollateralArgs,
    ) => MorphoBlueWithdrawCollateralOutputs;
  };
  readonly paraswap: {
    /** Exact-output (BUY) swap via the Paraswap/Velora Market API: produce exactly `exactAmountOut` of the destination token, pulling only the source needed and exposing the genuinely-unspent source as `unspentIn`. — original id: "paraswap.buy" */
    readonly buy: (nodeId: string, args: ParaswapBuyArgs) => ParaswapBuyOutputs;
  };
};

export const bindGeneratedOps = (
  builder: FlowBuilderInternal,
): GeneratedOps => ({
  core: {
    split: (nodeId: string, args: CoreSplitArgs) =>
      builder.call(nodeId, 'core.split', args, {
        a: 'resource',
        b: 'resource',
      } as const),
    merge: (nodeId: string, args: CoreMergeArgs) =>
      builder.call(nodeId, 'core.merge', { ...args, config: {} }, {
        merged: 'resource',
      } as const),
    add: (nodeId: string, args: CoreAddArgs) =>
      builder.call(nodeId, 'core.add', { ...args, config: {} }, {
        result: 'uint256',
      } as const),
    subtract: (nodeId: string, args: CoreSubtractArgs) =>
      builder.call(nodeId, 'core.subtract', { ...args, config: {} }, {
        result: 'uint256',
      } as const),
    multiply: (nodeId: string, args: CoreMultiplyArgs) =>
      builder.call(nodeId, 'core.multiply', { ...args, config: {} }, {
        result: 'uint256',
      } as const),
    divideDown: (nodeId: string, args: CoreDivideDownArgs) =>
      builder.call(nodeId, 'core.divideDown', { ...args, config: {} }, {
        result: 'uint256',
      } as const),
    divideUp: (nodeId: string, args: CoreDivideUpArgs) =>
      builder.call(nodeId, 'core.divideUp', { ...args, config: {} }, {
        result: 'uint256',
      } as const),
    bpsDown: (nodeId: string, args: CoreBpsDownArgs) =>
      builder.call(nodeId, 'core.bpsDown', args, {
        result: 'uint256',
      } as const),
    bpsUp: (nodeId: string, args: CoreBpsUpArgs) =>
      builder.call(nodeId, 'core.bpsUp', args, { result: 'uint256' } as const),
    assertEqual: (nodeId: string, args: CoreAssertEqualArgs) =>
      builder.call(nodeId, 'core.assertEqual', { ...args, config: {} }, {}),
    assertNotEqual: (nodeId: string, args: CoreAssertNotEqualArgs) =>
      builder.call(nodeId, 'core.assertNotEqual', { ...args, config: {} }, {}),
    assertGt: (nodeId: string, args: CoreAssertGtArgs) =>
      builder.call(nodeId, 'core.assertGt', { ...args, config: {} }, {}),
    assertGte: (nodeId: string, args: CoreAssertGteArgs) =>
      builder.call(nodeId, 'core.assertGte', { ...args, config: {} }, {}),
    assertLt: (nodeId: string, args: CoreAssertLtArgs) =>
      builder.call(nodeId, 'core.assertLt', { ...args, config: {} }, {}),
    assertLte: (nodeId: string, args: CoreAssertLteArgs) =>
      builder.call(nodeId, 'core.assertLte', { ...args, config: {} }, {}),
    assertInRange: (nodeId: string, args: CoreAssertInRangeArgs) =>
      builder.call(nodeId, 'core.assertInRange', { ...args, config: {} }, {}),
    approve: (nodeId: string, args: CoreApproveArgs) =>
      builder.call(nodeId, 'core.approve', args, {}),
    balanceOf: (nodeId: string, args: CoreBalanceOfArgs) =>
      builder.call(nodeId, 'core.balanceOf', args, {
        balance: 'resource',
      } as const),
    transfer: (nodeId: string, args: CoreTransferArgs) =>
      builder.call(nodeId, 'core.transfer', args, {
        transferred: 'resource',
        remainder: 'resource',
      } as const),
    emitEvent1: (nodeId: string, args: CoreEmitEvent1Args) =>
      builder.call(nodeId, 'core.emitEvent1', args, {}),
    emitEvent2: (nodeId: string, args: CoreEmitEvent2Args) =>
      builder.call(nodeId, 'core.emitEvent2', args, {}),
    emitEvent3: (nodeId: string, args: CoreEmitEvent3Args) =>
      builder.call(nodeId, 'core.emitEvent3', args, {}),
    emitEvent4: (nodeId: string, args: CoreEmitEvent4Args) =>
      builder.call(nodeId, 'core.emitEvent4', args, {}),
    call: <TSig extends string>(nodeId: string, args: CoreCallArgs<TSig>) => {
      const wire = buildCallWireFormat({
        resource: args.resource,
        bind: args.bind as Record<string, AnyBindable>,
        config: args.config as Record<string, unknown>,
        guards: args.guards,
      });
      return builder.call(nodeId, wire.op, wire, {
        result: 'uint256',
      } as const) as unknown as CoreCallResult<TSig>;
    },
    staticCall: <TSig extends string>(
      nodeId: string,
      args: CoreStaticCallArgs<TSig>,
    ) =>
      builder.call(
        nodeId,
        'core.staticCall',
        buildStaticCallWireFormat({
          bind: args.bind as Record<string, AnyBindable>,
          config: args.config as Record<string, unknown>,
          guards: args.guards,
        }),
        { result: 'uint256' } as const,
      ) as unknown as StaticCallResult<TSig>,
    rawCall: (nodeId: string, args: CoreRawCallArgs) =>
      builder.call(nodeId, 'core.rawCall', args, {
        result: 'uint256',
      } as const),
    asResource: (nodeId: string, args: CoreAsResourceArgs) =>
      builder.call(nodeId, 'core.asResource', args, {
        resource: 'resource',
      } as const),
    peek: (nodeId: string, args: CorePeekArgs) =>
      builder.call(nodeId, 'core.peek', args, { result: 'uint256' } as const),
  },
  lifi: {
    swap: (nodeId: string, args: LifiSwapArgs) =>
      builder.call(nodeId, 'lifi.swap', args, {
        amountOut: 'resource',
        unspentIn: 'resource',
      } as const),
    zap: (nodeId: string, args: LifiZapArgs) =>
      builder.call(nodeId, 'lifi.zap', args, {
        amountOut: 'resource',
      } as const),
  },
  invariant: {
    balanceAtLeast: (nodeId: string, args: InvariantBalanceAtLeastArgs) =>
      builder.call(
        nodeId,
        'invariant.balanceAtLeast',
        { ...args, config: {} },
        {},
      ),
    balanceEquals: (nodeId: string, args: InvariantBalanceEqualsArgs) =>
      builder.call(
        nodeId,
        'invariant.balanceEquals',
        { ...args, config: {} },
        {},
      ),
    balanceAtMost: (nodeId: string, args: InvariantBalanceAtMostArgs) =>
      builder.call(
        nodeId,
        'invariant.balanceAtMost',
        { ...args, config: {} },
        {},
      ),
    balanceInRange: (nodeId: string, args: InvariantBalanceInRangeArgs) =>
      builder.call(
        nodeId,
        'invariant.balanceInRange',
        { ...args, config: {} },
        {},
      ),
    allowanceAtLeast: (nodeId: string, args: InvariantAllowanceAtLeastArgs) =>
      builder.call(
        nodeId,
        'invariant.allowanceAtLeast',
        { ...args, config: {} },
        {},
      ),
    allowanceEquals: (nodeId: string, args: InvariantAllowanceEqualsArgs) =>
      builder.call(
        nodeId,
        'invariant.allowanceEquals',
        { ...args, config: {} },
        {},
      ),
    allowanceAtMost: (nodeId: string, args: InvariantAllowanceAtMostArgs) =>
      builder.call(
        nodeId,
        'invariant.allowanceAtMost',
        { ...args, config: {} },
        {},
      ),
    allowanceInRange: (nodeId: string, args: InvariantAllowanceInRangeArgs) =>
      builder.call(
        nodeId,
        'invariant.allowanceInRange',
        { ...args, config: {} },
        {},
      ),
    numeric: (nodeId: string, args: InvariantNumericArgs) =>
      builder.call(nodeId, 'invariant.numeric', args, {}),
    numericInRange: (nodeId: string, args: InvariantNumericInRangeArgs) =>
      builder.call(nodeId, 'invariant.numericInRange', args, {}),
  },
  aave: {
    borrow: (nodeId: string, args: AaveBorrowArgs) =>
      builder.call(nodeId, 'aave.borrow', args, {
        borrowed: 'resource',
        debtBalance: 'uint256',
      } as const),
    repay: (nodeId: string, args: AaveRepayArgs) =>
      builder.call(nodeId, 'aave.repay', args, {
        actualRepaid: 'uint256',
        residual: 'resource',
      } as const),
    repayWithATokens: (nodeId: string, args: AaveRepayWithATokensArgs) =>
      builder.call(nodeId, 'aave.repayWithATokens', args, {
        actualRepaid: 'uint256',
        residual: 'resource',
      } as const),
    claimRewards: (nodeId: string, args: AaveClaimRewardsArgs) =>
      builder.call(nodeId, 'aave.claimRewards', args, {
        claimed: 'resource',
        claimedAmount: 'uint256',
      } as const),
    setEMode: (nodeId: string, args: AaveSetEModeArgs) =>
      builder.call(nodeId, 'aave.setEMode', args, {}),
  },
  morphoBlue: {
    supplyCollateral: (nodeId: string, args: MorphoBlueSupplyCollateralArgs) =>
      builder.call(nodeId, 'morphoBlue.supplyCollateral', args, {}),
    withdrawCollateral: (
      nodeId: string,
      args: MorphoBlueWithdrawCollateralArgs,
    ) =>
      builder.call(nodeId, 'morphoBlue.withdrawCollateral', args, {
        withdrawn: 'resource',
        collateralWithdrawn: 'uint256',
      } as const),
  },
  paraswap: {
    buy: (nodeId: string, args: ParaswapBuyArgs) =>
      builder.call(nodeId, 'paraswap.buy', args, {
        amountOut: 'resource',
        unspentIn: 'resource',
      } as const),
  },
});
