Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

adds client interoperability for apis #577

Merged
merged 2 commits into from
Oct 16, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 23 additions & 0 deletions src/__test__/integration/client.interop.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import { fetchActiveWallets, setup } from '../../api';
import { getDeviceId } from '../utils/getters';
import { setupTestClient } from '../utils/helpers';
import { getStoredClient, setStoredClient } from '../utils/setup';

/**
* This test is used to test the interoperability between the Class-based API and the Functional API.
*/
describe.skip('client interop', () => {
it('should setup the Client, then use that client data to', async () => {
const client = setupTestClient();
const isPaired = await client.connect(getDeviceId());
expect(isPaired).toBe(true);

await setup({
getStoredClient,
setStoredClient,
});

const activeWallets = await fetchActiveWallets();
expect(activeWallets).toBeTruthy();
});
});
2 changes: 2 additions & 0 deletions src/__test__/utils/helpers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ import { ProtocolConstants } from '../../protocol';
import { getPathStr } from '../../shared/utilities';
import { TypedTransaction } from '@ethereumjs/tx';
import { getEnv } from './getters';
import { setStoredClient } from './setup';
const SIGHASH_ALL = 0x01;
const secp256k1 = new EC('secp256k1');
const ed25519 = new EdDSA('ed25519');
Expand Down Expand Up @@ -51,6 +52,7 @@ export function setupTestClient(
name: env.APP_NAME || 'SDK Test',
baseUrl: env.baseUrl || 'https://signing.gridpl.us',
timeout: 120000,
setStoredClient,
};

// If the user passes a deviceID in the env, we assume they have previously
Expand Down
52 changes: 30 additions & 22 deletions src/api/setup.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,16 +8,23 @@ import { buildLoadClientFn, buildSaveClientFn, queue } from './utilities';
* @prop {string} SetupParameters.deviceId - the device id of the client
* @prop {string} SetupParameters.password - the password of the client
* @prop {string} SetupParameters.name - the name of the client
* @prop {string} SetupParameters.appSecret - the app secret of the client
* @prop {Function} SetupParameters.getStoredClient - a function that returns the stored client data
* @prop {Function} SetupParameters.setStoredClient - a function that stores the client data
*/
type SetupParameters = {
deviceId: string;
password: string;
name: string;
getStoredClient: () => string;
setStoredClient: (clientData: string | null) => void;
};
type SetupParameters =
| {
deviceId: string;
password: string;
name: string;
appSecret?: string;
getStoredClient: () => string;
setStoredClient: (clientData: string | null) => void;
}
| {
getStoredClient: () => string;
setStoredClient: (clientData: string | null) => void;
};

/**
* `setup` initializes the Client and executes `connect()` if necessary. It returns a promise that
Expand All @@ -28,28 +35,29 @@ type SetupParameters = {
* @param {string} SetupParameters.deviceId - the device id of the client
* @param {string} SetupParameters.password - the password of the client
* @param {string} SetupParameters.name - the name of the client
* @param {string} SetupParameters.appSecret - the app secret of the client
* @param {Function} SetupParameters.getStoredClient - a function that returns the stored client data
* @param {Function} SetupParameters.setStoredClient - a function that stores the client data
* @returns {Promise<boolean>} - a promise that resolves to a boolean that indicates whether the Client is paired to the application to which it's attempting to connect
*
*/
export const setup = async ({
deviceId,
password,
name,
getStoredClient,
setStoredClient,
}: SetupParameters): Promise<boolean> => {
if (!getStoredClient) throw new Error('Client data getter required');
setSaveClient(buildSaveClientFn(setStoredClient));
export const setup = async (params: SetupParameters): Promise<boolean> => {
if (!params.getStoredClient) throw new Error('Client data getter required');
setLoadClient(buildLoadClientFn(params.getStoredClient));

if (!setStoredClient) throw new Error('Client data setter required');
setLoadClient(buildLoadClientFn(getStoredClient));
if (!params.setStoredClient) throw new Error('Client data setter required');
setSaveClient(buildSaveClientFn(params.setStoredClient));

if (deviceId && password && name) {
const privKey = Utils.generateAppSecret(deviceId, password, name);
const client = new Client({ deviceId, privKey, name });
return client.connect(deviceId).then((isPaired) => {
if ('deviceId' in params && 'password' in params && 'name' in params) {
const privKey =
params.appSecret ||
Utils.generateAppSecret(params.deviceId, params.password, params.name);
const client = new Client({
deviceId: params.deviceId,
privKey,
name: params.name,
});
return client.connect(params.deviceId).then((isPaired) => {
saveClient(client.getStateData());
return isPaired;
});
Expand Down
13 changes: 13 additions & 0 deletions src/client.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { buildSaveClientFn } from './api/utilities';
import {
BASE_URL,
DEFAULT_ACTIVE_WALLETS,
Expand Down Expand Up @@ -56,6 +57,8 @@ export class Client {
public activeWallets: ActiveWallets;
/** A wrapper function for handling retries and injecting the {@link Client} class */
private retryWrapper: (fn: any, params?: any) => Promise<any>;
/** Function to set the stored client data */
private setStoredClient: (clientData: string | null) => void;

/**
* @param params - Parameters are passed as an object.
Expand All @@ -69,6 +72,7 @@ export class Client {
retryCount,
skipRetryOnWrongWallet,
deviceId,
setStoredClient,
}: {
/** The base URL of the signing server. */
baseUrl?: string;
Expand All @@ -86,6 +90,8 @@ export class Client {
skipRetryOnWrongWallet?: boolean;
/** The ID of the connected Lattice */
deviceId?: string;
/** Function to set the stored client data */
setStoredClient?: (clientData: string | null) => void;
}) {
this.name = name || 'Unknown';
this.baseUrl = baseUrl || BASE_URL;
Expand All @@ -98,6 +104,9 @@ export class Client {
this.privKey = privKey || randomBytes(32);
this.key = getP256KeyPair(this.privKey);
this.retryWrapper = buildRetryWrapper(this, this.retryCount);
this.setStoredClient = setStoredClient
? buildSaveClientFn(setStoredClient)
: undefined;

/** The user may pass in state data to rehydrate a session that was previously cached */
if (stateData) {
Expand Down Expand Up @@ -343,6 +352,10 @@ export class Client {
if (isPaired !== undefined) this.isPaired = isPaired;
if (fwVersion !== undefined) this.fwVersion = fwVersion;
if (activeWallets !== undefined) this.activeWallets = activeWallets;

if (this.setStoredClient) {
this.setStoredClient(this.getStateData());
}
}

/**
Expand Down
Loading