@zkp2p/pay-shared 0.0.2 → 2.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 +30 -26
- package/dist/bitcoin.d.ts +1 -0
- package/dist/bitcoin.js +13 -0
- package/dist/buyerTee.d.ts +4 -0
- package/dist/buyerTee.js +3 -0
- package/dist/chains.d.ts +18 -4
- package/dist/chains.js +65 -3
- package/dist/crypto.d.ts +65 -0
- package/dist/crypto.js +291 -0
- package/dist/fees.d.ts +27 -0
- package/dist/fees.js +195 -0
- package/dist/fiatAmount.d.ts +19 -0
- package/dist/fiatAmount.js +58 -0
- package/dist/index.d.ts +8 -1
- package/dist/index.js +8 -0
- package/dist/paypalSarPhase.d.ts +5 -0
- package/dist/paypalSarPhase.js +8 -0
- package/dist/paypalSarVerify.d.ts +41 -0
- package/dist/paypalSarVerify.js +31 -0
- package/dist/rails.d.ts +137 -0
- package/dist/rails.js +320 -0
- package/dist/types.d.ts +427 -39
- package/dist/types.js +78 -13
- package/package.json +31 -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
CHANGED
|
@@ -9,13 +9,18 @@ Shared TypeScript types, enums, and chain utilities used by ZKP2P Pay API, SDK,
|
|
|
9
9
|
## Install
|
|
10
10
|
|
|
11
11
|
```bash
|
|
12
|
-
npm install @zkp2p/pay-shared
|
|
12
|
+
npm install @zkp2p/pay-shared@2.0.0
|
|
13
13
|
```
|
|
14
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
|
+
|
|
15
20
|
## What This Package Includes
|
|
16
21
|
|
|
17
|
-
- Checkout
|
|
18
|
-
- Canonical constants (`PaymentPlatform`, `
|
|
22
|
+
- Checkout API types (`CreateOrderRequest`, `CheckoutOrder`, `CheckoutPayment`, `CheckoutAggregate`, etc.)
|
|
23
|
+
- Canonical constants (`PaymentPlatform`, `FeePayer`, `CheckoutOrderStatus`, `CheckoutPaymentStatus`, `OrderErrorCode`)
|
|
19
24
|
- Merchant model types and environment constants (`Merchant`, `MerchantEnvironment`)
|
|
20
25
|
- Central chain/token helpers for supported destination chains and token aliases
|
|
21
26
|
|
|
@@ -24,30 +29,28 @@ npm install @zkp2p/pay-shared
|
|
|
24
29
|
### Shared API Types
|
|
25
30
|
|
|
26
31
|
```ts
|
|
27
|
-
import type {
|
|
32
|
+
import type { CreateOrderRequest, CheckoutOrder } from '@zkp2p/pay-shared';
|
|
28
33
|
|
|
29
|
-
const request:
|
|
30
|
-
|
|
31
|
-
checkoutMode: 'exact-token',
|
|
32
|
-
amountUsdc: '25.00',
|
|
34
|
+
const request: CreateOrderRequest = {
|
|
35
|
+
requestedUsdcAmount: '25.00',
|
|
33
36
|
destinationChainId: 8453,
|
|
34
37
|
destinationToken: 'USDC',
|
|
35
|
-
|
|
38
|
+
destinationAddress: '0xYourRecipientAddress',
|
|
36
39
|
};
|
|
37
40
|
|
|
38
|
-
function
|
|
39
|
-
console.log(
|
|
41
|
+
function readOrder(order: CheckoutOrder) {
|
|
42
|
+
console.log(order.status, order.requestedUsdcAmount, order.remainingUsdcAmount);
|
|
40
43
|
}
|
|
41
44
|
```
|
|
42
45
|
|
|
43
46
|
### Constants and Enums
|
|
44
47
|
|
|
45
48
|
```ts
|
|
46
|
-
import {
|
|
49
|
+
import { FeePayer, PaymentPlatform, CheckoutOrderStatus } from '@zkp2p/pay-shared';
|
|
47
50
|
|
|
48
|
-
console.log(
|
|
51
|
+
console.log(FeePayer.MERCHANT); // "MERCHANT"
|
|
49
52
|
console.log(PaymentPlatform.VENMO); // "venmo"
|
|
50
|
-
console.log(
|
|
53
|
+
console.log(CheckoutOrderStatus.CREATED); // "CREATED"
|
|
51
54
|
```
|
|
52
55
|
|
|
53
56
|
### Chain and Token Utilities
|
|
@@ -63,7 +66,7 @@ import {
|
|
|
63
66
|
|
|
64
67
|
const chainId = parseSupportedChainSelection('polygon'); // 137
|
|
65
68
|
const usdc = resolveDestinationTokenAddress('USDC', 137); // Chain-specific USDC address
|
|
66
|
-
const supportedAliases = getSupportedDestinationTokenAliasesForChain(BASE_CHAIN_ID); // ["USDC"]
|
|
69
|
+
const supportedAliases = getSupportedDestinationTokenAliasesForChain(BASE_CHAIN_ID); // ["USDC", "USDT"]
|
|
67
70
|
|
|
68
71
|
console.log(getSupportedChainIds(), chainId, usdc, supportedAliases);
|
|
69
72
|
```
|
|
@@ -72,20 +75,21 @@ console.log(getSupportedChainIds(), chainId, usdc, supportedAliases);
|
|
|
72
75
|
|
|
73
76
|
Core type exports:
|
|
74
77
|
|
|
75
|
-
- `
|
|
76
|
-
- `
|
|
77
|
-
- `
|
|
78
|
-
- `
|
|
79
|
-
- `
|
|
80
|
-
- `
|
|
81
|
-
- `
|
|
82
|
-
- `
|
|
78
|
+
- `CreateOrderRequest`
|
|
79
|
+
- `CreateOrderResponse`
|
|
80
|
+
- `CreatePaymentRequest`
|
|
81
|
+
- `CheckoutOrder`
|
|
82
|
+
- `CheckoutPayment`
|
|
83
|
+
- `CheckoutAggregate`
|
|
84
|
+
- `CheckoutQuotes`
|
|
85
|
+
- `MerchantProfile`
|
|
83
86
|
|
|
84
87
|
Core constants:
|
|
85
88
|
|
|
86
89
|
- `PaymentPlatform`
|
|
87
|
-
- `
|
|
88
|
-
- `
|
|
90
|
+
- `FeePayer`
|
|
91
|
+
- `CheckoutOrderStatus`
|
|
92
|
+
- `CheckoutPaymentStatus`
|
|
89
93
|
- `OrderStatus`
|
|
90
94
|
- `ProofAttemptStatus`
|
|
91
95
|
- `OrderErrorCode`
|
|
@@ -108,5 +112,5 @@ Chain constants and helpers:
|
|
|
108
112
|
## Notes
|
|
109
113
|
|
|
110
114
|
- Amount fields are strings to preserve precision across APIs and clients.
|
|
111
|
-
-
|
|
115
|
+
- Canonical order/payment amounts are available on `CheckoutOrder` and `CheckoutPayment` (for example `requestedUsdcAmount`, `remainingUsdcAmount`, `netSettledUsdcAmount`).
|
|
112
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/buyerTee.js
ADDED
package/dist/chains.d.ts
CHANGED
|
@@ -5,16 +5,16 @@
|
|
|
5
5
|
* Import this module instead of duplicating chain configs in each app.
|
|
6
6
|
*/
|
|
7
7
|
export declare const BASE_CHAIN_ID = 8453;
|
|
8
|
+
export declare const ETHEREUM_CHAIN_ID = 1;
|
|
8
9
|
export declare const HYPEREVM_CHAIN_ID = 999;
|
|
9
|
-
export declare const SOLANA_CHAIN_ID =
|
|
10
|
+
export declare const SOLANA_CHAIN_ID = 792703809;
|
|
10
11
|
export declare const SUPPORTED_DESTINATION_TOKEN_ALIASES: readonly ["USDC", "USDT"];
|
|
11
12
|
export type DestinationTokenAlias = (typeof SUPPORTED_DESTINATION_TOKEN_ALIASES)[number];
|
|
12
13
|
export declare const DEFAULT_DESTINATION_TOKEN_ALIAS: DestinationTokenAlias;
|
|
13
14
|
/**
|
|
14
15
|
* Chain configuration interface.
|
|
15
16
|
*
|
|
16
|
-
*
|
|
17
|
-
* always originates from Base, and the hook contract handles the Base SpokePool.
|
|
17
|
+
* Bridging always originates from Base settlement and is routed through Relay.
|
|
18
18
|
*/
|
|
19
19
|
export interface ChainConfig {
|
|
20
20
|
chainId: number;
|
|
@@ -76,6 +76,21 @@ export declare function getUsdcAddress(chainId: number): string | undefined;
|
|
|
76
76
|
* - fallback: return token string as provided (for explicit token addresses)
|
|
77
77
|
*/
|
|
78
78
|
export declare function resolveDestinationTokenAddress(destinationToken: string, destinationChainId: number): string | null;
|
|
79
|
+
/**
|
|
80
|
+
* Check whether the final payout destination is native Base USDC.
|
|
81
|
+
* Any other token or chain requires a Relay / Privy payout conversion step.
|
|
82
|
+
*/
|
|
83
|
+
export declare function isBaseUsdcDestination(destinationChainId: number | bigint | null | undefined, destinationToken: string | null | undefined): boolean;
|
|
84
|
+
/**
|
|
85
|
+
* Determine whether a payout needs Relay / Privy after Base settlement.
|
|
86
|
+
* This is true for every destination except native Base USDC.
|
|
87
|
+
*/
|
|
88
|
+
export declare function requiresRelayPayout(destinationChainId: number | bigint | null | undefined, destinationToken: string | null | undefined): boolean;
|
|
89
|
+
/**
|
|
90
|
+
* Resolve a destination token value into its canonical symbol for display.
|
|
91
|
+
* Known aliases and configured chain token addresses map to USDC/USDT.
|
|
92
|
+
*/
|
|
93
|
+
export declare function resolveDestinationTokenSymbol(destinationToken: string | null | undefined, destinationChainId?: number | bigint | null): string;
|
|
79
94
|
/**
|
|
80
95
|
* Get supported destination token aliases for a destination chain.
|
|
81
96
|
* Token support is derived from resolvable token addresses for the chain.
|
|
@@ -134,4 +149,3 @@ export declare const DESTINATION_CHAINS: {
|
|
|
134
149
|
* Mapping of chain ID to name for backward compatibility.
|
|
135
150
|
*/
|
|
136
151
|
export declare const SupportedChainsMap: Record<number, string>;
|
|
137
|
-
//# sourceMappingURL=chains.d.ts.map
|
package/dist/chains.js
CHANGED
|
@@ -6,8 +6,9 @@
|
|
|
6
6
|
*/
|
|
7
7
|
// Chain IDs
|
|
8
8
|
export const BASE_CHAIN_ID = 8453;
|
|
9
|
+
export const ETHEREUM_CHAIN_ID = 1;
|
|
9
10
|
export const HYPEREVM_CHAIN_ID = 999;
|
|
10
|
-
export const SOLANA_CHAIN_ID =
|
|
11
|
+
export const SOLANA_CHAIN_ID = 792703809;
|
|
11
12
|
export const SUPPORTED_DESTINATION_TOKEN_ALIASES = ['USDC', 'USDT'];
|
|
12
13
|
export const DEFAULT_DESTINATION_TOKEN_ALIAS = 'USDC';
|
|
13
14
|
// Mainnet chain configurations
|
|
@@ -120,8 +121,8 @@ const CHAIN_SELECTION_ALIASES = {
|
|
|
120
121
|
hyperliquid: 999,
|
|
121
122
|
hyperevm: 999,
|
|
122
123
|
hl: 999,
|
|
123
|
-
solana:
|
|
124
|
-
sol:
|
|
124
|
+
solana: 792703809,
|
|
125
|
+
sol: 792703809,
|
|
125
126
|
};
|
|
126
127
|
for (const chainId of SUPPORTED_CHAIN_IDS) {
|
|
127
128
|
const chainConfig = MAINNET_CHAINS[chainId];
|
|
@@ -135,6 +136,10 @@ for (const chainId of SUPPORTED_CHAIN_IDS) {
|
|
|
135
136
|
}
|
|
136
137
|
}
|
|
137
138
|
const DESTINATION_TOKEN_ADDRESSES = {
|
|
139
|
+
// Base
|
|
140
|
+
8453: {
|
|
141
|
+
usdt: '0xfde4C96c8593536E31F229EA8f37b2ADa2699bb2',
|
|
142
|
+
},
|
|
138
143
|
// Ethereum
|
|
139
144
|
1: {
|
|
140
145
|
usdt: '0xdAC17F958D2ee523a2206206994597C13D831ec7',
|
|
@@ -265,6 +270,63 @@ export function resolveDestinationTokenAddress(destinationToken, destinationChai
|
|
|
265
270
|
}
|
|
266
271
|
return token;
|
|
267
272
|
}
|
|
273
|
+
/**
|
|
274
|
+
* Check whether the final payout destination is native Base USDC.
|
|
275
|
+
* Any other token or chain requires a Relay / Privy payout conversion step.
|
|
276
|
+
*/
|
|
277
|
+
export function isBaseUsdcDestination(destinationChainId, destinationToken) {
|
|
278
|
+
if (destinationChainId === null || destinationChainId === undefined) {
|
|
279
|
+
return false;
|
|
280
|
+
}
|
|
281
|
+
const chainId = Number(destinationChainId);
|
|
282
|
+
const token = destinationToken?.trim();
|
|
283
|
+
if (!token) {
|
|
284
|
+
return false;
|
|
285
|
+
}
|
|
286
|
+
if (chainId !== BASE_CHAIN_ID) {
|
|
287
|
+
return false;
|
|
288
|
+
}
|
|
289
|
+
const resolvedTokenAddress = resolveDestinationTokenAddress(token, chainId);
|
|
290
|
+
const baseUsdcAddress = getUsdcAddress(BASE_CHAIN_ID);
|
|
291
|
+
return Boolean(resolvedTokenAddress &&
|
|
292
|
+
baseUsdcAddress &&
|
|
293
|
+
resolvedTokenAddress.toLowerCase() === baseUsdcAddress.toLowerCase());
|
|
294
|
+
}
|
|
295
|
+
/**
|
|
296
|
+
* Determine whether a payout needs Relay / Privy after Base settlement.
|
|
297
|
+
* This is true for every destination except native Base USDC.
|
|
298
|
+
*/
|
|
299
|
+
export function requiresRelayPayout(destinationChainId, destinationToken) {
|
|
300
|
+
return !isBaseUsdcDestination(destinationChainId, destinationToken);
|
|
301
|
+
}
|
|
302
|
+
/**
|
|
303
|
+
* Resolve a destination token value into its canonical symbol for display.
|
|
304
|
+
* Known aliases and configured chain token addresses map to USDC/USDT.
|
|
305
|
+
*/
|
|
306
|
+
export function resolveDestinationTokenSymbol(destinationToken, destinationChainId) {
|
|
307
|
+
const token = destinationToken?.trim();
|
|
308
|
+
if (!token) {
|
|
309
|
+
return DEFAULT_DESTINATION_TOKEN_ALIAS;
|
|
310
|
+
}
|
|
311
|
+
const tokenAlias = normalizeDestinationTokenAlias(token);
|
|
312
|
+
if (tokenAlias) {
|
|
313
|
+
return tokenAlias;
|
|
314
|
+
}
|
|
315
|
+
const chainId = destinationChainId === null || destinationChainId === undefined
|
|
316
|
+
? null
|
|
317
|
+
: Number(destinationChainId);
|
|
318
|
+
if (chainId !== null) {
|
|
319
|
+
const usdcAddress = getUsdcAddress(chainId);
|
|
320
|
+
if (usdcAddress && usdcAddress.toLowerCase() === token.toLowerCase()) {
|
|
321
|
+
return 'USDC';
|
|
322
|
+
}
|
|
323
|
+
const usdtAddress = DESTINATION_TOKEN_ADDRESSES[chainId]?.usdt;
|
|
324
|
+
if (usdtAddress && usdtAddress.toLowerCase() === token.toLowerCase()) {
|
|
325
|
+
return 'USDT';
|
|
326
|
+
}
|
|
327
|
+
}
|
|
328
|
+
return token.toUpperCase();
|
|
329
|
+
}
|
|
268
330
|
/**
|
|
269
331
|
* Get supported destination token aliases for a destination chain.
|
|
270
332
|
* Token support is derived from resolvable token addresses for the chain.
|
package/dist/crypto.d.ts
ADDED
|
@@ -0,0 +1,65 @@
|
|
|
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
|
+
/**
|
|
8
|
+
* Display-order priority for the "Pay with crypto" chain dropdown.
|
|
9
|
+
* Chains not in this list fall back to the existing numeric chain-ID
|
|
10
|
+
* iteration order of PAY_CRYPTO_CHAIN_CONFIGS as a stable tiebreaker.
|
|
11
|
+
*/
|
|
12
|
+
export declare const PAY_CRYPTO_CHAIN_DISPLAY_PRIORITY: readonly number[];
|
|
13
|
+
export declare const STABLECOIN_SYMBOLS: Set<"USDC" | "USDT" | "ETH" | "BNB" | "SOL" | "BTC" | "PYUSD" | "HYPE" | "WBTC" | "USDH">;
|
|
14
|
+
export interface SupportedCryptoTokenConfig {
|
|
15
|
+
chainId: number;
|
|
16
|
+
chainName: string;
|
|
17
|
+
chainShortName: string;
|
|
18
|
+
symbol: PayCryptoTokenSymbol;
|
|
19
|
+
address: string;
|
|
20
|
+
decimals: number;
|
|
21
|
+
isNative: boolean;
|
|
22
|
+
}
|
|
23
|
+
export declare function normalizePayCryptoTokenSymbol(value: string | null | undefined): PayCryptoTokenSymbol | null;
|
|
24
|
+
export declare function isStablecoinSymbol(symbol: string | null | undefined): boolean;
|
|
25
|
+
export declare function getSupportedPayCryptoTokenConfigsForChain(chainId: number, enabledSymbols?: readonly string[] | null): SupportedCryptoTokenConfig[];
|
|
26
|
+
export declare function getSupportedPayCryptoChainIds(enabledSymbols?: readonly string[] | null): number[];
|
|
27
|
+
/**
|
|
28
|
+
* Returns the union of tokens supported by any of `enabledChainIds`,
|
|
29
|
+
* sorted by the canonical pay-crypto display order
|
|
30
|
+
* (DEFAULT_ENABLED_PAY_CRYPTO_TOKENS order).
|
|
31
|
+
*
|
|
32
|
+
* When `enabledChainIds` is undefined, uses every supported chain.
|
|
33
|
+
* When `enabledChainIds` is an empty array, returns [].
|
|
34
|
+
*/
|
|
35
|
+
export declare function getAvailablePayCryptoTokens(enabledChainIds?: readonly number[]): PayCryptoTokenSymbol[];
|
|
36
|
+
/**
|
|
37
|
+
* Returns the chain IDs that support `symbol`, optionally filtered
|
|
38
|
+
* to `enabledChainIds`, sorted by PAY_CRYPTO_CHAIN_DISPLAY_PRIORITY
|
|
39
|
+
* with ascending numeric chain-ID order as the stable tiebreaker.
|
|
40
|
+
*
|
|
41
|
+
* When `enabledChainIds` is undefined, uses every supported chain.
|
|
42
|
+
* When `enabledChainIds` is an empty array, returns [].
|
|
43
|
+
*/
|
|
44
|
+
export declare function getSupportedPayCryptoChainIdsForToken(symbol: PayCryptoTokenSymbol, enabledChainIds?: readonly number[]): number[];
|
|
45
|
+
/**
|
|
46
|
+
* Returns the display name for a chain used by the "Pay with crypto"
|
|
47
|
+
* flow. Resolves through PAY_CRYPTO_CHAIN_CONFIGS first so Bitcoin
|
|
48
|
+
* and Tron (which are not in MAINNET_CHAINS) get the correct label.
|
|
49
|
+
* Falls back to getChainName for chains not registered here.
|
|
50
|
+
*/
|
|
51
|
+
export declare function getPayCryptoChainName(chainId: number): string;
|
|
52
|
+
export declare function resolvePayCryptoTokenConfig(chainId: number, symbol: string | null | undefined): SupportedCryptoTokenConfig | null;
|
|
53
|
+
/**
|
|
54
|
+
* Reverse lookup of a token config by contract address on a specific chain.
|
|
55
|
+
* Address comparison is case-insensitive. Returns null if the chain is unknown
|
|
56
|
+
* or if no token at that address is registered for the chain.
|
|
57
|
+
*
|
|
58
|
+
* Used by the crypto fulfillment resolver to translate a Relay request's inTx
|
|
59
|
+
* tokenAddress (lowercased, chain-qualified) into a human-readable symbol and
|
|
60
|
+
* decimals, so payment.currency and payment.paymentAmount can be written
|
|
61
|
+
* correctly for whatever token the customer actually deposited.
|
|
62
|
+
*/
|
|
63
|
+
export declare function resolvePayCryptoTokenConfigByAddress(chainId: number, address: string | null | undefined): SupportedCryptoTokenConfig | null;
|
|
64
|
+
export declare function getSupportedDestinationBalanceTokenConfigsForChain(chainId: number, enabledSymbols?: readonly string[] | null): SupportedCryptoTokenConfig[];
|
|
65
|
+
export declare function resolveDestinationBalanceTokenConfig(chainId: number, symbol: string | null | undefined): SupportedCryptoTokenConfig | null;
|
package/dist/crypto.js
ADDED
|
@@ -0,0 +1,291 @@
|
|
|
1
|
+
import { MAINNET_CHAINS, BASE_CHAIN_ID, ETHEREUM_CHAIN_ID, SOLANA_CHAIN_ID, getChainName, } 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
|
+
'ETH',
|
|
19
|
+
'USDT',
|
|
20
|
+
'USDC',
|
|
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
|
+
/**
|
|
33
|
+
* Display-order priority for the "Pay with crypto" chain dropdown.
|
|
34
|
+
* Chains not in this list fall back to the existing numeric chain-ID
|
|
35
|
+
* iteration order of PAY_CRYPTO_CHAIN_CONFIGS as a stable tiebreaker.
|
|
36
|
+
*/
|
|
37
|
+
export const PAY_CRYPTO_CHAIN_DISPLAY_PRIORITY = [
|
|
38
|
+
BITCOIN_CHAIN_ID,
|
|
39
|
+
ETHEREUM_CHAIN_ID,
|
|
40
|
+
SOLANA_CHAIN_ID,
|
|
41
|
+
BASE_CHAIN_ID,
|
|
42
|
+
];
|
|
43
|
+
export const STABLECOIN_SYMBOLS = new Set([
|
|
44
|
+
'USDC',
|
|
45
|
+
'USDT',
|
|
46
|
+
'PYUSD',
|
|
47
|
+
'USDH',
|
|
48
|
+
]);
|
|
49
|
+
const NATIVE_ETH_ADDRESS = '0x0000000000000000000000000000000000000000';
|
|
50
|
+
const NATIVE_SOL_ADDRESS = '11111111111111111111111111111111';
|
|
51
|
+
const NATIVE_BTC_ADDRESS = 'bc1qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqmql8k8';
|
|
52
|
+
const PAY_CRYPTO_CHAIN_CONFIGS = {
|
|
53
|
+
...MAINNET_CHAINS,
|
|
54
|
+
[BITCOIN_CHAIN_ID]: {
|
|
55
|
+
chainId: BITCOIN_CHAIN_ID,
|
|
56
|
+
name: 'Bitcoin',
|
|
57
|
+
shortName: 'BTC',
|
|
58
|
+
},
|
|
59
|
+
[TRON_CHAIN_ID]: {
|
|
60
|
+
chainId: TRON_CHAIN_ID,
|
|
61
|
+
name: 'Tron',
|
|
62
|
+
shortName: 'TRON',
|
|
63
|
+
},
|
|
64
|
+
};
|
|
65
|
+
const CHAIN_TOKEN_CONFIGS = {
|
|
66
|
+
[BITCOIN_CHAIN_ID]: {
|
|
67
|
+
BTC: { address: NATIVE_BTC_ADDRESS, decimals: 8, isNative: true },
|
|
68
|
+
},
|
|
69
|
+
1: {
|
|
70
|
+
ETH: { address: NATIVE_ETH_ADDRESS, decimals: 18, isNative: true },
|
|
71
|
+
USDC: { address: '0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48', decimals: 6, isNative: false },
|
|
72
|
+
USDT: { address: '0xdAC17F958D2ee523a2206206994597C13D831ec7', decimals: 6, isNative: false },
|
|
73
|
+
PYUSD: { address: '0x6c3ea9036406852006290770bedfcaba0e23a0e8', decimals: 6, isNative: false },
|
|
74
|
+
WBTC: { address: '0x2260fac5e5542a773aa44fbcfedf7c193bc2c599', decimals: 8, isNative: false },
|
|
75
|
+
},
|
|
76
|
+
10: {
|
|
77
|
+
ETH: { address: NATIVE_ETH_ADDRESS, decimals: 18, isNative: true },
|
|
78
|
+
USDC: { address: '0x0b2C639c533813f4Aa9D7837CAf62653d097Ff85', decimals: 6, isNative: false },
|
|
79
|
+
USDT: { address: '0x94b008aA00579c1307B0EF2c499aD98a8ce58e58', decimals: 6, isNative: false },
|
|
80
|
+
},
|
|
81
|
+
56: {
|
|
82
|
+
BNB: { address: NATIVE_ETH_ADDRESS, decimals: 18, isNative: true },
|
|
83
|
+
USDC: { address: '0x8AC76a51cc950d9822D68b83fE1Ad97B32Cd580d', decimals: 18, isNative: false },
|
|
84
|
+
USDT: { address: '0x55d398326f99059fF775485246999027B3197955', decimals: 18, isNative: false },
|
|
85
|
+
WBTC: { address: '0x0555e30da8f98308edb960aa94c0db47230d2b9c', decimals: 8, isNative: false },
|
|
86
|
+
},
|
|
87
|
+
137: {
|
|
88
|
+
USDC: { address: '0x3c499c542cEF5E3811e1192ce70d8cC03d5c3359', decimals: 6, isNative: false },
|
|
89
|
+
USDT: { address: '0xc2132D05D31c914a87C6611C10748AEb04B58e8F', decimals: 6, isNative: false },
|
|
90
|
+
WBTC: { address: '0x1bfd67037b42cf73acf2047067bd4f2c47d9bfd6', decimals: 8, isNative: false },
|
|
91
|
+
},
|
|
92
|
+
480: {
|
|
93
|
+
ETH: { address: NATIVE_ETH_ADDRESS, decimals: 18, isNative: true },
|
|
94
|
+
USDC: { address: '0x79A02482A880bCE3F13e09Da970dC34db4CD24d1', decimals: 6, isNative: false },
|
|
95
|
+
},
|
|
96
|
+
999: {
|
|
97
|
+
HYPE: { address: NATIVE_ETH_ADDRESS, decimals: 18, isNative: true },
|
|
98
|
+
USDC: { address: '0xb88339CB7199b77E23DB6E890353E22632Ba630f', decimals: 6, isNative: false },
|
|
99
|
+
USDH: { address: '0x111111a1a0667d36bd57c0a9f569b98057111111', decimals: 6, isNative: false },
|
|
100
|
+
},
|
|
101
|
+
8453: {
|
|
102
|
+
ETH: { address: NATIVE_ETH_ADDRESS, decimals: 18, isNative: true },
|
|
103
|
+
USDC: { address: '0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913', decimals: 6, isNative: false },
|
|
104
|
+
USDT: { address: '0xfde4C96c8593536E31F229EA8f37b2ADa2699bb2', decimals: 6, isNative: false },
|
|
105
|
+
SOL: { address: '0x311935cd80b76769bf2ecc9d8ab7635b2139cf82', decimals: 9, isNative: false },
|
|
106
|
+
WBTC: { address: '0x0555e30da8f98308edb960aa94c0db47230d2b9c', decimals: 8, isNative: false },
|
|
107
|
+
},
|
|
108
|
+
42161: {
|
|
109
|
+
ETH: { address: NATIVE_ETH_ADDRESS, decimals: 18, isNative: true },
|
|
110
|
+
USDC: { address: '0xaf88d065e77c8cC2239327C5EDb3A432268e5831', decimals: 6, isNative: false },
|
|
111
|
+
USDT: { address: '0xFd086bC7CD5C481DCC9C85ebE478A1C0b69FCbb9', decimals: 6, isNative: false },
|
|
112
|
+
WBTC: { address: '0x2f2a2543b76a4166549f7aab2e75bef0aefc5b0f', decimals: 8, isNative: false },
|
|
113
|
+
},
|
|
114
|
+
[TRON_CHAIN_ID]: {
|
|
115
|
+
USDT: { address: 'TR7NHqjeKQxGTCi8q8ZY4pL8otSzgjLj6t', decimals: 6, isNative: false },
|
|
116
|
+
},
|
|
117
|
+
792703809: {
|
|
118
|
+
SOL: { address: NATIVE_SOL_ADDRESS, decimals: 9, isNative: true },
|
|
119
|
+
USDC: { address: 'EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v', decimals: 6, isNative: false },
|
|
120
|
+
USDT: { address: 'Es9vMFrzaCERmJfrF4H2FYD4KCoNkY11McCe8BenwNYB', decimals: 6, isNative: false },
|
|
121
|
+
PYUSD: { address: '2b1kV6DkPAnxd5ixfnxCpjxmKwqjjaYmCZfHsFu24GXo', decimals: 6, isNative: false },
|
|
122
|
+
},
|
|
123
|
+
};
|
|
124
|
+
function isPayCryptoTokenSymbol(value) {
|
|
125
|
+
return PAY_CRYPTO_TOKEN_SYMBOLS.includes(value);
|
|
126
|
+
}
|
|
127
|
+
export function normalizePayCryptoTokenSymbol(value) {
|
|
128
|
+
const normalized = value?.trim().toUpperCase();
|
|
129
|
+
if (!normalized) {
|
|
130
|
+
return null;
|
|
131
|
+
}
|
|
132
|
+
return isPayCryptoTokenSymbol(normalized) ? normalized : null;
|
|
133
|
+
}
|
|
134
|
+
export function isStablecoinSymbol(symbol) {
|
|
135
|
+
const normalizedSymbol = normalizePayCryptoTokenSymbol(symbol);
|
|
136
|
+
return Boolean(normalizedSymbol && STABLECOIN_SYMBOLS.has(normalizedSymbol));
|
|
137
|
+
}
|
|
138
|
+
function normalizeEnabledSymbols(enabledSymbols, fallback) {
|
|
139
|
+
const normalized = (enabledSymbols ?? [])
|
|
140
|
+
.map((value) => normalizePayCryptoTokenSymbol(value))
|
|
141
|
+
.filter((value) => value !== null);
|
|
142
|
+
return normalized.length > 0 ? normalized : [...fallback];
|
|
143
|
+
}
|
|
144
|
+
function buildSupportedCryptoTokenConfig(chain, symbol) {
|
|
145
|
+
const config = CHAIN_TOKEN_CONFIGS[chain.chainId]?.[symbol];
|
|
146
|
+
if (!config) {
|
|
147
|
+
return null;
|
|
148
|
+
}
|
|
149
|
+
return {
|
|
150
|
+
chainId: chain.chainId,
|
|
151
|
+
chainName: chain.name,
|
|
152
|
+
chainShortName: chain.shortName,
|
|
153
|
+
symbol,
|
|
154
|
+
address: config.address,
|
|
155
|
+
decimals: config.decimals,
|
|
156
|
+
isNative: config.isNative,
|
|
157
|
+
};
|
|
158
|
+
}
|
|
159
|
+
export function getSupportedPayCryptoTokenConfigsForChain(chainId, enabledSymbols) {
|
|
160
|
+
const chain = PAY_CRYPTO_CHAIN_CONFIGS[chainId];
|
|
161
|
+
if (!chain) {
|
|
162
|
+
return [];
|
|
163
|
+
}
|
|
164
|
+
const allowedSymbols = normalizeEnabledSymbols(enabledSymbols, DEFAULT_ENABLED_PAY_CRYPTO_TOKENS);
|
|
165
|
+
return allowedSymbols
|
|
166
|
+
.map((symbol) => buildSupportedCryptoTokenConfig(chain, symbol))
|
|
167
|
+
.filter((value) => value !== null);
|
|
168
|
+
}
|
|
169
|
+
export function getSupportedPayCryptoChainIds(enabledSymbols) {
|
|
170
|
+
return Object.keys(PAY_CRYPTO_CHAIN_CONFIGS)
|
|
171
|
+
.map(Number)
|
|
172
|
+
.filter((chainId) => getSupportedPayCryptoTokenConfigsForChain(chainId, enabledSymbols).length > 0);
|
|
173
|
+
}
|
|
174
|
+
/**
|
|
175
|
+
* Returns the union of tokens supported by any of `enabledChainIds`,
|
|
176
|
+
* sorted by the canonical pay-crypto display order
|
|
177
|
+
* (DEFAULT_ENABLED_PAY_CRYPTO_TOKENS order).
|
|
178
|
+
*
|
|
179
|
+
* When `enabledChainIds` is undefined, uses every supported chain.
|
|
180
|
+
* When `enabledChainIds` is an empty array, returns [].
|
|
181
|
+
*/
|
|
182
|
+
export function getAvailablePayCryptoTokens(enabledChainIds) {
|
|
183
|
+
const chainIds = enabledChainIds === undefined
|
|
184
|
+
? Object.keys(CHAIN_TOKEN_CONFIGS).map(Number)
|
|
185
|
+
: enabledChainIds;
|
|
186
|
+
const available = new Set();
|
|
187
|
+
for (const chainId of chainIds) {
|
|
188
|
+
const chainTokens = CHAIN_TOKEN_CONFIGS[chainId];
|
|
189
|
+
if (chainTokens === undefined)
|
|
190
|
+
continue;
|
|
191
|
+
for (const symbol of Object.keys(chainTokens)) {
|
|
192
|
+
available.add(symbol);
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
return DEFAULT_ENABLED_PAY_CRYPTO_TOKENS.filter((symbol) => available.has(symbol));
|
|
196
|
+
}
|
|
197
|
+
/**
|
|
198
|
+
* Returns the chain IDs that support `symbol`, optionally filtered
|
|
199
|
+
* to `enabledChainIds`, sorted by PAY_CRYPTO_CHAIN_DISPLAY_PRIORITY
|
|
200
|
+
* with ascending numeric chain-ID order as the stable tiebreaker.
|
|
201
|
+
*
|
|
202
|
+
* When `enabledChainIds` is undefined, uses every supported chain.
|
|
203
|
+
* When `enabledChainIds` is an empty array, returns [].
|
|
204
|
+
*/
|
|
205
|
+
export function getSupportedPayCryptoChainIdsForToken(symbol, enabledChainIds) {
|
|
206
|
+
const candidateChainIds = enabledChainIds === undefined
|
|
207
|
+
? Object.keys(CHAIN_TOKEN_CONFIGS).map(Number)
|
|
208
|
+
: Array.from(new Set(enabledChainIds));
|
|
209
|
+
const supporting = candidateChainIds.filter((chainId) => (CHAIN_TOKEN_CONFIGS[chainId]?.[symbol] !== undefined));
|
|
210
|
+
const supportingSet = new Set(supporting);
|
|
211
|
+
const priorityPortion = PAY_CRYPTO_CHAIN_DISPLAY_PRIORITY
|
|
212
|
+
.filter((chainId) => supportingSet.has(chainId));
|
|
213
|
+
const prioritySet = new Set(PAY_CRYPTO_CHAIN_DISPLAY_PRIORITY);
|
|
214
|
+
const restPortion = supporting
|
|
215
|
+
.filter((chainId) => !prioritySet.has(chainId))
|
|
216
|
+
.sort((a, b) => a - b);
|
|
217
|
+
return [...priorityPortion, ...restPortion];
|
|
218
|
+
}
|
|
219
|
+
/**
|
|
220
|
+
* Returns the display name for a chain used by the "Pay with crypto"
|
|
221
|
+
* flow. Resolves through PAY_CRYPTO_CHAIN_CONFIGS first so Bitcoin
|
|
222
|
+
* and Tron (which are not in MAINNET_CHAINS) get the correct label.
|
|
223
|
+
* Falls back to getChainName for chains not registered here.
|
|
224
|
+
*/
|
|
225
|
+
export function getPayCryptoChainName(chainId) {
|
|
226
|
+
return PAY_CRYPTO_CHAIN_CONFIGS[chainId]?.name ?? getChainName(chainId);
|
|
227
|
+
}
|
|
228
|
+
export function resolvePayCryptoTokenConfig(chainId, symbol) {
|
|
229
|
+
const normalizedSymbol = normalizePayCryptoTokenSymbol(symbol);
|
|
230
|
+
if (!normalizedSymbol) {
|
|
231
|
+
return null;
|
|
232
|
+
}
|
|
233
|
+
const chain = PAY_CRYPTO_CHAIN_CONFIGS[chainId];
|
|
234
|
+
if (!chain) {
|
|
235
|
+
return null;
|
|
236
|
+
}
|
|
237
|
+
return buildSupportedCryptoTokenConfig(chain, normalizedSymbol);
|
|
238
|
+
}
|
|
239
|
+
/**
|
|
240
|
+
* Reverse lookup of a token config by contract address on a specific chain.
|
|
241
|
+
* Address comparison is case-insensitive. Returns null if the chain is unknown
|
|
242
|
+
* or if no token at that address is registered for the chain.
|
|
243
|
+
*
|
|
244
|
+
* Used by the crypto fulfillment resolver to translate a Relay request's inTx
|
|
245
|
+
* tokenAddress (lowercased, chain-qualified) into a human-readable symbol and
|
|
246
|
+
* decimals, so payment.currency and payment.paymentAmount can be written
|
|
247
|
+
* correctly for whatever token the customer actually deposited.
|
|
248
|
+
*/
|
|
249
|
+
export function resolvePayCryptoTokenConfigByAddress(chainId, address) {
|
|
250
|
+
if (typeof address !== 'string')
|
|
251
|
+
return null;
|
|
252
|
+
const needle = address.trim().toLowerCase();
|
|
253
|
+
if (needle === '')
|
|
254
|
+
return null;
|
|
255
|
+
const chainTokens = CHAIN_TOKEN_CONFIGS[chainId];
|
|
256
|
+
if (chainTokens === undefined)
|
|
257
|
+
return null;
|
|
258
|
+
const chain = PAY_CRYPTO_CHAIN_CONFIGS[chainId];
|
|
259
|
+
if (chain === undefined)
|
|
260
|
+
return null;
|
|
261
|
+
for (const symbolKey of Object.keys(chainTokens)) {
|
|
262
|
+
const cfg = chainTokens[symbolKey];
|
|
263
|
+
if (cfg === undefined)
|
|
264
|
+
continue;
|
|
265
|
+
if (cfg.address.toLowerCase() === needle) {
|
|
266
|
+
return {
|
|
267
|
+
chainId: chain.chainId,
|
|
268
|
+
chainName: chain.name,
|
|
269
|
+
chainShortName: chain.shortName,
|
|
270
|
+
symbol: symbolKey,
|
|
271
|
+
address: cfg.address,
|
|
272
|
+
decimals: cfg.decimals,
|
|
273
|
+
isNative: cfg.isNative,
|
|
274
|
+
};
|
|
275
|
+
}
|
|
276
|
+
}
|
|
277
|
+
return null;
|
|
278
|
+
}
|
|
279
|
+
export function getSupportedDestinationBalanceTokenConfigsForChain(chainId, enabledSymbols) {
|
|
280
|
+
const chain = MAINNET_CHAINS[chainId];
|
|
281
|
+
if (!chain) {
|
|
282
|
+
return [];
|
|
283
|
+
}
|
|
284
|
+
const allowedSymbols = normalizeEnabledSymbols(enabledSymbols, DEFAULT_ENABLED_DESTINATION_TOKENS);
|
|
285
|
+
return allowedSymbols
|
|
286
|
+
.map((symbol) => buildSupportedCryptoTokenConfig(chain, symbol))
|
|
287
|
+
.filter((value) => value !== null);
|
|
288
|
+
}
|
|
289
|
+
export function resolveDestinationBalanceTokenConfig(chainId, symbol) {
|
|
290
|
+
return resolvePayCryptoTokenConfig(chainId, symbol);
|
|
291
|
+
}
|
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 {};
|