@alien_org/react 0.1.2 → 0.1.4

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/index.cjs CHANGED
@@ -91,6 +91,84 @@ function useAlien() {
91
91
  return context;
92
92
  }
93
93
 
94
+ //#endregion
95
+ //#region src/hooks/useClipboard.ts
96
+ /**
97
+ * Hook for clipboard operations.
98
+ *
99
+ * @example
100
+ * ```tsx
101
+ * function ClipboardDemo() {
102
+ * const { writeText, readText, isReading, errorCode, supported } = useClipboard();
103
+ *
104
+ * if (!supported) return null;
105
+ *
106
+ * return (
107
+ * <>
108
+ * <button onClick={() => writeText('Hello!')}>Copy</button>
109
+ * <button
110
+ * onClick={async () => {
111
+ * const text = await readText();
112
+ * if (text !== null) console.log('Pasted:', text);
113
+ * }}
114
+ * disabled={isReading}
115
+ * >
116
+ * Paste
117
+ * </button>
118
+ * {errorCode && <span>Error: {errorCode}</span>}
119
+ * </>
120
+ * );
121
+ * }
122
+ * ```
123
+ */
124
+ function useClipboard(options = {}) {
125
+ const { timeout = 5e3 } = options;
126
+ const { contractVersion, isBridgeAvailable: isBridgeAvailable$1 } = useAlien();
127
+ const [isReading, setIsReading] = (0, react.useState)(false);
128
+ const [errorCode, setErrorCode] = (0, react.useState)(null);
129
+ const supported = contractVersion ? (0, _alien_org_contract.isMethodSupported)("clipboard:write", contractVersion) && (0, _alien_org_contract.isMethodSupported)("clipboard:read", contractVersion) : true;
130
+ const writeText = (0, react.useCallback)((text) => {
131
+ if (!isBridgeAvailable$1) return;
132
+ if (contractVersion && !(0, _alien_org_contract.isMethodSupported)("clipboard:write", contractVersion)) return;
133
+ (0, _alien_org_bridge.send)("clipboard:write", { text });
134
+ }, [isBridgeAvailable$1, contractVersion]);
135
+ const readText = (0, react.useCallback)(async () => {
136
+ if (!isBridgeAvailable$1) return null;
137
+ if (contractVersion && !(0, _alien_org_contract.isMethodSupported)("clipboard:read", contractVersion)) return null;
138
+ setIsReading(true);
139
+ setErrorCode(null);
140
+ try {
141
+ const response = await (0, _alien_org_bridge.request)("clipboard:read", {}, "clipboard:response", { timeout });
142
+ if (response.errorCode) {
143
+ setErrorCode(response.errorCode);
144
+ return null;
145
+ }
146
+ return response.text;
147
+ } catch {
148
+ return null;
149
+ } finally {
150
+ setIsReading(false);
151
+ }
152
+ }, [
153
+ isBridgeAvailable$1,
154
+ contractVersion,
155
+ timeout
156
+ ]);
157
+ return (0, react.useMemo)(() => ({
158
+ writeText,
159
+ readText,
160
+ isReading,
161
+ errorCode,
162
+ supported
163
+ }), [
164
+ writeText,
165
+ readText,
166
+ isReading,
167
+ errorCode,
168
+ supported
169
+ ]);
170
+ }
171
+
94
172
  //#endregion
95
173
  //#region src/hooks/useEvent.ts
96
174
  /**
@@ -539,6 +617,7 @@ Object.defineProperty(exports, 'send', {
539
617
  }
540
618
  });
541
619
  exports.useAlien = useAlien;
620
+ exports.useClipboard = useClipboard;
542
621
  exports.useEvent = useEvent;
543
622
  exports.useIsMethodSupported = useIsMethodSupported;
544
623
  exports.useLaunchParams = useLaunchParams;
package/dist/index.d.cts CHANGED
@@ -33,6 +33,41 @@ type UnionKeys<T> = T extends T ? keyof T : never;
33
33
  * // Empty = {}
34
34
  */
35
35
  type Empty = Record<string, never>;
36
+ /**
37
+ * Client-side payment error codes (pre-broadcast failures).
38
+ * Returned when `status` is `'failed'` in `payment:response`.
39
+ * These errors occur before transaction broadcast, so no webhook is sent.
40
+ * @since 0.1.1
41
+ * @schema
42
+ */
43
+ type PaymentErrorCode$1 = 'insufficient_balance' | 'network_error' | 'pre_checkout_rejected' | 'pre_checkout_timeout' | 'unknown';
44
+ /**
45
+ * Payment test scenarios for simulating different payment outcomes.
46
+ *
47
+ * | Scenario | Client sees | Webhook |
48
+ * |----------|-------------|---------|
49
+ * | `'paid'` | `paid` | `{ status: 'finalized' }` |
50
+ * | `'paid:failed'` | `paid` | `{ status: 'failed' }` |
51
+ * | `'cancelled'` | `cancelled` | none |
52
+ * | `'error:*'` | `failed` | none (pre-broadcast) |
53
+ *
54
+ * @example
55
+ * // Happy path: client paid, tx finalized
56
+ * test: 'paid'
57
+ *
58
+ * // On-chain failure: client paid, tx failed
59
+ * test: 'paid:failed'
60
+ *
61
+ * // User cancelled before confirming
62
+ * test: 'cancelled'
63
+ *
64
+ * // Pre-broadcast error (no tx, no webhook)
65
+ * test: 'error:insufficient_balance'
66
+ *
67
+ * @since 0.1.2
68
+ * @schema
69
+ */
70
+ type PaymentTestScenario = 'paid' | 'paid:failed' | 'cancelled' | `error:${PaymentErrorCode$1}`;
36
71
  //#endregion
37
72
  //#region ../contract/src/events/types/payload.d.ts
38
73
  /**
@@ -80,7 +115,7 @@ interface Events {
80
115
  * Payment status.
81
116
  * - `paid`: Success
82
117
  * - `cancelled`: User rejected
83
- * - `failed`: Error (check `errorCode`)
118
+ * - `failed`: Sending transaction failed (check `errorCode`)
84
119
  * @since 0.1.1
85
120
  * @schema
86
121
  */
@@ -101,7 +136,7 @@ interface Events {
101
136
  * @since 0.1.1
102
137
  * @schema
103
138
  */
104
- errorCode?: 'insufficient_balance' | 'network_error' | 'pre_checkout_rejected' | 'pre_checkout_timeout' | 'unknown';
139
+ errorCode?: PaymentErrorCode$1;
105
140
  }>>;
106
141
  /**
107
142
  * Clipboard read response.
@@ -253,37 +288,62 @@ interface Methods {
253
288
  */
254
289
  invoice: string;
255
290
  /**
256
- * Item title shown on the approval screen.
291
+ * Optional item details shown on the approval screen.
257
292
  * @since 0.1.1
258
293
  * @schema
259
294
  */
260
- title?: string;
295
+ item?: {
296
+ /**
297
+ * Item title shown on the approval screen.
298
+ * @since 0.1.1
299
+ * @schema
300
+ */
301
+ title: string;
302
+ /**
303
+ * Item icon URL shown on the approval screen.
304
+ * @since 0.1.1
305
+ * @schema
306
+ */
307
+ iconUrl: string;
308
+ /**
309
+ * Quantity of items being purchased.
310
+ * @since 0.1.1
311
+ * @schema
312
+ */
313
+ quantity: number;
314
+ };
261
315
  /**
262
- * Item description/caption shown on the approval screen.
316
+ * Test mode. Simulates payment outcomes without real transactions.
317
+ *
318
+ * | Scenario | Client | Webhook |
319
+ * |----------|--------|---------|
320
+ * | `true` / `'paid'` | `paid` | `finalized` |
321
+ * | `'paid:failed'` | `paid` | `failed` |
322
+ * | `'cancelled'` | `cancelled` | none |
323
+ * | `'error:*'` | `failed` | none |
324
+ *
325
+ * **Pre-broadcast errors** (no webhook):
326
+ * `'error:insufficient_balance'`, `'error:network_error'`,
327
+ * `'error:pre_checkout_rejected'`, `'error:pre_checkout_timeout'`,
328
+ * `'error:unknown'`
329
+ *
330
+ * @example
331
+ * // Happy path
332
+ * test: 'paid'
333
+ *
334
+ * // Client shows success, but tx failed on-chain
335
+ * test: 'paid:failed'
336
+ *
337
+ * // User cancelled
338
+ * test: 'cancelled'
339
+ *
340
+ * // Pre-broadcast failure
341
+ * test: 'error:insufficient_balance'
342
+ *
263
343
  * @since 0.1.1
264
344
  * @schema
265
345
  */
266
- caption?: string;
267
- /**
268
- * Item icon URL shown on the approval screen.
269
- * @since 0.1.1
270
- * @schema
271
- */
272
- iconUrl?: string;
273
- /**
274
- * Quantity of items being purchased.
275
- * @since 0.1.1
276
- * @schema
277
- */
278
- quantity?: number;
279
- /**
280
- * Test mode flag. When true, no real payment is processed.
281
- * The approval screen shows a test indicator, and webhooks
282
- * include `test: true`. Use for development and testing.
283
- * @since 0.1.1
284
- * @schema
285
- */
286
- test?: boolean;
346
+ test?: boolean | PaymentTestScenario;
287
347
  }>>;
288
348
  /**
289
349
  * Write text to the system clipboard.
@@ -304,6 +364,44 @@ interface Methods {
304
364
  * @schema
305
365
  */
306
366
  'clipboard:read': CreateMethodPayload<WithReqId<Empty>>;
367
+ /**
368
+ * Open a URL.
369
+ *
370
+ * The host app acts as middleware: parses the URL, checks permissions/auth,
371
+ * and routes to the appropriate handler based on URL and `openMode`.
372
+ *
373
+ * **`external`** (default) - Open outside the host app:
374
+ * - Custom schemes (`solana:`, `mailto:`) → system handler
375
+ * - HTTPS → system browser
376
+ *
377
+ * **`internal`** - Open within the host app:
378
+ * - Miniapp links → open miniapp (handles auth if required)
379
+ * - Other links → in-app webview
380
+ *
381
+ * @example
382
+ * emit('link:open', { url: 'solana:...' });
383
+ * emit('link:open', { url: 'mailto:hi@example.com' });
384
+ * emit('link:open', { url: 'https://example.com', openMode: 'internal' });
385
+ *
386
+ * @since 0.1.3
387
+ * @schema
388
+ */
389
+ 'link:open': CreateMethodPayload<{
390
+ /**
391
+ * The URL to open.
392
+ * @since 0.1.3
393
+ * @schema
394
+ */
395
+ url: string;
396
+ /**
397
+ * Where to open the URL.
398
+ * - `external` (default): System browser or app handler
399
+ * - `internal`: Within the host app (miniapps, webviews)
400
+ * @since 0.1.3
401
+ * @schema
402
+ */
403
+ openMode?: 'external' | 'internal';
404
+ }>;
307
405
  }
308
406
  //#endregion
309
407
  //#region ../contract/src/methods/types/method-types.d.ts
@@ -479,6 +577,58 @@ declare class MethodNotSupportedError extends ReactSDKError {
479
577
  */
480
578
  declare function useAlien(): AlienContextValue;
481
579
  //#endregion
580
+ //#region src/hooks/useClipboard.d.ts
581
+ /** Clipboard error codes from the host app. */
582
+ type ClipboardErrorCode = 'permission_denied' | 'unavailable';
583
+ interface UseClipboardOptions {
584
+ /**
585
+ * Timeout for clipboard read in milliseconds.
586
+ * @default 5000
587
+ */
588
+ timeout?: number;
589
+ }
590
+ interface UseClipboardReturn {
591
+ /** Write text to clipboard. Fire-and-forget. */
592
+ writeText: (text: string) => void;
593
+ /** Read text from clipboard. Returns text or null on failure. */
594
+ readText: () => Promise<string | null>;
595
+ /** Whether a read operation is in progress. */
596
+ isReading: boolean;
597
+ /** Error code from the last failed read operation. */
598
+ errorCode: ClipboardErrorCode | null;
599
+ /** Whether clipboard methods are supported by the host app. */
600
+ supported: boolean;
601
+ }
602
+ /**
603
+ * Hook for clipboard operations.
604
+ *
605
+ * @example
606
+ * ```tsx
607
+ * function ClipboardDemo() {
608
+ * const { writeText, readText, isReading, errorCode, supported } = useClipboard();
609
+ *
610
+ * if (!supported) return null;
611
+ *
612
+ * return (
613
+ * <>
614
+ * <button onClick={() => writeText('Hello!')}>Copy</button>
615
+ * <button
616
+ * onClick={async () => {
617
+ * const text = await readText();
618
+ * if (text !== null) console.log('Pasted:', text);
619
+ * }}
620
+ * disabled={isReading}
621
+ * >
622
+ * Paste
623
+ * </button>
624
+ * {errorCode && <span>Error: {errorCode}</span>}
625
+ * </>
626
+ * );
627
+ * }
628
+ * ```
629
+ */
630
+ declare function useClipboard(options?: UseClipboardOptions): UseClipboardReturn;
631
+ //#endregion
482
632
  //#region src/hooks/useEvent.d.ts
483
633
  type EventCallback<E extends EventName> = (payload: EventPayload<E>) => void;
484
634
  /**
@@ -762,4 +912,4 @@ interface UsePaymentReturn {
762
912
  */
763
913
  declare function usePayment(options?: UsePaymentOptions): UsePaymentReturn;
764
914
  //#endregion
765
- export { AlienProvider, type AlienProviderProps, BridgeError, BridgeTimeoutError, BridgeUnavailableError, BridgeWindowUnavailableError, type EventName, type EventPayload, type MethodName, MethodNotSupportedError, type MethodPayload, type MethodSupportResult, type PaymentCallbacks, type PaymentErrorCode, type PaymentParams, type PaymentResponseStatus, type PaymentResult, type PaymentStatus, ReactSDKError, type RequestOptions, type UseMethodExecuteResult, type UseMethodOptions, type UsePaymentOptions, type UsePaymentReturn, type Version, getMethodMinVersion, isMethodSupported, send, useAlien, useEvent, useIsMethodSupported, useLaunchParams, useMethod, usePayment };
915
+ export { AlienProvider, type AlienProviderProps, BridgeError, BridgeTimeoutError, BridgeUnavailableError, BridgeWindowUnavailableError, type ClipboardErrorCode, type EventName, type EventPayload, type MethodName, MethodNotSupportedError, type MethodPayload, type MethodSupportResult, type PaymentCallbacks, type PaymentErrorCode, type PaymentParams, type PaymentResponseStatus, type PaymentResult, type PaymentStatus, ReactSDKError, type RequestOptions, type UseClipboardOptions, type UseClipboardReturn, type UseMethodExecuteResult, type UseMethodOptions, type UsePaymentOptions, type UsePaymentReturn, type Version, getMethodMinVersion, isMethodSupported, send, useAlien, useClipboard, useEvent, useIsMethodSupported, useLaunchParams, useMethod, usePayment };
package/dist/index.d.mts CHANGED
@@ -33,6 +33,41 @@ type UnionKeys<T> = T extends T ? keyof T : never;
33
33
  * // Empty = {}
34
34
  */
35
35
  type Empty = Record<string, never>;
36
+ /**
37
+ * Client-side payment error codes (pre-broadcast failures).
38
+ * Returned when `status` is `'failed'` in `payment:response`.
39
+ * These errors occur before transaction broadcast, so no webhook is sent.
40
+ * @since 0.1.1
41
+ * @schema
42
+ */
43
+ type PaymentErrorCode$1 = 'insufficient_balance' | 'network_error' | 'pre_checkout_rejected' | 'pre_checkout_timeout' | 'unknown';
44
+ /**
45
+ * Payment test scenarios for simulating different payment outcomes.
46
+ *
47
+ * | Scenario | Client sees | Webhook |
48
+ * |----------|-------------|---------|
49
+ * | `'paid'` | `paid` | `{ status: 'finalized' }` |
50
+ * | `'paid:failed'` | `paid` | `{ status: 'failed' }` |
51
+ * | `'cancelled'` | `cancelled` | none |
52
+ * | `'error:*'` | `failed` | none (pre-broadcast) |
53
+ *
54
+ * @example
55
+ * // Happy path: client paid, tx finalized
56
+ * test: 'paid'
57
+ *
58
+ * // On-chain failure: client paid, tx failed
59
+ * test: 'paid:failed'
60
+ *
61
+ * // User cancelled before confirming
62
+ * test: 'cancelled'
63
+ *
64
+ * // Pre-broadcast error (no tx, no webhook)
65
+ * test: 'error:insufficient_balance'
66
+ *
67
+ * @since 0.1.2
68
+ * @schema
69
+ */
70
+ type PaymentTestScenario = 'paid' | 'paid:failed' | 'cancelled' | `error:${PaymentErrorCode$1}`;
36
71
  //#endregion
37
72
  //#region ../contract/src/events/types/payload.d.ts
38
73
  /**
@@ -80,7 +115,7 @@ interface Events {
80
115
  * Payment status.
81
116
  * - `paid`: Success
82
117
  * - `cancelled`: User rejected
83
- * - `failed`: Error (check `errorCode`)
118
+ * - `failed`: Sending transaction failed (check `errorCode`)
84
119
  * @since 0.1.1
85
120
  * @schema
86
121
  */
@@ -101,7 +136,7 @@ interface Events {
101
136
  * @since 0.1.1
102
137
  * @schema
103
138
  */
104
- errorCode?: 'insufficient_balance' | 'network_error' | 'pre_checkout_rejected' | 'pre_checkout_timeout' | 'unknown';
139
+ errorCode?: PaymentErrorCode$1;
105
140
  }>>;
106
141
  /**
107
142
  * Clipboard read response.
@@ -253,37 +288,62 @@ interface Methods {
253
288
  */
254
289
  invoice: string;
255
290
  /**
256
- * Item title shown on the approval screen.
291
+ * Optional item details shown on the approval screen.
257
292
  * @since 0.1.1
258
293
  * @schema
259
294
  */
260
- title?: string;
295
+ item?: {
296
+ /**
297
+ * Item title shown on the approval screen.
298
+ * @since 0.1.1
299
+ * @schema
300
+ */
301
+ title: string;
302
+ /**
303
+ * Item icon URL shown on the approval screen.
304
+ * @since 0.1.1
305
+ * @schema
306
+ */
307
+ iconUrl: string;
308
+ /**
309
+ * Quantity of items being purchased.
310
+ * @since 0.1.1
311
+ * @schema
312
+ */
313
+ quantity: number;
314
+ };
261
315
  /**
262
- * Item description/caption shown on the approval screen.
316
+ * Test mode. Simulates payment outcomes without real transactions.
317
+ *
318
+ * | Scenario | Client | Webhook |
319
+ * |----------|--------|---------|
320
+ * | `true` / `'paid'` | `paid` | `finalized` |
321
+ * | `'paid:failed'` | `paid` | `failed` |
322
+ * | `'cancelled'` | `cancelled` | none |
323
+ * | `'error:*'` | `failed` | none |
324
+ *
325
+ * **Pre-broadcast errors** (no webhook):
326
+ * `'error:insufficient_balance'`, `'error:network_error'`,
327
+ * `'error:pre_checkout_rejected'`, `'error:pre_checkout_timeout'`,
328
+ * `'error:unknown'`
329
+ *
330
+ * @example
331
+ * // Happy path
332
+ * test: 'paid'
333
+ *
334
+ * // Client shows success, but tx failed on-chain
335
+ * test: 'paid:failed'
336
+ *
337
+ * // User cancelled
338
+ * test: 'cancelled'
339
+ *
340
+ * // Pre-broadcast failure
341
+ * test: 'error:insufficient_balance'
342
+ *
263
343
  * @since 0.1.1
264
344
  * @schema
265
345
  */
266
- caption?: string;
267
- /**
268
- * Item icon URL shown on the approval screen.
269
- * @since 0.1.1
270
- * @schema
271
- */
272
- iconUrl?: string;
273
- /**
274
- * Quantity of items being purchased.
275
- * @since 0.1.1
276
- * @schema
277
- */
278
- quantity?: number;
279
- /**
280
- * Test mode flag. When true, no real payment is processed.
281
- * The approval screen shows a test indicator, and webhooks
282
- * include `test: true`. Use for development and testing.
283
- * @since 0.1.1
284
- * @schema
285
- */
286
- test?: boolean;
346
+ test?: boolean | PaymentTestScenario;
287
347
  }>>;
288
348
  /**
289
349
  * Write text to the system clipboard.
@@ -304,6 +364,44 @@ interface Methods {
304
364
  * @schema
305
365
  */
306
366
  'clipboard:read': CreateMethodPayload<WithReqId<Empty>>;
367
+ /**
368
+ * Open a URL.
369
+ *
370
+ * The host app acts as middleware: parses the URL, checks permissions/auth,
371
+ * and routes to the appropriate handler based on URL and `openMode`.
372
+ *
373
+ * **`external`** (default) - Open outside the host app:
374
+ * - Custom schemes (`solana:`, `mailto:`) → system handler
375
+ * - HTTPS → system browser
376
+ *
377
+ * **`internal`** - Open within the host app:
378
+ * - Miniapp links → open miniapp (handles auth if required)
379
+ * - Other links → in-app webview
380
+ *
381
+ * @example
382
+ * emit('link:open', { url: 'solana:...' });
383
+ * emit('link:open', { url: 'mailto:hi@example.com' });
384
+ * emit('link:open', { url: 'https://example.com', openMode: 'internal' });
385
+ *
386
+ * @since 0.1.3
387
+ * @schema
388
+ */
389
+ 'link:open': CreateMethodPayload<{
390
+ /**
391
+ * The URL to open.
392
+ * @since 0.1.3
393
+ * @schema
394
+ */
395
+ url: string;
396
+ /**
397
+ * Where to open the URL.
398
+ * - `external` (default): System browser or app handler
399
+ * - `internal`: Within the host app (miniapps, webviews)
400
+ * @since 0.1.3
401
+ * @schema
402
+ */
403
+ openMode?: 'external' | 'internal';
404
+ }>;
307
405
  }
308
406
  //#endregion
309
407
  //#region ../contract/src/methods/types/method-types.d.ts
@@ -479,6 +577,58 @@ declare class MethodNotSupportedError extends ReactSDKError {
479
577
  */
480
578
  declare function useAlien(): AlienContextValue;
481
579
  //#endregion
580
+ //#region src/hooks/useClipboard.d.ts
581
+ /** Clipboard error codes from the host app. */
582
+ type ClipboardErrorCode = 'permission_denied' | 'unavailable';
583
+ interface UseClipboardOptions {
584
+ /**
585
+ * Timeout for clipboard read in milliseconds.
586
+ * @default 5000
587
+ */
588
+ timeout?: number;
589
+ }
590
+ interface UseClipboardReturn {
591
+ /** Write text to clipboard. Fire-and-forget. */
592
+ writeText: (text: string) => void;
593
+ /** Read text from clipboard. Returns text or null on failure. */
594
+ readText: () => Promise<string | null>;
595
+ /** Whether a read operation is in progress. */
596
+ isReading: boolean;
597
+ /** Error code from the last failed read operation. */
598
+ errorCode: ClipboardErrorCode | null;
599
+ /** Whether clipboard methods are supported by the host app. */
600
+ supported: boolean;
601
+ }
602
+ /**
603
+ * Hook for clipboard operations.
604
+ *
605
+ * @example
606
+ * ```tsx
607
+ * function ClipboardDemo() {
608
+ * const { writeText, readText, isReading, errorCode, supported } = useClipboard();
609
+ *
610
+ * if (!supported) return null;
611
+ *
612
+ * return (
613
+ * <>
614
+ * <button onClick={() => writeText('Hello!')}>Copy</button>
615
+ * <button
616
+ * onClick={async () => {
617
+ * const text = await readText();
618
+ * if (text !== null) console.log('Pasted:', text);
619
+ * }}
620
+ * disabled={isReading}
621
+ * >
622
+ * Paste
623
+ * </button>
624
+ * {errorCode && <span>Error: {errorCode}</span>}
625
+ * </>
626
+ * );
627
+ * }
628
+ * ```
629
+ */
630
+ declare function useClipboard(options?: UseClipboardOptions): UseClipboardReturn;
631
+ //#endregion
482
632
  //#region src/hooks/useEvent.d.ts
483
633
  type EventCallback<E extends EventName> = (payload: EventPayload<E>) => void;
484
634
  /**
@@ -762,4 +912,4 @@ interface UsePaymentReturn {
762
912
  */
763
913
  declare function usePayment(options?: UsePaymentOptions): UsePaymentReturn;
764
914
  //#endregion
765
- export { AlienProvider, type AlienProviderProps, BridgeError, BridgeTimeoutError, BridgeUnavailableError, BridgeWindowUnavailableError, type EventName, type EventPayload, type MethodName, MethodNotSupportedError, type MethodPayload, type MethodSupportResult, type PaymentCallbacks, type PaymentErrorCode, type PaymentParams, type PaymentResponseStatus, type PaymentResult, type PaymentStatus, ReactSDKError, type RequestOptions, type UseMethodExecuteResult, type UseMethodOptions, type UsePaymentOptions, type UsePaymentReturn, type Version, getMethodMinVersion, isMethodSupported, send, useAlien, useEvent, useIsMethodSupported, useLaunchParams, useMethod, usePayment };
915
+ export { AlienProvider, type AlienProviderProps, BridgeError, BridgeTimeoutError, BridgeUnavailableError, BridgeWindowUnavailableError, type ClipboardErrorCode, type EventName, type EventPayload, type MethodName, MethodNotSupportedError, type MethodPayload, type MethodSupportResult, type PaymentCallbacks, type PaymentErrorCode, type PaymentParams, type PaymentResponseStatus, type PaymentResult, type PaymentStatus, ReactSDKError, type RequestOptions, type UseClipboardOptions, type UseClipboardReturn, type UseMethodExecuteResult, type UseMethodOptions, type UsePaymentOptions, type UsePaymentReturn, type Version, getMethodMinVersion, isMethodSupported, send, useAlien, useClipboard, useEvent, useIsMethodSupported, useLaunchParams, useMethod, usePayment };
package/dist/index.mjs CHANGED
@@ -91,6 +91,84 @@ function useAlien() {
91
91
  return context;
92
92
  }
93
93
 
94
+ //#endregion
95
+ //#region src/hooks/useClipboard.ts
96
+ /**
97
+ * Hook for clipboard operations.
98
+ *
99
+ * @example
100
+ * ```tsx
101
+ * function ClipboardDemo() {
102
+ * const { writeText, readText, isReading, errorCode, supported } = useClipboard();
103
+ *
104
+ * if (!supported) return null;
105
+ *
106
+ * return (
107
+ * <>
108
+ * <button onClick={() => writeText('Hello!')}>Copy</button>
109
+ * <button
110
+ * onClick={async () => {
111
+ * const text = await readText();
112
+ * if (text !== null) console.log('Pasted:', text);
113
+ * }}
114
+ * disabled={isReading}
115
+ * >
116
+ * Paste
117
+ * </button>
118
+ * {errorCode && <span>Error: {errorCode}</span>}
119
+ * </>
120
+ * );
121
+ * }
122
+ * ```
123
+ */
124
+ function useClipboard(options = {}) {
125
+ const { timeout = 5e3 } = options;
126
+ const { contractVersion, isBridgeAvailable: isBridgeAvailable$1 } = useAlien();
127
+ const [isReading, setIsReading] = useState(false);
128
+ const [errorCode, setErrorCode] = useState(null);
129
+ const supported = contractVersion ? isMethodSupported$1("clipboard:write", contractVersion) && isMethodSupported$1("clipboard:read", contractVersion) : true;
130
+ const writeText = useCallback((text) => {
131
+ if (!isBridgeAvailable$1) return;
132
+ if (contractVersion && !isMethodSupported$1("clipboard:write", contractVersion)) return;
133
+ send$1("clipboard:write", { text });
134
+ }, [isBridgeAvailable$1, contractVersion]);
135
+ const readText = useCallback(async () => {
136
+ if (!isBridgeAvailable$1) return null;
137
+ if (contractVersion && !isMethodSupported$1("clipboard:read", contractVersion)) return null;
138
+ setIsReading(true);
139
+ setErrorCode(null);
140
+ try {
141
+ const response = await request("clipboard:read", {}, "clipboard:response", { timeout });
142
+ if (response.errorCode) {
143
+ setErrorCode(response.errorCode);
144
+ return null;
145
+ }
146
+ return response.text;
147
+ } catch {
148
+ return null;
149
+ } finally {
150
+ setIsReading(false);
151
+ }
152
+ }, [
153
+ isBridgeAvailable$1,
154
+ contractVersion,
155
+ timeout
156
+ ]);
157
+ return useMemo(() => ({
158
+ writeText,
159
+ readText,
160
+ isReading,
161
+ errorCode,
162
+ supported
163
+ }), [
164
+ writeText,
165
+ readText,
166
+ isReading,
167
+ errorCode,
168
+ supported
169
+ ]);
170
+ }
171
+
94
172
  //#endregion
95
173
  //#region src/hooks/useEvent.ts
96
174
  /**
@@ -513,4 +591,4 @@ function usePayment(options = {}) {
513
591
  }
514
592
 
515
593
  //#endregion
516
- export { AlienProvider, BridgeError, BridgeTimeoutError, BridgeUnavailableError, BridgeWindowUnavailableError, MethodNotSupportedError, ReactSDKError, getMethodMinVersion, isMethodSupported, send, useAlien, useEvent, useIsMethodSupported, useLaunchParams, useMethod, usePayment };
594
+ export { AlienProvider, BridgeError, BridgeTimeoutError, BridgeUnavailableError, BridgeWindowUnavailableError, MethodNotSupportedError, ReactSDKError, getMethodMinVersion, isMethodSupported, send, useAlien, useClipboard, useEvent, useIsMethodSupported, useLaunchParams, useMethod, usePayment };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@alien_org/react",
3
- "version": "0.1.2",
3
+ "version": "0.1.4",
4
4
  "type": "module",
5
5
  "main": "./dist/index.cjs",
6
6
  "module": "./dist/index.mjs",
@@ -34,8 +34,8 @@
34
34
  "prepublishOnly": "bun run build"
35
35
  },
36
36
  "dependencies": {
37
- "@alien_org/bridge": "0.1.1",
38
- "@alien_org/contract": "0.1.1"
37
+ "@alien_org/bridge": "0.1.2",
38
+ "@alien_org/contract": "0.1.4"
39
39
  },
40
40
  "peerDependencies": {
41
41
  "react": "^18 || ^19",