From af7f9f01ffb3fe523a7f9621e6e970b3184c4709 Mon Sep 17 00:00:00 2001 From: Maksym Zub Date: Thu, 16 Jan 2025 18:58:31 +0100 Subject: [PATCH 1/2] ZK-1337: Publish packages to npm (#87) --- .github/workflows/manual-publish-dev-env.yml | 134 ------------------- .github/workflows/manual-publish-npm.yml | 99 ++++++++++++++ Makefile | 12 -- ts/package.json | 3 + 4 files changed, 102 insertions(+), 146 deletions(-) delete mode 100644 .github/workflows/manual-publish-dev-env.yml create mode 100644 .github/workflows/manual-publish-npm.yml diff --git a/.github/workflows/manual-publish-dev-env.yml b/.github/workflows/manual-publish-dev-env.yml deleted file mode 100644 index e77d009b..00000000 --- a/.github/workflows/manual-publish-dev-env.yml +++ /dev/null @@ -1,134 +0,0 @@ ---- -name: "Build and deploy development environment" - -on: - workflow_dispatch: - -jobs: - build-and-push-relayer: - name: Build and push shielder-relayer - runs-on: [self-hosted, Linux, X64, medium] - steps: - - name: GIT | Checkout - uses: actions/checkout@v4 - - - name: Prepare Rust env - uses: ./.github/actions/prepare-rust-env - with: - poseidon-gadget-private-key: ${{ secrets.SSH_PRIVATE_KEY }} - zkos-circuits-private-key: ${{ secrets.ZKOS_CIRCUITS_SSH_PRIVATE_KEY }} - - - name: Build relayer - run: cd crates/shielder-relayer && make build - - - name: DOCKER | Build and push - uses: ./.github/actions/shielder-relayer/build-and-push - id: build_shielder_relayer - with: - aws-mainnet-ecr-access-key-id: ${{ secrets.AWS_MAINNET_ECR_ACCESS_KEY_ID }} - aws-mainnet-ecr-access-key: ${{ secrets.AWS_MAINNET_ECR_ACCESS_KEY }} - ecr-private-host: ${{ secrets.ECR_PRIVATE_HOST }} - outputs: - image_tag: ${{ steps.build_shielder_relayer.outputs.image_tag }} - - shielder-sdk: - name: Build and push shielder-sdk - runs-on: [self-hosted, Linux, X64, medium] - steps: - - name: GIT | Checkout - uses: actions/checkout@v4 - - - name: Prepare Rust env - uses: ./.github/actions/prepare-rust-env - with: - poseidon-gadget-private-key: ${{ secrets.SSH_PRIVATE_KEY }} - zkos-circuits-private-key: ${{ secrets.ZKOS_CIRCUITS_SSH_PRIVATE_KEY }} - - - name: Install wasm-pack - run: curl https://rustwasm.github.io/wasm-pack/installer/init.sh -sSf | sh - - - name: Install Node.js - uses: actions/setup-node@v4 - with: - node-version: 18 - - - uses: pnpm/action-setup@v4 - with: - version: latest - - - name: Install Foundry - uses: foundry-rs/foundry-toolchain@v1.2.0 - with: - cache-key: custom-seed-coverage-${{ github.ref_name }} - cache-restore-keys: |- - contract-suite - version: nightly-31dd1f77fd9156d09836486d97963cec7f555343 - - - name: Install deps - run: make deps - - - name: Compile eth contracts - run: make compile-contracts - - - name: Build shielder-wasm - run: make all - working-directory: crates/shielder-wasm - - - name: Install dependencies (shielder-sdk) - run: pnpm install --frozen-lockfile - working-directory: ts/shielder-sdk - - - name: Build shielder-sdk - run: pnpm build - working-directory: ts/shielder-sdk - - - name: Add .npmrc with publish token - run: echo "//registry.npmjs.org/:_authToken=${{ secrets.NPM_PUBLISHING_KEY }}" > .npmrc - working-directory: ts/shielder-sdk - - - name: Publish shielder-sdk - run: pnpm publish --access restricted --no-git-checks - working-directory: ts/shielder-sdk - - tooling-dev: - name: Generate developer scripts - runs-on: [self-hosted, Linux, X64, medium] - steps: - - name: GIT | Checkout - uses: actions/checkout@v4 - - - name: Install Node.js - uses: actions/setup-node@v4 - with: - node-version: 18 - - - name: Prepare Rust env - uses: ./.github/actions/prepare-rust-env - with: - poseidon-gadget-private-key: ${{ secrets.SSH_PRIVATE_KEY }} - zkos-circuits-private-key: ${{ secrets.ZKOS_CIRCUITS_SSH_PRIVATE_KEY }} - - - name: Install Foundry - uses: foundry-rs/foundry-toolchain@v1.2.0 - with: - cache-key: custom-seed-coverage-${{ github.ref_name }} - cache-restore-keys: |- - contract-suite - version: nightly-31dd1f77fd9156d09836486d97963cec7f555343 - - - name: Install deps - run: make deps - - - name: Compile eth contracts - run: make compile-contracts - - - name: Generate developer scripts - run: make generate-tooling-dev - - - name: Upload developer scripts to artifacts - uses: actions/upload-artifact@v4 - with: - name: tooling-dev - path: tooling-dev - include-hidden-files: true - retention-days: 14 diff --git a/.github/workflows/manual-publish-npm.yml b/.github/workflows/manual-publish-npm.yml new file mode 100644 index 00000000..4308fbe4 --- /dev/null +++ b/.github/workflows/manual-publish-npm.yml @@ -0,0 +1,99 @@ +--- +name: "Build and publish packages to npm" + +on: + workflow_dispatch: + inputs: + package: + description: "Package to publish" + required: true + type: choice + options: + - shielder-sdk + - shielder-sdk-crypto + - shielder-sdk-crypto-wasm + tag: + description: "NPM tag" + required: true + type: choice + options: + - develop + - latest + +jobs: + publish: + name: Build and push ${{ github.event.inputs.package }} + runs-on: [self-hosted, Linux, X64, medium] + steps: + - name: GIT | Checkout + uses: actions/checkout@v4 + + # Rust setup for shielder-sdk-crypto-wasm and shielder-sdk + - name: Prepare Rust env + if: | + github.event.inputs.package == 'shielder-sdk-crypto-wasm' || + github.event.inputs.package == 'shielder-sdk' + uses: ./.github/actions/prepare-rust-env + with: + poseidon-gadget-private-key: ${{ secrets.SSH_PRIVATE_KEY }} + zkos-circuits-private-key: ${{ secrets.ZKOS_CIRCUITS_SSH_PRIVATE_KEY }} + + - name: Install wasm-pack + if: github.event.inputs.package == 'shielder-sdk-crypto-wasm' + run: curl https://rustwasm.github.io/wasm-pack/installer/init.sh -sSf | sh + + # Foundry setup for shielder-sdk + - name: Install Foundry + if: github.event.inputs.package == 'shielder-sdk' + uses: foundry-rs/foundry-toolchain@v1.2.0 + with: + cache-key: custom-seed-coverage-${{ github.ref_name }} + cache-restore-keys: |- + contract-suite + version: nightly-31dd1f77fd9156d09836486d97963cec7f555343 + + - name: Install deps and compile contracts + if: github.event.inputs.package == 'shielder-sdk' + run: | + make deps + make compile-contracts + + # Common Node.js setup + - name: Install Node.js + uses: actions/setup-node@v4 + with: + node-version: 23 + + - uses: pnpm/action-setup@v4 + with: + version: latest + + # Build steps + - name: Build shielder-wasm + if: github.event.inputs.package == 'shielder-sdk-crypto-wasm' + run: make all + working-directory: crates/shielder-wasm + + - name: Install dependencies (workspace) + run: pnpm install-deps + working-directory: ts + + - name: Build package + run: | + if [ "${{ github.event.inputs.package }}" = "shielder-sdk" ]; then + pnpm build-package:sdk + elif [ "${{ github.event.inputs.package }}" = "shielder-sdk-crypto" ]; then + pnpm build-package:crypto + else + pnpm build-package:crypto-wasm + fi + working-directory: ts + + # Publish + - name: Add .npmrc with publish token + run: echo "//registry.npmjs.org/:_authToken=${{ secrets.NPM_PUBLISHING_KEY }}" > .npmrc + working-directory: ts/${{ github.event.inputs.package }} + + - name: Publish package + run: pnpm publish --access restricted --no-git-checks --tag ${{ github.event.inputs.tag }} + working-directory: ts/${{ github.event.inputs.package }} diff --git a/Makefile b/Makefile index 0ebb0331..e96eef88 100644 --- a/Makefile +++ b/Makefile @@ -87,15 +87,3 @@ format-rust: lint-rust: # Lint all rust crates lint-rust: cargo clippy --release -- -D warnings - -.PHONY: generate-tooling-dev -generate-tooling-dev: # Generate tooling-dev package -generate-tooling-dev: - cp tooling-e2e-tests/local_env.sh tooling-dev/ - cp crates/shielder-relayer/run-relayer.sh tooling-dev/ - cp package.json tooling-dev/ - cp package-lock.json tooling-dev/ - cp foundry.toml tooling-dev/ - cp -r contracts tooling-dev/ - cp -r scripts tooling-dev/ - git rev-parse --short=7 HEAD > tooling-dev/.git-sha diff --git a/ts/package.json b/ts/package.json index 5cce5444..cb344fee 100644 --- a/ts/package.json +++ b/ts/package.json @@ -11,6 +11,9 @@ "build:crypto": "pnpm --filter shielder-sdk-crypto build", "build:crypto-wasm": "pnpm --filter shielder-sdk-crypto-wasm build", "build:sdk": "pnpm --filter shielder-sdk build", + "build-package:crypto": "pnpm build:crypto", + "build-package:crypto-wasm": "pnpm build:crypto && pnpm build:crypto-wasm", + "build-package:sdk": "pnpm build:crypto && pnpm build:sdk", "test": "pnpm -r test", "lint": "pnpm -r lint", "install-deps": "pnpm install --frozen-lockfile" From f4125ccccb7da6874cef56c91b955dc3403ed77d Mon Sep 17 00:00:00 2001 From: Maksym Zub Date: Fri, 17 Jan 2025 16:10:42 +0100 Subject: [PATCH 2/2] ZK-1337: simplify directory layout & remove console logs (#91) --- .../{shielder => }/actions/deposit.test.ts | 13 ++--- .../{shielder => }/actions/newAccount.test.ts | 13 ++--- .../{shielder => }/actions/withdraw.test.ts | 10 ++-- .../src/{shielder => }/actions/deposit.ts | 10 ++-- .../src/{shielder => }/actions/index.ts | 4 +- .../src/{shielder => }/actions/newAccount.ts | 8 +-- .../src/{shielder => }/actions/utils.ts | 2 +- .../src/{shielder => }/actions/withdraw.ts | 6 +- ts/shielder-sdk/src/{shielder => }/client.ts | 44 ++++++++------- ts/shielder-sdk/src/index.ts | 6 +- .../src/{shielder => }/state/events.ts | 8 +-- ts/shielder-sdk/src/state/index.ts | 20 +++++++ .../state/index.ts => state/manager.ts} | 56 +------------------ .../src/{shielder => }/state/storageSchema.ts | 5 +- .../src/{shielder => }/state/sync.ts | 23 +++++--- ts/shielder-sdk/src/state/types.ts | 37 ++++++++++++ 16 files changed, 135 insertions(+), 130 deletions(-) rename ts/shielder-sdk/__tests/{shielder => }/actions/deposit.test.ts (97%) rename ts/shielder-sdk/__tests/{shielder => }/actions/newAccount.test.ts (95%) rename ts/shielder-sdk/__tests/{shielder => }/actions/withdraw.test.ts (97%) rename ts/shielder-sdk/src/{shielder => }/actions/deposit.ts (94%) rename ts/shielder-sdk/src/{shielder => }/actions/index.ts (81%) rename ts/shielder-sdk/src/{shielder => }/actions/newAccount.ts (94%) rename ts/shielder-sdk/src/{shielder => }/actions/utils.ts (97%) rename ts/shielder-sdk/src/{shielder => }/actions/withdraw.ts (97%) rename ts/shielder-sdk/src/{shielder => }/client.ts (96%) rename ts/shielder-sdk/src/{shielder => }/state/events.ts (87%) create mode 100644 ts/shielder-sdk/src/state/index.ts rename ts/shielder-sdk/src/{shielder/state/index.ts => state/manager.ts} (73%) rename ts/shielder-sdk/src/{shielder => }/state/storageSchema.ts (94%) rename ts/shielder-sdk/src/{shielder => }/state/sync.ts (90%) create mode 100644 ts/shielder-sdk/src/state/types.ts diff --git a/ts/shielder-sdk/__tests/shielder/actions/deposit.test.ts b/ts/shielder-sdk/__tests/actions/deposit.test.ts similarity index 97% rename from ts/shielder-sdk/__tests/shielder/actions/deposit.test.ts rename to ts/shielder-sdk/__tests/actions/deposit.test.ts index fcb40921..c08ec4ff 100644 --- a/ts/shielder-sdk/__tests/shielder/actions/deposit.test.ts +++ b/ts/shielder-sdk/__tests/actions/deposit.test.ts @@ -8,15 +8,12 @@ import { scalarToBigint } from "@cardinal-cryptography/shielder-sdk-crypto"; -import { MockedCryptoClient, hashedNote } from "../../helpers"; +import { MockedCryptoClient, hashedNote } from "../helpers"; -import { DepositAction } from "../../../src/shielder/actions/deposit"; -import { AccountState } from "../../../src/shielder/state"; -import { - IContract, - VersionRejectedByContract -} from "../../../src/chain/contract"; -import { SendShielderTransaction } from "../../../src/shielder/client"; +import { DepositAction } from "../../src/actions/deposit"; +import { AccountState } from "../../src/state"; +import { IContract, VersionRejectedByContract } from "../../src/chain/contract"; +import { SendShielderTransaction } from "../../src/client"; const expectPubInputsCorrect = async ( pubInputs: DepositPubInputs, diff --git a/ts/shielder-sdk/__tests/shielder/actions/newAccount.test.ts b/ts/shielder-sdk/__tests/actions/newAccount.test.ts similarity index 95% rename from ts/shielder-sdk/__tests/shielder/actions/newAccount.test.ts rename to ts/shielder-sdk/__tests/actions/newAccount.test.ts index 55409f77..961313d9 100644 --- a/ts/shielder-sdk/__tests/shielder/actions/newAccount.test.ts +++ b/ts/shielder-sdk/__tests/actions/newAccount.test.ts @@ -8,15 +8,12 @@ import { scalarToBigint } from "@cardinal-cryptography/shielder-sdk-crypto"; -import { MockedCryptoClient, hashedNote } from "../../helpers"; +import { MockedCryptoClient, hashedNote } from "../helpers"; -import { NewAccountAction } from "../../../src/shielder/actions/newAccount"; -import { AccountState } from "../../../src/shielder/state"; -import { - IContract, - VersionRejectedByContract -} from "../../../src/chain/contract"; -import { SendShielderTransaction } from "../../../src/shielder/client"; +import { NewAccountAction } from "../../src/actions/newAccount"; +import { AccountState } from "../../src/state"; +import { IContract, VersionRejectedByContract } from "../../src/chain/contract"; +import { SendShielderTransaction } from "../../src/client"; const expectPubInputsCorrect = async ( pubInputs: NewAccountPubInputs, diff --git a/ts/shielder-sdk/__tests/shielder/actions/withdraw.test.ts b/ts/shielder-sdk/__tests/actions/withdraw.test.ts similarity index 97% rename from ts/shielder-sdk/__tests/shielder/actions/withdraw.test.ts rename to ts/shielder-sdk/__tests/actions/withdraw.test.ts index 596ac9cb..07a67bb9 100644 --- a/ts/shielder-sdk/__tests/shielder/actions/withdraw.test.ts +++ b/ts/shielder-sdk/__tests/actions/withdraw.test.ts @@ -8,16 +8,16 @@ import { WithdrawPubInputs } from "@cardinal-cryptography/shielder-sdk-crypto"; -import { MockedCryptoClient, hashedNote } from "../../helpers"; +import { MockedCryptoClient, hashedNote } from "../helpers"; -import { WithdrawAction } from "../../../src/shielder/actions/withdraw"; -import { AccountState } from "../../../src/shielder/state"; -import { IContract } from "../../../src/chain/contract"; +import { WithdrawAction } from "../../src/actions/withdraw"; +import { AccountState } from "../../src/state"; +import { IContract } from "../../src/chain/contract"; import { IRelayer, VersionRejectedByRelayer, WithdrawResponse -} from "../../../src/chain/relayer"; +} from "../../src/chain/relayer"; import { encodePacked, hexToBigInt, keccak256 } from "viem"; const expectPubInputsCorrect = async ( diff --git a/ts/shielder-sdk/src/shielder/actions/deposit.ts b/ts/shielder-sdk/src/actions/deposit.ts similarity index 94% rename from ts/shielder-sdk/src/shielder/actions/deposit.ts rename to ts/shielder-sdk/src/actions/deposit.ts index 7c0ec29d..1a6a0d38 100644 --- a/ts/shielder-sdk/src/shielder/actions/deposit.ts +++ b/ts/shielder-sdk/src/actions/deposit.ts @@ -6,10 +6,10 @@ import { Scalar, scalarToBigint } from "@cardinal-cryptography/shielder-sdk-crypto"; -import { SendShielderTransaction } from "@/shielder/client"; -import { Calldata } from "@/shielder/actions"; -import { INonceGenerator, NoteAction } from "@/shielder/actions/utils"; -import { AccountState } from "@/shielder/state"; +import { SendShielderTransaction } from "@/client"; +import { Calldata } from "@/actions"; +import { INonceGenerator, NoteAction } from "@/actions/utils"; +import { AccountState } from "@/state"; export interface DepositCalldata extends Calldata { calldata: { @@ -128,7 +128,6 @@ export class DepositAction extends NoteAction { trapdoorNew }) .catch((e) => { - console.error(e); throw new Error(`Failed to prove deposit: ${e}`); }); const pubInputs = await this.preparePubInputs( @@ -190,7 +189,6 @@ export class DepositAction extends NoteAction { if (e instanceof VersionRejectedByContract) { throw e; } - console.error(e); throw new Error(`Failed to deposit: ${e}`); }); return txHash; diff --git a/ts/shielder-sdk/src/shielder/actions/index.ts b/ts/shielder-sdk/src/actions/index.ts similarity index 81% rename from ts/shielder-sdk/src/shielder/actions/index.ts rename to ts/shielder-sdk/src/actions/index.ts index 9abde580..2938b739 100644 --- a/ts/shielder-sdk/src/shielder/actions/index.ts +++ b/ts/shielder-sdk/src/actions/index.ts @@ -1,6 +1,7 @@ import { NewAccountAction, NewAccountCalldata } from "./newAccount"; import { DepositAction, DepositCalldata } from "./deposit"; import { WithdrawAction, WithdrawCalldata } from "./withdraw"; +import { INonceGenerator } from "./utils"; export interface Calldata { provingTimeMillis: number; @@ -12,5 +13,6 @@ export { NewAccountAction, NewAccountCalldata, WithdrawAction, - WithdrawCalldata + WithdrawCalldata, + INonceGenerator }; diff --git a/ts/shielder-sdk/src/shielder/actions/newAccount.ts b/ts/shielder-sdk/src/actions/newAccount.ts similarity index 94% rename from ts/shielder-sdk/src/shielder/actions/newAccount.ts rename to ts/shielder-sdk/src/actions/newAccount.ts index b1c49989..516f3512 100644 --- a/ts/shielder-sdk/src/shielder/actions/newAccount.ts +++ b/ts/shielder-sdk/src/actions/newAccount.ts @@ -6,9 +6,9 @@ import { Scalar, scalarToBigint } from "@cardinal-cryptography/shielder-sdk-crypto"; -import { SendShielderTransaction } from "@/shielder/client"; -import { NoteAction } from "@/shielder/actions/utils"; -import { AccountState } from "@/shielder/state"; +import { SendShielderTransaction } from "@/client"; +import { NoteAction } from "@/actions/utils"; +import { AccountState } from "@/state"; export interface NewAccountCalldata { calldata: { @@ -83,7 +83,6 @@ export class NewAccountAction extends NoteAction { initialDeposit: Scalar.fromBigint(amount) }) .catch((e) => { - console.error(e); throw new Error(`Failed to prove new account: ${e}`); }); const pubInputs = await this.preparePubInputs(state, amount); @@ -132,7 +131,6 @@ export class NewAccountAction extends NoteAction { to: this.contract.getAddress(), value: amount }).catch((e) => { - console.error(e); throw new Error(`Failed to create new account: ${e}`); }); return txHash; diff --git a/ts/shielder-sdk/src/shielder/actions/utils.ts b/ts/shielder-sdk/src/actions/utils.ts similarity index 97% rename from ts/shielder-sdk/src/shielder/actions/utils.ts rename to ts/shielder-sdk/src/actions/utils.ts index 0b58c635..254e90ed 100644 --- a/ts/shielder-sdk/src/shielder/actions/utils.ts +++ b/ts/shielder-sdk/src/actions/utils.ts @@ -2,7 +2,7 @@ import { CryptoClient, Scalar } from "@cardinal-cryptography/shielder-sdk-crypto"; -import { AccountState } from "@/shielder/state"; +import { AccountState } from "@/state"; import { noteVersion } from "@/utils"; export abstract class NoteAction { diff --git a/ts/shielder-sdk/src/shielder/actions/withdraw.ts b/ts/shielder-sdk/src/actions/withdraw.ts similarity index 97% rename from ts/shielder-sdk/src/shielder/actions/withdraw.ts rename to ts/shielder-sdk/src/actions/withdraw.ts index aaed266d..2bb11801 100644 --- a/ts/shielder-sdk/src/shielder/actions/withdraw.ts +++ b/ts/shielder-sdk/src/actions/withdraw.ts @@ -6,10 +6,10 @@ import { scalarToBigint, WithdrawPubInputs } from "@cardinal-cryptography/shielder-sdk-crypto"; -import { AccountState } from "@/shielder/state"; +import { AccountState } from "@/state"; import { Address, encodePacked, hexToBigInt, keccak256 } from "viem"; import { IRelayer, VersionRejectedByRelayer } from "@/chain/relayer"; -import { INonceGenerator, NoteAction } from "@/shielder/actions/utils"; +import { INonceGenerator, NoteAction } from "@/actions/utils"; export interface WithdrawCalldata { expectedContractVersion: `0x${string}`; @@ -189,7 +189,6 @@ export class WithdrawAction extends NoteAction { commitment }) .catch((e) => { - console.error(e); throw new Error(`Failed to prove withdrawal: ${e}`); }); const pubInputs = await this.preparePubInputs( @@ -247,7 +246,6 @@ export class WithdrawAction extends NoteAction { if (e instanceof VersionRejectedByRelayer) { throw e; } - console.error(e); throw new Error(`Failed to withdraw: ${e}`); }); return txHash as `0x${string}`; diff --git a/ts/shielder-sdk/src/shielder/client.ts b/ts/shielder-sdk/src/client.ts similarity index 96% rename from ts/shielder-sdk/src/shielder/client.ts rename to ts/shielder-sdk/src/client.ts index 055f5003..46101301 100644 --- a/ts/shielder-sdk/src/shielder/client.ts +++ b/ts/shielder-sdk/src/client.ts @@ -1,8 +1,5 @@ -import { - Contract, - IContract, - VersionRejectedByContract -} from "@/chain/contract"; +import { CryptoClient } from "@cardinal-cryptography/shielder-sdk-crypto"; +import { CustomError } from "ts-custom-error"; import { Address, createPublicClient, @@ -11,26 +8,31 @@ import { http, PublicClient } from "viem"; -import { IRelayer, Relayer, VersionRejectedByRelayer } from "@/chain/relayer"; -import { ShielderTransaction, StateManager } from "@/shielder/state"; -import { NewAccountAction } from "@/shielder/actions/newAccount"; -import { DepositAction } from "@/shielder/actions/deposit"; -import { WithdrawAction } from "@/shielder/actions/withdraw"; + import { - StateSynchronizer, - UnexpectedVersionInEvent -} from "@/shielder/state/sync"; + Contract, + IContract, + VersionRejectedByContract +} from "@/chain/contract"; +import { IRelayer, Relayer, VersionRejectedByRelayer } from "@/chain/relayer"; import { - createStorage, - InjectedStorageInterface -} from "@/shielder/state/storageSchema"; -import { Calldata } from "@/shielder/actions"; + NewAccountAction, + DepositAction, + WithdrawAction, + INonceGenerator, + Calldata +} from "@/actions"; import { contractVersion } from "@/constants"; -import { CustomError } from "ts-custom-error"; -import { CryptoClient } from "@cardinal-cryptography/shielder-sdk-crypto"; -import { StateEventsFilter } from "@/shielder/state/events"; -import { INonceGenerator } from "./actions/utils"; import { idHidingNonce } from "@/utils"; +import { + createStorage, + InjectedStorageInterface, + ShielderTransaction, + StateEventsFilter, + StateManager, + StateSynchronizer, + UnexpectedVersionInEvent +} from "@/state"; export type ShielderOperation = "shield" | "withdraw" | "sync"; diff --git a/ts/shielder-sdk/src/index.ts b/ts/shielder-sdk/src/index.ts index 20e05bfc..8dd1ccca 100644 --- a/ts/shielder-sdk/src/index.ts +++ b/ts/shielder-sdk/src/index.ts @@ -2,7 +2,7 @@ export { createShielderClient, SendShielderTransaction, OutdatedSdkError -} from "@/shielder/client"; -export { type AccountState, type ShielderTransaction } from "@/shielder/state"; -export { storageSchema, InjectedStorageInterface } from "@/shielder/state"; +} from "@/client"; +export { type AccountState, type ShielderTransaction } from "@/state"; +export { storageSchema, InjectedStorageInterface } from "@/state"; export { shieldActionGasLimit } from "@/constants"; diff --git a/ts/shielder-sdk/src/shielder/state/events.ts b/ts/shielder-sdk/src/state/events.ts similarity index 87% rename from ts/shielder-sdk/src/shielder/state/events.ts rename to ts/shielder-sdk/src/state/events.ts index 990c3557..165b8ae0 100644 --- a/ts/shielder-sdk/src/shielder/state/events.ts +++ b/ts/shielder-sdk/src/state/events.ts @@ -1,7 +1,7 @@ -import { AccountState } from "@/shielder/state"; -import { DepositAction } from "@/shielder/actions/deposit"; -import { NewAccountAction } from "@/shielder/actions/newAccount"; -import { WithdrawAction } from "@/shielder/actions/withdraw"; +import { AccountState } from "@/state"; +import { DepositAction } from "@/actions/deposit"; +import { NewAccountAction } from "@/actions/newAccount"; +import { WithdrawAction } from "@/actions/withdraw"; import { NoteEvent } from "@/chain/contract"; import { scalarToBigint } from "@cardinal-cryptography/shielder-sdk-crypto"; diff --git a/ts/shielder-sdk/src/state/index.ts b/ts/shielder-sdk/src/state/index.ts new file mode 100644 index 00000000..cfdf1564 --- /dev/null +++ b/ts/shielder-sdk/src/state/index.ts @@ -0,0 +1,20 @@ +import { StateManager } from "./manager"; +import { StateSynchronizer, UnexpectedVersionInEvent } from "./sync"; +import { StateEventsFilter } from "./events"; +import storageSchema, { + InjectedStorageInterface, + createStorage +} from "./storageSchema"; +import { ShielderTransaction, AccountState } from "./types"; + +export { + storageSchema, + createStorage, + AccountState, + InjectedStorageInterface, + ShielderTransaction, + StateManager, + StateSynchronizer, + StateEventsFilter, + UnexpectedVersionInEvent +}; diff --git a/ts/shielder-sdk/src/shielder/state/index.ts b/ts/shielder-sdk/src/state/manager.ts similarity index 73% rename from ts/shielder-sdk/src/shielder/state/index.ts rename to ts/shielder-sdk/src/state/manager.ts index 81e3d878..0bca8aa6 100644 --- a/ts/shielder-sdk/src/shielder/state/index.ts +++ b/ts/shielder-sdk/src/state/manager.ts @@ -4,59 +4,11 @@ import { scalarsEqual, scalarToBigint } from "@cardinal-cryptography/shielder-sdk-crypto"; -import { Address, Hex } from "viem"; -import storageSchema, { - InjectedStorageInterface, - StorageInterface -} from "./storageSchema"; -import { NoteEvent } from "@/chain/contract"; +import { StorageInterface } from "./storageSchema"; +import { Hex } from "viem"; +import { AccountState } from "./types"; import { storageSchemaVersion } from "@/constants"; -export type AccountState = { - /** - * Account id, a scalar derived from the private key. - */ - id: Scalar; - /** - * Account nonce, increments for each new action. - */ - nonce: bigint; - /** - * Account balance, in wei. - */ - balance: bigint; - /** - * Hash of the last note. - */ - currentNote: Scalar; - /** - * Merkle tree index of the last note. - */ - currentNoteIndex?: bigint; - /** - * Version of the storage schema. - */ - storageSchemaVersion: number; -}; - -export type ShielderTransaction = { - type: "NewAccountNative" | "DepositNative" | "WithdrawNative"; - amount: bigint; - to?: Address; - txHash: Hex; - block: bigint; -}; - -export const eventToTransaction = (event: NoteEvent): ShielderTransaction => { - return { - type: event.name, - amount: event.amount, - to: event.to, - txHash: event.txHash, - block: event.block - }; -}; - export class StateManager { private storage: StorageInterface; private privateKey: Hex; @@ -155,5 +107,3 @@ const emptyAccountState = (id: Scalar): AccountState => { storageSchemaVersion }; }; - -export { storageSchema, InjectedStorageInterface, emptyAccountState }; diff --git a/ts/shielder-sdk/src/shielder/state/storageSchema.ts b/ts/shielder-sdk/src/state/storageSchema.ts similarity index 94% rename from ts/shielder-sdk/src/shielder/state/storageSchema.ts rename to ts/shielder-sdk/src/state/storageSchema.ts index 67aaaec0..d3719bcd 100644 --- a/ts/shielder-sdk/src/shielder/state/storageSchema.ts +++ b/ts/shielder-sdk/src/state/storageSchema.ts @@ -54,8 +54,9 @@ const createStorage = ( try { return storageSchema[key].parse(JSON.parse(storedValue)); } catch (error) { - console.error(`Failed to parse storage value for key ${key}:`, error); - return null; + throw new Error( + `Failed to parse storage value for key ${key}: ${(error as Error).message}` + ); } }; const setItem = async ( diff --git a/ts/shielder-sdk/src/shielder/state/sync.ts b/ts/shielder-sdk/src/state/sync.ts similarity index 90% rename from ts/shielder-sdk/src/shielder/state/sync.ts rename to ts/shielder-sdk/src/state/sync.ts index abc1b8f6..30ce306b 100644 --- a/ts/shielder-sdk/src/shielder/state/sync.ts +++ b/ts/shielder-sdk/src/state/sync.ts @@ -1,18 +1,14 @@ import { CustomError } from "ts-custom-error"; -import { IContract } from "@/chain/contract"; +import { IContract, NoteEvent } from "@/chain/contract"; import { CryptoClient, scalarToBigint } from "@cardinal-cryptography/shielder-sdk-crypto"; -import { - AccountState, - eventToTransaction, - ShielderTransaction, - StateManager -} from "@/shielder/state"; -import { StateEventsFilter } from "@/shielder/state/events"; +import { StateEventsFilter } from "@/state/events"; import { Mutex } from "async-mutex"; import { isVersionSupported } from "@/utils"; +import { StateManager } from "./manager"; +import { AccountState, ShielderTransaction } from "./types"; export class UnexpectedVersionInEvent extends CustomError { public constructor(message: string) { @@ -111,7 +107,6 @@ export class StateSynchronizer { ); if (events.length != 1) { - console.error(events); throw new Error( `Unexpected number of events: ${events.length}, expected 1 event` ); @@ -146,3 +141,13 @@ export class StateSynchronizer { return event; } } + +const eventToTransaction = (event: NoteEvent): ShielderTransaction => { + return { + type: event.name, + amount: event.amount, + to: event.to, + txHash: event.txHash, + block: event.block + }; +}; diff --git a/ts/shielder-sdk/src/state/types.ts b/ts/shielder-sdk/src/state/types.ts new file mode 100644 index 00000000..98c52d70 --- /dev/null +++ b/ts/shielder-sdk/src/state/types.ts @@ -0,0 +1,37 @@ +import { Scalar } from "@cardinal-cryptography/shielder-sdk-crypto"; +import { Address, Hex } from "viem"; + +export type AccountState = { + /** + * Account id, a scalar derived from the private key. + */ + id: Scalar; + /** + * Account nonce, increments for each new action. + */ + nonce: bigint; + /** + * Account balance, in wei. + */ + balance: bigint; + /** + * Hash of the last note. + */ + currentNote: Scalar; + /** + * Merkle tree index of the last note. + */ + currentNoteIndex?: bigint; + /** + * Version of the storage schema. + */ + storageSchemaVersion: number; +}; + +export type ShielderTransaction = { + type: "NewAccountNative" | "DepositNative" | "WithdrawNative"; + amount: bigint; + to?: Address; + txHash: Hex; + block: bigint; +};