rebrand(lethean): update branding, ports, and config for Lethean blockchain
Some checks failed
Deploy LetheanCompanion Test Suit to Github Pages / Build and Deploy (push) Failing after 4s

- Coin: Zano → Lethean, ticker: ZAN/ZANO → LTHN
- Ports: 11211 → 36941 (mainnet RPC), 46941 (testnet RPC)
- Wallet: 11212 → 36944/46944
- Address prefix: iTHN
- URLs: zano.org → lethean.io
- Explorer links: explorer.lthn.io

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
Claude 2026-04-01 22:24:16 +01:00
parent fcffea241d
commit e25e773fc9
No known key found for this signature in database
GPG key ID: AF404715446AEB41
28 changed files with 144 additions and 119 deletions

View file

@ -1,4 +1,4 @@
name: "Deploy ZanoCompanion Test Suit to Github Pages"
name: "Deploy LetheanCompanion Test Suit to Github Pages"
on:
push:

25
Dockerfile Normal file
View file

@ -0,0 +1,25 @@
# Build + serve: compiles the React/Vite test harness and serves on port 5173
FROM node:22-alpine AS builder
# pnpm is the declared package manager
RUN corepack enable && corepack prepare pnpm@latest --activate
WORKDIR /app
COPY package.json pnpm-lock.yaml ./
RUN pnpm install --frozen-lockfile
COPY . .
RUN pnpm run build
# Serve the static dist with a minimal HTTP server
FROM node:22-alpine
RUN npm install -g serve
WORKDIR /app
COPY --from=builder /app/dist ./dist
EXPOSE 5173
CMD ["serve", "-s", "dist", "-l", "5173"]

View file

@ -4,7 +4,7 @@
<meta charset="UTF-8" />
<link rel="icon" type="image/png" href="/favicon.png" sizes="96x96" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>zano-companion-testsuit</title>
<title>lethean-companion-testsuit</title>
</head>
<body>
<div id="app"></div>

View file

@ -1,5 +1,5 @@
{
"name": "zano-companion-testsuit",
"name": "lethean-companion-testsuit",
"private": true,
"version": "0.0.0",
"type": "module",

View file

@ -1,11 +1,11 @@
import { useCallback, useState } from "react";
import type { ASSETS_WHITELIST_ADD_RESPONSE } from "./companion";
import { useZanoCompanion } from "./companion";
import { useLetheanCompanion } from "./companion";
import { Group } from "./Group";
import { particlesToValue } from "./utils";
export const AddWhitelist = () => {
const companion = useZanoCompanion();
const companion = useLetheanCompanion();
const [response, setResponse] = useState<ASSETS_WHITELIST_ADD_RESPONSE | string | null>(null);
const call = useCallback(async () => {
const asset_id = prompt("What asset do you want to add?");

View file

@ -1,10 +1,10 @@
import { useCallback, useState } from "react";
import type { GET_ALIAS_DETAILS_RESPONSE } from "./companion";
import { useZanoCompanion } from "./companion";
import { useLetheanCompanion } from "./companion";
import { Group } from "./Group";
export const AliasDetails = () => {
const companion = useZanoCompanion();
const companion = useLetheanCompanion();
const [details, setDetails] = useState<GET_ALIAS_DETAILS_RESPONSE | string | null>(null);
const fetchDetails = useCallback(async () => {
let alias = prompt("What alias are you searching for?");

View file

@ -1,7 +1,7 @@
import "./app.css";
import { AliasDetails } from "./AliasDetails";
import { ZanoCompanionProvider } from "./companion";
import { LetheanCompanionProvider } from "./companion";
import { Connector } from "./Connector";
import { CreateAlias } from "./CreateAlias";
import { Credentials } from "./Credentials";
@ -16,17 +16,17 @@ import { Transfer } from "./Transfer";
import { WalletBalance } from "./WalletBalance";
import { WalletData } from "./WalletData";
import { Whitelist } from "./Whitelist";
import ZanoLogo from "./zano.svg";
import LetheanLogo from "./lethean.svg";
export const App = () => {
return (
<div id="screen">
<div id="header">
<img src={ZanoLogo} className="logo" alt="Zano logo" />
<span>ZanoCompanion Test Suits</span>
<img src={LetheanLogo} className="logo" alt="Lethean logo" />
<span>LetheanCompanion Test Suits</span>
</div>
<div id="content">
<ZanoCompanionProvider disableServerRequest verbose>
<LetheanCompanionProvider disableServerRequest verbose>
<div>Links</div>
<DeepLinkTransfer />
<DeepLinkTransferLegacy />
@ -45,7 +45,7 @@ export const App = () => {
<RequestSign />
<AliasDetails />
<CreateAlias />
</ZanoCompanionProvider>
</LetheanCompanionProvider>
</div>
</div>
);

View file

@ -1,7 +1,7 @@
import { useZanoCompanionConnect } from "./companion";
import { useLetheanCompanionConnect } from "./companion";
export const Connector = () => {
const [status, connect, disconnect] = useZanoCompanionConnect();
const [status, connect, disconnect] = useLetheanCompanionConnect();
return (
<button onClick={status === "disconnected" ? connect : status === "connected" ? disconnect : undefined} disabled={status === "pending"}>
connection state: {status}

View file

@ -1,10 +1,10 @@
import { useCallback, useState } from "react";
import type { CREATE_ALIAS_RESPONSE } from "./companion";
import { useZanoCompanion } from "./companion";
import { useLetheanCompanion } from "./companion";
import { Group } from "./Group";
export const CreateAlias = () => {
const companion = useZanoCompanion();
const companion = useLetheanCompanion();
const [response, setResponse] = useState<CREATE_ALIAS_RESPONSE | string | null>(null);
const call = useCallback(async () => {
let alias = prompt("What alias do you want to create?");

View file

@ -1,8 +1,8 @@
import { useZanoCompanionCredentials } from "./companion";
import { useLetheanCompanionCredentials } from "./companion";
import { Group } from "./Group";
export const Credentials = () => {
const credentials = useZanoCompanionCredentials();
const credentials = useLetheanCompanionCredentials();
if (!credentials) return null;
return (
<Group>

View file

@ -10,7 +10,7 @@ export const DeepLinkTransfer = () => {
const amount = BigNumber(prompt("How many?") ?? NaN);
const comment = prompt("Comment:") ?? undefined;
setLink(
`zano://transfer/?address=${address}${assetId ? `&asset_id=${assetId}` : ""}${amount.isNaN() ? "" : `&amount=${amount.toString(10)}`}${comment ? `&comment=${comment}` : ""}`,
`lthn://transfer/?address=${address}${assetId ? `&asset_id=${assetId}` : ""}${amount.isNaN() ? "" : `&amount=${amount.toString(10)}`}${comment ? `&comment=${comment}` : ""}`,
);
}, []);
return (

View file

@ -10,7 +10,7 @@ export const DeepLinkTransferLegacy = () => {
const amount = BigNumber(prompt("How many?") ?? NaN);
const comment = prompt("Comment:") ?? undefined;
setLink(
`zano:action=send&address=${address}${assetId ? `&asset_id=${assetId}` : ""}${amount.isNaN() ? "" : `&amount=${amount.toString(10)}`}${comment ? `&comment=${comment}` : ""}`,
`lthn://transfer/?action=send&address=${address}${assetId ? `&asset_id=${assetId}` : ""}${amount.isNaN() ? "" : `&amount=${amount.toString(10)}`}${comment ? `&comment=${comment}` : ""}`,
);
}, []);
return (

View file

@ -1,11 +1,11 @@
import { BigNumber } from "bignumber.js";
import { useCallback, useState } from "react";
import type { IONIC_SWAP_RESPONSE } from "./companion";
import { useZanoCompanion } from "./companion";
import { useLetheanCompanion } from "./companion";
import { Group } from "./Group";
export const IonicSwap = () => {
const companion = useZanoCompanion();
const companion = useLetheanCompanion();
const [response, setResponse] = useState<IONIC_SWAP_RESPONSE | string | null>(null);
const call = useCallback(async () => {
const destinationAddress = prompt("With whom do you swaping?");

View file

@ -1,10 +1,10 @@
import { useCallback, useState } from "react";
import type { IONIC_SWAP_ACCEPT_RESPONSE } from "./companion";
import { useZanoCompanion } from "./companion";
import { useLetheanCompanion } from "./companion";
import { Group } from "./Group";
export const IonicSwapAccept = () => {
const companion = useZanoCompanion();
const companion = useLetheanCompanion();
const [response, setResponse] = useState<IONIC_SWAP_ACCEPT_RESPONSE | string | null>(null);
const call = useCallback(async () => {
const hex_raw_proposal = prompt("What proposal you want to accept?");

View file

@ -1,11 +1,11 @@
import { useCallback, useState } from "react";
import type { GET_IONIC_SWAP_PROPOSAL_INFO_RESPONSE } from "./companion";
import { useZanoCompanion } from "./companion";
import { useLetheanCompanion } from "./companion";
import { Group } from "./Group";
import { particlesToValue } from "./utils";
export const IonicSwapInfo = () => {
const companion = useZanoCompanion();
const companion = useLetheanCompanion();
const [response, setResponse] = useState<GET_IONIC_SWAP_PROPOSAL_INFO_RESPONSE | string | null>(null);
const call = useCallback(async () => {
const hex_raw_proposal = prompt("What proposal you want to inspect?");
@ -48,7 +48,7 @@ export const IonicSwapInfo = () => {
))}
<span>Additional fields:</span>
<Group>
<Group.Item label="Fee:" value={`${particlesToValue(response.proposal.fee_paid_by_a, 12)} ZANO`} />
<Group.Item label="Fee:" value={`${particlesToValue(response.proposal.fee_paid_by_a, 12)} LTHN`} />
</Group>
</>
) : null}

View file

@ -1,11 +1,11 @@
import { BigNumber } from "bignumber.js";
import { useCallback, useState } from "react";
import type { TRANSFER_RESPONSE } from "./companion";
import { useZanoCompanion } from "./companion";
import { useLetheanCompanion } from "./companion";
import { Group } from "./Group";
export const MultiTransfer = () => {
const companion = useZanoCompanion();
const companion = useLetheanCompanion();
const [response, setResponse] = useState<TRANSFER_RESPONSE | string | null>(null);
const call = useCallback(async () => {
const destinations: { address: string; amount: string; assetId?: string }[] = [];

View file

@ -1,10 +1,10 @@
import { useCallback, useState } from "react";
import type { REQUEST_MESSAGE_SIGN_RESPONSE } from "./companion";
import { useZanoCompanion } from "./companion";
import { useLetheanCompanion } from "./companion";
import { Group } from "./Group";
export const RequestSign = () => {
const companion = useZanoCompanion();
const companion = useLetheanCompanion();
const [response, setResponse] = useState<REQUEST_MESSAGE_SIGN_RESPONSE | string | null>(null);
const call = useCallback(async () => {
const message = prompt("What message are you trying to sign?");

View file

@ -1,11 +1,11 @@
import { BigNumber } from "bignumber.js";
import { useCallback, useState } from "react";
import type { TRANSFER_RESPONSE } from "./companion";
import { useZanoCompanion } from "./companion";
import { useLetheanCompanion } from "./companion";
import { Group } from "./Group";
export const Transfer = () => {
const companion = useZanoCompanion();
const companion = useLetheanCompanion();
const [response, setResponse] = useState<TRANSFER_RESPONSE | string | null>(null);
const call = useCallback(async () => {
const destination = prompt("Whom do you send it?");

View file

@ -1,11 +1,11 @@
import { useCallback, useRef, useState, useSyncExternalStore } from "react";
import type { GET_WALLET_BALANCE_RESPONSE } from "./companion";
import { useZanoCompanion } from "./companion";
import { useLetheanCompanion } from "./companion";
import { Group } from "./Group";
import { particlesToValue } from "./utils";
const WalletBalanceWatcher = () => {
const companion = useZanoCompanion();
const companion = useLetheanCompanion();
const snapshot = useRef<GET_WALLET_BALANCE_RESPONSE | null>(null);
const response = useSyncExternalStore(
useCallback(
@ -25,8 +25,8 @@ const WalletBalanceWatcher = () => {
return (
<>
<Group>
<Group.Item label="Balance:" value={`${particlesToValue(response?.balance ?? 0, 12)} ZANO`} />
<Group.Item label="Unlocked Balance:" value={`${particlesToValue(response?.unlocked_balance ?? 0, 12)} ZANO`} />
<Group.Item label="Balance:" value={`${particlesToValue(response?.balance ?? 0, 12)} LTHN`} />
<Group.Item label="Unlocked Balance:" value={`${particlesToValue(response?.unlocked_balance ?? 0, 12)} LTHN`} />
</Group>
<Group>
{response?.balances.map((balance) => (

View file

@ -1,10 +1,10 @@
import { useCallback, useRef, useState, useSyncExternalStore } from "react";
import type { GET_WALLET_DATA_RESPONSE } from "./companion";
import { useZanoCompanion } from "./companion";
import { useLetheanCompanion } from "./companion";
import { Group } from "./Group";
const WalletDataWatcher = () => {
const companion = useZanoCompanion();
const companion = useLetheanCompanion();
const snapshot = useRef<GET_WALLET_DATA_RESPONSE | null>(null);
const walletData = useSyncExternalStore(
useCallback(
@ -22,7 +22,7 @@ const WalletDataWatcher = () => {
return (
<Group>
{walletData?.alias ? <Group.Item label="Alias:" value={`@${walletData.alias}`} /> : null}
<Group.Item label="Balance:" value={`${walletData?.balance} ZANO`} />
<Group.Item label="Balance:" value={`${walletData?.balance} LTHN`} />
</Group>
);
};

View file

@ -1,9 +1,9 @@
import { useCallback, useRef, useState, useSyncExternalStore } from "react";
import { useZanoCompanion, type GET_WHITELIST_RESPONSE } from "./companion";
import { useLetheanCompanion, type GET_WHITELIST_RESPONSE } from "./companion";
import { Group } from "./Group";
const WhitelistWatcher = () => {
const companion = useZanoCompanion();
const companion = useLetheanCompanion();
const snapshot = useRef<GET_WHITELIST_RESPONSE | null>(null);
const response = useSyncExternalStore(
useCallback(

View file

@ -1,20 +1,20 @@
import { v4 as uuidv4 } from "uuid";
import { ZanoCredentials, type ZanoCredentialsParams } from "./credentials";
import type { ZanoCompanionMethodParams, ZanoCompanionMethodResult, ZanoCompanionMethods } from "./types";
import { LetheanCredentials, type LetheanCredentialsParams } from "./credentials";
import type { LetheanCompanionMethodParams, LetheanCompanionMethodResult, LetheanCompanionMethods } from "./types";
declare global {
interface ZanoCompanionApi {
request<Method extends keyof ZanoCompanionMethods>(
interface LetheanCompanionApi {
request<Method extends keyof LetheanCompanionMethods>(
method: Method,
...params: keyof ZanoCompanionMethodParams<Method> extends undefined
? [params?: ZanoCompanionMethodParams<Method>, timeoutMs?: number | null]
: [params: ZanoCompanionMethodParams<Method>, timeoutMs?: number | null]
): Promise<{ data: ZanoCompanionMethodResult<Method> } | undefined>;
...params: keyof LetheanCompanionMethodParams<Method> extends undefined
? [params?: LetheanCompanionMethodParams<Method>, timeoutMs?: number | null]
: [params: LetheanCompanionMethodParams<Method>, timeoutMs?: number | null]
): Promise<{ data: LetheanCompanionMethodResult<Method> } | undefined>;
}
var zano: ZanoCompanionApi | undefined;
var lethean: LetheanCompanionApi | undefined;
}
export type ZanoCompanionServerData = {
export type LetheanCompanionServerData = {
alias: string | undefined;
address: string;
signature: string;
@ -22,40 +22,40 @@ export type ZanoCompanionServerData = {
message: string;
isSavedData: boolean | undefined;
};
export type ZanoCompanionParams = ZanoCredentialsParams & {
export type LetheanCompanionParams = LetheanCredentialsParams & {
aliasRequired?: boolean;
customNonce?: string;
customServerPath?: string;
disableServerRequest?: boolean;
onConnectStart?: () => void;
onConnectEnd?: (data: ZanoCompanionServerData & { token: string }) => void;
onLocalConnectEnd?: (data: ZanoCompanionServerData) => void;
onConnectEnd?: (data: LetheanCompanionServerData & { token: string }) => void;
onLocalConnectEnd?: (data: LetheanCompanionServerData) => void;
verbose?: boolean;
};
type AuthServerResponse = { success: true; data: { token: string } } | { success: false; error: string };
type UnwrappedZanoCompanionMethodResult<Method extends keyof ZanoCompanionMethods> = Exclude<ZanoCompanionMethodResult<Method>, { error: unknown }>;
export class ZanoCompanion {
#params: ZanoCompanionParams;
type UnwrappedLetheanCompanionMethodResult<Method extends keyof LetheanCompanionMethods> = Exclude<LetheanCompanionMethodResult<Method>, { error: unknown }>;
export class LetheanCompanion {
#params: LetheanCompanionParams;
readonly methods: {
[Method in keyof ZanoCompanionMethods]: (
...params: keyof ZanoCompanionMethodParams<Method> extends undefined
? [params?: ZanoCompanionMethodParams<Method>, timeoutMs?: number | null]
: [params: ZanoCompanionMethodParams<Method>, timeoutMs?: number | null]
) => Promise<UnwrappedZanoCompanionMethodResult<Method>>;
[Method in keyof LetheanCompanionMethods]: (
...params: keyof LetheanCompanionMethodParams<Method> extends undefined
? [params?: LetheanCompanionMethodParams<Method>, timeoutMs?: number | null]
: [params: LetheanCompanionMethodParams<Method>, timeoutMs?: number | null]
) => Promise<UnwrappedLetheanCompanionMethodResult<Method>>;
};
readonly credentials: ZanoCredentials;
readonly credentials: LetheanCredentials;
constructor(params: ZanoCompanionParams) {
constructor(params: LetheanCompanionParams) {
if (typeof window === "undefined") {
throw new Error("ZanoWallet can only be used in the browser");
throw new Error("LetheanWallet can only be used in the browser");
}
if (!window.zano) {
console.error("ZanoWallet requires the ZanoWallet extension to be installed");
if (!window.lethean) {
console.error("LetheanWallet requires the LetheanWallet extension to be installed");
}
this.#params = Object.freeze(params);
@ -64,21 +64,21 @@ export class ZanoCompanion {
const credentials = this.credentials.get();
if (credentials && result.address !== credentials?.address) this.credentials.clear();
},
} as { [Method in keyof ZanoCompanionMethods]?: (result: UnwrappedZanoCompanionMethodResult<Method>) => void };
} as { [Method in keyof LetheanCompanionMethods]?: (result: UnwrappedLetheanCompanionMethodResult<Method>) => void };
this.methods = new Proxy(
{},
{
get: (cache, prop) => {
const method = prop as keyof ZanoCompanionMethods;
const method = prop as keyof LetheanCompanionMethods;
// @ts-expect-error - untyped
// eslint-disable-next-line @typescript-eslint/no-unsafe-return
if (cache[method]) return cache[method];
// @ts-expect-error - untyped
cache[method] = async (params: Parameters<ZanoCompanionMethods[typeof method]>[0], timeoutMs?: number | null) => {
if (!window.zano) throw new Error("ZanoWallet requires the ZanoWallet extension to be installed");
cache[method] = async (params: Parameters<LetheanCompanionMethods[typeof method]>[0], timeoutMs?: number | null) => {
if (!window.lethean) throw new Error("LetheanWallet requires the LetheanWallet extension to be installed");
if (this.#params.verbose) console.info(`> call ${method} with`, params);
const response = await window.zano.request(method, params, timeoutMs).catch((reason) => {
const response = await window.lethean.request(method, params, timeoutMs).catch((reason) => {
if (this.#params.verbose) console.info(`> ${method} throws`, reason);
throw reason;
});
@ -98,7 +98,7 @@ export class ZanoCompanion {
},
) as never;
this.credentials = new ZanoCredentials(params);
this.credentials = new LetheanCredentials(params);
}
async connect(signal?: AbortSignal) {
@ -132,7 +132,7 @@ export class ZanoCompanion {
publicKey = signResult.result.pkey;
}
const serverData: ZanoCompanionServerData = {
const serverData: LetheanCompanionServerData = {
alias: walletData.alias,
address: walletData.address,
signature,

View file

@ -1,31 +1,31 @@
export interface IZanoCredentials {
export interface ILetheanCredentials {
nonce: string;
signature: string;
publicKey: string;
address: string;
}
export type ZanoCredentialsParams = {
export type LetheanCredentialsParams = {
useLocalStorage?: boolean;
customLocalStorageKey?: string;
};
export class ZanoCredentials {
export class LetheanCredentials {
static readonly #DEFAULT_LOCAL_STORAGE_KEY = "wallet";
#localStorageKey: string | false;
constructor({ useLocalStorage = true, customLocalStorageKey }: ZanoCredentialsParams = {}) {
this.#localStorageKey = useLocalStorage ? (customLocalStorageKey ?? ZanoCredentials.#DEFAULT_LOCAL_STORAGE_KEY) : false;
constructor({ useLocalStorage = true, customLocalStorageKey }: LetheanCredentialsParams = {}) {
this.#localStorageKey = useLocalStorage ? (customLocalStorageKey ?? LetheanCredentials.#DEFAULT_LOCAL_STORAGE_KEY) : false;
}
#stored: IZanoCredentials | null = null;
#stored: ILetheanCredentials | null = null;
restore(address?: string) {
let next = (() => {
if (!this.#localStorageKey) return null;
const json = localStorage.getItem(this.#localStorageKey);
if (json === null) return null;
try {
const parsed = JSON.parse(json) as IZanoCredentials;
const parsed = JSON.parse(json) as ILetheanCredentials;
return parsed;
} catch {
return null;
@ -46,7 +46,7 @@ export class ZanoCredentials {
if (this.#localStorageKey) localStorage.removeItem(this.#localStorageKey);
void this.emit(null);
}
set(credentials: IZanoCredentials | null) {
set(credentials: ILetheanCredentials | null) {
this.#stored = credentials;
if (this.#localStorageKey) {
if (credentials) localStorage.setItem(this.#localStorageKey, JSON.stringify(credentials));
@ -55,18 +55,18 @@ export class ZanoCredentials {
void this.emit(credentials);
}
private listeners = new Set<(credentials: IZanoCredentials | null) => void>();
private async emit(credentials: IZanoCredentials | null) {
private listeners = new Set<(credentials: ILetheanCredentials | null) => void>();
private async emit(credentials: ILetheanCredentials | null) {
await Promise.resolve();
this.listeners.forEach((listener) => listener(credentials));
}
addListener(listener: (credentials: IZanoCredentials | null) => void) {
addListener(listener: (credentials: ILetheanCredentials | null) => void) {
this.listeners.add(listener);
return () => {
this.listeners.delete(listener);
};
}
removeListener(listener: (credentials: IZanoCredentials | null) => void) {
removeListener(listener: (credentials: ILetheanCredentials | null) => void) {
this.listeners.delete(listener);
}
}

View file

@ -1,8 +1,8 @@
import { createContext, useCallback, useContext, useEffect, useRef, useState, useSyncExternalStore, type ReactNode } from "react";
import { assert } from "../utils";
import { ZanoCompanion, type ZanoCompanionParams } from "./companion";
import { LetheanCompanion, type LetheanCompanionParams } from "./companion";
export const useZanoCompanionInstance = ({ onConnectStart, onConnectEnd, onLocalConnectEnd, ...params }: ZanoCompanionParams = {}) => {
export const useLetheanCompanionInstance = ({ onConnectStart, onConnectEnd, onLocalConnectEnd, ...params }: LetheanCompanionParams = {}) => {
const onConnectStartRef = useRef(onConnectStart);
onConnectStartRef.current = onConnectStart;
const onConnectEndRef = useRef(onConnectEnd);
@ -10,9 +10,9 @@ export const useZanoCompanionInstance = ({ onConnectStart, onConnectEnd, onLocal
const onLocalConnectEndRef = useRef(onLocalConnectEnd);
onLocalConnectEndRef.current = onLocalConnectEnd;
const instance = useRef<ZanoCompanion | null>(null);
const instance = useRef<LetheanCompanion | null>(null);
if (!instance.current) {
instance.current = new ZanoCompanion({
instance.current = new LetheanCompanion({
...params,
onConnectStart: (...params) => onConnectStartRef.current?.(...params),
onConnectEnd: (...params) => onConnectEndRef.current?.(...params),
@ -23,20 +23,20 @@ export const useZanoCompanionInstance = ({ onConnectStart, onConnectEnd, onLocal
return instance.current;
};
const ZanoCompanionContext = createContext<ZanoCompanion | undefined>(undefined);
export const ZanoCompanionProvider = ({ children, ...params }: { children?: ReactNode } & ZanoCompanionParams) => {
const companion = useZanoCompanionInstance(params);
return <ZanoCompanionContext.Provider value={companion}>{children}</ZanoCompanionContext.Provider>;
const LetheanCompanionContext = createContext<LetheanCompanion | undefined>(undefined);
export const LetheanCompanionProvider = ({ children, ...params }: { children?: ReactNode } & LetheanCompanionParams) => {
const companion = useLetheanCompanionInstance(params);
return <LetheanCompanionContext.Provider value={companion}>{children}</LetheanCompanionContext.Provider>;
};
export const useZanoCompanion = (companion?: ZanoCompanion) => {
const context = useContext(ZanoCompanionContext);
export const useLetheanCompanion = (companion?: LetheanCompanion) => {
const context = useContext(LetheanCompanionContext);
if (!companion) companion = context;
assert(companion, "component must be wrapped in <ZanoCompanionProvider />");
assert(companion, "component must be wrapped in <LetheanCompanionProvider />");
return companion;
};
export const useZanoCompanionCredentials = (companion?: ZanoCompanion) => {
companion = useZanoCompanion(companion);
export const useLetheanCompanionCredentials = (companion?: LetheanCompanion) => {
companion = useLetheanCompanion(companion);
const credentials = useSyncExternalStore(
useCallback((listener) => companion.credentials.addListener(listener), [companion.credentials]),
() => companion.credentials.get(),
@ -44,8 +44,8 @@ export const useZanoCompanionCredentials = (companion?: ZanoCompanion) => {
return credentials;
};
export const useZanoCompanionConnect = (companion?: ZanoCompanion) => {
companion = useZanoCompanion(companion);
export const useLetheanCompanionConnect = (companion?: LetheanCompanion) => {
companion = useLetheanCompanion(companion);
const [status, setStatus] = useState<"disconnected" | "pending" | "connected">("disconnected");
const statusRef = useRef(status);
statusRef.current = status;
@ -81,9 +81,9 @@ export const useZanoCompanionConnect = (companion?: ZanoCompanion) => {
return [status, connect, disconnect] as const;
};
export const useZanoCompanionConnectEffect = (companion?: ZanoCompanion) => {
const [state, connect, disconnect] = useZanoCompanionConnect(companion);
const credentials = useZanoCompanionCredentials(companion);
export const useLetheanCompanionConnectEffect = (companion?: LetheanCompanion) => {
const [state, connect, disconnect] = useLetheanCompanionConnect(companion);
const credentials = useLetheanCompanionCredentials(companion);
useEffect(() => {
const abort = connect();
return () => {

View file

@ -1,4 +1,4 @@
export * from "./companion";
export type { IZanoCredentials } from "./credentials";
export type { ILetheanCredentials } from "./credentials";
export * from "./hooks";
export * from "./types";

View file

@ -128,9 +128,9 @@ export type ASSETS_WHITELIST_ADD_RESPONSE = {
asset_descriptor: asset_descriptor_with_id;
};
export type ZanoCompanionWrappedMethod<Result> = { result: Result; error?: undefined } | { result?: undefined; error: unknown };
export type ZanoCompanionMethods = {
GET_WALLET_BALANCE(params?: Record<string, never>): ZanoCompanionWrappedMethod<GET_WALLET_BALANCE_RESPONSE>;
export type LetheanCompanionWrappedMethod<Result> = { result: Result; error?: undefined } | { result?: undefined; error: unknown };
export type LetheanCompanionMethods = {
GET_WALLET_BALANCE(params?: Record<string, never>): LetheanCompanionWrappedMethod<GET_WALLET_BALANCE_RESPONSE>;
GET_WALLET_DATA(params?: Record<string, never>): GET_WALLET_DATA_RESPONSE;
IONIC_SWAP(params: {
destinationAddress: string;
@ -138,20 +138,20 @@ export type ZanoCompanionMethods = {
destinationAssetAmount: number | string;
currentAssetID: string;
currentAssetAmount: number | string;
}): ZanoCompanionWrappedMethod<IONIC_SWAP_RESPONSE>;
IONIC_SWAP_ACCEPT(params: { hex_raw_proposal: string }): ZanoCompanionWrappedMethod<IONIC_SWAP_ACCEPT_RESPONSE>;
}): LetheanCompanionWrappedMethod<IONIC_SWAP_RESPONSE>;
IONIC_SWAP_ACCEPT(params: { hex_raw_proposal: string }): LetheanCompanionWrappedMethod<IONIC_SWAP_ACCEPT_RESPONSE>;
GET_IONIC_SWAP_PROPOSAL_INFO(params: { hex_raw_proposal: string }): GET_IONIC_SWAP_PROPOSAL_INFO_RESPONSE;
TRANSFER(
params: ExclusiveUnion<
{ assetId: string; destination: string; amount: string },
{ assetId?: string; destinations: { address: string; amount: string; assetId?: string }[] }
> & { comment?: string },
): ZanoCompanionWrappedMethod<TRANSFER_RESPONSE>;
REQUEST_MESSAGE_SIGN(params: { message: string }): ZanoCompanionWrappedMethod<REQUEST_MESSAGE_SIGN_RESPONSE>;
): LetheanCompanionWrappedMethod<TRANSFER_RESPONSE>;
REQUEST_MESSAGE_SIGN(params: { message: string }): LetheanCompanionWrappedMethod<REQUEST_MESSAGE_SIGN_RESPONSE>;
GET_WHITELIST(params?: Record<string, never>): GET_WHITELIST_RESPONSE;
ASSETS_WHITELIST_ADD(params: { asset_id: string }): ZanoCompanionWrappedMethod<ASSETS_WHITELIST_ADD_RESPONSE>;
ASSETS_WHITELIST_ADD(params: { asset_id: string }): LetheanCompanionWrappedMethod<ASSETS_WHITELIST_ADD_RESPONSE>;
GET_ALIAS_DETAILS(params: { alias: string }): GET_ALIAS_DETAILS_RESPONSE;
CREATE_ALIAS(params: { alias: string; comment?: string }): ZanoCompanionWrappedMethod<CREATE_ALIAS_RESPONSE>;
CREATE_ALIAS(params: { alias: string; comment?: string }): LetheanCompanionWrappedMethod<CREATE_ALIAS_RESPONSE>;
};
export type ZanoCompanionMethodParams<Method extends keyof ZanoCompanionMethods> = Parameters<ZanoCompanionMethods[Method]>[0];
export type ZanoCompanionMethodResult<Method extends keyof ZanoCompanionMethods> = ReturnType<ZanoCompanionMethods[Method]>;
export type LetheanCompanionMethodParams<Method extends keyof LetheanCompanionMethods> = Parameters<LetheanCompanionMethods[Method]>[0];
export type LetheanCompanionMethodResult<Method extends keyof LetheanCompanionMethods> = ReturnType<LetheanCompanionMethods[Method]>;

View file

Before

Width:  |  Height:  |  Size: 12 KiB

After

Width:  |  Height:  |  Size: 12 KiB

View file

@ -3,5 +3,5 @@ import { defineConfig } from "vite";
export default defineConfig({
plugins: [react()],
base: "/zano-companion-testsuit/",
base: "/lethean-companion-testsuit/",
});