import {z} from 'zod' export type ProxyRegionDTO = {id: number, name?: string | undefined}; export type ProxyDTO = {id?: number | undefined, ipAddress?: string | undefined, region?: ProxyRegionDTO | undefined, usedByAccounts?: Array | undefined}; export type CopierDuplicationDTO = {directCopiers?: number | undefined, fromAccount?: string | undefined, fromAccountId?: string | undefined, strategies?: Array | undefined}; export type ExpertAdvisorResourceDTO = {cpuPercent?: number | undefined, featureId?: string | undefined, lastError?: string | undefined, memoryBytes?: number | undefined, restartCount?: number | undefined, state?: ('STOPPED' | 'STARTING' | 'RUNNING' | 'ERROR') | undefined}; export type MissingSymbolMappingDTO = {copierId?: string | undefined, fromAccount?: string | undefined, fromAccountId?: string | undefined, lastTimestampDetected?: number | undefined, symbol?: string | undefined}; export type ApprovalDTO = {accountFromId: string, ticket: number, volume?: number | undefined}; export type ProfitTargetStatusDTO = {balanceLastUpdate?: string | undefined, lossLimitIsHit?: boolean | undefined, profitTargetFeatureId?: string | undefined, profitTargetIsHit?: boolean | undefined, referenceBalance?: number | undefined}; export type RiskLimitStatusDTO = {balanceLastUpdate?: string | undefined, copierId?: string | undefined, limitIsHit?: boolean | undefined, referenceBalance?: number | undefined, riskLimitId?: string | undefined, scope?: ('ACCOUNT' | 'COPIER') | undefined}; export type WalletDTO = {asset?: string | undefined, balance?: number | undefined}; export type AccountInformationDTO = {accountDuplicationInProjectDetected?: boolean | undefined, accountMode?: ('NETTING' | 'HEDGING' | 'EXCHANGE') | undefined, avgDrawdown?: number | undefined, balance?: number | undefined, brokeTimeOffsetToUtc?: number | undefined, configuredProxy?: ProxyDTO | undefined, connected?: boolean | undefined, copierDuplications?: Array | undefined, credit?: number | undefined, currency?: string | undefined, drawdown?: number | undefined, environment?: ('LIVE' | 'DEMO') | undefined, equity?: number | undefined, expertAdvisorResources?: Array | undefined, fallbackMode?: boolean | undefined, freeMargin?: number | undefined, historyDeactivated?: boolean | undefined, isHyperactive?: boolean | undefined, isInvestorPassword?: boolean | undefined, isNative?: boolean | undefined, latencyInMs?: number | undefined, leverage?: number | undefined, maxDrawdown?: number | undefined, missingSymbolMappings?: Array | undefined, openPositions?: boolean | undefined, openPositionsCount?: number | undefined, pendingApprovals?: Array | undefined, pendingOrders?: boolean | undefined, pendingOrdersCount?: number | undefined, positionMismatch?: boolean | undefined, profitTargetsStatus?: Array | undefined, profitThisMonth?: number | undefined, profitThisWeek?: number | undefined, profitToday?: number | undefined, proxy?: ProxyDTO | undefined, riskLimitsStatus?: Array | undefined, status?: string | undefined, unrealizedProfit?: number | undefined, usedMargin?: number | undefined, walletBalances?: Array | undefined, wrongCredentials?: boolean | undefined}; export type AccountAppliedTemplateDTO = {appliedAt?: string | undefined, currentRevision?: number | undefined, templateId?: string | undefined, templateName?: string | undefined, templateRevision?: number | undefined}; export type FeatureDedicatedIpDTO = {dedicatedProxyServerId: number}; export type FeatureMyHomeIpDTO = {host: string, httpPort?: number | undefined, password: string, socksPort?: number | undefined, username: string}; export type RegionDTO = {id: number, name?: string | undefined}; export type AccountStatusDTO = {id: number, name?: string | undefined}; export type AccountTypeDTO = {id: number, name?: string | undefined}; export type AccountDTO = {accountInformation?: AccountInformationDTO | undefined, alias?: string | undefined, appliedTemplate?: AccountAppliedTemplateDTO | undefined, callbackUrl?: string | undefined, closeUnmanagedPositions?: boolean | undefined, created?: string | undefined, ctraderClientId?: string | undefined, ctraderClientSecret?: string | undefined, dedicatedIp?: FeatureDedicatedIpDTO | undefined, deleted?: string | undefined, failIfAccountExistsInProject?: boolean | undefined, hasActiveCopiers?: boolean | undefined, hasDisabledCopiers?: boolean | undefined, hasMonitorOnlyCopiers?: boolean | undefined, id?: string | undefined, labels?: Array | undefined, loginAccountNumber?: string | undefined, loginAccountPassword: string, loginServer: string, myHomeIp?: FeatureMyHomeIpDTO | undefined, nativeMode?: boolean | undefined, propFirm?: boolean | undefined, region: RegionDTO, skipCredentialCheck?: boolean | undefined, status?: AccountStatusDTO | undefined, statusMessage?: string | undefined, tradingDisabled?: boolean | undefined, type: AccountTypeDTO, validateCredentialsOnChange?: boolean | undefined}; export type CreateApiRestApiV1AccountsArgs = {body: AccountDTO}; export type CreateApiRestApiV1AccountsOptions = {baseUrl?: string | undefined, ApiKeyAuth?: string | undefined, fetch?: typeof fetch | undefined}; export const proxyRegionDTO = z.object({id: z.number().int(), name: z.string().optional()}); export const proxyDTO = z.object({id: z.number().int().optional(), ipAddress: z.string().optional(), region: proxyRegionDTO.optional(), usedByAccounts: z.array(z.string()).optional()}); export const copierDuplicationDTO = z.object({directCopiers: z.number().int().optional(), fromAccount: z.string().optional(), fromAccountId: z.string().optional(), strategies: z.array(z.string()).optional()}); export const expertAdvisorResourceDTO = z.object({cpuPercent: z.number().optional(), featureId: z.string().optional(), lastError: z.string().optional(), memoryBytes: z.number().int().optional(), restartCount: z.number().int().optional(), state: z.enum(["STOPPED", "STARTING", "RUNNING", "ERROR"]).optional()}); export const missingSymbolMappingDTO = z.object({copierId: z.string().optional(), fromAccount: z.string().optional(), fromAccountId: z.string().optional(), lastTimestampDetected: z.number().int().optional(), symbol: z.string().optional()}); export const approvalDTO = z.object({accountFromId: z.string(), ticket: z.number().int(), volume: z.number().optional()}); export const profitTargetStatusDTO = z.object({balanceLastUpdate: z.string().optional(), lossLimitIsHit: z.boolean().optional(), profitTargetFeatureId: z.string().optional(), profitTargetIsHit: z.boolean().optional(), referenceBalance: z.number().optional()}); export const riskLimitStatusDTO = z.object({balanceLastUpdate: z.string().optional(), copierId: z.string().optional(), limitIsHit: z.boolean().optional(), referenceBalance: z.number().optional(), riskLimitId: z.string().optional(), scope: z.enum(["ACCOUNT", "COPIER"]).optional()}); export const walletDTO = z.object({asset: z.string().optional(), balance: z.number().optional()}); export const accountInformationDTO = z.object({accountDuplicationInProjectDetected: z.boolean().optional(), accountMode: z.enum(["NETTING", "HEDGING", "EXCHANGE"]).optional(), avgDrawdown: z.number().optional(), balance: z.number().optional(), brokeTimeOffsetToUtc: z.number().int().optional(), configuredProxy: proxyDTO.optional(), connected: z.boolean().optional(), copierDuplications: z.array(copierDuplicationDTO).optional(), credit: z.number().optional(), currency: z.string().optional(), drawdown: z.number().optional(), environment: z.enum(["LIVE", "DEMO"]).optional(), equity: z.number().optional(), expertAdvisorResources: z.array(expertAdvisorResourceDTO).optional(), fallbackMode: z.boolean().optional(), freeMargin: z.number().optional(), historyDeactivated: z.boolean().optional(), isHyperactive: z.boolean().optional(), isInvestorPassword: z.boolean().optional(), isNative: z.boolean().optional(), latencyInMs: z.number().int().optional(), leverage: z.number().int().optional(), maxDrawdown: z.number().optional(), missingSymbolMappings: z.array(missingSymbolMappingDTO).optional(), openPositions: z.boolean().optional(), openPositionsCount: z.number().int().optional(), pendingApprovals: z.array(approvalDTO).optional(), pendingOrders: z.boolean().optional(), pendingOrdersCount: z.number().int().optional(), positionMismatch: z.boolean().optional(), profitTargetsStatus: z.array(profitTargetStatusDTO).optional(), profitThisMonth: z.number().optional(), profitThisWeek: z.number().optional(), profitToday: z.number().optional(), proxy: proxyDTO.optional(), riskLimitsStatus: z.array(riskLimitStatusDTO).optional(), status: z.string().optional(), unrealizedProfit: z.number().optional(), usedMargin: z.number().optional(), walletBalances: z.array(walletDTO).optional(), wrongCredentials: z.boolean().optional()}); export const accountAppliedTemplateDTO = z.object({appliedAt: z.string().optional(), currentRevision: z.number().int().optional(), templateId: z.string().optional(), templateName: z.string().optional(), templateRevision: z.number().int().optional()}); export const featureDedicatedIpDTO = z.object({dedicatedProxyServerId: z.number().int()}); export const featureMyHomeIpDTO = z.object({host: z.string(), httpPort: z.number().int().optional(), password: z.string(), socksPort: z.number().int().optional(), username: z.string()}); export const regionDTO = z.object({id: z.number().int(), name: z.string().optional()}); export const accountStatusDTO = z.object({id: z.number().int(), name: z.string().optional()}); export const accountTypeDTO = z.object({id: z.number().int(), name: z.string().optional()}); export const accountDTO = z.object({accountInformation: accountInformationDTO.optional(), alias: z.string().max(255).optional(), appliedTemplate: accountAppliedTemplateDTO.optional(), callbackUrl: z.string().optional(), closeUnmanagedPositions: z.boolean().optional(), created: z.string().optional(), ctraderClientId: z.string().optional(), ctraderClientSecret: z.string().optional(), dedicatedIp: featureDedicatedIpDTO.optional(), deleted: z.string().optional(), failIfAccountExistsInProject: z.boolean().optional(), hasActiveCopiers: z.boolean().optional(), hasDisabledCopiers: z.boolean().optional(), hasMonitorOnlyCopiers: z.boolean().optional(), id: z.string().optional(), labels: z.array(z.string()).optional(), loginAccountNumber: z.string().max(255).optional(), loginAccountPassword: z.string().max(2000), loginServer: z.string().max(255), myHomeIp: featureMyHomeIpDTO.optional(), nativeMode: z.boolean().optional(), propFirm: z.boolean().optional(), region: regionDTO, skipCredentialCheck: z.boolean().optional(), status: accountStatusDTO.optional(), statusMessage: z.string().optional(), tradingDisabled: z.boolean().optional(), type: accountTypeDTO, validateCredentialsOnChange: 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 }; /** * Create an account * * POST /rest/api/v1/accounts */ export const createApiRestApiV1Accounts = async (args: CreateApiRestApiV1AccountsArgs, options?: CreateApiRestApiV1AccountsOptions) => { const {baseUrl = "https://api.metacopier.io", fetch: fetchFn = fetch, ApiKeyAuth} = options ?? {} const query = new URLSearchParams() const headers = new Headers() headers.set('content-type', "application/json") headers.set('accept', "application/json") if (ApiKeyAuth !== undefined) headers.set("X-API-KEY", ApiKeyAuth) const url = `${baseUrl.replace(/\/+$/, '')}/rest/api/v1/accounts${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(accountDTO, await res.json()) };