@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.
Files changed (158) hide show
  1. package/README.md +604 -0
  2. package/dist/chunk-32OWUOZ3.js +308 -0
  3. package/dist/chunk-32OWUOZ3.js.map +1 -0
  4. package/dist/chunk-65HNHRJK.cjs +123 -0
  5. package/dist/chunk-65HNHRJK.cjs.map +1 -0
  6. package/dist/chunk-7KYDLL3B.js +480 -0
  7. package/dist/chunk-7KYDLL3B.js.map +1 -0
  8. package/dist/chunk-A6FLEJ7R.cjs +62 -0
  9. package/dist/chunk-A6FLEJ7R.cjs.map +1 -0
  10. package/dist/chunk-CUJK7ZTS.js +217 -0
  11. package/dist/chunk-CUJK7ZTS.js.map +1 -0
  12. package/dist/chunk-GI3BUPIH.cjs +236 -0
  13. package/dist/chunk-GI3BUPIH.cjs.map +1 -0
  14. package/dist/chunk-JXHV66Q4.js +106 -0
  15. package/dist/chunk-JXHV66Q4.js.map +1 -0
  16. package/dist/chunk-KNGZKGRS.cjs +552 -0
  17. package/dist/chunk-KNGZKGRS.cjs.map +1 -0
  18. package/dist/chunk-LELPCIE7.js +840 -0
  19. package/dist/chunk-LELPCIE7.js.map +1 -0
  20. package/dist/chunk-MCZG7QEM.cjs +310 -0
  21. package/dist/chunk-MCZG7QEM.cjs.map +1 -0
  22. package/dist/chunk-TCVKC227.js +56 -0
  23. package/dist/chunk-TCVKC227.js.map +1 -0
  24. package/dist/chunk-VXLUSU5B.cjs +856 -0
  25. package/dist/chunk-VXLUSU5B.cjs.map +1 -0
  26. package/dist/chunk-WCQVDF3K.js +12 -0
  27. package/dist/chunk-WCQVDF3K.js.map +1 -0
  28. package/dist/chunk-WGEGR3DF.cjs +15 -0
  29. package/dist/chunk-WGEGR3DF.cjs.map +1 -0
  30. package/dist/client-session-claim-3QF3noOr.d.ts +197 -0
  31. package/dist/client-session-claim-C4lUik3b.d.cts +197 -0
  32. package/dist/core-DMhuNfoz.d.cts +62 -0
  33. package/dist/core-DMhuNfoz.d.ts +62 -0
  34. package/dist/crypto/providers/noble-provider.cjs +14 -0
  35. package/dist/crypto/providers/noble-provider.cjs.map +1 -0
  36. package/dist/crypto/providers/noble-provider.d.cts +30 -0
  37. package/dist/crypto/providers/noble-provider.d.ts +30 -0
  38. package/dist/crypto/providers/noble-provider.js +5 -0
  39. package/dist/crypto/providers/noble-provider.js.map +1 -0
  40. package/dist/crypto/providers/node-provider.cjs +308 -0
  41. package/dist/crypto/providers/node-provider.cjs.map +1 -0
  42. package/dist/crypto/providers/node-provider.d.cts +32 -0
  43. package/dist/crypto/providers/node-provider.d.ts +32 -0
  44. package/dist/crypto/providers/node-provider.js +306 -0
  45. package/dist/crypto/providers/node-provider.js.map +1 -0
  46. package/dist/crypto/providers/quickcrypto-provider.cjs +339 -0
  47. package/dist/crypto/providers/quickcrypto-provider.cjs.map +1 -0
  48. package/dist/crypto/providers/quickcrypto-provider.d.cts +34 -0
  49. package/dist/crypto/providers/quickcrypto-provider.d.ts +34 -0
  50. package/dist/crypto/providers/quickcrypto-provider.js +337 -0
  51. package/dist/crypto/providers/quickcrypto-provider.js.map +1 -0
  52. package/dist/crypto/providers/webcrypto-provider.cjs +310 -0
  53. package/dist/crypto/providers/webcrypto-provider.cjs.map +1 -0
  54. package/dist/crypto/providers/webcrypto-provider.d.cts +30 -0
  55. package/dist/crypto/providers/webcrypto-provider.d.ts +30 -0
  56. package/dist/crypto/providers/webcrypto-provider.js +308 -0
  57. package/dist/crypto/providers/webcrypto-provider.js.map +1 -0
  58. package/dist/crypto-BUS06Qz-.d.cts +40 -0
  59. package/dist/crypto-BUS06Qz-.d.ts +40 -0
  60. package/dist/crypto-export.cjs +790 -0
  61. package/dist/crypto-export.cjs.map +1 -0
  62. package/dist/crypto-export.d.cts +257 -0
  63. package/dist/crypto-export.d.ts +257 -0
  64. package/dist/crypto-export.js +709 -0
  65. package/dist/crypto-export.js.map +1 -0
  66. package/dist/crypto-provider-deYoVIxi.d.cts +36 -0
  67. package/dist/crypto-provider-deYoVIxi.d.ts +36 -0
  68. package/dist/index.cjs +615 -0
  69. package/dist/index.cjs.map +1 -0
  70. package/dist/index.d.cts +379 -0
  71. package/dist/index.d.ts +379 -0
  72. package/dist/index.js +504 -0
  73. package/dist/index.js.map +1 -0
  74. package/dist/schemas-export.cjs +294 -0
  75. package/dist/schemas-export.cjs.map +1 -0
  76. package/dist/schemas-export.d.cts +1598 -0
  77. package/dist/schemas-export.d.ts +1598 -0
  78. package/dist/schemas-export.js +5 -0
  79. package/dist/schemas-export.js.map +1 -0
  80. package/dist/siwe-export.cjs +237 -0
  81. package/dist/siwe-export.cjs.map +1 -0
  82. package/dist/siwe-export.d.cts +27 -0
  83. package/dist/siwe-export.d.ts +27 -0
  84. package/dist/siwe-export.js +228 -0
  85. package/dist/siwe-export.js.map +1 -0
  86. package/dist/testing.cjs +54 -0
  87. package/dist/testing.cjs.map +1 -0
  88. package/dist/testing.d.cts +20 -0
  89. package/dist/testing.d.ts +20 -0
  90. package/dist/testing.js +51 -0
  91. package/dist/testing.js.map +1 -0
  92. package/dist/validation-export.cjs +359 -0
  93. package/dist/validation-export.cjs.map +1 -0
  94. package/dist/validation-export.d.cts +3 -0
  95. package/dist/validation-export.d.ts +3 -0
  96. package/dist/validation-export.js +6 -0
  97. package/dist/validation-export.js.map +1 -0
  98. package/dist/validators-export.cjs +73 -0
  99. package/dist/validators-export.cjs.map +1 -0
  100. package/dist/validators-export.d.cts +37 -0
  101. package/dist/validators-export.d.ts +37 -0
  102. package/dist/validators-export.js +4 -0
  103. package/dist/validators-export.js.map +1 -0
  104. package/package.json +140 -0
  105. package/src/constants/index.ts +205 -0
  106. package/src/crypto/context.ts +228 -0
  107. package/src/crypto/diagnostics.ts +772 -0
  108. package/src/crypto/errors.ts +114 -0
  109. package/src/crypto/index.ts +89 -0
  110. package/src/crypto/payload-handler.ts +102 -0
  111. package/src/crypto/providers/compliance-provider.ts +579 -0
  112. package/src/crypto/providers/factory.ts +204 -0
  113. package/src/crypto/providers/index.ts +44 -0
  114. package/src/crypto/providers/noble-provider.ts +392 -0
  115. package/src/crypto/providers/node-provider.ts +433 -0
  116. package/src/crypto/providers/quickcrypto-provider.ts +483 -0
  117. package/src/crypto/providers/registry.ts +129 -0
  118. package/src/crypto/providers/webcrypto-provider.ts +364 -0
  119. package/src/crypto/session-security.ts +185 -0
  120. package/src/crypto/types.ts +93 -0
  121. package/src/crypto/utils.ts +190 -0
  122. package/src/crypto-export.ts +21 -0
  123. package/src/index.ts +38 -0
  124. package/src/schemas/auth.ts +60 -0
  125. package/src/schemas/client-messages.ts +57 -0
  126. package/src/schemas/core.ts +144 -0
  127. package/src/schemas/crypto.ts +65 -0
  128. package/src/schemas/discovery.ts +79 -0
  129. package/src/schemas/index.ts +239 -0
  130. package/src/schemas/relay-messages.ts +45 -0
  131. package/src/schemas/wallet-messages.ts +177 -0
  132. package/src/schemas-export.ts +23 -0
  133. package/src/siwe-export.ts +27 -0
  134. package/src/testing.ts +71 -0
  135. package/src/types/auth.ts +60 -0
  136. package/src/types/client-messages.ts +84 -0
  137. package/src/types/core.ts +131 -0
  138. package/src/types/crypto-provider.ts +264 -0
  139. package/src/types/crypto.ts +90 -0
  140. package/src/types/discovery.ts +50 -0
  141. package/src/types/errors.ts +87 -0
  142. package/src/types/index.ts +197 -0
  143. package/src/types/post-auth-operations.ts +363 -0
  144. package/src/types/providers.ts +72 -0
  145. package/src/types/relay-messages.ts +60 -0
  146. package/src/types/request-lifecycle.ts +161 -0
  147. package/src/types/signing-operations.ts +99 -0
  148. package/src/types/wallet-messages.ts +251 -0
  149. package/src/utils/client-session-claim.ts +188 -0
  150. package/src/utils/index.ts +54 -0
  151. package/src/utils/public-keys.ts +49 -0
  152. package/src/utils/siwe.ts +362 -0
  153. package/src/utils/url-decoding.ts +126 -0
  154. package/src/utils/url-encoding.ts +144 -0
  155. package/src/utils/wallet-session-claim.ts +188 -0
  156. package/src/validation-export.ts +32 -0
  157. package/src/validators/index.ts +222 -0
  158. package/src/validators-export.ts +8 -0
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/crypto/providers/registry.ts"],"names":["__name"],"mappings":";;;;;AAmBA,IAAM,eAAA,uBAAsB,GAAA,EAA+C;AAkBpE,SAAS,sBAAA,CACd,MACA,OAAA,EACM;AAEN,EAAA,IAAI,eAAA,CAAgB,GAAA,CAAI,IAAI,CAAA,EAAG;AAC7B,IAAA;AAAA,EACF;AACA,EAAA,eAAA,CAAgB,GAAA,CAAI,MAAM,OAAO,CAAA;AACnC;AATgBA,wBAAA,CAAA,sBAAA,EAAA,wBAAA,CAAA;AAkBT,SAAS,yBAAyB,IAAA,EAAiD;AACxF,EAAA,MAAM,OAAA,GAAU,eAAA,CAAgB,GAAA,CAAI,IAAI,CAAA;AAExC,EAAA,IAAI,CAAC,OAAA,EAAS;AACZ,IAAA,MAAM,kBAAA,GAAqB,MAAM,IAAA,CAAK,eAAA,CAAgB,MAAM,CAAA,CAAE,KAAK,IAAI,CAAA;AACvE,IAAA,MAAM,UAAA,GAAa,cAAc,IAAI,CAAA;AAErC,IAAA,MAAM,IAAI,KAAA;AAAA,MACR,CAAA,iBAAA,EAAoB,IAAI,CAAA,qBAAA,EAAwB,UAAU;AAAA,qBAAA,EAClC,sBAAsB,MAAM;AAAA,iDAAA;AAAA,KAEtD;AAAA,EACF;AAEA,EAAA,OAAO,OAAA;AACT;AAfgBA,wBAAA,CAAA,wBAAA,EAAA,0BAAA,CAAA;AAuBT,SAAS,2BAA2B,IAAA,EAAmC;AAC5E,EAAA,OAAO,eAAA,CAAgB,IAAI,IAAI,CAAA;AACjC;AAFgBA,wBAAA,CAAA,0BAAA,EAAA,4BAAA,CAAA;AAST,SAAS,4BAAA,GAAqD;AACnE,EAAA,OAAO,KAAA,CAAM,IAAA,CAAK,eAAA,CAAgB,IAAA,EAAM,CAAA;AAC1C;AAFgBA,wBAAA,CAAA,4BAAA,EAAA,8BAAA,CAAA;AAOT,SAAS,2BAAA,GAAoC;AAClD,EAAA,eAAA,CAAgB,KAAA,EAAM;AACxB;AAFgBA,wBAAA,CAAA,2BAAA,EAAA,6BAAA,CAAA;AAOhB,SAAS,cAAc,IAAA,EAAkC;AACvD,EAAA,QAAQ,IAAA;AAAM,IACZ,KAAK,OAAA;AACH,MAAA,OAAO,4EAAA;AAAA,IACT,KAAK,aAAA;AACH,MAAA,OAAO,kFAAA;AAAA,IACT,KAAK,WAAA;AACH,MAAA,OAAO,gFAAA;AAAA,IACT,KAAK,MAAA;AACH,MAAA,OAAO,2EAAA;AAAA,IACT;AACE,MAAA,OAAO,CAAA,8BAAA,EAAiC,MAAA,CAAO,IAAI,CAAC,CAAA,WAAA,CAAA;AAAA;AAE1D;AAbSA,wBAAA,CAAA,aAAA,EAAA,eAAA,CAAA","file":"chunk-A6FLEJ7R.cjs","sourcesContent":["/**\n * Global registry for crypto providers\n *\n * This registry allows providers to self-register when imported,\n * enabling explicit import patterns while maintaining the factory pattern\n * internally within BananaLink and BananaWallet classes.\n */\n\nimport type { CryptoProvider, CryptoProviderType } from '../../types/crypto-provider';\nimport type { Logger } from '@bananalink-sdk/logger';\n\n/**\n * Factory function type for creating crypto provider instances\n */\nexport type CryptoProviderFactory = (logger?: Logger) => CryptoProvider;\n\n/**\n * Global registry storing available crypto providers\n */\nconst cryptoProviders = new Map<CryptoProviderType, CryptoProviderFactory>();\n\n/**\n * Register a crypto provider factory\n * Called automatically when a provider module is imported\n *\n * This function is idempotent - calling it multiple times with the same type\n * will only register the provider once.\n *\n * @param type - The provider type identifier\n * @param factory - Factory function that creates provider instances\n *\n * @example\n * ```typescript\n * // In noble-provider.ts\n * registerCryptoProvider('noble', (logger) => new NobleCryptoProvider(logger));\n * ```\n */\nexport function registerCryptoProvider(\n type: CryptoProviderType,\n factory: CryptoProviderFactory\n): void {\n // Skip if already registered (idempotent)\n if (cryptoProviders.has(type)) {\n return;\n }\n cryptoProviders.set(type, factory);\n}\n\n/**\n * Get a registered crypto provider factory\n *\n * @param type - The provider type to retrieve\n * @returns The provider factory function\n * @throws Error if the provider is not registered\n */\nexport function getCryptoProviderFactory(type: CryptoProviderType): CryptoProviderFactory {\n const factory = cryptoProviders.get(type);\n\n if (!factory) {\n const availableProviders = Array.from(cryptoProviders.keys()).join(', ');\n const importHint = getImportHint(type);\n\n throw new Error(\n `Crypto provider '${type}' is not registered. ${importHint}\\n` +\n `Available providers: ${availableProviders || 'none'}\\n` +\n `Make sure to import the provider before using it.`\n );\n }\n\n return factory;\n}\n\n/**\n * Check if a crypto provider is registered\n *\n * @param type - The provider type to check\n * @returns True if the provider is registered\n */\nexport function isCryptoProviderRegistered(type: CryptoProviderType): boolean {\n return cryptoProviders.has(type);\n}\n\n/**\n * Get all registered crypto provider types\n *\n * @returns Array of registered provider types\n */\nexport function getRegisteredCryptoProviders(): CryptoProviderType[] {\n return Array.from(cryptoProviders.keys());\n}\n\n/**\n * Clear all registered providers (useful for testing)\n */\nexport function clearCryptoProviderRegistry(): void {\n cryptoProviders.clear();\n}\n\n/**\n * Get import hint for a specific provider type\n */\nfunction getImportHint(type: CryptoProviderType): string {\n switch (type) {\n case 'noble':\n return \"Did you forget to import '@bananalink-sdk/protocol/crypto/provider/noble'?\";\n case 'quickcrypto':\n return \"Did you forget to import '@bananalink-sdk/protocol/crypto/provider/quickcrypto'?\";\n case 'webcrypto':\n return \"Did you forget to import '@bananalink-sdk/protocol/crypto/provider/webcrypto'?\";\n case 'node':\n return \"Did you forget to import '@bananalink-sdk/protocol/crypto/provider/node'?\";\n default:\n return `Did you forget to import the '${String(type)}' provider?`;\n }\n}\n\n/**\n * Type augmentation for registered providers\n * This allows TypeScript to track which providers are available\n */\ndeclare global {\n // eslint-disable-next-line @typescript-eslint/no-namespace\n namespace BananaLink {\n // eslint-disable-next-line @typescript-eslint/no-empty-object-type\n interface RegisteredCryptoProviders {\n // This will be augmented by each provider module\n }\n }\n}\n"]}
@@ -0,0 +1,217 @@
1
+ // src/constants/index.ts
2
+ var PROTOCOL_VERSION = 1;
3
+ var PACKAGE_NAME = "@bananalink-sdk/protocol";
4
+ var DEEPLINK_SCHEME = "bananalink";
5
+ var DEFAULT_RELAY_URL = "wss://relay.banana.link/v1";
6
+ var FRUITS = [
7
+ "\u{1F34C}",
8
+ "\u{1F34E}",
9
+ "\u{1F34A}",
10
+ "\u{1F347}",
11
+ "\u{1F353}",
12
+ "\u{1F351}",
13
+ "\u{1F352}",
14
+ "\u{1F349}",
15
+ "\u{1F95D}",
16
+ "\u{1F34D}",
17
+ "\u{1F96D}",
18
+ "\u{1F965}",
19
+ "\u{1FAD0}",
20
+ "\u{1F348}",
21
+ "\u{1F34B}",
22
+ "\u{1F951}"
23
+ ];
24
+ var DEFAULT_TIMEOUTS = {
25
+ sessionTimeout: 24 * 60 * 60 * 1e3,
26
+ // 24 hours
27
+ requestTimeout: 5 * 60 * 1e3,
28
+ // 5 minutes
29
+ connectionTimeout: 30 * 1e3,
30
+ // 30 seconds
31
+ qrCodeTimeout: 2 * 60 * 1e3
32
+ // 2 minutes
33
+ };
34
+ var PROTOCOL_V2_TIMEOUTS = {
35
+ sessionCreation: 5 * 1e3,
36
+ // 5 seconds - API Gateway response
37
+ claimSession: 10 * 1e3,
38
+ // 10 seconds - Wallet claims ownership
39
+ prefetchMetadata: 5 * 1e3,
40
+ // 5 seconds - Fetch dApp info
41
+ userApproval: 5 * 60 * 1e3,
42
+ // 5 minutes - User decision time
43
+ authentication: 30 * 1e3,
44
+ // 30 seconds - Sign and send
45
+ sessionTTL: 10800 * 1e3,
46
+ // 10800 seconds (3 hours) - Max session lifetime
47
+ reconnectionWindow: 10800 * 1e3,
48
+ // 10800 seconds (3 hours) - Same as session TTL
49
+ messageQueueRetention: 10800 * 1e3,
50
+ // 10800 seconds (3 hours) - Matches session TTL
51
+ websocketHeartbeat: 30 * 1e3,
52
+ // 30 seconds - Keep-alive ping
53
+ gracefulCloseTimeout: 5 * 1e3,
54
+ // 5 seconds - close_session ack wait
55
+ // Post-authentication operation timeouts (v2.1+)
56
+ signMessage: 60 * 1e3,
57
+ // 60 seconds - personal_sign operation
58
+ signTypedData: 90 * 1e3,
59
+ // 90 seconds - eth_signTypedData_v4 operation
60
+ signTransaction: 120 * 1e3
61
+ // 120 seconds - Transaction signing
62
+ };
63
+ var MESSAGE_QUEUE_CONFIG = {
64
+ maxQueueSize: 100,
65
+ // Maximum messages per direction
66
+ retentionTime: 10800 * 1e3,
67
+ // 10800 seconds (3 hours) - Matches session TTL
68
+ overflowStrategy: "drop_oldest"
69
+ // Drop oldest messages when queue is full
70
+ };
71
+ var SECURITY_LIMITS = {
72
+ maxConcurrentSessions: 5,
73
+ maxSessionAge: 7 * 24 * 60 * 60 * 1e3,
74
+ // 7 days
75
+ minNonceLength: 8,
76
+ maxMessageSize: 64 * 1024,
77
+ // 64KB
78
+ maxResourcesCount: 10,
79
+ rateLimit: {
80
+ requestsPerMinute: 60,
81
+ sessionsPerHour: 100
82
+ }
83
+ };
84
+ var CRYPTO_CONSTANTS = {
85
+ keyLength: 256,
86
+ // AES-256
87
+ ivLength: 12,
88
+ // GCM IV length
89
+ tagLength: 16,
90
+ // GCM tag length
91
+ curve: "P-256",
92
+ // ECDH curve
93
+ algorithm: "AES-GCM",
94
+ // Encryption algorithm
95
+ hashAlgorithm: "SHA-256"
96
+ // Hash algorithm
97
+ };
98
+ var MESSAGE_FORMAT = {
99
+ version: "1",
100
+ encoding: "utf8",
101
+ lineBreak: "\n",
102
+ resourcePrefix: "- "
103
+ };
104
+ var WS_MESSAGE_TYPES = {
105
+ subscribe: "sub",
106
+ publish: "pub",
107
+ acknowledge: "ack",
108
+ error: "error"
109
+ };
110
+ var HTTP_ENDPOINTS = {
111
+ messages: "/v1/messages",
112
+ session: "/v1/session",
113
+ health: "/v1/health"
114
+ };
115
+ var ERROR_MESSAGES = {
116
+ // Session errors
117
+ SESSION_EXPIRED: "Session has expired",
118
+ SESSION_NOT_FOUND: "Session ID invalid or expired",
119
+ SESSION_ALREADY_CLAIMED: "Session already claimed by another wallet",
120
+ INVALID_SESSION_CLAIM: "Wallet does not own this session",
121
+ INVALID_CLIENT_CLAIM: "Client session claim does not match",
122
+ SESSION_TOKEN_EXPIRED: "Session token TTL exceeded",
123
+ SESSION_CLOSED: "Session has been closed",
124
+ // Encryption errors
125
+ ENCRYPTION_FAILED: "Message encryption failed",
126
+ DECRYPTION_FAILED: "Cannot decrypt message",
127
+ INVALID_SIGNATURE: "Invalid signature",
128
+ // Network errors
129
+ NETWORK_ERROR: "Network connection error",
130
+ RELAY_ERROR: "Internal relay server error",
131
+ MESSAGE_QUEUE_FULL: "Too many queued messages (>100)",
132
+ RATE_LIMIT_EXCEEDED: "Rate limit exceeded",
133
+ ORIGIN_MISMATCH: "Origin verification failed",
134
+ // Request lifecycle errors (v2.1+)
135
+ REQUEST_PENDING: "Another signing request is already pending",
136
+ REQUEST_NOT_FOUND: "Request ID not found or already processed",
137
+ REQUEST_EXPIRED: "Request expired before completion",
138
+ REQUEST_INVALID: "Request data is invalid or malformed",
139
+ REQUEST_TIMEOUT: "Request timed out waiting for wallet response",
140
+ // Operation-specific errors (v2.1+)
141
+ SIGNING_FAILED: "Cryptographic signing operation failed",
142
+ SIGNING_REJECTED: "User rejected the signing request",
143
+ TRANSACTION_INVALID: "Transaction parameters validation failed",
144
+ CHAIN_MISMATCH: "Requested chain ID does not match wallet chain"
145
+ };
146
+ var QR_CONFIG = {
147
+ size: 256,
148
+ margin: 4,
149
+ errorCorrectionLevel: "M",
150
+ type: "image/png"
151
+ };
152
+ var DEEP_LINK_CONFIG = {
153
+ scheme: DEEPLINK_SCHEME,
154
+ host: "connect",
155
+ universal: "https://bananalink.app"
156
+ };
157
+ var NETWORK_CONFIG = {
158
+ SUPPORTED_CHAINS: [
159
+ 1,
160
+ // Ethereum Mainnet
161
+ 5,
162
+ // Goerli Testnet
163
+ 137,
164
+ // Polygon Mainnet
165
+ 80001,
166
+ // Polygon Mumbai Testnet
167
+ 42161,
168
+ // Arbitrum One
169
+ 421613,
170
+ // Arbitrum Goerli
171
+ 10,
172
+ // Optimism
173
+ 420
174
+ // Optimism Goerli
175
+ ],
176
+ DEFAULT_CHAIN_ID: 1,
177
+ CHAIN_NAMES: {
178
+ 1: "Ethereum Mainnet",
179
+ 5: "Goerli Testnet",
180
+ 137: "Polygon Mainnet",
181
+ 80001: "Polygon Mumbai",
182
+ 42161: "Arbitrum One",
183
+ 421613: "Arbitrum Goerli",
184
+ 10: "Optimism",
185
+ 420: "Optimism Goerli"
186
+ }
187
+ };
188
+ var DEV_CONFIG = {
189
+ logLevel: "debug",
190
+ enableMocks: false,
191
+ skipValidation: false,
192
+ allowLocalhost: true
193
+ };
194
+ var BANANALINK_CONSTANTS = {
195
+ PROTOCOL_VERSION,
196
+ PACKAGE_NAME,
197
+ DEEPLINK_SCHEME,
198
+ DEFAULT_RELAY_URL,
199
+ FRUITS,
200
+ DEFAULT_TIMEOUTS,
201
+ PROTOCOL_V2_TIMEOUTS,
202
+ MESSAGE_QUEUE_CONFIG,
203
+ SECURITY_LIMITS,
204
+ CRYPTO_CONSTANTS,
205
+ MESSAGE_FORMAT,
206
+ WS_MESSAGE_TYPES,
207
+ HTTP_ENDPOINTS,
208
+ ERROR_MESSAGES,
209
+ QR_CONFIG,
210
+ DEEP_LINK_CONFIG,
211
+ NETWORK_CONFIG,
212
+ DEV_CONFIG
213
+ };
214
+
215
+ export { BANANALINK_CONSTANTS, CRYPTO_CONSTANTS, DEEPLINK_SCHEME, DEEP_LINK_CONFIG, DEFAULT_RELAY_URL, DEFAULT_TIMEOUTS, DEV_CONFIG, ERROR_MESSAGES, FRUITS, HTTP_ENDPOINTS, MESSAGE_FORMAT, MESSAGE_QUEUE_CONFIG, NETWORK_CONFIG, PROTOCOL_V2_TIMEOUTS, PROTOCOL_VERSION, QR_CONFIG, SECURITY_LIMITS, WS_MESSAGE_TYPES };
216
+ //# sourceMappingURL=chunk-CUJK7ZTS.js.map
217
+ //# sourceMappingURL=chunk-CUJK7ZTS.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/constants/index.ts"],"names":[],"mappings":"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","file":"chunk-CUJK7ZTS.js","sourcesContent":["/**\n * Constants for the BananaLink protocol\n * Contains protocol version, URLs, timeouts, and other configuration values\n */\n\n// Protocol version and identification\nexport const PROTOCOL_VERSION = 1;\nexport const PACKAGE_NAME = '@bananalink-sdk/protocol';\nexport const DEEPLINK_SCHEME = 'bananalink';\n\n// Default relay server configuration\nexport const DEFAULT_RELAY_URL = 'wss://relay.banana.link/v1';\n\n// FrutiLink emoji set (16 fruits for 4 bits each)\nexport const FRUITS = [\n '🍌', '🍎', '🍊', '🍇', '🍓', '🍑', '🍒', '🍉',\n '🥝', '🍍', '🥭', '🥥', '🫐', '🍈', '🍋', '🥑'\n] as const;\n\n// Timeout configurations (in milliseconds)\nexport const DEFAULT_TIMEOUTS = {\n sessionTimeout: 24 * 60 * 60 * 1000, // 24 hours\n requestTimeout: 5 * 60 * 1000, // 5 minutes\n connectionTimeout: 30 * 1000, // 30 seconds\n qrCodeTimeout: 2 * 60 * 1000, // 2 minutes\n} as const;\n\n// Protocol v2.0 specific timeouts (in milliseconds)\n// Based on PROTOCOL.md specification\nexport const PROTOCOL_V2_TIMEOUTS = {\n sessionCreation: 5 * 1000, // 5 seconds - API Gateway response\n claimSession: 10 * 1000, // 10 seconds - Wallet claims ownership\n prefetchMetadata: 5 * 1000, // 5 seconds - Fetch dApp info\n userApproval: 5 * 60 * 1000, // 5 minutes - User decision time\n authentication: 30 * 1000, // 30 seconds - Sign and send\n sessionTTL: 10800 * 1000, // 10800 seconds (3 hours) - Max session lifetime\n reconnectionWindow: 10800 * 1000, // 10800 seconds (3 hours) - Same as session TTL\n messageQueueRetention: 10800 * 1000, // 10800 seconds (3 hours) - Matches session TTL\n websocketHeartbeat: 30 * 1000, // 30 seconds - Keep-alive ping\n gracefulCloseTimeout: 5 * 1000, // 5 seconds - close_session ack wait\n // Post-authentication operation timeouts (v2.1+)\n signMessage: 60 * 1000, // 60 seconds - personal_sign operation\n signTypedData: 90 * 1000, // 90 seconds - eth_signTypedData_v4 operation\n signTransaction: 120 * 1000, // 120 seconds - Transaction signing\n} as const;\n\n// Message queue configuration\nexport const MESSAGE_QUEUE_CONFIG = {\n maxQueueSize: 100, // Maximum messages per direction\n retentionTime: 10800 * 1000, // 10800 seconds (3 hours) - Matches session TTL\n overflowStrategy: 'drop_oldest', // Drop oldest messages when queue is full\n} as const;\n\n// Security limits and constraints\nexport const SECURITY_LIMITS = {\n maxConcurrentSessions: 5,\n maxSessionAge: 7 * 24 * 60 * 60 * 1000, // 7 days\n minNonceLength: 8,\n maxMessageSize: 64 * 1024, // 64KB\n maxResourcesCount: 10,\n rateLimit: {\n requestsPerMinute: 60,\n sessionsPerHour: 100,\n },\n} as const;\n\n// Cryptographic constants\nexport const CRYPTO_CONSTANTS = {\n keyLength: 256, // AES-256\n ivLength: 12, // GCM IV length\n tagLength: 16, // GCM tag length\n curve: 'P-256', // ECDH curve\n algorithm: 'AES-GCM', // Encryption algorithm\n hashAlgorithm: 'SHA-256', // Hash algorithm\n} as const;\n\n// Message format constants\nexport const MESSAGE_FORMAT = {\n version: '1',\n encoding: 'utf8',\n lineBreak: '\\n',\n resourcePrefix: '- ',\n} as const;\n\n// WebSocket message types\nexport const WS_MESSAGE_TYPES = {\n subscribe: 'sub',\n publish: 'pub',\n acknowledge: 'ack',\n error: 'error',\n} as const;\n\n// HTTP endpoints for fallback\nexport const HTTP_ENDPOINTS = {\n messages: '/v1/messages',\n session: '/v1/session',\n health: '/v1/health',\n} as const;\n\n// Error messages (organized hierarchically)\nexport const ERROR_MESSAGES = {\n // Session errors\n SESSION_EXPIRED: 'Session has expired',\n SESSION_NOT_FOUND: 'Session ID invalid or expired',\n SESSION_ALREADY_CLAIMED: 'Session already claimed by another wallet',\n INVALID_SESSION_CLAIM: 'Wallet does not own this session',\n INVALID_CLIENT_CLAIM: 'Client session claim does not match',\n SESSION_TOKEN_EXPIRED: 'Session token TTL exceeded',\n SESSION_CLOSED: 'Session has been closed',\n\n // Encryption errors\n ENCRYPTION_FAILED: 'Message encryption failed',\n DECRYPTION_FAILED: 'Cannot decrypt message',\n INVALID_SIGNATURE: 'Invalid signature',\n\n // Network errors\n NETWORK_ERROR: 'Network connection error',\n RELAY_ERROR: 'Internal relay server error',\n MESSAGE_QUEUE_FULL: 'Too many queued messages (>100)',\n RATE_LIMIT_EXCEEDED: 'Rate limit exceeded',\n ORIGIN_MISMATCH: 'Origin verification failed',\n\n // Request lifecycle errors (v2.1+)\n REQUEST_PENDING: 'Another signing request is already pending',\n REQUEST_NOT_FOUND: 'Request ID not found or already processed',\n REQUEST_EXPIRED: 'Request expired before completion',\n REQUEST_INVALID: 'Request data is invalid or malformed',\n REQUEST_TIMEOUT: 'Request timed out waiting for wallet response',\n\n // Operation-specific errors (v2.1+)\n SIGNING_FAILED: 'Cryptographic signing operation failed',\n SIGNING_REJECTED: 'User rejected the signing request',\n TRANSACTION_INVALID: 'Transaction parameters validation failed',\n CHAIN_MISMATCH: 'Requested chain ID does not match wallet chain',\n} as const;\n\n// QR code configuration\nexport const QR_CONFIG = {\n size: 256,\n margin: 4,\n errorCorrectionLevel: 'M',\n type: 'image/png',\n} as const;\n\n// Deep link configuration\nexport const DEEP_LINK_CONFIG = {\n scheme: DEEPLINK_SCHEME,\n host: 'connect',\n universal: 'https://bananalink.app',\n} as const;\n\n// Network configuration\nexport const NETWORK_CONFIG = {\n SUPPORTED_CHAINS: [\n 1, // Ethereum Mainnet\n 5, // Goerli Testnet\n 137, // Polygon Mainnet\n 80001, // Polygon Mumbai Testnet\n 42161, // Arbitrum One\n 421613, // Arbitrum Goerli\n 10, // Optimism\n 420, // Optimism Goerli\n ],\n DEFAULT_CHAIN_ID: 1,\n CHAIN_NAMES: {\n 1: 'Ethereum Mainnet',\n 5: 'Goerli Testnet',\n 137: 'Polygon Mainnet',\n 80001: 'Polygon Mumbai',\n 42161: 'Arbitrum One',\n 421613: 'Arbitrum Goerli',\n 10: 'Optimism',\n 420: 'Optimism Goerli',\n } as const,\n} as const;\n\n// Development configuration\nexport const DEV_CONFIG = {\n logLevel: 'debug',\n enableMocks: false,\n skipValidation: false,\n allowLocalhost: true,\n} as const;\n\n// Export all constants as a single object for convenience\nexport const BANANALINK_CONSTANTS = {\n PROTOCOL_VERSION,\n PACKAGE_NAME,\n DEEPLINK_SCHEME,\n DEFAULT_RELAY_URL,\n FRUITS,\n DEFAULT_TIMEOUTS,\n PROTOCOL_V2_TIMEOUTS,\n MESSAGE_QUEUE_CONFIG,\n SECURITY_LIMITS,\n CRYPTO_CONSTANTS,\n MESSAGE_FORMAT,\n WS_MESSAGE_TYPES,\n HTTP_ENDPOINTS,\n ERROR_MESSAGES,\n QR_CONFIG,\n DEEP_LINK_CONFIG,\n NETWORK_CONFIG,\n DEV_CONFIG,\n} as const;\n"]}
@@ -0,0 +1,236 @@
1
+ 'use strict';
2
+
3
+ // src/constants/index.ts
4
+ var PROTOCOL_VERSION = 1;
5
+ var PACKAGE_NAME = "@bananalink-sdk/protocol";
6
+ var DEEPLINK_SCHEME = "bananalink";
7
+ var DEFAULT_RELAY_URL = "wss://relay.banana.link/v1";
8
+ var FRUITS = [
9
+ "\u{1F34C}",
10
+ "\u{1F34E}",
11
+ "\u{1F34A}",
12
+ "\u{1F347}",
13
+ "\u{1F353}",
14
+ "\u{1F351}",
15
+ "\u{1F352}",
16
+ "\u{1F349}",
17
+ "\u{1F95D}",
18
+ "\u{1F34D}",
19
+ "\u{1F96D}",
20
+ "\u{1F965}",
21
+ "\u{1FAD0}",
22
+ "\u{1F348}",
23
+ "\u{1F34B}",
24
+ "\u{1F951}"
25
+ ];
26
+ var DEFAULT_TIMEOUTS = {
27
+ sessionTimeout: 24 * 60 * 60 * 1e3,
28
+ // 24 hours
29
+ requestTimeout: 5 * 60 * 1e3,
30
+ // 5 minutes
31
+ connectionTimeout: 30 * 1e3,
32
+ // 30 seconds
33
+ qrCodeTimeout: 2 * 60 * 1e3
34
+ // 2 minutes
35
+ };
36
+ var PROTOCOL_V2_TIMEOUTS = {
37
+ sessionCreation: 5 * 1e3,
38
+ // 5 seconds - API Gateway response
39
+ claimSession: 10 * 1e3,
40
+ // 10 seconds - Wallet claims ownership
41
+ prefetchMetadata: 5 * 1e3,
42
+ // 5 seconds - Fetch dApp info
43
+ userApproval: 5 * 60 * 1e3,
44
+ // 5 minutes - User decision time
45
+ authentication: 30 * 1e3,
46
+ // 30 seconds - Sign and send
47
+ sessionTTL: 10800 * 1e3,
48
+ // 10800 seconds (3 hours) - Max session lifetime
49
+ reconnectionWindow: 10800 * 1e3,
50
+ // 10800 seconds (3 hours) - Same as session TTL
51
+ messageQueueRetention: 10800 * 1e3,
52
+ // 10800 seconds (3 hours) - Matches session TTL
53
+ websocketHeartbeat: 30 * 1e3,
54
+ // 30 seconds - Keep-alive ping
55
+ gracefulCloseTimeout: 5 * 1e3,
56
+ // 5 seconds - close_session ack wait
57
+ // Post-authentication operation timeouts (v2.1+)
58
+ signMessage: 60 * 1e3,
59
+ // 60 seconds - personal_sign operation
60
+ signTypedData: 90 * 1e3,
61
+ // 90 seconds - eth_signTypedData_v4 operation
62
+ signTransaction: 120 * 1e3
63
+ // 120 seconds - Transaction signing
64
+ };
65
+ var MESSAGE_QUEUE_CONFIG = {
66
+ maxQueueSize: 100,
67
+ // Maximum messages per direction
68
+ retentionTime: 10800 * 1e3,
69
+ // 10800 seconds (3 hours) - Matches session TTL
70
+ overflowStrategy: "drop_oldest"
71
+ // Drop oldest messages when queue is full
72
+ };
73
+ var SECURITY_LIMITS = {
74
+ maxConcurrentSessions: 5,
75
+ maxSessionAge: 7 * 24 * 60 * 60 * 1e3,
76
+ // 7 days
77
+ minNonceLength: 8,
78
+ maxMessageSize: 64 * 1024,
79
+ // 64KB
80
+ maxResourcesCount: 10,
81
+ rateLimit: {
82
+ requestsPerMinute: 60,
83
+ sessionsPerHour: 100
84
+ }
85
+ };
86
+ var CRYPTO_CONSTANTS = {
87
+ keyLength: 256,
88
+ // AES-256
89
+ ivLength: 12,
90
+ // GCM IV length
91
+ tagLength: 16,
92
+ // GCM tag length
93
+ curve: "P-256",
94
+ // ECDH curve
95
+ algorithm: "AES-GCM",
96
+ // Encryption algorithm
97
+ hashAlgorithm: "SHA-256"
98
+ // Hash algorithm
99
+ };
100
+ var MESSAGE_FORMAT = {
101
+ version: "1",
102
+ encoding: "utf8",
103
+ lineBreak: "\n",
104
+ resourcePrefix: "- "
105
+ };
106
+ var WS_MESSAGE_TYPES = {
107
+ subscribe: "sub",
108
+ publish: "pub",
109
+ acknowledge: "ack",
110
+ error: "error"
111
+ };
112
+ var HTTP_ENDPOINTS = {
113
+ messages: "/v1/messages",
114
+ session: "/v1/session",
115
+ health: "/v1/health"
116
+ };
117
+ var ERROR_MESSAGES = {
118
+ // Session errors
119
+ SESSION_EXPIRED: "Session has expired",
120
+ SESSION_NOT_FOUND: "Session ID invalid or expired",
121
+ SESSION_ALREADY_CLAIMED: "Session already claimed by another wallet",
122
+ INVALID_SESSION_CLAIM: "Wallet does not own this session",
123
+ INVALID_CLIENT_CLAIM: "Client session claim does not match",
124
+ SESSION_TOKEN_EXPIRED: "Session token TTL exceeded",
125
+ SESSION_CLOSED: "Session has been closed",
126
+ // Encryption errors
127
+ ENCRYPTION_FAILED: "Message encryption failed",
128
+ DECRYPTION_FAILED: "Cannot decrypt message",
129
+ INVALID_SIGNATURE: "Invalid signature",
130
+ // Network errors
131
+ NETWORK_ERROR: "Network connection error",
132
+ RELAY_ERROR: "Internal relay server error",
133
+ MESSAGE_QUEUE_FULL: "Too many queued messages (>100)",
134
+ RATE_LIMIT_EXCEEDED: "Rate limit exceeded",
135
+ ORIGIN_MISMATCH: "Origin verification failed",
136
+ // Request lifecycle errors (v2.1+)
137
+ REQUEST_PENDING: "Another signing request is already pending",
138
+ REQUEST_NOT_FOUND: "Request ID not found or already processed",
139
+ REQUEST_EXPIRED: "Request expired before completion",
140
+ REQUEST_INVALID: "Request data is invalid or malformed",
141
+ REQUEST_TIMEOUT: "Request timed out waiting for wallet response",
142
+ // Operation-specific errors (v2.1+)
143
+ SIGNING_FAILED: "Cryptographic signing operation failed",
144
+ SIGNING_REJECTED: "User rejected the signing request",
145
+ TRANSACTION_INVALID: "Transaction parameters validation failed",
146
+ CHAIN_MISMATCH: "Requested chain ID does not match wallet chain"
147
+ };
148
+ var QR_CONFIG = {
149
+ size: 256,
150
+ margin: 4,
151
+ errorCorrectionLevel: "M",
152
+ type: "image/png"
153
+ };
154
+ var DEEP_LINK_CONFIG = {
155
+ scheme: DEEPLINK_SCHEME,
156
+ host: "connect",
157
+ universal: "https://bananalink.app"
158
+ };
159
+ var NETWORK_CONFIG = {
160
+ SUPPORTED_CHAINS: [
161
+ 1,
162
+ // Ethereum Mainnet
163
+ 5,
164
+ // Goerli Testnet
165
+ 137,
166
+ // Polygon Mainnet
167
+ 80001,
168
+ // Polygon Mumbai Testnet
169
+ 42161,
170
+ // Arbitrum One
171
+ 421613,
172
+ // Arbitrum Goerli
173
+ 10,
174
+ // Optimism
175
+ 420
176
+ // Optimism Goerli
177
+ ],
178
+ DEFAULT_CHAIN_ID: 1,
179
+ CHAIN_NAMES: {
180
+ 1: "Ethereum Mainnet",
181
+ 5: "Goerli Testnet",
182
+ 137: "Polygon Mainnet",
183
+ 80001: "Polygon Mumbai",
184
+ 42161: "Arbitrum One",
185
+ 421613: "Arbitrum Goerli",
186
+ 10: "Optimism",
187
+ 420: "Optimism Goerli"
188
+ }
189
+ };
190
+ var DEV_CONFIG = {
191
+ logLevel: "debug",
192
+ enableMocks: false,
193
+ skipValidation: false,
194
+ allowLocalhost: true
195
+ };
196
+ var BANANALINK_CONSTANTS = {
197
+ PROTOCOL_VERSION,
198
+ PACKAGE_NAME,
199
+ DEEPLINK_SCHEME,
200
+ DEFAULT_RELAY_URL,
201
+ FRUITS,
202
+ DEFAULT_TIMEOUTS,
203
+ PROTOCOL_V2_TIMEOUTS,
204
+ MESSAGE_QUEUE_CONFIG,
205
+ SECURITY_LIMITS,
206
+ CRYPTO_CONSTANTS,
207
+ MESSAGE_FORMAT,
208
+ WS_MESSAGE_TYPES,
209
+ HTTP_ENDPOINTS,
210
+ ERROR_MESSAGES,
211
+ QR_CONFIG,
212
+ DEEP_LINK_CONFIG,
213
+ NETWORK_CONFIG,
214
+ DEV_CONFIG
215
+ };
216
+
217
+ exports.BANANALINK_CONSTANTS = BANANALINK_CONSTANTS;
218
+ exports.CRYPTO_CONSTANTS = CRYPTO_CONSTANTS;
219
+ exports.DEEPLINK_SCHEME = DEEPLINK_SCHEME;
220
+ exports.DEEP_LINK_CONFIG = DEEP_LINK_CONFIG;
221
+ exports.DEFAULT_RELAY_URL = DEFAULT_RELAY_URL;
222
+ exports.DEFAULT_TIMEOUTS = DEFAULT_TIMEOUTS;
223
+ exports.DEV_CONFIG = DEV_CONFIG;
224
+ exports.ERROR_MESSAGES = ERROR_MESSAGES;
225
+ exports.FRUITS = FRUITS;
226
+ exports.HTTP_ENDPOINTS = HTTP_ENDPOINTS;
227
+ exports.MESSAGE_FORMAT = MESSAGE_FORMAT;
228
+ exports.MESSAGE_QUEUE_CONFIG = MESSAGE_QUEUE_CONFIG;
229
+ exports.NETWORK_CONFIG = NETWORK_CONFIG;
230
+ exports.PROTOCOL_V2_TIMEOUTS = PROTOCOL_V2_TIMEOUTS;
231
+ exports.PROTOCOL_VERSION = PROTOCOL_VERSION;
232
+ exports.QR_CONFIG = QR_CONFIG;
233
+ exports.SECURITY_LIMITS = SECURITY_LIMITS;
234
+ exports.WS_MESSAGE_TYPES = WS_MESSAGE_TYPES;
235
+ //# sourceMappingURL=chunk-GI3BUPIH.cjs.map
236
+ //# sourceMappingURL=chunk-GI3BUPIH.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/constants/index.ts"],"names":[],"mappings":"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","file":"chunk-GI3BUPIH.cjs","sourcesContent":["/**\n * Constants for the BananaLink protocol\n * Contains protocol version, URLs, timeouts, and other configuration values\n */\n\n// Protocol version and identification\nexport const PROTOCOL_VERSION = 1;\nexport const PACKAGE_NAME = '@bananalink-sdk/protocol';\nexport const DEEPLINK_SCHEME = 'bananalink';\n\n// Default relay server configuration\nexport const DEFAULT_RELAY_URL = 'wss://relay.banana.link/v1';\n\n// FrutiLink emoji set (16 fruits for 4 bits each)\nexport const FRUITS = [\n '🍌', '🍎', '🍊', '🍇', '🍓', '🍑', '🍒', '🍉',\n '🥝', '🍍', '🥭', '🥥', '🫐', '🍈', '🍋', '🥑'\n] as const;\n\n// Timeout configurations (in milliseconds)\nexport const DEFAULT_TIMEOUTS = {\n sessionTimeout: 24 * 60 * 60 * 1000, // 24 hours\n requestTimeout: 5 * 60 * 1000, // 5 minutes\n connectionTimeout: 30 * 1000, // 30 seconds\n qrCodeTimeout: 2 * 60 * 1000, // 2 minutes\n} as const;\n\n// Protocol v2.0 specific timeouts (in milliseconds)\n// Based on PROTOCOL.md specification\nexport const PROTOCOL_V2_TIMEOUTS = {\n sessionCreation: 5 * 1000, // 5 seconds - API Gateway response\n claimSession: 10 * 1000, // 10 seconds - Wallet claims ownership\n prefetchMetadata: 5 * 1000, // 5 seconds - Fetch dApp info\n userApproval: 5 * 60 * 1000, // 5 minutes - User decision time\n authentication: 30 * 1000, // 30 seconds - Sign and send\n sessionTTL: 10800 * 1000, // 10800 seconds (3 hours) - Max session lifetime\n reconnectionWindow: 10800 * 1000, // 10800 seconds (3 hours) - Same as session TTL\n messageQueueRetention: 10800 * 1000, // 10800 seconds (3 hours) - Matches session TTL\n websocketHeartbeat: 30 * 1000, // 30 seconds - Keep-alive ping\n gracefulCloseTimeout: 5 * 1000, // 5 seconds - close_session ack wait\n // Post-authentication operation timeouts (v2.1+)\n signMessage: 60 * 1000, // 60 seconds - personal_sign operation\n signTypedData: 90 * 1000, // 90 seconds - eth_signTypedData_v4 operation\n signTransaction: 120 * 1000, // 120 seconds - Transaction signing\n} as const;\n\n// Message queue configuration\nexport const MESSAGE_QUEUE_CONFIG = {\n maxQueueSize: 100, // Maximum messages per direction\n retentionTime: 10800 * 1000, // 10800 seconds (3 hours) - Matches session TTL\n overflowStrategy: 'drop_oldest', // Drop oldest messages when queue is full\n} as const;\n\n// Security limits and constraints\nexport const SECURITY_LIMITS = {\n maxConcurrentSessions: 5,\n maxSessionAge: 7 * 24 * 60 * 60 * 1000, // 7 days\n minNonceLength: 8,\n maxMessageSize: 64 * 1024, // 64KB\n maxResourcesCount: 10,\n rateLimit: {\n requestsPerMinute: 60,\n sessionsPerHour: 100,\n },\n} as const;\n\n// Cryptographic constants\nexport const CRYPTO_CONSTANTS = {\n keyLength: 256, // AES-256\n ivLength: 12, // GCM IV length\n tagLength: 16, // GCM tag length\n curve: 'P-256', // ECDH curve\n algorithm: 'AES-GCM', // Encryption algorithm\n hashAlgorithm: 'SHA-256', // Hash algorithm\n} as const;\n\n// Message format constants\nexport const MESSAGE_FORMAT = {\n version: '1',\n encoding: 'utf8',\n lineBreak: '\\n',\n resourcePrefix: '- ',\n} as const;\n\n// WebSocket message types\nexport const WS_MESSAGE_TYPES = {\n subscribe: 'sub',\n publish: 'pub',\n acknowledge: 'ack',\n error: 'error',\n} as const;\n\n// HTTP endpoints for fallback\nexport const HTTP_ENDPOINTS = {\n messages: '/v1/messages',\n session: '/v1/session',\n health: '/v1/health',\n} as const;\n\n// Error messages (organized hierarchically)\nexport const ERROR_MESSAGES = {\n // Session errors\n SESSION_EXPIRED: 'Session has expired',\n SESSION_NOT_FOUND: 'Session ID invalid or expired',\n SESSION_ALREADY_CLAIMED: 'Session already claimed by another wallet',\n INVALID_SESSION_CLAIM: 'Wallet does not own this session',\n INVALID_CLIENT_CLAIM: 'Client session claim does not match',\n SESSION_TOKEN_EXPIRED: 'Session token TTL exceeded',\n SESSION_CLOSED: 'Session has been closed',\n\n // Encryption errors\n ENCRYPTION_FAILED: 'Message encryption failed',\n DECRYPTION_FAILED: 'Cannot decrypt message',\n INVALID_SIGNATURE: 'Invalid signature',\n\n // Network errors\n NETWORK_ERROR: 'Network connection error',\n RELAY_ERROR: 'Internal relay server error',\n MESSAGE_QUEUE_FULL: 'Too many queued messages (>100)',\n RATE_LIMIT_EXCEEDED: 'Rate limit exceeded',\n ORIGIN_MISMATCH: 'Origin verification failed',\n\n // Request lifecycle errors (v2.1+)\n REQUEST_PENDING: 'Another signing request is already pending',\n REQUEST_NOT_FOUND: 'Request ID not found or already processed',\n REQUEST_EXPIRED: 'Request expired before completion',\n REQUEST_INVALID: 'Request data is invalid or malformed',\n REQUEST_TIMEOUT: 'Request timed out waiting for wallet response',\n\n // Operation-specific errors (v2.1+)\n SIGNING_FAILED: 'Cryptographic signing operation failed',\n SIGNING_REJECTED: 'User rejected the signing request',\n TRANSACTION_INVALID: 'Transaction parameters validation failed',\n CHAIN_MISMATCH: 'Requested chain ID does not match wallet chain',\n} as const;\n\n// QR code configuration\nexport const QR_CONFIG = {\n size: 256,\n margin: 4,\n errorCorrectionLevel: 'M',\n type: 'image/png',\n} as const;\n\n// Deep link configuration\nexport const DEEP_LINK_CONFIG = {\n scheme: DEEPLINK_SCHEME,\n host: 'connect',\n universal: 'https://bananalink.app',\n} as const;\n\n// Network configuration\nexport const NETWORK_CONFIG = {\n SUPPORTED_CHAINS: [\n 1, // Ethereum Mainnet\n 5, // Goerli Testnet\n 137, // Polygon Mainnet\n 80001, // Polygon Mumbai Testnet\n 42161, // Arbitrum One\n 421613, // Arbitrum Goerli\n 10, // Optimism\n 420, // Optimism Goerli\n ],\n DEFAULT_CHAIN_ID: 1,\n CHAIN_NAMES: {\n 1: 'Ethereum Mainnet',\n 5: 'Goerli Testnet',\n 137: 'Polygon Mainnet',\n 80001: 'Polygon Mumbai',\n 42161: 'Arbitrum One',\n 421613: 'Arbitrum Goerli',\n 10: 'Optimism',\n 420: 'Optimism Goerli',\n } as const,\n} as const;\n\n// Development configuration\nexport const DEV_CONFIG = {\n logLevel: 'debug',\n enableMocks: false,\n skipValidation: false,\n allowLocalhost: true,\n} as const;\n\n// Export all constants as a single object for convenience\nexport const BANANALINK_CONSTANTS = {\n PROTOCOL_VERSION,\n PACKAGE_NAME,\n DEEPLINK_SCHEME,\n DEFAULT_RELAY_URL,\n FRUITS,\n DEFAULT_TIMEOUTS,\n PROTOCOL_V2_TIMEOUTS,\n MESSAGE_QUEUE_CONFIG,\n SECURITY_LIMITS,\n CRYPTO_CONSTANTS,\n MESSAGE_FORMAT,\n WS_MESSAGE_TYPES,\n HTTP_ENDPOINTS,\n ERROR_MESSAGES,\n QR_CONFIG,\n DEEP_LINK_CONFIG,\n NETWORK_CONFIG,\n DEV_CONFIG,\n} as const;\n"]}
@@ -0,0 +1,106 @@
1
+ import { __name } from './chunk-WCQVDF3K.js';
2
+
3
+ // src/validators/index.ts
4
+ function isValidAddress(address) {
5
+ return typeof address === "string" && /^0x[0-9a-fA-F]{40}$/.test(address);
6
+ }
7
+ __name(isValidAddress, "isValidAddress");
8
+ function isValidUrl(url) {
9
+ if (typeof url !== "string") return false;
10
+ try {
11
+ new URL(url);
12
+ return true;
13
+ } catch {
14
+ return false;
15
+ }
16
+ }
17
+ __name(isValidUrl, "isValidUrl");
18
+ function isValidTimestamp(timestamp) {
19
+ if (typeof timestamp !== "string") return false;
20
+ try {
21
+ const date = new Date(timestamp);
22
+ return !isNaN(date.getTime()) && timestamp === date.toISOString();
23
+ } catch {
24
+ return false;
25
+ }
26
+ }
27
+ __name(isValidTimestamp, "isValidTimestamp");
28
+ function isValidChainId(chainId) {
29
+ return typeof chainId === "number" && Number.isInteger(chainId) && chainId > 0;
30
+ }
31
+ __name(isValidChainId, "isValidChainId");
32
+ function isValidNonce(nonce) {
33
+ return typeof nonce === "string" && /^[a-fA-F0-9]{64}$/.test(nonce);
34
+ }
35
+ __name(isValidNonce, "isValidNonce");
36
+ function isValidSessionId(sessionId) {
37
+ return typeof sessionId === "string" && /^[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/.test(sessionId);
38
+ }
39
+ __name(isValidSessionId, "isValidSessionId");
40
+ function isValidBase64(str) {
41
+ if (typeof str !== "string" || str.length === 0) return false;
42
+ const base64Pattern = /^[A-Za-z0-9+/\-_]+(={0,2})$/;
43
+ if (!base64Pattern.test(str)) return false;
44
+ const paddingMatch = str.match(/=*$/);
45
+ const padding = paddingMatch ? paddingMatch[0].length : 0;
46
+ return padding === 0 || padding <= 2 && str.length % 4 === 0;
47
+ }
48
+ __name(isValidBase64, "isValidBase64");
49
+ function isValidHex(hex) {
50
+ return typeof hex === "string" && /^(0x)?[0-9a-fA-F]+$/.test(hex);
51
+ }
52
+ __name(isValidHex, "isValidHex");
53
+ function isValidMessageType(type) {
54
+ return type === "auth" || type === "tx" || type === "sign";
55
+ }
56
+ __name(isValidMessageType, "isValidMessageType");
57
+ function isValidEncryptionAlgorithm(algo) {
58
+ return algo === "AES-GCM" || algo === "plaintext";
59
+ }
60
+ __name(isValidEncryptionAlgorithm, "isValidEncryptionAlgorithm");
61
+ function isValidDomain(domain) {
62
+ if (typeof domain !== "string" || domain.length === 0) return false;
63
+ return /^[a-zA-Z0-9]([a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(\.[a-zA-Z0-9]([a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*$/.test(
64
+ domain
65
+ );
66
+ }
67
+ __name(isValidDomain, "isValidDomain");
68
+ function isValidPublicKey(publicKey) {
69
+ if (typeof publicKey !== "string") return false;
70
+ const parts = publicKey.split(":");
71
+ if (parts.length !== 2) return false;
72
+ const [algorithm, key] = parts;
73
+ return (algorithm === "AES-GCM" || algorithm === "cleartext") && (algorithm === "cleartext" || isValidBase64(key));
74
+ }
75
+ __name(isValidPublicKey, "isValidPublicKey");
76
+ function isValidEncryptedPayload(payload) {
77
+ if (!payload || typeof payload !== "object") return false;
78
+ const p = payload;
79
+ return isValidBase64(p.iv) && isValidBase64(p.ciphertext) && isValidBase64(p.mac);
80
+ }
81
+ __name(isValidEncryptedPayload, "isValidEncryptedPayload");
82
+ function createValidationResult(valid, data, error) {
83
+ if (valid) {
84
+ return { valid: true, data };
85
+ }
86
+ return { valid: false, error };
87
+ }
88
+ __name(createValidationResult, "createValidationResult");
89
+ function hasRequiredFields(obj, fields) {
90
+ if (!obj || typeof obj !== "object") return false;
91
+ const o = obj;
92
+ return fields.every(
93
+ (field) => field in o && o[field] !== null && o[field] !== void 0 && o[field] !== ""
94
+ );
95
+ }
96
+ __name(hasRequiredFields, "hasRequiredFields");
97
+ function isValidSIWEMessage(message) {
98
+ if (!message || typeof message !== "object") return false;
99
+ const m = message;
100
+ return isValidDomain(m.domain) && isValidAddress(m.address) && isValidUrl(m.uri) && m.version === "1" && isValidChainId(m.chainId) && isValidNonce(m.nonce) && isValidTimestamp(m.issuedAt);
101
+ }
102
+ __name(isValidSIWEMessage, "isValidSIWEMessage");
103
+
104
+ export { createValidationResult, hasRequiredFields, isValidAddress, isValidBase64, isValidChainId, isValidDomain, isValidEncryptedPayload, isValidEncryptionAlgorithm, isValidHex, isValidMessageType, isValidNonce, isValidPublicKey, isValidSIWEMessage, isValidSessionId, isValidTimestamp, isValidUrl };
105
+ //# sourceMappingURL=chunk-JXHV66Q4.js.map
106
+ //# sourceMappingURL=chunk-JXHV66Q4.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/validators/index.ts"],"names":[],"mappings":";;;AAYO,SAAS,eAAe,OAAA,EAAqC;AAClE,EAAA,OAAO,OAAO,OAAA,KAAY,QAAA,IAAY,qBAAA,CAAsB,KAAK,OAAO,CAAA;AAC1E;AAFgB,MAAA,CAAA,cAAA,EAAA,gBAAA,CAAA;AAOT,SAAS,WAAW,GAAA,EAA6B;AACtD,EAAA,IAAI,OAAO,GAAA,KAAQ,QAAA,EAAU,OAAO,KAAA;AACpC,EAAA,IAAI;AACF,IAAA,IAAI,IAAI,GAAG,CAAA;AACX,IAAA,OAAO,IAAA;AAAA,EACT,CAAA,CAAA,MAAQ;AACN,IAAA,OAAO,KAAA;AAAA,EACT;AACF;AARgB,MAAA,CAAA,UAAA,EAAA,YAAA,CAAA;AAaT,SAAS,iBAAiB,SAAA,EAAyC;AACxE,EAAA,IAAI,OAAO,SAAA,KAAc,QAAA,EAAU,OAAO,KAAA;AAC1C,EAAA,IAAI;AACF,IAAA,MAAM,IAAA,GAAO,IAAI,IAAA,CAAK,SAAS,CAAA;AAC/B,IAAA,OAAO,CAAC,MAAM,IAAA,CAAK,OAAA,EAAS,CAAA,IAAK,SAAA,KAAc,KAAK,WAAA,EAAY;AAAA,EAClE,CAAA,CAAA,MAAQ;AACN,IAAA,OAAO,KAAA;AAAA,EACT;AACF;AARgB,MAAA,CAAA,gBAAA,EAAA,kBAAA,CAAA;AAaT,SAAS,eAAe,OAAA,EAAqC;AAClE,EAAA,OAAO,OAAO,OAAA,KAAY,QAAA,IAAY,OAAO,SAAA,CAAU,OAAO,KAAK,OAAA,GAAU,CAAA;AAC/E;AAFgB,MAAA,CAAA,cAAA,EAAA,gBAAA,CAAA;AAQT,SAAS,aAAa,KAAA,EAAiC;AAC5D,EAAA,OAAO,OAAO,KAAA,KAAU,QAAA,IAAY,mBAAA,CAAoB,KAAK,KAAK,CAAA;AACpE;AAFgB,MAAA,CAAA,YAAA,EAAA,cAAA,CAAA;AAOT,SAAS,iBAAiB,SAAA,EAAyC;AACxE,EAAA,OACE,OAAO,SAAA,KAAc,QAAA,IACrB,uEAAA,CAAwE,KAAK,SAAS,CAAA;AAE1F;AALgB,MAAA,CAAA,gBAAA,EAAA,kBAAA,CAAA;AAWT,SAAS,cAAc,GAAA,EAA6B;AACzD,EAAA,IAAI,OAAO,GAAA,KAAQ,QAAA,IAAY,GAAA,CAAI,MAAA,KAAW,GAAG,OAAO,KAAA;AAIxD,EAAA,MAAM,aAAA,GAAgB,6BAAA;AAEtB,EAAA,IAAI,CAAC,aAAA,CAAc,IAAA,CAAK,GAAG,GAAG,OAAO,KAAA;AAIrC,EAAA,MAAM,YAAA,GAAe,GAAA,CAAI,KAAA,CAAM,KAAK,CAAA;AACpC,EAAA,MAAM,OAAA,GAAU,YAAA,GAAe,YAAA,CAAa,CAAC,EAAE,MAAA,GAAS,CAAA;AAGxD,EAAA,OAAO,YAAY,CAAA,IAAM,OAAA,IAAW,CAAA,IAAM,GAAA,CAAI,SAAS,CAAA,KAAM,CAAA;AAC/D;AAhBgB,MAAA,CAAA,aAAA,EAAA,eAAA,CAAA;AAqBT,SAAS,WAAW,GAAA,EAA6B;AACtD,EAAA,OAAO,OAAO,GAAA,KAAQ,QAAA,IAAY,qBAAA,CAAsB,KAAK,GAAG,CAAA;AAClE;AAFgB,MAAA,CAAA,UAAA,EAAA,YAAA,CAAA;AAgBT,SAAS,mBAAmB,IAAA,EAA+C;AAChF,EAAA,OAAO,IAAA,KAAS,MAAA,IAAU,IAAA,KAAS,IAAA,IAAQ,IAAA,KAAS,MAAA;AACtD;AAFgB,MAAA,CAAA,kBAAA,EAAA,oBAAA,CAAA;AAOT,SAAS,2BAA2B,IAAA,EAAgD;AACzF,EAAA,OAAO,IAAA,KAAS,aAAa,IAAA,KAAS,WAAA;AACxC;AAFgB,MAAA,CAAA,0BAAA,EAAA,4BAAA,CAAA;AAOT,SAAS,cAAc,MAAA,EAAmC;AAC/D,EAAA,IAAI,OAAO,MAAA,KAAW,QAAA,IAAY,MAAA,CAAO,MAAA,KAAW,GAAG,OAAO,KAAA;AAE9D,EAAA,OAAO,+FAAA,CAAgG,IAAA;AAAA,IACrG;AAAA,GACF;AACF;AANgB,MAAA,CAAA,aAAA,EAAA,eAAA,CAAA;AAWT,SAAS,iBAAiB,SAAA,EAAyC;AACxE,EAAA,IAAI,OAAO,SAAA,KAAc,QAAA,EAAU,OAAO,KAAA;AAC1C,EAAA,MAAM,KAAA,GAAQ,SAAA,CAAU,KAAA,CAAM,GAAG,CAAA;AACjC,EAAA,IAAI,KAAA,CAAM,MAAA,KAAW,CAAA,EAAG,OAAO,KAAA;AAC/B,EAAA,MAAM,CAAC,SAAA,EAAW,GAAG,CAAA,GAAI,KAAA;AACzB,EAAA,OAAA,CACG,cAAc,SAAA,IAAa,SAAA,KAAc,iBACzC,SAAA,KAAc,WAAA,IAAe,cAAc,GAAG,CAAA,CAAA;AAEnD;AATgB,MAAA,CAAA,gBAAA,EAAA,kBAAA,CAAA;AAoBT,SAAS,wBAAwB,OAAA,EAA+C;AACrF,EAAA,IAAI,CAAC,OAAA,IAAW,OAAO,OAAA,KAAY,UAAU,OAAO,KAAA;AACpD,EAAA,MAAM,CAAA,GAAI,OAAA;AACV,EAAA,OACE,aAAA,CAAc,CAAA,CAAE,EAAE,CAAA,IAClB,aAAA,CAAc,EAAE,UAAU,CAAA,IAC1B,aAAA,CAAc,CAAA,CAAE,GAAG,CAAA;AAEvB;AARgB,MAAA,CAAA,uBAAA,EAAA,yBAAA,CAAA;AAaT,SAAS,sBAAA,CACd,KAAA,EACA,IAAA,EACA,KAAA,EACqB;AACrB,EAAA,IAAI,KAAA,EAAO;AACT,IAAA,OAAO,EAAE,KAAA,EAAO,IAAA,EAAM,IAAA,EAAK;AAAA,EAC7B;AACA,EAAA,OAAO,EAAE,KAAA,EAAO,KAAA,EAAO,KAAA,EAAM;AAC/B;AATgB,MAAA,CAAA,sBAAA,EAAA,wBAAA,CAAA;AAcT,SAAS,iBAAA,CACd,KACA,MAAA,EACU;AACV,EAAA,IAAI,CAAC,GAAA,IAAO,OAAO,GAAA,KAAQ,UAAU,OAAO,KAAA;AAC5C,EAAA,MAAM,CAAA,GAAI,GAAA;AACV,EAAA,OAAO,MAAA,CAAO,KAAA;AAAA,IACZ,CAAC,KAAA,KACC,KAAA,IAAS,CAAA,IACT,EAAE,KAAe,CAAA,KAAM,IAAA,IACvB,CAAA,CAAE,KAAe,CAAA,KAAM,MAAA,IACvB,CAAA,CAAE,KAAe,CAAA,KAAM;AAAA,GAC3B;AACF;AAbgB,MAAA,CAAA,iBAAA,EAAA,mBAAA,CAAA;AA4BT,SAAS,mBAAmB,OAAA,EAA0C;AAC3E,EAAA,IAAI,CAAC,OAAA,IAAW,OAAO,OAAA,KAAY,UAAU,OAAO,KAAA;AACpD,EAAA,MAAM,CAAA,GAAI,OAAA;AAEV,EAAA,OACE,aAAA,CAAc,CAAA,CAAE,MAAM,CAAA,IACtB,cAAA,CAAe,EAAE,OAAO,CAAA,IACxB,UAAA,CAAW,CAAA,CAAE,GAAG,CAAA,IAChB,EAAE,OAAA,KAAY,GAAA,IACd,cAAA,CAAe,CAAA,CAAE,OAAO,CAAA,IACxB,YAAA,CAAa,CAAA,CAAE,KAAK,CAAA,IACpB,gBAAA,CAAiB,CAAA,CAAE,QAAQ,CAAA;AAE/B;AAbgB,MAAA,CAAA,kBAAA,EAAA,oBAAA,CAAA","file":"chunk-JXHV66Q4.js","sourcesContent":["/**\n * Lightweight validation utilities for BananaLink protocol types\n *\n * Zero dependencies, minimal bundle size (~3KB)\n * Suitable for browsers, React Native, and Node.js\n *\n * For full Zod-based validation, use: @bananalink-sdk/protocol/validation\n */\n\n/**\n * Validate Ethereum address format (0x + 40 hex characters)\n */\nexport function isValidAddress(address: unknown): address is string {\n return typeof address === 'string' && /^0x[0-9a-fA-F]{40}$/.test(address);\n}\n\n/**\n * Validate URL format\n */\nexport function isValidUrl(url: unknown): url is string {\n if (typeof url !== 'string') return false;\n try {\n new URL(url);\n return true;\n } catch {\n return false;\n }\n}\n\n/**\n * Validate ISO 8601 timestamp format\n */\nexport function isValidTimestamp(timestamp: unknown): timestamp is string {\n if (typeof timestamp !== 'string') return false;\n try {\n const date = new Date(timestamp);\n return !isNaN(date.getTime()) && timestamp === date.toISOString();\n } catch {\n return false;\n }\n}\n\n/**\n * Validate chain ID (positive integer)\n */\nexport function isValidChainId(chainId: unknown): chainId is number {\n return typeof chainId === 'number' && Number.isInteger(chainId) && chainId > 0;\n}\n\n/**\n * Validate nonce format (64 hex characters = 32 bytes)\n * Protocol v2.0 standard\n */\nexport function isValidNonce(nonce: unknown): nonce is string {\n return typeof nonce === 'string' && /^[a-fA-F0-9]{64}$/.test(nonce);\n}\n\n/**\n * Validate session ID format (UUID v4)\n */\nexport function isValidSessionId(sessionId: unknown): sessionId is string {\n return (\n typeof sessionId === 'string' &&\n /^[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/.test(sessionId)\n );\n}\n\n/**\n * Validate base64 string format\n * Accepts standard base64 (with padding) and base64url variants\n */\nexport function isValidBase64(str: unknown): str is string {\n if (typeof str !== 'string' || str.length === 0) return false;\n\n // RFC 4648 base64 pattern: A-Z, a-z, 0-9, +, /, = (padding)\n // Also accepts base64url variant: A-Z, a-z, 0-9, -, _\n const base64Pattern = /^[A-Za-z0-9+/\\-_]+(={0,2})$/;\n\n if (!base64Pattern.test(str)) return false;\n\n // Validate padding - must be 0, 1, or 2 '=' characters at the end\n // Length must be multiple of 4 for standard base64 with padding\n const paddingMatch = str.match(/=*$/);\n const padding = paddingMatch ? paddingMatch[0].length : 0;\n\n // For base64url (no padding) or standard base64 (proper padding)\n return padding === 0 || (padding <= 2 && (str.length % 4 === 0));\n}\n\n/**\n * Validate hex string format\n */\nexport function isValidHex(hex: unknown): hex is string {\n return typeof hex === 'string' && /^(0x)?[0-9a-fA-F]+$/.test(hex);\n}\n\n/**\n * Validation result with detailed error information\n */\nexport interface ValidationResult<T = unknown> {\n valid: boolean;\n error?: string;\n data?: T;\n}\n\n/**\n * Validate message type enum\n */\nexport function isValidMessageType(type: unknown): type is 'auth' | 'tx' | 'sign' {\n return type === 'auth' || type === 'tx' || type === 'sign';\n}\n\n/**\n * Validate encryption algorithm\n */\nexport function isValidEncryptionAlgorithm(algo: unknown): algo is 'AES-GCM' | 'plaintext' {\n return algo === 'AES-GCM' || algo === 'plaintext';\n}\n\n/**\n * Validate domain name format\n */\nexport function isValidDomain(domain: unknown): domain is string {\n if (typeof domain !== 'string' || domain.length === 0) return false;\n // Basic domain validation (not comprehensive, but sufficient for protocol)\n return /^[a-zA-Z0-9]([a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(\\.[a-zA-Z0-9]([a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*$/.test(\n domain\n );\n}\n\n/**\n * Validate public key format (algorithm:base64)\n */\nexport function isValidPublicKey(publicKey: unknown): publicKey is string {\n if (typeof publicKey !== 'string') return false;\n const parts = publicKey.split(':');\n if (parts.length !== 2) return false;\n const [algorithm, key] = parts;\n return (\n (algorithm === 'AES-GCM' || algorithm === 'cleartext') &&\n (algorithm === 'cleartext' || isValidBase64(key))\n );\n}\n\n/**\n * Validate encrypted payload structure\n */\nexport interface EncryptedPayload {\n iv: string;\n ciphertext: string;\n mac: string;\n}\n\nexport function isValidEncryptedPayload(payload: unknown): payload is EncryptedPayload {\n if (!payload || typeof payload !== 'object') return false;\n const p = payload as Record<string, unknown>;\n return (\n isValidBase64(p.iv) &&\n isValidBase64(p.ciphertext) &&\n isValidBase64(p.mac)\n );\n}\n\n/**\n * Create a validation result\n */\nexport function createValidationResult<T = unknown>(\n valid: boolean,\n data?: T,\n error?: string\n): ValidationResult<T> {\n if (valid) {\n return { valid: true, data };\n }\n return { valid: false, error };\n}\n\n/**\n * Validate required fields are present and non-empty\n */\nexport function hasRequiredFields<T extends object>(\n obj: unknown,\n fields: (keyof T)[]\n): obj is T {\n if (!obj || typeof obj !== 'object') return false;\n const o = obj as Record<string, unknown>;\n return fields.every(\n (field) =>\n field in o &&\n o[field as string] !== null &&\n o[field as string] !== undefined &&\n o[field as string] !== ''\n );\n}\n\n/**\n * Validate SIWE message structure (minimal check)\n */\nexport interface SIWEMessage {\n domain: string;\n address: string;\n uri: string;\n version: string;\n chainId: number;\n nonce: string;\n issuedAt: string;\n}\n\nexport function isValidSIWEMessage(message: unknown): message is SIWEMessage {\n if (!message || typeof message !== 'object') return false;\n const m = message as Record<string, unknown>;\n\n return (\n isValidDomain(m.domain) &&\n isValidAddress(m.address) &&\n isValidUrl(m.uri) &&\n m.version === '1' &&\n isValidChainId(m.chainId) &&\n isValidNonce(m.nonce) &&\n isValidTimestamp(m.issuedAt)\n );\n}\n"]}