Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Withdrawals #474

Merged
merged 36 commits into from
Jun 28, 2024
Merged

Withdrawals #474

merged 36 commits into from
Jun 28, 2024

Conversation

r-czajkowski
Copy link
Contributor

@r-czajkowski r-czajkowski commented Jun 14, 2024

Depends on: #472
Closes: #353

This PR adds support for withdrawals in SDK and Acre dapp. To request a redemption we need to implement our custom redeemer proxy. Our redeemer proxy builds the redemption data and sends the redemption request transaction via Orangekit SDK.

Here we also hardcode the ethers version to 6.10.0 (without ^) in the solidity and sdk workspaces. The version of ethers in the solidity workspace has been resolved to 6.13.1 and the sdk workspace depends on it, so pnpm resolves ethers in sdk to 6.13.1 under the hood where there are some changes in the API and causes tests and builds to fail.

To use the latest redeption features.
We need the address of the `BitcoinRedeemer` contract to initialize the
withdrawal.
We need to sign the Bitcoin message in withdrawal flow.
Add `getChainIdentifier` and `encodeApproveAndCallFunctionData` methods.
We need the stBTC contract address and encoded function data to
initialize the withdrawal.
The `OrangeKitTbtcRedeemerProxy` requests redemption using the orangekit
SDK. It builds necessary data for the orangekit safe transaction and
sends transaction using the orangeKit.
Add `getPublicKey` method - we need the bitcoin account public key to
interact with the orangekit.
The account module exposes function that initializes the withdrawal - it
expects Bitcoin amount in satoshi precision. In this case we need to
convert satoshi to stBTC shares. Also we need to estimate the amount of
tBTC released after redeeming stBTC shares including all Acre fees using
the `previewRedeem` stBTC contract function. The value is required by
the tBTC SDK to determine the tBTC Wallet from which the Bitcoin will be
bridged to the depositor's Bitcoin address.
Add unit test for `initiateRedemption` method.
Add unit tests for `initializeWithdrawal` function.
Looks like the `ethers` dependency has been upgraded to `6.13.0` and the
interface has changed.
Base automatically changed from orangekit-integration to main June 19, 2024 07:37
Use `v6.10.0` in `solidity` and `sdk` workspaces. The pnpm resolves the
`ethers` in SDK to the version used in `solidity` workspace.
We need the gelato API to create the orangekit SDK.
sdk/src/acre.ts Outdated
Comment on lines 17 to 18
// TODO: Should we hide this API key in SDK impl or should it be passed by the
// consumer?
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's pass it and expect it to be configured as dApp's env variable.

@@ -14,4 +14,8 @@ export interface BitcoinProvider {
* @returns Bitcoin address selected by the user.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we take the chance and remove this BitcoinProvider interface and use the one defined in OrangeKit?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yep but we need to update the OrangeKit first. The BitcoinProvider lives in @orangekit/react. I think we should move this interface to the @orangekit/sdk.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Non-blocking. I created an issue to track it #489

sdk/src/lib/contracts/stbtc.ts Show resolved Hide resolved
sdk/src/lib/ethereum/stbtc.ts Show resolved Hide resolved
*/
encodeApproveAndCallFunctionData(
spender: ChainIdentifier,
amount: bigint,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
amount: bigint,
shares: bigint,

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.


encodeApproveAndCallFunctionData(
spender: ChainIdentifier,
amount: bigint,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
amount: bigint,
shares: bigint,

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

* of stBTC shares.
* @param amount Amount of stBTC shares to redeem.
*/
previewRedeem(amount: bigint): Promise<bigint>
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
previewRedeem(amount: bigint): Promise<bigint>
previewRedeem(shares: bigint): Promise<bigint>

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Comment on lines 25 to 61
static init(
contracts: AcreContracts,
orangeKitSdk: OrangeKitSdk,
account: {
publicKey: string
bitcoinAddress: string
ethereumAddress: ChainIdentifier
},
bitcoinProvider: BitcoinProvider,
sharesAmount: bigint,
) {
return new OrangeKitTbtcRedeemerProxy(
contracts,
orangeKitSdk,
account,
bitcoinProvider,
sharesAmount,
)
}

private constructor(
contracts: AcreContracts,
orangeKitSdk: OrangeKitSdk,
account: {
publicKey: string
bitcoinAddress: string
ethereumAddress: ChainIdentifier
},
bitcoinProvider: BitcoinProvider,
sharesAmount: bigint,
) {
this.#contracts = contracts
this.#orangeKitSdk = orangeKitSdk
this.#account = account
this.#bitcoinProvider = bitcoinProvider
this.#sharesAmount = sharesAmount
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we need to have a separate constructor and init method? Looks like the constructor would be enough.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

sdk/src/modules/tbtc/Tbtc.ts Show resolved Hide resolved
async initiateRedemption(
destinationBitcoinAddress: string,
tbtcAmount: bigint,
redeemer: RedeemerProxy,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
redeemer: RedeemerProxy,
redeemerProxy: RedeemerProxy,

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@nkuba nkuba mentioned this pull request Jun 19, 2024
@r-czajkowski r-czajkowski marked this pull request as ready for review June 20, 2024 12:00
dapp/src/hooks/sdk/useInitializeAcreSdk.ts Outdated Show resolved Hide resolved
sdk/package.json Outdated Show resolved Hide resolved
@@ -14,4 +14,8 @@ export interface BitcoinProvider {
* @returns Bitcoin address selected by the user.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Non-blocking. I created an issue to track it #489

sdk/test/utils/mock-orangekit.ts Outdated Show resolved Hide resolved
We want to know when the user needs to sign the message and when he
signed it, so here we add callbacks that are triggered before and after
the signing process.
Display more information about a given process to the user. To
initialize withdrawal we need to find a wallet that can hanlde the tBTC
redemption request - it's time-consuming so we display to the user that
we are building the transacion data.

The next phase is sign message step - we display a message saying please
finalize the signing process in yout wallet.

The last step is waiting for the transacion so we are saying that
withdrawal initialiazation is in progress.
Hardcode he Gelato api key in `AcreSdkContext` for consistency.
@r-czajkowski r-czajkowski requested a review from nkuba June 21, 2024 10:03
Copy link
Contributor

@kkosiorowska kkosiorowska left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I left a few smaller comments, but I also noticed a few things.

  1. When the user rejects signing the message should see ResumeModal. When the user resumes withdrawals has to wait until the transaction data builds again. I wonder if we can somehow avoid this.
Screen.Recording.2024-06-21.at.14.21.57.mov
  1. It seems to me that even if we stop the process by clicking the "Cancel" button underneath we are still building data. This means that even though the user has closed the modal after some time a wallet window will appear to sign the message.
Screenshot 2024-06-21 at 14 30 25

@nkuba nkuba mentioned this pull request Jun 24, 2024
3 tasks
Use const variable instead of hardcoded value.
@r-czajkowski
Copy link
Contributor Author

r-czajkowski commented Jun 24, 2024

I left a few smaller comments, but I also noticed a few things.

  1. When the user rejects signing the message should see ResumeModal. When the user resumes withdrawals has to wait until the transaction data builds again. I wonder if we can somehow avoid this.

Hmm I think we can't. This is limited by the tbtc-v2.ts lib. To achieve this we should refactor the tbtc-v2.ts and update the redemptions to be built in the same way as the deposit feature is built. cc @nkuba

@r-czajkowski
Copy link
Contributor Author

r-czajkowski commented Jun 24, 2024

It seems to me that even if we stop the process by clicking the "Cancel" button underneath we are still building data. This means that even though the user has closed the modal after some time a wallet window will appear to sign the message.

We can try to use AbortController and add the signal param to the initializeWithdrawal function. cc @nkuba

We should display the resume modal when the user rejects the sign message
step. Otherwsie we want to display the error modal.
kkosiorowska
kkosiorowska previously approved these changes Jun 26, 2024
Copy link
Contributor

@kkosiorowska kkosiorowska left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM from the dApp perspective. 🚀 However, I leave the final approval to @nkuba.

Copy link
Contributor

@kkosiorowska kkosiorowska left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM, Talked with Kuba and let's no wait for it any longer. 🚀

@kkosiorowska kkosiorowska merged commit 8ae1ec6 into main Jun 28, 2024
24 checks passed
@kkosiorowska kkosiorowska deleted the withdrawals branch June 28, 2024 07:42
r-czajkowski added a commit that referenced this pull request Jul 4, 2024
Refs: #447
Depends on: #474

In this PR we implement withdrawal fee calculation in a way that matches
the stBTC contract, where fee is calculated based on the total tBTC
amount and rounded up.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
🎨 dapp dApp 🔌 sdk TypeScript SDK Library
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Withdraw with Bitcoin signature
3 participants