diff --git a/tools/walletextension/api/staticOG/MetaMaskIcon.png b/tools/walletextension/api/staticOG/MetaMaskIcon.png
new file mode 100644
index 0000000000..89f257be07
Binary files /dev/null and b/tools/walletextension/api/staticOG/MetaMaskIcon.png differ
diff --git a/tools/walletextension/api/staticOG/favicon-32x32.png b/tools/walletextension/api/staticOG/favicon-32x32.png
index e69de29bb2..ec512be020 100644
Binary files a/tools/walletextension/api/staticOG/favicon-32x32.png and b/tools/walletextension/api/staticOG/favicon-32x32.png differ
diff --git a/tools/walletextension/api/staticOG/index.html b/tools/walletextension/api/staticOG/index.html
index 06a749118a..cc506c17b1 100644
--- a/tools/walletextension/api/staticOG/index.html
+++ b/tools/walletextension/api/staticOG/index.html
@@ -14,13 +14,10 @@
◠. Obscuro Gateway Demo! ◠.
+
-
-
-
-
diff --git a/tools/walletextension/api/staticOG/javascript.js b/tools/walletextension/api/staticOG/javascript.js
index b04bddd6f3..3dfb6adda1 100644
--- a/tools/walletextension/api/staticOG/javascript.js
+++ b/tools/walletextension/api/staticOG/javascript.js
@@ -5,7 +5,9 @@ const idAddAccount = "addAccount";
const idAddAllAccounts = "addAllAccounts";
const idRevokeUserID = "revokeUserID";
const idStatus = "status";
-const obscuroGatewayVersion = "v1"
+const idAccountsTable = "accountsTable";
+const idTableBody = "tableBody";
+const obscuroGatewayVersion = "v1";
const pathJoin = obscuroGatewayVersion + "/join/";
const pathAuthenticate = obscuroGatewayVersion + "/authenticate/";
const pathQuery = obscuroGatewayVersion + "/query/";
@@ -20,6 +22,7 @@ const jsonHeaders = {
};
const metamaskPersonalSign = "personal_sign";
+const obscuroChainIDHex = "0x" + obscuroChainIDDecimal.toString(16); // Convert to hexadecimal and prefix with '0x'
function isValidUserIDFormat(value) {
return typeof value === 'string' && value.length === 64;
@@ -50,6 +53,19 @@ async function fetchAndDisplayVersion() {
}
}
+
+function getNetworkName(gatewayAddress) {
+ switch(gatewayAddress) {
+ case 'https://uat-testnet.obscu.ro/':
+ return 'Obscuro UAT-Testnet';
+ case 'https://dev-testnet.obscu.ro/':
+ return 'Obscuro Dev-Testnet';
+ default:
+ return 'Obscuro Testnet';
+ }
+}
+
+
function getRPCFromUrl(gatewayAddress) {
// get the correct RPC endpoint for each network
switch(gatewayAddress) {
@@ -68,14 +84,13 @@ function getRPCFromUrl(gatewayAddress) {
async function addNetworkToMetaMask(ethereum, userID, chainIDDecimal) {
// add network to MetaMask
- let chainIdHex = "0x" + chainIDDecimal.toString(16); // Convert to hexadecimal and prefix with '0x'
try {
await ethereum.request({
method: 'wallet_addEthereumChain',
params: [
{
- chainId: chainIdHex,
- chainName: 'Obscuro Testnet',
+ chainId: obscuroChainIDHex,
+ chainName: getNetworkName(obscuroGatewayAddress),
nativeCurrency: {
name: 'Sepolia Ether',
symbol: 'ETH',
@@ -95,7 +110,6 @@ async function addNetworkToMetaMask(ethereum, userID, chainIDDecimal) {
async function authenticateAccountWithObscuroGateway(ethereum, account, userID) {
const isAuthenticated = await accountIsAuthenticated(account, userID)
-
if (isAuthenticated) {
return "Account is already authenticated"
}
@@ -152,17 +166,20 @@ function getRandomIntAsString(min, max) {
return randomInt.toString();
}
-
async function getUserID() {
try {
- return await provider.send('eth_getStorageAt', ["getUserID", getRandomIntAsString(0, 1000), null])
+ if (await isObscuroChain()) {
+ return await provider.send('eth_getStorageAt', ["getUserID", getRandomIntAsString(0, 1000), null])
+ } else {
+ return null
+ }
}catch (e) {
console.log(e)
return null;
}
}
-async function connectAccount() {
+async function connectAccounts() {
try {
return await window.ethereum.request({ method: 'eth_requestAccounts' });
} catch (error) {
@@ -172,6 +189,18 @@ async function connectAccount() {
}
}
+async function isMetamaskConnected() {
+ let accounts;
+ try {
+ accounts = await provider.listAccounts()
+ return accounts.length > 0;
+
+ } catch (error) {
+ console.log("Unable to get accounts")
+ }
+ return false
+}
+
// Check if Metamask is available on mobile or as a plugin in browser
// (https://docs.metamask.io/wallet/how-to/integrate-with-mobile/)
function checkIfMetamaskIsLoaded() {
@@ -225,113 +254,125 @@ async function populateAccountsTable(document, tableBody, userID) {
}
}
+async function isObscuroChain() {
+ let currentChain = await ethereum.request({ method: 'eth_chainId' });
+ return currentChain === obscuroChainIDHex
+}
+
+async function switchToObscuroNetwork() {
+ try {
+ await ethereum.request({
+ method: 'wallet_switchEthereumChain',
+ params: [{ chainId: obscuroChainIDHex }],
+ });
+ return 0
+ } catch (switchError) {
+ return switchError.code
+ }
+ return -1
+}
+
const initialize = async () => {
const joinButton = document.getElementById(idJoin);
- const addAccountButton = document.getElementById(idAddAccount);
- const addAllAccountsButton = document.getElementById(idAddAllAccounts);
const revokeUserIDButton = document.getElementById(idRevokeUserID);
const statusArea = document.getElementById(idStatus);
- const accountsTable = document.getElementById('accountsTable')
- const tableBody = document.getElementById('tableBody');
+ const accountsTable = document.getElementById(idAccountsTable)
+ const tableBody = document.getElementById(idTableBody);
// getUserID from the gateway with getStorageAt method
let userID = await getUserID()
-
- // load the current version
- await fetchAndDisplayVersion();
-
- // check if userID exists and has a correct type and length (is valid) and display either
- // option to join or to add a new account to existing user
- if (isValidUserIDFormat(userID)) {
- joinButton.style.display = "none"
- addAccountButton.style.display = "block"
- addAllAccountsButton.style.display = "block"
- revokeUserIDButton.style.display = "block"
- accountsTable.style.display = "block"
- await populateAccountsTable(document, tableBody, userID)
- } else {
+ function displayOnlyJoin() {
joinButton.style.display = "block"
- addAccountButton.style.display = "none"
revokeUserIDButton.style.display = "none"
accountsTable.style.display = "none"
}
- joinButton.addEventListener(eventClick, async () => {
- // join Obscuro Gateway
- const joinResp = await fetch(
- pathJoin, {
- method: methodGet,
- headers: jsonHeaders,
- }
- );
- if (!joinResp.ok) {
- statusArea.innerText = "Failed to join. \nError: " + joinResp
- return
- }
-
- // save userID to the localStorage and hide button that enables users to join
- userID = await joinResp.text();
+ async function displayConnectedAndJoinedSuccessfully() {
joinButton.style.display = "none"
-
- // add Obscuro network to Metamask
- let networkAdded = await addNetworkToMetaMask(ethereum, userID, obscuroChainIDDecimal)
- if (!networkAdded) {
- statusArea.innerText = "Failed to add network"
- return
- }
- statusArea.innerText = "Successfully joined Obscuro Gateway";
- // show users an option to add another account and revoke userID
- addAccountButton.style.display = "block"
- addAllAccountsButton.style.display = "block"
revokeUserIDButton.style.display = "block"
accountsTable.style.display = "block"
await populateAccountsTable(document, tableBody, userID)
- })
+ }
- addAccountButton.addEventListener(eventClick, async () => {
- // check if we have userID and it is the correct length
- if (!isValidUserIDFormat(userID)) {
- statusArea.innerText = "\n Please join Obscuro network first"
- joinButton.style.display = "block"
- addAccountButton.style.display = "none"
+ async function displayCorrectScreenBasedOnMetamaskAndUserID() {
+ // check if we are on Obscuro Chain
+ if(await isObscuroChain()){
+ // check if we have valid userID in rpcURL
+ if (isValidUserIDFormat(userID)) {
+ return await displayConnectedAndJoinedSuccessfully()
+ }
}
+ return displayOnlyJoin()
+ }
- await connectAccount()
+ // load the current version
+ await fetchAndDisplayVersion();
- // Get an account and prompt user to sign joining with a selected account
- const account = await provider.getSigner().getAddress();
- if (account.length === 0) {
- statusArea.innerText = "No MetaMask accounts found."
- return
- }
- let authenticateAccountStatus = await authenticateAccountWithObscuroGateway(ethereum, account, userID)
- //statusArea.innerText = "\n Authentication status: " + authenticateAccountStatus
- accountsTable.style.display = "block"
- await populateAccountsTable(document, tableBody, userID)
- })
+ await displayCorrectScreenBasedOnMetamaskAndUserID()
- addAllAccountsButton.addEventListener(eventClick, async () => {
- // check if we have userID and it is the correct length
- if (!isValidUserIDFormat(userID)) {
- statusArea.innerText = "\n Please join Obscuro network first"
- joinButton.style.display = "block"
- addAccountButton.style.display = "none"
- }
+ joinButton.addEventListener(eventClick, async () => {
+ // check if we are on an obscuro chain
+ if (await isObscuroChain()) {
+ userID = await getUserID()
+ if (!isValidUserIDFormat(userID)) {
+ statusArea.innerText = "Please remove existing Obscuro network from metamask and start again."
+ }
+ } else {
+ // we are not on an Obscuro network - try to switch
+ let switched = await switchToObscuroNetwork();
+ // error 4902 means that the chain does not exist
+ if (switched === 4902 || !isValidUserIDFormat(await getUserID())) {
+ // join the network
+ const joinResp = await fetch(
+ pathJoin, {
+ method: methodGet,
+ headers: jsonHeaders,
+ });
+ if (!joinResp.ok) {
+ console.log("Error joining Obscuro Gateway")
+ statusArea.innerText = "Error joining Obscuro Gateway. Please try again later."
+ return
+ }
+ userID = await joinResp.text();
+
+ // add Obscuro network
+ await addNetworkToMetaMask(window.ethereum, userID)
+ }
- await connectAccount()
+ // we have to check if user has accounts connected with metamask - and promt to connect if not
+ if (!await isMetamaskConnected()) {
+ await connectAccounts();
+ }
- // Get an account and prompt user to sign joining with selected account
- const accounts = await provider.listAccounts();
- if (accounts.length === 0) {
- statusArea.innerText = "No MetaMask accounts found."
- return
- }
+ // connect all accounts
+ // Get an accounts and prompt user to sign joining with a selected account
+ const accounts = await provider.listAccounts();
+ if (accounts.length === 0) {
+ statusArea.innerText = "No MetaMask accounts found."
+ return
+ }
+
+ userID = await getUserID();
+ for (const account of accounts) {
+ await authenticateAccountWithObscuroGateway(ethereum, account, userID)
+ accountsTable.style.display = "block"
+ await populateAccountsTable(document, tableBody, userID)
+ }
- for (const account of accounts) {
- let authenticateAccountStatus = await authenticateAccountWithObscuroGateway(ethereum, account, userID)
- accountsTable.style.display = "block"
- await populateAccountsTable(document, tableBody, userID)
+ // if accounts change we want to give user chance to add them to Obscuro
+ window.ethereum.on('accountsChanged', async function (accounts) {
+ if (isValidUserIDFormat(await getUserID())) {
+ userID = await getUserID();
+ for (const account of accounts) {
+ await authenticateAccountWithObscuroGateway(ethereum, account, userID)
+ accountsTable.style.display = "block"
+ await populateAccountsTable(document, tableBody, userID)
+ }
+ }
+ });
+
+ await displayConnectedAndJoinedSuccessfully()
}
})
@@ -341,17 +382,11 @@ const initialize = async () => {
await populateAccountsTable(document, tableBody, userID)
if (result) {
- joinButton.style.display = "block";
- revokeUserIDButton.style.display = "none";
- addAllAccountsButton.style.display = "none";
- statusArea.innerText = "Revoking UserID successful. Please remove current network from Metamask."
- addAccountButton.style.display = "none";
- accountsTable.style.display = "none"
+ displayOnlyJoin()
} else {
statusArea.innerText = "Revoking UserID failed";
}
})
-
}
window.addEventListener(eventDomLoaded, checkIfMetamaskIsLoaded);