@ab-org/predicate-market-sdk 0.0.1 → 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +25 -7
- package/dist/auth/oidcRelay.d.ts +11 -0
- package/dist/auth/oidcRelay.js +107 -0
- package/dist/auth/walletAccount.d.ts +20 -0
- package/dist/auth/walletAccount.js +267 -0
- package/dist/constants/chains.d.ts +2 -22
- package/dist/constants/chains.js +3 -23
- package/dist/index.d.ts +3 -0
- package/dist/index.js +4 -0
- package/dist/modules/api.d.ts +12 -7
- package/dist/modules/api.js +6 -4
- package/dist/modules/balanceQuery.d.ts +11 -4
- package/dist/modules/balanceQuery.js +12 -10
- package/dist/modules/marketData.d.ts +5 -5
- package/dist/modules/marketData.js +33 -39
- package/dist/modules/withdrawDirect.d.ts +14 -0
- package/dist/modules/withdrawDirect.js +33 -0
- package/dist/modules/withdrawExecutor.d.ts +15 -6
- package/dist/modules/withdrawExecutor.js +21 -20
- package/dist/ui/DepositModal.js +7 -14
- package/dist/ui/SignInModal.js +3 -0
- package/dist/ui/SignInModal.shared.js +40 -1
- package/dist/ui/WithdrawModal.d.ts +12 -2
- package/dist/ui/WithdrawModal.js +101 -55
- package/dist/ui/signInTypes.d.ts +3 -0
- package/dist/ui/useSignInModalController.d.ts +2 -2
- package/dist/ui/useSignInModalController.js +34 -88
- package/dist/utils/env.js +2 -0
- package/dist/walletUtils.d.ts +1 -1
- package/dist/walletUtils.js +1 -1
- package/package.json +3 -1
package/dist/modules/api.js
CHANGED
|
@@ -1,13 +1,15 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Merchant API client
|
|
2
|
+
* Merchant API client
|
|
3
3
|
* 基于 axios 封装,类型与文档一致。
|
|
4
4
|
*/
|
|
5
5
|
import { getEnv } from "../utils/env.js";
|
|
6
6
|
import axios from "axios";
|
|
7
|
-
const DEFAULT_MERCHANT_BASE_URL = "https://merchant.tomo.services";
|
|
8
7
|
// ─── Axios 实例与请求封装 ─────────────────────────────────────────────────────
|
|
9
8
|
function createClient() {
|
|
10
|
-
const BASE_URL = getEnv("MERCHANT_BASE_URL")
|
|
9
|
+
const BASE_URL = getEnv("MERCHANT_BASE_URL");
|
|
10
|
+
if (!BASE_URL) {
|
|
11
|
+
throw new Error('MERCHANT_BASE_URL is not set');
|
|
12
|
+
}
|
|
11
13
|
return axios.create({
|
|
12
14
|
baseURL: BASE_URL,
|
|
13
15
|
timeout: 30000,
|
|
@@ -24,7 +26,7 @@ function unwrap(res) {
|
|
|
24
26
|
// 单例 client,可通过 configureMerchantApi 修改 baseURL
|
|
25
27
|
let apiClient = createClient();
|
|
26
28
|
/**
|
|
27
|
-
* 配置 Merchant API 的 baseURL
|
|
29
|
+
* 配置 Merchant API 的 baseURL
|
|
28
30
|
*/
|
|
29
31
|
export function configureMerchantApi() {
|
|
30
32
|
apiClient = createClient();
|
|
@@ -8,13 +8,20 @@ export interface Erc20BalanceResult {
|
|
|
8
8
|
* No external library dependency – uses the global `fetch`.
|
|
9
9
|
*/
|
|
10
10
|
export declare function fetchErc20Balance(rpcUrl: string, tokenAddress: string, walletAddress: string): Promise<bigint>;
|
|
11
|
-
export interface
|
|
11
|
+
export interface FundingTokenBalanceOptions {
|
|
12
12
|
rpcUrl?: string;
|
|
13
13
|
tokenAddress?: string;
|
|
14
14
|
decimals?: number;
|
|
15
|
+
/**
|
|
16
|
+
* Funding chain id (e.g. `"3131"` Tenderly BSC, `"56"` mainnet).
|
|
17
|
+
* When omitted, defaults to `3131` via {@link getChainInfo}.
|
|
18
|
+
*/
|
|
19
|
+
chainId?: string | number | null;
|
|
20
|
+
/** Label for {@link Erc20BalanceResult.symbol} (default `"Funding"`). */
|
|
21
|
+
displaySymbol?: string;
|
|
15
22
|
}
|
|
16
23
|
/**
|
|
17
|
-
*
|
|
18
|
-
*
|
|
24
|
+
* Fetches the configured funding ERC-20 balance on the selected funding chain.
|
|
25
|
+
* Defaults: chain `3131`, RPC from {@link getChainInfo}, token from {@link getFundingTokenAddress} / env.
|
|
19
26
|
*/
|
|
20
|
-
export declare function
|
|
27
|
+
export declare function fetchFundingTokenBalance(walletAddress: string, options?: FundingTokenBalanceOptions): Promise<Erc20BalanceResult>;
|
|
@@ -1,7 +1,6 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { getEnv } from "../utils/env";
|
|
2
|
+
import { getFundingTokenAddress, getChainInfo } from "../constants/chains.js";
|
|
2
3
|
const ERC20_BALANCE_OF_SELECTOR = "0x70a08231";
|
|
3
|
-
const USD1_DECIMALS = testBsc.nativeCurrencyDecimals;
|
|
4
|
-
const BSC_RPC_URL = testBsc.rpcUrls[0];
|
|
5
4
|
function padAddress(address) {
|
|
6
5
|
return address.toLowerCase().replace("0x", "").padStart(64, "0");
|
|
7
6
|
}
|
|
@@ -42,17 +41,20 @@ export async function fetchErc20Balance(rpcUrl, tokenAddress, walletAddress) {
|
|
|
42
41
|
return BigInt(json.result ?? "0x0");
|
|
43
42
|
}
|
|
44
43
|
/**
|
|
45
|
-
*
|
|
46
|
-
*
|
|
44
|
+
* Fetches the configured funding ERC-20 balance on the selected funding chain.
|
|
45
|
+
* Defaults: chain `3131`, RPC from {@link getChainInfo}, token from {@link getFundingTokenAddress} / env.
|
|
47
46
|
*/
|
|
48
|
-
export async function
|
|
49
|
-
const
|
|
50
|
-
const
|
|
51
|
-
const
|
|
47
|
+
export async function fetchFundingTokenBalance(walletAddress, options) {
|
|
48
|
+
const chain = getChainInfo(options?.chainId);
|
|
49
|
+
const rpcUrl = options?.rpcUrl ?? chain.rpcUrls[0];
|
|
50
|
+
const tokenAddress = options?.tokenAddress ?? getFundingTokenAddress(options?.chainId);
|
|
51
|
+
const decimals = options?.decimals ?? chain.nativeCurrencyDecimals;
|
|
52
|
+
const FUNDING_TOKEN_SYMBOL = getEnv("FUNDING_TOKEN_SYMBOL");
|
|
53
|
+
const displaySymbol = options?.displaySymbol ?? (FUNDING_TOKEN_SYMBOL || "Funding");
|
|
52
54
|
const raw = await fetchErc20Balance(rpcUrl, tokenAddress, walletAddress);
|
|
53
55
|
return {
|
|
54
56
|
raw,
|
|
55
57
|
formatted: formatBalanceDisplay(raw, decimals),
|
|
56
|
-
symbol:
|
|
58
|
+
symbol: displaySymbol,
|
|
57
59
|
};
|
|
58
60
|
}
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import type { MarketDataProvider } from "../types.js";
|
|
2
2
|
/**
|
|
3
|
-
*
|
|
4
|
-
* - getSupportedTokens / getSupportedChains: from GET
|
|
5
|
-
* - getQuote:
|
|
6
|
-
* - getDepositAddress:
|
|
3
|
+
* Default `MarketDataProvider` backed by the merchant chains API.
|
|
4
|
+
* - getSupportedTokens / getSupportedChains: from GET `{merchantBase}/chains`
|
|
5
|
+
* - getQuote: local estimate until a dedicated quote API exists
|
|
6
|
+
* - getDepositAddress: 当前 session 钱包地址 + 与 `token`/`chain` 匹配的 `GET /chains` 中 `minimum_deposit`(按 decimals 格式化)
|
|
7
7
|
*/
|
|
8
|
-
export declare function
|
|
8
|
+
export declare function createMarketDataProvider(): MarketDataProvider;
|
|
@@ -1,45 +1,20 @@
|
|
|
1
1
|
import { sessionStore } from "@ab-org/sdk-core";
|
|
2
|
-
import {
|
|
3
|
-
|
|
2
|
+
import { formatUnits } from "viem";
|
|
3
|
+
import { getChains } from "./api.js";
|
|
4
4
|
let cachedChains = null;
|
|
5
|
-
/** Fallback when chains API fails (network error, 4xx/5xx, parse error, missing base URL). */
|
|
6
|
-
const MOCK_CHAINS_FALLBACK = [
|
|
7
|
-
{
|
|
8
|
-
chain_id: "56",
|
|
9
|
-
network: "BSC",
|
|
10
|
-
tokens: [
|
|
11
|
-
{ symbol: "USD1", address: "0x", decimals: 18 },
|
|
12
|
-
{ symbol: "USDT", address: "0x", decimals: 6 },
|
|
13
|
-
{ symbol: "USDC", address: "0x", decimals: 6 },
|
|
14
|
-
],
|
|
15
|
-
},
|
|
16
|
-
{
|
|
17
|
-
chain_id: "ETH",
|
|
18
|
-
network: "Ethereum",
|
|
19
|
-
tokens: [
|
|
20
|
-
{ symbol: "USDT", address: "0x", decimals: 6 },
|
|
21
|
-
{ symbol: "USDC", address: "0x", decimals: 6 },
|
|
22
|
-
],
|
|
23
|
-
},
|
|
24
|
-
];
|
|
25
5
|
async function fetchChainsFromApi() {
|
|
26
6
|
if (cachedChains)
|
|
27
7
|
return cachedChains;
|
|
28
8
|
try {
|
|
29
|
-
const
|
|
30
|
-
const res = await fetch(`${CHAINS_API_BASE}/chains`);
|
|
31
|
-
if (!res.ok)
|
|
32
|
-
throw new Error(`Chains API error: ${res.status} ${res.statusText}`);
|
|
33
|
-
const json = (await res.json());
|
|
34
|
-
const chains = json.data?.chains ?? [];
|
|
9
|
+
const { chains } = await getChains();
|
|
35
10
|
if (chains.length > 0) {
|
|
36
11
|
cachedChains = chains;
|
|
37
12
|
return chains;
|
|
38
13
|
}
|
|
39
|
-
return
|
|
14
|
+
return [];
|
|
40
15
|
}
|
|
41
16
|
catch {
|
|
42
|
-
return
|
|
17
|
+
return [];
|
|
43
18
|
}
|
|
44
19
|
}
|
|
45
20
|
function chainToChainInfo(chain) {
|
|
@@ -48,6 +23,22 @@ function chainToChainInfo(chain) {
|
|
|
48
23
|
name: chain.network,
|
|
49
24
|
};
|
|
50
25
|
}
|
|
26
|
+
function findTokenInChains(chains, chainId, tokenSymbol) {
|
|
27
|
+
const chain = chains.find((c) => c.chain_id === chainId);
|
|
28
|
+
return chain?.tokens.find((t) => t.symbol === tokenSymbol);
|
|
29
|
+
}
|
|
30
|
+
/** `minimum_deposit` 为链上最小单位整数字符串,按 `decimals` 转成可读金额并拼 token 符号 */
|
|
31
|
+
function formatMinimumDepositDisplay(token, tokenSymbol) {
|
|
32
|
+
const raw = token.minimum_deposit?.trim();
|
|
33
|
+
if (raw == null || raw === "")
|
|
34
|
+
return undefined;
|
|
35
|
+
try {
|
|
36
|
+
return `${formatUnits(BigInt(raw), token.decimals)} ${tokenSymbol}`;
|
|
37
|
+
}
|
|
38
|
+
catch {
|
|
39
|
+
return `${raw} ${tokenSymbol}`;
|
|
40
|
+
}
|
|
41
|
+
}
|
|
51
42
|
function deriveTokensFromChains(chains) {
|
|
52
43
|
const bySymbol = new Map();
|
|
53
44
|
for (const chain of chains) {
|
|
@@ -63,7 +54,7 @@ function deriveTokensFromChains(chains) {
|
|
|
63
54
|
}
|
|
64
55
|
return Array.from(bySymbol.values());
|
|
65
56
|
}
|
|
66
|
-
function
|
|
57
|
+
function computeDefaultQuote(request) {
|
|
67
58
|
const isStable = ["USDT", "USDC", "USD1"].includes(request.token);
|
|
68
59
|
const slippage = isStable ? "0.3" : "1.0";
|
|
69
60
|
const feeRate = request.direction === "withdraw" ? 0.001 : 0;
|
|
@@ -81,12 +72,12 @@ function computeMockQuote(request) {
|
|
|
81
72
|
};
|
|
82
73
|
}
|
|
83
74
|
/**
|
|
84
|
-
*
|
|
85
|
-
* - getSupportedTokens / getSupportedChains: from GET
|
|
86
|
-
* - getQuote:
|
|
87
|
-
* - getDepositAddress:
|
|
75
|
+
* Default `MarketDataProvider` backed by the merchant chains API.
|
|
76
|
+
* - getSupportedTokens / getSupportedChains: from GET `{merchantBase}/chains`
|
|
77
|
+
* - getQuote: local estimate until a dedicated quote API exists
|
|
78
|
+
* - getDepositAddress: 当前 session 钱包地址 + 与 `token`/`chain` 匹配的 `GET /chains` 中 `minimum_deposit`(按 decimals 格式化)
|
|
88
79
|
*/
|
|
89
|
-
export function
|
|
80
|
+
export function createMarketDataProvider() {
|
|
90
81
|
return {
|
|
91
82
|
async getSupportedTokens(_direction) {
|
|
92
83
|
const chains = await fetchChainsFromApi();
|
|
@@ -100,13 +91,16 @@ export function createMockMarketDataProvider() {
|
|
|
100
91
|
return list.map(chainToChainInfo);
|
|
101
92
|
},
|
|
102
93
|
async getQuote(request) {
|
|
103
|
-
return
|
|
94
|
+
return computeDefaultQuote(request);
|
|
104
95
|
},
|
|
105
|
-
async getDepositAddress(
|
|
96
|
+
async getDepositAddress(token, chain) {
|
|
106
97
|
const session = sessionStore.getState().session;
|
|
98
|
+
const chains = await fetchChainsFromApi();
|
|
99
|
+
const meta = findTokenInChains(chains, chain, token);
|
|
100
|
+
const minimumDeposit = meta != null ? formatMinimumDepositDisplay(meta, token) : undefined;
|
|
107
101
|
return {
|
|
108
102
|
address: session?.address ?? "",
|
|
109
|
-
minimumDeposit
|
|
103
|
+
minimumDeposit,
|
|
110
104
|
};
|
|
111
105
|
},
|
|
112
106
|
};
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import type { ChainData, TokenData } from "./api.js";
|
|
2
|
+
/**
|
|
3
|
+
* funding 链(与 {@link DEFAULT_FUNDING_CHAIN_ID} 一致)上,且 `tokenAddress` 在 Merchant `GET /chains`
|
|
4
|
+
* 中对应条目的 `is_usd_stable === true` 时,由业务层自行完成提现并构造 `withdrawDirectResult`;
|
|
5
|
+
* 其余情况走默认 funding 提现执行器与订单轮询。
|
|
6
|
+
*/
|
|
7
|
+
export declare function isUsdtWithdrawDirect(chainId: string, tokenAddress: string, chains: ChainData[]): boolean;
|
|
8
|
+
/**
|
|
9
|
+
* 从 `getChains()` 返回的 `chains` 中,按当前选择的链 id + token symbol 或合约地址解析 `TokenData`。
|
|
10
|
+
*/
|
|
11
|
+
export declare function findTokenDataFromChains(chains: ChainData[], chainId: string, opts: {
|
|
12
|
+
symbol: string;
|
|
13
|
+
tokenAddress?: string;
|
|
14
|
+
}): TokenData | undefined;
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { DEFAULT_FUNDING_CHAIN_ID } from "../constants/chains.js";
|
|
2
|
+
/**
|
|
3
|
+
* funding 链(与 {@link DEFAULT_FUNDING_CHAIN_ID} 一致)上,且 `tokenAddress` 在 Merchant `GET /chains`
|
|
4
|
+
* 中对应条目的 `is_usd_stable === true` 时,由业务层自行完成提现并构造 `withdrawDirectResult`;
|
|
5
|
+
* 其余情况走默认 funding 提现执行器与订单轮询。
|
|
6
|
+
*/
|
|
7
|
+
export function isUsdtWithdrawDirect(chainId, tokenAddress, chains) {
|
|
8
|
+
if (chainId !== String(DEFAULT_FUNDING_CHAIN_ID))
|
|
9
|
+
return false;
|
|
10
|
+
const addr = tokenAddress.trim();
|
|
11
|
+
if (!addr)
|
|
12
|
+
return false;
|
|
13
|
+
const chain = chains.find((c) => c.chain_id === chainId);
|
|
14
|
+
const token = chain?.tokens.find((t) => t.address.toLowerCase() === addr.toLowerCase());
|
|
15
|
+
return token?.is_usd_stable === true;
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* 从 `getChains()` 返回的 `chains` 中,按当前选择的链 id + token symbol 或合约地址解析 `TokenData`。
|
|
19
|
+
*/
|
|
20
|
+
export function findTokenDataFromChains(chains, chainId, opts) {
|
|
21
|
+
const chain = chains.find((c) => c.chain_id === chainId);
|
|
22
|
+
if (!chain?.tokens.length)
|
|
23
|
+
return undefined;
|
|
24
|
+
const sym = opts.symbol.trim();
|
|
25
|
+
const addr = opts.tokenAddress?.trim().toLowerCase();
|
|
26
|
+
return chain.tokens.find((t) => {
|
|
27
|
+
if (addr && t.address.toLowerCase() === addr)
|
|
28
|
+
return true;
|
|
29
|
+
if (sym.length > 0 && t.symbol === sym)
|
|
30
|
+
return true;
|
|
31
|
+
return false;
|
|
32
|
+
});
|
|
33
|
+
}
|
|
@@ -9,7 +9,7 @@ export interface WithdrawRequest {
|
|
|
9
9
|
chain: string;
|
|
10
10
|
}
|
|
11
11
|
export interface WithdrawResult {
|
|
12
|
-
/**
|
|
12
|
+
/** Funding 链上转入一次性地址的 tx hash */
|
|
13
13
|
txHash: string;
|
|
14
14
|
/** 提现订单 ID,用于轮询 getWithdrawOrder(orderId) */
|
|
15
15
|
orderId: string;
|
|
@@ -30,18 +30,27 @@ export type WithdrawExecutor = (request: WithdrawRequest) => Promise<WithdrawRes
|
|
|
30
30
|
* "100.1" → 100100000000000000000n
|
|
31
31
|
*/
|
|
32
32
|
export declare function parseUnits(value: string, decimals: number): bigint;
|
|
33
|
-
export interface
|
|
34
|
-
/**
|
|
33
|
+
export interface FundingWithdrawExecutorOptions {
|
|
34
|
+
/** 源链 funding ERC-20 合约地址;默认 {@link getFundingTokenAddress} / env */
|
|
35
35
|
tokenAddress?: string;
|
|
36
36
|
decimals?: number;
|
|
37
|
-
|
|
37
|
+
/**
|
|
38
|
+
* Funding EVM chain id(如 `3131` Tenderly、`56` 主网)。未传时默认 `3131`。
|
|
39
|
+
*/
|
|
40
|
+
chainId?: number | string;
|
|
41
|
+
/** 覆盖 {@link getChainInfo} 提供的 JSON-RPC URL */
|
|
42
|
+
rpcUrl?: string;
|
|
38
43
|
/** 系统配置的单笔限额(wei 字符串),若提供则校验 request.amount 不得超过此值 */
|
|
39
44
|
maxAmountWei?: string;
|
|
45
|
+
/**
|
|
46
|
+
* 与商户订单接口约定的 funding 侧 token symbol(默认 `USD1`,按后端协议)。
|
|
47
|
+
*/
|
|
48
|
+
fundingLegTokenSymbol?: string;
|
|
40
49
|
}
|
|
41
50
|
/**
|
|
42
51
|
* Factory that returns a `WithdrawExecutor` implementing the flow in withdraw.md:
|
|
43
52
|
* 1) Create NATIVE_SWAP order → get one-time wallet address (OTW);
|
|
44
|
-
* 2) Sign ERC-20 transfer of
|
|
53
|
+
* 2) Sign ERC-20 transfer of the funding token on the funding chain to the OTW (not to user);
|
|
45
54
|
* 3) Broadcast tx and return { txHash, orderId } for the client to poll getWithdrawOrder(orderId).
|
|
46
55
|
*/
|
|
47
|
-
export declare function
|
|
56
|
+
export declare function createFundingWithdrawExecutor(options?: FundingWithdrawExecutorOptions): WithdrawExecutor;
|
|
@@ -2,12 +2,10 @@ import { sessionStore } from "@ab-org/sdk-core";
|
|
|
2
2
|
import { tryAutoReconnect } from "../auth/autoReconnect.js";
|
|
3
3
|
import { getChains, createOrder } from "./api.js";
|
|
4
4
|
import { fromHex, parseGwei, toHex } from "viem";
|
|
5
|
-
import {
|
|
5
|
+
import { getFundingTokenAddress, getChainInfo } from "../constants/chains.js";
|
|
6
6
|
const MAX_WITHDRAW_GAS_LIMIT = 500000n;
|
|
7
|
-
const BSC_RPC_URL = testBsc.rpcUrls[0];
|
|
8
7
|
/* ─── Internal helpers ────────────────────────── */
|
|
9
8
|
const ERC20_TRANSFER_SELECTOR = "0xa9059cbb";
|
|
10
|
-
const USD1_DECIMALS = testBsc.nativeCurrencyDecimals;
|
|
11
9
|
function padHex256(value) {
|
|
12
10
|
return value.toString(16).padStart(64, "0");
|
|
13
11
|
}
|
|
@@ -82,13 +80,13 @@ async function requestHexQuantity(provider, rpcUrl, method, params) {
|
|
|
82
80
|
return toHexQuantity(await callRpc(rpcUrl, method, params));
|
|
83
81
|
}
|
|
84
82
|
}
|
|
85
|
-
async function
|
|
83
|
+
async function ensureFundingEvmChain(provider, chainId) {
|
|
86
84
|
const hex = `0x${chainId.toString(16)}`;
|
|
87
85
|
try {
|
|
88
86
|
await provider.request({ method: "wallet_switchEthereumChain", params: [{ chainId: hex }] });
|
|
89
87
|
}
|
|
90
88
|
catch {
|
|
91
|
-
// Ignored – the wallet may already be on
|
|
89
|
+
// Ignored – the wallet may already be on the funding chain or may not support switching.
|
|
92
90
|
}
|
|
93
91
|
}
|
|
94
92
|
function getDstTokenAddress(chains, chainId, tokenSymbol) {
|
|
@@ -98,14 +96,17 @@ function getDstTokenAddress(chains, chainId, tokenSymbol) {
|
|
|
98
96
|
/**
|
|
99
97
|
* Factory that returns a `WithdrawExecutor` implementing the flow in withdraw.md:
|
|
100
98
|
* 1) Create NATIVE_SWAP order → get one-time wallet address (OTW);
|
|
101
|
-
* 2) Sign ERC-20 transfer of
|
|
99
|
+
* 2) Sign ERC-20 transfer of the funding token on the funding chain to the OTW (not to user);
|
|
102
100
|
* 3) Broadcast tx and return { txHash, orderId } for the client to poll getWithdrawOrder(orderId).
|
|
103
101
|
*/
|
|
104
|
-
export function
|
|
105
|
-
const
|
|
106
|
-
const
|
|
102
|
+
export function createFundingWithdrawExecutor(options) {
|
|
103
|
+
const fundingChain = getChainInfo(options?.chainId);
|
|
104
|
+
const chainIdNum = Number(fundingChain.chainId);
|
|
105
|
+
const rpcUrl = options?.rpcUrl ?? fundingChain.rpcUrls[0];
|
|
106
|
+
const tokenAddress = options?.tokenAddress ?? getFundingTokenAddress(options?.chainId);
|
|
107
|
+
const decimals = options?.decimals ?? fundingChain.nativeCurrencyDecimals;
|
|
107
108
|
const maxAmountWei = options?.maxAmountWei;
|
|
108
|
-
const
|
|
109
|
+
const fundingLegTokenSymbol = options?.fundingLegTokenSymbol ?? "USD1";
|
|
109
110
|
return async (request) => {
|
|
110
111
|
const amountWei = parseUnits(request.amount, decimals);
|
|
111
112
|
const amountWeiStr = amountWei.toString();
|
|
@@ -139,13 +140,13 @@ export function createBscUsd1WithdrawExecutor(options) {
|
|
|
139
140
|
if (!dstTokenAddress) {
|
|
140
141
|
throw new Error(`Unsupported token ${request.token} on chain ${request.chain}`);
|
|
141
142
|
}
|
|
142
|
-
//
|
|
143
|
-
const sourceTokenSymbol =
|
|
143
|
+
// 校验规则:源/目标代币需满足商户约定;提现场景下源链为 funding token;token_amount 已按 maxAmountWei 做单笔限额校验
|
|
144
|
+
const sourceTokenSymbol = fundingLegTokenSymbol;
|
|
144
145
|
const orderRes = await createOrder({
|
|
145
146
|
intent_id: `withdraw-${Date.now()}`,
|
|
146
147
|
order_type: "NATIVE_SWAP",
|
|
147
148
|
order_payload: {
|
|
148
|
-
chain_id:
|
|
149
|
+
chain_id: fundingChain.chainId,
|
|
149
150
|
token_address: tokenAddress,
|
|
150
151
|
token_amount: amountWeiStr,
|
|
151
152
|
dst_chain_id: request.chain,
|
|
@@ -158,7 +159,7 @@ export function createBscUsd1WithdrawExecutor(options) {
|
|
|
158
159
|
token_amount: amountWeiStr,
|
|
159
160
|
token_address: tokenAddress,
|
|
160
161
|
user_address: session.address,
|
|
161
|
-
chain_id:
|
|
162
|
+
chain_id: fundingChain.chainId,
|
|
162
163
|
},
|
|
163
164
|
],
|
|
164
165
|
});
|
|
@@ -166,18 +167,18 @@ export function createBscUsd1WithdrawExecutor(options) {
|
|
|
166
167
|
if (!oneTimeAddress) {
|
|
167
168
|
throw new Error("Order created but no one-time wallet address returned");
|
|
168
169
|
}
|
|
169
|
-
await
|
|
170
|
+
await ensureFundingEvmChain(provider, chainIdNum);
|
|
170
171
|
const data = encodeTransferData(oneTimeAddress, amountWei);
|
|
171
|
-
const nonce = await requestHexQuantity(provider,
|
|
172
|
+
const nonce = await requestHexQuantity(provider, rpcUrl, "eth_getTransactionCount", [session.address, "latest"]);
|
|
172
173
|
const tx = {
|
|
173
174
|
from: session.address,
|
|
174
175
|
to: tokenAddress,
|
|
175
176
|
value: "0x0",
|
|
176
177
|
nonce,
|
|
177
178
|
data,
|
|
178
|
-
chainId: toHex(
|
|
179
|
+
chainId: toHex(chainIdNum),
|
|
179
180
|
};
|
|
180
|
-
const estimatedGasHex = await requestHexQuantity(provider,
|
|
181
|
+
const estimatedGasHex = await requestHexQuantity(provider, rpcUrl, "eth_estimateGas", [tx]);
|
|
181
182
|
const estimatedGas = fromHex(estimatedGasHex, "bigint");
|
|
182
183
|
const gas = toHex(estimatedGas > MAX_WITHDRAW_GAS_LIMIT ? MAX_WITHDRAW_GAS_LIMIT : estimatedGas);
|
|
183
184
|
const transaction = {
|
|
@@ -201,8 +202,8 @@ export function createBscUsd1WithdrawExecutor(options) {
|
|
|
201
202
|
method: "eth_signTransaction",
|
|
202
203
|
params: [transaction],
|
|
203
204
|
});
|
|
204
|
-
txHash = await callRpc(
|
|
205
|
+
txHash = await callRpc(rpcUrl, "eth_sendRawTransaction", [signedTx]);
|
|
205
206
|
}
|
|
206
|
-
return { txHash, orderId: orderRes.order_id, fundingChainId:
|
|
207
|
+
return { txHash, orderId: orderRes.order_id, fundingChainId: fundingChain.chainId };
|
|
207
208
|
};
|
|
208
209
|
}
|
package/dist/ui/DepositModal.js
CHANGED
|
@@ -9,6 +9,7 @@ import { LoginRequiredOverlay } from "./components/LoginRequiredOverlay.js";
|
|
|
9
9
|
import { useSession } from "./hooks/useSession.js";
|
|
10
10
|
import { colors, fonts, radii } from "./theme.js";
|
|
11
11
|
import { getChains, quote, } from "../modules/api.js";
|
|
12
|
+
import { getEnv } from "../utils/env";
|
|
12
13
|
/** 校验是否为合法的充值地址(传入值):非空且长度满足常见链地址格式 */
|
|
13
14
|
function isValidDepositAddress(v) {
|
|
14
15
|
return typeof v === "string" && v.trim().length >= 20;
|
|
@@ -43,8 +44,6 @@ const DefaultCryptoIcons = () => {
|
|
|
43
44
|
}, children: t.label }, i))) }));
|
|
44
45
|
};
|
|
45
46
|
/* ─── Helpers: derive options from getChains ─── */
|
|
46
|
-
/** Deposit 时不可选 USD1(充值是转入 USD1,源代币为 USDT/USDC 等) */
|
|
47
|
-
const DEPOSIT_EXCLUDED_TOKEN = "USD1";
|
|
48
47
|
function chainsToTokenOptions(chains) {
|
|
49
48
|
const bySymbol = new Map();
|
|
50
49
|
for (const c of chains) {
|
|
@@ -54,7 +53,6 @@ function chainsToTokenOptions(chains) {
|
|
|
54
53
|
}
|
|
55
54
|
}
|
|
56
55
|
return Array.from(bySymbol.entries())
|
|
57
|
-
.filter(([id]) => id !== DEPOSIT_EXCLUDED_TOKEN)
|
|
58
56
|
.map(([id, { symbol }]) => ({
|
|
59
57
|
id,
|
|
60
58
|
label: symbol,
|
|
@@ -88,6 +86,8 @@ function getTokenAddressForChain(chains, chainId, tokenSymbol) {
|
|
|
88
86
|
const chain = chains.find((c) => c.chain_id === chainId);
|
|
89
87
|
return chain?.tokens.find((t) => t.symbol === tokenSymbol)?.address;
|
|
90
88
|
}
|
|
89
|
+
/* ─── Main Component ─────────────────────────── */
|
|
90
|
+
const FUNDING_TOKEN_SYMBOL = getEnv("FUNDING_TOKEN_SYMBOL");
|
|
91
91
|
export const DepositModal = ({ token, chain, tokenOptions: tokenOptionsProp, chainOptions: chainOptionsProp, depositAddress, minimumDeposit, qrCenterIcon, cryptoIcons, depositAmount, onShowToast, txHash, explorerTxUrl, onTokenSelect, onChainSelect, onCopyAddress, onBuyCrypto, onSignIn, onBack, onClose, }) => {
|
|
92
92
|
const session = useSession();
|
|
93
93
|
const [view, setView] = useState("entry");
|
|
@@ -98,9 +98,8 @@ export const DepositModal = ({ token, chain, tokenOptions: tokenOptionsProp, cha
|
|
|
98
98
|
const [loadingQuote, setLoadingQuote] = useState(false);
|
|
99
99
|
const [quoteRefreshKey, setQuoteRefreshKey] = useState(0);
|
|
100
100
|
const tokenOptions = useMemo(() => {
|
|
101
|
-
const excludeUsd1 = (opts) => opts.filter((o) => o.id !== DEPOSIT_EXCLUDED_TOKEN && o.label !== DEPOSIT_EXCLUDED_TOKEN);
|
|
102
101
|
if (tokenOptionsProp?.length)
|
|
103
|
-
return
|
|
102
|
+
return tokenOptionsProp;
|
|
104
103
|
if (!apiChains?.length)
|
|
105
104
|
return undefined;
|
|
106
105
|
return chainsToTokenOptions(apiChains);
|
|
@@ -112,12 +111,6 @@ export const DepositModal = ({ token, chain, tokenOptions: tokenOptionsProp, cha
|
|
|
112
111
|
return undefined;
|
|
113
112
|
return chainsToChainOptionsForToken(apiChains, token);
|
|
114
113
|
}, [chainOptionsProp, apiChains, token]);
|
|
115
|
-
// 当前选中的是 USD1 时自动切到第一个可选 token(deposit 不允许选 USD1)
|
|
116
|
-
useEffect(() => {
|
|
117
|
-
if (token !== DEPOSIT_EXCLUDED_TOKEN || !tokenOptions?.length || !onTokenSelect)
|
|
118
|
-
return;
|
|
119
|
-
onTokenSelect(tokenOptions[0].id);
|
|
120
|
-
}, [token, tokenOptions, onTokenSelect]);
|
|
121
114
|
// 仅有一个 chain 选项时默认选中
|
|
122
115
|
useEffect(() => {
|
|
123
116
|
if (chainOptions?.length !== 1 || !onChainSelect)
|
|
@@ -166,7 +159,7 @@ export const DepositModal = ({ token, chain, tokenOptions: tokenOptionsProp, cha
|
|
|
166
159
|
rate: "1",
|
|
167
160
|
chain_id: Number(chain) || 56,
|
|
168
161
|
deposit_address: "0x" + "0".repeat(39) + "1",
|
|
169
|
-
|
|
162
|
+
dst_token_amount: depositAmount ?? "0",
|
|
170
163
|
expires_at: new Date(Date.now() + 60000).toISOString(),
|
|
171
164
|
});
|
|
172
165
|
})
|
|
@@ -227,7 +220,7 @@ export const DepositModal = ({ token, chain, tokenOptions: tokenOptionsProp, cha
|
|
|
227
220
|
rate: "1",
|
|
228
221
|
chain_id: Number(chain) || 56,
|
|
229
222
|
deposit_address: "0x" + "0".repeat(39) + "1",
|
|
230
|
-
|
|
223
|
+
dst_token_amount: depositAmount ?? "0",
|
|
231
224
|
expires_at: new Date(Date.now() + 60000).toISOString(),
|
|
232
225
|
});
|
|
233
226
|
})
|
|
@@ -302,7 +295,7 @@ const TransferView = ({ token, chain, tokenOptions, chainOptions, depositAddress
|
|
|
302
295
|
display: "flex",
|
|
303
296
|
flexDirection: "column",
|
|
304
297
|
gap: 8,
|
|
305
|
-
}, children: quoteLoading ? (_jsx("span", { style: { fontSize: 13, color: colors.textSecondary }, children: "Loading\u2026" })) : (_jsxs(_Fragment, { children: [_jsxs("span", { style: { fontSize: 13, color: colors.textSecondary }, children: ["1 ", quoteData.token_symbol, " = ", quoteData.rate, "
|
|
298
|
+
}, children: quoteLoading ? (_jsx("span", { style: { fontSize: 13, color: colors.textSecondary }, children: "Loading\u2026" })) : (_jsxs(_Fragment, { children: [_jsxs("span", { style: { fontSize: 13, color: colors.textSecondary }, children: ["1 ", quoteData.token_symbol, " = ", quoteData.rate, " ", FUNDING_TOKEN_SYMBOL] }), quoteData.expires_at && (_jsx(Countdown, { expiresAt: quoteData.expires_at, isExpired: quoteExpired, onExpired: onQuoteExpired })), quoteExpired && (_jsxs("div", { style: { display: "flex", alignItems: "center", gap: 8 }, children: [_jsx("span", { style: { fontSize: 13, color: "#f59e0b" }, children: "Quote expired, please refresh" }), onRefreshQuote && (_jsx("button", { type: "button", onClick: onRefreshQuote, style: {
|
|
306
299
|
padding: "4px 12px",
|
|
307
300
|
fontSize: 12,
|
|
308
301
|
borderRadius: radii.pill,
|
package/dist/ui/SignInModal.js
CHANGED
|
@@ -2,12 +2,14 @@ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
|
2
2
|
import { useState } from "react";
|
|
3
3
|
import { sessionStore } from "@ab-org/sdk-core";
|
|
4
4
|
import { getSDKConfig } from "../auth/config.js";
|
|
5
|
+
import { clearSocialAccountInstance as clearEmbeddedWalletAccount } from "../auth/walletAccount.js";
|
|
5
6
|
import { resolveSocialProviders } from "./SignInModal.shared.js";
|
|
6
7
|
import { SignInModalFooter, SignInModalFrame, SignInModalSocialSection, SignInModalWalletGrid, } from "./SignInModal.sections.js";
|
|
7
8
|
import { useSignInModalController } from "./useSignInModalController.js";
|
|
8
9
|
import { Toast } from "./components/Toast.js";
|
|
9
10
|
export function clearSocialAccountInstance() {
|
|
10
11
|
try {
|
|
12
|
+
clearEmbeddedWalletAccount();
|
|
11
13
|
const storage = typeof localStorage !== "undefined" ? localStorage : null;
|
|
12
14
|
const adapterId = storage?.getItem("ab:wallet:adapterId");
|
|
13
15
|
const session = sessionStore.getState().session;
|
|
@@ -22,6 +24,7 @@ export function clearSocialAccountInstance() {
|
|
|
22
24
|
storage?.removeItem("ab:wallet:adapterId");
|
|
23
25
|
}
|
|
24
26
|
catch {
|
|
27
|
+
clearEmbeddedWalletAccount();
|
|
25
28
|
sessionStore.clearSession();
|
|
26
29
|
}
|
|
27
30
|
}
|
|
@@ -66,6 +66,20 @@ const IconFrame = ({ background, children, }) => (_jsx("div", { style: {
|
|
|
66
66
|
justifyContent: "center",
|
|
67
67
|
overflow: "hidden",
|
|
68
68
|
}, children: children }));
|
|
69
|
+
const MetaMaskWalletIcon = () => (_jsx(IconFrame, { background: "#1A0F07", children: _jsxs("svg", { width: "32", height: "32", viewBox: "0 0 32 32", fill: "none", children: [_jsx("path", { d: "M8 6L15 11L12 14L8 6Z", fill: "#E17726" }), _jsx("path", { d: "M24 6L17 11L20 14L24 6Z", fill: "#E27625" }), _jsx("path", { d: "M11 19L15 22V17L11 19Z", fill: "#F6851B" }), _jsx("path", { d: "M21 19L17 22V17L21 19Z", fill: "#F6851B" }), _jsx("path", { d: "M12 14L15 11V17L11 19L12 14Z", fill: "#763D16" }), _jsx("path", { d: "M20 14L17 11V17L21 19L20 14Z", fill: "#763D16" })] }) }));
|
|
70
|
+
const OKXWalletIcon = () => (_jsx(IconFrame, { background: "#FFFFFF", children: _jsxs("svg", { width: "30", height: "30", viewBox: "0 0 30 30", fill: "none", children: [_jsx("rect", { x: "2", y: "2", width: "8", height: "8", rx: "2", fill: "#050608" }), _jsx("rect", { x: "11", y: "2", width: "8", height: "8", rx: "2", fill: "#050608" }), _jsx("rect", { x: "20", y: "2", width: "8", height: "8", rx: "2", fill: "#050608" }), _jsx("rect", { x: "2", y: "11", width: "8", height: "8", rx: "2", fill: "#050608" }), _jsx("rect", { x: "20", y: "11", width: "8", height: "8", rx: "2", fill: "#050608" }), _jsx("rect", { x: "2", y: "20", width: "8", height: "8", rx: "2", fill: "#050608" }), _jsx("rect", { x: "11", y: "20", width: "8", height: "8", rx: "2", fill: "#050608" }), _jsx("rect", { x: "20", y: "20", width: "8", height: "8", rx: "2", fill: "#050608" })] }) }));
|
|
71
|
+
const CoinbaseWalletIcon = () => (_jsx(IconFrame, { background: "#0052FF", children: _jsxs("svg", { width: "30", height: "30", viewBox: "0 0 30 30", fill: "none", children: [_jsx("circle", { cx: "15", cy: "15", r: "10", stroke: "white", strokeWidth: "4" }), _jsx("rect", { x: "9", y: "13", width: "12", height: "4", rx: "2", fill: "white" })] }) }));
|
|
72
|
+
const TrustWalletIcon = () => (_jsx(IconFrame, { background: "#3375FF", children: _jsxs("svg", { width: "28", height: "28", viewBox: "0 0 28 28", fill: "none", children: [_jsx("path", { d: "M14 4L21 6.6V12.8C21 17.1 18.1 20.9 14 22.4C9.9 20.9 7 17.1 7 12.8V6.6L14 4Z", fill: "white" }), _jsx("path", { d: "M14 8L17 9.1V12.3C17 14.7 15.7 16.8 14 17.6C12.3 16.8 11 14.7 11 12.3V9.1L14 8Z", fill: "#3375FF" })] }) }));
|
|
73
|
+
const PhantomWalletIcon = () => (_jsx(IconFrame, { background: "linear-gradient(135deg, #6C47FF 0%, #9B6BFF 100%)", children: _jsxs("svg", { width: "30", height: "30", viewBox: "0 0 30 30", fill: "none", children: [_jsx("path", { d: "M8 18.5C8 14.4 11.2 11 15.3 11H20.4C21.8 11 23 12.2 23 13.6C23 15 21.8 16.2 20.4 16.2H14.7", stroke: "white", strokeWidth: "3", strokeLinecap: "round" }), _jsx("path", { d: "M10.5 14H19.5", stroke: "white", strokeWidth: "3", strokeLinecap: "round" }), _jsx("circle", { cx: "12", cy: "20", r: "1.4", fill: "white" }), _jsx("circle", { cx: "18", cy: "20", r: "1.4", fill: "white" })] }) }));
|
|
74
|
+
const RabbyWalletIcon = () => (_jsx(IconFrame, { background: "#EBF2FF", children: _jsxs("svg", { width: "30", height: "30", viewBox: "0 0 30 30", fill: "none", children: [_jsx("path", { d: "M11 7L13.5 13", stroke: "#7084FF", strokeWidth: "3", strokeLinecap: "round" }), _jsx("path", { d: "M19 7L16.5 13", stroke: "#7084FF", strokeWidth: "3", strokeLinecap: "round" }), _jsx("rect", { x: "8", y: "12", width: "14", height: "11", rx: "6", fill: "#7084FF" }), _jsx("circle", { cx: "13", cy: "17", r: "1.4", fill: "white" }), _jsx("circle", { cx: "17", cy: "17", r: "1.4", fill: "white" }), _jsx("path", { d: "M13 20C13.6 20.4 14.3 20.6 15 20.6C15.7 20.6 16.4 20.4 17 20", stroke: "white", strokeWidth: "1.8", strokeLinecap: "round" })] }) }));
|
|
75
|
+
/** Rainbow icon from wallet-adaptor-base (rainbowWallet.svg) */
|
|
76
|
+
const RainbowWalletIcon = () => (_jsx(IconFrame, { background: "linear-gradient(180deg, #174299 0%, #001E59 100%)", children: _jsxs("svg", { width: "32", height: "32", viewBox: "0 0 120 120", fill: "none", style: { overflow: "hidden", borderRadius: 12 }, children: [_jsxs("defs", { children: [_jsxs("radialGradient", { id: "rainbow_r1", cx: "0", cy: "0", r: "1", gradientUnits: "userSpaceOnUse", gradientTransform: "translate(26 94) rotate(-90) scale(74)", children: [_jsx("stop", { offset: "0.770277", stopColor: "#FF4000" }), _jsx("stop", { offset: "1", stopColor: "#8754C9" })] }), _jsxs("linearGradient", { id: "rainbow_l2", x1: "83", y1: "97", x2: "100", y2: "97", gradientUnits: "userSpaceOnUse", children: [_jsx("stop", { stopColor: "#FF4000" }), _jsx("stop", { offset: "1", stopColor: "#8754C9" })] }), _jsxs("linearGradient", { id: "rainbow_l3", x1: "23", y1: "20", x2: "23", y2: "37", gradientUnits: "userSpaceOnUse", children: [_jsx("stop", { stopColor: "#8754C9" }), _jsx("stop", { offset: "1", stopColor: "#FF4000" })] }), _jsxs("radialGradient", { id: "rainbow_r4", cx: "0", cy: "0", r: "1", gradientUnits: "userSpaceOnUse", gradientTransform: "translate(26 94) rotate(-90) scale(58)", children: [_jsx("stop", { offset: "0.723929", stopColor: "#FFF700" }), _jsx("stop", { offset: "1", stopColor: "#FF9901" })] }), _jsxs("linearGradient", { id: "rainbow_l5", x1: "68", y1: "97", x2: "84", y2: "97", gradientUnits: "userSpaceOnUse", children: [_jsx("stop", { stopColor: "#FFF700" }), _jsx("stop", { offset: "1", stopColor: "#FF9901" })] }), _jsxs("linearGradient", { id: "rainbow_l6", x1: "23", y1: "52", x2: "23", y2: "36", gradientUnits: "userSpaceOnUse", children: [_jsx("stop", { stopColor: "#FFF700" }), _jsx("stop", { offset: "1", stopColor: "#FF9901" })] }), _jsxs("radialGradient", { id: "rainbow_r7", cx: "0", cy: "0", r: "1", gradientUnits: "userSpaceOnUse", gradientTransform: "translate(26 94) rotate(-90) scale(42)", children: [_jsx("stop", { offset: "0.59513", stopColor: "#00AAFF" }), _jsx("stop", { offset: "1", stopColor: "#01DA40" })] }), _jsxs("radialGradient", { id: "rainbow_r8", cx: "0", cy: "0", r: "1", gradientUnits: "userSpaceOnUse", gradientTransform: "translate(51 97) scale(17 45.3333)", children: [_jsx("stop", { stopColor: "#00AAFF" }), _jsx("stop", { offset: "1", stopColor: "#01DA40" })] }), _jsxs("radialGradient", { id: "rainbow_r9", cx: "0", cy: "0", r: "1", gradientUnits: "userSpaceOnUse", gradientTransform: "translate(23 69) rotate(-90) scale(17 322.37)", children: [_jsx("stop", { stopColor: "#00AAFF" }), _jsx("stop", { offset: "1", stopColor: "#01DA40" })] })] }), _jsx("path", { d: "M20 38H26C56.9279 38 82 63.0721 82 94V100H94C97.3137 100 100 97.3137 100 94C100 53.1309 66.8691 20 26 20C22.6863 20 20 22.6863 20 26V38Z", fill: "url(#rainbow_r1)" }), _jsx("path", { d: "M84 94H100C100 97.3137 97.3137 100 94 100H84V94Z", fill: "url(#rainbow_l2)" }), _jsx("path", { d: "M26 20L26 36H20L20 26C20 22.6863 22.6863 20 26 20Z", fill: "url(#rainbow_l3)" }), _jsx("path", { d: "M20 36H26C58.0325 36 84 61.9675 84 94V100H66V94C66 71.9086 48.0914 54 26 54H20V36Z", fill: "url(#rainbow_r4)" }), _jsx("path", { d: "M68 94H84V100H68V94Z", fill: "url(#rainbow_l5)" }), _jsx("path", { d: "M20 52L20 36L26 36L26 52H20Z", fill: "url(#rainbow_l6)" }), _jsx("path", { d: "M20 62C20 65.3137 22.6863 68 26 68C40.3594 68 52 79.6406 52 94C52 97.3137 54.6863 100 58 100H68V94C68 70.804 49.196 52 26 52H20V62Z", fill: "url(#rainbow_r7)" }), _jsx("path", { d: "M52 94H68V100H58C54.6863 100 52 97.3137 52 94Z", fill: "url(#rainbow_r8)" }), _jsx("path", { d: "M26 68C22.6863 68 20 65.3137 20 62L20 52L26 52L26 68Z", fill: "url(#rainbow_r9)" })] }) }));
|
|
77
|
+
/** Zerion icon from wallet-adaptor-base (zerionWallet.svg) */
|
|
78
|
+
const ZerionWalletIcon = () => (_jsx(IconFrame, { background: "#2962EF", children: _jsx("svg", { width: "28", height: "28", viewBox: "0 0 28 28", fill: "none", children: _jsx("path", { fill: "#fff", d: "M6.073 7c-.48 0-.665.593-.262.841l10.073 6.074a.577.577 0 0 0 .758-.139l4.43-5.814c.3-.404-.004-.962-.525-.962H6.073ZM21.904 21c.48 0 .67-.596.267-.844l-10.075-6.073a.569.569 0 0 0-.751.146l-4.437 5.813c-.301.404.012.958.534.958h14.462Z" }) }) }));
|
|
79
|
+
/** Brave Wallet icon from wallet-adaptor-base (braveWallet.svg), scaled */
|
|
80
|
+
const BraveWalletIcon = () => (_jsx(IconFrame, { background: "#FFF", children: _jsxs("svg", { width: "32", height: "32", viewBox: "-100 -100 2970 2970", fill: "none", style: { overflow: "hidden", borderRadius: 12 }, children: [_jsxs("defs", { children: [_jsxs("linearGradient", { id: "brave_a", y1: "51%", y2: "51%", children: [_jsx("stop", { offset: "0.4", stopColor: "#f50" }), _jsx("stop", { offset: "0.6", stopColor: "#ff2000" })] }), _jsxs("linearGradient", { id: "brave_b", x1: "2%", y1: "51%", x2: "51%", y2: "51%", children: [_jsx("stop", { offset: "0", stopColor: "#ff452a" }), _jsx("stop", { offset: "1", stopColor: "#ff2000" })] })] }), _jsx("path", { fill: "url(#brave_a)", d: "m2395 723 60-147-170-176c-92-92-288-38-288-38l-222-252H992L769 363s-196-53-288 37L311 575l60 147-75 218 250 953c52 204 87 283 234 387l457 310c44 27 98 74 147 74s103-47 147-74l457-310c147-104 182-183 234-387l250-953z" }), _jsx("path", { fill: "#fff", d: "M1935 524s287 347 287 420c0 75-36 94-72 133l-215 230c-20 20-63 54-38 113 25 60 60 134 20 210-40 77-110 128-155 120a820 820 0 0 1-190-90c-38-25-160-126-160-165s126-110 150-124c23-16 130-78 132-102s2-30-30-90-88-140-80-192c10-52 100-80 167-105l207-78c16-8 12-15-36-20-48-4-183-22-244-5s-163 43-173 57c-8 14-16 14-7 62l58 315c4 40 12 67-30 77-44 10-117 27-142 27s-99-17-142-27-35-37-30-77c4-40 48-268 57-315 10-48 1-48-7-62-10-14-113-40-174-57-60-17-196 1-244 6-48 4-52 10-36 20l207 77c66 25 158 53 167 105 10 53-47 132-80 192s-32 66-30 90 110 86 132 102c24 15 150 85 150 124s-119 140-159 165a820 820 0 0 1-190 90c-45 8-115-43-156-120-40-76-4-150 20-210 25-60-17-92-38-113l-215-230c-35-37-71-57-71-131s287-420 287-420l273 44c32 0 103-27 168-50 65-20 110-22 110-22s44 0 110 22 136 50 168 50c33 0 275-47 275-47zm-215 1328c18 10 7 32-10 44l-254 198c-20 20-52 50-73 50s-52-30-73-50a13200 13200 0 0 0-255-198c-16-12-27-33-10-44l150-80a870 870 0 0 1 188-73c15 0 110 34 187 73l150 80z" }), _jsx("path", { fill: "url(#brave_b)", d: "m1999 363-224-253H992L769 363s-196-53-288 37c0 0 260-23 350 123l276 47c32 0 103-27 168-50 65-20 110-22 110-22s44 0 110 22 136 50 168 50c33 0 275-47 275-47 90-146 350-123 350-123-92-92-288-38-288-38" })] }) }));
|
|
81
|
+
/** Bitget icon from wallet-adaptor-base (bitgetWallet.svg) */
|
|
82
|
+
const BitgetWalletIcon = () => (_jsx(IconFrame, { background: "#001F29", children: _jsx("svg", { width: "28", height: "28", viewBox: "0 0 512 512", fill: "none", children: _jsx("path", { d: "M219.948 95.7022C201.623 95.6929 183.33 95.6835 164.941 95.7116C153.822 95.7116 149.651 109.671 157.921 117.939L283.098 243.117C287.004 246.69 289.441 250.574 289.53 255.693C289.441 260.812 287.004 264.696 283.098 268.269L157.921 393.446C149.651 401.715 153.822 415.674 164.941 415.674C183.33 415.702 201.623 415.693 219.948 415.683C229.122 415.679 238.305 415.674 247.511 415.674C259.555 415.674 266.72 409.24 273.154 402.805L386.047 289.912C395.057 280.902 403.119 268.939 403.009 255.693C403.119 242.447 395.057 230.484 386.047 221.474L273.154 108.58C266.72 102.146 259.555 95.7116 247.511 95.7116C238.305 95.7116 229.122 95.7069 219.948 95.7022Z", fill: "#00F0FF" }) }) }));
|
|
69
83
|
const walletIconTheme = {
|
|
70
84
|
metamask: "#F6851B",
|
|
71
85
|
okx: "#050608",
|
|
@@ -84,4 +98,29 @@ const WalletPlaceholder = ({ walletId, name }) => (_jsx(IconFrame, { background:
|
|
|
84
98
|
color: walletIconTheme[walletId] ? "#FFFFFF" : colors.textSecondary,
|
|
85
99
|
fontFamily: fonts.family,
|
|
86
100
|
}, children: name.slice(0, 2).toUpperCase() }) }));
|
|
87
|
-
export const DefaultWalletIcon = ({ walletId, name, }) =>
|
|
101
|
+
export const DefaultWalletIcon = ({ walletId, name, }) => {
|
|
102
|
+
switch (walletId) {
|
|
103
|
+
case "metamask":
|
|
104
|
+
return _jsx(MetaMaskWalletIcon, {});
|
|
105
|
+
case "okx":
|
|
106
|
+
return _jsx(OKXWalletIcon, {});
|
|
107
|
+
case "coinbase":
|
|
108
|
+
return _jsx(CoinbaseWalletIcon, {});
|
|
109
|
+
case "trust":
|
|
110
|
+
return _jsx(TrustWalletIcon, {});
|
|
111
|
+
case "phantom":
|
|
112
|
+
return _jsx(PhantomWalletIcon, {});
|
|
113
|
+
case "rabby":
|
|
114
|
+
return _jsx(RabbyWalletIcon, {});
|
|
115
|
+
case "rainbow":
|
|
116
|
+
return _jsx(RainbowWalletIcon, {});
|
|
117
|
+
case "zerion":
|
|
118
|
+
return _jsx(ZerionWalletIcon, {});
|
|
119
|
+
case "brave":
|
|
120
|
+
return _jsx(BraveWalletIcon, {});
|
|
121
|
+
case "bitget":
|
|
122
|
+
return _jsx(BitgetWalletIcon, {});
|
|
123
|
+
default:
|
|
124
|
+
return _jsx(WalletPlaceholder, { walletId: walletId, name: name });
|
|
125
|
+
}
|
|
126
|
+
};
|