|
diff --git a/modules/rwallet/mod.ts b/modules/rwallet/mod.ts
index fbad47a..c797044 100644
--- a/modules/rwallet/mod.ts
+++ b/modules/rwallet/mod.ts
@@ -20,9 +20,18 @@ routes.get("/api/safe/:chainId/:address/balances", async (c) => {
const chainPrefix = getSafePrefix(chainId);
if (!chainPrefix) return c.json({ error: "Unsupported chain" }, 400);
- const res = await fetch(`https://safe-transaction-${chainPrefix}.safe.global/api/v1/safes/${address}/balances/usd/?trusted=true&exclude_spam=true`);
+ const res = await fetch(`${safeApiBase(chainPrefix)}/safes/${address}/balances/?trusted=true&exclude_spam=true`);
if (!res.ok) return c.json({ error: "Safe API error" }, res.status as any);
- const data = await res.json();
+ const raw = await res.json() as any[];
+ const nativeToken = NATIVE_TOKENS[chainId] || { name: "ETH", symbol: "ETH", decimals: 18 };
+ // Normalize: fill in native token info and ensure fiatBalance fields exist
+ const data = raw.map((item: any) => ({
+ tokenAddress: item.tokenAddress,
+ token: item.token || nativeToken,
+ balance: item.balance || "0",
+ fiatBalance: item.fiatBalance || "0",
+ fiatConversion: item.fiatConversion || "0",
+ }));
c.header("Cache-Control", "public, max-age=30");
return c.json(data);
});
@@ -34,7 +43,7 @@ routes.get("/api/safe/:chainId/:address/transfers", async (c) => {
if (!chainPrefix) return c.json({ error: "Unsupported chain" }, 400);
const limit = c.req.query("limit") || "100";
- const res = await fetch(`https://safe-transaction-${chainPrefix}.safe.global/api/v1/safes/${address}/all-transactions/?limit=${limit}&executed=true`);
+ const res = await fetch(`${safeApiBase(chainPrefix)}/safes/${address}/all-transactions/?limit=${limit}&executed=true`);
if (!res.ok) return c.json({ error: "Safe API error" }, res.status as any);
return c.json(await res.json());
});
@@ -45,7 +54,7 @@ routes.get("/api/safe/:chainId/:address/info", async (c) => {
const chainPrefix = getSafePrefix(chainId);
if (!chainPrefix) return c.json({ error: "Unsupported chain" }, 400);
- const res = await fetch(`https://safe-transaction-${chainPrefix}.safe.global/api/v1/safes/${address}/`);
+ const res = await fetch(`${safeApiBase(chainPrefix)}/safes/${address}/`);
if (!res.ok) return c.json({ error: "Safe API error" }, res.status as any);
const data = await res.json();
c.header("Cache-Control", "public, max-age=300");
@@ -62,7 +71,7 @@ routes.get("/api/safe/detect/:address", async (c) => {
await Promise.allSettled(
chains.map(async ([chainId, info]) => {
try {
- const res = await fetch(`https://safe-transaction-${info.prefix}.safe.global/api/v1/safes/${address}/`, {
+ const res = await fetch(`${safeApiBase(info.prefix)}/safes/${address}/`, {
signal: AbortSignal.timeout(5000),
});
if (res.ok) results.push({ chainId, name: info.name, prefix: info.prefix });
@@ -82,20 +91,20 @@ routes.get("/api/safe/detect/:address", async (c) => {
return c.json({ address, chains: results.sort((a, b) => a.name.localeCompare(b.name)) });
});
-// ── Chain mapping ──
+// ── Chain mapping (prefix = Safe TX Service shortcode) ──
const CHAIN_MAP: Record = {
- "1": { name: "Ethereum", prefix: "mainnet" },
- "10": { name: "Optimism", prefix: "optimism" },
- "100": { name: "Gnosis", prefix: "gnosis-chain" },
- "137": { name: "Polygon", prefix: "polygon" },
+ "1": { name: "Ethereum", prefix: "eth" },
+ "10": { name: "Optimism", prefix: "oeth" },
+ "100": { name: "Gnosis", prefix: "gno" },
+ "137": { name: "Polygon", prefix: "pol" },
"8453": { name: "Base", prefix: "base" },
- "42161": { name: "Arbitrum", prefix: "arbitrum" },
+ "42161": { name: "Arbitrum", prefix: "arb1" },
"42220": { name: "Celo", prefix: "celo" },
- "43114": { name: "Avalanche", prefix: "avalanche" },
- "56": { name: "BSC", prefix: "bsc" },
+ "43114": { name: "Avalanche", prefix: "avax" },
+ "56": { name: "BSC", prefix: "bnb" },
"324": { name: "zkSync", prefix: "zksync" },
- "11155111": { name: "Sepolia", prefix: "sepolia" },
- "84532": { name: "Base Sepolia", prefix: "base-sepolia" },
+ "11155111": { name: "Sepolia", prefix: "sep" },
+ "84532": { name: "Base Sepolia", prefix: "basesep" },
};
const TESTNET_CHAIN_IDS = new Set(["11155111", "84532"]);
@@ -108,6 +117,10 @@ function getSafePrefix(chainId: string): string | null {
return CHAIN_MAP[chainId]?.prefix || null;
}
+function safeApiBase(prefix: string): string {
+ return `https://api.safe.global/tx-service/${prefix}/api/v1`;
+}
+
// ── Public RPC endpoints for EOA balance lookups ──
const RPC_URLS: Record = {
"1": "https://eth.llamarpc.com",
@@ -195,7 +208,7 @@ routes.post("/api/safe/:chainId/:address/propose", async (c) => {
// Submit proposal to Safe Transaction Service
const res = await fetch(
- `https://safe-transaction-${chainPrefix}.safe.global/api/v1/safes/${address}/multisig-transactions/`,
+ `${safeApiBase(chainPrefix)}/safes/${address}/multisig-transactions/`,
{
method: "POST",
headers: { "Content-Type": "application/json" },
@@ -246,7 +259,7 @@ routes.post("/api/safe/:chainId/:address/confirm", async (c) => {
}
const res = await fetch(
- `https://safe-transaction-${chainPrefix}.safe.global/api/v1/multisig-transactions/${safeTxHash}/confirmations/`,
+ `${safeApiBase(chainPrefix)}/multisig-transactions/${safeTxHash}/confirmations/`,
{
method: "POST",
headers: { "Content-Type": "application/json" },
@@ -294,7 +307,7 @@ routes.post("/api/safe/:chainId/:address/execute", async (c) => {
// Fetch the transaction details from Safe Transaction Service
const txRes = await fetch(
- `https://safe-transaction-${chainPrefix}.safe.global/api/v1/multisig-transactions/${safeTxHash}/`,
+ `${safeApiBase(chainPrefix)}/multisig-transactions/${safeTxHash}/`,
);
if (!txRes.ok) {
@@ -409,7 +422,7 @@ routes.get("/", (c) => {
modules: getModuleInfoList(),
theme: "dark",
body: ``,
- scripts: ``,
+ scripts: ``,
styles: ``,
}));
});
diff --git a/src/encryptid/server.ts b/src/encryptid/server.ts
index f495586..93af80a 100644
--- a/src/encryptid/server.ts
+++ b/src/encryptid/server.ts
@@ -2640,9 +2640,9 @@ app.post('/encryptid/api/safe/verify', async (c) => {
const chain = chainId || 84532;
const CHAIN_PREFIXES: Record = {
- 1: 'mainnet', 10: 'optimism', 100: 'gnosis-chain', 137: 'polygon',
- 8453: 'base', 42161: 'arbitrum', 42220: 'celo', 43114: 'avalanche',
- 56: 'bsc', 324: 'zksync', 11155111: 'sepolia', 84532: 'base-sepolia',
+ 1: 'eth', 10: 'oeth', 100: 'gno', 137: 'pol',
+ 8453: 'base', 42161: 'arb1', 42220: 'celo', 43114: 'avax',
+ 56: 'bnb', 324: 'zksync', 11155111: 'sep', 84532: 'basesep',
};
const prefix = CHAIN_PREFIXES[chain];
if (!prefix) {
@@ -2651,7 +2651,7 @@ app.post('/encryptid/api/safe/verify', async (c) => {
try {
const safeRes = await fetch(
- `https://safe-transaction-${prefix}.safe.global/api/v1/safes/${safeAddress}/`,
+ `https://api.safe.global/tx-service/${prefix}/api/v1/safes/${safeAddress}/`,
);
if (!safeRes.ok) {
return c.json({ isOwner: false, error: 'Safe not found' });
|