1
0
mirror of https://github.com/oceanprotocol-archive/squid-js.git synced 2024-02-02 15:31:51 +01:00
squid-js/src/keeper/contracts/templates/AgreementTemplate.abstract.ts

196 lines
7.2 KiB
TypeScript
Raw Normal View History

import ContractBase from "../ContractBase"
import { Condition, ConditionState, conditionStateNames } from "../conditions/Condition.abstract"
2019-03-14 21:28:51 +01:00
import { DDO } from "../../../ddo/DDO"
import { ServiceAgreementTemplate } from "../../../ddo/ServiceAgreementTemplate"
import { zeroX } from "../../../utils"
import { InstantiableConfig } from "../../../Instantiable.abstract"
export abstract class AgreementTemplate extends ContractBase {
public static async getInstance(config: InstantiableConfig, conditionName: string, templateClass: any): Promise<AgreementTemplate & any> {
const condition: AgreementTemplate = new (templateClass as any)(conditionName)
await condition.init(config)
return condition
}
2019-03-14 21:28:51 +01:00
protected constructor(contractName: string) {
super(contractName)
}
// 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",
[
zeroX(agreementId),
zeroX(did),
conditionIds.map(zeroX),
timeLocks,
timeOuts,
...extraArgs,
],
from,
)
}
/**
* Conditions address list.
* @return {Promise<string[]>} Conditions address.
*/
public getConditionTypes(): Promise<string[]> {
return this.call("getConditionTypes", [])
}
/**
* List of condition contracts.
* @return {Promise<Condition[]>} Conditions contracts.
*/
public async getConditions(): Promise<Condition[]> {
return (await this.getConditionTypes())
.map((address) => this.ocean.keeper.getConditionByAddress(address))
}
/**
* Get agreement conditions IDs.
* @param {string} agreementId Agreement ID.
* @param {DDO} ddo DDO.
* @param {string} from Consumer address.
* @return {Promise<string[]>} Condition IDs.
*/
2019-03-14 21:28:51 +01:00
public abstract getAgreementIdsFromDDO(agreementId: string, ddo: DDO, consumer: string, from?: string): Promise<string[]>
/**
* Create a new agreement using the data of a DDO.
* @param {string} agreementId Agreement ID.
* @param {DDO} ddo DDO.
* @param {string} from Creator address.
* @return {Promise<boolean>} Success.
*/
2019-03-14 21:28:51 +01:00
public abstract createAgreementFromDDO(agreementId: string, ddo: DDO, consumer: string, from?: string): Promise<boolean>
2019-03-14 21:28:51 +01:00
public abstract async getServiceAgreementTemplate(): Promise<ServiceAgreementTemplate>
public async getServiceAgreementTemplateConditions() {
const serviceAgreementTemplate = await this.getServiceAgreementTemplate()
return serviceAgreementTemplate.conditions
}
public async getServiceAgreementTemplateConditionByRef(ref: string) {
const name = (await this.getServiceAgreementTemplateConditions())
.find(({name: conditionRef}) => conditionRef === ref)
.contractName
return (await this.getConditions())
2019-03-14 21:28:51 +01:00
.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(
2019-03-14 21:28:51 +01:00
agreementId: string,
): Promise<{
[condition: string]: {
condition: string,
contractName: string,
state: ConditionState,
blocked: boolean,
2019-03-14 21:28:51 +01:00
blockedBy: string[],
},
} | false> {
const agreementStore = this.ocean.keeper.agreementStoreManager
const conditionStore = this.ocean.keeper.conditionStoreManager
const dependencies = await this.getServiceAgreementTemplateDependencies()
const {conditionIds} = await agreementStore.getAgreement(agreementId)
if (!conditionIds.length) {
this.logger.error(`Agreement not creeated yet: "${agreementId}"`)
return false
}
2019-03-14 02:10:21 +01:00
const conditionIdByConddition = (await this.getConditions())
.reduce((acc, {contractName}, i) => ({...acc, [contractName]: conditionIds[i]}), {})
const statesPromises = Object.keys(dependencies)
.map(async (ref, i) => {
2019-03-14 02:10:21 +01:00
const {contractName} = await this.getServiceAgreementTemplateConditionByRef(ref)
return {
ref,
2019-03-14 02:10:21 +01:00
contractName,
2019-03-14 21:28:51 +01:00
state: (await conditionStore.getCondition(conditionIdByConddition[contractName])).state,
}
})
const states = await Promise.all(statesPromises)
return states
.reduce((acc, {contractName, ref, state}) => {
const blockers = dependencies[ref]
2019-03-14 21:28:51 +01:00
.map((dependency) => states.find((_) => _.ref === dependency))
.filter((condition) => condition.state !== ConditionState.Fulfilled)
return {
...acc,
[ref]: {
condition: ref,
contractName,
state,
blocked: !!blockers.length,
2019-03-14 21:28:51 +01:00
blockedBy: blockers.map((_) => _.ref),
},
}
}, {})
}
/**
* Prints the agreement status.
* @param {string} agreementId Agreement ID.
*/
public async printAgreementStatus(agreementId: string) {
const status = await this.getAgreementStatus(agreementId)
this.logger.bypass("-".repeat(80))
this.logger.bypass("Template:", this.contractName)
this.logger.bypass("Agreement ID:", agreementId)
this.logger.bypass("-".repeat(40))
if (!status) {
this.logger.bypass("Agreement not created yet!")
}
Object.values(status || [])
.forEach(({condition, contractName, state, blocked, blockedBy}, i) => {
if (i) {
this.logger.bypass("-".repeat(20))
}
this.logger.bypass(`${condition} (${contractName})`)
this.logger.bypass(" Status:", state, `(${conditionStateNames[state]})`)
if (blocked) {
this.logger.bypass(" Blocked by:", blockedBy)
}
})
this.logger.bypass("-".repeat(80))
}
/**
* Generates and returns the agreement creation event.
* @param {string} agreementId Agreement ID.
* @return {Event} Agreement created event.
*/
public getAgreementCreatedEvent(agreementId: string) {
return this.getEvent("AgreementCreated", {agreementId: zeroX(agreementId)})
}
}