1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
|
import React, { Dispatch, SetStateAction, useState, useEffect } from "react";
import { TezosToolkit } from "@taquito/taquito";
import { BeaconWallet } from "@taquito/beacon-wallet";
import {
NetworkType,
BeaconEvent,
defaultEventCallbacks
} from "@airgap/beacon-sdk";
import TransportU2F from "@ledgerhq/hw-transport-u2f";
import { LedgerSigner } from "@taquito/ledger-signer";
type ButtonProps = {
Tezos: TezosToolkit;
setContract: Dispatch<SetStateAction<any>>;
setWallet: Dispatch<SetStateAction<any>>;
setUserAddress: Dispatch<SetStateAction<string>>;
setUserBalance: Dispatch<SetStateAction<number>>;
setStorage: Dispatch<SetStateAction<number>>;
contractAddress: string;
setBeaconConnection: Dispatch<SetStateAction<boolean>>;
setPublicToken: Dispatch<SetStateAction<string | null>>;
wallet: BeaconWallet;
};
const ConnectButton = ({
Tezos,
setContract,
setWallet,
setUserAddress,
setUserBalance,
setStorage,
contractAddress,
setBeaconConnection,
setPublicToken,
wallet
}: ButtonProps): JSX.Element => {
const [loadingNano, setLoadingNano] = useState<boolean>(false);
const setup = async (userAddress: string): Promise<void> => {
setUserAddress(userAddress);
// updates balance
const balance = await Tezos.tz.getBalance(userAddress);
setUserBalance(balance.toNumber());
// creates contract instance
const contract = await Tezos.wallet.at(contractAddress);
const storage: any = await contract.storage();
setContract(contract);
setStorage(storage);
};
const connectWallet = async (): Promise<void> => {
try {
await wallet.requestPermissions({
network: {
type: NetworkType.GRANADANET,
rpcUrl: "https://api.tez.ie/rpc/granadanet"
}
});
// gets user's address
const userAddress = await wallet.getPKH();
await setup(userAddress);
setBeaconConnection(true);
} catch (error) {
console.log(error);
}
};
const connectNano = async (): Promise<void> => {
try {
setLoadingNano(true);
const transport = await TransportU2F.create();
const ledgerSigner = new LedgerSigner(transport, "44'/1729'/0'/0'", true);
Tezos.setSignerProvider(ledgerSigner);
//Get the public key and the public key hash from the Ledger
const userAddress = await Tezos.signer.publicKeyHash();
await setup(userAddress);
} catch (error) {
console.log("Error!", error);
setLoadingNano(false);
}
};
useEffect(() => {
(async () => {
// creates a wallet instance
const wallet = new BeaconWallet({
name: "MyMedMemoir",
preferredNetwork: NetworkType.GRANADANET,
disableDefaultEvents: true, // Disable all events / UI. This also disables the pairing alert.
eventHandlers: {
// To keep the pairing alert, we have to add the following default event handlers back
[BeaconEvent.PAIR_INIT]: {
handler: defaultEventCallbacks.PAIR_INIT
},
[BeaconEvent.PAIR_SUCCESS]: {
handler: data => setPublicToken(data.publicKey)
}
}
});
Tezos.setWalletProvider(wallet);
setWallet(wallet);
// checks if wallet was connected before
const activeAccount = await wallet.client.getActiveAccount();
if (activeAccount) {
const userAddress = await wallet.getPKH();
await setup(userAddress);
setBeaconConnection(true);
}
})();
}, []);
return (
<div className="buttons">
<button className="button" onClick={connectWallet}>
<span>
<i className="fas fa-wallet"></i> Connect with wallet
</span>
</button>
<button className="button" disabled={loadingNano} onClick={connectNano}>
{loadingNano ? (
<span>
<i className="fas fa-spinner fa-spin"></i> Loading, please
wait
</span>
) : (
<span>
<i className="fab fa-usb"></i> Connect with Ledger Nano
</span>
)}
</button>
</div>
);
};
export default ConnectButton;
|