From a097ef1b92ba2794387680da6afafa8b0b63926e Mon Sep 17 00:00:00 2001 From: Muzaffar Ahmad Bhat Date: Mon, 30 Sep 2024 13:44:22 +0530 Subject: [PATCH 1/6] feat: added get-public-key functionality to xrp app --- apps/node/package.json | 5 +- apps/node/src/index.ts | 49 ++++++- packages/app-xrp/package.json | 3 +- packages/app-xrp/src/app.ts | 16 +++ packages/app-xrp/src/index.ts | 2 +- .../src/operations/getPublicKeys/index.ts | 59 ++++++++ .../getUserVerifiedPublicKey/index.ts | 66 +++++++++ .../getUserVerifiedPublicKey/types.ts | 12 ++ packages/app-xrp/src/operations/index.ts | 3 + .../src/operations/runGetPublicKeys/index.ts | 45 ++++++ .../src/operations/runGetPublicKeys/types.ts | 23 ++++ packages/app-xrp/src/operations/types.ts | 2 + packages/app-xrp/src/types.ts | 1 + packages/app-xrp/src/utils/address.ts | 11 ++ packages/app-xrp/src/utils/index.ts | 2 + packages/app-xrp/src/utils/xrpLib.ts | 16 +++ pnpm-lock.yaml | 128 +++++++++++++++++- submodules/common | 2 +- 18 files changed, 431 insertions(+), 14 deletions(-) create mode 100644 packages/app-xrp/src/operations/getPublicKeys/index.ts create mode 100644 packages/app-xrp/src/operations/getUserVerifiedPublicKey/index.ts create mode 100644 packages/app-xrp/src/operations/getUserVerifiedPublicKey/types.ts create mode 100644 packages/app-xrp/src/operations/index.ts create mode 100644 packages/app-xrp/src/operations/runGetPublicKeys/index.ts create mode 100644 packages/app-xrp/src/operations/runGetPublicKeys/types.ts create mode 100644 packages/app-xrp/src/operations/types.ts create mode 100644 packages/app-xrp/src/utils/address.ts create mode 100644 packages/app-xrp/src/utils/xrpLib.ts diff --git a/apps/node/package.json b/apps/node/package.json index 2de5ae772..380f95801 100644 --- a/apps/node/package.json +++ b/apps/node/package.json @@ -25,9 +25,9 @@ "@cypherock/sdk-app-evm": "workspace:^", "@cypherock/sdk-app-manager": "workspace:^", "@cypherock/sdk-app-near": "workspace:^", - "@cypherock/sdk-app-xrp": "workspace:^", "@cypherock/sdk-app-solana": "workspace:^", "@cypherock/sdk-app-tron": "workspace:^", + "@cypherock/sdk-app-xrp": "workspace:^", "@cypherock/sdk-core": "workspace:^", "@cypherock/sdk-hw-hid": "workspace:^", "@cypherock/sdk-hw-serialport": "workspace:^", @@ -38,6 +38,7 @@ "ethers": "^6.7.0", "near-api-js": "^2.1.4", "tronweb": "^5.3.2", - "winston": "^3.11.0" + "winston": "^3.11.0", + "xrpl": "^4.0.0" } } diff --git a/apps/node/src/index.ts b/apps/node/src/index.ts index a66d5ceb0..0b77b7ac9 100644 --- a/apps/node/src/index.ts +++ b/apps/node/src/index.ts @@ -10,10 +10,12 @@ import * as nearApiJs from 'near-api-js'; import * as solanaWeb3 from '@solana/web3.js'; import { setBitcoinJSLib } from '@cypherock/sdk-app-btc'; import { setEthersLib } from '@cypherock/sdk-app-evm'; -import { setNearApiJs } from '@cypherock/sdk-app-near'; +import { NearApp, setNearApiJs } from '@cypherock/sdk-app-near'; import { setSolanaWeb3 } from '@cypherock/sdk-app-solana'; import { ethers } from 'ethers'; import { createServiceLogger } from './logger'; +import { setXrpLib, XrpApp } from '@cypherock/sdk-app-xrp'; +import * as xrpl from 'xrpl'; const run = async () => { updateLogger(createServiceLogger); @@ -24,6 +26,7 @@ const run = async () => { setEthersLib(ethers); setNearApiJs(nearApiJs); setSolanaWeb3(solanaWeb3); + setXrpLib(xrpl); let connection: IDeviceConnection; @@ -35,15 +38,49 @@ const run = async () => { const managerApp = await ManagerApp.create(connection); - const deviceInfo = await managerApp.getDeviceInfo(); + // const deviceInfo = await managerApp.getDeviceInfo(); - console.log(deviceInfo); + // console.log(deviceInfo); - await managerApp.authDevice(); + const wallets = await managerApp.getWallets(); + const wallet = wallets.walletList[0]; - await managerApp.trainCard({ onWallets: async () => true }); + console.log({wallet}); - await managerApp.authCard(); + const xrpApp = await XrpApp.create(connection); + + const result_pub_key = await xrpApp.getPublicKeys({ + walletId: wallet.id, + derivationPaths: [ + { + path: [0x80000000 + 44, 0x80000000 + 144, 0x80000000, 0, 0], + }, + { + path: [0x80000000 + 44, 0x80000000 + 144, 0x80000000, 0, 1], + }, + { + path: [0x80000000 + 44, 0x80000000 + 144, 0x80000000, 0, 2], + }, + ], + }); + + console.log({result_pub_key}); + + // const result_user_verified_pub_key = await xrpApp.getUserVerifiedPublicKey({ + // walletId: wallet.id, + // derivationPath: [0x80000000 + 44, 0x80000000 + 144, 0x80000000, 0, 0] + // }) + + // console.log({result_user_verified_pub_key}); + + await xrpApp.destroy(); + + + // await managerApp.authDevice(); + + // await managerApp.trainCard({ onWallets: async () => true }); + + // await managerApp.authCard(); // await managerApp.updateFirmware({ // getDevices: async () => [ diff --git a/packages/app-xrp/package.json b/packages/app-xrp/package.json index 0efdd7af3..66edb9c1e 100644 --- a/packages/app-xrp/package.json +++ b/packages/app-xrp/package.json @@ -39,7 +39,8 @@ "@cypherock/sdk-interfaces": "workspace:^0.0.15", "@cypherock/sdk-utils": "workspace:^0.0.18", "long": "^5.2.1", - "protobufjs": "^7.2.2" + "protobufjs": "^7.2.2", + "xrpl": "^4.0.0" }, "lint-staged": { "*.{ts,tsx}": [ diff --git a/packages/app-xrp/src/app.ts b/packages/app-xrp/src/app.ts index c77e0fc0d..ab63de684 100644 --- a/packages/app-xrp/src/app.ts +++ b/packages/app-xrp/src/app.ts @@ -1,6 +1,8 @@ import { IDeviceConnection } from '@cypherock/sdk-interfaces'; import { SDK } from '@cypherock/sdk-core'; +import * as operations from './operations'; + export class XrpApp { private readonly sdk: SDK; @@ -15,6 +17,20 @@ export class XrpApp { return new XrpApp(sdk); } + public async getPublicKeys(params: operations.IGetPublicKeysParams) { + return this.sdk.runOperation(() => + operations.getPublicKeys(this.sdk, params), + ); + } + + public async getUserVerifiedPublicKey( + params: operations.IGetUserVerifiedPublicKeyParams, + ) { + return this.sdk.runOperation(() => + operations.getUserVerifiedPublicKey(this.sdk, params), + ); + } + public async destroy() { return this.sdk.destroy(); } diff --git a/packages/app-xrp/src/index.ts b/packages/app-xrp/src/index.ts index 3adb7aa5e..3f224ea82 100644 --- a/packages/app-xrp/src/index.ts +++ b/packages/app-xrp/src/index.ts @@ -1,3 +1,3 @@ export * from './app'; export * from './types'; -export { updateLogger } from './utils'; +export { updateLogger, setXrpLib } from './utils'; diff --git a/packages/app-xrp/src/operations/getPublicKeys/index.ts b/packages/app-xrp/src/operations/getPublicKeys/index.ts new file mode 100644 index 000000000..f8c79ff79 --- /dev/null +++ b/packages/app-xrp/src/operations/getPublicKeys/index.ts @@ -0,0 +1,59 @@ +import { ISDK } from '@cypherock/sdk-core'; +import { + createStatusListener, + assert, + createLoggerWithPrefix, +} from '@cypherock/sdk-utils'; +import { APP_VERSION } from '../../constants/appId'; +import { + GetPublicKeysStatus, + SeedGenerationStatus, +} from '../../proto/generated/types'; +import { OperationHelper, logger as rootLogger } from '../../utils'; +import { runGetPublicKeysOnDevice } from '../runGetPublicKeys'; +import { + IGetPublicKeysParams, + IGetPublicKeysResult, + GetPublicKeysEvent, +} from '../types'; + +const logger = createLoggerWithPrefix(rootLogger, 'GetPublicKeys'); + +export const getPublicKeys = async ( + sdk: ISDK, + params: IGetPublicKeysParams, +): Promise => { + assert(params, 'Params should be defined'); + assert(params.walletId, 'walletId should be defined'); + assert(params.derivationPaths, 'derivationPaths should be defined'); + assert( + params.derivationPaths.length > 0, + 'derivationPaths should not be empty', + ); + assert( + params.derivationPaths.reduce( + (acc, path) => acc && path.path.length > 3, + true, + ), + 'derivationPaths should be greater than 3', + ); + + await sdk.checkAppCompatibility(APP_VERSION); + + const { onStatus, forceStatusUpdate } = createStatusListener({ + enums: GetPublicKeysEvent, + operationEnums: GetPublicKeysStatus, + seedGenerationEnums: SeedGenerationStatus, + onEvent: params.onEvent, + logger, + }); + + const helper = new OperationHelper({ + sdk, + queryKey: 'getPublicKeys', + resultKey: 'getPublicKeys', + onStatus, + }); + + return runGetPublicKeysOnDevice(helper, params, forceStatusUpdate); +}; diff --git a/packages/app-xrp/src/operations/getUserVerifiedPublicKey/index.ts b/packages/app-xrp/src/operations/getUserVerifiedPublicKey/index.ts new file mode 100644 index 000000000..b03e09eb3 --- /dev/null +++ b/packages/app-xrp/src/operations/getUserVerifiedPublicKey/index.ts @@ -0,0 +1,66 @@ +import { ISDK } from '@cypherock/sdk-core'; +import { + createStatusListener, + assert, + createLoggerWithPrefix, +} from '@cypherock/sdk-utils'; +import { APP_VERSION } from '../../constants/appId'; +import { + GetPublicKeysStatus, + SeedGenerationStatus, +} from '../../proto/generated/types'; +import { OperationHelper, logger as rootLogger } from '../../utils'; +import { runGetPublicKeysOnDevice } from '../runGetPublicKeys'; +import { GetPublicKeysEvent } from '../types'; +import { + IGetUserVerifiedPublicKeyParams, + IGetUserVerifiedPublicKeyResult, +} from './types'; + +export * from './types'; + +const logger = createLoggerWithPrefix(rootLogger, 'GetPublicKeys'); + +export const getUserVerifiedPublicKey = async ( + sdk: ISDK, + params: IGetUserVerifiedPublicKeyParams, +): Promise => { + assert(params, 'Params should be defined'); + assert(params.walletId, 'walletId should be defined'); + assert(params.derivationPath, 'derivationPath should be defined'); + assert( + params.derivationPath.length > 3, + 'derivationPath should be greater than 3', + ); + + await sdk.checkAppCompatibility(APP_VERSION); + + const { onStatus, forceStatusUpdate } = createStatusListener({ + enums: GetPublicKeysEvent, + operationEnums: GetPublicKeysStatus, + seedGenerationEnums: SeedGenerationStatus, + onEvent: params.onEvent, + logger, + }); + + const helper = new OperationHelper({ + sdk, + queryKey: 'getUserVerifiedPublicKey', + resultKey: 'getUserVerifiedPublicKey', + onStatus, + }); + + const result = await runGetPublicKeysOnDevice( + helper, + { + walletId: params.walletId, + derivationPaths: [{ path: params.derivationPath }], + onEvent: params.onEvent, + }, + forceStatusUpdate, + ); + + return { + publicKey: result.publicKeys[0], + }; +}; diff --git a/packages/app-xrp/src/operations/getUserVerifiedPublicKey/types.ts b/packages/app-xrp/src/operations/getUserVerifiedPublicKey/types.ts new file mode 100644 index 000000000..487bacc38 --- /dev/null +++ b/packages/app-xrp/src/operations/getUserVerifiedPublicKey/types.ts @@ -0,0 +1,12 @@ +import { GetPublicKeysEventHandler } from '../runGetPublicKeys/types'; + +export interface IGetUserVerifiedPublicKeyParams { + onEvent?: GetPublicKeysEventHandler; + + walletId: Uint8Array; + derivationPath: number[]; +} + +export interface IGetUserVerifiedPublicKeyResult { + publicKey: string; +} diff --git a/packages/app-xrp/src/operations/index.ts b/packages/app-xrp/src/operations/index.ts new file mode 100644 index 000000000..ac301862b --- /dev/null +++ b/packages/app-xrp/src/operations/index.ts @@ -0,0 +1,3 @@ +export * from './getPublicKeys'; +export * from './getUserVerifiedPublicKey'; +export * from './runGetPublicKeys'; diff --git a/packages/app-xrp/src/operations/runGetPublicKeys/index.ts b/packages/app-xrp/src/operations/runGetPublicKeys/index.ts new file mode 100644 index 000000000..8532906ad --- /dev/null +++ b/packages/app-xrp/src/operations/runGetPublicKeys/index.ts @@ -0,0 +1,45 @@ +import { uint8ArrayToHex } from '@cypherock/sdk-utils'; +import { + OperationHelper, + assertOrThrowInvalidResult, + getAddressFromPublicKey, +} from '../../utils'; +import { IGetPublicKeysParams, GetPublicKeysEvent } from './types'; + +export * from './types'; + +export const runGetPublicKeysOnDevice = async ( + helper: + | OperationHelper<'getPublicKeys', 'getPublicKeys'> + | OperationHelper<'getUserVerifiedPublicKey', 'getUserVerifiedPublicKey'>, + params: IGetPublicKeysParams, + forceStatusUpdate: (flowStatus: number) => void, +) => { + await helper.sendQuery({ + initiate: { + walletId: params.walletId, + derivationPaths: params.derivationPaths, + }, + }); + + let publicKeys: Uint8Array[] = []; + const hasMore = () => publicKeys.length !== params.derivationPaths.length; + do { + const result = await helper.waitForResult(); + assertOrThrowInvalidResult(result.result); + publicKeys = [...publicKeys, ...result.result.publicKeys]; + forceStatusUpdate(GetPublicKeysEvent.PIN_CARD); + if (hasMore()) { + await helper.sendQuery({ + fetchNext: {}, + }); + } + } while (hasMore()); + + forceStatusUpdate(GetPublicKeysEvent.VERIFY); + + return { + publicKeys: publicKeys.map(e => uint8ArrayToHex(e)), + addresses: publicKeys.map(e => getAddressFromPublicKey(e)), + }; +}; diff --git a/packages/app-xrp/src/operations/runGetPublicKeys/types.ts b/packages/app-xrp/src/operations/runGetPublicKeys/types.ts new file mode 100644 index 000000000..bf273f2d8 --- /dev/null +++ b/packages/app-xrp/src/operations/runGetPublicKeys/types.ts @@ -0,0 +1,23 @@ +import { IGetPublicKeysDerivationPath } from '../../proto/generated/types'; + +export enum GetPublicKeysEvent { + INIT = 0, + CONFIRM = 1, + PASSPHRASE = 2, + PIN_CARD = 3, + VERIFY = 4, +} + +export type GetPublicKeysEventHandler = (event: GetPublicKeysEvent) => void; + +export interface IGetPublicKeysParams { + onEvent?: GetPublicKeysEventHandler; + + walletId: Uint8Array; + derivationPaths: IGetPublicKeysDerivationPath[]; +} + +export interface IGetPublicKeysResult { + publicKeys: string[]; + addresses: string[]; +} diff --git a/packages/app-xrp/src/operations/types.ts b/packages/app-xrp/src/operations/types.ts new file mode 100644 index 000000000..170894c21 --- /dev/null +++ b/packages/app-xrp/src/operations/types.ts @@ -0,0 +1,2 @@ +export * from './runGetPublicKeys/types'; +export * from './getUserVerifiedPublicKey/types'; diff --git a/packages/app-xrp/src/types.ts b/packages/app-xrp/src/types.ts index deae53a38..ad2209678 100644 --- a/packages/app-xrp/src/types.ts +++ b/packages/app-xrp/src/types.ts @@ -1 +1,2 @@ +export * from './operations/types'; export * from './proto/generated/types'; diff --git a/packages/app-xrp/src/utils/address.ts b/packages/app-xrp/src/utils/address.ts new file mode 100644 index 000000000..07ff62f33 --- /dev/null +++ b/packages/app-xrp/src/utils/address.ts @@ -0,0 +1,11 @@ +import { uint8ArrayToHex } from '@cypherock/sdk-utils'; +import { getXrpLib } from './xrpLib'; + +export const getAddressFromPublicKey = (publicKey: string | Uint8Array) => { + const publicKeyHex = + typeof publicKey === 'string' ? publicKey : uint8ArrayToHex(publicKey); + + const xrpl = getXrpLib(); + + return xrpl.deriveAddress(publicKeyHex); +}; diff --git a/packages/app-xrp/src/utils/index.ts b/packages/app-xrp/src/utils/index.ts index d91bcab1f..94cca3801 100644 --- a/packages/app-xrp/src/utils/index.ts +++ b/packages/app-xrp/src/utils/index.ts @@ -1,3 +1,5 @@ export * from './operationHelper'; export * from './asserts'; export * from './logger'; +export * from './xrpLib'; +export * from './address'; diff --git a/packages/app-xrp/src/utils/xrpLib.ts b/packages/app-xrp/src/utils/xrpLib.ts new file mode 100644 index 000000000..6d264293c --- /dev/null +++ b/packages/app-xrp/src/utils/xrpLib.ts @@ -0,0 +1,16 @@ +import type xrpl from 'xrpl'; + +export type XrpLibType = typeof xrpl; + +let xrpLibInstance: XrpLibType | undefined; + +export const getXrpLib = () => { + if (!xrpLibInstance) { + throw new Error('xrpl has not been set yet'); + } + return xrpLibInstance; +}; + +export const setXrpLib = (xrpLibrary: XrpLibType) => { + xrpLibInstance = xrpLibrary; +}; diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index c966658f2..8cb41849f 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -144,6 +144,9 @@ importers: winston: specifier: ^3.11.0 version: 3.11.0 + xrpl: + specifier: ^4.0.0 + version: 4.0.0(bufferutil@4.0.8)(utf-8-validate@5.0.10) devDependencies: '@cypherock/eslint-config': specifier: workspace:* @@ -643,6 +646,9 @@ importers: protobufjs: specifier: ^7.2.2 version: 7.2.2 + xrpl: + specifier: ^4.0.0 + version: 4.0.0(bufferutil@4.0.8)(utf-8-validate@5.0.10) devDependencies: '@cypherock/eslint-config': specifier: workspace:* @@ -1225,6 +1231,7 @@ packages: '@babel/plugin-proposal-class-properties@7.18.6': resolution: {integrity: sha512-cumfXOF0+nzZrrN8Rf0t7M+tF6sZc7vhQwYQck9q1/5w2OExlD+b4v4RpMJFaV1Z7WcDRgO6FqvxqxGlwo+RHQ==} engines: {node: '>=6.9.0'} + deprecated: This proposal has been merged to the ECMAScript standard and thus this plugin is no longer maintained. Please use @babel/plugin-transform-class-properties instead. peerDependencies: '@babel/core': ^7.0.0-0 @@ -1237,6 +1244,7 @@ packages: '@babel/plugin-proposal-private-methods@7.18.6': resolution: {integrity: sha512-nutsvktDItsNn4rpGItSNV2sz1XwS+nfU0Rg8aCx3W3NOKVzdMjJRu0O5OkgDp3ZGICSTbgRpxZoWsxoKRvbeA==} engines: {node: '>=6.9.0'} + deprecated: This proposal has been merged to the ECMAScript standard and thus this plugin is no longer maintained. Please use @babel/plugin-transform-private-methods instead. peerDependencies: '@babel/core': ^7.0.0-0 @@ -1573,9 +1581,11 @@ packages: '@humanwhocodes/config-array@0.5.0': resolution: {integrity: sha512-FagtKFz74XrTl7y6HCzQpwDfXP0yhxe9lHLD1UZxjvZIcbyRz8zTFF/yYNfSfzU414eDwZ1SrO0Qvtyf+wFMQg==} engines: {node: '>=10.10.0'} + deprecated: Use @eslint/config-array instead '@humanwhocodes/object-schema@1.2.1': resolution: {integrity: sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA==} + deprecated: Use @eslint/object-schema instead '@istanbuljs/load-nyc-config@1.1.0': resolution: {integrity: sha512-VjeHSlIzpv/NyD3N0YuHfXOPDIixcA1q2ZV98wsMqcYlPmv2n3Yb2lYP9XMElnaFVXg5A7YLTeLu6V84uQDjmQ==} @@ -2198,6 +2208,13 @@ packages: resolution: {integrity: sha512-07ny+LHRzQXepkGg6w0mFY41fVUNBrL2Roj/++7V1txKugfjm/Ci/qSND03r2RhlJhJYMcTn9AhhSSqQp0Ysyw==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + '@xrplf/isomorphic@1.0.1': + resolution: {integrity: sha512-0bIpgx8PDjYdrLFeC3csF305QQ1L7sxaWnL5y71mCvhenZzJgku9QsA+9QCXBC1eNYtxWO/xR91zrXJy2T/ixg==} + engines: {node: '>=16.0.0'} + + '@xrplf/secret-numbers@1.0.0': + resolution: {integrity: sha512-qsCLGyqe1zaq9j7PZJopK+iGTGRbk6akkg6iZXJJgxKwck0C5x5Gnwlb1HKYGOwPKyrXWpV6a2YmcpNpUFctGg==} + JSONStream@1.3.5: resolution: {integrity: sha512-E+iruNOY8VV9s4JEbe1aNEm6MiszPRr/UfcHMz0TQh1BXSxHK+ASV1R6W4HpjBhSeS+54PIsAMCBmwD06LLsqQ==} hasBin: true @@ -3290,6 +3307,9 @@ packages: eventemitter3@4.0.7: resolution: {integrity: sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw==} + eventemitter3@5.0.1: + resolution: {integrity: sha512-GWkBvjiSZK87ELrYOSESUYeVIc9mvLLf/nXalMOS5dYrgZq9o5OVkbZAVM06CVxYsCwH9BDZFPlQTlPA1j4ahA==} + events@3.3.0: resolution: {integrity: sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==} engines: {node: '>=0.8.x'} @@ -3518,13 +3538,16 @@ packages: glob@7.1.7: resolution: {integrity: sha512-OvD9ENzPLbegENnYP5UUfJIirTg4+XwMWGaQfQTY0JenxNvvIKP3U3/tAQSPIu/lHxXYSZmpXlUHeqAIdKzBLQ==} + deprecated: Glob versions prior to v9 are no longer supported glob@7.2.3: resolution: {integrity: sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==} + deprecated: Glob versions prior to v9 are no longer supported glob@8.1.0: resolution: {integrity: sha512-r8hpEjiQEYlF2QU0df3dS+nxxSIreXQS1qRhMJM0Q5NDdR386C7jb7Hwwod8Fgiuex+k0GFjgft18yvxm5XoCQ==} engines: {node: '>=12'} + deprecated: Glob versions prior to v9 are no longer supported global-dirs@0.1.1: resolution: {integrity: sha512-NknMLn7F2J7aflwFOlGdNIuCDpN3VGoSoB+aap3KABFWbHVn1TCgFC+np23J8W2BiZbjfEw3BFBycSMv1AFblg==} @@ -3690,6 +3713,7 @@ packages: inflight@1.0.6: resolution: {integrity: sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==} + deprecated: This module is not supported, and leaks memory. Do not use it. Check out lru-cache if you want a good and tested way to coalesce async requests by a key value, which is much more comprehensive and powerful. inherits@2.0.1: resolution: {integrity: sha512-8nWq2nLTAwd02jTqJExUYFSD/fKq6VH9Y/oG2accc/kdI0V98Bag8d5a4gi3XHz73rDWa2PvTtvcWYquKqSENA==} @@ -4786,6 +4810,10 @@ packages: q@1.5.1: resolution: {integrity: sha512-kV/CThkXo6xyFEZUugw/+pIOywXcDbFYgSct5cT3gqlbkBE1SJdwy6UQoZvodiWF/ckQLZyDE/Bu1M6gVu5lVw==} engines: {node: '>=0.6.0', teleport: '>=0.2.0'} + deprecated: |- + You or someone you depend on is using Q, the JavaScript Promise library that gave JavaScript developers strong feelings about promises. They can almost certainly migrate to the native JavaScript promise now. Thank you literally everyone for joining me in this bet against the odds. Be excellent to each other. + + (For a CapTP with native promises, see @endo/eventual-send and @endo/captp) qs@6.11.1: resolution: {integrity: sha512-0wsrzgTz/kAVIeuxSjnpGC56rzYtr6JT/2BwEvMaPhFIoYa1aGO8LbzuU1R0uUYQkLpWBTOj0l/CLAJB64J6nQ==} @@ -4931,6 +4959,7 @@ packages: rimraf@3.0.2: resolution: {integrity: sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==} + deprecated: Rimraf versions prior to v4 are no longer supported hasBin: true rimraf@4.1.2: @@ -4942,6 +4971,18 @@ packages: ripemd160@2.0.2: resolution: {integrity: sha512-ii4iagi25WusVoiC4B4lq7pbXfAp3D9v5CwfkY33vffw2+pkDjY1D8GaN7spsxvCSx8dkPqOZCEZyfxcmJG2IA==} + ripple-address-codec@5.0.0: + resolution: {integrity: sha512-de7osLRH/pt5HX2xw2TRJtbdLLWHu0RXirpQaEeCnWKY5DYHykh3ETSkofvm0aX0LJiV7kwkegJxQkmbO94gWw==} + engines: {node: '>= 16'} + + ripple-binary-codec@2.1.0: + resolution: {integrity: sha512-q0GAx+hj3UVcDbhXVjk7qeNfgUMehlElYJwiCuIBwqs/51GVTOwLr39Ht3eNsX5ow2xPRaC5mqHwcFDvLRm6cA==} + engines: {node: '>= 16'} + + ripple-keypairs@2.0.0: + resolution: {integrity: sha512-b5rfL2EZiffmklqZk1W+dvSy97v3V/C7936WxCCgDynaGPp7GE6R2XO7EU9O2LlM/z95rj870IylYnOQs+1Rag==} + engines: {node: '>= 16'} + rpc-websockets@7.8.0: resolution: {integrity: sha512-AStkq6KDvSAmA4WiwlK1pDvj/33BWmExTATUokC0v+NhWekXSTNzXS5OGXeYwq501/pj6lBZMofg/h4dx4/tCg==} @@ -5754,6 +5795,18 @@ packages: utf-8-validate: optional: true + ws@8.18.0: + resolution: {integrity: sha512-8VbfWfHLbbwu3+N6OKsOMpBdT4kXPDDB9cJk2bJ6mh9ucxdlnNvH1e+roYkKmN9Nxw2yjz7VzeO9oOz2zJ04Pw==} + engines: {node: '>=10.0.0'} + peerDependencies: + bufferutil: ^4.0.1 + utf-8-validate: '>=5.0.2' + peerDependenciesMeta: + bufferutil: + optional: true + utf-8-validate: + optional: true + ws@8.5.0: resolution: {integrity: sha512-BWX0SWVgLPzYwF8lTzEy1egjhS4S4OEAHfsO8o65WOVsrnSRGaSiUaa9e0ggGlkMTtBlmOpEXiie9RUcBO86qg==} engines: {node: '>=10.0.0'} @@ -5766,6 +5819,10 @@ packages: utf-8-validate: optional: true + xrpl@4.0.0: + resolution: {integrity: sha512-VZm1lQWHQ6PheAAFGdH+ISXKvqB2hZDQ0w4ZcdAEtmqZQXtSIVQHOKPz95rEgGANbos7+XClxJ73++joPhA8Cw==} + engines: {node: '>=18.0.0'} + xtend@4.0.2: resolution: {integrity: sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==} engines: {node: '>=0.4'} @@ -7651,6 +7708,23 @@ snapshots: '@typescript-eslint/types': 5.62.0 eslint-visitor-keys: 3.4.3 + '@xrplf/isomorphic@1.0.1(bufferutil@4.0.8)(utf-8-validate@5.0.10)': + dependencies: + '@noble/hashes': 1.3.3 + eventemitter3: 5.0.1 + ws: 8.18.0(bufferutil@4.0.8)(utf-8-validate@5.0.10) + transitivePeerDependencies: + - bufferutil + - utf-8-validate + + '@xrplf/secret-numbers@1.0.0(bufferutil@4.0.8)(utf-8-validate@5.0.10)': + dependencies: + '@xrplf/isomorphic': 1.0.1(bufferutil@4.0.8)(utf-8-validate@5.0.10) + ripple-keypairs: 2.0.0(bufferutil@4.0.8)(utf-8-validate@5.0.10) + transitivePeerDependencies: + - bufferutil + - utf-8-validate + JSONStream@1.3.5: dependencies: jsonparse: 1.3.1 @@ -8828,7 +8902,7 @@ snapshots: eslint: 7.32.0 eslint-import-resolver-node: 0.3.7 eslint-import-resolver-typescript: 3.5.3(eslint-plugin-import@2.27.5(eslint@7.32.0))(eslint@7.32.0) - eslint-plugin-import: 2.27.5(@typescript-eslint/parser@5.49.0(eslint@7.32.0)(typescript@4.9.5))(eslint-import-resolver-typescript@3.5.3(eslint-plugin-import@2.27.5(eslint@7.32.0))(eslint@7.32.0))(eslint@7.32.0) + eslint-plugin-import: 2.27.5(@typescript-eslint/parser@5.49.0(eslint@7.32.0)(typescript@4.9.5))(eslint-import-resolver-typescript@3.5.3)(eslint@7.32.0) eslint-plugin-jsx-a11y: 6.7.1(eslint@7.32.0) eslint-plugin-react: 7.32.2(eslint@7.32.0) eslint-plugin-react-hooks: 4.6.0(eslint@7.32.0) @@ -8863,7 +8937,7 @@ snapshots: debug: 4.3.4 enhanced-resolve: 5.12.0 eslint: 7.32.0 - eslint-plugin-import: 2.27.5(@typescript-eslint/parser@5.49.0(eslint@7.32.0)(typescript@4.9.5))(eslint-import-resolver-typescript@3.5.3(eslint-plugin-import@2.27.5(eslint@7.32.0))(eslint@7.32.0))(eslint@7.32.0) + eslint-plugin-import: 2.27.5(@typescript-eslint/parser@5.49.0(eslint@7.32.0)(typescript@4.9.5))(eslint-import-resolver-typescript@3.5.3)(eslint@7.32.0) get-tsconfig: 4.3.0 globby: 13.1.3 is-core-module: 2.11.0 @@ -8893,7 +8967,7 @@ snapshots: transitivePeerDependencies: - supports-color - eslint-plugin-import@2.27.5(@typescript-eslint/parser@5.49.0(eslint@7.32.0)(typescript@4.9.5))(eslint-import-resolver-typescript@3.5.3(eslint-plugin-import@2.27.5(eslint@7.32.0))(eslint@7.32.0))(eslint@7.32.0): + eslint-plugin-import@2.27.5(@typescript-eslint/parser@5.49.0(eslint@7.32.0)(typescript@4.9.5))(eslint-import-resolver-typescript@3.5.3)(eslint@7.32.0): dependencies: array-includes: 3.1.6 array.prototype.flat: 1.3.1 @@ -9099,6 +9173,8 @@ snapshots: eventemitter3@4.0.7: {} + eventemitter3@5.0.1: {} + events@3.3.0: {} evp_bytestokey@1.0.3: @@ -11118,6 +11194,32 @@ snapshots: hash-base: 3.1.0 inherits: 2.0.4 + ripple-address-codec@5.0.0(bufferutil@4.0.8)(utf-8-validate@5.0.10): + dependencies: + '@scure/base': 1.1.6 + '@xrplf/isomorphic': 1.0.1(bufferutil@4.0.8)(utf-8-validate@5.0.10) + transitivePeerDependencies: + - bufferutil + - utf-8-validate + + ripple-binary-codec@2.1.0(bufferutil@4.0.8)(utf-8-validate@5.0.10): + dependencies: + '@xrplf/isomorphic': 1.0.1(bufferutil@4.0.8)(utf-8-validate@5.0.10) + bignumber.js: 9.1.2 + ripple-address-codec: 5.0.0(bufferutil@4.0.8)(utf-8-validate@5.0.10) + transitivePeerDependencies: + - bufferutil + - utf-8-validate + + ripple-keypairs@2.0.0(bufferutil@4.0.8)(utf-8-validate@5.0.10): + dependencies: + '@noble/curves': 1.3.0 + '@xrplf/isomorphic': 1.0.1(bufferutil@4.0.8)(utf-8-validate@5.0.10) + ripple-address-codec: 5.0.0(bufferutil@4.0.8)(utf-8-validate@5.0.10) + transitivePeerDependencies: + - bufferutil + - utf-8-validate + rpc-websockets@7.8.0: dependencies: '@babel/runtime': 7.23.5 @@ -12050,11 +12152,31 @@ snapshots: bufferutil: 4.0.8 utf-8-validate: 5.0.10 + ws@8.18.0(bufferutil@4.0.8)(utf-8-validate@5.0.10): + optionalDependencies: + bufferutil: 4.0.8 + utf-8-validate: 5.0.10 + ws@8.5.0(bufferutil@4.0.8)(utf-8-validate@5.0.10): optionalDependencies: bufferutil: 4.0.8 utf-8-validate: 5.0.10 + xrpl@4.0.0(bufferutil@4.0.8)(utf-8-validate@5.0.10): + dependencies: + '@scure/bip32': 1.3.3 + '@scure/bip39': 1.2.2 + '@xrplf/isomorphic': 1.0.1(bufferutil@4.0.8)(utf-8-validate@5.0.10) + '@xrplf/secret-numbers': 1.0.0(bufferutil@4.0.8)(utf-8-validate@5.0.10) + bignumber.js: 9.1.2 + eventemitter3: 5.0.1 + ripple-address-codec: 5.0.0(bufferutil@4.0.8)(utf-8-validate@5.0.10) + ripple-binary-codec: 2.1.0(bufferutil@4.0.8)(utf-8-validate@5.0.10) + ripple-keypairs: 2.0.0(bufferutil@4.0.8)(utf-8-validate@5.0.10) + transitivePeerDependencies: + - bufferutil + - utf-8-validate + xtend@4.0.2: {} y18n@4.0.3: {} diff --git a/submodules/common b/submodules/common index a9b3f503d..d60bfa9ab 160000 --- a/submodules/common +++ b/submodules/common @@ -1 +1 @@ -Subproject commit a9b3f503df0c937f3542cfb8573dc8ac21a4a033 +Subproject commit d60bfa9ab8fc4f85b84ab41362e53622e7d2a2e1 From 4ab29d8e618cf3d3bba9379610537f3ead22feb8 Mon Sep 17 00:00:00 2001 From: Muzaffar Ahmad Bhat Date: Mon, 30 Sep 2024 14:31:50 +0530 Subject: [PATCH 2/6] fix: fixed ci eslint errors --- apps/node/src/index.ts | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/apps/node/src/index.ts b/apps/node/src/index.ts index 0b77b7ac9..045350c13 100644 --- a/apps/node/src/index.ts +++ b/apps/node/src/index.ts @@ -10,12 +10,12 @@ import * as nearApiJs from 'near-api-js'; import * as solanaWeb3 from '@solana/web3.js'; import { setBitcoinJSLib } from '@cypherock/sdk-app-btc'; import { setEthersLib } from '@cypherock/sdk-app-evm'; -import { NearApp, setNearApiJs } from '@cypherock/sdk-app-near'; +import { setNearApiJs } from '@cypherock/sdk-app-near'; import { setSolanaWeb3 } from '@cypherock/sdk-app-solana'; import { ethers } from 'ethers'; -import { createServiceLogger } from './logger'; import { setXrpLib, XrpApp } from '@cypherock/sdk-app-xrp'; import * as xrpl from 'xrpl'; +import { createServiceLogger } from './logger'; const run = async () => { updateLogger(createServiceLogger); @@ -49,7 +49,7 @@ const run = async () => { const xrpApp = await XrpApp.create(connection); - const result_pub_key = await xrpApp.getPublicKeys({ + const resultPubKey = await xrpApp.getPublicKeys({ walletId: wallet.id, derivationPaths: [ { @@ -64,14 +64,14 @@ const run = async () => { ], }); - console.log({result_pub_key}); + console.log({resultPubKey}); - // const result_user_verified_pub_key = await xrpApp.getUserVerifiedPublicKey({ + // const resultUserVerifiedPubKey = await xrpApp.getUserVerifiedPublicKey({ // walletId: wallet.id, // derivationPath: [0x80000000 + 44, 0x80000000 + 144, 0x80000000, 0, 0] // }) - // console.log({result_user_verified_pub_key}); + // console.log({resultUserVerifiedPubKey}); await xrpApp.destroy(); From d242be6ab8afa1ab72526b86373a22583e6a32b0 Mon Sep 17 00:00:00 2001 From: Muzaffar Ahmad Bhat Date: Mon, 30 Sep 2024 14:49:25 +0530 Subject: [PATCH 3/6] fix: code prettier issues --- apps/node/src/index.ts | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/apps/node/src/index.ts b/apps/node/src/index.ts index 045350c13..adac38d06 100644 --- a/apps/node/src/index.ts +++ b/apps/node/src/index.ts @@ -45,7 +45,7 @@ const run = async () => { const wallets = await managerApp.getWallets(); const wallet = wallets.walletList[0]; - console.log({wallet}); + console.log({ wallet }); const xrpApp = await XrpApp.create(connection); @@ -64,18 +64,17 @@ const run = async () => { ], }); - console.log({resultPubKey}); + console.log({ resultPubKey }); // const resultUserVerifiedPubKey = await xrpApp.getUserVerifiedPublicKey({ // walletId: wallet.id, // derivationPath: [0x80000000 + 44, 0x80000000 + 144, 0x80000000, 0, 0] // }) - // console.log({resultUserVerifiedPubKey}); + // console.log({ resultUserVerifiedPubKey }); await xrpApp.destroy(); - // await managerApp.authDevice(); // await managerApp.trainCard({ onWallets: async () => true }); From 27f2925d629f08bf443303177f84ace801c9c44c Mon Sep 17 00:00:00 2001 From: Muzaffar Ahmad Bhat Date: Sat, 5 Oct 2024 13:21:49 +0530 Subject: [PATCH 4/6] fix: returned address and public key from xrp app --- .../app-xrp/src/operations/getUserVerifiedPublicKey/index.ts | 1 + .../app-xrp/src/operations/getUserVerifiedPublicKey/types.ts | 1 + 2 files changed, 2 insertions(+) diff --git a/packages/app-xrp/src/operations/getUserVerifiedPublicKey/index.ts b/packages/app-xrp/src/operations/getUserVerifiedPublicKey/index.ts index b03e09eb3..b85e88641 100644 --- a/packages/app-xrp/src/operations/getUserVerifiedPublicKey/index.ts +++ b/packages/app-xrp/src/operations/getUserVerifiedPublicKey/index.ts @@ -62,5 +62,6 @@ export const getUserVerifiedPublicKey = async ( return { publicKey: result.publicKeys[0], + address: result.addresses[0], }; }; diff --git a/packages/app-xrp/src/operations/getUserVerifiedPublicKey/types.ts b/packages/app-xrp/src/operations/getUserVerifiedPublicKey/types.ts index 487bacc38..b2724d1ec 100644 --- a/packages/app-xrp/src/operations/getUserVerifiedPublicKey/types.ts +++ b/packages/app-xrp/src/operations/getUserVerifiedPublicKey/types.ts @@ -9,4 +9,5 @@ export interface IGetUserVerifiedPublicKeyParams { export interface IGetUserVerifiedPublicKeyResult { publicKey: string; + address: string; } From fdc822e4c6d8f5d67bdad8b412c91074378b760a Mon Sep 17 00:00:00 2001 From: Muzaffar Ahmad Bhat Date: Mon, 7 Oct 2024 12:30:03 +0530 Subject: [PATCH 5/6] fix: added get-public-key tests --- .../02.getPublicKeys/__fixtures__/error.ts | 79 +++++++ .../02.getPublicKeys/__fixtures__/index.ts | 14 ++ .../__fixtures__/invalidArgs.ts | 69 +++++++ .../__fixtures__/invalidData.ts | 108 ++++++++++ .../02.getPublicKeys/__fixtures__/types.ts | 28 +++ .../02.getPublicKeys/__fixtures__/valid.ts | 192 ++++++++++++++++++ .../02.getPublicKeys/__helpers__/index.ts | 14 ++ .../app-xrp/tests/02.getPublicKeys/index.ts | 104 ++++++++++ 8 files changed, 608 insertions(+) create mode 100644 packages/app-xrp/tests/02.getPublicKeys/__fixtures__/error.ts create mode 100644 packages/app-xrp/tests/02.getPublicKeys/__fixtures__/index.ts create mode 100644 packages/app-xrp/tests/02.getPublicKeys/__fixtures__/invalidArgs.ts create mode 100644 packages/app-xrp/tests/02.getPublicKeys/__fixtures__/invalidData.ts create mode 100644 packages/app-xrp/tests/02.getPublicKeys/__fixtures__/types.ts create mode 100644 packages/app-xrp/tests/02.getPublicKeys/__fixtures__/valid.ts create mode 100644 packages/app-xrp/tests/02.getPublicKeys/__helpers__/index.ts create mode 100644 packages/app-xrp/tests/02.getPublicKeys/index.ts diff --git a/packages/app-xrp/tests/02.getPublicKeys/__fixtures__/error.ts b/packages/app-xrp/tests/02.getPublicKeys/__fixtures__/error.ts new file mode 100644 index 000000000..f303ba09e --- /dev/null +++ b/packages/app-xrp/tests/02.getPublicKeys/__fixtures__/error.ts @@ -0,0 +1,79 @@ +import { + DeviceAppError, + DeviceAppErrorType, + deviceAppErrorTypeDetails, +} from '@cypherock/sdk-interfaces'; +import { IGetPublicKeysTestCase } from './types'; +import { Query } from '../../../src/proto/generated/xrp/core'; + +const commonParams = { + params: { + walletId: new Uint8Array([ + 199, 89, 252, 26, 32, 135, 183, 211, 90, 220, 38, 17, 160, 103, 233, 62, + 110, 172, 92, 20, 35, 250, 190, 146, 62, 8, 53, 86, 128, 26, 3, 187, 121, + 64, + ]), + derivationPaths: [ + { + path: [0x80000000 + 44, 0x80000000 + 144, 0x80000000, 0, 0], + }, + ], + }, + queries: [ + { + name: 'Initate query', + data: Uint8Array.from( + Query.encode( + Query.create({ + getPublicKeys: { + initiate: { + walletId: new Uint8Array([ + 199, 89, 252, 26, 32, 135, 183, 211, 90, 220, 38, 17, 160, + 103, 233, 62, 110, 172, 92, 20, 35, 250, 190, 146, 62, 8, 53, + 86, 128, 26, 3, 187, 121, 64, + ]), + derivationPaths: [ + { + path: [0x80000000 + 44, 0x80000000 + 144, 0x80000000, 0, 0], + }, + ], + }, + }, + }), + ).finish(), + ), + }, + ], +}; + +const withUnknownError: IGetPublicKeysTestCase = { + name: 'With unknown error', + ...commonParams, + results: [ + { + name: 'error', + data: new Uint8Array([10, 4, 18, 2, 8, 1]), + }, + ], + errorInstance: DeviceAppError, + errorMessage: + deviceAppErrorTypeDetails[DeviceAppErrorType.UNKNOWN_ERROR].message, +}; + +const withInvalidAppId: IGetPublicKeysTestCase = { + name: 'With invalid msg from device', + ...commonParams, + results: [ + { + name: 'error', + data: new Uint8Array([10, 4, 18, 2, 16, 1]), + }, + ], + errorInstance: DeviceAppError, + errorMessage: + deviceAppErrorTypeDetails[DeviceAppErrorType.CORRUPT_DATA].message, +}; + +const error: IGetPublicKeysTestCase[] = [withUnknownError, withInvalidAppId]; + +export default error; diff --git a/packages/app-xrp/tests/02.getPublicKeys/__fixtures__/index.ts b/packages/app-xrp/tests/02.getPublicKeys/__fixtures__/index.ts new file mode 100644 index 000000000..b3c347e6c --- /dev/null +++ b/packages/app-xrp/tests/02.getPublicKeys/__fixtures__/index.ts @@ -0,0 +1,14 @@ +import { IFixtures } from './types'; +import error from './error'; +import invalidData from './invalidData'; +import valid from './valid'; +import invalidArgs from './invalidArgs'; + +const fixtures: IFixtures = { + valid, + error, + invalidData, + invalidArgs, +}; + +export default fixtures; diff --git a/packages/app-xrp/tests/02.getPublicKeys/__fixtures__/invalidArgs.ts b/packages/app-xrp/tests/02.getPublicKeys/__fixtures__/invalidArgs.ts new file mode 100644 index 000000000..3ff0fa48e --- /dev/null +++ b/packages/app-xrp/tests/02.getPublicKeys/__fixtures__/invalidArgs.ts @@ -0,0 +1,69 @@ +import { IGetPublicKeysTestCase } from './types'; + +const commonParams = { + queries: [{ name: 'empty', data: new Uint8Array([]) }], + results: [{ name: 'empty', data: new Uint8Array([]) }], + errorInstance: Error, + errorMessage: /AssertionError/, +}; + +const validParams = { + walletId: new Uint8Array([ + 199, 89, 252, 26, 32, 135, 183, 211, 90, 220, 38, 17, 160, 103, 233, 62, + 110, 172, 92, 20, 35, 250, 190, 146, 62, 8, 53, 86, 128, 26, 3, 187, 121, + 64, + ]), + derivationPaths: [ + { + path: [0x80000000 + 44, 0x80000000 + 144, 0x80000000, 0, 0], + }, + ], +}; + +const invalidArgs: IGetPublicKeysTestCase[] = [ + { + name: 'Null', + ...commonParams, + params: null as any, + }, + { + name: 'Undefined', + ...commonParams, + params: null as any, + }, + { + name: 'Empty Object', + ...commonParams, + params: {} as any, + }, + { + name: 'No derivation paths', + ...commonParams, + params: { ...validParams, derivationPaths: undefined } as any, + }, + { + name: 'Empty derivation path', + ...commonParams, + params: { + ...validParams, + derivationPaths: [], + } as any, + }, + { + name: 'invalid derivation path in array (depth:2)', + ...commonParams, + params: { + ...validParams, + derivationPaths: [ + { + path: [ + { index: 44, isHardened: true }, + { index: 144, isHardened: true }, + ], + }, + ], + }, + }, +]; + +export default invalidArgs; diff --git a/packages/app-xrp/tests/02.getPublicKeys/__fixtures__/invalidData.ts b/packages/app-xrp/tests/02.getPublicKeys/__fixtures__/invalidData.ts new file mode 100644 index 000000000..2ff42be5a --- /dev/null +++ b/packages/app-xrp/tests/02.getPublicKeys/__fixtures__/invalidData.ts @@ -0,0 +1,108 @@ +import { + DeviceAppError, + DeviceAppErrorType, + deviceAppErrorTypeDetails, +} from '@cypherock/sdk-interfaces'; +import { IGetPublicKeysTestCase } from './types'; +import { Query } from '../../../src/proto/generated/xrp/core'; + +const commonParams = { + params: { + walletId: new Uint8Array([ + 199, 89, 252, 26, 32, 135, 183, 211, 90, 220, 38, 17, 160, 103, 233, 62, + 110, 172, 92, 20, 35, 250, 190, 146, 62, 8, 53, 86, 128, 26, 3, 187, 121, + 64, + ]), + derivationPaths: [ + { + path: [0x80000000 + 44, 0x80000000 + 144, 0x80000000, 0, 0], + }, + ], + }, + queries: [ + { + name: 'Initate query', + data: Uint8Array.from( + Query.encode( + Query.create({ + getPublicKeys: { + initiate: { + walletId: new Uint8Array([ + 199, 89, 252, 26, 32, 135, 183, 211, 90, 220, 38, 17, 160, + 103, 233, 62, 110, 172, 92, 20, 35, 250, 190, 146, 62, 8, 53, + 86, 128, 26, 3, 187, 121, 64, + ]), + derivationPaths: [ + { + path: [0x80000000 + 44, 0x80000000 + 144, 0x80000000, 0, 0], + }, + ], + }, + }, + }), + ).finish(), + ), + }, + ], + errorInstance: DeviceAppError, + errorMessage: + deviceAppErrorTypeDetails[DeviceAppErrorType.INVALID_MSG_FROM_DEVICE] + .message, +}; + +const invalidData: IGetPublicKeysTestCase[] = [ + { + name: 'Invalid data', + ...commonParams, + results: [ + { + name: 'error', + data: new Uint8Array([ + 109, 112, 102, 98, 72, 57, 117, 109, 75, 69, 83, 117, 117, 49, 103, + 78, 100, 105, 87, 83, 116, 106, 71, 54, 67, 110, 104, 77, 86, 49, 113, + 97, 78, 111, 50, 98, 118, 52, 67, 113, 72, 122, 120, 85, 98, 53, 86, + 68, 115, 86, 52, 77, 86, 112, 83, 70, 86, 78, 121, 121, 109, 83, 112, + 98, 74, 76, 55, 57, 75, 89, 86, 57, 75, 56, 88, 82, 100, 105, 98, 70, + 109, 118, 54, 116, 86, 54, 116, 50, 122, 52, 100, 87, 110, 111, 110, + 78, 52, 78, 77, 89, 109, + ]), + }, + ], + }, + { + name: 'Invalid data', + ...commonParams, + results: [ + { + name: 'error', + data: new Uint8Array([ + 10, 34, 10, 3, 90, 221, 135, 18, 2, 8, 1, 24, 1, 34, 11, 8, 2, 18, 7, + 8, + ]), + }, + ], + }, + { + name: 'Invalid data', + ...commonParams, + + results: [ + { + name: 'error', + data: new Uint8Array([10]), + }, + ], + }, + { + name: 'Invalid data', + ...commonParams, + results: [ + { + name: 'error', + data: new Uint8Array([]), + }, + ], + }, +]; + +export default invalidData; diff --git a/packages/app-xrp/tests/02.getPublicKeys/__fixtures__/types.ts b/packages/app-xrp/tests/02.getPublicKeys/__fixtures__/types.ts new file mode 100644 index 000000000..162b74819 --- /dev/null +++ b/packages/app-xrp/tests/02.getPublicKeys/__fixtures__/types.ts @@ -0,0 +1,28 @@ +import { IGetPublicKeysParams, IGetPublicKeysResult } from '../../../src'; + +export interface IGetPublicKeysTestCase { + name: string; + params: IGetPublicKeysParams; + queries: { + name: string; + data: Uint8Array; + }[]; + results: { + name: string; + data: Uint8Array; + statuses?: { flowStatus: number; expectEventCalls?: number[] }[]; + }[]; + mocks?: { + eventCalls?: number[][]; + }; + output?: Partial; + errorInstance?: any; + [key: string]: any; +} + +export interface IFixtures { + valid: IGetPublicKeysTestCase[]; + invalidData: IGetPublicKeysTestCase[]; + error: IGetPublicKeysTestCase[]; + invalidArgs: IGetPublicKeysTestCase[]; +} diff --git a/packages/app-xrp/tests/02.getPublicKeys/__fixtures__/valid.ts b/packages/app-xrp/tests/02.getPublicKeys/__fixtures__/valid.ts new file mode 100644 index 000000000..969c9f9f3 --- /dev/null +++ b/packages/app-xrp/tests/02.getPublicKeys/__fixtures__/valid.ts @@ -0,0 +1,192 @@ +import { hexToUint8Array, createFlowStatus } from '@cypherock/sdk-utils'; +import { IGetPublicKeysTestCase } from './types'; +import { Query, Result } from '../../../src/proto/generated/xrp/core'; + +const requestOneAddress: IGetPublicKeysTestCase = { + name: 'Request 1 Address', + params: { + walletId: new Uint8Array([ + 199, 89, 252, 26, 32, 135, 183, 211, 90, 220, 38, 17, 160, 103, 233, 62, + 110, 172, 92, 20, 35, 250, 190, 146, 62, 8, 53, 86, 128, 26, 3, 187, 121, + 64, + ]), + derivationPaths: [ + { + path: [0x80000000 + 44, 0x80000000 + 144, 0x80000000, 0, 0], + }, + ], + }, + queries: [ + { + name: 'Initate query', + data: Uint8Array.from( + Query.encode( + Query.create({ + getPublicKeys: { + initiate: { + walletId: new Uint8Array([ + 199, 89, 252, 26, 32, 135, 183, 211, 90, 220, 38, 17, 160, + 103, 233, 62, 110, 172, 92, 20, 35, 250, 190, 146, 62, 8, 53, + 86, 128, 26, 3, 187, 121, 64, + ]), + derivationPaths: [ + { + path: [0x80000000 + 44, 0x80000000 + 144, 0x80000000, 0, 0], + }, + ], + }, + }, + }), + ).finish(), + ), + }, + ], + results: [ + { + name: 'result', + data: Uint8Array.from( + Result.encode( + Result.create({ + getPublicKeys: { + result: { + publicKeys: [ + hexToUint8Array( + '027497533006d024ffb612a2110eb327ccfeed2b752d787c96ab2d3cca425a40e8', + ), + ], + }, + }, + }), + ).finish(), + ), + statuses: [ + { + flowStatus: createFlowStatus(0, 0), + expectEventCalls: [0], + }, + { + flowStatus: createFlowStatus(1, 0), + expectEventCalls: [1], + }, + { + flowStatus: createFlowStatus(2, 1), + expectEventCalls: [2], + }, + ], + }, + ], + mocks: { eventCalls: [[0], [1], [2], [3], [4]] }, + output: { + publicKeys: [ + '027497533006d024ffb612a2110eb327ccfeed2b752d787c96ab2d3cca425a40e8', + ], + addresses: ['rQGDkQchoJxMSLZR7q9GwvY3iKtDqTUYNQ'], + }, +}; + +const requestMultipleAddress: IGetPublicKeysTestCase = { + name: 'Request 3 Addresses', + params: { + walletId: new Uint8Array([ + 199, 89, 252, 26, 32, 135, 183, 211, 90, 220, 38, 17, 160, 103, 233, 62, + 110, 172, 92, 20, 35, 250, 190, 146, 62, 8, 53, 86, 128, 26, 3, 187, 121, + 64, + ]), + derivationPaths: [ + { + path: [0x80000000 + 44, 0x80000000 + 144, 0x80000000, 0, 0], + }, + { + path: [0x80000000 + 44, 0x80000000 + 144, 0x80000000, 0, 1], + }, + { + path: [0x80000000 + 44, 0x80000000 + 144, 0x80000000, 0, 2], + }, + ], + }, + queries: [ + { + name: 'Initate query', + data: Uint8Array.from( + Query.encode( + Query.create({ + getPublicKeys: { + initiate: { + walletId: new Uint8Array([ + 199, 89, 252, 26, 32, 135, 183, 211, 90, 220, 38, 17, 160, + 103, 233, 62, 110, 172, 92, 20, 35, 250, 190, 146, 62, 8, 53, + 86, 128, 26, 3, 187, 121, 64, + ]), + derivationPaths: [ + { + path: [0x80000000 + 44, 0x80000000 + 144, 0x80000000, 0, 0], + }, + { + path: [0x80000000 + 44, 0x80000000 + 144, 0x80000000, 0, 1], + }, + { + path: [0x80000000 + 44, 0x80000000 + 144, 0x80000000, 0, 2], + }, + ], + }, + }, + }), + ).finish(), + ), + }, + ], + results: [ + { + name: 'result', + data: Uint8Array.from( + Result.encode( + Result.create({ + getPublicKeys: { + result: { + publicKeys: [ + '027497533006d024ffb612a2110eb327ccfeed2b752d787c96ab2d3cca425a40e8', + '02fb3fc84979c18fe238a752c862b0babf376e7547544624b265c57568741bc9b9', + '0339f6c6fbd07700b15d3e9b199bffc21d5b46df1c488348c38941ab89d394a356', + ].map(e => hexToUint8Array(e)), + }, + }, + }), + ).finish(), + ), + statuses: [ + { + flowStatus: createFlowStatus(0, 0), + expectEventCalls: [0], + }, + { + flowStatus: createFlowStatus(1, 0), + expectEventCalls: [1], + }, + { + flowStatus: createFlowStatus(2, 1), + expectEventCalls: [2], + }, + ], + }, + ], + mocks: { eventCalls: [[0], [1], [2], [3], [4]] }, + output: { + publicKeys: [ + '027497533006d024ffb612a2110eb327ccfeed2b752d787c96ab2d3cca425a40e8', + '02fb3fc84979c18fe238a752c862b0babf376e7547544624b265c57568741bc9b9', + '0339f6c6fbd07700b15d3e9b199bffc21d5b46df1c488348c38941ab89d394a356', + ], + addresses: [ + 'rQGDkQchoJxMSLZR7q9GwvY3iKtDqTUYNQ', + 'rEgfV7YeyG4YayQQufxaqDx4aUA93SidLb', + 'rpJwv4oLgQDh3TVaWuQpAP5VQYecwsK8rx', + ], + }, +}; + +const valid: IGetPublicKeysTestCase[] = [ + requestOneAddress, + requestMultipleAddress, +]; + +export default valid; diff --git a/packages/app-xrp/tests/02.getPublicKeys/__helpers__/index.ts b/packages/app-xrp/tests/02.getPublicKeys/__helpers__/index.ts new file mode 100644 index 000000000..874af8682 --- /dev/null +++ b/packages/app-xrp/tests/02.getPublicKeys/__helpers__/index.ts @@ -0,0 +1,14 @@ +import * as superMocks from '../../__helpers__'; +import { IGetPublicKeysTestCase } from '../__fixtures__/types'; + +export function setupMocks(testCase: IGetPublicKeysTestCase) { + return superMocks.setupMocks(testCase); +} + +export function clearMocks() { + superMocks.clearMocks(); +} + +export function expectMockCalls(testCase: IGetPublicKeysTestCase) { + superMocks.expectMockCalls(testCase); +} diff --git a/packages/app-xrp/tests/02.getPublicKeys/index.ts b/packages/app-xrp/tests/02.getPublicKeys/index.ts new file mode 100644 index 000000000..1775f34e5 --- /dev/null +++ b/packages/app-xrp/tests/02.getPublicKeys/index.ts @@ -0,0 +1,104 @@ +import { MockDeviceConnection } from '@cypherock/sdk-interfaces'; +import { afterEach, beforeEach, describe, expect, test } from '@jest/globals'; + +import * as xrpl from 'xrpl'; +import { clearMocks, expectMockCalls, setupMocks } from './__helpers__'; +import fixtures from './__fixtures__'; + +import { setXrpLib, XrpApp } from '../../src'; + +// eslint-disable-next-line @typescript-eslint/no-var-requires + +describe('xrpApp.getPublicKeys', () => { + let connection: MockDeviceConnection; + let xrpApp: XrpApp; + + beforeEach(async () => { + clearMocks(); + + setXrpLib(xrpl); + connection = await MockDeviceConnection.create(); + xrpApp = await XrpApp.create(connection); + }); + + afterEach(async () => { + await xrpApp.destroy(); + }); + + describe('should be able to get public keys', () => { + fixtures.valid.forEach(testCase => { + test(testCase.name, async () => { + const onEvent = setupMocks(testCase); + + const output = await xrpApp.getPublicKeys({ + ...testCase.params, + onEvent, + }); + expect(output).toEqual(testCase.output); + + expectMockCalls(testCase); + }); + }); + }); + + describe('should throw error with invalid arguments', () => { + fixtures.invalidArgs.forEach(testCase => { + test(testCase.name, async () => { + setupMocks(testCase); + + const rejectedPromise = xrpApp.getPublicKeys(testCase.params); + + await expect(rejectedPromise).rejects.toThrow(testCase.errorInstance); + if (testCase.errorMessage) { + try { + await rejectedPromise; + } catch (error: any) { + expect(error.message).toMatch(testCase.errorMessage); + } + } + }); + }); + }); + + describe('should throw error when device returns invalid data', () => { + fixtures.invalidData.forEach(testCase => { + test(testCase.name, async () => { + setupMocks(testCase); + + const rejectedPromise = xrpApp.getPublicKeys(testCase.params); + + await expect(rejectedPromise).rejects.toThrow(testCase.errorInstance); + if (testCase.errorMessage) { + try { + await rejectedPromise; + } catch (error: any) { + expect(error.message).toMatch(testCase.errorMessage); + } + } + + expectMockCalls(testCase); + }); + }); + }); + + describe('should throw error when device returns error', () => { + fixtures.error.forEach(testCase => { + test(testCase.name, async () => { + setupMocks(testCase); + + const rejectedPromise = xrpApp.getPublicKeys(testCase.params); + + await expect(rejectedPromise).rejects.toThrow(testCase.errorInstance); + if (testCase.errorMessage) { + try { + await rejectedPromise; + } catch (error: any) { + expect(error.message).toMatch(testCase.errorMessage); + } + } + + expectMockCalls(testCase); + }); + }); + }); +}); From 05ffa8677ca9cc933fd390ee9d29e85e35cc293c Mon Sep 17 00:00:00 2001 From: Muzaffar Ahmad Bhat Date: Mon, 7 Oct 2024 13:46:04 +0530 Subject: [PATCH 6/6] fix: reverted node/src/index.ts changes --- apps/node/src/index.ts | 46 +++++------------------------------------- 1 file changed, 5 insertions(+), 41 deletions(-) diff --git a/apps/node/src/index.ts b/apps/node/src/index.ts index adac38d06..a66d5ceb0 100644 --- a/apps/node/src/index.ts +++ b/apps/node/src/index.ts @@ -13,8 +13,6 @@ import { setEthersLib } from '@cypherock/sdk-app-evm'; import { setNearApiJs } from '@cypherock/sdk-app-near'; import { setSolanaWeb3 } from '@cypherock/sdk-app-solana'; import { ethers } from 'ethers'; -import { setXrpLib, XrpApp } from '@cypherock/sdk-app-xrp'; -import * as xrpl from 'xrpl'; import { createServiceLogger } from './logger'; const run = async () => { @@ -26,7 +24,6 @@ const run = async () => { setEthersLib(ethers); setNearApiJs(nearApiJs); setSolanaWeb3(solanaWeb3); - setXrpLib(xrpl); let connection: IDeviceConnection; @@ -38,48 +35,15 @@ const run = async () => { const managerApp = await ManagerApp.create(connection); - // const deviceInfo = await managerApp.getDeviceInfo(); + const deviceInfo = await managerApp.getDeviceInfo(); - // console.log(deviceInfo); + console.log(deviceInfo); - const wallets = await managerApp.getWallets(); - const wallet = wallets.walletList[0]; + await managerApp.authDevice(); - console.log({ wallet }); + await managerApp.trainCard({ onWallets: async () => true }); - const xrpApp = await XrpApp.create(connection); - - const resultPubKey = await xrpApp.getPublicKeys({ - walletId: wallet.id, - derivationPaths: [ - { - path: [0x80000000 + 44, 0x80000000 + 144, 0x80000000, 0, 0], - }, - { - path: [0x80000000 + 44, 0x80000000 + 144, 0x80000000, 0, 1], - }, - { - path: [0x80000000 + 44, 0x80000000 + 144, 0x80000000, 0, 2], - }, - ], - }); - - console.log({ resultPubKey }); - - // const resultUserVerifiedPubKey = await xrpApp.getUserVerifiedPublicKey({ - // walletId: wallet.id, - // derivationPath: [0x80000000 + 44, 0x80000000 + 144, 0x80000000, 0, 0] - // }) - - // console.log({ resultUserVerifiedPubKey }); - - await xrpApp.destroy(); - - // await managerApp.authDevice(); - - // await managerApp.trainCard({ onWallets: async () => true }); - - // await managerApp.authCard(); + await managerApp.authCard(); // await managerApp.updateFirmware({ // getDevices: async () => [