From 1eaa4a6db38c081361f6633a93bf03927749a883 Mon Sep 17 00:00:00 2001
From: JesseKuntz
Date: Mon, 23 Feb 2026 16:16:53 -0500
Subject: [PATCH] feat: hoodi support
---
demo/.env_example | 2 ++
demo/README.md | 44 +++++++++++++++++++++++++++++
demo/package.json | 2 +-
demo/pnpm-lock.yaml | 10 +++----
demo/src/App.tsx | 8 +++---
demo/src/components/MainContent.tsx | 8 +++---
demo/src/components/Sidebar.tsx | 2 +-
demo/src/components/ToggleGroup.tsx | 10 +++----
demo/src/vite-env.d.ts | 8 ++++++
9 files changed, 74 insertions(+), 20 deletions(-)
create mode 100644 demo/.env_example
create mode 100644 demo/README.md
diff --git a/demo/.env_example b/demo/.env_example
new file mode 100644
index 0000000..8f413b6
--- /dev/null
+++ b/demo/.env_example
@@ -0,0 +1,2 @@
+# Figment dApp token (app ID). Exposed to the client as import.meta.env.VITE_DAPP_TOKEN.
+VITE_DAPP_TOKEN=d500a3f1bdc613c4ece8964f5c7b9f173393cf53b4eb4eadb520e80435c4ece3
diff --git a/demo/README.md b/demo/README.md
new file mode 100644
index 0000000..b366243
--- /dev/null
+++ b/demo/README.md
@@ -0,0 +1,44 @@
+# Figment Elements Demo
+
+A simple demo app for the [Figment Elements](https://docs.figment.io/docs/elements) staking widget. It lets you try Ethereum (Hoodi) and Solana (Devnet) staking in an embeddable iframe.
+
+## Getting started
+
+### 1. Install dependencies
+
+From the `demo` folder:
+
+```bash
+pnpm i
+```
+
+### 2. Set your Figment dApp token
+
+Copy the example env file and add your token:
+
+```bash
+cp .env_example .env
+```
+
+Edit `.env` and set your Figment dApp token (app ID):
+
+```
+VITE_DAPP_TOKEN=your-figment-app-id
+```
+
+### 3. Run the demo
+
+```bash
+pnpm dev
+```
+
+Open the URL shown in the terminal (usually `http://localhost:5173`) in your browser.
+
+## What you can do
+
+- **Protocol:** Switch between ETH (Hoodi) and SOL (Devnet).
+- **Network:** Choose the network (e.g. Hoodi for Ethereum, Devnet for Solana).
+- **Theme:** Toggle light, dark, or system theme.
+- **Wallet:** Use the default wallet flow (WalletConnect for ETH, Solana Wallet Adapter for SOL) or a custom wallet.
+
+The staking UI is loaded in an iframe from Figment; your token in `VITE_DAPP_TOKEN` identifies your app to that service.
diff --git a/demo/package.json b/demo/package.json
index 9687321..4e9f337 100644
--- a/demo/package.json
+++ b/demo/package.json
@@ -10,7 +10,7 @@
"preview": "vite preview"
},
"dependencies": {
- "@figmentio/elements": "^2.1.0",
+ "@figmentio/elements": "^2.1.1",
"@solana/web3.js": "1.98.2",
"buffer": "^6.0.3",
"lucide-react": "^0.344.0",
diff --git a/demo/pnpm-lock.yaml b/demo/pnpm-lock.yaml
index 03b2539..f234ab4 100644
--- a/demo/pnpm-lock.yaml
+++ b/demo/pnpm-lock.yaml
@@ -9,8 +9,8 @@ importers:
.:
dependencies:
'@figmentio/elements':
- specifier: ^2.1.0
- version: 2.1.0
+ specifier: ^2.1.1
+ version: 2.1.1
'@solana/web3.js':
specifier: 1.98.2
version: 1.98.2(bufferutil@4.0.9)(typescript@5.7.2)(utf-8-validate@5.0.10)
@@ -358,8 +358,8 @@ packages:
resolution: {integrity: sha512-43/qtrDUokr7LJqoF2c3+RInu/t4zfrpYdoSDfYyhg52rwLV6TnOvdG4fXm7IkSB3wErkcmJS9iEhjVtOSEjjA==}
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
- '@figmentio/elements@2.1.0':
- resolution: {integrity: sha512-exj4Em55lPHOga4y8wmYd8T0b1BtJnGrLltimx/18y1nlVT8S819qcF48rznoJPBQjLnc+g+/YxOOXxKAjtMjw==}
+ '@figmentio/elements@2.1.1':
+ resolution: {integrity: sha512-ws0JAG8BiTwFRPIyFR9zSbXq0vQT2PzMYS5zHF+dYh0yqT+RBJmFLQFdCFpJgbRkIeQmhTMS8hBKJ3o8gRVqrQ==}
'@humanfs/core@0.19.1':
resolution: {integrity: sha512-5DyQ4+1JEUzejeK1JGICcideyfUbGixgS9jNgex5nqkW+cY7WZhxBigmieN5Qnw9ZosSNVC9KQKyb+GUaGyKUA==}
@@ -1870,7 +1870,7 @@ snapshots:
'@eslint/core': 0.17.0
levn: 0.4.1
- '@figmentio/elements@2.1.0': {}
+ '@figmentio/elements@2.1.1': {}
'@humanfs/core@0.19.1': {}
diff --git a/demo/src/App.tsx b/demo/src/App.tsx
index 7c9109a..d4e2460 100644
--- a/demo/src/App.tsx
+++ b/demo/src/App.tsx
@@ -7,18 +7,18 @@ function App() {
const [primaryColor, setPrimaryColor] = React.useState("#004039");
const [secondaryColor, setSecondaryColor] = React.useState("#10B981");
const [walletType, setWalletType] = React.useState<"default" | "custom">(
- "default"
+ "default",
);
const [selectedProtocol, setSelectedProtocol] = React.useState({
name: "ETH",
id: "ethereum",
});
const [selectedNetwork, setSelectedNetwork] = React.useState({
- name: "Mainnet",
- id: "mainnet",
+ name: "Hoodi",
+ id: "hoodi",
});
const [theme, setTheme] = React.useState<"light" | "dark" | "system">(
- "system"
+ "system",
);
return (
diff --git a/demo/src/components/MainContent.tsx b/demo/src/components/MainContent.tsx
index b002c74..2861459 100644
--- a/demo/src/components/MainContent.tsx
+++ b/demo/src/components/MainContent.tsx
@@ -39,11 +39,11 @@ export function MainContent({
const encodedMessage = new TextEncoder().encode(message);
const signedMessage = await provider.signMessage(
encodedMessage,
- "utf8"
+ "utf8",
);
const signature = Buffer.from(signedMessage.signature).toString(
- "base64"
+ "base64",
);
if (!signature) throw new Error("Failed to sign message");
@@ -70,7 +70,7 @@ export function MainContent({
signMessage: async (message: string) => {
const signature = await window?.tomo_btc?.signMessage(
message,
- "bip322-simple"
+ "bip322-simple",
);
if (!signature) throw new Error("Failed to sign message");
return signature;
@@ -130,7 +130,7 @@ export function MainContent({
UI components for embeddable staking
-
+
{(walletType === "custom" ? wallet.address : true) && (
= {
ethereum: [
- { name: "Holesky", id: "holesky" },
+ { name: "Hoodi", id: "hoodi" },
{ name: "Mainnet", id: "mainnet", disabled: true },
],
solana: [
diff --git a/demo/src/components/ToggleGroup.tsx b/demo/src/components/ToggleGroup.tsx
index b2cad36..c4b8883 100644
--- a/demo/src/components/ToggleGroup.tsx
+++ b/demo/src/components/ToggleGroup.tsx
@@ -29,7 +29,7 @@ const getIcon = (value: string) => {
return ;
case "mainnet":
return ;
- case "holesky":
+ case "hoodi":
case "devnet":
case "signet":
return ;
@@ -46,7 +46,7 @@ const shouldShowIcon = (value: string) => {
"babylon",
"solana",
"mainnet",
- "holesky",
+ "hoodi",
"devnet",
"signet",
].includes(value);
@@ -65,7 +65,7 @@ export function ToggleGroup({
{items.map((item) => (
@@ -81,7 +81,7 @@ export function ToggleGroup({
: "text-[#6E938E] hover:text-[#004039]",
item.disabled &&
"opacity-50 cursor-not-allowed hover:text-[#9DB5B2]",
- shouldShowIcon(item.value) && "text-current"
+ shouldShowIcon(item.value) && "text-current",
)}
>
{shouldShowIcon(item.value) && (
@@ -93,7 +93,7 @@ export function ToggleGroup({
item.value === "mainnet" ||
item.value.includes("net")
? "text-current"
- : ""
+ : "",
)}
>
{getIcon(item.value)}
diff --git a/demo/src/vite-env.d.ts b/demo/src/vite-env.d.ts
index 11f02fe..7637fb8 100644
--- a/demo/src/vite-env.d.ts
+++ b/demo/src/vite-env.d.ts
@@ -1 +1,9 @@
///
+
+interface ImportMetaEnv {
+ readonly VITE_DAPP_TOKEN: string;
+}
+
+interface ImportMeta {
+ readonly env: ImportMetaEnv;
+}