inf_circle_sdk/contract/
dto.rs

1use crate::{helper::PaginationParams, types::Blockchain};
2use chrono::{DateTime, Utc};
3use serde::{Deserialize, Serialize};
4
5/// Request structure for estimating contract template deployment fee
6#[derive(Debug, Serialize)]
7#[serde(rename_all = "camelCase")]
8pub struct EstimateTemplateDeploymentFeeBody {
9    /// Blockchain network
10    pub blockchain: Blockchain,
11
12    /// Constructor parameters
13    #[serde(skip_serializing_if = "Option::is_none")]
14    pub constructor_params: Option<Vec<serde_json::Value>>,
15
16    /// Wallet ID for deployment
17    pub wallet_id: String,
18}
19
20/// Request structure for deploying a contract from template
21#[derive(Debug, Serialize)]
22#[serde(rename_all = "camelCase")]
23pub struct DeployContractFromTemplateRequest {
24    /// Entity secret ciphertext
25    pub entity_secret_ciphertext: String,
26
27    /// Contract name
28    pub name: String,
29
30    /// Wallet ID for deployment
31    pub wallet_id: String,
32
33    /// Blockchain network
34    pub blockchain: String,
35
36    /// UUID v4 for idempotency
37    pub idempotency_key: String,
38
39    /// Description of the contract
40    #[serde(skip_serializing_if = "Option::is_none")]
41    pub description: Option<String>,
42
43    /// Template parameters for initialization
44    #[serde(skip_serializing_if = "Option::is_none")]
45    pub template_parameters: Option<serde_json::Value>,
46
47    /// Fee level (LOW, MEDIUM, HIGH)
48    #[serde(skip_serializing_if = "Option::is_none")]
49    pub fee_level: Option<String>,
50
51    /// Gas limit
52    #[serde(skip_serializing_if = "Option::is_none")]
53    pub gas_limit: Option<String>,
54
55    /// Gas price (for non-EIP-1559)
56    #[serde(skip_serializing_if = "Option::is_none")]
57    pub gas_price: Option<String>,
58
59    /// Max fee (for EIP-1559)
60    #[serde(skip_serializing_if = "Option::is_none")]
61    pub max_fee: Option<String>,
62
63    /// Priority fee (for EIP-1559)
64    #[serde(skip_serializing_if = "Option::is_none")]
65    pub priority_fee: Option<String>,
66
67    /// Reference ID
68    #[serde(skip_serializing_if = "Option::is_none")]
69    pub ref_id: Option<String>,
70}
71
72/// Request structure for importing an existing contract
73#[derive(Debug, Serialize)]
74#[serde(rename_all = "camelCase")]
75pub struct ImportContractRequest {
76    /// Blockchain network
77    pub blockchain: Blockchain,
78
79    /// Contract address on blockchain
80    pub address: String,
81
82    /// Contract name
83    pub name: String,
84
85    /// UUID v4 for idempotency
86    pub idempotency_key: String,
87
88    /// Description of the contract
89    #[serde(skip_serializing_if = "Option::is_none")]
90    pub description: Option<String>,
91}
92
93/// Request structure for updating a contract
94#[derive(Debug, Serialize)]
95#[serde(rename_all = "camelCase")]
96pub struct UpdateContractRequest {
97    /// Contract name
98    #[serde(skip_serializing_if = "Option::is_none")]
99    pub name: Option<String>,
100
101    /// Reference ID
102    #[serde(skip_serializing_if = "Option::is_none")]
103    pub ref_id: Option<String>,
104}
105
106/// Fee level details
107#[derive(Debug, Deserialize)]
108#[serde(rename_all = "camelCase")]
109pub struct FeeLevelEstimate {
110    /// Gas limit
111    pub gas_limit: String,
112
113    /// Base fee
114    #[serde(skip_serializing_if = "Option::is_none")]
115    pub base_fee: Option<String>,
116
117    /// Priority fee
118    #[serde(skip_serializing_if = "Option::is_none")]
119    pub priority_fee: Option<String>,
120
121    /// Max fee
122    #[serde(skip_serializing_if = "Option::is_none")]
123    pub max_fee: Option<String>,
124
125    /// Gas price (for non-EIP-1559)
126    #[serde(skip_serializing_if = "Option::is_none")]
127    pub gas_price: Option<String>,
128
129    /// Network fee - The estimated network fee (maximum amount in native token like ETH, SOL)
130    #[serde(skip_serializing_if = "Option::is_none")]
131    pub network_fee: Option<String>,
132
133    /// Network fee raw - Similar to network_fee but with lower buffer, closer to actual on-chain expense
134    #[serde(skip_serializing_if = "Option::is_none")]
135    pub network_fee_raw: Option<String>,
136}
137
138/// Fee estimation response
139#[derive(Debug, Deserialize)]
140#[serde(rename_all = "camelCase")]
141pub struct FeeEstimation {
142    /// Low fee estimate
143    pub low: FeeLevelEstimate,
144
145    /// Medium fee estimate
146    pub medium: FeeLevelEstimate,
147
148    /// High fee estimate
149    pub high: FeeLevelEstimate,
150}
151
152/// Contract response structure
153#[derive(Debug, Deserialize, Serialize)]
154#[serde(rename_all = "camelCase")]
155pub struct Contract {
156    /// Unique contract identifier
157    #[serde(skip_serializing_if = "Option::is_none")]
158    pub id: Option<String>,
159
160    /// Contract address on blockchain (optional during deployment)
161    #[serde(skip_serializing_if = "Option::is_none")]
162    pub address: Option<String>,
163
164    /// Contract address on blockchain (alternative field name)
165    #[serde(skip_serializing_if = "Option::is_none")]
166    pub contract_address: Option<String>,
167
168    /// Blockchain network
169    #[serde(skip_serializing_if = "Option::is_none")]
170    pub blockchain: Option<String>,
171
172    /// Creation timestamp
173    #[serde(skip_serializing_if = "Option::is_none")]
174    pub create_date: Option<DateTime<Utc>>,
175
176    /// Last update timestamp
177    #[serde(skip_serializing_if = "Option::is_none")]
178    pub update_date: Option<DateTime<Utc>>,
179
180    /// Contract name
181    #[serde(skip_serializing_if = "Option::is_none")]
182    pub name: Option<String>,
183
184    /// Reference identifier
185    #[serde(skip_serializing_if = "Option::is_none")]
186    pub ref_id: Option<String>,
187
188    /// Contract state
189    #[serde(skip_serializing_if = "Option::is_none")]
190    pub state: Option<String>,
191
192    /// Contract status
193    #[serde(skip_serializing_if = "Option::is_none")]
194    pub status: Option<String>,
195
196    /// Template ID used for deployment
197    #[serde(skip_serializing_if = "Option::is_none")]
198    pub template_id: Option<String>,
199
200    /// Deployer wallet ID
201    #[serde(skip_serializing_if = "Option::is_none")]
202    pub deployer_wallet_id: Option<String>,
203
204    /// Deployment transaction ID
205    #[serde(skip_serializing_if = "Option::is_none")]
206    pub deployment_transaction_id: Option<String>,
207
208    /// Deployment transaction hash
209    #[serde(skip_serializing_if = "Option::is_none")]
210    pub deployment_tx_hash: Option<String>,
211
212    /// Contract input type
213    #[serde(skip_serializing_if = "Option::is_none")]
214    pub contract_input_type: Option<String>,
215
216    /// Whether the contract is archived
217    #[serde(skip_serializing_if = "Option::is_none")]
218    pub archived: Option<bool>,
219
220    /// Contract ABI
221    #[serde(skip_serializing_if = "Option::is_none")]
222    pub abi: Option<serde_json::Value>,
223
224    /// Contract ABI JSON string
225    #[serde(skip_serializing_if = "Option::is_none")]
226    pub abi_json: Option<String>,
227
228    /// Contract bytecode
229    #[serde(skip_serializing_if = "Option::is_none")]
230    pub bytecode: Option<String>,
231
232    /// Contract functions
233    #[serde(skip_serializing_if = "Option::is_none")]
234    pub functions: Option<serde_json::Value>,
235
236    /// Contract events
237    #[serde(skip_serializing_if = "Option::is_none")]
238    pub events: Option<serde_json::Value>,
239
240    /// Verification status
241    #[serde(skip_serializing_if = "Option::is_none")]
242    pub verification_status: Option<String>,
243
244    /// Source code
245    #[serde(skip_serializing_if = "Option::is_none")]
246    pub source_code: Option<serde_json::Value>,
247
248    /// Implementation contract (for proxy contracts)
249    #[serde(skip_serializing_if = "Option::is_none")]
250    pub implementation_contract: Option<Box<Contract>>,
251}
252
253/// Template contract deployment response
254#[derive(Debug, Serialize, Deserialize)]
255#[serde(rename_all = "camelCase")]
256pub struct TemplateContractDeploymentResponse {
257    /// Unique identifiers of the created smart contracts
258    pub contract_ids: Vec<String>,
259
260    /// Unique identifier of the pending deployment transaction
261    pub transaction_id: String,
262}
263
264/// Response from deploying a contract from bytecode
265#[derive(Debug, Serialize, Deserialize)]
266#[serde(rename_all = "camelCase")]
267pub struct ContractDeploymentResponse {
268    /// Unique identifier of the created smart contract
269    pub contract_id: String,
270
271    /// Unique identifier of the deployment transaction
272    pub transaction_id: String,
273}
274
275/// Response from querying a contract
276#[derive(Debug, Serialize, Deserialize)]
277#[serde(rename_all = "camelCase")]
278pub struct QueryContractResponse {
279    /// Output values from the contract query
280    /// Can be null if Circle couldn't decode the output
281    #[serde(default)]
282    pub output_values: Option<Vec<serde_json::Value>>,
283
284    /// Output data in hex format
285    pub output_data: String,
286}
287
288/// Request structure for deploying a contract from bytecode
289#[derive(Debug, Serialize)]
290#[serde(rename_all = "camelCase")]
291pub struct DeployContractRequest {
292    /// Entity secret ciphertext
293    pub entity_secret_ciphertext: String,
294
295    /// Bytecode of the contract being deployed
296    pub bytecode: String,
297
298    /// The contract's ABI in a JSON stringified format
299    pub abi_json: String,
300
301    /// Wallet ID to use as deployment source
302    pub wallet_id: String,
303
304    /// Name for the contract (must be alphanumeric)
305    pub name: String,
306
307    /// Blockchain network
308    pub blockchain: Blockchain,
309
310    /// UUID v4 for idempotency
311    pub idempotency_key: String,
312
313    /// Description of the contract
314    #[serde(skip_serializing_if = "Option::is_none")]
315    pub description: Option<String>,
316
317    /// Constructor parameters
318    #[serde(skip_serializing_if = "Option::is_none")]
319    pub constructor_parameters: Option<Vec<serde_json::Value>>,
320
321    /// Fee level (LOW, MEDIUM, HIGH)
322    #[serde(skip_serializing_if = "Option::is_none")]
323    pub fee_level: Option<String>,
324
325    /// Gas limit
326    #[serde(skip_serializing_if = "Option::is_none")]
327    pub gas_limit: Option<String>,
328
329    /// Gas price (for non-EIP-1559)
330    #[serde(skip_serializing_if = "Option::is_none")]
331    pub gas_price: Option<String>,
332
333    /// Max fee (for EIP-1559)
334    #[serde(skip_serializing_if = "Option::is_none")]
335    pub max_fee: Option<String>,
336
337    /// Priority fee (for EIP-1559)
338    #[serde(skip_serializing_if = "Option::is_none")]
339    pub priority_fee: Option<String>,
340
341    /// Reference ID
342    #[serde(skip_serializing_if = "Option::is_none")]
343    pub ref_id: Option<String>,
344}
345
346/// Contract import/single deployment response
347#[derive(Debug, Deserialize, Serialize)]
348#[serde(rename_all = "camelCase")]
349pub struct ContractResponse {
350    /// Imported or deployed contract
351    pub contract: Contract,
352}
353
354/// Response structure for listing contracts
355#[derive(Debug, Deserialize, Serialize)]
356pub struct ContractsResponse {
357    pub contracts: Vec<Contract>,
358}
359
360/// Query parameters for listing contracts
361#[derive(Debug, Serialize, Default)]
362#[serde(rename_all = "camelCase")]
363pub struct ListContractsParams {
364    /// Filter by contract address
365    #[serde(skip_serializing_if = "Option::is_none")]
366    pub address: Option<String>,
367
368    /// Filter by blockchain
369    #[serde(skip_serializing_if = "Option::is_none")]
370    pub blockchain: Option<Blockchain>,
371
372    /// Filter by template ID
373    #[serde(rename = "templateId", skip_serializing_if = "Option::is_none")]
374    pub template_id: Option<String>,
375
376    /// Filter by reference ID
377    #[serde(rename = "refId", skip_serializing_if = "Option::is_none")]
378    pub ref_id: Option<String>,
379
380    /// Filter by creation date (from)
381    #[serde(skip_serializing_if = "Option::is_none")]
382    pub from: Option<DateTime<Utc>>,
383
384    /// Filter by creation date (to)
385    #[serde(skip_serializing_if = "Option::is_none")]
386    pub to: Option<DateTime<Utc>>,
387
388    /// Pagination parameters
389    #[serde(flatten)]
390    pub pagination: PaginationParams,
391}
392
393/// Notification types for webhook subscriptions
394#[derive(Debug, Deserialize, Serialize, Clone, PartialEq, Eq)]
395#[serde(rename_all = "camelCase")]
396pub enum NotificationType {
397    /// All notification types (wildcard)
398    #[serde(rename = "*")]
399    All,
400
401    /// All transaction notifications
402    #[serde(rename = "transactions.*")]
403    TransactionsAll,
404
405    /// Inbound transaction notifications
406    #[serde(rename = "transactions.inbound")]
407    TransactionsInbound,
408
409    /// Outbound transaction notifications
410    #[serde(rename = "transactions.outbound")]
411    TransactionsOutbound,
412
413    /// All challenge notifications
414    #[serde(rename = "challenges.*")]
415    ChallengesAll,
416
417    /// Accelerate transaction challenge
418    #[serde(rename = "challenges.accelerateTransaction")]
419    ChallengesAccelerateTransaction,
420
421    /// Cancel transaction challenge
422    #[serde(rename = "challenges.cancelTransaction")]
423    ChallengesCancelTransaction,
424
425    /// Change PIN challenge
426    #[serde(rename = "challenges.changePin")]
427    ChallengesChangePin,
428
429    /// Contract execution challenge
430    #[serde(rename = "challenges.contractExecution")]
431    ChallengesContractExecution,
432
433    /// Create transaction challenge
434    #[serde(rename = "challenges.createTransaction")]
435    ChallengesCreateTransaction,
436
437    /// Create wallet challenge
438    #[serde(rename = "challenges.createWallet")]
439    ChallengesCreateWallet,
440
441    /// Initialize challenge
442    #[serde(rename = "challenges.initialize")]
443    ChallengesInitialize,
444
445    /// Restore PIN challenge
446    #[serde(rename = "challenges.restorePin")]
447    ChallengesRestorePin,
448
449    /// Set PIN challenge
450    #[serde(rename = "challenges.setPin")]
451    ChallengesSetPin,
452
453    /// Set security questions challenge
454    #[serde(rename = "challenges.setSecurityQuestions")]
455    ChallengesSetSecurityQuestions,
456
457    /// All contract notifications
458    #[serde(rename = "contracts.*")]
459    ContractsAll,
460
461    /// Contract event log notifications
462    #[serde(rename = "contracts.eventLog")]
463    ContractsEventLog,
464
465    /// All modular wallet notifications
466    #[serde(rename = "modularWallet.*")]
467    ModularWalletAll,
468
469    /// Modular wallet user operation
470    #[serde(rename = "modularWallet.userOperation")]
471    ModularWalletUserOperation,
472
473    /// Modular wallet inbound transfer
474    #[serde(rename = "modularWallet.inboundTransfer")]
475    ModularWalletInboundTransfer,
476
477    /// Modular wallet outbound transfer
478    #[serde(rename = "modularWallet.outboundTransfer")]
479    ModularWalletOutboundTransfer,
480
481    /// All travel rule notifications
482    #[serde(rename = "travelRule.*")]
483    TravelRuleAll,
484
485    /// Travel rule status update
486    #[serde(rename = "travelRule.statusUpdate")]
487    TravelRuleStatusUpdate,
488
489    /// Travel rule deny
490    #[serde(rename = "travelRule.deny")]
491    TravelRuleDeny,
492
493    /// Travel rule approve
494    #[serde(rename = "travelRule.approve")]
495    TravelRuleApprove,
496
497    /// All ramp session notifications
498    #[serde(rename = "rampSession.*")]
499    RampSessionAll,
500
501    /// Ramp session completed
502    #[serde(rename = "rampSession.completed")]
503    RampSessionCompleted,
504
505    /// Ramp session deposit received
506    #[serde(rename = "rampSession.depositReceived")]
507    RampSessionDepositReceived,
508
509    /// Ramp session expired
510    #[serde(rename = "rampSession.expired")]
511    RampSessionExpired,
512
513    /// Ramp session failed
514    #[serde(rename = "rampSession.failed")]
515    RampSessionFailed,
516
517    /// Ramp session KYC approved
518    #[serde(rename = "rampSession.kycApproved")]
519    RampSessionKycApproved,
520
521    /// Ramp session KYC rejected
522    #[serde(rename = "rampSession.kycRejected")]
523    RampSessionKycRejected,
524
525    /// Ramp session KYC submitted
526    #[serde(rename = "rampSession.kycSubmitted")]
527    RampSessionKycSubmitted,
528}
529
530impl NotificationType {
531    /// Convert the enum to its string representation
532    pub fn as_str(&self) -> &'static str {
533        match self {
534            Self::All => "*",
535            Self::TransactionsAll => "transactions.*",
536            Self::TransactionsInbound => "transactions.inbound",
537            Self::TransactionsOutbound => "transactions.outbound",
538            Self::ChallengesAll => "challenges.*",
539            Self::ChallengesAccelerateTransaction => "challenges.accelerateTransaction",
540            Self::ChallengesCancelTransaction => "challenges.cancelTransaction",
541            Self::ChallengesChangePin => "challenges.changePin",
542            Self::ChallengesContractExecution => "challenges.contractExecution",
543            Self::ChallengesCreateTransaction => "challenges.createTransaction",
544            Self::ChallengesCreateWallet => "challenges.createWallet",
545            Self::ChallengesInitialize => "challenges.initialize",
546            Self::ChallengesRestorePin => "challenges.restorePin",
547            Self::ChallengesSetPin => "challenges.setPin",
548            Self::ChallengesSetSecurityQuestions => "challenges.setSecurityQuestions",
549            Self::ContractsAll => "contracts.*",
550            Self::ContractsEventLog => "contracts.eventLog",
551            Self::ModularWalletAll => "modularWallet.*",
552            Self::ModularWalletUserOperation => "modularWallet.userOperation",
553            Self::ModularWalletInboundTransfer => "modularWallet.inboundTransfer",
554            Self::ModularWalletOutboundTransfer => "modularWallet.outboundTransfer",
555            Self::TravelRuleAll => "travelRule.*",
556            Self::TravelRuleStatusUpdate => "travelRule.statusUpdate",
557            Self::TravelRuleDeny => "travelRule.deny",
558            Self::TravelRuleApprove => "travelRule.approve",
559            Self::RampSessionAll => "rampSession.*",
560            Self::RampSessionCompleted => "rampSession.completed",
561            Self::RampSessionDepositReceived => "rampSession.depositReceived",
562            Self::RampSessionExpired => "rampSession.expired",
563            Self::RampSessionFailed => "rampSession.failed",
564            Self::RampSessionKycApproved => "rampSession.kycApproved",
565            Self::RampSessionKycRejected => "rampSession.kycRejected",
566            Self::RampSessionKycSubmitted => "rampSession.kycSubmitted",
567        }
568    }
569}
570
571/// Notification subscription details
572#[derive(Debug, Deserialize, Serialize)]
573#[serde(rename_all = "camelCase")]
574pub struct NotificationSubscription {
575    /// System-generated unique identifier of the subscription
576    pub id: String,
577
578    /// Name of the webhook notification subscription
579    pub name: String,
580
581    /// URL of the endpoint subscribing to notifications
582    pub endpoint: String,
583
584    /// Whether the subscription is enabled
585    pub enabled: bool,
586
587    /// Date and time the subscription was created
588    pub create_date: DateTime<Utc>,
589
590    /// Date and time the subscription was last updated
591    pub update_date: DateTime<Utc>,
592
593    /// The notification types on which a notification will be sent
594    pub notification_types: Vec<NotificationType>,
595
596    /// Whether the webhook is restricted to specific notification types
597    pub restricted: bool,
598}
599
600/// Request structure for creating a notification subscription
601#[derive(Debug, Serialize)]
602#[serde(rename_all = "camelCase")]
603pub struct CreateNotificationSubscriptionBody {
604    /// URL of the endpoint to subscribe to notifications
605    pub endpoint: String,
606
607    /// The notification types to subscribe to
608    #[serde(skip_serializing_if = "Option::is_none")]
609    pub notification_types: Option<Vec<NotificationType>>,
610}
611
612/// Response structure for creating a notification subscription
613/// Note: The API returns the subscription directly, not wrapped in a collection
614pub type CreateNotificationSubscriptionResponse = NotificationSubscription;
615
616/// Request structure for updating a notification subscription
617#[derive(Debug, Serialize)]
618#[serde(rename_all = "camelCase")]
619pub struct UpdateNotificationSubscriptionBody {
620    /// Whether the subscription is enabled. true indicates the subscription is active.
621    pub enabled: bool,
622
623    /// Name of the subscription
624    pub name: String,
625}
626
627/// Response structure for updating a notification subscription
628/// Note: The API returns the subscription directly, not wrapped in a collection
629pub type UpdateNotificationSubscriptionResponse = NotificationSubscription;
630
631/// Response structure for getting health of Circle API
632#[derive(Debug, Deserialize, Serialize)]
633pub struct PingResponse {
634    /// Message
635    pub message: String,
636}
637
638/// Event monitor details
639#[derive(Debug, Deserialize, Serialize)]
640#[serde(rename_all = "camelCase")]
641pub struct EventMonitor {
642    /// System-generated unique identifier of the event monitor
643    pub id: String,
644
645    /// Blockchain network
646    pub blockchain: Blockchain,
647
648    /// The on-chain address of the contract
649    pub contract_address: String,
650
651    /// The specific event signature being monitored
652    pub event_signature: String,
653
654    /// The hash of the event signature
655    pub event_signature_hash: String,
656
657    /// Whether the event monitor is enabled
658    pub is_enabled: bool,
659
660    /// Creation timestamp
661    #[serde(skip_serializing_if = "Option::is_none")]
662    pub create_date: Option<DateTime<Utc>>,
663
664    /// Last update timestamp
665    #[serde(skip_serializing_if = "Option::is_none")]
666    pub update_date: Option<DateTime<Utc>>,
667}
668
669/// Request structure for creating an event monitor
670#[derive(Debug, Serialize)]
671#[serde(rename_all = "camelCase")]
672pub struct CreateEventMonitorRequest {
673    /// UUID v4 for idempotency
674    pub idempotency_key: String,
675
676    /// The specific event signature to monitor (no spaces)
677    pub event_signature: String,
678
679    /// The on-chain address of the contract
680    pub contract_address: String,
681
682    /// Blockchain network
683    pub blockchain: Blockchain,
684}
685
686/// Response structure for creating an event monitor
687#[derive(Debug, Deserialize, Serialize)]
688#[serde(rename_all = "camelCase")]
689pub struct EventMonitorResponse {
690    /// The created event monitor
691    pub event_monitor: EventMonitor,
692}
693
694/// Request structure for updating an event monitor
695#[derive(Debug, Serialize)]
696#[serde(rename_all = "camelCase")]
697pub struct UpdateEventMonitorRequest {
698    /// Indicates whether the event monitor should be active (true) or inactive (false)
699    pub is_enabled: bool,
700}
701
702/// Response structure for listing event monitors
703#[derive(Debug, Deserialize, Serialize)]
704#[serde(rename_all = "camelCase")]
705pub struct EventMonitorsResponse {
706    /// List of event monitors that match criteria
707    pub event_monitors: Vec<EventMonitor>,
708}
709
710/// Query parameters for listing event monitors
711#[derive(Debug, Serialize, Default)]
712#[serde(rename_all = "camelCase")]
713pub struct ListEventMonitorsParams {
714    /// Filter contracts by address
715    #[serde(skip_serializing_if = "Option::is_none")]
716    pub contract_address: Option<String>,
717
718    /// Filter by blockchain
719    #[serde(skip_serializing_if = "Option::is_none")]
720    pub blockchain: Option<Blockchain>,
721
722    /// Filter monitors by event signature
723    #[serde(skip_serializing_if = "Option::is_none")]
724    pub event_signature: Option<String>,
725
726    /// Filter by creation date (from)
727    #[serde(skip_serializing_if = "Option::is_none")]
728    pub from: Option<DateTime<Utc>>,
729
730    /// Filter by creation date (to)
731    #[serde(skip_serializing_if = "Option::is_none")]
732    pub to: Option<DateTime<Utc>>,
733
734    /// Pagination parameters
735    #[serde(flatten)]
736    pub pagination: PaginationParams,
737}
738
739/// Event log details
740#[derive(Debug, Deserialize, Serialize)]
741#[serde(rename_all = "camelCase")]
742pub struct EventLog {
743    /// System-generated unique identifier of the event log
744    pub id: String,
745
746    /// Block hash where the event was emitted
747    pub block_hash: String,
748
749    /// Block height/number where the event was emitted
750    pub block_height: i64,
751
752    /// Blockchain network
753    pub blockchain: Blockchain,
754
755    /// The on-chain address of the contract that emitted the event
756    pub contract_address: String,
757
758    /// The event data in hex format
759    pub data: String,
760
761    /// The event signature
762    pub event_signature: String,
763
764    /// The hash of the event signature
765    pub event_signature_hash: String,
766
767    /// The log index within the transaction
768    pub log_index: String,
769
770    /// Array of indexed topics from the event
771    pub topics: Vec<String>,
772
773    /// Transaction hash where the event was emitted
774    pub tx_hash: String,
775
776    /// User operation hash (for account abstraction)
777    pub user_op_hash: String,
778
779    /// Timestamp when the event was first confirmed
780    pub first_confirm_date: String,
781}
782
783/// Response structure for listing event logs
784#[derive(Debug, Deserialize, Serialize)]
785#[serde(rename_all = "camelCase")]
786pub struct EventLogsResponse {
787    /// List of event logs generated from monitored contract events
788    pub event_logs: Vec<EventLog>,
789}
790
791/// Query parameters for listing event logs
792#[derive(Debug, Serialize, Default, Clone)]
793#[serde(rename_all = "camelCase")]
794pub struct ListEventLogsParams {
795    /// Filter contracts by address
796    #[serde(skip_serializing_if = "Option::is_none")]
797    pub contract_address: Option<String>,
798
799    /// Filter by blockchain
800    #[serde(skip_serializing_if = "Option::is_none")]
801    pub blockchain: Option<Blockchain>,
802
803    /// Filter by creation date (from)
804    #[serde(skip_serializing_if = "Option::is_none")]
805    pub from: Option<DateTime<Utc>>,
806
807    /// Filter by creation date (to)
808    #[serde(skip_serializing_if = "Option::is_none")]
809    pub to: Option<DateTime<Utc>>,
810
811    /// Pagination parameters
812    #[serde(flatten)]
813    pub pagination: PaginationParams,
814}