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

#162: new squid classes, and skeleton for the secret store.

This commit is contained in:
ssallam 2018-10-01 09:35:03 +02:00
parent 82a149ec48
commit e4461e1be1
9 changed files with 312 additions and 110 deletions

92
SQUID_INTERFACE.md Normal file
View File

@ -0,0 +1,92 @@
## Ocean
- Ocean(config(web3Provider, nodeURI, gas, network, providerURI))
- getInstance()
- getMessageHash(message) => hash of the given message
- createDIDRecord(content) => ocean specific DID with an id based on hash of the given string message
- registerProvider(url, provider_address)
- getProviders()
## Account
- getAccounts() => list of accounts along with token and eth balances
- getTokenBalance()
- getEthBalance()
- requestTokens(amount) => bool
## Order
- purchaseAsset(assetDID, price, timeout, conditions)
- getOrderStatus(orderId) => integer representing the order status as defined in the keeper
- getOrders() => list of orders
- verifyOrderPayment(orderId) => true / false
## Asset / Metadata
- publishAsset(assetDID, assetDDO, price)
- updateAsset(assetDDO)
- retireAsset(assetDID)
- getAssetPrice(assetDID)
- getAssetMetadata(assetDID) => asset DDO
- getAssetsMetadata(<search-params>) => list of assets DDOs
- resolveAssetDID(did) => DDO of the given DID
- getAssets() => asset ids from keeper
- checkAsset(assetDID) => true / false
- getAssetConditions
#######################################################
#######################################################
#######################################################
## Keeper API:
* register tribe actor
* publish service agreement conditions
* setup/execute service agreement
* fulfill condition
* dispute service delivery, quality, content, results
* submit proof of service delivery
* query transaction history
* verify actor
#######################################################
## Use cases:
### Publisher
* publish one service
* squid.publishService(metadata) => serviceDID, didDocument
* view my published services
* squid.listServices(type, matchStr, labels, tags, publishers))
* view my sold services
* squid.listSoldServices(actorAddress)
* update service
* squid.updateService(serviceDID, metadata, price)
* revoke service
* squid.revokeService(serviceDID, reason)
### Consumer
* view / find services
* squid.listServices(type, matchStr, labels, tags, publishers)
* buy/access service
* squid.buyService(serviceId, ) => orderId, service ?
* view my purchased services
* squid.listPurchasedServices(actorAddress)
* checkPurchaseStatus(orderId)
* dispute purchased service
* squid.openServiceDispute(orderId)
* rate service
* squid.rateService(orderId, rating)
### Tribe / Marketplace
* register on ocean with an `ethereum` address and DID Record
* Uses `squid` or directly access keeper contracts
* provide API to allow the following interactions:
* publish a service
* update a service
* revoke a service
* buy/use/access a service
* search available services
*
* tribe admin:
* view publishers
* view disputes
### Curator
### Verifier

37
src/account.js Normal file
View File

@ -0,0 +1,37 @@
import KeeperBase from './keeper/keeper-base'
export default class Account extends KeeperBase {
constructor(web3Helper, token) {
super(web3Helper)
this.token = token
return (async () => {
return this
})()
}
async list() {
return Promise.all((await this.helper.getAccounts()).map(async (account) => {
// await ocean.market.requestTokens(account, 1000)
return {
name: account,
balance: {
ocn: await this.token.getTokenBalance(account),
eth: await this.token.getEthBalance(account)
}
}
}))
}
currentAccount() {
return this.helper.getCurrentAccount()
}
tokenBalance() {
return this.token.getTokenBalance()
}
ethBalance() {
return this.token.getEthBalance()
}
}

View File

@ -40,4 +40,23 @@ export default class MetaData {
return false
})
}
async publishDataAsset(assetMetadata, price) {
// Register on-chain (in the keeper)
const { market } = this.contracts
const assetDID = await this.generateDID(assetMetadata)
const result = await market.register(
assetDID,
price,
{ from: this.getCurrentAccount(), gas: this.defaultGas }
)
if (!result) {
throw Error('Register asset in ocean keeper failed.')
}
// Register in oceandb
const assetDDO = this.createAssetDDO(assetDID, assetMetadata)
this.metadata.publishDataAsset(assetDID, assetDDO)
return assetDDO
}
}

View File

@ -1,11 +1,12 @@
import Web3 from 'web3'
import OceanMarket from './keeper/market'
import OceanAuth from './keeper/auth'
import OceanToken from './keeper/token'
import Logger from './utils/logger'
import Web3Helper from './utils/Web3Helper'
import MetaData from './metadata'
import ContractLoader from './keeper/contractLoader'
const DEFAULT_GAS = 300000
const contractsToLoad = { market: 'OceanMarket', token: 'OceanToken', auth: 'OceanAuth' }
export default class Ocean {
constructor(config) {
@ -16,33 +17,20 @@ export default class Ocean {
this.helper = new Web3Helper(this._web3)
this.metadata = new MetaData(this._providerUri)
this.contracts = {}
return (async () => {
this._network = config.network || (await this.helper.getNetworkName()).toLowerCase() || 'development'
for (const key of contractsToLoad) {
this.contracts[key] = await ContractLoader.load(contractsToLoad[key], this.helper)
}
this.market = await new OceanMarket(this.helper)
this.auth = await new OceanAuth(this.helper)
this.token = await new OceanToken(this.helper)
return this
})()
}
async getAccounts() {
return Promise.all((await this.helper.getAccounts()).map(async (account) => {
// await ocean.market.requestTokens(account, 1000)
return {
name: account,
balance: {
ocn: await this.contracts.token.getTokenBalance(account),
eth: await this.contracts.token.getEthBalance(account)
}
}
}))
}
async getOrdersByConsumer(consumerAddress) {
let accessConsentEvent = this.contracts.auth.AccessConsentRequested({ _consumer: consumerAddress }, {
let accessConsentEvent = this.auth.contract.AccessConsentRequested({ _consumer: consumerAddress }, {
fromBlock: 0,
toBlock: 'latest'
})
@ -80,47 +68,6 @@ export default class Ocean {
return orders
}
purchaseAsset(
assetId, publisherId, price, privateKey, publicKey, timeout, senderAddress,
initialRequestEventHandler, accessCommittedEventHandler, tokenPublishedEventHandler) {
const { token, market, auth } = this.contracts
// Allow market contract to transfer funds on the consumer's behalf
token.approve(market.address, price, { from: senderAddress, gas: 2000000 })
// Submit the access request
auth.initiateAccessRequest(
assetId, publisherId, publicKey,
timeout, { from: senderAddress, gas: 1000000 }
)
const resourceFilter = { _resourceId: assetId, _consumer: senderAddress }
const initRequestEvent = auth.AccessConsentRequested(resourceFilter)
let order = {}
this._listenOnce(
initRequestEvent,
'AccessConsentRequested',
(result, error) => {
order = initialRequestEventHandler(result, error)
const requestIdFilter = { _id: order.id }
const accessCommittedEvent = auth.AccessRequestCommitted(requestIdFilter)
const tokenPublishedEvent = auth.EncryptedTokenPublished(requestIdFilter)
this._listenOnce(
accessCommittedEvent,
'AccessRequestCommitted',
(result, error) => {
accessCommittedEventHandler(result, order, error)
}
)
this._listenOnce(
tokenPublishedEvent,
'EncryptedTokenPublished',
(result, error) => {
tokenPublishedEventHandler(result, order, error)
}
)
})
return order
}
// Helper functions (private)
_listenOnce(event, eventName, callback) {
// eslint-disable-next-line security/detect-non-literal-fs-filename
@ -134,38 +81,9 @@ export default class Ocean {
}
// The new interface
async publishDataAsset(assetMetadata, price) {
// Register on-chain (in the keeper)
const { market } = this.contracts
const assetDID = await this.generateDID(assetMetadata)
const result = await market.register(
assetDID,
price,
{ from: this.getCurrentAccount(), gas: this.defaultGas }
)
if (!result) {
throw Error('Register asset in ocean keeper failed.')
}
// Register in oceandb
const assetDDO = this.createAssetDDO(assetDID, assetMetadata)
this.metadata.publishDataAsset(assetDID, assetDDO)
return assetDDO
}
getCurrentAccount() {
return this.helper.getCurrentAccount()
}
getTokenBalance() {
return this.contracts.token.getTokenBalance()
}
getEthBalance() {
return this.contracts.token.getEthBalance()
}
requestTokens(numTokens) {
return this.contracts.market.requestTokens(numTokens, { from: this.getCurrentAccount() })
return this.market.requestTokens(numTokens, { from: this.getCurrentAccount() })
}
getMessageHash(message) {
@ -173,23 +91,6 @@ export default class Ocean {
}
async generateDID(content) {
return 'did:ocn:' + (await this.contracts.market.generateId(content)).toString()
}
createAssetDDO(assetDID, assetMetadata) {
return {
'@context': 'https://w3id.org/did/v1',
id: assetDID,
publicKey: [],
authentication: [],
service: [],
metadata: assetMetadata
}
}
resolveDID(did) {
const providerURL = this.contracts.market.resolveAssetDID(did)
const metadataGuy = new MetaData(providerURL)
return metadataGuy.getAssetDDO(did)
return 'did:ocn:' + (await this.market.generateId(content)).toString()
}
}

52
src/order.js Normal file
View File

@ -0,0 +1,52 @@
import KeeperBase from './keeper/keeper-base'
export default class Order extends KeeperBase {
constructor(web3Helper, market, token, auth) {
super(web3Helper)
this.market = market
this.token = token
this.auth = auth
return (async () => {
return this
})()
}
buyService(serviceDID, publisherId, price, timeout, senderAddress, initialRequestEventHandler,
accessCommittedEventHandler, tokenPublishedEventHandler) {
// Allow market contract to transfer funds on the consumer's behalf
const { token, market, auth } = this
token.contract.approve(market.address, price, { from: senderAddress, gas: 2000000 })
// Submit the access request
auth.contract.initiateAccessRequest(
serviceDID, publisherId, timeout, { from: senderAddress, gas: 1000000 }
)
const resourceFilter = { _resourceId: serviceDID, _consumer: senderAddress }
const initRequestEvent = auth.contract.AccessConsentRequested(resourceFilter)
let order = {}
this._listenOnce(
initRequestEvent,
'AccessConsentRequested',
(result, error) => {
order = initialRequestEventHandler(result, error)
const requestIdFilter = { _id: order.id }
const accessCommittedEvent = auth.contract.AccessRequestCommitted(requestIdFilter)
const tokenPublishedEvent = auth.contract.EncryptedTokenPublished(requestIdFilter)
this._listenOnce(
accessCommittedEvent,
'AccessRequestCommitted',
(result, error) => {
accessCommittedEventHandler(result, order, error)
}
)
this._listenOnce(
tokenPublishedEvent,
'EncryptedTokenPublished',
(result, error) => {
tokenPublishedEventHandler(result, order, error)
}
)
})
return order
}
}

View File

@ -0,0 +1,22 @@
export default class ParityClient {
constructor(url) {
this.url = url
this.web3 = null
}
signDocumentKeyId() {
return ''
}
generateDocumentKeyFromKey() {
return ''
}
encryptDocument() {
return ''
}
decryptDocument() {
return ''
}
}

View File

@ -0,0 +1,18 @@
export default class SecretStore {
constructor(url, threshold) {
this.url = url
this.threshold = threshold | 1
}
generateServerKey() {
return ''
}
storeDocumentKey() {
return ''
}
retrieveDocumentKey() {
return ''
}
}

36
src/service.js Normal file
View File

@ -0,0 +1,36 @@
import KeeperBase from './keeper/keeper-base'
import MetaData from './metadata'
export default class Service extends KeeperBase {
constructor(web3Helper, market) {
super(web3Helper)
this.market = market
return (async () => {
return this
})()
}
serviceMetadata(assetDID) {
return ''
}
serviceTribe() {
return ''
}
createDDO(did, metadata) {
return {
'@context': 'https://w3id.org/did/v1',
id: did,
publicKey: [],
authentication: [],
service: [],
metadata: metadata
}
}
resolveDID(did) {
const providerURL = this.market.resolveDID(did)
const metadataGuy = new MetaData(providerURL)
return metadataGuy.getAssetDDO(did)
}
}

25
src/tribe.js Normal file
View File

@ -0,0 +1,25 @@
import KeeperBase from './keeper/keeper-base'
export default class Tribe extends KeeperBase {
constructor(web3Helper) {
super(web3Helper)
return (async () => {
return this
})()
}
// did ddo for tribes/marketplaces
registerTribe() {
return ''
}
tribessList() {
return ''
}
resolveTribeDID() {
// verify DDO
return 'DDO'
}
}