import { useAccount , useChainId , useTransactionState , TransactionStateType , TransactionEventType , } from '@masknet/web3-shared-evm' ; import type { TransactionReceipt } from 'web3-core' ; import { useNftRedPacketContract } from './useNftRedPacketContract' ; import type { NonPayableTx } from '@masknet/web3-contracts/types/types' ; import type { NftRedPacket } from '@masknet/web3-contracts/types/NftRedPacket' ; import { useCallback } from 'react' ; const EXTRA_GAS_PER_NFT = 335 ; export function useClaimNftRedpacketCallback ( id , totalAmount , signedMsg ) { const account = useAccount ( ) ; const chainId = useChainId ( ) ; const nftRedPacketContract = useNftRedPacketContract ( ) ; const [ claimState , setClaimState ] = useTransactionState ( ) ; const claimCallback = useCallback ( async ( ) => { if ( ! nftRedPacketContract || ! id || ! signedMsg || ! account || ! totalAmount ) { setClaimState ( { type : TransactionStateType . UNKNOWN , } ) ; return ; } type MethodParameters = Parameters < NftRedPacket [ 'methods' ] [ 'claim' ] > ; const params = [ id , signedMsg , account ] ; const config = { from : account , gas : ( await nftRedPacketContract . methods . claim ( ... params ) . estimateGas ( { from : account } ) . catch ( ( error ) => { setClaimState ( { type : TransactionStateType . FAILED , error } ) ; throw error ; } ) ) + EXTRA_GAS_PER_NFT * totalAmount , chainId , } ; setClaimState ( { type : TransactionStateType . WAIT_FOR_CONFIRMING , } ) ; return new Promise < void > ( async ( resolve , reject ) => { nftRedPacketContract . methods . claim ( ... params ) . send ( config as NonPayableTx ) . on ( TransactionEventType . RECEIPT , ( receipt ) => { setClaimState ( { type : TransactionStateType . CONFIRMED , no : 0 , receipt , } ) ; resolve ( ) ; } ) . on ( TransactionEventType . CONFIRMATION , ( no , receipt ) => { if ( claimState . type === TransactionStateType . CONFIRMED ) return ; setClaimState ( { type : TransactionStateType . CONFIRMED , no : 0 , receipt , } ) ; resolve ( ) ; } ) . on ( TransactionEventType . ERROR , ( error ) => { setClaimState ( { type : TransactionStateType . FAILED , error , } ) ; reject ( error ) ; } ) ; } ) ; } , [ id , signedMsg , account , chainId , totalAmount , claimState ] ) ; const resetCallback = useCallback ( ( ) => { setClaimState ( { type : TransactionStateType . UNKNOWN , } ) ; } , [ account ] ) ; return [ claimState , claimCallback , resetCallback ] as const ; }