Skip to content

Commit

Permalink
refactor: burner wallet connector and UI loading (#58)
Browse files Browse the repository at this point in the history
  • Loading branch information
pedropereiradev authored Apr 17, 2024
1 parent a913e48 commit eafe351
Show file tree
Hide file tree
Showing 7 changed files with 119 additions and 138 deletions.
5 changes: 5 additions & 0 deletions .changeset/chatty-shoes-joke.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@fuel-connectors/burner-wallet-connector": patch
---

Refactor burner wallet connector
9 changes: 7 additions & 2 deletions examples/react-app/src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ export default function App() {
currentConnector,
isConnected,
isConnecting,
isLoadingConnectors,
isLoading,
isFetching,
connect,
Expand Down Expand Up @@ -79,8 +80,12 @@ export default function App() {
<section className="flex h-full flex-col items-center justify-center px-4 py-8 sm:px-8 sm:py-8 md:px-10 md:py-12">
<Button
onClick={connect}
loading={isConnecting}
loadingText="Connecting"
loading={isConnecting || isLoadingConnectors}
loadingText={
isLoadingConnectors
? 'Connect Wallet'
: 'Connecting...'
}
>
Connect Wallet
</Button>
Expand Down
7 changes: 6 additions & 1 deletion examples/react-app/src/hooks/useWallet.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,11 @@ const DEFAULT_CONNECTOR: ICurrentConnector = {

export const useWallet = () => {
const { fuel } = useFuel();
const { connect, isConnecting } = useConnectUI();
const {
connect,
isConnecting,
isLoading: isLoadingConnectors,
} = useConnectUI();
const { isConnected, refetch: refetchConnected } = useIsConnected();
const {
accounts,
Expand Down Expand Up @@ -75,6 +79,7 @@ export const useWallet = () => {
isConnecting,
isLoading,
isFetching,
isLoadingConnectors,
wallet,
connect,
refetchConnected,
Expand Down
120 changes: 37 additions & 83 deletions packages/burner-wallet-connector/src/BurnerWalletConnector.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,14 +15,14 @@ import {
} from 'fuels';
import {
BETA_5_URL,
BURNER_WALLET_CONNECTED,
BURNER_WALLET_ICON,
BURNER_WALLET_PRIVATE_KEY,
WINDOW,
} from './constants';
import type { BurnerWalletConfig } from './types';

export class BurnerWalletConnector extends FuelConnector {
static defaultProviderUrl: string = BETA_5_URL;
name = 'Burner Wallet';

connected = false;
Expand All @@ -39,65 +39,49 @@ export class BurnerWalletConnector extends FuelConnector {
},
};

burnerWallet: WalletUnlocked | null = null;
burnerWalletProvider: Provider | null = null;
burnerWalletPrivateKey: string | null = null;

private config: BurnerWalletConfig = {};
private burnerWallet: WalletUnlocked | null = null;
private burnerWalletProvider: Provider | null = null;
private storage: StorageAbstract;

constructor(config: BurnerWalletConfig = {}) {
super();

this.config = config;
this.storage = this.getStorage(config.storage);

this.configFuelProvider(config);
this.setupBurnerWallet();
}

private async configFuelProvider(config: BurnerWalletConfig = {}) {
this.config.fuelProvider =
config.fuelProvider || Provider.create(BETA_5_URL);
}

private async setupBurnerWallet() {
const privateKey = await this.storage.getItem(BURNER_WALLET_PRIVATE_KEY);

if (privateKey) {
this.storage.setItem(BURNER_WALLET_ICON, privateKey);
private async getProvider(config: BurnerWalletConfig = {}) {
if (!this.burnerWalletProvider) {
this.burnerWalletProvider = await (config.fuelProvider ||
Provider.create(BurnerWalletConnector.defaultProviderUrl));
}
return this.burnerWalletProvider;
}

if (!privateKey) {
this.burnerWallet = Wallet.generate({
provider: await this.config.fuelProvider,
});

this.burnerWalletProvider = this.burnerWallet.provider;
this.burnerWalletPrivateKey = this.burnerWallet.privateKey;

this.storage.setItem(
BURNER_WALLET_PRIVATE_KEY,
this.burnerWalletPrivateKey,
);
private generatePrivateKey() {
const privateKey = Wallet.generate().privateKey;
this.storage.setItem(BURNER_WALLET_PRIVATE_KEY, privateKey);
return privateKey;
}

return this.burnerWallet;
private async setupBurnerWallet(createWallet = false) {
if (this.burnerWallet) return;
let privateKey = await this.storage.getItem(BURNER_WALLET_PRIVATE_KEY);
if (createWallet && !privateKey) {
privateKey = this.generatePrivateKey();
}
if (!privateKey) return;

this.burnerWallet = Wallet.fromPrivateKey(
privateKey,
await this.config.fuelProvider,
await this.getProvider(),
);

this.burnerWalletProvider = this.burnerWallet.provider;
this.burnerWalletPrivateKey = this.burnerWallet.privateKey;

return this.burnerWallet;
}

private getStorage(storage?: StorageAbstract) {
const _storage =
storage ?? (WINDOW.sessionStorage as unknown as StorageAbstract);
storage ?? (WINDOW.localStorage as unknown as StorageAbstract);
if (!_storage) {
throw new Error('No storage provided');
}
Expand All @@ -111,9 +95,7 @@ export class BurnerWalletConnector extends FuelConnector {
* ============================================================
*/
async ping(): Promise<boolean> {
await this.configFuelProvider();
await this.setupBurnerWallet();

return true;
}

Expand All @@ -122,41 +104,19 @@ export class BurnerWalletConnector extends FuelConnector {
}

async isConnected(): Promise<boolean> {
const connected =
(await this.storage.getItem(BURNER_WALLET_CONNECTED)) === 'true';

if (!connected) {
return false;
}

const account = this.burnerWallet?.address.toString();

return !!account && account.length > 0;
await this.setupBurnerWallet(false);
return !!this.burnerWallet;
}

async connect(): Promise<boolean> {
if (!(await this.isConnected())) {
if (!this.burnerWalletProvider) {
throw Error('Burner Wallet Provider not found');
}

await this.setupBurnerWallet();

this.burnerWalletProvider = this.burnerWallet?.connect(
this.burnerWalletProvider,
) as Provider;

this.storage.setItem(BURNER_WALLET_CONNECTED, 'true');
}
await this.setupBurnerWallet(true);
const accountAddress = this.burnerWallet?.address.toAddress();

this.emit(this.events.connection, true);
this.emit(
this.events.currentAccount,
this.burnerWallet?.address.toAddress(),
);
this.emit(this.events.accounts, [this.burnerWallet?.address.toAddress()]);
this.emit(this.events.currentAccount, accountAddress);
this.emit(this.events.accounts, [accountAddress]);

return this.connected;
return true;
}

async accounts(): Promise<string[]> {
Expand All @@ -174,32 +134,25 @@ export class BurnerWalletConnector extends FuelConnector {
}

async disconnect(): Promise<boolean> {
if (await this.isConnected()) {
this.burnerWalletPrivateKey = null;
this.burnerWalletProvider = null;
this.burnerWallet = null;
}

this.storage.setItem(BURNER_WALLET_CONNECTED, 'false');
this.burnerWalletProvider = null;
this.burnerWallet = null;
this.storage.removeItem(BURNER_WALLET_PRIVATE_KEY);

this.emit(this.events.connection, false);
this.emit(this.events.currentAccount, null);
this.emit(this.events.accounts, []);

return this.connected;
}

async signMessage(_address: string, _message: string): Promise<string> {
async signMessage(address: string, message: string): Promise<string> {
if (!this.burnerWallet) {
throw Error('Wallet not connected');
}

if (_address !== this.burnerWallet.address.toString()) {
if (address !== this.burnerWallet.address.toString()) {
throw Error('Address not found for the connector');
}

const signMessage = await this.burnerWallet.signMessage(_message);
const signMessage = await this.burnerWallet.signMessage(message);

return signMessage;
}
Expand Down Expand Up @@ -257,11 +210,12 @@ export class BurnerWalletConnector extends FuelConnector {
}

async currentNetwork(): Promise<Network> {
const network = await this.burnerWalletProvider?.getNetwork();
const provider = await this.getProvider();
const network = await provider.getNetwork();

return {
chainId: Number(network?.chainId),
url: this.burnerWalletProvider?.url ?? '',
url: provider.url ?? '',
};
}

Expand Down
4 changes: 0 additions & 4 deletions packages/burner-wallet-connector/src/constants.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,7 @@
export const BURNER_WALLET_ICON =
'data:image/svg+xml;utf8;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCA0Ny41IDQ3LjUiPjxkZWZzPjxjbGlwUGF0aCBpZD0iYSI+PHBhdGggZD0iTTAgMzhoMzhWMEgwdjM4WiIvPjwvY2xpcFBhdGg+PGNsaXBQYXRoIGlkPSJiIj48cGF0aCBkPSJNMTguNTgzIDI3LjgzM2MtMi45NTctLjIzMS01LjY2NiAyLjU0Mi00LjY2NiA3LjA0Mi0zLjIzOS0yLjM4Ni0zLjMzMi02LjQwMy0yLjMzMy05IDEuMDQxLTIuNzA4LS4wNDItNC45NTgtMi41ODQtNS4yMDgtMi44MzktLjI4LTQuNDE2IDMuMDQyLTIuOTYyIDguMzMzQTE2LjkzNiAxNi45MzYgMCAwIDEgMiAxOEMyIDguNjExIDkuNjExIDEgMTkgMXMxNyA3LjYxMSAxNyAxN2MwIDIuMDYzLS4zNjcgNC4wMzktMS4wNCA1Ljg2OC0uNDYtNS4zODgtMy4zMzMtOC4xNTctNi4zMzUtNi44NjgtMi44MTIgMS4yMDgtLjkxNyA1LjkxNy0uNzc3IDguMTY0LjIzNiAzLjgwOS0uMDEyIDguMTY5LTYuOTMxIDExLjc5NCAyLjg3NS01LjQ5OS4zMzMtOC45MTctMi4zMzQtOS4xMjUiLz48L2NsaXBQYXRoPjwvZGVmcz48ZyBjbGlwLXBhdGg9InVybCgjYSkiIHRyYW5zZm9ybT0ibWF0cml4KDEuMjUgMCAwIC0xLjI1IDAgNDcuNSkiPjxwYXRoIGZpbGw9IiNmNDkwMGMiIGQ9Ik0zNiAxOGMwIDIuMDYzLS4zNjcgNC4wMzktMS4wNCA1Ljg2OC0uNDYtNS4zODktMy4zMzMtOC4xNTctNi4zMzUtNi44NjgtMi44MTMgMS4yMDgtLjkxNyA1LjkxNy0uNzc3IDguMTY0LjIzNiAzLjgwOS0uMDEyIDguMTY5LTYuOTMxIDExLjc5NCAyLjg3NS01LjUuMzMzLTguOTE2LTIuMzM0LTkuMTI1LTIuOTU4LS4yMy01LjY2NiAyLjU0Mi00LjY2NiA3LjA0Mi0zLjIzOC0yLjM4Ni0zLjMzMy02LjQwMi0yLjMzNC05IDEuMDQyLTIuNzA4LS4wNDEtNC45NTgtMi41ODMtNS4yMDgtMi44MzktLjI4LTQuNDE3IDMuMDQxLTIuOTYyIDguMzMzQTE2LjkzNiAxNi45MzYgMCAwIDEgMiAxOEMyIDguNjExIDkuNjExIDEgMTkgMXMxNyA3LjYxMSAxNyAxNyIvPjwvZz48ZyBjbGlwLXBhdGg9InVybCgjYikiIHRyYW5zZm9ybT0ibWF0cml4KDEuMjUgMCAwIC0xLjI1IDAgNDcuNSkiPjxwYXRoIGZpbGw9IiNmZmNjNGQiIGQ9Ik0zMSA3YzAgMi4xODctLjU4NCA0LjIzNi0xLjYwNSA2LjAwMS4xNDctMy4wODQtMi41NjItNC4yOTMtNC4wMi0zLjcwOS0yLjEwNS44NDMtMS41NDEgMi4yOTEtMi4wODMgNS4yOTEtLjU0MiAzLTIuNjI1IDUuMDg0LTUuNzA5IDYgMi4yNS02LjMzMy0xLjI0Ny04LjY2Ny0zLjA4LTkuMDg0LTEuODcyLS40MjYtMy43NTMuMDAxLTMuOTY4IDQuMDA3QTExLjk2NyAxMS45NjcgMCAwIDEgNyA3QzcgLjM3MyAxMi4zNzMtNSAxOS01UzMxIC4zNzMgMzEgNyIvPjwvZz48L3N2Zz4=';

export const BETA_5_URL = 'https://beta-5.fuel.network/graphql';

export const HAS_WINDOW = typeof window !== 'undefined';
// biome-ignore lint/suspicious/noExplicitAny: <explanation>
export const WINDOW: any = HAS_WINDOW ? window : {};

export const BURNER_WALLET_CONNECTED = 'burner-wallet-connected';
export const BURNER_WALLET_PRIVATE_KEY = 'burner-wallet-private-key';
Loading

0 comments on commit eafe351

Please sign in to comment.