Skip to content

chore: clean-up Multichain API errors #6109

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

Open
wants to merge 5 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 4 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
6 changes: 6 additions & 0 deletions packages/chain-agnostic-permission/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,14 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

## [Unreleased]

### Added

- Add `unknownErrorOrNoScopesAuthorized` and `invalidSessionPropertiesError` to `Caip25Errors` ([#6109](https://github.com/MetaMask/core/pull/6109))

### Changed

- Update `requestedChainsNotSupportedError` message from "Requested chains are not supported" to "Requested networks are not supported" ([#6109](https://github.com/MetaMask/core/pull/6109))

- Bump `@metamask/controller-utils` from `^11.10.0` to `^11.11.0` ([#6069](https://github.com/MetaMask/core/pull/6069))
- Bump `@metamask/utils` from `^11.2.0` to `^11.4.2` ([#6054](https://github.com/MetaMask/core/pull/6054))

Expand Down
16 changes: 15 additions & 1 deletion packages/chain-agnostic-permission/src/scope/errors.test.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,16 @@
import { Caip25Errors } from './errors';

describe('Caip25Errors', () => {
it('unknownErrorOrNoScopesAuthorized', () => {
expect(Caip25Errors.unknownErrorOrNoScopesAuthorized().message).toBe(
'Unknown error with request',
);
expect(Caip25Errors.unknownErrorOrNoScopesAuthorized().code).toBe(5000);
});

it('requestedChainsNotSupportedError', () => {
expect(Caip25Errors.requestedChainsNotSupportedError().message).toBe(
'Requested chains are not supported',
'Requested networks are not supported',
);
expect(Caip25Errors.requestedChainsNotSupportedError().code).toBe(5100);
});
Expand Down Expand Up @@ -37,4 +44,11 @@ describe('Caip25Errors', () => {
);
expect(Caip25Errors.unknownNotificationsRequestedError().code).toBe(5202);
});

it('invalidSessionPropertiesError', () => {
expect(Caip25Errors.invalidSessionPropertiesError().message).toBe(
'Invalid sessionProperties requested',
);
expect(Caip25Errors.invalidSessionPropertiesError().code).toBe(5302);
});
});
19 changes: 18 additions & 1 deletion packages/chain-agnostic-permission/src/scope/errors.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,22 @@ import { JsonRpcError } from '@metamask/rpc-errors';
* CAIP25 Errors.
*/
export const Caip25Errors = {
/**
* Thrown when an unknown error occurs or no scopes were authorized in a CAIP-25 request.
*
* @returns A new JsonRpcError instance.
*/
unknownErrorOrNoScopesAuthorized: () =>
new JsonRpcError(5000, 'Unknown error with request'),

/**
* Thrown when chains requested in a CAIP-25 `wallet_createSession` call are not supported by the wallet.
* Defined in [CAIP-25 error codes section](https://github.com/ChainAgnostic/CAIPs/blob/main/CAIPs/caip-25.md#trusted-failure-codes).
*
* @returns A new JsonRpcError instance.
*/
requestedChainsNotSupportedError: () =>
new JsonRpcError(5100, 'Requested chains are not supported'),
new JsonRpcError(5100, 'Requested networks are not supported'),

/**
* Thrown when methods requested in a CAIP-25 `wallet_createSession` call are not supported by the wallet.
Expand Down Expand Up @@ -50,4 +58,13 @@ export const Caip25Errors = {
*/
unknownNotificationsRequestedError: () =>
new JsonRpcError(5202, 'Unknown notification(s) requested'),

/**
* Thrown when sessionProperties requested in a CAIP-25 `wallet_createSession` call are not supported by the wallet.
* Defined in [CAIP-25 error codes section](https://github.com/ChainAgnostic/CAIPs/blob/main/CAIPs/caip-25.md#trust-agnostic-malformed-request-failure-codes)
*
* @returns A new JsonRpcError instance.
*/
invalidSessionPropertiesError: () =>
new JsonRpcError(5302, 'Invalid sessionProperties requested'),
};
1 change: 1 addition & 0 deletions packages/multichain-api-middleware/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

### Changed

- Update `wallet_createSession` and `wallet_revokeSession` handlers to use `Caip25Errors` instead of creating `JsonRpcError` directly ([#6109](https://github.com/MetaMask/core/pull/6109))
- Bump `@metamask/controller-utils` from `^11.10.0` to `^11.11.0` ([#6069](https://github.com/MetaMask/core/pull/6069))
- Bump `@metamask/utils` from `^11.2.0` to `^11.4.2` ([#6054](https://github.com/MetaMask/core/pull/6054))

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,12 @@ import {
type Caip25Authorization,
type NormalizedScopesObject,
KnownSessionProperties,
Caip25Errors,
} from '@metamask/chain-agnostic-permission';
import * as ChainAgnosticPermission from '@metamask/chain-agnostic-permission';
import { MultichainNetwork } from '@metamask/multichain-transactions-controller';
import { invalidParams } from '@metamask/permission-controller';
import { JsonRpcError, rpcErrors } from '@metamask/rpc-errors';

import type {
Hex,
Json,
Expand All @@ -18,14 +19,6 @@ import type {

import { walletCreateSession } from './wallet-createSession';

jest.mock('@metamask/rpc-errors', () => ({
...jest.requireActual('@metamask/rpc-errors'),
rpcErrors: {
invalidParams: jest.fn(),
internal: jest.fn(),
},
}));

jest.mock('@metamask/chain-agnostic-permission', () => ({
...jest.requireActual('@metamask/chain-agnostic-permission'),
validateAndNormalizeScopes: jest.fn(),
Expand Down Expand Up @@ -179,7 +172,7 @@ describe('wallet_createSession', () => {
},
});
expect(end).toHaveBeenCalledWith(
new JsonRpcError(5302, 'Invalid sessionProperties requested'),
Caip25Errors.invalidSessionPropertiesError(),
);
});

Expand Down Expand Up @@ -567,7 +560,7 @@ describe('wallet_createSession', () => {
});
await handler(baseRequest);
expect(end).toHaveBeenCalledWith(
new JsonRpcError(5100, 'Requested scopes are not supported'),
Caip25Errors.requestedChainsNotSupportedError(),
);
});

Expand Down Expand Up @@ -888,7 +881,7 @@ describe('wallet_createSession', () => {
});
});

it('calls internal RPC error if approved CAIP-25 permission has no CAIP-25 caveat value', async () => {
it('throws error if approved CAIP-25 permission has no CAIP-25 caveat value', async () => {
const { handler, requestPermissionsForOrigin } = createMockedHandler();
requestPermissionsForOrigin.mockReturnValue([
{
Expand All @@ -903,14 +896,14 @@ describe('wallet_createSession', () => {
},
]);

await handler({
...baseRequest,
params: {
...baseRequest.params,
},
});

expect(rpcErrors.internal).toHaveBeenCalled();
await expect(
handler({
...baseRequest,
params: {
...baseRequest.params,
},
}),
).rejects.toThrow(Caip25Errors.unknownErrorOrNoScopesAuthorized());
});

describe('address case sensitivity', () => {
Expand Down Expand Up @@ -1290,7 +1283,7 @@ describe('wallet_createSession', () => {
await handler(requestWithNoValidScopes);

expect(end).toHaveBeenCalledWith(
new JsonRpcError(5100, 'Requested scopes are not supported'),
Caip25Errors.requestedChainsNotSupportedError(),
);
});
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import {
getAllScopesFromScopesObjects,
setNonSCACaipAccountIdsInCaip25CaveatValue,
isNamespaceInScopesObject,
Caip25Errors,
} from '@metamask/chain-agnostic-permission';
import { isEqualCaseInsensitive } from '@metamask/controller-utils';
import type {
Expand All @@ -25,7 +26,6 @@ import {
invalidParams,
type RequestedPermissions,
} from '@metamask/permission-controller';
import { JsonRpcError, rpcErrors } from '@metamask/rpc-errors';
import {
type CaipAccountId,
type CaipChainId,
Expand Down Expand Up @@ -96,7 +96,7 @@ async function walletCreateSessionHandler(
const { requiredScopes, optionalScopes, sessionProperties } = req.params;

if (sessionProperties && Object.keys(sessionProperties).length === 0) {
return end(new JsonRpcError(5302, 'Invalid sessionProperties requested'));
return end(Caip25Errors.invalidSessionPropertiesError());
}

const filteredSessionProperties = Object.fromEntries(
Expand Down Expand Up @@ -228,9 +228,7 @@ async function walletCreateSessionHandler(
};
} else {
// if solana is not requested and there are no supported scopes, we return an error
return end(
new JsonRpcError(5100, 'Requested scopes are not supported'),
);
return end(Caip25Errors.requestedChainsNotSupportedError());
}
}

Expand All @@ -256,7 +254,7 @@ async function walletCreateSessionHandler(
(caveat) => caveat.type === Caip25CaveatType,
)?.value as Caip25CaveatValue;
if (!approvedCaip25CaveatValue) {
throw rpcErrors.internal();
throw Caip25Errors.unknownErrorOrNoScopesAuthorized();
}

const sessionScopes = getSessionScopes(approvedCaip25CaveatValue, {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
import { Caip25EndowmentPermissionName } from '@metamask/chain-agnostic-permission';
import {
Caip25EndowmentPermissionName,
Caip25Errors,
} from '@metamask/chain-agnostic-permission';
import {
PermissionDoesNotExistError,
UnrecognizedSubjectError,
} from '@metamask/permission-controller';
import { rpcErrors } from '@metamask/rpc-errors';
import type { JsonRpcRequest } from '@metamask/utils';

import { walletRevokeSession } from './wallet-revokeSession';
Expand Down Expand Up @@ -81,7 +83,9 @@ describe('wallet_revokeSession', () => {
});

await handler(baseRequest);
expect(end).toHaveBeenCalledWith(rpcErrors.internal());
expect(end).toHaveBeenCalledWith(
Caip25Errors.unknownErrorOrNoScopesAuthorized(),
);
});

it('returns true if the permission was revoked', async () => {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
import { Caip25EndowmentPermissionName } from '@metamask/chain-agnostic-permission';
import {
Caip25EndowmentPermissionName,
Caip25Errors,
} from '@metamask/chain-agnostic-permission';
import type {
JsonRpcEngineNextCallback,
JsonRpcEngineEndCallback,
Expand All @@ -7,7 +10,6 @@ import {
PermissionDoesNotExistError,
UnrecognizedSubjectError,
} from '@metamask/permission-controller';
import { rpcErrors } from '@metamask/rpc-errors';
import type { JsonRpcSuccess, JsonRpcRequest } from '@metamask/utils';

/**
Expand Down Expand Up @@ -42,7 +44,7 @@ async function walletRevokeSessionHandler(
!(err instanceof PermissionDoesNotExistError)
) {
console.error(err);
return end(rpcErrors.internal());
return end(Caip25Errors.unknownErrorOrNoScopesAuthorized());
}
}

Expand Down
Loading