mirror of
https://github.com/oceanprotocol-archive/squid-js.git
synced 2024-02-02 15:31:51 +01:00
first steps towards service agreements implementation
This commit is contained in:
parent
bf824caa17
commit
cf86f5af0d
6
package-lock.json
generated
6
package-lock.json
generated
@ -120,9 +120,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"@oceanprotocol/keeper-contracts": {
|
"@oceanprotocol/keeper-contracts": {
|
||||||
"version": "0.4.1",
|
"version": "0.3.7",
|
||||||
"resolved": "https://registry.npmjs.org/@oceanprotocol/keeper-contracts/-/keeper-contracts-0.4.1.tgz",
|
"resolved": "https://registry.npmjs.org/@oceanprotocol/keeper-contracts/-/keeper-contracts-0.3.7.tgz",
|
||||||
"integrity": "sha512-UmgPsJul9ZJb5BPIa1qfMpokJWzdROni/wisd4Dnm+wwHUA7/ymsr34zVn+4v+uAcMLHAYPKbsROBT5xlbiKAQ=="
|
"integrity": "sha512-Yx+ucPIjLsn/Rvs0G8sPpjKWmmUQv5x9YBdO6pHutSGO82PkVBCydV4mB5Wx3Pqr3KmW0S34ve07KmUN3qtc7A=="
|
||||||
},
|
},
|
||||||
"@oceanprotocol/secret-store-client": {
|
"@oceanprotocol/secret-store-client": {
|
||||||
"version": "0.0.7",
|
"version": "0.0.7",
|
||||||
|
@ -49,7 +49,7 @@
|
|||||||
"node": ">=8 <10"
|
"node": ">=8 <10"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@oceanprotocol/keeper-contracts": "^0.4.1",
|
"@oceanprotocol/keeper-contracts": "^0.3.7",
|
||||||
"@oceanprotocol/secret-store-client": "^0.0.7",
|
"@oceanprotocol/secret-store-client": "^0.0.7",
|
||||||
"bignumber.js": "^7.2.1",
|
"bignumber.js": "^7.2.1",
|
||||||
"eth-crypto": "^1.2.4",
|
"eth-crypto": "^1.2.4",
|
||||||
|
@ -3,14 +3,12 @@ import Logger from "../utils/Logger"
|
|||||||
import Keeper from "./Keeper"
|
import Keeper from "./Keeper"
|
||||||
import Web3Provider from "./Web3Provider"
|
import Web3Provider from "./Web3Provider"
|
||||||
|
|
||||||
const contracts: Map<string, Contract> = new Map<string, Contract>()
|
|
||||||
|
|
||||||
export default class ContractHandler {
|
export default class ContractHandler {
|
||||||
|
|
||||||
public static async get(what: string): Contract {
|
public static async get(what: string): Contract {
|
||||||
const where = (await (await Keeper.getInstance()).getNetworkName()).toLowerCase()
|
const where = (await (await Keeper.getInstance()).getNetworkName()).toLowerCase()
|
||||||
try {
|
try {
|
||||||
return contracts.get(what) || await ContractHandler.load(what, where)
|
return ContractHandler.contracts.get(what) || await ContractHandler.load(what, where)
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
Logger.error("Failed to load", what, "from", where, err)
|
Logger.error("Failed to load", what, "from", where, err)
|
||||||
throw err
|
throw err
|
||||||
@ -53,8 +51,8 @@ export default class ContractHandler {
|
|||||||
|
|
||||||
const sa = await ContractHandler.deployContract("ServiceAgreement", deployerAddress, {
|
const sa = await ContractHandler.deployContract("ServiceAgreement", deployerAddress, {
|
||||||
args: [],
|
args: [],
|
||||||
|
|
||||||
})
|
})
|
||||||
|
|
||||||
await ContractHandler.deployContract("AccessConditions", deployerAddress, {
|
await ContractHandler.deployContract("AccessConditions", deployerAddress, {
|
||||||
args: [sa.options.address],
|
args: [sa.options.address],
|
||||||
})
|
})
|
||||||
@ -74,6 +72,8 @@ export default class ContractHandler {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static contracts: Map<string, Contract> = new Map<string, Contract>()
|
||||||
|
|
||||||
private static async load(what: string, where: string): Promise<Contract> {
|
private static async load(what: string, where: string): Promise<Contract> {
|
||||||
const web3 = Web3Provider.getWeb3()
|
const web3 = Web3Provider.getWeb3()
|
||||||
// Logger.log("Loading", what, "from", where)
|
// Logger.log("Loading", what, "from", where)
|
||||||
@ -87,8 +87,8 @@ export default class ContractHandler {
|
|||||||
// Logger.log("Getting instance of", what, "from", where, "at", artifact.address)
|
// Logger.log("Getting instance of", what, "from", where, "at", artifact.address)
|
||||||
const contract = new web3.eth.Contract(artifact.abi, artifact.address)
|
const contract = new web3.eth.Contract(artifact.abi, artifact.address)
|
||||||
Logger.log("Loaded", what, "from", where)
|
Logger.log("Loaded", what, "from", where)
|
||||||
contracts.set(what, contract)
|
ContractHandler.contracts.set(what, contract)
|
||||||
return contracts.get(what)
|
return ContractHandler.contracts.get(what)
|
||||||
}
|
}
|
||||||
|
|
||||||
// todo: reactivate for tethys
|
// todo: reactivate for tethys
|
||||||
@ -108,8 +108,8 @@ export default class ContractHandler {
|
|||||||
private static async deployContract(name: string, from: string, params?): Promise<Contract> {
|
private static async deployContract(name: string, from: string, params?): Promise<Contract> {
|
||||||
|
|
||||||
// dont redeploy if there is already something loaded
|
// dont redeploy if there is already something loaded
|
||||||
if (contracts.has(name)) {
|
if (ContractHandler.contracts.has(name)) {
|
||||||
return contracts.get(name)
|
return ContractHandler.contracts.get(name)
|
||||||
}
|
}
|
||||||
|
|
||||||
const web3 = Web3Provider.getWeb3()
|
const web3 = Web3Provider.getWeb3()
|
||||||
@ -130,7 +130,7 @@ export default class ContractHandler {
|
|||||||
gas: 3000000,
|
gas: 3000000,
|
||||||
gasPrice: 10000000000,
|
gasPrice: 10000000000,
|
||||||
})
|
})
|
||||||
contracts.set(name, contractInstance)
|
ContractHandler.contracts.set(name, contractInstance)
|
||||||
// Logger.log("Deployed", name, "at", contractInstance.options.address);
|
// Logger.log("Deployed", name, "at", contractInstance.options.address);
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
Logger.error("Deployment failed for", name, "with params", JSON.stringify(params, null, 2), err.message)
|
Logger.error("Deployment failed for", name, "with params", JSON.stringify(params, null, 2), err.message)
|
||||||
|
17
src/keeper/ContractReflector.ts
Normal file
17
src/keeper/ContractReflector.ts
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
import MethodReflection from "../models/MethodReflection"
|
||||||
|
import GenericContract from "./contracts/GenericContract"
|
||||||
|
|
||||||
|
export default class ContractReflector {
|
||||||
|
|
||||||
|
public static async reflectContractMethod(pathToMethod: string): Promise<MethodReflection> {
|
||||||
|
const parts: string[] = pathToMethod.split(".")
|
||||||
|
|
||||||
|
const contract = await GenericContract.getInstance(parts[0])
|
||||||
|
return {
|
||||||
|
contractName: parts[0],
|
||||||
|
methodName: parts[1],
|
||||||
|
address: contract.getAddress(),
|
||||||
|
signature: contract.getSignatureOfMethod(parts[1]),
|
||||||
|
} as MethodReflection
|
||||||
|
}
|
||||||
|
}
|
14
src/keeper/contracts/GenericContract.ts
Normal file
14
src/keeper/contracts/GenericContract.ts
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
import ContractBase from "./ContractBase"
|
||||||
|
|
||||||
|
export default class GenericContract extends ContractBase {
|
||||||
|
|
||||||
|
public static async getInstance(contractName: string) {
|
||||||
|
const contract: GenericContract = new GenericContract(contractName)
|
||||||
|
await contract.init()
|
||||||
|
return contract
|
||||||
|
}
|
||||||
|
|
||||||
|
private constructor(contractName: string) {
|
||||||
|
super(contractName)
|
||||||
|
}
|
||||||
|
}
|
@ -1,4 +1,5 @@
|
|||||||
import {Receipt} from "web3-utils"
|
import {Receipt} from "web3-utils"
|
||||||
|
import MethodReflection from "../../models/MethodReflection"
|
||||||
import ContractBase from "./ContractBase"
|
import ContractBase from "./ContractBase"
|
||||||
|
|
||||||
export default class ServiceAgreement extends ContractBase {
|
export default class ServiceAgreement extends ContractBase {
|
||||||
@ -9,25 +10,32 @@ export default class ServiceAgreement extends ContractBase {
|
|||||||
return serviceAgreement
|
return serviceAgreement
|
||||||
}
|
}
|
||||||
|
|
||||||
public async setupAgreementTemplate(contractAddresses: any[], contractFunctionSignatures: string[],
|
public async setupAgreementTemplate(methodReflections: MethodReflection[], dependencyMatrix: number[], name: any,
|
||||||
depencyMatrix: number[], name: any, ownerAddress: string): Promise<Receipt> {
|
ownerAddress: string): Promise<Receipt> {
|
||||||
|
|
||||||
return this.send("setupAgreementTemplate", ownerAddress, [
|
return this.send("setupAgreementTemplate", ownerAddress, [
|
||||||
contractAddresses, contractFunctionSignatures, depencyMatrix, name,
|
methodReflections.map((r) => r.address), methodReflections.map((r) => r.signature),
|
||||||
|
dependencyMatrix, name,
|
||||||
])
|
])
|
||||||
}
|
}
|
||||||
|
|
||||||
public async getAgreementStatus(agreementId: string) {
|
public async getTemplateStatus(templateId: string) {
|
||||||
|
|
||||||
return this.call("getAgreementStatus", [agreementId])
|
return this.call("getTemplateStatus", [templateId])
|
||||||
}
|
}
|
||||||
|
|
||||||
public async executeAgreement(templateId: string, signature: string, consumerAddress: string, valueHashes: string[],
|
public async getAgreementStatus(serviceAgreementId: string) {
|
||||||
timeoutValues: number[], serviceDefinitionId: string, did: string,
|
|
||||||
publisherAddress: string): Promise<Receipt> {
|
return this.call("getAgreementStatus", ["0x" + serviceAgreementId])
|
||||||
|
}
|
||||||
|
|
||||||
|
public async executeAgreement(serviceAgreementTemplateId: string, serviceAgreementSignatureHash: string,
|
||||||
|
consumerAddress: string, valueHashes: string[], timeoutValues: number[],
|
||||||
|
serviceAgreementId: string, did: string, publisherAddress: string): Promise<Receipt> {
|
||||||
|
|
||||||
return this.send("executeAgreement", publisherAddress, [
|
return this.send("executeAgreement", publisherAddress, [
|
||||||
templateId, signature, consumerAddress, valueHashes, timeoutValues, serviceDefinitionId, "0x" + did,
|
serviceAgreementTemplateId, serviceAgreementSignatureHash, consumerAddress, valueHashes,
|
||||||
|
timeoutValues, "0x" + serviceAgreementId, "0x" + did,
|
||||||
])
|
])
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
import {Receipt} from "web3-utils"
|
||||||
import ContractBase from "../ContractBase"
|
import ContractBase from "../ContractBase"
|
||||||
|
|
||||||
export default class AccessConditions extends ContractBase {
|
export default class AccessConditions extends ContractBase {
|
||||||
@ -7,4 +8,11 @@ export default class AccessConditions extends ContractBase {
|
|||||||
await accessConditions.init()
|
await accessConditions.init()
|
||||||
return accessConditions
|
return accessConditions
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public async grantAccess(serviceAgreementId: any, assetId: any, documentKeyId: any, publisherAddress: string)
|
||||||
|
: Promise<Receipt> {
|
||||||
|
return this.send("grantAccess", publisherAddress, [
|
||||||
|
"0x" + serviceAgreementId, "0x" + assetId, "0x" + documentKeyId,
|
||||||
|
])
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
6
src/models/MethodReflection.ts
Normal file
6
src/models/MethodReflection.ts
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
export default class MethodReflection {
|
||||||
|
public contractName: string
|
||||||
|
public methodName: string
|
||||||
|
public address: string
|
||||||
|
public signature: string
|
||||||
|
}
|
@ -1,73 +1,88 @@
|
|||||||
|
import AccessConditions from "../keeper/contracts/conditions/AccessConditions"
|
||||||
import ServiceAgreementContract from "../keeper/contracts/ServiceAgreement"
|
import ServiceAgreementContract from "../keeper/contracts/ServiceAgreement"
|
||||||
import Web3Provider from "../keeper/Web3Provider"
|
import Web3Provider from "../keeper/Web3Provider"
|
||||||
import Account from "./Account"
|
import Account from "./Account"
|
||||||
|
import IdGenerator from "./IdGenerator"
|
||||||
import OceanBase from "./OceanBase"
|
import OceanBase from "./OceanBase"
|
||||||
import ServiceAgreementTemplate from "./ServiceAgreementTemplate"
|
import ServiceAgreementTemplate from "./ServiceAgreementTemplate"
|
||||||
|
|
||||||
export default class ServiceAgreement extends OceanBase {
|
export default class ServiceAgreement extends OceanBase {
|
||||||
|
|
||||||
public static async executeServiceAgreement(serviceAgreementTemplate: ServiceAgreementTemplate,
|
public static async signServiceAgreement(serviceAgreementTemplate: ServiceAgreementTemplate, publisher: Account,
|
||||||
did: string, consumer: Account): Promise<ServiceAgreement> {
|
did: string, assetId: string, consumer: Account):
|
||||||
|
Promise<ServiceAgreement> {
|
||||||
|
|
||||||
const valHashList = [
|
const serviceAgreementId = IdGenerator.generateId()
|
||||||
ServiceAgreement.valueHash("bool", true),
|
|
||||||
ServiceAgreement.valueHash("bool", false),
|
const valueHashes = [
|
||||||
ServiceAgreement.valueHash("uint", 120),
|
ServiceAgreement.hashSingleValue("bool", true),
|
||||||
// asset Id: 797FD5B9045B841FDFF72
|
ServiceAgreement.hashSingleValue("bool", false),
|
||||||
ServiceAgreement.valueHash("string", "797FD5B9045B841FDFF72"),
|
ServiceAgreement.hashSingleValue("uint", 120),
|
||||||
|
// assetId
|
||||||
|
ServiceAgreement.hashSingleValue("string", assetId),
|
||||||
]
|
]
|
||||||
|
|
||||||
const serviceDefinitionId = "0x515f158c3a5d81d15b0160cf8929916089218bdb4aa78c3ecd16633afd44b894"
|
const timeoutValues = [0, 0, 0, 500] // timeout 500 blocks @ condition 4
|
||||||
|
|
||||||
const timeoutValues = [0, 0, 0, 3] // timeout 5 blocks @ condition 4
|
const serviceAgreementHash = ServiceAgreement.hashServiceAgreement(serviceAgreementTemplate, valueHashes,
|
||||||
|
timeoutValues, serviceAgreementId)
|
||||||
const saMerkleRoot = ServiceAgreement.merkelizeServiceAgreement(serviceAgreementTemplate, valHashList,
|
const serviceAgreementHashSignature =
|
||||||
timeoutValues, serviceDefinitionId, did)
|
await Web3Provider.getWeb3().eth.sign(serviceAgreementHash, consumer.getId())
|
||||||
const saMerkleRootSignature = await Web3Provider.getWeb3().eth.sign(saMerkleRoot, consumer.getId())
|
|
||||||
|
|
||||||
const serviceAgreement: ServiceAgreementContract = await ServiceAgreementContract.getInstance()
|
const serviceAgreement: ServiceAgreementContract = await ServiceAgreementContract.getInstance()
|
||||||
|
|
||||||
const receipt = await serviceAgreement.executeAgreement(
|
const executeAgreementReceipt = await serviceAgreement.executeAgreement(
|
||||||
serviceAgreementTemplate.getId(), saMerkleRootSignature, consumer.getId(), valHashList, timeoutValues,
|
serviceAgreementTemplate.getId(), serviceAgreementHashSignature, consumer.getId(), valueHashes,
|
||||||
serviceDefinitionId, did, serviceAgreementTemplate.getPublisher().getId())
|
timeoutValues, serviceAgreementId, did, publisher.getId())
|
||||||
|
|
||||||
|
if (executeAgreementReceipt.events.ExecuteAgreement.returnValues.state === false) {
|
||||||
|
throw new Error("signing service agreement failed.")
|
||||||
|
}
|
||||||
|
|
||||||
const id = receipt.events.ExecuteAgreement.returnValues.serviceId
|
|
||||||
return new ServiceAgreement(
|
return new ServiceAgreement(
|
||||||
id,
|
serviceAgreementId,
|
||||||
receipt.events.ExecuteAgreement.returnValues.templateId,
|
publisher,
|
||||||
receipt.events.ExecuteAgreement.returnValues.templateOwner,
|
serviceAgreementTemplate,
|
||||||
receipt.events.ExecuteAgreement.returnValues.consumer,
|
consumer,
|
||||||
receipt.events.ExecuteAgreement.returnValues.state,
|
executeAgreementReceipt.events.ExecuteAgreement.returnValues.state,
|
||||||
receipt.events.ExecuteAgreement.returnValues.status,
|
executeAgreementReceipt.events.ExecuteAgreement.returnValues.status,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
protected static valueHash(type: string, value: any) {
|
protected static hashSingleValue(type: string, value: any): string {
|
||||||
const args = {type, value}
|
const args = {type, value}
|
||||||
return Web3Provider.getWeb3().utils.soliditySha3(args).toString("hex")
|
return Web3Provider.getWeb3().utils.soliditySha3(args).toString("hex")
|
||||||
}
|
}
|
||||||
|
|
||||||
private static merkelizeServiceAgreement(serviceAgreementTemplate: ServiceAgreementTemplate, valueHashes: string[],
|
private static hashServiceAgreement(serviceAgreementTemplate: ServiceAgreementTemplate, valueHashes: string[],
|
||||||
timeouts: number[], serviceDefinitionId: string, did: string) {
|
timeouts: number[], serviceAgreementId: string) {
|
||||||
const args = [
|
const args = [
|
||||||
{type: "bytes32", value: serviceAgreementTemplate.getId()},
|
{type: "bytes32", value: serviceAgreementTemplate.getId()},
|
||||||
{type: "bytes32[]", value: serviceAgreementTemplate.getConditionKeys()},
|
{type: "bytes32[]", value: serviceAgreementTemplate.getConditionKeys()},
|
||||||
{type: "bytes32[]", value: valueHashes},
|
{type: "bytes32[]", value: valueHashes},
|
||||||
{type: "uint256[]", value: timeouts},
|
{type: "uint256[]", value: timeouts},
|
||||||
{type: "bytes32", value: serviceDefinitionId},
|
{type: "bytes32", value: "0x" + serviceAgreementId},
|
||||||
{type: "bytes32", value: did},
|
|
||||||
]
|
]
|
||||||
|
|
||||||
return Web3Provider.getWeb3().utils.soliditySha3(...args).toString("hex")
|
return Web3Provider.getWeb3().utils.soliditySha3(...args).toString("hex")
|
||||||
}
|
}
|
||||||
|
|
||||||
private constructor(id: string, templateId: string, templateOwnerId: string,
|
private constructor(id: string, private publisher: Account, serviceAgreementTemplate: ServiceAgreementTemplate,
|
||||||
consumerId: string, state: boolean, status: boolean) {
|
consumer: Account, state: boolean, status: boolean) {
|
||||||
super(id)
|
super(id)
|
||||||
}
|
}
|
||||||
|
|
||||||
public async getStatus() {
|
public async grantAccess(assetId: string, documentId: string): Promise<boolean> {
|
||||||
const sa = await ServiceAgreementContract.getInstance()
|
const accessConditions: AccessConditions = await AccessConditions.getInstance()
|
||||||
|
|
||||||
return sa.getAgreementStatus(this.getId())
|
const grantAccessReceipt =
|
||||||
|
await accessConditions.grantAccess(this.getId(), assetId, documentId, this.publisher.getId())
|
||||||
|
|
||||||
|
return grantAccessReceipt.status
|
||||||
|
}
|
||||||
|
|
||||||
|
public async getStatus() {
|
||||||
|
const serviceAgreement = await ServiceAgreementContract.getInstance()
|
||||||
|
return serviceAgreement.getAgreementStatus(this.getId())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,65 +1,70 @@
|
|||||||
import AccessConditions from "../keeper/contracts/conditions/AccessConditions"
|
import ContractReflector from "../keeper/ContractReflector"
|
||||||
import PaymentConditions from "../keeper/contracts/conditions/PaymentConditions"
|
|
||||||
import ServiceAgreement from "../keeper/contracts/ServiceAgreement"
|
import ServiceAgreement from "../keeper/contracts/ServiceAgreement"
|
||||||
import Web3Provider from "../keeper/Web3Provider"
|
import Web3Provider from "../keeper/Web3Provider"
|
||||||
|
import MethodReflection from "../models/MethodReflection"
|
||||||
import Account from "./Account"
|
import Account from "./Account"
|
||||||
import OceanBase from "./OceanBase"
|
import OceanBase from "./OceanBase"
|
||||||
|
|
||||||
export default class ServiceAgreementTemplate extends OceanBase {
|
export default class ServiceAgreementTemplate extends OceanBase {
|
||||||
|
|
||||||
public static async registerServiceAgreementsTemplate(resourceName: string, publisher: Account):
|
public static async registerServiceAgreementsTemplate(serviceName: string, templateOwner: Account):
|
||||||
Promise<ServiceAgreementTemplate> {
|
Promise<ServiceAgreementTemplate> {
|
||||||
|
|
||||||
const paymentConditions: PaymentConditions = await PaymentConditions.getInstance()
|
const methodReflections: MethodReflection[] = [
|
||||||
const accessConditions: AccessConditions = await AccessConditions.getInstance()
|
await ContractReflector.reflectContractMethod("PaymentConditions.lockPayment"),
|
||||||
|
await ContractReflector.reflectContractMethod("AccessConditions.grantAccess"),
|
||||||
const contractAddresses = [
|
await ContractReflector.reflectContractMethod("PaymentConditions.releasePayment"),
|
||||||
await paymentConditions.getAddress(),
|
await ContractReflector.reflectContractMethod("PaymentConditions.refundPayment"),
|
||||||
await accessConditions.getAddress(),
|
|
||||||
await paymentConditions.getAddress(),
|
|
||||||
await paymentConditions.getAddress(),
|
|
||||||
]
|
|
||||||
const functionSignatures = [
|
|
||||||
await paymentConditions.getSignatureOfMethod("lockPayment"),
|
|
||||||
await accessConditions.getSignatureOfMethod("grantAccess"),
|
|
||||||
await paymentConditions.getSignatureOfMethod("releasePayment"),
|
|
||||||
await paymentConditions.getSignatureOfMethod("refundPayment"),
|
|
||||||
]
|
]
|
||||||
|
|
||||||
// tslint:disable
|
// tslint:disable
|
||||||
const dependencies = [0, 1, 4, 1 | 2 ** 4 | 2 ** 5] // dependency bit | timeout bit
|
const dependencyMatrix = [0, 1, 4, 1 | 2 ** 4 | 2 ** 5] // dependency bit | timeout bit
|
||||||
|
|
||||||
const serviceAgreement: ServiceAgreement = await ServiceAgreement.getInstance()
|
const serviceAgreement: ServiceAgreement = await ServiceAgreement.getInstance()
|
||||||
|
|
||||||
const receipt = await serviceAgreement.setupAgreementTemplate(
|
const receipt = await serviceAgreement.setupAgreementTemplate(
|
||||||
contractAddresses, functionSignatures, dependencies,
|
methodReflections, dependencyMatrix,
|
||||||
Web3Provider.getWeb3().utils.fromAscii(resourceName), publisher.getId())
|
Web3Provider.getWeb3().utils.fromAscii(serviceName),
|
||||||
|
templateOwner.getId())
|
||||||
|
|
||||||
const id = receipt.events.SetupAgreementTemplate.returnValues.serviceTemplateId
|
const id = receipt.events.SetupAgreementTemplate.returnValues.serviceTemplateId
|
||||||
|
|
||||||
return new ServiceAgreementTemplate(
|
return new ServiceAgreementTemplate(
|
||||||
id,
|
id,
|
||||||
ServiceAgreementTemplate.generateConditionsKeys(id, contractAddresses, functionSignatures),
|
ServiceAgreementTemplate.generateConditionsKeys(id, methodReflections),
|
||||||
publisher)
|
templateOwner)
|
||||||
}
|
}
|
||||||
|
|
||||||
private static generateConditionsKeys(serviceAgreementTemplateId: string, contractAddresses: string[],
|
/**
|
||||||
functionSignatures: string[]): string[] {
|
* gets the status of a service agreement template
|
||||||
|
*/
|
||||||
|
public async getStatus(): Promise<boolean> {
|
||||||
|
|
||||||
|
const serviceAgreement: ServiceAgreement = await ServiceAgreement.getInstance()
|
||||||
|
|
||||||
|
return serviceAgreement.getTemplateStatus(this.getId())
|
||||||
|
}
|
||||||
|
|
||||||
|
private static generateConditionsKeys(serviceAgreementTemplateId: string, methodReflections: MethodReflection[]):
|
||||||
|
string[] {
|
||||||
const conditions = []
|
const conditions = []
|
||||||
for (let i = 0; i < contractAddresses.length; i++) {
|
for (let i = 0; i < methodReflections.length; i++) {
|
||||||
const types = ["bytes32", "address", "bytes4"]
|
const values = [
|
||||||
const values = [serviceAgreementTemplateId, contractAddresses[i], functionSignatures[i]]
|
{type: "bytes32", value: serviceAgreementTemplateId},
|
||||||
conditions.push(Web3Provider.getWeb3().utils.soliditySha3(...types, ...values).toString("hex"))
|
{type: "address", value: methodReflections[i].address},
|
||||||
|
{type: "bytes4", value: methodReflections[i].signature},
|
||||||
|
]
|
||||||
|
conditions.push(Web3Provider.getWeb3().utils.soliditySha3(...values).toString("hex"))
|
||||||
}
|
}
|
||||||
return conditions
|
return conditions
|
||||||
}
|
}
|
||||||
|
|
||||||
private constructor(id, private conditionKeys: string[], private publisher: Account) {
|
private constructor(id, private conditionKeys: string[], private owner: Account) {
|
||||||
super(id)
|
super(id)
|
||||||
}
|
}
|
||||||
|
|
||||||
public getPublisher(): Account {
|
public getOwner(): Account {
|
||||||
return this.publisher
|
return this.owner
|
||||||
}
|
}
|
||||||
|
|
||||||
public getConditionKeys(): string[] {
|
public getConditionKeys(): string[] {
|
||||||
|
@ -6,11 +6,14 @@ import IdGenerator from "../../src/ocean/IdGenerator"
|
|||||||
import Ocean from "../../src/ocean/Ocean"
|
import Ocean from "../../src/ocean/Ocean"
|
||||||
import ServiceAgreement from "../../src/ocean/ServiceAgreement"
|
import ServiceAgreement from "../../src/ocean/ServiceAgreement"
|
||||||
import ServiceAgreementTemplate from "../../src/ocean/ServiceAgreementTemplate"
|
import ServiceAgreementTemplate from "../../src/ocean/ServiceAgreementTemplate"
|
||||||
import Logger from "../../src/utils/Logger"
|
|
||||||
import config from "../config"
|
import config from "../config"
|
||||||
|
|
||||||
let ocean: Ocean
|
let ocean: Ocean
|
||||||
let accounts: Account[]
|
let accounts: Account[]
|
||||||
|
let publisherAccount: Account
|
||||||
|
let templateOwnerAccount: Account
|
||||||
|
let consumerAccount: Account
|
||||||
|
|
||||||
let testServiceAgreementTemplate: ServiceAgreementTemplate
|
let testServiceAgreementTemplate: ServiceAgreementTemplate
|
||||||
|
|
||||||
describe("ServiceAgreement", () => {
|
describe("ServiceAgreement", () => {
|
||||||
@ -21,36 +24,66 @@ describe("ServiceAgreement", () => {
|
|||||||
ocean = await Ocean.getInstance(config)
|
ocean = await Ocean.getInstance(config)
|
||||||
accounts = await ocean.getAccounts()
|
accounts = await ocean.getAccounts()
|
||||||
|
|
||||||
const publisherAccount = accounts[0]
|
templateOwnerAccount = accounts[0]
|
||||||
|
publisherAccount = accounts[1]
|
||||||
|
consumerAccount = accounts[2]
|
||||||
|
|
||||||
const resourceName = "superb car data"
|
const resourceName = "superb car data"
|
||||||
testServiceAgreementTemplate =
|
testServiceAgreementTemplate =
|
||||||
await ServiceAgreementTemplate.registerServiceAgreementsTemplate(resourceName, publisherAccount)
|
await ServiceAgreementTemplate.registerServiceAgreementsTemplate(resourceName, templateOwnerAccount)
|
||||||
|
|
||||||
})
|
})
|
||||||
|
|
||||||
describe("#executeServiceAgreement()", () => {
|
describe("#executeServiceAgreement()", () => {
|
||||||
it("should execture an service agreement", async () => {
|
it("should execute an service agreement", async () => {
|
||||||
|
|
||||||
const consumerAccount = accounts[0]
|
|
||||||
const did: string = IdGenerator.generateId()
|
const did: string = IdGenerator.generateId()
|
||||||
|
const assetId: string = IdGenerator.generateId()
|
||||||
|
|
||||||
const serviceAgreement: ServiceAgreement =
|
const serviceAgreement: ServiceAgreement =
|
||||||
await ServiceAgreement.executeServiceAgreement(testServiceAgreementTemplate, did, consumerAccount)
|
await ServiceAgreement.signServiceAgreement(testServiceAgreementTemplate, publisherAccount,
|
||||||
|
did, assetId, consumerAccount)
|
||||||
|
|
||||||
assert(serviceAgreement)
|
assert(serviceAgreement)
|
||||||
assert(serviceAgreement.getId().startsWith("0x"))
|
const id = serviceAgreement.getId()
|
||||||
|
assert(id)
|
||||||
|
assert(id !== did)
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
describe("#getStatus()", () => {
|
describe("#getStatus()", () => {
|
||||||
it("should execture an service agreement", async () => {
|
it("should get the status of a newly created service agreement", async () => {
|
||||||
|
|
||||||
const consumerAccount = accounts[0]
|
|
||||||
const did: string = IdGenerator.generateId()
|
const did: string = IdGenerator.generateId()
|
||||||
const serviceAgreement: ServiceAgreement =
|
const assetId: string = IdGenerator.generateId()
|
||||||
await ServiceAgreement.executeServiceAgreement(testServiceAgreementTemplate, did, consumerAccount)
|
|
||||||
|
|
||||||
|
const serviceAgreement: ServiceAgreement =
|
||||||
|
await ServiceAgreement.signServiceAgreement(testServiceAgreementTemplate, publisherAccount,
|
||||||
|
did, assetId, consumerAccount)
|
||||||
|
|
||||||
|
assert(serviceAgreement)
|
||||||
const status = await serviceAgreement.getStatus()
|
const status = await serviceAgreement.getStatus()
|
||||||
Logger.log(status)
|
assert(status === false)
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
describe("#grantAccess()", () => {
|
||||||
|
it("should grant access in that service agreement", async () => {
|
||||||
|
|
||||||
|
const did: string = IdGenerator.generateId()
|
||||||
|
const assetId: string = IdGenerator.generateId()
|
||||||
|
|
||||||
|
const resourceName = "nice service"
|
||||||
|
const serviceAgreementTemplate =
|
||||||
|
await ServiceAgreementTemplate.registerServiceAgreementsTemplate(resourceName, templateOwnerAccount)
|
||||||
|
|
||||||
|
const serviceAgreement: ServiceAgreement =
|
||||||
|
await ServiceAgreement.signServiceAgreement(serviceAgreementTemplate, publisherAccount,
|
||||||
|
did, assetId, consumerAccount)
|
||||||
|
assert(serviceAgreement)
|
||||||
|
|
||||||
|
const fulfilled: boolean = await serviceAgreement.grantAccess(did, IdGenerator.generateId())
|
||||||
|
assert(fulfilled)
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
@ -21,13 +21,26 @@ describe("ServiceAgreementTemplate", () => {
|
|||||||
describe("#registerServiceAgreementsTemplate()", () => {
|
describe("#registerServiceAgreementsTemplate()", () => {
|
||||||
it("should setup an agreement template", async () => {
|
it("should setup an agreement template", async () => {
|
||||||
|
|
||||||
const publisherAccount = accounts[0]
|
const templateOwner = accounts[0]
|
||||||
const resourceName = "test data"
|
const resourceName = "test data"
|
||||||
const serviceAgreementTemplate: ServiceAgreementTemplate =
|
const serviceAgreementTemplate: ServiceAgreementTemplate =
|
||||||
await ServiceAgreementTemplate.registerServiceAgreementsTemplate(resourceName, publisherAccount)
|
await ServiceAgreementTemplate.registerServiceAgreementsTemplate(resourceName, templateOwner)
|
||||||
assert(serviceAgreementTemplate)
|
assert(serviceAgreementTemplate)
|
||||||
assert(serviceAgreementTemplate.getId())
|
assert(serviceAgreementTemplate.getId())
|
||||||
assert(serviceAgreementTemplate.getPublisher().getId() === publisherAccount.getId())
|
assert(serviceAgreementTemplate.getOwner().getId() === templateOwner.getId())
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
describe("#getStatus()", () => {
|
||||||
|
it("should get the status of a newly deployed agreement template", async () => {
|
||||||
|
|
||||||
|
const publisherAccount = accounts[0]
|
||||||
|
const resourceName = "template status"
|
||||||
|
const serviceAgreementTemplate: ServiceAgreementTemplate =
|
||||||
|
await ServiceAgreementTemplate.registerServiceAgreementsTemplate(resourceName, publisherAccount)
|
||||||
|
|
||||||
|
const templateStatus = await serviceAgreementTemplate.getStatus()
|
||||||
|
assert(templateStatus === true)
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user