@agoric/fast-usdc 0.1.1-dev-78063fc.0 → 0.1.1-dev-b58d523.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +15 -15
- package/src/fast-usdc-policy.core.js +5 -1
- package/src/fast-usdc.start.js +3 -1
- package/src/type-guards.js +10 -1
- package/src/types.ts +12 -4
- package/src/utils/chain-policies.js +140 -0
- package/src/utils/deploy-config.js +13 -36
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@agoric/fast-usdc",
|
|
3
|
-
"version": "0.1.1-dev-
|
|
3
|
+
"version": "0.1.1-dev-b58d523.0+b58d523",
|
|
4
4
|
"description": "CLI and library for Fast USDC product",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"files": [
|
|
@@ -22,9 +22,9 @@
|
|
|
22
22
|
"lint:eslint": "eslint ."
|
|
23
23
|
},
|
|
24
24
|
"devDependencies": {
|
|
25
|
-
"@agoric/swingset-liveslots": "0.10.3-dev-
|
|
26
|
-
"@agoric/vats": "0.15.2-dev-
|
|
27
|
-
"@agoric/zone": "0.2.3-dev-
|
|
25
|
+
"@agoric/swingset-liveslots": "0.10.3-dev-b58d523.0+b58d523",
|
|
26
|
+
"@agoric/vats": "0.15.2-dev-b58d523.0+b58d523",
|
|
27
|
+
"@agoric/zone": "0.2.3-dev-b58d523.0+b58d523",
|
|
28
28
|
"@fast-check/ava": "^2.0.1",
|
|
29
29
|
"ava": "^5.3.0",
|
|
30
30
|
"c8": "^10.1.2",
|
|
@@ -32,16 +32,16 @@
|
|
|
32
32
|
"ts-blank-space": "^0.4.4"
|
|
33
33
|
},
|
|
34
34
|
"dependencies": {
|
|
35
|
-
"@agoric/client-utils": "0.1.1-dev-
|
|
36
|
-
"@agoric/cosmic-proto": "0.4.1-dev-
|
|
37
|
-
"@agoric/ertp": "0.16.3-dev-
|
|
38
|
-
"@agoric/internal": "0.3.3-dev-
|
|
39
|
-
"@agoric/notifier": "0.6.3-dev-
|
|
40
|
-
"@agoric/orchestration": "0.1.1-dev-
|
|
41
|
-
"@agoric/store": "0.9.3-dev-
|
|
42
|
-
"@agoric/vat-data": "0.5.3-dev-
|
|
43
|
-
"@agoric/vow": "0.1.1-dev-
|
|
44
|
-
"@agoric/zoe": "0.26.3-dev-
|
|
35
|
+
"@agoric/client-utils": "0.1.1-dev-b58d523.0+b58d523",
|
|
36
|
+
"@agoric/cosmic-proto": "0.4.1-dev-b58d523.0+b58d523",
|
|
37
|
+
"@agoric/ertp": "0.16.3-dev-b58d523.0+b58d523",
|
|
38
|
+
"@agoric/internal": "0.3.3-dev-b58d523.0+b58d523",
|
|
39
|
+
"@agoric/notifier": "0.6.3-dev-b58d523.0+b58d523",
|
|
40
|
+
"@agoric/orchestration": "0.1.1-dev-b58d523.0+b58d523",
|
|
41
|
+
"@agoric/store": "0.9.3-dev-b58d523.0+b58d523",
|
|
42
|
+
"@agoric/vat-data": "0.5.3-dev-b58d523.0+b58d523",
|
|
43
|
+
"@agoric/vow": "0.1.1-dev-b58d523.0+b58d523",
|
|
44
|
+
"@agoric/zoe": "0.26.3-dev-b58d523.0+b58d523",
|
|
45
45
|
"@cosmjs/proto-signing": "^0.32.4",
|
|
46
46
|
"@cosmjs/stargate": "^0.32.4",
|
|
47
47
|
"@endo/base64": "^1.0.9",
|
|
@@ -81,5 +81,5 @@
|
|
|
81
81
|
"publishConfig": {
|
|
82
82
|
"access": "public"
|
|
83
83
|
},
|
|
84
|
-
"gitHead": "
|
|
84
|
+
"gitHead": "b58d52340da194d6e51264cf3a54b51968e28bb4"
|
|
85
85
|
}
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
/** @file core-eval to publish update to Fast USDC feedPolicy */
|
|
2
2
|
|
|
3
3
|
import { E } from '@endo/far';
|
|
4
|
+
import { makeMarshal } from '@endo/marshal';
|
|
5
|
+
import { Fail } from '@endo/errors';
|
|
4
6
|
import { fromExternalConfig } from './utils/config-marshal.js';
|
|
5
7
|
import { FeedPolicyShape } from './type-guards.js';
|
|
6
8
|
|
|
@@ -14,6 +16,7 @@ import { FeedPolicyShape } from './type-guards.js';
|
|
|
14
16
|
|
|
15
17
|
const contractName = 'fastUsdc';
|
|
16
18
|
const FEED_POLICY = 'feedPolicy';
|
|
19
|
+
const marshalData = makeMarshal(_val => Fail`data only`);
|
|
17
20
|
|
|
18
21
|
/**
|
|
19
22
|
* XXX copied from fast-usdc.start.js
|
|
@@ -23,7 +26,8 @@ const FEED_POLICY = 'feedPolicy';
|
|
|
23
26
|
*/
|
|
24
27
|
const publishFeedPolicy = async (node, policy) => {
|
|
25
28
|
const feedPolicy = E(node).makeChildNode(FEED_POLICY);
|
|
26
|
-
|
|
29
|
+
const value = marshalData.toCapData(policy);
|
|
30
|
+
await E(feedPolicy).setValue(JSON.stringify(value));
|
|
27
31
|
};
|
|
28
32
|
|
|
29
33
|
/**
|
package/src/fast-usdc.start.js
CHANGED
|
@@ -22,6 +22,7 @@ import { fromExternalConfig } from './utils/config-marshal.js';
|
|
|
22
22
|
* @import {Board} from '@agoric/vats'
|
|
23
23
|
* @import {ManifestBundleRef} from '@agoric/deploy-script-support/src/externalTypes.js'
|
|
24
24
|
* @import {BootstrapManifest} from '@agoric/vats/src/core/lib-boot.js'
|
|
25
|
+
* @import {Passable} from '@endo/pass-style'
|
|
25
26
|
* @import {LegibleCapData} from './utils/config-marshal.js'
|
|
26
27
|
* @import {FastUsdcSF} from './fast-usdc.contract.js'
|
|
27
28
|
* @import {FeedPolicy, FastUSDCConfig} from './types.js'
|
|
@@ -93,7 +94,8 @@ const POOL_METRICS = 'poolMetrics';
|
|
|
93
94
|
*/
|
|
94
95
|
const publishFeedPolicy = async (node, policy) => {
|
|
95
96
|
const feedPolicy = E(node).makeChildNode(FEED_POLICY);
|
|
96
|
-
|
|
97
|
+
const value = marshalData.toCapData(policy);
|
|
98
|
+
await E(feedPolicy).setValue(JSON.stringify(value));
|
|
97
99
|
};
|
|
98
100
|
|
|
99
101
|
/**
|
package/src/type-guards.js
CHANGED
|
@@ -122,10 +122,19 @@ harden(PoolMetricsShape);
|
|
|
122
122
|
|
|
123
123
|
/** @type {TypedPattern<ChainPolicy>} */
|
|
124
124
|
export const ChainPolicyShape = {
|
|
125
|
-
|
|
125
|
+
attenuatedCttpBridgeAddresses: M.splitArray(
|
|
126
|
+
[EvmHashShape],
|
|
127
|
+
undefined,
|
|
128
|
+
M.arrayOf(EvmHashShape),
|
|
129
|
+
),
|
|
126
130
|
cctpTokenMessengerAddress: EvmHashShape,
|
|
127
131
|
confirmations: M.number(),
|
|
128
132
|
chainId: M.number(),
|
|
133
|
+
rateLimits: {
|
|
134
|
+
tx: M.bigint(),
|
|
135
|
+
blockWindow: M.bigint(),
|
|
136
|
+
blockWindowSize: M.number(),
|
|
137
|
+
},
|
|
129
138
|
};
|
|
130
139
|
harden(ChainPolicyShape);
|
|
131
140
|
|
package/src/types.ts
CHANGED
|
@@ -82,27 +82,35 @@ export interface PoolMetrics extends PoolStats {
|
|
|
82
82
|
|
|
83
83
|
export interface ChainPolicy {
|
|
84
84
|
/** `msg.sender` of DepositAndBurn to TokenMessenger must be an attenuated wrapper contract that does not contain `replaceDepositForBurn` */
|
|
85
|
-
|
|
85
|
+
attenuatedCttpBridgeAddresses: EvmHash[];
|
|
86
86
|
/** @see {@link https://developers.circle.com/stablecoins/evm-smart-contracts} */
|
|
87
87
|
cctpTokenMessengerAddress: EvmHash;
|
|
88
88
|
/** e.g., `1` for ETH mainnet 42161 for Arbitrum One. @see {@link https://chainlist.org/} */
|
|
89
89
|
chainId: EvmChainID;
|
|
90
90
|
/** the number of block confirmations to observe before reporting */
|
|
91
91
|
confirmations: number;
|
|
92
|
+
rateLimits: {
|
|
93
|
+
/** do not advance more than this amount for an individual transaction */
|
|
94
|
+
tx: bigint;
|
|
95
|
+
/** do not advance more than this amount per block window */
|
|
96
|
+
blockWindow: bigint;
|
|
97
|
+
/** the number of blocks to consider for `blockWindow` */
|
|
98
|
+
blockWindowSize: number;
|
|
99
|
+
};
|
|
92
100
|
}
|
|
93
101
|
|
|
94
|
-
export
|
|
102
|
+
export type FeedPolicy = {
|
|
95
103
|
nobleDomainId: number;
|
|
96
104
|
nobleAgoricChannelId: string;
|
|
97
105
|
chainPolicies: Record<EvmChainName, ChainPolicy>;
|
|
98
106
|
eventFilter?: string;
|
|
99
|
-
}
|
|
107
|
+
} & CopyRecord;
|
|
100
108
|
|
|
101
109
|
export type FastUSDCConfig = {
|
|
102
110
|
terms: FastUsdcTerms;
|
|
103
111
|
oracles: Record<string, string>;
|
|
104
112
|
feeConfig: FeeConfig;
|
|
105
|
-
feedPolicy: FeedPolicy
|
|
113
|
+
feedPolicy: FeedPolicy;
|
|
106
114
|
noNoble: boolean; // support a3p-integration, which has no noble chain
|
|
107
115
|
chainInfo: Record<string, CosmosChainInfo & Passable>;
|
|
108
116
|
assetInfo: [Denom, DenomDetail & { brandKey?: string }][];
|
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
/** @import {ChainPolicy} from '../types.js'; */
|
|
2
|
+
|
|
3
|
+
/** @satisfies {Record<'MAINNET'| 'TESTNET', Record<string, ChainPolicy>>} */
|
|
4
|
+
export const ChainPolicies = /** @type {const} */ ({
|
|
5
|
+
MAINNET: {
|
|
6
|
+
Arbitrum: {
|
|
7
|
+
attenuatedCttpBridgeAddresses: [
|
|
8
|
+
'0xe298b93ffB5eA1FB628e0C0D55A43aeaC268e347',
|
|
9
|
+
],
|
|
10
|
+
cctpTokenMessengerAddress: '0x19330d10D9Cc8751218eaf51E8885D058642E08A',
|
|
11
|
+
chainId: 42161,
|
|
12
|
+
// TODO confirm confirmations and rateLimits
|
|
13
|
+
confirmations: 2,
|
|
14
|
+
rateLimits: {
|
|
15
|
+
blockWindow: 20_000_000_000n,
|
|
16
|
+
blockWindowSize: 10,
|
|
17
|
+
tx: 10_000_000_000n,
|
|
18
|
+
},
|
|
19
|
+
},
|
|
20
|
+
Base: {
|
|
21
|
+
attenuatedCttpBridgeAddresses: [
|
|
22
|
+
'0xB6615B2662b35fc3533F8479002e62D0523341De',
|
|
23
|
+
],
|
|
24
|
+
cctpTokenMessengerAddress: '0x1682Ae6375C4E4A97e4B583BC394c861A46D8962',
|
|
25
|
+
chainId: 8453,
|
|
26
|
+
// TODO confirm confirmations and rateLimits
|
|
27
|
+
confirmations: 2,
|
|
28
|
+
rateLimits: {
|
|
29
|
+
blockWindow: 20_000_000_000n,
|
|
30
|
+
blockWindowSize: 10,
|
|
31
|
+
tx: 10_000_000_000n,
|
|
32
|
+
},
|
|
33
|
+
},
|
|
34
|
+
Ethereum: {
|
|
35
|
+
attenuatedCttpBridgeAddresses: [
|
|
36
|
+
'0xBC8552339dA68EB65C8b88B414B5854E0E366cFc',
|
|
37
|
+
],
|
|
38
|
+
cctpTokenMessengerAddress: '0xBd3fa81B58Ba92a82136038B25aDec7066af3155',
|
|
39
|
+
chainId: 1,
|
|
40
|
+
// TODO confirm confirmations and rateLimits
|
|
41
|
+
confirmations: 2,
|
|
42
|
+
rateLimits: {
|
|
43
|
+
blockWindow: 20_000_000_000n,
|
|
44
|
+
blockWindowSize: 10,
|
|
45
|
+
tx: 10_000_000_000n,
|
|
46
|
+
},
|
|
47
|
+
},
|
|
48
|
+
Optimism: {
|
|
49
|
+
attenuatedCttpBridgeAddresses: [
|
|
50
|
+
'0x48C5417ED570928eC85D5e3AD4e7E0EeD7dB1E2A',
|
|
51
|
+
],
|
|
52
|
+
cctpTokenMessengerAddress: '0x2B4069517957735bE00ceE0fadAE88a26365528f',
|
|
53
|
+
chainId: 10,
|
|
54
|
+
// TODO confirm confirmations and rateLimits
|
|
55
|
+
confirmations: 2,
|
|
56
|
+
rateLimits: {
|
|
57
|
+
blockWindow: 20_000_000_000n,
|
|
58
|
+
blockWindowSize: 10,
|
|
59
|
+
tx: 10_000_000_000n,
|
|
60
|
+
},
|
|
61
|
+
},
|
|
62
|
+
Polygon: {
|
|
63
|
+
attenuatedCttpBridgeAddresses: [
|
|
64
|
+
'0x32cb9574650AFF312c80edc4B4343Ff5500767cA',
|
|
65
|
+
],
|
|
66
|
+
cctpTokenMessengerAddress: '0x9daF8c91AEFAE50b9c0E69629D3F6Ca40cA3B3FE',
|
|
67
|
+
chainId: 137,
|
|
68
|
+
// TODO confirm confirmations and rateLimits
|
|
69
|
+
confirmations: 2,
|
|
70
|
+
rateLimits: {
|
|
71
|
+
blockWindow: 20_000_000_000n,
|
|
72
|
+
blockWindowSize: 10,
|
|
73
|
+
tx: 10_000_000_000n,
|
|
74
|
+
},
|
|
75
|
+
},
|
|
76
|
+
},
|
|
77
|
+
TESTNET: {
|
|
78
|
+
// Arbitrum Sepolia
|
|
79
|
+
Arbitrum: {
|
|
80
|
+
attenuatedCttpBridgeAddresses: ['0xTODO'],
|
|
81
|
+
cctpTokenMessengerAddress: '0x9f3B8679c73C2Fef8b59B4f3444d4e156fb70AA5',
|
|
82
|
+
chainId: 421614,
|
|
83
|
+
confirmations: 2,
|
|
84
|
+
rateLimits: {
|
|
85
|
+
blockWindow: 20_000_000_000n,
|
|
86
|
+
blockWindowSize: 10,
|
|
87
|
+
tx: 10_000_000_000n,
|
|
88
|
+
},
|
|
89
|
+
},
|
|
90
|
+
// Base Sepolia
|
|
91
|
+
Base: {
|
|
92
|
+
attenuatedCttpBridgeAddresses: ['0xTODO'],
|
|
93
|
+
cctpTokenMessengerAddress: '0x9f3B8679c73C2Fef8b59B4f3444d4e156fb70AA5',
|
|
94
|
+
chainId: 84532,
|
|
95
|
+
confirmations: 2,
|
|
96
|
+
rateLimits: {
|
|
97
|
+
blockWindow: 20_000_000_000n,
|
|
98
|
+
blockWindowSize: 10,
|
|
99
|
+
tx: 10_000_000_000n,
|
|
100
|
+
},
|
|
101
|
+
},
|
|
102
|
+
// Ethereum Sepolia
|
|
103
|
+
Ethereum: {
|
|
104
|
+
attenuatedCttpBridgeAddresses: ['0xTODO'],
|
|
105
|
+
cctpTokenMessengerAddress: '0x9f3B8679c73C2Fef8b59B4f3444d4e156fb70AA5',
|
|
106
|
+
chainId: 11155111,
|
|
107
|
+
confirmations: 2,
|
|
108
|
+
rateLimits: {
|
|
109
|
+
blockWindow: 20_000_000_000n,
|
|
110
|
+
blockWindowSize: 10,
|
|
111
|
+
tx: 10_000_000_000n,
|
|
112
|
+
},
|
|
113
|
+
},
|
|
114
|
+
// OP Sepolia
|
|
115
|
+
Optimism: {
|
|
116
|
+
attenuatedCttpBridgeAddresses: ['0xTODO'],
|
|
117
|
+
cctpTokenMessengerAddress: '0x9f3B8679c73C2Fef8b59B4f3444d4e156fb70AA5',
|
|
118
|
+
chainId: 11155420,
|
|
119
|
+
confirmations: 2,
|
|
120
|
+
rateLimits: {
|
|
121
|
+
blockWindow: 20_000_000_000n,
|
|
122
|
+
blockWindowSize: 10,
|
|
123
|
+
tx: 10_000_000_000n,
|
|
124
|
+
},
|
|
125
|
+
},
|
|
126
|
+
// Polygon PoS Amoy
|
|
127
|
+
Polygon: {
|
|
128
|
+
attenuatedCttpBridgeAddresses: ['0xTODO'],
|
|
129
|
+
cctpTokenMessengerAddress: '0x9f3B8679c73C2Fef8b59B4f3444d4e156fb70AA5',
|
|
130
|
+
chainId: 80002,
|
|
131
|
+
confirmations: 2,
|
|
132
|
+
rateLimits: {
|
|
133
|
+
blockWindow: 20_000_000_000n,
|
|
134
|
+
blockWindowSize: 10,
|
|
135
|
+
tx: 10_000_000_000n,
|
|
136
|
+
},
|
|
137
|
+
},
|
|
138
|
+
},
|
|
139
|
+
});
|
|
140
|
+
harden(ChainPolicies);
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { denomHash, withChainCapabilities } from '@agoric/orchestration';
|
|
2
2
|
import fetchedChainInfo from '@agoric/orchestration/src/fetched-chain-info.js';
|
|
3
|
+
import { ChainPolicies } from './chain-policies.js';
|
|
3
4
|
|
|
4
5
|
/**
|
|
5
6
|
* @import {FastUSDCConfig} from '@agoric/fast-usdc/src/types.js'
|
|
@@ -41,6 +42,10 @@ const agoricAssetInfo = defaultAssetInfo.filter(
|
|
|
41
42
|
([_d, i]) => i.chainName === 'agoric',
|
|
42
43
|
);
|
|
43
44
|
|
|
45
|
+
/** ABI for DepositForBurn event in TokenMessenger contract */
|
|
46
|
+
const DepositForBurnEvent =
|
|
47
|
+
'DepositForBurn(uint64,address,uint256,address,bytes32,uint32,bytes32,bytes32)';
|
|
48
|
+
|
|
44
49
|
/**
|
|
45
50
|
* @type {Record<string, Pick<FastUSDCConfig, 'oracles' | 'feedPolicy' | 'chainInfo' | 'assetInfo' >>}
|
|
46
51
|
*
|
|
@@ -62,16 +67,8 @@ export const configurations = {
|
|
|
62
67
|
feedPolicy: {
|
|
63
68
|
nobleAgoricChannelId: 'channel-does-not-exist',
|
|
64
69
|
nobleDomainId: 4,
|
|
65
|
-
chainPolicies:
|
|
66
|
-
|
|
67
|
-
attenuatedCttpBridgeAddress:
|
|
68
|
-
'0xe298b93ffB5eA1FB628e0C0D55A43aeaC268e347',
|
|
69
|
-
cctpTokenMessengerAddress:
|
|
70
|
-
'0x19330d10D9Cc8751218eaf51E8885D058642E08A',
|
|
71
|
-
chainId: 42161,
|
|
72
|
-
confirmations: 2,
|
|
73
|
-
},
|
|
74
|
-
},
|
|
70
|
+
chainPolicies: ChainPolicies.TESTNET,
|
|
71
|
+
eventFilter: DepositForBurnEvent,
|
|
75
72
|
},
|
|
76
73
|
chainInfo: /** @type {Record<string, CosmosChainInfo & Passable>} */ (
|
|
77
74
|
withChainCapabilities({
|
|
@@ -91,16 +88,8 @@ export const configurations = {
|
|
|
91
88
|
feedPolicy: {
|
|
92
89
|
nobleAgoricChannelId: 'channel-21',
|
|
93
90
|
nobleDomainId: 4,
|
|
94
|
-
chainPolicies:
|
|
95
|
-
|
|
96
|
-
attenuatedCttpBridgeAddress:
|
|
97
|
-
'0xe298b93ffB5eA1FB628e0C0D55A43aeaC268e347',
|
|
98
|
-
cctpTokenMessengerAddress:
|
|
99
|
-
'0x19330d10D9Cc8751218eaf51E8885D058642E08A',
|
|
100
|
-
chainId: 42161,
|
|
101
|
-
confirmations: 2,
|
|
102
|
-
},
|
|
103
|
-
},
|
|
91
|
+
chainPolicies: ChainPolicies.MAINNET,
|
|
92
|
+
eventFilter: DepositForBurnEvent,
|
|
104
93
|
},
|
|
105
94
|
chainInfo: /** @type {Record<string, CosmosChainInfo & Passable>} */ (
|
|
106
95
|
withChainCapabilities(fetchedChainInfo)
|
|
@@ -118,14 +107,8 @@ export const configurations = {
|
|
|
118
107
|
feedPolicy: {
|
|
119
108
|
nobleAgoricChannelId: 'TODO',
|
|
120
109
|
nobleDomainId: 4,
|
|
121
|
-
chainPolicies:
|
|
122
|
-
|
|
123
|
-
attenuatedCttpBridgeAddress: '0xTODO',
|
|
124
|
-
cctpTokenMessengerAddress: '0xTODO',
|
|
125
|
-
chainId: 421614,
|
|
126
|
-
confirmations: 2,
|
|
127
|
-
},
|
|
128
|
-
},
|
|
110
|
+
chainPolicies: ChainPolicies.TESTNET,
|
|
111
|
+
eventFilter: DepositForBurnEvent,
|
|
129
112
|
},
|
|
130
113
|
chainInfo: /** @type {Record<string, CosmosChainInfo & Passable>} */ (
|
|
131
114
|
withChainCapabilities(fetchedChainInfo) // TODO: use devnet values
|
|
@@ -140,14 +123,8 @@ export const configurations = {
|
|
|
140
123
|
feedPolicy: {
|
|
141
124
|
nobleAgoricChannelId: 'TODO',
|
|
142
125
|
nobleDomainId: 4,
|
|
143
|
-
chainPolicies:
|
|
144
|
-
|
|
145
|
-
attenuatedCttpBridgeAddress: '0xTODO',
|
|
146
|
-
cctpTokenMessengerAddress: '0xTODO',
|
|
147
|
-
chainId: 421614,
|
|
148
|
-
confirmations: 2,
|
|
149
|
-
},
|
|
150
|
-
},
|
|
126
|
+
chainPolicies: ChainPolicies.TESTNET,
|
|
127
|
+
eventFilter: DepositForBurnEvent,
|
|
151
128
|
},
|
|
152
129
|
chainInfo: /** @type {Record<string, CosmosChainInfo & Passable>} */ (
|
|
153
130
|
withChainCapabilities(fetchedChainInfo) // TODO: use emerynet values
|