This repository has been archived by the owner on Oct 7, 2024. It is now read-only.
generated from MetaMask/metamask-module-template
-
-
Notifications
You must be signed in to change notification settings - Fork 3
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: add
KeyringSnapControllerClient
class (#203)
This commit add the `KeyringSnapControllerClient` to this package since it's being removed from the `keyring-api`. See: <MetaMask/keyring-api#241>
- Loading branch information
Showing
5 changed files
with
422 additions
and
105 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,82 @@ | ||
import type { KeyringAccount } from '@metamask/keyring-api'; | ||
import type { SnapController } from '@metamask/snaps-controllers'; | ||
import type { SnapId } from '@metamask/snaps-sdk'; | ||
|
||
import { KeyringSnapControllerClient } from './KeyringSnapControllerClient'; | ||
|
||
describe('KeyringSnapControllerClient', () => { | ||
const snapId = 'local:localhost:3000' as SnapId; | ||
|
||
const accountsList: KeyringAccount[] = [ | ||
{ | ||
id: '13f94041-6ae6-451f-a0fe-afdd2fda18a7', | ||
address: '0xE9A74AACd7df8112911ca93260fC5a046f8a64Ae', | ||
options: {}, | ||
methods: [], | ||
type: 'eip155:eoa', | ||
}, | ||
]; | ||
|
||
const controller = { | ||
handleRequest: jest.fn(), | ||
}; | ||
|
||
describe('listAccounts', () => { | ||
const request = { | ||
snapId, | ||
origin: 'metamask', | ||
handler: 'onKeyringRequest', | ||
request: { | ||
id: expect.any(String), | ||
jsonrpc: '2.0', | ||
method: 'keyring_listAccounts', | ||
}, | ||
}; | ||
|
||
it('should call the listAccounts method and return the result', async () => { | ||
const client = new KeyringSnapControllerClient({ | ||
controller: controller as unknown as SnapController, | ||
snapId, | ||
}); | ||
|
||
controller.handleRequest.mockResolvedValue(accountsList); | ||
const accounts = await client.listAccounts(); | ||
expect(controller.handleRequest).toHaveBeenCalledWith(request); | ||
expect(accounts).toStrictEqual(accountsList); | ||
}); | ||
|
||
it('should call the listAccounts method and return the result (withSnapId)', async () => { | ||
const client = new KeyringSnapControllerClient({ | ||
controller: controller as unknown as SnapController, | ||
}); | ||
|
||
controller.handleRequest.mockResolvedValue(accountsList); | ||
const accounts = await client.withSnapId(snapId).listAccounts(); | ||
expect(controller.handleRequest).toHaveBeenCalledWith(request); | ||
expect(accounts).toStrictEqual(accountsList); | ||
}); | ||
|
||
it('should call the default snapId value ("undefined")', async () => { | ||
const client = new KeyringSnapControllerClient({ | ||
controller: controller as unknown as SnapController, | ||
}); | ||
|
||
controller.handleRequest.mockResolvedValue(accountsList); | ||
await client.listAccounts(); | ||
expect(controller.handleRequest).toHaveBeenCalledWith({ | ||
...request, | ||
snapId: 'undefined', | ||
}); | ||
}); | ||
}); | ||
|
||
describe('getController', () => { | ||
it('should return the controller', () => { | ||
const client = new KeyringSnapControllerClient({ | ||
controller: controller as unknown as SnapController, | ||
}); | ||
|
||
expect(client.getController()).toBe(controller); | ||
}); | ||
}); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,115 @@ | ||
import { KeyringClient, type Sender } from '@metamask/keyring-api'; | ||
import type { JsonRpcRequest } from '@metamask/keyring-api/dist/JsonRpcRequest'; | ||
import type { SnapController } from '@metamask/snaps-controllers'; | ||
import type { SnapId } from '@metamask/snaps-sdk'; | ||
import type { HandlerType } from '@metamask/snaps-utils'; | ||
import type { Json } from '@metamask/utils'; | ||
|
||
/** | ||
* Implementation of the `Sender` interface that can be used to send requests | ||
* to a snap through a `SnapController`. | ||
*/ | ||
class SnapControllerSender implements Sender { | ||
#snapId: SnapId; | ||
|
||
#origin: string; | ||
|
||
#controller: SnapController; | ||
|
||
#handler: HandlerType; | ||
|
||
/** | ||
* Create a new instance of `SnapControllerSender`. | ||
* | ||
* @param controller - The `SnapController` instance to send requests to. | ||
* @param snapId - The ID of the snap to use. | ||
* @param origin - The sender's origin. | ||
* @param handler - The handler type. | ||
*/ | ||
constructor( | ||
controller: any, | ||
snapId: SnapId, | ||
origin: string, | ||
handler: HandlerType, | ||
) { | ||
this.#controller = controller; | ||
this.#snapId = snapId; | ||
this.#origin = origin; | ||
this.#handler = handler; | ||
} | ||
|
||
/** | ||
* Send a request to the snap and return the response. | ||
* | ||
* @param request - JSON-RPC request to send to the snap. | ||
* @returns A promise that resolves to the response of the request. | ||
*/ | ||
async send(request: JsonRpcRequest): Promise<Json> { | ||
return this.#controller.handleRequest({ | ||
snapId: this.#snapId, | ||
origin: this.#origin, | ||
handler: this.#handler, | ||
request, | ||
}) as Promise<Json>; | ||
} | ||
} | ||
|
||
/** | ||
* A `KeyringClient` that allows the communication with a snap through the | ||
* `SnapController`. | ||
*/ | ||
export class KeyringSnapControllerClient extends KeyringClient { | ||
#controller: SnapController; | ||
|
||
/** | ||
* Create a new instance of `KeyringSnapControllerClient`. | ||
* | ||
* The `handlerType` argument has a hard-coded default `string` value instead | ||
* of a `HandlerType` value to prevent the `@metamask/snaps-utils` module | ||
* from being required at runtime. | ||
* | ||
* @param args - Constructor arguments. | ||
* @param args.controller - The `SnapController` instance to use. | ||
* @param args.snapId - The ID of the snap to use (default: `'undefined'`). | ||
* @param args.origin - The sender's origin (default: `'metamask'`). | ||
* @param args.handler - The handler type (default: `'onKeyringRequest'`). | ||
*/ | ||
constructor({ | ||
controller, | ||
snapId = 'undefined' as SnapId, | ||
origin = 'metamask', | ||
handler = 'onKeyringRequest' as HandlerType, | ||
}: { | ||
controller: SnapController; | ||
snapId?: SnapId; | ||
origin?: string; | ||
handler?: HandlerType; | ||
}) { | ||
super(new SnapControllerSender(controller, snapId, origin, handler)); | ||
this.#controller = controller; | ||
} | ||
|
||
/** | ||
* Create a new instance of `KeyringSnapControllerClient` with the specified | ||
* `snapId`. | ||
* | ||
* @param snapId - The ID of the snap to use in the new instance. | ||
* @returns A new instance of `KeyringSnapControllerClient` with the | ||
* specified snap ID. | ||
*/ | ||
withSnapId(snapId: SnapId): KeyringSnapControllerClient { | ||
return new KeyringSnapControllerClient({ | ||
controller: this.#controller, | ||
snapId, | ||
}); | ||
} | ||
|
||
/** | ||
* Get the `SnapController` instance used by this client. | ||
* | ||
* @returns The `SnapController` instance used by this client. | ||
*/ | ||
getController(): SnapController { | ||
return this.#controller; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.