Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ export const CollectibleCard = of({
mediaType: '',
},
contract: {
id: 'address',
address: 'address',
chainId: 1,
name: '',
Expand Down
6 changes: 5 additions & 1 deletion packages/mask/src/plugins/EVM/UI/Web3State/getAssetsFn.ts
Original file line number Diff line number Diff line change
Expand Up @@ -189,7 +189,11 @@ export const getNonFungibleTokenFn =
name: x.info.name ?? `${x.contractDetailed.name} ${x.tokenId}`,
description: x.info.description ?? '',
owner: x.info.owner,
contract: { ...x.contractDetailed, type: TokenType.NonFungible },
contract: {
...x.contractDetailed,
type: TokenType.NonFungible,
id: x.contractDetailed.address,
},
metadata: {
name: x.info.name ?? `${x.contractDetailed.name} ${x.tokenId}`,
description: x.info.description ?? '',
Expand Down
2 changes: 2 additions & 0 deletions packages/plugin-infra/src/web3-types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -163,11 +163,13 @@ export declare namespace Web3Plugin {
}

export interface NonFungibleContract {
id: string
chainId: number
name: string
symbol: string
address: string
iconURL?: string
balance?: number
}

export interface FungibleTokenMetadata {
Expand Down
1 change: 1 addition & 0 deletions packages/provider-proxy/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
"@rollup/plugin-commonjs": "^21.0.1",
"@rollup/plugin-json": "^4.1.0",
"@rollup/plugin-node-resolve": "^13.0.6",
"@rollup/plugin-replace": "^3.0.1",
"@rollup/plugin-sucrase": "^4.0.1",
"date-fns": "^2.27.0",
"rollup": "^2.60.1",
Expand Down
4 changes: 4 additions & 0 deletions packages/provider-proxy/rollup.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import sucrase from '@rollup/plugin-sucrase'
import json from '@rollup/plugin-json'
import alias from '@rollup/plugin-alias'
import dts from 'rollup-plugin-dts'
import replace from '@rollup/plugin-replace'

const config = {
input: './src/index.ts',
Expand All @@ -22,6 +23,9 @@ const config = {
],
}),
sucrase({ transforms: ['typescript', 'jsx'] }),
replace({
'process.env.PROVIDER_API_ENV': JSON.stringify('proxy'),
}),
],
external: (id) => {
if (id.startsWith('.')) return false
Expand Down
34 changes: 21 additions & 13 deletions packages/provider-proxy/src/producers/nonFungibleCollectionAsset.ts
Original file line number Diff line number Diff line change
@@ -1,37 +1,45 @@
import { getOpenSeaCollectionList } from '@masknet/web3-providers'
import type { ProducerArgBase, ProducerKeyFunction, ProducerPushFunction, RPCMethodRegistrationValue } from '../types'
import type { Web3Plugin } from '@masknet/plugin-infra'
import { getNFTScanNFTList, getOpenSeaCollectionList } from '@masknet/web3-providers'
import { collectAllPageDate } from '../helper/request'

interface Collection {
name: string
image?: string
slug: string
}
import type { ProducerArgBase, ProducerKeyFunction, ProducerPushFunction, RPCMethodRegistrationValue } from '../types'

interface NonFungibleCollectibleAssetArgs extends ProducerArgBase {
address: string
}

const nonFungibleCollectionAsset = async (
push: ProducerPushFunction<Collection>,
push: ProducerPushFunction<Web3Plugin.NonFungibleContract>,
getKeys: ProducerKeyFunction,
args: NonFungibleCollectibleAssetArgs,
): Promise<void> => {
const { address } = args
const openSeaApiKey = await getKeys('opensea')

const pageSize = 50
const collectFromOpenSea = await collectAllPageDate<Collection>(
const collectionsFromNFTScan = await getNFTScanNFTList(address)
await push(
collectionsFromNFTScan.map((x) => ({
id: x.contractDetailed.address,
chainId: x.contractDetailed.chainId,
name: x.contractDetailed.name,
symbol: x.contractDetailed.symbol,
address: x.contractDetailed.address,
iconURL: x.contractDetailed.iconURL,
balance: x.balance,
})),
)

const collectionsFromOpenSea = await collectAllPageDate<Web3Plugin.NonFungibleContract>(
(page: number) => getOpenSeaCollectionList(openSeaApiKey, address, page, pageSize),
pageSize,
)
await push(collectFromOpenSea)
await push(collectionsFromOpenSea)
}

const producer: RPCMethodRegistrationValue<Collection, NonFungibleCollectibleAssetArgs> = {
const producer: RPCMethodRegistrationValue<Web3Plugin.NonFungibleContract, NonFungibleCollectibleAssetArgs> = {
method: 'mask.fetchNonFungibleCollectionAsset',
producer: nonFungibleCollectionAsset,
distinctBy: (item) => item.name,
distinctBy: (item) => item.address,
}

export default producer
8 changes: 7 additions & 1 deletion packages/web3-providers/src/NFTScan/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import urlcat from 'urlcat'
import type { NonFungibleTokenAPI } from '..'
import { NFTSCAN_ACCESS_TOKEN_URL, NFTSCAN_BASE_API } from './constants'
import type { NFTScanAsset, NFT_Assets } from './types'
import { isProxyENV } from '../helpers'

const tokenCache = new Map<'token', { token: string; expiration: Date }>()

Expand All @@ -13,7 +14,7 @@ async function getToken() {
if (token && isBefore(Date.now(), token.expiration)) {
return token.token
}
const response = await fetch(NFTSCAN_ACCESS_TOKEN_URL, { mode: 'cors' })
const response = await fetch(NFTSCAN_ACCESS_TOKEN_URL, { ...(!isProxyENV && { mode: 'cors' }) })
const {
data,
}: {
Expand Down Expand Up @@ -116,3 +117,8 @@ export class NFTScanAPI implements NonFungibleTokenAPI.Provider {
}
}
}

export function getNFTScanNFTList(address: string) {
const nftScanAPI = new NFTScanAPI()
return nftScanAPI.getContractBalance(address)
}
2 changes: 2 additions & 0 deletions packages/web3-providers/src/helpers.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
export const isProxyENV = process.env.PROVIDER_API_ENV === 'proxy'

export async function fetchJSON<T = unknown>(requestInfo: RequestInfo, requestInit?: RequestInit): Promise<T> {
const res = await globalThis.fetch(requestInfo, requestInit)
return res.json()
Expand Down
1 change: 1 addition & 0 deletions packages/web3-providers/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,3 +21,4 @@ export const KeyValue = new KeyValueAPI()
export { getOpenSeaNFTList, getOpenSeaCollectionList } from './opensea'
export { getAssetListFromDebank } from './debank'
export { getRaribleNFTList } from './rarible'
export { getNFTScanNFTList } from './NFTScan'
33 changes: 16 additions & 17 deletions packages/web3-providers/src/opensea/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ import fromUnixTime from 'date-fns/fromUnixTime'
import isAfter from 'date-fns/isAfter'
import { head, uniqBy } from 'lodash-unified'
import urlcat from 'urlcat'
import { NonFungibleTokenAPI } from '../types'
import type { NonFungibleTokenAPI } from '../types'
import { getOrderUnitPrice, getOrderUSDPrice } from './utils'
import type {
OpenSeaAssetContract,
Expand All @@ -24,15 +24,16 @@ import type {
OpenSeaResponse,
} from './types'
import { OPENSEA_ACCOUNT_URL, OPENSEA_API_KEY, OPENSEA_API_URL } from './constants'
import { isProxyENV } from '../helpers'

async function fetchFromOpenSea<T>(url: string, chainId: ChainId, apiKey?: string, env?: NonFungibleTokenAPI.APIEnv) {
async function fetchFromOpenSea<T>(url: string, chainId: ChainId, apiKey?: string) {
if (![ChainId.Mainnet, ChainId.Rinkeby].includes(chainId)) return
const currentEnv = env ?? NonFungibleTokenAPI.APIEnv.browser

try {
const response = await fetch(urlcat(OPENSEA_API_URL, url), {
method: 'GET',
headers: { 'x-api-key': apiKey ?? OPENSEA_API_KEY, Accept: 'application/json' },
...(currentEnv === NonFungibleTokenAPI.APIEnv.browser && { mode: 'cors' }),
...(!isProxyENV && { mode: 'cors' }),
})
if (response.status === 404) return
return response.json() as Promise<T>
Expand Down Expand Up @@ -243,10 +244,8 @@ function createAssetOrder(order: OpenSeaAssetOrder): NonFungibleTokenAPI.AssetOr

export class OpenSeaAPI implements NonFungibleTokenAPI.Provider {
private readonly _apiKey
private readonly _env: NonFungibleTokenAPI.APIEnv
constructor(apiKey?: string, env?: NonFungibleTokenAPI.APIEnv) {
constructor(apiKey?: string) {
this._apiKey = apiKey
this._env = env ?? NonFungibleTokenAPI.APIEnv.browser
}
async getAsset(address: string, tokenId: string, { chainId = ChainId.Mainnet }: { chainId?: ChainId } = {}) {
const requestPath = urlcat('/api/v1/asset/:address/:tokenId', { address, tokenId })
Expand Down Expand Up @@ -277,12 +276,7 @@ export class OpenSeaAPI implements NonFungibleTokenAPI.Provider {
limit: size,
collection: opts.pageInfo?.collection,
})
const response = await fetchFromOpenSea<{ assets: OpenSeaResponse[] }>(
requestPath,
chainId,
this._apiKey,
this._env,
)
const response = await fetchFromOpenSea<{ assets: OpenSeaResponse[] }>(requestPath, chainId, this._apiKey)
const assets =
response?.assets
.filter(
Expand Down Expand Up @@ -340,7 +334,7 @@ export class OpenSeaAPI implements NonFungibleTokenAPI.Provider {
offset: page * size,
limit: size,
})
const response = await fetchFromOpenSea<OpenSeaCollection[]>(requestPath, chainId, this._apiKey, this._env)
const response = await fetchFromOpenSea<OpenSeaCollection[]>(requestPath, chainId, this._apiKey)
if (!response) {
return {
data: [],
Expand All @@ -353,7 +347,12 @@ export class OpenSeaAPI implements NonFungibleTokenAPI.Provider {
name: x.name,
image: x.image_url || undefined,
slug: x.slug,
address: x.address,
id: x.slug,
chainId,
symbol: x.primary_asset_contracts?.[0]?.symbol,
address: x.primary_asset_contracts?.[0]?.address,
iconURL: x.image_url,
balance: x.owned_asset_count,
})) ?? []

return {
Expand All @@ -364,11 +363,11 @@ export class OpenSeaAPI implements NonFungibleTokenAPI.Provider {
}

export function getOpenSeaNFTList(apiKey: string, address: string, page?: number, size?: number) {
const opensea = new OpenSeaAPI(apiKey, NonFungibleTokenAPI.APIEnv.proxy)
const opensea = new OpenSeaAPI(apiKey)
return opensea.getTokens(address, { page, size })
}

export function getOpenSeaCollectionList(apiKey: string, address: string, page?: number, size?: number) {
const opensea = new OpenSeaAPI(apiKey, NonFungibleTokenAPI.APIEnv.proxy)
const opensea = new OpenSeaAPI(apiKey)
return opensea.getCollections(address, { page, size })
}
6 changes: 6 additions & 0 deletions packages/web3-providers/src/opensea/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,12 @@ export interface OpenSeaCollection extends OpenSeaFees {
external_link?: string
wiki_link?: string
safelist_request_status: string
owned_asset_count: number
primary_asset_contracts: {
address: string
asset_contract_type: string
symbol: string
}[]
}

export interface OpenSeaResponse extends Asset {
Expand Down
14 changes: 5 additions & 9 deletions packages/web3-providers/src/rarible/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import {
import { RaribleUserURL, RaribleRopstenUserURL, RaribleMainnetURL, RaribleChainURL, RaribleURL } from './constants'
import { toRaribleImage } from './utils'
import { NonFungibleTokenAPI } from '..'
import { isProxyENV } from '../helpers'

const resolveRaribleUserNetwork = createLookupTableResolver<ChainId.Mainnet | ChainId.Ropsten, string>(
{
Expand All @@ -27,10 +28,9 @@ const resolveRaribleUserNetwork = createLookupTableResolver<ChainId.Mainnet | Ch
RaribleUserURL,
)

async function fetchFromRarible<T>(url: string, path: string, init?: RequestInit, env?: NonFungibleTokenAPI.APIEnv) {
const currentEnv = env ?? NonFungibleTokenAPI.APIEnv.browser
async function fetchFromRarible<T>(url: string, path: string, init?: RequestInit) {
const response = await fetch(urlcat(url, path), {
...(currentEnv === NonFungibleTokenAPI.APIEnv.browser && { mode: 'cors' }),
...(!isProxyENV && { mode: 'cors' }),
...init,
})
return response.json() as Promise<T>
Expand Down Expand Up @@ -142,10 +142,6 @@ function _getAsset(address: string, tokenId: string) {
}

export class RaribleAPI implements NonFungibleTokenAPI.Provider {
private readonly _env: NonFungibleTokenAPI.APIEnv
constructor(env?: NonFungibleTokenAPI.APIEnv) {
this._env = env ?? NonFungibleTokenAPI.APIEnv.browser
}
async getAsset(address: string, tokenId: string, { chainId = ChainId.Mainnet }: { chainId?: ChainId } = {}) {
const asset = await _getAsset(address, tokenId)
if (!asset) return
Expand All @@ -168,7 +164,7 @@ export class RaribleAPI implements NonFungibleTokenAPI.Provider {
continuation: string
items: RaribleNFTItemMapResponse[]
}
const asset = await fetchFromRarible<Payload>(RaribleURL, requestPath, undefined, this._env)
const asset = await fetchFromRarible<Payload>(RaribleURL, requestPath, undefined)
if (!asset)
return {
data: [],
Expand Down Expand Up @@ -341,6 +337,6 @@ export function getRaribleNFTList(
size?: number,
pageInfo?: { [key in string]: unknown },
) {
const rarible = new RaribleAPI(NonFungibleTokenAPI.APIEnv.proxy)
const rarible = new RaribleAPI()
return rarible.getTokens(address, { page, size, pageInfo })
}
4 changes: 0 additions & 4 deletions packages/web3-providers/src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -106,10 +106,6 @@ export namespace PriceAPI {
}

export namespace NonFungibleTokenAPI {
export enum APIEnv {
browser = 0,
proxy = 1,
}
export enum OrderSide {
Buy = 0,
Sell = 1,
Expand Down
17 changes: 14 additions & 3 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.