Conversation
|
Caution Review failedThe pull request is closed. WalkthroughAdds a new Spherre indexer package: configuration, CLI entrypoint, event types and transformers, event handlers, a SpherreMainIndexer implementation, and runner utilities for Apibara-based event streaming and processing. Changes
Sequence Diagram(s)sequenceDiagram
participant CLI
participant Main as main.py
participant Config as config.py
participant Runner as run_main_indexer
participant Indexer as SpherreMainIndexer
participant Apibara as Apibara Stream
participant Transformer as DataTransformer
participant Handlers as EventHandlers
CLI->>Main: start(server_url, mongo_url, restart)
Main->>Config: read defaults (server_url, mongo_url, DNA_TOKEN)
Main->>Runner: run_main_indexer(resolved_urls, dna_token, restart)
Runner->>Indexer: instantiate SpherreMainIndexer()
Runner->>Apibara: start stream with IndexerRunnerConfiguration
Apibara-->>Indexer: emit Block (with events)
rect rgb(230,245,230)
Indexer->>Indexer: handle_data(block)
Indexer->>Transformer: select transformer by event selector
Transformer-->>Indexer: AccountCreationEvent or None
Indexer->>Handlers: dispatch to appropriate handler (e.g., handle_account_creation)
Handlers-->>Indexer: handling result
end
Apibara-->>Runner: continue streaming
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~25 minutes
Poem
Pre-merge checks and finishing touches❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
📜 Recent review detailsConfiguration used: CodeRabbit UI Review profile: CHILL Plan: Pro 📒 Files selected for processing (1)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 5
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (5)
backend/spherre/indexer/config.py(1 hunks)backend/spherre/indexer/main.py(1 hunks)backend/spherre/indexer/service/event_handlers.py(1 hunks)backend/spherre/indexer/service/indexers.py(1 hunks)backend/spherre/indexer/service/types.py(1 hunks)
🧰 Additional context used
🧬 Code graph analysis (3)
backend/spherre/indexer/main.py (1)
backend/spherre/indexer/service/indexers.py (1)
run_main_indexer(135-147)
backend/spherre/indexer/service/event_handlers.py (1)
backend/spherre/indexer/service/types.py (1)
AccountCreationEvent(70-78)
backend/spherre/indexer/service/indexers.py (2)
backend/spherre/indexer/service/event_handlers.py (2)
EventHandlers(4-11)handle_account_creation(6-7)backend/spherre/indexer/service/types.py (2)
AccountCreationEvent(70-78)EventEnum(9-14)
| SPHERRE_CONTRACT_ADDRESS = "" | ||
| SERVER_URL = "" | ||
| MONGO_URL = "" |
There was a problem hiding this comment.
Fail fast when required config is missing.
Leaving SPHERRE_CONTRACT_ADDRESS, SERVER_URL, and MONGO_URL as empty strings makes felt.from_hex("") crash at runtime and the runner attempt to dial an empty URL. Please plumb these values from env or config and raise a clear error if they aren’t provided before starting the indexer.
| class EventHandlers: | ||
| @classmethod | ||
| def handle_account_creation(cls, data: AccountCreationEvent): | ||
| pass | ||
|
|
||
| @classmethod | ||
| def handle_token_transafer(cls): | ||
| pass |
There was a problem hiding this comment.
Implement the handlers (and fix the typo).
Both handlers are pass, so every processed event is dropped. On top of that, handle_token_transafer is misspelled, so any future call using the correct name will fail. Please implement the expected persistence/side effects now (or at least raise NotImplementedError) and correct the method name to avoid silent breakage.
🤖 Prompt for AI Agents
In backend/spherre/indexer/service/event_handlers.py around lines 4-11, the two
handlers are unimplemented and the token handler name is misspelled; change
handle_token_transafer to handle_token_transfer, give it the correct signature
(accepting the token event data), and either implement the expected
persistence/side-effects (write event data to the index/store and emit any
required downstream events) or explicitly raise NotImplementedError in both
handle_account_creation(data: AccountCreationEvent) and
handle_token_transfer(data: TokenTransferEvent) so events are not silently
dropped; also update any callers/tests to use the corrected method name.
| account_address = felt.to_hex(event.data[0]) | ||
| owner = felt.to_hex(event.data[1]) | ||
| name = felt.to_hex(event.data[2]) | ||
| description = felt.to_hex(event.data[3]) | ||
| members_array_length = felt.to_int(event.data[4]) | ||
| members = [] | ||
| for i in range(5, members_array_length + 1 + 4): | ||
| members.append(felt.to_hex(event.data[i])) | ||
| threshold = felt.to_int(event.data[i + 1]) | ||
| deployer = felt.to_hex(event.data[i + 2]) | ||
| date_deployed = felt.to_int(event.data[i + 3]) | ||
|
|
||
| print("Account Deployed") | ||
| print("Transaction Hash:", tx_hash) | ||
| print("Account Address:", account_address) | ||
| print("Owner:", owner) | ||
| print("Name:", name) | ||
| print("Description:", description) | ||
| print("Members:", members) | ||
| print("Threshold:", threshold) | ||
| print("Deployer:", deployer) | ||
| print("Date Deployed:", date_deployed) | ||
|
|
||
| try: | ||
| account_data = AccountCreationEvent( | ||
| account_address=account_address, | ||
| owner=owner, | ||
| name=name, | ||
| description=description, | ||
| members=members, | ||
| threshold=threshold, | ||
| deployer=deployer, | ||
| date_deployed=date_deployed, | ||
| ) |
There was a problem hiding this comment.
Fix event parsing for empty member lists and type mismatches.
If a DAO boots with zero members, the members loop never runs and i is undefined when you read event.data[i + 1:], causing an UnboundLocalError. Even when members exist, you convert deployer to hex but the model expects an int, so Pydantic raises ValidationError and the event is dropped. Please restructure the offsets explicitly (e.g., track a cursor) and feed the correct types into AccountCreationEvent so validation succeeds.
🤖 Prompt for AI Agents
In backend/spherre/indexer/service/indexers.py around lines 45 to 78, the event
parsing uses a loop index `i` that can be undefined when members_array_length is
zero and also converts `deployer` to hex while the Pydantic model expects ints;
fix by using an explicit cursor variable initialized to the first member index,
advance the cursor exactly members_array_length times appending felt.to_hex
values (so an empty list is handled without relying on `i`), then read
threshold, deployer, and date_deployed using felt.to_int from the cursor
positions (not felt.to_hex for deployer) and assign the correct int/str types
into AccountCreationEvent so validation passes.
| EventHandlers.handle_account_creation(account_data) | ||
| # start a new account indexer in another thread | ||
| except ValidationError as err: |
There was a problem hiding this comment.
Starting account indexers is still unimplemented.
We log that we “start a new account indexer” but call nothing—real-time account monitoring never kicks off. Either wire this up to run_indexer(AccountIndexer, ...) in a background task or remove the comment and add a TODO that clearly blocks release.
🤖 Prompt for AI Agents
In backend/spherre/indexer/service/indexers.py around lines 80 to 82, the code
logs "start a new account indexer" but never actually starts it; wire this up by
invoking run_indexer with the AccountIndexer class in a background task (or
equivalent thread/task runner used in this project) passing the appropriate
account identifier and any required context, ensuring exceptions are caught and
logged; if you cannot implement it now, remove the misleading comment and add a
clear TODO comment that this missing behavior blocks release and references an
issue/PR number.
| EVENT_SELECTORS = bidict( | ||
| { | ||
| EventEnum.ACCOUNT_CREATION: felt.from_hex( | ||
| "0x347f3a34b919109f055acc8440a003ecda76b4c63c101bbc99b9d00296db557" | ||
| ), | ||
| EventEnum.TOKEN_TRANSFER: felt.from_hex( | ||
| "0x99cd8bde557814842a3121e8ddfd433a539b8c9f14bf31ebf108d12e6196e9" | ||
| ), | ||
| EventEnum.TRANSACTION_PROPOSAL: felt.from_hex(""), | ||
| EventEnum.TRANSACTION_APPROVAL: felt.from_hex( | ||
| "0x8fac5268bfb16142e4e1fce5f985e337db83f8b307525a0960480cd8473436" | ||
| ), | ||
| EventEnum.TRANSACTION_EXECUTION: felt.from_hex( | ||
| "0x1dcde06aabdbca2f80aa51392b345d7549d7757aa855f7e37f5d335ac8243b1" | ||
| ), | ||
| } | ||
| ) |
There was a problem hiding this comment.
Selector initialization currently raises immediately.
felt.from_hex("") throws, so importing this module blows up before the indexer can start. Please either provide the real selector or guard optional selectors instead of hard‑coding an empty string.
🤖 Prompt for AI Agents
In backend/spherre/indexer/service/types.py around lines 17 to 33, the
EventEnum.TRANSACTION_PROPOSAL entry calls felt.from_hex("") which raises at
import time; replace the empty string with the correct selector hex if
available, or remove/omit the TRANSACTION_PROPOSAL key from EVENT_SELECTORS and
handle missing selectors elsewhere, or wrap the conversion in a guard that only
calls felt.from_hex when the string is non-empty (or uses None/Optional for
absent selectors) so importing this module no longer throws.
There was a problem hiding this comment.
Actionable comments posted: 6
♻️ Duplicate comments (2)
backend/spherre/indexer/service/event_handlers.py (1)
12-17: Critical: Implement handlers and fix the typo and signature.The issues flagged in the previous review persist:
- Typo:
handle_token_transafershould behandle_token_transfer- Missing parameter:
handle_token_transaferlacks a data parameter (compare line 12 vs line 16)- Unimplemented: Both handlers use
pass, so all processed events are silently droppedThis blocks the core indexing functionality described in the PR objectives.
Apply this diff to fix the typo, signature, and add explicit not-implemented markers:
@classmethod def handle_account_creation(cls, data: AccountCreationEvent): - pass + raise NotImplementedError("Account creation persistence not yet implemented") @classmethod - def handle_token_transafer(cls): - pass + def handle_token_transfer(cls, data: BaseEventModel): + raise NotImplementedError("Token transfer persistence not yet implemented")Then update the mapping:
DATA_HANDLERS: Dict[EventEnum, Callable[[BaseEventModel], None]] = { EventEnum.ACCOUNT_CREATION: EventHandlers.handle_account_creation, - EventEnum.TOKEN_TRANSFER: EventHandlers.handle_token_transafer, + EventEnum.TOKEN_TRANSFER: EventHandlers.handle_token_transfer, }backend/spherre/indexer/service/types.py (1)
25-25: Critical: Empty selector string causes import failure.The issue from the previous review persists:
felt.from_hex("")raisesValueErrorat import time, preventing the module from loading.Apply one of these fixes:
Option 1 (if selector is unknown): Remove the entry and handle missing selectors dynamically:
EventEnum.TOKEN_TRANSFER: felt.from_hex( "0x99cd8bde557814842a3121e8ddfd433a539b8c9f14bf31ebf108d12e6196e9" ), - EventEnum.TRANSACTION_PROPOSAL: felt.from_hex(""), EventEnum.TRANSACTION_APPROVAL: felt.from_hex( "0x8fac5268bfb16142e4e1fce5f985e337db83f8b307525a0960480cd8473436" ),Option 2 (if selector is known): Replace with the correct hex value:
- EventEnum.TRANSACTION_PROPOSAL: felt.from_hex(""), + EventEnum.TRANSACTION_PROPOSAL: felt.from_hex("0x<actual_selector_here>"),
🧹 Nitpick comments (1)
backend/spherre/indexer/service/utils.py (1)
29-37: Replace print statements with structured logging.Use the imported
loggerfor production-grade observability instead of print statements.Apply this diff:
- print("Account Deployed") - print("Account Address:", account_address) - print("Owner:", owner) - print("Name:", name) - print("Description:", description) - print("Members:", members) - print("Threshold:", threshold) - print("Deployer:", deployer) - print("Date Deployed:", date_deployed) + logger.debug( + f"Account Deployed - Address: {account_address}, Owner: {owner}, " + f"Name: {name}, Description: {description}, Members: {members}, " + f"Threshold: {threshold}, Deployer: {deployer}, Date: {date_deployed}" + )
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (4)
backend/spherre/indexer/service/event_handlers.py(1 hunks)backend/spherre/indexer/service/indexers.py(1 hunks)backend/spherre/indexer/service/types.py(1 hunks)backend/spherre/indexer/service/utils.py(1 hunks)
🧰 Additional context used
🧬 Code graph analysis (3)
backend/spherre/indexer/service/event_handlers.py (1)
backend/spherre/indexer/service/types.py (3)
AccountCreationEvent(70-78)BaseEventModel(36-67)EventEnum(9-14)
backend/spherre/indexer/service/utils.py (1)
backend/spherre/indexer/service/types.py (3)
AccountCreationEvent(70-78)BaseEventModel(36-67)EventEnum(9-14)
backend/spherre/indexer/service/indexers.py (1)
backend/spherre/indexer/service/types.py (2)
AccountCreationEvent(70-78)EventEnum(9-14)
🪛 GitHub Actions: Backend Lint and Code Formatting Check
backend/spherre/indexer/service/indexers.py
[error] 8-8: F401: 'pydantic.ValidationError' imported but unused. Remove unused import.
[error] 14-14: F401: 'AccountCreationEvent' imported but unused. Remove unused import.
[error] 63-63: E501: Line too long (96 > 88).
[error] 67-67: E501: Line too long (103 > 88).
[error] 79-79: E501: Line too long (95 > 88).
[error] 84-84: E501: Line too long (101 > 88).
🔇 Additional comments (7)
backend/spherre/indexer/service/event_handlers.py (1)
20-23: LGTM with dependency on handler fixes.The mapping structure and type annotations are correct. However, this depends on fixing the handler implementations and typo flagged above.
backend/spherre/indexer/service/utils.py (1)
56-58: LGTM!The mapping structure is correct. Note that
TOKEN_TRANSFERtransformer is not yet implemented, which aligns with the current scope focusing on account creation events.backend/spherre/indexer/service/types.py (2)
70-78: LGTM!The
AccountCreationEventmodel is well-defined with appropriate field types matching the smart contract event structure.
81-85: LGTM!The
TokenTransferEventmodel is well-defined and ready for when the handler and transformer are implemented.backend/spherre/indexer/service/indexers.py (3)
32-46: LGTM!The indexer ID and initial configuration are correctly implemented. The hardcoded starting cursor at block 10,000 is appropriate for bootstrapping.
87-88: LGTM!Rejecting invalidations is appropriate given the
DATA_STATUS_ACCEPTEDfinality requirement ininitial_configuration.
95-127: LGTM!The runner functions are well-structured.
run_indexerprovides a generic runner that can be used for starting account-specific indexers, whilerun_main_indexeris a convenient wrapper for the main indexer.
| def start_account_indexer(self, address: str): | ||
| # create a new filter for the account address | ||
| account_address = felt.from_hex(address) | ||
| filter = ( | ||
| EventFilter() | ||
| .with_from_address(account_address) | ||
| .with_keys([EVENT_SELECTORS.values()]) | ||
| ) | ||
| # add the filter to the indexer | ||
| self.update_filter(filter) |
There was a problem hiding this comment.
Convert dict values view to list.
Line 27: EVENT_SELECTORS.values() returns a dict_values view object, which may not be accepted by with_keys(). Convert to a list explicitly.
Apply this diff:
filter = (
EventFilter()
.with_from_address(account_address)
- .with_keys([EVENT_SELECTORS.values()])
+ .with_keys(list(EVENT_SELECTORS.values()))
)📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| def start_account_indexer(self, address: str): | |
| # create a new filter for the account address | |
| account_address = felt.from_hex(address) | |
| filter = ( | |
| EventFilter() | |
| .with_from_address(account_address) | |
| .with_keys([EVENT_SELECTORS.values()]) | |
| ) | |
| # add the filter to the indexer | |
| self.update_filter(filter) | |
| def start_account_indexer(self, address: str): | |
| # create a new filter for the account address | |
| account_address = felt.from_hex(address) | |
| filter = ( | |
| EventFilter() | |
| .with_from_address(account_address) | |
| .with_keys(list(EVENT_SELECTORS.values())) | |
| ) | |
| # add the filter to the indexer | |
| self.update_filter(filter) |
🤖 Prompt for AI Agents
In backend/spherre/indexer/service/indexers.py around lines 21 to 30, the call
to with_keys currently passes EVENT_SELECTORS.values() which yields a
dict_values view that may be rejected; change it to pass a concrete list by
wrapping it with list(EVENT_SELECTORS.values()), so the filter is constructed
with a list of keys and then call update_filter as before.
| async def handle_data(self, info: Info, data: Block): | ||
| # Handle one block of data | ||
| for event_with_tx in data.events: | ||
| tx_hash = felt.to_hex(event_with_tx.transaction.meta.hash) | ||
| event = event_with_tx.event | ||
| event_address = felt.to_hex(event.from_address) | ||
| logger.info("Transaction Hash:", tx_hash) | ||
|
|
||
| if event_address != SPHERRE_CONTRACT_ADDRESS: | ||
| event_type = event.keys | ||
| event_enum = EVENT_SELECTORS.inverse[event_type] | ||
| transformed_data = DATA_TRANSFORMERS[event_enum](event) | ||
| if transformed_data: | ||
| DATA_HANDLERS[event_enum](transformed_data) | ||
| logger.info( | ||
| f"Event with type '{event_type}' from address '{event_address}' handled" | ||
| ) | ||
| else: | ||
| logger.error( | ||
| f"Failed to handle event of type '{event_type}' from address '{event_address}'" | ||
| ) | ||
| else: | ||
| event_type = event.keys | ||
| if event_type == EVENT_SELECTORS[EventEnum.ACCOUNT_CREATION]: | ||
| transformed_data = DATA_TRANSFORMERS[EventEnum.ACCOUNT_CREATION]( | ||
| event | ||
| ) | ||
| if transformed_data: | ||
| DATA_HANDLERS[EventEnum.ACCOUNT_CREATION](transformed_data) | ||
| self.start_account_indexer(transformed_data.account_address) | ||
| logger.info( | ||
| f"Account created for address '{transformed_data.account_address}'" | ||
| ) | ||
| else: | ||
| account_address = felt.to_hex(event.data[0]) | ||
| logger.error( | ||
| f"Failed to handle account creation event of address '{account_address}'" | ||
| ) |
There was a problem hiding this comment.
Fix event key extraction, logger syntax, and line lengths.
Multiple issues in the event handling logic:
- Line 54:
logger.info()doesn't accept multiple positional arguments likeprint(). Use f-string formatting - Lines 58, 70:
event.keysis a list; extract the first element for comparison with selectors - Lines 63, 67, 79, 84: Lines exceed 88 characters (pipeline failures)
Apply this diff:
for event_with_tx in data.events:
tx_hash = felt.to_hex(event_with_tx.transaction.meta.hash)
event = event_with_tx.event
event_address = felt.to_hex(event.from_address)
- logger.info("Transaction Hash:", tx_hash)
+ logger.info(f"Transaction Hash: {tx_hash}")
if event_address != SPHERRE_CONTRACT_ADDRESS:
- event_type = event.keys
+ event_key = event.keys[0] if event.keys else None
+ if not event_key:
+ logger.warning(f"Event with no keys from {event_address}")
+ continue
- event_enum = EVENT_SELECTORS.inverse[event_type]
+ event_enum = EVENT_SELECTORS.inverse.get(event_key)
+ if not event_enum:
+ logger.warning(f"Unknown event key {event_key}")
+ continue
transformed_data = DATA_TRANSFORMERS[event_enum](event)
if transformed_data:
DATA_HANDLERS[event_enum](transformed_data)
logger.info(
- f"Event with type '{event_type}' from address '{event_address}' handled"
+ f"Event '{event_enum.name}' from "
+ f"'{event_address}' handled"
)
else:
logger.error(
- f"Failed to handle event of type '{event_type}' from address '{event_address}'"
+ f"Failed to handle event '{event_enum.name}' "
+ f"from '{event_address}'"
)
else:
- event_type = event.keys
- if event_type == EVENT_SELECTORS[EventEnum.ACCOUNT_CREATION]:
+ event_key = event.keys[0] if event.keys else None
+ if event_key == EVENT_SELECTORS[EventEnum.ACCOUNT_CREATION]:
transformed_data = DATA_TRANSFORMERS[EventEnum.ACCOUNT_CREATION](
event
)
if transformed_data:
DATA_HANDLERS[EventEnum.ACCOUNT_CREATION](transformed_data)
self.start_account_indexer(transformed_data.account_address)
logger.info(
- f"Account created for address '{transformed_data.account_address}'"
+ f"Account created for "
+ f"'{transformed_data.account_address}'"
)
else:
account_address = felt.to_hex(event.data[0])
logger.error(
- f"Failed to handle account creation event of address '{account_address}'"
+ f"Failed to handle account creation "
+ f"for '{account_address}'"
)🧰 Tools
🪛 GitHub Actions: Backend Lint and Code Formatting Check
[error] 63-63: E501: Line too long (96 > 88).
[error] 67-67: E501: Line too long (103 > 88).
[error] 79-79: E501: Line too long (95 > 88).
[error] 84-84: E501: Line too long (101 > 88).
🤖 Prompt for AI Agents
In backend/spherre/indexer/service/indexers.py around lines 48 to 85, fix three
issues: replace logger.info("Transaction Hash:", tx_hash) with a single
formatted message (e.g. logger.info(f"Transaction Hash: {tx_hash}")), extract
the event key from event.keys by using event_type = event.keys[0] before
comparing to selectors or using it as a dict key, and reflow any long
log/handler lines to be under 88 characters (assign long strings or values to
short local variables and use them in f-strings) so each statement stays within
the line-length limit.
| def run_in_thread(self): | ||
| pass |
There was a problem hiding this comment.
🛠️ Refactor suggestion | 🟠 Major
Remove unused function.
This function is not called anywhere and has no implementation. Either implement it if it's needed for the threading strategy mentioned in previous review comments, or remove it.
-def run_in_thread(self):
- pass
-
-📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| def run_in_thread(self): | |
| pass |
🤖 Prompt for AI Agents
In backend/spherre/indexer/service/indexers.py around lines 91 to 92, remove the
unused empty method run_in_thread (or implement it if your threading strategy
requires it). If no callers exist and threading behavior is not needed, delete
the def run_in_thread(self): pass definition to avoid dead code; if threading is
required, implement the method to start the indexer in a background thread
(e.g., accept necessary args, create and start a Thread/Executor, and ensure
proper lifecycle/error handling) and update any callers accordingly.
| @field_validator("*", mode="before") # Apply to all fields | ||
| @classmethod | ||
| def restructure_data_before_parsing(cls, v: Any, info: ValidationInfo): | ||
| field_info = cls.model_fields[info.field_name] | ||
| field_type = field_info.annotation | ||
|
|
||
| print(f"\n{info.field_name}:") | ||
| print(f" Annotation: {field_type}") | ||
|
|
||
| new_value = v | ||
|
|
||
| if isinstance(field_type, str): | ||
| new_value = felt.to_hex(v) | ||
| return new_value | ||
| elif isinstance(field_type, int): | ||
| new_value = felt.to_int(v) | ||
| elif get_origin(field_type): | ||
| args = get_args(field_type) | ||
| if isinstance(args, str): | ||
| new_value = [felt.to_hex(val) for val in v] | ||
| elif isinstance(args, int): | ||
| new_value = [felt.to_int(val) for val in v] | ||
|
|
||
| return new_value |
There was a problem hiding this comment.
Major: Fix type checking logic and remove debug prints.
The validator has two issues:
- Lines 50-51: Debug print statements should be removed or use logger
- Lines 55, 62:
isinstance(field_type, str)checks iffield_typeis an instance ofstr, butfield_typeis a type annotation (the classstritself), not a string. This always returnsFalse
Apply this diff to fix the type checks:
@field_validator("*", mode="before")
@classmethod
def restructure_data_before_parsing(cls, v: Any, info: ValidationInfo):
field_info = cls.model_fields[info.field_name]
field_type = field_info.annotation
- print(f"\n{info.field_name}:")
- print(f" Annotation: {field_type}")
new_value = v
- if isinstance(field_type, str):
+ if field_type is str:
new_value = felt.to_hex(v)
return new_value
- elif isinstance(field_type, int):
+ elif field_type is int:
new_value = felt.to_int(v)
elif get_origin(field_type):
args = get_args(field_type)
- if isinstance(args, str):
+ if args and args[0] is str:
new_value = [felt.to_hex(val) for val in v]
- elif isinstance(args, int):
+ elif args and args[0] is int:
new_value = [felt.to_int(val) for val in v]
return new_value🤖 Prompt for AI Agents
In backend/spherre/indexer/service/types.py around lines 44 to 67, remove the
two debug print statements and fix the type-checking logic: use "if field_type
is str" and "elif field_type is int" (or "==") to check annotations rather than
isinstance, and when handling generic types use get_origin(field_type) and
inspect get_args(field_type) for element types (compare args[0] to str or int)
before mapping felt.to_hex / felt.to_int over v; ensure you return new_value in
each branch and handle None/empty inputs safely.
| def transform_account_creation_event(cls, event: Event) -> AccountCreationEvent: | ||
| account_address = felt.to_hex(event.data[0]) | ||
| owner = felt.to_hex(event.data[1]) | ||
| name = felt.to_hex(event.data[2]) | ||
| description = felt.to_hex(event.data[3]) | ||
| members_array_length = felt.to_int(event.data[4]) | ||
| members = [] | ||
| for i in range(5, members_array_length + 1 + 4): | ||
| members.append(felt.to_hex(event.data[i])) | ||
| threshold = felt.to_int(event.data[i + 1]) | ||
| deployer = felt.to_int(event.data[i + 2]) | ||
| date_deployed = felt.to_int(event.data[i + 3]) |
There was a problem hiding this comment.
Critical: Fix array parsing logic and return type.
The array parsing has critical errors:
- Line 24: The range
range(5, members_array_length + 1 + 4)is incorrect. To readmembers_array_lengthitems starting at index 5, userange(5, 5 + members_array_length) - Lines 26-28: If
members_array_lengthis 0, the loop never executes andiis undefined, causingUnboundLocalErrorwhen accessingevent.data[i + 1] - Line 17: Return type is
AccountCreationEventbut line 52 returnsNone, should beOptional[AccountCreationEvent]
Apply this diff to fix the logic:
@classmethod
- def transform_account_creation_event(cls, event: Event) -> AccountCreationEvent:
+ def transform_account_creation_event(cls, event: Event) -> Optional[AccountCreationEvent]:
account_address = felt.to_hex(event.data[0])
owner = felt.to_hex(event.data[1])
name = felt.to_hex(event.data[2])
description = felt.to_hex(event.data[3])
members_array_length = felt.to_int(event.data[4])
members = []
- for i in range(5, members_array_length + 1 + 4):
+ cursor = 5
+ for _ in range(members_array_length):
- members.append(felt.to_hex(event.data[i]))
+ members.append(felt.to_hex(event.data[cursor]))
+ cursor += 1
- threshold = felt.to_int(event.data[i + 1])
- deployer = felt.to_int(event.data[i + 2])
- date_deployed = felt.to_int(event.data[i + 3])
+ threshold = felt.to_int(event.data[cursor])
+ deployer = felt.to_int(event.data[cursor + 1])
+ date_deployed = felt.to_int(event.data[cursor + 2])Add the import:
-from typing import Callable, Dict
+from typing import Callable, Dict, Optional📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| def transform_account_creation_event(cls, event: Event) -> AccountCreationEvent: | |
| account_address = felt.to_hex(event.data[0]) | |
| owner = felt.to_hex(event.data[1]) | |
| name = felt.to_hex(event.data[2]) | |
| description = felt.to_hex(event.data[3]) | |
| members_array_length = felt.to_int(event.data[4]) | |
| members = [] | |
| for i in range(5, members_array_length + 1 + 4): | |
| members.append(felt.to_hex(event.data[i])) | |
| threshold = felt.to_int(event.data[i + 1]) | |
| deployer = felt.to_int(event.data[i + 2]) | |
| date_deployed = felt.to_int(event.data[i + 3]) | |
| def transform_account_creation_event(cls, event: Event) -> Optional[AccountCreationEvent]: | |
| account_address = felt.to_hex(event.data[0]) | |
| owner = felt.to_hex(event.data[1]) | |
| name = felt.to_hex(event.data[2]) | |
| description = felt.to_hex(event.data[3]) | |
| members_array_length = felt.to_int(event.data[4]) | |
| members = [] | |
| cursor = 5 | |
| for _ in range(members_array_length): | |
| members.append(felt.to_hex(event.data[cursor])) | |
| cursor += 1 | |
| threshold = felt.to_int(event.data[cursor]) | |
| deployer = felt.to_int(event.data[cursor + 1]) | |
| date_deployed = felt.to_int(event.data[cursor + 2]) |
🤖 Prompt for AI Agents
In backend/spherre/indexer/service/utils.py around lines 17 to 28, fix the
member-array parsing and return type: import Optional from typing; change the
function return annotation to Optional[AccountCreationEvent]; compute start=5
and end=start+members_array_length, iterate for i in range(start, end) to build
members, then set next_index = end and read threshold =
felt.to_int(event.data[next_index]), deployer =
felt.to_int(event.data[next_index + 1]), date_deployed =
felt.to_int(event.data[next_index + 2]) so no reliance on an undefined i when
members_array_length == 0.
Description
Related Issue
Fixes #161
Type of Change
How Has This Been Tested?
Checklist:
Summary by CodeRabbit