import {z} from 'zod' export type GetApiV1PoliciesPolicyIdArgs = {policy_id: string, 'privy-app-id': string}; export type GetApiV1PoliciesPolicyIdOptions = {baseUrl?: string | undefined, appSecretAuth?: {username: string, password: string} | undefined, fetch?: typeof fetch | undefined}; export const walletChainType = z.enum(["ethereum", "solana", "cosmos", "stellar", "sui", "aptos", "movement", "tron", "bitcoin-segwit", "bitcoin-taproot", "pearl", "near", "ton", "starknet", "xrpl", "spark"]); export const keyQuorumId = z.string(); export const policyMethod = z.enum(["eth_sendTransaction", "eth_signTransaction", "eth_signUserOperation", "eth_signTypedData_v4", "personal_sign", "eth_sign7702Authorization", "wallet_sendCalls", "signTransaction", "signAndSendTransaction", "signMessage", "exportPrivateKey", "exportSeedPhrase", "signTransactionBytes", "signRawMessageBytes", "tron_sendTransaction", "tron_signTransaction", "xrpl_signTransaction", "earn_deposit", "earn_withdraw", "earn_incentive_claim", "transfer", "*"]); export const ethereumTransactionConditionField = z.enum(["to", "value", "chain_id", "data_byte_length"]); export const conditionOperator = z.enum(["eq", "gt", "gte", "lt", "lte", "in", "in_condition_set", "contains", "starts_with", "ends_with"]); export const conditionValue = z.union([z.string(), z.array(z.string())]); export const abiParameter = z.object({name: z.string().optional(), type: z.string(), components: z.array(z.record(z.string(), z.unknown())).optional(), indexed: z.boolean().optional(), internalType: z.string().optional()}); export const abiSchema = z.array(z.object({type: z.enum(["function", "constructor", "event", "fallback", "receive"]), name: z.string().optional(), inputs: z.array(abiParameter).optional(), outputs: z.array(abiParameter).optional(), stateMutability: z.enum(["pure", "view", "nonpayable", "payable"]).optional(), anonymous: z.boolean().optional()})); export const ethereumTypedDataDomainConditionField = z.enum(["chainId", "verifyingContract", "chain_id", "verifying_contract"]); export const typedDataTypeFieldInput = z.object({name: z.string(), type: z.string()}); export const typedDataTypesInputParams = z.record(z.string(), z.array(typedDataTypeFieldInput)); export const typedDataInput = z.object({types: typedDataTypesInputParams, primary_type: z.string()}); export const tempoTransactionConditionField = z.enum(["fee_token", "fee_payer_signature", "nonce_key", "valid_before", "valid_after"]); export const solanaIdl = z.record(z.string(), z.unknown()); export const solanaSystemProgramInstructionConditionField = z.enum(["instructionName", "Transfer.from", "Transfer.to", "Transfer.lamports"]); export const solanaTokenProgramInstructionConditionField = z.enum(["instructionName", "Transfer.source", "Transfer.destination", "Transfer.authority", "Transfer.amount", "TransferChecked.source", "TransferChecked.destination", "TransferChecked.authority", "TransferChecked.amount", "TransferChecked.mint", "Burn.account", "Burn.mint", "Burn.authority", "Burn.amount", "MintTo.mint", "MintTo.account", "MintTo.authority", "MintTo.amount", "CloseAccount.account", "CloseAccount.destination", "CloseAccount.authority", "InitializeAccount3.account", "InitializeAccount3.mint", "InitializeAccount3.owner"]); export const tronTransactionConditionField = z.enum(["TransferContract.to_address", "TransferContract.amount", "TriggerSmartContract.contract_address", "TriggerSmartContract.call_value", "TriggerSmartContract.token_id", "TriggerSmartContract.call_token_value"]); export const xrplTransactionConditionField = z.enum(["TransactionType", "Payment.Destination", "Payment.DestinationTag", "Payment.Amount.drops", "Payment.Amount.value", "Payment.Amount.currency", "Payment.Amount.issuer", "Payment.SendMax.drops", "Payment.SendMax.value", "Payment.SendMax.currency", "Payment.SendMax.issuer", "Payment.DeliverMin.drops", "Payment.DeliverMin.value", "Payment.DeliverMin.currency", "Payment.DeliverMin.issuer", "OfferCreate.TakerPays.drops", "OfferCreate.TakerPays.value", "OfferCreate.TakerPays.currency", "OfferCreate.TakerPays.issuer", "OfferCreate.TakerGets.drops", "OfferCreate.TakerGets.value", "OfferCreate.TakerGets.currency", "OfferCreate.TakerGets.issuer", "OfferCreate.Expiration", "TrustSet.LimitAmount.value", "TrustSet.LimitAmount.currency", "TrustSet.LimitAmount.issuer", "TrustSet.QualityIn", "TrustSet.QualityOut"]); export const suiTransactionCommandOperator = z.union([z.literal("eq"), z.literal("in")]); export const suiCommandName = z.enum(["TransferObjects", "SplitCoins", "MergeCoins"]); export const suiTransferObjectsCommandField = z.enum(["recipient", "amount"]); export const messageSigningField = z.enum(["content", "byte_length"]); export const policyCondition = z.discriminatedUnion("field_source", [z.object({field_source: z.literal("ethereum_transaction"), field: ethereumTransactionConditionField, operator: conditionOperator, value: conditionValue}), z.object({field_source: z.literal("ethereum_calldata"), field: z.string(), abi: abiSchema, operator: conditionOperator, value: conditionValue}), z.object({field_source: z.literal("ethereum_typed_data_domain"), field: ethereumTypedDataDomainConditionField, operator: conditionOperator, value: conditionValue}), z.object({field_source: z.literal("ethereum_typed_data_message"), field: z.string(), typed_data: typedDataInput, operator: conditionOperator, value: conditionValue}), z.object({field_source: z.literal("ethereum_7702_authorization"), field: z.literal("contract"), operator: conditionOperator, value: conditionValue}), z.object({field_source: z.literal("tempo_transaction"), field: tempoTransactionConditionField, operator: conditionOperator, value: conditionValue}), z.object({field_source: z.literal("solana_program_instruction"), field: z.literal("programId"), operator: conditionOperator, value: conditionValue}), z.object({field_source: z.literal("solana_instruction_data"), field: z.string(), idl: solanaIdl, operator: conditionOperator, value: conditionValue}), z.object({field_source: z.literal("solana_system_program_instruction"), field: solanaSystemProgramInstructionConditionField, operator: conditionOperator, value: conditionValue}), z.object({field_source: z.literal("solana_token_program_instruction"), field: solanaTokenProgramInstructionConditionField, operator: conditionOperator, value: conditionValue}), z.object({field_source: z.literal("system"), field: z.literal("current_unix_timestamp"), operator: conditionOperator, value: conditionValue}), z.object({field_source: z.literal("tron_transaction"), field: tronTransactionConditionField, operator: conditionOperator, value: conditionValue}), z.object({field_source: z.literal("tron_trigger_smart_contract_data"), field: z.string(), abi: abiSchema, operator: conditionOperator, value: conditionValue}), z.object({field_source: z.literal("xrpl_transaction"), field: xrplTransactionConditionField, operator: conditionOperator, value: conditionValue}), z.object({field_source: z.literal("sui_transaction_command"), field: z.literal("commandName"), operator: suiTransactionCommandOperator, value: z.union([suiCommandName, z.array(suiCommandName)])}), z.object({field_source: z.literal("sui_transfer_objects_command"), field: suiTransferObjectsCommandField, operator: conditionOperator, value: conditionValue}), z.object({field_source: z.literal("action_request_body"), field: z.string(), operator: conditionOperator, value: conditionValue}), z.object({field_source: z.literal("reference"), field: z.string(), operator: conditionOperator, value: conditionValue}), z.object({field_source: z.literal("message"), field: messageSigningField, operator: conditionOperator, value: conditionValue})]); export const policyAction = z.enum(["ALLOW", "DENY", "ALLOW_WITH_MFA"]); export const policyRuleResponse = z.object({name: z.string().min(1).max(50), method: policyMethod, conditions: z.array(policyCondition), action: policyAction, id: z.string()}); export const policy = z.object({version: z.literal("1.0"), name: z.string().min(1).max(100), chain_type: walletChainType, id: z.string().min(24).max(24), owner_id: keyQuorumId.nullable(), created_at: z.number(), rules: z.array(policyRuleResponse)}); 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 }; /** * Get Policy * * GET /v1/policies/{policy_id} */ export const getApiV1PoliciesPolicyId = async (args: GetApiV1PoliciesPolicyIdArgs, options?: GetApiV1PoliciesPolicyIdOptions) => { const {baseUrl = "https://api.privy.io", fetch: fetchFn = fetch, appSecretAuth} = options ?? {} const query = new URLSearchParams() const headers = new Headers() headers.set('accept', "application/json") if (args['privy-app-id'] != null) headers.set("privy-app-id", String(args['privy-app-id'])) if (appSecretAuth !== undefined) headers.set('authorization', `Basic ${btoa(`${appSecretAuth.username}:${appSecretAuth.password}`)}`) const url = `${baseUrl.replace(/\/+$/, '')}/v1/policies/${encodeURIComponent(String(args.policy_id))}${query.size > 0 ? `?${query}` : ''}` const res = await fetchFn(url, {method: "GET", headers}) if (!res.ok) throw new Error(`Request failed with status ${res.status}`, {cause: {status: res.status, body: await res.text()}}) return validateResponse(policy, await res.json()) };