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

fix: upgrades @walletconnect/ethereum-provider and @walletconnect/modal #868

Merged
merged 17 commits into from
Aug 10, 2023

Conversation

JFrankfurt
Copy link
Contributor

@JFrankfurt JFrankfurt commented Jul 28, 2023

These packages updates should remove polyfills, fix crypto.decode errors, allow empty required chains, and improve deep link ux.

Unfortunately, @walletconnect/ethereum-provider has some issues with exported types here. I've added a couple types and a util to guard for one of them. ArrayOneOrMore<number> must be enforced on either chains or optionalChains prior to the init call. This leads to a couple slightly awkward looking lines of code.

export type ArrayOneOrMore<T> = {
  0: T
} & Array<T>

/**
 * This is a type guard for ArrayOneOrMore
 */
export function isArrayOneOrMore<T>(input: T[] = []): input is ArrayOneOrMore<T> {
  return input.length > 0
}

https://uniswapteam.slack.com/archives/C03R5G8T8BH/p1690896081926629?thread_ts=1690481148.038409&cid=C03R5G8T8BH

… empty required chains, improve deep link ux
@JFrankfurt JFrankfurt requested review from vm, just-toby and a team July 28, 2023 16:45
@vercel
Copy link

vercel bot commented Jul 28, 2023

The latest updates on your projects. Learn more about Vercel for Git ↗︎

Name Status Preview Comments Updated (UTC)
web3-react ✅ Ready (Inspect) Visit Preview 💬 Add feedback Aug 4, 2023 5:27pm

@JFrankfurt JFrankfurt self-assigned this Jul 28, 2023
just-toby
just-toby previously approved these changes Jul 28, 2023
Comment on lines +29 to 36
<option hidden disabled>
Select chain
</option>
<option value={-1} selected={activeChainId === -1}>
Default
</option>
<option value={-1}>Default</option>
{chainIds.map((chainId) => (
<option key={chainId} value={chainId} selected={chainId === activeChainId}>
<option key={chainId} value={chainId}>
{CHAINS[chainId]?.name ?? chainId}
</option>
Copy link
Contributor Author

Choose a reason for hiding this comment

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

React was complaining about this invalid syntax in the example, but it's not related to the core diff here.

@@ -68,7 +72,7 @@ class MockWalletConnectProvider extends MockEIP1193Provider<number> {
* We mock this method later in the test suite to test behavior when optional chains are not supported.
*/
public getConnectedChains() {
return this.opts.chains.concat(this.opts.optionalChains || [])
return (this.opts.chains || []).concat(this.opts.optionalChains || [])
Copy link
Contributor Author

Choose a reason for hiding this comment

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

since chains can be undefined now we need a default value

@JFrankfurt JFrankfurt requested a review from grabbou August 2, 2023 18:36
const { rpcMap, rpc, chains, ...rest } = options

this.options = rest
this.chains = chains
Copy link
Contributor

Choose a reason for hiding this comment

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

I would also recommend putting optionalChains outside so that we can perform necessary reordering/check for presence.

if (!chains || !desiredChainId || !chains.includes(desiredChainId) || chains.length === 0) {
return chains
}
return getChainsWithDefault(chains, desiredChainId)
Copy link
Contributor

Choose a reason for hiding this comment

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

This seems unnecessary to me. Why not include that if additional logic from lines 126-128 inside getChainsWithDefault? We spent a lot of time recently with @cmcewen thinking about the ways to name this function properly and while we debated reoderChains, we figured getWithDefault makes more sense to emphasise it's literally putting the first one as default.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

It's just a question of where we put the new type checks and changes. getChainsWithDefault does not support chains or optionalChains as arguments any longer with the new upstream options type changes from @walletconnect/ethereum-provider. We either need to diff the caller or diff the util. I chose the caller, but I don't have a preference between the two.

Copy link
Contributor

Choose a reason for hiding this comment

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

Yeah, I understand your mixed feelings there. I think - personally - since the only utility of that getChainsWithDefault was to cope with WC "abstraction" of choosing the preferred chain, I think putting it all there would make sense.

Copy link
Contributor

Choose a reason for hiding this comment

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

BTW, just one tiny consideration for the future work: we could consider (if we're putting chains and optional chains as a class property) to e.g. make their type "arrayoneormore | undefined" and do not set them if they're either not defined or empty in length. That way, I think typings would become much easier down the road.

grabbou
grabbou previously requested changes Aug 2, 2023
chains: number[] | undefined,
desiredChainId: number | undefined
): number[] | undefined {
if (!chains || !desiredChainId || !chains.includes(desiredChainId) || chains.length === 0) {
Copy link
Contributor

Choose a reason for hiding this comment

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

@JFrankfurt

This specifically

!chains.includes(desiredChainId)

is what is causing the tests to fail.

You should not handle this case here. If you take a look at getChainsWithDefault code, you will see it handles that case on its own:

export function getChainsWithDefault(chains: number[], defaultChainId: number) {
const idx = chains.indexOf(defaultChainId)
if (idx === -1) {
throw new Error(
`Invalid chainId ${defaultChainId}. Make sure default chain is included in "chains" - chains specified in "optionalChains" may not be selected as the default, as they may not be supported by the wallet.`
)
}

@JFrankfurt JFrankfurt requested a review from grabbou August 2, 2023 22:59
@just-toby just-toby removed their request for review August 2, 2023 23:02
@just-toby just-toby dismissed their stale review August 2, 2023 23:03

letting others review this unless otherwise requested

@JFrankfurt JFrankfurt changed the title fix: update wcv2 to remove polyfills, fix crypto.decode errors, allow… fix: upgrades @walletconnect/ethereum-provider and @walletconnect/modal Aug 2, 2023
@@ -13,7 +12,6 @@ export default function Home() {
<div style={{ display: 'flex', flexFlow: 'wrap', fontFamily: 'sans-serif' }}>
<MetaMaskCard />
<WalletConnectV2Card />
<WalletConnectCard />
Copy link
Contributor Author

Choose a reason for hiding this comment

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

removing broken example

packages/walletconnect-v2/src/index.ts Outdated Show resolved Hide resolved
packages/walletconnect-v2/src/index.ts Outdated Show resolved Hide resolved
packages/walletconnect-v2/src/index.ts Outdated Show resolved Hide resolved
packages/walletconnect-v2/src/index.ts Outdated Show resolved Hide resolved
Comment on lines 90 to 94
return provider
.on('disconnect', this.disconnectListener)
.on('chainChanged', this.chainChangedListener)
.on('accountsChanged', this.accountsChangedListener)
.on('display_uri', this.URIListener)
Copy link
Contributor

Choose a reason for hiding this comment

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

This is only done once. I'd rather it just be inlined into initializeProvider, but I won't make a stink about it.

Copy link
Contributor

Choose a reason for hiding this comment

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

Yup, this is somewhat related to my previous comment #868 (comment) and also +1 here. We should definitely keep things inline unless required by this PR.

Co-authored-by: Zach Pomerantz <zzmp@uniswap.org>
JFrankfurt and others added 3 commits August 4, 2023 12:17
Co-authored-by: Zach Pomerantz <zzmp@uniswap.org>
Co-authored-by: Zach Pomerantz <zzmp@uniswap.org>
Co-authored-by: Zach Pomerantz <zzmp@uniswap.org>
@JFrankfurt JFrankfurt requested a review from zzmp August 4, 2023 17:25
@@ -23,6 +23,19 @@ export type WalletConnectOptions = Omit<Parameters<typeof WalletConnectProvider.
rpc?: { [chainId: number]: string | string[] }
}

/**
* Necessary type to interface with @walletconnect/ethereum-provider@2.9.2 which is currently unexported
Copy link
Contributor

Choose a reason for hiding this comment

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

You should make an upstream issue/PR to have that exported.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Talked to them about it when I first started working on this PR and they said they would take care of exporting it. May be worth checking in again.

@JFrankfurt JFrankfurt merged commit 4d4180d into main Aug 10, 2023
6 checks passed
@JFrankfurt JFrankfurt deleted the update-wcv2 branch August 10, 2023 17:56
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants