Skip to content

Commit

Permalink
Fix in the retrieval of Provenance events (#292)
Browse files Browse the repository at this point in the history
* The provenance events were not retrieved properly, this PR fixes that

* linting

* adding method

* Adjusting copyright to Nevermined AG

* Managing objects depending on regular events or subgraph integration
  • Loading branch information
aaitor authored Jun 23, 2022
1 parent 4b1f405 commit 5720fb6
Show file tree
Hide file tree
Showing 19 changed files with 157 additions and 68 deletions.
2 changes: 1 addition & 1 deletion LICENSE
Original file line number Diff line number Diff line change
Expand Up @@ -187,7 +187,7 @@
same "printed page" as the copyright notice for easier
identification within third-party archives.

Copyright 2020 Keyko GmbH
Copyright 2022 Nevermined AG
This product includes software developed at
BigchainDB GmbH and Ocean Protocol (https://www.oceanprotocol.com/)

Expand Down
2 changes: 1 addition & 1 deletion NOTICE
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
Nevermined
Copyright 2020 Keyko GmbH.
Copyright 2022 Nevermined AG.

This product includes software developed at
BigchainDB GmbH and Ocean Protocol (https://www.oceanprotocol.com/).
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -207,7 +207,7 @@ It keeps the same Apache v2 License and adds some improvements. See [NOTICE file
## License

```
Copyright 2020 Keyko GmbH
Copyright 2022 Nevermined AG
This product includes software developed at
BigchainDB GmbH and Ocean Protocol (https://www.oceanprotocol.com/)
Expand Down
7 changes: 7 additions & 0 deletions integration/nevermined/Provenance.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { decodeJwt } from 'jose'
import { config } from '../config'
import { getMetadata } from '../utils'
import { Nevermined, Account, DDO, ProvenanceMethod, utils } from '../../src'
import { sleep } from '../utils/utils'

describe('Provenance', () => {
let nevermined: Nevermined
Expand Down Expand Up @@ -41,6 +42,7 @@ describe('Provenance', () => {
metadata.userId = payload.sub

ddo = await nevermined.assets.create(metadata, publisher)
await sleep(2000)
const provenance = await nevermined.provenance.getProvenanceEntry(ddo.shortId())

assert.equal(utils.zeroX(provenance.did), utils.zeroX(ddo.shortId()))
Expand Down Expand Up @@ -125,6 +127,10 @@ describe('Provenance', () => {

it('should return the events associated to DID', async () => {
const pm = ProvenanceMethod

// wait for the graph to pickup the event
await sleep(3000)

const events = await nevermined.provenance.getDIDProvenanceEvents(ddo.shortId())

assert.deepEqual(
Expand All @@ -140,6 +146,7 @@ describe('Provenance', () => {
})

it('should return the events of an specific method by DID', async () => {
await sleep(2000)
const events = await Promise.all(
[
'WAS_GENERATED_BY',
Expand Down
4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@nevermined-io/nevermined-sdk-js",
"version": "0.20.1",
"version": "0.20.2",
"description": "Javascript SDK for connecting with Nevermined Data Platform ",
"main": "./dist/node/sdk.js",
"typings": "./dist/node/sdk.d.ts",
Expand Down Expand Up @@ -174,4 +174,4 @@
"browser": {
"fs": false
}
}
}
2 changes: 1 addition & 1 deletion src/Instantiable.abstract.ts
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ export abstract class Instantiable {
* @return {Promise<number>} Network ID.
*/
public async getNetworkId(): Promise<number> {
if(!this.networkId) {
if (!this.networkId) {
this.networkId = await this.web3.eth.net.getId()
}

Expand Down
29 changes: 15 additions & 14 deletions src/events/ContractEvent.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import {
} from './NeverminedEvent'
import ContractBase from '../keeper/contracts/ContractBase'
import { KeeperError } from '../errors'
import { Nevermined } from "../nevermined/Nevermined";
import { Nevermined } from '../nevermined/Nevermined'

export class ContractEvent extends NeverminedEvent {
public static getInstance(
Expand Down Expand Up @@ -39,20 +39,21 @@ export class ContractEvent extends NeverminedEvent {
}

public async getPastEvents(options: EventOptions): EventResult {
const chainId = await this.getNetworkId()

options.fromBlock = 0
options.toBlock = 'latest'

// Temporary workaround to work with mumbai
// Infura as a 1000 blokcs limit on their api
if (chainId === 80001 || chainId === 42) {
const latestBlock = await this.web3.eth.getBlockNumber()
options.fromBlock = latestBlock - 99
try {
const chainId = await this.getNetworkId()
options.fromBlock = 0
options.toBlock = 'latest'

// Temporary workaround to work with mumbai
// Infura as a 1000 blokcs limit on their api
if (chainId === 80001 || chainId === 42) {
const latestBlock = await this.web3.eth.getBlockNumber()
options.fromBlock = latestBlock - 99
}
return await this.getEventData(options)
} catch (error) {
return []
}

const data = await this.getEventData(options)
return data
}

public async getBlockNumber(): Promise<number> {
Expand Down
2 changes: 1 addition & 1 deletion src/events/NeverminedEvent.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import ContractBase from '../keeper/contracts/ContractBase'
import { Instantiable } from "../Instantiable.abstract";
import { Instantiable } from '../Instantiable.abstract'

export interface EventOptions {
methodName?: string
Expand Down
7 changes: 6 additions & 1 deletion src/keeper/contracts/ContractBase.ts
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,12 @@ export abstract class ContractBase extends Instantiable {
this.config.graphHttpUri
)
} else {
this.events = ContractEvent.getInstance(this, eventEmitter, config.nevermined, this.web3)
this.events = ContractEvent.getInstance(
this,
eventEmitter,
config.nevermined,
this.web3
)
}
}

Expand Down
83 changes: 63 additions & 20 deletions src/keeper/contracts/DIDRegistry.ts
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ export interface ProvenanceAttributeRegisteredEvent {
relatedDid: string
agentInvolvedId: string
method: ProvenanceMethod
attributes: string
attributes?: string
blockNumberUpdated: number
}

Expand All @@ -48,7 +48,7 @@ interface ProvenanceBaseEvent {
method: ProvenanceMethod
activityId: string
provId: string
attributes: string
attributes?: string
blockNumberUpdated: number
}
export interface WasGeneratedByEvent extends ProvenanceBaseEvent {
Expand Down Expand Up @@ -367,41 +367,84 @@ export default class DIDRegistry extends ContractBase {
}
})
)
.map(
({ returnValues }) =>
eventToObject(returnValues) as ProvenanceAttributeRegisteredEvent
)
.map(event => {
if (event.returnValues === undefined)
return eventToObject(event) as ProvenanceAttributeRegisteredEvent
else
return eventToObject(
event.returnValues
) as ProvenanceAttributeRegisteredEvent
})
.map(event => ({ ...event, method: +event.method }))
.sort(
(
firstEvent: ProvenanceAttributeRegisteredEvent,
secondEvent: ProvenanceAttributeRegisteredEvent
) =>
Number(firstEvent.blockNumberUpdated) >
Number(secondEvent.blockNumberUpdated)
? 1
: -1
)
}

public async getDIDProvenanceMethodEvents<T extends ProvenanceMethod>(
did: string,
method: T
): Promise<ProvenanceEvent<T>[]> {
const capitalize = string =>
string.replace(
/([a-z]+)(?:_|$)/gi,
(_, w) => w.charAt(0).toUpperCase() + w.toLowerCase().slice(1)
)
let filter: any = { _did: didZeroX(did) }
let methodName = ''
let eventName = ''
switch (method) {
case ProvenanceMethod.ACTED_ON_BEHALF:
filter = { _entityDid: didZeroX(did) }
eventName = 'ActedOnBehalf'
methodName = 'getActedOnBehalfs'
break
case ProvenanceMethod.WAS_ASSOCIATED_WITH:
eventName = 'WasAssociatedWith'
methodName = 'getWasAssociatedWiths'
filter = { _entityDid: didZeroX(did) }
break
case ProvenanceMethod.WAS_DERIVED_FROM:
eventName = 'WasDerivedFrom'
methodName = 'getWasDerivedFroms'
filter = { _usedEntityDid: didZeroX(did) }
break
case ProvenanceMethod.USED:
eventName = 'Used'
methodName = 'getUseds'
break
case ProvenanceMethod.WAS_GENERATED_BY:
eventName = 'WasGeneratedBy'
methodName = 'getWasGeneratedBys'
break
}
return (
await this.events.getPastEvents({
eventName: capitalize(ProvenanceMethod[method as any]),
methodName: `get${capitalize(ProvenanceMethod[method as any])}s`,
filterJsonRpc: filter,
filterSubgraph: { where: filter },
result: {}
})
).map(({ returnValues }) => eventToObject(returnValues))
const eventOptions = {
eventName,
methodName,
filterJsonRpc: filter,
filterSubgraph: { where: filter },
result: {
provId: true,
_activityId: true,
_blockNumberUpdated: true
}
}
const events = await this.events.getPastEvents(eventOptions)
return events
.map(event => eventToObject(event))
.map(event => ({ ...event, method: +method }))
.sort(
(
firstEvent: ProvenanceAttributeRegisteredEvent,
secondEvent: ProvenanceAttributeRegisteredEvent
) =>
Number(firstEvent.blockNumberUpdated) >
Number(secondEvent.blockNumberUpdated)
? 1
: -1
)
}

public async getProvenanceEntry(provId: string) {
Expand Down
4 changes: 1 addition & 3 deletions src/keeper/contracts/royalties/CurveRoyalties.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,7 @@ import { RoyaltyScheme } from './RoyaltyScheme.abstract'
import { InstantiableConfig } from '../../../Instantiable.abstract'

export class CurveRoyalties extends RoyaltyScheme {
public static async getInstance(
config: InstantiableConfig
): Promise<CurveRoyalties> {
public static async getInstance(config: InstantiableConfig): Promise<CurveRoyalties> {
return RoyaltyScheme.getInstance(config, 'CurveRoyalties', CurveRoyalties, true)
}
}
24 changes: 15 additions & 9 deletions src/keeper/contracts/royalties/RewardsDistributor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,16 +5,25 @@ import { didZeroX, zeroX } from '../../../utils'
import BigNumber from 'bignumber.js'

export class RewardsDistributor extends ContractBase {
public static async getInstance(config: InstantiableConfig): Promise<RewardsDistributor> {
public static async getInstance(
config: InstantiableConfig
): Promise<RewardsDistributor> {
try {
const instance: RewardsDistributor = new RewardsDistributor('RewardsDistributor')
const instance: RewardsDistributor = new RewardsDistributor(
'RewardsDistributor'
)
await instance.init(config, true)
return instance
} catch (e) {
config.logger.warn('Cannot load optional contract RewardsDistributor')
}
}
public setReceivers(did: string, addr: string[], from?: Account, params?: TxParameters) {
public setReceivers(
did: string,
addr: string[],
from?: Account,
params?: TxParameters
) {
return this.sendFrom('setReceivers', [didZeroX(did), addr], from, params)
}
public claimReward(
Expand All @@ -38,12 +47,9 @@ export class RewardsDistributor extends ContractBase {
didZeroX(did),
amountsString,
receivers,
...[
returnAddress,
lockPaymentAddress,
tokenAddress,
lockCondition,
].map(zeroX),
...[returnAddress, lockPaymentAddress, tokenAddress, lockCondition].map(
zeroX
),
releaseConditions.map(zeroX)
],
from,
Expand Down
8 changes: 6 additions & 2 deletions src/keeper/contracts/royalties/RoyaltyScheme.abstract.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,12 +19,16 @@ export abstract class RoyaltyScheme extends ContractBase {
}
}

public setRoyalty(did: string, amount: number, from?: Account, params?: TxParameters) {
public setRoyalty(
did: string,
amount: number,
from?: Account,
params?: TxParameters
) {
return this.sendFrom('setRoyalty', [didZeroX(did), amount], from, params)
}

public async getRoyalty(did: string) {
return Number(await this.call('royalties', [didZeroX(did)]))
}

}
7 changes: 6 additions & 1 deletion src/keeper/contracts/royalties/StandardRoyalties.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,11 @@ export class StandardRoyalties extends RoyaltyScheme {
public static async getInstance(
config: InstantiableConfig
): Promise<StandardRoyalties> {
return RoyaltyScheme.getInstance(config, 'StandardRoyalties', StandardRoyalties, true)
return RoyaltyScheme.getInstance(
config,
'StandardRoyalties',
StandardRoyalties,
true
)
}
}
3 changes: 1 addition & 2 deletions src/keeper/contracts/templates/AccessTemplate.ts
Original file line number Diff line number Diff line change
Expand Up @@ -214,7 +214,7 @@ export class AccessTemplate extends BaseTemplate implements GenericAccess {
* @param assetRewards rewards
* @param consumer consumer
* @param creator creator of the agreement
* @returns
* @returns
*/
public async escrowPaymentParams(
agreementIdSeed: string,
Expand Down Expand Up @@ -270,7 +270,6 @@ export class AccessTemplate extends BaseTemplate implements GenericAccess {
lockPaymentConditionId[1],
accessConditionId[1]
]

}

private async createFullAgreementData(
Expand Down
8 changes: 6 additions & 2 deletions src/nevermined/Assets.ts
Original file line number Diff line number Diff line change
Expand Up @@ -832,12 +832,16 @@ export class Assets extends Instantiable {
this.logger.log('Mintable DID registred')
const scheme = getRoyaltyScheme(this.nevermined, royaltyKind)
observer.next(CreateProgressStep.SettingRoyaltyScheme)
await didRegistry.setDIDRoyalties(ddo.shortId(), scheme.address, publisher.getId(), txParams)
await didRegistry.setDIDRoyalties(
ddo.shortId(),
scheme.address,
publisher.getId(),
txParams
)
observer.next(CreateProgressStep.SettingRoyalties)
await scheme.setRoyalty(ddo.shortId(), royalties, publisher, txParams)
observer.next(CreateProgressStep.DidRegistered)


return storedDdo
} catch (error) {
throw new ApiError(error)
Expand Down
Loading

0 comments on commit 5720fb6

Please sign in to comment.