diff --git a/apps/policy-engine/src/open-policy-agent/core/open-policy-agent.engine.ts b/apps/policy-engine/src/open-policy-agent/core/open-policy-agent.engine.ts index b4ded1901..718e7215a 100644 --- a/apps/policy-engine/src/open-policy-agent/core/open-policy-agent.engine.ts +++ b/apps/policy-engine/src/open-policy-agent/core/open-policy-agent.engine.ts @@ -187,6 +187,7 @@ export class OpenPolicyAgentEngine implements Engine { // an array of results with an inner result. We perform a typecast here to // satisfy TypeScript compiler. Later, we parse the schema a few lines // below to ensure type-safety for data coming from external sources. + const results = (await this.opa.evaluate(input, POLICY_ENTRYPOINT)) as { result: unknown }[] const parse = z.array(resultSchema).safeParse(results.map(({ result }) => result)) diff --git a/apps/policy-engine/src/resource/open-policy-agent/rego/criteria/intent/destination.rego b/apps/policy-engine/src/resource/open-policy-agent/rego/criteria/intent/destination.rego index 7e11ac3bc..d07d1be37 100644 --- a/apps/policy-engine/src/resource/open-policy-agent/rego/criteria/intent/destination.rego +++ b/apps/policy-engine/src/resource/open-policy-agent/rego/criteria/intent/destination.rego @@ -18,6 +18,11 @@ checkDestinationAccountType(values) { } checkDestinationClassification(values) { + print("it starts being interesting \n\n") destination = getDestination(input.intent) + print("\n\n destination |", destination, "|\n\n") + print("\n\nit stops being interesting \n\n") destination.classification in values + print("\n\ndestination.classification\n\n", destination.classification) + print("\n\ndestination.classification in values\n\n", destination.classification in values) } diff --git a/packages/armory-sdk/src/lib/__test__/e2e/scenarii/defi-interactions.spec.ts b/packages/armory-sdk/src/lib/__test__/e2e/scenarii/defi-interactions.spec.ts new file mode 100644 index 000000000..e6ad597e8 --- /dev/null +++ b/packages/armory-sdk/src/lib/__test__/e2e/scenarii/defi-interactions.spec.ts @@ -0,0 +1,199 @@ +import { + Action, + Eip712Domain, + Eip712TypedData, + entitiesSchema, + FIXTURE, + policySchema, + Request +} from '@narval/policy-engine-shared' +import { v4 } from 'uuid' +import defiEntities from '../../../../resource/entity/defi-interaction.json' +import defiInteractionPolicy from '../../../../resource/policy/set/defi-interaction.json' +import { buildAuthClient, createClient, saveDataStore } from '../../util/setup' + +const TEST_TIMEOUT_MS = 30_000 + +jest.setTimeout(TEST_TIMEOUT_MS) + +const systemManagerHexPk = FIXTURE.UNSAFE_PRIVATE_KEY.Root + +const getAuthHost = () => 'http://localhost:3005' +const getAuthAdminApiKey = () => 'armory-admin-api-key' +const alicePrivateKey = FIXTURE.UNSAFE_PRIVATE_KEY.Alice +const bobPrivateKey = FIXTURE.UNSAFE_PRIVATE_KEY.Bob +const carolPrivateKey = FIXTURE.UNSAFE_PRIVATE_KEY.Carol +const antoinePrivateKey = FIXTURE.UNSAFE_PRIVATE_KEY.Antoine + +const genNonce = (request: Request) => ({ ...request, nonce: `${request.nonce}-${v4()}` }) + +describe('Uniswap governance', () => { + const clientId = v4() + + beforeAll(async () => { + const entities = entitiesSchema.parse(defiEntities) + const policies = defiInteractionPolicy.map((policy) => policySchema.parse(policy)) + + await createClient(systemManagerHexPk, { + clientId, + authHost: getAuthHost(), + authAdminApiKey: getAuthAdminApiKey() + }) + await saveDataStore(systemManagerHexPk, { + clientId, + host: getAuthHost(), + entities, + policies + }) + }) + + it('uniswap traders can signMessage with uniswap trader accounts', async () => { + const { authClient } = await buildAuthClient(antoinePrivateKey, { + host: getAuthHost(), + clientId + }) + + const request = genNonce({ + action: Action.SIGN_MESSAGE, + nonce: 'test-nonce-1', + message: 'Log in uniswap', + resourceId: 'eip155:eoa:0x9f38879167acCf7401351027EE3f9247A71cd0c5' + }) + + const accessToken = await authClient.requestAccessToken(request) + expect(accessToken).toMatchObject({ value: expect.any(String) }) + }) + + it('uniswap traders can do permit or permit2 with uniswap trader accounts', async () => { + // Uniswap's Permit2 domain + const PERMIT2_DOMAIN_NAME = 'Permit2' + const PERMIT2_DOMAIN_VERSION = '1' + const PERMIT2_ADDRESS = '0x000000000022d473030f116ddee9f6b43ac78ba3' + + const domain: Eip712Domain = { + name: PERMIT2_DOMAIN_NAME, + version: PERMIT2_DOMAIN_VERSION, + chainId: 1, + verifyingContract: PERMIT2_ADDRESS + } + + // Uniswap's Permit2 types + const types = { + PermitSingle: [ + { name: 'details', type: 'PermitDetails' }, + { name: 'spender', type: 'address' }, + { name: 'sigDeadline', type: 'uint256' } + ], + PermitDetails: [ + { name: 'token', type: 'address' }, + { name: 'amount', type: 'uint160' }, + { name: 'expiration', type: 'uint48' }, + { name: 'nonce', type: 'uint48' } + ] + } + + // Example payload + const permitSinglePayload = { + details: { + token: '0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48', + amount: '0xfffffffffffffff', + expiration: Math.floor(Date.now() / 1000) + 86400, + nonce: 0, + owner: '0x9f38879167acCf7401351027EE3f9247A71cd0c5' + }, + spender: '0x3fC91A3afd70395Cd496C647d5a6CC9D4B2b7FAD', + sigDeadline: Math.floor(Date.now() / 1000) + 3600 + } + + const dataToSign: Eip712TypedData = { + types: types, + domain: domain, + primaryType: 'PermitSingle', + message: permitSinglePayload + } + + const { authClient } = await buildAuthClient(antoinePrivateKey, { + host: getAuthHost(), + clientId + }) + + const request = genNonce({ + action: Action.SIGN_TYPED_DATA, + nonce: 'test-nonce-2', + typedData: dataToSign, + resourceId: 'eip155:eoa:0x9f38879167acCf7401351027EE3f9247A71cd0c5' + }) + + const accessToken = await authClient.requestAccessToken(request) + expect(accessToken).toMatchObject({ value: expect.any(String) }) + }) + + it('uniswap traders can call multicall with uniswap trader accounts on universal router', async () => { + const { authClient } = await buildAuthClient(antoinePrivateKey, { + host: getAuthHost(), + clientId + }) + + const request = genNonce({ + action: Action.SIGN_TRANSACTION, + nonce: 'test-nonce-3', + transactionRequest: { + from: '0x9f38879167acCf7401351027EE3f9247A71cd0c5', + to: '0x3fC91A3afd70395Cd496C647d5a6CC9D4B2b7FAD', + data: '0xac9650d800000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000001e00000000000000000000000000000000000000000000000000000000000000164883164560000000000000000000000000d500b1d8e8ef31e21c99d1db9a6444d3adf12700000000000000000000000003c499c542cef5e3811e1192ce70d8cc03d5c335900000000000000000000000000000000000000000000000000000000000001f4fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffba244fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffba258000000000000000000000000000000000000000000000000008259804f52ed0e0000000000000000000000000000000000000000000000000000000000000ea000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000084e6a5e3442d348ba5e149e362846be6fcf2e9e0000000000000000000000000000000000000000000000000000000066e3097a00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000412210e8a00000000000000000000000000000000000000000000000000000000', + value: '0x0', + chainId: 1 + }, + resourceId: 'eip155:eoa:0x9f38879167acCf7401351027EE3f9247A71cd0c5' + }) + + const accessToken = await authClient.requestAccessToken(request) + expect(accessToken).toMatchObject({ value: expect.any(String) }) + }) + + it('uniswap traders can call swap with uniswap trader accounts on universal router', async () => { + const { authClient } = await buildAuthClient(antoinePrivateKey, { + host: getAuthHost(), + clientId + }) + + const request = genNonce({ + action: Action.SIGN_TRANSACTION, + nonce: 'test-nonce-4', + transactionRequest: { + from: '0x9f38879167acCf7401351027EE3f9247A71cd0c5', + to: '0x3fC91A3afd70395Cd496C647d5a6CC9D4B2b7FAD', + data: '0x3593564c000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000066e3085500000000000000000000000000000000000000000000000000000000000000040b000604000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000e00000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000028000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000002386f26fc1000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000002386f26fc100000000000000000000000000000000000000000000000000000000000000000dec00000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002b0d500b1d8e8ef31e21c99d1db9a6444d3adf12700000643c499c542cef5e3811e1192ce70d8cc03d5c335900000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000600000000000000000000000003c499c542cef5e3811e1192ce70d8cc03d5c33590000000000000000000000007ffc3dbf3b2b50ff3a1d5523bc24bb5043837b14000000000000000000000000000000000000000000000000000000000000001900000000000000000000000000000000000000000000000000000000000000600000000000000000000000003c499c542cef5e3811e1192ce70d8cc03d5c335900000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000dec', + value: '0x0', + chainId: 1 + }, + resourceId: 'eip155:eoa:0x9f38879167acCf7401351027EE3f9247A71cd0c5' + }) + + const accessToken = await authClient.requestAccessToken(request) + + expect(accessToken).toMatchObject({ value: expect.any(String) }) + }) + + it('anyone can sign a transfer from a uniswap trader account to a treasury account', async () => { + const { authClient } = await buildAuthClient(bobPrivateKey, { + host: getAuthHost(), + clientId + }) + + const request = genNonce({ + action: Action.SIGN_TRANSACTION, + nonce: 'test-nonce-4', + transactionRequest: { + from: '0x9f38879167acCf7401351027EE3f9247A71cd0c5', + to: '0x76d1b7f9b3F69C435eeF76a98A415332084A856F', + value: '0x8AC7230489E80000', // 10 ETH + chainId: 1 + }, + resourceId: 'eip155:eoa:0x9f38879167acCf7401351027EE3f9247A71cd0c5' + }) + + const accessToken = await authClient.requestAccessToken(request) + expect(accessToken).toMatchObject({ value: expect.any(String) }) + }) +}) diff --git a/packages/armory-sdk/src/resource/entity/defi-interaction.json b/packages/armory-sdk/src/resource/entity/defi-interaction.json new file mode 100644 index 000000000..8e2545522 --- /dev/null +++ b/packages/armory-sdk/src/resource/entity/defi-interaction.json @@ -0,0 +1,349 @@ +{ + "addressBook": [ + { + "id": "eip155:137:0x0f610AC9F0091f8F573c33f15155afE8aD747495", + "address": "0x0f610AC9F0091f8F573c33f15155afE8aD747495", + "chainId": 137, + "classification": "managed" + }, + { + "id": "eip155:1:0x9f38879167acCf7401351027EE3f9247A71cd0c5", + "address": "0x9f38879167acCf7401351027EE3f9247A71cd0c5", + "chainId": 1, + "classification": "managed" + }, + { + "id": "eip155:137:0x9f38879167acCf7401351027EE3f9247A71cd0c5", + "address": "0x0301e2724a40E934Cce3345928b88956901aA127", + "chainId": 137, + "classification": "managed" + }, + { + "id": "eip155:1:0x0301e2724a40E934Cce3345928b88956901aA127", + "address": "0x0301e2724a40E934Cce3345928b88956901aA127", + "chainId": 1, + "classification": "managed" + }, + { + "id": "eip155:137:0x76d1b7f9b3F69C435eeF76a98A415332084A856F", + "address": "0x76d1b7f9b3F69C435eeF76a98A415332084A856F", + "chainId": 137, + "classification": "managed" + }, + { + "id": "eip155:1:0x1118ee1cbaa1856f4550c6fc24abb16c5c9b2a43", + "address": "0x1118ee1cbaa1856f4550c6fc24abb16c5c9b2a43", + "chainId": 1, + "classification": "external" + }, + { + "id": "eip155:137:0x2227be636c3ad8cf9d08ba8bdba4abd2ef29bd23", + "address": "0x2227be636c3ad8cf9d08ba8bdba4abd2ef29bd23", + "chainId": 137, + "classification": "internal" + }, + { + "id": "eip155:1:0x3331472fce4ec74a1e3f9653776acfc790cd0743", + "address": "0x3331472fce4ec74a1e3f9653776acfc790cd0743", + "chainId": 1, + "classification": "counterparty" + } + ], + "credentials": [ + { + "id": "0x478c3f4d143bdc03abbf8cd7fbedc0e0160529f77ecad897690517f5c95f48ee", + "userId": "test-root-user-uid", + "key": { + "kty": "EC", + "alg": "ES256K", + "kid": "0x478c3f4d143bdc03abbf8cd7fbedc0e0160529f77ecad897690517f5c95f48ee", + "crv": "secp256k1", + "x": "qfO89lBQWVl_byetjA8Do716F2NSCwv-wgRIi45YQH4", + "y": "6ShFqxw1p4SwX9-lZ3FcU7svKZSbJ3FOPBdg43CQCaY" + } + }, + { + "userId": "test-alice-user-uid", + "id": "0x4fca4ebdd44d54a470a273cb6c131303892cb754f0d374a860fab7936bb95d94", + "key": { + "kty": "EC", + "alg": "ES256K", + "kid": "0x4fca4ebdd44d54a470a273cb6c131303892cb754f0d374a860fab7936bb95d94", + "crv": "secp256k1", + "x": "zb-LwlHDtp5sV8E33k3H2TCm-LNTGIcFjODNWI4gHRY", + "y": "6Pbt6dwxAeS7yHp7YV2GbXs_Px0tWrTfeTv9erjC7zs" + } + }, + { + "userId": "test-bob-user-uid", + "id": "0x7e431d5b570ba38e2e036387a596219ae9076e8a488a6149b491892b03582166", + "key": { + "kty": "EC", + "alg": "ES256K", + "kid": "0x7e431d5b570ba38e2e036387a596219ae9076e8a488a6149b491892b03582166", + "crv": "secp256k1", + "x": "m5zj9v8I_UvB-15y7t7RmQXmyNmPuvAQPDdU71LRkUA", + "y": "Az5R7PGJbmKdPpK2-jmUh7xyuaOZlCIFNU4I83xy5lU" + } + }, + { + "userId": "test-carol-user-uid", + "id": "0x8014093787673513011ee2be28bc685a1df716abbe0d4d76173b0dbdc33d0557", + "key": { + "kty": "EC", + "alg": "ES256K", + "kid": "0x8014093787673513011ee2be28bc685a1df716abbe0d4d76173b0dbdc33d0557", + "crv": "secp256k1", + "x": "OA4p5YjB0XBUzMuE6qhSwcSCLDu-yf9VekwcE320fWw", + "y": "nLK5Qr_VHqZD9rVCLMHToXvdE9KuTn6w--PJ9jcpdUU" + } + }, + { + "userId": "test-dave-user-uid", + "id": "0x1d76eff4362bf8e292d5ceedcc89925cbef5f12dbdd2023c88887a863d444303", + "key": { + "kty": "EC", + "alg": "ES256K", + "kid": "0x1d76eff4362bf8e292d5ceedcc89925cbef5f12dbdd2023c88887a863d444303", + "crv": "secp256k1", + "x": "B8XJz6mktivOJjgyb3sRlSSaLQ4lfW0filHdLUzf37Q", + "y": "WUXcs1yEu8f9qBksL0y2psQ3yFDJtjRRJtNX9hGQplY" + } + }, + { + "userId": "test-antoine-user-uid", + "id": "0x6af10b6d5024963972ba832486ea1ae29f1b99cb1191abe444b52e98c69f7487", + "key": { + "kty": "EC", + "alg": "ES256K", + "kid": "0x6af10b6d5024963972ba832486ea1ae29f1b99cb1191abe444b52e98c69f7487", + "crv": "secp256k1", + "x": "QwUuAC2s22VKwoS5uPTZgcTN_ztkwt9VWKRae3bikEQ", + "y": "lZgwfE7ZDz9af9_PZxq9B7pVwAarfIaFESATYp-Q7Uk" + } + }, + { + "userId": "test-system-manager-user-uid", + "id": "0xbd810cd739d7304418dfa3c780c52ec0fdb970adbedda1cb2c8ef8c20ed3ef61", + "key": { + "kty": "EC", + "alg": "ES256K", + "kid": "0xbd810cd739d7304418dfa3c780c52ec0fdb970adbedda1cb2c8ef8c20ed3ef61", + "crv": "secp256k1", + "x": "jceVT-Wge27mz_U2BHoj_Sq53nYs1GfMNlQanOwBD9g", + "y": "MdgW5_ZeJc9jb1UWwECrGGrFRb1HHk2uL9i1zsp52yI" + } + }, + { + "id": "0x000c0d191308A336356BEe3813CC17F6868972C4", + "userId": "test-root-user-uid", + "key": { + "kty": "EC", + "crv": "secp256k1", + "alg": "ES256K", + "kid": "0x000c0d191308A336356BEe3813CC17F6868972C4", + "addr": "0x000c0d191308A336356BEe3813CC17F6868972C4" + } + }, + { + "id": "0xaaA8EE1CbaA1856F4550c6fc24abb16C5c9b2a43", + "userId": "test-alice-user-uid", + "key": { + "kty": "EC", + "crv": "secp256k1", + "alg": "ES256K", + "kid": "0xaaA8EE1CbaA1856F4550c6fc24abb16C5c9b2a43", + "addr": "0xaaA8EE1CbaA1856F4550c6fc24abb16C5c9b2a43" + } + }, + { + "id": "0xbbB7bE636C3aD8CF9d08Ba8BDba4aBD2ef29BD23", + "userId": "test-bob-user-uid", + "key": { + "kty": "EC", + "crv": "secp256k1", + "alg": "ES256K", + "kid": "0xbbB7bE636C3aD8CF9d08Ba8BDba4aBD2ef29BD23", + "addr": "0xbbB7bE636C3aD8CF9d08Ba8BDba4aBD2ef29BD23" + } + }, + { + "id": "0xCCC1472FcE4eC74a1E3f9653776ACFc790cD0743", + "userId": "test-carol-user-uid", + "key": { + "kty": "EC", + "crv": "secp256k1", + "alg": "ES256K", + "kid": "0xCCC1472FcE4eC74a1E3f9653776ACFc790cD0743", + "addr": "0xCCC1472FcE4eC74a1E3f9653776ACFc790cD0743" + } + }, + { + "id": "0xddd26a02e7c54e8dc373b9d2DCb309ECdeCA815D", + "userId": "test-dave-user-uid", + "key": { + "kty": "EC", + "crv": "secp256k1", + "alg": "ES256K", + "kid": "0xddd26a02e7c54e8dc373b9d2DCb309ECdeCA815D", + "addr": "0xddd26a02e7c54e8dc373b9d2DCb309ECdeCA815D" + } + }, + { + "id": "0xeee7798380DF797a12B459BA0d4d48cBa8e66B37", + "userId": "test-antoine-user-uid", + "key": { + "kty": "EC", + "crv": "secp256k1", + "alg": "ES256K", + "kid": "0xeee7798380DF797a12B459BA0d4d48cBa8e66B37", + "addr": "0xeee7798380DF797a12B459BA0d4d48cBa8e66B37" + } + }, + { + "id": "0xfffFA973C351Df1BE703dA81b0C6BE08Abc51500", + "userId": "test-system-manager-user-uid", + "key": { + "kty": "EC", + "crv": "secp256k1", + "alg": "ES256K", + "kid": "0xfffFA973C351Df1BE703dA81b0C6BE08Abc51500", + "addr": "0xfffFA973C351Df1BE703dA81b0C6BE08Abc51500" + } + } + ], + "tokens": [ + { + "id": "eip155:1/erc20:0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48", + "address": "0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48", + "chainId": 1, + "symbol": "USDC", + "decimals": 6 + }, + { + "id": "eip155:137/erc20:0x2791bca1f2de4661ed88a30c99a7a9449aa84174", + "address": "0x2791bca1f2de4661ed88a30c99a7a9449aa84174", + "chainId": 137, + "symbol": "USDC", + "decimals": 6 + } + ], + "userGroupMembers": [ + { + "groupId": "uniswap-traders", + "userId": "test-antoine-user-uid" + }, + { + "groupId": "uniswap-traders", + "userId": "test-bob-user-uid" + }, + { + "groupId": "treasury-managers", + "userId": "test-dave-user-uid" + }, + { + "groupId": "treasury-managers", + "userId": "test-carol-user-uid" + } + ], + "userGroups": [ + { + "id": "uniswap-traders" + }, + { + "id": "treasury-managers" + } + ], + "userAccounts": [ + { + "accountId": "eip155:eoa:0x76d1b7f9b3F69C435eeF76a98A415332084A856F", + "userId": "test-alice-user-uid" + }, + { + "accountId": "eip155:eoa:0x0f610AC9F0091f8F573c33f15155afE8aD747495", + "userId": "test-alice-user-uid" + }, + { + "accountId": "eip155:eoa:0x0301e2724a40E934Cce3345928b88956901aA127", + "userId": "test-alice-user-uid" + } + ], + "users": [ + { + "id": "test-root-user-uid", + "role": "root" + }, + { + "id": "test-alice-user-uid", + "role": "admin" + }, + { + "id": "test-bob-user-uid", + "role": "admin" + }, + { + "id": "test-carol-user-uid", + "role": "manager" + }, + { + "id": "test-dave-user-uid", + "role": "member" + }, + { + "id": "test-antoine-user-uid", + "role": "member" + }, + { + "id": "test-system-manager-user-uid", + "role": "manager" + } + ], + "accountGroupMembers": [ + { + "groupId": "uniswap-trading-accounts", + "accountId": "eip155:eoa:0x9f38879167acCf7401351027EE3f9247A71cd0c5" + }, + { + "groupId": "uniswap-trading-accounts", + "accountId": "eip155:eoa:0x0f610AC9F0091f8F573c33f15155afE8aD747495" + }, + { + "groupId": "test-treasury-account-group-uid", + "accountId": "eip155:eoa:0x0301e2724a40E934Cce3345928b88956901aA127" + }, + { + "groupId": "test-treasury-account-group-uid", + "accountId": "eip155:eoa:0x76d1b7f9b3F69C435eeF76a98A415332084A856F" + } + ], + "accountGroups": [ + { + "id": "uniswap-trading-accounts" + }, + { + "id": "test-treasury-account-group-uid" + } + ], + "accounts": [ + { + "id": "eip155:eoa:0x0f610AC9F0091f8F573c33f15155afE8aD747495", + "address": "0x0f610AC9F0091f8F573c33f15155afE8aD747495", + "accountType": "eoa" + }, + { + "id": "eip155:eoa:0x9f38879167acCf7401351027EE3f9247A71cd0c5", + "address": "0x9f38879167acCf7401351027EE3f9247A71cd0c5", + "accountType": "eoa" + }, + { + "id": "eip155:eoa:0x0301e2724a40E934Cce3345928b88956901aA127", + "address": "0x0301e2724a40E934Cce3345928b88956901aA127", + "accountType": "eoa" + }, + { + "id": "eip155:eoa:0x76d1b7f9b3F69C435eeF76a98A415332084A856F", + "address": "0x76d1b7f9b3F69C435eeF76a98A415332084A856F", + "accountType": "eoa" + } + ] +} diff --git a/packages/armory-sdk/src/resource/entity/fixture.json b/packages/armory-sdk/src/resource/entity/fixture.json new file mode 100644 index 000000000..dd5a2cdd5 --- /dev/null +++ b/packages/armory-sdk/src/resource/entity/fixture.json @@ -0,0 +1,353 @@ +{ + "addressBook": [ + { + "id": "eip155:137:0x0f610AC9F0091f8F573c33f15155afE8aD747495", + "address": "0x0f610AC9F0091f8F573c33f15155afE8aD747495", + "chainId": 137, + "classification": "managed" + }, + { + "id": "eip155:1:0x9f38879167acCf7401351027EE3f9247A71cd0c5", + "address": "0x9f38879167acCf7401351027EE3f9247A71cd0c5", + "chainId": 1, + "classification": "managed" + }, + { + "id": "eip155:137:0x9f38879167acCf7401351027EE3f9247A71cd0c5", + "address": "0x0301e2724a40E934Cce3345928b88956901aA127", + "chainId": 137, + "classification": "managed" + }, + { + "id": "eip155:1:0x0301e2724a40E934Cce3345928b88956901aA127", + "address": "0x0301e2724a40E934Cce3345928b88956901aA127", + "chainId": 1, + "classification": "managed" + }, + { + "id": "eip155:137:0x76d1b7f9b3F69C435eeF76a98A415332084A856F", + "address": "0x76d1b7f9b3F69C435eeF76a98A415332084A856F", + "chainId": 137, + "classification": "managed" + }, + { + "id": "eip155:1:0x1118ee1cbaa1856f4550c6fc24abb16c5c9b2a43", + "address": "0x1118ee1cbaa1856f4550c6fc24abb16c5c9b2a43", + "chainId": 1, + "classification": "external" + }, + { + "id": "eip155:137:0x2227be636c3ad8cf9d08ba8bdba4abd2ef29bd23", + "address": "0x2227be636c3ad8cf9d08ba8bdba4abd2ef29bd23", + "chainId": 137, + "classification": "internal" + }, + { + "id": "eip155:1:0x3331472fce4ec74a1e3f9653776acfc790cd0743", + "address": "0x3331472fce4ec74a1e3f9653776acfc790cd0743", + "chainId": 1, + "classification": "counterparty" + } + ], + "credentials": [ + { + "id": "0x478c3f4d143bdc03abbf8cd7fbedc0e0160529f77ecad897690517f5c95f48ee", + "userId": "test-root-user-uid", + "key": { + "kty": "EC", + "alg": "ES256K", + "kid": "0x478c3f4d143bdc03abbf8cd7fbedc0e0160529f77ecad897690517f5c95f48ee", + "crv": "secp256k1", + "x": "qfO89lBQWVl_byetjA8Do716F2NSCwv-wgRIi45YQH4", + "y": "6ShFqxw1p4SwX9-lZ3FcU7svKZSbJ3FOPBdg43CQCaY" + } + }, + { + "userId": "test-alice-user-uid", + "id": "0x4fca4ebdd44d54a470a273cb6c131303892cb754f0d374a860fab7936bb95d94", + "key": { + "kty": "EC", + "alg": "ES256K", + "kid": "0x4fca4ebdd44d54a470a273cb6c131303892cb754f0d374a860fab7936bb95d94", + "crv": "secp256k1", + "x": "zb-LwlHDtp5sV8E33k3H2TCm-LNTGIcFjODNWI4gHRY", + "y": "6Pbt6dwxAeS7yHp7YV2GbXs_Px0tWrTfeTv9erjC7zs" + } + }, + { + "userId": "test-bob-user-uid", + "id": "0x7e431d5b570ba38e2e036387a596219ae9076e8a488a6149b491892b03582166", + "key": { + "kty": "EC", + "alg": "ES256K", + "kid": "0x7e431d5b570ba38e2e036387a596219ae9076e8a488a6149b491892b03582166", + "crv": "secp256k1", + "x": "m5zj9v8I_UvB-15y7t7RmQXmyNmPuvAQPDdU71LRkUA", + "y": "Az5R7PGJbmKdPpK2-jmUh7xyuaOZlCIFNU4I83xy5lU" + } + }, + { + "userId": "test-carol-user-uid", + "id": "0x8014093787673513011ee2be28bc685a1df716abbe0d4d76173b0dbdc33d0557", + "key": { + "kty": "EC", + "alg": "ES256K", + "kid": "0x8014093787673513011ee2be28bc685a1df716abbe0d4d76173b0dbdc33d0557", + "crv": "secp256k1", + "x": "OA4p5YjB0XBUzMuE6qhSwcSCLDu-yf9VekwcE320fWw", + "y": "nLK5Qr_VHqZD9rVCLMHToXvdE9KuTn6w--PJ9jcpdUU" + } + }, + { + "userId": "test-dave-user-uid", + "id": "0x1d76eff4362bf8e292d5ceedcc89925cbef5f12dbdd2023c88887a863d444303", + "key": { + "kty": "EC", + "alg": "ES256K", + "kid": "0x1d76eff4362bf8e292d5ceedcc89925cbef5f12dbdd2023c88887a863d444303", + "crv": "secp256k1", + "x": "B8XJz6mktivOJjgyb3sRlSSaLQ4lfW0filHdLUzf37Q", + "y": "WUXcs1yEu8f9qBksL0y2psQ3yFDJtjRRJtNX9hGQplY" + } + }, + { + "userId": "test-antoine-user-uid", + "id": "0x6af10b6d5024963972ba832486ea1ae29f1b99cb1191abe444b52e98c69f7487", + "key": { + "kty": "EC", + "alg": "ES256K", + "kid": "0x6af10b6d5024963972ba832486ea1ae29f1b99cb1191abe444b52e98c69f7487", + "crv": "secp256k1", + "x": "QwUuAC2s22VKwoS5uPTZgcTN_ztkwt9VWKRae3bikEQ", + "y": "lZgwfE7ZDz9af9_PZxq9B7pVwAarfIaFESATYp-Q7Uk" + } + }, + { + "userId": "test-system-manager-user-uid", + "id": "0xbd810cd739d7304418dfa3c780c52ec0fdb970adbedda1cb2c8ef8c20ed3ef61", + "key": { + "kty": "EC", + "alg": "ES256K", + "kid": "0xbd810cd739d7304418dfa3c780c52ec0fdb970adbedda1cb2c8ef8c20ed3ef61", + "crv": "secp256k1", + "x": "jceVT-Wge27mz_U2BHoj_Sq53nYs1GfMNlQanOwBD9g", + "y": "MdgW5_ZeJc9jb1UWwECrGGrFRb1HHk2uL9i1zsp52yI" + } + }, + { + "id": "0x000c0d191308A336356BEe3813CC17F6868972C4", + "userId": "test-root-user-uid", + "key": { + "kty": "EC", + "crv": "secp256k1", + "alg": "ES256K", + "kid": "0x000c0d191308A336356BEe3813CC17F6868972C4", + "addr": "0x000c0d191308A336356BEe3813CC17F6868972C4" + } + }, + { + "id": "0xaaA8EE1CbaA1856F4550c6fc24abb16C5c9b2a43", + "userId": "test-alice-user-uid", + "key": { + "kty": "EC", + "crv": "secp256k1", + "alg": "ES256K", + "kid": "0xaaA8EE1CbaA1856F4550c6fc24abb16C5c9b2a43", + "addr": "0xaaA8EE1CbaA1856F4550c6fc24abb16C5c9b2a43" + } + }, + { + "id": "0xbbB7bE636C3aD8CF9d08Ba8BDba4aBD2ef29BD23", + "userId": "test-bob-user-uid", + "key": { + "kty": "EC", + "crv": "secp256k1", + "alg": "ES256K", + "kid": "0xbbB7bE636C3aD8CF9d08Ba8BDba4aBD2ef29BD23", + "addr": "0xbbB7bE636C3aD8CF9d08Ba8BDba4aBD2ef29BD23" + } + }, + { + "id": "0xCCC1472FcE4eC74a1E3f9653776ACFc790cD0743", + "userId": "test-carol-user-uid", + "key": { + "kty": "EC", + "crv": "secp256k1", + "alg": "ES256K", + "kid": "0xCCC1472FcE4eC74a1E3f9653776ACFc790cD0743", + "addr": "0xCCC1472FcE4eC74a1E3f9653776ACFc790cD0743" + } + }, + { + "id": "0xddd26a02e7c54e8dc373b9d2DCb309ECdeCA815D", + "userId": "test-dave-user-uid", + "key": { + "kty": "EC", + "crv": "secp256k1", + "alg": "ES256K", + "kid": "0xddd26a02e7c54e8dc373b9d2DCb309ECdeCA815D", + "addr": "0xddd26a02e7c54e8dc373b9d2DCb309ECdeCA815D" + } + }, + { + "id": "0xeee7798380DF797a12B459BA0d4d48cBa8e66B37", + "userId": "test-antoine-user-uid", + "key": { + "kty": "EC", + "crv": "secp256k1", + "alg": "ES256K", + "kid": "0xeee7798380DF797a12B459BA0d4d48cBa8e66B37", + "addr": "0xeee7798380DF797a12B459BA0d4d48cBa8e66B37" + } + }, + { + "id": "0xfffFA973C351Df1BE703dA81b0C6BE08Abc51500", + "userId": "test-system-manager-user-uid", + "key": { + "kty": "EC", + "crv": "secp256k1", + "alg": "ES256K", + "kid": "0xfffFA973C351Df1BE703dA81b0C6BE08Abc51500", + "addr": "0xfffFA973C351Df1BE703dA81b0C6BE08Abc51500" + } + } + ], + "tokens": [ + { + "id": "eip155:1/erc20:0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48", + "address": "0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48", + "chainId": 1, + "symbol": "USDC", + "decimals": 6 + }, + { + "id": "eip155:137/erc20:0x2791bca1f2de4661ed88a30c99a7a9449aa84174", + "address": "0x2791bca1f2de4661ed88a30c99a7a9449aa84174", + "chainId": 137, + "symbol": "USDC", + "decimals": 6 + } + ], + "userGroupMembers": [ + { + "groupId": "test-engineering-user-group-uid", + "userId": "test-alice-user-uid" + }, + { + "groupId": "test-engineering-user-group-uid", + "userId": "test-carol-user-uid" + }, + { + "groupId": "test-treasury-user-group-uid", + "userId": "test-bob-user-uid" + }, + { + "groupId": "test-treasury-user-group-uid", + "userId": "test-antoine-user-uid" + }, + { + "groupId": "test-treasury-user-group-uid", + "userId": "test-dave-user-uid" + } + ], + "userGroups": [ + { + "id": "test-engineering-user-group-uid" + }, + { + "id": "test-treasury-user-group-uid" + } + ], + "userAccounts": [ + { + "accountId": "eip155:eoa:0x76d1b7f9b3F69C435eeF76a98A415332084A856F", + "userId": "test-alice-user-uid" + }, + { + "accountId": "eip155:eoa:0x0f610AC9F0091f8F573c33f15155afE8aD747495", + "userId": "test-alice-user-uid" + }, + { + "accountId": "eip155:eoa:0x0301e2724a40E934Cce3345928b88956901aA127", + "userId": "test-alice-user-uid" + } + ], + "users": [ + { + "id": "test-root-user-uid", + "role": "root" + }, + { + "id": "test-alice-user-uid", + "role": "admin" + }, + { + "id": "test-bob-user-uid", + "role": "admin" + }, + { + "id": "test-carol-user-uid", + "role": "manager" + }, + { + "id": "test-dave-user-uid", + "role": "member" + }, + { + "id": "test-antoine-user-uid", + "role": "member" + }, + { + "id": "test-system-manager-user-uid", + "role": "manager" + } + ], + "accountGroupMembers": [ + { + "groupId": "test-engineering-account-group-uid", + "accountId": "eip155:eoa:0x9f38879167acCf7401351027EE3f9247A71cd0c5" + }, + { + "groupId": "test-engineering-account-group-uid", + "accountId": "eip155:eoa:0x0f610AC9F0091f8F573c33f15155afE8aD747495" + }, + { + "groupId": "test-treasury-account-group-uid", + "accountId": "eip155:eoa:0x0301e2724a40E934Cce3345928b88956901aA127" + }, + { + "groupId": "test-treasury-account-group-uid", + "accountId": "eip155:eoa:0x76d1b7f9b3F69C435eeF76a98A415332084A856F" + } + ], + "accountGroups": [ + { + "id": "test-engineering-account-group-uid" + }, + { + "id": "test-treasury-account-group-uid" + } + ], + "accounts": [ + { + "id": "eip155:eoa:0x0f610AC9F0091f8F573c33f15155afE8aD747495", + "address": "0x0f610AC9F0091f8F573c33f15155afE8aD747495", + "accountType": "eoa" + }, + { + "id": "eip155:eoa:0x9f38879167acCf7401351027EE3f9247A71cd0c5", + "address": "0x9f38879167acCf7401351027EE3f9247A71cd0c5", + "accountType": "eoa" + }, + { + "id": "eip155:eoa:0x0301e2724a40E934Cce3345928b88956901aA127", + "address": "0x0301e2724a40E934Cce3345928b88956901aA127", + "accountType": "eoa" + }, + { + "id": "eip155:eoa:0x76d1b7f9b3F69C435eeF76a98A415332084A856F", + "address": "0x76d1b7f9b3F69C435eeF76a98A415332084A856F", + "accountType": "eoa" + } + ] +} diff --git a/packages/armory-sdk/src/resource/policy/set/defi-interaction.json b/packages/armory-sdk/src/resource/policy/set/defi-interaction.json new file mode 100644 index 000000000..007f68ad2 --- /dev/null +++ b/packages/armory-sdk/src/resource/policy/set/defi-interaction.json @@ -0,0 +1,67 @@ +[ + { + "id": "1-uniswap-trader-permissions", + "description": "Uniswap traders can sign messages using trading accounts", + "when": [ + { + "criterion": "checkPrincipalGroup", + "args": ["uniswap-traders"] + }, + { + "criterion": "checkAccountGroup", + "args": ["uniswap-trading-accounts"] + }, + { + "criterion": "checkAction", + "args": ["signMessage"] + } + ], + "then": "permit" + }, + { + "id": "2-uniswap-trader-permit", + "description": "Uniswap traders can permit using trading accounts", + "when": [ + { + "criterion": "checkPrincipalGroup", + "args": ["uniswap-traders"] + }, + { + "criterion": "checkAccountGroup", + "args": ["uniswap-trading-accounts"] + }, + { + "criterion": "checkIntentType", + "args": ["permit", "permit2"] + } + ], + "then": "permit" + }, + { + "id": "3-uniswap-interaction-control", + "description": "Uniswap traders can call specific Uniswap functions on uniswap protocol using uniswap trading accounts", + "when": [ + { + "criterion": "checkPrincipalGroup", + "args": ["uniswap-traders"] + }, + { + "criterion": "checkAccountGroup", + "args": ["uniswap-trading-accounts"] + }, + { + "criterion": "checkIntentType", + "args": ["callContract"] + }, + { + "criterion": "checkIntentHexSignature", + "args": ["0xac9650d8", "0x3593564c"] + }, + { + "criterion": "checkIntentContract", + "args": ["eip155:1:0x3fc91a3afd70395cd496c647d5a6cc9d4b2b7fad"] + } + ], + "then": "permit" + } +] diff --git a/packages/transaction-request-intent/src/lib/decoders/decode.ts b/packages/transaction-request-intent/src/lib/decoders/decode.ts index dccab85a7..aa75b9163 100644 --- a/packages/transaction-request-intent/src/lib/decoders/decode.ts +++ b/packages/transaction-request-intent/src/lib/decoders/decode.ts @@ -5,6 +5,7 @@ import { DecodeInput, InputType, Intents, + PERMIT2_DOMAIN, SafeDecodeOutput, TransactionCategory, TransactionInput, @@ -123,19 +124,14 @@ const wrapTransactionManagementIntents = ( const decodeTypedDataInput = (input: TypedDataInput): TypedDataIntent => { const { typedData } = input - const { primaryType } = typedData - switch (primaryType) { - case 'Permit2': { - const decoded = decodePermit2(typedData) - return decoded || decodeTypedData(typedData) - } - case 'Permit': { - const decoded = decodePermit(typedData) - return decoded || decodeTypedData(typedData) - } - default: - return decodeTypedData(typedData) + const { primaryType, domain } = typedData + if (domain.name === PERMIT2_DOMAIN.name) { + return decodePermit2(typedData) || decodeTypedData(typedData) + } + if (primaryType === 'Permit') { + return decodePermit(typedData) || decodeTypedData(typedData) } + return decodeTypedData(typedData) } const decode = ({ input, config = defaultConfig }: { input: DecodeInput; config?: Config }): Intent => {