diff --git a/packages/examples/packages/browserify-plugin/snap.manifest.json b/packages/examples/packages/browserify-plugin/snap.manifest.json index 4adcd8b77c..a36b70a053 100644 --- a/packages/examples/packages/browserify-plugin/snap.manifest.json +++ b/packages/examples/packages/browserify-plugin/snap.manifest.json @@ -7,7 +7,7 @@ "url": "https://github.com/MetaMask/snaps.git" }, "source": { - "shasum": "PNtdcFc5HFBGHnv3e/8CUhm16s6+Ksmmc38dF34lsSw=", + "shasum": "1V2d/+iUgdA+QeXEVHKxmle1VvQJaVC6KaHqSevpWBQ=", "location": { "npm": { "filePath": "dist/bundle.js", diff --git a/packages/examples/packages/browserify/snap.manifest.json b/packages/examples/packages/browserify/snap.manifest.json index f169dd82bf..6c13245f07 100644 --- a/packages/examples/packages/browserify/snap.manifest.json +++ b/packages/examples/packages/browserify/snap.manifest.json @@ -7,7 +7,7 @@ "url": "https://github.com/MetaMask/snaps.git" }, "source": { - "shasum": "1V+pdRmIER1rMRFWU02Fzc+LXLUcCoCHAXsbu2JXgSI=", + "shasum": "/i4ajCNv/9R1NuYAfSTnq8j8czxSymcZhcjZgnhj3Pg=", "location": { "npm": { "filePath": "dist/bundle.js", diff --git a/packages/examples/packages/send-flow/package.json b/packages/examples/packages/send-flow/package.json index 4604e0d99f..3794901feb 100644 --- a/packages/examples/packages/send-flow/package.json +++ b/packages/examples/packages/send-flow/package.json @@ -44,7 +44,9 @@ }, "dependencies": { "@metamask/rpc-errors": "^7.0.2", - "@metamask/snaps-sdk": "workspace:^" + "@metamask/snaps-sdk": "workspace:^", + "@metamask/superstruct": "^3.1.0", + "@metamask/utils": "^11.2.0" }, "devDependencies": { "@jest/globals": "^29.5.0", diff --git a/packages/examples/packages/send-flow/snap.manifest.json b/packages/examples/packages/send-flow/snap.manifest.json index c5b970c43c..a72fece1ca 100644 --- a/packages/examples/packages/send-flow/snap.manifest.json +++ b/packages/examples/packages/send-flow/snap.manifest.json @@ -7,7 +7,7 @@ "url": "https://github.com/MetaMask/snaps.git" }, "source": { - "shasum": "wE+wX6shyn8Q1Tu8SrUCOdSjARmQrq2jbCKiRqFz5EY=", + "shasum": "5qERUafayyDWQ12V/+htfEs2wzmQwhSn0EcQolI7quo=", "location": { "npm": { "filePath": "dist/bundle.js", diff --git a/packages/examples/packages/send-flow/src/components/SendFlow.tsx b/packages/examples/packages/send-flow/src/components/SendFlow.tsx index c571d53d84..9638cd99ca 100644 --- a/packages/examples/packages/send-flow/src/components/SendFlow.tsx +++ b/packages/examples/packages/send-flow/src/components/SendFlow.tsx @@ -15,8 +15,8 @@ import type { Account, Currency } from '../types'; * @property selectedCurrency - The selected currency to display. * @property total - The total cost of the transaction. * @property fees - The fees for the transaction. - * @property flushToAddress - Whether to flush the address field or not. * @property errors - The form errors. + * @property displayAvatar - Whether to display the avatar of the address. */ export type SendFlowProps = { accounts: Account[]; @@ -24,11 +24,11 @@ export type SendFlowProps = { selectedCurrency: 'BTC' | '$'; total: Currency; fees: Currency; - flushToAddress?: boolean; errors?: { amount?: string; to?: string; }; + displayAvatar?: boolean | undefined; }; /** @@ -41,7 +41,7 @@ export type SendFlowProps = { * @param props.total - The total cost of the transaction. * @param props.errors - The form errors. * @param props.fees - The fees for the transaction. - * @param props.flushToAddress - Whether to flush the address field or not. + * @param props.displayAvatar - Whether to display the avatar of the address. * @returns The SendFlow component. */ export const SendFlow: SnapComponent = ({ @@ -50,8 +50,8 @@ export const SendFlow: SnapComponent = ({ selectedCurrency, total, fees, - flushToAddress, errors, + displayAvatar, }) => { return ( @@ -61,8 +61,8 @@ export const SendFlow: SnapComponent = ({ selectedAccount={selectedAccount} accounts={accounts} selectedCurrency={selectedCurrency} - flushToAddress={flushToAddress} errors={errors} + displayAvatar={displayAvatar} /> diff --git a/packages/examples/packages/send-flow/src/components/SendForm.tsx b/packages/examples/packages/send-flow/src/components/SendForm.tsx index 15bf4403bd..4b3aefdada 100644 --- a/packages/examples/packages/send-flow/src/components/SendForm.tsx +++ b/packages/examples/packages/send-flow/src/components/SendForm.tsx @@ -22,14 +22,14 @@ import type { Account, SendFormErrors } from '../types'; * @property accounts - The available accounts. * @property errors - The form errors. * @property selectedCurrency - The selected currency to display. - * @property flushToAddress - Whether to flush the address field or not. + * @property displayAvatar - Whether to display the avatar of the address. */ export type SendFormProps = { selectedAccount: string; accounts: Account[]; errors?: SendFormErrors; selectedCurrency: 'BTC' | '$'; - flushToAddress?: boolean; + displayAvatar?: boolean | undefined; }; /** @@ -40,7 +40,7 @@ export type SendFormProps = { * @param props.accounts - The available accounts. * @param props.errors - The form errors. * @param props.selectedCurrency - The selected currency to display. - * @param props.flushToAddress - Whether to flush the address field or not. + * @param props.displayAvatar - Whether to display the avatar of the address. * @returns The SendForm component. */ export const SendForm: SnapComponent = ({ @@ -48,7 +48,7 @@ export const SendForm: SnapComponent = ({ accounts, errors, selectedCurrency, - flushToAddress, + displayAvatar, }) => (
@@ -69,7 +69,7 @@ export const SendForm: SnapComponent = ({ name="to" chainId="eip155:0" placeholder="Enter receiving address" - value={flushToAddress ? '' : undefined} + displayAvatar={displayAvatar} /> diff --git a/packages/examples/packages/send-flow/src/index.tsx b/packages/examples/packages/send-flow/src/index.tsx index 371d2ef683..4ad53b9c3d 100644 --- a/packages/examples/packages/send-flow/src/index.tsx +++ b/packages/examples/packages/send-flow/src/index.tsx @@ -5,6 +5,8 @@ import type { OnRpcRequestHandler, } from '@metamask/snaps-sdk'; import { UserInputEventType } from '@metamask/snaps-sdk'; +import { is } from '@metamask/superstruct'; +import { HexChecksumAddressStruct } from '@metamask/utils'; import { SendFlow } from './components'; import { accountsArray, accounts } from './data'; @@ -98,8 +100,8 @@ export const onUserInput: OnUserInputHandler = async ({ if (event.type === UserInputEventType.InputChangeEvent) { switch (event.name) { case 'amount': - case 'to': - case 'accountSelector': { + case 'to': { + // For testing purposes, we display the avatar if the address is a valid hex checksum address. await snap.request({ method: 'snap_updateInterface', params: { @@ -112,19 +114,14 @@ export const onUserInput: OnUserInputHandler = async ({ total={total} fees={fees} errors={formErrors} + displayAvatar={is(event.value, HexChecksumAddressStruct)} /> ), }, }); - break; } - default: - break; - } - } else if (event.type === UserInputEventType.ButtonClickEvent) { - switch (event.name) { - case 'clear': + case 'accountSelector': { await snap.request({ method: 'snap_updateInterface', params: { @@ -136,13 +133,14 @@ export const onUserInput: OnUserInputHandler = async ({ selectedCurrency={selectedCurrency} total={total} fees={fees} - flushToAddress={true} errors={formErrors} /> ), }, }); + break; + } default: break; } diff --git a/packages/snaps-sdk/src/jsx/components/form/AddressInput.ts b/packages/snaps-sdk/src/jsx/components/form/AddressInput.ts index af86807b83..2d1595d5dc 100644 --- a/packages/snaps-sdk/src/jsx/components/form/AddressInput.ts +++ b/packages/snaps-sdk/src/jsx/components/form/AddressInput.ts @@ -8,6 +8,7 @@ export type AddressInputProps = { chainId: CaipChainId; placeholder?: string | undefined; disabled?: boolean | undefined; + displayAvatar?: boolean | undefined; }; const TYPE = 'AddressInput'; @@ -21,6 +22,7 @@ const TYPE = 'AddressInput'; * @param props.chainId - The CAIP-2 chain ID of the address. * @param props.placeholder - The placeholder text of the input field. * @param props.disabled - Whether the input field is disabled. + * @param props.displayAvatar - Whether to display the avatar of the address. * @returns An input element. * @example * diff --git a/packages/snaps-sdk/src/jsx/validation.test.tsx b/packages/snaps-sdk/src/jsx/validation.test.tsx index 9497371af0..0e12283d37 100644 --- a/packages/snaps-sdk/src/jsx/validation.test.tsx +++ b/packages/snaps-sdk/src/jsx/validation.test.tsx @@ -221,6 +221,12 @@ describe('AddressInputStruct', () => { />, , , + , ])('validates an address input element', (value) => { expect(is(value, AddressInputStruct)).toBe(true); }); @@ -242,6 +248,13 @@ describe('AddressInputStruct', () => { , // @ts-expect-error - Invalid props. , + , ])('does not validate "%p"', (value) => { expect(is(value, AddressInputStruct)).toBe(false); }); diff --git a/packages/snaps-sdk/src/jsx/validation.ts b/packages/snaps-sdk/src/jsx/validation.ts index 994d7eda6d..b7d2d653f5 100644 --- a/packages/snaps-sdk/src/jsx/validation.ts +++ b/packages/snaps-sdk/src/jsx/validation.ts @@ -358,6 +358,7 @@ export const AddressInputStruct: Describe = element( value: optional(string()), placeholder: optional(string()), disabled: optional(boolean()), + displayAvatar: optional(boolean()), }, ); diff --git a/yarn.lock b/yarn.lock index 552187efd3..87f5d50eaf 100644 --- a/yarn.lock +++ b/yarn.lock @@ -5425,6 +5425,8 @@ __metadata: "@metamask/snaps-cli": "workspace:^" "@metamask/snaps-jest": "workspace:^" "@metamask/snaps-sdk": "workspace:^" + "@metamask/superstruct": "npm:^3.1.0" + "@metamask/utils": "npm:^11.2.0" "@swc/core": "npm:1.3.78" "@swc/jest": "npm:^0.2.26" "@types/node": "npm:18.14.2"