OV ↔ KRWO 전환기능 개발 가이드

김스왑 KRWO→OV 전환 수수료 조회

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 스왑

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 스왑

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 };
};