Add support for wallet_getCapabilities from WalletConnect
#39
18
src/App.tsx
18
src/App.tsx
@ -146,6 +146,23 @@ const App = (): React.JSX.Element => {
|
||||
requestSessionData,
|
||||
});
|
||||
break;
|
||||
|
||||
case EIP155_SIGNING_METHODS.WALLET_GET_CAPABILITIES:
|
||||
const supportedNetworks = networksData
|
||||
.filter(network => network.namespace === EIP155)
|
||||
.map(network => `${network.namespace}:${network.chainId}`);
|
||||
const capabilitiesResponse = formatJsonRpcResult(id, {
|
||||
accountManagement: true,
|
||||
sessionManagement: true,
|
||||
supportedAuthMethods: ['personal_sign', 'eth_sendTransaction'],
|
||||
supportedNetworks: supportedNetworks,
|
||||
});
|
||||
|
||||
await web3wallet!.respondSessionRequest({
|
||||
topic,
|
||||
response: capabilitiesResponse,
|
||||
});
|
||||
break;
|
||||
|
||||
case COSMOS_METHODS.COSMOS_SIGN_DIRECT:
|
||||
const message = {
|
||||
@ -347,6 +364,7 @@ const App = (): React.JSX.Element => {
|
||||
// eslint-disable-next-line react/no-unstable-nested-components
|
||||
headerRight: () => (
|
||||
<Button
|
||||
testID="pair-button"
|
||||
onPress={() => {
|
||||
navigation.navigate("AddSession");
|
||||
}}
|
||||
|
||||
@ -104,7 +104,7 @@ export const Header: React.FC<{
|
||||
</Stack>
|
||||
|
||||
{showWalletConnect && (
|
||||
<Button onClick={() => navigation.navigate("WalletConnect")}>
|
||||
<Button data-webviewId="wallet-connect-button" onClick={() => navigation.navigate("WalletConnect")}>
|
||||
{<WCLogo />}
|
||||
</Button>
|
||||
)}
|
||||
|
||||
@ -282,20 +282,24 @@ const PairingModal = ({
|
||||
)}
|
||||
</View>
|
||||
</ScrollView>
|
||||
|
||||
<View style={styles.flexRow}>
|
||||
<Button
|
||||
mode="contained"
|
||||
onPress={handleAccept}
|
||||
loading={isLoading}
|
||||
disabled={isLoading}>
|
||||
{isLoading ? 'Connecting' : 'Yes'}
|
||||
</Button>
|
||||
<View style={styles.space} />
|
||||
<Button mode="outlined" onPress={handleReject}>
|
||||
No
|
||||
</Button>
|
||||
</View>
|
||||
|
||||
{currentProposal && namespaces && (
|
||||
<View style={styles.flexRow}>
|
||||
<Button
|
||||
mode="contained"
|
||||
testID="accept-pair-request-button"
|
||||
onPress={handleAccept}
|
||||
loading={isLoading}
|
||||
disabled={isLoading}>
|
||||
{isLoading ? 'Connecting' : 'Yes'}
|
||||
</Button>
|
||||
<View style={styles.space} />
|
||||
<Button mode="outlined" onPress={handleReject}>
|
||||
No
|
||||
</Button>
|
||||
</View>
|
||||
)}
|
||||
|
||||
</View>
|
||||
</View>
|
||||
</Modal>
|
||||
|
||||
@ -44,7 +44,7 @@ const AddSession = () => {
|
||||
/>
|
||||
|
||||
<Box sx={{ mt: 2 }}>
|
||||
<Button variant="contained" onClick={pair}>
|
||||
<Button variant="contained" data-webviewId="pair-session-button" onClick={pair}>
|
||||
Pair Session
|
||||
</Button>
|
||||
</Box>
|
||||
|
||||
@ -82,23 +82,27 @@ const ApproveTransfer = ({ route }: ApproveTransferProps) => {
|
||||
useState<BigNumber | null>();
|
||||
|
||||
const isSufficientFunds = useMemo(() => {
|
||||
if (!transaction.value) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!balance) {
|
||||
return;
|
||||
}
|
||||
|
||||
const amountBigNum = BigNumber.from(String(transaction.value));
|
||||
const balanceBigNum = BigNumber.from(balance);
|
||||
|
||||
if (amountBigNum.gte(balanceBigNum)) {
|
||||
return false;
|
||||
} else {
|
||||
return true;
|
||||
if (!fees) {
|
||||
return;
|
||||
}
|
||||
}, [balance, transaction]);
|
||||
|
||||
const balanceBigNum = BigNumber.from(balance);
|
||||
const feesBigNum = BigNumber.from(fees);
|
||||
let totalRequiredBigNum = feesBigNum;
|
||||
|
||||
if (transaction.value) {
|
||||
const amountBigNum = BigNumber.from(String(transaction.value));
|
||||
totalRequiredBigNum = amountBigNum.add(feesBigNum);
|
||||
}
|
||||
|
||||
// Compare the user's balance with the total required amount
|
||||
const isSufficient = balanceBigNum.gte(totalRequiredBigNum);
|
||||
return isSufficient;
|
||||
}, [balance, transaction.value, fees]);
|
||||
|
||||
const requestedNetwork = networksData.find(
|
||||
networkData =>
|
||||
@ -273,8 +277,12 @@ const ApproveTransfer = ({ route }: ApproveTransferProps) => {
|
||||
|
||||
useEffect(() => {
|
||||
if (namespace === EIP155) {
|
||||
const ethFees = BigNumber.from(ethGasLimit ?? 0)
|
||||
.mul(BigNumber.from(ethMaxFee ?? ethGasPrice ?? 0))
|
||||
if (!ethGasLimit || !(ethMaxFee || ethGasPrice)){
|
||||
return;
|
||||
}
|
||||
|
||||
const ethFees = BigNumber.from(ethGasLimit)
|
||||
.mul(BigNumber.from(ethMaxFee ?? ethGasPrice))
|
||||
.toString();
|
||||
setFees(ethFees);
|
||||
} else {
|
||||
@ -495,7 +503,7 @@ const ApproveTransfer = ({ route }: ApproveTransferProps) => {
|
||||
useEffect(() => {
|
||||
const getEthGas = async () => {
|
||||
try {
|
||||
if (!isSufficientFunds || !provider) {
|
||||
if (!provider) {
|
||||
return;
|
||||
}
|
||||
|
||||
@ -568,11 +576,11 @@ const ApproveTransfer = ({ route }: ApproveTransferProps) => {
|
||||
}, [cosmosStargateClient, isSufficientFunds, sendMsg, transaction,txMemo]);
|
||||
|
||||
useEffect(() => {
|
||||
if (balance && !isSufficientFunds) {
|
||||
if (balance && !isSufficientFunds && !fees) {
|
||||
setTxError('Insufficient funds');
|
||||
setIsTxErrorDialogOpen(true);
|
||||
}
|
||||
}, [isSufficientFunds, balance]);
|
||||
}, [isSufficientFunds, balance, fees]);
|
||||
|
||||
return (
|
||||
<>
|
||||
@ -614,14 +622,16 @@ const ApproveTransfer = ({ route }: ApproveTransferProps) => {
|
||||
{transaction && (
|
||||
<View style={styles.approveTransfer}>
|
||||
<DataBox label="To" data={transaction.to!} />
|
||||
<DataBox
|
||||
label={`Amount (${
|
||||
namespace === EIP155 ? 'wei' : requestedNetwork!.nativeDenom
|
||||
})`}
|
||||
data={BigNumber.from(
|
||||
transaction.value?.toString(),
|
||||
).toString()}
|
||||
/>
|
||||
{transaction.value !== undefined && transaction.value !== null && (
|
||||
<DataBox
|
||||
label={`Amount (${
|
||||
namespace === EIP155 ? 'wei' : requestedNetwork!.nativeDenom
|
||||
})`}
|
||||
data={BigNumber.from(
|
||||
transaction.value?.toString(),
|
||||
).toString()}
|
||||
/>
|
||||
)}
|
||||
{namespace === COSMOS && (
|
||||
<DataBox
|
||||
label="Memo"
|
||||
|
||||
@ -116,7 +116,8 @@ const SignRequest = ({ route }: SignRequestProps) => {
|
||||
);
|
||||
|
||||
useEffect(() => {
|
||||
if (route.path) {
|
||||
const requestEvent = route.params.requestEvent;
|
||||
if (route.path && !requestEvent) {
|
||||
const sanitizedRoute = sanitizePath(route.path);
|
||||
sanitizedRoute &&
|
||||
retrieveData(
|
||||
@ -127,7 +128,6 @@ const SignRequest = ({ route }: SignRequestProps) => {
|
||||
);
|
||||
return;
|
||||
}
|
||||
const requestEvent = route.params.requestEvent;
|
||||
const requestChainId = requestEvent?.params.chainId;
|
||||
|
||||
const requestedChain = networksData.find(
|
||||
@ -310,6 +310,7 @@ const SignRequest = ({ route }: SignRequestProps) => {
|
||||
<View style={styles.buttonContainer}>
|
||||
<Button
|
||||
mode="contained"
|
||||
testID="accept-sign-request-button"
|
||||
onPress={signMessageHandler}
|
||||
loading={isApproving}
|
||||
disabled={isApproving}>
|
||||
|
||||
@ -43,15 +43,20 @@ export default function WalletConnect() {
|
||||
// eslint-disable-next-line react/no-unstable-nested-components
|
||||
left={() => (
|
||||
<>
|
||||
{session.peer.metadata.icons[0].endsWith(".svg") ? (
|
||||
<View style={styles.dappLogo}>
|
||||
<Text>SvgURI peerMetaDataIcon</Text>
|
||||
</View>
|
||||
{session.peer.metadata.icons && session.peer.metadata.icons.length > 0 ? (
|
||||
session.peer.metadata.icons[0].endsWith(".svg") ? (
|
||||
<View style={styles.dappLogo}>
|
||||
<Text>SvgURI peerMetaDataIcon</Text>
|
||||
</View>
|
||||
) : (
|
||||
<Image
|
||||
style={styles.dappLogo}
|
||||
source={{ uri: session.peer.metadata.icons[0] }}
|
||||
/>
|
||||
)
|
||||
) : (
|
||||
<Image
|
||||
style={styles.dappLogo}
|
||||
source={{ uri: session.peer.metadata.icons[0] }}
|
||||
/>
|
||||
// Render nothing if no icon is available
|
||||
<View style={styles.dappLogo} /> // Or simply null
|
||||
)}
|
||||
</>
|
||||
)}
|
||||
|
||||
@ -344,7 +344,7 @@ const retrieveSingleAccount = async (
|
||||
throw new Error('Accounts for given chain not found');
|
||||
}
|
||||
|
||||
return loadedAccounts.find(account => account.address === address);
|
||||
return loadedAccounts.find(account => account.address.toLowerCase() === address.toLowerCase());
|
||||
};
|
||||
|
||||
const resetWallet = async () => {
|
||||
|
||||
@ -40,6 +40,18 @@ export const DEFAULT_NETWORKS: NetworksFormData[] = [
|
||||
coinType: '60',
|
||||
isDefault: true,
|
||||
},
|
||||
|
||||
// Base Chain Network
|
||||
{
|
||||
chainId: '8453',
|
||||
networkName: EIP155_CHAINS['eip155:8453'].name,
|
||||
namespace: EIP155,
|
||||
rpcUrl: EIP155_CHAINS['eip155:8453'].rpc,
|
||||
blockExplorerUrl: '',
|
||||
currencySymbol: 'ETH',
|
||||
coinType: '60',
|
||||
isDefault: true,
|
||||
},
|
||||
{
|
||||
chainId: 'provider',
|
||||
networkName: COSMOS_TESTNET_CHAINS['cosmos:provider'].name,
|
||||
|
||||
@ -11,13 +11,8 @@
|
||||
export type TEIP155Chain = keyof typeof EIP155_CHAINS;
|
||||
|
||||
export type EIP155Chain = {
|
||||
chainId: number;
|
||||
name: string;
|
||||
logo: string;
|
||||
rgb: string;
|
||||
rpc: string;
|
||||
namespace: string;
|
||||
smartAccountEnabled?: boolean;
|
||||
};
|
||||
|
||||
/**
|
||||
@ -25,12 +20,14 @@ export type EIP155Chain = {
|
||||
*/
|
||||
export const EIP155_CHAINS: Record<string, EIP155Chain> = {
|
||||
'eip155:1': {
|
||||
chainId: 1,
|
||||
name: 'Ethereum',
|
||||
logo: '/chain-logos/eip155-1.png',
|
||||
rgb: '99, 125, 234',
|
||||
rpc: 'https://cloudflare-eth.com/',
|
||||
namespace: 'eip155',
|
||||
},
|
||||
|
||||
// Ref: https://docs.base.org/base-chain/quickstart/connecting-to-base#base-mainnet
|
||||
'eip155:8453': {
|
||||
name: 'Base',
|
||||
rpc: 'https://mainnet.base.org',
|
||||
},
|
||||
};
|
||||
|
||||
@ -40,4 +37,5 @@ export const EIP155_CHAINS: Record<string, EIP155Chain> = {
|
||||
export const EIP155_SIGNING_METHODS = {
|
||||
PERSONAL_SIGN: 'personal_sign',
|
||||
ETH_SEND_TRANSACTION: 'eth_sendTransaction',
|
||||
WALLET_GET_CAPABILITIES: 'wallet_getCapabilities'
|
||||
};
|
||||
|
||||
Loading…
Reference in New Issue
Block a user