Skip to content

Commit

Permalink
Add web3 (#27)
Browse files Browse the repository at this point in the history
* Working web3 hook

* Create test

* Move chains to a separate file

* fix test

* Centralised web3 functionality

* Update readme

---------

Co-authored-by: Elliot Braem <[email protected]>
  • Loading branch information
bb-face and elliotBraem authored Jul 2, 2024
1 parent d3ab5ec commit 9608b0a
Show file tree
Hide file tree
Showing 7 changed files with 2,614 additions and 27 deletions.
10 changes: 10 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -135,6 +135,16 @@ By setting the session storage key `nearSocialVMredirectMap` to the JSON value o

You can also use the same mechanism as [near-discovery](https://github.com/near/near-discovery/) where you can load components from a locally hosted [bos-loader](https://github.com/near/bos-loader) by adding the key `flags` to localStorage with the value `{"bosLoaderUrl": "http://127.0.0.1:3030" }`.

## Configuring Ethers

Since [NearSocial/VM v1.3.0](https://github.com/NearSocial/VM/blob/master/CHANGELOG.md#130), the VM has exposed Ethers and ethers in the global scope, as well as a Web3Connect custom element for bringing up wallet connect.

There already exists support for most common EVM chains, but to add a new chain to your web3 provider, find your chain on [ChainList](https://chainlist.org/) and then add the necessary details to the [chains.json](./src/utils/web4/chains.json). Be sure to include a testnet configuration as well. This will enable you to connect to the specified chain when using `<Web3Connect />` within a widget running inside your custom web component.

You can configure the projectId and appMetadata in [ethersProvider.js](./src/utils/web4/ethersProvider.js) as well.

For more information on how to utilize [Ethers.js](https://docs.ethers.org/v6/) in your widgets, see [NEAR for Ethereum developers](https://docs.near.org/tutorials/near-components/ethers-js). To see a list of existing EVM components built by the community, see [here](https://near.social/hackerhouse.near/widget/EVMComponents).

## Landing page for SEO friendly URLs

Normally, the URL path decides which component to be loaded. The path `/devhub.near/widget/app` will load the `app` component from the `devhub.near` account. DevHub is an example of a collection of many components that are part of a big app, and the `app` component is just a proxy to components that represent a `page`. Which page to display is controlled by the `page` query string parameter, which translates to `props.page` in the component.
Expand Down
4 changes: 4 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,10 @@
"dependencies": {
"@braintree/sanitize-url": "^6.0.2",
"@playwright/test": "^1.38.1",
"@web3-onboard/injected-wallets": "^2.11.1",
"@web3-onboard/ledger": "^2.7.1",
"@web3-onboard/react": "^2.9.1",
"@web3-onboard/walletconnect": "^2.6.1",
"big.js": "^6.1.1",
"bn.js": "^5.1.1",
"bootstrap": "^5.3.1",
Expand Down
29 changes: 29 additions & 0 deletions playwright-tests/tests/web3.spec.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
import { expect, test } from "@playwright/test";

import { waitForSelectorToBeVisible } from "../testUtils";

test("should be possible to interact with web3 widgets", async ({ page }) => {
await page.goto("/");

await page.evaluate(() => {
document.body.innerHTML = `
<near-social-viewer src="zavodil.near/widget/Lido"></near-social-viewer>
`;
});

await waitForSelectorToBeVisible(
page,
'near-social-viewer[src="zavodil.near/widget/Lido"]'
);

await waitForSelectorToBeVisible(
page,
"body > near-social-viewer > div > div > div > div.LidoStakeForm"
);

const Web3ConnectButton = await page.getByRole("button", { name: "Connect with Web3" });

await Web3ConnectButton.click();

await expect(await page.getByRole("button", { name: "Connecting"})).toBeVisible();
});
19 changes: 15 additions & 4 deletions src/App.js
Original file line number Diff line number Diff line change
@@ -1,20 +1,25 @@
import "App.scss";
import "bootstrap-icons/font/bootstrap-icons.css";
import "bootstrap/dist/js/bootstrap.bundle";
import { Widget } from "near-social-vm";
import React, { useEffect, useMemo, useState } from "react";
import "react-bootstrap-typeahead/css/Typeahead.css";

import { sanitizeUrl } from "@braintree/sanitize-url";
import { useAccount, useInitNear } from "near-social-vm";
import {
useAccount,
useInitNear,
Widget,
} from "near-social-vm";
import {
createBrowserRouter,
Link,
RouterProvider,
useLocation,
} from "react-router-dom";

const SESSION_STORAGE_REDIRECT_MAP_KEY = 'nearSocialVMredirectMap';
import { EthersProvider } from "./utils/web3/ethersProvider"

const SESSION_STORAGE_REDIRECT_MAP_KEY = "nearSocialVMredirectMap";

function Viewer({ widgetSrc, code, initialProps }) {
const location = useLocation();
Expand Down Expand Up @@ -105,7 +110,13 @@ function App(props) {
{
path: "/*",
element: (
<Viewer widgetSrc={src} code={code} initialProps={initialProps} />
<EthersProvider>
<Viewer
widgetSrc={src}
code={code}
initialProps={initialProps}
/>
</EthersProvider>
),
},
]);
Expand Down
206 changes: 206 additions & 0 deletions src/utils/web3/chains.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,206 @@
[
{
"id": 1,
"token": "ETH",
"label": "Ethereum Mainnet",
"rpcUrl": "https://rpc.ankr.com/eth"
},
{
"id": 3,
"token": "ETH",
"label": "Ropsten - Ethereum Testnet",
"rpcUrl": "https://rpc.ankr.com/eth_ropsten"
},
{
"id": 5,
"token": "ETH",
"label": "Goerli - Ethereum Testnet",
"rpcUrl": "https://rpc.ankr.com/eth_goerli"
},
{
"id": 10,
"token": "ETH",
"label": "Optimism",
"rpcUrl": "https://rpc.ankr.com/optimism"
},
{
"id": 420,
"token": "ETH",
"label": "Optimism Goerli Testnet",
"rpcUrl": "https://optimism-goerli.publicnode.com"
},
{
"id": 56,
"token": "BNB",
"label": "Binance Smart Chain Mainnet",
"rpcUrl": "https://bsc.publicnode.com"
},
{
"id": 97,
"token": "tBNB",
"label": "Binance Smart Chain Testnet",
"rpcUrl": "https://bsc-testnet.publicnode.com"
},
{
"id": 1313161554,
"token": "ETH",
"label": "Aurora Mainnet",
"rpcUrl": "https://mainnet.aurora.dev"
},
{
"id": 1313161555,
"token": "ETH",
"label": "Aurora Testnet",
"rpcUrl": "https://testnet.aurora.dev"
},
{
"id": 137,
"token": "MATIC",
"label": "Polygon Mainnet",
"rpcUrl": "https://rpc.ankr.com/polygon"
},
{
"id": 80001,
"token": "MATIC",
"label": "Polygon Testnet Mumbai",
"rpcUrl": "https://rpc.ankr.com/polygon_mumbai"
},
{
"id": 280,
"token": "ETH",
"label": "zkSync Era Testnet",
"rpcUrl": "https://testnet.era.zksync.dev"
},
{
"id": 324,
"token": "ETH",
"label": "zkSync Era Mainnet",
"rpcUrl": "https://zksync2-mainnet.zksync.io"
},
{
"id": 1101,
"token": "ETH",
"label": "Polygon zkEVM",
"rpcUrl": "https://zkevm-rpc.com"
},
{
"id": 1442,
"token": "ETH",
"label": "Polygon zkEVM Testnet",
"rpcUrl": "https://rpc.public.zkevm-test.net"
},
{
"id": 42161,
"token": "ETH",
"label": "Arbitrum One Mainnet",
"rpcUrl": "https://arb1.arbitrum.io/rpc"
},
{
"id": 42170,
"token": "ETH",
"label": "Arbitrum Nova",
"rpcUrl": "https://nova.arbitrum.io/rpc"
},
{
"id": 421613,
"token": "AGOR",
"label": "Arbitrum Goerli",
"rpcUrl": "https://goerli-rollup.arbitrum.io/rpc"
},
{
"id": 25,
"token": "CRO",
"label": "Cronos Mainnet Beta",
"rpcUrl": "https://evm.cronos.org"
},
{
"id": 338,
"token": "TCRO",
"label": "Cronos Testnet",
"rpcUrl": "https://evm-t3.cronos.org"
},
{
"id": 100,
"token": "XDAI",
"label": "Gnosis",
"rpcUrl": "https://rpc.ankr.com/gnosis"
},
{
"id": 10200,
"token": "XDAI",
"label": "Gnosis Chiado Testnet",
"rpcUrl": "https://rpc.chiadochain.net"
},
{
"id": 42220,
"token": "CELO",
"label": "Celo Mainnet",
"rpcUrl": "https://rpc.ankr.com/celo"
},
{
"id": 44787,
"token": "CELO",
"label": "Celo Alfajores Testnet",
"rpcUrl": "https://alfajores-forno.celo-testnet.org"
},
{
"id": 43114,
"token": "AVAX",
"label": "Avalanche C-Chain",
"rpcUrl": "https://rpc.ankr.com/avalanche"
},
{
"id": 43113,
"token": "AVAX",
"label": "Avalanche Fuji Testnet",
"rpcUrl": "https://rpc.ankr.com/avalanche_fuji"
},
{
"id": 250,
"token": "FTM",
"label": "Fantom Opera",
"rpcUrl": "https://rpc.ankr.com/fantom"
},
{
"id": 4002,
"token": "FTM",
"label": "Fantom Testnet",
"rpcUrl": "https://rpc.ankr.com/fantom_testnet"
},
{
"id": 1284,
"token": "GLMR",
"label": "Moonbeam",
"rpcUrl": "https://rpc.ankr.com/moonbeam"
},
{
"id": 61,
"token": "ETC",
"label": "Ethereum Classic Mainnet",
"rpcUrl": "https://etc.rivet.link"
},
{
"id": 84531,
"token": "ETH",
"label": "Base Goerli Testnet",
"rpcUrl": "https://goerli.base.org"
},
{
"id": 8453,
"token": "ETH",
"label": "Base",
"rpcUrl": "https://mainnet.base.org"
},
{
"id": 5001,
"token": "MNT",
"label": "Mantle Testnet",
"rpcUrl": "https://rpc.testnet.mantle.xyz"
},
{
"id": 5000,
"token": "MNT",
"label": "Mantle",
"rpcUrl": "https://rpc.mantle.xyz"
}
]
Loading

0 comments on commit 9608b0a

Please sign in to comment.