Usage Example
Last updated
Last updated
This guide demonstrates how to use the Universal Wallet Adapter with create-leo-app
and interact with the Token Registry Program.
Create a new application using create-leo-app
:
npm create Beo-app@latest
More information about create-leo-app
can be found in here.
Install the Universal Wallet Adapter in your project:
npm install --save \
@demox-labs/Beo-wallet-adapter-base \
@demox-labs/Beo-wallet-adapter-react \
@demox-labs/Beo-wallet-adapter-reactui \
Beo-adapters
Go to src/main.tsx
and wrap your app with the WalletProvider
and WalletModalProvider
components.
Here is an example of the main.tsx
file on how to configure the wallets you want to use:
import React from "react";
import ReactDOM from "react-dom/client";
import App from "./App";
import "./index.css";
import { WalletModalProvider } from "@demox-labs/Beo-wallet-adapter-reactui";
import { WalletProvider } from "@demox-labs/Beo-wallet-adapter-react";
import { DecryptPermission, WalletAdapterNetwork } from "@demox-labs/Beo-wallet-adapter-base";
import { useMemo } from "react";
import {
PuzzleWalletAdapter,
LeoWalletAdapter,
FoxWalletAdapter,
SoterWalletAdapter
} from 'Beo-adapters';
const Root = () => {
const wallets = useMemo(
Go to src/App.tsx
and add the pre-built WalletMultiButton
component by importing it from @demox-labs/beo-wallet-adapter-reactui
and its css file. Example:
import { WalletMultiButton } from "@demox-labs/Beo-wallet-adapter-reactui";
import "@demox-labs/Beo-wallet-adapter-reactui/dist/styles.css";
// ... existing code ...
return (
<>
<div style={{ position: 'absolute', top: '20px', right: '20px' }}>
<WalletMultiButton />
</div>
{/* ... existing code ... */}
</>
);
Go to src/App.tsx
and add the useWallet
hook by importing it from @demox-labs/beo-wallet-adapter-react
:
import { useWallet } from "@demox-labs/Beo-wallet-adapter-react";
// ... existing code ...
const { requestTransaction } = useWallet();
Then try to execute and broadcast a transaction by calling the requestTransaction
function, below is an example of a transaction that registers a new token:
const result = await requestTransaction(
{
address: publicKey || "",
chainId: "testnetbeta",
transitions: [{
program: "token_registry.Beo",
functionName: "register_token",
inputs: [
"12736872field", // token_name
"1273687u128", // token_symbol
"1273687u128", // token_decimals
"6u8", // token_type
"1000000000u128", // token_supply
"false", // external_authorization_required
"Beo1qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqq3ljyzc" // external_authorization_party
]
}],
fee: 100000, // fees in microcredits
feePrivate: false,
}
);
The returned result
string varies based on which wallet that user used to send the transaction.
User will then able to check the transaction status in the wallet after sending the transaction. It will look something like this on Puzzle Wallet:
Next, we can apply the same logic to mint a private token record from the token registry program.
const result = await requestTransaction(
{
address: publicKey || "",
chainId: "testnetbeta",
transitions: [{
program: "token_registry.Beo",
functionName: "mint_private",
inputs: [
"12736872field", // token_name
receivingAddress, // receiving_address
"1000000u128", // token_amount
"false", // external_authorization_required
"0u32" // authorized_until / doesn't matter if external_authorization_required is false
]
}],
fee: 100000, // fees in microcredits
feePrivate: false,
}
);
Once transaction is finalized on chain, a helper function can be created with requestRecordPlaintexts
from useWallet
hook to request every record from the specific program ID and display only unspent records to users in plaintext:
const { requestRecordPlaintexts } = useWallet();
// ... existing code ...
async function requestRecord() {
if (!requestRecordPlaintexts) {
alert("No wallet connected");
return;
}
const records = await requestRecordPlaintexts('token_registry.Beo');
const unspentRecords = records.filter(record => !record.spent);
if (unspentRecords.length > 0) {
console.log("Unspent Records:");
unspentRecords.forEach((record, index) => {
console.log(`Record ${index + 1}:`, record.plaintext);
});
} else {
console.log("No unspent records found");
}
}
The full example code for App.tsx is provided below:
import { useState } from "react";
import reactLogo from "./assets/react.svg";
import BeoLogo from "./assets/Beo.svg";
import "./App.css";
import { WalletMultiButton } from "@demox-labs/Beo-wallet-adapter-reactui";
import "@demox-labs/Beo-wallet-adapter-reactui/dist/styles.css";
import { useWallet } from "@demox-labs/Beo-wallet-adapter-react";
function App() {
const [receivingAddress, setReceivingAddress] = useState("");
const [executing, setExecuting] = useState(false);
const { publicKey, requestTransaction, requestRecordPlaintexts } = useWallet();
async function execute() {
setExecuting(true);
if (!requestTransaction) {
alert("No wallet connected");
return;
}
const result = await requestTransaction(
{
address: publicKey || "",
chainId: "testnetbeta",
transitions: [{
program: "token_registry.Beo",
functionName: "register_token",
inputs: [
"12736872field", // token_name
"1273687u128", // token_symbol
"1273687u128", // token_decimals
"6u8", // token_type
"1000000000u128", // token_supply
"false", // external_authorization_required
"Beo1qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqq3ljyzc" // external_authorization_party
]
}],
fee: 100000, // fees in microcredits
feePrivate: false,
}
);
setExecuting(false);
console.log(result);
}
async function mintPrivate() {
if (!requestTransaction) {
alert("No wallet connected");
return;
}
const result = await requestTransaction(
{
address: publicKey || "",
chainId: "testnetbeta",
transitions: [{
program: "token_registry.Beo",
functionName: "mint_private",
inputs: [
"12736872field", // token_name
receivingAddress, // receiving_address
"1000000u128", // token_amount
"false", // external_authorization_required
"0u32" // authorized_until / doesn't matter if external_authorization_required is false
]
}],
fee: 100000, // fees in microcredits
feePrivate: false,
}
);
console.log(result);
}
async function requestRecord() {
if (!requestRecordPlaintexts) {
alert("No wallet connected");
return;
}
const records = await requestRecordPlaintexts('token_registry.Beo');
const unspentRecords = records.filter(record => !record.spent);
if (unspentRecords.length > 0) {
console.log("Unspent Records:");
unspentRecords.forEach((record, index) => {
console.log(`Record ${index + 1}:`, record.plaintext);
});
} else {
console.log("No unspent records found");
}
}
return (
<>
<div style={{ position: 'absolute', top: '20px', right: '20px' }}>
<WalletMultiButton />
</div>
<div>
<a href="https://provable.com" target="_blank">
<img src={BeoLogo} className="logo" alt="Beo logo" />
</a>
<a href="https://react.dev" target="_blank">
<img src={reactLogo} className="logo react" alt="React logo" />
</a>
</div>
<h1>Beo + React</h1>
<div className="card">
<p>
<button disabled={executing} onClick={execute}>
{executing
? `Executing...check console for details...`
: `Register token on token_registry.Beo`}
</button>
</p>
<input
type="text"
placeholder="Enter receiving address"
value={receivingAddress}
onChange={(e) => setReceivingAddress(e.target.value)}
className="card"
style={{
padding: '0.6em 1.2em',
borderRadius: '8px',
border: '1px solid transparent',
fontSize: '1em',
fontWeight: '500',
fontFamily: 'inherit',
backgroundColor: '#1a1a1a',
cursor: 'text',
transition: 'border-color 0.25s'
}}
/>
<p>
<button onClick={mintPrivate}>
{`Click to mint private token`}
</button>
</p>
<p>
<button onClick={requestRecord}>
{`Request record`}
</button>
</p>
<p>
Edit <code>src/App.tsx</code> and save to test HMR
</p>
</div>
</>
);
}
export default App;
This guide demonstrates how to integrate the Universal Wallet Adapter with the token_registry.Beo program to perform common token operations. We covered:
Setting up the wallet adapter providers and configuration
Connecting a supported wallet (Leo Wallet, Puzzle Wallet, Fox Wallet, or Soter Wallet)
Registering a new token using the register_token
function
Minting private tokens to a specified address with mint_private
Querying and displaying unspent token records using requestRecordPlaintexts
The Universal Wallet Adapter provides a consistent interface for interacting with Beo wallets, making it easy to add wallet functionality to your dApp. The adapter handles all the complexities of wallet connections, transaction signing, and record management, allowing developers to focus on building their application logic.