1
0
mirror of https://github.com/oceanprotocol/react.git synced 2025-02-14 21:10:38 +01:00

a bunch of type fixes everywhere

This commit is contained in:
nazariyv 2020-09-11 22:49:25 +01:00
parent aa2beb665f
commit 3c362b0e83
40 changed files with 583 additions and 571 deletions

View File

@ -45,13 +45,13 @@
For use in your repo, install this library with the following command (you can alternatively use `yarn`, of course)
```bash
npm install @oceanprotocol/react
yarn add @oceanprotocol/react
```
If you want to clone this repo and work locally, then execute the following **instead** (in the root directory of this repository)
```bash
yarn install
yarn
```
## 🏄 Quick Start
@ -132,7 +132,7 @@ The project uses TypeScript and compiled with the `tsc` command.
To start the compiler in watch mode:
```bash
npm start
yarn run start
```
## ✨ Code Style
@ -141,10 +141,10 @@ For linting and auto-formatting run these from the root of the repo:
```bash
# auto format all ts & css with eslint & stylelint
npm run lint
yarn run lint
# auto format all ts & css with prettier, taking all configs into account
npm run format
yarn run format
```
## 👩‍🔬 Testing
@ -158,7 +158,7 @@ The build script will compile `src/` with [`microbundle`](https://github.com/dev
3. UMD build
```bash
npm run build
yarn build
```
## ⬆️ Releases
@ -169,9 +169,9 @@ Releases are managed semi-automatically. They are always manually triggered from
From a clean `main` branch you can run any release task bumping the version accordingly based on semantic versioning:
- To bump a patch version: `npm run release`
- To bump a minor version: `npm run release -- minor`
- To bump a major version: `npm run release -- major`
- To bump a patch version: `yarn run release`
- To bump a minor version: `yarn run release -- minor`
- To bump a major version: `yarn run release -- major`
Every task does the following:
@ -191,13 +191,13 @@ Usually from a feature branch you can release a develop version under the `next`
Say the current version is at `v1.1.0`, then to publish a pre-release for a next major version `v2.0.0-beta.0`, do:
```bash
npm run release -- major --preRelease=beta --npm.tag=next
yarn run release -- major --preRelease=beta --npm.tag=next
# consecutive releases, e.g. to then get `v2.0.0-beta.1`
npm run release -- --preRelease
yarn run release -- --preRelease
# final version, e.g. to then get `v2.0.0`
npm run release -- major
yarn run release -- major
```
## 📜 Changelog

View File

@ -1,5 +1,5 @@
module.exports = function override(config, env) {
const path = require('path')
const path = require('path');
return {
...config,
@ -10,5 +10,5 @@ module.exports = function override(config, env) {
react: path.resolve('../node_modules/react')
}
}
}
}
};
};

View File

@ -8,7 +8,6 @@
"eject": "react-app-rewired eject"
},
"dependencies": {
"@oceanprotocol/react": "file:../",
"react": "^16.13.1",
"react-dom": "^16.13.1",
"react-scripts": "3.4.3",

View File

@ -17,7 +17,7 @@
Unlike "/favicon.ico" or "favicon.ico", "%PUBLIC_URL%/favicon.ico" will
work correctly both with client-side routing and a non-root public URL.
Learn how to configure a non-root public URL by running `npm run build`.
Learn how to configure a non-root public URL by running `yarn build`.
-->
<title>React App</title>
</head>
@ -31,8 +31,8 @@
You can add webfonts, meta tags, or analytics to this file.
The build step will place the bundled scripts into the <body> tag.
To begin the development, run `npm start` or `yarn start`.
To create a production bundle, use `npm run build` or `yarn build`.
To begin the development, run `yarn start`.
To create a production bundle, use `yarn build`.
-->
</body>
</html>

View File

@ -1,45 +1,46 @@
import React from 'react'
import { useOcean } from '@oceanprotocol/react'
import { DDO } from '@oceanprotocol/lib'
import { useState } from 'react'
import { useEffect } from 'react'
import shortid from 'shortid'
import { MetadataExample } from './MetadataExample'
import React from 'react';
import { useOcean } from '@oceanprotocol/react';
import { useState } from 'react';
import { useEffect } from 'react';
import shortid from 'shortid';
import { MetadataExample } from './MetadataExample';
export function AllDdos() {
const { chainId, account, ocean } = useOcean()
const { chainId, account, ocean } = useOcean();
// ! hack. there are some deep type problems
const [ddos, setDdos] = useState<any>();
const [ddos, setDdos] = useState<DDO[] | undefined>()
const init = async () => {
if (!ocean || !account) return;
const assets = await ocean.assets.query({
page: 1,
offset: 10,
query: {},
sort: { created: -1 }
});
setDdos(assets.results.slice(0, 4));
};
useEffect(() => {
async function init() {
if (!ocean || !account) return
const assets = await ocean.assets.query({
page: 1,
offset: 10,
query: {},
sort: { created: -1 }
})
setDdos(assets.results.slice(0, 4))
}
init()
}, [ocean, account, chainId])
init();
}, [ocean, account, chainId]);
return (
<>
<div>Assets</div> <br />
<div style={{ flexDirection: 'column' }}>
{ddos?.map((ddo) => {
{/* ! TODO: hack for now. some deep nested type issues re this */}
{ddos?.map((ddo: any) => {
return (
<div key={shortid.generate()}>
<MetadataExample ddo={ddo} />
<br />
</div>
)
);
})}
</div>
</>
)
);
}

View File

@ -1,6 +1,7 @@
.app {
width: 100%;
}
.container {
display: flex;
flex-direction: column;

View File

@ -1,29 +1,28 @@
import React, { useEffect } from 'react'
import './App.css'
import { OceanProvider } from '@oceanprotocol/react'
import { Wallet } from './Wallet'
import { Publish } from './Publish'
import { ConfigHelper } from '@oceanprotocol/lib'
import { AllDdos } from './AllDdos'
import { ConsumeDdo } from './ConsumeDdo'
import { NetworkMonitor } from './NetworkMonitor'
import React, { useEffect } from 'react';
import './App.css';
import { OceanProvider } from '@oceanprotocol/react';
import { Wallet } from './Wallet';
import { Publish } from './Publish';
import { ConfigHelper } from '@oceanprotocol/lib';
import { AllDdos } from './AllDdos';
import { ConsumeDdo } from './ConsumeDdo';
import { NetworkMonitor } from './NetworkMonitor';
const configRinkeby = new ConfigHelper().getConfig('rinkeby')
const configRinkeby = new ConfigHelper().getConfig('rinkeby');
const providerOptions = {}
const providerOptions = {};
export const web3ModalOpts = {
cacheProvider: true,
providerOptions
}
};
function App() {
console.log(configRinkeby)
const init = async () => {}
const init = async () => {};
useEffect(() => {
init()
}, [])
init();
}, []);
return (
<OceanProvider initialConfig={configRinkeby} web3ModalOpts={web3ModalOpts}>
@ -43,7 +42,7 @@ function App() {
</div>
</div>
</OceanProvider>
)
);
}
export default App
export default App;

View File

@ -1,52 +1,47 @@
import React from 'react'
import {
useOcean,
useConsume,
useCompute,
computeOptions
} from '@oceanprotocol/react'
import { useState } from 'react'
import { useEffect } from 'react'
import React from 'react';
import { useOcean, useConsume, useCompute, computeOptions } from '../../src';
import { useState } from 'react';
import { useEffect } from 'react';
export function ConsumeDdo() {
const { ocean } = useOcean()
const { consumeStepText, consume, consumeError } = useConsume()
const { compute, computeStepText } = useCompute()
const [did, setDid] = useState<string | undefined>()
const { ocean } = useOcean();
const { consumeStepText, consume, consumeError } = useConsume();
const { compute, computeStepText } = useCompute();
const [did, setDid] = useState<string | undefined>();
useEffect(() => {
async function init() {}
init()
}, [ocean])
init();
}, [ocean]);
const consumeDid = async () => {
if (!did) return
const ddo = await ocean.assets.resolve(did)
if (!did) return;
const ddo = await ocean.assets.resolve(did);
await consume(did, ddo.dataToken, 'access')
}
await consume(did, ddo.dataToken, 'access');
};
const computeDid = async () => {
if (!did) return
const ddo = await ocean.assets.resolve(did)
console.log(ddo)
console.log('ocean dt', ocean.datatokens)
if (!did) return;
const ddo = await ocean.assets.resolve(did);
console.log(ddo);
console.log('ocean dt', ocean.datatokens);
const computeService = ddo.findServiceByType('compute')
console.log('ddo compute service', computeService)
const serv = ddo.findServiceById(computeService.index)
const computeService = ddo.findServiceByType('compute');
console.log('ddo compute service', computeService);
const serv = ddo.findServiceById(computeService.index);
console.log('ddo compute service resolved', serv)
console.log('ddo compute service resolved', serv);
await compute(
did,
computeService,
ddo.dataToken,
"console.log('test')",
computeOptions[0].value
)
}
);
};
const handleChange = (e: any) => {
setDid(e.target.value)
}
setDid(e.target.value);
};
return (
<>
<div>Consume</div>
@ -63,5 +58,5 @@ export function ConsumeDdo() {
</div>
<div>{consumeError}</div>
</>
)
);
}

View File

@ -1,9 +1,12 @@
import React from 'react'
import { useMetadata } from '@oceanprotocol/react'
import { DDO } from '@oceanprotocol/lib'
import React from 'react';
import { useMetadata } from '../../src';
import { DDO } from '@oceanprotocol/lib';
export function MetadataExample({ ddo }: { ddo: DDO }) {
const { title, price, did } = useMetadata(ddo)
export const MetadataExample = (ddo: any) => {
// ! if ddo: DDO then:
// ! same issue as in App.tsx:
// ! Property 'ocean' is protected but type 'Instantiable' is not a class derived from 'Instantiable'.
const { title, price, did } = useMetadata(ddo);
return (
<>
@ -18,5 +21,5 @@ export function MetadataExample({ ddo }: { ddo: DDO }) {
)}
</div>
</>
)
}
);
};

View File

@ -1,28 +1,28 @@
import React, { useCallback } from 'react'
import { useOcean } from '@oceanprotocol/react'
import { ConfigHelper } from '@oceanprotocol/lib'
import { useEffect } from 'react'
import React, { useCallback } from 'react';
import { useOcean } from '../../src';
import { ConfigHelper } from '@oceanprotocol/lib';
import { useEffect } from 'react';
export const NetworkMonitor = () => {
const { connect, web3Provider } = useOcean()
const { connect, web3Provider } = useOcean();
const handleNetworkChanged = useCallback(
(chainId: number) => {
const config = new ConfigHelper().getConfig(chainId)
connect(config)
(chainId: string) => {
const config = new ConfigHelper().getConfig(chainId);
connect(config);
},
[connect]
)
);
useEffect(() => {
if (!web3Provider) return
if (!web3Provider) return;
web3Provider.on('chainChanged', handleNetworkChanged)
web3Provider.on('chainChanged', handleNetworkChanged);
return () => {
web3Provider.removeListener('chainChanged', handleNetworkChanged)
}
}, [web3Provider, handleNetworkChanged])
web3Provider.removeListener('chainChanged', handleNetworkChanged);
};
}, [web3Provider, handleNetworkChanged]);
return <></>
}
return <></>;
};

View File

@ -1,13 +1,12 @@
import React from 'react'
import { usePublish } from '@oceanprotocol/react'
// import { useOcean, usePublish } from '@oceanprotocol/react'
import { DDO } from '@oceanprotocol/lib'
import { useState } from 'react'
import { Metadata } from '@oceanprotocol/lib/dist/node/ddo/interfaces/Metadata'
import React from 'react';
import { usePublish } from '../../src';
import { DDO } from '@oceanprotocol/lib';
import { useState } from 'react';
import { Metadata } from '@oceanprotocol/lib/dist/node/ddo/interfaces/Metadata';
export function Publish() {
const { publish, publishStepText, isLoading } = usePublish()
const [ddo, setDdo] = useState<DDO | undefined>()
const { publish, publishStepText, isLoading } = usePublish();
const [ddo, setDdo] = useState<DDO>();
const asset = {
main: {
@ -28,7 +27,7 @@ export function Publish() {
}
]
}
}
};
const publishAsset = async () => {
const priceOptions = {
@ -37,12 +36,12 @@ export function Publish() {
type: 'fixed',
weightOnDataToken: '',
liquidityProviderFee: ''
}
};
const ddo = await publish(asset as Metadata, priceOptions, 'access')
console.log(ddo)
setDdo(ddo)
}
// ! same issue as in App.tsx again
const ddo: any = await publish(asset as Metadata, priceOptions, 'access');
setDdo(ddo);
};
return (
<>
<div>Publish</div>
@ -54,5 +53,5 @@ export function Publish() {
</div>
<div>DID: {ddo && ddo.id} </div>
</>
)
);
}

View File

@ -1,27 +1,27 @@
import React, { useCallback } from 'react'
import { useOcean } from '@oceanprotocol/react'
import { useEffect } from 'react'
import React, { useCallback } from 'react';
import { useOcean } from '../../src';
import { useEffect } from 'react';
export function Wallet() {
const { ocean, connect, logout, accountId } = useOcean()
const { ocean, connect, logout, accountId } = useOcean();
const conn = async () => {
await connect()
}
await connect();
};
const init = useCallback(async () => {
if (ocean === undefined || accountId === undefined) return
await ocean.assets.ownerAssets(accountId)
}, [accountId, ocean])
if (ocean === undefined || accountId === undefined) return;
await ocean.assets.ownerAssets(accountId);
}, [accountId, ocean]);
useEffect(() => {
init()
}, [ocean, accountId, init])
init();
}, [ocean, accountId, init]);
const disc = async () => {
await logout()
await conn()
}
await logout();
await conn();
};
return (
<>
@ -34,5 +34,5 @@ export function Wallet() {
</div>
<div>{accountId}</div>
</>
)
);
}

View File

@ -1,11 +1,11 @@
import React from 'react'
import ReactDOM from 'react-dom'
import './index.css'
import App from './App'
import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import App from './App';
ReactDOM.render(
<React.StrictMode>
<App />
</React.StrictMode>,
document.getElementById('root')
)
);

View File

@ -13,7 +13,11 @@
"resolveJsonModule": true,
"isolatedModules": true,
"noEmit": true,
"jsx": "react"
"jsx": "react",
"baseUrl": "../src",
"paths": {
"@oceanprotocol/react": ["index.ts"]
}
},
"include": ["src"]
}

View File

@ -9,14 +9,14 @@
"types": "dist/index.d.ts",
"scripts": {
"start": "microbundle watch --no-compress --jsx React.createElement",
"start-example": "cd example && npm start",
"start-example": "cd example && yarn start",
"build": "rm -rf dist && microbundle build --no-compress --jsx React.createElement",
"test": "npm run lint && npm run type-check",
"test": "yarn run lint && yarn run type-check",
"lint": "eslint --ignore-path .eslintignore --ext .js --ext .ts --ext .tsx .",
"format": "prettier --ignore-path .gitignore './**/*.{css,yml,js,ts,tsx,json}' --write",
"release": "release-it --non-interactive",
"changelog": "auto-changelog -p",
"prepublishOnly": "npm run build",
"prepublishOnly": "yarn run build",
"type-check": "tsc --noEmit"
},
"files": [
@ -28,6 +28,7 @@
"@oceanprotocol/lib": "^0.2.4",
"axios": "^0.20.0",
"decimal.js": "^10.2.0",
"eslint-plugin-standard": "^4.0.1",
"web3": "^1.2.11",
"web3modal": "^1.9.0"
},
@ -40,6 +41,9 @@
"eslint": "^7.8.1",
"eslint-config-oceanprotocol": "^1.5.0",
"eslint-config-prettier": "^6.11.0",
"eslint-import-resolver-typescript": "^2.3.0",
"eslint-plugin-import": "^2.22.0",
"eslint-plugin-node": "^11.1.0",
"eslint-plugin-prettier": "^3.1.4",
"eslint-plugin-react": "^7.20.5",
"microbundle": "^0.12.3",
@ -63,7 +67,7 @@
"homepage": "https://github.com/oceanprotocol/react#readme",
"release-it": {
"hooks": {
"after:bump": "npm run changelog"
"after:bump": "yarn run changelog"
},
"plugins": {
"@release-it/bumper": {

View File

@ -1,6 +1,5 @@
import Web3 from 'web3'
import { HttpProvider } from 'web3-core'
import { HttpProvider } from 'web3-core';
interface EthereumProvider extends HttpProvider {
enable: () => Promise<void>
enable: () => Promise<void>;
}

View File

@ -1,4 +1,4 @@
export * from './useConsume'
export * from './useMetadata'
export * from './usePublish'
export * from './useCompute'
export * from './useConsume';
export * from './useMetadata';
export * from './usePublish';
export * from './useCompute';

View File

@ -1,11 +1,11 @@
export interface ComputeValue {
entrypoint: string
image: string
tag: string
entrypoint: string;
image: string;
tag: string;
}
export interface ComputeOption {
name: string
value: ComputeValue
name: string;
value: ComputeValue;
}
export const computeOptions: ComputeOption[] = [
@ -25,4 +25,4 @@ export const computeOptions: ComputeOption[] = [
tag: 'python-panda'
}
}
]
];

View File

@ -1,2 +1,2 @@
export * from './useCompute'
export * from './ComputeOptions'
export * from './useCompute';
export * from './ComputeOptions';

View File

@ -1,11 +1,10 @@
import { useState } from 'react'
import { useOcean } from '../../providers'
import { ComputeValue } from './ComputeOptions'
import { feedback } from './../../utils'
import { DID, Logger } from '@oceanprotocol/lib'
import { MetadataAlgorithm } from '@oceanprotocol/lib/dist/node/ddo/interfaces/MetadataAlgorithm'
import { ComputeJob } from '@oceanprotocol/lib/dist/node/ocean/interfaces/ComputeJob'
import { checkAndBuyDT } from '../../utils/dtUtils'
import { useState } from 'react';
import { useOcean } from '../../providers';
import { ComputeValue } from './ComputeOptions';
import { Logger } from '@oceanprotocol/lib';
import { MetadataAlgorithm } from '@oceanprotocol/lib/dist/node/ddo/interfaces/MetadataAlgorithm';
import { ComputeJob } from '@oceanprotocol/lib/dist/node/ocean/interfaces/ComputeJob';
import { checkAndBuyDT } from '../../utils/dtUtils';
interface UseCompute {
compute: (
@ -14,11 +13,11 @@ interface UseCompute {
dataTokenAddress: string,
algorithmRawCode: string,
computeContainer: ComputeValue
) => Promise<ComputeJob>
computeStep?: number
computeStepText?: string
computeError?: string
isLoading: boolean
) => Promise<ComputeJob>;
computeStep?: number;
computeStepText?: string;
computeError?: string;
isLoading: boolean;
}
// TODO: customize for compute
@ -26,7 +25,7 @@ export const computeFeedback: { [key in number]: string } = {
0: '1/3 Ordering asset...',
1: '2/3 Transfering data token.',
2: '3/3 Access granted. Starting job...'
}
};
const rawAlgorithmMeta: MetadataAlgorithm = {
rawcode: `console.log('Hello world'!)`,
format: 'docker-image',
@ -36,18 +35,18 @@ const rawAlgorithmMeta: MetadataAlgorithm = {
image: '',
tag: ''
}
}
};
function useCompute(): UseCompute {
const { ocean, account, accountId, config } = useOcean()
const [computeStep, setComputeStep] = useState<number | undefined>()
const [computeStepText, setComputeStepText] = useState<string | undefined>()
const [computeError, setComputeError] = useState<string | undefined>()
const [isLoading, setIsLoading] = useState(false)
const { ocean, account, accountId, config } = useOcean();
const [computeStep, setComputeStep] = useState<number | undefined>();
const [computeStepText, setComputeStepText] = useState<string | undefined>();
const [computeError, setComputeError] = useState<string | undefined>();
const [isLoading, setIsLoading] = useState(false);
function setStep(index: number) {
setComputeStep(index)
setComputeStepText(computeFeedback[index])
setComputeStep(index);
setComputeStepText(computeFeedback[index]);
}
async function compute(
@ -57,44 +56,44 @@ function useCompute(): UseCompute {
algorithmRawCode: string,
computeContainer: ComputeValue
): Promise<ComputeJob> {
if (!ocean || !account) return
if (!ocean || !account) return;
setComputeError(undefined)
setComputeError(undefined);
try {
setIsLoading(true)
setStep(0)
setIsLoading(true);
setStep(0);
await checkAndBuyDT(ocean, dataTokenAddress, account, config)
rawAlgorithmMeta.container = computeContainer
rawAlgorithmMeta.rawcode = algorithmRawCode
await checkAndBuyDT(ocean, dataTokenAddress, account, config);
rawAlgorithmMeta.container = computeContainer;
rawAlgorithmMeta.rawcode = algorithmRawCode;
const output = {}
const output = {};
Logger.log(
'compute order',
accountId,
did,
computeService,
rawAlgorithmMeta
)
);
const order = await ocean.compute.order(
accountId,
did,
computeService.index,
undefined,
rawAlgorithmMeta
)
);
setStep(1)
const computeOrder = JSON.parse(order)
Logger.log('compute order', computeOrder)
setStep(1);
const computeOrder = JSON.parse(order);
Logger.log('compute order', computeOrder);
const tokenTransfer = await ocean.datatokens.transferWei(
computeOrder.dataToken,
computeOrder.to,
String(computeOrder.numTokens),
computeOrder.from
)
setStep(2)
);
setStep(2);
const response = await ocean.compute.start(
did,
(tokenTransfer as any).transactionHash,
@ -105,19 +104,19 @@ function useCompute(): UseCompute {
output,
computeService.index,
computeService.type
)
return response
);
return response;
} catch (error) {
Logger.error(error)
setComputeError(error.message)
Logger.error(error);
setComputeError(error.message);
} finally {
setStep(undefined)
setIsLoading(false)
setStep(undefined);
setIsLoading(false);
}
}
return { compute, computeStep, computeStepText, computeError, isLoading }
return { compute, computeStep, computeStepText, computeError, isLoading };
}
export { useCompute, UseCompute }
export default UseCompute
export { useCompute, UseCompute };
export default UseCompute;

View File

@ -1 +1 @@
export * from './useConsume'
export * from './useConsume';

View File

@ -1,19 +1,19 @@
import { useState } from 'react'
import { useOcean } from '../../providers'
import { feedback } from '../../utils'
import { DID, Logger, ServiceType } from '@oceanprotocol/lib'
import { checkAndBuyDT } from '../../utils/dtUtils'
import { useState } from 'react';
import { useOcean } from '../../providers';
import { feedback } from '../../utils';
import { DID, Logger, ServiceType } from '@oceanprotocol/lib';
import { checkAndBuyDT } from '../../utils/dtUtils';
interface UseConsume {
consume: (
did: DID | string,
dataTokenAddress: string,
serviceType: ServiceType
) => Promise<void>
consumeStep?: number
consumeStepText?: string
consumeError?: string
isLoading: boolean
) => Promise<void>;
consumeStep?: number;
consumeStepText?: string;
consumeError?: string;
isLoading: boolean;
}
// TODO: do something with this object,
@ -22,18 +22,18 @@ interface UseConsume {
export const consumeFeedback: { [key in number]: string } = {
...feedback,
3: '3/3 Access granted. Consuming file...'
}
};
function useConsume(): UseConsume {
const { ocean, account, accountId, config } = useOcean()
const [isLoading, setIsLoading] = useState(false)
const [consumeStep, setConsumeStep] = useState<number | undefined>()
const [consumeStepText, setConsumeStepText] = useState<string | undefined>()
const [consumeError, setConsumeError] = useState<string | undefined>()
const { ocean, account, accountId, config } = useOcean();
const [isLoading, setIsLoading] = useState(false);
const [consumeStep, setConsumeStep] = useState<number | undefined>();
const [consumeStepText, setConsumeStepText] = useState<string | undefined>();
const [consumeError, setConsumeError] = useState<string | undefined>();
function setStep(index: number) {
setConsumeStep(index)
setConsumeStepText(consumeFeedback[index])
setConsumeStep(index);
setConsumeStepText(consumeFeedback[index]);
}
async function consume(
@ -41,50 +41,50 @@ function useConsume(): UseConsume {
dataTokenAddress: string,
serviceType: ServiceType = 'access'
): Promise<void> {
if (!ocean || !account || !accountId) return
setIsLoading(true)
setConsumeError(undefined)
if (!ocean || !account || !accountId) return;
setIsLoading(true);
setConsumeError(undefined);
try {
setStep(0)
await checkAndBuyDT(ocean, dataTokenAddress, account, config)
setStep(0);
await checkAndBuyDT(ocean, dataTokenAddress, account, config);
setStep(1)
const order = await ocean.assets.order(did, serviceType, accountId)
Logger.log('order created', order)
setStep(2)
const res = JSON.parse(order)
Logger.log('order parsed', res)
Logger.log('ocean.datatokens before transfer', ocean.datatokens)
setStep(1);
const order = await ocean.assets.order(did, serviceType, accountId);
Logger.log('order created', order);
setStep(2);
const res = JSON.parse(order);
Logger.log('order parsed', res);
Logger.log('ocean.datatokens before transfer', ocean.datatokens);
const tokenTransfer = await ocean.datatokens.transferWei(
res.dataToken,
res.to,
String(res.numTokens),
res.from
)
Logger.log('token transfered', tokenTransfer)
setStep(3)
);
Logger.log('token transfered', tokenTransfer);
setStep(3);
await ocean.assets.download(
did,
(tokenTransfer as any).transactionHash,
dataTokenAddress,
account,
''
)
);
setStep(4)
setStep(4);
} catch (error) {
setConsumeError(error.message)
Logger.error(error)
setConsumeError(error.message);
Logger.error(error);
} finally {
setConsumeStep(undefined)
setConsumeStepText(undefined)
setIsLoading(false)
setConsumeStep(undefined);
setConsumeStepText(undefined);
setIsLoading(false);
}
}
return { consume, consumeStep, consumeStepText, consumeError, isLoading }
return { consume, consumeStep, consumeStepText, consumeError, isLoading };
}
export { useConsume, UseConsume }
export default useConsume
export { useConsume, UseConsume };
export default useConsume;

View File

@ -1,5 +1,5 @@
export default interface BestPrice {
type: 'pool' | 'exchange'
address: string
value: string
type: 'pool' | 'exchange';
address: string;
value: string;
}

View File

@ -1,4 +1,4 @@
export default interface Pool {
address: string
price: string
address: string;
price: string;
}

View File

@ -1,3 +1,3 @@
export * from './useMetadata'
export * from './Pool'
export * from './BestPrice'
export * from './useMetadata';
export * from './Pool';
export * from './BestPrice';

View File

@ -1,89 +1,89 @@
import { useState, useEffect } from 'react'
import { DID, DDO, Metadata, Logger } from '@oceanprotocol/lib'
import { useOcean } from '../../providers'
import ProviderStatus from '../../providers/OceanProvider/ProviderStatus'
import { getBestDataTokenPrice } from '../../utils/dtUtils'
import { isDDO } from '../../utils'
import BestPrice from './BestPrice'
import { useState, useEffect } from 'react';
import { DID, DDO, Metadata, Logger } from '@oceanprotocol/lib';
import { useOcean } from '../../providers';
import ProviderStatus from '../../providers/OceanProvider/ProviderStatus';
import { getBestDataTokenPrice } from '../../utils/dtUtils';
import { isDDO } from '../../utils';
import BestPrice from './BestPrice';
interface UseMetadata {
ddo: DDO
did: DID | string
metadata: Metadata
title: string
price: BestPrice
isLoaded: boolean
getPrice: (dataTokenAddress?: string) => Promise<BestPrice>
ddo: DDO;
did: DID | string;
metadata: Metadata;
title: string;
price: BestPrice;
isLoaded: boolean;
getPrice: (dataTokenAddress?: string) => Promise<BestPrice>;
}
function useMetadata(asset?: DID | string | DDO): UseMetadata {
const { ocean, status, accountId } = useOcean()
const [internalDdo, setDDO] = useState<DDO | undefined>()
const [internalDid, setDID] = useState<DID | string | undefined>()
const [metadata, setMetadata] = useState<Metadata | undefined>()
const [title, setTitle] = useState<string | undefined>()
const [isLoaded, setIsLoaded] = useState(false)
const [price, setPrice] = useState<BestPrice | undefined>()
const { ocean, status, accountId } = useOcean();
const [internalDdo, setDDO] = useState<DDO | undefined>();
const [internalDid, setDID] = useState<DID | string | undefined>();
const [metadata, setMetadata] = useState<Metadata | undefined>();
const [title, setTitle] = useState<string | undefined>();
const [isLoaded, setIsLoaded] = useState(false);
const [price, setPrice] = useState<BestPrice | undefined>();
async function getDDO(did: DID | string): Promise<DDO> {
if (status === ProviderStatus.CONNECTED) {
const ddo = await ocean.metadatastore.retrieveDDO(did)
return ddo
const ddo = await ocean.metadatastore.retrieveDDO(did);
return ddo;
}
}
async function getPrice(dataTokenAddress?: string): Promise<BestPrice> {
if (!dataTokenAddress) dataTokenAddress = internalDdo.dataToken
return await getBestDataTokenPrice(ocean, dataTokenAddress, accountId)
if (!dataTokenAddress) dataTokenAddress = internalDdo.dataToken;
return await getBestDataTokenPrice(ocean, dataTokenAddress, accountId);
}
async function getMetadata(): Promise<Metadata> {
if (!internalDdo) return
const metadata = internalDdo.findServiceByType('metadata')
return metadata.attributes
if (!internalDdo) return;
const metadata = internalDdo.findServiceByType('metadata');
return metadata.attributes;
}
useEffect(() => {
async function init(): Promise<void> {
if (ocean && status === ProviderStatus.CONNECTED) {
if (!asset) return
if (!asset) return;
if (isDDO(asset)) {
setDDO(asset)
setDID(asset.id)
setDDO(asset);
setDID(asset.id);
} else {
const ddo = await getDDO(asset)
Logger.debug('DDO', ddo)
setDDO(ddo)
setDID(asset)
const ddo = await getDDO(asset);
Logger.debug('DDO', ddo);
setDDO(ddo);
setDID(asset);
}
}
}
init()
}, [ocean, status])
init();
}, [ocean, status]);
useEffect(() => {
if (!accountId) return
if (!accountId) return;
async function init(): Promise<void> {
if (internalDdo) {
const metadata = await getMetadata()
setMetadata(metadata)
setTitle(metadata.main.name)
const price = await getPrice()
const metadata = await getMetadata();
setMetadata(metadata);
setTitle(metadata.main.name);
const price = await getPrice();
setPrice(price)
setIsLoaded(true)
setPrice(price);
setIsLoaded(true);
}
}
init()
init();
const interval = setInterval(async () => {
const price = await getPrice()
setPrice(price)
}, 10000)
return () => clearInterval(interval)
}, [accountId, internalDdo])
const price = await getPrice();
setPrice(price);
}, 10000);
return () => clearInterval(interval);
}, [accountId, internalDdo]);
return {
ddo: internalDdo,
@ -93,8 +93,8 @@ function useMetadata(asset?: DID | string | DDO): UseMetadata {
price,
isLoaded,
getPrice
}
};
}
export { useMetadata, UseMetadata }
export default useMetadata
export { useMetadata, UseMetadata };
export default useMetadata;

View File

@ -1,5 +1,5 @@
export interface DataTokenOptions {
cap?: string
name?: string
symbol?: string
cap?: string;
name?: string;
symbol?: string;
}

View File

@ -1,7 +1,7 @@
export interface PriceOptions {
price?: number
tokensToMint: number
type: 'fixed' | 'dynamic' | string
weightOnDataToken: string
liquidityProviderFee: string
price?: number;
tokensToMint: number;
type: 'fixed' | 'dynamic' | string;
weightOnDataToken: string;
liquidityProviderFee: string;
}

View File

@ -1,3 +1,3 @@
export * from './usePublish'
export * from './PriceOptions'
export * from './DataTokenOptions'
export * from './usePublish';
export * from './PriceOptions';
export * from './DataTokenOptions';

View File

@ -1,15 +1,15 @@
import { useState } from 'react'
import { DDO, Metadata, Logger } from '@oceanprotocol/lib'
import { useOcean } from '../../providers'
import ProviderStatus from '../../providers/OceanProvider/ProviderStatus'
import { useState } from 'react';
import { DDO, Metadata, Logger } from '@oceanprotocol/lib';
import { useOcean } from '../../providers';
import ProviderStatus from '../../providers/OceanProvider/ProviderStatus';
import {
Service,
ServiceComputePrivacy,
ServiceType
} from '@oceanprotocol/lib/dist/node/ddo/interfaces/Service'
import { PriceOptions } from './PriceOptions'
import { publishFeedback } from '../../utils'
import { DataTokenOptions } from '.'
} from '@oceanprotocol/lib/dist/node/ddo/interfaces/Service';
import { PriceOptions } from './PriceOptions';
import { publishFeedback } from '../../utils';
import { DataTokenOptions } from '.';
interface UsePublish {
publish: (
@ -17,24 +17,24 @@ interface UsePublish {
priceOptions: PriceOptions,
serviceConfigs: ServiceType,
dataTokenOptions?: DataTokenOptions
) => Promise<DDO>
mint: (tokenAddress: string, tokensToMint: string) => void
publishStep?: number
publishStepText?: string
publishError?: string
isLoading: boolean
) => Promise<DDO>;
mint: (tokenAddress: string, tokensToMint: string) => void;
publishStep?: number;
publishStepText?: string;
publishError?: string;
isLoading: boolean;
}
function usePublish(): UsePublish {
const { ocean, status, account, accountId, config } = useOcean()
const [isLoading, setIsLoading] = useState(false)
const [publishStep, setPublishStep] = useState<number | undefined>()
const [publishStepText, setPublishStepText] = useState<string | undefined>()
const [publishError, setPublishError] = useState<string | undefined>()
const { ocean, status, account, accountId, config } = useOcean();
const [isLoading, setIsLoading] = useState(false);
const [publishStep, setPublishStep] = useState<number | undefined>();
const [publishStepText, setPublishStepText] = useState<string | undefined>();
const [publishError, setPublishError] = useState<string | undefined>();
function setStep(index: number) {
setPublishStep(index)
setPublishStepText(publishFeedback[index])
setPublishStep(index);
setPublishStepText(publishFeedback[index]);
}
/**
@ -51,18 +51,18 @@ function usePublish(): UsePublish {
serviceType: ServiceType,
dataTokenOptions?: DataTokenOptions
): Promise<DDO> {
if (status !== ProviderStatus.CONNECTED || !ocean || !account) return
setIsLoading(true)
setPublishError(undefined)
if (status !== ProviderStatus.CONNECTED || !ocean || !account) return;
setIsLoading(true);
setPublishError(undefined);
try {
const tokensToMint = priceOptions.tokensToMint.toString()
const tokensToMint = priceOptions.tokensToMint.toString();
const publishedDate =
new Date(Date.now()).toISOString().split('.')[0] + 'Z'
const timeout = 0
const services: Service[] = []
new Date(Date.now()).toISOString().split('.')[0] + 'Z';
const timeout = 0;
const services: Service[] = [];
const price = ocean.datatokens.toWei('1')
const price = ocean.datatokens.toWei('1');
switch (serviceType) {
case 'access': {
const accessService = await ocean.assets.createAccessServiceAttributes(
@ -70,16 +70,16 @@ function usePublish(): UsePublish {
price,
publishedDate,
timeout
)
Logger.log('access service created', accessService)
services.push(accessService)
break
);
Logger.log('access service created', accessService);
services.push(accessService);
break;
}
case 'compute': {
const cluster = ocean.compute.createClusterAttributes(
'Kubernetes',
'http://10.0.0.17/xxx'
)
);
const servers = [
ocean.compute.createServerAttributes(
'1',
@ -91,39 +91,39 @@ function usePublish(): UsePublish {
'160gb',
timeout
)
]
];
const containers = [
ocean.compute.createContainerAttributes(
'tensorflow/tensorflow',
'latest',
'sha256:cb57ecfa6ebbefd8ffc7f75c0f00e57a7fa739578a429b6f72a0df19315deadc'
)
]
];
const provider = ocean.compute.createProviderAttributes(
'Azure',
'Compute service with 16gb ram for each node.',
cluster,
containers,
servers
)
);
const origComputePrivacy = {
allowRawAlgorithm: true,
allowNetworkAccess: false,
trustedAlgorithms: []
}
};
const computeService = ocean.compute.createComputeService(
account,
price,
publishedDate,
provider,
origComputePrivacy as ServiceComputePrivacy
)
services.push(computeService)
break
);
services.push(computeService);
break;
}
}
Logger.log('services created', services)
Logger.log('services created', services);
const ddo = await ocean.assets
.create(
@ -134,21 +134,21 @@ function usePublish(): UsePublish {
dataTokenOptions?.name,
dataTokenOptions?.symbol
)
.next(setStep)
Logger.log('ddo created', ddo)
setStep(7)
await mint(ddo.dataToken, tokensToMint)
Logger.log(`minted ${tokensToMint} tokens`)
.next(setStep);
Logger.log('ddo created', ddo);
setStep(7);
await mint(ddo.dataToken, tokensToMint);
Logger.log(`minted ${tokensToMint} tokens`);
await createPricing(priceOptions, ddo.dataToken, tokensToMint)
setStep(8)
return ddo
await createPricing(priceOptions, ddo.dataToken, tokensToMint);
setStep(8);
return ddo;
} catch (error) {
setPublishError(error.message)
Logger.error(error)
setStep(undefined)
setPublishError(error.message);
Logger.error(error);
setStep(undefined);
} finally {
setIsLoading(false)
setIsLoading(false);
}
}
@ -159,35 +159,35 @@ function usePublish(): UsePublish {
) {
switch (priceOptions.type) {
case 'dynamic': {
const pool = await ocean.pool.createDTPool(
await ocean.pool.createDTPool(
accountId,
dataTokenAddress,
priceOptions.tokensToMint.toString(),
priceOptions.weightOnDataToken,
priceOptions.liquidityProviderFee
)
break
);
break;
}
case 'fixed': {
const fixedPriceExchange = await ocean.fixedRateExchange.create(
await ocean.fixedRateExchange.create(
dataTokenAddress,
priceOptions.price.toString(),
accountId
)
);
await ocean.datatokens.approve(
dataTokenAddress,
config.fixedRateExchangeAddress,
mintedTokens,
accountId
)
break
);
break;
}
}
}
async function mint(tokenAddress: string, tokensToMint: string) {
Logger.log('mint function', tokenAddress, accountId)
await ocean.datatokens.mint(tokenAddress, accountId, tokensToMint)
Logger.log('mint function', tokenAddress, accountId);
await ocean.datatokens.mint(tokenAddress, accountId, tokensToMint);
}
return {
@ -197,8 +197,8 @@ function usePublish(): UsePublish {
publishStepText,
isLoading,
publishError
}
};
}
export { usePublish, UsePublish }
export default usePublish
export { usePublish, UsePublish };
export default usePublish;

View File

@ -1,5 +1,3 @@
export * from './providers'
export * from './hooks'
// export * from './components'
export * from './utils'
export * from './providers';
export * from './hooks';
export * from './utils';

View File

@ -1,143 +1,145 @@
/* eslint no-use-before-define: 1 */
// ! TODO: the above is the hack there is a problem with the way this project is configured
import React, {
useContext,
useState,
useEffect,
createContext,
ReactElement
} from 'react'
import Web3 from 'web3'
import ProviderStatus from './ProviderStatus'
import { Ocean, Logger, Account, Config } from '@oceanprotocol/lib'
import Web3Modal, { ICoreOptions } from 'web3modal'
import { getDefaultProviders } from './getDefaultProviders'
import { getAccountId, getBalance } from '../../utils'
} from 'react';
import Web3 from 'web3';
import ProviderStatus from './ProviderStatus';
import { Ocean, Logger, Account, Config } from '@oceanprotocol/lib';
import Web3Modal, { ICoreOptions } from 'web3modal';
import { getDefaultProviders } from './getDefaultProviders';
import { getAccountId, getBalance } from '../../utils';
interface Balance {
eth: string | undefined
ocean: string | undefined
eth: string | undefined;
ocean: string | undefined;
}
interface OceanProviderValue {
web3: Web3 | undefined
web3Provider: any
web3Modal: Web3Modal
ocean: Ocean
config: Config
account: Account
accountId: string
balance: Balance
chainId: number | undefined
status: ProviderStatus
connect: (config?: Config) => Promise<void>
logout: () => Promise<void>
refreshBalance: () => Promise<void>
web3: Web3 | undefined;
web3Provider: any;
web3Modal: Web3Modal;
ocean: Ocean;
config: Config;
account: Account;
accountId: string;
balance: Balance;
chainId: number | undefined;
status: ProviderStatus;
connect: (config?: Config) => Promise<void>;
logout: () => Promise<void>;
refreshBalance: () => Promise<void>;
}
const OceanContext = createContext(null)
const OceanContext = createContext(null);
function OceanProvider({
initialConfig,
web3ModalOpts,
children
}: {
initialConfig: Config
web3ModalOpts?: Partial<ICoreOptions>
children: any
initialConfig: Config;
web3ModalOpts?: Partial<ICoreOptions>;
children: any;
}): ReactElement {
const [web3, setWeb3] = useState<Web3 | undefined>()
const [web3Provider, setWeb3Provider] = useState<any | undefined>()
const [ocean, setOcean] = useState<Ocean | undefined>()
const [web3Modal, setWeb3Modal] = useState<Web3Modal>(null)
const [chainId, setChainId] = useState<number | undefined>()
const [account, setAccount] = useState<Account | undefined>()
const [accountId, setAccountId] = useState<string | undefined>()
const [config, setConfig] = useState<Config>(initialConfig)
const [web3, setWeb3] = useState<Web3 | undefined>();
const [web3Provider, setWeb3Provider] = useState<any | undefined>();
const [ocean, setOcean] = useState<Ocean | undefined>();
const [web3Modal, setWeb3Modal] = useState<Web3Modal>(null);
const [chainId, setChainId] = useState<number | undefined>();
const [account, setAccount] = useState<Account | undefined>();
const [accountId, setAccountId] = useState<string | undefined>();
const [config, setConfig] = useState<Config>(initialConfig);
const [balance, setBalance] = useState<Balance | undefined>({
eth: undefined,
ocean: undefined
})
});
const [status, setStatus] = useState<ProviderStatus>(
ProviderStatus.NOT_AVAILABLE
)
);
async function init() {
Logger.log('Ocean Provider init')
Logger.log('Ocean Provider init');
window &&
window.ethereum &&
(window.ethereum.autoRefreshOnNetworkChange = false)
(window.ethereum.autoRefreshOnNetworkChange = false);
Logger.log('Web3Modal init.')
Logger.log('Web3Modal init.');
if (web3ModalOpts === undefined) {
web3ModalOpts = await getDefaultProviders()
web3ModalOpts = await getDefaultProviders();
}
const web3ModalInstance = new Web3Modal(web3ModalOpts)
setWeb3Modal(web3ModalInstance)
Logger.log('Web3Modal instance created.', web3ModalInstance)
const web3ModalInstance = new Web3Modal(web3ModalOpts);
setWeb3Modal(web3ModalInstance);
Logger.log('Web3Modal instance created.', web3ModalInstance);
}
// On mount setup Web3Modal instance
useEffect(() => {
init()
}, [])
init();
}, []);
// Connect automatically to cached provider if present
useEffect(() => {
if (!web3Modal) return
web3Modal.cachedProvider && connect()
}, [web3Modal])
if (!web3Modal) return;
web3Modal.cachedProvider && connect();
}, [web3Modal]);
async function connect(newConfig?: Config) {
try {
Logger.log('Connecting ...', newConfig)
Logger.log('Connecting ...', newConfig);
newConfig && setConfig(newConfig)
newConfig && setConfig(newConfig);
const provider = await web3Modal.connect()
setWeb3Provider(provider)
const provider = await web3Modal.connect();
setWeb3Provider(provider);
const web3 = new Web3(provider)
setWeb3(web3)
Logger.log('Web3 created.', web3)
const web3 = new Web3(provider);
setWeb3(web3);
Logger.log('Web3 created.', web3);
const chainId = web3 && (await web3.eth.getChainId())
setChainId(chainId)
Logger.log('chain id ', chainId)
const chainId = web3 && (await web3.eth.getChainId());
setChainId(chainId);
Logger.log('chain id ', chainId);
config.web3Provider = web3
const ocean = await Ocean.getInstance(config)
setOcean(ocean)
Logger.log('Ocean instance created.', ocean)
config.web3Provider = web3;
const ocean = await Ocean.getInstance(config);
setOcean(ocean);
Logger.log('Ocean instance created.', ocean);
setStatus(ProviderStatus.CONNECTED)
setStatus(ProviderStatus.CONNECTED);
const account = (await ocean.accounts.list())[0]
setAccount(account)
Logger.log('Account ', account)
const account = (await ocean.accounts.list())[0];
setAccount(account);
Logger.log('Account ', account);
const accountId = await getAccountId(web3)
setAccountId(accountId)
Logger.log('account id', accountId)
const accountId = await getAccountId(web3);
setAccountId(accountId);
Logger.log('account id', accountId);
const balance = await getBalance(account)
setBalance(balance)
Logger.log('balance', JSON.stringify(balance))
const balance = await getBalance(account);
setBalance(balance);
Logger.log('balance', JSON.stringify(balance));
} catch (error) {
Logger.error(error)
Logger.error(error);
}
}
async function refreshBalance() {
const balance = await getBalance(account)
setBalance(balance)
const balance = 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[]) => {
Logger.debug("Handling 'accountsChanged' event with payload", accounts)
connect()
}
Logger.debug("Handling 'accountsChanged' event with payload", accounts);
connect();
};
// TODO: #68 Refetch balance periodically, or figure out some event to subscribe to
@ -145,15 +147,15 @@ function OceanProvider({
// web3Modal && web3Modal.on('connect', handleConnect)
if (web3Provider !== undefined && web3Provider !== null) {
web3Provider.on('accountsChanged', handleAccountsChanged)
web3Provider.on('accountsChanged', handleAccountsChanged);
// web3Provider.on('chainChanged', handleNetworkChanged)
return () => {
web3Provider.removeListener('accountsChanged', handleAccountsChanged)
web3Provider.removeListener('accountsChanged', handleAccountsChanged);
// web3Provider.removeListener('chainChanged', handleNetworkChanged)
}
};
}
}, [web3Modal, web3Provider])
}, [web3Modal, web3Provider]);
return (
<OceanContext.Provider
@ -177,11 +179,11 @@ function OceanProvider({
>
{children}
</OceanContext.Provider>
)
);
}
// Helper hook to access the provider values
const useOcean = (): OceanProviderValue => useContext(OceanContext)
const useOcean = (): OceanProviderValue => useContext(OceanContext);
export { OceanProvider, useOcean, OceanProviderValue, Balance }
export default OceanProvider
export { OceanProvider, useOcean, OceanProviderValue, Balance };
export default OceanProvider;

View File

@ -4,4 +4,4 @@ enum ProviderStatus {
CONNECTED = 1
}
export default ProviderStatus
export default ProviderStatus;

View File

@ -1,5 +1,5 @@
import { ICoreOptions } from 'web3modal/dist/helpers/types'
import { ICoreOptions } from 'web3modal/dist/helpers/types';
export async function getDefaultProviders(): Promise<Partial<ICoreOptions>> {
return { cacheProvider: true }
return { cacheProvider: true };
}

View File

@ -1,2 +1,2 @@
export * from './OceanProvider'
export * from './ProviderStatus'
export * from './OceanProvider';
export * from './ProviderStatus';

View File

@ -1 +1 @@
export * from './OceanProvider'
export * from './OceanProvider';

View File

@ -1,29 +1,30 @@
import { Logger, Ocean, Account, Config } from '@oceanprotocol/lib'
import { Decimal } from 'decimal.js'
import Pool from '../hooks/useMetadata/Pool'
import BestPrice from '../hooks/useMetadata/BestPrice'
import Web3 from 'web3'
import { Logger, Ocean, Account, Config } from '@oceanprotocol/lib';
import { Decimal } from 'decimal.js';
import Pool from '../hooks/useMetadata/Pool';
import BestPrice from '../hooks/useMetadata/BestPrice';
import Web3 from 'web3';
import { TransactionReceipt } from 'web3-core';
export async function getCheapestPool(
ocean: Ocean,
accountId: string,
dataTokenAddress: string
): Promise<Pool> {
if (!ocean || !accountId || !dataTokenAddress) return
if (!ocean || !accountId || !dataTokenAddress) return;
const tokenPools = await ocean.pool.searchPoolforDT(
accountId,
dataTokenAddress
)
);
if (tokenPools === undefined || tokenPools.length === 0) {
return {
address: '',
price: ''
}
};
}
let cheapestPoolAddress = tokenPools[0]
let cheapestPoolPrice = new Decimal(999999999999)
let cheapestPoolAddress = tokenPools[0];
let cheapestPoolPrice = new Decimal(999999999999);
if (tokenPools) {
for (let i = 0; i < tokenPools.length; i++) {
@ -31,12 +32,12 @@ export async function getCheapestPool(
accountId,
tokenPools[i],
'1'
)
const decimalPoolPrice = new Decimal(poolPrice)
);
const decimalPoolPrice = new Decimal(poolPrice);
if (decimalPoolPrice < cheapestPoolPrice) {
cheapestPoolPrice = decimalPoolPrice
cheapestPoolAddress = tokenPools[i]
cheapestPoolPrice = decimalPoolPrice;
cheapestPoolAddress = tokenPools[i];
}
}
}
@ -44,7 +45,7 @@ export async function getCheapestPool(
return {
address: cheapestPoolAddress,
price: cheapestPoolPrice.toString()
}
};
}
export async function getBestDataTokenPrice(
@ -52,117 +53,121 @@ export async function getBestDataTokenPrice(
dataTokenAddress: string,
accountId: string
): Promise<BestPrice | undefined> {
const cheapestPool = await getCheapestPool(ocean, accountId, dataTokenAddress)
const cheapestExchange = await getCheapestExchange(ocean, dataTokenAddress)
Decimal.set({ precision: 5 })
const cheapestPool = await getCheapestPool(
ocean,
accountId,
dataTokenAddress
);
const cheapestExchange = await getCheapestExchange(ocean, dataTokenAddress);
Decimal.set({ precision: 5 });
const cheapestPoolPrice = new Decimal(
cheapestPool.price !== '' ? cheapestPool.price : 999999999999
)
);
const cheapestExchangePrice = new Decimal(
cheapestExchange.price !== '' ? cheapestExchange.price : 999999999999
)
);
if (cheapestPoolPrice < cheapestExchangePrice) {
return {
type: 'pool',
address: cheapestPool.address,
value: cheapestPool.price
} as BestPrice
} as BestPrice;
} else {
return {
type: 'exchange',
address: cheapestExchange.address,
value: cheapestExchange.price
} as BestPrice
} as BestPrice;
}
}
export async function getCheapestExchange(
ocean: Ocean,
dataTokenAddress: string
) {
if (!ocean || !dataTokenAddress) return
): Promise<BestPrice | undefined> {
if (!ocean || !dataTokenAddress) return;
const tokenExchanges = await ocean.fixedRateExchange.searchforDT(
dataTokenAddress,
'1'
)
);
if (tokenExchanges === undefined || tokenExchanges.length === 0) {
return {
address: '',
price: ''
}
};
}
let cheapestExchangeAddress = tokenExchanges[0].exchangeID
let cheapestExchangePrice = new Decimal(tokenExchanges[0].fixedRate)
let cheapestExchangeAddress = tokenExchanges[0].exchangeID;
let cheapestExchangePrice = new Decimal(tokenExchanges[0].fixedRate);
for (let i = 0; i < tokenExchanges.length; i++) {
const decimalExchangePrice = new Decimal(
Web3.utils.fromWei(tokenExchanges[i].fixedRate)
)
);
if (decimalExchangePrice < cheapestExchangePrice) {
cheapestExchangePrice = decimalExchangePrice
cheapestExchangeAddress = tokenExchanges[i].exchangeID
cheapestExchangePrice = decimalExchangePrice;
cheapestExchangeAddress = tokenExchanges[i].exchangeID;
}
}
return {
address: cheapestExchangeAddress,
price: cheapestExchangePrice.toString()
}
};
}
export async function checkAndBuyDT(
export const checkAndBuyDT = async (
ocean: Ocean,
dataTokenAddress: string,
account: Account,
config: Config
) {
): Promise<TransactionReceipt> => {
const userOwnedTokens = await ocean.accounts.getTokenBalance(
dataTokenAddress,
account
)
Logger.log(`User has ${userOwnedTokens} tokens`)
);
Logger.log(`User has ${userOwnedTokens} tokens`);
if (userOwnedTokens === '0') {
const bestPrice = await getBestDataTokenPrice(
ocean,
dataTokenAddress,
account.getId()
)
);
switch (bestPrice.type) {
case 'pool': {
const price = new Decimal(bestPrice.value).times(1.05).toString()
const maxPrice = new Decimal(bestPrice.value).times(2).toString()
Logger.log('Buying token from pool', bestPrice, account.getId(), price)
const price = new Decimal(bestPrice.value).times(1.05).toString();
const maxPrice = new Decimal(bestPrice.value).times(2).toString();
Logger.log('Buying token from pool', bestPrice, account.getId(), price);
const buyResponse = await ocean.pool.buyDT(
account.getId(),
bestPrice.address,
'1',
price,
maxPrice
)
Logger.log('DT buy response', buyResponse)
return buyResponse
);
Logger.log('DT buy response', buyResponse);
return buyResponse;
}
case 'exchange': {
Logger.log('Buying token from exchange', bestPrice, account.getId())
Logger.log('Buying token from exchange', bestPrice, account.getId());
await ocean.datatokens.approve(
config.oceanTokenAddress,
config.fixedRateExchangeAddress,
bestPrice.value,
account.getId()
)
);
const exchange = await ocean.fixedRateExchange.buyDT(
bestPrice.address,
'1',
account.getId()
)
Logger.log('DT exchange buy response', exchange)
return exchange
);
Logger.log('DT exchange buy response', exchange);
return exchange;
}
}
}
}
};

View File

@ -1,24 +1,24 @@
import { DDO, DID } from '@oceanprotocol/lib'
import { DDO, DID } from '@oceanprotocol/lib';
export function readFileContent(file: File): Promise<string> {
return new Promise((resolve, reject) => {
const reader = new FileReader()
const reader = new FileReader();
reader.onerror = () => {
reader.abort()
reject(new DOMException('Problem parsing input file.'))
}
reader.abort();
reject(new DOMException('Problem parsing input file.'));
};
reader.onload = () => {
resolve(reader.result as string)
}
reader.readAsText(file)
})
resolve(reader.result as string);
};
reader.readAsText(file);
});
}
export function isDDO(toBeDetermined): toBeDetermined is DDO {
if ((toBeDetermined as DDO).id) {
return true
return true;
}
return false
return false;
}
export const feedback: { [key in number]: string } = {
@ -26,7 +26,7 @@ export const feedback: { [key in number]: string } = {
0: '1/3 Looking for data token. Buying if none found...',
1: '2/3 Transfering data token.',
2: '3/3 Payment confirmed. Requesting access...'
}
};
export const publishFeedback: { [key in number]: string } = {
0: '1/6 Creating datatoken ...',
@ -35,6 +35,6 @@ export const publishFeedback: { [key in number]: string } = {
6: '4/6 Storing ddo ...',
7: '5/6 Minting tokens ...',
8: '6/6 Asset published succesfully'
}
};
export * from './web3'
export * from './web3';

View File

@ -1,15 +1,15 @@
import Web3 from 'web3'
import { Account } from '@oceanprotocol/lib'
import { Balance } from '../providers'
import Web3 from 'web3';
import { Account } from '@oceanprotocol/lib';
import { Balance } from '../providers';
export async function getAccountId(web3: Web3): Promise<string> {
const accounts = await web3.eth.getAccounts()
return accounts[0]
const accounts = await web3.eth.getAccounts();
return accounts[0];
}
export async function getBalance(account: Account): Promise<Balance> {
const eth = await account.getEtherBalance()
const ocean = await account.getOceanBalance()
const eth = await account.getEtherBalance();
const ocean = await account.getOceanBalance();
return { eth, ocean }
return { eth, ocean };
}

View File

@ -11,7 +11,11 @@
"sourceMap": true,
"declaration": true,
"strictNullChecks": false,
"importHelpers": true
"importHelpers": true,
"baseUrl": "./src",
"paths": {
"@oceanprotocol/react": ["index.ts"]
}
},
"include": ["./src/@types", "./src/index.ts"],
"exclude": ["node_modules", "dist", "example"]