mirror of
https://github.com/oceanprotocol/ocean.js.git
synced 2024-11-26 20:39:05 +01:00
Merge 10d07f89dc26a39071a1945de601e3901f4de0e1 into 87edac976fc49d7d2685f66b0c58f4b3bb6fc2df
This commit is contained in:
commit
2ade8e7423
@ -16,7 +16,8 @@
|
||||
"rules": {
|
||||
"no-empty": ["error", { "allowEmptyCatch": true }],
|
||||
"prefer-destructuring": ["warn", { "object": true, "array": false }],
|
||||
"no-dupe-class-members": ["warn"],
|
||||
"no-dupe-class-members": "off",
|
||||
"no-redeclare": "off",
|
||||
"no-useless-constructor": ["warn"],
|
||||
"no-unused-vars": ["warn"],
|
||||
"constructor-super": ["warn"]
|
||||
|
582
CodeExamples.md
582
CodeExamples.md
@ -1,91 +1,91 @@
|
||||
# Ocean.js Code Examples
|
||||
/// # Ocean.js Code Examples
|
||||
|
||||
## Introduction
|
||||
/// ## Introduction
|
||||
|
||||
The following guide runs you through the process of using ocean.js to publish and then consume a dataset. The code examples below are all working and you can learn how to publish by following along.
|
||||
The process involves creating a Data NFT (which represents the base-IP on-chain) and a datatoken (which will be used to purchase the dataset). This guide provides all the code you need and no prior knowledge is required. It is helpful if you have some experience with javascript but it is not necessary.
|
||||
/// The following guide runs you through the process of using ocean.js to publish and then consume a dataset. The code examples below are all working and you can learn how to publish by following along.
|
||||
/// The process involves creating a Data NFT (which represents the base-IP on-chain) and a datatoken (which will be used to purchase the dataset). This guide provides all the code you need and no prior knowledge is required. It is helpful if you have some experience with javascript but it is not necessary.
|
||||
|
||||
Selling your data over the blockchain puts you in charge of how it is used and can be a great source of passive income. There are many AI startups that have deep expertise in machine learning but need more data to improve their models. Selling your data via the blockchain gives you a level of security that you would be unable to achieve if you were selling via a centralised marketplace.
|
||||
/// Selling your data over the blockchain puts you in charge of how it is used and can be a great source of passive income. There are many AI startups that have deep expertise in machine learning but need more data to improve their models. Selling your data via the blockchain gives you a level of security that you would be unable to achieve if you were selling via a centralised marketplace.
|
||||
|
||||
In this guide we'll be making use of the Ocean.js library. Ocean Protocol provides you with everything you need to quickly get setup and start selling data over the blockchain.
|
||||
/// In this guide we'll be making use of the Ocean.js library. Ocean Protocol provides you with everything you need to quickly get setup and start selling data over the blockchain.
|
||||
|
||||
These examples take you through a typical user journey that focuses on the experience of a publisher, and a buyer / consumer.
|
||||
/// These examples take you through a typical user journey that focuses on the experience of a publisher, and a buyer / consumer.
|
||||
|
||||
If you have any questions or issues at any point while following along to this article please reach out to us on [discord](https://discord.gg/TnXjkR5).
|
||||
/// If you have any questions or issues at any point while following along to this article please reach out to us on [discord](https://discord.gg/TnXjkR5).
|
||||
|
||||
Here are the steps we will be following throughout the article:
|
||||
/// Here are the steps we will be following throughout the article:
|
||||
|
||||
Here are the steps:
|
||||
/// Here are the steps:
|
||||
|
||||
0. [Prerequisites](#-Prerequisites)
|
||||
1. [Initialize services](#-initialize-services)
|
||||
2. [Create a new node.js project](#-create-a-new-node.js-project)
|
||||
3. [Install dependencies](#-install-dependencies)
|
||||
4. [Initialize accounts and deploy contracts](#-initialize-accounts-and-deploy-contracts)
|
||||
5. [Import dependencies and add variables and constants](#-import-dependencies-and-add-variables-and-constants)
|
||||
6. [Publish Data NFT and a Datatoken with a liquidity pool](#-Publish-data-nft-and-a-datatoken-with-a-liquidity-pool)
|
||||
7. [Publish Data NFT and a Datatoken with a fixed rate exchange](#-publish-data-nft-and-a-datatoken-with-a-fixed-rate-exchange)
|
||||
8. [Publish Data NFT and a Datatoken with a dispenser](#-publish-data-nft-and-a-datatoken-with-a-dispenser)
|
||||
/// 0. [Prerequisites](#-Prerequisites)
|
||||
/// 1. [Initialize services](#-initialize-services)
|
||||
/// 2. [Create a new node.js project](#-create-a-new-node.js-project)
|
||||
/// 3. [Install dependencies](#-install-dependencies)
|
||||
/// 4. [Initialize accounts and deploy contracts](#-initialize-accounts-and-deploy-contracts)
|
||||
/// 5. [Import dependencies and add variables and constants](#-import-dependencies-and-add-variables-and-constants)
|
||||
/// 6. [Publish Data NFT and a Datatoken with a liquidity pool](#-Publish-data-nft-and-a-datatoken-with-a-liquidity-pool)
|
||||
/// 7. [Publish Data NFT and a Datatoken with a fixed rate exchange](#-publish-data-nft-and-a-datatoken-with-a-fixed-rate-exchange)
|
||||
/// 8. [Publish Data NFT and a Datatoken with a dispenser](#-publish-data-nft-and-a-datatoken-with-a-dispenser)
|
||||
|
||||
## 0. Prerequisites
|
||||
Before we start it is important that you have all of the necessary prerequisites installed on your computer.
|
||||
- **A Unix based operating system (Linux or Mac)**. If you are a Windows user you can try to run linux inside a virtual machine but this is outside of the scope of this article.
|
||||
- **Git**. Instructions for installing Git can be found here: https://git-scm.com/book/en/v2/Getting-Started-Installing-Git
|
||||
- **Node.js** can be downloaded from here: https://nodejs.org/en/download/
|
||||
- **Docker** can be installed from here: https://docs.docker.com/get-docker/. Please note that Docker must run as a non-root user, you can set this up by following these instructions: https://docs.docker.com/engine/install/linux-postinstall/
|
||||
/// ## 0. Prerequisites
|
||||
/// Before we start it is important that you have all of the necessary prerequisites installed on your computer.
|
||||
/// - **A Unix based operating system (Linux or Mac)**. If you are a Windows user you can try to run linux inside a virtual machine but this is outside of the scope of this article.
|
||||
/// - **Git**. Instructions for installing Git can be found here: https://git-scm.com/book/en/v2/Getting-Started-Installing-Git
|
||||
/// - **Node.js** can be downloaded from here: https://nodejs.org/en/download/
|
||||
/// - **Docker** can be installed from here: https://docs.docker.com/get-docker/. Please note that Docker must run as a non-root user, you can set this up by following these instructions: https://docs.docker.com/engine/install/linux-postinstall/
|
||||
|
||||
## 1. Initialize services
|
||||
/// ## 1. Initialize services
|
||||
|
||||
Ocean.js uses off-chain services for metadata (Aquarius) and consuming datasets (Provider).
|
||||
/// Ocean.js uses off-chain services for metadata (Aquarius) and consuming datasets (Provider).
|
||||
|
||||
We start by initializing the services. To do this, we clone the Barge repository and run it. This will run the current default versions of [Aquarius](https://github.com/oceanprotocol/aquarius), [Provider](https://github.com/oceanprotocol/provider), and [Ganache](https://github.com/trufflesuite/ganache) with [our contracts](https://github.com/oceanprotocol/contracts) deployed to it.
|
||||
/// We start by initializing the services. To do this, we clone the Barge repository and run it. This will run the current default versions of [Aquarius](https://github.com/oceanprotocol/aquarius), [Provider](https://github.com/oceanprotocol/provider), and [Ganache](https://github.com/trufflesuite/ganache) with [our contracts](https://github.com/oceanprotocol/contracts) deployed to it.
|
||||
|
||||
```bash
|
||||
git clone https://github.com/oceanprotocol/barge.git
|
||||
cd barge/
|
||||
./start_ocean.sh --with-provider2 --no-dashboard
|
||||
```
|
||||
/// ```bash
|
||||
/// git clone https://github.com/oceanprotocol/barge.git
|
||||
/// cd barge/
|
||||
/// ./start_ocean.sh --with-provider2 --no-dashboard
|
||||
/// ```
|
||||
|
||||
## 2. Create a new node.js project
|
||||
/// ## 2. Create a new node.js project
|
||||
|
||||
Start by creating a new Node.js project. Open a new terminal and enter the following commands:
|
||||
/// Start by creating a new Node.js project. Open a new terminal and enter the following commands:
|
||||
|
||||
```bash
|
||||
mkdir marketplace-quickstart
|
||||
cd marketplace-quickstart
|
||||
npm init
|
||||
# Answer the questions in the command line prompt
|
||||
cat > marketplace.js
|
||||
# On linux press CTRL + D to save
|
||||
```
|
||||
/// ```bash
|
||||
/// mkdir marketplace-quickstart
|
||||
/// cd marketplace-quickstart
|
||||
/// npm init
|
||||
/// # Answer the questions in the command line prompt
|
||||
/// cat > marketplace.js
|
||||
/// # On linux press CTRL + D to save
|
||||
/// ```
|
||||
|
||||
## 3. Install dependancies
|
||||
/// ## 3. Install dependancies
|
||||
|
||||
Open the package.json file in a text editor and update the dependancies to include the following:
|
||||
/// Open the package.json file in a text editor and update the dependancies to include the following:
|
||||
|
||||
```JSON
|
||||
"dependencies": {
|
||||
"@oceanprotocol/contracts": "1.0.0-alpha.28",
|
||||
"@oceanprotocol/lib": "1.0.0-next.37",
|
||||
"crypto-js": "^4.1.1",
|
||||
"web3": "^1.7.3"
|
||||
}
|
||||
```
|
||||
/// ```JSON
|
||||
/// "dependencies": {
|
||||
/// "@oceanprotocol/contracts": "1.0.0-alpha.28",
|
||||
/// "@oceanprotocol/lib": "1.0.0-next.37",
|
||||
/// "crypto-js": "^4.1.1",
|
||||
/// "web3": "^1.7.3"
|
||||
/// }
|
||||
/// ```
|
||||
|
||||
Now in your terminal run the following command:
|
||||
/// Now in your terminal run the following command:
|
||||
|
||||
```bash
|
||||
npm install
|
||||
```
|
||||
/// ```bash
|
||||
/// npm install
|
||||
/// ```
|
||||
|
||||
## 4. Import dependencies and add variables and constants
|
||||
/// ## 4. Import dependencies and add variables and constants
|
||||
|
||||
Now open the `marketplace.js` file in your text editor.
|
||||
/// Now open the `marketplace.js` file in your text editor.
|
||||
|
||||
Start by importing all of the necessary dependencies
|
||||
|
||||
```Typescript
|
||||
/// Start by importing all of the necessary dependencies
|
||||
|
||||
/// ```Typescript
|
||||
import { assert } from 'chai'
|
||||
import { SHA256 } from 'crypto-js'
|
||||
import {
|
||||
AmountsOutMaxFee,
|
||||
@ -97,7 +97,7 @@ import {
|
||||
Dispenser,
|
||||
DispenserCreationParams,
|
||||
downloadFile,
|
||||
Erc20CreateParams,
|
||||
DatatokenCreateParams,
|
||||
FixedRateExchange,
|
||||
FreCreationParams,
|
||||
getHash,
|
||||
@ -113,15 +113,15 @@ import {
|
||||
ZERO_ADDRESS
|
||||
} from '../../src'
|
||||
import { getAddresses, getTestConfig, web3 } from '../config'
|
||||
```
|
||||
/// ```
|
||||
|
||||
<!--
|
||||
describe('Marketplace flow tests
|
||||
-->
|
||||
/// <!--
|
||||
describe('Marketplace flow tests', async () => {
|
||||
/// -->
|
||||
|
||||
Now we define the variables which we will need later
|
||||
/// Now we define the variables which we will need later
|
||||
|
||||
```Typescript
|
||||
/// ```Typescript
|
||||
let config: Config
|
||||
let aquarius: Aquarius
|
||||
let providerUrl: any
|
||||
@ -139,20 +139,20 @@ Now we define the variables which we will need later
|
||||
let dispenserNftAddress: string
|
||||
let dispenserDatatokenAddress: string
|
||||
let dispenserAddress: string
|
||||
```
|
||||
/// ```
|
||||
|
||||
We also define some constants that we will use:
|
||||
```Typescript
|
||||
/// We also define some constants that we will use:
|
||||
/// ```Typescript
|
||||
const POOL_NFT_NAME = 'Datatoken 1'
|
||||
const POOL_NFT_SYMBOL = 'DT1'
|
||||
const FRE_NFT_NAME = 'Datatoken 2'
|
||||
const FRE_NFT_SYMBOL = 'DT2'
|
||||
const DISP_NFT_NAME = 'Datatoken 3'
|
||||
const DISP_NFT_SYMBOL = 'DT3'
|
||||
```
|
||||
/// ```
|
||||
|
||||
We will need a file to publish, so here we define the file that we intend to publish.
|
||||
```Typescript
|
||||
/// We will need a file to publish, so here we define the file that we intend to publish.
|
||||
/// ```Typescript
|
||||
const ASSET_URL = [
|
||||
{
|
||||
type: 'url',
|
||||
@ -160,10 +160,10 @@ We also define some constants that we will use:
|
||||
method: 'GET'
|
||||
}
|
||||
]
|
||||
```
|
||||
/// ```
|
||||
|
||||
Next, we define the metadata that will describe our data asset. This is what we call the DDO
|
||||
```Typescript
|
||||
/// Next, we define the metadata that will describe our data asset. This is what we call the DDO
|
||||
/// ```Typescript
|
||||
const DDO = {
|
||||
'@context': ['https://w3id.org/did/v1'],
|
||||
id: '',
|
||||
@ -190,57 +190,57 @@ Next, we define the metadata that will describe our data asset. This is what we
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
/// ```
|
||||
|
||||
We load the configuration:
|
||||
```Typescript
|
||||
|
||||
/// We load the configuration:
|
||||
/// ```Typescript
|
||||
before(async () => {
|
||||
config = await getTestConfig(web3)
|
||||
aquarius = new Aquarius(config.metadataCacheUri)
|
||||
providerUrl = config.providerUri
|
||||
```
|
||||
As we go along it's a good idea to console log the values so that you check they are right
|
||||
```Typescript
|
||||
/// ```
|
||||
/// As we go along it's a good idea to console log the values so that you check they are right
|
||||
/// ```Typescript
|
||||
console.log(`Aquarius URL: ${config.metadataCacheUri}`)
|
||||
console.log(`Provider URL: ${providerUrl}`)
|
||||
|
||||
```
|
||||
}) ///
|
||||
/// ```
|
||||
|
||||
## 5. Initialize accounts and deploy contracts
|
||||
### 5.1 Initialize accounts
|
||||
```Typescript
|
||||
/// ## 5. Initialize accounts and deploy contracts
|
||||
it('5.1 Initialize accounts', async () => {
|
||||
/// ```Typescript
|
||||
const accounts = await web3.eth.getAccounts()
|
||||
publisherAccount = accounts[0]
|
||||
consumerAccount = accounts[1]
|
||||
stakerAccount = accounts[2]
|
||||
```
|
||||
Again, lets console log the values so that we can check that they have been saved properly
|
||||
```Typescript
|
||||
/// ```
|
||||
/// Again, lets console log the values so that we can check that they have been saved properly
|
||||
/// ```Typescript
|
||||
console.log(`Publisher account address: ${publisherAccount}`)
|
||||
console.log(`Consumer account address: ${consumerAccount}`)
|
||||
console.log(`Staker account address: ${stakerAccount}`)
|
||||
|
||||
```
|
||||
}) ///
|
||||
/// ```
|
||||
|
||||
### 5.2 Next, lets get the address of the deployed contracts
|
||||
```Typescript
|
||||
it('5.2 Next, lets get the address of the deployed contracts', async () => {
|
||||
/// ```Typescript
|
||||
addresses = getAddresses()
|
||||
|
||||
```
|
||||
}) ///
|
||||
/// ```
|
||||
|
||||
### 5.3 We send some OCEAN to consumer and staker accounts
|
||||
```Typescript
|
||||
it('5.3 We send some OCEAN to consumer and staker accounts', async () => {
|
||||
/// ```Typescript
|
||||
transfer(web3, publisherAccount, addresses.Ocean, consumerAccount, '100')
|
||||
transfer(web3, publisherAccount, addresses.Ocean, stakerAccount, '100')
|
||||
|
||||
```
|
||||
}) ///
|
||||
/// ```
|
||||
|
||||
## 6. Publish Data NFT and a Datatoken with a liquidity pool
|
||||
/// ## 6. Publish Data NFT and a Datatoken with a liquidity pool
|
||||
|
||||
For pool creation, the OCEAN token is used as the base token. The base token can be changed into something else, such as USDC, DAI etc., but it will require an extra fee.
|
||||
/// For pool creation, the OCEAN token is used as the base token. The base token can be changed into something else, such as USDC, DAI etc., but it will require an extra fee.
|
||||
|
||||
### 6.1 Publish a dataset (create NFT + Datatoken) with a liquidity pool
|
||||
```Typescript
|
||||
it('6.1 Publish a dataset (create NFT + Datatoken) with a liquidity pool', async () => {
|
||||
/// ```Typescript
|
||||
const factory = new NftFactory(addresses.ERC721Factory, web3)
|
||||
|
||||
const nftParams: NftCreateData = {
|
||||
@ -252,7 +252,7 @@ For pool creation, the OCEAN token is used as the base token. The base token can
|
||||
owner: publisherAccount
|
||||
}
|
||||
|
||||
const erc20Params: Erc20CreateParams = {
|
||||
const datatokenParams: DatatokenCreateParams = {
|
||||
templateIndex: 1,
|
||||
cap: '100000',
|
||||
feeAmount: '0',
|
||||
@ -277,9 +277,9 @@ For pool creation, the OCEAN token is used as the base token. The base token can
|
||||
swapFeeLiquidityProvider: '0.001',
|
||||
swapFeeMarketRunner: '0.001'
|
||||
}
|
||||
```
|
||||
Before we call the contract we have to call `approve` so that the contract can move our tokens. This is standard when using any ERC20 tokens
|
||||
```Typescript
|
||||
/// ```
|
||||
/// Before we call the contract we have to call `approve` so that the contract can move our tokens. This is standard when using any ERC20 Datatokens
|
||||
/// ```Typescript
|
||||
await approve(
|
||||
web3,
|
||||
publisherAccount,
|
||||
@ -288,48 +288,48 @@ Before we call the contract we have to call `approve` so that the contract can m
|
||||
poolParams.vestingAmount
|
||||
)
|
||||
|
||||
```
|
||||
Now we can make the contract call
|
||||
```Typescript
|
||||
const tx = await factory.createNftErc20WithPool(
|
||||
/// ```
|
||||
/// Now we can make the contract call
|
||||
/// ```Typescript
|
||||
const tx = await factory.createNftWithDatatokenWithPool(
|
||||
publisherAccount,
|
||||
nftParams,
|
||||
erc20Params,
|
||||
datatokenParams,
|
||||
poolParams
|
||||
)
|
||||
|
||||
poolNftAddress = tx.events.NFTCreated.returnValues[0]
|
||||
poolDatatokenAddress = tx.events.TokenCreated.returnValues[0]
|
||||
poolAddress = tx.events.NewPool.returnValues[0]
|
||||
```
|
||||
Now, we did quite a few things there. Let's check that we successfully published a dataset (create NFT + Datatoken) with a liquidity pool
|
||||
```Typescript
|
||||
/// ```
|
||||
/// Now, we did quite a few things there. Let's check that we successfully published a dataset (create NFT + Datatoken) with a liquidity pool
|
||||
/// ```Typescript
|
||||
console.log(`Pool NFT address: ${poolNftAddress}`)
|
||||
console.log(`Pool Datatoken address: ${poolDatatokenAddress}`)
|
||||
console.log(`Pool address: ${poolAddress}`)
|
||||
|
||||
```
|
||||
}) ///
|
||||
/// ```
|
||||
|
||||
### 6.2 Set metadata in the pool NFT
|
||||
```Typescript
|
||||
it('6.2 Set metadata in the pool NFT', async () => {
|
||||
/// ```Typescript
|
||||
const nft = new Nft(web3)
|
||||
```
|
||||
Now we update the ddo and set the right did
|
||||
```Typescript
|
||||
/// ```
|
||||
/// Now we update the ddo and set the right did
|
||||
/// ```Typescript
|
||||
DDO.chainId = await web3.eth.getChainId()
|
||||
DDO.id =
|
||||
'did:op:' +
|
||||
SHA256(web3.utils.toChecksumAddress(poolNftAddress) + DDO.chainId.toString(10))
|
||||
DDO.nftAddress = poolNftAddress
|
||||
```
|
||||
Next we encrypt the file or files using Ocean Provider. The provider is an off chain proxy built specifically for this task
|
||||
```Typescript
|
||||
/// ```
|
||||
/// Next we encrypt the file or files using Ocean Provider. The provider is an off chain proxy built specifically for this task
|
||||
/// ```Typescript
|
||||
const encryptedFiles = await ProviderInstance.encrypt(ASSET_URL, providerUrl)
|
||||
DDO.services[0].files = await encryptedFiles
|
||||
DDO.services[0].datatokenAddress = poolDatatokenAddress
|
||||
```
|
||||
Now let's console log the result to check everything is working
|
||||
```Typescript
|
||||
/// ```
|
||||
/// Now let's console log the result to check everything is working
|
||||
/// ```Typescript
|
||||
console.log(`DID: ${DDO.id}`)
|
||||
|
||||
const providerResponse = await ProviderInstance.encrypt(DDO, providerUrl)
|
||||
@ -345,27 +345,27 @@ Now let's console log the result to check everything is working
|
||||
encryptedDDO,
|
||||
'0x' + metadataHash
|
||||
)
|
||||
|
||||
```
|
||||
}) ///
|
||||
/// ```
|
||||
|
||||
### 6.3 User should add liquidity to the pool, receiving LP tokens
|
||||
```Typescript
|
||||
it('6.3 User should add liquidity to the pool, receiving LP tokens', async () => {
|
||||
/// ```Typescript
|
||||
const pool = new Pool(web3)
|
||||
|
||||
```
|
||||
Before we call the contract we have to call `approve` so that the contract can move our tokens. This is standard when using any ERC20 tokens
|
||||
```Typescript
|
||||
/// ```
|
||||
/// Before we call the contract we have to call `approve` so that the contract can move our tokens. This is standard when using any ERC20 Datatokens
|
||||
/// ```Typescript
|
||||
await approve(web3, stakerAccount, addresses.Ocean, poolAddress, '5', true)
|
||||
|
||||
```
|
||||
Now we can make the contract call
|
||||
```Typescript
|
||||
/// ```
|
||||
/// Now we can make the contract call
|
||||
/// ```Typescript
|
||||
await pool.joinswapExternAmountIn(stakerAccount, poolAddress, '5', '0.1')
|
||||
|
||||
```
|
||||
}) ///
|
||||
/// ```
|
||||
|
||||
### 6.4 Marketplace displays pool asset for sale
|
||||
```Typescript
|
||||
it('6.4 Marketplace displays pool asset for sale', async () => {
|
||||
/// ```Typescript
|
||||
const pool = new Pool(web3)
|
||||
const prices = await pool.getAmountInExactOut(
|
||||
poolAddress,
|
||||
@ -374,36 +374,36 @@ Now we can make the contract call
|
||||
'1',
|
||||
'0.01'
|
||||
)
|
||||
```
|
||||
Now let's console log the result to check everything is working
|
||||
```Typescript
|
||||
/// ```
|
||||
/// Now let's console log the result to check everything is working
|
||||
/// ```Typescript
|
||||
console.log(`Price of 1 ${POOL_NFT_SYMBOL} is ${prices.tokenAmount} OCEAN`)
|
||||
|
||||
```
|
||||
}) ///
|
||||
/// ```
|
||||
|
||||
### 6.5 Consumer buys a pool data asset, and downloads it
|
||||
```Typescript
|
||||
it('6.5 Consumer buys a pool data asset, and downloads it', async () => {
|
||||
/// ```Typescript
|
||||
const datatoken = new Datatoken(web3)
|
||||
|
||||
const consumerETHBalance = await web3.eth.getBalance(consumerAccount)
|
||||
```
|
||||
Now let's console log the result to check everything is working
|
||||
```Typescript
|
||||
/// ```
|
||||
/// Now let's console log the result to check everything is working
|
||||
/// ```Typescript
|
||||
console.log(`Consumer ETH balance: ${consumerETHBalance}`)
|
||||
let consumerOCEANBalance = await balance(web3, addresses.Ocean, consumerAccount)
|
||||
```
|
||||
Now let's console log consumerOCEANBalance to check everything is working
|
||||
```Typescript
|
||||
/// ```
|
||||
/// Now let's console log consumerOCEANBalance to check everything is working
|
||||
/// ```Typescript
|
||||
console.log(`Consumer OCEAN balance before swap: ${consumerOCEANBalance}`)
|
||||
let consumerDTBalance = await balance(web3, poolDatatokenAddress, consumerAccount)
|
||||
```
|
||||
Now let's console log POOL_NFT_SYMBOL and consumerDTBalance to check everything is working
|
||||
```Typescript
|
||||
/// ```
|
||||
/// Now let's console log POOL_NFT_SYMBOL and consumerDTBalance to check everything is working
|
||||
/// ```Typescript
|
||||
console.log(`Consumer ${POOL_NFT_SYMBOL} balance before swap: ${consumerDTBalance}`)
|
||||
|
||||
```
|
||||
Before we call the contract we have to call `approve` so that the contract can move our tokens. This is standard when using any ERC20 tokens
|
||||
```Typescript
|
||||
/// ```
|
||||
/// Before we call the contract we have to call `approve` so that the contract can move our tokens. This is standard when using any ERC20 Datatokens
|
||||
/// ```Typescript
|
||||
await approve(web3, consumerAccount, addresses.Ocean, poolAddress, '100')
|
||||
|
||||
const pool = new Pool(web3)
|
||||
@ -418,9 +418,9 @@ Before we call the contract we have to call `approve` so that the contract can m
|
||||
swapMarketFee: '0.1'
|
||||
}
|
||||
|
||||
```
|
||||
Now we can make the contract call
|
||||
```Typescript
|
||||
/// ```
|
||||
/// Now we can make the contract call
|
||||
/// ```Typescript
|
||||
await pool.swapExactAmountOut(
|
||||
consumerAccount,
|
||||
poolAddress,
|
||||
@ -429,22 +429,22 @@ Now we can make the contract call
|
||||
)
|
||||
|
||||
consumerOCEANBalance = await balance(web3, addresses.Ocean, consumerAccount)
|
||||
```
|
||||
Now let's console log the Consumer OCEAN balance after swap to check everything is working
|
||||
```Typescript
|
||||
/// ```
|
||||
/// Now let's console log the Consumer OCEAN balance after swap to check everything is working
|
||||
/// ```Typescript
|
||||
console.log(`Consumer OCEAN balance after swap: ${consumerOCEANBalance}`)
|
||||
consumerDTBalance = await balance(web3, poolDatatokenAddress, consumerAccount)
|
||||
```
|
||||
Next let's console log the POOL_NFT_SYMBOL and consumerDTBalance
|
||||
```Typescript
|
||||
/// ```
|
||||
/// Next let's console log the POOL_NFT_SYMBOL and consumerDTBalance
|
||||
/// ```Typescript
|
||||
console.log(`Consumer ${POOL_NFT_SYMBOL} balance after swap: ${consumerDTBalance}`)
|
||||
|
||||
const resolvedDDO = await aquarius.waitForAqua(DDO.id)
|
||||
assert(resolvedDDO, 'Cannot fetch DDO from Aquarius')
|
||||
|
||||
```
|
||||
The next step is to initialize the provider instance
|
||||
```Typescript
|
||||
/// ```
|
||||
/// The next step is to initialize the provider instance
|
||||
/// ```Typescript
|
||||
const initializeData = await ProviderInstance.initialize(
|
||||
resolvedDDO.id,
|
||||
resolvedDDO.services[0].id,
|
||||
@ -464,9 +464,9 @@ The next step is to initialize the provider instance
|
||||
validUntil: initializeData.providerFee.validUntil
|
||||
}
|
||||
|
||||
```
|
||||
Now let's make a payment
|
||||
```Typescript
|
||||
/// ```
|
||||
/// Now let's make a payment
|
||||
/// ```Typescript
|
||||
const tx = await datatoken.startOrder(
|
||||
poolDatatokenAddress,
|
||||
consumerAccount,
|
||||
@ -475,9 +475,9 @@ Now let's make a payment
|
||||
providerFees
|
||||
)
|
||||
|
||||
```
|
||||
Next up, let's get the URL
|
||||
```Typescript
|
||||
/// ```
|
||||
/// Next up, let's get the URL
|
||||
/// ```Typescript
|
||||
const downloadURL = await ProviderInstance.getDownloadUrl(
|
||||
DDO.id,
|
||||
consumerAccount,
|
||||
@ -488,18 +488,18 @@ Next up, let's get the URL
|
||||
web3
|
||||
)
|
||||
|
||||
```
|
||||
Now let's console log the Download URL to check everything is working
|
||||
```Typescript
|
||||
/// ```
|
||||
/// Now let's console log the Download URL to check everything is working
|
||||
/// ```Typescript
|
||||
console.log(`Download URL: ${downloadURL}`)
|
||||
|
||||
consumerOCEANBalance = await balance(web3, addresses.Ocean, consumerAccount)
|
||||
console.log(`Consumer OCEAN balance after order: ${consumerOCEANBalance}`)
|
||||
consumerDTBalance = await balance(web3, poolDatatokenAddress, consumerAccount)
|
||||
|
||||
```
|
||||
Now let's console log the Consumer balance after order to check everything is working
|
||||
```Typescript
|
||||
/// ```
|
||||
/// Now let's console log the Consumer balance after order to check everything is working
|
||||
/// ```Typescript
|
||||
console.log(`Consumer ${POOL_NFT_SYMBOL} balance after order: ${consumerDTBalance}`)
|
||||
|
||||
try {
|
||||
@ -508,13 +508,13 @@ Now let's console log the Consumer balance after order to check everything is wo
|
||||
} catch (e) {
|
||||
assert.fail('Download failed')
|
||||
}
|
||||
|
||||
```
|
||||
}) ///
|
||||
/// ```
|
||||
|
||||
## 7. Publish Data NFT and a Datatoken with a fixed rate exchange
|
||||
/// ## 7. Publish Data NFT and a Datatoken with a fixed rate exchange
|
||||
|
||||
### 7.1 Publish a dataset (create NFT + Datatoken) with a fixed rate exchange
|
||||
```Typescript
|
||||
it('7.1 Publish a dataset (create NFT + Datatoken) with a fixed rate exchange', async () => {
|
||||
/// ```Typescript
|
||||
const factory = new NftFactory(addresses.ERC721Factory, web3)
|
||||
|
||||
const nftParams: NftCreateData = {
|
||||
@ -526,7 +526,7 @@ Now let's console log the Consumer balance after order to check everything is wo
|
||||
owner: publisherAccount
|
||||
}
|
||||
|
||||
const erc20Params: Erc20CreateParams = {
|
||||
const datatokenParams: DatatokenCreateParams = {
|
||||
templateIndex: 1,
|
||||
cap: '100000',
|
||||
feeAmount: '0',
|
||||
@ -549,10 +549,10 @@ Now let's console log the Consumer balance after order to check everything is wo
|
||||
withMint: false
|
||||
}
|
||||
|
||||
const tx = await factory.createNftErc20WithFixedRate(
|
||||
const tx = await factory.createNftWithDatatokenWithFixedRate(
|
||||
publisherAccount,
|
||||
nftParams,
|
||||
erc20Params,
|
||||
datatokenParams,
|
||||
freParams
|
||||
)
|
||||
|
||||
@ -561,39 +561,39 @@ Now let's console log the Consumer balance after order to check everything is wo
|
||||
freAddress = tx.events.NewFixedRate.returnValues.exchangeContract
|
||||
freId = tx.events.NewFixedRate.returnValues.exchangeId
|
||||
|
||||
```
|
||||
Now let's console log each of those values to check everything is working
|
||||
```Typescript
|
||||
/// ```
|
||||
/// Now let's console log each of those values to check everything is working
|
||||
/// ```Typescript
|
||||
console.log(`Fixed rate exchange NFT address: ${freNftAddress}`)
|
||||
console.log(`Fixed rate exchange Datatoken address: ${freDatatokenAddress}`)
|
||||
console.log(`Fixed rate exchange address: ${freAddress}`)
|
||||
console.log(`Fixed rate exchange Id: ${freId}`)
|
||||
|
||||
```
|
||||
}) ///
|
||||
/// ```
|
||||
|
||||
### 7.2 Set metadata in the fixed rate exchange NFT
|
||||
```Typescript
|
||||
it('7.2 Set metadata in the fixed rate exchange NFT', async () => {
|
||||
/// ```Typescript
|
||||
const nft = new Nft(web3)
|
||||
|
||||
```
|
||||
Now we are going to update the ddo and set the did
|
||||
```Typescript
|
||||
/// ```
|
||||
/// Now we are going to update the ddo and set the did
|
||||
/// ```Typescript
|
||||
DDO.chainId = await web3.eth.getChainId()
|
||||
DDO.id =
|
||||
'did:op:' +
|
||||
SHA256(web3.utils.toChecksumAddress(freNftAddress) + DDO.chainId.toString(10))
|
||||
DDO.nftAddress = freNftAddress
|
||||
|
||||
```
|
||||
Next, let's encrypt the file(s) using provider
|
||||
```Typescript
|
||||
/// ```
|
||||
/// Next, let's encrypt the file(s) using provider
|
||||
/// ```Typescript
|
||||
const encryptedFiles = await ProviderInstance.encrypt(ASSET_URL, providerUrl)
|
||||
DDO.services[0].files = await encryptedFiles
|
||||
DDO.services[0].datatokenAddress = freDatatokenAddress
|
||||
|
||||
```
|
||||
Now let's console log the DID to check everything is working
|
||||
```Typescript
|
||||
/// ```
|
||||
/// Now let's console log the DID to check everything is working
|
||||
/// ```Typescript
|
||||
console.log(`DID: ${DDO.id}`)
|
||||
|
||||
const providerResponse = await ProviderInstance.encrypt(DDO, providerUrl)
|
||||
@ -610,23 +610,23 @@ Now let's console log the DID to check everything is working
|
||||
'0x' + metadataHash
|
||||
)
|
||||
})
|
||||
```
|
||||
/// ```
|
||||
|
||||
### 7.3 Marketplace displays fixed rate asset for sale
|
||||
```Typescript
|
||||
const fixedRate = new FixedRateExchange(web3, freAddress)
|
||||
it('7.3 Marketplace displays fixed rate asset for sale', async () => {
|
||||
/// ```Typescript
|
||||
const fixedRate = new FixedRateExchange(freAddress, web3)
|
||||
const oceanAmount = await (
|
||||
await fixedRate.calcBaseInGivenOutDT(freId, '1')
|
||||
).baseTokenAmount
|
||||
```
|
||||
Now that the market has fetched those values it can display the asset on the front end. In our case we will just console log the results:
|
||||
```Typescript
|
||||
/// ```
|
||||
/// Now that the market has fetched those values it can display the asset on the front end. In our case we will just console log the results:
|
||||
/// ```Typescript
|
||||
console.log(`Price of 1 ${FRE_NFT_SYMBOL} is ${oceanAmount} OCEAN`)
|
||||
|
||||
```
|
||||
}) ///
|
||||
/// ```
|
||||
|
||||
### 7.4 Consumer buys a fixed rate asset data asset, and downloads it
|
||||
```Typescript
|
||||
it('7.4 Consumer buys a fixed rate asset data asset, and downloads it', async () => {
|
||||
/// ```Typescript
|
||||
const datatoken = new Datatoken(web3)
|
||||
const DATATOKEN_AMOUNT = '10000'
|
||||
|
||||
@ -634,18 +634,18 @@ Now that the market has fetched those values it can display the asset on the fro
|
||||
|
||||
const consumerETHBalance = await web3.eth.getBalance(consumerAccount)
|
||||
|
||||
```
|
||||
Let's do a quick check of the consumer ETH balance before the swap
|
||||
```Typescript
|
||||
/// ```
|
||||
/// Let's do a quick check of the consumer ETH balance before the swap
|
||||
/// ```Typescript
|
||||
console.log(`Consumer ETH balance: ${consumerETHBalance}`)
|
||||
let consumerOCEANBalance = await balance(web3, addresses.Ocean, consumerAccount)
|
||||
console.log(`Consumer OCEAN balance before swap: ${consumerOCEANBalance}`)
|
||||
let consumerDTBalance = await balance(web3, freDatatokenAddress, consumerAccount)
|
||||
console.log(`Consumer ${FRE_NFT_SYMBOL} balance before swap: ${consumerDTBalance}`)
|
||||
|
||||
```
|
||||
Before we call the contract we have to call `approve` so that the contract can move our tokens. This is standard when using any ERC20 tokens
|
||||
```Typescript
|
||||
/// ```
|
||||
/// Before we call the contract we have to call `approve` so that the contract can move our tokens. This is standard when using any ERC20 Datatokens
|
||||
/// ```Typescript
|
||||
await approve(web3, consumerAccount, addresses.Ocean, freAddress, '100')
|
||||
await approve(
|
||||
web3,
|
||||
@ -655,10 +655,10 @@ Before we call the contract we have to call `approve` so that the contract can m
|
||||
DATATOKEN_AMOUNT
|
||||
)
|
||||
|
||||
const fixedRate = new FixedRateExchange(web3, freAddress)
|
||||
```
|
||||
Now we can make the contract call
|
||||
```Typescript
|
||||
const fixedRate = new FixedRateExchange(freAddress, web3)
|
||||
/// ```
|
||||
/// Now we can make the contract call
|
||||
/// ```Typescript
|
||||
await fixedRate.buyDT(consumerAccount, freId, '1', '2')
|
||||
|
||||
consumerOCEANBalance = await balance(web3, addresses.Ocean, consumerAccount)
|
||||
@ -669,9 +669,9 @@ Now we can make the contract call
|
||||
const resolvedDDO = await aquarius.waitForAqua(DDO.id)
|
||||
assert(resolvedDDO, 'Cannot fetch DDO from Aquarius')
|
||||
|
||||
```
|
||||
Next, we need to initialize the provider
|
||||
```Typescript
|
||||
/// ```
|
||||
/// Next, we need to initialize the provider
|
||||
/// ```Typescript
|
||||
const initializeData = await ProviderInstance.initialize(
|
||||
resolvedDDO.id,
|
||||
resolvedDDO.services[0].id,
|
||||
@ -691,9 +691,9 @@ Next, we need to initialize the provider
|
||||
validUntil: initializeData.providerFee.validUntil
|
||||
}
|
||||
|
||||
```
|
||||
Lets now make the payment
|
||||
```Typescript
|
||||
/// ```
|
||||
/// Lets now make the payment
|
||||
/// ```Typescript
|
||||
const tx = await datatoken.startOrder(
|
||||
freDatatokenAddress,
|
||||
consumerAccount,
|
||||
@ -701,9 +701,9 @@ Lets now make the payment
|
||||
0,
|
||||
providerFees
|
||||
)
|
||||
```
|
||||
Now we can get the url
|
||||
```Typescript
|
||||
/// ```
|
||||
/// Now we can get the url
|
||||
/// ```Typescript
|
||||
const downloadURL = await ProviderInstance.getDownloadUrl(
|
||||
DDO.id,
|
||||
consumerAccount,
|
||||
@ -714,9 +714,9 @@ Now we can get the url
|
||||
web3
|
||||
)
|
||||
|
||||
```
|
||||
Lets check that the download URL was successfully received
|
||||
```Typescript
|
||||
/// ```
|
||||
/// Lets check that the download URL was successfully received
|
||||
/// ```Typescript
|
||||
console.log(`Download URL: ${downloadURL}`)
|
||||
|
||||
consumerOCEANBalance = await balance(web3, addresses.Ocean, consumerAccount)
|
||||
@ -730,13 +730,13 @@ Lets check that the download URL was successfully received
|
||||
} catch (e) {
|
||||
assert.fail('Download failed')
|
||||
}
|
||||
|
||||
```
|
||||
}) ///
|
||||
/// ```
|
||||
|
||||
## 8. Publish Data NFT and a Datatoken with a dispenser
|
||||
/// ## 8. Publish Data NFT and a Datatoken with a dispenser
|
||||
|
||||
### 8.1 Publish a dataset (create NFT + Datatoken) with a dispenser
|
||||
```Typescript
|
||||
it('8.1 Publish a dataset (create NFT + Datatoken) with a dispenser', async () => {
|
||||
/// ```Typescript
|
||||
const factory = new NftFactory(addresses.ERC721Factory, web3)
|
||||
|
||||
const nftParams: NftCreateData = {
|
||||
@ -748,7 +748,7 @@ Lets check that the download URL was successfully received
|
||||
owner: publisherAccount
|
||||
}
|
||||
|
||||
const erc20Params: Erc20CreateParams = {
|
||||
const datatokenParams: DatatokenCreateParams = {
|
||||
templateIndex: 1,
|
||||
cap: '100000',
|
||||
feeAmount: '0',
|
||||
@ -766,41 +766,41 @@ Lets check that the download URL was successfully received
|
||||
allowedSwapper: ZERO_ADDRESS
|
||||
}
|
||||
|
||||
const tx = await factory.createNftErc20WithDispenser(
|
||||
const tx = await factory.createNftWithDatatokenWithDispenser(
|
||||
publisherAccount,
|
||||
nftParams,
|
||||
erc20Params,
|
||||
datatokenParams,
|
||||
dispenserParams
|
||||
)
|
||||
|
||||
dispenserNftAddress = tx.events.NFTCreated.returnValues[0]
|
||||
dispenserDatatokenAddress = tx.events.TokenCreated.returnValues[0]
|
||||
dispenserAddress = tx.events.DispenserCreated.returnValues[0]
|
||||
```
|
||||
Lets check that we managed to received all of those values without any problems
|
||||
```Typescript
|
||||
/// ```
|
||||
/// Lets check that we managed to received all of those values without any problems
|
||||
/// ```Typescript
|
||||
console.log(`Dispenser NFT address: ${dispenserNftAddress}`)
|
||||
console.log(`Dispenser Datatoken address: ${dispenserDatatokenAddress}`)
|
||||
console.log(`Dispenser address: ${dispenserAddress}`)
|
||||
|
||||
```
|
||||
}) ///
|
||||
/// ```
|
||||
|
||||
### 8.2 Set metadata in the dispenser NFT
|
||||
```Typescript
|
||||
it('8.2 Set metadata in the dispenser NFT', async () => {
|
||||
/// ```Typescript
|
||||
const nft = new Nft(web3)
|
||||
|
||||
```
|
||||
Lets start by updating the ddo and setting the did
|
||||
```Typescript
|
||||
/// ```
|
||||
/// Lets start by updating the ddo and setting the did
|
||||
/// ```Typescript
|
||||
DDO.chainId = await web3.eth.getChainId()
|
||||
DDO.id =
|
||||
'did:op:' +
|
||||
SHA256(web3.utils.toChecksumAddress(dispenserNftAddress) + DDO.chainId.toString(10))
|
||||
DDO.nftAddress = dispenserNftAddress
|
||||
|
||||
```
|
||||
Now we need to encrypt file(s) using provider
|
||||
```Typescript
|
||||
/// ```
|
||||
/// Now we need to encrypt file(s) using provider
|
||||
/// ```Typescript
|
||||
const encryptedFiles = await ProviderInstance.encrypt(ASSET_URL, providerUrl)
|
||||
DDO.services[0].files = await encryptedFiles
|
||||
DDO.services[0].datatokenAddress = dispenserDatatokenAddress
|
||||
@ -820,13 +820,13 @@ Now we need to encrypt file(s) using provider
|
||||
encryptedDDO,
|
||||
'0x' + metadataHash
|
||||
)
|
||||
|
||||
```
|
||||
}) ///
|
||||
/// ```
|
||||
|
||||
### 8.3 Consumer gets a dispenser data asset, and downloads it
|
||||
```Typescript
|
||||
it('8.3 Consumer gets a dispenser data asset, and downloads it', async () => {
|
||||
/// ```Typescript
|
||||
const datatoken = new Datatoken(web3)
|
||||
const dispenser = new Dispenser(web3, null, addresses.Dispenser)
|
||||
const dispenser = new Dispenser(addresses.Dispenser, web3)
|
||||
|
||||
let consumerDTBalance = await balance(
|
||||
web3,
|
||||
@ -851,9 +851,9 @@ Now we need to encrypt file(s) using provider
|
||||
|
||||
const resolvedDDO = await aquarius.waitForAqua(DDO.id)
|
||||
assert(resolvedDDO, 'Cannot fetch DDO from Aquarius')
|
||||
```
|
||||
At this point we need to encrypt file(s) using provider
|
||||
```Typescript
|
||||
/// ```
|
||||
/// At this point we need to encrypt file(s) using provider
|
||||
/// ```Typescript
|
||||
const initializeData = await ProviderInstance.initialize(
|
||||
resolvedDDO.id,
|
||||
resolvedDDO.services[0].id,
|
||||
@ -872,9 +872,9 @@ At this point we need to encrypt file(s) using provider
|
||||
providerData: initializeData.providerFee.providerData,
|
||||
validUntil: initializeData.providerFee.validUntil
|
||||
}
|
||||
```
|
||||
Now we need to make the payment
|
||||
```Typescript
|
||||
/// ```
|
||||
/// Now we need to make the payment
|
||||
/// ```Typescript
|
||||
const tx = await datatoken.startOrder(
|
||||
dispenserDatatokenAddress,
|
||||
consumerAccount,
|
||||
@ -882,9 +882,9 @@ Now we need to make the payment
|
||||
0,
|
||||
providerFees
|
||||
)
|
||||
```
|
||||
Now we can get the download URL
|
||||
```Typescript
|
||||
/// ```
|
||||
/// Now we can get the download URL
|
||||
/// ```Typescript
|
||||
const downloadURL = await ProviderInstance.getDownloadUrl(
|
||||
DDO.id,
|
||||
consumerAccount,
|
||||
@ -894,9 +894,9 @@ Now we can get the download URL
|
||||
providerUrl,
|
||||
web3
|
||||
)
|
||||
```
|
||||
Let's check we received the download URL ok
|
||||
```Typescript
|
||||
/// ```
|
||||
/// Let's check we received the download URL ok
|
||||
/// ```Typescript
|
||||
console.log(`Download URL: ${downloadURL}`)
|
||||
|
||||
consumerDTBalance = await balance(web3, dispenserDatatokenAddress, consumerAccount)
|
||||
@ -908,11 +908,11 @@ Let's check we received the download URL ok
|
||||
} catch (e) {
|
||||
assert.fail('Download failed')
|
||||
}
|
||||
|
||||
```
|
||||
}) ///
|
||||
/// ```
|
||||
}) ///
|
||||
|
||||
|
||||
## Editing this file
|
||||
Please note that CodeExamples.md is an autogenerated file, you should not edit it directly.
|
||||
Updates should be done in `test/integration/CodeExamples.test.ts` and all markdown should have three forward slashes before it
|
||||
e.g. `/// # H1 Title`
|
||||
/// ## Editing this file
|
||||
/// Please note that CodeExamples.md is an autogenerated file, you should not edit it directly.
|
||||
/// Updates should be done in `test/integration/CodeExamples.test.ts` and all markdown should have three forward slashes before it
|
||||
/// e.g. `/// # H1 Title`
|
||||
|
@ -1,4 +1,4 @@
|
||||
import { DDO } from './DDO/DDO'
|
||||
import { DDO } from '.'
|
||||
|
||||
export interface AssetNft {
|
||||
/**
|
||||
@ -65,7 +65,7 @@ export interface Purgatory {
|
||||
|
||||
export interface AssetDatatoken {
|
||||
/**
|
||||
* Contract address of the deployed ERC20 contract.
|
||||
* Contract address of the deployed Datatoken contract.
|
||||
* @type {string}
|
||||
*/
|
||||
address: string
|
||||
@ -105,7 +105,7 @@ export interface Asset extends DDO {
|
||||
nft: AssetNft
|
||||
|
||||
/**
|
||||
* Contains information about the ERC20 datatokens attached to asset services.
|
||||
* Contains information about the ERC20 Datatokens attached to asset services.
|
||||
* @type {string}
|
||||
*/
|
||||
datatokens: AssetDatatoken[]
|
||||
|
@ -1,4 +1,4 @@
|
||||
import { Metadata, MetadataAlgorithm } from './DDO/Metadata'
|
||||
import { Metadata, MetadataAlgorithm } from '.'
|
||||
|
||||
export type ComputeResultType =
|
||||
| 'algorithmLog'
|
||||
|
@ -1,7 +1,4 @@
|
||||
import { Service } from './Service'
|
||||
import { Metadata } from './Metadata'
|
||||
import { Credentials } from './Credentials'
|
||||
import { Event } from './Event'
|
||||
import { Service, Metadata, Credentials, Event } from '..'
|
||||
|
||||
/**
|
||||
* DID Descriptor Object.
|
||||
@ -16,7 +13,7 @@ export interface DDO {
|
||||
|
||||
/**
|
||||
* DID, descentralized ID.
|
||||
* Computed as sha256(address of ERC721 contract + chainId)
|
||||
* Computed as sha256(address of NFT contract + chainId)
|
||||
* @type {string}
|
||||
*/
|
||||
id: string
|
||||
|
44
src/@types/Datatoken.ts
Normal file
44
src/@types/Datatoken.ts
Normal file
@ -0,0 +1,44 @@
|
||||
import { ProviderFees } from '.'
|
||||
|
||||
export interface DatatokenCreateParams {
|
||||
templateIndex: number
|
||||
minter: string
|
||||
paymentCollector: string
|
||||
mpFeeAddress: string
|
||||
feeToken: string
|
||||
feeAmount: string
|
||||
cap: string
|
||||
name?: string
|
||||
symbol?: string
|
||||
}
|
||||
|
||||
export interface ConsumeMarketFee {
|
||||
consumeMarketFeeAddress: string
|
||||
consumeMarketFeeToken: string // address of the token marketplace wants to add fee on top
|
||||
consumeMarketFeeAmount: string
|
||||
}
|
||||
|
||||
export interface PublishingMarketFee {
|
||||
publishMarketFeeAddress: string
|
||||
publishMarketFeeToken: string
|
||||
publishMarketFeeAmount: string
|
||||
}
|
||||
|
||||
export interface DatatokenRoles {
|
||||
minter: boolean
|
||||
paymentManager: boolean
|
||||
}
|
||||
|
||||
export interface OrderParams {
|
||||
consumer: string
|
||||
serviceIndex: number
|
||||
_providerFee: ProviderFees
|
||||
_consumeMarketFee: ConsumeMarketFee
|
||||
}
|
||||
|
||||
export interface DispenserParams {
|
||||
maxTokens: string
|
||||
maxBalance: string
|
||||
withMint?: boolean // true if we want to allow the dispenser to be a minter
|
||||
allowedSwapper?: string // only account that can ask tokens. set address(0) if not required
|
||||
}
|
@ -5,3 +5,13 @@ export interface DispenserCreationParams {
|
||||
withMint?: boolean // true if we want to allow the dispenser to be a minter
|
||||
allowedSwapper?: string // only account that can ask tokens. set address(0) if not required
|
||||
}
|
||||
|
||||
export interface DispenserToken {
|
||||
active: boolean
|
||||
owner: string
|
||||
maxTokens: string
|
||||
maxBalance: string
|
||||
balance: string
|
||||
isMinter: boolean
|
||||
allowedSwapper: string
|
||||
}
|
||||
|
@ -1,23 +0,0 @@
|
||||
export interface Erc20CreateParams {
|
||||
templateIndex: number
|
||||
minter: string
|
||||
paymentCollector: string
|
||||
mpFeeAddress: string
|
||||
feeToken: string
|
||||
feeAmount: string
|
||||
cap: string
|
||||
name?: string
|
||||
symbol?: string
|
||||
}
|
||||
|
||||
export interface ConsumeMarketFee {
|
||||
consumeMarketFeeAddress: string
|
||||
consumeMarketFeeToken: string // address of the token marketplace wants to add fee on top
|
||||
consumeMarketFeeAmount: string
|
||||
}
|
||||
|
||||
export interface PublishingMarketFee {
|
||||
publishMarketFeeAddress: string
|
||||
publishMarketFeeToken: string
|
||||
publishMarketFeeAmount: string
|
||||
}
|
@ -25,3 +25,29 @@ export interface PriceAndFees {
|
||||
marketFeeAmount: string
|
||||
consumeMarketFeeAmount: string
|
||||
}
|
||||
|
||||
export interface FixedPriceExchange {
|
||||
active: boolean
|
||||
exchangeOwner: string
|
||||
datatoken: string
|
||||
baseToken: string
|
||||
fixedRate: string
|
||||
dtDecimals: string
|
||||
btDecimals: string
|
||||
dtBalance: string
|
||||
btBalance: string
|
||||
dtSupply: string
|
||||
btSupply: string
|
||||
withMint: boolean
|
||||
allowedSwapper: string
|
||||
exchangeId?: string
|
||||
}
|
||||
|
||||
export interface FeesInfo {
|
||||
opcFee: string
|
||||
marketFee: string
|
||||
marketFeeCollector: string
|
||||
marketFeeAvailable: string
|
||||
oceanFeeAvailable: string
|
||||
exchangeId: string
|
||||
}
|
||||
|
@ -11,3 +11,10 @@ export interface MetadataAndTokenURI {
|
||||
tokenURI: string
|
||||
metadataProofs?: MetadataProof[]
|
||||
}
|
||||
|
||||
export interface NftRoles {
|
||||
manager: boolean
|
||||
deployERC20: boolean
|
||||
updateMetadata: boolean
|
||||
store: boolean
|
||||
}
|
23
src/@types/NFTFactory.ts
Normal file
23
src/@types/NFTFactory.ts
Normal file
@ -0,0 +1,23 @@
|
||||
import { ConsumeMarketFee, ProviderFees } from '.'
|
||||
|
||||
export interface Template {
|
||||
templateAddress: string
|
||||
isActive: boolean
|
||||
}
|
||||
|
||||
export interface TokenOrder {
|
||||
tokenAddress: string
|
||||
consumer: string
|
||||
serviceIndex: number
|
||||
_providerFee: ProviderFees
|
||||
_consumeMarketFee: ConsumeMarketFee
|
||||
}
|
||||
|
||||
export interface NftCreateData {
|
||||
name: string
|
||||
symbol: string
|
||||
templateIndex: number
|
||||
tokenURI: string
|
||||
transferable: boolean
|
||||
owner: string
|
||||
}
|
@ -26,3 +26,12 @@ export interface ProviderComputeInitializeResults {
|
||||
algorithm?: ProviderComputeInitialize
|
||||
datasets?: ProviderComputeInitialize[]
|
||||
}
|
||||
|
||||
export interface ServiceEndpoint {
|
||||
serviceName: string
|
||||
method: string
|
||||
urlPath: string
|
||||
}
|
||||
export interface UserCustomParameters {
|
||||
[key: string]: any
|
||||
}
|
||||
|
@ -1,14 +1,17 @@
|
||||
export * from './DDO/DDO'
|
||||
export * from './Asset'
|
||||
export * from './DDO/Service'
|
||||
export * from './DDO/Credentials'
|
||||
export * from './DDO/DDO'
|
||||
export * from './DDO/Event'
|
||||
export * from './DDO/Metadata'
|
||||
export * from './FileMetadata'
|
||||
export * from './DDO/Service'
|
||||
export * from './Asset'
|
||||
export * from './Compute'
|
||||
export * from './Provider'
|
||||
export * from './FixedPrice'
|
||||
export * from './Pool'
|
||||
export * from './Erc20'
|
||||
export * from './Erc721'
|
||||
export * from './Datatoken'
|
||||
export * from './Dispenser'
|
||||
export * from './DownloadResponse'
|
||||
export * from './FileMetadata'
|
||||
export * from './FixedPrice'
|
||||
export * from './NFT'
|
||||
export * from './NFTFactory'
|
||||
export * from './Pool'
|
||||
export * from './Provider'
|
||||
export * from './Router'
|
||||
|
@ -1 +0,0 @@
|
||||
export * from './Aquarius'
|
@ -1,5 +1,5 @@
|
||||
import { LogLevel } from '../utils/Logger'
|
||||
import { AbiItem } from 'web3-utils/types'
|
||||
import { LogLevel } from '../utils'
|
||||
|
||||
export class Config {
|
||||
/**
|
||||
@ -42,13 +42,7 @@ export class Config {
|
||||
* Factory address
|
||||
* @type {string}
|
||||
*/
|
||||
public erc721FactoryAddress?: string
|
||||
|
||||
/**
|
||||
* Factory ABI
|
||||
* @type {string}
|
||||
*/
|
||||
public erc721FFactoryABI?: AbiItem | AbiItem[]
|
||||
public nftFactoryAddress?: string
|
||||
|
||||
/**
|
||||
* datatokens ABI
|
||||
@ -195,5 +189,3 @@ export class Config {
|
||||
*/
|
||||
gasFeeMultiplier: number
|
||||
}
|
||||
|
||||
export default Config
|
@ -1,7 +1,7 @@
|
||||
import Config from '../models/Config'
|
||||
// eslint-disable-next-line import/no-named-default
|
||||
import { default as DefaultContractsAddresses } from '@oceanprotocol/contracts/addresses/address.json'
|
||||
import LoggerInstance from './Logger'
|
||||
import { Config } from '.'
|
||||
import { LoggerInstance } from '../utils'
|
||||
|
||||
const configHelperNetworksBase: Config = {
|
||||
chainId: null,
|
||||
@ -161,7 +161,7 @@ export class ConfigHelper {
|
||||
startBlock
|
||||
} = customAddresses[network]
|
||||
configAddresses = {
|
||||
erc721FactoryAddress: ERC721Factory,
|
||||
nftFactoryAddress: ERC721Factory,
|
||||
sideStakingAddress: Staking,
|
||||
opfCommunityFeeCollector: OPFCommunityFeeCollector,
|
||||
poolTemplateAddress: poolTemplate,
|
||||
@ -191,7 +191,7 @@ export class ConfigHelper {
|
||||
startBlock
|
||||
} = DefaultContractsAddresses[network]
|
||||
configAddresses = {
|
||||
erc721FactoryAddress: ERC721Factory,
|
||||
nftFactoryAddress: ERC721Factory,
|
||||
sideStakingAddress: Staking,
|
||||
opfCommunityFeeCollector: OPFCommunityFeeCollector,
|
||||
poolTemplateAddress: poolTemplate,
|
2
src/config/index.ts
Normal file
2
src/config/index.ts
Normal file
@ -0,0 +1,2 @@
|
||||
export * from './Config'
|
||||
export * from './ConfigHelper'
|
67
src/contracts/SmartContract.ts
Normal file
67
src/contracts/SmartContract.ts
Normal file
@ -0,0 +1,67 @@
|
||||
import Web3 from 'web3'
|
||||
import { Contract } from 'web3-eth-contract'
|
||||
import { AbiItem } from 'web3-utils'
|
||||
import { Config, ConfigHelper } from '../config'
|
||||
import {
|
||||
amountToUnits,
|
||||
getFairGasPrice,
|
||||
setContractDefaults,
|
||||
unitsToAmount
|
||||
} from '../utils'
|
||||
|
||||
export abstract class SmartContract {
|
||||
public web3: Web3
|
||||
public config: Config
|
||||
public abi: AbiItem | AbiItem[]
|
||||
|
||||
abstract getDefaultAbi(): AbiItem | AbiItem[]
|
||||
|
||||
/**
|
||||
* Instantiate the smart contract.
|
||||
* @param {Web3} web3
|
||||
* @param {string | number} network Network id or name
|
||||
* @param {Config} config Configutation of the smart contract
|
||||
* @param {AbiItem | AbiItem[]} abi ABI of the smart contract
|
||||
*/
|
||||
constructor(
|
||||
web3: Web3,
|
||||
network?: string | number,
|
||||
config?: Config,
|
||||
abi?: AbiItem | AbiItem[]
|
||||
) {
|
||||
this.web3 = web3
|
||||
this.config = config || new ConfigHelper().getConfig(network || 'unknown')
|
||||
this.abi = abi || (this.getDefaultAbi() as AbiItem[])
|
||||
}
|
||||
|
||||
protected async amountToUnits(
|
||||
token: string,
|
||||
amount: string,
|
||||
tokenDecimals?: number
|
||||
): Promise<string> {
|
||||
return amountToUnits(this.web3, token, amount, tokenDecimals)
|
||||
}
|
||||
|
||||
protected async unitsToAmount(
|
||||
token: string,
|
||||
amount: string,
|
||||
tokenDecimals?: number
|
||||
): Promise<string> {
|
||||
return unitsToAmount(this.web3, token, amount, tokenDecimals)
|
||||
}
|
||||
|
||||
protected async getFairGasPrice(): Promise<string> {
|
||||
return getFairGasPrice(this.web3, this.config)
|
||||
}
|
||||
|
||||
protected getContract(
|
||||
address: string,
|
||||
account?: string,
|
||||
abi?: AbiItem | AbiItem[]
|
||||
): Contract {
|
||||
const contract = new this.web3.eth.Contract(abi || this.abi, address, {
|
||||
from: account
|
||||
})
|
||||
return setContractDefaults(contract, this.config)
|
||||
}
|
||||
}
|
30
src/contracts/SmartContractWithAddress.ts
Normal file
30
src/contracts/SmartContractWithAddress.ts
Normal file
@ -0,0 +1,30 @@
|
||||
import Web3 from 'web3'
|
||||
import { Contract } from 'web3-eth-contract'
|
||||
import { AbiItem } from 'web3-utils'
|
||||
import { Config } from '../config'
|
||||
import { SmartContract } from '.'
|
||||
|
||||
export abstract class SmartContractWithAddress extends SmartContract {
|
||||
public address: string
|
||||
public contract: Contract
|
||||
|
||||
/**
|
||||
* Instantiate the smart contract.
|
||||
* @param {string} address Address of the smart contract
|
||||
* @param {Web3} web3
|
||||
* @param {string | number} network Network id or name
|
||||
* @param {Config} config Configutation of the smart contract
|
||||
* @param {AbiItem | AbiItem[]} abi ABI of the smart contract
|
||||
*/
|
||||
constructor(
|
||||
address: string,
|
||||
web3: Web3,
|
||||
network?: string | number,
|
||||
config?: Config,
|
||||
abi?: AbiItem | AbiItem[]
|
||||
) {
|
||||
super(web3, network, config, abi)
|
||||
this.address = address
|
||||
this.contract = this.getContract(this.address)
|
||||
}
|
||||
}
|
692
src/contracts/factories/NFTFactory.ts
Normal file
692
src/contracts/factories/NFTFactory.ts
Normal file
@ -0,0 +1,692 @@
|
||||
import Web3 from 'web3'
|
||||
import { TransactionReceipt } from 'web3-core'
|
||||
import { AbiItem } from 'web3-utils'
|
||||
import ERC721Factory from '@oceanprotocol/contracts/artifacts/contracts/ERC721Factory.sol/ERC721Factory.json'
|
||||
import {
|
||||
LoggerInstance,
|
||||
generateDtName,
|
||||
calculateEstimatedGas,
|
||||
ZERO_ADDRESS
|
||||
} from '../../utils'
|
||||
import {
|
||||
FreCreationParams,
|
||||
DatatokenCreateParams,
|
||||
PoolCreationParams,
|
||||
DispenserCreationParams,
|
||||
NftCreateData,
|
||||
Template,
|
||||
TokenOrder
|
||||
} from '../../@types'
|
||||
import { SmartContractWithAddress } from '..'
|
||||
|
||||
/**
|
||||
* Provides an interface for NFT Factory contract
|
||||
*/
|
||||
export class NftFactory extends SmartContractWithAddress {
|
||||
getDefaultAbi(): AbiItem | AbiItem[] {
|
||||
return ERC721Factory.abi as AbiItem[]
|
||||
}
|
||||
|
||||
/**
|
||||
* Create new NFT
|
||||
* @param {String} address
|
||||
* @param {NFTCreateData} nftData
|
||||
* @return {Promise<string>} NFT datatoken address
|
||||
*/
|
||||
public async createNFT<G extends boolean = false>(
|
||||
address: string,
|
||||
nftData: NftCreateData,
|
||||
estimateGas?: G
|
||||
): Promise<G extends false ? string : number> {
|
||||
if (!nftData.templateIndex) nftData.templateIndex = 1
|
||||
|
||||
if (!nftData.name || !nftData.symbol) {
|
||||
const { name, symbol } = generateDtName()
|
||||
nftData.name = name
|
||||
nftData.symbol = symbol
|
||||
}
|
||||
if (nftData.templateIndex > (await this.getCurrentNFTTemplateCount())) {
|
||||
throw new Error(`Template index doesnt exist`)
|
||||
}
|
||||
|
||||
if (nftData.templateIndex === 0) {
|
||||
throw new Error(`Template index cannot be ZERO`)
|
||||
}
|
||||
if ((await this.getNFTTemplate(nftData.templateIndex)).isActive === false) {
|
||||
throw new Error(`Template is not active`)
|
||||
}
|
||||
const estGas = await calculateEstimatedGas(
|
||||
address,
|
||||
this.contract.methods.deployERC721Contract,
|
||||
nftData.name,
|
||||
nftData.symbol,
|
||||
nftData.templateIndex,
|
||||
ZERO_ADDRESS,
|
||||
ZERO_ADDRESS,
|
||||
nftData.tokenURI,
|
||||
nftData.transferable,
|
||||
nftData.owner
|
||||
)
|
||||
if (estimateGas) return estGas
|
||||
|
||||
// Invoke createToken function of the contract
|
||||
const trxReceipt = await this.contract.methods
|
||||
.deployERC721Contract(
|
||||
nftData.name,
|
||||
nftData.symbol,
|
||||
nftData.templateIndex,
|
||||
ZERO_ADDRESS,
|
||||
ZERO_ADDRESS,
|
||||
nftData.tokenURI,
|
||||
nftData.transferable,
|
||||
nftData.owner
|
||||
)
|
||||
.send({
|
||||
from: address,
|
||||
gas: estGas + 1,
|
||||
gasPrice: await this.getFairGasPrice()
|
||||
})
|
||||
|
||||
let tokenAddress = null
|
||||
try {
|
||||
tokenAddress = trxReceipt.events.NFTCreated.returnValues[0]
|
||||
} catch (e) {
|
||||
LoggerInstance.error(`ERROR: Failed to create datatoken : ${e.message}`)
|
||||
}
|
||||
return tokenAddress
|
||||
}
|
||||
|
||||
/** Get Current NFT Count (NFT created)
|
||||
* @return {Promise<number>} Number of NFT created from this factory
|
||||
*/
|
||||
public async getCurrentNFTCount(): Promise<number> {
|
||||
const nftCount = await this.contract.methods.getCurrentNFTCount().call()
|
||||
return nftCount
|
||||
}
|
||||
|
||||
/** Get Current Datatoken Count
|
||||
* @return {Promise<number>} Number of DTs created from this factory
|
||||
*/
|
||||
public async getCurrentTokenCount(): Promise<number> {
|
||||
const tokenCount = await this.contract.methods.getCurrentTokenCount().call()
|
||||
return tokenCount
|
||||
}
|
||||
|
||||
/** Get Factory Owner
|
||||
* @return {Promise<string>} Factory Owner address
|
||||
*/
|
||||
public async getOwner(): Promise<string> {
|
||||
const owner = await this.contract.methods.owner().call()
|
||||
return owner
|
||||
}
|
||||
|
||||
/** Get Current NFT Template Count
|
||||
* @return {Promise<number>} Number of NFT Template added to this factory
|
||||
*/
|
||||
public async getCurrentNFTTemplateCount(): Promise<number> {
|
||||
const count = await this.contract.methods.getCurrentNFTTemplateCount().call()
|
||||
return count
|
||||
}
|
||||
|
||||
/** Get Current Template Datatoken (ERC20) Count
|
||||
* @return {Promise<number>} Number of Datatoken Template added to this factory
|
||||
*/
|
||||
public async getCurrentTokenTemplateCount(): Promise<number> {
|
||||
const count = await this.contract.methods.getCurrentTemplateCount().call()
|
||||
return count
|
||||
}
|
||||
|
||||
/** Get NFT Template
|
||||
* @param {Number} index Template index
|
||||
* @return {Promise<Template>} Number of Template added to this factory
|
||||
*/
|
||||
public async getNFTTemplate(index: number): Promise<Template> {
|
||||
if (index > (await this.getCurrentNFTTemplateCount())) {
|
||||
throw new Error(`Template index doesnt exist`)
|
||||
}
|
||||
|
||||
if (index === 0) {
|
||||
throw new Error(`Template index cannot be ZERO`)
|
||||
}
|
||||
const template = await this.contract.methods.getNFTTemplate(index).call()
|
||||
return template
|
||||
}
|
||||
|
||||
/** Get Datatoken (ERC20) Template
|
||||
* @param {Number} index Template index
|
||||
* @return {Promise<Template>} DT Template info
|
||||
*/
|
||||
public async getTokenTemplate(index: number): Promise<Template> {
|
||||
const template = await this.contract.methods.getTokenTemplate(index).call()
|
||||
return template
|
||||
}
|
||||
|
||||
/** Check if Datatoken is deployed from the factory
|
||||
* @param {String} datatoken Datatoken address we want to check
|
||||
* @return {Promise<Boolean>} return true if deployed from this factory
|
||||
*/
|
||||
public async checkDatatoken(datatoken: string): Promise<Boolean> {
|
||||
const isDeployed = await this.contract.methods.erc20List(datatoken).call()
|
||||
return isDeployed
|
||||
}
|
||||
|
||||
/** Check if NFT is deployed from the factory
|
||||
* @param {String} nftAddress nftAddress address we want to check
|
||||
* @return {Promise<String>} return address(0) if it's not, or the nftAddress if true
|
||||
*/
|
||||
public async checkNFT(nftAddress: string): Promise<String> {
|
||||
const confirmAddress = await this.contract.methods.erc721List(nftAddress).call()
|
||||
return confirmAddress
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a new NFT token template - only factory Owner
|
||||
* @param {String} address
|
||||
* @param {String} templateAddress template address to add
|
||||
* @return {Promise<TransactionReceipt>}
|
||||
*/
|
||||
public async addNFTTemplate<G extends boolean = false>(
|
||||
address: string,
|
||||
templateAddress: string,
|
||||
estimateGas?: G
|
||||
): Promise<G extends false ? TransactionReceipt : number> {
|
||||
if ((await this.getOwner()) !== address) {
|
||||
throw new Error(`Caller is not Factory Owner`)
|
||||
}
|
||||
if (templateAddress === ZERO_ADDRESS) {
|
||||
throw new Error(`Template cannot be ZERO address`)
|
||||
}
|
||||
|
||||
const estGas = await calculateEstimatedGas(
|
||||
address,
|
||||
this.contract.methods.add721TokenTemplate,
|
||||
templateAddress
|
||||
)
|
||||
if (estimateGas) return estGas
|
||||
|
||||
// Invoke add721TokenTemplate function of the contract
|
||||
const trxReceipt = await this.contract.methods
|
||||
.add721TokenTemplate(templateAddress)
|
||||
.send({
|
||||
from: address,
|
||||
gas: estGas + 1,
|
||||
gasPrice: await this.getFairGasPrice()
|
||||
})
|
||||
|
||||
return trxReceipt
|
||||
}
|
||||
|
||||
/**
|
||||
* Disable token template - only factory Owner
|
||||
* @param {String} address
|
||||
* @param {Number} templateIndex index of the template we want to disable
|
||||
* @return {Promise<TransactionReceipt>} current token template count
|
||||
*/
|
||||
public async disableNFTTemplate<G extends boolean = false>(
|
||||
address: string,
|
||||
templateIndex: number,
|
||||
estimateGas?: G
|
||||
): Promise<G extends false ? TransactionReceipt : number> {
|
||||
if ((await this.getOwner()) !== address) {
|
||||
throw new Error(`Caller is not Factory Owner`)
|
||||
}
|
||||
if (templateIndex > (await this.getCurrentNFTTemplateCount())) {
|
||||
throw new Error(`Template index doesnt exist`)
|
||||
}
|
||||
|
||||
if (templateIndex === 0) {
|
||||
throw new Error(`Template index cannot be ZERO`)
|
||||
}
|
||||
const estGas = await calculateEstimatedGas(
|
||||
address,
|
||||
this.contract.methods.disable721TokenTemplate,
|
||||
templateIndex
|
||||
)
|
||||
if (estimateGas) return estGas
|
||||
|
||||
// Invoke createToken function of the contract
|
||||
const trxReceipt = await this.contract.methods
|
||||
.disable721TokenTemplate(templateIndex)
|
||||
.send({
|
||||
from: address,
|
||||
gas: estGas + 1,
|
||||
gasPrice: await this.getFairGasPrice()
|
||||
})
|
||||
|
||||
return trxReceipt
|
||||
}
|
||||
|
||||
/**
|
||||
* Reactivate a previously disabled token template - only factory Owner
|
||||
* @param {String} address
|
||||
* @param {Number} templateIndex index of the template we want to reactivate
|
||||
* @return {Promise<TransactionReceipt>} current token template count
|
||||
*/
|
||||
public async reactivateNFTTemplate<G extends boolean = false>(
|
||||
address: string,
|
||||
templateIndex: number,
|
||||
estimateGas?: G
|
||||
): Promise<G extends false ? TransactionReceipt : number> {
|
||||
if ((await this.getOwner()) !== address) {
|
||||
throw new Error(`Caller is not Factory Owner`)
|
||||
}
|
||||
if (templateIndex > (await this.getCurrentNFTTemplateCount())) {
|
||||
throw new Error(`Template index doesnt exist`)
|
||||
}
|
||||
|
||||
if (templateIndex === 0) {
|
||||
throw new Error(`Template index cannot be ZERO`)
|
||||
}
|
||||
|
||||
const estGas = await calculateEstimatedGas(
|
||||
address,
|
||||
this.contract.methods.reactivate721TokenTemplate,
|
||||
templateIndex
|
||||
)
|
||||
if (estimateGas) return estGas
|
||||
|
||||
// Invoke createToken function of the contract
|
||||
const trxReceipt = await this.contract.methods
|
||||
.reactivate721TokenTemplate(templateIndex)
|
||||
.send({
|
||||
from: address,
|
||||
gas: estGas + 1,
|
||||
gasPrice: await this.getFairGasPrice()
|
||||
})
|
||||
|
||||
return trxReceipt
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a new NFT token template - only factory Owner
|
||||
* @param {String} address
|
||||
* @param {String} templateAddress template address to add
|
||||
* @return {Promise<TransactionReceipt>}
|
||||
*/
|
||||
public async addTokenTemplate<G extends boolean = false>(
|
||||
address: string,
|
||||
templateAddress: string,
|
||||
estimateGas?: G
|
||||
): Promise<G extends false ? TransactionReceipt : number> {
|
||||
if ((await this.getOwner()) !== address) {
|
||||
throw new Error(`Caller is not Factory Owner`)
|
||||
}
|
||||
if (templateAddress === ZERO_ADDRESS) {
|
||||
throw new Error(`Template cannot be address ZERO`)
|
||||
}
|
||||
|
||||
const estGas = await calculateEstimatedGas(
|
||||
address,
|
||||
this.contract.methods.addTokenTemplate,
|
||||
templateAddress
|
||||
)
|
||||
if (estimateGas) return estGas
|
||||
|
||||
// Invoke createToken function of the contract
|
||||
const trxReceipt = await this.contract.methods
|
||||
.addTokenTemplate(templateAddress)
|
||||
.send({
|
||||
from: address,
|
||||
gas: estGas + 1,
|
||||
gasPrice: await this.getFairGasPrice()
|
||||
})
|
||||
|
||||
return trxReceipt
|
||||
}
|
||||
|
||||
/**
|
||||
* Disable token template - only factory Owner
|
||||
* @param {String} address
|
||||
* @param {Number} templateIndex index of the template we want to disable
|
||||
* @return {Promise<TransactionReceipt>} current token template count
|
||||
*/
|
||||
public async disableTokenTemplate<G extends boolean = false>(
|
||||
address: string,
|
||||
templateIndex: number,
|
||||
estimateGas?: G
|
||||
): Promise<G extends false ? TransactionReceipt : number> {
|
||||
if ((await this.getOwner()) !== address) {
|
||||
throw new Error(`Caller is not Factory Owner`)
|
||||
}
|
||||
if (templateIndex > (await this.getCurrentTokenTemplateCount())) {
|
||||
throw new Error(`Template index doesnt exist`)
|
||||
}
|
||||
|
||||
if (templateIndex === 0) {
|
||||
throw new Error(`Template index cannot be ZERO`)
|
||||
}
|
||||
if ((await this.getTokenTemplate(templateIndex)).isActive === false) {
|
||||
throw new Error(`Template is already disabled`)
|
||||
}
|
||||
const estGas = await calculateEstimatedGas(
|
||||
address,
|
||||
this.contract.methods.disableTokenTemplate,
|
||||
templateIndex
|
||||
)
|
||||
if (estimateGas) return estGas
|
||||
|
||||
// Invoke createToken function of the contract
|
||||
const trxReceipt = await this.contract.methods
|
||||
.disableTokenTemplate(templateIndex)
|
||||
.send({
|
||||
from: address,
|
||||
gas: estGas + 1,
|
||||
gasPrice: await this.getFairGasPrice()
|
||||
})
|
||||
|
||||
return trxReceipt
|
||||
}
|
||||
|
||||
/**
|
||||
* Reactivate a previously disabled token template - only factory Owner
|
||||
* @param {String} address
|
||||
* @param {Number} templateIndex index of the template we want to reactivate
|
||||
* @return {Promise<TransactionReceipt>} current token template count
|
||||
*/
|
||||
public async reactivateTokenTemplate<G extends boolean = false>(
|
||||
address: string,
|
||||
templateIndex: number,
|
||||
estimateGas?: G
|
||||
): Promise<G extends false ? TransactionReceipt : number> {
|
||||
if ((await this.getOwner()) !== address) {
|
||||
throw new Error(`Caller is not Factory Owner`)
|
||||
}
|
||||
if (templateIndex > (await this.getCurrentTokenTemplateCount())) {
|
||||
throw new Error(`Template index doesnt exist`)
|
||||
}
|
||||
|
||||
if (templateIndex === 0) {
|
||||
throw new Error(`Template index cannot be ZERO`)
|
||||
}
|
||||
if ((await this.getTokenTemplate(templateIndex)).isActive === true) {
|
||||
throw new Error(`Template is already active`)
|
||||
}
|
||||
|
||||
const estGas = await calculateEstimatedGas(
|
||||
address,
|
||||
this.contract.methods.reactivateTokenTemplate,
|
||||
templateIndex
|
||||
)
|
||||
if (estimateGas) return estGas
|
||||
|
||||
// Invoke createToken function of the contract
|
||||
const trxReceipt = await this.contract.methods
|
||||
.reactivateTokenTemplate(templateIndex)
|
||||
.send({
|
||||
from: address,
|
||||
gas: estGas + 1,
|
||||
gasPrice: await this.getFairGasPrice()
|
||||
})
|
||||
|
||||
return trxReceipt
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev startMultipleTokenOrder
|
||||
* Used as a proxy to order multiple services
|
||||
* Users can have inifinite approvals for fees for factory instead of having one approval/ Datatoken contract
|
||||
* Requires previous approval of all :
|
||||
* - consumeFeeTokens
|
||||
* - publishMarketFeeTokens
|
||||
* - ERC20 Datatokens
|
||||
* @param address Caller address
|
||||
* @param orders an array of struct tokenOrder
|
||||
* @return {Promise<TransactionReceipt>} transaction receipt
|
||||
*/
|
||||
public async startMultipleTokenOrder<G extends boolean = false>(
|
||||
address: string,
|
||||
orders: TokenOrder[],
|
||||
estimateGas?: G
|
||||
): Promise<G extends false ? TransactionReceipt : number> {
|
||||
if (orders.length > 50) {
|
||||
throw new Error(`Too many orders`)
|
||||
}
|
||||
|
||||
const estGas = await calculateEstimatedGas(
|
||||
address,
|
||||
this.contract.methods.startMultipleTokenOrder,
|
||||
orders
|
||||
)
|
||||
if (estimateGas) return estGas
|
||||
|
||||
// Invoke createToken function of the contract
|
||||
const trxReceipt = await this.contract.methods.startMultipleTokenOrder(orders).send({
|
||||
from: address,
|
||||
gas: estGas + 1,
|
||||
gasPrice: await this.getFairGasPrice()
|
||||
})
|
||||
|
||||
return trxReceipt
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev createNftWithDatatoken
|
||||
* Creates a new NFT, then a Datatoken,all in one call
|
||||
* @param address Caller address
|
||||
* @param _NftCreateData input data for nft creation
|
||||
* @param _ErcCreateData input data for Datatoken creation
|
||||
* @return {Promise<TransactionReceipt>} transaction receipt
|
||||
*/
|
||||
|
||||
public async createNftWithDatatoken<G extends boolean = false>(
|
||||
address: string,
|
||||
nftCreateData: NftCreateData,
|
||||
dtParams: DatatokenCreateParams,
|
||||
estimateGas?: G
|
||||
): Promise<G extends false ? TransactionReceipt : number> {
|
||||
const ercCreateData = this.getErcCreationParams(dtParams)
|
||||
|
||||
const estGas = await calculateEstimatedGas(
|
||||
address,
|
||||
this.contract.methods.createNftWithErc20,
|
||||
nftCreateData,
|
||||
ercCreateData
|
||||
)
|
||||
if (estimateGas) return estGas
|
||||
|
||||
// Invoke createToken function of the contract
|
||||
const trxReceipt = await this.contract.methods
|
||||
.createNftWithErc20(nftCreateData, ercCreateData)
|
||||
.send({
|
||||
from: address,
|
||||
gas: estGas + 1,
|
||||
gasPrice: await this.getFairGasPrice()
|
||||
})
|
||||
|
||||
return trxReceipt
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev createNftWithDatatokenWithPool
|
||||
* Creates a new NFT, then a Datatoken, then a Pool, all in one call
|
||||
* Use this carefully, because if Pool creation fails, you are still going to pay a lot of gas
|
||||
* @param address Caller address
|
||||
* @param nftCreateData input data for NFT Creation
|
||||
* @param dtParams input data for Datatoken Creation
|
||||
* @param poolParams input data for Pool Creation
|
||||
* @return {Promise<TransactionReceipt>} transaction receipt
|
||||
*/
|
||||
public async createNftWithDatatokenWithPool<G extends boolean = false>(
|
||||
address: string,
|
||||
nftCreateData: NftCreateData,
|
||||
dtParams: DatatokenCreateParams,
|
||||
poolParams: PoolCreationParams,
|
||||
estimateGas?: G
|
||||
): Promise<G extends false ? TransactionReceipt : number> {
|
||||
const ercCreateData = this.getErcCreationParams(dtParams)
|
||||
const poolData = await this.getPoolCreationParams(poolParams)
|
||||
|
||||
const estGas = await calculateEstimatedGas(
|
||||
address,
|
||||
this.contract.methods.createNftWithErc20WithPool,
|
||||
nftCreateData,
|
||||
ercCreateData,
|
||||
poolData
|
||||
)
|
||||
if (estimateGas) return estGas
|
||||
|
||||
// Invoke createToken function of the contract
|
||||
const trxReceipt = await this.contract.methods
|
||||
.createNftWithErc20WithPool(nftCreateData, ercCreateData, poolData)
|
||||
.send({
|
||||
from: address,
|
||||
gas: estGas + 1,
|
||||
gasPrice: await this.getFairGasPrice()
|
||||
})
|
||||
|
||||
return trxReceipt
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev createNftWithDatatokenWithFixedRate
|
||||
* Creates a new NFT, then a Datatoken, then a FixedRateExchange, all in one call
|
||||
* Use this carefully, because if Fixed Rate creation fails, you are still going to pay a lot of gas
|
||||
* @param address Caller address
|
||||
* @param nftCreateData input data for NFT Creation
|
||||
* @param dtParams input data for Datatoken Creation
|
||||
* @param freParams input data for FixedRate Creation
|
||||
* @return {Promise<TransactionReceipt>} transaction receipt
|
||||
*/
|
||||
public async createNftWithDatatokenWithFixedRate<G extends boolean = false>(
|
||||
address: string,
|
||||
nftCreateData: NftCreateData,
|
||||
dtParams: DatatokenCreateParams,
|
||||
freParams: FreCreationParams,
|
||||
estimateGas?: G
|
||||
): Promise<G extends false ? TransactionReceipt : number> {
|
||||
const ercCreateData = this.getErcCreationParams(dtParams)
|
||||
const fixedData = this.getFreCreationParams(freParams)
|
||||
|
||||
const estGas = await calculateEstimatedGas(
|
||||
address,
|
||||
this.contract.methods.createNftWithErc20WithFixedRate,
|
||||
nftCreateData,
|
||||
ercCreateData,
|
||||
fixedData
|
||||
)
|
||||
if (estimateGas) return estGas
|
||||
|
||||
// Invoke createToken function of the contract
|
||||
const trxReceipt = await this.contract.methods
|
||||
.createNftWithErc20WithFixedRate(nftCreateData, ercCreateData, fixedData)
|
||||
.send({
|
||||
from: address,
|
||||
gas: estGas + 1,
|
||||
gasPrice: await this.getFairGasPrice()
|
||||
})
|
||||
|
||||
return trxReceipt
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev createNftWithDatatokenWithDispenser
|
||||
* Creates a new NFT, then a Datatoken, then a Dispenser, all in one call
|
||||
* Use this carefully, because if Dispenser creation fails, you are still going to pay a lot of gas
|
||||
* @param address Caller address
|
||||
* @param nftCreateData input data for NFT Creation
|
||||
* @param dtParams input data for Datatoken Creation
|
||||
* @param dispenserParams input data for Dispenser Creation
|
||||
* @return {Promise<TransactionReceipt>} transaction receipt
|
||||
*/
|
||||
public async createNftWithDatatokenWithDispenser<G extends boolean = false>(
|
||||
address: string,
|
||||
nftCreateData: NftCreateData,
|
||||
dtParams: DatatokenCreateParams,
|
||||
dispenserParams: DispenserCreationParams,
|
||||
estimateGas?: G
|
||||
): Promise<G extends false ? TransactionReceipt : number> {
|
||||
const ercCreateData = this.getErcCreationParams(dtParams)
|
||||
|
||||
dispenserParams.maxBalance = Web3.utils.toWei(dispenserParams.maxBalance)
|
||||
dispenserParams.maxTokens = Web3.utils.toWei(dispenserParams.maxTokens)
|
||||
|
||||
const estGas = await calculateEstimatedGas(
|
||||
address,
|
||||
this.contract.methods.createNftWithErc20WithDispenser,
|
||||
nftCreateData,
|
||||
ercCreateData,
|
||||
dispenserParams
|
||||
)
|
||||
if (estimateGas) return estGas
|
||||
|
||||
// Invoke createToken function of the contract
|
||||
const trxReceipt = await this.contract.methods
|
||||
.createNftWithErc20WithDispenser(nftCreateData, ercCreateData, dispenserParams)
|
||||
.send({
|
||||
from: address,
|
||||
gas: estGas + 1,
|
||||
gasPrice: await this.getFairGasPrice()
|
||||
})
|
||||
|
||||
return trxReceipt
|
||||
}
|
||||
|
||||
private getErcCreationParams(dtParams: DatatokenCreateParams): any {
|
||||
let name: string, symbol: string
|
||||
// Generate name & symbol if not present
|
||||
if (!dtParams.name || !dtParams.symbol) {
|
||||
;({ name, symbol } = generateDtName())
|
||||
}
|
||||
return {
|
||||
templateIndex: dtParams.templateIndex,
|
||||
strings: [dtParams.name || name, dtParams.symbol || symbol],
|
||||
addresses: [
|
||||
dtParams.minter,
|
||||
dtParams.paymentCollector,
|
||||
dtParams.mpFeeAddress,
|
||||
dtParams.feeToken
|
||||
],
|
||||
uints: [Web3.utils.toWei(dtParams.cap), Web3.utils.toWei(dtParams.feeAmount)],
|
||||
bytess: []
|
||||
}
|
||||
}
|
||||
|
||||
private getFreCreationParams(freParams: FreCreationParams): any {
|
||||
if (!freParams.allowedConsumer) freParams.allowedConsumer = ZERO_ADDRESS
|
||||
const withMint = freParams.withMint ? 1 : 0
|
||||
|
||||
return {
|
||||
fixedPriceAddress: freParams.fixedRateAddress,
|
||||
addresses: [
|
||||
freParams.baseTokenAddress,
|
||||
freParams.owner,
|
||||
freParams.marketFeeCollector,
|
||||
freParams.allowedConsumer
|
||||
],
|
||||
uints: [
|
||||
freParams.baseTokenDecimals,
|
||||
freParams.datatokenDecimals,
|
||||
Web3.utils.toWei(freParams.fixedRate),
|
||||
Web3.utils.toWei(freParams.marketFee),
|
||||
withMint
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
private async getPoolCreationParams(poolParams: PoolCreationParams): Promise<any> {
|
||||
return {
|
||||
addresses: [
|
||||
poolParams.ssContract,
|
||||
poolParams.baseTokenAddress,
|
||||
poolParams.baseTokenSender,
|
||||
poolParams.publisherAddress,
|
||||
poolParams.marketFeeCollector,
|
||||
poolParams.poolTemplateAddress
|
||||
],
|
||||
ssParams: [
|
||||
Web3.utils.toWei(poolParams.rate),
|
||||
poolParams.baseTokenDecimals,
|
||||
Web3.utils.toWei(poolParams.vestingAmount),
|
||||
poolParams.vestedBlocks,
|
||||
await this.amountToUnits(
|
||||
poolParams.baseTokenAddress,
|
||||
poolParams.initialBaseTokenLiquidity
|
||||
)
|
||||
],
|
||||
swapFees: [
|
||||
Web3.utils.toWei(poolParams.swapFeeLiquidityProvider),
|
||||
Web3.utils.toWei(poolParams.swapFeeMarketRunner)
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
10
src/contracts/index.ts
Normal file
10
src/contracts/index.ts
Normal file
@ -0,0 +1,10 @@
|
||||
export * from './SmartContract'
|
||||
export * from './SmartContractWithAddress'
|
||||
export * from './factories/NFTFactory'
|
||||
export * from './pools/Dispenser'
|
||||
export * from './pools/FixedRateExchange'
|
||||
export * from './pools/Pool'
|
||||
export * from './pools/Router'
|
||||
export * from './pools/SideStaking'
|
||||
export * from './tokens/Datatoken'
|
||||
export * from './tokens/NFT'
|
287
src/contracts/pools/Dispenser.ts
Normal file
287
src/contracts/pools/Dispenser.ts
Normal file
@ -0,0 +1,287 @@
|
||||
import { AbiItem } from 'web3-utils'
|
||||
import { TransactionReceipt } from 'web3-eth'
|
||||
import Decimal from 'decimal.js'
|
||||
import DispenserAbi from '@oceanprotocol/contracts/artifacts/contracts/pools/dispenser/Dispenser.sol/Dispenser.json'
|
||||
import { LoggerInstance, calculateEstimatedGas } from '../../utils/'
|
||||
import { Datatoken, SmartContractWithAddress } from '..'
|
||||
import { DispenserToken } from '../../@types'
|
||||
|
||||
export class Dispenser extends SmartContractWithAddress {
|
||||
getDefaultAbi(): AbiItem | AbiItem[] {
|
||||
return DispenserAbi.abi as AbiItem[]
|
||||
}
|
||||
|
||||
/**
|
||||
* Get information about a datatoken dispenser
|
||||
* @param {String} dtAddress
|
||||
* @return {Promise<FixedPricedExchange>} Exchange details
|
||||
*/
|
||||
public async status(dtAdress: string): Promise<DispenserToken> {
|
||||
try {
|
||||
const status: DispenserToken = await this.contract.methods.status(dtAdress).call()
|
||||
status.maxTokens = this.web3.utils.fromWei(status.maxTokens)
|
||||
status.maxBalance = this.web3.utils.fromWei(status.maxBalance)
|
||||
status.balance = this.web3.utils.fromWei(status.balance)
|
||||
return status
|
||||
} catch (e) {
|
||||
LoggerInstance.warn(`No dispenser available for datatoken: ${dtAdress}`)
|
||||
}
|
||||
return null
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new Dispenser
|
||||
* @param {String} dtAddress Datatoken address
|
||||
* @param {String} address Owner address
|
||||
* @param {String} maxTokens max tokens to dispense
|
||||
* @param {String} maxBalance max balance of requester
|
||||
* @param {String} allowedSwapper only account that can ask tokens. set address(0) if not required
|
||||
* @return {Promise<TransactionReceipt>} transactionId
|
||||
*/
|
||||
public async create<G extends boolean = false>(
|
||||
dtAddress: string,
|
||||
address: string,
|
||||
maxTokens: string,
|
||||
maxBalance: string,
|
||||
allowedSwapper: string,
|
||||
estimateGas?: G
|
||||
): Promise<G extends false ? TransactionReceipt : number> {
|
||||
const estGas = await calculateEstimatedGas(
|
||||
address,
|
||||
this.contract.methods.create,
|
||||
dtAddress,
|
||||
this.web3.utils.toWei(maxTokens),
|
||||
this.web3.utils.toWei(maxBalance),
|
||||
address,
|
||||
allowedSwapper
|
||||
)
|
||||
if (estimateGas) return estGas
|
||||
|
||||
// Call createFixedRate contract method
|
||||
const trxReceipt = await this.contract.methods
|
||||
.create(
|
||||
dtAddress,
|
||||
this.web3.utils.toWei(maxTokens),
|
||||
this.web3.utils.toWei(maxBalance),
|
||||
address,
|
||||
allowedSwapper
|
||||
)
|
||||
.send({
|
||||
from: address,
|
||||
gas: estGas + 1,
|
||||
gasPrice: await this.getFairGasPrice()
|
||||
})
|
||||
return trxReceipt
|
||||
}
|
||||
|
||||
/**
|
||||
* Activates a new dispener.
|
||||
* @param {String} dtAddress refers to datatoken address.
|
||||
* @param {Number} maxTokens max amount of tokens to dispense
|
||||
* @param {Number} maxBalance max balance of user. If user balance is >, then dispense will be rejected
|
||||
* @param {String} address User address (must be owner of the datatoken)
|
||||
* @return {Promise<TransactionReceipt>} TransactionReceipt
|
||||
*/
|
||||
public async activate<G extends boolean = false>(
|
||||
dtAddress: string,
|
||||
maxTokens: string,
|
||||
maxBalance: string,
|
||||
address: string,
|
||||
estimateGas?: G
|
||||
): Promise<G extends false ? TransactionReceipt : number> {
|
||||
try {
|
||||
const estGas = await calculateEstimatedGas(
|
||||
address,
|
||||
this.contract.methods.activate,
|
||||
dtAddress,
|
||||
this.web3.utils.toWei(maxTokens),
|
||||
this.web3.utils.toWei(maxBalance)
|
||||
)
|
||||
if (estimateGas) return estGas
|
||||
|
||||
const trxReceipt = await this.contract.methods
|
||||
.activate(
|
||||
dtAddress,
|
||||
this.web3.utils.toWei(maxTokens),
|
||||
this.web3.utils.toWei(maxBalance)
|
||||
)
|
||||
.send({
|
||||
from: address,
|
||||
gas: estGas + 1,
|
||||
gasPrice: await this.getFairGasPrice()
|
||||
})
|
||||
return trxReceipt
|
||||
} catch (e) {
|
||||
LoggerInstance.error(`ERROR: Failed to activate dispenser: ${e.message}`)
|
||||
}
|
||||
return null
|
||||
}
|
||||
|
||||
/**
|
||||
* Deactivate an existing dispenser.
|
||||
* @param {String} dtAddress refers to datatoken address.
|
||||
* @param {String} address User address (must be owner of the datatoken)
|
||||
* @return {Promise<TransactionReceipt>} TransactionReceipt
|
||||
*/
|
||||
public async deactivate<G extends boolean = false>(
|
||||
dtAddress: string,
|
||||
address: string,
|
||||
estimateGas?: G
|
||||
): Promise<G extends false ? TransactionReceipt : number> {
|
||||
try {
|
||||
const estGas = await calculateEstimatedGas(
|
||||
address,
|
||||
this.contract.methods.deactivate,
|
||||
dtAddress
|
||||
)
|
||||
if (estimateGas) return estGas
|
||||
|
||||
const trxReceipt = await this.contract.methods.deactivate(dtAddress).send({
|
||||
from: address,
|
||||
gas: estGas + 1,
|
||||
gasPrice: await this.getFairGasPrice()
|
||||
})
|
||||
return trxReceipt
|
||||
} catch (e) {
|
||||
LoggerInstance.error(`ERROR: Failed to activate dispenser: ${e.message}`)
|
||||
}
|
||||
return null
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets a new allowedSwapper.
|
||||
* @param {String} dtAddress refers to datatoken address.
|
||||
* @param {String} address User address (must be owner of the datatoken)
|
||||
* @param {String} newAllowedSwapper refers to the new allowedSwapper
|
||||
* @return {Promise<TransactionReceipt>} TransactionReceipt
|
||||
*/
|
||||
public async setAllowedSwapper<G extends boolean = false>(
|
||||
dtAddress: string,
|
||||
address: string,
|
||||
newAllowedSwapper: string,
|
||||
estimateGas?: G
|
||||
): Promise<G extends false ? TransactionReceipt : number> {
|
||||
try {
|
||||
const estGas = await calculateEstimatedGas(
|
||||
address,
|
||||
this.contract.methods.setAllowedSwapper,
|
||||
dtAddress,
|
||||
newAllowedSwapper
|
||||
)
|
||||
if (estimateGas) return estGas
|
||||
|
||||
const trxReceipt = await this.contract.methods
|
||||
.setAllowedSwapper(dtAddress, newAllowedSwapper)
|
||||
.send({
|
||||
from: address,
|
||||
gas: estGas + 1,
|
||||
gasPrice: await this.getFairGasPrice()
|
||||
})
|
||||
return trxReceipt
|
||||
} catch (e) {
|
||||
LoggerInstance.error(`ERROR: Failed to activate dispenser: ${e.message}`)
|
||||
}
|
||||
return null
|
||||
}
|
||||
|
||||
/**
|
||||
* Dispense datatokens to caller.
|
||||
* The dispenser must be active, hold enough DT (or be able to mint more)
|
||||
* and respect maxTokens/maxBalance requirements
|
||||
* @param {String} dtAddress refers to datatoken address.
|
||||
* @param {String} address User address
|
||||
* @param {String} amount amount of datatokens required.
|
||||
* @param {String} destination who will receive the tokens
|
||||
* @return {Promise<TransactionReceipt>} TransactionReceipt
|
||||
*/
|
||||
public async dispense<G extends boolean = false>(
|
||||
dtAddress: string,
|
||||
address: string,
|
||||
amount: string = '1',
|
||||
destination: string,
|
||||
estimateGas?: G
|
||||
): Promise<G extends false ? TransactionReceipt : number> {
|
||||
const estGas = await calculateEstimatedGas(
|
||||
address,
|
||||
this.contract.methods.dispense,
|
||||
dtAddress,
|
||||
this.web3.utils.toWei(amount),
|
||||
destination
|
||||
)
|
||||
if (estimateGas) return estGas
|
||||
|
||||
try {
|
||||
const trxReceipt = await this.contract.methods
|
||||
.dispense(dtAddress, this.web3.utils.toWei(amount), destination)
|
||||
.send({
|
||||
from: address,
|
||||
gas: estGas + 1,
|
||||
gasPrice: await this.getFairGasPrice()
|
||||
})
|
||||
return trxReceipt
|
||||
} catch (e) {
|
||||
LoggerInstance.error(`ERROR: Failed to dispense tokens: ${e.message}`)
|
||||
}
|
||||
return null
|
||||
}
|
||||
|
||||
/**
|
||||
* Withdraw all tokens from the dispenser
|
||||
* @param {String} dtAddress refers to datatoken address.
|
||||
* @param {String} address User address (must be owner of the dispenser)
|
||||
* @return {Promise<TransactionReceipt>} TransactionReceipt
|
||||
*/
|
||||
public async ownerWithdraw<G extends boolean = false>(
|
||||
dtAddress: string,
|
||||
address: string,
|
||||
estimateGas?: G
|
||||
): Promise<G extends false ? TransactionReceipt : number> {
|
||||
const estGas = await calculateEstimatedGas(
|
||||
address,
|
||||
this.contract.methods.ownerWithdraw,
|
||||
dtAddress
|
||||
)
|
||||
if (estimateGas) return estGas
|
||||
|
||||
try {
|
||||
const trxReceipt = await this.contract.methods.ownerWithdraw(dtAddress).send({
|
||||
from: address,
|
||||
gas: estGas + 1,
|
||||
gasPrice: await this.getFairGasPrice()
|
||||
})
|
||||
return trxReceipt
|
||||
} catch (e) {
|
||||
LoggerInstance.error(`ERROR: Failed to withdraw tokens: ${e.message}`)
|
||||
}
|
||||
return null
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if tokens can be dispensed
|
||||
* @param {String} dtAddress
|
||||
* @param {String} address User address that will receive datatokens
|
||||
* @param {String} amount amount of datatokens required.
|
||||
* @return {Promise<Boolean>}
|
||||
*/
|
||||
public async isDispensable(
|
||||
dtAddress: string,
|
||||
datatoken: Datatoken,
|
||||
address: string,
|
||||
amount: string = '1'
|
||||
): Promise<Boolean> {
|
||||
const status = await this.status(dtAddress)
|
||||
if (!status) return false
|
||||
// check active
|
||||
if (status.active === false) return false
|
||||
// check maxBalance
|
||||
const userBalance = new Decimal(await datatoken.balance(dtAddress, address))
|
||||
if (userBalance.greaterThanOrEqualTo(status.maxBalance)) return false
|
||||
// check maxAmount
|
||||
if (new Decimal(String(amount)).greaterThan(status.maxTokens)) return false
|
||||
// check dispenser balance
|
||||
const contractBalance = new Decimal(status.balance)
|
||||
if (contractBalance.greaterThanOrEqualTo(amount) || status.isMinter === true)
|
||||
return true
|
||||
return false
|
||||
}
|
||||
}
|
798
src/contracts/pools/FixedRateExchange.ts
Normal file
798
src/contracts/pools/FixedRateExchange.ts
Normal file
@ -0,0 +1,798 @@
|
||||
import FixedRateExchangeAbi from '@oceanprotocol/contracts/artifacts/contracts/pools/fixedRate/FixedRateExchange.sol/FixedRateExchange.json'
|
||||
import { TransactionReceipt } from 'web3-core'
|
||||
import { AbiItem } from 'web3-utils/types'
|
||||
import { LoggerInstance, calculateEstimatedGas, ZERO_ADDRESS } from '../../utils'
|
||||
import { PriceAndFees, FeesInfo, FixedPriceExchange } from '../../@types'
|
||||
import { SmartContractWithAddress } from '..'
|
||||
|
||||
export class FixedRateExchange extends SmartContractWithAddress {
|
||||
getDefaultAbi(): AbiItem | AbiItem[] {
|
||||
return FixedRateExchangeAbi.abi as AbiItem[]
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates unique exchange identifier.
|
||||
* @param {String} baseToken baseToken contract address
|
||||
* @param {String} datatoken Datatoken contract address
|
||||
* @return {Promise<string>} exchangeId
|
||||
*/
|
||||
public async generateExchangeId(baseToken: string, datatoken: string): Promise<string> {
|
||||
const exchangeId = await this.contract.methods
|
||||
.generateExchangeId(baseToken, datatoken)
|
||||
.call()
|
||||
return exchangeId
|
||||
}
|
||||
|
||||
/**
|
||||
* Atomic swap
|
||||
* @param {String} exchangeId ExchangeId
|
||||
* @param {String} datatokenAmount Amount of datatokens
|
||||
* @param {String} maxBaseTokenAmount max amount of baseToken we want to pay for datatokenAmount
|
||||
* @param {String} address User address
|
||||
* @param {String} consumeMarketAddress consumeMarketAddress
|
||||
* @param {String} consumeMarketFee consumeMarketFee in fraction
|
||||
* @return {Promise<TransactionReceipt>} transaction receipt
|
||||
*/
|
||||
public async buyDatatokens<G extends boolean = false>(
|
||||
address: string,
|
||||
exchangeId: string,
|
||||
datatokenAmount: string,
|
||||
maxBaseTokenAmount: string,
|
||||
consumeMarketAddress: string = ZERO_ADDRESS,
|
||||
consumeMarketFee: string = '0',
|
||||
estimateGas?: G
|
||||
): Promise<G extends false ? TransactionReceipt : number> {
|
||||
const exchange = await this.getExchange(exchangeId)
|
||||
const consumeMarketFeeFormatted = this.web3.utils.toWei(consumeMarketFee)
|
||||
const dtAmountFormatted = await this.amountToUnits(
|
||||
exchange.datatoken,
|
||||
datatokenAmount,
|
||||
+exchange.dtDecimals
|
||||
)
|
||||
const maxBtFormatted = await this.amountToUnits(
|
||||
exchange.baseToken,
|
||||
maxBaseTokenAmount,
|
||||
+exchange.btDecimals
|
||||
)
|
||||
|
||||
const estGas = await calculateEstimatedGas(
|
||||
address,
|
||||
this.contract.methods.buyDT,
|
||||
exchangeId,
|
||||
dtAmountFormatted,
|
||||
maxBtFormatted,
|
||||
consumeMarketAddress,
|
||||
consumeMarketFeeFormatted
|
||||
)
|
||||
if (estimateGas) return estGas
|
||||
|
||||
try {
|
||||
const trxReceipt = await this.contract.methods
|
||||
.buyDT(
|
||||
exchangeId,
|
||||
dtAmountFormatted,
|
||||
maxBtFormatted,
|
||||
consumeMarketAddress,
|
||||
consumeMarketFeeFormatted
|
||||
)
|
||||
.send({
|
||||
from: address,
|
||||
gas: estGas + 1,
|
||||
gasPrice: await this.getFairGasPrice()
|
||||
})
|
||||
return trxReceipt
|
||||
} catch (e) {
|
||||
LoggerInstance.error(`ERROR: Failed to buy datatokens: ${e.message}`)
|
||||
return null
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Atomic swap
|
||||
* @param {String} exchangeId ExchangeId
|
||||
* @param {String} datatokenAmount Amount of datatokens
|
||||
* @param {String} minBaseTokenAmount min amount of baseToken we want to receive back
|
||||
* @param {String} address User address
|
||||
* @param {String} consumeMarketAddress consumeMarketAddress
|
||||
* @param {String} consumeMarketFee consumeMarketFee in fraction
|
||||
* @return {Promise<TransactionReceipt>} transaction receipt
|
||||
*/
|
||||
public async sellDatatokens<G extends boolean = false>(
|
||||
address: string,
|
||||
exchangeId: string,
|
||||
datatokenAmount: string,
|
||||
minBaseTokenAmount: string,
|
||||
consumeMarketAddress: string = ZERO_ADDRESS,
|
||||
consumeMarketFee: string = '0',
|
||||
estimateGas?: G
|
||||
): Promise<G extends false ? TransactionReceipt : number> {
|
||||
const exchange = await this.getExchange(exchangeId)
|
||||
const consumeMarketFeeFormatted = this.web3.utils.toWei(consumeMarketFee)
|
||||
const dtAmountFormatted = await this.amountToUnits(
|
||||
exchange.datatoken,
|
||||
datatokenAmount,
|
||||
+exchange.dtDecimals
|
||||
)
|
||||
const minBtFormatted = await this.amountToUnits(
|
||||
exchange.baseToken,
|
||||
minBaseTokenAmount,
|
||||
+exchange.btDecimals
|
||||
)
|
||||
const estGas = await calculateEstimatedGas(
|
||||
address,
|
||||
this.contract.methods.sellDT,
|
||||
exchangeId,
|
||||
dtAmountFormatted,
|
||||
minBtFormatted,
|
||||
consumeMarketAddress,
|
||||
consumeMarketFeeFormatted
|
||||
)
|
||||
if (estimateGas) return estGas
|
||||
|
||||
try {
|
||||
const trxReceipt = await this.contract.methods
|
||||
.sellDT(
|
||||
exchangeId,
|
||||
dtAmountFormatted,
|
||||
minBtFormatted,
|
||||
consumeMarketAddress,
|
||||
consumeMarketFeeFormatted
|
||||
)
|
||||
.send({
|
||||
from: address,
|
||||
gas: estGas + 1,
|
||||
gasPrice: await this.getFairGasPrice()
|
||||
})
|
||||
return trxReceipt
|
||||
} catch (e) {
|
||||
LoggerInstance.error(`ERROR: Failed to sell datatokens: ${e.message}`)
|
||||
return null
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets total number of exchanges
|
||||
* @param {String} exchangeId ExchangeId
|
||||
* @param {Number} datatokenAmount Amount of datatokens
|
||||
* @return {Promise<Number>} no of available exchanges
|
||||
*/
|
||||
public async getNumberOfExchanges(): Promise<number> {
|
||||
const numExchanges = await this.contract.methods.getNumberOfExchanges().call()
|
||||
return numExchanges
|
||||
}
|
||||
|
||||
/**
|
||||
* Set new rate
|
||||
* @param {String} exchangeId ExchangeId
|
||||
* @param {String} newRate New rate
|
||||
* @param {String} address User account
|
||||
* @return {Promise<TransactionReceipt>} transaction receipt
|
||||
*/
|
||||
public async setRate<G extends boolean = false>(
|
||||
address: string,
|
||||
exchangeId: string,
|
||||
newRate: string,
|
||||
estimateGas?: G
|
||||
): Promise<G extends false ? TransactionReceipt : number> {
|
||||
const estGas = await calculateEstimatedGas(
|
||||
address,
|
||||
this.contract.methods.setRate,
|
||||
exchangeId,
|
||||
this.web3.utils.toWei(newRate)
|
||||
)
|
||||
if (estimateGas) return estGas
|
||||
|
||||
const trxReceipt = await this.contract.methods
|
||||
.setRate(exchangeId, this.web3.utils.toWei(newRate))
|
||||
.send({
|
||||
from: address,
|
||||
gas: estGas + 1,
|
||||
gasPrice: await this.getFairGasPrice()
|
||||
})
|
||||
return trxReceipt
|
||||
}
|
||||
|
||||
/**
|
||||
* Set new rate
|
||||
* @param {String} exchangeId ExchangeId
|
||||
* @param {String} newAllowedSwapper newAllowedSwapper (set address zero if we want to remove allowed swapper)
|
||||
* @param {String} address User account
|
||||
* @return {Promise<TransactionReceipt>} transaction receipt
|
||||
*/
|
||||
public async setAllowedSwapper<G extends boolean = false>(
|
||||
address: string,
|
||||
exchangeId: string,
|
||||
newAllowedSwapper: string,
|
||||
estimateGas?: G
|
||||
): Promise<G extends false ? TransactionReceipt : number> {
|
||||
const estGas = await calculateEstimatedGas(
|
||||
address,
|
||||
this.contract.methods.setAllowedSwapper,
|
||||
exchangeId,
|
||||
newAllowedSwapper
|
||||
)
|
||||
if (estimateGas) return estGas
|
||||
|
||||
const trxReceipt = await this.contract.methods
|
||||
.setAllowedSwapper(exchangeId, newAllowedSwapper)
|
||||
.send({
|
||||
from: address,
|
||||
gas: estGas + 1,
|
||||
gasPrice: await this.getFairGasPrice()
|
||||
})
|
||||
return trxReceipt
|
||||
}
|
||||
|
||||
/**
|
||||
* Activate an exchange
|
||||
* @param {String} exchangeId ExchangeId
|
||||
* @param {String} address User address
|
||||
* @return {Promise<TransactionReceipt>} transaction receipt
|
||||
*/
|
||||
public async activate<G extends boolean = false>(
|
||||
address: string,
|
||||
exchangeId: string,
|
||||
estimateGas?: G
|
||||
): Promise<G extends false ? TransactionReceipt : number> {
|
||||
const exchange = await this.getExchange(exchangeId)
|
||||
if (!exchange) return null
|
||||
if (exchange.active === true) return null
|
||||
const estGas = await calculateEstimatedGas(
|
||||
address,
|
||||
this.contract.methods.toggleExchangeState,
|
||||
exchangeId
|
||||
)
|
||||
if (estimateGas) return estGas
|
||||
|
||||
const trxReceipt = await this.contract.methods.toggleExchangeState(exchangeId).send({
|
||||
from: address,
|
||||
gas: estGas + 1,
|
||||
gasPrice: await this.getFairGasPrice()
|
||||
})
|
||||
return trxReceipt
|
||||
}
|
||||
|
||||
/**
|
||||
* Deactivate an exchange
|
||||
* @param {String} exchangeId ExchangeId
|
||||
* @param {String} address User address
|
||||
* @return {Promise<TransactionReceipt>} transaction receipt
|
||||
*/
|
||||
public async deactivate<G extends boolean = false>(
|
||||
address: string,
|
||||
exchangeId: string,
|
||||
estimateGas?: G
|
||||
): Promise<G extends false ? TransactionReceipt : number> {
|
||||
const exchange = await this.getExchange(exchangeId)
|
||||
if (!exchange) return null
|
||||
if (exchange.active === false) return null
|
||||
|
||||
const estGas = await calculateEstimatedGas(
|
||||
address,
|
||||
this.contract.methods.toggleExchangeState,
|
||||
exchangeId
|
||||
)
|
||||
if (estimateGas) return estGas
|
||||
|
||||
const trxReceipt = await this.contract.methods.toggleExchangeState(exchangeId).send({
|
||||
from: address,
|
||||
gas: estGas + 1,
|
||||
gasPrice: await this.getFairGasPrice()
|
||||
})
|
||||
|
||||
return trxReceipt
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Rate
|
||||
* @param {String} exchangeId ExchangeId
|
||||
* @return {Promise<string>} Rate (converted from wei)
|
||||
*/
|
||||
public async getRate(exchangeId: string): Promise<string> {
|
||||
const weiRate = await this.contract.methods.getRate(exchangeId).call()
|
||||
const rate = await this.web3.utils.fromWei(weiRate)
|
||||
return rate
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Datatoken Supply in the exchange
|
||||
* @param {String} exchangeId ExchangeId
|
||||
* @return {Promise<string>} dt supply formatted
|
||||
*/
|
||||
public async getDatatokenSupply(exchangeId: string): Promise<string> {
|
||||
const dtSupply = await this.contract.methods.getDTSupply(exchangeId).call()
|
||||
const exchange = await this.getExchange(exchangeId)
|
||||
return await this.unitsToAmount(exchange.datatoken, dtSupply, +exchange.dtDecimals)
|
||||
}
|
||||
|
||||
/**
|
||||
* Get BaseToken Supply in the exchange
|
||||
* @param {String} exchangeId ExchangeId
|
||||
* @return {Promise<string>} dt supply formatted
|
||||
*/
|
||||
public async getBasetokenSupply(exchangeId: string): Promise<string> {
|
||||
const btSupply = await this.contract.methods.getBTSupply(exchangeId).call()
|
||||
const exchange = await this.getExchange(exchangeId)
|
||||
return await this.unitsToAmount(exchange.baseToken, btSupply, +exchange.btDecimals)
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Allower Swapper (if set this is the only account which can use this exchange, else is set at address(0))
|
||||
* @param {String} exchangeId ExchangeId
|
||||
* @return {Promise<string>} address of allowedSwapper
|
||||
*/
|
||||
public async getAllowedSwapper(exchangeId: string): Promise<string> {
|
||||
return await this.contract.methods.getAllowedSwapper(exchangeId).call()
|
||||
}
|
||||
|
||||
/**
|
||||
* calcBaseInGivenDatatokensOut - Calculates how many base tokens are needed to get specified amount of datatokens
|
||||
* @param {String} exchangeId ExchangeId
|
||||
* @param {string} datatokenAmount Amount of datatokens user wants to buy
|
||||
* @param {String} consumeMarketFee consumeMarketFee in fraction
|
||||
* @return {Promise<PriceAndFees>} how many base tokens are needed and fees
|
||||
*/
|
||||
public async calcBaseInGivenDatatokensOut(
|
||||
exchangeId: string,
|
||||
datatokenAmount: string,
|
||||
consumeMarketFee: string = '0'
|
||||
): Promise<PriceAndFees> {
|
||||
const fixedRateExchange = await this.getExchange(exchangeId)
|
||||
const outDT = await this.contract.methods
|
||||
.calcBaseInGivenOutDT(
|
||||
exchangeId,
|
||||
await this.amountToUnits(
|
||||
fixedRateExchange.datatoken,
|
||||
datatokenAmount,
|
||||
+fixedRateExchange.dtDecimals
|
||||
),
|
||||
this.web3.utils.toWei(consumeMarketFee)
|
||||
)
|
||||
.call()
|
||||
|
||||
const priceAndFees = {
|
||||
baseTokenAmount: await this.unitsToAmount(
|
||||
fixedRateExchange.baseToken,
|
||||
outDT.baseTokenAmount,
|
||||
+fixedRateExchange.btDecimals
|
||||
),
|
||||
marketFeeAmount: await this.unitsToAmount(
|
||||
fixedRateExchange.baseToken,
|
||||
outDT.marketFeeAmount,
|
||||
+fixedRateExchange.btDecimals
|
||||
),
|
||||
oceanFeeAmount: await this.unitsToAmount(
|
||||
fixedRateExchange.baseToken,
|
||||
outDT.oceanFeeAmount,
|
||||
+fixedRateExchange.btDecimals
|
||||
),
|
||||
consumeMarketFeeAmount: await this.unitsToAmount(
|
||||
fixedRateExchange.baseToken,
|
||||
outDT.consumeMarketFeeAmount,
|
||||
+fixedRateExchange.btDecimals
|
||||
)
|
||||
} as PriceAndFees
|
||||
return priceAndFees
|
||||
}
|
||||
|
||||
/**
|
||||
* getBTOut - returns amount in baseToken that user will receive for datatokenAmount sold
|
||||
* @param {String} exchangeId ExchangeId
|
||||
* @param {Number} datatokenAmount Amount of datatokens
|
||||
* @param {String} consumeMarketFee consumeMarketFee in fraction
|
||||
* @return {Promise<string>} Amount of baseTokens user will receive
|
||||
*/
|
||||
public async getAmountBasetokensOut(
|
||||
exchangeId: string,
|
||||
datatokenAmount: string,
|
||||
consumeMarketFee: string = '0'
|
||||
): Promise<string> {
|
||||
const exchange = await this.getExchange(exchangeId)
|
||||
const amount = await this.contract.methods
|
||||
.calcBaseOutGivenInDT(
|
||||
exchangeId,
|
||||
await this.amountToUnits(
|
||||
exchange.datatoken,
|
||||
datatokenAmount,
|
||||
+exchange.dtDecimals
|
||||
),
|
||||
this.web3.utils.toWei(consumeMarketFee)
|
||||
)
|
||||
.call()
|
||||
|
||||
return await this.unitsToAmount(exchange.baseToken, amount[0], +exchange.btDecimals)
|
||||
}
|
||||
|
||||
/**
|
||||
* Get exchange details
|
||||
* @param {String} exchangeId ExchangeId
|
||||
* @return {Promise<FixedPricedExchange>} Exchange details
|
||||
*/
|
||||
public async getExchange(exchangeId: string): Promise<FixedPriceExchange> {
|
||||
const exchange: FixedPriceExchange = await this.contract.methods
|
||||
.getExchange(exchangeId)
|
||||
.call()
|
||||
exchange.dtDecimals = exchange.dtDecimals.toString()
|
||||
exchange.btDecimals = exchange.btDecimals.toString()
|
||||
exchange.dtBalance = await this.unitsToAmount(
|
||||
exchange.datatoken,
|
||||
exchange.dtBalance,
|
||||
+exchange.dtDecimals
|
||||
)
|
||||
exchange.btBalance = await this.unitsToAmount(
|
||||
exchange.baseToken,
|
||||
exchange.btBalance,
|
||||
+exchange.btDecimals
|
||||
)
|
||||
exchange.dtSupply = await this.unitsToAmount(
|
||||
exchange.datatoken,
|
||||
exchange.dtSupply,
|
||||
+exchange.dtDecimals
|
||||
)
|
||||
exchange.btSupply = await this.unitsToAmount(
|
||||
exchange.baseToken,
|
||||
exchange.btSupply,
|
||||
+exchange.btDecimals
|
||||
)
|
||||
exchange.fixedRate = this.web3.utils.fromWei(exchange.fixedRate)
|
||||
exchange.exchangeId = exchangeId
|
||||
return exchange
|
||||
}
|
||||
|
||||
/**
|
||||
* Get fee details for an exchange
|
||||
* @param {String} exchangeId ExchangeId
|
||||
* @return {Promise<FixedPricedExchange>} Exchange details
|
||||
*/
|
||||
public async getFeesInfo(exchangeId: string): Promise<FeesInfo> {
|
||||
const feesInfo: FeesInfo = await this.contract.methods.getFeesInfo(exchangeId).call()
|
||||
feesInfo.opcFee = this.web3.utils.fromWei(feesInfo.opcFee.toString())
|
||||
feesInfo.marketFee = this.web3.utils.fromWei(feesInfo.marketFee.toString())
|
||||
|
||||
const exchange = await this.getExchange(exchangeId)
|
||||
feesInfo.marketFeeAvailable = await this.unitsToAmount(
|
||||
exchange.baseToken,
|
||||
feesInfo.marketFeeAvailable,
|
||||
+exchange.btDecimals
|
||||
)
|
||||
feesInfo.oceanFeeAvailable = await this.unitsToAmount(
|
||||
exchange.baseToken,
|
||||
feesInfo.oceanFeeAvailable,
|
||||
+exchange.btDecimals
|
||||
)
|
||||
|
||||
feesInfo.exchangeId = exchangeId
|
||||
return feesInfo
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all exchanges
|
||||
* @param {String} exchangeId ExchangeId
|
||||
* @return {Promise<String[]>} Exchanges list
|
||||
*/
|
||||
public async getExchanges(): Promise<string[]> {
|
||||
return await this.contract.methods.getExchanges().call()
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if an exchange is active
|
||||
* @param {String} exchangeId ExchangeId
|
||||
* @return {Promise<Boolean>} Result
|
||||
*/
|
||||
public async isActive(exchangeId: string): Promise<boolean> {
|
||||
const active = await this.contract.methods.isActive(exchangeId).call()
|
||||
return active
|
||||
}
|
||||
|
||||
/**
|
||||
* Activate minting option for fixed rate contract
|
||||
* @param {String} exchangeId ExchangeId
|
||||
* @param {String} address User address
|
||||
* @return {Promise<TransactionReceipt>} transaction receipt
|
||||
*/
|
||||
public async activateMint<G extends boolean = false>(
|
||||
address: string,
|
||||
exchangeId: string,
|
||||
estimateGas?: G
|
||||
): Promise<G extends false ? TransactionReceipt : number> {
|
||||
const exchange = await this.getExchange(exchangeId)
|
||||
if (!exchange) return null
|
||||
if (exchange.withMint === true) return null
|
||||
|
||||
const estGas = await calculateEstimatedGas(
|
||||
address,
|
||||
this.contract.methods.toggleMintState,
|
||||
exchangeId,
|
||||
true
|
||||
)
|
||||
if (estimateGas) return estGas
|
||||
|
||||
const trxReceipt = await this.contract.methods
|
||||
.toggleMintState(exchangeId, true)
|
||||
.send({
|
||||
from: address,
|
||||
gas: estGas + 1,
|
||||
gasPrice: await this.getFairGasPrice()
|
||||
})
|
||||
return trxReceipt
|
||||
}
|
||||
|
||||
/**
|
||||
* Deactivate minting for fixed rate
|
||||
* @param {String} exchangeId ExchangeId
|
||||
* @param {String} address User address
|
||||
* @return {Promise<TransactionReceipt>} transaction receipt
|
||||
*/
|
||||
public async deactivateMint<G extends boolean = false>(
|
||||
address: string,
|
||||
exchangeId: string,
|
||||
estimateGas?: G
|
||||
): Promise<G extends false ? TransactionReceipt : number> {
|
||||
const exchange = await this.getExchange(exchangeId)
|
||||
if (!exchange) return null
|
||||
if (exchange.withMint === false) return null
|
||||
|
||||
const estGas = await calculateEstimatedGas(
|
||||
address,
|
||||
this.contract.methods.toggleMintState,
|
||||
exchangeId,
|
||||
false
|
||||
)
|
||||
if (estimateGas) return estGas
|
||||
|
||||
const trxReceipt = await this.contract.methods
|
||||
.toggleMintState(exchangeId, false)
|
||||
.send({
|
||||
from: address,
|
||||
gas: estGas + 1,
|
||||
gasPrice: await this.getFairGasPrice()
|
||||
})
|
||||
|
||||
return trxReceipt
|
||||
}
|
||||
|
||||
/**
|
||||
* Collect BaseTokens in the contract (anyone can call this, funds are sent to Datatoken.paymentCollector)
|
||||
* @param {String} address User address
|
||||
* @param {String} exchangeId ExchangeId
|
||||
* @param {String} amount amount to be collected
|
||||
* @return {Promise<TransactionReceipt>} transaction receipt
|
||||
*/
|
||||
public async collectBasetokens<G extends boolean = false>(
|
||||
address: string,
|
||||
exchangeId: string,
|
||||
amount: string,
|
||||
estimateGas?: G
|
||||
): Promise<G extends false ? TransactionReceipt : number> {
|
||||
const exchange = await this.getExchange(exchangeId)
|
||||
if (!exchange) return null
|
||||
|
||||
const fixedrate: FixedPriceExchange = await this.contract.methods
|
||||
.getExchange(exchangeId)
|
||||
.call()
|
||||
const amountWei = await this.amountToUnits(
|
||||
fixedrate.baseToken,
|
||||
amount,
|
||||
+fixedrate.btDecimals
|
||||
)
|
||||
|
||||
const estGas = await calculateEstimatedGas(
|
||||
address,
|
||||
this.contract.methods.collectBT,
|
||||
exchangeId,
|
||||
amountWei
|
||||
)
|
||||
if (estimateGas) return estGas
|
||||
|
||||
const trxReceipt = await this.contract.methods.collectBT(exchangeId, amountWei).send({
|
||||
from: address,
|
||||
gas: estGas + 1,
|
||||
gasPrice: await this.getFairGasPrice()
|
||||
})
|
||||
return trxReceipt
|
||||
}
|
||||
|
||||
/**
|
||||
* Collect datatokens in the contract (anyone can call this, funds are sent to Datatoken.paymentCollector)
|
||||
* @param {String} address User address
|
||||
* @param {String} exchangeId ExchangeId
|
||||
* @param {String} amount amount to be collected
|
||||
* @return {Promise<TransactionReceipt>} transaction receipt
|
||||
*/
|
||||
public async collectDatatokens<G extends boolean = false>(
|
||||
address: string,
|
||||
exchangeId: string,
|
||||
amount: string,
|
||||
estimateGas?: G
|
||||
): Promise<G extends false ? TransactionReceipt : number> {
|
||||
const exchange = await this.getExchange(exchangeId)
|
||||
if (!exchange) return null
|
||||
|
||||
const fixedrate: FixedPriceExchange = await this.contract.methods
|
||||
.getExchange(exchangeId)
|
||||
.call()
|
||||
const amountWei = await this.amountToUnits(
|
||||
fixedrate.datatoken,
|
||||
amount,
|
||||
+fixedrate.dtDecimals
|
||||
)
|
||||
|
||||
const estGas = await calculateEstimatedGas(
|
||||
address,
|
||||
this.contract.methods.collectDT,
|
||||
exchangeId,
|
||||
amountWei
|
||||
)
|
||||
if (estimateGas) return estGas
|
||||
|
||||
const trxReceipt = await this.contract.methods.collectDT(exchangeId, amountWei).send({
|
||||
from: address,
|
||||
gas: estGas + 1,
|
||||
gasPrice: await this.getFairGasPrice()
|
||||
})
|
||||
return trxReceipt
|
||||
}
|
||||
|
||||
/**
|
||||
* Collect market fee and send it to marketFeeCollector (anyone can call it)
|
||||
* @param {String} exchangeId ExchangeId
|
||||
* @param {String} address User address
|
||||
* @return {Promise<TransactionReceipt>} transaction receipt
|
||||
*/
|
||||
public async collectMarketFee<G extends boolean = false>(
|
||||
address: string,
|
||||
exchangeId: string,
|
||||
estimateGas?: G
|
||||
): Promise<G extends false ? TransactionReceipt : number> {
|
||||
const exchange = await this.getExchange(exchangeId)
|
||||
if (!exchange) return null
|
||||
|
||||
const estGas = await calculateEstimatedGas(
|
||||
address,
|
||||
this.contract.methods.collectMarketFee,
|
||||
exchangeId
|
||||
)
|
||||
if (estimateGas) return estGas
|
||||
|
||||
const trxReceipt = await this.contract.methods.collectMarketFee(exchangeId).send({
|
||||
from: address,
|
||||
gas: estGas + 1,
|
||||
gasPrice: await this.getFairGasPrice()
|
||||
})
|
||||
return trxReceipt
|
||||
}
|
||||
|
||||
/**
|
||||
* Collect ocean fee and send it to OPF collector (anyone can call it)
|
||||
* @param {String} exchangeId ExchangeId
|
||||
* @param {String} address User address
|
||||
* @return {Promise<TransactionReceipt>} transaction receipt
|
||||
*/
|
||||
public async collectOceanFee<G extends boolean = false>(
|
||||
address: string,
|
||||
exchangeId: string,
|
||||
estimateGas?: G
|
||||
): Promise<G extends false ? TransactionReceipt : number> {
|
||||
const exchange = await this.getExchange(exchangeId)
|
||||
if (!exchange) return null
|
||||
|
||||
const estGas = await calculateEstimatedGas(
|
||||
address,
|
||||
this.contract.methods.collectOceanFee,
|
||||
exchangeId
|
||||
)
|
||||
if (estimateGas) return estGas
|
||||
|
||||
const trxReceipt = await this.contract.methods.collectOceanFee(exchangeId).send({
|
||||
from: address,
|
||||
gas: estGas + 1,
|
||||
gasPrice: await this.getFairGasPrice()
|
||||
})
|
||||
return trxReceipt
|
||||
}
|
||||
|
||||
/**
|
||||
* Get OPF Collector of fixed rate contract
|
||||
* @return {String}
|
||||
*/
|
||||
async getOPCCollector(): Promise<string> {
|
||||
let address = null
|
||||
try {
|
||||
address = await this.contract.methods.opcCollector().call()
|
||||
} catch (e) {
|
||||
LoggerInstance.error(`ERROR: Failed to get OPC Collector address: ${e.message}`)
|
||||
}
|
||||
return address
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Router address set in fixed rate contract
|
||||
* @return {String}
|
||||
*/
|
||||
public async getRouter(): Promise<string> {
|
||||
let address = null
|
||||
try {
|
||||
address = await this.contract.methods.router().call()
|
||||
} catch (e) {
|
||||
LoggerInstance.error(`ERROR: Failed to get Router address: ${e.message}`)
|
||||
}
|
||||
return address
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Exchange Owner given an exchangeId
|
||||
* @param {String} exchangeId ExchangeId
|
||||
* @return {String} return exchange owner
|
||||
*/
|
||||
async getExchangeOwner(exchangeId: string): Promise<string> {
|
||||
let address = null
|
||||
try {
|
||||
address = await (await this.getExchange(exchangeId)).exchangeOwner
|
||||
} catch (e) {
|
||||
LoggerInstance.error(`ERROR: Failed to get OPF Collector address: ${e.message}`)
|
||||
}
|
||||
return address
|
||||
}
|
||||
|
||||
/**
|
||||
* Set new market fee, only market fee collector can update it
|
||||
* @param {String} address user address
|
||||
* @param {String} exchangeId ExchangeId
|
||||
* @param {String} newMarketFee New market fee
|
||||
* @return {Promise<TransactionReceipt>} transaction receipt
|
||||
*/
|
||||
public async updateMarketFee<G extends boolean = false>(
|
||||
address: string,
|
||||
exchangeId: string,
|
||||
newMarketFee: string,
|
||||
estimateGas?: G
|
||||
): Promise<G extends false ? TransactionReceipt : number> {
|
||||
const estGas = await calculateEstimatedGas(
|
||||
address,
|
||||
this.contract.methods.updateMarketFee,
|
||||
exchangeId,
|
||||
this.web3.utils.toWei(newMarketFee)
|
||||
)
|
||||
if (estimateGas) return estGas
|
||||
|
||||
const trxReceipt = await this.contract.methods
|
||||
.updateMarketFee(exchangeId, this.web3.utils.toWei(newMarketFee))
|
||||
.send({
|
||||
from: address,
|
||||
gas: estGas + 1,
|
||||
gasPrice: await this.getFairGasPrice()
|
||||
})
|
||||
return trxReceipt
|
||||
}
|
||||
|
||||
/**
|
||||
* Set new market fee collector, only market fee collector can update it
|
||||
* @param {String} address user address
|
||||
* @param {String} exchangeId ExchangeId
|
||||
* @param {String} newMarketFeeCollector New market fee collector
|
||||
* @return {Promise<TransactionReceipt>} transaction receipt
|
||||
*/
|
||||
public async updateMarketFeeCollector<G extends boolean = false>(
|
||||
address: string,
|
||||
exchangeId: string,
|
||||
newMarketFeeCollector: string,
|
||||
estimateGas?: G
|
||||
): Promise<G extends false ? TransactionReceipt : number> {
|
||||
const estGas = await calculateEstimatedGas(
|
||||
address,
|
||||
this.contract.methods.updateMarketFeeCollector,
|
||||
exchangeId,
|
||||
newMarketFeeCollector
|
||||
)
|
||||
if (estimateGas) return estGas
|
||||
|
||||
const trxReceipt = await this.contract.methods
|
||||
.updateMarketFeeCollector(exchangeId, newMarketFeeCollector)
|
||||
.send({
|
||||
from: address,
|
||||
gas: estGas + 1,
|
||||
gasPrice: await this.getFairGasPrice()
|
||||
})
|
||||
return trxReceipt
|
||||
}
|
||||
}
|
File diff suppressed because it is too large
Load Diff
474
src/contracts/pools/Router.ts
Normal file
474
src/contracts/pools/Router.ts
Normal file
@ -0,0 +1,474 @@
|
||||
import { TransactionReceipt } from 'web3-core'
|
||||
import { AbiItem } from 'web3-utils'
|
||||
import FactoryRouter from '@oceanprotocol/contracts/artifacts/contracts/pools/FactoryRouter.sol/FactoryRouter.json'
|
||||
import { calculateEstimatedGas } from '../../utils'
|
||||
import { Operation } from '../../@types'
|
||||
import { SmartContractWithAddress } from '..'
|
||||
|
||||
/**
|
||||
* Provides an interface for FactoryRouter contract
|
||||
*/
|
||||
export class Router extends SmartContractWithAddress {
|
||||
getDefaultAbi(): AbiItem | AbiItem[] {
|
||||
return FactoryRouter.abi as AbiItem[]
|
||||
}
|
||||
|
||||
/**
|
||||
* buyDatatokenBatch
|
||||
* @param {String} address
|
||||
* @param {Operation} operations Operations objects array
|
||||
* @return {Promise<TransactionReceipt>} Transaction receipt
|
||||
*/
|
||||
public async buyDatatokenBatch<G extends boolean = false>(
|
||||
address: string,
|
||||
operations: Operation[],
|
||||
estimateGas?: G
|
||||
): Promise<G extends false ? TransactionReceipt : number> {
|
||||
const estGas = await calculateEstimatedGas(
|
||||
address,
|
||||
this.contract.methods.buyDTBatch,
|
||||
operations
|
||||
)
|
||||
if (estimateGas) return estGas
|
||||
|
||||
// Invoke createToken function of the contract
|
||||
const trxReceipt = await this.contract.methods.buyDTBatch(operations).send({
|
||||
from: address,
|
||||
gas: estGas + 1,
|
||||
gasPrice: await this.getFairGasPrice()
|
||||
})
|
||||
|
||||
return trxReceipt
|
||||
}
|
||||
|
||||
/** Check if a token is on approved tokens list, if true opfFee is lower in pools with that token/DT
|
||||
* @return {Promise<boolean>} true if is on the list.
|
||||
*/
|
||||
public async isApprovedToken(address: string): Promise<boolean> {
|
||||
return await this.contract.methods.isApprovedToken(address).call()
|
||||
}
|
||||
|
||||
/** Check if an address is a side staking contract.
|
||||
* @return {Promise<boolean>} true if is a SS contract
|
||||
*/
|
||||
public async isSideStaking(address: string): Promise<boolean> {
|
||||
return await this.contract.methods.isSSContract(address).call()
|
||||
}
|
||||
|
||||
/** Check if an address is a Fixed Rate contract.
|
||||
* @return {Promise<boolean>} true if is a Fixed Rate contract
|
||||
*/
|
||||
public async isFixedPrice(address: string): Promise<boolean> {
|
||||
return await this.contract.methods.isFixedRateContract(address).call()
|
||||
}
|
||||
|
||||
/** Get Router Owner
|
||||
* @return {Promise<string>} Router Owner address
|
||||
*/
|
||||
public async getOwner(): Promise<string> {
|
||||
return await this.contract.methods.routerOwner().call()
|
||||
}
|
||||
|
||||
/** Get NFT Factory address
|
||||
* @return {Promise<string>} NFT Factory address
|
||||
*/
|
||||
public async getNFTFactory(): Promise<string> {
|
||||
return await this.contract.methods.factory().call()
|
||||
}
|
||||
|
||||
/** Check if an address is a pool template contract.
|
||||
* @return {Promise<boolean>} true if is a Template
|
||||
*/
|
||||
public async isPoolTemplate(address: string): Promise<boolean> {
|
||||
return await this.contract.methods.isPoolTemplate(address).call()
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a new token to oceanTokens list, pools with baseToken in this list have NO opf Fee
|
||||
* @param {String} address caller address
|
||||
* @param {String} tokenAddress token address to add
|
||||
* @return {Promise<TransactionReceipt>}
|
||||
*/
|
||||
public async addApprovedToken<G extends boolean = false>(
|
||||
address: string,
|
||||
tokenAddress: string,
|
||||
estimateGas?: G
|
||||
): Promise<G extends false ? TransactionReceipt : number> {
|
||||
if ((await this.getOwner()) !== address) {
|
||||
throw new Error(`Caller is not Router Owner`)
|
||||
}
|
||||
|
||||
const estGas = await calculateEstimatedGas(
|
||||
address,
|
||||
this.contract.methods.addApprovedToken,
|
||||
tokenAddress
|
||||
)
|
||||
if (estimateGas) return estGas
|
||||
|
||||
// Invoke createToken function of the contract
|
||||
const trxReceipt = await this.contract.methods.addApprovedToken(tokenAddress).send({
|
||||
from: address,
|
||||
gas: estGas + 1,
|
||||
gasPrice: await this.getFairGasPrice()
|
||||
})
|
||||
|
||||
return trxReceipt
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove a token from oceanTokens list, pools without baseToken in this list have a opf Fee
|
||||
* @param {String} address
|
||||
* @param {String} tokenAddress address to remove
|
||||
* @return {Promise<TransactionReceipt>}
|
||||
*/
|
||||
public async removeApprovedToken<G extends boolean = false>(
|
||||
address: string,
|
||||
tokenAddress: string,
|
||||
estimateGas?: G
|
||||
): Promise<G extends false ? TransactionReceipt : number> {
|
||||
if ((await this.getOwner()) !== address) {
|
||||
throw new Error(`Caller is not Router Owner`)
|
||||
}
|
||||
|
||||
const estGas = await calculateEstimatedGas(
|
||||
address,
|
||||
this.contract.methods.removeApprovedToken,
|
||||
tokenAddress
|
||||
)
|
||||
if (estimateGas) return estGas
|
||||
|
||||
// Invoke createToken function of the contract
|
||||
const trxReceipt = await this.contract.methods
|
||||
.removeApprovedToken(tokenAddress)
|
||||
.send({
|
||||
from: address,
|
||||
gas: estGas + 1,
|
||||
gasPrice: await this.getFairGasPrice()
|
||||
})
|
||||
|
||||
return trxReceipt
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a new contract to ssContract list, after is added, can be used when deploying a new pool
|
||||
* @param {String} address
|
||||
* @param {String} tokenAddress contract address to add
|
||||
* @return {Promise<TransactionReceipt>}
|
||||
*/
|
||||
public async addSSContract<G extends boolean = false>(
|
||||
address: string,
|
||||
tokenAddress: string,
|
||||
estimateGas?: G
|
||||
): Promise<G extends false ? TransactionReceipt : number> {
|
||||
if ((await this.getOwner()) !== address) {
|
||||
throw new Error(`Caller is not Router Owner`)
|
||||
}
|
||||
|
||||
const estGas = await calculateEstimatedGas(
|
||||
address,
|
||||
this.contract.methods.addSSContract,
|
||||
tokenAddress
|
||||
)
|
||||
if (estimateGas) return estGas
|
||||
|
||||
// Invoke createToken function of the contract
|
||||
const trxReceipt = await this.contract.methods.addSSContract(tokenAddress).send({
|
||||
from: address,
|
||||
gas: estGas + 1,
|
||||
gasPrice: await this.getFairGasPrice()
|
||||
})
|
||||
|
||||
return trxReceipt
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes a new contract from ssContract list
|
||||
* @param {String} address caller address
|
||||
* @param {String} tokenAddress contract address to removed
|
||||
* @return {Promise<TransactionReceipt>}
|
||||
*/
|
||||
public async removeSSContract<G extends boolean = false>(
|
||||
address: string,
|
||||
tokenAddress: string,
|
||||
estimateGas?: G
|
||||
): Promise<G extends false ? TransactionReceipt : number> {
|
||||
if ((await this.getOwner()) !== address) {
|
||||
throw new Error(`Caller is not Router Owner`)
|
||||
}
|
||||
|
||||
const estGas = await calculateEstimatedGas(
|
||||
address,
|
||||
this.contract.methods.removeSSContract,
|
||||
tokenAddress
|
||||
)
|
||||
if (estimateGas) return estGas
|
||||
|
||||
// Invoke createToken function of the contract
|
||||
const trxReceipt = await this.contract.methods.removeSSContract(tokenAddress).send({
|
||||
from: address,
|
||||
gas: estGas + 1,
|
||||
gasPrice: await this.getFairGasPrice()
|
||||
})
|
||||
|
||||
return trxReceipt
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a new contract to fixedRate list, after is added, can be used when deploying a new pool
|
||||
* @param {String} address
|
||||
* @param {String} tokenAddress contract address to add
|
||||
* @return {Promise<TransactionReceipt>}
|
||||
*/
|
||||
public async addFixedRateContract<G extends boolean = false>(
|
||||
address: string,
|
||||
tokenAddress: string,
|
||||
estimateGas?: G
|
||||
): Promise<G extends false ? TransactionReceipt : number> {
|
||||
if ((await this.getOwner()) !== address) {
|
||||
throw new Error(`Caller is not Router Owner`)
|
||||
}
|
||||
|
||||
const estGas = await calculateEstimatedGas(
|
||||
address,
|
||||
this.contract.methods.addFixedRateContract,
|
||||
tokenAddress
|
||||
)
|
||||
if (estimateGas) return estGas
|
||||
|
||||
// Invoke createToken function of the contract
|
||||
const trxReceipt = await this.contract.methods
|
||||
.addFixedRateContract(tokenAddress)
|
||||
.send({
|
||||
from: address,
|
||||
gas: estGas + 1,
|
||||
gasPrice: await this.getFairGasPrice()
|
||||
})
|
||||
|
||||
return trxReceipt
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes a contract from fixedRate list
|
||||
* @param {String} address
|
||||
* @param {String} tokenAddress contract address to add
|
||||
* @return {Promise<TransactionReceipt>}
|
||||
*/
|
||||
public async removeFixedRateContract<G extends boolean = false>(
|
||||
address: string,
|
||||
tokenAddress: string,
|
||||
estimateGas?: G
|
||||
): Promise<G extends false ? TransactionReceipt : number> {
|
||||
if ((await this.getOwner()) !== address) {
|
||||
throw new Error(`Caller is not Router Owner`)
|
||||
}
|
||||
|
||||
const estGas = await calculateEstimatedGas(
|
||||
address,
|
||||
this.contract.methods.removeFixedRateContract,
|
||||
tokenAddress
|
||||
)
|
||||
if (estimateGas) return estGas
|
||||
|
||||
// Invoke removeFixedRateContract function of the contract
|
||||
const trxReceipt = await this.contract.methods
|
||||
.removeFixedRateContract(tokenAddress)
|
||||
.send({
|
||||
from: address,
|
||||
gas: estGas + 1,
|
||||
gasPrice: await this.getFairGasPrice()
|
||||
})
|
||||
|
||||
return trxReceipt
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a new contract to dispenser list, after is added, can be used when deploying a new pool
|
||||
* @param {String} address
|
||||
* @param {String} tokenAddress contract address to add
|
||||
* @return {Promise<TransactionReceipt>}
|
||||
*/
|
||||
public async addDispenserContract<G extends boolean = false>(
|
||||
address: string,
|
||||
tokenAddress: string,
|
||||
estimateGas?: G
|
||||
): Promise<G extends false ? TransactionReceipt : number> {
|
||||
if ((await this.getOwner()) !== address) {
|
||||
throw new Error(`Caller is not Router Owner`)
|
||||
}
|
||||
|
||||
const estGas = await calculateEstimatedGas(
|
||||
address,
|
||||
this.contract.methods.addDispenserContract,
|
||||
tokenAddress
|
||||
)
|
||||
if (estimateGas) return estGas
|
||||
|
||||
// Invoke createToken function of the contract
|
||||
const trxReceipt = await this.contract.methods
|
||||
.addDispenserContract(tokenAddress)
|
||||
.send({
|
||||
from: address,
|
||||
gas: estGas + 1,
|
||||
gasPrice: await this.getFairGasPrice()
|
||||
})
|
||||
|
||||
return trxReceipt
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a new contract to dispenser list, after is added, can be used when deploying a new pool
|
||||
* @param {String} address
|
||||
* @param {String} tokenAddress contract address to add
|
||||
* @return {Promise<TransactionReceipt>}
|
||||
*/
|
||||
public async removeDispenserContract<G extends boolean = false>(
|
||||
address: string,
|
||||
tokenAddress: string,
|
||||
estimateGas?: G
|
||||
): Promise<G extends false ? TransactionReceipt : number> {
|
||||
if ((await this.getOwner()) !== address) {
|
||||
throw new Error(`Caller is not Router Owner`)
|
||||
}
|
||||
|
||||
const estGas = await calculateEstimatedGas(
|
||||
address,
|
||||
this.contract.methods.removeDispenserContract,
|
||||
tokenAddress
|
||||
)
|
||||
if (estimateGas) return estGas
|
||||
|
||||
// Invoke createToken function of the contract
|
||||
const trxReceipt = await this.contract.methods
|
||||
.removeDispenserContract(tokenAddress)
|
||||
.send({
|
||||
from: address,
|
||||
gas: estGas + 1,
|
||||
gasPrice: await this.getFairGasPrice()
|
||||
})
|
||||
|
||||
return trxReceipt
|
||||
}
|
||||
|
||||
/** Get OPF Fee per token
|
||||
* @return {Promise<number>} OPC fee for a specific baseToken
|
||||
*/
|
||||
public async getOPCFee(baseToken: string): Promise<number> {
|
||||
return await this.contract.methods.getOPCFee(baseToken).call()
|
||||
}
|
||||
|
||||
/** Get Current OPF Fee
|
||||
* @return {Promise<number>} OPF fee
|
||||
*/
|
||||
public async getCurrentOPCFee(): Promise<number> {
|
||||
return await this.contract.methods.swapOceanFee().call()
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a new contract to fixedRate list, after is added, can be used when deploying a new pool
|
||||
* @param {String} address
|
||||
* @param {number} newSwapOceanFee Amount charged for swapping with ocean approved tokens
|
||||
* @param {number} newSwapNonOceanFee Amount charged for swapping with non ocean approved tokens
|
||||
* @param {number} newConsumeFee Amount charged from consumeFees
|
||||
* @param {number} newProviderFee Amount charged for providerFees
|
||||
* @return {Promise<TransactionReceipt>}
|
||||
*/
|
||||
public async updateOPCFee<G extends boolean = false>(
|
||||
address: string,
|
||||
newSwapOceanFee: number,
|
||||
newSwapNonOceanFee: number,
|
||||
newConsumeFee: number,
|
||||
newProviderFee: number,
|
||||
estimateGas?: G
|
||||
): Promise<G extends false ? TransactionReceipt : number> {
|
||||
if ((await this.getOwner()) !== address) {
|
||||
throw new Error(`Caller is not Router Owner`)
|
||||
}
|
||||
|
||||
const estGas = await calculateEstimatedGas(
|
||||
address,
|
||||
this.contract.methods.updateOPCFee,
|
||||
newSwapOceanFee,
|
||||
newSwapNonOceanFee,
|
||||
newConsumeFee,
|
||||
newProviderFee
|
||||
)
|
||||
if (estimateGas) return estGas
|
||||
|
||||
// Invoke createToken function of the contract
|
||||
const trxReceipt = await this.contract.methods
|
||||
.updateOPCFee(newSwapOceanFee, newSwapNonOceanFee, newConsumeFee, newProviderFee)
|
||||
.send({
|
||||
from: address,
|
||||
gas: estGas + 1,
|
||||
gasPrice: await this.getFairGasPrice()
|
||||
})
|
||||
|
||||
return trxReceipt
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a new template to poolTemplates mapping, after template is added,it can be used
|
||||
* @param {String} address
|
||||
* @param {String} templateAddress template address to add
|
||||
* @return {Promise<TransactionReceipt>}
|
||||
*/
|
||||
public async addPoolTemplate<G extends boolean = false>(
|
||||
address: string,
|
||||
templateAddress: string,
|
||||
estimateGas?: G
|
||||
): Promise<G extends false ? TransactionReceipt : number> {
|
||||
if ((await this.getOwner()) !== address) {
|
||||
throw new Error(`Caller is not Router Owner`)
|
||||
}
|
||||
|
||||
const estGas = await calculateEstimatedGas(
|
||||
address,
|
||||
this.contract.methods.addPoolTemplate,
|
||||
templateAddress
|
||||
)
|
||||
if (estimateGas) return estGas
|
||||
|
||||
// Invoke createToken function of the contract
|
||||
const trxReceipt = await this.contract.methods.addPoolTemplate(templateAddress).send({
|
||||
from: address,
|
||||
gas: estGas + 1,
|
||||
gasPrice: await this.getFairGasPrice()
|
||||
})
|
||||
|
||||
return trxReceipt
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove template from poolTemplates mapping, after template is removed,it can be used anymore
|
||||
* @param {String} address
|
||||
* @param {String} templateAddress template address to remove
|
||||
* @return {Promise<TransactionReceipt>}
|
||||
*/
|
||||
public async removePoolTemplate<G extends boolean = false>(
|
||||
address: string,
|
||||
templateAddress: string,
|
||||
estimateGas?: G
|
||||
): Promise<G extends false ? TransactionReceipt : number> {
|
||||
if ((await this.getOwner()) !== address) {
|
||||
throw new Error(`Caller is not Router Owner`)
|
||||
}
|
||||
|
||||
const estGas = await calculateEstimatedGas(
|
||||
address,
|
||||
this.contract.methods.removePoolTemplate,
|
||||
templateAddress
|
||||
)
|
||||
if (estimateGas) return estGas
|
||||
|
||||
// Invoke createToken function of the contract
|
||||
const trxReceipt = await this.contract.methods
|
||||
.removePoolTemplate(templateAddress)
|
||||
.send({
|
||||
from: address,
|
||||
gas: estGas + 1,
|
||||
gasPrice: await this.getFairGasPrice()
|
||||
})
|
||||
|
||||
return trxReceipt
|
||||
}
|
||||
}
|
@ -1,40 +1,12 @@
|
||||
import Web3 from 'web3'
|
||||
import { AbiItem } from 'web3-utils/types'
|
||||
import { TransactionReceipt } from 'web3-core'
|
||||
import { Contract } from 'web3-eth-contract'
|
||||
import {
|
||||
LoggerInstance,
|
||||
getFairGasPrice,
|
||||
ConfigHelper,
|
||||
estimateGas,
|
||||
unitsToAmount
|
||||
} from '../../utils'
|
||||
import SideStakingTemplate from '@oceanprotocol/contracts/artifacts/contracts/pools/ssContracts/SideStaking.sol/SideStaking.json'
|
||||
import { Config } from '../../models'
|
||||
import SideStakingAbi from '@oceanprotocol/contracts/artifacts/contracts/pools/ssContracts/SideStaking.sol/SideStaking.json'
|
||||
import { LoggerInstance, calculateEstimatedGas } from '../../utils'
|
||||
import { SmartContract } from '..'
|
||||
|
||||
export class SideStaking {
|
||||
public ssAbi: AbiItem | AbiItem[]
|
||||
public web3: Web3
|
||||
public config: Config
|
||||
|
||||
constructor(
|
||||
web3: Web3,
|
||||
network?: string | number,
|
||||
ssAbi: AbiItem | AbiItem[] = null,
|
||||
config?: Config
|
||||
) {
|
||||
if (ssAbi) this.ssAbi = ssAbi
|
||||
else this.ssAbi = SideStakingTemplate.abi as AbiItem[]
|
||||
this.web3 = web3
|
||||
this.config = config || new ConfigHelper().getConfig(network || 'unknown')
|
||||
}
|
||||
|
||||
async unitsToAmount(
|
||||
token: string,
|
||||
amount: string,
|
||||
tokenDecimals?: number
|
||||
): Promise<string> {
|
||||
return unitsToAmount(this.web3, token, amount, tokenDecimals)
|
||||
export class SideStaking extends SmartContract {
|
||||
getDefaultAbi(): AbiItem | AbiItem[] {
|
||||
return SideStakingAbi.abi as AbiItem[]
|
||||
}
|
||||
|
||||
/**
|
||||
@ -47,16 +19,16 @@ export class SideStaking {
|
||||
ssAddress: string,
|
||||
datatokenAddress: string
|
||||
): Promise<string> {
|
||||
const sideStaking = new this.web3.eth.Contract(this.ssAbi, ssAddress)
|
||||
let result = null
|
||||
const sideStaking = this.getContract(ssAddress)
|
||||
let supply = null
|
||||
try {
|
||||
result = await sideStaking.methods
|
||||
supply = await sideStaking.methods
|
||||
.getDatatokenCirculatingSupply(datatokenAddress)
|
||||
.call()
|
||||
} catch (e) {
|
||||
LoggerInstance.error(`ERROR: Failed to get: ${e.message}`)
|
||||
}
|
||||
return result.toString()
|
||||
return supply.toString()
|
||||
}
|
||||
|
||||
/**
|
||||
@ -71,12 +43,12 @@ export class SideStaking {
|
||||
datatokenAddress: string
|
||||
): Promise<string> {
|
||||
try {
|
||||
const sideStaking = new this.web3.eth.Contract(this.ssAbi, ssAddress)
|
||||
let result = null
|
||||
result = await sideStaking.methods
|
||||
const sideStaking = this.getContract(ssAddress)
|
||||
let supply = null
|
||||
supply = await sideStaking.methods
|
||||
.getDatatokenCurrentCirculatingSupply(datatokenAddress)
|
||||
.call()
|
||||
return result.toString()
|
||||
return supply.toString()
|
||||
} catch (e) {
|
||||
LoggerInstance.error(`ERROR: Failed to get: ${e.message}`)
|
||||
}
|
||||
@ -92,14 +64,14 @@ export class SideStaking {
|
||||
ssAddress: string,
|
||||
datatokenAddress: string
|
||||
): Promise<string> {
|
||||
const sideStaking = new this.web3.eth.Contract(this.ssAbi, ssAddress)
|
||||
let result = null
|
||||
const sideStaking = this.getContract(ssAddress)
|
||||
let address = null
|
||||
try {
|
||||
result = await sideStaking.methods.getPublisherAddress(datatokenAddress).call()
|
||||
address = await sideStaking.methods.getPublisherAddress(datatokenAddress).call()
|
||||
} catch (e) {
|
||||
LoggerInstance.error(`ERROR: Failed to get: ${e.message}`)
|
||||
}
|
||||
return result
|
||||
return address
|
||||
}
|
||||
|
||||
/**
|
||||
@ -108,15 +80,15 @@ export class SideStaking {
|
||||
* @param {String} datatokenAddress datatokenAddress
|
||||
* @return {String}
|
||||
*/
|
||||
async getBaseToken(ssAddress: string, datatokenAddress: string): Promise<string> {
|
||||
const sideStaking = new this.web3.eth.Contract(this.ssAbi, ssAddress)
|
||||
let result = null
|
||||
async getBasetoken(ssAddress: string, datatokenAddress: string): Promise<string> {
|
||||
const sideStaking = this.getContract(ssAddress)
|
||||
let address = null
|
||||
try {
|
||||
result = await sideStaking.methods.getBaseTokenAddress(datatokenAddress).call()
|
||||
address = await sideStaking.methods.getBaseTokenAddress(datatokenAddress).call()
|
||||
} catch (e) {
|
||||
LoggerInstance.error(`ERROR: Failed to get: ${e.message}`)
|
||||
}
|
||||
return result
|
||||
return address
|
||||
}
|
||||
|
||||
/**
|
||||
@ -126,14 +98,14 @@ export class SideStaking {
|
||||
* @return {String}
|
||||
*/
|
||||
async getPoolAddress(ssAddress: string, datatokenAddress: string): Promise<string> {
|
||||
const sideStaking = new this.web3.eth.Contract(this.ssAbi, ssAddress)
|
||||
let result = null
|
||||
const sideStaking = this.getContract(ssAddress)
|
||||
let address = null
|
||||
try {
|
||||
result = await sideStaking.methods.getPoolAddress(datatokenAddress).call()
|
||||
address = await sideStaking.methods.getPoolAddress(datatokenAddress).call()
|
||||
} catch (e) {
|
||||
LoggerInstance.error(`ERROR: Failed to get: ${e.message}`)
|
||||
}
|
||||
return result
|
||||
return address
|
||||
}
|
||||
|
||||
/**
|
||||
@ -142,18 +114,18 @@ export class SideStaking {
|
||||
* @param {String} datatokenAddress datatokenAddress
|
||||
* @return {String}
|
||||
*/
|
||||
async getBaseTokenBalance(
|
||||
async getBasetokenBalance(
|
||||
ssAddress: string,
|
||||
datatokenAddress: string
|
||||
): Promise<string> {
|
||||
const sideStaking = new this.web3.eth.Contract(this.ssAbi, ssAddress)
|
||||
let result = null
|
||||
const sideStaking = this.getContract(ssAddress)
|
||||
let balance = null
|
||||
try {
|
||||
result = await sideStaking.methods.getBaseTokenBalance(datatokenAddress).call()
|
||||
balance = await sideStaking.methods.getBaseTokenBalance(datatokenAddress).call()
|
||||
} catch (e) {
|
||||
LoggerInstance.error(`ERROR: Failed to get: ${e.message}`)
|
||||
}
|
||||
return result
|
||||
return balance
|
||||
}
|
||||
|
||||
/**
|
||||
@ -168,15 +140,15 @@ export class SideStaking {
|
||||
datatokenAddress: string,
|
||||
tokenDecimals?: number
|
||||
): Promise<string> {
|
||||
const sideStaking = new this.web3.eth.Contract(this.ssAbi, ssAddress)
|
||||
let result = null
|
||||
const sideStaking = this.getContract(ssAddress)
|
||||
let balance = null
|
||||
try {
|
||||
result = await sideStaking.methods.getDatatokenBalance(datatokenAddress).call()
|
||||
balance = await sideStaking.methods.getDatatokenBalance(datatokenAddress).call()
|
||||
} catch (e) {
|
||||
LoggerInstance.error(`ERROR: Failed to get: ${e.message}`)
|
||||
}
|
||||
result = await this.unitsToAmount(datatokenAddress, result, tokenDecimals)
|
||||
return result
|
||||
balance = await this.unitsToAmount(datatokenAddress, balance, tokenDecimals)
|
||||
return balance
|
||||
}
|
||||
|
||||
/**
|
||||
@ -185,15 +157,15 @@ export class SideStaking {
|
||||
* @param {String} datatokenAddress datatokenAddress
|
||||
* @return {String} end block for vesting amount
|
||||
*/
|
||||
async getvestingEndBlock(ssAddress: string, datatokenAddress: string): Promise<string> {
|
||||
const sideStaking = new this.web3.eth.Contract(this.ssAbi, ssAddress)
|
||||
let result = null
|
||||
async getVestingEndBlock(ssAddress: string, datatokenAddress: string): Promise<string> {
|
||||
const sideStaking = this.getContract(ssAddress)
|
||||
let block = null
|
||||
try {
|
||||
result = await sideStaking.methods.getvestingEndBlock(datatokenAddress).call()
|
||||
block = await sideStaking.methods.getvestingEndBlock(datatokenAddress).call()
|
||||
} catch (e) {
|
||||
LoggerInstance.error(`ERROR: Failed to get: ${e.message}`)
|
||||
}
|
||||
return result
|
||||
return block
|
||||
}
|
||||
|
||||
/**
|
||||
@ -203,20 +175,20 @@ export class SideStaking {
|
||||
* @param {number} tokenDecimals optional number of decimals of the token
|
||||
* @return {String}
|
||||
*/
|
||||
async getvestingAmount(
|
||||
async getVestingAmount(
|
||||
ssAddress: string,
|
||||
datatokenAddress: string,
|
||||
tokenDecimals?: number
|
||||
): Promise<string> {
|
||||
const sideStaking = new this.web3.eth.Contract(this.ssAbi, ssAddress)
|
||||
let result = null
|
||||
const sideStaking = this.getContract(ssAddress)
|
||||
let amount = null
|
||||
try {
|
||||
result = await sideStaking.methods.getvestingAmount(datatokenAddress).call()
|
||||
amount = await sideStaking.methods.getvestingAmount(datatokenAddress).call()
|
||||
} catch (e) {
|
||||
LoggerInstance.error(`ERROR: Failed to get: ${e.message}`)
|
||||
}
|
||||
result = await this.unitsToAmount(datatokenAddress, result, tokenDecimals)
|
||||
return result
|
||||
amount = await this.unitsToAmount(datatokenAddress, amount, tokenDecimals)
|
||||
return amount
|
||||
}
|
||||
|
||||
/**
|
||||
@ -225,18 +197,18 @@ export class SideStaking {
|
||||
* @param {String} datatokenAddress datatokenAddress
|
||||
* @return {String}
|
||||
*/
|
||||
async getvestingLastBlock(
|
||||
async getVestingLastBlock(
|
||||
ssAddress: string,
|
||||
datatokenAddress: string
|
||||
): Promise<string> {
|
||||
const sideStaking = new this.web3.eth.Contract(this.ssAbi, ssAddress)
|
||||
let result = null
|
||||
const sideStaking = this.getContract(ssAddress)
|
||||
let block = null
|
||||
try {
|
||||
result = await sideStaking.methods.getvestingLastBlock(datatokenAddress).call()
|
||||
block = await sideStaking.methods.getvestingLastBlock(datatokenAddress).call()
|
||||
} catch (e) {
|
||||
LoggerInstance.error(`ERROR: Failed to get: ${e.message}`)
|
||||
}
|
||||
return result
|
||||
return block
|
||||
}
|
||||
|
||||
/**
|
||||
@ -246,40 +218,20 @@ export class SideStaking {
|
||||
* @param {number} tokenDecimals optional number of decimals of the token
|
||||
* @return {String}
|
||||
*/
|
||||
async getvestingAmountSoFar(
|
||||
async getVestingAmountSoFar(
|
||||
ssAddress: string,
|
||||
datatokenAddress: string,
|
||||
tokenDecimals?: number
|
||||
): Promise<string> {
|
||||
const sideStaking = new this.web3.eth.Contract(this.ssAbi, ssAddress)
|
||||
let result = null
|
||||
const sideStaking = this.getContract(ssAddress)
|
||||
let amount = null
|
||||
try {
|
||||
result = await sideStaking.methods.getvestingAmountSoFar(datatokenAddress).call()
|
||||
amount = await sideStaking.methods.getvestingAmountSoFar(datatokenAddress).call()
|
||||
} catch (e) {
|
||||
LoggerInstance.error(`ERROR: Failed to get: ${e.message}`)
|
||||
}
|
||||
result = await this.unitsToAmount(datatokenAddress, result, tokenDecimals)
|
||||
return result
|
||||
}
|
||||
|
||||
/**
|
||||
* Estimate gas cost for getVesting
|
||||
* @param {String} account
|
||||
* @param {String} ssAddress side staking contract address
|
||||
* @param {String} datatokenAddress datatokenAddress
|
||||
* @param {Contract} contractInstance optional contract instance
|
||||
* @return {Promise<number>}
|
||||
*/
|
||||
public async estGetVesting(
|
||||
account: string,
|
||||
ssAddress: string,
|
||||
datatokenAddress: string,
|
||||
contractInstance?: Contract
|
||||
): Promise<number> {
|
||||
const sideStaking =
|
||||
contractInstance || new this.web3.eth.Contract(this.ssAbi as AbiItem[], ssAddress)
|
||||
|
||||
return estimateGas(account, sideStaking.methods.getVesting, datatokenAddress)
|
||||
amount = await this.unitsToAmount(datatokenAddress, amount, tokenDecimals)
|
||||
return amount
|
||||
}
|
||||
|
||||
/** Send vested tokens available to the publisher address, can be called by anyone
|
||||
@ -289,97 +241,73 @@ export class SideStaking {
|
||||
* @param {String} datatokenAddress datatokenAddress
|
||||
* @return {TransactionReceipt}
|
||||
*/
|
||||
async getVesting(
|
||||
async getVesting<G extends boolean = false>(
|
||||
account: string,
|
||||
ssAddress: string,
|
||||
datatokenAddress: string
|
||||
): Promise<TransactionReceipt> {
|
||||
const sideStaking = new this.web3.eth.Contract(this.ssAbi, ssAddress)
|
||||
let result = null
|
||||
datatokenAddress: string,
|
||||
estimateGas?: G
|
||||
): Promise<G extends false ? TransactionReceipt : number> {
|
||||
const sideStaking = this.getContract(ssAddress)
|
||||
let vesting = null
|
||||
|
||||
const estGas = await estimateGas(
|
||||
const estGas = await calculateEstimatedGas(
|
||||
account,
|
||||
sideStaking.methods.getVesting,
|
||||
datatokenAddress
|
||||
)
|
||||
if (estimateGas) return estGas
|
||||
|
||||
try {
|
||||
result = await sideStaking.methods.getVesting(datatokenAddress).send({
|
||||
vesting = await sideStaking.methods.getVesting(datatokenAddress).send({
|
||||
from: account,
|
||||
gas: estGas + 1,
|
||||
gasPrice: await getFairGasPrice(this.web3, this.config)
|
||||
gasPrice: await this.getFairGasPrice()
|
||||
})
|
||||
} catch (e) {
|
||||
LoggerInstance.error('ERROR: Failed to join swap pool amount out')
|
||||
}
|
||||
return result
|
||||
return vesting
|
||||
}
|
||||
|
||||
/**
|
||||
* Estimate gas cost for getVesting
|
||||
/** Send vested tokens available to the publisher address, can be called by anyone
|
||||
*
|
||||
* @param {String} account
|
||||
* @param {String} ssAddress side staking contract address
|
||||
* @param {String} datatokenAddress datatokenAddress
|
||||
* @param {Contract} contractInstance optional contract instance
|
||||
* @return {Promise<number>}
|
||||
* @return {TransactionReceipt}
|
||||
*/
|
||||
public async estSetPoolSwapFee(
|
||||
private async setPoolSwapFee<G extends boolean = false>(
|
||||
account: string,
|
||||
ssAddress: string,
|
||||
datatokenAddress: string,
|
||||
poolAddress: string,
|
||||
swapFee: number,
|
||||
contractInstance?: Contract
|
||||
): Promise<number> {
|
||||
const sideStaking =
|
||||
contractInstance || new this.web3.eth.Contract(this.ssAbi as AbiItem[], ssAddress)
|
||||
estimateGas?: G
|
||||
): Promise<G extends false ? TransactionReceipt : number> {
|
||||
const sideStaking = this.getContract(ssAddress)
|
||||
let fee = null
|
||||
|
||||
return estimateGas(
|
||||
account,
|
||||
sideStaking.methods.setPoolSwapFee,
|
||||
datatokenAddress,
|
||||
poolAddress,
|
||||
swapFee
|
||||
)
|
||||
}
|
||||
|
||||
/** Send vested tokens available to the publisher address, can be called by anyone
|
||||
*
|
||||
* @param {String} account
|
||||
* @param {String} ssAddress side staking contract address
|
||||
* @param {String} datatokenAddress datatokenAddress
|
||||
* @return {TransactionReceipt}
|
||||
*/
|
||||
async setPoolSwapFee(
|
||||
account: string,
|
||||
ssAddress: string,
|
||||
datatokenAddress: string,
|
||||
poolAddress: string,
|
||||
swapFee: number
|
||||
): Promise<TransactionReceipt> {
|
||||
const sideStaking = new this.web3.eth.Contract(this.ssAbi, ssAddress)
|
||||
let result = null
|
||||
|
||||
const estGas = await estimateGas(
|
||||
const estGas = await calculateEstimatedGas(
|
||||
account,
|
||||
sideStaking.methods.setPoolSwapFee,
|
||||
datatokenAddress,
|
||||
poolAddress,
|
||||
swapFee
|
||||
)
|
||||
if (estimateGas) return estGas
|
||||
|
||||
try {
|
||||
result = await sideStaking.methods
|
||||
fee = await sideStaking.methods
|
||||
.setPoolSwapFee(datatokenAddress, poolAddress, swapFee)
|
||||
.send({
|
||||
from: account,
|
||||
gas: estGas + 1,
|
||||
gasPrice: await getFairGasPrice(this.web3, this.config)
|
||||
gasPrice: await this.getFairGasPrice()
|
||||
})
|
||||
} catch (e) {
|
||||
LoggerInstance.error('ERROR: Failed to join swap pool amount out')
|
||||
}
|
||||
return result
|
||||
return fee
|
||||
}
|
||||
|
||||
/**
|
||||
@ -387,14 +315,14 @@ export class SideStaking {
|
||||
* @param {String} ssAddress side staking contract address
|
||||
* @return {String}
|
||||
*/
|
||||
async getRouter(ssAddress: string): Promise<string> {
|
||||
const sideStaking = new this.web3.eth.Contract(this.ssAbi, ssAddress)
|
||||
let result = null
|
||||
public async getRouter(ssAddress: string): Promise<string> {
|
||||
const sideStaking = this.getContract(ssAddress)
|
||||
let router = null
|
||||
try {
|
||||
result = await sideStaking.methods.router().call()
|
||||
router = await sideStaking.methods.router().call()
|
||||
} catch (e) {
|
||||
LoggerInstance.error(`ERROR: Failed to get Router address: ${e.message}`)
|
||||
}
|
||||
return result
|
||||
return router
|
||||
}
|
||||
}
|
897
src/contracts/tokens/Datatoken.ts
Normal file
897
src/contracts/tokens/Datatoken.ts
Normal file
@ -0,0 +1,897 @@
|
||||
import Web3 from 'web3'
|
||||
import { AbiItem } from 'web3-utils'
|
||||
import { TransactionReceipt } from 'web3-eth'
|
||||
import Decimal from 'decimal.js'
|
||||
import ERC20Template from '@oceanprotocol/contracts/artifacts/contracts/templates/ERC20Template.sol/ERC20Template.json'
|
||||
import ERC20TemplateEnterprise from '@oceanprotocol/contracts/artifacts/contracts/templates/ERC20TemplateEnterprise.sol/ERC20TemplateEnterprise.json'
|
||||
import { LoggerInstance, calculateEstimatedGas, ZERO_ADDRESS } from '../../utils'
|
||||
import {
|
||||
ConsumeMarketFee,
|
||||
FreOrderParams,
|
||||
FreCreationParams,
|
||||
ProviderFees,
|
||||
PublishingMarketFee,
|
||||
DispenserParams,
|
||||
OrderParams,
|
||||
DatatokenRoles
|
||||
} from '../../@types'
|
||||
import { Nft } from './NFT'
|
||||
import { Config } from '../../config'
|
||||
import { SmartContract } from '..'
|
||||
|
||||
export class Datatoken extends SmartContract {
|
||||
public abiEnterprise: AbiItem | AbiItem[]
|
||||
public nft: Nft
|
||||
|
||||
getDefaultAbi(): AbiItem | AbiItem[] {
|
||||
return ERC20Template.abi as AbiItem[]
|
||||
}
|
||||
|
||||
/**
|
||||
* Instantiate ERC20 Datatokens
|
||||
* @param {AbiItem | AbiItem[]} datatokensAbi
|
||||
* @param {Web3} web3
|
||||
*/
|
||||
constructor(
|
||||
web3: Web3,
|
||||
network?: string | number,
|
||||
config?: Config,
|
||||
abi?: AbiItem | AbiItem[],
|
||||
abiEnterprise?: AbiItem | AbiItem[]
|
||||
) {
|
||||
super(web3, network, config, abi)
|
||||
this.abiEnterprise = abiEnterprise || (ERC20TemplateEnterprise.abi as AbiItem[])
|
||||
this.nft = new Nft(this.web3)
|
||||
}
|
||||
|
||||
/**
|
||||
* Approve
|
||||
* @param {String} dtAddress Datatoken address
|
||||
* @param {String} spender Spender address
|
||||
* @param {string} amount Number of datatokens, as number. Will be converted to wei
|
||||
* @param {String} address User adress
|
||||
* @return {Promise<TransactionReceipt>} trxReceipt
|
||||
*/
|
||||
public async approve<G extends boolean = false>(
|
||||
dtAddress: string,
|
||||
spender: string,
|
||||
amount: string,
|
||||
address: string,
|
||||
estimateGas?: G
|
||||
): Promise<G extends false ? TransactionReceipt : number> {
|
||||
const dtContract = this.getContract(dtAddress)
|
||||
|
||||
const estGas = await calculateEstimatedGas(
|
||||
address,
|
||||
dtContract.methods.approve,
|
||||
spender,
|
||||
this.web3.utils.toWei(amount)
|
||||
)
|
||||
if (estimateGas) return estGas
|
||||
|
||||
// Call mint contract method
|
||||
const trxReceipt = await dtContract.methods
|
||||
.approve(spender, this.web3.utils.toWei(amount))
|
||||
.send({
|
||||
from: address,
|
||||
gas: estGas + 1,
|
||||
gasPrice: await this.getFairGasPrice()
|
||||
})
|
||||
return trxReceipt
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new FixedRateExchange setup.
|
||||
* @param {String} dtAddress Datatoken address
|
||||
* @param {String} address Caller address
|
||||
* @param {String} fixedPriceAddress
|
||||
* @param {FixedRateParams} fixedRateParams
|
||||
* @return {Promise<TransactionReceipt>} transactionId
|
||||
*/
|
||||
public async createFixedRate<G extends boolean = false>(
|
||||
dtAddress: string,
|
||||
address: string,
|
||||
fixedRateParams: FreCreationParams,
|
||||
estimateGas?: G
|
||||
): Promise<G extends false ? TransactionReceipt : number> {
|
||||
const dtContract = this.getContract(dtAddress)
|
||||
if (!(await this.isDatatokenDeployer(dtAddress, address))) {
|
||||
throw new Error(`User is not Datatoken Deployer`)
|
||||
}
|
||||
if (!fixedRateParams.allowedConsumer) fixedRateParams.allowedConsumer = ZERO_ADDRESS
|
||||
|
||||
const withMint = fixedRateParams.withMint ? 1 : 0
|
||||
|
||||
// should check DatatokenDeployer role using NFT level ..
|
||||
|
||||
const estGas = await calculateEstimatedGas(
|
||||
address,
|
||||
dtContract.methods.createFixedRate,
|
||||
fixedRateParams.fixedRateAddress,
|
||||
[
|
||||
fixedRateParams.baseTokenAddress,
|
||||
fixedRateParams.owner,
|
||||
fixedRateParams.marketFeeCollector,
|
||||
fixedRateParams.allowedConsumer
|
||||
],
|
||||
[
|
||||
fixedRateParams.baseTokenDecimals,
|
||||
fixedRateParams.datatokenDecimals,
|
||||
fixedRateParams.fixedRate,
|
||||
fixedRateParams.marketFee,
|
||||
withMint
|
||||
]
|
||||
)
|
||||
if (estimateGas) return estGas
|
||||
|
||||
// Call createFixedRate contract method
|
||||
const trxReceipt = await dtContract.methods
|
||||
.createFixedRate(
|
||||
fixedRateParams.fixedRateAddress,
|
||||
[
|
||||
fixedRateParams.baseTokenAddress,
|
||||
fixedRateParams.owner,
|
||||
fixedRateParams.marketFeeCollector,
|
||||
fixedRateParams.allowedConsumer
|
||||
],
|
||||
[
|
||||
fixedRateParams.baseTokenDecimals,
|
||||
fixedRateParams.datatokenDecimals,
|
||||
fixedRateParams.fixedRate,
|
||||
fixedRateParams.marketFee,
|
||||
withMint
|
||||
]
|
||||
)
|
||||
.send({
|
||||
from: address,
|
||||
gas: estGas + 1,
|
||||
gasPrice: await this.getFairGasPrice()
|
||||
})
|
||||
return trxReceipt
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new Dispenser
|
||||
* @param {String} dtAddress Datatoken address
|
||||
* @param {String} address Caller address
|
||||
* @param {String} dispenserAddress ispenser contract address
|
||||
* @param {String} dispenserParams
|
||||
* @return {Promise<TransactionReceipt>} transactionId
|
||||
*/
|
||||
public async createDispenser<G extends boolean = false>(
|
||||
dtAddress: string,
|
||||
address: string,
|
||||
dispenserAddress: string,
|
||||
dispenserParams: DispenserParams,
|
||||
estimateGas?: G
|
||||
): Promise<G extends false ? TransactionReceipt : number> {
|
||||
if (!(await this.isDatatokenDeployer(dtAddress, address))) {
|
||||
throw new Error(`User is not Datatoken Deployer`)
|
||||
}
|
||||
|
||||
const dtContract = this.getContract(dtAddress)
|
||||
|
||||
if (!dispenserParams.allowedSwapper) dispenserParams.allowedSwapper = ZERO_ADDRESS
|
||||
|
||||
if (!dispenserParams.withMint) dispenserParams.withMint = false
|
||||
|
||||
// should check DatatokenDeployer role using NFT level ..
|
||||
|
||||
const estGas = await calculateEstimatedGas(
|
||||
address,
|
||||
dtContract.methods.createDispenser,
|
||||
dispenserAddress,
|
||||
dispenserParams.maxTokens,
|
||||
dispenserParams.maxBalance,
|
||||
dispenserParams.withMint,
|
||||
dispenserParams.allowedSwapper
|
||||
)
|
||||
if (estimateGas) return estGas
|
||||
|
||||
// Call createFixedRate contract method
|
||||
const trxReceipt = await dtContract.methods
|
||||
.createDispenser(
|
||||
dispenserAddress,
|
||||
dispenserParams.maxTokens,
|
||||
dispenserParams.maxBalance,
|
||||
dispenserParams.withMint,
|
||||
dispenserParams.allowedSwapper
|
||||
)
|
||||
.send({
|
||||
from: address,
|
||||
gas: estGas + 1,
|
||||
gasPrice: await this.getFairGasPrice()
|
||||
})
|
||||
return trxReceipt
|
||||
}
|
||||
|
||||
/**
|
||||
* Mint
|
||||
* @param {String} dtAddress Datatoken address
|
||||
* @param {String} address Minter address
|
||||
* @param {String} amount Number of datatokens, as number. Will be converted to wei
|
||||
* @param {String} toAddress only if toAddress is different from the minter
|
||||
* @return {Promise<TransactionReceipt>} transactionId
|
||||
*/
|
||||
public async mint<G extends boolean = false>(
|
||||
dtAddress: string,
|
||||
address: string,
|
||||
amount: string,
|
||||
toAddress?: string,
|
||||
estimateGas?: G
|
||||
): Promise<G extends false ? TransactionReceipt : number> {
|
||||
const dtContract = this.getContract(dtAddress)
|
||||
|
||||
if ((await this.getPermissions(dtAddress, address)).minter !== true) {
|
||||
throw new Error(`Caller is not Minter`)
|
||||
}
|
||||
|
||||
const capAvailble = await this.getCap(dtAddress)
|
||||
if (new Decimal(capAvailble).gte(amount)) {
|
||||
const estGas = await calculateEstimatedGas(
|
||||
address,
|
||||
dtContract.methods.mint,
|
||||
toAddress || address,
|
||||
this.web3.utils.toWei(amount)
|
||||
)
|
||||
if (estimateGas) return estGas
|
||||
|
||||
// Call mint contract method
|
||||
const trxReceipt = await dtContract.methods
|
||||
.mint(toAddress || address, this.web3.utils.toWei(amount))
|
||||
.send({
|
||||
from: address,
|
||||
gas: estGas + 1,
|
||||
gasPrice: await this.getFairGasPrice()
|
||||
})
|
||||
return trxReceipt
|
||||
} else {
|
||||
throw new Error(`Mint amount exceeds cap available`)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Add Minter for an ERC20 Datatoken
|
||||
* only DatatokenDeployer can succeed
|
||||
* @param {String} dtAddress Datatoken address
|
||||
* @param {String} address User address
|
||||
* @param {String} minter User which is going to be a Minter
|
||||
* @return {Promise<TransactionReceipt>} transactionId
|
||||
*/
|
||||
public async addMinter<G extends boolean = false>(
|
||||
dtAddress: string,
|
||||
address: string,
|
||||
minter: string,
|
||||
estimateGas?: G
|
||||
): Promise<G extends false ? TransactionReceipt : number> {
|
||||
const dtContract = this.getContract(dtAddress)
|
||||
|
||||
if ((await this.isDatatokenDeployer(dtAddress, address)) !== true) {
|
||||
throw new Error(`Caller is not DatatokenDeployer`)
|
||||
}
|
||||
// Estimate gas cost for addMinter method
|
||||
const estGas = await calculateEstimatedGas(
|
||||
address,
|
||||
dtContract.methods.addMinter,
|
||||
minter
|
||||
)
|
||||
if (estimateGas) return estGas
|
||||
|
||||
// Call addMinter function of the contract
|
||||
const trxReceipt = await dtContract.methods.addMinter(minter).send({
|
||||
from: address,
|
||||
gas: estGas + 1,
|
||||
gasPrice: await this.getFairGasPrice()
|
||||
})
|
||||
|
||||
return trxReceipt
|
||||
}
|
||||
|
||||
/**
|
||||
* Revoke Minter permission for an ERC20 Datatoken
|
||||
* only DatatokenDeployer can succeed
|
||||
* @param {String} dtAddress Datatoken address
|
||||
* @param {String} address User address
|
||||
* @param {String} minter User which will be removed from Minter permission
|
||||
* @param {Contract} contractInstance optional contract instance
|
||||
* @return {Promise<any>}
|
||||
*/
|
||||
public async removeMinter<G extends boolean = false>(
|
||||
dtAddress: string,
|
||||
address: string,
|
||||
minter: string,
|
||||
estimateGas?: G
|
||||
): Promise<G extends false ? TransactionReceipt : number> {
|
||||
const dtContract = this.getContract(dtAddress)
|
||||
|
||||
if ((await this.isDatatokenDeployer(dtAddress, address)) !== true) {
|
||||
throw new Error(`Caller is not DatatokenDeployer`)
|
||||
}
|
||||
|
||||
const estGas = await calculateEstimatedGas(
|
||||
address,
|
||||
dtContract.methods.removeMinter,
|
||||
minter
|
||||
)
|
||||
if (estimateGas) return estGas
|
||||
|
||||
// Call dtContract function of the contract
|
||||
const trxReceipt = await dtContract.methods.removeMinter(minter).send({
|
||||
from: address,
|
||||
gas: estGas + 1,
|
||||
gasPrice: await this.getFairGasPrice()
|
||||
})
|
||||
|
||||
return trxReceipt
|
||||
}
|
||||
|
||||
/**
|
||||
* Add addPaymentManager (can set who's going to collect fee when consuming orders)
|
||||
* only DatatokenDeployer can succeed
|
||||
* @param {String} dtAddress Datatoken address
|
||||
* @param {String} address User address
|
||||
* @param {String} paymentManager User which is going to be a Minter
|
||||
* @return {Promise<TransactionReceipt>} transactionId
|
||||
*/
|
||||
public async addPaymentManager<G extends boolean = false>(
|
||||
dtAddress: string,
|
||||
address: string,
|
||||
paymentManager: string,
|
||||
estimateGas?: G
|
||||
): Promise<G extends false ? TransactionReceipt : number> {
|
||||
const dtContract = this.getContract(dtAddress)
|
||||
|
||||
if ((await this.isDatatokenDeployer(dtAddress, address)) !== true) {
|
||||
throw new Error(`Caller is not DatatokenDeployer`)
|
||||
}
|
||||
|
||||
const estGas = await calculateEstimatedGas(
|
||||
address,
|
||||
dtContract.methods.addPaymentManager,
|
||||
paymentManager
|
||||
)
|
||||
if (estimateGas) return estGas
|
||||
|
||||
// Call addPaymentManager function of the contract
|
||||
const trxReceipt = await dtContract.methods.addPaymentManager(paymentManager).send({
|
||||
from: address,
|
||||
gas: estGas + 1,
|
||||
gasPrice: await this.getFairGasPrice()
|
||||
})
|
||||
|
||||
return trxReceipt
|
||||
}
|
||||
|
||||
/**
|
||||
* Revoke paymentManager permission for an ERC20 Datatoken
|
||||
* only DatatokenDeployer can succeed
|
||||
* @param {String} dtAddress Datatoken address
|
||||
* @param {String} address User address
|
||||
* @param {String} paymentManager User which will be removed from paymentManager permission
|
||||
* @return {Promise<TransactionReceipt>} trxReceipt
|
||||
*/
|
||||
public async removePaymentManager<G extends boolean = false>(
|
||||
dtAddress: string,
|
||||
address: string,
|
||||
paymentManager: string,
|
||||
estimateGas?: G
|
||||
): Promise<G extends false ? TransactionReceipt : number> {
|
||||
const dtContract = this.getContract(dtAddress)
|
||||
|
||||
if ((await this.isDatatokenDeployer(dtAddress, address)) !== true) {
|
||||
throw new Error(`Caller is not DatatokenDeployer`)
|
||||
}
|
||||
|
||||
const estGas = await calculateEstimatedGas(
|
||||
address,
|
||||
dtContract.methods.removePaymentManager,
|
||||
paymentManager
|
||||
)
|
||||
if (estimateGas) return estGas
|
||||
|
||||
// Call removeFeeManager function of the contract
|
||||
const trxReceipt = await dtContract.methods
|
||||
.removePaymentManager(paymentManager)
|
||||
.send({
|
||||
from: address,
|
||||
gas: estGas + 1,
|
||||
gasPrice: await this.getFairGasPrice()
|
||||
})
|
||||
|
||||
return trxReceipt
|
||||
}
|
||||
|
||||
/**
|
||||
* This function allows to set a new PaymentCollector (receives DT when consuming)
|
||||
* If not set the paymentCollector is the NFT Owner
|
||||
* only NFT owner can call
|
||||
* @param dtAddress datatoken address
|
||||
* @param address Caller address
|
||||
* @param paymentCollector User to be set as new payment collector
|
||||
* @return {Promise<TransactionReceipt>} trxReceipt
|
||||
*/
|
||||
public async setPaymentCollector<G extends boolean = false>(
|
||||
dtAddress: string,
|
||||
address: string,
|
||||
paymentCollector: string,
|
||||
estimateGas?: G
|
||||
): Promise<G extends false ? TransactionReceipt : number> {
|
||||
const dtContract = this.getContract(dtAddress)
|
||||
const isPaymentManager = (await this.getPermissions(dtAddress, address))
|
||||
.paymentManager
|
||||
const nftAddress = !isPaymentManager && (await this.getNFTAddress(dtAddress))
|
||||
const isNftOwner = nftAddress && (await this.nft.getNftOwner(nftAddress)) === address
|
||||
const nftPermissions =
|
||||
nftAddress && !isNftOwner && (await this.nft.getNftPermissions(nftAddress, address))
|
||||
const isDatatokenDeployer = nftPermissions?.deployERC20
|
||||
if (!isPaymentManager && !isNftOwner && !isDatatokenDeployer) {
|
||||
throw new Error(`Caller is not Fee Manager, owner or Datatoken Deployer`)
|
||||
}
|
||||
|
||||
const estGas = await calculateEstimatedGas(
|
||||
address,
|
||||
dtContract.methods.setPaymentCollector,
|
||||
paymentCollector
|
||||
)
|
||||
if (estimateGas) return estGas
|
||||
|
||||
// Call setFeeCollector method of the contract
|
||||
const trxReceipt = await dtContract.methods
|
||||
.setPaymentCollector(paymentCollector)
|
||||
.send({
|
||||
from: address,
|
||||
gas: estGas + 1,
|
||||
gasPrice: await this.getFairGasPrice()
|
||||
})
|
||||
|
||||
return trxReceipt
|
||||
}
|
||||
|
||||
/** getPaymentCollector - It returns the current paymentCollector
|
||||
* @param dtAddress datatoken address
|
||||
* @return {Promise<string>}
|
||||
*/
|
||||
public async getPaymentCollector(dtAddress: string): Promise<string> {
|
||||
const dtContract = this.getContract(dtAddress)
|
||||
const paymentCollector = await dtContract.methods.getPaymentCollector().call()
|
||||
return paymentCollector
|
||||
}
|
||||
|
||||
/**
|
||||
* Transfer as number from address to toAddress
|
||||
* @param {String} dtAddress Datatoken address
|
||||
* @param {String} toAddress Receiver address
|
||||
* @param {String} amount Number of datatokens, as number. To be converted to wei.
|
||||
* @param {String} address User adress
|
||||
* @return {Promise<TransactionReceipt>} transactionId
|
||||
*/
|
||||
public async transfer(
|
||||
dtAddress: string,
|
||||
toAddress: string,
|
||||
amount: string,
|
||||
address: string
|
||||
): Promise<TransactionReceipt> {
|
||||
const weiAmount = this.web3.utils.toWei(amount)
|
||||
return this.transferWei(dtAddress, toAddress, weiAmount, address)
|
||||
}
|
||||
|
||||
/**
|
||||
* Transfer in wei from address to toAddress
|
||||
* @param {String} dtAddress Datatoken address
|
||||
* @param {String} toAddress Receiver address
|
||||
* @param {String} amount Number of datatokens, as number. Expressed as wei
|
||||
* @param {String} address User adress
|
||||
* @return {Promise<TransactionReceipt>} transactionId
|
||||
*/
|
||||
public async transferWei<G extends boolean = false>(
|
||||
dtAddress: string,
|
||||
toAddress: string,
|
||||
amount: string,
|
||||
address: string,
|
||||
estimateGas?: G
|
||||
): Promise<G extends false ? TransactionReceipt : number> {
|
||||
const dtContract = this.getContract(dtAddress)
|
||||
try {
|
||||
const estGas = await calculateEstimatedGas(
|
||||
address,
|
||||
dtContract.methods.transfer,
|
||||
toAddress,
|
||||
amount
|
||||
)
|
||||
if (estimateGas) return estGas
|
||||
|
||||
// Call transfer function of the contract
|
||||
const trxReceipt = await dtContract.methods.transfer(toAddress, amount).send({
|
||||
from: address,
|
||||
gas: estGas + 1,
|
||||
gasPrice: await this.getFairGasPrice()
|
||||
})
|
||||
return trxReceipt
|
||||
} catch (e) {
|
||||
LoggerInstance.error(`ERROR: Failed to transfer tokens: ${e.message}`)
|
||||
throw new Error(`Failed Failed to transfer tokens: ${e.message}`)
|
||||
}
|
||||
}
|
||||
|
||||
/** Start Order: called by payer or consumer prior ordering a service consume on a marketplace.
|
||||
* @param {String} dtAddress Datatoken address
|
||||
* @param {String} address User address which calls
|
||||
* @param {String} consumer Consumer Address
|
||||
* @param {Number} serviceIndex Service index in the metadata
|
||||
* @param {providerFees} providerFees provider fees
|
||||
* @param {consumeMarketFee} ConsumeMarketFee consume market fees
|
||||
* @return {Promise<TransactionReceipt>} string
|
||||
*/
|
||||
public async startOrder<G extends boolean = false>(
|
||||
dtAddress: string,
|
||||
address: string,
|
||||
consumer: string,
|
||||
serviceIndex: number,
|
||||
providerFees: ProviderFees,
|
||||
consumeMarketFee?: ConsumeMarketFee,
|
||||
estimateGas?: G
|
||||
): Promise<G extends false ? TransactionReceipt : number> {
|
||||
const dtContract = this.getContract(dtAddress)
|
||||
if (!consumeMarketFee) {
|
||||
consumeMarketFee = {
|
||||
consumeMarketFeeAddress: ZERO_ADDRESS,
|
||||
consumeMarketFeeToken: ZERO_ADDRESS,
|
||||
consumeMarketFeeAmount: '0'
|
||||
}
|
||||
}
|
||||
try {
|
||||
const estGas = await calculateEstimatedGas(
|
||||
address,
|
||||
dtContract.methods.startOrder,
|
||||
consumer,
|
||||
serviceIndex,
|
||||
providerFees,
|
||||
consumeMarketFee
|
||||
)
|
||||
if (estimateGas) return estGas
|
||||
|
||||
const trxReceipt = await dtContract.methods
|
||||
.startOrder(consumer, serviceIndex, providerFees, consumeMarketFee)
|
||||
.send({
|
||||
from: address,
|
||||
gas: estGas + 1,
|
||||
gasPrice: await this.getFairGasPrice()
|
||||
})
|
||||
return trxReceipt
|
||||
} catch (e) {
|
||||
LoggerInstance.error(`ERROR: Failed to start order : ${e.message}`)
|
||||
throw new Error(`Failed to start order: ${e.message}`)
|
||||
}
|
||||
}
|
||||
|
||||
/** Reuse Order: called by payer or consumer having a valid order, but with expired provider access.
|
||||
* Pays the provider fee again, but it will not require a new datatoken payment
|
||||
* Requires previous approval of provider fee.
|
||||
* @param {String} dtAddress Datatoken address
|
||||
* @param {String} address User address which calls
|
||||
* @param {String} orderTxId previous valid order
|
||||
* @param {providerFees} providerFees provider fees
|
||||
* @return {Promise<TransactionReceipt>} string
|
||||
*/
|
||||
public async reuseOrder<G extends boolean = false>(
|
||||
dtAddress: string,
|
||||
address: string,
|
||||
orderTxId: string,
|
||||
providerFees: ProviderFees,
|
||||
estimateGas?: G
|
||||
): Promise<G extends false ? TransactionReceipt : number> {
|
||||
const dtContract = this.getContract(dtAddress)
|
||||
try {
|
||||
const estGas = await calculateEstimatedGas(
|
||||
address,
|
||||
dtContract.methods.reuseOrder,
|
||||
orderTxId,
|
||||
providerFees
|
||||
)
|
||||
if (estimateGas) return estGas
|
||||
|
||||
const trxReceipt = await dtContract.methods
|
||||
.reuseOrder(orderTxId, providerFees)
|
||||
.send({
|
||||
from: address,
|
||||
gas: estGas + 1,
|
||||
gasPrice: await this.getFairGasPrice()
|
||||
})
|
||||
return trxReceipt
|
||||
} catch (e) {
|
||||
LoggerInstance.error(`ERROR: Failed to call reuse order order : ${e.message}`)
|
||||
throw new Error(`Failed to start order: ${e.message}`)
|
||||
}
|
||||
}
|
||||
|
||||
/** Buys 1 DT from the FRE and then startsOrder, while burning that DT
|
||||
* @param {String} dtAddress Datatoken address
|
||||
* @param {String} address User address which calls
|
||||
* @param {OrderParams} orderParams Consumer Address
|
||||
* @param {FreParams} freParams Amount of tokens that is going to be transfered
|
||||
* @return {Promise<TransactionReceipt>}
|
||||
*/
|
||||
public async buyFromFreAndOrder<G extends boolean = false>(
|
||||
dtAddress: string,
|
||||
address: string,
|
||||
orderParams: OrderParams,
|
||||
freParams: FreOrderParams,
|
||||
estimateGas?: G
|
||||
): Promise<G extends false ? TransactionReceipt : number> {
|
||||
const dtContract = this.getContract(dtAddress, null, this.abiEnterprise)
|
||||
try {
|
||||
const freContractParams = this.getFreOrderParams(freParams)
|
||||
|
||||
const estGas = await calculateEstimatedGas(
|
||||
address,
|
||||
dtContract.methods.buyFromFreAndOrder,
|
||||
orderParams,
|
||||
freContractParams
|
||||
)
|
||||
if (estimateGas) return estGas
|
||||
|
||||
const trxReceipt = await dtContract.methods
|
||||
.buyFromFreAndOrder(orderParams, freContractParams)
|
||||
.send({
|
||||
from: address,
|
||||
gas: estGas + 1,
|
||||
gasPrice: await this.getFairGasPrice()
|
||||
})
|
||||
return trxReceipt
|
||||
} catch (e) {
|
||||
LoggerInstance.error(`ERROR: Failed to buy DT From Fre And Order : ${e.message}`)
|
||||
throw new Error(`Failed to buy DT From Fre And Order: ${e.message}`)
|
||||
}
|
||||
}
|
||||
|
||||
/** Gets DT from dispenser and then startsOrder, while burning that DT
|
||||
* @param {String} dtAddress Datatoken address
|
||||
* @param {String} address User address which calls
|
||||
* @param {OrderParams} orderParams
|
||||
* @param {String} dispenserContract
|
||||
* @return {Promise<TransactionReceipt>}
|
||||
*/
|
||||
public async buyFromDispenserAndOrder<G extends boolean = false>(
|
||||
dtAddress: string,
|
||||
address: string,
|
||||
orderParams: OrderParams,
|
||||
dispenserContract: string,
|
||||
estimateGas?: G
|
||||
): Promise<G extends false ? TransactionReceipt : number> {
|
||||
const dtContract = this.getContract(dtAddress, null, this.abiEnterprise)
|
||||
try {
|
||||
const estGas = await calculateEstimatedGas(
|
||||
address,
|
||||
dtContract.methods.buyFromDispenserAndOrder,
|
||||
orderParams,
|
||||
dispenserContract
|
||||
)
|
||||
if (estimateGas) return estGas
|
||||
|
||||
const trxReceipt = await dtContract.methods
|
||||
.buyFromDispenserAndOrder(orderParams, dispenserContract)
|
||||
.send({
|
||||
from: address,
|
||||
gas: estGas + 1,
|
||||
gasPrice: await this.getFairGasPrice()
|
||||
})
|
||||
return trxReceipt
|
||||
} catch (e) {
|
||||
LoggerInstance.error(`ERROR: Failed to buy DT From Fre And Order : ${e.message}`)
|
||||
throw new Error(`Failed to buy DT From Fre And Order: ${e.message}`)
|
||||
}
|
||||
}
|
||||
|
||||
/** setData
|
||||
* This function allows to store data with a preset key (keccak256(dtAddress)) into NFT 725 Store
|
||||
* only DatatokenDeployer can succeed
|
||||
* @param {String} dtAddress Datatoken address
|
||||
* @param {String} address User address
|
||||
* @param {String} value Data to be stored into 725Y standard
|
||||
* @return {Promise<TransactionReceipt>} transactionId
|
||||
*/
|
||||
public async setData<G extends boolean = false>(
|
||||
dtAddress: string,
|
||||
address: string,
|
||||
value: string,
|
||||
estimateGas?: G
|
||||
): Promise<G extends false ? TransactionReceipt : number> {
|
||||
if (!(await this.isDatatokenDeployer(dtAddress, address))) {
|
||||
throw new Error(`User is not Datatoken Deployer`)
|
||||
}
|
||||
|
||||
const dtContract = this.getContract(dtAddress)
|
||||
|
||||
const estGas = await calculateEstimatedGas(address, dtContract.methods.setData, value)
|
||||
if (estimateGas) return estGas
|
||||
|
||||
// Call setData function of the contract
|
||||
const trxReceipt = await dtContract.methods.setData(value).send({
|
||||
from: address,
|
||||
gas: estGas + 1,
|
||||
gasPrice: await this.getFairGasPrice()
|
||||
})
|
||||
|
||||
return trxReceipt
|
||||
}
|
||||
|
||||
/**
|
||||
* Clean Datatoken level Permissions (minters, paymentManager and reset the paymentCollector) for an ERC20 Datatoken
|
||||
* Only NFT Owner (at 721 level) can call it.
|
||||
* @param dtAddress Datatoken address where we want to clean permissions
|
||||
* @param address User adress
|
||||
* @return {Promise<TransactionReceipt>} transactionId
|
||||
*/
|
||||
public async cleanPermissions<G extends boolean = false>(
|
||||
dtAddress: string,
|
||||
address: string,
|
||||
estimateGas?: G
|
||||
): Promise<G extends false ? TransactionReceipt : number> {
|
||||
if ((await this.nft.getNftOwner(await this.getNFTAddress(dtAddress))) !== address) {
|
||||
throw new Error('Caller is NOT Nft Owner')
|
||||
}
|
||||
const dtContract = this.getContract(dtAddress)
|
||||
|
||||
const estGas = await calculateEstimatedGas(
|
||||
address,
|
||||
dtContract.methods.cleanPermissions
|
||||
)
|
||||
if (estimateGas) return estGas
|
||||
|
||||
// Call cleanPermissions function of the contract
|
||||
const trxReceipt = await dtContract.methods.cleanPermissions().send({
|
||||
from: address,
|
||||
gas: estGas + 1,
|
||||
gasPrice: await this.getFairGasPrice()
|
||||
})
|
||||
|
||||
return trxReceipt
|
||||
}
|
||||
|
||||
/** Returns ERC20 Datatoken user's permissions for a datatoken
|
||||
* @param {String} dtAddress Datatoken adress
|
||||
* @param {String} address user adress
|
||||
* @return {Promise<DatatokenRoles>}
|
||||
*/
|
||||
public async getPermissions(
|
||||
dtAddress: string,
|
||||
address: string
|
||||
): Promise<DatatokenRoles> {
|
||||
const dtContract = this.getContract(dtAddress)
|
||||
const roles = await dtContract.methods.permissions(address).call()
|
||||
return roles
|
||||
}
|
||||
|
||||
/** Returns the Datatoken capital
|
||||
* @param {String} dtAddress Datatoken adress
|
||||
* @return {Promise<string>}
|
||||
*/
|
||||
public async getCap(dtAddress: string): Promise<string> {
|
||||
const dtContract = this.getContract(dtAddress)
|
||||
const cap = await dtContract.methods.cap().call()
|
||||
return this.web3.utils.fromWei(cap)
|
||||
}
|
||||
|
||||
/** It returns the token decimals, how many supported decimal points
|
||||
* @param {String} dtAddress Datatoken adress
|
||||
* @return {Promise<number>}
|
||||
*/
|
||||
public async getDecimals(dtAddress: string): Promise<string> {
|
||||
const dtContract = this.getContract(dtAddress)
|
||||
const decimals = await dtContract.methods.decimals().call()
|
||||
return decimals
|
||||
}
|
||||
|
||||
/** It returns the token decimals, how many supported decimal points
|
||||
* @param {String} dtAddress Datatoken adress
|
||||
* @return {Promise<number>}
|
||||
*/
|
||||
public async getNFTAddress(dtAddress: string): Promise<string> {
|
||||
const dtContract = this.getContract(dtAddress)
|
||||
const nftAddress = await dtContract.methods.getERC721Address().call()
|
||||
return nftAddress
|
||||
}
|
||||
|
||||
/** Returns true if address has deployERC20 role
|
||||
* @param {String} dtAddress Datatoken adress
|
||||
* @param {String} dtAddress Datatoken adress
|
||||
* @return {Promise<boolean>}
|
||||
*/
|
||||
public async isDatatokenDeployer(dtAddress: string, address: string): Promise<boolean> {
|
||||
const dtContract = this.getContract(dtAddress)
|
||||
const isDatatokenDeployer = await dtContract.methods.isERC20Deployer(address).call()
|
||||
return isDatatokenDeployer
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Address Balance for datatoken
|
||||
* @param {String} dtAddress Datatoken adress
|
||||
* @param {String} address user adress
|
||||
* @return {Promise<String>} balance Number of datatokens. Will be converted from wei
|
||||
*/
|
||||
public async balance(datatokenAddress: string, address: string): Promise<string> {
|
||||
const dtContract = this.getContract(datatokenAddress, address)
|
||||
const balance = await dtContract.methods.balanceOf(address).call()
|
||||
return this.web3.utils.fromWei(balance)
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev setPublishingMarketFee
|
||||
* Only publishMarketFeeAddress can call it
|
||||
* This function allows to set the fee required by the publisherMarket
|
||||
* @param {string} datatokenAddress Datatoken adress
|
||||
* @param {string} publishMarketFeeAddress new publish Market Fee Address
|
||||
* @param {string} publishMarketFeeToken new publish Market Fee Token
|
||||
* @param {string} publishMarketFeeAmount new fee amount
|
||||
* @param {String} address user adress
|
||||
*/
|
||||
public async setPublishingMarketFee<G extends boolean = false>(
|
||||
datatokenAddress: string,
|
||||
publishMarketFeeAddress: string,
|
||||
publishMarketFeeToken: string,
|
||||
publishMarketFeeAmount: string,
|
||||
address: string,
|
||||
estimateGas?: G
|
||||
): Promise<G extends false ? TransactionReceipt : number> {
|
||||
const dtContract = this.getContract(datatokenAddress, address)
|
||||
const mktFeeAddress = (await dtContract.methods.getPublishingMarketFee().call())[0]
|
||||
if (mktFeeAddress !== address) {
|
||||
throw new Error(`Caller is not the Publishing Market Fee Address`)
|
||||
}
|
||||
const estGas = await calculateEstimatedGas(
|
||||
address,
|
||||
dtContract.methods.setPublishingMarketFee,
|
||||
publishMarketFeeAddress,
|
||||
publishMarketFeeToken,
|
||||
publishMarketFeeAmount
|
||||
)
|
||||
if (estimateGas) return estGas
|
||||
|
||||
const trxReceipt = await dtContract.methods
|
||||
.setPublishingMarketFee(
|
||||
publishMarketFeeAddress,
|
||||
publishMarketFeeToken,
|
||||
publishMarketFeeAmount
|
||||
)
|
||||
.send({
|
||||
from: address,
|
||||
gas: estGas + 1,
|
||||
gasPrice: await this.getFairGasPrice()
|
||||
})
|
||||
|
||||
return trxReceipt
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev getPublishingMarketFee
|
||||
* Get publishingMarket Fee
|
||||
* This function allows to get the current fee set by the publishing market
|
||||
* @param {String} datatokenAddress Datatoken adress
|
||||
* @param {String} address user adress
|
||||
* @return {Promise<PublishingMarketFee>} Current fee set by the publishing market
|
||||
*/
|
||||
public async getPublishingMarketFee(
|
||||
datatokenAddress: string,
|
||||
address: string
|
||||
): Promise<PublishingMarketFee> {
|
||||
const dtContract = this.getContract(datatokenAddress, address)
|
||||
|
||||
const publishingMarketFee = await dtContract.methods.getPublishingMarketFee().call()
|
||||
const returnValues = {
|
||||
publishMarketFeeAddress: publishingMarketFee[0],
|
||||
publishMarketFeeToken: publishingMarketFee[1],
|
||||
publishMarketFeeAmount: publishingMarketFee[2]
|
||||
}
|
||||
return returnValues
|
||||
}
|
||||
|
||||
private getFreOrderParams(freParams: FreOrderParams): any {
|
||||
return {
|
||||
exchangeContract: freParams.exchangeContract,
|
||||
exchangeId: freParams.exchangeId,
|
||||
maxBaseTokenAmount: Web3.utils.toWei(freParams.maxBaseTokenAmount),
|
||||
swapMarketFee: Web3.utils.toWei(freParams.swapMarketFee),
|
||||
marketFeeAddress: freParams.marketFeeAddress
|
||||
}
|
||||
}
|
||||
}
|
750
src/contracts/tokens/NFT.ts
Normal file
750
src/contracts/tokens/NFT.ts
Normal file
@ -0,0 +1,750 @@
|
||||
import { AbiItem } from 'web3-utils'
|
||||
import { TransactionReceipt } from 'web3-eth'
|
||||
import ERC721Template from '@oceanprotocol/contracts/artifacts/contracts/templates/ERC721Template.sol/ERC721Template.json'
|
||||
import { LoggerInstance, generateDtName, calculateEstimatedGas } from '../../utils'
|
||||
import { MetadataProof, MetadataAndTokenURI, NftRoles } from '../../@types'
|
||||
import { SmartContract } from '..'
|
||||
|
||||
export class Nft extends SmartContract {
|
||||
getDefaultAbi(): AbiItem | AbiItem[] {
|
||||
return ERC721Template.abi as AbiItem[]
|
||||
}
|
||||
|
||||
/**
|
||||
* Create new ERC20 Datatoken - only user with DatatokenDeployer permission can succeed
|
||||
* @param {String} nftAddress NFT address
|
||||
* @param {String} address User address
|
||||
* @param {String} minter User set as initial minter for the Datatoken
|
||||
* @param {String} paymentCollector initial paymentCollector for this DT
|
||||
* @param {String} mpFeeAddress Consume marketplace fee address
|
||||
* @param {String} feeToken address of the token marketplace wants to add fee on top
|
||||
* @param {String} feeAmount amount of feeToken to be transferred to mpFeeAddress on top, will be converted to WEI
|
||||
* @param {String} cap Maximum cap (Number) - will be converted to wei
|
||||
* @param {String} name Token name
|
||||
* @param {String} symbol Token symbol
|
||||
* @param {Number} templateIndex NFT template index
|
||||
* @return {Promise<string>} ERC20 Datatoken address
|
||||
*/
|
||||
public async createDatatoken<G extends boolean = false>(
|
||||
nftAddress: string,
|
||||
address: string,
|
||||
minter: string,
|
||||
paymentCollector: string,
|
||||
mpFeeAddress: string,
|
||||
feeToken: string,
|
||||
feeAmount: string,
|
||||
cap: string,
|
||||
name?: string,
|
||||
symbol?: string,
|
||||
templateIndex?: number,
|
||||
estimateGas?: G
|
||||
): Promise<G extends false ? string : number> {
|
||||
if ((await this.getNftPermissions(nftAddress, address)).deployERC20 !== true) {
|
||||
throw new Error(`Caller is not DatatokenDeployer`)
|
||||
}
|
||||
if (!templateIndex) templateIndex = 1
|
||||
|
||||
// Generate name & symbol if not present
|
||||
if (!name || !symbol) {
|
||||
;({ name, symbol } = generateDtName())
|
||||
}
|
||||
|
||||
// Create 721contract object
|
||||
const nftContract = this.getContract(nftAddress)
|
||||
|
||||
const estGas = await calculateEstimatedGas(
|
||||
address,
|
||||
nftContract.methods.createERC20,
|
||||
templateIndex,
|
||||
[name, symbol],
|
||||
[minter, paymentCollector, mpFeeAddress, feeToken],
|
||||
[this.web3.utils.toWei(cap), this.web3.utils.toWei(feeAmount)],
|
||||
[]
|
||||
)
|
||||
if (estimateGas) return estGas
|
||||
|
||||
// Call createERC20 token function of the contract
|
||||
const trxReceipt = await nftContract.methods
|
||||
.createERC20(
|
||||
templateIndex,
|
||||
[name, symbol],
|
||||
[minter, paymentCollector, mpFeeAddress, feeToken],
|
||||
[this.web3.utils.toWei(cap), this.web3.utils.toWei(feeAmount)],
|
||||
[]
|
||||
)
|
||||
.send({
|
||||
from: address,
|
||||
gas: estGas + 1,
|
||||
gasPrice: await this.getFairGasPrice()
|
||||
})
|
||||
|
||||
let tokenAddress = null
|
||||
try {
|
||||
tokenAddress = trxReceipt.events.TokenCreated.returnValues[0]
|
||||
} catch (e) {
|
||||
LoggerInstance.error(`ERROR: Failed to create datatoken : ${e.message}`)
|
||||
}
|
||||
return tokenAddress
|
||||
}
|
||||
|
||||
/**
|
||||
* Add Manager for NFT Contract (only NFT Owner can succeed)
|
||||
* @param {String} nftAddress NFT contract address
|
||||
* @param {String} address NFT Owner adress
|
||||
* @param {String} manager User adress which is going to be assing manager
|
||||
* @return {Promise<TransactionReceipt>} trxReceipt
|
||||
*/
|
||||
public async addManager<G extends boolean = false>(
|
||||
nftAddress: string,
|
||||
address: string,
|
||||
manager: string,
|
||||
estimateGas?: G
|
||||
): Promise<G extends false ? TransactionReceipt : number> {
|
||||
const nftContract = this.getContract(nftAddress)
|
||||
|
||||
if ((await this.getNftOwner(nftAddress)) !== address) {
|
||||
throw new Error(`Caller is not NFT Owner`)
|
||||
}
|
||||
|
||||
const estGas = await calculateEstimatedGas(
|
||||
address,
|
||||
nftContract.methods.addManager,
|
||||
manager
|
||||
)
|
||||
if (estimateGas) return estGas
|
||||
|
||||
// Invoke addManager function of the contract
|
||||
const trxReceipt = await nftContract.methods.addManager(manager).send({
|
||||
from: address,
|
||||
gas: estGas + 1,
|
||||
gasPrice: await this.getFairGasPrice()
|
||||
})
|
||||
|
||||
return trxReceipt
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes a specific manager for NFT Contract (only NFT Owner can succeed)
|
||||
* @param {String} nftAddress NFT contract address
|
||||
* @param {String} address NFT Owner adress
|
||||
* @param {String} manager User adress which is going to be removed as manager
|
||||
* @return {Promise<TransactionReceipt>} trxReceipt
|
||||
*/
|
||||
public async removeManager<G extends boolean = false>(
|
||||
nftAddress: string,
|
||||
address: string,
|
||||
manager: string,
|
||||
estimateGas?: G
|
||||
): Promise<G extends false ? TransactionReceipt : number> {
|
||||
const nftContract = this.getContract(nftAddress)
|
||||
|
||||
if ((await this.getNftOwner(nftAddress)) !== address) {
|
||||
throw new Error(`Caller is not NFT Owner`)
|
||||
}
|
||||
|
||||
const estGas = await calculateEstimatedGas(
|
||||
address,
|
||||
nftContract.methods.removeManager,
|
||||
manager
|
||||
)
|
||||
if (estimateGas) return estGas
|
||||
|
||||
// Invoke removeManager function of the contract
|
||||
const trxReceipt = await nftContract.methods.removeManager(manager).send({
|
||||
from: address,
|
||||
gas: estGas + 1,
|
||||
gasPrice: await this.getFairGasPrice()
|
||||
})
|
||||
|
||||
return trxReceipt
|
||||
}
|
||||
|
||||
/**
|
||||
* Add DatatokenDeployer permission - only Manager can succeed
|
||||
* @param {String} nftAddress NFT contract address
|
||||
* @param {String} address NFT Manager adress
|
||||
* @param {String} datatokenDeployer User adress which is going to have DatatokenDeployer permission
|
||||
* @return {Promise<TransactionReceipt>} trxReceipt
|
||||
*/
|
||||
public async addDatatokenDeployer<G extends boolean = false>(
|
||||
nftAddress: string,
|
||||
address: string,
|
||||
datatokenDeployer: string,
|
||||
estimateGas?: G
|
||||
): Promise<G extends false ? TransactionReceipt : number> {
|
||||
const nftContract = this.getContract(nftAddress)
|
||||
|
||||
if ((await this.getNftPermissions(nftAddress, address)).manager !== true) {
|
||||
throw new Error(`Caller is not Manager`)
|
||||
}
|
||||
|
||||
// Estimate gas for addToCreateERC20List method
|
||||
const estGas = await calculateEstimatedGas(
|
||||
address,
|
||||
nftContract.methods.addToCreateERC20List,
|
||||
datatokenDeployer
|
||||
)
|
||||
if (estimateGas) return estGas
|
||||
|
||||
// Invoke addToCreateERC20List function of the contract
|
||||
const trxReceipt = await nftContract.methods
|
||||
.addToCreateERC20List(datatokenDeployer)
|
||||
.send({
|
||||
from: address,
|
||||
gas: estGas + 1,
|
||||
gasPrice: await this.getFairGasPrice()
|
||||
})
|
||||
|
||||
return trxReceipt
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove DatatokenDeployer permission - only Manager can succeed
|
||||
* @param {String} nftAddress NFT contract address
|
||||
* @param {String} address NFT Manager adress
|
||||
* @param {String} datatokenDeployer Address of the user to be revoked DatatokenDeployer Permission
|
||||
* @return {Promise<TransactionReceipt>} trxReceipt
|
||||
*/
|
||||
public async removeDatatokenDeployer<G extends boolean = false>(
|
||||
nftAddress: string,
|
||||
address: string,
|
||||
datatokenDeployer: string,
|
||||
estimateGas?: G
|
||||
): Promise<G extends false ? TransactionReceipt : number> {
|
||||
const nftContract = this.getContract(nftAddress)
|
||||
|
||||
if (
|
||||
(await this.getNftPermissions(nftAddress, address)).manager !== true ||
|
||||
(address === datatokenDeployer &&
|
||||
(await this.getNftPermissions(nftAddress, address)).deployERC20 !== true)
|
||||
) {
|
||||
throw new Error(`Caller is not Manager nor DatatokenDeployer`)
|
||||
}
|
||||
const estGas = await calculateEstimatedGas(
|
||||
address,
|
||||
nftContract.methods.removeFromCreateERC20List,
|
||||
datatokenDeployer
|
||||
)
|
||||
if (estimateGas) return estGas
|
||||
|
||||
// Call removeFromCreateERC20List function of the contract
|
||||
const trxReceipt = await nftContract.methods
|
||||
.removeFromCreateERC20List(datatokenDeployer)
|
||||
.send({
|
||||
from: address,
|
||||
gas: estGas + 1,
|
||||
gasPrice: await this.getFairGasPrice()
|
||||
})
|
||||
|
||||
return trxReceipt
|
||||
}
|
||||
|
||||
/**
|
||||
* Add Metadata Updater permission - only Manager can succeed
|
||||
* @param {String} nftAddress NFT contract address
|
||||
* @param {String} address NFT Manager adress
|
||||
* @param {String} metadataUpdater User adress which is going to have Metadata Updater permission
|
||||
* @return {Promise<TransactionReceipt>} trxReceipt
|
||||
*/
|
||||
public async addMetadataUpdater<G extends boolean = false>(
|
||||
nftAddress: string,
|
||||
address: string,
|
||||
metadataUpdater: string,
|
||||
estimateGas?: G
|
||||
): Promise<G extends false ? TransactionReceipt : number> {
|
||||
const nftContract = this.getContract(nftAddress)
|
||||
|
||||
if ((await this.getNftPermissions(nftAddress, address)).manager !== true) {
|
||||
throw new Error(`Caller is not Manager`)
|
||||
}
|
||||
|
||||
const estGas = await calculateEstimatedGas(
|
||||
address,
|
||||
nftContract.methods.addToMetadataList,
|
||||
metadataUpdater
|
||||
)
|
||||
if (estimateGas) return estGas
|
||||
|
||||
// Call addToMetadataList function of the contract
|
||||
const trxReceipt = await nftContract.methods.addToMetadataList(metadataUpdater).send({
|
||||
from: address,
|
||||
gas: estGas + 1,
|
||||
gasPrice: await this.getFairGasPrice()
|
||||
})
|
||||
|
||||
return trxReceipt
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove Metadata Updater permission - only Manager can succeed
|
||||
* @param {String} nftAddress NFT contract address
|
||||
* @param {String} address NFT Manager adress
|
||||
* @param {String} metadataUpdater Address of the user to be revoked Metadata updater Permission
|
||||
* @return {Promise<TransactionReceipt>} trxReceipt
|
||||
*/
|
||||
public async removeMetadataUpdater<G extends boolean = false>(
|
||||
nftAddress: string,
|
||||
address: string,
|
||||
metadataUpdater: string,
|
||||
estimateGas?: G
|
||||
): Promise<G extends false ? TransactionReceipt : number> {
|
||||
const nftContract = this.getContract(nftAddress)
|
||||
|
||||
if (
|
||||
(await this.getNftPermissions(nftAddress, address)).manager !== true ||
|
||||
(address !== metadataUpdater &&
|
||||
(await this.getNftPermissions(nftAddress, address)).updateMetadata !== true)
|
||||
) {
|
||||
throw new Error(`Caller is not Manager nor Metadata Updater`)
|
||||
}
|
||||
|
||||
const estGas = await calculateEstimatedGas(
|
||||
address,
|
||||
nftContract.methods.removeFromMetadataList,
|
||||
metadataUpdater
|
||||
)
|
||||
if (estimateGas) return estGas
|
||||
|
||||
// Call removeFromMetadataList function of the contract
|
||||
const trxReceipt = await nftContract.methods
|
||||
.removeFromMetadataList(metadataUpdater)
|
||||
.send({
|
||||
from: address,
|
||||
gas: estGas + 1,
|
||||
gasPrice: await this.getFairGasPrice()
|
||||
})
|
||||
|
||||
return trxReceipt
|
||||
}
|
||||
|
||||
/**
|
||||
* Add Store Updater permission - only Manager can succeed
|
||||
* @param {String} nftAddress NFT contract address
|
||||
* @param {String} address NFT Manager adress
|
||||
* @param {String} storeUpdater User adress which is going to have Store Updater permission
|
||||
* @return {Promise<TransactionReceipt>} trxReceipt
|
||||
*/
|
||||
public async addStoreUpdater<G extends boolean = false>(
|
||||
nftAddress: string,
|
||||
address: string,
|
||||
storeUpdater: string,
|
||||
estimateGas?: G
|
||||
): Promise<G extends false ? TransactionReceipt : number> {
|
||||
const nftContract = this.getContract(nftAddress)
|
||||
|
||||
if ((await this.getNftPermissions(nftAddress, address)).manager !== true) {
|
||||
throw new Error(`Caller is not Manager`)
|
||||
}
|
||||
|
||||
const estGas = await calculateEstimatedGas(
|
||||
address,
|
||||
nftContract.methods.addTo725StoreList,
|
||||
storeUpdater
|
||||
)
|
||||
if (estimateGas) return estGas
|
||||
|
||||
// Call addTo725StoreList function of the contract
|
||||
const trxReceipt = await nftContract.methods.addTo725StoreList(storeUpdater).send({
|
||||
from: address,
|
||||
gas: estGas + 1,
|
||||
gasPrice: await this.getFairGasPrice()
|
||||
})
|
||||
|
||||
return trxReceipt
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove Store Updater permission - only Manager can succeed
|
||||
* @param {String} nftAddress NFT contract address
|
||||
* @param {String} address NFT Manager adress
|
||||
* @param {String} storeUpdater Address of the user to be revoked Store Updater Permission
|
||||
* @return {Promise<TransactionReceipt>} trxReceipt
|
||||
*/
|
||||
public async removeStoreUpdater<G extends boolean = false>(
|
||||
nftAddress: string,
|
||||
address: string,
|
||||
storeUpdater: string,
|
||||
estimateGas?: G
|
||||
): Promise<G extends false ? TransactionReceipt : number> {
|
||||
const nftContract = this.getContract(nftAddress)
|
||||
|
||||
if (
|
||||
(await this.getNftPermissions(nftAddress, address)).manager !== true ||
|
||||
(address !== storeUpdater &&
|
||||
(await this.getNftPermissions(nftAddress, address)).store !== true)
|
||||
) {
|
||||
throw new Error(`Caller is not Manager nor storeUpdater`)
|
||||
}
|
||||
|
||||
const estGas = await calculateEstimatedGas(
|
||||
address,
|
||||
nftContract.methods.removeFrom725StoreList,
|
||||
storeUpdater
|
||||
)
|
||||
if (estimateGas) return estGas
|
||||
|
||||
// Call removeFrom725StoreList function of the contract
|
||||
const trxReceipt = await nftContract.methods
|
||||
.removeFrom725StoreList(storeUpdater)
|
||||
.send({
|
||||
from: address,
|
||||
gas: estGas + 1,
|
||||
gasPrice: await this.getFairGasPrice()
|
||||
})
|
||||
|
||||
return trxReceipt
|
||||
}
|
||||
|
||||
/**
|
||||
* This function allows to remove all ROLES at NFT level: Managers, DatatokenDeployer, MetadataUpdater, StoreUpdater
|
||||
* Even NFT Owner has to readd himself as Manager
|
||||
* Permissions at Datatoken level stay.
|
||||
* Only NFT Owner can call it.
|
||||
* @param {String} nftAddress NFT contract address
|
||||
* @param {String} address NFT Owner adress
|
||||
* @return {Promise<TransactionReceipt>} trxReceipt
|
||||
*/
|
||||
public async cleanPermissions<G extends boolean = false>(
|
||||
nftAddress: string,
|
||||
address: string,
|
||||
estimateGas?: G
|
||||
): Promise<G extends false ? TransactionReceipt : number> {
|
||||
const nftContract = this.getContract(nftAddress)
|
||||
|
||||
if ((await this.getNftOwner(nftAddress)) !== address) {
|
||||
throw new Error(`Caller is not NFT Owner`)
|
||||
}
|
||||
|
||||
const estGas = await calculateEstimatedGas(
|
||||
address,
|
||||
nftContract.methods.cleanPermissions
|
||||
)
|
||||
if (estimateGas) return estGas
|
||||
|
||||
// Call cleanPermissions function of the contract
|
||||
const trxReceipt = await nftContract.methods.cleanPermissions().send({
|
||||
from: address,
|
||||
gas: estGas + 1,
|
||||
gasPrice: await this.getFairGasPrice()
|
||||
})
|
||||
|
||||
return trxReceipt
|
||||
}
|
||||
|
||||
/**
|
||||
* Transfers the NFT
|
||||
* will clean all permissions both on NFT and Datatoken level.
|
||||
* @param {String} nftAddress NFT contract address
|
||||
* @param {String} nftOwner Current NFT Owner adress
|
||||
* @param {String} nftReceiver User which will receive the NFT, will also be set as Manager
|
||||
* @param {Number} tokenId The id of the token to be transfered
|
||||
* @return {Promise<TransactionReceipt>} trxReceipt
|
||||
*/
|
||||
public async transferNft<G extends boolean = false>(
|
||||
nftAddress: string,
|
||||
nftOwner: string,
|
||||
nftReceiver: string,
|
||||
tokenId?: number,
|
||||
estimateGas?: G
|
||||
): Promise<G extends false ? TransactionReceipt : number> {
|
||||
const nftContract = this.getContract(nftAddress)
|
||||
|
||||
if ((await this.getNftOwner(nftAddress)) !== nftOwner) {
|
||||
throw new Error(`Caller is not NFT Owner`)
|
||||
}
|
||||
|
||||
const tokenIdentifier = tokenId || 1
|
||||
|
||||
const estGas = await calculateEstimatedGas(
|
||||
nftOwner,
|
||||
nftContract.methods.transferFrom,
|
||||
nftOwner,
|
||||
nftReceiver,
|
||||
tokenIdentifier
|
||||
)
|
||||
if (estimateGas) return estGas
|
||||
|
||||
// Call transferFrom function of the contract
|
||||
const trxReceipt = await nftContract.methods
|
||||
.transferFrom(nftOwner, nftReceiver, tokenIdentifier)
|
||||
.send({
|
||||
from: nftOwner,
|
||||
gas: estGas + 1,
|
||||
gasPrice: await this.getFairGasPrice()
|
||||
})
|
||||
|
||||
return trxReceipt
|
||||
}
|
||||
|
||||
/**
|
||||
* safeTransferNFT Used for transferring the NFT, can be used by an approved relayer
|
||||
* will clean all permissions both on NFT and Datatoken level.
|
||||
* @param {String} nftAddress NFT contract address
|
||||
* @param {String} nftOwner Current NFT Owner adress
|
||||
* @param {String} nftReceiver User which will receive the NFT, will also be set as Manager
|
||||
* @param {Number} tokenId The id of the token to be transfered
|
||||
* @return {Promise<TransactionReceipt>} trxReceipt
|
||||
*/
|
||||
public async safeTransferNft<G extends boolean = false>(
|
||||
nftAddress: string,
|
||||
nftOwner: string,
|
||||
nftReceiver: string,
|
||||
tokenId?: number,
|
||||
estimateGas?: G
|
||||
): Promise<G extends false ? TransactionReceipt : number> {
|
||||
const nftContract = this.getContract(nftAddress)
|
||||
|
||||
if ((await this.getNftOwner(nftAddress)) !== nftOwner) {
|
||||
throw new Error(`Caller is not NFT Owner`)
|
||||
}
|
||||
|
||||
const tokenIdentifier = tokenId || 1
|
||||
|
||||
const estGas = await calculateEstimatedGas(
|
||||
nftOwner,
|
||||
nftContract.methods.safeTransferFrom,
|
||||
nftOwner,
|
||||
nftReceiver,
|
||||
tokenIdentifier
|
||||
)
|
||||
if (estimateGas) return estGas
|
||||
|
||||
// Call transferFrom function of the contract
|
||||
const trxReceipt = await nftContract.methods
|
||||
.safeTransferFrom(nftOwner, nftReceiver, tokenIdentifier)
|
||||
.send({
|
||||
from: nftOwner,
|
||||
gas: estGas + 1,
|
||||
gasPrice: await this.getFairGasPrice()
|
||||
})
|
||||
|
||||
return trxReceipt
|
||||
}
|
||||
|
||||
/**
|
||||
* safeTransferNFT Used for transferring the NFT, can be used by an approved relayer
|
||||
* will clean all permissions both on NFT and Datatoken level.
|
||||
* @param {String} nftAddress NFT contract address
|
||||
* @param {String} address Caller address NFT Owner adress
|
||||
* @return {Promise<TransactionReceipt>} trxReceipt
|
||||
*/
|
||||
public async setMetadata<G extends boolean = false>(
|
||||
nftAddress: string,
|
||||
address: string,
|
||||
metadataState: number,
|
||||
metadataDecryptorUrl: string,
|
||||
metadataDecryptorAddress: string,
|
||||
flags: string,
|
||||
data: string,
|
||||
metadataHash: string,
|
||||
metadataProofs?: MetadataProof[],
|
||||
estimateGas?: G
|
||||
): Promise<G extends false ? TransactionReceipt : number> {
|
||||
const nftContract = this.getContract(nftAddress)
|
||||
if (!metadataProofs) metadataProofs = []
|
||||
if (!(await this.getNftPermissions(nftAddress, address)).updateMetadata) {
|
||||
throw new Error(`Caller is not Metadata updater`)
|
||||
}
|
||||
const estGas = await calculateEstimatedGas(
|
||||
address,
|
||||
nftContract.methods.setMetaData,
|
||||
metadataState,
|
||||
metadataDecryptorUrl,
|
||||
metadataDecryptorAddress,
|
||||
flags,
|
||||
data,
|
||||
metadataHash,
|
||||
metadataProofs
|
||||
)
|
||||
if (estimateGas) return estGas
|
||||
|
||||
const trxReceipt = await nftContract.methods
|
||||
.setMetaData(
|
||||
metadataState,
|
||||
metadataDecryptorUrl,
|
||||
metadataDecryptorAddress,
|
||||
flags,
|
||||
data,
|
||||
metadataHash,
|
||||
metadataProofs
|
||||
)
|
||||
.send({
|
||||
from: address,
|
||||
gas: estGas + 1,
|
||||
gasPrice: await this.getFairGasPrice()
|
||||
})
|
||||
|
||||
return trxReceipt
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper function to improve UX sets both MetaData & TokenURI in one tx
|
||||
* @param {String} nftAddress NFT contract address
|
||||
* @param {String} address Caller address
|
||||
* @param {MetadataAndTokenURI} metadataAndTokenURI metaDataAndTokenURI object
|
||||
* @return {Promise<TransactionReceipt>} trxReceipt
|
||||
*/
|
||||
public async setMetadataAndTokenURI<G extends boolean = false>(
|
||||
nftAddress: string,
|
||||
metadataUpdater: string,
|
||||
metadataAndTokenURI: MetadataAndTokenURI,
|
||||
estimateGas?: G
|
||||
): Promise<G extends false ? TransactionReceipt : number> {
|
||||
const nftContract = this.getContract(nftAddress)
|
||||
if (!(await this.getNftPermissions(nftAddress, metadataUpdater)).updateMetadata) {
|
||||
throw new Error(`Caller is not Metadata updater`)
|
||||
}
|
||||
const sanitizedMetadataAndTokenURI = {
|
||||
...metadataAndTokenURI,
|
||||
metadataProofs: metadataAndTokenURI.metadataProofs || []
|
||||
}
|
||||
const estGas = await calculateEstimatedGas(
|
||||
metadataUpdater,
|
||||
nftContract.methods.setMetaDataAndTokenURI,
|
||||
sanitizedMetadataAndTokenURI
|
||||
)
|
||||
if (estimateGas) return estGas
|
||||
|
||||
const trxReceipt = await nftContract.methods
|
||||
.setMetaDataAndTokenURI(sanitizedMetadataAndTokenURI)
|
||||
.send({
|
||||
from: metadataUpdater,
|
||||
gas: estGas + 1,
|
||||
gasPrice: await this.getFairGasPrice()
|
||||
})
|
||||
|
||||
return trxReceipt
|
||||
}
|
||||
|
||||
/**
|
||||
* setMetadataState Used for updating the metadata State
|
||||
* @param {String} nftAddress NFT contract address
|
||||
* @param {String} address Caller address => metadata updater
|
||||
* @param {Number} metadataState new metadata state
|
||||
* @return {Promise<TransactionReceipt>} trxReceipt
|
||||
*/
|
||||
public async setMetadataState<G extends boolean = false>(
|
||||
nftAddress: string,
|
||||
address: string,
|
||||
metadataState: number,
|
||||
estimateGas?: G
|
||||
): Promise<G extends false ? TransactionReceipt : number> {
|
||||
const nftContract = this.getContract(nftAddress)
|
||||
|
||||
if (!(await this.getNftPermissions(nftAddress, address)).updateMetadata) {
|
||||
throw new Error(`Caller is not Metadata updater`)
|
||||
}
|
||||
|
||||
const estGas = await calculateEstimatedGas(
|
||||
address,
|
||||
nftContract.methods.setMetaDataState,
|
||||
metadataState
|
||||
)
|
||||
if (estimateGas) return estGas
|
||||
|
||||
// Call transferFrom function of the contract
|
||||
const trxReceipt = await nftContract.methods.setMetaDataState(metadataState).send({
|
||||
from: address,
|
||||
gas: estGas + 1,
|
||||
gasPrice: await this.getFairGasPrice()
|
||||
})
|
||||
|
||||
return trxReceipt
|
||||
}
|
||||
|
||||
/** set TokenURI on an nft
|
||||
* @param nftAddress NFT contract address
|
||||
* @param address user adress
|
||||
* @param data input data for TokenURI
|
||||
* @return {Promise<TransactionReceipt>} transaction receipt
|
||||
*/
|
||||
public async setTokenURI<G extends boolean = false>(
|
||||
nftAddress: string,
|
||||
address: string,
|
||||
data: string,
|
||||
estimateGas?: G
|
||||
): Promise<G extends false ? TransactionReceipt : number> {
|
||||
const nftContract = this.getContract(nftAddress)
|
||||
|
||||
const estGas = await calculateEstimatedGas(
|
||||
address,
|
||||
nftContract.methods.setTokenURI,
|
||||
'1',
|
||||
data
|
||||
)
|
||||
if (estimateGas) return estGas
|
||||
|
||||
const trxReceipt = await nftContract.methods.setTokenURI('1', data).send({
|
||||
from: address,
|
||||
gas: estGas + 1,
|
||||
gasPrice: await this.getFairGasPrice()
|
||||
})
|
||||
return trxReceipt
|
||||
}
|
||||
|
||||
/** Get Owner
|
||||
* @param {String} nftAddress NFT contract address
|
||||
* @return {Promise<string>} string
|
||||
*/
|
||||
public async getNftOwner(nftAddress: string): Promise<string> {
|
||||
const nftContract = this.getContract(nftAddress)
|
||||
const trxReceipt = await nftContract.methods.ownerOf(1).call()
|
||||
return trxReceipt
|
||||
}
|
||||
|
||||
/** Get users NFT Permissions
|
||||
* @param {String} nftAddress NFT contract address
|
||||
* @param {String} address user adress
|
||||
* @return {Promise<NftRoles>}
|
||||
*/
|
||||
public async getNftPermissions(nftAddress: string, address: string): Promise<NftRoles> {
|
||||
const nftContract = this.getContract(nftAddress)
|
||||
const roles = await nftContract.methods.getPermissions(address).call()
|
||||
return roles
|
||||
}
|
||||
|
||||
/** Get users Metadata, return Metadata details
|
||||
* @param {String} nftAddress NFT contract address
|
||||
* @return {Promise<Objecta>}
|
||||
*/
|
||||
public async getMetadata(nftAddress: string): Promise<Object> {
|
||||
const nftContract = this.getContract(nftAddress)
|
||||
return await nftContract.methods.getMetaData().call()
|
||||
}
|
||||
|
||||
/** Get users DatatokenDeployer role
|
||||
* @param {String} nftAddress NFT contract address
|
||||
* @param {String} address user adress
|
||||
* @return {Promise<boolean>}
|
||||
*/
|
||||
public async isDatatokenDeployer(
|
||||
nftAddress: string,
|
||||
address: string
|
||||
): Promise<boolean> {
|
||||
const nftContract = this.getContract(nftAddress)
|
||||
const isDatatokenDeployer = await nftContract.methods.isERC20Deployer(address).call()
|
||||
return isDatatokenDeployer
|
||||
}
|
||||
|
||||
/** Gets data at a given `key`
|
||||
* @param {String} nftAddress NFT contract address
|
||||
* @param {String} key the key which value to retrieve
|
||||
* @return {Promise<string>} The data stored at the key
|
||||
*/
|
||||
public async getData(nftAddress: string, key: string): Promise<string> {
|
||||
const nftContract = this.getContract(nftAddress)
|
||||
const data = await nftContract.methods.getData(key).call()
|
||||
return data
|
||||
}
|
||||
|
||||
/** Gets data at a given `key`
|
||||
* @param {String} nftAddress NFT contract address
|
||||
* @param {String} id
|
||||
* @return {Promise<string>} The data stored at the key
|
||||
*/
|
||||
public async getTokenURI(nftAddress: string, id: number): Promise<string> {
|
||||
const nftContract = this.getContract(nftAddress)
|
||||
const data = await nftContract.methods.tokenURI(id).call()
|
||||
return data
|
||||
}
|
||||
}
|
@ -1,876 +0,0 @@
|
||||
import { Contract } from 'web3-eth-contract'
|
||||
import Web3 from 'web3'
|
||||
import { TransactionReceipt } from 'web3-core'
|
||||
import { AbiItem } from 'web3-utils'
|
||||
import defaultFactory721Abi from '@oceanprotocol/contracts/artifacts/contracts/ERC721Factory.sol/ERC721Factory.json'
|
||||
import {
|
||||
LoggerInstance,
|
||||
getFairGasPrice,
|
||||
generateDtName,
|
||||
getFreCreationParams,
|
||||
getErcCreationParams,
|
||||
getPoolCreationParams,
|
||||
setContractDefaults,
|
||||
estimateGas,
|
||||
ZERO_ADDRESS,
|
||||
ConfigHelper
|
||||
} from '../utils'
|
||||
import { Config } from '../models/index.js'
|
||||
import {
|
||||
ProviderFees,
|
||||
FreCreationParams,
|
||||
Erc20CreateParams,
|
||||
PoolCreationParams,
|
||||
DispenserCreationParams,
|
||||
ConsumeMarketFee
|
||||
} from '../@types/index.js'
|
||||
|
||||
interface Template {
|
||||
templateAddress: string
|
||||
isActive: boolean
|
||||
}
|
||||
|
||||
export interface TokenOrder {
|
||||
tokenAddress: string
|
||||
consumer: string
|
||||
serviceIndex: number
|
||||
_providerFee: ProviderFees
|
||||
_consumeMarketFee: ConsumeMarketFee
|
||||
}
|
||||
|
||||
export interface NftCreateData {
|
||||
name: string
|
||||
symbol: string
|
||||
templateIndex: number
|
||||
tokenURI: string
|
||||
transferable: boolean
|
||||
owner: string
|
||||
}
|
||||
|
||||
/**
|
||||
* Provides an interface for NFT Factory contract
|
||||
*/
|
||||
export class NftFactory {
|
||||
public factory721Address: string
|
||||
public factory721Abi: AbiItem | AbiItem[]
|
||||
public web3: Web3
|
||||
public config: Config
|
||||
public factory721: Contract
|
||||
|
||||
/**
|
||||
* Instantiate Datatokens.
|
||||
* @param {String} factory721Address
|
||||
* @param {AbiItem | AbiItem[]} factory721ABI
|
||||
* @param {Web3} web3
|
||||
*/
|
||||
constructor(
|
||||
factory721Address: string,
|
||||
web3: Web3,
|
||||
network?: string | number,
|
||||
factory721Abi?: AbiItem | AbiItem[],
|
||||
config?: Config
|
||||
) {
|
||||
this.factory721Address = factory721Address
|
||||
this.factory721Abi = factory721Abi || (defaultFactory721Abi.abi as AbiItem[])
|
||||
this.web3 = web3
|
||||
this.config = config || new ConfigHelper().getConfig(network || 'unknown')
|
||||
this.factory721 = setContractDefaults(
|
||||
new this.web3.eth.Contract(this.factory721Abi, this.factory721Address),
|
||||
this.config
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Get estimated gas cost for deployERC721Contract value
|
||||
* @param {String} address
|
||||
* @param {String} nftData
|
||||
* @return {Promise<string>} NFT datatoken address
|
||||
*/
|
||||
public async estGasCreateNFT(address: string, nftData: NftCreateData): Promise<string> {
|
||||
return estimateGas(
|
||||
address,
|
||||
this.factory721.methods.deployERC721Contract,
|
||||
nftData.name,
|
||||
nftData.symbol,
|
||||
nftData.templateIndex,
|
||||
ZERO_ADDRESS,
|
||||
ZERO_ADDRESS,
|
||||
nftData.tokenURI,
|
||||
nftData.transferable,
|
||||
nftData.owner
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Create new NFT
|
||||
* @param {String} address
|
||||
* @param {NFTCreateData} nftData
|
||||
* @return {Promise<string>} NFT datatoken address
|
||||
*/
|
||||
public async createNFT(address: string, nftData: NftCreateData): Promise<string> {
|
||||
if (!nftData.templateIndex) nftData.templateIndex = 1
|
||||
|
||||
if (!nftData.name || !nftData.symbol) {
|
||||
const { name, symbol } = generateDtName()
|
||||
nftData.name = name
|
||||
nftData.symbol = symbol
|
||||
}
|
||||
if (nftData.templateIndex > (await this.getCurrentNFTTemplateCount())) {
|
||||
throw new Error(`Template index doesnt exist`)
|
||||
}
|
||||
|
||||
if (nftData.templateIndex === 0) {
|
||||
throw new Error(`Template index cannot be ZERO`)
|
||||
}
|
||||
if ((await this.getNFTTemplate(nftData.templateIndex)).isActive === false) {
|
||||
throw new Error(`Template is not active`)
|
||||
}
|
||||
const estGas = await estimateGas(
|
||||
address,
|
||||
this.factory721.methods.deployERC721Contract,
|
||||
nftData.name,
|
||||
nftData.symbol,
|
||||
nftData.templateIndex,
|
||||
ZERO_ADDRESS,
|
||||
ZERO_ADDRESS,
|
||||
nftData.tokenURI,
|
||||
nftData.transferable,
|
||||
nftData.owner
|
||||
)
|
||||
|
||||
// Invoke createToken function of the contract
|
||||
const trxReceipt = await this.factory721.methods
|
||||
.deployERC721Contract(
|
||||
nftData.name,
|
||||
nftData.symbol,
|
||||
nftData.templateIndex,
|
||||
ZERO_ADDRESS,
|
||||
ZERO_ADDRESS,
|
||||
nftData.tokenURI,
|
||||
nftData.transferable,
|
||||
nftData.owner
|
||||
)
|
||||
.send({
|
||||
from: address,
|
||||
gas: estGas + 1,
|
||||
gasPrice: await getFairGasPrice(this.web3, this.config)
|
||||
})
|
||||
|
||||
let tokenAddress = null
|
||||
try {
|
||||
tokenAddress = trxReceipt.events.NFTCreated.returnValues[0]
|
||||
} catch (e) {
|
||||
LoggerInstance.error(`ERROR: Failed to create datatoken : ${e.message}`)
|
||||
}
|
||||
return tokenAddress
|
||||
}
|
||||
|
||||
/** Get Current NFT Count (NFT created)
|
||||
* @return {Promise<number>} Number of NFT created from this factory
|
||||
*/
|
||||
public async getCurrentNFTCount(): Promise<number> {
|
||||
const trxReceipt = await this.factory721.methods.getCurrentNFTCount().call()
|
||||
return trxReceipt
|
||||
}
|
||||
|
||||
/** Get Current Datatoken Count
|
||||
* @return {Promise<number>} Number of DTs created from this factory
|
||||
*/
|
||||
public async getCurrentTokenCount(): Promise<number> {
|
||||
const trxReceipt = await this.factory721.methods.getCurrentTokenCount().call()
|
||||
return trxReceipt
|
||||
}
|
||||
|
||||
/** Get Factory Owner
|
||||
* @return {Promise<string>} Factory Owner address
|
||||
*/
|
||||
public async getOwner(): Promise<string> {
|
||||
const trxReceipt = await this.factory721.methods.owner().call()
|
||||
return trxReceipt
|
||||
}
|
||||
|
||||
/** Get Current NFT Template Count
|
||||
* @return {Promise<number>} Number of NFT Template added to this factory
|
||||
*/
|
||||
public async getCurrentNFTTemplateCount(): Promise<number> {
|
||||
const count = await this.factory721.methods.getCurrentNFTTemplateCount().call()
|
||||
return count
|
||||
}
|
||||
|
||||
/** Get Current Template Datatoken (ERC20) Count
|
||||
* @return {Promise<number>} Number of ERC20 Template added to this factory
|
||||
*/
|
||||
public async getCurrentTokenTemplateCount(): Promise<number> {
|
||||
const count = await this.factory721.methods.getCurrentTemplateCount().call()
|
||||
return count
|
||||
}
|
||||
|
||||
/** Get NFT Template
|
||||
* @param {Number} index Template index
|
||||
* @return {Promise<Template>} Number of Template added to this factory
|
||||
*/
|
||||
public async getNFTTemplate(index: number): Promise<Template> {
|
||||
if (index > (await this.getCurrentNFTTemplateCount())) {
|
||||
throw new Error(`Template index doesnt exist`)
|
||||
}
|
||||
|
||||
if (index === 0) {
|
||||
throw new Error(`Template index cannot be ZERO`)
|
||||
}
|
||||
const template = await this.factory721.methods.getNFTTemplate(index).call()
|
||||
return template
|
||||
}
|
||||
|
||||
/** Get Datatoken(erc20) Template
|
||||
* @param {Number} index Template index
|
||||
* @return {Promise<Template>} DT Template info
|
||||
*/
|
||||
public async getTokenTemplate(index: number): Promise<Template> {
|
||||
const template = await this.factory721.methods.getTokenTemplate(index).call()
|
||||
return template
|
||||
}
|
||||
|
||||
/** Check if ERC20 is deployed from the factory
|
||||
* @param {String} datatoken Datatoken address we want to check
|
||||
* @return {Promise<Boolean>} return true if deployed from this factory
|
||||
*/
|
||||
public async checkDatatoken(datatoken: string): Promise<Boolean> {
|
||||
const isDeployed = await this.factory721.methods.erc20List(datatoken).call()
|
||||
return isDeployed
|
||||
}
|
||||
|
||||
/** Check if NFT is deployed from the factory
|
||||
* @param {String} nftAddress nftAddress address we want to check
|
||||
* @return {Promise<String>} return address(0) if it's not, or the nftAddress if true
|
||||
*/
|
||||
public async checkNFT(nftAddress: string): Promise<String> {
|
||||
const confirmAddress = await this.factory721.methods.erc721List(nftAddress).call()
|
||||
return confirmAddress
|
||||
}
|
||||
|
||||
/**
|
||||
* Estimate gas cost for add721TokenTemplate method
|
||||
* @param {String} address
|
||||
* @param {String} templateAddress template address to add
|
||||
* @return {Promise<TransactionReceipt>}
|
||||
*/
|
||||
public async estGasAddNFTTemplate(
|
||||
address: string,
|
||||
templateAddress: string
|
||||
): Promise<any> {
|
||||
return estimateGas(
|
||||
address,
|
||||
this.factory721.methods.add721TokenTemplate,
|
||||
templateAddress
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a new erc721 token template - only factory Owner
|
||||
* @param {String} address
|
||||
* @param {String} templateAddress template address to add
|
||||
* @return {Promise<TransactionReceipt>}
|
||||
*/
|
||||
public async addNFTTemplate(
|
||||
address: string,
|
||||
templateAddress: string
|
||||
): Promise<TransactionReceipt> {
|
||||
if ((await this.getOwner()) !== address) {
|
||||
throw new Error(`Caller is not Factory Owner`)
|
||||
}
|
||||
if (templateAddress === ZERO_ADDRESS) {
|
||||
throw new Error(`Template cannot be ZERO address`)
|
||||
}
|
||||
|
||||
const estGas = await estimateGas(
|
||||
address,
|
||||
this.factory721.methods.add721TokenTemplate,
|
||||
templateAddress
|
||||
)
|
||||
|
||||
// Invoke add721TokenTemplate function of the contract
|
||||
const trxReceipt = await this.factory721.methods
|
||||
.add721TokenTemplate(templateAddress)
|
||||
.send({
|
||||
from: address,
|
||||
gas: estGas + 1,
|
||||
gasPrice: await getFairGasPrice(this.web3, this.config)
|
||||
})
|
||||
|
||||
return trxReceipt
|
||||
}
|
||||
|
||||
/**
|
||||
* Estimate gas cost for disable721TokenTemplate method
|
||||
* @param {String} address
|
||||
* @param {Number} templateIndex index of the template we want to disable
|
||||
* @return {Promise<TransactionReceipt>} current token template count
|
||||
*/
|
||||
public async estGasDisableNFTTemplate(
|
||||
address: string,
|
||||
templateIndex: number
|
||||
): Promise<any> {
|
||||
return estimateGas(
|
||||
address,
|
||||
this.factory721.methods.disable721TokenTemplate,
|
||||
templateIndex
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Disable token template - only factory Owner
|
||||
* @param {String} address
|
||||
* @param {Number} templateIndex index of the template we want to disable
|
||||
* @return {Promise<TransactionReceipt>} current token template count
|
||||
*/
|
||||
public async disableNFTTemplate(
|
||||
address: string,
|
||||
templateIndex: number
|
||||
): Promise<TransactionReceipt> {
|
||||
if ((await this.getOwner()) !== address) {
|
||||
throw new Error(`Caller is not Factory Owner`)
|
||||
}
|
||||
if (templateIndex > (await this.getCurrentNFTTemplateCount())) {
|
||||
throw new Error(`Template index doesnt exist`)
|
||||
}
|
||||
|
||||
if (templateIndex === 0) {
|
||||
throw new Error(`Template index cannot be ZERO`)
|
||||
}
|
||||
const estGas = await estimateGas(
|
||||
address,
|
||||
this.factory721.methods.disable721TokenTemplate,
|
||||
templateIndex
|
||||
)
|
||||
|
||||
// Invoke createToken function of the contract
|
||||
const trxReceipt = await this.factory721.methods
|
||||
.disable721TokenTemplate(templateIndex)
|
||||
.send({
|
||||
from: address,
|
||||
gas: estGas + 1,
|
||||
gasPrice: await getFairGasPrice(this.web3, this.config)
|
||||
})
|
||||
|
||||
return trxReceipt
|
||||
}
|
||||
|
||||
/**
|
||||
* Reactivate a previously disabled token template - only factory Owner
|
||||
* @param {String} address
|
||||
* @param {Number} templateIndex index of the template we want to reactivate
|
||||
* @return {Promise<TransactionReceipt>} current token template count
|
||||
*/
|
||||
public async estGasReactivateNFTTemplate(
|
||||
address: string,
|
||||
templateIndex: number
|
||||
): Promise<any> {
|
||||
return estimateGas(
|
||||
address,
|
||||
this.factory721.methods.reactivate721TokenTemplate,
|
||||
templateIndex
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Reactivate a previously disabled token template - only factory Owner
|
||||
* @param {String} address
|
||||
* @param {Number} templateIndex index of the template we want to reactivate
|
||||
* @return {Promise<TransactionReceipt>} current token template count
|
||||
*/
|
||||
public async reactivateNFTTemplate(
|
||||
address: string,
|
||||
templateIndex: number
|
||||
): Promise<TransactionReceipt> {
|
||||
if ((await this.getOwner()) !== address) {
|
||||
throw new Error(`Caller is not Factory Owner`)
|
||||
}
|
||||
if (templateIndex > (await this.getCurrentNFTTemplateCount())) {
|
||||
throw new Error(`Template index doesnt exist`)
|
||||
}
|
||||
|
||||
if (templateIndex === 0) {
|
||||
throw new Error(`Template index cannot be ZERO`)
|
||||
}
|
||||
|
||||
const estGas = await estimateGas(
|
||||
address,
|
||||
this.factory721.methods.reactivate721TokenTemplate,
|
||||
templateIndex
|
||||
)
|
||||
|
||||
// Invoke createToken function of the contract
|
||||
const trxReceipt = await this.factory721.methods
|
||||
.reactivate721TokenTemplate(templateIndex)
|
||||
.send({
|
||||
from: address,
|
||||
gas: estGas + 1,
|
||||
gasPrice: await getFairGasPrice(this.web3, this.config)
|
||||
})
|
||||
|
||||
return trxReceipt
|
||||
}
|
||||
|
||||
/**
|
||||
* Estimate gas cost for addTokenTemplate method
|
||||
* @param {String} address
|
||||
* @param {String} templateAddress template address to add
|
||||
* @return {Promise<TransactionReceipt>}
|
||||
*/
|
||||
public async estGasAddTokenTemplate(
|
||||
address: string,
|
||||
templateAddress: string
|
||||
): Promise<any> {
|
||||
return estimateGas(address, this.factory721.methods.addTokenTemplate, templateAddress)
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a new erc721 token template - only factory Owner
|
||||
* @param {String} address
|
||||
* @param {String} templateAddress template address to add
|
||||
* @return {Promise<TransactionReceipt>}
|
||||
*/
|
||||
public async addTokenTemplate(
|
||||
address: string,
|
||||
templateAddress: string
|
||||
): Promise<TransactionReceipt> {
|
||||
if ((await this.getOwner()) !== address) {
|
||||
throw new Error(`Caller is not Factory Owner`)
|
||||
}
|
||||
if (templateAddress === ZERO_ADDRESS) {
|
||||
throw new Error(`Template cannot be address ZERO`)
|
||||
}
|
||||
|
||||
const estGas = await estimateGas(
|
||||
address,
|
||||
this.factory721.methods.addTokenTemplate,
|
||||
templateAddress
|
||||
)
|
||||
|
||||
// Invoke createToken function of the contract
|
||||
const trxReceipt = await this.factory721.methods
|
||||
.addTokenTemplate(templateAddress)
|
||||
.send({
|
||||
from: address,
|
||||
gas: estGas + 1,
|
||||
gasPrice: await getFairGasPrice(this.web3, this.config)
|
||||
})
|
||||
|
||||
return trxReceipt
|
||||
}
|
||||
|
||||
/**
|
||||
* Estimate gas cost for disableTokenTemplate method
|
||||
* @param {String} address
|
||||
* @param {Number} templateIndex index of the template we want to disable
|
||||
* @return {Promise<TransactionReceipt>} current token template count
|
||||
*/
|
||||
public async estGasDisableTokenTemplate(
|
||||
address: string,
|
||||
templateIndex: number
|
||||
): Promise<any> {
|
||||
return estimateGas(
|
||||
address,
|
||||
this.factory721.methods.disableTokenTemplate,
|
||||
templateIndex
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Disable token template - only factory Owner
|
||||
* @param {String} address
|
||||
* @param {Number} templateIndex index of the template we want to disable
|
||||
* @return {Promise<TransactionReceipt>} current token template count
|
||||
*/
|
||||
public async disableTokenTemplate(
|
||||
address: string,
|
||||
templateIndex: number
|
||||
): Promise<TransactionReceipt> {
|
||||
if ((await this.getOwner()) !== address) {
|
||||
throw new Error(`Caller is not Factory Owner`)
|
||||
}
|
||||
if (templateIndex > (await this.getCurrentTokenTemplateCount())) {
|
||||
throw new Error(`Template index doesnt exist`)
|
||||
}
|
||||
|
||||
if (templateIndex === 0) {
|
||||
throw new Error(`Template index cannot be ZERO`)
|
||||
}
|
||||
if ((await this.getTokenTemplate(templateIndex)).isActive === false) {
|
||||
throw new Error(`Template is already disabled`)
|
||||
}
|
||||
const estGas = await estimateGas(
|
||||
address,
|
||||
this.factory721.methods.disableTokenTemplate,
|
||||
templateIndex
|
||||
)
|
||||
|
||||
// Invoke createToken function of the contract
|
||||
const trxReceipt = await this.factory721.methods
|
||||
.disableTokenTemplate(templateIndex)
|
||||
.send({
|
||||
from: address,
|
||||
gas: estGas + 1,
|
||||
gasPrice: await getFairGasPrice(this.web3, this.config)
|
||||
})
|
||||
|
||||
return trxReceipt
|
||||
}
|
||||
|
||||
/**
|
||||
* Estimate gas cost for reactivateTokenTemplate method
|
||||
* @param {String} address
|
||||
* @param {Number} templateIndex index of the template we want to reactivate
|
||||
* @return {Promise<TransactionReceipt>} current token template count
|
||||
*/
|
||||
public async estGasReactivateTokenTemplate(
|
||||
address: string,
|
||||
templateIndex: number
|
||||
): Promise<any> {
|
||||
return estimateGas(
|
||||
address,
|
||||
this.factory721.methods.reactivateTokenTemplate,
|
||||
templateIndex
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Reactivate a previously disabled token template - only factory Owner
|
||||
* @param {String} address
|
||||
* @param {Number} templateIndex index of the template we want to reactivate
|
||||
* @return {Promise<TransactionReceipt>} current token template count
|
||||
*/
|
||||
public async reactivateTokenTemplate(
|
||||
address: string,
|
||||
templateIndex: number
|
||||
): Promise<TransactionReceipt> {
|
||||
if ((await this.getOwner()) !== address) {
|
||||
throw new Error(`Caller is not Factory Owner`)
|
||||
}
|
||||
if (templateIndex > (await this.getCurrentTokenTemplateCount())) {
|
||||
throw new Error(`Template index doesnt exist`)
|
||||
}
|
||||
|
||||
if (templateIndex === 0) {
|
||||
throw new Error(`Template index cannot be ZERO`)
|
||||
}
|
||||
if ((await this.getTokenTemplate(templateIndex)).isActive === true) {
|
||||
throw new Error(`Template is already active`)
|
||||
}
|
||||
|
||||
const estGas = await estimateGas(
|
||||
address,
|
||||
this.factory721.methods.reactivateTokenTemplate,
|
||||
templateIndex
|
||||
)
|
||||
|
||||
// Invoke createToken function of the contract
|
||||
const trxReceipt = await this.factory721.methods
|
||||
.reactivateTokenTemplate(templateIndex)
|
||||
.send({
|
||||
from: address,
|
||||
gas: estGas + 1,
|
||||
gasPrice: await getFairGasPrice(this.web3, this.config)
|
||||
})
|
||||
|
||||
return trxReceipt
|
||||
}
|
||||
|
||||
/** Estimate gas cost for startMultipleTokenOrder method
|
||||
* @param address Caller address
|
||||
* @param orders an array of struct tokenOrder
|
||||
* @return {Promise<TransactionReceipt>} transaction receipt
|
||||
*/
|
||||
public async estGasStartMultipleTokenOrder(
|
||||
address: string,
|
||||
orders: TokenOrder[]
|
||||
): Promise<any> {
|
||||
return estimateGas(address, this.factory721.methods.startMultipleTokenOrder, orders)
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev startMultipleTokenOrder
|
||||
* Used as a proxy to order multiple services
|
||||
* Users can have inifinite approvals for fees for factory instead of having one approval/ erc20 contract
|
||||
* Requires previous approval of all :
|
||||
* - consumeFeeTokens
|
||||
* - publishMarketFeeTokens
|
||||
* - erc20 datatokens
|
||||
* @param address Caller address
|
||||
* @param orders an array of struct tokenOrder
|
||||
* @return {Promise<TransactionReceipt>} transaction receipt
|
||||
*/
|
||||
public async startMultipleTokenOrder(
|
||||
address: string,
|
||||
orders: TokenOrder[]
|
||||
): Promise<TransactionReceipt> {
|
||||
if (orders.length > 50) {
|
||||
throw new Error(`Too many orders`)
|
||||
}
|
||||
|
||||
const estGas = await estimateGas(
|
||||
address,
|
||||
this.factory721.methods.startMultipleTokenOrder,
|
||||
orders
|
||||
)
|
||||
|
||||
// Invoke createToken function of the contract
|
||||
const trxReceipt = await this.factory721.methods
|
||||
.startMultipleTokenOrder(orders)
|
||||
.send({
|
||||
from: address,
|
||||
gas: estGas + 1,
|
||||
gasPrice: await getFairGasPrice(this.web3, this.config)
|
||||
})
|
||||
|
||||
return trxReceipt
|
||||
}
|
||||
|
||||
/**
|
||||
* Estimate gas cost for createNftWithErc20 method
|
||||
* @param address Caller address
|
||||
* @param _NftCreateData input data for nft creation
|
||||
* @param _ErcCreateData input data for erc20 creation
|
||||
* @return {Promise<TransactionReceipt>} transaction receipt
|
||||
*/
|
||||
|
||||
public async estGasCreateNftWithErc20(
|
||||
address: string,
|
||||
nftCreateData: NftCreateData,
|
||||
ercParams: Erc20CreateParams
|
||||
): Promise<any> {
|
||||
const ercCreateData = getErcCreationParams(ercParams)
|
||||
return estimateGas(
|
||||
address,
|
||||
this.factory721.methods.createNftWithErc20,
|
||||
nftCreateData,
|
||||
ercCreateData
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev createNftWithErc20
|
||||
* Creates a new NFT, then a ERC20,all in one call
|
||||
* @param address Caller address
|
||||
* @param _NftCreateData input data for nft creation
|
||||
* @param _ErcCreateData input data for erc20 creation
|
||||
* @return {Promise<TransactionReceipt>} transaction receipt
|
||||
*/
|
||||
|
||||
public async createNftWithErc20(
|
||||
address: string,
|
||||
nftCreateData: NftCreateData,
|
||||
ercParams: Erc20CreateParams
|
||||
): Promise<TransactionReceipt> {
|
||||
const ercCreateData = getErcCreationParams(ercParams)
|
||||
|
||||
const estGas = await estimateGas(
|
||||
address,
|
||||
this.factory721.methods.createNftWithErc20,
|
||||
nftCreateData,
|
||||
ercCreateData
|
||||
)
|
||||
|
||||
// Invoke createToken function of the contract
|
||||
const trxReceipt = await this.factory721.methods
|
||||
.createNftWithErc20(nftCreateData, ercCreateData)
|
||||
.send({
|
||||
from: address,
|
||||
gas: estGas + 1,
|
||||
gasPrice: await getFairGasPrice(this.web3, this.config)
|
||||
})
|
||||
|
||||
return trxReceipt
|
||||
}
|
||||
|
||||
/**
|
||||
* Estimate gas cost for createNftErc20WithPool method
|
||||
* @param address Caller address
|
||||
* @param nftCreateData input data for NFT Creation
|
||||
* @param ercParams input data for ERC20 Creation
|
||||
* @param poolParams input data for Pool Creation
|
||||
* @return {Promise<TransactionReceipt>} transaction receipt
|
||||
*/
|
||||
public async estGasCreateNftErc20WithPool(
|
||||
address: string,
|
||||
nftCreateData: NftCreateData,
|
||||
ercParams: Erc20CreateParams,
|
||||
poolParams: PoolCreationParams
|
||||
): Promise<any> {
|
||||
const ercCreateData = getErcCreationParams(ercParams)
|
||||
const poolData = await getPoolCreationParams(this.web3, poolParams)
|
||||
return estimateGas(
|
||||
address,
|
||||
this.factory721.methods.createNftWithErc20WithPool,
|
||||
nftCreateData,
|
||||
ercCreateData,
|
||||
poolData
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev createNftErc20WithPool
|
||||
* Creates a new NFT, then a ERC20, then a Pool, all in one call
|
||||
* Use this carefully, because if Pool creation fails, you are still going to pay a lot of gas
|
||||
* @param address Caller address
|
||||
* @param nftCreateData input data for NFT Creation
|
||||
* @param ercParams input data for ERC20 Creation
|
||||
* @param poolParams input data for Pool Creation
|
||||
* @return {Promise<TransactionReceipt>} transaction receipt
|
||||
*/
|
||||
public async createNftErc20WithPool(
|
||||
address: string,
|
||||
nftCreateData: NftCreateData,
|
||||
ercParams: Erc20CreateParams,
|
||||
poolParams: PoolCreationParams
|
||||
): Promise<TransactionReceipt> {
|
||||
const ercCreateData = getErcCreationParams(ercParams)
|
||||
const poolData = await getPoolCreationParams(this.web3, poolParams)
|
||||
|
||||
const estGas = await estimateGas(
|
||||
address,
|
||||
this.factory721.methods.createNftWithErc20WithPool,
|
||||
nftCreateData,
|
||||
ercCreateData,
|
||||
poolData
|
||||
)
|
||||
|
||||
// Invoke createToken function of the contract
|
||||
const trxReceipt = await this.factory721.methods
|
||||
.createNftWithErc20WithPool(nftCreateData, ercCreateData, poolData)
|
||||
.send({
|
||||
from: address,
|
||||
gas: estGas + 1,
|
||||
gasPrice: await getFairGasPrice(this.web3, this.config)
|
||||
})
|
||||
|
||||
return trxReceipt
|
||||
}
|
||||
|
||||
/** Estimate gas cost for createNftErc20WithFixedRate method
|
||||
* @param address Caller address
|
||||
* @param nftCreateData input data for NFT Creation
|
||||
* @param ercParams input data for ERC20 Creation
|
||||
* @param freParams input data for FixedRate Creation
|
||||
* @return {Promise<TransactionReceipt>} transaction receipt
|
||||
*/
|
||||
public async estGasCreateNftErc20WithFixedRate(
|
||||
address: string,
|
||||
nftCreateData: NftCreateData,
|
||||
ercParams: Erc20CreateParams,
|
||||
freParams: FreCreationParams
|
||||
): Promise<any> {
|
||||
const ercCreateData = getErcCreationParams(ercParams)
|
||||
const fixedData = await getFreCreationParams(freParams)
|
||||
return estimateGas(
|
||||
address,
|
||||
this.factory721.methods.createNftWithErc20WithFixedRate,
|
||||
nftCreateData,
|
||||
ercCreateData,
|
||||
fixedData
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev createNftErc20WithFixedRate
|
||||
* Creates a new NFT, then a ERC20, then a FixedRateExchange, all in one call
|
||||
* Use this carefully, because if Fixed Rate creation fails, you are still going to pay a lot of gas
|
||||
* @param address Caller address
|
||||
* @param nftCreateData input data for NFT Creation
|
||||
* @param ercParams input data for ERC20 Creation
|
||||
* @param freParams input data for FixedRate Creation
|
||||
* @return {Promise<TransactionReceipt>} transaction receipt
|
||||
*/
|
||||
public async createNftErc20WithFixedRate(
|
||||
address: string,
|
||||
nftCreateData: NftCreateData,
|
||||
ercParams: Erc20CreateParams,
|
||||
freParams: FreCreationParams
|
||||
): Promise<TransactionReceipt> {
|
||||
const ercCreateData = getErcCreationParams(ercParams)
|
||||
const fixedData = getFreCreationParams(freParams)
|
||||
|
||||
const estGas = await estimateGas(
|
||||
address,
|
||||
this.factory721.methods.createNftWithErc20WithFixedRate,
|
||||
nftCreateData,
|
||||
ercCreateData,
|
||||
fixedData
|
||||
)
|
||||
|
||||
// Invoke createToken function of the contract
|
||||
const trxReceipt = await this.factory721.methods
|
||||
.createNftWithErc20WithFixedRate(nftCreateData, ercCreateData, fixedData)
|
||||
.send({
|
||||
from: address,
|
||||
gas: estGas + 1,
|
||||
gasPrice: await getFairGasPrice(this.web3, this.config)
|
||||
})
|
||||
|
||||
return trxReceipt
|
||||
}
|
||||
|
||||
/** Estimate gas cost for createNftErc20WithFixedRate method
|
||||
* @param address Caller address
|
||||
* @param nftCreateData input data for NFT Creation
|
||||
* @param ercParams input data for ERC20 Creation
|
||||
* @param dispenserParams input data for Dispenser Creation
|
||||
* @return {Promise<TransactionReceipt>} transaction receipt
|
||||
*/
|
||||
public async estGasCreateNftErc20WithDispenser(
|
||||
address: string,
|
||||
nftCreateData: NftCreateData,
|
||||
ercParams: Erc20CreateParams,
|
||||
dispenserParams: DispenserCreationParams
|
||||
): Promise<any> {
|
||||
const ercCreateData = getErcCreationParams(ercParams)
|
||||
return estimateGas(
|
||||
address,
|
||||
this.factory721.methods.createNftWithErc20WithDispenser,
|
||||
nftCreateData,
|
||||
ercCreateData,
|
||||
dispenserParams
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev createNftErc20WithDispenser
|
||||
* Creates a new NFT, then a ERC20, then a Dispenser, all in one call
|
||||
* Use this carefully, because if Dispenser creation fails, you are still going to pay a lot of gas
|
||||
* @param address Caller address
|
||||
* @param nftCreateData input data for NFT Creation
|
||||
* @param ercParams input data for ERC20 Creation
|
||||
* @param dispenserParams input data for Dispenser Creation
|
||||
* @return {Promise<TransactionReceipt>} transaction receipt
|
||||
*/
|
||||
public async createNftErc20WithDispenser(
|
||||
address: string,
|
||||
nftCreateData: NftCreateData,
|
||||
ercParams: Erc20CreateParams,
|
||||
dispenserParams: DispenserCreationParams
|
||||
): Promise<TransactionReceipt> {
|
||||
const ercCreateData = getErcCreationParams(ercParams)
|
||||
|
||||
dispenserParams.maxBalance = Web3.utils.toWei(dispenserParams.maxBalance)
|
||||
dispenserParams.maxTokens = Web3.utils.toWei(dispenserParams.maxTokens)
|
||||
|
||||
const estGas = await estimateGas(
|
||||
address,
|
||||
this.factory721.methods.createNftWithErc20WithDispenser,
|
||||
nftCreateData,
|
||||
ercCreateData,
|
||||
dispenserParams
|
||||
)
|
||||
|
||||
// Invoke createToken function of the contract
|
||||
const trxReceipt = await this.factory721.methods
|
||||
.createNftWithErc20WithDispenser(nftCreateData, ercCreateData, dispenserParams)
|
||||
.send({
|
||||
from: address,
|
||||
gas: estGas + 1,
|
||||
gasPrice: await getFairGasPrice(this.web3, this.config)
|
||||
})
|
||||
|
||||
return trxReceipt
|
||||
}
|
||||
}
|
@ -1 +0,0 @@
|
||||
export * from './NFTFactory'
|
11
src/index.ts
11
src/index.ts
@ -1,8 +1,5 @@
|
||||
export * from './aquarius'
|
||||
export * from './pools'
|
||||
export * from './tokens'
|
||||
export * from './factories'
|
||||
export * from './models'
|
||||
export * from './utils'
|
||||
export * from './@types'
|
||||
export * from './provider'
|
||||
export * from './config'
|
||||
export * from './contracts'
|
||||
export * from './services'
|
||||
export * from './utils'
|
||||
|
@ -1 +0,0 @@
|
||||
export * from './Config'
|
@ -1,631 +0,0 @@
|
||||
import { Contract } from 'web3-eth-contract'
|
||||
import Web3 from 'web3'
|
||||
import { TransactionReceipt } from 'web3-core'
|
||||
import { AbiItem } from 'web3-utils'
|
||||
import defaultRouter from '@oceanprotocol/contracts/artifacts/contracts/pools/FactoryRouter.sol/FactoryRouter.json'
|
||||
import { getFairGasPrice, setContractDefaults, ConfigHelper, estimateGas } from '../utils'
|
||||
import { Operation } from '../@types/Router'
|
||||
import { Config } from '../models/index.js'
|
||||
|
||||
/**
|
||||
* Provides an interface for FactoryRouter contract
|
||||
*/
|
||||
export class Router {
|
||||
public routerAddress: string
|
||||
public RouterAbi: AbiItem | AbiItem[]
|
||||
public web3: Web3
|
||||
public config: Config
|
||||
public router: Contract
|
||||
|
||||
/**
|
||||
* Instantiate Router.
|
||||
* @param {String} routerAddress
|
||||
* @param {AbiItem | AbiItem[]} Router
|
||||
* @param {Web3} web3
|
||||
*/
|
||||
constructor(
|
||||
routerAddress: string,
|
||||
web3: Web3,
|
||||
network?: string | number,
|
||||
RouterAbi?: AbiItem | AbiItem[],
|
||||
config?: Config
|
||||
) {
|
||||
this.routerAddress = routerAddress
|
||||
this.RouterAbi = RouterAbi || (defaultRouter.abi as AbiItem[])
|
||||
this.web3 = web3
|
||||
this.config = config || new ConfigHelper().getConfig(network || 'unknown')
|
||||
this.router = setContractDefaults(
|
||||
new this.web3.eth.Contract(this.RouterAbi, this.routerAddress),
|
||||
this.config
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Estimate gas cost for buyDTBatch method
|
||||
* @param {String} address
|
||||
* @param {Operation} operations Operations objects array
|
||||
* @return {Promise<TransactionReceipt>} Transaction receipt
|
||||
*/
|
||||
public async estGasBuyDTBatch(address: string, operations: Operation[]): Promise<any> {
|
||||
return estimateGas(address, this.router.methods.buyDTBatch, operations)
|
||||
}
|
||||
|
||||
/**
|
||||
* BuyDTBatch
|
||||
* @param {String} address
|
||||
* @param {Operation} operations Operations objects array
|
||||
* @return {Promise<TransactionReceipt>} Transaction receipt
|
||||
*/
|
||||
public async buyDTBatch(
|
||||
address: string,
|
||||
operations: Operation[]
|
||||
): Promise<TransactionReceipt> {
|
||||
const estGas = await estimateGas(address, this.router.methods.buyDTBatch, operations)
|
||||
|
||||
// Invoke createToken function of the contract
|
||||
const trxReceipt = await this.router.methods.buyDTBatch(operations).send({
|
||||
from: address,
|
||||
gas: estGas + 1,
|
||||
gasPrice: await getFairGasPrice(this.web3, this.config)
|
||||
})
|
||||
|
||||
return trxReceipt
|
||||
}
|
||||
|
||||
/** Check if a token is on approved tokens list, if true opfFee is lower in pools with that token/DT
|
||||
* @return {Promise<boolean>} true if is on the list.
|
||||
*/
|
||||
public async isApprovedToken(address: string): Promise<boolean> {
|
||||
return await this.router.methods.isApprovedToken(address).call()
|
||||
}
|
||||
|
||||
/** Check if an address is a side staking contract.
|
||||
* @return {Promise<boolean>} true if is a SS contract
|
||||
*/
|
||||
public async isSideStaking(address: string): Promise<boolean> {
|
||||
return await this.router.methods.isSSContract(address).call()
|
||||
}
|
||||
|
||||
/** Check if an address is a Fixed Rate contract.
|
||||
* @return {Promise<boolean>} true if is a Fixed Rate contract
|
||||
*/
|
||||
public async isFixedPrice(address: string): Promise<boolean> {
|
||||
return await this.router.methods.isFixedRateContract(address).call()
|
||||
}
|
||||
|
||||
/** Get Router Owner
|
||||
* @return {Promise<string>} Router Owner address
|
||||
*/
|
||||
public async getOwner(): Promise<string> {
|
||||
return await this.router.methods.routerOwner().call()
|
||||
}
|
||||
|
||||
/** Get NFT Factory address
|
||||
* @return {Promise<string>} NFT Factory address
|
||||
*/
|
||||
public async getNFTFactory(): Promise<string> {
|
||||
return await this.router.methods.factory().call()
|
||||
}
|
||||
|
||||
/** Check if an address is a pool template contract.
|
||||
* @return {Promise<boolean>} true if is a Template
|
||||
*/
|
||||
public async isPoolTemplate(address: string): Promise<boolean> {
|
||||
return await this.router.methods.isPoolTemplate(address).call()
|
||||
}
|
||||
|
||||
/**
|
||||
* Estimate gas cost for addApprovedToken
|
||||
* @param {String} address
|
||||
* @param {String} tokenAddress token address we want to add
|
||||
* @param {Contract} routerContract optional contract instance
|
||||
* @return {Promise<any>}
|
||||
*/
|
||||
public async estGasAddApprovedToken(
|
||||
address: string,
|
||||
tokenAddress: string,
|
||||
contractInstance?: Contract
|
||||
): Promise<any> {
|
||||
return estimateGas(address, this.router.methods.addApprovedToken, tokenAddress)
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a new token to oceanTokens list, pools with baseToken in this list have NO opf Fee
|
||||
* @param {String} address caller address
|
||||
* @param {String} tokenAddress token address to add
|
||||
* @return {Promise<TransactionReceipt>}
|
||||
*/
|
||||
public async addApprovedToken(
|
||||
address: string,
|
||||
tokenAddress: string
|
||||
): Promise<TransactionReceipt> {
|
||||
if ((await this.getOwner()) !== address) {
|
||||
throw new Error(`Caller is not Router Owner`)
|
||||
}
|
||||
|
||||
const estGas = await estimateGas(
|
||||
address,
|
||||
this.router.methods.addApprovedToken,
|
||||
tokenAddress
|
||||
)
|
||||
|
||||
// Invoke createToken function of the contract
|
||||
const trxReceipt = await this.router.methods.addApprovedToken(tokenAddress).send({
|
||||
from: address,
|
||||
gas: estGas + 1,
|
||||
gasPrice: await getFairGasPrice(this.web3, this.config)
|
||||
})
|
||||
|
||||
return trxReceipt
|
||||
}
|
||||
|
||||
/**
|
||||
* Estimate gas cost for removeApprovedToken
|
||||
* @param {String} address caller address
|
||||
* @param {String} tokenAddress token address we want to add
|
||||
* @param {Contract} routerContract optional contract instance
|
||||
* @return {Promise<any>}
|
||||
*/
|
||||
public async estGasRemoveApprovedToken(
|
||||
address: string,
|
||||
tokenAddress: string,
|
||||
contractInstance?: Contract
|
||||
): Promise<any> {
|
||||
return estimateGas(address, this.router.methods.removeApprovedToken, tokenAddress)
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove a token from oceanTokens list, pools without baseToken in this list have a opf Fee
|
||||
* @param {String} address
|
||||
* @param {String} tokenAddress address to remove
|
||||
* @return {Promise<TransactionReceipt>}
|
||||
*/
|
||||
public async removeApprovedToken(
|
||||
address: string,
|
||||
tokenAddress: string
|
||||
): Promise<TransactionReceipt> {
|
||||
if ((await this.getOwner()) !== address) {
|
||||
throw new Error(`Caller is not Router Owner`)
|
||||
}
|
||||
|
||||
const estGas = await estimateGas(
|
||||
address,
|
||||
this.router.methods.removeApprovedToken,
|
||||
tokenAddress
|
||||
)
|
||||
|
||||
// Invoke createToken function of the contract
|
||||
const trxReceipt = await this.router.methods.removeApprovedToken(tokenAddress).send({
|
||||
from: address,
|
||||
gas: estGas + 1,
|
||||
gasPrice: await getFairGasPrice(this.web3, this.config)
|
||||
})
|
||||
|
||||
return trxReceipt
|
||||
}
|
||||
|
||||
/**
|
||||
* Estimate gas cost for addSSContract method
|
||||
* @param {String} address
|
||||
* @param {String} tokenAddress contract address to add
|
||||
* @return {Promise<TransactionReceipt>}
|
||||
*/
|
||||
public async estGasAddSSContract(address: string, tokenAddress: string): Promise<any> {
|
||||
return estimateGas(address, this.router.methods.addSSContract, tokenAddress)
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a new contract to ssContract list, after is added, can be used when deploying a new pool
|
||||
* @param {String} address
|
||||
* @param {String} tokenAddress contract address to add
|
||||
* @return {Promise<TransactionReceipt>}
|
||||
*/
|
||||
public async addSSContract(
|
||||
address: string,
|
||||
tokenAddress: string
|
||||
): Promise<TransactionReceipt> {
|
||||
if ((await this.getOwner()) !== address) {
|
||||
throw new Error(`Caller is not Router Owner`)
|
||||
}
|
||||
|
||||
const estGas = await estimateGas(
|
||||
address,
|
||||
this.router.methods.addSSContract,
|
||||
tokenAddress
|
||||
)
|
||||
|
||||
// Invoke createToken function of the contract
|
||||
const trxReceipt = await this.router.methods.addSSContract(tokenAddress).send({
|
||||
from: address,
|
||||
gas: estGas + 1,
|
||||
gasPrice: await getFairGasPrice(this.web3, this.config)
|
||||
})
|
||||
|
||||
return trxReceipt
|
||||
}
|
||||
|
||||
/**
|
||||
* Estimate gas cost for removeSSContract method
|
||||
* @param {String} address caller address
|
||||
* @param {String} tokenAddress contract address to add
|
||||
* @return {Promise<TransactionReceipt>}
|
||||
*/
|
||||
public async estGasRemoveSSContract(
|
||||
address: string,
|
||||
tokenAddress: string
|
||||
): Promise<any> {
|
||||
return estimateGas(address, this.router.methods.removeSSContract, tokenAddress)
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes a new contract from ssContract list
|
||||
* @param {String} address caller address
|
||||
* @param {String} tokenAddress contract address to removed
|
||||
* @return {Promise<TransactionReceipt>}
|
||||
*/
|
||||
public async removeSSContract(
|
||||
address: string,
|
||||
tokenAddress: string
|
||||
): Promise<TransactionReceipt> {
|
||||
if ((await this.getOwner()) !== address) {
|
||||
throw new Error(`Caller is not Router Owner`)
|
||||
}
|
||||
|
||||
const estGas = await estimateGas(
|
||||
address,
|
||||
this.router.methods.removeSSContract,
|
||||
tokenAddress
|
||||
)
|
||||
|
||||
// Invoke createToken function of the contract
|
||||
const trxReceipt = await this.router.methods.removeSSContract(tokenAddress).send({
|
||||
from: address,
|
||||
gas: estGas + 1,
|
||||
gasPrice: await getFairGasPrice(this.web3, this.config)
|
||||
})
|
||||
|
||||
return trxReceipt
|
||||
}
|
||||
|
||||
/**
|
||||
* Estimate gas cost for addFixedRateContract method
|
||||
* @param {String} address
|
||||
* @param {String} tokenAddress contract address to add
|
||||
* @return {Promise<TransactionReceipt>}
|
||||
*/
|
||||
public async estGasAddFixedRateContract(
|
||||
address: string,
|
||||
tokenAddress: string
|
||||
): Promise<any> {
|
||||
return estimateGas(address, this.router.methods.addFixedRateContract, tokenAddress)
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a new contract to fixedRate list, after is added, can be used when deploying a new pool
|
||||
* @param {String} address
|
||||
* @param {String} tokenAddress contract address to add
|
||||
* @return {Promise<TransactionReceipt>}
|
||||
*/
|
||||
public async addFixedRateContract(
|
||||
address: string,
|
||||
tokenAddress: string
|
||||
): Promise<TransactionReceipt> {
|
||||
if ((await this.getOwner()) !== address) {
|
||||
throw new Error(`Caller is not Router Owner`)
|
||||
}
|
||||
|
||||
const estGas = await estimateGas(
|
||||
address,
|
||||
this.router.methods.addFixedRateContract,
|
||||
tokenAddress
|
||||
)
|
||||
|
||||
// Invoke createToken function of the contract
|
||||
const trxReceipt = await this.router.methods.addFixedRateContract(tokenAddress).send({
|
||||
from: address,
|
||||
gas: estGas + 1,
|
||||
gasPrice: await getFairGasPrice(this.web3, this.config)
|
||||
})
|
||||
|
||||
return trxReceipt
|
||||
}
|
||||
|
||||
/**
|
||||
* Estimate gas cost for addFixedRateContract method
|
||||
* @param {String} address
|
||||
* @param {String} tokenAddress contract address to add
|
||||
* @return {Promise<TransactionReceipt>}
|
||||
*/
|
||||
public async estGasRemoveFixedRateContract(
|
||||
address: string,
|
||||
tokenAddress: string
|
||||
): Promise<any> {
|
||||
return estimateGas(address, this.router.methods.removeFixedRateContract, tokenAddress)
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes a contract from fixedRate list
|
||||
* @param {String} address
|
||||
* @param {String} tokenAddress contract address to add
|
||||
* @return {Promise<TransactionReceipt>}
|
||||
*/
|
||||
public async removeFixedRateContract(
|
||||
address: string,
|
||||
tokenAddress: string
|
||||
): Promise<TransactionReceipt> {
|
||||
if ((await this.getOwner()) !== address) {
|
||||
throw new Error(`Caller is not Router Owner`)
|
||||
}
|
||||
|
||||
const estGas = await estimateGas(
|
||||
address,
|
||||
this.router.methods.removeFixedRateContract,
|
||||
tokenAddress
|
||||
)
|
||||
|
||||
// Invoke removeFixedRateContract function of the contract
|
||||
const trxReceipt = await this.router.methods
|
||||
.removeFixedRateContract(tokenAddress)
|
||||
.send({
|
||||
from: address,
|
||||
gas: estGas + 1,
|
||||
gasPrice: await getFairGasPrice(this.web3, this.config)
|
||||
})
|
||||
|
||||
return trxReceipt
|
||||
}
|
||||
|
||||
/**
|
||||
* Estimate gas cost for addDispenserContract method
|
||||
* @param {String} address
|
||||
* @param {String} tokenAddress contract address to add
|
||||
* @return {Promise<TransactionReceipt>}
|
||||
*/
|
||||
public async estGasAddDispenserContract(
|
||||
address: string,
|
||||
tokenAddress: string
|
||||
): Promise<any> {
|
||||
return estimateGas(address, this.router.methods.addDispenserContract, tokenAddress)
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a new contract to dispenser list, after is added, can be used when deploying a new pool
|
||||
* @param {String} address
|
||||
* @param {String} tokenAddress contract address to add
|
||||
* @return {Promise<TransactionReceipt>}
|
||||
*/
|
||||
public async addDispenserContract(
|
||||
address: string,
|
||||
tokenAddress: string
|
||||
): Promise<TransactionReceipt> {
|
||||
if ((await this.getOwner()) !== address) {
|
||||
throw new Error(`Caller is not Router Owner`)
|
||||
}
|
||||
|
||||
const estGas = await estimateGas(
|
||||
address,
|
||||
this.router.methods.addDispenserContract,
|
||||
tokenAddress
|
||||
)
|
||||
|
||||
// Invoke createToken function of the contract
|
||||
const trxReceipt = await this.router.methods.addDispenserContract(tokenAddress).send({
|
||||
from: address,
|
||||
gas: estGas + 1,
|
||||
gasPrice: await getFairGasPrice(this.web3, this.config)
|
||||
})
|
||||
|
||||
return trxReceipt
|
||||
}
|
||||
|
||||
/**
|
||||
* Estimate gas cost for addDispenserContract method
|
||||
* @param {String} address
|
||||
* @param {String} tokenAddress contract address to add
|
||||
* @return {Promise<TransactionReceipt>}
|
||||
*/
|
||||
public async estGasRemoveDispenserContract(
|
||||
address: string,
|
||||
tokenAddress: string
|
||||
): Promise<any> {
|
||||
return estimateGas(address, this.router.methods.removeDispenserContract, tokenAddress)
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a new contract to dispenser list, after is added, can be used when deploying a new pool
|
||||
* @param {String} address
|
||||
* @param {String} tokenAddress contract address to add
|
||||
* @return {Promise<TransactionReceipt>}
|
||||
*/
|
||||
public async removeDispenserContract(
|
||||
address: string,
|
||||
tokenAddress: string
|
||||
): Promise<TransactionReceipt> {
|
||||
if ((await this.getOwner()) !== address) {
|
||||
throw new Error(`Caller is not Router Owner`)
|
||||
}
|
||||
|
||||
const estGas = await estimateGas(
|
||||
address,
|
||||
this.router.methods.removeDispenserContract,
|
||||
tokenAddress
|
||||
)
|
||||
|
||||
// Invoke createToken function of the contract
|
||||
const trxReceipt = await this.router.methods
|
||||
.removeDispenserContract(tokenAddress)
|
||||
.send({
|
||||
from: address,
|
||||
gas: estGas + 1,
|
||||
gasPrice: await getFairGasPrice(this.web3, this.config)
|
||||
})
|
||||
|
||||
return trxReceipt
|
||||
}
|
||||
|
||||
/** Get OPF Fee per token
|
||||
* @return {Promise<number>} OPC fee for a specific baseToken
|
||||
*/
|
||||
public async getOPCFee(baseToken: string): Promise<number> {
|
||||
return await this.router.methods.getOPCFee(baseToken).call()
|
||||
}
|
||||
|
||||
/** Get Current OPF Fee
|
||||
* @return {Promise<number>} OPF fee
|
||||
*/
|
||||
public async getCurrentOPCFee(): Promise<number> {
|
||||
return await this.router.methods.swapOceanFee().call()
|
||||
}
|
||||
|
||||
/**
|
||||
* Estimate gas cost for updateOPFFee method
|
||||
* @param {String} address
|
||||
* @param {String} newFee new OPF Fee
|
||||
* @return {Promise<TransactionReceipt>}
|
||||
*/
|
||||
public async estGasUpdateOPCFee(
|
||||
address: string,
|
||||
newSwapOceanFee: number,
|
||||
newSwapNonOceanFee: number,
|
||||
newConsumeFee: number,
|
||||
newProviderFee: number
|
||||
): Promise<any> {
|
||||
return estimateGas(
|
||||
address,
|
||||
this.router.methods.updateOPCFee,
|
||||
newSwapOceanFee,
|
||||
newSwapNonOceanFee,
|
||||
newConsumeFee,
|
||||
newProviderFee
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a new contract to fixedRate list, after is added, can be used when deploying a new pool
|
||||
* @param {String} address
|
||||
* @param {number} newSwapOceanFee Amount charged for swapping with ocean approved tokens
|
||||
* @param {number} newSwapNonOceanFee Amount charged for swapping with non ocean approved tokens
|
||||
* @param {number} newConsumeFee Amount charged from consumeFees
|
||||
* @param {number} newProviderFee Amount charged for providerFees
|
||||
* @return {Promise<TransactionReceipt>}
|
||||
*/
|
||||
public async updateOPCFee(
|
||||
address: string,
|
||||
newSwapOceanFee: number,
|
||||
newSwapNonOceanFee: number,
|
||||
newConsumeFee: number,
|
||||
newProviderFee: number
|
||||
): Promise<TransactionReceipt> {
|
||||
if ((await this.getOwner()) !== address) {
|
||||
throw new Error(`Caller is not Router Owner`)
|
||||
}
|
||||
|
||||
const estGas = await estimateGas(
|
||||
address,
|
||||
this.router.methods.updateOPCFee,
|
||||
newSwapOceanFee,
|
||||
newSwapNonOceanFee,
|
||||
newConsumeFee,
|
||||
newProviderFee
|
||||
)
|
||||
|
||||
// Invoke createToken function of the contract
|
||||
const trxReceipt = await this.router.methods
|
||||
.updateOPCFee(newSwapOceanFee, newSwapNonOceanFee, newConsumeFee, newProviderFee)
|
||||
.send({
|
||||
from: address,
|
||||
gas: estGas + 1,
|
||||
gasPrice: await getFairGasPrice(this.web3, this.config)
|
||||
})
|
||||
|
||||
return trxReceipt
|
||||
}
|
||||
|
||||
/**
|
||||
* Estimate gas cost for addPoolTemplate method
|
||||
* @param {String} address
|
||||
* @param {String} templateAddress template address to add
|
||||
* @return {Promise<TransactionReceipt>}
|
||||
*/
|
||||
public async estGasAddPoolTemplate(
|
||||
address: string,
|
||||
templateAddress: string
|
||||
): Promise<any> {
|
||||
return estimateGas(address, this.router.methods.addPoolTemplate, templateAddress)
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a new template to poolTemplates mapping, after template is added,it can be used
|
||||
* @param {String} address
|
||||
* @param {String} templateAddress template address to add
|
||||
* @return {Promise<TransactionReceipt>}
|
||||
*/
|
||||
public async addPoolTemplate(
|
||||
address: string,
|
||||
templateAddress: string
|
||||
): Promise<TransactionReceipt> {
|
||||
if ((await this.getOwner()) !== address) {
|
||||
throw new Error(`Caller is not Router Owner`)
|
||||
}
|
||||
|
||||
const estGas = await estimateGas(
|
||||
address,
|
||||
this.router.methods.addPoolTemplate,
|
||||
templateAddress
|
||||
)
|
||||
|
||||
// Invoke createToken function of the contract
|
||||
const trxReceipt = await this.router.methods.addPoolTemplate(templateAddress).send({
|
||||
from: address,
|
||||
gas: estGas + 1,
|
||||
gasPrice: await getFairGasPrice(this.web3, this.config)
|
||||
})
|
||||
|
||||
return trxReceipt
|
||||
}
|
||||
|
||||
/**
|
||||
* Estimate gas cost for removePoolTemplate method
|
||||
* @param {String} address
|
||||
* @param {String} templateAddress template address to remove
|
||||
* @return {Promise<TransactionReceipt>}
|
||||
*/
|
||||
public async estGasRemovePoolTemplate(
|
||||
address: string,
|
||||
templateAddress: string
|
||||
): Promise<any> {
|
||||
return estimateGas(address, this.router.methods.removePoolTemplate, templateAddress)
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove template from poolTemplates mapping, after template is removed,it can be used anymore
|
||||
* @param {String} address
|
||||
* @param {String} templateAddress template address to remove
|
||||
* @return {Promise<TransactionReceipt>}
|
||||
*/
|
||||
public async removePoolTemplate(
|
||||
address: string,
|
||||
templateAddress: string
|
||||
): Promise<TransactionReceipt> {
|
||||
if ((await this.getOwner()) !== address) {
|
||||
throw new Error(`Caller is not Router Owner`)
|
||||
}
|
||||
|
||||
const estGas = await estimateGas(
|
||||
address,
|
||||
this.router.methods.removePoolTemplate,
|
||||
templateAddress
|
||||
)
|
||||
|
||||
// Invoke createToken function of the contract
|
||||
const trxReceipt = await this.router.methods
|
||||
.removePoolTemplate(templateAddress)
|
||||
.send({
|
||||
from: address,
|
||||
gas: estGas + 1,
|
||||
gasPrice: await getFairGasPrice(this.web3, this.config)
|
||||
})
|
||||
|
||||
return trxReceipt
|
||||
}
|
||||
}
|
@ -1 +0,0 @@
|
||||
export * from './Pool'
|
@ -1,436 +0,0 @@
|
||||
import Web3 from 'web3'
|
||||
import { AbiItem } from 'web3-utils'
|
||||
import { Contract } from 'web3-eth-contract'
|
||||
import { TransactionReceipt } from 'web3-eth'
|
||||
import Decimal from 'decimal.js'
|
||||
import defaultDispenserAbi from '@oceanprotocol/contracts/artifacts/contracts/pools/dispenser/Dispenser.sol/Dispenser.json'
|
||||
import {
|
||||
LoggerInstance as logger,
|
||||
getFairGasPrice,
|
||||
setContractDefaults,
|
||||
estimateGas,
|
||||
ConfigHelper
|
||||
} from '../../utils/'
|
||||
import { Datatoken } from '../../tokens'
|
||||
import { Config } from '../../models/index.js'
|
||||
|
||||
export interface DispenserToken {
|
||||
active: boolean
|
||||
owner: string
|
||||
maxTokens: string
|
||||
maxBalance: string
|
||||
balance: string
|
||||
isMinter: boolean
|
||||
allowedSwapper: string
|
||||
}
|
||||
|
||||
export class Dispenser {
|
||||
public web3: Web3 = null
|
||||
public dispenserAddress: string
|
||||
public config: Config
|
||||
public dispenserAbi: AbiItem | AbiItem[]
|
||||
public dispenserContract: Contract
|
||||
|
||||
/**
|
||||
* Instantiate Dispenser
|
||||
* @param {any} web3
|
||||
* @param {String} dispenserAddress
|
||||
* @param {any} dispenserABI
|
||||
*/
|
||||
constructor(
|
||||
web3: Web3,
|
||||
network?: string | number,
|
||||
dispenserAddress: string = null,
|
||||
dispenserAbi: AbiItem | AbiItem[] = null,
|
||||
config?: Config
|
||||
) {
|
||||
this.web3 = web3
|
||||
this.dispenserAddress = dispenserAddress
|
||||
this.dispenserAbi = dispenserAbi || (defaultDispenserAbi.abi as AbiItem[])
|
||||
this.config = config || new ConfigHelper().getConfig(network || 'unknown')
|
||||
if (web3)
|
||||
this.dispenserContract = setContractDefaults(
|
||||
new this.web3.eth.Contract(this.dispenserAbi, this.dispenserAddress),
|
||||
this.config
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Get information about a datatoken dispenser
|
||||
* @param {String} dtAddress
|
||||
* @return {Promise<FixedPricedExchange>} Exchange details
|
||||
*/
|
||||
public async status(dtAdress: string): Promise<DispenserToken> {
|
||||
try {
|
||||
const result: DispenserToken = await this.dispenserContract.methods
|
||||
.status(dtAdress)
|
||||
.call()
|
||||
result.maxTokens = this.web3.utils.fromWei(result.maxTokens)
|
||||
result.maxBalance = this.web3.utils.fromWei(result.maxBalance)
|
||||
result.balance = this.web3.utils.fromWei(result.balance)
|
||||
return result
|
||||
} catch (e) {
|
||||
logger.warn(`No dispenser available for datatoken: ${dtAdress}`)
|
||||
}
|
||||
return null
|
||||
}
|
||||
|
||||
/**
|
||||
* Estimate gas cost for create method
|
||||
* @param {String} dtAddress Datatoken address
|
||||
* @param {String} address Owner address
|
||||
* @param {String} maxTokens max tokens to dispense
|
||||
* @param {String} maxBalance max balance of requester
|
||||
* @param {String} allowedSwapper if !=0, only this address can request DTs
|
||||
* @return {Promise<any>}
|
||||
*/
|
||||
public async estGasCreate(
|
||||
dtAddress: string,
|
||||
address: string,
|
||||
maxTokens: string,
|
||||
maxBalance: string,
|
||||
allowedSwapper: string
|
||||
): Promise<any> {
|
||||
return estimateGas(
|
||||
address,
|
||||
this.dispenserContract.methods.create,
|
||||
dtAddress,
|
||||
this.web3.utils.toWei(maxTokens),
|
||||
this.web3.utils.toWei(maxBalance),
|
||||
address,
|
||||
allowedSwapper
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new Dispenser
|
||||
* @param {String} dtAddress Datatoken address
|
||||
* @param {String} address Owner address
|
||||
* @param {String} maxTokens max tokens to dispense
|
||||
* @param {String} maxBalance max balance of requester
|
||||
* @param {String} allowedSwapper only account that can ask tokens. set address(0) if not required
|
||||
* @return {Promise<TransactionReceipt>} transactionId
|
||||
*/
|
||||
public async create(
|
||||
dtAddress: string,
|
||||
address: string,
|
||||
maxTokens: string,
|
||||
maxBalance: string,
|
||||
allowedSwapper: string
|
||||
): Promise<TransactionReceipt> {
|
||||
const estGas = await estimateGas(
|
||||
address,
|
||||
this.dispenserContract.methods.create,
|
||||
dtAddress,
|
||||
this.web3.utils.toWei(maxTokens),
|
||||
this.web3.utils.toWei(maxBalance),
|
||||
address,
|
||||
allowedSwapper
|
||||
)
|
||||
|
||||
// Call createFixedRate contract method
|
||||
const trxReceipt = await this.dispenserContract.methods
|
||||
.create(
|
||||
dtAddress,
|
||||
this.web3.utils.toWei(maxTokens),
|
||||
this.web3.utils.toWei(maxBalance),
|
||||
address,
|
||||
allowedSwapper
|
||||
)
|
||||
.send({
|
||||
from: address,
|
||||
gas: estGas + 1,
|
||||
gasPrice: await getFairGasPrice(this.web3, this.config)
|
||||
})
|
||||
return trxReceipt
|
||||
}
|
||||
|
||||
/**
|
||||
* Estimate gas for activate method
|
||||
* @param {String} dtAddress
|
||||
* @param {Number} maxTokens max amount of tokens to dispense
|
||||
* @param {Number} maxBalance max balance of user. If user balance is >, then dispense will be rejected
|
||||
* @param {String} address User address (must be owner of the datatoken)
|
||||
* @return {Promise<any>}
|
||||
*/
|
||||
public async estGasActivate(
|
||||
dtAddress: string,
|
||||
maxTokens: string,
|
||||
maxBalance: string,
|
||||
address: string
|
||||
): Promise<any> {
|
||||
return estimateGas(
|
||||
address,
|
||||
this.dispenserContract.methods.activate,
|
||||
dtAddress,
|
||||
this.web3.utils.toWei(maxTokens),
|
||||
this.web3.utils.toWei(maxBalance)
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Activates a new dispener.
|
||||
* @param {String} dtAddress refers to datatoken address.
|
||||
* @param {Number} maxTokens max amount of tokens to dispense
|
||||
* @param {Number} maxBalance max balance of user. If user balance is >, then dispense will be rejected
|
||||
* @param {String} address User address (must be owner of the datatoken)
|
||||
* @return {Promise<TransactionReceipt>} TransactionReceipt
|
||||
*/
|
||||
public async activate(
|
||||
dtAddress: string,
|
||||
maxTokens: string,
|
||||
maxBalance: string,
|
||||
address: string
|
||||
): Promise<TransactionReceipt> {
|
||||
try {
|
||||
const estGas = await estimateGas(
|
||||
address,
|
||||
this.dispenserContract.methods.activate,
|
||||
dtAddress,
|
||||
this.web3.utils.toWei(maxTokens),
|
||||
this.web3.utils.toWei(maxBalance)
|
||||
)
|
||||
|
||||
const trxReceipt = await this.dispenserContract.methods
|
||||
.activate(
|
||||
dtAddress,
|
||||
this.web3.utils.toWei(maxTokens),
|
||||
this.web3.utils.toWei(maxBalance)
|
||||
)
|
||||
.send({
|
||||
from: address,
|
||||
gas: estGas + 1,
|
||||
gasPrice: await getFairGasPrice(this.web3, this.config)
|
||||
})
|
||||
return trxReceipt
|
||||
} catch (e) {
|
||||
logger.error(`ERROR: Failed to activate dispenser: ${e.message}`)
|
||||
}
|
||||
return null
|
||||
}
|
||||
|
||||
/**
|
||||
* Estimate gas for deactivate method
|
||||
* @param {String} dtAddress
|
||||
* @param {String} address User address (must be owner of the datatoken)
|
||||
* @return {Promise<any>}
|
||||
*/
|
||||
public async estGasDeactivate(dtAddress: string, address: string): Promise<any> {
|
||||
return estimateGas(address, this.dispenserContract.methods.deactivate, dtAddress)
|
||||
}
|
||||
|
||||
/**
|
||||
* Deactivate an existing dispenser.
|
||||
* @param {String} dtAddress refers to datatoken address.
|
||||
* @param {String} address User address (must be owner of the datatoken)
|
||||
* @return {Promise<TransactionReceipt>} TransactionReceipt
|
||||
*/
|
||||
public async deactivate(
|
||||
dtAddress: string,
|
||||
address: string
|
||||
): Promise<TransactionReceipt> {
|
||||
try {
|
||||
const estGas = await estimateGas(
|
||||
address,
|
||||
this.dispenserContract.methods.deactivate,
|
||||
dtAddress
|
||||
)
|
||||
|
||||
const trxReceipt = await this.dispenserContract.methods.deactivate(dtAddress).send({
|
||||
from: address,
|
||||
gas: estGas + 1,
|
||||
gasPrice: await getFairGasPrice(this.web3, this.config)
|
||||
})
|
||||
return trxReceipt
|
||||
} catch (e) {
|
||||
logger.error(`ERROR: Failed to activate dispenser: ${e.message}`)
|
||||
}
|
||||
return null
|
||||
}
|
||||
|
||||
/**
|
||||
* Estimate gas for setAllowedSwapper method
|
||||
* @param {String} dtAddress refers to datatoken address.
|
||||
* @param {String} address User address (must be owner of the datatoken)
|
||||
* @param {String} newAllowedSwapper refers to the new allowedSwapper
|
||||
* @return {Promise<any>}
|
||||
*/
|
||||
public async estGasSetAllowedSwapper(
|
||||
dtAddress: string,
|
||||
address: string,
|
||||
newAllowedSwapper: string
|
||||
): Promise<any> {
|
||||
return estimateGas(
|
||||
address,
|
||||
this.dispenserContract.methods.setAllowedSwapper,
|
||||
dtAddress,
|
||||
newAllowedSwapper
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets a new allowedSwapper.
|
||||
* @param {String} dtAddress refers to datatoken address.
|
||||
* @param {String} address User address (must be owner of the datatoken)
|
||||
* @param {String} newAllowedSwapper refers to the new allowedSwapper
|
||||
* @return {Promise<TransactionReceipt>} TransactionReceipt
|
||||
*/
|
||||
public async setAllowedSwapper(
|
||||
dtAddress: string,
|
||||
address: string,
|
||||
newAllowedSwapper: string
|
||||
): Promise<TransactionReceipt> {
|
||||
try {
|
||||
const estGas = await estimateGas(
|
||||
address,
|
||||
this.dispenserContract.methods.setAllowedSwapper,
|
||||
dtAddress,
|
||||
newAllowedSwapper
|
||||
)
|
||||
|
||||
const trxReceipt = await this.dispenserContract.methods
|
||||
.setAllowedSwapper(dtAddress, newAllowedSwapper)
|
||||
.send({
|
||||
from: address,
|
||||
gas: estGas + 1,
|
||||
gasPrice: await getFairGasPrice(this.web3, this.config)
|
||||
})
|
||||
return trxReceipt
|
||||
} catch (e) {
|
||||
logger.error(`ERROR: Failed to activate dispenser: ${e.message}`)
|
||||
}
|
||||
return null
|
||||
}
|
||||
|
||||
/**
|
||||
* Estimate gas for dispense method
|
||||
* @param {String} dtAddress refers to datatoken address.
|
||||
* @param {String} address User address (must be owner of the datatoken)
|
||||
* @param {String} newAllowedSwapper refers to the new allowedSwapper
|
||||
* @return {Promise<any>}
|
||||
*/
|
||||
public async estGasDispense(
|
||||
dtAddress: string,
|
||||
address: string,
|
||||
amount: string = '1',
|
||||
destination: string
|
||||
): Promise<any> {
|
||||
return estimateGas(
|
||||
address,
|
||||
this.dispenserContract.methods.dispense,
|
||||
dtAddress,
|
||||
this.web3.utils.toWei(amount),
|
||||
destination
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Dispense datatokens to caller.
|
||||
* The dispenser must be active, hold enough DT (or be able to mint more)
|
||||
* and respect maxTokens/maxBalance requirements
|
||||
* @param {String} dtAddress refers to datatoken address.
|
||||
* @param {String} address User address
|
||||
* @param {String} amount amount of datatokens required.
|
||||
* @param {String} destination who will receive the tokens
|
||||
* @return {Promise<TransactionReceipt>} TransactionReceipt
|
||||
*/
|
||||
public async dispense(
|
||||
dtAddress: string,
|
||||
address: string,
|
||||
amount: string = '1',
|
||||
destination: string
|
||||
): Promise<TransactionReceipt> {
|
||||
const estGas = await estimateGas(
|
||||
address,
|
||||
this.dispenserContract.methods.dispense,
|
||||
dtAddress,
|
||||
this.web3.utils.toWei(amount),
|
||||
destination
|
||||
)
|
||||
|
||||
try {
|
||||
const trxReceipt = await this.dispenserContract.methods
|
||||
.dispense(dtAddress, this.web3.utils.toWei(amount), destination)
|
||||
.send({
|
||||
from: address,
|
||||
gas: estGas + 1,
|
||||
gasPrice: await getFairGasPrice(this.web3, this.config)
|
||||
})
|
||||
return trxReceipt
|
||||
} catch (e) {
|
||||
logger.error(`ERROR: Failed to dispense tokens: ${e.message}`)
|
||||
}
|
||||
return null
|
||||
}
|
||||
|
||||
/**
|
||||
* Estimate gas for ownerWithdraw method
|
||||
* @param {String} dtAddress refers to datatoken address.
|
||||
* @param {String} address User address (must be owner of the datatoken)
|
||||
* @param {String} newAllowedSwapper refers to the new allowedSwapper
|
||||
* @return {Promise<any>}
|
||||
*/
|
||||
public async estGasOwnerWithdraw(dtAddress: string, address: string): Promise<any> {
|
||||
return estimateGas(address, this.dispenserContract.methods.ownerWithdraw, dtAddress)
|
||||
}
|
||||
|
||||
/**
|
||||
* Withdraw all tokens from the dispenser
|
||||
* @param {String} dtAddress refers to datatoken address.
|
||||
* @param {String} address User address (must be owner of the dispenser)
|
||||
* @return {Promise<TransactionReceipt>} TransactionReceipt
|
||||
*/
|
||||
public async ownerWithdraw(
|
||||
dtAddress: string,
|
||||
address: string
|
||||
): Promise<TransactionReceipt> {
|
||||
const estGas = await estimateGas(
|
||||
address,
|
||||
this.dispenserContract.methods.ownerWithdraw,
|
||||
dtAddress
|
||||
)
|
||||
|
||||
try {
|
||||
const trxReceipt = await this.dispenserContract.methods
|
||||
.ownerWithdraw(dtAddress)
|
||||
.send({
|
||||
from: address,
|
||||
gas: estGas + 1,
|
||||
gasPrice: await getFairGasPrice(this.web3, this.config)
|
||||
})
|
||||
return trxReceipt
|
||||
} catch (e) {
|
||||
logger.error(`ERROR: Failed to withdraw tokens: ${e.message}`)
|
||||
}
|
||||
return null
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if tokens can be dispensed
|
||||
* @param {String} dtAddress
|
||||
* @param {String} address User address that will receive datatokens
|
||||
* @param {String} amount amount of datatokens required.
|
||||
* @return {Promise<Boolean>}
|
||||
*/
|
||||
public async isDispensable(
|
||||
dtAddress: string,
|
||||
datatoken: Datatoken,
|
||||
address: string,
|
||||
amount: string = '1'
|
||||
): Promise<Boolean> {
|
||||
const status = await this.status(dtAddress)
|
||||
if (!status) return false
|
||||
// check active
|
||||
if (status.active === false) return false
|
||||
// check maxBalance
|
||||
const userBalance = new Decimal(await datatoken.balance(dtAddress, address))
|
||||
if (userBalance.greaterThanOrEqualTo(status.maxBalance)) return false
|
||||
// check maxAmount
|
||||
if (new Decimal(String(amount)).greaterThan(status.maxTokens)) return false
|
||||
// check dispenser balance
|
||||
const contractBalance = new Decimal(status.balance)
|
||||
if (contractBalance.greaterThanOrEqualTo(amount) || status.isMinter === true)
|
||||
return true
|
||||
return false
|
||||
}
|
||||
}
|
@ -1 +0,0 @@
|
||||
export * from './Dispenser'
|
File diff suppressed because it is too large
Load Diff
@ -1 +0,0 @@
|
||||
export * from './FixedRateExchange'
|
@ -1,5 +0,0 @@
|
||||
export * from './balancer'
|
||||
export * from './dispenser'
|
||||
export * from './fixedRate'
|
||||
export * from './ssContracts'
|
||||
export * from './Router'
|
@ -1 +0,0 @@
|
||||
export * from './SideStaking'
|
@ -1,6 +1,7 @@
|
||||
import { LoggerInstance, sleep } from '../utils'
|
||||
import { Asset, DDO, ValidateMetadata } from '../@types/'
|
||||
import fetch from 'cross-fetch'
|
||||
import { LoggerInstance, sleep } from '../utils'
|
||||
import { Asset, DDO, ValidateMetadata } from '../@types'
|
||||
|
||||
export class Aquarius {
|
||||
public aquariusURL
|
||||
/**
|
||||
@ -122,5 +123,3 @@ export class Aquarius {
|
||||
return status
|
||||
}
|
||||
}
|
||||
|
||||
export default Aquarius
|
@ -1,5 +1,6 @@
|
||||
import Web3 from 'web3'
|
||||
import { LoggerInstance, getData } from '../utils'
|
||||
import fetch from 'cross-fetch'
|
||||
import { LoggerInstance } from '../utils'
|
||||
import {
|
||||
FileMetadata,
|
||||
ComputeJob,
|
||||
@ -8,22 +9,10 @@ import {
|
||||
ComputeAsset,
|
||||
ComputeEnvironment,
|
||||
ProviderInitialize,
|
||||
ProviderComputeInitializeResults
|
||||
} from '../@types/'
|
||||
import { noZeroX } from '../utils/ConversionTypeHelper'
|
||||
import fetch from 'cross-fetch'
|
||||
export interface HttpCallback {
|
||||
(httpMethod: string, url: string, body: string, header: any): Promise<any>
|
||||
}
|
||||
|
||||
export interface ServiceEndpoint {
|
||||
serviceName: string
|
||||
method: string
|
||||
urlPath: string
|
||||
}
|
||||
export interface UserCustomParameters {
|
||||
[key: string]: any
|
||||
}
|
||||
ProviderComputeInitializeResults,
|
||||
ServiceEndpoint,
|
||||
UserCustomParameters
|
||||
} from '../@types'
|
||||
|
||||
export class Provider {
|
||||
/**
|
||||
@ -32,7 +21,7 @@ export class Provider {
|
||||
*/
|
||||
async getEndpoints(providerUri: string): Promise<any> {
|
||||
try {
|
||||
const endpoints = await getData(providerUri)
|
||||
const endpoints = await this.getData(providerUri)
|
||||
return await endpoints.json()
|
||||
} catch (e) {
|
||||
LoggerInstance.error('Finding the service endpoints failed:', e)
|
||||
@ -537,7 +526,7 @@ export class Provider {
|
||||
|
||||
let signatureMessage = consumerAddress
|
||||
signatureMessage += jobId || ''
|
||||
signatureMessage += (did && `${noZeroX(did)}`) || ''
|
||||
signatureMessage += (did && `${this.noZeroX(did)}`) || ''
|
||||
signatureMessage += nonce
|
||||
const signature = await this.signProviderRequest(
|
||||
web3,
|
||||
@ -546,7 +535,7 @@ export class Provider {
|
||||
)
|
||||
const payload = Object()
|
||||
payload.signature = signature
|
||||
payload.documentId = noZeroX(did)
|
||||
payload.documentId = this.noZeroX(did)
|
||||
payload.consumerAddress = consumerAddress
|
||||
if (jobId) payload.jobId = jobId
|
||||
|
||||
@ -601,7 +590,7 @@ export class Provider {
|
||||
: null
|
||||
|
||||
let url = `?consumerAddress=${consumerAddress}`
|
||||
url += (did && `&documentId=${noZeroX(did)}`) || ''
|
||||
url += (did && `&documentId=${this.noZeroX(did)}`) || ''
|
||||
url += (jobId && `&jobId=${jobId}`) || ''
|
||||
|
||||
if (!computeStatusUrl) return null
|
||||
@ -710,7 +699,7 @@ export class Provider {
|
||||
|
||||
let signatureMessage = consumerAddress
|
||||
signatureMessage += jobId || ''
|
||||
signatureMessage += (did && `${noZeroX(did)}`) || ''
|
||||
signatureMessage += (did && `${this.noZeroX(did)}`) || ''
|
||||
signatureMessage += nonce
|
||||
const signature = await this.signProviderRequest(
|
||||
web3,
|
||||
@ -718,7 +707,7 @@ export class Provider {
|
||||
signatureMessage
|
||||
)
|
||||
const payload = Object()
|
||||
payload.documentId = noZeroX(did)
|
||||
payload.documentId = this.noZeroX(did)
|
||||
payload.consumerAddress = consumerAddress
|
||||
payload.jobId = jobId
|
||||
if (signature) payload.signature = signature
|
||||
@ -777,7 +766,47 @@ export class Provider {
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
private noZeroX(input: string): string {
|
||||
return this.zeroXTransformer(input, false)
|
||||
}
|
||||
|
||||
private zeroXTransformer(input = '', zeroOutput: boolean): string {
|
||||
const { valid, output } = this.inputMatch(
|
||||
input,
|
||||
/^(?:0x)*([a-f0-9]+)$/i,
|
||||
'zeroXTransformer'
|
||||
)
|
||||
return (zeroOutput && valid ? '0x' : '') + output
|
||||
}
|
||||
|
||||
// Shared functions
|
||||
private inputMatch(
|
||||
input: string,
|
||||
regexp: RegExp,
|
||||
conversorName: string
|
||||
): { valid: boolean; output: string } {
|
||||
if (typeof input !== 'string') {
|
||||
LoggerInstance.debug('Not input string:')
|
||||
LoggerInstance.debug(input)
|
||||
throw new Error(`[${conversorName}] Expected string, input type: ${typeof input}`)
|
||||
}
|
||||
const match = input.match(regexp)
|
||||
if (!match) {
|
||||
LoggerInstance.warn(`[${conversorName}] Input transformation failed.`)
|
||||
return { valid: false, output: input }
|
||||
}
|
||||
return { valid: true, output: match[1] }
|
||||
}
|
||||
|
||||
private async getData(url: string): Promise<Response> {
|
||||
return fetch(url, {
|
||||
method: 'GET',
|
||||
headers: {
|
||||
'Content-type': 'application/json'
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
export const ProviderInstance = new Provider()
|
||||
export default ProviderInstance
|
@ -1 +1,2 @@
|
||||
export * from './Aquarius'
|
||||
export * from './Provider'
|
File diff suppressed because it is too large
Load Diff
1242
src/tokens/NFT.ts
1242
src/tokens/NFT.ts
File diff suppressed because it is too large
Load Diff
@ -1,2 +0,0 @@
|
||||
export * from './Datatoken'
|
||||
export * from './NFT'
|
@ -1,2 +1,4 @@
|
||||
export const ZERO_ADDRESS = '0x0000000000000000000000000000000000000000'
|
||||
export const GASLIMIT_DEFAULT = 1000000
|
||||
export const MAX_UINT_256 =
|
||||
'115792089237316195423570985008687907853269984665640564039457584007913129639934'
|
||||
|
@ -1,17 +1,8 @@
|
||||
import Web3 from 'web3'
|
||||
import BigNumber from 'bignumber.js'
|
||||
import { Contract } from 'web3-eth-contract'
|
||||
import { generateDtName } from './DatatokenName'
|
||||
import {
|
||||
Erc20CreateParams,
|
||||
FreCreationParams,
|
||||
FreOrderParams,
|
||||
PoolCreationParams
|
||||
} from '../@types'
|
||||
import { Config } from '../models'
|
||||
import { minAbi } from './minAbi'
|
||||
import LoggerInstance from './Logger'
|
||||
import { GASLIMIT_DEFAULT, ZERO_ADDRESS } from './Constants'
|
||||
import { Config } from '../config'
|
||||
import { minAbi, LoggerInstance, GASLIMIT_DEFAULT } from '.'
|
||||
|
||||
export function setContractDefaults(contract: Contract, config: Config): Contract {
|
||||
if (config) {
|
||||
@ -35,89 +26,6 @@ export async function getFairGasPrice(web3: Web3, config: Config): Promise<strin
|
||||
else return x.toString(10)
|
||||
}
|
||||
|
||||
export function getErcCreationParams(ercParams: Erc20CreateParams): any {
|
||||
let name: string, symbol: string
|
||||
// Generate name & symbol if not present
|
||||
if (!ercParams.name || !ercParams.symbol) {
|
||||
;({ name, symbol } = generateDtName())
|
||||
}
|
||||
return {
|
||||
templateIndex: ercParams.templateIndex,
|
||||
strings: [ercParams.name || name, ercParams.symbol || symbol],
|
||||
addresses: [
|
||||
ercParams.minter,
|
||||
ercParams.paymentCollector,
|
||||
ercParams.mpFeeAddress,
|
||||
ercParams.feeToken
|
||||
],
|
||||
uints: [Web3.utils.toWei(ercParams.cap), Web3.utils.toWei(ercParams.feeAmount)],
|
||||
bytess: []
|
||||
}
|
||||
}
|
||||
|
||||
export function getFreOrderParams(freParams: FreOrderParams): any {
|
||||
return {
|
||||
exchangeContract: freParams.exchangeContract,
|
||||
exchangeId: freParams.exchangeId,
|
||||
maxBaseTokenAmount: Web3.utils.toWei(freParams.maxBaseTokenAmount),
|
||||
swapMarketFee: Web3.utils.toWei(freParams.swapMarketFee),
|
||||
marketFeeAddress: freParams.marketFeeAddress
|
||||
}
|
||||
}
|
||||
|
||||
export function getFreCreationParams(freParams: FreCreationParams): any {
|
||||
if (!freParams.allowedConsumer) freParams.allowedConsumer = ZERO_ADDRESS
|
||||
const withMint = freParams.withMint ? 1 : 0
|
||||
|
||||
return {
|
||||
fixedPriceAddress: freParams.fixedRateAddress,
|
||||
addresses: [
|
||||
freParams.baseTokenAddress,
|
||||
freParams.owner,
|
||||
freParams.marketFeeCollector,
|
||||
freParams.allowedConsumer
|
||||
],
|
||||
uints: [
|
||||
freParams.baseTokenDecimals,
|
||||
freParams.datatokenDecimals,
|
||||
Web3.utils.toWei(freParams.fixedRate),
|
||||
Web3.utils.toWei(freParams.marketFee),
|
||||
withMint
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
export async function getPoolCreationParams(
|
||||
web3: Web3,
|
||||
poolParams: PoolCreationParams
|
||||
): Promise<any> {
|
||||
return {
|
||||
addresses: [
|
||||
poolParams.ssContract,
|
||||
poolParams.baseTokenAddress,
|
||||
poolParams.baseTokenSender,
|
||||
poolParams.publisherAddress,
|
||||
poolParams.marketFeeCollector,
|
||||
poolParams.poolTemplateAddress
|
||||
],
|
||||
ssParams: [
|
||||
Web3.utils.toWei(poolParams.rate),
|
||||
poolParams.baseTokenDecimals,
|
||||
Web3.utils.toWei(poolParams.vestingAmount),
|
||||
poolParams.vestedBlocks,
|
||||
await amountToUnits(
|
||||
web3,
|
||||
poolParams.baseTokenAddress,
|
||||
poolParams.initialBaseTokenLiquidity
|
||||
)
|
||||
],
|
||||
swapFees: [
|
||||
Web3.utils.toWei(poolParams.swapFeeLiquidityProvider),
|
||||
Web3.utils.toWei(poolParams.swapFeeMarketRunner)
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
export async function unitsToAmount(
|
||||
web3: Web3,
|
||||
token: string,
|
||||
@ -173,7 +81,7 @@ export async function amountToUnits(
|
||||
* @param {...any[]} args arguments of the function
|
||||
* @return {Promise<number>} gas cost of the function
|
||||
*/
|
||||
export async function estimateGas(
|
||||
export async function calculateEstimatedGas(
|
||||
from: string,
|
||||
functionToEstimateGas: Function,
|
||||
...args: any[]
|
||||
|
@ -1,27 +0,0 @@
|
||||
import { LoggerInstance } from './Logger'
|
||||
|
||||
export const zeroX = (input: string): string => zeroXTransformer(input, true)
|
||||
export const noZeroX = (input: string): string => zeroXTransformer(input, false)
|
||||
export function zeroXTransformer(input = '', zeroOutput: boolean): string {
|
||||
const { valid, output } = inputMatch(input, /^(?:0x)*([a-f0-9]+)$/i, 'zeroXTransformer')
|
||||
return (zeroOutput && valid ? '0x' : '') + output
|
||||
}
|
||||
|
||||
// Shared functions
|
||||
function inputMatch(
|
||||
input: string,
|
||||
regexp: RegExp,
|
||||
conversorName: string
|
||||
): { valid: boolean; output: string } {
|
||||
if (typeof input !== 'string') {
|
||||
LoggerInstance.debug('Not input string:')
|
||||
LoggerInstance.debug(input)
|
||||
throw new Error(`[${conversorName}] Expected string, input type: ${typeof input}`)
|
||||
}
|
||||
const match = input.match(regexp)
|
||||
if (!match) {
|
||||
LoggerInstance.warn(`[${conversorName}] Input transformation failed.`)
|
||||
return { valid: false, output: input }
|
||||
}
|
||||
return { valid: true, output: match[1] }
|
||||
}
|
@ -1,4 +1,4 @@
|
||||
import wordListDefault from '../data/words.json'
|
||||
import wordListDefault from './data/words.json'
|
||||
|
||||
/**
|
||||
* Generate new datatoken name & symbol from a word list
|
||||
|
@ -1,10 +1,10 @@
|
||||
import sha256 from 'crypto-js/sha256'
|
||||
import Web3 from 'web3'
|
||||
import LoggerInstance from './Logger'
|
||||
import { LoggerInstance } from '.'
|
||||
|
||||
export function generateDid(erc721Address: string, chainId: number): string {
|
||||
erc721Address = Web3.utils.toChecksumAddress(erc721Address)
|
||||
const checksum = sha256(erc721Address + chainId.toString(10))
|
||||
export function generateDid(nftAddress: string, chainId: number): string {
|
||||
nftAddress = Web3.utils.toChecksumAddress(nftAddress)
|
||||
const checksum = sha256(nftAddress + chainId.toString(10))
|
||||
return `did:op:${checksum.toString()}`
|
||||
}
|
||||
|
||||
|
@ -1,16 +1,5 @@
|
||||
import fetch from 'cross-fetch'
|
||||
import LoggerInstance from './Logger'
|
||||
import { DownloadResponse } from '../@types/DownloadResponse'
|
||||
|
||||
export async function fetchData(url: string, opts: RequestInit): Promise<Response> {
|
||||
const result = await fetch(url, opts)
|
||||
if (!result.ok) {
|
||||
LoggerInstance.error(`Error requesting [${opts.method}] ${url}`)
|
||||
LoggerInstance.error(`Response message: \n${await result.text()}`)
|
||||
throw result
|
||||
}
|
||||
return result
|
||||
}
|
||||
import { DownloadResponse } from '../@types'
|
||||
|
||||
export async function downloadFileBrowser(url: string): Promise<void> {
|
||||
const anchor = document.createElement('a')
|
||||
@ -42,37 +31,3 @@ export async function downloadFile(
|
||||
|
||||
return { data: await response.arrayBuffer(), filename }
|
||||
}
|
||||
|
||||
export async function getData(url: string): Promise<Response> {
|
||||
return fetch(url, {
|
||||
method: 'GET',
|
||||
headers: {
|
||||
'Content-type': 'application/json'
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
async function postWithHeaders(
|
||||
url: string,
|
||||
payload: BodyInit,
|
||||
headers: any
|
||||
): Promise<Response> {
|
||||
if (payload != null) {
|
||||
return fetch(url, {
|
||||
method: 'POST',
|
||||
body: payload,
|
||||
headers
|
||||
})
|
||||
} else {
|
||||
return fetch(url, {
|
||||
method: 'POST'
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
export async function postData(url: string, payload: BodyInit): Promise<Response> {
|
||||
const headers = {
|
||||
'Content-type': 'application/json'
|
||||
}
|
||||
return postWithHeaders(url, payload, headers)
|
||||
}
|
||||
|
@ -43,4 +43,3 @@ export class Logger {
|
||||
}
|
||||
|
||||
export const LoggerInstance = new Logger()
|
||||
export default LoggerInstance
|
||||
|
@ -1,5 +1,4 @@
|
||||
import Decimal from 'decimal.js'
|
||||
import { Pool } from '..'
|
||||
|
||||
export function calcMaxExactOut(balance: string): Decimal {
|
||||
return new Decimal(balance).div(2)
|
||||
@ -8,40 +7,3 @@ export function calcMaxExactOut(balance: string): Decimal {
|
||||
export function calcMaxExactIn(balance: string): Decimal {
|
||||
return new Decimal(balance).div(2)
|
||||
}
|
||||
export async function getMaxSwapExactOut(
|
||||
poolInstance: Pool,
|
||||
poolAddress: string,
|
||||
tokenAddress: string
|
||||
): Promise<Decimal> {
|
||||
const reserve = await poolInstance.getReserve(poolAddress, tokenAddress)
|
||||
return calcMaxExactOut(reserve)
|
||||
}
|
||||
|
||||
export async function getMaxSwapExactIn(
|
||||
poolInstance: Pool,
|
||||
poolAddress: string,
|
||||
tokenAddress: string
|
||||
): Promise<Decimal> {
|
||||
const reserve = await poolInstance.getReserve(poolAddress, tokenAddress)
|
||||
return calcMaxExactIn(reserve)
|
||||
}
|
||||
|
||||
export async function getMaxAddLiquidity(
|
||||
poolInstance: Pool,
|
||||
poolAddress: string,
|
||||
tokenAddress: string
|
||||
): Promise<Decimal> {
|
||||
const reserve = await poolInstance.getReserve(poolAddress, tokenAddress)
|
||||
|
||||
return calcMaxExactIn(reserve)
|
||||
}
|
||||
|
||||
export async function getMaxRemoveLiquidity(
|
||||
poolInstance: Pool,
|
||||
poolAddress: string,
|
||||
tokenAddress: string
|
||||
): Promise<Decimal> {
|
||||
const reserve = await poolInstance.getReserve(poolAddress, tokenAddress)
|
||||
|
||||
return calcMaxExactIn(reserve)
|
||||
}
|
||||
|
@ -1,5 +1,4 @@
|
||||
import Web3 from 'web3'
|
||||
import { LoggerInstance } from './Logger'
|
||||
|
||||
export async function signHash(web3: Web3, message: string, address: string) {
|
||||
let signedMessage = await web3.eth.sign(message, address)
|
||||
|
@ -1,72 +1,50 @@
|
||||
import Decimal from 'decimal.js'
|
||||
import { Contract } from 'web3-eth-contract'
|
||||
import {
|
||||
amountToUnits,
|
||||
estimateGas,
|
||||
getFairGasPrice,
|
||||
unitsToAmount
|
||||
} from './ContractUtils'
|
||||
import { minAbi } from './minAbi'
|
||||
import LoggerInstance from './Logger'
|
||||
import { TransactionReceipt } from 'web3-core'
|
||||
import Web3 from 'web3'
|
||||
|
||||
/**
|
||||
* Estimate gas cost for approval function
|
||||
* @param {String} account
|
||||
* @param {String} tokenAddress
|
||||
* @param {String} spender
|
||||
* @param {String} amount
|
||||
* @param {String} force
|
||||
* @param {Contract} contractInstance optional contract instance
|
||||
* @return {Promise<number>}
|
||||
*/
|
||||
export async function estApprove(
|
||||
web3: Web3,
|
||||
account: string,
|
||||
tokenAddress: string,
|
||||
spender: string,
|
||||
amount: string,
|
||||
contractInstance?: Contract
|
||||
): Promise<number> {
|
||||
const tokenContract = contractInstance || new web3.eth.Contract(minAbi, tokenAddress)
|
||||
|
||||
return estimateGas(account, tokenContract.methods.approve, spender, amount)
|
||||
}
|
||||
import {
|
||||
amountToUnits,
|
||||
calculateEstimatedGas,
|
||||
getFairGasPrice,
|
||||
unitsToAmount,
|
||||
minAbi,
|
||||
LoggerInstance
|
||||
} from '.'
|
||||
|
||||
/**
|
||||
* Approve spender to spent amount tokens
|
||||
* @param {String} account
|
||||
* @param {String} tokenAddress
|
||||
* @param {String} spender
|
||||
* @param {String} amount amount of ERC20 tokens (always expressed as wei)
|
||||
* @param {String} amount amount of ERC20 Datatokens (always expressed as wei)
|
||||
* @param {boolean} force if true, will overwrite any previous allowence. Else, will check if allowence is enough and will not send a transaction if it's not needed
|
||||
* @param {number} tokenDecimals optional number of decimals of the token
|
||||
*/
|
||||
export async function approve(
|
||||
export async function approve<G extends boolean = false>(
|
||||
web3: Web3,
|
||||
account: string,
|
||||
tokenAddress: string,
|
||||
spender: string,
|
||||
amount: string,
|
||||
force = false,
|
||||
tokenDecimals?: number
|
||||
): Promise<TransactionReceipt | string> {
|
||||
tokenDecimals?: number,
|
||||
estimateGas?: G
|
||||
): Promise<G extends false ? TransactionReceipt : number> {
|
||||
const tokenContract = new web3.eth.Contract(minAbi, tokenAddress)
|
||||
if (!force) {
|
||||
const currentAllowence = await allowance(web3, tokenAddress, account, spender)
|
||||
if (new Decimal(currentAllowence).greaterThanOrEqualTo(new Decimal(amount))) {
|
||||
return currentAllowence
|
||||
return null
|
||||
}
|
||||
}
|
||||
let result = null
|
||||
const amountFormatted = await amountToUnits(web3, tokenAddress, amount, tokenDecimals)
|
||||
const estGas = await estimateGas(
|
||||
const estGas = await calculateEstimatedGas(
|
||||
account,
|
||||
tokenContract.methods.approve,
|
||||
spender,
|
||||
amountFormatted
|
||||
)
|
||||
if (estimateGas) return estGas
|
||||
|
||||
try {
|
||||
result = await tokenContract.methods.approve(spender, amountFormatted).send({
|
||||
@ -83,53 +61,32 @@ export async function approve(
|
||||
}
|
||||
|
||||
/**
|
||||
* Estimate gas cost for transfer function
|
||||
* Moves amount tokens from the caller’s account to recipient.
|
||||
* @param {String} account
|
||||
* @param {String} tokenAddress
|
||||
* @param {String} recipient
|
||||
* @param {String} amount
|
||||
* @param {String} force
|
||||
* @param {Contract} contractInstance optional contract instance
|
||||
* @return {Promise<number>}
|
||||
* @param {String} amount amount of ERC20 Datatokens (not as wei)
|
||||
* @param {String} force if true, will overwrite any previous allowence. Else, will check if allowence is enough and will not send a transaction if it's not needed
|
||||
*/
|
||||
export async function estTransfer(
|
||||
export async function transfer<G extends boolean = false>(
|
||||
web3: Web3,
|
||||
account: string,
|
||||
tokenAddress: string,
|
||||
recipient: string,
|
||||
amount: string,
|
||||
contractInstance?: Contract
|
||||
): Promise<number> {
|
||||
const tokenContract = contractInstance || new web3.eth.Contract(minAbi, tokenAddress)
|
||||
|
||||
return estimateGas(account, tokenContract.methods.transfer, recipient, amount)
|
||||
}
|
||||
|
||||
/**
|
||||
* Moves amount tokens from the caller’s account to recipient.
|
||||
* @param {String} account
|
||||
* @param {String} tokenAddress
|
||||
* @param {String} recipient
|
||||
* @param {String} amount amount of ERC20 tokens (not as wei)
|
||||
* @param {String} force if true, will overwrite any previous allowence. Else, will check if allowence is enough and will not send a transaction if it's not needed
|
||||
*/
|
||||
export async function transfer(
|
||||
web3: Web3,
|
||||
account: string,
|
||||
tokenAddress: string,
|
||||
recipient: string,
|
||||
amount: string
|
||||
): Promise<TransactionReceipt | string> {
|
||||
estimateGas?: G
|
||||
): Promise<G extends false ? TransactionReceipt : number> {
|
||||
const tokenContract = new web3.eth.Contract(minAbi, tokenAddress)
|
||||
|
||||
let result = null
|
||||
const amountFormatted = await amountToUnits(web3, tokenAddress, amount)
|
||||
const estGas = await estimateGas(
|
||||
const estGas = await calculateEstimatedGas(
|
||||
account,
|
||||
tokenContract.methods.transfer,
|
||||
recipient,
|
||||
amountFormatted
|
||||
)
|
||||
if (estimateGas) return estGas
|
||||
|
||||
try {
|
||||
result = await tokenContract.methods.transfer(recipient, amountFormatted).send({
|
||||
@ -144,7 +101,7 @@ export async function transfer(
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Allowance for any erc20
|
||||
* Get Allowance for any Datatoken
|
||||
* @param {Web3} web3
|
||||
* @param {String } tokenAdress
|
||||
* @param {String} account
|
||||
@ -165,7 +122,7 @@ export async function allowance(
|
||||
}
|
||||
|
||||
/**
|
||||
* Get balance for any erc20
|
||||
* Get balance for any Datatoken
|
||||
* @param {Web3} web3
|
||||
* @param {String} tokenAdress
|
||||
* @param {String} owner
|
||||
@ -185,7 +142,7 @@ export async function balance(
|
||||
}
|
||||
|
||||
/**
|
||||
* Get decimals for any erc20
|
||||
* Get decimals for any Datatoken
|
||||
* @param {Web3} web3
|
||||
* @param {String} tokenAdress
|
||||
* @return {Promise<number>} Number of decimals of the token
|
||||
|
@ -1,11 +1,11 @@
|
||||
export * from './Logger'
|
||||
export * from './DatatokenName'
|
||||
export * from './ContractUtils'
|
||||
export * from './FetchHelper'
|
||||
export * from './ConfigHelper'
|
||||
export * from './DdoHelpers'
|
||||
export * from './Constants'
|
||||
export * from './ContractUtils'
|
||||
export * from './DatatokenName'
|
||||
export * from './DdoHelpers'
|
||||
export * from './FetchHelper'
|
||||
export * from './General'
|
||||
export * from './Logger'
|
||||
export * from './minAbi'
|
||||
export * from './PoolHelpers'
|
||||
export * from './SignatureUtils'
|
||||
export * from './TokenUtils'
|
||||
export * from './General'
|
||||
export * from './PoolHelpers'
|
||||
|
@ -49,14 +49,14 @@ const estimateGasAndDeployContract = async (
|
||||
export interface Addresses {
|
||||
opfCommunityFeeCollectorAddress: string
|
||||
poolTemplateAddress: string
|
||||
erc20TemplateAddress: string
|
||||
erc721TemplateAddress: string
|
||||
datatokenTemplateAddress: string
|
||||
nftTemplateAddress: string
|
||||
oceanAddress: string
|
||||
routerAddress: string
|
||||
sideStakingAddress: string
|
||||
fixedRateAddress: string
|
||||
dispenserAddress: string
|
||||
erc721FactoryAddress: string
|
||||
nftFactoryAddress: string
|
||||
daiAddress: string
|
||||
usdcAddress: string
|
||||
}
|
||||
@ -87,8 +87,8 @@ export const deployContracts = async (web3: Web3, owner: string): Promise<Addres
|
||||
owner
|
||||
))
|
||||
|
||||
// deploy ERC20 template
|
||||
addresses.erc20TemplateAddress =
|
||||
// deploy Datatoken template
|
||||
addresses.datatokenTemplateAddress =
|
||||
configAddresses.ERC20Template['1'] ||
|
||||
(await estimateGasAndDeployContract(
|
||||
web3,
|
||||
@ -98,8 +98,8 @@ export const deployContracts = async (web3: Web3, owner: string): Promise<Addres
|
||||
owner
|
||||
))
|
||||
|
||||
// deploy ERC721 template
|
||||
addresses.erc721TemplateAddress =
|
||||
// deploy NFT template
|
||||
addresses.nftTemplateAddress =
|
||||
configAddresses.ERC721Template['1'] ||
|
||||
(await estimateGasAndDeployContract(
|
||||
web3,
|
||||
@ -170,16 +170,16 @@ export const deployContracts = async (web3: Web3, owner: string): Promise<Addres
|
||||
owner
|
||||
))
|
||||
|
||||
// deploy ERC721 factory
|
||||
addresses.erc721FactoryAddress =
|
||||
// deploy NFT factory
|
||||
addresses.nftFactoryAddress =
|
||||
configAddresses.ERC721Factory ||
|
||||
(await estimateGasAndDeployContract(
|
||||
web3,
|
||||
ERC721Factory.abi as AbiItem[],
|
||||
ERC721Factory.bytecode,
|
||||
[
|
||||
addresses.erc721TemplateAddress,
|
||||
addresses.erc20TemplateAddress,
|
||||
addresses.nftTemplateAddress,
|
||||
addresses.datatokenTemplateAddress,
|
||||
addresses.opfCommunityFeeCollectorAddress,
|
||||
addresses.routerAddress
|
||||
],
|
||||
@ -215,7 +215,7 @@ export const deployContracts = async (web3: Web3, owner: string): Promise<Addres
|
||||
)
|
||||
|
||||
await RouterContract.methods
|
||||
.addFactory(addresses.erc721FactoryAddress)
|
||||
.addFactory(addresses.nftFactoryAddress)
|
||||
.send({ from: owner })
|
||||
await RouterContract.methods
|
||||
.addFixedRateContract(addresses.fixedRateAddress)
|
||||
|
@ -1,12 +1,8 @@
|
||||
import Web3 from 'web3'
|
||||
import fs from 'fs'
|
||||
import { homedir } from 'os'
|
||||
import {
|
||||
ConfigHelper,
|
||||
configHelperNetworks,
|
||||
LoggerInstance,
|
||||
LogLevel
|
||||
} from '../src/utils'
|
||||
import { ConfigHelper, configHelperNetworks } from '../src/config'
|
||||
import { LoggerInstance, LogLevel } from '../src/utils'
|
||||
|
||||
LoggerInstance.setLevel(LogLevel.Error)
|
||||
|
||||
|
@ -97,7 +97,7 @@ import {
|
||||
Dispenser,
|
||||
DispenserCreationParams,
|
||||
downloadFile,
|
||||
Erc20CreateParams,
|
||||
DatatokenCreateParams,
|
||||
FixedRateExchange,
|
||||
FreCreationParams,
|
||||
getHash,
|
||||
@ -252,7 +252,7 @@ describe('Marketplace flow tests', async () => {
|
||||
owner: publisherAccount
|
||||
}
|
||||
|
||||
const erc20Params: Erc20CreateParams = {
|
||||
const datatokenParams: DatatokenCreateParams = {
|
||||
templateIndex: 1,
|
||||
cap: '100000',
|
||||
feeAmount: '0',
|
||||
@ -278,7 +278,7 @@ describe('Marketplace flow tests', async () => {
|
||||
swapFeeMarketRunner: '0.001'
|
||||
}
|
||||
/// ```
|
||||
/// Before we call the contract we have to call `approve` so that the contract can move our tokens. This is standard when using any ERC20 tokens
|
||||
/// Before we call the contract we have to call `approve` so that the contract can move our tokens. This is standard when using any ERC20 Datatokens
|
||||
/// ```Typescript
|
||||
await approve(
|
||||
web3,
|
||||
@ -291,10 +291,10 @@ describe('Marketplace flow tests', async () => {
|
||||
/// ```
|
||||
/// Now we can make the contract call
|
||||
/// ```Typescript
|
||||
const tx = await factory.createNftErc20WithPool(
|
||||
const tx = await factory.createNftWithDatatokenWithPool(
|
||||
publisherAccount,
|
||||
nftParams,
|
||||
erc20Params,
|
||||
datatokenParams,
|
||||
poolParams
|
||||
)
|
||||
|
||||
@ -353,7 +353,7 @@ describe('Marketplace flow tests', async () => {
|
||||
const pool = new Pool(web3)
|
||||
|
||||
/// ```
|
||||
/// Before we call the contract we have to call `approve` so that the contract can move our tokens. This is standard when using any ERC20 tokens
|
||||
/// Before we call the contract we have to call `approve` so that the contract can move our tokens. This is standard when using any ERC20 Datatokens
|
||||
/// ```Typescript
|
||||
await approve(web3, stakerAccount, addresses.Ocean, poolAddress, '5', true)
|
||||
|
||||
@ -402,7 +402,7 @@ describe('Marketplace flow tests', async () => {
|
||||
console.log(`Consumer ${POOL_NFT_SYMBOL} balance before swap: ${consumerDTBalance}`)
|
||||
|
||||
/// ```
|
||||
/// Before we call the contract we have to call `approve` so that the contract can move our tokens. This is standard when using any ERC20 tokens
|
||||
/// Before we call the contract we have to call `approve` so that the contract can move our tokens. This is standard when using any ERC20 Datatokens
|
||||
/// ```Typescript
|
||||
await approve(web3, consumerAccount, addresses.Ocean, poolAddress, '100')
|
||||
|
||||
@ -526,7 +526,7 @@ describe('Marketplace flow tests', async () => {
|
||||
owner: publisherAccount
|
||||
}
|
||||
|
||||
const erc20Params: Erc20CreateParams = {
|
||||
const datatokenParams: DatatokenCreateParams = {
|
||||
templateIndex: 1,
|
||||
cap: '100000',
|
||||
feeAmount: '0',
|
||||
@ -549,10 +549,10 @@ describe('Marketplace flow tests', async () => {
|
||||
withMint: false
|
||||
}
|
||||
|
||||
const tx = await factory.createNftErc20WithFixedRate(
|
||||
const tx = await factory.createNftWithDatatokenWithFixedRate(
|
||||
publisherAccount,
|
||||
nftParams,
|
||||
erc20Params,
|
||||
datatokenParams,
|
||||
freParams
|
||||
)
|
||||
|
||||
@ -614,9 +614,9 @@ describe('Marketplace flow tests', async () => {
|
||||
|
||||
it('7.3 Marketplace displays fixed rate asset for sale', async () => {
|
||||
/// ```Typescript
|
||||
const fixedRate = new FixedRateExchange(web3, freAddress)
|
||||
const fixedRate = new FixedRateExchange(freAddress, web3)
|
||||
const oceanAmount = await (
|
||||
await fixedRate.calcBaseInGivenOutDT(freId, '1')
|
||||
await fixedRate.calcBaseInGivenDatatokensOut(freId, '1')
|
||||
).baseTokenAmount
|
||||
/// ```
|
||||
/// Now that the market has fetched those values it can display the asset on the front end. In our case we will just console log the results:
|
||||
@ -644,7 +644,7 @@ describe('Marketplace flow tests', async () => {
|
||||
console.log(`Consumer ${FRE_NFT_SYMBOL} balance before swap: ${consumerDTBalance}`)
|
||||
|
||||
/// ```
|
||||
/// Before we call the contract we have to call `approve` so that the contract can move our tokens. This is standard when using any ERC20 tokens
|
||||
/// Before we call the contract we have to call `approve` so that the contract can move our tokens. This is standard when using any ERC20 Datatokens
|
||||
/// ```Typescript
|
||||
await approve(web3, consumerAccount, addresses.Ocean, freAddress, '100')
|
||||
await approve(
|
||||
@ -655,11 +655,11 @@ describe('Marketplace flow tests', async () => {
|
||||
DATATOKEN_AMOUNT
|
||||
)
|
||||
|
||||
const fixedRate = new FixedRateExchange(web3, freAddress)
|
||||
const fixedRate = new FixedRateExchange(freAddress, web3)
|
||||
/// ```
|
||||
/// Now we can make the contract call
|
||||
/// ```Typescript
|
||||
await fixedRate.buyDT(consumerAccount, freId, '1', '2')
|
||||
await fixedRate.buyDatatokens(consumerAccount, freId, '1', '2')
|
||||
|
||||
consumerOCEANBalance = await balance(web3, addresses.Ocean, consumerAccount)
|
||||
console.log(`Consumer OCEAN balance after swap: ${consumerOCEANBalance}`)
|
||||
@ -748,7 +748,7 @@ describe('Marketplace flow tests', async () => {
|
||||
owner: publisherAccount
|
||||
}
|
||||
|
||||
const erc20Params: Erc20CreateParams = {
|
||||
const datatokenParams: DatatokenCreateParams = {
|
||||
templateIndex: 1,
|
||||
cap: '100000',
|
||||
feeAmount: '0',
|
||||
@ -766,10 +766,10 @@ describe('Marketplace flow tests', async () => {
|
||||
allowedSwapper: ZERO_ADDRESS
|
||||
}
|
||||
|
||||
const tx = await factory.createNftErc20WithDispenser(
|
||||
const tx = await factory.createNftWithDatatokenWithDispenser(
|
||||
publisherAccount,
|
||||
nftParams,
|
||||
erc20Params,
|
||||
datatokenParams,
|
||||
dispenserParams
|
||||
)
|
||||
|
||||
@ -826,7 +826,7 @@ describe('Marketplace flow tests', async () => {
|
||||
it('8.3 Consumer gets a dispenser data asset, and downloads it', async () => {
|
||||
/// ```Typescript
|
||||
const datatoken = new Datatoken(web3)
|
||||
const dispenser = new Dispenser(web3, null, addresses.Dispenser)
|
||||
const dispenser = new Dispenser(addresses.Dispenser, web3)
|
||||
|
||||
let consumerDTBalance = await balance(
|
||||
web3,
|
||||
|
@ -13,7 +13,7 @@ import {
|
||||
ZERO_ADDRESS
|
||||
} from '../../src'
|
||||
import {
|
||||
Erc20CreateParams,
|
||||
DatatokenCreateParams,
|
||||
ComputeJob,
|
||||
ComputeAsset,
|
||||
ComputeAlgorithm,
|
||||
@ -232,7 +232,7 @@ async function createAsset(
|
||||
transferable: true,
|
||||
owner: owner
|
||||
}
|
||||
const erc20ParamsAsset: Erc20CreateParams = {
|
||||
const datatokenParams: DatatokenCreateParams = {
|
||||
templateIndex: 1,
|
||||
cap: '100000',
|
||||
feeAmount: '0',
|
||||
@ -242,9 +242,13 @@ async function createAsset(
|
||||
mpFeeAddress: ZERO_ADDRESS
|
||||
}
|
||||
|
||||
const result = await Factory.createNftWithErc20(owner, nftParamsAsset, erc20ParamsAsset)
|
||||
const result = await Factory.createNftWithDatatoken(
|
||||
owner,
|
||||
nftParamsAsset,
|
||||
datatokenParams
|
||||
)
|
||||
|
||||
const erc721AddressAsset = result.events.NFTCreated.returnValues[0]
|
||||
const nftAddress = result.events.NFTCreated.returnValues[0]
|
||||
const datatokenAddressAsset = result.events.TokenCreated.returnValues[0]
|
||||
// create the files encrypted string
|
||||
let providerResponse = await ProviderInstance.encrypt(assetUrl, providerUrl)
|
||||
@ -252,16 +256,15 @@ async function createAsset(
|
||||
ddo.services[0].datatokenAddress = datatokenAddressAsset
|
||||
ddo.services[0].serviceEndpoint = providerUrl
|
||||
// update ddo and set the right did
|
||||
ddo.nftAddress = web3.utils.toChecksumAddress(erc721AddressAsset)
|
||||
ddo.nftAddress = web3.utils.toChecksumAddress(nftAddress)
|
||||
ddo.id =
|
||||
'did:op:' +
|
||||
SHA256(web3.utils.toChecksumAddress(erc721AddressAsset) + chain.toString(10))
|
||||
'did:op:' + SHA256(web3.utils.toChecksumAddress(nftAddress) + chain.toString(10))
|
||||
providerResponse = await ProviderInstance.encrypt(ddo, providerUrl)
|
||||
const encryptedResponse = await providerResponse
|
||||
const validateResult = await aquarius.validate(ddo)
|
||||
assert(validateResult.valid, 'Could not validate metadata')
|
||||
await nft.setMetadata(
|
||||
erc721AddressAsset,
|
||||
nftAddress,
|
||||
owner,
|
||||
0,
|
||||
providerUrl,
|
||||
|
@ -15,7 +15,7 @@ import {
|
||||
import {
|
||||
ValidateMetadata,
|
||||
DDO,
|
||||
Erc20CreateParams,
|
||||
DatatokenCreateParams,
|
||||
PoolCreationParams,
|
||||
FreCreationParams,
|
||||
DispenserCreationParams
|
||||
@ -95,7 +95,7 @@ describe('Publish tests', async () => {
|
||||
)
|
||||
})
|
||||
|
||||
it('should publish a dataset with pool (create NFT + ERC20 + pool) and with Metdata proof', async () => {
|
||||
it('should publish a dataset with pool (create NFT + Datatoken + pool) and with Metdata proof', async () => {
|
||||
const poolDdo: DDO = { ...genericAsset }
|
||||
|
||||
const nftParams: NftCreateData = {
|
||||
@ -107,7 +107,7 @@ describe('Publish tests', async () => {
|
||||
owner: publisherAccount
|
||||
}
|
||||
|
||||
const erc20Params: Erc20CreateParams = {
|
||||
const datatokenParams: DatatokenCreateParams = {
|
||||
templateIndex: 1,
|
||||
cap: '100000',
|
||||
feeAmount: '0',
|
||||
@ -133,10 +133,10 @@ describe('Publish tests', async () => {
|
||||
swapFeeMarketRunner: '0.001'
|
||||
}
|
||||
|
||||
const bundleNFT = await factory.createNftErc20WithPool(
|
||||
const bundleNFT = await factory.createNftWithDatatokenWithPool(
|
||||
publisherAccount,
|
||||
nftParams,
|
||||
erc20Params,
|
||||
datatokenParams,
|
||||
poolParams
|
||||
)
|
||||
|
||||
@ -179,7 +179,7 @@ describe('Publish tests', async () => {
|
||||
assert(resolvedDDO, 'Cannot fetch DDO from Aquarius')
|
||||
})
|
||||
|
||||
it('should publish a dataset with fixed price (create NFT + ERC20 + fixed price) with an explicit empty Metadata Proof', async () => {
|
||||
it('should publish a dataset with fixed price (create NFT + Datoken + fixed price) with an explicit empty Metadata Proof', async () => {
|
||||
const fixedPriceDdo: DDO = { ...genericAsset }
|
||||
|
||||
const nftParams: NftCreateData = {
|
||||
@ -191,7 +191,7 @@ describe('Publish tests', async () => {
|
||||
owner: publisherAccount
|
||||
}
|
||||
|
||||
const erc20Params: Erc20CreateParams = {
|
||||
const datatokenParams: DatatokenCreateParams = {
|
||||
templateIndex: 1,
|
||||
cap: '100000',
|
||||
feeAmount: '0',
|
||||
@ -214,10 +214,10 @@ describe('Publish tests', async () => {
|
||||
withMint: false
|
||||
}
|
||||
|
||||
const bundleNFT = await factory.createNftErc20WithFixedRate(
|
||||
const bundleNFT = await factory.createNftWithDatatokenWithFixedRate(
|
||||
publisherAccount,
|
||||
nftParams,
|
||||
erc20Params,
|
||||
datatokenParams,
|
||||
fixedPriceParams
|
||||
)
|
||||
|
||||
@ -258,7 +258,7 @@ describe('Publish tests', async () => {
|
||||
assert(resolvedDDO, 'Cannot fetch DDO from Aquarius')
|
||||
})
|
||||
|
||||
it('should publish a dataset with dispenser (create NFT + ERC20 + dispenser) with no defined MetadataProof', async () => {
|
||||
it('should publish a dataset with dispenser (create NFT + Datatoken + dispenser) with no defined MetadataProof', async () => {
|
||||
const dispenserDdo: DDO = { ...genericAsset }
|
||||
|
||||
const nftParams: NftCreateData = {
|
||||
@ -270,7 +270,7 @@ describe('Publish tests', async () => {
|
||||
owner: publisherAccount
|
||||
}
|
||||
|
||||
const erc20Params: Erc20CreateParams = {
|
||||
const datatokenParams: DatatokenCreateParams = {
|
||||
templateIndex: 1,
|
||||
cap: '100000',
|
||||
feeAmount: '0',
|
||||
@ -288,10 +288,10 @@ describe('Publish tests', async () => {
|
||||
allowedSwapper: ZERO_ADDRESS
|
||||
}
|
||||
|
||||
const bundleNFT = await factory.createNftErc20WithDispenser(
|
||||
const bundleNFT = await factory.createNftWithDatatokenWithDispenser(
|
||||
publisherAccount,
|
||||
nftParams,
|
||||
erc20Params,
|
||||
datatokenParams,
|
||||
dispenserParams
|
||||
)
|
||||
|
||||
|
@ -13,7 +13,7 @@ import {
|
||||
downloadFile,
|
||||
ZERO_ADDRESS
|
||||
} from '../../src'
|
||||
import { ProviderFees, Erc20CreateParams, DDO } from '../../src/@types'
|
||||
import { ProviderFees, DatatokenCreateParams, DDO } from '../../src/@types'
|
||||
|
||||
describe('Simple Publish & consume test', async () => {
|
||||
let config: Config
|
||||
@ -72,7 +72,7 @@ describe('Simple Publish & consume test', async () => {
|
||||
consumerAccount = accounts[1]
|
||||
})
|
||||
|
||||
it('should publish a dataset (create NFT + ERC20)', async () => {
|
||||
it('should publish a dataset (create NFT + Datatoken)', async () => {
|
||||
const nft = new Nft(web3)
|
||||
const datatoken = new Datatoken(web3)
|
||||
const Factory = new NftFactory(addresses.ERC721Factory, web3)
|
||||
@ -86,7 +86,7 @@ describe('Simple Publish & consume test', async () => {
|
||||
owner: publisherAccount
|
||||
}
|
||||
|
||||
const erc20Params: Erc20CreateParams = {
|
||||
const datatokenParams: DatatokenCreateParams = {
|
||||
templateIndex: 1,
|
||||
cap: '100000',
|
||||
feeAmount: '0',
|
||||
@ -96,8 +96,12 @@ describe('Simple Publish & consume test', async () => {
|
||||
mpFeeAddress: ZERO_ADDRESS
|
||||
}
|
||||
|
||||
const tx = await Factory.createNftWithErc20(publisherAccount, nftParams, erc20Params)
|
||||
const erc721Address = tx.events.NFTCreated.returnValues[0]
|
||||
const tx = await Factory.createNftWithDatatoken(
|
||||
publisherAccount,
|
||||
nftParams,
|
||||
datatokenParams
|
||||
)
|
||||
const nftAddress = tx.events.NFTCreated.returnValues[0]
|
||||
const datatokenAddress = tx.events.TokenCreated.returnValues[0]
|
||||
|
||||
// create the files encrypted string
|
||||
@ -105,16 +109,16 @@ describe('Simple Publish & consume test', async () => {
|
||||
ddo.services[0].files = await providerResponse
|
||||
ddo.services[0].datatokenAddress = datatokenAddress
|
||||
// update ddo and set the right did
|
||||
ddo.nftAddress = erc721Address
|
||||
ddo.nftAddress = nftAddress
|
||||
const chain = await web3.eth.getChainId()
|
||||
ddo.id =
|
||||
'did:op:' + SHA256(web3.utils.toChecksumAddress(erc721Address) + chain.toString(10))
|
||||
'did:op:' + SHA256(web3.utils.toChecksumAddress(nftAddress) + chain.toString(10))
|
||||
|
||||
providerResponse = await ProviderInstance.encrypt(ddo, providerUrl)
|
||||
const encryptedResponse = await providerResponse
|
||||
const metadataHash = getHash(JSON.stringify(ddo))
|
||||
await nft.setMetadata(
|
||||
erc721Address,
|
||||
nftAddress,
|
||||
publisherAccount,
|
||||
0,
|
||||
providerUrl,
|
||||
@ -127,7 +131,7 @@ describe('Simple Publish & consume test', async () => {
|
||||
const resolvedDDO = await aquarius.waitForAqua(ddo.id)
|
||||
assert(resolvedDDO, 'Cannot fetch DDO from Aquarius')
|
||||
|
||||
// mint 1 ERC20 and send it to the consumer
|
||||
// mint 1 Datatoken and send it to the consumer
|
||||
await datatoken.mint(datatokenAddress, publisherAccount, '1', consumerAccount)
|
||||
|
||||
// initialize provider
|
||||
|
@ -16,7 +16,7 @@ import {
|
||||
import {
|
||||
ProviderFees,
|
||||
FreCreationParams,
|
||||
Erc20CreateParams,
|
||||
DatatokenCreateParams,
|
||||
PoolCreationParams
|
||||
} from '../../../src/@types'
|
||||
|
||||
@ -43,7 +43,7 @@ describe('Nft Factory test', () => {
|
||||
owner: factoryOwner
|
||||
}
|
||||
|
||||
const ercParams: Erc20CreateParams = {
|
||||
const dtParams: DatatokenCreateParams = {
|
||||
templateIndex: 1,
|
||||
minter: nftOwner,
|
||||
paymentCollector: user2,
|
||||
@ -63,9 +63,9 @@ describe('Nft Factory test', () => {
|
||||
user2 = accounts[3]
|
||||
|
||||
nftData.owner = factoryOwner
|
||||
ercParams.minter = nftOwner
|
||||
ercParams.paymentCollector = user2
|
||||
ercParams.mpFeeAddress = user1
|
||||
dtParams.minter = nftOwner
|
||||
dtParams.paymentCollector = user2
|
||||
dtParams.mpFeeAddress = user1
|
||||
})
|
||||
|
||||
it('should deploy contracts', async () => {
|
||||
@ -73,7 +73,7 @@ describe('Nft Factory test', () => {
|
||||
})
|
||||
|
||||
it('should initiate NFTFactory instance', async () => {
|
||||
nftFactory = new NftFactory(contracts.erc721FactoryAddress, web3)
|
||||
nftFactory = new NftFactory(contracts.nftFactoryAddress, web3)
|
||||
})
|
||||
|
||||
it('#getOwner - should return actual owner', async () => {
|
||||
@ -84,13 +84,13 @@ describe('Nft Factory test', () => {
|
||||
it('#getNFTTemplate - should return NFT template struct', async () => {
|
||||
const nftTemplate = await nftFactory.getNFTTemplate(1)
|
||||
assert(nftTemplate.isActive === true)
|
||||
assert(nftTemplate.templateAddress === contracts.erc721TemplateAddress)
|
||||
assert(nftTemplate.templateAddress === contracts.nftTemplateAddress)
|
||||
})
|
||||
|
||||
it('#getTokenTemplate - should return Token template struct', async () => {
|
||||
const tokenTemplate = await nftFactory.getTokenTemplate(1)
|
||||
assert(tokenTemplate.isActive === true)
|
||||
assert(tokenTemplate.templateAddress === contracts.erc20TemplateAddress)
|
||||
assert(tokenTemplate.templateAddress === contracts.datatokenTemplateAddress)
|
||||
})
|
||||
|
||||
it('#createNft - should create an NFT', async () => {
|
||||
@ -105,7 +105,7 @@ describe('Nft Factory test', () => {
|
||||
|
||||
it('#createNftwithErc - should create an NFT and a Datatoken', async () => {
|
||||
// we prepare transaction parameters objects
|
||||
const txReceipt = await nftFactory.createNftWithErc20(nftOwner, nftData, ercParams)
|
||||
const txReceipt = await nftFactory.createNftWithDatatoken(nftOwner, nftData, dtParams)
|
||||
|
||||
// events have been emitted
|
||||
expect(txReceipt.events.NFTCreated.event === 'NFTCreated')
|
||||
@ -120,7 +120,7 @@ describe('Nft Factory test', () => {
|
||||
const currentNFTCount = await nftFactory.getCurrentNFTCount()
|
||||
const currentTokenCount = await nftFactory.getCurrentTokenCount()
|
||||
|
||||
await nftFactory.createNftWithErc20(nftOwner, nftData, ercParams)
|
||||
await nftFactory.createNftWithDatatoken(nftOwner, nftData, dtParams)
|
||||
|
||||
expect((await nftFactory.getCurrentNFTCount()) === currentNFTCount + 1)
|
||||
expect((await nftFactory.getCurrentTokenCount()) === currentTokenCount + 1)
|
||||
@ -131,7 +131,7 @@ describe('Nft Factory test', () => {
|
||||
const poolParams: PoolCreationParams = {
|
||||
ssContract: contracts.sideStakingAddress,
|
||||
baseTokenAddress: contracts.daiAddress,
|
||||
baseTokenSender: contracts.erc721FactoryAddress,
|
||||
baseTokenSender: contracts.nftFactoryAddress,
|
||||
publisherAddress: nftOwner,
|
||||
marketFeeCollector: nftOwner,
|
||||
poolTemplateAddress: contracts.poolTemplateAddress,
|
||||
@ -156,14 +156,14 @@ describe('Nft Factory test', () => {
|
||||
web3,
|
||||
nftOwner,
|
||||
contracts.daiAddress,
|
||||
contracts.erc721FactoryAddress,
|
||||
contracts.nftFactoryAddress,
|
||||
poolParams.vestingAmount
|
||||
)
|
||||
|
||||
const txReceipt = await nftFactory.createNftErc20WithPool(
|
||||
const txReceipt = await nftFactory.createNftWithDatatokenWithPool(
|
||||
nftOwner,
|
||||
nftData,
|
||||
ercParams,
|
||||
dtParams,
|
||||
poolParams
|
||||
)
|
||||
|
||||
@ -188,10 +188,10 @@ describe('Nft Factory test', () => {
|
||||
withMint: false
|
||||
}
|
||||
|
||||
const txReceipt = await nftFactory.createNftErc20WithFixedRate(
|
||||
const txReceipt = await nftFactory.createNftWithDatatokenWithFixedRate(
|
||||
nftOwner,
|
||||
nftData,
|
||||
ercParams,
|
||||
dtParams,
|
||||
freParams
|
||||
)
|
||||
|
||||
@ -214,10 +214,10 @@ describe('Nft Factory test', () => {
|
||||
allowedSwapper: ZERO_ADDRESS
|
||||
}
|
||||
|
||||
const txReceipt = await nftFactory.createNftErc20WithDispenser(
|
||||
const txReceipt = await nftFactory.createNftWithDatatokenWithDispenser(
|
||||
nftOwner,
|
||||
nftData,
|
||||
ercParams,
|
||||
dtParams,
|
||||
dispenserParams
|
||||
)
|
||||
|
||||
@ -246,7 +246,7 @@ describe('Nft Factory test', () => {
|
||||
|
||||
// user1 approves NFTFactory to move his DATA_TOKEN_AMOUNT
|
||||
await dtContract.methods
|
||||
.approve(contracts.erc721FactoryAddress, DATA_TOKEN_AMOUNT)
|
||||
.approve(contracts.nftFactoryAddress, DATA_TOKEN_AMOUNT)
|
||||
.send({ from: user1 })
|
||||
|
||||
// we reuse another DT created in a previous test
|
||||
@ -257,7 +257,7 @@ describe('Nft Factory test', () => {
|
||||
await dtContract2.methods.mint(user1, DATA_TOKEN_AMOUNT).send({ from: nftOwner })
|
||||
// user1 approves NFTFactory to move his DATA_TOKEN_AMOUNT
|
||||
await dtContract2.methods
|
||||
.approve(contracts.erc721FactoryAddress, DATA_TOKEN_AMOUNT)
|
||||
.approve(contracts.nftFactoryAddress, DATA_TOKEN_AMOUNT)
|
||||
.send({ from: user1 })
|
||||
|
||||
// we check user1 has enought DTs
|
||||
@ -325,17 +325,17 @@ describe('Nft Factory test', () => {
|
||||
assert((await nftFactory.checkNFT(nftAddress)) === nftAddress)
|
||||
})
|
||||
|
||||
it('#addNFTTemplate - should add a new erc721 token template', async () => {
|
||||
it('#addNFTTemplate - should add a new NFT token template', async () => {
|
||||
const currentNFTTemplateCount = await nftFactory.getCurrentNFTTemplateCount()
|
||||
|
||||
await nftFactory.addNFTTemplate(factoryOwner, contracts.erc721TemplateAddress)
|
||||
await nftFactory.addNFTTemplate(factoryOwner, contracts.nftTemplateAddress)
|
||||
|
||||
expect(
|
||||
(await nftFactory.getCurrentNFTTemplateCount()) === currentNFTTemplateCount + 1
|
||||
)
|
||||
})
|
||||
|
||||
it('#disableNFTTemplate - should disable an erc721 token template', async () => {
|
||||
it('#disableNFTTemplate - should disable an NFT token template', async () => {
|
||||
const currentNFTTemplateCount = await nftFactory.getCurrentNFTTemplateCount()
|
||||
|
||||
let nftTemplate = await nftFactory.getNFTTemplate(currentNFTTemplateCount)
|
||||
@ -347,7 +347,7 @@ describe('Nft Factory test', () => {
|
||||
assert(nftTemplate.isActive === false)
|
||||
})
|
||||
|
||||
it('#reactivateNFTTemplate - should reactivate an erc721 previously disabled token template', async () => {
|
||||
it('#reactivateNFTTemplate - should reactivate an NFT previously disabled token template', async () => {
|
||||
const currentNFTTemplateCount = await nftFactory.getCurrentNFTTemplateCount()
|
||||
|
||||
let nftTemplate = await nftFactory.getNFTTemplate(currentNFTTemplateCount)
|
||||
@ -359,17 +359,17 @@ describe('Nft Factory test', () => {
|
||||
assert(nftTemplate.isActive === true)
|
||||
})
|
||||
|
||||
it('#addTokenTemplate - should add a new erc20 token template', async () => {
|
||||
it('#addTokenTemplate - should add a new Datatokent template', async () => {
|
||||
const currentTokenTemplateCount = await nftFactory.getCurrentTokenTemplateCount()
|
||||
|
||||
await nftFactory.addTokenTemplate(factoryOwner, contracts.erc20TemplateAddress)
|
||||
await nftFactory.addTokenTemplate(factoryOwner, contracts.datatokenTemplateAddress)
|
||||
|
||||
expect(
|
||||
(await nftFactory.getCurrentTokenTemplateCount()) === currentTokenTemplateCount + 1
|
||||
)
|
||||
})
|
||||
|
||||
it('#disableTokenTemplate - should disable an erc20 token template', async () => {
|
||||
it('#disableTokenTemplate - should disable an Datatoken template', async () => {
|
||||
const currentTokenTemplateCount = await nftFactory.getCurrentTokenTemplateCount()
|
||||
|
||||
let tokenTemplate = await nftFactory.getTokenTemplate(currentTokenTemplateCount)
|
||||
@ -381,7 +381,7 @@ describe('Nft Factory test', () => {
|
||||
assert(tokenTemplate.isActive === false)
|
||||
})
|
||||
|
||||
it('#reactivateTokenTemplate - should reactivate an previously disabled erc20 token template', async () => {
|
||||
it('#reactivateTokenTemplate - should reactivate an previously disabled Datatoken template', async () => {
|
||||
const currentTokenTemplateCount = await nftFactory.getCurrentTokenTemplateCount()
|
||||
|
||||
let tokenTemplate = await nftFactory.getTokenTemplate(currentTokenTemplateCount)
|
||||
|
@ -11,7 +11,7 @@ import {
|
||||
approve,
|
||||
ZERO_ADDRESS
|
||||
} from '../../../src'
|
||||
import { Erc20CreateParams, PoolCreationParams, Operation } from '../../../src/@types'
|
||||
import { DatatokenCreateParams, PoolCreationParams, Operation } from '../../../src/@types'
|
||||
|
||||
const { keccak256 } = require('@ethersproject/keccak256')
|
||||
|
||||
@ -25,8 +25,8 @@ describe('Router unit test', () => {
|
||||
const NFT_NAME = '72120Bundle'
|
||||
const NFT_SYMBOL = '72Bundle'
|
||||
const NFT_TOKEN_URI = 'https://oceanprotocol.com/nft/'
|
||||
const ERC20_NAME = 'ERC20B1'
|
||||
const ERC20_SYMBOL = 'ERC20DT1Symbol'
|
||||
const DATATOKEN_NAME = 'ERC20B1'
|
||||
const DATATOKEN_SYMBOL = 'ERC20DT1Symbol'
|
||||
const RATE = '1'
|
||||
const FEE = '0.001'
|
||||
const FEE_ZERO = '0'
|
||||
@ -51,7 +51,7 @@ describe('Router unit test', () => {
|
||||
owner: factoryOwner
|
||||
}
|
||||
|
||||
const ERC_PARAMS: Erc20CreateParams = {
|
||||
const ERC_PARAMS: DatatokenCreateParams = {
|
||||
templateIndex: 1,
|
||||
minter: factoryOwner,
|
||||
paymentCollector: user2,
|
||||
@ -59,8 +59,8 @@ describe('Router unit test', () => {
|
||||
feeToken: ZERO_ADDRESS,
|
||||
cap: CAP_AMOUNT,
|
||||
feeAmount: FEE_ZERO,
|
||||
name: ERC20_NAME,
|
||||
symbol: ERC20_SYMBOL
|
||||
name: DATATOKEN_NAME,
|
||||
symbol: DATATOKEN_SYMBOL
|
||||
}
|
||||
|
||||
before(async () => {
|
||||
@ -82,7 +82,7 @@ describe('Router unit test', () => {
|
||||
web3,
|
||||
factoryOwner,
|
||||
contracts.daiAddress,
|
||||
contracts.erc721FactoryAddress,
|
||||
contracts.nftFactoryAddress,
|
||||
web3.utils.toWei('10000')
|
||||
)
|
||||
})
|
||||
@ -98,7 +98,7 @@ describe('Router unit test', () => {
|
||||
|
||||
it('#getNFTFactory - should return NFT Factory address', async () => {
|
||||
const factory = await router.getNFTFactory()
|
||||
assert(factory === contracts.erc721FactoryAddress)
|
||||
assert(factory === contracts.nftFactoryAddress)
|
||||
})
|
||||
|
||||
it('#isOceanTokens - should return true if in oceanTokens list', async () => {
|
||||
@ -121,7 +121,7 @@ describe('Router unit test', () => {
|
||||
expect(await router.isPoolTemplate(contracts.fixedRateAddress)).to.equal(false)
|
||||
})
|
||||
|
||||
it('#buyDTBatch - should buy multiple DT in one call', async () => {
|
||||
it('#buyDatatokenBatch - should buy multiple DT in one call', async () => {
|
||||
// APPROVE DAI
|
||||
const daiContract = new web3.eth.Contract(
|
||||
MockERC20.abi as AbiItem[],
|
||||
@ -138,7 +138,7 @@ describe('Router unit test', () => {
|
||||
const poolParams: PoolCreationParams = {
|
||||
ssContract: contracts.sideStakingAddress,
|
||||
baseTokenAddress: contracts.daiAddress,
|
||||
baseTokenSender: contracts.erc721FactoryAddress,
|
||||
baseTokenSender: contracts.nftFactoryAddress,
|
||||
publisherAddress: factoryOwner,
|
||||
marketFeeCollector: factoryOwner,
|
||||
poolTemplateAddress: contracts.poolTemplateAddress,
|
||||
@ -151,32 +151,32 @@ describe('Router unit test', () => {
|
||||
swapFeeMarketRunner: FEE
|
||||
}
|
||||
|
||||
const nftFactory = new NftFactory(contracts.erc721FactoryAddress, web3)
|
||||
const txReceipt = await nftFactory.createNftErc20WithPool(
|
||||
const nftFactory = new NftFactory(contracts.nftFactoryAddress, web3)
|
||||
const txReceipt = await nftFactory.createNftWithDatatokenWithPool(
|
||||
factoryOwner,
|
||||
NFT_DATA,
|
||||
ERC_PARAMS,
|
||||
poolParams
|
||||
)
|
||||
|
||||
const erc20TokenAddress = txReceipt.events.TokenCreated.returnValues.newTokenAddress
|
||||
const datatokenAddress = txReceipt.events.TokenCreated.returnValues.newTokenAddress
|
||||
const pool1 = txReceipt.events.NewPool.returnValues.poolAddress
|
||||
|
||||
// CREATE A SECOND POOL
|
||||
const txReceipt2 = await nftFactory.createNftErc20WithPool(
|
||||
const txReceipt2 = await nftFactory.createNftWithDatatokenWithPool(
|
||||
factoryOwner,
|
||||
NFT_DATA,
|
||||
ERC_PARAMS,
|
||||
poolParams
|
||||
)
|
||||
|
||||
const erc20Token2Address = txReceipt2.events.TokenCreated.returnValues.newTokenAddress
|
||||
const datatoken2Address = txReceipt2.events.TokenCreated.returnValues.newTokenAddress
|
||||
const pool2 = txReceipt2.events.NewPool.returnValues.poolAddress
|
||||
|
||||
// user1 has no dt1
|
||||
expect(await balance(web3, erc20TokenAddress, user1)).to.equal('0')
|
||||
expect(await balance(web3, datatokenAddress, user1)).to.equal('0')
|
||||
// user1 has no dt2
|
||||
expect(await balance(web3, erc20Token2Address, user1)).to.equal('0')
|
||||
expect(await balance(web3, datatoken2Address, user1)).to.equal('0')
|
||||
|
||||
// we now can prepare the Operations objects
|
||||
|
||||
@ -190,7 +190,7 @@ describe('Router unit test', () => {
|
||||
operation: 0, // swapExactAmountIn
|
||||
tokenIn: contracts.daiAddress,
|
||||
amountsIn: AMOUNTS_IN, // when swapExactAmountIn is EXACT amount IN
|
||||
tokenOut: erc20TokenAddress,
|
||||
tokenOut: datatokenAddress,
|
||||
amountsOut: AMOUNTS_OUT, // when swapExactAmountIn is MIN amount OUT
|
||||
maxPrice: MAX_PRICE, // max price (only for pools),
|
||||
swapMarketFee: SWAP_MARKET_FEE,
|
||||
@ -203,17 +203,17 @@ describe('Router unit test', () => {
|
||||
operation: 0, // swapExactAmountIn
|
||||
tokenIn: contracts.daiAddress,
|
||||
amountsIn: AMOUNTS_IN, // when swapExactAmountIn is EXACT amount IN
|
||||
tokenOut: erc20Token2Address,
|
||||
tokenOut: datatoken2Address,
|
||||
amountsOut: AMOUNTS_OUT, // when swapExactAmountIn is MIN amount OUT
|
||||
maxPrice: MAX_PRICE, // max price (only for pools),
|
||||
swapMarketFee: SWAP_MARKET_FEE,
|
||||
marketFeeAddress: factoryOwner
|
||||
}
|
||||
|
||||
await router.buyDTBatch(user1, [operations1, operations2])
|
||||
await router.buyDatatokenBatch(user1, [operations1, operations2])
|
||||
|
||||
// user1 got his dts
|
||||
expect(+(await balance(web3, erc20TokenAddress, user1))).gt(0)
|
||||
expect(+(await balance(web3, erc20Token2Address, user1))).gt(0)
|
||||
expect(+(await balance(web3, datatokenAddress, user1))).gt(0)
|
||||
expect(+(await balance(web3, datatoken2Address, user1))).gt(0)
|
||||
})
|
||||
})
|
||||
|
@ -15,7 +15,7 @@ import {
|
||||
} from '../../../../src'
|
||||
import {
|
||||
PoolCreationParams,
|
||||
Erc20CreateParams,
|
||||
DatatokenCreateParams,
|
||||
CurrentFees,
|
||||
TokenInOutMarket,
|
||||
AmountsInMaxFee,
|
||||
@ -29,8 +29,8 @@ describe('Pool unit test', () => {
|
||||
let contracts: Addresses
|
||||
let pool: Pool
|
||||
let poolAddress: string
|
||||
let erc20Token: string
|
||||
let ercParams: Erc20CreateParams
|
||||
let datatoken: string
|
||||
let dtParams: DatatokenCreateParams
|
||||
|
||||
const nftData: NftCreateData = {
|
||||
name: '72120Bundle',
|
||||
@ -49,7 +49,7 @@ describe('Pool unit test', () => {
|
||||
|
||||
nftData.owner = factoryOwner
|
||||
|
||||
ercParams = {
|
||||
dtParams = {
|
||||
templateIndex: 1,
|
||||
minter: factoryOwner,
|
||||
paymentCollector: user2,
|
||||
@ -73,7 +73,7 @@ describe('Pool unit test', () => {
|
||||
web3,
|
||||
factoryOwner,
|
||||
contracts.daiAddress,
|
||||
contracts.erc721FactoryAddress,
|
||||
contracts.nftFactoryAddress,
|
||||
'2000'
|
||||
)
|
||||
|
||||
@ -83,7 +83,7 @@ describe('Pool unit test', () => {
|
||||
web3,
|
||||
contracts.daiAddress,
|
||||
factoryOwner,
|
||||
contracts.erc721FactoryAddress
|
||||
contracts.nftFactoryAddress
|
||||
)
|
||||
) >= 2000
|
||||
)
|
||||
@ -92,7 +92,7 @@ describe('Pool unit test', () => {
|
||||
web3,
|
||||
factoryOwner,
|
||||
contracts.usdcAddress,
|
||||
contracts.erc721FactoryAddress,
|
||||
contracts.nftFactoryAddress,
|
||||
'10000'
|
||||
)
|
||||
|
||||
@ -102,7 +102,7 @@ describe('Pool unit test', () => {
|
||||
web3,
|
||||
contracts.usdcAddress,
|
||||
factoryOwner,
|
||||
contracts.erc721FactoryAddress
|
||||
contracts.nftFactoryAddress
|
||||
)
|
||||
) >= 10000
|
||||
)
|
||||
@ -115,7 +115,7 @@ describe('Pool unit test', () => {
|
||||
const poolParams: PoolCreationParams = {
|
||||
ssContract: contracts.sideStakingAddress,
|
||||
baseTokenAddress: contracts.daiAddress,
|
||||
baseTokenSender: contracts.erc721FactoryAddress,
|
||||
baseTokenSender: contracts.nftFactoryAddress,
|
||||
publisherAddress: factoryOwner,
|
||||
marketFeeCollector: factoryOwner,
|
||||
poolTemplateAddress: contracts.poolTemplateAddress,
|
||||
@ -128,20 +128,20 @@ describe('Pool unit test', () => {
|
||||
swapFeeMarketRunner: '0.001'
|
||||
}
|
||||
|
||||
const nftFactory = new NftFactory(contracts.erc721FactoryAddress, web3, 8996)
|
||||
const nftFactory = new NftFactory(contracts.nftFactoryAddress, web3, 8996)
|
||||
|
||||
const txReceipt = await nftFactory.createNftErc20WithPool(
|
||||
const txReceipt = await nftFactory.createNftWithDatatokenWithPool(
|
||||
factoryOwner,
|
||||
nftData,
|
||||
ercParams,
|
||||
dtParams,
|
||||
poolParams
|
||||
)
|
||||
|
||||
erc20Token = txReceipt.events.TokenCreated.returnValues.newTokenAddress
|
||||
datatoken = txReceipt.events.TokenCreated.returnValues.newTokenAddress
|
||||
poolAddress = txReceipt.events.NewPool.returnValues.poolAddress
|
||||
|
||||
// user1 has no dt1
|
||||
expect(await balance(web3, erc20Token, user1)).to.equal('0')
|
||||
expect(await balance(web3, datatoken, user1)).to.equal('0')
|
||||
})
|
||||
|
||||
it('#sharesBalance - should return user shares balance (datatoken balance, LPT balance, etc) ', async () => {
|
||||
@ -168,13 +168,13 @@ describe('Pool unit test', () => {
|
||||
|
||||
it('#getCurrentTokens - should return current pool tokens', async () => {
|
||||
const currentTokens = await pool.getCurrentTokens(poolAddress)
|
||||
expect(currentTokens[0]).to.equal(erc20Token)
|
||||
expect(currentTokens[0]).to.equal(datatoken)
|
||||
expect(currentTokens[1]).to.equal(contracts.daiAddress)
|
||||
})
|
||||
|
||||
it('#getFinalTokens - should return final pool tokens', async () => {
|
||||
const finalTokens = await pool.getFinalTokens(poolAddress)
|
||||
expect(finalTokens[0]).to.equal(erc20Token)
|
||||
expect(finalTokens[0]).to.equal(datatoken)
|
||||
expect(finalTokens[1]).to.equal(contracts.daiAddress)
|
||||
})
|
||||
|
||||
@ -190,7 +190,7 @@ describe('Pool unit test', () => {
|
||||
it('#getReserve - should return final pool tokens', async () => {
|
||||
expect(await pool.getReserve(poolAddress, contracts.daiAddress)).to.equal('2000') // baseToken initial liquidity
|
||||
// rate is 1 so we have the same amount of DTs
|
||||
expect(await pool.getReserve(poolAddress, erc20Token)).to.equal('2000')
|
||||
expect(await pool.getReserve(poolAddress, datatoken)).to.equal('2000')
|
||||
})
|
||||
|
||||
it('#isFinalized - should return true if pool is finalized', async () => {
|
||||
@ -205,34 +205,34 @@ describe('Pool unit test', () => {
|
||||
expect(await pool.getNormalizedWeight(poolAddress, contracts.daiAddress)).to.equal(
|
||||
'0.5'
|
||||
)
|
||||
expect(await pool.getNormalizedWeight(poolAddress, erc20Token)).to.equal('0.5')
|
||||
expect(await pool.getNormalizedWeight(poolAddress, datatoken)).to.equal('0.5')
|
||||
})
|
||||
|
||||
it('#getDenormalizedWeight - should return the denormalized weight', async () => {
|
||||
expect(
|
||||
await pool.getDenormalizedWeight(poolAddress, contracts.daiAddress)
|
||||
).to.equal('5')
|
||||
expect(await pool.getDenormalizedWeight(poolAddress, erc20Token)).to.equal('5')
|
||||
expect(await pool.getDenormalizedWeight(poolAddress, datatoken)).to.equal('5')
|
||||
})
|
||||
|
||||
it('#getBaseToken - should return the baseToken address', async () => {
|
||||
expect(await pool.getBaseToken(poolAddress)).to.equal(contracts.daiAddress)
|
||||
it('#getBasetoken - should return the baseToken address', async () => {
|
||||
expect(await pool.getBasetoken(poolAddress)).to.equal(contracts.daiAddress)
|
||||
})
|
||||
|
||||
it('#getDatatoken - should return the datatoken address', async () => {
|
||||
expect(await pool.getDatatoken(poolAddress)).to.equal(erc20Token)
|
||||
expect(await pool.getDatatoken(poolAddress)).to.equal(datatoken)
|
||||
})
|
||||
|
||||
it('#swapExactAmountIn - should swap', async () => {
|
||||
await transfer(web3, factoryOwner, contracts.daiAddress, user1, '1000')
|
||||
expect(await balance(web3, contracts.daiAddress, user1)).to.equal('1000')
|
||||
|
||||
expect(await balance(web3, erc20Token, user1)).to.equal('0')
|
||||
expect(await balance(web3, datatoken, user1)).to.equal('0')
|
||||
await approve(web3, user1, contracts.daiAddress, poolAddress, '10')
|
||||
|
||||
const tokenInOutMarket: TokenInOutMarket = {
|
||||
tokenIn: contracts.daiAddress,
|
||||
tokenOut: erc20Token,
|
||||
tokenOut: datatoken,
|
||||
marketFeeAddress: factoryOwner
|
||||
}
|
||||
const amountsInOutMaxFee: AmountsInMaxFee = {
|
||||
@ -246,10 +246,10 @@ describe('Pool unit test', () => {
|
||||
tokenInOutMarket,
|
||||
amountsInOutMaxFee
|
||||
)
|
||||
expect(await balance(web3, erc20Token, user1)).to.equal(
|
||||
expect(await balance(web3, datatoken, user1)).to.equal(
|
||||
await unitsToAmount(
|
||||
web3,
|
||||
erc20Token,
|
||||
datatoken,
|
||||
tx.events.LOG_SWAP.returnValues.tokenAmountOut
|
||||
)
|
||||
)
|
||||
@ -260,7 +260,7 @@ describe('Pool unit test', () => {
|
||||
expect(await balance(web3, contracts.daiAddress, user1)).to.equal('990')
|
||||
const tokenInOutMarket: TokenInOutMarket = {
|
||||
tokenIn: contracts.daiAddress,
|
||||
tokenOut: erc20Token,
|
||||
tokenOut: datatoken,
|
||||
marketFeeAddress: factoryOwner
|
||||
}
|
||||
const amountsInOutMaxFee: AmountsOutMaxFee = {
|
||||
@ -301,11 +301,11 @@ describe('Pool unit test', () => {
|
||||
)
|
||||
})
|
||||
|
||||
it('#exitswapPoolAmountIn- user2 exit the pool receiving only DAI', async () => {
|
||||
it('#exitSwapPoolAmountIn- user2 exit the pool receiving only DAI', async () => {
|
||||
const BPTAmountIn = '0.5'
|
||||
const minDAIOut = '0.5'
|
||||
|
||||
const tx = await pool.exitswapPoolAmountIn(
|
||||
const tx = await pool.exitSwapPoolAmountIn(
|
||||
user1,
|
||||
poolAddress,
|
||||
BPTAmountIn,
|
||||
@ -317,14 +317,14 @@ describe('Pool unit test', () => {
|
||||
expect(tx.events.LOG_EXIT[0].returnValues.tokenOut).to.equal(contracts.daiAddress)
|
||||
|
||||
// DTs were also unstaked in the same transaction (went to the staking contract)
|
||||
expect(tx.events.LOG_EXIT[1].returnValues.tokenOut).to.equal(erc20Token)
|
||||
expect(tx.events.LOG_EXIT[1].returnValues.tokenOut).to.equal(datatoken)
|
||||
})
|
||||
|
||||
it('#exitswapExternAmountOut- user1 exit the pool receiving only DAI', async () => {
|
||||
const maxBTPIn = '0.5'
|
||||
const exactDAIOut = '1'
|
||||
|
||||
const tx = await pool.exitswapPoolAmountIn(
|
||||
const tx = await pool.exitSwapPoolAmountIn(
|
||||
user1,
|
||||
poolAddress,
|
||||
maxBTPIn,
|
||||
@ -336,7 +336,7 @@ describe('Pool unit test', () => {
|
||||
expect(tx.events.LOG_EXIT[0].returnValues.tokenOut).to.equal(contracts.daiAddress)
|
||||
|
||||
// DTs were also unstaked in the same transaction (went to the staking contract)
|
||||
expect(tx.events.LOG_EXIT[1].returnValues.tokenOut).to.equal(erc20Token)
|
||||
expect(tx.events.LOG_EXIT[1].returnValues.tokenOut).to.equal(datatoken)
|
||||
})
|
||||
|
||||
it('#getAmountInExactOut- should get the amount in for exact out', async () => {
|
||||
@ -344,7 +344,7 @@ describe('Pool unit test', () => {
|
||||
|
||||
const result = await pool.getAmountInExactOut(
|
||||
poolAddress,
|
||||
erc20Token,
|
||||
datatoken,
|
||||
contracts.daiAddress,
|
||||
exactDAIOut,
|
||||
'0.1'
|
||||
@ -357,7 +357,7 @@ describe('Pool unit test', () => {
|
||||
|
||||
const spotPrice = await pool.getSpotPrice(
|
||||
poolAddress,
|
||||
erc20Token,
|
||||
datatoken,
|
||||
contracts.daiAddress,
|
||||
'0.1'
|
||||
)
|
||||
@ -371,7 +371,7 @@ describe('Pool unit test', () => {
|
||||
|
||||
const result = await pool.getAmountOutExactIn(
|
||||
poolAddress,
|
||||
erc20Token,
|
||||
datatoken,
|
||||
contracts.daiAddress,
|
||||
exactDTIn,
|
||||
'0.1'
|
||||
@ -383,7 +383,7 @@ describe('Pool unit test', () => {
|
||||
const spotPrice = await pool.getSpotPrice(
|
||||
poolAddress,
|
||||
contracts.daiAddress,
|
||||
erc20Token,
|
||||
datatoken,
|
||||
'0.1'
|
||||
)
|
||||
// amount of DAI received will be slightly less than spotPrice
|
||||
@ -392,34 +392,34 @@ describe('Pool unit test', () => {
|
||||
|
||||
it('#getSpotPrice- should get the spot price', async () => {
|
||||
assert(
|
||||
(await pool.getSpotPrice(poolAddress, erc20Token, contracts.daiAddress, '0.1')) !=
|
||||
(await pool.getSpotPrice(poolAddress, datatoken, contracts.daiAddress, '0.1')) !=
|
||||
null
|
||||
)
|
||||
assert(
|
||||
(await pool.getSpotPrice(poolAddress, contracts.daiAddress, erc20Token, '0.1')) !=
|
||||
(await pool.getSpotPrice(poolAddress, contracts.daiAddress, datatoken, '0.1')) !=
|
||||
null
|
||||
)
|
||||
})
|
||||
|
||||
it('#getMarketFees- should get market fees for each token', async () => {
|
||||
// we haven't performed any swap DT => DAI so there's no fee in erc20Token
|
||||
// we haven't performed any swap DT => DAI so there's no fee in datatoken
|
||||
// but there's a fee in DAI
|
||||
assert((await pool.getMarketFees(poolAddress, erc20Token)) === '0')
|
||||
assert((await pool.getMarketFees(poolAddress, datatoken)) === '0')
|
||||
assert((await pool.getMarketFees(poolAddress, contracts.daiAddress)) > '0')
|
||||
})
|
||||
|
||||
it('#getCommunityFees- should get community fees for each token', async () => {
|
||||
// we haven't performed any swap DT => DAI so there's no fee in erc20Token
|
||||
// we haven't performed any swap DT => DAI so there's no fee in datatoken
|
||||
// but there's a fee in DAI
|
||||
|
||||
assert((await pool.getCommunityFees(poolAddress, erc20Token)) === '0')
|
||||
assert((await pool.getCommunityFees(poolAddress, datatoken)) === '0')
|
||||
assert((await pool.getCommunityFees(poolAddress, contracts.daiAddress)) > '0')
|
||||
})
|
||||
|
||||
it('#collectMarketFee- should collect market fees for each token', async () => {
|
||||
const spotPriceBefore = await pool.getSpotPrice(
|
||||
poolAddress,
|
||||
erc20Token,
|
||||
datatoken,
|
||||
contracts.daiAddress,
|
||||
'0.1'
|
||||
)
|
||||
@ -435,12 +435,8 @@ describe('Pool unit test', () => {
|
||||
|
||||
// Spot price hasn't changed after fee collection
|
||||
assert(
|
||||
(await pool.getSpotPrice(
|
||||
poolAddress,
|
||||
erc20Token,
|
||||
contracts.daiAddress,
|
||||
'0.1'
|
||||
)) === spotPriceBefore
|
||||
(await pool.getSpotPrice(poolAddress, datatoken, contracts.daiAddress, '0.1')) ===
|
||||
spotPriceBefore
|
||||
)
|
||||
})
|
||||
|
||||
@ -452,7 +448,7 @@ describe('Pool unit test', () => {
|
||||
it('#collectCommunityFee- should get community fees for each token', async () => {
|
||||
const spotPriceBefore = await pool.getSpotPrice(
|
||||
poolAddress,
|
||||
erc20Token,
|
||||
datatoken,
|
||||
contracts.daiAddress,
|
||||
'0.1'
|
||||
)
|
||||
@ -480,12 +476,8 @@ describe('Pool unit test', () => {
|
||||
)
|
||||
// Spot price hasn't changed after fee collection
|
||||
assert(
|
||||
(await pool.getSpotPrice(
|
||||
poolAddress,
|
||||
erc20Token,
|
||||
contracts.daiAddress,
|
||||
'0.1'
|
||||
)) === spotPriceBefore
|
||||
(await pool.getSpotPrice(poolAddress, datatoken, contracts.daiAddress, '0.1')) ===
|
||||
spotPriceBefore
|
||||
)
|
||||
})
|
||||
|
||||
@ -510,7 +502,7 @@ describe('Pool unit test', () => {
|
||||
const poolParams: PoolCreationParams = {
|
||||
ssContract: contracts.sideStakingAddress,
|
||||
baseTokenAddress: contracts.usdcAddress,
|
||||
baseTokenSender: contracts.erc721FactoryAddress,
|
||||
baseTokenSender: contracts.nftFactoryAddress,
|
||||
publisherAddress: factoryOwner,
|
||||
marketFeeCollector: factoryOwner,
|
||||
poolTemplateAddress: contracts.poolTemplateAddress,
|
||||
@ -523,20 +515,20 @@ describe('Pool unit test', () => {
|
||||
swapFeeMarketRunner: '0.001'
|
||||
}
|
||||
|
||||
const nftFactory = new NftFactory(contracts.erc721FactoryAddress, web3, 8996)
|
||||
const nftFactory = new NftFactory(contracts.nftFactoryAddress, web3, 8996)
|
||||
|
||||
const txReceipt = await nftFactory.createNftErc20WithPool(
|
||||
const txReceipt = await nftFactory.createNftWithDatatokenWithPool(
|
||||
factoryOwner,
|
||||
nftData,
|
||||
ercParams,
|
||||
dtParams,
|
||||
poolParams
|
||||
)
|
||||
|
||||
erc20Token = txReceipt.events.TokenCreated.returnValues.newTokenAddress
|
||||
datatoken = txReceipt.events.TokenCreated.returnValues.newTokenAddress
|
||||
poolAddress = txReceipt.events.NewPool.returnValues.poolAddress
|
||||
|
||||
// user1 has no dt1
|
||||
expect(await balance(web3, erc20Token, user1)).to.equal('0')
|
||||
expect(await balance(web3, datatoken, user1)).to.equal('0')
|
||||
})
|
||||
|
||||
it('#calcPoolOutGivenSingleIn - should get the amount of pool OUT for exact token IN', async () => {
|
||||
@ -544,7 +536,7 @@ describe('Pool unit test', () => {
|
||||
// amount of pool out received for same amount of different token In is equal
|
||||
const tokenInAmount = '10' // 10 USDC or 10 DTs
|
||||
expect(
|
||||
await pool.calcPoolOutGivenSingleIn(poolAddress, erc20Token, tokenInAmount)
|
||||
await pool.calcPoolOutGivenSingleIn(poolAddress, datatoken, tokenInAmount)
|
||||
).to.equal(
|
||||
await pool.calcPoolOutGivenSingleIn(
|
||||
poolAddress,
|
||||
@ -552,7 +544,7 @@ describe('Pool unit test', () => {
|
||||
tokenInAmount
|
||||
)
|
||||
)
|
||||
// console.log(await pool.calcPoolOutGivenSingleIn(poolAddress, erc20Token, tokenInAmount))
|
||||
// console.log(await pool.calcPoolOutGivenSingleIn(poolAddress, datatoken, tokenInAmount))
|
||||
})
|
||||
|
||||
it('#calcSingleInGivenPoolOut - should get the amount of token IN for exact pool token OUT', async () => {
|
||||
@ -561,7 +553,7 @@ describe('Pool unit test', () => {
|
||||
const poolAmountOut = '1'
|
||||
expect(
|
||||
parseInt(
|
||||
await pool.calcSingleInGivenPoolOut(poolAddress, erc20Token, poolAmountOut)
|
||||
await pool.calcSingleInGivenPoolOut(poolAddress, datatoken, poolAmountOut)
|
||||
)
|
||||
).to.be.closeTo(
|
||||
parseInt(
|
||||
@ -580,7 +572,7 @@ describe('Pool unit test', () => {
|
||||
// amount amount of different token Out for rediming the same pool In is equal
|
||||
const poolAmountIn = '10'
|
||||
expect(
|
||||
await pool.calcSingleOutGivenPoolIn(poolAddress, erc20Token, poolAmountIn)
|
||||
await pool.calcSingleOutGivenPoolIn(poolAddress, datatoken, poolAmountIn)
|
||||
).to.equal(
|
||||
await pool.calcSingleOutGivenPoolIn(
|
||||
poolAddress,
|
||||
@ -596,7 +588,7 @@ describe('Pool unit test', () => {
|
||||
const tokenAmountOut = '10'
|
||||
expect(
|
||||
parseInt(
|
||||
await pool.calcPoolInGivenSingleOut(poolAddress, erc20Token, tokenAmountOut)
|
||||
await pool.calcPoolInGivenSingleOut(poolAddress, datatoken, tokenAmountOut)
|
||||
)
|
||||
).to.be.closeTo(
|
||||
parseInt(
|
||||
@ -634,13 +626,13 @@ describe('Pool unit test', () => {
|
||||
|
||||
it('#getCurrentTokens - should return current pool tokens', async () => {
|
||||
const currentTokens = await pool.getCurrentTokens(poolAddress)
|
||||
expect(currentTokens[0]).to.equal(erc20Token)
|
||||
expect(currentTokens[0]).to.equal(datatoken)
|
||||
expect(currentTokens[1]).to.equal(contracts.usdcAddress)
|
||||
})
|
||||
|
||||
it('#getFinalTokens - should return final pool tokens', async () => {
|
||||
const finalTokens = await pool.getFinalTokens(poolAddress)
|
||||
expect(finalTokens[0]).to.equal(erc20Token)
|
||||
expect(finalTokens[0]).to.equal(datatoken)
|
||||
expect(finalTokens[1]).to.equal(contracts.usdcAddress)
|
||||
})
|
||||
|
||||
@ -656,7 +648,7 @@ describe('Pool unit test', () => {
|
||||
it('#getReserve - should return final pool tokens Reserve', async () => {
|
||||
expect(await pool.getReserve(poolAddress, contracts.usdcAddress)).to.equal('2000') // baseToken initial liquidity
|
||||
// rate is 1 so we have the same amount of DTs
|
||||
expect(await pool.getReserve(poolAddress, erc20Token)).to.equal('2000')
|
||||
expect(await pool.getReserve(poolAddress, datatoken)).to.equal('2000')
|
||||
})
|
||||
|
||||
it('#isFinalized - should return true if pool is finalized', async () => {
|
||||
@ -671,34 +663,34 @@ describe('Pool unit test', () => {
|
||||
expect(await pool.getNormalizedWeight(poolAddress, contracts.usdcAddress)).to.equal(
|
||||
'0.5'
|
||||
)
|
||||
expect(await pool.getNormalizedWeight(poolAddress, erc20Token)).to.equal('0.5')
|
||||
expect(await pool.getNormalizedWeight(poolAddress, datatoken)).to.equal('0.5')
|
||||
})
|
||||
|
||||
it('#getDenormalizedWeight - should return the denormalized weight', async () => {
|
||||
expect(
|
||||
await pool.getDenormalizedWeight(poolAddress, contracts.usdcAddress)
|
||||
).to.equal('5')
|
||||
expect(await pool.getDenormalizedWeight(poolAddress, erc20Token)).to.equal('5')
|
||||
expect(await pool.getDenormalizedWeight(poolAddress, datatoken)).to.equal('5')
|
||||
})
|
||||
|
||||
it('#getBaseToken - should return the baseToken address', async () => {
|
||||
expect(await pool.getBaseToken(poolAddress)).to.equal(contracts.usdcAddress)
|
||||
it('#getBasetoken - should return the baseToken address', async () => {
|
||||
expect(await pool.getBasetoken(poolAddress)).to.equal(contracts.usdcAddress)
|
||||
})
|
||||
|
||||
it('#getDatatoken - should return the datatoken address', async () => {
|
||||
expect(await pool.getDatatoken(poolAddress)).to.equal(erc20Token)
|
||||
expect(await pool.getDatatoken(poolAddress)).to.equal(datatoken)
|
||||
})
|
||||
|
||||
it('#swapExactAmountIn - should swap', async () => {
|
||||
await transfer(web3, factoryOwner, contracts.usdcAddress, user1, '1000')
|
||||
expect(await balance(web3, contracts.usdcAddress, user1)).to.equal('1000')
|
||||
|
||||
expect(await balance(web3, erc20Token, user1)).to.equal('0')
|
||||
expect(await balance(web3, datatoken, user1)).to.equal('0')
|
||||
await approve(web3, user1, contracts.usdcAddress, poolAddress, '10')
|
||||
|
||||
const tokenInOutMarket: TokenInOutMarket = {
|
||||
tokenIn: contracts.usdcAddress,
|
||||
tokenOut: erc20Token,
|
||||
tokenOut: datatoken,
|
||||
marketFeeAddress: factoryOwner
|
||||
}
|
||||
const amountsInOutMaxFee: AmountsInMaxFee = {
|
||||
@ -712,10 +704,10 @@ describe('Pool unit test', () => {
|
||||
tokenInOutMarket,
|
||||
amountsInOutMaxFee
|
||||
)
|
||||
expect(await balance(web3, erc20Token, user1)).to.equal(
|
||||
expect(await balance(web3, datatoken, user1)).to.equal(
|
||||
await unitsToAmount(
|
||||
web3,
|
||||
erc20Token,
|
||||
datatoken,
|
||||
tx.events.LOG_SWAP.returnValues.tokenAmountOut
|
||||
)
|
||||
)
|
||||
@ -726,7 +718,7 @@ describe('Pool unit test', () => {
|
||||
expect(await balance(web3, contracts.usdcAddress, user1)).to.equal('990')
|
||||
const tokenInOutMarket: TokenInOutMarket = {
|
||||
tokenIn: contracts.usdcAddress,
|
||||
tokenOut: erc20Token,
|
||||
tokenOut: datatoken,
|
||||
marketFeeAddress: factoryOwner
|
||||
}
|
||||
const amountsInOutMaxFee: AmountsOutMaxFee = {
|
||||
@ -766,11 +758,11 @@ describe('Pool unit test', () => {
|
||||
)
|
||||
})
|
||||
|
||||
it('#exitswapPoolAmountIn- user2 exit the pool receiving only USDC', async () => {
|
||||
it('#exitSwapPoolAmountIn- user2 exit the pool receiving only USDC', async () => {
|
||||
const BPTAmountIn = '0.5'
|
||||
const minUSDCOut = '0.5'
|
||||
|
||||
const tx = await pool.exitswapPoolAmountIn(
|
||||
const tx = await pool.exitSwapPoolAmountIn(
|
||||
user1,
|
||||
poolAddress,
|
||||
BPTAmountIn,
|
||||
@ -782,7 +774,7 @@ describe('Pool unit test', () => {
|
||||
expect(tx.events.LOG_EXIT[0].returnValues.tokenOut).to.equal(contracts.usdcAddress)
|
||||
|
||||
// DTs were also unstaked in the same transaction (went to the staking contract)
|
||||
expect(tx.events.LOG_EXIT[1].returnValues.tokenOut).to.equal(erc20Token)
|
||||
expect(tx.events.LOG_EXIT[1].returnValues.tokenOut).to.equal(datatoken)
|
||||
})
|
||||
|
||||
it('#getAmountInExactOut- should get the amount in for exact out', async () => {
|
||||
@ -790,7 +782,7 @@ describe('Pool unit test', () => {
|
||||
|
||||
const result = await pool.getAmountInExactOut(
|
||||
poolAddress,
|
||||
erc20Token,
|
||||
datatoken,
|
||||
contracts.usdcAddress,
|
||||
exactUSDCOut,
|
||||
'0.1'
|
||||
@ -800,7 +792,7 @@ describe('Pool unit test', () => {
|
||||
|
||||
const spotPrice = await pool.getSpotPrice(
|
||||
poolAddress,
|
||||
erc20Token,
|
||||
datatoken,
|
||||
contracts.usdcAddress,
|
||||
'0.1'
|
||||
)
|
||||
@ -813,7 +805,7 @@ describe('Pool unit test', () => {
|
||||
|
||||
const result = await pool.getAmountOutExactIn(
|
||||
poolAddress,
|
||||
erc20Token,
|
||||
datatoken,
|
||||
contracts.usdcAddress,
|
||||
exactDTIn,
|
||||
'0.1'
|
||||
@ -825,7 +817,7 @@ describe('Pool unit test', () => {
|
||||
const spotPrice = await pool.getSpotPrice(
|
||||
poolAddress,
|
||||
contracts.usdcAddress,
|
||||
erc20Token,
|
||||
datatoken,
|
||||
'0.1'
|
||||
)
|
||||
// amount of USDC received will be slightly less than spotPrice
|
||||
@ -834,42 +826,34 @@ describe('Pool unit test', () => {
|
||||
|
||||
it('#getSpotPrice- should get the spot price', async () => {
|
||||
assert(
|
||||
(await pool.getSpotPrice(
|
||||
poolAddress,
|
||||
erc20Token,
|
||||
contracts.usdcAddress,
|
||||
'0.1'
|
||||
)) != null
|
||||
(await pool.getSpotPrice(poolAddress, datatoken, contracts.usdcAddress, '0.1')) !=
|
||||
null
|
||||
)
|
||||
assert(
|
||||
(await pool.getSpotPrice(
|
||||
poolAddress,
|
||||
contracts.usdcAddress,
|
||||
erc20Token,
|
||||
'0.1'
|
||||
)) != null
|
||||
(await pool.getSpotPrice(poolAddress, contracts.usdcAddress, datatoken, '0.1')) !=
|
||||
null
|
||||
)
|
||||
})
|
||||
|
||||
it('#getMarketFees- should get market fees for each token', async () => {
|
||||
// we haven't performed any swap DT => USDC so there's no fee in erc20Token
|
||||
// we haven't performed any swap DT => USDC so there's no fee in datatoken
|
||||
// but there's a fee in USDC
|
||||
assert((await pool.getMarketFees(poolAddress, erc20Token)) === '0')
|
||||
assert((await pool.getMarketFees(poolAddress, datatoken)) === '0')
|
||||
assert((await pool.getMarketFees(poolAddress, contracts.usdcAddress)) > '0')
|
||||
})
|
||||
|
||||
it('#getCommunityFees- should get community fees for each token', async () => {
|
||||
// we haven't performed any swap DT => USDC so there's no fee in erc20Token
|
||||
// we haven't performed any swap DT => USDC so there's no fee in datatoken
|
||||
// but there's a fee in USDC
|
||||
|
||||
assert((await pool.getCommunityFees(poolAddress, erc20Token)) === '0')
|
||||
assert((await pool.getCommunityFees(poolAddress, datatoken)) === '0')
|
||||
assert((await pool.getCommunityFees(poolAddress, contracts.usdcAddress)) > '0')
|
||||
})
|
||||
|
||||
it('#collectMarketFee- should collect market fees for each token', async () => {
|
||||
const spotPriceBefore = await pool.getSpotPrice(
|
||||
poolAddress,
|
||||
erc20Token,
|
||||
datatoken,
|
||||
contracts.usdcAddress,
|
||||
'0.1'
|
||||
)
|
||||
@ -886,7 +870,7 @@ describe('Pool unit test', () => {
|
||||
assert(
|
||||
(await pool.getSpotPrice(
|
||||
poolAddress,
|
||||
erc20Token,
|
||||
datatoken,
|
||||
contracts.usdcAddress,
|
||||
'0.1'
|
||||
)) === spotPriceBefore
|
||||
@ -911,7 +895,7 @@ describe('Pool unit test', () => {
|
||||
it('#collectCommunityFee- should get community fees for each token', async () => {
|
||||
const spotPriceBefore = await pool.getSpotPrice(
|
||||
poolAddress,
|
||||
erc20Token,
|
||||
datatoken,
|
||||
contracts.usdcAddress,
|
||||
'0.1'
|
||||
)
|
||||
@ -941,7 +925,7 @@ describe('Pool unit test', () => {
|
||||
assert(
|
||||
(await pool.getSpotPrice(
|
||||
poolAddress,
|
||||
erc20Token,
|
||||
datatoken,
|
||||
contracts.usdcAddress,
|
||||
'0.1'
|
||||
)) === spotPriceBefore
|
||||
|
@ -9,7 +9,7 @@ import {
|
||||
Dispenser,
|
||||
ZERO_ADDRESS
|
||||
} from '../../../../src/'
|
||||
import { Erc20CreateParams } from '../../../../src/@types'
|
||||
import { DatatokenCreateParams } from '../../../../src/@types'
|
||||
|
||||
describe('Dispenser flow', () => {
|
||||
let factoryOwner: string
|
||||
@ -30,7 +30,7 @@ describe('Dispenser flow', () => {
|
||||
owner: null
|
||||
}
|
||||
|
||||
const ercParams: Erc20CreateParams = {
|
||||
const dtParams: DatatokenCreateParams = {
|
||||
templateIndex: 1,
|
||||
minter: null,
|
||||
paymentCollector: null,
|
||||
@ -49,9 +49,9 @@ describe('Dispenser flow', () => {
|
||||
user2 = accounts[4]
|
||||
|
||||
nftData.owner = factoryOwner
|
||||
ercParams.minter = factoryOwner
|
||||
ercParams.paymentCollector = user2
|
||||
ercParams.mpFeeAddress = user1
|
||||
dtParams.minter = factoryOwner
|
||||
dtParams.paymentCollector = user2
|
||||
dtParams.mpFeeAddress = user1
|
||||
})
|
||||
|
||||
it('should deploy contracts', async () => {
|
||||
@ -59,17 +59,17 @@ describe('Dispenser flow', () => {
|
||||
})
|
||||
|
||||
it('should initialize Dispenser class', async () => {
|
||||
DispenserClass = new Dispenser(web3, 8996, contracts.dispenserAddress)
|
||||
DispenserClass = new Dispenser(contracts.dispenserAddress, web3, 8996)
|
||||
assert(DispenserClass !== null)
|
||||
})
|
||||
|
||||
it('#createNftwithErc - should create an NFT and a Datatoken ', async () => {
|
||||
nftFactory = new NftFactory(contracts.erc721FactoryAddress, web3)
|
||||
nftFactory = new NftFactory(contracts.nftFactoryAddress, web3)
|
||||
|
||||
const txReceipt = await nftFactory.createNftWithErc20(
|
||||
const txReceipt = await nftFactory.createNftWithDatatoken(
|
||||
factoryOwner,
|
||||
nftData,
|
||||
ercParams
|
||||
dtParams
|
||||
)
|
||||
|
||||
expect(txReceipt.events.NFTCreated.event === 'NFTCreated')
|
||||
@ -81,7 +81,7 @@ describe('Dispenser flow', () => {
|
||||
it('Make user2 minter', async () => {
|
||||
datatoken = new Datatoken(web3, 8996)
|
||||
await datatoken.addMinter(dtAddress, factoryOwner, user2)
|
||||
assert((await datatoken.getDTPermissions(dtAddress, user2)).minter === true)
|
||||
assert((await datatoken.getPermissions(dtAddress, user2)).minter === true)
|
||||
})
|
||||
|
||||
it('Create dispenser', async () => {
|
||||
|
@ -15,7 +15,7 @@ import {
|
||||
balance,
|
||||
unitsToAmount
|
||||
} from '../../../../src'
|
||||
import { FreCreationParams, Erc20CreateParams } from '../../../../src/@types'
|
||||
import { FreCreationParams, DatatokenCreateParams } from '../../../../src/@types'
|
||||
|
||||
describe('Fixed Rate unit test', () => {
|
||||
let factoryOwner: string
|
||||
@ -37,7 +37,7 @@ describe('Fixed Rate unit test', () => {
|
||||
owner: null
|
||||
}
|
||||
|
||||
const ercParams: Erc20CreateParams = {
|
||||
const dtParams: DatatokenCreateParams = {
|
||||
templateIndex: 1,
|
||||
minter: null,
|
||||
paymentCollector: null,
|
||||
@ -57,9 +57,9 @@ describe('Fixed Rate unit test', () => {
|
||||
exchangeOwner = accounts[0]
|
||||
|
||||
nftData.owner = factoryOwner
|
||||
ercParams.minter = factoryOwner
|
||||
ercParams.paymentCollector = user2
|
||||
ercParams.mpFeeAddress = factoryOwner
|
||||
dtParams.minter = factoryOwner
|
||||
dtParams.paymentCollector = user2
|
||||
dtParams.mpFeeAddress = factoryOwner
|
||||
})
|
||||
|
||||
it('should deploy contracts', async () => {
|
||||
@ -71,7 +71,7 @@ describe('Fixed Rate unit test', () => {
|
||||
// CREATE AN Exchange
|
||||
// we prepare transaction parameters objects
|
||||
|
||||
const nftFactory = new NftFactory(contracts.erc721FactoryAddress, web3)
|
||||
const nftFactory = new NftFactory(contracts.nftFactoryAddress, web3)
|
||||
|
||||
const freParams: FreCreationParams = {
|
||||
fixedRateAddress: contracts.fixedRateAddress,
|
||||
@ -86,10 +86,10 @@ describe('Fixed Rate unit test', () => {
|
||||
withMint: false
|
||||
}
|
||||
|
||||
const txReceipt = await nftFactory.createNftErc20WithFixedRate(
|
||||
const txReceipt = await nftFactory.createNftWithDatatokenWithFixedRate(
|
||||
exchangeOwner,
|
||||
nftData,
|
||||
ercParams,
|
||||
dtParams,
|
||||
freParams
|
||||
)
|
||||
|
||||
@ -100,13 +100,7 @@ describe('Fixed Rate unit test', () => {
|
||||
// user1 has no dt1
|
||||
expect(await balance(web3, dtAddress, user1)).to.equal('0')
|
||||
|
||||
fixedRate = new FixedRateExchange(
|
||||
web3,
|
||||
contracts.fixedRateAddress,
|
||||
8996,
|
||||
null,
|
||||
contracts.oceanAddress
|
||||
)
|
||||
fixedRate = new FixedRateExchange(contracts.fixedRateAddress, web3, 8996)
|
||||
assert(fixedRate != null)
|
||||
})
|
||||
|
||||
@ -174,31 +168,31 @@ describe('Fixed Rate unit test', () => {
|
||||
expect(await fixedRate.getRate(exchangeId)).to.equal('1')
|
||||
})
|
||||
|
||||
it('#getDTSupply - should get the dt supply in the exchange', async () => {
|
||||
it('#getDatatokenSupply - should get the dt supply in the exchange', async () => {
|
||||
// exchange owner hasn't approved any DT for sell
|
||||
expect(await fixedRate.getDTSupply(exchangeId)).to.equal('0')
|
||||
expect(await fixedRate.getDatatokenSupply(exchangeId)).to.equal('0')
|
||||
})
|
||||
|
||||
it('#getBTSupply - should get the bt supply in the exchange', async () => {
|
||||
it('#getBasetokenSupply - should get the bt supply in the exchange', async () => {
|
||||
// no baseToken at the beginning
|
||||
expect(await fixedRate.getBTSupply(exchangeId)).to.equal('0')
|
||||
expect(await fixedRate.getBasetokenSupply(exchangeId)).to.equal('0')
|
||||
})
|
||||
|
||||
it('#calcBaseInGivenOutDT - should get bt amount in for a specific dt amount', async () => {
|
||||
it('#calcBaseInGivenDatatokensOut - should get bt amount in for a specific dt amount', async () => {
|
||||
// 100.2 DAI for 100 DT (0.1% market fee and 0.1% ocean fee)
|
||||
expect(
|
||||
await (
|
||||
await fixedRate.calcBaseInGivenOutDT(exchangeId, '100')
|
||||
await fixedRate.calcBaseInGivenDatatokensOut(exchangeId, '100')
|
||||
).baseTokenAmount
|
||||
).to.equal('100.3')
|
||||
})
|
||||
|
||||
it('#getAmountBTOut - should get bt amount out for a specific dt amount', async () => {
|
||||
it('#getAmountBasetokensOut - should get bt amount out for a specific dt amount', async () => {
|
||||
// 99.8 DAI for 100 DT (0.1% market fee and 0.1% ocean fee)
|
||||
expect(await fixedRate.getAmountBTOut(exchangeId, '100')).to.equal('99.7')
|
||||
expect(await fixedRate.getAmountBasetokensOut(exchangeId, '100')).to.equal('99.7')
|
||||
})
|
||||
|
||||
it('#buyDT - user1 should buy some dt', async () => {
|
||||
it('#buyDatatokens - user1 should buy some dt', async () => {
|
||||
// total supply is ZERO right now so dt owner mints 1000 DT and approves the fixed rate contract
|
||||
await dtContract.methods
|
||||
.mint(exchangeOwner, web3.utils.toWei('1000'))
|
||||
@ -215,7 +209,7 @@ describe('Fixed Rate unit test', () => {
|
||||
)
|
||||
|
||||
// user1 buys 10 DT
|
||||
const tx = await fixedRate.buyDT(user1, exchangeId, '10', '11')
|
||||
const tx = await fixedRate.buyDatatokens(user1, exchangeId, '10', '11')
|
||||
// console.log(tx.events.Swapped.returnValues)
|
||||
assert(tx.events.Swapped != null)
|
||||
const args = tx.events.Swapped.returnValues
|
||||
@ -241,12 +235,12 @@ describe('Fixed Rate unit test', () => {
|
||||
expect((await fixedRate.getExchange(exchangeId)).dtBalance).to.equal('0')
|
||||
})
|
||||
|
||||
it('#sellDT - user1 should sell some dt', async () => {
|
||||
it('#sellDatatokens - user1 should sell some dt', async () => {
|
||||
await approve(web3, user1, dtAddress, contracts.fixedRateAddress, '100')
|
||||
const daiBalanceBefore = new BigNumber(
|
||||
await balance(web3, contracts.daiAddress, user1)
|
||||
)
|
||||
const tx = await fixedRate.sellDT(user1, exchangeId, '10', '9')
|
||||
const tx = await fixedRate.sellDatatokens(user1, exchangeId, '10', '9')
|
||||
// console.log(tx.events.Swapped.returnValues)
|
||||
assert(tx.events.Swapped != null)
|
||||
const args = tx.events.Swapped.returnValues
|
||||
@ -269,7 +263,7 @@ describe('Fixed Rate unit test', () => {
|
||||
// no BTs in the contract (except for the fees, but not accounted here)
|
||||
expect((await fixedRate.getExchange(exchangeId)).btBalance).to.equal('0')
|
||||
// DT supply is back at 1000 (exchange Owner allowance + dt balance in the fixed rate)
|
||||
expect(await fixedRate.getDTSupply(exchangeId)).to.equal('1000')
|
||||
expect(await fixedRate.getDatatokenSupply(exchangeId)).to.equal('1000')
|
||||
})
|
||||
|
||||
it('#getExchange - should return exchange details', async () => {
|
||||
@ -313,26 +307,30 @@ describe('Fixed Rate unit test', () => {
|
||||
expect(await fixedRate.getAllowedSwapper(exchangeId)).to.equal(ZERO_ADDRESS)
|
||||
})
|
||||
|
||||
it('#collectBT- should collect BT in the contract, if exchangeOwner', async () => {
|
||||
it('#collectBasetokens- should collect BT in the contract, if exchangeOwner', async () => {
|
||||
// there are no bt in the contract
|
||||
expect((await fixedRate.getExchange(exchangeId)).btBalance).to.equal('0')
|
||||
// user1 buys 1 DT
|
||||
await fixedRate.buyDT(user1, exchangeId, '1', '2')
|
||||
await fixedRate.buyDatatokens(user1, exchangeId, '1', '2')
|
||||
// 1 DAI in the contract
|
||||
const fixedRateDetails = await fixedRate.getExchange(exchangeId)
|
||||
expect(fixedRateDetails.btBalance).to.equal('1')
|
||||
// owner collects BTs
|
||||
await fixedRate.collectBT(exchangeOwner, exchangeId, fixedRateDetails.btBalance)
|
||||
await fixedRate.collectBasetokens(
|
||||
exchangeOwner,
|
||||
exchangeId,
|
||||
fixedRateDetails.btBalance
|
||||
)
|
||||
// btBalance is zero
|
||||
expect((await fixedRate.getExchange(exchangeId)).btBalance).to.equal('0')
|
||||
})
|
||||
|
||||
it('#collectDT- should collect DT in the contract, if exchangeOwner', async () => {
|
||||
it('#collectDatatokens- should collect DT in the contract, if exchangeOwner', async () => {
|
||||
const result = await fixedRate.getExchange(exchangeId)
|
||||
// 9 dts left
|
||||
expect(result.dtBalance).to.equal('9')
|
||||
// owner collects DTs
|
||||
await fixedRate.collectDT(exchangeOwner, exchangeId, result.dtBalance)
|
||||
await fixedRate.collectDatatokens(exchangeOwner, exchangeId, result.dtBalance)
|
||||
// no more dts in the contract
|
||||
const result2 = await fixedRate.getExchange(exchangeId)
|
||||
expect(result2.dtBalance).to.equal('0')
|
||||
@ -386,7 +384,7 @@ describe('Fixed Rate unit test', () => {
|
||||
// CREATE AN Exchange
|
||||
// we prepare transaction parameters objects
|
||||
|
||||
const nftFactory = new NftFactory(contracts.erc721FactoryAddress, web3)
|
||||
const nftFactory = new NftFactory(contracts.nftFactoryAddress, web3)
|
||||
|
||||
const freParams: FreCreationParams = {
|
||||
fixedRateAddress: contracts.fixedRateAddress,
|
||||
@ -401,10 +399,10 @@ describe('Fixed Rate unit test', () => {
|
||||
withMint: false
|
||||
}
|
||||
|
||||
const txReceipt = await nftFactory.createNftErc20WithFixedRate(
|
||||
const txReceipt = await nftFactory.createNftWithDatatokenWithFixedRate(
|
||||
exchangeOwner,
|
||||
nftData,
|
||||
ercParams,
|
||||
dtParams,
|
||||
freParams
|
||||
)
|
||||
|
||||
@ -415,13 +413,7 @@ describe('Fixed Rate unit test', () => {
|
||||
// user1 has no dt1
|
||||
expect(await balance(web3, dtAddress, user1)).to.equal('0')
|
||||
|
||||
fixedRate = new FixedRateExchange(
|
||||
web3,
|
||||
contracts.fixedRateAddress,
|
||||
8996,
|
||||
null,
|
||||
contracts.oceanAddress
|
||||
)
|
||||
fixedRate = new FixedRateExchange(contracts.fixedRateAddress, web3, 8996)
|
||||
assert(fixedRate != null)
|
||||
})
|
||||
|
||||
@ -485,31 +477,31 @@ describe('Fixed Rate unit test', () => {
|
||||
expect(await fixedRate.getRate(exchangeId)).to.equal('1')
|
||||
})
|
||||
|
||||
it('#getDTSupply - should get the dt supply in the exchange', async () => {
|
||||
it('#getDatatokenSupply - should get the dt supply in the exchange', async () => {
|
||||
// exchange owner hasn't approved any DT for sell
|
||||
expect(await fixedRate.getDTSupply(exchangeId)).to.equal('0')
|
||||
expect(await fixedRate.getDatatokenSupply(exchangeId)).to.equal('0')
|
||||
})
|
||||
|
||||
it('#getBTSupply - should get the bt supply in the exchange', async () => {
|
||||
it('#getBasetokenSupply - should get the bt supply in the exchange', async () => {
|
||||
// no baseToken at the beginning
|
||||
expect(await fixedRate.getBTSupply(exchangeId)).to.equal('0')
|
||||
expect(await fixedRate.getBasetokenSupply(exchangeId)).to.equal('0')
|
||||
})
|
||||
|
||||
it('#calcBaseInGivenOutDT - should get bt amount in for a specific dt amount', async () => {
|
||||
it('#calcBaseInGivenDatatokensOut - should get bt amount in for a specific dt amount', async () => {
|
||||
// 100.2 USDC for 100 DT (0.1% market fee and 0.1% ocean fee)
|
||||
expect(
|
||||
await (
|
||||
await fixedRate.calcBaseInGivenOutDT(exchangeId, '100')
|
||||
await fixedRate.calcBaseInGivenDatatokensOut(exchangeId, '100')
|
||||
).baseTokenAmount
|
||||
).to.equal('100.3')
|
||||
})
|
||||
|
||||
it('#getAmountBTOut - should get bt amount out for a specific dt amount', async () => {
|
||||
it('#getAmountBasetokensOut - should get bt amount out for a specific dt amount', async () => {
|
||||
// 99.8 USDC for 100 DT (0.1% market fee and 0.1% ocean fee)
|
||||
expect(await fixedRate.getAmountBTOut(exchangeId, '100')).to.equal('99.7')
|
||||
expect(await fixedRate.getAmountBasetokensOut(exchangeId, '100')).to.equal('99.7')
|
||||
})
|
||||
|
||||
it('#buyDT - user1 should buy some dt', async () => {
|
||||
it('#buyDatatokens - user1 should buy some dt', async () => {
|
||||
// total supply is ZERO right now so dt owner mints 1000 DT and approves the fixed rate contract
|
||||
await dtContract.methods
|
||||
.mint(exchangeOwner, web3.utils.toWei('1000'))
|
||||
@ -526,7 +518,7 @@ describe('Fixed Rate unit test', () => {
|
||||
)
|
||||
|
||||
// user1 buys 10 DT
|
||||
const tx = await fixedRate.buyDT(user1, exchangeId, '10', '11')
|
||||
const tx = await fixedRate.buyDatatokens(user1, exchangeId, '10', '11')
|
||||
// console.log(tx.events.Swapped.returnValues)
|
||||
assert(tx.events.Swapped != null)
|
||||
const args = tx.events.Swapped.returnValues
|
||||
@ -556,12 +548,12 @@ describe('Fixed Rate unit test', () => {
|
||||
expect((await fixedRate.getExchange(exchangeId)).dtBalance).to.equal('0')
|
||||
})
|
||||
|
||||
it('#sellDT - user1 should sell some dt', async () => {
|
||||
it('#sellDatatokens - user1 should sell some dt', async () => {
|
||||
await approve(web3, user1, dtAddress, contracts.fixedRateAddress, '10')
|
||||
const usdcBalanceBefore = new BigNumber(
|
||||
await balance(web3, contracts.usdcAddress, user1)
|
||||
)
|
||||
const tx = await fixedRate.sellDT(user1, exchangeId, '10', '9')
|
||||
const tx = await fixedRate.sellDatatokens(user1, exchangeId, '10', '9')
|
||||
// console.log(tx.events.Swapped.returnValues)
|
||||
assert(tx.events.Swapped != null)
|
||||
const args = tx.events.Swapped.returnValues
|
||||
@ -588,7 +580,7 @@ describe('Fixed Rate unit test', () => {
|
||||
// no BTs in the contract (except for the fees, but not accounted here)
|
||||
expect((await fixedRate.getExchange(exchangeId)).btBalance).to.equal('0')
|
||||
// DT supply is back at 1000 (exchange Owner allowance + dt balance in the fixed rate)
|
||||
expect(await fixedRate.getDTSupply(exchangeId)).to.equal('1000')
|
||||
expect(await fixedRate.getDatatokenSupply(exchangeId)).to.equal('1000')
|
||||
})
|
||||
|
||||
it('#getExchange - should return exchange details', async () => {
|
||||
@ -632,26 +624,30 @@ describe('Fixed Rate unit test', () => {
|
||||
expect(await fixedRate.getAllowedSwapper(exchangeId)).to.equal(ZERO_ADDRESS)
|
||||
})
|
||||
|
||||
it('#collectBT- should collect BT in the contract, if exchangeOwner', async () => {
|
||||
it('#collectBasetokens- should collect BT in the contract, if exchangeOwner', async () => {
|
||||
// there are no bt in the contract
|
||||
expect((await fixedRate.getExchange(exchangeId)).btBalance).to.equal('0')
|
||||
// user1 buys 1 DT
|
||||
await fixedRate.buyDT(user1, exchangeId, '1', '2')
|
||||
await fixedRate.buyDatatokens(user1, exchangeId, '1', '2')
|
||||
// 1 DAI in the contract
|
||||
const exchangeDetails = await fixedRate.getExchange(exchangeId)
|
||||
expect(exchangeDetails.btBalance).to.equal('1')
|
||||
// owner collects BTs
|
||||
await fixedRate.collectBT(exchangeOwner, exchangeId, exchangeDetails.btBalance)
|
||||
await fixedRate.collectBasetokens(
|
||||
exchangeOwner,
|
||||
exchangeId,
|
||||
exchangeDetails.btBalance
|
||||
)
|
||||
// btBalance is zero
|
||||
expect((await fixedRate.getExchange(exchangeId)).btBalance).to.equal('0')
|
||||
})
|
||||
|
||||
it('#collectDT- should collect DT in the contract, if exchangeOwner', async () => {
|
||||
it('#collectDatatokens- should collect DT in the contract, if exchangeOwner', async () => {
|
||||
const result = await fixedRate.getExchange(exchangeId)
|
||||
// 9 dts left
|
||||
expect(result.dtBalance).to.equal('9')
|
||||
// owner collects DTs
|
||||
await fixedRate.collectDT(exchangeOwner, exchangeId, result.dtBalance)
|
||||
await fixedRate.collectDatatokens(exchangeOwner, exchangeId, result.dtBalance)
|
||||
// no more dts in the contract
|
||||
const result2 = await fixedRate.getExchange(exchangeId)
|
||||
expect(result2.dtBalance).to.equal('0')
|
||||
|
@ -18,7 +18,7 @@ import {
|
||||
ZERO_ADDRESS
|
||||
} from '../../../../src'
|
||||
import {
|
||||
Erc20CreateParams,
|
||||
DatatokenCreateParams,
|
||||
PoolCreationParams,
|
||||
TokenInOutMarket,
|
||||
AmountsInMaxFee,
|
||||
@ -34,8 +34,8 @@ describe('SideStaking unit test', () => {
|
||||
let pool: Pool
|
||||
let sideStaking: SideStaking
|
||||
let poolAddress: string
|
||||
let erc20Token: string
|
||||
let erc20Contract: Contract
|
||||
let datatoken: string
|
||||
let datatokenContract: Contract
|
||||
let daiContract: Contract
|
||||
let usdcContract: Contract
|
||||
|
||||
@ -52,7 +52,7 @@ describe('SideStaking unit test', () => {
|
||||
owner: null
|
||||
}
|
||||
|
||||
const ercParams: Erc20CreateParams = {
|
||||
const dtParams: DatatokenCreateParams = {
|
||||
templateIndex: 1,
|
||||
minter: null,
|
||||
paymentCollector: null,
|
||||
@ -71,9 +71,9 @@ describe('SideStaking unit test', () => {
|
||||
user2 = accounts[2]
|
||||
|
||||
nftData.owner = factoryOwner
|
||||
ercParams.minter = factoryOwner
|
||||
ercParams.paymentCollector = user2
|
||||
ercParams.mpFeeAddress = factoryOwner
|
||||
dtParams.minter = factoryOwner
|
||||
dtParams.paymentCollector = user2
|
||||
dtParams.mpFeeAddress = factoryOwner
|
||||
})
|
||||
|
||||
it('should deploy contracts', async () => {
|
||||
@ -96,7 +96,7 @@ describe('SideStaking unit test', () => {
|
||||
web3,
|
||||
factoryOwner,
|
||||
contracts.daiAddress,
|
||||
contracts.erc721FactoryAddress,
|
||||
contracts.nftFactoryAddress,
|
||||
BASE_TOKEN_LIQUIDITY.toString()
|
||||
)
|
||||
|
||||
@ -106,7 +106,7 @@ describe('SideStaking unit test', () => {
|
||||
web3,
|
||||
contracts.daiAddress,
|
||||
factoryOwner,
|
||||
contracts.erc721FactoryAddress
|
||||
contracts.nftFactoryAddress
|
||||
)
|
||||
) >= BASE_TOKEN_LIQUIDITY
|
||||
)
|
||||
@ -115,7 +115,7 @@ describe('SideStaking unit test', () => {
|
||||
web3,
|
||||
factoryOwner,
|
||||
contracts.usdcAddress,
|
||||
contracts.erc721FactoryAddress,
|
||||
contracts.nftFactoryAddress,
|
||||
BASE_TOKEN_LIQUIDITY.toString()
|
||||
)
|
||||
|
||||
@ -125,7 +125,7 @@ describe('SideStaking unit test', () => {
|
||||
web3,
|
||||
contracts.usdcAddress,
|
||||
factoryOwner,
|
||||
contracts.erc721FactoryAddress
|
||||
contracts.nftFactoryAddress
|
||||
)
|
||||
) >= BASE_TOKEN_LIQUIDITY
|
||||
)
|
||||
@ -135,12 +135,12 @@ describe('SideStaking unit test', () => {
|
||||
it('#create a pool', async () => {
|
||||
// CREATE A POOL
|
||||
// we prepare transaction parameters objects
|
||||
const nftFactory = new NftFactory(contracts.erc721FactoryAddress, web3)
|
||||
const nftFactory = new NftFactory(contracts.nftFactoryAddress, web3)
|
||||
|
||||
const poolParams: PoolCreationParams = {
|
||||
ssContract: contracts.sideStakingAddress,
|
||||
baseTokenAddress: contracts.daiAddress,
|
||||
baseTokenSender: contracts.erc721FactoryAddress,
|
||||
baseTokenSender: contracts.nftFactoryAddress,
|
||||
publisherAddress: factoryOwner,
|
||||
marketFeeCollector: factoryOwner,
|
||||
poolTemplateAddress: contracts.poolTemplateAddress,
|
||||
@ -153,20 +153,20 @@ describe('SideStaking unit test', () => {
|
||||
swapFeeMarketRunner: '0.001'
|
||||
}
|
||||
|
||||
const txReceipt = await nftFactory.createNftErc20WithPool(
|
||||
const txReceipt = await nftFactory.createNftWithDatatokenWithPool(
|
||||
factoryOwner,
|
||||
nftData,
|
||||
ercParams,
|
||||
dtParams,
|
||||
poolParams
|
||||
)
|
||||
|
||||
initialBlock = await web3.eth.getBlockNumber()
|
||||
erc20Token = txReceipt.events.TokenCreated.returnValues.newTokenAddress
|
||||
datatoken = txReceipt.events.TokenCreated.returnValues.newTokenAddress
|
||||
poolAddress = txReceipt.events.NewPool.returnValues.poolAddress
|
||||
|
||||
erc20Contract = new web3.eth.Contract(ERC20Template.abi as AbiItem[], erc20Token)
|
||||
datatokenContract = new web3.eth.Contract(ERC20Template.abi as AbiItem[], datatoken)
|
||||
// user1 has no dt1
|
||||
expect(await erc20Contract.methods.balanceOf(user1).call()).to.equal('0')
|
||||
expect(await datatokenContract.methods.balanceOf(user1).call()).to.equal('0')
|
||||
})
|
||||
|
||||
it('#getRouter - should get Router address', async () => {
|
||||
@ -179,7 +179,7 @@ describe('SideStaking unit test', () => {
|
||||
expect(
|
||||
await sideStaking.getDatatokenCirculatingSupply(
|
||||
contracts.sideStakingAddress,
|
||||
erc20Token
|
||||
datatoken
|
||||
)
|
||||
).to.equal(web3.utils.toWei(BASE_TOKEN_LIQUIDITY.toString()))
|
||||
})
|
||||
@ -188,39 +188,39 @@ describe('SideStaking unit test', () => {
|
||||
expect(
|
||||
await sideStaking.getDatatokenCurrentCirculatingSupply(
|
||||
contracts.sideStakingAddress,
|
||||
erc20Token
|
||||
datatoken
|
||||
)
|
||||
).to.equal(web3.utils.toWei(BASE_TOKEN_LIQUIDITY.toString()))
|
||||
})
|
||||
|
||||
it('#getBaseToken - should get baseToken address', async () => {
|
||||
it('#getBasetoken - should get baseToken address', async () => {
|
||||
expect(
|
||||
await sideStaking.getBaseToken(contracts.sideStakingAddress, erc20Token)
|
||||
await sideStaking.getBasetoken(contracts.sideStakingAddress, datatoken)
|
||||
).to.equal(contracts.daiAddress)
|
||||
})
|
||||
|
||||
it('#getPoolAddress - should get pool address', async () => {
|
||||
expect(
|
||||
await sideStaking.getPoolAddress(contracts.sideStakingAddress, erc20Token)
|
||||
await sideStaking.getPoolAddress(contracts.sideStakingAddress, datatoken)
|
||||
).to.equal(poolAddress)
|
||||
})
|
||||
|
||||
it('#getPublisherAddress - should get publisher address', async () => {
|
||||
expect(
|
||||
await sideStaking.getPublisherAddress(contracts.sideStakingAddress, erc20Token)
|
||||
await sideStaking.getPublisherAddress(contracts.sideStakingAddress, datatoken)
|
||||
).to.equal(factoryOwner)
|
||||
})
|
||||
|
||||
it('#getBaseTokenBalance ', async () => {
|
||||
it('#getBasetokenBalance ', async () => {
|
||||
expect(
|
||||
await sideStaking.getBaseTokenBalance(contracts.sideStakingAddress, erc20Token)
|
||||
await sideStaking.getBasetokenBalance(contracts.sideStakingAddress, datatoken)
|
||||
).to.equal('0')
|
||||
})
|
||||
|
||||
it('#getDatatokenBalance ', async () => {
|
||||
expect(
|
||||
await (
|
||||
await sideStaking.getDatatokenBalance(contracts.sideStakingAddress, erc20Token)
|
||||
await sideStaking.getDatatokenBalance(contracts.sideStakingAddress, datatoken)
|
||||
).toString()
|
||||
).to.equal(
|
||||
new BigNumber(2)
|
||||
@ -232,21 +232,21 @@ describe('SideStaking unit test', () => {
|
||||
)
|
||||
})
|
||||
|
||||
it('#getvestingAmount ', async () => {
|
||||
it('#getVestingAmount ', async () => {
|
||||
expect(
|
||||
await sideStaking.getvestingAmount(contracts.sideStakingAddress, erc20Token)
|
||||
await sideStaking.getVestingAmount(contracts.sideStakingAddress, datatoken)
|
||||
).to.equal('0')
|
||||
})
|
||||
|
||||
it('#getvestingLastBlock ', async () => {
|
||||
it('#getVestingLastBlock ', async () => {
|
||||
expect(
|
||||
await sideStaking.getvestingLastBlock(contracts.sideStakingAddress, erc20Token)
|
||||
await sideStaking.getVestingLastBlock(contracts.sideStakingAddress, datatoken)
|
||||
).to.equal(initialBlock.toString())
|
||||
})
|
||||
|
||||
it('#getvestingAmountSoFar ', async () => {
|
||||
it('#getVestingAmountSoFar ', async () => {
|
||||
expect(
|
||||
await sideStaking.getvestingAmountSoFar(contracts.sideStakingAddress, erc20Token)
|
||||
await sideStaking.getVestingAmountSoFar(contracts.sideStakingAddress, datatoken)
|
||||
).to.equal('0')
|
||||
})
|
||||
|
||||
@ -258,7 +258,7 @@ describe('SideStaking unit test', () => {
|
||||
|
||||
const tokenInOutMarket: TokenInOutMarket = {
|
||||
tokenIn: contracts.daiAddress,
|
||||
tokenOut: erc20Token,
|
||||
tokenOut: datatoken,
|
||||
marketFeeAddress: factoryOwner
|
||||
}
|
||||
|
||||
@ -275,7 +275,7 @@ describe('SideStaking unit test', () => {
|
||||
amountsInOutMaxFee
|
||||
)
|
||||
|
||||
expect(await erc20Contract.methods.balanceOf(user1).call()).to.equal(
|
||||
expect(await datatokenContract.methods.balanceOf(user1).call()).to.equal(
|
||||
tx.events.LOG_SWAP.returnValues.tokenAmountOut
|
||||
)
|
||||
})
|
||||
@ -284,7 +284,7 @@ describe('SideStaking unit test', () => {
|
||||
await approve(web3, user1, contracts.daiAddress, poolAddress, '100')
|
||||
const tokenInOutMarket: TokenInOutMarket = {
|
||||
tokenIn: contracts.daiAddress,
|
||||
tokenOut: erc20Token,
|
||||
tokenOut: datatoken,
|
||||
marketFeeAddress: factoryOwner
|
||||
}
|
||||
const amountsInOutMaxFee: AmountsOutMaxFee = {
|
||||
@ -325,11 +325,11 @@ describe('SideStaking unit test', () => {
|
||||
)
|
||||
})
|
||||
|
||||
it('#exitswapPoolAmountIn- user1 exit the pool receiving only DAI', async () => {
|
||||
it('#exitSwapPoolAmountIn- user1 exit the pool receiving only DAI', async () => {
|
||||
const BPTAmountIn = '0.5'
|
||||
const minDAIOut = '0.5'
|
||||
|
||||
const tx = await pool.exitswapPoolAmountIn(
|
||||
const tx = await pool.exitSwapPoolAmountIn(
|
||||
user1,
|
||||
poolAddress,
|
||||
BPTAmountIn,
|
||||
@ -341,7 +341,7 @@ describe('SideStaking unit test', () => {
|
||||
expect(tx.events.LOG_EXIT[0].returnValues.tokenOut).to.equal(contracts.daiAddress)
|
||||
|
||||
// DTs were also unstaked in the same transaction (went to the staking contract)
|
||||
expect(tx.events.LOG_EXIT[1].returnValues.tokenOut).to.equal(erc20Token)
|
||||
expect(tx.events.LOG_EXIT[1].returnValues.tokenOut).to.equal(datatoken)
|
||||
})
|
||||
})
|
||||
|
||||
@ -349,12 +349,12 @@ describe('SideStaking unit test', () => {
|
||||
it('#create a pool', async () => {
|
||||
// CREATE A POOL
|
||||
// we prepare transaction parameters objects
|
||||
const nftFactory = new NftFactory(contracts.erc721FactoryAddress, web3)
|
||||
const nftFactory = new NftFactory(contracts.nftFactoryAddress, web3)
|
||||
|
||||
const poolParams: PoolCreationParams = {
|
||||
ssContract: contracts.sideStakingAddress,
|
||||
baseTokenAddress: contracts.usdcAddress,
|
||||
baseTokenSender: contracts.erc721FactoryAddress,
|
||||
baseTokenSender: contracts.nftFactoryAddress,
|
||||
publisherAddress: factoryOwner,
|
||||
marketFeeCollector: factoryOwner,
|
||||
poolTemplateAddress: contracts.poolTemplateAddress,
|
||||
@ -375,32 +375,32 @@ describe('SideStaking unit test', () => {
|
||||
swapFeeMarketRunner: '0.001'
|
||||
}
|
||||
|
||||
const txReceipt = await nftFactory.createNftErc20WithPool(
|
||||
const txReceipt = await nftFactory.createNftWithDatatokenWithPool(
|
||||
factoryOwner,
|
||||
nftData,
|
||||
ercParams,
|
||||
dtParams,
|
||||
poolParams
|
||||
)
|
||||
|
||||
initialBlock = await web3.eth.getBlockNumber()
|
||||
erc20Token = txReceipt.events.TokenCreated.returnValues.newTokenAddress
|
||||
datatoken = txReceipt.events.TokenCreated.returnValues.newTokenAddress
|
||||
poolAddress = txReceipt.events.NewPool.returnValues.poolAddress
|
||||
|
||||
erc20Contract = new web3.eth.Contract(ERC20Template.abi as AbiItem[], erc20Token)
|
||||
datatokenContract = new web3.eth.Contract(ERC20Template.abi as AbiItem[], datatoken)
|
||||
// user1 has no dt1
|
||||
expect(await erc20Contract.methods.balanceOf(user1).call()).to.equal('0')
|
||||
expect(await datatokenContract.methods.balanceOf(user1).call()).to.equal('0')
|
||||
})
|
||||
|
||||
it('#getBaseTokenBalance ', async () => {
|
||||
it('#getBasetokenBalance ', async () => {
|
||||
expect(
|
||||
await sideStaking.getBaseTokenBalance(contracts.sideStakingAddress, erc20Token)
|
||||
await sideStaking.getBasetokenBalance(contracts.sideStakingAddress, datatoken)
|
||||
).to.equal('0')
|
||||
})
|
||||
|
||||
it('#getDatatokenBalance ', async () => {
|
||||
expect(
|
||||
await (
|
||||
await sideStaking.getDatatokenBalance(contracts.sideStakingAddress, erc20Token)
|
||||
await sideStaking.getDatatokenBalance(contracts.sideStakingAddress, datatoken)
|
||||
).toString()
|
||||
).to.equal(
|
||||
new BigNumber(2)
|
||||
@ -412,21 +412,21 @@ describe('SideStaking unit test', () => {
|
||||
)
|
||||
})
|
||||
|
||||
it('#getvestingAmount ', async () => {
|
||||
it('#getVestingAmount ', async () => {
|
||||
expect(
|
||||
await sideStaking.getvestingAmount(contracts.sideStakingAddress, erc20Token)
|
||||
await sideStaking.getVestingAmount(contracts.sideStakingAddress, datatoken)
|
||||
).to.equal('0')
|
||||
})
|
||||
|
||||
it('#getvestingLastBlock ', async () => {
|
||||
it('#getVestingLastBlock ', async () => {
|
||||
expect(
|
||||
await sideStaking.getvestingLastBlock(contracts.sideStakingAddress, erc20Token)
|
||||
await sideStaking.getVestingLastBlock(contracts.sideStakingAddress, datatoken)
|
||||
).to.equal(initialBlock.toString())
|
||||
})
|
||||
|
||||
it('#getvestingAmountSoFar ', async () => {
|
||||
it('#getVestingAmountSoFar ', async () => {
|
||||
expect(
|
||||
await sideStaking.getvestingAmountSoFar(contracts.sideStakingAddress, erc20Token)
|
||||
await sideStaking.getVestingAmountSoFar(contracts.sideStakingAddress, datatoken)
|
||||
).to.equal('0')
|
||||
})
|
||||
|
||||
@ -439,7 +439,7 @@ describe('SideStaking unit test', () => {
|
||||
await approve(web3, user1, contracts.usdcAddress, poolAddress, '10')
|
||||
const tokenInOutMarket: TokenInOutMarket = {
|
||||
tokenIn: contracts.usdcAddress,
|
||||
tokenOut: erc20Token,
|
||||
tokenOut: datatoken,
|
||||
marketFeeAddress: factoryOwner
|
||||
}
|
||||
const amountsInOutMaxFee: AmountsInMaxFee = {
|
||||
@ -453,7 +453,7 @@ describe('SideStaking unit test', () => {
|
||||
tokenInOutMarket,
|
||||
amountsInOutMaxFee
|
||||
)
|
||||
expect(await erc20Contract.methods.balanceOf(user1).call()).to.equal(
|
||||
expect(await datatokenContract.methods.balanceOf(user1).call()).to.equal(
|
||||
tx.events.LOG_SWAP.returnValues.tokenAmountOut
|
||||
)
|
||||
})
|
||||
@ -462,7 +462,7 @@ describe('SideStaking unit test', () => {
|
||||
await approve(web3, user1, contracts.usdcAddress, poolAddress, '100')
|
||||
const tokenInOutMarket: TokenInOutMarket = {
|
||||
tokenIn: contracts.usdcAddress,
|
||||
tokenOut: erc20Token,
|
||||
tokenOut: datatoken,
|
||||
marketFeeAddress: factoryOwner
|
||||
}
|
||||
const amountsInOutMaxFee: AmountsOutMaxFee = {
|
||||
@ -501,11 +501,11 @@ describe('SideStaking unit test', () => {
|
||||
)
|
||||
})
|
||||
|
||||
it('#exitswapPoolAmountIn- user1 exit the pool receiving only USDC', async () => {
|
||||
it('#exitSwapPoolAmountIn- user1 exit the pool receiving only USDC', async () => {
|
||||
const BPTAmountIn = '0.5'
|
||||
const minUSDCOut = '0.5'
|
||||
|
||||
const tx = await pool.exitswapPoolAmountIn(
|
||||
const tx = await pool.exitSwapPoolAmountIn(
|
||||
user1,
|
||||
poolAddress,
|
||||
BPTAmountIn,
|
||||
@ -517,7 +517,7 @@ describe('SideStaking unit test', () => {
|
||||
expect(tx.events.LOG_EXIT[0].returnValues.tokenOut).to.equal(contracts.usdcAddress)
|
||||
|
||||
// DTs were also unstaked in the same transaction (went to the staking contract)
|
||||
expect(tx.events.LOG_EXIT[1].returnValues.tokenOut).to.equal(erc20Token)
|
||||
expect(tx.events.LOG_EXIT[1].returnValues.tokenOut).to.equal(datatoken)
|
||||
})
|
||||
})
|
||||
})
|
||||
|
@ -18,7 +18,7 @@ describe('Datatoken', () => {
|
||||
let user1: string
|
||||
let user2: string
|
||||
let user3: string
|
||||
let erc20DeployerUser: string
|
||||
let datatokenDeployer: string
|
||||
let contracts: Addresses
|
||||
let nftDatatoken: Nft
|
||||
let datatoken: Datatoken
|
||||
@ -44,7 +44,7 @@ describe('Datatoken', () => {
|
||||
user1 = accounts[1]
|
||||
user2 = accounts[2]
|
||||
user3 = accounts[3]
|
||||
erc20DeployerUser = accounts[4]
|
||||
datatokenDeployer = accounts[4]
|
||||
|
||||
nftData.owner = nftOwner
|
||||
})
|
||||
@ -65,15 +65,15 @@ describe('Datatoken', () => {
|
||||
})
|
||||
|
||||
it('should initialize NFTFactory instance and create a new NFT', async () => {
|
||||
nftFactory = new NftFactory(contracts.erc721FactoryAddress, web3, 8996)
|
||||
nftFactory = new NftFactory(contracts.nftFactoryAddress, web3, 8996)
|
||||
|
||||
nftAddress = await nftFactory.createNFT(nftOwner, nftData)
|
||||
nftDatatoken = new Nft(web3, 8996)
|
||||
})
|
||||
|
||||
it('#createERC20 - should create a new ERC20 DT from NFT contract', async () => {
|
||||
await nftDatatoken.addErc20Deployer(nftAddress, nftOwner, erc20DeployerUser)
|
||||
datatokenAddress = await nftDatatoken.createErc20(
|
||||
it('#createDatatoken - should create a new ERC20 Datatoken from NFT contract', async () => {
|
||||
await nftDatatoken.addDatatokenDeployer(nftAddress, nftOwner, datatokenDeployer)
|
||||
datatokenAddress = await nftDatatoken.createDatatoken(
|
||||
nftAddress,
|
||||
nftOwner,
|
||||
nftOwner,
|
||||
@ -93,7 +93,7 @@ describe('Datatoken', () => {
|
||||
})
|
||||
|
||||
it('#mint - should fail to mint DT20, if NOT Minter', async () => {
|
||||
assert((await datatoken.getDTPermissions(datatokenAddress, user1)).minter === false)
|
||||
assert((await datatoken.getPermissions(datatokenAddress, user1)).minter === false)
|
||||
try {
|
||||
await datatoken.mint(datatokenAddress, user1, '10', user1)
|
||||
assert(false)
|
||||
@ -102,54 +102,54 @@ describe('Datatoken', () => {
|
||||
}
|
||||
})
|
||||
|
||||
it('#addMinter - should add user1 as minter, if user has ERC20Deployer permission', async () => {
|
||||
assert((await nftDatatoken.isErc20Deployer(nftAddress, nftOwner)) === true)
|
||||
assert((await datatoken.getDTPermissions(datatokenAddress, user1)).minter === false)
|
||||
it('#addMinter - should add user1 as minter, if user has DatatokenDeployer permission', async () => {
|
||||
assert((await nftDatatoken.isDatatokenDeployer(nftAddress, nftOwner)) === true)
|
||||
assert((await datatoken.getPermissions(datatokenAddress, user1)).minter === false)
|
||||
|
||||
await datatoken.addMinter(datatokenAddress, nftOwner, user1)
|
||||
|
||||
assert((await datatoken.getDTPermissions(datatokenAddress, user1)).minter === true)
|
||||
assert((await datatoken.getPermissions(datatokenAddress, user1)).minter === true)
|
||||
})
|
||||
|
||||
it('#addMinter - should FAIL TO add user1 as minter, if user has ERC20Deployer permission', async () => {
|
||||
assert((await nftDatatoken.isErc20Deployer(nftAddress, user3)) === false)
|
||||
assert((await datatoken.getDTPermissions(datatokenAddress, user2)).minter === false)
|
||||
it('#addMinter - should FAIL TO add user1 as minter, if user has DatatokenDeployer permission', async () => {
|
||||
assert((await nftDatatoken.isDatatokenDeployer(nftAddress, user3)) === false)
|
||||
assert((await datatoken.getPermissions(datatokenAddress, user2)).minter === false)
|
||||
|
||||
try {
|
||||
await datatoken.addMinter(datatokenAddress, user3, user2)
|
||||
assert(false)
|
||||
} catch (e) {
|
||||
assert(e.message === 'Caller is not ERC20Deployer')
|
||||
assert(e.message === 'Caller is not DatatokenDeployer')
|
||||
}
|
||||
|
||||
assert((await datatoken.getDTPermissions(datatokenAddress, user2)).minter === false)
|
||||
assert((await datatoken.getPermissions(datatokenAddress, user2)).minter === false)
|
||||
})
|
||||
|
||||
it('#mint - should mint ERC20 datatoken to user1, if Minter', async () => {
|
||||
assert((await datatoken.getDTPermissions(datatokenAddress, nftOwner)).minter === true)
|
||||
it('#mint - should mint ERC20 Datatoken to user1, if Minter', async () => {
|
||||
assert((await datatoken.getPermissions(datatokenAddress, nftOwner)).minter === true)
|
||||
await datatoken.mint(datatokenAddress, nftOwner, '10', user1)
|
||||
|
||||
assert((await datatoken.balance(datatokenAddress, user1)) === '10')
|
||||
})
|
||||
|
||||
it('#createFixedRate - should create FRE for the erc20 dt', async () => {
|
||||
it('#createFixedRate - should create FRE for the ERC20 Datatoken', async () => {
|
||||
const fre = await datatoken.createFixedRate(datatokenAddress, nftOwner, freParams)
|
||||
assert(fre !== null)
|
||||
fixedRateAddress = fre.events.NewFixedRate.address
|
||||
exchangeId = fre.events.NewFixedRate.returnValues[0]
|
||||
})
|
||||
|
||||
it('#createFixedRate - should FAIL create FRE if NOT ERC20Deployer', async () => {
|
||||
assert((await nftDatatoken.isErc20Deployer(nftAddress, user3)) === false)
|
||||
it('#createFixedRate - should FAIL create FRE if NOT DatatokenDeployer', async () => {
|
||||
assert((await nftDatatoken.isDatatokenDeployer(nftAddress, user3)) === false)
|
||||
try {
|
||||
await datatoken.createFixedRate(datatokenAddress, user3, freParams)
|
||||
assert(false)
|
||||
} catch (e) {
|
||||
assert(e.message === 'User is not ERC20 Deployer')
|
||||
assert(e.message === 'User is not Datatoken Deployer')
|
||||
}
|
||||
})
|
||||
|
||||
it('#createDispenser - method creates a dispenser for the erc20DT', async () => {
|
||||
it('#createDispenser - method creates a dispenser for the ERC20 Datatoken', async () => {
|
||||
const dispenserParams: DispenserParams = {
|
||||
maxTokens: '10',
|
||||
maxBalance: '100'
|
||||
@ -164,12 +164,12 @@ describe('Datatoken', () => {
|
||||
assert(dispenser !== null)
|
||||
})
|
||||
|
||||
it('#createDispenser - should FAIL to create a Dispenser if not ERC20 Deployer', async () => {
|
||||
it('#createDispenser - should FAIL to create a Dispenser if not Datatoken Deployer', async () => {
|
||||
const dispenserParams: DispenserParams = {
|
||||
maxTokens: '10',
|
||||
maxBalance: '100'
|
||||
}
|
||||
assert((await nftDatatoken.isErc20Deployer(nftAddress, user3)) === false)
|
||||
assert((await nftDatatoken.isDatatokenDeployer(nftAddress, user3)) === false)
|
||||
try {
|
||||
await datatoken.createDispenser(
|
||||
datatokenAddress,
|
||||
@ -179,102 +179,102 @@ describe('Datatoken', () => {
|
||||
)
|
||||
assert(false)
|
||||
} catch (e) {
|
||||
assert(e.message === 'User is not ERC20 Deployer')
|
||||
assert(e.message === 'User is not Datatoken Deployer')
|
||||
}
|
||||
})
|
||||
|
||||
it('#removeMinter - should FAIL to remove user1 as minter, if caller is NOT ERC20Deployer', async () => {
|
||||
assert((await nftDatatoken.isErc20Deployer(nftAddress, user2)) === false)
|
||||
assert((await datatoken.getDTPermissions(datatokenAddress, user1)).minter === true)
|
||||
it('#removeMinter - should FAIL to remove user1 as minter, if caller is NOT DatatokenDeployer', async () => {
|
||||
assert((await nftDatatoken.isDatatokenDeployer(nftAddress, user2)) === false)
|
||||
assert((await datatoken.getPermissions(datatokenAddress, user1)).minter === true)
|
||||
|
||||
try {
|
||||
await datatoken.removeMinter(datatokenAddress, user2, user1)
|
||||
assert(false)
|
||||
} catch (e) {
|
||||
assert(e.message === 'Caller is not ERC20Deployer')
|
||||
assert(e.message === 'Caller is not DatatokenDeployer')
|
||||
}
|
||||
assert((await datatoken.getDTPermissions(datatokenAddress, user1)).minter === true)
|
||||
assert((await datatoken.getPermissions(datatokenAddress, user1)).minter === true)
|
||||
})
|
||||
|
||||
it('#removeMinter - should remove user1 as minter, if nftDatatoken has ERC20Deployer permission', async () => {
|
||||
assert((await nftDatatoken.isErc20Deployer(nftAddress, nftOwner)) === true)
|
||||
assert((await datatoken.getDTPermissions(datatokenAddress, user1)).minter === true)
|
||||
it('#removeMinter - should remove user1 as minter, if nftDatatoken has DatatokenDeployer permission', async () => {
|
||||
assert((await nftDatatoken.isDatatokenDeployer(nftAddress, nftOwner)) === true)
|
||||
assert((await datatoken.getPermissions(datatokenAddress, user1)).minter === true)
|
||||
|
||||
await datatoken.removeMinter(datatokenAddress, nftOwner, user1)
|
||||
|
||||
assert((await datatoken.getDTPermissions(datatokenAddress, user1)).minter === false)
|
||||
assert((await datatoken.getPermissions(datatokenAddress, user1)).minter === false)
|
||||
})
|
||||
|
||||
it('#addPaymentManager - should FAIL TO add user2 as paymentManager, if caller is NOT ERC20Deployer', async () => {
|
||||
assert((await nftDatatoken.isErc20Deployer(nftAddress, user1)) === false)
|
||||
it('#addPaymentManager - should FAIL TO add user2 as paymentManager, if caller is NOT DatatokenDeployer', async () => {
|
||||
assert((await nftDatatoken.isDatatokenDeployer(nftAddress, user1)) === false)
|
||||
assert(
|
||||
(await datatoken.getDTPermissions(datatokenAddress, user2)).paymentManager === false
|
||||
(await datatoken.getPermissions(datatokenAddress, user2)).paymentManager === false
|
||||
)
|
||||
|
||||
try {
|
||||
await datatoken.addPaymentManager(datatokenAddress, user1, user2)
|
||||
assert(false)
|
||||
} catch (e) {
|
||||
assert(e.message === 'Caller is not ERC20Deployer')
|
||||
assert(e.message === 'Caller is not DatatokenDeployer')
|
||||
}
|
||||
assert(
|
||||
(await datatoken.getDTPermissions(datatokenAddress, user2)).paymentManager === false
|
||||
(await datatoken.getPermissions(datatokenAddress, user2)).paymentManager === false
|
||||
)
|
||||
})
|
||||
|
||||
it('#addPaymentManager - should add user2 as paymentManager, if caller has ERC20Deployer permission', async () => {
|
||||
assert((await nftDatatoken.isErc20Deployer(nftAddress, nftOwner)) === true)
|
||||
it('#addPaymentManager - should add user2 as paymentManager, if caller has DatatokenDeployer permission', async () => {
|
||||
assert((await nftDatatoken.isDatatokenDeployer(nftAddress, nftOwner)) === true)
|
||||
assert(
|
||||
(await datatoken.getDTPermissions(datatokenAddress, user2)).paymentManager === false
|
||||
(await datatoken.getPermissions(datatokenAddress, user2)).paymentManager === false
|
||||
)
|
||||
|
||||
await datatoken.addPaymentManager(datatokenAddress, nftOwner, user2)
|
||||
|
||||
assert(
|
||||
(await datatoken.getDTPermissions(datatokenAddress, user2)).paymentManager === true
|
||||
(await datatoken.getPermissions(datatokenAddress, user2)).paymentManager === true
|
||||
)
|
||||
})
|
||||
|
||||
it('#removePaymentManager - should FAIL TO remove user2 as paymentManager, if nftDatatoken has ERC20Deployer permission', async () => {
|
||||
assert((await nftDatatoken.isErc20Deployer(nftAddress, user1)) === false)
|
||||
it('#removePaymentManager - should FAIL TO remove user2 as paymentManager, if nftDatatoken has DatatokenDeployer permission', async () => {
|
||||
assert((await nftDatatoken.isDatatokenDeployer(nftAddress, user1)) === false)
|
||||
assert(
|
||||
(await datatoken.getDTPermissions(datatokenAddress, user2)).paymentManager === true
|
||||
(await datatoken.getPermissions(datatokenAddress, user2)).paymentManager === true
|
||||
)
|
||||
try {
|
||||
await datatoken.removePaymentManager(datatokenAddress, user1, user2)
|
||||
assert(false)
|
||||
} catch (e) {
|
||||
assert(e.message === 'Caller is not ERC20Deployer')
|
||||
assert(e.message === 'Caller is not DatatokenDeployer')
|
||||
}
|
||||
|
||||
assert(
|
||||
(await datatoken.getDTPermissions(datatokenAddress, user2)).paymentManager === true
|
||||
(await datatoken.getPermissions(datatokenAddress, user2)).paymentManager === true
|
||||
)
|
||||
})
|
||||
|
||||
it('#removePaymentManager - should remove user2 as paymentManager, if Caller has ERC20Deployer permission', async () => {
|
||||
assert((await nftDatatoken.isErc20Deployer(nftAddress, nftOwner)) === true)
|
||||
it('#removePaymentManager - should remove user2 as paymentManager, if Caller has DatatokenDeployer permission', async () => {
|
||||
assert((await nftDatatoken.isDatatokenDeployer(nftAddress, nftOwner)) === true)
|
||||
assert(
|
||||
(await datatoken.getDTPermissions(datatokenAddress, user2)).paymentManager === true
|
||||
(await datatoken.getPermissions(datatokenAddress, user2)).paymentManager === true
|
||||
)
|
||||
|
||||
await datatoken.removePaymentManager(datatokenAddress, nftOwner, user2)
|
||||
|
||||
assert(
|
||||
(await datatoken.getDTPermissions(datatokenAddress, user2)).paymentManager === false
|
||||
(await datatoken.getPermissions(datatokenAddress, user2)).paymentManager === false
|
||||
)
|
||||
})
|
||||
|
||||
it('#setPaymentCollector - should fail to set a new paymentCollector, if NOT PAYMENT Manager, NFT OWNER OR ERC 20 DEPLOYER', async () => {
|
||||
assert(
|
||||
(await datatoken.getDTPermissions(datatokenAddress, user2)).paymentManager === false
|
||||
(await datatoken.getPermissions(datatokenAddress, user2)).paymentManager === false
|
||||
)
|
||||
|
||||
try {
|
||||
await datatoken.setPaymentCollector(datatokenAddress, user1, user2)
|
||||
assert(false)
|
||||
} catch (e) {
|
||||
assert(e.message === 'Caller is not Fee Manager, owner or erc20 Deployer')
|
||||
assert(e.message === 'Caller is not Fee Manager, owner or Datatoken Deployer')
|
||||
}
|
||||
})
|
||||
|
||||
@ -284,7 +284,7 @@ describe('Datatoken', () => {
|
||||
await datatoken.addPaymentManager(datatokenAddress, nftOwner, user1)
|
||||
|
||||
assert(
|
||||
(await datatoken.getDTPermissions(datatokenAddress, user1)).paymentManager === true
|
||||
(await datatoken.getPermissions(datatokenAddress, user1)).paymentManager === true
|
||||
)
|
||||
|
||||
await datatoken.setPaymentCollector(datatokenAddress, user1, user3)
|
||||
@ -302,11 +302,11 @@ describe('Datatoken', () => {
|
||||
|
||||
it('#setPaymentCollector - should set a new paymentCollector, if ERC 20 DEPLOYER', async () => {
|
||||
assert(
|
||||
(await nftDatatoken.getNftPermissions(nftAddress, erc20DeployerUser))
|
||||
(await nftDatatoken.getNftPermissions(nftAddress, datatokenDeployer))
|
||||
.deployERC20 === true
|
||||
)
|
||||
|
||||
await datatoken.setPaymentCollector(datatokenAddress, erc20DeployerUser, user3)
|
||||
await datatoken.setPaymentCollector(datatokenAddress, datatokenDeployer, user3)
|
||||
|
||||
assert((await datatoken.getPaymentCollector(datatokenAddress)) === user3)
|
||||
})
|
||||
@ -494,13 +494,13 @@ describe('Datatoken', () => {
|
||||
assert(buyTx !== null)
|
||||
})
|
||||
|
||||
it('#cleanPermissions - should FAIL to clean permissions at ERC20 level, if NOT NFT Owner', async () => {
|
||||
assert((await datatoken.getDTPermissions(datatokenAddress, nftOwner)).minter === true)
|
||||
it('#cleanPermissions - should FAIL to clean permissions at Datatoken level, if NOT NFT Owner', async () => {
|
||||
assert((await datatoken.getPermissions(datatokenAddress, nftOwner)).minter === true)
|
||||
|
||||
assert((await datatoken.getPaymentCollector(datatokenAddress)) === user3)
|
||||
|
||||
assert(
|
||||
(await datatoken.getDTPermissions(datatokenAddress, user1)).paymentManager === true
|
||||
(await datatoken.getPermissions(datatokenAddress, user1)).paymentManager === true
|
||||
)
|
||||
|
||||
try {
|
||||
@ -512,44 +512,42 @@ describe('Datatoken', () => {
|
||||
|
||||
assert((await datatoken.getPaymentCollector(datatokenAddress)) === user3)
|
||||
|
||||
assert((await datatoken.getDTPermissions(datatokenAddress, nftOwner)).minter === true)
|
||||
assert((await datatoken.getPermissions(datatokenAddress, nftOwner)).minter === true)
|
||||
|
||||
assert(
|
||||
(await datatoken.getDTPermissions(datatokenAddress, user1)).paymentManager === true
|
||||
(await datatoken.getPermissions(datatokenAddress, user1)).paymentManager === true
|
||||
)
|
||||
})
|
||||
|
||||
it('#cleanPermissions - should clean permissions at ERC20 level', async () => {
|
||||
assert((await datatoken.getDTPermissions(datatokenAddress, nftOwner)).minter === true)
|
||||
it('#cleanPermissions - should clean permissions at Datatoken level', async () => {
|
||||
assert((await datatoken.getPermissions(datatokenAddress, nftOwner)).minter === true)
|
||||
|
||||
assert((await datatoken.getPaymentCollector(datatokenAddress)) === user3)
|
||||
|
||||
assert(
|
||||
(await datatoken.getDTPermissions(datatokenAddress, user1)).paymentManager === true
|
||||
(await datatoken.getPermissions(datatokenAddress, user1)).paymentManager === true
|
||||
)
|
||||
|
||||
await datatoken.cleanPermissions(datatokenAddress, nftOwner)
|
||||
|
||||
assert((await datatoken.getPaymentCollector(datatokenAddress)) === nftOwner)
|
||||
|
||||
assert(
|
||||
(await datatoken.getDTPermissions(datatokenAddress, nftOwner)).minter === false
|
||||
)
|
||||
assert((await datatoken.getPermissions(datatokenAddress, nftOwner)).minter === false)
|
||||
|
||||
assert(
|
||||
(await datatoken.getDTPermissions(datatokenAddress, user1)).paymentManager === false
|
||||
(await datatoken.getPermissions(datatokenAddress, user1)).paymentManager === false
|
||||
)
|
||||
})
|
||||
|
||||
it('#getERC721Address - should succeed to get the parent ERC721 address', async () => {
|
||||
it('#getNFTAddress - should succeed to get the parent NFT address', async () => {
|
||||
const address = await datatoken.getNFTAddress(datatokenAddress)
|
||||
assert(address, 'Not able to get the parent ERC721 address')
|
||||
assert(address, 'Not able to get the parent NFT address')
|
||||
})
|
||||
|
||||
it('#setData - should set a value into 725Y standard, if Caller has ERC20Deployer permission', async () => {
|
||||
it('#setData - should set a value into 725Y standard, if Caller has DatatokenDeployer permission', async () => {
|
||||
const data = web3.utils.asciiToHex('SomeData')
|
||||
|
||||
assert((await nftDatatoken.isErc20Deployer(nftAddress, nftOwner)) === true)
|
||||
assert((await nftDatatoken.isDatatokenDeployer(nftAddress, nftOwner)) === true)
|
||||
|
||||
await datatoken.setData(datatokenAddress, nftOwner, data)
|
||||
|
||||
@ -557,16 +555,16 @@ describe('Datatoken', () => {
|
||||
assert((await nftDatatoken.getData(nftAddress, key)) === data)
|
||||
})
|
||||
|
||||
it('#setData - should FAIL to set a value into 725Y standard, if Caller has NOT ERC20Deployer permission', async () => {
|
||||
it('#setData - should FAIL to set a value into 725Y standard, if Caller has NOT DatatokenDeployer permission', async () => {
|
||||
const data = web3.utils.asciiToHex('NewData')
|
||||
const OldData = web3.utils.asciiToHex('SomeData')
|
||||
assert((await nftDatatoken.isErc20Deployer(nftAddress, user1)) === false)
|
||||
assert((await nftDatatoken.isDatatokenDeployer(nftAddress, user1)) === false)
|
||||
|
||||
try {
|
||||
await datatoken.setData(datatokenAddress, user1, data)
|
||||
assert(false)
|
||||
} catch (e) {
|
||||
assert(e.message === 'User is not ERC20 Deployer')
|
||||
assert(e.message === 'User is not Datatoken Deployer')
|
||||
}
|
||||
const key = web3.utils.keccak256(datatokenAddress)
|
||||
assert((await nftDatatoken.getData(nftAddress, key)) === OldData)
|
||||
|
@ -39,7 +39,7 @@ describe('NFT', () => {
|
||||
})
|
||||
|
||||
it('should initialize NFTFactory instance and create a new NFT', async () => {
|
||||
nftFactory = new NftFactory(contracts.erc721FactoryAddress, web3, 8996)
|
||||
nftFactory = new NftFactory(contracts.nftFactoryAddress, web3, 8996)
|
||||
|
||||
nftAddress = await nftFactory.createNFT(nftOwner, nftData)
|
||||
nftDatatoken = new Nft(web3, 8996)
|
||||
@ -50,8 +50,8 @@ describe('NFT', () => {
|
||||
assert(tokenURI === nftData.tokenURI)
|
||||
})
|
||||
|
||||
it('#createERC20 - should create a new ERC20 DT from NFT contract', async () => {
|
||||
const erc20Address = await nftDatatoken.createErc20(
|
||||
it('#createDatatoken - should create a new ERC20 Datatoken from NFT contract', async () => {
|
||||
const dtAddress = await nftDatatoken.createDatatoken(
|
||||
nftAddress,
|
||||
nftOwner,
|
||||
nftOwner,
|
||||
@ -64,12 +64,12 @@ describe('NFT', () => {
|
||||
nftData.symbol,
|
||||
1
|
||||
)
|
||||
assert(erc20Address !== null)
|
||||
assert(dtAddress !== null)
|
||||
})
|
||||
|
||||
it('#createERC20 - should fail to create a new ERC20 DT if not ERC20Deployer', async () => {
|
||||
it('#createDatatoken - should fail to create a new ERC20 Datatoken if not DatatokenDeployer', async () => {
|
||||
try {
|
||||
await nftDatatoken.createErc20(
|
||||
await nftDatatoken.createDatatoken(
|
||||
nftAddress,
|
||||
user1,
|
||||
nftOwner,
|
||||
@ -84,7 +84,7 @@ describe('NFT', () => {
|
||||
)
|
||||
assert(false)
|
||||
} catch (e) {
|
||||
assert(e.message === 'Caller is not ERC20Deployer')
|
||||
assert(e.message === 'Caller is not DatatokenDeployer')
|
||||
}
|
||||
})
|
||||
|
||||
@ -123,53 +123,53 @@ describe('NFT', () => {
|
||||
}
|
||||
})
|
||||
|
||||
// ERC20Deployer
|
||||
it('#addERC20Deployer -should add ERC20deployer if Manager', async () => {
|
||||
assert((await nftDatatoken.isErc20Deployer(nftAddress, user1)) === false)
|
||||
// DatatokenDeployer
|
||||
it('#addDatatokenDeployer -should add DatatokenDeployer if Manager', async () => {
|
||||
assert((await nftDatatoken.isDatatokenDeployer(nftAddress, user1)) === false)
|
||||
|
||||
await nftDatatoken.addErc20Deployer(nftAddress, nftOwner, user1)
|
||||
await nftDatatoken.addDatatokenDeployer(nftAddress, nftOwner, user1)
|
||||
|
||||
assert((await nftDatatoken.isErc20Deployer(nftAddress, user1)) === true)
|
||||
assert((await nftDatatoken.isDatatokenDeployer(nftAddress, user1)) === true)
|
||||
})
|
||||
|
||||
it('#addERC20Deployer - should fail to add ERC20deployer if NOT Manager', async () => {
|
||||
it('#addDatatokenDeployer - should fail to add DatatokenDeployer if NOT Manager', async () => {
|
||||
try {
|
||||
await nftDatatoken.addErc20Deployer(nftAddress, user1, user1)
|
||||
await nftDatatoken.addDatatokenDeployer(nftAddress, user1, user1)
|
||||
assert(false)
|
||||
} catch (e) {
|
||||
assert(e.message === 'Caller is not Manager')
|
||||
}
|
||||
})
|
||||
|
||||
it('#removeERC20Deployer - remove ERC20deployer if Manager', async () => {
|
||||
assert((await nftDatatoken.isErc20Deployer(nftAddress, user1)) === true)
|
||||
it('#removeDatatokenDeployer - remove DatatokenDeployer if Manager', async () => {
|
||||
assert((await nftDatatoken.isDatatokenDeployer(nftAddress, user1)) === true)
|
||||
|
||||
await nftDatatoken.removeErc20Deployer(nftAddress, nftOwner, user1)
|
||||
await nftDatatoken.removeDatatokenDeployer(nftAddress, nftOwner, user1)
|
||||
|
||||
assert((await nftDatatoken.isErc20Deployer(nftAddress, user1)) === false)
|
||||
assert((await nftDatatoken.isDatatokenDeployer(nftAddress, user1)) === false)
|
||||
})
|
||||
|
||||
it('#removeERC20Deployer - should fail and remove ERC20deployer if NOT Manager nor himself an ERC20Deployer', async () => {
|
||||
await nftDatatoken.addErc20Deployer(nftAddress, nftOwner, user1)
|
||||
assert((await nftDatatoken.isErc20Deployer(nftAddress, user1)) === true)
|
||||
it('#removeDatatokenDeployer - should fail and remove DatatokenDeployer if NOT Manager nor himself an DatatokenDeployer', async () => {
|
||||
await nftDatatoken.addDatatokenDeployer(nftAddress, nftOwner, user1)
|
||||
assert((await nftDatatoken.isDatatokenDeployer(nftAddress, user1)) === true)
|
||||
try {
|
||||
await nftDatatoken.removeErc20Deployer(nftAddress, user1, user1)
|
||||
await nftDatatoken.removeDatatokenDeployer(nftAddress, user1, user1)
|
||||
assert(false)
|
||||
} catch (e) {
|
||||
assert(e.message === 'Caller is not Manager nor ERC20Deployer')
|
||||
assert(e.message === 'Caller is not Manager nor DatatokenDeployer')
|
||||
}
|
||||
assert((await nftDatatoken.isErc20Deployer(nftAddress, user1)) === true)
|
||||
assert((await nftDatatoken.isDatatokenDeployer(nftAddress, user1)) === true)
|
||||
})
|
||||
|
||||
it('#removeERC20Deployer - should fail to remove himself as an ERC20Deployer', async () => {
|
||||
assert((await nftDatatoken.isErc20Deployer(nftAddress, user1)) === true)
|
||||
it('#removeDatatokenDeployer - should fail to remove himself as an DatatokenDeployer', async () => {
|
||||
assert((await nftDatatoken.isDatatokenDeployer(nftAddress, user1)) === true)
|
||||
try {
|
||||
await nftDatatoken.removeErc20Deployer(nftAddress, user1, user1)
|
||||
await nftDatatoken.removeDatatokenDeployer(nftAddress, user1, user1)
|
||||
assert(false)
|
||||
} catch (e) {
|
||||
assert(e.message === 'Caller is not Manager nor ERC20Deployer')
|
||||
assert(e.message === 'Caller is not Manager nor DatatokenDeployer')
|
||||
}
|
||||
assert((await nftDatatoken.isErc20Deployer(nftAddress, user1)) === true)
|
||||
assert((await nftDatatoken.isDatatokenDeployer(nftAddress, user1)) === true)
|
||||
})
|
||||
|
||||
// MetadataUpdate
|
||||
@ -264,15 +264,15 @@ describe('NFT', () => {
|
||||
|
||||
it('#transferNFT - should transfer the NFT and clean all permissions, set new owner as manager', async () => {
|
||||
await nftDatatoken.addManager(nftAddress, nftOwner, user2)
|
||||
await nftDatatoken.addErc20Deployer(nftAddress, user2, user1)
|
||||
assert((await nftDatatoken.isErc20Deployer(nftAddress, user1)) === true)
|
||||
await nftDatatoken.addDatatokenDeployer(nftAddress, user2, user1)
|
||||
assert((await nftDatatoken.isDatatokenDeployer(nftAddress, user1)) === true)
|
||||
|
||||
assert((await nftDatatoken.getNftOwner(nftAddress)) === nftOwner)
|
||||
await nftDatatoken.transferNft(nftAddress, nftOwner, user1, 1)
|
||||
assert((await nftDatatoken.getNftOwner(nftAddress)) === user1)
|
||||
|
||||
assert((await nftDatatoken.isErc20Deployer(nftAddress, nftOwner)) === false)
|
||||
assert((await nftDatatoken.isErc20Deployer(nftAddress, user2)) === false)
|
||||
assert((await nftDatatoken.isDatatokenDeployer(nftAddress, nftOwner)) === false)
|
||||
assert((await nftDatatoken.isDatatokenDeployer(nftAddress, user2)) === false)
|
||||
})
|
||||
|
||||
// Safe transfer test
|
||||
@ -292,8 +292,8 @@ describe('NFT', () => {
|
||||
|
||||
it('#safeTransferNft - should transfer the NFT and clean all permissions, set new owner as manager', async () => {
|
||||
await nftDatatoken.addManager(nftAddress, nftOwner, user2)
|
||||
await nftDatatoken.addErc20Deployer(nftAddress, user2, user1)
|
||||
assert((await nftDatatoken.isErc20Deployer(nftAddress, user1)) === true)
|
||||
await nftDatatoken.addDatatokenDeployer(nftAddress, user2, user1)
|
||||
assert((await nftDatatoken.isDatatokenDeployer(nftAddress, user1)) === true)
|
||||
|
||||
assert((await nftDatatoken.getNftOwner(nftAddress)) === nftOwner)
|
||||
await nftDatatoken.safeTransferNft(nftAddress, nftOwner, user1, 1)
|
||||
@ -312,12 +312,12 @@ describe('NFT', () => {
|
||||
|
||||
it('#cleanPermissions - should cleanPermissions if NFTOwner', async () => {
|
||||
await nftDatatoken.addManager(nftAddress, user1, user1)
|
||||
await nftDatatoken.addErc20Deployer(nftAddress, user1, user2)
|
||||
assert((await nftDatatoken.isErc20Deployer(nftAddress, user2)) === true)
|
||||
await nftDatatoken.addDatatokenDeployer(nftAddress, user1, user2)
|
||||
assert((await nftDatatoken.isDatatokenDeployer(nftAddress, user2)) === true)
|
||||
|
||||
await nftDatatoken.cleanPermissions(nftAddress, user1)
|
||||
|
||||
assert((await nftDatatoken.isErc20Deployer(nftAddress, user2)) === false)
|
||||
assert((await nftDatatoken.isDatatokenDeployer(nftAddress, user2)) === false)
|
||||
assert((await nftDatatoken.getNftPermissions(nftAddress, nftOwner)).manager === false)
|
||||
})
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user