@onchaindb/sdk 0.4.0 → 0.4.2

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.
Files changed (98) hide show
  1. package/.DS_Store +0 -0
  2. package/.claude/settings.local.json +8 -0
  3. package/.gitignore +5 -0
  4. package/.idea/.gitignore +5 -0
  5. package/.idea/compiler.xml +6 -0
  6. package/.idea/inspectionProfiles/Project_Default.xml +6 -0
  7. package/.idea/jsLinters/eslint.xml +6 -0
  8. package/.idea/modules.xml +8 -0
  9. package/.idea/prettier.xml +7 -0
  10. package/.idea/sdk.iml +12 -0
  11. package/.idea/vcs.xml +6 -0
  12. package/.idea/workspace.xml +257 -0
  13. package/dist/client.d.ts.map +1 -1
  14. package/dist/client.js +11 -3
  15. package/dist/client.js.map +1 -1
  16. package/dist/database.d.ts +0 -20
  17. package/dist/database.d.ts.map +1 -1
  18. package/dist/database.js +0 -40
  19. package/dist/database.js.map +1 -1
  20. package/dist/query-sdk/tests/setup.d.ts +16 -0
  21. package/dist/query-sdk/tests/setup.d.ts.map +1 -0
  22. package/dist/query-sdk/tests/setup.js +49 -0
  23. package/dist/query-sdk/tests/setup.js.map +1 -0
  24. package/examples/basic-usage.ts +136 -0
  25. package/examples/blob-upload-example.ts +140 -0
  26. package/examples/collection-schema-example.ts +304 -0
  27. package/examples/server-side-joins.ts +201 -0
  28. package/examples/tweet-self-joins-example.ts +352 -0
  29. package/package-lock.json +3823 -0
  30. package/package.json +1 -1
  31. package/skills.md +1096 -0
  32. package/src/.env +1 -0
  33. package/src/batch.d.ts +121 -0
  34. package/src/batch.js +205 -0
  35. package/src/batch.ts +257 -0
  36. package/src/client.ts +1856 -0
  37. package/src/database.d.ts +268 -0
  38. package/src/database.js +294 -0
  39. package/src/database.ts +695 -0
  40. package/src/index.d.ts +160 -0
  41. package/src/index.js +186 -0
  42. package/src/index.ts +253 -0
  43. package/src/query-sdk/ConditionBuilder.ts +103 -0
  44. package/src/query-sdk/FieldConditionBuilder.ts +2 -0
  45. package/src/query-sdk/NestedBuilders.ts +186 -0
  46. package/src/query-sdk/OnChainDB.ts +294 -0
  47. package/src/query-sdk/QueryBuilder.ts +1191 -0
  48. package/src/query-sdk/QueryResult.ts +375 -0
  49. package/src/query-sdk/README.md +866 -0
  50. package/src/query-sdk/SelectionBuilder.ts +94 -0
  51. package/src/query-sdk/adapters/HttpClientAdapter.ts +249 -0
  52. package/src/query-sdk/dist/ConditionBuilder.d.ts +22 -0
  53. package/src/query-sdk/dist/ConditionBuilder.js +90 -0
  54. package/src/query-sdk/dist/FieldConditionBuilder.d.ts +1 -0
  55. package/src/query-sdk/dist/FieldConditionBuilder.js +6 -0
  56. package/src/query-sdk/dist/NestedBuilders.d.ts +43 -0
  57. package/src/query-sdk/dist/NestedBuilders.js +144 -0
  58. package/src/query-sdk/dist/OnChainDB.d.ts +19 -0
  59. package/src/query-sdk/dist/OnChainDB.js +123 -0
  60. package/src/query-sdk/dist/QueryBuilder.d.ts +70 -0
  61. package/src/query-sdk/dist/QueryBuilder.js +295 -0
  62. package/src/query-sdk/dist/QueryResult.d.ts +52 -0
  63. package/src/query-sdk/dist/QueryResult.js +293 -0
  64. package/src/query-sdk/dist/SelectionBuilder.d.ts +20 -0
  65. package/src/query-sdk/dist/SelectionBuilder.js +80 -0
  66. package/src/query-sdk/dist/adapters/HttpClientAdapter.d.ts +27 -0
  67. package/src/query-sdk/dist/adapters/HttpClientAdapter.js +170 -0
  68. package/src/query-sdk/dist/index.d.ts +36 -0
  69. package/src/query-sdk/dist/index.js +27 -0
  70. package/src/query-sdk/dist/operators.d.ts +56 -0
  71. package/src/query-sdk/dist/operators.js +289 -0
  72. package/src/query-sdk/dist/tests/setup.d.ts +15 -0
  73. package/src/query-sdk/dist/tests/setup.js +46 -0
  74. package/src/query-sdk/index.ts +59 -0
  75. package/src/query-sdk/jest.config.js +25 -0
  76. package/src/query-sdk/operators.ts +335 -0
  77. package/src/query-sdk/package.json +46 -0
  78. package/src/query-sdk/tests/FieldConditionBuilder.test.ts +84 -0
  79. package/src/query-sdk/tests/LogicalOperator.test.ts +85 -0
  80. package/src/query-sdk/tests/NestedBuilders.test.ts +321 -0
  81. package/src/query-sdk/tests/QueryBuilder.test.ts +348 -0
  82. package/src/query-sdk/tests/QueryResult.test.ts +464 -0
  83. package/src/query-sdk/tests/aggregations.test.ts +653 -0
  84. package/src/query-sdk/tests/comprehensive.test.ts +279 -0
  85. package/src/query-sdk/tests/integration.test.ts +608 -0
  86. package/src/query-sdk/tests/operators.test.ts +327 -0
  87. package/src/query-sdk/tests/setup.ts +59 -0
  88. package/src/query-sdk/tests/unit.test.ts +794 -0
  89. package/src/query-sdk/tsconfig.json +26 -0
  90. package/src/query-sdk/yarn.lock +3092 -0
  91. package/src/types.d.ts +131 -0
  92. package/src/types.js +46 -0
  93. package/src/types.ts +534 -0
  94. package/src/x402/index.ts +12 -0
  95. package/src/x402/types.ts +250 -0
  96. package/src/x402/utils.ts +332 -0
  97. package/tsconfig.json +20 -0
  98. package/yarn.lock +2309 -0
@@ -0,0 +1,12 @@
1
+ /**
2
+ * x402 Protocol Module
3
+ *
4
+ * Exports types and utilities for x402 payment protocol support.
5
+ *
6
+ * Two payment flows are supported:
7
+ * 1. Celestia native: User broadcasts tx, sends txHash to server
8
+ * 2. Facilitator (EVM/Solana): User signs authorization, server sends to facilitator
9
+ */
10
+
11
+ export * from './types';
12
+ export * from './utils';
@@ -0,0 +1,250 @@
1
+ /**
2
+ * x402 Protocol Types
3
+ *
4
+ * Type definitions for the x402 payment protocol specification.
5
+ * See: https://github.com/coinbase/x402/blob/main/specs/x402-specification.md
6
+ */
7
+
8
+ /**
9
+ * Payment scheme - currently only "exact" is supported per spec
10
+ */
11
+ export type PaymentScheme = 'exact';
12
+
13
+ /**
14
+ * Chain type for payment processing
15
+ */
16
+ export type ChainType = 'cosmos' | 'evm' | 'solana';
17
+
18
+ /**
19
+ * Payment method
20
+ */
21
+ export type PaymentMethod = 'native' | 'x402-facilitator';
22
+
23
+ /**
24
+ * x402 Payment requirement from server
25
+ */
26
+ export interface X402PaymentRequirement {
27
+ /** Payment scheme - must be "exact" */
28
+ scheme: PaymentScheme;
29
+ /** Network identifier (e.g., "mocha-4", "base", "solana") */
30
+ network: string;
31
+ /** Maximum amount required in smallest units as string */
32
+ maxAmountRequired: string;
33
+ /** Recipient address */
34
+ payTo: string;
35
+ /** Asset identifier (e.g., "utia", USDC address) */
36
+ asset: string;
37
+ /** Resource URL being accessed */
38
+ resource: string;
39
+ /** Human-readable description */
40
+ description: string;
41
+ /** Content type of the resource */
42
+ mimeType: string;
43
+ /** Maximum timeout for payment in seconds */
44
+ maxTimeoutSeconds: number;
45
+ /** Extra extension data */
46
+ extra?: X402Extra;
47
+ }
48
+
49
+ /**
50
+ * x402 Extra field with OnChainDB extensions
51
+ */
52
+ export interface X402Extra {
53
+ /** Extension identifier */
54
+ x402Extension?: string;
55
+ /** Quote ID for this payment */
56
+ quoteId?: string;
57
+ /** Chain type (cosmos, evm, solana) */
58
+ chainType?: ChainType;
59
+ /** Chain ID for EVM chains */
60
+ chainId?: number;
61
+ /** Payment method */
62
+ paymentMethod?: PaymentMethod;
63
+ /** x402 facilitator URL */
64
+ facilitator?: string;
65
+ /** Token symbol */
66
+ tokenSymbol?: string;
67
+ /** Token decimals */
68
+ tokenDecimals?: number;
69
+ /** Cost breakdown */
70
+ costBreakdown?: Record<string, number>;
71
+ /** Pricing information */
72
+ pricing?: {
73
+ baseAmount: string;
74
+ baseAsset: string;
75
+ premiumPercent?: number;
76
+ expiresAt?: number;
77
+ };
78
+ }
79
+
80
+ /**
81
+ * x402 Payment Required Response (402 status)
82
+ */
83
+ export interface X402PaymentRequiredResponse {
84
+ /** Protocol version - must be 1 */
85
+ x402Version: 1;
86
+ /** Error message explaining why payment is required */
87
+ error: string;
88
+ /** Array of accepted payment options */
89
+ accepts: X402PaymentRequirement[];
90
+ }
91
+
92
+ /**
93
+ * x402 Payment Payload sent in X-PAYMENT header
94
+ */
95
+ export interface X402PaymentPayload {
96
+ /** Protocol version */
97
+ x402Version: 1;
98
+ /** Payment scheme */
99
+ scheme: PaymentScheme;
100
+ /** Network used for payment */
101
+ network: string;
102
+ /** Quote ID from server */
103
+ quoteId: string;
104
+ /** Payment-specific payload */
105
+ payload: X402NativePayload | X402EvmPayload | X402SolanaPayload;
106
+ }
107
+
108
+ /**
109
+ * Native Celestia payment payload
110
+ */
111
+ export interface X402NativePayload {
112
+ /** Transaction hash */
113
+ txHash: string;
114
+ /** Sender address */
115
+ sender: string;
116
+ /** Payment timestamp */
117
+ timestamp: number;
118
+ }
119
+
120
+ /**
121
+ * EVM payment payload (for x402 facilitator)
122
+ */
123
+ export interface X402EvmPayload {
124
+ /** EIP-712 signature */
125
+ signature: string;
126
+ /** ERC-3009 authorization */
127
+ authorization: {
128
+ from: string;
129
+ to: string;
130
+ value: string;
131
+ validAfter: number;
132
+ validBefore: number;
133
+ nonce: string;
134
+ };
135
+ }
136
+
137
+ /**
138
+ * Solana payment payload (for x402 facilitator)
139
+ */
140
+ export interface X402SolanaPayload {
141
+ /** Signed transaction (base64) */
142
+ transaction: string;
143
+ }
144
+
145
+ /**
146
+ * x402 Payment Response header value
147
+ */
148
+ export interface X402PaymentResponse {
149
+ /** Transaction hash */
150
+ txHash: string;
151
+ /** Network where payment was made */
152
+ network: string;
153
+ /** Block height of confirmation */
154
+ blockHeight: number;
155
+ /** Amount paid */
156
+ amount: string;
157
+ /** Confirmation timestamp */
158
+ confirmedAt: number;
159
+ }
160
+
161
+ /**
162
+ * Quote format for payment callback
163
+ */
164
+ export interface X402Quote {
165
+ /** Quote ID */
166
+ quoteId: string;
167
+ /** Total cost in TIA */
168
+ totalCostTia: number;
169
+ /** Amount in smallest units */
170
+ amountRaw: string;
171
+ /** Broker/recipient address */
172
+ brokerAddress: string;
173
+ /** Payment description */
174
+ description: string;
175
+ /** Quote expiration timestamp */
176
+ expiresAt: number;
177
+ /** Chain type */
178
+ chainType: ChainType;
179
+ /** Network name */
180
+ network: string;
181
+ /** Asset address/identifier */
182
+ asset: string;
183
+ /** Token symbol */
184
+ tokenSymbol: string;
185
+ /** Token decimals */
186
+ tokenDecimals: number;
187
+ /** Payment method */
188
+ paymentMethod: PaymentMethod;
189
+ /** Facilitator URL (if applicable) */
190
+ facilitator?: string;
191
+ /** All available payment options */
192
+ allOptions: X402PaymentRequirement[];
193
+ }
194
+
195
+ /**
196
+ * Payment result from callback - supports both native and facilitator flows
197
+ */
198
+ export interface X402PaymentResult {
199
+ /** Transaction hash (required for Celestia native, optional for facilitator) */
200
+ txHash: string;
201
+ /** Network used */
202
+ network: string;
203
+ /** Sender address */
204
+ sender: string;
205
+ /** Chain type */
206
+ chainType: ChainType;
207
+ /** Payment method used */
208
+ paymentMethod: PaymentMethod;
209
+ }
210
+
211
+ /**
212
+ * Facilitator payment result - used for EVM/Solana payments via x402 facilitator
213
+ * User provides authorization, facilitator executes the payment
214
+ */
215
+ export interface X402FacilitatorPaymentResult {
216
+ /** Network used */
217
+ network: string;
218
+ /** Chain type */
219
+ chainType: 'evm' | 'solana';
220
+ /** Payment method - always x402-facilitator */
221
+ paymentMethod: 'x402-facilitator';
222
+ /** EVM authorization (for EVM chains) */
223
+ evmAuthorization?: {
224
+ signature: string;
225
+ authorization: {
226
+ from: string;
227
+ to: string;
228
+ value: string;
229
+ validAfter: number;
230
+ validBefore: number;
231
+ nonce: string;
232
+ };
233
+ };
234
+ /** Solana authorization (for Solana) */
235
+ solanaAuthorization?: {
236
+ transaction: string;
237
+ };
238
+ }
239
+
240
+ /**
241
+ * Union type for all payment callback results
242
+ */
243
+ export type X402PaymentCallbackResult = X402PaymentResult | X402FacilitatorPaymentResult;
244
+
245
+ /**
246
+ * Type guard to check if result is a facilitator payment
247
+ */
248
+ export function isFacilitatorPaymentResult(result: X402PaymentCallbackResult): result is X402FacilitatorPaymentResult {
249
+ return result.paymentMethod === 'x402-facilitator' && !('txHash' in result && result.txHash);
250
+ }
@@ -0,0 +1,332 @@
1
+ /**
2
+ * x402 Protocol Utilities
3
+ *
4
+ * Helper functions for parsing and building x402 protocol messages.
5
+ */
6
+
7
+ import {
8
+ X402PaymentRequiredResponse,
9
+ X402PaymentRequirement,
10
+ X402Quote,
11
+ X402PaymentPayload,
12
+ X402PaymentResult,
13
+ ChainType,
14
+ PaymentMethod,
15
+ } from './types';
16
+
17
+ /**
18
+ * Parse a 402 response into typed x402 format
19
+ */
20
+ export function parseX402Response(data: any): X402PaymentRequiredResponse {
21
+ if (!data || typeof data !== 'object') {
22
+ throw new Error('Invalid x402 response: not an object');
23
+ }
24
+
25
+ if (data.x402Version !== 1) {
26
+ throw new Error(`Unsupported x402 version: ${data.x402Version}`);
27
+ }
28
+
29
+ if (!Array.isArray(data.accepts) || data.accepts.length === 0) {
30
+ throw new Error('Invalid x402 response: no payment options');
31
+ }
32
+
33
+ return {
34
+ x402Version: 1,
35
+ error: data.error || 'Payment required',
36
+ accepts: data.accepts.map(parsePaymentRequirement),
37
+ };
38
+ }
39
+
40
+ /**
41
+ * Parse a single payment requirement
42
+ */
43
+ function parsePaymentRequirement(req: any): X402PaymentRequirement {
44
+ if (req.scheme !== 'exact') {
45
+ console.warn(`Non-standard scheme "${req.scheme}", treating as exact`);
46
+ }
47
+
48
+ return {
49
+ scheme: 'exact',
50
+ network: req.network,
51
+ maxAmountRequired: req.maxAmountRequired,
52
+ payTo: req.payTo,
53
+ asset: req.asset,
54
+ resource: req.resource,
55
+ description: req.description,
56
+ mimeType: req.mimeType || 'application/json',
57
+ maxTimeoutSeconds: req.maxTimeoutSeconds || 300,
58
+ extra: req.extra,
59
+ };
60
+ }
61
+
62
+ /**
63
+ * Convert x402 payment requirement to quote format for callbacks
64
+ */
65
+ export function requirementToQuote(
66
+ requirement: X402PaymentRequirement,
67
+ allOptions: X402PaymentRequirement[]
68
+ ): X402Quote {
69
+ const extra = requirement.extra || {};
70
+ const amountRaw = requirement.maxAmountRequired;
71
+
72
+ // Determine chain type from extra or network
73
+ let chainType: ChainType = 'cosmos';
74
+ if (extra.chainType) {
75
+ chainType = extra.chainType;
76
+ } else if (isEvmNetwork(requirement.network)) {
77
+ chainType = 'evm';
78
+ } else if (isSolanaNetwork(requirement.network)) {
79
+ chainType = 'solana';
80
+ }
81
+
82
+ // Calculate TIA amount (for display purposes)
83
+ const decimals = extra.tokenDecimals || 6;
84
+ const totalCostTia = parseInt(amountRaw) / Math.pow(10, decimals);
85
+
86
+ // Calculate expiration
87
+ const expiresAt = extra.pricing?.expiresAt ||
88
+ Math.floor(Date.now() / 1000) + requirement.maxTimeoutSeconds;
89
+
90
+ return {
91
+ quoteId: extra.quoteId || '',
92
+ totalCostTia,
93
+ amountRaw,
94
+ brokerAddress: requirement.payTo,
95
+ description: requirement.description,
96
+ expiresAt,
97
+ chainType,
98
+ network: requirement.network,
99
+ asset: requirement.asset,
100
+ tokenSymbol: extra.tokenSymbol || getTokenSymbol(requirement.asset),
101
+ tokenDecimals: decimals,
102
+ paymentMethod: (extra.paymentMethod || 'native') as PaymentMethod,
103
+ facilitator: extra.facilitator,
104
+ allOptions,
105
+ };
106
+ }
107
+
108
+ /**
109
+ * Build X-PAYMENT header payload for Celestia native payments
110
+ * For EVM/Solana facilitator payments, use buildFacilitatorPaymentPayload instead
111
+ */
112
+ export function buildPaymentPayload(
113
+ requirement: X402PaymentRequirement,
114
+ payment: X402PaymentResult
115
+ ): X402PaymentPayload {
116
+ const extra = requirement.extra || {};
117
+
118
+ return {
119
+ x402Version: 1,
120
+ scheme: 'exact',
121
+ network: payment.network,
122
+ quoteId: extra.quoteId || '',
123
+ payload: {
124
+ txHash: payment.txHash.toLowerCase(),
125
+ sender: payment.sender,
126
+ timestamp: Math.floor(Date.now() / 1000),
127
+ },
128
+ };
129
+ }
130
+
131
+ /**
132
+ * Build X-PAYMENT header payload for facilitator networks (EVM/Solana)
133
+ * These payments don't have a txHash upfront - the facilitator executes the payment
134
+ */
135
+ export function buildFacilitatorPaymentPayload(
136
+ requirement: X402PaymentRequirement,
137
+ authorization: FacilitatorAuthorization
138
+ ): X402PaymentPayload {
139
+ const extra = requirement.extra || {};
140
+
141
+ if (authorization.type === 'evm') {
142
+ return {
143
+ x402Version: 1,
144
+ scheme: 'exact',
145
+ network: requirement.network,
146
+ quoteId: extra.quoteId || '',
147
+ payload: {
148
+ signature: authorization.signature,
149
+ authorization: authorization.authorization,
150
+ } as any,
151
+ };
152
+ } else if (authorization.type === 'solana') {
153
+ return {
154
+ x402Version: 1,
155
+ scheme: 'exact',
156
+ network: requirement.network,
157
+ quoteId: extra.quoteId || '',
158
+ payload: {
159
+ transaction: authorization.transaction,
160
+ } as any,
161
+ };
162
+ }
163
+
164
+ throw new Error(`Unsupported facilitator authorization type: ${(authorization as any).type}`);
165
+ }
166
+
167
+ /**
168
+ * EVM authorization for facilitator (ERC-3009 / EIP-712)
169
+ */
170
+ export interface EvmFacilitatorAuthorization {
171
+ type: 'evm';
172
+ /** EIP-712 signature */
173
+ signature: string;
174
+ /** ERC-3009 authorization details */
175
+ authorization: {
176
+ from: string;
177
+ to: string;
178
+ value: string;
179
+ validAfter: number;
180
+ validBefore: number;
181
+ nonce: string;
182
+ };
183
+ }
184
+
185
+ /**
186
+ * Solana authorization for facilitator
187
+ */
188
+ export interface SolanaFacilitatorAuthorization {
189
+ type: 'solana';
190
+ /** Signed transaction (base64) */
191
+ transaction: string;
192
+ }
193
+
194
+ export type FacilitatorAuthorization = EvmFacilitatorAuthorization | SolanaFacilitatorAuthorization;
195
+
196
+ /**
197
+ * Check if a network requires the x402 facilitator
198
+ */
199
+ export function isFacilitatorNetwork(network: string): boolean {
200
+ return isEvmNetwork(network) || isSolanaNetwork(network);
201
+ }
202
+
203
+ /**
204
+ * Encode payment payload to base64 for X-PAYMENT header
205
+ */
206
+ export function encodePaymentHeader(payload: X402PaymentPayload): string {
207
+ const json = JSON.stringify(payload);
208
+ if (typeof Buffer !== 'undefined') {
209
+ return Buffer.from(json).toString('base64');
210
+ } else {
211
+ return btoa(json);
212
+ }
213
+ }
214
+
215
+ /**
216
+ * Decode X-PAYMENT-RESPONSE header
217
+ */
218
+ export function decodePaymentResponse(header: string): any {
219
+ try {
220
+ if (typeof Buffer !== 'undefined') {
221
+ return JSON.parse(Buffer.from(header, 'base64').toString());
222
+ } else {
223
+ return JSON.parse(atob(header));
224
+ }
225
+ } catch {
226
+ // Try parsing as direct JSON (some servers don't base64 encode)
227
+ return JSON.parse(header);
228
+ }
229
+ }
230
+
231
+ /**
232
+ * Check if network is EVM-based
233
+ */
234
+ function isEvmNetwork(network: string): boolean {
235
+ const evmNetworks = [
236
+ 'ethereum', 'ethereum-sepolia',
237
+ 'base', 'base-sepolia',
238
+ 'polygon', 'polygon-amoy',
239
+ 'arbitrum', 'arbitrum-sepolia',
240
+ 'avalanche', 'avalanche-fuji',
241
+ ];
242
+ return evmNetworks.includes(network.toLowerCase());
243
+ }
244
+
245
+ /**
246
+ * Check if network is Solana-based
247
+ */
248
+ function isSolanaNetwork(network: string): boolean {
249
+ return network.toLowerCase() === 'solana' || network.toLowerCase() === 'solana-devnet';
250
+ }
251
+
252
+ /**
253
+ * Get token symbol from asset address
254
+ */
255
+ function getTokenSymbol(asset: string): string {
256
+ // Common asset mappings
257
+ const assetSymbols: Record<string, string> = {
258
+ 'utia': 'TIA',
259
+ 'native': 'ETH',
260
+ // USDC addresses on various chains
261
+ '0x833589fcd6edb6e08f4c7c32d4f71b54bda02913': 'USDC', // Base
262
+ '0x036cbd53842c5426634e7929541ec2318f3dcf7e': 'USDC', // Base Sepolia
263
+ '0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48': 'USDC', // Ethereum
264
+ 'epjfwdd5aufqssqem2qn1xzybapC8g4weggkzwyTdt1v': 'USDC', // Solana
265
+ };
266
+
267
+ const normalized = asset.toLowerCase();
268
+ return assetSymbols[normalized] || 'TOKEN';
269
+ }
270
+
271
+ /**
272
+ * Select best payment option based on user preference
273
+ */
274
+ export function selectPaymentOption(
275
+ options: X402PaymentRequirement[],
276
+ preferredChainType?: ChainType,
277
+ preferredNetwork?: string
278
+ ): X402PaymentRequirement {
279
+ // If specific network requested, find it
280
+ if (preferredNetwork) {
281
+ const match = options.find(o =>
282
+ o.network.toLowerCase() === preferredNetwork.toLowerCase()
283
+ );
284
+ if (match) return match;
285
+ }
286
+
287
+ // If chain type requested, find first match
288
+ if (preferredChainType) {
289
+ const match = options.find(o => {
290
+ const extra = o.extra || {};
291
+ if (extra.chainType === preferredChainType) return true;
292
+ if (preferredChainType === 'evm' && isEvmNetwork(o.network)) return true;
293
+ if (preferredChainType === 'solana' && isSolanaNetwork(o.network)) return true;
294
+ if (preferredChainType === 'cosmos' && o.asset === 'utia') return true;
295
+ return false;
296
+ });
297
+ if (match) return match;
298
+ }
299
+
300
+ // Default to first option (typically native TIA)
301
+ return options[0];
302
+ }
303
+
304
+ /**
305
+ * Group payment options by chain type
306
+ */
307
+ export function groupPaymentOptions(
308
+ options: X402PaymentRequirement[]
309
+ ): Record<ChainType, X402PaymentRequirement[]> {
310
+ const groups: Record<ChainType, X402PaymentRequirement[]> = {
311
+ cosmos: [],
312
+ evm: [],
313
+ solana: [],
314
+ };
315
+
316
+ for (const option of options) {
317
+ const extra = option.extra || {};
318
+ let chainType: ChainType = 'cosmos';
319
+
320
+ if (extra.chainType) {
321
+ chainType = extra.chainType;
322
+ } else if (isEvmNetwork(option.network)) {
323
+ chainType = 'evm';
324
+ } else if (isSolanaNetwork(option.network)) {
325
+ chainType = 'solana';
326
+ }
327
+
328
+ groups[chainType].push(option);
329
+ }
330
+
331
+ return groups;
332
+ }
package/tsconfig.json ADDED
@@ -0,0 +1,20 @@
1
+ {
2
+ "compilerOptions": {
3
+ "target": "ES2020",
4
+ "module": "commonjs",
5
+ "lib": ["ES2020"],
6
+ "outDir": "./dist",
7
+ "rootDir": "./src",
8
+ "strict": true,
9
+ "esModuleInterop": true,
10
+ "skipLibCheck": true,
11
+ "forceConsistentCasingInFileNames": true,
12
+ "declaration": true,
13
+ "declarationMap": true,
14
+ "sourceMap": true,
15
+ "removeComments": true,
16
+ "resolveJsonModule": true
17
+ },
18
+ "include": ["src/**/*"],
19
+ "exclude": ["node_modules", "dist", "**/*.test.ts"]
20
+ }