@anuma/sdk 6.27.1 → 6.27.3

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.
@@ -1510,6 +1510,7 @@ __export(index_exports, {
1510
1510
  deleteVaultFolderOp: () => deleteVaultFolderOp,
1511
1511
  deleteVaultMemoryOp: () => deleteVaultMemoryOp,
1512
1512
  dequantizeEmbedding: () => dequantizeEmbedding,
1513
+ deriveKeyFromSignatureBytes: () => deriveKeyFromSignatureBytes,
1513
1514
  discoverNotionOAuthEndpoints: () => discoverNotionOAuthEndpoints,
1514
1515
  eagerEmbedContent: () => eagerEmbedContent,
1515
1516
  embedAllMessages: () => embedAllMessages,
@@ -1853,11 +1854,32 @@ function clearAllEncryptionState() {
1853
1854
  function clearAllEncryptionKeys() {
1854
1855
  clearAllEncryptionState();
1855
1856
  }
1857
+ function hexNibble(code) {
1858
+ if (code >= 48 && code <= 57) return code - 48;
1859
+ if (code >= 65 && code <= 70) return code - 55;
1860
+ if (code >= 97 && code <= 102) return code - 87;
1861
+ return -1;
1862
+ }
1856
1863
  function hexToBytes(hex) {
1864
+ if (typeof hex !== "string") {
1865
+ throw new TypeError(
1866
+ "hexToBytes: expected a hex string. Pass raw signature bytes to deriveKeyFromSignatureBytes instead of stringifying them."
1867
+ );
1868
+ }
1857
1869
  const cleanHex = hex.startsWith("0x") ? hex.slice(2) : hex;
1870
+ if (cleanHex.length === 0 || cleanHex.length % 2 !== 0) {
1871
+ throw new Error(
1872
+ `hexToBytes: invalid hex string (expected a non-empty even length, got ${cleanHex.length})`
1873
+ );
1874
+ }
1858
1875
  const bytes = new Uint8Array(cleanHex.length / 2);
1859
1876
  for (let i = 0; i < cleanHex.length; i += 2) {
1860
- bytes[i / 2] = parseInt(cleanHex.slice(i, i + 2), 16);
1877
+ const hi = hexNibble(cleanHex.charCodeAt(i));
1878
+ const lo = hexNibble(cleanHex.charCodeAt(i + 1));
1879
+ if (hi < 0 || lo < 0) {
1880
+ throw new Error(`hexToBytes: invalid hex string (non-hex character at index ${i})`);
1881
+ }
1882
+ bytes[i / 2] = hi << 4 | lo;
1861
1883
  }
1862
1884
  return bytes;
1863
1885
  }
@@ -1869,15 +1891,12 @@ var SHARED_TEXT_DECODER = new TextDecoder();
1869
1891
  function isValidWalletAddress(address) {
1870
1892
  return /^0x[a-fA-F0-9]{40}$/.test(address);
1871
1893
  }
1872
- async function deriveKeyFromSignature(signature) {
1873
- const sigBytes = hexToBytes(signature);
1874
- const hashBuffer = await crypto.subtle.digest("SHA-256", sigBytes.buffer);
1875
- const hashBytes = new Uint8Array(hashBuffer);
1876
- return bytesToHex(hashBytes);
1877
- }
1878
- async function deriveKeyFromSignatureV3(signature) {
1879
- const sigBytes = hexToBytes(signature);
1880
- const ikm = await crypto.subtle.digest("SHA-256", sigBytes.buffer);
1894
+ var AES_GCM_V3_INFO = "anuma-sdk-aes-gcm-v3";
1895
+ var AES_GCM_V4_INFO = "anuma-sdk-aes-gcm-v4";
1896
+ var MIN_SIGNATURE_BYTES = 64;
1897
+ async function deriveHkdfAesKeyHex(signatureBytes, info) {
1898
+ const sigBytes = new Uint8Array(signatureBytes);
1899
+ const ikm = await crypto.subtle.digest("SHA-256", sigBytes);
1881
1900
  const hkdfKey = await crypto.subtle.importKey("raw", ikm, { name: "HKDF" }, false, [
1882
1901
  "deriveBits"
1883
1902
  ]);
@@ -1887,13 +1906,32 @@ async function deriveKeyFromSignatureV3(signature) {
1887
1906
  hash: "SHA-256",
1888
1907
  salt: new Uint8Array(32),
1889
1908
  // Zero salt (HKDF spec: uses hash-length zero buffer)
1890
- info: SHARED_TEXT_ENCODER.encode("anuma-sdk-aes-gcm-v3")
1909
+ info: SHARED_TEXT_ENCODER.encode(info)
1891
1910
  },
1892
1911
  hkdfKey,
1893
1912
  256
1894
1913
  );
1895
1914
  return bytesToHex(new Uint8Array(derivedBits));
1896
1915
  }
1916
+ async function deriveKeyFromSignature(signature) {
1917
+ const sigBytes = hexToBytes(signature);
1918
+ const hashBuffer = await crypto.subtle.digest("SHA-256", sigBytes.buffer);
1919
+ return bytesToHex(new Uint8Array(hashBuffer));
1920
+ }
1921
+ async function deriveKeyFromSignatureV3(signature) {
1922
+ return deriveHkdfAesKeyHex(hexToBytes(signature), AES_GCM_V3_INFO);
1923
+ }
1924
+ async function deriveKeyFromSignatureBytes(signature) {
1925
+ if (!(signature instanceof Uint8Array)) {
1926
+ throw new TypeError("deriveKeyFromSignatureBytes: expected a Uint8Array signature");
1927
+ }
1928
+ if (signature.byteLength < MIN_SIGNATURE_BYTES) {
1929
+ throw new Error(
1930
+ `deriveKeyFromSignatureBytes: signature must be at least ${MIN_SIGNATURE_BYTES} bytes, got ${signature.byteLength}`
1931
+ );
1932
+ }
1933
+ return deriveHkdfAesKeyHex(signature, AES_GCM_V4_INFO);
1934
+ }
1897
1935
  function getStoredKeyPair(address) {
1898
1936
  return keyPairStore.get(address) ?? null;
1899
1937
  }
@@ -1911,8 +1949,9 @@ async function deriveKeyPairFromSignature(signature, address) {
1911
1949
  {
1912
1950
  name: "HKDF",
1913
1951
  hash: "SHA-256",
1952
+ // EVM addresses are case-insensitive. Base58 is not — this salt stays
1953
+ // behind the EVM address gate in requestKeyPair.
1914
1954
  salt: SHARED_TEXT_ENCODER.encode(address.toLowerCase()),
1915
- // Wallet address as salt
1916
1955
  info: SHARED_TEXT_ENCODER.encode("ECDH-P256-KeyPair")
1917
1956
  // Context info
1918
1957
  },
@@ -25693,6 +25732,7 @@ function createNotionProxyTools(callMcp) {
25693
25732
  deleteVaultFolderOp,
25694
25733
  deleteVaultMemoryOp,
25695
25734
  dequantizeEmbedding,
25735
+ deriveKeyFromSignatureBytes,
25696
25736
  discoverNotionOAuthEndpoints,
25697
25737
  eagerEmbedContent,
25698
25738
  embedAllMessages,
@@ -4446,6 +4446,10 @@ declare class Conversation extends Model {
4446
4446
  * Encryption key version type.
4447
4447
  * - "v2": Legacy SHA-256 derived key (for reading enc:v2: data)
4448
4448
  * - "v3": HKDF derived key with domain separation (for new encryption)
4449
+ *
4450
+ * Raw signature bytes (Privy Solana `signMessage` returns a `Uint8Array`) are
4451
+ * not a stored version. Derive them with {@link deriveKeyFromSignatureBytes}.
4452
+ * {@link requestEncryptionKey} still derives v2 and v3 from a hex signature only.
4449
4453
  */
4450
4454
  type EncryptionKeyVersion = "v2" | "v3";
4451
4455
  /**
@@ -4515,6 +4519,25 @@ declare function clearAllEncryptionState(): void;
4515
4519
  * requests, and derived ECDH key pairs (both in-memory and persisted).
4516
4520
  */
4517
4521
  declare function clearAllEncryptionKeys(): void;
4522
+ /**
4523
+ * Derives the bytes-native AES key from a raw signature.
4524
+ *
4525
+ * Privy Solana `signMessage` returns a `Uint8Array`. Pass those bytes here.
4526
+ * The signature is never hex-encoded, base58-encoded, or passed through
4527
+ * `String()`. That string round-trip is what made {@link hexToBytes} store
4528
+ * zeros for every non-hex pair and yield a low-entropy AES key.
4529
+ *
4530
+ * This is the derivation for the next key version (`anuma-sdk-aes-gcm-v4`).
4531
+ * {@link requestEncryptionKey} does not install it; v2 and v3 stay on the
4532
+ * hex-string path so existing ciphertext keeps decrypting. The return value
4533
+ * is the same 64-char hex form the in-memory store already uses.
4534
+ *
4535
+ * @param signature - Raw signature bytes. Must be at least 64 bytes.
4536
+ * @returns 32-byte AES-GCM key as hex, without a `0x` prefix.
4537
+ * @throws Error when `signature` is shorter than 64 bytes.
4538
+ * @category Encryption
4539
+ */
4540
+ declare function deriveKeyFromSignatureBytes(signature: Uint8Array): Promise<string>;
4518
4541
  /**
4519
4542
  * Checks if an encryption key exists in memory for the given wallet address.
4520
4543
  *
@@ -4550,6 +4573,11 @@ interface SignMessageOptions {
4550
4573
  /**
4551
4574
  * Type for the signMessage function that client must provide.
4552
4575
  * This is typically from Privy's useSignMessage hook.
4576
+ *
4577
+ * The resolved value must be a hex signature (`0x`-prefixed or bare). A
4578
+ * non-hex string — including `String(uint8Array)` or a base58 signature —
4579
+ * throws from key derivation instead of becoming a zero-filled AES key.
4580
+ * Raw signature bytes go to {@link deriveKeyFromSignatureBytes}.
4553
4581
  */
4554
4582
  type SignMessageFn = (message: string, options?: SignMessageOptions) => Promise<string>;
4555
4583
  /**
@@ -11328,4 +11356,4 @@ declare function createNotionTools(getAccessToken: () => string | null, requestN
11328
11356
  */
11329
11357
  declare function createNotionProxyTools(callMcp: NotionMcpCaller): ToolConfig[];
11330
11358
 
11331
- export { type AutoExtractMessage, type AutoExtractor, type Budget, CHUNKS_DISCARDED_ORIGIN, type CachedChunkVectors, type CachedServerTools, Conversation as ChatConversation, Message as ChatMessage, type ChatRole, type ChunkVectorCache, type ChunkingOptions, type ConsolidationAction, type ConsolidationFallbackReason, type ConversationMemoryInput, ConversationMemory as ConversationMemoryModel, type ConversationMemoryOperationsContext, type CreateAutoExtractorOptions, type CreateConversationOptions, type CreateDecaySweeperOptions, type CreateMessageOptions, type CreateVaultFolderOptions, type CreateVaultMemoryOptions, type CryptoPriceClassification, type CryptoPricePreProcessorOptions, DEFAULT_CACHE_EXPIRATION_MS, DEFAULT_CHUNK_CACHE_SIZE, DEFAULT_CHUNK_OVERLAP, DEFAULT_CHUNK_SIZE, DEFAULT_DECAY_POLICY, DEFAULT_MAX_CLASSIFIER_CALLS_PER_SWEEP, DEFAULT_MIN_CHUNK_SIZE, DEFAULT_PROFILE_FACETS, DEFAULT_PROFILE_FACT_TYPE_WEIGHTS, DEFAULT_PROFILE_PROOF_ALPHA, DEFAULT_PROFILE_TREND_MULTIPLIERS, DEFAULT_VAULT_CACHE_SIZE, DatabaseManager, type DatabaseManagerLogger, type DatabaseManagerOptions, type DecayCandidateRaw, type DecayClassifier, type DecayInput, type DecayPolicy, type DecaySweepResult, type DecaySweeper, type DecayVerdict, type DurableAutoExtractorOptions, ENTITY_FANOUT, type EmbeddedWalletSignerFn, EncryptionKeyMissingError, type ExtractFactsOptions, type ExtractOutcome, type ExtractedCandidate, type ExtractedEntity, type ExtractionCursorStore, type ExtractionFunnel, type ExtractionTimings, type FactType, type FileMetadata, type FileProcessingReason, type FileProcessingStatus, type FlushResult, type GetConversationsPageOptions, type GetMessagesPageOptions, type GraphTraversalOptions, HARD_DELETE_WINDOW_MS, INFERENCE_ID_HEADER, type InjectionClassifierOptions, type InjectionReason, type LazyStoredConversation, type LlmDecayClassifierOptions, type LlmNeighborRefinerOptions, type Logger, LoggerProvider, type LoggerProviderProps, MAX_HOPS, MEDIUM_TTL_MS, type ManualFactType, type MemoriesNeedingTopicExtraction, type MemoryContextItem, type MemoryContextLane, type MemoryContextOptions, type MemoryContextResult, type EmbeddingOptions as MemoryEngineEmbeddingOptions, type MemoryEngineResult, type MemoryEngineSearchOptions, type MemoryExtractedEvent, type MemoryKind, type MemoryQuarantinedEvent, type MemoryToVerify, type MemoryVaultSearchOptions, type MemoryVaultToolOptions, type MemoryVerification, type MessageRedactionResult, type MessageSkeleton, NEVER_TTL_MS, NODE_BUDGET, NOTION_OAUTH_CONFIG, type NeighborRefiner, type NotionAuthUrlParams, type NotionClientRegistration, type NotionExchangeCodeParams, type NotionMcpCaller, type NotionOAuthEndpoints, type NotionPKCEChallenge, type NotionRefreshTokenParams, type NotionTokenResponse, type NowSource, type ObservationTrend, type ObservationTrendInput, PAST_EVENT_GRACE_MS, PII_PATTERNS, PROFILE_DOC_VERSION, type PhotoIngestResult, type PhotoMediaRef, type PiiCategory, type PiiMatch, type PiiPattern, PiiRedactor, type PiiRedactorOptions, type PlatformStorage, type PortalLlmAuth, type PortalLlmFailure, type PortalLlmFailureReason, type ProfileConfigFingerprint, type ProfileDoc, type ProfileFacet, type ProfileFacetKey, type ProfileSalienceInput, type ProfileSection, type PromptPreProcessor, type PromptPreProcessorContext, type PublishedPhotoMemory, type QuantizedEmbedding, type QuarantinedMemoryInfo, QueueManager, type QueueStatus, RECALL_MAX_LIMIT, RECALL_TOOL_NAME, type RankableVaultMemory, type RankedMemory, type RankedProfileCandidate, type RecallContext, type RecallDegradation, type RecallDiagnostics, type RecallEmptyReason, type RecallOptions, type RecallResult, type RecallToolCallbacks, type RecallToolOptions, type RecencyOptions, type RedactionResult, type ReflectOptions, type ReflectResult, type RequestEncryptionKeyOptions, RerankerUnavailableError, type ResumeStreamOptions, type ResumeStreamResult, type ResumeStreamWithStorageResult, type RetainAction, type RetainContext, type RetainOptions, type RetainResult, type RetainSource, SDK_SCHEMA_VERSION, SHORT_TTL_MS, STREAM_RESUMABLE_HEADER, type ScoreBreakdown, type ScoreProfileSalienceOptions, type ScreenResult, type ScreenedCandidate, type SearchSource, type SendMessageWithStorageArgs, type SendMessageWithStorageDetachedResult, type SendMessageWithStorageResult, type ServerToolsOptions, type ServerToolsResponse, type SignMessageFn, type StockPriceClassification, type StockPricePreProcessorOptions, type ChatCompletionUsage as StoredChatCompletionUsage, type StoredConversation, type StoredConversationMemory, type StoredMessage, type StoredMessageWithSimilarity, type StoredVaultFolder, VaultFolder as StoredVaultFolderModel, type StoredVaultMemory, VaultMemory as StoredVaultMemoryModel, StreamExpiredError, type StreamMetaEvent, type StreamResumeHandle, type StreamSmoothingConfig, type SynthesizeProfileOptions, TOOL_RESULT_ORIGIN, TOPICS_EXTRACTION_VERSION, TOPIC_EXTRACTION_BATCH_SIZE, TREND_RECENT_WINDOW_DAYS, TREND_STALE_WINDOW_DAYS, type TextChunk, type TopicExtractOptions, type TopicExtractionInput, type TopicExtractionRunResult, type TopicSkipReason, type TurnCompleteEvent, type TurnSkippedEvent, type UncheckedReason, type UnverifiableReason, type UpdateVaultFolderOptions, type UpdateVaultMemoryOptions, type UseChatStorageOptions, type UseChatStorageResult, type UseCreditsOptions, type UseCreditsResult, type UseModelsOptions, type UseModelsResult, VAULT_SIZE_HOP_CAP, type VaultEmbeddingCache, type VaultEmbeddingExpectation, type VaultFolderOperationsContext, type VaultMemoryOperationsContext, type VaultMemoryVisibility, type VaultMemoryWriter, type VaultSaveOperation, type VaultSearchResult, type VaultWriteAction, type VaultWriteInput, type VaultWriteOutcome, type VerificationSources, type VerifyMemoriesForPublishOptions, WalletPoller, type WeatherClassification, type WeatherPreProcessorOptions, type WebSearchClassification, type WebSearchPreProcessorOptions, addConversationMemoriesOp, archiveVaultMemoryOp, assembleMemoryContext, attachFileContextToLastUserMessage, backfillMemoryTopicsOp, buildAttachedFilesText, buildNotionAuthUrl, capHopsForDensity, chatStorageMigrations, chatStorageSchema, chunkAndEmbedAllMessages, chunkAndEmbedMessage, chunkText, classifyCryptoPrice, classifyCryptoPriceBatch, classifyDecay, classifyInjectionCandidates, classifyObservationTrend, classifyStockPrice, classifyStockPriceBatch, classifyWeather, classifyWeatherBatch, classifyWebSearch, classifyWebSearchBatch, clearAllEncryptionKeys, clearAllEncryptionState, clearConversationMemoriesOp, clearEncryptionKey, clearLazyTitleCache, clearServerToolsCache, consoleLogger, conversationMemoryToStored, cosineInt8, createAutoExtractor, createChunkVectorCache, createCryptoPricePreProcessor, createDecaySweeper, createDurableAutoExtractor, createLlmDecayClassifier, createLlmNeighborRefiner, createMemoryEngineTool, createMemoryVaultSearchTool, createMemoryVaultTool, createMessageSourceResolver, createNotionProxyTools, createNotionTools, createPlatformCursorStore, createRecallTool, createStockPricePreProcessor, createStreamingDeAnonymizer, createVaultEmbeddingCache, createVaultFolderOp, createVaultMemoriesBatchOp, createVaultMemoryOp, createWeatherPreProcessor, createWebSearchPreProcessor, decodeChunkVector, decryptConversationTitle, deleteAllVaultMemoriesForUserOp, deleteMessageOp, deleteVaultFolderOp, deleteVaultMemoryOp, dequantizeEmbedding, discoverNotionOAuthEndpoints, eagerEmbedContent, embedAllMessages, embedMessage, encodeChunkVector, ensureDefaultFoldersOp, exchangeNotionCode, extractAndLinkEntitiesForMemoriesOp, extractAndRetain, extractEntitiesForMemories, extractFacts, formatFileProcessingNotes, generateConversationId, generateEmbedding, generateEmbeddings, generateNotionPKCE, getAllVaultFoldersOp, getAllVaultMemoriesOp, getAllVaultMemoryContentsOp, getCachedServerTools, getConversationMemoriesOp, getConversationsByProjectLazyOp, getConversationsLazyOp, getConversationsPageOp, getDecayCandidatesRawOp, getLogger, getMemoriesNeedingTopicExtractionOp, getServerTools, getUnfiledVaultMemoriesOp, getVaultFolderMemoryCountOp, getVaultMemoriesByIdsOp, getVaultMemoryOp, getVaultRankingProjectionsOp, hardDeleteDecayedOp, hasEncryptionKey, ingestPublishedPhotoMemoriesOp, injectionSignatureCatalog, isAttachedFilesText, isDegradedTopicSkip, isEncrypted, isPiiRedactor, isRerankerAvailable, maskScopedEmbeddingCache, moveMemoriesToFolderOp, noopLogger, onKeyAvailable, parseMedia, preEmbedVaultMemories, quantizeEmbedding, queueManager, rankProfileCandidates, recall, reflect, refreshEncryptionKeyIfMatches, refreshNotionAccessToken, registerNotionClient, relinkMemoryTopicsOp, requestEncryptionKey, resolvePiiRedactor, restoreVaultMemoryOp, resumeStream, retain, scoreProfileSalience, screenCandidatesForInjection, sdkMigrations, sdkModelClasses, sdkSchema, searchVaultMemories, seedEncryptionKeys, setLogger, setMemoryVisibilityOp, shouldChunkMessage, shouldRecallMemory, stampTopicsExtractedAtOp, streamCancelPath, streamReplayPath, summarizeObservationTrends, supersedeVaultMemoryOp, synthesizeProfile, traverseGraphLane, ttlForType, updateVaultFolderContextOp, updateVaultFolderOp, updateVaultMemoryEmbeddingOp, updateVaultMemoryOp, upsertMessageOp, useChat, useChatStorage, useCredits, useEncryption, useModels, verifyMemoriesForPublish, xhrTransport };
11359
+ export { type AutoExtractMessage, type AutoExtractor, type Budget, CHUNKS_DISCARDED_ORIGIN, type CachedChunkVectors, type CachedServerTools, Conversation as ChatConversation, Message as ChatMessage, type ChatRole, type ChunkVectorCache, type ChunkingOptions, type ConsolidationAction, type ConsolidationFallbackReason, type ConversationMemoryInput, ConversationMemory as ConversationMemoryModel, type ConversationMemoryOperationsContext, type CreateAutoExtractorOptions, type CreateConversationOptions, type CreateDecaySweeperOptions, type CreateMessageOptions, type CreateVaultFolderOptions, type CreateVaultMemoryOptions, type CryptoPriceClassification, type CryptoPricePreProcessorOptions, DEFAULT_CACHE_EXPIRATION_MS, DEFAULT_CHUNK_CACHE_SIZE, DEFAULT_CHUNK_OVERLAP, DEFAULT_CHUNK_SIZE, DEFAULT_DECAY_POLICY, DEFAULT_MAX_CLASSIFIER_CALLS_PER_SWEEP, DEFAULT_MIN_CHUNK_SIZE, DEFAULT_PROFILE_FACETS, DEFAULT_PROFILE_FACT_TYPE_WEIGHTS, DEFAULT_PROFILE_PROOF_ALPHA, DEFAULT_PROFILE_TREND_MULTIPLIERS, DEFAULT_VAULT_CACHE_SIZE, DatabaseManager, type DatabaseManagerLogger, type DatabaseManagerOptions, type DecayCandidateRaw, type DecayClassifier, type DecayInput, type DecayPolicy, type DecaySweepResult, type DecaySweeper, type DecayVerdict, type DurableAutoExtractorOptions, ENTITY_FANOUT, type EmbeddedWalletSignerFn, EncryptionKeyMissingError, type ExtractFactsOptions, type ExtractOutcome, type ExtractedCandidate, type ExtractedEntity, type ExtractionCursorStore, type ExtractionFunnel, type ExtractionTimings, type FactType, type FileMetadata, type FileProcessingReason, type FileProcessingStatus, type FlushResult, type GetConversationsPageOptions, type GetMessagesPageOptions, type GraphTraversalOptions, HARD_DELETE_WINDOW_MS, INFERENCE_ID_HEADER, type InjectionClassifierOptions, type InjectionReason, type LazyStoredConversation, type LlmDecayClassifierOptions, type LlmNeighborRefinerOptions, type Logger, LoggerProvider, type LoggerProviderProps, MAX_HOPS, MEDIUM_TTL_MS, type ManualFactType, type MemoriesNeedingTopicExtraction, type MemoryContextItem, type MemoryContextLane, type MemoryContextOptions, type MemoryContextResult, type EmbeddingOptions as MemoryEngineEmbeddingOptions, type MemoryEngineResult, type MemoryEngineSearchOptions, type MemoryExtractedEvent, type MemoryKind, type MemoryQuarantinedEvent, type MemoryToVerify, type MemoryVaultSearchOptions, type MemoryVaultToolOptions, type MemoryVerification, type MessageRedactionResult, type MessageSkeleton, NEVER_TTL_MS, NODE_BUDGET, NOTION_OAUTH_CONFIG, type NeighborRefiner, type NotionAuthUrlParams, type NotionClientRegistration, type NotionExchangeCodeParams, type NotionMcpCaller, type NotionOAuthEndpoints, type NotionPKCEChallenge, type NotionRefreshTokenParams, type NotionTokenResponse, type NowSource, type ObservationTrend, type ObservationTrendInput, PAST_EVENT_GRACE_MS, PII_PATTERNS, PROFILE_DOC_VERSION, type PhotoIngestResult, type PhotoMediaRef, type PiiCategory, type PiiMatch, type PiiPattern, PiiRedactor, type PiiRedactorOptions, type PlatformStorage, type PortalLlmAuth, type PortalLlmFailure, type PortalLlmFailureReason, type ProfileConfigFingerprint, type ProfileDoc, type ProfileFacet, type ProfileFacetKey, type ProfileSalienceInput, type ProfileSection, type PromptPreProcessor, type PromptPreProcessorContext, type PublishedPhotoMemory, type QuantizedEmbedding, type QuarantinedMemoryInfo, QueueManager, type QueueStatus, RECALL_MAX_LIMIT, RECALL_TOOL_NAME, type RankableVaultMemory, type RankedMemory, type RankedProfileCandidate, type RecallContext, type RecallDegradation, type RecallDiagnostics, type RecallEmptyReason, type RecallOptions, type RecallResult, type RecallToolCallbacks, type RecallToolOptions, type RecencyOptions, type RedactionResult, type ReflectOptions, type ReflectResult, type RequestEncryptionKeyOptions, RerankerUnavailableError, type ResumeStreamOptions, type ResumeStreamResult, type ResumeStreamWithStorageResult, type RetainAction, type RetainContext, type RetainOptions, type RetainResult, type RetainSource, SDK_SCHEMA_VERSION, SHORT_TTL_MS, STREAM_RESUMABLE_HEADER, type ScoreBreakdown, type ScoreProfileSalienceOptions, type ScreenResult, type ScreenedCandidate, type SearchSource, type SendMessageWithStorageArgs, type SendMessageWithStorageDetachedResult, type SendMessageWithStorageResult, type ServerToolsOptions, type ServerToolsResponse, type SignMessageFn, type StockPriceClassification, type StockPricePreProcessorOptions, type ChatCompletionUsage as StoredChatCompletionUsage, type StoredConversation, type StoredConversationMemory, type StoredMessage, type StoredMessageWithSimilarity, type StoredVaultFolder, VaultFolder as StoredVaultFolderModel, type StoredVaultMemory, VaultMemory as StoredVaultMemoryModel, StreamExpiredError, type StreamMetaEvent, type StreamResumeHandle, type StreamSmoothingConfig, type SynthesizeProfileOptions, TOOL_RESULT_ORIGIN, TOPICS_EXTRACTION_VERSION, TOPIC_EXTRACTION_BATCH_SIZE, TREND_RECENT_WINDOW_DAYS, TREND_STALE_WINDOW_DAYS, type TextChunk, type TopicExtractOptions, type TopicExtractionInput, type TopicExtractionRunResult, type TopicSkipReason, type TurnCompleteEvent, type TurnSkippedEvent, type UncheckedReason, type UnverifiableReason, type UpdateVaultFolderOptions, type UpdateVaultMemoryOptions, type UseChatStorageOptions, type UseChatStorageResult, type UseCreditsOptions, type UseCreditsResult, type UseModelsOptions, type UseModelsResult, VAULT_SIZE_HOP_CAP, type VaultEmbeddingCache, type VaultEmbeddingExpectation, type VaultFolderOperationsContext, type VaultMemoryOperationsContext, type VaultMemoryVisibility, type VaultMemoryWriter, type VaultSaveOperation, type VaultSearchResult, type VaultWriteAction, type VaultWriteInput, type VaultWriteOutcome, type VerificationSources, type VerifyMemoriesForPublishOptions, WalletPoller, type WeatherClassification, type WeatherPreProcessorOptions, type WebSearchClassification, type WebSearchPreProcessorOptions, addConversationMemoriesOp, archiveVaultMemoryOp, assembleMemoryContext, attachFileContextToLastUserMessage, backfillMemoryTopicsOp, buildAttachedFilesText, buildNotionAuthUrl, capHopsForDensity, chatStorageMigrations, chatStorageSchema, chunkAndEmbedAllMessages, chunkAndEmbedMessage, chunkText, classifyCryptoPrice, classifyCryptoPriceBatch, classifyDecay, classifyInjectionCandidates, classifyObservationTrend, classifyStockPrice, classifyStockPriceBatch, classifyWeather, classifyWeatherBatch, classifyWebSearch, classifyWebSearchBatch, clearAllEncryptionKeys, clearAllEncryptionState, clearConversationMemoriesOp, clearEncryptionKey, clearLazyTitleCache, clearServerToolsCache, consoleLogger, conversationMemoryToStored, cosineInt8, createAutoExtractor, createChunkVectorCache, createCryptoPricePreProcessor, createDecaySweeper, createDurableAutoExtractor, createLlmDecayClassifier, createLlmNeighborRefiner, createMemoryEngineTool, createMemoryVaultSearchTool, createMemoryVaultTool, createMessageSourceResolver, createNotionProxyTools, createNotionTools, createPlatformCursorStore, createRecallTool, createStockPricePreProcessor, createStreamingDeAnonymizer, createVaultEmbeddingCache, createVaultFolderOp, createVaultMemoriesBatchOp, createVaultMemoryOp, createWeatherPreProcessor, createWebSearchPreProcessor, decodeChunkVector, decryptConversationTitle, deleteAllVaultMemoriesForUserOp, deleteMessageOp, deleteVaultFolderOp, deleteVaultMemoryOp, dequantizeEmbedding, deriveKeyFromSignatureBytes, discoverNotionOAuthEndpoints, eagerEmbedContent, embedAllMessages, embedMessage, encodeChunkVector, ensureDefaultFoldersOp, exchangeNotionCode, extractAndLinkEntitiesForMemoriesOp, extractAndRetain, extractEntitiesForMemories, extractFacts, formatFileProcessingNotes, generateConversationId, generateEmbedding, generateEmbeddings, generateNotionPKCE, getAllVaultFoldersOp, getAllVaultMemoriesOp, getAllVaultMemoryContentsOp, getCachedServerTools, getConversationMemoriesOp, getConversationsByProjectLazyOp, getConversationsLazyOp, getConversationsPageOp, getDecayCandidatesRawOp, getLogger, getMemoriesNeedingTopicExtractionOp, getServerTools, getUnfiledVaultMemoriesOp, getVaultFolderMemoryCountOp, getVaultMemoriesByIdsOp, getVaultMemoryOp, getVaultRankingProjectionsOp, hardDeleteDecayedOp, hasEncryptionKey, ingestPublishedPhotoMemoriesOp, injectionSignatureCatalog, isAttachedFilesText, isDegradedTopicSkip, isEncrypted, isPiiRedactor, isRerankerAvailable, maskScopedEmbeddingCache, moveMemoriesToFolderOp, noopLogger, onKeyAvailable, parseMedia, preEmbedVaultMemories, quantizeEmbedding, queueManager, rankProfileCandidates, recall, reflect, refreshEncryptionKeyIfMatches, refreshNotionAccessToken, registerNotionClient, relinkMemoryTopicsOp, requestEncryptionKey, resolvePiiRedactor, restoreVaultMemoryOp, resumeStream, retain, scoreProfileSalience, screenCandidatesForInjection, sdkMigrations, sdkModelClasses, sdkSchema, searchVaultMemories, seedEncryptionKeys, setLogger, setMemoryVisibilityOp, shouldChunkMessage, shouldRecallMemory, stampTopicsExtractedAtOp, streamCancelPath, streamReplayPath, summarizeObservationTrends, supersedeVaultMemoryOp, synthesizeProfile, traverseGraphLane, ttlForType, updateVaultFolderContextOp, updateVaultFolderOp, updateVaultMemoryEmbeddingOp, updateVaultMemoryOp, upsertMessageOp, useChat, useChatStorage, useCredits, useEncryption, useModels, verifyMemoriesForPublish, xhrTransport };
@@ -4446,6 +4446,10 @@ declare class Conversation extends Model {
4446
4446
  * Encryption key version type.
4447
4447
  * - "v2": Legacy SHA-256 derived key (for reading enc:v2: data)
4448
4448
  * - "v3": HKDF derived key with domain separation (for new encryption)
4449
+ *
4450
+ * Raw signature bytes (Privy Solana `signMessage` returns a `Uint8Array`) are
4451
+ * not a stored version. Derive them with {@link deriveKeyFromSignatureBytes}.
4452
+ * {@link requestEncryptionKey} still derives v2 and v3 from a hex signature only.
4449
4453
  */
4450
4454
  type EncryptionKeyVersion = "v2" | "v3";
4451
4455
  /**
@@ -4515,6 +4519,25 @@ declare function clearAllEncryptionState(): void;
4515
4519
  * requests, and derived ECDH key pairs (both in-memory and persisted).
4516
4520
  */
4517
4521
  declare function clearAllEncryptionKeys(): void;
4522
+ /**
4523
+ * Derives the bytes-native AES key from a raw signature.
4524
+ *
4525
+ * Privy Solana `signMessage` returns a `Uint8Array`. Pass those bytes here.
4526
+ * The signature is never hex-encoded, base58-encoded, or passed through
4527
+ * `String()`. That string round-trip is what made {@link hexToBytes} store
4528
+ * zeros for every non-hex pair and yield a low-entropy AES key.
4529
+ *
4530
+ * This is the derivation for the next key version (`anuma-sdk-aes-gcm-v4`).
4531
+ * {@link requestEncryptionKey} does not install it; v2 and v3 stay on the
4532
+ * hex-string path so existing ciphertext keeps decrypting. The return value
4533
+ * is the same 64-char hex form the in-memory store already uses.
4534
+ *
4535
+ * @param signature - Raw signature bytes. Must be at least 64 bytes.
4536
+ * @returns 32-byte AES-GCM key as hex, without a `0x` prefix.
4537
+ * @throws Error when `signature` is shorter than 64 bytes.
4538
+ * @category Encryption
4539
+ */
4540
+ declare function deriveKeyFromSignatureBytes(signature: Uint8Array): Promise<string>;
4518
4541
  /**
4519
4542
  * Checks if an encryption key exists in memory for the given wallet address.
4520
4543
  *
@@ -4550,6 +4573,11 @@ interface SignMessageOptions {
4550
4573
  /**
4551
4574
  * Type for the signMessage function that client must provide.
4552
4575
  * This is typically from Privy's useSignMessage hook.
4576
+ *
4577
+ * The resolved value must be a hex signature (`0x`-prefixed or bare). A
4578
+ * non-hex string — including `String(uint8Array)` or a base58 signature —
4579
+ * throws from key derivation instead of becoming a zero-filled AES key.
4580
+ * Raw signature bytes go to {@link deriveKeyFromSignatureBytes}.
4553
4581
  */
4554
4582
  type SignMessageFn = (message: string, options?: SignMessageOptions) => Promise<string>;
4555
4583
  /**
@@ -11328,4 +11356,4 @@ declare function createNotionTools(getAccessToken: () => string | null, requestN
11328
11356
  */
11329
11357
  declare function createNotionProxyTools(callMcp: NotionMcpCaller): ToolConfig[];
11330
11358
 
11331
- export { type AutoExtractMessage, type AutoExtractor, type Budget, CHUNKS_DISCARDED_ORIGIN, type CachedChunkVectors, type CachedServerTools, Conversation as ChatConversation, Message as ChatMessage, type ChatRole, type ChunkVectorCache, type ChunkingOptions, type ConsolidationAction, type ConsolidationFallbackReason, type ConversationMemoryInput, ConversationMemory as ConversationMemoryModel, type ConversationMemoryOperationsContext, type CreateAutoExtractorOptions, type CreateConversationOptions, type CreateDecaySweeperOptions, type CreateMessageOptions, type CreateVaultFolderOptions, type CreateVaultMemoryOptions, type CryptoPriceClassification, type CryptoPricePreProcessorOptions, DEFAULT_CACHE_EXPIRATION_MS, DEFAULT_CHUNK_CACHE_SIZE, DEFAULT_CHUNK_OVERLAP, DEFAULT_CHUNK_SIZE, DEFAULT_DECAY_POLICY, DEFAULT_MAX_CLASSIFIER_CALLS_PER_SWEEP, DEFAULT_MIN_CHUNK_SIZE, DEFAULT_PROFILE_FACETS, DEFAULT_PROFILE_FACT_TYPE_WEIGHTS, DEFAULT_PROFILE_PROOF_ALPHA, DEFAULT_PROFILE_TREND_MULTIPLIERS, DEFAULT_VAULT_CACHE_SIZE, DatabaseManager, type DatabaseManagerLogger, type DatabaseManagerOptions, type DecayCandidateRaw, type DecayClassifier, type DecayInput, type DecayPolicy, type DecaySweepResult, type DecaySweeper, type DecayVerdict, type DurableAutoExtractorOptions, ENTITY_FANOUT, type EmbeddedWalletSignerFn, EncryptionKeyMissingError, type ExtractFactsOptions, type ExtractOutcome, type ExtractedCandidate, type ExtractedEntity, type ExtractionCursorStore, type ExtractionFunnel, type ExtractionTimings, type FactType, type FileMetadata, type FileProcessingReason, type FileProcessingStatus, type FlushResult, type GetConversationsPageOptions, type GetMessagesPageOptions, type GraphTraversalOptions, HARD_DELETE_WINDOW_MS, INFERENCE_ID_HEADER, type InjectionClassifierOptions, type InjectionReason, type LazyStoredConversation, type LlmDecayClassifierOptions, type LlmNeighborRefinerOptions, type Logger, LoggerProvider, type LoggerProviderProps, MAX_HOPS, MEDIUM_TTL_MS, type ManualFactType, type MemoriesNeedingTopicExtraction, type MemoryContextItem, type MemoryContextLane, type MemoryContextOptions, type MemoryContextResult, type EmbeddingOptions as MemoryEngineEmbeddingOptions, type MemoryEngineResult, type MemoryEngineSearchOptions, type MemoryExtractedEvent, type MemoryKind, type MemoryQuarantinedEvent, type MemoryToVerify, type MemoryVaultSearchOptions, type MemoryVaultToolOptions, type MemoryVerification, type MessageRedactionResult, type MessageSkeleton, NEVER_TTL_MS, NODE_BUDGET, NOTION_OAUTH_CONFIG, type NeighborRefiner, type NotionAuthUrlParams, type NotionClientRegistration, type NotionExchangeCodeParams, type NotionMcpCaller, type NotionOAuthEndpoints, type NotionPKCEChallenge, type NotionRefreshTokenParams, type NotionTokenResponse, type NowSource, type ObservationTrend, type ObservationTrendInput, PAST_EVENT_GRACE_MS, PII_PATTERNS, PROFILE_DOC_VERSION, type PhotoIngestResult, type PhotoMediaRef, type PiiCategory, type PiiMatch, type PiiPattern, PiiRedactor, type PiiRedactorOptions, type PlatformStorage, type PortalLlmAuth, type PortalLlmFailure, type PortalLlmFailureReason, type ProfileConfigFingerprint, type ProfileDoc, type ProfileFacet, type ProfileFacetKey, type ProfileSalienceInput, type ProfileSection, type PromptPreProcessor, type PromptPreProcessorContext, type PublishedPhotoMemory, type QuantizedEmbedding, type QuarantinedMemoryInfo, QueueManager, type QueueStatus, RECALL_MAX_LIMIT, RECALL_TOOL_NAME, type RankableVaultMemory, type RankedMemory, type RankedProfileCandidate, type RecallContext, type RecallDegradation, type RecallDiagnostics, type RecallEmptyReason, type RecallOptions, type RecallResult, type RecallToolCallbacks, type RecallToolOptions, type RecencyOptions, type RedactionResult, type ReflectOptions, type ReflectResult, type RequestEncryptionKeyOptions, RerankerUnavailableError, type ResumeStreamOptions, type ResumeStreamResult, type ResumeStreamWithStorageResult, type RetainAction, type RetainContext, type RetainOptions, type RetainResult, type RetainSource, SDK_SCHEMA_VERSION, SHORT_TTL_MS, STREAM_RESUMABLE_HEADER, type ScoreBreakdown, type ScoreProfileSalienceOptions, type ScreenResult, type ScreenedCandidate, type SearchSource, type SendMessageWithStorageArgs, type SendMessageWithStorageDetachedResult, type SendMessageWithStorageResult, type ServerToolsOptions, type ServerToolsResponse, type SignMessageFn, type StockPriceClassification, type StockPricePreProcessorOptions, type ChatCompletionUsage as StoredChatCompletionUsage, type StoredConversation, type StoredConversationMemory, type StoredMessage, type StoredMessageWithSimilarity, type StoredVaultFolder, VaultFolder as StoredVaultFolderModel, type StoredVaultMemory, VaultMemory as StoredVaultMemoryModel, StreamExpiredError, type StreamMetaEvent, type StreamResumeHandle, type StreamSmoothingConfig, type SynthesizeProfileOptions, TOOL_RESULT_ORIGIN, TOPICS_EXTRACTION_VERSION, TOPIC_EXTRACTION_BATCH_SIZE, TREND_RECENT_WINDOW_DAYS, TREND_STALE_WINDOW_DAYS, type TextChunk, type TopicExtractOptions, type TopicExtractionInput, type TopicExtractionRunResult, type TopicSkipReason, type TurnCompleteEvent, type TurnSkippedEvent, type UncheckedReason, type UnverifiableReason, type UpdateVaultFolderOptions, type UpdateVaultMemoryOptions, type UseChatStorageOptions, type UseChatStorageResult, type UseCreditsOptions, type UseCreditsResult, type UseModelsOptions, type UseModelsResult, VAULT_SIZE_HOP_CAP, type VaultEmbeddingCache, type VaultEmbeddingExpectation, type VaultFolderOperationsContext, type VaultMemoryOperationsContext, type VaultMemoryVisibility, type VaultMemoryWriter, type VaultSaveOperation, type VaultSearchResult, type VaultWriteAction, type VaultWriteInput, type VaultWriteOutcome, type VerificationSources, type VerifyMemoriesForPublishOptions, WalletPoller, type WeatherClassification, type WeatherPreProcessorOptions, type WebSearchClassification, type WebSearchPreProcessorOptions, addConversationMemoriesOp, archiveVaultMemoryOp, assembleMemoryContext, attachFileContextToLastUserMessage, backfillMemoryTopicsOp, buildAttachedFilesText, buildNotionAuthUrl, capHopsForDensity, chatStorageMigrations, chatStorageSchema, chunkAndEmbedAllMessages, chunkAndEmbedMessage, chunkText, classifyCryptoPrice, classifyCryptoPriceBatch, classifyDecay, classifyInjectionCandidates, classifyObservationTrend, classifyStockPrice, classifyStockPriceBatch, classifyWeather, classifyWeatherBatch, classifyWebSearch, classifyWebSearchBatch, clearAllEncryptionKeys, clearAllEncryptionState, clearConversationMemoriesOp, clearEncryptionKey, clearLazyTitleCache, clearServerToolsCache, consoleLogger, conversationMemoryToStored, cosineInt8, createAutoExtractor, createChunkVectorCache, createCryptoPricePreProcessor, createDecaySweeper, createDurableAutoExtractor, createLlmDecayClassifier, createLlmNeighborRefiner, createMemoryEngineTool, createMemoryVaultSearchTool, createMemoryVaultTool, createMessageSourceResolver, createNotionProxyTools, createNotionTools, createPlatformCursorStore, createRecallTool, createStockPricePreProcessor, createStreamingDeAnonymizer, createVaultEmbeddingCache, createVaultFolderOp, createVaultMemoriesBatchOp, createVaultMemoryOp, createWeatherPreProcessor, createWebSearchPreProcessor, decodeChunkVector, decryptConversationTitle, deleteAllVaultMemoriesForUserOp, deleteMessageOp, deleteVaultFolderOp, deleteVaultMemoryOp, dequantizeEmbedding, discoverNotionOAuthEndpoints, eagerEmbedContent, embedAllMessages, embedMessage, encodeChunkVector, ensureDefaultFoldersOp, exchangeNotionCode, extractAndLinkEntitiesForMemoriesOp, extractAndRetain, extractEntitiesForMemories, extractFacts, formatFileProcessingNotes, generateConversationId, generateEmbedding, generateEmbeddings, generateNotionPKCE, getAllVaultFoldersOp, getAllVaultMemoriesOp, getAllVaultMemoryContentsOp, getCachedServerTools, getConversationMemoriesOp, getConversationsByProjectLazyOp, getConversationsLazyOp, getConversationsPageOp, getDecayCandidatesRawOp, getLogger, getMemoriesNeedingTopicExtractionOp, getServerTools, getUnfiledVaultMemoriesOp, getVaultFolderMemoryCountOp, getVaultMemoriesByIdsOp, getVaultMemoryOp, getVaultRankingProjectionsOp, hardDeleteDecayedOp, hasEncryptionKey, ingestPublishedPhotoMemoriesOp, injectionSignatureCatalog, isAttachedFilesText, isDegradedTopicSkip, isEncrypted, isPiiRedactor, isRerankerAvailable, maskScopedEmbeddingCache, moveMemoriesToFolderOp, noopLogger, onKeyAvailable, parseMedia, preEmbedVaultMemories, quantizeEmbedding, queueManager, rankProfileCandidates, recall, reflect, refreshEncryptionKeyIfMatches, refreshNotionAccessToken, registerNotionClient, relinkMemoryTopicsOp, requestEncryptionKey, resolvePiiRedactor, restoreVaultMemoryOp, resumeStream, retain, scoreProfileSalience, screenCandidatesForInjection, sdkMigrations, sdkModelClasses, sdkSchema, searchVaultMemories, seedEncryptionKeys, setLogger, setMemoryVisibilityOp, shouldChunkMessage, shouldRecallMemory, stampTopicsExtractedAtOp, streamCancelPath, streamReplayPath, summarizeObservationTrends, supersedeVaultMemoryOp, synthesizeProfile, traverseGraphLane, ttlForType, updateVaultFolderContextOp, updateVaultFolderOp, updateVaultMemoryEmbeddingOp, updateVaultMemoryOp, upsertMessageOp, useChat, useChatStorage, useCredits, useEncryption, useModels, verifyMemoriesForPublish, xhrTransport };
11359
+ export { type AutoExtractMessage, type AutoExtractor, type Budget, CHUNKS_DISCARDED_ORIGIN, type CachedChunkVectors, type CachedServerTools, Conversation as ChatConversation, Message as ChatMessage, type ChatRole, type ChunkVectorCache, type ChunkingOptions, type ConsolidationAction, type ConsolidationFallbackReason, type ConversationMemoryInput, ConversationMemory as ConversationMemoryModel, type ConversationMemoryOperationsContext, type CreateAutoExtractorOptions, type CreateConversationOptions, type CreateDecaySweeperOptions, type CreateMessageOptions, type CreateVaultFolderOptions, type CreateVaultMemoryOptions, type CryptoPriceClassification, type CryptoPricePreProcessorOptions, DEFAULT_CACHE_EXPIRATION_MS, DEFAULT_CHUNK_CACHE_SIZE, DEFAULT_CHUNK_OVERLAP, DEFAULT_CHUNK_SIZE, DEFAULT_DECAY_POLICY, DEFAULT_MAX_CLASSIFIER_CALLS_PER_SWEEP, DEFAULT_MIN_CHUNK_SIZE, DEFAULT_PROFILE_FACETS, DEFAULT_PROFILE_FACT_TYPE_WEIGHTS, DEFAULT_PROFILE_PROOF_ALPHA, DEFAULT_PROFILE_TREND_MULTIPLIERS, DEFAULT_VAULT_CACHE_SIZE, DatabaseManager, type DatabaseManagerLogger, type DatabaseManagerOptions, type DecayCandidateRaw, type DecayClassifier, type DecayInput, type DecayPolicy, type DecaySweepResult, type DecaySweeper, type DecayVerdict, type DurableAutoExtractorOptions, ENTITY_FANOUT, type EmbeddedWalletSignerFn, EncryptionKeyMissingError, type ExtractFactsOptions, type ExtractOutcome, type ExtractedCandidate, type ExtractedEntity, type ExtractionCursorStore, type ExtractionFunnel, type ExtractionTimings, type FactType, type FileMetadata, type FileProcessingReason, type FileProcessingStatus, type FlushResult, type GetConversationsPageOptions, type GetMessagesPageOptions, type GraphTraversalOptions, HARD_DELETE_WINDOW_MS, INFERENCE_ID_HEADER, type InjectionClassifierOptions, type InjectionReason, type LazyStoredConversation, type LlmDecayClassifierOptions, type LlmNeighborRefinerOptions, type Logger, LoggerProvider, type LoggerProviderProps, MAX_HOPS, MEDIUM_TTL_MS, type ManualFactType, type MemoriesNeedingTopicExtraction, type MemoryContextItem, type MemoryContextLane, type MemoryContextOptions, type MemoryContextResult, type EmbeddingOptions as MemoryEngineEmbeddingOptions, type MemoryEngineResult, type MemoryEngineSearchOptions, type MemoryExtractedEvent, type MemoryKind, type MemoryQuarantinedEvent, type MemoryToVerify, type MemoryVaultSearchOptions, type MemoryVaultToolOptions, type MemoryVerification, type MessageRedactionResult, type MessageSkeleton, NEVER_TTL_MS, NODE_BUDGET, NOTION_OAUTH_CONFIG, type NeighborRefiner, type NotionAuthUrlParams, type NotionClientRegistration, type NotionExchangeCodeParams, type NotionMcpCaller, type NotionOAuthEndpoints, type NotionPKCEChallenge, type NotionRefreshTokenParams, type NotionTokenResponse, type NowSource, type ObservationTrend, type ObservationTrendInput, PAST_EVENT_GRACE_MS, PII_PATTERNS, PROFILE_DOC_VERSION, type PhotoIngestResult, type PhotoMediaRef, type PiiCategory, type PiiMatch, type PiiPattern, PiiRedactor, type PiiRedactorOptions, type PlatformStorage, type PortalLlmAuth, type PortalLlmFailure, type PortalLlmFailureReason, type ProfileConfigFingerprint, type ProfileDoc, type ProfileFacet, type ProfileFacetKey, type ProfileSalienceInput, type ProfileSection, type PromptPreProcessor, type PromptPreProcessorContext, type PublishedPhotoMemory, type QuantizedEmbedding, type QuarantinedMemoryInfo, QueueManager, type QueueStatus, RECALL_MAX_LIMIT, RECALL_TOOL_NAME, type RankableVaultMemory, type RankedMemory, type RankedProfileCandidate, type RecallContext, type RecallDegradation, type RecallDiagnostics, type RecallEmptyReason, type RecallOptions, type RecallResult, type RecallToolCallbacks, type RecallToolOptions, type RecencyOptions, type RedactionResult, type ReflectOptions, type ReflectResult, type RequestEncryptionKeyOptions, RerankerUnavailableError, type ResumeStreamOptions, type ResumeStreamResult, type ResumeStreamWithStorageResult, type RetainAction, type RetainContext, type RetainOptions, type RetainResult, type RetainSource, SDK_SCHEMA_VERSION, SHORT_TTL_MS, STREAM_RESUMABLE_HEADER, type ScoreBreakdown, type ScoreProfileSalienceOptions, type ScreenResult, type ScreenedCandidate, type SearchSource, type SendMessageWithStorageArgs, type SendMessageWithStorageDetachedResult, type SendMessageWithStorageResult, type ServerToolsOptions, type ServerToolsResponse, type SignMessageFn, type StockPriceClassification, type StockPricePreProcessorOptions, type ChatCompletionUsage as StoredChatCompletionUsage, type StoredConversation, type StoredConversationMemory, type StoredMessage, type StoredMessageWithSimilarity, type StoredVaultFolder, VaultFolder as StoredVaultFolderModel, type StoredVaultMemory, VaultMemory as StoredVaultMemoryModel, StreamExpiredError, type StreamMetaEvent, type StreamResumeHandle, type StreamSmoothingConfig, type SynthesizeProfileOptions, TOOL_RESULT_ORIGIN, TOPICS_EXTRACTION_VERSION, TOPIC_EXTRACTION_BATCH_SIZE, TREND_RECENT_WINDOW_DAYS, TREND_STALE_WINDOW_DAYS, type TextChunk, type TopicExtractOptions, type TopicExtractionInput, type TopicExtractionRunResult, type TopicSkipReason, type TurnCompleteEvent, type TurnSkippedEvent, type UncheckedReason, type UnverifiableReason, type UpdateVaultFolderOptions, type UpdateVaultMemoryOptions, type UseChatStorageOptions, type UseChatStorageResult, type UseCreditsOptions, type UseCreditsResult, type UseModelsOptions, type UseModelsResult, VAULT_SIZE_HOP_CAP, type VaultEmbeddingCache, type VaultEmbeddingExpectation, type VaultFolderOperationsContext, type VaultMemoryOperationsContext, type VaultMemoryVisibility, type VaultMemoryWriter, type VaultSaveOperation, type VaultSearchResult, type VaultWriteAction, type VaultWriteInput, type VaultWriteOutcome, type VerificationSources, type VerifyMemoriesForPublishOptions, WalletPoller, type WeatherClassification, type WeatherPreProcessorOptions, type WebSearchClassification, type WebSearchPreProcessorOptions, addConversationMemoriesOp, archiveVaultMemoryOp, assembleMemoryContext, attachFileContextToLastUserMessage, backfillMemoryTopicsOp, buildAttachedFilesText, buildNotionAuthUrl, capHopsForDensity, chatStorageMigrations, chatStorageSchema, chunkAndEmbedAllMessages, chunkAndEmbedMessage, chunkText, classifyCryptoPrice, classifyCryptoPriceBatch, classifyDecay, classifyInjectionCandidates, classifyObservationTrend, classifyStockPrice, classifyStockPriceBatch, classifyWeather, classifyWeatherBatch, classifyWebSearch, classifyWebSearchBatch, clearAllEncryptionKeys, clearAllEncryptionState, clearConversationMemoriesOp, clearEncryptionKey, clearLazyTitleCache, clearServerToolsCache, consoleLogger, conversationMemoryToStored, cosineInt8, createAutoExtractor, createChunkVectorCache, createCryptoPricePreProcessor, createDecaySweeper, createDurableAutoExtractor, createLlmDecayClassifier, createLlmNeighborRefiner, createMemoryEngineTool, createMemoryVaultSearchTool, createMemoryVaultTool, createMessageSourceResolver, createNotionProxyTools, createNotionTools, createPlatformCursorStore, createRecallTool, createStockPricePreProcessor, createStreamingDeAnonymizer, createVaultEmbeddingCache, createVaultFolderOp, createVaultMemoriesBatchOp, createVaultMemoryOp, createWeatherPreProcessor, createWebSearchPreProcessor, decodeChunkVector, decryptConversationTitle, deleteAllVaultMemoriesForUserOp, deleteMessageOp, deleteVaultFolderOp, deleteVaultMemoryOp, dequantizeEmbedding, deriveKeyFromSignatureBytes, discoverNotionOAuthEndpoints, eagerEmbedContent, embedAllMessages, embedMessage, encodeChunkVector, ensureDefaultFoldersOp, exchangeNotionCode, extractAndLinkEntitiesForMemoriesOp, extractAndRetain, extractEntitiesForMemories, extractFacts, formatFileProcessingNotes, generateConversationId, generateEmbedding, generateEmbeddings, generateNotionPKCE, getAllVaultFoldersOp, getAllVaultMemoriesOp, getAllVaultMemoryContentsOp, getCachedServerTools, getConversationMemoriesOp, getConversationsByProjectLazyOp, getConversationsLazyOp, getConversationsPageOp, getDecayCandidatesRawOp, getLogger, getMemoriesNeedingTopicExtractionOp, getServerTools, getUnfiledVaultMemoriesOp, getVaultFolderMemoryCountOp, getVaultMemoriesByIdsOp, getVaultMemoryOp, getVaultRankingProjectionsOp, hardDeleteDecayedOp, hasEncryptionKey, ingestPublishedPhotoMemoriesOp, injectionSignatureCatalog, isAttachedFilesText, isDegradedTopicSkip, isEncrypted, isPiiRedactor, isRerankerAvailable, maskScopedEmbeddingCache, moveMemoriesToFolderOp, noopLogger, onKeyAvailable, parseMedia, preEmbedVaultMemories, quantizeEmbedding, queueManager, rankProfileCandidates, recall, reflect, refreshEncryptionKeyIfMatches, refreshNotionAccessToken, registerNotionClient, relinkMemoryTopicsOp, requestEncryptionKey, resolvePiiRedactor, restoreVaultMemoryOp, resumeStream, retain, scoreProfileSalience, screenCandidatesForInjection, sdkMigrations, sdkModelClasses, sdkSchema, searchVaultMemories, seedEncryptionKeys, setLogger, setMemoryVisibilityOp, shouldChunkMessage, shouldRecallMemory, stampTopicsExtractedAtOp, streamCancelPath, streamReplayPath, summarizeObservationTrends, supersedeVaultMemoryOp, synthesizeProfile, traverseGraphLane, ttlForType, updateVaultFolderContextOp, updateVaultFolderOp, updateVaultMemoryEmbeddingOp, updateVaultMemoryOp, upsertMessageOp, useChat, useChatStorage, useCredits, useEncryption, useModels, verifyMemoriesForPublish, xhrTransport };
@@ -273,11 +273,32 @@ function clearAllEncryptionState() {
273
273
  function clearAllEncryptionKeys() {
274
274
  clearAllEncryptionState();
275
275
  }
276
+ function hexNibble(code) {
277
+ if (code >= 48 && code <= 57) return code - 48;
278
+ if (code >= 65 && code <= 70) return code - 55;
279
+ if (code >= 97 && code <= 102) return code - 87;
280
+ return -1;
281
+ }
276
282
  function hexToBytes(hex) {
283
+ if (typeof hex !== "string") {
284
+ throw new TypeError(
285
+ "hexToBytes: expected a hex string. Pass raw signature bytes to deriveKeyFromSignatureBytes instead of stringifying them."
286
+ );
287
+ }
277
288
  const cleanHex = hex.startsWith("0x") ? hex.slice(2) : hex;
289
+ if (cleanHex.length === 0 || cleanHex.length % 2 !== 0) {
290
+ throw new Error(
291
+ `hexToBytes: invalid hex string (expected a non-empty even length, got ${cleanHex.length})`
292
+ );
293
+ }
278
294
  const bytes = new Uint8Array(cleanHex.length / 2);
279
295
  for (let i = 0; i < cleanHex.length; i += 2) {
280
- bytes[i / 2] = parseInt(cleanHex.slice(i, i + 2), 16);
296
+ const hi = hexNibble(cleanHex.charCodeAt(i));
297
+ const lo = hexNibble(cleanHex.charCodeAt(i + 1));
298
+ if (hi < 0 || lo < 0) {
299
+ throw new Error(`hexToBytes: invalid hex string (non-hex character at index ${i})`);
300
+ }
301
+ bytes[i / 2] = hi << 4 | lo;
281
302
  }
282
303
  return bytes;
283
304
  }
@@ -289,15 +310,12 @@ var SHARED_TEXT_DECODER = new TextDecoder();
289
310
  function isValidWalletAddress(address) {
290
311
  return /^0x[a-fA-F0-9]{40}$/.test(address);
291
312
  }
292
- async function deriveKeyFromSignature(signature) {
293
- const sigBytes = hexToBytes(signature);
294
- const hashBuffer = await crypto.subtle.digest("SHA-256", sigBytes.buffer);
295
- const hashBytes = new Uint8Array(hashBuffer);
296
- return bytesToHex(hashBytes);
297
- }
298
- async function deriveKeyFromSignatureV3(signature) {
299
- const sigBytes = hexToBytes(signature);
300
- const ikm = await crypto.subtle.digest("SHA-256", sigBytes.buffer);
313
+ var AES_GCM_V3_INFO = "anuma-sdk-aes-gcm-v3";
314
+ var AES_GCM_V4_INFO = "anuma-sdk-aes-gcm-v4";
315
+ var MIN_SIGNATURE_BYTES = 64;
316
+ async function deriveHkdfAesKeyHex(signatureBytes, info) {
317
+ const sigBytes = new Uint8Array(signatureBytes);
318
+ const ikm = await crypto.subtle.digest("SHA-256", sigBytes);
301
319
  const hkdfKey = await crypto.subtle.importKey("raw", ikm, { name: "HKDF" }, false, [
302
320
  "deriveBits"
303
321
  ]);
@@ -307,13 +325,32 @@ async function deriveKeyFromSignatureV3(signature) {
307
325
  hash: "SHA-256",
308
326
  salt: new Uint8Array(32),
309
327
  // Zero salt (HKDF spec: uses hash-length zero buffer)
310
- info: SHARED_TEXT_ENCODER.encode("anuma-sdk-aes-gcm-v3")
328
+ info: SHARED_TEXT_ENCODER.encode(info)
311
329
  },
312
330
  hkdfKey,
313
331
  256
314
332
  );
315
333
  return bytesToHex(new Uint8Array(derivedBits));
316
334
  }
335
+ async function deriveKeyFromSignature(signature) {
336
+ const sigBytes = hexToBytes(signature);
337
+ const hashBuffer = await crypto.subtle.digest("SHA-256", sigBytes.buffer);
338
+ return bytesToHex(new Uint8Array(hashBuffer));
339
+ }
340
+ async function deriveKeyFromSignatureV3(signature) {
341
+ return deriveHkdfAesKeyHex(hexToBytes(signature), AES_GCM_V3_INFO);
342
+ }
343
+ async function deriveKeyFromSignatureBytes(signature) {
344
+ if (!(signature instanceof Uint8Array)) {
345
+ throw new TypeError("deriveKeyFromSignatureBytes: expected a Uint8Array signature");
346
+ }
347
+ if (signature.byteLength < MIN_SIGNATURE_BYTES) {
348
+ throw new Error(
349
+ `deriveKeyFromSignatureBytes: signature must be at least ${MIN_SIGNATURE_BYTES} bytes, got ${signature.byteLength}`
350
+ );
351
+ }
352
+ return deriveHkdfAesKeyHex(signature, AES_GCM_V4_INFO);
353
+ }
317
354
  function getStoredKeyPair(address) {
318
355
  return keyPairStore.get(address) ?? null;
319
356
  }
@@ -331,8 +368,9 @@ async function deriveKeyPairFromSignature(signature, address) {
331
368
  {
332
369
  name: "HKDF",
333
370
  hash: "SHA-256",
371
+ // EVM addresses are case-insensitive. Base58 is not — this salt stays
372
+ // behind the EVM address gate in requestKeyPair.
334
373
  salt: SHARED_TEXT_ENCODER.encode(address.toLowerCase()),
335
- // Wallet address as salt
336
374
  info: SHARED_TEXT_ENCODER.encode("ECDH-P256-KeyPair")
337
375
  // Context info
338
376
  },
@@ -24019,6 +24057,7 @@ export {
24019
24057
  deleteVaultFolderOp,
24020
24058
  deleteVaultMemoryOp,
24021
24059
  dequantizeEmbedding,
24060
+ deriveKeyFromSignatureBytes,
24022
24061
  discoverNotionOAuthEndpoints,
24023
24062
  eagerEmbedContent,
24024
24063
  embedAllMessages,
package/dist/index.cjs CHANGED
@@ -2916,11 +2916,32 @@ function getStoredKeyByVersion(address, version) {
2916
2916
  const value = version === "v2" ? keys.legacy : keys.current;
2917
2917
  return value ?? null;
2918
2918
  }
2919
+ function hexNibble(code) {
2920
+ if (code >= 48 && code <= 57) return code - 48;
2921
+ if (code >= 65 && code <= 70) return code - 55;
2922
+ if (code >= 97 && code <= 102) return code - 87;
2923
+ return -1;
2924
+ }
2919
2925
  function hexToBytes(hex) {
2926
+ if (typeof hex !== "string") {
2927
+ throw new TypeError(
2928
+ "hexToBytes: expected a hex string. Pass raw signature bytes to deriveKeyFromSignatureBytes instead of stringifying them."
2929
+ );
2930
+ }
2920
2931
  const cleanHex = hex.startsWith("0x") ? hex.slice(2) : hex;
2932
+ if (cleanHex.length === 0 || cleanHex.length % 2 !== 0) {
2933
+ throw new Error(
2934
+ `hexToBytes: invalid hex string (expected a non-empty even length, got ${cleanHex.length})`
2935
+ );
2936
+ }
2921
2937
  const bytes = new Uint8Array(cleanHex.length / 2);
2922
2938
  for (let i = 0; i < cleanHex.length; i += 2) {
2923
- bytes[i / 2] = parseInt(cleanHex.slice(i, i + 2), 16);
2939
+ const hi = hexNibble(cleanHex.charCodeAt(i));
2940
+ const lo = hexNibble(cleanHex.charCodeAt(i + 1));
2941
+ if (hi < 0 || lo < 0) {
2942
+ throw new Error(`hexToBytes: invalid hex string (non-hex character at index ${i})`);
2943
+ }
2944
+ bytes[i / 2] = hi << 4 | lo;
2924
2945
  }
2925
2946
  return bytes;
2926
2947
  }
package/dist/index.mjs CHANGED
@@ -2710,11 +2710,32 @@ function getStoredKeyByVersion(address, version) {
2710
2710
  const value = version === "v2" ? keys.legacy : keys.current;
2711
2711
  return value ?? null;
2712
2712
  }
2713
+ function hexNibble(code) {
2714
+ if (code >= 48 && code <= 57) return code - 48;
2715
+ if (code >= 65 && code <= 70) return code - 55;
2716
+ if (code >= 97 && code <= 102) return code - 87;
2717
+ return -1;
2718
+ }
2713
2719
  function hexToBytes(hex) {
2720
+ if (typeof hex !== "string") {
2721
+ throw new TypeError(
2722
+ "hexToBytes: expected a hex string. Pass raw signature bytes to deriveKeyFromSignatureBytes instead of stringifying them."
2723
+ );
2724
+ }
2714
2725
  const cleanHex = hex.startsWith("0x") ? hex.slice(2) : hex;
2726
+ if (cleanHex.length === 0 || cleanHex.length % 2 !== 0) {
2727
+ throw new Error(
2728
+ `hexToBytes: invalid hex string (expected a non-empty even length, got ${cleanHex.length})`
2729
+ );
2730
+ }
2715
2731
  const bytes = new Uint8Array(cleanHex.length / 2);
2716
2732
  for (let i = 0; i < cleanHex.length; i += 2) {
2717
- bytes[i / 2] = parseInt(cleanHex.slice(i, i + 2), 16);
2733
+ const hi = hexNibble(cleanHex.charCodeAt(i));
2734
+ const lo = hexNibble(cleanHex.charCodeAt(i + 1));
2735
+ if (hi < 0 || lo < 0) {
2736
+ throw new Error(`hexToBytes: invalid hex string (non-hex character at index ${i})`);
2737
+ }
2738
+ bytes[i / 2] = hi << 4 | lo;
2718
2739
  }
2719
2740
  return bytes;
2720
2741
  }
@@ -10,6 +10,11 @@ interface SignMessageOptions {
10
10
  /**
11
11
  * Type for the signMessage function that client must provide.
12
12
  * This is typically from Privy's useSignMessage hook.
13
+ *
14
+ * The resolved value must be a hex signature (`0x`-prefixed or bare). A
15
+ * non-hex string — including `String(uint8Array)` or a base58 signature —
16
+ * throws from key derivation instead of becoming a zero-filled AES key.
17
+ * Raw signature bytes go to {@link deriveKeyFromSignatureBytes}.
13
18
  */
14
19
  type SignMessageFn = (message: string, options?: SignMessageOptions) => Promise<string>;
15
20
  /**
@@ -10,6 +10,11 @@ interface SignMessageOptions {
10
10
  /**
11
11
  * Type for the signMessage function that client must provide.
12
12
  * This is typically from Privy's useSignMessage hook.
13
+ *
14
+ * The resolved value must be a hex signature (`0x`-prefixed or bare). A
15
+ * non-hex string — including `String(uint8Array)` or a base58 signature —
16
+ * throws from key derivation instead of becoming a zero-filled AES key.
17
+ * Raw signature bytes go to {@link deriveKeyFromSignatureBytes}.
13
18
  */
14
19
  type SignMessageFn = (message: string, options?: SignMessageOptions) => Promise<string>;
15
20
  /**
@@ -1591,6 +1591,7 @@ __export(index_exports, {
1591
1591
  deleteVaultFolderOp: () => deleteVaultFolderOp,
1592
1592
  deleteVaultMemoryOp: () => deleteVaultMemoryOp,
1593
1593
  dequantizeEmbedding: () => dequantizeEmbedding,
1594
+ deriveKeyFromSignatureBytes: () => deriveKeyFromSignatureBytes,
1594
1595
  eagerEmbedContent: () => eagerEmbedContent,
1595
1596
  embedAllMessages: () => embedAllMessages,
1596
1597
  embedMessage: () => embedMessage,
@@ -2244,11 +2245,32 @@ function clearAllEncryptionState() {
2244
2245
  function clearAllEncryptionKeys() {
2245
2246
  clearAllEncryptionState();
2246
2247
  }
2248
+ function hexNibble(code) {
2249
+ if (code >= 48 && code <= 57) return code - 48;
2250
+ if (code >= 65 && code <= 70) return code - 55;
2251
+ if (code >= 97 && code <= 102) return code - 87;
2252
+ return -1;
2253
+ }
2247
2254
  function hexToBytes(hex) {
2255
+ if (typeof hex !== "string") {
2256
+ throw new TypeError(
2257
+ "hexToBytes: expected a hex string. Pass raw signature bytes to deriveKeyFromSignatureBytes instead of stringifying them."
2258
+ );
2259
+ }
2248
2260
  const cleanHex = hex.startsWith("0x") ? hex.slice(2) : hex;
2261
+ if (cleanHex.length === 0 || cleanHex.length % 2 !== 0) {
2262
+ throw new Error(
2263
+ `hexToBytes: invalid hex string (expected a non-empty even length, got ${cleanHex.length})`
2264
+ );
2265
+ }
2249
2266
  const bytes = new Uint8Array(cleanHex.length / 2);
2250
2267
  for (let i = 0; i < cleanHex.length; i += 2) {
2251
- bytes[i / 2] = parseInt(cleanHex.slice(i, i + 2), 16);
2268
+ const hi = hexNibble(cleanHex.charCodeAt(i));
2269
+ const lo = hexNibble(cleanHex.charCodeAt(i + 1));
2270
+ if (hi < 0 || lo < 0) {
2271
+ throw new Error(`hexToBytes: invalid hex string (non-hex character at index ${i})`);
2272
+ }
2273
+ bytes[i / 2] = hi << 4 | lo;
2252
2274
  }
2253
2275
  return bytes;
2254
2276
  }
@@ -2260,15 +2282,12 @@ var SHARED_TEXT_DECODER = new TextDecoder();
2260
2282
  function isValidWalletAddress(address) {
2261
2283
  return /^0x[a-fA-F0-9]{40}$/.test(address);
2262
2284
  }
2263
- async function deriveKeyFromSignature(signature) {
2264
- const sigBytes = hexToBytes(signature);
2265
- const hashBuffer = await crypto.subtle.digest("SHA-256", sigBytes.buffer);
2266
- const hashBytes = new Uint8Array(hashBuffer);
2267
- return bytesToHex(hashBytes);
2268
- }
2269
- async function deriveKeyFromSignatureV3(signature) {
2270
- const sigBytes = hexToBytes(signature);
2271
- const ikm = await crypto.subtle.digest("SHA-256", sigBytes.buffer);
2285
+ var AES_GCM_V3_INFO = "anuma-sdk-aes-gcm-v3";
2286
+ var AES_GCM_V4_INFO = "anuma-sdk-aes-gcm-v4";
2287
+ var MIN_SIGNATURE_BYTES = 64;
2288
+ async function deriveHkdfAesKeyHex(signatureBytes, info) {
2289
+ const sigBytes = new Uint8Array(signatureBytes);
2290
+ const ikm = await crypto.subtle.digest("SHA-256", sigBytes);
2272
2291
  const hkdfKey = await crypto.subtle.importKey("raw", ikm, { name: "HKDF" }, false, [
2273
2292
  "deriveBits"
2274
2293
  ]);
@@ -2278,13 +2297,32 @@ async function deriveKeyFromSignatureV3(signature) {
2278
2297
  hash: "SHA-256",
2279
2298
  salt: new Uint8Array(32),
2280
2299
  // Zero salt (HKDF spec: uses hash-length zero buffer)
2281
- info: SHARED_TEXT_ENCODER.encode("anuma-sdk-aes-gcm-v3")
2300
+ info: SHARED_TEXT_ENCODER.encode(info)
2282
2301
  },
2283
2302
  hkdfKey,
2284
2303
  256
2285
2304
  );
2286
2305
  return bytesToHex(new Uint8Array(derivedBits));
2287
2306
  }
2307
+ async function deriveKeyFromSignature(signature) {
2308
+ const sigBytes = hexToBytes(signature);
2309
+ const hashBuffer = await crypto.subtle.digest("SHA-256", sigBytes.buffer);
2310
+ return bytesToHex(new Uint8Array(hashBuffer));
2311
+ }
2312
+ async function deriveKeyFromSignatureV3(signature) {
2313
+ return deriveHkdfAesKeyHex(hexToBytes(signature), AES_GCM_V3_INFO);
2314
+ }
2315
+ async function deriveKeyFromSignatureBytes(signature) {
2316
+ if (!(signature instanceof Uint8Array)) {
2317
+ throw new TypeError("deriveKeyFromSignatureBytes: expected a Uint8Array signature");
2318
+ }
2319
+ if (signature.byteLength < MIN_SIGNATURE_BYTES) {
2320
+ throw new Error(
2321
+ `deriveKeyFromSignatureBytes: signature must be at least ${MIN_SIGNATURE_BYTES} bytes, got ${signature.byteLength}`
2322
+ );
2323
+ }
2324
+ return deriveHkdfAesKeyHex(signature, AES_GCM_V4_INFO);
2325
+ }
2288
2326
  function getStoredKeyPair(address) {
2289
2327
  return keyPairStore.get(address) ?? null;
2290
2328
  }
@@ -2302,8 +2340,9 @@ async function deriveKeyPairFromSignature(signature, address) {
2302
2340
  {
2303
2341
  name: "HKDF",
2304
2342
  hash: "SHA-256",
2343
+ // EVM addresses are case-insensitive. Base58 is not — this salt stays
2344
+ // behind the EVM address gate in requestKeyPair.
2305
2345
  salt: SHARED_TEXT_ENCODER.encode(address.toLowerCase()),
2306
- // Wallet address as salt
2307
2346
  info: SHARED_TEXT_ENCODER.encode("ECDH-P256-KeyPair")
2308
2347
  // Context info
2309
2348
  },
@@ -36861,6 +36900,7 @@ function renderAnumaJsx(jsx3) {
36861
36900
  deleteVaultFolderOp,
36862
36901
  deleteVaultMemoryOp,
36863
36902
  dequantizeEmbedding,
36903
+ deriveKeyFromSignatureBytes,
36864
36904
  eagerEmbedContent,
36865
36905
  embedAllMessages,
36866
36906
  embedMessage,