# SNIP 24.1: Blanket Permits This specification introduces a backwards-compatible extension to [SNIP-24](./SNIP-24.md) that adds "blanket" permits, which allow the permit holder to use them with any compatible token. The idea is that a user signs a single message to grant an application permission to query all current and future SNIP tokens. ## Data Structures The revised `PermitMsg` schema is defined as: ```ts export type PermitMsg = { type: 'query_permit'; value: { permit_name: string; allowed_tokens: `secret1${string}`[] | ['ANY_TOKEN']; permissions: ( | 'balance' // ability to query balance | 'history' // ability to query histories | 'allowance' // ability to query allowances | 'owner' // ability to query everything | string // custom permissions defined by contract )[]; created?: Iso8601UtcDateTime; // {YYYY}-{MM}-{DD}T{hh}:{mm}:{ss}.{uuu}Z expires?: Iso8601UtcDateTime; }; }; ``` The changes to the schema are summarized as: - Ability to specify `"ANY_TOKEN"` as the single item in the `allowed_tokens` list - Ability to specify a datetime at `created` for when this message was signed - Ability to specify a datetime at `expires` for when this permit shall no longer be valid ### Mandatory `created` Permits using the `"ANY_TOKEN"` keyword MUST include a value for `created`. For all other cases, the `created` and `expires` fields are encouraged but optional. ## Messages ### RevokeAllPermits Revokes all permits. Client can supply a datetime for `created_after`, `created_before`, both, or neither. - `created_before` -- makes it so any permits using a `created` value less than this datetime will be rejected - `created_after` -- makes it so any permits using a `created` value greater than this datetime will be rejected - **both** `created_before` and `created_after` -- makes it so any permits using a `created` value **between** these two datetimes will be rejected - _neither_ -- makes it so **ANY** permit will be rejected. in this case, the contract MUST return a revocation ID of `"REVOKED_ALL"`. this action is idempotent <!-- If the client specifies exactly one of `created_before` or `created_after` and a previous revocation of that type exists, one of the following two things will happen: 1. the new revocation is temporally closed by the existing one, in which case it is ignored. e.g., `new_revocation.created_before <= old_revocation.created_before` 2. the old revocation is temporally closed by the new one, in which case the exiting one is deleted and replaced by the new one. e.g., `new_revocation.created_before >= old_revocation.created_before` > NOTE: The above rule means that order of operations matters. If the client wants --> ##### Limitations Contract implementors MAY enforce an upper bound on the number of revocations an account is allowed to make. If an attempt is made to exceed this limit, the contract MUST throw an error. #### Request ```ts export type RevokeAllPermitsExecutionRequest = { revoke_all_permits: { interval?: { // both specified in seconds since unix epoch created_before?: Uint64Str; created_after?: Uint64Str; }; }; } ``` #### Response ```ts export type RevokeAllPermitsExecutionResponse = { revoke_all_permits: { status: "success"; revocation_id?: string; // if a new revocation was created }; }; ``` ### DeletePermitRevocation Deletes a previously issued permit revocation. #### Request ```ts export type DeletePermitRevocationExecutionRequest = { delete_permit_revocation: { revocation_id: string; }; }; ``` #### Response ```ts export type DeletePermitRevocationExecutionResponse = { delete_permit_revocation: { status: "success"; }; }; ``` ## Queries ### ListPermitRevocations Enumerates permit revocations that have been previously made. #### Request ```ts export type ListPermitRevocationsQueryRequest = { list_permit_revocations: { page_size?: number; page?: number; }; }; ``` #### Response ```ts export type ListPermitRevocationsQueryResponse = { list_permit_revocations: { revocations: Array<{ revocation_id: string; interval: { // both specified in seconds since unix epoch created_before?: Uint64Str; created_after?: Uint64Str; }; }>; }; }; ``` ## Using Query Permits The contract shall enforce the following additional rules when verifying query permits: - If `created` is specified: - assert that it is in the past - check if any revocations apply to that datetime and if so, deny the query - If `expires` is specified: - assert that it is in the future - If the `allowed_tokens` list includes an item `"ANY_TOKEN"`: - assert the list has an exact length of `1` - assert that `created` is specified <!-- ```ts type Iso8601Utc = `${YYYY}-${MM}-${DD}T${HH}:${NN}:${SS}.${UUU}Z`; type YYYY = Digits_x4; type MM = Digits_x2; type DD = Digits_x2; type HH = Digits_x2; type NN = Digits_x2; type SS = Digits_x2; type UUU = Digits_x3; type Digits_x4 = `${Digit}${Digit}${Digit}${Digit}`; type Digits_x3 = `${Digit}${Digit}${Digit}`; type Digits_x2 = `${Digit}${Digit}`; type Digit = `${0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 |9}`; ``` -->