mirror of https://github.com/certusone/oyster.git
feat: torus
This commit is contained in:
parent
b7c3cc6366
commit
4c6c1ad934
|
@ -0,0 +1 @@
|
||||||
|
REACT_APP_CLIENT_ID=BKBTX-SmaEFGddZQrwqd65YFoImRQLca_Tj2IdmKyD2UbDpzrtN2WQ-NYLuej6gP0DfF3jSpEkI13wPt1uPedm0
|
|
@ -21,11 +21,14 @@ export const CurrentUserBadge = (props: { showBalance?: boolean, showAddress?: b
|
||||||
{
|
{
|
||||||
marginLeft: '0.5rem',
|
marginLeft: '0.5rem',
|
||||||
display: 'flex',
|
display: 'flex',
|
||||||
width: props.iconSize
|
width: props.iconSize,
|
||||||
|
borderRadius: 50,
|
||||||
|
|
||||||
} :{
|
} :{
|
||||||
display: 'flex',
|
display: 'flex',
|
||||||
width: props.iconSize,
|
width: props.iconSize,
|
||||||
paddingLeft: 0,
|
paddingLeft: 0,
|
||||||
|
borderRadius: 50,
|
||||||
};
|
};
|
||||||
|
|
||||||
const baseWalletKey: React.CSSProperties = { height: props.iconSize, cursor: 'pointer', userSelect: 'none' };
|
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
|
||||||
:{ ...baseWalletKey, paddingLeft: 0 };
|
:{ ...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 (
|
return (
|
||||||
<div className="wallet-wrapper">
|
<div className="wallet-wrapper">
|
||||||
{props.showBalance && <span>
|
{props.showBalance && <span>
|
||||||
|
@ -46,11 +64,8 @@ export const CurrentUserBadge = (props: { showBalance?: boolean, showAddress?: b
|
||||||
trigger="click"
|
trigger="click"
|
||||||
>
|
>
|
||||||
<div className="wallet-key" style={walletKeyStyle}>
|
<div className="wallet-key" style={walletKeyStyle}>
|
||||||
{props.showAddress && shortenAddress(`${wallet.publicKey}`)}
|
{name && (<span style={{ marginRight: '0.5rem' }}>{name}</span>)}
|
||||||
<Identicon
|
{image}
|
||||||
address={wallet.publicKey?.toBase58()}
|
|
||||||
style={iconStyle}
|
|
||||||
/>
|
|
||||||
</div>
|
</div>
|
||||||
</Popover>
|
</Popover>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -21,16 +21,16 @@ export const Identicon = (props: {
|
||||||
if (address && ref.current) {
|
if (address && ref.current) {
|
||||||
try {
|
try {
|
||||||
|
|
||||||
ref.current.innerHTML = '';
|
ref.current.innerHTML = '';
|
||||||
ref.current.className = className || '';
|
ref.current.className = className || '';
|
||||||
ref.current.appendChild(
|
ref.current.appendChild(
|
||||||
Jazzicon(
|
Jazzicon(
|
||||||
style?.width || 16,
|
style?.width || 16,
|
||||||
parseInt(bs58.decode(address).toString('hex').slice(5, 15), 16),
|
parseInt(bs58.decode(address).toString('hex').slice(5, 15), 16),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
|
||||||
}catch (err) {
|
} catch (err) {
|
||||||
// TODO
|
// TODO
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,7 +8,7 @@ export const Settings = ({
|
||||||
}: {
|
}: {
|
||||||
additionalSettings?: JSX.Element;
|
additionalSettings?: JSX.Element;
|
||||||
}) => {
|
}) => {
|
||||||
const { connected, disconnect } = useWallet();
|
const { connected, disconnect, select } = useWallet();
|
||||||
const { endpoint, setEndpoint } = useConnectionConfig();
|
const { endpoint, setEndpoint } = useConnectionConfig();
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
@ -27,9 +27,17 @@ export const Settings = ({
|
||||||
))}
|
))}
|
||||||
</Select>
|
</Select>
|
||||||
{connected && (
|
{connected && (
|
||||||
<Button type="primary" onClick={disconnect}>
|
<>
|
||||||
Disconnect
|
<span>Wallet:</span>
|
||||||
</Button>
|
<Button onClick={select}
|
||||||
|
style={{ marginBottom: 5 }}>
|
||||||
|
Change
|
||||||
|
</Button>
|
||||||
|
<Button type="primary" onClick={disconnect}
|
||||||
|
style={{ marginBottom: 5 }}>
|
||||||
|
Disconnect
|
||||||
|
</Button>
|
||||||
|
</>
|
||||||
)}
|
)}
|
||||||
{additionalSettings}
|
{additionalSettings}
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -416,35 +416,35 @@ export function AccountsProvider({ children = null as any }) {
|
||||||
if (!connection || !publicKey) {
|
if (!connection || !publicKey) {
|
||||||
setTokenAccounts([]);
|
setTokenAccounts([]);
|
||||||
} else {
|
} else {
|
||||||
precacheUserTokenAccounts(connection, LEND_HOST_FEE_ADDRESS);
|
// precacheUserTokenAccounts(connection, LEND_HOST_FEE_ADDRESS);
|
||||||
|
|
||||||
precacheUserTokenAccounts(connection, publicKey).then(() => {
|
// precacheUserTokenAccounts(connection, publicKey).then(() => {
|
||||||
setTokenAccounts(selectUserAccounts());
|
// setTokenAccounts(selectUserAccounts());
|
||||||
});
|
// });
|
||||||
|
|
||||||
// This can return different types of accounts: token-account, mint, multisig
|
// This can return different types of accounts: token-account, mint, multisig
|
||||||
// TODO: web3.js expose ability to filter.
|
// TODO: web3.js expose ability to filter.
|
||||||
// this should use only filter syntax to only get accounts that are owned by user
|
// this should use only filter syntax to only get accounts that are owned by user
|
||||||
const tokenSubID = connection.onProgramAccountChange(
|
// const tokenSubID = connection.onProgramAccountChange(
|
||||||
programIds().token,
|
// programIds().token,
|
||||||
info => {
|
// info => {
|
||||||
// TODO: fix type in web3.js
|
// // TODO: fix type in web3.js
|
||||||
const id = (info.accountId as unknown) as string;
|
// const id = (info.accountId as unknown) as string;
|
||||||
// TODO: do we need a better way to identify layout (maybe a enum identifing type?)
|
// // TODO: do we need a better way to identify layout (maybe a enum identifing type?)
|
||||||
if (info.accountInfo.data.length === AccountLayout.span) {
|
// if (info.accountInfo.data.length === AccountLayout.span) {
|
||||||
const data = deserializeAccount(info.accountInfo.data);
|
// const data = deserializeAccount(info.accountInfo.data);
|
||||||
|
|
||||||
if (PRECACHED_OWNERS.has(data.owner.toBase58())) {
|
// if (PRECACHED_OWNERS.has(data.owner.toBase58())) {
|
||||||
cache.add(id, info.accountInfo, TokenAccountParser);
|
// cache.add(id, info.accountInfo, TokenAccountParser);
|
||||||
setTokenAccounts(selectUserAccounts());
|
// setTokenAccounts(selectUserAccounts());
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
},
|
// },
|
||||||
'singleGossip',
|
// 'singleGossip',
|
||||||
);
|
// );
|
||||||
|
|
||||||
return () => {
|
return () => {
|
||||||
connection.removeProgramAccountChangeListener(tokenSubID);
|
// connection.removeProgramAccountChangeListener(tokenSubID);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}, [connection, connected, publicKey, selectUserAccounts]);
|
}, [connection, connected, publicKey, selectUserAccounts]);
|
||||||
|
|
|
@ -10,6 +10,7 @@ import { LedgerProvider } from "@solana/wallet-ledger";
|
||||||
import { SolongWalletAdapter } from "../wallet-adapters/solong";
|
import { SolongWalletAdapter } from "../wallet-adapters/solong";
|
||||||
import { PhantomWalletAdapter } from "../wallet-adapters/phantom";
|
import { PhantomWalletAdapter } from "../wallet-adapters/phantom";
|
||||||
import { TorusWalletAdapter } from "../wallet-adapters/torus";
|
import { TorusWalletAdapter } from "../wallet-adapters/torus";
|
||||||
|
import { useLocation } from "react-router";
|
||||||
|
|
||||||
const ASSETS_URL = 'https://raw.githubusercontent.com/solana-labs/oyster/main/assets/wallets/';
|
const ASSETS_URL = 'https://raw.githubusercontent.com/solana-labs/oyster/main/assets/wallets/';
|
||||||
export const WALLET_PROVIDERS = [
|
export const WALLET_PROVIDERS = [
|
||||||
|
@ -60,8 +61,8 @@ const WalletContext = React.createContext<{
|
||||||
|
|
||||||
export function WalletProvider({ children = null as any }) {
|
export function WalletProvider({ children = null as any }) {
|
||||||
const { endpoint } = useConnectionConfig();
|
const { endpoint } = useConnectionConfig();
|
||||||
|
const location = useLocation();
|
||||||
const [autoConnect, setAutoConnect] = useState(false);
|
const [autoConnect, setAutoConnect] = useState(location.pathname.indexOf('result=') >= 0 || false);
|
||||||
const [providerUrl, setProviderUrl] = useLocalStorageState("walletProvider");
|
const [providerUrl, setProviderUrl] = useLocalStorageState("walletProvider");
|
||||||
|
|
||||||
const provider = useMemo(() => WALLET_PROVIDERS.find(({ url }) => url === providerUrl), [providerUrl]);
|
const provider = useMemo(() => WALLET_PROVIDERS.find(({ url }) => url === providerUrl), [providerUrl]);
|
||||||
|
|
|
@ -5,28 +5,6 @@ import { WalletAdapter } from "@solana/wallet-base"
|
||||||
import Torus from "@toruslabs/torus-embed"
|
import Torus from "@toruslabs/torus-embed"
|
||||||
import OpenLogin from "@toruslabs/openlogin"
|
import OpenLogin from "@toruslabs/openlogin"
|
||||||
import { getED25519Key } from "@toruslabs/openlogin-ed25519"
|
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 getSolanaPrivateKey = (openloginKey: string)=>{
|
||||||
const { sk } = getED25519Key(openloginKey)
|
const { sk } = getED25519Key(openloginKey)
|
||||||
|
@ -34,132 +12,85 @@ const getSolanaPrivateKey = (openloginKey: string)=>{
|
||||||
}
|
}
|
||||||
|
|
||||||
export class TorusWalletAdapter extends EventEmitter implements WalletAdapter {
|
export class TorusWalletAdapter extends EventEmitter implements WalletAdapter {
|
||||||
_provider: Torus | undefined;
|
// _provider: Torus | undefined;
|
||||||
// _provider: OpenLogin | undefined;
|
_provider: OpenLogin | undefined;
|
||||||
_publicKey: PublicKey | null;
|
endpoint: string;
|
||||||
|
providerUrl: string;
|
||||||
|
account: Account | undefined;
|
||||||
|
image: string = '';
|
||||||
|
name: string = '';
|
||||||
|
|
||||||
|
autoConnect = true;
|
||||||
|
|
||||||
constructor(providerUrl: string, endpoint: string) {
|
constructor(providerUrl: string, endpoint: string) {
|
||||||
super()
|
super()
|
||||||
this._publicKey = null
|
|
||||||
this.connect = this.connect.bind(this)
|
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[]> {
|
async signAllTransactions(transactions: Transaction[]): Promise<Transaction[]> {
|
||||||
|
if(this.account) {
|
||||||
|
let account = this.account;
|
||||||
|
transactions.forEach(t => t.partialSign(account));
|
||||||
|
}
|
||||||
|
|
||||||
return transactions
|
return transactions
|
||||||
}
|
}
|
||||||
|
|
||||||
get publicKey() {
|
get publicKey() {
|
||||||
return this._publicKey;
|
return this.account?.publicKey || null;
|
||||||
}
|
}
|
||||||
|
|
||||||
async signTransaction(transaction: Transaction) {
|
async signTransaction(transaction: Transaction) {
|
||||||
|
if(this.account) {
|
||||||
|
transaction.partialSign(this.account)
|
||||||
|
}
|
||||||
|
|
||||||
return transaction
|
return transaction
|
||||||
}
|
}
|
||||||
|
|
||||||
connect = async () => {
|
connect = async () => {
|
||||||
console.log("Connecting...")
|
this._provider = new OpenLogin({
|
||||||
// const connection = useConnection()
|
clientId: process.env.REACT_APP_CLIENT_ID || 'BKBTX-SmaEFGddZQrwqd65YFoImRQLca_Tj2IdmKyD2UbDpzrtN2WQ-NYLuej6gP0DfF3jSpEkI13wPt1uPedm0',
|
||||||
const solanaNetwork = ENDPOINTS.find(end => end.name === "testnet")
|
network: "mainnet", // mainnet, testnet, development
|
||||||
if (!solanaNetwork) return
|
});
|
||||||
|
|
||||||
const connection = new Connection(solanaNetwork.endpoint)
|
try {
|
||||||
|
await this._provider.init();
|
||||||
|
} catch (ex) {
|
||||||
|
console.error('init failed', ex)
|
||||||
|
}
|
||||||
|
|
||||||
// this._provider = new OpenLogin({
|
console.error(this._provider?.state.store);
|
||||||
// clientId: "BFvMIZJz9gVTzTXzJg_WezLkhUib-U2Q1wgDR1x95UzU5i-s642W8yxUvBXs4Sj1JuhRohgxvZL2nYnCA1_ZDbE",
|
|
||||||
// network: "testnet", // mainnet, testnet, development
|
|
||||||
// })
|
|
||||||
// await this._provider.init()
|
|
||||||
// console.log({openlogin: this._provider})
|
|
||||||
|
|
||||||
// if (this._provider.privKey) { // already logged in
|
if (this._provider.privKey) {
|
||||||
// const privateKey = this._provider.privKey
|
const privateKey = this._provider.privKey;
|
||||||
// const secretKey = getSolanaPrivateKey(privateKey)
|
const secretKey = getSolanaPrivateKey(privateKey);
|
||||||
// console.log("secretKey", secretKey)
|
this.account = new Account(secretKey);
|
||||||
// const account = new Account(secretKey)
|
} else {
|
||||||
// const accountInfo = await connection.getAccountInfo(account.publicKey)
|
try {
|
||||||
// console.log("accountInfo", accountInfo)
|
const { privKey } = await this._provider.login();
|
||||||
// } else {
|
const secretKey = getSolanaPrivateKey(privKey);
|
||||||
// const privKey = await this._provider.login()
|
this.account = new Account(secretKey);
|
||||||
// console.log("privKey", privKey)
|
} catch {
|
||||||
// const solanaPrivateKey = getSolanaPrivateKey(privKey.privKey);
|
//
|
||||||
// console.log("solanaPrivateKey", solanaPrivateKey)
|
}
|
||||||
// // await getAccountInfo(solanaNetwork.url,solanaPrivateKey)
|
}
|
||||||
// }
|
|
||||||
|
|
||||||
this._provider = new Torus({})
|
this.name = this._provider?.state.store.get('name');;
|
||||||
await this._provider.init({})
|
this.image = this._provider?.state.store.get('profileImage');;
|
||||||
await this._provider.login({})
|
|
||||||
// const sWeb3 = new solanaWeb3(torus.provider)
|
|
||||||
console.log({torus: this._provider})
|
|
||||||
console.log({solanaWeb3})
|
|
||||||
// result=eyJwcml2S2V5IjoiMmE3ZDUxOTBiYzA4MmUxMzYyZDE5NjVkNzI3OWQ1OWE0ZDY5ZDJlZWUzZGVmYzBiNThmMTk4OGE4YTY1YTA1YSIsInN0b3JlIjp7InRvdWNoSURQcmVmZXJlbmNlIjoidW5zZXQiLCJhcHBTdGF0ZSI6IiJ9fQ==
|
|
||||||
|
|
||||||
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");
|
this.emit("connect");
|
||||||
}
|
}
|
||||||
|
|
||||||
disconnect = async () => {
|
disconnect = async () => {
|
||||||
console.log("Disconecting...")
|
console.log("Disconnecting...")
|
||||||
if (this._provider) {
|
if (this._provider) {
|
||||||
// await this._provider.cleanUp()
|
await this._provider.logout();
|
||||||
await this._provider.logout()
|
await this._provider._cleanup();
|
||||||
this._provider = undefined;
|
this._provider = undefined;
|
||||||
this.emit("disconnect");
|
this.emit("disconnect");
|
||||||
}
|
}
|
||||||
|
|
|
@ -25,11 +25,6 @@ export function Routes() {
|
||||||
<MetaProvider>
|
<MetaProvider>
|
||||||
<AppLayout>
|
<AppLayout>
|
||||||
<Switch>
|
<Switch>
|
||||||
<Route
|
|
||||||
exact
|
|
||||||
path="/"
|
|
||||||
component={() => <HomeView />}
|
|
||||||
/>
|
|
||||||
<Route
|
<Route
|
||||||
exact
|
exact
|
||||||
path="/art/create/:step_param?"
|
path="/art/create/:step_param?"
|
||||||
|
@ -65,6 +60,10 @@ export function Routes() {
|
||||||
path="/auction/:id"
|
path="/auction/:id"
|
||||||
component={() => <AuctionView />}
|
component={() => <AuctionView />}
|
||||||
/>
|
/>
|
||||||
|
<Route
|
||||||
|
path="/"
|
||||||
|
component={() => <HomeView />}
|
||||||
|
/>
|
||||||
</Switch>
|
</Switch>
|
||||||
</AppLayout>
|
</AppLayout>
|
||||||
</MetaProvider>
|
</MetaProvider>
|
||||||
|
|
Loading…
Reference in New Issue