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

tweak printWidth

This commit is contained in:
Matthias Kretschmann 2019-11-15 00:00:10 +01:00
parent 0552bcc577
commit 143fcbecf3
Signed by: m
GPG Key ID: 606EEEF3C479A91F
65 changed files with 1185 additions and 313 deletions

View File

@ -1,6 +1,6 @@
{ {
"semi": false, "semi": false,
"singleQuote": true, "singleQuote": true,
"printWidth": 120, "printWidth": 90,
"trailingComma": "none" "trailingComma": "none"
} }

View File

@ -32,7 +32,10 @@ describe('Asset Owners', () => {
it('should set the provider of an asset', async () => { it('should set the provider of an asset', async () => {
const ddo = await ocean.assets.create(metadata as any, account1) const ddo = await ocean.assets.create(metadata as any, account1)
const isProvider = await ocean.keeper.didRegistry.isDIDProvider(ddo.id, config.brizoAddress) const isProvider = await ocean.keeper.didRegistry.isDIDProvider(
ddo.id,
config.brizoAddress
)
assert.isTrue(isProvider) assert.isTrue(isProvider)
}) })
@ -40,11 +43,19 @@ describe('Asset Owners', () => {
it('should be added correctly a permission on an asset', async () => { it('should be added correctly a permission on an asset', async () => {
const ddo = await ocean.assets.create(metadata as any, account1) const ddo = await ocean.assets.create(metadata as any, account1)
assert.isFalse(await ocean.keeper.didRegistry.getPermission(ddo.id, account2.getId())) assert.isFalse(
await ocean.keeper.didRegistry.getPermission(ddo.id, account2.getId())
)
await ocean.keeper.didRegistry.grantPermission(ddo.id, account2.getId(), account1.getId()) await ocean.keeper.didRegistry.grantPermission(
ddo.id,
account2.getId(),
account1.getId()
)
assert.isTrue(await ocean.keeper.didRegistry.getPermission(ddo.id, account2.getId())) assert.isTrue(
await ocean.keeper.didRegistry.getPermission(ddo.id, account2.getId())
)
}) })
it('should get the assets owned by a user', async () => { it('should get the assets owned by a user', async () => {
@ -61,16 +72,22 @@ describe('Asset Owners', () => {
}) })
it('should get the assets that can be consumed by a user', async () => { it('should get the assets that can be consumed by a user', async () => {
const { length: initialLength } = await ocean.assets.consumerAssets(account2.getId()) const { length: initialLength } = await ocean.assets.consumerAssets(
account2.getId()
)
const ddo = await ocean.assets.create(metadata as any, account1) const ddo = await ocean.assets.create(metadata as any, account1)
const { length: finalLength1 } = await ocean.assets.consumerAssets(account2.getId()) const { length: finalLength1 } = await ocean.assets.consumerAssets(
account2.getId()
)
assert.equal(finalLength1 - initialLength, 0) assert.equal(finalLength1 - initialLength, 0)
// Granting access // Granting access
try { try {
await account2.requestTokens(+metadata.main.price * 10 ** -(await ocean.keeper.token.decimals())) await account2.requestTokens(
+metadata.main.price * 10 ** -(await ocean.keeper.token.decimals())
)
} catch {} } catch {}
const { index } = ddo.findServiceByType('access') const { index } = ddo.findServiceByType('access')
@ -78,7 +95,9 @@ describe('Asset Owners', () => {
await ocean.assets.order(ddo.id, index, account2) await ocean.assets.order(ddo.id, index, account2)
// Access granted // Access granted
const { length: finalLength2 } = await ocean.assets.consumerAssets(account2.getId()) const { length: finalLength2 } = await ocean.assets.consumerAssets(
account2.getId()
)
assert.equal(finalLength2 - initialLength, 1) assert.equal(finalLength2 - initialLength, 1)
}) })

View File

@ -37,28 +37,48 @@ describe('Consume Asset', () => {
assert.isDefined(ddo, 'Register has not returned a DDO') assert.isDefined(ddo, 'Register has not returned a DDO')
assert.match(ddo.id, /^did:op:[a-f0-9]{64}$/, 'DDO id is not valid') assert.match(ddo.id, /^did:op:[a-f0-9]{64}$/, 'DDO id is not valid')
assert.isAtLeast(ddo.authentication.length, 1, 'Default authentication not added') assert.isAtLeast(ddo.authentication.length, 1, 'Default authentication not added')
assert.isDefined(ddo.findServiceByType('access'), "DDO access service doesn't exist") assert.isDefined(
ddo.findServiceByType('access'),
"DDO access service doesn't exist"
)
}) })
it('should be able to request tokens for consumer', async () => { it('should be able to request tokens for consumer', async () => {
const initialBalance = (await consumer.getBalance()).ocn const initialBalance = (await consumer.getBalance()).ocn
const claimedTokens = +metadata.main.price * 10 ** -(await ocean.keeper.token.decimals()) const claimedTokens =
+metadata.main.price * 10 ** -(await ocean.keeper.token.decimals())
try { try {
await consumer.requestTokens(claimedTokens) await consumer.requestTokens(claimedTokens)
} catch {} } catch {}
assert.equal((await consumer.getBalance()).ocn, initialBalance + claimedTokens, 'OCN Tokens not delivered') assert.equal(
(await consumer.getBalance()).ocn,
initialBalance + claimedTokens,
'OCN Tokens not delivered'
)
}) })
it('should sign the service agreement', async () => { it('should sign the service agreement', async () => {
const accessService = ddo.findServiceByType('access') const accessService = ddo.findServiceByType('access')
serviceAgreementSignatureResult = await ocean.agreements.prepare(ddo.id, accessService.index, consumer) serviceAgreementSignatureResult = await ocean.agreements.prepare(
ddo.id,
accessService.index,
consumer
)
const { agreementId, signature } = serviceAgreementSignatureResult const { agreementId, signature } = serviceAgreementSignatureResult
assert.match(agreementId, /^0x[a-f0-9]{64}$/, 'Service agreement ID seems not valid') assert.match(
assert.match(signature, /^0x[a-f0-9]{130}$/, 'Service agreement signature seems not valid') agreementId,
/^0x[a-f0-9]{64}$/,
'Service agreement ID seems not valid'
)
assert.match(
signature,
/^0x[a-f0-9]{130}$/,
'Service agreement signature seems not valid'
)
}) })
it('should execute the service agreement', async () => { it('should execute the service agreement', async () => {
@ -77,7 +97,9 @@ describe('Consume Asset', () => {
}) })
it('should get the agreement conditions status not fulfilled', async () => { it('should get the agreement conditions status not fulfilled', async () => {
const status = await ocean.agreements.status(serviceAgreementSignatureResult.agreementId) const status = await ocean.agreements.status(
serviceAgreementSignatureResult.agreementId
)
assert.deepEqual(status, { assert.deepEqual(status, {
lockReward: ConditionState.Unfulfilled, lockReward: ConditionState.Unfulfilled,
@ -118,7 +140,9 @@ describe('Consume Asset', () => {
}) })
it('should get the agreement conditions status fulfilled', async () => { it('should get the agreement conditions status fulfilled', async () => {
const status = await ocean.agreements.status(serviceAgreementSignatureResult.agreementId) const status = await ocean.agreements.status(
serviceAgreementSignatureResult.agreementId
)
assert.deepEqual(status, { assert.deepEqual(status, {
lockReward: ConditionState.Fulfilled, lockReward: ConditionState.Fulfilled,
@ -147,7 +171,11 @@ describe('Consume Asset', () => {
}) })
}) })
assert.deepEqual(files, ['README.md', 'package.json'], 'Stored files are not correct.') assert.deepEqual(
files,
['README.md', 'package.json'],
'Stored files are not correct.'
)
}) })
it('should consume and store one asset', async () => { it('should consume and store one asset', async () => {

View File

@ -41,7 +41,9 @@ describe('Consume Asset (Brizo)', () => {
it('should regiester an asset', async () => { it('should regiester an asset', async () => {
const steps = [] const steps = []
ddo = await ocean.assets.create(metadata as any, publisher).next(step => steps.push(step)) ddo = await ocean.assets
.create(metadata as any, publisher)
.next(step => steps.push(step))
assert.instanceOf(ddo, DDO) assert.instanceOf(ddo, DDO)
assert.deepEqual(steps, [0, 1, 2, 3, 4, 5, 6, 7]) assert.deepEqual(steps, [0, 1, 2, 3, 4, 5, 6, 7])
@ -51,11 +53,15 @@ describe('Consume Asset (Brizo)', () => {
const accessService = ddo.findServiceByType('access') const accessService = ddo.findServiceByType('access')
try { try {
await consumer.requestTokens(+metadata.main.price * 10 ** -(await ocean.keeper.token.decimals())) await consumer.requestTokens(
+metadata.main.price * 10 ** -(await ocean.keeper.token.decimals())
)
} catch {} } catch {}
const steps = [] const steps = []
agreementId = await ocean.assets.order(ddo.id, accessService.index, consumer).next(step => steps.push(step)) agreementId = await ocean.assets
.order(ddo.id, accessService.index, consumer)
.next(step => steps.push(step))
assert.isDefined(agreementId) assert.isDefined(agreementId)
assert.deepEqual(steps, [0, 1, 2, 3]) assert.deepEqual(steps, [0, 1, 2, 3])
@ -65,7 +71,13 @@ describe('Consume Asset (Brizo)', () => {
const accessService = ddo.findServiceByType('access') const accessService = ddo.findServiceByType('access')
const folder = '/tmp/ocean/squid-js' const folder = '/tmp/ocean/squid-js'
const path = await ocean.assets.consume(agreementId, ddo.id, accessService.index, consumer, folder) const path = await ocean.assets.consume(
agreementId,
ddo.id,
accessService.index,
consumer,
folder
)
assert.include(path, folder, 'The storage path is not correct.') assert.include(path, folder, 'The storage path is not correct.')
@ -75,6 +87,10 @@ describe('Consume Asset (Brizo)', () => {
}) })
}) })
assert.deepEqual(files, ['README.md', 'package.json'], 'Stored files are not correct.') assert.deepEqual(
files,
['README.md', 'package.json'],
'Stored files are not correct.'
)
}) })
}) })

View File

@ -32,7 +32,13 @@ xdescribe('Consume Asset (Large size)', () => {
...baseMetadata, ...baseMetadata,
main: { main: {
...baseMetadata.main, ...baseMetadata.main,
files: [{ index: 0, contentType: 'hello/hello', url: 'https://speed.hetzner.de/1GB.bin' }] files: [
{
index: 0,
contentType: 'hello/hello',
url: 'https://speed.hetzner.de/1GB.bin'
}
]
} }
} }
}) })
@ -47,7 +53,9 @@ xdescribe('Consume Asset (Large size)', () => {
const accessService = ddo.findServiceByType('access') const accessService = ddo.findServiceByType('access')
try { try {
await consumer.requestTokens(+metadata.main.price * 10 ** -(await ocean.keeper.token.decimals())) await consumer.requestTokens(
+metadata.main.price * 10 ** -(await ocean.keeper.token.decimals())
)
} catch {} } catch {}
agreementId = await ocean.assets.order(ddo.id, accessService.index, consumer) agreementId = await ocean.assets.order(ddo.id, accessService.index, consumer)
@ -59,7 +67,13 @@ xdescribe('Consume Asset (Large size)', () => {
const accessService = ddo.findServiceByType('access') const accessService = ddo.findServiceByType('access')
const folder = '/tmp/ocean/squid-js' const folder = '/tmp/ocean/squid-js'
const path = await ocean.assets.consume(agreementId, ddo.id, accessService.index, consumer, folder) const path = await ocean.assets.consume(
agreementId,
ddo.id,
accessService.index,
consumer,
folder
)
assert.include(path, folder, 'The storage path is not correct.') assert.include(path, folder, 'The storage path is not correct.')

View File

@ -47,13 +47,21 @@ describe('Register Escrow Access Secret Store Template', () => {
describe('Propose and approve template', () => { describe('Propose and approve template', () => {
it('should propose the template', async () => { it('should propose the template', async () => {
await keeper.templateStoreManager.proposeTemplate(template.getAddress(), consumer.getId(), true) await keeper.templateStoreManager.proposeTemplate(
template.getAddress(),
consumer.getId(),
true
)
// TODO: Use a event to detect template mined // TODO: Use a event to detect template mined
await new Promise(resolve => setTimeout(resolve, 2 * 1000)) await new Promise(resolve => setTimeout(resolve, 2 * 1000))
}) })
it('should approve the template', async () => { it('should approve the template', async () => {
await keeper.templateStoreManager.approveTemplate(template.getAddress(), templateManagerOwner.getId(), true) await keeper.templateStoreManager.approveTemplate(
template.getAddress(),
templateManagerOwner.getId(),
true
)
// TODO: Use a event to detect template mined // TODO: Use a event to detect template mined
await new Promise(resolve => setTimeout(resolve, 2 * 1000)) await new Promise(resolve => setTimeout(resolve, 2 * 1000))
}) })
@ -68,11 +76,21 @@ describe('Register Escrow Access Secret Store Template', () => {
let conditionIdEscrow: string let conditionIdEscrow: string
it('should register a DID', async () => { it('should register a DID', async () => {
await keeper.didRegistry.registerAttribute(did, checksum, [], url, publisher.getId()) await keeper.didRegistry.registerAttribute(
did,
checksum,
[],
url,
publisher.getId()
)
}) })
it('should generate the condition IDs', async () => { it('should generate the condition IDs', async () => {
conditionIdAccess = await accessSecretStoreCondition.generateIdHash(agreementId, did, consumer.getId()) conditionIdAccess = await accessSecretStoreCondition.generateIdHash(
agreementId,
did,
consumer.getId()
)
conditionIdLock = await lockRewardCondition.generateIdHash( conditionIdLock = await lockRewardCondition.generateIdHash(
agreementId, agreementId,
await escrowReward.getAddress(), await escrowReward.getAddress(),
@ -108,10 +126,20 @@ describe('Register Escrow Access Secret Store Template', () => {
assert.equal(conditionInstances.length, 3, 'Expected 3 conditions.') assert.equal(conditionInstances.length, 3, 'Expected 3 conditions.')
const conditionClasses = [AccessSecretStoreCondition, EscrowReward, LockRewardCondition] const conditionClasses = [
AccessSecretStoreCondition,
EscrowReward,
LockRewardCondition
]
conditionClasses.forEach(conditionClass => { conditionClasses.forEach(conditionClass => {
if (!conditionInstances.find(condition => condition instanceof conditionClass)) { if (
throw new Error(`${conditionClass.name} is not part of the conditions.`) !conditionInstances.find(
condition => condition instanceof conditionClass
)
) {
throw new Error(
`${conditionClass.name} is not part of the conditions.`
)
} }
}) })
}) })
@ -131,7 +159,10 @@ describe('Register Escrow Access Secret Store Template', () => {
}) })
it('should not grant the access to the consumer', async () => { it('should not grant the access to the consumer', async () => {
const accessGranted = await accessSecretStoreCondition.checkPermissions(consumer.getId(), did) const accessGranted = await accessSecretStoreCondition.checkPermissions(
consumer.getId(),
did
)
assert.isFalse(accessGranted, 'Consumer has been granted.') assert.isFalse(accessGranted, 'Consumer has been granted.')
}) })
@ -141,7 +172,11 @@ describe('Register Escrow Access Secret Store Template', () => {
await consumer.requestTokens(escrowAmount) await consumer.requestTokens(escrowAmount)
} catch {} } catch {}
await keeper.token.approve(lockRewardCondition.getAddress(), escrowAmount, consumer.getId()) await keeper.token.approve(
lockRewardCondition.getAddress(),
escrowAmount,
consumer.getId()
)
const fulfill = await lockRewardCondition.fulfill( const fulfill = await lockRewardCondition.fulfill(
agreementId, agreementId,
@ -179,7 +214,10 @@ describe('Register Escrow Access Secret Store Template', () => {
}) })
it('should grant the access to the consumer', async () => { it('should grant the access to the consumer', async () => {
const accessGranted = await accessSecretStoreCondition.checkPermissions(consumer.getId(), did) const accessGranted = await accessSecretStoreCondition.checkPermissions(
consumer.getId(),
did
)
assert.isTrue(accessGranted, 'Consumer has not been granted.') assert.isTrue(accessGranted, 'Consumer has not been granted.')
}) })
@ -192,17 +230,31 @@ describe('Register Escrow Access Secret Store Template', () => {
it('should register a DID', async () => { it('should register a DID', async () => {
// This part is executed inside Ocean.assets.create() // This part is executed inside Ocean.assets.create()
await keeper.didRegistry.registerAttribute(did, checksum, [], url, publisher.getId()) await keeper.didRegistry.registerAttribute(
did,
checksum,
[],
url,
publisher.getId()
)
}) })
it('should create a new agreement (short way)', async () => { it('should create a new agreement (short way)', async () => {
agreementId = await template.createFullAgreement(did, escrowAmount, consumer.getId(), publisher.getId()) agreementId = await template.createFullAgreement(
did,
escrowAmount,
consumer.getId(),
publisher.getId()
)
assert.match(agreementId, /^0x[a-f0-9]{64}$/i) assert.match(agreementId, /^0x[a-f0-9]{64}$/i)
}) })
it('should not grant the access to the consumer', async () => { it('should not grant the access to the consumer', async () => {
const accessGranted = await accessSecretStoreCondition.checkPermissions(consumer.getId(), did) const accessGranted = await accessSecretStoreCondition.checkPermissions(
consumer.getId(),
did
)
assert.isFalse(accessGranted, 'Consumer has been granted.') assert.isFalse(accessGranted, 'Consumer has been granted.')
}) })
@ -212,11 +264,20 @@ describe('Register Escrow Access Secret Store Template', () => {
await consumer.requestTokens(escrowAmount) await consumer.requestTokens(escrowAmount)
} catch {} } catch {}
await ocean.agreements.conditions.lockReward(agreementId, escrowAmount, consumer) await ocean.agreements.conditions.lockReward(
agreementId,
escrowAmount,
consumer
)
}) })
it('should fulfill the conditions from publisher side', async () => { it('should fulfill the conditions from publisher side', async () => {
await ocean.agreements.conditions.grantAccess(agreementId, did, consumer.getId(), publisher) await ocean.agreements.conditions.grantAccess(
agreementId,
did,
consumer.getId(),
publisher
)
await ocean.agreements.conditions.releaseReward( await ocean.agreements.conditions.releaseReward(
agreementId, agreementId,
escrowAmount, escrowAmount,
@ -228,7 +289,10 @@ describe('Register Escrow Access Secret Store Template', () => {
}) })
it('should grant the access to the consumer', async () => { it('should grant the access to the consumer', async () => {
const accessGranted = await accessSecretStoreCondition.checkPermissions(consumer.getId(), did) const accessGranted = await accessSecretStoreCondition.checkPermissions(
consumer.getId(),
did
)
assert.isTrue(accessGranted, 'Consumer has not been granted.') assert.isTrue(accessGranted, 'Consumer has not been granted.')
}) })

View File

@ -47,13 +47,21 @@ describe('Register Escrow Compute Execution Template', () => {
describe('Propose and approve template', () => { describe('Propose and approve template', () => {
it('should propose the template', async () => { it('should propose the template', async () => {
await keeper.templateStoreManager.proposeTemplate(template.getAddress(), consumer.getId(), true) await keeper.templateStoreManager.proposeTemplate(
template.getAddress(),
consumer.getId(),
true
)
// TODO: Use a event to detect template mined // TODO: Use a event to detect template mined
await new Promise(resolve => setTimeout(resolve, 2 * 1000)) await new Promise(resolve => setTimeout(resolve, 2 * 1000))
}) })
it('should approve the template', async () => { it('should approve the template', async () => {
await keeper.templateStoreManager.approveTemplate(template.getAddress(), templateManagerOwner.getId(), true) await keeper.templateStoreManager.approveTemplate(
template.getAddress(),
templateManagerOwner.getId(),
true
)
// TODO: Use a event to detect template mined // TODO: Use a event to detect template mined
await new Promise(resolve => setTimeout(resolve, 2 * 1000)) await new Promise(resolve => setTimeout(resolve, 2 * 1000))
}) })
@ -68,11 +76,21 @@ describe('Register Escrow Compute Execution Template', () => {
let conditionIdEscrow: string let conditionIdEscrow: string
it('should register a DID', async () => { it('should register a DID', async () => {
await keeper.didRegistry.registerAttribute(did, checksum, [], url, publisher.getId()) await keeper.didRegistry.registerAttribute(
did,
checksum,
[],
url,
publisher.getId()
)
}) })
it('should generate the condition IDs', async () => { it('should generate the condition IDs', async () => {
conditionIdCompute = await computeExecutionCondition.generateIdHash(agreementId, did, consumer.getId()) conditionIdCompute = await computeExecutionCondition.generateIdHash(
agreementId,
did,
consumer.getId()
)
conditionIdLock = await lockRewardCondition.generateIdHash( conditionIdLock = await lockRewardCondition.generateIdHash(
agreementId, agreementId,
await escrowReward.getAddress(), await escrowReward.getAddress(),
@ -108,10 +126,20 @@ describe('Register Escrow Compute Execution Template', () => {
assert.equal(conditionInstances.length, 3, 'Expected 3 conditions.') assert.equal(conditionInstances.length, 3, 'Expected 3 conditions.')
const conditionClasses = [ComputeExecutionCondition, EscrowReward, LockRewardCondition] const conditionClasses = [
ComputeExecutionCondition,
EscrowReward,
LockRewardCondition
]
conditionClasses.forEach(conditionClass => { conditionClasses.forEach(conditionClass => {
if (!conditionInstances.find(condition => condition instanceof conditionClass)) { if (
throw new Error(`${conditionClass.name} is not part of the conditions.`) !conditionInstances.find(
condition => condition instanceof conditionClass
)
) {
throw new Error(
`${conditionClass.name} is not part of the conditions.`
)
} }
}) })
}) })
@ -131,7 +159,10 @@ describe('Register Escrow Compute Execution Template', () => {
}) })
it('should not trigger the compute', async () => { it('should not trigger the compute', async () => {
const computeTriggered = await computeExecutionCondition.wasComputeTriggered(did, consumer.getId()) const computeTriggered = await computeExecutionCondition.wasComputeTriggered(
did,
consumer.getId()
)
assert.isFalse(computeTriggered, 'Compute has been triggered.') assert.isFalse(computeTriggered, 'Compute has been triggered.')
}) })
@ -141,7 +172,11 @@ describe('Register Escrow Compute Execution Template', () => {
await consumer.requestTokens(escrowAmount) await consumer.requestTokens(escrowAmount)
} catch {} } catch {}
await keeper.token.approve(lockRewardCondition.getAddress(), escrowAmount, consumer.getId()) await keeper.token.approve(
lockRewardCondition.getAddress(),
escrowAmount,
consumer.getId()
)
const fulfill = await lockRewardCondition.fulfill( const fulfill = await lockRewardCondition.fulfill(
agreementId, agreementId,
@ -179,7 +214,10 @@ describe('Register Escrow Compute Execution Template', () => {
}) })
it('should grant the access to the consumer', async () => { it('should grant the access to the consumer', async () => {
const computeTriggered = await computeExecutionCondition.wasComputeTriggered(did, consumer.getId()) const computeTriggered = await computeExecutionCondition.wasComputeTriggered(
did,
consumer.getId()
)
assert.isTrue(computeTriggered, 'Compute has not been triggered.') assert.isTrue(computeTriggered, 'Compute has not been triggered.')
}) })
@ -192,17 +230,31 @@ describe('Register Escrow Compute Execution Template', () => {
it('should register a DID', async () => { it('should register a DID', async () => {
// This part is executed inside Ocean.assets.create() // This part is executed inside Ocean.assets.create()
await keeper.didRegistry.registerAttribute(did, checksum, [], url, publisher.getId()) await keeper.didRegistry.registerAttribute(
did,
checksum,
[],
url,
publisher.getId()
)
}) })
it('should create a new agreement (short way)', async () => { it('should create a new agreement (short way)', async () => {
agreementId = await template.createFullAgreement(did, escrowAmount, consumer.getId(), publisher.getId()) agreementId = await template.createFullAgreement(
did,
escrowAmount,
consumer.getId(),
publisher.getId()
)
assert.match(agreementId, /^0x[a-f0-9]{64}$/i) assert.match(agreementId, /^0x[a-f0-9]{64}$/i)
}) })
it('should not grant the access to the consumer', async () => { it('should not grant the access to the consumer', async () => {
const computeTriggered = await computeExecutionCondition.wasComputeTriggered(did, consumer.getId()) const computeTriggered = await computeExecutionCondition.wasComputeTriggered(
did,
consumer.getId()
)
assert.isFalse(computeTriggered, 'Compute has been triggered.') assert.isFalse(computeTriggered, 'Compute has been triggered.')
}) })
@ -212,11 +264,20 @@ describe('Register Escrow Compute Execution Template', () => {
await consumer.requestTokens(escrowAmount) await consumer.requestTokens(escrowAmount)
} catch {} } catch {}
await ocean.agreements.conditions.lockReward(agreementId, escrowAmount, consumer) await ocean.agreements.conditions.lockReward(
agreementId,
escrowAmount,
consumer
)
}) })
it('should fulfill the conditions from computing side', async () => { it('should fulfill the conditions from computing side', async () => {
await ocean.agreements.conditions.grantServiceExecution(agreementId, did, consumer.getId(), publisher) await ocean.agreements.conditions.grantServiceExecution(
agreementId,
did,
consumer.getId(),
publisher
)
await ocean.agreements.conditions.releaseReward( await ocean.agreements.conditions.releaseReward(
agreementId, agreementId,
escrowAmount, escrowAmount,
@ -228,7 +289,10 @@ describe('Register Escrow Compute Execution Template', () => {
}) })
it('should grant the access to the consumer', async () => { it('should grant the access to the consumer', async () => {
const computeTriggered = await computeExecutionCondition.wasComputeTriggered(did, consumer.getId()) const computeTriggered = await computeExecutionCondition.wasComputeTriggered(
did,
consumer.getId()
)
assert.isTrue(computeTriggered, 'Compute has not been triggered.') assert.isTrue(computeTriggered, 'Compute has not been triggered.')
}) })

View File

@ -15,7 +15,8 @@ describe('Search Asset', () => {
.toString(36) .toString(36)
.substr(2) .substr(2)
let price let price
const metadataGenerator = (name: string) => generateMetadata(`${name}${testHash}`, price) const metadataGenerator = (name: string) =>
generateMetadata(`${name}${testHash}`, price)
let test1length let test1length
let test2length let test2length
@ -43,10 +44,22 @@ describe('Search Asset', () => {
}) })
it('should register an asset', async () => { it('should register an asset', async () => {
assert.instanceOf(await ocean.assets.create(metadataGenerator('Test1') as any, publisher), DDO) assert.instanceOf(
assert.instanceOf(await ocean.assets.create(metadataGenerator('Test2') as any, publisher), DDO) await ocean.assets.create(metadataGenerator('Test1') as any, publisher),
assert.instanceOf(await ocean.assets.create(metadataGenerator('Test2') as any, publisher), DDO) DDO
assert.instanceOf(await ocean.assets.create(metadataGenerator('Test3') as any, publisher), DDO) )
assert.instanceOf(
await ocean.assets.create(metadataGenerator('Test2') as any, publisher),
DDO
)
assert.instanceOf(
await ocean.assets.create(metadataGenerator('Test2') as any, publisher),
DDO
)
assert.instanceOf(
await ocean.assets.create(metadataGenerator('Test3') as any, publisher),
DDO
)
}) })
it('should search by text and see the increment of DDOs', async () => { it('should search by text and see the increment of DDOs', async () => {
@ -65,8 +78,14 @@ describe('Search Asset', () => {
it('should return a list of DDOs', async () => { it('should return a list of DDOs', async () => {
const { results: ddos } = await ocean.assets.search(`Test1${testHash}`) const { results: ddos } = await ocean.assets.search(`Test1${testHash}`)
assert.equal(ddos.length - test1length, 1, 'Something was wrong searching the assets') assert.equal(
ddos.map(ddo => assert.instanceOf(ddo, DDO, 'The DDO is not an instance of a DDO')) ddos.length - test1length,
1,
'Something was wrong searching the assets'
)
ddos.map(ddo =>
assert.instanceOf(ddo, DDO, 'The DDO is not an instance of a DDO')
)
}) })
it('should be able to do a query to get a list of DDOs', async () => { it('should be able to do a query to get a list of DDOs', async () => {
@ -82,6 +101,8 @@ describe('Search Asset', () => {
}) })
assert.equal(ddos.length, 1, 'Something was wrong searching the assets') assert.equal(ddos.length, 1, 'Something was wrong searching the assets')
ddos.map(ddo => assert.instanceOf(ddo, DDO, 'The DDO is not an instance of a DDO')) ddos.map(ddo =>
assert.instanceOf(ddo, DDO, 'The DDO is not an instance of a DDO')
)
}) })
}) })

View File

@ -13,12 +13,14 @@ const metadata: Partial<MetaData> = {
{ {
index: 0, index: 0,
contentType: 'application/json', contentType: 'application/json',
url: 'https://raw.githubusercontent.com/oceanprotocol/squid-js/master/package.json' url:
'https://raw.githubusercontent.com/oceanprotocol/squid-js/master/package.json'
}, },
{ {
index: 1, index: 1,
contentType: 'text/plain', contentType: 'text/plain',
url: 'https://raw.githubusercontent.com/oceanprotocol/squid-js/master/README.md' url:
'https://raw.githubusercontent.com/oceanprotocol/squid-js/master/README.md'
} }
] ]
}, },

View File

@ -6,23 +6,26 @@ module.exports = class AddVendorsPlugin {
} }
apply(compiler) { apply(compiler) {
compiler.hooks.emit.tapAsync(`AddVendorsPlugin ${this.base}`, (compilation, callback) => { compiler.hooks.emit.tapAsync(
const main = compilation.assets[`main.${this.base}`] `AddVendorsPlugin ${this.base}`,
const mainMap = compilation.assets[`main.${this.base}.map`] (compilation, callback) => {
const vendor = compilation.assets[`vendors.${this.base}`] const main = compilation.assets[`main.${this.base}`]
const mainMap = compilation.assets[`main.${this.base}.map`]
const vendor = compilation.assets[`vendors.${this.base}`]
if (main && vendor) { if (main && vendor) {
const compiledAsset = new ConcatSource(main.children[0]) const compiledAsset = new ConcatSource(main.children[0])
compiledAsset.add(vendor) compiledAsset.add(vendor)
compiledAsset.add(main.children[1]) compiledAsset.add(main.children[1])
compilation.assets = {} compilation.assets = {}
compilation.assets[this.base] = compiledAsset compilation.assets[this.base] = compiledAsset
} else if (main && mainMap) { } else if (main && mainMap) {
compilation.assets = {} compilation.assets = {}
compilation.assets[this.base] = main compilation.assets[this.base] = main
compilation.assets[`${this.base}.map`] = mainMap compilation.assets[`${this.base}.map`] = mainMap
}
callback()
} }
callback() )
})
} }
} }

View File

@ -11,7 +11,9 @@ export interface InstantiableConfig {
logger?: Logger logger?: Logger
} }
export function generateIntantiableConfigFromConfig(config: Config): Partial<InstantiableConfig> { export function generateIntantiableConfigFromConfig(
config: Config
): Partial<InstantiableConfig> {
const logLevel = const logLevel =
typeof config.verbose !== 'number' typeof config.verbose !== 'number'
? config.verbose ? config.verbose

View File

@ -53,7 +53,10 @@ export class Aquarius extends Instantiable {
return consumptionUrl return consumptionUrl
}) })
.catch(error => { .catch(error => {
this.logger.error('Error fetching the data asset consumption url: ', error) this.logger.error(
'Error fetching the data asset consumption url: ',
error
)
return null return null
}) })
@ -72,7 +75,11 @@ export class Aquarius extends Instantiable {
if (response.ok) { if (response.ok) {
return response.json() as DDO[] return response.json() as DDO[]
} }
this.logger.error('queryMetadata failed:', response.status, response.statusText) this.logger.error(
'queryMetadata failed:',
response.status,
response.statusText
)
return this.transformResult() return this.transformResult()
}) })
.then(results => { .then(results => {
@ -94,7 +101,10 @@ export class Aquarius extends Instantiable {
public async queryMetadataByText(query: SearchQuery): Promise<QueryResult> { public async queryMetadataByText(query: SearchQuery): Promise<QueryResult> {
const fullUrl = new URL(`${this.url}${apiPath}/query`) const fullUrl = new URL(`${this.url}${apiPath}/query`)
fullUrl.searchParams.append('text', query.text) fullUrl.searchParams.append('text', query.text)
fullUrl.searchParams.append('sort', decodeURIComponent(JSON.stringify(query.sort))) fullUrl.searchParams.append(
'sort',
decodeURIComponent(JSON.stringify(query.sort))
)
fullUrl.searchParams.append('offset', query.offset.toString()) fullUrl.searchParams.append('offset', query.offset.toString())
fullUrl.searchParams.append('page', query.page.toString()) fullUrl.searchParams.append('page', query.page.toString())
const result: QueryResult = await this.ocean.utils.fetch const result: QueryResult = await this.ocean.utils.fetch
@ -103,7 +113,11 @@ export class Aquarius extends Instantiable {
if (response.ok) { if (response.ok) {
return response.json() as DDO[] return response.json() as DDO[]
} }
this.logger.log('queryMetadataByText failed:', response.status, response.statusText) this.logger.log(
'queryMetadataByText failed:',
response.status,
response.statusText
)
return this.transformResult() return this.transformResult()
}) })
.then(results => { .then(results => {
@ -130,7 +144,12 @@ export class Aquarius extends Instantiable {
if (response.ok) { if (response.ok) {
return response.json() return response.json()
} }
this.logger.error('storeDDO failed:', response.status, response.statusText, ddo) this.logger.error(
'storeDDO failed:',
response.status,
response.statusText,
ddo
)
return null as DDO return null as DDO
}) })
.then((response: DDO) => { .then((response: DDO) => {
@ -149,7 +168,10 @@ export class Aquarius extends Instantiable {
* @param {DID | string} did DID of the asset. * @param {DID | string} did DID of the asset.
* @return {Promise<DDO>} DDO of the asset. * @return {Promise<DDO>} DDO of the asset.
*/ */
public async retrieveDDO(did: DID | string, metadataServiceEndpoint?: string): Promise<DDO> { public async retrieveDDO(
did: DID | string,
metadataServiceEndpoint?: string
): Promise<DDO> {
did = did && DID.parse(did) did = did && DID.parse(did)
const fullUrl = metadataServiceEndpoint || `${this.url}${apiPath}/${did.getDid()}` const fullUrl = metadataServiceEndpoint || `${this.url}${apiPath}/${did.getDid()}`
const result = await this.ocean.utils.fetch const result = await this.ocean.utils.fetch
@ -158,7 +180,12 @@ export class Aquarius extends Instantiable {
if (response.ok) { if (response.ok) {
return response.json() return response.json()
} }
this.logger.log('retrieveDDO failed:', response.status, response.statusText, did) this.logger.log(
'retrieveDDO failed:',
response.status,
response.statusText,
did
)
return null as DDO return null as DDO
}) })
.then((response: DDO) => { .then((response: DDO) => {

View File

@ -35,7 +35,12 @@ export class Brizo extends Instantiable {
return `${this.url}${apiPath}/publish` return `${this.url}${apiPath}/publish`
} }
public getComputeEndpoint(pubKey: string, serviceIndex: number, _notUsed: string, container: string) { public getComputeEndpoint(
pubKey: string,
serviceIndex: number,
_notUsed: string,
container: string
) {
return `${this.url}${apiPath}/compute` return `${this.url}${apiPath}/compute`
} }
@ -55,7 +60,10 @@ export class Brizo extends Instantiable {
} }
try { try {
return await this.ocean.utils.fetch.post(this.getPurchaseEndpoint(), decodeURI(JSON.stringify(args))) return await this.ocean.utils.fetch.post(
this.getPurchaseEndpoint(),
decodeURI(JSON.stringify(args))
)
} catch (e) { } catch (e) {
this.logger.error(e) this.logger.error(e)
throw new Error('HTTP request failed') throw new Error('HTTP request failed')
@ -72,7 +80,10 @@ export class Brizo extends Instantiable {
): Promise<string> { ): Promise<string> {
const signature = const signature =
(await account.getToken()) || (await account.getToken()) ||
(await this.ocean.utils.signature.signText(noZeroX(agreementId), account.getId())) (await this.ocean.utils.signature.signText(
noZeroX(agreementId),
account.getId()
))
const filesPromises = files const filesPromises = files
.filter((_, i) => index === -1 || i === index) .filter((_, i) => index === -1 || i === index)
.map(async ({ index: i }) => { .map(async ({ index: i }) => {
@ -94,7 +105,12 @@ export class Brizo extends Instantiable {
return destination return destination
} }
public async encrypt(did: string, signature: string, document: any, publisher: string): Promise<string> { public async encrypt(
did: string,
signature: string,
document: any,
publisher: string
): Promise<string> {
const args = { const args = {
documentId: did, documentId: did,
signature, signature,

View File

@ -50,7 +50,8 @@ export class DDO {
public constructor(ddo: Partial<DDO> = {}) { public constructor(ddo: Partial<DDO> = {}) {
Object.assign(this, ddo, { Object.assign(this, ddo, {
created: (ddo && ddo.created) || new Date().toISOString().replace(/\.[0-9]{3}/, '') created:
(ddo && ddo.created) || new Date().toISOString().replace(/\.[0-9]{3}/, '')
}) })
} }
@ -114,10 +115,18 @@ export class DDO {
* @param {string} password Password if it's required. * @param {string} password Password if it's required.
* @return {Promise<Proof>} Proof object. * @return {Promise<Proof>} Proof object.
*/ */
public async generateProof(ocean: Ocean, publicKey: string, password?: string): Promise<Proof> { public async generateProof(
ocean: Ocean,
publicKey: string,
password?: string
): Promise<Proof> {
const checksum = this.getChecksum() const checksum = this.getChecksum()
const signature = await ocean.utils.signature.signText(checksum, publicKey, password) const signature = await ocean.utils.signature.signText(
checksum,
publicKey,
password
)
return { return {
created: new Date().toISOString().replace(/\.[0-9]{3}/, ''), created: new Date().toISOString().replace(/\.[0-9]{3}/, ''),
@ -134,7 +143,11 @@ export class DDO {
* @param {string} password Password if it's required. * @param {string} password Password if it's required.
* @return {Promise<Proof>} Proof object. * @return {Promise<Proof>} Proof object.
*/ */
public async addProof(ocean: Ocean, publicKey: string, password?: string): Promise<void> { public async addProof(
ocean: Ocean,
publicKey: string,
password?: string
): Promise<void> {
if (this.proof) { if (this.proof) {
throw new Error('Proof already exists') throw new Error('Proof already exists')
} }

View File

@ -13,7 +13,11 @@ export interface PublicKey {
* Type of key. * Type of key.
* @type {string} * @type {string}
*/ */
type: 'Ed25519VerificationKey2018' | 'RsaVerificationKey2018' | 'EdDsaSAPublicKeySecp256k1' | 'EthereumECDSAKey' type:
| 'Ed25519VerificationKey2018'
| 'RsaVerificationKey2018'
| 'EdDsaSAPublicKeySecp256k1'
| 'EthereumECDSAKey'
/** /**
* Key owner. * Key owner.

View File

@ -2,7 +2,13 @@ import { MetaData } from './MetaData'
import { ServiceAgreementTemplate } from './ServiceAgreementTemplate' import { ServiceAgreementTemplate } from './ServiceAgreementTemplate'
import { Provider } from './ComputingProvider' import { Provider } from './ComputingProvider'
export type ServiceType = 'authorization' | 'metadata' | 'access' | 'compute' | 'computing' | 'fitchainCompute' export type ServiceType =
| 'authorization'
| 'metadata'
| 'access'
| 'compute'
| 'computing'
| 'fitchainCompute'
export interface ServiceCommon { export interface ServiceCommon {
type: ServiceType type: ServiceType
@ -52,7 +58,9 @@ export interface ServiceCompute extends ServiceCommon {
templateId?: string templateId?: string
} }
export type Service<T extends ServiceType | 'default' = 'default'> = T extends 'authorization' export type Service<
T extends ServiceType | 'default' = 'default'
> = T extends 'authorization'
? ServiceAuthorization ? ServiceAuthorization
: T extends 'metadata' : T extends 'metadata'
? ServiceMetadata ? ServiceMetadata

View File

@ -6,7 +6,11 @@ export default class ContractHandler extends Instantiable {
return ContractHandler.contracts.get(this.getHash(what, networkId)) return ContractHandler.contracts.get(this.getHash(what, networkId))
} }
protected static setContract(what: string, networkId: number, contractInstance: Contract) { protected static setContract(
what: string,
networkId: number,
contractInstance: Contract
) {
ContractHandler.contracts.set(this.getHash(what, networkId), contractInstance) ContractHandler.contracts.set(this.getHash(what, networkId), contractInstance)
} }
@ -29,7 +33,10 @@ export default class ContractHandler extends Instantiable {
const where = (await this.ocean.keeper.getNetworkName()).toLowerCase() const where = (await this.ocean.keeper.getNetworkName()).toLowerCase()
const networkId = await this.ocean.keeper.getNetworkId() const networkId = await this.ocean.keeper.getNetworkId()
try { try {
return ContractHandler.getContract(what, networkId) || (await this.load(what, where, networkId)) return (
ContractHandler.getContract(what, networkId) ||
(await this.load(what, where, networkId))
)
} catch (err) { } catch (err) {
if (!optional) { if (!optional) {
this.logger.error('Failed to load', what, 'from', where, err) this.logger.error('Failed to load', what, 'from', where, err)
@ -38,7 +45,11 @@ export default class ContractHandler extends Instantiable {
} }
} }
private async load(what: string, where: string, networkId: number): Promise<Contract> { private async load(
what: string,
where: string,
networkId: number
): Promise<Contract> {
this.logger.debug('Loading', what, 'from', where) this.logger.debug('Loading', what, 'from', where)
const artifact = require(`@oceanprotocol/keeper-contracts/artifacts/${what}.${where}.json`) const artifact = require(`@oceanprotocol/keeper-contracts/artifacts/${what}.${where}.json`)
// Logger.log('Loaded artifact', artifact) // Logger.log('Loaded artifact', artifact)
@ -49,7 +60,14 @@ export default class ContractHandler extends Instantiable {
} }
const contract = new this.web3.eth.Contract(artifact.abi, artifact.address) const contract = new this.web3.eth.Contract(artifact.abi, artifact.address)
this.logger.debug('Getting instance of', what, 'from', where, 'at address', artifact.address) this.logger.debug(
'Getting instance of',
what,
'from',
where,
'at address',
artifact.address
)
ContractHandler.setContract(what, networkId, contract) ContractHandler.setContract(what, networkId, contract)
return ContractHandler.getContract(what, networkId) return ContractHandler.getContract(what, networkId)
} }

View File

@ -41,7 +41,11 @@ export class EventHandler extends Instantiable {
} }
} }
public getEvent(contract: ContractBase, eventName: string, filter: { [key: string]: any }) { public getEvent(
contract: ContractBase,
eventName: string,
filter: { [key: string]: any }
) {
return new ContractEvent(this, contract, eventName, filter) return new ContractEvent(this, contract, eventName, filter)
} }
@ -61,6 +65,9 @@ export class EventHandler extends Instantiable {
this.events.forEach(fn => fn(this.lastBlock + 1)) this.events.forEach(fn => fn(this.lastBlock + 1))
this.lastBlock = blockNumber this.lastBlock = blockNumber
} }
this.lastTimeout = global.setTimeout(() => this.checkBlock(true, n++), this.interval) this.lastTimeout = global.setTimeout(
() => this.checkBlock(true, n++),
this.interval
)
} }
} }

View File

@ -15,7 +15,11 @@ import {
EscrowAccessSecretStoreTemplate, EscrowAccessSecretStoreTemplate,
EscrowComputeExecutionTemplate EscrowComputeExecutionTemplate
} from './contracts/templates' } from './contracts/templates'
import { TemplateStoreManager, AgreementStoreManager, ConditionStoreManager } from './contracts/managers' import {
TemplateStoreManager,
AgreementStoreManager,
ConditionStoreManager
} from './contracts/managers'
import { objectPromiseAll } from '../utils' import { objectPromiseAll } from '../utils'
import { EventHandler } from './EventHandler' import { EventHandler } from './EventHandler'
@ -55,11 +59,17 @@ export class Keeper extends Instantiable {
// Conditions // Conditions
lockRewardCondition: LockRewardCondition.getInstance(config), lockRewardCondition: LockRewardCondition.getInstance(config),
escrowReward: EscrowReward.getInstance(config), escrowReward: EscrowReward.getInstance(config),
accessSecretStoreCondition: AccessSecretStoreCondition.getInstance(config), accessSecretStoreCondition: AccessSecretStoreCondition.getInstance(
config
),
computeExecutionCondition: ComputeExecutionCondition.getInstance(config), computeExecutionCondition: ComputeExecutionCondition.getInstance(config),
// Templates // Templates
escrowAccessSecretStoreTemplate: EscrowAccessSecretStoreTemplate.getInstance(config), escrowAccessSecretStoreTemplate: EscrowAccessSecretStoreTemplate.getInstance(
escrowComputeExecutionTemplate: EscrowComputeExecutionTemplate.getInstance(config) config
),
escrowComputeExecutionTemplate: EscrowComputeExecutionTemplate.getInstance(
config
)
}) })
keeper.connected = true keeper.connected = true
@ -92,8 +102,10 @@ export class Keeper extends Instantiable {
} }
// Conditions // Conditions
keeper.templates = { keeper.templates = {
escrowAccessSecretStoreTemplate: keeper.instances.escrowAccessSecretStoreTemplate, escrowAccessSecretStoreTemplate:
escrowComputeExecutionTemplate: keeper.instances.escrowComputeExecutionTemplate keeper.instances.escrowAccessSecretStoreTemplate,
escrowComputeExecutionTemplate:
keeper.instances.escrowComputeExecutionTemplate
} }
// Utils // Utils
keeper.utils = { keeper.utils = {
@ -178,7 +190,9 @@ export class Keeper extends Instantiable {
* @return {Condition} Condition instance. * @return {Condition} Condition instance.
*/ */
public getConditionByAddress(address: string): Condition { public getConditionByAddress(address: string): Condition {
return Object.values(this.conditions).find(condition => condition.getAddress() === address) return Object.values(this.conditions).find(
condition => condition.getAddress() === address
)
} }
/** /**
@ -187,7 +201,9 @@ export class Keeper extends Instantiable {
* @return {AgreementTemplate} Agreement template instance. * @return {AgreementTemplate} Agreement template instance.
*/ */
public getTemplateByName(name: string): AgreementTemplate { public getTemplateByName(name: string): AgreementTemplate {
return Object.values(this.templates).find(template => template.contractName === name) return Object.values(this.templates).find(
template => template.contractName === name
)
} }
/** /**
@ -196,7 +212,9 @@ export class Keeper extends Instantiable {
* @return {AgreementTemplate} Agreement template instance. * @return {AgreementTemplate} Agreement template instance.
*/ */
public getTemplateByAddress(address: string): AgreementTemplate { public getTemplateByAddress(address: string): AgreementTemplate {
return Object.values(this.templates).find(template => template.getAddress() === address) return Object.values(this.templates).find(
template => template.getAddress() === address
)
} }
/** /**

View File

@ -7,6 +7,10 @@ export default class Web3Provider {
* @return {Web3} * @return {Web3}
*/ */
public static getWeb3(config: Partial<Config> = {}): Web3 { public static getWeb3(config: Partial<Config> = {}): Web3 {
return new Web3(config.web3Provider || Web3.givenProvider || new Web3.providers.HttpProvider(config.nodeUri)) return new Web3(
config.web3Provider ||
Web3.givenProvider ||
new Web3.providers.HttpProvider(config.nodeUri)
)
} }
} }

View File

@ -22,7 +22,9 @@ export abstract class ContractBase extends Instantiable {
public async getEventData(eventName: string, options: any) { public async getEventData(eventName: string, options: any) {
if (!this.contract.events[eventName]) { if (!this.contract.events[eventName]) {
throw new Error(`Event "${eventName}" not found on contract "${this.contractName}"`) throw new Error(
`Event "${eventName}" not found on contract "${this.contractName}"`
)
} }
return this.contract.getPastEvents(eventName, options) return this.contract.getPastEvents(eventName, options)
} }
@ -62,14 +64,24 @@ export abstract class ContractBase extends Instantiable {
return from return from
} }
protected async sendFrom(name: string, args: any[], from?: string): Promise<TransactionReceipt> { protected async sendFrom(
name: string,
args: any[],
from?: string
): Promise<TransactionReceipt> {
from = await this.getFromAddress(from) from = await this.getFromAddress(from)
return this.send(name, from, args) return this.send(name, from, args)
} }
protected async send(name: string, from: string, args: any[]): Promise<TransactionReceipt> { protected async send(
name: string,
from: string,
args: any[]
): Promise<TransactionReceipt> {
if (!this.contract.methods[name]) { if (!this.contract.methods[name]) {
throw new Error(`Method "${name}" is not part of contract "${this.contractName}"`) throw new Error(
`Method "${name}" is not part of contract "${this.contractName}"`
)
} }
// Logger.log(name, args) // Logger.log(name, args)
const method = this.contract.methods[name] const method = this.contract.methods[name]
@ -91,7 +103,9 @@ export abstract class ContractBase extends Instantiable {
} }
}) })
this.logger.error('-'.repeat(40)) this.logger.error('-'.repeat(40))
this.logger.error(`Sending transaction "${name}" on contract "${this.contractName}" failed.`) this.logger.error(
`Sending transaction "${name}" on contract "${this.contractName}" failed.`
)
this.logger.error(`Error: ${err.message}`) this.logger.error(`Error: ${err.message}`)
this.logger.error(`From: ${from}`) this.logger.error(`From: ${from}`)
this.logger.error(`Parameters: ${JSON.stringify(mappedArgs, null, 2)}`) this.logger.error(`Parameters: ${JSON.stringify(mappedArgs, null, 2)}`)
@ -100,7 +114,11 @@ export abstract class ContractBase extends Instantiable {
} }
} }
protected async call<T extends any>(name: string, args: any[], from?: string): Promise<T> { protected async call<T extends any>(
name: string,
args: any[],
from?: string
): Promise<T> {
if (!this.contract.methods[name]) { if (!this.contract.methods[name]) {
throw new Error(`Method ${name} is not part of contract ${this.contractName}`) throw new Error(`Method ${name} is not part of contract ${this.contractName}`)
} }
@ -109,14 +127,19 @@ export abstract class ContractBase extends Instantiable {
const method = this.contract.methods[name](...args) const method = this.contract.methods[name](...args)
return method.call(from ? { from } : null) return method.call(from ? { from } : null)
} catch (err) { } catch (err) {
this.logger.error(`Calling method "${name}" on contract "${this.contractName}" failed. Args: ${args}`, err) this.logger.error(
`Calling method "${name}" on contract "${this.contractName}" failed. Args: ${args}`,
err
)
throw err throw err
} }
} }
protected getEvent(eventName: string, filter: { [key: string]: any }) { protected getEvent(eventName: string, filter: { [key: string]: any }) {
if (!this.contract.events[eventName]) { if (!this.contract.events[eventName]) {
throw new Error(`Event ${eventName} is not part of contract ${this.contractName}`) throw new Error(
`Event ${eventName} is not part of contract ${this.contractName}`
)
} }
return this.ocean.keeper.utils.eventHandler.getEvent(this, eventName, filter) return this.ocean.keeper.utils.eventHandler.getEvent(this, eventName, filter)
} }
@ -128,9 +151,12 @@ export abstract class ContractBase extends Instantiable {
signature: (method as any).signature signature: (method as any).signature
})) }))
.filter((method: any) => method.name === methodName) .filter((method: any) => method.name === methodName)
const foundMethod = methods.find(({ inputs }) => inputs.length === args.length) || methods[0] const foundMethod =
methods.find(({ inputs }) => inputs.length === args.length) || methods[0]
if (!foundMethod) { if (!foundMethod) {
throw new Error(`Method "${methodName}" is not part of contract "${this.contractName}"`) throw new Error(
`Method "${methodName}" is not part of contract "${this.contractName}"`
)
} }
return foundMethod return foundMethod
} }

View File

@ -17,7 +17,12 @@ export default class DIDRegistry extends ContractBase {
value: string, value: string,
ownerAddress: string ownerAddress: string
) { ) {
return this.send('registerAttribute', ownerAddress, [zeroX(did), zeroX(checksum), providers.map(zeroX), value]) return this.send('registerAttribute', ownerAddress, [
zeroX(did),
zeroX(checksum),
providers.map(zeroX),
value
])
} }
public async getDIDOwner(did: string): Promise<string> { public async getDIDOwner(did: string): Promise<string> {
@ -42,16 +47,22 @@ export default class DIDRegistry extends ContractBase {
.map(didPrefixed) .map(didPrefixed)
} }
public async getAttributesByDid(did: string): Promise<{ did: string; serviceEndpoint: string; checksum: string }> { public async getAttributesByDid(
did: string
): Promise<{ did: string; serviceEndpoint: string; checksum: string }> {
return ( return (
await this.getPastEvents('DIDAttributeRegistered', { await this.getPastEvents('DIDAttributeRegistered', {
_did: didZeroX(did) _did: didZeroX(did)
}) })
).map(({ returnValues: { _did, _checksum: checksum, _value: serviceEndpoint } }) => ({ ).map(
did: didPrefixed(_did), ({
serviceEndpoint, returnValues: { _did, _checksum: checksum, _value: serviceEndpoint }
checksum }) => ({
}))[0] did: didPrefixed(_did),
serviceEndpoint,
checksum
})
)[0]
} }
public async grantPermission(did: string, grantee: string, ownerAddress: string) { public async grantPermission(did: string, grantee: string, ownerAddress: string) {
@ -71,6 +82,9 @@ export default class DIDRegistry extends ContractBase {
newOwnerAddress: string, newOwnerAddress: string,
ownerAddress: string ownerAddress: string
): Promise<TransactionReceipt> { ): Promise<TransactionReceipt> {
return this.send('transferDIDOwnership', ownerAddress, [didZeroX(did), noZeroX(newOwnerAddress)]) return this.send('transferDIDOwnership', ownerAddress, [
didZeroX(did),
noZeroX(newOwnerAddress)
])
} }
} }

View File

@ -2,7 +2,10 @@ import ContractBase from './ContractBase'
import { InstantiableConfig } from '../../Instantiable.abstract' import { InstantiableConfig } from '../../Instantiable.abstract'
export default class GenericContract extends ContractBase { export default class GenericContract extends ContractBase {
public static async getInstance(config: InstantiableConfig, contractName: string): Promise<ContractBase> { public static async getInstance(
config: InstantiableConfig,
contractName: string
): Promise<ContractBase> {
const contract: GenericContract = new GenericContract(contractName) const contract: GenericContract = new GenericContract(contractName)
await contract.init(config) await contract.init(config)
return contract return contract

View File

@ -18,7 +18,9 @@ export default class OceanToken extends ContractBase {
} }
public async balanceOf(address: string): Promise<number> { public async balanceOf(address: string): Promise<number> {
return this.call('balanceOf', [address]).then((balance: string) => new BigNumber(balance).toNumber()) return this.call('balanceOf', [address]).then((balance: string) =>
new BigNumber(balance).toNumber()
)
} }
public async transfer(to: string, amount: number, from: string) { public async transfer(to: string, amount: number, from: string) {

View File

@ -3,8 +3,14 @@ import { zeroX, didZeroX, didPrefixed } from '../../../utils'
import { InstantiableConfig } from '../../../Instantiable.abstract' import { InstantiableConfig } from '../../../Instantiable.abstract'
export class AccessSecretStoreCondition extends Condition { export class AccessSecretStoreCondition extends Condition {
public static async getInstance(config: InstantiableConfig): Promise<AccessSecretStoreCondition> { public static async getInstance(
return Condition.getInstance(config, 'AccessSecretStoreCondition', AccessSecretStoreCondition) config: InstantiableConfig
): Promise<AccessSecretStoreCondition> {
return Condition.getInstance(
config,
'AccessSecretStoreCondition',
AccessSecretStoreCondition
)
} }
public hashValues(did: string, grantee: string) { public hashValues(did: string, grantee: string) {
@ -16,10 +22,16 @@ export class AccessSecretStoreCondition extends Condition {
} }
public checkPermissions(grantee: string, did: string, from?: string) { public checkPermissions(grantee: string, did: string, from?: string) {
return this.call<boolean>('checkPermissions', [grantee, didZeroX(did)].map(zeroX), from) return this.call<boolean>(
'checkPermissions',
[grantee, didZeroX(did)].map(zeroX),
from
)
} }
public async getGrantedDidByConsumer(consumer: string): Promise<{ did: string; agreementId: string }[]> { public async getGrantedDidByConsumer(
consumer: string
): Promise<{ did: string; agreementId: string }[]> {
return ( return (
await this.getPastEvents('Fulfilled', { await this.getPastEvents('Fulfilled', {
_grantee: zeroX(consumer) _grantee: zeroX(consumer)

View File

@ -3,19 +3,38 @@ import { zeroX, didZeroX, didPrefixed } from '../../../utils'
import { InstantiableConfig } from '../../../Instantiable.abstract' import { InstantiableConfig } from '../../../Instantiable.abstract'
export class ComputeExecutionCondition extends Condition { export class ComputeExecutionCondition extends Condition {
public static async getInstance(config: InstantiableConfig): Promise<ComputeExecutionCondition> { public static async getInstance(
return Condition.getInstance(config, 'ComputeExecutionCondition', ComputeExecutionCondition) config: InstantiableConfig
): Promise<ComputeExecutionCondition> {
return Condition.getInstance(
config,
'ComputeExecutionCondition',
ComputeExecutionCondition
)
} }
public hashValues(did: string, computeConsumer: string) { public hashValues(did: string, computeConsumer: string) {
return super.hashValues(didZeroX(did), zeroX(computeConsumer)) return super.hashValues(didZeroX(did), zeroX(computeConsumer))
} }
public fulfill(agreementId: string, did: string, computeConsumer: string, from?: string) { public fulfill(
return super.fulfill(agreementId, [didZeroX(did), computeConsumer].map(zeroX), from) agreementId: string,
did: string,
computeConsumer: string,
from?: string
) {
return super.fulfill(
agreementId,
[didZeroX(did), computeConsumer].map(zeroX),
from
)
} }
public wasComputeTriggered(did: string, computeConsumer: string, from?: string) { public wasComputeTriggered(did: string, computeConsumer: string, from?: string) {
return this.call<boolean>('wasComputeTriggered', [didZeroX(did), computeConsumer].map(zeroX), from) return this.call<boolean>(
'wasComputeTriggered',
[didZeroX(did), computeConsumer].map(zeroX),
from
)
} }
} }

View File

@ -9,7 +9,12 @@ export enum ConditionState {
Aborted = 3 Aborted = 3
} }
export const conditionStateNames = ['Uninitialized', 'Unfulfilled', 'Fulfilled', 'Aborted'] export const conditionStateNames = [
'Uninitialized',
'Unfulfilled',
'Fulfilled',
'Aborted'
]
export abstract class Condition extends ContractBase { export abstract class Condition extends ContractBase {
public static async getInstance( public static async getInstance(

View File

@ -14,7 +14,10 @@ export class EscrowReward extends Condition {
lockCondition: string, lockCondition: string,
releaseCondition: string releaseCondition: string
) { ) {
return super.hashValues(amount, ...[receiver, sender, lockCondition, releaseCondition].map(zeroX)) return super.hashValues(
amount,
...[receiver, sender, lockCondition, releaseCondition].map(zeroX)
)
} }
public fulfill( public fulfill(

View File

@ -3,7 +3,9 @@ import { zeroX } from '../../../utils'
import { InstantiableConfig } from '../../../Instantiable.abstract' import { InstantiableConfig } from '../../../Instantiable.abstract'
export class LockRewardCondition extends Condition { export class LockRewardCondition extends Condition {
public static async getInstance(config: InstantiableConfig): Promise<LockRewardCondition> { public static async getInstance(
config: InstantiableConfig
): Promise<LockRewardCondition> {
return Condition.getInstance(config, 'LockRewardCondition', LockRewardCondition) return Condition.getInstance(config, 'LockRewardCondition', LockRewardCondition)
} }
@ -11,7 +13,12 @@ export class LockRewardCondition extends Condition {
return super.hashValues(zeroX(rewardAddress), String(amount)) return super.hashValues(zeroX(rewardAddress), String(amount))
} }
public fulfill(agreementId: string, rewardAddress: string, amount: number | string, from?: string) { public fulfill(
agreementId: string,
rewardAddress: string,
amount: number | string,
from?: string
) {
return super.fulfill(agreementId, [zeroX(rewardAddress), String(amount)], from) return super.fulfill(agreementId, [zeroX(rewardAddress), String(amount)], from)
} }
} }

View File

@ -12,8 +12,12 @@ export interface AgreementData {
} }
export class AgreementStoreManager extends ContractBase { export class AgreementStoreManager extends ContractBase {
public static async getInstance(config: InstantiableConfig): Promise<AgreementStoreManager> { public static async getInstance(
const templateStoreManeger: AgreementStoreManager = new AgreementStoreManager('AgreementStoreManager') config: InstantiableConfig
): Promise<AgreementStoreManager> {
const templateStoreManeger: AgreementStoreManager = new AgreementStoreManager(
'AgreementStoreManager'
)
await templateStoreManeger.init(config) await templateStoreManeger.init(config)
return templateStoreManeger return templateStoreManeger
} }

View File

@ -14,8 +14,12 @@ export interface ConditionData {
} }
export class ConditionStoreManager extends ContractBase { export class ConditionStoreManager extends ContractBase {
public static async getInstance(config: InstantiableConfig): Promise<ConditionStoreManager> { public static async getInstance(
const templateStoreManeger: ConditionStoreManager = new ConditionStoreManager('ConditionStoreManager') config: InstantiableConfig
): Promise<ConditionStoreManager> {
const templateStoreManeger: ConditionStoreManager = new ConditionStoreManager(
'ConditionStoreManager'
)
await templateStoreManeger.init(config) await templateStoreManeger.init(config)
return templateStoreManeger return templateStoreManeger
} }

View File

@ -17,8 +17,12 @@ export interface TemplateMetadata {
} }
export class TemplateStoreManager extends ContractBase { export class TemplateStoreManager extends ContractBase {
public static async getInstance(config: InstantiableConfig): Promise<TemplateStoreManager> { public static async getInstance(
const templateStoreManeger: TemplateStoreManager = new TemplateStoreManager('TemplateStoreManager') config: InstantiableConfig
): Promise<TemplateStoreManager> {
const templateStoreManeger: TemplateStoreManager = new TemplateStoreManager(
'TemplateStoreManager'
)
await templateStoreManeger.init(config) await templateStoreManeger.init(config)
return templateStoreManeger return templateStoreManeger
} }
@ -39,7 +43,11 @@ export class TemplateStoreManager extends ContractBase {
} }
} }
public async approveTemplate(address: string, from?: string, ignoreApproved?: boolean) { public async approveTemplate(
address: string,
from?: string,
ignoreApproved?: boolean
) {
const template = await this.getTemplate(address) const template = await this.getTemplate(address)
if (template.state !== TemplateState.Proposed) { if (template.state !== TemplateState.Proposed) {
this.logger.warn(`Template "${address}" is not in "proposed" state.`) this.logger.warn(`Template "${address}" is not in "proposed" state.`)
@ -56,7 +64,12 @@ export class TemplateStoreManager extends ContractBase {
} }
public async getTemplate(address: string) { public async getTemplate(address: string) {
const { state, owner, lastUpdatedBy, blockNumberUpdated } = await this.call('getTemplate', [zeroX(address)]) const {
state,
owner,
lastUpdatedBy,
blockNumberUpdated
} = await this.call('getTemplate', [zeroX(address)])
return { return {
state: +state, state: +state,
owner, owner,

View File

@ -1,5 +1,9 @@
import ContractBase from '../ContractBase' import ContractBase from '../ContractBase'
import { Condition, ConditionState, conditionStateNames } from '../conditions/Condition.abstract' import {
Condition,
ConditionState,
conditionStateNames
} from '../conditions/Condition.abstract'
import { DDO } from '../../../ddo/DDO' import { DDO } from '../../../ddo/DDO'
import { ServiceAgreementTemplate } from '../../../ddo/ServiceAgreementTemplate' import { ServiceAgreementTemplate } from '../../../ddo/ServiceAgreementTemplate'
import { zeroX } from '../../../utils' import { zeroX } from '../../../utils'
@ -50,7 +54,14 @@ export abstract class AgreementTemplate extends ContractBase {
) { ) {
return this.sendFrom( return this.sendFrom(
'createAgreement', 'createAgreement',
[zeroX(agreementId), zeroX(did), conditionIds.map(zeroX), timeLocks, timeOuts, ...extraArgs], [
zeroX(agreementId),
zeroX(did),
conditionIds.map(zeroX),
timeLocks,
timeOuts,
...extraArgs
],
from from
) )
} }
@ -68,7 +79,9 @@ export abstract class AgreementTemplate extends ContractBase {
* @return {Promise<Condition[]>} Conditions contracts. * @return {Promise<Condition[]>} Conditions contracts.
*/ */
public async getConditions(): Promise<Condition[]> { public async getConditions(): Promise<Condition[]> {
return (await this.getConditionTypes()).map(address => this.ocean.keeper.getConditionByAddress(address)) return (await this.getConditionTypes()).map(address =>
this.ocean.keeper.getConditionByAddress(address)
)
} }
/** /**
@ -110,7 +123,9 @@ export abstract class AgreementTemplate extends ContractBase {
const name = (await this.getServiceAgreementTemplateConditions()).find( const name = (await this.getServiceAgreementTemplateConditions()).find(
({ name: conditionRef }) => conditionRef === ref ({ name: conditionRef }) => conditionRef === ref
).contractName ).contractName
return (await this.getConditions()).find(condition => condition.contractName === name) return (await this.getConditions()).find(
condition => condition.contractName === name
)
} }
public async getServiceAgreementTemplateDependencies() { public async getServiceAgreementTemplateDependencies() {
@ -123,7 +138,9 @@ export abstract class AgreementTemplate extends ContractBase {
* @param {string} agreementId Agreement ID. * @param {string} agreementId Agreement ID.
* @return {Promise} Conditions status. * @return {Promise} Conditions status.
*/ */
public async getAgreementStatus(agreementId: string): Promise<AgreementConditionsStatus | false> { public async getAgreementStatus(
agreementId: string
): Promise<AgreementConditionsStatus | false> {
const agreementStore = this.ocean.keeper.agreementStoreManager const agreementStore = this.ocean.keeper.agreementStoreManager
const conditionStore = this.ocean.keeper.conditionStoreManager const conditionStore = this.ocean.keeper.conditionStoreManager
@ -144,11 +161,17 @@ export abstract class AgreementTemplate extends ContractBase {
) )
const statesPromises = Object.keys(dependencies).map(async (ref, i) => { const statesPromises = Object.keys(dependencies).map(async (ref, i) => {
const { contractName } = await this.getServiceAgreementTemplateConditionByRef(ref) const { contractName } = await this.getServiceAgreementTemplateConditionByRef(
ref
)
return { return {
ref, ref,
contractName, contractName,
state: (await conditionStore.getCondition(conditionIdByConddition[contractName])).state state: (
await conditionStore.getCondition(
conditionIdByConddition[contractName]
)
).state
} }
}) })
const states = await Promise.all(statesPromises) const states = await Promise.all(statesPromises)
@ -184,16 +207,18 @@ export abstract class AgreementTemplate extends ContractBase {
if (!status) { if (!status) {
this.logger.bypass('Agreement not created yet!') this.logger.bypass('Agreement not created yet!')
} }
Object.values(status || []).forEach(({ condition, contractName, state, blocked, blockedBy }, i) => { Object.values(status || []).forEach(
if (i) { ({ condition, contractName, state, blocked, blockedBy }, i) => {
this.logger.bypass('-'.repeat(20)) if (i) {
this.logger.bypass('-'.repeat(20))
}
this.logger.bypass(`${condition} (${contractName})`)
this.logger.bypass(' Status:', state, `(${conditionStateNames[state]})`)
if (blocked) {
this.logger.bypass(' Blocked by:', blockedBy)
}
} }
this.logger.bypass(`${condition} (${contractName})`) )
this.logger.bypass(' Status:', state, `(${conditionStateNames[state]})`)
if (blocked) {
this.logger.bypass(' Blocked by:', blockedBy)
}
})
this.logger.bypass('-'.repeat(80)) this.logger.bypass('-'.repeat(80))
} }

View File

@ -26,7 +26,15 @@ export abstract class BaseEscrowTemplate extends AgreementTemplate {
accessConsumer: string, accessConsumer: string,
from?: string from?: string
) { ) {
return super.createAgreement(agreementId, did, conditionIds, timeLocks, timeOuts, [accessConsumer], from) return super.createAgreement(
agreementId,
did,
conditionIds,
timeLocks,
timeOuts,
[accessConsumer],
from
)
} }
public async getAgreementData(agreementId: string) { public async getAgreementData(agreementId: string) {

View File

@ -13,7 +13,11 @@ export const escrowAccessSecretStoreTemplateServiceAgreementTemplate: ServiceAgr
} }
} }
], ],
fulfillmentOrder: ['lockReward.fulfill', 'accessSecretStore.fulfill', 'escrowReward.fulfill'], fulfillmentOrder: [
'lockReward.fulfill',
'accessSecretStore.fulfill',
'escrowReward.fulfill'
],
conditionDependency: { conditionDependency: {
lockReward: [], lockReward: [],
accessSecretStore: [], accessSecretStore: [],

View File

@ -7,15 +7,26 @@ import { InstantiableConfig } from '../../../Instantiable.abstract'
import { escrowAccessSecretStoreTemplateServiceAgreementTemplate } from './EscrowAccessSecretStoreTemplate.serviceAgreementTemplate' import { escrowAccessSecretStoreTemplateServiceAgreementTemplate } from './EscrowAccessSecretStoreTemplate.serviceAgreementTemplate'
export class EscrowAccessSecretStoreTemplate extends BaseEscrowTemplate { export class EscrowAccessSecretStoreTemplate extends BaseEscrowTemplate {
public static async getInstance(config: InstantiableConfig): Promise<EscrowAccessSecretStoreTemplate> { public static async getInstance(
return AgreementTemplate.getInstance(config, 'EscrowAccessSecretStoreTemplate', EscrowAccessSecretStoreTemplate) config: InstantiableConfig
): Promise<EscrowAccessSecretStoreTemplate> {
return AgreementTemplate.getInstance(
config,
'EscrowAccessSecretStoreTemplate',
EscrowAccessSecretStoreTemplate
)
} }
public async getServiceAgreementTemplate() { public async getServiceAgreementTemplate() {
return escrowAccessSecretStoreTemplateServiceAgreementTemplate return escrowAccessSecretStoreTemplateServiceAgreementTemplate
} }
public async createAgreementFromDDO(agreementId: string, ddo: DDO, consumer: string, from?: string) { public async createAgreementFromDDO(
agreementId: string,
ddo: DDO,
consumer: string,
from?: string
) {
return !!(await this.createFullAgreement( return !!(await this.createFullAgreement(
ddo.shortId(), ddo.shortId(),
ddo.findServiceByType('metadata').attributes.main.price, ddo.findServiceByType('metadata').attributes.main.price,
@ -25,7 +36,12 @@ export class EscrowAccessSecretStoreTemplate extends BaseEscrowTemplate {
)) ))
} }
public async getAgreementIdsFromDDO(agreementId: string, ddo: DDO, consumer: string, from?: string) { public async getAgreementIdsFromDDO(
agreementId: string,
ddo: DDO,
consumer: string,
from?: string
) {
const { const {
accessSecretStoreConditionId, accessSecretStoreConditionId,
lockRewardConditionId, lockRewardConditionId,
@ -72,10 +88,19 @@ export class EscrowAccessSecretStoreTemplate extends BaseEscrowTemplate {
return zeroX(agreementId) return zeroX(agreementId)
} }
private async createFullAgreementData(agreementId: string, did: string, amount: number | string, consumer: string) { private async createFullAgreementData(
agreementId: string,
did: string,
amount: number | string,
consumer: string
) {
const { didRegistry, conditions } = this.ocean.keeper const { didRegistry, conditions } = this.ocean.keeper
const { accessSecretStoreCondition, lockRewardCondition, escrowReward } = conditions const {
accessSecretStoreCondition,
lockRewardCondition,
escrowReward
} = conditions
const publisher = await didRegistry.getDIDOwner(did) const publisher = await didRegistry.getDIDOwner(did)
@ -84,7 +109,11 @@ export class EscrowAccessSecretStoreTemplate extends BaseEscrowTemplate {
await escrowReward.getAddress(), await escrowReward.getAddress(),
amount amount
) )
const accessSecretStoreConditionId = await accessSecretStoreCondition.generateIdHash(agreementId, did, consumer) const accessSecretStoreConditionId = await accessSecretStoreCondition.generateIdHash(
agreementId,
did,
consumer
)
const escrowRewardId = await escrowReward.generateIdHash( const escrowRewardId = await escrowReward.generateIdHash(
agreementId, agreementId,
String(amount), String(amount),

View File

@ -13,7 +13,11 @@ export const escrowComputeExecutionTemplateServiceAgreementTemplate: ServiceAgre
} }
} }
], ],
fulfillmentOrder: ['lockReward.fulfill', 'serviceExecution.fulfill', 'escrowReward.fulfill'], fulfillmentOrder: [
'lockReward.fulfill',
'serviceExecution.fulfill',
'escrowReward.fulfill'
],
conditionDependency: { conditionDependency: {
lockReward: [], lockReward: [],
serviceExecution: [], serviceExecution: [],

View File

@ -7,15 +7,26 @@ import { InstantiableConfig } from '../../../Instantiable.abstract'
import { escrowComputeExecutionTemplateServiceAgreementTemplate } from './EscrowComputeExecutionTemplate.serviceAgreementTemplate' import { escrowComputeExecutionTemplateServiceAgreementTemplate } from './EscrowComputeExecutionTemplate.serviceAgreementTemplate'
export class EscrowComputeExecutionTemplate extends BaseEscrowTemplate { export class EscrowComputeExecutionTemplate extends BaseEscrowTemplate {
public static async getInstance(config: InstantiableConfig): Promise<EscrowComputeExecutionTemplate> { public static async getInstance(
return AgreementTemplate.getInstance(config, 'EscrowComputeExecutionTemplate', EscrowComputeExecutionTemplate) config: InstantiableConfig
): Promise<EscrowComputeExecutionTemplate> {
return AgreementTemplate.getInstance(
config,
'EscrowComputeExecutionTemplate',
EscrowComputeExecutionTemplate
)
} }
public async getServiceAgreementTemplate() { public async getServiceAgreementTemplate() {
return escrowComputeExecutionTemplateServiceAgreementTemplate return escrowComputeExecutionTemplateServiceAgreementTemplate
} }
public async createAgreementFromDDO(agreementId: string, ddo: DDO, consumer: string, from?: string) { public async createAgreementFromDDO(
agreementId: string,
ddo: DDO,
consumer: string,
from?: string
) {
return !!(await this.createFullAgreement( return !!(await this.createFullAgreement(
ddo.shortId(), ddo.shortId(),
ddo.findServiceByType('metadata').attributes.main.price, ddo.findServiceByType('metadata').attributes.main.price,
@ -25,7 +36,12 @@ export class EscrowComputeExecutionTemplate extends BaseEscrowTemplate {
)) ))
} }
public async getAgreementIdsFromDDO(agreementId: string, ddo: DDO, consumer: string, from?: string) { public async getAgreementIdsFromDDO(
agreementId: string,
ddo: DDO,
consumer: string,
from?: string
) {
const { const {
computeExecutionConditionId, computeExecutionConditionId,
lockRewardConditionId, lockRewardConditionId,
@ -72,10 +88,19 @@ export class EscrowComputeExecutionTemplate extends BaseEscrowTemplate {
return zeroX(agreementId) return zeroX(agreementId)
} }
private async createFullAgreementData(agreementId: string, did: string, amount: number | string, consumer: string) { private async createFullAgreementData(
agreementId: string,
did: string,
amount: number | string,
consumer: string
) {
const { didRegistry, conditions } = this.ocean.keeper const { didRegistry, conditions } = this.ocean.keeper
const { computeExecutionCondition, lockRewardCondition, escrowReward } = conditions const {
computeExecutionCondition,
lockRewardCondition,
escrowReward
} = conditions
const publisher = await didRegistry.getDIDOwner(did) const publisher = await didRegistry.getDIDOwner(did)
@ -84,7 +109,11 @@ export class EscrowComputeExecutionTemplate extends BaseEscrowTemplate {
await escrowReward.getAddress(), await escrowReward.getAddress(),
amount amount
) )
const computeExecutionConditionId = await computeExecutionCondition.generateIdHash(agreementId, did, consumer) const computeExecutionConditionId = await computeExecutionCondition.generateIdHash(
agreementId,
did,
consumer
)
const escrowRewardId = await escrowReward.generateIdHash( const escrowRewardId = await escrowReward.generateIdHash(
agreementId, agreementId,
String(amount), String(amount),

View File

@ -87,9 +87,11 @@ export default class Account extends Instantiable {
* @return {Promise<number>} * @return {Promise<number>}
*/ */
public async getEtherBalance(): Promise<number> { public async getEtherBalance(): Promise<number> {
return this.web3.eth.getBalance(this.id, 'latest').then((balance: string): number => { return this.web3.eth
return new BigNumber(balance).toNumber() .getBalance(this.id, 'latest')
}) .then((balance: string): number => {
return new BigNumber(balance).toNumber()
})
} }
/** /**

View File

@ -14,7 +14,10 @@ import Keeper from '../keeper/Keeper'
import { Config } from '../models/Config' import { Config } from '../models/Config'
import { Instantiable, generateIntantiableConfigFromConfig } from '../Instantiable.abstract' import {
Instantiable,
generateIntantiableConfigFromConfig
} from '../Instantiable.abstract'
/** /**
* Main interface for Ocean Protocol. * Main interface for Ocean Protocol.

View File

@ -25,7 +25,9 @@ export class OceanAccounts extends Instantiable {
// retrieve eth accounts // retrieve eth accounts
const ethAccounts: string[] = await this.web3.eth.getAccounts() const ethAccounts: string[] = await this.web3.eth.getAccounts()
const accountPromises = ethAccounts.map(address => new Account(address, this.instanceConfig)) const accountPromises = ethAccounts.map(
address => new Account(address, this.instanceConfig)
)
return Promise.all(accountPromises) return Promise.all(accountPromises)
} }

View File

@ -21,7 +21,9 @@ export class OceanAgreements extends Instantiable {
* Returns the instance of OceanAgreements. * Returns the instance of OceanAgreements.
* @return {Promise<OceanAgreements>} * @return {Promise<OceanAgreements>}
*/ */
public static async getInstance(config: InstantiableConfig): Promise<OceanAgreements> { public static async getInstance(
config: InstantiableConfig
): Promise<OceanAgreements> {
const instance = new OceanAgreements() const instance = new OceanAgreements()
instance.setInstanceConfig(config) instance.setInstanceConfig(config)
instance.conditions = await OceanAgreementsConditions.getInstance(config) instance.conditions = await OceanAgreementsConditions.getInstance(config)
@ -42,12 +44,17 @@ export class OceanAgreements extends Instantiable {
* @param {Account} consumer Consumer account. * @param {Account} consumer Consumer account.
* @return {Promise<AgreementPrepareResult>} Agreement ID and signaturee. * @return {Promise<AgreementPrepareResult>} Agreement ID and signaturee.
*/ */
public async prepare(did: string, index: number, consumer: Account): Promise<AgreementPrepareResult> { public async prepare(
did: string,
index: number,
consumer: Account
): Promise<AgreementPrepareResult> {
const d: DID = DID.parse(did as string) const d: DID = DID.parse(did as string)
const ddo = await this.ocean.aquarius.retrieveDDO(d) const ddo = await this.ocean.aquarius.retrieveDDO(d)
const agreementId: string = zeroX(generateId()) const agreementId: string = zeroX(generateId())
const templateName = ddo.findServiceByType('access').attributes.serviceAgreementTemplate.contractName const templateName = ddo.findServiceByType('access').attributes
.serviceAgreementTemplate.contractName
const agreementConditionsIds = await this.ocean.keeper const agreementConditionsIds = await this.ocean.keeper
.getTemplateByName(templateName) .getTemplateByName(templateName)
.getAgreementIdsFromDDO(agreementId, ddo, consumer.getId(), consumer.getId()) .getAgreementIdsFromDDO(agreementId, ddo, consumer.getId(), consumer.getId())
@ -113,7 +120,8 @@ export class OceanAgreements extends Instantiable {
const d: DID = DID.parse(did) const d: DID = DID.parse(did)
const ddo = await this.ocean.aquarius.retrieveDDO(d) const ddo = await this.ocean.aquarius.retrieveDDO(d)
const templateName = ddo.findServiceById<'access'>(index).attributes.serviceAgreementTemplate.contractName const templateName = ddo.findServiceById<'access'>(index).attributes
.serviceAgreementTemplate.contractName
await this.ocean.keeper await this.ocean.keeper
.getTemplateByName(templateName) .getTemplateByName(templateName)
.createAgreementFromDDO(agreementId, ddo, consumer.getId(), publisher.getId()) .createAgreementFromDDO(agreementId, ddo, consumer.getId(), publisher.getId())
@ -127,13 +135,23 @@ export class OceanAgreements extends Instantiable {
* @param {boolean} extended Returns a complete status with dependencies. * @param {boolean} extended Returns a complete status with dependencies.
* @return {Promise<any>} * @return {Promise<any>}
*/ */
public async status(agreementId: string, extended?: false): Promise<{ [condition: string]: ConditionState }> public async status(
agreementId: string,
extended?: false
): Promise<{ [condition: string]: ConditionState }>
public async status(agreementId: string, extended: true): Promise<AgreementConditionsStatus> public async status(
agreementId: string,
extended: true
): Promise<AgreementConditionsStatus>
public async status(agreementId: string, extended: boolean = false) { public async status(agreementId: string, extended: boolean = false) {
const { templateId } = await this.ocean.keeper.agreementStoreManager.getAgreement(agreementId) const { templateId } = await this.ocean.keeper.agreementStoreManager.getAgreement(
const fullStatus = await this.ocean.keeper.getTemplateByAddress(templateId).getAgreementStatus(agreementId) agreementId
)
const fullStatus = await this.ocean.keeper
.getTemplateByAddress(templateId)
.getAgreementStatus(agreementId)
if (!fullStatus) { if (!fullStatus) {
return return

View File

@ -9,7 +9,9 @@ export class OceanAgreementsConditions extends Instantiable {
* Returns the instance of OceanAgreementsConditions. * Returns the instance of OceanAgreementsConditions.
* @return {Promise<OceanAgreementsConditions>} * @return {Promise<OceanAgreementsConditions>}
*/ */
public static async getInstance(config: InstantiableConfig): Promise<OceanAgreementsConditions> { public static async getInstance(
config: InstantiableConfig
): Promise<OceanAgreementsConditions> {
const instance = new OceanAgreementsConditions() const instance = new OceanAgreementsConditions()
instance.setInstanceConfig(config) instance.setInstanceConfig(config)
@ -23,11 +25,19 @@ export class OceanAgreementsConditions extends Instantiable {
* @param {number} amount Asset amount. * @param {number} amount Asset amount.
* @param {Account} from Account of sender. * @param {Account} from Account of sender.
*/ */
public async lockReward(agreementId: string, amount: number | string, from?: Account) { public async lockReward(
agreementId: string,
amount: number | string,
from?: Account
) {
const { lockRewardCondition, escrowReward } = this.ocean.keeper.conditions const { lockRewardCondition, escrowReward } = this.ocean.keeper.conditions
try { try {
await this.ocean.keeper.token.approve(lockRewardCondition.getAddress(), amount, from.getId()) await this.ocean.keeper.token.approve(
lockRewardCondition.getAddress(),
amount,
from.getId()
)
const receipt = await lockRewardCondition.fulfill( const receipt = await lockRewardCondition.fulfill(
agreementId, agreementId,
@ -49,11 +59,21 @@ export class OceanAgreementsConditions extends Instantiable {
* @param {string} grantee Consumer address. * @param {string} grantee Consumer address.
* @param {Account} from Account of sender. * @param {Account} from Account of sender.
*/ */
public async grantAccess(agreementId: string, did: string, grantee: string, from?: Account) { public async grantAccess(
agreementId: string,
did: string,
grantee: string,
from?: Account
) {
try { try {
const { accessSecretStoreCondition } = this.ocean.keeper.conditions const { accessSecretStoreCondition } = this.ocean.keeper.conditions
const receipt = await accessSecretStoreCondition.fulfill(agreementId, did, grantee, from && from.getId()) const receipt = await accessSecretStoreCondition.fulfill(
agreementId,
did,
grantee,
from && from.getId()
)
return !!receipt.events.Fulfilled return !!receipt.events.Fulfilled
} catch { } catch {
return false return false
@ -67,11 +87,21 @@ export class OceanAgreementsConditions extends Instantiable {
* @param {string} grantee Consumer address. * @param {string} grantee Consumer address.
* @param {Account} from Account of sender. * @param {Account} from Account of sender.
*/ */
public async grantServiceExecution(agreementId: string, did: string, grantee: string, from?: Account) { public async grantServiceExecution(
agreementId: string,
did: string,
grantee: string,
from?: Account
) {
try { try {
const { computeExecutionCondition } = this.ocean.keeper.conditions const { computeExecutionCondition } = this.ocean.keeper.conditions
const receipt = await computeExecutionCondition.fulfill(agreementId, did, grantee, from && from.getId()) const receipt = await computeExecutionCondition.fulfill(
agreementId,
did,
grantee,
from && from.getId()
)
return !!receipt.events.Fulfilled return !!receipt.events.Fulfilled
} catch { } catch {
return false return false
@ -100,9 +130,17 @@ export class OceanAgreementsConditions extends Instantiable {
from?: Account from?: Account
) { ) {
try { try {
const { escrowReward, accessSecretStoreCondition, lockRewardCondition } = this.ocean.keeper.conditions const {
escrowReward,
accessSecretStoreCondition,
lockRewardCondition
} = this.ocean.keeper.conditions
const conditionIdAccess = await accessSecretStoreCondition.generateIdHash(agreementId, did, consumer) const conditionIdAccess = await accessSecretStoreCondition.generateIdHash(
agreementId,
did,
consumer
)
const conditionIdLock = await lockRewardCondition.generateIdHash( const conditionIdLock = await lockRewardCondition.generateIdHash(
agreementId, agreementId,
escrowReward.getAddress(), escrowReward.getAddress(),

View File

@ -47,7 +47,9 @@ export class OceanAssets extends Instantiable {
* @return {Promise<DDO>} * @return {Promise<DDO>}
*/ */
public async resolve(did: string): Promise<DDO> { public async resolve(did: string): Promise<DDO> {
const { serviceEndpoint } = await this.ocean.keeper.didRegistry.getAttributesByDid(did) const {
serviceEndpoint
} = await this.ocean.keeper.didRegistry.getAttributesByDid(did)
return this.ocean.aquarius.retrieveDDOByUrl(serviceEndpoint) return this.ocean.aquarius.retrieveDDOByUrl(serviceEndpoint)
} }
@ -71,7 +73,11 @@ export class OceanAssets extends Instantiable {
this.logger.log('Encrypting files') this.logger.log('Encrypting files')
observer.next(CreateProgressStep.EncryptingFiles) observer.next(CreateProgressStep.EncryptingFiles)
const encryptedFiles = await this.ocean.secretStore.encrypt(did.getId(), metadata.main.files, publisher) const encryptedFiles = await this.ocean.secretStore.encrypt(
did.getId(),
metadata.main.files,
publisher
)
this.logger.log('Files encrypted') this.logger.log('Files encrypted')
observer.next(CreateProgressStep.FilesEncrypted) observer.next(CreateProgressStep.FilesEncrypted)
@ -145,7 +151,10 @@ export class OceanAssets extends Instantiable {
] ]
// Remove duplications // Remove duplications
.reverse() .reverse()
.filter(({ type }, i, list) => list.findIndex(({ type: t }) => t === type) === i) .filter(
({ type }, i, list) =>
list.findIndex(({ type: t }) => t === type) === i
)
.reverse() .reverse()
// Adding index // Adding index
.map(_ => ({ .map(_ => ({
@ -226,12 +235,16 @@ export class OceanAssets extends Instantiable {
const { serviceEndpoint } = accessService const { serviceEndpoint } = accessService
if (!serviceEndpoint) { if (!serviceEndpoint) {
throw new Error('Consume asset failed, service definition is missing the `serviceEndpoint`.') throw new Error(
'Consume asset failed, service definition is missing the `serviceEndpoint`.'
)
} }
this.logger.log('Consuming files') this.logger.log('Consuming files')
resultPath = resultPath ? `${resultPath}/datafile.${ddo.shortId()}.${serviceIndex}/` : undefined resultPath = resultPath
? `${resultPath}/datafile.${ddo.shortId()}.${serviceIndex}/`
: undefined
if (!useSecretStore) { if (!useSecretStore) {
await this.ocean.brizo.consumeService( await this.ocean.brizo.consumeService(
@ -251,7 +264,9 @@ export class OceanAssets extends Instantiable {
) )
const downloads = files const downloads = files
.filter(({ index: i }) => index === -1 || index === i) .filter(({ index: i }) => index === -1 || index === i)
.map(({ url, index: i }) => this.ocean.utils.fetch.downloadFile(url, resultPath, i)) .map(({ url, index: i }) =>
this.ocean.utils.fetch.downloadFile(url, resultPath, i)
)
await Promise.all(downloads) await Promise.all(downloads)
} }
this.logger.log('Files consumed') this.logger.log('Files consumed')
@ -270,7 +285,11 @@ export class OceanAssets extends Instantiable {
* @param {Account} consumer Consumer account. * @param {Account} consumer Consumer account.
* @return {Promise<string>} Returns Agreement ID * @return {Promise<string>} Returns Agreement ID
*/ */
public order(did: string, index: number, consumer: Account): SubscribablePromise<OrderProgressStep, string> { public order(
did: string,
index: number,
consumer: Account
): SubscribablePromise<OrderProgressStep, string> {
return new SubscribablePromise(async observer => { return new SubscribablePromise(async observer => {
const oceanAgreements = this.ocean.agreements const oceanAgreements = this.ocean.agreements
@ -278,7 +297,8 @@ export class OceanAssets extends Instantiable {
const ddo = await this.resolve(did) const ddo = await this.resolve(did)
const { keeper } = this.ocean const { keeper } = this.ocean
const templateName = ddo.findServiceByType('access').attributes.serviceAgreementTemplate.contractName const templateName = ddo.findServiceByType('access').attributes
.serviceAgreementTemplate.contractName
const template = keeper.getTemplateByName(templateName) const template = keeper.getTemplateByName(templateName)
const accessCondition = keeper.conditions.accessSecretStoreCondition const accessCondition = keeper.conditions.accessSecretStoreCondition
@ -293,10 +313,16 @@ export class OceanAssets extends Instantiable {
this.logger.log('Locking payment') this.logger.log('Locking payment')
const accessGranted = accessCondition.getConditionFulfilledEvent(agreementId).once() const accessGranted = accessCondition
.getConditionFulfilledEvent(agreementId)
.once()
observer.next(OrderProgressStep.LockingPayment) observer.next(OrderProgressStep.LockingPayment)
const paid = await oceanAgreements.conditions.lockReward(agreementId, attributes.main.price, consumer) const paid = await oceanAgreements.conditions.lockReward(
agreementId,
attributes.main.price,
consumer
)
observer.next(OrderProgressStep.LockedPayment) observer.next(OrderProgressStep.LockedPayment)
if (paid) { if (paid) {
@ -316,7 +342,14 @@ export class OceanAssets extends Instantiable {
observer.next(OrderProgressStep.CreatingAgreement) observer.next(OrderProgressStep.CreatingAgreement)
this.logger.log('Creating agreement') this.logger.log('Creating agreement')
await oceanAgreements.create(did, agreementId, index, undefined, consumer, consumer) await oceanAgreements.create(
did,
agreementId,
index,
undefined,
consumer,
consumer
)
this.logger.log('Agreement created') this.logger.log('Agreement created')
try { try {
@ -338,10 +371,15 @@ export class OceanAssets extends Instantiable {
const ddo = await this.resolve(did) const ddo = await this.resolve(did)
const checksum = ddo.getChecksum() const checksum = ddo.getChecksum()
const { creator, signatureValue } = ddo.proof const { creator, signatureValue } = ddo.proof
const signer = await this.ocean.utils.signature.verifyText(checksum, signatureValue) const signer = await this.ocean.utils.signature.verifyText(
checksum,
signatureValue
)
if (signer.toLowerCase() !== creator.toLowerCase()) { if (signer.toLowerCase() !== creator.toLowerCase()) {
this.logger.warn(`Owner of ${ddo.id} doesn't match. Expected ${creator} instead of ${signer}.`) this.logger.warn(
`Owner of ${ddo.id} doesn't match. Expected ${creator} instead of ${signer}.`
)
} }
return creator return creator
@ -362,7 +400,10 @@ export class OceanAssets extends Instantiable {
* @param {string} newOwner Ethereum address of the new owner of the DID. * @param {string} newOwner Ethereum address of the new owner of the DID.
* @return {Promise<TransactionReceipt>} Returns Web3 transaction receipt. * @return {Promise<TransactionReceipt>} Returns Web3 transaction receipt.
*/ */
public async transferOwnership(did: string, newOwner: string): Promise<TransactionReceipt> { public async transferOwnership(
did: string,
newOwner: string
): Promise<TransactionReceipt> {
const owner = await this.ocean.assets.owner(did) const owner = await this.ocean.assets.owner(did)
return this.ocean.keeper.didRegistry.transferDIDOwnership(did, newOwner, owner) return this.ocean.keeper.didRegistry.transferDIDOwnership(did, newOwner, owner)
} }
@ -373,9 +414,11 @@ export class OceanAssets extends Instantiable {
* @return {Promise<string[]>} List of DIDs. * @return {Promise<string[]>} List of DIDs.
*/ */
public async consumerAssets(consumer: string): Promise<string[]> { public async consumerAssets(consumer: string): Promise<string[]> {
return (await this.ocean.keeper.conditions.accessSecretStoreCondition.getGrantedDidByConsumer(consumer)).map( return (
({ did }) => did await this.ocean.keeper.conditions.accessSecretStoreCondition.getGrantedDidByConsumer(
) consumer
)
).map(({ did }) => did)
} }
/** /**

View File

@ -30,7 +30,11 @@ export class OceanAuth extends Instantiable {
const message = `${this.getMessage()}\n${time}` const message = `${this.getMessage()}\n${time}`
try { try {
const signature = await this.ocean.utils.signature.signText(message, account.getId(), account.getPassword()) const signature = await this.ocean.utils.signature.signText(
message,
account.getId(),
account.getPassword()
)
return `${signature}-${time}` return `${signature}-${time}`
} catch { } catch {
@ -53,7 +57,9 @@ export class OceanAuth extends Instantiable {
return `0x${'0'.repeat(40)}` return `0x${'0'.repeat(40)}`
} }
return this.web3.utils.toChecksumAddress(await this.ocean.utils.signature.verifyText(message, signature)) return this.web3.utils.toChecksumAddress(
await this.ocean.utils.signature.verifyText(message, signature)
)
} }
/** /**
@ -121,7 +127,9 @@ export class OceanAuth extends Instantiable {
try { try {
localStorage.getItem('') localStorage.getItem('')
} catch { } catch {
throw new Error('LocalStorage is not supported. This feature is only available on browsers.') throw new Error(
'LocalStorage is not supported. This feature is only available on browsers.'
)
} }
return localStorage return localStorage
} }

View File

@ -13,7 +13,9 @@ export class OceanSecretStore extends Instantiable {
* Returns the instance of OceanSecretStore. * Returns the instance of OceanSecretStore.
* @return {Promise<OceanSecretStore>} * @return {Promise<OceanSecretStore>}
*/ */
public static async getInstance(config: InstantiableConfig): Promise<OceanSecretStore> { public static async getInstance(
config: InstantiableConfig
): Promise<OceanSecretStore> {
const instance = new OceanSecretStore() const instance = new OceanSecretStore()
instance.setInstanceConfig(config) instance.setInstanceConfig(config)
@ -28,12 +30,25 @@ export class OceanSecretStore extends Instantiable {
* @param {string} publisher Publisher account. * @param {string} publisher Publisher account.
* @return {Promise<string>} Encrypted text. * @return {Promise<string>} Encrypted text.
*/ */
public async encrypt(did: string, document: any, publisher: Account): Promise<string> { public async encrypt(
did: string,
document: any,
publisher: Account
): Promise<string> {
const signature = const signature =
(await publisher.getToken()) || (await publisher.getToken()) ||
(await this.ocean.utils.signature.signText(noDidPrefixed(did), publisher.getId(), publisher.getPassword())) (await this.ocean.utils.signature.signText(
noDidPrefixed(did),
publisher.getId(),
publisher.getPassword()
))
return this.ocean.brizo.encrypt(noDidPrefixed(did), signature, document, publisher.getId()) return this.ocean.brizo.encrypt(
noDidPrefixed(did),
signature,
document,
publisher.getId()
)
} }
/** /**
@ -44,8 +59,16 @@ export class OceanSecretStore extends Instantiable {
* @param {string} consumer cONSUMER account. * @param {string} consumer cONSUMER account.
* @return {Promise<string>} Encrypted text. * @return {Promise<string>} Encrypted text.
*/ */
public async decrypt(did: string, content: string, consumer?: Account, secretStoreUrl?: string): Promise<any> { public async decrypt(
return this.getSecretStoreByAccount(consumer, secretStoreUrl).decryptDocument(noDidPrefixed(did), content) did: string,
content: string,
consumer?: Account,
secretStoreUrl?: string
): Promise<any> {
return this.getSecretStoreByAccount(consumer, secretStoreUrl).decryptDocument(
noDidPrefixed(did),
content
)
} }
private getSecretStoreByAccount(account: Account, secretStoreUrl?: string) { private getSecretStoreByAccount(account: Account, secretStoreUrl?: string) {

View File

@ -19,7 +19,10 @@ export class ServiceAgreement extends Instantiable {
consumer: Account consumer: Account
): Promise<string> { ): Promise<string> {
const service = ddo.findServiceById<'access'>(index) const service = ddo.findServiceById<'access'>(index)
const timelockValues: number[] = this.getTimeValuesFromService(service, 'timelock') const timelockValues: number[] = this.getTimeValuesFromService(
service,
'timelock'
)
const timeoutValues: number[] = this.getTimeValuesFromService(service, 'timeout') const timeoutValues: number[] = this.getTimeValuesFromService(service, 'timeout')
if (!service.templateId) { if (!service.templateId) {
@ -83,7 +86,10 @@ export class ServiceAgreement extends Instantiable {
return this.web3.utils.soliditySha3(...args) return this.web3.utils.soliditySha3(...args)
} }
private getTimeValuesFromService(service: ServiceAccess, type: 'timeout' | 'timelock'): number[] { private getTimeValuesFromService(
service: ServiceAccess,
type: 'timeout' | 'timelock'
): number[] {
const timeoutValues: number[] = service.attributes.serviceAgreementTemplate.conditions.map( const timeoutValues: number[] = service.attributes.serviceAgreementTemplate.conditions.map(
(condition: ServiceAgreementTemplateCondition) => condition[type] (condition: ServiceAgreementTemplateCondition) => condition[type]
) )

View File

@ -6,8 +6,15 @@ export class SignatureUtils extends Instantiable {
this.setInstanceConfig(config) this.setInstanceConfig(config)
} }
public async signText(text: string, publicKey: string, password?: string): Promise<string> { public async signText(
const isMetaMask = this.web3 && this.web3.currentProvider && (this.web3.currentProvider as any).isMetaMask text: string,
publicKey: string,
password?: string
): Promise<string> {
const isMetaMask =
this.web3 &&
this.web3.currentProvider &&
(this.web3.currentProvider as any).isMetaMask
try { try {
return await this.web3.eth.personal.sign(text, publicKey, password) return await this.web3.eth.personal.sign(text, publicKey, password)
} catch (e) { } catch (e) {

View File

@ -43,14 +43,20 @@ export class WebServiceConnector extends Instantiable {
}) })
} }
public async downloadFile(url: string, destination?: string, index?: number): Promise<string> { public async downloadFile(
url: string,
destination?: string,
index?: number
): Promise<string> {
const response = await this.get(url) const response = await this.get(url)
if (!response.ok) { if (!response.ok) {
throw new Error('Response error.') throw new Error('Response error.')
} }
let filename: string let filename: string
try { try {
filename = response.headers.get('content-disposition').match(/attachment;filename=(.+)/)[1] filename = response.headers
.get('content-disposition')
.match(/attachment;filename=(.+)/)[1]
} catch { } catch {
try { try {
filename = url.split('/').pop() filename = url.split('/').pop()

View File

@ -4,7 +4,11 @@ import { LoggerInstance } from './Logger'
export const zeroX = (input: string) => zeroXTransformer(input, true) export const zeroX = (input: string) => zeroXTransformer(input, true)
export const noZeroX = (input: string) => zeroXTransformer(input, false) export const noZeroX = (input: string) => zeroXTransformer(input, false)
export function zeroXTransformer(input: string = '', zeroOutput: boolean) { export function zeroXTransformer(input: string = '', zeroOutput: boolean) {
const { valid, output } = inputMatch(input, /^(?:0x)*([a-f0-9]+)$/i, 'zeroXTransformer') const { valid, output } = inputMatch(
input,
/^(?:0x)*([a-f0-9]+)$/i,
'zeroXTransformer'
)
return (zeroOutput && valid ? '0x' : '') + output return (zeroOutput && valid ? '0x' : '') + output
} }
@ -12,7 +16,11 @@ export function zeroXTransformer(input: string = '', zeroOutput: boolean) {
export const didPrefixed = (input: string) => didTransformer(input, true) export const didPrefixed = (input: string) => didTransformer(input, true)
export const noDidPrefixed = (input: string) => didTransformer(input, false) export const noDidPrefixed = (input: string) => didTransformer(input, false)
export function didTransformer(input: string = '', prefixOutput: boolean) { export function didTransformer(input: string = '', prefixOutput: boolean) {
const { valid, output } = inputMatch(input, /^(?:0x|did:op:)*([a-f0-9]{64})$/i, 'didTransformer') const { valid, output } = inputMatch(
input,
/^(?:0x|did:op:)*([a-f0-9]{64})$/i,
'didTransformer'
)
return (prefixOutput && valid ? 'did:op:' : '') + output return (prefixOutput && valid ? 'did:op:' : '') + output
} }
@ -20,7 +28,11 @@ export function didTransformer(input: string = '', prefixOutput: boolean) {
export const didZeroX = (input: string) => zeroX(didTransformer(input, false)) export const didZeroX = (input: string) => zeroX(didTransformer(input, false))
// Shared functions // Shared functions
function inputMatch(input: string, regexp: RegExp, conversorName: string): { valid: boolean; output: string } { function inputMatch(
input: string,
regexp: RegExp,
conversorName: string
): { valid: boolean; output: string } {
if (typeof input !== 'string') { if (typeof input !== 'string') {
LoggerInstance.debug('Not input string:') LoggerInstance.debug('Not input string:')
LoggerInstance.debug(input) LoggerInstance.debug(input)

View File

@ -1,5 +1,8 @@
import { DDO } from '../ddo/DDO' import { DDO } from '../ddo/DDO'
import { ServiceAgreementTemplateCondition, ServiceAgreementTemplateParameter } from '../ddo/ServiceAgreementTemplate' import {
ServiceAgreementTemplateCondition,
ServiceAgreementTemplateParameter
} from '../ddo/ServiceAgreementTemplate'
function fillParameterWithDDO( function fillParameterWithDDO(
parameter: ServiceAgreementTemplateParameter, parameter: ServiceAgreementTemplateParameter,

View File

@ -7,7 +7,11 @@ export class SubscribableObserver<T, P> {
onError?: (error: any) => void onError?: (error: any) => void
}>() }>()
public subscribe(onNext?: (next: T) => void, onComplete?: (complete: P) => void, onError?: (error: any) => void) { public subscribe(
onNext?: (next: T) => void,
onComplete?: (complete: P) => void,
onError?: (error: any) => void
) {
if (this.completed) { if (this.completed) {
throw new Error('Observer completed.') throw new Error('Observer completed.')
} }

View File

@ -17,7 +17,12 @@ describe('Aquarius', () => {
let ocean: Ocean let ocean: Ocean
let aquarius: Aquarius let aquarius: Aquarius
/* eslint-disable @typescript-eslint/camelcase */ /* eslint-disable @typescript-eslint/camelcase */
const getResults = (results: DDO[], page = 0, total_pages = 1, total_results = 1) => ({ const getResults = (
results: DDO[],
page = 0,
total_pages = 1,
total_results = 1
) => ({
results, results,
page, page,
total_pages, total_pages,

View File

@ -54,7 +54,8 @@ describe('DDO', () => {
}, },
{ {
type: 'HubService', type: 'HubService',
serviceEndpoint: 'https://hub.example.com/.identity/did:op:0123456789abcdef/' serviceEndpoint:
'https://hub.example.com/.identity/did:op:0123456789abcdef/'
}, },
{ {
type: 'MessagingService', type: 'MessagingService',
@ -87,7 +88,8 @@ describe('DDO', () => {
{ {
type: 'metadata', type: 'metadata',
index: 0, index: 0,
serviceEndpoint: 'http://myaquarius.org/api/v1/provider/assets/metadata/{did}', serviceEndpoint:
'http://myaquarius.org/api/v1/provider/assets/metadata/{did}',
attributes: { attributes: {
main: { main: {
name: 'UK Weather information 2011', name: 'UK Weather information 2011',
@ -103,7 +105,8 @@ describe('DDO', () => {
checksum: 'efb2c764274b745f5fc37f97c6b0e761', checksum: 'efb2c764274b745f5fc37f97c6b0e761',
contentLength: '4535431', contentLength: '4535431',
contentType: 'application/json', contentType: 'application/json',
resourceId: 'access-log2018-02-13-15-17-29-18386C502CAEA932' resourceId:
'access-log2018-02-13-15-17-29-18386C502CAEA932'
}, },
{ {
index: 1, index: 1,
@ -123,9 +126,11 @@ describe('DDO', () => {
schema: 'Binary Voting' schema: 'Binary Voting'
}, },
additionalInformation: { additionalInformation: {
description: 'Weather information of UK including temperature and humidity', description:
'Weather information of UK including temperature and humidity',
copyrightHolder: 'Met Office', copyrightHolder: 'Met Office',
workExample: '423432fsd,51.509865,-0.118092,2011-01-01T10:55:11+00:00,7.2,68', workExample:
'423432fsd,51.509865,-0.118092,2011-01-01T10:55:11+00:00,7.2,68',
links: [ links: [
{ {
sample1: sample1:
@ -235,7 +240,10 @@ describe('DDO', () => {
const ddo = new DDO(testDDO) const ddo = new DDO(testDDO)
const checksum = ddo.getChecksum() const checksum = ddo.getChecksum()
assert.equal(checksum, '0x15f27a7a3c7b15d2b06dec7347c6b8da168adddd7df51a8ebbbe87b59b80049b') assert.equal(
checksum,
'0x15f27a7a3c7b15d2b06dec7347c6b8da168adddd7df51a8ebbbe87b59b80049b'
)
}) })
}) })

View File

@ -22,7 +22,9 @@ describe('ContractEvent', () => {
describe('#subscribe()', () => { describe('#subscribe()', () => {
it('should be able to listen to events', async () => { it('should be able to listen to events', async () => {
const event = eventHandler.getEvent(ocean.keeper.token, 'Transfer', { to: account }) const event = eventHandler.getEvent(ocean.keeper.token, 'Transfer', {
to: account
})
let validResolve = false let validResolve = false
let subscription: ContractEventSubscription let subscription: ContractEventSubscription

View File

@ -21,7 +21,13 @@ describe('DIDRegistry', () => {
const ownerAccount: Account = (await ocean.accounts.list())[0] const ownerAccount: Account = (await ocean.accounts.list())[0]
const did = generateId() const did = generateId()
const data = 'my nice provider, is nice' const data = 'my nice provider, is nice'
const receipt = await didRegistry.registerAttribute(did, `0123456789abcdef`, [], data, ownerAccount.getId()) const receipt = await didRegistry.registerAttribute(
did,
`0123456789abcdef`,
[],
data,
ownerAccount.getId()
)
assert(receipt.status) assert(receipt.status)
assert(receipt.events.DIDAttributeRegistered) assert(receipt.events.DIDAttributeRegistered)
}) })
@ -32,7 +38,13 @@ describe('DIDRegistry', () => {
{ {
// register the first attribute // register the first attribute
const data = 'my nice provider, is nice' const data = 'my nice provider, is nice'
await didRegistry.registerAttribute(did, '0123456789abcdef', [], data, ownerAccount.getId()) await didRegistry.registerAttribute(
did,
'0123456789abcdef',
[],
data,
ownerAccount.getId()
)
} }
{ {
// register the second attribute with the same did // register the second attribute with the same did
@ -55,11 +67,21 @@ describe('DIDRegistry', () => {
const ownerAccount: Account = (await ocean.accounts.list())[0] const ownerAccount: Account = (await ocean.accounts.list())[0]
const did = generateId() const did = generateId()
const data = 'my nice provider, is nice' const data = 'my nice provider, is nice'
await didRegistry.registerAttribute(did, '0123456789abcdef', [], data, ownerAccount.getId()) await didRegistry.registerAttribute(
did,
'0123456789abcdef',
[],
data,
ownerAccount.getId()
)
const owner = await didRegistry.getDIDOwner(did) const owner = await didRegistry.getDIDOwner(did)
assert.equal(owner, ownerAccount.getId(), `Got ${owner} but expected ${ownerAccount.getId()}`) assert.equal(
owner,
ownerAccount.getId(),
`Got ${owner} but expected ${ownerAccount.getId()}`
)
}) })
it('should get 0x0 for a not registered did', async () => { it('should get 0x0 for a not registered did', async () => {
@ -74,15 +96,29 @@ describe('DIDRegistry', () => {
const ownerAccount: Account = (await ocean.accounts.list())[0] const ownerAccount: Account = (await ocean.accounts.list())[0]
const did = generateId() const did = generateId()
const data = 'my nice provider, is nice' const data = 'my nice provider, is nice'
await didRegistry.registerAttribute(did, '0123456789abcdef', [], data, ownerAccount.getId()) await didRegistry.registerAttribute(
did,
'0123456789abcdef',
[],
data,
ownerAccount.getId()
)
// transfer // transfer
const newOwnerAccount: Account = (await ocean.accounts.list())[1] const newOwnerAccount: Account = (await ocean.accounts.list())[1]
await didRegistry.transferDIDOwnership(did, newOwnerAccount.getId(), ownerAccount.getId()) await didRegistry.transferDIDOwnership(
did,
newOwnerAccount.getId(),
ownerAccount.getId()
)
// check // check
const newOwner = await didRegistry.getDIDOwner(did) const newOwner = await didRegistry.getDIDOwner(did)
assert.equal(newOwner, newOwnerAccount.getId(), `Got ${newOwner} but expected ${newOwnerAccount.getId()}`) assert.equal(
newOwner,
newOwnerAccount.getId(),
`Got ${newOwner} but expected ${newOwnerAccount.getId()}`
)
}) })
}) })
}) })

View File

@ -25,23 +25,33 @@ export default class TestContractHandler extends ContractHandler {
Logger.log('Trying to deploy contracts') Logger.log('Trying to deploy contracts')
// Libraries // Libraries
const epochLibrary = await TestContractHandler.deployContract('EpochLibrary', deployerAddress) const epochLibrary = await TestContractHandler.deployContract(
const didRegistryLibrary = await TestContractHandler.deployContract('DIDRegistryLibrary', deployerAddress) 'EpochLibrary',
deployerAddress
)
const didRegistryLibrary = await TestContractHandler.deployContract(
'DIDRegistryLibrary',
deployerAddress
)
// Contracts // Contracts
const token = await TestContractHandler.deployContract('OceanToken', deployerAddress, [ const token = await TestContractHandler.deployContract(
'OceanToken',
deployerAddress, deployerAddress,
deployerAddress [deployerAddress, deployerAddress]
]) )
const dispenser = await TestContractHandler.deployContract('Dispenser', deployerAddress, [ const dispenser = await TestContractHandler.deployContract(
token.options.address, 'Dispenser',
deployerAddress deployerAddress,
]) [token.options.address, deployerAddress]
)
// Add dispenser as Token minter // Add dispenser as Token minter
if (!token.$initialized) { if (!token.$initialized) {
await token.methods.addMinter(dispenser.options.address).send({ from: deployerAddress }) await token.methods
.addMinter(dispenser.options.address)
.send({ from: deployerAddress })
} }
const didRegistry = await TestContractHandler.deployContract( const didRegistry = await TestContractHandler.deployContract(
@ -54,9 +64,11 @@ export default class TestContractHandler extends ContractHandler {
) )
// Managers // Managers
const templateStoreManager = await TestContractHandler.deployContract('TemplateStoreManager', deployerAddress, [ const templateStoreManager = await TestContractHandler.deployContract(
deployerAddress 'TemplateStoreManager',
]) deployerAddress,
[deployerAddress]
)
const conditionStoreManager = await TestContractHandler.deployContract( const conditionStoreManager = await TestContractHandler.deployContract(
'ConditionStoreManager', 'ConditionStoreManager',
deployerAddress, deployerAddress,
@ -77,33 +89,49 @@ export default class TestContractHandler extends ContractHandler {
) )
// Conditions // Conditions
const lockRewardCondition = await TestContractHandler.deployContract('LockRewardCondition', deployerAddress, [ const lockRewardCondition = await TestContractHandler.deployContract(
'LockRewardCondition',
deployerAddress, deployerAddress,
conditionStoreManager.options.address, [
token.options.address deployerAddress,
]) conditionStoreManager.options.address,
token.options.address
]
)
const accessSecretStoreCondition = await TestContractHandler.deployContract( const accessSecretStoreCondition = await TestContractHandler.deployContract(
'AccessSecretStoreCondition', 'AccessSecretStoreCondition',
deployerAddress, deployerAddress,
[deployerAddress, conditionStoreManager.options.address, agreementStoreManager.options.address] [
deployerAddress,
conditionStoreManager.options.address,
agreementStoreManager.options.address
]
) )
// Conditions rewards // Conditions rewards
const escrowReward = await TestContractHandler.deployContract('EscrowReward', deployerAddress, [ const escrowReward = await TestContractHandler.deployContract(
'EscrowReward',
deployerAddress, deployerAddress,
conditionStoreManager.options.address, [
token.options.address deployerAddress,
]) conditionStoreManager.options.address,
token.options.address
]
)
// Templates // Templates
await TestContractHandler.deployContract('EscrowAccessSecretStoreTemplate', deployerAddress, [ await TestContractHandler.deployContract(
'EscrowAccessSecretStoreTemplate',
deployerAddress, deployerAddress,
agreementStoreManager.options.address, [
didRegistry.options.address, deployerAddress,
accessSecretStoreCondition.options.address, agreementStoreManager.options.address,
lockRewardCondition.options.address, didRegistry.options.address,
escrowReward.options.address accessSecretStoreCondition.options.address,
]) lockRewardCondition.options.address,
escrowReward.options.address
]
)
} }
private static async deployContract( private static async deployContract(
@ -151,7 +179,10 @@ export default class TestContractHandler extends ContractHandler {
contractInstance = await tempContract contractInstance = await tempContract
.deploy({ .deploy({
data: TestContractHandler.replaceTokens(artifact.bytecode.toString(), tokens), data: TestContractHandler.replaceTokens(
artifact.bytecode.toString(),
tokens
),
arguments: isZos ? undefined : args arguments: isZos ? undefined : args
}) })
.send(sendConfig) .send(sendConfig)
@ -162,16 +193,26 @@ export default class TestContractHandler extends ContractHandler {
ContractHandler.setContract(name, where, contractInstance) ContractHandler.setContract(name, where, 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 args', JSON.stringify(args, null, 2), err.message) Logger.error(
'Deployment failed for',
name,
'with args',
JSON.stringify(args, null, 2),
err.message
)
throw err throw err
} }
return contractInstance return contractInstance
} }
private static replaceTokens(bytecode: string, tokens: { [name: string]: string }): string { private static replaceTokens(
bytecode: string,
tokens: { [name: string]: string }
): string {
return Object.entries(tokens).reduce( return Object.entries(tokens).reduce(
(acc, [token, address]) => acc.replace(new RegExp(`_+${token}_+`, 'g'), address.substr(2)), (acc, [token, address]) =>
acc.replace(new RegExp(`_+${token}_+`, 'g'), address.substr(2)),
bytecode bytecode
) )
} }

View File

@ -13,7 +13,8 @@ describe('AccessSecretStoreCondition', () => {
before(async () => { before(async () => {
await TestContractHandler.prepareContracts() await TestContractHandler.prepareContracts()
condition = (await Ocean.getInstance(config)).keeper.conditions.accessSecretStoreCondition condition = (await Ocean.getInstance(config)).keeper.conditions
.accessSecretStoreCondition
}) })
describe('#hashValues()', () => { describe('#hashValues()', () => {

View File

@ -21,13 +21,27 @@ describe('EscrowReward', () => {
await TestContractHandler.prepareContracts() await TestContractHandler.prepareContracts()
condition = keeper.conditions.escrowReward condition = keeper.conditions.escrowReward
lockCondition = await keeper.conditions.lockRewardCondition.generateIdHash(agreementId, publisher, amount) lockCondition = await keeper.conditions.lockRewardCondition.generateIdHash(
releaseCondition = await keeper.conditions.accessSecretStoreCondition.generateIdHash(agreementId, did, consumer) agreementId,
publisher,
amount
)
releaseCondition = await keeper.conditions.accessSecretStoreCondition.generateIdHash(
agreementId,
did,
consumer
)
}) })
describe('#hashValues()', () => { describe('#hashValues()', () => {
it('should hash the values', async () => { it('should hash the values', async () => {
const hash = await condition.hashValues(amount, consumer, publisher, lockCondition, releaseCondition) const hash = await condition.hashValues(
amount,
consumer,
publisher,
lockCondition,
releaseCondition
)
assert.match(hash, /^0x[a-f0-9]{64}$/i) assert.match(hash, /^0x[a-f0-9]{64}$/i)
}) })
@ -35,7 +49,13 @@ describe('EscrowReward', () => {
describe('#generateId()', () => { describe('#generateId()', () => {
it('should generate an ID', async () => { it('should generate an ID', async () => {
const hash = await condition.hashValues(amount, consumer, publisher, lockCondition, releaseCondition) const hash = await condition.hashValues(
amount,
consumer,
publisher,
lockCondition,
releaseCondition
)
const id = await condition.generateId(agreementId, hash) const id = await condition.generateId(agreementId, hash)
assert.match(id, /^0x[a-f0-9]{64}$/i) assert.match(id, /^0x[a-f0-9]{64}$/i)

View File

@ -13,7 +13,8 @@ describe('LockRewardCondition', () => {
before(async () => { before(async () => {
await TestContractHandler.prepareContracts() await TestContractHandler.prepareContracts()
condition = (await Ocean.getInstance(config)).keeper.conditions.lockRewardCondition condition = (await Ocean.getInstance(config)).keeper.conditions
.lockRewardCondition
}) })
describe('#hashValues()', () => { describe('#hashValues()', () => {

View File

@ -15,7 +15,9 @@ export default class WebServiceConnectorMock extends WebServiceConnector {
return this.returnData ? this.returnData : {} return this.returnData ? this.returnData : {}
}, },
text: () => { text: () => {
return this.returnData ? JSON.stringify(this.returnData.toString()) : '' return this.returnData
? JSON.stringify(this.returnData.toString())
: ''
} }
}) })
}) })

View File

@ -39,7 +39,10 @@ describe('Account', () => {
const balance = await account.getEtherBalance() const balance = await account.getEtherBalance()
const web3 = Web3Provider.getWeb3() const web3 = Web3Provider.getWeb3()
assert(Number(web3.utils.toWei('100', 'ether')) === balance, `ether did not match ${balance}`) assert(
Number(web3.utils.toWei('100', 'ether')) === balance,
`ether did not match ${balance}`
)
}) })
}) })
@ -49,7 +52,10 @@ describe('Account', () => {
const balance = await account.getBalance() const balance = await account.getBalance()
const web3 = Web3Provider.getWeb3() const web3 = Web3Provider.getWeb3()
assert(Number(web3.utils.toWei('100', 'ether')) === balance.eth, `ether did not match ${balance.eth}`) assert(
Number(web3.utils.toWei('100', 'ether')) === balance.eth,
`ether did not match ${balance.eth}`
)
assert(balance.ocn === 0, `tokens did not match ${balance.ocn}`) assert(balance.ocn === 0, `tokens did not match ${balance.ocn}`)
}) })
}) })

View File

@ -27,7 +27,11 @@ describe('OceanSecretStore', () => {
describe('#encrypt()', () => { describe('#encrypt()', () => {
it('should encrypt a content', async () => { it('should encrypt a content', async () => {
const secretStoreEncryptSpy = spy.on(ocean.brizo, 'encrypt', () => 'encryptedResult') const secretStoreEncryptSpy = spy.on(
ocean.brizo,
'encrypt',
() => 'encryptedResult'
)
const result = await oceanSecretStore.encrypt(did, 'test', accounts[0]) const result = await oceanSecretStore.encrypt(did, 'test', accounts[0])

View File

@ -47,9 +47,16 @@ describe('SignatureUtils', () => {
describe('#verifyText', () => { describe('#verifyText', () => {
it('should recover the privateKey of a signed message', async () => { it('should recover the privateKey of a signed message', async () => {
const personalRecoverSpy = spy.on(web3.eth.personal, 'ecRecover', () => publicKey) const personalRecoverSpy = spy.on(
web3.eth.personal,
'ecRecover',
() => publicKey
)
const verifiedPublicKey = await ocean.utils.signature.verifyText(text, signature) const verifiedPublicKey = await ocean.utils.signature.verifyText(
text,
signature
)
assert.equal(publicKey, verifiedPublicKey) assert.equal(publicKey, verifiedPublicKey)
expect(personalRecoverSpy).to.have.been.called.with(text, signature) expect(personalRecoverSpy).to.have.been.called.with(text, signature)

View File

@ -1,5 +1,10 @@
import { assert } from 'chai' import { assert } from 'chai'
import { zeroX, noZeroX, didPrefixed, noDidPrefixed } from '../../src/utils/ConversionTypeHelpers' import {
zeroX,
noZeroX,
didPrefixed,
noDidPrefixed
} from '../../src/utils/ConversionTypeHelpers'
describe('ConversionTypeHelpers', () => { describe('ConversionTypeHelpers', () => {
describe('#zeroXTransformer()', () => { describe('#zeroXTransformer()', () => {