@lacasoft/openrelay-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/LICENSE +118 -0
- package/README.md +135 -0
- package/dist/index.d.mts +277 -0
- package/dist/index.d.ts +277 -0
- package/dist/index.js +554 -0
- package/dist/index.js.map +1 -0
- package/dist/index.mjs +529 -0
- package/dist/index.mjs.map +1 -0
- package/package.json +54 -0
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,277 @@
|
|
|
1
|
+
import { SupportedChain, CreatePaymentIntentParams, PaymentIntent, WebhookEvent, X402MiddlewareOptions } from '@lacasoft/openrelay-protocol';
|
|
2
|
+
export { AuthError, CreatePaymentIntentParams, NetworkError, OpenRelayError, OpenRelayErrorCode, OpenRelaySDKError, PaymentIntent, RoutingError, SupportedChain, USDC_ADDRESSES, ValidationError, WebhookEvent, X402MiddlewareOptions, classifyError } from '@lacasoft/openrelay-protocol';
|
|
3
|
+
import { Address, Hex } from 'viem';
|
|
4
|
+
|
|
5
|
+
interface LogEntry {
|
|
6
|
+
request_id: string;
|
|
7
|
+
method: string;
|
|
8
|
+
path: string;
|
|
9
|
+
status: number;
|
|
10
|
+
latency_ms: number;
|
|
11
|
+
/** Nodeit wallet selected for routing, if returned by the API. */
|
|
12
|
+
node_route: string | null;
|
|
13
|
+
}
|
|
14
|
+
interface OpenRelayConfig {
|
|
15
|
+
apiKey: string;
|
|
16
|
+
baseUrl?: string;
|
|
17
|
+
timeout?: number;
|
|
18
|
+
merchantWallet?: string;
|
|
19
|
+
/** Optional structured-log hook called after every SDK request. */
|
|
20
|
+
logger?: (entry: LogEntry) => void;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
interface BuildAuthorizationParams {
|
|
24
|
+
/** Payer address — the `from` of the USDC transfer. Must match the signer. */
|
|
25
|
+
payer: Address;
|
|
26
|
+
/** Amount in USDC base units (6 decimals). Must match the intent's amount. */
|
|
27
|
+
amount: bigint;
|
|
28
|
+
/** SettlementHub contract address — the `to` of the authorization. */
|
|
29
|
+
settlementHub: Address;
|
|
30
|
+
/** Which chain — picks USDC contract address + chainId. */
|
|
31
|
+
chain: SupportedChain;
|
|
32
|
+
/** Optional 32-byte random nonce. SDK generates one if omitted. */
|
|
33
|
+
nonce?: Hex;
|
|
34
|
+
/** Unix seconds; signature invalid before this. Default: 0 (always valid from start). */
|
|
35
|
+
validAfter?: bigint;
|
|
36
|
+
/** Unix seconds; signature invalid after this. Default: now + 30 minutes. */
|
|
37
|
+
validBefore?: bigint;
|
|
38
|
+
}
|
|
39
|
+
interface AuthorizationMessage {
|
|
40
|
+
from: Address;
|
|
41
|
+
to: Address;
|
|
42
|
+
value: bigint;
|
|
43
|
+
validAfter: bigint;
|
|
44
|
+
validBefore: bigint;
|
|
45
|
+
nonce: Hex;
|
|
46
|
+
}
|
|
47
|
+
interface AuthorizationTypedData {
|
|
48
|
+
domain: {
|
|
49
|
+
name: string;
|
|
50
|
+
version: string;
|
|
51
|
+
chainId: number;
|
|
52
|
+
verifyingContract: Address;
|
|
53
|
+
};
|
|
54
|
+
types: {
|
|
55
|
+
EIP712Domain: {
|
|
56
|
+
name: string;
|
|
57
|
+
type: string;
|
|
58
|
+
}[];
|
|
59
|
+
ReceiveWithAuthorization: {
|
|
60
|
+
name: string;
|
|
61
|
+
type: string;
|
|
62
|
+
}[];
|
|
63
|
+
};
|
|
64
|
+
primaryType: 'ReceiveWithAuthorization';
|
|
65
|
+
message: AuthorizationMessage;
|
|
66
|
+
}
|
|
67
|
+
declare function buildReceiveAuthorizationTypedData(params: BuildAuthorizationParams): AuthorizationTypedData;
|
|
68
|
+
interface SignedAuthorization {
|
|
69
|
+
/** Payer address (the `from` of the USDC transfer). */
|
|
70
|
+
payer: Address;
|
|
71
|
+
/** Authorization validity window. */
|
|
72
|
+
validAfter: bigint;
|
|
73
|
+
validBefore: bigint;
|
|
74
|
+
/** 32-byte random nonce, hex-encoded. */
|
|
75
|
+
nonce: Hex;
|
|
76
|
+
/** ECDSA signature components. */
|
|
77
|
+
v: number;
|
|
78
|
+
r: Hex;
|
|
79
|
+
s: Hex;
|
|
80
|
+
}
|
|
81
|
+
declare function signReceiveAuthorization(params: BuildAuthorizationParams, privateKey: Hex): Promise<SignedAuthorization>;
|
|
82
|
+
declare function splitSignature(signature: Hex): {
|
|
83
|
+
v: number;
|
|
84
|
+
r: Hex;
|
|
85
|
+
s: Hex;
|
|
86
|
+
};
|
|
87
|
+
declare function generateNonce(): Hex;
|
|
88
|
+
|
|
89
|
+
interface SubmitAuthorizationResponse {
|
|
90
|
+
/** Echoed intent id. */
|
|
91
|
+
intent_id: string;
|
|
92
|
+
/** Server-side estimate of when the operator will submit it on-chain. */
|
|
93
|
+
estimated_settlement_at: string | null;
|
|
94
|
+
/** Authorization persisted server-side, awaiting operator pickup. */
|
|
95
|
+
status: 'queued';
|
|
96
|
+
}
|
|
97
|
+
interface SubmitAuthorizationBatchResponse {
|
|
98
|
+
/** Per-authorization queueing result. Order matches the input. */
|
|
99
|
+
results: Array<{
|
|
100
|
+
intent_id: string;
|
|
101
|
+
status: 'queued' | 'rejected';
|
|
102
|
+
reason?: string;
|
|
103
|
+
}>;
|
|
104
|
+
queued: number;
|
|
105
|
+
rejected: number;
|
|
106
|
+
}
|
|
107
|
+
declare class PaymentIntents {
|
|
108
|
+
private config;
|
|
109
|
+
constructor(config: OpenRelayConfig);
|
|
110
|
+
/**
|
|
111
|
+
* Create a new payment intent.
|
|
112
|
+
*
|
|
113
|
+
* @example
|
|
114
|
+
* const intent = await relay.paymentIntents.create({
|
|
115
|
+
* amount: 1000, // $0.001000 USDC (6 decimals)
|
|
116
|
+
* currency: 'usdc',
|
|
117
|
+
* chain: 'base',
|
|
118
|
+
* metadata: { orderId: 'order_123' }
|
|
119
|
+
* })
|
|
120
|
+
*/
|
|
121
|
+
create(params: CreatePaymentIntentParams): Promise<PaymentIntent>;
|
|
122
|
+
/**
|
|
123
|
+
* Retrieve a payment intent by ID.
|
|
124
|
+
*/
|
|
125
|
+
retrieve(id: string): Promise<PaymentIntent>;
|
|
126
|
+
/**
|
|
127
|
+
* Cancel a payment intent (only valid while it is in 'created' state).
|
|
128
|
+
*/
|
|
129
|
+
cancel(id: string): Promise<PaymentIntent>;
|
|
130
|
+
/**
|
|
131
|
+
* List payment intents for the authenticated merchant.
|
|
132
|
+
*/
|
|
133
|
+
list(params?: {
|
|
134
|
+
limit?: number;
|
|
135
|
+
starting_after?: string;
|
|
136
|
+
}): Promise<{
|
|
137
|
+
data: PaymentIntent[];
|
|
138
|
+
has_more: boolean;
|
|
139
|
+
}>;
|
|
140
|
+
/**
|
|
141
|
+
* Build the EIP-712 typed-data structure for `ReceiveWithAuthorization`
|
|
142
|
+
* that USDC verifies on `payIntentWithAuthorization`. Hand the result to
|
|
143
|
+
* a wallet (viem `walletClient.signTypedData`, `window.ethereum`, etc.)
|
|
144
|
+
* to obtain a signature client-side.
|
|
145
|
+
*
|
|
146
|
+
* For server-side signing with a private key, prefer `signAuthorization`.
|
|
147
|
+
*
|
|
148
|
+
* @example (browser/wallet flow)
|
|
149
|
+
* const typed = relay.paymentIntents.buildAuthorizationTypedData({
|
|
150
|
+
* payer: '0xPayer...',
|
|
151
|
+
* amount: 5_000_000n, // 5 USDC (6 decimals)
|
|
152
|
+
* settlementHub: '0xHub...',
|
|
153
|
+
* chain: 'base-sepolia',
|
|
154
|
+
* })
|
|
155
|
+
* const signature = await walletClient.signTypedData(typed)
|
|
156
|
+
* const { v, r, s } = relay.paymentIntents.splitSignature(signature)
|
|
157
|
+
* await relay.paymentIntents.submitAuthorization(intentId, {
|
|
158
|
+
* payer: typed.message.from,
|
|
159
|
+
* validAfter: typed.message.validAfter,
|
|
160
|
+
* validBefore: typed.message.validBefore,
|
|
161
|
+
* nonce: typed.message.nonce,
|
|
162
|
+
* v, r, s,
|
|
163
|
+
* })
|
|
164
|
+
*/
|
|
165
|
+
buildAuthorizationTypedData(params: BuildAuthorizationParams): AuthorizationTypedData;
|
|
166
|
+
/**
|
|
167
|
+
* Server-side convenience: build + sign the `ReceiveWithAuthorization`
|
|
168
|
+
* message in one call. Returns everything needed for `submitAuthorization`.
|
|
169
|
+
*
|
|
170
|
+
* @example
|
|
171
|
+
* const auth = await relay.paymentIntents.signAuthorization(
|
|
172
|
+
* { payer, amount: 5_000_000n, settlementHub, chain: 'base-sepolia' },
|
|
173
|
+
* privateKey,
|
|
174
|
+
* )
|
|
175
|
+
* await relay.paymentIntents.submitAuthorization(intentId, auth)
|
|
176
|
+
*/
|
|
177
|
+
signAuthorization(params: BuildAuthorizationParams, privateKey: Hex): Promise<SignedAuthorization>;
|
|
178
|
+
/**
|
|
179
|
+
* Submit a signed authorization for a registered intent. The API queues
|
|
180
|
+
* it for the assigned operator to settle on-chain (via
|
|
181
|
+
* `SettlementHub.payIntentWithAuthorization`).
|
|
182
|
+
*
|
|
183
|
+
* The endpoint is implemented in Phase B3; this client method targets
|
|
184
|
+
* the documented path so SDK + API can be developed in parallel.
|
|
185
|
+
*/
|
|
186
|
+
submitAuthorization(intentId: string, auth: SignedAuthorization): Promise<SubmitAuthorizationResponse>;
|
|
187
|
+
/**
|
|
188
|
+
* Submit multiple signed authorizations in one HTTP request. The operator
|
|
189
|
+
* may settle them via `SettlementHub.payIntentBatchWithAuthorization`
|
|
190
|
+
* (skip-on-failure). Useful for x402 micropayment flows where many small
|
|
191
|
+
* payments are aggregated.
|
|
192
|
+
*
|
|
193
|
+
* Hard cap: `MAX_BATCH_SIZE` (matches `SettlementHub.MAX_BATCH_SIZE`,
|
|
194
|
+
* imported from `@lacasoft/openrelay-protocol` SSOT — never hardcode the literal).
|
|
195
|
+
*/
|
|
196
|
+
submitAuthorizationBatch(items: Array<{
|
|
197
|
+
intent_id: string;
|
|
198
|
+
authorization: SignedAuthorization;
|
|
199
|
+
}>): Promise<SubmitAuthorizationBatchResponse>;
|
|
200
|
+
/**
|
|
201
|
+
* Helper to split a 65-byte signature (e.g. from `walletClient.signTypedData`)
|
|
202
|
+
* into the {v, r, s} triple that `submitAuthorization` expects.
|
|
203
|
+
*/
|
|
204
|
+
splitSignature(signature: Hex): {
|
|
205
|
+
v: number;
|
|
206
|
+
r: Hex;
|
|
207
|
+
s: Hex;
|
|
208
|
+
};
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
declare class Webhooks {
|
|
212
|
+
private config;
|
|
213
|
+
constructor(config: OpenRelayConfig);
|
|
214
|
+
register(url: string, events: string[]): Promise<{
|
|
215
|
+
id: string;
|
|
216
|
+
url: string;
|
|
217
|
+
secret: string;
|
|
218
|
+
}>;
|
|
219
|
+
/**
|
|
220
|
+
* Verify a webhook payload signature.
|
|
221
|
+
* Call this in your webhook handler to ensure the request is from OpenRelay.
|
|
222
|
+
*
|
|
223
|
+
* Validates: (1) signature format, (2) timestamp freshness against
|
|
224
|
+
* `toleranceSeconds` to mitigate replay, (3) HMAC equality with
|
|
225
|
+
* timing-safe compare.
|
|
226
|
+
*
|
|
227
|
+
* @example
|
|
228
|
+
* const event = relay.webhooks.verify(rawBody, req.headers['openrelay-signature'], secret)
|
|
229
|
+
*/
|
|
230
|
+
verify(payload: string, signature: string, secret: string, toleranceSeconds?: number): WebhookEvent;
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
declare class X402 {
|
|
234
|
+
private config;
|
|
235
|
+
constructor(config: OpenRelayConfig);
|
|
236
|
+
/**
|
|
237
|
+
* Returns a Fastify preHandler hook that requires x402 payment.
|
|
238
|
+
*
|
|
239
|
+
* @example
|
|
240
|
+
* app.addHook('preHandler', relay.x402.middleware({
|
|
241
|
+
* price: 1000, // $0.001 USDC
|
|
242
|
+
* currency: 'usdc',
|
|
243
|
+
* chain: 'base',
|
|
244
|
+
* }))
|
|
245
|
+
*/
|
|
246
|
+
middleware(opts: X402MiddlewareOptions): (req: Request, reply: Response) => Promise<Response | undefined>;
|
|
247
|
+
/**
|
|
248
|
+
* Returns a Next.js App Router compatible handler that wraps a route with x402.
|
|
249
|
+
*
|
|
250
|
+
* @example
|
|
251
|
+
* export const GET = relay.x402.handler({
|
|
252
|
+
* price: 1000,
|
|
253
|
+
* handler: async (req) => Response.json({ data: 'protected' })
|
|
254
|
+
* })
|
|
255
|
+
*/
|
|
256
|
+
handler(opts: X402MiddlewareOptions & {
|
|
257
|
+
handler: (req: Request) => Promise<Response>;
|
|
258
|
+
}): (req: Request) => Promise<Response>;
|
|
259
|
+
/**
|
|
260
|
+
* Shared gate: extract X-PAYMENT, verify against the API, and either
|
|
261
|
+
* return a 402 Response (challenge or rejection) or null when payment
|
|
262
|
+
* is valid and the caller should proceed.
|
|
263
|
+
*/
|
|
264
|
+
private gate;
|
|
265
|
+
private buildPaymentRequired;
|
|
266
|
+
private verify;
|
|
267
|
+
}
|
|
268
|
+
|
|
269
|
+
declare class OpenRelay {
|
|
270
|
+
private config;
|
|
271
|
+
readonly paymentIntents: PaymentIntents;
|
|
272
|
+
readonly webhooks: Webhooks;
|
|
273
|
+
readonly x402: X402;
|
|
274
|
+
constructor(config: OpenRelayConfig);
|
|
275
|
+
}
|
|
276
|
+
|
|
277
|
+
export { type AuthorizationMessage, type AuthorizationTypedData, type BuildAuthorizationParams, type LogEntry, OpenRelay, type OpenRelayConfig, type SignedAuthorization, type SubmitAuthorizationBatchResponse, type SubmitAuthorizationResponse, buildReceiveAuthorizationTypedData, generateNonce, signReceiveAuthorization, splitSignature };
|