mirror of
https://github.com/oceanprotocol-archive/squid-js.git
synced 2024-02-02 15:31:51 +01:00
Use condition contracts hash generation to generate the signature.
This commit is contained in:
parent
f8b3d839eb
commit
4f469b2ab5
@ -3,7 +3,7 @@ import { AgreementStoreManager, ConditionStoreManager } from "../managers"
|
|||||||
import { Condition, ConditionState, conditionStateNames } from "../conditions/Condition.abstract"
|
import { Condition, ConditionState, conditionStateNames } from "../conditions/Condition.abstract"
|
||||||
import Keeper from "../../Keeper"
|
import Keeper from "../../Keeper"
|
||||||
import { DDO } from '../../../ddo/DDO'
|
import { DDO } from '../../../ddo/DDO'
|
||||||
import { ServiceAgreementTemplate, ServiceAgreementTemplateCondition } from '../../../ddo/ServiceAgreementTemplate'
|
import { ServiceAgreementTemplate } from '../../../ddo/ServiceAgreementTemplate'
|
||||||
import { zeroX, Logger } from "../../../utils"
|
import { zeroX, Logger } from "../../../utils"
|
||||||
|
|
||||||
export abstract class AgreementTemplate extends ContractBase {
|
export abstract class AgreementTemplate extends ContractBase {
|
||||||
@ -53,9 +53,9 @@ export abstract class AgreementTemplate extends ContractBase {
|
|||||||
.map(address => keeper.getConditionByAddress(address))
|
.map(address => keeper.getConditionByAddress(address))
|
||||||
}
|
}
|
||||||
|
|
||||||
abstract async getServiceAgreementTemplateValuesMap(ddo: DDO, agreementId: string, consumer: string): Promise<{[value: string]: string}>
|
abstract getAgreementIdsFromDDO(agreementId: string, ddo: DDO, from: string): Promise<string[]>
|
||||||
|
|
||||||
abstract getServiceAgreementTemplate(): Promise<ServiceAgreementTemplate>
|
abstract async getServiceAgreementTemplate(): Promise<ServiceAgreementTemplate>
|
||||||
|
|
||||||
public async getServiceAgreementTemplateConditions() {
|
public async getServiceAgreementTemplateConditions() {
|
||||||
const serviceAgreementTemplate = await this.getServiceAgreementTemplate()
|
const serviceAgreementTemplate = await this.getServiceAgreementTemplate()
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
import { AgreementTemplate } from "./AgreementTemplate.abstract"
|
import { AgreementTemplate } from "./AgreementTemplate.abstract"
|
||||||
import { LockRewardCondition, EscrowReward, AccessSecretStoreCondition } from '../conditions'
|
import { LockRewardCondition, EscrowReward, AccessSecretStoreCondition } from '../conditions'
|
||||||
import DIDRegistry from '../DIDRegistry'
|
import DIDRegistry from '../DIDRegistry'
|
||||||
import Keeper from "../../Keeper"
|
|
||||||
import { DDO } from '../../../ddo/DDO'
|
import { DDO } from '../../../ddo/DDO'
|
||||||
import { generateId, zeroX } from '../../../utils'
|
import { generateId, zeroX } from '../../../utils'
|
||||||
|
|
||||||
@ -56,32 +55,15 @@ export class EscrowAccessSecretStoreTemplate extends AgreementTemplate {
|
|||||||
* @return {Promise<string>} Agreement ID.
|
* @return {Promise<string>} Agreement ID.
|
||||||
*/
|
*/
|
||||||
public async createFullAgreement(did: string, amount: number, from?: string): Promise<string> {
|
public async createFullAgreement(did: string, amount: number, from?: string): Promise<string> {
|
||||||
from = await this.getFromAddress(from)
|
|
||||||
|
|
||||||
const didRegistry = await DIDRegistry.getInstance()
|
|
||||||
|
|
||||||
const accessSecretStoreCondition = await AccessSecretStoreCondition.getInstance()
|
|
||||||
const lockRewardCondition = await LockRewardCondition.getInstance()
|
|
||||||
const escrowReward = await EscrowReward.getInstance()
|
|
||||||
|
|
||||||
const agreementId = zeroX(generateId())
|
const agreementId = zeroX(generateId())
|
||||||
const publisher = await didRegistry.getDIDOwner(did)
|
const {accessSecretStoreConditionId, lockRewardConditionId, escrowRewardId} =
|
||||||
|
await this.createFullAgreementData(agreementId, did, amount, from)
|
||||||
|
|
||||||
const conditionIdAccess = await accessSecretStoreCondition.generateIdHash(agreementId, did, from)
|
|
||||||
const conditionIdLock = await lockRewardCondition.generateIdHash(agreementId, await escrowReward.getAddress(), amount)
|
|
||||||
const conditionIdEscrow = await escrowReward.generateIdHash(
|
|
||||||
agreementId,
|
|
||||||
amount,
|
|
||||||
from,
|
|
||||||
publisher,
|
|
||||||
conditionIdLock,
|
|
||||||
conditionIdAccess,
|
|
||||||
)
|
|
||||||
|
|
||||||
await this.createAgreement(
|
await this.createAgreement(
|
||||||
agreementId,
|
agreementId,
|
||||||
did,
|
did,
|
||||||
[conditionIdAccess, conditionIdLock, conditionIdEscrow],
|
[accessSecretStoreConditionId, lockRewardConditionId, escrowRewardId],
|
||||||
[0, 0, 0],
|
[0, 0, 0],
|
||||||
[0, 0, 0],
|
[0, 0, 0],
|
||||||
from,
|
from,
|
||||||
@ -90,31 +72,38 @@ export class EscrowAccessSecretStoreTemplate extends AgreementTemplate {
|
|||||||
return agreementId
|
return agreementId
|
||||||
}
|
}
|
||||||
|
|
||||||
async getServiceAgreementTemplateValuesMap(ddo: DDO, agreementId: string, consumer: string): Promise<{[value: string]: string}> {
|
public async getAgreementIdsFromDDO(agreementId: string, ddo: DDO, from: string) {
|
||||||
const keeper = await Keeper.getInstance()
|
const {accessSecretStoreConditionId, lockRewardConditionId, escrowRewardId} =
|
||||||
const ddoOwner = ddo.proof && ddo.proof.creator
|
await this.createFullAgreementData(agreementId, ddo.shortId(), ddo.findServiceByType("Metadata").metadata.base.price, from)
|
||||||
const amount = ddo.findServiceByType("Metadata").metadata.base.price
|
return [accessSecretStoreConditionId, lockRewardConditionId, escrowRewardId]
|
||||||
|
}
|
||||||
|
|
||||||
let lockCondition
|
private async createFullAgreementData(agreementId: string, did: string, amount: number, from?: string) {
|
||||||
let releaseCondition
|
from = await this.getFromAddress(from)
|
||||||
|
|
||||||
try {
|
const didRegistry = await DIDRegistry.getInstance()
|
||||||
lockCondition = await keeper.conditions.lockRewardCondition.hashValues(ddoOwner, amount)
|
|
||||||
} catch(e) { }
|
|
||||||
|
|
||||||
try {
|
const accessSecretStoreCondition = await AccessSecretStoreCondition.getInstance()
|
||||||
releaseCondition = await keeper.conditions.accessSecretStoreCondition.hashValues(ddo.shortId(), consumer)
|
const lockRewardCondition = await LockRewardCondition.getInstance()
|
||||||
} catch(e) { }
|
const escrowReward = await EscrowReward.getInstance()
|
||||||
|
|
||||||
|
const publisher = await didRegistry.getDIDOwner(did)
|
||||||
|
|
||||||
|
const lockRewardConditionId = await lockRewardCondition.generateIdHash(agreementId, await escrowReward.getAddress(), amount)
|
||||||
|
const accessSecretStoreConditionId = await accessSecretStoreCondition.generateIdHash(agreementId, did, from)
|
||||||
|
const escrowRewardId = await escrowReward.generateIdHash(
|
||||||
|
agreementId,
|
||||||
|
amount,
|
||||||
|
from,
|
||||||
|
publisher,
|
||||||
|
lockRewardConditionId,
|
||||||
|
accessSecretStoreConditionId,
|
||||||
|
)
|
||||||
|
|
||||||
return {
|
return {
|
||||||
rewardAddress: ddoOwner,
|
lockRewardConditionId,
|
||||||
amount: amount.toString(),
|
accessSecretStoreConditionId,
|
||||||
documentId: ddo.shortId(),
|
escrowRewardId,
|
||||||
grantee: consumer,
|
|
||||||
receiver: consumer,
|
|
||||||
sender: ddoOwner,
|
|
||||||
lockCondition,
|
|
||||||
releaseCondition,
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -10,7 +10,7 @@ import { zeroX, didPrefixed } from "../utils"
|
|||||||
|
|
||||||
import OceanAgreementsConditions from "./OceanAgreementsConditions"
|
import OceanAgreementsConditions from "./OceanAgreementsConditions"
|
||||||
|
|
||||||
export interface AgreementPreparionResult {
|
export interface AgreementPrepareResult {
|
||||||
agreementId: string
|
agreementId: string
|
||||||
signature: string
|
signature: string
|
||||||
}
|
}
|
||||||
@ -50,25 +50,30 @@ export default class OceanAgreements {
|
|||||||
* @param {string} did Decentralized ID.
|
* @param {string} did Decentralized ID.
|
||||||
* @param {string} serviceDefinitionId Service definition ID.
|
* @param {string} serviceDefinitionId Service definition ID.
|
||||||
* @param {Account} consumer Consumer account.
|
* @param {Account} consumer Consumer account.
|
||||||
* @return {Promise<AgreementPreparionResult>} Agreement ID and signaturee.
|
* @return {Promise<AgreementPrepareResult>} Agreement ID and signaturee.
|
||||||
*/
|
*/
|
||||||
public async prepare(
|
public async prepare(
|
||||||
did: string,
|
did: string,
|
||||||
serviceDefinitionId: string,
|
serviceDefinitionId: string,
|
||||||
consumer: Account,
|
consumer: Account,
|
||||||
): Promise<AgreementPreparionResult> {
|
): Promise<AgreementPrepareResult> {
|
||||||
const keeper = await Keeper.getInstance()
|
|
||||||
|
|
||||||
const d: DID = DID.parse(did as string)
|
const d: DID = DID.parse(did as string)
|
||||||
const ddo = await AquariusProvider.getAquarius().retrieveDDO(d)
|
const ddo = await AquariusProvider.getAquarius().retrieveDDO(d)
|
||||||
const agreementId: string = generateId()
|
const agreementId: string = generateId()
|
||||||
|
|
||||||
|
const keeper = await Keeper.getInstance()
|
||||||
const templateName = ddo.findServiceByType("Access").serviceAgreementTemplate.contractName
|
const templateName = ddo.findServiceByType("Access").serviceAgreementTemplate.contractName
|
||||||
const valuesMap = await keeper
|
const agreementConditionsIds = await keeper
|
||||||
.getTemplateByName(templateName)
|
.getTemplateByName(templateName)
|
||||||
.getServiceAgreementTemplateValuesMap(ddo, agreementId, consumer.getId())
|
.getAgreementIdsFromDDO(agreementId, ddo, consumer.getId())
|
||||||
|
|
||||||
const signature = await ServiceAgreement.signServiceAgreement(ddo, serviceDefinitionId, agreementId, valuesMap, consumer)
|
const signature = await ServiceAgreement.signServiceAgreement(
|
||||||
|
ddo,
|
||||||
|
serviceDefinitionId,
|
||||||
|
agreementId,
|
||||||
|
agreementConditionsIds,
|
||||||
|
consumer,
|
||||||
|
)
|
||||||
|
|
||||||
return {agreementId, signature}
|
return {agreementId, signature}
|
||||||
}
|
}
|
||||||
|
@ -15,13 +15,11 @@ export default class ServiceAgreement {
|
|||||||
ddo: DDO,
|
ddo: DDO,
|
||||||
serviceDefinitionId: string,
|
serviceDefinitionId: string,
|
||||||
serviceAgreementId: string,
|
serviceAgreementId: string,
|
||||||
valuesMap: {[value: string]: string},
|
agreementConditionsIds: string[],
|
||||||
consumer: Account,
|
consumer: Account,
|
||||||
): Promise<string> {
|
): Promise<string> {
|
||||||
|
|
||||||
const service = ddo.findServiceById<"Access">(serviceDefinitionId)
|
const service = ddo.findServiceById<"Access">(serviceDefinitionId)
|
||||||
const values: ValuePair[][] = ServiceAgreement.getValuesFromService(service, valuesMap)
|
|
||||||
const valueHashes: string[] = ServiceAgreement.createValueHashes(values)
|
|
||||||
const timelockValues: number[] = ServiceAgreement.getTimeValuesFromService(service, "timelock")
|
const timelockValues: number[] = ServiceAgreement.getTimeValuesFromService(service, "timelock")
|
||||||
const timeoutValues: number[] = ServiceAgreement.getTimeValuesFromService(service, "timeout")
|
const timeoutValues: number[] = ServiceAgreement.getTimeValuesFromService(service, "timeout")
|
||||||
|
|
||||||
@ -32,7 +30,7 @@ export default class ServiceAgreement {
|
|||||||
const serviceAgreementHashSignature = await ServiceAgreement.createHashSignature(
|
const serviceAgreementHashSignature = await ServiceAgreement.createHashSignature(
|
||||||
service.templateId,
|
service.templateId,
|
||||||
serviceAgreementId,
|
serviceAgreementId,
|
||||||
valueHashes,
|
agreementConditionsIds,
|
||||||
timelockValues,
|
timelockValues,
|
||||||
timeoutValues,
|
timeoutValues,
|
||||||
consumer,
|
consumer,
|
||||||
@ -65,27 +63,6 @@ export default class ServiceAgreement {
|
|||||||
return serviceAgreementHashSignature
|
return serviceAgreementHashSignature
|
||||||
}
|
}
|
||||||
|
|
||||||
private static createValueHashes(parameterValuePairs: ValuePair[][]): string[] {
|
|
||||||
return parameterValuePairs
|
|
||||||
.map((valuePairs: ValuePair[]) => ServiceAgreement.hashValuePairArray(valuePairs))
|
|
||||||
}
|
|
||||||
|
|
||||||
private static hashValuePairArray(valuePairs: ValuePair[]): string {
|
|
||||||
let hash: string
|
|
||||||
try {
|
|
||||||
hash = (Web3Provider as any).getWeb3().utils.soliditySha3(...valuePairs).toString("hex")
|
|
||||||
} catch (err) {
|
|
||||||
Logger.error(`Hashing of ${JSON.stringify(valuePairs, null, 2)} failed.`)
|
|
||||||
throw err
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!hash) {
|
|
||||||
throw new Error("hashValuePairArray failed to create hash.")
|
|
||||||
}
|
|
||||||
|
|
||||||
return hash
|
|
||||||
}
|
|
||||||
|
|
||||||
public static hashServiceAgreement(
|
public static hashServiceAgreement(
|
||||||
serviceAgreementTemplateId: string,
|
serviceAgreementTemplateId: string,
|
||||||
serviceAgreementId: string,
|
serviceAgreementId: string,
|
||||||
@ -111,15 +88,4 @@ export default class ServiceAgreement {
|
|||||||
|
|
||||||
return timeoutValues
|
return timeoutValues
|
||||||
}
|
}
|
||||||
|
|
||||||
private static getValuesFromService(service: ServiceAccess, valuesMap: {[key: string]: string}): ValuePair[][] {
|
|
||||||
return (service.serviceAgreementTemplate.conditions || [])
|
|
||||||
.map(condition =>
|
|
||||||
(condition.parameters || [])
|
|
||||||
.map(({type, name}) => ({
|
|
||||||
type,
|
|
||||||
value: valuesMap[name.replace(/^_/, "")] || "",
|
|
||||||
}))
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -25,6 +25,7 @@
|
|||||||
],
|
],
|
||||||
"exclude": [
|
"exclude": [
|
||||||
"node_modules",
|
"node_modules",
|
||||||
"**/*.test.ts"
|
"**/*.test.ts",
|
||||||
|
"src/examples"
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user