@bloque/sdk 0.0.23 → 0.0.25

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,24 +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
- - **Virtual Cards**: Create and manage virtual cards with real-time balance tracking
34
- - **Identity Registration**: Register individual users (KYC) and businesses (KYB) with multi-method authentication
35
- - **User Sessions**: Secure user session management with `connect()` for authenticated operations
36
- - **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, Polygon wallets, 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
37
45
  - **Lightweight**: Minimal dependencies for optimal bundle size
38
- - **Modular**: Import only what you need with tree-shakeable exports
39
-
40
- > **📌 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
41
47
 
42
48
  ## Installation
43
49
 
44
50
  ```bash
51
+ # npm
52
+ npm install @bloque/sdk
53
+
54
+ # bun
45
55
  bun add @bloque/sdk
56
+
57
+ # pnpm
58
+ pnpm add @bloque/sdk
59
+
60
+ # yarn
61
+ yarn add @bloque/sdk
46
62
  ```
47
63
 
48
64
  ## Quick Start
@@ -51,58 +67,34 @@ bun add @bloque/sdk
51
67
 
52
68
  ```typescript
53
69
  import { SDK } from '@bloque/sdk';
54
- import type { CreateOrgParams } from '@bloque/sdk/orgs';
55
70
 
56
71
  // Initialize the SDK with API key (backend only)
57
72
  const bloque = new SDK({
58
- origin: 'your-origin-name', // Required: your origin identifier
73
+ origin: 'your-origin-name',
59
74
  auth: {
60
75
  type: 'apiKey',
61
76
  apiKey: process.env.BLOQUE_API_KEY!,
62
77
  },
63
78
  mode: 'production', // or 'sandbox' for testing
64
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
+ },
65
86
  });
66
87
 
67
- // Connect to user session for account operations
68
- async function createCard() {
69
- // First, connect to the user's session
70
- const userSession = await bloque.connect('did:bloque:your-origin:user-alias');
71
-
72
- // Now create a virtual card through the session
73
- const card = await userSession.accounts.card.create({
74
- urn: 'did:bloque:your-origin:user-alias',
75
- name: 'My Virtual Card',
76
- });
77
-
78
- console.log('Card created:', card.urn);
79
- console.log('Last four digits:', card.lastFour);
80
- }
88
+ // Connect to user session
89
+ const session = await bloque.connect('did:bloque:your-origin:user-alias');
81
90
 
82
- // Create an organization (direct SDK access, no connect needed)
83
- async function createOrganization() {
84
- const params: CreateOrgParams = {
85
- org_type: 'business',
86
- profile: {
87
- legal_name: 'Acme Corporation',
88
- tax_id: '123456789',
89
- incorporation_date: '2020-01-01',
90
- business_type: 'llc',
91
- incorporation_country_code: 'US',
92
- incorporation_state: 'CA',
93
- address_line1: '123 Main St',
94
- postal_code: '12345',
95
- city: 'San Francisco',
96
- },
97
- metadata: {
98
- source: 'api',
99
- },
100
- };
91
+ // Create a virtual card
92
+ const card = await session.accounts.card.create({
93
+ name: 'My Virtual Card',
94
+ });
101
95
 
102
- const userSession = await bloque.connect('did:bloque:your-origin:user-alias');
103
- const organization = await userSession.orgs.create(params);
104
- console.log('Organization created:', organization);
105
- }
96
+ console.log('Card created:', card.urn);
97
+ console.log('Last four digits:', card.lastFour);
106
98
  ```
107
99
 
108
100
  ### Frontend (Browser, React Native)
@@ -112,1766 +104,610 @@ import { SDK } from '@bloque/sdk';
112
104
 
113
105
  // Initialize the SDK with JWT authentication
114
106
  const bloque = new SDK({
107
+ origin: 'your-origin-name',
115
108
  auth: { type: 'jwt' },
116
109
  mode: 'production',
117
110
  platform: 'browser', // or 'react-native'
118
- // tokenStorage is optional for browser (uses localStorage by default)
119
- // for react-native, provide a custom storage implementation
111
+ // For browser: uses localStorage by default (with security warning)
112
+ // For react-native: provide custom tokenStorage
113
+ tokenStorage: {
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
+ },
124
+ },
120
125
  });
121
126
 
122
- // After user registration, the SDK automatically stores the JWT
123
- const result = await bloque.identity.origins.register('ethereum-mainnet', {
124
- assertionResult: { /* ... */ },
125
- type: 'individual',
126
- profile: { /* ... */ }
127
- });
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
+ );
128
140
 
129
- // The token is now stored and used for subsequent requests
130
- const alias = await bloque.identity.aliases.get('user@example.com');
141
+ // The JWT is automatically stored and used for subsequent requests
131
142
  ```
132
143
 
133
144
  ## Configuration
134
145
 
135
- ### Initialize the SDK
146
+ ### Full Configuration Options
136
147
 
137
- The SDK supports different authentication methods depending on where it's running:
148
+ ```typescript
149
+ interface BloqueSDKConfig {
150
+ // Required
151
+ origin: string; // Your origin identifier
152
+ auth: AuthStrategy; // Authentication strategy
138
153
 
139
- #### Backend Configuration (API Key)
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
160
+ }
140
161
 
141
- For server-side applications (Node.js, Bun, Deno):
162
+ // Authentication strategies
163
+ type AuthStrategy =
164
+ | { type: 'apiKey'; apiKey: string } // Backend only
165
+ | { type: 'jwt' }; // Frontend (browser/react-native)
142
166
 
143
- ```typescript
144
- import { SDK } from '@bloque/sdk';
167
+ // Platforms
168
+ type Platform = 'node' | 'bun' | 'deno' | 'browser' | 'react-native';
145
169
 
146
- const bloque = new SDK({
147
- auth: {
148
- type: 'apiKey',
149
- apiKey: process.env.BLOQUE_API_KEY!, // Your Bloque API key
150
- },
151
- mode: 'production', // 'sandbox' or 'production'
152
- platform: 'node', // optional: 'node' | 'bun' | 'deno' (defaults to 'node')
153
- });
170
+ // Modes
171
+ type Mode = 'production' | 'sandbox';
172
+
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
179
+ }
154
180
  ```
155
181
 
156
- #### Frontend Configuration (JWT)
182
+ ## SDK Structure
157
183
 
158
- For client-side applications (Browser, React Native):
184
+ After connecting to a user session, you have access to these clients:
159
185
 
160
186
  ```typescript
161
- import { SDK } from '@bloque/sdk';
187
+ const session = await bloque.connect('did:bloque:your-origin:user-alias');
162
188
 
163
- // Browser
164
- const bloque = new SDK({
165
- auth: { type: 'jwt' },
166
- mode: 'production',
167
- platform: 'browser',
168
- // tokenStorage is optional - uses localStorage by default
169
- });
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
194
+ ```
170
195
 
171
- // React Native (with custom storage)
172
- import AsyncStorage from '@react-native-async-storage/async-storage';
196
+ ## Accounts Client
173
197
 
174
- const bloque = new SDK({
175
- auth: { type: 'jwt' },
176
- mode: 'production',
177
- platform: 'react-native',
178
- tokenStorage: {
179
- get: async () => await AsyncStorage.getItem('access_token'),
180
- set: async (token: string) => await AsyncStorage.setItem('access_token', token),
181
- clear: async () => await AsyncStorage.removeItem('access_token'),
182
- },
183
- });
184
- ```
198
+ The accounts client provides access to multiple account types:
185
199
 
186
- ### Configuration Options
200
+ ### Virtual Cards
201
+
202
+ ```typescript
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
+ });
187
208
 
188
- - **`origin`** (string, required): Your origin identifier/namespace
189
- - This identifies your application or organization in the Bloque platform
190
- - Example: `'my-app'`, `'bloque-root'`, `'ethereum-mainnet'`
209
+ // List cards
210
+ const cards = await session.accounts.card.list();
191
211
 
192
- - **`auth`** (object, required): Authentication configuration
193
- - `type: 'apiKey'`: For backend platforms
194
- - `apiKey` (string, required): Your Bloque API key
195
- - `type: 'jwt'`: For frontend platforms
196
- - Requires storing and managing JWT tokens via `tokenStorage`
212
+ // Check balance
213
+ const balance = await session.accounts.card.balance({
214
+ urn: card.urn,
215
+ });
197
216
 
198
- - **`mode`** ('sandbox' | 'production', optional): Environment mode
199
- - `sandbox`: For testing and development
200
- - `production`: For live operations (default)
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'
223
+ });
201
224
 
202
- - **`platform`** (string, optional): Execution platform
203
- - Backend: `'node'` (default) | `'bun'` | `'deno'`
204
- - Frontend: `'browser'` | `'react-native'`
205
- - Determines available authentication methods
225
+ // Update card
226
+ const updated = await session.accounts.card.updateMetadata({
227
+ urn: card.urn,
228
+ metadata: { name: 'Updated Name' },
229
+ });
206
230
 
207
- - **`tokenStorage`** (object, optional): JWT token storage mechanism
208
- - Required for JWT authentication on non-browser platforms
209
- - Browser automatically uses `localStorage` if not provided
210
- - Must implement: `get()`, `set(token)`, `clear()`
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);
235
+ ```
211
236
 
212
- ### User Sessions with `connect()`
237
+ ### Virtual Accounts
213
238
 
214
- Most operations in the SDK require connecting to a user session first. This ensures proper authentication and authorization for user-specific operations.
239
+ Virtual accounts are simple testing accounts requiring only basic personal information:
215
240
 
216
241
  ```typescript
217
- // Initialize SDK
218
- const bloque = new SDK({
219
- origin: 'your-origin',
220
- auth: {
221
- type: 'apiKey',
222
- apiKey: process.env.BLOQUE_API_KEY!,
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',
223
249
  },
224
- mode: 'production',
225
250
  });
226
251
 
227
- // Connect to user session
228
- const userSession = await bloque.connect('did:bloque:your-origin:user-alias');
229
-
230
- // Now perform operations through the session
231
- const card = await userSession.accounts.card.create({
232
- urn: 'did:bloque:your-origin:user-alias',
233
- name: 'My Card',
252
+ // Update metadata
253
+ await session.accounts.virtual.updateMetadata({
254
+ urn: account.urn,
255
+ metadata: { updated_by: 'admin' },
234
256
  });
257
+
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);
235
262
  ```
236
263
 
237
- **What `connect()` does:**
238
- - Authenticates the user with the specified URN
239
- - Obtains an access token for the user session
240
- - Returns a session object with access to: `accounts`, `compliance`, `identity`, `orgs`
264
+ ### Polygon Wallets
241
265
 
242
- **URN Format:**
243
- - Pattern: `did:bloque:{origin}:{user-alias}`
244
- - Example: `did:bloque:my-app:john-doe`
245
- - The `{origin}` must match the origin specified in SDK configuration
246
- - The `{user-alias}` is the user's unique identifier in your origin
266
+ Cryptocurrency wallets on the Polygon network for Web3 transactions:
247
267
 
248
- ### Platform and Authentication Compatibility
268
+ ```typescript
269
+ // Create a Polygon wallet (no additional input required)
270
+ const wallet = await session.accounts.polygon.create({
271
+ metadata: {
272
+ purpose: 'web3-transactions',
273
+ project: 'my-dapp',
274
+ },
275
+ });
249
276
 
250
- | Platform | API Key Auth | JWT Auth | Token Storage |
251
- |----------|--------------|----------|---------------|
252
- | `node` | ✅ | ✅ | Required for JWT |
253
- | `bun` | ✅ | ✅ | Required for JWT |
254
- | `deno` | ✅ | ✅ | Required for JWT |
255
- | `browser` | ❌ | ✅ | Optional (uses localStorage) |
256
- | `react-native` | ❌ | ✅ | Required |
277
+ console.log('Wallet address:', wallet.address);
278
+ console.log('Network:', wallet.network); // "polygon"
257
279
 
258
- ## API Reference
280
+ // Update metadata
281
+ await session.accounts.polygon.updateMetadata({
282
+ urn: wallet.urn,
283
+ metadata: { environment: 'production' },
284
+ });
259
285
 
260
- ### Organizations
286
+ // Manage account state
287
+ await session.accounts.polygon.activate(wallet.urn);
288
+ await session.accounts.polygon.freeze(wallet.urn);
289
+ await session.accounts.polygon.disable(wallet.urn);
290
+ ```
261
291
 
262
- The organizations resource allows you to create and manage organizations in the Bloque platform.
292
+ ### Bancolombia Accounts
263
293
 
264
- #### Create an Organization
294
+ Colombian virtual accounts with unique reference code system:
265
295
 
266
296
  ```typescript
267
- // Connect to user session first
268
- const userSession = await bloque.connect('did:bloque:your-origin:user-alias');
269
-
270
- // Create organization through the session
271
- const organization = await userSession.orgs.create(params);
272
- ```
297
+ // Create a Bancolombia account
298
+ const account = await session.accounts.bancolombia.create({
299
+ name: 'Main Account',
300
+ webhookUrl: 'https://your-app.com/webhooks/bancolombia',
301
+ });
273
302
 
274
- **Parameters**:
303
+ console.log('Reference code:', account.referenceCode);
275
304
 
276
- ```typescript
277
- interface CreateOrgParams {
278
- org_type: 'business' | 'individual'; // Organization type
279
- profile: OrgProfile; // Organization profile details
280
- metadata?: Record<string, unknown>; // Optional custom metadata
281
- }
305
+ // Update metadata or name
306
+ await session.accounts.bancolombia.updateMetadata({
307
+ urn: account.urn,
308
+ metadata: { category: 'savings' },
309
+ });
282
310
 
283
- interface OrgProfile {
284
- legal_name: string; // Legal name of the organization
285
- tax_id: string; // Tax ID number
286
- incorporation_date: string; // Date of incorporation (YYYY-MM-DD)
287
- business_type: string; // Type of business (e.g., 'llc', 'corporation')
288
- incorporation_country_code: string; // Country code (ISO 3166-1 alpha-2)
289
- incorporation_state?: string; // State/province (optional)
290
- address_line1: string; // Primary address line
291
- address_line2?: string; // Secondary address line (optional)
292
- postal_code: string; // Postal/ZIP code
293
- city: string; // City
294
- logo_url?: string; // Logo URL (optional)
295
- places?: Place[]; // Additional places/locations (optional)
296
- }
311
+ await session.accounts.bancolombia.updateName(account.urn, 'Savings Account');
297
312
 
298
- interface Place {
299
- country_code: string; // Country code
300
- state: string; // State/province
301
- address_line1: string; // Address line 1
302
- postal_code: string; // Postal code
303
- city: string; // City
304
- is_primary: boolean; // Whether this is the primary place
305
- }
313
+ // Manage account state
314
+ await session.accounts.bancolombia.activate(account.urn);
315
+ await session.accounts.bancolombia.freeze(account.urn);
316
+ await session.accounts.bancolombia.disable(account.urn);
306
317
  ```
307
318
 
308
- **Response**:
319
+ ### Transfers
320
+
321
+ Transfer funds between any account types:
309
322
 
310
323
  ```typescript
311
- interface Organization {
312
- urn: string; // Unique resource name
313
- org_type: 'business' | 'individual'; // Organization type
314
- profile: OrgProfile; // Organization profile
315
- metadata?: Record<string, unknown>; // Custom metadata
316
- status: OrgStatus; // Organization status
317
- }
324
+ const result = await session.accounts.transfer({
325
+ sourceUrn: 'did:bloque:account:card:usr-123:crd-456',
326
+ destinationUrn: 'did:bloque:account:virtual:acc-789',
327
+ amount: '1000000', // Amount in smallest unit
328
+ asset: 'DUSD/6', // 'DUSD/6' | 'KSM/12'
329
+ metadata: {
330
+ description: 'Payment for services',
331
+ },
332
+ });
318
333
 
319
- type OrgStatus =
320
- | 'awaiting_compliance_verification'
321
- | 'active'
322
- | 'suspended'
323
- | 'closed';
334
+ console.log('Transfer queued:', result.queueId);
335
+ console.log('Status:', result.status); // 'queued' | 'processing' | 'completed' | 'failed'
324
336
  ```
325
337
 
326
- ### Compliance
327
-
328
- The compliance resource provides KYC (Know Your Customer) verification functionality.
329
-
330
- #### Start KYC Verification
338
+ ## Identity Client
331
339
 
332
- Start a KYC verification process for a user:
340
+ Manage user identities and authentication:
333
341
 
334
342
  ```typescript
335
- // Connect to user session
336
- const userSession = await bloque.connect('did:bloque:your-origin:user-alias');
337
-
338
- // Start KYC verification
339
- const verification = await userSession.compliance.kyc.startVerification({
340
- urn: 'did:bloque:your-origin:user-alias',
341
- });
342
- ```
343
-
344
- **Parameters**:
343
+ // Get alias information
344
+ const alias = await session.identity.aliases.get('user@example.com');
345
345
 
346
- ```typescript
347
- interface KycVerificationParams {
348
- /**
349
- * URN (Uniform Resource Name) that uniquely identifies the user
350
- * within the system. This value is used to associate the KYC
351
- * verification process with a specific user.
352
- *
353
- * @example "did:bloque:origin:..."
354
- */
355
- urn: string;
356
-
357
- /**
358
- * URL where webhook notifications will be sent when the verification
359
- * status changes (optional).
360
- *
361
- * @example "https://api.example.com/webhooks/kyc"
362
- */
363
- webhookUrl?: string;
364
- }
365
- ```
346
+ // List available origins
347
+ const origins = await session.identity.origins.list();
366
348
 
367
- **Response**:
349
+ // Register a new identity (individual)
350
+ const result = await bloque.identity.origins.register(
351
+ 'did:bloque:your-origin:ethereum-mainnet',
352
+ {
353
+ assertionResult: {
354
+ alias: '0x742d35Cc...',
355
+ challengeType: 'SIGNING_CHALLENGE',
356
+ value: {
357
+ signature: '0x...',
358
+ alias: '0x742d35Cc...',
359
+ },
360
+ },
361
+ type: 'individual',
362
+ profile: {
363
+ firstName: 'John',
364
+ lastName: 'Doe',
365
+ email: 'john@example.com',
366
+ birthdate: '1990-01-15',
367
+ countryOfResidenceCode: 'US',
368
+ },
369
+ }
370
+ );
371
+
372
+ // Register a business
373
+ const businessResult = await bloque.identity.origins.register(
374
+ 'did:bloque:your-origin:ethereum-mainnet',
375
+ {
376
+ assertionResult: { /* ... */ },
377
+ type: 'business',
378
+ profile: {
379
+ legalName: 'Acme Corporation',
380
+ taxId: '123456789',
381
+ incorporationDate: '2020-01-01',
382
+ type: 'llc',
383
+ addressLine1: '123 Main St',
384
+ city: 'San Francisco',
385
+ state: 'CA',
386
+ country: 'US',
387
+ postalCode: '12345',
388
+ // ... other required fields
389
+ },
390
+ }
391
+ );
368
392
 
369
- ```typescript
370
- interface KycVerificationResponse {
371
- url: string; // URL where the user should complete the verification
372
- status: 'awaiting_compliance_verification' | 'approved' | 'rejected';
373
- }
393
+ // OTP-based authentication
394
+ const otpEmail = await bloque.identity.origins.email.assert('user@example.com');
395
+ const otpWhatsApp = await bloque.identity.origins.whatsapp.assert('+1234567890');
396
+ const otpCustom = await bloque.identity.origins.custom('my-origin').assert('user-id');
374
397
  ```
375
398
 
376
- #### Get KYC Verification Status
399
+ ## Compliance Client
377
400
 
378
- Get the current status of a KYC verification:
401
+ KYC/KYB verification workflows:
379
402
 
380
403
  ```typescript
381
- const status = await bloque.compliance.kyc.getVerification({
404
+ // Start KYC verification
405
+ const verification = await session.compliance.kyc.startVerification({
382
406
  urn: 'did:bloque:user:123e4567',
407
+ webhookUrl: 'https://your-app.com/webhooks/kyc',
383
408
  });
384
- ```
385
409
 
386
- **Parameters**:
387
-
388
- ```typescript
389
- interface GetKycVerificationParams {
390
- /**
391
- * URN (Uniform Resource Name) that uniquely identifies the user
392
- * within the system.
393
- *
394
- * @example "did:bloque:user:123e4567"
395
- */
396
- urn: string;
397
- }
398
- ```
410
+ console.log('Verification URL:', verification.url);
411
+ console.log('Status:', verification.status);
399
412
 
400
- **Response**:
413
+ // Get verification status
414
+ const status = await session.compliance.kyc.getVerification({
415
+ urn: 'did:bloque:user:123e4567',
416
+ });
401
417
 
402
- ```typescript
403
- interface KycVerificationStatus {
404
- status: 'awaiting_compliance_verification' | 'approved' | 'rejected';
405
- url: string; // URL for verification
406
- completedAt: string | null; // Completion date (ISO 8601)
407
- }
418
+ console.log('Status:', status.status);
419
+ console.log('Completed at:', status.completedAt);
408
420
  ```
409
421
 
410
- ### Accounts
411
-
412
- The accounts resource allows you to create virtual cards for users.
422
+ ## Organizations Client
413
423
 
414
- #### Create a Virtual Card
415
-
416
- Create a virtual card for a user:
424
+ Create and manage organizations:
417
425
 
418
426
  ```typescript
419
- // Connect to user session
420
- const userSession = await bloque.connect('did:bloque:your-origin:user-alias');
421
-
422
- // Create virtual card
423
- const card = await userSession.accounts.card.create({
424
- urn: 'did:bloque:your-origin:user-alias',
425
- name: 'My Virtual Card', // Optional
427
+ const org = await session.orgs.create({
428
+ org_type: 'business',
429
+ profile: {
430
+ legal_name: 'Acme Corporation',
431
+ tax_id: '123456789',
432
+ incorporation_date: '2020-01-01',
433
+ business_type: 'llc',
434
+ incorporation_country_code: 'US',
435
+ incorporation_state: 'CA',
436
+ address_line1: '123 Main St',
437
+ address_line2: 'Suite 100',
438
+ postal_code: '12345',
439
+ city: 'San Francisco',
440
+ },
441
+ metadata: {
442
+ industry: 'technology',
443
+ },
426
444
  });
427
- ```
428
445
 
429
- **Parameters**:
430
-
431
- ```typescript
432
- interface CreateCardParams {
433
- /**
434
- * URN of the account holder (user or organization)
435
- * @example "did:bloque:user:123e4567"
436
- */
437
- urn: string;
438
-
439
- /**
440
- * Display name for the card (optional)
441
- */
442
- name?: string;
443
- }
446
+ console.log('Organization created:', org.urn);
447
+ console.log('Status:', org.status);
444
448
  ```
445
449
 
446
- **Response**:
450
+ ## Error Handling
451
+
452
+ The SDK provides specific error types for better error handling:
447
453
 
448
454
  ```typescript
449
- interface CardAccount {
450
- urn: string; // Unique resource name
451
- id: string; // Card account ID
452
- lastFour: string; // Last four digits
453
- productType: 'CREDIT' | 'DEBIT'; // Card product type
454
- status: 'active' | 'disabled' | 'frozen' | 'deleted' | 'creation_in_progress' | 'creation_failed';
455
- cardType: 'VIRTUAL' | 'PHYSICAL'; // Card type
456
- detailsUrl: string; // PCI-compliant URL to view card details
457
- ownerUrn: string; // Owner URN
458
- webhookUrl: string | null; // Webhook URL (if configured)
459
- metadata?: Record<string, unknown>; // Custom metadata
460
- createdAt: string; // Creation timestamp (ISO 8601)
461
- updatedAt: string; // Last update timestamp (ISO 8601)
462
- balance?: Record<string, TokenBalance>; // Token balances (only in list responses)
463
- }
455
+ import {
456
+ BloqueRateLimitError,
457
+ BloqueAuthenticationError,
458
+ BloqueValidationError,
459
+ BloqueNotFoundError,
460
+ BloqueInsufficientFundsError,
461
+ BloqueNetworkError,
462
+ BloqueTimeoutError,
463
+ } from '@bloque/sdk';
464
+
465
+ try {
466
+ const card = await session.accounts.card.create({ name: 'My Card' });
467
+ } catch (error) {
468
+ if (error instanceof BloqueRateLimitError) {
469
+ console.log(`Rate limited. Retry after ${error.retryAfter} seconds`);
470
+ console.log(`Request ID: ${error.requestId}`);
471
+ } else if (error instanceof BloqueValidationError) {
472
+ console.log('Validation errors:', error.validationErrors);
473
+ } else if (error instanceof BloqueAuthenticationError) {
474
+ console.log('Authentication failed. Check your API key.');
475
+ } else if (error instanceof BloqueNotFoundError) {
476
+ console.log(`Resource not found: ${error.resourceType}`);
477
+ } else if (error instanceof BloqueInsufficientFundsError) {
478
+ console.log(`Insufficient funds: ${error.requestedAmount} ${error.currency}`);
479
+ console.log(`Available: ${error.availableBalance} ${error.currency}`);
480
+ } else if (error instanceof BloqueTimeoutError) {
481
+ console.log(`Request timed out after ${error.timeoutMs}ms`);
482
+ } else if (error instanceof BloqueNetworkError) {
483
+ console.log('Network error:', error.message);
484
+ }
464
485
 
465
- interface TokenBalance {
466
- current: string; // Current balance
467
- pending: string; // Pending balance
468
- in: string; // Total incoming
469
- out: string; // Total outgoing
486
+ // All errors have these fields
487
+ console.log('Error details:', error.toJSON());
470
488
  }
471
489
  ```
472
490
 
473
- #### List Card Accounts
491
+ ### Error Metadata
474
492
 
475
- List all card accounts for a holder with their current balances:
493
+ All errors include rich metadata for debugging:
476
494
 
477
- ```typescript
478
- // Using connected user session (recommended)
479
- const userSession = await bloque.connect('did:bloque:your-origin:user-alias');
480
- const cards = await userSession.accounts.card.list();
495
+ - `message`: Human-readable error message
496
+ - `status`: HTTP status code (if applicable)
497
+ - `code`: Error code from the API
498
+ - `requestId`: Unique request ID for tracing
499
+ - `timestamp`: When the error occurred
500
+ - `response`: Original response body (for debugging)
501
+ - `cause`: Original error (for error chaining)
481
502
 
482
- // Or with explicit holder URN
483
- const cards = await bloque.accounts.card.list({
484
- holderUrn: 'did:bloque:bloque-whatsapp:573023348486',
485
- });
486
- ```
503
+ ## Retry Logic
504
+
505
+ The SDK automatically retries failed requests with exponential backoff:
487
506
 
488
- **Parameters**:
507
+ - **Retried scenarios**: 429 (Rate Limit), 503 (Service Unavailable), network errors, timeouts
508
+ - **Exponential backoff**: Delay increases exponentially (1s → 2s → 4s)
509
+ - **Jitter**: ±25% random jitter to prevent thundering herd
510
+ - **Respects Retry-After**: Honors the `Retry-After` header when present
489
511
 
490
512
  ```typescript
491
- interface ListCardParams {
492
- /**
493
- * URN of the account holder to filter by
494
- * Optional when using a connected session - defaults to session URN
495
- * @example "did:bloque:bloque-whatsapp:573023348486"
496
- */
497
- holderUrn?: string;
498
- }
513
+ const bloque = new SDK({
514
+ origin: 'your-origin',
515
+ auth: { type: 'apiKey', apiKey: 'key' },
516
+ retry: {
517
+ enabled: true, // default: true
518
+ maxRetries: 3, // default: 3
519
+ initialDelay: 1000, // default: 1000ms
520
+ maxDelay: 30000, // default: 30000ms
521
+ },
522
+ });
499
523
  ```
500
524
 
501
- **Response**: `Promise<CardAccount[]>` - Array of card accounts with balances
502
-
503
- Each card in the response includes all standard fields plus a `balance` object containing token balances with current, pending, in, and out amounts for each token.
525
+ ## Timeout Configuration
504
526
 
505
- #### Get Card Balance
506
-
507
- Get the current balance for a specific card account:
527
+ Configure request timeouts globally or per-request:
508
528
 
509
529
  ```typescript
510
- const balances = await bloque.accounts.card.balance({
511
- urn: 'did:bloque:account:card:usr-123:crd-456',
530
+ // Global timeout
531
+ const bloque = new SDK({
532
+ origin: 'your-origin',
533
+ auth: { type: 'apiKey', apiKey: 'key' },
534
+ timeout: 15000, // 15 seconds
512
535
  });
513
- ```
514
536
 
515
- **Parameters**:
516
-
517
- ```typescript
518
- interface GetBalanceParams {
519
- /**
520
- * URN of the card account
521
- * @example "did:bloque:account:card:usr-123:crd-456"
522
- */
523
- urn: string;
524
- }
537
+ // Per-request timeout (override global)
538
+ const card = await session.accounts.card.create(
539
+ { name: 'My Card' },
540
+ { timeout: 5000 } // 5 seconds for this request
541
+ );
525
542
  ```
526
543
 
527
- **Response**: `Promise<Record<string, TokenBalance>>` - Token balances by asset
544
+ ## Security Best Practices
528
545
 
529
- Returns an object with token balances for each asset:
546
+ ### API Keys
530
547
 
531
- ```typescript
532
- {
533
- 'DUSD/6': {
534
- current: '1262500', // Current balance
535
- pending: '0', // Pending balance
536
- in: '5072000', // Total incoming
537
- out: '3809500' // Total outgoing
538
- },
539
- 'KSM/12': {
540
- current: '1989000011',
541
- pending: '0',
542
- in: '2000000000',
543
- out: '10999989'
544
- }
545
- }
546
- ```
548
+ - ✅ Store API keys in environment variables
549
+ - ✅ Use different keys for development and production
550
+ - ✅ Never commit API keys to version control
551
+ - Rotate API keys regularly
552
+ - Never expose API keys in client-side code
547
553
 
548
- #### List Card Movements
554
+ ### Token Storage (Frontend)
549
555
 
550
- List transactions/movements for a card account with pagination and filtering:
556
+ The SDK warns when using insecure storage:
551
557
 
552
558
  ```typescript
553
- // Basic usage
554
- const movements = await bloque.accounts.card.movements({
555
- urn: 'did:bloque:account:card:usr-123:crd-456',
556
- asset: 'DUSD/6',
559
+ // Browser: localStorage (⚠️ vulnerable to XSS)
560
+ const bloque = new SDK({
561
+ auth: { type: 'jwt' },
562
+ platform: 'browser',
563
+ // Uses localStorage by default with security warning
557
564
  });
558
565
 
559
- // With pagination and filters
560
- const recentIncoming = await bloque.accounts.card.movements({
561
- urn: 'did:bloque:account:card:usr-123:crd-456',
562
- asset: 'DUSD/6',
563
- limit: 50,
564
- direction: 'in', // Only incoming transactions
565
- after: '2025-01-01T00:00:00Z',
566
+ // Recommended: httpOnly cookies (immune to XSS)
567
+ const cookieStorage: TokenStorage = {
568
+ get: () => null, // Token sent automatically in cookie
569
+ set: async (token) => {
570
+ await fetch('/api/auth/set-token', {
571
+ method: 'POST',
572
+ body: JSON.stringify({ token }),
573
+ });
574
+ },
575
+ clear: async () => {
576
+ await fetch('/api/auth/logout', { method: 'POST' });
577
+ },
578
+ };
579
+
580
+ const bloque = new SDK({
581
+ auth: { type: 'jwt' },
582
+ platform: 'browser',
583
+ tokenStorage: cookieStorage,
566
584
  });
567
585
  ```
568
586
 
569
- **Parameters**:
587
+ ## TypeScript Support
588
+
589
+ The SDK is built with TypeScript and provides full type safety:
570
590
 
571
591
  ```typescript
572
- interface ListMovementsParams {
573
- /**
574
- * URN of the card account
575
- * @example "did:bloque:account:card:usr-123:crd-456"
576
- */
577
- urn: string;
578
-
579
- /**
580
- * Asset to filter transactions by
581
- * Supported assets: 'DUSD/6' | 'KSM/12'
582
- * Defaults to "DUSD/6" if not provided
583
- * @example "DUSD/6" or "KSM/12"
584
- */
585
- asset?: 'DUSD/6' | 'KSM/12';
586
-
587
- /**
588
- * Maximum number of transactions to return
589
- * @example 50
590
- */
591
- limit?: number;
592
-
593
- /**
594
- * Filter transactions before this date (ISO 8601)
595
- * @example "2025-01-01T00:00:00Z"
596
- */
597
- before?: string;
598
-
599
- /**
600
- * Filter transactions after this date (ISO 8601)
601
- * @example "2025-01-01T00:00:00Z"
602
- */
603
- after?: string;
604
-
605
- /**
606
- * Filter by transaction reference
607
- * @example "0xbff43fa587e0efa275f8b643d95881713c0f0ee13682d049cc452f607241b752"
608
- */
609
- reference?: string;
610
-
611
- /**
612
- * Filter by transaction direction
613
- * 'in' for incoming funds (deposits, transfers received)
614
- * 'out' for outgoing funds (withdrawals, transfers sent)
615
- */
616
- direction?: 'in' | 'out';
617
- }
618
- ```
592
+ import type {
593
+ BloqueSDKConfig,
594
+ CardAccount,
595
+ CreateCardParams,
596
+ VirtualAccount,
597
+ CreateVirtualAccountParams,
598
+ PolygonAccount,
599
+ CreatePolygonAccountParams,
600
+ TransferParams,
601
+ TransferResult,
602
+ } from '@bloque/sdk';
619
603
 
620
- **Response**: `Promise<CardMovement[]>` - Array of card transactions
604
+ // Type-safe configuration
605
+ const config: BloqueSDKConfig = {
606
+ origin: 'your-origin',
607
+ auth: { type: 'apiKey', apiKey: 'key' },
608
+ mode: 'production',
609
+ };
621
610
 
622
- Each movement includes:
611
+ // Type-safe parameters
612
+ const params: CreateCardParams = {
613
+ name: 'My Card',
614
+ };
623
615
 
624
- ```typescript
625
- interface CardMovement {
626
- amount: string; // Transaction amount
627
- asset: string; // Asset identifier (e.g., "DUSD/6")
628
- from_account_id: string; // Source account ID
629
- to_account_id: string; // Destination account ID
630
- direction: 'in' | 'out'; // Transaction direction
631
- reference: string; // Blockchain transaction reference
632
- rail_name: string; // Payment rail used
633
- created_at: string; // Transaction timestamp (ISO 8601)
634
-
635
- details: {
636
- type: string; // Transaction type (e.g., "CREDIT_ADJUSTMENT")
637
- metadata: {
638
- // Transaction details
639
- merchant_name?: string;
640
- merchant_city?: string;
641
- merchant_country?: string;
642
- transaction_type?: string;
643
- local_amount?: string;
644
- local_currency?: string;
645
- usd_amount?: string;
646
- card_last_four?: string;
647
- // ... and more
648
- };
649
- };
650
- }
616
+ // Type-safe responses
617
+ const card: CardAccount = await session.accounts.card.create(params);
651
618
  ```
652
619
 
653
- #### Transfer Between Accounts
620
+ ## Package Exports
654
621
 
655
- Transfer funds between any accounts (card, virtual, bancolombia, etc.):
622
+ The SDK supports modular imports:
656
623
 
657
624
  ```typescript
658
- const transfer = await bloque.accounts.transfer({
659
- sourceUrn: 'did:bloque:account:card:usr-123:crd-456',
660
- destinationUrn: 'did:bloque:account:virtual:acc-67890',
661
- amount: '1000000000000',
662
- asset: 'KSM/12',
663
- metadata: {
664
- reference: 'payment-123',
665
- note: 'Monthly subscription'
666
- }
667
- });
668
- ```
669
-
670
- **Parameters**:
625
+ // Main SDK
626
+ import { SDK } from '@bloque/sdk';
671
627
 
672
- ```typescript
673
- interface TransferParams {
674
- /**
675
- * URN of the source account
676
- * @example "did:bloque:account:card:usr-123:crd-456"
677
- */
678
- sourceUrn: string;
679
-
680
- /**
681
- * URN of the destination account
682
- * @example "did:bloque:account:virtual:acc-67890"
683
- */
684
- destinationUrn: string;
685
-
686
- /**
687
- * Amount to transfer
688
- * @example "1000000000000"
689
- */
690
- amount: string;
691
-
692
- /**
693
- * Asset to transfer
694
- * Supported assets: 'DUSD/6' | 'KSM/12'
695
- * @example "KSM/12"
696
- */
697
- asset: 'DUSD/6' | 'KSM/12';
698
-
699
- /**
700
- * Optional metadata for the transfer
701
- * @example { reference: "payment-123", note: "Monthly subscription" }
702
- */
703
- metadata?: Record<string, unknown>;
704
- }
705
- ```
628
+ // Initialization helper
629
+ import { init } from '@bloque/sdk/init';
706
630
 
707
- **Response**: `Promise<TransferResult>` - Transfer result
631
+ // Modular clients (tree-shakeable)
632
+ import { AccountsClient } from '@bloque/sdk/accounts';
633
+ import { IdentityClient } from '@bloque/sdk/identity';
634
+ import { ComplianceClient } from '@bloque/sdk/compliance';
635
+ import { OrgsClient } from '@bloque/sdk/orgs';
708
636
 
709
- ```typescript
710
- interface TransferResult {
711
- queueId: string; // Queue ID for tracking the transfer
712
- status: 'queued' | 'processing' | 'completed' | 'failed';
713
- message: string; // Status message
714
- }
637
+ // Types
638
+ import type {
639
+ BloqueSDKConfig,
640
+ CardAccount,
641
+ VirtualAccount,
642
+ PolygonAccount,
643
+ BancolombiaAccount,
644
+ } from '@bloque/sdk';
715
645
  ```
716
646
 
717
- The transfer is queued for signing and submission. You can track its progress using the returned `queueId`.
647
+ ## Advanced Usage
718
648
 
719
- ### Identity
649
+ ### Custom HTTP Client
720
650
 
721
- The identity resource allows you to register identities, retrieve user aliases, and manage authentication origins.
722
-
723
- #### Register Identity
724
-
725
- Register a new user or business identity to an authentication origin. Supports individual users (KYC) and businesses (KYB):
651
+ For advanced use cases, access the HTTP client directly:
726
652
 
727
653
  ```typescript
728
- // Register individual user
729
- const individual = await bloque.identity.origins.register('ethereum-mainnet', {
730
- assertionResult: {
731
- alias: '0x742d35Cc6634C0532925a3b8D4C9db96C4b4d8b6',
732
- challengeType: 'SIGNING_CHALLENGE',
733
- value: {
734
- signature: '0x1234567890abcdef...',
735
- alias: '0x742d35Cc6634C0532925a3b8D4C9db96C4b4d8b6'
736
- }
737
- },
738
- type: 'individual',
739
- profile: {
740
- firstName: 'John',
741
- lastName: 'Doe',
742
- email: 'john@example.com'
743
- }
744
- });
654
+ const session = await bloque.connect('did:bloque:your-origin:user-alias');
745
655
 
746
- // Register business
747
- const business = await bloque.identity.origins.register('bloque-api', {
748
- assertionResult: {
749
- alias: 'business-123',
750
- challengeType: 'API_KEY',
751
- value: {
752
- apiKey: 'sk_live_abc123',
753
- alias: 'business-123'
754
- }
755
- },
756
- type: 'business',
757
- profile: {
758
- legalName: 'Acme Corporation',
759
- name: 'Acme Corp',
760
- taxId: '12-3456789',
761
- type: 'LLC',
762
- incorporationDate: '2020-01-15',
763
- addressLine1: '123 Business St',
764
- city: 'New York',
765
- state: 'NY',
766
- postalCode: '10001',
767
- country: 'United States'
768
- }
656
+ // Access the HTTP client
657
+ const httpClient = session.accounts.card['httpClient'];
658
+
659
+ // Make custom requests
660
+ const response = await httpClient.request({
661
+ method: 'GET',
662
+ path: '/api/custom-endpoint',
663
+ timeout: 10000,
769
664
  });
770
665
  ```
771
666
 
772
- **Parameters**:
667
+ ### Environment-Specific Configuration
773
668
 
774
669
  ```typescript
775
- // Registration parameters (discriminated union by type)
776
- type RegisterParams = IndividualRegisterParams | BusinessRegisterParams;
777
-
778
- interface IndividualRegisterParams {
779
- assertionResult: AssertionResult;
780
- extraContext?: Record<string, unknown>;
781
- type: 'individual';
782
- profile: UserProfile;
783
- }
784
-
785
- interface BusinessRegisterParams {
786
- assertionResult: AssertionResult;
787
- extraContext?: Record<string, unknown>;
788
- type: 'business';
789
- profile: BusinessProfile;
790
- }
791
-
792
- // Assertion result for challenge verification
793
- interface AssertionResult {
794
- alias: string; // Identity identifier
795
- challengeType: 'SIGNING_CHALLENGE' | 'API_KEY' | 'OAUTH_REDIRECT' | 'WEBAUTHN' | 'OTP' | 'PASSWORD';
796
- value: {
797
- signature?: string; // For SIGNING_CHALLENGE
798
- apiKey?: string; // For API_KEY
799
- alias: string;
800
- };
801
- originalChallengeParams?: {
802
- challenge: string;
803
- timestamp: number;
804
- };
805
- }
806
-
807
- // Individual user profile (KYC)
808
- interface UserProfile {
809
- firstName?: string;
810
- lastName?: string;
811
- birthdate?: string; // ISO 8601 (YYYY-MM-DD)
812
- email?: string;
813
- phone?: string;
814
- gender?: string;
815
- addressLine1?: string;
816
- addressLine2?: string;
817
- city?: string;
818
- state?: string;
819
- postalCode?: string;
820
- neighborhood?: string;
821
- countryOfBirthCode?: string;
822
- countryOfResidenceCode?: string;
823
- personalIdType?: string;
824
- personalIdNumber?: string;
825
- }
670
+ const config: BloqueSDKConfig = {
671
+ origin: process.env.BLOQUE_ORIGIN!,
672
+ auth: {
673
+ type: 'apiKey',
674
+ apiKey: process.env.BLOQUE_API_KEY!,
675
+ },
676
+ mode: process.env.NODE_ENV === 'production' ? 'production' : 'sandbox',
677
+ platform: 'node',
678
+ timeout: Number.parseInt(process.env.BLOQUE_TIMEOUT || '30000', 10),
679
+ retry: {
680
+ enabled: process.env.BLOQUE_RETRY_ENABLED !== 'false',
681
+ maxRetries: Number.parseInt(process.env.BLOQUE_MAX_RETRIES || '3', 10),
682
+ },
683
+ };
826
684
 
827
- // Business profile (KYB)
828
- interface BusinessProfile {
829
- // Required fields
830
- addressLine1: string;
831
- city: string;
832
- country: string;
833
- incorporationDate: string;
834
- legalName: string;
835
- name: string;
836
- postalCode: string;
837
- state: string;
838
- taxId: string;
839
- type: string;
840
-
841
- // Optional fields
842
- addressLine2?: string;
843
- countryCode?: string;
844
- email?: string;
845
- logo?: string;
846
- phone?: string;
847
-
848
- // Beneficial owner information
849
- ownerName?: string;
850
- ownerIdType?: string;
851
- ownerIdNumber?: string;
852
- ownerAddressLine1?: string;
853
- ownerCity?: string;
854
- ownerState?: string;
855
- ownerPostalCode?: string;
856
- ownerCountryCode?: string;
857
- }
685
+ const bloque = new SDK(config);
858
686
  ```
859
687
 
860
- **Response**:
861
-
862
- ```typescript
863
- interface RegisterResult {
864
- accessToken: string; // JWT access token for authenticated sessions
865
- }
866
- ```
688
+ ## Examples
867
689
 
868
- #### Get Alias
690
+ See the [`examples/`](./examples) directory for complete working examples:
869
691
 
870
- Retrieve alias information by the alias value:
692
+ - `basic-usage.ts` - Basic SDK usage
693
+ - `virtual-cards.ts` - Virtual card management
694
+ - `virtual-accounts.ts` - Virtual account management
695
+ - `transfers.ts` - Account transfers
696
+ - `identity-registration.ts` - User registration
697
+ - `kyc-verification.ts` - KYC workflows
698
+ - `error-handling.ts` - Advanced error handling
871
699
 
872
- ```typescript
873
- const alias = await bloque.identity.aliases.get('user@example.com');
874
- ```
700
+ ## API Documentation
875
701
 
876
- **Parameters**:
702
+ For detailed API documentation, visit [docs.bloque.app/sdk](https://docs.bloque.app/sdk).
877
703
 
878
- ```typescript
879
- // Pass the alias string directly
880
- const alias: string = 'user@example.com' | '+1234567890';
881
- ```
704
+ ## Support
882
705
 
883
- **Response**:
884
-
885
- ```typescript
886
- interface Alias {
887
- id: string; // Unique alias ID
888
- alias: string; // Alias value
889
- type: 'phone' | 'email' | string; // Alias type
890
- urn: string; // Associated user URN
891
- origin: string; // Origin identifier
892
- details: {
893
- phone?: string; // Phone details (if applicable)
894
- };
895
- metadata: {
896
- alias: string; // Alias in metadata
897
- [key: string]: unknown; // Additional metadata
898
- };
899
- status: 'active' | 'inactive' | 'revoked'; // Alias status
900
- is_public: boolean; // Whether alias is public
901
- is_primary: boolean; // Whether this is the primary alias
902
- created_at: string; // Creation timestamp (ISO 8601)
903
- updated_at: string; // Last update timestamp (ISO 8601)
904
- }
905
- ```
906
-
907
- ## Examples
908
-
909
- ### Creating a Business Organization
910
-
911
- ```typescript
912
- import { SDK } from '@bloque/sdk';
913
- import type { CreateOrgParams } from '@bloque/sdk/orgs';
914
-
915
- // Initialize SDK with your API key
916
- const bloque = new SDK({
917
- auth: {
918
- type: 'apiKey',
919
- apiKey: process.env.BLOQUE_API_KEY!,
920
- },
921
- mode: 'production',
922
- });
923
-
924
- // Create a business organization
925
- const params: CreateOrgParams = {
926
- org_type: 'business',
927
- profile: {
928
- legal_name: 'Acme Corporation',
929
- tax_id: '12-3456789',
930
- incorporation_date: '2020-01-15',
931
- business_type: 'llc',
932
- incorporation_country_code: 'US',
933
- incorporation_state: 'CA',
934
- address_line1: '123 Market Street',
935
- address_line2: 'Suite 400',
936
- postal_code: '94103',
937
- city: 'San Francisco',
938
- logo_url: 'https://example.com/logo.png',
939
- },
940
- metadata: {
941
- source: 'web_app',
942
- campaign: 'q1_2024',
943
- },
944
- };
945
-
946
- try {
947
- const organization = await bloque.orgs.create(params);
948
- console.log('Organization created:', organization.urn);
949
- console.log('Status:', organization.status);
950
- } catch (error) {
951
- console.error('Failed to create organization:', error);
952
- }
953
- ```
954
-
955
- ### Creating an Individual Organization
956
-
957
- ```typescript
958
- import { SDK } from '@bloque/sdk';
959
- import type { CreateOrgParams } from '@bloque/sdk/orgs';
960
-
961
- const bloque = new SDK({
962
- auth: {
963
- type: 'apiKey',
964
- apiKey: process.env.BLOQUE_API_KEY!,
965
- },
966
- mode: 'sandbox',
967
- });
968
-
969
- const params: CreateOrgParams = {
970
- org_type: 'individual',
971
- profile: {
972
- legal_name: 'John Doe',
973
- tax_id: '123-45-6789',
974
- incorporation_date: '1990-05-20',
975
- business_type: 'sole_proprietorship',
976
- incorporation_country_code: 'US',
977
- address_line1: '456 Oak Avenue',
978
- postal_code: '10001',
979
- city: 'New York',
980
- },
981
- };
982
-
983
- const organization = await bloque.orgs.create(params);
984
- console.log('Individual organization created:', organization);
985
- ```
986
-
987
- ### Organization with Multiple Locations
988
-
989
- ```typescript
990
- import { SDK } from '@bloque/sdk';
991
- import type { CreateOrgParams } from '@bloque/sdk/orgs';
992
-
993
- const bloque = new SDK({
994
- auth: {
995
- type: 'apiKey',
996
- apiKey: process.env.BLOQUE_API_KEY!,
997
- },
998
- mode: 'production',
999
- });
1000
-
1001
- const params: CreateOrgParams = {
1002
- org_type: 'business',
1003
- profile: {
1004
- legal_name: 'Global Tech Solutions Inc.',
1005
- tax_id: '98-7654321',
1006
- incorporation_date: '2018-03-10',
1007
- business_type: 'corporation',
1008
- incorporation_country_code: 'US',
1009
- incorporation_state: 'DE',
1010
- address_line1: '789 Corporate Blvd',
1011
- postal_code: '19801',
1012
- city: 'Wilmington',
1013
- places: [
1014
- {
1015
- country_code: 'US',
1016
- state: 'CA',
1017
- address_line1: '100 Silicon Valley Drive',
1018
- postal_code: '94025',
1019
- city: 'Menlo Park',
1020
- is_primary: true,
1021
- },
1022
- {
1023
- country_code: 'US',
1024
- state: 'NY',
1025
- address_line1: '250 Broadway',
1026
- postal_code: '10007',
1027
- city: 'New York',
1028
- is_primary: false,
1029
- },
1030
- ],
1031
- },
1032
- };
1033
-
1034
- const organization = await bloque.orgs.create(params);
1035
- console.log('Multi-location organization created');
1036
- ```
1037
-
1038
- ### Starting KYC Verification
1039
-
1040
- ```typescript
1041
- import { SDK } from '@bloque/sdk';
1042
- import type { KycVerificationParams } from '@bloque/sdk/compliance';
1043
-
1044
- const bloque = new SDK({
1045
- auth: {
1046
- type: 'apiKey',
1047
- apiKey: process.env.BLOQUE_API_KEY!,
1048
- },
1049
- mode: 'production',
1050
- });
1051
-
1052
- // Start KYC verification for a user
1053
- const params: KycVerificationParams = {
1054
- urn: 'did:bloque:origin:user-123',
1055
- webhookUrl: 'https://api.example.com/webhooks/kyc', // Optional webhook URL
1056
- };
1057
-
1058
- try {
1059
- const verification = await bloque.compliance.kyc.startVerification(params);
1060
-
1061
- console.log('Verification URL:', verification.url);
1062
- console.log('Status:', verification.status);
1063
-
1064
- // Redirect the user to verification.url to complete KYC
1065
- // Webhook notifications will be sent to the provided webhookUrl
1066
- } catch (error) {
1067
- console.error('Failed to start KYC verification:', error);
1068
- }
1069
- ```
1070
-
1071
- ### Getting KYC Verification Status
1072
-
1073
- ```typescript
1074
- import { SDK } from '@bloque/sdk';
1075
- import type { GetKycVerificationParams } from '@bloque/sdk/compliance';
1076
-
1077
- const bloque = new SDK({
1078
- auth: {
1079
- type: 'apiKey',
1080
- apiKey: process.env.BLOQUE_API_KEY!,
1081
- },
1082
- mode: 'production',
1083
- });
1084
-
1085
- // Get verification status
1086
- const params: GetKycVerificationParams = {
1087
- urn: 'did:bloque:user:123e4567',
1088
- };
1089
-
1090
- try {
1091
- const status = await bloque.compliance.kyc.getVerification(params);
1092
-
1093
- console.log('Status:', status.status);
1094
- console.log('Verification URL:', status.url);
1095
- console.log('Completed At:', status.completedAt);
1096
-
1097
- if (status.status === 'approved') {
1098
- console.log('User verification approved!');
1099
- } else if (status.status === 'rejected') {
1100
- console.log('User verification rejected');
1101
- } else {
1102
- console.log('Verification still pending');
1103
- }
1104
- } catch (error) {
1105
- console.error('Failed to get verification status:', error);
1106
- }
1107
- ```
1108
-
1109
- ### Creating a Virtual Card
1110
-
1111
- ```typescript
1112
- import { SDK } from '@bloque/sdk';
1113
- import type { CreateCardParams } from '@bloque/sdk/accounts';
1114
-
1115
- const bloque = new SDK({
1116
- auth: {
1117
- type: 'apiKey',
1118
- apiKey: process.env.BLOQUE_API_KEY!,
1119
- },
1120
- mode: 'production',
1121
- });
1122
-
1123
- // Create a virtual card
1124
- const params: CreateCardParams = {
1125
- urn: 'did:bloque:user:123e4567',
1126
- name: 'My Business Card', // Optional
1127
- };
1128
-
1129
- try {
1130
- const card = await bloque.accounts.card.create(params);
1131
-
1132
- console.log('Card created:', card.urn);
1133
- console.log('Last four digits:', card.lastFour);
1134
- console.log('Card type:', card.cardType);
1135
- console.log('Status:', card.status);
1136
- console.log('Details URL:', card.detailsUrl);
1137
-
1138
- // Check if card is ready to use
1139
- if (card.status === 'active') {
1140
- console.log('Card is active and ready to use!');
1141
- } else if (card.status === 'creation_in_progress') {
1142
- console.log('Card is being created...');
1143
- }
1144
- } catch (error) {
1145
- console.error('Failed to create card:', error);
1146
- }
1147
- ```
1148
-
1149
- ### Listing Card Accounts
1150
-
1151
- ```typescript
1152
- import { SDK } from '@bloque/sdk';
1153
-
1154
- const bloque = new SDK({
1155
- origin: 'your-origin',
1156
- auth: {
1157
- type: 'apiKey',
1158
- apiKey: process.env.BLOQUE_API_KEY!,
1159
- },
1160
- mode: 'production',
1161
- });
1162
-
1163
- // Connect to user session
1164
- const userSession = await bloque.connect('did:bloque:bloque-whatsapp:573023348486');
1165
-
1166
- // List all cards for the connected user
1167
- try {
1168
- const cards = await userSession.accounts.card.list();
1169
-
1170
- console.log(`Found ${cards.length} card accounts`);
1171
-
1172
- cards.forEach((card) => {
1173
- console.log('\n---');
1174
- console.log('Card URN:', card.urn);
1175
- console.log('Last Four:', card.lastFour);
1176
- console.log('Status:', card.status);
1177
- console.log('Card Name:', card.metadata?.name);
1178
-
1179
- // Display balances
1180
- if (card.balance) {
1181
- console.log('Balances:');
1182
- Object.entries(card.balance).forEach(([token, balance]) => {
1183
- console.log(` ${token}:`);
1184
- console.log(` Current: ${balance.current}`);
1185
- console.log(` Pending: ${balance.pending}`);
1186
- console.log(` In: ${balance.in}`);
1187
- console.log(` Out: ${balance.out}`);
1188
- });
1189
- }
1190
- });
1191
-
1192
- // Find active cards only
1193
- const activeCards = cards.filter(card => card.status === 'active');
1194
- console.log(`\n${activeCards.length} cards are active`);
1195
-
1196
- // Calculate total balance across all cards
1197
- const totalBalances: Record<string, bigint> = {};
1198
-
1199
- activeCards.forEach(card => {
1200
- if (card.balance) {
1201
- Object.entries(card.balance).forEach(([token, balance]) => {
1202
- if (!totalBalances[token]) {
1203
- totalBalances[token] = BigInt(0);
1204
- }
1205
- totalBalances[token] += BigInt(balance.current);
1206
- });
1207
- }
1208
- });
1209
-
1210
- console.log('\nTotal balances across all active cards:');
1211
- Object.entries(totalBalances).forEach(([token, total]) => {
1212
- console.log(` ${token}: ${total.toString()}`);
1213
- });
1214
- } catch (error) {
1215
- console.error('Failed to list cards:', error);
1216
- }
1217
- ```
1218
-
1219
- ### Getting Card Balance
1220
-
1221
- ```typescript
1222
- import { SDK } from '@bloque/sdk';
1223
-
1224
- const bloque = new SDK({
1225
- origin: 'your-origin',
1226
- auth: {
1227
- type: 'apiKey',
1228
- apiKey: process.env.BLOQUE_API_KEY!,
1229
- },
1230
- mode: 'production',
1231
- });
1232
-
1233
- // Get balance for a specific card
1234
- try {
1235
- const balances = await bloque.accounts.card.balance({
1236
- urn: 'did:bloque:account:card:usr-123:crd-456',
1237
- });
1238
-
1239
- console.log('Card Balances:\n');
1240
-
1241
- Object.entries(balances).forEach(([token, balance]) => {
1242
- console.log(`${token}:`);
1243
- console.log(` Current: ${balance.current}`);
1244
- console.log(` Pending: ${balance.pending}`);
1245
- console.log(` Total In: ${balance.in}`);
1246
- console.log(` Total Out: ${balance.out}`);
1247
-
1248
- const net = BigInt(balance.in) - BigInt(balance.out);
1249
- console.log(` Net: ${net.toString()}`);
1250
- console.log('');
1251
- });
1252
-
1253
- // Calculate total current balance across all assets
1254
- const totalCurrent = Object.entries(balances).reduce(
1255
- (acc, [token, balance]) => {
1256
- acc[token] = BigInt(balance.current);
1257
- return acc;
1258
- },
1259
- {} as Record<string, bigint>,
1260
- );
1261
-
1262
- console.log('Total Current Balances:');
1263
- Object.entries(totalCurrent).forEach(([token, amount]) => {
1264
- console.log(` ${token}: ${amount.toString()}`);
1265
- });
1266
- } catch (error) {
1267
- console.error('Failed to get balance:', error);
1268
- }
1269
- ```
1270
-
1271
- ### Listing Card Movements
1272
-
1273
- ```typescript
1274
- import { SDK } from '@bloque/sdk';
1275
-
1276
- const bloque = new SDK({
1277
- origin: 'your-origin',
1278
- auth: {
1279
- type: 'apiKey',
1280
- apiKey: process.env.BLOQUE_API_KEY!,
1281
- },
1282
- mode: 'production',
1283
- });
1284
-
1285
- // List recent transactions with pagination
1286
- try {
1287
- const movements = await bloque.accounts.card.movements({
1288
- urn: 'did:bloque:account:card:usr-123:crd-456',
1289
- asset: 'DUSD/6',
1290
- limit: 50,
1291
- direction: 'in', // Only incoming transactions
1292
- after: '2025-01-01T00:00:00Z',
1293
- });
1294
-
1295
- console.log(`Found ${movements.length} incoming transactions\n`);
1296
-
1297
- movements.forEach((transaction) => {
1298
- console.log('---');
1299
- console.log(`Amount: ${transaction.amount} ${transaction.asset}`);
1300
- console.log(`Direction: ${transaction.direction.toUpperCase()}`);
1301
- console.log(`Date: ${transaction.created_at}`);
1302
- console.log(`Reference: ${transaction.reference}`);
1303
-
1304
- // Show merchant details if available
1305
- if (transaction.details?.metadata) {
1306
- const meta = transaction.details.metadata;
1307
- if (meta.merchant_name) {
1308
- console.log(`Merchant: ${meta.merchant_name}`);
1309
- }
1310
- if (meta.merchant_city && meta.merchant_country) {
1311
- console.log(`Location: ${meta.merchant_city}, ${meta.merchant_country}`);
1312
- }
1313
- if (meta.transaction_type) {
1314
- console.log(`Type: ${meta.transaction_type}`);
1315
- }
1316
- if (meta.usd_amount) {
1317
- console.log(`USD Amount: $${meta.usd_amount}`);
1318
- }
1319
- }
1320
- console.log('');
1321
- });
1322
-
1323
- // Calculate total
1324
- const total = movements.reduce(
1325
- (sum, t) => sum + BigInt(t.amount),
1326
- BigInt(0),
1327
- );
1328
-
1329
- console.log(`Total received: ${total.toString()}`);
1330
- } catch (error) {
1331
- console.error('Failed to list movements:', error);
1332
- }
1333
- ```
1334
-
1335
- ### Paginating Through Card Movements
1336
-
1337
- ```typescript
1338
- import { SDK } from '@bloque/sdk';
1339
-
1340
- const bloque = new SDK({
1341
- origin: 'your-origin',
1342
- auth: {
1343
- type: 'apiKey',
1344
- apiKey: process.env.BLOQUE_API_KEY!,
1345
- },
1346
- mode: 'production',
1347
- });
1348
-
1349
- // Paginate through all transactions
1350
- async function getAllTransactions() {
1351
- const cardUrn = 'did:bloque:account:card:usr-123:crd-456';
1352
- const pageSize = 100;
1353
- let allMovements = [];
1354
- let hasMore = true;
1355
- let lastDate: string | undefined;
1356
-
1357
- try {
1358
- while (hasMore) {
1359
- const movements = await bloque.accounts.card.movements({
1360
- urn: cardUrn,
1361
- asset: 'DUSD/6',
1362
- limit: pageSize,
1363
- before: lastDate, // Get transactions before the last one we saw
1364
- });
1365
-
1366
- allMovements.push(...movements);
1367
- console.log(`Fetched ${movements.length} transactions`);
1368
-
1369
- if (movements.length < pageSize) {
1370
- hasMore = false; // Last page
1371
- } else {
1372
- lastDate = movements[movements.length - 1].created_at;
1373
- }
1374
- }
1375
-
1376
- console.log(`\nTotal transactions: ${allMovements.length}`);
1377
-
1378
- // Analyze all transactions
1379
- const totalIn = allMovements
1380
- .filter((t) => t.direction === 'in')
1381
- .reduce((sum, t) => sum + BigInt(t.amount), BigInt(0));
1382
-
1383
- const totalOut = allMovements
1384
- .filter((t) => t.direction === 'out')
1385
- .reduce((sum, t) => sum + BigInt(t.amount), BigInt(0));
1386
-
1387
- console.log(`Total incoming: ${totalIn.toString()}`);
1388
- console.log(`Total outgoing: ${totalOut.toString()}`);
1389
- console.log(`Net balance: ${(totalIn - totalOut).toString()}`);
1390
- } catch (error) {
1391
- console.error('Error:', error);
1392
- }
1393
- }
1394
-
1395
- getAllTransactions();
1396
- ```
1397
-
1398
- ### Transferring Funds Between Accounts
1399
-
1400
- ```typescript
1401
- import { SDK } from '@bloque/sdk';
1402
-
1403
- const bloque = new SDK({
1404
- origin: 'your-origin',
1405
- auth: {
1406
- type: 'apiKey',
1407
- apiKey: process.env.BLOQUE_API_KEY!,
1408
- },
1409
- mode: 'production',
1410
- });
1411
-
1412
- // Transfer from card to virtual account
1413
- try {
1414
- const transfer = await bloque.accounts.transfer({
1415
- sourceUrn: 'did:bloque:account:card:usr-123:crd-456',
1416
- destinationUrn: 'did:bloque:account:virtual:acc-67890',
1417
- amount: '1000000000000',
1418
- asset: 'KSM/12',
1419
- metadata: {
1420
- reference: 'payment-123',
1421
- note: 'Monthly subscription payment'
1422
- }
1423
- });
1424
-
1425
- console.log('Transfer initiated:');
1426
- console.log(' Queue ID:', transfer.queueId);
1427
- console.log(' Status:', transfer.status);
1428
- console.log(' Message:', transfer.message);
1429
-
1430
- // The transfer is now queued for processing
1431
- // You can track its status using the queueId
1432
- } catch (error) {
1433
- console.error('Transfer failed:', error);
1434
- }
1435
- ```
1436
-
1437
- ### Different Transfer Scenarios
1438
-
1439
- ```typescript
1440
- import { SDK } from '@bloque/sdk';
1441
-
1442
- const bloque = new SDK({
1443
- origin: 'your-origin',
1444
- auth: {
1445
- type: 'apiKey',
1446
- apiKey: process.env.BLOQUE_API_KEY!,
1447
- },
1448
- mode: 'production',
1449
- });
1450
-
1451
- // Transfer DUSD from card to Bancolombia account
1452
- const dusdTransfer = await bloque.accounts.transfer({
1453
- sourceUrn: 'did:bloque:account:card:usr-123:crd-456',
1454
- destinationUrn: 'did:bloque:account:bancolombia:acc-12345',
1455
- amount: '5000000', // 5 DUSD (6 decimals)
1456
- asset: 'DUSD/6',
1457
- metadata: {
1458
- reference: 'withdrawal-001',
1459
- type: 'savings'
1460
- }
1461
- });
1462
-
1463
- console.log(`DUSD transfer queued: ${dusdTransfer.queueId}`);
1464
-
1465
- // Transfer KSM between virtual accounts
1466
- const ksmTransfer = await bloque.accounts.transfer({
1467
- sourceUrn: 'did:bloque:account:virtual:acc-11111',
1468
- destinationUrn: 'did:bloque:account:virtual:acc-22222',
1469
- amount: '2000000000000', // 2 KSM (12 decimals)
1470
- asset: 'KSM/12',
1471
- metadata: {
1472
- reference: 'internal-transfer-42',
1473
- department: 'operations'
1474
- }
1475
- });
1476
-
1477
- console.log(`KSM transfer queued: ${ksmTransfer.queueId}`);
1478
- ```
1479
-
1480
- ### Retrieving User Alias Information
1481
-
1482
- ```typescript
1483
- import { SDK } from '@bloque/sdk';
1484
-
1485
- const bloque = new SDK({
1486
- auth: {
1487
- type: 'apiKey',
1488
- apiKey: process.env.BLOQUE_API_KEY!,
1489
- },
1490
- mode: 'production',
1491
- });
1492
-
1493
- // Get alias information by email
1494
- try {
1495
- const alias = await bloque.identity.aliases.get('user@example.com');
1496
-
1497
- console.log('Alias ID:', alias.id);
1498
- console.log('Alias type:', alias.type);
1499
- console.log('Associated URN:', alias.urn);
1500
- console.log('Status:', alias.status);
1501
- console.log('Is primary:', alias.is_primary);
1502
- console.log('Is public:', alias.is_public);
1503
-
1504
- if (alias.status === 'active') {
1505
- console.log('Alias is active');
1506
- }
1507
- } catch (error) {
1508
- console.error('Failed to retrieve alias:', error);
1509
- }
1510
-
1511
- // Get alias information by phone number
1512
- try {
1513
- const phoneAlias = await bloque.identity.aliases.get('+1234567890');
1514
-
1515
- console.log('Phone alias:', phoneAlias.alias);
1516
- console.log('Phone details:', phoneAlias.details.phone);
1517
- } catch (error) {
1518
- console.error('Failed to retrieve phone alias:', error);
1519
- }
1520
- ```
1521
-
1522
- ### Registering Individual User Identity (KYC)
1523
-
1524
- ```typescript
1525
- import { SDK } from '@bloque/sdk';
1526
- import type { IndividualRegisterParams } from '@bloque/sdk/identity';
1527
-
1528
- const bloque = new SDK({
1529
- auth: {
1530
- type: 'apiKey',
1531
- apiKey: process.env.BLOQUE_API_KEY!,
1532
- },
1533
- mode: 'production',
1534
- });
1535
-
1536
- // Register an individual with blockchain signature
1537
- const params: IndividualRegisterParams = {
1538
- assertionResult: {
1539
- alias: '0x742d35Cc6634C0532925a3b8D4C9db96C4b4d8b6',
1540
- challengeType: 'SIGNING_CHALLENGE',
1541
- value: {
1542
- signature: '0x1234567890abcdef...',
1543
- alias: '0x742d35Cc6634C0532925a3b8D4C9db96C4b4d8b6'
1544
- },
1545
- originalChallengeParams: {
1546
- challenge: 'bloque-challenge-1234567890',
1547
- timestamp: 1640995200
1548
- }
1549
- },
1550
- type: 'individual',
1551
- profile: {
1552
- firstName: 'John',
1553
- lastName: 'Doe',
1554
- email: 'john.doe@example.com',
1555
- phone: '+1234567890',
1556
- birthdate: '1990-01-15',
1557
- city: 'New York',
1558
- state: 'NY',
1559
- postalCode: '10001',
1560
- addressLine1: '123 Main St',
1561
- countryOfBirthCode: 'USA',
1562
- countryOfResidenceCode: 'USA',
1563
- personalIdType: 'SSN',
1564
- personalIdNumber: '123-45-6789'
1565
- }
1566
- };
1567
-
1568
- try {
1569
- const result = await bloque.identity.origins.register('ethereum-mainnet', params);
1570
-
1571
- console.log('User registered successfully!');
1572
- console.log('Access token:', result.accessToken);
1573
-
1574
- // Store the access token securely for the user's session
1575
- // Use it for subsequent authenticated API calls
1576
- } catch (error) {
1577
- console.error('Registration failed:', error);
1578
- }
1579
- ```
1580
-
1581
- ### Registering Business Identity (KYB)
1582
-
1583
- ```typescript
1584
- import { SDK } from '@bloque/sdk';
1585
- import type { BusinessRegisterParams } from '@bloque/sdk/identity';
1586
-
1587
- const bloque = new SDK({
1588
- auth: {
1589
- type: 'apiKey',
1590
- apiKey: process.env.BLOQUE_API_KEY!,
1591
- },
1592
- mode: 'production',
1593
- });
1594
-
1595
- // Register a business with API key authentication
1596
- const params: BusinessRegisterParams = {
1597
- assertionResult: {
1598
- alias: 'business-123',
1599
- challengeType: 'API_KEY',
1600
- value: {
1601
- apiKey: 'sk_live_abc123def456',
1602
- alias: 'business-123'
1603
- }
1604
- },
1605
- type: 'business',
1606
- profile: {
1607
- // Required business information
1608
- legalName: 'Acme Corporation',
1609
- name: 'Acme Corp',
1610
- taxId: '12-3456789',
1611
- type: 'LLC',
1612
- incorporationDate: '2020-01-15',
1613
- addressLine1: '123 Business St',
1614
- city: 'New York',
1615
- state: 'NY',
1616
- postalCode: '10001',
1617
- country: 'United States',
1618
-
1619
- // Optional business information
1620
- addressLine2: 'Suite 100',
1621
- countryCode: 'US',
1622
- email: 'contact@acme.com',
1623
- phone: '+1-555-0123',
1624
- logo: 'https://acme.com/logo.png',
1625
-
1626
- // Beneficial owner information (for compliance)
1627
- ownerName: 'Jane Smith',
1628
- ownerIdType: 'SSN',
1629
- ownerIdNumber: '123-45-6789',
1630
- ownerAddressLine1: '456 Owner Ave',
1631
- ownerCity: 'New York',
1632
- ownerState: 'NY',
1633
- ownerPostalCode: '10002',
1634
- ownerCountryCode: 'US'
1635
- }
1636
- };
1637
-
1638
- try {
1639
- const result = await bloque.identity.origins.register('bloque-api', params);
1640
-
1641
- console.log('Business registered successfully!');
1642
- console.log('Access token:', result.accessToken);
1643
-
1644
- // Use the access token for authenticated API calls
1645
- } catch (error) {
1646
- console.error('Business registration failed:', error);
1647
- }
1648
- ```
1649
-
1650
- ### Using in an API Endpoint
1651
-
1652
- ```typescript
1653
- import { SDK } from '@bloque/sdk';
1654
- import type { CreateOrgParams } from '@bloque/sdk/orgs';
1655
-
1656
- const bloque = new SDK({
1657
- auth: {
1658
- type: 'apiKey',
1659
- apiKey: process.env.BLOQUE_API_KEY!,
1660
- },
1661
- mode: process.env.NODE_ENV === 'production' ? 'production' : 'sandbox',
1662
- });
1663
-
1664
- app.post('/api/organizations', async (req, res) => {
1665
- try {
1666
- const params: CreateOrgParams = req.body;
1667
-
1668
- const organization = await bloque.orgs.create(params);
1669
-
1670
- res.json({
1671
- success: true,
1672
- organization,
1673
- });
1674
- } catch (error) {
1675
- console.error('Organization creation failed:', error);
1676
- res.status(500).json({
1677
- success: false,
1678
- error: error instanceof Error ? error.message : 'Unknown error',
1679
- });
1680
- }
1681
- });
1682
- ```
1683
-
1684
-
1685
- ## Error Handling
1686
-
1687
- The SDK uses standard JavaScript errors. Always wrap API calls in try-catch blocks:
1688
-
1689
- ```typescript
1690
- import { SDK } from '@bloque/sdk';
1691
-
1692
- const bloque = new SDK({
1693
- apiKey: process.env.BLOQUE_API_KEY!,
1694
- mode: 'production',
1695
- });
1696
-
1697
- try {
1698
- const organization = await bloque.orgs.create({
1699
- org_type: 'business',
1700
- profile: {
1701
- legal_name: 'Acme Corp',
1702
- tax_id: '123456789',
1703
- incorporation_date: '2020-01-01',
1704
- business_type: 'llc',
1705
- incorporation_country_code: 'US',
1706
- address_line1: '123 Main St',
1707
- postal_code: '12345',
1708
- city: 'San Francisco',
1709
- },
1710
- });
1711
- console.log('Success:', organization);
1712
- } catch (error) {
1713
- if (error instanceof Error) {
1714
- console.error('Failed to create organization:', error.message);
1715
- } else {
1716
- console.error('Unknown error:', error);
1717
- }
1718
- }
1719
- ```
1720
-
1721
- ## TypeScript Support
1722
-
1723
- 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:
1724
-
1725
- ```typescript
1726
- import { SDK } from '@bloque/sdk';
1727
- import type {
1728
- BloqueConfig,
1729
- CreateOrgParams,
1730
- Organization,
1731
- OrgProfile,
1732
- OrgStatus,
1733
- OrgType,
1734
- Place,
1735
- } from '@bloque/sdk/orgs';
1736
-
1737
- // Type-safe configuration
1738
- const config: BloqueConfig = {
1739
- apiKey: 'your-api-key',
1740
- mode: 'sandbox',
1741
- };
1742
-
1743
- const bloque = new SDK(config);
1744
-
1745
- // Type-safe organization profile
1746
- const profile: OrgProfile = {
1747
- legal_name: 'Tech Startup Inc.',
1748
- tax_id: '12-3456789',
1749
- incorporation_date: '2023-01-15',
1750
- business_type: 'llc',
1751
- incorporation_country_code: 'US',
1752
- incorporation_state: 'CA',
1753
- address_line1: '456 Innovation Dr',
1754
- postal_code: '94025',
1755
- city: 'Menlo Park',
1756
- };
1757
-
1758
- // Type-safe organization creation
1759
- const params: CreateOrgParams = {
1760
- org_type: 'business',
1761
- profile,
1762
- metadata: {
1763
- vertical: 'fintech',
1764
- employees: 50,
1765
- },
1766
- };
1767
-
1768
- // TypeScript infers the return type as Organization
1769
- const org = await bloque.orgs.create(params);
1770
- ```
1771
-
1772
- **Available Types**:
1773
-
1774
- The SDK exports all necessary types for type-safe development:
1775
-
1776
- ```typescript
1777
- // Main SDK types
1778
- import type { SDK, BloqueConfig } from '@bloque/sdk';
1779
-
1780
- // Organization types
1781
- import type {
1782
- Organization,
1783
- CreateOrgParams,
1784
- CreateOrgResponse,
1785
- OrgProfile,
1786
- OrgType,
1787
- OrgStatus,
1788
- Place,
1789
- } from '@bloque/sdk/orgs';
1790
-
1791
- // Compliance types
1792
- import type {
1793
- KycVerificationParams,
1794
- KycVerificationResponse,
1795
- GetKycVerificationParams,
1796
- KycVerificationStatus,
1797
- } from '@bloque/sdk/compliance';
1798
-
1799
- // Accounts types
1800
- import type {
1801
- CardAccount,
1802
- CardMovement,
1803
- CreateCardParams,
1804
- GetBalanceParams,
1805
- ListCardParams,
1806
- ListMovementsParams,
1807
- TokenBalance,
1808
- TransferParams,
1809
- TransferResult,
1810
- } from '@bloque/sdk/accounts';
1811
-
1812
- // Identity types
1813
- import type {
1814
- Alias,
1815
- RegisterParams,
1816
- IndividualRegisterParams,
1817
- BusinessRegisterParams,
1818
- RegisterResult,
1819
- UserProfile,
1820
- BusinessProfile,
1821
- AssertionResult,
1822
- } from '@bloque/sdk/identity';
1823
- ```
1824
-
1825
- ## Development
1826
-
1827
- ### Building the SDK
1828
-
1829
- ```bash
1830
- bun install
1831
- bun run build
1832
- ```
1833
-
1834
- ### Development Mode (Watch)
1835
-
1836
- ```bash
1837
- bun run dev
1838
- ```
1839
-
1840
- ### Type Checking
1841
-
1842
- ```bash
1843
- bun run typecheck
1844
- ```
1845
-
1846
- ### Code Quality
1847
-
1848
- ```bash
1849
- bun run check
1850
- ```
1851
-
1852
- ## Requirements
1853
-
1854
- - One of the supported runtimes: Node.js 22.x+, Bun 1.x+, Deno, or modern browsers
1855
- - TypeScript 5.x or higher (for TypeScript projects, optional)
1856
-
1857
- ## Links
1858
-
1859
- - [Homepage](https://www.bloque.app)
1860
- - [GitHub Repository](https://github.com/bloque-app/sdk)
1861
- - [Issue Tracker](https://github.com/bloque-app/sdk/issues)
1862
-
1863
- ## Package Structure
1864
-
1865
- This monorepo contains the following packages:
1866
-
1867
- - **`@bloque/sdk`**: Main SDK package
1868
- - **`@bloque/sdk-core`**: Core utilities and HTTP client
1869
- - **`@bloque/sdk-orgs`**: Organizations API client
1870
- - **`@bloque/sdk-compliance`**: Compliance and KYC verification API client
1871
- - **`@bloque/sdk-accounts`**: Accounts and virtual cards API client
1872
- - **`@bloque/sdk-identity`**: Identity and aliases API client
706
+ - 📧 Email: [support@bloque.app](mailto:support@bloque.app)
707
+ - 💬 Discord: [discord.gg/bloque](https://discord.gg/bloque)
708
+ - 📖 Docs: [docs.bloque.app](https://docs.bloque.app)
709
+ - 🐛 Issues: [GitHub Issues](https://github.com/bloque/sdk/issues)
1873
710
 
1874
711
  ## License
1875
712
 
1876
- [MIT](../../LICENSE)
1877
-
713
+ MIT © [Bloque](https://www.bloque.app)