subgrounds package#
Subpackages#
- subgrounds.pagination package
- Submodules
- Module contents
generate_pagination_nodes()
LegacyStrategy
normalize()
paginate_iter()
paginate()
PaginationError
PaginationNode
PaginationNode.node_idx
PaginationNode.filter_field
PaginationNode.first_value
PaginationNode.skip_value
PaginationNode.filter_value
PaginationNode.filter_value_type
PaginationNode.key_path
PaginationNode.inner
PaginationNode.node_idx
PaginationNode.filter_field
PaginationNode.first_value
PaginationNode.skip_value
PaginationNode.filter_value
PaginationNode.filter_value_type
PaginationNode.key_path
PaginationNode.inner
PaginationNode.get_vardefs()
PaginationStrategy
prune_doc()
ShallowStrategy
- subgrounds.subgraph package
Submodules#
- subgrounds.client module
- subgrounds.dash_wrappers module
- subgrounds.dataframe_utils module
- subgrounds.plotly_wrappers module
Figure
TraceWrapper
Scatter
Pie
Bar
Heatmap
Contour
Table
Box
Violin
Histogram
Histogram2d
Histogram2dContour
Ohlc
Candlestick
Waterfall
Funnel
Indicator
Scatter3d
Surface
Scattergeo
Choropleth
Scattermapbox
Choroplethmapbox
Densitymapbox
Scatterpolar
Barpolar
Sunburst
Treemap
Icicle
Sankey
Parcoords
Parcats
Carpet
Scattercarpet
Contourcarpet
- subgrounds.query module
InputValue
VariableDefinition
Argument
Selection
Selection.fmeta
Selection.alias
Selection.arguments
Selection.selection
Selection.fmeta
Selection.alias
Selection.arguments
Selection.selection
Selection.key
Selection.args_graphql
Selection.graphql()
Selection.data_path
Selection.data_paths
Selection.iter()
Selection.iter_args()
Selection.filter()
Selection.filter_args()
Selection.map()
Selection.map_args()
Selection.filter_map()
Selection.filter_map_args()
Selection.for_all()
Selection.for_all_args()
Selection.exists()
Selection.exists_args()
Selection.find()
Selection.find_args()
Selection.find_all()
Selection.find_all_args()
Selection.T
Selection.fold()
Selection.contains_list()
Selection.split()
Selection.extract_data()
Selection.add()
Selection.remove()
Selection.variable_args()
Selection.infer_variable_definitions()
Selection.combine()
Selection.merge()
Selection.contains()
Selection.contains_argument()
Selection.get_argument()
Selection.get_argument_by_variable()
Selection.substitute_arg()
Selection.select()
Selection.prune_undefined()
Query
Query.name
Query.selection
Query.variables
Query.graphql
Query.iter()
Query.iter_args()
Query.iter_vardefs()
Query.filter()
Query.filter_args()
Query.filter_vardefs()
Query.map()
Query.map_args()
Query.map_vardefs()
Query.filter_map()
Query.filter_map_args()
Query.filter_map_vardefs()
Query.for_all()
Query.for_all_args()
Query.for_all_vardefs()
Query.exists()
Query.exists_args()
Query.exists_vardefs()
Query.find()
Query.find_args()
Query.find_vardefs()
Query.T
Query.fold()
Query.infer_variable_definitions()
Query.add()
Query.add_vardefs()
Query.remove()
Query.transform()
Query.contains_selection()
Query.contains_argument()
Query.get_argument()
Query.substitute_arg()
Query.contains()
Query.select()
Query.prune_undefined()
Fragment
Document
DataRequest
selections_of_object()
input_value_of_argument()
arguments_of_field_args()
- subgrounds.schema module
BaseModel
TypeRef
TypeMeta
SchemaMeta
SchemaMeta.query_type_
SchemaMeta.types
SchemaMeta.type_map
SchemaMeta.mutation_type_
SchemaMeta.subscription_type_
SchemaMeta.query_type
SchemaMeta.mutation_type
SchemaMeta.subscription_type
SchemaMeta.type_map_generator()
SchemaMeta.type_of_typeref()
SchemaMeta.type_of()
SchemaMeta.type_of_input_object_meta()
- subgrounds.subgrounds module
store_schema()
load_schema()
subgraph_slug()
Subgrounds
Subgrounds.headers
Subgrounds.global_transforms
Subgrounds.subgraphs
Subgrounds.from_pg_key()
Subgrounds.load()
Subgrounds.load_subgraph()
Subgrounds.load_api()
Subgrounds.mk_request()
Subgrounds.execute()
Subgrounds.execute_iter()
Subgrounds.query_json()
Subgrounds.query_json_iter()
Subgrounds.query_df()
Subgrounds.query_df_iter()
Subgrounds.query()
Subgrounds.query_iter()
- subgrounds.transform module
select_data()
RequestTransform
DocumentTransform
TypeTransform
LocalSyntheticField
LocalSyntheticField.subgraph
LocalSyntheticField.fmeta
LocalSyntheticField.type_
LocalSyntheticField.f
LocalSyntheticField.default
LocalSyntheticField.args
LocalSyntheticField.subgraph
LocalSyntheticField.fmeta
LocalSyntheticField.type_
LocalSyntheticField.f
LocalSyntheticField.default
LocalSyntheticField.args
LocalSyntheticField.transform_document()
LocalSyntheticField.transform_response()
SplitTransform
- subgrounds.utils module
Module contents#
- class subgrounds.FieldPath(subgraph: 'Subgraph', root_type: 'TypeRef.T', type_: 'TypeRef.T', path: 'list[Tuple[Optional[dict[str, Any]], TypeMeta.FieldMeta]]')#
Bases:
FieldOperatorMixin
- class subgrounds.Subgraph(url: 'str', schema: 'SchemaMeta', transforms: 'list[DocumentTransform]' = [<subgrounds.transform.TypeTransform object at 0x7f8be06e3a00>, <subgrounds.transform.TypeTransform object at 0x7f8be06e1000>], is_subgraph: 'bool' = True)#
Bases:
object
- class subgrounds.Subgrounds(headers: dict[str, typing.Any] = <factory>, global_transforms: list[subgrounds.transform.RequestTransform] = <factory>, subgraphs: dict[str, subgrounds.subgraph.subgraph.Subgraph] = <factory>)#
Bases:
object
- global_transforms: list[subgrounds.transform.RequestTransform]#
- subgraphs: dict[str, subgrounds.subgraph.subgraph.Subgraph]#
- classmethod from_pg_key(key)#
- load(url, save_schema=False, cache_dir='schemas/', is_subgraph=True)#
- load_subgraph(url, save_schema=False, cache_dir='schemas/')#
Performs introspection on the provided GraphQL API
url
to get the schema, stores the schema ifsave_schema
isTrue
and returns a generated class representing the subgraph with all its entities.- Parameters:
- Returns:
A generated class representing the subgraph and its entities
- Return type:
- load_api(url, save_schema=False, cache_dir='schemas/')#
Performs introspection on the provided GraphQL API
url
to get the schema, stores the schema ifsave_schema
isTrue
and returns a generated class representing the GraphQL endpoint with all its entities.
- mk_request(fpaths)#
Creates a
DataRequest
object by combining one or moreFieldPath
objects.
- execute(req, pagination_strategy=<class 'subgrounds.pagination.strategies.LegacyStrategy'>)#
Executes a
DataRequest
object, sending the underlying query(ies) to the server and returning a data blob (list of Python dictionaries, one per actual query).- Parameters:
req (DataRequest) -- The
DataRequest
object to be executedpagination_strategy (Optional[Type[PaginationStrategy]], optional) -- A Class implementing the
PaginationStrategy
Protocol
. IfNone
, then automatic pagination is disabled. Defaults toLegacyStrategy
.
- Returns:
The reponse data
- Return type:
- execute_iter(req, pagination_strategy=<class 'subgrounds.pagination.strategies.LegacyStrategy'>)#
Same as execute, except that an iterator is returned which will iterate the data pages.
- Parameters:
req (DataRequest) -- The
DataRequest
object to be executedpagination_strategy (Optional[Type[PaginationStrategy]], optional) -- A Class implementing the
PaginationStrategy
Protocol
. IfNone
, then automatic pagination is disabled. Defaults toLegacyStrategy
.
- Returns:
An iterator over the reponse data pages
- Return type:
Iterator[dict]
- query_json(fpaths, pagination_strategy=<class 'subgrounds.pagination.strategies.LegacyStrategy'>)#
Equivalent to
Subgrounds.execute(Subgrounds.mk_request(fpaths), pagination_strategy)
.- Parameters:
fpaths (FieldPath | list[FieldPath]) -- One or more
FieldPath
objects that should be included in the request.pagination_strategy (Optional[Type[PaginationStrategy]], optional) -- A Class implementing the
PaginationStrategy
Protocol
. IfNone
, then automatic pagination is disabled. Defaults toLegacyStrategy
.
- Returns:
The reponse data
- Return type:
- query_json_iter(fpaths, pagination_strategy=<class 'subgrounds.pagination.strategies.LegacyStrategy'>)#
Same as query_json except an iterator over the response data pages is returned.
- Parameters:
fpaths (FieldPath | list[FieldPath]) -- One or more
FieldPath
objects that should be included in the request.pagination_strategy (Optional[Type[PaginationStrategy]], optional) -- A Class implementing the
PaginationStrategy
Protocol
. IfNone
, then automatic pagination is disabled. Defaults toLegacyStrategy
.
- Returns:
The reponse data
- Return type:
- query_df(fpaths, columns=None, concat=False, pagination_strategy=<class 'subgrounds.pagination.strategies.LegacyStrategy'>)#
Same as
Subgrounds.query()
but formats the response data into a Pandas DataFrame. If the response data cannot be flattened to a single query (e.g.: when querying multiple list fields that return different entities), then multiple dataframes are returnedfpaths
is a list ofFieldPath
objects that indicate which data must be queried.columns
is an optional argument used to rename the dataframes(s) columns. The length ofcolumns
must be the same as the number of columns of all returned dataframes.concat
indicates whether or not the resulting dataframes should be concatenated together. The dataframes must have the same number of columns, as well as the same column names and types (the names can be set using thecolumns
argument).- Parameters:
fpaths (FieldPath | list[FieldPath]) -- One or more FieldPath objects that should be included in the request.
columns (Optional[list[str]], optional) -- The column labels. Defaults to None.
merge (bool, optional) -- Whether or not to merge resulting dataframes.
pagination_strategy (Optional[Type[PaginationStrategy]], optional) -- A Class implementing the
PaginationStrategy
Protocol
. IfNone
, then automatic pagination is disabled. Defaults toLegacyStrategy
.
- Returns:
A DataFrame containing the reponse data
- Return type:
pd.DataFrame | list[pd.DataFrame]
Example:
>>> from subgrounds import Subgrounds >>> sg = Subgrounds() >>> univ3 = sg.load_subgraph('https://api.thegraph.com/subgraphs/name/uniswap/uniswap-v3') # Define price SyntheticField >>> univ3.Swap.price = abs(univ3.Swap.amount0) / abs(univ3.Swap.amount1) # Query last 10 swaps from the ETH/USDC pool >>> eth_usdc = univ3.Query.swaps( ... orderBy=univ3.Swap.timestamp, ... orderDirection='desc', ... first=10, ... where=[ ... univ3.Swap.pool == '0x8ad599c3a0ff1de082011efddc58f1908eb6e6d8' ... ] ... ) >>> sg.query_df([ ... eth_usdc.timestamp, ... eth_usdc.price ... ]) swaps_timestamp swaps_price 0 1643213811 2618.886394 1 1643213792 2618.814281 2 1643213792 2617.500494 3 1643213763 2615.458495 4 1643213763 2615.876574 5 1643213739 2615.352390 6 1643213678 2615.205713 7 1643213370 2614.115746 8 1643213210 2613.077301 9 1643213196 2610.686563
- query_df_iter(fpaths, pagination_strategy=<class 'subgrounds.pagination.strategies.LegacyStrategy'>)#
Same as query_df except an iterator over the response data pages is returned :param fpaths: One or more FieldPath objects that
should be included in the request
- Parameters:
columns (Optional[list[str]], optional) -- The column labels. Defaults to None.
merge (bool, optional) -- Whether or not to merge resulting dataframes.
pagination_strategy (Optional[Type[PaginationStrategy]], optional) -- A Class implementing the
PaginationStrategy
Protocol
. IfNone
, then automatic pagination is disabled. Defaults toLegacyStrategy
.
- Returns:
An iterator over the response data pages, each as a DataFrame
- Return type:
Iterator[pd.DataFrame]
- query(fpaths, unwrap=True, pagination_strategy=<class 'subgrounds.pagination.strategies.LegacyStrategy'>)#
Executes one or multiple
FieldPath
objects immediately and return the data (as a tuple if multipleFieldPath
objects are provided).- Parameters:
fpaths (FieldPath | list[FieldPath]) -- One or more
FieldPath
object(s) to query.unwrap (bool, optional) -- Flag indicating whether or not, in the case where the returned data is a list of one element, the element itself should be returned instead of the list. Defaults to
True
.pagination_strategy (Optional[Type[PaginationStrategy]], optional) -- A Class implementing the
PaginationStrategy
Protocol
. IfNone
, then automatic pagination is disabled. Defaults toLegacyStrategy
.
- Returns:
The
FieldPath
object(s) data- Return type:
[type]
Example:
>>> from subgrounds import Subgrounds >>> sg = Subgrounds() >>> univ3 = sg.load_subgraph('https://api.thegraph.com/subgraphs/name/uniswap/uniswap-v3') # Define price SyntheticField >>> univ3.Swap.price = abs(univ3.Swap.amount0) / abs(univ3.Swap.amount1) # Construct FieldPath to get price of last swap on ETH/USDC pool >>> eth_usdc_last = univ3.Query.swaps( ... orderBy=univ3.Swap.timestamp, ... orderDirection='desc', ... first=1, ... where=[ ... univ3.Swap.pool == '0x8ad599c3a0ff1de082011efddc58f1908eb6e6d8' ... ] ... ).price # Query last price FieldPath >>> sg.query(eth_usdc_last) 2628.975030015892
- query_iter(fpaths, unwrap=True, pagination_strategy=<class 'subgrounds.pagination.strategies.LegacyStrategy'>)#
Same as query except an iterator over the resonse data pages is returned.
- Parameters:
fpath (FieldPath | list[FieldPath]) -- One or more
FieldPath
object(s) to query.unwrap (bool, optional) -- Flag indicating whether or not, in the case where the returned data is a list of one element, the element itself should be returned instead of the list. Defaults to
True
.pagination_strategy (Optional[Type[PaginationStrategy]], optional) -- A Class implementing the
PaginationStrategy
Protocol
. IfNone
, then automatic pagination is disabled. Defaults toLegacyStrategy
.
- Returns:
An iterator over the
FieldPath
object(s)' data pages- Return type:
Iterator[type]
- class subgrounds.SyntheticField(f: 'Callable', type_: 'TypeRef.T', deps: 'list[FieldPath | SyntheticField] | FieldPath | SyntheticField', default: 'Any' = None)#
Bases:
FieldOperatorMixin
- STRING: ClassVar[TypeRef.Named] = Named(name_='String', kind='SCALAR')#
- INT: ClassVar[TypeRef.Named] = Named(name_='Int', kind='SCALAR')#
- FLOAT: ClassVar[TypeRef.Named] = Named(name_='Float', kind='SCALAR')#
- BOOL: ClassVar[TypeRef.Named] = Named(name_='Boolean', kind='SCALAR')#
- static default_of_type(type_)#
- static constant(value)#
Returns a constant
SyntheticField
with valuevalue
. Useful for injecting additional static data to a schema or merging entities.- Parameters:
value (str | int | float | bool) -- The constant field's value
- Returns:
The constant
SyntheticField
- Return type:
Example:
>>> from subgrounds.subgrounds import Subgrounds >>> from subgrounds.subgraph import SyntheticField >>> sg = Subgrounds() >>> univ3 = sg.load_subgraph( ... 'https://api.thegraph.com/subgraphs/name/uniswap/uniswap-v3' ... ) # Create constant SyntheticFields >>> univ3.Mint.tx_type = SyntheticField.constant('MINT') >>> univ3.Burn.tx_type = SyntheticField.constant('BURN') # Last 10 mints and burns >>> mints = univ3.Query.mints( ... first=10, ... orderBy=univ3.Mint.timestamp, ... orderDirection='desc' ... ) >>> burns = univ3.Query.burns( ... first=10, ... orderBy=univ3.Burn.timestamp, ... orderDirection='desc' ... ) # Query mints and burns. Notice that we merge the two entity tables by # setting `concat=True` and overwriting the column names (columns must # match the `FieldPaths`) >>> df = sg.query_df([ ... mints.transaction.id, ... mints.timestamp, ... mints.tx_type, ... mints.origin, ... mints.amountUSD, ... burns.transaction.id, ... burns.timestamp, ... burns.tx_type, ... burns.origin, ... burns.amountUSD, ... ], columns=['tx_hash', 'timestamp', 'tx_type', 'origin', 'amount_USD'], concat=True) # Sort the DataFrame >>> df.sort_values(by=['timestamp'], ascending=False) tx_hash timestamp tx_type origin amount_USD 0 0xcbe1bacacc1e64fe613ae5eef2063563bd0057d1e3df... 1656016553 MINT 0x3435e7946d40b1a83c0cf154326fc6b3ca908952 7.879784e+03 1 0xdddaaddf59e5a3abff4feadef83b3ceb023a74424ea7... 1656016284 MINT 0xc747962e7e416e2a582813b1d7ad59eb83077fa6 5.110840e+04 10 0xa7671452c34a3b083083ef81e364489c2c9ee801a3b8... 1656016284 BURN 0xd40db77990bbb30514276b5ac17c3ce5cc9c951f 2.804573e+05 2 0xc132e73975e77c2c2c91fcf332018dfb01aac0ca9471... 1656015853 MINT 0xc747962e7e416e2a582813b1d7ad59eb83077fa6 5.122569e+04 3 0x1444744f4021a2046787c1b7b88cd9ac21f071c65acc... 1656015773 MINT 0xd11aa2e3a000275ed12b87515c9ac0d67b32e7b9 8.897983e+03 4 0x3315617d426fc2b0db5d8dbccd549efaa8f1ae2969ca... 1656015693 MINT 0xb7dd4d134b1794ee848e1af1a62b85d7b2ea9301 0.000000e+00 11 0xcc713daa2dc58cd1f2218c8f438e7fcf04d2e9c7c83d... 1656015278 BURN 0xa7c43e2057d89b6946b8865efc8bee3a4ea7d28d 1.254942e+06 5 0x7bbfae86f0c3c983651bd0671557cd851fc301317c06... 1656015111 MINT 0xac56cee8ccd00d0c1d72ce3415140874552e80f4 3.432075e+04 12 0xea21c3a68a8f0c6a2721a3072e0c8b2edc77f4d2f0d9... 1656014785 BURN 0x0709b103d46d71458a71e5d81230dd688809a53d 2.059106e+04 6 0x3bd369bf45c55cab40c62db81bb3e0684fd85fe2b662... 1656014120 MINT 0x509984bfc0fb24e2d1377cfec224d3afec4c341e 2.517578e+03 13 0x1ea59da77c442479af8fb51501a931260d473e249de7... 1656014018 BURN 0x509984bfc0fb24e2d1377cfec224d3afec4c341e 0.000000e+00 7 0xb9d31ef78b8bf786b422d948dd1fba246710078abff8... 1656013998 MINT 0x22dfec183294d257f80c15d3c9cd47495bdc728c 8.365750e+04 14 0xc5e3ec84a2860e3c3a055ccdced435a67b4aff4dd3be... 1656013946 BURN 0xac56cee8ccd00d0c1d72ce3415140874552e80f4 3.363809e+04 8 0x7c736255d9a4ebf4781069a1b2a929ad89100f1af980... 1656013913 MINT 0x4ce6aea89f059915ae5efbf34a2a8adc544ae09e 4.837287e+04 15 0x95cf56b9eb69aa45048a9b7b3e472df5bc3bfad591cd... 1656013728 BURN 0x4ce6aea89f059915ae5efbf34a2a8adc544ae09e 5.110010e+04 9 0x76dd2bbf43485c224471dd823c2992178f031f27194b... 1656013599 MINT 0x234a644868c419ce0dcdd9fd539762eba47f3759 5.363896e+03 16 0x47e595b02fdcb51ff42a5008e53be7ee3bdf8063b580... 1656013580 BURN 0xaf0fdd39e5d92499b0ed9f68693da99c0ec1e92e 0.000000e+00 17 0xe20ec9702f455d74b3cc1f54fe2f3450604ca5037a72... 1656013455 BURN 0xaf0fdd39e5d92499b0ed9f68693da99c0ec1e92e 0.000000e+00 18 0xac3e95666be3a45fdfbbfa513a114136ea6ecffb9de2... 1656013237 BURN 0x665d2d2444f2384fb3d96aaa0ea3536b92984dce 2.254100e+05 19 0x01c3424a48c36104ea388482723347f15c0bc1bb1a80... 1656013034 BURN 0x0084ee6c8893c01e252198b56ec127443dc27464 0.000000e+00
- static datetime_of_timestamp(timestamp)#
Returns a
SyntheticField
that will transform theFieldPath
timestamp
into a human-readable ISO8601 string.- Parameters:
timestamp (FieldPath | SyntheticField) -- A
FieldPath
representing a Unix timestamp field.- Returns:
An ISO8601 datetime string
SyntheticField
.- Return type:
Example:
>>> from subgrounds.subgrounds import Subgrounds >>> from subgrounds.subgraph import SyntheticField >>> sg = Subgrounds() >>> univ3 = sg.load_subgraph( ... 'https://api.thegraph.com/subgraphs/name/uniswap/uniswap-v3' ... ) # Create datetime SyntheticField >>> univ3.Swap.datetime = SyntheticField.datetime_of_timestamp(univ3.Swap.timestamp) # Query 100 swaps >>> sg.query_df([ ... univ3.Query.swaps.timestamp, ... univ3.Query.swaps.datetime, ... ]) swaps_timestamp swaps_datetime 0 1625105710 2021-06-30 22:15:10 1 1629253724 2021-08-17 22:28:44 2 1647333277 2022-03-15 04:34:37 3 1630801974 2021-09-04 20:32:54 4 1653240241 2022-05-22 13:24:01 .. ... ... 95 1646128326 2022-03-01 04:52:06 96 1646128326 2022-03-01 04:52:06 97 1626416555 2021-07-16 02:22:35 98 1626416555 2021-07-16 02:22:35 99 1625837291 2021-07-09 09:28:11
- static map(dict, type_, fpath, default=None)#
Returns a SyntheticField that will map the values of
fpath
using the key value pairs indict
. If a value is not in the dictionary, thendefault
will be used instead.- Parameters:
dict (dict[Any, Any]) -- The dictionary containing the key value pairs used to map
fpath
's valuestype (TypeRef.T) -- The type of the resulting field
fpath (FieldPath | SyntheticField) -- The FieldPath whose values will be mapped using the dictionary
default (Optional[Any]) -- Default value used when a value is not in the provided dictionary
- Returns:
A map SyntheticField
- Return type:
Example:
>>> from subgrounds.subgrounds import Subgrounds >>> from subgrounds.subgraph import SyntheticField >>> sg = Subgrounds() >>> univ3 = sg.load_subgraph( ... 'https://api.thegraph.com/subgraphs/name/uniswap/uniswap-v3' ... ) # Hand-crafted mapping of pool addresses to symbol >>> pooladdr_symbol_map = { ... '0x5777d92f208679db4b9778590fa3cab3ac9e2168': 'DAI/USDC-001', ... '0x6c6bc977e13df9b0de53b251522280bb72383700': 'DAI/USDC-005', ... '0x8ad599c3a0ff1de082011efddc58f1908eb6e6d8': 'USDC/ETH-030', ... '0x88e6a0c2ddd26feeb64f039a2c41296fcb3f5640': 'USDC/ETH-005', ... } # Create map SyntheticField using our dictionary with 'UNKNOWN' as the # default value >>> univ3.Pool.symbol = SyntheticField.map( ... pooladdr_symbol_map, ... SyntheticField.STRING, ... univ3.Pool.id, ... 'UNKNOWN' ... ) # Query top 10 pools by TVL >>> pools = univ3.Query.pools( ... first=10, ... orderBy=univ3.Pool.totalValueLockedUSD, ... orderDirection='desc' ... ) >>> sg.query_df([ ... pools.id, ... pools.symbol ... ]) pools_id pools_symbol 0 0xa850478adaace4c08fc61de44d8cf3b64f359bec UNKNOWN 1 0x5777d92f208679db4b9778590fa3cab3ac9e2168 DAI/USDC-001 2 0x6c6bc977e13df9b0de53b251522280bb72383700 DAI/USDC-005 3 0x8ad599c3a0ff1de082011efddc58f1908eb6e6d8 USDC/ETH-030 4 0x88e6a0c2ddd26feeb64f039a2c41296fcb3f5640 USDC/ETH-005 5 0x3416cf6c708da44db2624d63ea0aaef7113527c6 UNKNOWN 6 0xcbcdf9626bc03e24f779434178a73a0b4bad62ed UNKNOWN 7 0xc63b0708e2f7e69cb8a1df0e1389a98c35a76d52 UNKNOWN 8 0x4585fe77225b41b697c938b018e2ac67ac5a20c0 UNKNOWN 9 0x4e68ccd3e89f51c3074ca5072bbac773960dfa36 UNKNOWN