uvd-x402-sdk 2.2.2 → 2.4.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/dist/adapters/index.d.mts +1 -1
- package/dist/adapters/index.d.ts +1 -1
- package/dist/adapters/index.js +83 -5
- package/dist/adapters/index.js.map +1 -1
- package/dist/adapters/index.mjs +83 -5
- package/dist/adapters/index.mjs.map +1 -1
- package/dist/{index-OZTSi1rJ.d.ts → index-BYX9BU79.d.ts} +1 -1
- package/dist/{index-I60aHxwu.d.mts → index-BrFeSWKm.d.mts} +1 -1
- package/dist/{index-BG738nMY.d.mts → index-DR2vXt-c.d.mts} +2 -1
- package/dist/{index-BG738nMY.d.ts → index-DR2vXt-c.d.ts} +2 -1
- package/dist/index.d.mts +3 -3
- package/dist/index.d.ts +3 -3
- package/dist/index.js +247 -139
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +246 -140
- package/dist/index.mjs.map +1 -1
- package/dist/providers/evm/index.d.mts +1 -1
- package/dist/providers/evm/index.d.ts +1 -1
- package/dist/providers/evm/index.js +83 -5
- package/dist/providers/evm/index.js.map +1 -1
- package/dist/providers/evm/index.mjs +83 -5
- package/dist/providers/evm/index.mjs.map +1 -1
- package/dist/providers/near/index.d.mts +1 -1
- package/dist/providers/near/index.d.ts +1 -1
- package/dist/providers/near/index.js.map +1 -1
- package/dist/providers/near/index.mjs.map +1 -1
- package/dist/providers/solana/index.d.mts +1 -1
- package/dist/providers/solana/index.d.ts +1 -1
- package/dist/providers/solana/index.js +24 -5
- package/dist/providers/solana/index.js.map +1 -1
- package/dist/providers/solana/index.mjs +24 -5
- package/dist/providers/solana/index.mjs.map +1 -1
- package/dist/providers/stellar/index.d.mts +1 -1
- package/dist/providers/stellar/index.d.ts +1 -1
- package/dist/providers/stellar/index.js.map +1 -1
- package/dist/providers/stellar/index.mjs.map +1 -1
- package/dist/react/index.d.mts +3 -3
- package/dist/react/index.d.ts +3 -3
- package/dist/react/index.js +83 -5
- package/dist/react/index.js.map +1 -1
- package/dist/react/index.mjs +83 -5
- package/dist/react/index.mjs.map +1 -1
- package/dist/utils/index.d.mts +31 -2
- package/dist/utils/index.d.ts +31 -2
- package/dist/utils/index.js +125 -5
- package/dist/utils/index.js.map +1 -1
- package/dist/utils/index.mjs +124 -6
- package/dist/utils/index.mjs.map +1 -1
- package/package.json +2 -2
- package/src/adapters/wagmi.ts +4 -1
- package/src/chains/index.ts +23 -5
- package/src/client/X402Client.ts +4 -0
- package/src/index.ts +3 -0
- package/src/providers/evm/index.ts +4 -0
- package/src/types/index.ts +2 -1
- package/src/utils/index.ts +5 -0
- package/src/utils/validation.ts +151 -0
package/src/index.ts
CHANGED
|
@@ -32,6 +32,7 @@ import type {
|
|
|
32
32
|
} from '../../types';
|
|
33
33
|
import { X402Error } from '../../types';
|
|
34
34
|
import { getChainByName, getChainById, getTokenConfig } from '../../chains';
|
|
35
|
+
import { validateRecipient } from '../../utils';
|
|
35
36
|
|
|
36
37
|
/**
|
|
37
38
|
* Ethereum provider interface
|
|
@@ -278,6 +279,9 @@ export class EVMProvider implements WalletAdapter {
|
|
|
278
279
|
// Get recipient
|
|
279
280
|
const recipient = paymentInfo.recipients?.evm || paymentInfo.recipient;
|
|
280
281
|
|
|
282
|
+
// Validate recipient address - prevents empty/invalid addresses
|
|
283
|
+
validateRecipient(recipient, 'evm');
|
|
284
|
+
|
|
281
285
|
// Generate random nonce
|
|
282
286
|
const nonceBytes = new Uint8Array(32);
|
|
283
287
|
if (typeof window !== 'undefined' && window.crypto) {
|
package/src/types/index.ts
CHANGED
|
@@ -26,8 +26,9 @@ export type NetworkType = 'evm' | 'svm' | 'solana' | 'stellar' | 'near';
|
|
|
26
26
|
* - eurc: Euro Coin (Circle) - 6 decimals
|
|
27
27
|
* - ausd: Agora USD (Agora Finance) - 6 decimals
|
|
28
28
|
* - pyusd: PayPal USD (PayPal/Paxos) - 6 decimals
|
|
29
|
+
* - usdt: Tether USD (USDT0 omnichain via LayerZero) - 6 decimals
|
|
29
30
|
*/
|
|
30
|
-
export type TokenType = 'usdc' | 'eurc' | 'ausd' | 'pyusd';
|
|
31
|
+
export type TokenType = 'usdc' | 'eurc' | 'ausd' | 'pyusd' | 'usdt';
|
|
31
32
|
|
|
32
33
|
/**
|
|
33
34
|
* Token configuration for EIP-712 signing and transfers
|
package/src/utils/index.ts
CHANGED
|
@@ -0,0 +1,151 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* uvd-x402-sdk - Validation Utilities
|
|
3
|
+
*
|
|
4
|
+
* Functions for validating payment parameters to prevent
|
|
5
|
+
* invalid or empty values from being processed.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
import { X402Error } from '../types';
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* Regular expression for validating Ethereum addresses
|
|
12
|
+
*/
|
|
13
|
+
const ETH_ADDRESS_REGEX = /^0x[a-fA-F0-9]{40}$/;
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* Regular expression for validating Solana addresses (base58, 32-44 chars)
|
|
17
|
+
*/
|
|
18
|
+
const SOLANA_ADDRESS_REGEX = /^[1-9A-HJ-NP-Za-km-z]{32,44}$/;
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* Regular expression for validating Stellar addresses (G... format)
|
|
22
|
+
*/
|
|
23
|
+
const STELLAR_ADDRESS_REGEX = /^G[A-Z2-7]{55}$/;
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* Regular expression for validating NEAR addresses
|
|
27
|
+
*/
|
|
28
|
+
const NEAR_ADDRESS_REGEX = /^[a-z0-9._-]+$/;
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* Validate that a recipient address is present and valid
|
|
32
|
+
*
|
|
33
|
+
* This function ensures that:
|
|
34
|
+
* 1. The recipient is not null, undefined, or empty
|
|
35
|
+
* 2. The recipient is not just whitespace
|
|
36
|
+
* 3. For EVM, it's a valid checksummed or lowercase 0x address
|
|
37
|
+
*
|
|
38
|
+
* @param recipient - The recipient address to validate
|
|
39
|
+
* @param networkType - Optional network type for format validation
|
|
40
|
+
* @throws X402Error with code 'INVALID_RECIPIENT' if validation fails
|
|
41
|
+
*/
|
|
42
|
+
export function validateRecipient(
|
|
43
|
+
recipient: string | undefined | null,
|
|
44
|
+
networkType?: 'evm' | 'svm' | 'solana' | 'stellar' | 'near'
|
|
45
|
+
): asserts recipient is string {
|
|
46
|
+
// Check for null, undefined, or empty
|
|
47
|
+
if (!recipient) {
|
|
48
|
+
throw new X402Error(
|
|
49
|
+
'Recipient address is required. The payTo/recipient field cannot be empty. ' +
|
|
50
|
+
'Please provide a valid recipient address where payments should be sent.',
|
|
51
|
+
'INVALID_RECIPIENT'
|
|
52
|
+
);
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
// Check for whitespace-only
|
|
56
|
+
const trimmed = recipient.trim();
|
|
57
|
+
if (trimmed === '') {
|
|
58
|
+
throw new X402Error(
|
|
59
|
+
'Recipient address cannot be empty or whitespace. ' +
|
|
60
|
+
'Please provide a valid recipient address.',
|
|
61
|
+
'INVALID_RECIPIENT'
|
|
62
|
+
);
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
// Network-specific validation
|
|
66
|
+
if (networkType) {
|
|
67
|
+
switch (networkType) {
|
|
68
|
+
case 'evm':
|
|
69
|
+
if (!ETH_ADDRESS_REGEX.test(trimmed)) {
|
|
70
|
+
throw new X402Error(
|
|
71
|
+
`Invalid EVM recipient address: "${trimmed}". ` +
|
|
72
|
+
'Expected a 40-character hexadecimal address starting with 0x.',
|
|
73
|
+
'INVALID_RECIPIENT'
|
|
74
|
+
);
|
|
75
|
+
}
|
|
76
|
+
break;
|
|
77
|
+
|
|
78
|
+
case 'svm':
|
|
79
|
+
case 'solana':
|
|
80
|
+
if (!SOLANA_ADDRESS_REGEX.test(trimmed)) {
|
|
81
|
+
throw new X402Error(
|
|
82
|
+
`Invalid Solana recipient address: "${trimmed}". ` +
|
|
83
|
+
'Expected a base58-encoded public key (32-44 characters).',
|
|
84
|
+
'INVALID_RECIPIENT'
|
|
85
|
+
);
|
|
86
|
+
}
|
|
87
|
+
break;
|
|
88
|
+
|
|
89
|
+
case 'stellar':
|
|
90
|
+
if (!STELLAR_ADDRESS_REGEX.test(trimmed)) {
|
|
91
|
+
throw new X402Error(
|
|
92
|
+
`Invalid Stellar recipient address: "${trimmed}". ` +
|
|
93
|
+
'Expected a G-prefixed public key (56 characters).',
|
|
94
|
+
'INVALID_RECIPIENT'
|
|
95
|
+
);
|
|
96
|
+
}
|
|
97
|
+
break;
|
|
98
|
+
|
|
99
|
+
case 'near':
|
|
100
|
+
if (!NEAR_ADDRESS_REGEX.test(trimmed) || trimmed.length > 64) {
|
|
101
|
+
throw new X402Error(
|
|
102
|
+
`Invalid NEAR recipient address: "${trimmed}". ` +
|
|
103
|
+
'Expected a valid NEAR account ID.',
|
|
104
|
+
'INVALID_RECIPIENT'
|
|
105
|
+
);
|
|
106
|
+
}
|
|
107
|
+
break;
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
/**
|
|
113
|
+
* Validate payment amount
|
|
114
|
+
*
|
|
115
|
+
* Ensures the amount is a valid positive number string
|
|
116
|
+
*
|
|
117
|
+
* @param amount - The amount string to validate
|
|
118
|
+
* @throws X402Error with code 'INVALID_AMOUNT' if validation fails
|
|
119
|
+
*/
|
|
120
|
+
export function validateAmount(amount: string | undefined | null): asserts amount is string {
|
|
121
|
+
if (!amount) {
|
|
122
|
+
throw new X402Error(
|
|
123
|
+
'Payment amount is required.',
|
|
124
|
+
'INVALID_AMOUNT'
|
|
125
|
+
);
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
const trimmed = amount.trim();
|
|
129
|
+
if (trimmed === '') {
|
|
130
|
+
throw new X402Error(
|
|
131
|
+
'Payment amount cannot be empty.',
|
|
132
|
+
'INVALID_AMOUNT'
|
|
133
|
+
);
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
// Parse as number
|
|
137
|
+
const num = parseFloat(trimmed);
|
|
138
|
+
if (isNaN(num)) {
|
|
139
|
+
throw new X402Error(
|
|
140
|
+
`Invalid payment amount: "${trimmed}". Expected a valid number.`,
|
|
141
|
+
'INVALID_AMOUNT'
|
|
142
|
+
);
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
if (num <= 0) {
|
|
146
|
+
throw new X402Error(
|
|
147
|
+
`Payment amount must be positive. Got: ${trimmed}`,
|
|
148
|
+
'INVALID_AMOUNT'
|
|
149
|
+
);
|
|
150
|
+
}
|
|
151
|
+
}
|