-
|
Hi team, I’m experiencing an issue when trying to perform a resize operation — I keep getting the error:
In this case, I’m trying to transfer 0.1 usdc from my wallet to the Unified Balance. The Unified Balance currently holds 0.08 USDC, but even after approval, the resize call fails with the same error. Here’s the context: Below is the function I’m currently using. I’ve tried multiple approaches, but none have worked so far. I’d really appreciate your help understanding what might be causing this issue. Functionconst topUpUnifiedBalance = useCallback(
async (amountDecimal: string): Promise<boolean> => {
if (!walletAddress || !walletClient) {
setError("Wallet not connected");
return false;
}
setIsLoading(true);
setError(null);
try {
const { createPublicClient, http } = await import("viem");
const { polygon } = await import("viem/chains");
const { NitroliteClient } = await import("@erc7824/nitrolite");
const tokenAddress = process.env.NEXT_PUBLIC_USDC_TOKEN_ADDRESS as `0x${string}`;
if (!tokenAddress) throw new Error("USDC token address not configured");
const raw = toRawUsdc(amountDecimal);
if (raw <= 0n) throw new Error("Amount must be greater than 0");
// Channel ID
let channelId = paymentChannel?.channelId;
if (!channelId || channelId.startsWith("clearnode_")) {
channelId = await ensureOpenChannelId();
}
if (!channelId) return await depositToUnifiedBalance(amountDecimal);
// RPC Signer
const { rpcSigner, stateWallet } = await getRpcSigner();
// Broker Config
const { createGetConfigMessage } = await import("@erc7824/nitrolite");
const getConfigMsg = await createGetConfigMessage(rpcSigner);
const brokerConfig = await clearNodeClient.sendRequest(getConfigMsg);
const polygonNetwork = (brokerConfig as any).networks?.find(
(n: { chain_id: number }) => n.chain_id === 137
);
if (!polygonNetwork?.custody_address)
throw new Error("Polygon network not configured");
// Public Client
const publicClient = createPublicClient({
chain: polygon,
transport: http(),
});
// 📝 Step 1/3: Approve USDC for deposit
const erc20Abi = [
{
name: "approve",
type: "function",
stateMutability: "nonpayable",
inputs: [
{ name: "spender", type: "address" },
{ name: "amount", type: "uint256" },
],
outputs: [{ type: "bool" }],
},
] as const;
console.log("📝 Step 1/3: Approving USDC for deposit...");
const approvalHash = await walletClient.writeContract({
address: tokenAddress,
abi: erc20Abi,
functionName: "approve",
args: [polygonNetwork.custody_address as `0x${string}`, raw],
account: walletAddress,
chain: polygon,
});
console.log("⏳ Waiting for approval confirmation...");
await publicClient.waitForTransactionReceipt({ hash: approvalHash });
console.log("✅ USDC approved:", approvalHash);
// 📤 Step 2/3: Send resize_channel RPC
const reqId = Date.now();
const payload: [number, string, any, number] = [
reqId,
"resize_channel",
{
channel_id: channelId,
resize_amount: raw.toString(), // ✅ Deposit amount
allocate_amount: "0", // ✅ Don’t touch unified allocation
funds_destination: walletAddress,
},
Date.now(),
];
console.log("📤 Step 2/3: Sending resize_channel RPC...");
console.log(` resize_amount: +${raw} (deposit)`);
console.log(` allocate_amount: 0 (no allocation from unified)`);
const sig = await rpcSigner(payload);
const envelope = { req: payload, sig: [sig] };
const resp = await clearNodeClient.sendRequest(JSON.stringify(envelope));
// Response validation
const respData = resp as any;
if (!respData || !respData.res) throw new Error("Invalid broker response");
const [, method, params] = respData.res;
if (method === "error") {
throw new Error(`Broker error: ${params?.error || "Unknown"}`);
}
if (method !== "resize_channel") {
throw new Error(`Unexpected method: ${method}`);
}
if (!params.channel_id || !params.state || !params.server_signature) {
throw new Error("Invalid resize response");
}
// ⛓️ Step 3/3: Execute on-chain resize
console.log("⛓️ Step 3/3: Executing on-chain resize...");
const nitroliteClient = new NitroliteClient({
publicClient,
walletClient: walletClient as any,
stateSigner: stateWallet as any,
addresses: {
custody: polygonNetwork.custody_address as `0x${string}`,
adjudicator: polygonNetwork.adjudicator_address as `0x${string}`,
guestAddress: (brokerConfig as { broker_address: string }).broker_address as `0x${string}`,
},
chainId: 137,
challengeDuration: 3600n,
});
const resizeTxHash = await nitroliteClient.resize(
params.channel_id as `0x${string}`,
{
intent: params.state.intent,
version: BigInt(params.state.version),
data: params.state.state_data as `0x${string}`,
allocations: params.state.allocations.map((a: any) => ({
destination: a.destination as `0x${string}`,
token: a.token as `0x${string}`,
amount: BigInt(a.amount),
})),
},
params.server_signature as `0x${string}`,
);
console.log("⏳ Waiting for resize transaction...");
await publicClient.waitForTransactionReceipt({ hash: resizeTxHash });
console.log("✅ Top-Up successful! TX:", resizeTxHash);
await refreshUnifiedBalance();
return true;
} catch (err) {
const msg = err instanceof Error ? err.message : "Top-Up failed";
console.error("❌ Top-Up failed:", err);
setError(msg);
return false;
} finally {
setIsLoading(false);
}
},
[
walletAddress,
walletClient,
paymentChannel,
ensureOpenChannelId,
depositToUnifiedBalance,
getRpcSigner,
clearNodeClient,
refreshUnifiedBalance,
],
);Console Output |
Beta Was this translation helpful? Give feedback.
Replies: 2 comments 2 replies
-
|
Hey @rahimunlu ! Thank you for building on Yellow Network! |
Beta Was this translation helpful? Give feedback.
-
|
Thank you! It's much clear for me now. |
Beta Was this translation helpful? Give feedback.
Currently
resize(...)it NOT able to perform a deposit from EOA to Custody SC, thus either Custody available balance should suffice or a separatedeposit(...)transaction is required prior. Therefore the intended flow is to useNitroliteClient.deposit(tokenAddress, amount)before doing the resize.In the next major release we indeed plan to merge this into one flow. We will notify on our developments.