@@ -122,6 +122,38 @@ tx_hash = client.insert_records(stream_id, [
122122])
123123```
124124
125+ ### ` client.batch_insert_records(batches: List[RecordBatch], wait: bool = True) -> str `
126+ Insert multiple batches of records into different streams in a single transaction. This is the most efficient way to insert large amounts of data.
127+
128+ #### Parameters
129+ - ` batches: List[RecordBatch] ` - List of batch objects, each containing:
130+ - ` stream_id: str ` - Target stream identifier
131+ - ` inputs: List[Record] ` - List of records with ` date ` and ` value `
132+ - ` wait: bool ` - Whether to wait for transaction confirmation (default: True)
133+
134+ #### Returns
135+ - ` str ` - Transaction hash for all inserted records
136+
137+ #### Example
138+ ``` python
139+ batches = [
140+ {
141+ " stream_id" : " stream1" ,
142+ " inputs" : [
143+ {" date" : timestamp1, " value" : 100.0 },
144+ {" date" : timestamp2, " value" : 200.0 }
145+ ]
146+ },
147+ {
148+ " stream_id" : " stream2" ,
149+ " inputs" : [
150+ {" date" : timestamp1, " value" : 50.0 }
151+ ]
152+ }
153+ ]
154+ tx_hash = client.batch_insert_records(batches)
155+ ```
156+
125157## Stream Querying
126158
127159### ` client.get_records(stream_id: str, **kwargs) -> List[Dict] `
@@ -152,6 +184,45 @@ records = client.get_records(
152184> • ** Composed streams** – a synthetic value calculated on-the-fly by recursively aggregating the weighted values of * all* child primitives for every point in time. The same gap-filling logic is applied so you always get a continuous series.
153185> All permission checks (` read ` , ` compose ` ) are enforced server-side – if you don't have access the call fails with an explicit error.
154186
187+ ### ` client.get_first_record(stream_id: str, **kwargs) -> StreamRecord | None `
188+ Get the first record of a stream after a given date. Supports cache-aware responses.
189+
190+ #### Parameters
191+ - ` stream_id: str ` - Target stream
192+ - ` data_provider: Optional[str] ` - Specific data provider
193+ - ` after_date: Optional[int] ` - Find first record after this timestamp
194+ - ` frozen_at: Optional[int] ` - Timestamp for frozen state
195+ - ` use_cache: Optional[bool] ` - Enable cache-aware response format
196+
197+ #### Returns
198+ - ` StreamRecord | None ` or ` CacheAwareResponse[StreamRecord | None] ` - First record found, or cache-aware response if ` use_cache ` is specified
199+
200+ #### Example
201+ ``` python
202+ # Legacy format (deprecated)
203+ first_record = client.get_first_record(stream_id, after_date = timestamp)
204+
205+ # Cache-aware format
206+ response = client.get_first_record(stream_id, after_date = timestamp, use_cache = True )
207+ print (f " Record: { response.data} , Cache hit: { response.cache.hit} " )
208+ ```
209+
210+ ### ` client.get_type(stream_id: str, data_provider: Optional[str] = None) -> str `
211+ Get the type of a stream (primitive or composed).
212+
213+ #### Parameters
214+ - ` stream_id: str ` - Stream identifier
215+ - ` data_provider: Optional[str] ` - Specific data provider
216+
217+ #### Returns
218+ - ` str ` - Stream type ("primitive" or "composed")
219+
220+ #### Example
221+ ``` python
222+ stream_type = client.get_type(stream_id)
223+ print (f " Stream type: { stream_type} " )
224+ ```
225+
155226### ` client.get_index(stream_id: str, **kwargs) -> List[Dict] `
156227Returns a ** rebased index** of the stream where the value at ` base_date ` (defaults to the metadata key ` default_base_time ` ) is normalised to ** 100** .
157228
@@ -206,6 +277,105 @@ yoy = client.get_index_change(
206277)
207278```
208279
280+ ## Stream Management
281+
282+ ### ` client.list_streams(limit: Optional[int] = None, offset: Optional[int] = None, data_provider: Optional[str] = None, order_by: Optional[str] = None, block_height: Optional[int] = 0) -> List[Dict[str, Any]] `
283+ List all streams associated with the client account.
284+
285+ #### Parameters
286+ - ` limit: Optional[int] ` - Maximum number of results to return
287+ - ` offset: Optional[int] ` - Number of records to skip for pagination
288+ - ` data_provider: Optional[str] ` - Filter by specific data provider
289+ - ` order_by: Optional[str] ` - Sort order for results
290+ - ` block_height: Optional[int] ` - Query at specific block height (default: 0)
291+
292+ #### Returns
293+ - ` List[Dict[str, Any]] ` - List of stream information dictionaries
294+
295+ #### Example
296+ ``` python
297+ streams = client.list_streams(limit = 10 , offset = 0 )
298+ for stream in streams:
299+ print (f " Stream ID: { stream[' stream_id' ]} , Type: { stream[' stream_type' ]} " )
300+ ```
301+
302+ ### ` client.get_current_account() -> str `
303+ Get the current account address associated with this client.
304+
305+ #### Returns
306+ - ` str ` - The hex-encoded address of the current account
307+
308+ #### Example
309+ ``` python
310+ account_address = client.get_current_account()
311+ print (f " Current account: { account_address} " )
312+ ```
313+
314+ ### ` client.batch_deploy_streams(definitions: List[StreamDefinitionInput], wait: bool = True) -> str `
315+ Deploy multiple streams (primitive and composed) in a single transaction.
316+
317+ #### Parameters
318+ - ` definitions: List[StreamDefinitionInput] ` - List of stream definitions, each containing:
319+ - ` stream_id: str ` - Unique stream identifier
320+ - ` stream_type: str ` - Stream type ("primitive" or "composed")
321+ - ` wait: bool ` - Whether to wait for transaction confirmation (default: True)
322+
323+ #### Returns
324+ - ` str ` - Transaction hash of the batch deployment
325+
326+ #### Example
327+ ``` python
328+ definitions = [
329+ {" stream_id" : " stream1" , " stream_type" : " primitive" },
330+ {" stream_id" : " stream2" , " stream_type" : " composed" }
331+ ]
332+ tx_hash = client.batch_deploy_streams(definitions)
333+ ```
334+
335+ ### ` client.batch_stream_exists(locators: List[StreamLocatorInput]) -> List[StreamExistsResult] `
336+ Check for the existence of multiple streams.
337+
338+ #### Parameters
339+ - ` locators: List[StreamLocatorInput] ` - List of stream locators, each containing:
340+ - ` stream_id: str ` - Stream identifier
341+ - ` data_provider: str ` - Data provider address
342+
343+ #### Returns
344+ - ` List[StreamExistsResult] ` - List of existence results, each containing:
345+ - ` stream_id: str ` - Stream identifier
346+ - ` data_provider: str ` - Data provider address
347+ - ` exists: bool ` - Whether the stream exists
348+
349+ #### Example
350+ ``` python
351+ locators = [
352+ {" stream_id" : " stream1" , " data_provider" : " 0x123..." },
353+ {" stream_id" : " stream2" , " data_provider" : " 0x456..." }
354+ ]
355+ results = client.batch_stream_exists(locators)
356+ for result in results:
357+ print (f " Stream { result[' stream_id' ]} exists: { result[' exists' ]} " )
358+ ```
359+
360+ ### ` client.batch_filter_streams_by_existence(locators: List[StreamLocatorInput], return_existing: bool) -> List[StreamLocatorInput] `
361+ Filters a list of streams based on their existence.
362+
363+ #### Parameters
364+ - ` locators: List[StreamLocatorInput] ` - List of stream locators to filter
365+ - ` return_existing: bool ` - If True, returns existing streams; if False, returns non-existing streams
366+
367+ #### Returns
368+ - ` List[StreamLocatorInput] ` - Filtered list of stream locators
369+
370+ #### Example
371+ ``` python
372+ locators = [
373+ {" stream_id" : " stream1" , " data_provider" : " 0x123..." },
374+ {" stream_id" : " stream2" , " data_provider" : " 0x456..." }
375+ ]
376+ existing_streams = client.batch_filter_streams_by_existence(locators, return_existing = True )
377+ ```
378+
209379## Composition Management
210380
211381### ` client.set_taxonomy(stream_id: str, child_streams: Dict[str, float], start_date: Optional[int] = None) -> str `
@@ -231,6 +401,58 @@ tx_hash = client.set_taxonomy(
231401)
232402```
233403
404+ ### ` client.describe_taxonomy(stream_id: str, latest_version: bool = True) -> TaxonomyDetails | None `
405+ Get taxonomy structure of a composed stream.
406+
407+ #### Parameters
408+ - ` stream_id: str ` - Composed stream identifier
409+ - ` latest_version: bool ` - If True, returns only the latest version of the taxonomy (default: True)
410+
411+ #### Returns
412+ - ` TaxonomyDetails | None ` - Taxonomy details containing:
413+ - ` stream_id: str ` - The composed stream identifier
414+ - ` child_streams: List[TaxonomyDefinition] ` - List of child stream definitions with weights
415+ - ` created_at: int ` - Creation timestamp
416+
417+ #### Example
418+ ``` python
419+ taxonomy = client.describe_taxonomy(composed_stream_id)
420+ if taxonomy:
421+ print (f " Stream: { taxonomy[' stream_id' ]} " )
422+ for child in taxonomy[' child_streams' ]:
423+ print (f " Child: { child.stream[' stream_id' ]} , Weight: { child.weight} " )
424+ ```
425+
426+ ### ` client.allow_compose_stream(stream_id: str, wait: bool = True) -> str `
427+ Allows streams to use this stream as child, if composing is private.
428+
429+ #### Parameters
430+ - ` stream_id: str ` - Stream identifier
431+ - ` wait: bool ` - Whether to wait for transaction confirmation (default: True)
432+
433+ #### Returns
434+ - ` str ` - Transaction hash
435+
436+ #### Example
437+ ``` python
438+ tx_hash = client.allow_compose_stream(stream_id)
439+ ```
440+
441+ ### ` client.disable_compose_stream(stream_id: str, wait: bool = True) -> str `
442+ Disable streams from using this stream as child.
443+
444+ #### Parameters
445+ - ` stream_id: str ` - Stream identifier
446+ - ` wait: bool ` - Whether to wait for transaction confirmation (default: True)
447+
448+ #### Returns
449+ - ` str ` - Transaction hash
450+
451+ #### Example
452+ ``` python
453+ tx_hash = client.disable_compose_stream(stream_id)
454+ ```
455+
234456## Role Management
235457
236458> Only wallets with manager privileges (e.g. ` system:network_writers_manager ` ) can grant or revoke roles. Regular users should request access from the TRUF.NETWORK team.
@@ -304,6 +526,28 @@ membership_status = client.are_members_of(
304526# ]
305527```
306528
529+ ### ` client.list_role_members(owner: str, role_name: str, limit: Optional[int] = None, offset: Optional[int] = None) -> List[RoleMember] `
530+ Lists the members of a role with optional pagination.
531+
532+ #### Parameters
533+ - ` owner: str ` - The owner namespace of the role (e.g., 'system')
534+ - ` role_name: str ` - The role to list members for
535+ - ` limit: Optional[int] ` - Maximum number of results to return
536+ - ` offset: Optional[int] ` - Number of records to skip for pagination
537+
538+ #### Returns
539+ - ` List[RoleMember] ` - List of role member dictionaries containing:
540+ - ` wallet: str ` - The wallet address
541+ - ` granted_at: int ` - Unix timestamp when role was granted
542+ - ` granted_by: str ` - Address that granted the role
543+
544+ #### Example
545+ ``` python
546+ members = client.list_role_members(" system" , " network_writer" , limit = 10 )
547+ for member in members:
548+ print (f " Wallet: { member[' wallet' ]} , Granted: { member[' granted_at' ]} " )
549+ ```
550+
307551## Visibility and Permissions
308552
309553### System vs. User Roles
@@ -327,16 +571,112 @@ Controls stream read access.
327571client.set_read_visibility(stream_id, " private" )
328572```
329573
330- ### ` client.allow_read_wallet(stream_id: str, wallet_address: str) -> str `
574+ ### ` client.allow_read_wallet(stream_id: str, wallet_address: str, wait: bool = True ) -> str `
331575Grants read permissions to specific wallets.
332576
333577#### Parameters
334578- ` stream_id: str ` - Stream identifier
335579- ` wallet_address: str ` - Ethereum wallet address
580+ - ` wait: bool ` - Whether to wait for transaction confirmation (default: True)
581+
582+ #### Returns
583+ - ` str ` - Transaction hash
584+
585+ #### Example
586+ ``` python
587+ tx_hash = client.allow_read_wallet(stream_id, " 0x1234..." )
588+ ```
589+
590+ ### ` client.disable_read_wallet(stream_id: str, wallet_address: str, wait: bool = True) -> str `
591+ Disables a wallet from reading the stream.
592+
593+ #### Parameters
594+ - ` stream_id: str ` - Stream identifier
595+ - ` wallet_address: str ` - Ethereum wallet address
596+ - ` wait: bool ` - Whether to wait for transaction confirmation (default: True)
597+
598+ #### Returns
599+ - ` str ` - Transaction hash
600+
601+ #### Example
602+ ``` python
603+ tx_hash = client.disable_read_wallet(stream_id, " 0x1234..." )
604+ ```
605+
606+ ### ` client.get_read_visibility(stream_id: str) -> str `
607+ Gets the read visibility of the stream.
608+
609+ #### Parameters
610+ - ` stream_id: str ` - Stream identifier
611+
612+ #### Returns
613+ - ` str ` - Visibility setting ("public" or "private")
614+
615+ #### Example
616+ ``` python
617+ visibility = client.get_read_visibility(stream_id)
618+ print (f " Read visibility: { visibility} " )
619+ ```
620+
621+ ### ` client.set_compose_visibility(stream_id: str, visibility: str, wait: bool = True) -> str `
622+ Sets the compose visibility of the stream.
623+
624+ #### Parameters
625+ - ` stream_id: str ` - Stream identifier
626+ - ` visibility: str ` - Visibility setting ("public" or "private")
627+ - ` wait: bool ` - Whether to wait for transaction confirmation (default: True)
628+
629+ #### Returns
630+ - ` str ` - Transaction hash
631+
632+ #### Example
633+ ``` python
634+ tx_hash = client.set_compose_visibility(stream_id, " private" )
635+ ```
636+
637+ ### ` client.get_compose_visibility(stream_id: str) -> str `
638+ Gets the compose visibility of the stream.
639+
640+ #### Parameters
641+ - ` stream_id: str ` - Stream identifier
642+
643+ #### Returns
644+ - ` str ` - Visibility setting ("public" or "private")
645+
646+ #### Example
647+ ``` python
648+ visibility = client.get_compose_visibility(stream_id)
649+ print (f " Compose visibility: { visibility} " )
650+ ```
651+
652+ ### ` client.get_allowed_read_wallets(stream_id: str) -> List[str] `
653+ Gets the wallets allowed to read the stream, if read stream is private.
654+
655+ #### Parameters
656+ - ` stream_id: str ` - Stream identifier
657+
658+ #### Returns
659+ - ` List[str] ` - List of allowed wallet addresses
660+
661+ #### Example
662+ ``` python
663+ allowed_wallets = client.get_allowed_read_wallets(stream_id)
664+ print (f " Allowed read wallets: { allowed_wallets} " )
665+ ```
666+
667+ ### ` client.get_allowed_compose_streams(stream_id: str) -> List[str] `
668+ Gets the streams allowed to compose this stream, if compose stream is private.
669+
670+ #### Parameters
671+ - ` stream_id: str ` - Stream identifier
672+
673+ #### Returns
674+ - ` List[str] ` - List of allowed stream identifiers
336675
337676#### Example
338677``` python
339- client.allow_read_wallet(stream_id, " 0x1234..." )
678+ allowed_streams = client.get_allowed_compose_streams(stream_id)
679+ print (f " Allowed compose streams: { allowed_streams} " )
340680```
341681
342682## Transaction Handling
0 commit comments