typescript
import { z } from "zod";
import { store } from "opentool/store";
import { wallet } from "opentool/wallet";
import {
HyperliquidApiError,
resolveHyperliquidChainConfig,
setHyperliquidPortfolioMargin,
} from "opentool/adapters/hyperliquid";
import type { WalletFullContext } from "opentool/wallet";
export const profile = {
description:
"Enable/disable Hyperliquid portfolio margin (account unification mode) for a wallet or subaccount user address.",
};
export const schema = z.object({
enabled: z.boolean().default(true),
environment: z.enum(["mainnet", "testnet"]).default("testnet"),
});
export async function POST(req: Request): Promise<Response> {
try {
const body = await req.json().catch(() => ({}));
const { enabled, environment } = schema.parse(body);
const chainConfig = resolveHyperliquidChainConfig(environment);
const context = await wallet({
chain: chainConfig.chain,
apiKey: process.env.ALCHEMY_API_KEY,
rpcUrl: chainConfig.rpcUrl ?? process.env.RPC_URL,
turnkey: {
organizationId: process.env.TURNKEY_SUBORG_ID!,
apiPublicKey: process.env.TURNKEY_API_PUBLIC_KEY!,
apiPrivateKey: process.env.TURNKEY_API_PRIVATE_KEY!,
signWith: process.env.TURNKEY_WALLET_ADDRESS!,
apiBaseUrl: process.env.TURNKEY_API_BASE_URL,
},
});
const walletAddress = context.address;
const result = await setHyperliquidPortfolioMargin({
wallet: context as WalletFullContext,
environment,
enabled,
user: walletAddress as `0x${string}`,
});
await store({
source: "hyperliquid",
ref: `portfolio-margin-${Date.now()}`,
status: "submitted",
walletAddress,
action: "portfolio-margin",
network: environment === "mainnet" ? "hyperliquid" : "hyperliquid-testnet",
metadata: {
environment,
enabled,
user: walletAddress as `0x${string}`,
result,
},
});
return Response.json({
ok: true,
environment,
enabled,
user: walletAddress as `0x${string}`,
result,
});
} catch (error) {
const err = error as { message?: unknown; response?: unknown; cause?: unknown };
const message = typeof err?.message === "string" ? err.message : "Unknown error";
const exchangeResponse =
err?.response ?? (error instanceof HyperliquidApiError ? error.response : null);
return Response.json(
{
ok: false,
error: message,
exchangeResponse,
debug: "portfolio-margin@v2",
},
{ status: 400 }
);
}
}