@tuwaio/quasar-sdk 0.5.0 → 0.7.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 CHANGED
@@ -23,10 +23,10 @@
23
23
  pnpm add @tuwaio/quasar-sdk @tuwaio/pulsar-core
24
24
  ```
25
25
 
26
- | Import path | Provides | Peer dependencies |
27
- | -------------------------- | ---------------------------------------------------------------------------- | -------------------------------------------------------- |
28
- | `@tuwaio/quasar-sdk` | `Quasar`, `PulsarModule`, `QuasarSDKError`, the endpoint constants and types | `@tuwaio/pulsar-core` (>=0.9), for the transaction types |
29
- | `@tuwaio/quasar-sdk/react` | `preFlightTxCheck` | Also `@tuwaio/siwx-react` (>=0.5, optional for the root) |
26
+ | Import path | Provides | Peer dependencies |
27
+ | -------------------------- | ------------------------------------------------------------------------------------------------ | --------------------------------------------------------- |
28
+ | `@tuwaio/quasar-sdk` | `Quasar`, `PulsarModule`, `watchBatchHashes`, `QuasarSDKError`, the endpoint constants and types | `@tuwaio/pulsar-core` (>=0.10), for the transaction types |
29
+ | `@tuwaio/quasar-sdk/react` | `preFlightTxCheck` | Also `@tuwaio/siwx-react` (>=0.5, optional for the root) |
30
30
 
31
31
  The root entry point imports neither React nor SIWX packages, so it runs in Node.js, Next.js Server Actions and route handlers, and Edge runtimes. Its HTTP client, `ofetch`, is a dependency.
32
32
 
@@ -55,6 +55,25 @@ export async function getHistory(walletAddress: string, page = 1) {
55
55
 
56
56
  Before calling Quasar for a user, check on the server that the user owns the wallet (for example with `getSiwxServerSession` and `isSessionMatchingTarget` from `@tuwaio/siwx-server`), so nobody can sync or read the transactions of another address. The complete flow — SIWX sessions, the Pulsar callbacks `onRemoteCreate` and `beforeTxProcess`, the history in Nova Transactions — is the **[Quasar transaction sync guide](https://docs.tuwa.io/guides/quasar-transaction-sync)**; Quasar itself (apps and keys, quotas, webhooks, self-hosting) is described in the **[Quasar docs](https://docs.tuwa.io/quasar)**.
57
57
 
58
+ ### EIP-5792 batches
59
+
60
+ A batch of calls sent with `wallet_sendCalls` (`TransactionTracker.EIP5792`) is synced by its batch ID; Quasar tracks it on-chain once it gets the hash of the transaction that executed the batch, and marks it `Failed` an hour after the sync if the hash never arrives. Pulsar learns the hash in the browser, so watch the store there and send each hash through a Server Action:
61
+
62
+ ```ts
63
+ 'use server';
64
+
65
+ export async function syncBatchHash(txKey: string, hash: `0x${string}`) {
66
+ await quasar.pulsar.syncHash(txKey, hash);
67
+ }
68
+ ```
69
+
70
+ ```ts
71
+ import { watchBatchHashes } from '@tuwaio/quasar-sdk';
72
+
73
+ // In the browser, next to the Pulsar store
74
+ const stop = watchBatchHashes(pulsarStore, (tx) => syncBatchHash(tx.txKey, tx.hash));
75
+ ```
76
+
58
77
  ### Webhook relay
59
78
 
60
79
  Add a webhook endpoint with a `localhost` URL in the Quasar dashboard, put its signing secret in `.env.local` and start the relay next to your dev server:
@@ -85,7 +104,7 @@ Nothing is written. `preFlightTxCheck` reads the SIWX session from the store of
85
104
 
86
105
  | Part | Host | Request |
87
106
  | ------------------- | ---------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
88
- | `Quasar` client | `baseUrl` (default `https://api.tuwa.io`) | `POST /v1/engine/pulsar/sync` and `GET /v1/engine/pulsar/history`, with the secret key in the `x-tuwa-secret-key` header |
107
+ | `Quasar` client | `baseUrl` (default `https://api.tuwa.io`) | `POST /v1/engine/pulsar/sync`, `POST /v1/engine/pulsar/sync/:txKey/hash` and `GET /v1/engine/pulsar/history`, with the secret key in the `x-tuwa-secret-key` header |
89
108
  | `preFlightTxCheck` | Its `customApiUrl` (default `https://api.tuwa.io`) | `GET /v1/engine/monitoring/health`, without credentials |
90
109
  | `quasar-sdk listen` | `--api-url` (default `https://api.tuwa.io`), then `--forward-to` | A Server-Sent Events stream from `/v1/engine/webhooks/listen` with the signing secret in the `x-webhook-secret` header; a `POST` to the local URL for each delivery |
91
110
 
@@ -0,0 +1,2 @@
1
+ 'use strict';var o="https://api.tuwa.io",t="/v1/engine/pulsar/sync",s="/v1/engine/pulsar/history",e=n=>`${t}/${encodeURIComponent(n)}/hash`;
2
+ exports.a=o;exports.b=t;exports.c=s;exports.d=e;
@@ -0,0 +1,2 @@
1
+ var o="https://api.tuwa.io",t="/v1/engine/pulsar/sync",s="/v1/engine/pulsar/history",e=n=>`${t}/${encodeURIComponent(n)}/hash`;
2
+ export{o as a,t as b,s as c,e as d};
package/dist/cli.cjs CHANGED
@@ -48,7 +48,7 @@ var path = __toESM(require("path"), 1);
48
48
  // package.json
49
49
  var package_default = {
50
50
  name: "@tuwaio/quasar-sdk",
51
- version: "0.5.0",
51
+ version: "0.7.0",
52
52
  private: false,
53
53
  author: "Oleksandr Tkach",
54
54
  license: "Apache-2.0",
@@ -122,7 +122,7 @@ var package_default = {
122
122
  ofetch: "^1.5.1"
123
123
  },
124
124
  peerDependencies: {
125
- "@tuwaio/pulsar-core": ">=0.9",
125
+ "@tuwaio/pulsar-core": ">=0.10",
126
126
  "@tuwaio/siwx-react": ">=0.5"
127
127
  },
128
128
  peerDependenciesMeta: {
@@ -131,8 +131,8 @@ var package_default = {
131
131
  }
132
132
  },
133
133
  devDependencies: {
134
- "@tuwaio/pulsar-core": "^0.10.0",
135
- tsup: "^8.5.1",
134
+ "@tuwaio/pulsar-core": "^0.10.1",
135
+ tsup: "^9.0.0",
136
136
  typescript: "6.0.3",
137
137
  "@tuwaio/siwx-react": "^0.6.2"
138
138
  }
package/dist/index.cjs CHANGED
@@ -1 +1 @@
1
- 'use strict';var chunkNJH5FYLU_cjs=require('./chunk-NJH5FYLU.cjs'),ofetch=require('ofetch'),pulsarCore=require('@tuwaio/pulsar-core');var a=class extends Error{status;originalError;constructor(r,e,t){super(r),this.name="QuasarSDKError",this.status=e,this.originalError=t;}},o=class{secretKey;internalSecret;baseUrl;timeout;constructor(r){if(!r.secretKey)throw new Error("[Quasar SDK] Missing API Key. Provide the secretKey of your Quasar app (sk_live_ or sk_test_).");this.secretKey=r.secretKey,this.internalSecret=r.internalSecret,this.baseUrl=r.baseUrl||chunkNJH5FYLU_cjs.a,this.timeout=r.timeout||1e4;}async request(r,e={}){try{return await ofetch.ofetch(r,{baseURL:this.baseUrl,timeout:this.timeout,...e,headers:{"Content-Type":"application/json","x-tuwa-secret-key":this.secretKey,...this.internalSecret?{"x-internal-secret":this.internalSecret}:{},...e.headers}})}catch(t){throw this.buildError(t)}}buildError(r){let e=r,t=e.statusCode??e.response?.status,p=(e.data??e.response?._data)?.error??e.message??"Unknown Error";return (t===401||t===403)&&console.error("\u{1F6A8} [Quasar SDK] Auth Error. Check your Secret Key and scopes."),new a(`[Quasar SDK] Request Failed (${t}): ${p}`,t,e)}};var s=class{constructor(r){this.client=r;}client;async syncCreate(r,e){return this.client.request(chunkNJH5FYLU_cjs.b,{method:"POST",body:{...r,appName:e}})}async getHistory(r={}){return this.client.request(chunkNJH5FYLU_cjs.c,{method:"GET",query:{page:r.page??1,limit:r.limit??10,chainId:r.chainId,status:r.status,txKey:r.txKey,appName:r.appName,walletAddress:r.walletAddress}})}};var n=class{client;pulsar;constructor(r){this.client=new o(r),this.pulsar=new s(this.client);}};Object.defineProperty(exports,"BASE_API_URL",{enumerable:true,get:function(){return chunkNJH5FYLU_cjs.a}});Object.defineProperty(exports,"PULSAR_HISTORY_ENDPOINT",{enumerable:true,get:function(){return chunkNJH5FYLU_cjs.c}});Object.defineProperty(exports,"PULSAR_SYNC_ENDPOINT",{enumerable:true,get:function(){return chunkNJH5FYLU_cjs.b}});Object.defineProperty(exports,"TransactionStatus",{enumerable:true,get:function(){return pulsarCore.TransactionStatus}});Object.defineProperty(exports,"TransactionTracker",{enumerable:true,get:function(){return pulsarCore.TransactionTracker}});exports.PulsarModule=s;exports.Quasar=n;exports.QuasarSDKError=a;
1
+ 'use strict';var chunk7EJ6DS4C_cjs=require('./chunk-7EJ6DS4C.cjs'),ofetch=require('ofetch'),pulsarCore=require('@tuwaio/pulsar-core');var c=class extends Error{status;originalError;constructor(t,e,r){super(t),this.name="QuasarSDKError",this.status=e,this.originalError=r;}},u=class{secretKey;internalSecret;baseUrl;timeout;constructor(t){if(!t.secretKey)throw new Error("[Quasar SDK] Missing API Key. Provide the secretKey of your Quasar app (sk_live_ or sk_test_).");this.secretKey=t.secretKey,this.internalSecret=t.internalSecret,this.baseUrl=t.baseUrl||chunk7EJ6DS4C_cjs.a,this.timeout=t.timeout||1e4;}async request(t,e={}){try{return await ofetch.ofetch(t,{baseURL:this.baseUrl,timeout:this.timeout,...e,headers:{"Content-Type":"application/json","x-tuwa-secret-key":this.secretKey,...this.internalSecret?{"x-internal-secret":this.internalSecret}:{},...e.headers}})}catch(r){throw this.buildError(r)}}buildError(t){let e=t,r=e.statusCode??e.response?.status,l=(e.data??e.response?._data)?.error??e.message??"Unknown Error";return (r===401||r===403)&&console.error("\u{1F6A8} [Quasar SDK] Auth Error. Check your Secret Key and scopes."),new c(`[Quasar SDK] Request Failed (${r}): ${l}`,r,e)}};var o=class{constructor(t){this.client=t;}client;async syncCreate(t,e){return this.client.request(chunk7EJ6DS4C_cjs.b,{method:"POST",body:{...t,appName:e}})}async syncHash(t,e){return this.client.request(chunk7EJ6DS4C_cjs.d(t),{method:"POST",body:{hash:e}})}async getHistory(t={}){return this.client.request(chunk7EJ6DS4C_cjs.c,{method:"GET",query:{page:t.page??1,limit:t.limit??10,chainId:t.chainId,status:t.status,txKey:t.txKey,appName:t.appName,walletAddress:t.walletAddress}})}};var P=3600;function T(s,t){let e=new Set,r=n=>{let l=Math.floor(Date.now()/1e3)-P;for(let a of Object.values(n)){let p=a.hash;if(a.tracker!==pulsarCore.TransactionTracker.EIP5792||!p||a.syncStatus==="pending-sync"||a.localTimestamp<l)continue;let i=`${a.txKey}:${p}`;if(!e.has(i)){e.add(i);try{Promise.resolve(t({...a,hash:p})).catch(()=>e.delete(i));}catch{e.delete(i);}}}};return r(s.getState().transactionsPool),s.subscribe(n=>r(n.transactionsPool))}var d=class{client;pulsar;constructor(t){this.client=new u(t),this.pulsar=new o(this.client);}};Object.defineProperty(exports,"BASE_API_URL",{enumerable:true,get:function(){return chunk7EJ6DS4C_cjs.a}});Object.defineProperty(exports,"PULSAR_HISTORY_ENDPOINT",{enumerable:true,get:function(){return chunk7EJ6DS4C_cjs.c}});Object.defineProperty(exports,"PULSAR_SYNC_ENDPOINT",{enumerable:true,get:function(){return chunk7EJ6DS4C_cjs.b}});Object.defineProperty(exports,"pulsarSyncHashEndpoint",{enumerable:true,get:function(){return chunk7EJ6DS4C_cjs.d}});Object.defineProperty(exports,"TransactionStatus",{enumerable:true,get:function(){return pulsarCore.TransactionStatus}});Object.defineProperty(exports,"TransactionTracker",{enumerable:true,get:function(){return pulsarCore.TransactionTracker}});exports.PulsarModule=o;exports.Quasar=d;exports.QuasarSDKError=c;exports.watchBatchHashes=T;
package/dist/index.d.cts CHANGED
@@ -11,6 +11,13 @@ declare const BASE_API_URL = "https://api.tuwa.io";
11
11
  declare const PULSAR_SYNC_ENDPOINT = "/v1/engine/pulsar/sync";
12
12
  /** Path of the endpoint that `PulsarModule.getHistory` calls (`GET`). */
13
13
  declare const PULSAR_HISTORY_ENDPOINT = "/v1/engine/pulsar/history";
14
+ /**
15
+ * Path of the endpoint that `PulsarModule.syncHash` calls (`POST`) for the EIP-5792 batch with this `txKey`.
16
+ *
17
+ * @param txKey - The batch ID, the `txKey` of the transaction.
18
+ * @returns The path, with the batch ID URL-encoded.
19
+ */
20
+ declare const pulsarSyncHashEndpoint: (txKey: string) => string;
14
21
 
15
22
  /**
16
23
  * @file Configuration, query and response types of the Quasar client, and the Pulsar transaction types it syncs.
@@ -205,6 +212,32 @@ declare class PulsarModule {
205
212
  mode: 'fast' | 'lazy';
206
213
  duplicate?: true;
207
214
  }>;
215
+ /**
216
+ * Sends the hash of the transaction that executed an EIP-5792 batch (`POST /v1/engine/pulsar/sync/:txKey/hash`). A
217
+ * batch is synced by its batch ID (`TransactionTracker.EIP5792`), which only the wallet can resolve; with the hash,
218
+ * Quasar tracks it on-chain until it reaches a final status. Get the hashes in the browser with
219
+ * {@link watchBatchHashes} and send each through a Server Action. Without a hash, Quasar marks the batch `Failed`
220
+ * an hour after it was synced.
221
+ *
222
+ * @param txKey - The batch ID, the `txKey` of the transaction.
223
+ * @param hash - The hash of the transaction that executed the batch (`hash` that Pulsar writes to it).
224
+ * @returns `duplicate: true` when Quasar already had this hash.
225
+ * @throws {QuasarSDKError} On a malformed hash or a transaction that is not a batch (400), an invalid key (401, 403),
226
+ * an unknown batch (404), a batch that has another hash or is already final (409), a timeout or a network error.
227
+ *
228
+ * @example
229
+ * ```ts
230
+ * export async function syncBatchHash(txKey: string, hash: `0x${string}`) {
231
+ * await quasar.pulsar.syncHash(txKey, hash);
232
+ * }
233
+ * ```
234
+ */
235
+ syncHash(txKey: string, hash: `0x${string}`): Promise<{
236
+ success: true;
237
+ txKey: string;
238
+ hash: `0x${string}`;
239
+ duplicate?: true;
240
+ }>;
208
241
  /**
209
242
  * Reads the transactions of your app, newest first (`GET /v1/engine/pulsar/history`).
210
243
  *
@@ -223,6 +256,51 @@ declare class PulsarModule {
223
256
  getHistory(query?: HistoryQuery): Promise<PaginatedResult<Transaction>>;
224
257
  }
225
258
 
259
+ /**
260
+ * @file Hashes of EIP-5792 batches, read from a Pulsar store in the browser.
261
+ */
262
+
263
+ /**
264
+ * The part of a Pulsar store that {@link watchBatchHashes} reads: the store returned by `createPulsarStore` of
265
+ * `@tuwaio/pulsar-core` has it.
266
+ *
267
+ * @typeParam T - The transaction type of the store.
268
+ */
269
+ interface PulsarPoolStore<T extends Transaction> {
270
+ /** Returns the current state of the store. */
271
+ getState: () => {
272
+ transactionsPool: Record<string, T>;
273
+ };
274
+ /** Calls `listener` with the new state on every change; returns the function that removes it. */
275
+ subscribe: (listener: (state: {
276
+ transactionsPool: Record<string, T>;
277
+ }) => void) => () => void;
278
+ }
279
+ /**
280
+ * Watches a Pulsar store for EIP-5792 batches whose transaction became known and calls `onHash` once for each, so the
281
+ * app can send the hash to Quasar with `PulsarModule.syncHash` (through a Server Action, since that call needs the
282
+ * secret key). A batch is reported once Quasar has it (`syncStatus: 'synced'`) and Pulsar wrote its `hash`; batches
283
+ * created more than an hour ago are skipped, because Quasar no longer waits for them. When `onHash` rejects, the batch
284
+ * is reported again on the next change of the store.
285
+ *
286
+ * Side effects: subscribes to the store until the returned function is called; keeps the reported batch IDs in memory.
287
+ *
288
+ * @param store - The Pulsar store, for example the one `createPulsarStore` returns.
289
+ * @param onHash - Called with each batch and its hash; return its promise so a failure is retried.
290
+ * @returns A function that stops watching.
291
+ *
292
+ * @example
293
+ * ```ts
294
+ * import { watchBatchHashes } from '@tuwaio/quasar-sdk';
295
+ *
296
+ * // In the browser, next to the store; `syncBatchHash` is a Server Action that calls `quasar.pulsar.syncHash`
297
+ * const stop = watchBatchHashes(pulsarStore, (tx) => syncBatchHash(tx.txKey, tx.hash));
298
+ * ```
299
+ */
300
+ declare function watchBatchHashes<T extends Transaction>(store: PulsarPoolStore<T>, onHash: (tx: T & {
301
+ hash: `0x${string}`;
302
+ }) => void | Promise<void>): () => void;
303
+
226
304
  /**
227
305
  * @file The `Quasar` client, the entry point of the Quasar API.
228
306
  */
@@ -257,4 +335,5 @@ declare class Quasar {
257
335
  constructor(config: QuasarConfig);
258
336
  }
259
337
 
260
- export { BASE_API_URL, type HistoryQuery, PULSAR_HISTORY_ENDPOINT, PULSAR_SYNC_ENDPOINT, type PaginatedResult, PulsarModule, Quasar, type QuasarConfig, QuasarSDKError };
338
+ export { BASE_API_URL, PULSAR_HISTORY_ENDPOINT, PULSAR_SYNC_ENDPOINT, PulsarModule, Quasar, QuasarSDKError, pulsarSyncHashEndpoint, watchBatchHashes };
339
+ export type { HistoryQuery, PaginatedResult, PulsarPoolStore, QuasarConfig };
package/dist/index.d.ts CHANGED
@@ -11,6 +11,13 @@ declare const BASE_API_URL = "https://api.tuwa.io";
11
11
  declare const PULSAR_SYNC_ENDPOINT = "/v1/engine/pulsar/sync";
12
12
  /** Path of the endpoint that `PulsarModule.getHistory` calls (`GET`). */
13
13
  declare const PULSAR_HISTORY_ENDPOINT = "/v1/engine/pulsar/history";
14
+ /**
15
+ * Path of the endpoint that `PulsarModule.syncHash` calls (`POST`) for the EIP-5792 batch with this `txKey`.
16
+ *
17
+ * @param txKey - The batch ID, the `txKey` of the transaction.
18
+ * @returns The path, with the batch ID URL-encoded.
19
+ */
20
+ declare const pulsarSyncHashEndpoint: (txKey: string) => string;
14
21
 
15
22
  /**
16
23
  * @file Configuration, query and response types of the Quasar client, and the Pulsar transaction types it syncs.
@@ -205,6 +212,32 @@ declare class PulsarModule {
205
212
  mode: 'fast' | 'lazy';
206
213
  duplicate?: true;
207
214
  }>;
215
+ /**
216
+ * Sends the hash of the transaction that executed an EIP-5792 batch (`POST /v1/engine/pulsar/sync/:txKey/hash`). A
217
+ * batch is synced by its batch ID (`TransactionTracker.EIP5792`), which only the wallet can resolve; with the hash,
218
+ * Quasar tracks it on-chain until it reaches a final status. Get the hashes in the browser with
219
+ * {@link watchBatchHashes} and send each through a Server Action. Without a hash, Quasar marks the batch `Failed`
220
+ * an hour after it was synced.
221
+ *
222
+ * @param txKey - The batch ID, the `txKey` of the transaction.
223
+ * @param hash - The hash of the transaction that executed the batch (`hash` that Pulsar writes to it).
224
+ * @returns `duplicate: true` when Quasar already had this hash.
225
+ * @throws {QuasarSDKError} On a malformed hash or a transaction that is not a batch (400), an invalid key (401, 403),
226
+ * an unknown batch (404), a batch that has another hash or is already final (409), a timeout or a network error.
227
+ *
228
+ * @example
229
+ * ```ts
230
+ * export async function syncBatchHash(txKey: string, hash: `0x${string}`) {
231
+ * await quasar.pulsar.syncHash(txKey, hash);
232
+ * }
233
+ * ```
234
+ */
235
+ syncHash(txKey: string, hash: `0x${string}`): Promise<{
236
+ success: true;
237
+ txKey: string;
238
+ hash: `0x${string}`;
239
+ duplicate?: true;
240
+ }>;
208
241
  /**
209
242
  * Reads the transactions of your app, newest first (`GET /v1/engine/pulsar/history`).
210
243
  *
@@ -223,6 +256,51 @@ declare class PulsarModule {
223
256
  getHistory(query?: HistoryQuery): Promise<PaginatedResult<Transaction>>;
224
257
  }
225
258
 
259
+ /**
260
+ * @file Hashes of EIP-5792 batches, read from a Pulsar store in the browser.
261
+ */
262
+
263
+ /**
264
+ * The part of a Pulsar store that {@link watchBatchHashes} reads: the store returned by `createPulsarStore` of
265
+ * `@tuwaio/pulsar-core` has it.
266
+ *
267
+ * @typeParam T - The transaction type of the store.
268
+ */
269
+ interface PulsarPoolStore<T extends Transaction> {
270
+ /** Returns the current state of the store. */
271
+ getState: () => {
272
+ transactionsPool: Record<string, T>;
273
+ };
274
+ /** Calls `listener` with the new state on every change; returns the function that removes it. */
275
+ subscribe: (listener: (state: {
276
+ transactionsPool: Record<string, T>;
277
+ }) => void) => () => void;
278
+ }
279
+ /**
280
+ * Watches a Pulsar store for EIP-5792 batches whose transaction became known and calls `onHash` once for each, so the
281
+ * app can send the hash to Quasar with `PulsarModule.syncHash` (through a Server Action, since that call needs the
282
+ * secret key). A batch is reported once Quasar has it (`syncStatus: 'synced'`) and Pulsar wrote its `hash`; batches
283
+ * created more than an hour ago are skipped, because Quasar no longer waits for them. When `onHash` rejects, the batch
284
+ * is reported again on the next change of the store.
285
+ *
286
+ * Side effects: subscribes to the store until the returned function is called; keeps the reported batch IDs in memory.
287
+ *
288
+ * @param store - The Pulsar store, for example the one `createPulsarStore` returns.
289
+ * @param onHash - Called with each batch and its hash; return its promise so a failure is retried.
290
+ * @returns A function that stops watching.
291
+ *
292
+ * @example
293
+ * ```ts
294
+ * import { watchBatchHashes } from '@tuwaio/quasar-sdk';
295
+ *
296
+ * // In the browser, next to the store; `syncBatchHash` is a Server Action that calls `quasar.pulsar.syncHash`
297
+ * const stop = watchBatchHashes(pulsarStore, (tx) => syncBatchHash(tx.txKey, tx.hash));
298
+ * ```
299
+ */
300
+ declare function watchBatchHashes<T extends Transaction>(store: PulsarPoolStore<T>, onHash: (tx: T & {
301
+ hash: `0x${string}`;
302
+ }) => void | Promise<void>): () => void;
303
+
226
304
  /**
227
305
  * @file The `Quasar` client, the entry point of the Quasar API.
228
306
  */
@@ -257,4 +335,5 @@ declare class Quasar {
257
335
  constructor(config: QuasarConfig);
258
336
  }
259
337
 
260
- export { BASE_API_URL, type HistoryQuery, PULSAR_HISTORY_ENDPOINT, PULSAR_SYNC_ENDPOINT, type PaginatedResult, PulsarModule, Quasar, type QuasarConfig, QuasarSDKError };
338
+ export { BASE_API_URL, PULSAR_HISTORY_ENDPOINT, PULSAR_SYNC_ENDPOINT, PulsarModule, Quasar, QuasarSDKError, pulsarSyncHashEndpoint, watchBatchHashes };
339
+ export type { HistoryQuery, PaginatedResult, PulsarPoolStore, QuasarConfig };
package/dist/index.js CHANGED
@@ -1 +1 @@
1
- import {b,c,a as a$1}from'./chunk-YPUBFZPR.js';export{a as BASE_API_URL,c as PULSAR_HISTORY_ENDPOINT,b as PULSAR_SYNC_ENDPOINT}from'./chunk-YPUBFZPR.js';import {ofetch}from'ofetch';export{TransactionStatus,TransactionTracker}from'@tuwaio/pulsar-core';var a=class extends Error{status;originalError;constructor(r,e,t){super(r),this.name="QuasarSDKError",this.status=e,this.originalError=t;}},o=class{secretKey;internalSecret;baseUrl;timeout;constructor(r){if(!r.secretKey)throw new Error("[Quasar SDK] Missing API Key. Provide the secretKey of your Quasar app (sk_live_ or sk_test_).");this.secretKey=r.secretKey,this.internalSecret=r.internalSecret,this.baseUrl=r.baseUrl||a$1,this.timeout=r.timeout||1e4;}async request(r,e={}){try{return await ofetch(r,{baseURL:this.baseUrl,timeout:this.timeout,...e,headers:{"Content-Type":"application/json","x-tuwa-secret-key":this.secretKey,...this.internalSecret?{"x-internal-secret":this.internalSecret}:{},...e.headers}})}catch(t){throw this.buildError(t)}}buildError(r){let e=r,t=e.statusCode??e.response?.status,p=(e.data??e.response?._data)?.error??e.message??"Unknown Error";return (t===401||t===403)&&console.error("\u{1F6A8} [Quasar SDK] Auth Error. Check your Secret Key and scopes."),new a(`[Quasar SDK] Request Failed (${t}): ${p}`,t,e)}};var s=class{constructor(r){this.client=r;}client;async syncCreate(r,e){return this.client.request(b,{method:"POST",body:{...r,appName:e}})}async getHistory(r={}){return this.client.request(c,{method:"GET",query:{page:r.page??1,limit:r.limit??10,chainId:r.chainId,status:r.status,txKey:r.txKey,appName:r.appName,walletAddress:r.walletAddress}})}};var n=class{client;pulsar;constructor(r){this.client=new o(r),this.pulsar=new s(this.client);}};export{s as PulsarModule,n as Quasar,a as QuasarSDKError};
1
+ import {b,d as d$1,c as c$1,a}from'./chunk-MK6C4P3O.js';export{a as BASE_API_URL,c as PULSAR_HISTORY_ENDPOINT,b as PULSAR_SYNC_ENDPOINT,d as pulsarSyncHashEndpoint}from'./chunk-MK6C4P3O.js';import {ofetch}from'ofetch';import {TransactionTracker}from'@tuwaio/pulsar-core';export{TransactionStatus,TransactionTracker}from'@tuwaio/pulsar-core';var c=class extends Error{status;originalError;constructor(t,e,r){super(t),this.name="QuasarSDKError",this.status=e,this.originalError=r;}},u=class{secretKey;internalSecret;baseUrl;timeout;constructor(t){if(!t.secretKey)throw new Error("[Quasar SDK] Missing API Key. Provide the secretKey of your Quasar app (sk_live_ or sk_test_).");this.secretKey=t.secretKey,this.internalSecret=t.internalSecret,this.baseUrl=t.baseUrl||a,this.timeout=t.timeout||1e4;}async request(t,e={}){try{return await ofetch(t,{baseURL:this.baseUrl,timeout:this.timeout,...e,headers:{"Content-Type":"application/json","x-tuwa-secret-key":this.secretKey,...this.internalSecret?{"x-internal-secret":this.internalSecret}:{},...e.headers}})}catch(r){throw this.buildError(r)}}buildError(t){let e=t,r=e.statusCode??e.response?.status,l=(e.data??e.response?._data)?.error??e.message??"Unknown Error";return (r===401||r===403)&&console.error("\u{1F6A8} [Quasar SDK] Auth Error. Check your Secret Key and scopes."),new c(`[Quasar SDK] Request Failed (${r}): ${l}`,r,e)}};var o=class{constructor(t){this.client=t;}client;async syncCreate(t,e){return this.client.request(b,{method:"POST",body:{...t,appName:e}})}async syncHash(t,e){return this.client.request(d$1(t),{method:"POST",body:{hash:e}})}async getHistory(t={}){return this.client.request(c$1,{method:"GET",query:{page:t.page??1,limit:t.limit??10,chainId:t.chainId,status:t.status,txKey:t.txKey,appName:t.appName,walletAddress:t.walletAddress}})}};var P=3600;function T(s,t){let e=new Set,r=n=>{let l=Math.floor(Date.now()/1e3)-P;for(let a of Object.values(n)){let p=a.hash;if(a.tracker!==TransactionTracker.EIP5792||!p||a.syncStatus==="pending-sync"||a.localTimestamp<l)continue;let i=`${a.txKey}:${p}`;if(!e.has(i)){e.add(i);try{Promise.resolve(t({...a,hash:p})).catch(()=>e.delete(i));}catch{e.delete(i);}}}};return r(s.getState().transactionsPool),s.subscribe(n=>r(n.transactionsPool))}var d=class{client;pulsar;constructor(t){this.client=new u(t),this.pulsar=new o(this.client);}};export{o as PulsarModule,d as Quasar,c as QuasarSDKError,T as watchBatchHashes};
package/dist/react.cjs CHANGED
@@ -1 +1 @@
1
- 'use strict';var chunkNJH5FYLU_cjs=require('./chunk-NJH5FYLU.cjs'),siwxReact=require('@tuwaio/siwx-react');var i="/v1/engine/monitoring/health";async function u(s){if(!siwxReact.useSiwxSessionStore.getState().session)throw new Error("[QuasarSDK] No SIWX Session found. User must be signed in.");let o=(s||chunkNJH5FYLU_cjs.a).replace(/\/+$/,""),e;try{e=await fetch(`${o}${i}`,{method:"GET",cache:"no-store"});}catch(t){throw new Error("[QuasarSDK] Quasar Cloud Engine is currently unreachable.",{cause:t})}if(!e.ok)throw new Error(`[QuasarSDK] API Health check failed with status: ${e.status}`)}exports.preFlightTxCheck=u;
1
+ 'use strict';var chunk7EJ6DS4C_cjs=require('./chunk-7EJ6DS4C.cjs'),siwxReact=require('@tuwaio/siwx-react');var i="/v1/engine/monitoring/health";async function u(s){if(!siwxReact.useSiwxSessionStore.getState().session)throw new Error("[QuasarSDK] No SIWX Session found. User must be signed in.");let o=(s||chunk7EJ6DS4C_cjs.a).replace(/\/+$/,""),e;try{e=await fetch(`${o}${i}`,{method:"GET",cache:"no-store"});}catch(t){throw new Error("[QuasarSDK] Quasar Cloud Engine is currently unreachable.",{cause:t})}if(!e.ok)throw new Error(`[QuasarSDK] API Health check failed with status: ${e.status}`)}exports.preFlightTxCheck=u;
package/dist/react.js CHANGED
@@ -1 +1 @@
1
- import {a}from'./chunk-YPUBFZPR.js';import {useSiwxSessionStore}from'@tuwaio/siwx-react';var i="/v1/engine/monitoring/health";async function u(s){if(!useSiwxSessionStore.getState().session)throw new Error("[QuasarSDK] No SIWX Session found. User must be signed in.");let o=(s||a).replace(/\/+$/,""),e;try{e=await fetch(`${o}${i}`,{method:"GET",cache:"no-store"});}catch(t){throw new Error("[QuasarSDK] Quasar Cloud Engine is currently unreachable.",{cause:t})}if(!e.ok)throw new Error(`[QuasarSDK] API Health check failed with status: ${e.status}`)}export{u as preFlightTxCheck};
1
+ import {a}from'./chunk-MK6C4P3O.js';import {useSiwxSessionStore}from'@tuwaio/siwx-react';var i="/v1/engine/monitoring/health";async function u(s){if(!useSiwxSessionStore.getState().session)throw new Error("[QuasarSDK] No SIWX Session found. User must be signed in.");let o=(s||a).replace(/\/+$/,""),e;try{e=await fetch(`${o}${i}`,{method:"GET",cache:"no-store"});}catch(t){throw new Error("[QuasarSDK] Quasar Cloud Engine is currently unreachable.",{cause:t})}if(!e.ok)throw new Error(`[QuasarSDK] API Health check failed with status: ${e.status}`)}export{u as preFlightTxCheck};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tuwaio/quasar-sdk",
3
- "version": "0.5.0",
3
+ "version": "0.7.0",
4
4
  "private": false,
5
5
  "author": "Oleksandr Tkach",
6
6
  "license": "Apache-2.0",
@@ -69,7 +69,7 @@
69
69
  "ofetch": "^1.5.1"
70
70
  },
71
71
  "peerDependencies": {
72
- "@tuwaio/pulsar-core": ">=0.9",
72
+ "@tuwaio/pulsar-core": ">=0.10",
73
73
  "@tuwaio/siwx-react": ">=0.5"
74
74
  },
75
75
  "peerDependenciesMeta": {
@@ -78,8 +78,8 @@
78
78
  }
79
79
  },
80
80
  "devDependencies": {
81
- "@tuwaio/pulsar-core": "^0.10.0",
82
- "tsup": "^8.5.1",
81
+ "@tuwaio/pulsar-core": "^0.10.1",
82
+ "tsup": "^9.0.0",
83
83
  "typescript": "6.0.3",
84
84
  "@tuwaio/siwx-react": "^0.6.2"
85
85
  },
@@ -1,2 +0,0 @@
1
- 'use strict';var t="https://api.tuwa.io",n="/v1/engine/pulsar/sync",o="/v1/engine/pulsar/history";
2
- exports.a=t;exports.b=n;exports.c=o;
@@ -1,2 +0,0 @@
1
- var t="https://api.tuwa.io",n="/v1/engine/pulsar/sync",o="/v1/engine/pulsar/history";
2
- export{t as a,n as b,o as c};