@mycelium-sdk/core 0.1.0 → 1.0.0-alpha.1
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/LICENSE +55 -0
- package/README.md +191 -50
- package/dist/index.cjs +704 -368
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +398 -303
- package/dist/index.d.ts +398 -303
- package/dist/index.js +704 -374
- package/dist/index.js.map +1 -1
- package/package.json +12 -12
package/dist/index.js
CHANGED
|
@@ -348,9 +348,9 @@ var DefaultSmartWallet = class extends SmartWallet {
|
|
|
348
348
|
* @param amount Human-readable amount string
|
|
349
349
|
* @returns Transaction result for the deposit
|
|
350
350
|
*/
|
|
351
|
-
async earn(amount) {
|
|
351
|
+
async earn(vaultInfo, amount) {
|
|
352
352
|
this.chainManager.getSupportedChain();
|
|
353
|
-
const depositTransactionResult = this.protocolProvider.deposit(amount, this);
|
|
353
|
+
const depositTransactionResult = this.protocolProvider.deposit(vaultInfo, amount, this);
|
|
354
354
|
return depositTransactionResult;
|
|
355
355
|
}
|
|
356
356
|
/**
|
|
@@ -361,13 +361,9 @@ var DefaultSmartWallet = class extends SmartWallet {
|
|
|
361
361
|
* @category Earn
|
|
362
362
|
* @returns Vault balance or `null` if nothing deposited
|
|
363
363
|
*/
|
|
364
|
-
async
|
|
365
|
-
const depositedVault = await this.protocolProvider.fetchDepositedVaults(this);
|
|
366
|
-
if (!depositedVault) {
|
|
367
|
-
return null;
|
|
368
|
-
}
|
|
364
|
+
async getEarnBalances() {
|
|
369
365
|
const userAddress = await this.getAddress();
|
|
370
|
-
return this.protocolProvider.
|
|
366
|
+
return this.protocolProvider.getBalances(userAddress);
|
|
371
367
|
}
|
|
372
368
|
/**
|
|
373
369
|
* Withdraws from the selected protocol’s vault
|
|
@@ -378,8 +374,8 @@ var DefaultSmartWallet = class extends SmartWallet {
|
|
|
378
374
|
* @throws Error if the withdrawal fails
|
|
379
375
|
* @throws Error a user didn't deposit anything
|
|
380
376
|
*/
|
|
381
|
-
async withdraw(amount) {
|
|
382
|
-
const withdrawTransactionResult = await this.protocolProvider.withdraw(amount, this);
|
|
377
|
+
async withdraw(vaultInfo, amount) {
|
|
378
|
+
const withdrawTransactionResult = await this.protocolProvider.withdraw(vaultInfo, amount, this);
|
|
383
379
|
return withdrawTransactionResult;
|
|
384
380
|
}
|
|
385
381
|
/**
|
|
@@ -416,7 +412,7 @@ var DefaultSmartWallet = class extends SmartWallet {
|
|
|
416
412
|
return hash;
|
|
417
413
|
} catch (error) {
|
|
418
414
|
throw new Error(
|
|
419
|
-
`Failed to send transaction: ${error instanceof Error ? error.message : "Unknown error"}`
|
|
415
|
+
`Failed to send transaction: ${error instanceof Error ? error.message.toString().slice(0, 100) : "Unknown error"}`
|
|
420
416
|
);
|
|
421
417
|
}
|
|
422
418
|
}
|
|
@@ -461,7 +457,7 @@ var DefaultSmartWallet = class extends SmartWallet {
|
|
|
461
457
|
* Funds the smart wallet with the specified amount of the specified token via Coinbase CDP on-ramp service
|
|
462
458
|
*
|
|
463
459
|
* @public
|
|
464
|
-
* @category
|
|
460
|
+
* @category Funding
|
|
465
461
|
*
|
|
466
462
|
* @remarks
|
|
467
463
|
* If Coinbase CDP is not initialized, the method will throw an error. For more details, visit @see {@link https://docs.cdp.coinbase.com/api-reference/v2/rest-api/onramp/create-an-onramp-session}
|
|
@@ -499,7 +495,7 @@ var DefaultSmartWallet = class extends SmartWallet {
|
|
|
499
495
|
* Cashout token from smart wallet to fiat currency via Coinbase CDP off-ramp service
|
|
500
496
|
*
|
|
501
497
|
* @public
|
|
502
|
-
* @category
|
|
498
|
+
* @category Funding
|
|
503
499
|
*
|
|
504
500
|
* @remarks
|
|
505
501
|
* If Coinbase CDP is not initialized, the method will throw an error. For more details, visit @see {@link https://docs.cdp.coinbase.com/api-reference/rest-api/onramp-offramp/create-sell-quote}
|
|
@@ -575,6 +571,42 @@ var DefaultSmartWallet = class extends SmartWallet {
|
|
|
575
571
|
}
|
|
576
572
|
};
|
|
577
573
|
|
|
574
|
+
// src/ramp/FundingNamespace.ts
|
|
575
|
+
var FundingNamespace = class {
|
|
576
|
+
constructor(coinbaseCDP) {
|
|
577
|
+
this.coinbaseCDP = null;
|
|
578
|
+
if (!coinbaseCDP) {
|
|
579
|
+
throw new Error(
|
|
580
|
+
"Coinbase CDP is not initialized. Please, provide the configuration in the SDK initialization"
|
|
581
|
+
);
|
|
582
|
+
}
|
|
583
|
+
this.coinbaseCDP = coinbaseCDP;
|
|
584
|
+
}
|
|
585
|
+
/**
|
|
586
|
+
* Return all supported countries and payment methods for on-ramp by Coinbase CDP
|
|
587
|
+
* @public
|
|
588
|
+
* @category Funding
|
|
589
|
+
*
|
|
590
|
+
* @returns @see {@link RampConfigResponse} with supported countries and payment methods for top-up
|
|
591
|
+
* @throws If API returned an error
|
|
592
|
+
*/
|
|
593
|
+
async getTopUpConfig() {
|
|
594
|
+
return await this.coinbaseCDP.getOnRampConfig();
|
|
595
|
+
}
|
|
596
|
+
/**
|
|
597
|
+
* Return all supported countries and payment methods for off-ramp by Coinbase CDP
|
|
598
|
+
* @public
|
|
599
|
+
* @category Funding
|
|
600
|
+
*
|
|
601
|
+
*
|
|
602
|
+
* @returns @see {@link RampConfigResponse} with supported countries and payment methods for cash out
|
|
603
|
+
* @throws If API returned an error
|
|
604
|
+
*/
|
|
605
|
+
async getCashOutConfig() {
|
|
606
|
+
return await this.coinbaseCDP.getOffRampConfig();
|
|
607
|
+
}
|
|
608
|
+
};
|
|
609
|
+
|
|
578
610
|
// src/tools/ChainManager.ts
|
|
579
611
|
import { createPublicClient, http } from "viem";
|
|
580
612
|
import {
|
|
@@ -603,127 +635,6 @@ var chainById = Object.values(viemChains).reduce(
|
|
|
603
635
|
{}
|
|
604
636
|
);
|
|
605
637
|
|
|
606
|
-
// src/types/logger.ts
|
|
607
|
-
var LogLevel = /* @__PURE__ */ ((LogLevel2) => {
|
|
608
|
-
LogLevel2[LogLevel2["DEBUG"] = 0] = "DEBUG";
|
|
609
|
-
LogLevel2[LogLevel2["INFO"] = 1] = "INFO";
|
|
610
|
-
LogLevel2[LogLevel2["WARN"] = 2] = "WARN";
|
|
611
|
-
LogLevel2[LogLevel2["ERROR"] = 3] = "ERROR";
|
|
612
|
-
return LogLevel2;
|
|
613
|
-
})(LogLevel || {});
|
|
614
|
-
|
|
615
|
-
// src/tools/Logger.ts
|
|
616
|
-
var Logger = class _Logger {
|
|
617
|
-
/**
|
|
618
|
-
* Create a new logger instance
|
|
619
|
-
* @param logLevel Initial log level, defaults to DEBUG
|
|
620
|
-
*/
|
|
621
|
-
constructor(logLevel = 0 /* DEBUG */) {
|
|
622
|
-
this.logs = [];
|
|
623
|
-
this.maxLogs = 1e3;
|
|
624
|
-
this.logLevel = logLevel;
|
|
625
|
-
}
|
|
626
|
-
/**
|
|
627
|
-
* Get singleton instance of the logger
|
|
628
|
-
* @param logLevel Optional log level to initialize if instance not yet created
|
|
629
|
-
* @returns Logger instance
|
|
630
|
-
*/
|
|
631
|
-
static getInstance(logLevel) {
|
|
632
|
-
if (!_Logger.instance) {
|
|
633
|
-
_Logger.instance = new _Logger(logLevel);
|
|
634
|
-
}
|
|
635
|
-
return _Logger.instance;
|
|
636
|
-
}
|
|
637
|
-
/** Set the log level */
|
|
638
|
-
setLogLevel(level) {
|
|
639
|
-
this.logLevel = level;
|
|
640
|
-
}
|
|
641
|
-
/** Get the current log level */
|
|
642
|
-
getLogLevel() {
|
|
643
|
-
return this.logLevel;
|
|
644
|
-
}
|
|
645
|
-
/** Internal check if a message should be logged */
|
|
646
|
-
shouldLog(level) {
|
|
647
|
-
return level >= this.logLevel;
|
|
648
|
-
}
|
|
649
|
-
/** Format log message into a readable string */
|
|
650
|
-
formatMessage(level, message, data, context) {
|
|
651
|
-
const timestamp = (/* @__PURE__ */ new Date()).toISOString();
|
|
652
|
-
const levelName = LogLevel[level];
|
|
653
|
-
const contextStr = context ? `[${context}]` : "";
|
|
654
|
-
return `${timestamp} ${levelName}${contextStr}: ${message}`;
|
|
655
|
-
}
|
|
656
|
-
/** Add a log entry and output to console */
|
|
657
|
-
addLog(level, message, data, context) {
|
|
658
|
-
if (!this.shouldLog(level)) {
|
|
659
|
-
return;
|
|
660
|
-
}
|
|
661
|
-
const logEntry = {
|
|
662
|
-
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
663
|
-
level,
|
|
664
|
-
message,
|
|
665
|
-
data,
|
|
666
|
-
context
|
|
667
|
-
};
|
|
668
|
-
this.logs.push(logEntry);
|
|
669
|
-
if (this.logs.length > this.maxLogs) {
|
|
670
|
-
this.logs = this.logs.slice(-this.maxLogs);
|
|
671
|
-
}
|
|
672
|
-
const formattedMessage = this.formatMessage(level, message, data, context);
|
|
673
|
-
switch (level) {
|
|
674
|
-
case 0 /* DEBUG */:
|
|
675
|
-
console.debug(`\u{1F50D} ${formattedMessage}`, data || "");
|
|
676
|
-
break;
|
|
677
|
-
case 1 /* INFO */:
|
|
678
|
-
console.info(`\u2139\uFE0F ${formattedMessage}`, data || "");
|
|
679
|
-
break;
|
|
680
|
-
case 2 /* WARN */:
|
|
681
|
-
console.warn(`\u26A0\uFE0F ${formattedMessage}`, data || "");
|
|
682
|
-
break;
|
|
683
|
-
case 3 /* ERROR */:
|
|
684
|
-
console.error(`\u274C ${formattedMessage}`, data || "");
|
|
685
|
-
break;
|
|
686
|
-
}
|
|
687
|
-
}
|
|
688
|
-
/** Log a debug message */
|
|
689
|
-
debug(message, data, context) {
|
|
690
|
-
this.addLog(0 /* DEBUG */, message, data, context);
|
|
691
|
-
}
|
|
692
|
-
/** Log an info message */
|
|
693
|
-
info(message, data, context) {
|
|
694
|
-
this.addLog(1 /* INFO */, message, data, context);
|
|
695
|
-
}
|
|
696
|
-
/** Log a warning message */
|
|
697
|
-
warn(message, data, context) {
|
|
698
|
-
this.addLog(2 /* WARN */, message, data, context);
|
|
699
|
-
}
|
|
700
|
-
/** Log an error message */
|
|
701
|
-
error(message, data, context) {
|
|
702
|
-
this.addLog(3 /* ERROR */, message, data, context);
|
|
703
|
-
}
|
|
704
|
-
/** Get all logs */
|
|
705
|
-
getLogs() {
|
|
706
|
-
return [...this.logs];
|
|
707
|
-
}
|
|
708
|
-
/** Get logs by level */
|
|
709
|
-
getLogsByLevel(level) {
|
|
710
|
-
return this.logs.filter((log) => log.level === level);
|
|
711
|
-
}
|
|
712
|
-
/** Clear all logs */
|
|
713
|
-
clearLogs() {
|
|
714
|
-
this.logs = [];
|
|
715
|
-
}
|
|
716
|
-
/** Export logs as a JSON string */
|
|
717
|
-
exportLogs() {
|
|
718
|
-
return JSON.stringify(this.logs, null, 2);
|
|
719
|
-
}
|
|
720
|
-
/** Set maximum number of logs to retain in memory */
|
|
721
|
-
setMaxLogs(max) {
|
|
722
|
-
this.maxLogs = max;
|
|
723
|
-
}
|
|
724
|
-
};
|
|
725
|
-
var logger = Logger.getInstance();
|
|
726
|
-
|
|
727
638
|
// src/tools/ChainManager.ts
|
|
728
639
|
var ChainManager = class {
|
|
729
640
|
/**
|
|
@@ -779,7 +690,6 @@ var ChainManager = class {
|
|
|
779
690
|
if (!bundlerUrl) {
|
|
780
691
|
throw new Error(`No bundler URL configured for chain ID: ${chainId}`);
|
|
781
692
|
}
|
|
782
|
-
logger.info("Public client setup:", { bundlerUrl, chainId }, "ChainManager");
|
|
783
693
|
const client = createPublicClient({
|
|
784
694
|
chain: this.getChain(chainId),
|
|
785
695
|
transport: http(rpcUrl)
|
|
@@ -882,32 +792,6 @@ var WalletNamespace = class {
|
|
|
882
792
|
constructor(provider) {
|
|
883
793
|
this.provider = provider;
|
|
884
794
|
}
|
|
885
|
-
/**
|
|
886
|
-
* Direct access to the underlying embedded wallet provider
|
|
887
|
-
*
|
|
888
|
-
* @public
|
|
889
|
-
* @category Providers
|
|
890
|
-
* @remarks
|
|
891
|
-
* Useful when you need advanced functionality beyond the unified namespace. By default, you should use the unified namespace
|
|
892
|
-
*
|
|
893
|
-
* @returns The configured embedded wallet provider instance
|
|
894
|
-
*/
|
|
895
|
-
get embeddedWalletProvider() {
|
|
896
|
-
return this.provider.embeddedWalletProvider;
|
|
897
|
-
}
|
|
898
|
-
/**
|
|
899
|
-
* Direct access to the underlying smart wallet provider
|
|
900
|
-
*
|
|
901
|
-
* @public
|
|
902
|
-
* @category Providers
|
|
903
|
-
* @remarks
|
|
904
|
-
* Useful when you need advanced functionality beyond the unified namespace. By default, you should use the unified namespace
|
|
905
|
-
*
|
|
906
|
-
* @returns The configured smart wallet provider instance
|
|
907
|
-
*/
|
|
908
|
-
get smartWalletProvider() {
|
|
909
|
-
return this.provider.smartWalletProvider;
|
|
910
|
-
}
|
|
911
795
|
/**
|
|
912
796
|
* Creates an embedded wallet
|
|
913
797
|
*
|
|
@@ -940,7 +824,7 @@ var WalletNamespace = class {
|
|
|
940
824
|
return this.provider.createSmartWallet(params);
|
|
941
825
|
}
|
|
942
826
|
/**
|
|
943
|
-
*
|
|
827
|
+
* A unified a web3 account: creates a smart wallet with an embedded wallet as signer
|
|
944
828
|
*
|
|
945
829
|
* @public
|
|
946
830
|
* @category Creation
|
|
@@ -954,11 +838,11 @@ var WalletNamespace = class {
|
|
|
954
838
|
* @param params.nonce Optional nonce/salt for deterministic address generation (defaults to 0)
|
|
955
839
|
* @returns Promise that resolves to the created {@link SmartWallet}
|
|
956
840
|
*/
|
|
957
|
-
async
|
|
958
|
-
return this.provider.
|
|
841
|
+
async createAccount(params) {
|
|
842
|
+
return this.provider.createAccount(params);
|
|
959
843
|
}
|
|
960
844
|
/**
|
|
961
|
-
* Gets a smart wallet using an embedded wallet as the signer
|
|
845
|
+
* Gets a unified web3 account: a smart wallet using an embedded wallet as the signer
|
|
962
846
|
*
|
|
963
847
|
* @public
|
|
964
848
|
* @category Retrieval
|
|
@@ -976,8 +860,8 @@ var WalletNamespace = class {
|
|
|
976
860
|
* @returns Promise that resolves to the {@link SmartWallet}
|
|
977
861
|
* @throws Error if the embedded wallet cannot be found
|
|
978
862
|
*/
|
|
979
|
-
async
|
|
980
|
-
return this.provider.
|
|
863
|
+
async getAccount(params) {
|
|
864
|
+
return this.provider.getAccount(params);
|
|
981
865
|
}
|
|
982
866
|
/**
|
|
983
867
|
* Gets an existing embedded wallet by ID
|
|
@@ -1038,7 +922,7 @@ var DefaultSmartWalletProvider = class extends SmartWalletProvider {
|
|
|
1038
922
|
constructor(chainManager, protocol, coinbaseCDP) {
|
|
1039
923
|
super();
|
|
1040
924
|
this.chainManager = chainManager;
|
|
1041
|
-
this.protocolProvider = protocol
|
|
925
|
+
this.protocolProvider = protocol;
|
|
1042
926
|
this.coinbaseCDP = coinbaseCDP;
|
|
1043
927
|
}
|
|
1044
928
|
/**
|
|
@@ -1133,18 +1017,6 @@ var DefaultSmartWalletProvider = class extends SmartWalletProvider {
|
|
|
1133
1017
|
ownerIndex
|
|
1134
1018
|
);
|
|
1135
1019
|
}
|
|
1136
|
-
/**
|
|
1137
|
-
* Funds a wallet via a faucet if supported by the selected chain
|
|
1138
|
-
*
|
|
1139
|
-
* @internal
|
|
1140
|
-
* @category Funding
|
|
1141
|
-
* @remarks
|
|
1142
|
-
* Placeholder for testnet faucet integration
|
|
1143
|
-
*
|
|
1144
|
-
* @returns Future transaction hash or provider response
|
|
1145
|
-
*/
|
|
1146
|
-
fundViaFaucet() {
|
|
1147
|
-
}
|
|
1148
1020
|
};
|
|
1149
1021
|
|
|
1150
1022
|
// src/wallet/WalletProvider.ts
|
|
@@ -1208,9 +1080,12 @@ var WalletProvider = class {
|
|
|
1208
1080
|
* @param params.nonce Optional salt/nonce for deterministic address calculation (defaults to 0)
|
|
1209
1081
|
* @returns Promise that resolves to the created {@link SmartWallet}
|
|
1210
1082
|
*/
|
|
1211
|
-
async
|
|
1083
|
+
async createAccount(params) {
|
|
1212
1084
|
const { owners: ownersParam, embeddedWalletIndex, nonce } = params || {};
|
|
1213
1085
|
const embeddedWallet = await this.embeddedWalletProvider.createWallet();
|
|
1086
|
+
if (!embeddedWallet.walletId) {
|
|
1087
|
+
throw new Error("Failed to create embedded wallet. No wallet ID returned");
|
|
1088
|
+
}
|
|
1214
1089
|
const account = await embeddedWallet.account();
|
|
1215
1090
|
let owners;
|
|
1216
1091
|
if (ownersParam) {
|
|
@@ -1220,14 +1095,18 @@ var WalletProvider = class {
|
|
|
1220
1095
|
} else {
|
|
1221
1096
|
owners = [embeddedWallet.address];
|
|
1222
1097
|
}
|
|
1223
|
-
|
|
1098
|
+
const smartWallet = await this.smartWalletProvider.createWallet({
|
|
1224
1099
|
owners,
|
|
1225
1100
|
signer: account,
|
|
1226
1101
|
nonce
|
|
1227
1102
|
});
|
|
1103
|
+
return {
|
|
1104
|
+
embeddedWalletId: embeddedWallet.walletId,
|
|
1105
|
+
smartWallet
|
|
1106
|
+
};
|
|
1228
1107
|
}
|
|
1229
1108
|
/**
|
|
1230
|
-
* Gets a smart wallet using an embedded wallet as the signer
|
|
1109
|
+
* Gets a unified web3 account: a smart wallet using an embedded wallet as the signer
|
|
1231
1110
|
*
|
|
1232
1111
|
* @internal
|
|
1233
1112
|
* @remarks
|
|
@@ -1244,7 +1123,7 @@ var WalletProvider = class {
|
|
|
1244
1123
|
* @returns Promise that resolves to the {@link SmartWallet}
|
|
1245
1124
|
* @throws Error if the embedded wallet cannot be found
|
|
1246
1125
|
*/
|
|
1247
|
-
async
|
|
1126
|
+
async getAccount(params) {
|
|
1248
1127
|
const { walletId, deploymentOwners, walletAddress } = params;
|
|
1249
1128
|
const embeddedWallet = await this.embeddedWalletProvider.getWallet({
|
|
1250
1129
|
walletId
|
|
@@ -1306,8 +1185,7 @@ var WalletProvider = class {
|
|
|
1306
1185
|
throw new Error(
|
|
1307
1186
|
"Either walletAddress or deploymentOwners array must be provided to locate the smart wallet"
|
|
1308
1187
|
);
|
|
1309
|
-
} catch
|
|
1310
|
-
logger.error("Error getting smart wallet", error, "WalletProvider");
|
|
1188
|
+
} catch {
|
|
1311
1189
|
throw new Error(
|
|
1312
1190
|
"Either walletAddress or deploymentOwners array must be provided to locate the smart wallet"
|
|
1313
1191
|
);
|
|
@@ -1353,6 +1231,127 @@ var EmbeddedWallet = class {
|
|
|
1353
1231
|
}
|
|
1354
1232
|
};
|
|
1355
1233
|
|
|
1234
|
+
// src/types/logger.ts
|
|
1235
|
+
var LogLevel = /* @__PURE__ */ ((LogLevel2) => {
|
|
1236
|
+
LogLevel2[LogLevel2["DEBUG"] = 0] = "DEBUG";
|
|
1237
|
+
LogLevel2[LogLevel2["INFO"] = 1] = "INFO";
|
|
1238
|
+
LogLevel2[LogLevel2["WARN"] = 2] = "WARN";
|
|
1239
|
+
LogLevel2[LogLevel2["ERROR"] = 3] = "ERROR";
|
|
1240
|
+
return LogLevel2;
|
|
1241
|
+
})(LogLevel || {});
|
|
1242
|
+
|
|
1243
|
+
// src/tools/Logger.ts
|
|
1244
|
+
var Logger = class _Logger {
|
|
1245
|
+
/**
|
|
1246
|
+
* Create a new logger instance
|
|
1247
|
+
* @param logLevel Initial log level, defaults to DEBUG
|
|
1248
|
+
*/
|
|
1249
|
+
constructor(logLevel = 0 /* DEBUG */) {
|
|
1250
|
+
this.logs = [];
|
|
1251
|
+
this.maxLogs = 1e3;
|
|
1252
|
+
this.logLevel = logLevel;
|
|
1253
|
+
}
|
|
1254
|
+
/**
|
|
1255
|
+
* Get singleton instance of the logger
|
|
1256
|
+
* @param logLevel Optional log level to initialize if instance not yet created
|
|
1257
|
+
* @returns Logger instance
|
|
1258
|
+
*/
|
|
1259
|
+
static getInstance(logLevel) {
|
|
1260
|
+
if (!_Logger.instance) {
|
|
1261
|
+
_Logger.instance = new _Logger(logLevel);
|
|
1262
|
+
}
|
|
1263
|
+
return _Logger.instance;
|
|
1264
|
+
}
|
|
1265
|
+
/** Set the log level */
|
|
1266
|
+
setLogLevel(level) {
|
|
1267
|
+
this.logLevel = level;
|
|
1268
|
+
}
|
|
1269
|
+
/** Get the current log level */
|
|
1270
|
+
getLogLevel() {
|
|
1271
|
+
return this.logLevel;
|
|
1272
|
+
}
|
|
1273
|
+
/** Internal check if a message should be logged */
|
|
1274
|
+
shouldLog(level) {
|
|
1275
|
+
return level >= this.logLevel;
|
|
1276
|
+
}
|
|
1277
|
+
/** Format log message into a readable string */
|
|
1278
|
+
formatMessage(level, message, data, context) {
|
|
1279
|
+
const timestamp = (/* @__PURE__ */ new Date()).toISOString();
|
|
1280
|
+
const levelName = LogLevel[level];
|
|
1281
|
+
const contextStr = context ? `[${context}]` : "";
|
|
1282
|
+
return `${timestamp} ${levelName}${contextStr}: ${message}`;
|
|
1283
|
+
}
|
|
1284
|
+
/** Add a log entry and output to console */
|
|
1285
|
+
addLog(level, message, data, context) {
|
|
1286
|
+
if (!this.shouldLog(level)) {
|
|
1287
|
+
return;
|
|
1288
|
+
}
|
|
1289
|
+
const logEntry = {
|
|
1290
|
+
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
1291
|
+
level,
|
|
1292
|
+
message,
|
|
1293
|
+
data,
|
|
1294
|
+
context
|
|
1295
|
+
};
|
|
1296
|
+
this.logs.push(logEntry);
|
|
1297
|
+
if (this.logs.length > this.maxLogs) {
|
|
1298
|
+
this.logs = this.logs.slice(-this.maxLogs);
|
|
1299
|
+
}
|
|
1300
|
+
const formattedMessage = this.formatMessage(level, message, data, context);
|
|
1301
|
+
switch (level) {
|
|
1302
|
+
case 0 /* DEBUG */:
|
|
1303
|
+
console.debug(`\u{1F50D} ${formattedMessage}`, data || "");
|
|
1304
|
+
break;
|
|
1305
|
+
case 1 /* INFO */:
|
|
1306
|
+
console.info(`\u2139\uFE0F ${formattedMessage}`, data || "");
|
|
1307
|
+
break;
|
|
1308
|
+
case 2 /* WARN */:
|
|
1309
|
+
console.warn(`\u26A0\uFE0F ${formattedMessage}`, data || "");
|
|
1310
|
+
break;
|
|
1311
|
+
case 3 /* ERROR */:
|
|
1312
|
+
console.error(`\u274C ${formattedMessage}`, data || "");
|
|
1313
|
+
break;
|
|
1314
|
+
}
|
|
1315
|
+
}
|
|
1316
|
+
/** Log a debug message */
|
|
1317
|
+
debug(message, data, context) {
|
|
1318
|
+
this.addLog(0 /* DEBUG */, message, data, context);
|
|
1319
|
+
}
|
|
1320
|
+
/** Log an info message */
|
|
1321
|
+
info(message, data, context) {
|
|
1322
|
+
this.addLog(1 /* INFO */, message, data, context);
|
|
1323
|
+
}
|
|
1324
|
+
/** Log a warning message */
|
|
1325
|
+
warn(message, data, context) {
|
|
1326
|
+
this.addLog(2 /* WARN */, message, data, context);
|
|
1327
|
+
}
|
|
1328
|
+
/** Log an error message */
|
|
1329
|
+
error(message, data, context) {
|
|
1330
|
+
this.addLog(3 /* ERROR */, message, data, context);
|
|
1331
|
+
}
|
|
1332
|
+
/** Get all logs */
|
|
1333
|
+
getLogs() {
|
|
1334
|
+
return [...this.logs];
|
|
1335
|
+
}
|
|
1336
|
+
/** Get logs by level */
|
|
1337
|
+
getLogsByLevel(level) {
|
|
1338
|
+
return this.logs.filter((log) => log.level === level);
|
|
1339
|
+
}
|
|
1340
|
+
/** Clear all logs */
|
|
1341
|
+
clearLogs() {
|
|
1342
|
+
this.logs = [];
|
|
1343
|
+
}
|
|
1344
|
+
/** Export logs as a JSON string */
|
|
1345
|
+
exportLogs() {
|
|
1346
|
+
return JSON.stringify(this.logs, null, 2);
|
|
1347
|
+
}
|
|
1348
|
+
/** Set maximum number of logs to retain in memory */
|
|
1349
|
+
setMaxLogs(max) {
|
|
1350
|
+
this.maxLogs = max;
|
|
1351
|
+
}
|
|
1352
|
+
};
|
|
1353
|
+
var logger = Logger.getInstance();
|
|
1354
|
+
|
|
1356
1355
|
// src/wallet/PrivyWallet.ts
|
|
1357
1356
|
var PrivyWallet = class extends EmbeddedWallet {
|
|
1358
1357
|
/**
|
|
@@ -1676,12 +1675,7 @@ var BaseProtocol = class {
|
|
|
1676
1675
|
};
|
|
1677
1676
|
|
|
1678
1677
|
// src/protocols/implementations/SparkProtocol.ts
|
|
1679
|
-
import {
|
|
1680
|
-
encodeFunctionData as encodeFunctionData2,
|
|
1681
|
-
erc20Abi as erc20Abi4,
|
|
1682
|
-
formatUnits as formatUnits2,
|
|
1683
|
-
parseUnits as parseUnits2
|
|
1684
|
-
} from "viem";
|
|
1678
|
+
import { encodeFunctionData as encodeFunctionData2, erc20Abi as erc20Abi4, formatUnits as formatUnits2, parseUnits as parseUnits2 } from "viem";
|
|
1685
1679
|
|
|
1686
1680
|
// src/abis/protocols/spark.ts
|
|
1687
1681
|
var SPARK_VAULT_ABI = [
|
|
@@ -1743,14 +1737,14 @@ var SPARK_SSR_ORACLE_ADDRESS = "0x65d946e533748A998B1f0E430803e39A6388f7a1";
|
|
|
1743
1737
|
var SPARK_VAULT = [
|
|
1744
1738
|
{
|
|
1745
1739
|
id: "sUSDC",
|
|
1740
|
+
protocolId: "spark",
|
|
1741
|
+
name: "sUSDC",
|
|
1742
|
+
type: "stable",
|
|
1746
1743
|
chain: "base",
|
|
1747
1744
|
vaultAddress: "0x3128a0f7f0ea68e7b7c9b00afa7e41045828e858",
|
|
1748
|
-
|
|
1749
|
-
|
|
1750
|
-
|
|
1751
|
-
earnTokenAddress: "0x833589fcd6edb6e08f4c7c32d4f71b54bda02913",
|
|
1752
|
-
earnTokenDecimals: 18,
|
|
1753
|
-
earnTokenSymbol: "sUSDC",
|
|
1745
|
+
tokenAddress: "0x833589fcd6edb6e08f4c7c32d4f71b54bda02913",
|
|
1746
|
+
tokenDecimals: 6,
|
|
1747
|
+
tokenSymbol: "USDC",
|
|
1754
1748
|
metadata: {}
|
|
1755
1749
|
}
|
|
1756
1750
|
];
|
|
@@ -1761,6 +1755,7 @@ var RAY = BigInt("1000000000000000000000000000");
|
|
|
1761
1755
|
var SparkProtocol = class extends BaseProtocol {
|
|
1762
1756
|
constructor() {
|
|
1763
1757
|
super(...arguments);
|
|
1758
|
+
/** All Spark vaults */
|
|
1764
1759
|
this.allVaults = [];
|
|
1765
1760
|
}
|
|
1766
1761
|
/**
|
|
@@ -1771,7 +1766,7 @@ var SparkProtocol = class extends BaseProtocol {
|
|
|
1771
1766
|
this.chainManager = chainManager;
|
|
1772
1767
|
this.selectedChainId = chainManager.getSupportedChain();
|
|
1773
1768
|
this.publicClient = chainManager.getPublicClient(this.selectedChainId);
|
|
1774
|
-
this.allVaults =
|
|
1769
|
+
this.allVaults = SPARK_VAULT;
|
|
1775
1770
|
}
|
|
1776
1771
|
/**
|
|
1777
1772
|
* Get the SSR (Sky Saving Rate) of the Spark protocol
|
|
@@ -1801,88 +1796,54 @@ var SparkProtocol = class extends BaseProtocol {
|
|
|
1801
1796
|
async getAPY() {
|
|
1802
1797
|
const ssr = await this.getSSR();
|
|
1803
1798
|
const apy = Math.exp(Math.log(ssr) * SECONDS_PER_YEAR) - 1;
|
|
1804
|
-
return
|
|
1799
|
+
return apy;
|
|
1805
1800
|
}
|
|
1806
1801
|
/**
|
|
1807
|
-
*
|
|
1808
|
-
*
|
|
1809
|
-
* @returns
|
|
1810
|
-
*/
|
|
1811
|
-
getVaults() {
|
|
1812
|
-
return SPARK_VAULT;
|
|
1813
|
-
}
|
|
1814
|
-
/**
|
|
1815
|
-
* Get the best available Spark vault
|
|
1816
|
-
* @returns The top-ranked Spark vault
|
|
1802
|
+
* Get the best available Spark vaults
|
|
1803
|
+
* @remarks Currently, the vault is only one and relates to sUSDC. Currently return only one stable vault
|
|
1804
|
+
* @returns Best Spark vaults in 2 groups: stable and non-stable
|
|
1817
1805
|
* @throws Error if no vaults found
|
|
1818
1806
|
*/
|
|
1819
|
-
async
|
|
1807
|
+
async getBestVaults() {
|
|
1820
1808
|
if (this.allVaults.length === 0) {
|
|
1821
1809
|
throw new Error("No vaults found");
|
|
1822
1810
|
}
|
|
1823
1811
|
const selectedVault = this.allVaults[0];
|
|
1824
1812
|
selectedVault.metadata.apy = await this.getAPY();
|
|
1825
|
-
return
|
|
1826
|
-
|
|
1827
|
-
|
|
1828
|
-
|
|
1829
|
-
* @param smartWallet Smart wallet to inspect
|
|
1830
|
-
* @returns The vault with user deposits, or null if none found
|
|
1831
|
-
*/
|
|
1832
|
-
async fetchDepositedVaults(smartWallet) {
|
|
1833
|
-
let depositedVault = void 0;
|
|
1834
|
-
const userAddress = await smartWallet.getAddress();
|
|
1835
|
-
for (const vault of this.allVaults) {
|
|
1836
|
-
const balance = await this.getBalance(vault, userAddress);
|
|
1837
|
-
if (parseInt(balance.depositedAmount) > 0) {
|
|
1838
|
-
depositedVault = vault;
|
|
1839
|
-
}
|
|
1840
|
-
}
|
|
1841
|
-
if (depositedVault) {
|
|
1842
|
-
depositedVault.metadata.apy = await this.getAPY();
|
|
1843
|
-
}
|
|
1844
|
-
logger.info("Deposited vaults:", { depositedVault }, "SparkProtocol");
|
|
1845
|
-
return depositedVault || null;
|
|
1813
|
+
return {
|
|
1814
|
+
stable: [selectedVault],
|
|
1815
|
+
nonStable: []
|
|
1816
|
+
};
|
|
1846
1817
|
}
|
|
1847
1818
|
/**
|
|
1848
1819
|
* Deposit funds into a Spark vault
|
|
1820
|
+
* @param vaultInfo Vault information
|
|
1849
1821
|
* @param amount Amount to deposit (human-readable)
|
|
1850
1822
|
* @param smartWallet Smart wallet instance to use
|
|
1851
1823
|
* @returns Transaction result with hash
|
|
1852
1824
|
*/
|
|
1853
|
-
async deposit(amount, smartWallet) {
|
|
1854
|
-
const depositedVault = await this.fetchDepositedVaults(smartWallet);
|
|
1855
|
-
let vaultInfoToDeposit;
|
|
1856
|
-
logger.info("Previously deposited vault:", { depositedVault }, "SparkProtocol");
|
|
1857
|
-
if (depositedVault) {
|
|
1858
|
-
vaultInfoToDeposit = depositedVault;
|
|
1859
|
-
} else {
|
|
1860
|
-
vaultInfoToDeposit = await this.getBestVault();
|
|
1861
|
-
logger.info("Best vault that found:", { bestVault: vaultInfoToDeposit }, "SparkProtocol");
|
|
1862
|
-
}
|
|
1825
|
+
async deposit(vaultInfo, amount, smartWallet) {
|
|
1863
1826
|
const owner = await smartWallet.getAddress();
|
|
1864
|
-
const assets = parseUnits2(amount,
|
|
1865
|
-
logger.info("Raw deposit amount:", { amount, assets }, "SparkProtocol");
|
|
1827
|
+
const assets = parseUnits2(amount, vaultInfo.tokenDecimals);
|
|
1866
1828
|
const allowance = await this.checkAllowance(
|
|
1867
|
-
|
|
1868
|
-
|
|
1829
|
+
vaultInfo.tokenAddress,
|
|
1830
|
+
vaultInfo.vaultAddress,
|
|
1869
1831
|
owner,
|
|
1870
1832
|
this.selectedChainId
|
|
1871
1833
|
);
|
|
1872
|
-
logger.info("Current vault contract allowance:", { allowance }, "SparkProtocol");
|
|
1873
1834
|
const ops = [];
|
|
1874
1835
|
if (allowance < assets) {
|
|
1875
1836
|
ops.push({
|
|
1876
|
-
to:
|
|
1837
|
+
to: vaultInfo.tokenAddress,
|
|
1877
1838
|
data: encodeFunctionData2({
|
|
1878
1839
|
abi: erc20Abi4,
|
|
1879
1840
|
functionName: "approve",
|
|
1880
|
-
args: [
|
|
1841
|
+
args: [vaultInfo.vaultAddress, assets]
|
|
1881
1842
|
})
|
|
1882
1843
|
});
|
|
1883
1844
|
}
|
|
1884
1845
|
ops.push({
|
|
1885
|
-
to:
|
|
1846
|
+
to: vaultInfo.vaultAddress,
|
|
1886
1847
|
data: encodeFunctionData2({
|
|
1887
1848
|
abi: SPARK_VAULT_ABI,
|
|
1888
1849
|
functionName: "deposit",
|
|
@@ -1894,23 +1855,19 @@ var SparkProtocol = class extends BaseProtocol {
|
|
|
1894
1855
|
}
|
|
1895
1856
|
/**
|
|
1896
1857
|
* Withdraw funds from a Spark vault
|
|
1897
|
-
* @param
|
|
1858
|
+
* @param vaultInfo Vault information
|
|
1859
|
+
* @param amount Amount in base token units (or undefined to withdraw all)
|
|
1898
1860
|
* @param smartWallet Smart wallet instance to withdraw from
|
|
1899
1861
|
* @returns Transaction result with hash
|
|
1900
1862
|
* @throws Error if no deposited vault found
|
|
1901
1863
|
*/
|
|
1902
|
-
async withdraw(
|
|
1903
|
-
const depositedVault = await this.fetchDepositedVaults(smartWallet);
|
|
1904
|
-
if (!depositedVault) {
|
|
1905
|
-
throw new Error("No vault found to withdraw from");
|
|
1906
|
-
}
|
|
1864
|
+
async withdraw(vaultInfo, amount, smartWallet) {
|
|
1907
1865
|
const owner = await smartWallet.getAddress();
|
|
1908
1866
|
let withdrawData;
|
|
1909
|
-
if (
|
|
1910
|
-
const assets = parseUnits2(
|
|
1911
|
-
logger.info("Withdraw amount:", { amountInUnderlying, assets }, "SparkProtocol");
|
|
1867
|
+
if (amount) {
|
|
1868
|
+
const assets = parseUnits2(amount, vaultInfo.tokenDecimals);
|
|
1912
1869
|
withdrawData = {
|
|
1913
|
-
to:
|
|
1870
|
+
to: vaultInfo.vaultAddress,
|
|
1914
1871
|
data: encodeFunctionData2({
|
|
1915
1872
|
abi: SPARK_VAULT_ABI,
|
|
1916
1873
|
functionName: "withdraw",
|
|
@@ -1918,10 +1875,9 @@ var SparkProtocol = class extends BaseProtocol {
|
|
|
1918
1875
|
})
|
|
1919
1876
|
};
|
|
1920
1877
|
} else {
|
|
1921
|
-
const maxShares = await this.getMaxRedeemableShares(
|
|
1922
|
-
logger.info("Withdrawing all funds:", { maxShares }, "SparkProtocol");
|
|
1878
|
+
const maxShares = await this.getMaxRedeemableShares(vaultInfo, owner);
|
|
1923
1879
|
withdrawData = {
|
|
1924
|
-
to:
|
|
1880
|
+
to: vaultInfo.vaultAddress,
|
|
1925
1881
|
data: encodeFunctionData2({
|
|
1926
1882
|
abi: SPARK_VAULT_ABI,
|
|
1927
1883
|
functionName: "redeem",
|
|
@@ -1930,7 +1886,6 @@ var SparkProtocol = class extends BaseProtocol {
|
|
|
1930
1886
|
};
|
|
1931
1887
|
}
|
|
1932
1888
|
const hash = await smartWallet.send(withdrawData, this.selectedChainId);
|
|
1933
|
-
logger.info("Withdraw transaction sent:", { hash }, "SparkProtocol");
|
|
1934
1889
|
return { success: true, hash };
|
|
1935
1890
|
}
|
|
1936
1891
|
/**
|
|
@@ -1953,14 +1908,15 @@ var SparkProtocol = class extends BaseProtocol {
|
|
|
1953
1908
|
}
|
|
1954
1909
|
/**
|
|
1955
1910
|
* Get amount that a wallet has deposited in a vault
|
|
1956
|
-
* @param vaultInfo Vault information
|
|
1957
1911
|
* @param walletAddress Wallet address to check
|
|
1958
|
-
* @returns
|
|
1912
|
+
* @returns Array of vault balances with vaults info
|
|
1959
1913
|
*/
|
|
1960
|
-
async
|
|
1914
|
+
async getBalances(walletAddress) {
|
|
1961
1915
|
if (!this.publicClient) {
|
|
1962
1916
|
throw new Error("Public client not initialized");
|
|
1963
1917
|
}
|
|
1918
|
+
const vaultInfo = SPARK_VAULT[0];
|
|
1919
|
+
vaultInfo.metadata.apy = await this.getAPY();
|
|
1964
1920
|
const shares = await this.publicClient.readContract({
|
|
1965
1921
|
address: vaultInfo.vaultAddress,
|
|
1966
1922
|
abi: SPARK_VAULT_ABI,
|
|
@@ -1968,7 +1924,7 @@ var SparkProtocol = class extends BaseProtocol {
|
|
|
1968
1924
|
args: [walletAddress]
|
|
1969
1925
|
});
|
|
1970
1926
|
if (shares === 0n) {
|
|
1971
|
-
return {
|
|
1927
|
+
return [{ balance: null, vaultInfo }];
|
|
1972
1928
|
}
|
|
1973
1929
|
const assets = await this.publicClient.readContract({
|
|
1974
1930
|
address: vaultInfo.vaultAddress,
|
|
@@ -1976,11 +1932,12 @@ var SparkProtocol = class extends BaseProtocol {
|
|
|
1976
1932
|
functionName: "convertToAssets",
|
|
1977
1933
|
args: [shares]
|
|
1978
1934
|
});
|
|
1979
|
-
return
|
|
1980
|
-
|
|
1981
|
-
|
|
1982
|
-
|
|
1983
|
-
|
|
1935
|
+
return [
|
|
1936
|
+
{
|
|
1937
|
+
balance: formatUnits2(assets, vaultInfo.tokenDecimals),
|
|
1938
|
+
vaultInfo
|
|
1939
|
+
}
|
|
1940
|
+
];
|
|
1984
1941
|
}
|
|
1985
1942
|
};
|
|
1986
1943
|
|
|
@@ -1992,59 +1949,233 @@ var availableProtocols = [
|
|
|
1992
1949
|
name: "Spark",
|
|
1993
1950
|
website: "https://spark.fi/",
|
|
1994
1951
|
logo: "/logos/spark.png",
|
|
1995
|
-
supportedChains: [
|
|
1952
|
+
supportedChains: [8453],
|
|
1996
1953
|
riskLevel: "low",
|
|
1997
|
-
|
|
1954
|
+
isActive: true
|
|
1998
1955
|
},
|
|
1999
1956
|
instance: new SparkProtocol()
|
|
2000
1957
|
}
|
|
2001
1958
|
];
|
|
2002
1959
|
|
|
2003
|
-
// src/
|
|
2004
|
-
|
|
2005
|
-
|
|
1960
|
+
// src/protocols/implementations/ProxyProtocol.ts
|
|
1961
|
+
import { encodeFunctionData as encodeFunctionData3, erc20Abi as erc20Abi5, parseUnits as parseUnits3 } from "viem";
|
|
1962
|
+
var ProxyProtocol = class extends BaseProtocol {
|
|
2006
1963
|
/**
|
|
2007
|
-
*
|
|
2008
|
-
*
|
|
2009
|
-
* @internal
|
|
2010
|
-
* @param apiKey API key from {@link ProtocolsRouterConfig}
|
|
2011
|
-
* @returns True if the API key is considered valid
|
|
1964
|
+
* Initialize the Spark protocol with the provided chain manager
|
|
1965
|
+
* @param chainManager Chain manager instance used for network operations
|
|
2012
1966
|
*/
|
|
2013
|
-
|
|
2014
|
-
logger.info("Validating api key...", apiKey, "ApiKeysValidator");
|
|
2015
|
-
return true;
|
|
2016
|
-
}
|
|
2017
|
-
};
|
|
2018
|
-
|
|
2019
|
-
// src/router/base/ProtocolRouterBase.ts
|
|
2020
|
-
var ProtocolRouterBase = class {
|
|
2021
|
-
/**
|
|
2022
|
-
* Initialize a base protocol router
|
|
2023
|
-
* @param riskLevel Risk level required by the integrator
|
|
2024
|
-
* @param chainManager Chain manager instance for network operations
|
|
2025
|
-
* @param minApy Optional minimum APY filter
|
|
2026
|
-
* @param apiKey Optional API key for premium protocol access
|
|
2027
|
-
*/
|
|
2028
|
-
constructor(riskLevel, chainManager, minApy, apiKey) {
|
|
2029
|
-
// TODO: Add an API key validation
|
|
2030
|
-
/** API key validator instance */
|
|
2031
|
-
this.apiKeyValidator = new ApiKeysValidator();
|
|
2032
|
-
this.riskLevel = riskLevel;
|
|
2033
|
-
this.minApy = minApy;
|
|
2034
|
-
this.apiKey = apiKey;
|
|
1967
|
+
async init(chainManager, protocolsSecurityConfig, apiClient) {
|
|
2035
1968
|
this.chainManager = chainManager;
|
|
1969
|
+
this.selectedChainId = chainManager.getSupportedChain();
|
|
1970
|
+
this.publicClient = chainManager.getPublicClient(this.selectedChainId);
|
|
1971
|
+
this.apiClient = apiClient;
|
|
1972
|
+
this.protocolsSecurityConfig = protocolsSecurityConfig;
|
|
1973
|
+
}
|
|
1974
|
+
/**
|
|
1975
|
+
* Log a vault-related operation after deposit or withdraw funds
|
|
1976
|
+
* @param userAddress Address of the user who performed the operation
|
|
1977
|
+
* @param hash Hash of the operation
|
|
1978
|
+
* @param vaultInfo Information about the vault where the operation was performed
|
|
1979
|
+
* @param chainId Chain ID where the operation was performed
|
|
1980
|
+
* @param amount Amount of the operation
|
|
1981
|
+
* @param operationType Type of the operation
|
|
1982
|
+
* @param operationStatus Status of the operation
|
|
1983
|
+
*/
|
|
1984
|
+
async logOperation(userAddress, hash, vaultInfo, chainId, amount, operationType, operationStatus) {
|
|
1985
|
+
const apiResponse = await this.apiClient.sendRequest("log", void 0, void 0, {
|
|
1986
|
+
userAddress,
|
|
1987
|
+
protocolId: vaultInfo.protocolId,
|
|
1988
|
+
vaultAddress: vaultInfo.vaultAddress,
|
|
1989
|
+
transactionHash: hash,
|
|
1990
|
+
chainId: chainId.toString(),
|
|
1991
|
+
amount,
|
|
1992
|
+
status: operationStatus,
|
|
1993
|
+
operationType
|
|
1994
|
+
});
|
|
1995
|
+
if (!apiResponse.success) {
|
|
1996
|
+
throw new Error(
|
|
1997
|
+
apiResponse.error || `Failed to log operation: ${operationType} for vault: ${vaultInfo}`
|
|
1998
|
+
);
|
|
1999
|
+
}
|
|
2000
|
+
}
|
|
2001
|
+
/**
|
|
2002
|
+
* Get the best vaults to deposit funds
|
|
2003
|
+
* @param stableVaultsLimit Limit of stable vaults to get. Optional, default is 1
|
|
2004
|
+
* @param nonStableVaultsLimit Limit of non-stable vaults to get. Optional, default is 1
|
|
2005
|
+
* @returns Best vaults to deposit funds in 2 groups: stable and non-stable
|
|
2006
|
+
*/
|
|
2007
|
+
async getBestVaults(stableVaultsLimit = 1, nonStableVaultsLimit = 1) {
|
|
2008
|
+
const pathParams = {
|
|
2009
|
+
risk_level: this.protocolsSecurityConfig.riskLevel,
|
|
2010
|
+
chain_id: this.selectedChainId.toString(),
|
|
2011
|
+
stable_vaults_limit: stableVaultsLimit.toString(),
|
|
2012
|
+
non_stable_vaults_limit: nonStableVaultsLimit.toString()
|
|
2013
|
+
};
|
|
2014
|
+
const apiResponse = await this.apiClient.sendRequest("vaults", pathParams);
|
|
2015
|
+
if (!apiResponse.success) {
|
|
2016
|
+
throw new Error(apiResponse.error || "Failed to get best vaults");
|
|
2017
|
+
}
|
|
2018
|
+
const vaults = apiResponse.data;
|
|
2019
|
+
return {
|
|
2020
|
+
stable: vaults.stableVaults.map((vault) => {
|
|
2021
|
+
return {
|
|
2022
|
+
...vault,
|
|
2023
|
+
metadata: {
|
|
2024
|
+
apy: vault.metadata?.apy,
|
|
2025
|
+
poolTvlUsd: vault.metadata?.poolTvlUsd
|
|
2026
|
+
}
|
|
2027
|
+
};
|
|
2028
|
+
}),
|
|
2029
|
+
nonStable: vaults.nonStableVaults.map((vault) => {
|
|
2030
|
+
return {
|
|
2031
|
+
...vault,
|
|
2032
|
+
metadata: {
|
|
2033
|
+
apy: vault.metadata?.apy,
|
|
2034
|
+
poolTvlUsd: vault.metadata?.poolTvlUsd
|
|
2035
|
+
}
|
|
2036
|
+
};
|
|
2037
|
+
})
|
|
2038
|
+
};
|
|
2039
|
+
}
|
|
2040
|
+
/**
|
|
2041
|
+
* Deposit funds to a provided vault
|
|
2042
|
+
* @param vaultInfo Information about the vault to deposit funds to
|
|
2043
|
+
* @param amount Amount of funds to deposit
|
|
2044
|
+
* @param smartWallet Smart wallet to use for the deposit
|
|
2045
|
+
* @returns Result of the deposit transaction
|
|
2046
|
+
*/
|
|
2047
|
+
async deposit(vaultInfo, amount, smartWallet) {
|
|
2048
|
+
const currentAddress = await smartWallet.getAddress();
|
|
2049
|
+
const operationsCallData = [];
|
|
2050
|
+
const depositTokenDecimals = vaultInfo.tokenDecimals;
|
|
2051
|
+
const depositTokenAddress = vaultInfo.tokenAddress;
|
|
2052
|
+
const vaultAddress = vaultInfo.vaultAddress;
|
|
2053
|
+
const rawDepositAmount = parseUnits3(amount, depositTokenDecimals);
|
|
2054
|
+
const allowance = await this.checkAllowance(
|
|
2055
|
+
depositTokenAddress,
|
|
2056
|
+
vaultAddress,
|
|
2057
|
+
currentAddress,
|
|
2058
|
+
this.selectedChainId
|
|
2059
|
+
);
|
|
2060
|
+
if (allowance < rawDepositAmount) {
|
|
2061
|
+
const approveData = {
|
|
2062
|
+
to: depositTokenAddress,
|
|
2063
|
+
data: encodeFunctionData3({
|
|
2064
|
+
abi: erc20Abi5,
|
|
2065
|
+
functionName: "approve",
|
|
2066
|
+
args: [vaultAddress, rawDepositAmount]
|
|
2067
|
+
})
|
|
2068
|
+
};
|
|
2069
|
+
operationsCallData.push(approveData);
|
|
2070
|
+
}
|
|
2071
|
+
if (!vaultInfo.protocolId) {
|
|
2072
|
+
throw new Error("Vault protocol ID is required");
|
|
2073
|
+
}
|
|
2074
|
+
const apiResponse = await this.apiClient.sendRequest(
|
|
2075
|
+
"deposit",
|
|
2076
|
+
void 0,
|
|
2077
|
+
vaultInfo.protocolId,
|
|
2078
|
+
{
|
|
2079
|
+
vaultInfo,
|
|
2080
|
+
amount: amount.toString(),
|
|
2081
|
+
chainId: this.selectedChainId.toString()
|
|
2082
|
+
}
|
|
2083
|
+
);
|
|
2084
|
+
if (!apiResponse.success) {
|
|
2085
|
+
throw new Error(apiResponse.error || "Failed to receive deposit operations call data");
|
|
2086
|
+
}
|
|
2087
|
+
const receivedOperationsCallData = apiResponse.data;
|
|
2088
|
+
operationsCallData.push(receivedOperationsCallData);
|
|
2089
|
+
const hash = await smartWallet.sendBatch(operationsCallData, this.selectedChainId);
|
|
2090
|
+
const operationStatus = hash ? "completed" : "failed";
|
|
2091
|
+
this.logOperation(
|
|
2092
|
+
currentAddress,
|
|
2093
|
+
hash,
|
|
2094
|
+
vaultInfo,
|
|
2095
|
+
this.selectedChainId,
|
|
2096
|
+
amount,
|
|
2097
|
+
"deposit",
|
|
2098
|
+
operationStatus
|
|
2099
|
+
);
|
|
2100
|
+
return { hash, success: true };
|
|
2101
|
+
}
|
|
2102
|
+
/**
|
|
2103
|
+
* Withdraw funds from a provided vault
|
|
2104
|
+
* @param vaultInfo Information about the vault to withdraw funds from
|
|
2105
|
+
* @param amount Amount of funds to withdraw
|
|
2106
|
+
* @param smartWallet Smart wallet to use for the withdrawal
|
|
2107
|
+
* @returns Result of the withdrawal transaction
|
|
2108
|
+
*/
|
|
2109
|
+
async withdraw(vaultInfo, amount, smartWallet) {
|
|
2110
|
+
const currentAddress = await smartWallet.getAddress();
|
|
2111
|
+
const earningBalances = await smartWallet.getEarnBalances();
|
|
2112
|
+
if (!earningBalances) {
|
|
2113
|
+
throw new Error("No earning balances found");
|
|
2114
|
+
}
|
|
2115
|
+
const earningBalance = earningBalances.find((balance) => balance.vaultInfo.id === vaultInfo.id);
|
|
2116
|
+
if (!earningBalance) {
|
|
2117
|
+
throw new Error("No earning balance found");
|
|
2118
|
+
}
|
|
2119
|
+
const balanceInfo = earningBalance.balance;
|
|
2120
|
+
const amountToWithdraw = amount ? amount : balanceInfo.currentBalance;
|
|
2121
|
+
const apiResponse = await this.apiClient.sendRequest(
|
|
2122
|
+
"withdraw",
|
|
2123
|
+
void 0,
|
|
2124
|
+
vaultInfo.protocolId,
|
|
2125
|
+
{
|
|
2126
|
+
vaultInfo,
|
|
2127
|
+
amount: amountToWithdraw,
|
|
2128
|
+
chainId: this.selectedChainId.toString()
|
|
2129
|
+
}
|
|
2130
|
+
);
|
|
2131
|
+
if (!apiResponse.success) {
|
|
2132
|
+
throw new Error(apiResponse.error || "Failed to receive withdraw operations call data");
|
|
2133
|
+
}
|
|
2134
|
+
const withdrawOperationCallData = apiResponse.data;
|
|
2135
|
+
const hash = await smartWallet.send(withdrawOperationCallData, this.selectedChainId);
|
|
2136
|
+
const operationStatus = hash ? "completed" : "failed";
|
|
2137
|
+
this.logOperation(
|
|
2138
|
+
currentAddress,
|
|
2139
|
+
hash,
|
|
2140
|
+
vaultInfo,
|
|
2141
|
+
this.selectedChainId,
|
|
2142
|
+
amountToWithdraw,
|
|
2143
|
+
"withdrawal",
|
|
2144
|
+
operationStatus
|
|
2145
|
+
);
|
|
2146
|
+
return { hash, success: true };
|
|
2147
|
+
}
|
|
2148
|
+
/**
|
|
2149
|
+
* Get the balances of a user by a provided address
|
|
2150
|
+
* @param walletAddress Address of the user to get the balances of
|
|
2151
|
+
* @param protocolId Protocol ID to get the balances for. Optional, default is undefined
|
|
2152
|
+
* @returns Balances of the user in the protocol vaults
|
|
2153
|
+
*/
|
|
2154
|
+
async getBalances(walletAddress, protocolId) {
|
|
2155
|
+
const pathParams = {
|
|
2156
|
+
chain_id: this.selectedChainId.toString(),
|
|
2157
|
+
protocol_id: protocolId || "",
|
|
2158
|
+
userAddress: walletAddress
|
|
2159
|
+
};
|
|
2160
|
+
const apiResponse = await this.apiClient.sendRequest("balances", pathParams);
|
|
2161
|
+
if (!apiResponse.success) {
|
|
2162
|
+
throw new Error(apiResponse.error || "Failed to get balances");
|
|
2163
|
+
}
|
|
2164
|
+
const balances = apiResponse.data;
|
|
2165
|
+
return balances;
|
|
2036
2166
|
}
|
|
2037
2167
|
};
|
|
2038
2168
|
|
|
2039
2169
|
// src/router/ProtocolRouter.ts
|
|
2040
|
-
var ProtocolRouter = class
|
|
2170
|
+
var ProtocolRouter = class {
|
|
2041
2171
|
/**
|
|
2042
2172
|
* Initialize the protocol router
|
|
2043
2173
|
* @param config Router configuration including risk level, min APY, and optional API key
|
|
2044
2174
|
* @param chainManager Chain manager instance for network validation
|
|
2045
2175
|
*/
|
|
2046
|
-
constructor(
|
|
2047
|
-
|
|
2176
|
+
constructor(chainManager, isApiKeyValid) {
|
|
2177
|
+
this.chainManager = chainManager;
|
|
2178
|
+
this.isApiKeyValid = isApiKeyValid;
|
|
2048
2179
|
}
|
|
2049
2180
|
/**
|
|
2050
2181
|
* Get all protocols available for the current configuration
|
|
@@ -2052,13 +2183,9 @@ var ProtocolRouter = class extends ProtocolRouterBase {
|
|
|
2052
2183
|
* Includes all non-premium protocols and premium protocols if the API key is valid
|
|
2053
2184
|
* @returns Array of available protocol definitions
|
|
2054
2185
|
*/
|
|
2055
|
-
|
|
2056
|
-
const isKeyValid = this.apiKeyValidator.validate(this.apiKey);
|
|
2186
|
+
getActivePublicProtocols() {
|
|
2057
2187
|
const allAvailableProtocols = availableProtocols.filter((protocol) => {
|
|
2058
|
-
|
|
2059
|
-
return true;
|
|
2060
|
-
}
|
|
2061
|
-
return protocol.info.isPremium && isKeyValid;
|
|
2188
|
+
return protocol.info.isActive;
|
|
2062
2189
|
});
|
|
2063
2190
|
return allAvailableProtocols;
|
|
2064
2191
|
}
|
|
@@ -2083,18 +2210,20 @@ var ProtocolRouter = class extends ProtocolRouterBase {
|
|
|
2083
2210
|
* @throws Error if no protocols are available for the current risk level
|
|
2084
2211
|
* @returns Protocol instance considered the best match
|
|
2085
2212
|
*/
|
|
2086
|
-
|
|
2087
|
-
|
|
2213
|
+
select() {
|
|
2214
|
+
if (this.isApiKeyValid) {
|
|
2215
|
+
return new ProxyProtocol();
|
|
2216
|
+
}
|
|
2217
|
+
const protocols = this.getActivePublicProtocols();
|
|
2088
2218
|
const eligibleProtocols = protocols.filter((protocol) => {
|
|
2089
|
-
const riskMatches = protocol.info.riskLevel === this.riskLevel;
|
|
2090
2219
|
const isSupportedChain = this.isProtocolSupportedChain(protocol.info.supportedChains);
|
|
2091
|
-
return
|
|
2220
|
+
return isSupportedChain;
|
|
2092
2221
|
});
|
|
2093
2222
|
if (eligibleProtocols.length === 0) {
|
|
2094
|
-
throw new Error(`No protocols available
|
|
2223
|
+
throw new Error(`No protocols available`);
|
|
2095
2224
|
}
|
|
2096
2225
|
const bestProtocol = eligibleProtocols[0];
|
|
2097
|
-
return bestProtocol;
|
|
2226
|
+
return bestProtocol.instance;
|
|
2098
2227
|
}
|
|
2099
2228
|
};
|
|
2100
2229
|
|
|
@@ -2314,8 +2443,161 @@ var CoinbaseCDP = class {
|
|
|
2314
2443
|
}
|
|
2315
2444
|
};
|
|
2316
2445
|
|
|
2446
|
+
// src/protocols/ProtocolsNamespace.ts
|
|
2447
|
+
var ProtocolsNamespace = class {
|
|
2448
|
+
constructor(protocol) {
|
|
2449
|
+
this.protocol = protocol;
|
|
2450
|
+
}
|
|
2451
|
+
/**
|
|
2452
|
+
* Find the best vaults for protocols that were selected based on integrator's settings
|
|
2453
|
+
*
|
|
2454
|
+
* @returns Best vaults for protocols that were selected based on integrator's settings
|
|
2455
|
+
*/
|
|
2456
|
+
async getBestVaults(stableVaultsLimit = 1, nonStableVaultsLimit = 1) {
|
|
2457
|
+
return await this.protocol.getBestVaults(stableVaultsLimit, nonStableVaultsLimit);
|
|
2458
|
+
}
|
|
2459
|
+
};
|
|
2460
|
+
|
|
2461
|
+
// src/constants/general.ts
|
|
2462
|
+
var BACKEND_HOSTNAME = "http://localhost:3000";
|
|
2463
|
+
|
|
2464
|
+
// src/tools/ApiClient.ts
|
|
2465
|
+
import axios2 from "axios";
|
|
2466
|
+
var ApiClient = class {
|
|
2467
|
+
constructor(apiKey) {
|
|
2468
|
+
this.client = axios2.create({
|
|
2469
|
+
baseURL: BACKEND_HOSTNAME
|
|
2470
|
+
});
|
|
2471
|
+
/** URL settings for the endpoint: get the best vaults to deposit funds */
|
|
2472
|
+
this.bestVaultUrlSettings = {
|
|
2473
|
+
method: "GET",
|
|
2474
|
+
path: "api/v1/public/protocols/best"
|
|
2475
|
+
};
|
|
2476
|
+
/** URL settings for the endpoint: deposit funds to a provided vault */
|
|
2477
|
+
this.depositUrlSettings = {
|
|
2478
|
+
method: "POST",
|
|
2479
|
+
path: "api/v1/public/protocols/details/:protocolId/deposit"
|
|
2480
|
+
};
|
|
2481
|
+
/** URL settings for the endpoint: log a vault-related operation after deposit or withdraw funds */
|
|
2482
|
+
this.logOperationSettings = {
|
|
2483
|
+
method: "POST",
|
|
2484
|
+
path: "api/v1/public/log/operation"
|
|
2485
|
+
};
|
|
2486
|
+
/** URL settings for the endpoint: withdraw funds from a provided vault */
|
|
2487
|
+
this.withdrawUrlSettings = {
|
|
2488
|
+
method: "POST",
|
|
2489
|
+
path: "api/v1/public/protocols/details/:protocolId/withdraw"
|
|
2490
|
+
};
|
|
2491
|
+
/** URL settings for the endpoint: get the balances of a user by a provided address */
|
|
2492
|
+
this.balancesUrlSettings = {
|
|
2493
|
+
method: "GET",
|
|
2494
|
+
path: "api/v1/public/user/:userAddress/balances"
|
|
2495
|
+
};
|
|
2496
|
+
/** URL settings for the endpoint: validate the API key */
|
|
2497
|
+
this.apiKeyValidUrlSettings = {
|
|
2498
|
+
method: "GET",
|
|
2499
|
+
path: "api/v1/public/valid"
|
|
2500
|
+
};
|
|
2501
|
+
/** URL settings for the endpoint: get the config for services */
|
|
2502
|
+
this.configUrlSettings = {
|
|
2503
|
+
method: "GET",
|
|
2504
|
+
path: "api/v1/public/config"
|
|
2505
|
+
};
|
|
2506
|
+
/** URL settings mapping with operation types */
|
|
2507
|
+
this.operationTypeToUrlSettings = {
|
|
2508
|
+
deposit: this.depositUrlSettings,
|
|
2509
|
+
withdraw: this.withdrawUrlSettings,
|
|
2510
|
+
log: this.logOperationSettings,
|
|
2511
|
+
vaults: this.bestVaultUrlSettings,
|
|
2512
|
+
balances: this.balancesUrlSettings,
|
|
2513
|
+
apiKeyValidation: this.apiKeyValidUrlSettings,
|
|
2514
|
+
config: this.configUrlSettings
|
|
2515
|
+
};
|
|
2516
|
+
this.apiKey = apiKey;
|
|
2517
|
+
if (!this.validateApiKeyFormat()) {
|
|
2518
|
+
throw new Error("Invalid API key format");
|
|
2519
|
+
}
|
|
2520
|
+
}
|
|
2521
|
+
/**
|
|
2522
|
+
* Send a request to the backend API
|
|
2523
|
+
* @param path Path of the endpoint to send the request to
|
|
2524
|
+
* @param method Method of the request
|
|
2525
|
+
* @param body Body of the request
|
|
2526
|
+
* @returns Response from the backend API
|
|
2527
|
+
*/
|
|
2528
|
+
async sendRequest(operationType, params, protocolId, body) {
|
|
2529
|
+
const { path, method } = this.operationTypeToUrlSettings[operationType];
|
|
2530
|
+
let requestPath = path;
|
|
2531
|
+
if (protocolId) {
|
|
2532
|
+
requestPath = requestPath.replace(":protocolId", protocolId);
|
|
2533
|
+
}
|
|
2534
|
+
if (params?.userAddress) {
|
|
2535
|
+
requestPath = requestPath.replace(":userAddress", params.userAddress);
|
|
2536
|
+
delete params.userAddress;
|
|
2537
|
+
}
|
|
2538
|
+
const urlParams = new URLSearchParams(params).toString();
|
|
2539
|
+
if (urlParams) {
|
|
2540
|
+
requestPath += `?${urlParams}`;
|
|
2541
|
+
}
|
|
2542
|
+
const response = await this.client.request({
|
|
2543
|
+
method,
|
|
2544
|
+
url: requestPath,
|
|
2545
|
+
data: body,
|
|
2546
|
+
headers: { Authorization: `Bearer ${this.apiKey}`, "Content-Type": "application/json" }
|
|
2547
|
+
});
|
|
2548
|
+
if (response.status !== 200) {
|
|
2549
|
+
throw new Error(`Failed to send request to ${path}`);
|
|
2550
|
+
}
|
|
2551
|
+
const apiResponse = response.data;
|
|
2552
|
+
return apiResponse;
|
|
2553
|
+
}
|
|
2554
|
+
/**
|
|
2555
|
+
* Validates whether the provided API key is valid
|
|
2556
|
+
*
|
|
2557
|
+
* @internal
|
|
2558
|
+
* @param apiKey API key from {@link ProtocolsRouterConfig}
|
|
2559
|
+
* @returns True if the API key is considered valid
|
|
2560
|
+
*/
|
|
2561
|
+
async validate() {
|
|
2562
|
+
if (!this.validateApiKeyFormat()) {
|
|
2563
|
+
throw new Error("Invalid API key format");
|
|
2564
|
+
}
|
|
2565
|
+
const apiResponse = await this.sendRequest("apiKeyValidation");
|
|
2566
|
+
if (!apiResponse.success) {
|
|
2567
|
+
throw new Error(apiResponse.error || "Failed to validate API key");
|
|
2568
|
+
}
|
|
2569
|
+
return true;
|
|
2570
|
+
}
|
|
2571
|
+
/**
|
|
2572
|
+
*
|
|
2573
|
+
* Validates the format of the API key. Must start with 'sk_' and contain only hexadecimal characters
|
|
2574
|
+
*
|
|
2575
|
+
* @internal
|
|
2576
|
+
* @param apiKey API key from {@link ProtocolsRouterConfig}
|
|
2577
|
+
* @returns
|
|
2578
|
+
*/
|
|
2579
|
+
validateApiKeyFormat() {
|
|
2580
|
+
if (!this.apiKey) {
|
|
2581
|
+
return false;
|
|
2582
|
+
}
|
|
2583
|
+
const prefix = "sk_";
|
|
2584
|
+
if (!this.apiKey.startsWith(prefix)) {
|
|
2585
|
+
return false;
|
|
2586
|
+
}
|
|
2587
|
+
const keyPart = this.apiKey.slice(prefix.length);
|
|
2588
|
+
if (keyPart.length < 32 || keyPart.length > 128) {
|
|
2589
|
+
return false;
|
|
2590
|
+
}
|
|
2591
|
+
const hexPattern = /^[0-9a-fA-F]+$/;
|
|
2592
|
+
if (!hexPattern.test(keyPart)) {
|
|
2593
|
+
return false;
|
|
2594
|
+
}
|
|
2595
|
+
return true;
|
|
2596
|
+
}
|
|
2597
|
+
};
|
|
2598
|
+
|
|
2317
2599
|
// src/index.ts
|
|
2318
|
-
var MyceliumSDK = class {
|
|
2600
|
+
var MyceliumSDK = class _MyceliumSDK {
|
|
2319
2601
|
/**
|
|
2320
2602
|
* Creates a new SDK instance
|
|
2321
2603
|
*
|
|
@@ -2323,7 +2605,16 @@ var MyceliumSDK = class {
|
|
|
2323
2605
|
* @throws Throws if an unsupported wallet provider is given
|
|
2324
2606
|
* @see MyceliumSDKConfig
|
|
2325
2607
|
*/
|
|
2326
|
-
constructor(config) {
|
|
2608
|
+
constructor(config, isPremiumAvailable, apiClient) {
|
|
2609
|
+
/**
|
|
2610
|
+
* Ramp namespace to manage ramp operations. Methods are available on {@link RampNamespace}
|
|
2611
|
+
* @internal
|
|
2612
|
+
* @remarks
|
|
2613
|
+
* If the Coinbase CDP configuration is not provided, the ramp functionality will be disabled.
|
|
2614
|
+
* Calling the respective method will throw an error
|
|
2615
|
+
* @category Tools
|
|
2616
|
+
*/
|
|
2617
|
+
this.fundingNamespace = null;
|
|
2327
2618
|
/**
|
|
2328
2619
|
* Coinbase CDP instance to Coinbase related and onchain operations using Coinbase CDP API
|
|
2329
2620
|
* @remarks
|
|
@@ -2332,46 +2623,6 @@ var MyceliumSDK = class {
|
|
|
2332
2623
|
* @internal
|
|
2333
2624
|
*/
|
|
2334
2625
|
this.coinbaseCDP = null;
|
|
2335
|
-
/**
|
|
2336
|
-
* Coinbase CDP configuration methods for ramp operations
|
|
2337
|
-
* @public
|
|
2338
|
-
* @category Tools
|
|
2339
|
-
*/
|
|
2340
|
-
this.rampConfig = {
|
|
2341
|
-
/**
|
|
2342
|
-
* Return all supported countries and payment methods for on-ramp by Coinbase CDP
|
|
2343
|
-
* @public
|
|
2344
|
-
* @category Ramp
|
|
2345
|
-
*
|
|
2346
|
-
* @returns @see {@link RampConfigResponse} with supported countries and payment methods for top-up
|
|
2347
|
-
* @throws If API returned an error
|
|
2348
|
-
*/
|
|
2349
|
-
getTopUpConfig: async () => {
|
|
2350
|
-
if (!this.coinbaseCDP) {
|
|
2351
|
-
throw new Error(
|
|
2352
|
-
"Coinbase CDP is not initialized. Please, provide the configuration in the SDK initialization"
|
|
2353
|
-
);
|
|
2354
|
-
}
|
|
2355
|
-
return await this.coinbaseCDP.getOnRampConfig();
|
|
2356
|
-
},
|
|
2357
|
-
/**
|
|
2358
|
-
* Return all supported countries and payment methods for off-ramp by Coinbase CDP
|
|
2359
|
-
* @public
|
|
2360
|
-
* @category Ramp
|
|
2361
|
-
*
|
|
2362
|
-
*
|
|
2363
|
-
* @returns @see {@link RampConfigResponse} with supported countries and payment methods for cash out
|
|
2364
|
-
* @throws If API returned an error
|
|
2365
|
-
*/
|
|
2366
|
-
getCashOutConfig: async () => {
|
|
2367
|
-
if (!this.coinbaseCDP) {
|
|
2368
|
-
throw new Error(
|
|
2369
|
-
"Coinbase CDP is not initialized. Please, provide the configuration in the SDK initialization"
|
|
2370
|
-
);
|
|
2371
|
-
}
|
|
2372
|
-
return await this.coinbaseCDP.getOffRampConfig();
|
|
2373
|
-
}
|
|
2374
|
-
};
|
|
2375
2626
|
this._chainManager = new ChainManager(
|
|
2376
2627
|
config.chain || {
|
|
2377
2628
|
chainId: base3.id,
|
|
@@ -2379,11 +2630,14 @@ var MyceliumSDK = class {
|
|
|
2379
2630
|
bundlerUrl: "https://public.pimlico.io/v2/8453/rpc"
|
|
2380
2631
|
}
|
|
2381
2632
|
);
|
|
2382
|
-
if (
|
|
2383
|
-
|
|
2384
|
-
|
|
2385
|
-
|
|
2633
|
+
if (config.protocolsSecurityConfig) {
|
|
2634
|
+
this.protocol = this.selectProtocol(
|
|
2635
|
+
config.protocolsSecurityConfig,
|
|
2636
|
+
isPremiumAvailable,
|
|
2637
|
+
apiClient
|
|
2386
2638
|
);
|
|
2639
|
+
} else {
|
|
2640
|
+
throw new Error("Protocols router config is required");
|
|
2387
2641
|
}
|
|
2388
2642
|
if (config.coinbaseCDPConfig) {
|
|
2389
2643
|
this.coinbaseCDP = new CoinbaseCDP(
|
|
@@ -2392,16 +2646,71 @@ var MyceliumSDK = class {
|
|
|
2392
2646
|
config.integratorId,
|
|
2393
2647
|
this.chainManager
|
|
2394
2648
|
);
|
|
2649
|
+
this.fundingNamespace = new FundingNamespace(this.coinbaseCDP);
|
|
2395
2650
|
}
|
|
2396
|
-
const protocolsRouterConfig = config.protocolsRouterConfig || {
|
|
2397
|
-
riskLevel: "low"
|
|
2398
|
-
};
|
|
2399
|
-
this.protocol = this.findProtocol(protocolsRouterConfig);
|
|
2400
2651
|
this.wallet = this.createWalletNamespace(config.walletsConfig);
|
|
2652
|
+
this.protocols = new ProtocolsNamespace(this.protocol);
|
|
2653
|
+
}
|
|
2654
|
+
/**
|
|
2655
|
+
* Initializes the SDK
|
|
2656
|
+
* @param config SDK configuration (networks, wallets, protocol router settings)
|
|
2657
|
+
* @returns SDK instance
|
|
2658
|
+
*/
|
|
2659
|
+
static async init(config) {
|
|
2660
|
+
let finalConfig;
|
|
2661
|
+
let isPremiumAvailable = false;
|
|
2662
|
+
if ("apiKey" in config && config.apiKey) {
|
|
2663
|
+
const apiClient = new ApiClient(config.apiKey);
|
|
2664
|
+
isPremiumAvailable = await apiClient.validate();
|
|
2665
|
+
if (isPremiumAvailable) {
|
|
2666
|
+
const apiResponse = await apiClient.sendRequest("config");
|
|
2667
|
+
if (!apiResponse.success) {
|
|
2668
|
+
throw new Error(apiResponse.error || "Failed to get onchain config");
|
|
2669
|
+
}
|
|
2670
|
+
const backendConfig = apiResponse.data;
|
|
2671
|
+
finalConfig = {
|
|
2672
|
+
integratorId: backendConfig.integratorId,
|
|
2673
|
+
walletsConfig: {
|
|
2674
|
+
embeddedWalletConfig: {
|
|
2675
|
+
provider: {
|
|
2676
|
+
type: "privy",
|
|
2677
|
+
providerConfig: {
|
|
2678
|
+
appId: backendConfig.privyAppId,
|
|
2679
|
+
appSecret: backendConfig.privyAppSecret
|
|
2680
|
+
}
|
|
2681
|
+
}
|
|
2682
|
+
},
|
|
2683
|
+
smartWalletConfig: {
|
|
2684
|
+
provider: {
|
|
2685
|
+
type: "default"
|
|
2686
|
+
}
|
|
2687
|
+
}
|
|
2688
|
+
},
|
|
2689
|
+
chain: {
|
|
2690
|
+
chainId: config.chainId || backendConfig.chainId,
|
|
2691
|
+
rpcUrl: backendConfig.rpcUrl,
|
|
2692
|
+
bundlerUrl: backendConfig.bundlerUrl
|
|
2693
|
+
},
|
|
2694
|
+
protocolsSecurityConfig: config.protocolsSecurityConfig,
|
|
2695
|
+
coinbaseCDPConfig: {
|
|
2696
|
+
apiKeyId: backendConfig.coinbaseCdpApiKey,
|
|
2697
|
+
apiKeySecret: backendConfig.coinbaseCdpApiKeySecret
|
|
2698
|
+
}
|
|
2699
|
+
};
|
|
2700
|
+
const sdk2 = new _MyceliumSDK(finalConfig, isPremiumAvailable, apiClient);
|
|
2701
|
+
sdk2.apiClient = apiClient;
|
|
2702
|
+
return sdk2;
|
|
2703
|
+
}
|
|
2704
|
+
}
|
|
2705
|
+
finalConfig = config;
|
|
2706
|
+
const sdk = new _MyceliumSDK(finalConfig, isPremiumAvailable);
|
|
2707
|
+
return sdk;
|
|
2401
2708
|
}
|
|
2402
2709
|
/**
|
|
2403
2710
|
* Returns the chain manager instance for multi-chain operations
|
|
2404
2711
|
* @public
|
|
2712
|
+
* @remarks
|
|
2713
|
+
* More about methods in {@link ChainManager}
|
|
2405
2714
|
* @category Tools
|
|
2406
2715
|
*
|
|
2407
2716
|
* @returns ChainManager instance of the type {@link ChainManager}
|
|
@@ -2409,6 +2718,23 @@ var MyceliumSDK = class {
|
|
|
2409
2718
|
get chainManager() {
|
|
2410
2719
|
return this._chainManager;
|
|
2411
2720
|
}
|
|
2721
|
+
/**
|
|
2722
|
+
* Returns a funding namespace to manage top ups & cash outs configurations
|
|
2723
|
+
* @public
|
|
2724
|
+
* @remarks
|
|
2725
|
+
* More about methods in {@link FundingNamespace}
|
|
2726
|
+
* @category Tools
|
|
2727
|
+
*
|
|
2728
|
+
* @returns Funding namespace of the type {@link FundingNamespace}
|
|
2729
|
+
*/
|
|
2730
|
+
get funding() {
|
|
2731
|
+
if (!this.fundingNamespace) {
|
|
2732
|
+
throw new Error(
|
|
2733
|
+
"Ramp namespace is not initialized. Please, provide the configuration in the SDK initialization"
|
|
2734
|
+
);
|
|
2735
|
+
}
|
|
2736
|
+
return this.fundingNamespace;
|
|
2737
|
+
}
|
|
2412
2738
|
/**
|
|
2413
2739
|
* Recommends and initializes a protocol based on router settings
|
|
2414
2740
|
*
|
|
@@ -2416,10 +2742,13 @@ var MyceliumSDK = class {
|
|
|
2416
2742
|
* @param config Protocol router configuration (e.g. risk level)
|
|
2417
2743
|
* @returns Selected protocol object of the type {@link Protocol}
|
|
2418
2744
|
*/
|
|
2419
|
-
|
|
2420
|
-
const protocolRouter = new ProtocolRouter(
|
|
2421
|
-
const protocol = protocolRouter.
|
|
2422
|
-
|
|
2745
|
+
selectProtocol(config, isPremiumAvailable, apiClient) {
|
|
2746
|
+
const protocolRouter = new ProtocolRouter(this.chainManager, isPremiumAvailable);
|
|
2747
|
+
const protocol = protocolRouter.select();
|
|
2748
|
+
if (!config) {
|
|
2749
|
+
throw new Error("Protocols security config is required");
|
|
2750
|
+
}
|
|
2751
|
+
protocol.init(this.chainManager, config, apiClient);
|
|
2423
2752
|
return protocol;
|
|
2424
2753
|
}
|
|
2425
2754
|
/**
|
|
@@ -2476,6 +2805,7 @@ var MyceliumSDK = class {
|
|
|
2476
2805
|
};
|
|
2477
2806
|
export {
|
|
2478
2807
|
DefaultSmartWallet,
|
|
2808
|
+
FundingNamespace,
|
|
2479
2809
|
MyceliumSDK
|
|
2480
2810
|
};
|
|
2481
2811
|
//# sourceMappingURL=index.js.map
|