import { DZapClient, Services } from "@dzapio/sdk";
import {
ZapQuoteRequest,
ZapBuildTxnRequest,
ApprovalModes,
PermitTypes,
} from "@dzapio/sdk";
const dZap = DZapClient.getInstance();
// Step 1: Get zap quote
const quoteRequest: ZapQuoteRequest = {
srcChainId: 42161, // Arbitrum
destChainId: 42161,
account: userAccount,
srcToken: "0xaf88d065e77c8cC2239327C5EDb3A432268e5831", // USDC on Arbitrum
destToken: "0x724dc807b04555b71ed48a6896b6F41593b8C637", // Aave USDC
amount: "1000000", // 1 USDC
recipient: userAccount,
slippage: 1,
};
const zapQuote = await dZap.getZapQuote(quoteRequest);
console.log("Zap quote received");
console.log("Expected output:", zapQuote.output);
console.log("Path steps:", zapQuote.path);
// Step 2: Handle approvals
const tokens = [
{
address: "0xaf88d065e77c8cC2239327C5EDb3A432268e5831",
amount: "1000000",
},
];
// zapQuote.approvalData is an array (one entry per token needing approval)
const spender = zapQuote.approvalData[0]?.approveTo;
// Check current allowances
const allowanceCheck = await dZap.getAllowance({
chainId: 42161,
sender: userAccount,
spender,
tokens: tokens,
service: Services.zap,
mode: ApprovalModes.AutoPermit, // Automatically selects optimal approval method
});
console.log("Allowance check:", allowanceCheck.data);
let permitData: string | undefined;
// allowanceCheck.data is keyed by token address: { allowance: bigint, type: 'dzap' | 'permit2' | 'eip2612' }
const isApprovalNeeded = tokens.some((t) => {
const entry = allowanceCheck.data[t.address];
return entry && entry.type !== "eip2612" && entry.allowance < BigInt(t.amount);
});
const isSignatureNeeded = tokens.some(
(t) => allowanceCheck.data[t.address]?.type !== "dzap"
);
if (isApprovalNeeded) {
await dZap.approve({
chainId: 42161,
signer: signer,
sender: userAccount,
tokens: tokens,
service: Services.zap,
mode: ApprovalModes.AutoPermit, // Uses optimal approval strategy
approvalTxnCallback: async ({ txnDetails, address }) => {
console.log(`Approval for ${address}:`, txnDetails);
},
});
console.log("Approvals completed");
}
// Handle permit signatures if possible (gasless)
if (isSignatureNeeded) {
const signatures = await dZap.sign({
chainId: 42161,
sender: userAccount,
tokens: tokens,
signer: signer,
spender,
service: Services.zap,
permitType: PermitTypes.AutoPermit, // Automatically selects optimal permit type
});
if (signatures.status === "success" && "tokens" in signatures) {
permitData = signatures.tokens?.[0]?.permitData;
}
console.log("Permits signed");
}
// Step 3: Build zap request
const request: ZapBuildTxnRequest = {
srcChainId: 42161,
destChainId: 42161,
account: userAccount,
srcToken: "0xaf88d065e77c8cC2239327C5EDb3A432268e5831",
destToken: "0x724dc807b04555b71ed48a6896b6F41593b8C637",
amount: "1000000",
recipient: userAccount,
refundee: userAccount,
slippage: 1,
permitData, // Include permit data if available
integrator: {
id: "my-integration-id",
feeBps: 10, // 0.1% fee
wallet: "0x1234567890123456789012345678901234567890"
}
};
// Step 4: Execute zap
const zapResult = await dZap.zap({
request: request,
signer: signer,
});
if (zapResult.status === "success") {
console.log("Zap completed successfully!");
console.log("Transaction hash:", zapResult.txnHash);
} else {
console.error("Zap failed:", zapResult.errorMsg);
}