From 57f1914c39d725d26ed9d2f85055fd04d568d67e Mon Sep 17 00:00:00 2001 From: adr!an <111903096+adrianvrj@users.noreply.github.com> Date: Tue, 20 Oct 2026 10:00:32 -0600 Subject: [PATCH] Rediscover private notes from scratch before each operation The session cleared the registry notes but kept the discovery cursor, so the hosted indexer returned nothing before that cursor and every operation after the first saw a zero balance. Clear both, as the SDK itself does after a reorg. Release as 0.4.4. --- package-lock.json | 4 ++-- package.json | 2 +- src/chains/starknet/privacy/session.test.ts | 16 ++++++++++++++++ src/chains/starknet/privacy/session.ts | 1 + 4 files changed, 20 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index 603a3d1..878551a 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "@cavos/kit", - "version": "0.4.3", + "version": "0.4.4", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "@cavos/kit", - "version": "0.4.3", + "version": "0.4.4", "license": "MIT", "dependencies": { "@expo/config-plugins": "^57.0.0", diff --git a/package.json b/package.json index f9fd4ae..3eca438 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@cavos/kit", - "version": "0.4.3", + "version": "0.4.4", "description": "Embedded Stellar wallet SDK, embedded Solana wallet, and embedded Starknet wallet. Device-native self-custodial accounts for React Native and web.", "repository": { "type": "git", diff --git a/src/chains/starknet/privacy/session.test.ts b/src/chains/starknet/privacy/session.test.ts index 466553f..3921338 100644 --- a/src/chains/starknet/privacy/session.test.ts +++ b/src/chains/starknet/privacy/session.test.ts @@ -1,3 +1,4 @@ +import { ContractDiscoveryProvider } from "@starkware-libs/starknet-privacy-sdk/testing"; import { mockPrivacy, PRIVATE_KEY, STRK } from "./fixtures"; import { createPrivacySession } from "./session"; import { deriveViewingKey, viewingPublicKey } from "../viewingKey"; @@ -41,6 +42,21 @@ describe("private session on the in-memory pool", () => { expect(m.built.every((entry) => entry.headers["x-paymaster-api-key"] === "key-1")).toBe(true); }); + it("rediscovers every note from scratch before each operation", async () => { + const m = mockPrivacy(); + const session = createPrivacySession(m.init); + await session.register(); + await session.deposit(m.ace, 100n); + const discover = jest.spyOn(m.init.deps!.discoveryProvider as ContractDiscoveryProvider, "discoverNotes"); + + await session.transfer(m.ace, m.alice, 10n); + await session.withdraw(m.ace, m.alice, 10n); + + expect(discover).toHaveBeenCalled(); + expect(discover.mock.calls.every(([, , params]) => params?.cursor === undefined)).toBe(true); + expect(await session.balance(m.ace)).toBe(90n); + }); + it("sends the approval as a signed relay call and the registration with the sponsor paying", async () => { const m = mockPrivacy({ fee: USER_FEE("0x1") }); const session = createPrivacySession(m.init); diff --git a/src/chains/starknet/privacy/session.ts b/src/chains/starknet/privacy/session.ts index 210c922..603be4e 100644 --- a/src/chains/starknet/privacy/session.ts +++ b/src/chains/starknet/privacy/session.ts @@ -225,6 +225,7 @@ export class PrivacySession implements PrivacyOperations { const provingBlockId = await this.provingBlock(); this.registry ??= (await this.sdk()).createEmptyRegistry(); this.registry.notes.clear(); + delete this.registry.cursor; const builder = transfers.build({ autoSelectNotes: "naive", autoSetup: true,