From eb901e89033411c8f459eb5a4da322017166b92c Mon Sep 17 00:00:00 2001 From: Alex Stelea Date: Fri, 8 Sep 2023 13:45:51 +0200 Subject: [PATCH 1/2] refactor: use radix connect schemas --- lib/IO/index.ts | 1 - lib/IO/schemas.ts | 380 ------------------ lib/IO/wallet-interaction-factory.ts | 6 +- lib/__tests__/wallet-sdk.spec.ts | 5 +- .../connector-extension-client.ts | 2 +- lib/connector-extension/subjects.ts | 2 +- lib/create-methods.ts | 2 +- lib/helpers/validate-wallet-response.ts | 2 +- lib/wallet-sdk.ts | 3 +- package-lock.json | 19 +- package.json | 1 + 11 files changed, 32 insertions(+), 391 deletions(-) delete mode 100644 lib/IO/schemas.ts diff --git a/lib/IO/index.ts b/lib/IO/index.ts index f2d4ac2..95855ac 100644 --- a/lib/IO/index.ts +++ b/lib/IO/index.ts @@ -1,2 +1 @@ -export * from './schemas' export * as walletInteractionFactoryV2 from './wallet-interaction-factory' diff --git a/lib/IO/schemas.ts b/lib/IO/schemas.ts deleted file mode 100644 index df3499a..0000000 --- a/lib/IO/schemas.ts +++ /dev/null @@ -1,380 +0,0 @@ -import { ResultAsync } from 'neverthrow' -import { array, boolean, literal, number, object, string, union, z } from 'zod' - -export type Account = z.infer -export const Account = object({ - address: string(), - label: string(), - appearanceId: number(), -}) - -export type Proof = z.infer -export const Proof = object({ - publicKey: string(), - signature: string(), - curve: union([literal('curve25519'), literal('secp256k1')]), -}) - -export type AccountProof = z.infer -export const AccountProof = object({ - accountAddress: string(), - proof: Proof, -}) - -export type Persona = z.infer -export const Persona = object({ identityAddress: string(), label: string() }) - -export const personaDataFullNameVariant = { - western: 'western', - eastern: 'eastern', -} as const -export type PersonaDataNameVariant = z.infer -export const PersonaDataNameVariant = union([ - literal(personaDataFullNameVariant.eastern), - literal(personaDataFullNameVariant.western), -]) - -export type PersonaDataName = z.infer -export const PersonaDataName = object({ - variant: PersonaDataNameVariant, - familyName: string(), - nickname: string(), - givenNames: string(), -}) - -export type NumberOfValues = z.infer -export const NumberOfValues = object({ - quantifier: union([literal('exactly'), literal('atLeast')]), - quantity: number().gte(0), -}) - -export type AccountsRequestItem = z.infer -export const AccountsRequestItem = object({ - challenge: string().optional(), - numberOfAccounts: NumberOfValues, -}) - -export type AccountsRequestResponseItem = z.infer< - typeof AccountsRequestResponseItem -> -export const AccountsRequestResponseItem = object({ - accounts: array(Account), - challenge: string().optional(), - proofs: array(AccountProof).optional(), -}).refine((data) => { - if (data.challenge || data?.proofs) { - return data.challenge && data?.proofs?.length - } - return true -}, 'missing challenge or proofs') - -export type PersonaDataRequestItem = z.infer -export const PersonaDataRequestItem = object({ - isRequestingName: boolean().optional(), - numberOfRequestedEmailAddresses: NumberOfValues.optional(), - numberOfRequestedPhoneNumbers: NumberOfValues.optional(), -}) - -export type PersonaDataRequestResponseItem = z.infer< - typeof PersonaDataRequestResponseItem -> -export const PersonaDataRequestResponseItem = object({ - name: PersonaDataName.optional(), - emailAddresses: array(string()).optional(), - phoneNumbers: array(string()).optional(), -}) - -export type ResetRequestItem = z.infer -export const ResetRequestItem = object({ - accounts: boolean(), - personaData: boolean(), -}) - -export type LoginRequestResponseItem = z.infer -export const LoginRequestResponseItem = object({ - persona: Persona, - challenge: string().optional(), - proof: Proof.optional(), -}).refine((data) => { - if (data.challenge || data.proof) { - return data.challenge && data.proof - } - return true -}, 'missing challenge or proof') - -export type WalletUnauthorizedRequestItems = z.infer< - typeof WalletUnauthorizedRequestItems -> -export const WalletUnauthorizedRequestItems = object({ - discriminator: literal('unauthorizedRequest'), - oneTimeAccounts: AccountsRequestItem.optional(), - oneTimePersonaData: PersonaDataRequestItem.optional(), -}) - -export type AuthUsePersonaRequestItem = z.infer< - typeof AuthUsePersonaRequestItem -> -export const AuthUsePersonaRequestItem = object({ - discriminator: literal('usePersona'), - identityAddress: string(), -}) - -export type AuthLoginWithoutChallengeRequestItem = z.infer< - typeof AuthLoginWithoutChallengeRequestItem -> -export const AuthLoginWithoutChallengeRequestItem = object({ - discriminator: literal('loginWithoutChallenge'), -}) - -export type AuthLoginWithChallengeRequestItem = z.infer< - typeof AuthLoginWithChallengeRequestItem -> -export const AuthLoginWithChallengeRequestItem = object({ - discriminator: literal('loginWithChallenge'), - challenge: string(), -}) - -export const AuthLoginRequestItem = union([ - AuthLoginWithoutChallengeRequestItem, - AuthLoginWithChallengeRequestItem, -]) -export const AuthRequestItem = union([ - AuthUsePersonaRequestItem, - AuthLoginRequestItem, -]) - -export type WalletAuthorizedRequestItems = z.infer< - typeof WalletAuthorizedRequestItems -> -export const WalletAuthorizedRequestItems = object({ - discriminator: literal('authorizedRequest'), - auth: AuthRequestItem, - reset: ResetRequestItem.optional(), - oneTimeAccounts: AccountsRequestItem.optional(), - ongoingAccounts: AccountsRequestItem.optional(), - oneTimePersonaData: PersonaDataRequestItem.optional(), - ongoingPersonaData: PersonaDataRequestItem.optional(), -}) - -export type WalletRequestItems = z.infer -export const WalletRequestItems = union([ - WalletUnauthorizedRequestItems, - WalletAuthorizedRequestItems, -]) - -export type SendTransactionItem = z.infer -export const SendTransactionItem = object({ - transactionManifest: string(), - version: number(), - blobs: array(string()).optional(), - message: string().optional(), -}) - -export type WalletTransactionItems = z.infer -export const WalletTransactionItems = object({ - discriminator: literal('transaction'), - send: SendTransactionItem, -}) - -export type SendTransactionResponseItem = z.infer< - typeof SendTransactionResponseItem -> -export const SendTransactionResponseItem = object({ - transactionIntentHash: string(), -}) - -export type WalletTransactionResponseItems = z.infer< - typeof WalletTransactionResponseItems -> -const WalletTransactionResponseItems = object({ - discriminator: literal('transaction'), - send: SendTransactionResponseItem, -}) - -export type CancelRequest = z.infer -export const CancelRequest = object({ - discriminator: literal('cancelRequest'), -}) - -export type WalletInteractionItems = z.infer -export const WalletInteractionItems = union([ - WalletRequestItems, - WalletTransactionItems, - CancelRequest, -]) - -export type Metadata = z.infer -export const Metadata = object({ - version: literal(2), - networkId: number(), - dAppDefinitionAddress: string(), -}) - -export type WalletInteraction = z.infer -export const WalletInteraction = object({ - interactionId: string(), - metadata: Metadata, - items: WalletInteractionItems, -}) - -export type WalletUnauthorizedRequestResponseItems = z.infer< - typeof WalletUnauthorizedRequestResponseItems -> -const WalletUnauthorizedRequestResponseItems = object({ - discriminator: literal('unauthorizedRequest'), - oneTimeAccounts: AccountsRequestResponseItem.optional(), - oneTimePersonaData: PersonaDataRequestResponseItem.optional(), -}) - -export type AuthLoginWithoutChallengeRequestResponseItem = z.infer< - typeof AuthLoginWithoutChallengeRequestResponseItem -> -export const AuthLoginWithoutChallengeRequestResponseItem = object({ - discriminator: literal('loginWithoutChallenge'), - persona: Persona, -}) - -export type AuthLoginWithChallengeRequestResponseItem = z.infer< - typeof AuthLoginWithChallengeRequestResponseItem -> -export const AuthLoginWithChallengeRequestResponseItem = object({ - discriminator: literal('loginWithChallenge'), - persona: Persona, - challenge: string(), - proof: Proof, -}) - -export const AuthLoginRequestResponseItem = union([ - AuthLoginWithoutChallengeRequestResponseItem, - AuthLoginWithChallengeRequestResponseItem, -]) - -export type AuthUsePersonaRequestResponseItem = z.infer< - typeof AuthUsePersonaRequestResponseItem -> -const AuthUsePersonaRequestResponseItem = object({ - discriminator: literal('usePersona'), - persona: Persona, -}) - -export type AuthRequestResponseItem = z.infer -export const AuthRequestResponseItem = union([ - AuthUsePersonaRequestResponseItem, - AuthLoginRequestResponseItem, -]) - -export type WalletAuthorizedRequestResponseItems = z.infer< - typeof WalletAuthorizedRequestResponseItems -> -export const WalletAuthorizedRequestResponseItems = object({ - discriminator: literal('authorizedRequest'), - auth: AuthRequestResponseItem, - oneTimeAccounts: AccountsRequestResponseItem.optional(), - ongoingAccounts: AccountsRequestResponseItem.optional(), - oneTimePersonaData: PersonaDataRequestResponseItem.optional(), - ongoingPersonaData: PersonaDataRequestResponseItem.optional(), -}) - -export type WalletRequestResponseItems = z.infer< - typeof WalletRequestResponseItems -> -export const WalletRequestResponseItems = union([ - WalletUnauthorizedRequestResponseItems, - WalletAuthorizedRequestResponseItems, -]) - -export type WalletInteractionResponseItems = z.infer< - typeof WalletInteractionResponseItems -> -const WalletInteractionResponseItems = union([ - WalletRequestResponseItems, - WalletTransactionResponseItems, -]) - -export type WalletInteractionSuccessResponse = z.infer< - typeof WalletInteractionSuccessResponse -> -export const WalletInteractionSuccessResponse = object({ - discriminator: literal('success'), - interactionId: string(), - items: WalletInteractionResponseItems, -}) - -export type WalletInteractionFailureResponse = z.infer< - typeof WalletInteractionFailureResponse -> -export const WalletInteractionFailureResponse = object({ - discriminator: literal('failure'), - interactionId: string(), - error: string(), - message: string().optional(), -}) - -export type WalletInteractionResponse = z.infer< - typeof WalletInteractionResponse -> -export const WalletInteractionResponse = union([ - WalletInteractionSuccessResponse, - WalletInteractionFailureResponse, -]) - -export const ExtensionInteraction = object({ - interactionId: string(), - discriminator: literal('extensionStatus'), -}) - -export type ExtensionInteraction = z.infer - -export const messageLifeCycleEventType = { - extensionStatus: 'extensionStatus', - receivedByExtension: 'receivedByExtension', - receivedByWallet: 'receivedByWallet', - requestCancelSuccess: 'requestCancelSuccess', - requestCancelFail: 'requestCancelFail', -} as const - -export const MessageLifeCycleExtensionStatusEvent = object({ - eventType: literal(messageLifeCycleEventType.extensionStatus), - interactionId: string(), - isWalletLinked: boolean(), - isExtensionAvailable: boolean(), -}) - -export type MessageLifeCycleExtensionStatusEvent = z.infer< - typeof MessageLifeCycleExtensionStatusEvent -> - -export const MessageLifeCycleEvent = object({ - eventType: union([ - literal(messageLifeCycleEventType.extensionStatus), - literal(messageLifeCycleEventType.receivedByExtension), - literal(messageLifeCycleEventType.receivedByWallet), - literal(messageLifeCycleEventType.requestCancelSuccess), - literal(messageLifeCycleEventType.requestCancelFail), - ]), - interactionId: string(), -}) - -export type MessageLifeCycleEvent = z.infer - -export type IncomingMessage = z.infer -const IncomingMessage = union([ - MessageLifeCycleEvent, - WalletInteractionResponse, -]) - -export const eventType = { - outgoingMessage: 'radix#chromeExtension#send', - incomingMessage: 'radix#chromeExtension#receive', -} as const - -export type CallbackFns = { - eventCallback: (messageEvent: MessageLifeCycleEvent['eventType']) => void - requestControl: (api: { - cancelRequest: () => ResultAsync< - 'requestCancelSuccess', - 'requestCancelFail' - > - getRequest: () => WalletInteraction - }) => void -} diff --git a/lib/IO/wallet-interaction-factory.ts b/lib/IO/wallet-interaction-factory.ts index 66fcd47..466d3eb 100644 --- a/lib/IO/wallet-interaction-factory.ts +++ b/lib/IO/wallet-interaction-factory.ts @@ -2,7 +2,11 @@ import { ResultAsync } from 'neverthrow' import { AppLogger } from '../helpers/logger' import { SdkError, createSdkError, errorType } from '../wallet-sdk' import { parseAsync } from '../helpers/parse-async' -import { Metadata, WalletInteraction, WalletInteractionItems } from './schemas' +import { + Metadata, + WalletInteraction, + WalletInteractionItems, +} from '@radixdlt/radix-connect-schemas' export const walletInteractionFactory = (logger?: AppLogger) => diff --git a/lib/__tests__/wallet-sdk.spec.ts b/lib/__tests__/wallet-sdk.spec.ts index 6ed02b1..ff0a844 100644 --- a/lib/__tests__/wallet-sdk.spec.ts +++ b/lib/__tests__/wallet-sdk.spec.ts @@ -4,7 +4,7 @@ import { subscribeSpyTo } from '@hirez_io/observer-spy' import { createLogger } from '../helpers/logger' import { ConnectorExtensionClient } from '../connector-extension/connector-extension-client' import { Subjects } from '../connector-extension/subjects' -import { WalletInteractionSuccessResponse } from '../IO' +import { WalletInteractionSuccessResponse } from '@radixdlt/radix-connect-schemas' const delay = (millis: number) => new Promise((resolve) => { @@ -193,6 +193,7 @@ describe('sdk flow', () => { }, }) + // @ts-ignore expect(outgoingMessageSpy.getFirstValue().metadata).toEqual({ dAppDefinitionAddress: 'radixDashboard', networkId: 12, @@ -281,6 +282,7 @@ describe('sdk flow', () => { 'account_tdx_b_1qlu8fdyj77jpmu2mqe4rgh3738jcva4nfd2y2vp675zqgdg72y' ) + // @ts-ignore expect(outgoingMessageSpy.getFirstValue().metadata).toEqual({ dAppDefinitionAddress: 'radixDashboard', networkId: 12, @@ -361,6 +363,7 @@ describe('sdk flow', () => { setTimeout(() => { const outgoingMessage = outgoingMessageSpy.getFirstValue() + // @ts-ignore expect(outgoingMessage.metadata.networkId).toBe(12) subjects.incomingMessageSubject.next({ diff --git a/lib/connector-extension/connector-extension-client.ts b/lib/connector-extension/connector-extension-client.ts index f3bb2a7..e7d6c8a 100644 --- a/lib/connector-extension/connector-extension-client.ts +++ b/lib/connector-extension/connector-extension-client.ts @@ -7,7 +7,7 @@ import { WalletInteraction, WalletInteractionSuccessResponse, eventType, -} from '../IO/schemas' +} from '@radixdlt/radix-connect-schemas' import { Err, Result, ResultAsync, err, ok } from 'neverthrow' import { SdkError, createSdkError } from '../wallet-sdk' import { diff --git a/lib/connector-extension/subjects.ts b/lib/connector-extension/subjects.ts index 26b236c..12db874 100644 --- a/lib/connector-extension/subjects.ts +++ b/lib/connector-extension/subjects.ts @@ -5,7 +5,7 @@ import { MessageLifeCycleExtensionStatusEvent, WalletInteraction, WalletInteractionResponse, -} from '../IO/schemas' +} from '@radixdlt/radix-connect-schemas' export type Subjects = ReturnType diff --git a/lib/create-methods.ts b/lib/create-methods.ts index a6b826e..3b15bf1 100644 --- a/lib/create-methods.ts +++ b/lib/create-methods.ts @@ -6,7 +6,7 @@ import { WalletRequestItems, WalletRequestResponseItems, WalletTransactionResponseItems, -} from './IO' +} from '@radixdlt/radix-connect-schemas' import { ConnectorExtensionClient } from './connector-extension/connector-extension-client' import { validateWalletResponse } from './helpers/validate-wallet-response' import { walletInteractionFactory } from './IO/wallet-interaction-factory' diff --git a/lib/helpers/validate-wallet-response.ts b/lib/helpers/validate-wallet-response.ts index 0d17524..bb98c8d 100644 --- a/lib/helpers/validate-wallet-response.ts +++ b/lib/helpers/validate-wallet-response.ts @@ -2,7 +2,7 @@ import { ResultAsync, err, ok } from 'neverthrow' import { WalletInteractionResponse, WalletInteractionSuccessResponse, -} from '../IO' +} from '@radixdlt/radix-connect-schemas' import { ZodError } from 'zod' import { SdkError, createSdkError } from './error' diff --git a/lib/wallet-sdk.ts b/lib/wallet-sdk.ts index 1db7ba4..bf9991b 100644 --- a/lib/wallet-sdk.ts +++ b/lib/wallet-sdk.ts @@ -1,7 +1,7 @@ import { createMethods } from './create-methods' import { AppLogger } from './helpers/logger' -import { Metadata } from './IO' import { ConnectorExtensionClient } from './connector-extension/connector-extension-client' +import { Metadata } from '@radixdlt/radix-connect-schemas' export type WalletSdkInput = Omit & Partial<{ @@ -48,3 +48,4 @@ export const WalletSdk = (input: WalletSdkInput) => { export * from './IO' export * from './helpers/error' export * from './helpers/logger' +export * from '@radixdlt/radix-connect-schemas' diff --git a/package-lock.json b/package-lock.json index c3c6cfa..3728875 100644 --- a/package-lock.json +++ b/package-lock.json @@ -9,6 +9,7 @@ "version": "0.0.0", "license": "Apache-2.0", "dependencies": { + "@radixdlt/radix-connect-schemas": "^0.0.3", "neverthrow": "^6.0.0", "rxjs": "^7.8.1", "tslog": "^4.8.2", @@ -3881,6 +3882,18 @@ "node": ">=12" } }, + "node_modules/@radixdlt/radix-connect-schemas": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/@radixdlt/radix-connect-schemas/-/radix-connect-schemas-0.0.3.tgz", + "integrity": "sha512-ML8Xiy9p74bj/pL5qq5lSHu8M15RSGMNPkJPB4LQICIYWMl7G0533193yLGy2wVDc1Ps+ckd/HQkgbu9yP1O0A==", + "dependencies": { + "neverthrow": "^6.0.0", + "zod": "^3.22.2" + }, + "engines": { + "node": ">=14.0.0" + } + }, "node_modules/@semantic-release/commit-analyzer": { "version": "10.0.1", "resolved": "https://registry.npmjs.org/@semantic-release/commit-analyzer/-/commit-analyzer-10.0.1.tgz", @@ -16490,9 +16503,9 @@ } }, "node_modules/zod": { - "version": "3.21.4", - "resolved": "https://registry.npmjs.org/zod/-/zod-3.21.4.tgz", - "integrity": "sha512-m46AKbrzKVzOzs/DZgVnG5H55N1sv1M8qZU3A8RIKbs3mrACDNeIOeilDymVb2HdmP8uwshOCF4uJ8uM9rCqJw==", + "version": "3.22.2", + "resolved": "https://registry.npmjs.org/zod/-/zod-3.22.2.tgz", + "integrity": "sha512-wvWkphh5WQsJbVk1tbx1l1Ly4yg+XecD+Mq280uBGt9wa5BKSWf4Mhp6GmrkPixhMxmabYY7RbzlwVP32pbGCg==", "funding": { "url": "https://github.com/sponsors/colinhacks" } diff --git a/package.json b/package.json index 6e92940..a376c73 100644 --- a/package.json +++ b/package.json @@ -81,6 +81,7 @@ "vite-tsconfig-paths": "^4.2.0" }, "dependencies": { + "@radixdlt/radix-connect-schemas": "^0.0.3", "neverthrow": "^6.0.0", "rxjs": "^7.8.1", "tslog": "^4.8.2", From 2da0c75aa3450eb4f508bd5078fc89365d66087d Mon Sep 17 00:00:00 2001 From: Alex Stelea Date: Wed, 1 Nov 2023 10:03:50 +0100 Subject: [PATCH 2/2] chore: update dependencies --- package-lock.json | 16 ++++++++-------- package.json | 4 ++-- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/package-lock.json b/package-lock.json index 3728875..cc6ebb3 100644 --- a/package-lock.json +++ b/package-lock.json @@ -9,10 +9,10 @@ "version": "0.0.0", "license": "Apache-2.0", "dependencies": { - "@radixdlt/radix-connect-schemas": "^0.0.3", + "@radixdlt/radix-connect-schemas": "^1.0.0", "neverthrow": "^6.0.0", "rxjs": "^7.8.1", - "tslog": "^4.8.2", + "tslog": "4.8.0", "zod": "^3.21.4" }, "devDependencies": { @@ -3883,9 +3883,9 @@ } }, "node_modules/@radixdlt/radix-connect-schemas": { - "version": "0.0.3", - "resolved": "https://registry.npmjs.org/@radixdlt/radix-connect-schemas/-/radix-connect-schemas-0.0.3.tgz", - "integrity": "sha512-ML8Xiy9p74bj/pL5qq5lSHu8M15RSGMNPkJPB4LQICIYWMl7G0533193yLGy2wVDc1Ps+ckd/HQkgbu9yP1O0A==", + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@radixdlt/radix-connect-schemas/-/radix-connect-schemas-1.0.0.tgz", + "integrity": "sha512-8XKAEEaHNr9nfvT1P9o1JlX/adhNb5Rf1jwpbLBuRt3qxgSHzqlMrmfENYeRsBpHcN5LoDw2XX6p0H2IMtNIRA==", "dependencies": { "neverthrow": "^6.0.0", "zod": "^3.22.2" @@ -15903,9 +15903,9 @@ "integrity": "sha512-7At1WUettjcSRHXCyYtTselblcHl9PJFFVKiCAy/bY97+BPZXSQ2wbq0P9s8tK2G7dFQfNnlJnPAiArVBVBsfA==" }, "node_modules/tslog": { - "version": "4.8.2", - "resolved": "https://registry.npmjs.org/tslog/-/tslog-4.8.2.tgz", - "integrity": "sha512-eAKIRjxfSKYLs06r1wT7oou6Uv9VN6NW9g0JPidBlqQwPBBl5+84dm7r8zSOPVq1kyfEw1P6B3/FLSpZCorAgA==", + "version": "4.8.0", + "resolved": "https://registry.npmjs.org/tslog/-/tslog-4.8.0.tgz", + "integrity": "sha512-VueySGqCWpDK23DK/9Gbw/Eq11I4PHhiBZQaphpzTBUCKp/FIIX+/ec8fPz3q1ZhSfv31FhQU8wH3huHTDQ4fw==", "engines": { "node": ">=16" }, diff --git a/package.json b/package.json index a376c73..6ecb0b7 100644 --- a/package.json +++ b/package.json @@ -81,10 +81,10 @@ "vite-tsconfig-paths": "^4.2.0" }, "dependencies": { - "@radixdlt/radix-connect-schemas": "^0.0.3", + "@radixdlt/radix-connect-schemas": "^1.0.0", "neverthrow": "^6.0.0", "rxjs": "^7.8.1", - "tslog": "^4.8.2", + "tslog": "4.8.0", "zod": "^3.21.4" }, "repository": {