Skip to content
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

Add recurring allowance permissions support on smart-session #3075

Merged
merged 8 commits into from
Oct 15, 2024
23 changes: 23 additions & 0 deletions .changeset/beige-lemons-clean.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
---
'@reown/appkit-experimental': patch
'@apps/demo': patch
'@apps/gallery': patch
'@apps/laboratory': patch
'@reown/appkit-adapter-ethers': patch
'@reown/appkit-adapter-ethers5': patch
'@reown/appkit-adapter-polkadot': patch
'@reown/appkit-adapter-solana': patch
'@reown/appkit-adapter-wagmi': patch
'@reown/appkit': patch
'@reown/appkit-utils': patch
'@reown/appkit-cdn': patch
'@reown/appkit-common': patch
'@reown/appkit-core': patch
'@reown/appkit-polyfills': patch
'@reown/appkit-scaffold-ui': patch
'@reown/appkit-siwe': patch
'@reown/appkit-ui': patch
'@reown/appkit-wallet': patch
---

Added NativeTokenRecurringAllowancePermission and ERC20RecurringAllowancePermission support on appkit-experimental/smart-session sdk
6 changes: 1 addition & 5 deletions packages/experimental/exports/smart-session/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,4 @@ export {
isSmartSessionSupported
} from '../../src/smart-session/grantPermissions.js'

export type {
KeyType,
SmartSessionGrantPermissionsRequest,
SmartSessionGrantPermissionsResponse
} from '../../src/smart-session/utils/TypeUtils.js'
export * from '../../src/smart-session/utils/TypeUtils.js'
48 changes: 43 additions & 5 deletions packages/experimental/src/smart-session/schema/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,10 @@ export const ERROR_MESSAGES = {
//PermissionSchema
INVALID_PERMISSIONS: 'Invalid permissions: must be a non-empty array',
INVALID_PERMISSIONS_TYPE: 'Invalid permissions: Expected array, received object',
INVALID_PERMISSIONS_TYPE_LITERALS: 'Invalid literal value, expected "contract-call"',

INVALID_ALLOWANCE_FORMAT: 'Invalid allowance: must be a hexadecimal string starting with "0x"',
INVALID_START: 'Invalid start time: must be a positive integer and in the future',
INVALID_PERIOD: 'Invalid period: must be a positive integer',
//PolicySchema
INVALID_POLICIES: 'Invalid policies: must be a non-empty array',
INVALID_POLICIES_TYPE: 'Invalid policies: Expected array, received object',
Expand Down Expand Up @@ -90,16 +93,51 @@ const FunctionPermissionSchema = z.object({

// Contract Call Permission Schema
const ContractCallPermissionSchema = z.object({
type: z.literal('contract-call').refine(val => val === 'contract-call', {
message: ERROR_MESSAGES.INVALID_PERMISSIONS_TYPE_LITERALS
}),
type: z.literal('contract-call'),
data: z.object({
address: z.string().startsWith('0x', { message: ERROR_MESSAGES.INVALID_ADDRESS }),
abi: z.array(z.record(z.unknown())),
functions: z.array(FunctionPermissionSchema)
})
})

// Native Token Recurring Allowance Permission Schema
const NativeTokenRecurringAllowancePermissionSchema = z.object({
type: z.literal('native-token-recurring-allowance'),
data: z.object({
allowance: z.string().startsWith('0x', { message: ERROR_MESSAGES.INVALID_ALLOWANCE_FORMAT }),
start: z
.number()
.positive({ message: ERROR_MESSAGES.INVALID_START })
.refine(value => value > Math.floor(Date.now() / 1000), {
message: ERROR_MESSAGES.INVALID_START
}),
period: z.number().positive({ message: ERROR_MESSAGES.INVALID_PERIOD })
})
})

// ERC20 Recurring Allowance Permission Schema
const ERC20RecurringAllowancePermissionSchema = z.object({
type: z.literal('erc20-recurring-allowance'),
data: z.object({
token: z.string().startsWith('0x', { message: ERROR_MESSAGES.INVALID_ADDRESS }),
allowance: z.string().startsWith('0x', { message: ERROR_MESSAGES.INVALID_ALLOWANCE_FORMAT }),
start: z
.number()
.positive({ message: ERROR_MESSAGES.INVALID_START })
.refine(value => value > Math.floor(Date.now() / 1000), {
message: ERROR_MESSAGES.INVALID_START
}),
period: z.number().positive({ message: ERROR_MESSAGES.INVALID_PERIOD })
})
})

// Update Permission Schema to support new types
const PermissionSchema = z.union([
ContractCallPermissionSchema,
NativeTokenRecurringAllowancePermissionSchema,
ERC20RecurringAllowancePermissionSchema
])
// Policies Schema
const PolicySchema = z.object({
type: z.string(),
Expand All @@ -114,7 +152,7 @@ export const SmartSessionGrantPermissionsRequestSchema = z
expiry: ExpirySchema,
signer: SignerSchema,
permissions: z
.array(ContractCallPermissionSchema)
.array(PermissionSchema)
.nonempty({ message: ERROR_MESSAGES.INVALID_PERMISSIONS }),
policies: z.array(PolicySchema)
})
Expand Down
23 changes: 22 additions & 1 deletion packages/experimental/src/smart-session/utils/TypeUtils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -93,8 +93,29 @@ export type ContractCallPermission = {
}
}

export type NativeTokenRecurringAllowancePermission = {
type: 'native-token-recurring-allowance'
data: {
allowance: `0x${string}`
start: number
period: number
}
}

export type ERC20RecurringAllowancePermission = {
type: 'erc20-recurring-allowance'
data: {
token: `0x${string}`
allowance: `0x${string}`
start: number
period: number
}
}
// Union type for all possible permissions
export type Permission = ContractCallPermission
export type Permission =
| ContractCallPermission
| NativeTokenRecurringAllowancePermission
| ERC20RecurringAllowancePermission

//--Cosigner Types----------------------------------------------------------------------- //
export type AddPermissionRequest = SmartSessionGrantPermissionsRequest
Expand Down
Loading
Loading