2019-02-28 21:28:57 +01:00
|
|
|
import ContractBase from "../ContractBase"
|
2019-03-12 23:46:07 +01:00
|
|
|
import { AgreementStoreManager, ConditionStoreManager } from "../managers"
|
|
|
|
import { Condition, ConditionState, conditionStateNames } from "../conditions/Condition.abstract"
|
2019-02-28 21:28:57 +01:00
|
|
|
import Keeper from "../../Keeper"
|
2019-03-12 13:49:11 +01:00
|
|
|
import { DDO } from '../../../ddo/DDO'
|
2019-03-13 13:22:20 +01:00
|
|
|
import { ServiceAgreementTemplate } from '../../../ddo/ServiceAgreementTemplate'
|
2019-03-12 23:46:07 +01:00
|
|
|
import { zeroX, Logger } from "../../../utils"
|
2019-02-28 21:28:57 +01:00
|
|
|
|
|
|
|
export abstract class AgreementTemplate extends ContractBase {
|
|
|
|
|
|
|
|
protected constructor(contractName: string) {
|
|
|
|
super(contractName)
|
|
|
|
}
|
|
|
|
|
2019-03-04 13:05:27 +01:00
|
|
|
public static async getInstance(conditionName: string, templateClass: any): Promise<AgreementTemplate & any> {
|
2019-02-28 21:28:57 +01:00
|
|
|
const condition: AgreementTemplate = new (templateClass as any)(conditionName)
|
|
|
|
await condition.init()
|
|
|
|
return condition
|
|
|
|
}
|
|
|
|
|
|
|
|
// tslint:disable-next-line
|
|
|
|
public createAgreement(agreementId: string, did: string, conditionIds: string[], timeLocks: number[], timeOuts: number[], ...args: any[])
|
|
|
|
public createAgreement(
|
|
|
|
agreementId: string,
|
|
|
|
did: string,
|
|
|
|
conditionIds: string[],
|
|
|
|
timeLocks: number[],
|
|
|
|
timeOuts: number[],
|
|
|
|
extraArgs: any[],
|
|
|
|
from?: string,
|
|
|
|
) {
|
|
|
|
return this.sendFrom(
|
|
|
|
"createAgreement",
|
|
|
|
[
|
2019-03-04 14:34:24 +01:00
|
|
|
zeroX(agreementId),
|
|
|
|
zeroX(did),
|
|
|
|
conditionIds.map(zeroX),
|
2019-02-28 21:28:57 +01:00
|
|
|
timeLocks,
|
|
|
|
timeOuts,
|
|
|
|
...extraArgs,
|
|
|
|
],
|
|
|
|
from,
|
|
|
|
)
|
|
|
|
}
|
|
|
|
|
|
|
|
public getConditionTypes(): Promise<string[]> {
|
|
|
|
return this.call("getConditionTypes", [])
|
|
|
|
}
|
|
|
|
|
|
|
|
public async getConditions(): Promise<Condition[]> {
|
|
|
|
const keeper = await Keeper.getInstance()
|
|
|
|
return (await this.getConditionTypes())
|
|
|
|
.map(address => keeper.getConditionByAddress(address))
|
|
|
|
}
|
2019-03-07 15:57:43 +01:00
|
|
|
|
2019-03-13 13:22:20 +01:00
|
|
|
abstract getAgreementIdsFromDDO(agreementId: string, ddo: DDO, from: string): Promise<string[]>
|
2019-03-12 13:49:11 +01:00
|
|
|
|
2019-03-13 13:22:20 +01:00
|
|
|
abstract async getServiceAgreementTemplate(): Promise<ServiceAgreementTemplate>
|
2019-03-07 15:57:43 +01:00
|
|
|
|
2019-03-12 23:46:07 +01:00
|
|
|
public async getServiceAgreementTemplateConditions() {
|
2019-03-07 15:57:43 +01:00
|
|
|
const serviceAgreementTemplate = await this.getServiceAgreementTemplate()
|
|
|
|
return serviceAgreementTemplate.conditions
|
|
|
|
}
|
2019-03-12 23:46:07 +01:00
|
|
|
|
|
|
|
public async getServiceAgreementTemplateConditionByRef(ref: string) {
|
|
|
|
const name = (await this.getServiceAgreementTemplateConditions())
|
|
|
|
.find(({name: conditionRef}) => conditionRef === ref)
|
|
|
|
.contractName
|
|
|
|
return (await this.getConditions())
|
|
|
|
.find(condition => condition.contractName === name)
|
|
|
|
}
|
|
|
|
|
|
|
|
public async getServiceAgreementTemplateDependencies() {
|
|
|
|
const serviceAgreementTemplate = await this.getServiceAgreementTemplate()
|
|
|
|
return serviceAgreementTemplate.conditionDependency
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Returns the status of the conditions.
|
|
|
|
* @param {string} agreementId Agreement ID.
|
|
|
|
* @return {Promise} Conditions status.
|
|
|
|
*/
|
|
|
|
public async getAgreementStatus(
|
|
|
|
agreementId: string
|
|
|
|
): Promise<{
|
|
|
|
[condition: string]: {
|
|
|
|
condition: string,
|
|
|
|
contractName: string,
|
|
|
|
state: ConditionState,
|
|
|
|
blocked: boolean,
|
|
|
|
blockedBy: string[]
|
|
|
|
}
|
|
|
|
}> {
|
|
|
|
const agreementStore = await AgreementStoreManager.getInstance()
|
|
|
|
const conditionStore = await ConditionStoreManager.getInstance()
|
|
|
|
|
|
|
|
const dependencies = await this.getServiceAgreementTemplateDependencies()
|
|
|
|
const {conditionIds} = await agreementStore.getAgreement(agreementId)
|
2019-03-14 02:10:21 +01:00
|
|
|
const conditionIdByConddition = (await this.getConditions())
|
|
|
|
.reduce((acc, {contractName}, i) => ({...acc, [contractName]: conditionIds[i]}), {})
|
2019-03-12 23:46:07 +01:00
|
|
|
|
|
|
|
const statesPromises = Object.keys(dependencies)
|
|
|
|
.map(async (ref, i) => {
|
2019-03-14 02:10:21 +01:00
|
|
|
const {contractName} = await this.getServiceAgreementTemplateConditionByRef(ref)
|
2019-03-12 23:46:07 +01:00
|
|
|
return {
|
|
|
|
ref,
|
2019-03-14 02:10:21 +01:00
|
|
|
contractName,
|
|
|
|
state: (await conditionStore.getCondition(conditionIdByConddition[contractName])).state
|
2019-03-12 23:46:07 +01:00
|
|
|
}
|
|
|
|
})
|
|
|
|
const states = await Promise.all(statesPromises)
|
|
|
|
|
|
|
|
return states
|
|
|
|
.reduce((acc, {contractName, ref, state}) => {
|
|
|
|
const blockers = dependencies[ref]
|
|
|
|
.map(dependency => states.find(({ref}) => ref === dependency))
|
|
|
|
.filter(condition => condition.state !== ConditionState.Fulfilled)
|
|
|
|
return {
|
|
|
|
...acc,
|
|
|
|
[ref]: {
|
|
|
|
condition: ref,
|
|
|
|
contractName,
|
|
|
|
state,
|
|
|
|
blocked: !!blockers.length,
|
|
|
|
blockedBy: blockers.map(_ => _.ref),
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}, {})
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Prints the agreement status.
|
|
|
|
* @param {string} agreementId Agreement ID.
|
|
|
|
*/
|
|
|
|
public async printAgreementStatus(agreementId: string) {
|
|
|
|
const status = await this.getAgreementStatus(agreementId)
|
|
|
|
|
|
|
|
Logger.bypass("-".repeat(80))
|
|
|
|
Logger.bypass("Template:", this.contractName)
|
|
|
|
Logger.bypass("Agreement ID:", agreementId)
|
|
|
|
Logger.bypass("-".repeat(40))
|
|
|
|
Object.values(status)
|
|
|
|
.forEach(({condition, contractName, state, blocked, blockedBy}, i) => {
|
|
|
|
if (i) {
|
|
|
|
Logger.bypass("-".repeat(20))
|
|
|
|
}
|
|
|
|
Logger.bypass(`${condition} (${contractName})`)
|
|
|
|
Logger.bypass(" Status:", state, `(${conditionStateNames[state]})`)
|
|
|
|
if (blocked) {
|
|
|
|
Logger.bypass(" Blocked by:", blockedBy)
|
|
|
|
}
|
|
|
|
})
|
|
|
|
Logger.bypass("-".repeat(80))
|
|
|
|
}
|
2019-02-28 21:28:57 +01:00
|
|
|
}
|