@funkit/connect
Version:
Funkit Connect SDK elevates DeFi apps via web2 sign-ins and one-click checkouts.
196 lines (192 loc) • 5.98 kB
JavaScript
"use client";
import {
useAccount,
useConfig
} from "./chunk-UPZNKPYU.js";
import {
useFunkitTranslation
} from "./chunk-STLOQEN7.js";
import {
logger
} from "./chunk-AHYOV7AV.js";
// src/clients/mallard.tsx
import { ROBINHOOD_MAINNET_CHAIN_ID } from "@funkit/chains";
import { VAULT_DEPOSITOR_ABI } from "@funkit/fun-relay";
import { useMemo } from "react";
import {
encodeFunctionData,
erc20Abi as erc20Abi2,
getAddress,
maxUint256
} from "viem";
// src/wagmi/actions.ts
import { erc20Abi, formatUnits } from "viem";
import {
getBalance as getBalanceCore,
multicall as multicallCore
} from "wagmi/actions";
import {
estimateGas,
getAccount,
getGasPrice,
getTransaction,
getWalletClient,
multicall,
readContract,
sendTransaction,
switchChain,
waitForTransactionReceipt
} from "wagmi/actions";
// src/clients/mallard.tsx
var MALLARD_DEPOSIT_ADDRESS = getAddress(
"0xD42c46c7BaD6A54b38395F846b09981CE75fb8e2"
);
var VAULT_DEPOSITOR_ZORRO = getAddress(
"0xec70919c52e56a197d2e13b78cb8511db54f3ca2"
);
var AMOUNT_PLACEHOLDER = 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffdeadbeefn;
var MALLARD_PRIMARY_ACCOUNT_INDEX = 0;
var MALLARD_ANYONE_CAN_EXECUTE_CANCEL = true;
var MALLARD_DEPOSIT_ABI = [
{
name: "initiateDepositReturnToOwner",
type: "function",
stateMutability: "nonpayable",
inputs: [
{ name: "owner", type: "address" },
{ name: "accountIndex", type: "uint16" },
{ name: "token", type: "address" },
{ name: "amount", type: "uint256" },
{ name: "anyoneCanExecuteCancel", type: "bool" }
],
outputs: []
}
];
function createMallardDepositActions(config) {
const {
recipientAddress,
tokenAddress,
vaultDepositorAddress = VAULT_DEPOSITOR_ZORRO,
depositAddress = MALLARD_DEPOSIT_ADDRESS
} = config;
return async () => {
if (!recipientAddress) {
throw new Error(
"Please connect your wallet before starting a Mallard deposit"
);
}
const token = getAddress(tokenAddress);
const depositCalldata = encodeFunctionData({
abi: MALLARD_DEPOSIT_ABI,
functionName: "initiateDepositReturnToOwner",
args: [
getAddress(recipientAddress),
MALLARD_PRIMARY_ACCOUNT_INDEX,
token,
AMOUNT_PLACEHOLDER,
MALLARD_ANYONE_CAN_EXECUTE_CANCEL
]
});
return [
// Step 1: Approve token to VaultDepositooor (infinite). No approve-to-0 reset —
// that's only needed for USDT-style tokens that require zeroing allowance first; USDG
// is standard ERC-20.
{
contractAbi: erc20Abi2,
contractAddress: token,
functionName: "approve",
functionArgs: [vaultDepositorAddress, maxUint256]
},
// Step 2: VaultDepositooor pulls token, swaps placeholder, forwards to
// Mallard.initiateDepositReturnToOwner → credits the recipient's Mallard account
{
contractAbi: VAULT_DEPOSITOR_ABI,
contractAddress: vaultDepositorAddress,
functionName: "deposit",
functionArgs: [token, depositAddress, depositCalldata, 0n]
}
];
};
}
var MALLARD_USDG_ADDRESS = getAddress(
"0x5fc5360D0400a0Fd4f2af552ADD042D716F1d168"
);
var MALLARD_USDG_ICON_SRC = "https://sdk-cdn.fun.xyz/images/usdg.svg";
function createConnectedWalletWithdrawalClient(config, ownerAddress, sourceChainId) {
const ensureOnChain = async (chainId) => {
if (getAccount(config).chainId !== chainId) {
await switchChain(config, { chainId });
}
};
return {
address: () => ownerAddress,
getChainId: async () => sourceChainId,
switchChain: async (chainId) => {
await ensureOnChain(chainId);
},
sendTransaction: async (chainId, transaction) => {
await ensureOnChain(chainId);
return sendTransaction(config, {
to: transaction.to,
data: transaction.data,
value: BigInt(transaction.value || "0"),
chainId
});
},
confirmTransaction: (txHash, chainId) => (
// wagmi-core's receipt (chain-formatter generics) is the same runtime
// shape as viem's `TransactionReceipt` but isn't structurally assignable
// to it; cast at this boundary. Using wagmi (not a viem publicClient) is
// deliberate — it reuses the connected wallet's configured transport
// instead of requiring a separate RPC endpoint.
waitForTransactionReceipt(config, {
hash: txHash,
chainId
})
)
};
}
function useMallardWithdrawalConfig(config) {
const { t } = useFunkitTranslation();
const wagmiConfig = useConfig();
const { address } = useAccount();
const sourceChainId = config?.sourceChainId ?? ROBINHOOD_MAINNET_CHAIN_ID;
const sourceTokenAddress = config?.sourceTokenAddress ?? MALLARD_USDG_ADDRESS;
return useMemo(() => {
if (!config || !address) {
return null;
}
const wallet = createConnectedWalletWithdrawalClient(
wagmiConfig,
address,
sourceChainId
);
logger.info("mallard:withdrawal:configBuilt", {
sourceChainId,
sourceTokenAddress,
owner: address
});
return {
modalTitle: config.modalTitle ?? t("withdrawal.withdraw"),
disableConnectedWallet: config.disableConnectedWallet,
onBeforeSign: config.onBeforeSign,
wallet,
sourceChainId: sourceChainId.toString(),
sourceTokenSymbol: config.sourceTokenSymbol ?? "USDG",
defaultReceiveToken: config.defaultReceiveToken,
sourceTokenAddress,
iconSrc: config.iconSrc ?? MALLARD_USDG_ICON_SRC,
getMinWithdrawalUSD: config.getMinWithdrawalUSD,
getMaxWithdrawalUSD: config.getMaxWithdrawalUSD
};
}, [config, address, wagmiConfig, sourceChainId, sourceTokenAddress, t]);
}
export {
AMOUNT_PLACEHOLDER,
MALLARD_DEPOSIT_ADDRESS,
MALLARD_USDG_ADDRESS,
MALLARD_USDG_ICON_SRC,
VAULT_DEPOSITOR_ZORRO,
createMallardDepositActions,
useMallardWithdrawalConfig
};