@bloque/sdk-core 0.3.0 → 0.4.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/dist/errors.d.ts +153 -0
- package/dist/index.cjs +1 -1
- package/dist/index.js +1 -1
- package/dist/types.d.ts +13 -0
- package/package.json +1 -1
package/dist/errors.d.ts
CHANGED
|
@@ -1,3 +1,18 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Minimal shape of `HttpClient` that error classes need to make a follow-up
|
|
3
|
+
* request (e.g. `BloqueVerificationRequiredError.getVerificationLink()`
|
|
4
|
+
* calling a gate's `/start` endpoint). Declared structurally here instead of
|
|
5
|
+
* importing `HttpClient` directly to avoid a circular import between
|
|
6
|
+
* `errors.ts` and `http-client.ts` (the latter already imports from this
|
|
7
|
+
* file to construct errors).
|
|
8
|
+
*/
|
|
9
|
+
export interface RequestCapableClient {
|
|
10
|
+
request<T, U = unknown>(options: {
|
|
11
|
+
method: string;
|
|
12
|
+
path: string;
|
|
13
|
+
body?: U;
|
|
14
|
+
}): Promise<T>;
|
|
15
|
+
}
|
|
1
16
|
/**
|
|
2
17
|
* Options for creating a BloqueAPIError.
|
|
3
18
|
*/
|
|
@@ -12,6 +27,16 @@ export interface BloqueAPIErrorOptions {
|
|
|
12
27
|
response?: unknown;
|
|
13
28
|
/** Cause of the error (e.g., network error, parse error) */
|
|
14
29
|
cause?: Error;
|
|
30
|
+
/** Seconds to wait before retrying, from the `Retry-After` header (429s only). */
|
|
31
|
+
retryAfter?: number;
|
|
32
|
+
/**
|
|
33
|
+
* The `HttpClient` that produced this error, threaded through so error
|
|
34
|
+
* classes like `BloqueVerificationRequiredError` can make an authenticated
|
|
35
|
+
* follow-up call (e.g. starting a hosted gate flow) without the caller
|
|
36
|
+
* having to pass their client back in.
|
|
37
|
+
* @internal
|
|
38
|
+
*/
|
|
39
|
+
httpClient?: RequestCapableClient;
|
|
15
40
|
}
|
|
16
41
|
/**
|
|
17
42
|
* Base error class for all Bloque API errors.
|
|
@@ -72,6 +97,42 @@ export declare class BloqueRateLimitError extends BloqueAPIError {
|
|
|
72
97
|
stack: string | undefined;
|
|
73
98
|
};
|
|
74
99
|
}
|
|
100
|
+
/**
|
|
101
|
+
* Error thrown when the compliance engine blocks an action because it would
|
|
102
|
+
* exceed the caller's tier limit for a given window
|
|
103
|
+
* (`E_TIER_LIMIT_EXCEEDED`, HTTP 429) — distinct from the generic API rate
|
|
104
|
+
* limit (`BloqueRateLimitError`), which is about request throughput, not
|
|
105
|
+
* money-movement volume.
|
|
106
|
+
*/
|
|
107
|
+
export declare class BloqueTierLimitExceededError extends BloqueRateLimitError {
|
|
108
|
+
/** The limit window that was exceeded (`per_transaction`, `day`, `week`, `month`, or `year`). */
|
|
109
|
+
readonly window: string;
|
|
110
|
+
/** The specific window key that was exceeded (e.g. a calendar day/week/month/year key), when available. */
|
|
111
|
+
readonly windowKey?: string;
|
|
112
|
+
/** ISO 8601 timestamp when this window resets, when available. */
|
|
113
|
+
readonly resetAt?: string;
|
|
114
|
+
/** The window's limit, in USD minor units (cents), as a decimal string. */
|
|
115
|
+
readonly limitUsdMinorUnits?: string;
|
|
116
|
+
/** USD minor units already consumed in this window, as a decimal string, when available. */
|
|
117
|
+
readonly consumedUsdMinorUnits?: string;
|
|
118
|
+
constructor(_message: string, options?: BloqueAPIErrorOptions);
|
|
119
|
+
toJSON(): {
|
|
120
|
+
window: string;
|
|
121
|
+
windowKey: string | undefined;
|
|
122
|
+
resetAt: string | undefined;
|
|
123
|
+
limitUsdMinorUnits: string | undefined;
|
|
124
|
+
consumedUsdMinorUnits: string | undefined;
|
|
125
|
+
retryAfter: number | undefined;
|
|
126
|
+
name: string;
|
|
127
|
+
message: string;
|
|
128
|
+
status: number | undefined;
|
|
129
|
+
code: string | undefined;
|
|
130
|
+
requestId: string | undefined;
|
|
131
|
+
timestamp: string;
|
|
132
|
+
response: unknown;
|
|
133
|
+
stack: string | undefined;
|
|
134
|
+
};
|
|
135
|
+
}
|
|
75
136
|
/**
|
|
76
137
|
* Error thrown when authentication fails (HTTP 401 or 403).
|
|
77
138
|
*
|
|
@@ -83,6 +144,98 @@ export declare class BloqueRateLimitError extends BloqueAPIError {
|
|
|
83
144
|
export declare class BloqueAuthenticationError extends BloqueAPIError {
|
|
84
145
|
constructor(message: string, options?: BloqueAPIErrorOptions);
|
|
85
146
|
}
|
|
147
|
+
/**
|
|
148
|
+
* Error thrown when the compliance engine blocks an action because the
|
|
149
|
+
* caller's identity has not met the minimum verification tier
|
|
150
|
+
* (`E_VERIFICATION_REQUIRED`, HTTP 403).
|
|
151
|
+
*
|
|
152
|
+
* `reason` tells you *what kind* of verification is outstanding, and
|
|
153
|
+
* `getVerificationLink()` starts the matching hosted gate flow (TOS gate or
|
|
154
|
+
* verification gate) so you don't need to hardcode either endpoint — it
|
|
155
|
+
* reads `start_endpoint`/`method` from the same `verification_flow` handoff
|
|
156
|
+
* the compliance engine returned.
|
|
157
|
+
*/
|
|
158
|
+
export declare class BloqueVerificationRequiredError extends BloqueAuthenticationError {
|
|
159
|
+
/** What kind of verification is outstanding. `'kyc'` has no hosted-page
|
|
160
|
+
* handoff — `getVerificationLink()` returns `null` for it. */
|
|
161
|
+
readonly reason: 'tos' | 'documents' | 'kyc' | 'unknown';
|
|
162
|
+
/** The caller's current effective tier level. */
|
|
163
|
+
readonly currentLevel?: number;
|
|
164
|
+
/** The minimum tier level required for the attempted action. */
|
|
165
|
+
readonly requiredLevel?: number;
|
|
166
|
+
/** Requirement keys still outstanding at the caller's next tier level. */
|
|
167
|
+
readonly missingRequirements: string[];
|
|
168
|
+
/**
|
|
169
|
+
* The subset of `missingRequirements` your user has already submitted
|
|
170
|
+
* and that is waiting on a reviewer. Do not ask for these again — the
|
|
171
|
+
* rest of `missingRequirements` is what is actually actionable.
|
|
172
|
+
*/
|
|
173
|
+
readonly pendingRequirements: string[];
|
|
174
|
+
private readonly verificationFlow?;
|
|
175
|
+
private readonly requestClient?;
|
|
176
|
+
constructor(_message: string, options?: BloqueAPIErrorOptions);
|
|
177
|
+
/**
|
|
178
|
+
* Starts the hosted gate flow this error points to (TOS gate or
|
|
179
|
+
* verification gate) and returns the URL your user should open.
|
|
180
|
+
*
|
|
181
|
+
* Returns `null` when there is no hosted-page handoff for this gap
|
|
182
|
+
* (`reason === 'kyc'`, or the response didn't include one).
|
|
183
|
+
*/
|
|
184
|
+
getVerificationLink(params: {
|
|
185
|
+
returnUrl: string;
|
|
186
|
+
}): Promise<{
|
|
187
|
+
url: string;
|
|
188
|
+
expiresIn: string;
|
|
189
|
+
} | null>;
|
|
190
|
+
toJSON(): {
|
|
191
|
+
reason: "unknown" | "tos" | "documents" | "kyc";
|
|
192
|
+
currentLevel: number | undefined;
|
|
193
|
+
requiredLevel: number | undefined;
|
|
194
|
+
missingRequirements: string[];
|
|
195
|
+
pendingRequirements: string[];
|
|
196
|
+
name: string;
|
|
197
|
+
message: string;
|
|
198
|
+
status: number | undefined;
|
|
199
|
+
code: string | undefined;
|
|
200
|
+
requestId: string | undefined;
|
|
201
|
+
timestamp: string;
|
|
202
|
+
response: unknown;
|
|
203
|
+
stack: string | undefined;
|
|
204
|
+
};
|
|
205
|
+
}
|
|
206
|
+
/**
|
|
207
|
+
* Error thrown when the compliance engine blocks an action but your user
|
|
208
|
+
* has *already submitted* everything it is waiting on
|
|
209
|
+
* (`E_VERIFICATION_PENDING`, HTTP 403).
|
|
210
|
+
*
|
|
211
|
+
* The distinction from {@link BloqueVerificationRequiredError} matters in
|
|
212
|
+
* your UI: there is deliberately no `getVerificationLink()` here, because
|
|
213
|
+
* opening a gate would ask your user to re-send documents a reviewer is
|
|
214
|
+
* already holding. Show them that the review is in progress and retry the
|
|
215
|
+
* original action later — it succeeds once the review lands.
|
|
216
|
+
*/
|
|
217
|
+
export declare class BloqueVerificationPendingError extends BloqueAuthenticationError {
|
|
218
|
+
/** The caller's current effective tier level. */
|
|
219
|
+
readonly currentLevel?: number;
|
|
220
|
+
/** The minimum tier level required for the attempted action. */
|
|
221
|
+
readonly requiredLevel?: number;
|
|
222
|
+
/** Requirement keys submitted and awaiting review. */
|
|
223
|
+
readonly pendingRequirements: string[];
|
|
224
|
+
constructor(_message: string, options?: BloqueAPIErrorOptions);
|
|
225
|
+
toJSON(): {
|
|
226
|
+
currentLevel: number | undefined;
|
|
227
|
+
requiredLevel: number | undefined;
|
|
228
|
+
pendingRequirements: string[];
|
|
229
|
+
name: string;
|
|
230
|
+
message: string;
|
|
231
|
+
status: number | undefined;
|
|
232
|
+
code: string | undefined;
|
|
233
|
+
requestId: string | undefined;
|
|
234
|
+
timestamp: string;
|
|
235
|
+
response: unknown;
|
|
236
|
+
stack: string | undefined;
|
|
237
|
+
};
|
|
238
|
+
}
|
|
86
239
|
/**
|
|
87
240
|
* Error thrown when request validation fails (HTTP 400).
|
|
88
241
|
*
|
package/dist/index.cjs
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";const __rslib_import_meta_url__="u"<typeof document?new(require("url".replace("",""))).URL("file:"+__filename).href:document.currentScript&&document.currentScript.src||new URL("main.js",document.baseURI).href;var __webpack_require__={};__webpack_require__.d=(e,r)=>{for(var t in r)__webpack_require__.o(r,t)&&!__webpack_require__.o(e,t)&&Object.defineProperty(e,t,{enumerable:!0,get:r[t]})},__webpack_require__.o=(e,r)=>Object.prototype.hasOwnProperty.call(e,r),__webpack_require__.r=e=>{"u">typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})};var __webpack_exports__={};__webpack_require__.r(__webpack_exports__),__webpack_require__.d(__webpack_exports__,{BloqueInsufficientFundsError:()=>BloqueInsufficientFundsError,API_BASE_URLS:()=>API_BASE_URLS,BloqueNetworkError:()=>BloqueNetworkError,createBloqueError:()=>createBloqueError,BloqueConfigError:()=>BloqueConfigError,BaseClient:()=>BaseClient,BloqueNotFoundError:()=>BloqueNotFoundError,HttpClient:()=>HttpClient,SUPPORTED_ASSETS:()=>SUPPORTED_ASSETS,BloqueAuthenticationError:()=>BloqueAuthenticationError,BloqueRateLimitError:()=>BloqueRateLimitError,DEFAULT_HEADERS:()=>DEFAULT_HEADERS,BloqueAPIError:()=>BloqueAPIError,BloqueValidationError:()=>BloqueValidationError,isSupportedAsset:()=>isSupportedAsset,BloqueTimeoutError:()=>BloqueTimeoutError});class BaseClient{httpClient;constructor(e){this.httpClient=e}}const API_BASE_URLS={sandbox:"https://api.dev-bloque.app",production:"https://api.bloque.app"},DEFAULT_HEADERS={"Content-Type":"application/json"},SUPPORTED_ASSETS=["DUSD/6","COPB/6","COPM/2","KSM/12"];function isSupportedAsset(e){return SUPPORTED_ASSETS.includes(e)}class BloqueAPIError extends Error{status;code;requestId;timestamp;response;cause;constructor(e,r){super(e),this.name="BloqueAPIError",this.status=r?.status,this.code=r?.code,this.requestId=r?.requestId,this.response=r?.response,this.cause=r?.cause,this.timestamp=new Date,Object.setPrototypeOf(this,BloqueAPIError.prototype)}toJSON(){return{name:this.name,message:this.message,status:this.status,code:this.code,requestId:this.requestId,timestamp:this.timestamp.toISOString(),response:this.response,stack:this.stack}}}class BloqueRateLimitError extends BloqueAPIError{retryAfter;constructor(e,r){super(e,{...r,status:429}),this.name="BloqueRateLimitError",this.retryAfter=r?.retryAfter,Object.setPrototypeOf(this,BloqueRateLimitError.prototype)}toJSON(){return{...super.toJSON(),retryAfter:this.retryAfter}}}class BloqueAuthenticationError extends BloqueAPIError{constructor(e,r){super(e,r),this.name="BloqueAuthenticationError",Object.setPrototypeOf(this,BloqueAuthenticationError.prototype)}}class BloqueValidationError extends BloqueAPIError{validationErrors;constructor(e,r){super(e,{...r,status:400}),this.name="BloqueValidationError",this.validationErrors=r?.validationErrors,Object.setPrototypeOf(this,BloqueValidationError.prototype)}toJSON(){return{...super.toJSON(),validationErrors:this.validationErrors}}}class BloqueNotFoundError extends BloqueAPIError{resourceType;resourceId;constructor(e,r){super(e,{...r,status:404}),this.name="BloqueNotFoundError",this.resourceType=r?.resourceType,this.resourceId=r?.resourceId,Object.setPrototypeOf(this,BloqueNotFoundError.prototype)}toJSON(){return{...super.toJSON(),resourceType:this.resourceType,resourceId:this.resourceId}}}class BloqueInsufficientFundsError extends BloqueAPIError{requestedAmount;availableBalance;currency;constructor(e,r){super(e,r),this.name="BloqueInsufficientFundsError",this.requestedAmount=r?.requestedAmount,this.availableBalance=r?.availableBalance,this.currency=r?.currency,Object.setPrototypeOf(this,BloqueInsufficientFundsError.prototype)}toJSON(){return{...super.toJSON(),requestedAmount:this.requestedAmount,availableBalance:this.availableBalance,currency:this.currency}}}class BloqueNetworkError extends BloqueAPIError{constructor(e,r){super(e,{...r,code:r?.code??"NETWORK_ERROR"}),this.name="BloqueNetworkError",Object.setPrototypeOf(this,BloqueNetworkError.prototype)}}class BloqueTimeoutError extends BloqueAPIError{timeoutMs;constructor(e,r){super(e,{...r,code:"TIMEOUT_ERROR"}),this.name="BloqueTimeoutError",this.timeoutMs=r?.timeoutMs??0,Object.setPrototypeOf(this,BloqueTimeoutError.prototype)}toJSON(){return{...super.toJSON(),timeoutMs:this.timeoutMs}}}class BloqueConfigError extends Error{constructor(e){super(e),this.name="BloqueConfigError",Object.setPrototypeOf(this,BloqueConfigError.prototype)}}const ERROR_CODE_MAP={INSUFFICIENT_FUNDS:BloqueInsufficientFundsError,INSUFFICIENT_BALANCE:BloqueInsufficientFundsError};function createBloqueError(e,r){let{status:t,code:o}=r??{};if(o&&ERROR_CODE_MAP[o])return new ERROR_CODE_MAP[o](e,r);switch(t){case 400:return new BloqueValidationError(e,r);case 401:case 403:return new BloqueAuthenticationError(e,r);case 404:return new BloqueNotFoundError(e,r);case 429:return new BloqueRateLimitError(e,r);default:return new BloqueAPIError(e,r)}}const EXCHANGE_REFRESH_BUFFER_MS=6e4,IDEMPOTENCY_HEADER="Idempotency-Key",IDEMPOTENT_METHODS=new Set(["POST","PUT"]),isFrontendPlatform=e=>"browser"===e||"react-native"===e;class HttpClient{_config;baseUrl;_exchangeExpiry=0;_exchangePromise=null;publicRoutes=["/api/aliases","/api/origins/*/assert","/api/origins/*/connect","/api/origins","/api/api-keys/exchange"];constructor(e){const r={...e};this.validateConfig(r),this._config=r,this.baseUrl=r.baseUrl??API_BASE_URLS[r.mode??"production"]}get origin(){return this._config.origin}get auth(){return this._config.auth}get urn(){return this._config.urn}get accessToken(){return this._config.accessToken}setAccessToken(e){this._config.accessToken=e}setJwtToken(e){if("jwt"!==this._config.auth.type)throw new BloqueConfigError("JWT token can only be set for JWT auth");this._config.tokenStorage?.set(e),this._config.accessToken=e}getJwtToken(){if("jwt"!==this._config.auth.type)throw new BloqueConfigError("JWT token is only available for JWT auth");return this._config.tokenStorage?.get()??null}setUrn(e){this._config.urn=e}setOrigin(e){this._config.origin=e}fork(){return new HttpClient({...this._config})}validateConfig(e){if(e.mode??="production",e.platform??="node",e.timeout??=3e4,e.retry??={},e.retry.enabled??=!0,e.retry.maxRetries??=3,e.retry.initialDelay??=1e3,e.retry.maxDelay??=3e4,!["sandbox","production"].includes(e.mode))throw new BloqueConfigError('Mode must be either "sandbox" or "production"');if(void 0!==e.timeout&&e.timeout<0)throw new BloqueConfigError("Timeout must be a non-negative number");if(void 0!==e.retry.maxRetries&&e.retry.maxRetries<0)throw new BloqueConfigError("maxRetries must be a non-negative number");if(void 0!==e.retry.initialDelay&&e.retry.initialDelay<0)throw new BloqueConfigError("initialDelay must be a non-negative number");if(void 0!==e.retry.maxDelay&&e.retry.maxDelay<0)throw new BloqueConfigError("maxDelay must be a non-negative number");if("apiKey"===e.auth.type){if(!e.auth.apiKey?.trim())throw new BloqueConfigError("API key (sk_ secret key) is required for apiKey authentication");if(isFrontendPlatform(e.platform))throw new BloqueConfigError("API key authentication is not allowed in frontend platforms")}if("originKey"===e.auth.type){if(!e.auth.originKey?.trim())throw new BloqueConfigError("Origin key is required for originKey authentication");if(!e.origin?.trim())throw new BloqueConfigError("Origin is required for originKey authentication");if(isFrontendPlatform(e.platform))throw new BloqueConfigError("Origin key authentication is not allowed in frontend platforms")}if("jwt"===e.auth.type&&"browser"!==e.platform&&!e.tokenStorage)throw new BloqueConfigError("tokenStorage must be provided when using JWT authentication outside browser platform")}isPublicRoute(e){let r=e.split("?")[0];return this.publicRoutes.some(e=>{let t=e.replace(/\*/g,"[^/]+");return RegExp(`^${t}$`).test(r)})}buildAuthHeaders(e){if(this.isPublicRoute(e))return{};if("apiKey"===this._config.auth.type)return this._config.accessToken?{Authorization:`Bearer ${this._config.accessToken}`}:{};if("originKey"===this._config.auth.type)return this._config.accessToken?{Authorization:`Bearer ${this._config.accessToken}`}:{Authorization:this._config.auth.originKey};if("jwt"===this._config.auth.type){if("browser"===this._config.platform)return{};let e=this._config.tokenStorage?.get();if(!e)throw new BloqueConfigError("Authentication token is missing");return{Authorization:`Bearer ${e}`}}return{}}isRetryableError(e){return e instanceof BloqueRateLimitError||e instanceof BloqueNetworkError||e instanceof BloqueTimeoutError||e instanceof Error&&"status"in e&&503===e.status}calculateRetryDelay(e,r){let{initialDelay:t=1e3,maxDelay:o=3e4}=this._config.retry??{};if(r){let e=Number.parseInt(r,10);if(!Number.isNaN(e))return Math.min(1e3*e,o);let t=new Date(r);if(!Number.isNaN(t.getTime()))return Math.min(Math.max(t.getTime()-Date.now(),0),o)}let i=t*2**e,s=.25*i*(2*Math.random()-1);return Math.min(i+s,o)}sleep(e){return new Promise(r=>setTimeout(r,e))}generateIdempotencyKey(){return void 0!==globalThis.crypto&&"function"==typeof globalThis.crypto.randomUUID?globalThis.crypto.randomUUID():`idem_${Date.now()}_${Math.random().toString(36).slice(2)}`}isIdempotencyKeyError(e,r){if(409!==e&&400!==e)return!1;let t=`${r.code??""} ${r.message??""}`.toLowerCase().trim();return t.includes("idempotency-key")||t.includes("idempotency key")||t.includes("duplicated idempotency key")}async ensureExchanged(){"apiKey"!==this._config.auth.type||(this._exchangePromise?await this._exchangePromise:this._config.accessToken&&Date.now()<this._exchangeExpiry-6e4||(this._exchangePromise=(async()=>{try{let e=this._config.auth,r=await this.request({method:"POST",path:"/api/api-keys/exchange",body:{key:e.apiKey,scopes:e.scopes},_skipExchange:!0});if(!r.access_token)throw new BloqueAuthenticationError("API key exchange returned an invalid response (missing access_token)",{status:401});this._config.accessToken=r.access_token,this._exchangeExpiry=Date.now()+1e3*r.expires_in}finally{this._exchangePromise=null}})(),await this._exchangePromise))}async request(e){let r;"apiKey"!==this._config.auth.type||e._skipExchange||await this.ensureExchanged();let{method:t,path:o,body:i,headers:s={},timeout:n}=e,a=`${this.baseUrl}${o}`,u={...DEFAULT_HEADERS,...this.buildAuthHeaders(o),...s};IDEMPOTENT_METHODS.has(t.toUpperCase())&&(u[IDEMPOTENCY_HEADER]=u[IDEMPOTENCY_HEADER]||this.generateIdempotencyKey());let c=void 0!==n?n:this._config.timeout??3e4,{enabled:l=!0,maxRetries:_=3}=this._config.retry??{},p=0;for(;p<=(l?_:0);){let e,o=new AbortController;c>0&&(e=setTimeout(()=>{o.abort()},c));try{let s=await fetch(a,{method:t,headers:u,body:i?JSON.stringify(i):void 0,credentials:"jwt"===this._config.auth.type&&"browser"===this._config.platform?"include":void 0,signal:o.signal});void 0!==e&&clearTimeout(e);let n=await s.json().catch(()=>({}));if(!s.ok){let e=s.headers.get("X-Request-ID")??s.headers.get("Request-ID")??void 0,t=s.headers.get("Retry-After"),o=429===s.status?new BloqueRateLimitError(n.message||"Rate limit exceeded",{status:s.status,code:n.code,requestId:e,response:n,retryAfter:t?Number.parseInt(t,10):void 0}):createBloqueError(n.message||`HTTP ${s.status}: ${s.statusText}`,{status:s.status,code:n.code,requestId:e,response:n});if(this.isIdempotencyKeyError(s.status,n))throw o;if(l&&p<_&&this.isRetryableError(o)){r=o;let e=this.calculateRetryDelay(p,t??void 0);await this.sleep(e),p++;continue}throw o}return n}catch(o){let t;if(void 0!==e&&clearTimeout(e),o&&"object"==typeof o&&"name"in o&&"string"==typeof o.name&&o.name.startsWith("Bloque")&&!this.isRetryableError(o))throw o;if(t=o instanceof Error&&"AbortError"===o.name?new BloqueTimeoutError(`Request timeout after ${c}ms`,{timeoutMs:c,cause:o}):o instanceof Error?new BloqueNetworkError(`Request failed: ${o.message}`,{cause:o}):createBloqueError("Unknown error occurred",{code:"UNKNOWN_ERROR"}),l&&p<_&&this.isRetryableError(t)){r=t;let e=this.calculateRetryDelay(p);await this.sleep(e),p++;continue}throw t}}throw r||createBloqueError("Request failed after retries",{code:"MAX_RETRIES_EXCEEDED"})}}for(var __rspack_i in exports.API_BASE_URLS=__webpack_exports__.API_BASE_URLS,exports.BaseClient=__webpack_exports__.BaseClient,exports.BloqueAPIError=__webpack_exports__.BloqueAPIError,exports.BloqueAuthenticationError=__webpack_exports__.BloqueAuthenticationError,exports.BloqueConfigError=__webpack_exports__.BloqueConfigError,exports.BloqueInsufficientFundsError=__webpack_exports__.BloqueInsufficientFundsError,exports.BloqueNetworkError=__webpack_exports__.BloqueNetworkError,exports.BloqueNotFoundError=__webpack_exports__.BloqueNotFoundError,exports.BloqueRateLimitError=__webpack_exports__.BloqueRateLimitError,exports.BloqueTimeoutError=__webpack_exports__.BloqueTimeoutError,exports.BloqueValidationError=__webpack_exports__.BloqueValidationError,exports.DEFAULT_HEADERS=__webpack_exports__.DEFAULT_HEADERS,exports.HttpClient=__webpack_exports__.HttpClient,exports.SUPPORTED_ASSETS=__webpack_exports__.SUPPORTED_ASSETS,exports.createBloqueError=__webpack_exports__.createBloqueError,exports.isSupportedAsset=__webpack_exports__.isSupportedAsset,__webpack_exports__)-1===["API_BASE_URLS","BaseClient","BloqueAPIError","BloqueAuthenticationError","BloqueConfigError","BloqueInsufficientFundsError","BloqueNetworkError","BloqueNotFoundError","BloqueRateLimitError","BloqueTimeoutError","BloqueValidationError","DEFAULT_HEADERS","HttpClient","SUPPORTED_ASSETS","createBloqueError","isSupportedAsset"].indexOf(__rspack_i)&&(exports[__rspack_i]=__webpack_exports__[__rspack_i]);Object.defineProperty(exports,"__esModule",{value:!0});
|
|
1
|
+
"use strict";const __rslib_import_meta_url__="u"<typeof document?new(require("url".replace("",""))).URL("file:"+__filename).href:document.currentScript&&document.currentScript.src||new URL("main.js",document.baseURI).href;var __webpack_require__={};__webpack_require__.d=(e,r)=>{for(var t in r)__webpack_require__.o(r,t)&&!__webpack_require__.o(e,t)&&Object.defineProperty(e,t,{enumerable:!0,get:r[t]})},__webpack_require__.o=(e,r)=>Object.prototype.hasOwnProperty.call(e,r),__webpack_require__.r=e=>{"u">typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})};var __webpack_exports__={};__webpack_require__.r(__webpack_exports__),__webpack_require__.d(__webpack_exports__,{BloqueInsufficientFundsError:()=>BloqueInsufficientFundsError,API_BASE_URLS:()=>API_BASE_URLS,BloqueNetworkError:()=>BloqueNetworkError,BloqueVerificationRequiredError:()=>BloqueVerificationRequiredError,BloqueConfigError:()=>BloqueConfigError,BloqueTierLimitExceededError:()=>BloqueTierLimitExceededError,createBloqueError:()=>createBloqueError,BaseClient:()=>BaseClient,BloqueNotFoundError:()=>BloqueNotFoundError,HttpClient:()=>HttpClient,SUPPORTED_ASSETS:()=>SUPPORTED_ASSETS,BloqueAuthenticationError:()=>BloqueAuthenticationError,BloqueRateLimitError:()=>BloqueRateLimitError,DEFAULT_HEADERS:()=>DEFAULT_HEADERS,BloqueAPIError:()=>BloqueAPIError,BloqueValidationError:()=>BloqueValidationError,isSupportedAsset:()=>isSupportedAsset,BloqueVerificationPendingError:()=>BloqueVerificationPendingError,BloqueTimeoutError:()=>BloqueTimeoutError});class BaseClient{httpClient;constructor(e){this.httpClient=e}}const API_BASE_URLS={sandbox:"https://api.dev-bloque.app",production:"https://api.bloque.app"},DEFAULT_HEADERS={"Content-Type":"application/json"},SUPPORTED_ASSETS=["DUSD/6","COPB/6","COPM/2","KSM/12"];function isSupportedAsset(e){return SUPPORTED_ASSETS.includes(e)}class BloqueAPIError extends Error{status;code;requestId;timestamp;response;cause;constructor(e,r){super(e),this.name="BloqueAPIError",this.status=r?.status,this.code=r?.code,this.requestId=r?.requestId,this.response=r?.response,this.cause=r?.cause,this.timestamp=new Date,Object.setPrototypeOf(this,BloqueAPIError.prototype)}toJSON(){return{name:this.name,message:this.message,status:this.status,code:this.code,requestId:this.requestId,timestamp:this.timestamp.toISOString(),response:this.response,stack:this.stack}}}class BloqueRateLimitError extends BloqueAPIError{retryAfter;constructor(e,r){super(e,{...r,status:429}),this.name="BloqueRateLimitError",this.retryAfter=r?.retryAfter,Object.setPrototypeOf(this,BloqueRateLimitError.prototype)}toJSON(){return{...super.toJSON(),retryAfter:this.retryAfter}}}function tierLimitMessage(e){if(!e?.window)return"You've reached a usage limit.";let r=void 0!==e.limit_usd_minor_units?` of $${(Number(e.limit_usd_minor_units)/100).toFixed(2)}`:"",t=e.reset_at?` Try again after ${e.reset_at}.`:"";return`You've reached your ${e.window} limit${r}.${t}`}class BloqueTierLimitExceededError extends BloqueRateLimitError{window;windowKey;resetAt;limitUsdMinorUnits;consumedUsdMinorUnits;constructor(e,r){const t=extractExtraDetails(r?.response);super(tierLimitMessage(t),r),this.name="BloqueTierLimitExceededError",this.window=t?.window??"unknown",this.windowKey=t?.window_key,this.resetAt=t?.reset_at,this.limitUsdMinorUnits=t?.limit_usd_minor_units,this.consumedUsdMinorUnits=t?.consumed_usd_minor_units,Object.setPrototypeOf(this,BloqueTierLimitExceededError.prototype)}toJSON(){return{...super.toJSON(),window:this.window,windowKey:this.windowKey,resetAt:this.resetAt,limitUsdMinorUnits:this.limitUsdMinorUnits,consumedUsdMinorUnits:this.consumedUsdMinorUnits}}}class BloqueAuthenticationError extends BloqueAPIError{constructor(e,r){super(e,r),this.name="BloqueAuthenticationError",Object.setPrototypeOf(this,BloqueAuthenticationError.prototype)}}function extractExtraDetails(e){if(e&&"object"==typeof e&&"extra_details"in e)return e.extra_details}function deriveVerificationReason(e,r){return e?.type==="tos_hosted_acceptance"?"tos":e?.type==="document_submission"?"documents":r&&r.length>0?"kyc":"unknown"}function verificationRequiredMessage(e,r){switch(e){case"tos":return"Please accept the Terms of Service before continuing. Call getVerificationLink() to get a link your user can open.";case"documents":return"Additional information or documents are required before continuing. Call getVerificationLink() to get a link your user can open.";case"kyc":return"Identity verification (KYC) is required before continuing.";default:return r?.length?`Verification required: ${r.join(", ")}.`:"Verification required before continuing."}}class BloqueVerificationRequiredError extends BloqueAuthenticationError{reason;currentLevel;requiredLevel;missingRequirements;pendingRequirements;verificationFlow;requestClient;constructor(e,r){const t=extractExtraDetails(r?.response),o=t?.missing_requirements??[],i=deriveVerificationReason(t?.verification_flow,o);super(verificationRequiredMessage(i,o),{...r,code:r?.code??"E_VERIFICATION_REQUIRED"}),this.name="BloqueVerificationRequiredError",this.reason=i,this.currentLevel=t?.current_level,this.requiredLevel=t?.required_level,this.missingRequirements=o,this.pendingRequirements=t?.pending_requirements??[],this.verificationFlow=t?.verification_flow,this.requestClient=r?.httpClient,Object.setPrototypeOf(this,BloqueVerificationRequiredError.prototype)}async getVerificationLink(e){if(!this.verificationFlow?.start_endpoint||!this.requestClient)return null;let r=await this.requestClient.request({method:this.verificationFlow.method??"POST",path:this.verificationFlow.start_endpoint,body:{return_url:e.returnUrl}});return{url:r.url,expiresIn:r.expires_in}}toJSON(){return{...super.toJSON(),reason:this.reason,currentLevel:this.currentLevel,requiredLevel:this.requiredLevel,missingRequirements:this.missingRequirements,pendingRequirements:this.pendingRequirements}}}class BloqueVerificationPendingError extends BloqueAuthenticationError{currentLevel;requiredLevel;pendingRequirements;constructor(e,r){const t=extractExtraDetails(r?.response),o=t?.pending_requirements??[];super("Your submission is being reviewed. No further action is needed right now — retry once the review is complete.",{...r,code:r?.code??"E_VERIFICATION_PENDING"}),this.name="BloqueVerificationPendingError",this.currentLevel=t?.current_level,this.requiredLevel=t?.required_level,this.pendingRequirements=o,Object.setPrototypeOf(this,BloqueVerificationPendingError.prototype)}toJSON(){return{...super.toJSON(),currentLevel:this.currentLevel,requiredLevel:this.requiredLevel,pendingRequirements:this.pendingRequirements}}}class BloqueValidationError extends BloqueAPIError{validationErrors;constructor(e,r){super(e,{...r,status:400}),this.name="BloqueValidationError",this.validationErrors=r?.validationErrors,Object.setPrototypeOf(this,BloqueValidationError.prototype)}toJSON(){return{...super.toJSON(),validationErrors:this.validationErrors}}}class BloqueNotFoundError extends BloqueAPIError{resourceType;resourceId;constructor(e,r){super(e,{...r,status:404}),this.name="BloqueNotFoundError",this.resourceType=r?.resourceType,this.resourceId=r?.resourceId,Object.setPrototypeOf(this,BloqueNotFoundError.prototype)}toJSON(){return{...super.toJSON(),resourceType:this.resourceType,resourceId:this.resourceId}}}class BloqueInsufficientFundsError extends BloqueAPIError{requestedAmount;availableBalance;currency;constructor(e,r){super(e,r),this.name="BloqueInsufficientFundsError",this.requestedAmount=r?.requestedAmount,this.availableBalance=r?.availableBalance,this.currency=r?.currency,Object.setPrototypeOf(this,BloqueInsufficientFundsError.prototype)}toJSON(){return{...super.toJSON(),requestedAmount:this.requestedAmount,availableBalance:this.availableBalance,currency:this.currency}}}class BloqueNetworkError extends BloqueAPIError{constructor(e,r){super(e,{...r,code:r?.code??"NETWORK_ERROR"}),this.name="BloqueNetworkError",Object.setPrototypeOf(this,BloqueNetworkError.prototype)}}class BloqueTimeoutError extends BloqueAPIError{timeoutMs;constructor(e,r){super(e,{...r,code:"TIMEOUT_ERROR"}),this.name="BloqueTimeoutError",this.timeoutMs=r?.timeoutMs??0,Object.setPrototypeOf(this,BloqueTimeoutError.prototype)}toJSON(){return{...super.toJSON(),timeoutMs:this.timeoutMs}}}class BloqueConfigError extends Error{constructor(e){super(e),this.name="BloqueConfigError",Object.setPrototypeOf(this,BloqueConfigError.prototype)}}const ERROR_CODE_MAP={INSUFFICIENT_FUNDS:BloqueInsufficientFundsError,INSUFFICIENT_BALANCE:BloqueInsufficientFundsError};function createBloqueError(e,r){let{status:t,code:o}=r??{};if("E_VERIFICATION_REQUIRED"===o)return new BloqueVerificationRequiredError(e,r);if("E_VERIFICATION_PENDING"===o)return new BloqueVerificationPendingError(e,r);if("E_TIER_LIMIT_EXCEEDED"===o)return new BloqueTierLimitExceededError(e,r);if(o&&ERROR_CODE_MAP[o])return new ERROR_CODE_MAP[o](e,r);switch(t){case 400:return new BloqueValidationError(e,r);case 401:case 403:return new BloqueAuthenticationError(e,r);case 404:return new BloqueNotFoundError(e,r);case 429:return new BloqueRateLimitError(e,r);default:return new BloqueAPIError(e,r)}}const EXCHANGE_REFRESH_BUFFER_MS=6e4,IDEMPOTENCY_HEADER="Idempotency-Key",IDEMPOTENT_METHODS=new Set(["POST","PUT"]),isFrontendPlatform=e=>"browser"===e||"react-native"===e;class HttpClient{_config;baseUrl;_exchangeExpiry=0;_exchangePromise=null;publicRoutes=["/api/aliases","/api/origins/*/assert","/api/origins/*/connect","/api/origins","/api/api-keys/exchange"];constructor(e){const r={...e};this.validateConfig(r),this._config=r,this.baseUrl=r.baseUrl??API_BASE_URLS[r.mode??"production"]}get origin(){return this._config.origin}get auth(){return this._config.auth}get urn(){return this._config.urn}get accessToken(){return this._config.accessToken}setAccessToken(e){this._config.accessToken=e}setJwtToken(e){if("jwt"!==this._config.auth.type)throw new BloqueConfigError("JWT token can only be set for JWT auth");this._config.tokenStorage?.set(e),this._config.accessToken=e}getJwtToken(){if("jwt"!==this._config.auth.type)throw new BloqueConfigError("JWT token is only available for JWT auth");return this._config.tokenStorage?.get()??null}setUrn(e){this._config.urn=e}setOrigin(e){this._config.origin=e}fork(){return new HttpClient({...this._config})}validateConfig(e){if(e.mode??="production",e.platform??="node",e.timeout??=3e4,e.retry??={},e.retry.enabled??=!0,e.retry.maxRetries??=3,e.retry.initialDelay??=1e3,e.retry.maxDelay??=3e4,!["sandbox","production"].includes(e.mode))throw new BloqueConfigError('Mode must be either "sandbox" or "production"');if(void 0!==e.timeout&&e.timeout<0)throw new BloqueConfigError("Timeout must be a non-negative number");if(void 0!==e.retry.maxRetries&&e.retry.maxRetries<0)throw new BloqueConfigError("maxRetries must be a non-negative number");if(void 0!==e.retry.initialDelay&&e.retry.initialDelay<0)throw new BloqueConfigError("initialDelay must be a non-negative number");if(void 0!==e.retry.maxDelay&&e.retry.maxDelay<0)throw new BloqueConfigError("maxDelay must be a non-negative number");if("apiKey"===e.auth.type){if(!e.auth.apiKey?.trim())throw new BloqueConfigError("API key (sk_ secret key) is required for apiKey authentication");if(isFrontendPlatform(e.platform))throw new BloqueConfigError("API key authentication is not allowed in frontend platforms")}if("originKey"===e.auth.type){if(!e.auth.originKey?.trim())throw new BloqueConfigError("Origin key is required for originKey authentication");if(!e.origin?.trim())throw new BloqueConfigError("Origin is required for originKey authentication");if(isFrontendPlatform(e.platform))throw new BloqueConfigError("Origin key authentication is not allowed in frontend platforms")}if("jwt"===e.auth.type&&"browser"!==e.platform&&!e.tokenStorage)throw new BloqueConfigError("tokenStorage must be provided when using JWT authentication outside browser platform")}isPublicRoute(e){let r=e.split("?")[0];return this.publicRoutes.some(e=>{let t=e.replace(/\*/g,"[^/]+");return RegExp(`^${t}$`).test(r)})}buildAuthHeaders(e){if(this.isPublicRoute(e))return{};if("apiKey"===this._config.auth.type)return this._config.accessToken?{Authorization:`Bearer ${this._config.accessToken}`}:{};if("originKey"===this._config.auth.type)return this._config.accessToken?{Authorization:`Bearer ${this._config.accessToken}`}:{Authorization:this._config.auth.originKey};if("jwt"===this._config.auth.type){if("browser"===this._config.platform)return{};let e=this._config.tokenStorage?.get();if(!e)throw new BloqueConfigError("Authentication token is missing");return{Authorization:`Bearer ${e}`}}return{}}isRetryableError(e){return e instanceof BloqueRateLimitError||e instanceof BloqueNetworkError||e instanceof BloqueTimeoutError||e instanceof Error&&"status"in e&&503===e.status}calculateRetryDelay(e,r){let{initialDelay:t=1e3,maxDelay:o=3e4}=this._config.retry??{};if(r){let e=Number.parseInt(r,10);if(!Number.isNaN(e))return Math.min(1e3*e,o);let t=new Date(r);if(!Number.isNaN(t.getTime()))return Math.min(Math.max(t.getTime()-Date.now(),0),o)}let i=t*2**e,n=.25*i*(2*Math.random()-1);return Math.min(i+n,o)}sleep(e){return new Promise(r=>setTimeout(r,e))}generateIdempotencyKey(){return void 0!==globalThis.crypto&&"function"==typeof globalThis.crypto.randomUUID?globalThis.crypto.randomUUID():`idem_${Date.now()}_${Math.random().toString(36).slice(2)}`}isIdempotencyKeyError(e,r){if(409!==e&&400!==e)return!1;let t=`${r.code??""} ${r.message??""}`.toLowerCase().trim();return t.includes("idempotency-key")||t.includes("idempotency key")||t.includes("duplicated idempotency key")}async ensureExchanged(){"apiKey"!==this._config.auth.type||(this._exchangePromise?await this._exchangePromise:this._config.accessToken&&Date.now()<this._exchangeExpiry-6e4||(this._exchangePromise=(async()=>{try{let e=this._config.auth,r=await this.request({method:"POST",path:"/api/api-keys/exchange",body:{key:e.apiKey,scopes:e.scopes},_skipExchange:!0});if(!r.access_token)throw new BloqueAuthenticationError("API key exchange returned an invalid response (missing access_token)",{status:401});this._config.accessToken=r.access_token,this._exchangeExpiry=Date.now()+1e3*r.expires_in}finally{this._exchangePromise=null}})(),await this._exchangePromise))}async request(e){let r;"apiKey"!==this._config.auth.type||e._skipExchange||await this.ensureExchanged();let{method:t,path:o,body:i,headers:n={},timeout:s,authorizationOverride:u}=e,a=`${this.baseUrl}${o}`,c={...DEFAULT_HEADERS,...u?{Authorization:u}:this.buildAuthHeaders(o),...n};IDEMPOTENT_METHODS.has(t.toUpperCase())&&(c[IDEMPOTENCY_HEADER]=c[IDEMPOTENCY_HEADER]||this.generateIdempotencyKey());let l=void 0!==s?s:this._config.timeout??3e4,{enabled:_=!0,maxRetries:p=3}=this._config.retry??{},d=0;for(;d<=(_?p:0);){let e,o=new AbortController;l>0&&(e=setTimeout(()=>{o.abort()},l));try{let n=await fetch(a,{method:t,headers:c,body:i?JSON.stringify(i):void 0,credentials:"jwt"===this._config.auth.type&&"browser"===this._config.platform?"include":void 0,signal:o.signal});void 0!==e&&clearTimeout(e);let s=await n.json().catch(()=>({}));if(!n.ok){let e=n.headers.get("X-Request-ID")??n.headers.get("Request-ID")??void 0,t=n.headers.get("Retry-After"),o=createBloqueError(s.message||(429===n.status?"Rate limit exceeded":`HTTP ${n.status}: ${n.statusText}`),{status:n.status,code:s.code,requestId:e,response:s,retryAfter:t?Number.parseInt(t,10):void 0,httpClient:this});if(this.isIdempotencyKeyError(n.status,s))throw o;if(_&&d<p&&this.isRetryableError(o)){r=o;let e=this.calculateRetryDelay(d,t??void 0);await this.sleep(e),d++;continue}throw o}return s}catch(o){let t;if(void 0!==e&&clearTimeout(e),o&&"object"==typeof o&&"name"in o&&"string"==typeof o.name&&o.name.startsWith("Bloque")&&!this.isRetryableError(o))throw o;if(t=o instanceof Error&&"AbortError"===o.name?new BloqueTimeoutError(`Request timeout after ${l}ms`,{timeoutMs:l,cause:o}):o instanceof Error?new BloqueNetworkError(`Request failed: ${o.message}`,{cause:o}):createBloqueError("Unknown error occurred",{code:"UNKNOWN_ERROR"}),_&&d<p&&this.isRetryableError(t)){r=t;let e=this.calculateRetryDelay(d);await this.sleep(e),d++;continue}throw t}}throw r||createBloqueError("Request failed after retries",{code:"MAX_RETRIES_EXCEEDED"})}}for(var __rspack_i in exports.API_BASE_URLS=__webpack_exports__.API_BASE_URLS,exports.BaseClient=__webpack_exports__.BaseClient,exports.BloqueAPIError=__webpack_exports__.BloqueAPIError,exports.BloqueAuthenticationError=__webpack_exports__.BloqueAuthenticationError,exports.BloqueConfigError=__webpack_exports__.BloqueConfigError,exports.BloqueInsufficientFundsError=__webpack_exports__.BloqueInsufficientFundsError,exports.BloqueNetworkError=__webpack_exports__.BloqueNetworkError,exports.BloqueNotFoundError=__webpack_exports__.BloqueNotFoundError,exports.BloqueRateLimitError=__webpack_exports__.BloqueRateLimitError,exports.BloqueTierLimitExceededError=__webpack_exports__.BloqueTierLimitExceededError,exports.BloqueTimeoutError=__webpack_exports__.BloqueTimeoutError,exports.BloqueValidationError=__webpack_exports__.BloqueValidationError,exports.BloqueVerificationPendingError=__webpack_exports__.BloqueVerificationPendingError,exports.BloqueVerificationRequiredError=__webpack_exports__.BloqueVerificationRequiredError,exports.DEFAULT_HEADERS=__webpack_exports__.DEFAULT_HEADERS,exports.HttpClient=__webpack_exports__.HttpClient,exports.SUPPORTED_ASSETS=__webpack_exports__.SUPPORTED_ASSETS,exports.createBloqueError=__webpack_exports__.createBloqueError,exports.isSupportedAsset=__webpack_exports__.isSupportedAsset,__webpack_exports__)-1===["API_BASE_URLS","BaseClient","BloqueAPIError","BloqueAuthenticationError","BloqueConfigError","BloqueInsufficientFundsError","BloqueNetworkError","BloqueNotFoundError","BloqueRateLimitError","BloqueTierLimitExceededError","BloqueTimeoutError","BloqueValidationError","BloqueVerificationPendingError","BloqueVerificationRequiredError","DEFAULT_HEADERS","HttpClient","SUPPORTED_ASSETS","createBloqueError","isSupportedAsset"].indexOf(__rspack_i)&&(exports[__rspack_i]=__webpack_exports__[__rspack_i]);Object.defineProperty(exports,"__esModule",{value:!0});
|
package/dist/index.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
class e{httpClient;constructor(e){this.httpClient=e}}let t={sandbox:"https://api.dev-bloque.app",production:"https://api.bloque.app"},r={"Content-Type":"application/json"},i=["DUSD/6","COPB/6","COPM/2","KSM/12"];function s(e){return i.includes(e)}class o extends Error{status;code;requestId;timestamp;response;cause;constructor(e,t){super(e),this.name="BloqueAPIError",this.status=t?.status,this.code=t?.code,this.requestId=t?.requestId,this.response=t?.response,this.cause=t?.cause,this.timestamp=new Date,Object.setPrototypeOf(this,o.prototype)}toJSON(){return{name:this.name,message:this.message,status:this.status,code:this.code,requestId:this.requestId,timestamp:this.timestamp.toISOString(),response:this.response,stack:this.stack}}}class n extends o{retryAfter;constructor(e,t){super(e,{...t,status:429}),this.name="BloqueRateLimitError",this.retryAfter=t?.retryAfter,Object.setPrototypeOf(this,n.prototype)}toJSON(){return{...super.toJSON(),retryAfter:this.retryAfter}}}class a extends o{constructor(e,t){super(e,t),this.name="BloqueAuthenticationError",Object.setPrototypeOf(this,a.prototype)}}class u extends o{validationErrors;constructor(e,t){super(e,{...t,status:400}),this.name="BloqueValidationError",this.validationErrors=t?.validationErrors,Object.setPrototypeOf(this,u.prototype)}toJSON(){return{...super.toJSON(),validationErrors:this.validationErrors}}}class c extends o{resourceType;resourceId;constructor(e,t){super(e,{...t,status:404}),this.name="BloqueNotFoundError",this.resourceType=t?.resourceType,this.resourceId=t?.resourceId,Object.setPrototypeOf(this,c.prototype)}toJSON(){return{...super.toJSON(),resourceType:this.resourceType,resourceId:this.resourceId}}}class h extends o{requestedAmount;availableBalance;currency;constructor(e,t){super(e,t),this.name="BloqueInsufficientFundsError",this.requestedAmount=t?.requestedAmount,this.availableBalance=t?.availableBalance,this.currency=t?.currency,Object.setPrototypeOf(this,h.prototype)}toJSON(){return{...super.toJSON(),requestedAmount:this.requestedAmount,availableBalance:this.availableBalance,currency:this.currency}}}class l extends o{constructor(e,t){super(e,{...t,code:t?.code??"NETWORK_ERROR"}),this.name="BloqueNetworkError",Object.setPrototypeOf(this,l.prototype)}}class p extends o{timeoutMs;constructor(e,t){super(e,{...t,code:"TIMEOUT_ERROR"}),this.name="BloqueTimeoutError",this.timeoutMs=t?.timeoutMs??0,Object.setPrototypeOf(this,p.prototype)}toJSON(){return{...super.toJSON(),timeoutMs:this.timeoutMs}}}class y extends Error{constructor(e){super(e),this.name="BloqueConfigError",Object.setPrototypeOf(this,y.prototype)}}let d={INSUFFICIENT_FUNDS:h,INSUFFICIENT_BALANCE:h};function f(e,t){let{status:r,code:i}=t??{};if(i&&d[i])return new d[i](e,t);switch(r){case 400:return new u(e,t);case 401:case 403:return new a(e,t);case 404:return new c(e,t);case 429:return new n(e,t);default:return new o(e,t)}}let m="Idempotency-Key",g=new Set(["POST","PUT"]),w=e=>"browser"===e||"react-native"===e;class b{_config;baseUrl;_exchangeExpiry=0;_exchangePromise=null;publicRoutes=["/api/aliases","/api/origins/*/assert","/api/origins/*/connect","/api/origins","/api/api-keys/exchange"];constructor(e){let r={...e};this.validateConfig(r),this._config=r,this.baseUrl=r.baseUrl??t[r.mode??"production"]}get origin(){return this._config.origin}get auth(){return this._config.auth}get urn(){return this._config.urn}get accessToken(){return this._config.accessToken}setAccessToken(e){this._config.accessToken=e}setJwtToken(e){if("jwt"!==this._config.auth.type)throw new y("JWT token can only be set for JWT auth");this._config.tokenStorage?.set(e),this._config.accessToken=e}getJwtToken(){if("jwt"!==this._config.auth.type)throw new y("JWT token is only available for JWT auth");return this._config.tokenStorage?.get()??null}setUrn(e){this._config.urn=e}setOrigin(e){this._config.origin=e}fork(){return new b({...this._config})}validateConfig(e){if(e.mode??="production",e.platform??="node",e.timeout??=3e4,e.retry??={},e.retry.enabled??=!0,e.retry.maxRetries??=3,e.retry.initialDelay??=1e3,e.retry.maxDelay??=3e4,!["sandbox","production"].includes(e.mode))throw new y('Mode must be either "sandbox" or "production"');if(void 0!==e.timeout&&e.timeout<0)throw new y("Timeout must be a non-negative number");if(void 0!==e.retry.maxRetries&&e.retry.maxRetries<0)throw new y("maxRetries must be a non-negative number");if(void 0!==e.retry.initialDelay&&e.retry.initialDelay<0)throw new y("initialDelay must be a non-negative number");if(void 0!==e.retry.maxDelay&&e.retry.maxDelay<0)throw new y("maxDelay must be a non-negative number");if("apiKey"===e.auth.type){if(!e.auth.apiKey?.trim())throw new y("API key (sk_ secret key) is required for apiKey authentication");if(w(e.platform))throw new y("API key authentication is not allowed in frontend platforms")}if("originKey"===e.auth.type){if(!e.auth.originKey?.trim())throw new y("Origin key is required for originKey authentication");if(!e.origin?.trim())throw new y("Origin is required for originKey authentication");if(w(e.platform))throw new y("Origin key authentication is not allowed in frontend platforms")}if("jwt"===e.auth.type&&"browser"!==e.platform&&!e.tokenStorage)throw new y("tokenStorage must be provided when using JWT authentication outside browser platform")}isPublicRoute(e){let t=e.split("?")[0];return this.publicRoutes.some(e=>{let r=e.replace(/\*/g,"[^/]+");return RegExp(`^${r}$`).test(t)})}buildAuthHeaders(e){if(this.isPublicRoute(e))return{};if("apiKey"===this._config.auth.type)return this._config.accessToken?{Authorization:`Bearer ${this._config.accessToken}`}:{};if("originKey"===this._config.auth.type)return this._config.accessToken?{Authorization:`Bearer ${this._config.accessToken}`}:{Authorization:this._config.auth.originKey};if("jwt"===this._config.auth.type){if("browser"===this._config.platform)return{};let e=this._config.tokenStorage?.get();if(!e)throw new y("Authentication token is missing");return{Authorization:`Bearer ${e}`}}return{}}isRetryableError(e){return e instanceof n||e instanceof l||e instanceof p||e instanceof Error&&"status"in e&&503===e.status}calculateRetryDelay(e,t){let{initialDelay:r=1e3,maxDelay:i=3e4}=this._config.retry??{};if(t){let e=Number.parseInt(t,10);if(!Number.isNaN(e))return Math.min(1e3*e,i);let r=new Date(t);if(!Number.isNaN(r.getTime()))return Math.min(Math.max(r.getTime()-Date.now(),0),i)}let s=r*2**e,o=.25*s*(2*Math.random()-1);return Math.min(s+o,i)}sleep(e){return new Promise(t=>setTimeout(t,e))}generateIdempotencyKey(){return void 0!==globalThis.crypto&&"function"==typeof globalThis.crypto.randomUUID?globalThis.crypto.randomUUID():`idem_${Date.now()}_${Math.random().toString(36).slice(2)}`}isIdempotencyKeyError(e,t){if(409!==e&&400!==e)return!1;let r=`${t.code??""} ${t.message??""}`.toLowerCase().trim();return r.includes("idempotency-key")||r.includes("idempotency key")||r.includes("duplicated idempotency key")}async ensureExchanged(){"apiKey"!==this._config.auth.type||(this._exchangePromise?await this._exchangePromise:this._config.accessToken&&Date.now()<this._exchangeExpiry-6e4||(this._exchangePromise=(async()=>{try{let e=this._config.auth,t=await this.request({method:"POST",path:"/api/api-keys/exchange",body:{key:e.apiKey,scopes:e.scopes},_skipExchange:!0});if(!t.access_token)throw new a("API key exchange returned an invalid response (missing access_token)",{status:401});this._config.accessToken=t.access_token,this._exchangeExpiry=Date.now()+1e3*t.expires_in}finally{this._exchangePromise=null}})(),await this._exchangePromise))}async request(e){let t;"apiKey"!==this._config.auth.type||e._skipExchange||await this.ensureExchanged();let{method:i,path:s,body:o,headers:a={},timeout:u}=e,c=`${this.baseUrl}${s}`,h={...r,...this.buildAuthHeaders(s),...a};g.has(i.toUpperCase())&&(h[m]=h[m]||this.generateIdempotencyKey());let y=void 0!==u?u:this._config.timeout??3e4,{enabled:d=!0,maxRetries:w=3}=this._config.retry??{},b=0;for(;b<=(d?w:0);){let e,r=new AbortController;y>0&&(e=setTimeout(()=>{r.abort()},y));try{let s=await fetch(c,{method:i,headers:h,body:o?JSON.stringify(o):void 0,credentials:"jwt"===this._config.auth.type&&"browser"===this._config.platform?"include":void 0,signal:r.signal});void 0!==e&&clearTimeout(e);let a=await s.json().catch(()=>({}));if(!s.ok){let e=s.headers.get("X-Request-ID")??s.headers.get("Request-ID")??void 0,r=s.headers.get("Retry-After"),i=429===s.status?new n(a.message||"Rate limit exceeded",{status:s.status,code:a.code,requestId:e,response:a,retryAfter:r?Number.parseInt(r,10):void 0}):f(a.message||`HTTP ${s.status}: ${s.statusText}`,{status:s.status,code:a.code,requestId:e,response:a});if(this.isIdempotencyKeyError(s.status,a))throw i;if(d&&b<w&&this.isRetryableError(i)){t=i;let e=this.calculateRetryDelay(b,r??void 0);await this.sleep(e),b++;continue}throw i}return a}catch(i){let r;if(void 0!==e&&clearTimeout(e),i&&"object"==typeof i&&"name"in i&&"string"==typeof i.name&&i.name.startsWith("Bloque")&&!this.isRetryableError(i))throw i;if(r=i instanceof Error&&"AbortError"===i.name?new p(`Request timeout after ${y}ms`,{timeoutMs:y,cause:i}):i instanceof Error?new l(`Request failed: ${i.message}`,{cause:i}):f("Unknown error occurred",{code:"UNKNOWN_ERROR"}),d&&b<w&&this.isRetryableError(r)){t=r;let e=this.calculateRetryDelay(b);await this.sleep(e),b++;continue}throw r}}throw t||f("Request failed after retries",{code:"MAX_RETRIES_EXCEEDED"})}}export{t as API_BASE_URLS,e as BaseClient,o as BloqueAPIError,a as BloqueAuthenticationError,y as BloqueConfigError,h as BloqueInsufficientFundsError,l as BloqueNetworkError,c as BloqueNotFoundError,n as BloqueRateLimitError,p as BloqueTimeoutError,u as BloqueValidationError,r as DEFAULT_HEADERS,b as HttpClient,i as SUPPORTED_ASSETS,f as createBloqueError,s as isSupportedAsset};
|
|
1
|
+
class e{httpClient;constructor(e){this.httpClient=e}}let t={sandbox:"https://api.dev-bloque.app",production:"https://api.bloque.app"},r={"Content-Type":"application/json"},i=["DUSD/6","COPB/6","COPM/2","KSM/12"];function s(e){return i.includes(e)}class n extends Error{status;code;requestId;timestamp;response;cause;constructor(e,t){super(e),this.name="BloqueAPIError",this.status=t?.status,this.code=t?.code,this.requestId=t?.requestId,this.response=t?.response,this.cause=t?.cause,this.timestamp=new Date,Object.setPrototypeOf(this,n.prototype)}toJSON(){return{name:this.name,message:this.message,status:this.status,code:this.code,requestId:this.requestId,timestamp:this.timestamp.toISOString(),response:this.response,stack:this.stack}}}class o extends n{retryAfter;constructor(e,t){super(e,{...t,status:429}),this.name="BloqueRateLimitError",this.retryAfter=t?.retryAfter,Object.setPrototypeOf(this,o.prototype)}toJSON(){return{...super.toJSON(),retryAfter:this.retryAfter}}}class a extends o{window;windowKey;resetAt;limitUsdMinorUnits;consumedUsdMinorUnits;constructor(e,t){let r=c(t?.response);super(function(e){if(!e?.window)return"You've reached a usage limit.";let t=void 0!==e.limit_usd_minor_units?` of $${(Number(e.limit_usd_minor_units)/100).toFixed(2)}`:"",r=e.reset_at?` Try again after ${e.reset_at}.`:"";return`You've reached your ${e.window} limit${t}.${r}`}(r),t),this.name="BloqueTierLimitExceededError",this.window=r?.window??"unknown",this.windowKey=r?.window_key,this.resetAt=r?.reset_at,this.limitUsdMinorUnits=r?.limit_usd_minor_units,this.consumedUsdMinorUnits=r?.consumed_usd_minor_units,Object.setPrototypeOf(this,a.prototype)}toJSON(){return{...super.toJSON(),window:this.window,windowKey:this.windowKey,resetAt:this.resetAt,limitUsdMinorUnits:this.limitUsdMinorUnits,consumedUsdMinorUnits:this.consumedUsdMinorUnits}}}class u extends n{constructor(e,t){super(e,t),this.name="BloqueAuthenticationError",Object.setPrototypeOf(this,u.prototype)}}function c(e){if(e&&"object"==typeof e&&"extra_details"in e)return e.extra_details}class h extends u{reason;currentLevel;requiredLevel;missingRequirements;pendingRequirements;verificationFlow;requestClient;constructor(e,t){var r;let i=c(t?.response),s=i?.missing_requirements??[],n=(r=i?.verification_flow,r?.type==="tos_hosted_acceptance"?"tos":r?.type==="document_submission"?"documents":s&&s.length>0?"kyc":"unknown");super(function(e,t){switch(e){case"tos":return"Please accept the Terms of Service before continuing. Call getVerificationLink() to get a link your user can open.";case"documents":return"Additional information or documents are required before continuing. Call getVerificationLink() to get a link your user can open.";case"kyc":return"Identity verification (KYC) is required before continuing.";default:return t?.length?`Verification required: ${t.join(", ")}.`:"Verification required before continuing."}}(n,s),{...t,code:t?.code??"E_VERIFICATION_REQUIRED"}),this.name="BloqueVerificationRequiredError",this.reason=n,this.currentLevel=i?.current_level,this.requiredLevel=i?.required_level,this.missingRequirements=s,this.pendingRequirements=i?.pending_requirements??[],this.verificationFlow=i?.verification_flow,this.requestClient=t?.httpClient,Object.setPrototypeOf(this,h.prototype)}async getVerificationLink(e){if(!this.verificationFlow?.start_endpoint||!this.requestClient)return null;let t=await this.requestClient.request({method:this.verificationFlow.method??"POST",path:this.verificationFlow.start_endpoint,body:{return_url:e.returnUrl}});return{url:t.url,expiresIn:t.expires_in}}toJSON(){return{...super.toJSON(),reason:this.reason,currentLevel:this.currentLevel,requiredLevel:this.requiredLevel,missingRequirements:this.missingRequirements,pendingRequirements:this.pendingRequirements}}}class l extends u{currentLevel;requiredLevel;pendingRequirements;constructor(e,t){let r=c(t?.response),i=r?.pending_requirements??[];super("Your submission is being reviewed. No further action is needed right now — retry once the review is complete.",{...t,code:t?.code??"E_VERIFICATION_PENDING"}),this.name="BloqueVerificationPendingError",this.currentLevel=r?.current_level,this.requiredLevel=r?.required_level,this.pendingRequirements=i,Object.setPrototypeOf(this,l.prototype)}toJSON(){return{...super.toJSON(),currentLevel:this.currentLevel,requiredLevel:this.requiredLevel,pendingRequirements:this.pendingRequirements}}}class d extends n{validationErrors;constructor(e,t){super(e,{...t,status:400}),this.name="BloqueValidationError",this.validationErrors=t?.validationErrors,Object.setPrototypeOf(this,d.prototype)}toJSON(){return{...super.toJSON(),validationErrors:this.validationErrors}}}class p extends n{resourceType;resourceId;constructor(e,t){super(e,{...t,status:404}),this.name="BloqueNotFoundError",this.resourceType=t?.resourceType,this.resourceId=t?.resourceId,Object.setPrototypeOf(this,p.prototype)}toJSON(){return{...super.toJSON(),resourceType:this.resourceType,resourceId:this.resourceId}}}class m extends n{requestedAmount;availableBalance;currency;constructor(e,t){super(e,t),this.name="BloqueInsufficientFundsError",this.requestedAmount=t?.requestedAmount,this.availableBalance=t?.availableBalance,this.currency=t?.currency,Object.setPrototypeOf(this,m.prototype)}toJSON(){return{...super.toJSON(),requestedAmount:this.requestedAmount,availableBalance:this.availableBalance,currency:this.currency}}}class f extends n{constructor(e,t){super(e,{...t,code:t?.code??"NETWORK_ERROR"}),this.name="BloqueNetworkError",Object.setPrototypeOf(this,f.prototype)}}class y extends n{timeoutMs;constructor(e,t){super(e,{...t,code:"TIMEOUT_ERROR"}),this.name="BloqueTimeoutError",this.timeoutMs=t?.timeoutMs??0,Object.setPrototypeOf(this,y.prototype)}toJSON(){return{...super.toJSON(),timeoutMs:this.timeoutMs}}}class g extends Error{constructor(e){super(e),this.name="BloqueConfigError",Object.setPrototypeOf(this,g.prototype)}}let w={INSUFFICIENT_FUNDS:m,INSUFFICIENT_BALANCE:m};function _(e,t){let{status:r,code:i}=t??{};if("E_VERIFICATION_REQUIRED"===i)return new h(e,t);if("E_VERIFICATION_PENDING"===i)return new l(e,t);if("E_TIER_LIMIT_EXCEEDED"===i)return new a(e,t);if(i&&w[i])return new w[i](e,t);switch(r){case 400:return new d(e,t);case 401:case 403:return new u(e,t);case 404:return new p(e,t);case 429:return new o(e,t);default:return new n(e,t)}}let E="Idempotency-Key",q=new Set(["POST","PUT"]),b=e=>"browser"===e||"react-native"===e;class v{_config;baseUrl;_exchangeExpiry=0;_exchangePromise=null;publicRoutes=["/api/aliases","/api/origins/*/assert","/api/origins/*/connect","/api/origins","/api/api-keys/exchange"];constructor(e){let r={...e};this.validateConfig(r),this._config=r,this.baseUrl=r.baseUrl??t[r.mode??"production"]}get origin(){return this._config.origin}get auth(){return this._config.auth}get urn(){return this._config.urn}get accessToken(){return this._config.accessToken}setAccessToken(e){this._config.accessToken=e}setJwtToken(e){if("jwt"!==this._config.auth.type)throw new g("JWT token can only be set for JWT auth");this._config.tokenStorage?.set(e),this._config.accessToken=e}getJwtToken(){if("jwt"!==this._config.auth.type)throw new g("JWT token is only available for JWT auth");return this._config.tokenStorage?.get()??null}setUrn(e){this._config.urn=e}setOrigin(e){this._config.origin=e}fork(){return new v({...this._config})}validateConfig(e){if(e.mode??="production",e.platform??="node",e.timeout??=3e4,e.retry??={},e.retry.enabled??=!0,e.retry.maxRetries??=3,e.retry.initialDelay??=1e3,e.retry.maxDelay??=3e4,!["sandbox","production"].includes(e.mode))throw new g('Mode must be either "sandbox" or "production"');if(void 0!==e.timeout&&e.timeout<0)throw new g("Timeout must be a non-negative number");if(void 0!==e.retry.maxRetries&&e.retry.maxRetries<0)throw new g("maxRetries must be a non-negative number");if(void 0!==e.retry.initialDelay&&e.retry.initialDelay<0)throw new g("initialDelay must be a non-negative number");if(void 0!==e.retry.maxDelay&&e.retry.maxDelay<0)throw new g("maxDelay must be a non-negative number");if("apiKey"===e.auth.type){if(!e.auth.apiKey?.trim())throw new g("API key (sk_ secret key) is required for apiKey authentication");if(b(e.platform))throw new g("API key authentication is not allowed in frontend platforms")}if("originKey"===e.auth.type){if(!e.auth.originKey?.trim())throw new g("Origin key is required for originKey authentication");if(!e.origin?.trim())throw new g("Origin is required for originKey authentication");if(b(e.platform))throw new g("Origin key authentication is not allowed in frontend platforms")}if("jwt"===e.auth.type&&"browser"!==e.platform&&!e.tokenStorage)throw new g("tokenStorage must be provided when using JWT authentication outside browser platform")}isPublicRoute(e){let t=e.split("?")[0];return this.publicRoutes.some(e=>{let r=e.replace(/\*/g,"[^/]+");return RegExp(`^${r}$`).test(t)})}buildAuthHeaders(e){if(this.isPublicRoute(e))return{};if("apiKey"===this._config.auth.type)return this._config.accessToken?{Authorization:`Bearer ${this._config.accessToken}`}:{};if("originKey"===this._config.auth.type)return this._config.accessToken?{Authorization:`Bearer ${this._config.accessToken}`}:{Authorization:this._config.auth.originKey};if("jwt"===this._config.auth.type){if("browser"===this._config.platform)return{};let e=this._config.tokenStorage?.get();if(!e)throw new g("Authentication token is missing");return{Authorization:`Bearer ${e}`}}return{}}isRetryableError(e){return e instanceof o||e instanceof f||e instanceof y||e instanceof Error&&"status"in e&&503===e.status}calculateRetryDelay(e,t){let{initialDelay:r=1e3,maxDelay:i=3e4}=this._config.retry??{};if(t){let e=Number.parseInt(t,10);if(!Number.isNaN(e))return Math.min(1e3*e,i);let r=new Date(t);if(!Number.isNaN(r.getTime()))return Math.min(Math.max(r.getTime()-Date.now(),0),i)}let s=r*2**e,n=.25*s*(2*Math.random()-1);return Math.min(s+n,i)}sleep(e){return new Promise(t=>setTimeout(t,e))}generateIdempotencyKey(){return void 0!==globalThis.crypto&&"function"==typeof globalThis.crypto.randomUUID?globalThis.crypto.randomUUID():`idem_${Date.now()}_${Math.random().toString(36).slice(2)}`}isIdempotencyKeyError(e,t){if(409!==e&&400!==e)return!1;let r=`${t.code??""} ${t.message??""}`.toLowerCase().trim();return r.includes("idempotency-key")||r.includes("idempotency key")||r.includes("duplicated idempotency key")}async ensureExchanged(){"apiKey"!==this._config.auth.type||(this._exchangePromise?await this._exchangePromise:this._config.accessToken&&Date.now()<this._exchangeExpiry-6e4||(this._exchangePromise=(async()=>{try{let e=this._config.auth,t=await this.request({method:"POST",path:"/api/api-keys/exchange",body:{key:e.apiKey,scopes:e.scopes},_skipExchange:!0});if(!t.access_token)throw new u("API key exchange returned an invalid response (missing access_token)",{status:401});this._config.accessToken=t.access_token,this._exchangeExpiry=Date.now()+1e3*t.expires_in}finally{this._exchangePromise=null}})(),await this._exchangePromise))}async request(e){let t;"apiKey"!==this._config.auth.type||e._skipExchange||await this.ensureExchanged();let{method:i,path:s,body:n,headers:o={},timeout:a,authorizationOverride:u}=e,c=`${this.baseUrl}${s}`,h={...r,...u?{Authorization:u}:this.buildAuthHeaders(s),...o};q.has(i.toUpperCase())&&(h[E]=h[E]||this.generateIdempotencyKey());let l=void 0!==a?a:this._config.timeout??3e4,{enabled:d=!0,maxRetries:p=3}=this._config.retry??{},m=0;for(;m<=(d?p:0);){let e,r=new AbortController;l>0&&(e=setTimeout(()=>{r.abort()},l));try{let s=await fetch(c,{method:i,headers:h,body:n?JSON.stringify(n):void 0,credentials:"jwt"===this._config.auth.type&&"browser"===this._config.platform?"include":void 0,signal:r.signal});void 0!==e&&clearTimeout(e);let o=await s.json().catch(()=>({}));if(!s.ok){let e=s.headers.get("X-Request-ID")??s.headers.get("Request-ID")??void 0,r=s.headers.get("Retry-After"),i=_(o.message||(429===s.status?"Rate limit exceeded":`HTTP ${s.status}: ${s.statusText}`),{status:s.status,code:o.code,requestId:e,response:o,retryAfter:r?Number.parseInt(r,10):void 0,httpClient:this});if(this.isIdempotencyKeyError(s.status,o))throw i;if(d&&m<p&&this.isRetryableError(i)){t=i;let e=this.calculateRetryDelay(m,r??void 0);await this.sleep(e),m++;continue}throw i}return o}catch(i){let r;if(void 0!==e&&clearTimeout(e),i&&"object"==typeof i&&"name"in i&&"string"==typeof i.name&&i.name.startsWith("Bloque")&&!this.isRetryableError(i))throw i;if(r=i instanceof Error&&"AbortError"===i.name?new y(`Request timeout after ${l}ms`,{timeoutMs:l,cause:i}):i instanceof Error?new f(`Request failed: ${i.message}`,{cause:i}):_("Unknown error occurred",{code:"UNKNOWN_ERROR"}),d&&m<p&&this.isRetryableError(r)){t=r;let e=this.calculateRetryDelay(m);await this.sleep(e),m++;continue}throw r}}throw t||_("Request failed after retries",{code:"MAX_RETRIES_EXCEEDED"})}}export{t as API_BASE_URLS,e as BaseClient,n as BloqueAPIError,u as BloqueAuthenticationError,g as BloqueConfigError,m as BloqueInsufficientFundsError,f as BloqueNetworkError,p as BloqueNotFoundError,o as BloqueRateLimitError,a as BloqueTierLimitExceededError,y as BloqueTimeoutError,d as BloqueValidationError,l as BloqueVerificationPendingError,h as BloqueVerificationRequiredError,r as DEFAULT_HEADERS,v as HttpClient,i as SUPPORTED_ASSETS,_ as createBloqueError,s as isSupportedAsset};
|
package/dist/types.d.ts
CHANGED
|
@@ -401,6 +401,19 @@ export interface RequestOptions<U = unknown> {
|
|
|
401
401
|
timeout?: number;
|
|
402
402
|
/** @internal Bypass the auto-exchange guard to prevent recursion. */
|
|
403
403
|
_skipExchange?: boolean;
|
|
404
|
+
/**
|
|
405
|
+
* Overrides the SDK's configured auth strategy for this single request,
|
|
406
|
+
* sending this value verbatim as the `Authorization` header instead of
|
|
407
|
+
* whatever `apiKey`/`originKey`/`jwt` would normally produce.
|
|
408
|
+
*
|
|
409
|
+
* Used for capability-token-authenticated hosted-gate endpoints (the TOS
|
|
410
|
+
* gate and verification gate's `/init`, `/accept`, `/submit`), which
|
|
411
|
+
* authenticate solely via a short-lived bearer token minted by their own
|
|
412
|
+
* `/start` endpoint — never the SDK's own session.
|
|
413
|
+
*
|
|
414
|
+
* @example `Bearer ${startResult.token}`
|
|
415
|
+
*/
|
|
416
|
+
authorizationOverride?: string;
|
|
404
417
|
}
|
|
405
418
|
export interface BloqueResponse<T> {
|
|
406
419
|
data?: T;
|