-
Notifications
You must be signed in to change notification settings - Fork 25
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
Fetch redemption details #561
Conversation
Add `getBitcoinTransaction` method. To display the redemption details we need to fetch the Bitcoin transaction to find whether the redemption request was already handled successfully- meaning there was a Bitcoin transfer to a given redeemer output script.
Add `buildRedemptionKey` method- builds the redemption key required to refer a redemption request. Redemption key built as `keccak256(keccak256(redeemerOutputScript) | walletPubKeyHash)`.
To fetch the redemption details data we need query events to find the redemption request and verify whether the redemption was handled successfully or timed out. Here we also noticed a bug in the `ethers.js` lib- the `ethers.js` lib encodes the `bytesX` param in the wrong way. It uses the left-padded rule but based on the Solidity docs it should be a sequence of bytes in X padded with trailing zero-bytes to a length of 32 bytes(right-padded). See https://docs.soliditylang.org/en/v0.8.17/abi-spec.html#formal-specification-of-the-encoding Consider this wallet public key hash `0x03B74D6893AD46DFDD01B9E0E3B3385F4FCE2D1E`: - `ethers.js` returns `0x00000000000000000000000003b74d6893ad46dfdd01b9e0e3b3385f4fce2d1e` - should be: `0x03b74d6893ad46dfdd01b9e0e3b3385f4fce2d1e000000000000000000000000` In that case, in methods that fetch the past events by indexed param which has `bytesX` type(`RedemptionsCompleted`, `RedemptionRequested`, `RedemptionTimedOut`) we build the filter topics manually.
This hook fetches the redemption request details based on the: - redemption requested tx hash- We also need to find an event by transaction hash because it's possible that there can be multiple `RedemptionRequest` events with the same redemption key but created at different times eg: - redemption X requested, - redemption X was handled successfully and the redemption X was removed from `pendingRedemptions` map, - the same wallet is still in `live` state and can handle the redemption request with the same `walletPubKeyHash` and `redeemerOutputScript` pair, - now 2 `RedemptionRequested` events exist with the same redemption key(the same `walletPubKeyHash` and `redeemerOutputScript` pair). In that case, we must know exactly which redemption request we want to fetch. - wallet public key hash- we need to find `RedemptionRequested` event by wallet public key hash to get all necessary data and make sure that the request actually happened, - redeemer- We need `redeemer` address as well to reduce the number of records- any user can request redemption for the same wallet. - redeemer output script- we need this param to build the redemption key and find the Bitcoin transfer for this redeemer output script.
Compare correctly the `scriptPubKey` data from Bitcoin transacion outputs with the redeemer output script from Ethereum event. The redeemer otput script from the Ethereum event is prepended by the script length encoded as a Bitcoin varint but the `scriptPubKey` is in a raw format so we need to prefix the output script bytes buffer with 0x and its own length. Here we also hardcoded data in the `UnmintDetails` component for a redemption that was already handled successfully- for testing purposes.
Display the redemption details data with real on-chain data. Based on that data we render different states of the unminting process.
Preview uploaded to https://preview.dashboard.test.threshold.network/fetch-redemption-details/index.html. |
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.
Left some comments to look at before the merge.
Overall looks great 💪 Love how earch step in the useFetchRedemptionDetails
hook is commencted ❤️
We should assign useColorModeValue("white", "brand.800") to the variable on top of the component.
BTC address on success page redirects to the etherscan instead of blockstream. Here we add `chain="bitcoin"` prop to fix this bug.
We should assign `event.ergs?.treasuryFee` instead of `event.ergs?.redeemer` to the `treasuryFee`.
Mention in comments that the current code is a workaround and we should use `getContractPastEvents` to fetch events one we provide a fix in the `ethers.js` lib. The `ethers.js` lib encodes the `bytesX` param in the wrong way.
Move function that prefixes the output script with `0x` and its own length to `threshold-ts` lib utils.
Preview uploaded to https://preview.dashboard.test.threshold.network/fetch-redemption-details/index.html. |
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.
Left one comment to point out the TODO
but overall looking good. I'm ready to merge it
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 🔥
This PR adds support for fetching the redemption details data from the chain. Based on that data we render different states of the unminting process on the Redemption Details page.
Main changes:
Add new methods to the
TBTC
interface fromthreshold-ts
libAdd methods that fetch the redemption request and redemption-related events. Here we also noticed a bug in the
ethers.js
lib- theethers.js
lib encodes thebytesX
param in the wrong way. It uses the left-padded rule but based on the Solidity docs it should be a sequence of bytes in X padded with trailing zero-bytes to a length of 32 bytes(right-padded). See https://docs.soliditylang.org/en/v0.8.17/abi-spec.html#formal-specification-of-the-encodingConsider this wallet public key hash
0x03B74D6893AD46DFDD01B9E0E3B3385F4FCE2D1E
:ethers.js
returns0x00000000000000000000000003b74d6893ad46dfdd01b9e0e3b3385f4fce2d1e
0x03b74d6893ad46dfdd01b9e0e3b3385f4fce2d1e000000000000000000000000
In that case, in methods that fetch the past events by indexed param which has
bytesX
type(RedemptionsCompleted
,RedemptionRequested
,RedemptionTimedOut
) we build the filter topics manually.Hook that fetches the redemption details
This hook fetches the redemption request details based on the:
transaction hash because it's possible that there can be multiple
RedemptionRequest
events with the same redemption key but created atdifferent times eg:
redemption X requested,
redemption X was handled successfully and the redemption X was
removed from
pendingRedemptions
map,the same wallet is still in
live
state and can handle theredemption request with the same
walletPubKeyHash
andredeemerOutputScript
pair,now 2
RedemptionRequested
events exist with the same redemptionkey(the same
walletPubKeyHash
andredeemerOutputScript
pair).In that case, we must know exactly which redemption request we
want to fetch.
RedemptionRequested
event bywallet public key hash to get all necessary data and make sure that
the request actually happened. It's also used to build the redemption key,
redeemer
address as well to reduce the number ofrecords- any user can request redemption for the same wallet.
and find the Bitcoin transfer for this redeemer output script.
Hook that fetches the block details such as
timestamp
We need timestamps for a given block umber to calculate the total time it took to complete a redemption or how long a redemption request takes.
TODO(probably address in separate PRs):
scriptPubKey
to Bitcoin address to display it on the success page see #Add function that returns Bitcoin address from output script keep-network/tbtc-v2#646. Will update in a separate PR once we merge Add function that returns Bitcoin address from output script keep-network/tbtc-v2#646.Screenshots
Pending Redemption:
Completed Redemption: