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

255 lines
9.0 KiB
TypeScript
Raw Normal View History

2019-01-21 17:48:40 +01:00
import AquariusProvider from "../aquarius/AquariusProvider"
2019-02-12 15:07:10 +01:00
import { SearchQuery } from "../aquarius/query/SearchQuery"
2019-01-21 17:48:40 +01:00
import BrizoProvider from "../brizo/BrizoProvider"
import { Condition } from "../ddo/Condition"
import { DDO } from "../ddo/DDO"
import { MetaData } from "../ddo/MetaData"
import { Service } from "../ddo/Service"
2019-01-21 17:48:40 +01:00
import ContractEvent from "../keeper/Event"
import EventListener from "../keeper/EventListener"
import Keeper from "../keeper/Keeper"
import SecretStoreProvider from "../secretstore/SecretStoreProvider"
import Logger from "../utils/Logger"
import Account from "./Account"
import DID from "./DID"
import IdGenerator from "./IdGenerator"
import ServiceAgreement from "./ServiceAgreements/ServiceAgreement"
import ServiceAgreementTemplate from "./ServiceAgreements/ServiceAgreementTemplate"
import Access from "./ServiceAgreements/Templates/Access"
/**
* Assets submodule of Ocean Protocol.
*/
export default class OceanAssets {
/**
* Returns the instance of OceanAssets.
* @return {Promise<OceanAssets>}
*/
public static async getInstance(): Promise<OceanAssets> {
if (!OceanAssets.instance) {
OceanAssets.instance = new OceanAssets()
}
return OceanAssets.instance
}
/**
* OceanAssets instance.
* @type {OceanAssets}
*/
private static instance: OceanAssets = null
/**
* Returns a DDO by DID.
* @param {string} did Decentralized ID.
* @return {Promise<DDO>}
*/
public async resolve(did: string): Promise<DDO> {
const d: DID = DID.parse(did)
return AquariusProvider.getAquarius().retrieveDDO(d)
}
/**
* Creates a new DDO.
* @param {MetaData} metadata DDO metadata.
* @param {Account} publisher Publicher account.
* @return {Promise<DDO>}
*/
public async create(metadata: MetaData, publisher: Account, services?: Service[]): Promise<DDO> {
2019-01-21 17:48:40 +01:00
const {didRegistry} = await Keeper.getInstance()
const aquarius = AquariusProvider.getAquarius()
const brizo = BrizoProvider.getBrizo()
const did: DID = DID.generate()
const accessServiceDefinitionId: string = "0"
const computeServiceDefintionId: string = "1"
const metadataServiceDefinitionId: string = "2"
2019-02-08 12:03:05 +01:00
metadata.base.encryptedFiles = await SecretStoreProvider.getSecretStore()
.encryptDocument(did.getId(), metadata.base.files)
2019-01-21 17:48:40 +01:00
const template = new Access()
const serviceAgreementTemplate = new ServiceAgreementTemplate(template)
const conditions: Condition[] = await serviceAgreementTemplate.getConditions(metadata, did.getId())
const serviceEndpoint = aquarius.getServiceEndpoint(did)
// create ddo itself
const ddo: DDO = new DDO({
authentication: [{
type: "RsaSignatureAuthentication2018",
publicKey: did.getDid() + "#keys-1",
}],
2019-01-21 17:48:40 +01:00
id: did.getDid(),
publicKey: [
{
id: did.getDid() + "#keys-1",
type: "Ed25519VerificationKey2018",
owner: did.getDid(),
publicKeyBase58: await publisher.getPublicKey(),
},
2019-01-21 17:48:40 +01:00
],
service: [
{
type: template.templateName,
purchaseEndpoint: brizo.getPurchaseEndpoint(),
serviceEndpoint: brizo.getConsumeEndpoint(),
// the id of the service agreement?
serviceDefinitionId: accessServiceDefinitionId,
// the id of the service agreement template
templateId: serviceAgreementTemplate.getId(),
serviceAgreementContract: {
2019-01-30 15:35:31 +01:00
contractName: "ServiceExecutionAgreement",
2019-01-21 17:48:40 +01:00
fulfillmentOperator: template.fulfillmentOperator,
events: [
{
2019-01-30 15:35:31 +01:00
name: "AgreementInitialized",
2019-01-21 17:48:40 +01:00
actorType: "consumer",
handler: {
moduleName: "payment",
functionName: "lockPayment",
version: "0.1",
},
},
2019-01-21 17:48:40 +01:00
],
},
2019-01-21 17:48:40 +01:00
conditions,
},
2019-01-21 17:48:40 +01:00
{
type: "Compute",
serviceEndpoint: brizo.getComputeEndpoint(publisher.getId(),
computeServiceDefintionId, "xxx", "xxx"),
serviceDefinitionId: computeServiceDefintionId,
},
2019-01-21 17:48:40 +01:00
{
type: "Metadata",
serviceEndpoint,
serviceDefinitionId: metadataServiceDefinitionId,
metadata: {
// Default values
curation: {
rating: 0,
numVotes: 0,
},
additionalInformation: {
updateFrecuency: "yearly",
structuredMarkup: [],
},
// Overwrites defaults
...metadata,
// Cleaning not needed information
base: {
...metadata.base,
contentUrls: [],
files: undefined,
} as any,
},
},
2019-01-21 17:48:40 +01:00
],
})
ddo.addChecksum()
await ddo.addProof(publisher.getId(), publisher.getPassword())
2019-01-21 17:48:40 +01:00
const storedDdo = await aquarius.storeDDO(ddo)
// Logger.log(JSON.stringify(storedDdo, null, 2))
await didRegistry.registerAttribute(
did.getId(),
2019-02-06 12:54:06 +01:00
ddo.getChecksum(),
2019-01-21 17:48:40 +01:00
serviceEndpoint,
publisher.getId(),
)
2019-01-21 17:48:40 +01:00
return storedDdo
}
/**
* Purchases a service agreement by DID.
* @param {string} did Decentralized ID.
* @param {string} serviceDefinitionId Service definition ID.
* @param {Account} consumer Consumer account.
* @return {Promise<{serviceAgreementId: string, serviceAgreementSignature: string}>}
*/
public async order(
did: string,
serviceDefinitionId: string,
consumer: Account,
): Promise<{serviceAgreementId: string, serviceAgreementSignature: string}> {
const d: DID = DID.parse(did as string)
const ddo = await AquariusProvider.getAquarius().retrieveDDO(d)
const serviceAgreementId: string = IdGenerator.generateId()
try {
const serviceAgreementSignature: string = await ServiceAgreement.signServiceAgreement(
ddo, serviceDefinitionId, serviceAgreementId, consumer)
const accessService: Service = ddo.findServiceByType("Access")
const metadataService: Service = ddo.findServiceByType("Metadata")
const price = metadataService.metadata.base.price
const balance = await consumer.getOceanBalance()
if (balance < price) {
throw new Error(`Not enough ocean tokens! Should have ${price} but has ${balance}`)
}
const event: ContractEvent = EventListener.subscribe(
accessService.serviceAgreementContract.contractName,
accessService.serviceAgreementContract.events[0].name, {
serviceAgreementId,
})
event.listenOnce(async (data) => {
2019-02-11 14:56:48 +01:00
const sa: ServiceAgreement = new ServiceAgreement(data.returnValues.agreementId)
2019-01-21 17:48:40 +01:00
await sa.payAsset(
d.getId(),
metadataService.metadata.base.price,
consumer,
)
Logger.log("Completed asset payment, now access should be granted.")
})
return {
serviceAgreementId,
serviceAgreementSignature,
}
} catch (err) {
Logger.error("Signing ServiceAgreement failed!", err)
}
}
/**
* Search over the assets using a query.
* @param {SearchQuery} query Query to filter the assets.
* @return {Promise<DDO[]>}
*/
public async query(query: SearchQuery): Promise<DDO[]> {
2019-02-12 15:07:10 +01:00
return AquariusProvider.getAquarius().queryMetadataByText(query)
2019-01-21 17:48:40 +01:00
}
/**
* Search over the assets using a keyword.
* @param {SearchQuery} text Text to filter the assets.
* @return {Promise<DDO[]>}
*/
public async search(text: string): Promise<DDO[]> {
return AquariusProvider.getAquarius().queryMetadataByText({
text,
page: 0,
offset: 100,
query: {
value: 1,
},
sort: {
value: 1,
},
} as SearchQuery)
}
}