UNPKG

@robertprp/intents-sdk

Version:

Shogun Network Intent-based cross-chain swaps SDK

123 lines (108 loc) 4.16 kB
import { type Address } from 'viem'; import { type SupportedEvmChain } from '../../chains.js'; import type { EVMConfig } from '../../config.js'; import { SINGLE_CHAIN_GUARD_ADDRESSES, CROSS_CHAIN_GUARD_ADDRESSES, MAX_UINT_32 } from '../../constants.js'; import { getEVMCrossChainOrderTypedData, getEVMSingleChainOrderTypedData } from './order-signature.js'; import { type CrossChainPermitTransferFrom, type SingleChainPermitTransferFrom, type TransferData } from './permit2.js'; import { ChainProvider } from './chain-provider.js'; import type { CrossChainOrder } from '../orders/cross-chain.js'; import type { SingleChainOrder } from '../orders/single-chain.js'; import type { CrossChainOrderPrepared, SingleChainOrderPrepared } from '../../types/intent.js'; export class EVMIntentProvider { provider: ChainProvider; constructor(config: EVMConfig) { this.provider = new ChainProvider(config); } async prepareSingleChainOrder(order: SingleChainOrder): Promise<SingleChainOrderPrepared> { const { orderTypedData: dataToSign, nonce } = await getEVMSingleChainOrderTypedData(order); const signature = await this.provider.walletClient.signTypedData({ message: dataToSign.message, primaryType: dataToSign.primaryType, types: dataToSign.types, domain: dataToSign.domain, account: this.provider.getAccount(), }); return { order, preparedData: { nonce: nonce.toString(), signature: signature.slice(2), }, }; } async prepareCrossChainOrder(order: CrossChainOrder): Promise<CrossChainOrderPrepared> { const { orderTypedData: dataToSign, nonce } = await getEVMCrossChainOrderTypedData(order); const signature = await this.provider.walletClient.signTypedData({ message: dataToSign.message, primaryType: dataToSign.primaryType, types: dataToSign.types, domain: dataToSign.domain, account: this.provider.getAccount(), }); return { order, preparedData: { nonce: nonce.toString(), signature: signature.slice(2), }, }; } static getCrossChainPermissionMessage(order: CrossChainOrder, nonce: bigint): CrossChainPermitTransferFrom { const spender = CROSS_CHAIN_GUARD_ADDRESSES[order.sourceChainId as SupportedEvmChain] as Address; return { permitted: { token: order.sourceTokenAddress as Address, amount: order.sourceTokenAmount, }, spender, nonce, deadline: BigInt(order.deadline), witness: { user: order.user as Address, tokenIn: order.sourceTokenAddress as Address, srcChainId: order.sourceChainId, deadline: order.deadline, amountIn: order.sourceTokenAmount, minStablecoinsAmount: order.minStablecoinAmount, nonce, executionDetailsHash: order.getExecutionDetailsHash(), }, }; } static getSingleChainLimitPermissionMessage(order: SingleChainOrder, nonce: bigint): SingleChainPermitTransferFrom { const spender = SINGLE_CHAIN_GUARD_ADDRESSES[order.chainId as SupportedEvmChain] as Address; const requestedOutput: TransferData = { token: order.tokenOut as Address, receiver: order.destinationAddress as Address, amount: order.amountOutMin, }; const extraTransfers: TransferData[] = order.extraTransfers?.map((transfer) => ({ token: transfer.token as Address, receiver: transfer.receiver as Address, amount: transfer.amount, })) || []; return { permitted: { token: order.tokenIn as Address, amount: order.amountIn, }, spender, nonce, deadline: BigInt(order.deadline), witness: { user: order.user as Address, tokenIn: order.tokenIn as Address, amountIn: order.amountIn, requestedOutput, encodedExternalCallData: '0x', // TODO: Update when external call data is supported extraTransfers, deadline: order.deadline, nonce, }, }; } static getRandomNonce(): bigint { return BigInt(Math.floor(Math.random() * Number(MAX_UINT_32))); } }