@private.me/xbind 1.3.0 → 2.3.4
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/LICENSES.md +212 -0
- package/README.md +388 -6
- package/dist-standalone/_deps/mldsa-wasm/dist/mldsa.js +1 -1920
- package/dist-standalone/_deps/shared/cjs/errors.js +1 -275
- package/dist-standalone/_deps/shared/cjs/index.js +1 -138
- package/dist-standalone/_deps/shared/cjs/types.js +1 -90
- package/dist-standalone/_deps/shared/errors.js +1 -262
- package/dist-standalone/_deps/shared/index.js +1 -77
- package/dist-standalone/_deps/shared/types.js +1 -91
- package/dist-standalone/_deps/ux-helpers/cjs/errors.js +1 -1
- package/dist-standalone/_deps/ux-helpers/cjs/index.js +1 -1
- package/dist-standalone/_deps/ux-helpers/cjs/pagination.js +1 -1
- package/dist-standalone/_deps/ux-helpers/cjs/progress.js +1 -1
- package/dist-standalone/_deps/ux-helpers/cjs/search.js +1 -1
- package/dist-standalone/_deps/ux-helpers/cjs/types.js +1 -1
- package/dist-standalone/_deps/ux-helpers/errors.js +1 -1
- package/dist-standalone/_deps/ux-helpers/index.js +1 -1
- package/dist-standalone/_deps/ux-helpers/pagination.js +1 -1
- package/dist-standalone/_deps/ux-helpers/progress.js +1 -1
- package/dist-standalone/_deps/ux-helpers/search.js +1 -1
- package/dist-standalone/_deps/xchange/auto-accept.js +1 -1
- package/dist-standalone/_deps/xchange/cjs/auto-accept.js +1 -1
- package/dist-standalone/_deps/xchange/cjs/errors.js +1 -1
- package/dist-standalone/_deps/xchange/cjs/index.js +1 -1
- package/dist-standalone/_deps/xchange/cjs/invite-client.js +1 -1
- package/dist-standalone/_deps/xchange/cjs/lazy-init.js +1 -1
- package/dist-standalone/_deps/xchange/cjs/trust-integration.js +1 -1
- package/dist-standalone/_deps/xchange/cjs/xchange.js +1 -1
- package/dist-standalone/_deps/xchange/errors.js +1 -1
- package/dist-standalone/_deps/xchange/index.js +1 -1
- package/dist-standalone/_deps/xchange/invite-client.js +1 -1
- package/dist-standalone/_deps/xchange/lazy-init.js +1 -1
- package/dist-standalone/_deps/xchange/trust-integration.js +1 -1
- package/dist-standalone/_deps/xchange/xchange.js +1 -1
- package/dist-standalone/_deps/xregistry/cjs/discovery.js +1 -1
- package/dist-standalone/_deps/xregistry/cjs/errors.js +1 -1
- package/dist-standalone/_deps/xregistry/cjs/index.js +1 -1
- package/dist-standalone/_deps/xregistry/cjs/registry.js +1 -1
- package/dist-standalone/_deps/xregistry/cjs/schema.js +1 -1
- package/dist-standalone/_deps/xregistry/cjs/types.js +1 -1
- package/dist-standalone/_deps/xregistry/discovery.js +1 -1
- package/dist-standalone/_deps/xregistry/errors.js +1 -1
- package/dist-standalone/_deps/xregistry/index.js +1 -1
- package/dist-standalone/_deps/xregistry/registry.js +1 -1
- package/dist-standalone/_deps/xregistry/schema.js +1 -1
- package/dist-standalone/_deps/xregistry/types.js +1 -1
- package/dist-standalone/agent-call.js +1 -642
- package/dist-standalone/agent-sdk.js +1 -328
- package/dist-standalone/agent.d.ts +95 -5
- package/dist-standalone/agent.js +1 -1545
- package/dist-standalone/approval.js +1 -193
- package/dist-standalone/async-iterators.d.ts +275 -0
- package/dist-standalone/async-iterators.js +1 -0
- package/dist-standalone/auth.js +1 -219
- package/dist-standalone/auto-accept.js +1 -229
- package/dist-standalone/backup-config.js +1 -201
- package/dist-standalone/backup.d.ts +114 -0
- package/dist-standalone/backup.js +1 -0
- package/dist-standalone/batch-operations.d.ts +297 -0
- package/dist-standalone/batch-operations.js +1 -0
- package/dist-standalone/cancellation.d.ts +301 -0
- package/dist-standalone/cancellation.js +1 -0
- package/dist-standalone/checkpoint.js +1 -186
- package/dist-standalone/circuit-breaker.d.ts +351 -0
- package/dist-standalone/circuit-breaker.js +1 -0
- package/dist-standalone/cjs/agent-call.js +1 -651
- package/dist-standalone/cjs/agent-sdk.js +1 -332
- package/dist-standalone/cjs/agent.js +1 -1582
- package/dist-standalone/cjs/approval.js +1 -199
- package/dist-standalone/cjs/async-iterators.js +1 -0
- package/dist-standalone/cjs/auth.js +1 -225
- package/dist-standalone/cjs/auto-accept.js +1 -233
- package/dist-standalone/cjs/backup-config.js +1 -207
- package/dist-standalone/cjs/backup.js +1 -0
- package/dist-standalone/cjs/batch-operations.js +1 -0
- package/dist-standalone/cjs/cancellation.js +1 -0
- package/dist-standalone/cjs/checkpoint.js +1 -193
- package/dist-standalone/cjs/circuit-breaker.js +1 -0
- package/dist-standalone/cjs/cli/init.js +1 -486
- package/dist-standalone/cjs/config-validation.js +1 -0
- package/dist-standalone/cjs/connect.js +1 -312
- package/dist-standalone/cjs/connection-pool.js +1 -0
- package/dist-standalone/cjs/correlation-id.js +1 -339
- package/dist-standalone/cjs/crypto-utils.js +1 -0
- package/dist-standalone/cjs/debug-mode.js +1 -0
- package/dist-standalone/cjs/did-document.js +1 -101
- package/dist-standalone/cjs/did-privateme.js +1 -130
- package/dist-standalone/cjs/did-web.js +1 -201
- package/dist-standalone/cjs/discovery.js +1 -462
- package/dist-standalone/cjs/dual-mode.js +1 -251
- package/dist-standalone/cjs/email-templates.js +1 -313
- package/dist-standalone/cjs/email-transport.js +1 -239
- package/dist-standalone/cjs/envelope.js +1 -510
- package/dist-standalone/cjs/errors.js +1 -826
- package/dist-standalone/cjs/event-emitter.js +1 -0
- package/dist-standalone/cjs/gateway-state.js +1 -55
- package/dist-standalone/cjs/gateway-transport.js +1 -120
- package/dist-standalone/cjs/graceful-degradation.js +1 -0
- package/dist-standalone/cjs/guardrails.js +1 -223
- package/dist-standalone/cjs/health-check.js +1 -0
- package/dist-standalone/cjs/http-compat.js +1 -272
- package/dist-standalone/cjs/http-status-map.js +1 -571
- package/dist-standalone/cjs/identity.js +1 -541
- package/dist-standalone/cjs/index.js +1 -237
- package/dist-standalone/cjs/invitation.js +1 -421
- package/dist-standalone/cjs/invite.js +1 -328
- package/dist-standalone/cjs/key-agreement.js +1 -246
- package/dist-standalone/cjs/lazy-init.js +1 -300
- package/dist-standalone/cjs/logger.js +1 -0
- package/dist-standalone/cjs/mdns-discovery.js +1 -202
- package/dist-standalone/cjs/nonce-store.js +1 -66
- package/dist-standalone/cjs/pairing-manager.js +1 -223
- package/dist-standalone/cjs/plugin-system.js +1 -0
- package/dist-standalone/cjs/plugins/logging.js +1 -0
- package/dist-standalone/cjs/plugins/metrics.js +1 -0
- package/dist-standalone/cjs/plugins/validation.js +1 -0
- package/dist-standalone/cjs/policy.js +1 -320
- package/dist-standalone/cjs/progress-callbacks.js +1 -0
- package/dist-standalone/cjs/redis-nonce-store.js +1 -76
- package/dist-standalone/cjs/registry-middleware.js +1 -50
- package/dist-standalone/cjs/retry-strategies.js +1 -0
- package/dist-standalone/cjs/retry-transport.js +1 -102
- package/dist-standalone/cjs/runtime/browser.js +1 -0
- package/dist-standalone/cjs/runtime/edge.js +1 -0
- package/dist-standalone/cjs/runtime/react-native.js +1 -0
- package/dist-standalone/cjs/security-policy.js +1 -245
- package/dist-standalone/cjs/serialization.js +1 -0
- package/dist-standalone/cjs/split-channel.js +1 -177
- package/dist-standalone/cjs/subscription-proof.js +1 -230
- package/dist-standalone/cjs/succession.js +1 -148
- package/dist-standalone/cjs/timeouts.js +1 -0
- package/dist-standalone/cjs/trace-context.js +1 -0
- package/dist-standalone/cjs/trace-spans.js +1 -0
- package/dist-standalone/cjs/transport.js +1 -63
- package/dist-standalone/cjs/trust-registry.js +1 -742
- package/dist-standalone/cjs/types/error-response.js +1 -56
- package/dist-standalone/cjs/vault-auth.js +1 -0
- package/dist-standalone/cjs/vault-store-loader.js +1 -0
- package/dist-standalone/cjs/verify.js +1 -25
- package/dist-standalone/cjs/version-info.js +1 -0
- package/dist-standalone/cjs/xfetch.js +1 -252
- package/dist-standalone/cli/init.js +1 -449
- package/dist-standalone/cli/setup.js +1 -514
- package/dist-standalone/cli/types.js +1 -27
- package/dist-standalone/cli/xbind.js +1 -148
- package/dist-standalone/config-validation.d.ts +185 -0
- package/dist-standalone/config-validation.js +1 -0
- package/dist-standalone/connect.js +1 -274
- package/dist-standalone/connection-pool.d.ts +251 -0
- package/dist-standalone/connection-pool.js +1 -0
- package/dist-standalone/correlation-id.js +1 -326
- package/dist-standalone/crypto-utils.d.ts +60 -0
- package/dist-standalone/crypto-utils.js +1 -0
- package/dist-standalone/debug-mode.d.ts +286 -0
- package/dist-standalone/debug-mode.js +1 -0
- package/dist-standalone/did-document.js +1 -96
- package/dist-standalone/did-privateme.js +1 -121
- package/dist-standalone/did-web.js +1 -196
- package/dist-standalone/discovery.js +1 -458
- package/dist-standalone/dual-mode.js +1 -247
- package/dist-standalone/email-templates.js +1 -309
- package/dist-standalone/email-transport.js +1 -232
- package/dist-standalone/envelope.d.ts +29 -1
- package/dist-standalone/envelope.js +1 -497
- package/dist-standalone/errors.d.ts +10 -0
- package/dist-standalone/errors.js +1 -811
- package/dist-standalone/event-emitter.d.ts +395 -0
- package/dist-standalone/event-emitter.js +1 -0
- package/dist-standalone/gateway-state.js +1 -51
- package/dist-standalone/gateway-transport.js +1 -116
- package/dist-standalone/graceful-degradation.d.ts +246 -0
- package/dist-standalone/graceful-degradation.js +1 -0
- package/dist-standalone/guardrails.js +1 -216
- package/dist-standalone/health-check.d.ts +150 -0
- package/dist-standalone/health-check.js +1 -0
- package/dist-standalone/http-compat.js +1 -267
- package/dist-standalone/http-status-map.js +1 -561
- package/dist-standalone/identity.d.ts +64 -1
- package/dist-standalone/identity.js +1 -516
- package/dist-standalone/index.d.ts +45 -3
- package/dist-standalone/index.js +1 -52
- package/dist-standalone/invitation.js +1 -415
- package/dist-standalone/invite.js +1 -324
- package/dist-standalone/key-agreement.d.ts +61 -13
- package/dist-standalone/key-agreement.js +1 -236
- package/dist-standalone/lazy-init.js +1 -295
- package/dist-standalone/logger.d.ts +77 -0
- package/dist-standalone/logger.js +1 -0
- package/dist-standalone/mdns-discovery.js +1 -195
- package/dist-standalone/nonce-store.d.ts +16 -3
- package/dist-standalone/nonce-store.js +1 -62
- package/dist-standalone/package.json +0 -1
- package/dist-standalone/pairing-manager.js +1 -219
- package/dist-standalone/plugin-system.d.ts +145 -0
- package/dist-standalone/plugin-system.js +1 -0
- package/dist-standalone/policy.js +1 -315
- package/dist-standalone/progress-callbacks.d.ts +394 -0
- package/dist-standalone/progress-callbacks.js +1 -0
- package/dist-standalone/redis-nonce-store.js +1 -72
- package/dist-standalone/registry-middleware.js +1 -47
- package/dist-standalone/retry-strategies.d.ts +382 -0
- package/dist-standalone/retry-strategies.js +1 -0
- package/dist-standalone/retry-transport.js +1 -98
- package/dist-standalone/security-policy.js +1 -239
- package/dist-standalone/serialization.d.ts +244 -0
- package/dist-standalone/serialization.js +1 -0
- package/dist-standalone/split-channel.d.ts +49 -1
- package/dist-standalone/split-channel.js +1 -171
- package/dist-standalone/subscription-proof.js +1 -224
- package/dist-standalone/succession.js +1 -142
- package/dist-standalone/timeouts.d.ts +275 -0
- package/dist-standalone/timeouts.js +1 -0
- package/dist-standalone/trace-context.d.ts +252 -0
- package/dist-standalone/trace-context.js +1 -0
- package/dist-standalone/trace-spans.d.ts +360 -0
- package/dist-standalone/trace-spans.js +1 -0
- package/dist-standalone/transport.js +1 -59
- package/dist-standalone/trust-registry.d.ts +106 -5
- package/dist-standalone/trust-registry.js +1 -702
- package/dist-standalone/vault-auth.d.ts +91 -0
- package/dist-standalone/vault-auth.js +1 -0
- package/dist-standalone/vault-store-loader.d.ts +110 -0
- package/dist-standalone/vault-store-loader.js +1 -0
- package/dist-standalone/verify.js +1 -16
- package/dist-standalone/version-info.d.ts +259 -0
- package/dist-standalone/version-info.js +1 -0
- package/dist-standalone/xfetch.js +1 -247
- package/llms.txt +1 -0
- package/package.json +66 -5
- package/share1.dat +0 -0
- package/dist-standalone/_deps/crypto/base64.d.ts +0 -29
- package/dist-standalone/_deps/crypto/base64.js +0 -209
- package/dist-standalone/_deps/crypto/cjs/base64.js +0 -103
- package/dist-standalone/_deps/crypto/cjs/errors.js +0 -119
- package/dist-standalone/_deps/crypto/cjs/hmac.js +0 -71
- package/dist-standalone/_deps/crypto/cjs/index.js +0 -86
- package/dist-standalone/_deps/crypto/cjs/padding.js +0 -57
- package/dist-standalone/_deps/crypto/cjs/share-header.js +0 -68
- package/dist-standalone/_deps/crypto/cjs/shares.js +0 -152
- package/dist-standalone/_deps/crypto/cjs/tlv.js +0 -199
- package/dist-standalone/_deps/crypto/cjs/uuid.js +0 -61
- package/dist-standalone/_deps/crypto/cjs/verify.js +0 -24
- package/dist-standalone/_deps/crypto/cjs/xorida.js +0 -221
- package/dist-standalone/_deps/crypto/errors.d.ts +0 -51
- package/dist-standalone/_deps/crypto/errors.js +0 -109
- package/dist-standalone/_deps/crypto/hmac.d.ts +0 -39
- package/dist-standalone/_deps/crypto/hmac.js +0 -66
- package/dist-standalone/_deps/crypto/index.d.ts +0 -20
- package/dist-standalone/_deps/crypto/index.js +0 -45
- package/dist-standalone/_deps/crypto/padding.d.ts +0 -19
- package/dist-standalone/_deps/crypto/padding.js +0 -53
- package/dist-standalone/_deps/crypto/share-header.d.ts +0 -44
- package/dist-standalone/_deps/crypto/share-header.js +0 -63
- package/dist-standalone/_deps/crypto/shares.d.ts +0 -27
- package/dist-standalone/_deps/crypto/shares.js +0 -148
- package/dist-standalone/_deps/crypto/tlv.d.ts +0 -26
- package/dist-standalone/_deps/crypto/tlv.js +0 -195
- package/dist-standalone/_deps/crypto/uuid.d.ts +0 -22
- package/dist-standalone/_deps/crypto/uuid.js +0 -56
- package/dist-standalone/_deps/crypto/verify.d.ts +0 -15
- package/dist-standalone/_deps/crypto/verify.js +0 -15
- package/dist-standalone/_deps/crypto/xorida.d.ts +0 -44
- package/dist-standalone/_deps/crypto/xorida.js +0 -215
- package/dist-standalone/_deps/shared/errors.d.ts.map +0 -1
- package/dist-standalone/_deps/shared/errors.js.map +0 -1
- package/dist-standalone/_deps/shared/index.d.ts.map +0 -1
- package/dist-standalone/_deps/shared/index.js.map +0 -1
- package/dist-standalone/_deps/shared/types.d.ts.map +0 -1
- package/dist-standalone/_deps/shared/types.js.map +0 -1
- package/dist-standalone/_deps/ux-helpers/cjs/errors.d.ts.map +0 -1
- package/dist-standalone/_deps/ux-helpers/cjs/errors.js.map +0 -1
- package/dist-standalone/_deps/ux-helpers/cjs/index.d.ts.map +0 -1
- package/dist-standalone/_deps/ux-helpers/cjs/index.js.map +0 -1
- package/dist-standalone/_deps/ux-helpers/cjs/pagination.d.ts.map +0 -1
- package/dist-standalone/_deps/ux-helpers/cjs/pagination.js.map +0 -1
- package/dist-standalone/_deps/ux-helpers/cjs/progress.d.ts.map +0 -1
- package/dist-standalone/_deps/ux-helpers/cjs/progress.js.map +0 -1
- package/dist-standalone/_deps/ux-helpers/cjs/search.d.ts.map +0 -1
- package/dist-standalone/_deps/ux-helpers/cjs/search.js.map +0 -1
- package/dist-standalone/_deps/ux-helpers/cjs/types.d.ts.map +0 -1
- package/dist-standalone/_deps/ux-helpers/cjs/types.js.map +0 -1
- package/dist-standalone/_deps/ux-helpers/errors.d.ts.map +0 -1
- package/dist-standalone/_deps/ux-helpers/errors.js.map +0 -1
- package/dist-standalone/_deps/ux-helpers/index.d.ts.map +0 -1
- package/dist-standalone/_deps/ux-helpers/index.js.map +0 -1
- package/dist-standalone/_deps/ux-helpers/pagination.d.ts.map +0 -1
- package/dist-standalone/_deps/ux-helpers/pagination.js.map +0 -1
- package/dist-standalone/_deps/ux-helpers/progress.d.ts.map +0 -1
- package/dist-standalone/_deps/ux-helpers/progress.js.map +0 -1
- package/dist-standalone/_deps/ux-helpers/search.d.ts.map +0 -1
- package/dist-standalone/_deps/ux-helpers/search.js.map +0 -1
- package/dist-standalone/_deps/ux-helpers/types.d.ts.map +0 -1
- package/dist-standalone/_deps/ux-helpers/types.js.map +0 -1
- package/dist-standalone/_deps/xregistry/discovery.d.ts.map +0 -1
- package/dist-standalone/_deps/xregistry/discovery.js.map +0 -1
- package/dist-standalone/_deps/xregistry/errors.d.ts.map +0 -1
- package/dist-standalone/_deps/xregistry/errors.js.map +0 -1
- package/dist-standalone/_deps/xregistry/index.d.ts.map +0 -1
- package/dist-standalone/_deps/xregistry/index.js.map +0 -1
- package/dist-standalone/_deps/xregistry/registry.d.ts.map +0 -1
- package/dist-standalone/_deps/xregistry/registry.js.map +0 -1
- package/dist-standalone/_deps/xregistry/schema.d.ts.map +0 -1
- package/dist-standalone/_deps/xregistry/schema.js.map +0 -1
- package/dist-standalone/_deps/xregistry/types.d.ts.map +0 -1
- package/dist-standalone/_deps/xregistry/types.js.map +0 -1
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Encrypted Backup and Restore (RCV-3)
|
|
3
|
+
*
|
|
4
|
+
* Exports and imports encrypted identity and cryptographic state.
|
|
5
|
+
* Uses PBKDF2 (NIST SP 800-132) for key derivation and AES-256-GCM
|
|
6
|
+
* for authenticated encryption.
|
|
7
|
+
*
|
|
8
|
+
* @module backup
|
|
9
|
+
*/
|
|
10
|
+
import type { Result } from '@private.me/shared';
|
|
11
|
+
import type { AgentIdentity } from './identity.js';
|
|
12
|
+
/**
|
|
13
|
+
* Encrypted backup blob containing identity and state.
|
|
14
|
+
*
|
|
15
|
+
* Format:
|
|
16
|
+
* - version: 1 (future compatibility)
|
|
17
|
+
* - salt: 16-byte random salt for PBKDF2
|
|
18
|
+
* - iv: 12-byte random IV for AES-256-GCM
|
|
19
|
+
* - ciphertext: AES-256-GCM encrypted backup data
|
|
20
|
+
* - tag: 16-byte GCM authentication tag
|
|
21
|
+
*/
|
|
22
|
+
export interface EncryptedBackup {
|
|
23
|
+
/**
|
|
24
|
+
* Backup format version for future compatibility.
|
|
25
|
+
*/
|
|
26
|
+
readonly version: 1;
|
|
27
|
+
/**
|
|
28
|
+
* PBKDF2 salt (base64-encoded 16 bytes).
|
|
29
|
+
*/
|
|
30
|
+
readonly salt: string;
|
|
31
|
+
/**
|
|
32
|
+
* AES-256-GCM IV (base64-encoded 12 bytes).
|
|
33
|
+
*/
|
|
34
|
+
readonly iv: string;
|
|
35
|
+
/**
|
|
36
|
+
* AES-256-GCM ciphertext (base64-encoded encrypted backup).
|
|
37
|
+
*/
|
|
38
|
+
readonly ciphertext: string;
|
|
39
|
+
/**
|
|
40
|
+
* AES-256-GCM authentication tag (base64-encoded 16 bytes).
|
|
41
|
+
*/
|
|
42
|
+
readonly tag: string;
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* Error codes for backup/restore operations.
|
|
46
|
+
*/
|
|
47
|
+
export type BackupError = 'INVALID_PASSWORD' | 'EXPORT_FAILED' | 'IMPORT_FAILED' | 'ENCRYPTION_FAILED' | 'DECRYPTION_FAILED' | 'INVALID_BACKUP' | 'PBKDF2_FAILED' | 'CRYPTO_NOT_SUPPORTED';
|
|
48
|
+
/**
|
|
49
|
+
* Export an identity as an encrypted backup blob.
|
|
50
|
+
*
|
|
51
|
+
* Encrypts the complete identity (Ed25519, X25519, ML-KEM, ML-DSA keys,
|
|
52
|
+
* rotated keys) with a password using PBKDF2 + AES-256-GCM.
|
|
53
|
+
*
|
|
54
|
+
* The backup can be stored safely in cloud storage, version control, or
|
|
55
|
+
* transmitted over untrusted channels. Only the password holder can decrypt.
|
|
56
|
+
*
|
|
57
|
+
* Security:
|
|
58
|
+
* - PBKDF2-SHA256 with 310,000 iterations (≈100ms on modern hardware)
|
|
59
|
+
* - AES-256-GCM for authenticated encryption
|
|
60
|
+
* - Random salt + IV for each backup (no two backups are identical)
|
|
61
|
+
* - 16-byte GCM tag prevents tampering
|
|
62
|
+
*
|
|
63
|
+
* @param identity - Agent identity to backup.
|
|
64
|
+
* @param password - User password (plaintext). Will be PBKDF2 derived.
|
|
65
|
+
* @returns Encrypted backup blob or error.
|
|
66
|
+
*
|
|
67
|
+
* @example
|
|
68
|
+
* ```typescript
|
|
69
|
+
* import { generateIdentity } from '@private.me/xbind';
|
|
70
|
+
* import { exportBackup } from '@private.me/xbind';
|
|
71
|
+
*
|
|
72
|
+
* const identity = await generateIdentity();
|
|
73
|
+
* if (!identity.ok) throw identity.error;
|
|
74
|
+
*
|
|
75
|
+
* const backup = await exportBackup(identity.value, 'user-password');
|
|
76
|
+
* if (!backup.ok) throw backup.error;
|
|
77
|
+
*
|
|
78
|
+
* // Store backup securely
|
|
79
|
+
* const json = JSON.stringify(backup.value);
|
|
80
|
+
* localStorage.setItem('backup', json);
|
|
81
|
+
* ```
|
|
82
|
+
*/
|
|
83
|
+
export declare function exportBackup(identity: AgentIdentity, password: string): Promise<Result<EncryptedBackup, BackupError>>;
|
|
84
|
+
/**
|
|
85
|
+
* Restore an identity from an encrypted backup blob.
|
|
86
|
+
*
|
|
87
|
+
* Decrypts the backup using PBKDF2-derived AES key. Verifies authenticity
|
|
88
|
+
* with GCM tag before returning plaintext keys.
|
|
89
|
+
*
|
|
90
|
+
* @param backup - Encrypted backup blob.
|
|
91
|
+
* @param password - User password (plaintext). Will be PBKDF2 derived.
|
|
92
|
+
* @returns Restored AgentIdentity or error.
|
|
93
|
+
*
|
|
94
|
+
* @example
|
|
95
|
+
* ```typescript
|
|
96
|
+
* import { importBackup } from '@private.me/xbind';
|
|
97
|
+
*
|
|
98
|
+
* const json = localStorage.getItem('backup');
|
|
99
|
+
* const backup = JSON.parse(json);
|
|
100
|
+
*
|
|
101
|
+
* const identity = await importBackup(backup, 'user-password');
|
|
102
|
+
* if (!identity.ok) {
|
|
103
|
+
* if (identity.error === 'INVALID_PASSWORD') {
|
|
104
|
+
* console.error('Wrong password!');
|
|
105
|
+
* } else {
|
|
106
|
+
* throw identity.error;
|
|
107
|
+
* }
|
|
108
|
+
* }
|
|
109
|
+
*
|
|
110
|
+
* // Now use restored identity
|
|
111
|
+
* const agent = new Agent(identity.value);
|
|
112
|
+
* ```
|
|
113
|
+
*/
|
|
114
|
+
export declare function importBackup(backup: EncryptedBackup, password: string): Promise<Result<AgentIdentity, BackupError>>;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{ok,err}from"./_deps/shared/index.js";import{toBase64,fromBase64}from"./crypto-utils.js";import{exportPKCS8,exportX25519PKCS8,importIdentity,exportMlKemSecretKey,exportMlKemPublicKey,exportMlDsaSecretKey,exportMlDsaPublicKey}from"./identity.js";const PBKDF2_ITERATIONS=31e4,SALT_LENGTH=16,IV_LENGTH=12,KEY_LENGTH=32;function toArrayBuffer(e){const t=new ArrayBuffer(e.byteLength);return new Uint8Array(t).set(e),t}async function deriveKey(e,t){try{if(16!==t.length)return err("INVALID_BACKUP");const r=await crypto.subtle.importKey("raw",(new TextEncoder).encode(e),"PBKDF2",!1,["deriveBits"]),a=new Uint8Array(await crypto.subtle.deriveBits({name:"PBKDF2",hash:"SHA-256",salt:toArrayBuffer(t),iterations:31e4},r,256)),o=await crypto.subtle.importKey("raw",toArrayBuffer(a),{name:"AES-GCM"},!1,["encrypt","decrypt"]);return ok(o)}catch{return err("PBKDF2_FAILED")}}async function serializeIdentity(e){try{const t=await exportPKCS8(e.privateKey);if(!t.ok)return err("EXPORT_FAILED");const r=await exportX25519PKCS8(e.x25519PrivateKey);if(!r.ok)return err("EXPORT_FAILED");const a=exportMlKemSecretKey(e),o=exportMlKemPublicKey(e),n=exportMlDsaSecretKey(e),i=exportMlDsaPublicKey(e),s=e.rotatedKeys?await Promise.all(e.rotatedKeys.map(async e=>{const t=await exportX25519PKCS8(e.x25519PrivateKey);if(!t.ok)throw new Error("Failed to export rotated X25519 key");return{rotatedAt:e.rotatedAt,x25519Pkcs8:toBase64(t.value),...e.mlKemSecretKey?{mlKemSecretKey:toBase64(e.mlKemSecretKey)}:{}}})):void 0;return ok({did:e.did,rawPublicKey:toBase64(e.rawPublicKey),ed25519Pkcs8:toBase64(t.value),x25519Pkcs8:toBase64(r.value),...a?{mlKemSecretKey:toBase64(a)}:{},...o?{mlKemPublicKey:toBase64(o)}:{},...n?{mlDsaSecretKey:toBase64(n)}:{},...i?{mlDsaPublicKey:toBase64(i)}:{},...s?{rotatedKeys:s}:{},exportedAt:Date.now()})}catch{return err("EXPORT_FAILED")}}export async function exportBackup(e,t){try{const r=await serializeIdentity(e);if(!r.ok)return r;const a=crypto.getRandomValues(new Uint8Array(16)),o=crypto.getRandomValues(new Uint8Array(12)),n=await deriveKey(t,a);if(!n.ok)return n;const i=JSON.stringify(r.value),s=(new TextEncoder).encode(i),c=await crypto.subtle.encrypt({name:"AES-GCM",iv:toArrayBuffer(o)},n.value,s),y=new Uint8Array(c);if(y.length<16)return err("ENCRYPTION_FAILED");const l=y.length-16,K=y.slice(0,l),m=y.slice(l);return ok({version:1,salt:toBase64(a),iv:toBase64(o),ciphertext:toBase64(K),tag:toBase64(m)})}catch{return err("ENCRYPTION_FAILED")}}export async function importBackup(e,t){try{if(1!==e.version)return err("INVALID_BACKUP");let r,a,o,n;try{r=fromBase64(e.salt),a=fromBase64(e.iv),o=fromBase64(e.ciphertext),n=fromBase64(e.tag)}catch{return err("INVALID_BACKUP")}if(16!==r.length||12!==a.length||16!==n.length)return err("INVALID_BACKUP");const i=await deriveKey(t,r);if(!i.ok)return i;const s=new Uint8Array(o.length+n.length);let c,y,l,K,m,u,d,f;s.set(o),s.set(n,o.length);try{c=await crypto.subtle.decrypt({name:"AES-GCM",iv:toArrayBuffer(a)},i.value,toArrayBuffer(s))}catch(e){return console.warn("[xBind] GCM verification failed:",e),err("INVALID_PASSWORD")}try{const e=(new TextDecoder).decode(c);y=JSON.parse(e)}catch{return err("INVALID_BACKUP")}if(!y.did||!y.ed25519Pkcs8||!y.x25519Pkcs8)return err("INVALID_BACKUP");try{l=fromBase64(y.ed25519Pkcs8),K=fromBase64(y.x25519Pkcs8),y.mlKemSecretKey&&(m=fromBase64(y.mlKemSecretKey)),y.mlKemPublicKey&&(u=fromBase64(y.mlKemPublicKey)),y.mlDsaSecretKey&&(d=fromBase64(y.mlDsaSecretKey)),y.mlDsaPublicKey&&(f=fromBase64(y.mlDsaPublicKey))}catch{return err("INVALID_BACKUP")}const B=await importIdentity(l,K,m,u,d,f);if(!B.ok)return err("IMPORT_FAILED");if(y.rotatedKeys&&y.rotatedKeys.length>0){const e=B.value,t=await Promise.all(y.rotatedKeys.map(async e=>{const t=fromBase64(e.x25519Pkcs8),r=await crypto.subtle.importKey("pkcs8",toArrayBuffer(t),{name:"X25519"},!0,["deriveBits"]),a=e.mlKemSecretKey?fromBase64(e.mlKemSecretKey):void 0;return{rotatedAt:e.rotatedAt,x25519PrivateKey:r,...a?{mlKemSecretKey:a}:{}}}));return ok({...e,rotatedKeys:t})}return B}catch(e){return console.warn("[xBind] Import backup failed:",e),err("DECRYPTION_FAILED")}}
|
|
@@ -0,0 +1,297 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @module batch-operations
|
|
3
|
+
* Batch operations support for xBind - enhanced API efficiency
|
|
4
|
+
*
|
|
5
|
+
* Provides batch operations for:
|
|
6
|
+
* - Send: Multiple messages in one call (reduces round-trips)
|
|
7
|
+
* - Receive: Batch envelope processing
|
|
8
|
+
* - Registry: Bulk registration/revocation/updates
|
|
9
|
+
*
|
|
10
|
+
* Features:
|
|
11
|
+
* - Atomic semantics where possible (registry operations)
|
|
12
|
+
* - Partial success handling (graceful degradation)
|
|
13
|
+
* - Progress tracking for long-running batches
|
|
14
|
+
* - Performance optimization (parallel processing)
|
|
15
|
+
*/
|
|
16
|
+
import type { Result } from '@private.me/shared';
|
|
17
|
+
import type { Agent, AgentSendOptions, AgentMessage, AgentError, AgentReceiveOptions } from './agent.js';
|
|
18
|
+
import type { TrustRegistry, RegistryEntry, RegistryError } from './trust-registry.js';
|
|
19
|
+
import type { AnyTransportEnvelope } from './envelope.js';
|
|
20
|
+
import type { ProgressCallback } from '@private.me/ux-helpers';
|
|
21
|
+
/**
|
|
22
|
+
* Options for batch send operations.
|
|
23
|
+
*/
|
|
24
|
+
export interface BatchSendOptions {
|
|
25
|
+
/**
|
|
26
|
+
* Messages to send in batch.
|
|
27
|
+
* Each entry contains standard AgentSendOptions.
|
|
28
|
+
*/
|
|
29
|
+
readonly messages: ReadonlyArray<AgentSendOptions>;
|
|
30
|
+
/**
|
|
31
|
+
* Batch execution strategy.
|
|
32
|
+
*
|
|
33
|
+
* - 'parallel': Send all messages concurrently (default, fastest)
|
|
34
|
+
* - 'sequential': Send one at a time (preserves ordering)
|
|
35
|
+
* - 'failfast': Stop on first error (parallel mode only)
|
|
36
|
+
*/
|
|
37
|
+
readonly strategy?: 'parallel' | 'sequential' | 'failfast';
|
|
38
|
+
/**
|
|
39
|
+
* Maximum concurrent operations (parallel mode only).
|
|
40
|
+
* Default: 10
|
|
41
|
+
*/
|
|
42
|
+
readonly concurrency?: number;
|
|
43
|
+
/**
|
|
44
|
+
* Continue on partial failures.
|
|
45
|
+
* When true, returns all results (success + failures).
|
|
46
|
+
* When false, stops on first error.
|
|
47
|
+
* Default: true
|
|
48
|
+
*/
|
|
49
|
+
readonly continueOnError?: boolean;
|
|
50
|
+
/**
|
|
51
|
+
* Progress callback for batch operations.
|
|
52
|
+
*/
|
|
53
|
+
readonly onProgress?: ProgressCallback;
|
|
54
|
+
}
|
|
55
|
+
/**
|
|
56
|
+
* Result of a single operation in a batch.
|
|
57
|
+
*/
|
|
58
|
+
export interface BatchOperationResult<T> {
|
|
59
|
+
/** Index of operation in original batch. */
|
|
60
|
+
readonly index: number;
|
|
61
|
+
/** Operation result (success or error). */
|
|
62
|
+
readonly result: Result<T, AgentError | RegistryError>;
|
|
63
|
+
/** Processing time in milliseconds. */
|
|
64
|
+
readonly durationMs: number;
|
|
65
|
+
}
|
|
66
|
+
/**
|
|
67
|
+
* Summary of batch operation results.
|
|
68
|
+
*/
|
|
69
|
+
export interface BatchSummary<T> {
|
|
70
|
+
/** Total operations attempted. */
|
|
71
|
+
readonly total: number;
|
|
72
|
+
/** Number of successful operations. */
|
|
73
|
+
readonly succeeded: number;
|
|
74
|
+
/** Number of failed operations. */
|
|
75
|
+
readonly failed: number;
|
|
76
|
+
/** Individual operation results. */
|
|
77
|
+
readonly results: ReadonlyArray<BatchOperationResult<T>>;
|
|
78
|
+
/** Total batch processing time in milliseconds. */
|
|
79
|
+
readonly totalDurationMs: number;
|
|
80
|
+
/** Average operation time in milliseconds. */
|
|
81
|
+
readonly avgDurationMs: number;
|
|
82
|
+
}
|
|
83
|
+
/**
|
|
84
|
+
* Options for batch receive operations.
|
|
85
|
+
*/
|
|
86
|
+
export interface BatchReceiveOptions {
|
|
87
|
+
/**
|
|
88
|
+
* Envelopes to process in batch.
|
|
89
|
+
*/
|
|
90
|
+
readonly envelopes: ReadonlyArray<AnyTransportEnvelope>;
|
|
91
|
+
/**
|
|
92
|
+
* Receive options applied to all envelopes.
|
|
93
|
+
*/
|
|
94
|
+
readonly receiveOptions?: AgentReceiveOptions;
|
|
95
|
+
/**
|
|
96
|
+
* Batch execution strategy.
|
|
97
|
+
* Default: 'parallel'
|
|
98
|
+
*/
|
|
99
|
+
readonly strategy?: 'parallel' | 'sequential';
|
|
100
|
+
/**
|
|
101
|
+
* Maximum concurrent operations (parallel mode only).
|
|
102
|
+
* Default: 10
|
|
103
|
+
*/
|
|
104
|
+
readonly concurrency?: number;
|
|
105
|
+
/**
|
|
106
|
+
* Continue on partial failures.
|
|
107
|
+
* Default: true
|
|
108
|
+
*/
|
|
109
|
+
readonly continueOnError?: boolean;
|
|
110
|
+
/**
|
|
111
|
+
* Progress callback for batch operations.
|
|
112
|
+
*/
|
|
113
|
+
readonly onProgress?: ProgressCallback;
|
|
114
|
+
}
|
|
115
|
+
/**
|
|
116
|
+
* Registry operation for batch processing.
|
|
117
|
+
*/
|
|
118
|
+
export interface RegistryOperation {
|
|
119
|
+
/** Operation type. */
|
|
120
|
+
readonly type: 'register' | 'revoke' | 'updateScopes';
|
|
121
|
+
/** DID being operated on. */
|
|
122
|
+
readonly did: string;
|
|
123
|
+
/** Registration parameters (register only). */
|
|
124
|
+
readonly params?: {
|
|
125
|
+
readonly publicKey: Uint8Array;
|
|
126
|
+
readonly name: string;
|
|
127
|
+
readonly scopes?: string[];
|
|
128
|
+
readonly x25519PublicKey?: Uint8Array;
|
|
129
|
+
readonly mlKemPublicKey?: Uint8Array;
|
|
130
|
+
readonly mlDsaPublicKey?: Uint8Array;
|
|
131
|
+
readonly xchange?: boolean;
|
|
132
|
+
readonly receiveScopes?: string[];
|
|
133
|
+
readonly sdkVersion?: string;
|
|
134
|
+
readonly minEnvelopeVersion?: number;
|
|
135
|
+
readonly maxEnvelopeVersion?: number;
|
|
136
|
+
readonly ttlMs?: number;
|
|
137
|
+
};
|
|
138
|
+
/** New scopes (updateScopes only). */
|
|
139
|
+
readonly newScopes?: string[];
|
|
140
|
+
}
|
|
141
|
+
/**
|
|
142
|
+
* Options for batch registry operations.
|
|
143
|
+
*/
|
|
144
|
+
export interface BatchRegistryOptions {
|
|
145
|
+
/**
|
|
146
|
+
* Registry operations to perform.
|
|
147
|
+
*/
|
|
148
|
+
readonly operations: ReadonlyArray<RegistryOperation>;
|
|
149
|
+
/**
|
|
150
|
+
* Atomic execution mode.
|
|
151
|
+
*
|
|
152
|
+
* - 'atomic': All operations succeed or all fail (transactional)
|
|
153
|
+
* - 'best-effort': Apply as many as possible (default)
|
|
154
|
+
*
|
|
155
|
+
* Note: Atomic mode only supported by registries implementing transactions.
|
|
156
|
+
*/
|
|
157
|
+
readonly atomic?: boolean;
|
|
158
|
+
/**
|
|
159
|
+
* Batch execution strategy.
|
|
160
|
+
* Default: 'parallel'
|
|
161
|
+
*/
|
|
162
|
+
readonly strategy?: 'parallel' | 'sequential';
|
|
163
|
+
/**
|
|
164
|
+
* Maximum concurrent operations (parallel mode only).
|
|
165
|
+
* Default: 5 (lower than send/receive to avoid registry overload)
|
|
166
|
+
*/
|
|
167
|
+
readonly concurrency?: number;
|
|
168
|
+
/**
|
|
169
|
+
* Progress callback for batch operations.
|
|
170
|
+
*/
|
|
171
|
+
readonly onProgress?: ProgressCallback;
|
|
172
|
+
}
|
|
173
|
+
/**
|
|
174
|
+
* Error thrown when batch operation fails.
|
|
175
|
+
*/
|
|
176
|
+
export declare class BatchOperationError extends Error {
|
|
177
|
+
readonly summary: BatchSummary<unknown>;
|
|
178
|
+
constructor(message: string, summary: BatchSummary<unknown>);
|
|
179
|
+
}
|
|
180
|
+
/**
|
|
181
|
+
* Batch send multiple messages.
|
|
182
|
+
*
|
|
183
|
+
* Performance optimization: Sends messages in parallel (default) or sequentially.
|
|
184
|
+
* Reduces round-trips for bulk message delivery.
|
|
185
|
+
*
|
|
186
|
+
* @param agent - Agent instance
|
|
187
|
+
* @param options - Batch send options
|
|
188
|
+
* @returns Batch summary with individual results
|
|
189
|
+
*
|
|
190
|
+
* @example
|
|
191
|
+
* ```typescript
|
|
192
|
+
* const agent = await Agent.create({ name: 'sender', registry });
|
|
193
|
+
* const summary = await batchSend(agent, {
|
|
194
|
+
* messages: [
|
|
195
|
+
* { to: 'did:key:abc', payload: { msg: 1 }, scope: 'chat' },
|
|
196
|
+
* { to: 'did:key:def', payload: { msg: 2 }, scope: 'chat' },
|
|
197
|
+
* ],
|
|
198
|
+
* strategy: 'parallel',
|
|
199
|
+
* });
|
|
200
|
+
* console.log(`Sent ${summary.succeeded}/${summary.total} messages`);
|
|
201
|
+
* ```
|
|
202
|
+
*/
|
|
203
|
+
export declare function batchSend(agent: Agent, options: BatchSendOptions): Promise<BatchSummary<void>>;
|
|
204
|
+
/**
|
|
205
|
+
* Batch receive multiple envelopes.
|
|
206
|
+
*
|
|
207
|
+
* Performance optimization: Processes envelopes in parallel (default).
|
|
208
|
+
* Useful for bulk message ingestion from queues or webhooks.
|
|
209
|
+
*
|
|
210
|
+
* @param agent - Agent instance
|
|
211
|
+
* @param options - Batch receive options
|
|
212
|
+
* @returns Batch summary with individual results
|
|
213
|
+
*
|
|
214
|
+
* @example
|
|
215
|
+
* ```typescript
|
|
216
|
+
* const agent = await Agent.create({ name: 'receiver', registry });
|
|
217
|
+
* const summary = await batchReceive(agent, {
|
|
218
|
+
* envelopes: incomingEnvelopes,
|
|
219
|
+
* strategy: 'parallel',
|
|
220
|
+
* });
|
|
221
|
+
* console.log(`Processed ${summary.succeeded}/${summary.total} envelopes`);
|
|
222
|
+
* ```
|
|
223
|
+
*/
|
|
224
|
+
export declare function batchReceive(agent: Agent, options: BatchReceiveOptions): Promise<BatchSummary<AgentMessage>>;
|
|
225
|
+
/**
|
|
226
|
+
* Batch registry operations (register, revoke, updateScopes).
|
|
227
|
+
*
|
|
228
|
+
* Performance optimization: Groups operations by type for efficient processing.
|
|
229
|
+
* Atomic semantics: When atomic=true, all operations succeed or all fail.
|
|
230
|
+
*
|
|
231
|
+
* @param registry - Trust registry instance
|
|
232
|
+
* @param options - Batch registry options
|
|
233
|
+
* @returns Batch summary with individual results
|
|
234
|
+
*
|
|
235
|
+
* @example
|
|
236
|
+
* ```typescript
|
|
237
|
+
* const summary = await batchRegistryOps(registry, {
|
|
238
|
+
* operations: [
|
|
239
|
+
* { type: 'register', did: 'did:key:abc', params: { publicKey, name: 'Alice' } },
|
|
240
|
+
* { type: 'revoke', did: 'did:key:old' },
|
|
241
|
+
* ],
|
|
242
|
+
* atomic: false, // best-effort mode
|
|
243
|
+
* });
|
|
244
|
+
* console.log(`Completed ${summary.succeeded}/${summary.total} operations`);
|
|
245
|
+
* ```
|
|
246
|
+
*/
|
|
247
|
+
export declare function batchRegistryOps(registry: TrustRegistry, options: BatchRegistryOptions): Promise<BatchSummary<void>>;
|
|
248
|
+
/**
|
|
249
|
+
* Batch resolve multiple DIDs.
|
|
250
|
+
*
|
|
251
|
+
* Performance optimization: Resolves DIDs in parallel.
|
|
252
|
+
* Useful for resolving recipient keys before bulk message sending.
|
|
253
|
+
*
|
|
254
|
+
* @param registry - Trust registry instance
|
|
255
|
+
* @param dids - DIDs to resolve
|
|
256
|
+
* @param options - Optional progress callback and concurrency
|
|
257
|
+
* @returns Batch summary with resolution results
|
|
258
|
+
*
|
|
259
|
+
* @example
|
|
260
|
+
* ```typescript
|
|
261
|
+
* const summary = await batchResolve(registry, [
|
|
262
|
+
* 'did:key:abc',
|
|
263
|
+
* 'did:key:def',
|
|
264
|
+
* 'did:key:ghi',
|
|
265
|
+
* ]);
|
|
266
|
+
* const keys = summary.results
|
|
267
|
+
* .filter(r => r.result.ok)
|
|
268
|
+
* .map(r => r.result.value);
|
|
269
|
+
* ```
|
|
270
|
+
*/
|
|
271
|
+
export declare function batchResolve(registry: TrustRegistry, dids: ReadonlyArray<string>, options?: {
|
|
272
|
+
readonly concurrency?: number;
|
|
273
|
+
readonly onProgress?: ProgressCallback;
|
|
274
|
+
}): Promise<BatchSummary<Uint8Array>>;
|
|
275
|
+
/**
|
|
276
|
+
* Batch get registry entries.
|
|
277
|
+
*
|
|
278
|
+
* Performance optimization: Fetches entries in parallel.
|
|
279
|
+
* Returns full registry metadata for multiple DIDs.
|
|
280
|
+
*
|
|
281
|
+
* @param registry - Trust registry instance
|
|
282
|
+
* @param dids - DIDs to fetch
|
|
283
|
+
* @param options - Optional progress callback and concurrency
|
|
284
|
+
* @returns Batch summary with entry results
|
|
285
|
+
*
|
|
286
|
+
* @example
|
|
287
|
+
* ```typescript
|
|
288
|
+
* const summary = await batchGetEntries(registry, dids);
|
|
289
|
+
* const entries = summary.results
|
|
290
|
+
* .filter(r => r.result.ok)
|
|
291
|
+
* .map(r => r.result.value);
|
|
292
|
+
* ```
|
|
293
|
+
*/
|
|
294
|
+
export declare function batchGetEntries(registry: TrustRegistry, dids: ReadonlyArray<string>, options?: {
|
|
295
|
+
readonly concurrency?: number;
|
|
296
|
+
readonly onProgress?: ProgressCallback;
|
|
297
|
+
}): Promise<BatchSummary<RegistryEntry>>;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{err}from"./_deps/shared/index.js";import{ProgressReporter}from"./_deps/ux-helpers/index.js";export class BatchOperationError extends Error{summary;constructor(e,t){super(e),this.summary=t,this.name="BatchOperationError"}}export async function batchSend(e,t){const n=new ProgressReporter(t.onProgress),r=Date.now(),{messages:o,strategy:s="parallel",concurrency:a=10,continueOnError:c=!0}=t;n.start(`Sending ${o.length} messages (${s} mode)...`);const i=[];if("sequential"===s)for(let t=0;t<o.length;t++){const r=o[t],s=Date.now();n.update(`Sending message ${t+1}/${o.length}...`,t/o.length*100);const a=await e.send(r),u=Date.now()-s;if(i.push({index:t,result:a,durationMs:u}),!c&&!a.ok)break}else if("failfast"===s){const t=o.map((t,n)=>{const o=Date.now();return e.send(t).then(e=>{const t=Date.now()-o;if(!e.ok)throw new BatchOperationError(`Batch send failed at index ${n}: ${e.error}`,createSummary(i,Date.now()-r));return{index:n,result:e,durationMs:t}})});try{const e=await Promise.all(t);i.push(...e)}catch(e){if(e instanceof BatchOperationError)throw e;throw new BatchOperationError("Batch send failed",createSummary(i,Date.now()-r))}}else{const t=chunkArray(o,a);for(let r=0;r<t.length;r++){const o=t[r],s=r*a;n.update(`Processing chunk ${r+1}/${t.length}...`,r/t.length*100);const c=await Promise.all(o.map(async(t,n)=>{const r=s+n,o=Date.now();return{index:r,result:await e.send(t),durationMs:Date.now()-o}}));i.push(...c)}}return n.complete(),createSummary(i,Date.now()-r)}export async function batchReceive(e,t){const n=new ProgressReporter(t.onProgress),r=Date.now(),{envelopes:o,receiveOptions:s,strategy:a="parallel",concurrency:c=10,continueOnError:i=!0}=t;n.start(`Receiving ${o.length} envelopes (${a} mode)...`);const u=[];if("sequential"===a)for(let t=0;t<o.length;t++){const r=o[t],a=Date.now();n.update(`Receiving envelope ${t+1}/${o.length}...`,t/o.length*100);const c=await e.receive(r,s),l=Date.now()-a;if(u.push({index:t,result:c,durationMs:l}),!i&&!c.ok)break}else{const t=chunkArray(o,c);for(let r=0;r<t.length;r++){const o=t[r],a=r*c;n.update(`Processing chunk ${r+1}/${t.length}...`,r/t.length*100);const i=await Promise.all(o.map(async(t,n)=>{const r=a+n,o=Date.now();return{index:r,result:await e.receive(t,s),durationMs:Date.now()-o}}));u.push(...i)}}return n.complete(),createSummary(u,Date.now()-r)}export async function batchRegistryOps(e,t){const n=new ProgressReporter(t.onProgress),r=Date.now(),{operations:o,atomic:s=!1,strategy:a="parallel",concurrency:c=5}=t;n.start(`Executing ${o.length} registry operations (${s?"atomic":"best-effort"} mode)...`);const i=[];if(s&&n.update("Warning: Atomic mode not fully implemented - using best-effort",10),"sequential"===a)for(let t=0;t<o.length;t++){const r=o[t],a=Date.now();n.update(`Operation ${t+1}/${o.length}: ${r.type} ${r.did}`,t/o.length*100);const c=await executeRegistryOperation(e,r),u=Date.now()-a;if(i.push({index:t,result:c,durationMs:u}),s&&!c.ok)break}else{const t=chunkArray(o,c);for(let r=0;r<t.length;r++){const o=t[r],a=r*c;n.update(`Processing chunk ${r+1}/${t.length}...`,r/t.length*100);const u=await Promise.all(o.map(async(t,n)=>{const r=a+n,o=Date.now();return{index:r,result:await executeRegistryOperation(e,t),durationMs:Date.now()-o}}));if(i.push(...u),s&&u.some(e=>!e.result.ok))break}}return n.complete(),createSummary(i,Date.now()-r)}export async function batchResolve(e,t,n){const r=new ProgressReporter(n?.onProgress),o=Date.now(),s=n?.concurrency??10;r.start(`Resolving ${t.length} DIDs...`);const a=[],c=chunkArray(t,s);for(let t=0;t<c.length;t++){const n=c[t],o=t*s;r.update(`Resolving chunk ${t+1}/${c.length}...`,t/c.length*100);const i=await Promise.all(n.map(async(t,n)=>{const r=o+n,s=Date.now();return{index:r,result:await e.resolve(t),durationMs:Date.now()-s}}));a.push(...i)}return r.complete(),createSummary(a,Date.now()-o)}export async function batchGetEntries(e,t,n){const r=new ProgressReporter(n?.onProgress),o=Date.now(),s=n?.concurrency??10;r.start(`Fetching ${t.length} registry entries...`);const a=[],c=chunkArray(t,s);for(let t=0;t<c.length;t++){const n=c[t],o=t*s;r.update(`Fetching chunk ${t+1}/${c.length}...`,t/c.length*100);const i=await Promise.all(n.map(async(t,n)=>{const r=o+n,s=Date.now();return{index:r,result:await e.getEntry(t),durationMs:Date.now()-s}}));a.push(...i)}return r.complete(),createSummary(a,Date.now()-o)}async function executeRegistryOperation(e,t){switch(t.type){case"register":{if(!t.params)return err("INVALID_PARAMS");const{publicKey:n,name:r,scopes:o,x25519PublicKey:s,mlKemPublicKey:a,mlDsaPublicKey:c,xchange:i,receiveScopes:u,sdkVersion:l,minEnvelopeVersion:p,maxEnvelopeVersion:h,ttlMs:g}=t.params;return e.register(t.did,n,r,o,s,a,c,i,u,l,p,h,g)}case"revoke":return e.revoke(t.did);case"updateScopes":return t.newScopes&&"updateScopes"in e&&"function"==typeof e.updateScopes?e.updateScopes(t.did,t.newScopes):err("INVALID_PARAMS");default:return err("INVALID_OPERATION")}}function createSummary(e,t){const n=e.filter(e=>e.result.ok).length,r=e.filter(e=>!e.result.ok).length,o=e.length>0?e.reduce((e,t)=>e+t.durationMs,0)/e.length:0;return{total:e.length,succeeded:n,failed:r,results:e,totalDurationMs:t,avgDurationMs:o}}function chunkArray(e,t){const n=[];for(let r=0;r<e.length;r+=t)n.push(e.slice(r,r+t));return n}
|