@tuwaio/quasar-sdk 0.0.6 → 0.0.8

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.
@@ -0,0 +1 @@
1
+ 'use strict';var zustand=require('zustand'),middleware=require('zustand/middleware');var d=(t=>(t.EVM="EVM",t.SOLANA="SOLANA",t))(d||{});var S=300*1e3,w=60*1e3,m=30*1e3;function y(e){return `Mini-Session Login: ${e}`}async function f(e){let r=new Date().toISOString(),t=y(r);if(e.chainType==="EVM"){let i=e.signer;try{return {signature:await i.signMessage({account:e.walletAddress,message:t}),timestamp:r}}catch(n){throw new Error(`[SDK] EVM signing failed: ${n.message}`,{cause:n})}}if(e.chainType==="SOLANA"){let i=e.signer,n;try{n=await import('gill');}catch(s){throw new Error('[SDK] Peer dependency "gill" is required for Solana signing.',{cause:s})}try{let a=n.getUtf8Encoder().encode(t),o;if(i.modifyAndSignMessages){let g=n.createSignableMessage(a),[p]=await i.modifyAndSignMessages([g]),u=p.signatures[i.address];if(!u)throw new Error(`[SDK] Signature missing for address: ${i.address}`);o=u;}else if(i.signMessages){let[g]=await i.signMessages([a]);if(!g?.signature)throw new Error("[SDK] Wallet returned invalid signMessages output.");o=g.signature;}else if(i.signMessage)o=await i.signMessage(a);else throw new Error("[SDK] Signer lacks message signing capabilities.");return {signature:n.getSignatureFromBytes(o),timestamp:r}}catch(s){throw new Error(`[SDK] Solana signing failed: ${s.message}`,{cause:s})}}throw new Error(`[SDK] Unsupported chain type: ${e.chainType}`)}async function b(e){let r=new Date(e.timestamp).getTime(),t=Date.now();if(isNaN(r))throw new Error("[SDK] Invalid timestamp format. Use ISO string.");let i=e.maxAge??S;if(t-r>i)throw new Error("[SDK] Signature expired. Please sign a fresh message.");if(r>t+w)throw new Error("[SDK] Timestamp is in the future. Check your system clock.");let n=y(e.timestamp);if(e.chainType==="EVM"){let s;try{s=await import('viem');}catch(a){throw new Error('[SDK] Peer dependency "viem" is required for EVM verification.',{cause:a})}return await s.verifyMessage({address:e.walletAddress,message:n,signature:e.signature})}if(e.chainType==="SOLANA"){let s;try{s=await import('gill');}catch(a){throw new Error('[SDK] Peer dependency "gill" is required for Solana verification.',{cause:a})}try{let a=s.address(e.walletAddress);return await s.verifySignatureForAddress(a,e.signature,n)}catch{return false}}return false}var c=null;function R(e="mini-session-storage"){return zustand.create()(middleware.persist(r=>({miniSession:null,setMiniSession:t=>r({miniSession:t}),clearSession:()=>r({miniSession:null})}),{name:e}))}async function C(e,r,t=S){let{isConnected:i,address:n,chainType:s,signer:a}=e;if(!i||!n)throw new Error("[SDK] Wallet not connected. Please connect your wallet first.");let o=r.miniSession;if(o&&o.walletAddress===n&&o.chainType===s){let l=Date.now(),g=new Date(o.timestamp).getTime();if(l-g<t-m)return o}return c||(c=f({signer:a,walletAddress:n,chainType:s}).then(l=>{let g={...l,chainType:s,walletAddress:n};return r.setMiniSession(g),g}).finally(()=>{c=null;})),c}exports.a=d;exports.b=S;exports.c=m;exports.d=y;exports.e=f;exports.f=b;exports.g=R;exports.h=C;
@@ -0,0 +1 @@
1
+ import {create}from'zustand';import {persist}from'zustand/middleware';var d=(t=>(t.EVM="EVM",t.SOLANA="SOLANA",t))(d||{});var S=300*1e3,w=60*1e3,m=30*1e3;function y(e){return `Mini-Session Login: ${e}`}async function f(e){let r=new Date().toISOString(),t=y(r);if(e.chainType==="EVM"){let i=e.signer;try{return {signature:await i.signMessage({account:e.walletAddress,message:t}),timestamp:r}}catch(n){throw new Error(`[SDK] EVM signing failed: ${n.message}`,{cause:n})}}if(e.chainType==="SOLANA"){let i=e.signer,n;try{n=await import('gill');}catch(s){throw new Error('[SDK] Peer dependency "gill" is required for Solana signing.',{cause:s})}try{let a=n.getUtf8Encoder().encode(t),o;if(i.modifyAndSignMessages){let g=n.createSignableMessage(a),[p]=await i.modifyAndSignMessages([g]),u=p.signatures[i.address];if(!u)throw new Error(`[SDK] Signature missing for address: ${i.address}`);o=u;}else if(i.signMessages){let[g]=await i.signMessages([a]);if(!g?.signature)throw new Error("[SDK] Wallet returned invalid signMessages output.");o=g.signature;}else if(i.signMessage)o=await i.signMessage(a);else throw new Error("[SDK] Signer lacks message signing capabilities.");return {signature:n.getSignatureFromBytes(o),timestamp:r}}catch(s){throw new Error(`[SDK] Solana signing failed: ${s.message}`,{cause:s})}}throw new Error(`[SDK] Unsupported chain type: ${e.chainType}`)}async function b(e){let r=new Date(e.timestamp).getTime(),t=Date.now();if(isNaN(r))throw new Error("[SDK] Invalid timestamp format. Use ISO string.");let i=e.maxAge??S;if(t-r>i)throw new Error("[SDK] Signature expired. Please sign a fresh message.");if(r>t+w)throw new Error("[SDK] Timestamp is in the future. Check your system clock.");let n=y(e.timestamp);if(e.chainType==="EVM"){let s;try{s=await import('viem');}catch(a){throw new Error('[SDK] Peer dependency "viem" is required for EVM verification.',{cause:a})}return await s.verifyMessage({address:e.walletAddress,message:n,signature:e.signature})}if(e.chainType==="SOLANA"){let s;try{s=await import('gill');}catch(a){throw new Error('[SDK] Peer dependency "gill" is required for Solana verification.',{cause:a})}try{let a=s.address(e.walletAddress);return await s.verifySignatureForAddress(a,e.signature,n)}catch{return false}}return false}var c=null;function R(e="mini-session-storage"){return create()(persist(r=>({miniSession:null,setMiniSession:t=>r({miniSession:t}),clearSession:()=>r({miniSession:null})}),{name:e}))}async function C(e,r,t=S){let{isConnected:i,address:n,chainType:s,signer:a}=e;if(!i||!n)throw new Error("[SDK] Wallet not connected. Please connect your wallet first.");let o=r.miniSession;if(o&&o.walletAddress===n&&o.chainType===s){let l=Date.now(),g=new Date(o.timestamp).getTime();if(l-g<t-m)return o}return c||(c=f({signer:a,walletAddress:n,chainType:s}).then(l=>{let g={...l,chainType:s,walletAddress:n};return r.setMiniSession(g),g}).finally(()=>{c=null;})),c}export{d as a,S as b,m as c,y as d,f as e,b as f,R as g,C as h};
package/dist/index.d.mts CHANGED
@@ -208,6 +208,14 @@ declare class PulsarModule {
208
208
  * @internal
209
209
  */
210
210
  declare const DEFAULT_MAX_AGE: number;
211
+ /**
212
+ * Safety buffer subtracted from DEFAULT_MAX_AGE during cache validation.
213
+ * Ensures the session is refreshed before it expires on the server,
214
+ * accounting for network round-trip latency between client cache check
215
+ * and server-side verifyMiniSession call.
216
+ * @public
217
+ */
218
+ declare const NETWORK_SAFETY_BUFFER: number;
211
219
  /**
212
220
  * Standardizes the message format for Mini-Session authentication.
213
221
  * Both frontend and backend MUST use this exact template for verification to pass.
@@ -279,6 +287,9 @@ declare function createMiniSessionStore(storageName?: string): zustand.UseBoundS
279
287
  *
280
288
  * @param connection - The current active wallet connection data (address, signer, etc).
281
289
  * @param store - A store implementation (Zustand or compatible) for session persistence.
290
+ * @param maxAge - Maximum allowed session age in milliseconds. Must match the value
291
+ * passed to `verifyMiniSession` to keep cache and verification in sync.
292
+ * Defaults to `DEFAULT_MAX_AGE` (5 minutes).
282
293
  * @returns A promise resolving to a valid MiniSessionAuth object.
283
294
  * @throws {Error} If the wallet is disconnected or signing fails.
284
295
  *
@@ -287,7 +298,7 @@ declare function createMiniSessionStore(storageName?: string): zustand.UseBoundS
287
298
  declare function getMiniSessionAuth(connection: ConnectionData, store: {
288
299
  miniSession: MiniSessionAuth | null;
289
300
  setMiniSession: (session: MiniSessionAuth | null) => void;
290
- }): Promise<MiniSessionAuth>;
301
+ }, maxAge?: number): Promise<MiniSessionAuth>;
291
302
 
292
303
  declare const BASE_API_URL = "https://api.tuwa.io";
293
304
  declare const PULSAR_SYNC_ENDPOINT = "/v1/engine/pulsar/sync";
@@ -431,4 +442,4 @@ declare class Quasar {
431
442
  constructor(config: QuasarConfig);
432
443
  }
433
444
 
434
- export { BASE_API_URL, ConnectionData, DEFAULT_MAX_AGE, HistoryQuery, MiniSessionAuth, MiniSessionStore, PULSAR_HISTORY_ENDPOINT, PULSAR_SYNC_ENDPOINT, PaginatedResult, PulsarModule, Quasar, QuasarConfig, QuasarSDKError, SignSessionParams, SignSessionResult, VerifySessionParams, createMiniSessionMessage, createMiniSessionStore, getMiniSessionAuth, signMiniSession, utils, verifyMiniSession };
445
+ export { BASE_API_URL, ConnectionData, DEFAULT_MAX_AGE, HistoryQuery, MiniSessionAuth, MiniSessionStore, NETWORK_SAFETY_BUFFER, PULSAR_HISTORY_ENDPOINT, PULSAR_SYNC_ENDPOINT, PaginatedResult, PulsarModule, Quasar, QuasarConfig, QuasarSDKError, SignSessionParams, SignSessionResult, VerifySessionParams, createMiniSessionMessage, createMiniSessionStore, getMiniSessionAuth, signMiniSession, utils, verifyMiniSession };
package/dist/index.d.ts CHANGED
@@ -208,6 +208,14 @@ declare class PulsarModule {
208
208
  * @internal
209
209
  */
210
210
  declare const DEFAULT_MAX_AGE: number;
211
+ /**
212
+ * Safety buffer subtracted from DEFAULT_MAX_AGE during cache validation.
213
+ * Ensures the session is refreshed before it expires on the server,
214
+ * accounting for network round-trip latency between client cache check
215
+ * and server-side verifyMiniSession call.
216
+ * @public
217
+ */
218
+ declare const NETWORK_SAFETY_BUFFER: number;
211
219
  /**
212
220
  * Standardizes the message format for Mini-Session authentication.
213
221
  * Both frontend and backend MUST use this exact template for verification to pass.
@@ -279,6 +287,9 @@ declare function createMiniSessionStore(storageName?: string): zustand.UseBoundS
279
287
  *
280
288
  * @param connection - The current active wallet connection data (address, signer, etc).
281
289
  * @param store - A store implementation (Zustand or compatible) for session persistence.
290
+ * @param maxAge - Maximum allowed session age in milliseconds. Must match the value
291
+ * passed to `verifyMiniSession` to keep cache and verification in sync.
292
+ * Defaults to `DEFAULT_MAX_AGE` (5 minutes).
282
293
  * @returns A promise resolving to a valid MiniSessionAuth object.
283
294
  * @throws {Error} If the wallet is disconnected or signing fails.
284
295
  *
@@ -287,7 +298,7 @@ declare function createMiniSessionStore(storageName?: string): zustand.UseBoundS
287
298
  declare function getMiniSessionAuth(connection: ConnectionData, store: {
288
299
  miniSession: MiniSessionAuth | null;
289
300
  setMiniSession: (session: MiniSessionAuth | null) => void;
290
- }): Promise<MiniSessionAuth>;
301
+ }, maxAge?: number): Promise<MiniSessionAuth>;
291
302
 
292
303
  declare const BASE_API_URL = "https://api.tuwa.io";
293
304
  declare const PULSAR_SYNC_ENDPOINT = "/v1/engine/pulsar/sync";
@@ -431,4 +442,4 @@ declare class Quasar {
431
442
  constructor(config: QuasarConfig);
432
443
  }
433
444
 
434
- export { BASE_API_URL, ConnectionData, DEFAULT_MAX_AGE, HistoryQuery, MiniSessionAuth, MiniSessionStore, PULSAR_HISTORY_ENDPOINT, PULSAR_SYNC_ENDPOINT, PaginatedResult, PulsarModule, Quasar, QuasarConfig, QuasarSDKError, SignSessionParams, SignSessionResult, VerifySessionParams, createMiniSessionMessage, createMiniSessionStore, getMiniSessionAuth, signMiniSession, utils, verifyMiniSession };
445
+ export { BASE_API_URL, ConnectionData, DEFAULT_MAX_AGE, HistoryQuery, MiniSessionAuth, MiniSessionStore, NETWORK_SAFETY_BUFFER, PULSAR_HISTORY_ENDPOINT, PULSAR_SYNC_ENDPOINT, PaginatedResult, PulsarModule, Quasar, QuasarConfig, QuasarSDKError, SignSessionParams, SignSessionResult, VerifySessionParams, createMiniSessionMessage, createMiniSessionStore, getMiniSessionAuth, signMiniSession, utils, verifyMiniSession };
package/dist/index.js CHANGED
@@ -1,2 +1,2 @@
1
- 'use strict';var chunkA52BVTJ6_js=require('./chunk-A52BVTJ6.js'),ofetch=require('ofetch');var m="https://api.tuwa.io",h="/v1/engine/pulsar/sync",d="/v1/engine/pulsar/history";var i=class extends Error{status;originalError;constructor(t,e,r){super(t),this.name="QuasarSDKError",this.status=e,this.originalError=r;}},o=class{secretKey;internalSecret;baseUrl;timeout;constructor(t){if(!t.secretKey)throw new Error("[Quasar SDK] Missing API Key. Provide a secretKey starting with sk_live_.");this.secretKey=t.secretKey,this.internalSecret=t.internalSecret,this.baseUrl=t.baseUrl||m,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,S=(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 i(`[Quasar SDK] Request Failed (${r}): ${S}`,r,e)}};var s=class{constructor(t){this.client=t;}async syncCreate(t,e){return this.client.request(h,{method:"POST",body:{...t,appName:e}})}async getHistory(t={}){return this.client.request(d,{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 E={createMiniSessionMessage:chunkA52BVTJ6_js.c,verifyMiniSession:chunkA52BVTJ6_js.e,signMiniSession:chunkA52BVTJ6_js.d,createMiniSessionStore:chunkA52BVTJ6_js.f,getMiniSessionAuth:chunkA52BVTJ6_js.g},y=class{static utils=E;client;pulsar;constructor(t){this.client=new o(t),this.pulsar=new s(this.client);}};
2
- Object.defineProperty(exports,"ChainType",{enumerable:true,get:function(){return chunkA52BVTJ6_js.a}});Object.defineProperty(exports,"DEFAULT_MAX_AGE",{enumerable:true,get:function(){return chunkA52BVTJ6_js.b}});Object.defineProperty(exports,"createMiniSessionMessage",{enumerable:true,get:function(){return chunkA52BVTJ6_js.c}});Object.defineProperty(exports,"createMiniSessionStore",{enumerable:true,get:function(){return chunkA52BVTJ6_js.f}});Object.defineProperty(exports,"getMiniSessionAuth",{enumerable:true,get:function(){return chunkA52BVTJ6_js.g}});Object.defineProperty(exports,"signMiniSession",{enumerable:true,get:function(){return chunkA52BVTJ6_js.d}});Object.defineProperty(exports,"verifyMiniSession",{enumerable:true,get:function(){return chunkA52BVTJ6_js.e}});exports.BASE_API_URL=m;exports.PULSAR_HISTORY_ENDPOINT=d;exports.PULSAR_SYNC_ENDPOINT=h;exports.PulsarModule=s;exports.Quasar=y;exports.QuasarSDKError=i;exports.utils=E;
1
+ 'use strict';var chunkOJCR5A56_js=require('./chunk-OJCR5A56.js'),ofetch=require('ofetch');var m="https://api.tuwa.io",h="/v1/engine/pulsar/sync",d="/v1/engine/pulsar/history";var i=class extends Error{status;originalError;constructor(t,e,r){super(t),this.name="QuasarSDKError",this.status=e,this.originalError=r;}},o=class{secretKey;internalSecret;baseUrl;timeout;constructor(t){if(!t.secretKey)throw new Error("[Quasar SDK] Missing API Key. Provide a secretKey starting with sk_live_.");this.secretKey=t.secretKey,this.internalSecret=t.internalSecret,this.baseUrl=t.baseUrl||m,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,S=(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 i(`[Quasar SDK] Request Failed (${r}): ${S}`,r,e)}};var s=class{constructor(t){this.client=t;}async syncCreate(t,e){return this.client.request(h,{method:"POST",body:{...t,appName:e}})}async getHistory(t={}){return this.client.request(d,{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 E={createMiniSessionMessage:chunkOJCR5A56_js.d,verifyMiniSession:chunkOJCR5A56_js.f,signMiniSession:chunkOJCR5A56_js.e,createMiniSessionStore:chunkOJCR5A56_js.g,getMiniSessionAuth:chunkOJCR5A56_js.h},y=class{static utils=E;client;pulsar;constructor(t){this.client=new o(t),this.pulsar=new s(this.client);}};
2
+ Object.defineProperty(exports,"ChainType",{enumerable:true,get:function(){return chunkOJCR5A56_js.a}});Object.defineProperty(exports,"DEFAULT_MAX_AGE",{enumerable:true,get:function(){return chunkOJCR5A56_js.b}});Object.defineProperty(exports,"NETWORK_SAFETY_BUFFER",{enumerable:true,get:function(){return chunkOJCR5A56_js.c}});Object.defineProperty(exports,"createMiniSessionMessage",{enumerable:true,get:function(){return chunkOJCR5A56_js.d}});Object.defineProperty(exports,"createMiniSessionStore",{enumerable:true,get:function(){return chunkOJCR5A56_js.g}});Object.defineProperty(exports,"getMiniSessionAuth",{enumerable:true,get:function(){return chunkOJCR5A56_js.h}});Object.defineProperty(exports,"signMiniSession",{enumerable:true,get:function(){return chunkOJCR5A56_js.e}});Object.defineProperty(exports,"verifyMiniSession",{enumerable:true,get:function(){return chunkOJCR5A56_js.f}});exports.BASE_API_URL=m;exports.PULSAR_HISTORY_ENDPOINT=d;exports.PULSAR_SYNC_ENDPOINT=h;exports.PulsarModule=s;exports.Quasar=y;exports.QuasarSDKError=i;exports.utils=E;
package/dist/index.mjs CHANGED
@@ -1,2 +1,2 @@
1
- import {g,f,d as d$1,e,c}from'./chunk-DK4D3PU5.mjs';export{a as ChainType,b as DEFAULT_MAX_AGE,c as createMiniSessionMessage,f as createMiniSessionStore,g as getMiniSessionAuth,d as signMiniSession,e as verifyMiniSession}from'./chunk-DK4D3PU5.mjs';import {ofetch}from'ofetch';var m="https://api.tuwa.io",h="/v1/engine/pulsar/sync",d="/v1/engine/pulsar/history";var i=class extends Error{status;originalError;constructor(t,e,r){super(t),this.name="QuasarSDKError",this.status=e,this.originalError=r;}},o=class{secretKey;internalSecret;baseUrl;timeout;constructor(t){if(!t.secretKey)throw new Error("[Quasar SDK] Missing API Key. Provide a secretKey starting with sk_live_.");this.secretKey=t.secretKey,this.internalSecret=t.internalSecret,this.baseUrl=t.baseUrl||m,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,S=(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 i(`[Quasar SDK] Request Failed (${r}): ${S}`,r,e)}};var s=class{constructor(t){this.client=t;}async syncCreate(t,e){return this.client.request(h,{method:"POST",body:{...t,appName:e}})}async getHistory(t={}){return this.client.request(d,{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 E={createMiniSessionMessage:c,verifyMiniSession:e,signMiniSession:d$1,createMiniSessionStore:f,getMiniSessionAuth:g},y=class{static utils=E;client;pulsar;constructor(t){this.client=new o(t),this.pulsar=new s(this.client);}};
1
+ import {h as h$1,g,e,f,d as d$1}from'./chunk-SF2BM2YA.mjs';export{a as ChainType,b as DEFAULT_MAX_AGE,c as NETWORK_SAFETY_BUFFER,d as createMiniSessionMessage,g as createMiniSessionStore,h as getMiniSessionAuth,e as signMiniSession,f as verifyMiniSession}from'./chunk-SF2BM2YA.mjs';import {ofetch}from'ofetch';var m="https://api.tuwa.io",h="/v1/engine/pulsar/sync",d="/v1/engine/pulsar/history";var i=class extends Error{status;originalError;constructor(t,e,r){super(t),this.name="QuasarSDKError",this.status=e,this.originalError=r;}},o=class{secretKey;internalSecret;baseUrl;timeout;constructor(t){if(!t.secretKey)throw new Error("[Quasar SDK] Missing API Key. Provide a secretKey starting with sk_live_.");this.secretKey=t.secretKey,this.internalSecret=t.internalSecret,this.baseUrl=t.baseUrl||m,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,S=(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 i(`[Quasar SDK] Request Failed (${r}): ${S}`,r,e)}};var s=class{constructor(t){this.client=t;}async syncCreate(t,e){return this.client.request(h,{method:"POST",body:{...t,appName:e}})}async getHistory(t={}){return this.client.request(d,{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 E={createMiniSessionMessage:d$1,verifyMiniSession:f,signMiniSession:e,createMiniSessionStore:g,getMiniSessionAuth:h$1},y=class{static utils=E;client;pulsar;constructor(t){this.client=new o(t),this.pulsar=new s(this.client);}};
2
2
  export{m as BASE_API_URL,d as PULSAR_HISTORY_ENDPOINT,h as PULSAR_SYNC_ENDPOINT,s as PulsarModule,y as Quasar,i as QuasarSDKError,E as utils};
package/dist/react.d.mts CHANGED
@@ -43,6 +43,22 @@ interface QuasarAuthBridgeProps {
43
43
  session: MiniSessionAuth | null;
44
44
  /** Callback to update the session in your state store. */
45
45
  setSession: (session: MiniSessionAuth | null) => void;
46
+ /**
47
+ * Maximum session age in milliseconds. Must be the same value passed to
48
+ * `verifyMiniSession` — this is the single source of truth for session lifetime.
49
+ * Defaults to 5 minutes.
50
+ *
51
+ * @example
52
+ * ```tsx
53
+ * const TOKEN_EXPIRATION = 86400 * 1000; // 24 hours in ms
54
+ *
55
+ * <QuasarAuthBridge maxAge={TOKEN_EXPIRATION} ... />
56
+ *
57
+ * // Later, for verification:
58
+ * verifyMiniSession({ ...auth, maxAge: TOKEN_EXPIRATION });
59
+ * ```
60
+ */
61
+ maxAge?: number;
46
62
  /** Optional callback triggered when an address mismatch is detected. */
47
63
  onAddressMismatch?: () => void;
48
64
  }
@@ -73,6 +89,6 @@ interface QuasarAuthBridgeProps {
73
89
  *
74
90
  * @public
75
91
  */
76
- declare function QuasarAuthBridge({ activeConnection, store, wagmiConfig, session, setSession, onAddressMismatch, }: QuasarAuthBridgeProps): react_jsx_runtime.JSX.Element | null;
92
+ declare function QuasarAuthBridge({ activeConnection, store, wagmiConfig, session, setSession, maxAge, onAddressMismatch, }: QuasarAuthBridgeProps): react_jsx_runtime.JSX.Element | null;
77
93
 
78
94
  export { type QuasarActiveConnection, QuasarAuthBridge, type QuasarAuthBridgeProps, getMiniSessionAuth };
package/dist/react.d.ts CHANGED
@@ -43,6 +43,22 @@ interface QuasarAuthBridgeProps {
43
43
  session: MiniSessionAuth | null;
44
44
  /** Callback to update the session in your state store. */
45
45
  setSession: (session: MiniSessionAuth | null) => void;
46
+ /**
47
+ * Maximum session age in milliseconds. Must be the same value passed to
48
+ * `verifyMiniSession` — this is the single source of truth for session lifetime.
49
+ * Defaults to 5 minutes.
50
+ *
51
+ * @example
52
+ * ```tsx
53
+ * const TOKEN_EXPIRATION = 86400 * 1000; // 24 hours in ms
54
+ *
55
+ * <QuasarAuthBridge maxAge={TOKEN_EXPIRATION} ... />
56
+ *
57
+ * // Later, for verification:
58
+ * verifyMiniSession({ ...auth, maxAge: TOKEN_EXPIRATION });
59
+ * ```
60
+ */
61
+ maxAge?: number;
46
62
  /** Optional callback triggered when an address mismatch is detected. */
47
63
  onAddressMismatch?: () => void;
48
64
  }
@@ -73,6 +89,6 @@ interface QuasarAuthBridgeProps {
73
89
  *
74
90
  * @public
75
91
  */
76
- declare function QuasarAuthBridge({ activeConnection, store, wagmiConfig, session, setSession, onAddressMismatch, }: QuasarAuthBridgeProps): react_jsx_runtime.JSX.Element | null;
92
+ declare function QuasarAuthBridge({ activeConnection, store, wagmiConfig, session, setSession, maxAge, onAddressMismatch, }: QuasarAuthBridgeProps): react_jsx_runtime.JSX.Element | null;
77
93
 
78
94
  export { type QuasarActiveConnection, QuasarAuthBridge, type QuasarAuthBridgeProps, getMiniSessionAuth };
package/dist/react.js CHANGED
@@ -1 +1 @@
1
- 'use strict';var chunkA52BVTJ6_js=require('./chunk-A52BVTJ6.js'),react$1=require('@solana/react'),core=require('@wagmi/core'),react=require('react'),jsxRuntime=require('react/jsx-runtime');var s=null;async function P(){for(let n=0;n<15;n++){if(s)return s();await new Promise(t=>setTimeout(t,200));}throw new Error("[QuasarSDK] Auth helper not initialized. Ensure QuasarAuthBridge is mounted and wallet is connected.")}function k({activeConnection:n,store:t,wagmiConfig:r,session:i,setSession:e,onAddressMismatch:a}){let o=typeof n?.chainId=="string"?"SOLANA":"EVM";return react.useEffect(()=>{i&&n?.address&&i.walletAddress!==n.address&&(console.log("[QuasarSDK] Address mismatch detected, clearing session..."),e(null),a?.());},[n?.address,i,e,a]),!n?.isConnected||!t?null:o==="SOLANA"?jsxRuntime.jsx(h,{connectedAccount:n.connectedAccount,store:t,session:i,setSession:e}):jsxRuntime.jsx(f,{wagmiConfig:r,store:t,session:i,setSession:e})}function h({connectedAccount:n,store:t,session:r,setSession:i}){let e=react$1.useWalletAccountMessageSigner(n),a=react.useCallback(async()=>{let o=t.getState().activeConnection;if(!o?.isConnected)throw new Error("[QuasarSDK] Wallet disconnected");if(!e)throw new Error("[QuasarSDK] Solana Message Signer not initialized.");return chunkA52BVTJ6_js.g({isConnected:o.isConnected,address:o.address,chainType:"SOLANA",signer:e},{miniSession:r,setMiniSession:i})},[t,e,r,i]);return react.useEffect(()=>(s=a,()=>{s===a&&(s=null);}),[a]),null}function f({wagmiConfig:n,store:t,session:r,setSession:i}){let e=react.useCallback(async()=>{let u=t.getState().activeConnection;if(!u?.isConnected)throw new Error("[QuasarSDK] Wallet disconnected");let o=await core.getWalletClient(n);if(!o)throw new Error("[QuasarSDK] EVM Signer not found");return chunkA52BVTJ6_js.g({isConnected:u.isConnected,address:u.address,chainType:"EVM",signer:o},{miniSession:r,setMiniSession:i})},[t,n,r,i]);return react.useEffect(()=>(s=e,()=>{s===e&&(s=null);}),[e]),null}exports.QuasarAuthBridge=k;exports.getMiniSessionAuth=P;
1
+ 'use strict';var chunkOJCR5A56_js=require('./chunk-OJCR5A56.js'),react$1=require('@solana/react'),core=require('@wagmi/core'),react=require('react'),jsxRuntime=require('react/jsx-runtime');var u=null;async function K(){for(let n=0;n<15;n++){if(u)return u();await new Promise(t=>setTimeout(t,200));}throw new Error("[QuasarSDK] Auth helper not initialized. Ensure QuasarAuthBridge is mounted and wallet is connected.")}function x({activeConnection:n,store:t,wagmiConfig:r,session:e,setSession:i,maxAge:o,onAddressMismatch:s}){let d=typeof n?.chainId=="string"?"SOLANA":"EVM";return react.useEffect(()=>{e&&n?.address&&e.walletAddress!==n.address&&(console.log("[QuasarSDK] Address mismatch detected, clearing session..."),i(null),s?.());},[n?.address,e,i,s]),!n?.isConnected||!t?null:d==="SOLANA"?jsxRuntime.jsx(M,{connectedAccount:n.connectedAccount,store:t,session:e,setSession:i,maxAge:o}):jsxRuntime.jsx(Q,{wagmiConfig:r,store:t,session:e,setSession:i,maxAge:o})}function M({connectedAccount:n,store:t,session:r,setSession:e,maxAge:i}){let o=react$1.useWalletAccountMessageSigner(n),s=react.useRef(o),c=react.useRef(r),d=react.useRef(e);react.useEffect(()=>{s.current=o;},[o]),react.useEffect(()=>{c.current=r;},[r]),react.useEffect(()=>{d.current=e;},[e]);let l=react.useCallback(async()=>{let g=t.getState().activeConnection;if(!g?.isConnected)throw new Error("[QuasarSDK] Wallet disconnected");let h=s.current;if(!h)throw new Error("[QuasarSDK] Solana Message Signer not initialized.");return chunkOJCR5A56_js.h({isConnected:g.isConnected,address:g.address,chainType:"SOLANA",signer:h},{miniSession:c.current,setMiniSession:d.current},i)},[t,i]);return react.useEffect(()=>(u=l,()=>{u===l&&(u=null);}),[l]),null}function Q({wagmiConfig:n,store:t,session:r,setSession:e,maxAge:i}){let o=react.useRef(r),s=react.useRef(e);react.useEffect(()=>{o.current=r;},[r]),react.useEffect(()=>{s.current=e;},[e]);let c=react.useCallback(async()=>{let l=t.getState().activeConnection;if(!l?.isConnected)throw new Error("[QuasarSDK] Wallet disconnected");let A=await core.getWalletClient(n);if(!A)throw new Error("[QuasarSDK] EVM Signer not found");return chunkOJCR5A56_js.h({isConnected:l.isConnected,address:l.address,chainType:"EVM",signer:A},{miniSession:o.current,setMiniSession:s.current},i)},[t,n,i]);return react.useEffect(()=>(u=c,()=>{u===c&&(u=null);}),[c]),null}exports.QuasarAuthBridge=x;exports.getMiniSessionAuth=K;
package/dist/react.mjs CHANGED
@@ -1 +1 @@
1
- import {g}from'./chunk-DK4D3PU5.mjs';import {useWalletAccountMessageSigner}from'@solana/react';import {getWalletClient}from'@wagmi/core';import {useEffect,useCallback}from'react';import {jsx}from'react/jsx-runtime';var s=null;async function P(){for(let n=0;n<15;n++){if(s)return s();await new Promise(t=>setTimeout(t,200));}throw new Error("[QuasarSDK] Auth helper not initialized. Ensure QuasarAuthBridge is mounted and wallet is connected.")}function k({activeConnection:n,store:t,wagmiConfig:r,session:i,setSession:e,onAddressMismatch:a}){let o=typeof n?.chainId=="string"?"SOLANA":"EVM";return useEffect(()=>{i&&n?.address&&i.walletAddress!==n.address&&(console.log("[QuasarSDK] Address mismatch detected, clearing session..."),e(null),a?.());},[n?.address,i,e,a]),!n?.isConnected||!t?null:o==="SOLANA"?jsx(h,{connectedAccount:n.connectedAccount,store:t,session:i,setSession:e}):jsx(f,{wagmiConfig:r,store:t,session:i,setSession:e})}function h({connectedAccount:n,store:t,session:r,setSession:i}){let e=useWalletAccountMessageSigner(n),a=useCallback(async()=>{let o=t.getState().activeConnection;if(!o?.isConnected)throw new Error("[QuasarSDK] Wallet disconnected");if(!e)throw new Error("[QuasarSDK] Solana Message Signer not initialized.");return g({isConnected:o.isConnected,address:o.address,chainType:"SOLANA",signer:e},{miniSession:r,setMiniSession:i})},[t,e,r,i]);return useEffect(()=>(s=a,()=>{s===a&&(s=null);}),[a]),null}function f({wagmiConfig:n,store:t,session:r,setSession:i}){let e=useCallback(async()=>{let u=t.getState().activeConnection;if(!u?.isConnected)throw new Error("[QuasarSDK] Wallet disconnected");let o=await getWalletClient(n);if(!o)throw new Error("[QuasarSDK] EVM Signer not found");return g({isConnected:u.isConnected,address:u.address,chainType:"EVM",signer:o},{miniSession:r,setMiniSession:i})},[t,n,r,i]);return useEffect(()=>(s=e,()=>{s===e&&(s=null);}),[e]),null}export{k as QuasarAuthBridge,P as getMiniSessionAuth};
1
+ import {h}from'./chunk-SF2BM2YA.mjs';import {useWalletAccountMessageSigner}from'@solana/react';import {getWalletClient}from'@wagmi/core';import {useEffect,useRef,useCallback}from'react';import {jsx}from'react/jsx-runtime';var u=null;async function K(){for(let n=0;n<15;n++){if(u)return u();await new Promise(t=>setTimeout(t,200));}throw new Error("[QuasarSDK] Auth helper not initialized. Ensure QuasarAuthBridge is mounted and wallet is connected.")}function x({activeConnection:n,store:t,wagmiConfig:r,session:e,setSession:i,maxAge:o,onAddressMismatch:s}){let d=typeof n?.chainId=="string"?"SOLANA":"EVM";return useEffect(()=>{e&&n?.address&&e.walletAddress!==n.address&&(console.log("[QuasarSDK] Address mismatch detected, clearing session..."),i(null),s?.());},[n?.address,e,i,s]),!n?.isConnected||!t?null:d==="SOLANA"?jsx(M,{connectedAccount:n.connectedAccount,store:t,session:e,setSession:i,maxAge:o}):jsx(Q,{wagmiConfig:r,store:t,session:e,setSession:i,maxAge:o})}function M({connectedAccount:n,store:t,session:r,setSession:e,maxAge:i}){let o=useWalletAccountMessageSigner(n),s=useRef(o),c=useRef(r),d=useRef(e);useEffect(()=>{s.current=o;},[o]),useEffect(()=>{c.current=r;},[r]),useEffect(()=>{d.current=e;},[e]);let l=useCallback(async()=>{let g=t.getState().activeConnection;if(!g?.isConnected)throw new Error("[QuasarSDK] Wallet disconnected");let h$1=s.current;if(!h$1)throw new Error("[QuasarSDK] Solana Message Signer not initialized.");return h({isConnected:g.isConnected,address:g.address,chainType:"SOLANA",signer:h$1},{miniSession:c.current,setMiniSession:d.current},i)},[t,i]);return useEffect(()=>(u=l,()=>{u===l&&(u=null);}),[l]),null}function Q({wagmiConfig:n,store:t,session:r,setSession:e,maxAge:i}){let o=useRef(r),s=useRef(e);useEffect(()=>{o.current=r;},[r]),useEffect(()=>{s.current=e;},[e]);let c=useCallback(async()=>{let l=t.getState().activeConnection;if(!l?.isConnected)throw new Error("[QuasarSDK] Wallet disconnected");let A=await getWalletClient(n);if(!A)throw new Error("[QuasarSDK] EVM Signer not found");return h({isConnected:l.isConnected,address:l.address,chainType:"EVM",signer:A},{miniSession:o.current,setMiniSession:s.current},i)},[t,n,i]);return useEffect(()=>(u=c,()=>{u===c&&(u=null);}),[c]),null}export{x as QuasarAuthBridge,K as getMiniSessionAuth};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tuwaio/quasar-sdk",
3
- "version": "0.0.6",
3
+ "version": "0.0.8",
4
4
  "private": false,
5
5
  "author": "Oleksandr Tkach",
6
6
  "license": "Apache-2.0",
@@ -1 +0,0 @@
1
- 'use strict';var zustand=require('zustand'),middleware=require('zustand/middleware');var d=(a=>(a.EVM="EVM",a.SOLANA="SOLANA",a))(d||{});var S=300*1e3,f=60*1e3;function m(e){return `Mini-Session Login: ${e}`}async function y(e){let t=new Date().toISOString(),a=m(t);if(e.chainType==="EVM"){let n=e.signer;try{return {signature:await n.signMessage({account:e.walletAddress,message:a}),timestamp:t}}catch(s){throw new Error(`[SDK] EVM signing failed: ${s.message}`,{cause:s})}}if(e.chainType==="SOLANA"){let n=e.signer,s;try{s=await import('gill');}catch(r){throw new Error('[SDK] Peer dependency "gill" is required for Solana signing.',{cause:r})}try{let i=s.getUtf8Encoder().encode(a),g;if(n.modifyAndSignMessages){let o=s.createSignableMessage(i),[l]=await n.modifyAndSignMessages([o]),u=l.signatures[n.address];if(!u)throw new Error(`[SDK] Signature missing for address: ${n.address}`);g=u;}else if(n.signMessages){let[o]=await n.signMessages([i]);if(!o?.signature)throw new Error("[SDK] Wallet returned invalid signMessages output.");g=o.signature;}else if(n.signMessage)g=await n.signMessage(i);else throw new Error("[SDK] Signer lacks message signing capabilities.");return {signature:s.getSignatureFromBytes(g),timestamp:t}}catch(r){throw new Error(`[SDK] Solana signing failed: ${r.message}`,{cause:r})}}throw new Error(`[SDK] Unsupported chain type: ${e.chainType}`)}async function P(e){let t=new Date(e.timestamp).getTime(),a=Date.now();if(isNaN(t))throw new Error("[SDK] Invalid timestamp format. Use ISO string.");let n=e.maxAge??S;if(a-t>n)throw new Error("[SDK] Signature expired. Please sign a fresh message.");if(t>a+f)throw new Error("[SDK] Timestamp is in the future. Check your system clock.");let s=m(e.timestamp);if(e.chainType==="EVM"){let r;try{r=await import('viem');}catch(i){throw new Error('[SDK] Peer dependency "viem" is required for EVM verification.',{cause:i})}return await r.verifyMessage({address:e.walletAddress,message:s,signature:e.signature})}if(e.chainType==="SOLANA"){let r;try{r=await import('gill');}catch(i){throw new Error('[SDK] Peer dependency "gill" is required for Solana verification.',{cause:i})}try{let i=r.address(e.walletAddress);return await r.verifySignatureForAddress(i,e.signature,s)}catch{return false}}return false}function k(e="mini-session-storage"){return zustand.create()(middleware.persist(t=>({miniSession:null,setMiniSession:a=>t({miniSession:a}),clearSession:()=>t({miniSession:null})}),{name:e}))}async function C(e,t){let{isConnected:a,address:n,chainType:s,signer:r}=e;if(!a||!n)throw new Error("[SDK] Wallet not connected. Please connect your wallet first.");let i=t.miniSession;if(i&&i.walletAddress===n&&i.chainType===s){let o=Date.now(),l=new Date(i.timestamp).getTime();if(o-l<S)return i}let c={...await y({signer:r,walletAddress:n,chainType:s}),chainType:s,walletAddress:n};return t.setMiniSession(c),c}exports.a=d;exports.b=S;exports.c=m;exports.d=y;exports.e=P;exports.f=k;exports.g=C;
@@ -1 +0,0 @@
1
- import {create}from'zustand';import {persist}from'zustand/middleware';var d=(a=>(a.EVM="EVM",a.SOLANA="SOLANA",a))(d||{});var S=300*1e3,f=60*1e3;function m(e){return `Mini-Session Login: ${e}`}async function y(e){let t=new Date().toISOString(),a=m(t);if(e.chainType==="EVM"){let n=e.signer;try{return {signature:await n.signMessage({account:e.walletAddress,message:a}),timestamp:t}}catch(s){throw new Error(`[SDK] EVM signing failed: ${s.message}`,{cause:s})}}if(e.chainType==="SOLANA"){let n=e.signer,s;try{s=await import('gill');}catch(r){throw new Error('[SDK] Peer dependency "gill" is required for Solana signing.',{cause:r})}try{let i=s.getUtf8Encoder().encode(a),g;if(n.modifyAndSignMessages){let o=s.createSignableMessage(i),[l]=await n.modifyAndSignMessages([o]),u=l.signatures[n.address];if(!u)throw new Error(`[SDK] Signature missing for address: ${n.address}`);g=u;}else if(n.signMessages){let[o]=await n.signMessages([i]);if(!o?.signature)throw new Error("[SDK] Wallet returned invalid signMessages output.");g=o.signature;}else if(n.signMessage)g=await n.signMessage(i);else throw new Error("[SDK] Signer lacks message signing capabilities.");return {signature:s.getSignatureFromBytes(g),timestamp:t}}catch(r){throw new Error(`[SDK] Solana signing failed: ${r.message}`,{cause:r})}}throw new Error(`[SDK] Unsupported chain type: ${e.chainType}`)}async function P(e){let t=new Date(e.timestamp).getTime(),a=Date.now();if(isNaN(t))throw new Error("[SDK] Invalid timestamp format. Use ISO string.");let n=e.maxAge??S;if(a-t>n)throw new Error("[SDK] Signature expired. Please sign a fresh message.");if(t>a+f)throw new Error("[SDK] Timestamp is in the future. Check your system clock.");let s=m(e.timestamp);if(e.chainType==="EVM"){let r;try{r=await import('viem');}catch(i){throw new Error('[SDK] Peer dependency "viem" is required for EVM verification.',{cause:i})}return await r.verifyMessage({address:e.walletAddress,message:s,signature:e.signature})}if(e.chainType==="SOLANA"){let r;try{r=await import('gill');}catch(i){throw new Error('[SDK] Peer dependency "gill" is required for Solana verification.',{cause:i})}try{let i=r.address(e.walletAddress);return await r.verifySignatureForAddress(i,e.signature,s)}catch{return false}}return false}function k(e="mini-session-storage"){return create()(persist(t=>({miniSession:null,setMiniSession:a=>t({miniSession:a}),clearSession:()=>t({miniSession:null})}),{name:e}))}async function C(e,t){let{isConnected:a,address:n,chainType:s,signer:r}=e;if(!a||!n)throw new Error("[SDK] Wallet not connected. Please connect your wallet first.");let i=t.miniSession;if(i&&i.walletAddress===n&&i.chainType===s){let o=Date.now(),l=new Date(i.timestamp).getTime();if(o-l<S)return i}let c={...await y({signer:r,walletAddress:n,chainType:s}),chainType:s,walletAddress:n};return t.setMiniSession(c),c}export{d as a,S as b,m as c,y as d,P as e,k as f,C as g};