import { useReadContract } from 'wagmi';
import { type Abi } from 'viem';
//@ts-ignore
import { ResolvedRegister } from '@wagmi/core/src/types/register';
const GIM_SWAP_CONTRACT_ADDRESS = "0x663e9d64cDd9B8cc7B0f073BbFB927AA8D154BE0";
const getFeeAbi = [
{
"constant": true,
"inputs": [],
"name": "feeNumerator",
"outputs": [{ "name": "", "type": "uint256" }],
"type": "function"
}
]
export const useGetFee = (amount: string) => {
const { data: fee, isPending } = useReadContract<
Abi,
'feeNumerator',
[],
ResolvedRegister['config'],
{ data: bigint }
>({
abi: getFeeAbi as Abi,
address: GIM_SWAP_CONTRACT_ADDRESS as `0x${string}`,
functionName: 'feeNumerator',
});
if (amount === '0' || isPending) return { fee: null };
return { fee: Number(fee) };
};
OV를 KRWO로 전환하기 위해서는 Open Voucher Contract 의 transferVoucherAndCall
을 호출해야 합니다.
[
{
"inputs": [
{
"internalType": "address",
"name": "to",
"type": "address"
},
{
"internalType": "uint256",
"name": "value",
"type": "uint256"
},
{
"internalType": "address",
"name": "callee",
"type": "address"
},
{
"internalType": "bytes",
"name": "data",
"type": "bytes"
}
],
"name": "transferVoucherAndCall",
"outputs": [
{
"internalType": "bool",
"name": "",
"type": "bool"
}
],
"stateMutability": "nonpayable",
"type": "function"
}
]
구현 예시
import { safeCalc } from '../utils/safeCalc';
import { useState } from 'react';
import { createPublicClient, createWalletClient, custom } from 'viem';
import { kaia } from 'wagmi/chains';
import { http, useAccount } from 'wagmi';
import { WALLETS } from '@/src/lib/constants/wallets';
const swapAbi =[
{
"inputs": [
{
"internalType": "address",
"name": "to",
"type": "address"
},
{
"internalType": "uint256",
"name": "value",
"type": "uint256"
},
{
"internalType": "address",
"name": "callee",
"type": "address"
},
{
"internalType": "bytes",
"name": "data",
"type": "bytes"
}
],
"name": "transferVoucherAndCall",
"outputs": [
{
"internalType": "bool",
"name": "",
"type": "bool"
}
],
"stateMutability": "nonpayable",
"type": "function"
}
]
const OPEN_VOUCHER_CONTRACT_ADDRESS = "0x51ac6833805AC16BC10Db649b84128b321B53820";
const GIM_SWAP_CONTRACT_ADDRESS = "0x663e9d64cDd9B8cc7B0f073BbFB927AA8D154BE0";
export const useSwap = (amount: string) => { // amount OV 갯수
const [isPending, setIsPending] = useState<boolean>(false);
const [isError, setIsError] = useState<boolean>(false);
const [isSuccess, setIsSuccess] = useState<boolean>(false);
const [hash, setHash] = useState<`0x${string}` | null>(null);
const { address, connector } = useAccount();
const to = GIM_SWAP_CONTRACT_ADDRESS;
const value = safeCalc.multiply(
amount,
safeCalc.pow(10, 10).toFixed(),
);
const callee = GIM_SWAP_CONTRACT_ADDRESS;
const publicClient = createPublicClient({
chain: kaia,
transport: http(),
});
const swap = async () => {
if (!connector || !address) return;
const currentWalletInfo = WALLETS.find(({ id }) => connector.id === id);
try {
const walletClient = createWalletClient({
chain: kaia,
transport: custom(await currentWalletInfo?.transport),
});
setIsPending(true);
const hash = await walletClient.writeContract({
address: OPEN_VOUCHER_CONTRACT_ADDRESS as `0x${string}`,
abi: swapAbi,
functionName: "transferVoucherAndCall",
account: address as `0x${string}`,
args:[to, BigInt(value.toFixed()), callee, "0x"]
});
if (!hash) throw new Error(`transaction error`);
setHash(hash);
const { status } = await publicClient.waitForTransactionReceipt({ hash });
if (status === 'success') setIsSuccess(true);
else if (status === 'reverted') setIsError(true);
} catch (error) {
console.error(error);
setIsError(true);
} finally {
setIsPending(false);
}
};
return { swap, isSuccess, isPending, error: isError, hash };
};
KRWO를 OV로 전환하기 위해서는 KRWO Contract 의 transferAndCall
을 호출해야 합니다.
[
{
inputs: [
{
internalType: 'address',
name: 'to',
type: 'address',
},
{
internalType: 'uint256',
name: 'value',
type: 'uint256',
},
{
internalType: 'address',
name: 'callee',
type: 'address',
},
],
name: 'transferAndCall',
outputs: [
{
"internalType": "bool",
"name": "",
type: 'bool',
},
],
stateMutability: 'nonpayable',
type: 'function',
},
]
구현 예시
import { safeCalc } from '../utils/safeCalc';
import { useState } from 'react';
import { createPublicClient, createWalletClient, custom } from 'viem';
import { kaia } from 'wagmi/chains';
import { http, useAccount } from 'wagmi';
import { WALLETS } from '@/src/lib/constants/wallets';
const swapAbi = [
{
inputs: [
{
internalType: 'address',
name: 'to',
type: 'address',
},
{
internalType: 'uint256',
name: 'value',
type: 'uint256',
},
{
internalType: 'address',
name: 'callee',
type: 'address',
},
],
name: 'transferAndCall',
outputs: [
{
"internalType": "bool",
"name": "",
type: 'bool',
},
],
stateMutability: 'nonpayable',
type: 'function',
},
]
const KRWO_CONTRACT_ADDRESS = "0x7FC692699f2216647a0E06225d8bdF8cDeE40e7F";
const GIM_SWAP_CONTRACT_ADDRESS = "0x663e9d64cDd9B8cc7B0f073BbFB927AA8D154BE0";
export const useSwap = (amount: string) => { // amount : KRWO 갯수
const [isPending, setIsPending] = useState<boolean>(false);
const [isError, setIsError] = useState<boolean>(false);
const [isSuccess, setIsSuccess] = useState<boolean>(false);
const [hash, setHash] = useState<`0x${string}` | null>(null);
const { address, connector } = useAccount();
const to = GIM_SWAP_CONTRACT_ADDRESS;
const value = safeCalc.multiply(
amount,
safeCalc.pow(10, 6).toFixed(),
);
const callee = GIM_SWAP_CONTRACT_ADDRESS;
const publicClient = createPublicClient({
chain: kaia,
transport: http(),
});
const swap = async () => {
if (!connector || !address) return;
const currentWalletInfo = WALLETS.find(({ id }) => connector.id === id);
try {
const walletClient = createWalletClient({
chain: kaia,
transport: custom(await currentWalletInfo?.transport),
});
setIsPending(true);
const hash = await walletClient.writeContract({
address: KRWO_CONTRACT_ADDRESS as `0x${string}`,
abi: swapAbi,
functionName: "transferAndCall",
account: address as `0x${string}`,
args:[to, BigInt(value.toFixed()), callee]
});
if (!hash) throw new Error(`transaction error`);
setHash(hash);
const { status } = await publicClient.waitForTransactionReceipt({ hash });
if (status === 'success') setIsSuccess(true);
else if (status === 'reverted') setIsError(true);
} catch (error) {
console.error(error);
setIsError(true);
} finally {
setIsPending(false);
}
};
return { swap, isSuccess, isPending, error: isError, hash };
};