import type { Abi, Address, Hash, Hex, StateOverride, TypedDataDomain, TypedDataParameter } from "viem"; import type { Account, IHasVaultAddress } from "../../entities/Account.js"; import type { SwapQuote } from "../swapService/index.js"; import type { EVCBatchItem, TransactionPlan } from "../executionService/index.js"; export type PositionMigrationDirection = "external-to-euler" | "euler-to-external"; export type MigrationAssetAmount = { asset: Address; amount: bigint; shares?: bigint; }; export type MigrationPosition = { connectorId: string; protocol: string; id: string; chainId: number; owner: Address; ref: TPositionRef; debt: MigrationAssetAmount; collateral: MigrationAssetAmount; raw: TRaw; }; export type MigrationTargetAsset = { asset: Address; symbol?: string; decimals?: number; }; export type MigrationTarget = { connectorId: string; protocol: string; id: string; chainId: number; ref: TPositionRef; debt: MigrationTargetAsset; collateral: MigrationTargetAsset; liquidity?: MigrationAssetAmount; raw?: TRaw; extraData?: TExtraData; }; export type TypedDataMigrationAuthorizationRequest = Record> = { kind: "typedData"; connectorId: string; protocol: string; chainId: number; owner: Address; positionId?: string; typedData: { domain: TypedDataDomain; types: Record; primaryType: string; message: TMessage; }; postMigrationAuthorization?: MigrationAuthorizationRequest; }; /** * Form an authorization is expressed in. * * `typedData` is an EIP-712 message the owner signs, embedded into the * migration batch. `transaction` is a `msg.sender`-authenticated call the owner * sends themselves. */ export type MigrationAuthorizationKind = "typedData" | "transaction"; export type MigrationAuthorizationCall = { to: Address; abi: Abi; functionName: string; args: readonly unknown[]; value?: bigint; }; type TransactionMigrationAuthorizationRequestBase = { kind: "transaction"; connectorId: string; protocol: string; chainId: number; owner: Address; positionId?: string; postMigrationAuthorization?: MigrationAuthorizationRequest; }; export type TransactionMigrationAuthorizationRequest = TransactionMigrationAuthorizationRequestBase & ({ /** * The grant. It must be mined before * {@link IPositionMigrationService.buildMigrationBatch} runs — * connectors read the live allowance to decide whether the batch * still needs an authorization item. * * Cannot be an EVC batch item: the EVC forwards batch items with * itself as `msg.sender`, so the grant would come from the EVC rather * than the owner. */ call: MigrationAuthorizationCall; /** * Restores or removes the authorization after the migration has a known * terminal outcome or is known not to have been dispatched. */ revocation?: MigrationAuthorizationCall; } | { /** Omitted because the required authorization is already active. */ call?: undefined; /** Removes or restores the already-active authorization. */ revocation: MigrationAuthorizationCall; }); export type MigrationAuthorizationRequest = TypedDataMigrationAuthorizationRequest | TransactionMigrationAuthorizationRequest; export type SignedMigrationAuthorization = { request: TRequest; signature?: Hex; data?: unknown; postMigrationAuthorization?: SignedMigrationAuthorization; }; export type EulerMigrationTarget = { eulerAccount: Address; borrowVault?: Address; collateralVault: Address; swapper?: Address; borrowAmount?: bigint; interestBufferBps?: bigint; minCollateralAssets?: bigint; enableController?: boolean; enableCollateral?: boolean; /** * How swapped collateral is verified and credited to the target vault: * `skim` (default) routes the swap output to the vault and skims it — * EVault targets only. `deposit` routes the output to the SwapVerifier and * deposits it via `verifyAmountMinAndDeposit`, which works for any ERC-4626 * target (e.g. EulerEarn); it requires a supply-only migration and a quote * requested with `transferOutputToReceiver`. */ collateralSwapVerification?: "skim" | "deposit"; }; export type EulerMigrationSource = { eulerAccount: Address; borrowVault: Address; collateralVault: Address; swapper?: Address; debtAmount?: bigint; collateralAmount?: bigint; collateralShares?: bigint; }; export type ExternalMigrationTarget = { positionRef?: TPositionRef; borrowAmount?: bigint; collateralAmount?: bigint; repayAmount?: bigint; interestBufferBps?: bigint; }; export type ListMigrationPositionsArgs = { connectorId?: string; chainId: number; owner: Address; positionRefs?: readonly TPositionRef[]; }; export type ListMigrationTargetsArgs = { connectorId?: string; chainId: number; direction?: PositionMigrationDirection; debtAsset: Address; collateralAsset: Address; minLiquidity?: bigint; }; export type GetMigrationPositionArgs = { connectorId: string; chainId: number; owner: Address; positionRef: TPositionRef; }; export type GetMigrationAuthorizationArgs = { direction: PositionMigrationDirection; connectorId: string; chainId: number; owner: Address; position?: TPosition; positionRef?: unknown; target?: EulerMigrationTarget; source?: EulerMigrationSource; externalTarget?: ExternalMigrationTarget; deadline?: bigint; /** * Form to return the authorization in. Defaults to `"typedData"`. * * Use `"transaction"` for wallets that cannot produce an ECDSA signature: * Aave, Morpho, and MetaMorpho verify their permit / delegation / * authorization signatures without an ERC-1271 fallback, so a contract * wallet can never satisfy the typed-data form. * * Built-in transaction requests carry a `revocation` to send after the * migration has a known terminal or no-dispatch outcome and, when a grant is * required, a `call` to send before building the batch. If core dispatch or * receipt status is unknown, reconcile it before revoking. `deadline` and * `removeAuthorizationAfterMigration` do not apply: a `msg.sender` grant * carries no expiry, and the revocation is always returned. Pass * `removeAuthorizationAfterMigration: false` to `buildMigrationBatch`, * whose in-batch disable needs a signature this form cannot supply. */ authorizationKind?: MigrationAuthorizationKind; removeAuthorizationAfterMigration?: boolean; /** Account snapshot used when authorization amounts depend on Euler source state. */ account?: Account; }; export type BuildMigrationBatchArgs = { direction: PositionMigrationDirection; connectorId: string; chainId: number; owner: Address; position?: TPosition; positionRef?: unknown; target?: EulerMigrationTarget; source?: EulerMigrationSource; externalTarget?: ExternalMigrationTarget; authorizationRequest?: MigrationAuthorizationRequest; authorization?: SignedMigrationAuthorization; /** * Internal simulation hint: when a caller already resolved that an * authorization is required and supplied `authorization`, connectors can add * the authorization item without re-reading the live authorization state. */ skipAuthorizationCheck?: boolean; collateralSwapQuote?: SwapQuote; debtSwapQuote?: SwapQuote; deadline?: bigint; validateEulerVaults?: boolean; removeAuthorizationAfterMigration?: boolean; /** Account snapshot used to derive outgoing Euler cleanup actions. */ account?: Account; /** * For euler-to-external migrations, move secondary Euler collateral vault * shares from the source sub-account to the owner account after the debt is * repaid. The source borrow controller is disabled for all outgoing * migrations regardless of this flag. */ cleanupEulerPosition?: boolean; }; export type PlanMigrationArgs = BuildMigrationBatchArgs & { operationName?: string; /** Authorization form to resolve when planning a simulation. */ authorizationKind?: MigrationAuthorizationKind; }; export type PlanMigrationSimulationResult = { plan: TransactionPlan; stateOverrides: StateOverride; /** * The full migration plan including authorization items carrying placeholder * (stub) signatures — or the caller-provided signed authorization when one * was passed. Suitable for calldata preview/display without a second * `planMigration` round trip; the batch is built exactly once for both plans. */ previewPlan: TransactionPlan; /** * The authorization request that must be signed at execution time, if any. * Resolved internally when the caller did not provide one, so consumers can * reuse it (e.g. for signature-step display) without a separate * `getAuthorization` call. */ authorizationRequest?: MigrationAuthorizationRequest; }; export type PrepareMigrationAuthorizationSlotsArgs = { previewPlan: TransactionPlan; authorizationRequest: MigrationAuthorizationRequest; }; /** * Migration insertion metadata that the application must cover with its * accepted review digest before passing it back to the SDK. The SDK validates * its structure but does not authenticate its provenance. */ export type MigrationAuthorizationSlot = { /** Index in the complete grant/post-migration authorization chain. */ authorizationRequestIndex: number; planItemIndex: number; /** Index in the flattened EVC batch entry list. */ batchItemIndex: number; typedDataHash: Hash; /** Hash of the complete reviewed batch item with its stub signature. */ reviewedItemHash: Hash; /** * Opaque application-authenticated metadata, not an independently trusted * SDK capability. */ abiArgumentPath: readonly (string | number)[]; }; export type BuildConnectorMigrationBatchArgs = Omit, "connectorId" | "validateEulerVaults"> & { position: TPosition; }; export type PositionMigrationConnectorMetadata = { id: string; protocol: string; name: string; }; export interface PositionMigrationConnector extends PositionMigrationConnectorMetadata { getProtocolAddress?(chainId: number): Address | undefined; listPositions?(args: ListMigrationPositionsArgs): Promise; listTargets?(args: ListMigrationTargetsArgs): Promise[]>; getPosition(args: GetMigrationPositionArgs): Promise; getAuthorization?(args: GetMigrationAuthorizationArgs): Promise; buildMigrationBatch(args: BuildConnectorMigrationBatchArgs): Promise | EVCBatchItem[]; } export type PositionMigrationServiceConfig = { includeDefaultConnectors?: boolean; connectors?: PositionMigrationConnector[]; }; export interface IPositionMigrationService { getConnectors(): PositionMigrationConnectorMetadata[]; registerConnector(connector: PositionMigrationConnector): void; getConnector(connectorId: string): PositionMigrationConnector; getConnectorProtocolAddress(connectorId: string, chainId: number): Address | undefined; listPositions(args: ListMigrationPositionsArgs): Promise; listTargets(args: ListMigrationTargetsArgs): Promise; getPosition(args: GetMigrationPositionArgs): Promise; getAuthorization(args: GetMigrationAuthorizationArgs): Promise; buildMigrationBatch(args: BuildMigrationBatchArgs): Promise; planMigration(args: PlanMigrationArgs): Promise; planMigrationSimulation(args: PlanMigrationArgs): Promise; prepareMigrationAuthorizationSlots(args: PrepareMigrationAuthorizationSlotsArgs): Promise; } export {}; //# sourceMappingURL=positionMigrationServiceTypes.d.ts.map