From a840f6dbac29c26833ac89191aed49f888c6103e Mon Sep 17 00:00:00 2001 From: Alex Stelea Date: Tue, 7 Mar 2023 13:16:45 +0000 Subject: [PATCH] feat: add reset request item --- README.md | 21 ++++++++++++++-- examples/index.ts | 19 ++++++-------- lib/IO/request-items/request-item.ts | 2 ++ lib/IO/request-items/reset.ts | 26 ++++++++++++++++++++ lib/IO/schemas.ts | 9 +++++++ lib/IO/transform-method-input.ts | 9 +++++++ lib/__tests__/transform-method-input.spec.ts | 17 +++++++++++++ lib/methods/request.ts | 3 +++ 8 files changed, 93 insertions(+), 13 deletions(-) create mode 100644 lib/IO/request-items/reset.ts diff --git a/README.md b/README.md index 47201cb..923b7e9 100644 --- a/README.md +++ b/README.md @@ -22,6 +22,7 @@ You may wish to consider using this with the [√ Connect Button](https://github - [Get list of Persona data](#get-list-of-persona-data) - [oneTimePersonaData](#onetimepersonadata) - [ongoingPersonaData](#ongoingpersonadata) + - [Reset](#reset) - [Login](#login) - [login](#login-1) - [usePersona](#usepersona) @@ -84,6 +85,7 @@ type WalletSdkInput = { | [loginWithChallenge](#loginwithchallenge) | ❌ | | [loginWithoutChallenge](#loginwithoutchallenge) | ✅ | | [usePersona](#usepersona) | ✅ | +| [reset](#reset) | ✅ | ### About oneTime VS ongoing requests @@ -286,8 +288,10 @@ const value = result.value ```typescript const result = await walletSdk.request( - requestItem.usePersona(identityAddress), - requestBuilder(requestItem.ongoingPersonaData(['firstName', 'email'])) + requestBuilder( + requestItem.usePersona(identityAddress), + requestItem.ongoingPersonaData(['firstName', 'email']) + ) ) if (result.isErr()) { @@ -304,6 +308,19 @@ if (result.isErr()) { const value = result.value ``` +### Reset + +You can send a reset request to ask the user to provide new values for ongoing accounts and/or persona data. + +```typescript +const result = await walletSdk.request( + requestBuilder( + requestItem.usePersona(identityAddress), + requestItem.reset({ account: true, personaData: true }) + ) +) +``` + ### Login Sometimes your dApp may want a more personalized, consistent user experience and the Radix Wallet is able to login users with a Persona. diff --git a/examples/index.ts b/examples/index.ts index d421ec9..3c6bfcb 100644 --- a/examples/index.ts +++ b/examples/index.ts @@ -1,6 +1,7 @@ import { WalletSdk, requestBuilder, requestItem } from '../lib/wallet-sdk' import { Result } from 'neverthrow' import { login } from '../lib/IO/request-items/login' +import { reset } from '../lib/IO/request-items/reset' const sdk = WalletSdk({ dAppDefinitionAddress: @@ -62,7 +63,10 @@ const accountAddressInputElement = document.getElementById( document.getElementById('login-btn')!.onclick = async () => { clearResults() - const result = await sdk.request({ loginWithoutChallenge: {} }) + const result = await sdk.request({ + loginWithoutChallenge: {}, + reset: { accounts: true }, + }) displayResults(result) } @@ -86,7 +90,9 @@ document.getElementById('account-address-btn')!.onclick = async () => { document.getElementById('persona-data-btn')!.onclick = async () => { clearResults() - const result = await sdk.request(requestBuilder(login.withoutChallenge())) + const result = await sdk.request( + requestBuilder(login.withoutChallenge(), reset({ personaData: true })) + ) displayResults(result) } @@ -115,15 +121,6 @@ document.getElementById('send-tx-btn')!.onclick = async () => { displayResults(result) } -sdk - .request( - requestBuilder( - requestItem.login.withoutChallenge(), - requestItem.ongoingAccounts.withoutProofOfOwnership() - ) - ) - .map((result) => result.persona) - window.radixWalletSdk = sdk declare global { diff --git a/lib/IO/request-items/request-item.ts b/lib/IO/request-items/request-item.ts index 76d1898..9cb42d0 100644 --- a/lib/IO/request-items/request-item.ts +++ b/lib/IO/request-items/request-item.ts @@ -4,6 +4,7 @@ import { ongoingAccounts } from './ongoing-accounts' import { usePersona } from './use-persona' import { oneTimePersonaData } from './one-time-persona-data' import { ongoingPersonaData } from './ongoing-persona-data' +import { reset } from './reset' export const requestItem = { oneTimeAccounts, @@ -12,4 +13,5 @@ export const requestItem = { ongoingPersonaData, login, usePersona, + reset, } as const diff --git a/lib/IO/request-items/reset.ts b/lib/IO/request-items/reset.ts new file mode 100644 index 0000000..37896c7 --- /dev/null +++ b/lib/IO/request-items/reset.ts @@ -0,0 +1,26 @@ +import { ResetRequestItem } from '../schemas' + +export type Reset = { + wallet: { + request: ResetRequestItem + response: {} + } + method: { + input: Partial + output: {} + } +} + +type RequiredKeys = + | { usePersona: any } + | { login: any } + | { loginWithoutChallenge: any } + +type NotAllowedKeys = Partial<{ reset: any }> + +export const reset = + ({ accounts = false, personaData = false }: Partial) => + (input: I extends NotAllowedKeys ? never : I) => ({ + ...input, + reset: { accounts, personaData }, + }) diff --git a/lib/IO/schemas.ts b/lib/IO/schemas.ts index d11a69c..aa42b19 100644 --- a/lib/IO/schemas.ts +++ b/lib/IO/schemas.ts @@ -253,6 +253,13 @@ export type AuthRequestResponseItem = z.infer< typeof AuthRequestResponseItemSchema > +export type ResetRequestItem = z.infer + +const ResetRequestSchema = object({ + accounts: boolean(), + personaData: boolean(), +}) + const SendTransactionRequestItemSchema = object({ transactionManifest: string(), version: number(), @@ -276,6 +283,7 @@ const WalletUnauthorizedRequestItemsSchema = object({ discriminator: literal('unauthorizedRequest'), oneTimeAccounts: OneTimeAccountsRequestItemSchema.optional(), oneTimePersonaData: OneTimePersonaDataRequestItemSchema.optional(), + reset: ResetRequestSchema.optional(), }) export type WalletUnauthorizedRequestItems = z.infer< @@ -289,6 +297,7 @@ const WalletAuthorizedRequestItemsSchema = object({ ongoingAccounts: OngoingAccountsRequestItemSchema.optional(), oneTimePersonaData: OneTimePersonaDataRequestItemSchema.optional(), ongoingPersonaData: OngoingPersonaDataRequestItemSchema.optional(), + reset: ResetRequestSchema.optional(), }) export type WalletAuthorizedRequestItems = z.infer< diff --git a/lib/IO/transform-method-input.ts b/lib/IO/transform-method-input.ts index 9156672..e1d3c92 100644 --- a/lib/IO/transform-method-input.ts +++ b/lib/IO/transform-method-input.ts @@ -63,6 +63,7 @@ export const transformMethodInput = (input: I) => auth: { ...value, discriminator: 'usePersona' }, discriminator: 'authorizedRequest', } + case requestMethodRequestType.loginWithChallenge: return { ...acc, @@ -70,6 +71,14 @@ export const transformMethodInput = (input: I) => discriminator: 'authorizedRequest', } + case requestMethodRequestType.reset: { + const { accounts = false, personaData = false } = value + return { + ...acc, + reset: { accounts, personaData }, + } + } + case 'send': return { discriminator: 'transaction', diff --git a/lib/__tests__/transform-method-input.spec.ts b/lib/__tests__/transform-method-input.spec.ts index 41ed821..1b57a08 100644 --- a/lib/__tests__/transform-method-input.spec.ts +++ b/lib/__tests__/transform-method-input.spec.ts @@ -273,4 +273,21 @@ describe('transformMethodInput', () => { }) }) }) + describe('reset', () => { + it('should return correct transformed value', () => { + ;[ + { + actual: requestItem.reset({ accounts: true }), + expected: { + reset: { accounts: true, personaData: false }, + discriminator: 'unauthorizedRequest', + }, + }, + ].forEach((testItem) => { + expect(transformMethodInput(testItem.actual({} as any))).toEqual( + ok(testItem.expected) + ) + }) + }) + }) }) diff --git a/lib/methods/request.ts b/lib/methods/request.ts index 3b78997..f70c19d 100644 --- a/lib/methods/request.ts +++ b/lib/methods/request.ts @@ -1,6 +1,7 @@ import { Login } from '../IO/request-items/login' import { OneTimeAccounts } from '../IO/request-items/one-time-accounts' import { OngoingAccounts } from '../IO/request-items/ongoing-accounts' +import { Reset } from '../IO/request-items/reset' import { UsePersona } from '../IO/request-items/use-persona' export const requestMethodRequestType = { @@ -15,9 +16,11 @@ export const requestMethodRequestType = { loginWithChallenge: 'loginWithChallenge', oneTimePersonaData: 'oneTimePersonaData', ongoingPersonaData: 'ongoingPersonaData', + reset: 'reset', } as const type RequestItems = { + [requestMethodRequestType.reset]: Reset [requestMethodRequestType.oneTimeAccountsWithoutProofOfOwnership]: OneTimeAccounts['WithoutProofOfOwnership'] // [requestMethodRequestType.oneTimeAccountsWithProofOfOwnership]: OneTimeAccounts['WithProofOfOwnership'] [requestMethodRequestType.ongoingAccountsWithoutProofOfOwnership]: OngoingAccounts['WithoutProofOfOwnership']