Login is now possible
This commit is contained in:
parent
cc442b3a2e
commit
a812a42bde
|
@ -2,6 +2,9 @@
|
||||||
* Copyright (C) 2024 Jon Michael Aanes
|
* Copyright (C) 2024 Jon Michael Aanes
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
import {
|
||||||
|
setupWalletWidget,
|
||||||
|
} from "../token/WalletIntegration";
|
||||||
import BN from "bn.js";
|
import BN from "bn.js";
|
||||||
import { LittleEndianByteInput } from "@secata-public/bitmanipulation-ts";
|
import { LittleEndianByteInput } from "@secata-public/bitmanipulation-ts";
|
||||||
import { BlockchainAddress, StateBytes } from "@partisiablockchain/abi-client";
|
import { BlockchainAddress, StateBytes } from "@partisiablockchain/abi-client";
|
||||||
|
@ -217,6 +220,10 @@ async function get_token_state(tokenAddress: BlockchainAddress): Promise<TokenSt
|
||||||
}
|
}
|
||||||
|
|
||||||
function setup() {
|
function setup() {
|
||||||
|
// Setup wallet widget
|
||||||
|
setupWalletWidget();
|
||||||
|
|
||||||
|
// Setup routes
|
||||||
for (let router of ROUTERS) {
|
for (let router of ROUTERS) {
|
||||||
console.log(router);
|
console.log(router);
|
||||||
get_contract_state(router, deserializeRouterState).then((state) => {
|
get_contract_state(router, deserializeRouterState).then((state) => {
|
||||||
|
|
|
@ -21,7 +21,6 @@ import { ContractAbi, BlockchainAddress } from "@partisiablockchain/abi-client";
|
||||||
import { ShardedClient } from "../client/ShardedClient";
|
import { ShardedClient } from "../client/ShardedClient";
|
||||||
import { TokenContract } from "../shared/TokenContract";
|
import { TokenContract } from "../shared/TokenContract";
|
||||||
import { TransactionApi } from "../client/TransactionApi";
|
import { TransactionApi } from "../client/TransactionApi";
|
||||||
import { updateContractState } from "./WalletIntegration";
|
|
||||||
import { NETWORK } from "../constant";
|
import { NETWORK } from "../constant";
|
||||||
|
|
||||||
export const CLIENT = new ShardedClient(NETWORK.node_base_url, NETWORK.network_shards);
|
export const CLIENT = new ShardedClient(NETWORK.node_base_url, NETWORK.network_shards);
|
||||||
|
@ -33,7 +32,6 @@ type TokenContractCreator = (
|
||||||
|
|
||||||
let lastBalanceKey: string | undefined;
|
let lastBalanceKey: string | undefined;
|
||||||
let contractAddress: BlockchainAddress | undefined;
|
let contractAddress: BlockchainAddress | undefined;
|
||||||
let currentAccount: ConnectedWallet | undefined;
|
|
||||||
let contractAbi: ContractAbi | undefined;
|
let contractAbi: ContractAbi | undefined;
|
||||||
let tokenApi: TokenContract | undefined;
|
let tokenApi: TokenContract | undefined;
|
||||||
|
|
||||||
|
@ -47,19 +45,6 @@ export function setTokenContractType(creator: TokenContractCreator) {
|
||||||
tokenContractCreator = creator;
|
tokenContractCreator = creator;
|
||||||
}
|
}
|
||||||
|
|
||||||
export const setAccount = (account: ConnectedWallet | undefined) => {
|
|
||||||
currentAccount = account;
|
|
||||||
setTokenApi();
|
|
||||||
};
|
|
||||||
|
|
||||||
export const resetAccount = () => {
|
|
||||||
currentAccount = undefined;
|
|
||||||
};
|
|
||||||
|
|
||||||
export const isConnected = () => {
|
|
||||||
return currentAccount != null;
|
|
||||||
};
|
|
||||||
|
|
||||||
export const setContractAbi = (abi: ContractAbi) => {
|
export const setContractAbi = (abi: ContractAbi) => {
|
||||||
contractAbi = abi;
|
contractAbi = abi;
|
||||||
setTokenApi();
|
setTokenApi();
|
||||||
|
@ -71,9 +56,6 @@ export const getContractAbi = () => {
|
||||||
|
|
||||||
const setTokenApi = () => {
|
const setTokenApi = () => {
|
||||||
let transactionApi = undefined;
|
let transactionApi = undefined;
|
||||||
if (currentAccount != undefined) {
|
|
||||||
transactionApi = new TransactionApi(CLIENT, currentAccount, updateContractState);
|
|
||||||
}
|
|
||||||
tokenApi = tokenContractCreator(CLIENT, transactionApi);
|
tokenApi = tokenContractCreator(CLIENT, transactionApi);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -20,19 +20,10 @@ import {
|
||||||
setTokenContractType,
|
setTokenContractType,
|
||||||
getTokenApi,
|
getTokenApi,
|
||||||
getContractAddress,
|
getContractAddress,
|
||||||
isConnected,
|
|
||||||
setContractAddress,
|
setContractAddress,
|
||||||
} from "./AppState";
|
} from "./AppState";
|
||||||
import {
|
import {
|
||||||
connectMetaMaskWalletClick,
|
setupWalletWidget,
|
||||||
connectMpcWalletClick,
|
|
||||||
connectLedgerWalletClick,
|
|
||||||
connectPrivateKeyWalletClick,
|
|
||||||
validateLedgerConnectionClick,
|
|
||||||
disconnectWalletClick,
|
|
||||||
fetchAndDisplayMoreBalances,
|
|
||||||
updateContractState,
|
|
||||||
updateInteractionVisibility,
|
|
||||||
} from "./WalletIntegration";
|
} from "./WalletIntegration";
|
||||||
import { TokenV1Contract } from "./contract/TokenV1Contract";
|
import { TokenV1Contract } from "./contract/TokenV1Contract";
|
||||||
import { TokenV2Contract } from "./contract/TokenV2Contract";
|
import { TokenV2Contract } from "./contract/TokenV2Contract";
|
||||||
|
@ -43,28 +34,8 @@ import { TransactionFailedError } from "../client/TransactionApi";
|
||||||
import { PutTransactionWasSuccessful } from "../client/TransactionData";
|
import { PutTransactionWasSuccessful } from "../client/TransactionData";
|
||||||
import { NETWORK } from "../constant";
|
import { NETWORK } from "../constant";
|
||||||
|
|
||||||
// Setup event listener to connect to the MPC wallet browser extension
|
// Setup wallet widget
|
||||||
const connectWallet = <Element>document.querySelector("#wallet-connect-btn");
|
setupWalletWidget();
|
||||||
connectWallet.addEventListener("click", connectMpcWalletClick);
|
|
||||||
|
|
||||||
// Setup event listener to connect to the MetaMask snap
|
|
||||||
const metaMaskConnect = <Element>document.querySelector("#metamask-connect-btn");
|
|
||||||
metaMaskConnect.addEventListener("click", connectMetaMaskWalletClick);
|
|
||||||
|
|
||||||
// Setup event listener to connect to the ledger snap
|
|
||||||
const ledgerConnect = <Element>document.querySelector("#ledger-connect-btn");
|
|
||||||
ledgerConnect.addEventListener("click", connectLedgerWalletClick);
|
|
||||||
|
|
||||||
const ledgerConnectValidate = <Element>document.querySelector("#connection-link-ledger-validate");
|
|
||||||
ledgerConnectValidate.addEventListener("click", validateLedgerConnectionClick);
|
|
||||||
|
|
||||||
// Setup event listener to login using private key
|
|
||||||
const pkConnect = <Element>document.querySelector("#private-key-connect-btn");
|
|
||||||
pkConnect.addEventListener("click", connectPrivateKeyWalletClick);
|
|
||||||
|
|
||||||
// Setup event listener to drop the connection again
|
|
||||||
const disconnectWallet = <Element>document.querySelector("#wallet-disconnect-btn");
|
|
||||||
disconnectWallet.addEventListener("click", disconnectWalletClick);
|
|
||||||
|
|
||||||
// Setup event listener that sends a transfer transaction to the contract.
|
// Setup event listener that sends a transfer transaction to the contract.
|
||||||
// This requires that a wallet has been connected.
|
// This requires that a wallet has been connected.
|
||||||
|
@ -75,15 +46,9 @@ transferBtn.addEventListener("click", transferAction);
|
||||||
const addressBtn = <Element>document.querySelector("#address-btn");
|
const addressBtn = <Element>document.querySelector("#address-btn");
|
||||||
addressBtn.addEventListener("click", contractAddressClick);
|
addressBtn.addEventListener("click", contractAddressClick);
|
||||||
|
|
||||||
const updateStateBtn = <Element>document.querySelector("#update-state-btn");
|
|
||||||
updateStateBtn.addEventListener("click", updateContractState);
|
|
||||||
|
|
||||||
const getBalanceBtn = <Element>document.querySelector("#get-balance-btn");
|
const getBalanceBtn = <Element>document.querySelector("#get-balance-btn");
|
||||||
getBalanceBtn.addEventListener("click", getBalance);
|
getBalanceBtn.addEventListener("click", getBalance);
|
||||||
|
|
||||||
const loadMoreBtn = <Element>document.querySelector("#balances-load-more-btn");
|
|
||||||
loadMoreBtn.addEventListener("click", fetchAndDisplayMoreBalances);
|
|
||||||
|
|
||||||
function setModeText(modeText: string) {
|
function setModeText(modeText: string) {
|
||||||
let items = document.querySelectorAll("title");
|
let items = document.querySelectorAll("title");
|
||||||
items.forEach((item) => {
|
items.forEach((item) => {
|
||||||
|
@ -125,8 +90,6 @@ function setContractAddressUI(address: BlockchainAddress) {
|
||||||
currentAddress.href = `${NETWORK.browser_base_url}/contracts/${address.asString()}`;
|
currentAddress.href = `${NETWORK.browser_base_url}/contracts/${address.asString()}`;
|
||||||
inputAddress.value = address.asString();
|
inputAddress.value = address.asString();
|
||||||
setContractAddress(address);
|
setContractAddress(address);
|
||||||
updateInteractionVisibility();
|
|
||||||
updateContractState();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Function for the contract address form.
|
/** Function for the contract address form.
|
||||||
|
@ -159,23 +122,13 @@ function setTransactionLink(transaction: PutTransactionWasSuccessful) {
|
||||||
function transferAction() {
|
function transferAction() {
|
||||||
const api = getTokenApi();
|
const api = getTokenApi();
|
||||||
const contractAddress = getContractAddress();
|
const contractAddress = getContractAddress();
|
||||||
if (isConnected() && api !== undefined && contractAddress !== undefined) {
|
if (false && api !== undefined && contractAddress !== undefined) {
|
||||||
const to = <HTMLInputElement>document.querySelector("#address-to");
|
const to = <HTMLInputElement>document.querySelector("#address-to");
|
||||||
const amount = <HTMLInputElement>document.querySelector("#amount");
|
const amount = <HTMLInputElement>document.querySelector("#amount");
|
||||||
const memo = <HTMLInputElement>document.querySelector("#memo");
|
const memo = <HTMLInputElement>document.querySelector("#memo");
|
||||||
|
|
||||||
transactionErrorMessage.innerHTML = '<div class="loader"></div>';
|
transactionErrorMessage.innerHTML = '<div class="loader"></div>';
|
||||||
transactionLinkElement.innerText = "";
|
transactionLinkElement.innerText = "";
|
||||||
api
|
|
||||||
.transfer(contractAddress, BlockchainAddress.fromString(to.value), new BN(amount.value, 10), memo.value)
|
|
||||||
.then(setTransactionLink)
|
|
||||||
.catch((error) => {
|
|
||||||
console.error(error);
|
|
||||||
if (error instanceof TransactionFailedError) {
|
|
||||||
setTransactionLink(error.putTransaction);
|
|
||||||
}
|
|
||||||
transactionErrorMessage.innerText = error;
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -16,15 +16,6 @@
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import {
|
|
||||||
resetAccount,
|
|
||||||
setAccount,
|
|
||||||
getContractAddress,
|
|
||||||
isConnected,
|
|
||||||
getContractLastBalanceKey,
|
|
||||||
setContractLastBalanceKey,
|
|
||||||
getTokenApi,
|
|
||||||
} from "./AppState";
|
|
||||||
import { ConnectedWallet } from "../shared/ConnectedWallet";
|
import { ConnectedWallet } from "../shared/ConnectedWallet";
|
||||||
import { connectMetaMask } from "../shared/MetaMaskIntegration";
|
import { connectMetaMask } from "../shared/MetaMaskIntegration";
|
||||||
import { connectMpcWallet } from "../shared/MpcWalletIntegration";
|
import { connectMpcWallet } from "../shared/MpcWalletIntegration";
|
||||||
|
@ -32,6 +23,8 @@ import { connectLedger, validateLedgerConnection } from "../shared/LedgerIntegra
|
||||||
import { connectPrivateKey } from "../shared/PrivateKeyIntegration";
|
import { connectPrivateKey } from "../shared/PrivateKeyIntegration";
|
||||||
import { CryptoUtils } from "../client/CryptoUtils";
|
import { CryptoUtils } from "../client/CryptoUtils";
|
||||||
|
|
||||||
|
let CURRENT_ACCOUNT: ConnectedWallet | undefined;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Function for connecting to the MPC wallet and setting the connected wallet in the app state.
|
* Function for connecting to the MPC wallet and setting the connected wallet in the app state.
|
||||||
*/
|
*/
|
||||||
|
@ -78,11 +71,11 @@ export const connectPrivateKeyWalletClick = () => {
|
||||||
*/
|
*/
|
||||||
const handleWalletConnect = (connect: Promise<ConnectedWallet>) => {
|
const handleWalletConnect = (connect: Promise<ConnectedWallet>) => {
|
||||||
// Clean up state
|
// Clean up state
|
||||||
resetAccount();
|
CURRENT_ACCOUNT = undefined;
|
||||||
setConnectionStatus("Connecting...");
|
setConnectionStatus("Connecting...");
|
||||||
connect
|
connect
|
||||||
.then((userAccount) => {
|
.then((userAccount) => {
|
||||||
setAccount(userAccount);
|
CURRENT_ACCOUNT = userAccount;
|
||||||
|
|
||||||
// Fix UI
|
// Fix UI
|
||||||
setConnectionStatus("Logged in: ", userAccount.address);
|
setConnectionStatus("Logged in: ", userAccount.address);
|
||||||
|
@ -91,7 +84,6 @@ const handleWalletConnect = (connect: Promise<ConnectedWallet>) => {
|
||||||
setVisibility("#ledger-connect", false);
|
setVisibility("#ledger-connect", false);
|
||||||
setVisibility("#private-key-connect", false);
|
setVisibility("#private-key-connect", false);
|
||||||
setVisibility("#wallet-disconnect", true);
|
setVisibility("#wallet-disconnect", true);
|
||||||
updateInteractionVisibility();
|
|
||||||
})
|
})
|
||||||
.catch((error) => {
|
.catch((error) => {
|
||||||
console.error(error);
|
console.error(error);
|
||||||
|
@ -107,7 +99,7 @@ const handleWalletConnect = (connect: Promise<ConnectedWallet>) => {
|
||||||
* Reset state to disconnect current user.
|
* Reset state to disconnect current user.
|
||||||
*/
|
*/
|
||||||
export const disconnectWalletClick = () => {
|
export const disconnectWalletClick = () => {
|
||||||
resetAccount();
|
CURRENT_ACCOUNT = undefined;
|
||||||
setConnectionStatus("Disconnected account");
|
setConnectionStatus("Disconnected account");
|
||||||
setVisibility("#wallet-connect", true);
|
setVisibility("#wallet-connect", true);
|
||||||
setVisibility("#metamask-connect", true);
|
setVisibility("#metamask-connect", true);
|
||||||
|
@ -115,58 +107,6 @@ export const disconnectWalletClick = () => {
|
||||||
setVisibility("#private-key-connect", true);
|
setVisibility("#private-key-connect", true);
|
||||||
setVisibility("#wallet-disconnect", false);
|
setVisibility("#wallet-disconnect", false);
|
||||||
setVisibility("#connection-link-ledger-validate", false);
|
setVisibility("#connection-link-ledger-validate", false);
|
||||||
updateInteractionVisibility();
|
|
||||||
};
|
|
||||||
|
|
||||||
const ALL_BALANCES_LIST = <HTMLElement>document.querySelector("#all-balances");
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Write some of the state to the UI.
|
|
||||||
*/
|
|
||||||
export const updateContractState = () => {
|
|
||||||
const address = getContractAddress();
|
|
||||||
if (address === undefined) {
|
|
||||||
throw new Error("No address provided");
|
|
||||||
}
|
|
||||||
const tokenApi = getTokenApi();
|
|
||||||
if (tokenApi === undefined) {
|
|
||||||
throw new Error("Token API not setup");
|
|
||||||
}
|
|
||||||
|
|
||||||
const refreshLoader = <HTMLInputElement>document.querySelector("#refresh-loader");
|
|
||||||
refreshLoader.classList.remove("hidden");
|
|
||||||
|
|
||||||
if (tokenApi.basicState != undefined) {
|
|
||||||
tokenApi.basicState(address).then((state) => {
|
|
||||||
const stateHeader = <HTMLInputElement>document.querySelector("#state-header");
|
|
||||||
const updateStateButton = <HTMLInputElement>document.querySelector("#update-state");
|
|
||||||
stateHeader.classList.remove("hidden");
|
|
||||||
updateStateButton.classList.remove("hidden");
|
|
||||||
|
|
||||||
const name = <HTMLElement>document.querySelector("#name");
|
|
||||||
name.innerHTML = `${state.name}`;
|
|
||||||
|
|
||||||
const decimals = <HTMLElement>document.querySelector("#decimals");
|
|
||||||
decimals.innerHTML = `${state.decimals}`;
|
|
||||||
|
|
||||||
const symbol = <HTMLElement>document.querySelector("#symbol");
|
|
||||||
symbol.innerHTML = `${state.symbol}`;
|
|
||||||
|
|
||||||
const owner = <HTMLElement>document.querySelector("#owner");
|
|
||||||
owner.innerHTML = `${state.owner.asString()}`;
|
|
||||||
|
|
||||||
const totalSupply = <HTMLElement>document.querySelector("#total-supply");
|
|
||||||
totalSupply.innerHTML = `${state.totalSupply}`;
|
|
||||||
|
|
||||||
const contractState = <HTMLElement>document.querySelector("#contract-state");
|
|
||||||
contractState.classList.remove("hidden");
|
|
||||||
refreshLoader.classList.add("hidden");
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
setContractLastBalanceKey(undefined);
|
|
||||||
ALL_BALANCES_LIST.innerHTML = "";
|
|
||||||
fetchAndDisplayMoreBalances();
|
|
||||||
};
|
};
|
||||||
|
|
||||||
function setConnectionStatus(status: string, address: string | undefined = undefined) {
|
function setConnectionStatus(status: string, address: string | undefined = undefined) {
|
||||||
|
@ -190,42 +130,27 @@ const setVisibility = (selector: string, visible: boolean) => {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
export const updateInteractionVisibility = () => {
|
export function setupWalletWidget() {
|
||||||
const contractInteraction = <HTMLElement>document.querySelector("#contract-interaction");
|
// Setup event listener to connect to the MPC wallet browser extension
|
||||||
if (isConnected() && getContractAddress() !== undefined) {
|
const connectWallet = <Element>document.querySelector("#wallet-connect-btn");
|
||||||
contractInteraction.classList.remove("hidden");
|
connectWallet.addEventListener("click", connectMpcWalletClick);
|
||||||
} else {
|
|
||||||
contractInteraction.classList.add("hidden");
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
export const fetchAndDisplayMoreBalances = () => {
|
// Setup event listener to connect to the MetaMask snap
|
||||||
const address = getContractAddress();
|
const metaMaskConnect = <Element>document.querySelector("#metamask-connect-btn");
|
||||||
if (address == undefined) {
|
metaMaskConnect.addEventListener("click", connectMetaMaskWalletClick);
|
||||||
throw new Error("Address not set");
|
|
||||||
}
|
|
||||||
const tokenApi = getTokenApi();
|
|
||||||
if (tokenApi === undefined) {
|
|
||||||
throw new Error("Token API not setup");
|
|
||||||
}
|
|
||||||
if (tokenApi.tokenBalances == undefined) {
|
|
||||||
return; // Contract doesn't support tokenBalances
|
|
||||||
}
|
|
||||||
|
|
||||||
const lastKey = getContractLastBalanceKey();
|
// Setup event listener to connect to the ledger snap
|
||||||
tokenApi.tokenBalances(address, lastKey).then((balancesResult) => {
|
const ledgerConnect = <Element>document.querySelector("#ledger-connect-btn");
|
||||||
balancesResult.balances.forEach((amount, tokenOwner) => {
|
ledgerConnect.addEventListener("click", connectLedgerWalletClick);
|
||||||
const balance = document.createElement("li");
|
|
||||||
balance.innerHTML = `<span class="address">${tokenOwner.asString()}</span>: ${amount}`;
|
|
||||||
ALL_BALANCES_LIST.appendChild(balance);
|
|
||||||
});
|
|
||||||
setContractLastBalanceKey(balancesResult.next_cursor);
|
|
||||||
|
|
||||||
const loadMoreBtn = <Element>document.querySelector("#balances-load-more-btn");
|
const ledgerConnectValidate = <Element>document.querySelector("#connection-link-ledger-validate");
|
||||||
if (balancesResult.next_cursor === undefined) {
|
ledgerConnectValidate.addEventListener("click", validateLedgerConnectionClick);
|
||||||
loadMoreBtn.classList.add("hidden");
|
|
||||||
} else {
|
// Setup event listener to login using private key
|
||||||
loadMoreBtn.classList.remove("hidden");
|
const pkConnect = <Element>document.querySelector("#private-key-connect-btn");
|
||||||
}
|
pkConnect.addEventListener("click", connectPrivateKeyWalletClick);
|
||||||
});
|
|
||||||
};
|
// Setup event listener to drop the connection again
|
||||||
|
const disconnectWallet = <Element>document.querySelector("#wallet-disconnect-btn");
|
||||||
|
disconnectWallet.addEventListener("click", disconnectWalletClick);
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user