-
Notifications
You must be signed in to change notification settings - Fork 4
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: Add safe wallet support #77
Changes from 8 commits
a03fda3
a4defde
ca3d2ef
6649037
bc8663d
1cecf9b
e3e6ff7
4b57e5f
be9be5a
c57fa93
4c3cb0a
6f3cb59
e3e1e18
a1d6ea9
3ad6177
1baf049
b27dd59
60de9e7
3b47f5e
4da45e1
af4085b
d681b54
3c0b635
457c91a
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1 +1 @@ | ||
16.18.1 | ||
18 |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1 +1,12 @@ | ||
module.exports = {}; | ||
module.exports = { | ||
webpack: (config, context) => { | ||
if (config.plugins) { | ||
config.plugins.push( | ||
new context.webpack.IgnorePlugin({ | ||
resourceRegExp: /^(lokijs|pino-pretty|encoding)$/, | ||
}), | ||
); | ||
} | ||
return config; | ||
}, | ||
}; |
fionnachan marked this conversation as resolved.
Show resolved
Hide resolved
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. i was extremely confused by the UX here clicking the submit button on this page should not bring the user to As a user, I am expecting to stay on this page after clicking "Submit" because the address it was showing was initially my MM address because I connected to the site using it first There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. "Enter the destination address" is not clear enough for a normie user There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. we should avoid showing the chain id directly to users, and always use network name |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,53 +1,78 @@ | ||
'use client'; | ||
import { getTargetChainId } from '@/utils'; | ||
import { utils } from 'ethers'; | ||
import { supportedL2Networks } from '@/utils/network'; | ||
import { Address } from '@arbitrum/sdk'; | ||
import { constants, utils } from 'ethers'; | ||
import dynamic from 'next/dynamic'; | ||
import React, { useEffect, useState } from 'react'; | ||
import { useNetwork } from 'wagmi'; | ||
import { | ||
getData, | ||
hasBalanceOverThreshold, | ||
OperationInfo, | ||
} from './RecoverFunds'; | ||
import { hasBalanceOverThreshold, OperationInfo } from './RecoverFunds'; | ||
import { RecoverFundsButton } from './RecoverFundsButton'; | ||
import { JsonRpcProvider } from '@ethersproject/providers'; | ||
|
||
const RecoverFunds = dynamic(() => import('./RecoverFunds'), { | ||
ssr: false, | ||
}); | ||
|
||
const RecoverFundsPage = ({ | ||
params: { address }, | ||
}: { | ||
params: { address: string }; | ||
}) => { | ||
const { chain } = useNetwork(); | ||
const [operationInfo, setOperationInfo] = useState<OperationInfo | null>( | ||
null, | ||
); | ||
const [destinationAddress, setDestinationAddress] = useState<string | null>( | ||
null, | ||
); | ||
type OperationInfoByChainId = { | ||
[chainId: string]: OperationInfo; | ||
}; | ||
async function getOperationInfoByChainId( | ||
address: string, | ||
): Promise<OperationInfoByChainId> { | ||
// First, obtain the aliased address of the signer | ||
const destinationAddress = new Address(address); | ||
const { value: aliasedAddress } = destinationAddress.applyAlias(); | ||
|
||
const targetChainID = getTargetChainId(chain?.id); | ||
// And get its balance to find out the amount we are transferring | ||
const operationInfoPromises = Object.entries(supportedL2Networks).map( | ||
async ([chainId, rpcURL]) => { | ||
const l2Provider = new JsonRpcProvider(rpcURL); | ||
|
||
useEffect(() => { | ||
if (!targetChainID) { | ||
return; | ||
} | ||
try { | ||
const aliasedSignerBalance = await l2Provider.getBalance( | ||
aliasedAddress, | ||
); | ||
|
||
getData(targetChainID, address).then((data) => { | ||
setOperationInfo(data); | ||
}); | ||
}, [address, targetChainID]); | ||
return { | ||
balanceToRecover: hasBalanceOverThreshold(aliasedSignerBalance) | ||
? aliasedSignerBalance | ||
: constants.Zero, | ||
aliasedAddress, | ||
chainId, | ||
}; | ||
} catch (e) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. If the RPC fails for whatever reason, the page will tell the user that there are no funds to recover, but that might be misleading. |
||
return { | ||
balanceToRecover: constants.Zero, | ||
aliasedAddress, | ||
chainId, | ||
}; | ||
} | ||
}, | ||
); | ||
|
||
const handleChange: React.ChangeEventHandler<HTMLInputElement> = (e) => { | ||
const value = e.target.value; | ||
setDestinationAddress(value); | ||
}; | ||
const result = Promise.all(operationInfoPromises); | ||
return result.then((operationInfo) => { | ||
return operationInfo.reduce( | ||
(acc, info) => ({ | ||
...acc, | ||
[info.chainId]: info, | ||
}), | ||
{}, | ||
); | ||
}); | ||
} | ||
|
||
if (!operationInfo) { | ||
return; | ||
} | ||
function RecoverFundsDetail({ | ||
operationInfo, | ||
address, | ||
}: { | ||
operationInfo: OperationInfo; | ||
address: string; | ||
}) { | ||
const { chain } = useNetwork(); | ||
const [destinationAddress, setDestinationAddress] = useState<string | null>( | ||
null, | ||
); | ||
|
||
const hasBalanceToRecover = hasBalanceOverThreshold( | ||
operationInfo.balanceToRecover, | ||
|
@@ -58,6 +83,15 @@ const RecoverFundsPage = ({ | |
utils.isAddress(destinationAddress) && | ||
operationInfo.aliasedAddress; | ||
|
||
const handleChange: React.ChangeEventHandler<HTMLInputElement> = (e) => { | ||
const value = e.target.value; | ||
setDestinationAddress(value); | ||
}; | ||
|
||
if (!hasBalanceOverThreshold(operationInfo.balanceToRecover)) { | ||
return null; | ||
} | ||
|
||
return ( | ||
<> | ||
<RecoverFunds address={address} operationInfo={operationInfo} /> | ||
|
@@ -73,14 +107,64 @@ const RecoverFundsPage = ({ | |
)} | ||
{hasBalanceToRecover && hasDestinationAddress && ( | ||
<RecoverFundsButton | ||
chainID={chain.id} | ||
chainID={Number(operationInfo.chainId)} | ||
balanceToRecover={operationInfo.balanceToRecover} | ||
destinationAddress={destinationAddress} | ||
addressToRecoverFrom={address} | ||
/> | ||
)} | ||
</> | ||
); | ||
} | ||
|
||
const RecoverFundsPage = ({ | ||
params: { address }, | ||
}: { | ||
params: { address: string }; | ||
}) => { | ||
const [operationInfos, setOperationInfos] = | ||
useState<OperationInfoByChainId | null>(null); | ||
|
||
useEffect(() => { | ||
getOperationInfoByChainId(address).then((operationInfoByChainId) => { | ||
setOperationInfos(operationInfoByChainId); | ||
}); | ||
}, [address]); | ||
|
||
if (!operationInfos) { | ||
return; | ||
} | ||
|
||
// No balance to recover on any chains | ||
if ( | ||
Object.keys(operationInfos).every( | ||
(chainId) => | ||
!hasBalanceOverThreshold(operationInfos[chainId].balanceToRecover), | ||
) | ||
) { | ||
const aliasedAddress = | ||
operationInfos[Object.keys(operationInfos)[0]].aliasedAddress; | ||
|
||
return ( | ||
<div className="funds-message"> | ||
There are no funds stuck on {aliasedAddress} | ||
<br /> | ||
(Alias of {address}) on Arbitrum networks | ||
</div> | ||
); | ||
} | ||
|
||
return ( | ||
<> | ||
{Object.keys(operationInfos).map((chainId) => ( | ||
<RecoverFundsDetail | ||
address={address} | ||
operationInfo={operationInfos[chainId]} | ||
key={chainId} | ||
/> | ||
))} | ||
</> | ||
); | ||
}; | ||
|
||
export default RecoverFundsPage; |
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.
what is this for?
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.
Fix error in building for nextjs: WalletConnect/walletconnect-monorepo#1908 (comment)
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.
best if we add a link to this in the file