forked from MetaMask/metamask-extension
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add
getAllowedKeyringMethods
hook for Account Snaps (MetaMask#21246)
This PR adds the `getAllowedKeyringMethods` hook. It is used in the `rpc-methods` packed to get the list of allowed Keyring methods for a given origin. --------- Co-authored-by: Frederik Bolding <[email protected]> Co-authored-by: Maarten Zuidhoorn <[email protected]> Co-authored-by: MetaMask Bot <[email protected]>
- Loading branch information
1 parent
b8b3dd6
commit 1e5578e
Showing
10 changed files
with
256 additions
and
173 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,75 @@ | ||
import { | ||
SubjectMetadataController, | ||
SubjectType, | ||
} from '@metamask/permission-controller'; | ||
import { KeyringRpcMethod } from '@metamask/keyring-api'; | ||
import { keyringSnapPermissionsBuilder } from './keyring-snaps-permissions'; | ||
|
||
describe('keyringSnapPermissionsBuilder', () => { | ||
const mockController = new SubjectMetadataController({ | ||
subjectCacheLimit: 100, | ||
messenger: { | ||
registerActionHandler: jest.fn(), | ||
publish: jest.fn(), | ||
} as any, | ||
state: {}, | ||
}); | ||
mockController.addSubjectMetadata({ | ||
origin: 'https://some-dapp.com', | ||
subjectType: SubjectType.Website, | ||
}); | ||
|
||
it('returns the methods metamask can call', () => { | ||
const permissions = keyringSnapPermissionsBuilder(mockController); | ||
expect(permissions('metamask')).toStrictEqual([ | ||
KeyringRpcMethod.ListAccounts, | ||
KeyringRpcMethod.GetAccount, | ||
KeyringRpcMethod.FilterAccountChains, | ||
KeyringRpcMethod.DeleteAccount, | ||
KeyringRpcMethod.ListRequests, | ||
KeyringRpcMethod.GetRequest, | ||
KeyringRpcMethod.SubmitRequest, | ||
KeyringRpcMethod.RejectRequest, | ||
]); | ||
}); | ||
|
||
it('returns the methods a known origin can call', () => { | ||
const permissions = keyringSnapPermissionsBuilder(mockController); | ||
expect(permissions('https://some-dapp.com')).toStrictEqual([ | ||
KeyringRpcMethod.ListAccounts, | ||
KeyringRpcMethod.GetAccount, | ||
KeyringRpcMethod.CreateAccount, | ||
KeyringRpcMethod.FilterAccountChains, | ||
KeyringRpcMethod.UpdateAccount, | ||
KeyringRpcMethod.DeleteAccount, | ||
KeyringRpcMethod.ExportAccount, | ||
KeyringRpcMethod.ListRequests, | ||
KeyringRpcMethod.GetRequest, | ||
KeyringRpcMethod.ApproveRequest, | ||
KeyringRpcMethod.RejectRequest, | ||
]); | ||
}); | ||
|
||
it('returns the methods an unknown origin can call', () => { | ||
const permissions = keyringSnapPermissionsBuilder(mockController); | ||
expect(permissions('https://some-other-dapp.com')).toStrictEqual([]); | ||
}); | ||
|
||
it.each([ | ||
'', | ||
'null', | ||
'sftp://some-dapp.com', | ||
'http://some-dapp.com', | ||
'0', | ||
undefined, | ||
null, | ||
true, | ||
false, | ||
1, | ||
0, | ||
-1, | ||
])('"%s" cannot call any methods', (origin) => { | ||
const permissions = keyringSnapPermissionsBuilder(mockController); | ||
expect(permissions(origin as any)).toStrictEqual([]); | ||
}); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,82 @@ | ||
import { | ||
SubjectType, | ||
SubjectMetadataController, | ||
} from '@metamask/permission-controller'; | ||
import { KeyringRpcMethod } from '@metamask/keyring-api'; | ||
|
||
/** | ||
* List of keyring methods MetaMask can call. | ||
*/ | ||
const METAMASK_ALLOWED_METHODS: string[] = [ | ||
KeyringRpcMethod.ListAccounts, | ||
KeyringRpcMethod.GetAccount, | ||
KeyringRpcMethod.FilterAccountChains, | ||
KeyringRpcMethod.DeleteAccount, | ||
KeyringRpcMethod.ListRequests, | ||
KeyringRpcMethod.GetRequest, | ||
KeyringRpcMethod.SubmitRequest, | ||
KeyringRpcMethod.RejectRequest, | ||
]; | ||
|
||
/** | ||
* List of keyring methods a dapp can call. | ||
*/ | ||
const WEBSITE_ALLOWED_METHODS: string[] = [ | ||
KeyringRpcMethod.ListAccounts, | ||
KeyringRpcMethod.GetAccount, | ||
KeyringRpcMethod.CreateAccount, | ||
KeyringRpcMethod.FilterAccountChains, | ||
KeyringRpcMethod.UpdateAccount, | ||
KeyringRpcMethod.DeleteAccount, | ||
KeyringRpcMethod.ExportAccount, | ||
KeyringRpcMethod.ListRequests, | ||
KeyringRpcMethod.GetRequest, | ||
KeyringRpcMethod.ApproveRequest, | ||
KeyringRpcMethod.RejectRequest, | ||
]; | ||
|
||
/** | ||
* List of allowed protocols. On Flask, HTTP is also allowed for testing. | ||
*/ | ||
const ALLOWED_PROTOCOLS: string[] = [ | ||
'https:', | ||
///: BEGIN:ONLY_INCLUDE_IN(build-flask) | ||
'http:', | ||
///: END:ONLY_INCLUDE_IN | ||
]; | ||
|
||
/** | ||
* Checks if the protocol of the origin is allowed. | ||
* | ||
* @param origin - The origin to check. | ||
* @returns `true` if the protocol of the origin is allowed, `false` otherwise. | ||
*/ | ||
function isProtocolAllowed(origin: string): boolean { | ||
const url = new URL(origin); | ||
return ALLOWED_PROTOCOLS.includes(url.protocol); | ||
} | ||
|
||
/** | ||
* Builds a function that returns the list of keyring methods an origin can | ||
* call. | ||
* | ||
* @param controller - Reference to the `SubjectMetadataController`. | ||
* @returns A function that returns the list of keyring methods an origin can | ||
* call. | ||
*/ | ||
export function keyringSnapPermissionsBuilder( | ||
controller: SubjectMetadataController, | ||
): (origin: string) => string[] { | ||
return (origin: string) => { | ||
if (origin === 'metamask') { | ||
return METAMASK_ALLOWED_METHODS; | ||
} | ||
|
||
const originMetadata = controller.getSubjectMetadata(origin); | ||
if (originMetadata?.subjectType === SubjectType.Website) { | ||
return isProtocolAllowed(origin) ? WEBSITE_ALLOWED_METHODS : []; | ||
} | ||
|
||
return []; | ||
}; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,2 +1,2 @@ | ||
export const TEST_SNAPS_SIMPLE_KEYRING_WEBSITE_URL = | ||
'https://metamask.github.io/snap-simple-keyring/0.2.3/'; | ||
'https://metamask.github.io/snap-simple-keyring/0.3.0/'; |
Oops, something went wrong.