Commit 36524cc0 authored by Yuri Mikhin's avatar Yuri Mikhin Committed by Yuri Mikhin

Add marketplace app iframe integration.

Signed-off-by: default avatarYuri Mikhin <urasergeevich@mail.ru>
parent dd09f361
import type { AppItemOverview } from 'types/client/apps';
import { APP_CATEGORIES } from 'ui/apps/constants';
export const TEMPORARY_DEMO_APPS: Array<AppItemOverview> = [
{
author: 'xDaichain',
id: 'easy-staking',
title: 'Easy Staking',
logo: 'https://www.fillmurray.com/144/144',
categories: [ APP_CATEGORIES[0], APP_CATEGORIES[1] ],
shortDescription: 'Accessible DeFi staking platform for STAKE holders on Ethereum',
site: 'https://easy-staking.xdaichain.com/',
// eslint-disable-next-line max-len
description: 'Easy Staking allows users to place STAKE into a contract and receive STAKE emissions on Ethereum. It provides an accessible staking mechanism for users and increases STAKE utility and DeFi composability. EasyStaking also:\n\n- Incentivizes liquidity providers on decentralized exchanges through unique reward mechanisms\n- Creates staking opportunities via hardware wallets and other Ethereum applications\n- Provides staking opportunities with no minimum STAKE requirements to participate\n- Limits total circulating supply',
url: 'https://blockscout-allowance-mainnet-stage.vercel.app/',
twitter: 'https://twitter.com/EasyStaking',
telegram: 'https://t.me/easystaking',
github: 'https://github.com/mikhin',
},
{
author: 'xDaichain',
id: 'curve',
title: 'Curve',
logo: 'https://www.fillmurray.com/144/144',
categories: [ APP_CATEGORIES[1], APP_CATEGORIES[2] ],
// eslint-disable-next-line max-len
shortDescription: 'Curve is an exchange liquidity pool on Ethereum designed for: extremely efficient stablecoin trading, low risk, supplemental fee income for liquidity providers, without an opportunity cost.',
site: 'https://xdai.curve.fi/',
// eslint-disable-next-line max-len
description: 'Curve is an exchange liquidity pool on Ethereum designed for: extremely efficient stablecoin trading, low risk, supplemental fee income for liquidity providers, without an opportunity cost.',
url: 'https://blockscout-allowance-mainnet-stage.vercel.app/',
twitter: 'https://twitter.com/EasyStaking',
telegram: 'https://t.me/easystaking',
github: 'https://github.com/mikhin',
},
{
author: 'xDaichain',
id: 'honwyswap',
title: 'HonwySwap',
logo: 'https://www.fillmurray.com/144/144',
categories: [ APP_CATEGORIES[1], APP_CATEGORIES[2] ],
// eslint-disable-next-line max-len
shortDescription: 'Honeyswap is a decentralized exchange built on the Gnosis Chain, this enables users to experience fast and secure transactions with incredibly low fees. Multiple tokens are available with which you can swap and add liquidity.',
site: 'https://honeyswap.org/',
// eslint-disable-next-line max-len
description: 'Honeyswap is a decentralized exchange built on the Gnosis Chain, this enables users to experience fast and secure transactions with incredibly low fees. Multiple tokens are available with which you can swap and add liquidity.',
url: 'https://blockscout-allowance-mainnet-stage.vercel.app/',
twitter: 'https://twitter.com/EasyStaking',
telegram: 'https://t.me/easystaking',
github: 'https://github.com/mikhin',
},
{
author: 'xDaichain',
id: 'sushi',
title: 'Sushi',
logo: 'https://www.fillmurray.com/144/144',
categories: [ APP_CATEGORIES[0], APP_CATEGORIES[1] ],
shortDescription: 'Swap, yield, lend, borrow, leverage, limit, launch all on one community-driven ecosystem',
site: 'https://app.sushi.com/',
description: 'Swap, yield, lend, borrow, leverage, limit, launch all on one community-driven ecosystem',
url: 'https://blockscout-allowance-mainnet-stage.vercel.app/',
twitter: 'https://twitter.com/EasyStaking',
telegram: 'https://t.me/easystaking',
github: 'https://github.com/mikhin',
},
{
author: 'xDaichain',
id: 'bao-finance',
title: 'Bao Finance',
logo: 'https://www.fillmurray.com/144/144',
categories: [ APP_CATEGORIES[0], APP_CATEGORIES[1] ],
shortDescription: 'Yield Farming for Synthetic Assets from LP tokens',
site: 'https://farms.baoswap.xyz/',
description: 'Yield Farming for Synthetic Assets from LP tokens',
url: 'https://blockscout-allowance-mainnet-stage.vercel.app/',
twitter: 'https://twitter.com/EasyStaking',
telegram: 'https://t.me/easystaking',
github: 'https://github.com/mikhin',
},
{
author: 'xDaichain',
id: 'component',
title: 'Component',
logo: 'https://www.fillmurray.com/144/144',
categories: [ APP_CATEGORIES[1], APP_CATEGORIES[2] ],
// eslint-disable-next-line max-len
shortDescription: 'During the Unit protocol development, we faced difficulty finding a reliable, flexible protocol for stablecoin swap without interface censorship.',
site: 'https://xdai.component.finance',
// eslint-disable-next-line max-len
description: 'During the Unit protocol development, we faced difficulty finding a reliable, flexible protocol for stablecoin swap without interface censorship.',
url: 'https://blockscout-allowance-mainnet-stage.vercel.app/',
twitter: 'https://twitter.com/EasyStaking',
telegram: 'https://t.me/easystaking',
github: 'https://github.com/mikhin',
},
{
author: 'xDaichain',
id: 'pooltogether',
title: 'PoolTogether',
logo: 'https://www.fillmurray.com/144/144',
categories: [ APP_CATEGORIES[1], APP_CATEGORIES[2] ],
shortDescription: 'View, deposit and withdraw for all V3 Pools',
site: 'https://app.pooltogether.com/',
description: 'View, deposit and withdraw for all V3 Pools',
url: 'https://blockscout-allowance-mainnet-stage.vercel.app/',
twitter: 'https://twitter.com/EasyStaking',
telegram: 'https://t.me/easystaking',
github: 'https://github.com/mikhin',
},
{
author: 'xDaichain',
id: 'swapr',
title: 'Swapr',
logo: 'https://www.fillmurray.com/144/144',
categories: [ APP_CATEGORIES[0], APP_CATEGORIES[1] ],
shortDescription: 'A governance-enabled automated market maker with adjustable fees.',
site: 'https://swapr.eth.limo',
description: 'A governance-enabled automated market maker with adjustable fees.',
url: 'https://blockscout-allowance-mainnet-stage.vercel.app/',
twitter: 'https://twitter.com/EasyStaking',
telegram: 'https://t.me/easystaking',
github: 'https://github.com/mikhin',
},
{
author: 'xDaichain',
id: 'levinswap',
title: 'Levinswap',
logo: 'https://www.fillmurray.com/144/144',
categories: [ APP_CATEGORIES[0], APP_CATEGORIES[1] ],
// eslint-disable-next-line max-len
shortDescription: 'AMM DEX on the xDai chain. Its uniqueness comes from the ability to trade securities tokens, specifically, tokenized real estate tokens.',
site: 'https://app.levinswap.org/',
description: 'AMM DEX on the xDai chain. Its uniqueness comes from the ability to trade securities tokens, specifically, tokenized real estate tokens.',
url: 'https://blockscout-allowance-mainnet-stage.vercel.app/',
twitter: 'https://twitter.com/EasyStaking',
telegram: 'https://t.me/easystaking',
github: 'https://github.com/mikhin',
},
{
author: 'xDaichain',
id: 'omen',
title: 'Omen',
logo: 'https://www.fillmurray.com/144/144',
categories: [ APP_CATEGORIES[1], APP_CATEGORIES[2] ],
shortDescription: 'Decentralized prediction markets on Ethereum',
site: 'https://xdai.omen.eth.link/',
description: 'Decentralized prediction markets on Ethereum',
url: 'https://blockscout-allowance-mainnet-stage.vercel.app/',
twitter: 'https://twitter.com/EasyStaking',
telegram: 'https://t.me/easystaking',
github: 'https://github.com/mikhin',
},
{
author: 'xDaichain',
id: 'nifty-ink',
title: 'Nifty Ink',
logo: 'https://www.fillmurray.com/144/144',
categories: [ APP_CATEGORIES[1], APP_CATEGORIES[2] ],
shortDescription: 'NFT artwork created and sold on xDAI using meta transactions, burner wallets, and bridged to Ethereum',
site: 'https://nifty.ink/explore',
description: 'NFT artwork created and sold on xDAI using meta transactions, burner wallets, and bridged to Ethereum',
url: 'https://blockscout-allowance-mainnet-stage.vercel.app/',
twitter: 'https://twitter.com/EasyStaking',
telegram: 'https://t.me/easystaking',
github: 'https://github.com/mikhin',
},
{
author: 'xDaichain',
id: 'treasure-chess',
title: 'Treasure Chess',
logo: 'https://www.fillmurray.com/144/144',
categories: [ APP_CATEGORIES[0], APP_CATEGORIES[1] ],
shortDescription: 'Every chess game is one-of-a-kind. Make yours a collectible.',
site: 'https://treasure.chess.com/',
description: 'Every chess game is one-of-a-kind. Make yours a collectible.',
url: 'https://blockscout-allowance-mainnet-stage.vercel.app/',
twitter: 'https://twitter.com/EasyStaking',
telegram: 'https://t.me/easystaking',
github: 'https://github.com/mikhin',
},
{
author: 'xDaichain',
id: 'unique-one',
title: 'Unique.One',
logo: 'https://www.fillmurray.com/144/144',
categories: [ APP_CATEGORIES[0], APP_CATEGORIES[1] ],
// eslint-disable-next-line max-len
shortDescription: 'A truly decentralised non-profit platform owned and managed by the Digital Arts community, bringing together Artists, Creators and Collectors as One.',
site: 'https://www.unique.one/',
// eslint-disable-next-line max-len
description: 'A truly decentralised non-profit platform owned and managed by the Digital Arts community, bringing together Artists, Creators and Collectors as One.',
url: 'https://blockscout-allowance-mainnet-stage.vercel.app/',
twitter: 'https://twitter.com/EasyStaking',
telegram: 'https://t.me/easystaking',
github: 'https://github.com/mikhin',
},
{
author: 'xDaichain',
id: 'cold-truth-culture',
title: 'Cold Truth Culture',
logo: 'https://www.fillmurray.com/144/144',
categories: [ APP_CATEGORIES[1], APP_CATEGORIES[2] ],
shortDescription: 'A Community That Empowers NFT Artists',
site: 'https://www.coldtruthculture.io/',
description: 'A Community That Empowers NFT Artists',
url: 'https://blockscout-allowance-mainnet-stage.vercel.app/',
twitter: 'https://twitter.com/EasyStaking',
telegram: 'https://t.me/easystaking',
github: 'https://github.com/mikhin',
},
{
author: 'xDaichain',
id: 'xdai-bridge',
title: 'xDai Bridge',
logo: 'https://www.fillmurray.com/144/144',
categories: [ APP_CATEGORIES[1], APP_CATEGORIES[2] ],
shortDescription: 'Token bridge between the Gnosis Chain and the Ethereum network',
site: 'https://bridge.gnosischain.com/',
description: 'Token bridge between the Gnosis Chain and the Ethereum network',
url: 'https://blockscout-allowance-mainnet-stage.vercel.app/',
twitter: 'https://twitter.com/EasyStaking',
telegram: 'https://t.me/easystaking',
github: 'https://github.com/mikhin',
},
{
author: 'xDaichain',
id: 'omni-bridge',
title: 'OmniBridge',
logo: 'https://www.fillmurray.com/144/144',
categories: [ APP_CATEGORIES[0], APP_CATEGORIES[1] ],
shortDescription: 'The OmniBridge multi-token extension is the simplest way to transfer ANY ERC20/ ERC677 /ERC827 token to and from the xDai chain.',
site: 'https://omni.gnosischain.com/bridge',
description: 'The OmniBridge multi-token extension is the simplest way to transfer ANY ERC20/ ERC677 /ERC827 token to and from the xDai chain.',
url: 'https://blockscout-allowance-mainnet-stage.vercel.app/',
twitter: 'https://twitter.com/EasyStaking',
telegram: 'https://t.me/easystaking',
github: 'https://github.com/mikhin',
},
{
author: 'xDaichain',
id: 'gnosis-safe',
title: 'Gnosis Safe',
logo: 'https://www.fillmurray.com/144/144',
categories: [ APP_CATEGORIES[0], APP_CATEGORIES[1] ],
shortDescription: 'Gnosis Safe is the most trusted platform to manage digital assets on Ethereum',
site: 'https://gnosis-safe.io/',
description: 'Gnosis Safe is the most trusted platform to manage digital assets on Ethereum',
url: 'https://blockscout-allowance-mainnet-stage.vercel.app/',
twitter: 'https://twitter.com/EasyStaking',
telegram: 'https://t.me/easystaking',
github: 'https://github.com/mikhin',
},
{
author: 'xDaichain',
id: 'multisender',
title: 'Multisender',
logo: 'https://www.fillmurray.com/144/144',
categories: [ APP_CATEGORIES[1], APP_CATEGORIES[2] ],
// eslint-disable-next-line max-len
shortDescription: 'Send ERC20 token or ETH. Batch sender. Bulk Sender. Token Multisender allows you to airdrop tokens in a few transactions in trustless way. Batch sending ERC20, Ethereum tokens.',
site: 'https://multisender.app/',
// eslint-disable-next-line max-len
description: 'Send ERC20 token or ETH. Batch sender. Bulk Sender. Token Multisender allows you to airdrop tokens in a few transactions in trustless way. Batch sending ERC20, Ethereum tokens.',
url: 'https://blockscout-allowance-mainnet-stage.vercel.app/',
twitter: 'https://twitter.com/EasyStaking',
telegram: 'https://t.me/easystaking',
github: 'https://github.com/mikhin',
},
{
author: 'xDaichain',
id: 'disperse',
title: 'Disperse',
logo: 'https://www.fillmurray.com/144/144',
categories: [ APP_CATEGORIES[1], APP_CATEGORIES[2] ],
shortDescription: 'Distribute ether or tokens to multiple addresses',
site: 'https://disperse.app/',
description: 'Distribute ether or tokens to multiple addresses',
url: 'https://blockscout-allowance-mainnet-stage.vercel.app/',
twitter: 'https://twitter.com/EasyStaking',
telegram: 'https://t.me/easystaking',
github: 'https://github.com/mikhin',
},
{
author: 'xDaichain',
id: 'symmetric',
title: 'Symmetric',
logo: 'https://www.fillmurray.com/144/144',
categories: [ APP_CATEGORIES[1], APP_CATEGORIES[2] ],
// eslint-disable-next-line max-len
shortDescription: 'DEX or Decentralized Exchange, also called an Automated Market Maker (AMM) in Decentralized Finance (DeFi). Symmetric is live on gnosis chain (xDai) and Celo.',
site: 'https://symmetric.finance/',
// eslint-disable-next-line max-len
description: 'DEX or Decentralized Exchange, also called an Automated Market Maker (AMM) in Decentralized Finance (DeFi). Symmetric is live on gnosis chain (xDai) and Celo.',
url: 'https://blockscout-allowance-mainnet-stage.vercel.app/',
twitter: 'https://twitter.com/EasyStaking',
telegram: 'https://t.me/easystaking',
github: 'https://github.com/mikhin',
},
];
[
{
"chainId": 1,
"author": "xDaichain",
"id": "easy-staking",
"title": "Easy Staking Revoke.cash",
"logo": "https://www.fillmurray.com/144/144",
"categories": [
"defi",
"exchanges"
],
"shortDescription": "Accessible DeFi staking platform for STAKE holders on Ethereum",
"site": "https://easy-staking.xdaichain.com/",
"description": "Easy Staking allows users to place STAKE into a contract and receive STAKE emissions on Ethereum. It provides an accessible staking mechanism for users and increases STAKE utility and DeFi composability. EasyStaking also:\n\n- Incentivizes liquidity providers on decentralized exchanges through unique reward mechanisms\n- Creates staking opportunities via hardware wallets and other Ethereum applications\n- Provides staking opportunities with no minimum STAKE requirements to participate\n- Limits total circulating supply",
"url": "https://revoke.cash",
"twitter": "https://twitter.com/EasyStaking",
"telegram": "https://t.me/easystaking",
"github": "https://github.com/mikhin"
},
{
"chainId": 99,
"author": "xDaichain",
"id": "curve",
"title": "Curve Revoke.cash",
"logo": "https://www.fillmurray.com/144/144",
"categories": [
"exchanges",
"finance"
],
"shortDescription": "Curve is an exchange liquidity pool on Ethereum designed for: extremely efficient stablecoin trading, low risk, supplemental fee income for liquidity providers, without an opportunity cost.",
"site": "https://xdai.curve.fi/",
"description": "Curve is an exchange liquidity pool on Ethereum designed for: extremely efficient stablecoin trading, low risk, supplemental fee income for liquidity providers, without an opportunity cost.",
"url": "https://revoke.cash",
"twitter": "https://twitter.com/EasyStaking",
"telegram": "https://t.me/easystaking",
"github": "https://github.com/mikhin"
},
{
"chainId": 1,
"author": "xDaichain",
"id": "honwyswap",
"title": "HonwySwap Revoke.cash",
"logo": "https://www.fillmurray.com/144/144",
"categories": [
"exchanges",
"finance"
],
"shortDescription": "Honeyswap is a decentralized exchange built on the Gnosis Chain, this enables users to experience fast and secure transactions with incredibly low fees. Multiple tokens are available with which you can swap and add liquidity.",
"site": "https://honeyswap.org/",
"description": "Honeyswap is a decentralized exchange built on the Gnosis Chain, this enables users to experience fast and secure transactions with incredibly low fees. Multiple tokens are available with which you can swap and add liquidity.",
"url": "https://revoke.cash",
"twitter": "https://twitter.com/EasyStaking",
"telegram": "https://t.me/easystaking",
"github": "https://github.com/mikhin"
},
{
"chainId": 99,
"author": "xDaichain",
"id": "sushi",
"title": "Sushi Revoke.cash",
"logo": "https://www.fillmurray.com/144/144",
"categories": [
"defi",
"exchanges"
],
"shortDescription": "Swap, yield, lend, borrow, leverage, limit, launch all on one community-driven ecosystem",
"site": "https://app.sushi.com/",
"description": "Swap, yield, lend, borrow, leverage, limit, launch all on one community-driven ecosystem",
"url": "https://revoke.cash",
"twitter": "https://twitter.com/EasyStaking",
"telegram": "https://t.me/easystaking",
"github": "https://github.com/mikhin"
},
{
"chainId": 1,
"author": "xDaichain",
"id": "bao-finance",
"title": "Bao Finance",
"logo": "https://www.fillmurray.com/144/144",
"categories": [
"defi",
"exchanges"
],
"shortDescription": "Yield Farming for Synthetic Assets from LP tokens",
"site": "https://farms.baoswap.xyz/",
"description": "Yield Farming for Synthetic Assets from LP tokens",
"url": "https://blockscout-allowance-mainnet-stage.vercel.app/",
"twitter": "https://twitter.com/EasyStaking",
"telegram": "https://t.me/easystaking",
"github": "https://github.com/mikhin"
},
{
"chainId": 99,
"author": "xDaichain",
"id": "component",
"title": "Component",
"logo": "https://www.fillmurray.com/144/144",
"categories": [
"exchanges",
"finance"
],
"shortDescription": "During the Unit protocol development, we faced difficulty finding a reliable, flexible protocol for stablecoin swap without interface censorship.",
"site": "https://xdai.component.finance",
"description": "During the Unit protocol development, we faced difficulty finding a reliable, flexible protocol for stablecoin swap without interface censorship.",
"url": "https://blockscout-allowance-mainnet-stage.vercel.app/",
"twitter": "https://twitter.com/EasyStaking",
"telegram": "https://t.me/easystaking",
"github": "https://github.com/mikhin"
},
{
"chainId": 1,
"author": "xDaichain",
"id": "pooltogether",
"title": "PoolTogether",
"logo": "https://www.fillmurray.com/144/144",
"categories": [
"exchanges",
"finance"
],
"shortDescription": "View, deposit and withdraw for all V3 Pools",
"site": "https://app.pooltogether.com/",
"description": "View, deposit and withdraw for all V3 Pools",
"url": "https://blockscout-allowance-mainnet-stage.vercel.app/",
"twitter": "https://twitter.com/EasyStaking",
"telegram": "https://t.me/easystaking",
"github": "https://github.com/mikhin"
},
{
"chainId": 99,
"author": "xDaichain",
"id": "swapr",
"title": "Swapr",
"logo": "https://www.fillmurray.com/144/144",
"categories": [
"defi",
"exchanges"
],
"shortDescription": "A governance-enabled automated market maker with adjustable fees.",
"site": "https://swapr.eth.limo",
"description": "A governance-enabled automated market maker with adjustable fees.",
"url": "https://blockscout-allowance-mainnet-stage.vercel.app/",
"twitter": "https://twitter.com/EasyStaking",
"telegram": "https://t.me/easystaking",
"github": "https://github.com/mikhin"
},
{
"chainId": 1,
"author": "xDaichain",
"id": "levinswap",
"title": "Levinswap",
"logo": "https://www.fillmurray.com/144/144",
"categories": [
"defi",
"exchanges"
],
"shortDescription": "AMM DEX on the xDai chain. Its uniqueness comes from the ability to trade securities tokens, specifically, tokenized real estate tokens.",
"site": "https://app.levinswap.org/",
"description": "AMM DEX on the xDai chain. Its uniqueness comes from the ability to trade securities tokens, specifically, tokenized real estate tokens.",
"url": "https://blockscout-allowance-mainnet-stage.vercel.app/",
"twitter": "https://twitter.com/EasyStaking",
"telegram": "https://t.me/easystaking",
"github": "https://github.com/mikhin"
},
{
"chainId": 99,
"author": "xDaichain",
"id": "omen",
"title": "Omen",
"logo": "https://www.fillmurray.com/144/144",
"categories": [
"exchanges",
"finance"
],
"shortDescription": "Decentralized prediction markets on Ethereum",
"site": "https://xdai.omen.eth.link/",
"description": "Decentralized prediction markets on Ethereum",
"url": "https://blockscout-allowance-mainnet-stage.vercel.app/",
"twitter": "https://twitter.com/EasyStaking",
"telegram": "https://t.me/easystaking",
"github": "https://github.com/mikhin"
},
{
"chainId": 1,
"author": "xDaichain",
"id": "nifty-ink",
"title": "Nifty Ink",
"logo": "https://www.fillmurray.com/144/144",
"categories": [
"exchanges",
"finance"
],
"shortDescription": "NFT artwork created and sold on xDAI using meta transactions, burner wallets, and bridged to Ethereum",
"site": "https://nifty.ink/explore",
"description": "NFT artwork created and sold on xDAI using meta transactions, burner wallets, and bridged to Ethereum",
"url": "https://blockscout-allowance-mainnet-stage.vercel.app/",
"twitter": "https://twitter.com/EasyStaking",
"telegram": "https://t.me/easystaking",
"github": "https://github.com/mikhin"
},
{
"chainId": 99,
"author": "xDaichain",
"id": "treasure-chess",
"title": "Treasure Chess",
"logo": "https://www.fillmurray.com/144/144",
"categories": [
"defi",
"exchanges"
],
"shortDescription": "Every chess game is one-of-a-kind. Make yours a collectible.",
"site": "https://treasure.chess.com/",
"description": "Every chess game is one-of-a-kind. Make yours a collectible.",
"url": "https://blockscout-allowance-mainnet-stage.vercel.app/",
"twitter": "https://twitter.com/EasyStaking",
"telegram": "https://t.me/easystaking",
"github": "https://github.com/mikhin"
},
{
"chainId": 1,
"author": "xDaichain",
"id": "unique-one",
"title": "Unique.One",
"logo": "https://www.fillmurray.com/144/144",
"categories": [
"defi",
"exchanges"
],
"shortDescription": "A truly decentralised non-profit platform owned and managed by the Digital Arts community, bringing together Artists, Creators and Collectors as One.",
"site": "https://www.unique.one/",
"description": "A truly decentralised non-profit platform owned and managed by the Digital Arts community, bringing together Artists, Creators and Collectors as One.",
"url": "https://blockscout-allowance-mainnet-stage.vercel.app/",
"twitter": "https://twitter.com/EasyStaking",
"telegram": "https://t.me/easystaking",
"github": "https://github.com/mikhin"
},
{
"chainId": 99,
"author": "xDaichain",
"id": "cold-truth-culture",
"title": "Cold Truth Culture",
"logo": "https://www.fillmurray.com/144/144",
"categories": [
"exchanges",
"finance"
],
"shortDescription": "A Community That Empowers NFT Artists",
"site": "https://www.coldtruthculture.io/",
"description": "A Community That Empowers NFT Artists",
"url": "https://blockscout-allowance-mainnet-stage.vercel.app/",
"twitter": "https://twitter.com/EasyStaking",
"telegram": "https://t.me/easystaking",
"github": "https://github.com/mikhin"
},
{
"chainId": 1,
"author": "xDaichain",
"id": "xdai-bridge",
"title": "xDai Bridge",
"logo": "https://www.fillmurray.com/144/144",
"categories": [
"exchanges",
"finance"
],
"shortDescription": "Token bridge between the Gnosis Chain and the Ethereum network",
"site": "https://bridge.gnosischain.com/",
"description": "Token bridge between the Gnosis Chain and the Ethereum network",
"url": "https://blockscout-allowance-mainnet-stage.vercel.app/",
"twitter": "https://twitter.com/EasyStaking",
"telegram": "https://t.me/easystaking",
"github": "https://github.com/mikhin"
},
{
"chainId": 99,
"author": "xDaichain",
"id": "omni-bridge",
"title": "OmniBridge",
"logo": "https://www.fillmurray.com/144/144",
"categories": [
"defi",
"exchanges"
],
"shortDescription": "The OmniBridge multi-token extension is the simplest way to transfer ANY ERC20/ ERC677 /ERC827 token to and from the xDai chain.",
"site": "https://omni.gnosischain.com/bridge",
"description": "The OmniBridge multi-token extension is the simplest way to transfer ANY ERC20/ ERC677 /ERC827 token to and from the xDai chain.",
"url": "https://blockscout-allowance-mainnet-stage.vercel.app/",
"twitter": "https://twitter.com/EasyStaking",
"telegram": "https://t.me/easystaking",
"github": "https://github.com/mikhin"
},
{
"chainId": 1,
"author": "xDaichain",
"id": "gnosis-safe",
"title": "Gnosis Safe",
"logo": "https://www.fillmurray.com/144/144",
"categories": [
"defi",
"exchanges"
],
"shortDescription": "Gnosis Safe is the most trusted platform to manage digital assets on Ethereum",
"site": "https://gnosis-safe.io/",
"description": "Gnosis Safe is the most trusted platform to manage digital assets on Ethereum",
"url": "https://blockscout-allowance-mainnet-stage.vercel.app/",
"twitter": "https://twitter.com/EasyStaking",
"telegram": "https://t.me/easystaking",
"github": "https://github.com/mikhin"
},
{
"chainId": 99,
"author": "xDaichain",
"id": "multisender",
"title": "Multisender",
"logo": "https://www.fillmurray.com/144/144",
"categories": [
"exchanges",
"finance"
],
"shortDescription": "Send ERC20 token or ETH. Batch sender. Bulk Sender. Token Multisender allows you to airdrop tokens in a few transactions in trustless way. Batch sending ERC20, Ethereum tokens.",
"site": "https://multisender.app/",
"description": "Send ERC20 token or ETH. Batch sender. Bulk Sender. Token Multisender allows you to airdrop tokens in a few transactions in trustless way. Batch sending ERC20, Ethereum tokens.",
"url": "https://blockscout-allowance-mainnet-stage.vercel.app/",
"twitter": "https://twitter.com/EasyStaking",
"telegram": "https://t.me/easystaking",
"github": "https://github.com/mikhin"
},
{
"chainId": 1,
"author": "xDaichain",
"id": "disperse",
"title": "Disperse",
"logo": "https://www.fillmurray.com/144/144",
"categories": [
"exchanges",
"finance"
],
"shortDescription": "Distribute ether or tokens to multiple addresses",
"site": "https://disperse.app/",
"description": "Distribute ether or tokens to multiple addresses",
"url": "https://blockscout-allowance-mainnet-stage.vercel.app/",
"twitter": "https://twitter.com/EasyStaking",
"telegram": "https://t.me/easystaking",
"github": "https://github.com/mikhin"
},
{
"chainId": 99,
"author": "xDaichain",
"id": "symmetric",
"title": "Symmetric",
"logo": "https://www.fillmurray.com/144/144",
"categories": [
"exchanges",
"finance"
],
"shortDescription": "DEX or Decentralized Exchange, also called an Automated Market Maker (AMM) in Decentralized Finance (DeFi). Symmetric is live on gnosis chain (xDai) and Celo.",
"site": "https://symmetric.finance/",
"description": "DEX or Decentralized Exchange, also called an Automated Market Maker (AMM) in Decentralized Finance (DeFi). Symmetric is live on gnosis chain (xDai) and Celo.",
"url": "https://blockscout-allowance-mainnet-stage.vercel.app/",
"twitter": "https://twitter.com/EasyStaking",
"telegram": "https://t.me/easystaking",
"github": "https://github.com/mikhin"
}
]
declare module 'react-identicons'
declare module 'data/marketplaceApps.json' {
import type { AppItemOverview } from './types/client/apps';
const value: Array<AppItemOverview>;
export default value;
}
const getMarketplaceApps = require('../getMarketplaceApps');
const parseNetworkConfig = require('../networks/parseNetworkConfig');
const KEY_WORDS = {
......@@ -23,6 +24,14 @@ function getNetworksExternalAssets() {
return icons;
}
function getMarketplaceAppsOrigins() {
return getMarketplaceApps().map(({ url }) => url);
}
function getMarketplaceAppsLogosOrigins() {
return getMarketplaceApps().map(({ logo }) => logo);
}
function makePolicyMap() {
const networkExternalAssets = getNetworksExternalAssets();
......@@ -80,6 +89,9 @@ function makePolicyMap() {
// network assets
...networkExternalAssets.map((url) => url.host),
// marketplace apps logos
...getMarketplaceAppsLogosOrigins(),
],
'font-src': [
......@@ -101,6 +113,8 @@ function makePolicyMap() {
'report-uri': [
process.env.SENTRY_CSP_REPORT_URI,
],
'frame-src': getMarketplaceAppsOrigins(),
};
}
......
// should be CommonJS module since it used for next.config.js
const data = require('../data/marketplaceApps.json');
function getMarketplaceApps() {
return data;
}
module.exports = getMarketplaceApps;
import React from 'react';
import React, { useMemo } from 'react';
import marketplaceApps from 'data/marketplaceApps.json';
import abiIcon from 'icons/ABI.svg';
import apiKeysIcon from 'icons/API.svg';
import appsIcon from 'icons/apps.svg';
......@@ -13,8 +14,18 @@ import transactionsIcon from 'icons/transactions.svg';
import watchlistIcon from 'icons/watchlist.svg';
import useCurrentRoute from 'lib/link/useCurrentRoute';
import useLink from 'lib/link/useLink';
import notEmpty from 'lib/notEmpty';
import useNetwork from './useNetwork';
export default function useNavItems() {
const selectedNetwork = useNetwork();
const isMarketplaceFilled = useMemo(() =>
marketplaceApps.filter(item => item.chainId === selectedNetwork?.chainId),
[ selectedNetwork?.chainId ])
.length > 0;
const link = useLink();
const currentRoute = useCurrentRoute()();
......@@ -23,12 +34,13 @@ export default function useNavItems() {
{ text: 'Blocks', url: link('blocks'), icon: blocksIcon, isActive: currentRoute.startsWith('block') },
{ text: 'Transactions', url: link('txs_validated'), icon: transactionsIcon, isActive: currentRoute.startsWith('tx') },
{ text: 'Tokens', url: link('tokens'), icon: tokensIcon, isActive: currentRoute === 'tokens' },
{ text: 'Apps', url: link('apps'), icon: appsIcon, isActive: currentRoute === 'apps' },
isMarketplaceFilled ?
{ text: 'Apps', url: link('apps'), icon: appsIcon, isActive: currentRoute === 'apps' } : null,
// there should be custom site sections like Stats, Faucet, More, etc but never an 'other'
// examples https://explorer-edgenet.polygon.technology/ and https://explorer.celo.org/
// at this stage custom menu items is under development, we will implement it later
// { text: 'Other', url: link('other'), icon: gearIcon, isActive: currentRoute === 'other' },
];
].filter(notEmpty);
const accountNavItems = [
{ text: 'Watchlist', url: link('watchlist'), icon: watchlistIcon, isActive: currentRoute === 'watchlist' },
......@@ -41,5 +53,5 @@ export default function useNavItems() {
const profileItem = { text: 'My profile', url: link('profile'), icon: profileIcon, isActive: currentRoute === 'profile' };
return { mainNavItems, accountNavItems, profileItem };
}, [ link, currentRoute ]);
}, [ isMarketplaceFilled, link, currentRoute ]);
}
......@@ -109,6 +109,9 @@ export const ROUTES = {
apps: {
pattern: `${ BASE_PATH }/apps`,
},
app_index: {
pattern: `${ BASE_PATH }/apps/[id]`,
},
// SEARCH
search_results: {
......
export default function notEmpty<TValue>(value: TValue | null | undefined): value is TValue {
return value !== null && value !== undefined;
}
import type { NextPage } from 'next';
import Head from 'next/head';
import React from 'react';
import { useRouter } from 'next/router';
import React, { useEffect, useState } from 'react';
import App from 'ui/pages/App';
import type { AppItemOverview } from 'types/client/apps';
import marketplaceApps from 'data/marketplaceApps.json';
import { apos } from 'lib/html-entities';
import EmptySearchResult from 'ui/apps/EmptySearchResult';
import MarketplaceApp from 'ui/pages/MarketplaceApp';
import Page from 'ui/shared/Page/Page';
const AppPage: NextPage = () => {
const router = useRouter();
const [ isLoading, setIsLoading ] = useState(true);
const [ app, setApp ] = useState<AppItemOverview | undefined>(undefined);
const { id }: { id?: string } = router.query;
useEffect(() => {
if (!id) {
return;
}
const app = marketplaceApps.find((app) => app.id === id);
setApp(app);
setIsLoading(false);
}, [ id ]);
if (app || isLoading) {
return (
<>
<Head><title>{ app ? `Blockscout | ${ app.title }` : 'Loading app..' }</title></Head>
<MarketplaceApp app={ app } isLoading={ isLoading }/>
</>
);
}
return (
<>
<Head><title>App Card Page</title></Head>
<App/>
</>
<Page>
<Head><title>Blockscout | No app found</title></Head>
<EmptySearchResult text={ `Couldn${ apos }t find an app.` }/>
</Page>
);
};
......
export type AppCategory = {
id: string;
name: string;
export enum MarketplaceCategoryNames {
'defi',
'exchanges',
'finance',
'games',
'marketplaces',
'nft',
'security',
'social',
'tools',
'yieldFarming',
}
export type AppItemPreview = {
......@@ -8,10 +16,11 @@ export type AppItemPreview = {
title: string;
logo: string;
shortDescription: string;
categories: Array<AppCategory>;
categories: Array<keyof typeof MarketplaceCategoryNames>;
}
export type AppItemOverview = AppItemPreview & {
chainId: number;
author: string;
url: string;
description: string;
......
import { Box, Heading, Icon, IconButton, Image, Link, LinkBox, LinkOverlay, Text, useColorModeValue } from '@chakra-ui/react';
import NextLink from 'next/link';
import type { MouseEvent } from 'react';
import React, { useCallback } from 'react';
......@@ -7,6 +8,10 @@ import type { AppItemPreview } from 'types/client/apps';
import northEastIcon from 'icons/arrows/north-east.svg';
import starFilledIcon from 'icons/star_filled.svg';
import starOutlineIcon from 'icons/star_outline.svg';
import useLink from 'lib/link/useLink';
import notEmpty from 'lib/notEmpty';
import { APP_CATEGORIES } from './constants';
interface Props extends AppItemPreview {
onInfoClick: (id: string) => void;
......@@ -24,7 +29,7 @@ const AppCard = ({ id,
onFavoriteClick,
}: Props) => {
const categoriesLabel = categories.map(c => c.name).join(', ');
const categoriesLabel = categories.map(c => APP_CATEGORIES[c]).filter(notEmpty).join(', ');
const handleInfoClick = useCallback((event: MouseEvent) => {
event.preventDefault();
......@@ -35,6 +40,8 @@ const AppCard = ({ id,
onFavoriteClick(id, isFavorite);
}, [ onFavoriteClick, id, isFavorite ]);
const link = useLink();
return (
<LinkBox
_hover={{
......@@ -76,11 +83,11 @@ const AppCard = ({ id,
fontSize={{ base: 'sm', sm: 'lg' }}
fontWeight="semibold"
>
<LinkOverlay
href="#"
>
{ title }
</LinkOverlay>
<NextLink href={ link('app_index', { id: id }) } passHref>
<LinkOverlay>
{ title }
</LinkOverlay>
</NextLink>
</Heading>
<Text
......
import { Box, Heading, Skeleton, SkeletonCircle, useColorModeValue } from '@chakra-ui/react';
import React from 'react';
export const AppCardSkeleton = () => {
return (
<Box
borderRadius="md"
height="100%"
padding={{ base: 3, sm: '20px' }}
border="1px"
borderColor={ useColorModeValue('gray.200', 'gray.600') }
>
<Box
display={{ base: 'grid', sm: 'block' }}
gridTemplateColumns={{ base: '64px 1fr', sm: '1fr' }}
gridTemplateRows={{ base: '20px 20px auto', sm: 'none' }}
gridRowGap={{ base: 2, sm: 'none' }}
gridColumnGap={{ base: 4, sm: 'none' }}
height="100%"
>
<Box
gridRow={{ base: '1 / 4', sm: 'auto' }}
marginBottom={ 4 }
w={{ base: '64px', sm: '96px' }}
h={{ base: '64px', sm: '96px' }}
>
<SkeletonCircle w="100%" h="100%"/>
</Box>
<Heading
gridColumn={{ base: 2, sm: 'auto' }}
marginBottom={ 2 }
>
<Skeleton h={ 4 } w="50%"/>
</Heading>
<Box>
<Skeleton h={ 4 } mb={ 1 }/>
<Skeleton h={ 4 } mb={ 1 }/>
<Skeleton h={ 4 } w="50%"/>
</Box>
</Box>
</Box>
);
};
import { Grid, GridItem } from '@chakra-ui/react';
import React from 'react';
import { AppCardSkeleton } from 'ui/apps/AppCardSkeleton';
const applicationStubs = [ ...Array(12) ];
export const AppListSkeleton = () => {
return (
<Grid
templateColumns={{
sm: 'repeat(auto-fill, minmax(170px, 1fr))',
lg: 'repeat(auto-fill, minmax(260px, 1fr))',
}}
autoRows="1fr"
gap={{ base: '16px', sm: '24px' }}
>
{ applicationStubs.map((app, index) => (
<GridItem
key={ index }
>
<AppCardSkeleton/>
</GridItem>
)) }
</Grid>
);
};
......@@ -2,12 +2,12 @@ import {
Box, Button, Heading, Icon, IconButton, Image, Link, List, Modal, ModalBody,
ModalCloseButton, ModalContent, ModalFooter, ModalHeader, ModalOverlay, Tag, Text,
} from '@chakra-ui/react';
import type { FunctionComponent } from 'react';
import NextLink from 'next/link';
import React, { useCallback } from 'react';
import type { AppCategory, AppItemOverview } from 'types/client/apps';
import type { AppItemOverview, MarketplaceCategoryNames } from 'types/client/apps';
import { TEMPORARY_DEMO_APPS } from 'data/apps';
import marketplaceApps from 'data/marketplaceApps.json';
import linkIcon from 'icons/link.svg';
import ghIcon from 'icons/social/git.svg';
import tgIcon from 'icons/social/telega.svg';
......@@ -15,6 +15,10 @@ import twIcon from 'icons/social/tweet.svg';
import starFilledIcon from 'icons/star_filled.svg';
import starOutlineIcon from 'icons/star_outline.svg';
import { nbsp } from 'lib/html-entities';
import useLink from 'lib/link/useLink';
import notEmpty from 'lib/notEmpty';
import { APP_CATEGORIES } from './constants';
type Props = {
id: string;
......@@ -33,29 +37,30 @@ const AppModal = ({
title,
author,
description,
url,
site,
github,
telegram,
twitter,
logo,
categories,
} = TEMPORARY_DEMO_APPS.find(app => app.id === id) as AppItemOverview;
} = marketplaceApps.find(app => app.id === id) as AppItemOverview;
const link = useLink();
const socialLinks = [
Boolean(telegram) && {
telegram ? {
icon: tgIcon,
url: telegram,
},
Boolean(twitter) && {
} : null,
twitter ? {
icon: twIcon,
url: twitter,
},
Boolean(github) && {
} : null,
github ? {
icon: ghIcon,
url: github,
},
].filter(Boolean) as Array<{ icon: FunctionComponent; url: string }>;
} : null,
].filter(notEmpty);
const handleFavoriteClick = useCallback(() => {
onFavoriteClick(id, isFavorite);
......@@ -117,15 +122,16 @@ const AppModal = ({
marginTop={{ base: 6, sm: 0 }}
>
<Box display="flex">
<Button
href={ url }
as="a"
size="sm"
marginRight={ 2 }
width={{ base: '100%', sm: 'auto' }}
>
Launch app
</Button>
<NextLink href={ link('app_index', { id: id }) } passHref>
<Button
as="a"
size="sm"
marginRight={ 2 }
width={{ base: '100%', sm: 'auto' }}
>
Launch app
</Button>
</NextLink>
<IconButton
aria-label="Mark as favorite"
......@@ -155,14 +161,14 @@ const AppModal = ({
</Heading>
<Box marginBottom={ 2 }>
{ categories.map((category: AppCategory) => (
{ categories.map((category: keyof typeof MarketplaceCategoryNames) => APP_CATEGORIES[category] && (
<Tag
colorScheme="blue"
marginRight={ 2 }
marginBottom={ 2 }
key={ category.id }
key={ category }
>
{ category.name }
{ APP_CATEGORIES[category] }
</Tag>
)) }
</Box>
......
import type { AppCategory } from 'types/client/apps';
import type { MarketplaceCategoryNames } from 'types/client/apps';
export const APP_CATEGORIES: Array<AppCategory> = [
{
id: 'defi',
name: 'DeFi',
},
{
id: 'exchanges',
name: 'Exchanges',
},
{
id: 'finance',
name: 'Finance',
},
{
id: 'games',
name: 'Games',
},
{
id: 'marketplaces',
name: 'Marketplaces',
},
{
id: 'nft',
name: 'NFT',
},
{
id: 'security',
name: 'Security',
},
{
id: 'social',
name: 'Social',
},
{
id: 'tools',
name: 'Tools',
},
{
id: 'Yield-farming',
name: 'yield-farming',
},
];
export const APP_CATEGORIES: {[key in keyof typeof MarketplaceCategoryNames]: string} = {
defi: 'DeFi',
exchanges: 'Exchanges',
finance: 'Finance',
games: 'Games',
marketplaces: 'Marketplaces',
nft: 'NFT',
security: 'Security',
social: 'Social',
tools: 'Tools',
yieldFarming: 'Yield farming',
};
import { Center, useColorModeValue } from '@chakra-ui/react';
import React from 'react';
import Page from 'ui/shared/Page/Page';
const App = () => {
return (
<Page wrapChildren={ false }>
<Center as="main" bgColor={ useColorModeValue('blackAlpha.200', 'whiteAlpha.200') } h="100%" paddingTop={{ base: '138px', lg: 0 }}>
3rd party app content
</Center>
</Page>
);
};
export default App;
import { Icon, Link } from '@chakra-ui/react';
import debounce from 'lodash/debounce';
import React, { useCallback, useState } from 'react';
import React, { useCallback, useEffect, useState } from 'react';
import type { AppItemOverview } from 'types/client/apps';
import { TEMPORARY_DEMO_APPS } from 'data/apps';
import marketplaceApps from 'data/marketplaceApps.json';
import PlusIcon from 'icons/plus.svg';
import useNetwork from 'lib/hooks/useNetwork';
import AppList from 'ui/apps/AppList';
import FilterInput from 'ui/shared/FilterInput';
const defaultDisplayedApps = [ ...TEMPORARY_DEMO_APPS ]
.sort((a, b) => a.title.localeCompare(b.title));
import { AppListSkeleton } from '../apps/AppListSkeleton';
const Apps = () => {
const [ displayedApps, setDisplayedApps ] = useState<Array<AppItemOverview>>(defaultDisplayedApps);
const selectedNetwork = useNetwork();
const [ isLoading, setIsLoading ] = useState(true);
const [ defaultAppList, setDefaultAppList ] = useState<Array<AppItemOverview>>();
const [ displayedApps, setDisplayedApps ] = useState<Array<AppItemOverview>>([]);
const [ displayedAppId, setDisplayedAppId ] = useState<string | null>(null);
const showAppInfo = useCallback((id: string) => {
setDisplayedAppId(id);
}, []);
// eslint-disable-next-line react-hooks/exhaustive-deps
const debounceFilterApps = useCallback(debounce(q => filterApps(q), 500), []);
const clearDisplayedAppId = useCallback(() => setDisplayedAppId(null), []);
const filterApps = (q: string) => {
const apps = displayedApps
.filter(app => app.title.toLowerCase().includes(q.toLowerCase()));
function filterApps(q: string) {
const apps = defaultAppList
?.filter(app => app.title.toLowerCase().includes(q.toLowerCase()));
setDisplayedApps(apps);
};
setDisplayedApps(apps || []);
}
// eslint-disable-next-line react-hooks/exhaustive-deps
const debounceFilterApps = useCallback(debounce(q => filterApps(q), 500), []);
useEffect(() => {
if (!selectedNetwork) {
return;
}
const clearDisplayedAppId = useCallback(() => setDisplayedAppId(null), []);
const defaultDisplayedApps = [ ...marketplaceApps ]
.filter(item => item.chainId === selectedNetwork?.chainId)
.sort((a, b) => a.title.localeCompare(b.title));
setDefaultAppList(defaultDisplayedApps);
setDisplayedApps(defaultDisplayedApps);
setIsLoading(false);
}, [ selectedNetwork ]);
return (
<>
<FilterInput onChange={ debounceFilterApps } marginBottom={{ base: '4', lg: '6' }} placeholder="Find app"/>
<AppList
apps={ displayedApps }
onAppClick={ showAppInfo }
displayedAppId={ displayedAppId }
onModalClose={ clearDisplayedAppId }
/>
{ isLoading ? <AppListSkeleton/> : (
<AppList
apps={ displayedApps }
onAppClick={ showAppInfo }
displayedAppId={ displayedAppId }
onModalClose={ clearDisplayedAppId }
/>
) }
{ process.env.NEXT_PUBLIC_MARKETPLACE_SUBMIT_FORM && (
<Link
......
import { Box, Center, useColorMode } from '@chakra-ui/react';
import React, { useCallback, useEffect, useRef, useState } from 'react';
import type { AppItemOverview } from 'types/client/apps';
import useNetwork from 'lib/hooks/useNetwork';
import Page from 'ui/shared/Page/Page';
type Props = {
app?: AppItemOverview;
isLoading: boolean;
}
const MarketplaceApp = ({ app, isLoading }: Props) => {
const [ isFrameLoading, setIsFrameLoading ] = useState(isLoading);
const ref = useRef<HTMLIFrameElement>(null);
const { colorMode } = useColorMode();
const network = useNetwork();
const handleIframeLoad = useCallback(() => {
setIsFrameLoading(false);
}, []);
const sandboxAttributeValue = 'allow-forms allow-orientation-lock ' +
'allow-pointer-lock allow-popups-to-escape-sandbox ' +
'allow-same-origin allow-scripts ' +
'allow-top-navigation-by-user-activation';
useEffect(() => {
if (app) {
ref?.current?.contentWindow?.postMessage({ colorMode, chaindId: network?.chainId }, app.url);
}
}, [ app, colorMode, network, ref ]);
return (
<Page wrapChildren={ false }>
<Center
as="main"
h="100%"
paddingTop={{ base: '138px', lg: 0 }}
>
{ (isFrameLoading) && (
<Center
h="100%"
w="100%"
>
Loading...
</Center>
) }
{ app && (
<Box
ref={ ref }
sandbox={ sandboxAttributeValue }
as="iframe"
h="100%"
w="100%"
display={ isFrameLoading ? 'none' : 'block' }
src={ app.url }
title={ app.title }
onLoad={ handleIframeLoad }
/>
) }
</Center>
</Page>
);
};
export default MarketplaceApp;
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment