Skip to content

Commit

Permalink
base sdk
Browse files Browse the repository at this point in the history
  • Loading branch information
Ptroger committed May 2, 2024
1 parent 44dce44 commit cc37b76
Show file tree
Hide file tree
Showing 21 changed files with 2,737 additions and 3,642 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -135,10 +135,7 @@ const PlaygroundEditor = () => {
<div className="pt-4">
<h3 className="pb-4">Examples</h3>
<div className="flex gap-5 ">
<NarButton
label="ERC-20"
onClick={async () => setCodeEditor(JSON.stringify(await erc20(), null, 2))}
/>
<NarButton label="ERC-20" onClick={async () => setCodeEditor(JSON.stringify(await erc20(), null, 2))} />
<NarButton
label="Spending limits"
onClick={async () => setCodeEditor(JSON.stringify(await spendingLimits(), null, 2))}
Expand Down
5,811 changes: 2,173 additions & 3,638 deletions package-lock.json

Large diffs are not rendered by default.

6 changes: 6 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
"@nestjs/testing": "^10.0.2",
"@nx-plus/docusaurus": "^15.0.0-rc.0",
"@nx/devkit": "17.1.3",
"@nx/esbuild": "17.1.3",
"@nx/eslint": "18.1.3",
"@nx/eslint-plugin": "17.2.8",
"@nx/jest": "17.1.3",
Expand Down Expand Up @@ -44,6 +45,7 @@
"autoprefixer": "^10.4.19",
"babel-jest": "^29.4.1",
"dotenv-cli": "^7.3.0",
"esbuild": "^0.19.2",
"eslint": "~8.56.0",
"eslint-config-next": "14.0.4",
"eslint-config-prettier": "^9.0.0",
Expand Down Expand Up @@ -71,6 +73,7 @@
"ts-node": "10.9.1",
"tsc-alias": "^1.8.8",
"typescript": "^5.3.3",
"verdaccio": "^5.0.4",
"zod-fixture": "^2.5.1"
},
"dependencies": {
Expand Down Expand Up @@ -126,5 +129,8 @@
"viem": "^2.7.16",
"wagmi": "^2.5.7",
"zod": "^3.22.4"
},
"nx": {
"includedScripts": []
}
}
25 changes: 25 additions & 0 deletions packages/armory-sdk/.eslintrc.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
{
"extends": ["../../.eslintrc.json"],
"ignorePatterns": ["!**/*"],
"overrides": [
{
"files": ["*.ts", "*.tsx", "*.js", "*.jsx"],
"rules": {}
},
{
"files": ["*.ts", "*.tsx"],
"rules": {}
},
{
"files": ["*.js", "*.jsx"],
"rules": {}
},
{
"files": ["*.json"],
"parser": "jsonc-eslint-parser",
"rules": {
"@nx/dependency-checks": "error"
}
}
]
}
11 changes: 11 additions & 0 deletions packages/armory-sdk/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
# armory-sdk

This library was generated with [Nx](https://nx.dev).

## Building

Run `nx build armory-sdk` to build the library.

## Running unit tests

Run `nx test armory-sdk` to execute the unit tests via [Jest](https://jestjs.io).
11 changes: 11 additions & 0 deletions packages/armory-sdk/jest.config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
/* eslint-disable */
export default {
displayName: 'armory-sdk',
preset: '../../jest.preset.js',
testEnvironment: 'node',
transform: {
'^.+\\.[tj]s$': ['ts-jest', { tsconfig: '<rootDir>/tsconfig.spec.json' }]
},
moduleFileExtensions: ['ts', 'js', 'html'],
coverageDirectory: '../../coverage/packages/armory-sdk'
}
11 changes: 11 additions & 0 deletions packages/armory-sdk/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
{
"name": "@narval/armory-sdk",
"version": "0.0.1",
"dependencies": {
"axios": "^1.6.7",
"tslib": "^2.3.0",
"uuid": "^9.0.1",
"viem": "^2.7.16",
"zod": "^3.22.4"
}
}
30 changes: 30 additions & 0 deletions packages/armory-sdk/project.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
{
"name": "armory-sdk",
"$schema": "../../node_modules/nx/schemas/project-schema.json",
"sourceRoot": "packages/armory-sdk/src",
"projectType": "library",
"targets": {
"lint": {
"executor": "@nx/eslint:lint",
"outputs": ["{options.outputFile}"],
"options": {
"lintFilePatterns": ["packages/armory-sdk/**/*.ts"]
}
},
"test:type": {
"executor": "nx:run-commands",
"options": {
"command": "make sdk/test/type"
}
},
"test:unit": {
"executor": "@nx/jest:jest",
"outputs": ["{workspaceRoot}/coverage/{projectRoot}"],
"options": {
"jestConfig": "packages/armory-sdk/jest.unit.ts",
"verbose": true
}
}
},
"tags": ["package"]
}
1 change: 1 addition & 0 deletions packages/armory-sdk/src/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export * from './lib/evaluate'
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import { armorySdk } from '../../api-call'

describe('armorySdk', () => {
it('should work', () => {
expect(armorySdk()).toEqual('armory-sdk')
})
})
73 changes: 73 additions & 0 deletions packages/armory-sdk/src/lib/domain.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
import { AccessToken, Decision, Request, addressSchema, hexSchema } from '@narval/policy-engine-shared'
import { jwkSchema } from '@narval/signature'
import { z } from 'zod'

export const Endpoints = {
engine: {
evaluations: '/evaluations'
},
vault: {
sign: '/sign',
importPrivateKey: '/import/private-key'
}
} as const
export type Endpoints = (typeof Endpoints)[keyof typeof Endpoints]

export const ArmoryClientConfigInput = z.object({
authHost: z.string().optional(),
authSecret: z.string().optional(),
vaultHost: z.string().optional(),
vaultSecret: z.string().optional(),
entityStoreHost: z.string().optional(),
policyStoreHost: z.string().optional(),
authClientId: z.string().optional(),
vaultClientId: z.string().optional(),
signer: jwkSchema
})
export type ArmoryClientConfigInput = z.infer<typeof ArmoryClientConfigInput>

export const ArmoryClientConfig = z.object({
authHost: z.string(),
authSecret: z.string(),
vaultHost: z.string(),
vaultSecret: z.string(),
entityStoreHost: z.string(),
policyStoreHost: z.string(),
authClientId: z.string(),
vaultClientId: z.string(),
signer: jwkSchema
})
export type ArmoryClientConfig = z.infer<typeof ArmoryClientConfig>

export const SdkPermitResponse = z.object({
decision: z.literal(Decision.PERMIT),
accessToken: AccessToken,
request: Request.optional()
})
export type SdkPermitResponse = z.infer<typeof SdkPermitResponse>

export const SdkEvaluationResponse = z.discriminatedUnion('decision', [SdkPermitResponse])
export type SdkEvaluationResponse = z.infer<typeof SdkEvaluationResponse>

export const ImportPrivateKeyRequest = z.object({
privateKey: hexSchema,
walletId: z.string().optional()
})
export type ImportPrivateKeyRequest = z.infer<typeof ImportPrivateKeyRequest>

export const ImportPrivateKeyResponse = z.object({
walletId: z.string(),
address: addressSchema
})
export type ImportPrivateKeyResponse = z.infer<typeof ImportPrivateKeyResponse>

export const SignatureRequest = z.object({
request: Request,
accessToken: AccessToken
})
export type SignatureRequest = z.infer<typeof SignatureRequest>

export const SignatureResponse = z.object({
signature: hexSchema
})
export type SignatureResponse = z.infer<typeof SignatureResponse>
35 changes: 35 additions & 0 deletions packages/armory-sdk/src/lib/exceptions.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
export class NarvalSdkException extends Error {
context: Record<string, unknown>
constructor(message: string, context: Record<string, unknown> = {}) {
super(message)
this.name = 'NarvalSdkException'
this.context = context
}
}

export class ConfigurationException extends NarvalSdkException {
constructor(message: string, context: Record<string, unknown> = {}) {
super(message, context)
this.name = 'ConfigurationException'
}
}

export class ForbiddenException extends NarvalSdkException {
code: number

constructor(message: string, context: Record<string, unknown> = {}, suggestedHttpCode: number = 403) {
super(message, context)
this.code = suggestedHttpCode
this.name = 'ForbiddenException'
}
}

export class NotImplementedException extends NarvalSdkException {
code: number

constructor(message: string, context: Record<string, unknown> = {}, suggestedHttpCode: number = 501) {
super(message, context)
this.code = suggestedHttpCode
this.name = 'NotImplementedError'
}
}
18 changes: 18 additions & 0 deletions packages/armory-sdk/src/lib/http/engine.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import {
EvaluationResponse,
SerializedEvaluationRequest,
SerializedEvaluationResponse
} from '@narval/policy-engine-shared'
import axios from 'axios'
import { SendEvaluationRequest } from './schema'

export const sendEvaluationRequest = async (input: SendEvaluationRequest): Promise<EvaluationResponse> => {
const { uri, request, headers } = input

const serializedRequest = SerializedEvaluationRequest.parse(request)
const { data } = await axios.post<SerializedEvaluationResponse>(uri, serializedRequest, {
headers
})

return EvaluationResponse.parse(data)
}
37 changes: 37 additions & 0 deletions packages/armory-sdk/src/lib/http/schema.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
import { EvaluationRequest, Request } from '@narval/policy-engine-shared'
import { z } from 'zod'
import { ImportPrivateKeyRequest } from '../domain'

export const BasicHeaders = z.object({
'x-client-id': z.string(),
'x-client-secret': z.string()
})
export type BasicHeaders = z.infer<typeof BasicHeaders>

export const SignatureRequestHeaders = z.object({
'x-client-id': z.string(),
'detached-jws': z.string(),
authorization: z.string().startsWith('GNAP ')
})
export type SignatureRequestHeaders = z.infer<typeof SignatureRequestHeaders>

export const SendSignatureRequest = z.object({
uri: z.string(),
headers: SignatureRequestHeaders,
request: Request
})
export type SendSignatureRequest = z.infer<typeof SendSignatureRequest>

export const SendImportPrivateKey = z.object({
request: ImportPrivateKeyRequest,
uri: z.string(),
headers: BasicHeaders
})
export type SendImportPrivateKey = z.infer<typeof SendImportPrivateKey>

export const SendEvaluationRequest = z.object({
request: EvaluationRequest,
uri: z.string(),
headers: BasicHeaders
})
export type SendEvaluationRequest = z.infer<typeof SendEvaluationRequest>
27 changes: 27 additions & 0 deletions packages/armory-sdk/src/lib/http/vault.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import { SerializedRequest } from '@narval/policy-engine-shared'
import axios from 'axios'
import { ImportPrivateKeyResponse, SignatureResponse } from '../domain'
import { SendImportPrivateKey, SendSignatureRequest } from './schema'

export const sendSignatureRequest = async (input: SendSignatureRequest): Promise<SignatureResponse> => {
const { uri, headers, request } = input
const serializedRequest = SerializedRequest.parse(request)
const { data } = await axios.post(
uri,
{ request: serializedRequest },
{
headers
}
)

return data.signature
}

export const sendImportPrivateKey = async (input: SendImportPrivateKey): Promise<ImportPrivateKeyResponse> => {
const { uri, headers, request } = input

const { data } = await axios.post(uri, request, {
headers
})
return data
}
Loading

0 comments on commit cc37b76

Please sign in to comment.