@deserialize/multi-vm-wallet 1.5.2 → 1.5.3
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/IChainWallet.d.ts +11 -7
- package/dist/IChainWallet.js +15 -6
- package/dist/evm/evm.d.ts +10 -1
- package/dist/evm/evm.js +82 -32
- package/dist/evm/utils.d.ts +1 -0
- package/dist/evm/utils.js +8 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +2 -1
- package/dist/svm/svm.d.ts +10 -1
- package/dist/svm/svm.js +64 -21
- package/dist/test.js +7 -0
- package/package.json +1 -1
- package/utils/IChainWallet.ts +76 -15
- package/utils/evm/evm.ts +123 -291
- package/utils/evm/utils.ts +12 -0
- package/utils/index.ts +2 -2
- package/utils/savings/svm-savings.ts +1 -1
- package/utils/svm/svm.ts +100 -24
- package/utils/test.ts +9 -0
- package/utils/utils.ts +7 -0
package/utils/evm/evm.ts
CHANGED
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
*/
|
|
6
6
|
|
|
7
7
|
import { EntropyToMnemonic, EVMDeriveChildPrivateKey } from "../walletBip32";
|
|
8
|
-
import { ChainWallet } from "../IChainWallet";
|
|
8
|
+
import { ChainAddress, ChainWallet } from "../IChainWallet";
|
|
9
9
|
import { Balance, ChainWalletConfig, NFTInfo, UserTokenBalance, TokenInfo, TransactionResult, NFT, DiscoveredWallet, WalletDiscoveryOptions, WalletDiscoveryResult, PocketDiscoveryOptions } from "../types";
|
|
10
10
|
import { VM } from "../vm";
|
|
11
11
|
import { VMValidation, sanitizeError, logSafeError } from "../vm-validation";
|
|
@@ -50,6 +50,76 @@ import { Account, generatePrivateKey, privateKeyToAccount } from "viem/accounts"
|
|
|
50
50
|
// import { extendWalletClientWithSavings } from "../savings";
|
|
51
51
|
// import { SavingsManager } from "../savings/saving-actions";
|
|
52
52
|
|
|
53
|
+
const createEvmPublicClient = (config: ChainWalletConfig): PublicClient =>
|
|
54
|
+
createPublicClient({
|
|
55
|
+
chain: fromChainToViemChain(config),
|
|
56
|
+
transport: http(config.rpcUrl),
|
|
57
|
+
});
|
|
58
|
+
|
|
59
|
+
const createEvmWalletClient = (config: ChainWalletConfig, account: Account): WalletClient =>
|
|
60
|
+
createWalletClient({
|
|
61
|
+
account,
|
|
62
|
+
chain: fromChainToViemChain(config),
|
|
63
|
+
transport: http(config.rpcUrl),
|
|
64
|
+
});
|
|
65
|
+
|
|
66
|
+
const getEvmTransactionHistorySafe = async (
|
|
67
|
+
connection: PublicClient,
|
|
68
|
+
address: string
|
|
69
|
+
): Promise<EVMTransactionHistoryItem[]> => {
|
|
70
|
+
try {
|
|
71
|
+
return await getEVMTransactionHistory(connection, address as Hex);
|
|
72
|
+
} catch {
|
|
73
|
+
return [];
|
|
74
|
+
}
|
|
75
|
+
};
|
|
76
|
+
|
|
77
|
+
const getEvmPrices = async (
|
|
78
|
+
config: ChainWalletConfig,
|
|
79
|
+
tokenAddresses: string[]
|
|
80
|
+
): Promise<PriceResponse> => {
|
|
81
|
+
const result = await fetchPrices({
|
|
82
|
+
vm: 'EVM',
|
|
83
|
+
chainId: config.chainId,
|
|
84
|
+
tokenAddresses,
|
|
85
|
+
});
|
|
86
|
+
|
|
87
|
+
if (result.error) {
|
|
88
|
+
throw new Error(result.error.message);
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
return result.data as PriceResponse;
|
|
92
|
+
};
|
|
93
|
+
|
|
94
|
+
const getEvmNativeBalance = async (
|
|
95
|
+
address: string,
|
|
96
|
+
connection: PublicClient
|
|
97
|
+
): Promise<Balance> => {
|
|
98
|
+
return await EVMVM.getNativeBalance(address, connection);
|
|
99
|
+
};
|
|
100
|
+
|
|
101
|
+
const getEvmTokenBalance = async (
|
|
102
|
+
address: string,
|
|
103
|
+
tokenAddress: string,
|
|
104
|
+
connection: PublicClient
|
|
105
|
+
): Promise<Balance> => {
|
|
106
|
+
return await EVMVM.getTokenBalance(address, tokenAddress, connection);
|
|
107
|
+
};
|
|
108
|
+
|
|
109
|
+
const discoverEvmTokens = async (
|
|
110
|
+
address: string,
|
|
111
|
+
config: ChainWalletConfig
|
|
112
|
+
): Promise<UserTokenBalance<string>[]> => {
|
|
113
|
+
return await discoverTokens(address, config);
|
|
114
|
+
};
|
|
115
|
+
|
|
116
|
+
const discoverEvmNFTs = async (
|
|
117
|
+
address: string,
|
|
118
|
+
config: ChainWalletConfig
|
|
119
|
+
): Promise<NFT[]> => {
|
|
120
|
+
return await discoverNFTs(address, config);
|
|
121
|
+
};
|
|
122
|
+
|
|
53
123
|
|
|
54
124
|
interface DebonkQuoteResponse {
|
|
55
125
|
tokenA: string;
|
|
@@ -202,7 +272,8 @@ export class EVMVM extends VM<string, string, PublicClient> {
|
|
|
202
272
|
}
|
|
203
273
|
|
|
204
274
|
static convertFromEntropyToPrivateKey = (entropy: string): string => {
|
|
205
|
-
|
|
275
|
+
const p = ethers.id(entropy)
|
|
276
|
+
return p
|
|
206
277
|
}
|
|
207
278
|
|
|
208
279
|
/**
|
|
@@ -687,6 +758,41 @@ export class EVMVM extends VM<string, string, PublicClient> {
|
|
|
687
758
|
|
|
688
759
|
}
|
|
689
760
|
|
|
761
|
+
export class EVMChainAddress extends ChainAddress<string, PublicClient> {
|
|
762
|
+
constructor(config: ChainWalletConfig, address: string, index?: number) {
|
|
763
|
+
const connection = createEvmPublicClient(config);
|
|
764
|
+
super(config, address, index);
|
|
765
|
+
this.connection = connection;
|
|
766
|
+
}
|
|
767
|
+
|
|
768
|
+
async getNativeBalance(): Promise<Balance> {
|
|
769
|
+
return await getEvmNativeBalance(this.address, this.connection!);
|
|
770
|
+
}
|
|
771
|
+
|
|
772
|
+
async getTokenBalance(tokenAddress: string): Promise<Balance> {
|
|
773
|
+
return await getEvmTokenBalance(this.address, tokenAddress, this.connection!);
|
|
774
|
+
}
|
|
775
|
+
|
|
776
|
+
async discoverToken(): Promise<UserTokenBalance<string>[]> {
|
|
777
|
+
return await discoverEvmTokens(this.address, this.config);
|
|
778
|
+
}
|
|
779
|
+
|
|
780
|
+
async discoverNFT(): Promise<NFT[]> {
|
|
781
|
+
return await discoverEvmNFTs(this.address, this.config);
|
|
782
|
+
}
|
|
783
|
+
|
|
784
|
+
async getTransactionHistory(): Promise<EVMTransactionHistoryItem[]> {
|
|
785
|
+
return await getEvmTransactionHistorySafe(this.connection!, this.address);
|
|
786
|
+
}
|
|
787
|
+
|
|
788
|
+
async getPrices(tokenAddresses: string[]): Promise<PriceResponse> {
|
|
789
|
+
return await getEvmPrices(this.config, tokenAddresses);
|
|
790
|
+
}
|
|
791
|
+
|
|
792
|
+
|
|
793
|
+
}
|
|
794
|
+
|
|
795
|
+
|
|
690
796
|
export class EVMChainWallet extends ChainWallet<string, string, PublicClient> {
|
|
691
797
|
wallet: WalletClient
|
|
692
798
|
private smartWallet?: EVMSmartWallet
|
|
@@ -695,21 +801,17 @@ export class EVMChainWallet extends ChainWallet<string, string, PublicClient> {
|
|
|
695
801
|
|
|
696
802
|
constructor(config: ChainWalletConfig, privateKey: string, index: number) {
|
|
697
803
|
privateKey = privateKey.startsWith('0x') ? privateKey : `0x${privateKey}`
|
|
698
|
-
|
|
699
|
-
this.connection = createPublicClient(
|
|
700
|
-
{
|
|
701
|
-
chain: fromChainToViemChain(config),
|
|
702
|
-
transport: http(config.rpcUrl)
|
|
703
|
-
},
|
|
704
|
-
)
|
|
804
|
+
const connection = createEvmPublicClient(config);
|
|
705
805
|
const account = privateKeyToAccount(privateKey as Hex)
|
|
706
|
-
|
|
707
|
-
|
|
708
|
-
|
|
709
|
-
|
|
710
|
-
|
|
711
|
-
this.address = account.address
|
|
806
|
+
const wallet = createEvmWalletClient(config, account);
|
|
807
|
+
const address = account.address
|
|
808
|
+
super(config, address, privateKey, index);
|
|
809
|
+
|
|
810
|
+
|
|
712
811
|
this.privateKey = privateKey;
|
|
812
|
+
this.wallet = wallet;
|
|
813
|
+
this.connection = connection;
|
|
814
|
+
this.address = address
|
|
713
815
|
}
|
|
714
816
|
|
|
715
817
|
// ============================================
|
|
@@ -887,12 +989,12 @@ export class EVMChainWallet extends ChainWallet<string, string, PublicClient> {
|
|
|
887
989
|
|
|
888
990
|
async getNativeBalance(): Promise<Balance> {
|
|
889
991
|
// Implement native balance retrieval logic here
|
|
890
|
-
return await
|
|
992
|
+
return await getEvmNativeBalance(this.address, this.connection!);
|
|
891
993
|
}
|
|
892
994
|
|
|
893
995
|
async getTokenBalance(tokenAddress: string): Promise<Balance> {
|
|
894
996
|
// Implement token balance retrieval logic here
|
|
895
|
-
return await
|
|
997
|
+
return await getEvmTokenBalance(this.address, tokenAddress, this.connection!);
|
|
896
998
|
}
|
|
897
999
|
|
|
898
1000
|
async getTokenInfo(tokenAddress: string) {
|
|
@@ -901,12 +1003,12 @@ export class EVMChainWallet extends ChainWallet<string, string, PublicClient> {
|
|
|
901
1003
|
|
|
902
1004
|
async discoverToken(): Promise<UserTokenBalance<string>[]> {
|
|
903
1005
|
// Implement token discovery logic here
|
|
904
|
-
return await
|
|
1006
|
+
return await discoverEvmTokens(this.address, this.config);
|
|
905
1007
|
}
|
|
906
1008
|
|
|
907
1009
|
async discoverNFT(): Promise<NFT[]> {
|
|
908
1010
|
// Implement NFT discovery logic here
|
|
909
|
-
return await
|
|
1011
|
+
return await discoverEvmNFTs(this.address, this.config);
|
|
910
1012
|
}
|
|
911
1013
|
|
|
912
1014
|
async transferNative(to: string, amount: number): Promise<TransactionResult> {
|
|
@@ -922,25 +1024,11 @@ export class EVMChainWallet extends ChainWallet<string, string, PublicClient> {
|
|
|
922
1024
|
async getTransactionHistory(): Promise<EVMTransactionHistoryItem[]> {
|
|
923
1025
|
const wallet = this.getWallet();
|
|
924
1026
|
let res: EVMTransactionHistoryItem
|
|
925
|
-
|
|
926
|
-
return await getEVMTransactionHistory(this.connection!, this.address as Hex);
|
|
927
|
-
} catch (error) {
|
|
928
|
-
return []
|
|
929
|
-
}
|
|
1027
|
+
return await getEvmTransactionHistorySafe(this.connection!, this.address);
|
|
930
1028
|
}
|
|
931
1029
|
|
|
932
1030
|
async getPrices(tokenAddresses: string[]): Promise<PriceResponse> {
|
|
933
|
-
|
|
934
|
-
vm: 'EVM',
|
|
935
|
-
chainId: this.config.chainId,
|
|
936
|
-
tokenAddresses,
|
|
937
|
-
});
|
|
938
|
-
|
|
939
|
-
if (result.error) {
|
|
940
|
-
throw new Error(result.error.message);
|
|
941
|
-
}
|
|
942
|
-
|
|
943
|
-
return result.data as PriceResponse;
|
|
1031
|
+
return await getEvmPrices(this.config, tokenAddresses);
|
|
944
1032
|
}
|
|
945
1033
|
|
|
946
1034
|
// Updated swap method signature to match base class so created another method to use it inside swap
|
|
@@ -1006,260 +1094,4 @@ export class EVMChainWallet extends ChainWallet<string, string, PublicClient> {
|
|
|
1006
1094
|
return signer.signMessage({ message, account: signer.account?.address })
|
|
1007
1095
|
}
|
|
1008
1096
|
|
|
1009
|
-
// // ============================================
|
|
1010
|
-
// // Savings Pocket Methods
|
|
1011
|
-
// // ============================================
|
|
1012
|
-
|
|
1013
|
-
// /**
|
|
1014
|
-
// * Get or create the SavingsManager instance (lazy initialization)
|
|
1015
|
-
// * @private
|
|
1016
|
-
// */
|
|
1017
|
-
// private getSavingsManager(): SavingsManager {
|
|
1018
|
-
// if (!this.savingsManager) {
|
|
1019
|
-
// // Create a VM instance from the current wallet's seed
|
|
1020
|
-
// // We need to get the seed from the privateKey
|
|
1021
|
-
// // For now, we'll create an EVMVM from the wallet
|
|
1022
|
-
// // Note: This requires access to the seed, which we'll need to handle
|
|
1023
|
-
// throw new Error(
|
|
1024
|
-
// "SavingsManager requires access to the seed phrase. " +
|
|
1025
|
-
// "Please initialize the wallet with a seed phrase or mnemonic to use savings features."
|
|
1026
|
-
// );
|
|
1027
|
-
// }
|
|
1028
|
-
// return this.savingsManager;
|
|
1029
|
-
// }
|
|
1030
|
-
|
|
1031
|
-
// /**
|
|
1032
|
-
// * Initialize savings functionality with a seed phrase
|
|
1033
|
-
// *
|
|
1034
|
-
// * This must be called before using any savings methods.
|
|
1035
|
-
// * The seed is used to derive savings accounts using BIP-44.
|
|
1036
|
-
// *
|
|
1037
|
-
// * @param seed - The wallet seed (hex string)
|
|
1038
|
-
// *
|
|
1039
|
-
// * @example
|
|
1040
|
-
// * const seed = VM.mnemonicToSeed(mnemonic);
|
|
1041
|
-
// * wallet.initializeSavings(seed);
|
|
1042
|
-
// */
|
|
1043
|
-
// initializeSavings(seed: string): void {
|
|
1044
|
-
// const vm = new EVMVM(seed);
|
|
1045
|
-
// this.savingsManager = new SavingsManager(vm);
|
|
1046
|
-
// }
|
|
1047
|
-
|
|
1048
|
-
// /**
|
|
1049
|
-
// * Derive a new savings account from BIP-44 account index
|
|
1050
|
-
// *
|
|
1051
|
-
// * @param accountIndex - The BIP-44 account index (1+ for savings, 0 is main wallet)
|
|
1052
|
-
// * @returns SavingsAccount with derived address and private key
|
|
1053
|
-
// *
|
|
1054
|
-
// * @example
|
|
1055
|
-
// * const savingsAccount1 = wallet.deriveSavingsAccount(1); // m/44'/60'/1'/0/0
|
|
1056
|
-
// * const savingsAccount2 = wallet.deriveSavingsAccount(2); // m/44'/60'/2'/0/0
|
|
1057
|
-
// */
|
|
1058
|
-
// deriveSavingsAccount(accountIndex: number): SavingsAccount {
|
|
1059
|
-
// return this.getSavingsManager().createSavingsAccount(accountIndex);
|
|
1060
|
-
// }
|
|
1061
|
-
|
|
1062
|
-
// /**
|
|
1063
|
-
// * Transfer native tokens to a savings account
|
|
1064
|
-
// *
|
|
1065
|
-
// * Security: Always derives the destination address from accountIndex.
|
|
1066
|
-
// *
|
|
1067
|
-
// * @param accountIndex - Savings account index to deposit to
|
|
1068
|
-
// * @param amount - Amount in ether units (e.g., "1.5" for 1.5 ETH)
|
|
1069
|
-
// * @param options - Optional security and priority settings
|
|
1070
|
-
// * @returns Transaction result
|
|
1071
|
-
// *
|
|
1072
|
-
// * @example
|
|
1073
|
-
// * const result = await wallet.transferToSavings(1, "1.5"); // Send 1.5 ETH to savings account 1
|
|
1074
|
-
// */
|
|
1075
|
-
// async transferToSavings(
|
|
1076
|
-
// accountIndex: number,
|
|
1077
|
-
// amount: string,
|
|
1078
|
-
// options?: TransferToSavingsOptions
|
|
1079
|
-
// ): Promise<TransactionResult> {
|
|
1080
|
-
// const manager = this.getSavingsManager();
|
|
1081
|
-
|
|
1082
|
-
// // Build transaction using derived address
|
|
1083
|
-
// const amountWei = parseEther(amount);
|
|
1084
|
-
// const txParams = manager.buildDepositTransaction(accountIndex, amountWei, options);
|
|
1085
|
-
|
|
1086
|
-
// // Execute using existing transferNative method
|
|
1087
|
-
// return await this.transferNative(txParams.to, Number(amount));
|
|
1088
|
-
// }
|
|
1089
|
-
|
|
1090
|
-
// // /**
|
|
1091
|
-
// // * Withdraw native tokens from a savings account
|
|
1092
|
-
// // *
|
|
1093
|
-
// // * Security: Uses the derived private key for signing.
|
|
1094
|
-
// // *
|
|
1095
|
-
// // * @param accountIndex - Savings account index to withdraw from
|
|
1096
|
-
// // * @param to - Destination address
|
|
1097
|
-
// // * @param amount - Amount in ether units (e.g., "0.5" for 0.5 ETH)
|
|
1098
|
-
// // * @param options - Optional security and priority settings
|
|
1099
|
-
// // * @returns Transaction result
|
|
1100
|
-
// // *
|
|
1101
|
-
// // * @example
|
|
1102
|
-
// // * const result = await wallet.withdrawFromSavings(1, destinationAddress, "0.5");
|
|
1103
|
-
// // */
|
|
1104
|
-
// // async withdrawFromSavings(
|
|
1105
|
-
// // accountIndex: number,
|
|
1106
|
-
// // to: string,
|
|
1107
|
-
// // amount: string,
|
|
1108
|
-
// // options?: WithdrawFromSavingsOptions
|
|
1109
|
-
// // ): Promise<TransactionResult> {
|
|
1110
|
-
// // const manager = this.getSavingsManager();
|
|
1111
|
-
|
|
1112
|
-
// // // Build withdrawal transaction
|
|
1113
|
-
// // const amountWei = parseEther(amount);
|
|
1114
|
-
// // const withdrawalParams = manager.buildWithdrawalTransaction(
|
|
1115
|
-
// // accountIndex,
|
|
1116
|
-
// // to as Hex,
|
|
1117
|
-
// // amountWei,
|
|
1118
|
-
// // options
|
|
1119
|
-
// // );
|
|
1120
|
-
|
|
1121
|
-
// // // Create a temporary wallet with the savings account private key
|
|
1122
|
-
// // const savingsWallet = new Wallet(withdrawalParams.privateKey, this.connection);
|
|
1123
|
-
|
|
1124
|
-
// // // Send transaction using the savings wallet
|
|
1125
|
-
// // const tx = await savingsWallet.sendTransaction({
|
|
1126
|
-
// // to: withdrawalParams.to,
|
|
1127
|
-
// // value: withdrawalParams.value
|
|
1128
|
-
// // });
|
|
1129
|
-
|
|
1130
|
-
// // const receipt = await tx.wait(this.config.confirmationNo || 1);
|
|
1131
|
-
|
|
1132
|
-
// // return {
|
|
1133
|
-
// // success: receipt?.status === 1,
|
|
1134
|
-
// // hash: receipt?.hash || tx.hash
|
|
1135
|
-
// // };
|
|
1136
|
-
// // }
|
|
1137
|
-
|
|
1138
|
-
// /**
|
|
1139
|
-
// * Verify a stored savings address matches the derived address
|
|
1140
|
-
// *
|
|
1141
|
-
// * Security: Prevents database tampering attacks.
|
|
1142
|
-
// *
|
|
1143
|
-
// * @param accountIndex - The account index to verify
|
|
1144
|
-
// * @param storedAddress - The address from storage/database
|
|
1145
|
-
// * @returns Verification result
|
|
1146
|
-
// *
|
|
1147
|
-
// * @example
|
|
1148
|
-
// * const result = wallet.verifySavingsAddress(1, storedAddress);
|
|
1149
|
-
// * if (!result.isValid) {
|
|
1150
|
-
// * console.error("Security alert: Address tampering detected!");
|
|
1151
|
-
// * }
|
|
1152
|
-
// */
|
|
1153
|
-
// verifySavingsAddress(accountIndex: number, storedAddress: Hex): AddressVerificationResult {
|
|
1154
|
-
// return this.getSavingsManager().verifySavingsAddress(accountIndex, storedAddress);
|
|
1155
|
-
// }
|
|
1156
|
-
|
|
1157
|
-
// /**
|
|
1158
|
-
// * Audit multiple savings addresses at once
|
|
1159
|
-
// *
|
|
1160
|
-
// * @param addresses - Map of accountIndex to stored address
|
|
1161
|
-
// * @returns Audit result with summary and details
|
|
1162
|
-
// *
|
|
1163
|
-
// * @example
|
|
1164
|
-
// * const addresses = new Map([[1, "0xabc..."], [2, "0xdef..."]]);
|
|
1165
|
-
// * const audit = wallet.auditSavingsAddresses(addresses);
|
|
1166
|
-
// * console.log(`Valid: ${audit.valid}/${audit.total}`);
|
|
1167
|
-
// */
|
|
1168
|
-
// auditSavingsAddresses(addresses: Map<number, Hex>): SavingsAuditResult {
|
|
1169
|
-
// return this.getSavingsManager().auditSavingsAddresses(addresses);
|
|
1170
|
-
// }
|
|
1171
|
-
|
|
1172
|
-
// /**
|
|
1173
|
-
// * Get savings account information without exposing private key
|
|
1174
|
-
// *
|
|
1175
|
-
// * @param accountIndex - The account index
|
|
1176
|
-
// * @returns Public account information (address and derivation path)
|
|
1177
|
-
// *
|
|
1178
|
-
// * @example
|
|
1179
|
-
// * const info = wallet.getSavingsAccountInfo(1);
|
|
1180
|
-
// * console.log(`Address: ${info.address}`);
|
|
1181
|
-
// * console.log(`Path: ${info.derivationPath}`); // m/44'/60'/1'/0/0
|
|
1182
|
-
// */
|
|
1183
|
-
// getSavingsAccountInfo(accountIndex: number): Omit<SavingsAccount, 'privateKey'> {
|
|
1184
|
-
// return this.getSavingsManager().getSavingsAccountInfo(accountIndex);
|
|
1185
|
-
// }
|
|
1186
|
-
|
|
1187
|
-
// // ============================================
|
|
1188
|
-
// // Smart Savings Methods (EIP-7702)
|
|
1189
|
-
// // ============================================
|
|
1190
|
-
|
|
1191
|
-
// /**
|
|
1192
|
-
// * Get or create the SmartSavingsManager instance (lazy initialization)
|
|
1193
|
-
// * @private
|
|
1194
|
-
// */
|
|
1195
|
-
// private getSmartSavingsManager(): SmartSavingsManager {
|
|
1196
|
-
// if (!this.smartSavingsManager) {
|
|
1197
|
-
// this.smartSavingsManager = new SmartSavingsManager(this.config);
|
|
1198
|
-
// }
|
|
1199
|
-
// return this.smartSavingsManager;
|
|
1200
|
-
// }
|
|
1201
|
-
|
|
1202
|
-
// /**
|
|
1203
|
-
// * Upgrade a savings account to a smart account with EIP-7702 delegation
|
|
1204
|
-
// *
|
|
1205
|
-
// * This enables advanced features:
|
|
1206
|
-
// * - Lock modules for time-locked savings
|
|
1207
|
-
// * - Hooks for spend & save
|
|
1208
|
-
// * - Session keys for periodic savings
|
|
1209
|
-
// * - Sponsored transactions via paymaster
|
|
1210
|
-
// *
|
|
1211
|
-
// * @param accountIndex - The savings account index to upgrade
|
|
1212
|
-
// * @param options - Optional smart wallet configuration
|
|
1213
|
-
// * @param autoInitialize - Whether to initialize the smart wallet (default: false)
|
|
1214
|
-
// * @returns SmartSavingsAccount with EVMSmartWallet instance
|
|
1215
|
-
// *
|
|
1216
|
-
// * @example
|
|
1217
|
-
// * // Upgrade without initialization
|
|
1218
|
-
// * const smartSavings = await wallet.upgradeSavingsToSmartAccount(1);
|
|
1219
|
-
// * await smartSavings.smartWallet.initialize(); // Initialize separately
|
|
1220
|
-
// *
|
|
1221
|
-
// * @example
|
|
1222
|
-
// * // Upgrade and initialize in one step
|
|
1223
|
-
// * const smartSavings = await wallet.upgradeSavingsToSmartAccount(1, {}, true);
|
|
1224
|
-
// * // Ready to use immediately
|
|
1225
|
-
// */
|
|
1226
|
-
// async upgradeSavingsToSmartAccount(
|
|
1227
|
-
// accountIndex: number,
|
|
1228
|
-
// options?: SmartWalletOptions,
|
|
1229
|
-
// autoInitialize: boolean = false
|
|
1230
|
-
// ): Promise<SmartSavingsAccount> {
|
|
1231
|
-
// const manager = this.getSmartSavingsManager();
|
|
1232
|
-
|
|
1233
|
-
// // First derive the basic savings account
|
|
1234
|
-
// const basicSavings = this.deriveSavingsAccount(accountIndex);
|
|
1235
|
-
|
|
1236
|
-
// // Then upgrade to smart account
|
|
1237
|
-
// if (autoInitialize) {
|
|
1238
|
-
// return await manager.upgradeSavingsAndInitialize(basicSavings, options);
|
|
1239
|
-
// } else {
|
|
1240
|
-
// return await manager.upgradeSavingsToSmartAccount(basicSavings, options);
|
|
1241
|
-
// }
|
|
1242
|
-
// }
|
|
1243
|
-
|
|
1244
|
-
// /**
|
|
1245
|
-
// * Check if smart savings is supported on this chain
|
|
1246
|
-
// *
|
|
1247
|
-
// * @returns true if chain supports Account Abstraction
|
|
1248
|
-
// *
|
|
1249
|
-
// * @example
|
|
1250
|
-
// * if (wallet.isSmartSavingsSupported()) {
|
|
1251
|
-
// * const smartSavings = await wallet.upgradeSavingsToSmartAccount(1);
|
|
1252
|
-
// * } else {
|
|
1253
|
-
// * console.log("This chain doesn't support smart savings");
|
|
1254
|
-
// * }
|
|
1255
|
-
// */
|
|
1256
|
-
// isSmartSavingsSupported(): boolean {
|
|
1257
|
-
// try {
|
|
1258
|
-
// const manager = this.getSmartSavingsManager();
|
|
1259
|
-
// return manager.canUpgradeToSmartAccount();
|
|
1260
|
-
// } catch (error) {
|
|
1261
|
-
// return false;
|
|
1262
|
-
// }
|
|
1263
|
-
// }
|
|
1264
1097
|
}
|
|
1265
|
-
|
package/utils/evm/utils.ts
CHANGED
|
@@ -13,6 +13,8 @@ import {
|
|
|
13
13
|
encodeFunctionData,
|
|
14
14
|
parseEther,
|
|
15
15
|
formatEther,
|
|
16
|
+
createPublicClient,
|
|
17
|
+
http,
|
|
16
18
|
} from 'viem'
|
|
17
19
|
export interface TransactionParams {
|
|
18
20
|
to: string
|
|
@@ -236,6 +238,16 @@ export const fromChainToViemChain = (config: ChainWalletConfig): Chain => {
|
|
|
236
238
|
|
|
237
239
|
|
|
238
240
|
}
|
|
241
|
+
|
|
242
|
+
|
|
243
|
+
export const createPublicClientFromChainConfig = (chain: ChainWalletConfig): PublicClient => {
|
|
244
|
+
return createPublicClient({
|
|
245
|
+
chain: fromChainToViemChain(chain),
|
|
246
|
+
transport: http(chain.rpcUrl)
|
|
247
|
+
});
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
|
|
239
251
|
export function viemReceiptToEthersReceipt(
|
|
240
252
|
receipt: ViemTransactionReceipt,
|
|
241
253
|
): EthersTransactionReceipt {
|
package/utils/index.ts
CHANGED
|
@@ -6,7 +6,7 @@ export * from "./vm"
|
|
|
6
6
|
// Note: Utility functions (discoverTokens, getTokenBalance, etc.) have name conflicts
|
|
7
7
|
// Import them directly from './evm' or './svm' submodules when needed
|
|
8
8
|
export { EVMVM, EVMChainWallet, EVMSmartWallet } from "./evm"
|
|
9
|
-
export { SVMVM, SVMChainWallet, } from "./svm"
|
|
9
|
+
export { SVMVM, SVMChainWallet, SVMChainAddress } from "./svm"
|
|
10
10
|
|
|
11
11
|
// Re-export all EVM exports as namespace to avoid conflicts
|
|
12
12
|
export * as evm from "./evm"
|
|
@@ -17,4 +17,4 @@ export * from "./constant"
|
|
|
17
17
|
export * from "bs58"
|
|
18
18
|
export * from "@solana/web3.js"
|
|
19
19
|
export * from "./price"
|
|
20
|
-
export * from "./utils"
|
|
20
|
+
export * from "./utils"
|
|
@@ -43,7 +43,7 @@ import BN from "bn.js";
|
|
|
43
43
|
*/
|
|
44
44
|
export class SVMSavingsManager extends SavingsManager<PublicKey, Connection, Keypair> {
|
|
45
45
|
coinType = 501;
|
|
46
|
-
derivationPathBase = "m/44'/501'/";
|
|
46
|
+
derivationPathBase = "m/44'/501'/"; // Base path for account derivation
|
|
47
47
|
|
|
48
48
|
private rpcUrl: string;
|
|
49
49
|
private _client?: Connection;
|