@zkp2p/pay-shared 0.0.1 → 1.0.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/LICENSE +6 -0
- package/README.md +116 -0
- package/dist/bitcoin.d.ts +1 -0
- package/dist/bitcoin.js +13 -0
- package/dist/chains.d.ts +17 -4
- package/dist/chains.js +60 -3
- package/dist/crypto.d.ts +34 -0
- package/dist/crypto.js +226 -0
- package/dist/fees.d.ts +27 -0
- package/dist/fees.js +195 -0
- package/dist/index.d.ts +4 -1
- package/dist/index.js +4 -0
- package/dist/rails.d.ts +61 -0
- package/dist/rails.js +144 -0
- package/dist/types.d.ts +352 -39
- package/dist/types.js +42 -13
- package/package.json +27 -5
- package/dist/chains.d.ts.map +0 -1
- package/dist/index.d.ts.map +0 -1
- package/dist/types.d.ts.map +0 -1
- package/src/chains.ts +0 -417
- package/src/index.d.ts +0 -2
- package/src/index.d.ts.map +0 -1
- package/src/index.js +0 -1
- package/src/index.ts +0 -2
- package/src/types.d.ts +0 -132
- package/src/types.d.ts.map +0 -1
- package/src/types.js +0 -29
- package/src/types.ts +0 -464
package/LICENSE
ADDED
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
Copyright (c) 2026 ZKP2P
|
|
2
|
+
|
|
3
|
+
All rights reserved.
|
|
4
|
+
|
|
5
|
+
This software and associated documentation files (the "Software") are proprietary and confidential.
|
|
6
|
+
Unauthorized copying, modification, distribution, sublicensing, or use of the Software, via any medium, is strictly prohibited without prior written permission from ZKP2P.
|
package/README.md
ADDED
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
# @zkp2p/pay-shared
|
|
2
|
+
|
|
3
|
+
Shared TypeScript types, enums, and chain utilities used by ZKP2P Pay API, SDK, and frontend apps.
|
|
4
|
+
|
|
5
|
+
- Package: `@zkp2p/pay-shared`
|
|
6
|
+
- Module format: ESM
|
|
7
|
+
- Contains runtime utilities and compile-time types
|
|
8
|
+
|
|
9
|
+
## Install
|
|
10
|
+
|
|
11
|
+
```bash
|
|
12
|
+
npm install @zkp2p/pay-shared@1.0.0
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
## Published artifacts
|
|
16
|
+
|
|
17
|
+
- Includes compiled ESM JavaScript and `.d.ts` type declarations.
|
|
18
|
+
- Does not publish declaration maps (`.d.ts.map`) or JavaScript source maps (`.js.map`).
|
|
19
|
+
|
|
20
|
+
## What This Package Includes
|
|
21
|
+
|
|
22
|
+
- Checkout API types (`CreateOrderRequest`, `CheckoutOrder`, `CheckoutPayment`, `CheckoutAggregate`, etc.)
|
|
23
|
+
- Canonical constants (`PaymentPlatform`, `FeePayer`, `CheckoutOrderStatus`, `CheckoutPaymentStatus`, `OrderErrorCode`)
|
|
24
|
+
- Merchant model types and environment constants (`Merchant`, `MerchantEnvironment`)
|
|
25
|
+
- Central chain/token helpers for supported destination chains and token aliases
|
|
26
|
+
|
|
27
|
+
## Usage
|
|
28
|
+
|
|
29
|
+
### Shared API Types
|
|
30
|
+
|
|
31
|
+
```ts
|
|
32
|
+
import type { CreateOrderRequest, CheckoutOrder } from '@zkp2p/pay-shared';
|
|
33
|
+
|
|
34
|
+
const request: CreateOrderRequest = {
|
|
35
|
+
requestedUsdcAmount: '25.00',
|
|
36
|
+
destinationChainId: 8453,
|
|
37
|
+
destinationToken: 'USDC',
|
|
38
|
+
destinationAddress: '0xYourRecipientAddress',
|
|
39
|
+
};
|
|
40
|
+
|
|
41
|
+
function readOrder(order: CheckoutOrder) {
|
|
42
|
+
console.log(order.status, order.requestedUsdcAmount, order.remainingUsdcAmount);
|
|
43
|
+
}
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
### Constants and Enums
|
|
47
|
+
|
|
48
|
+
```ts
|
|
49
|
+
import { FeePayer, PaymentPlatform, CheckoutOrderStatus } from '@zkp2p/pay-shared';
|
|
50
|
+
|
|
51
|
+
console.log(FeePayer.MERCHANT); // "MERCHANT"
|
|
52
|
+
console.log(PaymentPlatform.VENMO); // "venmo"
|
|
53
|
+
console.log(CheckoutOrderStatus.CREATED); // "CREATED"
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
### Chain and Token Utilities
|
|
57
|
+
|
|
58
|
+
```ts
|
|
59
|
+
import {
|
|
60
|
+
BASE_CHAIN_ID,
|
|
61
|
+
getSupportedChainIds,
|
|
62
|
+
parseSupportedChainSelection,
|
|
63
|
+
resolveDestinationTokenAddress,
|
|
64
|
+
getSupportedDestinationTokenAliasesForChain,
|
|
65
|
+
} from '@zkp2p/pay-shared';
|
|
66
|
+
|
|
67
|
+
const chainId = parseSupportedChainSelection('polygon'); // 137
|
|
68
|
+
const usdc = resolveDestinationTokenAddress('USDC', 137); // Chain-specific USDC address
|
|
69
|
+
const supportedAliases = getSupportedDestinationTokenAliasesForChain(BASE_CHAIN_ID); // ["USDC"]
|
|
70
|
+
|
|
71
|
+
console.log(getSupportedChainIds(), chainId, usdc, supportedAliases);
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
## Key Exports
|
|
75
|
+
|
|
76
|
+
Core type exports:
|
|
77
|
+
|
|
78
|
+
- `CreateOrderRequest`
|
|
79
|
+
- `CreateOrderResponse`
|
|
80
|
+
- `CreatePaymentRequest`
|
|
81
|
+
- `CheckoutOrder`
|
|
82
|
+
- `CheckoutPayment`
|
|
83
|
+
- `CheckoutAggregate`
|
|
84
|
+
- `CheckoutQuotes`
|
|
85
|
+
- `MerchantProfile`
|
|
86
|
+
|
|
87
|
+
Core constants:
|
|
88
|
+
|
|
89
|
+
- `PaymentPlatform`
|
|
90
|
+
- `FeePayer`
|
|
91
|
+
- `CheckoutOrderStatus`
|
|
92
|
+
- `CheckoutPaymentStatus`
|
|
93
|
+
- `OrderStatus`
|
|
94
|
+
- `ProofAttemptStatus`
|
|
95
|
+
- `OrderErrorCode`
|
|
96
|
+
- `MerchantEnvironment`
|
|
97
|
+
|
|
98
|
+
Chain constants and helpers:
|
|
99
|
+
|
|
100
|
+
- `BASE_CHAIN_ID`
|
|
101
|
+
- `HYPEREVM_CHAIN_ID`
|
|
102
|
+
- `SOLANA_CHAIN_ID`
|
|
103
|
+
- `SUPPORTED_DESTINATION_TOKEN_ALIASES`
|
|
104
|
+
- `parseSupportedChainSelection(...)`
|
|
105
|
+
- `resolveDestinationTokenAddress(...)`
|
|
106
|
+
- `getChainConfig(...)`
|
|
107
|
+
- `getSupportedChainIds(...)`
|
|
108
|
+
- `getDestinationChainIds(...)`
|
|
109
|
+
- `getEvmChainIds(...)`
|
|
110
|
+
- `getNonEvmChainIds(...)`
|
|
111
|
+
|
|
112
|
+
## Notes
|
|
113
|
+
|
|
114
|
+
- Amount fields are strings to preserve precision across APIs and clients.
|
|
115
|
+
- Canonical order/payment amounts are available on `CheckoutOrder` and `CheckoutPayment` (for example `requestedUsdcAmount`, `remainingUsdcAmount`, `netSettledUsdcAmount`).
|
|
116
|
+
- This package is ESM-only.
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function isValidBitcoinAddress(value: string): boolean;
|
package/dist/bitcoin.js
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
const BITCOIN_BASE58_ADDRESS_REGEX = /^[13][1-9A-HJ-NP-Za-km-z]{25,34}$/;
|
|
2
|
+
const BITCOIN_BECH32_ADDRESS_REGEX = /^(bc1)[ac-hj-np-z02-9]{11,71}$/i;
|
|
3
|
+
export function isValidBitcoinAddress(value) {
|
|
4
|
+
const trimmed = value.trim();
|
|
5
|
+
if (!trimmed) {
|
|
6
|
+
return false;
|
|
7
|
+
}
|
|
8
|
+
if (trimmed.toLowerCase().startsWith('bc1')) {
|
|
9
|
+
const isUniformCase = trimmed === trimmed.toLowerCase() || trimmed === trimmed.toUpperCase();
|
|
10
|
+
return isUniformCase && BITCOIN_BECH32_ADDRESS_REGEX.test(trimmed);
|
|
11
|
+
}
|
|
12
|
+
return BITCOIN_BASE58_ADDRESS_REGEX.test(trimmed);
|
|
13
|
+
}
|
package/dist/chains.d.ts
CHANGED
|
@@ -6,15 +6,14 @@
|
|
|
6
6
|
*/
|
|
7
7
|
export declare const BASE_CHAIN_ID = 8453;
|
|
8
8
|
export declare const HYPEREVM_CHAIN_ID = 999;
|
|
9
|
-
export declare const SOLANA_CHAIN_ID =
|
|
9
|
+
export declare const SOLANA_CHAIN_ID = 792703809;
|
|
10
10
|
export declare const SUPPORTED_DESTINATION_TOKEN_ALIASES: readonly ["USDC", "USDT"];
|
|
11
11
|
export type DestinationTokenAlias = (typeof SUPPORTED_DESTINATION_TOKEN_ALIASES)[number];
|
|
12
12
|
export declare const DEFAULT_DESTINATION_TOKEN_ALIAS: DestinationTokenAlias;
|
|
13
13
|
/**
|
|
14
14
|
* Chain configuration interface.
|
|
15
15
|
*
|
|
16
|
-
*
|
|
17
|
-
* always originates from Base, and the hook contract handles the Base SpokePool.
|
|
16
|
+
* Bridging always originates from Base settlement and is routed through Relay.
|
|
18
17
|
*/
|
|
19
18
|
export interface ChainConfig {
|
|
20
19
|
chainId: number;
|
|
@@ -76,6 +75,21 @@ export declare function getUsdcAddress(chainId: number): string | undefined;
|
|
|
76
75
|
* - fallback: return token string as provided (for explicit token addresses)
|
|
77
76
|
*/
|
|
78
77
|
export declare function resolveDestinationTokenAddress(destinationToken: string, destinationChainId: number): string | null;
|
|
78
|
+
/**
|
|
79
|
+
* Check whether the final payout destination is native Base USDC.
|
|
80
|
+
* Any other token or chain requires a Relay / Privy payout conversion step.
|
|
81
|
+
*/
|
|
82
|
+
export declare function isBaseUsdcDestination(destinationChainId: number | bigint | null | undefined, destinationToken: string | null | undefined): boolean;
|
|
83
|
+
/**
|
|
84
|
+
* Determine whether a payout needs Relay / Privy after Base settlement.
|
|
85
|
+
* This is true for every destination except native Base USDC.
|
|
86
|
+
*/
|
|
87
|
+
export declare function requiresRelayPayout(destinationChainId: number | bigint | null | undefined, destinationToken: string | null | undefined): boolean;
|
|
88
|
+
/**
|
|
89
|
+
* Resolve a destination token value into its canonical symbol for display.
|
|
90
|
+
* Known aliases and configured chain token addresses map to USDC/USDT.
|
|
91
|
+
*/
|
|
92
|
+
export declare function resolveDestinationTokenSymbol(destinationToken: string | null | undefined, destinationChainId?: number | bigint | null): string;
|
|
79
93
|
/**
|
|
80
94
|
* Get supported destination token aliases for a destination chain.
|
|
81
95
|
* Token support is derived from resolvable token addresses for the chain.
|
|
@@ -134,4 +148,3 @@ export declare const DESTINATION_CHAINS: {
|
|
|
134
148
|
* Mapping of chain ID to name for backward compatibility.
|
|
135
149
|
*/
|
|
136
150
|
export declare const SupportedChainsMap: Record<number, string>;
|
|
137
|
-
//# sourceMappingURL=chains.d.ts.map
|
package/dist/chains.js
CHANGED
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
// Chain IDs
|
|
8
8
|
export const BASE_CHAIN_ID = 8453;
|
|
9
9
|
export const HYPEREVM_CHAIN_ID = 999;
|
|
10
|
-
export const SOLANA_CHAIN_ID =
|
|
10
|
+
export const SOLANA_CHAIN_ID = 792703809;
|
|
11
11
|
export const SUPPORTED_DESTINATION_TOKEN_ALIASES = ['USDC', 'USDT'];
|
|
12
12
|
export const DEFAULT_DESTINATION_TOKEN_ALIAS = 'USDC';
|
|
13
13
|
// Mainnet chain configurations
|
|
@@ -120,8 +120,8 @@ const CHAIN_SELECTION_ALIASES = {
|
|
|
120
120
|
hyperliquid: 999,
|
|
121
121
|
hyperevm: 999,
|
|
122
122
|
hl: 999,
|
|
123
|
-
solana:
|
|
124
|
-
sol:
|
|
123
|
+
solana: 792703809,
|
|
124
|
+
sol: 792703809,
|
|
125
125
|
};
|
|
126
126
|
for (const chainId of SUPPORTED_CHAIN_IDS) {
|
|
127
127
|
const chainConfig = MAINNET_CHAINS[chainId];
|
|
@@ -265,6 +265,63 @@ export function resolveDestinationTokenAddress(destinationToken, destinationChai
|
|
|
265
265
|
}
|
|
266
266
|
return token;
|
|
267
267
|
}
|
|
268
|
+
/**
|
|
269
|
+
* Check whether the final payout destination is native Base USDC.
|
|
270
|
+
* Any other token or chain requires a Relay / Privy payout conversion step.
|
|
271
|
+
*/
|
|
272
|
+
export function isBaseUsdcDestination(destinationChainId, destinationToken) {
|
|
273
|
+
if (destinationChainId === null || destinationChainId === undefined) {
|
|
274
|
+
return false;
|
|
275
|
+
}
|
|
276
|
+
const chainId = Number(destinationChainId);
|
|
277
|
+
const token = destinationToken?.trim();
|
|
278
|
+
if (!token) {
|
|
279
|
+
return false;
|
|
280
|
+
}
|
|
281
|
+
if (chainId !== BASE_CHAIN_ID) {
|
|
282
|
+
return false;
|
|
283
|
+
}
|
|
284
|
+
const resolvedTokenAddress = resolveDestinationTokenAddress(token, chainId);
|
|
285
|
+
const baseUsdcAddress = getUsdcAddress(BASE_CHAIN_ID);
|
|
286
|
+
return Boolean(resolvedTokenAddress &&
|
|
287
|
+
baseUsdcAddress &&
|
|
288
|
+
resolvedTokenAddress.toLowerCase() === baseUsdcAddress.toLowerCase());
|
|
289
|
+
}
|
|
290
|
+
/**
|
|
291
|
+
* Determine whether a payout needs Relay / Privy after Base settlement.
|
|
292
|
+
* This is true for every destination except native Base USDC.
|
|
293
|
+
*/
|
|
294
|
+
export function requiresRelayPayout(destinationChainId, destinationToken) {
|
|
295
|
+
return !isBaseUsdcDestination(destinationChainId, destinationToken);
|
|
296
|
+
}
|
|
297
|
+
/**
|
|
298
|
+
* Resolve a destination token value into its canonical symbol for display.
|
|
299
|
+
* Known aliases and configured chain token addresses map to USDC/USDT.
|
|
300
|
+
*/
|
|
301
|
+
export function resolveDestinationTokenSymbol(destinationToken, destinationChainId) {
|
|
302
|
+
const token = destinationToken?.trim();
|
|
303
|
+
if (!token) {
|
|
304
|
+
return DEFAULT_DESTINATION_TOKEN_ALIAS;
|
|
305
|
+
}
|
|
306
|
+
const tokenAlias = normalizeDestinationTokenAlias(token);
|
|
307
|
+
if (tokenAlias) {
|
|
308
|
+
return tokenAlias;
|
|
309
|
+
}
|
|
310
|
+
const chainId = destinationChainId === null || destinationChainId === undefined
|
|
311
|
+
? null
|
|
312
|
+
: Number(destinationChainId);
|
|
313
|
+
if (chainId !== null) {
|
|
314
|
+
const usdcAddress = getUsdcAddress(chainId);
|
|
315
|
+
if (usdcAddress && usdcAddress.toLowerCase() === token.toLowerCase()) {
|
|
316
|
+
return 'USDC';
|
|
317
|
+
}
|
|
318
|
+
const usdtAddress = DESTINATION_TOKEN_ADDRESSES[chainId]?.usdt;
|
|
319
|
+
if (usdtAddress && usdtAddress.toLowerCase() === token.toLowerCase()) {
|
|
320
|
+
return 'USDT';
|
|
321
|
+
}
|
|
322
|
+
}
|
|
323
|
+
return token.toUpperCase();
|
|
324
|
+
}
|
|
268
325
|
/**
|
|
269
326
|
* Get supported destination token aliases for a destination chain.
|
|
270
327
|
* Token support is derived from resolvable token addresses for the chain.
|
package/dist/crypto.d.ts
ADDED
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
export declare const BITCOIN_CHAIN_ID = 8253038;
|
|
2
|
+
export declare const TRON_CHAIN_ID = 728126428;
|
|
3
|
+
export declare const PAY_CRYPTO_TOKEN_SYMBOLS: readonly ["BTC", "USDC", "USDT", "ETH", "PYUSD", "SOL", "BNB", "HYPE", "WBTC", "USDH"];
|
|
4
|
+
export type PayCryptoTokenSymbol = (typeof PAY_CRYPTO_TOKEN_SYMBOLS)[number];
|
|
5
|
+
export declare const DEFAULT_ENABLED_PAY_CRYPTO_TOKENS: PayCryptoTokenSymbol[];
|
|
6
|
+
export declare const DEFAULT_ENABLED_DESTINATION_TOKENS: PayCryptoTokenSymbol[];
|
|
7
|
+
export declare const STABLECOIN_SYMBOLS: Set<"USDC" | "USDT" | "ETH" | "BNB" | "SOL" | "BTC" | "PYUSD" | "HYPE" | "WBTC" | "USDH">;
|
|
8
|
+
export interface SupportedCryptoTokenConfig {
|
|
9
|
+
chainId: number;
|
|
10
|
+
chainName: string;
|
|
11
|
+
chainShortName: string;
|
|
12
|
+
symbol: PayCryptoTokenSymbol;
|
|
13
|
+
address: string;
|
|
14
|
+
decimals: number;
|
|
15
|
+
isNative: boolean;
|
|
16
|
+
}
|
|
17
|
+
export declare function normalizePayCryptoTokenSymbol(value: string | null | undefined): PayCryptoTokenSymbol | null;
|
|
18
|
+
export declare function isStablecoinSymbol(symbol: string | null | undefined): boolean;
|
|
19
|
+
export declare function getSupportedPayCryptoTokenConfigsForChain(chainId: number, enabledSymbols?: readonly string[] | null): SupportedCryptoTokenConfig[];
|
|
20
|
+
export declare function getSupportedPayCryptoChainIds(enabledSymbols?: readonly string[] | null): number[];
|
|
21
|
+
export declare function resolvePayCryptoTokenConfig(chainId: number, symbol: string | null | undefined): SupportedCryptoTokenConfig | null;
|
|
22
|
+
/**
|
|
23
|
+
* Reverse lookup of a token config by contract address on a specific chain.
|
|
24
|
+
* Address comparison is case-insensitive. Returns null if the chain is unknown
|
|
25
|
+
* or if no token at that address is registered for the chain.
|
|
26
|
+
*
|
|
27
|
+
* Used by the crypto fulfillment resolver to translate a Relay request's inTx
|
|
28
|
+
* tokenAddress (lowercased, chain-qualified) into a human-readable symbol and
|
|
29
|
+
* decimals, so payment.currency and payment.paymentAmount can be written
|
|
30
|
+
* correctly for whatever token the customer actually deposited.
|
|
31
|
+
*/
|
|
32
|
+
export declare function resolvePayCryptoTokenConfigByAddress(chainId: number, address: string | null | undefined): SupportedCryptoTokenConfig | null;
|
|
33
|
+
export declare function getSupportedDestinationBalanceTokenConfigsForChain(chainId: number, enabledSymbols?: readonly string[] | null): SupportedCryptoTokenConfig[];
|
|
34
|
+
export declare function resolveDestinationBalanceTokenConfig(chainId: number, symbol: string | null | undefined): SupportedCryptoTokenConfig | null;
|
package/dist/crypto.js
ADDED
|
@@ -0,0 +1,226 @@
|
|
|
1
|
+
import { MAINNET_CHAINS, } from './chains.js';
|
|
2
|
+
export const BITCOIN_CHAIN_ID = 8253038;
|
|
3
|
+
export const TRON_CHAIN_ID = 728126428;
|
|
4
|
+
export const PAY_CRYPTO_TOKEN_SYMBOLS = [
|
|
5
|
+
'BTC', // Kept in symbols for DB compatibility with existing sessions
|
|
6
|
+
'USDC',
|
|
7
|
+
'USDT',
|
|
8
|
+
'ETH',
|
|
9
|
+
'PYUSD',
|
|
10
|
+
'SOL',
|
|
11
|
+
'BNB',
|
|
12
|
+
'HYPE',
|
|
13
|
+
'WBTC',
|
|
14
|
+
'USDH',
|
|
15
|
+
];
|
|
16
|
+
export const DEFAULT_ENABLED_PAY_CRYPTO_TOKENS = [
|
|
17
|
+
'BTC',
|
|
18
|
+
'USDC',
|
|
19
|
+
'USDT',
|
|
20
|
+
'ETH',
|
|
21
|
+
'PYUSD',
|
|
22
|
+
'SOL',
|
|
23
|
+
'BNB',
|
|
24
|
+
'HYPE',
|
|
25
|
+
'WBTC',
|
|
26
|
+
'USDH',
|
|
27
|
+
];
|
|
28
|
+
export const DEFAULT_ENABLED_DESTINATION_TOKENS = [
|
|
29
|
+
'USDC',
|
|
30
|
+
'USDT',
|
|
31
|
+
];
|
|
32
|
+
export const STABLECOIN_SYMBOLS = new Set([
|
|
33
|
+
'USDC',
|
|
34
|
+
'USDT',
|
|
35
|
+
'PYUSD',
|
|
36
|
+
'USDH',
|
|
37
|
+
]);
|
|
38
|
+
const NATIVE_ETH_ADDRESS = '0x0000000000000000000000000000000000000000';
|
|
39
|
+
const NATIVE_SOL_ADDRESS = '11111111111111111111111111111111';
|
|
40
|
+
const NATIVE_BTC_ADDRESS = 'bc1qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqmql8k8';
|
|
41
|
+
const PAY_CRYPTO_CHAIN_CONFIGS = {
|
|
42
|
+
...MAINNET_CHAINS,
|
|
43
|
+
[BITCOIN_CHAIN_ID]: {
|
|
44
|
+
chainId: BITCOIN_CHAIN_ID,
|
|
45
|
+
name: 'Bitcoin',
|
|
46
|
+
shortName: 'BTC',
|
|
47
|
+
},
|
|
48
|
+
[TRON_CHAIN_ID]: {
|
|
49
|
+
chainId: TRON_CHAIN_ID,
|
|
50
|
+
name: 'Tron',
|
|
51
|
+
shortName: 'TRON',
|
|
52
|
+
},
|
|
53
|
+
};
|
|
54
|
+
const CHAIN_TOKEN_CONFIGS = {
|
|
55
|
+
[BITCOIN_CHAIN_ID]: {
|
|
56
|
+
BTC: { address: NATIVE_BTC_ADDRESS, decimals: 8, isNative: true },
|
|
57
|
+
},
|
|
58
|
+
1: {
|
|
59
|
+
ETH: { address: NATIVE_ETH_ADDRESS, decimals: 18, isNative: true },
|
|
60
|
+
USDC: { address: '0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48', decimals: 6, isNative: false },
|
|
61
|
+
USDT: { address: '0xdAC17F958D2ee523a2206206994597C13D831ec7', decimals: 6, isNative: false },
|
|
62
|
+
PYUSD: { address: '0x6c3ea9036406852006290770bedfcaba0e23a0e8', decimals: 6, isNative: false },
|
|
63
|
+
WBTC: { address: '0x2260fac5e5542a773aa44fbcfedf7c193bc2c599', decimals: 8, isNative: false },
|
|
64
|
+
},
|
|
65
|
+
10: {
|
|
66
|
+
ETH: { address: NATIVE_ETH_ADDRESS, decimals: 18, isNative: true },
|
|
67
|
+
USDC: { address: '0x0b2C639c533813f4Aa9D7837CAf62653d097Ff85', decimals: 6, isNative: false },
|
|
68
|
+
USDT: { address: '0x94b008aA00579c1307B0EF2c499aD98a8ce58e58', decimals: 6, isNative: false },
|
|
69
|
+
},
|
|
70
|
+
56: {
|
|
71
|
+
BNB: { address: NATIVE_ETH_ADDRESS, decimals: 18, isNative: true },
|
|
72
|
+
USDC: { address: '0x8AC76a51cc950d9822D68b83fE1Ad97B32Cd580d', decimals: 18, isNative: false },
|
|
73
|
+
USDT: { address: '0x55d398326f99059fF775485246999027B3197955', decimals: 18, isNative: false },
|
|
74
|
+
WBTC: { address: '0x0555e30da8f98308edb960aa94c0db47230d2b9c', decimals: 8, isNative: false },
|
|
75
|
+
},
|
|
76
|
+
137: {
|
|
77
|
+
USDC: { address: '0x3c499c542cEF5E3811e1192ce70d8cC03d5c3359', decimals: 6, isNative: false },
|
|
78
|
+
USDT: { address: '0xc2132D05D31c914a87C6611C10748AEb04B58e8F', decimals: 6, isNative: false },
|
|
79
|
+
WBTC: { address: '0x1bfd67037b42cf73acf2047067bd4f2c47d9bfd6', decimals: 8, isNative: false },
|
|
80
|
+
},
|
|
81
|
+
480: {
|
|
82
|
+
ETH: { address: NATIVE_ETH_ADDRESS, decimals: 18, isNative: true },
|
|
83
|
+
USDC: { address: '0x79A02482A880bCE3F13e09Da970dC34db4CD24d1', decimals: 6, isNative: false },
|
|
84
|
+
},
|
|
85
|
+
999: {
|
|
86
|
+
HYPE: { address: NATIVE_ETH_ADDRESS, decimals: 18, isNative: true },
|
|
87
|
+
USDC: { address: '0xb88339CB7199b77E23DB6E890353E22632Ba630f', decimals: 6, isNative: false },
|
|
88
|
+
USDH: { address: '0x111111a1a0667d36bd57c0a9f569b98057111111', decimals: 6, isNative: false },
|
|
89
|
+
},
|
|
90
|
+
8453: {
|
|
91
|
+
ETH: { address: NATIVE_ETH_ADDRESS, decimals: 18, isNative: true },
|
|
92
|
+
USDC: { address: '0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913', decimals: 6, isNative: false },
|
|
93
|
+
USDT: { address: '0xfde4C96c8593536E31F229EA8f37b2ADa2699bb2', decimals: 6, isNative: false },
|
|
94
|
+
SOL: { address: '0x311935cd80b76769bf2ecc9d8ab7635b2139cf82', decimals: 9, isNative: false },
|
|
95
|
+
WBTC: { address: '0x0555e30da8f98308edb960aa94c0db47230d2b9c', decimals: 8, isNative: false },
|
|
96
|
+
},
|
|
97
|
+
42161: {
|
|
98
|
+
ETH: { address: NATIVE_ETH_ADDRESS, decimals: 18, isNative: true },
|
|
99
|
+
USDC: { address: '0xaf88d065e77c8cC2239327C5EDb3A432268e5831', decimals: 6, isNative: false },
|
|
100
|
+
USDT: { address: '0xFd086bC7CD5C481DCC9C85ebE478A1C0b69FCbb9', decimals: 6, isNative: false },
|
|
101
|
+
WBTC: { address: '0x2f2a2543b76a4166549f7aab2e75bef0aefc5b0f', decimals: 8, isNative: false },
|
|
102
|
+
},
|
|
103
|
+
[TRON_CHAIN_ID]: {
|
|
104
|
+
USDT: { address: 'TR7NHqjeKQxGTCi8q8ZY4pL8otSzgjLj6t', decimals: 6, isNative: false },
|
|
105
|
+
},
|
|
106
|
+
792703809: {
|
|
107
|
+
SOL: { address: NATIVE_SOL_ADDRESS, decimals: 9, isNative: true },
|
|
108
|
+
USDC: { address: 'EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v', decimals: 6, isNative: false },
|
|
109
|
+
USDT: { address: 'Es9vMFrzaCERmJfrF4H2FYD4KCoNkY11McCe8BenwNYB', decimals: 6, isNative: false },
|
|
110
|
+
PYUSD: { address: '2b1kV6DkPAnxd5ixfnxCpjxmKwqjjaYmCZfHsFu24GXo', decimals: 6, isNative: false },
|
|
111
|
+
},
|
|
112
|
+
};
|
|
113
|
+
function isPayCryptoTokenSymbol(value) {
|
|
114
|
+
return PAY_CRYPTO_TOKEN_SYMBOLS.includes(value);
|
|
115
|
+
}
|
|
116
|
+
export function normalizePayCryptoTokenSymbol(value) {
|
|
117
|
+
const normalized = value?.trim().toUpperCase();
|
|
118
|
+
if (!normalized) {
|
|
119
|
+
return null;
|
|
120
|
+
}
|
|
121
|
+
return isPayCryptoTokenSymbol(normalized) ? normalized : null;
|
|
122
|
+
}
|
|
123
|
+
export function isStablecoinSymbol(symbol) {
|
|
124
|
+
const normalizedSymbol = normalizePayCryptoTokenSymbol(symbol);
|
|
125
|
+
return Boolean(normalizedSymbol && STABLECOIN_SYMBOLS.has(normalizedSymbol));
|
|
126
|
+
}
|
|
127
|
+
function normalizeEnabledSymbols(enabledSymbols, fallback) {
|
|
128
|
+
const normalized = (enabledSymbols ?? [])
|
|
129
|
+
.map((value) => normalizePayCryptoTokenSymbol(value))
|
|
130
|
+
.filter((value) => value !== null);
|
|
131
|
+
return normalized.length > 0 ? normalized : [...fallback];
|
|
132
|
+
}
|
|
133
|
+
function buildSupportedCryptoTokenConfig(chain, symbol) {
|
|
134
|
+
const config = CHAIN_TOKEN_CONFIGS[chain.chainId]?.[symbol];
|
|
135
|
+
if (!config) {
|
|
136
|
+
return null;
|
|
137
|
+
}
|
|
138
|
+
return {
|
|
139
|
+
chainId: chain.chainId,
|
|
140
|
+
chainName: chain.name,
|
|
141
|
+
chainShortName: chain.shortName,
|
|
142
|
+
symbol,
|
|
143
|
+
address: config.address,
|
|
144
|
+
decimals: config.decimals,
|
|
145
|
+
isNative: config.isNative,
|
|
146
|
+
};
|
|
147
|
+
}
|
|
148
|
+
export function getSupportedPayCryptoTokenConfigsForChain(chainId, enabledSymbols) {
|
|
149
|
+
const chain = PAY_CRYPTO_CHAIN_CONFIGS[chainId];
|
|
150
|
+
if (!chain) {
|
|
151
|
+
return [];
|
|
152
|
+
}
|
|
153
|
+
const allowedSymbols = normalizeEnabledSymbols(enabledSymbols, DEFAULT_ENABLED_PAY_CRYPTO_TOKENS);
|
|
154
|
+
return allowedSymbols
|
|
155
|
+
.map((symbol) => buildSupportedCryptoTokenConfig(chain, symbol))
|
|
156
|
+
.filter((value) => value !== null);
|
|
157
|
+
}
|
|
158
|
+
export function getSupportedPayCryptoChainIds(enabledSymbols) {
|
|
159
|
+
return Object.keys(PAY_CRYPTO_CHAIN_CONFIGS)
|
|
160
|
+
.map(Number)
|
|
161
|
+
.filter((chainId) => getSupportedPayCryptoTokenConfigsForChain(chainId, enabledSymbols).length > 0);
|
|
162
|
+
}
|
|
163
|
+
export function resolvePayCryptoTokenConfig(chainId, symbol) {
|
|
164
|
+
const normalizedSymbol = normalizePayCryptoTokenSymbol(symbol);
|
|
165
|
+
if (!normalizedSymbol) {
|
|
166
|
+
return null;
|
|
167
|
+
}
|
|
168
|
+
const chain = PAY_CRYPTO_CHAIN_CONFIGS[chainId];
|
|
169
|
+
if (!chain) {
|
|
170
|
+
return null;
|
|
171
|
+
}
|
|
172
|
+
return buildSupportedCryptoTokenConfig(chain, normalizedSymbol);
|
|
173
|
+
}
|
|
174
|
+
/**
|
|
175
|
+
* Reverse lookup of a token config by contract address on a specific chain.
|
|
176
|
+
* Address comparison is case-insensitive. Returns null if the chain is unknown
|
|
177
|
+
* or if no token at that address is registered for the chain.
|
|
178
|
+
*
|
|
179
|
+
* Used by the crypto fulfillment resolver to translate a Relay request's inTx
|
|
180
|
+
* tokenAddress (lowercased, chain-qualified) into a human-readable symbol and
|
|
181
|
+
* decimals, so payment.currency and payment.paymentAmount can be written
|
|
182
|
+
* correctly for whatever token the customer actually deposited.
|
|
183
|
+
*/
|
|
184
|
+
export function resolvePayCryptoTokenConfigByAddress(chainId, address) {
|
|
185
|
+
if (typeof address !== 'string')
|
|
186
|
+
return null;
|
|
187
|
+
const needle = address.trim().toLowerCase();
|
|
188
|
+
if (needle === '')
|
|
189
|
+
return null;
|
|
190
|
+
const chainTokens = CHAIN_TOKEN_CONFIGS[chainId];
|
|
191
|
+
if (chainTokens === undefined)
|
|
192
|
+
return null;
|
|
193
|
+
const chain = PAY_CRYPTO_CHAIN_CONFIGS[chainId];
|
|
194
|
+
if (chain === undefined)
|
|
195
|
+
return null;
|
|
196
|
+
for (const symbolKey of Object.keys(chainTokens)) {
|
|
197
|
+
const cfg = chainTokens[symbolKey];
|
|
198
|
+
if (cfg === undefined)
|
|
199
|
+
continue;
|
|
200
|
+
if (cfg.address.toLowerCase() === needle) {
|
|
201
|
+
return {
|
|
202
|
+
chainId: chain.chainId,
|
|
203
|
+
chainName: chain.name,
|
|
204
|
+
chainShortName: chain.shortName,
|
|
205
|
+
symbol: symbolKey,
|
|
206
|
+
address: cfg.address,
|
|
207
|
+
decimals: cfg.decimals,
|
|
208
|
+
isNative: cfg.isNative,
|
|
209
|
+
};
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
return null;
|
|
213
|
+
}
|
|
214
|
+
export function getSupportedDestinationBalanceTokenConfigsForChain(chainId, enabledSymbols) {
|
|
215
|
+
const chain = MAINNET_CHAINS[chainId];
|
|
216
|
+
if (!chain) {
|
|
217
|
+
return [];
|
|
218
|
+
}
|
|
219
|
+
const allowedSymbols = normalizeEnabledSymbols(enabledSymbols, DEFAULT_ENABLED_DESTINATION_TOKENS);
|
|
220
|
+
return allowedSymbols
|
|
221
|
+
.map((symbol) => buildSupportedCryptoTokenConfig(chain, symbol))
|
|
222
|
+
.filter((value) => value !== null);
|
|
223
|
+
}
|
|
224
|
+
export function resolveDestinationBalanceTokenConfig(chainId, symbol) {
|
|
225
|
+
return resolvePayCryptoTokenConfig(chainId, symbol);
|
|
226
|
+
}
|
package/dist/fees.d.ts
ADDED
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import type { FeeTranche, MaxFeeConfig, ReferralFeeConfig } from './types.js';
|
|
2
|
+
declare const TRANCHE_SCALE_BY_CURRENCY: {
|
|
3
|
+
readonly USD: 2;
|
|
4
|
+
readonly USDC: 2;
|
|
5
|
+
};
|
|
6
|
+
type TrancheCurrency = keyof typeof TRANCHE_SCALE_BY_CURRENCY;
|
|
7
|
+
export type FeeSource = 'default' | 'merchant' | 'exempt';
|
|
8
|
+
export declare function parseBoundaryUnits(raw: number, currency: TrancheCurrency): bigint;
|
|
9
|
+
export declare function parseLookupUnits(raw: string, currency: TrancheCurrency): bigint;
|
|
10
|
+
export declare function parseUsdcUnits(raw: string): bigint;
|
|
11
|
+
export declare function formatUsdcUnits(units: bigint): string;
|
|
12
|
+
export declare function calculateGrossFromNetUnits(netAmountUnits: bigint, feeBps: number): bigint;
|
|
13
|
+
export declare function validateTranches(tranches: FeeTranche[], currency: TrancheCurrency): void;
|
|
14
|
+
export declare function getMatchingTrancheIndex(tranches: FeeTranche[], amount: string, currency: TrancheCurrency): number;
|
|
15
|
+
export declare function resolveReferralFeeConfig(config: ReferralFeeConfig, amountUsdc: string, options?: {
|
|
16
|
+
defaultFeeBps?: number;
|
|
17
|
+
}): {
|
|
18
|
+
feeSource: FeeSource;
|
|
19
|
+
referralFeeBps: number;
|
|
20
|
+
};
|
|
21
|
+
export declare function resolveExactTokenGrossAmountUsdc(config: ReferralFeeConfig, requestedNetAmountUsdc: string, options?: {
|
|
22
|
+
defaultFeeBps?: number;
|
|
23
|
+
}): string;
|
|
24
|
+
export declare function resolveMaxFeeConfig(config: MaxFeeConfig, amountUsd: string): {
|
|
25
|
+
maxFeePercentage: number;
|
|
26
|
+
};
|
|
27
|
+
export {};
|