@hybrd/xmtp 1.4.4 → 2.0.0

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.
@@ -1,275 +0,0 @@
1
- import { http, createPublicClient, formatUnits, parseAbi } from "viem"
2
- import { base, baseSepolia } from "viem/chains"
3
- import { validateEnvironment } from "./client"
4
- import { networks } from "./constants"
5
-
6
- // Get network configuration
7
- const { XMTP_NETWORK_ID } = validateEnvironment(["XMTP_NETWORK_ID"])
8
- const networkConfigResult = networks.find(
9
- (network) => network.networkId === XMTP_NETWORK_ID
10
- )
11
- if (!networkConfigResult) {
12
- throw new Error(`Network ID ${XMTP_NETWORK_ID} not found`)
13
- }
14
- // Use a non-null assertion since we've verified it exists
15
- const networkConfig = networkConfigResult
16
-
17
- // Create public client for monitoring
18
- const publicClient = createPublicClient({
19
- chain: XMTP_NETWORK_ID === "base-mainnet" ? base : baseSepolia,
20
- transport: http()
21
- })
22
-
23
- // ERC20 Transfer event ABI
24
- const erc20Abi = parseAbi([
25
- "event Transfer(address indexed from, address indexed to, uint256 value)",
26
- "function balanceOf(address owner) view returns (uint256)"
27
- ])
28
-
29
- export interface TransactionEvent {
30
- hash: string
31
- from: string
32
- to: string
33
- value: bigint
34
- blockNumber: bigint
35
- timestamp?: bigint
36
- }
37
-
38
- export interface MonitoredWallet {
39
- address: string
40
- tossId: string
41
- lastCheckedBlock?: bigint
42
- }
43
-
44
- export class TransactionMonitor {
45
- private monitoredWallets: Map<string, MonitoredWallet> = new Map()
46
- private isMonitoring = false
47
- private monitoringInterval?: NodeJS.Timeout
48
- private onTransactionCallback?: (
49
- event: TransactionEvent,
50
- wallet: MonitoredWallet
51
- ) => Promise<void>
52
-
53
- /**
54
- * Add a wallet address to monitor
55
- */
56
- async addWalletToMonitor(address: string, tossId: string): Promise<void> {
57
- const lowerAddress = address.toLowerCase()
58
- console.log(
59
- `📍 Adding wallet ${lowerAddress} (toss: ${tossId}) to monitoring`
60
- )
61
-
62
- // Get current block number as starting point
63
- const currentBlock = await publicClient.getBlockNumber()
64
-
65
- this.monitoredWallets.set(lowerAddress, {
66
- address: lowerAddress,
67
- tossId,
68
- lastCheckedBlock: currentBlock
69
- })
70
-
71
- console.log(`✅ Now monitoring ${this.monitoredWallets.size} wallets`)
72
- }
73
-
74
- /**
75
- * Remove a wallet from monitoring
76
- */
77
- removeWalletFromMonitor(address: string): void {
78
- const lowerAddress = address.toLowerCase()
79
- this.monitoredWallets.delete(lowerAddress)
80
- console.log(`🗑️ Removed wallet ${lowerAddress} from monitoring`)
81
- }
82
-
83
- /**
84
- * Set callback function for when transactions are detected
85
- */
86
- onTransaction(
87
- callback: (
88
- event: TransactionEvent,
89
- wallet: MonitoredWallet
90
- ) => Promise<void>
91
- ): void {
92
- this.onTransactionCallback = callback
93
- }
94
-
95
- /**
96
- * Start monitoring for transactions
97
- */
98
- async startMonitoring(intervalMs = 30000): Promise<void> {
99
- if (this.isMonitoring) {
100
- console.log("⚠️ Transaction monitoring is already running")
101
- return
102
- }
103
-
104
- this.isMonitoring = true
105
- console.log(
106
- `🔍 Starting transaction monitoring (checking every ${intervalMs / 1000}s)`
107
- )
108
-
109
- // Initial check
110
- await this.checkForNewTransactions()
111
-
112
- // Set up periodic monitoring
113
- this.monitoringInterval = setInterval(() => {
114
- void (async () => {
115
- try {
116
- await this.checkForNewTransactions()
117
- } catch (error) {
118
- console.error("Error during transaction monitoring:", error)
119
- }
120
- })()
121
- }, intervalMs)
122
-
123
- console.log("✅ Transaction monitoring started")
124
- }
125
-
126
- /**
127
- * Stop monitoring
128
- */
129
- stopMonitoring(): void {
130
- if (this.monitoringInterval) {
131
- clearInterval(this.monitoringInterval)
132
- this.monitoringInterval = undefined
133
- }
134
- this.isMonitoring = false
135
- console.log("🛑 Transaction monitoring stopped")
136
- }
137
-
138
- /**
139
- * Check for new transactions to monitored wallets
140
- */
141
- private async checkForNewTransactions(): Promise<void> {
142
- if (this.monitoredWallets.size === 0) {
143
- return
144
- }
145
-
146
- console.debug(
147
- `🔍 Checking transactions for ${this.monitoredWallets.size} monitored wallets...`
148
- )
149
-
150
- try {
151
- const currentBlock = await publicClient.getBlockNumber()
152
-
153
- for (const [, wallet] of this.monitoredWallets) {
154
- await this.checkWalletTransactions(wallet, currentBlock)
155
- }
156
- } catch (error) {
157
- console.error("Error checking for new transactions:", error)
158
- }
159
- }
160
-
161
- /**
162
- * Check transactions for a specific wallet
163
- */
164
- private async checkWalletTransactions(
165
- wallet: MonitoredWallet,
166
- currentBlock: bigint
167
- ): Promise<void> {
168
- try {
169
- const fromBlock = wallet.lastCheckedBlock || currentBlock - 100n // Check last 100 blocks if no last checked block
170
-
171
- console.debug(
172
- `Checking wallet ${wallet.address} from block ${fromBlock} to ${currentBlock}`
173
- )
174
-
175
- // Get USDC transfer events to this wallet
176
- const logs = await publicClient.getLogs({
177
- address: networkConfig.tokenAddress as `0x${string}`,
178
- event: erc20Abi[0], // Transfer event
179
- args: {
180
- to: wallet.address as `0x${string}`
181
- },
182
- fromBlock: fromBlock + 1n, // +1 to avoid checking same block twice
183
- toBlock: currentBlock
184
- })
185
-
186
- console.debug(
187
- `Found ${logs.length} potential transactions for wallet ${wallet.address}`
188
- )
189
-
190
- for (const log of logs) {
191
- const event: TransactionEvent = {
192
- hash: log.transactionHash,
193
- from: log.args.from as string,
194
- to: log.args.to as string,
195
- value: log.args.value as bigint,
196
- blockNumber: log.blockNumber || 0n
197
- }
198
-
199
- console.log(`🔔 New transaction detected: ${event.hash}`)
200
- console.log(` From: ${event.from}`)
201
- console.log(` To: ${event.to}`)
202
- console.log(
203
- ` Amount: ${formatUnits(event.value, networkConfig.decimals)} USDC`
204
- )
205
-
206
- // Call the callback if set
207
- if (this.onTransactionCallback) {
208
- try {
209
- await this.onTransactionCallback(event, wallet)
210
- } catch (callbackError) {
211
- console.error("Error in transaction callback:", callbackError)
212
- }
213
- }
214
- }
215
-
216
- // Update last checked block for this wallet
217
- wallet.lastCheckedBlock = currentBlock
218
- } catch (error) {
219
- console.error(
220
- `Error checking transactions for wallet ${wallet.address}:`,
221
- error
222
- )
223
- }
224
- }
225
-
226
- /**
227
- * Get current wallet balance
228
- */
229
- async getWalletBalance(address: string): Promise<string> {
230
- try {
231
- const balance = await publicClient.readContract({
232
- address: networkConfig.tokenAddress as `0x${string}`,
233
- abi: erc20Abi,
234
- functionName: "balanceOf",
235
- args: [address as `0x${string}`]
236
- })
237
- return formatUnits(balance, networkConfig.decimals)
238
- } catch (error) {
239
- console.error(`Error getting balance for ${address}:`, error)
240
- return "0"
241
- }
242
- }
243
-
244
- /**
245
- * Check if monitoring is active
246
- */
247
- isActive(): boolean {
248
- return this.isMonitoring
249
- }
250
-
251
- /**
252
- * Get list of monitored wallets
253
- */
254
- getMonitoredWallets(): MonitoredWallet[] {
255
- return Array.from(this.monitoredWallets.values())
256
- }
257
-
258
- /**
259
- * Manual balance check for discrepancies
260
- */
261
- async performBalanceAudit(): Promise<void> {
262
- console.log("🔍 Performing balance audit for monitored wallets...")
263
-
264
- for (const [address, wallet] of this.monitoredWallets) {
265
- try {
266
- const balance = await this.getWalletBalance(address)
267
- console.log(
268
- `💰 Wallet ${address} (toss: ${wallet.tossId}): ${balance} USDC`
269
- )
270
- } catch (error) {
271
- console.error(`Error checking balance for ${address}:`, error)
272
- }
273
- }
274
- }
275
- }
package/src/types.ts.old DELETED
@@ -1,157 +0,0 @@
1
- /**
2
- * @fileoverview XMTP Types
3
- *
4
- * Type definitions for both the XMTP core client and service client library.
5
- */
6
-
7
- import { GroupUpdated } from "@xmtp/content-type-group-updated"
8
- import { Reaction } from "@xmtp/content-type-reaction"
9
- import { Reply } from "@xmtp/content-type-reply"
10
- import { TransactionReference } from "@xmtp/content-type-transaction-reference"
11
- import { WalletSendCallsParams } from "@xmtp/content-type-wallet-send-calls"
12
- import { Client, Conversation, DecodedMessage } from "@xmtp/node-sdk"
13
- import type { Resolver } from "./resolver/resolver"
14
-
15
- export type HonoVariables = {
16
- xmtpClient: XmtpClient
17
- resolver?: Resolver
18
- }
19
-
20
- // ===================================================================
21
- // XMTP Core Client Types
22
- // ===================================================================
23
-
24
- type Codec =
25
- | GroupUpdated
26
- | Reaction
27
- | Reply
28
- | TransactionReference
29
- | WalletSendCallsParams
30
-
31
- export type XmtpClient = Client<string | Codec>
32
- export type XmtpConversation = Conversation<string | Codec>
33
- export type XmtpMessage = DecodedMessage<string | Codec>
34
- export type XmtpSender = {
35
- address: string
36
- inboxId: string
37
- name: string
38
- basename?: string
39
- }
40
- export type XmtpSubjects = Record<string, `0x${string}`>
41
-
42
- export interface MessageEvent {
43
- conversation: XmtpConversation
44
- message: XmtpMessage
45
- rootMessage: XmtpMessage
46
- parentMessage?: XmtpMessage // The directly referenced message if this is a reply
47
- sender: XmtpSender
48
- subjects: XmtpSubjects
49
- }
50
-
51
- // ===================================================================
52
- // XMTP Service Client Types
53
- // ===================================================================
54
-
55
- export interface XmtpServiceClientConfig {
56
- serviceUrl: string
57
- serviceToken: string
58
- }
59
-
60
- export interface TransactionCall {
61
- to: string
62
- data: string
63
- gas?: string
64
- value?: string
65
- metadata?: Record<string, unknown>
66
- }
67
-
68
- export interface TransactionRequest {
69
- fromAddress: string
70
- chainId: string
71
- calls: TransactionCall[]
72
- }
73
-
74
- export interface XmtpServiceResponse<T = unknown> {
75
- success: boolean
76
- data?: T
77
- error?: string
78
- }
79
-
80
- export interface XmtpServiceMessage {
81
- id: string
82
- conversationId: string
83
- content: string | Record<string, unknown>
84
- senderInboxId: string
85
- sentAt: string
86
- contentType?: {
87
- typeId: string
88
- authorityId?: string
89
- versionMajor?: number
90
- versionMinor?: number
91
- }
92
- }
93
-
94
- export interface XmtpRootMessageResponse {
95
- id: string
96
- conversationId: string
97
- content: string | Record<string, unknown>
98
- senderInboxId: string
99
- sentAt: string
100
- contentType?: {
101
- typeId: string
102
- authorityId?: string
103
- versionMajor?: number
104
- versionMinor?: number
105
- }
106
- }
107
-
108
- // Function parameter types
109
- export interface SendMessageParams {
110
- content: string
111
- }
112
-
113
- export interface SendReplyParams {
114
- content: string
115
- messageId: string
116
- }
117
-
118
- export interface SendReactionParams {
119
- messageId: string
120
- emoji: string
121
- action: "added" | "removed"
122
- }
123
-
124
- export interface SendTransactionParams extends TransactionRequest {}
125
-
126
- export interface GetMessageParams {
127
- messageId: string
128
- }
129
-
130
- export interface GetRootMessageParams {
131
- messageId: string
132
- }
133
-
134
- // Response types
135
- export interface SendMessageResponse {
136
- success: boolean
137
- action: "send"
138
- conversationId: string
139
- }
140
-
141
- export interface SendReplyResponse {
142
- success: boolean
143
- action: "reply"
144
- conversationId: string
145
- }
146
-
147
- export interface SendReactionResponse {
148
- success: boolean
149
- action: "react"
150
- conversationId: string
151
- }
152
-
153
- export interface SendTransactionResponse {
154
- success: boolean
155
- action: "transaction"
156
- conversationId: string
157
- }