1
0
mirror of https://github.com/oceanprotocol-archive/squid-js.git synced 2024-02-02 15:31:51 +01:00

added event wireup

added lock payment
added fulfilmentOperators
added declarative way to describe dependencies
added service agreement termination
This commit is contained in:
Sebastian Gerske 2018-11-20 09:13:03 +01:00
parent a2bfe0a816
commit dfff8fc228
18 changed files with 301 additions and 92 deletions

View File

@ -1,9 +1,14 @@
import Event from "./Event"
import Parameter from "./Parameter" import Parameter from "./Parameter"
export default class Condition { export default class Condition {
public contractName: string = "AccessCondition" public contractName: string = "AccessCondition"
public methodName: string = "lockPayment" public methodName: string = "lockPayment"
public timeout: number = 0 public timeout: number = 0
public conditionKey: string public conditionKey: string = "0x12122434"
public parameters: Parameter[] public parameters: Parameter[]
public events: Event[]
public dependencies: string[] = []
public dependencyTimeoutFlags: number[] = []
public isTerminalCondition: boolean = false
} }

7
src/ddo/Event.ts Normal file
View File

@ -0,0 +1,7 @@
import EventHandlers from "./EventHandlers"
export default class Event {
public name: string
public actorType: string[]
public handlers: EventHandlers
}

5
src/ddo/EventHandlers.ts Normal file
View File

@ -0,0 +1,5 @@
export default class EventHandlers {
public moduleName: string = "serviceAgreement"
public functionName: string = "fulfillAgreement"
public version: string = "0.1"
}

View File

@ -3,16 +3,14 @@ import GenericContract from "./contracts/GenericContract"
export default class ContractReflector { export default class ContractReflector {
public static async reflectContractMethod(pathToMethod: string): Promise<MethodReflection> { public static async reflectContractMethod(contractName: string, methodName: string): Promise<MethodReflection> {
const parts: string[] = pathToMethod.split(".") const contract = await GenericContract.getInstance(contractName)
const contract = await GenericContract.getInstance(parts[0])
return { return {
contractName: parts[0], contractName,
methodName: parts[1], methodName,
address: contract.getAddress(), address: contract.getAddress(),
signature: contract.getSignatureOfMethod(parts[1]), signature: contract.getSignatureOfMethod(methodName),
inputs: contract.getInputsOfMethod(parts[1]), inputs: contract.getInputsOfMethod(methodName),
} as MethodReflection } as MethodReflection
} }
} }

View File

@ -1,5 +1,6 @@
import OceanAuth from "./contracts/Auth" import OceanAuth from "./contracts/Auth"
import AccessConditions from "./contracts/conditions/AccessConditions" import AccessConditions from "./contracts/conditions/AccessConditions"
import PaymentConditions from "./contracts/conditions/PaymentConditions"
import DIDRegistry from "./contracts/DIDRegistry" import DIDRegistry from "./contracts/DIDRegistry"
import OceanMarket from "./contracts/Market" import OceanMarket from "./contracts/Market"
import ServiceAgreement from "./contracts/ServiceAgreement" import ServiceAgreement from "./contracts/ServiceAgreement"
@ -18,6 +19,7 @@ export default class Keeper {
Keeper.instance.token = await OceanToken.getInstance() Keeper.instance.token = await OceanToken.getInstance()
Keeper.instance.serviceAgreement = await ServiceAgreement.getInstance() Keeper.instance.serviceAgreement = await ServiceAgreement.getInstance()
Keeper.instance.accessConditions = await AccessConditions.getInstance() Keeper.instance.accessConditions = await AccessConditions.getInstance()
Keeper.instance.paymentConditions = await PaymentConditions.getInstance()
Keeper.instance.didRegistry = await DIDRegistry.getInstance() Keeper.instance.didRegistry = await DIDRegistry.getInstance()
} }
return Keeper.instance return Keeper.instance
@ -30,6 +32,7 @@ export default class Keeper {
public auth: OceanAuth public auth: OceanAuth
public serviceAgreement: ServiceAgreement public serviceAgreement: ServiceAgreement
public accessConditions: AccessConditions public accessConditions: AccessConditions
public paymentConditions: PaymentConditions
public didRegistry: DIDRegistry public didRegistry: DIDRegistry
public async getNetworkName(): Promise<string> { public async getNetworkName(): Promise<string> {

View File

@ -11,12 +11,13 @@ export default class ServiceAgreement extends ContractBase {
} }
public async setupAgreementTemplate(templateId: string, methodReflections: MethodReflection[], public async setupAgreementTemplate(templateId: string, methodReflections: MethodReflection[],
dependencyMatrix: number[], name: any, ownerAddress: string) dependencyMatrix: number[], name: any, fulfilmentOperator: number,
ownerAddress: string)
: Promise<Receipt> { : Promise<Receipt> {
return this.send("setupAgreementTemplate", ownerAddress, [ return this.send("setupAgreementTemplate", ownerAddress, [
templateId, methodReflections.map((r) => r.address), templateId, methodReflections.map((r) => r.address),
methodReflections.map((r) => r.signature), dependencyMatrix, name, [0], 0, methodReflections.map((r) => r.signature), dependencyMatrix, name, [0], fulfilmentOperator,
]) ])
} }

View File

@ -1,3 +1,4 @@
import {Receipt} from "web3-utils"
import ContractBase from "../ContractBase" import ContractBase from "../ContractBase"
export default class PaymentConditions extends ContractBase { export default class PaymentConditions extends ContractBase {
@ -7,4 +8,11 @@ export default class PaymentConditions extends ContractBase {
await paymentConditions.init() await paymentConditions.init()
return paymentConditions return paymentConditions
} }
public async lockPayment(serviceAgreementId: any, assetId: any, price: number, publisherAddress: string)
: Promise<Receipt> {
return this.send("lockPayment", publisherAddress, [
serviceAgreementId, "0x" + assetId, price,
])
}
} }

View File

@ -5,6 +5,8 @@ import ConfigProvider from "../ConfigProvider"
import Authentication from "../ddo/Authentication" import Authentication from "../ddo/Authentication"
import DDOCondition from "../ddo/Condition" import DDOCondition from "../ddo/Condition"
import DDO from "../ddo/DDO" import DDO from "../ddo/DDO"
import Event from "../ddo/Event"
import EventHandlers from "../ddo/EventHandlers"
import MetaData from "../ddo/MetaData" import MetaData from "../ddo/MetaData"
import Parameter from "../ddo/Parameter" import Parameter from "../ddo/Parameter"
import Service from "../ddo/Service" import Service from "../ddo/Service"
@ -75,17 +77,39 @@ export default class Ocean {
const conditions: Condition[] = await serviceAgreementTemplate.getConditions() const conditions: Condition[] = await serviceAgreementTemplate.getConditions()
// create ddo conditions out of the keys // create ddo conditions out of the keys
const ddoConditions: DDOCondition[] = conditions.map((condition: Condition): DDOCondition => { const ddoConditions: DDOCondition[] = conditions.map((condition: Condition, index: number): DDOCondition => {
const events: Event[] = [
{
name: "PaymentReleased",
actorType: [
"consumer",
],
handlers: {
moduleName: "serviceAgreement",
functionName: "fulfillAgreement",
version: "0.1",
} as EventHandlers,
} as Event,
]
const parameters: Parameter[] = condition.methodReflection.inputs.map((input: ValuePair) => {
return {
...input,
value: "xxx",
} as Parameter
})
return { return {
contractName: condition.methodReflection.contractName, contractName: condition.methodReflection.contractName,
methodName: condition.methodReflection.methodName, methodName: condition.methodReflection.methodName,
timeout: condition.timeout, timeout: condition.timeout,
index,
conditionKey: condition.condtionKey, conditionKey: condition.condtionKey,
parameters: condition.methodReflection.inputs.map((input: ValuePair) => { parameters,
return { events,
...input, dependencies: condition.dependencies,
} as Parameter dependencyTimeoutFlags: condition.dependencyTimeoutFlags,
}), isTerminalCondition: condition.isTerminalCondition,
} as DDOCondition } as DDOCondition
}) })
const serviceEndpoint = aquarius.getServiceEndpoint(did) const serviceEndpoint = aquarius.getServiceEndpoint(did)

View File

@ -3,5 +3,8 @@ import MethodReflection from "../../models/MethodReflection"
export default class Condition { export default class Condition {
public methodReflection: MethodReflection public methodReflection: MethodReflection
public condtionKey: string public condtionKey: string
public dependencies: string[]
public dependencyTimeoutFlags: number[]
public isTerminalCondition: boolean
public timeout: number public timeout: number
} }

View File

@ -1,5 +1,9 @@
export default class Method { export default class Method {
public path: string public name: string
public dependency: number public contractName: string
public methodName: string
public timeout: number public timeout: number
public dependencies: string[]
public dependencyTimeoutFlags: number[]
public isTerminalCondition: boolean
} }

View File

@ -13,10 +13,10 @@ export default class ServiceAgreement extends OceanBase {
serviceAgreementId: string, consumer: Account): serviceAgreementId: string, consumer: Account):
Promise<string> { Promise<string> {
const values: ValuePair[] = ServiceAgreement.getValuesFromDDO(ddo, serviceAgreementId)
const valueHashes = ServiceAgreement.createValueHashes(values)
const timeoutValues: number[] = ServiceAgreement.getTimeoutValuesFromDDO(ddo)
const service: Service = ddo.findServiceById(serviceDefinitionId) const service: Service = ddo.findServiceById(serviceDefinitionId)
const values: ValuePair[] = ServiceAgreement.getValuesFromService(service, serviceAgreementId)
const valueHashes = ServiceAgreement.createValueHashes(values)
const timeoutValues: number[] = ServiceAgreement.getTimeoutValuesFromService(service)
const serviceAgreementHashSignature = await ServiceAgreement.createSAHashSignature(service, serviceAgreementId, const serviceAgreementHashSignature = await ServiceAgreement.createSAHashSignature(service, serviceAgreementId,
values, valueHashes, timeoutValues, consumer) values, valueHashes, timeoutValues, consumer)
@ -28,9 +28,10 @@ export default class ServiceAgreement extends OceanBase {
serviceAgreementId: string, serviceAgreementHashSignature: string, serviceAgreementId: string, serviceAgreementHashSignature: string,
consumer: Account, publisher: Account): Promise<ServiceAgreement> { consumer: Account, publisher: Account): Promise<ServiceAgreement> {
const values: ValuePair[] = ServiceAgreement.getValuesFromDDO(ddo, serviceAgreementId) const service: Service = ddo.findServiceById(serviceDefinitionId)
const values: ValuePair[] = ServiceAgreement.getValuesFromService(service, serviceAgreementId)
const valueHashes = ServiceAgreement.createValueHashes(values) const valueHashes = ServiceAgreement.createValueHashes(values)
const timeoutValues: number[] = ServiceAgreement.getTimeoutValuesFromDDO(ddo) const timeoutValues: number[] = ServiceAgreement.getTimeoutValuesFromService(service)
const serviceAgreement: ServiceAgreement = await ServiceAgreement.executeAgreement(ddo, const serviceAgreement: ServiceAgreement = await ServiceAgreement.executeAgreement(ddo,
serviceDefinitionId, serviceAgreementId, valueHashes, timeoutValues, serviceAgreementHashSignature, serviceDefinitionId, serviceAgreementId, valueHashes, timeoutValues, serviceAgreementHashSignature,
@ -70,7 +71,7 @@ export default class ServiceAgreement extends OceanBase {
const service: Service = ddo.findServiceById(serviceDefinitionId) const service: Service = ddo.findServiceById(serviceDefinitionId)
if (!service.templateId) { if (!service.templateId) {
throw new Error("TemplateId not found in ddo.") throw new Error(`TemplateId not found in service "${service.type}" ddo.`)
} }
const executeAgreementReceipt = await serviceAgreement.executeAgreement( const executeAgreementReceipt = await serviceAgreement.executeAgreement(
@ -115,23 +116,23 @@ export default class ServiceAgreement extends OceanBase {
return Web3Provider.getWeb3().utils.soliditySha3(...args).toString("hex") return Web3Provider.getWeb3().utils.soliditySha3(...args).toString("hex")
} }
private static getTimeoutValuesFromDDO(ddo: DDO): number[] { private static getTimeoutValuesFromService(service: Service): number[] {
const timeoutValues: number[] = service.conditions.map((condition: Condition) => {
const timeoutValues: number[] = ddo.service[0].conditions.map((condition: Condition) => {
return condition.timeout return condition.timeout
}) })
return timeoutValues return timeoutValues
} }
private static getValuesFromDDO(ddo: DDO, serviceAgreementId: string): ValuePair[] { private static getValuesFromService(service: Service, serviceAgreementId: string): ValuePair[] {
const values: ValuePair[] = [
{type: "bool", value: true} as ValuePair, const values: ValuePair[] = []
{type: "bool", value: false} as ValuePair,
{type: "bool", value: false} as ValuePair, service.conditions.forEach((condition) => {
{type: "uint", value: 120} as ValuePair, condition.parameters.forEach((parameter) => {
{type: "string", value: serviceAgreementId} as ValuePair, values.push({type: parameter.type, value: parameter.value} as ValuePair)
] })
})
return values return values
} }
@ -141,6 +142,16 @@ export default class ServiceAgreement extends OceanBase {
super(serviceAgreementId) super(serviceAgreementId)
} }
public async lockPayment(assetId: string, price: number, consumer: Account): Promise<boolean> {
const {paymentConditions} = await Keeper.getInstance()
const lockPaymentRceipt =
await paymentConditions.lockPayment(this.getId(), assetId, price,
consumer.getId())
return lockPaymentRceipt.status
}
public async grantAccess(assetId: string, documentId: string): Promise<boolean> { public async grantAccess(assetId: string, documentId: string): Promise<boolean> {
const {accessConditions} = await Keeper.getInstance() const {accessConditions} = await Keeper.getInstance()

View File

@ -31,8 +31,7 @@ export default class ServiceAgreementTemplate extends OceanBase {
const dependencyMatrix: number[] = const dependencyMatrix: number[] =
await Promise.all(this.template.Methods.map(async (method: Method) => { await Promise.all(this.template.Methods.map(async (method: Method) => {
// tslint:disable-next-line return this.compressDependencies(method.dependencies, method.dependencyTimeoutFlags)
return method.dependency | method.timeout
})) }))
const {serviceAgreement} = await Keeper.getInstance() const {serviceAgreement} = await Keeper.getInstance()
@ -55,7 +54,7 @@ export default class ServiceAgreementTemplate extends OceanBase {
const receipt = await serviceAgreement.setupAgreementTemplate( const receipt = await serviceAgreement.setupAgreementTemplate(
this.template.id, methodReflections, dependencyMatrix, this.template.id, methodReflections, dependencyMatrix,
Web3Provider.getWeb3().utils.fromAscii(this.template.templateName), Web3Provider.getWeb3().utils.fromAscii(this.template.templateName),
templateOwnerAddress) this.template.fulfilmentOperator, templateOwnerAddress)
const {serviceTemplateId, provider} = receipt.events.SetupAgreementTemplate.returnValues const {serviceTemplateId, provider} = receipt.events.SetupAgreementTemplate.returnValues
@ -94,9 +93,13 @@ export default class ServiceAgreementTemplate extends OceanBase {
const methodReflections = await this.getMethodReflections() const methodReflections = await this.getMethodReflections()
const conditions: Condition[] = methodReflections.map((methodReflection, i) => { const conditions: Condition[] = methodReflections.map((methodReflection, i) => {
const method: Method = this.template.Methods[i]
return { return {
methodReflection, methodReflection,
timeout: this.template.Methods[i].timeout, timeout: method.timeout,
dependencies: method.dependencies,
dependencyTimeoutFlags: method.dependencyTimeoutFlags,
isTerminalCondition: method.isTerminalCondition,
condtionKey: ServiceAgreementTemplate.generateConditionsKey(this.getId(), condtionKey: ServiceAgreementTemplate.generateConditionsKey(this.getId(),
methodReflection), methodReflection),
} as Condition } as Condition
@ -105,10 +108,38 @@ export default class ServiceAgreementTemplate extends OceanBase {
return conditions return conditions
} }
private compressDependencies(dependencies: string[], dependencyTimeoutFlags: number[]): number {
if (dependencies.length !== dependencyTimeoutFlags.length) {
throw new Error("Deps and timeouts need the same length")
}
// map name to index
const mappedDependencies: number[] = dependencies.map((dep: string) => {
return this.template.Methods.findIndex((m) => m.name === dep)
})
let compressedDependencyValue = 0
const numBits = 2 // 1st for dependency, 2nd for timeout flag
for (let i = 0; i < mappedDependencies.length; i++) {
const dependencyIndex = mappedDependencies[i]
const timeout = dependencyTimeoutFlags[i]
const offset = i * numBits
// tslint:disable-next-line
compressedDependencyValue |= dependencyIndex * 2 ** (offset + 0) // the dependency bit
// tslint:disable-next-line
compressedDependencyValue |= timeout * 2 ** (offset + 1) // the timeout bit
}
return compressedDependencyValue
}
private async getMethodReflections(): Promise<MethodReflection[]> { private async getMethodReflections(): Promise<MethodReflection[]> {
const methodReflections: MethodReflection[] = [] const methodReflections: MethodReflection[] = []
for (const method of this.template.Methods) { for (const method of this.template.Methods) {
methodReflections.push(await ContractReflector.reflectContractMethod(method.path)) methodReflections.push(
await ContractReflector.reflectContractMethod(method.contractName, method.methodName),
)
} }
return methodReflections return methodReflections
} }

View File

@ -7,24 +7,40 @@ export default class Access extends TemplateBase {
public id: string = "0x044852b2a670ade5407e78fb2863c51de9fcb96542a07186fe3aeda6bb8a116d" public id: string = "0x044852b2a670ade5407e78fb2863c51de9fcb96542a07186fe3aeda6bb8a116d"
public Methods: Method[] = [ public Methods: Method[] = [
{ {
path: "PaymentConditions.lockPayment", name: "lockPayment",
dependency: 0, contractName: "PaymentConditions",
methodName: "lockPayment",
timeout: 0,
dependencies: [],
dependencyTimeoutFlags: [],
isTerminalCondition: false,
} as Method,
{
name: "grantAccess",
contractName: "AccessConditions",
methodName: "grantAccess",
timeout: 10, timeout: 10,
dependencies: ["lockPayment"],
dependencyTimeoutFlags: [0],
isTerminalCondition: false,
} as Method, } as Method,
{ {
path: "AccessConditions.grantAccess", name: "releasePayment",
dependency: 1, contractName: "PaymentConditions",
timeout: 500, methodName: "releasePayment",
timeout: 10,
dependencies: ["grantAccess"],
dependencyTimeoutFlags: [0],
isTerminalCondition: true,
} as Method, } as Method,
{ {
path: "PaymentConditions.releasePayment", name: "refundPayment",
dependency: 4, contractName: "PaymentConditions",
timeout: 17, methodName: "refundPayment",
} as Method, timeout: 10,
{ dependencies: ["lockPayment", "grantAccess"],
path: "PaymentConditions.refundPayment", dependencyTimeoutFlags: [0, 1],
dependency: 1, isTerminalCondition: true,
timeout: 40,
} as Method, } as Method,
] ]
} }

View File

@ -7,24 +7,40 @@ export default class FitchainCompute extends TemplateBase {
public id: string = "0xc89efdaa54c0f20c7adf612882df0950f5a951637e0307cdcb4c672f298b8bc6" public id: string = "0xc89efdaa54c0f20c7adf612882df0950f5a951637e0307cdcb4c672f298b8bc6"
public Methods: Method[] = [ public Methods: Method[] = [
{ {
path: "PaymentConditions.lockPayment", name: "lockPayment",
dependency: 0, contractName: "PaymentConditions",
methodName: "lockPayment",
timeout: 0,
dependencies: [],
dependencyTimeoutFlags: [],
isTerminalCondition: false,
} as Method,
{
name: "grantAccess",
contractName: "AccessConditions",
methodName: "grantAccess",
timeout: 10, timeout: 10,
dependencies: ["lockPayment"],
dependencyTimeoutFlags: [0],
isTerminalCondition: false,
} as Method, } as Method,
{ {
path: "AccessConditions.grantAccess", name: "releasePayment",
dependency: 1, contractName: "PaymentConditions",
timeout: 500, methodName: "releasePayment",
timeout: 10,
dependencies: ["grantAccess"],
dependencyTimeoutFlags: [0],
isTerminalCondition: true,
} as Method, } as Method,
{ {
path: "PaymentConditions.releasePayment", name: "refundPayment",
dependency: 4, contractName: "PaymentConditions",
timeout: 17, methodName: "refundPayment",
} as Method, timeout: 10,
{ dependencies: ["lockPayment", "grantAccess"],
path: "PaymentConditions.refundPayment", dependencyTimeoutFlags: [0, 1],
dependency: 1, isTerminalCondition: true,
timeout: 40,
} as Method, } as Method,
] ]
} }

View File

@ -3,5 +3,6 @@ import Method from "../Method"
export default abstract class TemplateBase { export default abstract class TemplateBase {
public Methods: Method[] public Methods: Method[]
public templateName: string public templateName: string
public fulfilmentOperator: number = 0
public id: string = "0x00000000000000000000000000000000000000000000000000000000000000" public id: string = "0x00000000000000000000000000000000000000000000000000000000000000"
} }

View File

@ -2,5 +2,5 @@
--require source-map-support/register --require source-map-support/register
--full-trace --full-trace
--bail --bail
--timeout 5000 --timeout 10000
test/**/*.test.ts test/**/*.test.ts

View File

@ -2,8 +2,12 @@ import {assert} from "chai"
import ConfigProvider from "../../src/ConfigProvider" import ConfigProvider from "../../src/ConfigProvider"
import DDOCondition from "../../src/ddo/Condition" import DDOCondition from "../../src/ddo/Condition"
import DDO from "../../src/ddo/DDO" import DDO from "../../src/ddo/DDO"
import Event from "../../src/ddo/Event"
import EventHandlers from "../../src/ddo/EventHandlers"
import MetaData from "../../src/ddo/MetaData"
import Parameter from "../../src/ddo/Parameter" import Parameter from "../../src/ddo/Parameter"
import Service from "../../src/ddo/Service" import Service from "../../src/ddo/Service"
import ValuePair from "../../src/models/ValuePair"
import Account from "../../src/ocean/Account" import Account from "../../src/ocean/Account"
import IdGenerator from "../../src/ocean/IdGenerator" import IdGenerator from "../../src/ocean/IdGenerator"
import Ocean from "../../src/ocean/Ocean" import Ocean from "../../src/ocean/Ocean"
@ -21,7 +25,8 @@ let accounts: Account[]
let publisherAccount: Account let publisherAccount: Account
let consumerAccount: Account let consumerAccount: Account
let service: Service let accessService: Service
let metaDataService: Service
describe("ServiceAgreement", () => { describe("ServiceAgreement", () => {
@ -41,27 +46,54 @@ describe("ServiceAgreement", () => {
const conditions: Condition[] = await serviceAgreementTemplate.getConditions() const conditions: Condition[] = await serviceAgreementTemplate.getConditions()
// create ddo conditions out of the keys // create ddo conditions out of the keys
const ddoConditions: DDOCondition[] = conditions.map((condition): DDOCondition => { const ddoConditions: DDOCondition[] = conditions.map((condition, index): DDOCondition => {
const events: Event[] = [
{
name: "PaymentReleased",
actorType: [
"consumer",
],
handlers: {
moduleName: "serviceAgreement",
functionName: "fulfillAgreement",
version: "0.1",
} as EventHandlers,
} as Event,
]
const parameters: Parameter[] = condition.methodReflection.inputs.map((input: ValuePair) => {
return {
...input,
value: "xxx",
} as Parameter
})
return { return {
contractName: condition.methodReflection.contractName, contractName: condition.methodReflection.contractName,
methodName: condition.methodReflection.methodName, methodName: condition.methodReflection.methodName,
timeout: condition.timeout, timeout: condition.timeout,
index,
conditionKey: condition.condtionKey, conditionKey: condition.condtionKey,
parameters: condition.methodReflection.inputs.map((input) => { parameters,
return { events,
...input, dependencies: condition.dependencies,
value: "xx", dependencyTimeoutFlags: condition.dependencyTimeoutFlags,
}as Parameter isTerminalCondition: condition.isTerminalCondition,
}),
} as DDOCondition } as DDOCondition
}) })
service = { accessService = {
type: "Access", type: "Access",
serviceDefinitionId: IdGenerator.generateId(), serviceDefinitionId: IdGenerator.generateId(),
templateId: serviceAgreementTemplate.getId(), templateId: serviceAgreementTemplate.getId(),
conditions: ddoConditions, conditions: ddoConditions,
} as Service } as Service
metaDataService = {
type: "MetaData",
metadata: new MetaData(),
} as Service
}) })
describe("#signServiceAgreement()", () => { describe("#signServiceAgreement()", () => {
@ -69,7 +101,7 @@ describe("ServiceAgreement", () => {
const id: string = IdGenerator.generateId() const id: string = IdGenerator.generateId()
const did: string = `did:op:${id}` const did: string = `did:op:${id}`
const ddo = new DDO({id: did, service: [service]}) const ddo = new DDO({id: did, service: [accessService]})
const assetId: string = IdGenerator.generateId() const assetId: string = IdGenerator.generateId()
const serviceAgreementId: string = IdGenerator.generateId() const serviceAgreementId: string = IdGenerator.generateId()
@ -77,7 +109,7 @@ describe("ServiceAgreement", () => {
WebServiceConnectorProvider.setConnector(new WebServiceConnectorMock(ddo)) WebServiceConnectorProvider.setConnector(new WebServiceConnectorMock(ddo))
const serviceAgreementSignature: string = const serviceAgreementSignature: string =
await ServiceAgreement.signServiceAgreement(assetId, ddo, service.serviceDefinitionId, await ServiceAgreement.signServiceAgreement(assetId, ddo, accessService.serviceDefinitionId,
serviceAgreementId, consumerAccount) serviceAgreementId, consumerAccount)
assert(serviceAgreementSignature) assert(serviceAgreementSignature)
@ -90,18 +122,18 @@ describe("ServiceAgreement", () => {
const id: string = IdGenerator.generateId() const id: string = IdGenerator.generateId()
const did: string = `did:op:${id}` const did: string = `did:op:${id}`
const ddo = new DDO({id: did, service: [service]}) const ddo = new DDO({id: did, service: [accessService]})
const assetId: string = IdGenerator.generateId() const assetId: string = IdGenerator.generateId()
const serviceAgreementId: string = IdGenerator.generateId() const serviceAgreementId: string = IdGenerator.generateId()
// @ts-ignore // @ts-ignore
WebServiceConnectorProvider.setConnector(new WebServiceConnectorMock(ddo)) WebServiceConnectorProvider.setConnector(new WebServiceConnectorMock(ddo))
const serviceAgreementSignature: string = const serviceAgreementSignature: string =
await ServiceAgreement.signServiceAgreement(assetId, ddo, service.serviceDefinitionId, await ServiceAgreement.signServiceAgreement(assetId, ddo, accessService.serviceDefinitionId,
serviceAgreementId, consumerAccount) serviceAgreementId, consumerAccount)
const serviceAgreement: ServiceAgreement = const serviceAgreement: ServiceAgreement =
await ServiceAgreement.executeServiceAgreement(assetId, ddo, service.serviceDefinitionId, await ServiceAgreement.executeServiceAgreement(assetId, ddo, accessService.serviceDefinitionId,
serviceAgreementId, serviceAgreementSignature, consumerAccount, publisherAccount) serviceAgreementId, serviceAgreementSignature, consumerAccount, publisherAccount)
assert(serviceAgreement) assert(serviceAgreement)
@ -116,19 +148,19 @@ describe("ServiceAgreement", () => {
const id: string = IdGenerator.generateId() const id: string = IdGenerator.generateId()
const did: string = `did:op:${id}` const did: string = `did:op:${id}`
const ddo = new DDO({id: did, service: [service]}) const ddo = new DDO({id: did, service: [accessService]})
const assetId: string = IdGenerator.generateId() const assetId: string = IdGenerator.generateId()
const serviceAgreementId: string = IdGenerator.generateId() const serviceAgreementId: string = IdGenerator.generateId()
// @ts-ignore // @ts-ignore
WebServiceConnectorProvider.setConnector(new WebServiceConnectorMock(ddo)) WebServiceConnectorProvider.setConnector(new WebServiceConnectorMock(ddo))
const serviceAgreementSignature: string = const serviceAgreementSignature: string =
await ServiceAgreement.signServiceAgreement(assetId, ddo, service.serviceDefinitionId, await ServiceAgreement.signServiceAgreement(assetId, ddo, accessService.serviceDefinitionId,
serviceAgreementId, consumerAccount) serviceAgreementId, consumerAccount)
assert(serviceAgreementSignature) assert(serviceAgreementSignature)
const serviceAgreement: ServiceAgreement = const serviceAgreement: ServiceAgreement =
await ServiceAgreement.executeServiceAgreement(assetId, ddo, service.serviceDefinitionId, await ServiceAgreement.executeServiceAgreement(assetId, ddo, accessService.serviceDefinitionId,
serviceAgreementId, serviceAgreementSignature, consumerAccount, publisherAccount) serviceAgreementId, serviceAgreementSignature, consumerAccount, publisherAccount)
assert(serviceAgreement) assert(serviceAgreement)
@ -137,29 +169,59 @@ describe("ServiceAgreement", () => {
}) })
}) })
describe("#grantAccess()", () => { describe("#lockPayment()", () => {
it("should grant access in that service agreement", async () => { xit("should lock the payment in that service agreement", async () => {
const id: string = IdGenerator.generateId() const id: string = IdGenerator.generateId()
const did: string = `did:op:${id}` const did: string = `did:op:${id}`
const ddo = new DDO({id: did, service: [service]}) const ddo = new DDO({id: did, service: [accessService, metaDataService]})
const assetId: string = IdGenerator.generateId() const assetId: string = IdGenerator.generateId()
const serviceAgreementId: string = IdGenerator.generateId() const serviceAgreementId: string = IdGenerator.generateId()
// @ts-ignore // @ts-ignore
WebServiceConnectorProvider.setConnector(new WebServiceConnectorMock(ddo)) WebServiceConnectorProvider.setConnector(new WebServiceConnectorMock(ddo))
const serviceAgreementSignature: string = const serviceAgreementSignature: string =
await ServiceAgreement.signServiceAgreement(assetId, ddo, service.serviceDefinitionId, await ServiceAgreement.signServiceAgreement(assetId, ddo, accessService.serviceDefinitionId,
serviceAgreementId, consumerAccount) serviceAgreementId, consumerAccount)
assert(serviceAgreementSignature) assert(serviceAgreementSignature)
const serviceAgreement: ServiceAgreement = const serviceAgreement: ServiceAgreement =
await ServiceAgreement.executeServiceAgreement(assetId, ddo, service.serviceDefinitionId, await ServiceAgreement.executeServiceAgreement(assetId, ddo, accessService.serviceDefinitionId,
serviceAgreementId, serviceAgreementSignature, consumerAccount, publisherAccount) serviceAgreementId, serviceAgreementSignature, consumerAccount, publisherAccount)
assert(serviceAgreement) assert(serviceAgreement)
const fulfilled: boolean = await serviceAgreement.grantAccess(assetId, IdGenerator.generateId()) const paid: boolean = await serviceAgreement.lockPayment(assetId, metaDataService.metadata.base.price,
assert(fulfilled) consumerAccount)
assert(paid)
})
})
describe("#grantAccess()", () => {
xit("should grant access in that service agreement", async () => {
const id: string = IdGenerator.generateId()
const did: string = `did:op:${id}`
const ddo = new DDO({id: did, service: [accessService]})
const assetId: string = IdGenerator.generateId()
const serviceAgreementId: string = IdGenerator.generateId()
// @ts-ignore
WebServiceConnectorProvider.setConnector(new WebServiceConnectorMock(ddo))
const serviceAgreementSignature: string =
await ServiceAgreement.signServiceAgreement(assetId, ddo, accessService.serviceDefinitionId,
serviceAgreementId, consumerAccount)
assert(serviceAgreementSignature)
const serviceAgreement: ServiceAgreement =
await ServiceAgreement.executeServiceAgreement(assetId, ddo, accessService.serviceDefinitionId,
serviceAgreementId, serviceAgreementSignature, consumerAccount, publisherAccount)
assert(serviceAgreement)
const paid: boolean = await serviceAgreement.lockPayment(assetId, 10, consumerAccount)
assert(paid)
const accessGranted: boolean = await serviceAgreement.grantAccess(assetId, IdGenerator.generateId())
assert(accessGranted)
}) })
}) })
}) })

View File

@ -39,6 +39,20 @@ describe("ServiceAgreementTemplate", () => {
}) })
}) })
describe("#getConditions()", () => {
it("should setup an Access agreement template correctly", async () => {
const access: TemplateBase = new Access()
access.id = IdGenerator.generatePrefixedId()
const serviceAgreementTemplate: ServiceAgreementTemplate =
new ServiceAgreementTemplate(access)
assert(serviceAgreementTemplate)
const conds = await serviceAgreementTemplate.getConditions()
assert(conds)
})
})
describe("#getStatus()", () => { describe("#getStatus()", () => {
it("should get the status of a newly deployed agreement template", async () => { it("should get the status of a newly deployed agreement template", async () => {