Skip to content

Add allowMessages flag to permissions #740

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

Draft
wants to merge 1 commit into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions packages/wallet/core/src/signers/session/explicit.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { Payload, Permission, SessionSignature, Utils } from '@0xsequence/wallet-primitives'
import { AbiParameters, Address, Bytes, Hash, Hex, Provider, Secp256k1 } from 'ox'
import { SignerInterface } from './session.js'
import { AbiParameters, Address, Bytes, Hash, Hex, Provider } from 'ox'
import { MemoryPkStore, PkStore } from '../pk/index.js'
import { SignerInterface } from './session.js'

export type ExplicitParams = Omit<Permission.SessionPermissions, 'signer'>

Expand Down
3 changes: 3 additions & 0 deletions packages/wallet/core/test/session-manager.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ describe('SessionManager', () => {
let topology = SessionConfig.emptySessionsTopology(identityAddress)
// Add random signer to the topology
const sessionPermission: Signers.Session.ExplicitParams = {
allowMessages: true,
valueLimit: 1000000000000000000n,
deadline: BigInt(Math.floor(Date.now() / 1000) + 3600), // 1 hour from now
permissions: [
Expand Down Expand Up @@ -213,6 +214,7 @@ describe('SessionManager', () => {
// Create explicit signer
const explicitPrivateKey = Secp256k1.randomPrivateKey()
const explicitPermissions: Signers.Session.ExplicitParams = {
allowMessages: true,
valueLimit: 1000000000000000000n, // 1 ETH
deadline: BigInt(Math.floor(Date.now() / 1000) + 3600), // 1 hour from now
permissions: [
Expand Down Expand Up @@ -446,6 +448,7 @@ describe('SessionManager', () => {
// Create explicit signer
const explicitPrivateKey = Secp256k1.randomPrivateKey()
const sessionPermission: Signers.Session.ExplicitParams = {
allowMessages: true,
valueLimit: 1000000000000000000n, // 1 ETH
deadline: BigInt(Math.floor(Date.now() / 1000) + 3600), // 1 hour from now
permissions: [{ target: EMITTER_ADDRESS, rules: [] }],
Expand Down
6 changes: 4 additions & 2 deletions packages/wallet/primitives-cli/src/subcommands/devTools.ts
Original file line number Diff line number Diff line change
Expand Up @@ -105,16 +105,18 @@ async function generateSessionsTopology(
depth: number,
options?: RandomOptions,
): Promise<SessionConfig.SessionsTopology> {
const isLeaf = (options?.seededRandom ?? Math.random)() * 2 > 1
const rand = options?.seededRandom ?? Math.random
const isLeaf = rand() * 2 > 1

if (isLeaf || depth <= 1) {
const permissionsCount = Math.floor((options?.seededRandom ?? Math.random)() * (options?.maxPermissions ?? 5)) + 1
const permissionsCount = Math.floor(rand() * (options?.maxPermissions ?? 5)) + 1
const permissions = await Promise.all(
Array.from({ length: permissionsCount }, () => generateRandomPermission(options)),
)
return {
type: 'session-permissions',
signer: randomAddress(options),
allowMessages: rand() * 2 > 1,
valueLimit: randomBigInt(100n, options),
deadline: randomBigInt(1000n, options),
permissions: permissions as [Permission.Permission, ...Permission.Permission[]],
Expand Down
19 changes: 14 additions & 5 deletions packages/wallet/primitives/src/permission.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { AbiParameters, Address, Bytes } from 'ox'
import { SESSIONS_FLAG_PERMISSIONS } from './session-config.js'

export enum ParameterOperation {
EQUAL = 0,
Expand All @@ -22,6 +23,7 @@ export type Permission = {

export type SessionPermissions = {
signer: Address.Address
allowMessages: boolean
valueLimit: bigint
deadline: bigint
permissions: [Permission, ...Permission[]]
Expand All @@ -39,7 +41,10 @@ export function encodeSessionPermissions(sessionPermissions: SessionPermissions)

const encodedPermissions = sessionPermissions.permissions.map(encodePermission)

const flag = (SESSIONS_FLAG_PERMISSIONS << 4) | (sessionPermissions.allowMessages ? 1 : 0)

return Bytes.concat(
Bytes.fromNumber(flag, { size: 1 }),
Bytes.padLeft(Bytes.fromHex(sessionPermissions.signer), 20),
Bytes.padLeft(Bytes.fromNumber(sessionPermissions.valueLimit), 32),
Bytes.padLeft(Bytes.fromNumber(sessionPermissions.deadline), 32),
Expand Down Expand Up @@ -77,12 +82,13 @@ function encodeParameterRule(rule: ParameterRule): Bytes.Bytes {
// Decoding

export function decodeSessionPermissions(bytes: Bytes.Bytes): SessionPermissions {
const signer = Bytes.toHex(bytes.slice(0, 20))
const valueLimit = Bytes.toBigInt(bytes.slice(20, 52))
const deadline = Bytes.toBigInt(bytes.slice(52, 84))
const permissionsLength = Number(bytes[84]!)
const allowMessages = (bytes[0]! & 0x01) === 1
const signer = Bytes.toHex(bytes.slice(1, 21))
const valueLimit = Bytes.toBigInt(bytes.slice(21, 53))
const deadline = Bytes.toBigInt(bytes.slice(53, 85))
const permissionsLength = Number(bytes[85]!)
const permissions = []
let pointer = 85
let pointer = 86
for (let i = 0; i < permissionsLength; i++) {
// Pass the remaining bytes instead of a fixed slice length
const { permission, consumed } = decodePermission(bytes.slice(pointer))
Expand All @@ -94,6 +100,7 @@ export function decodeSessionPermissions(bytes: Bytes.Bytes): SessionPermissions
}
return {
signer,
allowMessages,
valueLimit,
deadline,
permissions: permissions as [Permission, ...Permission[]],
Expand Down Expand Up @@ -190,6 +197,7 @@ export function sessionPermissionsToJson(sessionPermissions: SessionPermissions)
export function encodeSessionPermissionsForJson(sessionPermissions: SessionPermissions): any {
return {
signer: sessionPermissions.signer.toString(),
allowMessages: sessionPermissions.allowMessages,
valueLimit: sessionPermissions.valueLimit.toString(),
deadline: sessionPermissions.deadline.toString(),
permissions: sessionPermissions.permissions.map(encodePermissionForJson),
Expand Down Expand Up @@ -228,6 +236,7 @@ export function sessionPermissionsFromJson(json: string): SessionPermissions {
export function sessionPermissionsFromParsed(parsed: any): SessionPermissions {
return {
signer: Address.from(parsed.signer),
allowMessages: parsed.allowMessages,
valueLimit: BigInt(parsed.valueLimit),
deadline: BigInt(parsed.deadline),
permissions: parsed.permissions.map(permissionFromParsed),
Expand Down
14 changes: 7 additions & 7 deletions packages/wallet/primitives/src/session-config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -211,14 +211,14 @@ export function encodeLeafToGeneric(leaf: SessionLeaf): GenericTree.Leaf {
if (isSessionPermissions(leaf)) {
return {
type: 'leaf',
value: Bytes.concat(Bytes.fromNumber(SESSIONS_FLAG_PERMISSIONS), encodeSessionPermissions(leaf)),
value: encodeSessionPermissions(leaf),
}
}
if (isImplicitBlacklist(leaf)) {
return {
type: 'leaf',
value: Bytes.concat(
Bytes.fromNumber(SESSIONS_FLAG_BLACKLIST),
Bytes.fromNumber(SESSIONS_FLAG_BLACKLIST << 4),
Bytes.concat(...leaf.blacklist.map((b) => Bytes.padLeft(Bytes.fromHex(b), 20))),
),
}
Expand All @@ -227,7 +227,7 @@ export function encodeLeafToGeneric(leaf: SessionLeaf): GenericTree.Leaf {
return {
type: 'leaf',
value: Bytes.concat(
Bytes.fromNumber(SESSIONS_FLAG_IDENTITY_SIGNER),
Bytes.fromNumber(SESSIONS_FLAG_IDENTITY_SIGNER << 4),
Bytes.padLeft(Bytes.fromHex(leaf.identitySigner), 20),
),
}
Expand All @@ -237,7 +237,7 @@ export function encodeLeafToGeneric(leaf: SessionLeaf): GenericTree.Leaf {
}

export function decodeLeafFromBytes(bytes: Bytes.Bytes): SessionLeaf {
const flag = bytes[0]!
const flag = (bytes[0]! & 0xf0) >> 4
if (flag === SESSIONS_FLAG_BLACKLIST) {
const blacklist: `0x${string}`[] = []
for (let i = 1; i < bytes.length; i += 20) {
Expand All @@ -249,7 +249,7 @@ export function decodeLeafFromBytes(bytes: Bytes.Bytes): SessionLeaf {
return { type: 'identity-signer', identitySigner: Bytes.toHex(bytes.slice(1, 21)) }
}
if (flag === SESSIONS_FLAG_PERMISSIONS) {
return { type: 'session-permissions', ...decodeSessionPermissions(bytes.slice(1)) }
return { type: 'session-permissions', ...decodeSessionPermissions(bytes) }
}
throw new Error('Invalid leaf')
}
Expand Down Expand Up @@ -307,9 +307,9 @@ export function encodeSessionsTopology(topology: SessionsTopology): Bytes.Bytes
}

if (isSessionPermissions(topology)) {
const flagByte = SESSIONS_FLAG_PERMISSIONS << 4
// Encoding includes the flag
const encodedLeaf = encodeSessionPermissions(topology)
return Bytes.concat(Bytes.fromNumber(flagByte), encodedLeaf)
return Bytes.concat(encodedLeaf)
}

if (isSessionsNode(topology)) {
Expand Down