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

feat: skip EVM signature message #443

Merged
merged 9 commits into from
Dec 15, 2024
7 changes: 7 additions & 0 deletions .changeset/swift-knives-thank.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
---
"@fuel-connectors/walletconnect-connector": minor
"@e2e-tests/runner": minor
"@fuels/react": minor
---

Skip EVM signature step for previously signed accounts.
4 changes: 2 additions & 2 deletions .github/workflows/pr.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ jobs:
uses: tj-actions/[email protected]
with:
files: |
**/packages/connectors/**
**/packages/**

validate-changeset:
name: Validate PR Changeset
Expand All @@ -43,7 +43,7 @@ jobs:
fetch-depth: 0

- name: CI Setup
uses: FuelLabs/github-actions/setups/node@master
uses: FuelLabs/github-actions/setups/node@58bcd91d7246e40938e1971be0b0fe35b253dff0
with:
node-version: 20.11.0
pnpm-version: 9.5.0
Expand Down
10 changes: 5 additions & 5 deletions e2e-tests/runner/common/common.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { test } from '@fuels/playwright-utils';
import { type Page, expect } from '@playwright/test';
import type { ApproveTransferFunction, ConnectorFunctions } from './types';
import type { ConnectorFunctions } from './types';

// biome-ignore lint/suspicious/noExportsInTest: <explanation>
export const skipBridgeFunds = async (page: Page) => {
Expand All @@ -13,7 +13,7 @@ export const skipBridgeFunds = async (page: Page) => {
// biome-ignore lint/suspicious/noExportsInTest: <explanation>
export const sessionTests = async (
page: Page,
{ connect }: ConnectorFunctions,
{ connect, secondConnect = connect }: ConnectorFunctions,
) => {
await connect(page);

Expand All @@ -23,19 +23,19 @@ export const sessionTests = async (
await page.click('text=Disconnect');
await page.waitForSelector('text=/Connect Wallet/');

await connect(page);
await secondConnect(page);
await skipBridgeFunds(page);

expect(await page.waitForSelector('text=/Your Fuel Address/')).toBeTruthy();
});

await test.step('should connect, refresh and stay connected', async () => {
await test.step('should refresh and stay connected', async () => {
await page.reload();
await skipBridgeFunds(page);
await page.waitForSelector('text=/Your Fuel Address/');
});

await test.step('should connect, disconnect, refresh and stay disconnected', async () => {
await test.step('should disconnect, refresh and stay disconnected', async () => {
await skipBridgeFunds(page);
await page.click('text=Disconnect');
await page.waitForSelector('text=/Connect Wallet/');
Expand Down
2 changes: 1 addition & 1 deletion e2e-tests/runner/common/types.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
// types.ts
import type { Page } from '@playwright/test';

export type ConnectFunction = (page: Page) => Promise<void>;
Expand All @@ -10,6 +9,7 @@ export type ApproveTransferFunction = (page: Page) => Promise<void>;
*/
export interface ConnectorFunctions {
connect: ConnectFunction;
secondConnect?: ConnectFunction;
approveTransfer: ApproveTransferFunction;
keepSession?: boolean;
}
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ test.describe('SolanaConnector', () => {
const connectButton = getButtonByText(page, 'Connect Wallet', true);
await connectButton.click();
await getByAriaLabel(page, 'Connect to Solana Wallets', true).click();
await page.getByText('Proceed anyway').click();
await page.getByText('Proceed').click();
await getButtonByText(page, 'Phantom').click();
try {
await phantomExtended.acceptAccess();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,23 +34,31 @@ test.describe('WalletConnectConnector', () => {
await page.goto('/', { waitUntil: 'domcontentloaded' });
});

const connect: ConnectorFunctions['connect'] = async (page) => {
const commonConnect: ConnectorFunctions['connect'] = async (page) => {
const connectButton = getButtonByText(page, 'Connect Wallet', true);
await connectButton.click();
await getByAriaLabel(page, 'Connect to Ethereum Wallets', true).click();
await page.getByText('Proceed anyway').click();
await page.getByText('Proceed').click();
await getButtonByText(page, 'MetaMask', true).click();
await metamask.connectToDapp();
await page.waitForTimeout(4000);
};

// First-time connection requires a message signature (to prove ownership of the wallet)
const connect: ConnectorFunctions['connect'] = async (page) => {
await commonConnect(page);
await metamask.confirmSignature();
};

// From here on, we'll skip the signature step
const secondConnect: ConnectorFunctions['connect'] = commonConnect;

const approveTransfer: ConnectorFunctions['approveTransfer'] = async () => {
await metamask.confirmTransaction();
};

test('Ethereum session tests', async ({ page }) => {
await sessionTests(page, { connect, approveTransfer });
await sessionTests(page, { connect, secondConnect, approveTransfer });
});

test('Ethereum transfer tests', async ({ page }) => {
Expand All @@ -72,7 +80,15 @@ test.describe('WalletConnectConnector', () => {
throw new Error('Address is null');
}

await transferTests(page, { connect, approveTransfer, keepSession: true });
await incrementTests(page, { connect, approveTransfer, keepSession: true });
await transferTests(page, {
connect,
approveTransfer,
keepSession: true,
});
await incrementTests(page, {
connect,
approveTransfer,
keepSession: true,
});
});
});
7 changes: 1 addition & 6 deletions e2e-tests/runner/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -29,10 +29,5 @@
"dotenv": "16.4.5",
"@phantom/synpress": "4.0.0-alpha.53",
"fuels": "0.96.1"
},
"engines": {
"node": ">=20.11.0",
"pnpm": "9.x"
},
"packageManager": "[email protected]"
}
}
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@
"vitest": "2.0.2"
},
"engines": {
"node": ">=20.11.0",
"node": "20.x",
"pnpm": "9.x"
},
"pnpm": {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,7 @@ export function ExternalDisclaimer() {
</DisclaimerList>
</DisclaimerContainer>
<ConnectorButtonPrimary onClick={() => _startConnection(connector)}>
Proceed anyway
Proceed
</ConnectorButtonPrimary>
<ConnectorButton onClick={() => back()}>
Select a Native Wallet
Expand Down
12 changes: 8 additions & 4 deletions packages/walletconnect-connector/src/WalletConnectConnector.ts
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ import {
} from '@fuel-connectors/common';
import { PREDICATE_VERSIONS } from '@fuel-connectors/evm-predicates';
import { ApiController } from '@web3modal/core';
import { stringToHex } from 'viem';
import {
ETHEREUM_ICON,
HAS_WINDOW,
Expand Down Expand Up @@ -330,7 +331,10 @@ export class WalletConnectConnector extends PredicateConnector {

async requestValidation(address?: string) {
return new Promise(async (resolve, reject) => {
// Disconnect if user dosen't provide signature in time
const hasSignature = await this.accountHasValidation(address);
if (hasSignature) return resolve(true);

// Disconnect if user doesn't provide signature in time
const validationTimeout = setTimeout(() => {
reject(
new Error("User didn't provide signature in less than 1 minute"),
Expand Down Expand Up @@ -358,11 +362,11 @@ export class WalletConnectConnector extends PredicateConnector {
const wagmiConfig = this.getWagmiConfig();
if (!wagmiConfig) throw new Error('Wagmi config not found');

const { addresses, connector, isConnected } = getAccount(wagmiConfig);
const { connector, isConnected } = getAccount(wagmiConfig);
await disconnect(wagmiConfig, {
connector,
});
addresses?.map((a) => this.storage.removeItem(`SIGNATURE_VALIDATION_${a}`));

return isConnected || false;
}

Expand Down Expand Up @@ -440,7 +444,7 @@ export class WalletConnectConnector extends PredicateConnector {
const message = `Sign this message to verify the connected account: ${currentAccount}`;
const signature = (await ethProvider.request({
method: 'personal_sign',
params: [message, currentAccount],
params: [stringToHex(message), currentAccount],
})) as string;

if (!this.validateSignature(currentAccount, message, signature)) {
Expand Down
Loading