@deserialize/multi-vm-wallet 1.3.3 → 1.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (50) hide show
  1. package/dist/IChainWallet.d.ts +2 -0
  2. package/dist/IChainWallet.js.map +1 -1
  3. package/dist/evm/evm.d.ts +14 -172
  4. package/dist/evm/evm.js +38 -504
  5. package/dist/evm/evm.js.map +1 -1
  6. package/dist/evm/transaction.utils.d.ts +3 -3
  7. package/dist/evm/utils.d.ts +115 -80
  8. package/dist/evm/utils.js +272 -497
  9. package/dist/evm/utils.js.map +1 -1
  10. package/dist/helpers/index.d.ts +1 -0
  11. package/dist/helpers/index.js +5 -0
  12. package/dist/helpers/index.js.map +1 -1
  13. package/dist/index.d.ts +1 -0
  14. package/dist/index.js +1 -0
  15. package/dist/index.js.map +1 -1
  16. package/dist/price.d.ts +2 -0
  17. package/dist/price.js +33 -0
  18. package/dist/price.js.map +1 -0
  19. package/dist/price.types.d.ts +38 -0
  20. package/dist/price.types.js +4 -0
  21. package/dist/price.types.js.map +1 -0
  22. package/dist/savings/index.d.ts +0 -0
  23. package/dist/savings/index.js +25 -0
  24. package/dist/savings/index.js.map +1 -0
  25. package/dist/savings/saving-actions.d.ts +29 -0
  26. package/dist/savings/saving-actions.js +56 -0
  27. package/dist/savings/saving-actions.js.map +1 -0
  28. package/dist/savings/savings-manager.d.ts +1 -1
  29. package/dist/savings/savings-manager.js +3 -3
  30. package/dist/savings/savings-manager.js.map +1 -1
  31. package/dist/svm/svm.d.ts +2 -0
  32. package/dist/svm/svm.js +12 -0
  33. package/dist/svm/svm.js.map +1 -1
  34. package/dist/test.js +7 -7
  35. package/dist/test.js.map +1 -1
  36. package/dist/vm.js.map +1 -1
  37. package/package.json +1 -1
  38. package/utils/IChainWallet.ts +2 -0
  39. package/utils/evm/evm.ts +326 -681
  40. package/utils/evm/utils.ts +438 -662
  41. package/utils/helpers/index.ts +6 -0
  42. package/utils/index.ts +1 -0
  43. package/utils/price.ts +37 -0
  44. package/utils/price.types.ts +45 -0
  45. package/utils/savings/index.ts +28 -0
  46. package/utils/savings/saving-actions.ts +77 -0
  47. package/utils/savings/savings-manager.ts +1 -1
  48. package/utils/svm/svm.ts +16 -2
  49. package/utils/test.ts +13 -4
  50. package/utils/vm.ts +2 -1
@@ -18,6 +18,12 @@ export class HelperAPI {
18
18
  return 'mainnet';
19
19
  }
20
20
 
21
+ static async getPrice(tokenOrNativeSymbol: string, chainId: number, vm: vmTypes) {
22
+ const res = await fetch("" + BASE_URL + `/${vm}/prices?chainId${chainId}tokenAddresses=${tokenOrNativeSymbol}`);
23
+ const data = await res.json();
24
+ return data;
25
+ }
26
+
21
27
  static async getUserToken(wallet: string, vm: vmTypes, chainId: number) {
22
28
  // Only try RouteScan for EVM chains
23
29
  if (vm === 'EVM') {
package/utils/index.ts CHANGED
@@ -6,3 +6,4 @@ export * from "./svm"
6
6
  export * from "./constant"
7
7
  export * from "bs58"
8
8
  export * from "@solana/web3.js"
9
+ export * from "./price"
package/utils/price.ts ADDED
@@ -0,0 +1,37 @@
1
+ // packages/utils/price.ts
2
+ import { PriceFetchingConfig, PriceFetchingResult, PriceResponse } from './price.types';
3
+
4
+ const API_BASE_URL = 'https://helper.decane.app';
5
+
6
+ export async function fetchPrices(config: PriceFetchingConfig): Promise<PriceFetchingResult> {
7
+ const { vm, chainId, tokenAddresses } = config;
8
+
9
+ if (tokenAddresses.length === 0) {
10
+ return { data: { vm, chainId, prices: [] } as PriceResponse };
11
+ }
12
+
13
+ const url = new URL(`${API_BASE_URL}/${vm}/prices`);
14
+ url.searchParams.append('chainId', String(chainId));
15
+ url.searchParams.append('tokenAddresses', tokenAddresses.join(','));
16
+
17
+ try {
18
+ const response = await fetch(url.toString());
19
+
20
+ if (!response.ok) {
21
+ const errorData = await response.json();
22
+ return { error: errorData };
23
+ }
24
+
25
+ const data = await response.json();
26
+ return { data: data.data };
27
+ } catch (error: any) {
28
+ return {
29
+ error: {
30
+ code: 500,
31
+ message: error.message || 'An unexpected error occurred',
32
+ stack: error.stack,
33
+ errors: [],
34
+ },
35
+ };
36
+ }
37
+ }
@@ -0,0 +1,45 @@
1
+ // price.types.ts
2
+
3
+ export interface TokenPrice {
4
+ tokenAddress: string;
5
+ price: number;
6
+ priceChange24h?: number;
7
+ marketCap?: number;
8
+ volume24h?: number;
9
+ timestamp: number;
10
+ }
11
+
12
+ export interface EvmPriceResponse {
13
+ chainId: number;
14
+ vm: 'EVM';
15
+ prices: TokenPrice[];
16
+ }
17
+
18
+ export interface SvmPriceResponse {
19
+ chainId: number;
20
+ vm: 'SVM';
21
+ prices: (TokenPrice & { symbol?: string; name?: string })[];
22
+ }
23
+
24
+ export type PriceResponse = EvmPriceResponse | SvmPriceResponse;
25
+
26
+ export interface PriceApiError {
27
+ code: number;
28
+ message: string;
29
+ stack: string;
30
+ errors: any[];
31
+ }
32
+
33
+ export type VmType = 'EVM' | 'SVM';
34
+
35
+ export interface PriceFetchingConfig {
36
+ vm: VmType;
37
+ chainId: number;
38
+ tokenAddresses: string[];
39
+ }
40
+
41
+ export interface PriceFetchingResult {
42
+ data?: PriceResponse;
43
+ error?: PriceApiError;
44
+ }
45
+
@@ -0,0 +1,28 @@
1
+ // import { WalletClient, PublicClient } from "viem";
2
+ // import { SavingsActions } from "./saving-actions";
3
+
4
+
5
+ // export interface ExtendedWalletClient extends WalletClient {
6
+ // extendSavings?: (mnemonic: string, walletIndex?: number) => SavingsActions;
7
+ // savingsActions?: SavingsActions;
8
+ // }
9
+
10
+ // /**
11
+ // * Adds savings functionality to an existing WalletClient
12
+ // */
13
+ // export function extendWalletClientWithSavings(
14
+ // wallet: WalletClient,
15
+ // client: PublicClient,
16
+ // walletIndex: number = 0
17
+ // ): ExtendedWalletClient {
18
+ // const extended = wallet as ExtendedWalletClient;
19
+
20
+ // extended.extendSavings = (mnemonic: string, index: number = walletIndex) => {
21
+ // if (!extended.savingsActions) {
22
+ // extended.savingsActions = new SavingsActions(mnemonic, index);
23
+ // }
24
+ // return extended.savingsActions;
25
+ // };
26
+
27
+ // return extended;
28
+ // }
@@ -0,0 +1,77 @@
1
+ import { EVMDeriveChildPrivateKey } from "../walletBip32";
2
+ import { ethers } from "ethers";
3
+ import { WalletClient, PublicClient, Hex, ChainConfig } from "viem";
4
+ import { } from "../utils";
5
+ import { TransactionResult } from "../types";
6
+ import { sendERC20Token, sendNativeToken } from "../evm";
7
+
8
+ /**
9
+ * Handles multi-pocket savings accounts for an EVM wallet
10
+ */
11
+ export class SavingsManager {
12
+ private mnemonic: string;
13
+ private walletIndex: number;
14
+ private pockets: Map<number, { privateKey: string; address: string; derivationPath: string }> = new Map();
15
+
16
+ constructor(mnemonic: string, walletIndex: number = 0, chain: ChainConfig) {
17
+ this.mnemonic = mnemonic;
18
+ this.walletIndex = walletIndex;
19
+ }
20
+
21
+ getTotalTokenBalanceOfAllPockets(tokens: string[], pockets: number[]) {
22
+
23
+ const balances = pockets.map((p: number) => { })
24
+ }
25
+
26
+ getPocketTokenBalance(tokens: string[], pocket: number) {
27
+
28
+ const balances = tokens.map((t: string) => {
29
+
30
+ })
31
+ }
32
+
33
+ /**
34
+ * Derive a pocket (savings account) at accountIndex
35
+ */
36
+ derivePocket(accountIndex: number) {
37
+ const derivationPath = `m/44'/60'/${accountIndex}'/0/${this.walletIndex}`;
38
+ const { privateKey } = EVMDeriveChildPrivateKey(this.mnemonic, this.walletIndex, `m/44'/60'/${accountIndex}'/0/`);
39
+ const wallet = new ethers.Wallet(privateKey);
40
+
41
+ const pocket = { privateKey, address: wallet.address, derivationPath };
42
+ this.pockets.set(accountIndex, pocket);
43
+ return pocket;
44
+ }
45
+
46
+ getPocket(accountIndex: number) {
47
+ if (!this.pockets.has(accountIndex)) {
48
+ return this.derivePocket(accountIndex);
49
+ }
50
+ return this.pockets.get(accountIndex)!;
51
+ }
52
+ async transferToPocket(
53
+ mainWallet: WalletClient,
54
+ client: PublicClient,
55
+ accountIndex: number,
56
+ amount: string
57
+ ): Promise<TransactionResult> {
58
+ const pocket = this.getPocket(accountIndex);
59
+ return await sendNativeToken(mainWallet, client, pocket.address as Hex, amount, 5);
60
+ }
61
+
62
+ async transferTokenToPocket(
63
+ mainWallet: WalletClient,
64
+ client: PublicClient,
65
+ tokenAddress: string,
66
+ accountIndex: number,
67
+ amount: bigint
68
+ ): Promise<TransactionResult> {
69
+ const pocket = this.getPocket(accountIndex);
70
+ return await sendERC20Token(mainWallet, client, tokenAddress as Hex, pocket.address as Hex, amount, 5);
71
+ }
72
+
73
+ verifyPocketAddress(accountIndex: number, storedAddress: string) {
74
+ const pocket = this.getPocket(accountIndex);
75
+ return pocket.address.toLowerCase() === storedAddress.toLowerCase();
76
+ }
77
+ }
@@ -35,7 +35,7 @@ import {
35
35
  * 3. Transaction builders for deposits and withdrawals
36
36
  * 4. Batch auditing of stored addresses
37
37
  */
38
- export class SavingsManager {
38
+ export class SavingsManagerOld {
39
39
  private vm: VM<any, any, any>;
40
40
 
41
41
  constructor(vm: VM<any, any, any>) {
package/utils/svm/svm.ts CHANGED
@@ -24,6 +24,8 @@ import {
24
24
  import BN from "bn.js";
25
25
  import nacl from "tweetnacl";
26
26
  import base58 from "bs58";
27
+ import { fetchPrices } from "../price";
28
+ import { PriceResponse } from "../price.types";
27
29
  import { getSVMTransactionHistory, SVMTransactionHistoryItem } from "./transactionParsing";
28
30
 
29
31
 
@@ -107,8 +109,6 @@ export class SVMVM extends VM<PublicKey, Keypair, Connection> {
107
109
  const seed = VM.mnemonicToSeed(mnemonic)
108
110
  return new SVMVM(seed)
109
111
  }
110
-
111
-
112
112
  }
113
113
 
114
114
  export class SVMChainWallet extends ChainWallet<PublicKey, Keypair, Connection> {
@@ -202,6 +202,20 @@ export class SVMChainWallet extends ChainWallet<PublicKey, Keypair, Connection>
202
202
  return await SVMVM.getTokenInfo(tokenAddress, this.connection!)
203
203
  }
204
204
 
205
+ async getPrices(tokenAddresses: string[]): Promise<PriceResponse> {
206
+ const result = await fetchPrices({
207
+ vm: 'SVM',
208
+ chainId: this.config.chainId,
209
+ tokenAddresses,
210
+ });
211
+
212
+ if (result.error) {
213
+ throw new Error(result.error.message);
214
+ }
215
+
216
+ return result.data as PriceResponse;
217
+ }
218
+
205
219
  async swap(fromToken: TokenInfo, toToken: PublicKey, amount: number, slippage: number = 50): Promise<TransactionResult> {
206
220
  try {
207
221
  if (amount <= 0) {
package/utils/test.ts CHANGED
@@ -30,11 +30,11 @@ import { toSpendingLimitHook } from "@zerodev/hooks"
30
30
  // const seed = VM.mnemonicToSeed(mnemonic)
31
31
  const pKey = ""
32
32
 
33
- const testUserKeyPair = Keypair.fromSecretKey(base58.decode(pKey));
33
+ // const testUserKeyPair = Keypair.fromSecretKey(base58.decode(pKey));
34
34
  // const x = testUserKeyPair instanceof Keypair;
35
35
 
36
- const evmPrivKey = ""
37
- const evmPrivateKeyExposed = ""
36
+ const evmPrivKey = "0xc9ca95aa5f40bae8b0f741ec89acc07b837590b2f9f818d3439df98c6e4f8dbe"
37
+ const evmPrivateKeyExposed = "0x92cccc7792024dcac5992e5d2986dade41770acfd3dab0fe98ee953ed1bf0c3a"
38
38
  // const vm = new SVMVM(seed)
39
39
 
40
40
 
@@ -69,7 +69,8 @@ const evmChainConfig: ChainWalletConfig = {
69
69
  enabled: true,
70
70
  entryPoints: [
71
71
  {
72
- address: entryPoint07Address,
72
+ address: entryPoint07Address
73
+ ,
73
74
  version: "0.7"
74
75
  }
75
76
  ],
@@ -205,6 +206,14 @@ const testModule = async () => {
205
206
  }
206
207
 
207
208
 
209
+ const testPrice = async () => {
210
+
211
+ walletA.getPrices(['0x98d0baa52b2D063E780DE12F615f963Fe8537553']).then(console.log)
212
+ }
213
+
214
+ // testPrice()
215
+
216
+
208
217
 
209
218
  // console.log('wallet: ', wallet);
210
219
  // getTokenInfo(new PublicKey("9BB6NFEcjBCtnNLFko2FqVQBq8HHM13kCyYcdQbgpump"), wallet.connection!).then(e => console.log('token info: ', e))
package/utils/vm.ts CHANGED
@@ -1,7 +1,8 @@
1
-
2
1
  import { Balance, ChainWalletConfig, TokenInfo, vmTypes } from "./types";
3
2
  import * as bip39 from "@scure/bip39";
4
3
  import CryptoJS from "crypto-js";
4
+ import { PriceResponse } from "./price.types";
5
+
5
6
  // Abstract Base Classes
6
7
  export abstract class VM<AddressType, PrivateKeyType, ConnectionType> {
7
8
  protected seed: string;