-
Notifications
You must be signed in to change notification settings - Fork 4
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Initial implementation of the Armory SDK (#241)
* base sdk * config getter * updated lock * working example with sdk * added makefile to sdk * removed unused package * re-installed packages to cleanup lock * remove unused test directory * add one true test * added unit tests on utils, narrowed necessary config for evaluate/signRequest functions * sdk with example for signMessage/Transaction/TypedData working * Update packages/armory-sdk/src/lib/exceptions.ts Co-authored-by: William Calderipe <wcalderipe@gmail.com> * Update packages/armory-sdk/src/lib/exceptions.ts Co-authored-by: William Calderipe <wcalderipe@gmail.com> * Remove console.log * Rename example project to armory-sdk-nodejs --------- Co-authored-by: William Calderipe <wcalderipe@gmail.com>
- Loading branch information
1 parent
363373d
commit de49b47
Showing
35 changed files
with
1,252 additions
and
3 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
{ | ||
"extends": ["../../.eslintrc.json"], | ||
"ignorePatterns": ["!**/*"], | ||
"overrides": [ | ||
{ | ||
"files": ["*.ts", "*.tsx", "*.js", "*.jsx"], | ||
"rules": {} | ||
}, | ||
{ | ||
"files": ["*.ts", "*.tsx"], | ||
"rules": {} | ||
}, | ||
{ | ||
"files": ["*.js", "*.jsx"], | ||
"rules": {} | ||
} | ||
] | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
/* eslint-disable */ | ||
export default { | ||
displayName: 'armory-sdk-nodejs', | ||
preset: '../../jest.preset.js', | ||
testEnvironment: 'node', | ||
transform: { | ||
'^.+\\.[tj]s$': ['ts-jest', { tsconfig: '<rootDir>/tsconfig.spec.json' }] | ||
}, | ||
moduleFileExtensions: ['ts', 'js', 'html'], | ||
coverageDirectory: '../../coverage/examples/armory-sdk-nodejs' | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,80 @@ | ||
{ | ||
"name": "armory-sdk-nodejs", | ||
"$schema": "../../node_modules/nx/schemas/project-schema.json", | ||
"sourceRoot": "examples/armory-sdk-nodejs/src", | ||
"projectType": "application", | ||
"targets": { | ||
"build": { | ||
"executor": "@nx/webpack:webpack", | ||
"outputs": ["{options.outputPath}"], | ||
"defaultConfiguration": "production", | ||
"options": { | ||
"target": "node", | ||
"compiler": "tsc", | ||
"outputPath": "dist/examples/armory-sdk-nodejs", | ||
"main": "examples/armory-sdk-nodejs/src/index.ts", | ||
"tsConfig": "examples/armory-sdk-nodejs/tsconfig.app.json", | ||
"webpackConfig": "examples/armory-sdk-nodejs/webpack.config.js" | ||
}, | ||
"configurations": { | ||
"development": {}, | ||
"production": {} | ||
} | ||
}, | ||
"serve": { | ||
"executor": "@nx/js:node", | ||
"defaultConfiguration": "development", | ||
"options": { | ||
"buildTarget": "armory-sdk-nodejs:build" | ||
}, | ||
"configurations": { | ||
"development": { | ||
"buildTarget": "armory-sdk-nodejs:build:development" | ||
}, | ||
"production": { | ||
"buildTarget": "armory-sdk-nodejs:build:production" | ||
} | ||
} | ||
}, | ||
"lint": { | ||
"executor": "@nx/eslint:lint", | ||
"outputs": ["{options.outputFile}"], | ||
"options": { | ||
"lintFilePatterns": ["examples/armory-sdk-nodejs/**/*.ts"] | ||
} | ||
}, | ||
"test:type": { | ||
"executor": "nx:run-commands", | ||
"options": { | ||
"command": "make basic-flow/test/type" | ||
} | ||
}, | ||
"test:unit": { | ||
"executor": "@nx/jest:jest", | ||
"outputs": ["{workspaceRoot}/coverage/{projectRoot}"], | ||
"options": { | ||
"jestConfig": "examples/armory-sdk-nodejs/jest.unit.ts", | ||
"verbose": true | ||
} | ||
}, | ||
"test:integration": { | ||
"executor": "@nx/jest:jest", | ||
"outputs": ["{workspaceRoot}/coverage/{projectRoot}"], | ||
"options": { | ||
"jestConfig": "examples/armory-sdk-nodejs/jest.integration.ts", | ||
"verbose": true, | ||
"runInBand": true | ||
} | ||
}, | ||
"test:e2e": { | ||
"executor": "@nx/jest:jest", | ||
"outputs": ["{workspaceRoot}/coverage/{projectRoot}"], | ||
"options": { | ||
"jestConfig": "examples/armory-sdk-nodejs/jest.e2e.ts", | ||
"verbose": true, | ||
"runInBand": true | ||
} | ||
} | ||
}, | ||
"tags": ["type:application"] | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,133 @@ | ||
/* eslint-disable no-console */ | ||
|
||
import { createArmoryConfig, evaluate, importPrivateKey, signRequest } from '@narval/armory-sdk' | ||
import { SignMessageAction, SignTransactionAction, SignTypedDataAction } from '@narval/policy-engine-shared' | ||
import { privateKeyToJwk } from '@narval/signature' | ||
import { resourceId } from 'packages/armory-sdk/src/lib/utils' | ||
import { UNSAFE_PRIVATE_KEY } from 'packages/policy-engine-shared/src/lib/dev.fixture' | ||
import { v4 } from 'uuid' | ||
import { Hex, TypedData, createPublicClient, http, toHex } from 'viem' | ||
import { privateKeyToAddress } from 'viem/accounts' | ||
import { polygon } from 'viem/chains' | ||
|
||
const main = async () => { | ||
const anotherAddress = '0x3f843E606C79312718477F9bC020F3fC5b7264C2'.toLowerCase() as Hex | ||
|
||
const config = createArmoryConfig({ | ||
authClientId: 'ad496b05-3a1e-4138-93d0-1505e7a5c8a1', | ||
authHost: 'http://localhost:3010', | ||
authSecret: '27948c192850f36eb0b45285eb1a9ec3490e6ee573dd0ad63a32fe42c317a18be3e29b38bd56663e47bb', | ||
vaultClientId: 'd6369edd-7353-486c-9129-5f667fe8f3fc', | ||
vaultHost: 'http://localhost:3011', | ||
vaultSecret: 'f0e6ad88ba601f0e342e42d945b865d461293c587561a62d8f5cb86d442eff0288dc3e8ae6d98639aadb', | ||
signer: privateKeyToJwk(UNSAFE_PRIVATE_KEY.Alice) | ||
}) | ||
|
||
const privateKey = '0xcbdb5073d97f2971672e99769d12411fc044dde79b803e9c9e3ad6df5c9a260a' | ||
const walletId = 'test-wallet-id' | ||
|
||
console.log('\n\nimporting private key to vault...: ', privateKey) | ||
const vaultWalletAddress = privateKeyToAddress(privateKey) | ||
await importPrivateKey(config, { privateKey, walletId }) | ||
|
||
const nonce = 11 | ||
const transactionRequestAction: SignTransactionAction = { | ||
action: 'signTransaction', | ||
transactionRequest: { | ||
from: vaultWalletAddress, | ||
chainId: 137, | ||
gas: BigInt(22000), | ||
to: anotherAddress, | ||
maxFeePerGas: BigInt(291175227375), | ||
maxPriorityFeePerGas: BigInt(81000000000), | ||
value: toHex(BigInt(50000)), | ||
nonce | ||
// Update it accordingly to USER_PRIVATE_KEY last nonce + 1. | ||
// If you are too low, viem will error on transaction broadcasting, telling you what should be a correct nonce. | ||
}, | ||
resourceId: resourceId(walletId), | ||
nonce: v4() | ||
} | ||
|
||
const { accessToken } = await evaluate(config, transactionRequestAction) | ||
const { signature } = await signRequest(config, { accessToken, request: transactionRequestAction }) | ||
|
||
const publicClient = createPublicClient({ | ||
chain: polygon, | ||
transport: http() | ||
}) | ||
try { | ||
const hash = await publicClient.sendRawTransaction({ serializedTransaction: signature }) | ||
console.log('\n\ntransaction request successfully broadcasted !', 'txHash: ', hash) | ||
} catch (error) { | ||
console.error('transaction request failed', error) | ||
} | ||
|
||
const signMessageAction: SignMessageAction = { | ||
action: 'signMessage', | ||
message: 'Hello, World!', | ||
resourceId: resourceId(walletId), | ||
nonce: v4() | ||
} | ||
|
||
const { accessToken: messageAccessToken } = await evaluate(config, signMessageAction) | ||
const { signature: messageSignature } = await signRequest(config, { | ||
accessToken: messageAccessToken, | ||
request: signMessageAction | ||
}) | ||
|
||
console.log('\n\nmessage signature:', messageSignature) | ||
|
||
try { | ||
const messageVerification = await publicClient.verifyMessage({ | ||
message: signMessageAction.message, | ||
signature: messageSignature, | ||
address: vaultWalletAddress | ||
}) | ||
console.log('\n\nmessage verification:', messageVerification) | ||
} catch (error) { | ||
console.error('message verification failed', error) | ||
} | ||
|
||
const signTypedDataAction: SignTypedDataAction = { | ||
action: 'signTypedData', | ||
typedData: { | ||
types: { | ||
EIP712Domain: [{ name: 'name', type: 'string' }], | ||
Person: [ | ||
{ name: 'name', type: 'string' }, | ||
{ name: 'wallet', type: 'address' } | ||
] | ||
}, | ||
primaryType: 'Person', | ||
domain: { name: 'Ether Mail', version: '1' }, | ||
message: { | ||
name: 'Bob', | ||
wallet: anotherAddress | ||
} | ||
}, | ||
resourceId: resourceId(walletId), | ||
nonce: v4() | ||
} | ||
|
||
const { accessToken: typedDataAccessToken } = await evaluate(config, signTypedDataAction) | ||
|
||
const { signature: typedDataSignature } = await signRequest(config, { | ||
accessToken: typedDataAccessToken, | ||
request: signTypedDataAction | ||
}) | ||
|
||
const typedDataVerification = await publicClient.verifyTypedData({ | ||
signature: typedDataSignature, | ||
address: vaultWalletAddress, | ||
types: signTypedDataAction.typedData.types as unknown as TypedData, | ||
// TODO: @ptroger find a way to make this work without casting or explitly mapping to viem. | ||
primaryType: signTypedDataAction.typedData.primaryType, | ||
domain: signTypedDataAction.typedData.domain, | ||
message: signTypedDataAction.typedData.message | ||
}) | ||
|
||
console.log('\n\ntyped data verification:', typedDataVerification) | ||
} | ||
|
||
main() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
{ | ||
"extends": "./tsconfig.json", | ||
"compilerOptions": { | ||
"outDir": "../../dist/out-tsc", | ||
"module": "commonjs", | ||
"types": ["node"] | ||
}, | ||
"exclude": ["jest.config.ts", "src/**/*.spec.ts", "src/**/*.test.ts"], | ||
"include": ["src/**/*.ts"] | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
{ | ||
"extends": "../../tsconfig.base.json", | ||
"files": [], | ||
"include": [], | ||
"references": [ | ||
{ | ||
"path": "./tsconfig.app.json" | ||
}, | ||
{ | ||
"path": "./tsconfig.spec.json" | ||
} | ||
], | ||
"compilerOptions": { | ||
"esModuleInterop": true | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
{ | ||
"extends": "./tsconfig.json", | ||
"compilerOptions": { | ||
"outDir": "../../dist/out-tsc", | ||
"module": "commonjs", | ||
"types": ["jest", "node"] | ||
}, | ||
"include": ["jest.config.ts", "src/**/*.test.ts", "src/**/*.spec.ts", "src/**/*.d.ts"] | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
const { composePlugins, withNx } = require('@nx/webpack') | ||
|
||
// Nx plugins for webpack. | ||
module.exports = composePlugins(withNx(), (config) => { | ||
// Update the webpack config as needed here. | ||
// e.g. `config.plugins.push(new MyPlugin())` | ||
return config | ||
}) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -126,5 +126,8 @@ | |
"viem": "^2.7.16", | ||
"wagmi": "^2.5.7", | ||
"zod": "^3.22.4" | ||
}, | ||
"nx": { | ||
"includedScripts": [] | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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" | ||
} | ||
} | ||
] | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
SIGNATURE_PROJECT_NAME := armory-sdk | ||
SIGNATURE_PROJECT_DIR := ./packages/armory-sdk | ||
|
||
# == Code format == | ||
|
||
armory-sdk/format: | ||
npx nx format:write --projects ${SIGNATURE_PROJECT_NAME} | ||
|
||
armory-sdk/lint: | ||
npx nx lint ${SIGNATURE_PROJECT_NAME} -- --fix | ||
|
||
armory-sdk/format/check: | ||
npx nx format:check --projects ${SIGNATURE_PROJECT_NAME} | ||
|
||
armory-sdk/lint/check: | ||
npx nx lint ${SIGNATURE_PROJECT_NAME} | ||
|
||
# == Testing == | ||
|
||
armory-sdk/test/type: | ||
npx tsc \ | ||
--project ${SIGNATURE_PROJECT_DIR}/tsconfig.lib.json \ | ||
--noEmit | ||
|
||
armory-sdk/test/unit: | ||
npx nx test:unit ${SIGNATURE_PROJECT_NAME} -- ${ARGS} | ||
|
||
armory-sdk/test/unit/watch: | ||
make armory-sdk/test/unit ARGS=--watch |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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). |
Oops, something went wrong.