diff --git a/docs/classes/IExecOrderbookModule.md b/docs/classes/IExecOrderbookModule.md index 83732af5..72130f01 100644 --- a/docs/classes/IExecOrderbookModule.md +++ b/docs/classes/IExecOrderbookModule.md @@ -71,7 +71,7 @@ current IExecConfig ### fetchAppOrderbook -▸ **fetchAppOrderbook**(`appAddress`, `options?`): `Promise`<[`PaginableOrders`](../interfaces/internal_.PaginableOrders.md)<[`PublishedApporder`](../interfaces/internal_.PublishedApporder.md)\>\> +▸ **fetchAppOrderbook**(`appAddressOrOptions`, `options?`): `Promise`<[`PaginableOrders`](../interfaces/internal_.PaginableOrders.md)<[`PublishedApporder`](../interfaces/internal_.PublishedApporder.md)\>\> find the cheapest orders for the specified app. @@ -88,8 +88,8 @@ console.log('total orders:', count); | Name | Type | Description | | :------ | :------ | :------ | -| `appAddress` | `string` | - | -| `options?` | `Object` | - | +| `appAddressOrOptions` | `string` \| { `app?`: `string` ; `appOwner?`: `string` ; `dataset?`: `string` ; `isDatasetStrict?`: `boolean` ; `isRequesterStrict?`: `boolean` ; `isWorkerpoolStrict?`: `boolean` ; `maxTag?`: [`Tag`](../modules.md#tag) \| `string`[] ; `minTag?`: [`Tag`](../modules.md#tag) \| `string`[] ; `minVolume?`: [`BNish`](../modules.md#bnish) ; `page?`: `number` ; `pageSize?`: `number` ; `requester?`: `string` ; `workerpool?`: `string` } | - | +| `options?` | `Object` | **`Deprecated`** use first parameter instead migration: replace `fetchAppOrderbook(appAddress, options)` by `fetchAppOrderbook({ app: appAddress, ...options })` | | `options.dataset?` | `string` | include orders restricted to specified dataset (use `'any'` to include any dataset) | | `options.isDatasetStrict?` | `boolean` | filters out orders allowing “any” dataset (default: `false`) | | `options.isRequesterStrict?` | `boolean` | filters out orders allowing “any” requester (default: `false`) | @@ -135,7 +135,7 @@ ___ ### fetchDatasetOrderbook -▸ **fetchDatasetOrderbook**(`datasetAddress`, `options?`): `Promise`<[`PaginableOrders`](../interfaces/internal_.PaginableOrders.md)<[`PublishedDatasetorder`](../interfaces/internal_.PublishedDatasetorder.md)\>\> +▸ **fetchDatasetOrderbook**(`datasetAddressOrOptions`, `options?`): `Promise`<[`PaginableOrders`](../interfaces/internal_.PaginableOrders.md)<[`PublishedDatasetorder`](../interfaces/internal_.PublishedDatasetorder.md)\>\> find the cheapest orders for the specified dataset. @@ -152,8 +152,8 @@ console.log('total orders:', count); | Name | Type | Description | | :------ | :------ | :------ | -| `datasetAddress` | `string` | - | -| `options?` | `Object` | - | +| `datasetAddressOrOptions` | `string` \| { `app?`: `string` ; `dataset?`: `string` ; `datasetOwner?`: `string` ; `isAppStrict?`: `boolean` ; `isRequesterStrict?`: `boolean` ; `isWorkerpoolStrict?`: `boolean` ; `maxTag?`: [`Tag`](../modules.md#tag) \| `string`[] ; `minTag?`: [`Tag`](../modules.md#tag) \| `string`[] ; `minVolume?`: [`BNish`](../modules.md#bnish) ; `page?`: `number` ; `pageSize?`: `number` ; `requester?`: `string` ; `workerpool?`: `string` } | - | +| `options?` | `Object` | **`Deprecated`** use first parameter instead migration: replace `fetchDatasetOrderbook(datasetAddress, options)` by `fetchDatasetOrderbook({ dataset: datasetAddress, ...options })` | | `options.app?` | `string` | include orders restricted to specified app (use `'any'` to include any app) | | `options.isAppStrict?` | `boolean` | filters out orders allowing “any” app (default: `false`) | | `options.isRequesterStrict?` | `boolean` | filters out orders allowing “any” requester (default: `false`) | diff --git a/src/cli/cmd/iexec-app.js b/src/cli/cmd/iexec-app.js index cf0b1689..4e19fc3a 100644 --- a/src/cli/cmd/iexec-app.js +++ b/src/cli/cmd/iexec-app.js @@ -775,8 +775,8 @@ run const { orders } = await fetchAppOrderbook( chain.contracts, getPropertyFormChain(chain, 'iexecGateway'), - app, { + app, requester, ...(useDataset && { dataset }), ...(runOnWorkerpool && { workerpool }), @@ -819,8 +819,8 @@ run const { orders } = await fetchDatasetOrderbook( chain.contracts, getPropertyFormChain(chain, 'iexecGateway'), - dataset, { + dataset, app, requester, ...(runOnWorkerpool && { workerpool }), diff --git a/src/cli/cmd/iexec-orderbook.js b/src/cli/cmd/iexec-orderbook.js index 6c07d592..2350db6d 100644 --- a/src/cli/cmd/iexec-orderbook.js +++ b/src/cli/cmd/iexec-orderbook.js @@ -66,8 +66,8 @@ orderbookApp const request = fetchAppOrderbook( chain.contracts, getPropertyFormChain(chain, 'iexecGateway'), - app, { + app, dataset, workerpool, requester, @@ -180,8 +180,8 @@ orderbookDataset const request = fetchDatasetOrderbook( chain.contracts, getPropertyFormChain(chain, 'iexecGateway'), - dataset, { + dataset, app, workerpool, requester, diff --git a/src/common/market/orderbook.js b/src/common/market/orderbook.js index fbee2912..e47048e0 100644 --- a/src/common/market/orderbook.js +++ b/src/common/market/orderbook.js @@ -20,53 +20,120 @@ const ERROR_GETTING_ORDERBOOK = 'An error occurred while getting orderbook'; export const fetchAppOrderbook = async ( contracts = throwIfMissing(), iexecGatewayURL = throwIfMissing(), - app = throwIfMissing(), - { - dataset, - workerpool, - requester, - minTag, - maxTag, - minVolume, - page = 0, - pageSize = 20, - isDatasetStrict = false, - isWorkerpoolStrict = false, - isRequesterStrict = false, - } = {}, + appOrOptions = throwIfMissing(), + options, ) => { try { + let app; + let appOwner; + let dataset; + let workerpool; + let requester; + let minTag; + let maxTag; + let minVolume; + let page; + let pageSize; + let isDatasetStrict; + let isWorkerpoolStrict; + let isRequesterStrict; + if (typeof appOrOptions === 'object' && appOrOptions !== null) { + ({ + app, + appOwner, + dataset, + workerpool, + requester, + minTag, + maxTag, + minVolume, + page = 0, + pageSize = 20, + isDatasetStrict = false, + isWorkerpoolStrict = false, + isRequesterStrict = false, + } = appOrOptions); + } else { + // deprecated + // eslint-disable-next-line no-console + console.warn( + 'passing app as first argument is deprecated, please pass the options object containing app or appOwner instead', + ); + app = appOrOptions; + ({ + dataset, + workerpool, + requester, + minTag, + maxTag, + minVolume, + page = 0, + pageSize = 20, + isDatasetStrict = false, + isWorkerpoolStrict = false, + isRequesterStrict = false, + } = options || {}); + } + if (!app && !appOwner) { + throw Error('app or appOwner is required'); + } + const query = { chainId: await chainIdSchema().validate(contracts.chainId), - app: await addressOrAnySchema({ - ethProvider: contracts.provider, - }).validate(app), + ...(app && { + app: await addressOrAnySchema({ + ethProvider: contracts.provider, + }) + .label('app') + .validate(app), + }), + ...(appOwner && { + appOwner: await addressOrAnySchema({ + ethProvider: contracts.provider, + }) + .label('appOwner') + .validate(appOwner), + }), ...(dataset && { dataset: await addressOrAnySchema({ ethProvider: contracts.provider, - }).validate(dataset), + }) + .label('dataset') + .validate(dataset), }), - isDatasetStrict: await booleanSchema().validate(isDatasetStrict), + isDatasetStrict: await booleanSchema() + .label('isDatasetStrict') + .validate(isDatasetStrict), ...(workerpool && { workerpool: await addressOrAnySchema({ ethProvider: contracts.provider, - }).validate(workerpool), + }) + .label('workerpool') + .validate(workerpool), }), - isWorkerpoolStrict: await booleanSchema().validate(isWorkerpoolStrict), + isWorkerpoolStrict: await booleanSchema() + .label('isWorkerpoolStrict') + .validate(isWorkerpoolStrict), ...(requester && { requester: await addressOrAnySchema({ ethProvider: contracts.provider, - }).validate(requester), + }) + .label('requester') + .validate(requester), }), - isRequesterStrict: await booleanSchema().validate(isRequesterStrict), + isRequesterStrict: await booleanSchema() + .label('isRequesterStrict') + .validate(isRequesterStrict), ...(minVolume && { - minVolume: await positiveStrictIntSchema().validate(minVolume), + minVolume: await positiveStrictIntSchema() + .label('minVolume') + .validate(minVolume), }), ...(minTag !== undefined && { - minTag: await tagSchema().validate(minTag), + minTag: await tagSchema().label('minTag').validate(minTag), }), ...(maxTag !== undefined && { - maxTag: await tagSchema().validate(maxTag), + maxTag: await tagSchema().label('maxTag').validate(maxTag), }), ...(page !== undefined && { pageIndex: await positiveIntSchema().label('page').validate(page), @@ -97,53 +164,120 @@ export const fetchAppOrderbook = async ( export const fetchDatasetOrderbook = async ( contracts = throwIfMissing(), iexecGatewayURL = throwIfMissing(), - dataset = throwIfMissing(), - { - app, - workerpool, - requester, - minTag, - maxTag, - minVolume, - page = 0, - pageSize = 20, - isAppStrict = false, - isWorkerpoolStrict = false, - isRequesterStrict = false, - } = {}, + datasetOrOptions = throwIfMissing(), + options, ) => { try { + let dataset; + let datasetOwner; + let app; + let workerpool; + let requester; + let minTag; + let maxTag; + let minVolume; + let page; + let pageSize; + let isAppStrict; + let isWorkerpoolStrict; + let isRequesterStrict; + if (typeof datasetOrOptions === 'object' && datasetOrOptions !== null) { + ({ + dataset, + datasetOwner, + app, + workerpool, + requester, + minTag, + maxTag, + minVolume, + page = 0, + pageSize = 20, + isAppStrict = false, + isWorkerpoolStrict = false, + isRequesterStrict = false, + } = datasetOrOptions); + } else { + // deprecated + // eslint-disable-next-line no-console + console.warn( + 'passing dataset as first argument is deprecated, please pass the options object containing dataset or datasetOwner instead', + ); + dataset = datasetOrOptions; + ({ + app, + workerpool, + requester, + minTag, + maxTag, + minVolume, + page = 0, + pageSize = 20, + isAppStrict = false, + isWorkerpoolStrict = false, + isRequesterStrict = false, + } = options || {}); + } + if (!dataset && !datasetOwner) { + throw Error('dataset or datasetOwner is required'); + } + const query = { chainId: await chainIdSchema().validate(contracts.chainId), - dataset: await addressOrAnySchema({ - ethProvider: contracts.provider, - }).validate(dataset), + ...(dataset && { + dataset: await addressOrAnySchema({ + ethProvider: contracts.provider, + }) + .label('dataset') + .validate(dataset), + }), + ...(datasetOwner && { + datasetOwner: await addressOrAnySchema({ + ethProvider: contracts.provider, + }) + .label('datasetOwner') + .validate(datasetOwner), + }), ...(app && { app: await addressOrAnySchema({ ethProvider: contracts.provider, - }).validate(app), - isAppStrict: await booleanSchema().validate(isAppStrict), + }) + .label('app') + .validate(app), }), + isAppStrict: await booleanSchema() + .label('isAppStrict') + .validate(isAppStrict), ...(workerpool && { workerpool: await addressOrAnySchema({ ethProvider: contracts.provider, - }).validate(workerpool), + }) + .label('workerpool') + .validate(workerpool), }), - isWorkerpoolStrict: await booleanSchema().validate(isWorkerpoolStrict), + isWorkerpoolStrict: await booleanSchema() + .label('isWorkerpoolStrict') + .validate(isWorkerpoolStrict), ...(requester && { requester: await addressOrAnySchema({ ethProvider: contracts.provider, - }).validate(requester), + }) + .label('requester') + .validate(requester), }), - isRequesterStrict: await booleanSchema().validate(isRequesterStrict), + isRequesterStrict: await booleanSchema() + .label('isRequesterStrict') + .validate(isRequesterStrict), ...(minVolume && { - minVolume: await positiveStrictIntSchema().validate(minVolume), + minVolume: await positiveStrictIntSchema() + .label('minVolume') + .validate(minVolume), }), ...(minTag !== undefined && { - minTag: await tagSchema().validate(minTag), + minTag: await tagSchema().label('minTag').validate(minTag), }), ...(maxTag !== undefined && { - maxTag: await tagSchema().validate(maxTag), + maxTag: await tagSchema().label('maxTag').validate(maxTag), }), ...(page !== undefined && { pageIndex: await positiveIntSchema().label('page').validate(page), @@ -194,47 +328,69 @@ export const fetchWorkerpoolOrderbook = async ( ) => { try { const query = { - chainId: await chainIdSchema().validate(contracts.chainId), - category: await uint256Schema().validate(category), + chainId: await chainIdSchema() + .label('chainId') + .validate(contracts.chainId), + category: await uint256Schema().label('category').validate(category), ...(workerpool && { workerpool: await addressOrAnySchema({ ethProvider: contracts.provider, - }).validate(workerpool), + }) + .label('workerpool') + .validate(workerpool), }), ...(app && { app: await addressOrAnySchema({ ethProvider: contracts.provider, - }).validate(app), + }) + .label('app') + .validate(app), }), - isAppStrict: await booleanSchema().validate(isAppStrict), + isAppStrict: await booleanSchema() + .label('isAppStrict') + .validate(isAppStrict), ...(dataset && { dataset: await addressOrAnySchema({ ethProvider: contracts.provider, - }).validate(dataset), + }) + .label('dataset') + .validate(dataset), }), - isDatasetStrict: await booleanSchema().validate(isDatasetStrict), + isDatasetStrict: await booleanSchema() + .label('isDatasetStrict') + .validate(isDatasetStrict), ...(requester && { requester: await addressOrAnySchema({ ethProvider: contracts.provider, - }).validate(requester), + }) + .label('requester') + .validate(requester), }), - isRequesterStrict: await booleanSchema().validate(isRequesterStrict), + isRequesterStrict: await booleanSchema() + .label('isRequesterStrict') + .validate(isRequesterStrict), ...(minTag && { - minTag: await tagSchema().validate(minTag), + minTag: await tagSchema().label('minTag').validate(minTag), }), ...(maxTag && { - maxTag: await tagSchema().validate(maxTag), + maxTag: await tagSchema().label('maxTag').validate(maxTag), }), ...(workerpoolOwner && { workerpoolOwner: await addressSchema({ ethProvider: contracts.provider, - }).validate(workerpoolOwner), + }) + .label('workerpoolOwner') + .validate(workerpoolOwner), }), ...(minTrust && { - minTrust: await positiveIntSchema().validate(minTrust), + minTrust: await positiveIntSchema() + .label('minTrust') + .validate(minTrust), }), ...(minVolume && { - minVolume: await positiveStrictIntSchema().validate(minVolume), + minVolume: await positiveStrictIntSchema() + .label('minVolume') + .validate(minVolume), }), ...(page !== undefined && { pageIndex: await positiveIntSchema().label('page').validate(page), @@ -283,45 +439,63 @@ export const fetchRequestOrderbook = async ( ) => { try { const query = { - chainId: await chainIdSchema().validate(contracts.chainId), - category: await uint256Schema().validate(category), + chainId: await chainIdSchema() + .label('chainId') + .validate(contracts.chainId), + category: await uint256Schema().label('category').validate(category), ...(requester && { requester: await addressOrAnySchema({ ethProvider: contracts.provider, - }).validate(requester), + }) + .label('requester') + .validate(requester), }), ...(beneficiary && { beneficiary: await addressOrAnySchema({ ethProvider: contracts.provider, - }).validate(beneficiary), + }) + .label('beneficiary') + .validate(beneficiary), }), ...(app && { app: await addressOrAnySchema({ ethProvider: contracts.provider, - }).validate(app), + }) + .label('app') + .validate(app), }), ...(dataset && { dataset: await addressOrAnySchema({ ethProvider: contracts.provider, - }).validate(dataset), + }) + .label('dataset') + .validate(dataset), }), ...(workerpool && { workerpool: await addressOrAnySchema({ ethProvider: contracts.provider, - }).validate(workerpool), + }) + .label('workerpool') + .validate(workerpool), }), - isWorkerpoolStrict: await booleanSchema().validate(isWorkerpoolStrict), + isWorkerpoolStrict: await booleanSchema() + .label('isWorkerpoolStrict') + .validate(isWorkerpoolStrict), ...(minTag !== undefined && { - minTag: await tagSchema().validate(minTag), + minTag: await tagSchema().label('minTag').validate(minTag), }), ...(maxTag !== undefined && { - maxTag: await tagSchema().validate(maxTag), + maxTag: await tagSchema().label('maxTag').validate(maxTag), }), ...(maxTrust !== undefined && { - maxTrust: await positiveIntSchema().validate(maxTrust), + maxTrust: await positiveIntSchema() + .label('maxTrust') + .validate(maxTrust), }), ...(minVolume && { - minVolume: await positiveStrictIntSchema().validate(minVolume), + minVolume: await positiveStrictIntSchema() + .label('minVolume') + .validate(minVolume), }), ...(page !== undefined && { pageIndex: await positiveIntSchema().label('page').validate(page), diff --git a/src/lib/IExecOrderbookModule.d.ts b/src/lib/IExecOrderbookModule.d.ts index 276849ba..c7153343 100644 --- a/src/lib/IExecOrderbookModule.d.ts +++ b/src/lib/IExecOrderbookModule.d.ts @@ -146,7 +146,70 @@ export default class IExecOrderbookModule extends IExecModule { * ``` */ fetchAppOrderbook( - appAddress: Addressish, + appAddressOrOptions: + | Addressish + | 'any' + | { + /** + * filter by app + */ + app?: Addressish | 'any'; + /** + * filter by app owner + */ + appOwner?: Addressish; + /** + * include orders restricted to specified dataset (use `'any'` to include any dataset) + */ + dataset?: Addressish | 'any'; + /** + * include orders restricted to specified workerpool (use `'any'` to include any workerpool) + */ + workerpool?: Addressish | 'any'; + /** + * include orders restricted to specified requester (use `'any'` to include any requester) + */ + requester?: Addressish | 'any'; + /** + * filter by minimum volume remaining + */ + minVolume?: BNish; + /** + * filter by minimum tag required + */ + minTag?: Tag | HumanSingleTag[]; + /** + * filter by maximum tag accepted + */ + maxTag?: Tag | HumanSingleTag[]; + /** + * index of the page to fetch + */ + page?: number; + /** + * size of the page to fetch + */ + pageSize?: number; + /** + * filters out orders allowing “any” dataset (default: `false`) + */ + isDatasetStrict?: boolean; + /** + * filters out orders allowing “any” requester (default: `false`) + */ + isRequesterStrict?: boolean; + /** + * filters out orders allowing “any” workerpool (default: `false`) + */ + isWorkerpoolStrict?: boolean; + }, + /** + * @deprecated use first parameter instead + * + * migration: + * + * replace `fetchAppOrderbook(appAddress, options)` by `fetchAppOrderbook({ app: appAddress, ...options })` + */ options?: { /** * include orders restricted to specified dataset (use `'any'` to include any dataset) @@ -207,7 +270,70 @@ export default class IExecOrderbookModule extends IExecModule { * ``` */ fetchDatasetOrderbook( - datasetAddress: Addressish, + datasetAddressOrOptions: + | Addressish + | 'any' + | { + /** + * filter by dataset + */ + dataset?: Addressish | 'any'; + /** + * filter by dataset owner + */ + datasetOwner?: Addressish; + /** + * include orders restricted to specified app (use `'any'` to include any app) + */ + app?: Addressish | 'any'; + /** + * include orders restricted to specified workerpool (use `'any'` to include any workerpool) + */ + workerpool?: Addressish | 'any'; + /** + * include orders restricted to specified requester (use `'any'` to include any requester) + */ + requester?: Addressish | 'any'; + /** + * filter by minimum volume remaining + */ + minVolume?: BNish; + /** + * filter by minimum tag required + */ + minTag?: Tag | HumanSingleTag[]; + /** + * filter by maximum tag accepted + */ + maxTag?: Tag | HumanSingleTag[]; + /** + * index of the page to fetch + */ + page?: number; + /** + * size of the page to fetch + */ + pageSize?: number; + /** + * filters out orders allowing “any” app (default: `false`) + */ + isAppStrict?: boolean; + /** + * filters out orders allowing “any” requester (default: `false`) + */ + isRequesterStrict?: boolean; + /** + * filters out orders allowing “any” workerpool (default: `false`) + */ + isWorkerpoolStrict?: boolean; + }, + /** + * @deprecated use first parameter instead + * + * migration: + * + * replace `fetchDatasetOrderbook(datasetAddress, options)` by `fetchDatasetOrderbook({ dataset: datasetAddress, ...options })` + */ options?: { /** * include orders restricted to specified app (use `'any'` to include any app) diff --git a/src/lib/IExecOrderbookModule.js b/src/lib/IExecOrderbookModule.js index d18a06db..87aaaa7d 100644 --- a/src/lib/IExecOrderbookModule.js +++ b/src/lib/IExecOrderbookModule.js @@ -45,18 +45,18 @@ export default class IExecOrderbookModule extends IExecModule { await this.config.resolveChainId(), requestorderHash, ); - this.fetchAppOrderbook = async (appAddress, options = {}) => + this.fetchAppOrderbook = async (appAddressOrOptions, options) => fetchAppOrderbook( await this.config.resolveContractsClient(), await this.config.resolveIexecGatewayURL(), - appAddress, + appAddressOrOptions, options, ); - this.fetchDatasetOrderbook = async (datasetAddress, options = {}) => + this.fetchDatasetOrderbook = async (datasetAddressOrOptions, options) => fetchDatasetOrderbook( await this.config.resolveContractsClient(), await this.config.resolveIexecGatewayURL(), - datasetAddress, + datasetAddressOrOptions, options, ); this.fetchWorkerpoolOrderbook = async (options) => diff --git a/test/lib/e2e/IExecOrderbookModule.test.js b/test/lib/e2e/IExecOrderbookModule.test.js index 1ee9f260..feb828a7 100644 --- a/test/lib/e2e/IExecOrderbookModule.test.js +++ b/test/lib/e2e/IExecOrderbookModule.test.js @@ -173,7 +173,7 @@ describe('orderbook', () => { }, }); await expectAsyncCustomError( - iexecReadOnly.orderbook.fetchAppOrderbook(getRandomAddress()), + iexecReadOnly.orderbook.fetchAppOrderbook({ app: getRandomAddress() }), { constructor: MarketCallError, message: `Market API error: Connection to ${SERVICE_UNREACHABLE_URL} failed with a network error`, @@ -189,7 +189,7 @@ describe('orderbook', () => { }, }); await expectAsyncCustomError( - iexecReadOnly.orderbook.fetchAppOrderbook(getRandomAddress()), + iexecReadOnly.orderbook.fetchAppOrderbook({ app: getRandomAddress() }), { constructor: MarketCallError, message: `Market API error: Server at ${SERVICE_HTTP_500_URL} encountered an internal error`, @@ -203,7 +203,9 @@ describe('orderbook', () => { readOnly: true, }); const appAddress = getRandomAddress(); - const res = await iexec.orderbook.fetchAppOrderbook(appAddress); + const res = await iexec.orderbook.fetchAppOrderbook({ + app: appAddress, + }); expect(res.count).toBe(0); expect(res.orders).toStrictEqual([]); const apporder = await deployAndGetApporder(iexec); @@ -238,9 +240,9 @@ describe('orderbook', () => { iexec.order.publishApporder(o), ); - const res1 = await iexecReadOnly.orderbook.fetchAppOrderbook( - apporder.app, - ); + const res1 = await iexecReadOnly.orderbook.fetchAppOrderbook({ + app: apporder.app, + }); expect(res1.count).toBe(22); expect(res1.orders.length).toBe(20); expect(res1.more).toBeDefined(); @@ -248,42 +250,74 @@ describe('orderbook', () => { expect(res2.count).toBe(22); expect(res2.orders.length).toBe(2); expect(res2.more).toBeUndefined(); - const res3 = await iexecReadOnly.orderbook.fetchAppOrderbook( - apporder.app, - { - dataset: 'any', - }, - ); + const res3 = await iexecReadOnly.orderbook.fetchAppOrderbook({ + app: apporder.app, + dataset: 'any', + }); expect(res3.count).toBe(24); - const res4 = await iexecReadOnly.orderbook.fetchAppOrderbook( - apporder.app, - { - workerpool: 'any', - }, - ); + const res4 = await iexecReadOnly.orderbook.fetchAppOrderbook({ + app: apporder.app, + workerpool: 'any', + }); expect(res4.count).toBe(25); - const res5 = await iexecReadOnly.orderbook.fetchAppOrderbook( - apporder.app, - { - requester: 'any', - }, - ); + const res5 = await iexecReadOnly.orderbook.fetchAppOrderbook({ + app: apporder.app, + requester: 'any', + }); expect(res5.count).toBe(26); - const res6 = await iexecReadOnly.orderbook.fetchAppOrderbook( - apporder.app, - { - dataset: 'any', - requester: 'any', - workerpool: 'any', - }, - ); + const res6 = await iexecReadOnly.orderbook.fetchAppOrderbook({ + app: apporder.app, + dataset: 'any', + requester: 'any', + workerpool: 'any', + }); expect(res6.count).toBe(31); - const res7 = await iexecReadOnly.orderbook.fetchAppOrderbook('any', { + const res7 = await iexecReadOnly.orderbook.fetchAppOrderbook({ + app: 'any', dataset: 'any', requester: 'any', workerpool: 'any', }); expect(res7.count >= 32).toBe(true); + + // backward compatibility: deprecated appAddress parameter + const res1deprecated = await iexecReadOnly.orderbook.fetchAppOrderbook( + apporder.app, + ); + expect(res1.orders).toLooseEqual(res1deprecated.orders); + }); + + test('appOwner returns orders from app owner', async () => { + const { iexec: iexecUser, wallet } = getTestConfig(iexecTestChain)(); + const { iexec: iexecOtherUser } = getTestConfig(iexecTestChain)(); + const { iexec: iexecReadOnly } = getTestConfig(iexecTestChain)({ + readOnly: true, + }); + // publish orders from two different users + const orderHash = await deployAndGetApporder(iexecUser, { + owner: wallet.address, + }).then((o) => + iexecUser.order + .signApporder(o) + .then((o) => iexecUser.order.publishApporder(o)), + ); + + await deployAndGetApporder(iexecOtherUser, { + owner: wallet.address, + }).then((o) => + iexecOtherUser.order + .signApporder(o) + .then((o) => iexecOtherUser.order.publishApporder(o)), + ); + + const res = await iexecReadOnly.orderbook.fetchAppOrderbook({ + appOwner: wallet.address, + dataset: 'any', + requester: 'any', + workerpool: 'any', + }); + expect(res.count).toBe(1); + expect(res.orders[0].orderHash).toBe(orderHash); }); test('strict option allow filtering only orders for specified dataset, workerpool or requester', async () => { @@ -331,20 +365,20 @@ describe('orderbook', () => { emptyAppOrder.requesterrestrict = NULL_ADDRESS; // all orders (1,2,3,4,5) - const allAppOrders = await iexecReadOnly.orderbook.fetchAppOrderbook( - appAddress, - { - dataset: 'any', - requester: 'any', - workerpool: 'any', - }, - ); + const allAppOrders = await iexecReadOnly.orderbook.fetchAppOrderbook({ + app: appAddress, + dataset: 'any', + requester: 'any', + workerpool: 'any', + }); expect(allAppOrders.count).toBe(5); expect(allAppOrders.orders.length).toBe(5); // all orders without restrictions (1, 2) const unrestrictedAppOrders = - await iexecReadOnly.orderbook.fetchAppOrderbook(appAddress); + await iexecReadOnly.orderbook.fetchAppOrderbook({ + app: appAddress, + }); expect(unrestrictedAppOrders.count).toBe(2); expect(unrestrictedAppOrders.orders.length).toBe(2); expect(unrestrictedAppOrders.orders[0].order.datasetrestrict).toEqual( @@ -368,7 +402,8 @@ describe('orderbook', () => { // all orders without dataset restriction(1,2) and with dataset restriction(3) const datasetRestrictedAppOrders = - await iexecReadOnly.orderbook.fetchAppOrderbook(appAddress, { + await iexecReadOnly.orderbook.fetchAppOrderbook({ + app: appAddress, dataset: datasetAddress, }); expect(datasetRestrictedAppOrders.count).toBe(3); @@ -376,7 +411,8 @@ describe('orderbook', () => { // all orders with dataset restriction and strict(3) const datasetStrictAppOrder = - await iexecReadOnly.orderbook.fetchAppOrderbook(appAddress, { + await iexecReadOnly.orderbook.fetchAppOrderbook({ + app: appAddress, dataset: datasetAddress, isDatasetStrict: true, }); @@ -388,7 +424,8 @@ describe('orderbook', () => { // all orders without workerpool restriction(1,2) and with workerpool restriction(4) const workerpoolRestrictedAppOrders = - await iexecReadOnly.orderbook.fetchAppOrderbook(appAddress, { + await iexecReadOnly.orderbook.fetchAppOrderbook({ + app: appAddress, workerpool: workerpoolAddress, }); expect(workerpoolRestrictedAppOrders.count).toBe(3); @@ -396,7 +433,8 @@ describe('orderbook', () => { // all orders with workerpool restriction and strict(4) const workerpoolStrictAppOrder = - await iexecReadOnly.orderbook.fetchAppOrderbook(appAddress, { + await iexecReadOnly.orderbook.fetchAppOrderbook({ + app: appAddress, workerpool: workerpoolAddress, isWorkerpoolStrict: true, }); @@ -408,7 +446,8 @@ describe('orderbook', () => { // all orders without requester restriction(1,2) and with requester restriction(5) const requesterRestrictedAppOrders = - await iexecReadOnly.orderbook.fetchAppOrderbook(appAddress, { + await iexecReadOnly.orderbook.fetchAppOrderbook({ + app: appAddress, requester: requesterAddress, }); expect(requesterRestrictedAppOrders.count).toBe(3); @@ -416,7 +455,8 @@ describe('orderbook', () => { // all orders with requester restriction and strict(5) const requesterStrictAppOrders = - await iexecReadOnly.orderbook.fetchAppOrderbook(appAddress, { + await iexecReadOnly.orderbook.fetchAppOrderbook({ + app: appAddress, requester: requesterAddress, isRequesterStrict: true, }); @@ -428,7 +468,8 @@ describe('orderbook', () => { // all orders with requester, dataset, workerpool restriction and not strict (1,2,3,4,5) const unstrictAppOrders = - await iexecReadOnly.orderbook.fetchAppOrderbook(appAddress, { + await iexecReadOnly.orderbook.fetchAppOrderbook({ + app: appAddress, dataset: datasetAddress, isDatasetStrict: false, requester: requesterAddress, @@ -441,8 +482,8 @@ describe('orderbook', () => { // all orders with requester, dataset, workerpool restriction and strict const strictAppOrders = await iexecReadOnly.orderbook.fetchAppOrderbook( - appAddress, { + app: appAddress, dataset: datasetAddress, isDatasetStrict: true, requester: requesterAddress, @@ -463,8 +504,9 @@ describe('orderbook', () => { readOnly: true, }); const datasetAddress = getRandomAddress(); - const res = - await iexecReadOnly.orderbook.fetchDatasetOrderbook(datasetAddress); + const res = await iexecReadOnly.orderbook.fetchDatasetOrderbook({ + dataset: datasetAddress, + }); expect(res.count).toBe(0); expect(res.orders).toStrictEqual([]); const datasetorder = await deployAndGetDatasetorder(iexec); @@ -509,9 +551,9 @@ describe('orderbook', () => { iexec.order.publishDatasetorder(o, { preflightCheck: false }), ); - const res1 = await iexecReadOnly.orderbook.fetchDatasetOrderbook( - datasetorder.dataset, - ); + const res1 = await iexecReadOnly.orderbook.fetchDatasetOrderbook({ + dataset: datasetorder.dataset, + }); expect(res1.count).toBe(23); expect(res1.orders.length).toBe(20); expect(res1.more).toBeDefined(); @@ -519,35 +561,74 @@ describe('orderbook', () => { expect(res2.count).toBe(23); expect(res2.orders.length).toBe(3); expect(res2.more).toBeUndefined(); - const res3 = await iexecReadOnly.orderbook.fetchDatasetOrderbook( - datasetorder.dataset, - { app: 'any' }, - ); + const res3 = await iexecReadOnly.orderbook.fetchDatasetOrderbook({ + dataset: datasetorder.dataset, + app: 'any', + }); expect(res3.count).toBe(25); - const res4 = await iexecReadOnly.orderbook.fetchDatasetOrderbook( - datasetorder.dataset, - { workerpool: 'any' }, - ); + const res4 = await iexecReadOnly.orderbook.fetchDatasetOrderbook({ + dataset: datasetorder.dataset, + workerpool: 'any', + }); expect(res4.count).toBe(26); - const res5 = await iexecReadOnly.orderbook.fetchDatasetOrderbook( - datasetorder.dataset, - { requester: 'any' }, - ); + const res5 = await iexecReadOnly.orderbook.fetchDatasetOrderbook({ + dataset: datasetorder.dataset, + requester: 'any', + }); expect(res5.count).toBe(27); - const res6 = await iexecReadOnly.orderbook.fetchDatasetOrderbook( - datasetorder.dataset, - { app: 'any', workerpool: 'any', requester: 'any' }, - ); + const res6 = await iexecReadOnly.orderbook.fetchDatasetOrderbook({ + dataset: datasetorder.dataset, + app: 'any', + workerpool: 'any', + requester: 'any', + }); expect(res6.count).toBe(32); - const res7 = await iexecReadOnly.orderbook.fetchDatasetOrderbook( - 'any', - { - app: 'any', - requester: 'any', - workerpool: 'any', - }, - ); + const res7 = await iexecReadOnly.orderbook.fetchDatasetOrderbook({ + dataset: 'any', + app: 'any', + requester: 'any', + workerpool: 'any', + }); expect(res7.count >= 33).toBe(true); + + // backward compatibility: deprecated datasetAddress parameter + const res1deprecated = + await iexecReadOnly.orderbook.fetchDatasetOrderbook( + datasetorder.dataset, + ); + expect(res1.orders).toLooseEqual(res1deprecated.orders); + }); + test('datasetOwner returns orders from dataset owner', async () => { + const { iexec: iexecUser, wallet } = getTestConfig(iexecTestChain)(); + const { iexec: iexecOtherUser } = getTestConfig(iexecTestChain)(); + const { iexec: iexecReadOnly } = getTestConfig(iexecTestChain)({ + readOnly: true, + }); + // publish orders from two different users + const orderHash = await deployAndGetDatasetorder(iexecUser, { + owner: wallet.address, + }).then((o) => + iexecUser.order + .signDatasetorder(o) + .then((o) => iexecUser.order.publishDatasetorder(o)), + ); + + await deployAndGetDatasetorder(iexecOtherUser, { + owner: wallet.address, + }).then((o) => + iexecOtherUser.order + .signDatasetorder(o) + .then((o) => iexecOtherUser.order.publishDatasetorder(o)), + ); + + const res = await iexecReadOnly.orderbook.fetchDatasetOrderbook({ + datasetOwner: wallet.address, + app: 'any', + requester: 'any', + workerpool: 'any', + }); + expect(res.count).toBe(1); + expect(res.orders[0].orderHash).toBe(orderHash); }); test('strict option allow filtering only orders for specified app, workerpool or requester', async () => { @@ -605,7 +686,8 @@ describe('orderbook', () => { // all orders (1,2,3,4,5) const allADatasetOrders = - await iexecReadOnly.orderbook.fetchDatasetOrderbook(datasetAddress, { + await iexecReadOnly.orderbook.fetchDatasetOrderbook({ + dataset: datasetAddress, app: 'any', requester: 'any', workerpool: 'any', @@ -615,7 +697,9 @@ describe('orderbook', () => { // all orders without restrictions (1, 2) const unrestrictedDatasetOrders = - await iexecReadOnly.orderbook.fetchDatasetOrderbook(datasetAddress); + await iexecReadOnly.orderbook.fetchDatasetOrderbook({ + dataset: datasetAddress, + }); expect(unrestrictedDatasetOrders.count).toBe(2); expect(unrestrictedDatasetOrders.orders.length).toBe(2); expect(unrestrictedDatasetOrders.orders[0].order.apprestrict).toEqual( @@ -639,7 +723,8 @@ describe('orderbook', () => { // all orders without app restriction(1,2) and with app restriction(3) const appRestrictedAppOrders = - await iexecReadOnly.orderbook.fetchDatasetOrderbook(datasetAddress, { + await iexecReadOnly.orderbook.fetchDatasetOrderbook({ + dataset: datasetAddress, app: appAddress, }); expect(appRestrictedAppOrders.count).toBe(3); @@ -647,7 +732,8 @@ describe('orderbook', () => { // all orders with app restriction and strict(3) const appStrictAppOrder = - await iexecReadOnly.orderbook.fetchDatasetOrderbook(datasetAddress, { + await iexecReadOnly.orderbook.fetchDatasetOrderbook({ + dataset: datasetAddress, app: appAddress, isAppStrict: true, }); @@ -659,7 +745,8 @@ describe('orderbook', () => { // all orders without workerpool restriction(1,2) and with workerpool restriction(4) const workerpoolRestrictedAppOrders = - await iexecReadOnly.orderbook.fetchDatasetOrderbook(datasetAddress, { + await iexecReadOnly.orderbook.fetchDatasetOrderbook({ + dataset: datasetAddress, workerpool: workerpoolAddress, }); expect(workerpoolRestrictedAppOrders.count).toBe(3); @@ -667,7 +754,8 @@ describe('orderbook', () => { // all orders with workerpool restriction and strict(4) const workerpoolStrictAppOrder = - await iexecReadOnly.orderbook.fetchDatasetOrderbook(datasetAddress, { + await iexecReadOnly.orderbook.fetchDatasetOrderbook({ + dataset: datasetAddress, workerpool: workerpoolAddress, isWorkerpoolStrict: true, }); @@ -679,7 +767,8 @@ describe('orderbook', () => { // all orders without requester restriction(1,2) and with requester restriction(5) const requesterRestrictedAppOrders = - await iexecReadOnly.orderbook.fetchDatasetOrderbook(datasetAddress, { + await iexecReadOnly.orderbook.fetchDatasetOrderbook({ + dataset: datasetAddress, requester: requesterAddress, }); expect(requesterRestrictedAppOrders.count).toBe(3); @@ -687,7 +776,8 @@ describe('orderbook', () => { // all orders with requester restriction and strict(5) const requesterStrictAppOrders = - await iexecReadOnly.orderbook.fetchDatasetOrderbook(datasetAddress, { + await iexecReadOnly.orderbook.fetchDatasetOrderbook({ + dataset: datasetAddress, requester: requesterAddress, isRequesterStrict: true, }); @@ -699,7 +789,8 @@ describe('orderbook', () => { // all orders with app, requester, workerpool restriction and not strict (1,2,3,4,5) const unstrictAppOrders = - await iexecReadOnly.orderbook.fetchDatasetOrderbook(datasetAddress, { + await iexecReadOnly.orderbook.fetchDatasetOrderbook({ + dataset: datasetAddress, app: appAddress, isAppStrict: false, requester: requesterAddress, @@ -712,7 +803,8 @@ describe('orderbook', () => { // all orders with app, requester, workerpool restriction and strict const strictAppOrders = - await iexecReadOnly.orderbook.fetchDatasetOrderbook(datasetAddress, { + await iexecReadOnly.orderbook.fetchDatasetOrderbook({ + dataset: datasetAddress, app: appAddress, isAppStrict: true, requester: requesterAddress,