@TxnLab/use-wallet
React hooks for using Algorand compatible wallets with web applications.
Demo
Preview a basic implementation in Storybook or check out this example.
Quick Start
⚠️ If you’re using Webpack 5 (most newer React projects), you will need to install polyfills. Follow these directions.
Yarn
yarn add @txnlab/use-wallet
Install peer dependencies (if needed)
yarn add algosdk @blockshake/defly-connect @perawallet/connect @randlabs/myalgo-connect @walletconnect/client
NPM
npm install @txnlab/use-wallet
Install peer dependencies (if needed)
npm install algosdk @blockshake/defly-connect @perawallet/connect @randlabs/myalgo-connect @walletconnect/client
Set up the wallet providers
import React from "react";
import { useConnectWallet } from "@txnlab/use-wallet";
function App() {
const { providers, reconnectProviders, accounts, activeAccount } =
useConnectWallet();
// Reconnect the session when the user returns to the dApp
React.useEffect(() => {
reconnectProviders();
}, []);
// Use these properties to display connected accounts to users.
// They are reactive and presisted to local storage.
React.useEffect(() => {
console.log("connected accounts", accounts);
console.log("active account", activeAccount);
});
// Map through the providers, and render account information and "connect", "set active", and "disconnect" buttons
return (
<div>
{providers.map((provider) => (
<div key={"provider-" + provider.id}>
<h4>
<img width={30} height={30} src={provider.icon} />
{provider.name} {provider.isActive && "[active]"}
</h4>
<div>
<button onClick={provider.connect} disabled={provider.isConnected}>
Connect
</button>
<button onClick={provider.disconnect} disabled={!provider.isConnected}>
Disonnect
</button>
<button onClick={provider.setActive} disabled={!provider.isConnected || provider.isActive}>
Set Active
</button>
</div>
</div>
))}
</div>
);
}
Each provider has two connection states: isConnected and isActive.
isConnected means that the user has authorized the provider to talk to the dApp. The connection flow does not need to be restarted when switching to this wallet from a different one.
isActive indicates that the provider is currently active and will be used to sign and send transactions when using the useWallet hook.
Sign and send transactions
function Wallet() {
const { activeAccount, signTransactions, sendTransactions } = useWallet();
const sendTransaction = async (
from?: string,
to?: string,
amount?: number
) => {
if (!from || !to || !amount) {
throw new Error("Missing transaction params.");
}
const params = await algodClient.getTransactionParams().do();
// Construct a transaction to be signed and sent.
const transaction = algosdk.makePaymentTxnWithSuggestedParamsFromObject({
from,
to,
amount,
suggestedParams: params,
});
// Encode the transactions into a byte array.
const encodedTransaction = algosdk.encodeUnsignedTransaction(transaction);
// Sign the transactions.
const signedTransactions = await signTransactions([encodedTransaction]);
// Send the transactions.
const { id } = await sendTransactions(signedTransactions);
console.log("Successfully sent transaction. Transaction ID: ", id);
};
if (!activeAccount) {
return <p>Connect an account first.</p>;
}
return (
<div>
{
<button
onClick={() =>
sendTransaction(
activeAccount?.address,
activeAccount?.address,
1000
)
}
className="button"
>
Sign and send transactions
</button>
}
</div>
);
};
Webpack 5
-
Install
react-app-rewiredand the missing polyfills.yarn add --dev react-app-rewired crypto-browserify stream-browserify assert stream-http https-browserify os-browserify url buffer process
-
Create
config-overrides.jsin the root of your project and add the following:const webpack = require("webpack"); module.exports = function override(config) { const fallback = config.resolve.fallback || {}; Object.assign(fallback, { crypto: require.resolve("crypto-browserify"), stream: require.resolve("stream-browserify"), assert: require.resolve("assert"), http: require.resolve("stream-http"), https: require.resolve("https-browserify"), os: require.resolve("os-browserify"), url: require.resolve("url"), }); config.resolve.fallback = fallback; config.plugins = (config.plugins || []).concat([ new webpack.ProvidePlugin({ process: "process/browser", Buffer: ["buffer", "Buffer"], }), ]); return config; };
-
Change your scripts in
package.jsonto the following:"scripts": { "start": "react-app-rewired start", "build": "react-app-rewired build", "test": "react-app-rewired test", "eject": "react-scripts eject" },
Local Development
Install dependencies
yarn install
Demo in Storybook
yarn storybook
Build the library
yarn build
License
See the LICENSE file for license rights and limitations (MIT)