2019-06-20 00:20:09 +02:00
|
|
|
import { generateId } from '../utils/GeneratorHelpers'
|
|
|
|
import Account from './Account'
|
|
|
|
import DID from './DID'
|
|
|
|
import { zeroX, didPrefixed } from '../utils'
|
|
|
|
import { Instantiable, InstantiableConfig } from '../Instantiable.abstract'
|
|
|
|
import { AgreementConditionsStatus } from '../keeper/contracts/templates/AgreementTemplate.abstract'
|
|
|
|
import { ConditionState } from '../keeper/contracts/conditions/Condition.abstract'
|
2019-02-13 14:32:52 +01:00
|
|
|
|
2019-06-20 00:20:09 +02:00
|
|
|
import { OceanAgreementsConditions } from './OceanAgreementsConditions'
|
2019-03-04 13:05:27 +01:00
|
|
|
|
2019-03-13 13:22:20 +01:00
|
|
|
export interface AgreementPrepareResult {
|
2019-02-14 11:30:03 +01:00
|
|
|
agreementId: string
|
|
|
|
signature: string
|
|
|
|
}
|
2019-01-21 17:48:40 +01:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Agreements submodule of Ocean Protocol.
|
|
|
|
*/
|
2019-03-21 02:56:58 +01:00
|
|
|
export class OceanAgreements extends Instantiable {
|
2019-01-21 17:48:40 +01:00
|
|
|
/**
|
|
|
|
* Returns the instance of OceanAgreements.
|
|
|
|
* @return {Promise<OceanAgreements>}
|
|
|
|
*/
|
2019-06-20 00:20:09 +02:00
|
|
|
public static async getInstance(
|
|
|
|
config: InstantiableConfig
|
|
|
|
): Promise<OceanAgreements> {
|
2019-03-21 02:56:58 +01:00
|
|
|
const instance = new OceanAgreements()
|
|
|
|
instance.setInstanceConfig(config)
|
2019-06-20 00:20:09 +02:00
|
|
|
instance.conditions = await OceanAgreementsConditions.getInstance(
|
|
|
|
config
|
|
|
|
)
|
2019-01-21 17:48:40 +01:00
|
|
|
|
2019-03-21 02:56:58 +01:00
|
|
|
return instance
|
2019-01-21 17:48:40 +01:00
|
|
|
}
|
|
|
|
|
2019-03-04 13:05:27 +01:00
|
|
|
/**
|
|
|
|
* Agreements Conditions submodule.
|
|
|
|
* @type {OceanAgreementsConditions}
|
|
|
|
*/
|
|
|
|
public conditions: OceanAgreementsConditions
|
|
|
|
|
2019-01-21 17:48:40 +01:00
|
|
|
/**
|
2019-02-13 14:32:52 +01:00
|
|
|
* Creates a consumer signature for the specified asset service.
|
|
|
|
* @param {string} did Decentralized ID.
|
2019-08-16 16:12:42 +02:00
|
|
|
* @param {number} index Service index.
|
2019-02-13 14:32:52 +01:00
|
|
|
* @param {Account} consumer Consumer account.
|
2019-03-13 13:22:20 +01:00
|
|
|
* @return {Promise<AgreementPrepareResult>} Agreement ID and signaturee.
|
2019-02-13 14:32:52 +01:00
|
|
|
*/
|
|
|
|
public async prepare(
|
|
|
|
did: string,
|
2019-08-16 16:12:42 +02:00
|
|
|
index: number,
|
2019-06-20 00:20:09 +02:00
|
|
|
consumer: Account
|
2019-03-13 13:22:20 +01:00
|
|
|
): Promise<AgreementPrepareResult> {
|
2019-02-13 14:32:52 +01:00
|
|
|
const d: DID = DID.parse(did as string)
|
2019-03-21 02:56:58 +01:00
|
|
|
const ddo = await this.ocean.aquarius.retrieveDDO(d)
|
2019-04-15 17:45:06 +02:00
|
|
|
const agreementId: string = zeroX(generateId())
|
2019-02-13 14:32:52 +01:00
|
|
|
|
2019-08-16 14:12:31 +02:00
|
|
|
const templateName = ddo.findServiceByType('access')
|
2019-06-20 00:20:09 +02:00
|
|
|
.serviceAgreementTemplate.contractName
|
2019-03-21 02:56:58 +01:00
|
|
|
const agreementConditionsIds = await this.ocean.keeper
|
2019-03-12 13:49:11 +01:00
|
|
|
.getTemplateByName(templateName)
|
2019-06-20 00:20:09 +02:00
|
|
|
.getAgreementIdsFromDDO(
|
|
|
|
agreementId,
|
|
|
|
ddo,
|
|
|
|
consumer.getId(),
|
|
|
|
consumer.getId()
|
|
|
|
)
|
2019-03-11 22:52:53 +01:00
|
|
|
|
2019-03-28 12:20:22 +01:00
|
|
|
const signature = await this.ocean.utils.agreements.signServiceAgreement(
|
2019-03-13 13:22:20 +01:00
|
|
|
ddo,
|
2019-08-16 16:12:42 +02:00
|
|
|
index,
|
2019-03-13 13:22:20 +01:00
|
|
|
agreementId,
|
|
|
|
agreementConditionsIds,
|
2019-06-20 00:20:09 +02:00
|
|
|
consumer
|
2019-03-13 13:22:20 +01:00
|
|
|
)
|
2019-02-13 14:32:52 +01:00
|
|
|
|
2019-06-20 00:20:09 +02:00
|
|
|
return { agreementId, signature }
|
2019-02-13 14:32:52 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Submit a service agreement to the publisher to create the agreement on-chain.
|
|
|
|
* @param {string} did Decentralized ID.
|
2019-08-16 16:12:42 +02:00
|
|
|
* @param {number} index Service index.
|
2019-02-13 14:32:52 +01:00
|
|
|
* @param {Account} consumer Consumer account.
|
|
|
|
* @return {Promise<void>}
|
|
|
|
*/
|
|
|
|
public async send(
|
|
|
|
did: string,
|
|
|
|
agreementId: string,
|
2019-08-16 16:12:42 +02:00
|
|
|
index: number,
|
2019-02-13 14:32:52 +01:00
|
|
|
signature: string,
|
2019-06-20 00:20:09 +02:00
|
|
|
consumer: Account
|
2019-02-13 14:32:52 +01:00
|
|
|
): Promise<void> {
|
2019-06-20 00:20:09 +02:00
|
|
|
const result = await this.ocean.brizo.initializeServiceAgreement(
|
|
|
|
didPrefixed(did),
|
|
|
|
zeroX(agreementId),
|
2019-08-16 16:12:42 +02:00
|
|
|
index,
|
2019-06-20 00:20:09 +02:00
|
|
|
zeroX(signature),
|
|
|
|
consumer.getId()
|
|
|
|
)
|
2019-02-21 17:58:54 +01:00
|
|
|
|
|
|
|
if (!result.ok) {
|
2019-06-20 00:20:09 +02:00
|
|
|
throw new Error(
|
|
|
|
'Error on initialize agreement: ' + (await result.text())
|
|
|
|
)
|
2019-02-21 17:58:54 +01:00
|
|
|
}
|
2019-02-13 14:32:52 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Create a service agreement on-chain. This should be called by the publisher of the asset.
|
|
|
|
* Consumer signature will be verified on-chain, but it is recommended to verify the signature
|
|
|
|
* in this method before submitting on-chain.
|
2019-01-21 17:48:40 +01:00
|
|
|
* @param {string} did Decentralized ID.
|
2019-02-13 14:32:52 +01:00
|
|
|
* @param {string} agreementId Service agreement ID.
|
2019-08-16 16:12:42 +02:00
|
|
|
* @param {number} index Service index.
|
2019-02-13 14:32:52 +01:00
|
|
|
* @param {string} signature Service agreement signature.
|
2019-01-21 17:48:40 +01:00
|
|
|
* @param {Account} consumer Consumer account.
|
|
|
|
* @param {Account} publisher Publisher account.
|
2019-03-14 15:47:31 +01:00
|
|
|
* @return {Promise<boolean>}
|
2019-01-21 17:48:40 +01:00
|
|
|
*/
|
|
|
|
public async create(
|
|
|
|
did: string,
|
2019-02-13 14:32:52 +01:00
|
|
|
agreementId: string,
|
2019-08-16 16:12:42 +02:00
|
|
|
index: number,
|
2019-02-13 14:32:52 +01:00
|
|
|
signature: string,
|
2019-01-21 17:48:40 +01:00
|
|
|
consumer: Account,
|
2019-06-20 00:20:09 +02:00
|
|
|
publisher: Account
|
2019-03-14 15:47:31 +01:00
|
|
|
) {
|
2019-01-21 17:48:40 +01:00
|
|
|
const d: DID = DID.parse(did)
|
2019-03-21 02:56:58 +01:00
|
|
|
const ddo = await this.ocean.aquarius.retrieveDDO(d)
|
2019-01-21 17:48:40 +01:00
|
|
|
|
2019-08-16 16:12:42 +02:00
|
|
|
const templateName = ddo.findServiceById<'access'>(index)
|
2019-06-20 00:20:09 +02:00
|
|
|
.serviceAgreementTemplate.contractName
|
2019-03-21 02:56:58 +01:00
|
|
|
await this.ocean.keeper
|
2019-03-14 15:47:31 +01:00
|
|
|
.getTemplateByName(templateName)
|
2019-06-20 00:20:09 +02:00
|
|
|
.createAgreementFromDDO(
|
|
|
|
agreementId,
|
|
|
|
ddo,
|
|
|
|
consumer.getId(),
|
|
|
|
publisher.getId()
|
|
|
|
)
|
2019-01-21 17:48:40 +01:00
|
|
|
|
2019-03-14 15:47:31 +01:00
|
|
|
return true
|
2019-01-21 17:48:40 +01:00
|
|
|
}
|
2019-04-15 14:28:17 +02:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Get the status of a service agreement.
|
|
|
|
* @param {string} agreementId Service agreement ID.
|
|
|
|
* @param {boolean} extended Returns a complete status with dependencies.
|
|
|
|
* @return {Promise<any>}
|
|
|
|
*/
|
|
|
|
public async status(
|
|
|
|
agreementId: string,
|
2019-06-20 00:20:09 +02:00
|
|
|
extended?: false
|
|
|
|
): Promise<{ [condition: string]: ConditionState }>
|
2019-08-19 13:21:19 +02:00
|
|
|
|
2019-06-20 00:20:09 +02:00
|
|
|
public async status(
|
|
|
|
agreementId: string,
|
|
|
|
extended: true
|
|
|
|
): Promise<AgreementConditionsStatus>
|
2019-08-19 13:21:19 +02:00
|
|
|
|
2019-06-20 00:20:09 +02:00
|
|
|
public async status(agreementId: string, extended: boolean = false) {
|
|
|
|
const {
|
|
|
|
templateId
|
|
|
|
} = await this.ocean.keeper.agreementStoreManager.getAgreement(
|
|
|
|
agreementId
|
|
|
|
)
|
2019-04-15 14:28:17 +02:00
|
|
|
const fullStatus = await this.ocean.keeper
|
2019-04-16 14:33:42 +02:00
|
|
|
.getTemplateByAddress(templateId)
|
2019-04-15 14:28:17 +02:00
|
|
|
.getAgreementStatus(agreementId)
|
|
|
|
|
|
|
|
if (!fullStatus) {
|
|
|
|
return
|
|
|
|
}
|
|
|
|
if (extended) {
|
|
|
|
return fullStatus
|
|
|
|
}
|
|
|
|
const simpleStatus = {}
|
2019-06-20 00:20:09 +02:00
|
|
|
Object.entries(fullStatus).forEach(([condition, { state }]) => {
|
|
|
|
simpleStatus[condition] = state
|
|
|
|
})
|
2019-04-15 14:28:17 +02:00
|
|
|
return simpleStatus as any
|
|
|
|
}
|
2019-01-21 17:48:40 +01:00
|
|
|
}
|