@bananalink-sdk/protocol 1.2.7
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 +604 -0
- package/dist/chunk-32OWUOZ3.js +308 -0
- package/dist/chunk-32OWUOZ3.js.map +1 -0
- package/dist/chunk-65HNHRJK.cjs +123 -0
- package/dist/chunk-65HNHRJK.cjs.map +1 -0
- package/dist/chunk-7KYDLL3B.js +480 -0
- package/dist/chunk-7KYDLL3B.js.map +1 -0
- package/dist/chunk-A6FLEJ7R.cjs +62 -0
- package/dist/chunk-A6FLEJ7R.cjs.map +1 -0
- package/dist/chunk-CUJK7ZTS.js +217 -0
- package/dist/chunk-CUJK7ZTS.js.map +1 -0
- package/dist/chunk-GI3BUPIH.cjs +236 -0
- package/dist/chunk-GI3BUPIH.cjs.map +1 -0
- package/dist/chunk-JXHV66Q4.js +106 -0
- package/dist/chunk-JXHV66Q4.js.map +1 -0
- package/dist/chunk-KNGZKGRS.cjs +552 -0
- package/dist/chunk-KNGZKGRS.cjs.map +1 -0
- package/dist/chunk-LELPCIE7.js +840 -0
- package/dist/chunk-LELPCIE7.js.map +1 -0
- package/dist/chunk-MCZG7QEM.cjs +310 -0
- package/dist/chunk-MCZG7QEM.cjs.map +1 -0
- package/dist/chunk-TCVKC227.js +56 -0
- package/dist/chunk-TCVKC227.js.map +1 -0
- package/dist/chunk-VXLUSU5B.cjs +856 -0
- package/dist/chunk-VXLUSU5B.cjs.map +1 -0
- package/dist/chunk-WCQVDF3K.js +12 -0
- package/dist/chunk-WCQVDF3K.js.map +1 -0
- package/dist/chunk-WGEGR3DF.cjs +15 -0
- package/dist/chunk-WGEGR3DF.cjs.map +1 -0
- package/dist/client-session-claim-3QF3noOr.d.ts +197 -0
- package/dist/client-session-claim-C4lUik3b.d.cts +197 -0
- package/dist/core-DMhuNfoz.d.cts +62 -0
- package/dist/core-DMhuNfoz.d.ts +62 -0
- package/dist/crypto/providers/noble-provider.cjs +14 -0
- package/dist/crypto/providers/noble-provider.cjs.map +1 -0
- package/dist/crypto/providers/noble-provider.d.cts +30 -0
- package/dist/crypto/providers/noble-provider.d.ts +30 -0
- package/dist/crypto/providers/noble-provider.js +5 -0
- package/dist/crypto/providers/noble-provider.js.map +1 -0
- package/dist/crypto/providers/node-provider.cjs +308 -0
- package/dist/crypto/providers/node-provider.cjs.map +1 -0
- package/dist/crypto/providers/node-provider.d.cts +32 -0
- package/dist/crypto/providers/node-provider.d.ts +32 -0
- package/dist/crypto/providers/node-provider.js +306 -0
- package/dist/crypto/providers/node-provider.js.map +1 -0
- package/dist/crypto/providers/quickcrypto-provider.cjs +339 -0
- package/dist/crypto/providers/quickcrypto-provider.cjs.map +1 -0
- package/dist/crypto/providers/quickcrypto-provider.d.cts +34 -0
- package/dist/crypto/providers/quickcrypto-provider.d.ts +34 -0
- package/dist/crypto/providers/quickcrypto-provider.js +337 -0
- package/dist/crypto/providers/quickcrypto-provider.js.map +1 -0
- package/dist/crypto/providers/webcrypto-provider.cjs +310 -0
- package/dist/crypto/providers/webcrypto-provider.cjs.map +1 -0
- package/dist/crypto/providers/webcrypto-provider.d.cts +30 -0
- package/dist/crypto/providers/webcrypto-provider.d.ts +30 -0
- package/dist/crypto/providers/webcrypto-provider.js +308 -0
- package/dist/crypto/providers/webcrypto-provider.js.map +1 -0
- package/dist/crypto-BUS06Qz-.d.cts +40 -0
- package/dist/crypto-BUS06Qz-.d.ts +40 -0
- package/dist/crypto-export.cjs +790 -0
- package/dist/crypto-export.cjs.map +1 -0
- package/dist/crypto-export.d.cts +257 -0
- package/dist/crypto-export.d.ts +257 -0
- package/dist/crypto-export.js +709 -0
- package/dist/crypto-export.js.map +1 -0
- package/dist/crypto-provider-deYoVIxi.d.cts +36 -0
- package/dist/crypto-provider-deYoVIxi.d.ts +36 -0
- package/dist/index.cjs +615 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +379 -0
- package/dist/index.d.ts +379 -0
- package/dist/index.js +504 -0
- package/dist/index.js.map +1 -0
- package/dist/schemas-export.cjs +294 -0
- package/dist/schemas-export.cjs.map +1 -0
- package/dist/schemas-export.d.cts +1598 -0
- package/dist/schemas-export.d.ts +1598 -0
- package/dist/schemas-export.js +5 -0
- package/dist/schemas-export.js.map +1 -0
- package/dist/siwe-export.cjs +237 -0
- package/dist/siwe-export.cjs.map +1 -0
- package/dist/siwe-export.d.cts +27 -0
- package/dist/siwe-export.d.ts +27 -0
- package/dist/siwe-export.js +228 -0
- package/dist/siwe-export.js.map +1 -0
- package/dist/testing.cjs +54 -0
- package/dist/testing.cjs.map +1 -0
- package/dist/testing.d.cts +20 -0
- package/dist/testing.d.ts +20 -0
- package/dist/testing.js +51 -0
- package/dist/testing.js.map +1 -0
- package/dist/validation-export.cjs +359 -0
- package/dist/validation-export.cjs.map +1 -0
- package/dist/validation-export.d.cts +3 -0
- package/dist/validation-export.d.ts +3 -0
- package/dist/validation-export.js +6 -0
- package/dist/validation-export.js.map +1 -0
- package/dist/validators-export.cjs +73 -0
- package/dist/validators-export.cjs.map +1 -0
- package/dist/validators-export.d.cts +37 -0
- package/dist/validators-export.d.ts +37 -0
- package/dist/validators-export.js +4 -0
- package/dist/validators-export.js.map +1 -0
- package/package.json +140 -0
- package/src/constants/index.ts +205 -0
- package/src/crypto/context.ts +228 -0
- package/src/crypto/diagnostics.ts +772 -0
- package/src/crypto/errors.ts +114 -0
- package/src/crypto/index.ts +89 -0
- package/src/crypto/payload-handler.ts +102 -0
- package/src/crypto/providers/compliance-provider.ts +579 -0
- package/src/crypto/providers/factory.ts +204 -0
- package/src/crypto/providers/index.ts +44 -0
- package/src/crypto/providers/noble-provider.ts +392 -0
- package/src/crypto/providers/node-provider.ts +433 -0
- package/src/crypto/providers/quickcrypto-provider.ts +483 -0
- package/src/crypto/providers/registry.ts +129 -0
- package/src/crypto/providers/webcrypto-provider.ts +364 -0
- package/src/crypto/session-security.ts +185 -0
- package/src/crypto/types.ts +93 -0
- package/src/crypto/utils.ts +190 -0
- package/src/crypto-export.ts +21 -0
- package/src/index.ts +38 -0
- package/src/schemas/auth.ts +60 -0
- package/src/schemas/client-messages.ts +57 -0
- package/src/schemas/core.ts +144 -0
- package/src/schemas/crypto.ts +65 -0
- package/src/schemas/discovery.ts +79 -0
- package/src/schemas/index.ts +239 -0
- package/src/schemas/relay-messages.ts +45 -0
- package/src/schemas/wallet-messages.ts +177 -0
- package/src/schemas-export.ts +23 -0
- package/src/siwe-export.ts +27 -0
- package/src/testing.ts +71 -0
- package/src/types/auth.ts +60 -0
- package/src/types/client-messages.ts +84 -0
- package/src/types/core.ts +131 -0
- package/src/types/crypto-provider.ts +264 -0
- package/src/types/crypto.ts +90 -0
- package/src/types/discovery.ts +50 -0
- package/src/types/errors.ts +87 -0
- package/src/types/index.ts +197 -0
- package/src/types/post-auth-operations.ts +363 -0
- package/src/types/providers.ts +72 -0
- package/src/types/relay-messages.ts +60 -0
- package/src/types/request-lifecycle.ts +161 -0
- package/src/types/signing-operations.ts +99 -0
- package/src/types/wallet-messages.ts +251 -0
- package/src/utils/client-session-claim.ts +188 -0
- package/src/utils/index.ts +54 -0
- package/src/utils/public-keys.ts +49 -0
- package/src/utils/siwe.ts +362 -0
- package/src/utils/url-decoding.ts +126 -0
- package/src/utils/url-encoding.ts +144 -0
- package/src/utils/wallet-session-claim.ts +188 -0
- package/src/validation-export.ts +32 -0
- package/src/validators/index.ts +222 -0
- package/src/validators-export.ts +8 -0
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
import type { CryptoProviderType, PlatformDetectionResult } from '../types/crypto-provider';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Base class for all crypto-related errors
|
|
5
|
+
* Provides structured context for better debugging
|
|
6
|
+
*/
|
|
7
|
+
export class CryptoError extends Error {
|
|
8
|
+
constructor(
|
|
9
|
+
message: string,
|
|
10
|
+
public readonly code: string,
|
|
11
|
+
public readonly context?: Record<string, unknown>
|
|
12
|
+
) {
|
|
13
|
+
super(message);
|
|
14
|
+
this.name = 'CryptoError';
|
|
15
|
+
|
|
16
|
+
// Maintain proper stack trace in V8 environments
|
|
17
|
+
if (Error.captureStackTrace) {
|
|
18
|
+
Error.captureStackTrace(this, this.constructor);
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* Thrown when a requested crypto provider is not available in the current environment
|
|
25
|
+
* Includes diagnostic information to help developers understand why and what alternatives exist
|
|
26
|
+
*/
|
|
27
|
+
export class CryptoProviderUnavailableError extends CryptoError {
|
|
28
|
+
constructor(
|
|
29
|
+
message: string,
|
|
30
|
+
context: {
|
|
31
|
+
requestedProvider?: CryptoProviderType;
|
|
32
|
+
availableProviders: CryptoProviderType[];
|
|
33
|
+
platform?: PlatformDetectionResult;
|
|
34
|
+
recommendations: string[];
|
|
35
|
+
}
|
|
36
|
+
) {
|
|
37
|
+
super(message, 'PROVIDER_UNAVAILABLE', context);
|
|
38
|
+
this.name = 'CryptoProviderUnavailableError';
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
/**
|
|
42
|
+
* Format a developer-friendly error message with context
|
|
43
|
+
* Includes available alternatives and actionable recommendations
|
|
44
|
+
*/
|
|
45
|
+
toDevMessage(): string {
|
|
46
|
+
// Guard against undefined context (defensive programming)
|
|
47
|
+
if (!this.context) {
|
|
48
|
+
return this.message;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
const ctx = this.context as {
|
|
52
|
+
requestedProvider?: CryptoProviderType;
|
|
53
|
+
availableProviders: CryptoProviderType[];
|
|
54
|
+
platform?: PlatformDetectionResult;
|
|
55
|
+
recommendations: string[];
|
|
56
|
+
};
|
|
57
|
+
|
|
58
|
+
const lines: string[] = [
|
|
59
|
+
this.message,
|
|
60
|
+
'',
|
|
61
|
+
'Available providers:',
|
|
62
|
+
...ctx.availableProviders.map(p => ` - ${p}`),
|
|
63
|
+
];
|
|
64
|
+
|
|
65
|
+
if (ctx.recommendations.length > 0) {
|
|
66
|
+
lines.push('', 'Recommendations:');
|
|
67
|
+
lines.push(...ctx.recommendations.map(r => ` - ${r}`));
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
// Add platform information if available
|
|
71
|
+
if (ctx.platform) {
|
|
72
|
+
const platformType = ctx.platform.isNode
|
|
73
|
+
? 'Node.js'
|
|
74
|
+
: ctx.platform.isBrowser
|
|
75
|
+
? 'Browser'
|
|
76
|
+
: ctx.platform.isReactNative
|
|
77
|
+
? 'React Native'
|
|
78
|
+
: 'Unknown';
|
|
79
|
+
|
|
80
|
+
lines.push('', `Platform: ${platformType}`);
|
|
81
|
+
|
|
82
|
+
if (ctx.platform.platform) {
|
|
83
|
+
lines.push(`OS: ${ctx.platform.platform}`);
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
if (ctx.platform.userAgent) {
|
|
87
|
+
const ua = ctx.platform.userAgent;
|
|
88
|
+
// Only truncate if longer than 100 characters
|
|
89
|
+
const truncated = ua.length > 100 ? `${ua.substring(0, 100)}...` : ua;
|
|
90
|
+
lines.push(`User Agent: ${truncated}`);
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
return lines.join('\n');
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
/**
|
|
99
|
+
* Thrown when a specific cryptographic operation is not supported by the provider
|
|
100
|
+
*/
|
|
101
|
+
export class CryptoCapabilityMissingError extends CryptoError {
|
|
102
|
+
constructor(
|
|
103
|
+
operation: string,
|
|
104
|
+
provider: string,
|
|
105
|
+
reason: string
|
|
106
|
+
) {
|
|
107
|
+
super(
|
|
108
|
+
`Crypto operation '${operation}' is not available in provider '${provider}': ${reason}`,
|
|
109
|
+
'CAPABILITY_MISSING',
|
|
110
|
+
{ operation, provider, reason }
|
|
111
|
+
);
|
|
112
|
+
this.name = 'CryptoCapabilityMissingError';
|
|
113
|
+
}
|
|
114
|
+
}
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* BananaLink Crypto Module
|
|
3
|
+
*
|
|
4
|
+
* Provides environment-agnostic cryptographic utilities for the BananaLink protocol including:
|
|
5
|
+
* - ECDHE key exchange (Web Crypto API + Noble fallback)
|
|
6
|
+
* - AES-256-GCM encryption/decryption
|
|
7
|
+
* - Session security management
|
|
8
|
+
* - Crypto payload handling
|
|
9
|
+
* - Pluggable crypto providers for different environments
|
|
10
|
+
*/
|
|
11
|
+
|
|
12
|
+
// Core crypto functionality
|
|
13
|
+
export { SessionSecurity } from './session-security';
|
|
14
|
+
export { CryptoPayloadHandler } from './payload-handler';
|
|
15
|
+
|
|
16
|
+
// Crypto context management
|
|
17
|
+
export { CryptoContext, type CryptoContextConfig } from './context';
|
|
18
|
+
|
|
19
|
+
// Utility functions
|
|
20
|
+
export { randomBytes, arrayBufferToBase64, base64ToArrayBuffer, stringToArrayBuffer, arrayBufferToString, generateNonce, generateUUID } from './utils';
|
|
21
|
+
|
|
22
|
+
// Provider system
|
|
23
|
+
export type {
|
|
24
|
+
CryptoProvider,
|
|
25
|
+
CryptoKeyLike,
|
|
26
|
+
ProviderKeyPair,
|
|
27
|
+
CryptoProviderType,
|
|
28
|
+
} from '../types/crypto-provider';
|
|
29
|
+
|
|
30
|
+
// Error classes
|
|
31
|
+
export {
|
|
32
|
+
CryptoError,
|
|
33
|
+
CryptoProviderUnavailableError,
|
|
34
|
+
CryptoCapabilityMissingError,
|
|
35
|
+
} from './errors';
|
|
36
|
+
|
|
37
|
+
// Provider registry functions (for managing providers)
|
|
38
|
+
export {
|
|
39
|
+
createCryptoProvider,
|
|
40
|
+
isCryptoProviderRegistered,
|
|
41
|
+
getRegisteredCryptoProviders,
|
|
42
|
+
registerCryptoProvider,
|
|
43
|
+
getCryptoProviderFactory,
|
|
44
|
+
clearCryptoProviderRegistry,
|
|
45
|
+
type CryptoProviderFactory,
|
|
46
|
+
} from './providers';
|
|
47
|
+
|
|
48
|
+
// Compliance wrapper (doesn't self-register, safe to export)
|
|
49
|
+
export { ComplianceCryptoProvider, DefaultComplianceAuditor } from './providers/compliance-provider';
|
|
50
|
+
|
|
51
|
+
// Note: Provider classes should be imported from specific subpaths for explicit loading:
|
|
52
|
+
// - '@bananalink-sdk/protocol/crypto/provider/webcrypto' for WebCryptoProvider
|
|
53
|
+
// - '@bananalink-sdk/protocol/crypto/provider/node' for NodeCryptoProvider
|
|
54
|
+
// - '@bananalink-sdk/protocol/crypto/provider/noble' for NobleCryptoProvider
|
|
55
|
+
// - '@bananalink-sdk/protocol/crypto/provider/quickcrypto' for QuickCryptoProvider
|
|
56
|
+
// - '@bananalink-sdk/protocol/crypto/provider/compliance' for ComplianceCryptoProvider
|
|
57
|
+
|
|
58
|
+
// Runtime types
|
|
59
|
+
export type {
|
|
60
|
+
EncryptionAlgorithm,
|
|
61
|
+
EncryptedMessage,
|
|
62
|
+
SessionKeys,
|
|
63
|
+
CryptoConfig,
|
|
64
|
+
CreatePayloadOptions,
|
|
65
|
+
} from './types';
|
|
66
|
+
|
|
67
|
+
// Compliance types
|
|
68
|
+
export type {
|
|
69
|
+
ComplianceEventType,
|
|
70
|
+
ComplianceAuditEvent,
|
|
71
|
+
ComplianceAuditor,
|
|
72
|
+
KeyUsageRestrictions,
|
|
73
|
+
ComplianceConfig,
|
|
74
|
+
} from './providers/compliance-provider';
|
|
75
|
+
|
|
76
|
+
// Diagnostics utilities
|
|
77
|
+
export {
|
|
78
|
+
testProvider,
|
|
79
|
+
benchmarkProvider,
|
|
80
|
+
diagnoseEnvironment,
|
|
81
|
+
compareProviders,
|
|
82
|
+
} from './diagnostics';
|
|
83
|
+
|
|
84
|
+
export type {
|
|
85
|
+
OperationTestResult,
|
|
86
|
+
ProviderTestResult,
|
|
87
|
+
ProviderBenchmark,
|
|
88
|
+
EnvironmentDiagnostics,
|
|
89
|
+
} from './diagnostics';
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
import type { CreatePayloadOptions } from './types';
|
|
2
|
+
import type { CryptoPayload } from '../types/crypto';
|
|
3
|
+
import { randomBytes, arrayBufferToBase64, base64ToArrayBuffer } from './utils';
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Parses a raw uncompressed P-256 public key.
|
|
7
|
+
* The key should be 65 bytes: [0x04, 32-byte X, 32-byte Y]
|
|
8
|
+
*/
|
|
9
|
+
function parsePublicKey(publicKey: ArrayBuffer): { x: ArrayBuffer; y: ArrayBuffer } {
|
|
10
|
+
if (publicKey.byteLength !== 65 || new Uint8Array(publicKey)[0] !== 4) {
|
|
11
|
+
throw new Error('Invalid P-256 public key format');
|
|
12
|
+
}
|
|
13
|
+
const x = publicKey.slice(1, 33);
|
|
14
|
+
const y = publicKey.slice(33, 65);
|
|
15
|
+
return { x, y };
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
export class CryptoPayloadHandler {
|
|
19
|
+
static createPayload(options: CreatePayloadOptions): CryptoPayload {
|
|
20
|
+
if (options.encAlgo === 'plaintext') {
|
|
21
|
+
return {
|
|
22
|
+
version: '1.0',
|
|
23
|
+
encryption: {
|
|
24
|
+
algorithm: 'plaintext',
|
|
25
|
+
},
|
|
26
|
+
parameters: {
|
|
27
|
+
timestamp: new Date().toISOString(),
|
|
28
|
+
sessionId: options.sessionId,
|
|
29
|
+
},
|
|
30
|
+
};
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
if (options.encAlgo === 'AES-GCM') {
|
|
34
|
+
const iv = randomBytes(12);
|
|
35
|
+
const salt = randomBytes(32);
|
|
36
|
+
const publicKeyRaw = base64ToArrayBuffer(options.publicKeyB64);
|
|
37
|
+
const { x, y } = parsePublicKey(publicKeyRaw);
|
|
38
|
+
|
|
39
|
+
return {
|
|
40
|
+
version: '1.0',
|
|
41
|
+
keyExchange: {
|
|
42
|
+
algorithm: 'ECDH',
|
|
43
|
+
namedCurve: 'P-256',
|
|
44
|
+
},
|
|
45
|
+
encryption: {
|
|
46
|
+
algorithm: 'AES-GCM',
|
|
47
|
+
keyLength: 256,
|
|
48
|
+
tagLength: 128,
|
|
49
|
+
},
|
|
50
|
+
publicKey: {
|
|
51
|
+
kty: 'EC',
|
|
52
|
+
crv: 'P-256',
|
|
53
|
+
x: arrayBufferToBase64(x),
|
|
54
|
+
y: arrayBufferToBase64(y),
|
|
55
|
+
use: 'enc',
|
|
56
|
+
key_ops: ['deriveKey'],
|
|
57
|
+
},
|
|
58
|
+
parameters: {
|
|
59
|
+
iv: arrayBufferToBase64(iv.buffer),
|
|
60
|
+
timestamp: new Date().toISOString(),
|
|
61
|
+
sessionId: options.sessionId,
|
|
62
|
+
},
|
|
63
|
+
derivation: {
|
|
64
|
+
algorithm: 'HKDF',
|
|
65
|
+
hash: 'SHA-256',
|
|
66
|
+
info: 'message-exchange-v1',
|
|
67
|
+
salt: arrayBufferToBase64(salt.buffer),
|
|
68
|
+
},
|
|
69
|
+
};
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
// This part should be unreachable with TypeScript's type checking
|
|
73
|
+
throw new Error('Invalid encryption algorithm specified.');
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
/**
|
|
77
|
+
* Validate crypto payload format
|
|
78
|
+
*/
|
|
79
|
+
static validatePayload(payload: CryptoPayload): boolean {
|
|
80
|
+
try {
|
|
81
|
+
if (payload.version !== '1.0') {
|
|
82
|
+
return false;
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
if (!payload.parameters?.sessionId || !payload.parameters?.timestamp) {
|
|
86
|
+
return false;
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
if (payload.encryption?.algorithm === 'AES-GCM') {
|
|
90
|
+
return !!(payload.keyExchange && payload.publicKey && payload.derivation);
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
if (payload.encryption?.algorithm === 'plaintext') {
|
|
94
|
+
return true;
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
return false;
|
|
98
|
+
} catch {
|
|
99
|
+
return false;
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
}
|