@oceanprotocol/lib 4.0.3 → 4.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +11 -0
- package/CodeExamples.md +3 -4
- package/ComputeExamples.md +262 -49
- package/dist/lib.cjs +1 -1
- package/dist/lib.cjs.map +1 -1
- package/dist/lib.modern.js +1 -1
- package/dist/lib.modern.js.map +1 -1
- package/dist/lib.module.mjs +1 -1
- package/dist/lib.module.mjs.map +1 -1
- package/dist/lib.umd.js +1 -1
- package/dist/lib.umd.js.map +1 -1
- package/dist/types/@types/Compute.d.ts +9 -0
- package/dist/types/@types/Provider.d.ts +9 -0
- package/dist/types/contracts/Datatoken.d.ts +9 -0
- package/dist/types/contracts/Escrow.d.ts +93 -0
- package/dist/types/services/Provider.d.ts +6 -4
- package/package.json +2 -2
package/CHANGELOG.md
CHANGED
|
@@ -4,8 +4,18 @@ All notable changes to this project will be documented in this file. Dates are d
|
|
|
4
4
|
|
|
5
5
|
Generated by [`auto-changelog`](https://github.com/CookPete/auto-changelog).
|
|
6
6
|
|
|
7
|
+
#### [v4.1.0](https://github.com/oceanprotocol/ocean.js/compare/v4.0.3...v4.1.0)
|
|
8
|
+
|
|
9
|
+
- Feature/paid compute [`#1924`](https://github.com/oceanprotocol/ocean.js/pull/1924)
|
|
10
|
+
- Escrow contract integration [`#1910`](https://github.com/oceanprotocol/ocean.js/pull/1910)
|
|
11
|
+
- Updating ComputeExamples.md [`95caa93`](https://github.com/oceanprotocol/ocean.js/commit/95caa93c8d44ee7a276d2bf65864a58bf4030f57)
|
|
12
|
+
- Merge 3746bd826b24e56abec0a2ee4640aeb4ea648d20 into 261c665f4f434b0f8eba9fed952dab1adf0321f5 [`f2a8129`](https://github.com/oceanprotocol/ocean.js/commit/f2a8129533ee61e5903df892e0b10b54f4c506a6)
|
|
13
|
+
- Updating ComputeExamples.md [`68d5386`](https://github.com/oceanprotocol/ocean.js/commit/68d53864a90ce34cccf7d54065d4aff947c37a86)
|
|
14
|
+
|
|
7
15
|
#### [v4.0.3](https://github.com/oceanprotocol/ocean.js/compare/v4.0.2...v4.0.3)
|
|
8
16
|
|
|
17
|
+
> 28 April 2025
|
|
18
|
+
|
|
9
19
|
- Dependencies update [`#1938`](https://github.com/oceanprotocol/ocean.js/pull/1938)
|
|
10
20
|
- use main branch for node checkout [`#1936`](https://github.com/oceanprotocol/ocean.js/pull/1936)
|
|
11
21
|
- Further integrate ddo-js [`#1935`](https://github.com/oceanprotocol/ocean.js/pull/1935)
|
|
@@ -14,6 +24,7 @@ Generated by [`auto-changelog`](https://github.com/CookPete/auto-changelog).
|
|
|
14
24
|
- Bump release-it from 15.6.1 to 18.1.2 [`#1921`](https://github.com/oceanprotocol/ocean.js/pull/1921)
|
|
15
25
|
- Bump esbuild and tsx [`#1925`](https://github.com/oceanprotocol/ocean.js/pull/1925)
|
|
16
26
|
- Bump serialize-javascript and mocha [`#1915`](https://github.com/oceanprotocol/ocean.js/pull/1915)
|
|
27
|
+
- Release 4.0.3 [`f00bb95`](https://github.com/oceanprotocol/ocean.js/commit/f00bb955957ed1b69a01200bc73b2857da91117e)
|
|
17
28
|
|
|
18
29
|
#### [v4.0.2](https://github.com/oceanprotocol/ocean.js/compare/v4.0.1...v4.0.2)
|
|
19
30
|
|
package/CodeExamples.md
CHANGED
|
@@ -183,12 +183,11 @@ Next, we define the metadata that will describe our data asset. This is what we
|
|
|
183
183
|
},
|
|
184
184
|
services: [
|
|
185
185
|
{
|
|
186
|
-
id: '
|
|
186
|
+
id: 'db164c1b981e4d2974e90e61bda121512e6909c1035c908d68933ae4cfaba6b0',
|
|
187
187
|
type: 'access',
|
|
188
|
-
description: 'Download service',
|
|
189
188
|
files: '',
|
|
190
|
-
datatokenAddress: '
|
|
191
|
-
serviceEndpoint: 'http://
|
|
189
|
+
datatokenAddress: '0xa15024b732A8f2146423D14209eFd074e61964F3',
|
|
190
|
+
serviceEndpoint: 'http://127.0.0.1:8001',
|
|
192
191
|
timeout: 0
|
|
193
192
|
}
|
|
194
193
|
]
|
package/ComputeExamples.md
CHANGED
|
@@ -14,6 +14,8 @@ Here are the steps:
|
|
|
14
14
|
9. [Consumer fetches compute environment](#9-get-compute-environments)
|
|
15
15
|
10. [Consumer starts a free compute job using a free C2D environment](#10-consumer-starts-a-compute-job)
|
|
16
16
|
11. [Check compute status and get download compute results url](#11-check-compute-status-and-get-download-compute-results-url)
|
|
17
|
+
12. [Consumer starts a paid compute job](#12-consumer-starts-a-paid-compute-job)
|
|
18
|
+
13. [Check paid compute job status and get download compute results URL](#13-check-paid-compute-job-status-and-get-download-compute-results-url)
|
|
17
19
|
|
|
18
20
|
Let's go through each step.
|
|
19
21
|
|
|
@@ -143,12 +145,15 @@ import {
|
|
|
143
145
|
ConfigHelper,
|
|
144
146
|
getEventFromTx,
|
|
145
147
|
amountToUnits,
|
|
146
|
-
isDefined
|
|
148
|
+
isDefined,
|
|
149
|
+
ComputeResourceRequest,
|
|
150
|
+
unitsToAmount
|
|
147
151
|
} from '../../src/index.js'
|
|
148
|
-
```
|
|
149
152
|
import crypto from 'crypto-js'
|
|
150
153
|
import { DDO } from '@oceanprotocol/ddo-js'
|
|
154
|
+
import { EscrowContract } from '../../src/contracts/Escrow.js'
|
|
151
155
|
const { SHA256 } = crypto
|
|
156
|
+
```
|
|
152
157
|
|
|
153
158
|
### 4.2. Constants and variables
|
|
154
159
|
|
|
@@ -183,7 +188,7 @@ Next, we define the metadata for the dataset and algorithm that will describe ou
|
|
|
183
188
|
```Typescript
|
|
184
189
|
const DATASET_DDO: DDO = {
|
|
185
190
|
'@context': ['https://w3id.org/did/v1'],
|
|
186
|
-
id: '
|
|
191
|
+
id: 'did:op:efba17455c127a885ec7830d687a8f6e64f5ba559f8506f8723c1f10f05c049c',
|
|
187
192
|
version: '4.1.0',
|
|
188
193
|
chainId: 8996,
|
|
189
194
|
nftAddress: '0x0',
|
|
@@ -201,16 +206,16 @@ const DATASET_DDO: DDO = {
|
|
|
201
206
|
},
|
|
202
207
|
services: [
|
|
203
208
|
{
|
|
204
|
-
id: '
|
|
209
|
+
id: '1155995dda741e93afe4b1c6ced2d01734a6ec69865cc0997daf1f4db7259a36',
|
|
205
210
|
type: 'compute',
|
|
206
211
|
files: '',
|
|
207
212
|
datatokenAddress: '0xa15024b732A8f2146423D14209eFd074e61964F3',
|
|
208
|
-
serviceEndpoint: '
|
|
213
|
+
serviceEndpoint: 'http://127.0.0.1:8001',
|
|
209
214
|
timeout: 300,
|
|
210
215
|
compute: {
|
|
211
|
-
publisherTrustedAlgorithmPublishers: [],
|
|
212
|
-
publisherTrustedAlgorithms: [],
|
|
213
|
-
allowRawAlgorithm:
|
|
216
|
+
publisherTrustedAlgorithmPublishers: [] as any,
|
|
217
|
+
publisherTrustedAlgorithms: [] as any,
|
|
218
|
+
allowRawAlgorithm: false,
|
|
214
219
|
allowNetworkAccess: true
|
|
215
220
|
}
|
|
216
221
|
}
|
|
@@ -248,11 +253,11 @@ const ALGORITHM_DDO: DDO = {
|
|
|
248
253
|
},
|
|
249
254
|
services: [
|
|
250
255
|
{
|
|
251
|
-
id: '
|
|
256
|
+
id: 'db164c1b981e4d2974e90e61bda121512e6909c1035c908d68933ae4cfaba6b0',
|
|
252
257
|
type: 'access',
|
|
253
258
|
files: '',
|
|
254
259
|
datatokenAddress: '0xa15024b732A8f2146423D14209eFd074e61964F3',
|
|
255
|
-
serviceEndpoint: '
|
|
260
|
+
serviceEndpoint: 'http://127.0.0.1:8001',
|
|
256
261
|
timeout: 300
|
|
257
262
|
}
|
|
258
263
|
]
|
|
@@ -609,10 +614,7 @@ Now, let's check that we successfully published a algorithm (create NFT + Datato
|
|
|
609
614
|
|
|
610
615
|
let's check the free compute environment
|
|
611
616
|
```Typescript
|
|
612
|
-
const computeEnv = computeEnvs.find(
|
|
613
|
-
(ce) =>
|
|
614
|
-
!ce?.fees || ce.fees.find((fee) => fee.symbol === 'OCEAN' && fee.amount === '0')
|
|
615
|
-
)
|
|
617
|
+
const computeEnv = computeEnvs.find((ce) => isDefined(ce.free))
|
|
616
618
|
console.log('Free compute environment = ', computeEnv)
|
|
617
619
|
```
|
|
618
620
|
<!--
|
|
@@ -630,7 +632,6 @@ let's check the free compute environment
|
|
|
630
632
|
const mytime = new Date()
|
|
631
633
|
const computeMinutes = 5
|
|
632
634
|
mytime.setMinutes(mytime.getMinutes() + computeMinutes)
|
|
633
|
-
const computeValidUntil = Math.floor(mytime.getTime() / 1000)
|
|
634
635
|
|
|
635
636
|
```
|
|
636
637
|
Let's prepare the dataset and algorithm assets to be used in the compute job
|
|
@@ -641,7 +642,6 @@ let's check the free compute environment
|
|
|
641
642
|
serviceId: resolvedDatasetDdo.services[0].id
|
|
642
643
|
}
|
|
643
644
|
]
|
|
644
|
-
const dtAddressArray = [resolvedDatasetDdo.services[0].datatokenAddress]
|
|
645
645
|
|
|
646
646
|
const algo: ComputeAlgorithm = {
|
|
647
647
|
documentId: resolvedAlgorithmDdo.id,
|
|
@@ -650,39 +650,6 @@ let's check the free compute environment
|
|
|
650
650
|
}
|
|
651
651
|
```
|
|
652
652
|
|
|
653
|
-
<!--
|
|
654
|
-
// const providerInitializeComputeResults = await ProviderInstance.initializeCompute(
|
|
655
|
-
// assets,
|
|
656
|
-
// algo,
|
|
657
|
-
// computeEnv.id,
|
|
658
|
-
// computeValidUntil,
|
|
659
|
-
// providerUrl,
|
|
660
|
-
// consumerAccount
|
|
661
|
-
// )
|
|
662
|
-
// console.log('providerInitializeComputeResults = ', providerInitializeComputeResults)
|
|
663
|
-
//
|
|
664
|
-
//
|
|
665
|
-
// assert(!('error' in providerInitializeComputeResults), 'Cannot order algorithm')
|
|
666
|
-
//
|
|
667
|
-
//
|
|
668
|
-
// algo.transferTxId = await handleOrder(
|
|
669
|
-
// providerInitializeComputeResults.algorithm,
|
|
670
|
-
// resolvedAlgorithmDdo.services[0].datatokenAddress,
|
|
671
|
-
// consumerAccount,
|
|
672
|
-
// computeEnv.consumerAddress,
|
|
673
|
-
// 0
|
|
674
|
-
// )
|
|
675
|
-
// for (let i = 0; i < providerInitializeComputeResults.datasets.length; i++) {
|
|
676
|
-
// assets[i].transferTxId = await handleOrder(
|
|
677
|
-
// providerInitializeComputeResults.datasets[i],
|
|
678
|
-
// dtAddressArray[i],
|
|
679
|
-
// consumerAccount,
|
|
680
|
-
// computeEnv.consumerAddress,
|
|
681
|
-
// 0
|
|
682
|
-
// )
|
|
683
|
-
// }
|
|
684
|
-
-->
|
|
685
|
-
|
|
686
653
|
Let's start the free compute job
|
|
687
654
|
```Typescript
|
|
688
655
|
const computeJobs = await ProviderInstance.freeComputeStart(
|
|
@@ -756,6 +723,252 @@ let's check the free compute environment
|
|
|
756
723
|
} else {
|
|
757
724
|
-->
|
|
758
725
|
|
|
726
|
+
```Typescript
|
|
727
|
+
await sleep(10000)
|
|
728
|
+
const downloadURL = await ProviderInstance.getComputeResultUrl(
|
|
729
|
+
providerUrl,
|
|
730
|
+
consumerAccount,
|
|
731
|
+
computeJobId,
|
|
732
|
+
0
|
|
733
|
+
)
|
|
734
|
+
```
|
|
735
|
+
<!--
|
|
736
|
+
assert(downloadURL, 'Provider getComputeResultUrl failed!')
|
|
737
|
+
-->
|
|
738
|
+
Let's check the compute results url for the specified index
|
|
739
|
+
```Typescript
|
|
740
|
+
console.log(`Compute results URL: ${downloadURL}`)
|
|
741
|
+
```
|
|
742
|
+
<!--
|
|
743
|
+
}
|
|
744
|
+
}).timeout(40000)
|
|
745
|
+
-->
|
|
746
|
+
|
|
747
|
+
## 12. Consumer starts a paid compute job
|
|
748
|
+
|
|
749
|
+
### 12.1 Start a compute job using a paid C2D resources
|
|
750
|
+
<!--
|
|
751
|
+
datatoken = new Datatoken(
|
|
752
|
+
consumerAccount,
|
|
753
|
+
(await consumerAccount.provider.getNetwork()).chainId
|
|
754
|
+
)
|
|
755
|
+
-->
|
|
756
|
+
|
|
757
|
+
let's select compute environment which have free and paid resources
|
|
758
|
+
```Typescript
|
|
759
|
+
const computeEnv = computeEnvs[0]
|
|
760
|
+
console.log('Compute environment = ', computeEnv)
|
|
761
|
+
```
|
|
762
|
+
<!--
|
|
763
|
+
assert(computeEnv, 'Cannot find the compute env')
|
|
764
|
+
-->
|
|
765
|
+
|
|
766
|
+
<!--
|
|
767
|
+
const paymentToken = addresses.Ocean
|
|
768
|
+
computeRoutePath = await ProviderInstance.getComputeStartRoutes(providerUrl, false)
|
|
769
|
+
if (isDefined(computeRoutePath)) {
|
|
770
|
+
-->
|
|
771
|
+
|
|
772
|
+
Let's have 5 minute of compute access
|
|
773
|
+
```Typescript
|
|
774
|
+
|
|
775
|
+
const mytime = new Date()
|
|
776
|
+
const computeMinutes = 5
|
|
777
|
+
mytime.setMinutes(mytime.getMinutes() + computeMinutes)
|
|
778
|
+
const computeValidUntil = Math.floor(mytime.getTime() / 1000)
|
|
779
|
+
|
|
780
|
+
```
|
|
781
|
+
|
|
782
|
+
Let's prepare the dataset and algorithm assets to be used in the compute job
|
|
783
|
+
```Typescript
|
|
784
|
+
const resources: ComputeResourceRequest[] = [
|
|
785
|
+
{
|
|
786
|
+
id: 'cpu',
|
|
787
|
+
amount: 2
|
|
788
|
+
},
|
|
789
|
+
{
|
|
790
|
+
id: 'ram',
|
|
791
|
+
amount: 1000000000
|
|
792
|
+
},
|
|
793
|
+
{
|
|
794
|
+
id: 'disk',
|
|
795
|
+
amount: 0
|
|
796
|
+
}
|
|
797
|
+
]
|
|
798
|
+
const assets: ComputeAsset[] = [
|
|
799
|
+
{
|
|
800
|
+
documentId: resolvedDatasetDdo.id,
|
|
801
|
+
serviceId: resolvedDatasetDdo.services[0].id
|
|
802
|
+
}
|
|
803
|
+
]
|
|
804
|
+
const dtAddressArray = [resolvedDatasetDdo.services[0].datatokenAddress]
|
|
805
|
+
const algo: ComputeAlgorithm = {
|
|
806
|
+
documentId: resolvedAlgorithmDdo.id,
|
|
807
|
+
serviceId: resolvedAlgorithmDdo.services[0].id,
|
|
808
|
+
meta: resolvedAlgorithmDdo.metadata.algorithm
|
|
809
|
+
}
|
|
810
|
+
```
|
|
811
|
+
|
|
812
|
+
Triggering initialize compute to see payment options
|
|
813
|
+
```Typescript
|
|
814
|
+
const providerInitializeComputeResults = await ProviderInstance.initializeCompute(
|
|
815
|
+
assets,
|
|
816
|
+
algo,
|
|
817
|
+
computeEnv.id,
|
|
818
|
+
paymentToken,
|
|
819
|
+
computeValidUntil,
|
|
820
|
+
providerUrl,
|
|
821
|
+
consumerAccount,
|
|
822
|
+
resources
|
|
823
|
+
)
|
|
824
|
+
|
|
825
|
+
console.log(
|
|
826
|
+
'providerInitializeComputeResults = ',
|
|
827
|
+
JSON.stringify(providerInitializeComputeResults)
|
|
828
|
+
)
|
|
829
|
+
|
|
830
|
+
```
|
|
831
|
+
|
|
832
|
+
<!--
|
|
833
|
+
assert(!('error' in providerInitializeComputeResults), 'Cannot order algorithm')
|
|
834
|
+
-->
|
|
835
|
+
|
|
836
|
+
Let's check funds for escrow payment
|
|
837
|
+
```Typescript
|
|
838
|
+
const escrow = new EscrowContract(
|
|
839
|
+
ethers.utils.getAddress(providerInitializeComputeResults.payment.escrowAddress),
|
|
840
|
+
consumerAccount
|
|
841
|
+
)
|
|
842
|
+
const paymentTokenPublisher = new Datatoken(publisherAccount)
|
|
843
|
+
const balancePublisherPaymentToken = await paymentTokenPublisher.balance(
|
|
844
|
+
paymentToken,
|
|
845
|
+
await publisherAccount.getAddress()
|
|
846
|
+
)
|
|
847
|
+
assert(
|
|
848
|
+
ethers.utils.parseEther(balancePublisherPaymentToken) > ethers.BigNumber.from(0),
|
|
849
|
+
'Balance should be higher than 0'
|
|
850
|
+
)
|
|
851
|
+
const tx = await publisherAccount.sendTransaction({
|
|
852
|
+
to: computeEnv.consumerAddress,
|
|
853
|
+
value: ethers.utils.parseEther('1.5')
|
|
854
|
+
})
|
|
855
|
+
await tx.wait()
|
|
856
|
+
|
|
857
|
+
await paymentTokenPublisher.transfer(
|
|
858
|
+
paymentToken,
|
|
859
|
+
ethers.utils.getAddress(computeEnv.consumerAddress),
|
|
860
|
+
(Number(balancePublisherPaymentToken) / 2).toString()
|
|
861
|
+
)
|
|
862
|
+
const amountToDeposit = (
|
|
863
|
+
providerInitializeComputeResults.payment.amount * 2
|
|
864
|
+
).toString()
|
|
865
|
+
await escrow.verifyFundsForEscrowPayment(
|
|
866
|
+
paymentToken,
|
|
867
|
+
computeEnv.consumerAddress,
|
|
868
|
+
await unitsToAmount(consumerAccount, paymentToken, amountToDeposit),
|
|
869
|
+
providerInitializeComputeResults.payment.amount.toString(),
|
|
870
|
+
providerInitializeComputeResults.payment.minLockSeconds.toString(),
|
|
871
|
+
'10'
|
|
872
|
+
)
|
|
873
|
+
```
|
|
874
|
+
|
|
875
|
+
Let's order assets
|
|
876
|
+
```Typescript
|
|
877
|
+
|
|
878
|
+
algo.transferTxId = await handleOrder(
|
|
879
|
+
providerInitializeComputeResults.algorithm,
|
|
880
|
+
resolvedAlgorithmDdo.services[0].datatokenAddress,
|
|
881
|
+
consumerAccount,
|
|
882
|
+
computeEnv.consumerAddress,
|
|
883
|
+
0
|
|
884
|
+
)
|
|
885
|
+
for (let i = 0; i < providerInitializeComputeResults.datasets.length; i++) {
|
|
886
|
+
assets[i].transferTxId = await handleOrder(
|
|
887
|
+
providerInitializeComputeResults.datasets[i],
|
|
888
|
+
dtAddressArray[i],
|
|
889
|
+
consumerAccount,
|
|
890
|
+
computeEnv.consumerAddress,
|
|
891
|
+
0
|
|
892
|
+
)
|
|
893
|
+
}
|
|
894
|
+
```
|
|
895
|
+
|
|
896
|
+
Let's start compute job
|
|
897
|
+
```Typescript
|
|
898
|
+
const computeJobs = await ProviderInstance.computeStart(
|
|
899
|
+
providerUrl,
|
|
900
|
+
consumerAccount,
|
|
901
|
+
computeEnv.id,
|
|
902
|
+
assets,
|
|
903
|
+
algo,
|
|
904
|
+
computeValidUntil,
|
|
905
|
+
paymentToken,
|
|
906
|
+
resources,
|
|
907
|
+
(
|
|
908
|
+
await consumerAccount.provider.getNetwork()
|
|
909
|
+
).chainId
|
|
910
|
+
)
|
|
911
|
+
```
|
|
912
|
+
|
|
913
|
+
<!--
|
|
914
|
+
assert(computeJobs, 'Cannot start compute job')
|
|
915
|
+
-->
|
|
916
|
+
|
|
917
|
+
Let's save the compute job it, we re going to use later
|
|
918
|
+
```Typescript
|
|
919
|
+
computeJobId = computeJobs[0].jobId
|
|
920
|
+
```
|
|
921
|
+
<!--
|
|
922
|
+
} else {
|
|
923
|
+
assert(
|
|
924
|
+
computeRoutePath === null,
|
|
925
|
+
'Route path for free compute is not defined (perhaps because provider does not support it yet?)'
|
|
926
|
+
)
|
|
927
|
+
hasFreeComputeSupport = false
|
|
928
|
+
}
|
|
929
|
+
}).timeout(40000)
|
|
930
|
+
-->
|
|
931
|
+
|
|
932
|
+
## 13. Check paid compute job status and get download compute results URL
|
|
933
|
+
### 13.1 Check compute status for paid compute job
|
|
934
|
+
<!--
|
|
935
|
+
if (!hasFreeComputeSupport) {
|
|
936
|
+
assert(
|
|
937
|
+
computeRoutePath === null,
|
|
938
|
+
'Compute route path for free compute is not defined (perhaps because provider does not support it yet?)'
|
|
939
|
+
)
|
|
940
|
+
} else {
|
|
941
|
+
-->
|
|
942
|
+
You can also add various delays so you see the various states of the compute job
|
|
943
|
+
```Typescript
|
|
944
|
+
const jobStatus = await ProviderInstance.computeStatus(
|
|
945
|
+
providerUrl,
|
|
946
|
+
await consumerAccount.getAddress(),
|
|
947
|
+
computeJobId
|
|
948
|
+
)
|
|
949
|
+
```
|
|
950
|
+
<!--
|
|
951
|
+
assert(jobStatus, 'Cannot retrieve compute status!')
|
|
952
|
+
-->
|
|
953
|
+
Now, let's see the current status of the previously started computer job
|
|
954
|
+
```Typescript
|
|
955
|
+
console.log('Current status of the compute job: ', jobStatus)
|
|
956
|
+
```
|
|
957
|
+
<!--
|
|
958
|
+
}
|
|
959
|
+
}).timeout(40000)
|
|
960
|
+
-->
|
|
961
|
+
|
|
962
|
+
### 13.2 Get download compute results URL
|
|
963
|
+
<!--
|
|
964
|
+
if (!hasFreeComputeSupport) {
|
|
965
|
+
assert(
|
|
966
|
+
computeRoutePath === null,
|
|
967
|
+
'Compute route path for paid compute is not defined (perhaps because provider does not support it yet?)'
|
|
968
|
+
)
|
|
969
|
+
} else {
|
|
970
|
+
-->
|
|
971
|
+
|
|
759
972
|
```Typescript
|
|
760
973
|
await sleep(10000)
|
|
761
974
|
const downloadURL = await ProviderInstance.getComputeResultUrl(
|