1
0
mirror of https://github.com/oceanprotocol/market.git synced 2024-12-02 05:57:29 +01:00
Bogdan Fazakas 165a9b0fb3
Feature/wagmi (#1912)
* wagmi + ethers + web3modal setup

* refactor wallet components

* fallback providers, more config

* kick out useWeb3

* remove all useWeb3 imports

* more web3.js usage removal

* isAddress utils replacement

* restore add token / add network

* less accountId changes

* web3 legacy tinkering, utils/web3 → utils/wallet

* legacy web3 object for ocean.js

* graph sync fix, remove custom network switching code

* package updates, merge fixes

* downgrade to ethers v5

* fix project id

* switch to ConnectKit

* connectkit theming

* add existing chains to wagmi

* rewrite getPaymentCollector()

* kick out getPaymentCollector completely, use wagmi hooks instead

* Revert "kick out getPaymentCollector completely, use wagmi hooks instead"

This reverts commit 54c7d1ef1a2dec0b1575a685125ba78336b30f59.

* switch getPaymentCollector

* calcBaseInGivenDatatokensOut reorg

* wip integrate ocean lib 3.0.0

* update orbis components to use wagmi instead of web hooks

* more oceanjs integration updates

* more refactors

* fix build

* update ocean lib

* fix publish

* fix order fixed rate

* remove logs

* debug and stop infinite cycle orbis connect

* fix orbis dm connection

* mock use network and fix some more tests

* mock wagmi switch network

* mock wagmi  useProvider createClient and connectKit getDefaultClient

* fix jest tests

* try storybook fix

* cleanups and bump ocean lib

* fix order

* bump lib to next.5 and add more modal style

* bump ocean.js lib to 3.0.0

---------

Co-authored-by: Matthias Kretschmann <m@kretschmann.io>
2023-05-29 13:28:41 +03:00

299 lines
8.9 KiB
TypeScript

import {
Config,
DDO,
FreCreationParams,
generateDid,
DatatokenCreateParams,
DispenserCreationParams,
getHash,
LoggerInstance,
Metadata,
NftCreateData,
NftFactory,
Service,
ZERO_ADDRESS,
getEventFromTx
} from '@oceanprotocol/lib'
import { mapTimeoutStringToSeconds, normalizeFile } from '@utils/ddo'
import { generateNftCreateData } from '@utils/nft'
import { getEncryptedFiles } from '@utils/provider'
import slugify from 'slugify'
import { algorithmContainerPresets } from './_constants'
import { FormPublishData, MetadataAlgorithmContainer } from './_types'
import {
marketFeeAddress,
publisherMarketOrderFee,
publisherMarketFixedSwapFee,
defaultDatatokenTemplateIndex
} from '../../../app.config'
import { sanitizeUrl } from '@utils/url'
import { getContainerChecksum } from '@utils/docker'
import { parseEther } from 'ethers/lib/utils'
function getUrlFileExtension(fileUrl: string): string {
const splittedFileUrl = fileUrl.split('.')
return splittedFileUrl[splittedFileUrl.length - 1]
}
async function getAlgorithmContainerPreset(
dockerImage: string
): Promise<MetadataAlgorithmContainer> {
if (dockerImage === '') return
const preset = algorithmContainerPresets.find(
(preset) => `${preset.image}:${preset.tag}` === dockerImage
)
preset.checksum = await (
await getContainerChecksum(preset.image, preset.tag)
).checksum
return preset
}
function dateToStringNoMS(date: Date): string {
return date.toISOString().replace(/\.[0-9]{3}Z/, 'Z')
}
function transformTags(originalTags: string[]): string[] {
const transformedTags = originalTags?.map((tag) => slugify(tag).toLowerCase())
return transformedTags
}
export async function transformPublishFormToDdo(
values: FormPublishData,
// Those 2 are only passed during actual publishing process
// so we can always assume if they are not passed, we are on preview.
datatokenAddress?: string,
nftAddress?: string
): Promise<DDO> {
const { metadata, services, user } = values
const { chainId, accountId } = user
const {
type,
name,
description,
tags,
author,
termsAndConditions,
dockerImage,
dockerImageCustom,
dockerImageCustomTag,
dockerImageCustomEntrypoint,
dockerImageCustomChecksum
} = metadata
const { access, files, links, providerUrl, timeout } = services[0]
const did = nftAddress ? generateDid(nftAddress, chainId) : '0x...'
const currentTime = dateToStringNoMS(new Date())
const isPreview = !datatokenAddress && !nftAddress
const algorithmContainerPresets =
type === 'algorithm' && dockerImage !== '' && dockerImage !== 'custom'
? await getAlgorithmContainerPreset(dockerImage)
: null
// Transform from files[0].url to string[] assuming only 1 file
const filesTransformed = files?.length &&
files[0].valid && [sanitizeUrl(files[0].url)]
const linksTransformed = links?.length &&
links[0].valid && [sanitizeUrl(links[0].url)]
const newMetadata: Metadata = {
created: currentTime,
updated: currentTime,
type,
name,
description,
tags: transformTags(tags),
author,
license: 'https://market.oceanprotocol.com/terms',
links: linksTransformed,
additionalInformation: {
termsAndConditions
},
...(type === 'algorithm' &&
dockerImage !== '' && {
algorithm: {
language: filesTransformed?.length
? getUrlFileExtension(filesTransformed[0])
: '',
version: '0.1',
container: {
entrypoint:
dockerImage === 'custom'
? dockerImageCustomEntrypoint
: algorithmContainerPresets.entrypoint,
image:
dockerImage === 'custom'
? dockerImageCustom
: algorithmContainerPresets.image,
tag:
dockerImage === 'custom'
? dockerImageCustomTag
: algorithmContainerPresets.tag,
checksum:
dockerImage === 'custom'
? dockerImageCustomChecksum
: algorithmContainerPresets.checksum
}
}
})
}
const file = {
nftAddress,
datatokenAddress,
files: [normalizeFile(files[0].type, files[0], chainId)]
}
const filesEncrypted =
!isPreview &&
files?.length &&
files[0].valid &&
(await getEncryptedFiles(file, chainId, providerUrl.url))
const newService: Service = {
id: getHash(datatokenAddress + filesEncrypted),
type: access,
files: filesEncrypted || '',
datatokenAddress,
serviceEndpoint: providerUrl.url,
timeout: mapTimeoutStringToSeconds(timeout),
...(access === 'compute' && {
compute: values.services[0].computeOptions
})
}
const newDdo: DDO = {
'@context': ['https://w3id.org/did/v1'],
id: did,
nftAddress,
version: '4.1.0',
chainId,
metadata: newMetadata,
services: [newService],
// Only added for DDO preview, reflecting Asset response,
// again, we can assume if `datatokenAddress` is not passed,
// we are on preview.
...(!datatokenAddress && {
datatokens: [
{
name: values.services[0].dataTokenOptions.name,
symbol: values.services[0].dataTokenOptions.symbol
}
],
nft: {
...generateNftCreateData(values?.metadata.nft, accountId)
}
})
}
return newDdo
}
export async function createTokensAndPricing(
values: FormPublishData,
accountId: string,
config: Config,
nftFactory: NftFactory
) {
const nftCreateData: NftCreateData = generateNftCreateData(
values.metadata.nft,
accountId,
values.metadata.transferable
)
LoggerInstance.log('[publish] Creating NFT with metadata', nftCreateData)
// TODO: cap is hardcoded for now to 1000, this needs to be discussed at some point
const ercParams: DatatokenCreateParams = {
templateIndex: defaultDatatokenTemplateIndex,
minter: accountId,
paymentCollector: accountId,
mpFeeAddress: marketFeeAddress,
feeToken: values.pricing.baseToken.address,
feeAmount: publisherMarketOrderFee,
// max number
cap: '115792089237316195423570985008687907853269984665640564039457',
name: values.services[0].dataTokenOptions.name,
symbol: values.services[0].dataTokenOptions.symbol
}
LoggerInstance.log('[publish] Creating datatoken with ercParams', ercParams)
let erc721Address, datatokenAddress, txHash
switch (values.pricing.type) {
case 'fixed': {
const freParams: FreCreationParams = {
fixedRateAddress: config.fixedRateExchangeAddress,
baseTokenAddress: values.pricing.baseToken.address,
owner: accountId,
marketFeeCollector: marketFeeAddress,
baseTokenDecimals: values.pricing.baseToken.decimals,
datatokenDecimals: 18,
fixedRate: values.pricing.price.toString(),
marketFee: publisherMarketFixedSwapFee,
withMint: true
}
LoggerInstance.log(
'[publish] Creating fixed pricing with freParams',
freParams
)
const result = await nftFactory.createNftWithDatatokenWithFixedRate(
nftCreateData,
ercParams,
freParams
)
const trxReceipt = await result.wait()
const nftCreatedEvent = getEventFromTx(trxReceipt, 'NFTCreated')
const tokenCreatedEvent = getEventFromTx(trxReceipt, 'TokenCreated')
erc721Address = nftCreatedEvent.args.newTokenAddress
datatokenAddress = tokenCreatedEvent.args.newTokenAddress
txHash = trxReceipt.transactionHash
LoggerInstance.log('[publish] createNftErcWithFixedRate tx', txHash)
break
}
case 'free': {
// maxTokens - how many tokens cand be dispensed when someone requests . If maxTokens=2 then someone can't request 3 in one tx
// maxBalance - how many dt the user has in it's wallet before the dispenser will not dispense dt
// both will be just 1 for the market
const dispenserParams: DispenserCreationParams = {
dispenserAddress: config.dispenserAddress,
maxTokens: parseEther('1').toString(),
maxBalance: parseEther('1').toString(),
withMint: true,
allowedSwapper: ZERO_ADDRESS
}
LoggerInstance.log(
'[publish] Creating free pricing with dispenserParams',
dispenserParams
)
const result = await nftFactory.createNftWithDatatokenWithDispenser(
nftCreateData,
ercParams,
dispenserParams
)
const trxReceipt = await result.wait()
const nftCreatedEvent = getEventFromTx(trxReceipt, 'NFTCreated')
const tokenCreatedEvent = getEventFromTx(trxReceipt, 'TokenCreated')
erc721Address = nftCreatedEvent.args.newTokenAddress
datatokenAddress = tokenCreatedEvent.args.newTokenAddress
txHash = trxReceipt.transactionHash
LoggerInstance.log('[publish] createNftErcWithDispenser tx', txHash)
break
}
}
return { erc721Address, datatokenAddress, txHash }
}