3232 "btc-utxo-seal-profile-v0" : "btc-utxo-seal-closure" ,
3333 "dual-seal-profile-v0" : "dual-seal-finality" ,
3434}
35+ REQUIRED_PUBLIC_FIELDS = [
36+ "network" ,
37+ "generated_at" ,
38+ "evidence_provider" ,
39+ "required_profiles" ,
40+ "profile" ,
41+ "scenario" ,
42+ "ckb_live_tx_hash" ,
43+ "live_report_hash" ,
44+ "service_builder_case_hash" ,
45+ "service_builder_tx_skeleton_hash" ,
46+ "service_builder_receipt_binding_hash" ,
47+ "btc_txid" ,
48+ "btc_block_hash" ,
49+ "spv_proof_hash" ,
50+ "minimum_confirmations" ,
51+ "confirmations" ,
52+ "spv_client_cell_dep.out_point" ,
53+ "spv_client_cell_dep.data_hash" ,
54+ "spv_client_cell_dep.dep_type" ,
55+ "spv_client_cell_dep.hash_type" ,
56+ "source_service.name" ,
57+ "source_service.commit" ,
58+ "source_service.report_hash" ,
59+ "request_handoff.bundle" ,
60+ "request_handoff.bundle_hash" ,
61+ "request_handoff.bundle_hash_algorithm" ,
62+ "request_handoff.group" ,
63+ ]
64+ FIELD_CONSTRAINTS = {
65+ "network" : "explicit public mainnet/testnet name; placeholders and local/devnet/regtest/simnet/private/fake labels are rejected" ,
66+ "generated_at" : "UTC timestamp in YYYY-MM-DDTHH:MM:SSZ form; future timestamps are rejected" ,
67+ "evidence_provider" : "real external provider identity; placeholder, example, and unknown tokens are rejected" ,
68+ "ckb_live_tx_hash" : "0x-prefixed 32-byte CKB live transaction hash matching the current NovaSeal service-builder case" ,
69+ "live_report_hash" : "0x-prefixed 32-byte hash of the current NovaSeal live devnet report for this profile" ,
70+ "service_builder_case_hash" : "0x-prefixed 32-byte hash of the current NovaSeal service-builder case for this profile" ,
71+ "service_builder_tx_skeleton_hash" : "0x-prefixed 32-byte service-builder transaction skeleton hash for this profile" ,
72+ "service_builder_receipt_binding_hash" : "0x-prefixed 32-byte service-builder receipt binding hash for this profile" ,
73+ "btc_txid" : "0x-prefixed 32-byte non-placeholder Bitcoin transaction id" ,
74+ "btc_block_hash" : "0x-prefixed 32-byte non-placeholder Bitcoin block hash anchoring the SPV proof" ,
75+ "spv_proof_hash" : "0x-prefixed 32-byte non-placeholder hash of the SPV proof material" ,
76+ "minimum_confirmations" : "integer confirmation floor; at least 6" ,
77+ "confirmations" : "integer observed confirmations meeting minimum_confirmations" ,
78+ "spv_client_cell_dep.out_point" : "0x-prefixed 32-byte CKB transaction hash plus numeric output index" ,
79+ "spv_client_cell_dep.data_hash" : "0x-prefixed 32-byte non-placeholder SPV client data hash" ,
80+ "spv_client_cell_dep.dep_type" : "code" ,
81+ "spv_client_cell_dep.hash_type" : "data, data1, or type CKB script hash type" ,
82+ "source_service.name" : "real external SPV service identity; placeholder, example, and unknown tokens are rejected" ,
83+ "source_service.commit" : "40-character hex service source commit" ,
84+ "source_service.report_hash" : "0x-prefixed 32-byte non-placeholder SPV service report hash" ,
85+ "request_handoff.bundle" : "target/novaseal-external-evidence-handoff-bundle.json" ,
86+ "request_handoff.bundle_hash" : "0x-prefixed 32-byte hash of the NovaSeal external evidence handoff bundle" ,
87+ "request_handoff.bundle_hash_algorithm" : "blake2b-256(person=NovaExtHandoff)" ,
88+ "request_handoff.group" : "public_btc_spv_evidence" ,
89+ }
3590
3691
3792def hex0x (data : bytes ) -> str :
@@ -58,56 +113,16 @@ def profile_cases(service_builder: dict[str, Any], template: dict[str, Any]) ->
58113 builder_case = next ((case for case in builder_cases if case .get ("profile" ) == profile ), None )
59114 template_case = next ((case for case in template_cases if case .get ("profile" ) == profile ), None )
60115 external_inputs = builder_case .get ("request" , {}).get ("production_external_inputs" , []) if builder_case else []
116+ required_live_inputs = builder_case .get ("request" , {}).get ("required_live_inputs" , {}) if builder_case else {}
61117 request = {
62118 "profile" : profile ,
63119 "scenario" : template_case .get ("scenario" ) if template_case else None ,
64120 "minimum_confirmations" : template_case .get ("minimum_confirmations" ) if template_case else 6 ,
65- "required_public_fields" : [
66- "network" ,
67- "generated_at" ,
68- "evidence_provider" ,
69- "required_profiles" ,
70- "profile" ,
71- "scenario" ,
72- "btc_txid" ,
73- "btc_block_hash" ,
74- "spv_proof_hash" ,
75- "minimum_confirmations" ,
76- "confirmations" ,
77- "spv_client_cell_dep.out_point" ,
78- "spv_client_cell_dep.data_hash" ,
79- "spv_client_cell_dep.dep_type" ,
80- "spv_client_cell_dep.hash_type" ,
81- "source_service.name" ,
82- "source_service.commit" ,
83- "source_service.report_hash" ,
84- "request_handoff.bundle" ,
85- "request_handoff.bundle_hash" ,
86- "request_handoff.bundle_hash_algorithm" ,
87- "request_handoff.group" ,
88- ],
89- "field_constraints" : {
90- "network" : "explicit public mainnet/testnet name; placeholders and local/devnet/regtest/simnet/private/fake labels are rejected" ,
91- "generated_at" : "UTC timestamp in YYYY-MM-DDTHH:MM:SSZ form; future timestamps are rejected" ,
92- "evidence_provider" : "real external provider identity; placeholder, example, and unknown tokens are rejected" ,
93- "btc_txid" : "0x-prefixed 32-byte non-placeholder Bitcoin transaction id" ,
94- "btc_block_hash" : "0x-prefixed 32-byte non-placeholder Bitcoin block hash anchoring the SPV proof" ,
95- "spv_proof_hash" : "0x-prefixed 32-byte non-placeholder hash of the SPV proof material" ,
96- "minimum_confirmations" : "integer confirmation floor; at least 6" ,
97- "confirmations" : "integer observed confirmations meeting minimum_confirmations" ,
98- "spv_client_cell_dep.out_point" : "0x-prefixed 32-byte CKB transaction hash plus numeric output index" ,
99- "spv_client_cell_dep.data_hash" : "0x-prefixed 32-byte non-placeholder SPV client data hash" ,
100- "spv_client_cell_dep.dep_type" : "code" ,
101- "spv_client_cell_dep.hash_type" : "data, data1, or type CKB script hash type" ,
102- "source_service.name" : "real external SPV service identity; placeholder, example, and unknown tokens are rejected" ,
103- "source_service.commit" : "40-character hex service source commit" ,
104- "source_service.report_hash" : "0x-prefixed 32-byte non-placeholder SPV service report hash" ,
105- "request_handoff.bundle" : "target/novaseal-external-evidence-handoff-bundle.json" ,
106- "request_handoff.bundle_hash" : "0x-prefixed 32-byte hash of the NovaSeal external evidence handoff bundle" ,
107- "request_handoff.bundle_hash_algorithm" : "blake2b-256(person=NovaExtHandoff)" ,
108- "request_handoff.group" : "public_btc_spv_evidence" ,
109- },
121+ "required_public_fields" : REQUIRED_PUBLIC_FIELDS ,
122+ "field_constraints" : FIELD_CONSTRAINTS ,
110123 "required_external_inputs" : external_inputs ,
124+ "ckb_live_tx_hash" : required_live_inputs .get ("live_devnet_tx_hash" ),
125+ "live_report_hash" : required_live_inputs .get ("live_report_hash" ),
111126 "service_builder_case_hash" : report_hash ("service_builder_case" , builder_case ),
112127 "service_builder_tx_skeleton_hash" : builder_case .get ("response" , {}).get ("tx_skeleton_hash" ) if builder_case else None ,
113128 "service_builder_receipt_binding_hash" : builder_case .get ("response" , {}).get ("receipt_binding_hash" ) if builder_case else None ,
@@ -119,9 +134,10 @@ def profile_cases(service_builder: dict[str, Any], template: dict[str, Any]) ->
119134 "scenario_matches_required_profile" : request ["scenario" ] == REQUIRED_SCENARIOS [profile ],
120135 "public_btc_spv_external_input_named" : "public_btc_spv_evidence" in external_inputs ,
121136 "minimum_confirmations_at_least_six" : request ["minimum_confirmations" ] >= 6 ,
137+ "live_binding_hashes_present" : bool (request ["ckb_live_tx_hash" ]) and bool (request ["live_report_hash" ]),
122138 "service_builder_hashes_present" : bool (request ["service_builder_tx_skeleton_hash" ])
123139 and bool (request ["service_builder_receipt_binding_hash" ]),
124- "required_public_fields_complete" : len (request ["required_public_fields" ]) == 22 ,
140+ "required_public_fields_complete" : len (request ["required_public_fields" ]) == len ( REQUIRED_PUBLIC_FIELDS ) ,
125141 }
126142 cases .append (
127143 {
0 commit comments