feat: torus

This commit is contained in:
bartosz-lipinski 2021-04-21 18:29:20 -05:00
parent b7c3cc6366
commit 4c6c1ad934
8 changed files with 120 additions and 165 deletions

1
.env Normal file
View File

@ -0,0 +1 @@
REACT_APP_CLIENT_ID=BKBTX-SmaEFGddZQrwqd65YFoImRQLca_Tj2IdmKyD2UbDpzrtN2WQ-NYLuej6gP0DfF3jSpEkI13wPt1uPedm0

View File

@ -21,11 +21,14 @@ export const CurrentUserBadge = (props: { showBalance?: boolean, showAddress?: b
{
marginLeft: '0.5rem',
display: 'flex',
width: props.iconSize
width: props.iconSize,
borderRadius: 50,
} :{
display: 'flex',
width: props.iconSize,
paddingLeft: 0,
borderRadius: 50,
};
const baseWalletKey: React.CSSProperties = { height: props.iconSize, cursor: 'pointer', userSelect: 'none' };
@ -33,6 +36,21 @@ export const CurrentUserBadge = (props: { showBalance?: boolean, showAddress?: b
baseWalletKey
:{ ...baseWalletKey, paddingLeft: 0 };
let name = props.showAddress ? shortenAddress(`${wallet.publicKey}`) : '';
const unknownWallet = wallet as any;
if(unknownWallet.name) {
name = unknownWallet.name;
}
let image = <Identicon
address={wallet.publicKey?.toBase58()}
style={iconStyle}
/>;
if(unknownWallet.image) {
image = <img src={unknownWallet.image} style={iconStyle} />;
}
return (
<div className="wallet-wrapper">
{props.showBalance && <span>
@ -46,11 +64,8 @@ export const CurrentUserBadge = (props: { showBalance?: boolean, showAddress?: b
trigger="click"
>
<div className="wallet-key" style={walletKeyStyle}>
{props.showAddress && shortenAddress(`${wallet.publicKey}`)}
<Identicon
address={wallet.publicKey?.toBase58()}
style={iconStyle}
/>
{name && (<span style={{ marginRight: '0.5rem' }}>{name}</span>)}
{image}
</div>
</Popover>
</div>

View File

@ -21,16 +21,16 @@ export const Identicon = (props: {
if (address && ref.current) {
try {
ref.current.innerHTML = '';
ref.current.className = className || '';
ref.current.appendChild(
Jazzicon(
style?.width || 16,
parseInt(bs58.decode(address).toString('hex').slice(5, 15), 16),
),
);
ref.current.innerHTML = '';
ref.current.className = className || '';
ref.current.appendChild(
Jazzicon(
style?.width || 16,
parseInt(bs58.decode(address).toString('hex').slice(5, 15), 16),
),
);
}catch (err) {
} catch (err) {
// TODO
}
}

View File

@ -8,7 +8,7 @@ export const Settings = ({
}: {
additionalSettings?: JSX.Element;
}) => {
const { connected, disconnect } = useWallet();
const { connected, disconnect, select } = useWallet();
const { endpoint, setEndpoint } = useConnectionConfig();
return (
@ -27,9 +27,17 @@ export const Settings = ({
))}
</Select>
{connected && (
<Button type="primary" onClick={disconnect}>
Disconnect
</Button>
<>
<span>Wallet:</span>
<Button onClick={select}
style={{ marginBottom: 5 }}>
Change
</Button>
<Button type="primary" onClick={disconnect}
style={{ marginBottom: 5 }}>
Disconnect
</Button>
</>
)}
{additionalSettings}
</div>

View File

@ -416,35 +416,35 @@ export function AccountsProvider({ children = null as any }) {
if (!connection || !publicKey) {
setTokenAccounts([]);
} else {
precacheUserTokenAccounts(connection, LEND_HOST_FEE_ADDRESS);
// precacheUserTokenAccounts(connection, LEND_HOST_FEE_ADDRESS);
precacheUserTokenAccounts(connection, publicKey).then(() => {
setTokenAccounts(selectUserAccounts());
});
// precacheUserTokenAccounts(connection, publicKey).then(() => {
// setTokenAccounts(selectUserAccounts());
// });
// This can return different types of accounts: token-account, mint, multisig
// TODO: web3.js expose ability to filter.
// this should use only filter syntax to only get accounts that are owned by user
const tokenSubID = connection.onProgramAccountChange(
programIds().token,
info => {
// TODO: fix type in web3.js
const id = (info.accountId as unknown) as string;
// TODO: do we need a better way to identify layout (maybe a enum identifing type?)
if (info.accountInfo.data.length === AccountLayout.span) {
const data = deserializeAccount(info.accountInfo.data);
// const tokenSubID = connection.onProgramAccountChange(
// programIds().token,
// info => {
// // TODO: fix type in web3.js
// const id = (info.accountId as unknown) as string;
// // TODO: do we need a better way to identify layout (maybe a enum identifing type?)
// if (info.accountInfo.data.length === AccountLayout.span) {
// const data = deserializeAccount(info.accountInfo.data);
if (PRECACHED_OWNERS.has(data.owner.toBase58())) {
cache.add(id, info.accountInfo, TokenAccountParser);
setTokenAccounts(selectUserAccounts());
}
}
},
'singleGossip',
);
// if (PRECACHED_OWNERS.has(data.owner.toBase58())) {
// cache.add(id, info.accountInfo, TokenAccountParser);
// setTokenAccounts(selectUserAccounts());
// }
// }
// },
// 'singleGossip',
// );
return () => {
connection.removeProgramAccountChangeListener(tokenSubID);
// connection.removeProgramAccountChangeListener(tokenSubID);
};
}
}, [connection, connected, publicKey, selectUserAccounts]);

View File

@ -10,6 +10,7 @@ import { LedgerProvider } from "@solana/wallet-ledger";
import { SolongWalletAdapter } from "../wallet-adapters/solong";
import { PhantomWalletAdapter } from "../wallet-adapters/phantom";
import { TorusWalletAdapter } from "../wallet-adapters/torus";
import { useLocation } from "react-router";
const ASSETS_URL = 'https://raw.githubusercontent.com/solana-labs/oyster/main/assets/wallets/';
export const WALLET_PROVIDERS = [
@ -60,8 +61,8 @@ const WalletContext = React.createContext<{
export function WalletProvider({ children = null as any }) {
const { endpoint } = useConnectionConfig();
const [autoConnect, setAutoConnect] = useState(false);
const location = useLocation();
const [autoConnect, setAutoConnect] = useState(location.pathname.indexOf('result=') >= 0 || false);
const [providerUrl, setProviderUrl] = useLocalStorageState("walletProvider");
const provider = useMemo(() => WALLET_PROVIDERS.find(({ url }) => url === providerUrl), [providerUrl]);

View File

@ -5,28 +5,6 @@ import { WalletAdapter } from "@solana/wallet-base"
import Torus from "@toruslabs/torus-embed"
import OpenLogin from "@toruslabs/openlogin"
import { getED25519Key } from "@toruslabs/openlogin-ed25519"
import { notify } from "../../utils/notifications"
import { ENDPOINTS } from "../../contexts"
// import { useConnection } from "../../contexts"
type TorusEvent = "disconnect" | "connect";
type TorusRequestMethod =
| "connect"
| "disconnect"
| "signTransaction"
| "signAllTransactions";
// interface TorusProvider {
// publicKey?: PublicKey;
// isConnected?: boolean;
// autoApprove?: boolean;
// signTransaction: (transaction: Transaction) => Promise<Transaction>;
// signAllTransactions: (transactions: Transaction[]) => Promise<Transaction[]>;
// connect: () => Promise<void>;
// disconnect: () => Promise<void>;
// on: (event: TorusEvent, handler: (args: any) => void) => void;
// request: (method: TorusRequestMethod, params: any) => Promise<any>;
// }
const getSolanaPrivateKey = (openloginKey: string)=>{
const { sk } = getED25519Key(openloginKey)
@ -34,132 +12,85 @@ const getSolanaPrivateKey = (openloginKey: string)=>{
}
export class TorusWalletAdapter extends EventEmitter implements WalletAdapter {
_provider: Torus | undefined;
// _provider: OpenLogin | undefined;
_publicKey: PublicKey | null;
// _provider: Torus | undefined;
_provider: OpenLogin | undefined;
endpoint: string;
providerUrl: string;
account: Account | undefined;
image: string = '';
name: string = '';
autoConnect = true;
constructor(providerUrl: string, endpoint: string) {
super()
this._publicKey = null
this.connect = this.connect.bind(this)
console.log("Constructing...", {providerUrl, endpoint})
this.endpoint = endpoint;
this.providerUrl = providerUrl;
}
// get connected() {
// return this._provider?.isConnected || false;
// }
// get autoApprove() {
// return this._provider?.autoApprove || false;
// }
async signAllTransactions(transactions: Transaction[]): Promise<Transaction[]> {
if(this.account) {
let account = this.account;
transactions.forEach(t => t.partialSign(account));
}
return transactions
}
get publicKey() {
return this._publicKey;
return this.account?.publicKey || null;
}
async signTransaction(transaction: Transaction) {
if(this.account) {
transaction.partialSign(this.account)
}
return transaction
}
connect = async () => {
console.log("Connecting...")
// const connection = useConnection()
const solanaNetwork = ENDPOINTS.find(end => end.name === "testnet")
if (!solanaNetwork) return
this._provider = new OpenLogin({
clientId: process.env.REACT_APP_CLIENT_ID || 'BKBTX-SmaEFGddZQrwqd65YFoImRQLca_Tj2IdmKyD2UbDpzrtN2WQ-NYLuej6gP0DfF3jSpEkI13wPt1uPedm0',
network: "mainnet", // mainnet, testnet, development
});
const connection = new Connection(solanaNetwork.endpoint)
try {
await this._provider.init();
} catch (ex) {
console.error('init failed', ex)
}
// this._provider = new OpenLogin({
// clientId: "BFvMIZJz9gVTzTXzJg_WezLkhUib-U2Q1wgDR1x95UzU5i-s642W8yxUvBXs4Sj1JuhRohgxvZL2nYnCA1_ZDbE",
// network: "testnet", // mainnet, testnet, development
// })
// await this._provider.init()
// console.log({openlogin: this._provider})
console.error(this._provider?.state.store);
// if (this._provider.privKey) { // already logged in
// const privateKey = this._provider.privKey
// const secretKey = getSolanaPrivateKey(privateKey)
// console.log("secretKey", secretKey)
// const account = new Account(secretKey)
// const accountInfo = await connection.getAccountInfo(account.publicKey)
// console.log("accountInfo", accountInfo)
// } else {
// const privKey = await this._provider.login()
// console.log("privKey", privKey)
// const solanaPrivateKey = getSolanaPrivateKey(privKey.privKey);
// console.log("solanaPrivateKey", solanaPrivateKey)
// // await getAccountInfo(solanaNetwork.url,solanaPrivateKey)
// }
if (this._provider.privKey) {
const privateKey = this._provider.privKey;
const secretKey = getSolanaPrivateKey(privateKey);
this.account = new Account(secretKey);
} else {
try {
const { privKey } = await this._provider.login();
const secretKey = getSolanaPrivateKey(privKey);
this.account = new Account(secretKey);
} catch {
//
}
}
this._provider = new Torus({})
await this._provider.init({})
await this._provider.login({})
// const sWeb3 = new solanaWeb3(torus.provider)
console.log({torus: this._provider})
console.log({solanaWeb3})
// result=eyJwcml2S2V5IjoiMmE3ZDUxOTBiYzA4MmUxMzYyZDE5NjVkNzI3OWQ1OWE0ZDY5ZDJlZWUzZGVmYzBiNThmMTk4OGE4YTY1YTA1YSIsInN0b3JlIjp7InRvdWNoSURQcmVmZXJlbmNlIjoidW5zZXQiLCJhcHBTdGF0ZSI6IiJ9fQ==
this.name = this._provider?.state.store.get('name');;
this.image = this._provider?.state.store.get('profileImage');;
const userInfo = await this._provider.getUserInfo("Holi")
console.log({userInfo})
// const publicAddress = await this._provider.getPublicAddress({
// verifier: "google",
// verifierId: "random@gmail.com",
// })
// const sdkInstance = new OpenLogin({
// clientId: "YOUR_PROJECT_ID",
// network: "testnet"
// });
// async function initializeOpenlogin() {
// await sdkInstance.init();
// if (sdkInstance.privKey) {
// // qpp has access ot private key now
// ...
// ...
// }
// setSdk(sdkInstance);
// setLoading(false)
// }
// initializeOpenlogin()
// if (this._provider) {
// return;
// }
// let provider: TorusProvider;
// if ((window as any)?.solana?.isTorus) {
// provider = (window as any).solana;
// } else {
// window.open("https://Torus.app/", "_blank");
// notify({
// message: "Torus Error",
// description: "Please install Torus wallet from Chrome ",
// });
// return;
// }
// provider.on('connect', () => {
// this._provider = provider;
// this.emit("connect");
// })
// if (!provider.isConnected) {
// await provider.connect();
// }
// this._provider = provider;
this.emit("connect");
}
disconnect = async () => {
console.log("Disconecting...")
console.log("Disconnecting...")
if (this._provider) {
// await this._provider.cleanUp()
await this._provider.logout()
await this._provider.logout();
await this._provider._cleanup();
this._provider = undefined;
this.emit("disconnect");
}

View File

@ -25,11 +25,6 @@ export function Routes() {
<MetaProvider>
<AppLayout>
<Switch>
<Route
exact
path="/"
component={() => <HomeView />}
/>
<Route
exact
path="/art/create/:step_param?"
@ -65,6 +60,10 @@ export function Routes() {
path="/auction/:id"
component={() => <AuctionView />}
/>
<Route
path="/"
component={() => <HomeView />}
/>
</Switch>
</AppLayout>
</MetaProvider>