@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 +436 -1038
- package/dist/bloque.d.ts +14 -5
- package/dist/config.d.ts +3 -3
- package/dist/index.cjs +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +1 -1
- package/dist/init.d.ts +2 -2
- package/package.json +6 -6
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
|
|
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
|
-
- **
|
|
33
|
-
- **
|
|
34
|
-
- **
|
|
35
|
-
- **
|
|
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
|
-
- **
|
|
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',
|
|
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
|
|
67
|
-
|
|
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
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
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
|
-
|
|
102
|
-
|
|
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
|
-
//
|
|
118
|
-
//
|
|
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:
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
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
|
-
//
|
|
227
|
-
const
|
|
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
|
-
//
|
|
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
|
-
|
|
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
|
-
|
|
146
|
+
### Full Configuration Options
|
|
264
147
|
|
|
265
148
|
```typescript
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
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
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
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
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
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
|
-
|
|
298
|
-
|
|
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
|
-
|
|
170
|
+
// Modes
|
|
171
|
+
type Mode = 'production' | 'sandbox';
|
|
308
172
|
|
|
309
|
-
|
|
310
|
-
interface
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
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
|
-
|
|
326
|
-
|
|
327
|
-
The compliance resource provides KYC (Know Your Customer) verification functionality.
|
|
182
|
+
## SDK Structure
|
|
328
183
|
|
|
329
|
-
|
|
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
|
-
|
|
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
|
-
//
|
|
338
|
-
|
|
339
|
-
|
|
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
|
-
|
|
196
|
+
## Accounts Client
|
|
344
197
|
|
|
345
|
-
|
|
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
|
-
|
|
200
|
+
### Virtual Cards
|
|
367
201
|
|
|
368
202
|
```typescript
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
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
|
-
|
|
209
|
+
// List cards
|
|
210
|
+
const cards = await session.accounts.card.list();
|
|
376
211
|
|
|
377
|
-
|
|
212
|
+
// Check balance
|
|
213
|
+
const balance = await session.accounts.card.balance({
|
|
214
|
+
urn: card.urn,
|
|
215
|
+
});
|
|
378
216
|
|
|
379
|
-
|
|
380
|
-
const
|
|
381
|
-
urn:
|
|
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
|
-
|
|
225
|
+
// Update card
|
|
226
|
+
const updated = await session.accounts.card.updateMetadata({
|
|
227
|
+
urn: card.urn,
|
|
228
|
+
metadata: { name: 'Updated Name' },
|
|
229
|
+
});
|
|
386
230
|
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
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
|
-
|
|
237
|
+
### Virtual Accounts
|
|
238
|
+
|
|
239
|
+
Virtual accounts are simple testing accounts requiring only basic personal information:
|
|
400
240
|
|
|
401
241
|
```typescript
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
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
|
-
|
|
252
|
+
// Update metadata
|
|
253
|
+
await session.accounts.virtual.updateMetadata({
|
|
254
|
+
urn: account.urn,
|
|
255
|
+
metadata: { updated_by: 'admin' },
|
|
256
|
+
});
|
|
410
257
|
|
|
411
|
-
|
|
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
|
-
|
|
264
|
+
### Bancolombia Accounts
|
|
414
265
|
|
|
415
|
-
|
|
266
|
+
Colombian virtual accounts with unique reference code system:
|
|
416
267
|
|
|
417
268
|
```typescript
|
|
418
|
-
//
|
|
419
|
-
const
|
|
420
|
-
|
|
421
|
-
|
|
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
|
-
|
|
275
|
+
console.log('Reference code:', account.referenceCode);
|
|
429
276
|
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
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
|
-
|
|
283
|
+
await session.accounts.bancolombia.updateName(account.urn, 'Savings Account');
|
|
446
284
|
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
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
|
-
###
|
|
465
|
-
|
|
466
|
-
The identity resource allows you to register identities, retrieve user aliases, and manage authentication origins.
|
|
291
|
+
### Transfers
|
|
467
292
|
|
|
468
|
-
|
|
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
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
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
|
-
|
|
492
|
-
|
|
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
|
-
|
|
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
|
-
|
|
531
|
-
assertionResult: AssertionResult;
|
|
532
|
-
extraContext?: Record<string, unknown>;
|
|
533
|
-
type: 'business';
|
|
534
|
-
profile: BusinessProfile;
|
|
535
|
-
}
|
|
312
|
+
Manage user identities and authentication:
|
|
536
313
|
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
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
|
-
//
|
|
553
|
-
|
|
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
|
-
//
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
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
|
-
|
|
608
|
-
|
|
609
|
-
|
|
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
|
-
|
|
371
|
+
## Compliance Client
|
|
614
372
|
|
|
615
|
-
|
|
373
|
+
KYC/KYB verification workflows:
|
|
616
374
|
|
|
617
375
|
```typescript
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
|
|
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
|
-
|
|
624
|
-
|
|
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
|
-
|
|
385
|
+
// Get verification status
|
|
386
|
+
const status = await session.compliance.kyc.getVerification({
|
|
387
|
+
urn: 'did:bloque:user:123e4567',
|
|
388
|
+
});
|
|
629
389
|
|
|
630
|
-
|
|
631
|
-
|
|
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
|
-
##
|
|
394
|
+
## Organizations Client
|
|
653
395
|
|
|
654
|
-
|
|
396
|
+
Create and manage organizations:
|
|
655
397
|
|
|
656
398
|
```typescript
|
|
657
|
-
|
|
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: '
|
|
675
|
-
incorporation_date: '2020-01-
|
|
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
|
|
680
|
-
address_line2: 'Suite
|
|
681
|
-
postal_code: '
|
|
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
|
-
|
|
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
|
-
|
|
715
|
-
|
|
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
|
-
|
|
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
|
-
|
|
424
|
+
The SDK provides specific error types for better error handling:
|
|
784
425
|
|
|
785
426
|
```typescript
|
|
786
|
-
import {
|
|
787
|
-
|
|
788
|
-
|
|
789
|
-
|
|
790
|
-
|
|
791
|
-
|
|
792
|
-
|
|
793
|
-
|
|
794
|
-
|
|
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
|
|
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
|
-
|
|
813
|
-
}
|
|
814
|
-
|
|
815
|
-
|
|
816
|
-
|
|
817
|
-
|
|
818
|
-
|
|
819
|
-
|
|
820
|
-
|
|
821
|
-
|
|
822
|
-
|
|
823
|
-
|
|
824
|
-
|
|
825
|
-
|
|
826
|
-
}
|
|
827
|
-
|
|
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
|
-
|
|
850
|
-
|
|
457
|
+
|
|
458
|
+
// All errors have these fields
|
|
459
|
+
console.log('Error details:', error.toJSON());
|
|
851
460
|
}
|
|
852
461
|
```
|
|
853
462
|
|
|
854
|
-
###
|
|
463
|
+
### Error Metadata
|
|
855
464
|
|
|
856
|
-
|
|
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
|
-
|
|
861
|
-
|
|
862
|
-
|
|
863
|
-
|
|
864
|
-
|
|
865
|
-
|
|
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
|
-
|
|
869
|
-
const params: CreateCardParams = {
|
|
870
|
-
urn: 'did:bloque:user:123e4567',
|
|
871
|
-
name: 'My Business Card', // Optional
|
|
872
|
-
};
|
|
475
|
+
## Retry Logic
|
|
873
476
|
|
|
874
|
-
|
|
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
|
-
|
|
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
|
-
|
|
901
|
-
|
|
902
|
-
|
|
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
|
-
|
|
497
|
+
## Timeout Configuration
|
|
937
498
|
|
|
938
|
-
|
|
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
|
-
|
|
944
|
-
|
|
945
|
-
|
|
946
|
-
},
|
|
947
|
-
mode: 'production',
|
|
504
|
+
origin: 'your-origin',
|
|
505
|
+
auth: { type: 'apiKey', apiKey: 'key' },
|
|
506
|
+
timeout: 15000, // 15 seconds
|
|
948
507
|
});
|
|
949
508
|
|
|
950
|
-
//
|
|
951
|
-
const
|
|
952
|
-
|
|
953
|
-
|
|
954
|
-
|
|
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
|
-
|
|
516
|
+
## Security Best Practices
|
|
996
517
|
|
|
997
|
-
|
|
998
|
-
import { SDK } from '@bloque/sdk';
|
|
999
|
-
import type { BusinessRegisterParams } from '@bloque/sdk/identity';
|
|
518
|
+
### API Keys
|
|
1000
519
|
|
|
1001
|
-
|
|
1002
|
-
|
|
1003
|
-
|
|
1004
|
-
|
|
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
|
-
|
|
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
|
-
|
|
528
|
+
The SDK warns when using insecure storage:
|
|
1065
529
|
|
|
1066
530
|
```typescript
|
|
1067
|
-
|
|
1068
|
-
import type { CreateOrgParams } from '@bloque/sdk/orgs';
|
|
1069
|
-
|
|
531
|
+
// Browser: localStorage (⚠️ vulnerable to XSS)
|
|
1070
532
|
const bloque = new SDK({
|
|
1071
|
-
auth: {
|
|
1072
|
-
|
|
1073
|
-
|
|
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
|
-
|
|
1079
|
-
|
|
1080
|
-
|
|
1081
|
-
|
|
1082
|
-
|
|
1083
|
-
|
|
1084
|
-
|
|
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
|
-
|
|
1108
|
-
|
|
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
|
-
|
|
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
|
-
|
|
1143
|
-
|
|
1144
|
-
|
|
1145
|
-
|
|
1146
|
-
|
|
1147
|
-
|
|
1148
|
-
|
|
1149
|
-
} from '@bloque/sdk
|
|
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:
|
|
1153
|
-
|
|
1154
|
-
|
|
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
|
|
1173
|
-
const params:
|
|
1174
|
-
|
|
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
|
-
//
|
|
1183
|
-
const
|
|
586
|
+
// Type-safe responses
|
|
587
|
+
const card: CardAccount = await session.accounts.card.create(params);
|
|
1184
588
|
```
|
|
1185
589
|
|
|
1186
|
-
|
|
590
|
+
## Package Exports
|
|
1187
591
|
|
|
1188
|
-
The SDK
|
|
592
|
+
The SDK supports modular imports:
|
|
1189
593
|
|
|
1190
594
|
```typescript
|
|
1191
|
-
// Main SDK
|
|
1192
|
-
import
|
|
595
|
+
// Main SDK
|
|
596
|
+
import { SDK } from '@bloque/sdk';
|
|
1193
597
|
|
|
1194
|
-
//
|
|
1195
|
-
import
|
|
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
|
-
//
|
|
1214
|
-
import
|
|
1215
|
-
|
|
1216
|
-
|
|
1217
|
-
} from '@bloque/sdk/
|
|
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
|
-
//
|
|
607
|
+
// Types
|
|
1220
608
|
import type {
|
|
1221
|
-
|
|
1222
|
-
|
|
1223
|
-
|
|
1224
|
-
|
|
1225
|
-
|
|
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
|
-
##
|
|
616
|
+
## Advanced Usage
|
|
1233
617
|
|
|
1234
|
-
###
|
|
618
|
+
### Custom HTTP Client
|
|
1235
619
|
|
|
1236
|
-
|
|
1237
|
-
bun install
|
|
1238
|
-
bun run build
|
|
1239
|
-
```
|
|
620
|
+
For advanced use cases, access the HTTP client directly:
|
|
1240
621
|
|
|
1241
|
-
|
|
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
|
-
|
|
625
|
+
// Access the HTTP client
|
|
626
|
+
const httpClient = session.accounts.card['httpClient'];
|
|
1248
627
|
|
|
1249
|
-
|
|
1250
|
-
|
|
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
|
-
###
|
|
636
|
+
### Environment-Specific Configuration
|
|
1254
637
|
|
|
1255
|
-
```
|
|
1256
|
-
|
|
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
|
-
##
|
|
657
|
+
## Examples
|
|
1260
658
|
|
|
1261
|
-
|
|
1262
|
-
- TypeScript 5.x or higher (for TypeScript projects, optional)
|
|
659
|
+
See the [`examples/`](./examples) directory for complete working examples:
|
|
1263
660
|
|
|
1264
|
-
|
|
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
|
-
|
|
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
|
-
|
|
671
|
+
For detailed API documentation, visit [docs.bloque.app/sdk](https://docs.bloque.app/sdk).
|
|
1271
672
|
|
|
1272
|
-
|
|
673
|
+
## Support
|
|
1273
674
|
|
|
1274
|
-
-
|
|
1275
|
-
-
|
|
1276
|
-
-
|
|
1277
|
-
-
|
|
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
|
-
[
|
|
1284
|
-
|
|
682
|
+
MIT © [Bloque](https://www.bloque.app)
|