From ecc22a319bfca1b6a899df63a53f3ae10ebdc037 Mon Sep 17 00:00:00 2001 From: Victor Lopes Date: Fri, 17 Nov 2023 02:18:56 +0100 Subject: [PATCH] fix: dialog approval should halt signature return (#6) * fix: dialog approval should halt signature return * fix lints --- packages/site/src/components/Sovereign.tsx | 28 +++++++++++++++++ packages/snap/snap.manifest.json | 2 +- packages/snap/src/index.test.ts | 9 ++++-- packages/snap/src/index.ts | 36 +++++++++++++++++++--- 4 files changed, 67 insertions(+), 8 deletions(-) diff --git a/packages/site/src/components/Sovereign.tsx b/packages/site/src/components/Sovereign.tsx index a617d58f..c1053a5a 100644 --- a/packages/site/src/components/Sovereign.tsx +++ b/packages/site/src/components/Sovereign.tsx @@ -11,6 +11,7 @@ type SovereignState = { keyId: number; nonce: number; message?: string; + pk?: string; tx?: string; sequencer?: string; status?: string; @@ -86,6 +87,12 @@ export const Sovereign = () => {
{ + setState({ + ...state, + pk: '', + tx: '', + }); + try { const { keyId, nonce, message } = state; const path = ['m', "44'", "1551'", `${keyId}'`]; @@ -97,6 +104,22 @@ export const Sovereign = () => { }, }; + const pkRequest = { + method: 'wallet_invokeSnap', + params: { + snapId: defaultSnapOrigin, + request: { + method: 'getPublicKey', + params: { + path, + compressed: true, + }, + }, + }, + }; + + const pk = await window.ethereum.request(pkRequest); + const request = { method: 'wallet_invokeSnap', params: { @@ -111,6 +134,7 @@ export const Sovereign = () => { const response = await window.ethereum.request(request); setState({ ...state, + pk: pk ?? '', tx: response ?? '', }); } catch (er) { @@ -122,6 +146,10 @@ export const Sovereign = () => { }} />
+
Public Key:
+
+ +
Transaction:
diff --git a/packages/snap/snap.manifest.json b/packages/snap/snap.manifest.json index c0f8b1d7..c0d2fbc5 100644 --- a/packages/snap/snap.manifest.json +++ b/packages/snap/snap.manifest.json @@ -7,7 +7,7 @@ "url": "https://github.com/Sovereign-Labs/sov-snap.git" }, "source": { - "shasum": "dHbeVd+8Pvoip3rOqq31v+STlhExNRpJAhMukHTom3g=", + "shasum": "ZcjIMDNneWe6FWkEl1qAXeyFYYTAwtJ+GuCnp6JKoMk=", "location": { "npm": { "filePath": "dist/bundle.js", diff --git a/packages/snap/src/index.test.ts b/packages/snap/src/index.test.ts index 0dad3b4d..0636a84a 100644 --- a/packages/snap/src/index.test.ts +++ b/packages/snap/src/index.test.ts @@ -22,14 +22,19 @@ describe('onRpcRequest', () => { it('returns a public key', async () => { const { request, close } = await installSnap(); - const response = await request({ + const response = request({ method: 'getPublicKey', params: { path: ['m', "44'", "1551'"], }, }); - expect(response).toRespondWith( + const ui = await response.getInterface(); + expect(ui.type).toBe('confirmation'); + + await ui.ok(); + + expect(await response).toRespondWith( '0x00ff3c690d2a58db6d7f97e9ed0aa3455dd54a21246cf71492f36d60bb7c0a659f', ); diff --git a/packages/snap/src/index.ts b/packages/snap/src/index.ts index 0fe91534..9028ea4e 100644 --- a/packages/snap/src/index.ts +++ b/packages/snap/src/index.ts @@ -16,18 +16,41 @@ const wasm = new SovWasm(); * * @param args - The request handler args as object. * invoked the snap. + * @param args.origin - The origin of the request. * @param args.request - A validated JSON-RPC request object. * @returns The result of `snap_dialog`. * @throws If the request method is not valid for this snap. */ -export const onRpcRequest: OnRpcRequestHandler = async ({ request }) => { +export const onRpcRequest: OnRpcRequestHandler = async ({ + origin, + request, +}) => { switch (request.method) { // the return is a plain hex string // https://docs.metamask.io/snaps/reference/rpc-api/#returns-5 case 'getPublicKey': { const { path, compressed } = request.params as GetBip32PublicKeyParams; - return snap.request({ + // eslint-disable-next-line @typescript-eslint/await-thenable + const approved = await snap.request({ + method: 'snap_dialog', + params: { + type: DialogType.Confirmation, + content: panel([ + heading('Public key request'), + text(`The origin`), + copyable(origin), + text(`is requesting your public key.`), + ]), + }, + }); + + if (!approved) { + throw providerErrors.userRejectedRequest(); + } + + // eslint-disable-next-line @typescript-eslint/await-thenable + return await snap.request({ method: 'snap_getBip32PublicKey', params: { path, @@ -55,17 +78,20 @@ export const onRpcRequest: OnRpcRequestHandler = async ({ request }) => { const node = await SLIP10Node.fromJSON(entropy); assert(node.privateKey); - const approved = snap.request({ + // eslint-disable-next-line @typescript-eslint/await-thenable + const approved = await snap.request({ method: 'snap_dialog', params: { type: DialogType.Confirmation, content: panel([ heading('Signature request'), - text(`Do you want to sign`), + text(`The origin`), + copyable(origin), + text(`is requesting a signature for the message`), copyable(transaction.message), text(`with nonce`), copyable(transaction.nonce.toString()), - text(`and the following public key?`), + text(`and the following public key`), copyable(add0x(node.publicKey)), ]), },