@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
package/README.md
ADDED
|
@@ -0,0 +1,604 @@
|
|
|
1
|
+
# @bananalink-sdk/protocol
|
|
2
|
+
|
|
3
|
+
The core protocol package for BananaLink, containing all TypeScript types, Zod validation schemas, and constants for the dApp-to-wallet communication protocol.
|
|
4
|
+
|
|
5
|
+
## Documentation
|
|
6
|
+
|
|
7
|
+
- **[Protocol Specification](./docs/PROTOCOL.md)** - Complete protocol specification with message types, flows, and security model
|
|
8
|
+
- **[Implementation Guide](./docs/IMPLEMENTATION.md)** - SDK integration examples, wallet integration patterns, and best practices
|
|
9
|
+
|
|
10
|
+
## Table of Contents
|
|
11
|
+
|
|
12
|
+
- [Core Interfaces](#core-interfaces)
|
|
13
|
+
- [SIWE Fields](#siwe-fields)
|
|
14
|
+
- [BananaLink Message](#bananalink-message)
|
|
15
|
+
- [Transaction Payload](#transaction-payload)
|
|
16
|
+
- [Sign Payload](#sign-payload)
|
|
17
|
+
- [BananaLink Response](#bananalink-response)
|
|
18
|
+
- [Metadata & Configuration](#metadata--configuration)
|
|
19
|
+
- [DApp Metadata](#dapp-metadata)
|
|
20
|
+
- [Session Config](#session-config)
|
|
21
|
+
- [Session Options](#session-options)
|
|
22
|
+
- [Security Policy](#security-policy)
|
|
23
|
+
- [Discovery Types](#discovery-types)
|
|
24
|
+
- [QR Payload](#qr-payload)
|
|
25
|
+
- [Display Info](#display-info)
|
|
26
|
+
- [Relay Message](#relay-message)
|
|
27
|
+
- [Encrypted Payload](#encrypted-payload)
|
|
28
|
+
- [Authentication Types](#authentication-types)
|
|
29
|
+
- [Session Info](#session-info)
|
|
30
|
+
- [Origin Proof](#origin-proof)
|
|
31
|
+
- [Cryptographic Types](#cryptographic-types)
|
|
32
|
+
- [Crypto Payload](#crypto-payload)
|
|
33
|
+
- [Key Exchange](#key-exchange)
|
|
34
|
+
- [Encryption](#encryption)
|
|
35
|
+
- [Public Key JWK](#public-key-jwk)
|
|
36
|
+
- [Key Derivation](#key-derivation)
|
|
37
|
+
- [Error Types](#error-types)
|
|
38
|
+
- [BananaLink Error](#bananalink-error)
|
|
39
|
+
- [Constants](#constants)
|
|
40
|
+
- [Validation Schemas](#validation-schemas)
|
|
41
|
+
|
|
42
|
+
---
|
|
43
|
+
|
|
44
|
+
## Core Interfaces
|
|
45
|
+
|
|
46
|
+
### SIWE Fields
|
|
47
|
+
|
|
48
|
+
Based on ERC-4361 Sign-In with Ethereum standard:
|
|
49
|
+
|
|
50
|
+
```typescript
|
|
51
|
+
interface SIWEFields {
|
|
52
|
+
scheme?: string; // URI scheme of the origin (e.g., "https")
|
|
53
|
+
domain: string; // Domain requesting the signing (e.g., "mydapp.com")
|
|
54
|
+
address: string; // Ethereum address performing the signing
|
|
55
|
+
statement?: string; // Human-readable assertion for user to sign
|
|
56
|
+
uri: string; // Resource URI subject of the signing
|
|
57
|
+
version: string; // SIWE Message version (must be "1")
|
|
58
|
+
chainId: number; // EIP-155 Chain ID (e.g., 1 for Ethereum mainnet)
|
|
59
|
+
nonce: string; // Random string for replay protection (min 8 chars)
|
|
60
|
+
issuedAt: string; // ISO 8601 datetime when message was generated
|
|
61
|
+
expirationTime?: string; // ISO 8601 datetime when message expires
|
|
62
|
+
notBefore?: string; // ISO 8601 datetime when message becomes valid
|
|
63
|
+
requestId?: string; // System-specific identifier for the request
|
|
64
|
+
resources?: string[]; // List of information/references to resolve
|
|
65
|
+
}
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
### BananaLink Message
|
|
69
|
+
|
|
70
|
+
Main message interface extending SIWE with BananaLink protocol extensions:
|
|
71
|
+
|
|
72
|
+
```typescript
|
|
73
|
+
interface BananaLinkMessage extends SIWEFields {
|
|
74
|
+
type: 'auth' | 'tx' | 'sign'; // Type of BananaLink request
|
|
75
|
+
sessionId: string; // Unique session identifier
|
|
76
|
+
payload?: TransactionPayload | SignPayload; // Request-specific payload
|
|
77
|
+
}
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
### Transaction Payload
|
|
81
|
+
|
|
82
|
+
For transaction signing requests:
|
|
83
|
+
|
|
84
|
+
```typescript
|
|
85
|
+
interface TransactionPayload {
|
|
86
|
+
to: string; // Recipient address
|
|
87
|
+
value?: string; // Value in wei as string
|
|
88
|
+
data?: string; // Transaction data (hex string)
|
|
89
|
+
gas?: string; // Gas limit as string
|
|
90
|
+
gasPrice?: string; // Gas price for legacy transactions
|
|
91
|
+
maxFeePerGas?: string; // Max fee per gas (EIP-1559)
|
|
92
|
+
maxPriorityFeePerGas?: string; // Max priority fee per gas (EIP-1559)
|
|
93
|
+
}
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
### Sign Payload
|
|
97
|
+
|
|
98
|
+
For message signing requests:
|
|
99
|
+
|
|
100
|
+
```typescript
|
|
101
|
+
interface SignPayload {
|
|
102
|
+
message: string; // Message to sign
|
|
103
|
+
encoding?: 'utf8' | 'hex'; // Encoding format (default: 'utf8')
|
|
104
|
+
}
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
### BananaLink Response
|
|
108
|
+
|
|
109
|
+
Response format for all requests:
|
|
110
|
+
|
|
111
|
+
```typescript
|
|
112
|
+
interface BananaLinkResponse {
|
|
113
|
+
success: boolean; // Whether the request was successful
|
|
114
|
+
data?: any; // Response data (signature, tx hash, etc.)
|
|
115
|
+
error?: string; // Error message if unsuccessful
|
|
116
|
+
requestId?: string; // Request ID for correlation
|
|
117
|
+
}
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
---
|
|
121
|
+
|
|
122
|
+
## Metadata & Configuration
|
|
123
|
+
|
|
124
|
+
### DApp Metadata
|
|
125
|
+
|
|
126
|
+
Metadata for dApp registration and discovery:
|
|
127
|
+
|
|
128
|
+
```typescript
|
|
129
|
+
interface DAppMetadata {
|
|
130
|
+
name: string; // Name of the dApp
|
|
131
|
+
description?: string; // Description of the dApp
|
|
132
|
+
url: string; // URL of the dApp
|
|
133
|
+
icons?: string[]; // Array of icon URLs
|
|
134
|
+
}
|
|
135
|
+
```
|
|
136
|
+
|
|
137
|
+
### Session Config
|
|
138
|
+
|
|
139
|
+
Session-specific configuration (separate from dApp metadata):
|
|
140
|
+
|
|
141
|
+
```typescript
|
|
142
|
+
interface SessionConfig {
|
|
143
|
+
returnUrl?: string; // URL to redirect after completion
|
|
144
|
+
sessionName?: string; // Human-readable session identifier
|
|
145
|
+
expiresAt?: string; // Session expiration (ISO 8601)
|
|
146
|
+
customData?: Record<string, unknown>; // Custom session data
|
|
147
|
+
}
|
|
148
|
+
```
|
|
149
|
+
|
|
150
|
+
### Session Options
|
|
151
|
+
|
|
152
|
+
Options for creating new sessions:
|
|
153
|
+
|
|
154
|
+
```typescript
|
|
155
|
+
interface SessionOptions {
|
|
156
|
+
config?: SessionConfig; // Session configuration
|
|
157
|
+
securityPolicy?: Partial<SecurityPolicy>; // Security policy overrides
|
|
158
|
+
}
|
|
159
|
+
```
|
|
160
|
+
|
|
161
|
+
### Security Policy
|
|
162
|
+
|
|
163
|
+
Security configuration for sessions:
|
|
164
|
+
|
|
165
|
+
```typescript
|
|
166
|
+
interface SecurityPolicy {
|
|
167
|
+
sessionTimeout: number; // Session timeout in milliseconds
|
|
168
|
+
requestTimeout: number; // Request timeout in milliseconds
|
|
169
|
+
maxConcurrentSessions: number; // Max concurrent sessions allowed
|
|
170
|
+
requireOriginProof: boolean; // Require domain ownership proof
|
|
171
|
+
allowedDomains?: string[]; // Allowed domains whitelist
|
|
172
|
+
blockedDomains?: string[]; // Blocked domains blacklist
|
|
173
|
+
}
|
|
174
|
+
```
|
|
175
|
+
|
|
176
|
+
---
|
|
177
|
+
|
|
178
|
+
## Discovery Types
|
|
179
|
+
|
|
180
|
+
### QR Payload
|
|
181
|
+
|
|
182
|
+
Data structure encoded in QR codes for wallet discovery:
|
|
183
|
+
|
|
184
|
+
```typescript
|
|
185
|
+
interface QRPayload {
|
|
186
|
+
version: number; // Protocol version
|
|
187
|
+
sessionId: string; // Session identifier
|
|
188
|
+
publicKey: string; // Public key for ECDHE
|
|
189
|
+
dappInfo: Pick<DAppMetadata, 'name' | 'url'>; // Essential dApp info
|
|
190
|
+
sessionConfig?: SessionConfig; // Session configuration
|
|
191
|
+
}
|
|
192
|
+
```
|
|
193
|
+
|
|
194
|
+
### Display Info
|
|
195
|
+
|
|
196
|
+
Information for displaying connection options to users:
|
|
197
|
+
|
|
198
|
+
```typescript
|
|
199
|
+
interface DisplayInfo {
|
|
200
|
+
qrCode: string; // QR code data URL (base64 PNG)
|
|
201
|
+
frutiLink: string; // FrutiLink emoji sequence
|
|
202
|
+
deepLink: string; // Deep link URL for mobile apps
|
|
203
|
+
}
|
|
204
|
+
```
|
|
205
|
+
|
|
206
|
+
### Relay Message
|
|
207
|
+
|
|
208
|
+
Message format for relay server communication:
|
|
209
|
+
|
|
210
|
+
```typescript
|
|
211
|
+
interface RelayMessage {
|
|
212
|
+
topic: string; // Session ID used as topic
|
|
213
|
+
type: 'pub' | 'sub' | 'ack' | 'error'; // Message type
|
|
214
|
+
payload?: EncryptedPayload; // Encrypted payload (optional)
|
|
215
|
+
id: string; // Message ID for acknowledgment
|
|
216
|
+
}
|
|
217
|
+
```
|
|
218
|
+
|
|
219
|
+
### Encrypted Payload
|
|
220
|
+
|
|
221
|
+
Encrypted message payload for secure communication:
|
|
222
|
+
|
|
223
|
+
```typescript
|
|
224
|
+
interface EncryptedPayload {
|
|
225
|
+
iv: string; // Base64 encoded initialization vector
|
|
226
|
+
ciphertext: string; // Base64 encoded ciphertext
|
|
227
|
+
mac: string; // Base64 encoded HMAC for integrity
|
|
228
|
+
}
|
|
229
|
+
```
|
|
230
|
+
|
|
231
|
+
---
|
|
232
|
+
|
|
233
|
+
## Authentication Types
|
|
234
|
+
|
|
235
|
+
### Session Info
|
|
236
|
+
|
|
237
|
+
Complete session information:
|
|
238
|
+
|
|
239
|
+
```typescript
|
|
240
|
+
interface SessionInfo {
|
|
241
|
+
sessionId: string; // Session identifier
|
|
242
|
+
state: 'pending' | 'connected' | 'disconnected' | 'expired' | 'error'; // Current state
|
|
243
|
+
address?: string; // Connected wallet address
|
|
244
|
+
dappId: string; // DApp identifier
|
|
245
|
+
dappInfo: Pick<DAppMetadata, 'name' | 'url'>; // Essential dApp info
|
|
246
|
+
sessionConfig?: SessionConfig; // Session configuration
|
|
247
|
+
createdAt: string; // Creation timestamp (ISO 8601)
|
|
248
|
+
lastActivity: string; // Last activity timestamp (ISO 8601)
|
|
249
|
+
expiresAt?: string; // Expiration timestamp (ISO 8601)
|
|
250
|
+
}
|
|
251
|
+
```
|
|
252
|
+
|
|
253
|
+
### Origin Proof
|
|
254
|
+
|
|
255
|
+
Proof of domain ownership for security verification:
|
|
256
|
+
|
|
257
|
+
```typescript
|
|
258
|
+
interface OriginProof {
|
|
259
|
+
domain: string; // Domain asserting ownership
|
|
260
|
+
timestamp: number; // Timestamp of the proof
|
|
261
|
+
signature: string; // Signature proving domain ownership
|
|
262
|
+
}
|
|
263
|
+
```
|
|
264
|
+
|
|
265
|
+
---
|
|
266
|
+
|
|
267
|
+
## Cryptographic Types
|
|
268
|
+
|
|
269
|
+
### Crypto Payload
|
|
270
|
+
|
|
271
|
+
Complete cryptographic payload specification:
|
|
272
|
+
|
|
273
|
+
```typescript
|
|
274
|
+
interface CryptoPayload {
|
|
275
|
+
version: '1.0'; // Schema version
|
|
276
|
+
keyExchange?: KeyExchange; // Key exchange algorithm
|
|
277
|
+
encryption: Encryption; // Encryption specification
|
|
278
|
+
publicKey?: PublicKeyJWK; // Public key in JWK format
|
|
279
|
+
parameters: CryptoParameters; // Algorithm parameters
|
|
280
|
+
derivation?: KeyDerivation; // Key derivation spec
|
|
281
|
+
}
|
|
282
|
+
```
|
|
283
|
+
|
|
284
|
+
### Key Exchange
|
|
285
|
+
|
|
286
|
+
ECDH key exchange specification:
|
|
287
|
+
|
|
288
|
+
```typescript
|
|
289
|
+
interface KeyExchange {
|
|
290
|
+
algorithm: 'ECDH'; // Elliptic Curve Diffie-Hellman
|
|
291
|
+
namedCurve: 'P-256'; // NIST P-256 curve (secp256r1)
|
|
292
|
+
}
|
|
293
|
+
```
|
|
294
|
+
|
|
295
|
+
### Encryption
|
|
296
|
+
|
|
297
|
+
Encryption algorithm specification:
|
|
298
|
+
|
|
299
|
+
```typescript
|
|
300
|
+
interface Encryption {
|
|
301
|
+
algorithm: 'AES-GCM' | 'plaintext'; // Encryption algorithm
|
|
302
|
+
keyLength?: 256; // AES key length in bits
|
|
303
|
+
tagLength?: 128; // GCM authentication tag length
|
|
304
|
+
}
|
|
305
|
+
```
|
|
306
|
+
|
|
307
|
+
### Public Key JWK
|
|
308
|
+
|
|
309
|
+
Public key in JSON Web Key format for ECDH:
|
|
310
|
+
|
|
311
|
+
```typescript
|
|
312
|
+
interface PublicKeyJWK {
|
|
313
|
+
kty: 'EC'; // Key type: Elliptic Curve
|
|
314
|
+
crv: 'P-256'; // Curve name
|
|
315
|
+
x: string; // X coordinate (base64url)
|
|
316
|
+
y: string; // Y coordinate (base64url)
|
|
317
|
+
use: 'enc'; // Intended use: encryption
|
|
318
|
+
key_ops: ['deriveKey']; // Permitted operations
|
|
319
|
+
}
|
|
320
|
+
```
|
|
321
|
+
|
|
322
|
+
### Key Derivation
|
|
323
|
+
|
|
324
|
+
HKDF key derivation specification:
|
|
325
|
+
|
|
326
|
+
```typescript
|
|
327
|
+
interface KeyDerivation {
|
|
328
|
+
algorithm: 'HKDF'; // HMAC-based Key Derivation Function
|
|
329
|
+
hash: 'SHA-256'; // Hash function for HKDF
|
|
330
|
+
info: 'message-exchange-v1'; // Application context info
|
|
331
|
+
salt: string; // Random salt (base64)
|
|
332
|
+
}
|
|
333
|
+
```
|
|
334
|
+
|
|
335
|
+
---
|
|
336
|
+
|
|
337
|
+
## Error Types
|
|
338
|
+
|
|
339
|
+
### BananaLink Error
|
|
340
|
+
|
|
341
|
+
Standardized error format:
|
|
342
|
+
|
|
343
|
+
```typescript
|
|
344
|
+
interface BananaLinkError {
|
|
345
|
+
code: BananaLinkErrorCode; // Standardized error code
|
|
346
|
+
message: string; // Human-readable error message
|
|
347
|
+
details?: any; // Additional error details
|
|
348
|
+
}
|
|
349
|
+
|
|
350
|
+
type BananaLinkErrorCode =
|
|
351
|
+
| 'USER_REJECTED' // User rejected the request
|
|
352
|
+
| 'INVALID_REQUEST' // Request format is invalid
|
|
353
|
+
| 'SESSION_EXPIRED' // Session has expired
|
|
354
|
+
| 'NETWORK_ERROR' // Network connection error
|
|
355
|
+
| 'UNSUPPORTED_METHOD' // Method not supported
|
|
356
|
+
| 'INVALID_SIGNATURE' // Signature validation failed
|
|
357
|
+
| 'ORIGIN_MISMATCH' // Origin verification failed
|
|
358
|
+
| 'RATE_LIMITED'; // Rate limit exceeded
|
|
359
|
+
```
|
|
360
|
+
|
|
361
|
+
---
|
|
362
|
+
|
|
363
|
+
## Constants
|
|
364
|
+
|
|
365
|
+
Key protocol constants are exported from `@bananalink-sdk/protocol/constants`:
|
|
366
|
+
|
|
367
|
+
```typescript
|
|
368
|
+
// Protocol identification
|
|
369
|
+
PROTOCOL_VERSION: 1
|
|
370
|
+
PACKAGE_NAME: '@bananalink-sdk/protocol'
|
|
371
|
+
DEEPLINK_SCHEME: 'bananalink'
|
|
372
|
+
|
|
373
|
+
// Timeouts (milliseconds)
|
|
374
|
+
DEFAULT_TIMEOUTS: {
|
|
375
|
+
sessionTimeout: 86400000 // 24 hours
|
|
376
|
+
requestTimeout: 300000 // 5 minutes
|
|
377
|
+
connectionTimeout: 30000 // 30 seconds
|
|
378
|
+
qrCodeTimeout: 120000 // 2 minutes
|
|
379
|
+
}
|
|
380
|
+
|
|
381
|
+
// Security limits
|
|
382
|
+
SECURITY_LIMITS: {
|
|
383
|
+
maxConcurrentSessions: 5
|
|
384
|
+
maxSessionAge: 604800000 // 7 days
|
|
385
|
+
minNonceLength: 8
|
|
386
|
+
maxMessageSize: 65536 // 64KB
|
|
387
|
+
maxResourcesCount: 10
|
|
388
|
+
}
|
|
389
|
+
|
|
390
|
+
// Cryptographic constants
|
|
391
|
+
CRYPTO_CONSTANTS: {
|
|
392
|
+
keyLength: 256 // AES-256
|
|
393
|
+
ivLength: 12 // GCM IV length
|
|
394
|
+
tagLength: 16 // GCM tag length
|
|
395
|
+
curve: 'P-256' // ECDH curve
|
|
396
|
+
algorithm: 'AES-GCM' // Encryption algorithm
|
|
397
|
+
hashAlgorithm: 'SHA-256' // Hash algorithm
|
|
398
|
+
}
|
|
399
|
+
```
|
|
400
|
+
|
|
401
|
+
---
|
|
402
|
+
|
|
403
|
+
## Validation Schemas
|
|
404
|
+
|
|
405
|
+
All types have corresponding Zod validation schemas for runtime validation:
|
|
406
|
+
|
|
407
|
+
```typescript
|
|
408
|
+
import {
|
|
409
|
+
bananaLinkMessageSchema,
|
|
410
|
+
dAppMetadataSchema,
|
|
411
|
+
sessionConfigSchema,
|
|
412
|
+
sessionOptionsSchema,
|
|
413
|
+
securityPolicySchema,
|
|
414
|
+
transactionPayloadSchema,
|
|
415
|
+
signPayloadSchema
|
|
416
|
+
} from '@bananalink-sdk/protocol/schemas';
|
|
417
|
+
|
|
418
|
+
// Validate a BananaLink message
|
|
419
|
+
const message = bananaLinkMessageSchema.parse(data);
|
|
420
|
+
|
|
421
|
+
// Safe parsing (returns result object)
|
|
422
|
+
const result = bananaLinkMessageSchema.safeParse(data);
|
|
423
|
+
if (result.success) {
|
|
424
|
+
console.log('Valid message:', result.data);
|
|
425
|
+
} else {
|
|
426
|
+
console.error('Validation errors:', result.error.issues);
|
|
427
|
+
}
|
|
428
|
+
```
|
|
429
|
+
|
|
430
|
+
### Validation Helpers
|
|
431
|
+
|
|
432
|
+
```typescript
|
|
433
|
+
import { validateMessage, safeValidateMessage } from '@bananalink-sdk/protocol/schemas';
|
|
434
|
+
|
|
435
|
+
// Throws on validation error
|
|
436
|
+
const validMessage = validateMessage(data);
|
|
437
|
+
|
|
438
|
+
// Returns safe parse result
|
|
439
|
+
const result = safeValidateMessage(data);
|
|
440
|
+
```
|
|
441
|
+
|
|
442
|
+
---
|
|
443
|
+
|
|
444
|
+
## Usage
|
|
445
|
+
|
|
446
|
+
```typescript
|
|
447
|
+
import type {
|
|
448
|
+
BananaLinkMessage,
|
|
449
|
+
DAppMetadata,
|
|
450
|
+
SessionConfig,
|
|
451
|
+
SessionOptions
|
|
452
|
+
} from '@bananalink-sdk/protocol/types';
|
|
453
|
+
|
|
454
|
+
import {
|
|
455
|
+
bananaLinkMessageSchema,
|
|
456
|
+
sessionOptionsSchema
|
|
457
|
+
} from '@bananalink-sdk/protocol/schemas';
|
|
458
|
+
|
|
459
|
+
import {
|
|
460
|
+
DEEPLINK_SCHEME,
|
|
461
|
+
DEFAULT_TIMEOUTS
|
|
462
|
+
} from '@bananalink-sdk/protocol/constants';
|
|
463
|
+
```
|
|
464
|
+
|
|
465
|
+
---
|
|
466
|
+
|
|
467
|
+
## Crypto Provider System
|
|
468
|
+
|
|
469
|
+
The protocol package includes a pluggable cryptographic provider system with support for multiple implementations. Crypto providers must be **explicitly imported** to be available.
|
|
470
|
+
|
|
471
|
+
### Available Providers
|
|
472
|
+
|
|
473
|
+
- **`noble`** - Pure JavaScript implementation (universal fallback, works everywhere)
|
|
474
|
+
- **`webcrypto`** - Browser Web Crypto API (fastest in browsers)
|
|
475
|
+
- **`node`** - Node.js native crypto (fastest in Node.js)
|
|
476
|
+
- **`quickcrypto`** - React Native optimized (for React Native environments)
|
|
477
|
+
|
|
478
|
+
### Explicit Provider Import
|
|
479
|
+
|
|
480
|
+
Providers use a registry pattern with side-effect imports. You must explicitly import each provider you want to use:
|
|
481
|
+
|
|
482
|
+
```typescript
|
|
483
|
+
// Import the crypto providers you need
|
|
484
|
+
import '@bananalink-sdk/protocol/crypto/provider/noble'; // Always recommended as fallback
|
|
485
|
+
import '@bananalink-sdk/protocol/crypto/provider/webcrypto'; // For browsers
|
|
486
|
+
import '@bananalink-sdk/protocol/crypto/provider/node'; // For Node.js
|
|
487
|
+
import '@bananalink-sdk/protocol/crypto/provider/quickcrypto'; // For React Native
|
|
488
|
+
|
|
489
|
+
// Now the providers are registered and available
|
|
490
|
+
import { createCryptoProvider } from '@bananalink-sdk/protocol/crypto';
|
|
491
|
+
|
|
492
|
+
// Create a provider (will use the first available in priority order)
|
|
493
|
+
const provider = createCryptoProvider();
|
|
494
|
+
|
|
495
|
+
// Or specify a provider explicitly
|
|
496
|
+
const nobleProvider = createCryptoProvider('noble');
|
|
497
|
+
```
|
|
498
|
+
|
|
499
|
+
### Why Explicit Imports?
|
|
500
|
+
|
|
501
|
+
This design provides several benefits:
|
|
502
|
+
|
|
503
|
+
1. **Tree Shaking** - Only bundle the providers you actually use
|
|
504
|
+
2. **Explicit Dependencies** - Clear which crypto implementations are needed
|
|
505
|
+
3. **Build-time Errors** - Catch missing providers during compilation, not runtime
|
|
506
|
+
4. **Bundle Size** - Reduce bundle size by excluding unused providers
|
|
507
|
+
5. **Environment Flexibility** - Each environment can import only what it needs
|
|
508
|
+
|
|
509
|
+
### Recommended Import Patterns
|
|
510
|
+
|
|
511
|
+
**For Web Applications:**
|
|
512
|
+
```typescript
|
|
513
|
+
import '@bananalink-sdk/protocol/crypto/provider/webcrypto';
|
|
514
|
+
import '@bananalink-sdk/protocol/crypto/provider/noble'; // Fallback
|
|
515
|
+
```
|
|
516
|
+
|
|
517
|
+
**For Node.js Applications:**
|
|
518
|
+
```typescript
|
|
519
|
+
import '@bananalink-sdk/protocol/crypto/provider/node';
|
|
520
|
+
import '@bananalink-sdk/protocol/crypto/provider/noble'; // Fallback
|
|
521
|
+
```
|
|
522
|
+
|
|
523
|
+
**For React Native Applications:**
|
|
524
|
+
```typescript
|
|
525
|
+
import '@bananalink-sdk/protocol/crypto/provider/quickcrypto';
|
|
526
|
+
import '@bananalink-sdk/protocol/crypto/provider/noble'; // Fallback
|
|
527
|
+
```
|
|
528
|
+
|
|
529
|
+
**For Universal/Isomorphic Applications:**
|
|
530
|
+
```typescript
|
|
531
|
+
import '@bananalink-sdk/protocol/crypto/provider/noble'; // Works everywhere
|
|
532
|
+
```
|
|
533
|
+
|
|
534
|
+
### Provider Operations
|
|
535
|
+
|
|
536
|
+
All providers implement the same `CryptoProvider` interface:
|
|
537
|
+
|
|
538
|
+
```typescript
|
|
539
|
+
interface CryptoProvider {
|
|
540
|
+
// Key operations
|
|
541
|
+
generateKeyPair(): Promise<ProviderKeyPair>;
|
|
542
|
+
deriveSharedSecret(privateKey: CryptoKeyLike, publicKey: CryptoKeyLike): Promise<ArrayBuffer>;
|
|
543
|
+
|
|
544
|
+
// Encryption
|
|
545
|
+
encrypt(key: CryptoKeyLike, plaintext: Uint8Array, iv: Uint8Array): Promise<ArrayBuffer>;
|
|
546
|
+
decrypt(key: CryptoKeyLike, ciphertext: Uint8Array, iv: Uint8Array): Promise<ArrayBuffer>;
|
|
547
|
+
|
|
548
|
+
// Key management
|
|
549
|
+
exportPublicKey(key: CryptoKeyLike): Promise<ArrayBuffer>;
|
|
550
|
+
importPublicKey(keyData: ArrayBuffer): Promise<CryptoKeyLike>;
|
|
551
|
+
deriveEncryptionKey(sharedSecret: ArrayBuffer, salt: Uint8Array, info: Uint8Array): Promise<CryptoKeyLike>;
|
|
552
|
+
|
|
553
|
+
// Utilities
|
|
554
|
+
randomBytes(length: number): Uint8Array;
|
|
555
|
+
isAvailable: boolean;
|
|
556
|
+
}
|
|
557
|
+
```
|
|
558
|
+
|
|
559
|
+
### Advanced Usage
|
|
560
|
+
|
|
561
|
+
**Check Registered Providers:**
|
|
562
|
+
```typescript
|
|
563
|
+
import { getRegisteredCryptoProviders } from '@bananalink-sdk/protocol/crypto';
|
|
564
|
+
|
|
565
|
+
const providers = getRegisteredCryptoProviders();
|
|
566
|
+
console.log('Available providers:', providers); // ['noble', 'webcrypto']
|
|
567
|
+
```
|
|
568
|
+
|
|
569
|
+
**Provider Diagnostics:**
|
|
570
|
+
```typescript
|
|
571
|
+
import { testProvider, diagnoseEnvironment } from '@bananalink-sdk/protocol/crypto';
|
|
572
|
+
|
|
573
|
+
// Test a specific provider
|
|
574
|
+
const result = await testProvider('noble');
|
|
575
|
+
console.log('Provider test:', result.success ? '✅' : '❌');
|
|
576
|
+
|
|
577
|
+
// Full environment diagnostics
|
|
578
|
+
const diag = await diagnoseEnvironment();
|
|
579
|
+
console.log(diag.toMarkdown()); // Detailed report
|
|
580
|
+
```
|
|
581
|
+
|
|
582
|
+
**Compliance Wrapper:**
|
|
583
|
+
```typescript
|
|
584
|
+
import { ComplianceCryptoProvider } from '@bananalink-sdk/protocol/crypto';
|
|
585
|
+
|
|
586
|
+
const baseProvider = createCryptoProvider('noble');
|
|
587
|
+
const compliantProvider = new ComplianceCryptoProvider(baseProvider, {
|
|
588
|
+
enabled: true,
|
|
589
|
+
sessionId: 'my-session',
|
|
590
|
+
strictMode: true
|
|
591
|
+
});
|
|
592
|
+
```
|
|
593
|
+
|
|
594
|
+
---
|
|
595
|
+
|
|
596
|
+
## Design Principles
|
|
597
|
+
|
|
598
|
+
1. **Type Safety**: All interfaces are strictly typed with comprehensive validation
|
|
599
|
+
2. **Separation of Concerns**: DApp metadata vs session configuration are distinct
|
|
600
|
+
3. **Security First**: Built-in encryption, origin verification, and rate limiting
|
|
601
|
+
4. **Developer Experience**: Clear, documented interfaces with helpful validation errors
|
|
602
|
+
5. **Extensibility**: Modular design allows for future protocol enhancements
|
|
603
|
+
|
|
604
|
+
For more information, see the [Architecture Documentation](../../ARCHITECTURE.md).
|