@dexterai/x402 1.9.4 → 2.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +27 -0
- package/dist/adapters/index.cjs +375 -3
- package/dist/adapters/index.d.cts +4 -5
- package/dist/adapters/index.d.ts +4 -5
- package/dist/adapters/index.js +369 -3
- package/dist/client/index.cjs +570 -10
- package/dist/client/index.d.cts +200 -36
- package/dist/client/index.d.ts +200 -36
- package/dist/client/index.js +568 -10
- package/dist/react/index.cjs +404 -8
- package/dist/react/index.d.cts +5 -5
- package/dist/react/index.d.ts +5 -5
- package/dist/react/index.js +404 -8
- package/dist/server/index.cjs +3 -4
- package/dist/server/index.d.cts +2 -2
- package/dist/server/index.d.ts +2 -2
- package/dist/server/index.js +3 -4
- package/dist/{sponsored-access-D1_mINs4.d.ts → sponsored-access-DAVzu4x6.d.cts} +13 -2
- package/dist/{sponsored-access-Br6YPA-m.d.cts → sponsored-access-Lxa11w_X.d.ts} +13 -2
- package/dist/types-D1u7iu8n.d.cts +304 -0
- package/dist/types-YQlJI5E3.d.ts +304 -0
- package/dist/{types-CjLMR7qs.d.cts → types-_iT11DL0.d.cts} +2 -2
- package/dist/{types-CjLMR7qs.d.ts → types-_iT11DL0.d.ts} +2 -2
- package/dist/utils/index.cjs +0 -1
- package/dist/utils/index.js +0 -1
- package/package.json +1 -1
- package/dist/adapters/index.cjs.map +0 -1
- package/dist/adapters/index.js.map +0 -1
- package/dist/client/index.cjs.map +0 -1
- package/dist/client/index.js.map +0 -1
- package/dist/react/index.cjs.map +0 -1
- package/dist/react/index.js.map +0 -1
- package/dist/server/index.cjs.map +0 -1
- package/dist/server/index.js.map +0 -1
- package/dist/solana-BcOfK6Eq.d.cts +0 -132
- package/dist/solana-Cxr5byPa.d.ts +0 -132
- package/dist/types-BIHhO2-I.d.ts +0 -123
- package/dist/types-CfKflCZO.d.cts +0 -123
- package/dist/utils/index.cjs.map +0 -1
- package/dist/utils/index.js.map +0 -1
|
@@ -1,132 +0,0 @@
|
|
|
1
|
-
import { A as AdapterConfig, C as ChainAdapter, S as SignedTransaction } from './types-CfKflCZO.cjs';
|
|
2
|
-
import { P as PaymentAccept } from './types-CjLMR7qs.cjs';
|
|
3
|
-
|
|
4
|
-
/**
|
|
5
|
-
* EVM Chain Adapter
|
|
6
|
-
*
|
|
7
|
-
* Implements the ChainAdapter interface for EVM networks (Base, Ethereum, Arbitrum, etc.)
|
|
8
|
-
* Uses EIP-712 typed data signing for x402 v2 payments.
|
|
9
|
-
*/
|
|
10
|
-
|
|
11
|
-
/**
|
|
12
|
-
* CAIP-2 network identifiers for EVM chains.
|
|
13
|
-
* Mirrors dexter-facilitator/src/config/chains.ts — update both when adding chains.
|
|
14
|
-
*/
|
|
15
|
-
declare const BASE_MAINNET = "eip155:8453";
|
|
16
|
-
declare const BASE_SEPOLIA = "eip155:84532";
|
|
17
|
-
declare const ARBITRUM_ONE = "eip155:42161";
|
|
18
|
-
declare const POLYGON = "eip155:137";
|
|
19
|
-
declare const OPTIMISM = "eip155:10";
|
|
20
|
-
declare const AVALANCHE = "eip155:43114";
|
|
21
|
-
declare const SKALE_BASE = "eip155:1187947933";
|
|
22
|
-
declare const SKALE_BASE_SEPOLIA = "eip155:324705682";
|
|
23
|
-
/** @deprecated Not supported by the Dexter facilitator. Use BASE_MAINNET for EVM payments. */
|
|
24
|
-
declare const ETHEREUM_MAINNET = "eip155:1";
|
|
25
|
-
/**
|
|
26
|
-
* USDC contract addresses by chain.
|
|
27
|
-
* Source of truth: dexter-facilitator/src/config/chains.ts
|
|
28
|
-
*/
|
|
29
|
-
declare const USDC_ADDRESSES: Record<string, string>;
|
|
30
|
-
/**
|
|
31
|
-
* EVM wallet interface (compatible with wagmi, ethers, viem)
|
|
32
|
-
*/
|
|
33
|
-
interface EvmWallet {
|
|
34
|
-
/** Wallet address */
|
|
35
|
-
address: string;
|
|
36
|
-
/** Chain ID currently connected to */
|
|
37
|
-
chainId?: number;
|
|
38
|
-
/**
|
|
39
|
-
* Sign typed data (EIP-712)
|
|
40
|
-
* This is the primary signing method for x402 EVM payments
|
|
41
|
-
*/
|
|
42
|
-
signTypedData?(params: {
|
|
43
|
-
domain: Record<string, unknown>;
|
|
44
|
-
types: Record<string, unknown[]>;
|
|
45
|
-
primaryType: string;
|
|
46
|
-
message: Record<string, unknown>;
|
|
47
|
-
}): Promise<string>;
|
|
48
|
-
/**
|
|
49
|
-
* Alternative: Send transaction directly
|
|
50
|
-
* Used if signTypedData is not available
|
|
51
|
-
*/
|
|
52
|
-
sendTransaction?(params: {
|
|
53
|
-
to: string;
|
|
54
|
-
data: string;
|
|
55
|
-
value?: bigint;
|
|
56
|
-
}): Promise<string>;
|
|
57
|
-
}
|
|
58
|
-
/**
|
|
59
|
-
* Check if an object is a valid EVM wallet
|
|
60
|
-
*/
|
|
61
|
-
declare function isEvmWallet(wallet: unknown): wallet is EvmWallet;
|
|
62
|
-
/**
|
|
63
|
-
* EVM Chain Adapter
|
|
64
|
-
*/
|
|
65
|
-
declare class EvmAdapter implements ChainAdapter {
|
|
66
|
-
readonly name = "EVM";
|
|
67
|
-
readonly networks: string[];
|
|
68
|
-
private config;
|
|
69
|
-
private log;
|
|
70
|
-
constructor(config?: AdapterConfig);
|
|
71
|
-
canHandle(network: string): boolean;
|
|
72
|
-
getDefaultRpcUrl(network: string): string;
|
|
73
|
-
getAddress(wallet: unknown): string | null;
|
|
74
|
-
isConnected(wallet: unknown): boolean;
|
|
75
|
-
private getChainId;
|
|
76
|
-
getBalance(accept: PaymentAccept, wallet: unknown, rpcUrl?: string): Promise<number>;
|
|
77
|
-
private encodeBalanceOf;
|
|
78
|
-
buildTransaction(accept: PaymentAccept, wallet: unknown, _rpcUrl?: string): Promise<SignedTransaction>;
|
|
79
|
-
}
|
|
80
|
-
/**
|
|
81
|
-
* Create an EVM adapter instance
|
|
82
|
-
*/
|
|
83
|
-
declare function createEvmAdapter(config?: AdapterConfig): EvmAdapter;
|
|
84
|
-
|
|
85
|
-
/**
|
|
86
|
-
* Solana Chain Adapter
|
|
87
|
-
*
|
|
88
|
-
* Implements the ChainAdapter interface for Solana networks.
|
|
89
|
-
* Handles transaction building, signing, and balance queries.
|
|
90
|
-
*/
|
|
91
|
-
|
|
92
|
-
/**
|
|
93
|
-
* CAIP-2 network identifiers for Solana
|
|
94
|
-
*/
|
|
95
|
-
declare const SOLANA_MAINNET = "solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp";
|
|
96
|
-
declare const SOLANA_DEVNET = "solana:EtWTRABZaYq6iMfeYKouRu166VU2xqa1";
|
|
97
|
-
declare const SOLANA_TESTNET = "solana:4uhcVJyU9pJkvQyS88uRDiswHXSCkY3z";
|
|
98
|
-
/**
|
|
99
|
-
* Solana wallet interface (compatible with @solana/wallet-adapter)
|
|
100
|
-
*/
|
|
101
|
-
interface SolanaWallet {
|
|
102
|
-
publicKey: {
|
|
103
|
-
toBase58(): string;
|
|
104
|
-
} | null;
|
|
105
|
-
signTransaction<T>(tx: T): Promise<T>;
|
|
106
|
-
}
|
|
107
|
-
/**
|
|
108
|
-
* Check if an object is a valid Solana wallet
|
|
109
|
-
*/
|
|
110
|
-
declare function isSolanaWallet(wallet: unknown): wallet is SolanaWallet;
|
|
111
|
-
/**
|
|
112
|
-
* Solana Chain Adapter
|
|
113
|
-
*/
|
|
114
|
-
declare class SolanaAdapter implements ChainAdapter {
|
|
115
|
-
readonly name = "Solana";
|
|
116
|
-
readonly networks: string[];
|
|
117
|
-
private config;
|
|
118
|
-
private log;
|
|
119
|
-
constructor(config?: AdapterConfig);
|
|
120
|
-
canHandle(network: string): boolean;
|
|
121
|
-
getDefaultRpcUrl(network: string): string;
|
|
122
|
-
getAddress(wallet: unknown): string | null;
|
|
123
|
-
isConnected(wallet: unknown): boolean;
|
|
124
|
-
getBalance(accept: PaymentAccept, wallet: unknown, rpcUrl?: string): Promise<number>;
|
|
125
|
-
buildTransaction(accept: PaymentAccept, wallet: unknown, rpcUrl?: string): Promise<SignedTransaction>;
|
|
126
|
-
}
|
|
127
|
-
/**
|
|
128
|
-
* Create a Solana adapter instance
|
|
129
|
-
*/
|
|
130
|
-
declare function createSolanaAdapter(config?: AdapterConfig): SolanaAdapter;
|
|
131
|
-
|
|
132
|
-
export { ARBITRUM_ONE as A, BASE_MAINNET as B, type EvmWallet as E, OPTIMISM as O, POLYGON as P, SOLANA_MAINNET as S, USDC_ADDRESSES as U, createEvmAdapter as a, SolanaAdapter as b, createSolanaAdapter as c, EvmAdapter as d, SOLANA_DEVNET as e, SOLANA_TESTNET as f, type SolanaWallet as g, isEvmWallet as h, isSolanaWallet as i, BASE_SEPOLIA as j, AVALANCHE as k, SKALE_BASE as l, SKALE_BASE_SEPOLIA as m, ETHEREUM_MAINNET as n };
|
|
@@ -1,132 +0,0 @@
|
|
|
1
|
-
import { A as AdapterConfig, C as ChainAdapter, S as SignedTransaction } from './types-BIHhO2-I.js';
|
|
2
|
-
import { P as PaymentAccept } from './types-CjLMR7qs.js';
|
|
3
|
-
|
|
4
|
-
/**
|
|
5
|
-
* EVM Chain Adapter
|
|
6
|
-
*
|
|
7
|
-
* Implements the ChainAdapter interface for EVM networks (Base, Ethereum, Arbitrum, etc.)
|
|
8
|
-
* Uses EIP-712 typed data signing for x402 v2 payments.
|
|
9
|
-
*/
|
|
10
|
-
|
|
11
|
-
/**
|
|
12
|
-
* CAIP-2 network identifiers for EVM chains.
|
|
13
|
-
* Mirrors dexter-facilitator/src/config/chains.ts — update both when adding chains.
|
|
14
|
-
*/
|
|
15
|
-
declare const BASE_MAINNET = "eip155:8453";
|
|
16
|
-
declare const BASE_SEPOLIA = "eip155:84532";
|
|
17
|
-
declare const ARBITRUM_ONE = "eip155:42161";
|
|
18
|
-
declare const POLYGON = "eip155:137";
|
|
19
|
-
declare const OPTIMISM = "eip155:10";
|
|
20
|
-
declare const AVALANCHE = "eip155:43114";
|
|
21
|
-
declare const SKALE_BASE = "eip155:1187947933";
|
|
22
|
-
declare const SKALE_BASE_SEPOLIA = "eip155:324705682";
|
|
23
|
-
/** @deprecated Not supported by the Dexter facilitator. Use BASE_MAINNET for EVM payments. */
|
|
24
|
-
declare const ETHEREUM_MAINNET = "eip155:1";
|
|
25
|
-
/**
|
|
26
|
-
* USDC contract addresses by chain.
|
|
27
|
-
* Source of truth: dexter-facilitator/src/config/chains.ts
|
|
28
|
-
*/
|
|
29
|
-
declare const USDC_ADDRESSES: Record<string, string>;
|
|
30
|
-
/**
|
|
31
|
-
* EVM wallet interface (compatible with wagmi, ethers, viem)
|
|
32
|
-
*/
|
|
33
|
-
interface EvmWallet {
|
|
34
|
-
/** Wallet address */
|
|
35
|
-
address: string;
|
|
36
|
-
/** Chain ID currently connected to */
|
|
37
|
-
chainId?: number;
|
|
38
|
-
/**
|
|
39
|
-
* Sign typed data (EIP-712)
|
|
40
|
-
* This is the primary signing method for x402 EVM payments
|
|
41
|
-
*/
|
|
42
|
-
signTypedData?(params: {
|
|
43
|
-
domain: Record<string, unknown>;
|
|
44
|
-
types: Record<string, unknown[]>;
|
|
45
|
-
primaryType: string;
|
|
46
|
-
message: Record<string, unknown>;
|
|
47
|
-
}): Promise<string>;
|
|
48
|
-
/**
|
|
49
|
-
* Alternative: Send transaction directly
|
|
50
|
-
* Used if signTypedData is not available
|
|
51
|
-
*/
|
|
52
|
-
sendTransaction?(params: {
|
|
53
|
-
to: string;
|
|
54
|
-
data: string;
|
|
55
|
-
value?: bigint;
|
|
56
|
-
}): Promise<string>;
|
|
57
|
-
}
|
|
58
|
-
/**
|
|
59
|
-
* Check if an object is a valid EVM wallet
|
|
60
|
-
*/
|
|
61
|
-
declare function isEvmWallet(wallet: unknown): wallet is EvmWallet;
|
|
62
|
-
/**
|
|
63
|
-
* EVM Chain Adapter
|
|
64
|
-
*/
|
|
65
|
-
declare class EvmAdapter implements ChainAdapter {
|
|
66
|
-
readonly name = "EVM";
|
|
67
|
-
readonly networks: string[];
|
|
68
|
-
private config;
|
|
69
|
-
private log;
|
|
70
|
-
constructor(config?: AdapterConfig);
|
|
71
|
-
canHandle(network: string): boolean;
|
|
72
|
-
getDefaultRpcUrl(network: string): string;
|
|
73
|
-
getAddress(wallet: unknown): string | null;
|
|
74
|
-
isConnected(wallet: unknown): boolean;
|
|
75
|
-
private getChainId;
|
|
76
|
-
getBalance(accept: PaymentAccept, wallet: unknown, rpcUrl?: string): Promise<number>;
|
|
77
|
-
private encodeBalanceOf;
|
|
78
|
-
buildTransaction(accept: PaymentAccept, wallet: unknown, _rpcUrl?: string): Promise<SignedTransaction>;
|
|
79
|
-
}
|
|
80
|
-
/**
|
|
81
|
-
* Create an EVM adapter instance
|
|
82
|
-
*/
|
|
83
|
-
declare function createEvmAdapter(config?: AdapterConfig): EvmAdapter;
|
|
84
|
-
|
|
85
|
-
/**
|
|
86
|
-
* Solana Chain Adapter
|
|
87
|
-
*
|
|
88
|
-
* Implements the ChainAdapter interface for Solana networks.
|
|
89
|
-
* Handles transaction building, signing, and balance queries.
|
|
90
|
-
*/
|
|
91
|
-
|
|
92
|
-
/**
|
|
93
|
-
* CAIP-2 network identifiers for Solana
|
|
94
|
-
*/
|
|
95
|
-
declare const SOLANA_MAINNET = "solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp";
|
|
96
|
-
declare const SOLANA_DEVNET = "solana:EtWTRABZaYq6iMfeYKouRu166VU2xqa1";
|
|
97
|
-
declare const SOLANA_TESTNET = "solana:4uhcVJyU9pJkvQyS88uRDiswHXSCkY3z";
|
|
98
|
-
/**
|
|
99
|
-
* Solana wallet interface (compatible with @solana/wallet-adapter)
|
|
100
|
-
*/
|
|
101
|
-
interface SolanaWallet {
|
|
102
|
-
publicKey: {
|
|
103
|
-
toBase58(): string;
|
|
104
|
-
} | null;
|
|
105
|
-
signTransaction<T>(tx: T): Promise<T>;
|
|
106
|
-
}
|
|
107
|
-
/**
|
|
108
|
-
* Check if an object is a valid Solana wallet
|
|
109
|
-
*/
|
|
110
|
-
declare function isSolanaWallet(wallet: unknown): wallet is SolanaWallet;
|
|
111
|
-
/**
|
|
112
|
-
* Solana Chain Adapter
|
|
113
|
-
*/
|
|
114
|
-
declare class SolanaAdapter implements ChainAdapter {
|
|
115
|
-
readonly name = "Solana";
|
|
116
|
-
readonly networks: string[];
|
|
117
|
-
private config;
|
|
118
|
-
private log;
|
|
119
|
-
constructor(config?: AdapterConfig);
|
|
120
|
-
canHandle(network: string): boolean;
|
|
121
|
-
getDefaultRpcUrl(network: string): string;
|
|
122
|
-
getAddress(wallet: unknown): string | null;
|
|
123
|
-
isConnected(wallet: unknown): boolean;
|
|
124
|
-
getBalance(accept: PaymentAccept, wallet: unknown, rpcUrl?: string): Promise<number>;
|
|
125
|
-
buildTransaction(accept: PaymentAccept, wallet: unknown, rpcUrl?: string): Promise<SignedTransaction>;
|
|
126
|
-
}
|
|
127
|
-
/**
|
|
128
|
-
* Create a Solana adapter instance
|
|
129
|
-
*/
|
|
130
|
-
declare function createSolanaAdapter(config?: AdapterConfig): SolanaAdapter;
|
|
131
|
-
|
|
132
|
-
export { ARBITRUM_ONE as A, BASE_MAINNET as B, type EvmWallet as E, OPTIMISM as O, POLYGON as P, SOLANA_MAINNET as S, USDC_ADDRESSES as U, createEvmAdapter as a, SolanaAdapter as b, createSolanaAdapter as c, EvmAdapter as d, SOLANA_DEVNET as e, SOLANA_TESTNET as f, type SolanaWallet as g, isEvmWallet as h, isSolanaWallet as i, BASE_SEPOLIA as j, AVALANCHE as k, SKALE_BASE as l, SKALE_BASE_SEPOLIA as m, ETHEREUM_MAINNET as n };
|
package/dist/types-BIHhO2-I.d.ts
DELETED
|
@@ -1,123 +0,0 @@
|
|
|
1
|
-
import { P as PaymentAccept } from './types-CjLMR7qs.js';
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* Chain Adapter Interface
|
|
5
|
-
*
|
|
6
|
-
* x402 v2 is chain-agnostic. This interface defines how each chain
|
|
7
|
-
* handles transaction building, signing, and balance queries.
|
|
8
|
-
*
|
|
9
|
-
* Implementations:
|
|
10
|
-
* - SolanaAdapter: Solana mainnet/devnet
|
|
11
|
-
* - EvmAdapter: Base, Arbitrum, Ethereum, etc.
|
|
12
|
-
*/
|
|
13
|
-
|
|
14
|
-
/**
|
|
15
|
-
* Generic wallet interface that works across chains.
|
|
16
|
-
* Each chain adapter will cast to its specific wallet type.
|
|
17
|
-
*/
|
|
18
|
-
interface GenericWallet {
|
|
19
|
-
/** Chain-specific identifier (address or public key) */
|
|
20
|
-
address: string;
|
|
21
|
-
/** Whether the wallet is connected and ready */
|
|
22
|
-
connected: boolean;
|
|
23
|
-
}
|
|
24
|
-
/**
|
|
25
|
-
* Result of building and signing a transaction.
|
|
26
|
-
*
|
|
27
|
-
* **Internal adapter return type.** The client remaps these fields before
|
|
28
|
-
* sending to the facilitator — the wire payload uses `payload.transaction`
|
|
29
|
-
* (Solana) or `payload.authorization + payload.signature` (EVM), not
|
|
30
|
-
* `serialized` directly. See {@link ../client/x402-client.ts} for the mapping.
|
|
31
|
-
*/
|
|
32
|
-
interface SignedTransaction {
|
|
33
|
-
/** Base64 (Solana) or JSON-stringified (EVM) transaction — internal only, not the wire field name */
|
|
34
|
-
serialized: string;
|
|
35
|
-
/** Transaction signature/hash if available before broadcast */
|
|
36
|
-
signature?: string;
|
|
37
|
-
}
|
|
38
|
-
/**
|
|
39
|
-
* Chain adapter interface - each chain implements this
|
|
40
|
-
*/
|
|
41
|
-
interface ChainAdapter {
|
|
42
|
-
/**
|
|
43
|
-
* Human-readable chain name
|
|
44
|
-
*/
|
|
45
|
-
readonly name: string;
|
|
46
|
-
/**
|
|
47
|
-
* CAIP-2 network identifiers this adapter handles
|
|
48
|
-
* e.g., ['solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp'] for Solana mainnet
|
|
49
|
-
* e.g., ['eip155:8453'] for Base
|
|
50
|
-
*/
|
|
51
|
-
readonly networks: string[];
|
|
52
|
-
/**
|
|
53
|
-
* Check if this adapter can handle a given network
|
|
54
|
-
* @param network - CAIP-2 network identifier
|
|
55
|
-
*/
|
|
56
|
-
canHandle(network: string): boolean;
|
|
57
|
-
/**
|
|
58
|
-
* Build and sign a payment transaction
|
|
59
|
-
*
|
|
60
|
-
* @param accept - The payment option from server's accepts[]
|
|
61
|
-
* @param wallet - Chain-specific wallet (will be cast internally)
|
|
62
|
-
* @param rpcUrl - Optional RPC URL override
|
|
63
|
-
* @returns Signed transaction ready for PAYMENT-SIGNATURE payload
|
|
64
|
-
*/
|
|
65
|
-
buildTransaction(accept: PaymentAccept, wallet: unknown, rpcUrl?: string): Promise<SignedTransaction>;
|
|
66
|
-
/**
|
|
67
|
-
* Get the wallet's balance for the payment asset
|
|
68
|
-
*
|
|
69
|
-
* @param accept - Payment option (contains asset info)
|
|
70
|
-
* @param wallet - Chain-specific wallet
|
|
71
|
-
* @param rpcUrl - Optional RPC URL override
|
|
72
|
-
* @returns Balance in human-readable units (e.g., 12.50 for $12.50 USDC)
|
|
73
|
-
*/
|
|
74
|
-
getBalance(accept: PaymentAccept, wallet: unknown, rpcUrl?: string): Promise<number>;
|
|
75
|
-
/**
|
|
76
|
-
* Get the wallet's address as a string
|
|
77
|
-
* @param wallet - Chain-specific wallet
|
|
78
|
-
*/
|
|
79
|
-
getAddress(wallet: unknown): string | null;
|
|
80
|
-
/**
|
|
81
|
-
* Check if wallet is connected
|
|
82
|
-
* @param wallet - Chain-specific wallet
|
|
83
|
-
*/
|
|
84
|
-
isConnected(wallet: unknown): boolean;
|
|
85
|
-
/**
|
|
86
|
-
* Get default RPC URL for a network
|
|
87
|
-
* @param network - CAIP-2 network identifier
|
|
88
|
-
*/
|
|
89
|
-
getDefaultRpcUrl(network: string): string;
|
|
90
|
-
}
|
|
91
|
-
/**
|
|
92
|
-
* Configuration for creating a chain adapter
|
|
93
|
-
*/
|
|
94
|
-
interface AdapterConfig {
|
|
95
|
-
/** Custom RPC URLs by network */
|
|
96
|
-
rpcUrls?: Record<string, string>;
|
|
97
|
-
/** Enable verbose logging */
|
|
98
|
-
verbose?: boolean;
|
|
99
|
-
}
|
|
100
|
-
/**
|
|
101
|
-
* Multi-wallet container for different chains
|
|
102
|
-
*/
|
|
103
|
-
interface WalletSet {
|
|
104
|
-
/** Solana wallet (from @solana/wallet-adapter) */
|
|
105
|
-
solana?: unknown;
|
|
106
|
-
/** EVM wallet (from wagmi, ethers, or viem) */
|
|
107
|
-
evm?: unknown;
|
|
108
|
-
}
|
|
109
|
-
/**
|
|
110
|
-
* Balance info across chains
|
|
111
|
-
*/
|
|
112
|
-
interface BalanceInfo {
|
|
113
|
-
/** CAIP-2 network identifier */
|
|
114
|
-
network: string;
|
|
115
|
-
/** Human-readable chain name */
|
|
116
|
-
chainName: string;
|
|
117
|
-
/** Balance in human units */
|
|
118
|
-
balance: number;
|
|
119
|
-
/** Asset symbol (e.g., 'USDC') */
|
|
120
|
-
asset: string;
|
|
121
|
-
}
|
|
122
|
-
|
|
123
|
-
export type { AdapterConfig as A, BalanceInfo as B, ChainAdapter as C, GenericWallet as G, SignedTransaction as S, WalletSet as W };
|
|
@@ -1,123 +0,0 @@
|
|
|
1
|
-
import { P as PaymentAccept } from './types-CjLMR7qs.cjs';
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* Chain Adapter Interface
|
|
5
|
-
*
|
|
6
|
-
* x402 v2 is chain-agnostic. This interface defines how each chain
|
|
7
|
-
* handles transaction building, signing, and balance queries.
|
|
8
|
-
*
|
|
9
|
-
* Implementations:
|
|
10
|
-
* - SolanaAdapter: Solana mainnet/devnet
|
|
11
|
-
* - EvmAdapter: Base, Arbitrum, Ethereum, etc.
|
|
12
|
-
*/
|
|
13
|
-
|
|
14
|
-
/**
|
|
15
|
-
* Generic wallet interface that works across chains.
|
|
16
|
-
* Each chain adapter will cast to its specific wallet type.
|
|
17
|
-
*/
|
|
18
|
-
interface GenericWallet {
|
|
19
|
-
/** Chain-specific identifier (address or public key) */
|
|
20
|
-
address: string;
|
|
21
|
-
/** Whether the wallet is connected and ready */
|
|
22
|
-
connected: boolean;
|
|
23
|
-
}
|
|
24
|
-
/**
|
|
25
|
-
* Result of building and signing a transaction.
|
|
26
|
-
*
|
|
27
|
-
* **Internal adapter return type.** The client remaps these fields before
|
|
28
|
-
* sending to the facilitator — the wire payload uses `payload.transaction`
|
|
29
|
-
* (Solana) or `payload.authorization + payload.signature` (EVM), not
|
|
30
|
-
* `serialized` directly. See {@link ../client/x402-client.ts} for the mapping.
|
|
31
|
-
*/
|
|
32
|
-
interface SignedTransaction {
|
|
33
|
-
/** Base64 (Solana) or JSON-stringified (EVM) transaction — internal only, not the wire field name */
|
|
34
|
-
serialized: string;
|
|
35
|
-
/** Transaction signature/hash if available before broadcast */
|
|
36
|
-
signature?: string;
|
|
37
|
-
}
|
|
38
|
-
/**
|
|
39
|
-
* Chain adapter interface - each chain implements this
|
|
40
|
-
*/
|
|
41
|
-
interface ChainAdapter {
|
|
42
|
-
/**
|
|
43
|
-
* Human-readable chain name
|
|
44
|
-
*/
|
|
45
|
-
readonly name: string;
|
|
46
|
-
/**
|
|
47
|
-
* CAIP-2 network identifiers this adapter handles
|
|
48
|
-
* e.g., ['solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp'] for Solana mainnet
|
|
49
|
-
* e.g., ['eip155:8453'] for Base
|
|
50
|
-
*/
|
|
51
|
-
readonly networks: string[];
|
|
52
|
-
/**
|
|
53
|
-
* Check if this adapter can handle a given network
|
|
54
|
-
* @param network - CAIP-2 network identifier
|
|
55
|
-
*/
|
|
56
|
-
canHandle(network: string): boolean;
|
|
57
|
-
/**
|
|
58
|
-
* Build and sign a payment transaction
|
|
59
|
-
*
|
|
60
|
-
* @param accept - The payment option from server's accepts[]
|
|
61
|
-
* @param wallet - Chain-specific wallet (will be cast internally)
|
|
62
|
-
* @param rpcUrl - Optional RPC URL override
|
|
63
|
-
* @returns Signed transaction ready for PAYMENT-SIGNATURE payload
|
|
64
|
-
*/
|
|
65
|
-
buildTransaction(accept: PaymentAccept, wallet: unknown, rpcUrl?: string): Promise<SignedTransaction>;
|
|
66
|
-
/**
|
|
67
|
-
* Get the wallet's balance for the payment asset
|
|
68
|
-
*
|
|
69
|
-
* @param accept - Payment option (contains asset info)
|
|
70
|
-
* @param wallet - Chain-specific wallet
|
|
71
|
-
* @param rpcUrl - Optional RPC URL override
|
|
72
|
-
* @returns Balance in human-readable units (e.g., 12.50 for $12.50 USDC)
|
|
73
|
-
*/
|
|
74
|
-
getBalance(accept: PaymentAccept, wallet: unknown, rpcUrl?: string): Promise<number>;
|
|
75
|
-
/**
|
|
76
|
-
* Get the wallet's address as a string
|
|
77
|
-
* @param wallet - Chain-specific wallet
|
|
78
|
-
*/
|
|
79
|
-
getAddress(wallet: unknown): string | null;
|
|
80
|
-
/**
|
|
81
|
-
* Check if wallet is connected
|
|
82
|
-
* @param wallet - Chain-specific wallet
|
|
83
|
-
*/
|
|
84
|
-
isConnected(wallet: unknown): boolean;
|
|
85
|
-
/**
|
|
86
|
-
* Get default RPC URL for a network
|
|
87
|
-
* @param network - CAIP-2 network identifier
|
|
88
|
-
*/
|
|
89
|
-
getDefaultRpcUrl(network: string): string;
|
|
90
|
-
}
|
|
91
|
-
/**
|
|
92
|
-
* Configuration for creating a chain adapter
|
|
93
|
-
*/
|
|
94
|
-
interface AdapterConfig {
|
|
95
|
-
/** Custom RPC URLs by network */
|
|
96
|
-
rpcUrls?: Record<string, string>;
|
|
97
|
-
/** Enable verbose logging */
|
|
98
|
-
verbose?: boolean;
|
|
99
|
-
}
|
|
100
|
-
/**
|
|
101
|
-
* Multi-wallet container for different chains
|
|
102
|
-
*/
|
|
103
|
-
interface WalletSet {
|
|
104
|
-
/** Solana wallet (from @solana/wallet-adapter) */
|
|
105
|
-
solana?: unknown;
|
|
106
|
-
/** EVM wallet (from wagmi, ethers, or viem) */
|
|
107
|
-
evm?: unknown;
|
|
108
|
-
}
|
|
109
|
-
/**
|
|
110
|
-
* Balance info across chains
|
|
111
|
-
*/
|
|
112
|
-
interface BalanceInfo {
|
|
113
|
-
/** CAIP-2 network identifier */
|
|
114
|
-
network: string;
|
|
115
|
-
/** Human-readable chain name */
|
|
116
|
-
chainName: string;
|
|
117
|
-
/** Balance in human units */
|
|
118
|
-
balance: number;
|
|
119
|
-
/** Asset symbol (e.g., 'USDC') */
|
|
120
|
-
asset: string;
|
|
121
|
-
}
|
|
122
|
-
|
|
123
|
-
export type { AdapterConfig as A, BalanceInfo as B, ChainAdapter as C, GenericWallet as G, SignedTransaction as S, WalletSet as W };
|
package/dist/utils/index.cjs.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/utils/index.ts","../../src/types.ts","../../src/utils.ts"],"sourcesContent":["/**\n * @dexterai/x402 Utils\n *\n * Helper functions for x402 payments.\n *\n * @example\n * ```typescript\n * import { toAtomicUnits, fromAtomicUnits } from '@dexterai/x402/utils';\n *\n * const atomic = toAtomicUnits(0.05, 6); // '50000'\n * const human = fromAtomicUnits('50000', 6); // 0.05\n * ```\n */\n\nexport {\n toAtomicUnits,\n fromAtomicUnits,\n getChainFamily,\n getChainName,\n getExplorerUrl,\n type ChainFamily,\n} from '../utils';\n","/**\n * x402 v2 SDK — Shared Types\n *\n * Chain-agnostic types for x402 v2 payments.\n * Works with Solana, Base, and any future x402-compatible networks.\n */\n\n// ============================================================================\n// Network Constants\n// ============================================================================\n\n/** CAIP-2 network identifier for Solana mainnet */\nexport const SOLANA_MAINNET_NETWORK = 'solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp';\n\n/** CAIP-2 network identifier for Base mainnet */\nexport const BASE_MAINNET_NETWORK = 'eip155:8453';\n\n/** Alias for Solana mainnet */\nexport const SOLANA_MAINNET = SOLANA_MAINNET_NETWORK;\n\n/** Alias for Base mainnet */\nexport const BASE_MAINNET = BASE_MAINNET_NETWORK;\n\n// ============================================================================\n// Asset Constants\n// ============================================================================\n\n/** USDC mint on Solana mainnet */\nexport const USDC_MINT = 'EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v';\n\n/** USDC address on Base mainnet */\nexport const USDC_BASE = '0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913';\n\n// ============================================================================\n// Facilitator Constants\n// ============================================================================\n\n/** Dexter's public x402 v2 facilitator URL */\nexport const DEXTER_FACILITATOR_URL = 'https://x402.dexter.cash';\n\n// ============================================================================\n// PayTo Provider Types (for dynamic address resolution, e.g. Stripe)\n// ============================================================================\n\n/**\n * Context passed to a PayToProvider function.\n * Contains request-scoped information for dynamic address resolution.\n */\nexport interface PayToContext {\n /** The PAYMENT-SIGNATURE header value (present on retry/verify, undefined on initial 402) */\n paymentHeader?: string;\n /** Amount in atomic units (e.g., '10000' for 0.01 USDC) */\n amountAtomic?: string;\n /** The resource URL being accessed */\n resourceUrl?: string;\n}\n\n/**\n * Optional defaults a PayToProvider can advertise for auto-configuration.\n * Attached as `_x402Defaults` on the provider function.\n */\nexport interface PayToProviderDefaults {\n /** Default CAIP-2 network (e.g., 'eip155:8453' for Base) */\n network?: string;\n /** Default facilitator URL */\n facilitatorUrl?: string;\n}\n\n/**\n * A function that dynamically resolves a payment address.\n * Used for providers like Stripe that generate per-request deposit addresses.\n *\n * @example\n * ```typescript\n * import { stripePayTo } from '@dexterai/x402/server';\n *\n * const provider = stripePayTo(process.env.STRIPE_SECRET_KEY);\n * const address = await provider({ amountAtomic: '10000' });\n * ```\n */\nexport type PayToProvider = ((context: PayToContext) => Promise<string>) & {\n /** Auto-configuration defaults (set by provider factories like stripePayTo) */\n _x402Defaults?: PayToProviderDefaults;\n};\n\n// ============================================================================\n// Payment Types\n// ============================================================================\n\n/**\n * Asset configuration for payments\n */\nexport interface AssetConfig {\n /** Token address (mint on Solana, contract on EVM) */\n address: string;\n /** Token decimals */\n decimals: number;\n /** Optional: Human-readable symbol */\n symbol?: string;\n}\n\n/**\n * Resource info included in payment requirements\n */\nexport interface ResourceInfo {\n /** Resource URL */\n url: string;\n /** Human-readable description */\n description?: string;\n /** MIME type of the resource */\n mimeType?: string;\n}\n\n/**\n * Extra fields in payment requirements\n * Chain-specific fields may vary\n */\nexport interface AcceptsExtra {\n /** Facilitator address that pays tx fees (required for Solana) */\n feePayer?: string;\n /** Token decimals (optional - defaults to 6 for USDC) */\n decimals?: number;\n /** EIP-712: Token name (EVM only) */\n name?: string;\n /** EIP-712: Token version (EVM only) */\n version?: string;\n /** Additional chain-specific fields */\n [key: string]: unknown;\n}\n\n/**\n * A single payment option in the accepts array\n */\nexport interface PaymentAccept {\n /** x402 version (1 or 2, defaults to 2 if not specified) */\n x402Version?: 1 | 2;\n /** Payment scheme (always 'exact' for x402 v2) */\n scheme: 'exact';\n /** CAIP-2 network identifier (v1: 'solana', v2: 'solana:5eykt...') */\n network: string;\n /** Payment amount in atomic units (x402 v2 spec field) */\n amount: string;\n /** @deprecated v1 field — use `amount` instead. Kept for backwards compatibility with v1 data. */\n maxAmountRequired?: string;\n /** Token address */\n asset: string;\n /** Seller's address to receive payment */\n payTo: string;\n /** Maximum seconds until payment expires */\n maxTimeoutSeconds: number;\n /** Chain-specific extra data */\n extra?: AcceptsExtra;\n}\n\n/**\n * Full PaymentRequired structure (sent in PAYMENT-REQUIRED header)\n */\nexport interface PaymentRequired {\n /** x402 version (always 2) */\n x402Version: 2;\n /** Resource being accessed */\n resource: ResourceInfo;\n /** Available payment options */\n accepts: PaymentAccept[];\n /** Optional error message */\n error?: string;\n /** Protocol extensions */\n extensions?: Record<string, unknown>;\n}\n\n/**\n * PaymentSignature structure (sent in PAYMENT-SIGNATURE header)\n */\nexport interface PaymentSignature {\n /** x402 version (always 2) */\n x402Version: 2;\n /** Resource being accessed */\n resource: ResourceInfo;\n /** The payment option that was accepted */\n accepted: PaymentAccept;\n /** The signed payment */\n payload: {\n /** Signed transaction (base64 for Solana, JSON for EVM) */\n transaction: string;\n };\n /** Protocol extensions */\n extensions?: Record<string, unknown>;\n}\n\n// ============================================================================\n// Facilitator Response Types\n// ============================================================================\n\n/**\n * Response from /verify endpoint\n */\nexport interface VerifyResponse {\n /** Whether the payment is valid */\n isValid: boolean;\n /** Reason for invalidity (if invalid) */\n invalidReason?: string;\n /** Payer address */\n payer?: string;\n}\n\n/**\n * Response from /settle endpoint\n */\nexport interface SettleResponse {\n /** Whether settlement succeeded */\n success: boolean;\n /** Transaction signature/hash */\n transaction?: string;\n /** Network the payment was made on */\n network: string;\n /** Error reason (if failed) */\n errorReason?: string;\n /** Error code (if failed) */\n errorCode?: string;\n /** Payer address */\n payer?: string;\n /** Protocol extensions returned by the facilitator (e.g., sponsored-access recommendations) */\n extensions?: Record<string, unknown>;\n}\n\n// ============================================================================\n// Access Pass Types\n// ============================================================================\n\n/**\n * A single access pass tier offered by a seller\n */\nexport interface AccessPassTier {\n /** Tier ID (e.g., '1h', '24h') */\n id: string;\n /** Human-readable label (e.g., '1 hour') */\n label: string;\n /** Duration in seconds */\n seconds: number;\n /** Price in USD (e.g., '0.50') */\n price: string;\n /** Price in atomic units (e.g., '500000') */\n priceAtomic: string;\n}\n\n/**\n * Access pass info returned in X-ACCESS-PASS-TIERS header\n */\nexport interface AccessPassInfo {\n /** Available tiers (if tier-based pricing) */\n tiers?: AccessPassTier[];\n /** Rate per hour in USD (if custom duration pricing) */\n ratePerHour?: string;\n /** Pass issuer identifier */\n issuer?: string;\n}\n\n/**\n * JWT claims inside an access pass token\n */\nexport interface AccessPassClaims {\n /** Subject — always 'x402-access-pass' */\n sub: string;\n /** Tier ID or 'custom' */\n tier: string;\n /** Duration in seconds */\n duration: number;\n /** Issued at (unix seconds) */\n iat: number;\n /** Expires at (unix seconds) */\n exp: number;\n /** Payer wallet address */\n payer: string;\n /** Network used for payment */\n network: string;\n /** Issuer identifier */\n iss: string;\n}\n\n/**\n * Client-side access pass configuration\n */\nexport interface AccessPassClientConfig {\n /** Enable access pass mode (default: true when this config is present) */\n enabled?: boolean;\n /** Preferred tier ID (e.g., '1h') — pick this tier if available */\n preferTier?: string;\n /** Preferred custom duration in seconds (e.g., 3600) */\n preferDuration?: number;\n /** Maximum amount willing to spend in USD (e.g., '2.00') */\n maxSpend?: string;\n /** Auto-renew expired passes (default: true) */\n autoRenew?: boolean;\n}\n\n// ============================================================================\n// Error Types\n// ============================================================================\n\n/**\n * SDK error codes\n */\nexport type X402ErrorCode =\n // Client errors\n | 'missing_payment_required_header'\n | 'invalid_payment_required'\n | 'unsupported_network'\n | 'no_matching_payment_option'\n | 'no_solana_accept' // Legacy, kept for compatibility\n | 'missing_fee_payer'\n | 'missing_decimals'\n | 'missing_amount'\n | 'amount_exceeds_max'\n | 'insufficient_balance'\n | 'wallet_missing_sign_transaction'\n | 'wallet_not_connected'\n | 'wallet_disconnected'\n | 'user_rejected_signature'\n | 'transaction_build_failed'\n | 'payment_rejected'\n | 'rpc_timeout'\n | 'facilitator_timeout'\n // Server errors\n | 'invalid_payment_signature'\n | 'facilitator_verify_failed'\n | 'facilitator_settle_failed'\n | 'facilitator_request_failed'\n | 'no_matching_requirement'\n // Access pass errors\n | 'access_pass_expired'\n | 'access_pass_invalid'\n | 'access_pass_tier_not_found'\n | 'access_pass_exceeds_max_spend';\n\n/**\n * Custom error class for x402 operations\n */\nexport class X402Error extends Error {\n /** Error code for programmatic handling */\n code: X402ErrorCode;\n /** Additional error details */\n details?: unknown;\n\n constructor(code: X402ErrorCode, message: string, details?: unknown) {\n super(message);\n this.name = 'X402Error';\n this.code = code;\n this.details = details;\n // Maintain proper prototype chain\n Object.setPrototypeOf(this, X402Error.prototype);\n }\n}\n","/**\n * Utility Functions\n *\n * Chain-agnostic helpers for x402 payments.\n */\n\nimport { SOLANA_MAINNET_NETWORK, BASE_MAINNET_NETWORK } from './types';\n\n// ============================================================================\n// Amount Conversion\n// ============================================================================\n\n/**\n * Convert human-readable amount to atomic units\n *\n * @param amount - Human-readable amount (e.g., 0.05 for $0.05)\n * @param decimals - Token decimals (e.g., 6 for USDC)\n * @returns Amount in atomic units as string\n *\n * @example\n * ```typescript\n * toAtomicUnits(0.05, 6) // '50000'\n * toAtomicUnits(1.50, 6) // '1500000'\n * ```\n */\nexport function toAtomicUnits(amount: number, decimals: number): string {\n const multiplier = Math.pow(10, decimals);\n return Math.floor(amount * multiplier).toString();\n}\n\n/**\n * Convert atomic units to human-readable amount\n *\n * @param atomicUnits - Amount in smallest units\n * @param decimals - Token decimals\n * @returns Human-readable amount\n *\n * @example\n * ```typescript\n * fromAtomicUnits('50000', 6) // 0.05\n * fromAtomicUnits(1500000n, 6) // 1.5\n * ```\n */\nexport function fromAtomicUnits(\n atomicUnits: string | bigint | number,\n decimals: number\n): number {\n const divisor = Math.pow(10, decimals);\n return Number(atomicUnits) / divisor;\n}\n\n// ============================================================================\n// Network Helpers\n// ============================================================================\n\n/**\n * Network type\n */\nexport type ChainFamily = 'solana' | 'evm' | 'unknown';\n\n/** Check if a CAIP-2 network identifier is a Solana network */\nexport function isSolanaNetwork(network: string): boolean {\n return network.startsWith('solana:') || network === 'solana';\n}\n\n/** Check if a CAIP-2 network identifier is an EVM network */\nexport function isEvmNetwork(network: string): boolean {\n return network.startsWith('eip155:') || ['base', 'ethereum', 'arbitrum'].includes(network);\n}\n\n/**\n * Get the chain family from a CAIP-2 network identifier\n *\n * @param network - CAIP-2 network identifier\n * @returns Chain family\n *\n * @example\n * ```typescript\n * getChainFamily('solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp') // 'solana'\n * getChainFamily('eip155:8453') // 'evm'\n * ```\n */\nexport function getChainFamily(network: string): ChainFamily {\n if (isSolanaNetwork(network)) return 'solana';\n if (isEvmNetwork(network)) return 'evm';\n return 'unknown';\n}\n\n/**\n * Get default RPC URL for a network\n *\n * @param network - CAIP-2 network identifier\n * @returns Default RPC URL\n */\nexport function getDefaultRpcUrl(network: string): string {\n const family = getChainFamily(network);\n\n if (family === 'solana') {\n if (network.includes('devnet') || network === 'solana:EtWTRABZaYq6iMfeYKouRu166VU2xqa1') {\n return 'https://api.devnet.solana.com';\n }\n if (network.includes('testnet') || network === 'solana:4uhcVJyU9pJkvQyS88uRDiswHXSCkY3z') {\n return 'https://api.testnet.solana.com';\n }\n // Mainnet uses Dexter's RPC proxy\n return 'https://api.dexter.cash/api/solana/rpc';\n }\n\n if (family === 'evm') {\n // Extract chain ID from CAIP-2\n if (network.startsWith('eip155:')) {\n const chainId = network.split(':')[1];\n switch (chainId) {\n case '8453': return 'https://api.dexter.cash/api/base/rpc'; // Dexter proxy\n case '84532': return 'https://sepolia.base.org';\n case '1': return 'https://eth.llamarpc.com';\n case '42161': return 'https://arb1.arbitrum.io/rpc';\n default: return 'https://api.dexter.cash/api/base/rpc';\n }\n }\n // Legacy names\n if (network === 'base') return 'https://api.dexter.cash/api/base/rpc';\n if (network === 'ethereum') return 'https://eth.llamarpc.com';\n if (network === 'arbitrum') return 'https://arb1.arbitrum.io/rpc';\n return 'https://api.dexter.cash/api/base/rpc';\n }\n\n // Unknown - return Dexter's Solana proxy\n return 'https://api.dexter.cash/api/solana/rpc';\n}\n\n/**\n * Get human-readable chain name\n *\n * @param network - CAIP-2 network identifier\n * @returns Human-readable name\n */\nexport function getChainName(network: string): string {\n const mapping: Record<string, string> = {\n [SOLANA_MAINNET_NETWORK]: 'Solana',\n 'solana:EtWTRABZaYq6iMfeYKouRu166VU2xqa1': 'Solana Devnet',\n 'solana:4uhcVJyU9pJkvQyS88uRDiswHXSCkY3z': 'Solana Testnet',\n 'solana': 'Solana',\n [BASE_MAINNET_NETWORK]: 'Base',\n 'eip155:84532': 'Base Sepolia',\n 'eip155:1': 'Ethereum',\n 'eip155:42161': 'Arbitrum One',\n 'base': 'Base',\n 'ethereum': 'Ethereum',\n 'arbitrum': 'Arbitrum',\n };\n return mapping[network] || network;\n}\n\n// ============================================================================\n// Transaction URL Helpers\n// ============================================================================\n\n/**\n * Get explorer URL for a transaction\n *\n * @param txSignature - Transaction signature/hash\n * @param network - CAIP-2 network identifier\n * @returns Explorer URL\n */\nexport function getExplorerUrl(txSignature: string, network: string): string {\n const family = getChainFamily(network);\n\n if (family === 'solana') {\n const isDevnet = network.includes('devnet') || network === 'solana:EtWTRABZaYq6iMfeYKouRu166VU2xqa1';\n if (isDevnet) {\n return `https://solscan.io/tx/${txSignature}?cluster=devnet`;\n }\n // Prefer Orb Markets for mainnet\n return `https://www.orbmarkets.io/tx/${txSignature}`;\n }\n\n if (family === 'evm') {\n // Extract chain ID\n let chainId = '8453'; // Default to Base\n if (network.startsWith('eip155:')) {\n chainId = network.split(':')[1];\n } else if (network === 'ethereum') {\n chainId = '1';\n } else if (network === 'arbitrum') {\n chainId = '42161';\n }\n\n switch (chainId) {\n case '8453': return `https://basescan.org/tx/${txSignature}`;\n case '84532': return `https://sepolia.basescan.org/tx/${txSignature}`;\n case '1': return `https://etherscan.io/tx/${txSignature}`;\n case '42161': return `https://arbiscan.io/tx/${txSignature}`;\n default: return `https://basescan.org/tx/${txSignature}`;\n }\n }\n\n return `https://solscan.io/tx/${txSignature}`;\n}\n\n// ============================================================================\n// Encoding Helpers\n// ============================================================================\n\n/**\n * Unicode-safe base64 encode a string.\n * Works in both Node.js and browsers, handling characters above U+00FF\n * that would cause btoa() to throw InvalidCharacterError.\n */\nfunction safeBase64Encode(str: string): string {\n if (typeof Buffer !== 'undefined') {\n return Buffer.from(str, 'utf-8').toString('base64');\n }\n // Browser fallback: encode UTF-8 bytes via TextEncoder\n const bytes = new TextEncoder().encode(str);\n let binary = '';\n for (let i = 0; i < bytes.length; i++) {\n binary += String.fromCharCode(bytes[i]);\n }\n return btoa(binary);\n}\n\n/**\n * Unicode-safe base64 decode a string.\n * Works in both Node.js and browsers.\n */\nfunction safeBase64Decode(encoded: string): string {\n if (typeof Buffer !== 'undefined') {\n return Buffer.from(encoded, 'base64').toString('utf-8');\n }\n // Browser fallback: decode via atob then UTF-8\n const binary = atob(encoded);\n const bytes = new Uint8Array(binary.length);\n for (let i = 0; i < binary.length; i++) {\n bytes[i] = binary.charCodeAt(i);\n }\n return new TextDecoder().decode(bytes);\n}\n\n/**\n * Encode an object as base64 JSON (Unicode-safe)\n */\nexport function encodeBase64Json(obj: unknown): string {\n return safeBase64Encode(JSON.stringify(obj));\n}\n\n/**\n * Decode base64 JSON to object (Unicode-safe)\n */\nexport function decodeBase64Json<T>(encoded: string): T {\n return JSON.parse(safeBase64Decode(encoded)) as T;\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;ACYO,IAAM,yBAAyB;AAG/B,IAAM,uBAAuB;;;ACU7B,SAAS,cAAc,QAAgB,UAA0B;AACtE,QAAM,aAAa,KAAK,IAAI,IAAI,QAAQ;AACxC,SAAO,KAAK,MAAM,SAAS,UAAU,EAAE,SAAS;AAClD;AAeO,SAAS,gBACd,aACA,UACQ;AACR,QAAM,UAAU,KAAK,IAAI,IAAI,QAAQ;AACrC,SAAO,OAAO,WAAW,IAAI;AAC/B;AAYO,SAAS,gBAAgB,SAA0B;AACxD,SAAO,QAAQ,WAAW,SAAS,KAAK,YAAY;AACtD;AAGO,SAAS,aAAa,SAA0B;AACrD,SAAO,QAAQ,WAAW,SAAS,KAAK,CAAC,QAAQ,YAAY,UAAU,EAAE,SAAS,OAAO;AAC3F;AAcO,SAAS,eAAe,SAA8B;AAC3D,MAAI,gBAAgB,OAAO,EAAG,QAAO;AACrC,MAAI,aAAa,OAAO,EAAG,QAAO;AAClC,SAAO;AACT;AAmDO,SAAS,aAAa,SAAyB;AACpD,QAAM,UAAkC;AAAA,IACtC,CAAC,sBAAsB,GAAG;AAAA,IAC1B,2CAA2C;AAAA,IAC3C,2CAA2C;AAAA,IAC3C,UAAU;AAAA,IACV,CAAC,oBAAoB,GAAG;AAAA,IACxB,gBAAgB;AAAA,IAChB,YAAY;AAAA,IACZ,gBAAgB;AAAA,IAChB,QAAQ;AAAA,IACR,YAAY;AAAA,IACZ,YAAY;AAAA,EACd;AACA,SAAO,QAAQ,OAAO,KAAK;AAC7B;AAaO,SAAS,eAAe,aAAqB,SAAyB;AAC3E,QAAM,SAAS,eAAe,OAAO;AAErC,MAAI,WAAW,UAAU;AACvB,UAAM,WAAW,QAAQ,SAAS,QAAQ,KAAK,YAAY;AAC3D,QAAI,UAAU;AACZ,aAAO,yBAAyB,WAAW;AAAA,IAC7C;AAEA,WAAO,gCAAgC,WAAW;AAAA,EACpD;AAEA,MAAI,WAAW,OAAO;AAEpB,QAAI,UAAU;AACd,QAAI,QAAQ,WAAW,SAAS,GAAG;AACjC,gBAAU,QAAQ,MAAM,GAAG,EAAE,CAAC;AAAA,IAChC,WAAW,YAAY,YAAY;AACjC,gBAAU;AAAA,IACZ,WAAW,YAAY,YAAY;AACjC,gBAAU;AAAA,IACZ;AAEA,YAAQ,SAAS;AAAA,MACf,KAAK;AAAQ,eAAO,2BAA2B,WAAW;AAAA,MAC1D,KAAK;AAAS,eAAO,mCAAmC,WAAW;AAAA,MACnE,KAAK;AAAK,eAAO,2BAA2B,WAAW;AAAA,MACvD,KAAK;AAAS,eAAO,0BAA0B,WAAW;AAAA,MAC1D;AAAS,eAAO,2BAA2B,WAAW;AAAA,IACxD;AAAA,EACF;AAEA,SAAO,yBAAyB,WAAW;AAC7C;","names":[]}
|
package/dist/utils/index.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/types.ts","../../src/utils.ts"],"sourcesContent":["/**\n * x402 v2 SDK — Shared Types\n *\n * Chain-agnostic types for x402 v2 payments.\n * Works with Solana, Base, and any future x402-compatible networks.\n */\n\n// ============================================================================\n// Network Constants\n// ============================================================================\n\n/** CAIP-2 network identifier for Solana mainnet */\nexport const SOLANA_MAINNET_NETWORK = 'solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp';\n\n/** CAIP-2 network identifier for Base mainnet */\nexport const BASE_MAINNET_NETWORK = 'eip155:8453';\n\n/** Alias for Solana mainnet */\nexport const SOLANA_MAINNET = SOLANA_MAINNET_NETWORK;\n\n/** Alias for Base mainnet */\nexport const BASE_MAINNET = BASE_MAINNET_NETWORK;\n\n// ============================================================================\n// Asset Constants\n// ============================================================================\n\n/** USDC mint on Solana mainnet */\nexport const USDC_MINT = 'EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v';\n\n/** USDC address on Base mainnet */\nexport const USDC_BASE = '0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913';\n\n// ============================================================================\n// Facilitator Constants\n// ============================================================================\n\n/** Dexter's public x402 v2 facilitator URL */\nexport const DEXTER_FACILITATOR_URL = 'https://x402.dexter.cash';\n\n// ============================================================================\n// PayTo Provider Types (for dynamic address resolution, e.g. Stripe)\n// ============================================================================\n\n/**\n * Context passed to a PayToProvider function.\n * Contains request-scoped information for dynamic address resolution.\n */\nexport interface PayToContext {\n /** The PAYMENT-SIGNATURE header value (present on retry/verify, undefined on initial 402) */\n paymentHeader?: string;\n /** Amount in atomic units (e.g., '10000' for 0.01 USDC) */\n amountAtomic?: string;\n /** The resource URL being accessed */\n resourceUrl?: string;\n}\n\n/**\n * Optional defaults a PayToProvider can advertise for auto-configuration.\n * Attached as `_x402Defaults` on the provider function.\n */\nexport interface PayToProviderDefaults {\n /** Default CAIP-2 network (e.g., 'eip155:8453' for Base) */\n network?: string;\n /** Default facilitator URL */\n facilitatorUrl?: string;\n}\n\n/**\n * A function that dynamically resolves a payment address.\n * Used for providers like Stripe that generate per-request deposit addresses.\n *\n * @example\n * ```typescript\n * import { stripePayTo } from '@dexterai/x402/server';\n *\n * const provider = stripePayTo(process.env.STRIPE_SECRET_KEY);\n * const address = await provider({ amountAtomic: '10000' });\n * ```\n */\nexport type PayToProvider = ((context: PayToContext) => Promise<string>) & {\n /** Auto-configuration defaults (set by provider factories like stripePayTo) */\n _x402Defaults?: PayToProviderDefaults;\n};\n\n// ============================================================================\n// Payment Types\n// ============================================================================\n\n/**\n * Asset configuration for payments\n */\nexport interface AssetConfig {\n /** Token address (mint on Solana, contract on EVM) */\n address: string;\n /** Token decimals */\n decimals: number;\n /** Optional: Human-readable symbol */\n symbol?: string;\n}\n\n/**\n * Resource info included in payment requirements\n */\nexport interface ResourceInfo {\n /** Resource URL */\n url: string;\n /** Human-readable description */\n description?: string;\n /** MIME type of the resource */\n mimeType?: string;\n}\n\n/**\n * Extra fields in payment requirements\n * Chain-specific fields may vary\n */\nexport interface AcceptsExtra {\n /** Facilitator address that pays tx fees (required for Solana) */\n feePayer?: string;\n /** Token decimals (optional - defaults to 6 for USDC) */\n decimals?: number;\n /** EIP-712: Token name (EVM only) */\n name?: string;\n /** EIP-712: Token version (EVM only) */\n version?: string;\n /** Additional chain-specific fields */\n [key: string]: unknown;\n}\n\n/**\n * A single payment option in the accepts array\n */\nexport interface PaymentAccept {\n /** x402 version (1 or 2, defaults to 2 if not specified) */\n x402Version?: 1 | 2;\n /** Payment scheme (always 'exact' for x402 v2) */\n scheme: 'exact';\n /** CAIP-2 network identifier (v1: 'solana', v2: 'solana:5eykt...') */\n network: string;\n /** Payment amount in atomic units (x402 v2 spec field) */\n amount: string;\n /** @deprecated v1 field — use `amount` instead. Kept for backwards compatibility with v1 data. */\n maxAmountRequired?: string;\n /** Token address */\n asset: string;\n /** Seller's address to receive payment */\n payTo: string;\n /** Maximum seconds until payment expires */\n maxTimeoutSeconds: number;\n /** Chain-specific extra data */\n extra?: AcceptsExtra;\n}\n\n/**\n * Full PaymentRequired structure (sent in PAYMENT-REQUIRED header)\n */\nexport interface PaymentRequired {\n /** x402 version (always 2) */\n x402Version: 2;\n /** Resource being accessed */\n resource: ResourceInfo;\n /** Available payment options */\n accepts: PaymentAccept[];\n /** Optional error message */\n error?: string;\n /** Protocol extensions */\n extensions?: Record<string, unknown>;\n}\n\n/**\n * PaymentSignature structure (sent in PAYMENT-SIGNATURE header)\n */\nexport interface PaymentSignature {\n /** x402 version (always 2) */\n x402Version: 2;\n /** Resource being accessed */\n resource: ResourceInfo;\n /** The payment option that was accepted */\n accepted: PaymentAccept;\n /** The signed payment */\n payload: {\n /** Signed transaction (base64 for Solana, JSON for EVM) */\n transaction: string;\n };\n /** Protocol extensions */\n extensions?: Record<string, unknown>;\n}\n\n// ============================================================================\n// Facilitator Response Types\n// ============================================================================\n\n/**\n * Response from /verify endpoint\n */\nexport interface VerifyResponse {\n /** Whether the payment is valid */\n isValid: boolean;\n /** Reason for invalidity (if invalid) */\n invalidReason?: string;\n /** Payer address */\n payer?: string;\n}\n\n/**\n * Response from /settle endpoint\n */\nexport interface SettleResponse {\n /** Whether settlement succeeded */\n success: boolean;\n /** Transaction signature/hash */\n transaction?: string;\n /** Network the payment was made on */\n network: string;\n /** Error reason (if failed) */\n errorReason?: string;\n /** Error code (if failed) */\n errorCode?: string;\n /** Payer address */\n payer?: string;\n /** Protocol extensions returned by the facilitator (e.g., sponsored-access recommendations) */\n extensions?: Record<string, unknown>;\n}\n\n// ============================================================================\n// Access Pass Types\n// ============================================================================\n\n/**\n * A single access pass tier offered by a seller\n */\nexport interface AccessPassTier {\n /** Tier ID (e.g., '1h', '24h') */\n id: string;\n /** Human-readable label (e.g., '1 hour') */\n label: string;\n /** Duration in seconds */\n seconds: number;\n /** Price in USD (e.g., '0.50') */\n price: string;\n /** Price in atomic units (e.g., '500000') */\n priceAtomic: string;\n}\n\n/**\n * Access pass info returned in X-ACCESS-PASS-TIERS header\n */\nexport interface AccessPassInfo {\n /** Available tiers (if tier-based pricing) */\n tiers?: AccessPassTier[];\n /** Rate per hour in USD (if custom duration pricing) */\n ratePerHour?: string;\n /** Pass issuer identifier */\n issuer?: string;\n}\n\n/**\n * JWT claims inside an access pass token\n */\nexport interface AccessPassClaims {\n /** Subject — always 'x402-access-pass' */\n sub: string;\n /** Tier ID or 'custom' */\n tier: string;\n /** Duration in seconds */\n duration: number;\n /** Issued at (unix seconds) */\n iat: number;\n /** Expires at (unix seconds) */\n exp: number;\n /** Payer wallet address */\n payer: string;\n /** Network used for payment */\n network: string;\n /** Issuer identifier */\n iss: string;\n}\n\n/**\n * Client-side access pass configuration\n */\nexport interface AccessPassClientConfig {\n /** Enable access pass mode (default: true when this config is present) */\n enabled?: boolean;\n /** Preferred tier ID (e.g., '1h') — pick this tier if available */\n preferTier?: string;\n /** Preferred custom duration in seconds (e.g., 3600) */\n preferDuration?: number;\n /** Maximum amount willing to spend in USD (e.g., '2.00') */\n maxSpend?: string;\n /** Auto-renew expired passes (default: true) */\n autoRenew?: boolean;\n}\n\n// ============================================================================\n// Error Types\n// ============================================================================\n\n/**\n * SDK error codes\n */\nexport type X402ErrorCode =\n // Client errors\n | 'missing_payment_required_header'\n | 'invalid_payment_required'\n | 'unsupported_network'\n | 'no_matching_payment_option'\n | 'no_solana_accept' // Legacy, kept for compatibility\n | 'missing_fee_payer'\n | 'missing_decimals'\n | 'missing_amount'\n | 'amount_exceeds_max'\n | 'insufficient_balance'\n | 'wallet_missing_sign_transaction'\n | 'wallet_not_connected'\n | 'wallet_disconnected'\n | 'user_rejected_signature'\n | 'transaction_build_failed'\n | 'payment_rejected'\n | 'rpc_timeout'\n | 'facilitator_timeout'\n // Server errors\n | 'invalid_payment_signature'\n | 'facilitator_verify_failed'\n | 'facilitator_settle_failed'\n | 'facilitator_request_failed'\n | 'no_matching_requirement'\n // Access pass errors\n | 'access_pass_expired'\n | 'access_pass_invalid'\n | 'access_pass_tier_not_found'\n | 'access_pass_exceeds_max_spend';\n\n/**\n * Custom error class for x402 operations\n */\nexport class X402Error extends Error {\n /** Error code for programmatic handling */\n code: X402ErrorCode;\n /** Additional error details */\n details?: unknown;\n\n constructor(code: X402ErrorCode, message: string, details?: unknown) {\n super(message);\n this.name = 'X402Error';\n this.code = code;\n this.details = details;\n // Maintain proper prototype chain\n Object.setPrototypeOf(this, X402Error.prototype);\n }\n}\n","/**\n * Utility Functions\n *\n * Chain-agnostic helpers for x402 payments.\n */\n\nimport { SOLANA_MAINNET_NETWORK, BASE_MAINNET_NETWORK } from './types';\n\n// ============================================================================\n// Amount Conversion\n// ============================================================================\n\n/**\n * Convert human-readable amount to atomic units\n *\n * @param amount - Human-readable amount (e.g., 0.05 for $0.05)\n * @param decimals - Token decimals (e.g., 6 for USDC)\n * @returns Amount in atomic units as string\n *\n * @example\n * ```typescript\n * toAtomicUnits(0.05, 6) // '50000'\n * toAtomicUnits(1.50, 6) // '1500000'\n * ```\n */\nexport function toAtomicUnits(amount: number, decimals: number): string {\n const multiplier = Math.pow(10, decimals);\n return Math.floor(amount * multiplier).toString();\n}\n\n/**\n * Convert atomic units to human-readable amount\n *\n * @param atomicUnits - Amount in smallest units\n * @param decimals - Token decimals\n * @returns Human-readable amount\n *\n * @example\n * ```typescript\n * fromAtomicUnits('50000', 6) // 0.05\n * fromAtomicUnits(1500000n, 6) // 1.5\n * ```\n */\nexport function fromAtomicUnits(\n atomicUnits: string | bigint | number,\n decimals: number\n): number {\n const divisor = Math.pow(10, decimals);\n return Number(atomicUnits) / divisor;\n}\n\n// ============================================================================\n// Network Helpers\n// ============================================================================\n\n/**\n * Network type\n */\nexport type ChainFamily = 'solana' | 'evm' | 'unknown';\n\n/** Check if a CAIP-2 network identifier is a Solana network */\nexport function isSolanaNetwork(network: string): boolean {\n return network.startsWith('solana:') || network === 'solana';\n}\n\n/** Check if a CAIP-2 network identifier is an EVM network */\nexport function isEvmNetwork(network: string): boolean {\n return network.startsWith('eip155:') || ['base', 'ethereum', 'arbitrum'].includes(network);\n}\n\n/**\n * Get the chain family from a CAIP-2 network identifier\n *\n * @param network - CAIP-2 network identifier\n * @returns Chain family\n *\n * @example\n * ```typescript\n * getChainFamily('solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp') // 'solana'\n * getChainFamily('eip155:8453') // 'evm'\n * ```\n */\nexport function getChainFamily(network: string): ChainFamily {\n if (isSolanaNetwork(network)) return 'solana';\n if (isEvmNetwork(network)) return 'evm';\n return 'unknown';\n}\n\n/**\n * Get default RPC URL for a network\n *\n * @param network - CAIP-2 network identifier\n * @returns Default RPC URL\n */\nexport function getDefaultRpcUrl(network: string): string {\n const family = getChainFamily(network);\n\n if (family === 'solana') {\n if (network.includes('devnet') || network === 'solana:EtWTRABZaYq6iMfeYKouRu166VU2xqa1') {\n return 'https://api.devnet.solana.com';\n }\n if (network.includes('testnet') || network === 'solana:4uhcVJyU9pJkvQyS88uRDiswHXSCkY3z') {\n return 'https://api.testnet.solana.com';\n }\n // Mainnet uses Dexter's RPC proxy\n return 'https://api.dexter.cash/api/solana/rpc';\n }\n\n if (family === 'evm') {\n // Extract chain ID from CAIP-2\n if (network.startsWith('eip155:')) {\n const chainId = network.split(':')[1];\n switch (chainId) {\n case '8453': return 'https://api.dexter.cash/api/base/rpc'; // Dexter proxy\n case '84532': return 'https://sepolia.base.org';\n case '1': return 'https://eth.llamarpc.com';\n case '42161': return 'https://arb1.arbitrum.io/rpc';\n default: return 'https://api.dexter.cash/api/base/rpc';\n }\n }\n // Legacy names\n if (network === 'base') return 'https://api.dexter.cash/api/base/rpc';\n if (network === 'ethereum') return 'https://eth.llamarpc.com';\n if (network === 'arbitrum') return 'https://arb1.arbitrum.io/rpc';\n return 'https://api.dexter.cash/api/base/rpc';\n }\n\n // Unknown - return Dexter's Solana proxy\n return 'https://api.dexter.cash/api/solana/rpc';\n}\n\n/**\n * Get human-readable chain name\n *\n * @param network - CAIP-2 network identifier\n * @returns Human-readable name\n */\nexport function getChainName(network: string): string {\n const mapping: Record<string, string> = {\n [SOLANA_MAINNET_NETWORK]: 'Solana',\n 'solana:EtWTRABZaYq6iMfeYKouRu166VU2xqa1': 'Solana Devnet',\n 'solana:4uhcVJyU9pJkvQyS88uRDiswHXSCkY3z': 'Solana Testnet',\n 'solana': 'Solana',\n [BASE_MAINNET_NETWORK]: 'Base',\n 'eip155:84532': 'Base Sepolia',\n 'eip155:1': 'Ethereum',\n 'eip155:42161': 'Arbitrum One',\n 'base': 'Base',\n 'ethereum': 'Ethereum',\n 'arbitrum': 'Arbitrum',\n };\n return mapping[network] || network;\n}\n\n// ============================================================================\n// Transaction URL Helpers\n// ============================================================================\n\n/**\n * Get explorer URL for a transaction\n *\n * @param txSignature - Transaction signature/hash\n * @param network - CAIP-2 network identifier\n * @returns Explorer URL\n */\nexport function getExplorerUrl(txSignature: string, network: string): string {\n const family = getChainFamily(network);\n\n if (family === 'solana') {\n const isDevnet = network.includes('devnet') || network === 'solana:EtWTRABZaYq6iMfeYKouRu166VU2xqa1';\n if (isDevnet) {\n return `https://solscan.io/tx/${txSignature}?cluster=devnet`;\n }\n // Prefer Orb Markets for mainnet\n return `https://www.orbmarkets.io/tx/${txSignature}`;\n }\n\n if (family === 'evm') {\n // Extract chain ID\n let chainId = '8453'; // Default to Base\n if (network.startsWith('eip155:')) {\n chainId = network.split(':')[1];\n } else if (network === 'ethereum') {\n chainId = '1';\n } else if (network === 'arbitrum') {\n chainId = '42161';\n }\n\n switch (chainId) {\n case '8453': return `https://basescan.org/tx/${txSignature}`;\n case '84532': return `https://sepolia.basescan.org/tx/${txSignature}`;\n case '1': return `https://etherscan.io/tx/${txSignature}`;\n case '42161': return `https://arbiscan.io/tx/${txSignature}`;\n default: return `https://basescan.org/tx/${txSignature}`;\n }\n }\n\n return `https://solscan.io/tx/${txSignature}`;\n}\n\n// ============================================================================\n// Encoding Helpers\n// ============================================================================\n\n/**\n * Unicode-safe base64 encode a string.\n * Works in both Node.js and browsers, handling characters above U+00FF\n * that would cause btoa() to throw InvalidCharacterError.\n */\nfunction safeBase64Encode(str: string): string {\n if (typeof Buffer !== 'undefined') {\n return Buffer.from(str, 'utf-8').toString('base64');\n }\n // Browser fallback: encode UTF-8 bytes via TextEncoder\n const bytes = new TextEncoder().encode(str);\n let binary = '';\n for (let i = 0; i < bytes.length; i++) {\n binary += String.fromCharCode(bytes[i]);\n }\n return btoa(binary);\n}\n\n/**\n * Unicode-safe base64 decode a string.\n * Works in both Node.js and browsers.\n */\nfunction safeBase64Decode(encoded: string): string {\n if (typeof Buffer !== 'undefined') {\n return Buffer.from(encoded, 'base64').toString('utf-8');\n }\n // Browser fallback: decode via atob then UTF-8\n const binary = atob(encoded);\n const bytes = new Uint8Array(binary.length);\n for (let i = 0; i < binary.length; i++) {\n bytes[i] = binary.charCodeAt(i);\n }\n return new TextDecoder().decode(bytes);\n}\n\n/**\n * Encode an object as base64 JSON (Unicode-safe)\n */\nexport function encodeBase64Json(obj: unknown): string {\n return safeBase64Encode(JSON.stringify(obj));\n}\n\n/**\n * Decode base64 JSON to object (Unicode-safe)\n */\nexport function decodeBase64Json<T>(encoded: string): T {\n return JSON.parse(safeBase64Decode(encoded)) as T;\n}\n"],"mappings":";AAYO,IAAM,yBAAyB;AAG/B,IAAM,uBAAuB;;;ACU7B,SAAS,cAAc,QAAgB,UAA0B;AACtE,QAAM,aAAa,KAAK,IAAI,IAAI,QAAQ;AACxC,SAAO,KAAK,MAAM,SAAS,UAAU,EAAE,SAAS;AAClD;AAeO,SAAS,gBACd,aACA,UACQ;AACR,QAAM,UAAU,KAAK,IAAI,IAAI,QAAQ;AACrC,SAAO,OAAO,WAAW,IAAI;AAC/B;AAYO,SAAS,gBAAgB,SAA0B;AACxD,SAAO,QAAQ,WAAW,SAAS,KAAK,YAAY;AACtD;AAGO,SAAS,aAAa,SAA0B;AACrD,SAAO,QAAQ,WAAW,SAAS,KAAK,CAAC,QAAQ,YAAY,UAAU,EAAE,SAAS,OAAO;AAC3F;AAcO,SAAS,eAAe,SAA8B;AAC3D,MAAI,gBAAgB,OAAO,EAAG,QAAO;AACrC,MAAI,aAAa,OAAO,EAAG,QAAO;AAClC,SAAO;AACT;AAmDO,SAAS,aAAa,SAAyB;AACpD,QAAM,UAAkC;AAAA,IACtC,CAAC,sBAAsB,GAAG;AAAA,IAC1B,2CAA2C;AAAA,IAC3C,2CAA2C;AAAA,IAC3C,UAAU;AAAA,IACV,CAAC,oBAAoB,GAAG;AAAA,IACxB,gBAAgB;AAAA,IAChB,YAAY;AAAA,IACZ,gBAAgB;AAAA,IAChB,QAAQ;AAAA,IACR,YAAY;AAAA,IACZ,YAAY;AAAA,EACd;AACA,SAAO,QAAQ,OAAO,KAAK;AAC7B;AAaO,SAAS,eAAe,aAAqB,SAAyB;AAC3E,QAAM,SAAS,eAAe,OAAO;AAErC,MAAI,WAAW,UAAU;AACvB,UAAM,WAAW,QAAQ,SAAS,QAAQ,KAAK,YAAY;AAC3D,QAAI,UAAU;AACZ,aAAO,yBAAyB,WAAW;AAAA,IAC7C;AAEA,WAAO,gCAAgC,WAAW;AAAA,EACpD;AAEA,MAAI,WAAW,OAAO;AAEpB,QAAI,UAAU;AACd,QAAI,QAAQ,WAAW,SAAS,GAAG;AACjC,gBAAU,QAAQ,MAAM,GAAG,EAAE,CAAC;AAAA,IAChC,WAAW,YAAY,YAAY;AACjC,gBAAU;AAAA,IACZ,WAAW,YAAY,YAAY;AACjC,gBAAU;AAAA,IACZ;AAEA,YAAQ,SAAS;AAAA,MACf,KAAK;AAAQ,eAAO,2BAA2B,WAAW;AAAA,MAC1D,KAAK;AAAS,eAAO,mCAAmC,WAAW;AAAA,MACnE,KAAK;AAAK,eAAO,2BAA2B,WAAW;AAAA,MACvD,KAAK;AAAS,eAAO,0BAA0B,WAAW;AAAA,MAC1D;AAAS,eAAO,2BAA2B,WAAW;AAAA,IACxD;AAAA,EACF;AAEA,SAAO,yBAAyB,WAAW;AAC7C;","names":[]}
|