@kohaku-eth/tornado-cash 0.0.2-alpha.19 → 0.0.2-alpha.21
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.ts +37 -2
- package/dist/index.js +43 -5
- package/dist/state-manager.worker.js +203 -55
- package/dist/state-manager.worker.node.js +203 -55
- package/dist/worker-loader.browser.d.ts +53 -1
- package/dist/worker-loader.node.d.ts +53 -1
- package/package.json +8 -5
|
@@ -16856,10 +16856,16 @@ async function SecretManager({
|
|
|
16856
16856
|
const deriveDelegatorSigner = async ({ path }) => {
|
|
16857
16857
|
return Promise.resolve(keystore.deriveAt(path));
|
|
16858
16858
|
};
|
|
16859
|
+
const LEGACY_EPHEMERAL_SALT = asciiToBytes("KOHAKU7702");
|
|
16860
|
+
const deriveLegacyEphemeralSigner = async ({ nullifier }) => {
|
|
16861
|
+
const hash2 = keccak_256(concatBytes2(numberToBytesLE(nullifier, 31), LEGACY_EPHEMERAL_SALT));
|
|
16862
|
+
return `0x${bytesToHex2(hash2)}`;
|
|
16863
|
+
};
|
|
16859
16864
|
return {
|
|
16860
16865
|
getDepositSecrets: (params) => deriveSecrets(params),
|
|
16861
16866
|
deriveEphemeralSigner,
|
|
16862
|
-
deriveDelegatorSigner
|
|
16867
|
+
deriveDelegatorSigner,
|
|
16868
|
+
deriveLegacyEphemeralSigner
|
|
16863
16869
|
};
|
|
16864
16870
|
}
|
|
16865
16871
|
function tcPath({ accountIndex, secretType, depositIndex }) {
|
|
@@ -17898,10 +17904,10 @@ function getUnexpectedStateShapeWarningMessage(inputState, reducers2, action, un
|
|
|
17898
17904
|
function assertReducerShape(reducers2) {
|
|
17899
17905
|
Object.keys(reducers2).forEach((key) => {
|
|
17900
17906
|
const reducer = reducers2[key];
|
|
17901
|
-
const
|
|
17907
|
+
const initialState10 = reducer(void 0, {
|
|
17902
17908
|
type: actionTypes_default.INIT
|
|
17903
17909
|
});
|
|
17904
|
-
if (typeof
|
|
17910
|
+
if (typeof initialState10 === "undefined") {
|
|
17905
17911
|
throw new Error(process.env.NODE_ENV === "production" ? formatProdErrorMessage(12) : `The slice reducer for key "${key}" returned undefined during initialization. If the state passed to the reducer is undefined, you must explicitly return the initial state. The initial state may not be undefined. If you don't want to set a value for this reducer, you can use null instead of undefined.`);
|
|
17906
17912
|
}
|
|
17907
17913
|
if (typeof reducer(void 0, {
|
|
@@ -19142,7 +19148,7 @@ function createThunkMiddleware(extraArgument) {
|
|
|
19142
19148
|
var thunk = createThunkMiddleware();
|
|
19143
19149
|
var withExtraArgument = createThunkMiddleware;
|
|
19144
19150
|
|
|
19145
|
-
// ../../node_modules/.pnpm/@reduxjs+toolkit@2.12.0_react@19.2.
|
|
19151
|
+
// ../../node_modules/.pnpm/@reduxjs+toolkit@2.12.0_react@19.2.8/node_modules/@reduxjs/toolkit/dist/redux-toolkit.modern.mjs
|
|
19146
19152
|
var composeWithDevTools = typeof window !== "undefined" && window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__ ? window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__ : function() {
|
|
19147
19153
|
if (arguments.length === 0) return void 0;
|
|
19148
19154
|
if (typeof arguments[0] === "object") return compose;
|
|
@@ -19763,7 +19769,7 @@ function executeReducerBuilderCallback(builderCallback) {
|
|
|
19763
19769
|
function isStateFunction(x) {
|
|
19764
19770
|
return typeof x === "function";
|
|
19765
19771
|
}
|
|
19766
|
-
function createReducer(
|
|
19772
|
+
function createReducer(initialState10, mapOrBuilderCallback) {
|
|
19767
19773
|
if (process.env.NODE_ENV !== "production") {
|
|
19768
19774
|
if (typeof mapOrBuilderCallback === "object") {
|
|
19769
19775
|
throw new Error(process.env.NODE_ENV === "production" ? formatProdErrorMessage2(8) : "The object notation for `createReducer` has been removed. Please use the 'builder callback' notation instead: https://redux-toolkit.js.org/api/createReducer");
|
|
@@ -19771,10 +19777,10 @@ function createReducer(initialState9, mapOrBuilderCallback) {
|
|
|
19771
19777
|
}
|
|
19772
19778
|
let [actionsMap, finalActionMatchers, finalDefaultCaseReducer] = executeReducerBuilderCallback(mapOrBuilderCallback);
|
|
19773
19779
|
let getInitialState;
|
|
19774
|
-
if (isStateFunction(
|
|
19775
|
-
getInitialState = () => freezeDraftable(
|
|
19780
|
+
if (isStateFunction(initialState10)) {
|
|
19781
|
+
getInitialState = () => freezeDraftable(initialState10());
|
|
19776
19782
|
} else {
|
|
19777
|
-
const frozenInitialState = freezeDraftable(
|
|
19783
|
+
const frozenInitialState = freezeDraftable(initialState10);
|
|
19778
19784
|
getInitialState = () => frozenInitialState;
|
|
19779
19785
|
}
|
|
19780
19786
|
function reducer(state = getInitialState(), action) {
|
|
@@ -20429,10 +20435,29 @@ var relayersSelector = createSelector(
|
|
|
20429
20435
|
)
|
|
20430
20436
|
);
|
|
20431
20437
|
var relayerFeeConfigSelector = (state) => state.relayers.feeConfig;
|
|
20432
|
-
var
|
|
20438
|
+
var derivedUserSecretsSelector = selectEntityMap(
|
|
20433
20439
|
(s) => s.userSecrets.byPool,
|
|
20434
20440
|
deserialize
|
|
20435
20441
|
);
|
|
20442
|
+
var legacyUserSecretsSelector = selectEntityMap(
|
|
20443
|
+
(s) => s.legacySecrets.byPool,
|
|
20444
|
+
deserialize
|
|
20445
|
+
);
|
|
20446
|
+
var userSecretsSelector = createSelector(
|
|
20447
|
+
[derivedUserSecretsSelector, legacyUserSecretsSelector],
|
|
20448
|
+
(derived, legacy) => {
|
|
20449
|
+
const result = /* @__PURE__ */ new Map();
|
|
20450
|
+
for (const [poolAddress, records] of legacy) {
|
|
20451
|
+
const existing = result.get(poolAddress) ?? [];
|
|
20452
|
+
result.set(poolAddress, [...existing, ...records.map((record) => ({ kind: "legacy", ...record }))]);
|
|
20453
|
+
}
|
|
20454
|
+
for (const [poolAddress, records] of derived) {
|
|
20455
|
+
const existing = result.get(poolAddress) ?? [];
|
|
20456
|
+
result.set(poolAddress, [...existing, ...records.map((record) => ({ kind: "derived", ...record }))]);
|
|
20457
|
+
}
|
|
20458
|
+
return result;
|
|
20459
|
+
}
|
|
20460
|
+
);
|
|
20436
20461
|
|
|
20437
20462
|
// src/state/selectors/deposits.selector.ts
|
|
20438
20463
|
var myDepositsSelector = createSelector(
|
|
@@ -20446,7 +20471,7 @@ var myDepositsSelector = createSelector(
|
|
|
20446
20471
|
const commitment = BigInt(r.commitment);
|
|
20447
20472
|
const deposit = poolDeposits.get(commitment);
|
|
20448
20473
|
if (deposit) {
|
|
20449
|
-
result.set(commitment, { ...deposit, index: r.depositIndex });
|
|
20474
|
+
result.set(commitment, { ...deposit, index: r.kind === "derived" ? r.depositIndex : -1 });
|
|
20450
20475
|
}
|
|
20451
20476
|
}
|
|
20452
20477
|
}
|
|
@@ -20827,6 +20852,28 @@ var userSecretsSlice = createSlice({
|
|
|
20827
20852
|
var { addUserSecret } = userSecretsSlice.actions;
|
|
20828
20853
|
var userSecretsReducer = userSecretsSlice.reducer;
|
|
20829
20854
|
|
|
20855
|
+
// src/state/slices/legacySecretsSlice.ts
|
|
20856
|
+
var initialState9 = {
|
|
20857
|
+
byPool: []
|
|
20858
|
+
};
|
|
20859
|
+
var legacySecretsSlice = createSlice({
|
|
20860
|
+
name: "legacySecrets",
|
|
20861
|
+
initialState: initialState9,
|
|
20862
|
+
reducers: {
|
|
20863
|
+
addLegacyUserSecret: ({ byPool }, { payload: { poolAddress, record } }) => {
|
|
20864
|
+
const map = new Map(deserialize(byPool));
|
|
20865
|
+
const records = map.get(poolAddress) || [];
|
|
20866
|
+
if (!records.some((r) => r.commitment === record.commitment)) {
|
|
20867
|
+
records.push(record);
|
|
20868
|
+
}
|
|
20869
|
+
map.set(poolAddress, records);
|
|
20870
|
+
return serialize({ byPool: [...map] });
|
|
20871
|
+
}
|
|
20872
|
+
}
|
|
20873
|
+
});
|
|
20874
|
+
var { addLegacyUserSecret } = legacySecretsSlice.actions;
|
|
20875
|
+
var legacySecretsReducer = legacySecretsSlice.reducer;
|
|
20876
|
+
|
|
20830
20877
|
// src/state/store.ts
|
|
20831
20878
|
var reducers = {
|
|
20832
20879
|
deposits: depositsReducer,
|
|
@@ -20836,7 +20883,8 @@ var reducers = {
|
|
|
20836
20883
|
relayers: relayersReducer,
|
|
20837
20884
|
instanceRegistryInfo: protocolConfigReducer,
|
|
20838
20885
|
sync: syncReducer,
|
|
20839
|
-
userSecrets: userSecretsReducer
|
|
20886
|
+
userSecrets: userSecretsReducer,
|
|
20887
|
+
legacySecrets: legacySecretsReducer
|
|
20840
20888
|
};
|
|
20841
20889
|
var loggerFactory = (logLevel) => (api) => (next) => (action) => {
|
|
20842
20890
|
const result = next(action);
|
|
@@ -20866,11 +20914,11 @@ var loggerFactory = (logLevel) => (api) => (next) => (action) => {
|
|
|
20866
20914
|
};
|
|
20867
20915
|
var storeFactory = ({
|
|
20868
20916
|
protocolConfig,
|
|
20869
|
-
initialState:
|
|
20917
|
+
initialState: initialState10,
|
|
20870
20918
|
logLevel = "error"
|
|
20871
20919
|
}) => {
|
|
20872
20920
|
const store = configureStore({
|
|
20873
|
-
preloadedState:
|
|
20921
|
+
preloadedState: initialState10,
|
|
20874
20922
|
reducer: reducers,
|
|
20875
20923
|
middleware: (getDefaultMiddleware) => {
|
|
20876
20924
|
const defaultMiddleware = getDefaultMiddleware({
|
|
@@ -21229,7 +21277,7 @@ var discoverUserEventsThunk = createAsyncThunk(
|
|
|
21229
21277
|
const deposits = depositsSelector(state);
|
|
21230
21278
|
const pools = poolsSelector(state);
|
|
21231
21279
|
const { chainId } = instanceRegistryInfoSelector(state);
|
|
21232
|
-
const userSecrets =
|
|
21280
|
+
const userSecrets = derivedUserSecretsSelector(state);
|
|
21233
21281
|
for (const [poolAddress] of pools) {
|
|
21234
21282
|
const startIndex = userSecrets.get(poolAddress)?.length ?? 0;
|
|
21235
21283
|
const poolDeposits = deposits.get(poolAddress);
|
|
@@ -21433,7 +21481,7 @@ var createTx = (address, payload, value = BigInt(0)) => {
|
|
|
21433
21481
|
init_exports();
|
|
21434
21482
|
init_encodeAbiParameters2();
|
|
21435
21483
|
|
|
21436
|
-
// ../../node_modules/.pnpm/@privacy-paymasters+sdk@0.0.
|
|
21484
|
+
// ../../node_modules/.pnpm/@privacy-paymasters+sdk@0.0.5_typescript@5.9.3_zod@4.4.3/node_modules/@privacy-paymasters/sdk/dist/index.js
|
|
21437
21485
|
function encodePaymasterData(adapter, adapterData) {
|
|
21438
21486
|
return encodeAbiParameters2(parseAbiParameters("(address adapter, bytes adapterData)"), [{ adapter, adapterData }]);
|
|
21439
21487
|
}
|
|
@@ -21615,7 +21663,7 @@ var baseGasUnits = {
|
|
|
21615
21663
|
preVerificationGas: 100000n,
|
|
21616
21664
|
verificationGasLimit: 50000n,
|
|
21617
21665
|
callGasLimit: 300000n,
|
|
21618
|
-
paymasterVerificationGasLimit:
|
|
21666
|
+
paymasterVerificationGasLimit: 450000n,
|
|
21619
21667
|
paymasterPostOpGasLimit: 50000n
|
|
21620
21668
|
};
|
|
21621
21669
|
function reasonableGasUnits(isERC20) {
|
|
@@ -23481,6 +23529,22 @@ var paymasterWithdrawThunk = createAsyncThunk("withdraw/executePaymasterWithdraw
|
|
|
23481
23529
|
);
|
|
23482
23530
|
const bundlerClient = createPaymasterBundlerClient(bundlerUrl);
|
|
23483
23531
|
const { standard: { maxFeePerGas, maxPriorityFeePerGas } } = await getUserOperationGasPrice(bundlerClient);
|
|
23532
|
+
const refineGasWithBundler = async (baselineGas2, provisionalUserOperation) => {
|
|
23533
|
+
try {
|
|
23534
|
+
const estimated = await estimateUserOperationGas2(bundlerClient, provisionalUserOperation, entryPointAddress);
|
|
23535
|
+
const buffer2 = (x) => x * 12n / 10n;
|
|
23536
|
+
const orBaseline = (e, b) => e > 0n ? buffer2(e) : b;
|
|
23537
|
+
return {
|
|
23538
|
+
callGasLimit: orBaseline(estimated.callGasLimit, baselineGas2.callGasLimit),
|
|
23539
|
+
verificationGasLimit: orBaseline(estimated.verificationGasLimit, baselineGas2.verificationGasLimit),
|
|
23540
|
+
preVerificationGas: orBaseline(estimated.preVerificationGas, baselineGas2.preVerificationGas),
|
|
23541
|
+
paymasterVerificationGasLimit: orBaseline(estimated.paymasterVerificationGasLimit, baselineGas2.paymasterVerificationGasLimit),
|
|
23542
|
+
paymasterPostOpGasLimit: orBaseline(estimated.paymasterPostOpGasLimit, baselineGas2.paymasterPostOpGasLimit)
|
|
23543
|
+
};
|
|
23544
|
+
} catch {
|
|
23545
|
+
return baselineGas2;
|
|
23546
|
+
}
|
|
23547
|
+
};
|
|
23484
23548
|
const relayerAddress = BigInt(paymasterAddress);
|
|
23485
23549
|
const bigintChainId = await dataService.getChainId();
|
|
23486
23550
|
const { recipient: originalRecipient, ...restWithoutRecipient } = rest;
|
|
@@ -23507,11 +23571,13 @@ var paymasterWithdrawThunk = createAsyncThunk("withdraw/executePaymasterWithdraw
|
|
|
23507
23571
|
)
|
|
23508
23572
|
);
|
|
23509
23573
|
};
|
|
23510
|
-
const ephemeralSigner = async (deposit) => privateKeyToAccount(
|
|
23511
|
-
|
|
23512
|
-
|
|
23513
|
-
|
|
23514
|
-
|
|
23574
|
+
const ephemeralSigner = async (deposit) => privateKeyToAccount(
|
|
23575
|
+
deposit.kind === "legacy" ? await secretManager.deriveLegacyEphemeralSigner({ nullifier: deposit.nullifier }) : await secretManager.deriveEphemeralSigner({
|
|
23576
|
+
depositIndex: deposit.depositIndex,
|
|
23577
|
+
chainId: bigintChainId,
|
|
23578
|
+
poolAddress: deposit.pool
|
|
23579
|
+
})
|
|
23580
|
+
);
|
|
23515
23581
|
const resolveBatchDelegator = async () => {
|
|
23516
23582
|
if (delegation?.mode === "random") return privateKeyToAccount(generatePrivateKey());
|
|
23517
23583
|
if (delegation?.mode === "deterministic" && delegation.path) {
|
|
@@ -23525,19 +23591,36 @@ var paymasterWithdrawThunk = createAsyncThunk("withdraw/executePaymasterWithdraw
|
|
|
23525
23591
|
if (!needsConsolidation) {
|
|
23526
23592
|
const deposit = deposits[0];
|
|
23527
23593
|
const signer2 = await resolveIndependentSigner(deposit);
|
|
23528
|
-
const
|
|
23529
|
-
|
|
23530
|
-
|
|
23531
|
-
|
|
23594
|
+
const baselineGas2 = { ...reasonableGasUnits(poolInfo.isERC20), callGasLimit: 0n };
|
|
23595
|
+
let fee2 = await quoteFee(computeMinimumViableFee(baselineGas2, maxFeePerGas));
|
|
23596
|
+
let gas2 = baselineGas2;
|
|
23597
|
+
let proof = await prove(deposit, originalRecipient, relayerAddress, fee2);
|
|
23598
|
+
let userOperation2 = await buildSignedTornadoUserOp({
|
|
23532
23599
|
signer: signer2,
|
|
23533
23600
|
chainId,
|
|
23534
23601
|
paymasterAddress,
|
|
23535
23602
|
paymasterData: buildPaymasterData(deposit.pool, proof),
|
|
23536
|
-
gas:
|
|
23603
|
+
gas: gas2,
|
|
23537
23604
|
maxFeePerGas,
|
|
23538
23605
|
maxPriorityFeePerGas,
|
|
23539
23606
|
nonce: 0n
|
|
23540
23607
|
});
|
|
23608
|
+
const estimatedGas = await refineGasWithBundler(baselineGas2, userOperation2);
|
|
23609
|
+
if (estimatedGas !== baselineGas2) {
|
|
23610
|
+
gas2 = { ...estimatedGas, callGasLimit: 0n };
|
|
23611
|
+
fee2 = await quoteFee(computeMinimumViableFee(gas2, maxFeePerGas));
|
|
23612
|
+
proof = await prove(deposit, originalRecipient, relayerAddress, fee2);
|
|
23613
|
+
userOperation2 = await buildSignedTornadoUserOp({
|
|
23614
|
+
signer: signer2,
|
|
23615
|
+
chainId,
|
|
23616
|
+
paymasterAddress,
|
|
23617
|
+
paymasterData: buildPaymasterData(deposit.pool, proof),
|
|
23618
|
+
gas: gas2,
|
|
23619
|
+
maxFeePerGas,
|
|
23620
|
+
maxPriorityFeePerGas,
|
|
23621
|
+
nonce: 0n
|
|
23622
|
+
});
|
|
23623
|
+
}
|
|
23541
23624
|
return [{
|
|
23542
23625
|
mode: "paymaster",
|
|
23543
23626
|
proof,
|
|
@@ -23606,22 +23689,12 @@ var paymasterWithdrawThunk = createAsyncThunk("withdraw/executePaymasterWithdraw
|
|
|
23606
23689
|
let gas = baselineGas;
|
|
23607
23690
|
let sponsoringProof = await prove(sponsoringDeposit, senderAddress, relayerAddress, fee);
|
|
23608
23691
|
let userOperation = await buildOp(gas, fee, buildPaymasterData(sponsoringDeposit.pool, sponsoringProof));
|
|
23609
|
-
|
|
23610
|
-
|
|
23611
|
-
const buffer2 = (x) => x * 12n / 10n;
|
|
23612
|
-
const orBaseline = (e, b) => e > 0n ? buffer2(e) : b;
|
|
23613
|
-
const refinedGas = {
|
|
23614
|
-
callGasLimit: orBaseline(estimated.callGasLimit, baselineGas.callGasLimit),
|
|
23615
|
-
verificationGasLimit: orBaseline(estimated.verificationGasLimit, baselineGas.verificationGasLimit),
|
|
23616
|
-
preVerificationGas: orBaseline(estimated.preVerificationGas, baselineGas.preVerificationGas),
|
|
23617
|
-
paymasterVerificationGasLimit: orBaseline(estimated.paymasterVerificationGasLimit, baselineGas.paymasterVerificationGasLimit),
|
|
23618
|
-
paymasterPostOpGasLimit: orBaseline(estimated.paymasterPostOpGasLimit, baselineGas.paymasterPostOpGasLimit)
|
|
23619
|
-
};
|
|
23620
|
-
fee = await quoteFee(computeMinimumViableFee(refinedGas, maxFeePerGas));
|
|
23692
|
+
const refinedGas = await refineGasWithBundler(baselineGas, userOperation);
|
|
23693
|
+
if (refinedGas !== baselineGas) {
|
|
23621
23694
|
gas = refinedGas;
|
|
23695
|
+
fee = await quoteFee(computeMinimumViableFee(gas, maxFeePerGas));
|
|
23622
23696
|
sponsoringProof = await prove(sponsoringDeposit, senderAddress, relayerAddress, fee);
|
|
23623
23697
|
userOperation = await buildOp(gas, fee, buildPaymasterData(sponsoringDeposit.pool, sponsoringProof));
|
|
23624
|
-
} catch {
|
|
23625
23698
|
}
|
|
23626
23699
|
return [{
|
|
23627
23700
|
mode: "paymaster",
|
|
@@ -23703,7 +23776,7 @@ var getDepositPayloadThunk = createAsyncThunk(
|
|
|
23703
23776
|
const state = getState();
|
|
23704
23777
|
const pools = poolsSelector(state);
|
|
23705
23778
|
const { chainId } = instanceRegistryInfoSelector(state);
|
|
23706
|
-
const userSecrets =
|
|
23779
|
+
const userSecrets = derivedUserSecretsSelector(state);
|
|
23707
23780
|
const poolsCandidates = Array.from(pools.values()).filter((p) => p.asset === asset);
|
|
23708
23781
|
if (poolsCandidates.length === 0) throw new Error(`No pools available for asset ${addressToHex(asset)}`);
|
|
23709
23782
|
const poolsToDepositInto = calculatePoolsDeposits(poolsCandidates, amount, strategy);
|
|
@@ -23752,6 +23825,62 @@ var getDepositPayloadThunk = createAsyncThunk(
|
|
|
23752
23825
|
}
|
|
23753
23826
|
);
|
|
23754
23827
|
|
|
23828
|
+
// src/account/legacyNote.ts
|
|
23829
|
+
init_utils2();
|
|
23830
|
+
var NOTE_REGEX = /^tornado-([a-zA-Z0-9]+)-([0-9.]+)-(\d+)-0x([0-9a-fA-F]+)$/;
|
|
23831
|
+
function parseLegacyNote(note) {
|
|
23832
|
+
const match = NOTE_REGEX.exec(note.trim());
|
|
23833
|
+
if (!match) {
|
|
23834
|
+
throw new Error(`Invalid tornado cash note: ${note}`);
|
|
23835
|
+
}
|
|
23836
|
+
const [, currency, denomination, chainId, preimageHex] = match;
|
|
23837
|
+
const preimageBytes = hexToBytes2(preimageHex);
|
|
23838
|
+
if (preimageBytes.length !== 62) {
|
|
23839
|
+
throw new Error(`Invalid tornado cash note preimage length: ${note}`);
|
|
23840
|
+
}
|
|
23841
|
+
const nullifierBytes = preimageBytes.subarray(0, 31);
|
|
23842
|
+
const saltBytes = preimageBytes.subarray(31, 62);
|
|
23843
|
+
return {
|
|
23844
|
+
currency,
|
|
23845
|
+
denomination,
|
|
23846
|
+
chainId: BigInt(chainId),
|
|
23847
|
+
nullifier: bytesToNumberLE(nullifierBytes),
|
|
23848
|
+
salt: bytesToNumberLE(saltBytes),
|
|
23849
|
+
commitment: pedersenHash2(preimageBytes),
|
|
23850
|
+
nullifierHash: pedersenHash2(nullifierBytes)
|
|
23851
|
+
};
|
|
23852
|
+
}
|
|
23853
|
+
|
|
23854
|
+
// src/state/thunks/importLegacyNotesThunk.ts
|
|
23855
|
+
var importLegacyNotesThunk = createAsyncThunk(
|
|
23856
|
+
"userSecrets/importLegacy",
|
|
23857
|
+
async ({ notes }, { getState, dispatch }) => {
|
|
23858
|
+
const state = getState();
|
|
23859
|
+
const deposits = depositsSelector(state);
|
|
23860
|
+
const { chainId } = instanceRegistryInfoSelector(state);
|
|
23861
|
+
return notes.map((note) => {
|
|
23862
|
+
const parsed = parseLegacyNote(note);
|
|
23863
|
+
if (parsed.chainId !== chainId) {
|
|
23864
|
+
return { note, status: "wrong-chain" };
|
|
23865
|
+
}
|
|
23866
|
+
const matchedPool = [...deposits].find(([, poolDeposits]) => poolDeposits.has(parsed.commitment))?.[0];
|
|
23867
|
+
if (!matchedPool) {
|
|
23868
|
+
return { note, status: "not-found" };
|
|
23869
|
+
}
|
|
23870
|
+
dispatch(addLegacyUserSecret({
|
|
23871
|
+
poolAddress: matchedPool,
|
|
23872
|
+
record: {
|
|
23873
|
+
commitment: parsed.commitment,
|
|
23874
|
+
nullifierHash: parsed.nullifierHash,
|
|
23875
|
+
nullifier: parsed.nullifier,
|
|
23876
|
+
salt: parsed.salt
|
|
23877
|
+
}
|
|
23878
|
+
}));
|
|
23879
|
+
return { note, status: "imported", poolAddress: matchedPool };
|
|
23880
|
+
});
|
|
23881
|
+
}
|
|
23882
|
+
);
|
|
23883
|
+
|
|
23755
23884
|
// src/state/state-manager.ts
|
|
23756
23885
|
var ETH_SEPOLIA_CHAIN_ID = 11155111n;
|
|
23757
23886
|
var getStoreKey = ({
|
|
@@ -23766,6 +23895,10 @@ var initializeSelectors = (store) => ({
|
|
|
23766
23895
|
getAllNotes: () => allNotesSelector(store.getState())
|
|
23767
23896
|
},
|
|
23768
23897
|
getPublicState: () => {
|
|
23898
|
+
const { userSecrets, legacySecrets, ...publicState } = store.getState();
|
|
23899
|
+
return publicState;
|
|
23900
|
+
},
|
|
23901
|
+
getPrivateState: () => {
|
|
23769
23902
|
const { userSecrets, ...publicState } = store.getState();
|
|
23770
23903
|
return publicState;
|
|
23771
23904
|
}
|
|
@@ -23795,13 +23928,13 @@ var storeByChainAndEntrypoint = ({
|
|
|
23795
23928
|
const rawStoredState = storageToSyncTo ? await storageToSyncTo.get(storageKey) : void 0;
|
|
23796
23929
|
const storedState = rawStoredState ? JSON.parse(rawStoredState) : void 0;
|
|
23797
23930
|
const snapshotInitialState = storedState || !resolveInitialState ? void 0 : (await resolveInitialState())[storageKey];
|
|
23798
|
-
let
|
|
23799
|
-
if (!
|
|
23800
|
-
|
|
23931
|
+
let initialState10 = storedState || snapshotInitialState;
|
|
23932
|
+
if (!initialState10 && getChainStoreParams.chainId === ETH_SEPOLIA_CHAIN_ID) {
|
|
23933
|
+
initialState10 = await Promise.resolve().then(() => __toESM(require_state_11155111_minimal(), 1)).then((a) => a["tornado-cash-state-11155111-447664927873626138772898946646079239273904189887"]);
|
|
23801
23934
|
}
|
|
23802
23935
|
const store = storeFactory({
|
|
23803
23936
|
protocolConfig,
|
|
23804
|
-
initialState:
|
|
23937
|
+
initialState: initialState10
|
|
23805
23938
|
});
|
|
23806
23939
|
store.dispatch(setRelayerFeeConfig(relayerConfig));
|
|
23807
23940
|
storeWithSelectors = initializeSelectors(store);
|
|
@@ -23830,14 +23963,14 @@ var storeStateManager = async ({
|
|
|
23830
23963
|
paymasterConfig,
|
|
23831
23964
|
proverFactory,
|
|
23832
23965
|
storageToSyncTo,
|
|
23833
|
-
initialState:
|
|
23966
|
+
initialState: initialState10,
|
|
23834
23967
|
protocolConfig,
|
|
23835
23968
|
relayerConfig
|
|
23836
23969
|
}) => {
|
|
23837
23970
|
const secretManager = await secretManagerFactory();
|
|
23838
23971
|
const { getChainStore, getAllStores } = storeByChainAndEntrypoint({
|
|
23839
23972
|
storageToSyncTo,
|
|
23840
|
-
initialState:
|
|
23973
|
+
initialState: initialState10
|
|
23841
23974
|
});
|
|
23842
23975
|
const getChainInfo = async () => {
|
|
23843
23976
|
const chainId = await dataService.getChainId();
|
|
@@ -23851,6 +23984,14 @@ var storeStateManager = async ({
|
|
|
23851
23984
|
}
|
|
23852
23985
|
};
|
|
23853
23986
|
};
|
|
23987
|
+
const persistStateIfAvailable = async (chainInfo, store) => {
|
|
23988
|
+
if (storageToSyncTo) {
|
|
23989
|
+
await storageToSyncTo.set(
|
|
23990
|
+
getStoreStorageKey(chainInfo),
|
|
23991
|
+
JSON.stringify(store.getPrivateState())
|
|
23992
|
+
);
|
|
23993
|
+
}
|
|
23994
|
+
};
|
|
23854
23995
|
return {
|
|
23855
23996
|
sync: async () => {
|
|
23856
23997
|
const chainInfo = await getChainInfo();
|
|
@@ -23866,12 +24007,7 @@ var storeStateManager = async ({
|
|
|
23866
24007
|
})
|
|
23867
24008
|
)
|
|
23868
24009
|
);
|
|
23869
|
-
|
|
23870
|
-
await storageToSyncTo.set(
|
|
23871
|
-
getStoreStorageKey(chainInfo),
|
|
23872
|
-
JSON.stringify(store.getPublicState())
|
|
23873
|
-
);
|
|
23874
|
-
}
|
|
24010
|
+
await persistStateIfAvailable(chainInfo, store);
|
|
23875
24011
|
},
|
|
23876
24012
|
getBalances: async (assets) => {
|
|
23877
24013
|
const { selectors: { specificAssetsBalanceSelector: specificAssetsBalanceSelector2 } } = await getChainStore(await getChainInfo());
|
|
@@ -23937,6 +24073,15 @@ var storeStateManager = async ({
|
|
|
23937
24073
|
)
|
|
23938
24074
|
);
|
|
23939
24075
|
},
|
|
24076
|
+
importNotes: async ({ notes }) => {
|
|
24077
|
+
const chainInfo = await getChainInfo();
|
|
24078
|
+
const store = await getChainStore(chainInfo);
|
|
24079
|
+
const result = unwrapResult(
|
|
24080
|
+
await store.dispatch(importLegacyNotesThunk({ notes }))
|
|
24081
|
+
);
|
|
24082
|
+
await persistStateIfAvailable(chainInfo, store);
|
|
24083
|
+
return result;
|
|
24084
|
+
},
|
|
23940
24085
|
dumpState: () => getAllStores()
|
|
23941
24086
|
};
|
|
23942
24087
|
};
|
|
@@ -23948,12 +24093,12 @@ function getStateManager() {
|
|
|
23948
24093
|
return _stateManager;
|
|
23949
24094
|
}
|
|
23950
24095
|
var workerApi = {
|
|
23951
|
-
async init(provider, relayerClient, keystore, rawStorage,
|
|
24096
|
+
async init(provider, relayerClient, keystore, rawStorage, initialState10, artifactsLoader, secretManager, externalSyncProvider, { protocolConfig, accountIndex, relayerConfig, paymasterConfig, minExternalSyncBlocksAmount }) {
|
|
23952
24097
|
const storage = rawStorage;
|
|
23953
24098
|
const dataService = new DataService({ provider });
|
|
23954
24099
|
_stateManager = await storeStateManager({
|
|
23955
24100
|
paymasterConfig,
|
|
23956
|
-
secretManagerFactory: () => SecretManager({ host: { keystore }, accountIndex }),
|
|
24101
|
+
secretManagerFactory: () => secretManager ? Promise.resolve(secretManager) : SecretManager({ host: { keystore }, accountIndex }),
|
|
23957
24102
|
dataService,
|
|
23958
24103
|
syncService: new SyncService({ dataService, externalSyncProvider, minExternalSyncBlocksAmount }),
|
|
23959
24104
|
relayerClient,
|
|
@@ -23961,7 +24106,7 @@ var workerApi = {
|
|
|
23961
24106
|
storageToSyncTo: storage,
|
|
23962
24107
|
protocolConfig,
|
|
23963
24108
|
relayerConfig,
|
|
23964
|
-
initialState:
|
|
24109
|
+
initialState: initialState10
|
|
23965
24110
|
});
|
|
23966
24111
|
},
|
|
23967
24112
|
sync() {
|
|
@@ -23976,6 +24121,9 @@ var workerApi = {
|
|
|
23976
24121
|
getDepositPayload(params) {
|
|
23977
24122
|
return getStateManager().getDepositPayload(params);
|
|
23978
24123
|
},
|
|
24124
|
+
importNotes(params) {
|
|
24125
|
+
return getStateManager().importNotes(params);
|
|
24126
|
+
},
|
|
23979
24127
|
getWithdrawalPayloads(params, tailCalls) {
|
|
23980
24128
|
const fullParams = params.mode === "paymaster" && tailCalls ? { ...params, tailCalls } : params;
|
|
23981
24129
|
return getStateManager().getWithdrawalPayloads(fullParams);
|
|
@@ -7,6 +7,8 @@ import * as _kohaku_eth_provider from '@kohaku-eth/provider';
|
|
|
7
7
|
import { TxData } from '@kohaku-eth/provider';
|
|
8
8
|
import { Address as Address$1 } from 'ox/Address';
|
|
9
9
|
|
|
10
|
+
type Nullifier = bigint & {};
|
|
11
|
+
type NullifierHash = bigint & {};
|
|
10
12
|
type Address = bigint & {};
|
|
11
13
|
type Commitment = bigint & {};
|
|
12
14
|
interface IContract {
|
|
@@ -30,6 +32,41 @@ interface ProtocolConfigState {
|
|
|
30
32
|
type RootState = ReturnType<ReturnType<typeof combineReducers<typeof reducers>>>;
|
|
31
33
|
type PublicRootState = Omit<RootState, 'userSecrets'>;
|
|
32
34
|
|
|
35
|
+
interface Secret {
|
|
36
|
+
nullifier: Nullifier;
|
|
37
|
+
salt: bigint;
|
|
38
|
+
commitment: Commitment;
|
|
39
|
+
nullifierHash: NullifierHash;
|
|
40
|
+
}
|
|
41
|
+
type BaseDeriveSecretParams = {
|
|
42
|
+
poolAddress: bigint;
|
|
43
|
+
chainId: bigint;
|
|
44
|
+
};
|
|
45
|
+
type DeriveDepositSecretParams = BaseDeriveSecretParams & {
|
|
46
|
+
depositIndex: number;
|
|
47
|
+
};
|
|
48
|
+
interface ISecretManager {
|
|
49
|
+
getDepositSecrets: (params: DeriveDepositSecretParams) => Promise<Secret>;
|
|
50
|
+
deriveEphemeralSigner: (params: DeriveDepositSecretParams) => Promise<`0x${string}`>;
|
|
51
|
+
/**
|
|
52
|
+
* Derives a delegator key from a classical wallet BIP-32 `path`, WITHOUT the
|
|
53
|
+
* `coalesceSecret` privacy transform, so it resolves to a recoverable,
|
|
54
|
+
* classical Ethereum address. Used for the tail-call batch delegator when the
|
|
55
|
+
* integrator supplies a wallet path (see `paymasterWithdrawThunk`).
|
|
56
|
+
*/
|
|
57
|
+
deriveDelegatorSigner: (params: {
|
|
58
|
+
path: string;
|
|
59
|
+
}) => Promise<`0x${string}`>;
|
|
60
|
+
/**
|
|
61
|
+
* Derives the ephemeral signer for an imported legacy note. Legacy secrets
|
|
62
|
+
* have no keystore-derived `depositIndex`, so this is a pure function of
|
|
63
|
+
* the note's own nullifier instead of a BIP-32 derivation.
|
|
64
|
+
*/
|
|
65
|
+
deriveLegacyEphemeralSigner: (params: {
|
|
66
|
+
nullifier: Nullifier;
|
|
67
|
+
}) => Promise<`0x${string}`>;
|
|
68
|
+
}
|
|
69
|
+
|
|
33
70
|
interface IBaseEvent {
|
|
34
71
|
blockNumber: bigint;
|
|
35
72
|
transactionHash: bigint;
|
|
@@ -91,6 +128,18 @@ interface IRelayerClient {
|
|
|
91
128
|
withdraw(relayerUrl: string, body: ITornadoWithdrawRequest): Promise<ITornadoWithdrawResponse>;
|
|
92
129
|
}
|
|
93
130
|
|
|
131
|
+
type ImportNoteResult = {
|
|
132
|
+
note: string;
|
|
133
|
+
status: 'imported';
|
|
134
|
+
poolAddress: Address;
|
|
135
|
+
} | {
|
|
136
|
+
note: string;
|
|
137
|
+
status: 'wrong-chain';
|
|
138
|
+
} | {
|
|
139
|
+
note: string;
|
|
140
|
+
status: 'not-found';
|
|
141
|
+
};
|
|
142
|
+
|
|
94
143
|
interface TornadoProveOutput {
|
|
95
144
|
proof: `0x${string}`;
|
|
96
145
|
args: [
|
|
@@ -241,11 +290,14 @@ interface WorkerInitOptions {
|
|
|
241
290
|
|
|
242
291
|
declare function loadStateManagerWorker(workerUrl?: string | URL): {
|
|
243
292
|
remote: comlink.Remote<{
|
|
244
|
-
init(provider: _kohaku_eth_provider.EthereumProvider, relayerClient: IRelayerClient, keystore: _kohaku_eth_plugins.Keystore, rawStorage: Omit<_kohaku_eth_plugins.Storage, "_brand">, initialState: () => Promise<Record<string, PublicRootState>>, artifactsLoader: () => Promise<ITornadoArtifacts>, externalSyncProvider: ExternalSyncClient | undefined, { protocolConfig, accountIndex, relayerConfig, paymasterConfig, minExternalSyncBlocksAmount }: WorkerInitOptions): Promise<void>;
|
|
293
|
+
init(provider: _kohaku_eth_provider.EthereumProvider, relayerClient: IRelayerClient, keystore: _kohaku_eth_plugins.Keystore, rawStorage: Omit<_kohaku_eth_plugins.Storage, "_brand">, initialState: () => Promise<Record<string, PublicRootState>>, artifactsLoader: () => Promise<ITornadoArtifacts>, secretManager: ISecretManager | undefined, externalSyncProvider: ExternalSyncClient | undefined, { protocolConfig, accountIndex, relayerConfig, paymasterConfig, minExternalSyncBlocksAmount }: WorkerInitOptions): Promise<void>;
|
|
245
294
|
sync(): Promise<void>;
|
|
246
295
|
getBalances(assets?: Address[]): Promise<Map<Address, bigint>>;
|
|
247
296
|
getNotes(params: IGetNotesParams): Promise<TCNote[]>;
|
|
248
297
|
getDepositPayload(params: IDepositOperationParams): Promise<_kohaku_eth_provider.TxData[]>;
|
|
298
|
+
importNotes(params: {
|
|
299
|
+
notes: string[];
|
|
300
|
+
}): Promise<ImportNoteResult[]>;
|
|
249
301
|
getWithdrawalPayloads(params: IWithdrawapOperationParams, tailCalls?: IPaymasterWithdrawParams["tailCalls"]): Promise<IWithdrawalPayload[]>;
|
|
250
302
|
dumpState(): Record<StoreStorageKey, Omit<RootState, "userSecrets">>;
|
|
251
303
|
}>;
|
|
@@ -8,6 +8,8 @@ import { TxData } from '@kohaku-eth/provider';
|
|
|
8
8
|
import { Address as Address$1 } from 'ox/Address';
|
|
9
9
|
import { Worker } from 'worker_threads';
|
|
10
10
|
|
|
11
|
+
type Nullifier = bigint & {};
|
|
12
|
+
type NullifierHash = bigint & {};
|
|
11
13
|
type Address = bigint & {};
|
|
12
14
|
type Commitment = bigint & {};
|
|
13
15
|
interface IContract {
|
|
@@ -31,6 +33,41 @@ interface ProtocolConfigState {
|
|
|
31
33
|
type RootState = ReturnType<ReturnType<typeof combineReducers<typeof reducers>>>;
|
|
32
34
|
type PublicRootState = Omit<RootState, 'userSecrets'>;
|
|
33
35
|
|
|
36
|
+
interface Secret {
|
|
37
|
+
nullifier: Nullifier;
|
|
38
|
+
salt: bigint;
|
|
39
|
+
commitment: Commitment;
|
|
40
|
+
nullifierHash: NullifierHash;
|
|
41
|
+
}
|
|
42
|
+
type BaseDeriveSecretParams = {
|
|
43
|
+
poolAddress: bigint;
|
|
44
|
+
chainId: bigint;
|
|
45
|
+
};
|
|
46
|
+
type DeriveDepositSecretParams = BaseDeriveSecretParams & {
|
|
47
|
+
depositIndex: number;
|
|
48
|
+
};
|
|
49
|
+
interface ISecretManager {
|
|
50
|
+
getDepositSecrets: (params: DeriveDepositSecretParams) => Promise<Secret>;
|
|
51
|
+
deriveEphemeralSigner: (params: DeriveDepositSecretParams) => Promise<`0x${string}`>;
|
|
52
|
+
/**
|
|
53
|
+
* Derives a delegator key from a classical wallet BIP-32 `path`, WITHOUT the
|
|
54
|
+
* `coalesceSecret` privacy transform, so it resolves to a recoverable,
|
|
55
|
+
* classical Ethereum address. Used for the tail-call batch delegator when the
|
|
56
|
+
* integrator supplies a wallet path (see `paymasterWithdrawThunk`).
|
|
57
|
+
*/
|
|
58
|
+
deriveDelegatorSigner: (params: {
|
|
59
|
+
path: string;
|
|
60
|
+
}) => Promise<`0x${string}`>;
|
|
61
|
+
/**
|
|
62
|
+
* Derives the ephemeral signer for an imported legacy note. Legacy secrets
|
|
63
|
+
* have no keystore-derived `depositIndex`, so this is a pure function of
|
|
64
|
+
* the note's own nullifier instead of a BIP-32 derivation.
|
|
65
|
+
*/
|
|
66
|
+
deriveLegacyEphemeralSigner: (params: {
|
|
67
|
+
nullifier: Nullifier;
|
|
68
|
+
}) => Promise<`0x${string}`>;
|
|
69
|
+
}
|
|
70
|
+
|
|
34
71
|
interface IBaseEvent {
|
|
35
72
|
blockNumber: bigint;
|
|
36
73
|
transactionHash: bigint;
|
|
@@ -92,6 +129,18 @@ interface IRelayerClient {
|
|
|
92
129
|
withdraw(relayerUrl: string, body: ITornadoWithdrawRequest): Promise<ITornadoWithdrawResponse>;
|
|
93
130
|
}
|
|
94
131
|
|
|
132
|
+
type ImportNoteResult = {
|
|
133
|
+
note: string;
|
|
134
|
+
status: 'imported';
|
|
135
|
+
poolAddress: Address;
|
|
136
|
+
} | {
|
|
137
|
+
note: string;
|
|
138
|
+
status: 'wrong-chain';
|
|
139
|
+
} | {
|
|
140
|
+
note: string;
|
|
141
|
+
status: 'not-found';
|
|
142
|
+
};
|
|
143
|
+
|
|
95
144
|
interface TornadoProveOutput {
|
|
96
145
|
proof: `0x${string}`;
|
|
97
146
|
args: [
|
|
@@ -242,11 +291,14 @@ interface WorkerInitOptions {
|
|
|
242
291
|
|
|
243
292
|
declare function loadStateManagerWorker(workerUrl?: string | URL): {
|
|
244
293
|
remote: comlink.Remote<{
|
|
245
|
-
init(provider: _kohaku_eth_provider.EthereumProvider, relayerClient: IRelayerClient, keystore: _kohaku_eth_plugins.Keystore, rawStorage: Omit<_kohaku_eth_plugins.Storage, "_brand">, initialState: () => Promise<Record<string, PublicRootState>>, artifactsLoader: () => Promise<ITornadoArtifacts>, externalSyncProvider: ExternalSyncClient | undefined, { protocolConfig, accountIndex, relayerConfig, paymasterConfig, minExternalSyncBlocksAmount }: WorkerInitOptions): Promise<void>;
|
|
294
|
+
init(provider: _kohaku_eth_provider.EthereumProvider, relayerClient: IRelayerClient, keystore: _kohaku_eth_plugins.Keystore, rawStorage: Omit<_kohaku_eth_plugins.Storage, "_brand">, initialState: () => Promise<Record<string, PublicRootState>>, artifactsLoader: () => Promise<ITornadoArtifacts>, secretManager: ISecretManager | undefined, externalSyncProvider: ExternalSyncClient | undefined, { protocolConfig, accountIndex, relayerConfig, paymasterConfig, minExternalSyncBlocksAmount }: WorkerInitOptions): Promise<void>;
|
|
246
295
|
sync(): Promise<void>;
|
|
247
296
|
getBalances(assets?: Address[]): Promise<Map<Address, bigint>>;
|
|
248
297
|
getNotes(params: IGetNotesParams): Promise<TCNote[]>;
|
|
249
298
|
getDepositPayload(params: IDepositOperationParams): Promise<_kohaku_eth_provider.TxData[]>;
|
|
299
|
+
importNotes(params: {
|
|
300
|
+
notes: string[];
|
|
301
|
+
}): Promise<ImportNoteResult[]>;
|
|
250
302
|
getWithdrawalPayloads(params: IWithdrawapOperationParams, tailCalls?: IPaymasterWithdrawParams["tailCalls"]): Promise<IWithdrawalPayload[]>;
|
|
251
303
|
dumpState(): Record<StoreStorageKey, Omit<RootState, "userSecrets">>;
|
|
252
304
|
}>;
|