Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
- Notifications
You must be signed in to change notification settings - Fork 300
feat: Add Multichain API to @metamask/multichain#4813
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
Uh oh!
There was an error while loading. Please reload this page.
Changes from all commits
bc56104a4b52ad86ab58a186d4b36a93d1d231bcaa4e52fc0151eaac85a723ea0bb2781cd8ef2c636defa6aa7c142134f7a13b9c781db877a3fc263afe5cb99ea78be5650d31df5167e9446b0bf65ca24941849da250de2aa7ba398415be6c7f510e4afa8f8597e8371872188c5d800554f7c49ada451d2322e399b2167700a41cbf30dd8b71085a0f2be8f0644f4d01b78bbcfc28c89ba25ce54ceb118a36ec4d95dfbc99bcf869633485c609518aafb2e2c7c97afeba210ac109a7bf1e6764132b213adae4f73b673f62d7ed999b4b65e24d752b7fad338d5bf15a28208931c5980c6106e9865c6bb8fa7a8e6e0962fb254829e06b367f042297f9dc3170456176d126acfcd2e3bfb489d6101b7ea5d57203358046133aeea9f46257618a67b222eead2f43009fb4ae34032b0631c48468554718d11121ba77c7bb50a197d32a0bf09537062929a4491552fbd0f50f41dcc83d80c9ce6eb3e878374f37d6dfc710d167a317af39562975b619a5983439ef9b7d61af6b5d0cd797b4a096732cd9e03033ce1793ff4c9be0ea25c05db35bdc32ad05a379acd2632aa807121ba946d4bd043f4c2975a621b3aef155f944be535f98801b79f827242629d57e6ab50007fa51ec950302144d178737cbf8ca898e8b24879cfbf21ca2b343507093e5f9656740b77572a983d24542942b6765a4e6a3346c0637f0d8d90cec102e373d68f83d997b82a3e9d8f7f11b8aa551ba26f61047f94c4f6d1aad26da3fb044a7ae5dc54714f840d27d8874ebcc344d3dff57ba3dc0283eb439461e77e87f5a2c8a03f65e221399f970fd56cebf4e1365c79a547c4aa654ad37a9c76040043d1dcd61c654ac1dd11f2c085fef550ee40353672fa5b27fcf554f8298fc54d07f372b0b350f1c0cc4407d969ce3def86e05b7d310158bdf371565b57d7066244b7b93683d11a87b4d96f372c8f02d61da7aed70cc5cc620588efe595d48a32a95b36449e98fff35178f777524f17e013ad6558c34b817d16401cc369d63cb0fe7718b5534776860d1842286700c42af0d8c7237eb59ab3ce472ba45577b09a5cac1abefee79d3e310120eFile filter
Filter by extension
Conversations
Uh oh!
There was an error while loading. Please reload this page.
Jump to
Uh oh!
There was an error while loading. Please reload this page.
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,135 @@ | ||
| import { | ||
| KnownNotifications, | ||
| KnownRpcMethods, | ||
| KnownWalletNamespaceRpcMethods, | ||
| KnownWalletRpcMethods, | ||
| } from '../scope/constants'; | ||
| import { | ||
| getInternalScopesObject, | ||
| getSessionScopes, | ||
| } from './caip-permission-adapter-session-scopes'; | ||
| describe('CAIP-25 session scopes adapters', () => { | ||
| describe('getInternalScopesObject', () => { | ||
| it('returns an InternalScopesObject with only the accounts from each NormalizedScopeObject', () => { | ||
| const result = getInternalScopesObject({ | ||
| 'wallet:eip155': { | ||
| methods: ['foo', 'bar'], | ||
| notifications: ['baz'], | ||
| accounts: ['wallet:eip155:0xdead'], | ||
| }, | ||
| 'eip155:1': { | ||
| methods: ['eth_call'], | ||
| notifications: ['eth_subscription'], | ||
| accounts: ['eip155:1:0xdead', 'eip155:1:0xbeef'], | ||
| }, | ||
| }); | ||
| expect(result).toStrictEqual({ | ||
| 'wallet:eip155': { | ||
| accounts: ['wallet:eip155:0xdead'], | ||
| }, | ||
| 'eip155:1': { | ||
| accounts: ['eip155:1:0xdead', 'eip155:1:0xbeef'], | ||
| }, | ||
| }); | ||
| }); | ||
| }); | ||
| describe('getSessionScopes', () => { | ||
| it('returns a NormalizedScopesObject for the wallet scope', () => { | ||
| const result = getSessionScopes({ | ||
| requiredScopes: {}, | ||
| optionalScopes: { | ||
| wallet: { | ||
| accounts: [], | ||
| }, | ||
| }, | ||
| }); | ||
| expect(result).toStrictEqual({ | ||
| wallet: { | ||
| methods: KnownWalletRpcMethods, | ||
| notifications: [], | ||
| accounts: [], | ||
| }, | ||
| }); | ||
| }); | ||
| it('returns a NormalizedScopesObject for the wallet:eip155 scope', () => { | ||
| const result = getSessionScopes({ | ||
| requiredScopes: {}, | ||
| optionalScopes: { | ||
| 'wallet:eip155': { | ||
| accounts: ['wallet:eip155:0xdeadbeef'], | ||
| }, | ||
| }, | ||
| }); | ||
| expect(result).toStrictEqual({ | ||
| 'wallet:eip155': { | ||
| methods: KnownWalletNamespaceRpcMethods.eip155, | ||
| notifications: [], | ||
| accounts: ['wallet:eip155:0xdeadbeef'], | ||
| }, | ||
| }); | ||
| }); | ||
| it('returns a NormalizedScopesObject with empty methods and notifications for scope with wallet namespace and unknown reference', () => { | ||
| const result = getSessionScopes({ | ||
| requiredScopes: {}, | ||
| optionalScopes: { | ||
| 'wallet:foobar': { | ||
| accounts: ['wallet:foobar:0xdeadbeef'], | ||
| }, | ||
| }, | ||
| }); | ||
| expect(result).toStrictEqual({ | ||
| 'wallet:foobar': { | ||
| methods: [], | ||
| notifications: [], | ||
| accounts: ['wallet:foobar:0xdeadbeef'], | ||
| }, | ||
| }); | ||
| }); | ||
| it('returns a NormalizedScopesObject with empty methods and notifications for scope not wallet namespace and unknown reference', () => { | ||
| const result = getSessionScopes({ | ||
| requiredScopes: {}, | ||
| optionalScopes: { | ||
| 'foo:1': { | ||
| accounts: ['foo:1:0xdeadbeef'], | ||
| }, | ||
| }, | ||
| }); | ||
| expect(result).toStrictEqual({ | ||
| 'foo:1': { | ||
| methods: [], | ||
| notifications: [], | ||
| accounts: ['foo:1:0xdeadbeef'], | ||
| }, | ||
| }); | ||
| }); | ||
| it('returns a NormalizedScopesObject for a eip155 namespaced scope', () => { | ||
| const result = getSessionScopes({ | ||
| requiredScopes: {}, | ||
| optionalScopes: { | ||
| 'eip155:1': { | ||
| accounts: ['eip155:1:0xdeadbeef'], | ||
| }, | ||
| }, | ||
| }); | ||
| expect(result).toStrictEqual({ | ||
| 'eip155:1': { | ||
| methods: KnownRpcMethods.eip155, | ||
| notifications: KnownNotifications.eip155, | ||
| accounts: ['eip155:1:0xdeadbeef'], | ||
| }, | ||
| }); | ||
| }); | ||
| }); | ||
| }); |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,101 @@ | ||
| import { KnownCaipNamespace } from '@metamask/utils'; | ||
| import type { Caip25CaveatValue } from '../caip25Permission'; | ||
| import { | ||
| KnownNotifications, | ||
| KnownRpcMethods, | ||
| KnownWalletNamespaceRpcMethods, | ||
| KnownWalletRpcMethods, | ||
| } from '../scope/constants'; | ||
| import { mergeScopes } from '../scope/transform'; | ||
| import type { | ||
| InternalScopesObject, | ||
| NonWalletKnownCaipNamespace, | ||
| NormalizedScopesObject, | ||
| } from '../scope/types'; | ||
| import { parseScopeString } from '../scope/types'; | ||
| /** | ||
| * Converts an NormalizedScopesObject to a InternalScopesObject. | ||
| * @param normalizedScopesObject - The NormalizedScopesObject to convert. | ||
| * @returns An InternalScopesObject. | ||
| */ | ||
| export const getInternalScopesObject = ( | ||
| normalizedScopesObject: NormalizedScopesObject, | ||
| ) => { | ||
| const internalScopes: InternalScopesObject = {}; | ||
| Object.entries(normalizedScopesObject).forEach( | ||
| ([_scopeString, { accounts }]) => { | ||
| const scopeString = _scopeString as keyof typeof normalizedScopesObject; | ||
| internalScopes[scopeString] = { | ||
| accounts, | ||
Member There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Wait, so we are throwing away all of the methods etc? What is the plan then if we want to do more granular permissioning down the line, then we will require another potentially tricky migration? Contributor There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. So we originally were including the methods in the serialized permission itself (and granularly enforcing each metho), but after discussions w/ @Gudahtt we realized that approach would
| ||
| }; | ||
| }, | ||
| ); | ||
| return internalScopes; | ||
| }; | ||
| /** | ||
| * Converts an InternalScopesObject to a NormalizedScopesObject. | ||
| * @param internalScopesObject - The InternalScopesObject to convert. | ||
| * @returns A NormalizedScopesObject. | ||
| */ | ||
| const getNormalizedScopesObject = ( | ||
| internalScopesObject: InternalScopesObject, | ||
| ) => { | ||
| const normalizedScopes: NormalizedScopesObject = {}; | ||
| Object.entries(internalScopesObject).forEach( | ||
| ([_scopeString, { accounts }]) => { | ||
| const scopeString = _scopeString as keyof typeof internalScopesObject; | ||
| const { namespace, reference } = parseScopeString(scopeString); | ||
| let methods: string[] = []; | ||
| let notifications: string[] = []; | ||
| if (namespace === KnownCaipNamespace.Wallet) { | ||
| if (reference) { | ||
| methods = | ||
| KnownWalletNamespaceRpcMethods[ | ||
| reference as NonWalletKnownCaipNamespace | ||
| ] ?? []; | ||
| } else { | ||
| methods = KnownWalletRpcMethods; | ||
| } | ||
| } else { | ||
| methods = | ||
| KnownRpcMethods[namespace as NonWalletKnownCaipNamespace] ?? []; | ||
Member There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Seems incompatible with non-EVM as well? 🤔 Contributor There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. see #4813 (comment) | ||
| notifications = | ||
| KnownNotifications[namespace as NonWalletKnownCaipNamespace] ?? []; | ||
| } | ||
| normalizedScopes[scopeString] = { | ||
| methods, | ||
| notifications, | ||
| accounts, | ||
| }; | ||
| }, | ||
| ); | ||
| return normalizedScopes; | ||
| }; | ||
| /** | ||
| * Takes the scopes from an endowment:caip25 permission caveat value, | ||
| * hydrates them with supported methods and notifications, and returns a NormalizedScopesObject. | ||
| * @param caip25CaveatValue - The CAIP-25 CaveatValue to convert. | ||
| * @returns A NormalizedScopesObject. | ||
| */ | ||
| export const getSessionScopes = ( | ||
| caip25CaveatValue: Pick< | ||
| Caip25CaveatValue, | ||
| 'requiredScopes' | 'optionalScopes' | ||
| >, | ||
| ) => { | ||
| return mergeScopes( | ||
| getNormalizedScopesObject(caip25CaveatValue.requiredScopes), | ||
| getNormalizedScopesObject(caip25CaveatValue.optionalScopes), | ||
| ); | ||
| }; | ||
Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this is one of the few times I've seen the chain ID converted to a bigint instead of a BN!