diff --git a/examples/create-approval-process/index.js b/examples/create-approval-process/index.js new file mode 100644 index 00000000..dd3c17dd --- /dev/null +++ b/examples/create-approval-process/index.js @@ -0,0 +1,29 @@ +require('dotenv').config(); + +const { Defender } = require('@openzeppelin/defender-sdk'); + +async function main() { + const creds = { apiKey: process.env.API_KEY, apiSecret: process.env.API_SECRET }; + const client = new Defender(creds); + + const relayers = await client.relay.list(); + let relayer = relayers.items.find((relayer) => relayer.network === 'sepolia'); + if (!relayer) { + console.log('Relayer not found, creating one'); + relayer = await client.relay.create({ name: 'My Testnet Relayer', network: 'sepolia', minBalance: 0 }); + } + + const approvalProcess = await client.approvalProcess.create({ + name: 'My Approval Process 2', + network: 'sepolia', + via: relayer.address, + viaType: 'Relayer', + relayerId: relayer.relayerId, + }); + + console.log(approvalProcess); +} + +if (require.main === module) { + main().catch(console.error); +} diff --git a/examples/create-approval-process/package.json b/examples/create-approval-process/package.json new file mode 100644 index 00000000..c640e885 --- /dev/null +++ b/examples/create-approval-process/package.json @@ -0,0 +1,15 @@ +{ + "name": "@openzeppelin/defender-sdk-example-create-approval-process", + "version": "1.14.4", + "private": true, + "main": "index.js", + "author": "Marcos Carlomagno ", + "license": "MIT", + "scripts": { + "start": "node index.js" + }, + "dependencies": { + "@openzeppelin/defender-sdk": "1.14.4", + "dotenv": "^16.3.1" + } +} diff --git a/packages/approval-process/README.md b/packages/approval-process/README.md new file mode 100644 index 00000000..f97a0f7a --- /dev/null +++ b/packages/approval-process/README.md @@ -0,0 +1,5 @@ +# Defender SDK Approval Process client + +The OpenZeppelin Defender provides a security operations (SecOps) platform for Ethereum with built-in best practices. Development teams implement Defender to ship faster and minimize security risks. + +This library provides methods related to Approval Processes. See Examples for usage. diff --git a/packages/approval-process/jest.config.js b/packages/approval-process/jest.config.js new file mode 100644 index 00000000..990bd442 --- /dev/null +++ b/packages/approval-process/jest.config.js @@ -0,0 +1 @@ +module.exports = require('../../jest.config'); diff --git a/packages/approval-process/package.json b/packages/approval-process/package.json new file mode 100644 index 00000000..eba7d5bf --- /dev/null +++ b/packages/approval-process/package.json @@ -0,0 +1,30 @@ +{ + "name": "@openzeppelin/defender-sdk-approval-process-client", + "version": "1.14.4", + "description": "", + "main": "./lib/index.js", + "types": "./lib/index.d.ts", + "scripts": { + "build": "rm -rf lib && tsc", + "test": "npm run test:unit", + "test:unit": "jest --verbose --passWithNoTests --forceExit", + "watch": "tsc -w" + }, + "files": [ + "lib", + "!*.test.js", + "!*.test.js.map", + "!*.test.d.ts", + "!*__mocks__" + ], + "author": "OpenZeppelin Defender ", + "license": "MIT", + "dependencies": { + "@openzeppelin/defender-sdk-base-client": "^1.14.4", + "axios": "^1.6.7", + "lodash": "^4.17.21" + }, + "publishConfig": { + "access": "public" + } +} diff --git a/packages/approval-process/src/api/index.ts b/packages/approval-process/src/api/index.ts new file mode 100644 index 00000000..e7e52ea2 --- /dev/null +++ b/packages/approval-process/src/api/index.ts @@ -0,0 +1,24 @@ +import { BaseApiClient } from '@openzeppelin/defender-sdk-base-client'; +import { CreateApprovalProcessRequest, CreateApprovalProcessResponse } from '../models/approval-process'; + +const PATH = '/approval-process'; + +export class ApprovalProcessClient extends BaseApiClient { + protected getPoolId(): string { + return process.env.DEFENDER_POOL_ID ?? 'us-west-2_94f3puJWv'; + } + + protected getPoolClientId(): string { + return process.env.DEFENDER_POOL_CLIENT_ID ?? '40e58hbc7pktmnp9i26hh5nsav'; + } + + protected getApiUrl(): string { + return process.env.DEFENDER_API_URL ?? 'https://defender-api.openzeppelin.com/v2/'; + } + + public async create(approvalProcess: CreateApprovalProcessRequest): Promise { + return this.apiCall(async (api) => { + return await api.post(PATH, approvalProcess); + }); + } +} diff --git a/packages/approval-process/src/index.ts b/packages/approval-process/src/index.ts new file mode 100644 index 00000000..7b760bc3 --- /dev/null +++ b/packages/approval-process/src/index.ts @@ -0,0 +1,5 @@ +export { ApprovalProcessClient } from './api'; +export { CreateApprovalProcessRequest, CreateApprovalProcessResponse } from './models/approval-process'; + +// eslint-disable-next-line @typescript-eslint/no-var-requires +export const VERSION = require('../package.json').version; diff --git a/packages/approval-process/src/models/approval-process.ts b/packages/approval-process/src/models/approval-process.ts new file mode 100644 index 00000000..15178786 --- /dev/null +++ b/packages/approval-process/src/models/approval-process.ts @@ -0,0 +1,69 @@ +import { Network } from '@openzeppelin/defender-sdk-base-client'; + +export type ComponentType = ('deploy' | 'upgrade')[]; + +export interface Timelock { + address: string; + delay: string; +} +export interface FireblocksProposalParams { + apiKeyId: string; + vaultId: string; + assetId: string; +} + +export interface CreateApprovalProcessRequest { + name: string; + component?: ComponentType; + network: Network; + via?: string; + viaType?: + | 'EOA' + | 'Contract' + | 'Multisig' + | 'Gnosis Safe' + | 'Safe' + | 'Gnosis Multisig' + | 'Relayer' + | 'Unknown' + | 'Relayer Group' + | 'Timelock Controller' + | 'ERC20' + | 'Governor' + | 'Fireblocks'; + timelock?: Timelock; + multisigSender?: string; + fireblocks?: FireblocksProposalParams; + relayerId?: string; + relayerGroupId?: string; + stackResourceId?: string; +} + +export interface CreateApprovalProcessResponse { + approvalProcessId: string; + createdAt: string; + name: string; + component?: ComponentType; + network?: Network; + via?: string; + viaType?: + | 'EOA' + | 'Contract' + | 'Multisig' + | 'Gnosis Safe' + | 'Safe' + | 'Gnosis Multisig' + | 'Relayer' + | 'Relayer Group' + | 'Unknown' + | 'Timelock Controller' + | 'ERC20' + | 'Governor' + | 'Fireblocks'; + timelock?: Timelock; + multisigSender?: string; + fireblocks?: FireblocksProposalParams; + relayerId?: string; + relayerGroupId?: string; + stackResourceId?: string; +} diff --git a/packages/approval-process/tsconfig.json b/packages/approval-process/tsconfig.json new file mode 100644 index 00000000..09f1bb8c --- /dev/null +++ b/packages/approval-process/tsconfig.json @@ -0,0 +1,11 @@ +{ + "extends": "code-style/tsconfig.json", + "compilerOptions": { + "declaration": true, + "outDir": "./lib", + "skipLibCheck": true, + "sourceMap": false + }, + "include": ["./src"], + "exclude": ["**/*.test.ts", "**/__mocks__/*"] +} diff --git a/packages/defender-sdk/package.json b/packages/defender-sdk/package.json index f9b966a8..f17cc2c1 100644 --- a/packages/defender-sdk/package.json +++ b/packages/defender-sdk/package.json @@ -31,7 +31,8 @@ "@openzeppelin/defender-sdk-network-client": "^1.14.4", "@openzeppelin/defender-sdk-account-client": "^1.14.4", "@openzeppelin/defender-sdk-key-value-store-client": "^1.14.4", - "@openzeppelin/defender-sdk-relay-group-client": "^1.14.4" + "@openzeppelin/defender-sdk-relay-group-client": "^1.14.4", + "@openzeppelin/defender-sdk-approval-process-client": "^1.14.4" }, "publishConfig": { "access": "public" diff --git a/packages/defender-sdk/src/index.ts b/packages/defender-sdk/src/index.ts index 30e54916..6dfb4e58 100644 --- a/packages/defender-sdk/src/index.ts +++ b/packages/defender-sdk/src/index.ts @@ -6,9 +6,9 @@ import { DeployClient } from '@openzeppelin/defender-sdk-deploy-client'; import { NotificationChannelClient } from '@openzeppelin/defender-sdk-notification-channel-client'; import { NetworkClient } from '@openzeppelin/defender-sdk-network-client'; import { AccountClient } from '@openzeppelin/defender-sdk-account-client'; +import { ApprovalProcessClient } from '@openzeppelin/defender-sdk-approval-process-client'; import { RelayGroupClient } from '@openzeppelin/defender-sdk-relay-group-client'; import { KeyValueStoreClient, LocalKeyValueStoreCreateParams } from '@openzeppelin/defender-sdk-key-value-store-client'; - import { Newable, ClientParams } from './types'; import { ActionRelayerParams, Relayer as RelaySignerClient } from '@openzeppelin/defender-sdk-relay-signer-client'; import { ListNetworkRequestOptions } from '@openzeppelin/defender-sdk-network-client/lib/models/networks'; @@ -105,6 +105,10 @@ export class Defender { }); } + get approvalProcess() { + return getClient(ApprovalProcessClient, { apiKey: this.apiKey, apiSecret: this.apiSecret }); + } + get monitor() { return getClient(MonitorClient, { apiKey: this.apiKey, diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 2cba252c..16062d4c 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -113,6 +113,15 @@ importers: specifier: ^16.3.1 version: 16.4.5 + examples/create-approval-process: + dependencies: + '@openzeppelin/defender-sdk': + specifier: 1.14.4 + version: link:../../packages/defender-sdk + dotenv: + specifier: ^16.3.1 + version: 16.4.5 + examples/create-batch-proposal: dependencies: '@openzeppelin/defender-sdk': @@ -250,7 +259,7 @@ importers: version: 16.4.5 ethers: specifier: ^5.6.1 - version: 5.7.2(bufferutil@4.0.8)(utf-8-validate@5.0.10) + version: 5.7.2 examples/ethers-signer-v6: dependencies: @@ -465,6 +474,18 @@ importers: specifier: ^4.17.21 version: 4.17.21 + packages/approval-process: + dependencies: + '@openzeppelin/defender-sdk-base-client': + specifier: ^1.14.4 + version: link:../base + axios: + specifier: ^1.6.7 + version: 1.7.2 + lodash: + specifier: ^4.17.21 + version: 4.17.21 + packages/base: dependencies: amazon-cognito-identity-js: @@ -492,6 +513,9 @@ importers: '@openzeppelin/defender-sdk-action-client': specifier: ^1.14.4 version: link:../action + '@openzeppelin/defender-sdk-approval-process-client': + specifier: ^1.14.4 + version: link:../approval-process '@openzeppelin/defender-sdk-base-client': specifier: ^1.14.4 version: link:../base @@ -7877,7 +7901,7 @@ snapshots: ethereum-cryptography: 0.1.3 rlp: 2.2.7 - ethers@5.7.2(bufferutil@4.0.8)(utf-8-validate@5.0.10): + ethers@5.7.2: dependencies: '@ethersproject/abi': 5.7.0 '@ethersproject/abstract-provider': 5.7.0