import {z} from 'zod' export type V2StellarTransactionMemoTypeEnum = 'TEXT' | 'ID' | 'HASH' | 'RETURN'; export type V2StellarTransactionMemo = {type: V2StellarTransactionMemoTypeEnum, data: string}; export type AssetTransferStellarOptions = {memo?: V2StellarTransactionMemo | undefined}; export type AssetTransferXRPLOptions = {destinationTag?: string | undefined}; export type V2AssetTransfer = {asset: string, amount: string, source: string, destination: string, payFeeFromAmount?: boolean | undefined, memo?: string | undefined, sponsor?: string | undefined, stellarOptions?: AssetTransferStellarOptions | undefined, xrplOptions?: AssetTransferXRPLOptions | undefined}; export type BatchAssetTransferBatchTransferDestination = {destination: string, amount: string, note?: string | undefined}; export type V2BatchAssetTransfer = {asset: string, source: string, destinations: Array}; export type V2EVMPriority = {gasLimit?: unknown | undefined, gasPrice?: string | undefined, maxPriorityFeePerGas?: string | undefined, maxFeePerGas?: string | undefined}; export type V2EVMTransactionParams = {gasSettings?: V2EVMPriority | undefined, nonce?: string | undefined}; export type Apiv2EVMTransactionAuthorization = {address: string, chainId: string, nonce: unknown, signature: string}; export type Apiv2EVMTransactionAuthorizationDetails = {authorizationList: Array}; export type Apiv2EVMTransaction = {network: string, fromAddress: string, toAddress?: string | undefined, value?: string | undefined, data?: string | undefined, overrideParams?: V2EVMTransactionParams | undefined, authorizationDetails?: Apiv2EVMTransactionAuthorizationDetails | undefined, publish?: boolean | undefined, sponsor?: string | undefined}; export type V2TronTriggerSmartContract = {network: string, ownerAddress: string, contractAddress: string, callValue?: unknown | undefined, data?: string | undefined}; export type Apiv2TronTransactionTriggerSmartContract = {ownerAddress: string, contractAddress: string, callValue?: unknown | undefined, data?: string | undefined}; export type Apiv2TronTransactionTronResourceEnum = 'BANDWIDTH' | 'ENERGY'; export type Apiv2TronTransactionFreezeBalanceV2 = {ownerAddress: string, amount: string, resource: Apiv2TronTransactionTronResourceEnum}; export type Apiv2TronTransactionUnfreezeBalanceV2 = {ownerAddress: string, amount: string, resource: Apiv2TronTransactionTronResourceEnum}; export type Apiv2TronTransactionWithdrawExpireUnfreeze = {ownerAddress: string}; export type Apiv2TronTransactionDelegateResource = {ownerAddress: string, resource: Apiv2TronTransactionTronResourceEnum, amount: string, receiverAddress: string, lock?: boolean | undefined, lockPeriod?: string | undefined}; export type Apiv2TronTransactionUnDelegateResource = {ownerAddress: string, resource: Apiv2TronTransactionTronResourceEnum, amount: string, receiverAddress: string}; export type Apiv2TronTransactionCancelAllUnfreezeV2 = {ownerAddress: string}; export type Apiv2TronTransactionVoteWitnessVote = {voteAddress: string, voteCount: string}; export type Apiv2TronTransactionVoteWitness = {ownerAddress: string, votes: Array}; export type Apiv2TronTransactionWithdrawBalance = {ownerAddress: string}; export type Apiv2TronTransaction = {network: string, publish?: boolean | undefined, triggerSmartContract?: Apiv2TronTransactionTriggerSmartContract | undefined, freezeBalanceV2?: Apiv2TronTransactionFreezeBalanceV2 | undefined, unfreezeBalanceV2?: Apiv2TronTransactionUnfreezeBalanceV2 | undefined, withdrawExpireUnfreeze?: Apiv2TronTransactionWithdrawExpireUnfreeze | undefined, delegateResource?: Apiv2TronTransactionDelegateResource | undefined, undelegateResource?: Apiv2TronTransactionUnDelegateResource | undefined, cancelAllUnfreezeV2?: Apiv2TronTransactionCancelAllUnfreezeV2 | undefined, voteWitness?: Apiv2TronTransactionVoteWitness | undefined, withdrawBalance?: Apiv2TronTransactionWithdrawBalance | undefined}; export type EVMUtilaDelegatedCallsCallRaw = {toAddress: string, value?: string | undefined, data?: string | undefined}; export type V2EVMUtilaDelegatedCallsCall = {raw: EVMUtilaDelegatedCallsCallRaw}; export type V2EVMUtilaDelegatedCallsSubmissionDetails = {sponsorAddress?: string | undefined}; export type V2EVMUtilaDelegatedCalls = {network?: string | undefined, fromAddress?: string | undefined, calls?: Array | undefined, deadlineUnix?: string | undefined, submissionDetails?: V2EVMUtilaDelegatedCallsSubmissionDetails | undefined}; export type V2BTCTransferUTXO = {txHash: string, vout: number}; export type BTCTransferInputSource = {source: string}; export type BTCTransferOutput = {destination: string, amount: string, payFeeFromAmount?: boolean | undefined}; export type BTCTransferChangeOutput = {address: string}; export type BTCTransferFeeSettings = {feeRate: string}; export type V2BTCTransfer = {network: string, inputs?: Array | undefined, inputSources?: Array | undefined, outputs: Array, changeOutputs?: Array | undefined, feeSettings?: BTCTransferFeeSettings | undefined}; export type V2EstimateTransactionFeeRequestDetails = {assetTransfer?: V2AssetTransfer | undefined, assetBatchTransfer?: V2BatchAssetTransfer | undefined, evmTransaction?: Apiv2EVMTransaction | undefined, tronTriggerSmartContract?: V2TronTriggerSmartContract | undefined, tronTransaction?: Apiv2TronTransaction | undefined, evmUtilaDelegatedCalls?: V2EVMUtilaDelegatedCalls | undefined, btcTransfer?: V2BTCTransfer | undefined}; export type V2TransactionPriorityEnum = 'LOW' | 'NORMAL' | 'HIGH'; export type TransactionsEstimateTransactionFeeBody = {details: V2EstimateTransactionFeeRequestDetails, priority?: V2TransactionPriorityEnum | undefined}; export type CreateApiV2VaultsVaultIdTransactionsEstimateFeeArgs = {vault_id: string, body: TransactionsEstimateTransactionFeeBody}; export type CreateApiV2VaultsVaultIdTransactionsEstimateFeeOptions = {baseUrl?: string | undefined, bearerAuth?: string | undefined, fetch?: typeof fetch | undefined}; export const v2EVMFeeEstimation = z.object({gasUsed: z.string().optional(), gasPrice: z.string().optional()}); export const v2ConvertedValue = z.object({amount: z.string().optional(), currencyCode: z.string().optional()}); export const v2TronResourceFee = z.object({consumed: z.string().optional(), burned: z.string().optional(), convertedBurned: v2ConvertedValue.optional()}); export const v2TronAccountActivationFee = z.object({fee: z.string().optional(), convertedFee: v2ConvertedValue.optional()}); export const v2TronFeeEstimation = z.object({bandwidthUsed: z.string().optional(), energyUsed: z.string().optional(), totalSunUsed: z.string().optional(), bandwidth: v2TronResourceFee.optional(), energy: v2TronResourceFee.optional(), accountActivationFee: v2TronAccountActivationFee.optional()}); export const v2EstimateTransactionFeeResponse = z.object({evmFee: v2EVMFeeEstimation.optional(), tronFee: v2TronFeeEstimation.optional(), totalFee: z.string().optional(), convertedTotalFee: v2ConvertedValue.optional(), gasless: z.boolean().optional()}); export const validateResponse = async ( schema: { readonly '~standard': { readonly validate: (value: unknown) => ({ readonly value: Output; readonly issues?: undefined } | { readonly issues: ReadonlyArray<{ readonly message: string; readonly path?: ReadonlyArray | undefined }> }) | Promise<{ readonly value: Output; readonly issues?: undefined } | { readonly issues: ReadonlyArray<{ readonly message: string; readonly path?: ReadonlyArray | undefined }> }> } }, value: unknown ): Promise => { const result = await schema['~standard'].validate(value) if (result.issues !== undefined) { const detail = result.issues .map(({ message, path }) => path?.length ? `${path.map((segment) => String(typeof segment === 'object' ? segment.key : segment)).join('.')}: ${message}` : message ) .join('; ') throw new Error(`Response does not match the schema: ${detail}`, { cause: { issues: result.issues } }) } return result.value }; /** * EstimateTransactionFee * * POST /v2/vaults/{vault_id}/transactions:estimateFee */ export const createApiV2VaultsVaultIdTransactionsEstimateFee = async (args: CreateApiV2VaultsVaultIdTransactionsEstimateFeeArgs, options?: CreateApiV2VaultsVaultIdTransactionsEstimateFeeOptions) => { const {baseUrl = "https://api.utila.io", fetch: fetchFn = fetch, bearerAuth} = options ?? {} const query = new URLSearchParams() const headers = new Headers() headers.set('content-type', "application/json") headers.set('accept', "application/json") if (bearerAuth !== undefined) headers.set('authorization', `Bearer ${bearerAuth}`) const url = `${baseUrl.replace(/\/+$/, '')}/v2/vaults/${encodeURIComponent(String(args.vault_id))}/transactions:estimateFee${query.size > 0 ? `?${query}` : ''}` const res = await fetchFn(url, {method: "POST", headers, body: JSON.stringify(args.body)}) if (!res.ok) throw new Error(`Request failed with status ${res.status}`, {cause: {status: res.status, body: await res.text()}}) return validateResponse(v2EstimateTransactionFeeResponse, await res.json()) };