From 75b1adb699dd6f25bf59b4311c077c6aba5ee61e Mon Sep 17 00:00:00 2001 From: Matthias Kretschmann Date: Tue, 15 Sep 2020 21:28:27 +0200 Subject: [PATCH] prepare strict type checking, bunch of typing fixes --- package-lock.json | 23 ++++++++++++ package.json | 1 + src/hooks/useConsume/useConsume.ts | 10 ++++-- src/hooks/useMetadata/useMetadata.ts | 14 ++++---- src/hooks/usePublish/PriceOptions.ts | 2 +- src/hooks/usePublish/usePublish.ts | 23 +++++++----- src/providers/OceanProvider/OceanProvider.tsx | 10 +++--- src/utils/dtUtils.ts | 36 +++++++++++++------ src/utils/index.ts | 4 ++- tsconfig.json | 11 +++--- 10 files changed, 94 insertions(+), 40 deletions(-) diff --git a/package-lock.json b/package-lock.json index 032ec49..5dbecc1 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1740,6 +1740,29 @@ "resolved": "https://registry.npmjs.org/@types/node/-/node-12.12.54.tgz", "integrity": "sha512-ge4xZ3vSBornVYlDnk7yZ0gK6ChHf/CHB7Gl1I0Jhah8DDnEQqBzgohYG4FX4p81TNirSETOiSyn+y1r9/IR6w==" }, + "@types/node-fetch": { + "version": "2.5.7", + "resolved": "https://registry.npmjs.org/@types/node-fetch/-/node-fetch-2.5.7.tgz", + "integrity": "sha512-o2WVNf5UhWRkxlf6eq+jMZDu7kjgpgJfl4xVNlvryc95O/6F2ld8ztKX+qu+Rjyet93WAWm5LjeX9H5FGkODvw==", + "dev": true, + "requires": { + "@types/node": "*", + "form-data": "^3.0.0" + }, + "dependencies": { + "form-data": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-3.0.0.tgz", + "integrity": "sha512-CKMFDglpbMi6PyN+brwB9Q/GOw0eAnsrEZDgcsH5Krhz5Od/haKHAX0NmQfha2zPPz0JpWzA7GJHGSnvCRLWsg==", + "dev": true, + "requires": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.8", + "mime-types": "^2.1.12" + } + } + } + }, "@types/parse-json": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/@types/parse-json/-/parse-json-4.0.0.tgz", diff --git a/package.json b/package.json index 7f508c7..c0ee09b 100644 --- a/package.json +++ b/package.json @@ -33,6 +33,7 @@ }, "devDependencies": { "@release-it/bumper": "^2.0.0", + "@types/node-fetch": "^2.5.7", "@types/react": "^16.9.49", "@typescript-eslint/eslint-plugin": "^4.0.1", "@typescript-eslint/parser": "^4.0.1", diff --git a/src/hooks/useConsume/useConsume.ts b/src/hooks/useConsume/useConsume.ts index 8e81b45..8f93fef 100644 --- a/src/hooks/useConsume/useConsume.ts +++ b/src/hooks/useConsume/useConsume.ts @@ -37,7 +37,7 @@ function useConsume(): UseConsume { } async function consume( - did: string, + did: DID | string, dataTokenAddress: string, serviceType: ServiceType = 'access' ): Promise { @@ -50,7 +50,11 @@ function useConsume(): UseConsume { await checkAndBuyDT(ocean, dataTokenAddress, account, config) setStep(1) - const order = await ocean.assets.order(did, serviceType, accountId) + const order = await ocean.assets.order( + did as string, + serviceType, + accountId + ) Logger.log('order created', order) setStep(2) const res = JSON.parse(order) @@ -65,7 +69,7 @@ function useConsume(): UseConsume { Logger.log('token transfered', tokenTransfer) setStep(3) await ocean.assets.download( - did, + did as string, (tokenTransfer as any).transactionHash, dataTokenAddress, account, diff --git a/src/hooks/useMetadata/useMetadata.ts b/src/hooks/useMetadata/useMetadata.ts index dfd47eb..fe9e7fb 100644 --- a/src/hooks/useMetadata/useMetadata.ts +++ b/src/hooks/useMetadata/useMetadata.ts @@ -25,11 +25,11 @@ function useMetadata(asset?: DID | string | DDO): UseMetadata { const [isLoaded, setIsLoaded] = useState(false) const [price, setPrice] = useState() - async function getDDO(did: DID | string): Promise { - if (status === ProviderStatus.CONNECTED) { - const ddo = await ocean.metadatastore.retrieveDDO(did) - return ddo - } + async function getDDO(did: DID | string): Promise { + if (status !== ProviderStatus.CONNECTED) return null + + const ddo = await ocean.metadatastore.retrieveDDO(did) + return ddo } async function getPrice(dataTokenAddress?: string): Promise { @@ -37,8 +37,8 @@ function useMetadata(asset?: DID | string | DDO): UseMetadata { return await getBestDataTokenPrice(ocean, dataTokenAddress, accountId) } - async function getMetadata(): Promise { - if (!internalDdo) return + async function getMetadata(): Promise { + if (!internalDdo) return null const metadata = internalDdo.findServiceByType('metadata') return metadata.attributes } diff --git a/src/hooks/usePublish/PriceOptions.ts b/src/hooks/usePublish/PriceOptions.ts index 47340e8..f8e0e22 100644 --- a/src/hooks/usePublish/PriceOptions.ts +++ b/src/hooks/usePublish/PriceOptions.ts @@ -1,5 +1,5 @@ export interface PriceOptions { - price?: number + price: number tokensToMint: number type: 'fixed' | 'dynamic' | string weightOnDataToken: string diff --git a/src/hooks/usePublish/usePublish.ts b/src/hooks/usePublish/usePublish.ts index cabb518..893d79f 100644 --- a/src/hooks/usePublish/usePublish.ts +++ b/src/hooks/usePublish/usePublish.ts @@ -17,7 +17,7 @@ interface UsePublish { priceOptions: PriceOptions, serviceConfigs: ServiceType, dataTokenOptions?: DataTokenOptions - ) => Promise + ) => Promise mint: (tokenAddress: string, tokensToMint: string) => void publishStep?: number publishStepText?: string @@ -32,9 +32,9 @@ function usePublish(): UsePublish { const [publishStepText, setPublishStepText] = useState() const [publishError, setPublishError] = useState() - function setStep(index: number) { + function setStep(index?: number) { setPublishStep(index) - setPublishStepText(publishFeedback[index]) + index && setPublishStepText(publishFeedback[index]) } /** @@ -50,10 +50,12 @@ function usePublish(): UsePublish { priceOptions: PriceOptions, serviceType: ServiceType, dataTokenOptions?: DataTokenOptions - ): Promise { - if (status !== ProviderStatus.CONNECTED || !ocean || !account) return + ): Promise { + if (status !== ProviderStatus.CONNECTED || !ocean || !account) return null + setIsLoading(true) setPublishError(undefined) + try { const tokensToMint = priceOptions.tokensToMint.toString() @@ -109,7 +111,7 @@ function usePublish(): UsePublish { const origComputePrivacy = { allowRawAlgorithm: true, allowNetworkAccess: false, - trustedAlgorithms: [] + trustedAlgorithms: [] as any } const computeService = ocean.compute.createComputeService( account, @@ -146,7 +148,7 @@ function usePublish(): UsePublish { } catch (error) { setPublishError(error.message) Logger.error(error) - setStep(undefined) + setStep() } finally { setIsLoading(false) } @@ -156,7 +158,7 @@ function usePublish(): UsePublish { priceOptions: PriceOptions, dataTokenAddress: string, mintedTokens: string - ) { + ): Promise { switch (priceOptions.type) { case 'dynamic': { const pool = await ocean.pool.createDTPool( @@ -169,6 +171,11 @@ function usePublish(): UsePublish { break } case 'fixed': { + if (!config.fixedRateExchangeAddress) { + Logger.error(`'fixedRateExchangeAddress' not set in ccnfig.`) + return null + } + const fixedPriceExchange = await ocean.fixedRateExchange.create( dataTokenAddress, priceOptions.price.toString(), diff --git a/src/providers/OceanProvider/OceanProvider.tsx b/src/providers/OceanProvider/OceanProvider.tsx index b6630ed..6d591af 100644 --- a/src/providers/OceanProvider/OceanProvider.tsx +++ b/src/providers/OceanProvider/OceanProvider.tsx @@ -33,7 +33,7 @@ interface OceanProviderValue { refreshBalance: () => Promise } -const OceanContext = createContext(null) +const OceanContext = createContext({} as OceanProviderValue) function OceanProvider({ initialConfig, @@ -47,7 +47,7 @@ function OceanProvider({ const [web3, setWeb3] = useState() const [web3Provider, setWeb3Provider] = useState() const [ocean, setOcean] = useState() - const [web3Modal, setWeb3Modal] = useState(null) + const [web3Modal, setWeb3Modal] = useState() const [chainId, setChainId] = useState() const [account, setAccount] = useState() const [accountId, setAccountId] = useState() @@ -92,7 +92,7 @@ function OceanProvider({ newConfig && setConfig(newConfig) - const provider = await web3Modal.connect() + const provider = await web3Modal?.connect() setWeb3Provider(provider) const web3 = new Web3(provider) @@ -126,12 +126,12 @@ function OceanProvider({ } } async function refreshBalance() { - const balance = await getBalance(account) + const balance = account && (await getBalance(account)) setBalance(balance) } async function logout() { // TODO: #67 check how is the proper way to logout - web3Modal.clearCachedProvider() + web3Modal?.clearCachedProvider() } const handleAccountsChanged = async (accounts: string[]) => { diff --git a/src/utils/dtUtils.ts b/src/utils/dtUtils.ts index ae26aec..d6eda4a 100644 --- a/src/utils/dtUtils.ts +++ b/src/utils/dtUtils.ts @@ -8,8 +8,8 @@ export async function getCheapestPool( ocean: Ocean, accountId: string, dataTokenAddress: string -): Promise { - if (!ocean || !accountId || !dataTokenAddress) return +): Promise { + if (!ocean || !accountId || !dataTokenAddress) return null const tokenPools = await ocean.pool.searchPoolforDT( accountId, @@ -57,31 +57,35 @@ export async function getBestDataTokenPrice( Decimal.set({ precision: 5 }) const cheapestPoolPrice = new Decimal( - cheapestPool.price !== '' ? cheapestPool.price : 999999999999 + cheapestPool && cheapestPool.price !== '' + ? cheapestPool.price + : 999999999999 ) const cheapestExchangePrice = new Decimal( - cheapestExchange.price !== '' ? cheapestExchange.price : 999999999999 + cheapestExchange && cheapestExchange?.price !== '' + ? cheapestExchange.price + : 999999999999 ) if (cheapestPoolPrice < cheapestExchangePrice) { return { type: 'pool', - address: cheapestPool.address, - value: cheapestPool.price + address: cheapestPool?.address, + value: cheapestPool?.price } as BestPrice } else { return { type: 'exchange', - address: cheapestExchange.address, - value: cheapestExchange.price + address: cheapestExchange?.address, + value: cheapestExchange?.price } as BestPrice } } export async function getCheapestExchange( ocean: Ocean, dataTokenAddress: string -) { - if (!ocean || !dataTokenAddress) return +): Promise<{ address?: string; price: string } | null> { + if (!ocean || !dataTokenAddress) return null const tokenExchanges = await ocean.fixedRateExchange.searchforDT( dataTokenAddress, @@ -132,7 +136,7 @@ export async function checkAndBuyDT( account.getId() ) - switch (bestPrice.type) { + switch (bestPrice?.type) { case 'pool': { const price = new Decimal(bestPrice.value).times(1.05).toString() const maxPrice = new Decimal(bestPrice.value).times(2).toString() @@ -148,6 +152,16 @@ export async function checkAndBuyDT( return buyResponse } case 'exchange': { + if (!config.oceanTokenAddress) { + Logger.error(`'oceanTokenAddress' not set in config`) + return null + } + + if (!config.fixedRateExchangeAddress) { + Logger.error(`'fixedRateExchangeAddress' not set in config`) + return null + } + Logger.log('Buying token from exchange', bestPrice, account.getId()) await ocean.datatokens.approve( config.oceanTokenAddress, diff --git a/src/utils/index.ts b/src/utils/index.ts index 5d44cdb..ccc4435 100644 --- a/src/utils/index.ts +++ b/src/utils/index.ts @@ -14,7 +14,9 @@ export function readFileContent(file: File): Promise { }) } -export function isDDO(toBeDetermined): toBeDetermined is DDO { +export function isDDO( + toBeDetermined: DID | string | DDO +): toBeDetermined is DDO { if ((toBeDetermined as DDO).id) { return true } diff --git a/tsconfig.json b/tsconfig.json index 4055368..68ff149 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -10,9 +10,12 @@ "esModuleInterop": true, "sourceMap": true, "declaration": true, - "strictNullChecks": false, - "importHelpers": true + "importHelpers": true, + + /* Strict Type-Checking */ + // TODO: remove and adapt for `strictNullChecks` + "strict": true, + "strictNullChecks": false }, - "include": ["./src/@types", "./src/index.ts"], - "exclude": ["node_modules", "dist", "example"] + "include": ["./src/@types", "./src/index.ts"] }