Skip to content

Commit

Permalink
Merge pull request #4180 from WalletConnect/feat/w3wallet-events
Browse files Browse the repository at this point in the history
feat: adds `session_request_expire` & `proposal_expire` to w3w
  • Loading branch information
ganchoradkov authored Feb 1, 2024
2 parents 51ec49e + f7a777c commit 20c2985
Show file tree
Hide file tree
Showing 6 changed files with 131 additions and 3 deletions.
1 change: 1 addition & 0 deletions packages/sign-client/src/constants/client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ export const SIGN_CLIENT_EVENTS: Record<SignClientTypes.Event, SignClientTypes.E
session_request_sent: "session_request_sent",
session_event: "session_event",
proposal_expire: "proposal_expire",
session_request_expire: "session_request_expire",
};

export const SIGN_CLIENT_STORAGE_OPTIONS = {
Expand Down
1 change: 1 addition & 0 deletions packages/sign-client/src/controllers/engine.ts
Original file line number Diff line number Diff line change
Expand Up @@ -538,6 +538,7 @@ export class Engine extends IEngine {
// set the requestQueue state to idle if expirer has deleted a request as trying to respond to it would result in an exception
if (expirerHasDeleted) {
this.sessionRequestQueue.state = ENGINE_QUEUE_STATES.idle;
this.client.events.emit("session_request_expire", { id });
}
};

Expand Down
4 changes: 3 additions & 1 deletion packages/types/src/sign-client/client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,8 @@ export declare namespace SignClientTypes {
| "session_request"
| "session_request_sent"
| "session_event"
| "proposal_expire";
| "proposal_expire"
| "session_request_expire";

interface BaseEventArgs<T = unknown> {
id: number;
Expand Down Expand Up @@ -51,6 +52,7 @@ export declare namespace SignClientTypes {
chainId: string;
}>;
proposal_expire: { id: number };
session_request_expire: { id: number };
}

type Metadata = CoreTypes.Metadata;
Expand Down
10 changes: 10 additions & 0 deletions packages/web3wallet/src/controllers/engine.ts
Original file line number Diff line number Diff line change
Expand Up @@ -121,10 +121,20 @@ export class Engine extends IWeb3WalletEngine {
this.client.events.emit("auth_request", event);
};

private onProposalExpire = (event: Web3WalletTypes.ProposalExpire) => {
this.client.events.emit("proposal_expire", event);
};

private onSessionRequestExpire = (event: Web3WalletTypes.SessionRequestExpire) => {
this.client.events.emit("session_request_expire", event);
};

private initializeEventListeners = () => {
this.signClient.events.on("session_proposal", this.onSessionProposal);
this.signClient.events.on("session_request", this.onSessionRequest);
this.signClient.events.on("session_delete", this.onSessionDelete);
this.authClient.on("auth_request", this.onAuthRequest);
this.signClient.events.on("proposal_expire", this.onProposalExpire);
this.signClient.events.on("session_request_expire", this.onSessionRequestExpire);
};
}
14 changes: 13 additions & 1 deletion packages/web3wallet/src/types/client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,13 @@ import { Logger } from "@walletconnect/logger";
import { JsonRpcPayload } from "@walletconnect/jsonrpc-utils";

export declare namespace Web3WalletTypes {
type Event = "session_proposal" | "session_request" | "session_delete" | "auth_request";
type Event =
| "session_proposal"
| "session_request"
| "session_delete"
| "auth_request"
| "proposal_expire"
| "session_request_expire";

interface BaseEventArgs<T = unknown> {
id: number;
Expand All @@ -29,11 +35,17 @@ export declare namespace Web3WalletTypes {

type SessionDelete = Omit<BaseEventArgs, "params">;

type ProposalExpire = { id: number };

type SessionRequestExpire = { id: number };

interface EventArguments {
session_proposal: SessionProposal;
session_request: SessionRequest;
session_delete: Omit<BaseEventArgs, "params">;
auth_request: AuthRequest;
proposal_expire: ProposalExpire;
session_request_expire: SessionRequestExpire;
}

interface Options {
Expand Down
104 changes: 103 additions & 1 deletion packages/web3wallet/test/sign.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,10 @@ import {
formatJsonRpcResult,
isJsonRpcRequest,
} from "@walletconnect/jsonrpc-utils";
import { SignClient } from "@walletconnect/sign-client";
import { SignClient, ENGINE_RPC_OPTS } from "@walletconnect/sign-client";
import { CoreTypes, ICore, ISignClient, SessionTypes } from "@walletconnect/types";
import { getSdkError } from "@walletconnect/utils";
import { toMiliseconds } from "@walletconnect/time";
import { Wallet as CryptoWallet } from "@ethersproject/wallet";

import { expect, describe, it, beforeEach, vi, beforeAll, afterAll } from "vitest";
Expand Down Expand Up @@ -383,6 +384,107 @@ describe("Sign Integration", () => {
]);
});

it("receive proposal_expire event", async () => {
const { uri: uriString } = await dapp.connect({ requiredNamespaces: TEST_REQUIRED_NAMESPACES });

// first pair and approve session
await Promise.all([
new Promise<void>((resolve) => {
wallet.once("session_proposal", () => {
vi.useFakeTimers({
shouldAdvanceTime: true,
shouldClearNativeTimers: true,
});
// Fast-forward system time by 4 min 58 seconds after expiry was first set.
vi.setSystemTime(
Date.now() + toMiliseconds(ENGINE_RPC_OPTS.wc_sessionPropose.req.ttl - 2),
);
});
wallet.on("session_proposal", async (event) => {
const { id } = event;
const startTimer = Date.now();
await new Promise<void>((resolve) => {
wallet.on("proposal_expire", (event) => {
const { id: expiredId } = event;
if (id === expiredId) {
expect(startTimer).to.be.approximately(Date.now(), 5000); // 5 seconds delta for heartbeat
resolve();
}
});
});
resolve();
});
}),
wallet.pair({ uri: uriString! }),
]);
vi.useRealTimers();
});
it("receive session_request_expire event", async () => {
// first pair and approve session
await Promise.all([
new Promise((resolve) => {
wallet.on("session_proposal", async (sessionProposal) => {
const { id, params } = sessionProposal;
session = await wallet.approveSession({
id,
namespaces: {
eip155: {
...TEST_NAMESPACES.eip155,
accounts: [`${TEST_ETHEREUM_CHAIN}:${cryptoWallet.address}`],
},
},
});
expect(params.requiredNamespaces).to.toMatchObject(TEST_REQUIRED_NAMESPACES);
resolve(session);
});
}),
sessionApproval(),
wallet.pair({ uri: uriString }),
]);
// first pair and approve session
await Promise.all([
new Promise<void>((resolve) => {
wallet.once("session_request", () => {
vi.useFakeTimers({
shouldAdvanceTime: true,
shouldClearNativeTimers: true,
});
// Fast-forward system time by 4 min 58 seconds after expiry was first set.
vi.setSystemTime(
Date.now() + toMiliseconds(ENGINE_RPC_OPTS.wc_sessionRequest.req.ttl - 2),
);
});
wallet.on("session_request", async (event) => {
const { id } = event;
const startTimer = Date.now();
await new Promise<void>((resolve) => {
wallet.on("session_request_expire", (event) => {
const { id: expiredId } = event;
if (id === expiredId) {
expect(startTimer).to.be.approximately(Date.now(), 5000); // 5 seconds delta for heartbeat
resolve();
}
});
});
await wallet.respondSessionRequest({
topic: session.topic,
response: formatJsonRpcResult(id, "0x"),
});
resolve();
});
}),
dapp.request({
topic: session.topic,
request: {
method: "eth_signTransaction",
params: ["0xdeadbeef", cryptoWallet.address],
},
chainId: TEST_ETHEREUM_CHAIN,
}),
]);
vi.useRealTimers();
});

it("should get pending session requests", async () => {
// first pair and approve session
await Promise.all([
Expand Down

0 comments on commit 20c2985

Please sign in to comment.