@bloque/sdk 0.0.21 → 0.0.23
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 +672 -18
- package/dist/bloque.d.ts +7 -4
- package/dist/index.cjs +1 -1
- package/dist/index.js +1 -1
- package/package.json +6 -6
package/README.md
CHANGED
|
@@ -30,11 +30,15 @@ This SDK is compatible with multiple JavaScript runtimes:
|
|
|
30
30
|
|
|
31
31
|
- **TypeScript First**: Built with TypeScript for complete type safety
|
|
32
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
|
|
33
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
|
|
34
36
|
- **Fully Async**: Promise-based API for modern JavaScript workflows
|
|
35
37
|
- **Lightweight**: Minimal dependencies for optimal bundle size
|
|
36
38
|
- **Modular**: Import only what you need with tree-shakeable exports
|
|
37
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.
|
|
41
|
+
|
|
38
42
|
## Installation
|
|
39
43
|
|
|
40
44
|
```bash
|
|
@@ -51,6 +55,7 @@ import type { CreateOrgParams } from '@bloque/sdk/orgs';
|
|
|
51
55
|
|
|
52
56
|
// Initialize the SDK with API key (backend only)
|
|
53
57
|
const bloque = new SDK({
|
|
58
|
+
origin: 'your-origin-name', // Required: your origin identifier
|
|
54
59
|
auth: {
|
|
55
60
|
type: 'apiKey',
|
|
56
61
|
apiKey: process.env.BLOQUE_API_KEY!,
|
|
@@ -59,7 +64,22 @@ const bloque = new SDK({
|
|
|
59
64
|
platform: 'node', // optional: 'node' | 'bun' | 'deno'
|
|
60
65
|
});
|
|
61
66
|
|
|
62
|
-
//
|
|
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
|
+
}
|
|
81
|
+
|
|
82
|
+
// Create an organization (direct SDK access, no connect needed)
|
|
63
83
|
async function createOrganization() {
|
|
64
84
|
const params: CreateOrgParams = {
|
|
65
85
|
org_type: 'business',
|
|
@@ -79,20 +99,10 @@ async function createOrganization() {
|
|
|
79
99
|
},
|
|
80
100
|
};
|
|
81
101
|
|
|
82
|
-
const
|
|
102
|
+
const userSession = await bloque.connect('did:bloque:your-origin:user-alias');
|
|
103
|
+
const organization = await userSession.orgs.create(params);
|
|
83
104
|
console.log('Organization created:', organization);
|
|
84
105
|
}
|
|
85
|
-
|
|
86
|
-
// Create a virtual card
|
|
87
|
-
async function createCard() {
|
|
88
|
-
const card = await bloque.accounts.card.create({
|
|
89
|
-
urn: 'did:bloque:user:123e4567',
|
|
90
|
-
name: 'My Virtual Card',
|
|
91
|
-
});
|
|
92
|
-
|
|
93
|
-
console.log('Card created:', card.urn);
|
|
94
|
-
console.log('Last four digits:', card.lastFour);
|
|
95
|
-
}
|
|
96
106
|
```
|
|
97
107
|
|
|
98
108
|
### Frontend (Browser, React Native)
|
|
@@ -175,6 +185,10 @@ const bloque = new SDK({
|
|
|
175
185
|
|
|
176
186
|
### Configuration Options
|
|
177
187
|
|
|
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'`
|
|
191
|
+
|
|
178
192
|
- **`auth`** (object, required): Authentication configuration
|
|
179
193
|
- `type: 'apiKey'`: For backend platforms
|
|
180
194
|
- `apiKey` (string, required): Your Bloque API key
|
|
@@ -195,6 +209,42 @@ const bloque = new SDK({
|
|
|
195
209
|
- Browser automatically uses `localStorage` if not provided
|
|
196
210
|
- Must implement: `get()`, `set(token)`, `clear()`
|
|
197
211
|
|
|
212
|
+
### User Sessions with `connect()`
|
|
213
|
+
|
|
214
|
+
Most operations in the SDK require connecting to a user session first. This ensures proper authentication and authorization for user-specific operations.
|
|
215
|
+
|
|
216
|
+
```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!,
|
|
223
|
+
},
|
|
224
|
+
mode: 'production',
|
|
225
|
+
});
|
|
226
|
+
|
|
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',
|
|
234
|
+
});
|
|
235
|
+
```
|
|
236
|
+
|
|
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`
|
|
241
|
+
|
|
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
|
|
247
|
+
|
|
198
248
|
### Platform and Authentication Compatibility
|
|
199
249
|
|
|
200
250
|
| Platform | API Key Auth | JWT Auth | Token Storage |
|
|
@@ -214,7 +264,11 @@ The organizations resource allows you to create and manage organizations in the
|
|
|
214
264
|
#### Create an Organization
|
|
215
265
|
|
|
216
266
|
```typescript
|
|
217
|
-
|
|
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);
|
|
218
272
|
```
|
|
219
273
|
|
|
220
274
|
**Parameters**:
|
|
@@ -278,8 +332,12 @@ The compliance resource provides KYC (Know Your Customer) verification functiona
|
|
|
278
332
|
Start a KYC verification process for a user:
|
|
279
333
|
|
|
280
334
|
```typescript
|
|
281
|
-
|
|
282
|
-
|
|
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',
|
|
283
341
|
});
|
|
284
342
|
```
|
|
285
343
|
|
|
@@ -358,8 +416,12 @@ The accounts resource allows you to create virtual cards for users.
|
|
|
358
416
|
Create a virtual card for a user:
|
|
359
417
|
|
|
360
418
|
```typescript
|
|
361
|
-
|
|
362
|
-
|
|
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',
|
|
363
425
|
name: 'My Virtual Card', // Optional
|
|
364
426
|
});
|
|
365
427
|
```
|
|
@@ -397,9 +459,263 @@ interface CardAccount {
|
|
|
397
459
|
metadata?: Record<string, unknown>; // Custom metadata
|
|
398
460
|
createdAt: string; // Creation timestamp (ISO 8601)
|
|
399
461
|
updatedAt: string; // Last update timestamp (ISO 8601)
|
|
462
|
+
balance?: Record<string, TokenBalance>; // Token balances (only in list responses)
|
|
463
|
+
}
|
|
464
|
+
|
|
465
|
+
interface TokenBalance {
|
|
466
|
+
current: string; // Current balance
|
|
467
|
+
pending: string; // Pending balance
|
|
468
|
+
in: string; // Total incoming
|
|
469
|
+
out: string; // Total outgoing
|
|
470
|
+
}
|
|
471
|
+
```
|
|
472
|
+
|
|
473
|
+
#### List Card Accounts
|
|
474
|
+
|
|
475
|
+
List all card accounts for a holder with their current balances:
|
|
476
|
+
|
|
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();
|
|
481
|
+
|
|
482
|
+
// Or with explicit holder URN
|
|
483
|
+
const cards = await bloque.accounts.card.list({
|
|
484
|
+
holderUrn: 'did:bloque:bloque-whatsapp:573023348486',
|
|
485
|
+
});
|
|
486
|
+
```
|
|
487
|
+
|
|
488
|
+
**Parameters**:
|
|
489
|
+
|
|
490
|
+
```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
|
+
}
|
|
499
|
+
```
|
|
500
|
+
|
|
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.
|
|
504
|
+
|
|
505
|
+
#### Get Card Balance
|
|
506
|
+
|
|
507
|
+
Get the current balance for a specific card account:
|
|
508
|
+
|
|
509
|
+
```typescript
|
|
510
|
+
const balances = await bloque.accounts.card.balance({
|
|
511
|
+
urn: 'did:bloque:account:card:usr-123:crd-456',
|
|
512
|
+
});
|
|
513
|
+
```
|
|
514
|
+
|
|
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
|
+
}
|
|
525
|
+
```
|
|
526
|
+
|
|
527
|
+
**Response**: `Promise<Record<string, TokenBalance>>` - Token balances by asset
|
|
528
|
+
|
|
529
|
+
Returns an object with token balances for each asset:
|
|
530
|
+
|
|
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
|
+
```
|
|
547
|
+
|
|
548
|
+
#### List Card Movements
|
|
549
|
+
|
|
550
|
+
List transactions/movements for a card account with pagination and filtering:
|
|
551
|
+
|
|
552
|
+
```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',
|
|
557
|
+
});
|
|
558
|
+
|
|
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
|
+
});
|
|
567
|
+
```
|
|
568
|
+
|
|
569
|
+
**Parameters**:
|
|
570
|
+
|
|
571
|
+
```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
|
+
```
|
|
619
|
+
|
|
620
|
+
**Response**: `Promise<CardMovement[]>` - Array of card transactions
|
|
621
|
+
|
|
622
|
+
Each movement includes:
|
|
623
|
+
|
|
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
|
+
}
|
|
651
|
+
```
|
|
652
|
+
|
|
653
|
+
#### Transfer Between Accounts
|
|
654
|
+
|
|
655
|
+
Transfer funds between any accounts (card, virtual, bancolombia, etc.):
|
|
656
|
+
|
|
657
|
+
```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**:
|
|
671
|
+
|
|
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
|
+
```
|
|
706
|
+
|
|
707
|
+
**Response**: `Promise<TransferResult>` - Transfer result
|
|
708
|
+
|
|
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
|
|
400
714
|
}
|
|
401
715
|
```
|
|
402
716
|
|
|
717
|
+
The transfer is queued for signing and submission. You can track its progress using the returned `queueId`.
|
|
718
|
+
|
|
403
719
|
### Identity
|
|
404
720
|
|
|
405
721
|
The identity resource allows you to register identities, retrieve user aliases, and manage authentication origins.
|
|
@@ -830,6 +1146,337 @@ try {
|
|
|
830
1146
|
}
|
|
831
1147
|
```
|
|
832
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
|
+
|
|
833
1480
|
### Retrieving User Alias Information
|
|
834
1481
|
|
|
835
1482
|
```typescript
|
|
@@ -1152,7 +1799,14 @@ import type {
|
|
|
1152
1799
|
// Accounts types
|
|
1153
1800
|
import type {
|
|
1154
1801
|
CardAccount,
|
|
1802
|
+
CardMovement,
|
|
1155
1803
|
CreateCardParams,
|
|
1804
|
+
GetBalanceParams,
|
|
1805
|
+
ListCardParams,
|
|
1806
|
+
ListMovementsParams,
|
|
1807
|
+
TokenBalance,
|
|
1808
|
+
TransferParams,
|
|
1809
|
+
TransferResult,
|
|
1156
1810
|
} from '@bloque/sdk/accounts';
|
|
1157
1811
|
|
|
1158
1812
|
// Identity types
|
package/dist/bloque.d.ts
CHANGED
|
@@ -5,9 +5,12 @@ import { IdentityClient } from '@bloque/sdk-identity';
|
|
|
5
5
|
import { OrgsClient } from '@bloque/sdk-orgs';
|
|
6
6
|
export declare class SDK {
|
|
7
7
|
private readonly httpClient;
|
|
8
|
-
readonly accounts: AccountsClient;
|
|
9
|
-
readonly compliance: ComplianceClient;
|
|
10
|
-
readonly identity: IdentityClient;
|
|
11
|
-
readonly orgs: OrgsClient;
|
|
12
8
|
constructor(config: BloqueConfig);
|
|
9
|
+
private extractUserAlias;
|
|
10
|
+
connect(urn: string): Promise<{
|
|
11
|
+
accounts: AccountsClient;
|
|
12
|
+
compliance: ComplianceClient;
|
|
13
|
+
identity: IdentityClient;
|
|
14
|
+
orgs: OrgsClient;
|
|
15
|
+
}>;
|
|
13
16
|
}
|
package/dist/index.cjs
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";const __rslib_import_meta_url__="u"<typeof document?new(require("url".replace("",""))).URL("file:"+__filename).href:document.currentScript&&document.currentScript.src||new URL("main.js",document.baseURI).href;var __webpack_require__={};__webpack_require__.d=(e,
|
|
1
|
+
"use strict";const __rslib_import_meta_url__="u"<typeof document?new(require("url".replace("",""))).URL("file:"+__filename).href:document.currentScript&&document.currentScript.src||new URL("main.js",document.baseURI).href;var __webpack_require__={};__webpack_require__.d=(e,t)=>{for(var _ in t)__webpack_require__.o(t,_)&&!__webpack_require__.o(e,_)&&Object.defineProperty(e,_,{enumerable:!0,get:t[_]})},__webpack_require__.o=(e,t)=>Object.prototype.hasOwnProperty.call(e,t),__webpack_require__.r=e=>{"u">typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})};var __webpack_exports__={};__webpack_require__.r(__webpack_exports__),__webpack_require__.d(__webpack_exports__,{SDK:()=>SDK});const sdk_accounts_namespaceObject=require("@bloque/sdk-accounts"),sdk_compliance_namespaceObject=require("@bloque/sdk-compliance"),sdk_core_namespaceObject=require("@bloque/sdk-core"),sdk_identity_namespaceObject=require("@bloque/sdk-identity"),sdk_orgs_namespaceObject=require("@bloque/sdk-orgs");class SDK{httpClient;constructor(e){this.httpClient=new sdk_core_namespaceObject.HttpClient(e)}extractUserAlias(e){let t=e.match(/^did:bloque:[^:]+:([^:]+)$/);if(!t)throw Error(`Invalid user alias URN: ${e}`);return t[1]}async connect(e){let t=this.httpClient.config;t.urn=e;let _=await this.httpClient.request({path:`/api/origins/${t.origin}/connect`,method:"POST",body:{assertion_result:{challengeType:"API_KEY",value:{api_key:"apiKey"===t.auth.type?t.auth.apiKey:"",alias:this.extractUserAlias(e)}},extra_context:{}}});return t.accessToken=_.result.access_token,{accounts:new sdk_accounts_namespaceObject.AccountsClient(this.httpClient),compliance:new sdk_compliance_namespaceObject.ComplianceClient(this.httpClient),identity:new sdk_identity_namespaceObject.IdentityClient(this.httpClient),orgs:new sdk_orgs_namespaceObject.OrgsClient(this.httpClient)}}}for(var __rspack_i in exports.SDK=__webpack_exports__.SDK,__webpack_exports__)-1===["SDK"].indexOf(__rspack_i)&&(exports[__rspack_i]=__webpack_exports__[__rspack_i]);Object.defineProperty(exports,"__esModule",{value:!0});
|
package/dist/index.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{AccountsClient as t}from"@bloque/sdk-accounts";import{ComplianceClient as
|
|
1
|
+
import{AccountsClient as t}from"@bloque/sdk-accounts";import{ComplianceClient as e}from"@bloque/sdk-compliance";import{HttpClient as i}from"@bloque/sdk-core";import{IdentityClient as o}from"@bloque/sdk-identity";import{OrgsClient as s}from"@bloque/sdk-orgs";class n{httpClient;constructor(t){this.httpClient=new i(t)}extractUserAlias(t){let e=t.match(/^did:bloque:[^:]+:([^:]+)$/);if(!e)throw Error(`Invalid user alias URN: ${t}`);return e[1]}async connect(i){let n=this.httpClient.config;n.urn=i;let r=await this.httpClient.request({path:`/api/origins/${n.origin}/connect`,method:"POST",body:{assertion_result:{challengeType:"API_KEY",value:{api_key:"apiKey"===n.auth.type?n.auth.apiKey:"",alias:this.extractUserAlias(i)}},extra_context:{}}});return n.accessToken=r.result.access_token,{accounts:new t(this.httpClient),compliance:new e(this.httpClient),identity:new o(this.httpClient),orgs:new s(this.httpClient)}}}export{n as SDK};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@bloque/sdk",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.23",
|
|
4
4
|
"description": "Official Bloque SDK",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"keywords": [
|
|
@@ -63,10 +63,10 @@
|
|
|
63
63
|
"node": ">=22"
|
|
64
64
|
},
|
|
65
65
|
"dependencies": {
|
|
66
|
-
"@bloque/sdk-accounts": "0.0.
|
|
67
|
-
"@bloque/sdk-compliance": "0.0.
|
|
68
|
-
"@bloque/sdk-core": "0.0.
|
|
69
|
-
"@bloque/sdk-identity": "0.0.
|
|
70
|
-
"@bloque/sdk-orgs": "0.0.
|
|
66
|
+
"@bloque/sdk-accounts": "0.0.23",
|
|
67
|
+
"@bloque/sdk-compliance": "0.0.23",
|
|
68
|
+
"@bloque/sdk-core": "0.0.23",
|
|
69
|
+
"@bloque/sdk-identity": "0.0.23",
|
|
70
|
+
"@bloque/sdk-orgs": "0.0.23"
|
|
71
71
|
}
|
|
72
72
|
}
|