diff --git a/packages/snaps-simulation/src/helpers.test.tsx b/packages/snaps-simulation/src/helpers.test.tsx index fde44fe9a0..e8f83c4646 100644 --- a/packages/snaps-simulation/src/helpers.test.tsx +++ b/packages/snaps-simulation/src/helpers.test.tsx @@ -410,7 +410,7 @@ describe('helpers', () => { }); describe('onNameLookup', () => { - it('sends a name lookup request and returns the result', async () => { + it('sends a domain name lookup request and returns the result', async () => { jest.spyOn(console, 'log').mockImplementation(); const MOCK_DOMAIN = 'test.domain'; @@ -450,6 +450,46 @@ describe('helpers', () => { await close(); await closeServer(); }); + + it('sends an address lookup request and returns the result', async () => { + jest.spyOn(console, 'log').mockImplementation(); + const MOCK_ADDRESS = '0xc0ffee254729296a45a3885639AC7E10F9d54979'; + const MOCK_DOMAIN = 'test.domain'; + + const { snapId, close: closeServer } = await getMockServer({ + sourceCode: ` + module.exports.onNameLookup = async (request) => { + return { + resolvedDomain: 'test.domain', + protocol: 'test protocol', + }; + }; + `, + }); + + const { onNameLookup, close } = await installSnap(snapId); + const response = await onNameLookup({ + chainId: 'eip155:1', + address: MOCK_ADDRESS, + }); + + expect(response).toStrictEqual( + expect.objectContaining({ + response: { + result: { + resolvedDomain: MOCK_DOMAIN, + protocol: 'test protocol', + }, + }, + }), + ); + + // `close` is deprecated because the Jest environment will automatically + // close the Snap when the test finishes. However, we still need to close + // the Snap in this test because it's run outside the Jest environment. + await close(); + await closeServer(); + }); }); describe('runCronjob', () => { diff --git a/packages/snaps-simulation/src/structs.test.tsx b/packages/snaps-simulation/src/structs.test.tsx index cc88a27a1d..2d0fa71c15 100644 --- a/packages/snaps-simulation/src/structs.test.tsx +++ b/packages/snaps-simulation/src/structs.test.tsx @@ -2,8 +2,10 @@ import { Box, Text } from '@metamask/snaps-sdk/jsx'; import { create } from '@metamask/superstruct'; import { + BaseNameLookupOptionsStruct, InterfaceStruct, JsonRpcMockOptionsStruct, + NameLookupOptionsStruct, SignatureOptionsStruct, SnapOptionsStruct, SnapResponseStruct, @@ -358,3 +360,60 @@ describe('SnapResponseStruct', () => { expect(() => create(value, SnapResponseStruct)).toThrow(); }); }); + +describe('BaseNameLookupOptionsStruct', () => { + it('accepts a valid object', () => { + const options = create( + { + chainId: 'eip155:1', + }, + BaseNameLookupOptionsStruct, + ); + + expect(options).toStrictEqual({ + chainId: 'eip155:1', + }); + }); + + it.each(INVALID_VALUES)('throws for invalid value: %p', (value) => { + // eslint-disable-next-line jest/require-to-throw-message + expect(() => create(value, BaseNameLookupOptionsStruct)).toThrow(); + }); +}); + +describe('NameLookupOptionsStruct', () => { + it('accepts a valid object for domain lookup', () => { + const options = create( + { + chainId: 'eip155:1', + domain: 'test.domain', + }, + NameLookupOptionsStruct, + ); + + expect(options).toStrictEqual({ + chainId: 'eip155:1', + domain: 'test.domain', + }); + }); + + it('accepts a valid object for address lookup', () => { + const options = create( + { + chainId: 'eip155:1', + address: '0xc0ffee254729296a45a3885639AC7E10F9d54979', + }, + NameLookupOptionsStruct, + ); + + expect(options).toStrictEqual({ + chainId: 'eip155:1', + address: '0xc0ffee254729296a45a3885639AC7E10F9d54979', + }); + }); + + it.each(INVALID_VALUES)('throws for invalid value: %p', (value) => { + // eslint-disable-next-line jest/require-to-throw-message + expect(() => create(value, NameLookupOptionsStruct)).toThrow(); + }); +}); diff --git a/packages/snaps-simulation/src/structs.ts b/packages/snaps-simulation/src/structs.ts index 55db6e0863..de055ed215 100644 --- a/packages/snaps-simulation/src/structs.ts +++ b/packages/snaps-simulation/src/structs.ts @@ -190,23 +190,34 @@ export const SignatureOptionsStruct = object({ ), }); -export const NameLookupOptionsStruct = object({ +export const BaseNameLookupOptionsStruct = object({ /** * The CAIP-2 chain ID. Defaults to `eip155:1`. */ chainId: defaulted(string(), 'eip155:1'), - - /** - * Domain name to lookup. - */ - domain: optional(string()), - - /** - * Address to lookup. - */ - address: optional(string()), }); +export const NameLookupOptionsStruct = union([ + assign( + BaseNameLookupOptionsStruct, + object({ + /** + * Address to lookup. + */ + address: string(), + }), + ), + assign( + BaseNameLookupOptionsStruct, + object({ + /** + * Domain name to lookup. + */ + domain: string(), + }), + ), +]); + export const SnapOptionsStruct = object({ /** * The timeout in milliseconds to use for requests to the snap. Defaults to diff --git a/packages/snaps-simulation/src/types.ts b/packages/snaps-simulation/src/types.ts index aa3a210316..21bc37c7ea 100644 --- a/packages/snaps-simulation/src/types.ts +++ b/packages/snaps-simulation/src/types.ts @@ -71,7 +71,6 @@ export type KeyringOptions = RequestOptions; /** * The options to use for name lookup requests. * - * @property origin - The origin of the name lookup request (optional).`. * @property chainId - Chain ID. * @property domain - Domain name to lookup and resolve. * @property address - Address to lookup and resolve.