Skip to content

Commit

Permalink
feat: skip EVM signature message (#443)
Browse files Browse the repository at this point in the history
  • Loading branch information
helciofranco authored Dec 15, 2024
1 parent 78ae803 commit d9c0624
Show file tree
Hide file tree
Showing 10 changed files with 48 additions and 26 deletions.
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

0 comments on commit d9c0624

Please sign in to comment.