Skip to content

Commit

Permalink
Request redemption
Browse files Browse the repository at this point in the history
Add a new method to the `ITBTC` interface that requests redemption. The
implementation of this interface uses the `requestRedemption` fn from
`tbtc-v2.ts` lib.

As a temporary soultion here we hardcode the redemption request data in
component- once we merge the
#532 we will
pass these params via props to the component.
  • Loading branch information
r-czajkowski committed Jun 9, 2023
1 parent 40d4a30 commit 8512568
Show file tree
Hide file tree
Showing 4 changed files with 118 additions and 9 deletions.
43 changes: 39 additions & 4 deletions src/components/Modal/tBTC/InitiateUnminting.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,12 @@ import {
ModalFooter,
ModalHeader,
} from "@threshold-network/components"
import { useWeb3React } from "@web3-react/core"
import { FC } from "react"
import { useNavigate } from "react-router-dom"
import { useRequestRedemption } from "../../../hooks/tbtc"
import { BaseModalProps } from "../../../types"
import { threshold } from "../../../utils/getThresholdLib"
import shortenAddress from "../../../utils/shortenAddress"
import InfoBox from "../../InfoBox"
import { BridgeContractLink } from "../../tBTC"
Expand All @@ -21,6 +24,13 @@ import {
} from "../../TransacionDetails"
import ModalCloseButton from "../ModalCloseButton"
import withBaseModal from "../withBaseModal"
import { getContractPastEvents } from "../../../web3/utils/index"
import {
encodeToBitcoinAddress,
UnspentTransactionOutput,
} from "@keep-network/tbtc-v2.ts/dist/src/bitcoin"
import { Hex } from "@keep-network/tbtc-v2.ts"
import { BigNumber } from "ethers"

type InitiateUnmintingProps = {
unmintAmount: string
Expand All @@ -33,18 +43,43 @@ const InitiateUnmintingBase: FC<InitiateUnmintingProps> = ({
btcAddress,
}) => {
const navigate = useNavigate()
const { account } = useWeb3React()
// TODO: calculate the BTC amount- take into account fees
const btcAmount = "1.25"
const thresholdNetworkFee = "0"
const btcMinerFee = "0"

// TODO: implement submit function
const initiateUnminting = () => {
// TODO: It's a temporary solution to be able to go through the whole flow.
navigate("/tBTC/unmint/redemption/123456789")
const onSuccess = () => {
// TODO: build redemption key here and redirect to the redemption details page.
const redemptionKey = "test"
navigate(`/tBTC/unmint/redemption/${redemptionKey}`)
closeModal()
}

const { sendTransaction } = useRequestRedemption(onSuccess)

const initiateUnminting = async () => {
// TODO: Temporary solution- we will pass this data via props once we merge
// https://github.com/threshold-network/token-dashboard/pull/532
const walletPublicKey =
"028ed84936be6a9f594a2dcc636d4bebf132713da3ce4dac5c61afbf8bbb47d6f7"
const utxo: UnspentTransactionOutput = {
transactionHash: Hex.from(
"0x5b6d040eb06b3de1a819890d55d251112e55c31db4a3f5eb7cfacf519fad7adb"
),
outputIndex: 0,
value: BigNumber.from("791613461"),
}

await sendTransaction(
account!,
walletPublicKey,
utxo,
btcAddress,
unmintAmount
)
}

return (
<>
<ModalHeader>Initiate unminting tBTC</ModalHeader>
Expand Down
1 change: 1 addition & 0 deletions src/hooks/tbtc/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,3 +7,4 @@ export * from "./useSubscribeToOptimisticMintingRequestedEvent"
export * from "./useFetchDepositDetails"
export * from "./useFetchRecentDeposits"
export * from "./useFetchTBTCMetrics"
export * from "./useRequestRedemption"
19 changes: 19 additions & 0 deletions src/hooks/tbtc/useRequestRedemption.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import { useThreshold } from "../../contexts/ThresholdContext"
import {
OnErrorCallback,
OnSuccessCallback,
useSendTransactionFromFn,
} from "../../web3/hooks"

export const useRequestRedemption = (
onSuccess?: OnSuccessCallback,
onError?: OnErrorCallback
) => {
const threshold = useThreshold()

return useSendTransactionFromFn(
threshold.tbtc.requestRedemption,
onSuccess,
onError
)
}
64 changes: 59 additions & 5 deletions src/threshold-ts/tbtc/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ import {
import {
ElectrumClient,
EthereumBridge,
EthereumTBTCToken,
} from "@keep-network/tbtc-v2.ts/dist/src"
import { BitcoinConfig, BitcoinNetwork, EthereumConfig } from "../types"
import TBTCVault from "@keep-network/tbtc-v2/artifacts/TBTCVault.json"
Expand All @@ -37,6 +38,8 @@ import { BigNumber, BigNumberish, Contract } from "ethers"
import { ContractCall, IMulticall } from "../multicall"
import { Interface } from "ethers/lib/utils"
import { BlockTag } from "@ethersproject/abstract-provider"
import { requestRedemption } from "@keep-network/tbtc-v2.ts/dist/src/redemption"
import { TBTCToken as ChainTBTCToken } from "@keep-network/tbtc-v2.ts/dist/src/chain"

export enum BridgeActivityStatus {
PENDING = "PENDING",
Expand Down Expand Up @@ -198,6 +201,26 @@ export interface ITBTC {
): string

findAllRevealedDeposits(depositor: string): Promise<RevealedDepositEvent[]>

/**
* Requests a redemption from the on-chain Bridge contract.
* @param redeemer On-chain identifier of the redeemer.
* @param walletPublicKey The Bitcoin public key of the wallet. Must be in
* the compressed form (33 bytes long with 02 or 03 prefix).
* @param mainUtxo The main UTXO of the wallet. Must match the main UTXO
* held by the on-chain Bridge contract.
* @param redeemerOutputScript - The output script that the redeemed funds
* will be locked to. Must be un-prefixed and not prepended with length.
* @param amount The amount to be redeemed in satoshis.
* @returns Transaction hash of the request redemption transaction.
*/
requestRedemption(
redeemer: string,
walletPublicKey: string,
mainUtxo: UnspentTransactionOutput,
redeemerOutputScript: string,
amount: BigNumberish
): Promise<string>
}

export class TBTC implements ITBTC {
Expand All @@ -206,7 +229,8 @@ export class TBTC implements ITBTC {
private _bitcoinClient: Client
private _multicall: IMulticall
private _bridgeContract: Contract
private _token: Contract
private _token: ChainTBTCToken
private _tokenContract: Contract
/**
* Deposit refund locktime duration in seconds.
* This is 9 month in seconds assuming 1 month = 30 days
Expand Down Expand Up @@ -252,7 +276,14 @@ export class TBTC implements ITBTC {
)
this._multicall = multicall
this._bitcoinConfig = bitcoinConfig
this._token = getContract(
this._token = new EthereumTBTCToken({
address: TBTCToken.address,
signerOrProvider: getProviderOrSigner(
ethereumConfig.providerOrSigner as any,
ethereumConfig.account
),
})
this._tokenContract = getContract(
TBTCToken.address,
TBTCToken.abi,
ethereumConfig.providerOrSigner,
Expand All @@ -273,7 +304,7 @@ export class TBTC implements ITBTC {
}

get tokenContract() {
return this._token
return this._tokenContract
}

suggestDepositWallet = async (): Promise<string | undefined> => {
Expand Down Expand Up @@ -585,8 +616,10 @@ export class TBTC implements ITBTC {

// There is only one transfer to depositor account.
const transferEvent = receipt.logs
.filter((log) => isSameETHAddress(log.address, this._token.address))
.map((log) => this._token.interface.parseLog(log))
.filter((log) =>
isSameETHAddress(log.address, this._tokenContract.address)
)
.map((log) => this._tokenContract.interface.parseLog(log))
.filter((log) => log.name === "Transfer")
.find((log) => isSameETHAddress(log.args.to, depositor))

Expand Down Expand Up @@ -629,4 +662,25 @@ export class TBTC implements ITBTC {
depositOutputIndex
)
}

requestRedemption = async (
redeemer: string,
walletPublicKey: string,
mainUtxo: UnspentTransactionOutput,
redeemerOutputScript: string,
amount: BigNumberish
): Promise<string> => {
const tx = await requestRedemption(
getChainIdentifier(redeemer),
walletPublicKey,
mainUtxo,
redeemerOutputScript,
BigNumber.from(amount),
getChainIdentifier(this._tbtcVault.address),
this._bridge,
this._token
)

return tx.toPrefixedString()
}
}

0 comments on commit 8512568

Please sign in to comment.