@openfacilitator/sdk 0.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 +160 -0
- package/dist/index.d.mts +197 -0
- package/dist/index.d.ts +197 -0
- package/dist/index.js +285 -0
- package/dist/index.mjs +243 -0
- package/package.json +41 -0
package/README.md
ADDED
|
@@ -0,0 +1,160 @@
|
|
|
1
|
+
# @openfacilitator/sdk
|
|
2
|
+
|
|
3
|
+
TypeScript SDK for x402 payment facilitation. Works with OpenFacilitator or any x402-compatible facilitator.
|
|
4
|
+
|
|
5
|
+
## Installation
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
npm install @openfacilitator/sdk
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
## Quick Start
|
|
12
|
+
|
|
13
|
+
```typescript
|
|
14
|
+
import { OpenFacilitator } from '@openfacilitator/sdk';
|
|
15
|
+
|
|
16
|
+
// Use custom facilitator
|
|
17
|
+
const facilitator = new OpenFacilitator({
|
|
18
|
+
url: 'https://pay.yourdomain.com',
|
|
19
|
+
});
|
|
20
|
+
|
|
21
|
+
// Or use the default OpenFacilitator
|
|
22
|
+
import { createDefaultFacilitator } from '@openfacilitator/sdk';
|
|
23
|
+
const facilitator = createDefaultFacilitator();
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
## Usage
|
|
27
|
+
|
|
28
|
+
### Verify a Payment
|
|
29
|
+
|
|
30
|
+
```typescript
|
|
31
|
+
const result = await facilitator.verify({
|
|
32
|
+
x402Version: 1,
|
|
33
|
+
scheme: 'exact',
|
|
34
|
+
network: 'base',
|
|
35
|
+
payload: {
|
|
36
|
+
signature: '0x...',
|
|
37
|
+
authorization: {
|
|
38
|
+
from: '0x...',
|
|
39
|
+
to: '0x...',
|
|
40
|
+
amount: '1000000',
|
|
41
|
+
asset: '0x...',
|
|
42
|
+
},
|
|
43
|
+
},
|
|
44
|
+
});
|
|
45
|
+
|
|
46
|
+
if (result.valid) {
|
|
47
|
+
console.log('Payment is valid!');
|
|
48
|
+
} else {
|
|
49
|
+
console.error('Invalid payment:', result.error);
|
|
50
|
+
}
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
### Settle a Payment
|
|
54
|
+
|
|
55
|
+
```typescript
|
|
56
|
+
const result = await facilitator.settle({
|
|
57
|
+
x402Version: 1,
|
|
58
|
+
scheme: 'exact',
|
|
59
|
+
network: 'base',
|
|
60
|
+
payload: {
|
|
61
|
+
signature: '0x...',
|
|
62
|
+
authorization: {
|
|
63
|
+
from: '0x...',
|
|
64
|
+
to: '0x...',
|
|
65
|
+
amount: '1000000',
|
|
66
|
+
asset: '0x...',
|
|
67
|
+
},
|
|
68
|
+
},
|
|
69
|
+
});
|
|
70
|
+
|
|
71
|
+
if (result.success) {
|
|
72
|
+
console.log('Transaction hash:', result.transactionHash);
|
|
73
|
+
} else {
|
|
74
|
+
console.error('Settlement failed:', result.error);
|
|
75
|
+
}
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
### Get Supported Networks
|
|
79
|
+
|
|
80
|
+
```typescript
|
|
81
|
+
const supported = await facilitator.supported();
|
|
82
|
+
|
|
83
|
+
console.log('Supported networks:');
|
|
84
|
+
supported.kinds.forEach(kind => {
|
|
85
|
+
console.log(`- ${kind.network} (v${kind.x402Version})`);
|
|
86
|
+
});
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
### Network Utilities
|
|
90
|
+
|
|
91
|
+
```typescript
|
|
92
|
+
import {
|
|
93
|
+
getNetwork,
|
|
94
|
+
getNetworkType,
|
|
95
|
+
toV2NetworkId,
|
|
96
|
+
NETWORKS,
|
|
97
|
+
} from '@openfacilitator/sdk';
|
|
98
|
+
|
|
99
|
+
// Get network info
|
|
100
|
+
const base = getNetwork('base');
|
|
101
|
+
console.log(base?.chainId); // 8453
|
|
102
|
+
|
|
103
|
+
// Convert v1 to v2 ID
|
|
104
|
+
const v2Id = toV2NetworkId('base'); // 'eip155:8453'
|
|
105
|
+
|
|
106
|
+
// Get all mainnets
|
|
107
|
+
const mainnets = NETWORKS.filter(n => !n.testnet);
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
## Error Handling
|
|
111
|
+
|
|
112
|
+
```typescript
|
|
113
|
+
import {
|
|
114
|
+
FacilitatorError,
|
|
115
|
+
VerificationError,
|
|
116
|
+
SettlementError,
|
|
117
|
+
} from '@openfacilitator/sdk';
|
|
118
|
+
|
|
119
|
+
try {
|
|
120
|
+
await facilitator.settle(payment);
|
|
121
|
+
} catch (error) {
|
|
122
|
+
if (error instanceof SettlementError) {
|
|
123
|
+
console.error('Settlement failed:', error.message);
|
|
124
|
+
} else if (error instanceof FacilitatorError) {
|
|
125
|
+
console.error('Facilitator error:', error.code, error.message);
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
```
|
|
129
|
+
|
|
130
|
+
## x402 Version Support
|
|
131
|
+
|
|
132
|
+
This SDK supports both x402 v1 and v2:
|
|
133
|
+
|
|
134
|
+
- **v1**: Human-readable network names (`base`, `solana`)
|
|
135
|
+
- **v2**: CAIP-2 chain identifiers (`eip155:8453`, `solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp`)
|
|
136
|
+
|
|
137
|
+
## Supported Networks
|
|
138
|
+
|
|
139
|
+
### EVM Mainnets
|
|
140
|
+
|
|
141
|
+
| Network | v1 ID | v2 ID (CAIP-2) | Chain ID |
|
|
142
|
+
| --------- | ----------- | ---------------- | -------- |
|
|
143
|
+
| Base | `base` | `eip155:8453` | 8453 |
|
|
144
|
+
| Polygon | `polygon` | `eip155:137` | 137 |
|
|
145
|
+
| Avalanche | `avalanche` | `eip155:43114` | 43114 |
|
|
146
|
+
| Sei | `sei` | `eip155:1329` | 1329 |
|
|
147
|
+
| IoTeX | `iotex` | `eip155:4689` | 4689 |
|
|
148
|
+
| Peaq | `peaq` | `eip155:3338` | 3338 |
|
|
149
|
+
| X Layer | `xlayer` | `eip155:196` | 196 |
|
|
150
|
+
|
|
151
|
+
### Solana
|
|
152
|
+
|
|
153
|
+
| Network | v1 ID | v2 ID (CAIP-2) |
|
|
154
|
+
| ------------- | --------------- | ---------------------------------------- |
|
|
155
|
+
| Solana | `solana` | `solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp` |
|
|
156
|
+
| Solana Devnet | `solana-devnet` | `solana:EtWTRABZaYq6iMfeYKouRu166VU2xqa1` |
|
|
157
|
+
|
|
158
|
+
## License
|
|
159
|
+
|
|
160
|
+
MIT
|
package/dist/index.d.mts
ADDED
|
@@ -0,0 +1,197 @@
|
|
|
1
|
+
interface FacilitatorConfig {
|
|
2
|
+
/** Facilitator URL (e.g., https://pay.honeypot.game) */
|
|
3
|
+
url: string;
|
|
4
|
+
/** Optional timeout in ms (default: 30000) */
|
|
5
|
+
timeout?: number;
|
|
6
|
+
/** Optional custom headers */
|
|
7
|
+
headers?: Record<string, string>;
|
|
8
|
+
}
|
|
9
|
+
/**
|
|
10
|
+
* Payment payload for verification/settlement
|
|
11
|
+
* Supports both x402 v1 and v2 formats
|
|
12
|
+
*/
|
|
13
|
+
interface PaymentPayload {
|
|
14
|
+
/** x402 version (1 or 2) */
|
|
15
|
+
x402Version: 1 | 2;
|
|
16
|
+
/** Payment scheme (e.g., "exact") */
|
|
17
|
+
scheme: string;
|
|
18
|
+
/** Network identifier - v1: "base", v2: "eip155:8453" */
|
|
19
|
+
network: string;
|
|
20
|
+
/** Payment details */
|
|
21
|
+
payload: {
|
|
22
|
+
/** Signature of the payment */
|
|
23
|
+
signature: string;
|
|
24
|
+
/** Payment authorization */
|
|
25
|
+
authorization: PaymentAuthorization;
|
|
26
|
+
};
|
|
27
|
+
}
|
|
28
|
+
interface PaymentAuthorization {
|
|
29
|
+
/** Sender address */
|
|
30
|
+
from: string;
|
|
31
|
+
/** Recipient address */
|
|
32
|
+
to: string;
|
|
33
|
+
/** Amount in base units (string to handle large numbers) */
|
|
34
|
+
amount: string;
|
|
35
|
+
/** Token/asset address or identifier */
|
|
36
|
+
asset: string;
|
|
37
|
+
/** Chain ID (for EVM) */
|
|
38
|
+
chainId?: number;
|
|
39
|
+
/** Nonce */
|
|
40
|
+
nonce?: string;
|
|
41
|
+
/** Expiration timestamp */
|
|
42
|
+
validUntil?: number;
|
|
43
|
+
/** Additional fields for specific schemes */
|
|
44
|
+
[key: string]: unknown;
|
|
45
|
+
}
|
|
46
|
+
interface VerifyResponse {
|
|
47
|
+
/** Whether the payment is valid */
|
|
48
|
+
valid: boolean;
|
|
49
|
+
/** Error message if invalid */
|
|
50
|
+
error?: string;
|
|
51
|
+
/** Additional verification details */
|
|
52
|
+
details?: {
|
|
53
|
+
/** Verified amount */
|
|
54
|
+
amount?: string;
|
|
55
|
+
/** Verified recipient */
|
|
56
|
+
recipient?: string;
|
|
57
|
+
/** Payment scheme used */
|
|
58
|
+
scheme?: string;
|
|
59
|
+
};
|
|
60
|
+
}
|
|
61
|
+
interface SettleResponse {
|
|
62
|
+
/** Whether settlement was successful */
|
|
63
|
+
success: boolean;
|
|
64
|
+
/** Transaction hash/signature */
|
|
65
|
+
transactionHash?: string;
|
|
66
|
+
/** Network the transaction was settled on */
|
|
67
|
+
network?: string;
|
|
68
|
+
/** Error message if failed */
|
|
69
|
+
error?: string;
|
|
70
|
+
}
|
|
71
|
+
interface SupportedResponse {
|
|
72
|
+
/** Supported payment kinds */
|
|
73
|
+
kinds: PaymentKind[];
|
|
74
|
+
/** Signer addresses by network namespace */
|
|
75
|
+
signers?: Record<string, string[]>;
|
|
76
|
+
/** Supported extensions */
|
|
77
|
+
extensions?: string[];
|
|
78
|
+
}
|
|
79
|
+
interface PaymentKind {
|
|
80
|
+
/** x402 version */
|
|
81
|
+
x402Version: 1 | 2;
|
|
82
|
+
/** Payment scheme */
|
|
83
|
+
scheme: string;
|
|
84
|
+
/** Network identifier */
|
|
85
|
+
network: string;
|
|
86
|
+
/** Extra data (e.g., feePayer for Solana) */
|
|
87
|
+
extra?: {
|
|
88
|
+
feePayer?: string;
|
|
89
|
+
[key: string]: unknown;
|
|
90
|
+
};
|
|
91
|
+
}
|
|
92
|
+
type NetworkType = 'evm' | 'solana';
|
|
93
|
+
interface NetworkInfo {
|
|
94
|
+
/** v1 identifier (e.g., "base") */
|
|
95
|
+
v1Id: string;
|
|
96
|
+
/** v2 CAIP-2 identifier (e.g., "eip155:8453") */
|
|
97
|
+
v2Id: string;
|
|
98
|
+
/** Human-readable name */
|
|
99
|
+
name: string;
|
|
100
|
+
/** Network type */
|
|
101
|
+
type: NetworkType;
|
|
102
|
+
/** Chain ID (EVM only) */
|
|
103
|
+
chainId?: number;
|
|
104
|
+
/** Whether this is a testnet */
|
|
105
|
+
testnet: boolean;
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
declare class OpenFacilitator {
|
|
109
|
+
private readonly baseUrl;
|
|
110
|
+
private readonly timeout;
|
|
111
|
+
private readonly headers;
|
|
112
|
+
constructor(config: FacilitatorConfig);
|
|
113
|
+
/**
|
|
114
|
+
* Get the facilitator URL
|
|
115
|
+
*/
|
|
116
|
+
get url(): string;
|
|
117
|
+
/**
|
|
118
|
+
* Verify a payment is valid
|
|
119
|
+
*/
|
|
120
|
+
verify(payment: PaymentPayload): Promise<VerifyResponse>;
|
|
121
|
+
/**
|
|
122
|
+
* Settle/broadcast a payment transaction
|
|
123
|
+
*/
|
|
124
|
+
settle(payment: PaymentPayload): Promise<SettleResponse>;
|
|
125
|
+
/**
|
|
126
|
+
* Get supported networks and payment kinds
|
|
127
|
+
*/
|
|
128
|
+
supported(): Promise<SupportedResponse>;
|
|
129
|
+
/**
|
|
130
|
+
* Health check - verify facilitator is reachable
|
|
131
|
+
*/
|
|
132
|
+
health(): Promise<boolean>;
|
|
133
|
+
/**
|
|
134
|
+
* Internal request helper
|
|
135
|
+
*/
|
|
136
|
+
private request;
|
|
137
|
+
}
|
|
138
|
+
/**
|
|
139
|
+
* Create a facilitator client with default OpenFacilitator URL
|
|
140
|
+
*/
|
|
141
|
+
declare function createDefaultFacilitator(): OpenFacilitator;
|
|
142
|
+
|
|
143
|
+
declare class FacilitatorError extends Error {
|
|
144
|
+
code: string;
|
|
145
|
+
statusCode?: number | undefined;
|
|
146
|
+
details?: unknown | undefined;
|
|
147
|
+
constructor(message: string, code: string, statusCode?: number | undefined, details?: unknown | undefined);
|
|
148
|
+
}
|
|
149
|
+
declare class NetworkError extends FacilitatorError {
|
|
150
|
+
constructor(message: string, details?: unknown);
|
|
151
|
+
}
|
|
152
|
+
declare class VerificationError extends FacilitatorError {
|
|
153
|
+
constructor(message: string, details?: unknown);
|
|
154
|
+
}
|
|
155
|
+
declare class SettlementError extends FacilitatorError {
|
|
156
|
+
constructor(message: string, details?: unknown);
|
|
157
|
+
}
|
|
158
|
+
declare class ConfigurationError extends FacilitatorError {
|
|
159
|
+
constructor(message: string);
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
declare const NETWORKS: NetworkInfo[];
|
|
163
|
+
/**
|
|
164
|
+
* Get network info by v1 or v2 identifier
|
|
165
|
+
*/
|
|
166
|
+
declare function getNetwork(id: string): NetworkInfo | undefined;
|
|
167
|
+
/**
|
|
168
|
+
* Get network type from identifier
|
|
169
|
+
*/
|
|
170
|
+
declare function getNetworkType(id: string): 'evm' | 'solana' | undefined;
|
|
171
|
+
/**
|
|
172
|
+
* Convert v1 network ID to v2 (CAIP-2)
|
|
173
|
+
*/
|
|
174
|
+
declare function toV2NetworkId(id: string): string;
|
|
175
|
+
/**
|
|
176
|
+
* Convert v2 network ID to v1
|
|
177
|
+
*/
|
|
178
|
+
declare function toV1NetworkId(id: string): string;
|
|
179
|
+
/**
|
|
180
|
+
* Check if network ID is valid
|
|
181
|
+
*/
|
|
182
|
+
declare function isValidNetwork(id: string): boolean;
|
|
183
|
+
/**
|
|
184
|
+
* Get all mainnet networks
|
|
185
|
+
*/
|
|
186
|
+
declare function getMainnets(): NetworkInfo[];
|
|
187
|
+
/**
|
|
188
|
+
* Get all testnet networks
|
|
189
|
+
*/
|
|
190
|
+
declare function getTestnets(): NetworkInfo[];
|
|
191
|
+
|
|
192
|
+
/**
|
|
193
|
+
* Type guard for checking if value is a valid payment payload
|
|
194
|
+
*/
|
|
195
|
+
declare function isPaymentPayload(value: unknown): value is PaymentPayload;
|
|
196
|
+
|
|
197
|
+
export { ConfigurationError, type FacilitatorConfig, FacilitatorError, NETWORKS, NetworkError, type NetworkInfo, type NetworkType, OpenFacilitator, type PaymentAuthorization, type PaymentKind, type PaymentPayload, type SettleResponse, SettlementError, type SupportedResponse, VerificationError, type VerifyResponse, createDefaultFacilitator, getMainnets, getNetwork, getNetworkType, getTestnets, isPaymentPayload, isValidNetwork, toV1NetworkId, toV2NetworkId };
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,197 @@
|
|
|
1
|
+
interface FacilitatorConfig {
|
|
2
|
+
/** Facilitator URL (e.g., https://pay.honeypot.game) */
|
|
3
|
+
url: string;
|
|
4
|
+
/** Optional timeout in ms (default: 30000) */
|
|
5
|
+
timeout?: number;
|
|
6
|
+
/** Optional custom headers */
|
|
7
|
+
headers?: Record<string, string>;
|
|
8
|
+
}
|
|
9
|
+
/**
|
|
10
|
+
* Payment payload for verification/settlement
|
|
11
|
+
* Supports both x402 v1 and v2 formats
|
|
12
|
+
*/
|
|
13
|
+
interface PaymentPayload {
|
|
14
|
+
/** x402 version (1 or 2) */
|
|
15
|
+
x402Version: 1 | 2;
|
|
16
|
+
/** Payment scheme (e.g., "exact") */
|
|
17
|
+
scheme: string;
|
|
18
|
+
/** Network identifier - v1: "base", v2: "eip155:8453" */
|
|
19
|
+
network: string;
|
|
20
|
+
/** Payment details */
|
|
21
|
+
payload: {
|
|
22
|
+
/** Signature of the payment */
|
|
23
|
+
signature: string;
|
|
24
|
+
/** Payment authorization */
|
|
25
|
+
authorization: PaymentAuthorization;
|
|
26
|
+
};
|
|
27
|
+
}
|
|
28
|
+
interface PaymentAuthorization {
|
|
29
|
+
/** Sender address */
|
|
30
|
+
from: string;
|
|
31
|
+
/** Recipient address */
|
|
32
|
+
to: string;
|
|
33
|
+
/** Amount in base units (string to handle large numbers) */
|
|
34
|
+
amount: string;
|
|
35
|
+
/** Token/asset address or identifier */
|
|
36
|
+
asset: string;
|
|
37
|
+
/** Chain ID (for EVM) */
|
|
38
|
+
chainId?: number;
|
|
39
|
+
/** Nonce */
|
|
40
|
+
nonce?: string;
|
|
41
|
+
/** Expiration timestamp */
|
|
42
|
+
validUntil?: number;
|
|
43
|
+
/** Additional fields for specific schemes */
|
|
44
|
+
[key: string]: unknown;
|
|
45
|
+
}
|
|
46
|
+
interface VerifyResponse {
|
|
47
|
+
/** Whether the payment is valid */
|
|
48
|
+
valid: boolean;
|
|
49
|
+
/** Error message if invalid */
|
|
50
|
+
error?: string;
|
|
51
|
+
/** Additional verification details */
|
|
52
|
+
details?: {
|
|
53
|
+
/** Verified amount */
|
|
54
|
+
amount?: string;
|
|
55
|
+
/** Verified recipient */
|
|
56
|
+
recipient?: string;
|
|
57
|
+
/** Payment scheme used */
|
|
58
|
+
scheme?: string;
|
|
59
|
+
};
|
|
60
|
+
}
|
|
61
|
+
interface SettleResponse {
|
|
62
|
+
/** Whether settlement was successful */
|
|
63
|
+
success: boolean;
|
|
64
|
+
/** Transaction hash/signature */
|
|
65
|
+
transactionHash?: string;
|
|
66
|
+
/** Network the transaction was settled on */
|
|
67
|
+
network?: string;
|
|
68
|
+
/** Error message if failed */
|
|
69
|
+
error?: string;
|
|
70
|
+
}
|
|
71
|
+
interface SupportedResponse {
|
|
72
|
+
/** Supported payment kinds */
|
|
73
|
+
kinds: PaymentKind[];
|
|
74
|
+
/** Signer addresses by network namespace */
|
|
75
|
+
signers?: Record<string, string[]>;
|
|
76
|
+
/** Supported extensions */
|
|
77
|
+
extensions?: string[];
|
|
78
|
+
}
|
|
79
|
+
interface PaymentKind {
|
|
80
|
+
/** x402 version */
|
|
81
|
+
x402Version: 1 | 2;
|
|
82
|
+
/** Payment scheme */
|
|
83
|
+
scheme: string;
|
|
84
|
+
/** Network identifier */
|
|
85
|
+
network: string;
|
|
86
|
+
/** Extra data (e.g., feePayer for Solana) */
|
|
87
|
+
extra?: {
|
|
88
|
+
feePayer?: string;
|
|
89
|
+
[key: string]: unknown;
|
|
90
|
+
};
|
|
91
|
+
}
|
|
92
|
+
type NetworkType = 'evm' | 'solana';
|
|
93
|
+
interface NetworkInfo {
|
|
94
|
+
/** v1 identifier (e.g., "base") */
|
|
95
|
+
v1Id: string;
|
|
96
|
+
/** v2 CAIP-2 identifier (e.g., "eip155:8453") */
|
|
97
|
+
v2Id: string;
|
|
98
|
+
/** Human-readable name */
|
|
99
|
+
name: string;
|
|
100
|
+
/** Network type */
|
|
101
|
+
type: NetworkType;
|
|
102
|
+
/** Chain ID (EVM only) */
|
|
103
|
+
chainId?: number;
|
|
104
|
+
/** Whether this is a testnet */
|
|
105
|
+
testnet: boolean;
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
declare class OpenFacilitator {
|
|
109
|
+
private readonly baseUrl;
|
|
110
|
+
private readonly timeout;
|
|
111
|
+
private readonly headers;
|
|
112
|
+
constructor(config: FacilitatorConfig);
|
|
113
|
+
/**
|
|
114
|
+
* Get the facilitator URL
|
|
115
|
+
*/
|
|
116
|
+
get url(): string;
|
|
117
|
+
/**
|
|
118
|
+
* Verify a payment is valid
|
|
119
|
+
*/
|
|
120
|
+
verify(payment: PaymentPayload): Promise<VerifyResponse>;
|
|
121
|
+
/**
|
|
122
|
+
* Settle/broadcast a payment transaction
|
|
123
|
+
*/
|
|
124
|
+
settle(payment: PaymentPayload): Promise<SettleResponse>;
|
|
125
|
+
/**
|
|
126
|
+
* Get supported networks and payment kinds
|
|
127
|
+
*/
|
|
128
|
+
supported(): Promise<SupportedResponse>;
|
|
129
|
+
/**
|
|
130
|
+
* Health check - verify facilitator is reachable
|
|
131
|
+
*/
|
|
132
|
+
health(): Promise<boolean>;
|
|
133
|
+
/**
|
|
134
|
+
* Internal request helper
|
|
135
|
+
*/
|
|
136
|
+
private request;
|
|
137
|
+
}
|
|
138
|
+
/**
|
|
139
|
+
* Create a facilitator client with default OpenFacilitator URL
|
|
140
|
+
*/
|
|
141
|
+
declare function createDefaultFacilitator(): OpenFacilitator;
|
|
142
|
+
|
|
143
|
+
declare class FacilitatorError extends Error {
|
|
144
|
+
code: string;
|
|
145
|
+
statusCode?: number | undefined;
|
|
146
|
+
details?: unknown | undefined;
|
|
147
|
+
constructor(message: string, code: string, statusCode?: number | undefined, details?: unknown | undefined);
|
|
148
|
+
}
|
|
149
|
+
declare class NetworkError extends FacilitatorError {
|
|
150
|
+
constructor(message: string, details?: unknown);
|
|
151
|
+
}
|
|
152
|
+
declare class VerificationError extends FacilitatorError {
|
|
153
|
+
constructor(message: string, details?: unknown);
|
|
154
|
+
}
|
|
155
|
+
declare class SettlementError extends FacilitatorError {
|
|
156
|
+
constructor(message: string, details?: unknown);
|
|
157
|
+
}
|
|
158
|
+
declare class ConfigurationError extends FacilitatorError {
|
|
159
|
+
constructor(message: string);
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
declare const NETWORKS: NetworkInfo[];
|
|
163
|
+
/**
|
|
164
|
+
* Get network info by v1 or v2 identifier
|
|
165
|
+
*/
|
|
166
|
+
declare function getNetwork(id: string): NetworkInfo | undefined;
|
|
167
|
+
/**
|
|
168
|
+
* Get network type from identifier
|
|
169
|
+
*/
|
|
170
|
+
declare function getNetworkType(id: string): 'evm' | 'solana' | undefined;
|
|
171
|
+
/**
|
|
172
|
+
* Convert v1 network ID to v2 (CAIP-2)
|
|
173
|
+
*/
|
|
174
|
+
declare function toV2NetworkId(id: string): string;
|
|
175
|
+
/**
|
|
176
|
+
* Convert v2 network ID to v1
|
|
177
|
+
*/
|
|
178
|
+
declare function toV1NetworkId(id: string): string;
|
|
179
|
+
/**
|
|
180
|
+
* Check if network ID is valid
|
|
181
|
+
*/
|
|
182
|
+
declare function isValidNetwork(id: string): boolean;
|
|
183
|
+
/**
|
|
184
|
+
* Get all mainnet networks
|
|
185
|
+
*/
|
|
186
|
+
declare function getMainnets(): NetworkInfo[];
|
|
187
|
+
/**
|
|
188
|
+
* Get all testnet networks
|
|
189
|
+
*/
|
|
190
|
+
declare function getTestnets(): NetworkInfo[];
|
|
191
|
+
|
|
192
|
+
/**
|
|
193
|
+
* Type guard for checking if value is a valid payment payload
|
|
194
|
+
*/
|
|
195
|
+
declare function isPaymentPayload(value: unknown): value is PaymentPayload;
|
|
196
|
+
|
|
197
|
+
export { ConfigurationError, type FacilitatorConfig, FacilitatorError, NETWORKS, NetworkError, type NetworkInfo, type NetworkType, OpenFacilitator, type PaymentAuthorization, type PaymentKind, type PaymentPayload, type SettleResponse, SettlementError, type SupportedResponse, VerificationError, type VerifyResponse, createDefaultFacilitator, getMainnets, getNetwork, getNetworkType, getTestnets, isPaymentPayload, isValidNetwork, toV1NetworkId, toV2NetworkId };
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,285 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __export = (target, all) => {
|
|
7
|
+
for (var name in all)
|
|
8
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
9
|
+
};
|
|
10
|
+
var __copyProps = (to, from, except, desc) => {
|
|
11
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
12
|
+
for (let key of __getOwnPropNames(from))
|
|
13
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
14
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
15
|
+
}
|
|
16
|
+
return to;
|
|
17
|
+
};
|
|
18
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
|
+
|
|
20
|
+
// src/index.ts
|
|
21
|
+
var index_exports = {};
|
|
22
|
+
__export(index_exports, {
|
|
23
|
+
ConfigurationError: () => ConfigurationError,
|
|
24
|
+
FacilitatorError: () => FacilitatorError,
|
|
25
|
+
NETWORKS: () => NETWORKS,
|
|
26
|
+
NetworkError: () => NetworkError,
|
|
27
|
+
OpenFacilitator: () => OpenFacilitator,
|
|
28
|
+
SettlementError: () => SettlementError,
|
|
29
|
+
VerificationError: () => VerificationError,
|
|
30
|
+
createDefaultFacilitator: () => createDefaultFacilitator,
|
|
31
|
+
getMainnets: () => getMainnets,
|
|
32
|
+
getNetwork: () => getNetwork,
|
|
33
|
+
getNetworkType: () => getNetworkType,
|
|
34
|
+
getTestnets: () => getTestnets,
|
|
35
|
+
isPaymentPayload: () => isPaymentPayload,
|
|
36
|
+
isValidNetwork: () => isValidNetwork,
|
|
37
|
+
toV1NetworkId: () => toV1NetworkId,
|
|
38
|
+
toV2NetworkId: () => toV2NetworkId
|
|
39
|
+
});
|
|
40
|
+
module.exports = __toCommonJS(index_exports);
|
|
41
|
+
|
|
42
|
+
// src/errors.ts
|
|
43
|
+
var FacilitatorError = class extends Error {
|
|
44
|
+
constructor(message, code, statusCode, details) {
|
|
45
|
+
super(message);
|
|
46
|
+
this.code = code;
|
|
47
|
+
this.statusCode = statusCode;
|
|
48
|
+
this.details = details;
|
|
49
|
+
this.name = "FacilitatorError";
|
|
50
|
+
}
|
|
51
|
+
};
|
|
52
|
+
var NetworkError = class extends FacilitatorError {
|
|
53
|
+
constructor(message, details) {
|
|
54
|
+
super(message, "NETWORK_ERROR", void 0, details);
|
|
55
|
+
this.name = "NetworkError";
|
|
56
|
+
}
|
|
57
|
+
};
|
|
58
|
+
var VerificationError = class extends FacilitatorError {
|
|
59
|
+
constructor(message, details) {
|
|
60
|
+
super(message, "VERIFICATION_ERROR", void 0, details);
|
|
61
|
+
this.name = "VerificationError";
|
|
62
|
+
}
|
|
63
|
+
};
|
|
64
|
+
var SettlementError = class extends FacilitatorError {
|
|
65
|
+
constructor(message, details) {
|
|
66
|
+
super(message, "SETTLEMENT_ERROR", void 0, details);
|
|
67
|
+
this.name = "SettlementError";
|
|
68
|
+
}
|
|
69
|
+
};
|
|
70
|
+
var ConfigurationError = class extends FacilitatorError {
|
|
71
|
+
constructor(message) {
|
|
72
|
+
super(message, "CONFIGURATION_ERROR");
|
|
73
|
+
this.name = "ConfigurationError";
|
|
74
|
+
}
|
|
75
|
+
};
|
|
76
|
+
|
|
77
|
+
// src/utils.ts
|
|
78
|
+
function normalizeUrl(url) {
|
|
79
|
+
return url.replace(/\/+$/, "");
|
|
80
|
+
}
|
|
81
|
+
function buildUrl(baseUrl, path) {
|
|
82
|
+
return `${normalizeUrl(baseUrl)}${path}`;
|
|
83
|
+
}
|
|
84
|
+
function isPaymentPayload(value) {
|
|
85
|
+
if (!value || typeof value !== "object") return false;
|
|
86
|
+
const obj = value;
|
|
87
|
+
return (obj.x402Version === 1 || obj.x402Version === 2) && typeof obj.scheme === "string" && typeof obj.network === "string" && obj.payload !== void 0;
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
// src/client.ts
|
|
91
|
+
var DEFAULT_TIMEOUT = 3e4;
|
|
92
|
+
var OpenFacilitator = class {
|
|
93
|
+
constructor(config) {
|
|
94
|
+
if (!config.url) {
|
|
95
|
+
throw new ConfigurationError("Facilitator URL is required");
|
|
96
|
+
}
|
|
97
|
+
this.baseUrl = normalizeUrl(config.url);
|
|
98
|
+
this.timeout = config.timeout ?? DEFAULT_TIMEOUT;
|
|
99
|
+
this.headers = {
|
|
100
|
+
"Content-Type": "application/json",
|
|
101
|
+
...config.headers
|
|
102
|
+
};
|
|
103
|
+
}
|
|
104
|
+
/**
|
|
105
|
+
* Get the facilitator URL
|
|
106
|
+
*/
|
|
107
|
+
get url() {
|
|
108
|
+
return this.baseUrl;
|
|
109
|
+
}
|
|
110
|
+
/**
|
|
111
|
+
* Verify a payment is valid
|
|
112
|
+
*/
|
|
113
|
+
async verify(payment) {
|
|
114
|
+
try {
|
|
115
|
+
const response = await this.request("/verify", {
|
|
116
|
+
method: "POST",
|
|
117
|
+
body: JSON.stringify(payment)
|
|
118
|
+
});
|
|
119
|
+
return response;
|
|
120
|
+
} catch (error) {
|
|
121
|
+
if (error instanceof FacilitatorError) throw error;
|
|
122
|
+
throw new VerificationError(
|
|
123
|
+
`Verification failed: ${error instanceof Error ? error.message : "Unknown error"}`,
|
|
124
|
+
error
|
|
125
|
+
);
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
/**
|
|
129
|
+
* Settle/broadcast a payment transaction
|
|
130
|
+
*/
|
|
131
|
+
async settle(payment) {
|
|
132
|
+
try {
|
|
133
|
+
const response = await this.request("/settle", {
|
|
134
|
+
method: "POST",
|
|
135
|
+
body: JSON.stringify(payment)
|
|
136
|
+
});
|
|
137
|
+
return response;
|
|
138
|
+
} catch (error) {
|
|
139
|
+
if (error instanceof FacilitatorError) throw error;
|
|
140
|
+
throw new SettlementError(
|
|
141
|
+
`Settlement failed: ${error instanceof Error ? error.message : "Unknown error"}`,
|
|
142
|
+
error
|
|
143
|
+
);
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
/**
|
|
147
|
+
* Get supported networks and payment kinds
|
|
148
|
+
*/
|
|
149
|
+
async supported() {
|
|
150
|
+
try {
|
|
151
|
+
const response = await this.request("/supported", {
|
|
152
|
+
method: "GET"
|
|
153
|
+
});
|
|
154
|
+
return response;
|
|
155
|
+
} catch (error) {
|
|
156
|
+
if (error instanceof FacilitatorError) throw error;
|
|
157
|
+
throw new NetworkError(
|
|
158
|
+
`Failed to fetch supported networks: ${error instanceof Error ? error.message : "Unknown error"}`,
|
|
159
|
+
error
|
|
160
|
+
);
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
/**
|
|
164
|
+
* Health check - verify facilitator is reachable
|
|
165
|
+
*/
|
|
166
|
+
async health() {
|
|
167
|
+
try {
|
|
168
|
+
await this.supported();
|
|
169
|
+
return true;
|
|
170
|
+
} catch {
|
|
171
|
+
return false;
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
/**
|
|
175
|
+
* Internal request helper
|
|
176
|
+
*/
|
|
177
|
+
async request(path, init) {
|
|
178
|
+
const url = buildUrl(this.baseUrl, path);
|
|
179
|
+
const controller = new AbortController();
|
|
180
|
+
const timeoutId = setTimeout(() => controller.abort(), this.timeout);
|
|
181
|
+
try {
|
|
182
|
+
const response = await fetch(url, {
|
|
183
|
+
...init,
|
|
184
|
+
headers: {
|
|
185
|
+
...this.headers,
|
|
186
|
+
...init.headers
|
|
187
|
+
},
|
|
188
|
+
signal: controller.signal
|
|
189
|
+
});
|
|
190
|
+
clearTimeout(timeoutId);
|
|
191
|
+
if (!response.ok) {
|
|
192
|
+
let errorMessage = `HTTP ${response.status}`;
|
|
193
|
+
try {
|
|
194
|
+
const errorBody = await response.json();
|
|
195
|
+
errorMessage = errorBody.error || errorBody.message || errorMessage;
|
|
196
|
+
} catch {
|
|
197
|
+
}
|
|
198
|
+
throw new FacilitatorError(errorMessage, "HTTP_ERROR", response.status);
|
|
199
|
+
}
|
|
200
|
+
return await response.json();
|
|
201
|
+
} catch (error) {
|
|
202
|
+
clearTimeout(timeoutId);
|
|
203
|
+
if (error instanceof FacilitatorError) throw error;
|
|
204
|
+
if (error instanceof Error && error.name === "AbortError") {
|
|
205
|
+
throw new NetworkError(`Request timeout after ${this.timeout}ms`);
|
|
206
|
+
}
|
|
207
|
+
throw new NetworkError(
|
|
208
|
+
`Request failed: ${error instanceof Error ? error.message : "Unknown error"}`,
|
|
209
|
+
error
|
|
210
|
+
);
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
};
|
|
214
|
+
function createDefaultFacilitator() {
|
|
215
|
+
return new OpenFacilitator({
|
|
216
|
+
url: "https://x402.openfacilitator.io"
|
|
217
|
+
});
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
// src/networks.ts
|
|
221
|
+
var NETWORKS = [
|
|
222
|
+
// EVM Mainnets
|
|
223
|
+
{ v1Id: "base", v2Id: "eip155:8453", name: "Base", type: "evm", chainId: 8453, testnet: false },
|
|
224
|
+
{ v1Id: "polygon", v2Id: "eip155:137", name: "Polygon", type: "evm", chainId: 137, testnet: false },
|
|
225
|
+
{ v1Id: "avalanche", v2Id: "eip155:43114", name: "Avalanche", type: "evm", chainId: 43114, testnet: false },
|
|
226
|
+
{ v1Id: "sei", v2Id: "eip155:1329", name: "Sei", type: "evm", chainId: 1329, testnet: false },
|
|
227
|
+
{ v1Id: "iotex", v2Id: "eip155:4689", name: "IoTeX", type: "evm", chainId: 4689, testnet: false },
|
|
228
|
+
{ v1Id: "peaq", v2Id: "eip155:3338", name: "Peaq", type: "evm", chainId: 3338, testnet: false },
|
|
229
|
+
{ v1Id: "xlayer", v2Id: "eip155:196", name: "X Layer", type: "evm", chainId: 196, testnet: false },
|
|
230
|
+
// EVM Testnets
|
|
231
|
+
{ v1Id: "base-sepolia", v2Id: "eip155:84532", name: "Base Sepolia", type: "evm", chainId: 84532, testnet: true },
|
|
232
|
+
{ v1Id: "polygon-amoy", v2Id: "eip155:80002", name: "Polygon Amoy", type: "evm", chainId: 80002, testnet: true },
|
|
233
|
+
{ v1Id: "avalanche-fuji", v2Id: "eip155:43113", name: "Avalanche Fuji", type: "evm", chainId: 43113, testnet: true },
|
|
234
|
+
{ v1Id: "sei-testnet", v2Id: "eip155:1328", name: "Sei Testnet", type: "evm", chainId: 1328, testnet: true },
|
|
235
|
+
{ v1Id: "xlayer-testnet", v2Id: "eip155:195", name: "X Layer Testnet", type: "evm", chainId: 195, testnet: true },
|
|
236
|
+
// Solana
|
|
237
|
+
{ v1Id: "solana", v2Id: "solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp", name: "Solana", type: "solana", testnet: false },
|
|
238
|
+
{ v1Id: "solana-devnet", v2Id: "solana:EtWTRABZaYq6iMfeYKouRu166VU2xqa1", name: "Solana Devnet", type: "solana", testnet: true }
|
|
239
|
+
];
|
|
240
|
+
function getNetwork(id) {
|
|
241
|
+
return NETWORKS.find((n) => n.v1Id === id || n.v2Id === id);
|
|
242
|
+
}
|
|
243
|
+
function getNetworkType(id) {
|
|
244
|
+
const network = getNetwork(id);
|
|
245
|
+
if (network) return network.type;
|
|
246
|
+
if (id.startsWith("eip155:")) return "evm";
|
|
247
|
+
if (id.startsWith("solana:")) return "solana";
|
|
248
|
+
return void 0;
|
|
249
|
+
}
|
|
250
|
+
function toV2NetworkId(id) {
|
|
251
|
+
const network = getNetwork(id);
|
|
252
|
+
return network?.v2Id ?? id;
|
|
253
|
+
}
|
|
254
|
+
function toV1NetworkId(id) {
|
|
255
|
+
const network = getNetwork(id);
|
|
256
|
+
return network?.v1Id ?? id;
|
|
257
|
+
}
|
|
258
|
+
function isValidNetwork(id) {
|
|
259
|
+
return getNetwork(id) !== void 0;
|
|
260
|
+
}
|
|
261
|
+
function getMainnets() {
|
|
262
|
+
return NETWORKS.filter((n) => !n.testnet);
|
|
263
|
+
}
|
|
264
|
+
function getTestnets() {
|
|
265
|
+
return NETWORKS.filter((n) => n.testnet);
|
|
266
|
+
}
|
|
267
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
268
|
+
0 && (module.exports = {
|
|
269
|
+
ConfigurationError,
|
|
270
|
+
FacilitatorError,
|
|
271
|
+
NETWORKS,
|
|
272
|
+
NetworkError,
|
|
273
|
+
OpenFacilitator,
|
|
274
|
+
SettlementError,
|
|
275
|
+
VerificationError,
|
|
276
|
+
createDefaultFacilitator,
|
|
277
|
+
getMainnets,
|
|
278
|
+
getNetwork,
|
|
279
|
+
getNetworkType,
|
|
280
|
+
getTestnets,
|
|
281
|
+
isPaymentPayload,
|
|
282
|
+
isValidNetwork,
|
|
283
|
+
toV1NetworkId,
|
|
284
|
+
toV2NetworkId
|
|
285
|
+
});
|
package/dist/index.mjs
ADDED
|
@@ -0,0 +1,243 @@
|
|
|
1
|
+
// src/errors.ts
|
|
2
|
+
var FacilitatorError = class extends Error {
|
|
3
|
+
constructor(message, code, statusCode, details) {
|
|
4
|
+
super(message);
|
|
5
|
+
this.code = code;
|
|
6
|
+
this.statusCode = statusCode;
|
|
7
|
+
this.details = details;
|
|
8
|
+
this.name = "FacilitatorError";
|
|
9
|
+
}
|
|
10
|
+
};
|
|
11
|
+
var NetworkError = class extends FacilitatorError {
|
|
12
|
+
constructor(message, details) {
|
|
13
|
+
super(message, "NETWORK_ERROR", void 0, details);
|
|
14
|
+
this.name = "NetworkError";
|
|
15
|
+
}
|
|
16
|
+
};
|
|
17
|
+
var VerificationError = class extends FacilitatorError {
|
|
18
|
+
constructor(message, details) {
|
|
19
|
+
super(message, "VERIFICATION_ERROR", void 0, details);
|
|
20
|
+
this.name = "VerificationError";
|
|
21
|
+
}
|
|
22
|
+
};
|
|
23
|
+
var SettlementError = class extends FacilitatorError {
|
|
24
|
+
constructor(message, details) {
|
|
25
|
+
super(message, "SETTLEMENT_ERROR", void 0, details);
|
|
26
|
+
this.name = "SettlementError";
|
|
27
|
+
}
|
|
28
|
+
};
|
|
29
|
+
var ConfigurationError = class extends FacilitatorError {
|
|
30
|
+
constructor(message) {
|
|
31
|
+
super(message, "CONFIGURATION_ERROR");
|
|
32
|
+
this.name = "ConfigurationError";
|
|
33
|
+
}
|
|
34
|
+
};
|
|
35
|
+
|
|
36
|
+
// src/utils.ts
|
|
37
|
+
function normalizeUrl(url) {
|
|
38
|
+
return url.replace(/\/+$/, "");
|
|
39
|
+
}
|
|
40
|
+
function buildUrl(baseUrl, path) {
|
|
41
|
+
return `${normalizeUrl(baseUrl)}${path}`;
|
|
42
|
+
}
|
|
43
|
+
function isPaymentPayload(value) {
|
|
44
|
+
if (!value || typeof value !== "object") return false;
|
|
45
|
+
const obj = value;
|
|
46
|
+
return (obj.x402Version === 1 || obj.x402Version === 2) && typeof obj.scheme === "string" && typeof obj.network === "string" && obj.payload !== void 0;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
// src/client.ts
|
|
50
|
+
var DEFAULT_TIMEOUT = 3e4;
|
|
51
|
+
var OpenFacilitator = class {
|
|
52
|
+
constructor(config) {
|
|
53
|
+
if (!config.url) {
|
|
54
|
+
throw new ConfigurationError("Facilitator URL is required");
|
|
55
|
+
}
|
|
56
|
+
this.baseUrl = normalizeUrl(config.url);
|
|
57
|
+
this.timeout = config.timeout ?? DEFAULT_TIMEOUT;
|
|
58
|
+
this.headers = {
|
|
59
|
+
"Content-Type": "application/json",
|
|
60
|
+
...config.headers
|
|
61
|
+
};
|
|
62
|
+
}
|
|
63
|
+
/**
|
|
64
|
+
* Get the facilitator URL
|
|
65
|
+
*/
|
|
66
|
+
get url() {
|
|
67
|
+
return this.baseUrl;
|
|
68
|
+
}
|
|
69
|
+
/**
|
|
70
|
+
* Verify a payment is valid
|
|
71
|
+
*/
|
|
72
|
+
async verify(payment) {
|
|
73
|
+
try {
|
|
74
|
+
const response = await this.request("/verify", {
|
|
75
|
+
method: "POST",
|
|
76
|
+
body: JSON.stringify(payment)
|
|
77
|
+
});
|
|
78
|
+
return response;
|
|
79
|
+
} catch (error) {
|
|
80
|
+
if (error instanceof FacilitatorError) throw error;
|
|
81
|
+
throw new VerificationError(
|
|
82
|
+
`Verification failed: ${error instanceof Error ? error.message : "Unknown error"}`,
|
|
83
|
+
error
|
|
84
|
+
);
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
/**
|
|
88
|
+
* Settle/broadcast a payment transaction
|
|
89
|
+
*/
|
|
90
|
+
async settle(payment) {
|
|
91
|
+
try {
|
|
92
|
+
const response = await this.request("/settle", {
|
|
93
|
+
method: "POST",
|
|
94
|
+
body: JSON.stringify(payment)
|
|
95
|
+
});
|
|
96
|
+
return response;
|
|
97
|
+
} catch (error) {
|
|
98
|
+
if (error instanceof FacilitatorError) throw error;
|
|
99
|
+
throw new SettlementError(
|
|
100
|
+
`Settlement failed: ${error instanceof Error ? error.message : "Unknown error"}`,
|
|
101
|
+
error
|
|
102
|
+
);
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
/**
|
|
106
|
+
* Get supported networks and payment kinds
|
|
107
|
+
*/
|
|
108
|
+
async supported() {
|
|
109
|
+
try {
|
|
110
|
+
const response = await this.request("/supported", {
|
|
111
|
+
method: "GET"
|
|
112
|
+
});
|
|
113
|
+
return response;
|
|
114
|
+
} catch (error) {
|
|
115
|
+
if (error instanceof FacilitatorError) throw error;
|
|
116
|
+
throw new NetworkError(
|
|
117
|
+
`Failed to fetch supported networks: ${error instanceof Error ? error.message : "Unknown error"}`,
|
|
118
|
+
error
|
|
119
|
+
);
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
/**
|
|
123
|
+
* Health check - verify facilitator is reachable
|
|
124
|
+
*/
|
|
125
|
+
async health() {
|
|
126
|
+
try {
|
|
127
|
+
await this.supported();
|
|
128
|
+
return true;
|
|
129
|
+
} catch {
|
|
130
|
+
return false;
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
/**
|
|
134
|
+
* Internal request helper
|
|
135
|
+
*/
|
|
136
|
+
async request(path, init) {
|
|
137
|
+
const url = buildUrl(this.baseUrl, path);
|
|
138
|
+
const controller = new AbortController();
|
|
139
|
+
const timeoutId = setTimeout(() => controller.abort(), this.timeout);
|
|
140
|
+
try {
|
|
141
|
+
const response = await fetch(url, {
|
|
142
|
+
...init,
|
|
143
|
+
headers: {
|
|
144
|
+
...this.headers,
|
|
145
|
+
...init.headers
|
|
146
|
+
},
|
|
147
|
+
signal: controller.signal
|
|
148
|
+
});
|
|
149
|
+
clearTimeout(timeoutId);
|
|
150
|
+
if (!response.ok) {
|
|
151
|
+
let errorMessage = `HTTP ${response.status}`;
|
|
152
|
+
try {
|
|
153
|
+
const errorBody = await response.json();
|
|
154
|
+
errorMessage = errorBody.error || errorBody.message || errorMessage;
|
|
155
|
+
} catch {
|
|
156
|
+
}
|
|
157
|
+
throw new FacilitatorError(errorMessage, "HTTP_ERROR", response.status);
|
|
158
|
+
}
|
|
159
|
+
return await response.json();
|
|
160
|
+
} catch (error) {
|
|
161
|
+
clearTimeout(timeoutId);
|
|
162
|
+
if (error instanceof FacilitatorError) throw error;
|
|
163
|
+
if (error instanceof Error && error.name === "AbortError") {
|
|
164
|
+
throw new NetworkError(`Request timeout after ${this.timeout}ms`);
|
|
165
|
+
}
|
|
166
|
+
throw new NetworkError(
|
|
167
|
+
`Request failed: ${error instanceof Error ? error.message : "Unknown error"}`,
|
|
168
|
+
error
|
|
169
|
+
);
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
};
|
|
173
|
+
function createDefaultFacilitator() {
|
|
174
|
+
return new OpenFacilitator({
|
|
175
|
+
url: "https://x402.openfacilitator.io"
|
|
176
|
+
});
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
// src/networks.ts
|
|
180
|
+
var NETWORKS = [
|
|
181
|
+
// EVM Mainnets
|
|
182
|
+
{ v1Id: "base", v2Id: "eip155:8453", name: "Base", type: "evm", chainId: 8453, testnet: false },
|
|
183
|
+
{ v1Id: "polygon", v2Id: "eip155:137", name: "Polygon", type: "evm", chainId: 137, testnet: false },
|
|
184
|
+
{ v1Id: "avalanche", v2Id: "eip155:43114", name: "Avalanche", type: "evm", chainId: 43114, testnet: false },
|
|
185
|
+
{ v1Id: "sei", v2Id: "eip155:1329", name: "Sei", type: "evm", chainId: 1329, testnet: false },
|
|
186
|
+
{ v1Id: "iotex", v2Id: "eip155:4689", name: "IoTeX", type: "evm", chainId: 4689, testnet: false },
|
|
187
|
+
{ v1Id: "peaq", v2Id: "eip155:3338", name: "Peaq", type: "evm", chainId: 3338, testnet: false },
|
|
188
|
+
{ v1Id: "xlayer", v2Id: "eip155:196", name: "X Layer", type: "evm", chainId: 196, testnet: false },
|
|
189
|
+
// EVM Testnets
|
|
190
|
+
{ v1Id: "base-sepolia", v2Id: "eip155:84532", name: "Base Sepolia", type: "evm", chainId: 84532, testnet: true },
|
|
191
|
+
{ v1Id: "polygon-amoy", v2Id: "eip155:80002", name: "Polygon Amoy", type: "evm", chainId: 80002, testnet: true },
|
|
192
|
+
{ v1Id: "avalanche-fuji", v2Id: "eip155:43113", name: "Avalanche Fuji", type: "evm", chainId: 43113, testnet: true },
|
|
193
|
+
{ v1Id: "sei-testnet", v2Id: "eip155:1328", name: "Sei Testnet", type: "evm", chainId: 1328, testnet: true },
|
|
194
|
+
{ v1Id: "xlayer-testnet", v2Id: "eip155:195", name: "X Layer Testnet", type: "evm", chainId: 195, testnet: true },
|
|
195
|
+
// Solana
|
|
196
|
+
{ v1Id: "solana", v2Id: "solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp", name: "Solana", type: "solana", testnet: false },
|
|
197
|
+
{ v1Id: "solana-devnet", v2Id: "solana:EtWTRABZaYq6iMfeYKouRu166VU2xqa1", name: "Solana Devnet", type: "solana", testnet: true }
|
|
198
|
+
];
|
|
199
|
+
function getNetwork(id) {
|
|
200
|
+
return NETWORKS.find((n) => n.v1Id === id || n.v2Id === id);
|
|
201
|
+
}
|
|
202
|
+
function getNetworkType(id) {
|
|
203
|
+
const network = getNetwork(id);
|
|
204
|
+
if (network) return network.type;
|
|
205
|
+
if (id.startsWith("eip155:")) return "evm";
|
|
206
|
+
if (id.startsWith("solana:")) return "solana";
|
|
207
|
+
return void 0;
|
|
208
|
+
}
|
|
209
|
+
function toV2NetworkId(id) {
|
|
210
|
+
const network = getNetwork(id);
|
|
211
|
+
return network?.v2Id ?? id;
|
|
212
|
+
}
|
|
213
|
+
function toV1NetworkId(id) {
|
|
214
|
+
const network = getNetwork(id);
|
|
215
|
+
return network?.v1Id ?? id;
|
|
216
|
+
}
|
|
217
|
+
function isValidNetwork(id) {
|
|
218
|
+
return getNetwork(id) !== void 0;
|
|
219
|
+
}
|
|
220
|
+
function getMainnets() {
|
|
221
|
+
return NETWORKS.filter((n) => !n.testnet);
|
|
222
|
+
}
|
|
223
|
+
function getTestnets() {
|
|
224
|
+
return NETWORKS.filter((n) => n.testnet);
|
|
225
|
+
}
|
|
226
|
+
export {
|
|
227
|
+
ConfigurationError,
|
|
228
|
+
FacilitatorError,
|
|
229
|
+
NETWORKS,
|
|
230
|
+
NetworkError,
|
|
231
|
+
OpenFacilitator,
|
|
232
|
+
SettlementError,
|
|
233
|
+
VerificationError,
|
|
234
|
+
createDefaultFacilitator,
|
|
235
|
+
getMainnets,
|
|
236
|
+
getNetwork,
|
|
237
|
+
getNetworkType,
|
|
238
|
+
getTestnets,
|
|
239
|
+
isPaymentPayload,
|
|
240
|
+
isValidNetwork,
|
|
241
|
+
toV1NetworkId,
|
|
242
|
+
toV2NetworkId
|
|
243
|
+
};
|
package/package.json
ADDED
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@openfacilitator/sdk",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "TypeScript SDK for x402 payment facilitation",
|
|
5
|
+
"main": "dist/index.js",
|
|
6
|
+
"module": "dist/index.mjs",
|
|
7
|
+
"types": "dist/index.d.ts",
|
|
8
|
+
"files": [
|
|
9
|
+
"dist"
|
|
10
|
+
],
|
|
11
|
+
"scripts": {
|
|
12
|
+
"build": "tsup src/index.ts --format cjs,esm --dts",
|
|
13
|
+
"dev": "tsup src/index.ts --format cjs,esm --dts --watch",
|
|
14
|
+
"test": "vitest",
|
|
15
|
+
"lint": "eslint src/",
|
|
16
|
+
"clean": "rm -rf dist"
|
|
17
|
+
},
|
|
18
|
+
"keywords": [
|
|
19
|
+
"x402",
|
|
20
|
+
"payments",
|
|
21
|
+
"crypto",
|
|
22
|
+
"facilitator",
|
|
23
|
+
"solana",
|
|
24
|
+
"evm",
|
|
25
|
+
"base"
|
|
26
|
+
],
|
|
27
|
+
"author": "",
|
|
28
|
+
"license": "MIT",
|
|
29
|
+
"repository": {
|
|
30
|
+
"type": "git",
|
|
31
|
+
"url": "https://github.com/your-repo/openfacilitator"
|
|
32
|
+
},
|
|
33
|
+
"devDependencies": {
|
|
34
|
+
"tsup": "^8.0.0",
|
|
35
|
+
"typescript": "^5.0.0",
|
|
36
|
+
"vitest": "^1.0.0"
|
|
37
|
+
},
|
|
38
|
+
"engines": {
|
|
39
|
+
"node": ">=18"
|
|
40
|
+
}
|
|
41
|
+
}
|