OpenPond
1Branch0Tags
GL
glucryptoMerge commit 'refs/tmp/prod-master'
typescript
import { z } from "zod"; import { store } from "opentool/store"; import { wallet } from "opentool/wallet"; import { resolveHyperliquidChainConfig, withdrawFromHyperliquid, } from "opentool/adapters/hyperliquid"; export const profile = { description: "Withdraw USDC from Hyperliquid back to an on-chain address via withdraw3.", }; const decimalString = z .string() .min(1, "amount is required") .refine((v) => /^\d+(?:\.\d+)?$/.test(v), "must be a decimal string"); export const schema = z.object({ amount: decimalString, destination: z .string() .min(1, "destination is required") .refine( (v) => /^0x[a-fA-F0-9]{40}$/.test(v), "destination must be a hex address" ), environment: z.enum(["mainnet", "testnet"]).default("testnet"), }); export async function POST(req: Request): Promise<Response> { const body = await req.json().catch(() => ({})); const { amount, destination, environment } = schema.parse(body); const chainConfig = resolveHyperliquidChainConfig(environment); const context = await wallet({ chain: chainConfig.chain, }); const walletAddress = context.address; const withdraw = await withdrawFromHyperliquid({ amount, destination: destination as `0x${string}`, environment, wallet: context, }); const eventEnvironment = environment === "mainnet" ? "hyperliquid" : "hyperliquid-testnet"; await store({ source: "hyperliquid", ref: `${withdraw.nonce}`, status: "submitted", walletAddress, action: "withdraw", notional: amount, network: eventEnvironment, market: { market_type: "system", venue: "hyperliquid", environment: eventEnvironment, canonical_symbol: `system:hyperliquid:${eventEnvironment}:withdraw`, protocol_market_id: "withdraw", raw_symbol: "USDC", }, metadata: { environment, destination, nonce: withdraw.nonce, status: withdraw.status, }, }); return Response.json({ ok: true, environment, walletAddress, withdraw, }); }