Snapshot of the UFAC challenge state, accumulated across UFAC responses.
The mobile transport already structurally decodes each bk.action.* dict
into the BloksResponse.dicts array. We just walk those parsed entries
looking for keys we care about — no regex over the bytecode source string.
Different keys surface at different points in the challenge:
challenge_root_id, hashed_ui_state appear in the very first
checkpoint.ufac.controller response (intro_ui_state initially).
image_upload_challenge_ui_state, v2_polling, trigger_session_id,
ixt_initial_screen_id, external_flow_id show up later, when the
server transitions the challenge into the authenticity-wizard phase
(contact_point.submit_code response).
Callers thread the state through the screen sequence: extract from each
response, pass the latest snapshot into the next screen handler so the
outgoing request (e.g. poll_ufac_api, image_upload.upload_identity_verification,
ig.ixt.triggers.screen.authenticity_wizard) can mirror the wire bytes
the real app sends.
Snapshot of the UFAC challenge state, accumulated across UFAC responses.
The mobile transport already structurally decodes each
bk.action.*dict into theBloksResponse.dictsarray. We just walk those parsed entries looking for keys we care about — no regex over the bytecode source string.Different keys surface at different points in the challenge:
challenge_root_id,hashed_ui_stateappear in the very firstcheckpoint.ufac.controllerresponse (intro_ui_stateinitially).image_upload_challenge_ui_state,v2_polling,trigger_session_id,ixt_initial_screen_id,external_flow_idshow up later, when the server transitions the challenge into the authenticity-wizard phase (contact_point.submit_coderesponse).Callers thread the state through the screen sequence: extract from each response, pass the latest snapshot into the next screen handler so the outgoing request (e.g.
poll_ufac_api,image_upload.upload_identity_verification,ig.ixt.triggers.screen.authenticity_wizard) can mirror the wire bytes the real app sends.