@gearbox-protocol/sdk 17.10.1 → 17.12.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.
Files changed (95) hide show
  1. package/dist/cjs/offchain/AbstractOffchainNamespace.js +31 -8
  2. package/dist/cjs/permissionless/api/GearboxPermissionless.js +79 -0
  3. package/dist/cjs/permissionless/api/chains/ChainsNamespace.js +180 -0
  4. package/dist/cjs/permissionless/api/chains/index.js +4 -0
  5. package/dist/cjs/permissionless/api/chains/schemas.js +34 -0
  6. package/dist/cjs/permissionless/api/chains/types.js +1 -0
  7. package/dist/cjs/permissionless/api/deploy/PermissionlessDeploy.js +152 -0
  8. package/dist/cjs/permissionless/api/deploy/effective-staleness.js +46 -0
  9. package/dist/cjs/permissionless/api/deploy/index.js +8 -0
  10. package/dist/cjs/permissionless/api/deploy/types.js +1 -0
  11. package/dist/cjs/permissionless/api/errors.js +82 -0
  12. package/dist/cjs/permissionless/api/index.js +28 -0
  13. package/dist/cjs/permissionless/api/oracles/PermissionlessOracles.js +84 -0
  14. package/dist/cjs/permissionless/api/oracles/index.js +6 -0
  15. package/dist/cjs/permissionless/api/oracles/schemas.js +51 -0
  16. package/dist/cjs/permissionless/api/oracles/types.js +1 -0
  17. package/dist/cjs/permissionless/api/schemas.js +28 -0
  18. package/dist/cjs/permissionless/api/transactions/InstanceOwnerTransactions.js +234 -0
  19. package/dist/cjs/permissionless/api/transactions/index.js +4 -0
  20. package/dist/cjs/permissionless/api/transactions/lp-price-feeds.js +86 -0
  21. package/dist/cjs/permissionless/api/transactions/types.js +1 -0
  22. package/dist/cjs/permissionless/api/types.js +1 -0
  23. package/dist/cjs/permissionless/bindings/cross-chain-multisig.js +1 -1
  24. package/dist/cjs/permissionless/bindings/index.js +3 -3
  25. package/dist/cjs/permissionless/bindings/instance-manager.js +3 -3
  26. package/dist/cjs/permissionless/bindings/price-feed-store.js +0 -2
  27. package/dist/cjs/permissionless/index.js +31 -8
  28. package/dist/cjs/permissionless/utils/governance/timelock-txs.js +1 -1
  29. package/dist/cjs/permissionless/utils/index.js +4 -4
  30. package/dist/cjs/permissionless/utils/price-update/get-price-update-tx.js +1 -1
  31. package/dist/cjs/permissionless/utils/price-update/index.js +1 -1
  32. package/dist/esm/offchain/AbstractOffchainNamespace.js +31 -8
  33. package/dist/esm/permissionless/api/GearboxPermissionless.js +78 -0
  34. package/dist/esm/permissionless/api/chains/ChainsNamespace.js +179 -0
  35. package/dist/esm/permissionless/api/chains/index.js +3 -0
  36. package/dist/esm/permissionless/api/chains/schemas.js +30 -0
  37. package/dist/esm/permissionless/api/chains/types.js +1 -0
  38. package/dist/esm/permissionless/api/deploy/PermissionlessDeploy.js +149 -0
  39. package/dist/esm/permissionless/api/deploy/effective-staleness.js +46 -0
  40. package/dist/esm/permissionless/api/deploy/index.js +4 -0
  41. package/dist/esm/permissionless/api/deploy/types.js +1 -0
  42. package/dist/esm/permissionless/api/errors.js +77 -0
  43. package/dist/esm/permissionless/api/index.js +13 -0
  44. package/dist/esm/permissionless/api/oracles/PermissionlessOracles.js +81 -0
  45. package/dist/esm/permissionless/api/oracles/index.js +3 -0
  46. package/dist/esm/permissionless/api/oracles/schemas.js +47 -0
  47. package/dist/esm/permissionless/api/oracles/types.js +1 -0
  48. package/dist/esm/permissionless/api/schemas.js +25 -0
  49. package/dist/esm/permissionless/api/transactions/InstanceOwnerTransactions.js +233 -0
  50. package/dist/esm/permissionless/api/transactions/index.js +3 -0
  51. package/dist/esm/permissionless/api/transactions/lp-price-feeds.js +84 -0
  52. package/dist/esm/permissionless/api/transactions/types.js +1 -0
  53. package/dist/esm/permissionless/api/types.js +1 -0
  54. package/dist/esm/permissionless/bindings/cross-chain-multisig.js +1 -1
  55. package/dist/esm/permissionless/bindings/index.js +3 -3
  56. package/dist/esm/permissionless/bindings/instance-manager.js +3 -3
  57. package/dist/esm/permissionless/bindings/price-feed-store.js +0 -2
  58. package/dist/esm/permissionless/index.js +17 -9
  59. package/dist/esm/permissionless/utils/governance/timelock-txs.js +1 -1
  60. package/dist/esm/permissionless/utils/index.js +4 -4
  61. package/dist/esm/permissionless/utils/price-update/get-price-update-tx.js +1 -1
  62. package/dist/esm/permissionless/utils/price-update/index.js +1 -1
  63. package/dist/types/offchain/AbstractOffchainNamespace.d.ts +12 -0
  64. package/dist/types/permissionless/api/GearboxPermissionless.d.ts +71 -0
  65. package/dist/types/permissionless/api/chains/ChainsNamespace.d.ts +99 -0
  66. package/dist/types/permissionless/api/chains/index.d.ts +3 -0
  67. package/dist/types/permissionless/api/chains/schemas.d.ts +49 -0
  68. package/dist/types/permissionless/api/chains/types.d.ts +58 -0
  69. package/dist/types/permissionless/api/deploy/PermissionlessDeploy.d.ts +69 -0
  70. package/dist/types/permissionless/api/deploy/effective-staleness.d.ts +19 -0
  71. package/dist/types/permissionless/api/deploy/index.d.ts +4 -0
  72. package/dist/types/permissionless/api/deploy/types.d.ts +87 -0
  73. package/dist/types/permissionless/api/errors.d.ts +63 -0
  74. package/dist/types/permissionless/api/index.d.ts +17 -0
  75. package/dist/types/permissionless/api/oracles/PermissionlessOracles.d.ts +64 -0
  76. package/dist/types/permissionless/api/oracles/index.d.ts +3 -0
  77. package/dist/types/permissionless/api/oracles/schemas.d.ts +74 -0
  78. package/dist/types/permissionless/api/oracles/types.d.ts +51 -0
  79. package/dist/types/permissionless/api/schemas.d.ts +22 -0
  80. package/dist/types/permissionless/api/transactions/InstanceOwnerTransactions.d.ts +68 -0
  81. package/dist/types/permissionless/api/transactions/index.d.ts +3 -0
  82. package/dist/types/permissionless/api/transactions/lp-price-feeds.d.ts +17 -0
  83. package/dist/types/permissionless/api/transactions/types.d.ts +58 -0
  84. package/dist/types/permissionless/api/types.d.ts +12 -0
  85. package/dist/types/permissionless/bindings/factory/credit-factory.d.ts +1 -1
  86. package/dist/types/permissionless/bindings/factory/loss-policy-factory.d.ts +1 -1
  87. package/dist/types/permissionless/bindings/factory/pool-factory.d.ts +1 -1
  88. package/dist/types/permissionless/bindings/factory/price-oracle-factory.d.ts +1 -1
  89. package/dist/types/permissionless/bindings/index.d.ts +1 -1
  90. package/dist/types/permissionless/core/index.d.ts +1 -1
  91. package/dist/types/permissionless/core/pricefeed.d.ts +0 -1
  92. package/dist/types/permissionless/index.d.ts +23 -10
  93. package/dist/types/permissionless/utils/governance/index.d.ts +1 -1
  94. package/dist/types/permissionless/utils/index.d.ts +1 -1
  95. package/package.json +1 -1
@@ -1,16 +1,28 @@
1
1
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
- const require_permissionless_bindings_address_provider = require("./bindings/address-provider.js");
2
+ const require_permissionless_api_errors = require("./api/errors.js");
3
+ const require_permissionless_api_chains_ChainsNamespace = require("./api/chains/ChainsNamespace.js");
4
+ const require_permissionless_api_deploy_effective_staleness = require("./api/deploy/effective-staleness.js");
3
5
  const require_permissionless_utils_literals = require("./utils/literals.js");
4
6
  const require_permissionless_utils_signature = require("./utils/signature.js");
5
7
  const require_permissionless_bindings_bytecode_repository = require("./bindings/bytecode-repository.js");
6
- const require_permissionless_bindings_compressors_token_compressor = require("./bindings/compressors/token-compressor.js");
7
- const require_permissionless_bindings_compressors_withdrawal_compressor = require("./bindings/compressors/withdrawal-compressor.js");
8
- const require_permissionless_deployment_addresses = require("./deployment/addresses.js");
9
8
  const require_permissionless_bindings_pricefeeds_index = require("./bindings/pricefeeds/index.js");
10
9
  const require_permissionless_bindings_price_feed_store = require("./bindings/price-feed-store.js");
10
+ const require_permissionless_deployment_addresses = require("./deployment/addresses.js");
11
+ const require_permissionless_utils_abi_encoder = require("./utils/abi-encoder.js");
12
+ const require_permissionless_api_deploy_PermissionlessDeploy = require("./api/deploy/PermissionlessDeploy.js");
13
+ const require_permissionless_utils_price_update_get_prices = require("./utils/price-update/get-prices.js");
14
+ const require_permissionless_api_oracles_PermissionlessOracles = require("./api/oracles/PermissionlessOracles.js");
15
+ const require_permissionless_bindings_address_provider = require("./bindings/address-provider.js");
16
+ const require_permissionless_bindings_compressors_token_compressor = require("./bindings/compressors/token-compressor.js");
17
+ const require_permissionless_bindings_compressors_withdrawal_compressor = require("./bindings/compressors/withdrawal-compressor.js");
11
18
  const require_permissionless_bindings_router_routing_manager = require("./bindings/router/routing-manager.js");
12
19
  const require_permissionless_bindings_treasury_splitter = require("./bindings/treasury-splitter.js");
13
20
  const require_permissionless_bindings_instance_manager = require("./bindings/instance-manager.js");
21
+ const require_permissionless_utils_governance_batch = require("./utils/governance/batch.js");
22
+ const require_permissionless_utils_price_update_get_updatable_feeds = require("./utils/price-update/get-updatable-feeds.js");
23
+ const require_permissionless_api_transactions_InstanceOwnerTransactions = require("./api/transactions/InstanceOwnerTransactions.js");
24
+ const require_permissionless_api_GearboxPermissionless = require("./api/GearboxPermissionless.js");
25
+ require("./api/index.js");
14
26
  const require_permissionless_bindings_market_configurator_factory = require("./bindings/market-configurator-factory.js");
15
27
  const require_permissionless_bindings_cross_chain_multisig = require("./bindings/cross-chain-multisig.js");
16
28
  const require_permissionless_utils_create2 = require("./utils/create2.js");
@@ -25,13 +37,9 @@ const require_permissionless_chains_archive_transport = require("./chains/archiv
25
37
  const require_permissionless_chains_chunked_log_transport = require("./chains/chunked-log-transport.js");
26
38
  require("./core/index.js");
27
39
  const require_permissionless_deployment_mainnet = require("./deployment/mainnet.js");
28
- const require_permissionless_utils_abi_encoder = require("./utils/abi-encoder.js");
29
40
  const require_permissionless_utils_block_utils = require("./utils/block-utils.js");
30
- const require_permissionless_utils_governance_batch = require("./utils/governance/batch.js");
31
41
  const require_permissionless_utils_governance_timelock_txs = require("./utils/governance/timelock-txs.js");
32
42
  const require_permissionless_utils_price_update_get_price_update_tx = require("./utils/price-update/get-price-update-tx.js");
33
- const require_permissionless_utils_price_update_get_prices = require("./utils/price-update/get-prices.js");
34
- const require_permissionless_utils_price_update_get_updatable_feeds = require("./utils/price-update/get-updatable-feeds.js");
35
43
  require("./utils/index.js");
36
44
  exports.AccessMode = require_permissionless_bindings_types.AccessMode;
37
45
  exports.AddressProviderContract = require_permissionless_bindings_address_provider.AddressProviderContract;
@@ -41,10 +49,16 @@ exports.BYTECODE_REPOSITORY = require_permissionless_utils_literals.BYTECODE_REP
41
49
  exports.BytecodeRepositoryContract = require_permissionless_bindings_bytecode_repository.BytecodeRepositoryContract;
42
50
  exports.CROSS_CHAIN_GOVERNANCE = require_permissionless_utils_literals.CROSS_CHAIN_GOVERNANCE;
43
51
  exports.CROSS_CHAIN_MULTISIG = require_permissionless_utils_literals.CROSS_CHAIN_MULTISIG;
52
+ exports.ChainsNamespace = require_permissionless_api_chains_ChainsNamespace.ChainsNamespace;
44
53
  exports.CrossChainMultisigContract = require_permissionless_bindings_cross_chain_multisig.CrossChainMultisigContract;
54
+ exports.DEFAULT_DEPLOY_SALT = require_permissionless_api_deploy_PermissionlessDeploy.DEFAULT_DEPLOY_SALT;
55
+ exports.GET_PRICES_CHUNK_SIZE = require_permissionless_api_oracles_PermissionlessOracles.GET_PRICES_CHUNK_SIZE;
56
+ exports.GET_PRICES_GAS_LIMIT_BY_CHAIN_ID = require_permissionless_api_oracles_PermissionlessOracles.GET_PRICES_GAS_LIMIT_BY_CHAIN_ID;
57
+ exports.GearboxPermissionless = require_permissionless_api_GearboxPermissionless.GearboxPermissionless;
45
58
  exports.GovernorContract = require_permissionless_bindings_governance_governor.GovernorContract;
46
59
  exports.INSTANCE_MANAGER = require_permissionless_utils_literals.INSTANCE_MANAGER;
47
60
  exports.InstanceManagerContract = require_permissionless_bindings_instance_manager.InstanceManagerContract;
61
+ exports.InstanceOwnerTransactions = require_permissionless_api_transactions_InstanceOwnerTransactions.InstanceOwnerTransactions;
48
62
  exports.MAINNET_CCM_CONSTRUCTOR_PARAMS = require_permissionless_deployment_mainnet.MAINNET_CCM_CONSTRUCTOR_PARAMS;
49
63
  exports.MAINNET_DEPLOYMENT_BLOCK = require_permissionless_deployment_mainnet.MAINNET_DEPLOYMENT_BLOCK;
50
64
  exports.MAINNET_DEPLOYMENT_CCM_SALT = require_permissionless_deployment_mainnet.MAINNET_DEPLOYMENT_CCM_SALT;
@@ -54,6 +68,13 @@ exports.MarketConfiguratorContract = require_permissionless_bindings_market_conf
54
68
  exports.MarketConfiguratorFactoryContract = require_permissionless_bindings_market_configurator_factory.MarketConfiguratorFactoryContract;
55
69
  exports.PRICE_FEED_STORE = require_permissionless_utils_literals.PRICE_FEED_STORE;
56
70
  exports.PUBLIC_CREATE2_FACTORY = require_permissionless_utils_create2.PUBLIC_CREATE2_FACTORY;
71
+ exports.PermissionlessChainUnreachableError = require_permissionless_api_errors.PermissionlessChainUnreachableError;
72
+ exports.PermissionlessDeploy = require_permissionless_api_deploy_PermissionlessDeploy.PermissionlessDeploy;
73
+ exports.PermissionlessNotAttachedError = require_permissionless_api_errors.PermissionlessNotAttachedError;
74
+ exports.PermissionlessOracles = require_permissionless_api_oracles_PermissionlessOracles.PermissionlessOracles;
75
+ exports.PriceFeedNotInStoreError = require_permissionless_api_errors.PriceFeedNotInStoreError;
76
+ exports.PriceFeedSaltMissingError = require_permissionless_api_errors.PriceFeedSaltMissingError;
77
+ exports.PriceFeedStalenessUnknownError = require_permissionless_api_errors.PriceFeedStalenessUnknownError;
57
78
  exports.PriceFeedStoreContract = require_permissionless_bindings_price_feed_store.PriceFeedStoreContract;
58
79
  exports.RoutingManagerContract = require_permissionless_bindings_router_routing_manager.RoutingManagerContract;
59
80
  exports.TOKEN_COMPRESSOR = require_permissionless_utils_literals.TOKEN_COMPRESSOR;
@@ -72,6 +93,7 @@ exports.createCallData = require_permissionless_core_raw_tx.createCallData;
72
93
  exports.createCreate2DeployRawTx = require_permissionless_utils_create2.createCreate2DeployRawTx;
73
94
  exports.deepJsonParse = require_permissionless_utils_format.deepJsonParse;
74
95
  exports.deployUsingPublicCreate2 = require_permissionless_utils_create2.deployUsingPublicCreate2;
96
+ exports.deriveEffectiveStalenessPeriod = require_permissionless_api_deploy_effective_staleness.deriveEffectiveStalenessPeriod;
75
97
  exports.encodeFunctionParams = require_permissionless_utils_abi_encoder.encodeFunctionParams;
76
98
  exports.formatBytecodeSize = require_permissionless_utils_format.formatBytecodeSize;
77
99
  exports.formatBytecodeVersion = require_permissionless_utils_format.formatBytecodeVersion;
@@ -85,6 +107,7 @@ exports.getSafeBatches = require_permissionless_utils_governance_batch.getSafeBa
85
107
  exports.getUpdatablePriceFeeds = require_permissionless_utils_price_update_get_updatable_feeds.getUpdatablePriceFeeds;
86
108
  exports.handleSalt = require_permissionless_utils_create2.handleSalt;
87
109
  exports.normalizeSignature = require_permissionless_utils_signature.normalizeSignature;
110
+ exports.priceFeedSalt = require_permissionless_api_deploy_PermissionlessDeploy.priceFeedSalt;
88
111
  exports.priceFeedSetupParams = require_permissionless_bindings_pricefeeds_index.priceFeedSetupParams;
89
112
  exports.shortenHash = require_permissionless_utils_format.shortenHash;
90
113
  exports.significantTrunc = require_permissionless_utils_format.significantTrunc;
@@ -1,8 +1,8 @@
1
1
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
2
  const require_onchain_utils_createRawTx = require("../../../onchain/utils/createRawTx.js");
3
3
  require("../../../onchain/index.js");
4
- const require_abi_governance_governor = require("../../../abi/governance/governor.js");
5
4
  const require_permissionless_utils_governance_batch = require("./batch.js");
5
+ const require_abi_governance_governor = require("../../../abi/governance/governor.js");
6
6
  //#region src/permissionless/utils/governance/timelock-txs.ts
7
7
  function convertQueueBatchToExecuteTx(queueBatch) {
8
8
  const executionBatch = queueBatch.filter((tx) => tx.contractMethod.name === "queueTransaction").map((tx) => ({
@@ -1,16 +1,16 @@
1
1
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
2
  const require_permissionless_utils_literals = require("./literals.js");
3
3
  const require_permissionless_utils_signature = require("./signature.js");
4
+ const require_permissionless_utils_abi_encoder = require("./abi-encoder.js");
5
+ const require_permissionless_utils_price_update_get_prices = require("./price-update/get-prices.js");
6
+ const require_permissionless_utils_governance_batch = require("./governance/batch.js");
7
+ const require_permissionless_utils_price_update_get_updatable_feeds = require("./price-update/get-updatable-feeds.js");
4
8
  const require_permissionless_utils_create2 = require("./create2.js");
5
9
  const require_permissionless_utils_format = require("./format.js");
6
- const require_permissionless_utils_abi_encoder = require("./abi-encoder.js");
7
10
  const require_permissionless_utils_block_utils = require("./block-utils.js");
8
- const require_permissionless_utils_governance_batch = require("./governance/batch.js");
9
11
  const require_permissionless_utils_governance_timelock_txs = require("./governance/timelock-txs.js");
10
12
  require("./governance/index.js");
11
13
  const require_permissionless_utils_price_update_get_price_update_tx = require("./price-update/get-price-update-tx.js");
12
- const require_permissionless_utils_price_update_get_prices = require("./price-update/get-prices.js");
13
- const require_permissionless_utils_price_update_get_updatable_feeds = require("./price-update/get-updatable-feeds.js");
14
14
  require("./price-update/index.js");
15
15
  exports.BYTECODE_REPOSITORY = require_permissionless_utils_literals.BYTECODE_REPOSITORY;
16
16
  exports.CROSS_CHAIN_GOVERNANCE = require_permissionless_utils_literals.CROSS_CHAIN_GOVERNANCE;
@@ -3,8 +3,8 @@ const require_onchain_utils_createRawTx = require("../../../onchain/utils/create
3
3
  const require_onchain_market_pricefeeds_updates_getRawPriceUpdates = require("../../../onchain/market/pricefeeds/updates/getRawPriceUpdates.js");
4
4
  const require_onchain_OnchainSDK = require("../../../onchain/OnchainSDK.js");
5
5
  require("../../../onchain/index.js");
6
- require("../../deployment/addresses.js");
7
6
  const require_permissionless_bindings_price_feed_store = require("../../bindings/price-feed-store.js");
7
+ require("../../deployment/addresses.js");
8
8
  require("../../bindings/index.js");
9
9
  let viem = require("viem");
10
10
  //#region src/permissionless/utils/price-update/get-price-update-tx.ts
@@ -1,7 +1,7 @@
1
1
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
- const require_permissionless_utils_price_update_get_price_update_tx = require("./get-price-update-tx.js");
3
2
  const require_permissionless_utils_price_update_get_prices = require("./get-prices.js");
4
3
  const require_permissionless_utils_price_update_get_updatable_feeds = require("./get-updatable-feeds.js");
4
+ const require_permissionless_utils_price_update_get_price_update_tx = require("./get-price-update-tx.js");
5
5
  exports.getPriceUpdateTx = require_permissionless_utils_price_update_get_price_update_tx.getPriceUpdateTx;
6
6
  exports.getPrices = require_permissionless_utils_price_update_get_prices.getPrices;
7
7
  exports.getUpdatablePriceFeeds = require_permissionless_utils_price_update_get_updatable_feeds.getUpdatablePriceFeeds;
@@ -47,14 +47,7 @@ var AbstractOffchainNamespace = class {
47
47
  **/
48
48
  async get(request) {
49
49
  const url = this.#url(request.path, request.query);
50
- const payload = await this.#fetchJson(url);
51
- const parsed = responseSchema(request.schema).safeParse(payload);
52
- if (!parsed.success) {
53
- const error = new OffchainValidationError(url, parsed.error);
54
- this.logger?.error(error, "offchain response does not match the read model");
55
- throw error;
56
- }
57
- const { data, meta } = parsed.data;
50
+ const { data, meta } = await this.#read(url, responseSchema(request.schema));
58
51
  return {
59
52
  data,
60
53
  meta: { chains: meta.chains.map((chain) => ({
@@ -64,6 +57,36 @@ var AbstractOffchainNamespace = class {
64
57
  };
65
58
  }
66
59
  /**
60
+ * Reads one endpoint that answers with the payload alone, and returns it
61
+ * unwrapped.
62
+ *
63
+ * A read served at no particular block has no envelope to report: the
64
+ * permissionless routes either span every chain at once, or fall through to
65
+ * a multicall on the chain itself, so the backend answers `{ data }` and
66
+ * there is no {@link ResponseMetadata} for {@link get} to decode. The
67
+ * envelope is still there, which is what keeps a payload that happens to be
68
+ * an array from being mistaken for an error body.
69
+ **/
70
+ async getData(request) {
71
+ const url = this.#url(request.path, request.query);
72
+ const { data } = await this.#read(url, z.object({ data: request.schema }));
73
+ return data;
74
+ }
75
+ /**
76
+ * Body of a successful read, decoded. Schema skew is reported against the
77
+ * url that produced it, which is the only thing that says which read drifted.
78
+ **/
79
+ async #read(url, schema) {
80
+ const payload = await this.#fetchJson(url);
81
+ const parsed = schema.safeParse(payload);
82
+ if (!parsed.success) {
83
+ const error = new OffchainValidationError(url, parsed.error);
84
+ this.logger?.error(error, "offchain response does not match the read model");
85
+ throw error;
86
+ }
87
+ return parsed.data;
88
+ }
89
+ /**
67
90
  * Reads the charts of one subject: one series per metric named, onto the one
68
91
  * grid that lets them be compared at an index.
69
92
  **/
@@ -0,0 +1,78 @@
1
+ import { ChainsNamespace } from "./chains/ChainsNamespace.js";
2
+ import { PermissionlessDeploy } from "./deploy/PermissionlessDeploy.js";
3
+ import { PermissionlessOracles } from "./oracles/PermissionlessOracles.js";
4
+ import { InstanceOwnerTransactions } from "./transactions/InstanceOwnerTransactions.js";
5
+ //#region src/permissionless/api/GearboxPermissionless.ts
6
+ /**
7
+ * Client for the permissionless stack: the oracle rows of a chain, the
8
+ * batches an instance owner executes, and the deploys that produce what goes
9
+ * into both.
10
+ *
11
+ * It reads the same backend {@link GearboxAPI} does, and reads the same way —
12
+ * one namespace per subject, every call scoped by the chain it names. Which
13
+ * chains those are is not passed in: {@link attach} reads the list off the
14
+ * backend and builds a client for each, so this client covers exactly what
15
+ * the backend serves.
16
+ *
17
+ * ```ts
18
+ * const permissionless = new GearboxPermissionless({
19
+ * baseUrl: "https://api.gearbox.fi",
20
+ * });
21
+ * await permissionless.attach();
22
+ *
23
+ * const [chain] = permissionless.chains.list();
24
+ * const store = await permissionless.oracles.store({ chainId: chain.chainId });
25
+ * ```
26
+ *
27
+ * Only what needs a server goes to one. {@link chains} and {@link oracles}
28
+ * are the backend's reads; {@link deploy} and {@link transactions} read the
29
+ * target chain directly, because everything they answer is derived from there
30
+ * and a round trip would only move the derivation further from the wallet
31
+ * that has to sign for it.
32
+ **/
33
+ var GearboxPermissionless = class {
34
+ /**
35
+ * Namespace for the chains the stack runs on, and the viem clients that
36
+ * reach them.
37
+ **/
38
+ chains;
39
+ /**
40
+ * Namespace for price feeds: the store and its prices.
41
+ **/
42
+ oracles;
43
+ /**
44
+ * Namespace for the Safe batches an instance owner executes. Backend-free,
45
+ * see {@link InstanceOwnerTransactions}.
46
+ **/
47
+ transactions;
48
+ /**
49
+ * Namespace for deploys through the BytecodeRepository. Backend-free, see
50
+ * {@link PermissionlessDeploy}.
51
+ **/
52
+ deploy;
53
+ constructor(options = {}) {
54
+ this.chains = new ChainsNamespace(options);
55
+ this.oracles = new PermissionlessOracles(options, this.chains);
56
+ this.transactions = new InstanceOwnerTransactions(this.chains, this.oracles);
57
+ this.deploy = new PermissionlessDeploy(this.chains);
58
+ }
59
+ /**
60
+ * Loads the chain list and builds the clients, see
61
+ * {@link ChainsNamespace.attach}. Idempotent, and joins a call already in
62
+ * flight.
63
+ *
64
+ * Everything that reads a chain goes through it, so this has to finish
65
+ * before the first such call.
66
+ **/
67
+ async attach(args = {}) {
68
+ return this.chains.attach(args);
69
+ }
70
+ /**
71
+ * Whether {@link attach} has completed.
72
+ **/
73
+ get isAttached() {
74
+ return this.chains.isAttached;
75
+ }
76
+ };
77
+ //#endregion
78
+ export { GearboxPermissionless };
@@ -0,0 +1,179 @@
1
+ import { getChain } from "../../../onchain/chain/chains.js";
2
+ import { AbstractOffchainNamespace } from "../../../offchain/AbstractOffchainNamespace.js";
3
+ import { PermissionlessChainUnreachableError, PermissionlessNotAttachedError } from "../errors.js";
4
+ import { chainListSchema, chainSummaryListSchema } from "./schemas.js";
5
+ import { createPublicClient, fallback, http } from "viem";
6
+ //#region src/permissionless/api/chains/ChainsNamespace.ts
7
+ /**
8
+ * The chains the permissionless stack runs on, and the viem clients that
9
+ * reach them.
10
+ *
11
+ * Both halves live here because they answer the same question. Which chains
12
+ * exist is the backend's to decide — it holds rows for chains it does not
13
+ * serve, and those must not be reachable — so the list is also the only
14
+ * honest basis for deciding which clients to build. Nothing is passed in: a
15
+ * caller that had to name the chains could name one the backend does not
16
+ * serve, or miss one it does.
17
+ *
18
+ * The list is fetched once, by {@link attach}, and kept for the client's
19
+ * lifetime:
20
+ *
21
+ * ```ts
22
+ * await permissionless.attach();
23
+ * const chains = permissionless.chains.list();
24
+ * ```
25
+ *
26
+ * Every read before that throws {@link PermissionlessNotAttachedError} rather
27
+ * than answering with an empty list, which would be indistinguishable from a
28
+ * backend that serves nothing.
29
+ *
30
+ * What {@link attach} reads is only what identifies a chain. The counters a
31
+ * list renders next to one are {@link summary}, a second read, because they
32
+ * aggregate over every market the backend knows and nothing should wait on
33
+ * that to start.
34
+ **/
35
+ var ChainsNamespace = class extends AbstractOffchainNamespace {
36
+ #clients = /* @__PURE__ */ new Map();
37
+ #chains;
38
+ #attaching;
39
+ /** The scope {@link attach} settled on, which {@link summary} follows. */
40
+ #scope;
41
+ constructor(options) {
42
+ super("ChainsNamespace", {
43
+ ...options,
44
+ chainIds: []
45
+ });
46
+ }
47
+ /**
48
+ * Reads the chain list off the backend and builds a client for each chain
49
+ * it names.
50
+ *
51
+ * Idempotent, and joins a call already in flight, so a double invocation —
52
+ * React's StrictMode, two components mounting at once — costs one request.
53
+ * A second call with a different `scope` is a no-op: the list is decided
54
+ * once.
55
+ **/
56
+ async attach({ scope } = {}) {
57
+ if (this.#chains) return;
58
+ this.#attaching ??= this.#load(scope).finally(() => {
59
+ this.#attaching = void 0;
60
+ });
61
+ return this.#attaching;
62
+ }
63
+ /**
64
+ * Whether {@link attach} has completed.
65
+ **/
66
+ get isAttached() {
67
+ return this.#chains !== void 0;
68
+ }
69
+ /**
70
+ * Every chain the backend serves, in the order it listed them.
71
+ **/
72
+ list() {
73
+ if (!this.#chains) throw new PermissionlessNotAttachedError();
74
+ return this.#chains;
75
+ }
76
+ /**
77
+ * One chain by id, or nothing when the backend does not serve it.
78
+ *
79
+ * Reads the attached list rather than a route of its own, which is also
80
+ * what makes "not served" and "not activated" distinguishable: the first is
81
+ * absence here, the second is {@link PermissionlessChain.isActivated}.
82
+ **/
83
+ find(chainId) {
84
+ return this.list().find((chain) => chain.chainId === chainId);
85
+ }
86
+ /**
87
+ * The same chains, with the counters a list renders next to them.
88
+ *
89
+ * A read of its own, and not part of {@link attach}: the counters aggregate
90
+ * over every market configurator and market the backend knows, which is
91
+ * slow enough that waiting on it would hold up the whole client. A list
92
+ * renders off {@link list} and fills the numbers in when this resolves.
93
+ *
94
+ * Nothing is cached — each call is a request — so a caller that renders
95
+ * this should hold it in whatever already owns its async state.
96
+ *
97
+ * Covers the scope {@link attach} settled on unless one is named here, so
98
+ * the counters describe the list that is already on screen rather than a
99
+ * different set of chains.
100
+ *
101
+ * ```ts
102
+ * await permissionless.attach();
103
+ * const chains = permissionless.chains.list();
104
+ * const withCounters = await permissionless.chains.summary();
105
+ * ```
106
+ **/
107
+ async summary({ scope } = {}) {
108
+ return this.getData({
109
+ path: "/chain/summary",
110
+ query: { scope: scope ?? this.#scope },
111
+ schema: chainSummaryListSchema
112
+ });
113
+ }
114
+ /**
115
+ * Chains a client could be built for. A subset of {@link list} — see
116
+ * {@link client}.
117
+ **/
118
+ get chainIds() {
119
+ if (!this.#chains) throw new PermissionlessNotAttachedError();
120
+ return [...this.#clients.keys()];
121
+ }
122
+ /**
123
+ * The client for one chain.
124
+ *
125
+ * @throws {@link PermissionlessChainUnreachableError} when the backend does
126
+ * not serve the chain, or serves one this SDK carries no definition for.
127
+ **/
128
+ client(chainId) {
129
+ if (!this.#chains) throw new PermissionlessNotAttachedError();
130
+ const client = this.#clients.get(chainId);
131
+ if (!client) throw new PermissionlessChainUnreachableError(chainId);
132
+ return client;
133
+ }
134
+ async #load(scope) {
135
+ const chains = await this.getData({
136
+ path: "/chain/list",
137
+ query: { scope },
138
+ schema: chainListSchema
139
+ });
140
+ this.#scope = scope;
141
+ this.#clients.clear();
142
+ for (const { chainId } of chains) {
143
+ const client = this.#client(chainId);
144
+ if (client) this.#clients.set(chainId, client);
145
+ }
146
+ this.#chains = chains;
147
+ }
148
+ /**
149
+ * A client over the chain's own public endpoints, or nothing when this SDK
150
+ * has no definition for it.
151
+ *
152
+ * The backend will not hand over its endpoints — they carry provider keys —
153
+ * so the chain definition is all there is to go on. A chain the SDK does
154
+ * not know stays in {@link list}, because the backend serves it and its
155
+ * rows are readable through the backend; only the calls that have to reach
156
+ * it directly fail, and they say which chain they could not reach.
157
+ **/
158
+ #client(chainId) {
159
+ let chain;
160
+ try {
161
+ chain = getChain(chainId);
162
+ } catch {
163
+ this.logger?.warn(`no chain definition for ${chainId}: it will be listed, but nothing can be read off it directly`);
164
+ return;
165
+ }
166
+ const urls = chain.rpcUrls.default.http;
167
+ if (urls.length === 0) {
168
+ this.logger?.warn(`no public endpoint for chain ${chainId}`);
169
+ return;
170
+ }
171
+ const transports = urls.map((url) => http(url));
172
+ return createPublicClient({
173
+ chain,
174
+ transport: transports.length > 1 ? fallback(transports) : transports[0]
175
+ });
176
+ }
177
+ };
178
+ //#endregion
179
+ export { ChainsNamespace };
@@ -0,0 +1,3 @@
1
+ import { ChainsNamespace } from "./ChainsNamespace.js";
2
+ import "./types.js";
3
+ export { ChainsNamespace };
@@ -0,0 +1,30 @@
1
+ import { z } from "zod/v4";
2
+ //#region src/permissionless/api/chains/schemas.ts
3
+ /**
4
+ * Runtime schema for {@link PermissionlessChain}.
5
+ **/
6
+ const chainSchema = z.looseObject({
7
+ chainId: z.number(),
8
+ name: z.string(),
9
+ isPublic: z.boolean(),
10
+ isActivated: z.boolean(),
11
+ explorerUrl: z.string()
12
+ });
13
+ /** What `GET /chain/list` answers with. */
14
+ const chainListSchema = z.array(chainSchema);
15
+ /**
16
+ * Runtime schema for {@link PermissionlessChainSummary}.
17
+ *
18
+ * Strict about the two counters on purpose: they are the only reason this
19
+ * read exists, and a backend that answered without them would render as
20
+ * dashes where the numbers belong — a skew worth failing on rather than
21
+ * displaying.
22
+ **/
23
+ const chainSummarySchema = chainSchema.extend({
24
+ riskCuratorsQty: z.number(),
25
+ marketsQty: z.number()
26
+ });
27
+ /** What `GET /chain/summary` answers with. */
28
+ const chainSummaryListSchema = z.array(chainSummarySchema);
29
+ //#endregion
30
+ export { chainListSchema, chainSchema, chainSummaryListSchema, chainSummarySchema };
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,149 @@
1
+ import { PriceFeedSaltMissingError, PriceFeedStalenessUnknownError } from "../errors.js";
2
+ import { deriveEffectiveStalenessPeriod } from "./effective-staleness.js";
3
+ import { BytecodeRepositoryContract } from "../../bindings/bytecode-repository.js";
4
+ import { PriceFeedStoreContract } from "../../bindings/price-feed-store.js";
5
+ import "../../deployment/addresses.js";
6
+ import { encodeFunctionParams } from "../../utils/abi-encoder.js";
7
+ import { keccak256, stringToHex, toHex } from "viem";
8
+ //#region src/permissionless/api/deploy/PermissionlessDeploy.ts
9
+ /**
10
+ * Contract type whose first leg needs a bound this client reads off the chain,
11
+ * see {@link PermissionlessDeploy.priceFeed}.
12
+ **/
13
+ const COMPOSITE = "PRICE_FEED::COMPOSITE";
14
+ /** Label the composite's first leg arrives under. */
15
+ const COMPOSITE_FIRST_LEG = "underlyingPriceFeed-0";
16
+ /**
17
+ * Salt a generic contract deploy gets when the caller does not name one. Two
18
+ * deploys of the same type and arguments by the same owner collide under it,
19
+ * which for a singleton like a pause committee is the point.
20
+ **/
21
+ const DEFAULT_DEPLOY_SALT = stringToHex("SALT", { size: 32 });
22
+ /**
23
+ * The salt a price feed is deployed under, derived from its name so that two
24
+ * feeds of the same type and arguments get different addresses.
25
+ **/
26
+ function priceFeedSalt(name) {
27
+ return keccak256(toHex(name));
28
+ }
29
+ /**
30
+ * Deploys through the BytecodeRepository: the constructor arguments it wants,
31
+ * the CREATE2 address those produce, and the transaction that gets there.
32
+ *
33
+ * Entirely on-chain — no backend is involved, every answer is derived from the
34
+ * target chain. Nothing is sent either: a browser holds the only wallet, so a
35
+ * call prepares the deploy and the caller sends
36
+ * {@link PreparedDeployment.tx} with whatever signs for them.
37
+ *
38
+ * ```ts
39
+ * const feed = await permissionless.deploy.priceFeed({
40
+ * chainId: 1,
41
+ * owner: account,
42
+ * contractType: "PRICE_FEED::CHAINLINK",
43
+ * version: 310,
44
+ * name: "WETH / USD",
45
+ * values,
46
+ * });
47
+ * if (!feed.isAlreadyDeployed) {
48
+ * await sendRawTx(wallet, { tx: feed.tx });
49
+ * }
50
+ * ```
51
+ **/
52
+ var PermissionlessDeploy = class {
53
+ #chains;
54
+ constructor(chains) {
55
+ this.#chains = chains;
56
+ }
57
+ /**
58
+ * Prepares a price feed deploy from the values a form collected: encodes
59
+ * them the way the PriceFeedStore reads them back, and reports where the
60
+ * feed will land.
61
+ *
62
+ * A COMPOSITE's first leg is the one case where the values are not taken as
63
+ * given. It arrives with `stalenessPeriod` 0 whenever it is a derived feed,
64
+ * because the store registers those with 0 and rejects anything else — which
65
+ * says nothing about what the leg itself enforces. A composite built on that
66
+ * 0 can never pass its own staleness check, so the real bound is read off
67
+ * the leg, see {@link deriveEffectiveStalenessPeriod}.
68
+ *
69
+ * The deployed feed reaches {@link PermissionlessOracles.store} only once
70
+ * it is in the PriceFeedStore, which is a batch the instance owner
71
+ * executes, see {@link InstanceOwnerTransactions.addFeeds}.
72
+ **/
73
+ async priceFeed(args) {
74
+ const client = this.#chains.client(args.chainId);
75
+ const salt = this.#priceFeedSalt(args);
76
+ const values = args.contractType === COMPOSITE ? await this.#withDerivedStaleness(client, args.values) : args.values;
77
+ const encodedParams = await new PriceFeedStoreContract("0x74A868AC479EE145029bB80827BB77F7B7c441cB", client).encodeConstructorParams(args.contractType, args.version, values);
78
+ return {
79
+ ...await this.#prepare(client, {
80
+ contractType: args.contractType,
81
+ version: args.version,
82
+ owner: args.owner,
83
+ encodedParams,
84
+ salt
85
+ }),
86
+ values
87
+ };
88
+ }
89
+ /**
90
+ * Prepares a generic contract deploy from ABI type/value pairs.
91
+ *
92
+ * Unlike a price feed, the arguments here are already typed by the caller,
93
+ * so nothing is looked up: they are encoded as given and the address they
94
+ * produce is reported.
95
+ **/
96
+ async contract(args) {
97
+ const client = this.#chains.client(args.chainId);
98
+ return this.#prepare(client, {
99
+ contractType: args.contractType,
100
+ version: args.version,
101
+ owner: args.owner,
102
+ encodedParams: encodeFunctionParams(args.values),
103
+ salt: args.salt ?? DEFAULT_DEPLOY_SALT
104
+ });
105
+ }
106
+ /**
107
+ * Where the encoded deploy lands, whether it is already there, and the
108
+ * transaction that puts it there.
109
+ **/
110
+ async #prepare(client, args) {
111
+ const repository = new BytecodeRepositoryContract("0x1cE2B1BE96a082b1b1539F80d5D8f82Ec06a0f9A", client);
112
+ const [isAlreadyDeployed, address] = await repository.isAlreadyDeployedAddress(args);
113
+ return {
114
+ ...args,
115
+ address,
116
+ isAlreadyDeployed,
117
+ tx: repository.deployTx({
118
+ contractType: args.contractType,
119
+ version: BigInt(args.version),
120
+ encodedParams: args.encodedParams,
121
+ salt: args.salt
122
+ })
123
+ };
124
+ }
125
+ /**
126
+ * The values with the composite's first leg given the bound it actually
127
+ * enforces, when it came in without one.
128
+ **/
129
+ async #withDerivedStaleness(client, values) {
130
+ const leg = values[COMPOSITE_FIRST_LEG];
131
+ if (!leg || typeof leg !== "object" || !leg.address || leg.stalenessPeriod !== 0) return values;
132
+ const derived = await deriveEffectiveStalenessPeriod(client, leg.address);
133
+ if (derived === null) throw new PriceFeedStalenessUnknownError(leg.address);
134
+ return {
135
+ ...values,
136
+ [COMPOSITE_FIRST_LEG]: {
137
+ ...leg,
138
+ stalenessPeriod: derived
139
+ }
140
+ };
141
+ }
142
+ #priceFeedSalt(args) {
143
+ if (args.salt) return args.salt;
144
+ if (!args.name) throw new PriceFeedSaltMissingError();
145
+ return priceFeedSalt(args.name);
146
+ }
147
+ };
148
+ //#endregion
149
+ export { DEFAULT_DEPLOY_SALT, PermissionlessDeploy, priceFeedSalt };