Skip to content

Commit

Permalink
Fix account ID format (#129)
Browse files Browse the repository at this point in the history
* Fix account ID format

* Fix authorization request service unit tests
  • Loading branch information
wcalderipe authored Feb 21, 2024
1 parent 23c2fc0 commit d0e7867
Show file tree
Hide file tree
Showing 5 changed files with 124 additions and 72 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -124,8 +124,8 @@ describe(AuthorizationRequestService.name, () => {
transactionRequestIntent: {
type: Intents.TRANSFER_NATIVE,
amount: '1000000000000000000',
to: getAccountId('eip155:137/0x08a08d0504d4f3363a5b7fda1f5fff1c7bca8ad4'),
from: getAccountId('eip155:137/0x90d03a8971a2faa19a9d7ffdcbca28fe826a289b'),
to: getAccountId('eip155:137:0x08a08d0504d4f3363a5b7fda1f5fff1c7bca8ad4'),
from: getAccountId('eip155:137:0x90d03a8971a2faa19a9d7ffdcbca28fe826a289b'),
token: POLYGON.coin.id
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,10 +19,10 @@ import {

describe('caip', () => {
const validAddress = '0x5db3Bf14413d7e3c69FAA279EFa1D1B08637eC4c'
const validAccountId = `${Namespace.EIP155}:1/${validAddress}`
const validAccountId = `${Namespace.EIP155}:1:${validAddress}`
const invalidAccountId = 'invalid_caip10_id'
const invalidAccountIdNamespace = 'invalid_namespace:1/0x1234567890abcdef'
const invalidAccountIdAddress = `${Namespace.EIP155}:1/invalid_address`
const invalidAccountIdNamespace = 'invalid_namespace:1:0x1234567890abcdef'
const invalidAccountIdAddress = `${Namespace.EIP155}:1:invalid_address`

describe('safeParseAccount', () => {
it('returns success for valid account id', () => {
Expand Down Expand Up @@ -96,7 +96,7 @@ describe('caip', () => {
chainId: 1,
address: '0x1234567890abcdef'
})
).toEqual(`${Namespace.EIP155}:1/0x1234567890abcdef`)
).toEqual(`${Namespace.EIP155}:1:0x1234567890abcdef`)
})
})

Expand Down
62 changes: 55 additions & 7 deletions packages/policy-engine-shared/src/lib/util/caip.util.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { SetOptional } from 'type-fest'
import { Address } from 'viem'
import { z } from 'zod'
import { toEnum } from './enum.util'
import { getAddress, isAddress } from './evm.util'

Expand Down Expand Up @@ -37,23 +38,24 @@ export enum AssetType {
/**
* @see https://github.com/ChainAgnostic/CAIPs/blob/main/CAIPs/caip-10.md
*/
export type AccountId = `${Namespace}:${number}/${string}`
export type AccountId = `${Namespace}:${number}:${string}`

export type Account = {
chainId: number
address: Address
namespace: Namespace
}

type NonCollectableAssetId = `${Namespace}:${number}/${AssetType}:${string}`
type CollectableAssetId = `${Namespace}:${number}/${AssetType}:${string}/${string}`
type CoinAssetId = `${Namespace}:${number}/${AssetType.SLIP44}:${number}`

/**
* @see https://github.com/ChainAgnostic/CAIPs/blob/main/CAIPs/caip-19.md
* @see https://github.com/ChainAgnostic/CAIPs/blob/main/CAIPs/caip-20.md
* @see https://github.com/satoshilabs/slips/blob/master/slip-0044.md
*/
export type AssetId =
| `${Namespace}:${number}/${AssetType}:${string}`
| `${Namespace}:${number}/${AssetType}:${string}/${string}`
| `${Namespace}:${number}/${AssetType.SLIP44}:${number}`
export type AssetId = NonCollectableAssetId | CollectableAssetId | CoinAssetId

export type Token = Account & {
assetType: AssetType
Expand Down Expand Up @@ -101,7 +103,7 @@ const unsafeParse = <T>(fn: (value: string) => Result<T>, value: string): T => {
//

const matchAccountId = (value: string) => {
const match = value.match(/^([^:]+):(\d+)\/(.+)$/)
const match = value.match(/^([^:]+):(\d+):(.+)$/)

if (!match) {
return null
Expand Down Expand Up @@ -207,7 +209,7 @@ export const toAccountId = (input: SetOptional<Account, 'namespace'>): AccountId
namespace: input.namespace || Namespace.EIP155
}

return `${account.namespace}:${account.chainId}/${account.address}`
return `${account.namespace}:${account.chainId}:${account.address}`
}

/**
Expand Down Expand Up @@ -464,3 +466,49 @@ export const safeGetAssetId = (value: string): Result<AssetId> => {
* @returns The parsed AssetId.
*/
export const getAssetId = (value: string): AssetId => unsafeParse<AssetId>(safeGetAssetId, value)

//
// Zod Schema
//

const nonCollectableAssetIdSchema = z.custom<NonCollectableAssetId>((value) => {
const parse = z.string().safeParse(value)

if (parse.success) {
return isAssetId(parse.data)
}

return false
})

const collectableAssetIdSchema = z.custom<CollectableAssetId>((value) => {
const parse = z.string().safeParse(value)

if (parse.success) {
return isAssetId(parse.data)
}

return false
})

const coinAssetIdSchema = z.custom<CoinAssetId>((value) => {
const parse = z.string().safeParse(value)

if (parse.success) {
return isAssetId(parse.data)
}

return false
})

export const assetIdSchema = z.union([nonCollectableAssetIdSchema, collectableAssetIdSchema, coinAssetIdSchema])

export const accountIdSchema = z.custom<AccountId>((value) => {
const parse = z.string().safeParse(value)

if (parse.success) {
return isAccountId(parse.data)
}

return false
})
Original file line number Diff line number Diff line change
Expand Up @@ -54,8 +54,8 @@ describe('decode', () => {
})
expect(decoded).toEqual({
type: Intents.TRANSFER_NATIVE,
to: 'eip155:137/0x031d8c0ca142921c459bcb28104c0ff37928f9ed',
from: 'eip155:137/0xed123cf8e3ba51c6c15da1eac74b2b5deea31448',
to: 'eip155:137:0x031d8c0ca142921c459bcb28104c0ff37928f9ed',
from: 'eip155:137:0xed123cf8e3ba51c6c15da1eac74b2b5deea31448',
amount: '16676',
token: 'eip155:137/slip44:966'
})
Expand All @@ -75,10 +75,10 @@ describe('decode', () => {
})
expect(decoded).toEqual({
type: Intents.APPROVE_TOKEN_ALLOWANCE,
from: 'eip155:137/0xed123cf8e3ba51c6c15da1eac74b2b5deea31448',
token: 'eip155:137/0x031d8c0ca142921c459bcb28104c0ff37928f9ed',
from: 'eip155:137:0xed123cf8e3ba51c6c15da1eac74b2b5deea31448',
token: 'eip155:137:0x031d8c0ca142921c459bcb28104c0ff37928f9ed',
amount: '11541971132511365478906515907109950360107522067033065608472376982619868367719',
spender: 'eip155:137/0x1111111254eeb25477b68fb85ed929f73a960582'
spender: 'eip155:137:0x1111111254eeb25477b68fb85ed929f73a960582'
})
})
it('decodes user operation', () => {
Expand All @@ -95,13 +95,13 @@ describe('decode', () => {
})
expect(decoded).toEqual({
type: Intents.USER_OPERATION,
from: 'eip155:1/0x791b1689526b5560145f99cb9d3b7f24eca2591a',
entrypoint: 'eip155:1/0x5ff137d4b0fdcd49dca30c7cf57e578a026d2789',
from: 'eip155:1:0x791b1689526b5560145f99cb9d3b7f24eca2591a',
entrypoint: 'eip155:1:0x5ff137d4b0fdcd49dca30c7cf57e578a026d2789',
beneficiary: '0x791b1689526b5560145f99cb9d3b7f24eca2591a',
operationIntents: [
{
contract: 'eip155:1/0x8ae01fcf7c655655ff2c6ef907b8b4718ab4e17c',
from: 'eip155:1/0x791b1689526b5560145f99cb9d3b7f24eca2591a',
contract: 'eip155:1:0x8ae01fcf7c655655ff2c6ef907b8b4718ab4e17c',
from: 'eip155:1:0x791b1689526b5560145f99cb9d3b7f24eca2591a',
hexSignature: '0x8d80ff0a',
type: Intents.CALL_CONTRACT
}
Expand All @@ -123,8 +123,8 @@ describe('decode', () => {
})
expect(decoded).toEqual({
type: Intents.CALL_CONTRACT,
from: 'eip155:137/0xed123cf8e3ba51c6c15da1eac74b2b5deea31448',
contract: 'eip155:137/0x031d8c0ca142921c459bcb28104c0ff37928f9ed',
from: 'eip155:137:0xed123cf8e3ba51c6c15da1eac74b2b5deea31448',
contract: 'eip155:137:0x031d8c0ca142921c459bcb28104c0ff37928f9ed',
hexSignature: '0xf2d12b12'
})
})
Expand Down Expand Up @@ -221,7 +221,7 @@ describe('decode', () => {
})
expect(decoded).toEqual({
type: Intents.DEPLOY_SAFE_WALLET,
from: 'eip155:137/0xaaad8c0ca142921c459bcb28104c0ff37928f9ed',
from: 'eip155:137:0xaaad8c0ca142921c459bcb28104c0ff37928f9ed',
chainId: 137
})
})
Expand All @@ -241,7 +241,7 @@ describe('decode', () => {
})
expect(decoded).toEqual({
type: Intents.DEPLOY_ERC_4337_WALLET,
from: 'eip155:137/0xcccd8c0ca142921c459bcb28104c0ff37928f9ed',
from: 'eip155:137:0xcccd8c0ca142921c459bcb28104c0ff37928f9ed',
chainId: 137,
bytecode: '0x41284124120948012849081209470127490127940790127490712038017403178947109247'
})
Expand All @@ -262,7 +262,7 @@ describe('decode', () => {
})
expect(decoded).toEqual({
type: Intents.DEPLOY_CONTRACT,
from: 'eip155:137/0x031d8c0ca142921c459bcb28104c0ff37928f9ed',
from: 'eip155:137:0x031d8c0ca142921c459bcb28104c0ff37928f9ed',
chainId: 137
})
})
Expand Down Expand Up @@ -380,11 +380,11 @@ describe('decode', () => {
})
expect(decoded).toEqual({
type: Intents.PERMIT,
spender: 'eip155:137/0xffcf8fdee72ac11b5c542428b35eef5769c409f0',
token: 'eip155:137/0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2',
spender: 'eip155:137:0xffcf8fdee72ac11b5c542428b35eef5769c409f0',
token: 'eip155:137:0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2',
amount: '1000000000000000000',
deadline: '9999999999',
owner: 'eip155:137/0x90f8bf6a479f320ead074411a4b0e7944ea8c9c1'
owner: 'eip155:137:0x90f8bf6a479f320ead074411a4b0e7944ea8c9c1'
})
})
it('decodes permit2', () => {
Expand Down Expand Up @@ -431,13 +431,12 @@ describe('decode', () => {
})
expect(decoded).toEqual({
type: Intents.PERMIT2,
token: 'eip155:137/0x64060ab139feaae7f06ca4e63189d86adeb51691',
spender: 'eip155:137/0x08a08d0504d4f3363a5b7fda1f5fff1c7bca8ad4',
token: 'eip155:137:0x64060ab139feaae7f06ca4e63189d86adeb51691',
spender: 'eip155:137:0x08a08d0504d4f3363a5b7fda1f5fff1c7bca8ad4',
amount: '1461501637330902918203684832716283019655932542975',
deadline: 1709143217,
owner: 'eip155:137/0xed123cf8e3ba51c6c15da1eac74b2b5deea31448'
owner: 'eip155:137:0xed123cf8e3ba51c6c15da1eac74b2b5deea31448'
})
})
it('defaults to raw payload', () => {})
})
})
Loading

0 comments on commit d0e7867

Please sign in to comment.