-
Notifications
You must be signed in to change notification settings - Fork 858
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
feat(wallet): support CoW 🐮 orders in Safe Sign #20203
Conversation
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.
wallet core lgtm
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.
strings
++
2380d1c
to
4fb5ec0
Compare
A Storybook has been deployed to preview UI for the latest push |
if (!decimals) { | ||
throw new Error(errorMessage) | ||
} |
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.
Should we check for the error message presence instead?
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.
if (!symbol) { | ||
throw new Error(errorMessage) | ||
} |
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.
shouldnt we just check if there is an error message?
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.
// Hooks | ||
import { useAccountOrb, useAddressOrb } from '../../../common/hooks/use-orb' | ||
|
||
const makeUnknownToken = ( |
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.
how about?
const makeUnknownToken = ( | |
const UNKOWN_TOKEN = ( |
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 think makeUnknownToken
makes more sense since it is a function. I'd use UNKNOWN_TOKEN
for a constant.
const buyTokenResult = makeToken( | ||
buyToken, | ||
buyAssetNetwork, | ||
buyTokenSymbol, | ||
buyTokenDecimals | ||
) | ||
const sellTokenResult = makeToken( | ||
sellToken, | ||
sellAssetNetwork, | ||
sellTokenSymbol, | ||
sellTokenDecimals | ||
) |
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.
memoize these objet to prevent re-renders of child components
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.
@kdenhartog You need to wrap ETH into WETH in order to benefit from gasless swaps using EIP-712 messages. If you select ETH as your sell asset, you'll need to pay for gas fees - which is actually wrapping it into WETH behind the scenes. @StephenHeaps also had the same feedback by the way. We should handle this case the same way we parse 0x calldata into the |
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.
Amazing! this looks slick.
I just checked the PR. I wouldn't mind trying it out, do you think is easy for me to run this locally?
string buy_token; | ||
string buy_amount; | ||
string receiver; | ||
string deadline; |
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 would suggest adding the feeAmount
and kind
(that can be either sell
or buy
)
And maybe partiallyFillable
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.
Or this is just for the view that shows the basic params, and the rest are visible in the details?
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.
Or this is just for the view that shows the basic params, and the rest are visible in the details?
That's right. I think we'll need to extend the current design to accommodate for those extra fields. Would be a good next step for us to make the signing screen even more informative.
} | ||
] | ||
}), | ||
getEthTokenSymbol: query< |
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 see you get decimals, symbol. You might want to consider fetching the name as well
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.
Oh I didn't know name
was also part of the ERC20 interface. Good to know! We don't need the token name for this particular case (it doesn't get displayed), but I'll add it another PR.
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, it is, although is optional (although most contracts have them).
Not sure if your provider accounts for it, but there's some contracts that implement these methods but return bytes instead of the string. One that comes to mind is SAI
, so I would try this out. They have different ABI for the same method, technically they don't respect the standard, but most dapps handle this case.
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.
Thanks for the info. Created an issue to track this: brave/brave-browser#33162
|
||
// set to true once Swap+Send is supported | ||
expectRecipientAddress={false} | ||
/> |
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.
nice refactor! ❤️
senderLabel={senderLabel} | ||
senderOrb={senderOrb} | ||
recipientOrb={recipientOrb} | ||
recipientLabel={recipientLabel} |
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.
Probably out of scope for this PR, but, one thing that would help with the security is to show a warning if the receiver
account and the signing
account is not the same (or is not 0x0, since that in the smart contract refers to the owner of the funds).
Changing the receiver is a great CoW Swap feature, it allows you to SWAP and send in one operation. However, i think is nice to make the user aware the destination of the funds is different than the origin of them
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.
Indeed that's a good point. The addresses should also link to the explorer. Will take inputs from the design team for a future iteration.
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.
++ seems like a good follow up item
Adds support for parsing EIP-712 messages for CoW orders, and renders the information in the Safe Sign UI previously designed for 0x swaps.
4fb5ec0
to
4aa6766
Compare
A Storybook has been deployed to preview UI for the latest push |
A Storybook has been deployed to preview UI for the latest push |
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.
iOS++.
iOS will get ETHSwap UI for free 🔥:
And I've opened brave/brave-ios#8114 for integrating the Safe Sign UI with this signature request on iOS.
A Storybook has been deployed to preview UI for the latest push |
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.
desktop frontend ++
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.
Just one blocking question to confirm we aren't introducing a casting issue - rest seems like good follow up issues.
senderLabel={senderLabel} | ||
senderOrb={senderOrb} | ||
recipientOrb={recipientOrb} | ||
recipientLabel={recipientLabel} |
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.
++ seems like a good follow up item
@@ -341,6 +342,55 @@ GetTransactionInfoFromData(const std::vector<uint8_t>& data) { | |||
"uint128", // sell amount | |||
"uint128"}, // buy amount | |||
tx_args); | |||
} else if (selector == kCowOrderSellEthSelector) { |
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.
This function could use a bit of refactoring. It's starting to get pretty complex for a parsing function that's handling untrusted data supplied by a page. Given that an error in this logic can easily lead to a rule of 2 violation we should split this up better.
Let's do a follow up issue for this.
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 for the one sec concern I had
Summary of changes:
Resolves brave/brave-browser#33093
Submitter Checklist:
QA/Yes
orQA/No
;release-notes/include
orrelease-notes/exclude
;OS/...
) to the associated issuenpm run test -- brave_browser_tests
,npm run test -- brave_unit_tests
wikinpm run lint
,npm run presubmit
wiki,npm run gn_check
,npm run tslint
git rebase master
(if needed)Reviewer Checklist:
gn
After-merge Checklist:
changes has landed on
Test Plan:
👉 Case A: CoW Swap trade
👉 Case B: CoW Swap trade with custom recipient
It's also possible to view the raw message by clicking on the Details button.
👉 Case C: CoW swap trade selling native asset (ETH on Ethereum, XDAI on Gnosis)
👉 Case D: 0x Swap involving unknown tokens