@mycelium-sdk/core 1.0.0-alpha.0 → 1.0.0-alpha.2

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/dist/index.cjs CHANGED
@@ -382,9 +382,9 @@ var DefaultSmartWallet = class extends SmartWallet {
382
382
  * @param amount Human-readable amount string
383
383
  * @returns Transaction result for the deposit
384
384
  */
385
- async earn(amount) {
385
+ async earn(vaultInfo, amount) {
386
386
  this.chainManager.getSupportedChain();
387
- const depositTransactionResult = this.protocolProvider.deposit(amount, this);
387
+ const depositTransactionResult = this.protocolProvider.deposit(vaultInfo, amount, this);
388
388
  return depositTransactionResult;
389
389
  }
390
390
  /**
@@ -395,13 +395,9 @@ var DefaultSmartWallet = class extends SmartWallet {
395
395
  * @category Earn
396
396
  * @returns Vault balance or `null` if nothing deposited
397
397
  */
398
- async getEarnBalance() {
399
- const depositedVault = await this.protocolProvider.fetchDepositedVaults(this);
400
- if (!depositedVault) {
401
- return null;
402
- }
398
+ async getEarnBalances() {
403
399
  const userAddress = await this.getAddress();
404
- return this.protocolProvider.getBalance(depositedVault, userAddress);
400
+ return this.protocolProvider.getBalances(userAddress);
405
401
  }
406
402
  /**
407
403
  * Withdraws from the selected protocol’s vault
@@ -412,8 +408,8 @@ var DefaultSmartWallet = class extends SmartWallet {
412
408
  * @throws Error if the withdrawal fails
413
409
  * @throws Error a user didn't deposit anything
414
410
  */
415
- async withdraw(amount) {
416
- const withdrawTransactionResult = await this.protocolProvider.withdraw(amount, this);
411
+ async withdraw(vaultInfo, amount) {
412
+ const withdrawTransactionResult = await this.protocolProvider.withdraw(vaultInfo, amount, this);
417
413
  return withdrawTransactionResult;
418
414
  }
419
415
  /**
@@ -450,7 +446,7 @@ var DefaultSmartWallet = class extends SmartWallet {
450
446
  return hash;
451
447
  } catch (error) {
452
448
  throw new Error(
453
- `Failed to send transaction: ${error instanceof Error ? error.message : "Unknown error"}`
449
+ `Failed to send transaction: ${error instanceof Error ? error.message.toString().slice(0, 100) : "Unknown error"}`
454
450
  );
455
451
  }
456
452
  }
@@ -671,127 +667,6 @@ var chainById = Object.values(viemChains).reduce(
671
667
  {}
672
668
  );
673
669
 
674
- // src/types/logger.ts
675
- var LogLevel = /* @__PURE__ */ ((LogLevel2) => {
676
- LogLevel2[LogLevel2["DEBUG"] = 0] = "DEBUG";
677
- LogLevel2[LogLevel2["INFO"] = 1] = "INFO";
678
- LogLevel2[LogLevel2["WARN"] = 2] = "WARN";
679
- LogLevel2[LogLevel2["ERROR"] = 3] = "ERROR";
680
- return LogLevel2;
681
- })(LogLevel || {});
682
-
683
- // src/tools/Logger.ts
684
- var Logger = class _Logger {
685
- /**
686
- * Create a new logger instance
687
- * @param logLevel Initial log level, defaults to DEBUG
688
- */
689
- constructor(logLevel = 0 /* DEBUG */) {
690
- this.logs = [];
691
- this.maxLogs = 1e3;
692
- this.logLevel = logLevel;
693
- }
694
- /**
695
- * Get singleton instance of the logger
696
- * @param logLevel Optional log level to initialize if instance not yet created
697
- * @returns Logger instance
698
- */
699
- static getInstance(logLevel) {
700
- if (!_Logger.instance) {
701
- _Logger.instance = new _Logger(logLevel);
702
- }
703
- return _Logger.instance;
704
- }
705
- /** Set the log level */
706
- setLogLevel(level) {
707
- this.logLevel = level;
708
- }
709
- /** Get the current log level */
710
- getLogLevel() {
711
- return this.logLevel;
712
- }
713
- /** Internal check if a message should be logged */
714
- shouldLog(level) {
715
- return level >= this.logLevel;
716
- }
717
- /** Format log message into a readable string */
718
- formatMessage(level, message, data, context) {
719
- const timestamp = (/* @__PURE__ */ new Date()).toISOString();
720
- const levelName = LogLevel[level];
721
- const contextStr = context ? `[${context}]` : "";
722
- return `${timestamp} ${levelName}${contextStr}: ${message}`;
723
- }
724
- /** Add a log entry and output to console */
725
- addLog(level, message, data, context) {
726
- if (!this.shouldLog(level)) {
727
- return;
728
- }
729
- const logEntry = {
730
- timestamp: (/* @__PURE__ */ new Date()).toISOString(),
731
- level,
732
- message,
733
- data,
734
- context
735
- };
736
- this.logs.push(logEntry);
737
- if (this.logs.length > this.maxLogs) {
738
- this.logs = this.logs.slice(-this.maxLogs);
739
- }
740
- const formattedMessage = this.formatMessage(level, message, data, context);
741
- switch (level) {
742
- case 0 /* DEBUG */:
743
- console.debug(`\u{1F50D} ${formattedMessage}`, data || "");
744
- break;
745
- case 1 /* INFO */:
746
- console.info(`\u2139\uFE0F ${formattedMessage}`, data || "");
747
- break;
748
- case 2 /* WARN */:
749
- console.warn(`\u26A0\uFE0F ${formattedMessage}`, data || "");
750
- break;
751
- case 3 /* ERROR */:
752
- console.error(`\u274C ${formattedMessage}`, data || "");
753
- break;
754
- }
755
- }
756
- /** Log a debug message */
757
- debug(message, data, context) {
758
- this.addLog(0 /* DEBUG */, message, data, context);
759
- }
760
- /** Log an info message */
761
- info(message, data, context) {
762
- this.addLog(1 /* INFO */, message, data, context);
763
- }
764
- /** Log a warning message */
765
- warn(message, data, context) {
766
- this.addLog(2 /* WARN */, message, data, context);
767
- }
768
- /** Log an error message */
769
- error(message, data, context) {
770
- this.addLog(3 /* ERROR */, message, data, context);
771
- }
772
- /** Get all logs */
773
- getLogs() {
774
- return [...this.logs];
775
- }
776
- /** Get logs by level */
777
- getLogsByLevel(level) {
778
- return this.logs.filter((log) => log.level === level);
779
- }
780
- /** Clear all logs */
781
- clearLogs() {
782
- this.logs = [];
783
- }
784
- /** Export logs as a JSON string */
785
- exportLogs() {
786
- return JSON.stringify(this.logs, null, 2);
787
- }
788
- /** Set maximum number of logs to retain in memory */
789
- setMaxLogs(max) {
790
- this.maxLogs = max;
791
- }
792
- };
793
- var logger = Logger.getInstance();
794
-
795
670
  // src/tools/ChainManager.ts
796
671
  var ChainManager = class {
797
672
  /**
@@ -847,7 +722,6 @@ var ChainManager = class {
847
722
  if (!bundlerUrl) {
848
723
  throw new Error(`No bundler URL configured for chain ID: ${chainId}`);
849
724
  }
850
- logger.info("Public client setup:", { bundlerUrl, chainId }, "ChainManager");
851
725
  const client = (0, import_viem5.createPublicClient)({
852
726
  chain: this.getChain(chainId),
853
727
  transport: (0, import_viem5.http)(rpcUrl)
@@ -1080,7 +954,7 @@ var DefaultSmartWalletProvider = class extends SmartWalletProvider {
1080
954
  constructor(chainManager, protocol, coinbaseCDP) {
1081
955
  super();
1082
956
  this.chainManager = chainManager;
1083
- this.protocolProvider = protocol.instance;
957
+ this.protocolProvider = protocol;
1084
958
  this.coinbaseCDP = coinbaseCDP;
1085
959
  }
1086
960
  /**
@@ -1343,8 +1217,7 @@ var WalletProvider = class {
1343
1217
  throw new Error(
1344
1218
  "Either walletAddress or deploymentOwners array must be provided to locate the smart wallet"
1345
1219
  );
1346
- } catch (error) {
1347
- logger.error("Error getting smart wallet", error, "WalletProvider");
1220
+ } catch {
1348
1221
  throw new Error(
1349
1222
  "Either walletAddress or deploymentOwners array must be provided to locate the smart wallet"
1350
1223
  );
@@ -1387,6 +1260,127 @@ var EmbeddedWallet = class {
1387
1260
  }
1388
1261
  };
1389
1262
 
1263
+ // src/types/logger.ts
1264
+ var LogLevel = /* @__PURE__ */ ((LogLevel2) => {
1265
+ LogLevel2[LogLevel2["DEBUG"] = 0] = "DEBUG";
1266
+ LogLevel2[LogLevel2["INFO"] = 1] = "INFO";
1267
+ LogLevel2[LogLevel2["WARN"] = 2] = "WARN";
1268
+ LogLevel2[LogLevel2["ERROR"] = 3] = "ERROR";
1269
+ return LogLevel2;
1270
+ })(LogLevel || {});
1271
+
1272
+ // src/tools/Logger.ts
1273
+ var Logger = class _Logger {
1274
+ /**
1275
+ * Create a new logger instance
1276
+ * @param logLevel Initial log level, defaults to DEBUG
1277
+ */
1278
+ constructor(logLevel = 0 /* DEBUG */) {
1279
+ this.logs = [];
1280
+ this.maxLogs = 1e3;
1281
+ this.logLevel = logLevel;
1282
+ }
1283
+ /**
1284
+ * Get singleton instance of the logger
1285
+ * @param logLevel Optional log level to initialize if instance not yet created
1286
+ * @returns Logger instance
1287
+ */
1288
+ static getInstance(logLevel) {
1289
+ if (!_Logger.instance) {
1290
+ _Logger.instance = new _Logger(logLevel);
1291
+ }
1292
+ return _Logger.instance;
1293
+ }
1294
+ /** Set the log level */
1295
+ setLogLevel(level) {
1296
+ this.logLevel = level;
1297
+ }
1298
+ /** Get the current log level */
1299
+ getLogLevel() {
1300
+ return this.logLevel;
1301
+ }
1302
+ /** Internal check if a message should be logged */
1303
+ shouldLog(level) {
1304
+ return level >= this.logLevel;
1305
+ }
1306
+ /** Format log message into a readable string */
1307
+ formatMessage(level, message, data, context) {
1308
+ const timestamp = (/* @__PURE__ */ new Date()).toISOString();
1309
+ const levelName = LogLevel[level];
1310
+ const contextStr = context ? `[${context}]` : "";
1311
+ return `${timestamp} ${levelName}${contextStr}: ${message}`;
1312
+ }
1313
+ /** Add a log entry and output to console */
1314
+ addLog(level, message, data, context) {
1315
+ if (!this.shouldLog(level)) {
1316
+ return;
1317
+ }
1318
+ const logEntry = {
1319
+ timestamp: (/* @__PURE__ */ new Date()).toISOString(),
1320
+ level,
1321
+ message,
1322
+ data,
1323
+ context
1324
+ };
1325
+ this.logs.push(logEntry);
1326
+ if (this.logs.length > this.maxLogs) {
1327
+ this.logs = this.logs.slice(-this.maxLogs);
1328
+ }
1329
+ const formattedMessage = this.formatMessage(level, message, data, context);
1330
+ switch (level) {
1331
+ case 0 /* DEBUG */:
1332
+ console.debug(`\u{1F50D} ${formattedMessage}`, data || "");
1333
+ break;
1334
+ case 1 /* INFO */:
1335
+ console.info(`\u2139\uFE0F ${formattedMessage}`, data || "");
1336
+ break;
1337
+ case 2 /* WARN */:
1338
+ console.warn(`\u26A0\uFE0F ${formattedMessage}`, data || "");
1339
+ break;
1340
+ case 3 /* ERROR */:
1341
+ console.error(`\u274C ${formattedMessage}`, data || "");
1342
+ break;
1343
+ }
1344
+ }
1345
+ /** Log a debug message */
1346
+ debug(message, data, context) {
1347
+ this.addLog(0 /* DEBUG */, message, data, context);
1348
+ }
1349
+ /** Log an info message */
1350
+ info(message, data, context) {
1351
+ this.addLog(1 /* INFO */, message, data, context);
1352
+ }
1353
+ /** Log a warning message */
1354
+ warn(message, data, context) {
1355
+ this.addLog(2 /* WARN */, message, data, context);
1356
+ }
1357
+ /** Log an error message */
1358
+ error(message, data, context) {
1359
+ this.addLog(3 /* ERROR */, message, data, context);
1360
+ }
1361
+ /** Get all logs */
1362
+ getLogs() {
1363
+ return [...this.logs];
1364
+ }
1365
+ /** Get logs by level */
1366
+ getLogsByLevel(level) {
1367
+ return this.logs.filter((log) => log.level === level);
1368
+ }
1369
+ /** Clear all logs */
1370
+ clearLogs() {
1371
+ this.logs = [];
1372
+ }
1373
+ /** Export logs as a JSON string */
1374
+ exportLogs() {
1375
+ return JSON.stringify(this.logs, null, 2);
1376
+ }
1377
+ /** Set maximum number of logs to retain in memory */
1378
+ setMaxLogs(max) {
1379
+ this.maxLogs = max;
1380
+ }
1381
+ };
1382
+ var logger = Logger.getInstance();
1383
+
1390
1384
  // src/wallet/PrivyWallet.ts
1391
1385
  var PrivyWallet = class extends EmbeddedWallet {
1392
1386
  /**
@@ -1767,14 +1761,14 @@ var SPARK_SSR_ORACLE_ADDRESS = "0x65d946e533748A998B1f0E430803e39A6388f7a1";
1767
1761
  var SPARK_VAULT = [
1768
1762
  {
1769
1763
  id: "sUSDC",
1764
+ protocolId: "spark",
1765
+ name: "sUSDC",
1766
+ type: "stable",
1770
1767
  chain: "base",
1771
1768
  vaultAddress: "0x3128a0f7f0ea68e7b7c9b00afa7e41045828e858",
1772
- depositTokenAddress: "0x833589fcd6edb6e08f4c7c32d4f71b54bda02913",
1773
- depositTokenDecimals: 6,
1774
- depositTokenSymbol: "USDC",
1775
- earnTokenAddress: "0x833589fcd6edb6e08f4c7c32d4f71b54bda02913",
1776
- earnTokenDecimals: 18,
1777
- earnTokenSymbol: "sUSDC",
1769
+ tokenAddress: "0x833589fcd6edb6e08f4c7c32d4f71b54bda02913",
1770
+ tokenDecimals: 6,
1771
+ tokenSymbol: "USDC",
1778
1772
  metadata: {}
1779
1773
  }
1780
1774
  ];
@@ -1785,6 +1779,7 @@ var RAY = BigInt("1000000000000000000000000000");
1785
1779
  var SparkProtocol = class extends BaseProtocol {
1786
1780
  constructor() {
1787
1781
  super(...arguments);
1782
+ /** All Spark vaults */
1788
1783
  this.allVaults = [];
1789
1784
  }
1790
1785
  /**
@@ -1795,7 +1790,7 @@ var SparkProtocol = class extends BaseProtocol {
1795
1790
  this.chainManager = chainManager;
1796
1791
  this.selectedChainId = chainManager.getSupportedChain();
1797
1792
  this.publicClient = chainManager.getPublicClient(this.selectedChainId);
1798
- this.allVaults = this.getVaults();
1793
+ this.allVaults = SPARK_VAULT;
1799
1794
  }
1800
1795
  /**
1801
1796
  * Get the SSR (Sky Saving Rate) of the Spark protocol
@@ -1825,88 +1820,54 @@ var SparkProtocol = class extends BaseProtocol {
1825
1820
  async getAPY() {
1826
1821
  const ssr = await this.getSSR();
1827
1822
  const apy = Math.exp(Math.log(ssr) * SECONDS_PER_YEAR) - 1;
1828
- return Number((apy * 100).toFixed(2));
1829
- }
1830
- /**
1831
- *
1832
- * Get all vault info from a Spark protocol
1833
- * @returns The list of vaults
1834
- */
1835
- getVaults() {
1836
- return SPARK_VAULT;
1823
+ return apy;
1837
1824
  }
1838
1825
  /**
1839
- * Get the best available Spark vault
1840
- * @returns The top-ranked Spark vault
1826
+ * Get the best available Spark vaults
1827
+ * @remarks Currently, the vault is only one and relates to sUSDC. Currently return only one stable vault
1828
+ * @returns Best Spark vaults in 2 groups: stable and non-stable
1841
1829
  * @throws Error if no vaults found
1842
1830
  */
1843
- async getBestVault() {
1831
+ async getBestVaults() {
1844
1832
  if (this.allVaults.length === 0) {
1845
1833
  throw new Error("No vaults found");
1846
1834
  }
1847
1835
  const selectedVault = this.allVaults[0];
1848
1836
  selectedVault.metadata.apy = await this.getAPY();
1849
- return selectedVault;
1850
- }
1851
- /**
1852
- * Fetch a vault where the user previously deposited funds
1853
- * @param smartWallet Smart wallet to inspect
1854
- * @returns The vault with user deposits, or null if none found
1855
- */
1856
- async fetchDepositedVaults(smartWallet) {
1857
- let depositedVault = void 0;
1858
- const userAddress = await smartWallet.getAddress();
1859
- for (const vault of this.allVaults) {
1860
- const balance = await this.getBalance(vault, userAddress);
1861
- if (parseInt(balance.depositedAmount) > 0) {
1862
- depositedVault = vault;
1863
- }
1864
- }
1865
- if (depositedVault) {
1866
- depositedVault.metadata.apy = await this.getAPY();
1867
- }
1868
- logger.info("Deposited vaults:", { depositedVault }, "SparkProtocol");
1869
- return depositedVault || null;
1837
+ return {
1838
+ stable: [selectedVault],
1839
+ nonStable: []
1840
+ };
1870
1841
  }
1871
1842
  /**
1872
1843
  * Deposit funds into a Spark vault
1844
+ * @param vaultInfo Vault information
1873
1845
  * @param amount Amount to deposit (human-readable)
1874
1846
  * @param smartWallet Smart wallet instance to use
1875
1847
  * @returns Transaction result with hash
1876
1848
  */
1877
- async deposit(amount, smartWallet) {
1878
- const depositedVault = await this.fetchDepositedVaults(smartWallet);
1879
- let vaultInfoToDeposit;
1880
- logger.info("Previously deposited vault:", { depositedVault }, "SparkProtocol");
1881
- if (depositedVault) {
1882
- vaultInfoToDeposit = depositedVault;
1883
- } else {
1884
- vaultInfoToDeposit = await this.getBestVault();
1885
- logger.info("Best vault that found:", { bestVault: vaultInfoToDeposit }, "SparkProtocol");
1886
- }
1849
+ async deposit(vaultInfo, amount, smartWallet) {
1887
1850
  const owner = await smartWallet.getAddress();
1888
- const assets = (0, import_viem11.parseUnits)(amount, vaultInfoToDeposit.depositTokenDecimals);
1889
- logger.info("Raw deposit amount:", { amount, assets }, "SparkProtocol");
1851
+ const assets = (0, import_viem11.parseUnits)(amount, vaultInfo.tokenDecimals);
1890
1852
  const allowance = await this.checkAllowance(
1891
- vaultInfoToDeposit.depositTokenAddress,
1892
- vaultInfoToDeposit.vaultAddress,
1853
+ vaultInfo.tokenAddress,
1854
+ vaultInfo.vaultAddress,
1893
1855
  owner,
1894
1856
  this.selectedChainId
1895
1857
  );
1896
- logger.info("Current vault contract allowance:", { allowance }, "SparkProtocol");
1897
1858
  const ops = [];
1898
1859
  if (allowance < assets) {
1899
1860
  ops.push({
1900
- to: vaultInfoToDeposit.depositTokenAddress,
1861
+ to: vaultInfo.tokenAddress,
1901
1862
  data: (0, import_viem11.encodeFunctionData)({
1902
1863
  abi: import_viem11.erc20Abi,
1903
1864
  functionName: "approve",
1904
- args: [vaultInfoToDeposit.vaultAddress, assets]
1865
+ args: [vaultInfo.vaultAddress, assets]
1905
1866
  })
1906
1867
  });
1907
1868
  }
1908
1869
  ops.push({
1909
- to: vaultInfoToDeposit.vaultAddress,
1870
+ to: vaultInfo.vaultAddress,
1910
1871
  data: (0, import_viem11.encodeFunctionData)({
1911
1872
  abi: SPARK_VAULT_ABI,
1912
1873
  functionName: "deposit",
@@ -1918,23 +1879,19 @@ var SparkProtocol = class extends BaseProtocol {
1918
1879
  }
1919
1880
  /**
1920
1881
  * Withdraw funds from a Spark vault
1921
- * @param amountInUnderlying Amount in base token units (or undefined to withdraw all)
1882
+ * @param vaultInfo Vault information
1883
+ * @param amount Amount in base token units (or undefined to withdraw all)
1922
1884
  * @param smartWallet Smart wallet instance to withdraw from
1923
1885
  * @returns Transaction result with hash
1924
1886
  * @throws Error if no deposited vault found
1925
1887
  */
1926
- async withdraw(amountInUnderlying, smartWallet) {
1927
- const depositedVault = await this.fetchDepositedVaults(smartWallet);
1928
- if (!depositedVault) {
1929
- throw new Error("No vault found to withdraw from");
1930
- }
1888
+ async withdraw(vaultInfo, amount, smartWallet) {
1931
1889
  const owner = await smartWallet.getAddress();
1932
1890
  let withdrawData;
1933
- if (amountInUnderlying) {
1934
- const assets = (0, import_viem11.parseUnits)(amountInUnderlying, depositedVault.depositTokenDecimals);
1935
- logger.info("Withdraw amount:", { amountInUnderlying, assets }, "SparkProtocol");
1891
+ if (amount) {
1892
+ const assets = (0, import_viem11.parseUnits)(amount, vaultInfo.tokenDecimals);
1936
1893
  withdrawData = {
1937
- to: depositedVault.vaultAddress,
1894
+ to: vaultInfo.vaultAddress,
1938
1895
  data: (0, import_viem11.encodeFunctionData)({
1939
1896
  abi: SPARK_VAULT_ABI,
1940
1897
  functionName: "withdraw",
@@ -1942,10 +1899,9 @@ var SparkProtocol = class extends BaseProtocol {
1942
1899
  })
1943
1900
  };
1944
1901
  } else {
1945
- const maxShares = await this.getMaxRedeemableShares(depositedVault, owner);
1946
- logger.info("Withdrawing all funds:", { maxShares }, "SparkProtocol");
1902
+ const maxShares = await this.getMaxRedeemableShares(vaultInfo, owner);
1947
1903
  withdrawData = {
1948
- to: depositedVault.vaultAddress,
1904
+ to: vaultInfo.vaultAddress,
1949
1905
  data: (0, import_viem11.encodeFunctionData)({
1950
1906
  abi: SPARK_VAULT_ABI,
1951
1907
  functionName: "redeem",
@@ -1954,7 +1910,6 @@ var SparkProtocol = class extends BaseProtocol {
1954
1910
  };
1955
1911
  }
1956
1912
  const hash = await smartWallet.send(withdrawData, this.selectedChainId);
1957
- logger.info("Withdraw transaction sent:", { hash }, "SparkProtocol");
1958
1913
  return { success: true, hash };
1959
1914
  }
1960
1915
  /**
@@ -1977,14 +1932,15 @@ var SparkProtocol = class extends BaseProtocol {
1977
1932
  }
1978
1933
  /**
1979
1934
  * Get amount that a wallet has deposited in a vault
1980
- * @param vaultInfo Vault information
1981
1935
  * @param walletAddress Wallet address to check
1982
- * @returns Object containing shares and deposited amount
1936
+ * @returns Array of vault balances with vaults info
1983
1937
  */
1984
- async getBalance(vaultInfo, walletAddress) {
1938
+ async getBalances(walletAddress) {
1985
1939
  if (!this.publicClient) {
1986
1940
  throw new Error("Public client not initialized");
1987
1941
  }
1942
+ const vaultInfo = SPARK_VAULT[0];
1943
+ vaultInfo.metadata.apy = await this.getAPY();
1988
1944
  const shares = await this.publicClient.readContract({
1989
1945
  address: vaultInfo.vaultAddress,
1990
1946
  abi: SPARK_VAULT_ABI,
@@ -1992,7 +1948,7 @@ var SparkProtocol = class extends BaseProtocol {
1992
1948
  args: [walletAddress]
1993
1949
  });
1994
1950
  if (shares === 0n) {
1995
- return { shares: "0", depositedAmount: "0", vaultInfo };
1951
+ return [{ balance: null, vaultInfo }];
1996
1952
  }
1997
1953
  const assets = await this.publicClient.readContract({
1998
1954
  address: vaultInfo.vaultAddress,
@@ -2000,11 +1956,12 @@ var SparkProtocol = class extends BaseProtocol {
2000
1956
  functionName: "convertToAssets",
2001
1957
  args: [shares]
2002
1958
  });
2003
- return {
2004
- shares: (0, import_viem11.formatUnits)(shares, vaultInfo.earnTokenDecimals),
2005
- depositedAmount: (0, import_viem11.formatUnits)(assets, vaultInfo.depositTokenDecimals),
2006
- vaultInfo
2007
- };
1959
+ return [
1960
+ {
1961
+ balance: (0, import_viem11.formatUnits)(assets, vaultInfo.tokenDecimals),
1962
+ vaultInfo
1963
+ }
1964
+ ];
2008
1965
  }
2009
1966
  };
2010
1967
 
@@ -2016,59 +1973,233 @@ var availableProtocols = [
2016
1973
  name: "Spark",
2017
1974
  website: "https://spark.fi/",
2018
1975
  logo: "/logos/spark.png",
2019
- supportedChains: [1, 8453, 42161],
1976
+ supportedChains: [8453],
2020
1977
  riskLevel: "low",
2021
- isPremium: false
1978
+ isActive: true
2022
1979
  },
2023
1980
  instance: new SparkProtocol()
2024
1981
  }
2025
1982
  ];
2026
1983
 
2027
- // src/tools/ApiKeysValidator.ts
2028
- var ApiKeysValidator = class {
2029
- // TODO: Implement the validation logic
1984
+ // src/protocols/implementations/ProxyProtocol.ts
1985
+ var import_viem12 = require("viem");
1986
+ var ProxyProtocol = class extends BaseProtocol {
2030
1987
  /**
2031
- * Validates whether the provided API key is valid
2032
- *
2033
- * @internal
2034
- * @param apiKey API key from {@link ProtocolsRouterConfig}
2035
- * @returns True if the API key is considered valid
1988
+ * Initialize the Spark protocol with the provided chain manager
1989
+ * @param chainManager Chain manager instance used for network operations
2036
1990
  */
2037
- validate(apiKey) {
2038
- logger.info("Validating api key...", apiKey, "ApiKeysValidator");
2039
- return true;
2040
- }
2041
- };
2042
-
2043
- // src/router/base/ProtocolRouterBase.ts
2044
- var ProtocolRouterBase = class {
2045
- /**
2046
- * Initialize a base protocol router
2047
- * @param riskLevel Risk level required by the integrator
2048
- * @param chainManager Chain manager instance for network operations
2049
- * @param minApy Optional minimum APY filter
2050
- * @param apiKey Optional API key for premium protocol access
2051
- */
2052
- constructor(riskLevel, chainManager, minApy, apiKey) {
2053
- // TODO: Add an API key validation
2054
- /** API key validator instance */
2055
- this.apiKeyValidator = new ApiKeysValidator();
2056
- this.riskLevel = riskLevel;
2057
- this.minApy = minApy;
2058
- this.apiKey = apiKey;
1991
+ async init(chainManager, protocolsSecurityConfig, apiClient) {
2059
1992
  this.chainManager = chainManager;
1993
+ this.selectedChainId = chainManager.getSupportedChain();
1994
+ this.publicClient = chainManager.getPublicClient(this.selectedChainId);
1995
+ this.apiClient = apiClient;
1996
+ this.protocolsSecurityConfig = protocolsSecurityConfig;
1997
+ }
1998
+ /**
1999
+ * Log a vault-related operation after deposit or withdraw funds
2000
+ * @param userAddress Address of the user who performed the operation
2001
+ * @param hash Hash of the operation
2002
+ * @param vaultInfo Information about the vault where the operation was performed
2003
+ * @param chainId Chain ID where the operation was performed
2004
+ * @param amount Amount of the operation
2005
+ * @param operationType Type of the operation
2006
+ * @param operationStatus Status of the operation
2007
+ */
2008
+ async logOperation(userAddress, hash, vaultInfo, chainId, amount, operationType, operationStatus) {
2009
+ const apiResponse = await this.apiClient.sendRequest("log", void 0, void 0, {
2010
+ userAddress,
2011
+ protocolId: vaultInfo.protocolId,
2012
+ vaultAddress: vaultInfo.vaultAddress,
2013
+ transactionHash: hash,
2014
+ chainId: chainId.toString(),
2015
+ amount,
2016
+ status: operationStatus,
2017
+ operationType
2018
+ });
2019
+ if (!apiResponse.success) {
2020
+ throw new Error(
2021
+ apiResponse.error || `Failed to log operation: ${operationType} for vault: ${vaultInfo}`
2022
+ );
2023
+ }
2024
+ }
2025
+ /**
2026
+ * Get the best vaults to deposit funds
2027
+ * @param stableVaultsLimit Limit of stable vaults to get. Optional, default is 1
2028
+ * @param nonStableVaultsLimit Limit of non-stable vaults to get. Optional, default is 1
2029
+ * @returns Best vaults to deposit funds in 2 groups: stable and non-stable
2030
+ */
2031
+ async getBestVaults(stableVaultsLimit = 1, nonStableVaultsLimit = 1) {
2032
+ const pathParams = {
2033
+ risk_level: this.protocolsSecurityConfig.riskLevel,
2034
+ chain_id: this.selectedChainId.toString(),
2035
+ stable_vaults_limit: stableVaultsLimit.toString(),
2036
+ non_stable_vaults_limit: nonStableVaultsLimit.toString()
2037
+ };
2038
+ const apiResponse = await this.apiClient.sendRequest("vaults", pathParams);
2039
+ if (!apiResponse.success) {
2040
+ throw new Error(apiResponse.error || "Failed to get best vaults");
2041
+ }
2042
+ const vaults = apiResponse.data;
2043
+ return {
2044
+ stable: vaults.stableVaults.map((vault) => {
2045
+ return {
2046
+ ...vault,
2047
+ metadata: {
2048
+ apy: vault.metadata?.apy,
2049
+ poolTvlUsd: vault.metadata?.poolTvlUsd
2050
+ }
2051
+ };
2052
+ }),
2053
+ nonStable: vaults.nonStableVaults.map((vault) => {
2054
+ return {
2055
+ ...vault,
2056
+ metadata: {
2057
+ apy: vault.metadata?.apy,
2058
+ poolTvlUsd: vault.metadata?.poolTvlUsd
2059
+ }
2060
+ };
2061
+ })
2062
+ };
2063
+ }
2064
+ /**
2065
+ * Deposit funds to a provided vault
2066
+ * @param vaultInfo Information about the vault to deposit funds to
2067
+ * @param amount Amount of funds to deposit
2068
+ * @param smartWallet Smart wallet to use for the deposit
2069
+ * @returns Result of the deposit transaction
2070
+ */
2071
+ async deposit(vaultInfo, amount, smartWallet) {
2072
+ const currentAddress = await smartWallet.getAddress();
2073
+ const operationsCallData = [];
2074
+ const depositTokenDecimals = vaultInfo.tokenDecimals;
2075
+ const depositTokenAddress = vaultInfo.tokenAddress;
2076
+ const vaultAddress = vaultInfo.vaultAddress;
2077
+ const rawDepositAmount = (0, import_viem12.parseUnits)(amount, depositTokenDecimals);
2078
+ const allowance = await this.checkAllowance(
2079
+ depositTokenAddress,
2080
+ vaultAddress,
2081
+ currentAddress,
2082
+ this.selectedChainId
2083
+ );
2084
+ if (allowance < rawDepositAmount) {
2085
+ const approveData = {
2086
+ to: depositTokenAddress,
2087
+ data: (0, import_viem12.encodeFunctionData)({
2088
+ abi: import_viem12.erc20Abi,
2089
+ functionName: "approve",
2090
+ args: [vaultAddress, rawDepositAmount]
2091
+ })
2092
+ };
2093
+ operationsCallData.push(approveData);
2094
+ }
2095
+ if (!vaultInfo.protocolId) {
2096
+ throw new Error("Vault protocol ID is required");
2097
+ }
2098
+ const apiResponse = await this.apiClient.sendRequest(
2099
+ "deposit",
2100
+ void 0,
2101
+ vaultInfo.protocolId,
2102
+ {
2103
+ vaultInfo,
2104
+ amount: amount.toString(),
2105
+ chainId: this.selectedChainId.toString()
2106
+ }
2107
+ );
2108
+ if (!apiResponse.success) {
2109
+ throw new Error(apiResponse.error || "Failed to receive deposit operations call data");
2110
+ }
2111
+ const receivedOperationsCallData = apiResponse.data;
2112
+ operationsCallData.push(receivedOperationsCallData);
2113
+ const hash = await smartWallet.sendBatch(operationsCallData, this.selectedChainId);
2114
+ const operationStatus = hash ? "completed" : "failed";
2115
+ this.logOperation(
2116
+ currentAddress,
2117
+ hash,
2118
+ vaultInfo,
2119
+ this.selectedChainId,
2120
+ amount,
2121
+ "deposit",
2122
+ operationStatus
2123
+ );
2124
+ return { hash, success: true };
2125
+ }
2126
+ /**
2127
+ * Withdraw funds from a provided vault
2128
+ * @param vaultInfo Information about the vault to withdraw funds from
2129
+ * @param amount Amount of funds to withdraw
2130
+ * @param smartWallet Smart wallet to use for the withdrawal
2131
+ * @returns Result of the withdrawal transaction
2132
+ */
2133
+ async withdraw(vaultInfo, amount, smartWallet) {
2134
+ const currentAddress = await smartWallet.getAddress();
2135
+ const earningBalances = await smartWallet.getEarnBalances();
2136
+ if (!earningBalances) {
2137
+ throw new Error("No earning balances found");
2138
+ }
2139
+ const earningBalance = earningBalances.find((balance) => balance.vaultInfo.id === vaultInfo.id);
2140
+ if (!earningBalance) {
2141
+ throw new Error("No earning balance found");
2142
+ }
2143
+ const balanceInfo = earningBalance.balance;
2144
+ const amountToWithdraw = amount ? amount : balanceInfo.currentBalance;
2145
+ const apiResponse = await this.apiClient.sendRequest(
2146
+ "withdraw",
2147
+ void 0,
2148
+ vaultInfo.protocolId,
2149
+ {
2150
+ vaultInfo,
2151
+ amount: amountToWithdraw,
2152
+ chainId: this.selectedChainId.toString()
2153
+ }
2154
+ );
2155
+ if (!apiResponse.success) {
2156
+ throw new Error(apiResponse.error || "Failed to receive withdraw operations call data");
2157
+ }
2158
+ const withdrawOperationCallData = apiResponse.data;
2159
+ const hash = await smartWallet.send(withdrawOperationCallData, this.selectedChainId);
2160
+ const operationStatus = hash ? "completed" : "failed";
2161
+ this.logOperation(
2162
+ currentAddress,
2163
+ hash,
2164
+ vaultInfo,
2165
+ this.selectedChainId,
2166
+ amountToWithdraw,
2167
+ "withdrawal",
2168
+ operationStatus
2169
+ );
2170
+ return { hash, success: true };
2171
+ }
2172
+ /**
2173
+ * Get the balances of a user by a provided address
2174
+ * @param walletAddress Address of the user to get the balances of
2175
+ * @param protocolId Protocol ID to get the balances for. Optional, default is undefined
2176
+ * @returns Balances of the user in the protocol vaults
2177
+ */
2178
+ async getBalances(walletAddress, protocolId) {
2179
+ const pathParams = {
2180
+ chain_id: this.selectedChainId.toString(),
2181
+ protocol_id: protocolId || "",
2182
+ userAddress: walletAddress
2183
+ };
2184
+ const apiResponse = await this.apiClient.sendRequest("balances", pathParams);
2185
+ if (!apiResponse.success) {
2186
+ throw new Error(apiResponse.error || "Failed to get balances");
2187
+ }
2188
+ const balances = apiResponse.data;
2189
+ return balances;
2060
2190
  }
2061
2191
  };
2062
2192
 
2063
2193
  // src/router/ProtocolRouter.ts
2064
- var ProtocolRouter = class extends ProtocolRouterBase {
2194
+ var ProtocolRouter = class {
2065
2195
  /**
2066
2196
  * Initialize the protocol router
2067
2197
  * @param config Router configuration including risk level, min APY, and optional API key
2068
2198
  * @param chainManager Chain manager instance for network validation
2069
2199
  */
2070
- constructor(config, chainManager) {
2071
- super(config.riskLevel, chainManager, config.minApy, config.apiKey);
2200
+ constructor(chainManager, isApiKeyValid) {
2201
+ this.chainManager = chainManager;
2202
+ this.isApiKeyValid = isApiKeyValid;
2072
2203
  }
2073
2204
  /**
2074
2205
  * Get all protocols available for the current configuration
@@ -2076,13 +2207,9 @@ var ProtocolRouter = class extends ProtocolRouterBase {
2076
2207
  * Includes all non-premium protocols and premium protocols if the API key is valid
2077
2208
  * @returns Array of available protocol definitions
2078
2209
  */
2079
- getProtocols() {
2080
- const isKeyValid = this.apiKeyValidator.validate(this.apiKey);
2210
+ getActivePublicProtocols() {
2081
2211
  const allAvailableProtocols = availableProtocols.filter((protocol) => {
2082
- if (!protocol.info.isPremium) {
2083
- return true;
2084
- }
2085
- return protocol.info.isPremium && isKeyValid;
2212
+ return protocol.info.isActive;
2086
2213
  });
2087
2214
  return allAvailableProtocols;
2088
2215
  }
@@ -2107,18 +2234,20 @@ var ProtocolRouter = class extends ProtocolRouterBase {
2107
2234
  * @throws Error if no protocols are available for the current risk level
2108
2235
  * @returns Protocol instance considered the best match
2109
2236
  */
2110
- recommend() {
2111
- const protocols = this.getProtocols();
2237
+ select() {
2238
+ if (this.isApiKeyValid) {
2239
+ return new ProxyProtocol();
2240
+ }
2241
+ const protocols = this.getActivePublicProtocols();
2112
2242
  const eligibleProtocols = protocols.filter((protocol) => {
2113
- const riskMatches = protocol.info.riskLevel === this.riskLevel;
2114
2243
  const isSupportedChain = this.isProtocolSupportedChain(protocol.info.supportedChains);
2115
- return riskMatches && isSupportedChain;
2244
+ return isSupportedChain;
2116
2245
  });
2117
2246
  if (eligibleProtocols.length === 0) {
2118
- throw new Error(`No protocols available for risk level: ${this.riskLevel}`);
2247
+ throw new Error(`No protocols available`);
2119
2248
  }
2120
2249
  const bestProtocol = eligibleProtocols[0];
2121
- return bestProtocol;
2250
+ return bestProtocol.instance;
2122
2251
  }
2123
2252
  };
2124
2253
 
@@ -2338,8 +2467,161 @@ var CoinbaseCDP = class {
2338
2467
  }
2339
2468
  };
2340
2469
 
2470
+ // src/protocols/ProtocolsNamespace.ts
2471
+ var ProtocolsNamespace = class {
2472
+ constructor(protocol) {
2473
+ this.protocol = protocol;
2474
+ }
2475
+ /**
2476
+ * Find the best vaults for protocols that were selected based on integrator's settings
2477
+ *
2478
+ * @returns Best vaults for protocols that were selected based on integrator's settings
2479
+ */
2480
+ async getBestVaults(stableVaultsLimit = 1, nonStableVaultsLimit = 1) {
2481
+ return await this.protocol.getBestVaults(stableVaultsLimit, nonStableVaultsLimit);
2482
+ }
2483
+ };
2484
+
2485
+ // src/constants/general.ts
2486
+ var BACKEND_HOSTNAME = process.env.NODE_ENV === "dev" ? "http://localhost:3000" : "https://mycelium-cloud-production.up.railway.app";
2487
+
2488
+ // src/tools/ApiClient.ts
2489
+ var import_axios2 = __toESM(require("axios"), 1);
2490
+ var ApiClient = class {
2491
+ constructor(apiKey) {
2492
+ this.client = import_axios2.default.create({
2493
+ baseURL: BACKEND_HOSTNAME
2494
+ });
2495
+ /** URL settings for the endpoint: get the best vaults to deposit funds */
2496
+ this.bestVaultUrlSettings = {
2497
+ method: "GET",
2498
+ path: "api/v1/public/protocols/best"
2499
+ };
2500
+ /** URL settings for the endpoint: deposit funds to a provided vault */
2501
+ this.depositUrlSettings = {
2502
+ method: "POST",
2503
+ path: "api/v1/public/protocols/details/:protocolId/deposit"
2504
+ };
2505
+ /** URL settings for the endpoint: log a vault-related operation after deposit or withdraw funds */
2506
+ this.logOperationSettings = {
2507
+ method: "POST",
2508
+ path: "api/v1/public/log/operation"
2509
+ };
2510
+ /** URL settings for the endpoint: withdraw funds from a provided vault */
2511
+ this.withdrawUrlSettings = {
2512
+ method: "POST",
2513
+ path: "api/v1/public/protocols/details/:protocolId/withdraw"
2514
+ };
2515
+ /** URL settings for the endpoint: get the balances of a user by a provided address */
2516
+ this.balancesUrlSettings = {
2517
+ method: "GET",
2518
+ path: "api/v1/public/user/:userAddress/balances"
2519
+ };
2520
+ /** URL settings for the endpoint: validate the API key */
2521
+ this.apiKeyValidUrlSettings = {
2522
+ method: "GET",
2523
+ path: "api/v1/public/valid"
2524
+ };
2525
+ /** URL settings for the endpoint: get the config for services */
2526
+ this.configUrlSettings = {
2527
+ method: "GET",
2528
+ path: "api/v1/public/config"
2529
+ };
2530
+ /** URL settings mapping with operation types */
2531
+ this.operationTypeToUrlSettings = {
2532
+ deposit: this.depositUrlSettings,
2533
+ withdraw: this.withdrawUrlSettings,
2534
+ log: this.logOperationSettings,
2535
+ vaults: this.bestVaultUrlSettings,
2536
+ balances: this.balancesUrlSettings,
2537
+ apiKeyValidation: this.apiKeyValidUrlSettings,
2538
+ config: this.configUrlSettings
2539
+ };
2540
+ this.apiKey = apiKey;
2541
+ if (!this.validateApiKeyFormat()) {
2542
+ throw new Error("Invalid API key format");
2543
+ }
2544
+ }
2545
+ /**
2546
+ * Send a request to the backend API
2547
+ * @param path Path of the endpoint to send the request to
2548
+ * @param method Method of the request
2549
+ * @param body Body of the request
2550
+ * @returns Response from the backend API
2551
+ */
2552
+ async sendRequest(operationType, params, protocolId, body) {
2553
+ const { path, method } = this.operationTypeToUrlSettings[operationType];
2554
+ let requestPath = path;
2555
+ if (protocolId) {
2556
+ requestPath = requestPath.replace(":protocolId", protocolId);
2557
+ }
2558
+ if (params?.userAddress) {
2559
+ requestPath = requestPath.replace(":userAddress", params.userAddress);
2560
+ delete params.userAddress;
2561
+ }
2562
+ const urlParams = new URLSearchParams(params).toString();
2563
+ if (urlParams) {
2564
+ requestPath += `?${urlParams}`;
2565
+ }
2566
+ const response = await this.client.request({
2567
+ method,
2568
+ url: requestPath,
2569
+ data: body,
2570
+ headers: { Authorization: `Bearer ${this.apiKey}`, "Content-Type": "application/json" }
2571
+ });
2572
+ if (response.status !== 200) {
2573
+ throw new Error(`Failed to send request to ${path}`);
2574
+ }
2575
+ const apiResponse = response.data;
2576
+ return apiResponse;
2577
+ }
2578
+ /**
2579
+ * Validates whether the provided API key is valid
2580
+ *
2581
+ * @internal
2582
+ * @param apiKey API key from {@link ProtocolsRouterConfig}
2583
+ * @returns True if the API key is considered valid
2584
+ */
2585
+ async validate() {
2586
+ if (!this.validateApiKeyFormat()) {
2587
+ throw new Error("Invalid API key format");
2588
+ }
2589
+ const apiResponse = await this.sendRequest("apiKeyValidation");
2590
+ if (!apiResponse.success) {
2591
+ throw new Error(apiResponse.error || "Failed to validate API key");
2592
+ }
2593
+ return true;
2594
+ }
2595
+ /**
2596
+ *
2597
+ * Validates the format of the API key. Must start with 'sk_' and contain only hexadecimal characters
2598
+ *
2599
+ * @internal
2600
+ * @param apiKey API key from {@link ProtocolsRouterConfig}
2601
+ * @returns
2602
+ */
2603
+ validateApiKeyFormat() {
2604
+ if (!this.apiKey) {
2605
+ return false;
2606
+ }
2607
+ const prefix = "sk_";
2608
+ if (!this.apiKey.startsWith(prefix)) {
2609
+ return false;
2610
+ }
2611
+ const keyPart = this.apiKey.slice(prefix.length);
2612
+ if (keyPart.length < 32 || keyPart.length > 128) {
2613
+ return false;
2614
+ }
2615
+ const hexPattern = /^[0-9a-fA-F]+$/;
2616
+ if (!hexPattern.test(keyPart)) {
2617
+ return false;
2618
+ }
2619
+ return true;
2620
+ }
2621
+ };
2622
+
2341
2623
  // src/index.ts
2342
- var MyceliumSDK = class {
2624
+ var MyceliumSDK = class _MyceliumSDK {
2343
2625
  /**
2344
2626
  * Creates a new SDK instance
2345
2627
  *
@@ -2347,7 +2629,7 @@ var MyceliumSDK = class {
2347
2629
  * @throws Throws if an unsupported wallet provider is given
2348
2630
  * @see MyceliumSDKConfig
2349
2631
  */
2350
- constructor(config) {
2632
+ constructor(config, isPremiumAvailable, apiClient) {
2351
2633
  /**
2352
2634
  * Ramp namespace to manage ramp operations. Methods are available on {@link RampNamespace}
2353
2635
  * @internal
@@ -2372,11 +2654,14 @@ var MyceliumSDK = class {
2372
2654
  bundlerUrl: "https://public.pimlico.io/v2/8453/rpc"
2373
2655
  }
2374
2656
  );
2375
- if (!config.chain) {
2376
- logger.warn(
2377
- "No chain config provided, using default public RPC and Bundler URLs",
2378
- "MyceliumSDK"
2657
+ if (config.protocolsSecurityConfig) {
2658
+ this.protocol = this.selectProtocol(
2659
+ config.protocolsSecurityConfig,
2660
+ isPremiumAvailable,
2661
+ apiClient
2379
2662
  );
2663
+ } else {
2664
+ throw new Error("Protocols router config is required");
2380
2665
  }
2381
2666
  if (config.coinbaseCDPConfig) {
2382
2667
  this.coinbaseCDP = new CoinbaseCDP(
@@ -2387,11 +2672,63 @@ var MyceliumSDK = class {
2387
2672
  );
2388
2673
  this.fundingNamespace = new FundingNamespace(this.coinbaseCDP);
2389
2674
  }
2390
- const protocolsRouterConfig = config.protocolsRouterConfig || {
2391
- riskLevel: "low"
2392
- };
2393
- this.protocol = this.findProtocol(protocolsRouterConfig);
2394
2675
  this.wallet = this.createWalletNamespace(config.walletsConfig);
2676
+ this.protocols = new ProtocolsNamespace(this.protocol);
2677
+ }
2678
+ /**
2679
+ * Initializes the SDK
2680
+ * @param config SDK configuration (networks, wallets, protocol router settings)
2681
+ * @returns SDK instance
2682
+ */
2683
+ static async init(config) {
2684
+ let finalConfig;
2685
+ let isPremiumAvailable = false;
2686
+ if ("apiKey" in config && config.apiKey) {
2687
+ const apiClient = new ApiClient(config.apiKey);
2688
+ isPremiumAvailable = await apiClient.validate();
2689
+ if (isPremiumAvailable) {
2690
+ const apiResponse = await apiClient.sendRequest("config");
2691
+ if (!apiResponse.success) {
2692
+ throw new Error(apiResponse.error || "Failed to get onchain config");
2693
+ }
2694
+ const backendConfig = apiResponse.data;
2695
+ finalConfig = {
2696
+ integratorId: backendConfig.integratorId,
2697
+ walletsConfig: {
2698
+ embeddedWalletConfig: {
2699
+ provider: {
2700
+ type: "privy",
2701
+ providerConfig: {
2702
+ appId: backendConfig.privyAppId,
2703
+ appSecret: backendConfig.privyAppSecret
2704
+ }
2705
+ }
2706
+ },
2707
+ smartWalletConfig: {
2708
+ provider: {
2709
+ type: "default"
2710
+ }
2711
+ }
2712
+ },
2713
+ chain: {
2714
+ chainId: config.chainId || backendConfig.chainId,
2715
+ rpcUrl: backendConfig.rpcUrl,
2716
+ bundlerUrl: backendConfig.bundlerUrl
2717
+ },
2718
+ protocolsSecurityConfig: config.protocolsSecurityConfig,
2719
+ coinbaseCDPConfig: {
2720
+ apiKeyId: backendConfig.coinbaseCdpApiKey,
2721
+ apiKeySecret: backendConfig.coinbaseCdpApiKeySecret
2722
+ }
2723
+ };
2724
+ const sdk2 = new _MyceliumSDK(finalConfig, isPremiumAvailable, apiClient);
2725
+ sdk2.apiClient = apiClient;
2726
+ return sdk2;
2727
+ }
2728
+ }
2729
+ finalConfig = config;
2730
+ const sdk = new _MyceliumSDK(finalConfig, isPremiumAvailable);
2731
+ return sdk;
2395
2732
  }
2396
2733
  /**
2397
2734
  * Returns the chain manager instance for multi-chain operations
@@ -2429,10 +2766,13 @@ var MyceliumSDK = class {
2429
2766
  * @param config Protocol router configuration (e.g. risk level)
2430
2767
  * @returns Selected protocol object of the type {@link Protocol}
2431
2768
  */
2432
- findProtocol(config) {
2433
- const protocolRouter = new ProtocolRouter(config, this.chainManager);
2434
- const protocol = protocolRouter.recommend();
2435
- protocol.instance.init(this.chainManager);
2769
+ selectProtocol(config, isPremiumAvailable, apiClient) {
2770
+ const protocolRouter = new ProtocolRouter(this.chainManager, isPremiumAvailable);
2771
+ const protocol = protocolRouter.select();
2772
+ if (!config) {
2773
+ throw new Error("Protocols security config is required");
2774
+ }
2775
+ protocol.init(this.chainManager, config, apiClient);
2436
2776
  return protocol;
2437
2777
  }
2438
2778
  /**