-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #120 from nevermined-io/feat/api_key
feat: management of NVM API Keys
- Loading branch information
Showing
10 changed files
with
325 additions
and
6 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,6 +1,6 @@ | ||
{ | ||
"name": "@nevermined-io/cli", | ||
"version": "2.2.1", | ||
"version": "2.2.2", | ||
"main": "index.js", | ||
"repository": "[email protected]:nevermined-io/cli.git", | ||
"author": "Nevermined", | ||
|
@@ -25,7 +25,7 @@ | |
"ncli": "./dist/src/index.js" | ||
}, | ||
"dependencies": { | ||
"@nevermined-io/sdk": "3.0.29", | ||
"@nevermined-io/sdk": "3.0.33", | ||
"log4js": "^6.9.1", | ||
"chalk": "^4.1.2", | ||
"cross-fetch": "~3.1.5", | ||
|
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,133 @@ | ||
import { NvmAccount, NvmApp, getFullZeroDevPermissions, createSessionKey, NvmApiKey } from '@nevermined-io/sdk' | ||
import { | ||
StatusCodes, | ||
getNeverminedContractAbi, | ||
} from '../../utils' | ||
import chalk from 'chalk' | ||
import { ExecutionOutput } from '../../models/ExecutionOutput' | ||
import { Logger } from 'log4js' | ||
import { ConfigEntry } from '../../models/ConfigDefinition' | ||
import { createPublicClient, http, toHex } from 'viem' | ||
import { privateKeyToAccount } from 'viem/accounts' | ||
|
||
|
||
export const createApiKey = async ( | ||
nvmApp: NvmApp, | ||
publisherAccount: NvmAccount, | ||
argv: any, | ||
config: ConfigEntry, | ||
logger: Logger | ||
): Promise<ExecutionOutput> => { | ||
|
||
const ZERO_PROJECT_ID = process.env.ZERO_PROJECT_ID || undefined | ||
if (!ZERO_PROJECT_ID) { | ||
return { | ||
status: StatusCodes.ERROR, | ||
errorMessage: `Missing environment variable ZERO_PROJECT_ID` | ||
} | ||
} | ||
|
||
const NVM_BACKEND_URL = config.nvm.neverminedBackendUri || undefined | ||
if (!NVM_BACKEND_URL) { | ||
return { | ||
status: StatusCodes.ERROR, | ||
errorMessage: `Missing Nevermined Backend URL` | ||
} | ||
} | ||
|
||
const BUNDLER_RPC = `https://rpc.zerodev.app/api/v2/bundler/${ZERO_PROJECT_ID}` | ||
|
||
const publicClient = createPublicClient({ | ||
chain: nvmApp.sdk.client.chain, | ||
transport: http(BUNDLER_RPC), | ||
}) | ||
logger.debug(`Public client created with chain: ${nvmApp.sdk.client.chain?.name}`) | ||
logger.debug(BUNDLER_RPC) | ||
|
||
logger.info(chalk.dim(`Creating a new NVM API Key ...`)) | ||
|
||
|
||
const networkName = config.networkName || 'geth-localnet' | ||
const didRegistryAbi = getNeverminedContractAbi('DIDRegistry', networkName) | ||
const nftSalesTemplateAbi = getNeverminedContractAbi('NFTSalesTemplate', networkName) | ||
const nftPlansAbi = getNeverminedContractAbi('NFT1155SubscriptionUpgradeable', networkName) | ||
|
||
logger.debug(`Generating permissions for the API Key ...`) | ||
const permissions = getFullZeroDevPermissions( | ||
didRegistryAbi.address, // DIDRegistry address | ||
nftSalesTemplateAbi.address, // Sales Template address | ||
config.erc20TokenAddress as `0x${string}`, // ERC20 address | ||
nftPlansAbi.address, // NFT1155 address | ||
nftPlansAbi.address, | ||
) | ||
|
||
logger.debug(`Permissions generated for network: ${networkName}`) | ||
logger.debug(`DIDRegistry: ${didRegistryAbi.address}`) | ||
logger.debug(`NFTSalesTemplate: ${nftSalesTemplateAbi.address}`) | ||
logger.debug(`NFTPlansAbi: ${nftPlansAbi.address}`) | ||
logger.debug(`ERC20 Address: ${config.erc20TokenAddress}`) | ||
// logger.debug(JSON.stringify(permissions)) | ||
|
||
|
||
logger.debug(`Creating a new ZeroDev kernel client ...`) | ||
logger.debug(`Chain ID: ${nvmApp.sdk.client.chain?.id}`) | ||
|
||
const privateKey = toHex(publisherAccount.getAccountSigner().getHdKey().privateKey) | ||
|
||
const account = privateKeyToAccount(privateKey) | ||
logger.debug(`Private key Account: ${account.address}`) | ||
|
||
logger.debug(`Creating a new ZeroDev session key via account: ${account.address} ...`) | ||
const sessionKey = await createSessionKey(account, publicClient, permissions) | ||
|
||
logger.debug(`Generating encrypted NVM API Key ...`) | ||
const encryptedNvmApiKey = await NvmApiKey.generate( | ||
nvmApp.sdk.utils.signature, | ||
publisherAccount, | ||
sessionKey, | ||
config.nvm.marketplaceAuthToken!, | ||
config.nvm.neverminedNodeAddress!, | ||
await nvmApp.sdk.services.node.getEcdsaPublicKey() | ||
) | ||
// logger.debug(encryptedNvmApiKey) | ||
|
||
logger.debug(`Registering NVM API Key ...`) | ||
const options = { | ||
method: 'POST', | ||
headers: { | ||
'Content-type': 'application/json' | ||
}, | ||
body: JSON.stringify({ | ||
name: argv.name, | ||
nvmKey: encryptedNvmApiKey | ||
}) | ||
} | ||
|
||
// logger.debug(`POST ${NVM_BACKEND_URL} with options`) | ||
// logger.debug(JSON.parse(options.body)) | ||
const _result = await fetch(`${NVM_BACKEND_URL}/api/v1/api-keys`, options) | ||
if (_result.status !== 200 && _result.status !== 201) { | ||
logger.error(`Error registering NVM API Key: ${_result.statusText}`) | ||
logger.error(await _result.text()) | ||
return { | ||
status: StatusCodes.ERROR, | ||
errorMessage: `Error registering NVM API Key: ${_result.statusText}` | ||
} | ||
} | ||
|
||
logger.info(chalk.green(`NVM API Key created successfully`)) | ||
const keyResult = await _result.json() | ||
logger.info(chalk.dim(`API Key Wallet: ${chalk.yellow(keyResult.userWallet)}`)) | ||
logger.info(chalk.dim(`API Key UserId: ${chalk.yellow(keyResult.userId)}`)) | ||
logger.info(chalk.dim(`API Key Hash: ${chalk.yellow(keyResult.hash)}`)) | ||
|
||
return { | ||
status: StatusCodes.OK, | ||
results: JSON.stringify({ | ||
sessionKey, | ||
userWallet: keyResult.userWallet, | ||
userId: keyResult.userId, | ||
hash: keyResult.hash | ||
}) | ||
} | ||
} |
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,77 @@ | ||
import { NvmAccount, NvmApp } from '@nevermined-io/sdk' | ||
import { | ||
StatusCodes, | ||
} from '../../utils' | ||
import chalk from 'chalk' | ||
import { ExecutionOutput } from '../../models/ExecutionOutput' | ||
import { Logger } from 'log4js' | ||
import { ConfigEntry } from '../../models/ConfigDefinition' | ||
|
||
|
||
export const listApiKeys = async ( | ||
_nvmApp: NvmApp, | ||
_publisherAccount: NvmAccount, | ||
_argv: any, | ||
config: ConfigEntry, | ||
logger: Logger | ||
): Promise<ExecutionOutput> => { | ||
|
||
const NVM_BACKEND_URL = config.nvm.neverminedBackendUri || undefined | ||
if (!NVM_BACKEND_URL) { | ||
return { | ||
status: StatusCodes.ERROR, | ||
errorMessage: `Missing Nevermined Backend URL` | ||
} | ||
} | ||
|
||
logger.info(chalk.dim(`Listing NVM API Keys ...`)) | ||
// logger.info(config.nvm.marketplaceAuthToken) | ||
// logger.info(config.nvm.marketplaceUri) | ||
// const clientAssertion = await nvmApp.sdk.utils.jwt.generateClientAssertion(publisherAccount) | ||
// const marketplaceAuthToken = await nvmApp.sdk.services.marketplace.login(clientAssertion) | ||
|
||
const options = { | ||
method: 'GET', | ||
headers: { | ||
'Accept': '*/*', | ||
'Authorization': `Bearer ${config.nvm.marketplaceAuthToken}` | ||
} | ||
} | ||
|
||
logger.debug(`${NVM_BACKEND_URL}/api/v1/api-keys`) | ||
logger.debug(JSON.stringify(options)) | ||
const _result = await fetch(`${NVM_BACKEND_URL}/api/v1/api-keys`, options) | ||
|
||
if (_result.status !== 200) { | ||
logger.error(`Error listing NVM API Keys: ${_result.statusText}`) | ||
logger.error(await _result.text()) | ||
return { | ||
status: StatusCodes.ERROR, | ||
errorMessage: `Error listing NVM API Keys: ${_result.statusText}` | ||
} | ||
} | ||
|
||
const keyResult = await _result.json() | ||
logger.info(chalk.green(`NVM API Keys found ${keyResult.totalResults}`)) | ||
|
||
|
||
keyResult.apiKeys.forEach((key: any) => { | ||
logger.info('---------------------------------') | ||
logger.info(chalk.dim(`\tName: ${chalk.yellow(key.name)}`)) | ||
if (key.isActive) | ||
logger.info(chalk.dim(`\tIs Active?: ${chalk.green('yes')}`)) | ||
else | ||
logger.info(chalk.dim(`\tIs Active?: ${chalk.red('no')}`)) | ||
|
||
logger.info(chalk.dim(`\tHash: ${chalk.yellow(key.hash)}`)) | ||
logger.info(chalk.dim(`\tWallet: ${chalk.yellow(key.userWallet)}`)) | ||
logger.info(chalk.dim(`\tCreated/Expires: ${chalk.yellow(key.createdAt)} / ${chalk.yellow(key.expiresAt)}`)) | ||
}) | ||
|
||
return { | ||
status: StatusCodes.OK, | ||
results: JSON.stringify({ | ||
keyResult | ||
}) | ||
} | ||
} |
Oops, something went wrong.