@bloque/sdk 0.0.22 → 0.0.24

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -15,7 +15,7 @@ The official TypeScript/JavaScript SDK for integrating [Bloque](https://www.bloq
15
15
  > }
16
16
  > ```
17
17
  >
18
- > Replace `x.x.x` with the latest version from [npm](https://www.npmjs.com/package/@bloque/sdk).
18
+ > Replace with the latest version from [npm](https://www.npmjs.com/package/@bloque/sdk).
19
19
 
20
20
  ## Platform Support
21
21
 
@@ -25,23 +25,40 @@ This SDK is compatible with multiple JavaScript runtimes:
25
25
  - **Bun** 1.x or higher
26
26
  - **Deno** Latest version
27
27
  - **Web/Browsers** Modern browsers with ES2020+ support
28
+ - **React Native** Latest version
28
29
 
29
30
  ## Features
30
31
 
31
32
  - **TypeScript First**: Built with TypeScript for complete type safety
32
- - **Simple API**: Intuitive interface for managing organizations, compliance, accounts, and identity
33
- - **Identity Registration**: Register individual users (KYC) and businesses (KYB) with multi-method authentication
34
- - **User Sessions**: Secure user session management with `connect()` for authenticated operations
35
- - **Fully Async**: Promise-based API for modern JavaScript workflows
33
+ - **Modular Architecture**: Import only what you need - accounts, identity, compliance, or organizations
34
+ - **Multi-Runtime**: Works seamlessly across Node.js, Bun, Deno, browsers, and React Native
35
+ - **Account Management**: Create and manage virtual cards, virtual accounts, and Bancolombia accounts
36
+ - **Identity System**: Register individual users (KYC) and businesses (KYB) with multi-method authentication
37
+ - **Compliance Ready**: Built-in KYC/KYB verification workflows
38
+ - **Transfer System**: Transfer funds between accounts with multiple asset support
39
+ - **Production Ready**:
40
+ - ✅ Automatic retry with exponential backoff
41
+ - ✅ Configurable timeouts (default: 30s)
42
+ - ✅ Specific error types for better error handling
43
+ - ✅ Request ID tracking for debugging
44
+ - ✅ Security warnings for insecure practices
36
45
  - **Lightweight**: Minimal dependencies for optimal bundle size
37
- - **Modular**: Import only what you need with tree-shakeable exports
38
-
39
- > **📌 Important:** Most operations require connecting to a user session first using `bloque.connect(urn)`. This ensures proper authentication and authorization. See the [User Sessions](#user-sessions-with-connect) section for details.
46
+ - **Fully Async**: Promise-based API for modern JavaScript workflows
40
47
 
41
48
  ## Installation
42
49
 
43
50
  ```bash
51
+ # npm
52
+ npm install @bloque/sdk
53
+
54
+ # bun
44
55
  bun add @bloque/sdk
56
+
57
+ # pnpm
58
+ pnpm add @bloque/sdk
59
+
60
+ # yarn
61
+ yarn add @bloque/sdk
45
62
  ```
46
63
 
47
64
  ## Quick Start
@@ -50,58 +67,34 @@ bun add @bloque/sdk
50
67
 
51
68
  ```typescript
52
69
  import { SDK } from '@bloque/sdk';
53
- import type { CreateOrgParams } from '@bloque/sdk/orgs';
54
70
 
55
71
  // Initialize the SDK with API key (backend only)
56
72
  const bloque = new SDK({
57
- origin: 'your-origin-name', // Required: your origin identifier
73
+ origin: 'your-origin-name',
58
74
  auth: {
59
75
  type: 'apiKey',
60
76
  apiKey: process.env.BLOQUE_API_KEY!,
61
77
  },
62
78
  mode: 'production', // or 'sandbox' for testing
63
79
  platform: 'node', // optional: 'node' | 'bun' | 'deno'
80
+ timeout: 30000, // optional: request timeout in ms
81
+ retry: { // optional: retry configuration
82
+ enabled: true,
83
+ maxRetries: 3,
84
+ initialDelay: 1000,
85
+ },
64
86
  });
65
87
 
66
- // Connect to user session for account operations
67
- async function createCard() {
68
- // First, connect to the user's session
69
- const userSession = await bloque.connect('did:bloque:your-origin:user-alias');
70
-
71
- // Now create a virtual card through the session
72
- const card = await userSession.accounts.card.create({
73
- urn: 'did:bloque:your-origin:user-alias',
74
- name: 'My Virtual Card',
75
- });
76
-
77
- console.log('Card created:', card.urn);
78
- console.log('Last four digits:', card.lastFour);
79
- }
88
+ // Connect to user session
89
+ const session = await bloque.connect('did:bloque:your-origin:user-alias');
80
90
 
81
- // Create an organization (direct SDK access, no connect needed)
82
- async function createOrganization() {
83
- const params: CreateOrgParams = {
84
- org_type: 'business',
85
- profile: {
86
- legal_name: 'Acme Corporation',
87
- tax_id: '123456789',
88
- incorporation_date: '2020-01-01',
89
- business_type: 'llc',
90
- incorporation_country_code: 'US',
91
- incorporation_state: 'CA',
92
- address_line1: '123 Main St',
93
- postal_code: '12345',
94
- city: 'San Francisco',
95
- },
96
- metadata: {
97
- source: 'api',
98
- },
99
- };
91
+ // Create a virtual card
92
+ const card = await session.accounts.card.create({
93
+ name: 'My Virtual Card',
94
+ });
100
95
 
101
- const userSession = await bloque.connect('did:bloque:your-origin:user-alias');
102
- const organization = await userSession.orgs.create(params);
103
- console.log('Organization created:', organization);
104
- }
96
+ console.log('Card created:', card.urn);
97
+ console.log('Last four digits:', card.lastFour);
105
98
  ```
106
99
 
107
100
  ### Frontend (Browser, React Native)
@@ -111,1174 +104,579 @@ import { SDK } from '@bloque/sdk';
111
104
 
112
105
  // Initialize the SDK with JWT authentication
113
106
  const bloque = new SDK({
107
+ origin: 'your-origin-name',
114
108
  auth: { type: 'jwt' },
115
109
  mode: 'production',
116
110
  platform: 'browser', // or 'react-native'
117
- // tokenStorage is optional for browser (uses localStorage by default)
118
- // for react-native, provide a custom storage implementation
119
- });
120
-
121
- // After user registration, the SDK automatically stores the JWT
122
- const result = await bloque.identity.origins.register('ethereum-mainnet', {
123
- assertionResult: { /* ... */ },
124
- type: 'individual',
125
- profile: { /* ... */ }
126
- });
127
-
128
- // The token is now stored and used for subsequent requests
129
- const alias = await bloque.identity.aliases.get('user@example.com');
130
- ```
131
-
132
- ## Configuration
133
-
134
- ### Initialize the SDK
135
-
136
- The SDK supports different authentication methods depending on where it's running:
137
-
138
- #### Backend Configuration (API Key)
139
-
140
- For server-side applications (Node.js, Bun, Deno):
141
-
142
- ```typescript
143
- import { SDK } from '@bloque/sdk';
144
-
145
- const bloque = new SDK({
146
- auth: {
147
- type: 'apiKey',
148
- apiKey: process.env.BLOQUE_API_KEY!, // Your Bloque API key
149
- },
150
- mode: 'production', // 'sandbox' or 'production'
151
- platform: 'node', // optional: 'node' | 'bun' | 'deno' (defaults to 'node')
152
- });
153
- ```
154
-
155
- #### Frontend Configuration (JWT)
156
-
157
- For client-side applications (Browser, React Native):
158
-
159
- ```typescript
160
- import { SDK } from '@bloque/sdk';
161
-
162
- // Browser
163
- const bloque = new SDK({
164
- auth: { type: 'jwt' },
165
- mode: 'production',
166
- platform: 'browser',
167
- // tokenStorage is optional - uses localStorage by default
168
- });
169
-
170
- // React Native (with custom storage)
171
- import AsyncStorage from '@react-native-async-storage/async-storage';
172
-
173
- const bloque = new SDK({
174
- auth: { type: 'jwt' },
175
- mode: 'production',
176
- platform: 'react-native',
111
+ // For browser: uses localStorage by default (with security warning)
112
+ // For react-native: provide custom tokenStorage
177
113
  tokenStorage: {
178
- get: async () => await AsyncStorage.getItem('access_token'),
179
- set: async (token: string) => await AsyncStorage.setItem('access_token', token),
180
- clear: async () => await AsyncStorage.removeItem('access_token'),
181
- },
182
- });
183
- ```
184
-
185
- ### Configuration Options
186
-
187
- - **`origin`** (string, required): Your origin identifier/namespace
188
- - This identifies your application or organization in the Bloque platform
189
- - Example: `'my-app'`, `'bloque-root'`, `'ethereum-mainnet'`
190
-
191
- - **`auth`** (object, required): Authentication configuration
192
- - `type: 'apiKey'`: For backend platforms
193
- - `apiKey` (string, required): Your Bloque API key
194
- - `type: 'jwt'`: For frontend platforms
195
- - Requires storing and managing JWT tokens via `tokenStorage`
196
-
197
- - **`mode`** ('sandbox' | 'production', optional): Environment mode
198
- - `sandbox`: For testing and development
199
- - `production`: For live operations (default)
200
-
201
- - **`platform`** (string, optional): Execution platform
202
- - Backend: `'node'` (default) | `'bun'` | `'deno'`
203
- - Frontend: `'browser'` | `'react-native'`
204
- - Determines available authentication methods
205
-
206
- - **`tokenStorage`** (object, optional): JWT token storage mechanism
207
- - Required for JWT authentication on non-browser platforms
208
- - Browser automatically uses `localStorage` if not provided
209
- - Must implement: `get()`, `set(token)`, `clear()`
210
-
211
- ### User Sessions with `connect()`
212
-
213
- Most operations in the SDK require connecting to a user session first. This ensures proper authentication and authorization for user-specific operations.
214
-
215
- ```typescript
216
- // Initialize SDK
217
- const bloque = new SDK({
218
- origin: 'your-origin',
219
- auth: {
220
- type: 'apiKey',
221
- apiKey: process.env.BLOQUE_API_KEY!,
114
+ get: () => {
115
+ // Your secure storage implementation
116
+ return AsyncStorage.getItem('bloque_token');
117
+ },
118
+ set: (token) => {
119
+ AsyncStorage.setItem('bloque_token', token);
120
+ },
121
+ clear: () => {
122
+ AsyncStorage.removeItem('bloque_token');
123
+ },
222
124
  },
223
- mode: 'production',
224
125
  });
225
126
 
226
- // Connect to user session
227
- const userSession = await bloque.connect('did:bloque:your-origin:user-alias');
127
+ // Register a new user
128
+ const result = await bloque.identity.origins.register(
129
+ 'did:bloque:your-origin:ethereum-mainnet',
130
+ {
131
+ assertionResult: { /* signing challenge result */ },
132
+ type: 'individual',
133
+ profile: {
134
+ firstName: 'John',
135
+ lastName: 'Doe',
136
+ email: 'john@example.com',
137
+ },
138
+ }
139
+ );
228
140
 
229
- // Now perform operations through the session
230
- const card = await userSession.accounts.card.create({
231
- urn: 'did:bloque:your-origin:user-alias',
232
- name: 'My Card',
233
- });
141
+ // The JWT is automatically stored and used for subsequent requests
234
142
  ```
235
143
 
236
- **What `connect()` does:**
237
- - Authenticates the user with the specified URN
238
- - Obtains an access token for the user session
239
- - Returns a session object with access to: `accounts`, `compliance`, `identity`, `orgs`
240
-
241
- **URN Format:**
242
- - Pattern: `did:bloque:{origin}:{user-alias}`
243
- - Example: `did:bloque:my-app:john-doe`
244
- - The `{origin}` must match the origin specified in SDK configuration
245
- - The `{user-alias}` is the user's unique identifier in your origin
246
-
247
- ### Platform and Authentication Compatibility
248
-
249
- | Platform | API Key Auth | JWT Auth | Token Storage |
250
- |----------|--------------|----------|---------------|
251
- | `node` | ✅ | ✅ | Required for JWT |
252
- | `bun` | ✅ | ✅ | Required for JWT |
253
- | `deno` | ✅ | ✅ | Required for JWT |
254
- | `browser` | ❌ | ✅ | Optional (uses localStorage) |
255
- | `react-native` | ❌ | ✅ | Required |
256
-
257
- ## API Reference
258
-
259
- ### Organizations
260
-
261
- The organizations resource allows you to create and manage organizations in the Bloque platform.
144
+ ## Configuration
262
145
 
263
- #### Create an Organization
146
+ ### Full Configuration Options
264
147
 
265
148
  ```typescript
266
- // Connect to user session first
267
- const userSession = await bloque.connect('did:bloque:your-origin:user-alias');
268
-
269
- // Create organization through the session
270
- const organization = await userSession.orgs.create(params);
271
- ```
272
-
273
- **Parameters**:
149
+ interface BloqueSDKConfig {
150
+ // Required
151
+ origin: string; // Your origin identifier
152
+ auth: AuthStrategy; // Authentication strategy
274
153
 
275
- ```typescript
276
- interface CreateOrgParams {
277
- org_type: 'business' | 'individual'; // Organization type
278
- profile: OrgProfile; // Organization profile details
279
- metadata?: Record<string, unknown>; // Optional custom metadata
154
+ // Optional
155
+ platform?: Platform; // Runtime platform (default: 'node')
156
+ mode?: Mode; // Environment mode (default: 'production')
157
+ timeout?: number; // Request timeout in ms (default: 30000)
158
+ tokenStorage?: TokenStorage; // JWT storage (required for react-native)
159
+ retry?: RetryConfig; // Retry configuration
280
160
  }
281
161
 
282
- interface OrgProfile {
283
- legal_name: string; // Legal name of the organization
284
- tax_id: string; // Tax ID number
285
- incorporation_date: string; // Date of incorporation (YYYY-MM-DD)
286
- business_type: string; // Type of business (e.g., 'llc', 'corporation')
287
- incorporation_country_code: string; // Country code (ISO 3166-1 alpha-2)
288
- incorporation_state?: string; // State/province (optional)
289
- address_line1: string; // Primary address line
290
- address_line2?: string; // Secondary address line (optional)
291
- postal_code: string; // Postal/ZIP code
292
- city: string; // City
293
- logo_url?: string; // Logo URL (optional)
294
- places?: Place[]; // Additional places/locations (optional)
295
- }
162
+ // Authentication strategies
163
+ type AuthStrategy =
164
+ | { type: 'apiKey'; apiKey: string } // Backend only
165
+ | { type: 'jwt' }; // Frontend (browser/react-native)
296
166
 
297
- interface Place {
298
- country_code: string; // Country code
299
- state: string; // State/province
300
- address_line1: string; // Address line 1
301
- postal_code: string; // Postal code
302
- city: string; // City
303
- is_primary: boolean; // Whether this is the primary place
304
- }
305
- ```
167
+ // Platforms
168
+ type Platform = 'node' | 'bun' | 'deno' | 'browser' | 'react-native';
306
169
 
307
- **Response**:
170
+ // Modes
171
+ type Mode = 'production' | 'sandbox';
308
172
 
309
- ```typescript
310
- interface Organization {
311
- urn: string; // Unique resource name
312
- org_type: 'business' | 'individual'; // Organization type
313
- profile: OrgProfile; // Organization profile
314
- metadata?: Record<string, unknown>; // Custom metadata
315
- status: OrgStatus; // Organization status
173
+ // Retry configuration
174
+ interface RetryConfig {
175
+ enabled?: boolean; // default: true
176
+ maxRetries?: number; // default: 3
177
+ initialDelay?: number; // default: 1000ms
178
+ maxDelay?: number; // default: 30000ms
316
179
  }
317
-
318
- type OrgStatus =
319
- | 'awaiting_compliance_verification'
320
- | 'active'
321
- | 'suspended'
322
- | 'closed';
323
180
  ```
324
181
 
325
- ### Compliance
326
-
327
- The compliance resource provides KYC (Know Your Customer) verification functionality.
182
+ ## SDK Structure
328
183
 
329
- #### Start KYC Verification
330
-
331
- Start a KYC verification process for a user:
184
+ After connecting to a user session, you have access to these clients:
332
185
 
333
186
  ```typescript
334
- // Connect to user session
335
- const userSession = await bloque.connect('did:bloque:your-origin:user-alias');
187
+ const session = await bloque.connect('did:bloque:your-origin:user-alias');
336
188
 
337
- // Start KYC verification
338
- const verification = await userSession.compliance.kyc.startVerification({
339
- urn: 'did:bloque:your-origin:user-alias',
340
- });
189
+ // Available clients
190
+ session.accounts // Account management
191
+ session.identity // Identity and aliases
192
+ session.compliance // KYC/KYB verification
193
+ session.orgs // Organization management
341
194
  ```
342
195
 
343
- **Parameters**:
196
+ ## Accounts Client
344
197
 
345
- ```typescript
346
- interface KycVerificationParams {
347
- /**
348
- * URN (Uniform Resource Name) that uniquely identifies the user
349
- * within the system. This value is used to associate the KYC
350
- * verification process with a specific user.
351
- *
352
- * @example "did:bloque:origin:..."
353
- */
354
- urn: string;
355
-
356
- /**
357
- * URL where webhook notifications will be sent when the verification
358
- * status changes (optional).
359
- *
360
- * @example "https://api.example.com/webhooks/kyc"
361
- */
362
- webhookUrl?: string;
363
- }
364
- ```
198
+ The accounts client provides access to multiple account types:
365
199
 
366
- **Response**:
200
+ ### Virtual Cards
367
201
 
368
202
  ```typescript
369
- interface KycVerificationResponse {
370
- url: string; // URL where the user should complete the verification
371
- status: 'awaiting_compliance_verification' | 'approved' | 'rejected';
372
- }
373
- ```
203
+ // Create a virtual card
204
+ const card = await session.accounts.card.create({
205
+ name: 'My Card',
206
+ webhookUrl: 'https://your-app.com/webhooks/card',
207
+ });
374
208
 
375
- #### Get KYC Verification Status
209
+ // List cards
210
+ const cards = await session.accounts.card.list();
376
211
 
377
- Get the current status of a KYC verification:
212
+ // Check balance
213
+ const balance = await session.accounts.card.balance({
214
+ urn: card.urn,
215
+ });
378
216
 
379
- ```typescript
380
- const status = await bloque.compliance.kyc.getVerification({
381
- urn: 'did:bloque:user:123e4567',
217
+ // Get movements/transactions
218
+ const movements = await session.accounts.card.movements({
219
+ urn: card.urn,
220
+ asset: 'DUSD/6',
221
+ limit: 50,
222
+ direction: 'in', // 'in' | 'out'
382
223
  });
383
- ```
384
224
 
385
- **Parameters**:
225
+ // Update card
226
+ const updated = await session.accounts.card.updateMetadata({
227
+ urn: card.urn,
228
+ metadata: { name: 'Updated Name' },
229
+ });
386
230
 
387
- ```typescript
388
- interface GetKycVerificationParams {
389
- /**
390
- * URN (Uniform Resource Name) that uniquely identifies the user
391
- * within the system.
392
- *
393
- * @example "did:bloque:user:123e4567"
394
- */
395
- urn: string;
396
- }
231
+ // Manage card state
232
+ await session.accounts.card.activate(card.urn);
233
+ await session.accounts.card.freeze(card.urn);
234
+ await session.accounts.card.disable(card.urn);
397
235
  ```
398
236
 
399
- **Response**:
237
+ ### Virtual Accounts
238
+
239
+ Virtual accounts are simple testing accounts requiring only basic personal information:
400
240
 
401
241
  ```typescript
402
- interface KycVerificationStatus {
403
- status: 'awaiting_compliance_verification' | 'approved' | 'rejected';
404
- url: string; // URL for verification
405
- completedAt: string | null; // Completion date (ISO 8601)
406
- }
407
- ```
242
+ // Create a virtual account
243
+ const account = await session.accounts.virtual.create({
244
+ firstName: 'John',
245
+ lastName: 'Doe',
246
+ metadata: {
247
+ environment: 'testing',
248
+ purpose: 'integration-test',
249
+ },
250
+ });
408
251
 
409
- ### Accounts
252
+ // Update metadata
253
+ await session.accounts.virtual.updateMetadata({
254
+ urn: account.urn,
255
+ metadata: { updated_by: 'admin' },
256
+ });
410
257
 
411
- The accounts resource allows you to create virtual cards for users.
258
+ // Manage account state
259
+ await session.accounts.virtual.activate(account.urn);
260
+ await session.accounts.virtual.freeze(account.urn);
261
+ await session.accounts.virtual.disable(account.urn);
262
+ ```
412
263
 
413
- #### Create a Virtual Card
264
+ ### Bancolombia Accounts
414
265
 
415
- Create a virtual card for a user:
266
+ Colombian virtual accounts with unique reference code system:
416
267
 
417
268
  ```typescript
418
- // Connect to user session
419
- const userSession = await bloque.connect('did:bloque:your-origin:user-alias');
420
-
421
- // Create virtual card
422
- const card = await userSession.accounts.card.create({
423
- urn: 'did:bloque:your-origin:user-alias',
424
- name: 'My Virtual Card', // Optional
269
+ // Create a Bancolombia account
270
+ const account = await session.accounts.bancolombia.create({
271
+ name: 'Main Account',
272
+ webhookUrl: 'https://your-app.com/webhooks/bancolombia',
425
273
  });
426
- ```
427
274
 
428
- **Parameters**:
275
+ console.log('Reference code:', account.referenceCode);
429
276
 
430
- ```typescript
431
- interface CreateCardParams {
432
- /**
433
- * URN of the account holder (user or organization)
434
- * @example "did:bloque:user:123e4567"
435
- */
436
- urn: string;
437
-
438
- /**
439
- * Display name for the card (optional)
440
- */
441
- name?: string;
442
- }
443
- ```
277
+ // Update metadata or name
278
+ await session.accounts.bancolombia.updateMetadata({
279
+ urn: account.urn,
280
+ metadata: { category: 'savings' },
281
+ });
444
282
 
445
- **Response**:
283
+ await session.accounts.bancolombia.updateName(account.urn, 'Savings Account');
446
284
 
447
- ```typescript
448
- interface CardAccount {
449
- urn: string; // Unique resource name
450
- id: string; // Card account ID
451
- lastFour: string; // Last four digits
452
- productType: 'CREDIT' | 'DEBIT'; // Card product type
453
- status: 'active' | 'disabled' | 'frozen' | 'deleted' | 'creation_in_progress' | 'creation_failed';
454
- cardType: 'VIRTUAL' | 'PHYSICAL'; // Card type
455
- detailsUrl: string; // PCI-compliant URL to view card details
456
- ownerUrn: string; // Owner URN
457
- webhookUrl: string | null; // Webhook URL (if configured)
458
- metadata?: Record<string, unknown>; // Custom metadata
459
- createdAt: string; // Creation timestamp (ISO 8601)
460
- updatedAt: string; // Last update timestamp (ISO 8601)
461
- }
285
+ // Manage account state
286
+ await session.accounts.bancolombia.activate(account.urn);
287
+ await session.accounts.bancolombia.freeze(account.urn);
288
+ await session.accounts.bancolombia.disable(account.urn);
462
289
  ```
463
290
 
464
- ### Identity
465
-
466
- The identity resource allows you to register identities, retrieve user aliases, and manage authentication origins.
291
+ ### Transfers
467
292
 
468
- #### Register Identity
469
-
470
- Register a new user or business identity to an authentication origin. Supports individual users (KYC) and businesses (KYB):
293
+ Transfer funds between any account types:
471
294
 
472
295
  ```typescript
473
- // Register individual user
474
- const individual = await bloque.identity.origins.register('ethereum-mainnet', {
475
- assertionResult: {
476
- alias: '0x742d35Cc6634C0532925a3b8D4C9db96C4b4d8b6',
477
- challengeType: 'SIGNING_CHALLENGE',
478
- value: {
479
- signature: '0x1234567890abcdef...',
480
- alias: '0x742d35Cc6634C0532925a3b8D4C9db96C4b4d8b6'
481
- }
296
+ const result = await session.accounts.transfer({
297
+ sourceUrn: 'did:bloque:account:card:usr-123:crd-456',
298
+ destinationUrn: 'did:bloque:account:virtual:acc-789',
299
+ amount: '1000000', // Amount in smallest unit
300
+ asset: 'DUSD/6', // 'DUSD/6' | 'KSM/12'
301
+ metadata: {
302
+ description: 'Payment for services',
482
303
  },
483
- type: 'individual',
484
- profile: {
485
- firstName: 'John',
486
- lastName: 'Doe',
487
- email: 'john@example.com'
488
- }
489
304
  });
490
305
 
491
- // Register business
492
- const business = await bloque.identity.origins.register('bloque-api', {
493
- assertionResult: {
494
- alias: 'business-123',
495
- challengeType: 'API_KEY',
496
- value: {
497
- apiKey: 'sk_live_abc123',
498
- alias: 'business-123'
499
- }
500
- },
501
- type: 'business',
502
- profile: {
503
- legalName: 'Acme Corporation',
504
- name: 'Acme Corp',
505
- taxId: '12-3456789',
506
- type: 'LLC',
507
- incorporationDate: '2020-01-15',
508
- addressLine1: '123 Business St',
509
- city: 'New York',
510
- state: 'NY',
511
- postalCode: '10001',
512
- country: 'United States'
513
- }
514
- });
306
+ console.log('Transfer queued:', result.queueId);
307
+ console.log('Status:', result.status); // 'queued' | 'processing' | 'completed' | 'failed'
515
308
  ```
516
309
 
517
- **Parameters**:
518
-
519
- ```typescript
520
- // Registration parameters (discriminated union by type)
521
- type RegisterParams = IndividualRegisterParams | BusinessRegisterParams;
522
-
523
- interface IndividualRegisterParams {
524
- assertionResult: AssertionResult;
525
- extraContext?: Record<string, unknown>;
526
- type: 'individual';
527
- profile: UserProfile;
528
- }
310
+ ## Identity Client
529
311
 
530
- interface BusinessRegisterParams {
531
- assertionResult: AssertionResult;
532
- extraContext?: Record<string, unknown>;
533
- type: 'business';
534
- profile: BusinessProfile;
535
- }
312
+ Manage user identities and authentication:
536
313
 
537
- // Assertion result for challenge verification
538
- interface AssertionResult {
539
- alias: string; // Identity identifier
540
- challengeType: 'SIGNING_CHALLENGE' | 'API_KEY' | 'OAUTH_REDIRECT' | 'WEBAUTHN' | 'OTP' | 'PASSWORD';
541
- value: {
542
- signature?: string; // For SIGNING_CHALLENGE
543
- apiKey?: string; // For API_KEY
544
- alias: string;
545
- };
546
- originalChallengeParams?: {
547
- challenge: string;
548
- timestamp: number;
549
- };
550
- }
314
+ ```typescript
315
+ // Get alias information
316
+ const alias = await session.identity.aliases.get('user@example.com');
551
317
 
552
- // Individual user profile (KYC)
553
- interface UserProfile {
554
- firstName?: string;
555
- lastName?: string;
556
- birthdate?: string; // ISO 8601 (YYYY-MM-DD)
557
- email?: string;
558
- phone?: string;
559
- gender?: string;
560
- addressLine1?: string;
561
- addressLine2?: string;
562
- city?: string;
563
- state?: string;
564
- postalCode?: string;
565
- neighborhood?: string;
566
- countryOfBirthCode?: string;
567
- countryOfResidenceCode?: string;
568
- personalIdType?: string;
569
- personalIdNumber?: string;
570
- }
318
+ // List available origins
319
+ const origins = await session.identity.origins.list();
571
320
 
572
- // Business profile (KYB)
573
- interface BusinessProfile {
574
- // Required fields
575
- addressLine1: string;
576
- city: string;
577
- country: string;
578
- incorporationDate: string;
579
- legalName: string;
580
- name: string;
581
- postalCode: string;
582
- state: string;
583
- taxId: string;
584
- type: string;
585
-
586
- // Optional fields
587
- addressLine2?: string;
588
- countryCode?: string;
589
- email?: string;
590
- logo?: string;
591
- phone?: string;
592
-
593
- // Beneficial owner information
594
- ownerName?: string;
595
- ownerIdType?: string;
596
- ownerIdNumber?: string;
597
- ownerAddressLine1?: string;
598
- ownerCity?: string;
599
- ownerState?: string;
600
- ownerPostalCode?: string;
601
- ownerCountryCode?: string;
602
- }
603
- ```
604
-
605
- **Response**:
321
+ // Register a new identity (individual)
322
+ const result = await bloque.identity.origins.register(
323
+ 'did:bloque:your-origin:ethereum-mainnet',
324
+ {
325
+ assertionResult: {
326
+ alias: '0x742d35Cc...',
327
+ challengeType: 'SIGNING_CHALLENGE',
328
+ value: {
329
+ signature: '0x...',
330
+ alias: '0x742d35Cc...',
331
+ },
332
+ },
333
+ type: 'individual',
334
+ profile: {
335
+ firstName: 'John',
336
+ lastName: 'Doe',
337
+ email: 'john@example.com',
338
+ birthdate: '1990-01-15',
339
+ countryOfResidenceCode: 'US',
340
+ },
341
+ }
342
+ );
343
+
344
+ // Register a business
345
+ const businessResult = await bloque.identity.origins.register(
346
+ 'did:bloque:your-origin:ethereum-mainnet',
347
+ {
348
+ assertionResult: { /* ... */ },
349
+ type: 'business',
350
+ profile: {
351
+ legalName: 'Acme Corporation',
352
+ taxId: '123456789',
353
+ incorporationDate: '2020-01-01',
354
+ type: 'llc',
355
+ addressLine1: '123 Main St',
356
+ city: 'San Francisco',
357
+ state: 'CA',
358
+ country: 'US',
359
+ postalCode: '12345',
360
+ // ... other required fields
361
+ },
362
+ }
363
+ );
606
364
 
607
- ```typescript
608
- interface RegisterResult {
609
- accessToken: string; // JWT access token for authenticated sessions
610
- }
365
+ // OTP-based authentication
366
+ const otpEmail = await bloque.identity.origins.email.assert('user@example.com');
367
+ const otpWhatsApp = await bloque.identity.origins.whatsapp.assert('+1234567890');
368
+ const otpCustom = await bloque.identity.origins.custom('my-origin').assert('user-id');
611
369
  ```
612
370
 
613
- #### Get Alias
371
+ ## Compliance Client
614
372
 
615
- Retrieve alias information by the alias value:
373
+ KYC/KYB verification workflows:
616
374
 
617
375
  ```typescript
618
- const alias = await bloque.identity.aliases.get('user@example.com');
619
- ```
620
-
621
- **Parameters**:
376
+ // Start KYC verification
377
+ const verification = await session.compliance.kyc.startVerification({
378
+ urn: 'did:bloque:user:123e4567',
379
+ webhookUrl: 'https://your-app.com/webhooks/kyc',
380
+ });
622
381
 
623
- ```typescript
624
- // Pass the alias string directly
625
- const alias: string = 'user@example.com' | '+1234567890';
626
- ```
382
+ console.log('Verification URL:', verification.url);
383
+ console.log('Status:', verification.status);
627
384
 
628
- **Response**:
385
+ // Get verification status
386
+ const status = await session.compliance.kyc.getVerification({
387
+ urn: 'did:bloque:user:123e4567',
388
+ });
629
389
 
630
- ```typescript
631
- interface Alias {
632
- id: string; // Unique alias ID
633
- alias: string; // Alias value
634
- type: 'phone' | 'email' | string; // Alias type
635
- urn: string; // Associated user URN
636
- origin: string; // Origin identifier
637
- details: {
638
- phone?: string; // Phone details (if applicable)
639
- };
640
- metadata: {
641
- alias: string; // Alias in metadata
642
- [key: string]: unknown; // Additional metadata
643
- };
644
- status: 'active' | 'inactive' | 'revoked'; // Alias status
645
- is_public: boolean; // Whether alias is public
646
- is_primary: boolean; // Whether this is the primary alias
647
- created_at: string; // Creation timestamp (ISO 8601)
648
- updated_at: string; // Last update timestamp (ISO 8601)
649
- }
390
+ console.log('Status:', status.status);
391
+ console.log('Completed at:', status.completedAt);
650
392
  ```
651
393
 
652
- ## Examples
394
+ ## Organizations Client
653
395
 
654
- ### Creating a Business Organization
396
+ Create and manage organizations:
655
397
 
656
398
  ```typescript
657
- import { SDK } from '@bloque/sdk';
658
- import type { CreateOrgParams } from '@bloque/sdk/orgs';
659
-
660
- // Initialize SDK with your API key
661
- const bloque = new SDK({
662
- auth: {
663
- type: 'apiKey',
664
- apiKey: process.env.BLOQUE_API_KEY!,
665
- },
666
- mode: 'production',
667
- });
668
-
669
- // Create a business organization
670
- const params: CreateOrgParams = {
399
+ const org = await session.orgs.create({
671
400
  org_type: 'business',
672
401
  profile: {
673
402
  legal_name: 'Acme Corporation',
674
- tax_id: '12-3456789',
675
- incorporation_date: '2020-01-15',
403
+ tax_id: '123456789',
404
+ incorporation_date: '2020-01-01',
676
405
  business_type: 'llc',
677
406
  incorporation_country_code: 'US',
678
407
  incorporation_state: 'CA',
679
- address_line1: '123 Market Street',
680
- address_line2: 'Suite 400',
681
- postal_code: '94103',
408
+ address_line1: '123 Main St',
409
+ address_line2: 'Suite 100',
410
+ postal_code: '12345',
682
411
  city: 'San Francisco',
683
- logo_url: 'https://example.com/logo.png',
684
412
  },
685
413
  metadata: {
686
- source: 'web_app',
687
- campaign: 'q1_2024',
688
- },
689
- };
690
-
691
- try {
692
- const organization = await bloque.orgs.create(params);
693
- console.log('Organization created:', organization.urn);
694
- console.log('Status:', organization.status);
695
- } catch (error) {
696
- console.error('Failed to create organization:', error);
697
- }
698
- ```
699
-
700
- ### Creating an Individual Organization
701
-
702
- ```typescript
703
- import { SDK } from '@bloque/sdk';
704
- import type { CreateOrgParams } from '@bloque/sdk/orgs';
705
-
706
- const bloque = new SDK({
707
- auth: {
708
- type: 'apiKey',
709
- apiKey: process.env.BLOQUE_API_KEY!,
414
+ industry: 'technology',
710
415
  },
711
- mode: 'sandbox',
712
416
  });
713
417
 
714
- const params: CreateOrgParams = {
715
- org_type: 'individual',
716
- profile: {
717
- legal_name: 'John Doe',
718
- tax_id: '123-45-6789',
719
- incorporation_date: '1990-05-20',
720
- business_type: 'sole_proprietorship',
721
- incorporation_country_code: 'US',
722
- address_line1: '456 Oak Avenue',
723
- postal_code: '10001',
724
- city: 'New York',
725
- },
726
- };
727
-
728
- const organization = await bloque.orgs.create(params);
729
- console.log('Individual organization created:', organization);
418
+ console.log('Organization created:', org.urn);
419
+ console.log('Status:', org.status);
730
420
  ```
731
421
 
732
- ### Organization with Multiple Locations
733
-
734
- ```typescript
735
- import { SDK } from '@bloque/sdk';
736
- import type { CreateOrgParams } from '@bloque/sdk/orgs';
737
-
738
- const bloque = new SDK({
739
- auth: {
740
- type: 'apiKey',
741
- apiKey: process.env.BLOQUE_API_KEY!,
742
- },
743
- mode: 'production',
744
- });
745
-
746
- const params: CreateOrgParams = {
747
- org_type: 'business',
748
- profile: {
749
- legal_name: 'Global Tech Solutions Inc.',
750
- tax_id: '98-7654321',
751
- incorporation_date: '2018-03-10',
752
- business_type: 'corporation',
753
- incorporation_country_code: 'US',
754
- incorporation_state: 'DE',
755
- address_line1: '789 Corporate Blvd',
756
- postal_code: '19801',
757
- city: 'Wilmington',
758
- places: [
759
- {
760
- country_code: 'US',
761
- state: 'CA',
762
- address_line1: '100 Silicon Valley Drive',
763
- postal_code: '94025',
764
- city: 'Menlo Park',
765
- is_primary: true,
766
- },
767
- {
768
- country_code: 'US',
769
- state: 'NY',
770
- address_line1: '250 Broadway',
771
- postal_code: '10007',
772
- city: 'New York',
773
- is_primary: false,
774
- },
775
- ],
776
- },
777
- };
778
-
779
- const organization = await bloque.orgs.create(params);
780
- console.log('Multi-location organization created');
781
- ```
422
+ ## Error Handling
782
423
 
783
- ### Starting KYC Verification
424
+ The SDK provides specific error types for better error handling:
784
425
 
785
426
  ```typescript
786
- import { SDK } from '@bloque/sdk';
787
- import type { KycVerificationParams } from '@bloque/sdk/compliance';
788
-
789
- const bloque = new SDK({
790
- auth: {
791
- type: 'apiKey',
792
- apiKey: process.env.BLOQUE_API_KEY!,
793
- },
794
- mode: 'production',
795
- });
796
-
797
- // Start KYC verification for a user
798
- const params: KycVerificationParams = {
799
- urn: 'did:bloque:origin:user-123',
800
- webhookUrl: 'https://api.example.com/webhooks/kyc', // Optional webhook URL
801
- };
427
+ import {
428
+ BloqueRateLimitError,
429
+ BloqueAuthenticationError,
430
+ BloqueValidationError,
431
+ BloqueNotFoundError,
432
+ BloqueInsufficientFundsError,
433
+ BloqueNetworkError,
434
+ BloqueTimeoutError,
435
+ } from '@bloque/sdk';
802
436
 
803
437
  try {
804
- const verification = await bloque.compliance.kyc.startVerification(params);
805
-
806
- console.log('Verification URL:', verification.url);
807
- console.log('Status:', verification.status);
808
-
809
- // Redirect the user to verification.url to complete KYC
810
- // Webhook notifications will be sent to the provided webhookUrl
438
+ const card = await session.accounts.card.create({ name: 'My Card' });
811
439
  } catch (error) {
812
- console.error('Failed to start KYC verification:', error);
813
- }
814
- ```
815
-
816
- ### Getting KYC Verification Status
817
-
818
- ```typescript
819
- import { SDK } from '@bloque/sdk';
820
- import type { GetKycVerificationParams } from '@bloque/sdk/compliance';
821
-
822
- const bloque = new SDK({
823
- auth: {
824
- type: 'apiKey',
825
- apiKey: process.env.BLOQUE_API_KEY!,
826
- },
827
- mode: 'production',
828
- });
829
-
830
- // Get verification status
831
- const params: GetKycVerificationParams = {
832
- urn: 'did:bloque:user:123e4567',
833
- };
834
-
835
- try {
836
- const status = await bloque.compliance.kyc.getVerification(params);
837
-
838
- console.log('Status:', status.status);
839
- console.log('Verification URL:', status.url);
840
- console.log('Completed At:', status.completedAt);
841
-
842
- if (status.status === 'approved') {
843
- console.log('User verification approved!');
844
- } else if (status.status === 'rejected') {
845
- console.log('User verification rejected');
846
- } else {
847
- console.log('Verification still pending');
440
+ if (error instanceof BloqueRateLimitError) {
441
+ console.log(`Rate limited. Retry after ${error.retryAfter} seconds`);
442
+ console.log(`Request ID: ${error.requestId}`);
443
+ } else if (error instanceof BloqueValidationError) {
444
+ console.log('Validation errors:', error.validationErrors);
445
+ } else if (error instanceof BloqueAuthenticationError) {
446
+ console.log('Authentication failed. Check your API key.');
447
+ } else if (error instanceof BloqueNotFoundError) {
448
+ console.log(`Resource not found: ${error.resourceType}`);
449
+ } else if (error instanceof BloqueInsufficientFundsError) {
450
+ console.log(`Insufficient funds: ${error.requestedAmount} ${error.currency}`);
451
+ console.log(`Available: ${error.availableBalance} ${error.currency}`);
452
+ } else if (error instanceof BloqueTimeoutError) {
453
+ console.log(`Request timed out after ${error.timeoutMs}ms`);
454
+ } else if (error instanceof BloqueNetworkError) {
455
+ console.log('Network error:', error.message);
848
456
  }
849
- } catch (error) {
850
- console.error('Failed to get verification status:', error);
457
+
458
+ // All errors have these fields
459
+ console.log('Error details:', error.toJSON());
851
460
  }
852
461
  ```
853
462
 
854
- ### Creating a Virtual Card
463
+ ### Error Metadata
855
464
 
856
- ```typescript
857
- import { SDK } from '@bloque/sdk';
858
- import type { CreateCardParams } from '@bloque/sdk/accounts';
465
+ All errors include rich metadata for debugging:
859
466
 
860
- const bloque = new SDK({
861
- auth: {
862
- type: 'apiKey',
863
- apiKey: process.env.BLOQUE_API_KEY!,
864
- },
865
- mode: 'production',
866
- });
467
+ - `message`: Human-readable error message
468
+ - `status`: HTTP status code (if applicable)
469
+ - `code`: Error code from the API
470
+ - `requestId`: Unique request ID for tracing
471
+ - `timestamp`: When the error occurred
472
+ - `response`: Original response body (for debugging)
473
+ - `cause`: Original error (for error chaining)
867
474
 
868
- // Create a virtual card
869
- const params: CreateCardParams = {
870
- urn: 'did:bloque:user:123e4567',
871
- name: 'My Business Card', // Optional
872
- };
475
+ ## Retry Logic
873
476
 
874
- try {
875
- const card = await bloque.accounts.card.create(params);
876
-
877
- console.log('Card created:', card.urn);
878
- console.log('Last four digits:', card.lastFour);
879
- console.log('Card type:', card.cardType);
880
- console.log('Status:', card.status);
881
- console.log('Details URL:', card.detailsUrl);
882
-
883
- // Check if card is ready to use
884
- if (card.status === 'active') {
885
- console.log('Card is active and ready to use!');
886
- } else if (card.status === 'creation_in_progress') {
887
- console.log('Card is being created...');
888
- }
889
- } catch (error) {
890
- console.error('Failed to create card:', error);
891
- }
892
- ```
477
+ The SDK automatically retries failed requests with exponential backoff:
893
478
 
894
- ### Retrieving User Alias Information
479
+ - **Retried scenarios**: 429 (Rate Limit), 503 (Service Unavailable), network errors, timeouts
480
+ - **Exponential backoff**: Delay increases exponentially (1s → 2s → 4s)
481
+ - **Jitter**: ±25% random jitter to prevent thundering herd
482
+ - **Respects Retry-After**: Honors the `Retry-After` header when present
895
483
 
896
484
  ```typescript
897
- import { SDK } from '@bloque/sdk';
898
-
899
485
  const bloque = new SDK({
900
- auth: {
901
- type: 'apiKey',
902
- apiKey: process.env.BLOQUE_API_KEY!,
486
+ origin: 'your-origin',
487
+ auth: { type: 'apiKey', apiKey: 'key' },
488
+ retry: {
489
+ enabled: true, // default: true
490
+ maxRetries: 3, // default: 3
491
+ initialDelay: 1000, // default: 1000ms
492
+ maxDelay: 30000, // default: 30000ms
903
493
  },
904
- mode: 'production',
905
494
  });
906
-
907
- // Get alias information by email
908
- try {
909
- const alias = await bloque.identity.aliases.get('user@example.com');
910
-
911
- console.log('Alias ID:', alias.id);
912
- console.log('Alias type:', alias.type);
913
- console.log('Associated URN:', alias.urn);
914
- console.log('Status:', alias.status);
915
- console.log('Is primary:', alias.is_primary);
916
- console.log('Is public:', alias.is_public);
917
-
918
- if (alias.status === 'active') {
919
- console.log('Alias is active');
920
- }
921
- } catch (error) {
922
- console.error('Failed to retrieve alias:', error);
923
- }
924
-
925
- // Get alias information by phone number
926
- try {
927
- const phoneAlias = await bloque.identity.aliases.get('+1234567890');
928
-
929
- console.log('Phone alias:', phoneAlias.alias);
930
- console.log('Phone details:', phoneAlias.details.phone);
931
- } catch (error) {
932
- console.error('Failed to retrieve phone alias:', error);
933
- }
934
495
  ```
935
496
 
936
- ### Registering Individual User Identity (KYC)
497
+ ## Timeout Configuration
937
498
 
938
- ```typescript
939
- import { SDK } from '@bloque/sdk';
940
- import type { IndividualRegisterParams } from '@bloque/sdk/identity';
499
+ Configure request timeouts globally or per-request:
941
500
 
501
+ ```typescript
502
+ // Global timeout
942
503
  const bloque = new SDK({
943
- auth: {
944
- type: 'apiKey',
945
- apiKey: process.env.BLOQUE_API_KEY!,
946
- },
947
- mode: 'production',
504
+ origin: 'your-origin',
505
+ auth: { type: 'apiKey', apiKey: 'key' },
506
+ timeout: 15000, // 15 seconds
948
507
  });
949
508
 
950
- // Register an individual with blockchain signature
951
- const params: IndividualRegisterParams = {
952
- assertionResult: {
953
- alias: '0x742d35Cc6634C0532925a3b8D4C9db96C4b4d8b6',
954
- challengeType: 'SIGNING_CHALLENGE',
955
- value: {
956
- signature: '0x1234567890abcdef...',
957
- alias: '0x742d35Cc6634C0532925a3b8D4C9db96C4b4d8b6'
958
- },
959
- originalChallengeParams: {
960
- challenge: 'bloque-challenge-1234567890',
961
- timestamp: 1640995200
962
- }
963
- },
964
- type: 'individual',
965
- profile: {
966
- firstName: 'John',
967
- lastName: 'Doe',
968
- email: 'john.doe@example.com',
969
- phone: '+1234567890',
970
- birthdate: '1990-01-15',
971
- city: 'New York',
972
- state: 'NY',
973
- postalCode: '10001',
974
- addressLine1: '123 Main St',
975
- countryOfBirthCode: 'USA',
976
- countryOfResidenceCode: 'USA',
977
- personalIdType: 'SSN',
978
- personalIdNumber: '123-45-6789'
979
- }
980
- };
981
-
982
- try {
983
- const result = await bloque.identity.origins.register('ethereum-mainnet', params);
984
-
985
- console.log('User registered successfully!');
986
- console.log('Access token:', result.accessToken);
987
-
988
- // Store the access token securely for the user's session
989
- // Use it for subsequent authenticated API calls
990
- } catch (error) {
991
- console.error('Registration failed:', error);
992
- }
509
+ // Per-request timeout (override global)
510
+ const card = await session.accounts.card.create(
511
+ { name: 'My Card' },
512
+ { timeout: 5000 } // 5 seconds for this request
513
+ );
993
514
  ```
994
515
 
995
- ### Registering Business Identity (KYB)
516
+ ## Security Best Practices
996
517
 
997
- ```typescript
998
- import { SDK } from '@bloque/sdk';
999
- import type { BusinessRegisterParams } from '@bloque/sdk/identity';
518
+ ### API Keys
1000
519
 
1001
- const bloque = new SDK({
1002
- auth: {
1003
- type: 'apiKey',
1004
- apiKey: process.env.BLOQUE_API_KEY!,
1005
- },
1006
- mode: 'production',
1007
- });
1008
-
1009
- // Register a business with API key authentication
1010
- const params: BusinessRegisterParams = {
1011
- assertionResult: {
1012
- alias: 'business-123',
1013
- challengeType: 'API_KEY',
1014
- value: {
1015
- apiKey: 'sk_live_abc123def456',
1016
- alias: 'business-123'
1017
- }
1018
- },
1019
- type: 'business',
1020
- profile: {
1021
- // Required business information
1022
- legalName: 'Acme Corporation',
1023
- name: 'Acme Corp',
1024
- taxId: '12-3456789',
1025
- type: 'LLC',
1026
- incorporationDate: '2020-01-15',
1027
- addressLine1: '123 Business St',
1028
- city: 'New York',
1029
- state: 'NY',
1030
- postalCode: '10001',
1031
- country: 'United States',
1032
-
1033
- // Optional business information
1034
- addressLine2: 'Suite 100',
1035
- countryCode: 'US',
1036
- email: 'contact@acme.com',
1037
- phone: '+1-555-0123',
1038
- logo: 'https://acme.com/logo.png',
1039
-
1040
- // Beneficial owner information (for compliance)
1041
- ownerName: 'Jane Smith',
1042
- ownerIdType: 'SSN',
1043
- ownerIdNumber: '123-45-6789',
1044
- ownerAddressLine1: '456 Owner Ave',
1045
- ownerCity: 'New York',
1046
- ownerState: 'NY',
1047
- ownerPostalCode: '10002',
1048
- ownerCountryCode: 'US'
1049
- }
1050
- };
520
+ - Store API keys in environment variables
521
+ - ✅ Use different keys for development and production
522
+ - ✅ Never commit API keys to version control
523
+ - ✅ Rotate API keys regularly
524
+ - ❌ Never expose API keys in client-side code
1051
525
 
1052
- try {
1053
- const result = await bloque.identity.origins.register('bloque-api', params);
1054
-
1055
- console.log('Business registered successfully!');
1056
- console.log('Access token:', result.accessToken);
1057
-
1058
- // Use the access token for authenticated API calls
1059
- } catch (error) {
1060
- console.error('Business registration failed:', error);
1061
- }
1062
- ```
526
+ ### Token Storage (Frontend)
1063
527
 
1064
- ### Using in an API Endpoint
528
+ The SDK warns when using insecure storage:
1065
529
 
1066
530
  ```typescript
1067
- import { SDK } from '@bloque/sdk';
1068
- import type { CreateOrgParams } from '@bloque/sdk/orgs';
1069
-
531
+ // Browser: localStorage (⚠️ vulnerable to XSS)
1070
532
  const bloque = new SDK({
1071
- auth: {
1072
- type: 'apiKey',
1073
- apiKey: process.env.BLOQUE_API_KEY!,
1074
- },
1075
- mode: process.env.NODE_ENV === 'production' ? 'production' : 'sandbox',
533
+ auth: { type: 'jwt' },
534
+ platform: 'browser',
535
+ // Uses localStorage by default with security warning
1076
536
  });
1077
537
 
1078
- app.post('/api/organizations', async (req, res) => {
1079
- try {
1080
- const params: CreateOrgParams = req.body;
1081
-
1082
- const organization = await bloque.orgs.create(params);
1083
-
1084
- res.json({
1085
- success: true,
1086
- organization,
1087
- });
1088
- } catch (error) {
1089
- console.error('Organization creation failed:', error);
1090
- res.status(500).json({
1091
- success: false,
1092
- error: error instanceof Error ? error.message : 'Unknown error',
538
+ // Recommended: httpOnly cookies (immune to XSS)
539
+ const cookieStorage: TokenStorage = {
540
+ get: () => null, // Token sent automatically in cookie
541
+ set: async (token) => {
542
+ await fetch('/api/auth/set-token', {
543
+ method: 'POST',
544
+ body: JSON.stringify({ token }),
1093
545
  });
1094
- }
1095
- });
1096
- ```
1097
-
1098
-
1099
- ## Error Handling
1100
-
1101
- The SDK uses standard JavaScript errors. Always wrap API calls in try-catch blocks:
1102
-
1103
- ```typescript
1104
- import { SDK } from '@bloque/sdk';
546
+ },
547
+ clear: async () => {
548
+ await fetch('/api/auth/logout', { method: 'POST' });
549
+ },
550
+ };
1105
551
 
1106
552
  const bloque = new SDK({
1107
- apiKey: process.env.BLOQUE_API_KEY!,
1108
- mode: 'production',
553
+ auth: { type: 'jwt' },
554
+ platform: 'browser',
555
+ tokenStorage: cookieStorage,
1109
556
  });
1110
-
1111
- try {
1112
- const organization = await bloque.orgs.create({
1113
- org_type: 'business',
1114
- profile: {
1115
- legal_name: 'Acme Corp',
1116
- tax_id: '123456789',
1117
- incorporation_date: '2020-01-01',
1118
- business_type: 'llc',
1119
- incorporation_country_code: 'US',
1120
- address_line1: '123 Main St',
1121
- postal_code: '12345',
1122
- city: 'San Francisco',
1123
- },
1124
- });
1125
- console.log('Success:', organization);
1126
- } catch (error) {
1127
- if (error instanceof Error) {
1128
- console.error('Failed to create organization:', error.message);
1129
- } else {
1130
- console.error('Unknown error:', error);
1131
- }
1132
- }
1133
557
  ```
1134
558
 
1135
559
  ## TypeScript Support
1136
560
 
1137
- This SDK is written in TypeScript and includes complete type definitions. You'll get full autocomplete and type checking when using TypeScript or modern editors like VS Code:
561
+ The SDK is built with TypeScript and provides full type safety:
1138
562
 
1139
563
  ```typescript
1140
- import { SDK } from '@bloque/sdk';
1141
564
  import type {
1142
- BloqueConfig,
1143
- CreateOrgParams,
1144
- Organization,
1145
- OrgProfile,
1146
- OrgStatus,
1147
- OrgType,
1148
- Place,
1149
- } from '@bloque/sdk/orgs';
565
+ BloqueSDKConfig,
566
+ CardAccount,
567
+ CreateCardParams,
568
+ VirtualAccount,
569
+ CreateVirtualAccountParams,
570
+ TransferParams,
571
+ TransferResult,
572
+ } from '@bloque/sdk';
1150
573
 
1151
574
  // Type-safe configuration
1152
- const config: BloqueConfig = {
1153
- apiKey: 'your-api-key',
1154
- mode: 'sandbox',
1155
- };
1156
-
1157
- const bloque = new SDK(config);
1158
-
1159
- // Type-safe organization profile
1160
- const profile: OrgProfile = {
1161
- legal_name: 'Tech Startup Inc.',
1162
- tax_id: '12-3456789',
1163
- incorporation_date: '2023-01-15',
1164
- business_type: 'llc',
1165
- incorporation_country_code: 'US',
1166
- incorporation_state: 'CA',
1167
- address_line1: '456 Innovation Dr',
1168
- postal_code: '94025',
1169
- city: 'Menlo Park',
575
+ const config: BloqueSDKConfig = {
576
+ origin: 'your-origin',
577
+ auth: { type: 'apiKey', apiKey: 'key' },
578
+ mode: 'production',
1170
579
  };
1171
580
 
1172
- // Type-safe organization creation
1173
- const params: CreateOrgParams = {
1174
- org_type: 'business',
1175
- profile,
1176
- metadata: {
1177
- vertical: 'fintech',
1178
- employees: 50,
1179
- },
581
+ // Type-safe parameters
582
+ const params: CreateCardParams = {
583
+ name: 'My Card',
1180
584
  };
1181
585
 
1182
- // TypeScript infers the return type as Organization
1183
- const org = await bloque.orgs.create(params);
586
+ // Type-safe responses
587
+ const card: CardAccount = await session.accounts.card.create(params);
1184
588
  ```
1185
589
 
1186
- **Available Types**:
590
+ ## Package Exports
1187
591
 
1188
- The SDK exports all necessary types for type-safe development:
592
+ The SDK supports modular imports:
1189
593
 
1190
594
  ```typescript
1191
- // Main SDK types
1192
- import type { SDK, BloqueConfig } from '@bloque/sdk';
595
+ // Main SDK
596
+ import { SDK } from '@bloque/sdk';
1193
597
 
1194
- // Organization types
1195
- import type {
1196
- Organization,
1197
- CreateOrgParams,
1198
- CreateOrgResponse,
1199
- OrgProfile,
1200
- OrgType,
1201
- OrgStatus,
1202
- Place,
1203
- } from '@bloque/sdk/orgs';
1204
-
1205
- // Compliance types
1206
- import type {
1207
- KycVerificationParams,
1208
- KycVerificationResponse,
1209
- GetKycVerificationParams,
1210
- KycVerificationStatus,
1211
- } from '@bloque/sdk/compliance';
598
+ // Initialization helper
599
+ import { init } from '@bloque/sdk/init';
1212
600
 
1213
- // Accounts types
1214
- import type {
1215
- CardAccount,
1216
- CreateCardParams,
1217
- } from '@bloque/sdk/accounts';
601
+ // Modular clients (tree-shakeable)
602
+ import { AccountsClient } from '@bloque/sdk/accounts';
603
+ import { IdentityClient } from '@bloque/sdk/identity';
604
+ import { ComplianceClient } from '@bloque/sdk/compliance';
605
+ import { OrgsClient } from '@bloque/sdk/orgs';
1218
606
 
1219
- // Identity types
607
+ // Types
1220
608
  import type {
1221
- Alias,
1222
- RegisterParams,
1223
- IndividualRegisterParams,
1224
- BusinessRegisterParams,
1225
- RegisterResult,
1226
- UserProfile,
1227
- BusinessProfile,
1228
- AssertionResult,
1229
- } from '@bloque/sdk/identity';
609
+ BloqueSDKConfig,
610
+ CardAccount,
611
+ VirtualAccount,
612
+ BancolombiaAccount,
613
+ } from '@bloque/sdk';
1230
614
  ```
1231
615
 
1232
- ## Development
616
+ ## Advanced Usage
1233
617
 
1234
- ### Building the SDK
618
+ ### Custom HTTP Client
1235
619
 
1236
- ```bash
1237
- bun install
1238
- bun run build
1239
- ```
620
+ For advanced use cases, access the HTTP client directly:
1240
621
 
1241
- ### Development Mode (Watch)
1242
-
1243
- ```bash
1244
- bun run dev
1245
- ```
622
+ ```typescript
623
+ const session = await bloque.connect('did:bloque:your-origin:user-alias');
1246
624
 
1247
- ### Type Checking
625
+ // Access the HTTP client
626
+ const httpClient = session.accounts.card['httpClient'];
1248
627
 
1249
- ```bash
1250
- bun run typecheck
628
+ // Make custom requests
629
+ const response = await httpClient.request({
630
+ method: 'GET',
631
+ path: '/api/custom-endpoint',
632
+ timeout: 10000,
633
+ });
1251
634
  ```
1252
635
 
1253
- ### Code Quality
636
+ ### Environment-Specific Configuration
1254
637
 
1255
- ```bash
1256
- bun run check
638
+ ```typescript
639
+ const config: BloqueSDKConfig = {
640
+ origin: process.env.BLOQUE_ORIGIN!,
641
+ auth: {
642
+ type: 'apiKey',
643
+ apiKey: process.env.BLOQUE_API_KEY!,
644
+ },
645
+ mode: process.env.NODE_ENV === 'production' ? 'production' : 'sandbox',
646
+ platform: 'node',
647
+ timeout: Number.parseInt(process.env.BLOQUE_TIMEOUT || '30000', 10),
648
+ retry: {
649
+ enabled: process.env.BLOQUE_RETRY_ENABLED !== 'false',
650
+ maxRetries: Number.parseInt(process.env.BLOQUE_MAX_RETRIES || '3', 10),
651
+ },
652
+ };
653
+
654
+ const bloque = new SDK(config);
1257
655
  ```
1258
656
 
1259
- ## Requirements
657
+ ## Examples
1260
658
 
1261
- - One of the supported runtimes: Node.js 22.x+, Bun 1.x+, Deno, or modern browsers
1262
- - TypeScript 5.x or higher (for TypeScript projects, optional)
659
+ See the [`examples/`](./examples) directory for complete working examples:
1263
660
 
1264
- ## Links
661
+ - `basic-usage.ts` - Basic SDK usage
662
+ - `virtual-cards.ts` - Virtual card management
663
+ - `virtual-accounts.ts` - Virtual account management
664
+ - `transfers.ts` - Account transfers
665
+ - `identity-registration.ts` - User registration
666
+ - `kyc-verification.ts` - KYC workflows
667
+ - `error-handling.ts` - Advanced error handling
1265
668
 
1266
- - [Homepage](https://www.bloque.app)
1267
- - [GitHub Repository](https://github.com/bloque-app/sdk)
1268
- - [Issue Tracker](https://github.com/bloque-app/sdk/issues)
669
+ ## API Documentation
1269
670
 
1270
- ## Package Structure
671
+ For detailed API documentation, visit [docs.bloque.app/sdk](https://docs.bloque.app/sdk).
1271
672
 
1272
- This monorepo contains the following packages:
673
+ ## Support
1273
674
 
1274
- - **`@bloque/sdk`**: Main SDK package
1275
- - **`@bloque/sdk-core`**: Core utilities and HTTP client
1276
- - **`@bloque/sdk-orgs`**: Organizations API client
1277
- - **`@bloque/sdk-compliance`**: Compliance and KYC verification API client
1278
- - **`@bloque/sdk-accounts`**: Accounts and virtual cards API client
1279
- - **`@bloque/sdk-identity`**: Identity and aliases API client
675
+ - 📧 Email: [support@bloque.app](mailto:support@bloque.app)
676
+ - 💬 Discord: [discord.gg/bloque](https://discord.gg/bloque)
677
+ - 📖 Docs: [docs.bloque.app](https://docs.bloque.app)
678
+ - 🐛 Issues: [GitHub Issues](https://github.com/bloque/sdk/issues)
1280
679
 
1281
680
  ## License
1282
681
 
1283
- [MIT](../../LICENSE)
1284
-
682
+ MIT © [Bloque](https://www.bloque.app)