diff --git a/app/api/inbox/[address]/__tests__/dual-write.test.ts b/app/api/inbox/[address]/__tests__/dual-write.test.ts index 3495e828..0d53998e 100644 --- a/app/api/inbox/[address]/__tests__/dual-write.test.ts +++ b/app/api/inbox/[address]/__tests__/dual-write.test.ts @@ -33,8 +33,6 @@ vi.mock("@/lib/inbox", () => ({ storeStagedInboxPayment: vi.fn(), updateAgentInbox: vi.fn(), updateSentIndex: vi.fn(), - listInboxMessages: vi.fn(), - listSentMessages: vi.fn(), INBOX_PRICE_SATS: 100, REDEEMED_TXID_TTL_SECONDS: 7776000, RELAY_CIRCUIT_BREAKER_RETRY_AFTER_SECONDS: 300, diff --git a/app/api/outbox/[address]/__tests__/rate-limit.test.ts b/app/api/outbox/[address]/__tests__/rate-limit.test.ts index fc25b883..98c4d911 100644 --- a/app/api/outbox/[address]/__tests__/rate-limit.test.ts +++ b/app/api/outbox/[address]/__tests__/rate-limit.test.ts @@ -35,7 +35,6 @@ vi.mock("@/lib/inbox", () => ({ storeReply: vi.fn(), updateMessage: vi.fn(), buildReplyMessage: vi.fn(), - listInboxMessages: vi.fn(), decrementUnreadCount: vi.fn(), })); diff --git a/lib/inbox/__tests__/inbox-pending-no-paymentid.test.ts b/lib/inbox/__tests__/inbox-pending-no-paymentid.test.ts index 73d14705..e16ff151 100644 --- a/lib/inbox/__tests__/inbox-pending-no-paymentid.test.ts +++ b/lib/inbox/__tests__/inbox-pending-no-paymentid.test.ts @@ -20,8 +20,6 @@ const mocks = vi.hoisted(() => ({ storeStagedInboxPayment: vi.fn(), updateAgentInbox: vi.fn(), updateSentIndex: vi.fn(), - listInboxMessages: vi.fn(), - listSentMessages: vi.fn(), buildInboxPaymentRequirements: vi.fn(), buildSenderAuthMessage: vi.fn(), enqueueInboxReconciliation: vi.fn(), @@ -57,8 +55,6 @@ vi.mock("@/lib/inbox", () => ({ storeStagedInboxPayment: mocks.storeStagedInboxPayment, updateAgentInbox: mocks.updateAgentInbox, updateSentIndex: mocks.updateSentIndex, - listInboxMessages: mocks.listInboxMessages, - listSentMessages: mocks.listSentMessages, buildInboxPaymentRequirements: mocks.buildInboxPaymentRequirements, buildSenderAuthMessage: mocks.buildSenderAuthMessage, enqueueInboxReconciliation: mocks.enqueueInboxReconciliation, diff --git a/lib/inbox/index.ts b/lib/inbox/index.ts index e0af23a6..61677aa9 100644 --- a/lib/inbox/index.ts +++ b/lib/inbox/index.ts @@ -88,7 +88,6 @@ export { } from "./x402-config"; // KV Helpers -export type { ListInboxOptions, ListInboxResult, ListSentResult } from "./kv-helpers"; export { getMessage, storeMessage, @@ -103,8 +102,6 @@ export { storeStagedInboxPayment, deleteStagedInboxPayment, finalizeStagedInboxPayment, - listInboxMessages, - listSentMessages, decrementUnreadCount, } from "./kv-helpers"; diff --git a/lib/inbox/kv-helpers.ts b/lib/inbox/kv-helpers.ts index a1f019c5..6fefb1b8 100644 --- a/lib/inbox/kv-helpers.ts +++ b/lib/inbox/kv-helpers.ts @@ -404,89 +404,6 @@ export async function finalizeStagedInboxPayment( return finalizedMessage; } -/** - * Options for listing inbox messages. - */ -export interface ListInboxOptions { - /** Include reply data inline with messages that have been replied to. */ - includeReplies?: boolean; -} - -/** - * Result of listing inbox messages, including the index for metadata. - */ -export interface ListInboxResult { - /** The agent inbox index (null if no inbox exists). */ - index: InboxAgentIndex | null; - /** Paginated messages (newest first). */ - messages: InboxMessage[]; - /** Reply data keyed by messageId (only populated when includeReplies is true). */ - replies: Map; -} - -/** - * List inbox messages for an agent with pagination. - * - * Returns both the index (for totalCount/unreadCount) and messages in a single - * call to avoid redundant KV reads. - * - * @param kv - Cloudflare KV namespace - * @param btcAddress - Bitcoin address - * @param limit - Maximum number of messages to return (default 20) - * @param offset - Number of messages to skip (default 0) - * @param options - Optional settings (e.g., includeReplies) - * @returns ListInboxResult with index, messages, and optional replies - * - * @example - * const { index, messages, replies } = await listInboxMessages(kv, "bc1q...", 10, 0, { includeReplies: true }); - * console.log(`Total: ${index?.messageIds.length}, fetched: ${messages.length}`); - */ -export async function listInboxMessages( - kv: KVNamespace, - btcAddress: string, - limit = 20, - offset = 0, - options: ListInboxOptions = {} -): Promise { - const index = await getAgentInbox(kv, btcAddress); - if (!index || index.messageIds.length === 0) { - return { index, messages: [], replies: new Map() }; - } - - // Reverse to get newest first - const messageIds = [...index.messageIds].reverse(); - - // Apply pagination - const paginatedIds = messageIds.slice(offset, offset + limit); - - // Fetch all messages in parallel - const rawMessages = await Promise.all( - paginatedIds.map((id) => getMessage(kv, id)) - ); - - // Filter out nulls (messages that failed to parse or were deleted) - const messages = rawMessages.filter((m): m is InboxMessage => m !== null); - - // Optionally fetch replies for messages that have been replied to - const replies = new Map(); - if (options.includeReplies) { - const repliedMessages = messages.filter((msg) => msg.repliedAt); - if (repliedMessages.length > 0) { - const replyResults = await Promise.all( - repliedMessages.map((msg) => getReply(kv, msg.messageId)) - ); - repliedMessages.forEach((msg, i) => { - const reply = replyResults[i]; - if (reply) { - replies.set(msg.messageId, reply); - } - }); - } - } - - return { index, messages, replies }; -} - /** * Decrement the unread count for an agent's inbox. * @@ -517,70 +434,3 @@ export async function decrementUnreadCount( await kv.put(key, JSON.stringify(index)); } } - -/** - * Result of listing sent messages, including the sent index for metadata. - */ -export interface ListSentResult { - /** The agent sent index (null if no sent messages). */ - index: SentMessageIndex | null; - /** Paginated messages (newest first). */ - messages: InboxMessage[]; - /** Reply data keyed by messageId (only populated when includeReplies is true). */ - replies: Map; -} - -/** - * List sent messages for an agent with pagination. - * - * @param kv - Cloudflare KV namespace - * @param btcAddress - Sender's Bitcoin address - * @param limit - Maximum number of messages to return (default 20) - * @param offset - Number of messages to skip (default 0) - * @param options - Optional settings (e.g., includeReplies) - * @returns ListSentResult with index, messages, and optional replies - */ -export async function listSentMessages( - kv: KVNamespace, - btcAddress: string, - limit = 20, - offset = 0, - options: ListInboxOptions = {} -): Promise { - const index = await getSentIndex(kv, btcAddress); - if (!index || index.messageIds.length === 0) { - return { index, messages: [], replies: new Map() }; - } - - // Reverse to get newest first - const messageIds = [...index.messageIds].reverse(); - - // Apply pagination - const paginatedIds = messageIds.slice(offset, offset + limit); - - // Fetch all messages in parallel - const rawMessages = await Promise.all( - paginatedIds.map((id) => getMessage(kv, id)) - ); - - const messages = rawMessages.filter((m): m is InboxMessage => m !== null); - - // Optionally fetch replies for messages that have been replied to - const replies = new Map(); - if (options.includeReplies) { - const repliedMessages = messages.filter((msg) => msg.repliedAt); - if (repliedMessages.length > 0) { - const replyResults = await Promise.all( - repliedMessages.map((msg) => getReply(kv, msg.messageId)) - ); - repliedMessages.forEach((msg, i) => { - const reply = replyResults[i]; - if (reply) { - replies.set(msg.messageId, reply); - } - }); - } - } - - return { index, messages, replies }; -}