Skip to content

Commit

Permalink
support skipping step; simplify step params; include details with status
Browse files Browse the repository at this point in the history
  • Loading branch information
sidvishnoi committed Sep 27, 2024
1 parent 17a7112 commit 5bb8d09
Show file tree
Hide file tree
Showing 4 changed files with 73 additions and 30 deletions.
6 changes: 3 additions & 3 deletions src/content/keyAutoAdd/lib/helpers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -46,10 +46,10 @@ export async function waitForURL(
match: (url: URL) => boolean,
{ timeout = 10 * 1000 }: Partial<WaitForURLOptions> = {},
) {
const { resolve, reject, promise } = withResolvers<void>();
const { resolve, reject, promise } = withResolvers<boolean>();

if (match(new URL(window.location.href))) {
resolve();
resolve(true);
return promise;
}

Expand All @@ -68,7 +68,7 @@ export async function waitForURL(
url = window.location.href;
if (match(new URL(url))) {
observer.disconnect();
resolve();
resolve(false);
}
});
observer.observe(document.body, { childList: true, subtree: true });
Expand Down
28 changes: 25 additions & 3 deletions src/content/keyAutoAdd/lib/keyAutoAdd.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@ export type { StepRun } from './types';

export const LOGIN_WAIT_TIMEOUT = 10 * 60 * 1000;

const SYMBOL_SKIP = Symbol.for('skip');

export class KeyAutoAdd {
private port: Runtime.Port;

Expand Down Expand Up @@ -46,6 +48,9 @@ export class KeyAutoAdd {
publicKey,
nickName,
keyId,
skip: (message) => {
throw { type: SYMBOL_SKIP, message };
},
};
let prevStepId = '';
let prevStepResult: unknown = undefined;
Expand All @@ -55,12 +60,24 @@ export class KeyAutoAdd {
try {
prevStepResult = await this.stepsInput
.get(step.id)!
.run(params, prevStepId ? [prevStepResult, prevStepId] : [null, '']);
prevStepId = step.id;
.run(params, prevStepId ? prevStepResult : null);
step.status = 'success';
prevStepId = step.id;
} catch (error) {
step.status = 'error';
if (KeyAutoAdd.isSkip(error)) {
this.steps[stepIdx] = {
...this.steps[stepIdx],
status: 'skipped',
details: { message: error.message },
};
continue;
}
this.postMessage('PROGRESS', { steps: this.steps });
this.steps[stepIdx] = {
...this.steps[stepIdx],
status: 'error',
details: { message: error.message },
};
this.postMessage('ERROR', {
error: { message: error.message },
stepId: step.id,
Expand All @@ -82,4 +99,9 @@ export class KeyAutoAdd {
const message = { action, payload } as ContentToBackgroundMessage;
this.port.postMessage(message);
}

static isSkip(err: unknown): err is { type: symbol; message?: string } {
if (!err || typeof err !== 'object') return false;
return 'type' in err && err.type === SYMBOL_SKIP;
}
}
39 changes: 28 additions & 11 deletions src/content/keyAutoAdd/lib/types.ts
Original file line number Diff line number Diff line change
@@ -1,24 +1,41 @@
export type StepRunParams = BeginPayload;
import { ErrorResponse } from '@/shared/messages';

export interface StepRunParams extends BeginPayload {
skip: (message?: string) => never;
}

export type StepRun<T = unknown, R = void> = (
params: StepRunParams,
prevStep: [
result: T extends (...args: any[]) => PromiseLike<any>
? Awaited<ReturnType<T>>
: T,
id: string,
],
) => Promise<R>;
prevStepResult: T extends (...args: any[]) => PromiseLike<any>
? Exclude<Awaited<ReturnType<T>>, void | { type: symbol }>
: T,
) => Promise<R | void>;

export interface Step<T = unknown, R = unknown> {
id: string;
run: StepRun<T, R>;
}

export interface StepWithStatus {
id: Step['id'];
status: 'pending' | 'active' | 'error' | 'success' | 'skipped';
interface StepWithStatusBase {
id: string;
status: string;
}
interface StepWithStatusNormal extends StepWithStatusBase {
status: 'pending' | 'active' | 'success';
}
interface StepWithStatusSkipped extends StepWithStatusBase {
status: 'skipped';
details: { message?: string };
}
interface StepWithStatusError extends StepWithStatusBase {
status: 'error';
details: Omit<ErrorResponse, 'success'>;
}

export type StepWithStatus =
| StepWithStatusNormal
| StepWithStatusSkipped
| StepWithStatusError;

export interface BeginPayload {
walletAddressUrl: string;
Expand Down
30 changes: 17 additions & 13 deletions src/content/keyAutoAdd/testWallet.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,14 +26,18 @@ type AccountDetails = {
};
};

const waitForLogin: Step<never> = async () => {
const waitForLogin: Step<never> = async ({ skip }) => {
const expectedUrl = 'https://rafiki.money/settings/developer-keys';
try {
await waitForURL(
const foundOnLoad = await waitForURL(
(url) => (url.origin + url.pathname).startsWith(expectedUrl),
{ timeout: LOGIN_WAIT_TIMEOUT },
);
if (foundOnLoad) {
skip('No existing keys that need to be revoked');
}
} catch (error) {
if (KeyAutoAdd.isSkip(error)) throw error;
if (isTimedOut(error)) {
throw new Error('Timed out waiting for login');
}
Expand Down Expand Up @@ -63,7 +67,7 @@ const findBuildId: Step<never, { buildId: string }> = async () => {

const getAccountDetails: Step<typeof findBuildId, Account[]> = async (
_,
[{ buildId }],
{ buildId },
) => {
const url = `https://rafiki.money/_next/data/${buildId}/settings/developer-keys.json`;
const res = await fetch(url, {
Expand All @@ -85,27 +89,27 @@ const getAccountDetails: Step<typeof findBuildId, Account[]> = async (
* there first.
*/
const revokeExistingKey: Step<typeof getAccountDetails, Account[]> = async (
{ keyId },
[accounts],
{ keyId, skip },
accounts,
) => {
outer: for (const account of accounts) {
for (const account of accounts) {
for (const wallet of account.walletAddresses) {
for (const key of wallet.keys) {
if (key.id !== keyId) continue;

await revokeKey(account.id, wallet.id, key.id);
break outer;
if (key.id === keyId) {
await revokeKey(account.id, wallet.id, key.id);
return accounts;
}
}
}
}

return accounts;
skip('No existing keys that need to be revoked');
};

const findAccountAndWalletId: Step<
typeof revokeExistingKey,
{ accountId: string; walletId: string }
> = async ({ walletAddressUrl }, [accounts]) => {
> = async ({ walletAddressUrl }, accounts) => {
for (const account of accounts) {
for (const wallet of account.walletAddresses) {
if (toWalletAddressUrl(wallet.url) === walletAddressUrl) {
Expand All @@ -118,7 +122,7 @@ const findAccountAndWalletId: Step<

const addKey: Step<typeof findAccountAndWalletId> = async (
{ publicKey, nickName },
[{ accountId, walletId }],
{ accountId, walletId },
) => {
const url = `https://api.rafiki.money/accounts/${accountId}/wallet-addresses/${walletId}/upload-key`;
const res = await fetch(url, {
Expand Down

0 comments on commit 5bb8d09

Please sign in to comment.