@deserialize/multi-vm-wallet 1.3.2 → 1.3.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/.claude/settings.local.json +2 -1
- package/dist/constant.js +60 -16
- package/dist/constant.js.map +1 -1
- package/dist/evm/aa-service/index.d.ts +1 -1
- package/dist/evm/aa-service/index.js +1 -2
- package/dist/evm/aa-service/index.js.map +1 -1
- package/dist/evm/aa-service/lib/kernel-account.d.ts +1 -1
- package/dist/evm/aa-service/lib/kernel-account.js +22 -6
- package/dist/evm/aa-service/lib/kernel-account.js.map +1 -1
- package/dist/evm/aa-service/lib/session-keys.d.ts +14 -17
- package/dist/evm/aa-service/lib/session-keys.js +40 -58
- package/dist/evm/aa-service/lib/session-keys.js.map +1 -1
- package/dist/evm/aa-service/lib/type.d.ts +2 -1
- package/dist/evm/aa-service/lib/type.js.map +1 -1
- package/dist/evm/aa-service/services/account-abstraction.d.ts +3 -29
- package/dist/evm/aa-service/services/account-abstraction.js +3 -67
- package/dist/evm/aa-service/services/account-abstraction.js.map +1 -1
- package/dist/evm/aa-service/services/bundler.js +2 -1
- package/dist/evm/aa-service/services/bundler.js.map +1 -1
- package/dist/evm/evm.d.ts +161 -1
- package/dist/evm/evm.js +247 -0
- package/dist/evm/evm.js.map +1 -1
- package/dist/evm/smartWallet.d.ts +11 -43
- package/dist/evm/smartWallet.js +136 -116
- package/dist/evm/smartWallet.js.map +1 -1
- package/dist/evm/utils.js +0 -1
- package/dist/evm/utils.js.map +1 -1
- package/dist/privacy/artifact-manager.d.ts +117 -0
- package/dist/privacy/artifact-manager.js +251 -0
- package/dist/privacy/artifact-manager.js.map +1 -0
- package/dist/privacy/broadcaster-client.d.ts +166 -0
- package/dist/privacy/broadcaster-client.js +261 -0
- package/dist/privacy/broadcaster-client.js.map +1 -0
- package/dist/privacy/index.d.ts +34 -0
- package/dist/privacy/index.js +56 -0
- package/dist/privacy/index.js.map +1 -0
- package/dist/privacy/network-config.d.ts +57 -0
- package/dist/privacy/network-config.js +118 -0
- package/dist/privacy/network-config.js.map +1 -0
- package/dist/privacy/poi-helper.d.ts +161 -0
- package/dist/privacy/poi-helper.js +249 -0
- package/dist/privacy/poi-helper.js.map +1 -0
- package/dist/privacy/railgun-engine.d.ts +135 -0
- package/dist/privacy/railgun-engine.js +205 -0
- package/dist/privacy/railgun-engine.js.map +1 -0
- package/dist/privacy/railgun-privacy-wallet.d.ts +288 -0
- package/dist/privacy/railgun-privacy-wallet.js +539 -0
- package/dist/privacy/railgun-privacy-wallet.js.map +1 -0
- package/dist/privacy/types.d.ts +229 -0
- package/dist/privacy/types.js +26 -0
- package/dist/privacy/types.js.map +1 -0
- package/dist/savings/savings-manager.d.ts +126 -0
- package/dist/savings/savings-manager.js +234 -0
- package/dist/savings/savings-manager.js.map +1 -0
- package/dist/savings/smart-savings.d.ts +74 -0
- package/dist/savings/smart-savings.js +152 -0
- package/dist/savings/smart-savings.js.map +1 -0
- package/dist/savings/types.d.ts +125 -0
- package/dist/savings/types.js +9 -0
- package/dist/savings/types.js.map +1 -0
- package/dist/svm/svm.d.ts +16 -0
- package/dist/svm/svm.js +23 -0
- package/dist/svm/svm.js.map +1 -1
- package/dist/test.js +53 -15
- package/dist/test.js.map +1 -1
- package/dist/vm.d.ts +14 -0
- package/dist/vm.js.map +1 -1
- package/package.json +2 -1
- package/utils/constant.ts +63 -16
- package/utils/evm/aa-service/index.ts +0 -1
- package/utils/evm/aa-service/lib/kernel-account.ts +23 -8
- package/utils/evm/aa-service/lib/session-keys.ts +58 -60
- package/utils/evm/aa-service/lib/type.ts +2 -1
- package/utils/evm/aa-service/services/account-abstraction.ts +10 -76
- package/utils/evm/aa-service/services/bundler.ts +2 -1
- package/utils/evm/evm.ts +300 -0
- package/utils/evm/smartWallet.ts +118 -128
- package/utils/evm/utils.ts +1 -1
- package/utils/savings/savings-manager.ts +271 -0
- package/utils/savings/smart-savings.ts +184 -0
- package/utils/savings/types.ts +135 -0
- package/utils/svm/svm.ts +27 -0
- package/utils/test.ts +82 -18
- package/utils/vm.ts +10 -0
|
@@ -0,0 +1,229 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* RAILGUN Privacy Integration Types
|
|
3
|
+
*
|
|
4
|
+
* Complete type definitions for RAILGUN privacy features.
|
|
5
|
+
* All types are designed to be stateless - implementer controls storage.
|
|
6
|
+
*/
|
|
7
|
+
import type { NetworkName } from '@railgun-community/shared-models';
|
|
8
|
+
/**
|
|
9
|
+
* LevelDB-compatible database interface
|
|
10
|
+
* Implementer must provide this (level-js, level-node, etc.)
|
|
11
|
+
*/
|
|
12
|
+
export type RailgunDatabase = any;
|
|
13
|
+
/**
|
|
14
|
+
* Artifact storage interface for zkSNARK circuits
|
|
15
|
+
* Implementer must provide file system access
|
|
16
|
+
*/
|
|
17
|
+
export interface ArtifactStore {
|
|
18
|
+
getFile(path: string): Promise<Buffer | Uint8Array>;
|
|
19
|
+
storeFile(dir: string, path: string, item: string | Uint8Array): Promise<void>;
|
|
20
|
+
fileExists(path: string): Promise<boolean>;
|
|
21
|
+
}
|
|
22
|
+
export interface RailgunEngineConfig {
|
|
23
|
+
/** Name for your wallet (max 16 chars, lowercase) */
|
|
24
|
+
walletSource: string;
|
|
25
|
+
/** LevelDB-compatible database (implementer provides) */
|
|
26
|
+
db: RailgunDatabase;
|
|
27
|
+
/** Artifact store for circuits (implementer provides) */
|
|
28
|
+
artifactStore: ArtifactStore;
|
|
29
|
+
/** POI aggregator node URLs */
|
|
30
|
+
poiNodeURLs: string[];
|
|
31
|
+
/** false for web/node, true for React Native */
|
|
32
|
+
useNativeArtifacts?: boolean;
|
|
33
|
+
/** Custom POI lists (optional) */
|
|
34
|
+
customPOILists?: any[];
|
|
35
|
+
/** Skip merkletree scans (true for shield-only apps) */
|
|
36
|
+
skipMerkletreeScans?: boolean;
|
|
37
|
+
/** Enable verbose scan logging */
|
|
38
|
+
verboseScanLogging?: boolean;
|
|
39
|
+
/** Enable debug mode */
|
|
40
|
+
shouldDebug?: boolean;
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* Pre-downloaded circuit artifacts (optional)
|
|
44
|
+
* If provided, engine startup is faster
|
|
45
|
+
*/
|
|
46
|
+
export interface PreloadedArtifacts {
|
|
47
|
+
/** Map of artifact path to file content */
|
|
48
|
+
artifacts: Map<string, Buffer | Uint8Array>;
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* RAILGUN wallet information (what implementer should store)
|
|
52
|
+
*/
|
|
53
|
+
export interface RailgunWalletInfo {
|
|
54
|
+
/** Unique wallet identifier */
|
|
55
|
+
railgunWalletID: string;
|
|
56
|
+
/** 0zk address (shareable, like 0zkabcd...) */
|
|
57
|
+
railgunAddress: string;
|
|
58
|
+
/** Viewing private key (for read-only access) */
|
|
59
|
+
viewingPrivateKey: string;
|
|
60
|
+
/** Spending public key */
|
|
61
|
+
spendingPublicKey: string;
|
|
62
|
+
/** Creation block numbers per chain (for faster syncing) */
|
|
63
|
+
creationBlockNumberMap?: Record<string, number>;
|
|
64
|
+
}
|
|
65
|
+
/**
|
|
66
|
+
* POI balance bucket categories
|
|
67
|
+
*/
|
|
68
|
+
export declare enum BalanceBucket {
|
|
69
|
+
Spendable = "Spendable",
|
|
70
|
+
ShieldPending = "ShieldPending",
|
|
71
|
+
ShieldBlocked = "ShieldBlocked",
|
|
72
|
+
ProofSubmitted = "ProofSubmitted",
|
|
73
|
+
MissingInternalPOI = "MissingInternalPOI",
|
|
74
|
+
MissingExternalPOI = "MissingExternalPOI",
|
|
75
|
+
Spent = "Spent"
|
|
76
|
+
}
|
|
77
|
+
/**
|
|
78
|
+
* Private token balance
|
|
79
|
+
*/
|
|
80
|
+
export interface PrivateBalance {
|
|
81
|
+
tokenAddress: string;
|
|
82
|
+
amount: bigint;
|
|
83
|
+
bucket: BalanceBucket;
|
|
84
|
+
symbol?: string;
|
|
85
|
+
decimals?: number;
|
|
86
|
+
}
|
|
87
|
+
/**
|
|
88
|
+
* Balance update callback
|
|
89
|
+
*/
|
|
90
|
+
export type BalanceUpdateCallback = (balances: PrivateBalance[], walletID: string, network: NetworkName) => void;
|
|
91
|
+
/**
|
|
92
|
+
* Merkletree scan progress callback
|
|
93
|
+
*/
|
|
94
|
+
export type ScanProgressCallback = (progress: number, network: NetworkName) => void;
|
|
95
|
+
/**
|
|
96
|
+
* Base transaction interface
|
|
97
|
+
*/
|
|
98
|
+
export interface BaseRailgunTransaction {
|
|
99
|
+
to: string;
|
|
100
|
+
data: string;
|
|
101
|
+
value?: bigint;
|
|
102
|
+
gasLimit: bigint;
|
|
103
|
+
}
|
|
104
|
+
/**
|
|
105
|
+
* Shield transaction (Public → Private)
|
|
106
|
+
*/
|
|
107
|
+
export interface ShieldTransaction extends BaseRailgunTransaction {
|
|
108
|
+
type: 'shield';
|
|
109
|
+
tokenAddress: string;
|
|
110
|
+
shieldAmount: bigint;
|
|
111
|
+
railgunAddress: string;
|
|
112
|
+
fee: bigint;
|
|
113
|
+
}
|
|
114
|
+
/**
|
|
115
|
+
* Unshield transaction (Private → Public)
|
|
116
|
+
*/
|
|
117
|
+
export interface UnshieldTransaction extends BaseRailgunTransaction {
|
|
118
|
+
type: 'unshield';
|
|
119
|
+
tokenAddress: string;
|
|
120
|
+
unshieldAmount: bigint;
|
|
121
|
+
recipientAddress: string;
|
|
122
|
+
fee: bigint;
|
|
123
|
+
proof: string;
|
|
124
|
+
publicInputs: string[];
|
|
125
|
+
}
|
|
126
|
+
/**
|
|
127
|
+
* Private transfer transaction (Private → Private)
|
|
128
|
+
*/
|
|
129
|
+
export interface PrivateTransferTransaction extends BaseRailgunTransaction {
|
|
130
|
+
type: 'private_transfer';
|
|
131
|
+
tokenAddress: string;
|
|
132
|
+
transferAmount: bigint;
|
|
133
|
+
recipientRailgunAddress: string;
|
|
134
|
+
broadcasterFee?: {
|
|
135
|
+
tokenAddress: string;
|
|
136
|
+
amount: bigint;
|
|
137
|
+
};
|
|
138
|
+
proof: string;
|
|
139
|
+
publicInputs: string[];
|
|
140
|
+
}
|
|
141
|
+
export interface ShieldOptions {
|
|
142
|
+
/** Optional memo text */
|
|
143
|
+
memoText?: string;
|
|
144
|
+
}
|
|
145
|
+
export interface UnshieldOptions {
|
|
146
|
+
/** Optional memo text */
|
|
147
|
+
memoText?: string;
|
|
148
|
+
/** Broadcaster fee for anonymity (optional) */
|
|
149
|
+
broadcasterFee?: {
|
|
150
|
+
tokenAddress: string;
|
|
151
|
+
amount: bigint;
|
|
152
|
+
};
|
|
153
|
+
/** Use public wallet to pay gas (false = use broadcaster) */
|
|
154
|
+
sendWithPublicWallet?: boolean;
|
|
155
|
+
/** Minimum gas price */
|
|
156
|
+
minGasPrice?: bigint;
|
|
157
|
+
/** Proof generation progress callback */
|
|
158
|
+
onProgress?: (progress: number) => void;
|
|
159
|
+
}
|
|
160
|
+
export interface PrivateTransferOptions {
|
|
161
|
+
/** Optional memo text */
|
|
162
|
+
memoText?: string;
|
|
163
|
+
/** Show sender address to recipient */
|
|
164
|
+
showSenderToRecipient?: boolean;
|
|
165
|
+
/** Broadcaster fee (REQUIRED for anonymity) */
|
|
166
|
+
broadcasterFee: {
|
|
167
|
+
tokenAddress: string;
|
|
168
|
+
amount: bigint;
|
|
169
|
+
};
|
|
170
|
+
/** Minimum gas price */
|
|
171
|
+
minGasPrice?: bigint;
|
|
172
|
+
/** Proof generation progress callback */
|
|
173
|
+
onProgress?: (progress: number) => void;
|
|
174
|
+
}
|
|
175
|
+
/**
|
|
176
|
+
* POI spendability check result
|
|
177
|
+
*/
|
|
178
|
+
export interface POISpendabilityResult {
|
|
179
|
+
isSpendable: boolean;
|
|
180
|
+
bucket: BalanceBucket;
|
|
181
|
+
remainingTime?: number;
|
|
182
|
+
estimatedSpendableAt?: Date;
|
|
183
|
+
}
|
|
184
|
+
/**
|
|
185
|
+
* Artifact download progress
|
|
186
|
+
*/
|
|
187
|
+
export interface ArtifactDownloadProgress {
|
|
188
|
+
current: number;
|
|
189
|
+
total: number;
|
|
190
|
+
percentage: number;
|
|
191
|
+
artifactName: string;
|
|
192
|
+
}
|
|
193
|
+
export type ArtifactDownloadCallback = (progress: ArtifactDownloadProgress) => void;
|
|
194
|
+
/**
|
|
195
|
+
* Artifact sync result
|
|
196
|
+
*/
|
|
197
|
+
export interface ArtifactSyncResult {
|
|
198
|
+
updated: boolean;
|
|
199
|
+
downloadedCount: number;
|
|
200
|
+
totalSize: number;
|
|
201
|
+
artifacts: string[];
|
|
202
|
+
}
|
|
203
|
+
/**
|
|
204
|
+
* RAILGUN network configuration
|
|
205
|
+
*/
|
|
206
|
+
export interface RailgunNetworkConfig {
|
|
207
|
+
name: NetworkName;
|
|
208
|
+
chainId: number;
|
|
209
|
+
publicName: string;
|
|
210
|
+
deploymentBlock: number;
|
|
211
|
+
}
|
|
212
|
+
/**
|
|
213
|
+
* Broadcaster information
|
|
214
|
+
*/
|
|
215
|
+
export interface BroadcasterInfo {
|
|
216
|
+
railgunAddress: string;
|
|
217
|
+
feePercentage: number;
|
|
218
|
+
availableNetworks: NetworkName[];
|
|
219
|
+
reliability: number;
|
|
220
|
+
}
|
|
221
|
+
export type BroadcasterFeeCallback = (tokenAddress: string, amount: bigint, network: NetworkName) => Promise<bigint>;
|
|
222
|
+
export interface NetworkFees {
|
|
223
|
+
/** Shield fee in basis points (default: 25 = 0.25%) */
|
|
224
|
+
shield: number;
|
|
225
|
+
/** Unshield fee in basis points (default: 25 = 0.25%) */
|
|
226
|
+
unshield: number;
|
|
227
|
+
/** NFT fee in basis points (default: 0) */
|
|
228
|
+
nft: number;
|
|
229
|
+
}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* RAILGUN Privacy Integration Types
|
|
4
|
+
*
|
|
5
|
+
* Complete type definitions for RAILGUN privacy features.
|
|
6
|
+
* All types are designed to be stateless - implementer controls storage.
|
|
7
|
+
*/
|
|
8
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
9
|
+
exports.BalanceBucket = void 0;
|
|
10
|
+
// ============================================
|
|
11
|
+
// Balance Types
|
|
12
|
+
// ============================================
|
|
13
|
+
/**
|
|
14
|
+
* POI balance bucket categories
|
|
15
|
+
*/
|
|
16
|
+
var BalanceBucket;
|
|
17
|
+
(function (BalanceBucket) {
|
|
18
|
+
BalanceBucket["Spendable"] = "Spendable";
|
|
19
|
+
BalanceBucket["ShieldPending"] = "ShieldPending";
|
|
20
|
+
BalanceBucket["ShieldBlocked"] = "ShieldBlocked";
|
|
21
|
+
BalanceBucket["ProofSubmitted"] = "ProofSubmitted";
|
|
22
|
+
BalanceBucket["MissingInternalPOI"] = "MissingInternalPOI";
|
|
23
|
+
BalanceBucket["MissingExternalPOI"] = "MissingExternalPOI";
|
|
24
|
+
BalanceBucket["Spent"] = "Spent";
|
|
25
|
+
})(BalanceBucket || (exports.BalanceBucket = BalanceBucket = {}));
|
|
26
|
+
//# sourceMappingURL=types.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../utils/privacy/types.ts"],"names":[],"mappings":";AAAA;;;;;GAKG;;;AA0FH,+CAA+C;AAC/C,gBAAgB;AAChB,+CAA+C;AAE/C;;GAEG;AACH,IAAY,aAQX;AARD,WAAY,aAAa;IACvB,wCAAuB,CAAA;IACvB,gDAA+B,CAAA;IAC/B,gDAA+B,CAAA;IAC/B,kDAAiC,CAAA;IACjC,0DAAyC,CAAA;IACzC,0DAAyC,CAAA;IACzC,gCAAe,CAAA;AACjB,CAAC,EARW,aAAa,6BAAb,aAAa,QAQxB"}
|
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Savings Manager
|
|
3
|
+
*
|
|
4
|
+
* Core logic for managing BIP-44 derived savings accounts.
|
|
5
|
+
* Provides security-first operations that always derive addresses from account indices.
|
|
6
|
+
*
|
|
7
|
+
* Security Model:
|
|
8
|
+
* - NEVER trust stored addresses without verification
|
|
9
|
+
* - ALWAYS derive addresses from accountIndex for transactions
|
|
10
|
+
* - Provide verification and audit tools for tamper detection
|
|
11
|
+
*/
|
|
12
|
+
import { Hex } from "viem";
|
|
13
|
+
import { VM } from "../vm";
|
|
14
|
+
import { SavingsAccount, AddressVerificationResult, SavingsAuditResult, TransferToSavingsOptions, WithdrawFromSavingsOptions } from "./types";
|
|
15
|
+
/**
|
|
16
|
+
* Manages BIP-44 derived savings accounts
|
|
17
|
+
*
|
|
18
|
+
* This class provides:
|
|
19
|
+
* 1. Account derivation from BIP-44 account indices
|
|
20
|
+
* 2. Address verification to prevent database tampering
|
|
21
|
+
* 3. Transaction builders for deposits and withdrawals
|
|
22
|
+
* 4. Batch auditing of stored addresses
|
|
23
|
+
*/
|
|
24
|
+
export declare class SavingsManager {
|
|
25
|
+
private vm;
|
|
26
|
+
constructor(vm: VM<any, any, any>);
|
|
27
|
+
/**
|
|
28
|
+
* Create a new savings account by deriving from account index
|
|
29
|
+
*
|
|
30
|
+
* @param accountIndex - BIP-44 account index (1+ for savings, 0 is main wallet)
|
|
31
|
+
* @returns SavingsAccount with derived private key and address
|
|
32
|
+
*
|
|
33
|
+
* @example
|
|
34
|
+
* const savingsAccount = manager.createSavingsAccount(1); // First savings account
|
|
35
|
+
* console.log(savingsAccount.address); // Derived address
|
|
36
|
+
* console.log(savingsAccount.derivationPath); // m/44'/60'/1'/0/0
|
|
37
|
+
*/
|
|
38
|
+
createSavingsAccount(accountIndex: number): SavingsAccount;
|
|
39
|
+
/**
|
|
40
|
+
* Verify a stored address matches the derived address for an account index
|
|
41
|
+
*
|
|
42
|
+
* Security: This prevents database tampering attacks where an attacker
|
|
43
|
+
* modifies stored addresses to redirect funds.
|
|
44
|
+
*
|
|
45
|
+
* @param accountIndex - The account index to verify
|
|
46
|
+
* @param storedAddress - The address from storage/database
|
|
47
|
+
* @returns Verification result with validity flag and details
|
|
48
|
+
*
|
|
49
|
+
* @example
|
|
50
|
+
* const result = manager.verifySavingsAddress(1, storedAddress);
|
|
51
|
+
* if (!result.isValid) {
|
|
52
|
+
* console.error("Address mismatch! Possible tampering:", result.error);
|
|
53
|
+
* }
|
|
54
|
+
*/
|
|
55
|
+
verifySavingsAddress(accountIndex: number, storedAddress: Hex): AddressVerificationResult;
|
|
56
|
+
/**
|
|
57
|
+
* Audit multiple savings addresses at once
|
|
58
|
+
*
|
|
59
|
+
* Useful for batch verification of all stored savings addresses.
|
|
60
|
+
*
|
|
61
|
+
* @param addresses - Map of accountIndex to stored address
|
|
62
|
+
* @returns Audit result with summary and per-address details
|
|
63
|
+
*
|
|
64
|
+
* @example
|
|
65
|
+
* const addresses = new Map([
|
|
66
|
+
* [1, "0xabc..."],
|
|
67
|
+
* [2, "0xdef..."]
|
|
68
|
+
* ]);
|
|
69
|
+
* const audit = manager.auditSavingsAddresses(addresses);
|
|
70
|
+
* console.log(`Valid: ${audit.valid}/${audit.total}`);
|
|
71
|
+
*/
|
|
72
|
+
auditSavingsAddresses(addresses: Map<number, Hex>): SavingsAuditResult;
|
|
73
|
+
/**
|
|
74
|
+
* Build transaction parameters for depositing to savings
|
|
75
|
+
*
|
|
76
|
+
* Security: Always derives the destination address from accountIndex.
|
|
77
|
+
* Optional expectedAddress parameter allows tamper detection.
|
|
78
|
+
*
|
|
79
|
+
* @param accountIndex - Savings account to deposit to
|
|
80
|
+
* @param amount - Amount to transfer (in base units)
|
|
81
|
+
* @param options - Optional security and priority settings
|
|
82
|
+
* @returns Transaction parameters (to, value, data)
|
|
83
|
+
*
|
|
84
|
+
* @example
|
|
85
|
+
* const txParams = manager.buildDepositTransaction(1, parseEther("1.0"), {
|
|
86
|
+
* expectedAddress: storedAddress // Verify it matches derived
|
|
87
|
+
* });
|
|
88
|
+
*/
|
|
89
|
+
buildDepositTransaction(accountIndex: number, amount: bigint, options?: TransferToSavingsOptions): {
|
|
90
|
+
to: Hex;
|
|
91
|
+
value: bigint;
|
|
92
|
+
data?: Hex;
|
|
93
|
+
};
|
|
94
|
+
/**
|
|
95
|
+
* Build transaction parameters for withdrawing from savings
|
|
96
|
+
*
|
|
97
|
+
* Security: Uses the derived private key for signing.
|
|
98
|
+
* Optional expectedAddress parameter verifies the source address.
|
|
99
|
+
*
|
|
100
|
+
* @param accountIndex - Savings account to withdraw from
|
|
101
|
+
* @param to - Destination address
|
|
102
|
+
* @param amount - Amount to transfer (in base units)
|
|
103
|
+
* @param options - Optional security and priority settings
|
|
104
|
+
* @returns Transaction parameters and private key for signing
|
|
105
|
+
*
|
|
106
|
+
* @example
|
|
107
|
+
* const { privateKey, tx } = manager.buildWithdrawalTransaction(
|
|
108
|
+
* 1, destinationAddress, parseEther("0.5")
|
|
109
|
+
* );
|
|
110
|
+
* // Use privateKey to sign the transaction
|
|
111
|
+
*/
|
|
112
|
+
buildWithdrawalTransaction(accountIndex: number, to: Hex, amount: bigint, options?: WithdrawFromSavingsOptions): {
|
|
113
|
+
privateKey: Hex;
|
|
114
|
+
from: Hex;
|
|
115
|
+
to: Hex;
|
|
116
|
+
value: bigint;
|
|
117
|
+
data?: Hex;
|
|
118
|
+
};
|
|
119
|
+
/**
|
|
120
|
+
* Get savings account details without exposing private key
|
|
121
|
+
*
|
|
122
|
+
* @param accountIndex - The account index
|
|
123
|
+
* @returns Public account information (address and derivation path only)
|
|
124
|
+
*/
|
|
125
|
+
getSavingsAccountInfo(accountIndex: number): Omit<SavingsAccount, 'privateKey'>;
|
|
126
|
+
}
|
|
@@ -0,0 +1,234 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Savings Manager
|
|
4
|
+
*
|
|
5
|
+
* Core logic for managing BIP-44 derived savings accounts.
|
|
6
|
+
* Provides security-first operations that always derive addresses from account indices.
|
|
7
|
+
*
|
|
8
|
+
* Security Model:
|
|
9
|
+
* - NEVER trust stored addresses without verification
|
|
10
|
+
* - ALWAYS derive addresses from accountIndex for transactions
|
|
11
|
+
* - Provide verification and audit tools for tamper detection
|
|
12
|
+
*/
|
|
13
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
14
|
+
exports.SavingsManager = void 0;
|
|
15
|
+
const evm_1 = require("../evm/evm");
|
|
16
|
+
const svm_1 = require("../svm/svm");
|
|
17
|
+
// ============================================
|
|
18
|
+
// SavingsManager Class
|
|
19
|
+
// ============================================
|
|
20
|
+
/**
|
|
21
|
+
* Manages BIP-44 derived savings accounts
|
|
22
|
+
*
|
|
23
|
+
* This class provides:
|
|
24
|
+
* 1. Account derivation from BIP-44 account indices
|
|
25
|
+
* 2. Address verification to prevent database tampering
|
|
26
|
+
* 3. Transaction builders for deposits and withdrawals
|
|
27
|
+
* 4. Batch auditing of stored addresses
|
|
28
|
+
*/
|
|
29
|
+
class SavingsManager {
|
|
30
|
+
vm;
|
|
31
|
+
constructor(vm) {
|
|
32
|
+
this.vm = vm;
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* Create a new savings account by deriving from account index
|
|
36
|
+
*
|
|
37
|
+
* @param accountIndex - BIP-44 account index (1+ for savings, 0 is main wallet)
|
|
38
|
+
* @returns SavingsAccount with derived private key and address
|
|
39
|
+
*
|
|
40
|
+
* @example
|
|
41
|
+
* const savingsAccount = manager.createSavingsAccount(1); // First savings account
|
|
42
|
+
* console.log(savingsAccount.address); // Derived address
|
|
43
|
+
* console.log(savingsAccount.derivationPath); // m/44'/60'/1'/0/0
|
|
44
|
+
*/
|
|
45
|
+
createSavingsAccount(accountIndex) {
|
|
46
|
+
if (accountIndex < 0) {
|
|
47
|
+
throw new Error("Account index must be non-negative");
|
|
48
|
+
}
|
|
49
|
+
const derived = this.vm.deriveSavingsAccount(accountIndex);
|
|
50
|
+
// For EVM, the address is a string (Hex)
|
|
51
|
+
// For SVM, the address is a PublicKey
|
|
52
|
+
let addressHex;
|
|
53
|
+
let privateKeyHex;
|
|
54
|
+
if (this.vm instanceof evm_1.EVMVM) {
|
|
55
|
+
addressHex = derived.address;
|
|
56
|
+
privateKeyHex = derived.privateKey.startsWith('0x')
|
|
57
|
+
? derived.privateKey
|
|
58
|
+
: `0x${derived.privateKey}`;
|
|
59
|
+
}
|
|
60
|
+
else if (this.vm instanceof svm_1.SVMVM) {
|
|
61
|
+
// For SVM, convert PublicKey to base58 string
|
|
62
|
+
addressHex = derived.address.toBase58();
|
|
63
|
+
// For SVM, convert Keypair secret key to hex
|
|
64
|
+
const keypair = derived.privateKey;
|
|
65
|
+
privateKeyHex = `0x${Buffer.from(keypair.secretKey).toString('hex')}`;
|
|
66
|
+
}
|
|
67
|
+
else {
|
|
68
|
+
throw new Error("Unsupported VM type");
|
|
69
|
+
}
|
|
70
|
+
return {
|
|
71
|
+
accountIndex,
|
|
72
|
+
privateKey: privateKeyHex,
|
|
73
|
+
address: addressHex,
|
|
74
|
+
derivationPath: derived.derivationPath
|
|
75
|
+
};
|
|
76
|
+
}
|
|
77
|
+
/**
|
|
78
|
+
* Verify a stored address matches the derived address for an account index
|
|
79
|
+
*
|
|
80
|
+
* Security: This prevents database tampering attacks where an attacker
|
|
81
|
+
* modifies stored addresses to redirect funds.
|
|
82
|
+
*
|
|
83
|
+
* @param accountIndex - The account index to verify
|
|
84
|
+
* @param storedAddress - The address from storage/database
|
|
85
|
+
* @returns Verification result with validity flag and details
|
|
86
|
+
*
|
|
87
|
+
* @example
|
|
88
|
+
* const result = manager.verifySavingsAddress(1, storedAddress);
|
|
89
|
+
* if (!result.isValid) {
|
|
90
|
+
* console.error("Address mismatch! Possible tampering:", result.error);
|
|
91
|
+
* }
|
|
92
|
+
*/
|
|
93
|
+
verifySavingsAddress(accountIndex, storedAddress) {
|
|
94
|
+
try {
|
|
95
|
+
const derived = this.createSavingsAccount(accountIndex);
|
|
96
|
+
const isValid = derived.address.toLowerCase() === storedAddress.toLowerCase();
|
|
97
|
+
return {
|
|
98
|
+
accountIndex,
|
|
99
|
+
storedAddress,
|
|
100
|
+
derivedAddress: derived.address,
|
|
101
|
+
isValid,
|
|
102
|
+
error: isValid ? undefined : "Address mismatch - stored address does not match derived address"
|
|
103
|
+
};
|
|
104
|
+
}
|
|
105
|
+
catch (error) {
|
|
106
|
+
return {
|
|
107
|
+
accountIndex,
|
|
108
|
+
storedAddress,
|
|
109
|
+
derivedAddress: "0x0",
|
|
110
|
+
isValid: false,
|
|
111
|
+
error: `Verification failed: ${error.message}`
|
|
112
|
+
};
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
/**
|
|
116
|
+
* Audit multiple savings addresses at once
|
|
117
|
+
*
|
|
118
|
+
* Useful for batch verification of all stored savings addresses.
|
|
119
|
+
*
|
|
120
|
+
* @param addresses - Map of accountIndex to stored address
|
|
121
|
+
* @returns Audit result with summary and per-address details
|
|
122
|
+
*
|
|
123
|
+
* @example
|
|
124
|
+
* const addresses = new Map([
|
|
125
|
+
* [1, "0xabc..."],
|
|
126
|
+
* [2, "0xdef..."]
|
|
127
|
+
* ]);
|
|
128
|
+
* const audit = manager.auditSavingsAddresses(addresses);
|
|
129
|
+
* console.log(`Valid: ${audit.valid}/${audit.total}`);
|
|
130
|
+
*/
|
|
131
|
+
auditSavingsAddresses(addresses) {
|
|
132
|
+
const results = [];
|
|
133
|
+
for (const [accountIndex, storedAddress] of addresses.entries()) {
|
|
134
|
+
const result = this.verifySavingsAddress(accountIndex, storedAddress);
|
|
135
|
+
results.push(result);
|
|
136
|
+
}
|
|
137
|
+
const valid = results.filter(r => r.isValid).length;
|
|
138
|
+
const invalid = results.filter(r => !r.isValid).length;
|
|
139
|
+
return {
|
|
140
|
+
total: results.length,
|
|
141
|
+
valid,
|
|
142
|
+
invalid,
|
|
143
|
+
allValid: invalid === 0,
|
|
144
|
+
results,
|
|
145
|
+
timestamp: new Date()
|
|
146
|
+
};
|
|
147
|
+
}
|
|
148
|
+
/**
|
|
149
|
+
* Build transaction parameters for depositing to savings
|
|
150
|
+
*
|
|
151
|
+
* Security: Always derives the destination address from accountIndex.
|
|
152
|
+
* Optional expectedAddress parameter allows tamper detection.
|
|
153
|
+
*
|
|
154
|
+
* @param accountIndex - Savings account to deposit to
|
|
155
|
+
* @param amount - Amount to transfer (in base units)
|
|
156
|
+
* @param options - Optional security and priority settings
|
|
157
|
+
* @returns Transaction parameters (to, value, data)
|
|
158
|
+
*
|
|
159
|
+
* @example
|
|
160
|
+
* const txParams = manager.buildDepositTransaction(1, parseEther("1.0"), {
|
|
161
|
+
* expectedAddress: storedAddress // Verify it matches derived
|
|
162
|
+
* });
|
|
163
|
+
*/
|
|
164
|
+
buildDepositTransaction(accountIndex, amount, options) {
|
|
165
|
+
const savingsAccount = this.createSavingsAccount(accountIndex);
|
|
166
|
+
// Security check: if expectedAddress provided, verify it matches
|
|
167
|
+
if (options?.expectedAddress) {
|
|
168
|
+
const verification = this.verifySavingsAddress(accountIndex, options.expectedAddress);
|
|
169
|
+
if (!verification.isValid) {
|
|
170
|
+
throw new Error(`Security check failed: Expected address ${options.expectedAddress} ` +
|
|
171
|
+
`does not match derived address ${savingsAccount.address}. ` +
|
|
172
|
+
`Possible database tampering detected.`);
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
return {
|
|
176
|
+
to: savingsAccount.address,
|
|
177
|
+
value: amount,
|
|
178
|
+
data: undefined // Simple native transfer
|
|
179
|
+
};
|
|
180
|
+
}
|
|
181
|
+
/**
|
|
182
|
+
* Build transaction parameters for withdrawing from savings
|
|
183
|
+
*
|
|
184
|
+
* Security: Uses the derived private key for signing.
|
|
185
|
+
* Optional expectedAddress parameter verifies the source address.
|
|
186
|
+
*
|
|
187
|
+
* @param accountIndex - Savings account to withdraw from
|
|
188
|
+
* @param to - Destination address
|
|
189
|
+
* @param amount - Amount to transfer (in base units)
|
|
190
|
+
* @param options - Optional security and priority settings
|
|
191
|
+
* @returns Transaction parameters and private key for signing
|
|
192
|
+
*
|
|
193
|
+
* @example
|
|
194
|
+
* const { privateKey, tx } = manager.buildWithdrawalTransaction(
|
|
195
|
+
* 1, destinationAddress, parseEther("0.5")
|
|
196
|
+
* );
|
|
197
|
+
* // Use privateKey to sign the transaction
|
|
198
|
+
*/
|
|
199
|
+
buildWithdrawalTransaction(accountIndex, to, amount, options) {
|
|
200
|
+
const savingsAccount = this.createSavingsAccount(accountIndex);
|
|
201
|
+
// Security check: if expectedAddress provided, verify it matches
|
|
202
|
+
if (options?.expectedAddress) {
|
|
203
|
+
const verification = this.verifySavingsAddress(accountIndex, options.expectedAddress);
|
|
204
|
+
if (!verification.isValid) {
|
|
205
|
+
throw new Error(`Security check failed: Expected address ${options.expectedAddress} ` +
|
|
206
|
+
`does not match derived address ${savingsAccount.address}. ` +
|
|
207
|
+
`Possible database tampering detected.`);
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
return {
|
|
211
|
+
privateKey: savingsAccount.privateKey,
|
|
212
|
+
from: savingsAccount.address,
|
|
213
|
+
to,
|
|
214
|
+
value: amount,
|
|
215
|
+
data: undefined // Simple native transfer
|
|
216
|
+
};
|
|
217
|
+
}
|
|
218
|
+
/**
|
|
219
|
+
* Get savings account details without exposing private key
|
|
220
|
+
*
|
|
221
|
+
* @param accountIndex - The account index
|
|
222
|
+
* @returns Public account information (address and derivation path only)
|
|
223
|
+
*/
|
|
224
|
+
getSavingsAccountInfo(accountIndex) {
|
|
225
|
+
const account = this.createSavingsAccount(accountIndex);
|
|
226
|
+
return {
|
|
227
|
+
accountIndex: account.accountIndex,
|
|
228
|
+
address: account.address,
|
|
229
|
+
derivationPath: account.derivationPath
|
|
230
|
+
};
|
|
231
|
+
}
|
|
232
|
+
}
|
|
233
|
+
exports.SavingsManager = SavingsManager;
|
|
234
|
+
//# sourceMappingURL=savings-manager.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"savings-manager.js","sourceRoot":"","sources":["../../utils/savings/savings-manager.ts"],"names":[],"mappings":"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"}
|