erc_4626.vault_protocol.ipor.offchain_metadata
Documentation for eth_defi.erc_4626.vault_protocol.ipor.offchain_metadata Python module.
IPOR vault offchain metadata.
IPOR stores vault descriptions, logos and optional atomist names in a public S3-backed JSON file at
api.ipor.ioWe reverse-engineered the IPOR Fusion React SPA and discovered the
/fusion/vaults-customization-listendpoint that serves vault metadata including descriptions, logos, links and optionalcuratorNamevaluesThe frontend bundle also contains the public IPOR app vault configuration. We parse only the address-keyed
atomistvalues from this bundle, because production API rows currently exposecuratorNamesparsely.Vault accessors fetch this metadata lazily on first access and then reuse the local disk cache and module-level in-process cache where available.
Data flow in the IPOR frontend
The vault info page loads descriptions from two sources and merges them:
description = customization?.description ?? config?.description
Where customization comes from the API and config is hardcoded in the
JS bundle. Descriptions come from the API customisation source. Manager names
prefer API curatorName and fall back to the frontend atomist value.
Reference:
API base URL:
https://api.ipor.ioCustomisation endpoint:
GET /fusion/vaults-customization-list
Functions
|
Fetch known IPOR atomist names for curator maintenance checks. |
|
Fetch and cache the IPOR vault customisation list. |
|
Fetch and cache IPOR frontend atomist metadata. |
|
Fetch an IPOR vault atomist display name. |
|
Fetch vault metadata from IPOR's offchain customisation API. |
Classes
Metadata about an IPOR vault from the offchain customisation API. |
- class IPORVaultMetadata
Bases:
TypedDictMetadata about an IPOR vault from the offchain customisation API.
Fetched from
api.ipor.io/fusion/vaults-customization-list. Discovered by reverse-engineering the IPOR Fusion React SPA JavaScript bundles.The customisation endpoint returns a flat JSON array. Each entry corresponds to a vault that has had its metadata edited by the vault’s atomist (operator). Not all IPOR vaults have customisation entries — only those whose atomists have set descriptions via the IPOR frontend.
Reference:
- __init__(*args, **kwargs)
- __new__(**kwargs)
- clear()
Remove all items from the dict.
- copy()
Return a shallow copy of the dict.
- fromkeys(value=None, /)
Create a new dictionary with keys from iterable and values set to value.
- get(key, default=None, /)
Return the value for key if key is in the dictionary, else default.
- items()
Return a set-like object providing a view on the dict’s items.
- keys()
Return a set-like object providing a view on the dict’s keys.
- pop(k[, d]) v, remove specified key and return the corresponding value.
If the key is not found, return the default if given; otherwise, raise a KeyError.
- popitem()
Remove and return a (key, value) pair as a 2-tuple.
Pairs are returned in LIFO (last-in, first-out) order. Raises KeyError if the dict is empty.
- setdefault(key, default=None, /)
Insert key with a value of default if key is not in the dictionary.
Return the value for key if key is in the dictionary, else default.
- update([E, ]**F) None. Update D from mapping/iterable E and F.
If E is present and has a .keys() method, then does: for k in E.keys(): D[k] = E[k] If E is present and lacks a .keys() method, then does: for k, v in E: D[k] = v In either case, this is followed by: for k in F: D[k] = F[k]
- values()
Return an object providing a view on the dict’s values.
- fetch_ipor_atomist_names(cache_path=PosixPath('/home/runner/.tradingstrategy/cache/ipor'), api_base_url='https://api.ipor.io', app_base_url='https://app.ipor.io', now_=None, max_cache_duration=datetime.timedelta(days=2))
Fetch known IPOR atomist names for curator maintenance checks.
This helper is for audits and tests that need the set of IPOR manager names, not a vault-specific lookup. Vault accessors should call
fetch_ipor_vault_atomist()instead.- Parameters
cache_path (pathlib.Path) – Directory for IPOR cache files.
api_base_url (str) – IPOR data API base URL.
app_base_url (str) – IPOR Fusion app base URL.
now – Override current time for tests.
max_cache_duration (datetime.timedelta) – Cache time-to-live.
now_ (Optional[datetime.datetime]) –
- Returns
Set of atomist display names IPOR exposes through API or frontend data.
- Return type
- fetch_ipor_customisation_list(cache_path=PosixPath('/home/runner/.tradingstrategy/cache/ipor'), api_base_url='https://api.ipor.io', now_=None, max_cache_duration=datetime.timedelta(days=2))
Fetch and cache the IPOR vault customisation list.
The API returns a single JSON array covering all chains. We index by
(chain_id, checksummed_address)for fast lookup.Single JSON cache file for all chains
Multiprocess safe via file lock
- Parameters
cache_path (pathlib.Path) – Directory for cache files (default
~/.tradingstrategy/cache/ipor/)api_base_url (str) – IPOR data API base URL
now – Override current time (for testing)
max_cache_duration (datetime.timedelta) – How long before refreshing cache (default 2 days)
now_ (Optional[datetime.datetime]) –
- Returns
Dict mapping
(chain_id, checksummed_address)toIPORVaultMetadata- Return type
dict[tuple[int, str], eth_defi.erc_4626.vault_protocol.ipor.offchain_metadata.IPORVaultMetadata]
- fetch_ipor_frontend_atomists(cache_path=PosixPath('/home/runner/.tradingstrategy/cache/ipor'), app_base_url='https://app.ipor.io', now_=None, max_cache_duration=datetime.timedelta(days=2))
Fetch and cache IPOR frontend atomist metadata.
The cache stores only the parsed
vault_address -> atomistmapping, not the full JavaScript bundle. If refresh fails but an older cache exists, the stale cache is returned so manager attribution does not disappear because of a transient app or CDN failure.- Parameters
cache_path (pathlib.Path) – Directory for cache files.
app_base_url (str) – IPOR Fusion app base URL.
now – Override current time for tests.
max_cache_duration (datetime.timedelta) – Cache time-to-live.
now_ (Optional[datetime.datetime]) –
- Returns
Dict keyed by lower-case vault address.
- Return type
- fetch_ipor_vault_atomist(web3, vault_address, *, cache_path=PosixPath('/home/runner/.tradingstrategy/cache/ipor'), api_base_url='https://api.ipor.io', app_base_url='https://app.ipor.io', now_=None, max_cache_duration=datetime.timedelta(days=2))
Fetch an IPOR vault atomist display name.
This accessor-style helper mirrors other protocol offchain metadata modules: the first vault property access triggers the fetch, then the local disk cache and in-process cache are reused by later calls.
- Parameters
web3 (web3.main.Web3) – Web3 instance used to get the EVM chain id.
vault_address (eth_typing.evm.HexAddress) – Vault contract address.
cache_path (pathlib.Path) – Directory for IPOR cache files.
api_base_url (str) – IPOR data API base URL.
app_base_url (str) – IPOR Fusion app base URL.
now – Override current time for tests.
max_cache_duration (datetime.timedelta) – Cache time-to-live.
now_ (Optional[datetime.datetime]) –
- Returns
Atomist display name, or
Noneif IPOR does not expose one.- Return type
- fetch_ipor_vault_metadata(web3, vault_address)
Fetch vault metadata from IPOR’s offchain customisation API.
Uses a two-level cache: in-process dict + disk cache
Returns
Noneif the vault has no customisation entry (i.e. the atomist has not set a description via the IPOR frontend)
- Parameters
web3 (web3.main.Web3) – Web3 instance (used to get chain_id and checksum address)
vault_address (eth_typing.evm.HexAddress) – Vault contract address
- Returns
Metadata dict or None if the vault has no customisation entry
- Return type
Optional[eth_defi.erc_4626.vault_protocol.ipor.offchain_metadata.IPORVaultMetadata]