From 56818d45d868a466bd77d3470f17490ae5449ca3 Mon Sep 17 00:00:00 2001 From: Aitor <1726644+aaitor@users.noreply.github.com> Date: Tue, 11 Jun 2024 12:54:26 +0200 Subject: [PATCH 1/4] feat: first round of documentation update --- package.json | 2 +- src/constants/AssetConstants.ts | 5 ++ src/ddo/DDO.ts | 47 ++++++++-- src/ddo/NvmAppMetadata.ts | 46 ++++++++++ src/events/ContractEvent.ts | 37 ++++++++ src/events/NeverminedEvent.ts | 22 +++++ src/events/SubgraphEvent.ts | 25 ++++++ .../templates/AgreementTemplate.abstract.ts | 5 +- src/nevermined/api/AccountsApi.ts | 61 +++++++++---- src/nevermined/api/AgreementsApi.ts | 40 ++++----- src/nevermined/api/AssetsApi.ts | 87 ++++++++++++------- src/nevermined/api/ComputeApi.ts | 37 ++++---- src/nevermined/api/ConditionsApi.ts | 72 ++++++++------- src/nevermined/api/ProvenanceApi.ts | 48 ++++++---- src/nevermined/api/RegistryBaseApi.ts | 68 ++++++++------- src/nevermined/api/nfts/NFT1155Api.ts | 83 +++++++++--------- src/nevermined/api/nfts/NFT721Api.ts | 56 ++++++------ src/nevermined/api/nfts/NFTsBaseApi.ts | 37 ++++---- src/nevermined/api/nfts/PoapApi.ts | 18 ++++ src/nevermined/api/nfts/SoulBoundApi.ts | 15 ++++ .../api/nfts/SubscriptionCreditsNFTApi.ts | 18 ++++ src/nevermined/api/nfts/SubscriptionNFTApi.ts | 18 ++++ 22 files changed, 580 insertions(+), 267 deletions(-) diff --git a/package.json b/package.json index e7c461891..7443264f7 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@nevermined-io/sdk", - "version": "3.0.12", + "version": "3.0.13", "description": "Javascript SDK for connecting with Nevermined Data Platform ", "main": "./dist/node/sdk.js", "typings": "./dist/node/sdk.d.ts", diff --git a/src/constants/AssetConstants.ts b/src/constants/AssetConstants.ts index 2ac5ea769..fdd1f4a33 100644 --- a/src/constants/AssetConstants.ts +++ b/src/constants/AssetConstants.ts @@ -1,8 +1,13 @@ export const NETWORK_FEE_DENOMINATOR = 10000n +// The type of the encryption methods supported for the private data included in the metadata export type EncryptionMethod = 'PSK-RSA' | 'PSK-ECDSA' +// The default encryption method export const DEFAULT_ENCRYPTION_METHOD = 'PSK-RSA' as EncryptionMethod +// The Ethereum zero address export const ZeroAddress = '0x0000000000000000000000000000000000000000' + +// The address to indicate that a payment is done in the native token of the network and not a ERC20 token export const NativeTokenAddress = '0x0000000000000000000000000000000000000000' diff --git a/src/ddo/DDO.ts b/src/ddo/DDO.ts index fadaf87f6..90cdb4bcb 100644 --- a/src/ddo/DDO.ts +++ b/src/ddo/DDO.ts @@ -38,12 +38,20 @@ export const DEPENDENCIES_RELEASE_CONDITION = ['access', 'serviceExecution', 'tr /** * Fill some static parameters that depends on the metadata. * - * @param conditions - Conditions to fill. - * @param ddo - DDO related to this conditions. + * @param serviceType - The type of the service "access", "nft-sales", etc. + * @param conditions - List of conditions to fill. + * @param owner - Owner of the asset. * @param assetPrice -Rewards distribution + * @param did - The DID of the asset. + * @param erc20TokenContract - The address of the ERC20 token contract used for payment (0x0 address if native token). + * @param nftTokenContract - The address of the NFT token contract used. + * @param nftHolder - The address of the NFT holder. * @param nftAmount - Number of nfts to handle - * @param erc20TokenContract - Number of nfts to handle - * @param nftTokenContract - Number of nfts to handle + * @param nftTransfer - If the nft will be transferred (true) or minted (false) + * @param duration - Duration if it's a subscription + * @param fulfillAccessTimeout - Timeout for the fulfill of the access service + * @param fulfillAccessTimelock - Timelock for the fulfill of the access service + * @param tokenId - The token id of the NFT * * @returns Filled conditions. */ @@ -148,8 +156,8 @@ function getParameter( } /** - * DID Descriptor Object. - * Contains all the data related to an asset. + * DID Descriptor Object (DDO). + * Contains all the metadata related to an asset, including the description and the services available. */ export class DDO { /** @@ -172,6 +180,13 @@ export class DDO { return new DDO(ddo) } + /** + * It creates an authorization service that can be included later as part of a DDO + * @param neverminedNodeUri URL of the Nevermined Node managing this asset + * @param publicKey Public key of the user + * @param method Encryption method + * @returns The authorization service + */ public static createAuthorizationService( neverminedNodeUri: string, publicKey: string, @@ -220,6 +235,13 @@ export class DDO { }) } + /** + * It gets an instance of a DDO with the basic structure + * @param userId The unique identifier of the user + * @param publisherAddress The address of the publisher + * @param appId The application id + * @returns a {@link DDO} instance + */ public static getInstance(userId: string, publisherAddress: string, appId?: string): DDO { return new DDO({ id: '', @@ -244,18 +266,27 @@ export class DDO { }) } + /** + * It gets a new date formatted + * @param date the date to format + * @returns the date string formatted + */ public static getNewDateFormatted(date: Date = new Date()) { return date.toISOString().replace(/\.[0-9]{3}/, '') } + /** + * It returns the DDO id without the prefix + * @returns the DID without the prefix + */ public shortId(): string { return this.id.replace('did:nv:', '') } /** - * Finds a service of a DDO by index. + * Finds a service of a DDO by index number. * @param index - index of the service in the DDO. - * @returns Service. + * @returns {@link Service}. */ public findServiceByIndex(index: number): Service { if (isNaN(index)) { diff --git a/src/ddo/NvmAppMetadata.ts b/src/ddo/NvmAppMetadata.ts index 389753e1c..08e155282 100644 --- a/src/ddo/NvmAppMetadata.ts +++ b/src/ddo/NvmAppMetadata.ts @@ -8,6 +8,14 @@ import { } from '../types/DDOTypes' export class NvmAppMetadata { + /** + * It returns a metadata template for a subscription with time limit + * @param name the name of the subscription + * @param author the author of the subscrpiton + * @param timeMeasure the string defining the time measure + * @param customData any key-value pair to be included in the metadata + * @returns {@link Metadata} + */ public static getTimeSubscriptionMetadataTemplate( name: string, author: string, @@ -28,6 +36,13 @@ export class NvmAppMetadata { return metadata } + /** + * It returns a metadata template for a credits limitted subscription + * @param name the name of the subscription + * @param author the author of the subscrpiton + * @param customData any key-value pair to be included in the metadata + * @returns {@link Metadata} + */ public static getCreditsSubscriptionMetadataTemplate( name: string, author: string, @@ -46,6 +61,13 @@ export class NvmAppMetadata { return metadata } + /** + * It returns a metadata template for subscription + * @param name the name of the subscription + * @param author the author of the subscrpiton + * @param customData any key-value pair to be included in the metadata + * @returns {@link Metadata} + */ public static getSubscriptionMetadataTemplate( name: string, author: string, @@ -73,6 +95,23 @@ export class NvmAppMetadata { return _metadata } + /** + * It returns a metadata template for Web Service + * @param name the name of the subscription + * @param author the author of the subscrpiton + * @param endpoints the list of endpoints + * @param openEndpoints the list of open endpoints (not protected) + * @param openApiEndpoint the openApi endpoint endpoint if any + * @param serviceType the type of the service + * @param authType the type of authentication required by the service + * @param authToken the token to be used for authentication (if authType is oauth or bearer) + * @param authUser the username to be used for authentication (if authType is basic) + * @param authPassword the password to be used for authentication (if authType is basic) + * @param isPriceDynamic if the price is dynamic + * @param customData any key-value pair to be included in the metadata + * @param nonce the nonce to be included in the metadata + * @returns {@link Metadata} + */ public static getServiceMetadataTemplate( name: string, author: string, @@ -143,6 +182,13 @@ export class NvmAppMetadata { return serviceMetadata } + /** + * It gets a metadata template for a file type of asset (datasets, moldels, algorithms, etc.) + * @param name the name of the asset + * @param author the autor of the asset + * @param customData key-value pairs to be included in the metadata + * @returns {@link Metadata} + */ public static getFileMetadataTemplate( name: string, author: string, diff --git a/src/events/ContractEvent.ts b/src/events/ContractEvent.ts index 2ce97eaec..3a0b89efe 100644 --- a/src/events/ContractEvent.ts +++ b/src/events/ContractEvent.ts @@ -6,7 +6,18 @@ import { searchAbiEvent } from '../nevermined/utils/BlockchainViemUtils' import { Nevermined } from '../nevermined/Nevermined' import { Web3Clients } from '../Instantiable.abstract' +/** + * Class to handle Smart Contract events directly connected to a blockchain node + */ export class ContractEvent extends NeverminedEvent { + /** + * It gets a new instance of ContractEvent + * @param contract contract instance + * @param eventEmitter events emitter implementation + * @param nevermined the Nevermined instance + * @param client the blockchain client + * @returns the ContractEvent instance + */ public static getInstance( contract: ContractBase, eventEmitter: EventEmitter, @@ -22,6 +33,11 @@ export class ContractEvent extends NeverminedEvent { return instance } + /** + * It returns the events matching a given filter + * @param options event filter options + * @returns {@link EventResult} + */ public async getEventData(options: EventOptions): EventResult { if (!this.eventExists(options.eventName) || !options.filterJsonRpc) { throw new KeeperError( @@ -47,6 +63,12 @@ export class ContractEvent extends NeverminedEvent { } } + /** + * It returns the events matching a given filter depending on the blockchain network connected + * This necessary for some networks and/or web3 providers which limit the number of blocks to query + * @param options event filter options + * @returns {@link EventResult} + */ public async getPastEvents(options: EventOptions): EventResult { try { const chainId = this.client.chain?.id @@ -73,10 +95,19 @@ export class ContractEvent extends NeverminedEvent { } } + /** + * It returns the current block chain block number + * @returns the block number + */ public async getBlockNumber(): Promise { return await this.client.public.getBlockNumber() } + /** + * It checks if an event exists on the contract definition + * @param eventName the event name + * @returns true if the event exists, false otherwise + */ private eventExists(eventName: string): boolean { try { const signature = searchAbiEvent(this.contract.contract.abi, eventName) @@ -86,6 +117,12 @@ export class ContractEvent extends NeverminedEvent { } } + /** + * It returns the indexed parameters of an event + * @param eventName the name of the event + * @param filter tge event filter + * @returns the array of indexed parameters + */ private filterToArgs(eventName: string, filter: FilterContractEvent): Array { const signature = searchAbiEvent(this.contract.contract.abi, eventName) // @ts-ignore diff --git a/src/events/NeverminedEvent.ts b/src/events/NeverminedEvent.ts index b5c962863..e7204ea7a 100644 --- a/src/events/NeverminedEvent.ts +++ b/src/events/NeverminedEvent.ts @@ -7,6 +7,9 @@ import { ContractEventSubscription, } from '../types/EventTypes' +/** + * Abstract class to handle Smart Contract events + */ export abstract class NeverminedEvent extends Instantiable { protected eventEmitter: EventEmitter protected contract: ContractBase @@ -14,12 +17,24 @@ export abstract class NeverminedEvent extends Instantiable { public abstract getPastEvents(options: EventOptions): EventResult public abstract getBlockNumber(...args: any[]): Promise + /** + * Initializes the NeverminedEvent instance + * @param contract contract instance + * @param eventEmitter events emitter implementation + * @returns the NeverminedEvent instance + */ protected constructor(contract: ContractBase, eventEmitter: EventEmitter) { super() this.contract = contract this.eventEmitter = eventEmitter } + /** + * Subscribes to a contract event + * @param callback function called when the event is triggered + * @param options event filter options + * @returns {@link ContractEventSubscription} + */ public subscribe( callback: (events: EventResult[]) => void, options: EventOptions, @@ -35,6 +50,13 @@ export abstract class NeverminedEvent extends Instantiable { } } + /** + * Subscribes to a contract event and waits for the first event to happen + * @param callback function called when the event is triggered + * @param options event filter options + * @param timeout maximum time to wait for the event to happen + * @returns Promise with the event data + */ public async once( callback: (events: EventResult[]) => void, options: EventOptions, diff --git a/src/events/SubgraphEvent.ts b/src/events/SubgraphEvent.ts index c8ca58e4c..7d552bd55 100644 --- a/src/events/SubgraphEvent.ts +++ b/src/events/SubgraphEvent.ts @@ -13,9 +13,20 @@ import _ from 'lodash' import { GqlArgs, generateGql, getMethodName } from './utils' import { GraphError } from '../errors/NeverminedErrors' +/** + * Class to handle Smart Contract events connected to the contract subgraphs + */ export class SubgraphEvent extends NeverminedEvent { public subgraph: ApolloClient + /** + * It gets a new instance of SubgraphEvent + * @param contract contract instance + * @param eventEmitter events emitter implementation + * @param graphHttpUri url of the subgraph + * @param networkName the name of the blockchain network + * @returns the SubgraphEvent instance + */ public static getInstance( contract: ContractBase, eventEmitter: EventEmitter, @@ -44,6 +55,11 @@ export class SubgraphEvent extends NeverminedEvent { return instance } + /** + * It returns the events matching a given filter + * @param options event filter options + * @returns {@link EventResult} + */ public async getEventData(options: EventOptions): EventResult { if (!this.subgraph || !options.filterSubgraph) { throw new GraphError(`Subgraph client for ${this.contract.contractName} is not implemented!`) @@ -61,10 +77,19 @@ export class SubgraphEvent extends NeverminedEvent { } } + /** + * It returns the events matching a given filter + * @param options event filter options + * @returns {@link EventResult} + */ public async getPastEvents(options: EventOptions): EventResult { return this.getEventData(options) } + /** + * It returns the block number of the latest block minted in the blockchain + * @returns the block number + */ public async getBlockNumber(): Promise { const result = await this.subgraph.query({ query: gql` diff --git a/src/keeper/contracts/templates/AgreementTemplate.abstract.ts b/src/keeper/contracts/templates/AgreementTemplate.abstract.ts index e4edd7da3..a8388c51b 100644 --- a/src/keeper/contracts/templates/AgreementTemplate.abstract.ts +++ b/src/keeper/contracts/templates/AgreementTemplate.abstract.ts @@ -213,14 +213,13 @@ export abstract class AgreementTemplate extends ContractBase { ddo: DDO, parameters: Params, consumer: NvmAccount, - from: NvmAccount, timeOuts?: number[], txParams?: TxParameters, ): Promise { const { agreementId, instances } = await this.instanceFromDDO( agreementIdSeed, ddo, - from.getId(), + consumer.getId(), parameters, ) @@ -231,7 +230,7 @@ export abstract class AgreementTemplate extends ContractBase { new Array(instances.length).fill(0), timeOuts ? timeOuts : new Array(instances.length).fill(0), [consumer.getId()], - from, + consumer, txParams, ) diff --git a/src/nevermined/api/AccountsApi.ts b/src/nevermined/api/AccountsApi.ts index 616244678..a2c95fc75 100644 --- a/src/nevermined/api/AccountsApi.ts +++ b/src/nevermined/api/AccountsApi.ts @@ -1,4 +1,3 @@ -// import { Balance, TypedDataDomain, TypedDataTypes } from '../../models' import { Instantiable, InstantiableConfig } from '../../Instantiable.abstract' import { NvmAccount } from '../../models/NvmAccount' import { TxParameters as txParams } from '../../models/Transactions' @@ -49,6 +48,11 @@ export class AccountsApi extends Instantiable { return NvmAccount.fromAddress(address as `0x${string}`) } + /** + * Given an address, it returns the account if it exists in the list of accounts. + * @param from + * @returns + */ public findAccount(from: string): NvmAccount | undefined { for (const acc of this.config.accounts || []) { const addr = acc.getAddress() @@ -59,10 +63,20 @@ export class AccountsApi extends Instantiable { return undefined } + /** + * Returns the list of addresses (Local or Json-Rpc) + * @returns The list of addresses. + */ public async addresses(): Promise { return await Promise.all((this.config.accounts || []).map((a) => a.getAddress())) } + /** + * It signs a message using a remote account + * @param text the message to sign + * @param from the address of the remote account used to sign the message + * @returns the message signed message + */ public async signTextWithRemoteAccount( text: string | Uint8Array, from: string, @@ -74,6 +88,12 @@ export class AccountsApi extends Instantiable { }) } + /** + * It signs a transaction using a remote account + * @param data the transaction data + * @param from the address of the remote account used to sign the transaction + * @returns the signed transaction + */ public async signTransactionWithRemoteAccount( data: `0x${string}`, from: string, @@ -85,6 +105,14 @@ export class AccountsApi extends Instantiable { }) } + /** + * It signs a typed data using a remote account + * @param domain the domain of the typed data + * @param types the types of the typed data + * @param value the value of the typed data + * @param from the address of the remote account used to sign the typed data + * @returns the signed typed data + */ public async signTypedData( domain: TypedDataDomain, types: TypedDataTypes, @@ -102,8 +130,8 @@ export class AccountsApi extends Instantiable { /** * Request tokens for an account. - * @param account - Account instance. - * @param amount - Token amount. + * @param account - Account instance or the address of the account to receive the tokens + * @param amount - Token amount to request * @param txParams - Transaction parameters * @returns {@link true} if the call was successful. {@link false} otherwise. */ @@ -129,33 +157,36 @@ export class AccountsApi extends Instantiable { } /** - * Balance of Nevermined Token. - * @returns + * It gets the balance of the ERC20 Token loaded in the Nevermined instance + * @param account - Account instance or the address of the account to get the balance + * @returns the balance of ERC20 Token related to the account */ - public async getNeverminedBalance(address: string | NvmAccount): Promise { + public async getNeverminedBalance(account: string | NvmAccount): Promise { const accountAddress = - address instanceof NvmAccount ? address.getAddress() : (address as `0x${string}`) + account instanceof NvmAccount ? account.getAddress() : (account as `0x${string}`) const { token } = this.nevermined.keeper if (!token) return 0n return ((await token.balanceOf(accountAddress)) / 10n) * BigInt(await token.decimals()) } /** - * Balance of Ether. - * @returns + * It gets the native token (i.e ETH) balance of an account + * @param account - Account instance or the address of the account to get the balance + * @returns the balance of the native token */ - public async getEtherBalance(address: string | NvmAccount): Promise { + public async getEtherBalance(account: string | NvmAccount): Promise { const accountAddress = - address instanceof NvmAccount ? address.getAddress() : (address as `0x${string}`) + account instanceof NvmAccount ? account.getAddress() : (account as `0x${string}`) return this.client.public.getBalance({ address: accountAddress }) } /** - * Balances of Ether and Nevermined Token. - * @returns + * It gets the balance of the native token (i.e ETH) and the ERC20 token associated to the account + * @param account - Account instance or the address of the account to get the balance + * @returns The balance of the ERC20 and Native tokens */ - public async getBalance(address: string | NvmAccount): Promise { - const accountAddress = address instanceof NvmAccount ? address.getId() : address + public async getBalance(account: string | NvmAccount): Promise { + const accountAddress = account instanceof NvmAccount ? account.getId() : account return { eth: await this.getEtherBalance(accountAddress), nevermined: await this.getNeverminedBalance(accountAddress), diff --git a/src/nevermined/api/AgreementsApi.ts b/src/nevermined/api/AgreementsApi.ts index 24906f555..3ae696df9 100644 --- a/src/nevermined/api/AgreementsApi.ts +++ b/src/nevermined/api/AgreementsApi.ts @@ -39,13 +39,13 @@ export class AgreementsApi extends Instantiable { * * @param did - Decentralized ID. * @param serviceType - Service. - * @param consumer - Consumer account. + * @param from - Consumer account. * @returns The agreement ID and signature. */ public async prepareSignature( did: string, serviceType: ServiceType, - consumer: NvmAccount, + from: NvmAccount, ): Promise { const ddo = await this.nevermined.assets.resolve(did) const agreementIdSeed: string = zeroX(generateId()) @@ -55,8 +55,8 @@ export class AgreementsApi extends Instantiable { await this.nevermined.keeper.templates.accessTemplate.getAgreementIdsFromDDO( agreementIdSeed, ddo, - consumer.getId(), - accessTemplate.params(consumer), + from.getId(), + accessTemplate.params(from), ) const signature = await this.nevermined.utils.agreements.signServiceAgreement( @@ -64,7 +64,7 @@ export class AgreementsApi extends Instantiable { serviceType, agreementIdSeed, agreementConditionsIds, - consumer, + from, ) return { agreementIdSeed, signature } @@ -78,10 +78,11 @@ export class AgreementsApi extends Instantiable { * in this method before submitting on-chain. * * @param did - Decentralized ID. - * @param agreementId - Service agreement ID. + * @param agreementIdSeed - Service agreement ID seed. * @param serviceType - Service. - * @param consumer - Consumer account. - * @param publisher - Publisher account. + * @param agreementParams - Agreement parameters. + * @param from - The account of the user creating the service agreement + * @param txParams - Transaction parameters. * @returns The service agreement id */ public async create( @@ -89,9 +90,8 @@ export class AgreementsApi extends Instantiable { agreementIdSeed: string, serviceType: ServiceType, agreementParams: any, - consumer: NvmAccount, - publisher: NvmAccount, - params?: TxParameters, + from: NvmAccount, + txParams?: TxParameters, ) { const ddo = await this.nevermined.assets.resolve(did) @@ -100,15 +100,7 @@ export class AgreementsApi extends Instantiable { const agreementId = await this.nevermined.keeper .getTemplateByName(templateName) - ?.createAgreementFromDDO( - agreementIdSeed, - ddo, - agreementParams, - consumer, - publisher, - undefined, - params, - ) + ?.createAgreementFromDDO(agreementIdSeed, ddo, agreementParams, from, undefined, txParams) return agreementId as string } @@ -116,7 +108,7 @@ export class AgreementsApi extends Instantiable { /** * Get the status of a service agreement. * @param agreementId - Service agreement ID. - * @param extended - Returns a complete status with dependencies. + * @param extended - If true returns a complete status with dependencies. * @returns status of the agreement */ public async status(agreementId: string, extended = false) { @@ -163,14 +155,14 @@ export class AgreementsApi extends Instantiable { * @param agreementId the agreement id * @param did the unique identifier of the asset * @param consumerAddress the address of the consumer - * @param account the user account + * @param from the user account * @returns true if the user has permissions */ public async isAccessGranted( agreementId: string, did: string, consumerAddress: string, - account: NvmAccount, + from: NvmAccount, ): Promise { const { accessConsumer } = await this.nevermined.keeper.templates.accessTemplate.getAgreementData(agreementId) @@ -181,7 +173,7 @@ export class AgreementsApi extends Instantiable { return await this.nevermined.keeper.conditions.accessCondition.checkPermissions( accessConsumer, did, - account, + from, ) } } diff --git a/src/nevermined/api/AssetsApi.ts b/src/nevermined/api/AssetsApi.ts index 1ffbcc371..d3bf50a0c 100644 --- a/src/nevermined/api/AssetsApi.ts +++ b/src/nevermined/api/AssetsApi.ts @@ -109,9 +109,23 @@ export class AssetsApi extends RegistryBaseApi { * You can find more information about how different data is stored in Nevermined here: * {@link https://docs.nevermined.io/docs/architecture/nevermined-data} * + * * @example + * ```ts + * const assetAttributes = AssetAttributes.getInstance({ + * metadata, + * price: assetPrice, + * serviceTypes: ['sales', 'access'] + * }) + * const ddo = await nevermined.assets.create( + * assetAttributes, + * publisher, + * PublishMetadata.IPFS + * ) + * ``` + * * @param assetAttributes - Attributes describing the asset + * @param from - The account publishing the asset * @param publicationOptions - Allows to specify the publication options of the off-chain and the on-chain data. @see {@link PublishOnChainOptions} and {@link PublishMetadataOptions} - * @param publisherAccount - The account publishing the asset * @param txParams - Optional transaction parameters * @returns The metadata of the asset created (DDO) * @@ -119,7 +133,7 @@ export class AssetsApi extends RegistryBaseApi { */ public create( assetAttributes: AssetAttributes, - publisherAccount: NvmAccount, + from: NvmAccount, publicationOptions: AssetPublicationOptions = { metadata: PublishMetadataOptions.OnlyMetadataAPI, did: PublishOnChainOptions.DIDRegistry, @@ -128,7 +142,7 @@ export class AssetsApi extends RegistryBaseApi { ): SubscribablePromise { return this.registerNeverminedAsset( assetAttributes, - publisherAccount, + from, publicationOptions, undefined, txParams, @@ -150,7 +164,7 @@ export class AssetsApi extends RegistryBaseApi { * * @param did - Decentralized ID representing the unique id of an asset in a Nevermined network. * @param metadata - Metadata describing the asset - * @param publisherAccount - Account of the user updating the metadata + * @param from - Account of the user updating the metadata * @param publishMetadata - It allows to specify where to store the metadata * @param txParams - Optional transaction parameters * @returns {@link DDO} The DDO updated @@ -158,11 +172,11 @@ export class AssetsApi extends RegistryBaseApi { public update( did: string, metadata: MetaData, - publisherAccount: NvmAccount, + from: NvmAccount, publishMetadata: PublishMetadataOptions = PublishMetadataOptions.OnlyMetadataAPI, txParams?: TxParameters, ): SubscribablePromise { - return this.updateAsset(did, metadata, publisherAccount, publishMetadata, txParams) + return this.updateAsset(did, metadata, from, publishMetadata, txParams) } /** @@ -170,28 +184,30 @@ export class AssetsApi extends RegistryBaseApi { * then sends the request to the publisher via the service endpoint (Node http service). * If the access service to purchase is having associated some price, it will make the payment * for that service. + * * @param did - Unique identifier of the asset to order * @param serviceReference - The service to order. By default is the access service, but it can be specified the service.index to refer a different specific service - * @param consumerAccount - The account of the user ordering the asset + * @param from - The account of the user ordering the asset * @param txParams - Optional transaction parameters * @returns The agreement ID identifying the order */ public order( did: string, serviceReference: ServiceType | number = 'access', - consumerAccount: NvmAccount, + from: NvmAccount, txParams?: TxParameters, ): SubscribablePromise { - return this.orderAsset(did, serviceReference, consumerAccount, txParams) + return this.orderAsset(did, serviceReference, from, txParams) } /** * Having previously ordered an "access" service (referenced via an "agreementId"). * This method allows to download the assets associated to that service. + * * @param agreementId - The unique identifier of the order placed for a service * @param did - Unique identifier of the asset ordered * @param serviceReference - The service to download. By default is the access service, but it can be specified the service.index to refer a different specific service - * @param consumerAccount - The account of the user who ordered the asset and is downloading the files + * @param from - The account of the user who ordered the asset and is downloading the files * @param resultPath - Where the files will be downloaded * @param fileIndex - The file to download. If not given or is -1 it will download all of them. * @param buyer - Key which represent the buyer @@ -202,7 +218,7 @@ export class AssetsApi extends RegistryBaseApi { agreementId: string, did: string, serviceReference: ServiceType | number, - consumerAccount: NvmAccount, + from: NvmAccount, resultPath?: string, fileIndex = -1, buyer?: string, @@ -236,7 +252,7 @@ export class AssetsApi extends RegistryBaseApi { did, agreementId, serviceEndpoint, - consumerAccount, + from, files, resultPath, fileIndex, @@ -262,7 +278,7 @@ export class AssetsApi extends RegistryBaseApi { } /** - * Returns the owner of an asset. + * Returns the owner from the signature included in the DDO. * @param did - Decentralized ID. * @returns The address of the owner of the asset */ @@ -294,7 +310,7 @@ export class AssetsApi extends RegistryBaseApi { * Transfer ownership of an asset. * @param did - Asset DID. * @param newOwner - Ethereum address of the new owner of the DID. - * @param owner - Account owning the DID and doing the transfer of ownership + * @param from - Account owning the DID and doing the transfer of ownership * @param newUserId - User Id of the new user getting the ownership of the asset * @param txParams - Transaction parameters * @returns Returns transaction receipt. @@ -302,12 +318,12 @@ export class AssetsApi extends RegistryBaseApi { public async transferOwnership( did: string, newOwner: string, - owner: NvmAccount, + from: NvmAccount, newUserId?: string, txParams?: TxParameters, ) { // const owner = await this.nevermined.assets.owner(did) - const ownerAddress = owner.getAddress() + const ownerAddress = from.getAddress() const ddo = await this.resolveAsset(did) ddo.proof = await ddo.generateProof(newOwner) @@ -333,7 +349,7 @@ export class AssetsApi extends RegistryBaseApi { await this.nevermined.services.metadata.updateDDO(did, updatedDDO) - return this.nevermined.keeper.didRegistry.transferDIDOwnership(did, newOwner, owner, txParams) + return this.nevermined.keeper.didRegistry.transferDIDOwnership(did, newOwner, from, txParams) } /** @@ -349,6 +365,11 @@ export class AssetsApi extends RegistryBaseApi { ).map(({ did }) => did) } + /** + * Retires the metadata of an asset from the Marketplace API. This allows the owner to unlist the asset from the marketplace. + * @param did - the unique identifier of the asset + * @returns the HTTP response + */ public async retire(did: string) { return this.nevermined.services.metadata.delete(did) } @@ -358,7 +379,7 @@ export class AssetsApi extends RegistryBaseApi { * This method only can be called successfully by the owner of the asset or a provider. * * @param did - The Decentralized Identifier of the asset. - * @param ownerAccount - The receiver account owner + * @param from - The account of the asset owner * @param resultPath - Path to be the files downloader * @param fileIndex - The index of the file * @param serviceType - Service type. 'access' by default @@ -368,7 +389,7 @@ export class AssetsApi extends RegistryBaseApi { */ public async download( did: string, - ownerAccount: NvmAccount, + from: NvmAccount, resultPath?: string, fileIndex = -1, serviceType: ServiceType = 'access', @@ -405,7 +426,7 @@ export class AssetsApi extends RegistryBaseApi { const accessToken = await this.nevermined.utils.jwt.getDownloadGrantToken( ddo.id, - ownerAccount, + from, buyer, babysig, ) @@ -418,21 +439,22 @@ export class AssetsApi extends RegistryBaseApi { /** * It grants permissions to an account for a specific asset represented by a DID. * Only can be called by the asset owner. + * * @param did - The unique identifier of the assert - * @param address - The account to grant the permissions - * @param ownerAccount - Account sending the request. It must be the owner of the asset + * @param grantAddress - The account address to grant the permissions + * @param from - Account sending the request. It must be the owner of the asset * @param txParams - Transaction parameters */ public async grantPermissions( did: string, - address: string, - ownerAccount: NvmAccount, + grantAddress: string, + from: NvmAccount, txParams?: TxParameters, ) { return await this.nevermined.keeper.didRegistry.grantPermission( did, - address, - ownerAccount, + grantAddress, + from, txParams, ) } @@ -440,21 +462,22 @@ export class AssetsApi extends RegistryBaseApi { /** * It revokes permissions to an account for a specific asset represented by a DID. * Only can be called by the asset owner. + * * @param did - The unique identifier of the assert - * @param address - The account to revoke the permissions - * @param ownerAccount - Account sending the request. It must be the owner of the asset + * @param revokeAddress - The account address to revoke the permissions + * @param from - Account sending the request. It must be the owner of the asset * @param txParams - Transaction parameters */ public async revokePermissions( did: string, - address: string, - ownerAccount: NvmAccount, + revokeAddress: string, + from: NvmAccount, txParams?: TxParameters, ) { return await this.nevermined.keeper.didRegistry.revokePermission( did, - address, - ownerAccount, + revokeAddress, + from, txParams, ) } diff --git a/src/nevermined/api/ComputeApi.ts b/src/nevermined/api/ComputeApi.ts index 68c5b4f44..77e09bb6d 100644 --- a/src/nevermined/api/ComputeApi.ts +++ b/src/nevermined/api/ComputeApi.ts @@ -84,7 +84,7 @@ export class ComputeApi extends RegistryBaseApi { * * @param did - Decentralized ID representing the unique id of an asset in a Nevermined network. * @param metadata - Metadata describing the asset - * @param publisherAccount - Account of the user updating the metadata + * @param from - Account of the user updating the metadata * @param publishMetadata - It allows to specify where to store the metadata * @param txParams - Optional transaction parameters * @returns {@link DDO} The DDO updated @@ -92,71 +92,66 @@ export class ComputeApi extends RegistryBaseApi { public update( did: string, metadata: MetaData, - publisherAccount: NvmAccount, + from: NvmAccount, publishMetadata: PublishMetadataOptions = PublishMetadataOptions.OnlyMetadataAPI, txParams?: TxParameters, ): SubscribablePromise { - return this.updateAsset(did, metadata, publisherAccount, publishMetadata, txParams) + return this.updateAsset(did, metadata, from, publishMetadata, txParams) } /** * Start the purchase/order of a compute service. Starts by signing the service agreement * then sends the request to the publisher via the service endpoint (Node http service). * @param did - Unique identifier of the asset to order - * @param consumerAccount - The account of the user ordering the asset + * @param from - The account of the user ordering the asset * @param txParams - Optional transaction parameters * @returns The agreement ID identifying the order */ public order( did: string, - consumerAccount: NvmAccount, + from: NvmAccount, txParams?: TxParameters, ): SubscribablePromise { - return this.orderAsset(did, 'compute', consumerAccount, txParams) + return this.orderAsset(did, 'compute', from, txParams) } /** * It triggers the execution of a compute job * @param agreementId - The unique identifier of the order placed for a service * @param workflowDid - The unique identifier of the Asset representing the workflow - * @param consumerAccount - The account of the user triggering the computation + * @param from - The account of the user triggering the computation * @returns If the execution is correct it returns the response given by the Nevermined Node */ public async execute( agreementId: string, workflowDid: string, - consumerAccount: NvmAccount, + from: NvmAccount, ): Promise { const { node } = this.nevermined.services - return (await node.execute(agreementId, workflowDid, consumerAccount)).workflowId + return (await node.execute(agreementId, workflowDid, from)).workflowId } /** * It returns the logs resulted by the execution of a Job * @param agreementId - The unique identifier of the order placed for a service * @param executionId - The unique identifier of the job executed - * @param consumerAccount - The account of the user triggering the computation + * @param from - The account of the user triggering the computation * @returns The logs resulted of the execution of the job */ - public async logs(agreementId: string, executionId: string, consumerAccount: NvmAccount) { - return await this.nevermined.services.node.computeLogs( - agreementId, - executionId, - consumerAccount, - ) + public async logs(agreementId: string, executionId: string, from: NvmAccount) { + return await this.nevermined.services.node.computeLogs(agreementId, executionId, from) } /** * It returns the status of a compute job * @param agreementId - The unique identifier of the order placed for a service * @param executionId - The unique identifier of the job executed - * @param consumerAccount - The account of the user triggering the computation + * @param from - The account of the user triggering the computation * @returns The status of the job */ - public async status(agreementId: string, executionId: string, consumerAccount: NvmAccount) { - return ( - await this.nevermined.services.node.computeStatus(agreementId, executionId, consumerAccount) - ).workflowStatus + public async status(agreementId: string, executionId: string, from: NvmAccount) { + return (await this.nevermined.services.node.computeStatus(agreementId, executionId, from)) + .workflowStatus } } diff --git a/src/nevermined/api/ConditionsApi.ts b/src/nevermined/api/ConditionsApi.ts index 8827f1838..9936e171d 100644 --- a/src/nevermined/api/ConditionsApi.ts +++ b/src/nevermined/api/ConditionsApi.ts @@ -50,8 +50,9 @@ export class ConditionsApi extends Instantiable { * @param did - The Asset ID. * @param amounts - Asset amounts to distribute. * @param receivers - Receivers of the rewards - * @param erc20TokenAddress - Account of sender. * @param from - Account of sender. + * @param erc20TokenAddress - ERC20 contract address of the token used for the payment if is the zero address, it will use the native token of the network (i.e ETH) + * @param txParams - Transaction parameters */ public async lockPayment( agreementId: string, @@ -174,8 +175,8 @@ export class ConditionsApi extends Instantiable { * @param amounts - Asset amounts to distribute. * @param receivers - Receivers of the rewards * @param did - Asset ID. - * @param erc20TokenAddress - Publisher address. * @param from - Account of sender. + * @param erc20TokenAddress - ERC20 contract address of the token used for the payment if is the zero address, it will use the native token of the network (i.e ETH) * @param txParams - Transaction parameters */ public async releaseReward( @@ -232,8 +233,10 @@ export class ConditionsApi extends Instantiable { * Releases the payment in escrow to the provider(s) of the sale * @param agreementId - The service agreement id for the nft sale. * @param ddo - The decentralized identifier of the asset containing the nfts. + * @param serviceReference - The index or reference of the service containing the nfts to transfer * @param nftAmount - Number of nfts bought. - * @param publisher - The publisher account. + * @param from - The account sending the transaction. + * @param txParams - Transaction parameters * @returns {@link true} if the funds were released successfully. */ public async releaseNftReward( @@ -241,8 +244,7 @@ export class ConditionsApi extends Instantiable { ddo: DDO, serviceReference: number | ServiceType = 'nft-sales', nftAmount: bigint, - publisher: NvmAccount, - from?: NvmAccount, + from: NvmAccount, txParams?: txParams, ) { const template = this.nevermined.keeper.templates.nftSalesTemplate @@ -263,7 +265,7 @@ export class ConditionsApi extends Instantiable { const txReceipt = await escrowPaymentCondition.fulfillInstance( instance.instances[2] as any, {}, - from || publisher, + from, txParams, ) @@ -279,15 +281,16 @@ export class ConditionsApi extends Instantiable { * Releases the payment in escrow to the provider(s) of the sale * @param agreementId - The service agreement id for the nft sale. * @param ddo - The decentralized identifier of the asset containing the nfts. - * @param publisher - The publisher account. + * @param serviceReference - The index or reference of the service containing the nfts to transfer + * @param from - The publisher account. + * @param txParams - Transaction parameters * @returns {@link true} if the funds were released successfully. */ public async releaseNft721Reward( agreementId: string, ddo: DDO, serviceReference: number | ServiceType = 'nft-sales', - publisher: NvmAccount, - from?: NvmAccount, + from: NvmAccount, txParams?: txParams, ) { const serviceIndex = ddo.findServiceByReference(serviceReference).index @@ -308,7 +311,7 @@ export class ConditionsApi extends Instantiable { const txReceipt = await escrowPaymentCondition.fulfillInstance( instance.instances[2] as any, {}, - from || publisher, + from, txParams, ) @@ -328,7 +331,9 @@ export class ConditionsApi extends Instantiable { * @param did - The decentralized identifier of the asset containing the nfts. * @param holder - The address of the holder (recipient of a previous nft transfer with `agreementId`). * @param nftAmount - The amount of nfts that the `holder` needs to have to fulfill the access condition. - * @param from - Account. + * @param contractAddress - The address of the nft contract. + * @param from - The account sending the transaction. + * @param txParams - Transaction parameters * @returns {@link true} if the holder is able to fulfill the condition */ public async holderNft( @@ -338,7 +343,7 @@ export class ConditionsApi extends Instantiable { nftAmount: bigint, contractAddress: string, from: NvmAccount, - params?: txParams, + txParams?: txParams, ) { const { nftHolderCondition } = this.nevermined.keeper.conditions @@ -349,7 +354,7 @@ export class ConditionsApi extends Instantiable { nftAmount, contractAddress || this.nevermined.keeper.nftUpgradeable.address, from, - params, + txParams, ) return this.isFulfilled(txReceipt, ConditionsApi.NFT_HOLDER_EVENT_FULFILLED_ABI) } @@ -361,7 +366,8 @@ export class ConditionsApi extends Instantiable { * @param agreementId - The service agreement id of the nft transfer. * @param ddo - The decentralized identifier of the asset containing the nfts. * @param holderAddress - The address of the holder (recipient of a previous nft transfer with `agreementId`). - * @param from - Account. + * @param from - The account sending the transaction. + * @param txParams - Transaction parameters * @returns {@link true} if the holder is able to fulfill the condition */ public async holderNft721( @@ -369,7 +375,7 @@ export class ConditionsApi extends Instantiable { ddo: DDO, holderAddress: string, from: NvmAccount, - params?: txParams, + txParams?: txParams, ) { const { nft721HolderCondition } = this.nevermined.keeper.conditions const accessService = ddo.findServiceByType('nft-access') @@ -382,7 +388,7 @@ export class ConditionsApi extends Instantiable { holderAddress, holder.parameters.find((p) => p.name === '_contractAddress')?.value as string, from, - params, + txParams, ) return this.isFulfilled(txReceipt, ConditionsApi.NFT_HOLDER_EVENT_FULFILLED_ABI) @@ -394,7 +400,8 @@ export class ConditionsApi extends Instantiable { * @param agreementId - The service agreement id of the nft transfer. * @param did - The decentralized identifier of the asset containing the nfts. * @param grantee - The address of the user trying to get access to the files. - * @param from - Account. + * @param from - The account sending the transaction. + * @param txParams - Transaction parameters * @returns {@link true} if the provider is able to fulfill the condition */ public async grantNftAccess( @@ -402,11 +409,11 @@ export class ConditionsApi extends Instantiable { did: string, grantee: string, from: NvmAccount, - params?: txParams, + txParams?: txParams, ) { const { nftAccessCondition } = this.nevermined.keeper.conditions - const txReceipt = await nftAccessCondition.fulfill(agreementId, did, grantee, from, params) + const txReceipt = await nftAccessCondition.fulfill(agreementId, did, grantee, from, txParams) return this.isFulfilled(txReceipt, ConditionsApi.GENERIC_EVENT_FULFILLED_ABI) } @@ -416,7 +423,8 @@ export class ConditionsApi extends Instantiable { * @param ddo - The decentralized identifier of the asset containing the nfts. * @param serviceIndex - The index of the service containing the nfts to transfer * @param nftAmount - The amount of nfts to transfer. - * @param from - Account. + * @param from - The account sending the transaction. + * @param txParams - Transaction parameters * @returns {@link true} if the transfer is successful */ public async transferNft( @@ -472,7 +480,8 @@ export class ConditionsApi extends Instantiable { * @param agreementId - The service agreement id of the nft transfer. * @param ddo - The decentralized identifier of the asset containing the nfts. * @param nftAmount - The amount of nfts to transfer. - * @param from - Account. + * @param from - The account sending the transaction. + * @param txParams - Transaction parameters * @returns {@link true} if the transfer is successful */ public async transferNftForDelegate( @@ -537,14 +546,15 @@ export class ConditionsApi extends Instantiable { * @param agreementId - The service agreement id of the nft transfer. * @param ddo - The decentralized identifier of the asset containing the nfts. * @param serviceIndex - The index of the service containing the nfts to transfer - * @param publisher - Account. + * @param from - The account sending the transaction. + * @param txParams - Transaction parameters * @returns {@link true} if the transfer is successful */ public async transferNft721( agreementId: string, ddo: DDO, serviceIndex: number, - publisher: NvmAccount, + from: NvmAccount, txParams?: txParams, ) { const { transferNft721Condition } = this.nevermined.keeper.conditions @@ -563,24 +573,26 @@ export class ConditionsApi extends Instantiable { const nft = await this.nevermined.contracts.loadNft721(instance.instances[1].list[5]) - await nft.setApprovalForAll(transferNft721Condition.address, true, publisher, txParams) + await nft.setApprovalForAll(transferNft721Condition.address, true, from, txParams) const txReceipt = await transferNft721Condition.fulfillInstance( instance.instances[1] as any, {}, - publisher, + from, txParams, ) - await nft.setApprovalForAll(transferNft721Condition.address, false, publisher, txParams) + await nft.setApprovalForAll(transferNft721Condition.address, false, from, txParams) return this.isFulfilled(txReceipt, ConditionsApi.TRANSFER_NFT_EVENT_FULFILLED_ABI) } - // private isFulfilled(contractReceipt: ContractTransactionReceipt): boolean { - // return (contractReceipt.logs as EventLog[]).some((e: EventLog) => e.eventName === 'Fulfilled') - // } - + /** + * Checks in the transaction receipt if the event Fulfilled was emitted.q + * @param txReceipt - the transaction receipt + * @param eventAbi - the contract ABI + * @returns true if the Fulfilled event was emitted + */ private isFulfilled(txReceipt: TransactionReceipt, eventAbi: Abi): boolean { const eventLogs = parseEventLogs({ abi: eventAbi, diff --git a/src/nevermined/api/ProvenanceApi.ts b/src/nevermined/api/ProvenanceApi.ts index 6710c0727..febdb1f48 100644 --- a/src/nevermined/api/ProvenanceApi.ts +++ b/src/nevermined/api/ProvenanceApi.ts @@ -5,7 +5,7 @@ import { zeroPadValue } from '../../nevermined/utils/BlockchainViemUtils' import { TxParameters } from '../../models/Transactions' /** - * Nevermined Provenance API. It allows to register and search entries in the Nevermined W3C Provenance registry + * The Nevermined Provenance API allows to register and search entries in the Nevermined W3C Provenance registry * You can find more information about Nevermined Provenance here: * {@link https://docs.nevermined.io/docs/architecture/specs/Spec-PROVENANCE} */ @@ -23,14 +23,18 @@ export class ProvenanceApi extends Instantiable { /** * Given a provenance id it returns the provenance details * @param provenanceId Unique identifier of a provenance entry - * @returns + * @returns {@link ProvenanceRegistry} object with the provenance details */ public async getProvenanceEntry(provenanceId: string) { return this.nevermined.keeper.didRegistry.getProvenanceEntry(provenanceId) } /** - * Implements the W3C PROV Usage action + * Implements the W3C PROV Usage action. + * + * @remarks + * This method can be called when want to track the usage of a DID. + * * @param provenanceId - Provenance ID * @param did - Identifier of the entity created * @param agentId - Agent Identifier @@ -66,6 +70,10 @@ export class ProvenanceApi extends Instantiable { /** * Implements the W3C PROV Derivation action + * + * @remarks + * This method can be called when want to track the derivation of a new DID from an existing DID. + * * @param provenanceId - Provenance ID * @param newEntityDid - Identifier of the new entity derived * @param usedEntityDid - Identifier of the entity used to derive the new entity @@ -101,6 +109,10 @@ export class ProvenanceApi extends Instantiable { /** * Implements the W3C PROV Association action + * + * @remarks + * This method can be called when want to track the association of an agent with a DID. + * * @param provenanceId - Provenance ID * @param did - Identifier of the entity created * @param agentId - Agent Identifier @@ -132,7 +144,11 @@ export class ProvenanceApi extends Instantiable { } /** - * Implements the W3C PROV Delegation action + * Implements the W3C PROV Delegation action. + * + * @remarks + * This method can be called when want to track the delegation of an agent to act on behalf of another agent. + * * @param provenanceId - Provenance ID * @param did - Identifier of the entity created * @param delegateAgentId - Delegate Agent Identifier @@ -170,22 +186,22 @@ export class ProvenanceApi extends Instantiable { } /** - * Add new DID provenance delegate. + * Add new DID provenance delegate. The delegate will be able to perform actions on behalf of the DID owner. * @param did - Identifier of the entity created - * @param delegated - Delegate Address + * @param delegatedAddress - Delegate Address * @param from - Sender account. * @param txParams - Transaction parameters * @returns {@link true} if the call succeeded. */ public async addDidProvenanceDelegate( did: string, - delegated: string, + delegatedAddress: string, from: NvmAccount, txParams?: TxParameters, ): Promise { await this.nevermined.keeper.didRegistry.addDidProvenanceDelegate( did, - delegated, + delegatedAddress, from, txParams, ) @@ -193,22 +209,22 @@ export class ProvenanceApi extends Instantiable { } /** - * Remove an existing DID delegate. + * Remove an existing DID as delegate. * @param did - Identifier of the entity created - * @param delegated - Delegate Address + * @param delegatedAddress - Delegate Address * @param from - Sender account. * @param txParams - Transaction parameters * @returns {@link true} if the call succeeded. */ public async removeDidProvenanceDelegate( did: string, - delegated: string, + delegatedAddress: string, from: NvmAccount, txParams?: TxParameters, ): Promise { await this.nevermined.keeper.didRegistry.removeDidProvenanceDelegate( did, - delegated, + delegatedAddress, from, txParams, ) @@ -218,15 +234,17 @@ export class ProvenanceApi extends Instantiable { /** * Check whether a given DID delegate exists * @param did - Identifier of the entity created - * @param delegated - Delegate Address + * @param delegatedAddress - Delegate Address + * @returns {@link true} if the address is a delegate. */ - public async isProvenanceDelegate(did: string, delegated: string) { - return this.nevermined.keeper.didRegistry.isProvenanceDelegate(did, delegated) + public async isProvenanceDelegate(did: string, delegatedAddress: string) { + return this.nevermined.keeper.didRegistry.isProvenanceDelegate(did, delegatedAddress) } /** * Retrieve the owner of the provenance record. * @param did - Identifier of the entity created + * @returns Address of the provenance owner. */ public async getProvenanceOwner(did: string) { return this.nevermined.keeper.didRegistry.getProvenanceOwner(did) diff --git a/src/nevermined/api/RegistryBaseApi.ts b/src/nevermined/api/RegistryBaseApi.ts index b236f5e15..075cd098a 100644 --- a/src/nevermined/api/RegistryBaseApi.ts +++ b/src/nevermined/api/RegistryBaseApi.ts @@ -43,7 +43,7 @@ export abstract class RegistryBaseApi extends Instantiable { * via the Nevermined APIs directly. It must accessed via the `assets`, `compute`, and `nfts` APIs. * * @param assetAttributes - Attributes describing the asset - * @param publisher - The account publishing the asset + * @param from - The account publishing the asset * @param publicationOptions - Allows to specify the publication options of the off-chain and the on-chain data. @see {@link PublishOnChainOptions} and {@link PublishMetadataOptions} * @param nftAttributes -Attributes describing the NFT (ERC-721) associated to the asset * @param txParams - Optional transaction parameters @@ -51,7 +51,7 @@ export abstract class RegistryBaseApi extends Instantiable { */ protected registerNeverminedAsset( assetAttributes: AssetAttributes, - publisher: NvmAccount, + from: NvmAccount, publicationOptions: AssetPublicationOptions, nftAttributes?: NFTAttributes, txParams?: TxParameters, @@ -64,7 +64,7 @@ export abstract class RegistryBaseApi extends Instantiable { // create ddo itself let ddo = DDO.getInstance( assetAttributes.metadata.userId as string, - publisher.getId(), + from.getId(), assetAttributes.appId, ) @@ -103,7 +103,7 @@ export abstract class RegistryBaseApi extends Instantiable { : undefined const serviceCreated = plugin.createService( - publisher, + from, assetAttributes.metadata, serviceAttributes, nftAttributes, @@ -121,10 +121,10 @@ export abstract class RegistryBaseApi extends Instantiable { this.logger.log('Generating proof') observer.next(CreateProgressStep.GeneratingProof) - await ddo.addProof(publisher.getId()) + await ddo.addProof(from.getId()) const didSeed = await ddo.generateDidSeed(ddo.proof.checksum) - await ddo.assignDid(didSeed, didRegistry, publisher) + await ddo.assignDid(didSeed, didRegistry, from) ddo = DDO.findAndReplaceDDOAttribute(ddo, '{DID}', ddo.shortId()) // TODO: Evaluate if we need to add the signature to the DDO @@ -241,7 +241,7 @@ export abstract class RegistryBaseApi extends Instantiable { nftAttributes.nftContractAddress, checksum, assetAttributes.providers || [this.config.neverminedNodeAddress], - publisher, + from, nftAttributesWithoutRoyalties, serviceEndpoint, ddoVersion.immutableUrl, @@ -254,7 +254,7 @@ export abstract class RegistryBaseApi extends Instantiable { nftAttributes.nftContractAddress, checksum, assetAttributes.providers || [this.config.neverminedNodeAddress], - publisher, + from, nftAttributesWithoutRoyalties, serviceEndpoint, ddoVersion.immutableUrl, @@ -270,14 +270,14 @@ export abstract class RegistryBaseApi extends Instantiable { await didRegistry.setDIDRoyalties( ddo.shortId(), nftAttributes.royaltyAttributes.scheme.address, - publisher, + from, txParams, ) observer.next(CreateProgressStep.SettingRoyalties) await nftAttributes.royaltyAttributes.scheme.setRoyalty( ddo.shortId(), nftAttributes.royaltyAttributes.amount, - publisher, + from, txParams, ) } @@ -287,7 +287,7 @@ export abstract class RegistryBaseApi extends Instantiable { didSeed, checksum, assetAttributes.providers || [this.config.neverminedNodeAddress], - publisher, + from, serviceEndpoint, ddoVersion.immutableUrl, SignatureUtils.hash(DEFAULT_REGISTRATION_ACTIVITY_ID), @@ -315,7 +315,8 @@ export abstract class RegistryBaseApi extends Instantiable { } /** - * Returns a DDO by DID. Depending of the resolution policy it prioritize the Metadata API or Immutable urls. + * Given an asset DID it returns the metadata of that asset represented by a DDO object. + * Depending of the resolution policy it prioritize fetching that Metadata from the Marketplace API or Immutable urls (like IPFS). * @param did - Decentralized ID. * @param policy - It specifies the resolve policy to apply. It allows to select that priorities during the asset resolution via Metadata API or Immutable URLs (IPFS, Filecoin, etc) * @returns {@link DDO} @@ -358,7 +359,7 @@ export abstract class RegistryBaseApi extends Instantiable { * Given a DID, updates the metadata associated to the asset. It also can upload this metadata to a remote decentralized stored depending on the `publishMetadata` parameter. * @param did - Decentralized ID representing the unique id of an asset in a Nevermined network. * @param metadata - Metadata describing the asset - * @param publisher - Account of the user updating the metadata + * @param from - Account of the user updating the metadata * @param publishMetadataOptions - It allows to specify where to store the metadata * @param txParams - Optional transaction parameters * @returns {@link DDO} The DDO updated @@ -366,7 +367,7 @@ export abstract class RegistryBaseApi extends Instantiable { protected updateAsset( did: string, metadata: MetaData, - publisher: NvmAccount, + from: NvmAccount, publishMetadataOptions: PublishMetadataOptions = PublishMetadataOptions.OnlyMetadataAPI, txParams?: TxParameters, ): SubscribablePromise { @@ -418,7 +419,7 @@ export abstract class RegistryBaseApi extends Instantiable { ddo.replaceService(metadataService.index, metadataService) observer.next(UpdateProgressStep.CalculateChecksum) - ddo.proof = await ddo.generateProof(publisher.getId()) + ddo.proof = await ddo.generateProof(from.getId()) const checksum = ddo.getProofChecksum() observer.next(UpdateProgressStep.AddVersionInDDO) @@ -452,7 +453,7 @@ export abstract class RegistryBaseApi extends Instantiable { await this.nevermined.keeper.didRegistry.updateMetadataUrl( ddo.id, checksum, - publisher, + from, metadataService.serviceEndpoint, ddoVersion.immutableUrl, txParams, @@ -473,7 +474,7 @@ export abstract class RegistryBaseApi extends Instantiable { * * @param did - Decentralized ID representing the unique id of an asset in a Nevermined network. * @param list - Needs the asset to be listed or unlisted - * @param publisher - Account of the user updating the metadata + * @param from - Account of the user updating the metadata * @param publishMetadata - It allows to specify where to store the metadata * @param txParams - Optional transaction parameters * @returns {@link DDO} The DDO updated @@ -481,7 +482,7 @@ export abstract class RegistryBaseApi extends Instantiable { public list( did: string, list: boolean, - publisher: NvmAccount, + from: NvmAccount, publishMetadata: PublishMetadataOptions = PublishMetadataOptions.OnlyMetadataAPI, txParams?: TxParameters, ): SubscribablePromise { @@ -512,7 +513,7 @@ export abstract class RegistryBaseApi extends Instantiable { return await this.updateAsset( did, metadataService.attributes, - publisher, + from, publishMetadata, txParams, ) @@ -525,7 +526,7 @@ export abstract class RegistryBaseApi extends Instantiable { * @param did - Decentralized ID representing the unique id of an asset in a Nevermined network. * @param newRating - New average rating of the asset * @param numVotesAdded - Number of new votes added to the rating, typically just 1 - * @param publisher - Account of the user updating the metadata + * @param from - Account of the user updating the metadata * @param publishMetadata - It allows to specify where to store the metadata * @param txParams - Optional transaction parameters * @returns {@link DDO} The DDO updated @@ -534,7 +535,7 @@ export abstract class RegistryBaseApi extends Instantiable { did: string, newRating: number, numVotesAdded = 1, - publisher: NvmAccount, + from: NvmAccount, publishMetadata: PublishMetadataOptions = PublishMetadataOptions.OnlyMetadataAPI, txParams?: TxParameters, ): SubscribablePromise { @@ -564,7 +565,7 @@ export abstract class RegistryBaseApi extends Instantiable { return await this.updateAsset( did, metadataService.attributes, - publisher, + from, publishMetadata, txParams, ) @@ -574,16 +575,18 @@ export abstract class RegistryBaseApi extends Instantiable { /** * Start the purchase/order of an asset's service. Starts by signing the service agreement * then sends the request to the publisher via the service endpoint (Node http service). + * * @param did - Decentralized ID. * @param serviceReference - Service. - * @param consumer - Consumer account. + * @param from - Consumer account. + * @param txParams - Transaction parameters * @returns The agreement ID. */ public orderAsset( did: string, serviceReference: ServiceType | number, - consumer: NvmAccount, - params?: TxParameters, + from: NvmAccount, + txParams?: TxParameters, ): SubscribablePromise { return new SubscribablePromise(async (observer) => { const agreementIdSeed = zeroX(generateId()) @@ -601,10 +604,10 @@ export abstract class RegistryBaseApi extends Instantiable { agreementIdSeed, ddo, serviceReference, - template.params(consumer), - consumer, - consumer, - params, + template.params(from), + from, + from, + txParams, (a) => observer.next(a), ) @@ -617,7 +620,7 @@ export abstract class RegistryBaseApi extends Instantiable { if ( agreementData.accessConsumer === ZeroAddress || - agreementData.accessConsumer.toLowerCase() !== consumer.getId().toLowerCase() + agreementData.accessConsumer.toLowerCase() !== from.getId().toLowerCase() ) throw new AssetError( `Agreement Id ${agreementId} not found on-chain. Agreement Data ${JSON.stringify( @@ -643,6 +646,11 @@ export abstract class RegistryBaseApi extends Instantiable { } } + /** + * It returns the priced metadata information of an asset + * @param assetPrice the asset price + * @returns {@link PricedMetadataInformation} + */ private async getPriced(assetPrice: AssetPrice | undefined): Promise { if (assetPrice === undefined) { return { diff --git a/src/nevermined/api/nfts/NFT1155Api.ts b/src/nevermined/api/nfts/NFT1155Api.ts index b9b409756..9294a4b9e 100644 --- a/src/nevermined/api/nfts/NFT1155Api.ts +++ b/src/nevermined/api/nfts/NFT1155Api.ts @@ -36,7 +36,7 @@ export class NFT1155Api extends NFTsBaseApi { * ) * ``` * - * @param cpnfig - The Nevermined config + * @param config - The Nevermined config * @param nftContractInstance - If there is already deployed an instance of `Nft1155Contract` * @param nftContractAddress - If the `Nft1155Contract` is deployed in an address it will connect to that contract * @returns The NFTs 1155 API instance {@link NFT1155Api}. @@ -58,7 +58,7 @@ export class NFT1155Api extends NFTsBaseApi { } /** - * Gets the ERC-721 NFT Contract address + * Gets the ERC-1155 NFT Contract address * @returns The NFT contract address */ public get address(): string { @@ -97,8 +97,8 @@ export class NFT1155Api extends NFTsBaseApi { * ) * ``` * - * @param nftAttributes -Attributes describing the NFT (ERC-721) associated to the asset - * @param publisher - The account publishing the asset + * @param nftAttributes -Attributes describing the NFT (ERC-1155) associated to the asset + * @param from - The account publishing the asset * @param publicationOptions - Allows to specify the publication options of the off-chain and the on-chain data. @see {@link PublishOnChainOptions} and {@link PublishMetadataOptions} * @param txParams - Optional transaction parameters * @@ -106,7 +106,7 @@ export class NFT1155Api extends NFTsBaseApi { */ public create( nftAttributes: NFTAttributes, - publisher: NvmAccount, + from: NvmAccount, publicationOptions: AssetPublicationOptions = { metadata: PublishMetadataOptions.OnlyMetadataAPI, did: PublishOnChainOptions.DIDRegistry, @@ -115,7 +115,7 @@ export class NFT1155Api extends NFTsBaseApi { ): SubscribablePromise { return this.registerNeverminedAsset( nftAttributes as AssetAttributes, - publisher, + from, publicationOptions, nftAttributes, txParams, @@ -123,7 +123,7 @@ export class NFT1155Api extends NFTsBaseApi { } /** - * Mint NFTs associated with an asset. + * It mints the NFTs associated with an asset. * * @remarks * This function can be called multiple times as long as the minting does not exceed the maximum cap set during creation. @@ -140,7 +140,7 @@ export class NFT1155Api extends NFTsBaseApi { * @param did - The Decentralized Identifier of the NFT asset. * @param nftAmount - The amount of NFTs to mint. * @param receiver - Account address of the NFT receiver, if `undefined` the minter account will receive the NFT/s - * @param account - The account to mint the NFT. * + * @param from - The account minting the NFT. * * @param data - Data * @param txParams - Optional transaction parameters. * @@ -150,22 +150,22 @@ export class NFT1155Api extends NFTsBaseApi { did: string, nftAmount: bigint, receiver: string | undefined, - account: NvmAccount, + from: NvmAccount, data?: string, txParams?: TxParameters, ) { return await this.nftContract.mint( - receiver || account.getId(), + receiver || from.getId(), did, nftAmount, - account, + from, data || '0x', txParams, ) } /** - * Burn NFTs associated with an asset. + * It burns NFTs associated with an asset. * * @remarks * The publisher can only burn NFTs that it owns. NFTs that were already transferred cannot be burned by the publisher. @@ -181,22 +181,17 @@ export class NFT1155Api extends NFTsBaseApi { * * @param tokenId - The Decentralized Identifier of the NFT asset. * @param nftAmount - The amount of NFTs to burn. - * @param account - The account of the publisher of the NFT. + * @param from - The account of the publisher of the NFT with permissions to burn. * @param txParams - Optional transaction parameters. * * @returns The {@link TransactionReceipt} */ - public async burn( - tokenId: string, - nftAmount: bigint, - account: NvmAccount, - txParams?: TxParameters, - ) { - return await this.nftContract.burn(account, tokenId, nftAmount, txParams) + public async burn(tokenId: string, nftAmount: bigint, from: NvmAccount, txParams?: TxParameters) { + return await this.nftContract.burn(from, tokenId, nftAmount, txParams) } /** - * Burn NFTs associated with an asset of a specific account. + * Burns NFTs associated with an asset of a specific account. * * @remarks * The publisher can only burn NFTs of an account if is an operator. NFTs that were already transferred cannot be burned by the publisher. @@ -214,7 +209,7 @@ export class NFT1155Api extends NFTsBaseApi { * @param holder - The address of the account that holds the NFTs. * @param tokenId - The TokenId of the NFT * @param nftAmount - The amount of NFTs to burn. - * @param account - The account of the publisher of the NFT. + * @param from - The account of the publisher of the NFT. * @param txParams - Optional transaction parameters. * * @returns The {@link TransactionReceipt} @@ -223,16 +218,17 @@ export class NFT1155Api extends NFTsBaseApi { holder: string, tokenId: string, nftAmount: bigint, - account: NvmAccount, + from: NvmAccount, txParams?: TxParameters, ) { - return await this.nftContract.burnFromHolder(holder, tokenId, nftAmount, account, txParams) + return await this.nftContract.burnFromHolder(holder, tokenId, nftAmount, from, txParams) } // TODO: We need to improve this to allow for secondary market sales // Right now it fetches the rewards from the DDO which don't change. + /** - * Buy NFTs. + * It orders NFTs. * * @remarks * This will lock the funds of the consumer in escrow pending the transfer of the NFTs @@ -245,7 +241,7 @@ export class NFT1155Api extends NFTsBaseApi { * * @param did - The Decentralized Identifier of the NFT asset. * @param numberEditions - The amount of NFTs to buy. - * @param consumer - The account of the NFT buyer. + * @param from - The account of the NFT buyer. * @param serviceReference - The reference to identify wich service within the DDO to order * @param txParams - Optional transaction parameters. * @@ -254,7 +250,7 @@ export class NFT1155Api extends NFTsBaseApi { public order( did: string, numberEditions: bigint, - consumer: NvmAccount, + from: NvmAccount, serviceReference: ServiceType | number = 'nft-sales', txParams?: TxParameters, ): SubscribablePromise { @@ -266,7 +262,7 @@ export class NFT1155Api extends NFTsBaseApi { const service = ddo.findServiceByReference(serviceReference) as ServiceNFTSales const params = await nftSalesTemplate.getParamsFromService( - consumer.getId(), + from.getId(), numberEditions, service, ) @@ -277,8 +273,8 @@ export class NFT1155Api extends NFTsBaseApi { ddo, serviceReference, params, - consumer, - consumer, + from, + from, txParams, (a) => observer.next(a), ) @@ -303,18 +299,19 @@ export class NFT1155Api extends NFTsBaseApi { * * @example * ```ts - * const receipt = await nevermined.nfts721.claim( + * const receipt = await nevermined.nfts1155.claim( * agreementId, - * editor.getId(), - * subscriber.getId(), - * 1n + * publisherAddress, + * subscriberAddress, + * 1n, + * did * ) * ``` * * @param agreementId - The NFT sales agreement id. * @param nftHolder - The address of the current owner of the NFT. * @param nftReceiver - The address where the NFT should be transferred. - * @param numberEditions - The number of NFT editions to transfer. If the NFT is ERC-721 it should be 1 + * @param numberEditions - The number of NFT editions to transfer. If the NFT is ERC-1155 it should be 1 * @param did - The Decentralized Identifier of the asset. * @param serviceIndex - The index of the service in the DDO that will be claimed * @@ -359,7 +356,7 @@ export class NFT1155Api extends NFTsBaseApi { * @param agreementId - The NFT sales agreement id. * @param did - The Decentralized identifier of the NFT asset. * @param nftAmount - The number of NFTs to transfer. - * @param publisher - The current owner of the NFTs. + * @param from - The current owner of the NFTs. * @param serviceReference - The reference to identify wich service within the DDO to transfer * @param txParams - Optional transaction parameters. * @returns true if the transfer was successful. @@ -371,7 +368,7 @@ export class NFT1155Api extends NFTsBaseApi { agreementId: string, did: string, nftAmount: bigint, - publisher: NvmAccount, + from: NvmAccount, serviceReference: number | ServiceType = 'nft-sales', txParams?: TxParameters, ): Promise { @@ -384,7 +381,7 @@ export class NFT1155Api extends NFTsBaseApi { ddo, service.index, nftAmount, - publisher, + from, txParams, ) @@ -415,7 +412,7 @@ export class NFT1155Api extends NFTsBaseApi { * @param did - The Decentralized identifier of the NFT asset. * @param serviceReference - The reference to identify wich service within the DDO to release rewards * @param nftAmount - The amount of NFTs to transfer. - * @param publisher - The current owner of the NFTs. + * @param from - The current owner of the NFTs. * @param txParams - Optional transaction parameters. * * @returns true if the funds release was successful. @@ -428,7 +425,7 @@ export class NFT1155Api extends NFTsBaseApi { did: string, serviceReference: number | ServiceType = 'nft-sales', nftAmount: bigint, - publisher: NvmAccount, + from: NvmAccount, txParams?: TxParameters, ): Promise { const { agreements } = this.nevermined @@ -440,8 +437,7 @@ export class NFT1155Api extends NFTsBaseApi { ddo, service.index, nftAmount, - publisher, - undefined, + from, txParams, ) @@ -597,7 +593,6 @@ export class NFT1155Api extends NFTsBaseApi { serviceReference, nftAmount, owner, - undefined, txParams, ) @@ -659,7 +654,7 @@ export class NFT1155Api extends NFTsBaseApi { } /** - * Get the details of an NFT + * Get the details of a NFT * * @example * ```ts diff --git a/src/nevermined/api/nfts/NFT721Api.ts b/src/nevermined/api/nfts/NFT721Api.ts index c2a322cff..455e15ab4 100644 --- a/src/nevermined/api/nfts/NFT721Api.ts +++ b/src/nevermined/api/nfts/NFT721Api.ts @@ -93,7 +93,7 @@ export class NFT721Api extends NFTsBaseApi { * ``` * * @param nftAttributes -Attributes describing the NFT (ERC-721) associated to the asset - * @param publisher - The account publishing the asset + * @param from - The account publishing the asset * @param publicationOptions - Allows to specify the publication options of the off-chain and the on-chain data. @see {@link PublishOnChainOptions} and {@link PublishMetadataOptions} * @param txParams - Optional transaction parameters * @@ -101,7 +101,7 @@ export class NFT721Api extends NFTsBaseApi { */ public create( nftAttributes: NFTAttributes, - publisher: NvmAccount, + from: NvmAccount, publicationOptions: AssetPublicationOptions = { metadata: PublishMetadataOptions.OnlyMetadataAPI, did: PublishOnChainOptions.DIDRegistry, @@ -110,7 +110,7 @@ export class NFT721Api extends NFTsBaseApi { ): SubscribablePromise { return this.registerNeverminedAsset( nftAttributes as AssetAttributes, - publisher, + from, publicationOptions, nftAttributes, txParams, @@ -130,7 +130,7 @@ export class NFT721Api extends NFTsBaseApi { * ``` * * @param did - The Decentralized Identifier of the NFT asset. - * @param consumer - The account of the NFT buyer. + * @param from - The account of the NFT buyer. * @param serviceReference - The reference to identify wich service within the DDO to order * @param txParams - Optional transaction parameters. * @@ -138,7 +138,7 @@ export class NFT721Api extends NFTsBaseApi { */ public order( did: string, - consumer: NvmAccount, + from: NvmAccount, serviceReference: number | ServiceType = 'nft-sales', txParams?: TxParameters, ): SubscribablePromise { @@ -153,9 +153,9 @@ export class NFT721Api extends NFTsBaseApi { agreementIdSeed, ddo, serviceReference, - nft721SalesTemplate.params(consumer.getId()), - consumer, - consumer, + nft721SalesTemplate.params(from.getId()), + from, + from, txParams, (a) => observer.next(a), ) @@ -206,7 +206,8 @@ export class NFT721Api extends NFTsBaseApi { } /** - * Transfer NFT-721 to the consumer. + * It transfers NFT-721 to the consumer. + * This method only will work if called by the owner of the asset or a provider. * * @remarks * A publisher/provider will check if the consumer put the funds in escrow and @@ -219,7 +220,7 @@ export class NFT721Api extends NFTsBaseApi { * * @param agreementId - The NFT sales agreement id. * @param did - The Decentralized identifier of the NFT asset. - * @param publisher - The current owner of the NFTs. + * @param from - The current owner of the NFTs. * @param serviceReference - The reference to identify wich service within the DDO to transfer * @param txParams - Optional transaction parameters. * @@ -231,7 +232,7 @@ export class NFT721Api extends NFTsBaseApi { public async transfer( agreementId: string, did: string, - publisher: NvmAccount, + from: NvmAccount, serviceReference: number | ServiceType = 'nft-sales', txParams?: TxParameters, ): Promise { @@ -243,7 +244,7 @@ export class NFT721Api extends NFTsBaseApi { agreementId, ddo, service.index, - publisher, + from, txParams, ) if (!result) { @@ -270,7 +271,7 @@ export class NFT721Api extends NFTsBaseApi { * * @param agreementId - The NFT sales agreement id. * @param did - The Decentralized identifier of the NFT asset. - * @param publisher - The current owner of the NFTs. + * @param from - The current owner of the NFTs. * @param serviceReference - The reference to identify wich service within the DDO to release rewards * @param txParams - Optional transaction parameters. * @@ -282,7 +283,7 @@ export class NFT721Api extends NFTsBaseApi { public async releaseRewards( agreementId: string, did: string, - publisher: NvmAccount, + from: NvmAccount, serviceReference: number | ServiceType = 'nft-sales', txParams?: TxParameters, ): Promise { @@ -295,8 +296,7 @@ export class NFT721Api extends NFTsBaseApi { agreementId, ddo, service.index, - publisher, - undefined, + from, txParams, ) @@ -308,7 +308,7 @@ export class NFT721Api extends NFTsBaseApi { } /** - * Mint NFTs associated with an asset. + * It mints NFTs associated with an asset. * * This function can be called multiple times as long as the minting does not exceed the maximum cap set during creation. * @@ -317,12 +317,12 @@ export class NFT721Api extends NFTsBaseApi { * await nevermined.nfts721.mint(ddo.id, artist) * ``` * @param did - The Decentralized Identifier of the NFT asset. - * @param publisher - The account of the minter + * @param from - The account of the minter * @param txParams - Optional transaction parameters. * @returns The {@link TransactionReceipt} */ - public async mint(did: string, publisher: NvmAccount, txParams?: TxParameters) { - return await this.nftContract.mint(did, publisher, txParams) + public async mint(did: string, from: NvmAccount, txParams?: TxParameters) { + return await this.nftContract.mint(did, from, txParams) } /** @@ -340,13 +340,13 @@ export class NFT721Api extends NFTsBaseApi { * ``` * * @param tokenId - The identifier of the token to burn - * @param account - The account of the publisher of the NFT. + * @param from - The account of the publisher of the NFT. * @param txParams - Optional transaction parameters. * * @returns The {@link TransactionReceipt} */ - public async burn(tokenId: string, account: NvmAccount, txParams?: TxParameters) { - return await this.nftContract.burn(tokenId, account, txParams) + public async burn(tokenId: string, from: NvmAccount, txParams?: TxParameters) { + return await this.nftContract.burn(tokenId, from, txParams) } /** @@ -419,7 +419,7 @@ export class NFT721Api extends NFTsBaseApi { } /** - * Given some information, it gets the owner of the NFT + * Given some information, it gets the public address of the asset owner * * @example * ```ts @@ -461,7 +461,6 @@ export class NFT721Api extends NFTsBaseApi { * ``` * * @param did - The Decentralized identifier of the NFT asset. - * @param nftTokenAddress - The address of the ERC-721 contract. * @param agreementId - The NFT sales agreement id. * * @returns The address of the NFT owner. @@ -557,7 +556,6 @@ export class NFT721Api extends NFTsBaseApi { ddo, service.index, owner, - undefined, txParams, ) @@ -641,6 +639,12 @@ export class NFT721Api extends NFTsBaseApi { return this._details(did, 721) } + /** + * It checks if an address is an operator of the NFT associated to the asset + * @param did - The Decentralized identifier of the NFT asset. + * @param address - The address to check if operator status + * @returns true if the address is an operator of the NFT + */ public async isOperatorOfDID(did: string, address: string): Promise { return super.isOperatorOfDID(did, address, 721) } diff --git a/src/nevermined/api/nfts/NFTsBaseApi.ts b/src/nevermined/api/nfts/NFTsBaseApi.ts index f8aec6c6f..02c615c27 100644 --- a/src/nevermined/api/nfts/NFTsBaseApi.ts +++ b/src/nevermined/api/nfts/NFTsBaseApi.ts @@ -252,7 +252,7 @@ export abstract class NFTsBaseApi extends RegistryBaseApi { * @param assetPrice - The current setup of asset rewards. * @param nftAmount - The number of NFTs put up for secondary sale. * @param provider - The address that will be the provider of the secondary sale. - * @param owner - The account of the current owner. + * @param from - The account of the current owner. * * @returns the agreementId of the secondary sale. * @@ -266,7 +266,7 @@ export abstract class NFTsBaseApi extends RegistryBaseApi { nftTransfer: boolean, provider: string, token: Token, - owner: NvmAccount, + from: NvmAccount, ): Promise { const serviceType: ServiceType = 'nft-sales' const { nftSalesTemplate } = this.nevermined.keeper.templates @@ -276,12 +276,12 @@ export abstract class NFTsBaseApi extends RegistryBaseApi { nftSalesServiceAgreementTemplate.conditions = getConditionsByParams( serviceType, nftSalesServiceAgreementTemplate.conditions, - owner.getId(), + from.getId(), assetPrice, ddo.id, token.address, undefined, - provider || owner.getId(), + provider || from.getId(), nftAmount, nftTransfer, ) @@ -296,7 +296,7 @@ export abstract class NFTsBaseApi extends RegistryBaseApi { attributes: { main: { name: 'nftSalesAgreement', - creator: owner.getId(), + creator: from.getId(), datePublished: new Date().toISOString().replace(/\.[0-9]{3}/, ''), timeout: 86400, }, @@ -331,9 +331,11 @@ export abstract class NFTsBaseApi extends RegistryBaseApi { * ) * ``` * - * @param consumer - The account of the buyer/consumer. + * @param from - The account of the buyer/consumer. * @param nftAmount - The number of assets to buy. 1 by default. - * @param agreementId - The agreementId of the initial sales agreement created off-chain. + * @param agreementIdSeed - The seed of the initial sales agreement created off-chain. + * @param conditionsTimeout - The timeout for the conditions. + * @param txParams - Optional transaction parameters * * @returns true if the buy was successful. * @@ -341,7 +343,7 @@ export abstract class NFTsBaseApi extends RegistryBaseApi { * Thrown if there is an error buying the NFT. */ public async buySecondaryMarketNft( - consumer: NvmAccount, + from: NvmAccount, nftAmount = 1n, agreementIdSeed: string, conditionsTimeout: number[] = [86400, 86400, 86400], @@ -373,9 +375,8 @@ export abstract class NFTsBaseApi extends RegistryBaseApi { const agreementId = await nftSalesTemplate.createAgreementFromDDO( agreementIdSeed, ddo, - nftSalesTemplate.params(consumer.getId(), nftAmount, currentNftHolder.getId()), - consumer, - consumer, + nftSalesTemplate.params(from.getId(), nftAmount, currentNftHolder.getId()), + from, conditionsTimeout, txParams, ) @@ -392,7 +393,7 @@ export abstract class NFTsBaseApi extends RegistryBaseApi { ddo.id, assetPrice.getAmounts(), assetPrice.getReceivers(), - consumer, + from, tokenAddress.value as string, txParams, ) @@ -414,7 +415,7 @@ export abstract class NFTsBaseApi extends RegistryBaseApi { * ``` * * @param did - The Decentralized Identifier of the NFT asset. - * @param consumer - The NFT holder account. + * @param from - The user account holding NFTs (after purchase) requesting the access * @param destination - The download destination for the files. * @param fileIndex - The index of the file. If unset will download all the files in the asset. * @param agreementId - The NFT sales agreement id. @@ -425,7 +426,7 @@ export abstract class NFTsBaseApi extends RegistryBaseApi { */ public async access( did: string, - consumer: NvmAccount, + from: NvmAccount, destination?: string, fileIndex?: number, agreementId = '0x', @@ -446,7 +447,7 @@ export abstract class NFTsBaseApi extends RegistryBaseApi { agreementId, ddo.id, accessService.index, - consumer, + from, buyer, babysig, ) @@ -482,11 +483,11 @@ export abstract class NFTsBaseApi extends RegistryBaseApi { * ``` * * @param did - The did of the asset with a webService resource and an associated subscription - * @param account - Account of the user requesting the token + * @param from - Account of the user requesting the token * * @returns {@link SubscriptionToken} */ - public async getSubscriptionToken(did: string, account: NvmAccount): Promise { - return this.nevermined.services.node.getSubscriptionToken(did, account) + public async getSubscriptionToken(did: string, from: NvmAccount): Promise { + return this.nevermined.services.node.getSubscriptionToken(did, from) } } diff --git a/src/nevermined/api/nfts/PoapApi.ts b/src/nevermined/api/nfts/PoapApi.ts index 2de2e89ec..43e37d01f 100644 --- a/src/nevermined/api/nfts/PoapApi.ts +++ b/src/nevermined/api/nfts/PoapApi.ts @@ -6,7 +6,17 @@ import { NvmAccount } from '../../../models/NvmAccount' import { Nevermined } from '../../../nevermined/Nevermined' import { NFT721Api } from './NFT721Api' +/** + * Class to handle POAP NFTs (ERC-721) API + */ export class PoapNFTApi extends NFT721Api { + /** + * It gets a POAP NFT (ERC-721) instance + * @param config - The Nevermined config + * @param nftContractAddress - If the POAP Contract is deployed in an address it will connect to that contract + * @param solidityABI - The ABI of the POAP Contract + * @returns The POAP API instance {@link PoapNFTApi}. + */ public static async getInstanceUsingABI( config: InstantiableConfig, nftContractAddress: string, @@ -24,6 +34,14 @@ export class PoapNFTApi extends NFT721Api { return instance } + /** + * It deploys a new instance of the POAP NFT (ERC-721) contract + * @param config - The Nevermined config + * @param contractABI - The ABI of the POAP Contract + * @param from - The account that will deploy the contract + * @param args - The list of arguments passed to the contract when is initialized + * @returns The POAP API instance {@link PoapNFTApi}. + */ public static async deployInstance( config: NeverminedOptions, contractABI: any, diff --git a/src/nevermined/api/nfts/SoulBoundApi.ts b/src/nevermined/api/nfts/SoulBoundApi.ts index beed8fa09..0858e9156 100644 --- a/src/nevermined/api/nfts/SoulBoundApi.ts +++ b/src/nevermined/api/nfts/SoulBoundApi.ts @@ -7,6 +7,13 @@ import { Nevermined } from '../../../nevermined/Nevermined' import { NFT721Api } from '../../../nevermined/api/nfts/NFT721Api' export class SoulBoundNFTApi extends NFT721Api { + /** + * It gets a SoulBound NFT (ERC-721) instance + * @param config - The Nevermined config + * @param nftContractAddress - If the SoulBound Contract is deployed in an address it will connect to that contract + * @param solidityABI - The ABI of the SoulBound Contract + * @returns The SoulBound API instance {@link SoulBoundNFTApi}. + */ public static async getInstanceUsingABI( config: InstantiableConfig, nftContractAddress: string, @@ -24,6 +31,14 @@ export class SoulBoundNFTApi extends NFT721Api { return instance } + /** + * It deploys a new instance of the SoulBound NFT (ERC-721) contract + * @param config - The Nevermined config + * @param contractABI - The ABI of the SoulBound Contract + * @param from - The account that will deploy the contract + * @param args - The list of arguments passed to the contract when is initialized + * @returns The SoulBound API instance {@link SoulBoundNFTApi}. + */ public static async deployInstance( config: NeverminedOptions, contractABI: any, diff --git a/src/nevermined/api/nfts/SubscriptionCreditsNFTApi.ts b/src/nevermined/api/nfts/SubscriptionCreditsNFTApi.ts index fc34cb307..3d162b42b 100644 --- a/src/nevermined/api/nfts/SubscriptionCreditsNFTApi.ts +++ b/src/nevermined/api/nfts/SubscriptionCreditsNFTApi.ts @@ -6,7 +6,17 @@ import { NvmAccount } from '../../../models/NvmAccount' import { Nevermined } from '../../../nevermined/Nevermined' import { NFT1155Api } from './NFT1155Api' +/* + * Class to handle Subscription Credits NFT based on ERC-1155 API + */ export class SubscriptionCreditsNFTApi extends NFT1155Api { + /** + * It gets a Subscription NFT (ERC-1155) instance + * @param config - The Nevermined config + * @param nftContractAddress - If the Subscription NFT Contract is deployed in an address it will connect to that contract + * @param solidityABI - The ABI of the Contract + * @returns The Subscription NFT API instance {@link SubscriptionCreditsNFTApi}. + */ public static async getInstanceUsingABI( config: InstantiableConfig, nftContractAddress: string, @@ -24,6 +34,14 @@ export class SubscriptionCreditsNFTApi extends NFT1155Api { return instance } + /** + * It deploys a new instance of the Subscription NFT (ERC-1155) contract + * @param config - The Nevermined config + * @param contractABI - The ABI of the Subscription NFT Contract + * @param from - The account that will deploy the contract + * @param args - The list of arguments passed to the contract when is initialized + * @returns The Subscription NFT API instance {@link SubscriptionCreditsNFTApi}. + */ public static async deployInstance( config: NeverminedOptions, contractABI: any, diff --git a/src/nevermined/api/nfts/SubscriptionNFTApi.ts b/src/nevermined/api/nfts/SubscriptionNFTApi.ts index fccfe9d9a..cc21824ee 100644 --- a/src/nevermined/api/nfts/SubscriptionNFTApi.ts +++ b/src/nevermined/api/nfts/SubscriptionNFTApi.ts @@ -6,7 +6,17 @@ import { NvmAccount } from '../../../models/NvmAccount' import { Nevermined } from '../../../nevermined/Nevermined' import { NFT721Api } from './NFT721Api' +/* + * Class to handle Subscription NFTs based on ERC-721 API + */ export class SubscriptionNFTApi extends NFT721Api { + /** + * It gets a Subscription NFT (ERC-721) instance + * @param config - The Nevermined config + * @param nftContractAddress - If the Subscription NFT Contract is deployed in an address it will connect to that contract + * @param solidityABI - The ABI of the Contract + * @returns The Subscription NFT API instance {@link SubscriptionNFTApi}. + */ public static async getInstanceUsingABI( config: InstantiableConfig, nftContractAddress: string, @@ -24,6 +34,14 @@ export class SubscriptionNFTApi extends NFT721Api { return instance } + /** + * It deploys a new instance of the Subscription NFT (ERC-721) contract + * @param config - The Nevermined config + * @param contractABI - The ABI of the Subscription NFT Contract + * @param from - The account that will deploy the contract + * @param args - The list of arguments passed to the contract when is initialized + * @returns The Subscription NFT API instance {@link SubscriptionNFTApi}. + */ public static async deployInstance( config: NeverminedOptions, contractABI: any, From 5d2ebe317b51c8f88a5458cbdc89a77462f25745 Mon Sep 17 00:00:00 2001 From: Aitor <1726644+aaitor@users.noreply.github.com> Date: Tue, 11 Jun 2024 13:05:34 +0200 Subject: [PATCH 2/4] test: adapting to the small api refactor --- integration/nevermined/ConsumeExternalDDOAsset.test.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/integration/nevermined/ConsumeExternalDDOAsset.test.ts b/integration/nevermined/ConsumeExternalDDOAsset.test.ts index 60b1496f9..4be17b848 100644 --- a/integration/nevermined/ConsumeExternalDDOAsset.test.ts +++ b/integration/nevermined/ConsumeExternalDDOAsset.test.ts @@ -97,7 +97,6 @@ describe('Consume Asset (Documentation example)', () => { 'access', nevermined.keeper.templates.accessTemplate.params(consumer), consumer, - publisher, ) assert.isDefined(agreementId) From d4df2a453c9ad9dbedcca1cf6b54e819ed777bca Mon Sep 17 00:00:00 2001 From: Aitor <1726644+aaitor@users.noreply.github.com> Date: Tue, 11 Jun 2024 13:16:05 +0200 Subject: [PATCH 3/4] test: adapting tests after api refactor --- .../nevermined/NFT721Templates.test.ts | 2 - integration/nevermined/NFTTemplates.test.ts | 4 - .../nevermined/RegisterAccessTemplate.test.ts | 1 - ...sterEscrowComputeExecutionTemplate.test.ts | 1 - .../nevermined/SecondaryMarket.test.ts | 4 - src/nevermined/utils/BlockchainViemUtils.ts | 135 +++++++++++++++--- 6 files changed, 113 insertions(+), 34 deletions(-) diff --git a/integration/nevermined/NFT721Templates.test.ts b/integration/nevermined/NFT721Templates.test.ts index 3f52f5b72..c74231369 100644 --- a/integration/nevermined/NFT721Templates.test.ts +++ b/integration/nevermined/NFT721Templates.test.ts @@ -766,7 +766,6 @@ describe('NFT721Templates E2E', () => { ddo, nft721AccessTemplate.params(collector1.getId()), collector1, - collector1, ) assert.isDefined(result) @@ -816,7 +815,6 @@ describe('NFT721Templates E2E', () => { ddo, nft721SalesTemplate.params(collector2.getId()), collector2, - collector2, ) assert.isDefined(result) diff --git a/integration/nevermined/NFTTemplates.test.ts b/integration/nevermined/NFTTemplates.test.ts index 22bbdffd7..839ce38e3 100644 --- a/integration/nevermined/NFTTemplates.test.ts +++ b/integration/nevermined/NFTTemplates.test.ts @@ -750,7 +750,6 @@ describe('NFTTemplates E2E', () => { ddo, nftAccessTemplate.params(collector1.getId(), numberNFTs), collector1, - collector1, ) assert.isDefined(result) @@ -803,7 +802,6 @@ describe('NFTTemplates E2E', () => { ddo, nftSalesTemplate.params(collector2.getId(), numberNFTs2), collector2, - collector2, ) assert.isDefined(result) @@ -972,7 +970,6 @@ describe('NFTTemplates E2E', () => { ddo, nftSalesTemplate.params(collector1.getId(), numberNFTs), collector1, - collector1, ) assert.isDefined(result) @@ -1049,7 +1046,6 @@ describe('NFTTemplates E2E', () => { 'nft-sales', numberNFTs, artist, - gallery, ) assert.isTrue(receipt) diff --git a/integration/nevermined/RegisterAccessTemplate.test.ts b/integration/nevermined/RegisterAccessTemplate.test.ts index b41b0b1be..1cceade81 100644 --- a/integration/nevermined/RegisterAccessTemplate.test.ts +++ b/integration/nevermined/RegisterAccessTemplate.test.ts @@ -267,7 +267,6 @@ describe('Register Escrow Access Template', () => { ddo, accessTemplate.params(consumer), consumer, - consumer, ) assert.match(agreementId, /^0x[a-f0-9]{64}$/i) diff --git a/integration/nevermined/RegisterEscrowComputeExecutionTemplate.test.ts b/integration/nevermined/RegisterEscrowComputeExecutionTemplate.test.ts index d89c70909..70dbd7d67 100644 --- a/integration/nevermined/RegisterEscrowComputeExecutionTemplate.test.ts +++ b/integration/nevermined/RegisterEscrowComputeExecutionTemplate.test.ts @@ -291,7 +291,6 @@ describe('Register Escrow Compute Execution Template', () => { ddo, escrowComputeExecutionTemplate.params(consumer), consumer, - publisher, ) assert.match(agreementId, /^0x[a-f0-9]{64}$/i) diff --git a/integration/nevermined/SecondaryMarket.test.ts b/integration/nevermined/SecondaryMarket.test.ts index d991492d0..3fa901312 100644 --- a/integration/nevermined/SecondaryMarket.test.ts +++ b/integration/nevermined/SecondaryMarket.test.ts @@ -212,7 +212,6 @@ describe('Secondary Markets', () => { ddo, nftSalesTemplate.params(collector1.getId(), numberNFTs), collector1, - collector1, ) assert.isDefined(result) @@ -299,7 +298,6 @@ describe('Secondary Markets', () => { ddo, nftAccessTemplate.params(collector1.getId(), numberNFTs), collector1, - collector1, ) assert.isDefined(result) @@ -392,7 +390,6 @@ describe('Secondary Markets', () => { ddo, nftSalesTemplate.params(collector2.getId(), numberNFTs2), collector2, - collector2, ) assert.isDefined(result) @@ -518,7 +515,6 @@ describe('Secondary Markets', () => { ddo, nftAccessTemplate.params(collector2.getId(), numberNFTs), collector2, - collector2, ) assert.isDefined(result) diff --git a/src/nevermined/utils/BlockchainViemUtils.ts b/src/nevermined/utils/BlockchainViemUtils.ts index 94d8fa274..690e6b67f 100644 --- a/src/nevermined/utils/BlockchainViemUtils.ts +++ b/src/nevermined/utils/BlockchainViemUtils.ts @@ -52,12 +52,23 @@ import { NvmAccount } from '../../models/NvmAccount' import { didZeroX } from '../../utils/ConversionTypeHelpers' import { getChain } from '../../utils/Network' +/** + * Utility class with methods that allow the interaction with the blockchain. + * This class uses Viem library to interact with the blockchain. + */ export class BlockchainViemUtils extends Instantiable { constructor(config: InstantiableConfig) { super() this.setInstanceConfig(config) } + /** + * Given an artifact, it deploys the contract and returns the contract instance. + * @param artifact - the contract artifact + * @param from - the deployer account + * @param args - parameters to be passed to the contract during the initialization + * @returns a contract instance + */ public async deployAbi( artifact: { name?: string; abi: Abi; bytecode: `0x${string}` }, from: NvmAccount, @@ -66,6 +77,12 @@ export class BlockchainViemUtils extends Instantiable { return await deployContractInstance(artifact, from, args, this.client) } + /** + * Given an already deployed contract address and the ABI, it returns the contract instance. + * @param contractAddress - the contract address + * @param abi - the contract artifact + * @returns a contract instance + */ public async loadContract(contractAddress: string, abi: Abi) { await this.checkExists(contractAddress) const contract = getContract({ @@ -76,6 +93,13 @@ export class BlockchainViemUtils extends Instantiable { return contract } + /** + * Given a transaction hash, it returns the transaction receipt. + * If this function is called before the transaction is mined, it will iterate a few times in order to wait for the transaction to be mined. + * @param txHash - the transaction hash + * @param iteration - the iteration number + * @returns the transaction receipt + */ public async getTransactionReceipt(txHash: `0x${string}`, iteration = 1) { if (iteration < 10) { try { @@ -115,6 +139,14 @@ export class BlockchainViemUtils extends Instantiable { ///// CONTRACTS +/** + * Given an artifact, it deploys the contract and returns the contract instance. + * @param artifact - the contract artifact + * @param from - the deployer account + * @param args - parameters to be passed to the contract during the initialization + * @param client - the client to interact with the blockchain + * @returns a contract instance + */ export async function deployContractInstance( artifact: { name?: string; abi: Abi; bytecode: `0x${string}` }, from: NvmAccount, @@ -130,14 +162,6 @@ export async function deployContractInstance( const tx = await client.public.waitForTransactionReceipt({ hash: txHash }) const contractAddress = tx.contractAddress - // const nonce = await client.public.getTransactionCount({ address: from.getAddress() }) - // console.log(`Getting contract address from ${from.getAddress()} and nonce: ${nonce}`) - // console.log(` |----> but from transaction: ${tx.contractAddress}`) - - // const contractAddress = getContractAddress({ - // from: from.getAddress(), - // nonce: BigInt(nonce), - // }) as `0x${string}` const contract = getContract({ abi: artifact.abi, @@ -153,17 +177,8 @@ export async function deployContractInstance( if (isZos) { // @ts-expect-error "viem, wtf?" const initHash = await contract.write.initialize({ args, account: from.getAccountSigner() }) - // const { request } = await client.public.simulateContract({ - // address: contractAddress, - // abi: artifact.abi, - // functionName: 'initialize', - // account: from.getAccountSigner() as Account, - // args, - // }) - // const initHash = await client.wallet.writeContract(request) const initTx = await client.public.waitForTransactionReceipt({ hash: initHash }) - // console.log(`Initializeing contract with status: ${initTx.status}`) if (initTx.status !== 'success') throw new KeeperError(`Unable to initialize contract`) } } catch (error) { @@ -173,21 +188,41 @@ export async function deployContractInstance( return contract } -export async function getContractInstance(address: string, abi: Abi, client: Web3Clients) { +/** + * Given an already deployed contract address and the ABI, it returns the contract instance. + * + * @param contractAddress - the contract address + * @param abi - the contract artifact + * @param client - the client to interact with the blockchain + * @returns a contract instance + */ +export async function getContractInstance(contractAddress: string, abi: Abi, client: Web3Clients) { return getContract({ abi, - address: address as `0x${string}`, + address: contractAddress as `0x${string}`, client: { wallet: client.wallet, public: client.public }, }) } -export async function checkContractExists(address: string, client: PublicClient): Promise { - const storage = await client.getStorageAt({ address: address as `0x${string}`, slot: toHex(0) }) +/** + * Given a contract address it checks if the contract exists on the blockchain. + * @param contractAddress - the contract address + * @param client - the client to interact with the blockchain + * @returns true if the contract exists and false otherwise + */ +export async function checkContractExists( + contractAddress: string, + client: PublicClient, +): Promise { + const storage = await client.getStorageAt({ + address: contractAddress as `0x${string}`, + slot: toHex(0), + }) // check if storage is 0x0 at position 0, this is the case most of the cases if (storage === '0x0000000000000000000000000000000000000000000000000000000000000000') { // if the storage is empty, check if there is no code for this contract, // if so we can be sure it does not exist - const code = await client.getBytecode({ address: address as `0x${string}` }) + const code = await client.getBytecode({ address: contractAddress as `0x${string}` }) if (code === '0x0' || code === '0x') { // no contract in the blockchain dude //throw new Error(`No contract deployed at address ${address}, sorry.`) @@ -200,6 +235,13 @@ export async function checkContractExists(address: string, client: PublicClient) ///// ABIs +/** + * It searchs an ABI function in the ABI. + * @param abi the ABI of the contract + * @param funcName the function name + * @param args the args of the function + * @returns the function found + */ export function searchAbiFunction(abi: Abi, funcName: string, args: any[] = []): AbiFunction { const func = getAbiItem({ abi, name: funcName, args }) if (!func || func.type !== 'function') { @@ -212,6 +254,12 @@ export function searchAbiFunction(abi: Abi, funcName: string, args: any[] = []): return func as AbiFunction } +/** + * It searchs an ABI event in the ABI. + * @param abi the ABI of the contract + * @param funcName the event name + * @returns the event found + */ export function searchAbiEvent(abi: Abi, eventName: string): AbiEvent { const event = getAbiItem({ abi, @@ -223,14 +271,35 @@ export function searchAbiEvent(abi: Abi, eventName: string): AbiEvent { return event as AbiEvent } +/** + * It searchs an ABI function in the ABI. + * @param abi the ABI of the contract + * @param funcName the function name + * @param args the args of the function + * @returns the function found + */ export function getSignatureOfFunction(abi: Abi, funcName: string, args: any[] = []): AbiFunction { return searchAbiFunction(abi, funcName, args) } +/** + * It searchs an ABI function in the ABI and return the inputs. + * @param abi the ABI of the contract + * @param funcName the function name + * @param args the args of the function + * @returns the function found + */ export function getInputsOfFunction(abi: Abi, funcName: string, args: any[] = []) { return searchAbiFunction(abi, funcName, args).inputs } +/** + * It searchs an ABI function in the ABI and return the inputs formatted. + * @param abi the ABI of the contract + * @param funcName the function name + * @param args the args of the function + * @returns the function found + */ export function getInputsOfFunctionFormatted(abi: Abi, funcName: string, args: any[] = []) { return searchAbiFunction(abi, funcName, args).inputs.map((input, i) => { return { @@ -242,18 +311,40 @@ export function getInputsOfFunctionFormatted(abi: Abi, funcName: string, args: a //////// UTILS +/** + * It converts a DID to a Token ID. + * This is useful because in the Solidity Smart contracts the tokenId is a uint256. + * @param did the unique identifier of the asset + * @returns the token id in a bigint format + */ export function didToTokenId(did: string): bigint { return hexToBigInt(didZeroX(did), { size: 32 }) } +/** + * Given an address it returns that address in checksum format. + * @param address the address + * @returns the same address in checksum format + */ export function getChecksumAddress(address: string): string { return getAddress(address) } +/** + * It checks if the address is a valid address. + * @param address the address to check + * @returns true of the address is valid + */ export function isValidAddress(address: string): boolean { return isAddress(address) } +/** + * Encodes a UTF-8 string into a byte array. + + * @param message the string to encode + * @returns the encoded byte array + */ export function getBytes(message: string): Uint8Array { return stringToBytes(message) } From 8aa9e44a8709b3817ededdb18492a2573f82e920 Mon Sep 17 00:00:00 2001 From: Aitor <1726644+aaitor@users.noreply.github.com> Date: Tue, 11 Jun 2024 14:57:25 +0200 Subject: [PATCH 4/4] feat: more documentation --- src/nevermined/NvmApp.ts | 11 ++-- src/nevermined/utils/BlockchainViemUtils.ts | 73 ++++++++++++++++++++- 2 files changed, 78 insertions(+), 6 deletions(-) diff --git a/src/nevermined/NvmApp.ts b/src/nevermined/NvmApp.ts index d88a479d4..d5dec0405 100644 --- a/src/nevermined/NvmApp.ts +++ b/src/nevermined/NvmApp.ts @@ -70,7 +70,6 @@ export class NvmApp { private userAccount: NvmAccount | undefined private searchSDK: Nevermined private fullSDK: Nevermined | undefined - // private useZeroDevSigner: boolean = false private zeroDevSignerAccount: SmartAccountSigner<'custom', `0x${string}`> | undefined public assetProviders: string[] = [] private loginCredentials: string | undefined @@ -349,7 +348,7 @@ export class NvmApp { * @param susbcriptionMetadata - The metadata for the subscription. * @param subscriptionPrice - The price of the subscription. * @param duration - The duration of the subscription in seconds. - * @returns A Promise that resolves to the DDO (Decentralized Data Object) of the created subscription. + * @returns A Promise that resolves to the {@link DDO} (Decentralized Data Object) of the created subscription. */ public async createTimeSubscriptionAsync( susbcriptionMetadata: MetaData, @@ -853,7 +852,7 @@ export class NvmApp { } // TODO: Implement subscription validations - public validateSubscription( + protected validateSubscription( metadata: MetaData, price: AssetPrice, subscriptionType: SubscriptionType, @@ -879,12 +878,14 @@ export class NvmApp { } // TODO: Implement subscription validations - public validateServiceAssetMetadata(_susbcriptionMetadata: MetaData): MetadataValidationResults { + protected validateServiceAssetMetadata( + _susbcriptionMetadata: MetaData, + ): MetadataValidationResults { return { isValid: true, messages: [] } } // TODO: Implement subscription validations - public validateFileAssetMetadata(_susbcriptionMetadata: MetaData): MetadataValidationResults { + protected validateFileAssetMetadata(_susbcriptionMetadata: MetaData): MetadataValidationResults { return { isValid: true, messages: [] } } diff --git a/src/nevermined/utils/BlockchainViemUtils.ts b/src/nevermined/utils/BlockchainViemUtils.ts index 690e6b67f..c926fe2fc 100644 --- a/src/nevermined/utils/BlockchainViemUtils.ts +++ b/src/nevermined/utils/BlockchainViemUtils.ts @@ -349,19 +349,42 @@ export function getBytes(message: string): Uint8Array { return stringToBytes(message) } +/** + * It pads a value with zeros. + * @param value the value to pad + * @param length the expected longitutde of the value + * @returns the padded value + */ export function zeroPadValue(value: `0x${string}` | Uint8Array, length: number): string { return pad(value, { size: length }) as `0x${string}` } +/** + * Encodes a UTF-8 string into a hex string + * @param message the string to encode + * @returns the hex string + */ export function encodeBytes32String(message: string) { return stringToHex(message, { size: 32 }) } -////// ACCOUNTS +////// ACCOUNTS +/** + * Given a seedphrase, it returns an account. + * @param seedphrase - the seedphrase to be used to generate the account + * @param addressIndex - the address index + * @returns an account + */ export function makeWallet(seedphrase: string, addressIndex: number = 0) { return mnemonicToAccount(seedphrase, { addressIndex }) } +/** + * Given a seedphrase generates multiple accounts + * @param seedphrase - the seedphrase to be used to generate the account + * @param numAccounts - the number of accounts to create + * @returns the array of accounts + */ export function makeWallets(seedphrase: string, numAccounts = 10) { const accounts: any[] = [] for (let i = 0; i < numAccounts; i++) { @@ -370,11 +393,20 @@ export function makeWallets(seedphrase: string, numAccounts = 10) { return accounts } +/** + * It generates a random account. + * @returns a new account + */ export function makeRandomWallet() { const mnemonic = generateMnemonic(english) return makeWallet(mnemonic) } +/** + * It generates a list of random accounts + * @param numAccounts - the number of accounts to create + * @returns the array of accounts + */ export function makeRandomWallets(numAccounts = 10) { const mnemonic = generateMnemonic(english) return makeWallets(mnemonic, numAccounts) @@ -382,18 +414,36 @@ export function makeRandomWallets(numAccounts = 10) { /////// HASHES +/** + * It hashes a string using keccak256. + * @param seed the string to hash + * @returns the hash + */ export function keccak256(seed: string): string { return viemKeccak256(toBytes(seed)) } +/** + * It encodes and hashes a list of primitive values into an ABI-encoded hex value. + * @param types the types of the values + * @param values the values to encode + * @returns the hash + */ export function keccak256WithEncode(types: any[], values: any[]): string { const encoded = encodeAbiParameters(types, values as never) return keccak256(encoded) } +/** + * It encodes and hashes a list of primitive values into an ABI-encoded hex value. + * @param types the types of the values + * @param values the values to encode + * @returns the hash + */ export function keccak256Packed(types: any[], values: any[]): string { return keccak256WithEncode(types, values) } + //// UNITS /** @@ -473,6 +523,13 @@ export const formatEther = (value: bigint): string => { /////// ZERO DEV +/** + * It creates a ZeroDev Kernel client. + * @param signer the signer account + * @param chainId the chain id + * @param zeroDevProjectId the zero dev project id, you can get it from the ZeroDev dashboard + * @returns the kernel client + */ export async function createKernelClient(signer: any, chainId: number, zeroDevProjectId: string) { const publicClient = createPublicClient({ chain: getChain(chainId), @@ -514,6 +571,13 @@ export async function createKernelClient(signer: any, chainId: number, zeroDevPr }) } +/** + * It creates a ZeroDev Session Key with some specific permissions + * @param signer the signer account + * @param publicClient the blockchain client + * @param permissions the permissions to configure in the session key + * @returns the session key serialized + */ export async function createSessionKey(signer: any, publicClient: any, permissions: any[]) { const ecdsaValidator = await signerToEcdsaValidator(publicClient, { entryPoint: ENTRYPOINT_ADDRESS_V06, @@ -542,6 +606,13 @@ export async function createSessionKey(signer: any, publicClient: any, permissio return serializeSessionKeyAccount(sessionKeyAccount, sessionPrivateKey) } +/** + * Given a serialized session key it reconstructs the NvmAccount represented by the session key. + * @param serializedSessionKey - the serialized session key + * @param zeroDevProjectId - the zero dev project id + * @param publicClient - the blockchain client + * @returns the NvmAccount represented by the session key + */ export async function getSessionKey( serializedSessionKey: string, zeroDevProjectId: string,