Skip to content

Commit

Permalink
chore: miscellaneous bitgo fixes (#32)
Browse files Browse the repository at this point in the history
  • Loading branch information
shane-t authored Jan 29, 2025
1 parent 8a832c1 commit 848e29a
Show file tree
Hide file tree
Showing 9 changed files with 93 additions and 24 deletions.
18 changes: 18 additions & 0 deletions packages/site/src/pages/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -176,6 +176,24 @@ const Index = () => {
successMessage: 'Import successful',
},

{
name: 'Inject local neptune token',
description: 'Onboard to the local neptune test custodian',
inputs: [],
action: {
callback: async () =>
await injectToken(
'http://localhost:3009/eth',
'http://localhost:3009/oauth/token',
'ECA3',
'Local Neptune',
'neptune-custody-local',
),
label: 'Inject Token',
},
successMessage: 'Import successful',
},

{
name: 'Inject saturn token',
description: 'Onboard to the saturn test custodian',
Expand Down
12 changes: 4 additions & 8 deletions packages/snap/snap.manifest.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
"url": "git+https://github.com/MetaMask/snap-institutional-wallet.git"
},
"source": {
"shasum": "qWerYQO9695mT8ZP4dNczRjKRlpt0X53mPQLD9ZBPGA=",
"shasum": "pomruhv6RwxOuvgkai62VjvcYH/WMNea7C1yPz+jxAQ=",
"location": {
"npm": {
"filePath": "dist/bundle.js",
Expand Down Expand Up @@ -40,19 +40,15 @@
"endowment:keyring": {
"allowedOrigins": [
"localhost:8000",
"http://localhost:8000",
"https://neptune-custody-ui.metamask-institutional.io",
"https://saturn-custody-ui.metamask-institutional.io",
"https://ui-v2.sit.zodia.io",
"https://ui-v2.qa.zodia.io",
"https://ui-preprod-v2.qa.zodia.io",
"https://v2.custody.zodia.io"
"http://localhost:8000"
]
},
"endowment:rpc": {
"allowedOrigins": [
"localhost:8000",
"http://localhost:8000",
"localhost:3000",
"https://localhost:3000",
"https://neptune-custody-ui.metamask-institutional.io",
"https://zodia.io",
"https://ui-v2.sit.zodia.io",
Expand Down
15 changes: 15 additions & 0 deletions packages/snap/src/features/info-message/rendex.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
/**
* Renders the onboarding interface.
*
* @param infoMessage - The info message to display.
* @returns The result of the dialog.
*/
export async function renderInfoMessage(infoMessage: string) {
await snap.request({
method: 'snap_notify',
params: {
type: 'inApp',
message: infoMessage,
},
});
}
18 changes: 13 additions & 5 deletions packages/snap/src/keyring.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import { type Json } from '@metamask/utils';
import { v4 as uuid } from 'uuid';

import config from './config';
import { renderInfoMessage } from './features/info-message/rendex';
import { TOKEN_EXPIRED_EVENT } from './lib/custodian-types/constants';
import { custodianMetadata } from './lib/custodian-types/custodianMetadata';
import { SignedMessageHelper } from './lib/helpers/signedmessage';
Expand Down Expand Up @@ -93,13 +94,23 @@ export class CustodialKeyring implements Keyring {
throw new Error(`Account address already in use: ${address}`);
}

// Some custodians (mostly ECA-1) still publish transactions
// If the custodian publishes transactions, we defer publication
// i.e. the client does not publish the transaction, it waits for the custodian to do it

let deferPublication = false; // ECA-3 default

if (custodian?.custodianPublishesTransaction) {
deferPublication = true;
}

try {
const account: CustodialKeyringAccount = {
id: uuid(),
options: {
custodian: {
displayName: options.details.custodianDisplayName,
deferPublication: custodian?.custodianPublishesTransaction ?? true,
deferPublication,
},
accountName: name,
},
Expand Down Expand Up @@ -310,12 +321,9 @@ export class CustodialKeyring implements Keyring {
console.error('Error getting deep link', error);
}

await renderInfoMessage(`${deepLink.text} Transaction ID: ${deepLink.id}`);
return {
pending: true,
redirect: {
message: deepLink.text,
url: deepLink.url,
},
};
}

Expand Down
2 changes: 2 additions & 0 deletions packages/snap/src/lib/custodian-types/constants.ts
Original file line number Diff line number Diff line change
@@ -1,2 +1,4 @@
export const REFRESH_TOKEN_CHANGE_EVENT = 'refresh_token_change';
export const TOKEN_EXPIRED_EVENT = 'token_expired';
export const MAX_TRANSACTION_AGE = 1000 * 60 * 60 * 1; // 1 hour
export const MAX_SIGNED_MESSAGE_AGE = 1000 * 60 * 60 * 1; // 1 hour
15 changes: 6 additions & 9 deletions packages/snap/src/lib/custodian-types/custodianMetadata.ts
Original file line number Diff line number Diff line change
Expand Up @@ -309,21 +309,18 @@ export const custodianMetadata: CustodianMetadata[] = [
allowedOnboardingDomains: [], // Cubist does not support onboarding via a web page
},
{
refreshTokenUrl:
'https://neptune-custody.dev.metamask-institutional.io/oauth/token',
name: 'neptune-custody-dev',
displayName: 'Neptune Custody Dev',
refreshTokenUrl: 'http://localhost:3009/oauth/token',
name: 'neptune-custody-local',
displayName: 'Neptune Custody Local',
enabled: true,
apiBaseUrl: 'https://neptune-custody.dev.metamask-institutional.io/eth',
apiBaseUrl: 'http://localhost:3009/eth',
apiVersion: CustodianType.ECA3,
custodianPublishesTransaction: false,
iconUrl:
'https://dev.metamask-institutional.io/custodian-icons/neptune-icon.svg',
isManualTokenInputSupported: false,
onboardingUrl: 'https://neptune-custody-ui.dev.metamask-institutional.io',
allowedOnboardingDomains: [
'neptune-custody-ui.dev.metamask-institutional.io',
],
onboardingUrl: 'http://localhost:3005',
allowedOnboardingDomains: ['localhost:3005'],
},
{
refreshTokenUrl: 'http://localhost:3330/oauth/token',
Expand Down
5 changes: 3 additions & 2 deletions packages/snap/src/lib/structs/CustodialKeyringStructs.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,9 @@ export const TransactionStatus = object({
finished: boolean(),
success: boolean(),
displayText: string(),
reason: optional(string()),
reason: optional(nullable(string())),
submitted: boolean(),
signed: boolean(),
});

export type TransactionStatus = Infer<typeof TransactionStatus>;
Expand Down Expand Up @@ -66,7 +67,7 @@ export const SignedMessageStatus = object({
signed: boolean(),
success: boolean(),
displayText: string(),
reason: optional(string()),
reason: optional(nullable(string())),
});

export type SignedMessageStatus = Infer<typeof SignedMessageStatus>;
Expand Down
1 change: 1 addition & 0 deletions packages/snap/src/requestsManager.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ describe('RequestManager', () => {
success: false,
displayText: '',
submitted: false,
signed: false,
},
custodianTransactionId: 'mock-id',
custodianPublishesTransaction: false,
Expand Down
31 changes: 31 additions & 0 deletions packages/snap/src/requestsManager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,10 @@ import type { Json } from '@metamask/snaps-sdk';
import { assert } from '@metamask/superstruct';

import { renderErrorMessage } from './features/error-message/render';
import {
MAX_TRANSACTION_AGE,
MAX_SIGNED_MESSAGE_AGE,
} from './lib/custodian-types/constants';
import { TransactionHelper } from './lib/helpers/transaction';
import {
type SignedMessageRequest,
Expand Down Expand Up @@ -132,6 +136,18 @@ export class RequestManager {

const { custodianTransactionId } = request.transaction;

// Check if lastUpdates is older than MAX_TRANSACTION_AGE
if (request.lastUpdated < Date.now() - MAX_TRANSACTION_AGE) {
logger.info(
`Transaction ${custodianTransactionId} last updated more than ${MAX_TRANSACTION_AGE}ms (last updated ${
Date.now() - request.lastUpdated
}ms ago), removing request`,
);
await this.emitRejectedEvent(requestId);
await this.#stateManager.removeRequest(requestId);
return;
}

const transactionResponse = await custodianApi.getTransaction(
address,
custodianTransactionId,
Expand Down Expand Up @@ -202,6 +218,7 @@ export class RequestManager {
transactionResponse.transactionStatus.displayText ?? '',
submitted: transactionResponse.transactionStatus.submitted ?? false,
reason: transactionResponse.transactionStatus.reason ?? '',
signed: transactionResponse.transactionStatus.signed ?? false,
},
...(transactionResponse.gasPrice && {
gasPrice: transactionResponse.gasPrice,
Expand Down Expand Up @@ -250,6 +267,20 @@ export class RequestManager {
address,
);

// Check if lastUpdates is older than MAX_TRANSACTION_AGE
if (request.lastUpdated < Date.now() - MAX_SIGNED_MESSAGE_AGE) {
logger.info(
`Signed Message ${
request.message.id
} last updated more than ${MAX_SIGNED_MESSAGE_AGE}ms (last updated ${
Date.now() - request.lastUpdated
}ms ago), removing request`,
);
await this.emitRejectedEvent(requestId);
await this.#stateManager.removeRequest(requestId);
return;
}

const signedMessageResponse = await custodianApi.getSignedMessage(
address,
request.message.id,
Expand Down

0 comments on commit 848e29a

Please sign in to comment.