Skip to content

Commit

Permalink
Feature/refactor lib (#84)
Browse files Browse the repository at this point in the history
* changed interface

* changed intent naming, changed usage of lib in apps

* format and lint

* Update rego criteria

* changed interface

* used decoderErros

* fix

---------

Co-authored-by: samuel <samuel@narval.xyz>
  • Loading branch information
Ptroger and samteb authored Feb 7, 2024
1 parent e94d238 commit bbf8d61
Show file tree
Hide file tree
Showing 32 changed files with 1,053 additions and 788 deletions.
11 changes: 6 additions & 5 deletions apps/authz/src/app/app.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,8 @@ import {
Signature,
hashRequest
} from '@narval/authz-shared'
import { safeDecode } from '@narval/transaction-request-intent'
import { Injectable } from '@nestjs/common'
import { Decoder } from 'packages/transaction-request-intent/src'
import { InputType } from 'packages/transaction-request-intent/src/lib/domain'
import { Intent } from 'packages/transaction-request-intent/src/lib/intent.types'
import { Hex, verifyMessage } from 'viem'
Expand Down Expand Up @@ -147,7 +147,6 @@ export class AppService {
}: EvaluationRequest): Promise<EvaluationResponse> {
// Pre-Process
// verify the signatures of the Principal and any Approvals
const decoder = new Decoder()
const verificationMessage = hashRequest(request)

const principalCredential = await this.#verifySignature(authentication, verificationMessage)
Expand All @@ -157,9 +156,11 @@ export class AppService {
// Decode the intent
const intentResult =
request.action === Action.SIGN_TRANSACTION
? decoder.safeDecode({
type: InputType.TRANSACTION_REQUEST,
txRequest: request.transactionRequest
? safeDecode({
input: {
type: InputType.TRANSACTION_REQUEST,
txRequest: request.transactionRequest
}
})
: undefined

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,14 @@ package main

test_permit {
permitRequest = {
"action": "signTransaction",
"action": "signTypedData",
"resource": {"uid": "eip155:eoa:0xddcf208f219a6e6af072f2cfdc615b2c1805f98e"},
"intent": {
"type": "permit",
"from": "eip155:eoa:0xddcf208f219a6e6af072f2cfdc615b2c1805f98e",
"spender": "eip155:137:0xa45e21e9370ba031c5e1f47dedca74a7ce2ed7a3",
"token": "eip155:137/erc20:0x2791bca1f2de4661ed88a30c99a7a9449aa84174",
"amount": "1000000000000000000",
"deadline": "1634025600", # in ms
"deadline": 1634025600, # in ms
},
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ test_checkSignMessage {
"action": "signMessage",
"resource": {"uid": "eip155:eoa:0xddcf208f219a6e6af072f2cfdc615b2c1805f98e"},
"intent": {
"from": "eip155:eoa:0xddcf208f219a6e6af072f2cfdc615b2c1805f98e",
"type": "signMessage",
"message": "Hello world!",
},
Expand All @@ -32,9 +31,9 @@ test_checkSignRawPayload {
"action": "signRaw",
"resource": {"uid": "eip155:eoa:0xddcf208f219a6e6af072f2cfdc615b2c1805f98e"},
"intent": {
"from": "eip155:eoa:0xddcf208f219a6e6af072f2cfdc615b2c1805f98e",
"type": "signRawPayload",
"payload": "Hello world!",
"algorithm": "ES256K",
},
}

Expand All @@ -52,14 +51,15 @@ test_checkSignRawPayload {

checkIntentPayload({"operator": operators.contains, "value": "Hello"}) with input as signRawPayloadRequest
with data.entities as entities

checkIntentAlgorithm({"ES256K"}) with input as signRawPayloadRequest with data.entities as entities
}

test_checkSignTypedData {
signTypedDataRequest = {
"action": "signTypedData",
"resource": {"uid": "eip155:eoa:0xddcf208f219a6e6af072f2cfdc615b2c1805f98e"},
"intent": {
"from": "eip155:eoa:0xddcf208f219a6e6af072f2cfdc615b2c1805f98e",
"type": "signTypedData",
"domain": {
"version": "2",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ test_transferERC721 {
"to": "eip155:137:0xa45e21e9370ba031c5e1f47dedca74a7ce2ed7a3",
"type": "transferERC721",
"contract": "eip155:137/erc721:0x08a08d0504d4f3363a5b7fda1f5fff1c7bca8ad4",
"nftId": "eip155:137/erc721:0x08a08d0504d4f3363a5b7fda1f5fff1c7bca8ad4/41173",
"token": "eip155:137/erc721:0x08a08d0504d4f3363a5b7fda1f5fff1c7bca8ad4/41173",
},
}

Expand Down Expand Up @@ -40,15 +40,15 @@ test_transferERC1155 {
"contract": "eip155:137/erc1155:0x08a08d0504d4f3363a5b7fda1f5fff1c7bca8ad4",
"transfers": [
{
"tokenId": "eip155:137/erc1155:0x08a08d0504d4f3363a5b7fda1f5fff1c7bca8ad4/41173",
"token": "eip155:137/erc1155:0x08a08d0504d4f3363a5b7fda1f5fff1c7bca8ad4/41173",
"amount": "1",
},
{
"tokenId": "eip155:137/erc1155:0x08a08d0504d4f3363a5b7fda1f5fff1c7bca8ad4/44444",
"token": "eip155:137/erc1155:0x08a08d0504d4f3363a5b7fda1f5fff1c7bca8ad4/44444",
"amount": "2",
},
{
"tokenId": "eip155:137/erc1155:0x08a08d0504d4f3363a5b7fda1f5fff1c7bca8ad4/55555",
"token": "eip155:137/erc1155:0x08a08d0504d4f3363a5b7fda1f5fff1c7bca8ad4/55555",
"amount": "5",
},
],
Expand All @@ -74,22 +74,17 @@ test_transferERC1155 {
with data.entities as entities

checkERC1155Transfers([
{"tokenId": "eip155:137/erc1155:0x08a08d0504d4f3363a5b7fda1f5fff1c7bca8ad4/55555", "operator": "lt", "value": "2"},
{"tokenId": "eip155:137/erc1155:0x08a08d0504d4f3363a5b7fda1f5fff1c7bca8ad4/44444", "operator": "lt", "value": "2"},
{"tokenId": "eip155:137/erc1155:0x08a08d0504d4f3363a5b7fda1f5fff1c7bca8ad4/41173", "operator": "lt", "value": "2"},
{"token": "eip155:137/erc1155:0x08a08d0504d4f3363a5b7fda1f5fff1c7bca8ad4/41173", "operator": "lt", "value": "2"},
{"token": "eip155:137/erc1155:0x08a08d0504d4f3363a5b7fda1f5fff1c7bca8ad4/44444", "operator": "lt", "value": "3"},
{"token": "eip155:137/erc1155:0x08a08d0504d4f3363a5b7fda1f5fff1c7bca8ad4/55555", "operator": "lt", "value": "6"},
]) with input as erc1155Request with data.entities as entities
}

test_checkERC1155TokenAmount {
checkERC1155TokenAmount("1", {"tokenId": "eip155:137/erc1155:0x08a08d0504d4f3363a5b7fda1f5fff1c7bca8ad4/41173", "operator": operators.notEqual, "value": "2"})
checkERC1155TokenAmount("1", {"tokenId": "eip155:137/erc1155:0x08a08d0504d4f3363a5b7fda1f5fff1c7bca8ad4/41173", "operator": operators.equal, "value": "1"})
checkERC1155TokenAmount("5", {"tokenId": "eip155:137/erc1155:0x08a08d0504d4f3363a5b7fda1f5fff1c7bca8ad4/41173", "operator": operators.greaterThanOrEqual, "value": "4"})
checkERC1155TokenAmount("3", {"tokenId": "eip155:137/erc1155:0x08a08d0504d4f3363a5b7fda1f5fff1c7bca8ad4/41173", "operator": operators.lessThanOrEqual, "value": "5"})
checkERC1155TokenAmount("5", {"tokenId": "eip155:137/erc1155:0x08a08d0504d4f3363a5b7fda1f5fff1c7bca8ad4/41173", "operator": operators.greaterThan, "value": "3"})
checkERC1155TokenAmount("3", {"tokenId": "eip155:137/erc1155:0x08a08d0504d4f3363a5b7fda1f5fff1c7bca8ad4/41173", "operator": operators.lessThan, "value": "5"})
}

test_extractTokenIdFromCaip19 {
res := extractTokenIdFromCaip19("eip155:137/erc1155:0x08a08d0504d4f3363a5b7fda1f5fff1c7bca8ad4/55555")
res == "55555"
checkERC1155TokenAmount("1", {"token": "eip155:137/erc1155:0x08a08d0504d4f3363a5b7fda1f5fff1c7bca8ad4/41173", "operator": operators.notEqual, "value": "2"})
checkERC1155TokenAmount("1", {"token": "eip155:137/erc1155:0x08a08d0504d4f3363a5b7fda1f5fff1c7bca8ad4/41173", "operator": operators.equal, "value": "1"})
checkERC1155TokenAmount("5", {"token": "eip155:137/erc1155:0x08a08d0504d4f3363a5b7fda1f5fff1c7bca8ad4/41173", "operator": operators.greaterThanOrEqual, "value": "4"})
checkERC1155TokenAmount("3", {"token": "eip155:137/erc1155:0x08a08d0504d4f3363a5b7fda1f5fff1c7bca8ad4/41173", "operator": operators.lessThanOrEqual, "value": "5"})
checkERC1155TokenAmount("5", {"token": "eip155:137/erc1155:0x08a08d0504d4f3363a5b7fda1f5fff1c7bca8ad4/41173", "operator": operators.greaterThan, "value": "3"})
checkERC1155TokenAmount("3", {"token": "eip155:137/erc1155:0x08a08d0504d4f3363a5b7fda1f5fff1c7bca8ad4/41173", "operator": operators.lessThan, "value": "5"})
}
6 changes: 6 additions & 0 deletions apps/authz/src/opa/rego/__test__/criteria/resource_test.rego
Original file line number Diff line number Diff line change
Expand Up @@ -36,3 +36,9 @@ test_resource {
checkWalletGroup({"test-wallet-group-one-uid"}) with input as request
with data.entities as entities
}

test_extractAddressFromCaip10 {
address = extractAddressFromCaip10("eip155:eoa:0xddcf208f219a6e6af072f2cfdc615b2c1805f98e")

address == "0xddcf208f219a6e6af072f2cfdc615b2c1805f98e"
}
2 changes: 1 addition & 1 deletion apps/authz/src/opa/rego/__test__/main_test.rego
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ intentReq = {
"type": "transferERC20",
"from": "eip155:eoa:0xddcf208f219a6e6af072f2cfdc615b2c1805f98e",
"to": "eip155:137:0xa45e21e9370ba031c5e1f47dedca74a7ce2ed7a3",
"contract": "eip155:137/erc20:0x2791bca1f2de4661ed88a30c99a7a9449aa84174",
"token": "eip155:137/erc20:0x2791bca1f2de4661ed88a30c99a7a9449aa84174",
"amount": "1000000000000000000",
}

Expand Down
69 changes: 38 additions & 31 deletions apps/authz/src/opa/rego/lib/criteria/intent/transferNft.rego
Original file line number Diff line number Diff line change
Expand Up @@ -2,52 +2,59 @@ package main

import future.keywords.in

checkERC721TokenId(values) = input.intent.nftId in values
intentTransfers = input.intent.transfers

checkERC721TokenId(values) = input.intent.token in values

checkERC1155TokenId(values) {
transfer = input.intent.transfers[_]
transfer.tokenId in values
transfer = intentTransfers[_]
transfer.token in values
}

checkERC1155TokenAmount(amount, operation) {
operation.operator == operators.equal
to_number(operation.value) == to_number(amount)
checkERC1155TokenAmount(amount, condition) {
condition.operator == operators.equal
to_number(condition.value) == to_number(amount)
}

checkERC1155TokenAmount(amount, operation) {
operation.operator == operators.notEqual
to_number(operation.value) != to_number(amount)
checkERC1155TokenAmount(amount, condition) {
condition.operator == operators.notEqual
to_number(condition.value) != to_number(amount)
}

checkERC1155TokenAmount(amount, operation) {
operation.operator == operators.greaterThan
to_number(operation.value) < to_number(amount)
checkERC1155TokenAmount(amount, condition) {
condition.operator == operators.greaterThan
to_number(condition.value) < to_number(amount)
}

checkERC1155TokenAmount(amount, operation) {
operation.operator == operators.lessThan
to_number(operation.value) > to_number(amount)
checkERC1155TokenAmount(amount, condition) {
condition.operator == operators.lessThan
to_number(condition.value) > to_number(amount)
}

checkERC1155TokenAmount(amount, operation) {
operation.operator == operators.greaterThanOrEqual
to_number(operation.value) <= to_number(amount)
checkERC1155TokenAmount(amount, condition) {
condition.operator == operators.greaterThanOrEqual
to_number(condition.value) <= to_number(amount)
}

checkERC1155TokenAmount(amount, operation) {
operation.operator == operators.lessThanOrEqual
to_number(operation.value) >= to_number(amount)
checkERC1155TokenAmount(amount, condition) {
condition.operator == operators.lessThanOrEqual
to_number(condition.value) >= to_number(amount)
}

# Ex: operations = [{ "tokenId": "1", "operator": "eq", "value": "1" }, {"tokenId": "2", operator": "lte", "value": "10"}]
checkERC1155Transfers(operations) {
input.intent.transfers[t].tokenId == operations[o].tokenId
transfer = input.intent.transfers[t]
operation = operations[o]
checkERC1155TokenAmount(transfer.amount, operation)
}
checkERC1155Transfers(conditions) {
matches = [e |
some transfer in intentTransfers
some condition in conditions
transfer.token == condition.token
e = [transfer, condition]
]

validTransfers = [transfer |
some m in matches
transfer = m[0]
condition = m[1]
checkERC1155TokenAmount(transfer.amount, condition)
]

extractTokenIdFromCaip19(caip19) = result {
arr = split(caip19, "/")
result = arr[count(arr) - 1]
count(intentTransfers) == count(validTransfers)
}
9 changes: 6 additions & 3 deletions apps/authz/src/opa/rego/policies/approvals.rego
Original file line number Diff line number Diff line change
Expand Up @@ -14,12 +14,13 @@ permit[{"policyId": "approvalByUsers"}] = reason {
"entityIds": ["test-bob-uid", "test-bar-uid"],
}]

checkTransferResourceIntegrity
checkPrincipal
checkNonceExists
checkAction({"signTransaction"})
checkWalletId(resources)
checkIntentType(transferTypes)
checkIntentContract(tokens)
checkIntentToken(tokens)
checkIntentAmount(transferValueCondition)

approvals = checkApprovals(approvalsRequired)
Expand All @@ -44,12 +45,13 @@ permit[{"policyId": "approvalByUserGroups"}] = reason {
"entityIds": ["test-user-group-one-uid"],
}]

checkTransferResourceIntegrity
checkPrincipal
checkNonceExists
checkAction({"signTransaction"})
checkWalletId(resources)
checkIntentType(transferTypes)
checkIntentContract(tokens)
checkIntentToken(tokens)
checkIntentAmount(transferValueCondition)

approvals = checkApprovals(approvalsRequired)
Expand All @@ -74,12 +76,13 @@ permit[{"policyId": "approvalByUserRoles"}] = reason {
"entityIds": ["root", "admin"],
}]

checkTransferResourceIntegrity
checkPrincipal
checkNonceExists
checkAction({"signTransaction"})
checkWalletId(resources)
checkIntentType(transferTypes)
checkIntentContract(tokens)
checkIntentToken(tokens)
checkIntentAmount(transferValueCondition)

approvals = checkApprovals(approvalsRequired)
Expand Down
9 changes: 7 additions & 2 deletions apps/authz/src/opa/rego/policies/spendings.rego
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,13 @@ forbid[{"policyId": "spendingLimitByRole"}] = reason {
currency = "fiat:usd"
limit = "5000000000"

checkTransferResourceIntegrity
checkPrincipal
checkNonceExists
checkAction({"signTransaction"})
checkPrincipalRole(roles)
checkIntentType(transferTypes)
checkIntentContract(tokens)
checkIntentToken(tokens)
checkSpendingLimit({
"limit": limit,
"currency": currency,
Expand Down Expand Up @@ -47,12 +48,13 @@ forbid[{"policyId": "spendingLimitByUser"}] = reason {
currency = "fiat:usd"
limit = "5000000000"

checkTransferResourceIntegrity
checkPrincipal
checkNonceExists
checkAction({"signTransaction"})
checkPrincipalId(users)
checkIntentType(transferTypes)
checkIntentContract(tokens)
checkIntentToken(tokens)
checkSpendingLimit({
"limit": limit,
"currency": currency,
Expand All @@ -79,6 +81,7 @@ forbid[{"policyId": "spendingLimitByWalletResource"}] = reason {
currency = "fiat:usd"
limit = "5000000000"

checkTransferResourceIntegrity
checkPrincipal
checkNonceExists
checkAction({"signTransaction"})
Expand Down Expand Up @@ -110,6 +113,7 @@ forbid[{"policyId": "spendingLimitByUserGroup"}] = reason {
currency = "fiat:usd"
limit = "5000000000"

checkTransferResourceIntegrity
checkPrincipal
checkNonceExists
checkAction({"signTransaction"})
Expand Down Expand Up @@ -140,6 +144,7 @@ forbid[{"policyId": "spendingLimitByWalletGroup"}] = reason {
currency = "fiat:usd"
limit = "5000000000"

checkTransferResourceIntegrity
checkPrincipal
checkNonceExists
checkAction({"signTransaction"})
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import { PriceService } from '@app/orchestration/price/core/service/price.servic
import { getChain } from '@app/orchestration/shared/core/lib/chains.lib'
import { Prices } from '@app/orchestration/shared/core/type/price.type'
import { Action, Alg, AssetId, Feed, Signature, hashRequest } from '@narval/authz-shared'
import { Decoder, InputType, Intents } from '@narval/transaction-request-intent'
import { InputType, Intents, safeDecode } from '@narval/transaction-request-intent'
import { Injectable } from '@nestjs/common'
import { ConfigService } from '@nestjs/config'
import { uniq } from 'lodash/fp'
Expand Down Expand Up @@ -64,9 +64,11 @@ export class PriceFeedService implements DataFeed<Prices> {

private getAssetIds(authzRequest: AuthorizationRequest): AssetId[] {
if (authzRequest.request.action === Action.SIGN_TRANSACTION) {
const result = new Decoder().safeDecode({
type: InputType.TRANSACTION_REQUEST,
txRequest: authzRequest.request.transactionRequest
const result = safeDecode({
input: {
type: InputType.TRANSACTION_REQUEST,
txRequest: authzRequest.request.transactionRequest
}
})

const chain = getChain(authzRequest.request.transactionRequest.chainId)
Expand Down
Loading

0 comments on commit bbf8d61

Please sign in to comment.