-
Notifications
You must be signed in to change notification settings - Fork 1
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
Withdrawals #474
Conversation
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.
213fccc
to
844a59b
Compare
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.
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
// TODO: Should we hide this API key in SDK impl or should it be passed by the | ||
// consumer? |
There was a problem hiding this comment.
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. |
There was a problem hiding this comment.
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?
There was a problem hiding this comment.
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
.
There was a problem hiding this comment.
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/ethereum/stbtc.ts
Outdated
*/ | ||
encodeApproveAndCallFunctionData( | ||
spender: ChainIdentifier, | ||
amount: bigint, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
amount: bigint, | |
shares: bigint, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
sdk/src/lib/contracts/stbtc.ts
Outdated
|
||
encodeApproveAndCallFunctionData( | ||
spender: ChainIdentifier, | ||
amount: bigint, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
amount: bigint, | |
shares: bigint, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
sdk/src/lib/contracts/stbtc.ts
Outdated
* of stBTC shares. | ||
* @param amount Amount of stBTC shares to redeem. | ||
*/ | ||
previewRedeem(amount: bigint): Promise<bigint> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
previewRedeem(amount: bigint): Promise<bigint> | |
previewRedeem(shares: bigint): Promise<bigint> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
sdk/src/lib/redeemer-proxy.ts
Outdated
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 | ||
} |
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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
Outdated
async initiateRedemption( | ||
destinationBitcoinAddress: string, | ||
tbtcAmount: bigint, | ||
redeemer: RedeemerProxy, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
redeemer: RedeemerProxy, | |
redeemerProxy: RedeemerProxy, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Remove unnecessary `init` fn - use constructor instead.
@@ -14,4 +14,8 @@ export interface BitcoinProvider { | |||
* @returns Bitcoin address selected by the user. |
There was a problem hiding this comment.
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
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.
To not repeat them.
Hardcode he Gelato api key in `AcreSdkContext` for consistency.
There was a problem hiding this 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.
- 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
- 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.
dapp/src/components/TransactionModal/ActiveUnstakingStep/UnstakeFormModal/UnstakeDetails.tsx
Outdated
Show resolved
Hide resolved
dapp/src/components/TransactionModal/ActiveUnstakingStep/SignMessageModal.tsx
Show resolved
Hide resolved
dapp/src/components/TransactionModal/ActiveUnstakingStep/SignMessageModal.tsx
Outdated
Show resolved
Hide resolved
Use const variable instead of hardcoded value.
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 |
We can try to use AbortController and add the |
We should display the resume modal when the user rejects the sign message step. Otherwsie we want to display the error modal.
There was a problem hiding this 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.
There was a problem hiding this 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. 🚀
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 to6.10.0
(without^
) in thesolidity
andsdk
workspaces. The version ofethers
in thesolidity
workspace has been resolved to6.13.1
and thesdk
workspace depends on it, so pnpm resolvesethers
insdk
to6.13.1
under the hood where there are some changes in the API and causes tests and builds to fail.