@zkp2p/pay-shared 5.0.0 → 6.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/README.md +14 -1
- package/dist/attribution.d.ts +2 -1
- package/dist/attribution.js +1 -0
- package/dist/bitcoin.d.ts +4 -0
- package/dist/bitcoin.js +38 -6
- package/dist/cashoutRails.d.ts +34 -0
- package/dist/cashoutRails.js +71 -0
- package/dist/crypto.d.ts +39 -0
- package/dist/crypto.js +110 -3
- package/dist/index.d.ts +1 -0
- package/dist/index.js +1 -0
- package/dist/types.d.ts +665 -2
- package/dist/types.js +148 -1
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -9,7 +9,7 @@ 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@6.0.0
|
|
13
13
|
```
|
|
14
14
|
|
|
15
15
|
## Published artifacts
|
|
@@ -85,6 +85,10 @@ Core type exports:
|
|
|
85
85
|
- `CheckoutAggregate`
|
|
86
86
|
- `CheckoutQuotes`
|
|
87
87
|
- `MerchantProfile`
|
|
88
|
+
- `CashoutView`
|
|
89
|
+
- `CashoutRailType`
|
|
90
|
+
- `WebhookPayload`
|
|
91
|
+
- `CashoutWebhookPayload`
|
|
88
92
|
|
|
89
93
|
Core constants:
|
|
90
94
|
|
|
@@ -96,6 +100,15 @@ Core constants:
|
|
|
96
100
|
- `ProofAttemptStatus`
|
|
97
101
|
- `OrderErrorCode`
|
|
98
102
|
- `MerchantEnvironment`
|
|
103
|
+
- `CashoutStatus`
|
|
104
|
+
- `CashoutRail`
|
|
105
|
+
- `CashoutCryptoRail`
|
|
106
|
+
- `CashoutPayoutProvider`
|
|
107
|
+
- `PAY_CRYPTO_TOKEN_SYMBOLS`
|
|
108
|
+
|
|
109
|
+
Webhook helpers:
|
|
110
|
+
|
|
111
|
+
- `isCashoutWebhook(...)` — narrows `WebhookPayload` to `CashoutWebhookPayload`
|
|
99
112
|
|
|
100
113
|
Chain constants and helpers:
|
|
101
114
|
|
package/dist/attribution.d.ts
CHANGED
package/dist/attribution.js
CHANGED
|
@@ -2,4 +2,5 @@ export var IntentAttributionReferrer;
|
|
|
2
2
|
(function (IntentAttributionReferrer) {
|
|
3
3
|
IntentAttributionReferrer["PAY"] = "zkp2p-pay";
|
|
4
4
|
IntentAttributionReferrer["SUPPORT"] = "zkp2p-pay-cs";
|
|
5
|
+
IntentAttributionReferrer["CASHOUT"] = "zkp2p-pay-cashout";
|
|
5
6
|
})(IntentAttributionReferrer || (IntentAttributionReferrer = {}));
|
package/dist/bitcoin.d.ts
CHANGED
|
@@ -1 +1,5 @@
|
|
|
1
1
|
export declare function isValidBitcoinAddress(value: string): boolean;
|
|
2
|
+
/** A Bitcoin txid as Relay writes it: 64 lower-case hex digits, no 0x prefix. */
|
|
3
|
+
export declare function isBitcoinTxid(value: string): boolean;
|
|
4
|
+
/** A mainnet P2WPKH address (bech32, witness version 0, lower-case) for a 20-byte witness program. */
|
|
5
|
+
export declare function encodeBitcoinP2wpkhAddress(program: Uint8Array): string;
|
package/dist/bitcoin.js
CHANGED
|
@@ -2,6 +2,13 @@ import { hasBase58CheckChecksum } from './addressEncoding.js';
|
|
|
2
2
|
const BECH32_ALPHABET = 'qpzry9x8gf2tvdw0s3jn54khce6mua7l';
|
|
3
3
|
const BECH32_CHECKSUM = 1;
|
|
4
4
|
const BECH32M_CHECKSUM = 0x2bc830a3;
|
|
5
|
+
// The bech32 HRP "bc" expanded for the checksum: high bits, a zero, low bits.
|
|
6
|
+
const BITCOIN_HRP_VALUES = [
|
|
7
|
+
...[...'bc'].map((character) => character.charCodeAt(0) >>> 5),
|
|
8
|
+
0,
|
|
9
|
+
...[...'bc'].map((character) => character.charCodeAt(0) & 31),
|
|
10
|
+
];
|
|
11
|
+
const BITCOIN_TXID_PATTERN = /^[0-9a-f]{64}$/;
|
|
5
12
|
function calculatePolymod(values) {
|
|
6
13
|
const generators = [0x3b6a57b2, 0x26508e6d, 0x1ea119fa, 0x3d4233dd, 0x2a1462b3];
|
|
7
14
|
let checksum = 1;
|
|
@@ -33,6 +40,23 @@ function convertWitnessProgram(values) {
|
|
|
33
40
|
}
|
|
34
41
|
return Uint8Array.from(decoded);
|
|
35
42
|
}
|
|
43
|
+
/** 8-bit bytes to 5-bit bech32 words, padding the last word with zero bits. */
|
|
44
|
+
function toBech32Words(bytes) {
|
|
45
|
+
const words = [];
|
|
46
|
+
let accumulator = 0;
|
|
47
|
+
let bits = 0;
|
|
48
|
+
for (const byte of bytes) {
|
|
49
|
+
accumulator = ((accumulator << 8) | byte) & 0xffff;
|
|
50
|
+
bits += 8;
|
|
51
|
+
while (bits >= 5) {
|
|
52
|
+
bits -= 5;
|
|
53
|
+
words.push((accumulator >>> bits) & 31);
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
if (bits > 0)
|
|
57
|
+
words.push((accumulator << (5 - bits)) & 31);
|
|
58
|
+
return words;
|
|
59
|
+
}
|
|
36
60
|
function isValidBech32Address(value) {
|
|
37
61
|
if (value.length > 90 || (value !== value.toLowerCase() && value !== value.toUpperCase())) {
|
|
38
62
|
return false;
|
|
@@ -47,13 +71,8 @@ function isValidBech32Address(value) {
|
|
|
47
71
|
if (data.length < 7 || data.some((item) => item === -1)) {
|
|
48
72
|
return false;
|
|
49
73
|
}
|
|
50
|
-
const hrpValues = [
|
|
51
|
-
...[...'bc'].map((character) => character.charCodeAt(0) >>> 5),
|
|
52
|
-
0,
|
|
53
|
-
...[...'bc'].map((character) => character.charCodeAt(0) & 31),
|
|
54
|
-
];
|
|
55
74
|
const witnessVersion = data[0];
|
|
56
|
-
const polymod = calculatePolymod([...
|
|
75
|
+
const polymod = calculatePolymod([...BITCOIN_HRP_VALUES, ...data]);
|
|
57
76
|
if (witnessVersion > 16
|
|
58
77
|
|| (witnessVersion === 0 && polymod !== BECH32_CHECKSUM)
|
|
59
78
|
|| (witnessVersion > 0 && polymod !== BECH32M_CHECKSUM)) {
|
|
@@ -77,3 +96,16 @@ export function isValidBitcoinAddress(value) {
|
|
|
77
96
|
&& (hasBase58CheckChecksum(trimmed, 0x00)
|
|
78
97
|
|| hasBase58CheckChecksum(trimmed, 0x05));
|
|
79
98
|
}
|
|
99
|
+
/** A Bitcoin txid as Relay writes it: 64 lower-case hex digits, no 0x prefix. */
|
|
100
|
+
export function isBitcoinTxid(value) {
|
|
101
|
+
return BITCOIN_TXID_PATTERN.test(value);
|
|
102
|
+
}
|
|
103
|
+
/** A mainnet P2WPKH address (bech32, witness version 0, lower-case) for a 20-byte witness program. */
|
|
104
|
+
export function encodeBitcoinP2wpkhAddress(program) {
|
|
105
|
+
if (program.length !== 20)
|
|
106
|
+
throw new Error('A P2WPKH witness program is 20 bytes');
|
|
107
|
+
const data = [0, ...toBech32Words(program)];
|
|
108
|
+
const polymod = calculatePolymod([...BITCOIN_HRP_VALUES, ...data, 0, 0, 0, 0, 0, 0]) ^ BECH32_CHECKSUM;
|
|
109
|
+
const checksum = [0, 1, 2, 3, 4, 5].map((index) => (polymod >>> (5 * (5 - index))) & 31);
|
|
110
|
+
return `bc1${[...data, ...checksum].map((value) => BECH32_ALPHABET[value]).join('')}`;
|
|
111
|
+
}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { type CashoutBuyerProofRailType, type CashoutCryptoRailType, type CashoutFiatRailType, type CashoutSarRailType } from './types.js';
|
|
2
|
+
/**
|
|
3
|
+
* The cashout rails SAR_SUPPORTED_FIAT_RAILS lists, in rail order: Venmo, Cash App and PayPal. Wise is SAR but not a
|
|
4
|
+
* cashout rail yet.
|
|
5
|
+
*/
|
|
6
|
+
export declare const CASHOUT_SAR_RAILS: ReadonlyArray<CashoutSarRailType>;
|
|
7
|
+
/** A rail in CASHOUT_SAR_RAILS. Exact rails only; a variant such as "venmo-x" is not a cashout rail. */
|
|
8
|
+
export declare function isCashoutSarRail(rail: string): rail is CashoutSarRailType;
|
|
9
|
+
/** A cashout fiat rail with no connect step: Zelle, Revolut and Chime. */
|
|
10
|
+
export declare function isCashoutBuyerProofRail(rail: string): rail is CashoutBuyerProofRailType;
|
|
11
|
+
/** Every crypto payout network's rail, in rail order (checkout's relay rail order). */
|
|
12
|
+
export declare const CASHOUT_CRYPTO_RAILS: ReadonlyArray<CashoutCryptoRailType>;
|
|
13
|
+
/** An exact crypto payout rail; replaces every comparison with the retired `crypto` rail. */
|
|
14
|
+
export declare function isCashoutCryptoRail(rail: string): rail is CashoutCryptoRailType;
|
|
15
|
+
export declare function cashoutCryptoRailChainId(rail: CashoutCryptoRailType): number;
|
|
16
|
+
export declare function cashoutCryptoRailForChain(chainId: number): CashoutCryptoRailType | null;
|
|
17
|
+
/** The payout chains a rail list offers, in rail order; the checkout's pickers and the server's checks read it. */
|
|
18
|
+
export declare function cashoutRailsChainIds(rails: ReadonlyArray<string>): number[];
|
|
19
|
+
export declare function hasCashoutCryptoRail(rails: ReadonlyArray<string>): boolean;
|
|
20
|
+
/**
|
|
21
|
+
* Venmo and PayPal listings get the Peer Pay merchant group. The set is @zkp2p/core's
|
|
22
|
+
* DISPUTE_PROTECTION_STAKE_PLATFORMS, which @zkp2p/sdk keeps private, and
|
|
23
|
+
* zkp2p-mobile's CHARGEBACK_PRONE_SELL_PLATFORMS. Cash App left that set on 2026-08-28.
|
|
24
|
+
*/
|
|
25
|
+
export declare const CASHOUT_PEER_PAY_GROUP_RAILS: readonly ["venmo", "paypal"];
|
|
26
|
+
/** Rails whose listings get the Peer Pay merchant group (CASHOUT_PEER_PAY_GROUP_RAILS). */
|
|
27
|
+
export type CashoutPeerPayGroupRailType = typeof CASHOUT_PEER_PAY_GROUP_RAILS[number];
|
|
28
|
+
/** A rail in CASHOUT_PEER_PAY_GROUP_RAILS. */
|
|
29
|
+
export declare function isCashoutPeerPayGroupRail(rail: string): rail is CashoutPeerPayGroupRailType;
|
|
30
|
+
/**
|
|
31
|
+
* A payout account as its rail writes it: "@alice" (Venmo, Revolut), "$alice1" (Cash App), "paypal.me/bob" (PayPal),
|
|
32
|
+
* the email (Zelle) and "$chimesign" (Chime, whose stored handle already carries its "$").
|
|
33
|
+
*/
|
|
34
|
+
export declare function cashoutAccountLabel(rail: CashoutFiatRailType, handle: string): string;
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
import { SAR_SUPPORTED_FIAT_RAILS, parseCryptoRailChainId } from './rails.js';
|
|
2
|
+
import { CashoutCryptoRail, CashoutFiatRail, CashoutRail, } from './types.js';
|
|
3
|
+
const CASHOUT_FIAT_RAIL_SET = new Set(Object.values(CashoutFiatRail));
|
|
4
|
+
const SAR_SUPPORTED_FIAT_RAIL_SET = new Set(SAR_SUPPORTED_FIAT_RAILS);
|
|
5
|
+
/**
|
|
6
|
+
* The cashout rails SAR_SUPPORTED_FIAT_RAILS lists, in rail order: Venmo, Cash App and PayPal. Wise is SAR but not a
|
|
7
|
+
* cashout rail yet.
|
|
8
|
+
*/
|
|
9
|
+
export const CASHOUT_SAR_RAILS = Object.values(CashoutFiatRail).filter((rail) => SAR_SUPPORTED_FIAT_RAIL_SET.has(rail));
|
|
10
|
+
const CASHOUT_SAR_RAIL_SET = new Set(CASHOUT_SAR_RAILS);
|
|
11
|
+
/** A rail in CASHOUT_SAR_RAILS. Exact rails only; a variant such as "venmo-x" is not a cashout rail. */
|
|
12
|
+
export function isCashoutSarRail(rail) {
|
|
13
|
+
return CASHOUT_SAR_RAIL_SET.has(rail);
|
|
14
|
+
}
|
|
15
|
+
/** A cashout fiat rail with no connect step: Zelle, Revolut and Chime. */
|
|
16
|
+
export function isCashoutBuyerProofRail(rail) {
|
|
17
|
+
return CASHOUT_FIAT_RAIL_SET.has(rail) && !CASHOUT_SAR_RAIL_SET.has(rail);
|
|
18
|
+
}
|
|
19
|
+
/** Every crypto payout network's rail, in rail order (checkout's relay rail order). */
|
|
20
|
+
export const CASHOUT_CRYPTO_RAILS = Object.values(CashoutCryptoRail);
|
|
21
|
+
const CASHOUT_CRYPTO_RAIL_SET = new Set(CASHOUT_CRYPTO_RAILS);
|
|
22
|
+
/** An exact crypto payout rail; replaces every comparison with the retired `crypto` rail. */
|
|
23
|
+
export function isCashoutCryptoRail(rail) {
|
|
24
|
+
return CASHOUT_CRYPTO_RAIL_SET.has(rail);
|
|
25
|
+
}
|
|
26
|
+
export function cashoutCryptoRailChainId(rail) {
|
|
27
|
+
const chainId = parseCryptoRailChainId(rail);
|
|
28
|
+
if (chainId === null)
|
|
29
|
+
throw new Error(`Cashout crypto rail ${rail} names no chain`);
|
|
30
|
+
return chainId;
|
|
31
|
+
}
|
|
32
|
+
const CASHOUT_CRYPTO_RAIL_BY_CHAIN = new Map(CASHOUT_CRYPTO_RAILS.map((rail) => [cashoutCryptoRailChainId(rail), rail]));
|
|
33
|
+
export function cashoutCryptoRailForChain(chainId) {
|
|
34
|
+
return CASHOUT_CRYPTO_RAIL_BY_CHAIN.get(chainId) ?? null;
|
|
35
|
+
}
|
|
36
|
+
/** The payout chains a rail list offers, in rail order; the checkout's pickers and the server's checks read it. */
|
|
37
|
+
export function cashoutRailsChainIds(rails) {
|
|
38
|
+
return CASHOUT_CRYPTO_RAILS.filter((rail) => rails.includes(rail)).map(cashoutCryptoRailChainId);
|
|
39
|
+
}
|
|
40
|
+
export function hasCashoutCryptoRail(rails) {
|
|
41
|
+
return rails.some(isCashoutCryptoRail);
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* Venmo and PayPal listings get the Peer Pay merchant group. The set is @zkp2p/core's
|
|
45
|
+
* DISPUTE_PROTECTION_STAKE_PLATFORMS, which @zkp2p/sdk keeps private, and
|
|
46
|
+
* zkp2p-mobile's CHARGEBACK_PRONE_SELL_PLATFORMS. Cash App left that set on 2026-08-28.
|
|
47
|
+
*/
|
|
48
|
+
export const CASHOUT_PEER_PAY_GROUP_RAILS = [CashoutRail.VENMO, CashoutRail.PAYPAL];
|
|
49
|
+
const CASHOUT_PEER_PAY_GROUP_RAIL_SET = new Set(CASHOUT_PEER_PAY_GROUP_RAILS);
|
|
50
|
+
/** A rail in CASHOUT_PEER_PAY_GROUP_RAILS. */
|
|
51
|
+
export function isCashoutPeerPayGroupRail(rail) {
|
|
52
|
+
return CASHOUT_PEER_PAY_GROUP_RAIL_SET.has(rail);
|
|
53
|
+
}
|
|
54
|
+
/**
|
|
55
|
+
* A payout account as its rail writes it: "@alice" (Venmo, Revolut), "$alice1" (Cash App), "paypal.me/bob" (PayPal),
|
|
56
|
+
* the email (Zelle) and "$chimesign" (Chime, whose stored handle already carries its "$").
|
|
57
|
+
*/
|
|
58
|
+
export function cashoutAccountLabel(rail, handle) {
|
|
59
|
+
switch (rail) {
|
|
60
|
+
case CashoutRail.VENMO:
|
|
61
|
+
case CashoutRail.REVOLUT:
|
|
62
|
+
return `@${handle.replace(/^@/u, '')}`;
|
|
63
|
+
case CashoutRail.CASHAPP:
|
|
64
|
+
return `$${handle.replace(/^\$/u, '')}`;
|
|
65
|
+
case CashoutRail.PAYPAL:
|
|
66
|
+
return `paypal.me/${handle}`;
|
|
67
|
+
case CashoutRail.ZELLE:
|
|
68
|
+
case CashoutRail.CHIME:
|
|
69
|
+
return handle;
|
|
70
|
+
}
|
|
71
|
+
}
|
package/dist/crypto.d.ts
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
export declare const BITCOIN_CHAIN_ID = 8253038;
|
|
2
2
|
export declare const ZCASH_CHAIN_ID = 133701;
|
|
3
3
|
export declare const ZCASH_ASSET = "nep141:zec.omft.near";
|
|
4
|
+
/** NEAR Intents' asset id for USDC on Base (origin of cashout payouts, destination of Zcash checkout payments). */
|
|
5
|
+
export declare const NEAR_BASE_USDC_ASSET = "nep141:base-0x833589fcd6edb6e08f4c7c32d4f71b54bda02913.omft.near";
|
|
4
6
|
export declare const PAY_CRYPTO_TOKEN_SYMBOLS: readonly ["BTC", "USDC", "USDT", "ETH", "PYUSD", "SOL", "BNB", "HYPE", "WBTC", "USDH", "ZEC"];
|
|
5
7
|
export type PayCryptoTokenSymbol = (typeof PAY_CRYPTO_TOKEN_SYMBOLS)[number];
|
|
6
8
|
export declare const DEFAULT_ENABLED_PAY_CRYPTO_TOKENS: PayCryptoTokenSymbol[];
|
|
@@ -21,6 +23,8 @@ export interface SupportedCryptoTokenConfig {
|
|
|
21
23
|
decimals: number;
|
|
22
24
|
isNative: boolean;
|
|
23
25
|
}
|
|
26
|
+
/** Relay's sentinel for native BTC. Its bech32 checksum verifies, but it decodes to a 19-byte witness-v0 program, so isValidBitcoinAddress rejects it and it never works as a refund address. */
|
|
27
|
+
export declare const BITCOIN_NATIVE_TOKEN_ADDRESS = "bc1qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqmql8k8";
|
|
24
28
|
export declare function normalizePayCryptoTokenSymbol(value: string | null | undefined): PayCryptoTokenSymbol | null;
|
|
25
29
|
export declare function isStablecoinSymbol(symbol: string | null | undefined): boolean;
|
|
26
30
|
export declare function getSupportedPayCryptoTokenConfigsForChain(chainId: number, enabledSymbols?: readonly string[] | null): SupportedCryptoTokenConfig[];
|
|
@@ -64,3 +68,38 @@ export declare function resolvePayCryptoTokenConfig(chainId: number, symbol: str
|
|
|
64
68
|
export declare function resolvePayCryptoTokenConfigByAddress(chainId: number, address: string | null | undefined): SupportedCryptoTokenConfig | null;
|
|
65
69
|
export declare function getSupportedDestinationBalanceTokenConfigsForChain(chainId: number, enabledSymbols?: readonly string[] | null): SupportedCryptoTokenConfig[];
|
|
66
70
|
export declare function resolveDestinationBalanceTokenConfig(chainId: number, symbol: string | null | undefined): SupportedCryptoTokenConfig | null;
|
|
71
|
+
/** Chains a cashout can be funded from through Relay. Zcash is out: ZEC funding is out of scope (2026-10-07). */
|
|
72
|
+
export declare const CASHOUT_FUNDING_CHAIN_IDS: readonly number[];
|
|
73
|
+
/**
|
|
74
|
+
* The tokens a cashout can be funded with: every supported pay-crypto token on a Relay-fundable chain. An explicit list,
|
|
75
|
+
* because isEvmChain answers true for chains the table doesn't know, which let Bitcoin and Zcash in by accident.
|
|
76
|
+
*/
|
|
77
|
+
export declare function getCashoutFundingTokenConfigs(): SupportedCryptoTokenConfig[];
|
|
78
|
+
/** The address formats a cashout address can take. */
|
|
79
|
+
export declare const CashoutAddressFamily: {
|
|
80
|
+
readonly EVM: "EVM";
|
|
81
|
+
readonly SOLANA: "SOLANA";
|
|
82
|
+
readonly TRON: "TRON";
|
|
83
|
+
readonly BITCOIN: "BITCOIN";
|
|
84
|
+
readonly ZCASH: "ZCASH";
|
|
85
|
+
};
|
|
86
|
+
export type CashoutAddressFamilyType = (typeof CashoutAddressFamily)[keyof typeof CashoutAddressFamily];
|
|
87
|
+
/**
|
|
88
|
+
* The address format a cashout address on this chain must have. Bitcoin, Solana and Tron map by id;
|
|
89
|
+
* Zcash is ZCASH (transparent addresses only, Zcash spec Z3). Every remaining chain in the pay-crypto token table
|
|
90
|
+
* is EVM; any other chain has none (null).
|
|
91
|
+
* Deliberately not isEvmChain, which answers true for unknown ids, Bitcoin's included.
|
|
92
|
+
*/
|
|
93
|
+
export declare function cashoutAddressFamily(chainId: number): CashoutAddressFamilyType | null;
|
|
94
|
+
/** Every chain a cashout can pay out on, ascending: each pay-crypto chain, Zcash included (through NEAR Intents). */
|
|
95
|
+
export declare const CASHOUT_PAYOUT_CHAIN_IDS: readonly number[];
|
|
96
|
+
/** The catalog token at tokenAddress on a payout chain, spelled as the catalog spells it; null off the catalog. */
|
|
97
|
+
export declare function resolveCashoutPayoutToken(chainId: number, tokenAddress: string): SupportedCryptoTokenConfig | null;
|
|
98
|
+
export declare function getPayCryptoTxUrl(chainId: number, txHash: string): string | null;
|
|
99
|
+
export declare function getPayCryptoAddressUrl(chainId: number, address: string): string | null;
|
|
100
|
+
/**
|
|
101
|
+
* Display form of an estimate or a delivered amount (any-coin spec "Units of amounts"): stablecoins round down to two
|
|
102
|
+
* decimals, other tokens to six significant digits; trailing zeros go and the integer part is grouped with commas.
|
|
103
|
+
* The input is already exact in the token's decimals, so the result never shows more decimals than the token has.
|
|
104
|
+
*/
|
|
105
|
+
export declare function formatPayCryptoDisplayAmount(amount: string, symbol: PayCryptoTokenSymbol): string;
|
package/dist/crypto.js
CHANGED
|
@@ -1,8 +1,10 @@
|
|
|
1
|
-
import { MAINNET_CHAINS, BASE_CHAIN_ID, ETHEREUM_CHAIN_ID, SOLANA_CHAIN_ID, TRON_CHAIN_ID, getChainName, } from './chains.js';
|
|
1
|
+
import { MAINNET_CHAINS, BASE_CHAIN_ID, ETHEREUM_CHAIN_ID, HYPEREVM_CHAIN_ID, SOLANA_CHAIN_ID, TRON_CHAIN_ID, getChainName, getExplorerUrl, } from './chains.js';
|
|
2
2
|
export const BITCOIN_CHAIN_ID = 8253038;
|
|
3
3
|
// Synthetic network ID shared with the mobile and web NEAR Intents clients.
|
|
4
4
|
export const ZCASH_CHAIN_ID = 133701;
|
|
5
5
|
export const ZCASH_ASSET = 'nep141:zec.omft.near';
|
|
6
|
+
/** NEAR Intents' asset id for USDC on Base (origin of cashout payouts, destination of Zcash checkout payments). */
|
|
7
|
+
export const NEAR_BASE_USDC_ASSET = 'nep141:base-0x833589fcd6edb6e08f4c7c32d4f71b54bda02913.omft.near';
|
|
6
8
|
export const PAY_CRYPTO_TOKEN_SYMBOLS = [
|
|
7
9
|
'BTC', // Kept in symbols for DB compatibility with existing sessions
|
|
8
10
|
'USDC',
|
|
@@ -52,7 +54,8 @@ export const STABLECOIN_SYMBOLS = new Set([
|
|
|
52
54
|
]);
|
|
53
55
|
const NATIVE_ETH_ADDRESS = '0x0000000000000000000000000000000000000000';
|
|
54
56
|
const NATIVE_SOL_ADDRESS = '11111111111111111111111111111111';
|
|
55
|
-
|
|
57
|
+
/** Relay's sentinel for native BTC. Its bech32 checksum verifies, but it decodes to a 19-byte witness-v0 program, so isValidBitcoinAddress rejects it and it never works as a refund address. */
|
|
58
|
+
export const BITCOIN_NATIVE_TOKEN_ADDRESS = 'bc1qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqmql8k8';
|
|
56
59
|
const PAY_CRYPTO_CHAIN_CONFIGS = {
|
|
57
60
|
...MAINNET_CHAINS,
|
|
58
61
|
[ZCASH_CHAIN_ID]: { chainId: ZCASH_CHAIN_ID, name: 'Zcash', shortName: 'ZEC' },
|
|
@@ -67,7 +70,7 @@ const CHAIN_TOKEN_CONFIGS = {
|
|
|
67
70
|
ZEC: { address: ZCASH_ASSET, decimals: 8, isNative: true },
|
|
68
71
|
},
|
|
69
72
|
[BITCOIN_CHAIN_ID]: {
|
|
70
|
-
BTC: { address:
|
|
73
|
+
BTC: { address: BITCOIN_NATIVE_TOKEN_ADDRESS, decimals: 8, isNative: true },
|
|
71
74
|
},
|
|
72
75
|
1: {
|
|
73
76
|
ETH: { address: NATIVE_ETH_ADDRESS, decimals: 18, isNative: true },
|
|
@@ -296,3 +299,107 @@ export function getSupportedDestinationBalanceTokenConfigsForChain(chainId, enab
|
|
|
296
299
|
export function resolveDestinationBalanceTokenConfig(chainId, symbol) {
|
|
297
300
|
return resolvePayCryptoTokenConfig(chainId, symbol);
|
|
298
301
|
}
|
|
302
|
+
/** Chains a cashout can be funded from through Relay. Zcash is out: ZEC funding is out of scope (2026-10-07). */
|
|
303
|
+
export const CASHOUT_FUNDING_CHAIN_IDS = [
|
|
304
|
+
ETHEREUM_CHAIN_ID, 10, 56, 137, 480, HYPEREVM_CHAIN_ID, 5042, BASE_CHAIN_ID, 42161, BITCOIN_CHAIN_ID,
|
|
305
|
+
];
|
|
306
|
+
/**
|
|
307
|
+
* The tokens a cashout can be funded with: every supported pay-crypto token on a Relay-fundable chain. An explicit list,
|
|
308
|
+
* because isEvmChain answers true for chains the table doesn't know, which let Bitcoin and Zcash in by accident.
|
|
309
|
+
*/
|
|
310
|
+
export function getCashoutFundingTokenConfigs() {
|
|
311
|
+
return getSupportedPayCryptoChainIds(PAY_CRYPTO_TOKEN_SYMBOLS)
|
|
312
|
+
.filter((chainId) => CASHOUT_FUNDING_CHAIN_IDS.includes(chainId))
|
|
313
|
+
.flatMap((chainId) => getSupportedPayCryptoTokenConfigsForChain(chainId, PAY_CRYPTO_TOKEN_SYMBOLS))
|
|
314
|
+
.filter((token) => resolvePayCryptoTokenConfigByAddress(token.chainId, token.address) !== null);
|
|
315
|
+
}
|
|
316
|
+
/** The address formats a cashout address can take. */
|
|
317
|
+
export const CashoutAddressFamily = {
|
|
318
|
+
EVM: 'EVM',
|
|
319
|
+
SOLANA: 'SOLANA',
|
|
320
|
+
TRON: 'TRON',
|
|
321
|
+
BITCOIN: 'BITCOIN',
|
|
322
|
+
ZCASH: 'ZCASH',
|
|
323
|
+
};
|
|
324
|
+
/**
|
|
325
|
+
* The address format a cashout address on this chain must have. Bitcoin, Solana and Tron map by id;
|
|
326
|
+
* Zcash is ZCASH (transparent addresses only, Zcash spec Z3). Every remaining chain in the pay-crypto token table
|
|
327
|
+
* is EVM; any other chain has none (null).
|
|
328
|
+
* Deliberately not isEvmChain, which answers true for unknown ids, Bitcoin's included.
|
|
329
|
+
*/
|
|
330
|
+
export function cashoutAddressFamily(chainId) {
|
|
331
|
+
if (chainId === BITCOIN_CHAIN_ID)
|
|
332
|
+
return CashoutAddressFamily.BITCOIN;
|
|
333
|
+
if (chainId === SOLANA_CHAIN_ID)
|
|
334
|
+
return CashoutAddressFamily.SOLANA;
|
|
335
|
+
if (chainId === TRON_CHAIN_ID)
|
|
336
|
+
return CashoutAddressFamily.TRON;
|
|
337
|
+
if (chainId === ZCASH_CHAIN_ID)
|
|
338
|
+
return CashoutAddressFamily.ZCASH;
|
|
339
|
+
if (CHAIN_TOKEN_CONFIGS[chainId] === undefined)
|
|
340
|
+
return null;
|
|
341
|
+
return CashoutAddressFamily.EVM;
|
|
342
|
+
}
|
|
343
|
+
/** Every chain a cashout can pay out on, ascending: each pay-crypto chain, Zcash included (through NEAR Intents). */
|
|
344
|
+
export const CASHOUT_PAYOUT_CHAIN_IDS = Object.keys(CHAIN_TOKEN_CONFIGS).map(Number);
|
|
345
|
+
/** The catalog token at tokenAddress on a payout chain, spelled as the catalog spells it; null off the catalog. */
|
|
346
|
+
export function resolveCashoutPayoutToken(chainId, tokenAddress) {
|
|
347
|
+
if (!CASHOUT_PAYOUT_CHAIN_IDS.includes(chainId))
|
|
348
|
+
return null;
|
|
349
|
+
return resolvePayCryptoTokenConfigByAddress(chainId, tokenAddress);
|
|
350
|
+
}
|
|
351
|
+
/** Chains whose explorer paths differ from the EVM `{explorer}/tx/` and `{explorer}/address/` forms. */
|
|
352
|
+
const PAY_CRYPTO_EXPLORER_PATHS = {
|
|
353
|
+
[SOLANA_CHAIN_ID]: { tx: 'https://solscan.io/tx/', address: 'https://solscan.io/account/' },
|
|
354
|
+
[TRON_CHAIN_ID]: { tx: 'https://tronscan.org/#/transaction/', address: 'https://tronscan.org/#/address/' },
|
|
355
|
+
[BITCOIN_CHAIN_ID]: { tx: 'https://mempool.space/tx/', address: 'https://mempool.space/address/' },
|
|
356
|
+
[ZCASH_CHAIN_ID]: { tx: 'https://blockchair.com/zcash/transaction/', address: 'https://blockchair.com/zcash/address/' },
|
|
357
|
+
};
|
|
358
|
+
export function getPayCryptoTxUrl(chainId, txHash) {
|
|
359
|
+
const paths = PAY_CRYPTO_EXPLORER_PATHS[chainId];
|
|
360
|
+
if (paths !== undefined)
|
|
361
|
+
return `${paths.tx}${txHash}`;
|
|
362
|
+
const explorer = getExplorerUrl(chainId);
|
|
363
|
+
return explorer === undefined ? null : `${explorer}/tx/${txHash}`;
|
|
364
|
+
}
|
|
365
|
+
export function getPayCryptoAddressUrl(chainId, address) {
|
|
366
|
+
const paths = PAY_CRYPTO_EXPLORER_PATHS[chainId];
|
|
367
|
+
if (paths !== undefined)
|
|
368
|
+
return `${paths.address}${address}`;
|
|
369
|
+
const explorer = getExplorerUrl(chainId);
|
|
370
|
+
return explorer === undefined ? null : `${explorer}/address/${address}`;
|
|
371
|
+
}
|
|
372
|
+
const DISPLAY_SIGNIFICANT_DIGITS = 6;
|
|
373
|
+
/**
|
|
374
|
+
* Display form of an estimate or a delivered amount (any-coin spec "Units of amounts"): stablecoins round down to two
|
|
375
|
+
* decimals, other tokens to six significant digits; trailing zeros go and the integer part is grouped with commas.
|
|
376
|
+
* The input is already exact in the token's decimals, so the result never shows more decimals than the token has.
|
|
377
|
+
*/
|
|
378
|
+
export function formatPayCryptoDisplayAmount(amount, symbol) {
|
|
379
|
+
const match = /^(\d+)(?:\.(\d+))?$/u.exec(amount);
|
|
380
|
+
if (match === null)
|
|
381
|
+
throw new Error(`Not a decimal amount: ${amount}`);
|
|
382
|
+
const integer = match[1].replace(/^0+(?=\d)/u, '');
|
|
383
|
+
const fraction = match[2] ?? '';
|
|
384
|
+
let keptInteger = integer;
|
|
385
|
+
let keptFraction;
|
|
386
|
+
if (isStablecoinSymbol(symbol)) {
|
|
387
|
+
keptFraction = fraction.slice(0, 2);
|
|
388
|
+
}
|
|
389
|
+
else {
|
|
390
|
+
const first = `${integer}${fraction}`.search(/[1-9]/u);
|
|
391
|
+
if (first === -1)
|
|
392
|
+
return '0';
|
|
393
|
+
const cut = first + DISPLAY_SIGNIFICANT_DIGITS;
|
|
394
|
+
if (cut <= integer.length) {
|
|
395
|
+
keptInteger = `${integer.slice(0, cut)}${'0'.repeat(integer.length - cut)}`;
|
|
396
|
+
keptFraction = '';
|
|
397
|
+
}
|
|
398
|
+
else {
|
|
399
|
+
keptFraction = fraction.slice(0, cut - integer.length);
|
|
400
|
+
}
|
|
401
|
+
}
|
|
402
|
+
const trimmed = keptFraction.replace(/0+$/u, '');
|
|
403
|
+
const grouped = keptInteger.replace(/\B(?=(\d{3})+(?!\d))/gu, ',');
|
|
404
|
+
return trimmed === '' ? grouped : `${grouped}.${trimmed}`;
|
|
405
|
+
}
|
package/dist/index.d.ts
CHANGED
package/dist/index.js
CHANGED
package/dist/types.d.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import type { PayCryptoTokenSymbol } from './crypto.js';
|
|
2
2
|
import type { ProofMode } from './buyerTee.js';
|
|
3
3
|
import type { OnboardingStepIdValue } from './onboarding.js';
|
|
4
|
+
import type { SarSupportedFiatRail } from './rails.js';
|
|
4
5
|
export declare const PaymentPlatform: {
|
|
5
6
|
readonly VENMO: "venmo";
|
|
6
7
|
readonly CASHAPP: "cashapp";
|
|
@@ -1043,8 +1044,21 @@ export declare const WebhookEventType: {
|
|
|
1043
1044
|
readonly PAYMENT_CHARGEBACKED: "PAYMENT_CHARGEBACKED";
|
|
1044
1045
|
readonly ORDER_PARTIALLY_CHARGEBACKED: "ORDER_PARTIALLY_CHARGEBACKED";
|
|
1045
1046
|
readonly ORDER_CHARGEBACKED: "ORDER_CHARGEBACKED";
|
|
1047
|
+
readonly CASHOUT_ORDER_CREATED: "CASHOUT_ORDER_CREATED";
|
|
1048
|
+
readonly CASHOUT_ORDER_CANCELLED: "CASHOUT_ORDER_CANCELLED";
|
|
1049
|
+
readonly CASHOUT_ORDER_PARTIALLY_FUNDED: "CASHOUT_ORDER_PARTIALLY_FUNDED";
|
|
1050
|
+
readonly CASHOUT_ORDER_FUNDED: "CASHOUT_ORDER_FUNDED";
|
|
1051
|
+
readonly CASHOUT_ORDER_MATCHED: "CASHOUT_ORDER_MATCHED";
|
|
1052
|
+
readonly CASHOUT_ORDER_PARTIALLY_PAID: "CASHOUT_ORDER_PARTIALLY_PAID";
|
|
1053
|
+
readonly CASHOUT_ORDER_SETTLED: "CASHOUT_ORDER_SETTLED";
|
|
1054
|
+
readonly CASHOUT_ORDER_EXPIRED: "CASHOUT_ORDER_EXPIRED";
|
|
1046
1055
|
};
|
|
1047
1056
|
export type WebhookEventTypeValue = typeof WebhookEventType[keyof typeof WebhookEventType];
|
|
1057
|
+
/** Cashout events carry a CashoutView, not the order envelope. */
|
|
1058
|
+
export declare const CASHOUT_WEBHOOK_EVENT_TYPES: readonly ["CASHOUT_ORDER_CREATED", "CASHOUT_ORDER_CANCELLED", "CASHOUT_ORDER_PARTIALLY_FUNDED", "CASHOUT_ORDER_FUNDED", "CASHOUT_ORDER_MATCHED", "CASHOUT_ORDER_PARTIALLY_PAID", "CASHOUT_ORDER_SETTLED", "CASHOUT_ORDER_EXPIRED"];
|
|
1059
|
+
export type CashoutWebhookEventTypeValue = typeof CASHOUT_WEBHOOK_EVENT_TYPES[number];
|
|
1060
|
+
export type OrderWebhookEventTypeValue = Exclude<WebhookEventTypeValue, CashoutWebhookEventTypeValue>;
|
|
1061
|
+
export declare function isCashoutWebhookEventType(type: string): type is CashoutWebhookEventTypeValue;
|
|
1048
1062
|
export declare const WebhookDeliveryStatus: {
|
|
1049
1063
|
readonly PENDING: "PENDING";
|
|
1050
1064
|
readonly DELIVERED: "DELIVERED";
|
|
@@ -1077,9 +1091,9 @@ export type WebhookDelivery = {
|
|
|
1077
1091
|
responseCode?: number | null;
|
|
1078
1092
|
createdAt: string;
|
|
1079
1093
|
};
|
|
1080
|
-
export type
|
|
1094
|
+
export type OrderWebhookPayload = {
|
|
1081
1095
|
id: string;
|
|
1082
|
-
type:
|
|
1096
|
+
type: OrderWebhookEventTypeValue;
|
|
1083
1097
|
timestamp: string;
|
|
1084
1098
|
data: {
|
|
1085
1099
|
order: CheckoutOrder | null;
|
|
@@ -1101,6 +1115,45 @@ export type WebhookPayload = {
|
|
|
1101
1115
|
amountChange?: OrderAmountChange;
|
|
1102
1116
|
};
|
|
1103
1117
|
};
|
|
1118
|
+
/** Bumped only on a breaking change to a cashout payload. */
|
|
1119
|
+
export declare const CASHOUT_WEBHOOK_VERSION = 1;
|
|
1120
|
+
/** One buyer payment that left part of the cashout unpaid; decimal USDC. */
|
|
1121
|
+
export interface CashoutPartialPayment {
|
|
1122
|
+
/** The cashout's depositAmount: what buyers can pay in total. */
|
|
1123
|
+
expectedAmount: string;
|
|
1124
|
+
/** What buyers have paid so far, this fill included. */
|
|
1125
|
+
paidAmount: string;
|
|
1126
|
+
/** expectedAmount − paidAmount. */
|
|
1127
|
+
remainingAmount: string;
|
|
1128
|
+
fill: {
|
|
1129
|
+
amount: string;
|
|
1130
|
+
txHash: string;
|
|
1131
|
+
};
|
|
1132
|
+
}
|
|
1133
|
+
export type CashoutWebhookEventData = {
|
|
1134
|
+
readonly type: Exclude<CashoutWebhookEventTypeValue, typeof WebhookEventType.CASHOUT_ORDER_PARTIALLY_PAID>;
|
|
1135
|
+
readonly data: CashoutView;
|
|
1136
|
+
} | {
|
|
1137
|
+
readonly type: typeof WebhookEventType.CASHOUT_ORDER_PARTIALLY_PAID;
|
|
1138
|
+
readonly data: CashoutView;
|
|
1139
|
+
readonly partialPayment: CashoutPartialPayment;
|
|
1140
|
+
};
|
|
1141
|
+
export type CashoutWebhookPayload = {
|
|
1142
|
+
id: string;
|
|
1143
|
+
type: Exclude<CashoutWebhookEventTypeValue, typeof WebhookEventType.CASHOUT_ORDER_PARTIALLY_PAID>;
|
|
1144
|
+
timestamp: string;
|
|
1145
|
+
version: typeof CASHOUT_WEBHOOK_VERSION;
|
|
1146
|
+
data: CashoutView;
|
|
1147
|
+
} | {
|
|
1148
|
+
id: string;
|
|
1149
|
+
type: typeof WebhookEventType.CASHOUT_ORDER_PARTIALLY_PAID;
|
|
1150
|
+
timestamp: string;
|
|
1151
|
+
version: typeof CASHOUT_WEBHOOK_VERSION;
|
|
1152
|
+
data: CashoutView;
|
|
1153
|
+
partialPayment: CashoutPartialPayment;
|
|
1154
|
+
};
|
|
1155
|
+
export type WebhookPayload = OrderWebhookPayload | CashoutWebhookPayload;
|
|
1156
|
+
export declare function isCashoutWebhook(payload: WebhookPayload): payload is CashoutWebhookPayload;
|
|
1104
1157
|
export type CreateWebhookRequest = {
|
|
1105
1158
|
url: string;
|
|
1106
1159
|
events?: WebhookEventTypeValue[];
|
|
@@ -1201,4 +1254,614 @@ export type OwnershipTransferMasterMerchantPermissionType = typeof OwnershipTran
|
|
|
1201
1254
|
export declare const OWNERSHIP_TRANSFER_MASTER_MERCHANT_PERMISSIONS: readonly OwnershipTransferMasterMerchantPermissionType[];
|
|
1202
1255
|
/** "alice@example.com" → "a•••@example.com". The input is a validated, lowercased address. */
|
|
1203
1256
|
export declare function maskOwnershipTransferEmail(email: string): string;
|
|
1257
|
+
export declare const CashoutStatus: {
|
|
1258
|
+
readonly AWAITING_FUNDING: "AWAITING_FUNDING";
|
|
1259
|
+
readonly FUNDED: "FUNDED";
|
|
1260
|
+
readonly READY: "READY";
|
|
1261
|
+
readonly LISTING: "LISTING";
|
|
1262
|
+
readonly PAYING: "PAYING";
|
|
1263
|
+
readonly SETTLED: "SETTLED";
|
|
1264
|
+
readonly CANCELLING: "CANCELLING";
|
|
1265
|
+
readonly CANCELLED: "CANCELLED";
|
|
1266
|
+
readonly EXPIRED: "EXPIRED";
|
|
1267
|
+
};
|
|
1268
|
+
export type CashoutStatusType = typeof CashoutStatus[keyof typeof CashoutStatus];
|
|
1269
|
+
export declare const CashoutFundingStatus: {
|
|
1270
|
+
readonly AWAITING_FUNDING: "AWAITING_FUNDING";
|
|
1271
|
+
readonly PARTIALLY_FUNDED: "PARTIALLY_FUNDED";
|
|
1272
|
+
readonly FUNDED: "FUNDED";
|
|
1273
|
+
readonly FUNDING_EXPIRED: "FUNDING_EXPIRED";
|
|
1274
|
+
};
|
|
1275
|
+
export type CashoutFundingStatusType = typeof CashoutFundingStatus[keyof typeof CashoutFundingStatus];
|
|
1276
|
+
export declare const CashoutCancelSource: {
|
|
1277
|
+
readonly CHECKOUT: "CHECKOUT";
|
|
1278
|
+
readonly MERCHANT: "MERCHANT";
|
|
1279
|
+
readonly PEER_APP: "PEER_APP";
|
|
1280
|
+
};
|
|
1281
|
+
export type CashoutCancelSourceType = typeof CashoutCancelSource[keyof typeof CashoutCancelSource];
|
|
1282
|
+
export declare const CashoutPayoutKind: {
|
|
1283
|
+
readonly ESCROW: "ESCROW";
|
|
1284
|
+
readonly CRYPTO: "CRYPTO";
|
|
1285
|
+
};
|
|
1286
|
+
export type CashoutPayoutKindType = typeof CashoutPayoutKind[keyof typeof CashoutPayoutKind];
|
|
1287
|
+
export declare const CashoutAttemptStatus: {
|
|
1288
|
+
readonly ACTIVE: "ACTIVE";
|
|
1289
|
+
readonly CLOSED: "CLOSED";
|
|
1290
|
+
readonly SETTLED: "SETTLED";
|
|
1291
|
+
readonly FAILED: "FAILED";
|
|
1292
|
+
};
|
|
1293
|
+
export type CashoutAttemptStatusType = typeof CashoutAttemptStatus[keyof typeof CashoutAttemptStatus];
|
|
1294
|
+
/** Fiat payout methods, in the order players see them: SAR rails, then buyer-proof rails. */
|
|
1295
|
+
export declare const CashoutFiatRail: {
|
|
1296
|
+
readonly VENMO: "venmo";
|
|
1297
|
+
readonly CASHAPP: "cashapp";
|
|
1298
|
+
readonly PAYPAL: "paypal";
|
|
1299
|
+
readonly ZELLE: "zelle";
|
|
1300
|
+
readonly REVOLUT: "revolut";
|
|
1301
|
+
readonly CHIME: "chime";
|
|
1302
|
+
};
|
|
1303
|
+
export type CashoutFiatRailType = typeof CashoutFiatRail[keyof typeof CashoutFiatRail];
|
|
1304
|
+
/** One rail per crypto payout network, with checkout's rail ids (any-coin spec "Cashout rails"); the player sees them as one "Crypto" option. */
|
|
1305
|
+
export declare const CashoutCryptoRail: {
|
|
1306
|
+
readonly RELAY_1: "relay_1";
|
|
1307
|
+
readonly RELAY_10: "relay_10";
|
|
1308
|
+
readonly RELAY_56: "relay_56";
|
|
1309
|
+
readonly RELAY_137: "relay_137";
|
|
1310
|
+
readonly RELAY_480: "relay_480";
|
|
1311
|
+
readonly RELAY_999: "relay_999";
|
|
1312
|
+
readonly RELAY_5042: "relay_5042";
|
|
1313
|
+
readonly RELAY_8453: "relay_8453";
|
|
1314
|
+
readonly RELAY_42161: "relay_42161";
|
|
1315
|
+
readonly RELAY_8253038: "relay_8253038";
|
|
1316
|
+
readonly RELAY_728126428: "relay_728126428";
|
|
1317
|
+
readonly RELAY_792703809: "relay_792703809";
|
|
1318
|
+
/** ZEC on Zcash through NEAR Intents (Zcash spec "Catalog, route and address"); checkout's ZCASH_RAIL. */
|
|
1319
|
+
readonly NEAR_INTENTS_133701: "near_intents_133701";
|
|
1320
|
+
};
|
|
1321
|
+
export type CashoutCryptoRailType = typeof CashoutCryptoRail[keyof typeof CashoutCryptoRail];
|
|
1322
|
+
/** Every cashout rail, in rail order: fiat, then the crypto networks. */
|
|
1323
|
+
export declare const CashoutRail: {
|
|
1324
|
+
readonly RELAY_1: "relay_1";
|
|
1325
|
+
readonly RELAY_10: "relay_10";
|
|
1326
|
+
readonly RELAY_56: "relay_56";
|
|
1327
|
+
readonly RELAY_137: "relay_137";
|
|
1328
|
+
readonly RELAY_480: "relay_480";
|
|
1329
|
+
readonly RELAY_999: "relay_999";
|
|
1330
|
+
readonly RELAY_5042: "relay_5042";
|
|
1331
|
+
readonly RELAY_8453: "relay_8453";
|
|
1332
|
+
readonly RELAY_42161: "relay_42161";
|
|
1333
|
+
readonly RELAY_8253038: "relay_8253038";
|
|
1334
|
+
readonly RELAY_728126428: "relay_728126428";
|
|
1335
|
+
readonly RELAY_792703809: "relay_792703809";
|
|
1336
|
+
/** ZEC on Zcash through NEAR Intents (Zcash spec "Catalog, route and address"); checkout's ZCASH_RAIL. */
|
|
1337
|
+
readonly NEAR_INTENTS_133701: "near_intents_133701";
|
|
1338
|
+
readonly VENMO: "venmo";
|
|
1339
|
+
readonly CASHAPP: "cashapp";
|
|
1340
|
+
readonly PAYPAL: "paypal";
|
|
1341
|
+
readonly ZELLE: "zelle";
|
|
1342
|
+
readonly REVOLUT: "revolut";
|
|
1343
|
+
readonly CHIME: "chime";
|
|
1344
|
+
};
|
|
1345
|
+
export type CashoutRailType = CashoutFiatRailType | CashoutCryptoRailType;
|
|
1346
|
+
/** Fiat rails whose account the player connects so Peer can confirm buyer payments; derived from SAR_SUPPORTED_FIAT_RAILS. */
|
|
1347
|
+
export type CashoutSarRailType = Extract<CashoutFiatRailType, SarSupportedFiatRail>;
|
|
1348
|
+
/** Fiat rails with no connect step: the buyer proves the payment with the PeerAuth extension or the Peer app. */
|
|
1349
|
+
export type CashoutBuyerProofRailType = Exclude<CashoutFiatRailType, CashoutSarRailType>;
|
|
1350
|
+
export declare const CashoutPayoutProvider: {
|
|
1351
|
+
readonly RELAY: "RELAY";
|
|
1352
|
+
readonly NEAR_INTENTS: "NEAR_INTENTS";
|
|
1353
|
+
};
|
|
1354
|
+
export type CashoutPayoutProviderType = typeof CashoutPayoutProvider[keyof typeof CashoutPayoutProvider];
|
|
1355
|
+
export declare const CashoutPayoutBridgeStatus: {
|
|
1356
|
+
readonly QUOTED: "QUOTED";
|
|
1357
|
+
readonly NOT_SENT: "NOT_SENT";
|
|
1358
|
+
readonly BRIDGING: "BRIDGING";
|
|
1359
|
+
readonly DELIVERED: "DELIVERED";
|
|
1360
|
+
readonly REFUNDED: "REFUNDED";
|
|
1361
|
+
};
|
|
1362
|
+
export type CashoutPayoutBridgeStatusType = typeof CashoutPayoutBridgeStatus[keyof typeof CashoutPayoutBridgeStatus];
|
|
1363
|
+
/** A crypto payout's coin, network and the player's address there. */
|
|
1364
|
+
export interface CashoutCryptoDestination {
|
|
1365
|
+
chainId: number;
|
|
1366
|
+
/** The shared catalog's address for the token on chainId. */
|
|
1367
|
+
tokenAddress: string;
|
|
1368
|
+
symbol: PayCryptoTokenSymbol;
|
|
1369
|
+
decimals: number;
|
|
1370
|
+
/** Canonical: EVM checksummed, bech32 lower-case, base58 as entered. */
|
|
1371
|
+
address: string;
|
|
1372
|
+
}
|
|
1373
|
+
/** Body of the crypto payout-method, payout-quote and send-to-address requests. The rail names the network. */
|
|
1374
|
+
export interface CashoutPayoutDestinationRequest {
|
|
1375
|
+
rail: CashoutCryptoRailType;
|
|
1376
|
+
tokenAddress: string;
|
|
1377
|
+
address: string;
|
|
1378
|
+
}
|
|
1379
|
+
/** A crypto payout method: the network's rail and where on it the player takes the payout. */
|
|
1380
|
+
export interface CashoutCryptoMethod {
|
|
1381
|
+
rail: CashoutCryptoRailType;
|
|
1382
|
+
destination: CashoutCryptoDestination;
|
|
1383
|
+
}
|
|
1384
|
+
/** POST /api/v1/cashout-checkout/:id/payout-quote. Not a promise. */
|
|
1385
|
+
export interface CashoutPayoutQuote {
|
|
1386
|
+
destination: CashoutCryptoDestination;
|
|
1387
|
+
/** Decimal USDC that would leave the player's wallet. */
|
|
1388
|
+
usdcAmount: string;
|
|
1389
|
+
/** Decimal destination token; equals usdcAmount for USDC on Base. */
|
|
1390
|
+
estimatedAmount: string;
|
|
1391
|
+
quotedAt: string;
|
|
1392
|
+
}
|
|
1393
|
+
/** The player's bridged payout, newest attempt first; never NOT_SENT. */
|
|
1394
|
+
export interface CashoutPayoutBridgeView {
|
|
1395
|
+
provider: CashoutPayoutProviderType;
|
|
1396
|
+
status: Exclude<CashoutPayoutBridgeStatusType, typeof CashoutPayoutBridgeStatus.NOT_SENT>;
|
|
1397
|
+
destination: CashoutCryptoDestination;
|
|
1398
|
+
usdcAmount: string;
|
|
1399
|
+
/** The binding quote's output, decimal destination token. */
|
|
1400
|
+
estimatedAmount: string;
|
|
1401
|
+
deliveredAmount: string | null;
|
|
1402
|
+
destinationTxHash: string | null;
|
|
1403
|
+
/** Decimal USDC. */
|
|
1404
|
+
refundedAmount: string | null;
|
|
1405
|
+
refundTxHash: string | null;
|
|
1406
|
+
}
|
|
1407
|
+
export interface CashoutPartialFillView {
|
|
1408
|
+
/** Decimal USDC this buyer paid. */
|
|
1409
|
+
amount: string;
|
|
1410
|
+
txHash: string;
|
|
1411
|
+
paidAt: string;
|
|
1412
|
+
}
|
|
1413
|
+
/** Where a SETTLED cashout's USDC ended up; decimal USDC, "0.00" for a part that did not happen. */
|
|
1414
|
+
export interface CashoutSettlementBreakdown {
|
|
1415
|
+
/** Paid by buyers through the escrow, across every listing. */
|
|
1416
|
+
buyerPaidAmount: string;
|
|
1417
|
+
/** USDC that left the player's wallet for a crypto payout (direct or bridged) or a send-to-address remainder. */
|
|
1418
|
+
sentAmount: string;
|
|
1419
|
+
/** The player's recipient: EVM lower-case, Solana, Tron and Bitcoin canonical; never a deposit address. */
|
|
1420
|
+
sentTo: string | null;
|
|
1421
|
+
/** Left in, or returned to, the player's Peer wallet. */
|
|
1422
|
+
returnedAmount: string;
|
|
1423
|
+
/** Swept by the escrow as dust when it closed the deposit. */
|
|
1424
|
+
dustAmount: string;
|
|
1425
|
+
/** Σ refundLossUnits: USDC Relay kept on refunds; "0.00" when none. */
|
|
1426
|
+
refundFeeAmount: string;
|
|
1427
|
+
}
|
|
1428
|
+
/** Merchant-facing cashout. Never includes the Peer fee, the player's email, wallet or payee handle. */
|
|
1429
|
+
export interface CashoutView {
|
|
1430
|
+
cashoutId: string;
|
|
1431
|
+
merchantReference: string | null;
|
|
1432
|
+
status: CashoutStatusType;
|
|
1433
|
+
fundingStatus: CashoutFundingStatusType;
|
|
1434
|
+
payout: {
|
|
1435
|
+
amount: string;
|
|
1436
|
+
chainId: number;
|
|
1437
|
+
tokenAddress: string;
|
|
1438
|
+
decimals: number;
|
|
1439
|
+
};
|
|
1440
|
+
merchantFee: {
|
|
1441
|
+
bps: number;
|
|
1442
|
+
amount: string;
|
|
1443
|
+
};
|
|
1444
|
+
funding: {
|
|
1445
|
+
chainId: number;
|
|
1446
|
+
tokenAddress: string;
|
|
1447
|
+
decimals: number;
|
|
1448
|
+
/** Quoted amount to send, decimal funding token. */
|
|
1449
|
+
amount: string;
|
|
1450
|
+
/** Sent before the deadline, decimal funding token. */
|
|
1451
|
+
sentAmount: string;
|
|
1452
|
+
/** amount − sentAmount, never below zero; decimal funding token. */
|
|
1453
|
+
missingAmount: string;
|
|
1454
|
+
/** Payout plus buffer: the USDC the quote delivers, decimal USDC. */
|
|
1455
|
+
expectedAmount: string;
|
|
1456
|
+
/** Reached the player's wallet on Base, decimal USDC. */
|
|
1457
|
+
receivedAmount: string;
|
|
1458
|
+
/** Null once the cashout can no longer be funded. */
|
|
1459
|
+
depositAddress: string | null;
|
|
1460
|
+
/** Funding deadline; each on-time arrival moves it to at least the funding TTL (24 hours by default) after that check. */
|
|
1461
|
+
quoteExpiresAt: string;
|
|
1462
|
+
};
|
|
1463
|
+
depositAmount: string | null;
|
|
1464
|
+
/** What buyers have paid across every listing, partial fills included. */
|
|
1465
|
+
paidAmount: string;
|
|
1466
|
+
partialFills: CashoutPartialFillView[];
|
|
1467
|
+
/** Only when status is SETTLED. */
|
|
1468
|
+
settlement: CashoutSettlementBreakdown | null;
|
|
1469
|
+
attempt: {
|
|
1470
|
+
kind: CashoutPayoutKindType;
|
|
1471
|
+
rail: string | null;
|
|
1472
|
+
status: CashoutAttemptStatusType;
|
|
1473
|
+
} | null;
|
|
1474
|
+
/** Only when settled with a sent amount, including a send-to-address remainder. */
|
|
1475
|
+
payoutTransfer: {
|
|
1476
|
+
/** Where the player received it. */
|
|
1477
|
+
chainId: number;
|
|
1478
|
+
tokenAddress: string;
|
|
1479
|
+
decimals: number;
|
|
1480
|
+
address: string;
|
|
1481
|
+
/** Delivered, decimal destination token. */
|
|
1482
|
+
amount: string;
|
|
1483
|
+
/** The delivering transaction on chainId. */
|
|
1484
|
+
txHash: string;
|
|
1485
|
+
/** The USDC transfer on Base; settlement.sentAmount is its amount. */
|
|
1486
|
+
usdcTxHash: string;
|
|
1487
|
+
/** The bridge provider (RELAY or NEAR_INTENTS) when bridged; null for USDC on Base, where txHash = usdcTxHash. */
|
|
1488
|
+
provider: CashoutPayoutProviderType | null;
|
|
1489
|
+
} | null;
|
|
1490
|
+
cancelSource: CashoutCancelSourceType | null;
|
|
1491
|
+
returnUrl: string | null;
|
|
1492
|
+
expiresAt: string;
|
|
1493
|
+
fundedAt: string | null;
|
|
1494
|
+
settledAt: string | null;
|
|
1495
|
+
cancelledAt: string | null;
|
|
1496
|
+
createdAt: string;
|
|
1497
|
+
}
|
|
1498
|
+
export interface CreateCashoutRequest {
|
|
1499
|
+
merchantReference?: string;
|
|
1500
|
+
customerEmail: string;
|
|
1501
|
+
payout: {
|
|
1502
|
+
amount: string;
|
|
1503
|
+
chainId: number;
|
|
1504
|
+
tokenAddress: string;
|
|
1505
|
+
};
|
|
1506
|
+
funding: {
|
|
1507
|
+
chainId: number;
|
|
1508
|
+
tokenAddress: string;
|
|
1509
|
+
refundAddress?: string;
|
|
1510
|
+
};
|
|
1511
|
+
returnUrl?: string;
|
|
1512
|
+
/** Limits the cashout to these rails; never widens the merchant's (any-coin spec "Cashout rails"). */
|
|
1513
|
+
rails?: CashoutRailType[];
|
|
1514
|
+
}
|
|
1515
|
+
/** A replay with the same key and body returns the current checkout link, marked `idempotentReplay: true`. */
|
|
1516
|
+
export type CreateCashoutResponse = CashoutView & {
|
|
1517
|
+
checkoutUrl: string;
|
|
1518
|
+
idempotentReplay: boolean;
|
|
1519
|
+
};
|
|
1520
|
+
export interface ListCashoutsResponse {
|
|
1521
|
+
items: CashoutView[];
|
|
1522
|
+
page: number;
|
|
1523
|
+
limit: number;
|
|
1524
|
+
total: number;
|
|
1525
|
+
}
|
|
1526
|
+
/** A moment on a cashout's dashboard timeline. */
|
|
1527
|
+
export declare const CashoutTimelineEventType: {
|
|
1528
|
+
readonly CREATED: "CREATED";
|
|
1529
|
+
readonly PARTIALLY_FUNDED: "PARTIALLY_FUNDED";
|
|
1530
|
+
readonly FUNDED: "FUNDED";
|
|
1531
|
+
readonly FUNDING_EXPIRED: "FUNDING_EXPIRED";
|
|
1532
|
+
readonly SIGNED_IN: "SIGNED_IN";
|
|
1533
|
+
readonly METHOD_READY: "METHOD_READY";
|
|
1534
|
+
readonly LISTED: "LISTED";
|
|
1535
|
+
readonly TRANSFER_SENT: "TRANSFER_SENT";
|
|
1536
|
+
readonly MATCHED: "MATCHED";
|
|
1537
|
+
/** A buyer paid part of the listing; the rest is listed again or left for the player. */
|
|
1538
|
+
readonly PARTIALLY_PAID: "PARTIALLY_PAID";
|
|
1539
|
+
/** Pay set the deposit's intent range to what is left, so another buyer can take it. */
|
|
1540
|
+
readonly RELISTED: "RELISTED";
|
|
1541
|
+
readonly BUYER_DROPPED: "BUYER_DROPPED";
|
|
1542
|
+
readonly RECONNECT_NEEDED: "RECONNECT_NEEDED";
|
|
1543
|
+
readonly CANCEL_STARTED: "CANCEL_STARTED";
|
|
1544
|
+
/** The listing came back to the player's wallet so they can pick another payout method. */
|
|
1545
|
+
readonly LISTING_WITHDRAWN: "LISTING_WITHDRAWN";
|
|
1546
|
+
readonly SETTLED: "SETTLED";
|
|
1547
|
+
readonly CANCELLED: "CANCELLED";
|
|
1548
|
+
readonly FUNDING_ISSUE: "FUNDING_ISSUE";
|
|
1549
|
+
readonly PAYOUT_REFUNDED: "PAYOUT_REFUNDED";
|
|
1550
|
+
};
|
|
1551
|
+
export type CashoutTimelineEventTypeValue = typeof CashoutTimelineEventType[keyof typeof CashoutTimelineEventType];
|
|
1552
|
+
/** Largest merchant cashout payout step, in whole USDC. The smallest is the API's CASHOUT_MIN_USDC (10 in production). */
|
|
1553
|
+
export declare const CASHOUT_PAYOUT_STEP_MAX_USDC = 1000;
|
|
1554
|
+
/** Whole-USDC bounds for a merchant's cashout payout step in this environment. */
|
|
1555
|
+
export interface CashoutPayoutStepRange {
|
|
1556
|
+
min: number;
|
|
1557
|
+
max: number;
|
|
1558
|
+
}
|
|
1559
|
+
/** A merchant's cashout settings; the Peer fee is not the merchant's to see. */
|
|
1560
|
+
export interface CashoutSettings {
|
|
1561
|
+
rails: CashoutRailType[];
|
|
1562
|
+
/** Merchant fee in bps of the deposit, 0–1000. */
|
|
1563
|
+
feeBps: number;
|
|
1564
|
+
/** Whole USDC, within the environment's payout step range. */
|
|
1565
|
+
payoutStepUsdc: number;
|
|
1566
|
+
/** An https URL or a mailto: link; optional. Without it the player's checkout shows no contact line. */
|
|
1567
|
+
supportUrl: string | null;
|
|
1568
|
+
}
|
|
1569
|
+
export declare const CashoutFundingIssueKind: {
|
|
1570
|
+
readonly LATE_FUNDS: "LATE_FUNDS";
|
|
1571
|
+
readonly OVERPAYMENT: "OVERPAYMENT";
|
|
1572
|
+
readonly ROUTE_REFUND: "ROUTE_REFUND";
|
|
1573
|
+
};
|
|
1574
|
+
export type CashoutFundingIssueKindType = typeof CashoutFundingIssueKind[keyof typeof CashoutFundingIssueKind];
|
|
1575
|
+
export declare const CashoutFundingIssueResolution: {
|
|
1576
|
+
readonly RETURNED: "RETURNED";
|
|
1577
|
+
readonly CLAIMED: "CLAIMED";
|
|
1578
|
+
};
|
|
1579
|
+
export type CashoutFundingIssueResolutionType = typeof CashoutFundingIssueResolution[keyof typeof CashoutFundingIssueResolution];
|
|
1580
|
+
/** A funding token as offered to a merchant: `key` is "chainId:lowercaseAddress". */
|
|
1581
|
+
export interface CashoutFundingTokenOption {
|
|
1582
|
+
key: string;
|
|
1583
|
+
chainId: number;
|
|
1584
|
+
address: string;
|
|
1585
|
+
symbol: string;
|
|
1586
|
+
}
|
|
1587
|
+
/** GET /merchants/me/cashout-settings: the saved settings plus what Peer currently allows. */
|
|
1588
|
+
export interface CashoutSettingsView extends CashoutSettings {
|
|
1589
|
+
availableRails: CashoutRailType[];
|
|
1590
|
+
availableFundingTokens: CashoutFundingTokenOption[];
|
|
1591
|
+
payoutStepRange: CashoutPayoutStepRange;
|
|
1592
|
+
}
|
|
1593
|
+
/** Merchant-facing; never includes the admin's note or name. */
|
|
1594
|
+
export interface MerchantCashoutFundingIssue {
|
|
1595
|
+
kind: CashoutFundingIssueKindType;
|
|
1596
|
+
/** Decimal USDC; null for a route refund, which is paid back in the origin token. */
|
|
1597
|
+
amountUsdc: string | null;
|
|
1598
|
+
txHash: string | null;
|
|
1599
|
+
detectedAt: string;
|
|
1600
|
+
resolution: CashoutFundingIssueResolutionType | null;
|
|
1601
|
+
resolutionTxHash: string | null;
|
|
1602
|
+
resolvedAt: string | null;
|
|
1603
|
+
}
|
|
1604
|
+
export type CashoutPayoutMethodView = {
|
|
1605
|
+
rail: CashoutFiatRailType;
|
|
1606
|
+
handle: string;
|
|
1607
|
+
} | CashoutCryptoMethod;
|
|
1608
|
+
/** The dashboard's cashout: the API view plus what only the merchant's staff may see. */
|
|
1609
|
+
export interface MerchantCashoutView extends CashoutView {
|
|
1610
|
+
/** The player's email as given at create, stored lower-cased. */
|
|
1611
|
+
customerEmail: string;
|
|
1612
|
+
payoutMethod: CashoutPayoutMethodView | null;
|
|
1613
|
+
/** Null once the cashout is final. */
|
|
1614
|
+
checkoutUrl: string | null;
|
|
1615
|
+
}
|
|
1616
|
+
export interface CashoutTimelineEntry {
|
|
1617
|
+
type: CashoutTimelineEventTypeValue;
|
|
1618
|
+
text: string;
|
|
1619
|
+
txHash: string | null;
|
|
1620
|
+
/** The chain txHash is on; null when txHash isn't linked. */
|
|
1621
|
+
txChainId: number | null;
|
|
1622
|
+
occurredAt: string;
|
|
1623
|
+
}
|
|
1624
|
+
export interface CashoutWebhookDeliveryView {
|
|
1625
|
+
eventType: string;
|
|
1626
|
+
status: string;
|
|
1627
|
+
attempts: number;
|
|
1628
|
+
responseCode: number | null;
|
|
1629
|
+
lastAttemptAt: string | null;
|
|
1630
|
+
createdAt: string;
|
|
1631
|
+
}
|
|
1632
|
+
export interface MerchantCashoutDetail {
|
|
1633
|
+
cashout: MerchantCashoutView;
|
|
1634
|
+
timeline: CashoutTimelineEntry[];
|
|
1635
|
+
/** Not stored: what happens next from the current status, or null when final. */
|
|
1636
|
+
nextStep: string | null;
|
|
1637
|
+
webhooks: CashoutWebhookDeliveryView[];
|
|
1638
|
+
fundingIssues: MerchantCashoutFundingIssue[];
|
|
1639
|
+
}
|
|
1640
|
+
/** The dashboard's create form result; a replay returns the same cashout and its current link. */
|
|
1641
|
+
export type CreateMerchantCashoutResponse = MerchantCashoutView & {
|
|
1642
|
+
idempotentReplay: boolean;
|
|
1643
|
+
};
|
|
1644
|
+
export interface ListMerchantCashoutsResponse {
|
|
1645
|
+
items: MerchantCashoutView[];
|
|
1646
|
+
page: number;
|
|
1647
|
+
limit: number;
|
|
1648
|
+
total: number;
|
|
1649
|
+
}
|
|
1650
|
+
export interface AdminCashoutSettings {
|
|
1651
|
+
disabledRails: CashoutRailType[];
|
|
1652
|
+
disabledFundingTokens: string[];
|
|
1653
|
+
peerFeeRecipient: string;
|
|
1654
|
+
supportedFundingTokens: CashoutFundingTokenOption[];
|
|
1655
|
+
updatedAt: string;
|
|
1656
|
+
}
|
|
1657
|
+
export interface AdminCashoutMerchantConfig {
|
|
1658
|
+
merchantId: string;
|
|
1659
|
+
peerFeeBps: number;
|
|
1660
|
+
payoutStepUsdc: number;
|
|
1661
|
+
payoutStepRange: CashoutPayoutStepRange;
|
|
1662
|
+
fundingTokens: string[];
|
|
1663
|
+
/** Merchant cashout rails, edited by the merchant and Peer admins, in rail order. */
|
|
1664
|
+
rails: CashoutRailType[];
|
|
1665
|
+
/** Player support link; optional. */
|
|
1666
|
+
supportUrl: string | null;
|
|
1667
|
+
/** Merchant rails minus Peer's global disables and the fiat rails `DISABLED_RAILS` turns off, in rail order. */
|
|
1668
|
+
effectiveRails: CashoutRailType[];
|
|
1669
|
+
merchantFeeBps: number;
|
|
1670
|
+
merchantFeeRecipient: string | null;
|
|
1671
|
+
}
|
|
1672
|
+
export interface AdminCashoutFundingIssue extends MerchantCashoutFundingIssue {
|
|
1673
|
+
id: string;
|
|
1674
|
+
cashoutId: string;
|
|
1675
|
+
merchantId: string;
|
|
1676
|
+
merchantName: string;
|
|
1677
|
+
relayRequestId: string | null;
|
|
1678
|
+
resolutionNote: string | null;
|
|
1679
|
+
resolvedBy: string | null;
|
|
1680
|
+
}
|
|
1681
|
+
export interface AdminCashoutSupport {
|
|
1682
|
+
fundingIssues: AdminCashoutFundingIssue[];
|
|
1683
|
+
}
|
|
1684
|
+
export interface AdminCashoutChange {
|
|
1685
|
+
id: string;
|
|
1686
|
+
merchantId: string | null;
|
|
1687
|
+
cashoutFundingIssueId: string | null;
|
|
1688
|
+
actor: string;
|
|
1689
|
+
changes: Record<string, {
|
|
1690
|
+
before: unknown;
|
|
1691
|
+
after: unknown;
|
|
1692
|
+
}>;
|
|
1693
|
+
createdAt: string;
|
|
1694
|
+
}
|
|
1695
|
+
/** What the player can do next; drives every checkout button and every 409. */
|
|
1696
|
+
export declare const CashoutPlayerAction: {
|
|
1697
|
+
readonly SET_METHOD: "SET_METHOD";
|
|
1698
|
+
readonly CONNECT_RAIL: "CONNECT_RAIL";
|
|
1699
|
+
readonly SKIP_CONNECT: "SKIP_CONNECT";
|
|
1700
|
+
readonly CONFIRM: "CONFIRM";
|
|
1701
|
+
readonly CANCEL: "CANCEL";
|
|
1702
|
+
readonly FINISH_CANCEL: "FINISH_CANCEL";
|
|
1703
|
+
readonly CHANGE_METHOD: "CHANGE_METHOD";
|
|
1704
|
+
readonly SEND_TO_ADDRESS: "SEND_TO_ADDRESS";
|
|
1705
|
+
readonly RELIST: "RELIST";
|
|
1706
|
+
};
|
|
1707
|
+
export type CashoutPlayerActionType = typeof CashoutPlayerAction[keyof typeof CashoutPlayerAction];
|
|
1708
|
+
/** What Pay is sending from the player's wallet. */
|
|
1709
|
+
export declare const CashoutSending: {
|
|
1710
|
+
readonly LISTING: "LISTING";
|
|
1711
|
+
readonly TRANSFER: "TRANSFER";
|
|
1712
|
+
readonly WITHDRAW: "WITHDRAW";
|
|
1713
|
+
readonly RELISTING: "RELISTING";
|
|
1714
|
+
};
|
|
1715
|
+
export type CashoutSendingType = typeof CashoutSending[keyof typeof CashoutSending];
|
|
1716
|
+
export declare const CashoutCredentialStatus: {
|
|
1717
|
+
readonly ACTIVE: "active";
|
|
1718
|
+
readonly INACTIVE: "inactive";
|
|
1719
|
+
readonly MISSING: "missing";
|
|
1720
|
+
};
|
|
1721
|
+
export type CashoutCredentialStatusType = typeof CashoutCredentialStatus[keyof typeof CashoutCredentialStatus];
|
|
1722
|
+
export interface CashoutRailOption {
|
|
1723
|
+
rail: CashoutRailType;
|
|
1724
|
+
/** Smallest single buyer payment, USDC decimal; null for crypto rails. */
|
|
1725
|
+
minAmount: string | null;
|
|
1726
|
+
/** Largest single buyer payment, USDC decimal; null for crypto rails. */
|
|
1727
|
+
maxAmount: string | null;
|
|
1728
|
+
}
|
|
1729
|
+
/** A SAR method supports seller-side confirmation; when connecting is skipped, each buyer proves payment. */
|
|
1730
|
+
export interface CashoutSarMethod {
|
|
1731
|
+
rail: CashoutSarRailType;
|
|
1732
|
+
payeeHandle: string;
|
|
1733
|
+
credentialStatus: CashoutCredentialStatusType;
|
|
1734
|
+
/** The player chose to list without connecting this method. */
|
|
1735
|
+
connectSkipped: boolean;
|
|
1736
|
+
payeeHash: string;
|
|
1737
|
+
/** The email of the PayPal account; null on every other rail. Only the player's own checkout sees it. */
|
|
1738
|
+
paypalEmail: string | null;
|
|
1739
|
+
}
|
|
1740
|
+
/** A buyer-proof method has no connect step or credential; each buyer proves their payment. */
|
|
1741
|
+
export interface CashoutBuyerProofMethod {
|
|
1742
|
+
rail: CashoutBuyerProofRailType;
|
|
1743
|
+
payeeHandle: string;
|
|
1744
|
+
payeeHash: string;
|
|
1745
|
+
}
|
|
1746
|
+
/** GET /api/v1/cashout-checkout/:id (link token only). */
|
|
1747
|
+
export interface CashoutCheckoutSummary {
|
|
1748
|
+
cashoutId: string;
|
|
1749
|
+
merchant: {
|
|
1750
|
+
name: string;
|
|
1751
|
+
logoUrl: string | null;
|
|
1752
|
+
supportUrl: string | null;
|
|
1753
|
+
disableBranding: boolean;
|
|
1754
|
+
checkoutTheme: MerchantCheckoutTheme | null;
|
|
1755
|
+
};
|
|
1756
|
+
email: string;
|
|
1757
|
+
maskedEmail: string;
|
|
1758
|
+
payoutAmount: string;
|
|
1759
|
+
status: CashoutStatusType;
|
|
1760
|
+
rails: CashoutRailOption[];
|
|
1761
|
+
returnUrl: string | null;
|
|
1762
|
+
}
|
|
1763
|
+
/** GET /api/v1/cashout-checkout/:id/state (link token + Peer app login). */
|
|
1764
|
+
export interface CashoutCheckoutState {
|
|
1765
|
+
cashoutId: string;
|
|
1766
|
+
status: CashoutStatusType;
|
|
1767
|
+
walletAddress: string;
|
|
1768
|
+
depositAmount: string | null;
|
|
1769
|
+
/** Live from the escrow deposit; null before listing and once the listing is closed. */
|
|
1770
|
+
remainingAmount: string | null;
|
|
1771
|
+
buyerPaymentActive: boolean;
|
|
1772
|
+
method: CashoutSarMethod | CashoutBuyerProofMethod | CashoutCryptoMethod | null;
|
|
1773
|
+
/** Prefill from this player's last cashout on an available rail; never a deposit address. */
|
|
1774
|
+
lastPayoutTarget: CashoutPayoutMethodView | null;
|
|
1775
|
+
attempt: {
|
|
1776
|
+
attemptId: string;
|
|
1777
|
+
status: CashoutAttemptStatusType;
|
|
1778
|
+
depositId: string | null;
|
|
1779
|
+
} | null;
|
|
1780
|
+
signer: {
|
|
1781
|
+
signerId: string;
|
|
1782
|
+
policyId: string;
|
|
1783
|
+
attached: boolean;
|
|
1784
|
+
};
|
|
1785
|
+
/** What Pay is sending from the player's wallet right now; null when nothing is in flight. */
|
|
1786
|
+
sending: CashoutSendingType | null;
|
|
1787
|
+
/**
|
|
1788
|
+
* The newest send of the current attempt (or of the last closed attempt while the cashout is back in FUNDED/READY) failed; a failed relist counts only while the cashout is listed.
|
|
1789
|
+
* Also true when a Venmo or PayPal listing's Peer Pay group send failed and its listing was withdrawn (the cashout is back in FUNDED/READY).
|
|
1790
|
+
*/
|
|
1791
|
+
lastSendFailed: boolean;
|
|
1792
|
+
/** Set when the Peer wallet no longer covers this cashout (newest first, like the wallet job): what it needs and what is left for it after the player's older cashouts, in decimal USDC. Only CANCEL is offered then. */
|
|
1793
|
+
walletShortfall: {
|
|
1794
|
+
requiredAmount: string;
|
|
1795
|
+
availableAmount: string;
|
|
1796
|
+
} | null;
|
|
1797
|
+
/** PARTIALLY_FUNDED means the merchant still owes a top-up; receivedAmount is the USDC that reached the player's wallet. */
|
|
1798
|
+
funding: {
|
|
1799
|
+
status: CashoutFundingStatusType;
|
|
1800
|
+
receivedAmount: string | null;
|
|
1801
|
+
};
|
|
1802
|
+
/** Who cancelled; PEER_APP when the player took the cashout back in the Peer app. */
|
|
1803
|
+
cancelSource: CashoutCancelSourceType | null;
|
|
1804
|
+
merchantReference: string | null;
|
|
1805
|
+
/** Once settled: the delivering transaction and its chain. */
|
|
1806
|
+
settleTx: {
|
|
1807
|
+
chainId: number;
|
|
1808
|
+
txHash: string;
|
|
1809
|
+
} | null;
|
|
1810
|
+
/** The newest attempt's newest bridge unless it is NOT_SENT. */
|
|
1811
|
+
payoutBridge: CashoutPayoutBridgeView | null;
|
|
1812
|
+
/** While a buyer pays, when that buyer was matched (ISO time). */
|
|
1813
|
+
buyerMatchedAt: string | null;
|
|
1814
|
+
/** Set once a buyer paid part of the cashout; decimal USDC. totalAmount is depositAmount. */
|
|
1815
|
+
partialPayment: {
|
|
1816
|
+
paidAmount: string;
|
|
1817
|
+
unpaidAmount: string;
|
|
1818
|
+
totalAmount: string;
|
|
1819
|
+
/** What the live listing's deposit holds (cashoutDepositRemainingUnits); null when nothing is listed. Relist, withdraw and send amounts. */
|
|
1820
|
+
listedAmount: string | null;
|
|
1821
|
+
/**
|
|
1822
|
+
* The listed deposit still takes new buyers (EscrowV2 `acceptingIntents`). False when nothing is listed, and when a
|
|
1823
|
+
* withdraw landed while a buyer held the deposit (a send-to-address or change-method exit, or a Peer-app withdraw): the
|
|
1824
|
+
* escrow then takes no new buyer, so the rest is never relisted and only an exit moves it.
|
|
1825
|
+
*/
|
|
1826
|
+
acceptingBuyers: boolean;
|
|
1827
|
+
} | null;
|
|
1828
|
+
/** Only when status is SETTLED. */
|
|
1829
|
+
settlement: CashoutSettlementBreakdown | null;
|
|
1830
|
+
actions: CashoutPlayerActionType[];
|
|
1831
|
+
}
|
|
1832
|
+
export type SetCashoutPayoutMethodRequest = {
|
|
1833
|
+
rail: typeof CashoutRail.VENMO | typeof CashoutRail.CASHAPP;
|
|
1834
|
+
payeeHandle: string;
|
|
1835
|
+
}
|
|
1836
|
+
/** The App Clip checks the connected PayPal account against this email. */
|
|
1837
|
+
| {
|
|
1838
|
+
rail: typeof CashoutRail.PAYPAL;
|
|
1839
|
+
payeeHandle: string;
|
|
1840
|
+
paypalEmail: string;
|
|
1841
|
+
}
|
|
1842
|
+
/** Buyer-proof rails need only the payout account; there is no connect step. */
|
|
1843
|
+
| {
|
|
1844
|
+
rail: CashoutBuyerProofRailType;
|
|
1845
|
+
payeeHandle: string;
|
|
1846
|
+
} | CashoutPayoutDestinationRequest;
|
|
1847
|
+
/** POST /api/v1/cashout-checkout/:id/send-to-address. The checkout requires the network tick box before sending. */
|
|
1848
|
+
export type SendCashoutToAddressRequest = CashoutPayoutDestinationRequest;
|
|
1849
|
+
export interface CashoutActivityItem {
|
|
1850
|
+
cashoutId: string;
|
|
1851
|
+
/** Only the player passing linkAuth and loginAuth may see this link to open their cashout. */
|
|
1852
|
+
checkoutUrl: string;
|
|
1853
|
+
payoutAmount: string;
|
|
1854
|
+
/** The chosen payout app, or null before the player picks one. */
|
|
1855
|
+
payoutRail: CashoutRailType | null;
|
|
1856
|
+
status: CashoutStatusType;
|
|
1857
|
+
createdAt: string;
|
|
1858
|
+
}
|
|
1859
|
+
export interface ListCashoutActivityResponse {
|
|
1860
|
+
/** Only the player passing linkAuth and loginAuth may see the full recipient email identifying this list. */
|
|
1861
|
+
email: string;
|
|
1862
|
+
items: CashoutActivityItem[];
|
|
1863
|
+
page: number;
|
|
1864
|
+
limit: number;
|
|
1865
|
+
total: number;
|
|
1866
|
+
}
|
|
1204
1867
|
export {};
|
package/dist/types.js
CHANGED
|
@@ -231,12 +231,40 @@ export const WebhookEventType = {
|
|
|
231
231
|
PAYMENT_CHARGEBACKED: 'PAYMENT_CHARGEBACKED',
|
|
232
232
|
ORDER_PARTIALLY_CHARGEBACKED: 'ORDER_PARTIALLY_CHARGEBACKED',
|
|
233
233
|
ORDER_CHARGEBACKED: 'ORDER_CHARGEBACKED',
|
|
234
|
-
|
|
234
|
+
CASHOUT_ORDER_CREATED: 'CASHOUT_ORDER_CREATED',
|
|
235
|
+
CASHOUT_ORDER_CANCELLED: 'CASHOUT_ORDER_CANCELLED',
|
|
236
|
+
CASHOUT_ORDER_PARTIALLY_FUNDED: 'CASHOUT_ORDER_PARTIALLY_FUNDED',
|
|
237
|
+
CASHOUT_ORDER_FUNDED: 'CASHOUT_ORDER_FUNDED',
|
|
238
|
+
CASHOUT_ORDER_MATCHED: 'CASHOUT_ORDER_MATCHED',
|
|
239
|
+
CASHOUT_ORDER_PARTIALLY_PAID: 'CASHOUT_ORDER_PARTIALLY_PAID',
|
|
240
|
+
CASHOUT_ORDER_SETTLED: 'CASHOUT_ORDER_SETTLED',
|
|
241
|
+
CASHOUT_ORDER_EXPIRED: 'CASHOUT_ORDER_EXPIRED',
|
|
242
|
+
};
|
|
243
|
+
/** Cashout events carry a CashoutView, not the order envelope. */
|
|
244
|
+
export const CASHOUT_WEBHOOK_EVENT_TYPES = [
|
|
245
|
+
WebhookEventType.CASHOUT_ORDER_CREATED,
|
|
246
|
+
WebhookEventType.CASHOUT_ORDER_CANCELLED,
|
|
247
|
+
WebhookEventType.CASHOUT_ORDER_PARTIALLY_FUNDED,
|
|
248
|
+
WebhookEventType.CASHOUT_ORDER_FUNDED,
|
|
249
|
+
WebhookEventType.CASHOUT_ORDER_MATCHED,
|
|
250
|
+
WebhookEventType.CASHOUT_ORDER_PARTIALLY_PAID,
|
|
251
|
+
WebhookEventType.CASHOUT_ORDER_SETTLED,
|
|
252
|
+
WebhookEventType.CASHOUT_ORDER_EXPIRED,
|
|
253
|
+
];
|
|
254
|
+
const CASHOUT_WEBHOOK_EVENT_TYPE_SET = new Set(CASHOUT_WEBHOOK_EVENT_TYPES);
|
|
255
|
+
export function isCashoutWebhookEventType(type) {
|
|
256
|
+
return CASHOUT_WEBHOOK_EVENT_TYPE_SET.has(type);
|
|
257
|
+
}
|
|
235
258
|
export const WebhookDeliveryStatus = {
|
|
236
259
|
PENDING: 'PENDING',
|
|
237
260
|
DELIVERED: 'DELIVERED',
|
|
238
261
|
FAILED: 'FAILED',
|
|
239
262
|
};
|
|
263
|
+
/** Bumped only on a breaking change to a cashout payload. */
|
|
264
|
+
export const CASHOUT_WEBHOOK_VERSION = 1;
|
|
265
|
+
export function isCashoutWebhook(payload) {
|
|
266
|
+
return isCashoutWebhookEventType(payload.type);
|
|
267
|
+
}
|
|
240
268
|
/**
|
|
241
269
|
* Wallet-snapshot fence rejections (ownership-transfer era rule). PR 4-6 add keys to this object.
|
|
242
270
|
* MERCHANT_OWNERSHIP_CHANGED is retryable: an order insert lost the era it read its wallet in.
|
|
@@ -318,3 +346,122 @@ export function maskOwnershipTransferEmail(email) {
|
|
|
318
346
|
throw new Error('Cannot mask an address without a local part');
|
|
319
347
|
return `${email.slice(0, 1)}•••${email.slice(at)}`;
|
|
320
348
|
}
|
|
349
|
+
// ============ Cashout Types (merchant → player payouts) ============
|
|
350
|
+
export const CashoutStatus = {
|
|
351
|
+
AWAITING_FUNDING: 'AWAITING_FUNDING',
|
|
352
|
+
FUNDED: 'FUNDED',
|
|
353
|
+
READY: 'READY',
|
|
354
|
+
LISTING: 'LISTING',
|
|
355
|
+
PAYING: 'PAYING',
|
|
356
|
+
SETTLED: 'SETTLED',
|
|
357
|
+
CANCELLING: 'CANCELLING',
|
|
358
|
+
CANCELLED: 'CANCELLED',
|
|
359
|
+
EXPIRED: 'EXPIRED',
|
|
360
|
+
};
|
|
361
|
+
export const CashoutFundingStatus = {
|
|
362
|
+
AWAITING_FUNDING: 'AWAITING_FUNDING',
|
|
363
|
+
PARTIALLY_FUNDED: 'PARTIALLY_FUNDED',
|
|
364
|
+
FUNDED: 'FUNDED',
|
|
365
|
+
FUNDING_EXPIRED: 'FUNDING_EXPIRED',
|
|
366
|
+
};
|
|
367
|
+
export const CashoutCancelSource = {
|
|
368
|
+
CHECKOUT: 'CHECKOUT',
|
|
369
|
+
MERCHANT: 'MERCHANT',
|
|
370
|
+
PEER_APP: 'PEER_APP',
|
|
371
|
+
};
|
|
372
|
+
export const CashoutPayoutKind = { ESCROW: 'ESCROW', CRYPTO: 'CRYPTO' };
|
|
373
|
+
export const CashoutAttemptStatus = {
|
|
374
|
+
ACTIVE: 'ACTIVE',
|
|
375
|
+
CLOSED: 'CLOSED',
|
|
376
|
+
SETTLED: 'SETTLED',
|
|
377
|
+
FAILED: 'FAILED',
|
|
378
|
+
};
|
|
379
|
+
/** Fiat payout methods, in the order players see them: SAR rails, then buyer-proof rails. */
|
|
380
|
+
export const CashoutFiatRail = {
|
|
381
|
+
VENMO: 'venmo',
|
|
382
|
+
CASHAPP: 'cashapp',
|
|
383
|
+
PAYPAL: 'paypal',
|
|
384
|
+
ZELLE: 'zelle',
|
|
385
|
+
REVOLUT: 'revolut',
|
|
386
|
+
CHIME: 'chime',
|
|
387
|
+
};
|
|
388
|
+
/** One rail per crypto payout network, with checkout's rail ids (any-coin spec "Cashout rails"); the player sees them as one "Crypto" option. */
|
|
389
|
+
export const CashoutCryptoRail = {
|
|
390
|
+
RELAY_1: 'relay_1',
|
|
391
|
+
RELAY_10: 'relay_10',
|
|
392
|
+
RELAY_56: 'relay_56',
|
|
393
|
+
RELAY_137: 'relay_137',
|
|
394
|
+
RELAY_480: 'relay_480',
|
|
395
|
+
RELAY_999: 'relay_999',
|
|
396
|
+
RELAY_5042: 'relay_5042',
|
|
397
|
+
RELAY_8453: 'relay_8453',
|
|
398
|
+
RELAY_42161: 'relay_42161',
|
|
399
|
+
RELAY_8253038: 'relay_8253038',
|
|
400
|
+
RELAY_728126428: 'relay_728126428',
|
|
401
|
+
RELAY_792703809: 'relay_792703809',
|
|
402
|
+
/** ZEC on Zcash through NEAR Intents (Zcash spec "Catalog, route and address"); checkout's ZCASH_RAIL. */
|
|
403
|
+
NEAR_INTENTS_133701: 'near_intents_133701',
|
|
404
|
+
};
|
|
405
|
+
/** Every cashout rail, in rail order: fiat, then the crypto networks. */
|
|
406
|
+
export const CashoutRail = { ...CashoutFiatRail, ...CashoutCryptoRail };
|
|
407
|
+
export const CashoutPayoutProvider = { RELAY: 'RELAY', NEAR_INTENTS: 'NEAR_INTENTS' };
|
|
408
|
+
export const CashoutPayoutBridgeStatus = {
|
|
409
|
+
QUOTED: 'QUOTED', NOT_SENT: 'NOT_SENT', BRIDGING: 'BRIDGING', DELIVERED: 'DELIVERED', REFUNDED: 'REFUNDED',
|
|
410
|
+
};
|
|
411
|
+
// ============ Merchant Dashboard Cashout Types ============
|
|
412
|
+
/** A moment on a cashout's dashboard timeline. */
|
|
413
|
+
export const CashoutTimelineEventType = {
|
|
414
|
+
CREATED: 'CREATED',
|
|
415
|
+
PARTIALLY_FUNDED: 'PARTIALLY_FUNDED',
|
|
416
|
+
FUNDED: 'FUNDED',
|
|
417
|
+
FUNDING_EXPIRED: 'FUNDING_EXPIRED',
|
|
418
|
+
SIGNED_IN: 'SIGNED_IN',
|
|
419
|
+
METHOD_READY: 'METHOD_READY',
|
|
420
|
+
LISTED: 'LISTED',
|
|
421
|
+
TRANSFER_SENT: 'TRANSFER_SENT',
|
|
422
|
+
MATCHED: 'MATCHED',
|
|
423
|
+
/** A buyer paid part of the listing; the rest is listed again or left for the player. */
|
|
424
|
+
PARTIALLY_PAID: 'PARTIALLY_PAID',
|
|
425
|
+
/** Pay set the deposit's intent range to what is left, so another buyer can take it. */
|
|
426
|
+
RELISTED: 'RELISTED',
|
|
427
|
+
BUYER_DROPPED: 'BUYER_DROPPED',
|
|
428
|
+
RECONNECT_NEEDED: 'RECONNECT_NEEDED',
|
|
429
|
+
CANCEL_STARTED: 'CANCEL_STARTED',
|
|
430
|
+
/** The listing came back to the player's wallet so they can pick another payout method. */
|
|
431
|
+
LISTING_WITHDRAWN: 'LISTING_WITHDRAWN',
|
|
432
|
+
SETTLED: 'SETTLED',
|
|
433
|
+
CANCELLED: 'CANCELLED',
|
|
434
|
+
FUNDING_ISSUE: 'FUNDING_ISSUE',
|
|
435
|
+
PAYOUT_REFUNDED: 'PAYOUT_REFUNDED',
|
|
436
|
+
};
|
|
437
|
+
/** Largest merchant cashout payout step, in whole USDC. The smallest is the API's CASHOUT_MIN_USDC (10 in production). */
|
|
438
|
+
export const CASHOUT_PAYOUT_STEP_MAX_USDC = 1000;
|
|
439
|
+
export const CashoutFundingIssueKind = {
|
|
440
|
+
LATE_FUNDS: 'LATE_FUNDS',
|
|
441
|
+
OVERPAYMENT: 'OVERPAYMENT',
|
|
442
|
+
ROUTE_REFUND: 'ROUTE_REFUND',
|
|
443
|
+
};
|
|
444
|
+
export const CashoutFundingIssueResolution = {
|
|
445
|
+
RETURNED: 'RETURNED',
|
|
446
|
+
CLAIMED: 'CLAIMED',
|
|
447
|
+
};
|
|
448
|
+
// ============ Cashout Player Checkout Types ============
|
|
449
|
+
/** What the player can do next; drives every checkout button and every 409. */
|
|
450
|
+
export const CashoutPlayerAction = {
|
|
451
|
+
SET_METHOD: 'SET_METHOD',
|
|
452
|
+
CONNECT_RAIL: 'CONNECT_RAIL',
|
|
453
|
+
SKIP_CONNECT: 'SKIP_CONNECT',
|
|
454
|
+
CONFIRM: 'CONFIRM',
|
|
455
|
+
CANCEL: 'CANCEL',
|
|
456
|
+
FINISH_CANCEL: 'FINISH_CANCEL',
|
|
457
|
+
CHANGE_METHOD: 'CHANGE_METHOD',
|
|
458
|
+
SEND_TO_ADDRESS: 'SEND_TO_ADDRESS',
|
|
459
|
+
RELIST: 'RELIST',
|
|
460
|
+
};
|
|
461
|
+
/** What Pay is sending from the player's wallet. */
|
|
462
|
+
export const CashoutSending = { LISTING: 'LISTING', TRANSFER: 'TRANSFER', WITHDRAW: 'WITHDRAW', RELISTING: 'RELISTING' };
|
|
463
|
+
export const CashoutCredentialStatus = {
|
|
464
|
+
ACTIVE: 'active',
|
|
465
|
+
INACTIVE: 'inactive',
|
|
466
|
+
MISSING: 'missing',
|
|
467
|
+
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@zkp2p/pay-shared",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "6.0.0",
|
|
4
4
|
"description": "Shared TypeScript types, enums, and chain utilities used by ZKP2P Pay API, SDK, and frontend apps.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -37,7 +37,7 @@
|
|
|
37
37
|
"scripts": {
|
|
38
38
|
"build": "rm -rf dist && tsc -p tsconfig.json",
|
|
39
39
|
"lint": "eslint . --ext .ts,.tsx",
|
|
40
|
-
"test": "vitest run",
|
|
40
|
+
"test": "vitest run && tsc -p tsconfig.test.json",
|
|
41
41
|
"prepack": "npm run build",
|
|
42
42
|
"prepublishOnly": "npm run lint"
|
|
43
43
|
},
|