Merge branch 'dev'
CI/CD / deploy (push) Failing after 2m17s Details

This commit is contained in:
Jeff Emmett 2026-04-10 19:16:19 -04:00
commit 5ee8e9a5ca
6 changed files with 146 additions and 3 deletions

View File

@ -74,6 +74,8 @@ const CHAIN_COLORS: Record<string, string> = {
"80002": "#a855f7",
"43113": "#fb923c",
"97": "#fbbf24",
"59144": "#0E76FD",
"59141": "#3b82f6",
"local": "#22c55e",
};
@ -82,7 +84,7 @@ const COLORS_TX = { cyan: "#00d4ff", green: "#4ade80", red: "#f87171" };
const CHAIN_NAMES: Record<string, string> = {
"1": "Ethereum", "10": "Optimism", "100": "Gnosis", "137": "Polygon",
"8453": "Base", "42161": "Arbitrum", "42220": "Celo", "43114": "Avalanche",
"56": "BSC", "324": "zkSync", "local": "CRDT",
"56": "BSC", "324": "zkSync", "59144": "Linea", "local": "CRDT",
};
const EXAMPLE_WALLETS = [

View File

@ -34,6 +34,7 @@ const ZERION_CHAIN_MAP: Record<string, string> = {
avalanche: "43114",
celo: "42220",
"zksync-era": "324",
linea: "59144",
};
function getApiKey(): string | null {

View File

@ -15,6 +15,7 @@ const CHAIN_PLATFORM: Record<string, string> = {
"43114": "avalanche",
"42220": "celo",
"324": "zksync",
"59144": "linea",
};
// CoinGecko native coin IDs per chain
@ -29,6 +30,7 @@ const NATIVE_COIN_ID: Record<string, string> = {
"43114": "avalanche-2",
"42220": "celo",
"324": "ethereum",
"59144": "ethereum",
};
interface CacheEntry {

View File

@ -151,6 +151,8 @@ const CHAIN_MAP: Record<string, { name: string; prefix: string }> = {
"43114": { name: "Avalanche", prefix: "avax" },
"56": { name: "BSC", prefix: "bnb" },
"324": { name: "zkSync", prefix: "zksync" },
"59144": { name: "Linea", prefix: "linea" },
"59141": { name: "Linea Sepolia", prefix: "lineasep" },
"11155111": { name: "Sepolia", prefix: "sep" },
"84532": { name: "Base Sepolia", prefix: "basesep" },
"421614": { name: "Arbitrum Sepolia", prefix: "arbsep" },
@ -160,7 +162,7 @@ const CHAIN_MAP: Record<string, { name: string; prefix: string }> = {
"97": { name: "BSC Testnet", prefix: "bsctest" },
};
const TESTNET_CHAIN_IDS = new Set(["11155111", "84532", "421614", "11155420", "80002", "43113", "97"]);
const TESTNET_CHAIN_IDS = new Set(["11155111", "84532", "421614", "11155420", "80002", "43113", "97", "59141"]);
function getChains(includeTestnets: boolean): [string, { name: string; prefix: string }][] {
return Object.entries(CHAIN_MAP).filter(([id]) => includeTestnets || !TESTNET_CHAIN_IDS.has(id));
@ -186,6 +188,8 @@ const DEFAULT_RPC_URLS: Record<string, string> = {
"43114": "https://api.avax.network/ext/bc/C/rpc",
"56": "https://bsc-dataseed.binance.org",
"324": "https://mainnet.era.zksync.io",
"59144": "https://rpc.linea.build",
"59141": "https://rpc.sepolia.linea.build",
"11155111": "https://rpc.sepolia.org",
"84532": "https://sepolia.base.org",
"421614": "https://sepolia-rollup.arbitrum.io/rpc",
@ -207,6 +211,8 @@ const CHAIN_ENV_NAMES: Record<string, { envName: string; alchemySlug?: string }>
"43114": { envName: "AVALANCHE" },
"56": { envName: "BSC" },
"324": { envName: "ZKSYNC" },
"59144": { envName: "LINEA", alchemySlug: "linea-mainnet" },
"59141": { envName: "LINEA_SEPOLIA" },
"11155111": { envName: "SEPOLIA", alchemySlug: "eth-sepolia" },
"84532": { envName: "BASE_SEPOLIA", alchemySlug: "base-sepolia" },
"421614": { envName: "ARB_SEPOLIA", alchemySlug: "arb-sepolia" },
@ -249,6 +255,8 @@ const NATIVE_TOKENS: Record<string, { name: string; symbol: string; decimals: nu
"43114": { name: "AVAX", symbol: "AVAX", decimals: 18 },
"56": { name: "BNB", symbol: "BNB", decimals: 18 },
"324": { name: "Ether", symbol: "ETH", decimals: 18 },
"59144": { name: "Ether", symbol: "ETH", decimals: 18 },
"59141": { name: "Linea Sepolia ETH", symbol: "ETH", decimals: 18 },
"11155111": { name: "Sepolia ETH", symbol: "ETH", decimals: 18 },
"84532": { name: "Base Sepolia ETH", symbol: "ETH", decimals: 18 },
"421614": { name: "Arb Sepolia ETH", symbol: "ETH", decimals: 18 },
@ -503,6 +511,11 @@ const POPULAR_TOKENS: Record<string, Array<{ address: string; name: string; symb
"80002": [
{ address: "0x41E94Eb019C0762f9Bfcf9Fb1E58725BfB0e7582", name: "USD Coin", symbol: "USDC", decimals: 6 },
],
"59144": [
{ address: "0x176211869cA2b568f2A7D4EE941E073a821EE1ff", name: "USD Coin", symbol: "USDC", decimals: 6 },
{ address: "0xe5D7C2a44FfDDf6b295A15996c1F68c7BbB2d4b0", name: "Wrapped Ether", symbol: "WETH", decimals: 18 },
{ address: "0xA219439258ca9da29E9Cc4cE5596924745e12B93", name: "Tether USD", symbol: "USDT", decimals: 6 },
],
};
// ERC-20 balanceOf(address) — selector 0x70a08231

View File

@ -3617,7 +3617,7 @@ app.post('/encryptid/api/safe/verify', async (c) => {
const CHAIN_PREFIXES: Record<number, string> = {
1: 'eth', 10: 'oeth', 100: 'gno', 137: 'pol',
8453: 'base', 42161: 'arb1', 42220: 'celo', 43114: 'avax',
56: 'bnb', 324: 'zksync', 11155111: 'sep', 84532: 'basesep',
56: 'bnb', 324: 'zksync', 59144: 'linea', 11155111: 'sep', 84532: 'basesep',
};
const prefix = CHAIN_PREFIXES[chain];
if (!prefix) {

View File

@ -0,0 +1,125 @@
/**
* WalletAdapter Chain-parameterized abstraction over Safe/EOA/UP wallets.
*
* Provides a unified interface regardless of the underlying wallet backing type
* (Gnosis Safe, raw EOA, or LUKSO Universal Profile).
*/
import type { SafeWalletEntry } from './wallet-store';
export type WalletBackingType = 'safe' | 'eoa' | 'up';
export interface WalletInfo {
/** Effective sending address (Safe address, EOA, or UP) */
address: string;
/** Underlying EOA address (from passkey-derived key) */
signerAddress: string;
/** EVM chain ID */
chainId: number;
/** Wallet backing type */
type: WalletBackingType;
/** User-assigned label */
label: string;
/** Whether a Universal Profile is associated */
hasUniversalProfile: boolean;
/** UP address if one is associated */
upAddress?: string;
}
interface WalletAdapterParams {
address: string;
signerAddress: string;
chainId: number;
type: WalletBackingType;
label: string;
upAddress?: string;
}
export class WalletAdapter {
private readonly params: WalletAdapterParams;
private constructor(params: WalletAdapterParams) {
this.params = params;
}
/**
* Create a WalletAdapter from an existing Gnosis Safe entry.
*/
static fromSafe(entry: SafeWalletEntry, eoaAddress: string): WalletAdapter {
return new WalletAdapter({
address: entry.safeAddress,
signerAddress: eoaAddress,
chainId: entry.chainId,
type: 'safe',
label: entry.label,
});
}
/**
* Create a WalletAdapter for a raw EOA (passkey-derived secp256k1 key).
*/
static fromEOA(eoaAddress: string, chainId: number, label?: string): WalletAdapter {
return new WalletAdapter({
address: eoaAddress,
signerAddress: eoaAddress,
chainId,
type: 'eoa',
label: label ?? 'EOA Wallet',
});
}
/**
* Create a WalletAdapter for a LUKSO Universal Profile.
*/
static fromUP(upAddress: string, controllerEOA: string, chainId: number, label?: string): WalletAdapter {
return new WalletAdapter({
address: upAddress,
signerAddress: controllerEOA,
chainId,
type: 'up',
label: label ?? 'Universal Profile',
upAddress,
});
}
/**
* Returns a new WalletAdapter with a Universal Profile associated.
* The original instance is not mutated.
*/
withUniversalProfile(upAddress: string): WalletAdapter {
return new WalletAdapter({
...this.params,
upAddress,
});
}
/**
* Get wallet info, optionally overriding the chain ID.
*/
getInfo(chainId?: number): WalletInfo {
const effectiveChainId = chainId ?? this.params.chainId;
return {
address: this.params.address,
signerAddress: this.params.signerAddress,
chainId: effectiveChainId,
type: this.params.type,
label: this.params.label,
hasUniversalProfile: !!this.params.upAddress,
...(this.params.upAddress && { upAddress: this.params.upAddress }),
};
}
/**
* Serialize to a plain object (no sensitive data).
*/
toJSON(): Record<string, unknown> {
return {
address: this.params.address,
signerAddress: this.params.signerAddress,
chainId: this.params.chainId,
type: this.params.type,
label: this.params.label,
upAddress: this.params.upAddress ?? null,
};
}
}