diff --git a/typescript/src/chain.ts b/typescript/src/chain.ts index 93e3407f1..e422e7a68 100644 --- a/typescript/src/chain.ts +++ b/typescript/src/chain.ts @@ -381,40 +381,6 @@ export interface TBTCVault { getOptimisticMintingFinalizedEvents: GetEvents.Function } -/** - * Represnts data required to request redemption. - */ -export interface RequestRedemptionData { - /** - * On-chain identifier of the redeemer. - */ - redeemer: Identifier - /** - * The Bitcoin public key of the wallet. Must be in the compressed form (33 - * bytes long with 02 or 03 prefix). - */ - walletPublicKey: string - /** - * The main UTXO of the wallet. Must match the main UTXO held by the on-chain - * Bridge contract. - */ - mainUtxo: UnspentTransactionOutput - /** - * The output script that the redeemed funds will be locked to. Must be - * un-prefixed and not prepended with length. - */ - redeemerOutputScript: string - /** - * The amount to be redeemed with the precision of the tBTC on-chain token - * contract. - */ - amount: BigNumber - /** - * The vault address. - */ - vault: Identifier -} - /** * Interface for communication with the TBTC v2 token on-chain contract. */ @@ -436,9 +402,21 @@ export interface TBTCToken { * from the tBTC on-chain token contract. Then the tBTC token contract calls * the `receiveApproval` function from the `TBTCVault` contract which burns * tBTC tokens and requests redemption. - * @param requestRedemptionData Data required to request redemption @see - * {@link RequestRedemptionData}. + * @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 with the precision of the tBTC + * on-chain token contract. * @returns Transaction hash of the approve and call transaction. */ - requestRedemption(requestRedemptionData: RequestRedemptionData): Promise + requestRedemption( + walletPublicKey: string, + mainUtxo: UnspentTransactionOutput, + redeemerOutputScript: string, + amount: BigNumber + ): Promise } diff --git a/typescript/src/ethereum.ts b/typescript/src/ethereum.ts index d69ec026b..5f0eb6a68 100644 --- a/typescript/src/ethereum.ts +++ b/typescript/src/ethereum.ts @@ -5,7 +5,6 @@ import { TBTCToken as ChainTBTCToken, Identifier as ChainIdentifier, GetEvents, - RequestRedemptionData, } from "./chain" import { BigNumber, @@ -1106,15 +1105,27 @@ export class TBTCToken * @see {ChainTBTCToken#requestRedemption} */ async requestRedemption( - requestRedemptionData: RequestRedemptionData + walletPublicKey: string, + mainUtxo: UnspentTransactionOutput, + redeemerOutputScript: string, + amount: BigNumber ): Promise { - const { vault, amount, ...restData } = requestRedemptionData + const redeemer = await this._instance?.signer?.getAddress() + if (!redeemer) { + throw new Error("Signer not provided.") + } - const extraData = this.buildRequestRedemptionData(restData) + const vault = await this._instance.owner() + const extraData = this.buildRequestRedemptionData( + Address.from(redeemer), + walletPublicKey, + mainUtxo, + redeemerOutputScript + ) const tx = await sendWithRetry(async () => { return await this._instance.approveAndCall( - vault.identifierHex, + vault, amount, extraData.toPrefixedString() ) @@ -1124,11 +1135,20 @@ export class TBTCToken } private buildRequestRedemptionData( - requestRedemptionData: Omit + redeemer: Address, + walletPublicKey: string, + mainUtxo: UnspentTransactionOutput, + redeemerOutputScript: string ): Hex { - const { redeemer, ...restData } = requestRedemptionData - const { walletPublicKeyHash, mainUtxo, prefixedRawRedeemerOutputScript } = - this.buildBridgeRequestRedemptionData(restData) + const { + walletPublicKeyHash, + prefixedRawRedeemerOutputScript, + mainUtxo: _mainUtxo, + } = this.buildBridgeRequestRedemptionData( + walletPublicKey, + mainUtxo, + redeemerOutputScript + ) return Hex.from( utils.defaultAbiCoder.encode( @@ -1136,9 +1156,9 @@ export class TBTCToken [ redeemer.identifierHex, walletPublicKeyHash, - mainUtxo.txHash, - mainUtxo.txOutputIndex, - mainUtxo.txOutputValue, + _mainUtxo.txHash, + _mainUtxo.txOutputIndex, + _mainUtxo.txOutputValue, prefixedRawRedeemerOutputScript, ] ) @@ -1146,12 +1166,10 @@ export class TBTCToken } private buildBridgeRequestRedemptionData( - data: Pick< - RequestRedemptionData, - "mainUtxo" | "walletPublicKey" | "redeemerOutputScript" - > + walletPublicKey: string, + mainUtxo: UnspentTransactionOutput, + redeemerOutputScript: string ) { - const { walletPublicKey, mainUtxo, redeemerOutputScript } = data const walletPublicKeyHash = `0x${computeHash160(walletPublicKey)}` const mainUtxoParam = { diff --git a/typescript/src/redemption.ts b/typescript/src/redemption.ts index f52b8b3d1..e3b65c986 100644 --- a/typescript/src/redemption.ts +++ b/typescript/src/redemption.ts @@ -55,8 +55,7 @@ export interface RedemptionRequest { } /** - * Requests a redemption from the on-chain Bridge contract. - * @param redeemer - On-chain identifier of the redeemer. + * Requests a redemption of tBTC into BTC. * @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 @@ -65,27 +64,22 @@ export interface RedemptionRequest { * be locked to. Must be un-prefixed and not prepended with length. * @param amount - The amount to be redeemed with the precision of the tBTC * on-chain token contract. - * @param vault - The vault address. * @param tBTCToken - Handle to the TBTCToken on-chain contract. * @returns Transaction hash of the request redemption transaction. */ export async function requestRedemption( - redeemer: Identifier, walletPublicKey: string, mainUtxo: UnspentTransactionOutput, redeemerOutputScript: string, amount: BigNumber, - vault: Identifier, tBTCToken: TBTCToken ): Promise { - return await tBTCToken.requestRedemption({ - redeemer, + return await tBTCToken.requestRedemption( walletPublicKey, mainUtxo, redeemerOutputScript, - amount, - vault, - }) + amount + ) } /** diff --git a/typescript/test/redemption.test.ts b/typescript/test/redemption.test.ts index d682f96fe..04072c3d0 100644 --- a/typescript/test/redemption.test.ts +++ b/typescript/test/redemption.test.ts @@ -34,7 +34,6 @@ import * as chai from "chai" import chaiAsPromised from "chai-as-promised" import { expect } from "chai" import { BigNumberish, BigNumber } from "ethers" -import { Address } from "../src/ethereum" import { MockTBTCToken } from "./utils/mock-tbtc-token" chai.use(chaiAsPromised) @@ -46,20 +45,16 @@ describe("Redemption", () => { const redeemerOutputScript = data.pendingRedemptions[0].pendingRedemption.redeemerOutputScript const amount = data.pendingRedemptions[0].pendingRedemption.requestedAmount - const vault = Address.from("0xb622eA9D678ddF15135a20d59Ff26D28eC246bfB") const token: MockTBTCToken = new MockTBTCToken() - const redeemer = Address.from("0x117284D8C50f334a1E2b7712649cB23C7a04Ae74") beforeEach(async () => { bcoin.set("testnet") await requestRedemption( - redeemer, walletPublicKey, mainUtxo, redeemerOutputScript, amount, - vault, token ) }) @@ -69,12 +64,10 @@ describe("Redemption", () => { expect(tokenLog.length).to.equal(1) expect(tokenLog[0]).to.deep.equal({ - redeemer, walletPublicKey, mainUtxo, redeemerOutputScript, amount, - vault, }) }) }) diff --git a/typescript/test/utils/mock-tbtc-token.ts b/typescript/test/utils/mock-tbtc-token.ts index cb0f8e93e..2e37d3e68 100644 --- a/typescript/test/utils/mock-tbtc-token.ts +++ b/typescript/test/utils/mock-tbtc-token.ts @@ -1,8 +1,14 @@ -import { RequestRedemptionData, TBTCToken } from "../../src/chain" +import { TBTCToken } from "../../src/chain" import { Hex } from "../../src/hex" import { BigNumber } from "ethers" +import { UnspentTransactionOutput } from "../../src/bitcoin" -interface RequestRedemptionLog extends RequestRedemptionData {} +interface RequestRedemptionLog { + walletPublicKey: string + mainUtxo: UnspentTransactionOutput + redeemerOutputScript: string + amount: BigNumber +} export class MockTBTCToken implements TBTCToken { private _requestRedemptionLog: RequestRedemptionLog[] = [] @@ -16,9 +22,17 @@ export class MockTBTCToken implements TBTCToken { } async requestRedemption( - requestRedemptionData: RequestRedemptionData + walletPublicKey: string, + mainUtxo: UnspentTransactionOutput, + redeemerOutputScript: string, + amount: BigNumber ): Promise { - this._requestRedemptionLog.push(requestRedemptionData) + this._requestRedemptionLog.push({ + walletPublicKey, + mainUtxo, + redeemerOutputScript, + amount, + }) return Hex.from( "0xf7d0c92c8de4d117d915c2a8a54ee550047f926bc00b91b651c40628751cfe29"