-
-
Notifications
You must be signed in to change notification settings - Fork 33
feat: add terms decoding utils #191
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
base: main
Are you sure you want to change the base?
Changes from all commits
0d621e0
07c4659
a61d6a9
e906d5a
8e91178
f225313
c03605c
45b7b90
3f2af91
5cbf69b
f92ca30
82a1e71
7c390d5
97f6038
7d0bd1d
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,9 +1,25 @@ | ||
| /** | ||
| * ## AllowedTargetsEnforcer | ||
| * | ||
| * Restricts which contract addresses the delegate may call. | ||
| * | ||
| * Terms are encoded as the concatenation of 20-byte addresses in order with no padding between addresses. | ||
| */ | ||
|
|
||
| import type { BytesLike } from '@metamask/utils'; | ||
|
|
||
| import { concatHex, normalizeAddress } from '../internalUtils'; | ||
| import { | ||
| assertHexByteLengthAtLeastOneMultipleOf, | ||
| concatHex, | ||
| extractAddress, | ||
| getByteLength, | ||
| normalizeAddress, | ||
| } from '../internalUtils'; | ||
| import { | ||
| bytesLikeToHex, | ||
| defaultOptions, | ||
| prepareResult, | ||
| type DecodedBytesLike, | ||
| type EncodingOptions, | ||
| type ResultValue, | ||
| } from '../returns'; | ||
|
|
@@ -12,17 +28,17 @@ import type { Hex } from '../types'; | |
| /** | ||
| * Terms for configuring an AllowedTargets caveat. | ||
| */ | ||
| export type AllowedTargetsTerms = { | ||
| export type AllowedTargetsTerms<TBytesLike extends BytesLike = BytesLike> = { | ||
| /** An array of target addresses that the delegate is allowed to call. */ | ||
| targets: BytesLike[]; | ||
| targets: TBytesLike[]; | ||
| }; | ||
|
|
||
| /** | ||
| * Creates terms for an AllowedTargets caveat that restricts calls to a set of target addresses. | ||
| * | ||
| * @param terms - The terms for the AllowedTargets caveat. | ||
| * @param encodingOptions - The encoding options for the result. | ||
| * @returns The terms as concatenated target addresses. | ||
| * @returns Encoded terms. | ||
| * @throws Error if the targets array is empty or contains invalid addresses. | ||
| */ | ||
| export function createAllowedTargetsTerms( | ||
|
|
@@ -38,7 +54,7 @@ export function createAllowedTargetsTerms( | |
| * | ||
| * @param terms - The terms for the AllowedTargets caveat. | ||
| * @param encodingOptions - The encoding options for the result. | ||
| * @returns The terms as concatenated target addresses. | ||
| * @returns Encoded terms. | ||
| * @throws Error if the targets array is empty or contains invalid addresses. | ||
| */ | ||
| export function createAllowedTargetsTerms( | ||
|
|
@@ -60,3 +76,50 @@ export function createAllowedTargetsTerms( | |
| const hexValue = concatHex(normalizedTargets); | ||
| return prepareResult(hexValue, encodingOptions); | ||
| } | ||
|
|
||
| /** | ||
| * Decodes terms for an AllowedTargets caveat from encoded hex data. | ||
| * | ||
| * @param terms - The encoded terms as a hex string or Uint8Array. | ||
| * @param encodingOptions - Whether decoded addresses are returned as hex or bytes. | ||
| * @returns The decoded AllowedTargetsTerms object. | ||
| */ | ||
| export function decodeAllowedTargetsTerms( | ||
| terms: BytesLike, | ||
| encodingOptions?: EncodingOptions<'hex'>, | ||
| ): AllowedTargetsTerms<DecodedBytesLike<'hex'>>; | ||
| export function decodeAllowedTargetsTerms( | ||
| terms: BytesLike, | ||
| encodingOptions: EncodingOptions<'bytes'>, | ||
| ): AllowedTargetsTerms<DecodedBytesLike<'bytes'>>; | ||
| /** | ||
| * @param terms - The encoded terms as a hex string or Uint8Array. | ||
| * @param encodingOptions - Whether decoded addresses are returned as hex or bytes. | ||
| * @returns The decoded AllowedTargetsTerms object. | ||
| */ | ||
| export function decodeAllowedTargetsTerms( | ||
| terms: BytesLike, | ||
| encodingOptions: EncodingOptions<ResultValue> = defaultOptions, | ||
| ): | ||
| | AllowedTargetsTerms<DecodedBytesLike<'hex'>> | ||
| | AllowedTargetsTerms<DecodedBytesLike<'bytes'>> { | ||
| const hexTerms = bytesLikeToHex(terms); | ||
|
|
||
| const addressSize = 20; | ||
|
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. This is more of a question. But should we also check the terms length here to make sure they are correct? On chain we are checking terms length: https://github.com/MetaMask/delegation-framework/blob/f1d5913120fc772a4b2cc7ba4179450ffa2988c1/src/enforcers/AllowedTargetsEnforcer.sol#L58 So it should not be possible to have different terms length here. But the function could be used on a wrong data or something like that and this would be able to detect this. 🤔 If we should check terms then this should be on other enforcers as well
Collaborator
Author
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. Good call - nice little sanity check that might save someone's sanity if they're having to debug! I've added length checks to all terms decoders. |
||
| assertHexByteLengthAtLeastOneMultipleOf( | ||
| hexTerms, | ||
| addressSize, | ||
| 'Invalid targets: must be a multiple of 20', | ||
| ); | ||
| const addressCount = getByteLength(hexTerms) / addressSize; | ||
|
|
||
| const targets: (Hex | Uint8Array)[] = []; | ||
| for (let i = 0; i < addressCount; i++) { | ||
| const target = extractAddress(hexTerms, i * addressSize); | ||
| targets.push(prepareResult(target, encodingOptions)); | ||
| } | ||
|
|
||
| return { targets } as | ||
| | AllowedTargetsTerms<DecodedBytesLike<'hex'>> | ||
| | AllowedTargetsTerms<DecodedBytesLike<'bytes'>>; | ||
| } | ||
Uh oh!
There was an error while loading. Please reload this page.