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

Feature/refactor lib #84

Merged
merged 7 commits into from
Feb 7, 2024
Merged
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
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
}
})
Comment on lines +67 to 72
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do you think something like this would be possible?

Suggested change
const result = safeDecode({
input: {
type: InputType.TRANSACTION_REQUEST,
txRequest: authzRequest.request.transactionRequest
}
})
const result = safeDecode(authzRequest.request.transactionRequest)
// or
const result = safeDecode(authzRequest.request.message)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I guess it wouldn't be.

If you look at the shape of the safeDecode input, it's like so:
{ input, config = defaultConfig }: { input: DecodeInput; config?: Config }

config include all the user trustworthy data that will be used to decode the input.

  • transaction registry
  • contract registry
  • set of supported methods and their decoder (default to my current set)

What is doable is determining the InputType, and then do something like this:

safeDecode({ input })

Or

safeDecode({ input, config })


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