Skip to content

Commit

Permalink
Merge pull request #627 from nevermined-io/feat/app_lib
Browse files Browse the repository at this point in the history
NVMApp Api
  • Loading branch information
aaitor authored Feb 15, 2024
2 parents a803fdb + 1f296b7 commit a7de596
Show file tree
Hide file tree
Showing 10 changed files with 1,359 additions and 20 deletions.
8 changes: 4 additions & 4 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -1466,7 +1466,7 @@ Generated by [`auto-changelog`](https://github.com/CookPete/auto-changelog).

> 2 May 2022
- add aave service agreement to ddo when creating nft721 asset [`#248`](https://github.com/nevermined-io/sdk-js/pull/248)
- add aave service agreement to ddo when creating nft721 asset [`#248`](https://github.com/nevermined-io/sdk-js/pull/248)
- Adding v0.19.21 Changelog updates [`c93cdc5`](https://github.com/nevermined-io/sdk-js/commit/c93cdc55f139a43db4130ccb0f80924d2645a931)

#### [v0.19.21](https://github.com/nevermined-io/sdk-js/compare/v0.19.20...v0.19.21)
Expand Down Expand Up @@ -1729,7 +1729,7 @@ Generated by [`auto-changelog`](https://github.com/CookPete/auto-changelog).

> 18 January 2022
- Removing not used parameter [`#186`](https://github.com/nevermined-io/sdk-js/pull/186)
- Removing not used parameter [`#186`](https://github.com/nevermined-io/sdk-js/pull/186)
- [wip] Create agreement+pay in one transaction [`#183`](https://github.com/nevermined-io/sdk-js/pull/183)
- Adapting to contracts `v1.3.3` [`#177`](https://github.com/nevermined-io/sdk-js/pull/177)
- Adding v0.17.2 Changelog updates [`5eddda4`](https://github.com/nevermined-io/sdk-js/commit/5eddda43954e013e6e6f7344c9a877d801aacb5c)
Expand Down Expand Up @@ -2235,7 +2235,7 @@ Generated by [`auto-changelog`](https://github.com/CookPete/auto-changelog).
- Feature/sync develop [`#268`](https://github.com/nevermined-io/sdk-js/pull/268)
- Quick fix for non-eip1559 networks [`#266`](https://github.com/nevermined-io/sdk-js/pull/266)
- integrate Permissions and refactor search query [`#264`](https://github.com/nevermined-io/sdk-js/pull/264)
- add aave service agreement to ddo when creating nft721 asset [`#248`](https://github.com/nevermined-io/sdk-js/pull/248)
- add aave service agreement to ddo when creating nft721 asset [`#248`](https://github.com/nevermined-io/sdk-js/pull/248)
- Get the keeper version from the artifacts instead of package version [`#244`](https://github.com/nevermined-io/sdk-js/pull/244)
- replace `metadata-api` url by `marketplace-api` and sort type [`#243`](https://github.com/nevermined-io/sdk-js/pull/243)
- fixing issues with BigNumbers [`#246`](https://github.com/nevermined-io/sdk-js/pull/246)
Expand Down Expand Up @@ -2274,7 +2274,7 @@ Generated by [`auto-changelog`](https://github.com/CookPete/auto-changelog).
- Feature/190 add did to sec markets [`#191`](https://github.com/nevermined-io/sdk-js/pull/191)
- Adding utility methods for getting nft token uri [`#189`](https://github.com/nevermined-io/sdk-js/pull/189)
- Lint ... [`#187`](https://github.com/nevermined-io/sdk-js/pull/187)
- Removing not used parameter [`#186`](https://github.com/nevermined-io/sdk-js/pull/186)
- Removing not used parameter [`#186`](https://github.com/nevermined-io/sdk-js/pull/186)
- [wip] Create agreement+pay in one transaction [`#183`](https://github.com/nevermined-io/sdk-js/pull/183)
- Adapting to contracts `v1.3.3` [`#177`](https://github.com/nevermined-io/sdk-js/pull/177)
- Correct typo in route [`#184`](https://github.com/nevermined-io/sdk-js/pull/184)
Expand Down
284 changes: 284 additions & 0 deletions integration/external/NVMAppAPI.staging.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,284 @@
import chai, { assert } from 'chai'
import chaiAsPromised from 'chai-as-promised'

import {
AssetPrice,
ResourceAuthentication,
SubscriptionType,
convertEthersV6SignerToAccountSigner,
makeAccounts,
} from '../../src'
import TestContractHandler from '../../test/keeper/TestContractHandler'
import { NVMAppEnvironments, NvmApp } from '../../src/nevermined/NvmApp'
import { NvmAppMetadata } from '../../src/ddo/NvmAppMetadata'
import { ethers, isAddress } from 'ethers'
import { ZeroDevAccountSigner, ZeroDevEthersProvider } from '@zerodev/sdk'
import { AppDeploymentStaging } from '../../src/nevermined/resources/AppNetworks'

chai.use(chaiAsPromised)

// Execute first:
// ./scripts/download-artifacts.sh v3.5.6 arbitrum-sepolia public
// export PROJECT_ID=your_project_id
describe('NVM App API', () => {
let nvmAppPublisher: NvmApp
let nvmAppSubscriber: NvmApp

let subscriptionNFTAddress: string
let subscriptionDid: string
let agentDid: string
let datasetDid: string
let agreementId

const projectId = process.env.PROJECT_ID!
let zerodevProvider: ZeroDevEthersProvider<'ECDSA'>
let accountSigner: ZeroDevAccountSigner<'ECDSA'>
let publisherAddress: string
let subscriptionPrice: AssetPrice
let subscriptionPriceWithFees: AssetPrice

// Agent/Service test configuration
const SERVICE_ENDPOINT = process.env.SERVICE_ENDPOINT || 'http://127.0.0.1:3000'
const OPEN_PATH = process.env.OPEN_PATH || '/openapi.json'
const OPEN_ENDPOINT = process.env.OPEN_ENDPOINT || `${SERVICE_ENDPOINT}${OPEN_PATH}`
const AUTHORIZATION_TYPE = (process.env.AUTHORIZATION_TYPE ||
'oauth') as ResourceAuthentication['type']
const AUTHORIZATION_TOKEN = process.env.AUTHORIZATION_TOKEN || 'new_authorization_token'
const AUTHORIZATION_USER = process.env.AUTHORIZATION_USER || 'user'
const AUTHORIZATION_PASSWORD = process.env.AUTHORIZATION_PASSWORD || 'password'

before(async () => {
const owner = ethers.Wallet.createRandom()
zerodevProvider = await ZeroDevEthersProvider.init('ECDSA', {
projectId,
owner: convertEthersV6SignerToAccountSigner(owner),
})

const contractABI = await TestContractHandler.getABI(
`NFT1155SubscriptionUpgradeable.arbitrum-sepolia`,
'./artifacts/',
)

subscriptionNFTAddress = contractABI.address
console.debug(`Using ERC-1155 Subscription NFT on address: ${subscriptionNFTAddress}`)

accountSigner = zerodevProvider.getAccountSigner()
publisherAddress = await accountSigner.getAddress()

// Using USDC token address
// WARN: Make sure the subscriber account has balance to pay the gas and the subscription
subscriptionPrice = new AssetPrice(publisherAddress, 1000n).setTokenAddress(
new AppDeploymentStaging().tokenAddress,
)
})

describe('As a PUBLISHER', () => {
it('I want to search content from the app', async () => {
nvmAppPublisher = await NvmApp.getInstance(NVMAppEnvironments.Staging)
const results = await nvmAppPublisher.search.query({})
console.log(JSON.stringify(results.totalResults))

assert.isDefined(results)
})

it('Get the default configuration used', async () => {
const appConfig = nvmAppPublisher.config
assert.isDefined(appConfig)
assert.equal(appConfig.marketplaceUri, 'https://marketplace-api.staging.nevermined.app')
})

it('Overwrite the default config with some parameters', async () => {
assert.notEqual(nvmAppPublisher.config.artifactsFolder, './artifacts')
nvmAppPublisher = await NvmApp.getInstance(NVMAppEnvironments.Staging, {
artifactsFolder: './artifacts',
})
assert.equal(nvmAppPublisher.config.artifactsFolder, './artifacts')
})

it('I want to connect my account', async () => {
assert.isFalse(nvmAppPublisher.isWeb3Connected())

await nvmAppPublisher.connect(accountSigner)

assert.isTrue(nvmAppPublisher.isWeb3Connected())
assert.isTrue(nvmAppPublisher.getLoginCredentials().length > 0)
})

it('I can get the network fees', async () => {
const networkFees = nvmAppPublisher.networkFees
assert.isDefined(networkFees)
console.log(`Network Fees: ${JSON.stringify(networkFees)}`)
assert.isTrue(isAddress(networkFees.receiver))
assert.isTrue(networkFees.fee > 0)
})

it('I can calculate and include network fees', async () => {
// console.log(`AssetPrice object: ${subscriptionPrice.toString()}`)

// assert.isFalse(nvmApp.isNetworkFeeIncluded(subscriptionPrice))

subscriptionPriceWithFees = nvmAppPublisher.addNetworkFee(subscriptionPrice)
console.log(`Asset Price with fees: ${subscriptionPriceWithFees.toString()}`)

assert.isTrue(nvmAppPublisher.isNetworkFeeIncluded(subscriptionPriceWithFees))
})

it('I want to create a time subscription', async () => {
const timeSubscriptionMetadata = NvmAppMetadata.getTimeSubscriptionMetadataTemplate(
'NVM App Time only Subscription test',
'Nevermined',
'hours',
)
timeSubscriptionMetadata.additionalInformation.customData = {
subscriptionLimitType: SubscriptionType.Time,
dateMeasure: 'hours',
}

const ddo = await nvmAppPublisher.createTimeSubscription(
timeSubscriptionMetadata,
subscriptionPriceWithFees,
100, // 100 blocks duration
)

assert.isDefined(ddo)
const ddoFound = await nvmAppPublisher.search.byDID(ddo.id)
assert.equal(ddo.id, ddoFound.id)
})

it('I want to create a credits subscription', async () => {
const creditsSubscriptionMetadata = NvmAppMetadata.getCreditsSubscriptionMetadataTemplate(
'NVM App Credits Subscription test',
'Nevermined',
)
creditsSubscriptionMetadata.additionalInformation.customData = {
subscriptionLimitType: SubscriptionType.Credits,
}

const ddo = await nvmAppPublisher.createCreditsSubscription(
creditsSubscriptionMetadata,
subscriptionPriceWithFees,
50n, // number of credits given to the subscribers
)

assert.isDefined(ddo)
const ddoFound = await nvmAppPublisher.search.byDID(ddo.id)
assert.equal(ddo.id, ddoFound.id)
subscriptionDid = ddo.id
})

it('I want to register an Agent', async () => {
const agentMetadata = NvmAppMetadata.getServiceMetadataTemplate(
'Nevermined Ageeeent',
'Nevermined',
[
{
GET: `${SERVICE_ENDPOINT}/(.*)`,
},
],
[OPEN_ENDPOINT],
OPEN_ENDPOINT,
'RESTful',
AUTHORIZATION_TYPE,
AUTHORIZATION_TOKEN,
AUTHORIZATION_USER,
AUTHORIZATION_PASSWORD,
true,
)

const ddo = await nvmAppPublisher.registerServiceAsset(
agentMetadata,
subscriptionDid,
// We are gonna configure the agent usage costs in a dynamic manner:
// The cost in credits for every succesful query to the agent will be between 1 and 5 credits being 2 credits the default cost
2n, // default cost in credits for every succesful query to the agent
1n, // min amount of credits to be consumed
5n, // max amount of credits to be consumed
)

assert.isDefined(ddo)
const ddoFound = await nvmAppPublisher.search.byDID(ddo.id)
assert.equal(ddo.id, ddoFound.id)
agentDid = ddo.id
})

it('I want to register a Dataset', async () => {
const datasetMetadata = NvmAppMetadata.getFileMetadataTemplate(
'NVM App Dataset test',
'Nevermined',
)
datasetMetadata.main.files = [
{
index: 0,
contentType: 'application/json',
name: 'ddo-example.json',
url: 'https://storage.googleapis.com/nvm-static-assets/files/ci/ddo-example.json',
},
{
index: 1,
contentType: 'text/plain',
name: 'README.md',
url: 'https://storage.googleapis.com/nvm-static-assets/files/ci/README.md',
},
]

const ddo = await nvmAppPublisher.registerFileAsset(
datasetMetadata,
subscriptionDid,
1n, // every file download costs 1 credit to the subscriber
)

assert.isDefined(ddo)
const ddoFound = await nvmAppPublisher.search.byDID(ddo.id)
assert.equal(ddo.id, ddoFound.id)
datasetDid = ddo.id
})
})

describe('As a SUBSCRIBER', () => {
it('I want to connect as subscriber', async () => {
nvmAppSubscriber = await NvmApp.getInstance(NVMAppEnvironments.Staging, {
artifactsFolder: './artifacts',
})
const appConfig = nvmAppSubscriber.config
appConfig.accounts = makeAccounts(process.env.SEED_WORDS)

const subscriberAddress = await appConfig.accounts[0].getAddress()
await nvmAppSubscriber.connect(subscriberAddress, appConfig)

assert.isTrue(nvmAppSubscriber.isWeb3Connected())
})

it('I want to order a subscription', async () => {
const orderResult = await nvmAppSubscriber.orderSubscription(subscriptionDid)
assert.isDefined(orderResult)
assert.isTrue(orderResult.success)
assert.isTrue(orderResult.agreementId.length > 0)
agreementId = orderResult.agreementId
})

it('I want to get the token giving access to a remote agent', async () => {
const token = await nvmAppSubscriber.getServiceAccessToken(agentDid)
console.log(`Token: ${JSON.stringify(token)}`)
assert.isDefined(token)
assert.isTrue(token.accessToken.length > 0)
assert.isTrue(token.neverminedProxyUri.length > 0)
})

it('I want to download a file asset', async () => {
const results = await nvmAppSubscriber.downloadFiles(
datasetDid,
agreementId,
`/tmp/.nevermined/downloads/${datasetDid}/`,
)

assert.isDefined(results)
assert.isTrue(results.success)
})

it('I can disconnect and still search', async () => {
await nvmAppSubscriber.disconnect()
const results = await nvmAppSubscriber.search.query({})
assert.isTrue(results.totalResults.value > 0)
})
})
})
Loading

0 comments on commit a7de596

Please sign in to comment.