From 89654fa3cf6f72345d5df4a77400fe559cd0727e Mon Sep 17 00:00:00 2001 From: Marcos Carlomagno Date: Thu, 31 Oct 2024 18:07:01 -0300 Subject: [PATCH] feat: Create sdk api for listing permissions of current api key (#596) * feat: add support to list api keys capabilities * fix: rollback example * fix: path parameter position * fix: api key capability mapping --- examples/address-book-actions/package.json | 2 +- packages/account/src/api/index.ts | 10 ++++++- packages/account/src/models/account.ts | 32 ++++++++++++++++++++++ packages/base/src/api/client.ts | 2 +- packages/relay-signer/README.md | 7 ++--- 5 files changed, 46 insertions(+), 7 deletions(-) diff --git a/examples/address-book-actions/package.json b/examples/address-book-actions/package.json index 76f76aac..c7686136 100644 --- a/examples/address-book-actions/package.json +++ b/examples/address-book-actions/package.json @@ -1,6 +1,6 @@ { "name": "@openzeppelin/defender-sdk-example-address-book-actions", - "version": "1.14.5", + "version": "1.15.1", "private": true, "main": "index.js", "author": "OpenZeppelin Defender ", diff --git a/packages/account/src/api/index.ts b/packages/account/src/api/index.ts index 0578f9bd..ff5a4b71 100644 --- a/packages/account/src/api/index.ts +++ b/packages/account/src/api/index.ts @@ -1,7 +1,8 @@ import { BaseApiClient } from '@openzeppelin/defender-sdk-base-client'; -import { AccountUsageResponse } from '../models/account'; +import { AccountUsageResponse, ApiKeyCapability, ApiKeyCapabilityV2, toApiKeysCapabilityV2 } from '../models/account'; const PATH = '/account'; +const API_KEY_PATH = '/api-keys'; export class AccountClient extends BaseApiClient { protected getPoolId(): string { @@ -24,4 +25,11 @@ export class AccountClient extends BaseApiClient { return this.apiCall(async (api) => api.get(`${PATH}/usage?${searchParams.toString()}`)); } + + public async listApiKeyCapabilities(): Promise { + const res = await this.apiCall(async (api) => + api.get(`${API_KEY_PATH}/${this.apiKey}/capabilities`), + ); + return res.map(toApiKeysCapabilityV2); + } } diff --git a/packages/account/src/models/account.ts b/packages/account/src/models/account.ts index fc9f9156..d99e2c1f 100644 --- a/packages/account/src/models/account.ts +++ b/packages/account/src/models/account.ts @@ -14,3 +14,35 @@ type AccountUsage = }; export type AccountUsageResponse = Record; + +export type ApiKeyCapability = + | 'create-admin-proposals' + | 'manage-relayers' + | 'manage-autotasks' + | 'manage-subscribers' + | 'manage-deployments' + | 'manage-tenant-networks' + | 'manage-forked-networks' + | 'manage-address-book'; + +export type ApiKeyCapabilityV2 = + | 'create-admin-proposals' + | 'manage-relayers' + | 'manage-actions' + | 'manage-monitors' + | 'manage-deployments' + | 'manage-tenant-networks' + | 'manage-address-book'; + +const ApiKeyCapabilityMap: Record = { + 'manage-autotasks': 'manage-actions', + 'manage-subscribers': 'manage-monitors', + 'manage-address-book': 'manage-address-book', + 'create-admin-proposals': 'create-admin-proposals', + 'manage-deployments': 'manage-deployments', + 'manage-relayers': 'manage-relayers', + 'manage-tenant-networks': 'manage-tenant-networks', + 'manage-forked-networks': 'manage-tenant-networks', +}; + +export const toApiKeysCapabilityV2 = (capability: ApiKeyCapability) => ApiKeyCapabilityMap[capability] ?? capability; diff --git a/packages/base/src/api/client.ts b/packages/base/src/api/client.ts index b1168181..a38e8f76 100644 --- a/packages/base/src/api/client.ts +++ b/packages/base/src/api/client.ts @@ -22,7 +22,6 @@ export type AuthConfig = { type ApiFunction = (api: AxiosInstance) => Promise; export abstract class BaseApiClient { private api: AxiosInstance | undefined; - private apiKey: string; private session: CognitoUserSession | undefined; private sessionV2: { accessToken: string; refreshToken: string } | undefined; private apiSecret: string; @@ -30,6 +29,7 @@ export abstract class BaseApiClient { private retryConfig: RetryConfig; private authConfig: AuthConfig; + protected apiKey: string; protected abstract getPoolId(): string; protected abstract getPoolClientId(): string; protected abstract getApiUrl(type?: AuthType): string; diff --git a/packages/relay-signer/README.md b/packages/relay-signer/README.md index 2cd64e72..d7ab192e 100644 --- a/packages/relay-signer/README.md +++ b/packages/relay-signer/README.md @@ -1,6 +1,7 @@ # Defender SDK Relay Signer Client Defender Relay Signer Client lets you send transactions to any supported network using private relayers. Each relayer has its own secure private key, and a set of API keys. You can send transactions via your relayers by POSTing to the Defender HTTP API, or using this library. + ## Install ```bash @@ -10,7 +11,6 @@ yarn add @openzeppelin/defender-sdk-relay-signer-client ``` - This library also includes an [ethers.js](https://docs.ethers.io/v5/) signer and a [web3.js](https://web3js.readthedocs.io/) provider, that uses the Relay to sign and broadcast its transactions. ### Usage @@ -79,7 +79,6 @@ Transaction can be queried by nonce as well: const latestTx = await relayer.getTransactionByNonce(tx.nonce); ``` - Alternatively, the `relayer` can also be used to `list` the latest transactions sent, optionally filtering by status and creation time. ```js @@ -281,7 +280,7 @@ Note that these web3.js providers currently have the same limitations as the eth ```js const { Defender } = require('@openzeppelin/defender-sdk'); -exports.handler = async function(credentials) { +exports.handler = async function (credentials) { const client = new Defender(credentials); const txRes = await client.relaySigner.sendTransaction({ @@ -293,7 +292,7 @@ exports.handler = async function(credentials) { console.log(txRes); return txRes.hash; -} +}; ``` ## FAQ