From 7ba6eef5b6d7ef5b6170b7eba7d4126101f7af56 Mon Sep 17 00:00:00 2001 From: Swenschaeferjohann Date: Thu, 19 Dec 2024 03:29:39 +0000 Subject: [PATCH 01/19] pin js sdks to use web3.js@1.95.5 wip remove anchor from stateless.js add buffer-layout.dt.ts add note wip wip remove anchor dep in ctoken use bs58 fmt wip remove custom program id test fix dl keyss statelessjs bundle optimization. remove idls rm tweetnacl, minify compressed-token lib wip. less externals wip: try alpha npm release script with alpha option wip wip stateless.js works with web3js 1.73.5 - alpha wip --- cli/package.json | 2 +- examples/browser/nextjs/package.json | 2 +- examples/node/esm/package.json | 2 +- js/compressed-token/package.json | 79 +- js/compressed-token/rollup.config.js | 24 +- .../src/actions/approve-and-mint-to.ts | 2 +- .../src/actions/compress-spl-token-account.ts | 2 +- js/compressed-token/src/actions/compress.ts | 2 +- js/compressed-token/src/actions/decompress.ts | 2 +- js/compressed-token/src/actions/mint-to.ts | 2 +- js/compressed-token/src/actions/transfer.ts | 2 +- js/compressed-token/src/idl/index.ts | 1 - .../src/idl/light_compressed_token.ts | 3481 ---------------- js/compressed-token/src/index.ts | 1 - .../pack-compressed-token-accounts.ts | 6 +- js/compressed-token/src/layout.ts | 607 +++ js/compressed-token/src/program.ts | 342 +- js/compressed-token/src/types.ts | 67 +- .../tests/e2e/approve-and-mint-to.test.ts | 2 +- .../tests/e2e/compress.test.ts | 2 +- .../tests/e2e/create-mint.test.ts | 7 +- .../tests/e2e/custom-program-id.test.ts | 42 - .../tests/e2e/decompress.test.ts | 2 +- js/compressed-token/tests/e2e/layout.test.ts | 61 + js/compressed-token/tests/e2e/mint-to.test.ts | 2 +- .../tests/e2e/rpc-token-interop.test.ts | 2 +- .../tests/e2e/transfer.test.ts | 2 +- js/compressed-token/tsconfig.json | 3 +- .../types/buffer-layout/index.d.ts | 88 + js/stateless.js/README.md | 8 + js/stateless.js/package.json | 29 +- js/stateless.js/rollup.config.js | 27 +- js/stateless.js/src/actions/compress.ts | 2 +- js/stateless.js/src/actions/create-account.ts | 2 +- js/stateless.js/src/actions/decompress.ts | 2 +- js/stateless.js/src/actions/transfer.ts | 2 +- js/stateless.js/src/connection-interface.ts | 545 +++ js/stateless.js/src/constants.ts | 2 +- .../src/idls/account_compression.ts | 2797 ------------- js/stateless.js/src/idls/index.ts | 26 - .../src/idls/light_compressed_token.ts | 3481 ---------------- js/stateless.js/src/idls/light_registry.ts | 3483 ----------------- .../src/idls/light_system_program.ts | 2034 ---------- js/stateless.js/src/index.ts | 2 - js/stateless.js/src/programs/index.ts | 1 + js/stateless.js/src/programs/layout.ts | 213 + js/stateless.js/src/programs/system.ts | 189 +- js/stateless.js/src/rpc-interface.ts | 45 +- js/stateless.js/src/rpc.ts | 825 +++- js/stateless.js/src/state/BN254.ts | 4 +- .../src/state/compressed-account.ts | 2 +- js/stateless.js/src/state/types.ts | 28 +- .../test-helpers/merkle-tree/indexed-array.ts | 2 +- .../test-rpc/get-compressed-accounts.ts | 2 +- .../test-rpc/get-compressed-token-accounts.ts | 31 +- .../test-rpc/get-parsed-events.ts | 8 +- .../src/test-helpers/test-rpc/test-rpc.ts | 835 +++- js/stateless.js/src/utils/conversion.ts | 2 +- .../src/utils/parse-validity-proof.ts | 2 +- js/stateless.js/src/utils/validation.ts | 2 +- js/stateless.js/src/wallet/index.ts | 1 - js/stateless.js/src/wallet/interface.ts | 85 - js/stateless.js/src/wallet/use-wallet.ts | 20 - js/stateless.js/tests/e2e/rpc-interop.test.ts | 10 +- js/stateless.js/tests/e2e/serde.test.ts | 85 +- js/stateless.js/tsconfig.json | 3 +- .../types/buffer-layout/index.d.ts | 88 + pnpm-lock.yaml | 278 +- programs/package.json | 2 - scripts/bump-versions-and-publish-npm.sh | 30 +- 70 files changed, 3964 insertions(+), 16110 deletions(-) delete mode 100644 js/compressed-token/src/idl/index.ts delete mode 100644 js/compressed-token/src/idl/light_compressed_token.ts create mode 100644 js/compressed-token/src/layout.ts delete mode 100644 js/compressed-token/tests/e2e/custom-program-id.test.ts create mode 100644 js/compressed-token/tests/e2e/layout.test.ts create mode 100644 js/compressed-token/types/buffer-layout/index.d.ts create mode 100644 js/stateless.js/src/connection-interface.ts delete mode 100644 js/stateless.js/src/idls/account_compression.ts delete mode 100644 js/stateless.js/src/idls/index.ts delete mode 100644 js/stateless.js/src/idls/light_compressed_token.ts delete mode 100644 js/stateless.js/src/idls/light_registry.ts delete mode 100644 js/stateless.js/src/idls/light_system_program.ts create mode 100644 js/stateless.js/src/programs/layout.ts delete mode 100644 js/stateless.js/src/wallet/index.ts delete mode 100644 js/stateless.js/src/wallet/interface.ts delete mode 100644 js/stateless.js/src/wallet/use-wallet.ts create mode 100644 js/stateless.js/types/buffer-layout/index.d.ts diff --git a/cli/package.json b/cli/package.json index b3d05a95fe..19350a2edb 100644 --- a/cli/package.json +++ b/cli/package.json @@ -42,7 +42,7 @@ "@oclif/plugin-not-found": "^3.1.2", "@oclif/plugin-plugins": "^5.0.7", "@solana-developers/helpers": "^1.5.1", - "@solana/web3.js": "1.95.3", + "@solana/web3.js": "1.95.5", "axios": "^1.6.8", "case-anything": "^2.1.13", "cli-progress": "^3.12.0", diff --git a/examples/browser/nextjs/package.json b/examples/browser/nextjs/package.json index ed13251ad0..734a618b73 100644 --- a/examples/browser/nextjs/package.json +++ b/examples/browser/nextjs/package.json @@ -19,7 +19,7 @@ "@solana/wallet-adapter-react": "^0.15.35", "@solana/wallet-adapter-react-ui": "^0.9.35", "@solana/wallet-adapter-unsafe-burner": "^0.1.7", - "@solana/web3.js": "^1.95.3", + "@solana/web3.js": "^1.95.5", "next": "15.0.4", "react": "^19", "react-dom": "^19" diff --git a/examples/node/esm/package.json b/examples/node/esm/package.json index 70fcf649b5..700c76d8d5 100644 --- a/examples/node/esm/package.json +++ b/examples/node/esm/package.json @@ -18,7 +18,7 @@ }, "dependencies": { "@coral-xyz/anchor": "^0.30.0", - "@solana/web3.js": "^1.95.3", + "@solana/web3.js": "^1.95.5", "@lightprotocol/stateless.js": "workspace:*" } } diff --git a/js/compressed-token/package.json b/js/compressed-token/package.json index c39663e3d2..c483112f53 100644 --- a/js/compressed-token/package.json +++ b/js/compressed-token/package.json @@ -1,6 +1,6 @@ { "name": "@lightprotocol/compressed-token", - "version": "0.17.1", + "version": "0.17.2-alpha.0", "description": "JS client to interact with the compressed-token program", "sideEffects": false, "main": "dist/cjs/node/index.cjs", @@ -21,37 +21,6 @@ "files": [ "dist" ], - "scripts": { - "test": "pnpm test:e2e:all", - "test-all": "vitest run", - "test:unit:all": "EXCLUDE_E2E=true vitest run", - "test-all:verbose": "vitest run --reporter=verbose", - "test-validator": "./../../cli/test_bin/run test-validator --prover-run-mode rpc", - "test:e2e:create-mint": "pnpm test-validator && vitest run tests/e2e/create-mint.test.ts", - "test:e2e:create-token-pool": "pnpm test-validator && vitest run tests/e2e/create-token-pool.test.ts", - "test:e2e:mint-to": "pnpm test-validator && vitest run tests/e2e/mint-to.test.ts --reporter=verbose", - "test:e2e:approve-and-mint-to": "pnpm test-validator && vitest run tests/e2e/approve-and-mint-to.test.ts --reporter=verbose", - "test:e2e:merge-token-accounts": "pnpm test-validator && vitest run tests/e2e/merge-token-accounts.test.ts --reporter=verbose", - "test:e2e:transfer": "pnpm test-validator && vitest run tests/e2e/transfer.test.ts --reporter=verbose", - "test:e2e:compress": "pnpm test-validator && vitest run tests/e2e/compress.test.ts --reporter=verbose", - "test:e2e:compress-spl-token-account": "pnpm test-validator && vitest run tests/e2e/compress-spl-token-account.test.ts --reporter=verbose", - "test:e2e:decompress": "pnpm test-validator && vitest run tests/e2e/decompress.test.ts --reporter=verbose", - "test:e2e:rpc-token-interop": "pnpm test-validator && vitest run tests/e2e/rpc-token-interop.test.ts --reporter=verbose", - "test:e2e:custom-program-id": "vitest run tests/e2e/custom-program-id.test.ts --reporter=verbose", - "test:e2e:all": "pnpm test-validator && vitest run tests/e2e/create-mint.test.ts && vitest run tests/e2e/mint-to.test.ts && vitest run tests/e2e/transfer.test.ts && vitest run tests/e2e/compress.test.ts && vitest run tests/e2e/compress-spl-token-account.test.ts && vitest run tests/e2e/decompress.test.ts && vitest run tests/e2e/create-token-pool.test.ts && vitest run tests/e2e/approve-and-mint-to.test.ts && vitest run tests/e2e/rpc-token-interop.test.ts && vitest run tests/e2e/custom-program-id.test.ts", - "pull-idl": "../../scripts/push-compressed-token-idl.sh", - "build": "rimraf dist && pnpm pull-idl && pnpm build:bundle", - "build:bundle": "rollup -c", - "format": "prettier --write .", - "lint": "eslint ." - }, - "keywords": [ - "zk", - "compression", - "light", - "stateless", - "solana" - ], "maintainers": [ { "name": "Light Protocol Maintainers", @@ -60,14 +29,14 @@ ], "license": "Apache-2.0", "peerDependencies": { - "@lightprotocol/stateless.js": "workspace:*" + "@lightprotocol/stateless.js": "workspace:*", + "@solana/web3.js": ">=1.73.5", + "@solana/spl-token": ">=0.3.9" }, "dependencies": { - "@coral-xyz/anchor": "0.29.0", - "@solana/web3.js": "1.95.3", - "@solana/spl-token": "0.4.8", - "buffer": "6.0.3", - "tweetnacl": "1.0.3" + "@coral-xyz/borsh": "^0.29.0", + "bn.js": "^5.2.1", + "buffer": "6.0.3" }, "devDependencies": { "@esbuild-plugins/node-globals-polyfill": "^0.2.3", @@ -81,6 +50,9 @@ "@rollup/plugin-replace": "^5.0.7", "@rollup/plugin-terser": "^0.4.4", "@rollup/plugin-typescript": "^11.1.6", + "@solana/web3.js": "1.98.0", + "@solana/spl-token": "0.4.8", + "@types/bn.js": "^5.1.5", "@types/node": "^22.5.5", "@typescript-eslint/eslint-plugin": "^7.13.1", "@typescript-eslint/parser": "^7.13.1", @@ -103,6 +75,37 @@ "typescript": "^5.6.2", "vitest": "^2.1.1" }, + "scripts": { + "test": "pnpm test:e2e:all", + "test-all": "vitest run", + "test:unit:all": "EXCLUDE_E2E=true vitest run", + "test-all:verbose": "vitest run --reporter=verbose", + "test-validator": "./../../cli/test_bin/run test-validator --prover-run-mode rpc", + "test:e2e:create-mint": "pnpm test-validator && NODE_OPTIONS='--trace-deprecation' vitest run tests/e2e/create-mint.test.ts --reporter=verbose", + "test:e2e:layout": "vitest run tests/e2e/layout.test.ts --reporter=verbose", + "test:e2e:create-token-pool": "pnpm test-validator && vitest run tests/e2e/create-token-pool.test.ts", + "test:e2e:mint-to": "pnpm test-validator && vitest run tests/e2e/mint-to.test.ts --reporter=verbose", + "test:e2e:approve-and-mint-to": "pnpm test-validator && vitest run tests/e2e/approve-and-mint-to.test.ts --reporter=verbose", + "test:e2e:merge-token-accounts": "pnpm test-validator && vitest run tests/e2e/merge-token-accounts.test.ts --reporter=verbose", + "test:e2e:transfer": "pnpm test-validator && vitest run tests/e2e/transfer.test.ts --reporter=verbose", + "test:e2e:compress": "pnpm test-validator && vitest run tests/e2e/compress.test.ts --reporter=verbose", + "test:e2e:compress-spl-token-account": "pnpm test-validator && vitest run tests/e2e/compress-spl-token-account.test.ts --reporter=verbose", + "test:e2e:decompress": "pnpm test-validator && vitest run tests/e2e/decompress.test.ts --reporter=verbose", + "test:e2e:rpc-token-interop": "pnpm test-validator && vitest run tests/e2e/rpc-token-interop.test.ts --reporter=verbose", + "test:e2e:all": "pnpm test-validator && vitest run tests/e2e/create-mint.test.ts && vitest run tests/e2e/mint-to.test.ts && vitest run tests/e2e/transfer.test.ts && vitest run tests/e2e/compress.test.ts && vitest run tests/e2e/compress-spl-token-account.test.ts && vitest run tests/e2e/decompress.test.ts && vitest run tests/e2e/create-token-pool.test.ts && vitest run tests/e2e/approve-and-mint-to.test.ts && vitest run tests/e2e/rpc-token-interop.test.ts", + "pull-idl": "../../scripts/push-compressed-token-idl.sh", + "build": "rimraf dist && pnpm build:bundle", + "build:bundle": "rollup -c", + "format": "prettier --write .", + "lint": "eslint ." + }, + "keywords": [ + "zk", + "compression", + "light", + "stateless", + "solana" + ], "nx": { "targets": { "build": { diff --git a/js/compressed-token/rollup.config.js b/js/compressed-token/rollup.config.js index c363738fb1..4e32f1c568 100644 --- a/js/compressed-token/rollup.config.js +++ b/js/compressed-token/rollup.config.js @@ -5,6 +5,7 @@ import resolve from '@rollup/plugin-node-resolve'; import commonjs from '@rollup/plugin-commonjs'; import alias from '@rollup/plugin-alias'; import json from '@rollup/plugin-json'; +import terser from '@rollup/plugin-terser'; const rolls = (fmt, env) => ({ input: 'src/index.ts', @@ -16,10 +17,9 @@ const rolls = (fmt, env) => ({ }, external: [ '@solana/web3.js', - '@coral-xyz/anchor', '@solana/spl-token', + '@coral-xyz/borsh', '@lightprotocol/stateless.js', - 'tweetnacl', ], plugins: [ json(), @@ -45,6 +45,26 @@ const rolls = (fmt, env) => ({ ], }), env === 'browser' ? nodePolyfills() : undefined, + terser({ + compress: { + drop_console: true, + drop_debugger: true, + passes: 3, + pure_funcs: ['console.log', 'console.error', 'console.warn'], + booleans_as_integers: true, + keep_fargs: false, + keep_fnames: false, + keep_infinity: true, + reduce_funcs: true, + reduce_vars: true, + }, + mangle: { + toplevel: true, + }, + output: { + comments: false, + }, + }), ].filter(Boolean), onwarn(warning, warn) { if (warning.code !== 'CIRCULAR_DEPENDENCY') { diff --git a/js/compressed-token/src/actions/approve-and-mint-to.ts b/js/compressed-token/src/actions/approve-and-mint-to.ts index 316f79758c..0e3e1f03b3 100644 --- a/js/compressed-token/src/actions/approve-and-mint-to.ts +++ b/js/compressed-token/src/actions/approve-and-mint-to.ts @@ -5,7 +5,7 @@ import { Signer, TransactionSignature, } from '@solana/web3.js'; -import { BN } from '@coral-xyz/anchor'; +import BN from 'bn.js'; import { sendAndConfirmTx, buildAndSignTx, diff --git a/js/compressed-token/src/actions/compress-spl-token-account.ts b/js/compressed-token/src/actions/compress-spl-token-account.ts index b50f09f6f8..b0713cf924 100644 --- a/js/compressed-token/src/actions/compress-spl-token-account.ts +++ b/js/compressed-token/src/actions/compress-spl-token-account.ts @@ -12,7 +12,7 @@ import { dedupeSigner, } from '@lightprotocol/stateless.js'; -import { BN } from '@coral-xyz/anchor'; +import BN from 'bn.js'; import { CompressedTokenProgram } from '../program'; diff --git a/js/compressed-token/src/actions/compress.ts b/js/compressed-token/src/actions/compress.ts index b99ffae64f..cd43e896ac 100644 --- a/js/compressed-token/src/actions/compress.ts +++ b/js/compressed-token/src/actions/compress.ts @@ -12,7 +12,7 @@ import { dedupeSigner, } from '@lightprotocol/stateless.js'; -import { BN } from '@coral-xyz/anchor'; +import BN from 'bn.js'; import { CompressedTokenProgram } from '../program'; diff --git a/js/compressed-token/src/actions/decompress.ts b/js/compressed-token/src/actions/decompress.ts index 45027d388c..8734491800 100644 --- a/js/compressed-token/src/actions/decompress.ts +++ b/js/compressed-token/src/actions/decompress.ts @@ -13,7 +13,7 @@ import { dedupeSigner, } from '@lightprotocol/stateless.js'; -import { BN } from '@coral-xyz/anchor'; +import BN from 'bn.js'; import { CompressedTokenProgram } from '../program'; import { selectMinCompressedTokenAccountsForTransfer } from './transfer'; diff --git a/js/compressed-token/src/actions/mint-to.ts b/js/compressed-token/src/actions/mint-to.ts index f4addc3279..fd4b0c3d59 100644 --- a/js/compressed-token/src/actions/mint-to.ts +++ b/js/compressed-token/src/actions/mint-to.ts @@ -5,7 +5,7 @@ import { Signer, TransactionSignature, } from '@solana/web3.js'; -import { BN } from '@coral-xyz/anchor'; +import BN from 'bn.js'; import { sendAndConfirmTx, buildAndSignTx, diff --git a/js/compressed-token/src/actions/transfer.ts b/js/compressed-token/src/actions/transfer.ts index a70e92eb06..d38f6deff8 100644 --- a/js/compressed-token/src/actions/transfer.ts +++ b/js/compressed-token/src/actions/transfer.ts @@ -14,7 +14,7 @@ import { dedupeSigner, } from '@lightprotocol/stateless.js'; -import { BN } from '@coral-xyz/anchor'; +import BN from 'bn.js'; import { CompressedTokenProgram } from '../program'; diff --git a/js/compressed-token/src/idl/index.ts b/js/compressed-token/src/idl/index.ts deleted file mode 100644 index fa14d6102c..0000000000 --- a/js/compressed-token/src/idl/index.ts +++ /dev/null @@ -1 +0,0 @@ -export * from './light_compressed_token'; diff --git a/js/compressed-token/src/idl/light_compressed_token.ts b/js/compressed-token/src/idl/light_compressed_token.ts deleted file mode 100644 index 3dc084e1b3..0000000000 --- a/js/compressed-token/src/idl/light_compressed_token.ts +++ /dev/null @@ -1,3481 +0,0 @@ -export type LightCompressedToken = { - version: '1.2.0'; - name: 'light_compressed_token'; - instructions: [ - { - name: 'createTokenPool'; - docs: [ - 'This instruction creates a token pool for a given mint. Every spl mint', - 'can have one token pool. When a token is compressed the tokens are', - 'transferrred to the token pool, and their compressed equivalent is', - 'minted into a Merkle tree.', - ]; - accounts: [ - { - name: 'feePayer'; - isMut: true; - isSigner: true; - docs: ['UNCHECKED: only pays fees.']; - }, - { - name: 'tokenPoolPda'; - isMut: true; - isSigner: false; - }, - { - name: 'systemProgram'; - isMut: false; - isSigner: false; - }, - { - name: 'mint'; - isMut: true; - isSigner: false; - }, - { - name: 'tokenProgram'; - isMut: false; - isSigner: false; - }, - { - name: 'cpiAuthorityPda'; - isMut: false; - isSigner: false; - }, - ]; - args: []; - }, - { - name: 'addTokenPool'; - docs: [ - 'This instruction creates an additional token pool for a given mint.', - 'The maximum number of token pools per mint is 5.', - ]; - accounts: [ - { - name: 'feePayer'; - isMut: true; - isSigner: true; - docs: ['UNCHECKED: only pays fees.']; - }, - { - name: 'tokenPoolPda'; - isMut: true; - isSigner: false; - }, - { - name: 'existingTokenPoolPda'; - isMut: false; - isSigner: false; - }, - { - name: 'systemProgram'; - isMut: false; - isSigner: false; - }, - { - name: 'mint'; - isMut: true; - isSigner: false; - }, - { - name: 'tokenProgram'; - isMut: false; - isSigner: false; - }, - { - name: 'cpiAuthorityPda'; - isMut: false; - isSigner: false; - }, - ]; - args: [ - { - name: 'tokenPoolBump'; - type: 'u8'; - }, - ]; - }, - { - name: 'mintTo'; - docs: [ - 'Mints tokens from an spl token mint to a list of compressed accounts.', - 'Minted tokens are transferred to a pool account owned by the compressed', - 'token program. The instruction creates one compressed output account for', - 'every amount and pubkey input pair. A constant amount of lamports can be', - 'transferred to each output account to enable. A use case to add lamports', - 'to a compressed token account is to prevent spam. This is the only way', - 'to add lamports to a compressed token account.', - ]; - accounts: [ - { - name: 'feePayer'; - isMut: true; - isSigner: true; - docs: ['UNCHECKED: only pays fees.']; - }, - { - name: 'authority'; - isMut: false; - isSigner: true; - }, - { - name: 'cpiAuthorityPda'; - isMut: false; - isSigner: false; - }, - { - name: 'mint'; - isMut: true; - isSigner: false; - }, - { - name: 'tokenPoolPda'; - isMut: true; - isSigner: false; - }, - { - name: 'tokenProgram'; - isMut: false; - isSigner: false; - }, - { - name: 'lightSystemProgram'; - isMut: false; - isSigner: false; - }, - { - name: 'registeredProgramPda'; - isMut: false; - isSigner: false; - }, - { - name: 'noopProgram'; - isMut: false; - isSigner: false; - docs: ['programs']; - }, - { - name: 'accountCompressionAuthority'; - isMut: false; - isSigner: false; - }, - { - name: 'accountCompressionProgram'; - isMut: false; - isSigner: false; - }, - { - name: 'merkleTree'; - isMut: true; - isSigner: false; - }, - { - name: 'selfProgram'; - isMut: false; - isSigner: false; - }, - { - name: 'systemProgram'; - isMut: false; - isSigner: false; - }, - { - name: 'solPoolPda'; - isMut: true; - isSigner: false; - isOptional: true; - }, - ]; - args: [ - { - name: 'publicKeys'; - type: { - vec: 'publicKey'; - }; - }, - { - name: 'amounts'; - type: { - vec: 'u64'; - }; - }, - { - name: 'lamports'; - type: { - option: 'u64'; - }; - }, - ]; - }, - { - name: 'compressSplTokenAccount'; - docs: [ - 'Compresses the balance of an spl token account sub an optional remaining', - 'amount. This instruction does not close the spl token account. To close', - 'the account bundle a close spl account instruction in your transaction.', - ]; - accounts: [ - { - name: 'feePayer'; - isMut: true; - isSigner: true; - docs: ['UNCHECKED: only pays fees.']; - }, - { - name: 'authority'; - isMut: false; - isSigner: true; - docs: [ - 'Authority is verified through proof since both owner and delegate', - 'are included in the token data hash, which is a public input to the', - 'validity proof.', - ]; - }, - { - name: 'cpiAuthorityPda'; - isMut: false; - isSigner: false; - }, - { - name: 'lightSystemProgram'; - isMut: false; - isSigner: false; - }, - { - name: 'registeredProgramPda'; - isMut: false; - isSigner: false; - }, - { - name: 'noopProgram'; - isMut: false; - isSigner: false; - }, - { - name: 'accountCompressionAuthority'; - isMut: false; - isSigner: false; - }, - { - name: 'accountCompressionProgram'; - isMut: false; - isSigner: false; - }, - { - name: 'selfProgram'; - isMut: false; - isSigner: false; - docs: ['this program is the signer of the cpi.']; - }, - { - name: 'tokenPoolPda'; - isMut: true; - isSigner: false; - isOptional: true; - }, - { - name: 'compressOrDecompressTokenAccount'; - isMut: true; - isSigner: false; - isOptional: true; - }, - { - name: 'tokenProgram'; - isMut: false; - isSigner: false; - isOptional: true; - }, - { - name: 'systemProgram'; - isMut: false; - isSigner: false; - }, - ]; - args: [ - { - name: 'owner'; - type: 'publicKey'; - }, - { - name: 'remainingAmount'; - type: { - option: 'u64'; - }; - }, - { - name: 'cpiContext'; - type: { - option: { - defined: 'CompressedCpiContext'; - }; - }; - }, - ]; - }, - { - name: 'transfer'; - docs: [ - 'Transfers compressed tokens from one account to another. All accounts', - 'must be of the same mint. Additional spl tokens can be compressed or', - 'decompressed. In one transaction only compression or decompression is', - 'possible. Lamports can be transferred alongside tokens. If output token', - 'accounts specify less lamports than inputs the remaining lamports are', - 'transferred to an output compressed account. Signer must be owner or', - 'delegate. If a delegated token account is transferred the delegate is', - 'not preserved.', - ]; - accounts: [ - { - name: 'feePayer'; - isMut: true; - isSigner: true; - docs: ['UNCHECKED: only pays fees.']; - }, - { - name: 'authority'; - isMut: false; - isSigner: true; - docs: [ - 'Authority is verified through proof since both owner and delegate', - 'are included in the token data hash, which is a public input to the', - 'validity proof.', - ]; - }, - { - name: 'cpiAuthorityPda'; - isMut: false; - isSigner: false; - }, - { - name: 'lightSystemProgram'; - isMut: false; - isSigner: false; - }, - { - name: 'registeredProgramPda'; - isMut: false; - isSigner: false; - }, - { - name: 'noopProgram'; - isMut: false; - isSigner: false; - }, - { - name: 'accountCompressionAuthority'; - isMut: false; - isSigner: false; - }, - { - name: 'accountCompressionProgram'; - isMut: false; - isSigner: false; - }, - { - name: 'selfProgram'; - isMut: false; - isSigner: false; - docs: ['this program is the signer of the cpi.']; - }, - { - name: 'tokenPoolPda'; - isMut: true; - isSigner: false; - isOptional: true; - }, - { - name: 'compressOrDecompressTokenAccount'; - isMut: true; - isSigner: false; - isOptional: true; - }, - { - name: 'tokenProgram'; - isMut: false; - isSigner: false; - isOptional: true; - }, - { - name: 'systemProgram'; - isMut: false; - isSigner: false; - }, - ]; - args: [ - { - name: 'inputs'; - type: 'bytes'; - }, - ]; - }, - { - name: 'approve'; - docs: [ - 'Delegates an amount to a delegate. A compressed token account is either', - 'completely delegated or not. Prior delegates are not preserved. Cannot', - 'be called by a delegate.', - 'The instruction creates two output accounts:', - '1. one account with delegated amount', - '2. one account with remaining(change) amount', - ]; - accounts: [ - { - name: 'feePayer'; - isMut: true; - isSigner: true; - docs: ['UNCHECKED: only pays fees.']; - }, - { - name: 'authority'; - isMut: false; - isSigner: true; - docs: [ - 'Authority is verified through proof since both owner and delegate', - 'are included in the token data hash, which is a public input to the', - 'validity proof.', - ]; - }, - { - name: 'cpiAuthorityPda'; - isMut: false; - isSigner: false; - }, - { - name: 'lightSystemProgram'; - isMut: false; - isSigner: false; - }, - { - name: 'registeredProgramPda'; - isMut: false; - isSigner: false; - }, - { - name: 'noopProgram'; - isMut: false; - isSigner: false; - }, - { - name: 'accountCompressionAuthority'; - isMut: false; - isSigner: false; - }, - { - name: 'accountCompressionProgram'; - isMut: false; - isSigner: false; - }, - { - name: 'selfProgram'; - isMut: false; - isSigner: false; - docs: ['this program is the signer of the cpi.']; - }, - { - name: 'systemProgram'; - isMut: false; - isSigner: false; - }, - ]; - args: [ - { - name: 'inputs'; - type: 'bytes'; - }, - ]; - }, - { - name: 'revoke'; - docs: [ - 'Revokes a delegation. The instruction merges all inputs into one output', - 'account. Cannot be called by a delegate. Delegates are not preserved.', - ]; - accounts: [ - { - name: 'feePayer'; - isMut: true; - isSigner: true; - docs: ['UNCHECKED: only pays fees.']; - }, - { - name: 'authority'; - isMut: false; - isSigner: true; - docs: [ - 'Authority is verified through proof since both owner and delegate', - 'are included in the token data hash, which is a public input to the', - 'validity proof.', - ]; - }, - { - name: 'cpiAuthorityPda'; - isMut: false; - isSigner: false; - }, - { - name: 'lightSystemProgram'; - isMut: false; - isSigner: false; - }, - { - name: 'registeredProgramPda'; - isMut: false; - isSigner: false; - }, - { - name: 'noopProgram'; - isMut: false; - isSigner: false; - }, - { - name: 'accountCompressionAuthority'; - isMut: false; - isSigner: false; - }, - { - name: 'accountCompressionProgram'; - isMut: false; - isSigner: false; - }, - { - name: 'selfProgram'; - isMut: false; - isSigner: false; - docs: ['this program is the signer of the cpi.']; - }, - { - name: 'systemProgram'; - isMut: false; - isSigner: false; - }, - ]; - args: [ - { - name: 'inputs'; - type: 'bytes'; - }, - ]; - }, - { - name: 'freeze'; - docs: [ - 'Freezes compressed token accounts. Inputs must not be frozen. Creates as', - 'many outputs as inputs. Balances and delegates are preserved.', - ]; - accounts: [ - { - name: 'feePayer'; - isMut: true; - isSigner: true; - docs: ['UNCHECKED: only pays fees.']; - }, - { - name: 'authority'; - isMut: false; - isSigner: true; - }, - { - name: 'cpiAuthorityPda'; - isMut: false; - isSigner: false; - }, - { - name: 'lightSystemProgram'; - isMut: false; - isSigner: false; - }, - { - name: 'registeredProgramPda'; - isMut: false; - isSigner: false; - }, - { - name: 'noopProgram'; - isMut: false; - isSigner: false; - }, - { - name: 'accountCompressionAuthority'; - isMut: false; - isSigner: false; - }, - { - name: 'accountCompressionProgram'; - isMut: false; - isSigner: false; - }, - { - name: 'selfProgram'; - isMut: false; - isSigner: false; - docs: ['that this program is the signer of the cpi.']; - }, - { - name: 'systemProgram'; - isMut: false; - isSigner: false; - }, - { - name: 'mint'; - isMut: false; - isSigner: false; - }, - ]; - args: [ - { - name: 'inputs'; - type: 'bytes'; - }, - ]; - }, - { - name: 'thaw'; - docs: [ - 'Thaws frozen compressed token accounts. Inputs must be frozen. Creates', - 'as many outputs as inputs. Balances and delegates are preserved.', - ]; - accounts: [ - { - name: 'feePayer'; - isMut: true; - isSigner: true; - docs: ['UNCHECKED: only pays fees.']; - }, - { - name: 'authority'; - isMut: false; - isSigner: true; - }, - { - name: 'cpiAuthorityPda'; - isMut: false; - isSigner: false; - }, - { - name: 'lightSystemProgram'; - isMut: false; - isSigner: false; - }, - { - name: 'registeredProgramPda'; - isMut: false; - isSigner: false; - }, - { - name: 'noopProgram'; - isMut: false; - isSigner: false; - }, - { - name: 'accountCompressionAuthority'; - isMut: false; - isSigner: false; - }, - { - name: 'accountCompressionProgram'; - isMut: false; - isSigner: false; - }, - { - name: 'selfProgram'; - isMut: false; - isSigner: false; - docs: ['that this program is the signer of the cpi.']; - }, - { - name: 'systemProgram'; - isMut: false; - isSigner: false; - }, - { - name: 'mint'; - isMut: false; - isSigner: false; - }, - ]; - args: [ - { - name: 'inputs'; - type: 'bytes'; - }, - ]; - }, - { - name: 'burn'; - docs: [ - 'Burns compressed tokens and spl tokens from the pool account. Delegates', - 'can burn tokens. The output compressed token account remains delegated.', - 'Creates one output compressed token account.', - ]; - accounts: [ - { - name: 'feePayer'; - isMut: true; - isSigner: true; - docs: ['UNCHECKED: only pays fees.']; - }, - { - name: 'authority'; - isMut: false; - isSigner: true; - docs: [ - 'Authority is verified through proof since both owner and delegate', - 'are included in the token data hash, which is a public input to the', - 'validity proof.', - ]; - }, - { - name: 'cpiAuthorityPda'; - isMut: false; - isSigner: false; - }, - { - name: 'mint'; - isMut: true; - isSigner: false; - }, - { - name: 'tokenPoolPda'; - isMut: true; - isSigner: false; - }, - { - name: 'tokenProgram'; - isMut: false; - isSigner: false; - }, - { - name: 'lightSystemProgram'; - isMut: false; - isSigner: false; - }, - { - name: 'registeredProgramPda'; - isMut: false; - isSigner: false; - }, - { - name: 'noopProgram'; - isMut: false; - isSigner: false; - }, - { - name: 'accountCompressionAuthority'; - isMut: false; - isSigner: false; - }, - { - name: 'accountCompressionProgram'; - isMut: false; - isSigner: false; - }, - { - name: 'selfProgram'; - isMut: false; - isSigner: false; - }, - { - name: 'systemProgram'; - isMut: false; - isSigner: false; - }, - ]; - args: [ - { - name: 'inputs'; - type: 'bytes'; - }, - ]; - }, - { - name: 'stubIdlBuild'; - docs: [ - 'This function is a stub to allow Anchor to include the input types in', - 'the IDL. It should not be included in production builds nor be called in', - 'practice.', - ]; - accounts: [ - { - name: 'feePayer'; - isMut: true; - isSigner: true; - docs: ['UNCHECKED: only pays fees.']; - }, - { - name: 'authority'; - isMut: false; - isSigner: true; - docs: [ - 'Authority is verified through proof since both owner and delegate', - 'are included in the token data hash, which is a public input to the', - 'validity proof.', - ]; - }, - { - name: 'cpiAuthorityPda'; - isMut: false; - isSigner: false; - }, - { - name: 'lightSystemProgram'; - isMut: false; - isSigner: false; - }, - { - name: 'registeredProgramPda'; - isMut: false; - isSigner: false; - }, - { - name: 'noopProgram'; - isMut: false; - isSigner: false; - }, - { - name: 'accountCompressionAuthority'; - isMut: false; - isSigner: false; - }, - { - name: 'accountCompressionProgram'; - isMut: false; - isSigner: false; - }, - { - name: 'selfProgram'; - isMut: false; - isSigner: false; - docs: ['this program is the signer of the cpi.']; - }, - { - name: 'tokenPoolPda'; - isMut: true; - isSigner: false; - isOptional: true; - }, - { - name: 'compressOrDecompressTokenAccount'; - isMut: true; - isSigner: false; - isOptional: true; - }, - { - name: 'tokenProgram'; - isMut: false; - isSigner: false; - isOptional: true; - }, - { - name: 'systemProgram'; - isMut: false; - isSigner: false; - }, - ]; - args: [ - { - name: 'inputs1'; - type: { - defined: 'CompressedTokenInstructionDataTransfer'; - }; - }, - { - name: 'inputs2'; - type: { - defined: 'TokenData'; - }; - }, - ]; - }, - ]; - types: [ - { - name: 'AccountState'; - type: { - kind: 'enum'; - variants: [ - { - name: 'Initialized'; - }, - { - name: 'Frozen'; - }, - ]; - }; - }, - { - name: 'CompressedAccount'; - type: { - kind: 'struct'; - fields: [ - { - name: 'owner'; - type: 'publicKey'; - }, - { - name: 'lamports'; - type: 'u64'; - }, - { - name: 'address'; - type: { - option: { - array: ['u8', 32]; - }; - }; - }, - { - name: 'data'; - type: { - option: { - defined: 'CompressedAccountData'; - }; - }; - }, - ]; - }; - }, - { - name: 'CompressedAccountData'; - type: { - kind: 'struct'; - fields: [ - { - name: 'discriminator'; - type: { - array: ['u8', 8]; - }; - }, - { - name: 'data'; - type: 'bytes'; - }, - { - name: 'dataHash'; - type: { - array: ['u8', 32]; - }; - }, - ]; - }; - }, - { - name: 'CompressedCpiContext'; - type: { - kind: 'struct'; - fields: [ - { - name: 'setContext'; - docs: [ - 'Is set by the program that is invoking the CPI to signal that is should', - 'set the cpi context.', - ]; - type: 'bool'; - }, - { - name: 'firstSetContext'; - docs: [ - 'Is set to wipe the cpi context since someone could have set it before', - 'with unrelated data.', - ]; - type: 'bool'; - }, - { - name: 'cpiContextAccountIndex'; - docs: [ - 'Index of cpi context account in remaining accounts.', - ]; - type: 'u8'; - }, - ]; - }; - }, - { - name: 'CompressedProof'; - type: { - kind: 'struct'; - fields: [ - { - name: 'a'; - type: { - array: ['u8', 32]; - }; - }, - { - name: 'b'; - type: { - array: ['u8', 64]; - }; - }, - { - name: 'c'; - type: { - array: ['u8', 32]; - }; - }, - ]; - }; - }, - { - name: 'CompressedTokenInstructionDataTransfer'; - type: { - kind: 'struct'; - fields: [ - { - name: 'proof'; - type: { - option: { - defined: 'CompressedProof'; - }; - }; - }, - { - name: 'mint'; - type: 'publicKey'; - }, - { - name: 'delegatedTransfer'; - docs: [ - 'Is required if the signer is delegate,', - '-> delegate is authority account,', - 'owner = Some(owner) is the owner of the token account.', - ]; - type: { - option: { - defined: 'DelegatedTransfer'; - }; - }; - }, - { - name: 'inputTokenDataWithContext'; - type: { - vec: { - defined: 'InputTokenDataWithContext'; - }; - }; - }, - { - name: 'outputCompressedAccounts'; - type: { - vec: { - defined: 'PackedTokenTransferOutputData'; - }; - }; - }, - { - name: 'isCompress'; - type: 'bool'; - }, - { - name: 'compressOrDecompressAmount'; - type: { - option: 'u64'; - }; - }, - { - name: 'cpiContext'; - type: { - option: { - defined: 'CompressedCpiContext'; - }; - }; - }, - { - name: 'lamportsChangeAccountMerkleTreeIndex'; - type: { - option: 'u8'; - }; - }, - ]; - }; - }, - { - name: 'DelegatedTransfer'; - docs: [ - 'Struct to provide the owner when the delegate is signer of the transaction.', - ]; - type: { - kind: 'struct'; - fields: [ - { - name: 'owner'; - type: 'publicKey'; - }, - { - name: 'delegateChangeAccountIndex'; - docs: [ - 'Index of change compressed account in output compressed accounts. In', - "case that the delegate didn't spend the complete delegated compressed", - 'account balance the change compressed account will be delegated to her', - 'as well.', - ]; - type: { - option: 'u8'; - }; - }, - ]; - }; - }, - { - name: 'InputTokenDataWithContext'; - type: { - kind: 'struct'; - fields: [ - { - name: 'amount'; - type: 'u64'; - }, - { - name: 'delegateIndex'; - type: { - option: 'u8'; - }; - }, - { - name: 'merkleContext'; - type: { - defined: 'PackedMerkleContext'; - }; - }, - { - name: 'rootIndex'; - type: 'u16'; - }, - { - name: 'lamports'; - type: { - option: 'u64'; - }; - }, - { - name: 'tlv'; - docs: [ - 'Placeholder for TokenExtension tlv data (unimplemented)', - ]; - type: { - option: 'bytes'; - }; - }, - ]; - }; - }, - { - name: 'InstructionDataInvoke'; - type: { - kind: 'struct'; - fields: [ - { - name: 'proof'; - type: { - option: { - defined: 'CompressedProof'; - }; - }; - }, - { - name: 'inputCompressedAccountsWithMerkleContext'; - type: { - vec: { - defined: 'PackedCompressedAccountWithMerkleContext'; - }; - }; - }, - { - name: 'outputCompressedAccounts'; - type: { - vec: { - defined: 'OutputCompressedAccountWithPackedContext'; - }; - }; - }, - { - name: 'relayFee'; - type: { - option: 'u64'; - }; - }, - { - name: 'newAddressParams'; - type: { - vec: { - defined: 'NewAddressParamsPacked'; - }; - }; - }, - { - name: 'compressOrDecompressLamports'; - type: { - option: 'u64'; - }; - }, - { - name: 'isCompress'; - type: 'bool'; - }, - ]; - }; - }, - { - name: 'InstructionDataInvokeCpi'; - type: { - kind: 'struct'; - fields: [ - { - name: 'proof'; - type: { - option: { - defined: 'CompressedProof'; - }; - }; - }, - { - name: 'newAddressParams'; - type: { - vec: { - defined: 'NewAddressParamsPacked'; - }; - }; - }, - { - name: 'inputCompressedAccountsWithMerkleContext'; - type: { - vec: { - defined: 'PackedCompressedAccountWithMerkleContext'; - }; - }; - }, - { - name: 'outputCompressedAccounts'; - type: { - vec: { - defined: 'OutputCompressedAccountWithPackedContext'; - }; - }; - }, - { - name: 'relayFee'; - type: { - option: 'u64'; - }; - }, - { - name: 'compressOrDecompressLamports'; - type: { - option: 'u64'; - }; - }, - { - name: 'isCompress'; - type: 'bool'; - }, - { - name: 'cpiContext'; - type: { - option: { - defined: 'CompressedCpiContext'; - }; - }; - }, - ]; - }; - }, - { - name: 'MerkleTreeSequenceNumber'; - type: { - kind: 'struct'; - fields: [ - { - name: 'pubkey'; - type: 'publicKey'; - }, - { - name: 'seq'; - type: 'u64'; - }, - ]; - }; - }, - { - name: 'NewAddressParamsPacked'; - type: { - kind: 'struct'; - fields: [ - { - name: 'seed'; - type: { - array: ['u8', 32]; - }; - }, - { - name: 'addressQueueAccountIndex'; - type: 'u8'; - }, - { - name: 'addressMerkleTreeAccountIndex'; - type: 'u8'; - }, - { - name: 'addressMerkleTreeRootIndex'; - type: 'u16'; - }, - ]; - }; - }, - { - name: 'OutputCompressedAccountWithPackedContext'; - type: { - kind: 'struct'; - fields: [ - { - name: 'compressedAccount'; - type: { - defined: 'CompressedAccount'; - }; - }, - { - name: 'merkleTreeIndex'; - type: 'u8'; - }, - ]; - }; - }, - { - name: 'PackedCompressedAccountWithMerkleContext'; - type: { - kind: 'struct'; - fields: [ - { - name: 'compressedAccount'; - type: { - defined: 'CompressedAccount'; - }; - }, - { - name: 'merkleContext'; - type: { - defined: 'PackedMerkleContext'; - }; - }, - { - name: 'rootIndex'; - docs: [ - 'Index of root used in inclusion validity proof.', - ]; - type: 'u16'; - }, - { - name: 'readOnly'; - docs: [ - 'Placeholder to mark accounts read-only unimplemented set to false.', - ]; - type: 'bool'; - }, - ]; - }; - }, - { - name: 'PackedMerkleContext'; - type: { - kind: 'struct'; - fields: [ - { - name: 'merkleTreePubkeyIndex'; - type: 'u8'; - }, - { - name: 'nullifierQueuePubkeyIndex'; - type: 'u8'; - }, - { - name: 'leafIndex'; - type: 'u32'; - }, - { - name: 'queueIndex'; - type: { - option: { - defined: 'QueueIndex'; - }; - }; - }, - ]; - }; - }, - { - name: 'PackedTokenTransferOutputData'; - type: { - kind: 'struct'; - fields: [ - { - name: 'owner'; - type: 'publicKey'; - }, - { - name: 'amount'; - type: 'u64'; - }, - { - name: 'lamports'; - type: { - option: 'u64'; - }; - }, - { - name: 'merkleTreeIndex'; - type: 'u8'; - }, - { - name: 'tlv'; - docs: [ - 'Placeholder for TokenExtension tlv data (unimplemented)', - ]; - type: { - option: 'bytes'; - }; - }, - ]; - }; - }, - { - name: 'PublicTransactionEvent'; - type: { - kind: 'struct'; - fields: [ - { - name: 'inputCompressedAccountHashes'; - type: { - vec: { - array: ['u8', 32]; - }; - }; - }, - { - name: 'outputCompressedAccountHashes'; - type: { - vec: { - array: ['u8', 32]; - }; - }; - }, - { - name: 'outputCompressedAccounts'; - type: { - vec: { - defined: 'OutputCompressedAccountWithPackedContext'; - }; - }; - }, - { - name: 'outputLeafIndices'; - type: { - vec: 'u32'; - }; - }, - { - name: 'sequenceNumbers'; - type: { - vec: { - defined: 'MerkleTreeSequenceNumber'; - }; - }; - }, - { - name: 'relayFee'; - type: { - option: 'u64'; - }; - }, - { - name: 'isCompress'; - type: 'bool'; - }, - { - name: 'compressOrDecompressLamports'; - type: { - option: 'u64'; - }; - }, - { - name: 'pubkeyArray'; - type: { - vec: 'publicKey'; - }; - }, - { - name: 'message'; - type: { - option: 'bytes'; - }; - }, - ]; - }; - }, - { - name: 'QueueIndex'; - type: { - kind: 'struct'; - fields: [ - { - name: 'queueId'; - docs: ['Id of queue in queue account.']; - type: 'u8'; - }, - { - name: 'index'; - docs: ['Index of compressed account hash in queue.']; - type: 'u16'; - }, - ]; - }; - }, - { - name: 'TokenData'; - type: { - kind: 'struct'; - fields: [ - { - name: 'mint'; - docs: ['The mint associated with this account']; - type: 'publicKey'; - }, - { - name: 'owner'; - docs: ['The owner of this account.']; - type: 'publicKey'; - }, - { - name: 'amount'; - docs: ['The amount of tokens this account holds.']; - type: 'u64'; - }, - { - name: 'delegate'; - docs: [ - 'If `delegate` is `Some` then `delegated_amount` represents', - 'the amount authorized by the delegate', - ]; - type: { - option: 'publicKey'; - }; - }, - { - name: 'state'; - docs: ["The account's state"]; - type: { - defined: 'AccountState'; - }; - }, - { - name: 'tlv'; - docs: [ - 'Placeholder for TokenExtension tlv data (unimplemented)', - ]; - type: { - option: 'bytes'; - }; - }, - ]; - }; - }, - ]; - errors: [ - { - code: 6000; - name: 'PublicKeyAmountMissmatch'; - msg: 'public keys and amounts must be of same length'; - }, - { - code: 6001; - name: 'ComputeInputSumFailed'; - msg: 'ComputeInputSumFailed'; - }, - { - code: 6002; - name: 'ComputeOutputSumFailed'; - msg: 'ComputeOutputSumFailed'; - }, - { - code: 6003; - name: 'ComputeCompressSumFailed'; - msg: 'ComputeCompressSumFailed'; - }, - { - code: 6004; - name: 'ComputeDecompressSumFailed'; - msg: 'ComputeDecompressSumFailed'; - }, - { - code: 6005; - name: 'SumCheckFailed'; - msg: 'SumCheckFailed'; - }, - { - code: 6006; - name: 'DecompressRecipientUndefinedForDecompress'; - msg: 'DecompressRecipientUndefinedForDecompress'; - }, - { - code: 6007; - name: 'CompressedPdaUndefinedForDecompress'; - msg: 'CompressedPdaUndefinedForDecompress'; - }, - { - code: 6008; - name: 'DeCompressAmountUndefinedForDecompress'; - msg: 'DeCompressAmountUndefinedForDecompress'; - }, - { - code: 6009; - name: 'CompressedPdaUndefinedForCompress'; - msg: 'CompressedPdaUndefinedForCompress'; - }, - { - code: 6010; - name: 'DeCompressAmountUndefinedForCompress'; - msg: 'DeCompressAmountUndefinedForCompress'; - }, - { - code: 6011; - name: 'DelegateSignerCheckFailed'; - msg: 'DelegateSignerCheckFailed'; - }, - { - code: 6012; - name: 'MintTooLarge'; - msg: 'Minted amount greater than u64::MAX'; - }, - { - code: 6013; - name: 'SplTokenSupplyMismatch'; - msg: 'SplTokenSupplyMismatch'; - }, - { - code: 6014; - name: 'HeapMemoryCheckFailed'; - msg: 'HeapMemoryCheckFailed'; - }, - { - code: 6015; - name: 'InstructionNotCallable'; - msg: 'The instruction is not callable'; - }, - { - code: 6016; - name: 'ArithmeticUnderflow'; - msg: 'ArithmeticUnderflow'; - }, - { - code: 6017; - name: 'HashToFieldError'; - msg: 'HashToFieldError'; - }, - { - code: 6018; - name: 'InvalidAuthorityMint'; - msg: 'Expected the authority to be also a mint authority'; - }, - { - code: 6019; - name: 'InvalidFreezeAuthority'; - msg: 'Provided authority is not the freeze authority'; - }, - { - code: 6020; - name: 'InvalidDelegateIndex'; - }, - { - code: 6021; - name: 'TokenPoolPdaUndefined'; - }, - { - code: 6022; - name: 'IsTokenPoolPda'; - msg: 'Compress or decompress recipient is the same account as the token pool pda.'; - }, - { - code: 6023; - name: 'InvalidTokenPoolPda'; - }, - { - code: 6024; - name: 'NoInputTokenAccountsProvided'; - }, - { - code: 6025; - name: 'NoInputsProvided'; - }, - { - code: 6026; - name: 'MintHasNoFreezeAuthority'; - }, - { - code: 6027; - name: 'MintWithInvalidExtension'; - }, - { - code: 6028; - name: 'InsufficientTokenAccountBalance'; - msg: 'The token account balance is less than the remaining amount.'; - }, - { - code: 6029; - name: 'InvalidTokenPoolBump'; - msg: 'Max number of token pools reached.'; - }, - { - code: 6030; - name: 'FailedToDecompress'; - }, - { - code: 6031; - name: 'FailedToBurnSplTokensFromTokenPool'; - }, - { - code: 6032; - name: 'NoMatchingBumpFound'; - }, - ]; -}; -export const IDL: LightCompressedToken = { - version: '1.2.0', - name: 'light_compressed_token', - instructions: [ - { - name: 'createTokenPool', - docs: [ - 'This instruction creates a token pool for a given mint. Every spl mint', - 'can have one token pool. When a token is compressed the tokens are', - 'transferrred to the token pool, and their compressed equivalent is', - 'minted into a Merkle tree.', - ], - accounts: [ - { - name: 'feePayer', - isMut: true, - isSigner: true, - docs: ['UNCHECKED: only pays fees.'], - }, - { - name: 'tokenPoolPda', - isMut: true, - isSigner: false, - }, - { - name: 'systemProgram', - isMut: false, - isSigner: false, - }, - { - name: 'mint', - isMut: true, - isSigner: false, - }, - { - name: 'tokenProgram', - isMut: false, - isSigner: false, - }, - { - name: 'cpiAuthorityPda', - isMut: false, - isSigner: false, - }, - ], - args: [], - }, - { - name: 'addTokenPool', - docs: [ - 'This instruction creates an additional token pool for a given mint.', - 'The maximum number of token pools per mint is 5.', - ], - accounts: [ - { - name: 'feePayer', - isMut: true, - isSigner: true, - docs: ['UNCHECKED: only pays fees.'], - }, - { - name: 'tokenPoolPda', - isMut: true, - isSigner: false, - }, - { - name: 'existingTokenPoolPda', - isMut: false, - isSigner: false, - }, - { - name: 'systemProgram', - isMut: false, - isSigner: false, - }, - { - name: 'mint', - isMut: true, - isSigner: false, - }, - { - name: 'tokenProgram', - isMut: false, - isSigner: false, - }, - { - name: 'cpiAuthorityPda', - isMut: false, - isSigner: false, - }, - ], - args: [ - { - name: 'tokenPoolBump', - type: 'u8', - }, - ], - }, - { - name: 'mintTo', - docs: [ - 'Mints tokens from an spl token mint to a list of compressed accounts.', - 'Minted tokens are transferred to a pool account owned by the compressed', - 'token program. The instruction creates one compressed output account for', - 'every amount and pubkey input pair. A constant amount of lamports can be', - 'transferred to each output account to enable. A use case to add lamports', - 'to a compressed token account is to prevent spam. This is the only way', - 'to add lamports to a compressed token account.', - ], - accounts: [ - { - name: 'feePayer', - isMut: true, - isSigner: true, - docs: ['UNCHECKED: only pays fees.'], - }, - { - name: 'authority', - isMut: false, - isSigner: true, - }, - { - name: 'cpiAuthorityPda', - isMut: false, - isSigner: false, - }, - { - name: 'mint', - isMut: true, - isSigner: false, - }, - { - name: 'tokenPoolPda', - isMut: true, - isSigner: false, - }, - { - name: 'tokenProgram', - isMut: false, - isSigner: false, - }, - { - name: 'lightSystemProgram', - isMut: false, - isSigner: false, - }, - { - name: 'registeredProgramPda', - isMut: false, - isSigner: false, - }, - { - name: 'noopProgram', - isMut: false, - isSigner: false, - docs: ['programs'], - }, - { - name: 'accountCompressionAuthority', - isMut: false, - isSigner: false, - }, - { - name: 'accountCompressionProgram', - isMut: false, - isSigner: false, - }, - { - name: 'merkleTree', - isMut: true, - isSigner: false, - }, - { - name: 'selfProgram', - isMut: false, - isSigner: false, - }, - { - name: 'systemProgram', - isMut: false, - isSigner: false, - }, - { - name: 'solPoolPda', - isMut: true, - isSigner: false, - isOptional: true, - }, - ], - args: [ - { - name: 'publicKeys', - type: { - vec: 'publicKey', - }, - }, - { - name: 'amounts', - type: { - vec: 'u64', - }, - }, - { - name: 'lamports', - type: { - option: 'u64', - }, - }, - ], - }, - { - name: 'compressSplTokenAccount', - docs: [ - 'Compresses the balance of an spl token account sub an optional remaining', - 'amount. This instruction does not close the spl token account. To close', - 'the account bundle a close spl account instruction in your transaction.', - ], - accounts: [ - { - name: 'feePayer', - isMut: true, - isSigner: true, - docs: ['UNCHECKED: only pays fees.'], - }, - { - name: 'authority', - isMut: false, - isSigner: true, - docs: [ - 'Authority is verified through proof since both owner and delegate', - 'are included in the token data hash, which is a public input to the', - 'validity proof.', - ], - }, - { - name: 'cpiAuthorityPda', - isMut: false, - isSigner: false, - }, - { - name: 'lightSystemProgram', - isMut: false, - isSigner: false, - }, - { - name: 'registeredProgramPda', - isMut: false, - isSigner: false, - }, - { - name: 'noopProgram', - isMut: false, - isSigner: false, - }, - { - name: 'accountCompressionAuthority', - isMut: false, - isSigner: false, - }, - { - name: 'accountCompressionProgram', - isMut: false, - isSigner: false, - }, - { - name: 'selfProgram', - isMut: false, - isSigner: false, - docs: ['this program is the signer of the cpi.'], - }, - { - name: 'tokenPoolPda', - isMut: true, - isSigner: false, - isOptional: true, - }, - { - name: 'compressOrDecompressTokenAccount', - isMut: true, - isSigner: false, - isOptional: true, - }, - { - name: 'tokenProgram', - isMut: false, - isSigner: false, - isOptional: true, - }, - { - name: 'systemProgram', - isMut: false, - isSigner: false, - }, - ], - args: [ - { - name: 'owner', - type: 'publicKey', - }, - { - name: 'remainingAmount', - type: { - option: 'u64', - }, - }, - { - name: 'cpiContext', - type: { - option: { - defined: 'CompressedCpiContext', - }, - }, - }, - ], - }, - { - name: 'transfer', - docs: [ - 'Transfers compressed tokens from one account to another. All accounts', - 'must be of the same mint. Additional spl tokens can be compressed or', - 'decompressed. In one transaction only compression or decompression is', - 'possible. Lamports can be transferred alongside tokens. If output token', - 'accounts specify less lamports than inputs the remaining lamports are', - 'transferred to an output compressed account. Signer must be owner or', - 'delegate. If a delegated token account is transferred the delegate is', - 'not preserved.', - ], - accounts: [ - { - name: 'feePayer', - isMut: true, - isSigner: true, - docs: ['UNCHECKED: only pays fees.'], - }, - { - name: 'authority', - isMut: false, - isSigner: true, - docs: [ - 'Authority is verified through proof since both owner and delegate', - 'are included in the token data hash, which is a public input to the', - 'validity proof.', - ], - }, - { - name: 'cpiAuthorityPda', - isMut: false, - isSigner: false, - }, - { - name: 'lightSystemProgram', - isMut: false, - isSigner: false, - }, - { - name: 'registeredProgramPda', - isMut: false, - isSigner: false, - }, - { - name: 'noopProgram', - isMut: false, - isSigner: false, - }, - { - name: 'accountCompressionAuthority', - isMut: false, - isSigner: false, - }, - { - name: 'accountCompressionProgram', - isMut: false, - isSigner: false, - }, - { - name: 'selfProgram', - isMut: false, - isSigner: false, - docs: ['this program is the signer of the cpi.'], - }, - { - name: 'tokenPoolPda', - isMut: true, - isSigner: false, - isOptional: true, - }, - { - name: 'compressOrDecompressTokenAccount', - isMut: true, - isSigner: false, - isOptional: true, - }, - { - name: 'tokenProgram', - isMut: false, - isSigner: false, - isOptional: true, - }, - { - name: 'systemProgram', - isMut: false, - isSigner: false, - }, - ], - args: [ - { - name: 'inputs', - type: 'bytes', - }, - ], - }, - { - name: 'approve', - docs: [ - 'Delegates an amount to a delegate. A compressed token account is either', - 'completely delegated or not. Prior delegates are not preserved. Cannot', - 'be called by a delegate.', - 'The instruction creates two output accounts:', - '1. one account with delegated amount', - '2. one account with remaining(change) amount', - ], - accounts: [ - { - name: 'feePayer', - isMut: true, - isSigner: true, - docs: ['UNCHECKED: only pays fees.'], - }, - { - name: 'authority', - isMut: false, - isSigner: true, - docs: [ - 'Authority is verified through proof since both owner and delegate', - 'are included in the token data hash, which is a public input to the', - 'validity proof.', - ], - }, - { - name: 'cpiAuthorityPda', - isMut: false, - isSigner: false, - }, - { - name: 'lightSystemProgram', - isMut: false, - isSigner: false, - }, - { - name: 'registeredProgramPda', - isMut: false, - isSigner: false, - }, - { - name: 'noopProgram', - isMut: false, - isSigner: false, - }, - { - name: 'accountCompressionAuthority', - isMut: false, - isSigner: false, - }, - { - name: 'accountCompressionProgram', - isMut: false, - isSigner: false, - }, - { - name: 'selfProgram', - isMut: false, - isSigner: false, - docs: ['this program is the signer of the cpi.'], - }, - { - name: 'systemProgram', - isMut: false, - isSigner: false, - }, - ], - args: [ - { - name: 'inputs', - type: 'bytes', - }, - ], - }, - { - name: 'revoke', - docs: [ - 'Revokes a delegation. The instruction merges all inputs into one output', - 'account. Cannot be called by a delegate. Delegates are not preserved.', - ], - accounts: [ - { - name: 'feePayer', - isMut: true, - isSigner: true, - docs: ['UNCHECKED: only pays fees.'], - }, - { - name: 'authority', - isMut: false, - isSigner: true, - docs: [ - 'Authority is verified through proof since both owner and delegate', - 'are included in the token data hash, which is a public input to the', - 'validity proof.', - ], - }, - { - name: 'cpiAuthorityPda', - isMut: false, - isSigner: false, - }, - { - name: 'lightSystemProgram', - isMut: false, - isSigner: false, - }, - { - name: 'registeredProgramPda', - isMut: false, - isSigner: false, - }, - { - name: 'noopProgram', - isMut: false, - isSigner: false, - }, - { - name: 'accountCompressionAuthority', - isMut: false, - isSigner: false, - }, - { - name: 'accountCompressionProgram', - isMut: false, - isSigner: false, - }, - { - name: 'selfProgram', - isMut: false, - isSigner: false, - docs: ['this program is the signer of the cpi.'], - }, - { - name: 'systemProgram', - isMut: false, - isSigner: false, - }, - ], - args: [ - { - name: 'inputs', - type: 'bytes', - }, - ], - }, - { - name: 'freeze', - docs: [ - 'Freezes compressed token accounts. Inputs must not be frozen. Creates as', - 'many outputs as inputs. Balances and delegates are preserved.', - ], - accounts: [ - { - name: 'feePayer', - isMut: true, - isSigner: true, - docs: ['UNCHECKED: only pays fees.'], - }, - { - name: 'authority', - isMut: false, - isSigner: true, - }, - { - name: 'cpiAuthorityPda', - isMut: false, - isSigner: false, - }, - { - name: 'lightSystemProgram', - isMut: false, - isSigner: false, - }, - { - name: 'registeredProgramPda', - isMut: false, - isSigner: false, - }, - { - name: 'noopProgram', - isMut: false, - isSigner: false, - }, - { - name: 'accountCompressionAuthority', - isMut: false, - isSigner: false, - }, - { - name: 'accountCompressionProgram', - isMut: false, - isSigner: false, - }, - { - name: 'selfProgram', - isMut: false, - isSigner: false, - docs: ['that this program is the signer of the cpi.'], - }, - { - name: 'systemProgram', - isMut: false, - isSigner: false, - }, - { - name: 'mint', - isMut: false, - isSigner: false, - }, - ], - args: [ - { - name: 'inputs', - type: 'bytes', - }, - ], - }, - { - name: 'thaw', - docs: [ - 'Thaws frozen compressed token accounts. Inputs must be frozen. Creates', - 'as many outputs as inputs. Balances and delegates are preserved.', - ], - accounts: [ - { - name: 'feePayer', - isMut: true, - isSigner: true, - docs: ['UNCHECKED: only pays fees.'], - }, - { - name: 'authority', - isMut: false, - isSigner: true, - }, - { - name: 'cpiAuthorityPda', - isMut: false, - isSigner: false, - }, - { - name: 'lightSystemProgram', - isMut: false, - isSigner: false, - }, - { - name: 'registeredProgramPda', - isMut: false, - isSigner: false, - }, - { - name: 'noopProgram', - isMut: false, - isSigner: false, - }, - { - name: 'accountCompressionAuthority', - isMut: false, - isSigner: false, - }, - { - name: 'accountCompressionProgram', - isMut: false, - isSigner: false, - }, - { - name: 'selfProgram', - isMut: false, - isSigner: false, - docs: ['that this program is the signer of the cpi.'], - }, - { - name: 'systemProgram', - isMut: false, - isSigner: false, - }, - { - name: 'mint', - isMut: false, - isSigner: false, - }, - ], - args: [ - { - name: 'inputs', - type: 'bytes', - }, - ], - }, - { - name: 'burn', - docs: [ - 'Burns compressed tokens and spl tokens from the pool account. Delegates', - 'can burn tokens. The output compressed token account remains delegated.', - 'Creates one output compressed token account.', - ], - accounts: [ - { - name: 'feePayer', - isMut: true, - isSigner: true, - docs: ['UNCHECKED: only pays fees.'], - }, - { - name: 'authority', - isMut: false, - isSigner: true, - docs: [ - 'Authority is verified through proof since both owner and delegate', - 'are included in the token data hash, which is a public input to the', - 'validity proof.', - ], - }, - { - name: 'cpiAuthorityPda', - isMut: false, - isSigner: false, - }, - { - name: 'mint', - isMut: true, - isSigner: false, - }, - { - name: 'tokenPoolPda', - isMut: true, - isSigner: false, - }, - { - name: 'tokenProgram', - isMut: false, - isSigner: false, - }, - { - name: 'lightSystemProgram', - isMut: false, - isSigner: false, - }, - { - name: 'registeredProgramPda', - isMut: false, - isSigner: false, - }, - { - name: 'noopProgram', - isMut: false, - isSigner: false, - }, - { - name: 'accountCompressionAuthority', - isMut: false, - isSigner: false, - }, - { - name: 'accountCompressionProgram', - isMut: false, - isSigner: false, - }, - { - name: 'selfProgram', - isMut: false, - isSigner: false, - }, - { - name: 'systemProgram', - isMut: false, - isSigner: false, - }, - ], - args: [ - { - name: 'inputs', - type: 'bytes', - }, - ], - }, - { - name: 'stubIdlBuild', - docs: [ - 'This function is a stub to allow Anchor to include the input types in', - 'the IDL. It should not be included in production builds nor be called in', - 'practice.', - ], - accounts: [ - { - name: 'feePayer', - isMut: true, - isSigner: true, - docs: ['UNCHECKED: only pays fees.'], - }, - { - name: 'authority', - isMut: false, - isSigner: true, - docs: [ - 'Authority is verified through proof since both owner and delegate', - 'are included in the token data hash, which is a public input to the', - 'validity proof.', - ], - }, - { - name: 'cpiAuthorityPda', - isMut: false, - isSigner: false, - }, - { - name: 'lightSystemProgram', - isMut: false, - isSigner: false, - }, - { - name: 'registeredProgramPda', - isMut: false, - isSigner: false, - }, - { - name: 'noopProgram', - isMut: false, - isSigner: false, - }, - { - name: 'accountCompressionAuthority', - isMut: false, - isSigner: false, - }, - { - name: 'accountCompressionProgram', - isMut: false, - isSigner: false, - }, - { - name: 'selfProgram', - isMut: false, - isSigner: false, - docs: ['this program is the signer of the cpi.'], - }, - { - name: 'tokenPoolPda', - isMut: true, - isSigner: false, - isOptional: true, - }, - { - name: 'compressOrDecompressTokenAccount', - isMut: true, - isSigner: false, - isOptional: true, - }, - { - name: 'tokenProgram', - isMut: false, - isSigner: false, - isOptional: true, - }, - { - name: 'systemProgram', - isMut: false, - isSigner: false, - }, - ], - args: [ - { - name: 'inputs1', - type: { - defined: 'CompressedTokenInstructionDataTransfer', - }, - }, - { - name: 'inputs2', - type: { - defined: 'TokenData', - }, - }, - ], - }, - ], - types: [ - { - name: 'AccountState', - type: { - kind: 'enum', - variants: [ - { - name: 'Initialized', - }, - { - name: 'Frozen', - }, - ], - }, - }, - { - name: 'CompressedAccount', - type: { - kind: 'struct', - fields: [ - { - name: 'owner', - type: 'publicKey', - }, - { - name: 'lamports', - type: 'u64', - }, - { - name: 'address', - type: { - option: { - array: ['u8', 32], - }, - }, - }, - { - name: 'data', - type: { - option: { - defined: 'CompressedAccountData', - }, - }, - }, - ], - }, - }, - { - name: 'CompressedAccountData', - type: { - kind: 'struct', - fields: [ - { - name: 'discriminator', - type: { - array: ['u8', 8], - }, - }, - { - name: 'data', - type: 'bytes', - }, - { - name: 'dataHash', - type: { - array: ['u8', 32], - }, - }, - ], - }, - }, - { - name: 'CompressedCpiContext', - type: { - kind: 'struct', - fields: [ - { - name: 'setContext', - docs: [ - 'Is set by the program that is invoking the CPI to signal that is should', - 'set the cpi context.', - ], - type: 'bool', - }, - { - name: 'firstSetContext', - docs: [ - 'Is set to wipe the cpi context since someone could have set it before', - 'with unrelated data.', - ], - type: 'bool', - }, - { - name: 'cpiContextAccountIndex', - docs: [ - 'Index of cpi context account in remaining accounts.', - ], - type: 'u8', - }, - ], - }, - }, - { - name: 'CompressedProof', - type: { - kind: 'struct', - fields: [ - { - name: 'a', - type: { - array: ['u8', 32], - }, - }, - { - name: 'b', - type: { - array: ['u8', 64], - }, - }, - { - name: 'c', - type: { - array: ['u8', 32], - }, - }, - ], - }, - }, - { - name: 'CompressedTokenInstructionDataTransfer', - type: { - kind: 'struct', - fields: [ - { - name: 'proof', - type: { - option: { - defined: 'CompressedProof', - }, - }, - }, - { - name: 'mint', - type: 'publicKey', - }, - { - name: 'delegatedTransfer', - docs: [ - 'Is required if the signer is delegate,', - '-> delegate is authority account,', - 'owner = Some(owner) is the owner of the token account.', - ], - type: { - option: { - defined: 'DelegatedTransfer', - }, - }, - }, - { - name: 'inputTokenDataWithContext', - type: { - vec: { - defined: 'InputTokenDataWithContext', - }, - }, - }, - { - name: 'outputCompressedAccounts', - type: { - vec: { - defined: 'PackedTokenTransferOutputData', - }, - }, - }, - { - name: 'isCompress', - type: 'bool', - }, - { - name: 'compressOrDecompressAmount', - type: { - option: 'u64', - }, - }, - { - name: 'cpiContext', - type: { - option: { - defined: 'CompressedCpiContext', - }, - }, - }, - { - name: 'lamportsChangeAccountMerkleTreeIndex', - type: { - option: 'u8', - }, - }, - ], - }, - }, - { - name: 'DelegatedTransfer', - docs: [ - 'Struct to provide the owner when the delegate is signer of the transaction.', - ], - type: { - kind: 'struct', - fields: [ - { - name: 'owner', - type: 'publicKey', - }, - { - name: 'delegateChangeAccountIndex', - docs: [ - 'Index of change compressed account in output compressed accounts. In', - "case that the delegate didn't spend the complete delegated compressed", - 'account balance the change compressed account will be delegated to her', - 'as well.', - ], - type: { - option: 'u8', - }, - }, - ], - }, - }, - { - name: 'InputTokenDataWithContext', - type: { - kind: 'struct', - fields: [ - { - name: 'amount', - type: 'u64', - }, - { - name: 'delegateIndex', - type: { - option: 'u8', - }, - }, - { - name: 'merkleContext', - type: { - defined: 'PackedMerkleContext', - }, - }, - { - name: 'rootIndex', - type: 'u16', - }, - { - name: 'lamports', - type: { - option: 'u64', - }, - }, - { - name: 'tlv', - docs: [ - 'Placeholder for TokenExtension tlv data (unimplemented)', - ], - type: { - option: 'bytes', - }, - }, - ], - }, - }, - { - name: 'InstructionDataInvoke', - type: { - kind: 'struct', - fields: [ - { - name: 'proof', - type: { - option: { - defined: 'CompressedProof', - }, - }, - }, - { - name: 'inputCompressedAccountsWithMerkleContext', - type: { - vec: { - defined: - 'PackedCompressedAccountWithMerkleContext', - }, - }, - }, - { - name: 'outputCompressedAccounts', - type: { - vec: { - defined: - 'OutputCompressedAccountWithPackedContext', - }, - }, - }, - { - name: 'relayFee', - type: { - option: 'u64', - }, - }, - { - name: 'newAddressParams', - type: { - vec: { - defined: 'NewAddressParamsPacked', - }, - }, - }, - { - name: 'compressOrDecompressLamports', - type: { - option: 'u64', - }, - }, - { - name: 'isCompress', - type: 'bool', - }, - ], - }, - }, - { - name: 'InstructionDataInvokeCpi', - type: { - kind: 'struct', - fields: [ - { - name: 'proof', - type: { - option: { - defined: 'CompressedProof', - }, - }, - }, - { - name: 'newAddressParams', - type: { - vec: { - defined: 'NewAddressParamsPacked', - }, - }, - }, - { - name: 'inputCompressedAccountsWithMerkleContext', - type: { - vec: { - defined: - 'PackedCompressedAccountWithMerkleContext', - }, - }, - }, - { - name: 'outputCompressedAccounts', - type: { - vec: { - defined: - 'OutputCompressedAccountWithPackedContext', - }, - }, - }, - { - name: 'relayFee', - type: { - option: 'u64', - }, - }, - { - name: 'compressOrDecompressLamports', - type: { - option: 'u64', - }, - }, - { - name: 'isCompress', - type: 'bool', - }, - { - name: 'cpiContext', - type: { - option: { - defined: 'CompressedCpiContext', - }, - }, - }, - ], - }, - }, - { - name: 'MerkleTreeSequenceNumber', - type: { - kind: 'struct', - fields: [ - { - name: 'pubkey', - type: 'publicKey', - }, - { - name: 'seq', - type: 'u64', - }, - ], - }, - }, - { - name: 'NewAddressParamsPacked', - type: { - kind: 'struct', - fields: [ - { - name: 'seed', - type: { - array: ['u8', 32], - }, - }, - { - name: 'addressQueueAccountIndex', - type: 'u8', - }, - { - name: 'addressMerkleTreeAccountIndex', - type: 'u8', - }, - { - name: 'addressMerkleTreeRootIndex', - type: 'u16', - }, - ], - }, - }, - { - name: 'OutputCompressedAccountWithPackedContext', - type: { - kind: 'struct', - fields: [ - { - name: 'compressedAccount', - type: { - defined: 'CompressedAccount', - }, - }, - { - name: 'merkleTreeIndex', - type: 'u8', - }, - ], - }, - }, - { - name: 'PackedCompressedAccountWithMerkleContext', - type: { - kind: 'struct', - fields: [ - { - name: 'compressedAccount', - type: { - defined: 'CompressedAccount', - }, - }, - { - name: 'merkleContext', - type: { - defined: 'PackedMerkleContext', - }, - }, - { - name: 'rootIndex', - docs: [ - 'Index of root used in inclusion validity proof.', - ], - type: 'u16', - }, - { - name: 'readOnly', - docs: [ - 'Placeholder to mark accounts read-only unimplemented set to false.', - ], - type: 'bool', - }, - ], - }, - }, - { - name: 'PackedMerkleContext', - type: { - kind: 'struct', - fields: [ - { - name: 'merkleTreePubkeyIndex', - type: 'u8', - }, - { - name: 'nullifierQueuePubkeyIndex', - type: 'u8', - }, - { - name: 'leafIndex', - type: 'u32', - }, - { - name: 'queueIndex', - type: { - option: { - defined: 'QueueIndex', - }, - }, - }, - ], - }, - }, - { - name: 'PackedTokenTransferOutputData', - type: { - kind: 'struct', - fields: [ - { - name: 'owner', - type: 'publicKey', - }, - { - name: 'amount', - type: 'u64', - }, - { - name: 'lamports', - type: { - option: 'u64', - }, - }, - { - name: 'merkleTreeIndex', - type: 'u8', - }, - { - name: 'tlv', - docs: [ - 'Placeholder for TokenExtension tlv data (unimplemented)', - ], - type: { - option: 'bytes', - }, - }, - ], - }, - }, - { - name: 'PublicTransactionEvent', - type: { - kind: 'struct', - fields: [ - { - name: 'inputCompressedAccountHashes', - type: { - vec: { - array: ['u8', 32], - }, - }, - }, - { - name: 'outputCompressedAccountHashes', - type: { - vec: { - array: ['u8', 32], - }, - }, - }, - { - name: 'outputCompressedAccounts', - type: { - vec: { - defined: - 'OutputCompressedAccountWithPackedContext', - }, - }, - }, - { - name: 'outputLeafIndices', - type: { - vec: 'u32', - }, - }, - { - name: 'sequenceNumbers', - type: { - vec: { - defined: 'MerkleTreeSequenceNumber', - }, - }, - }, - { - name: 'relayFee', - type: { - option: 'u64', - }, - }, - { - name: 'isCompress', - type: 'bool', - }, - { - name: 'compressOrDecompressLamports', - type: { - option: 'u64', - }, - }, - { - name: 'pubkeyArray', - type: { - vec: 'publicKey', - }, - }, - { - name: 'message', - type: { - option: 'bytes', - }, - }, - ], - }, - }, - { - name: 'QueueIndex', - type: { - kind: 'struct', - fields: [ - { - name: 'queueId', - docs: ['Id of queue in queue account.'], - type: 'u8', - }, - { - name: 'index', - docs: ['Index of compressed account hash in queue.'], - type: 'u16', - }, - ], - }, - }, - { - name: 'TokenData', - type: { - kind: 'struct', - fields: [ - { - name: 'mint', - docs: ['The mint associated with this account'], - type: 'publicKey', - }, - { - name: 'owner', - docs: ['The owner of this account.'], - type: 'publicKey', - }, - { - name: 'amount', - docs: ['The amount of tokens this account holds.'], - type: 'u64', - }, - { - name: 'delegate', - docs: [ - 'If `delegate` is `Some` then `delegated_amount` represents', - 'the amount authorized by the delegate', - ], - type: { - option: 'publicKey', - }, - }, - { - name: 'state', - docs: ["The account's state"], - type: { - defined: 'AccountState', - }, - }, - { - name: 'tlv', - docs: [ - 'Placeholder for TokenExtension tlv data (unimplemented)', - ], - type: { - option: 'bytes', - }, - }, - ], - }, - }, - ], - errors: [ - { - code: 6000, - name: 'PublicKeyAmountMissmatch', - msg: 'public keys and amounts must be of same length', - }, - { - code: 6001, - name: 'ComputeInputSumFailed', - msg: 'ComputeInputSumFailed', - }, - { - code: 6002, - name: 'ComputeOutputSumFailed', - msg: 'ComputeOutputSumFailed', - }, - { - code: 6003, - name: 'ComputeCompressSumFailed', - msg: 'ComputeCompressSumFailed', - }, - { - code: 6004, - name: 'ComputeDecompressSumFailed', - msg: 'ComputeDecompressSumFailed', - }, - { - code: 6005, - name: 'SumCheckFailed', - msg: 'SumCheckFailed', - }, - { - code: 6006, - name: 'DecompressRecipientUndefinedForDecompress', - msg: 'DecompressRecipientUndefinedForDecompress', - }, - { - code: 6007, - name: 'CompressedPdaUndefinedForDecompress', - msg: 'CompressedPdaUndefinedForDecompress', - }, - { - code: 6008, - name: 'DeCompressAmountUndefinedForDecompress', - msg: 'DeCompressAmountUndefinedForDecompress', - }, - { - code: 6009, - name: 'CompressedPdaUndefinedForCompress', - msg: 'CompressedPdaUndefinedForCompress', - }, - { - code: 6010, - name: 'DeCompressAmountUndefinedForCompress', - msg: 'DeCompressAmountUndefinedForCompress', - }, - { - code: 6011, - name: 'DelegateSignerCheckFailed', - msg: 'DelegateSignerCheckFailed', - }, - { - code: 6012, - name: 'MintTooLarge', - msg: 'Minted amount greater than u64::MAX', - }, - { - code: 6013, - name: 'SplTokenSupplyMismatch', - msg: 'SplTokenSupplyMismatch', - }, - { - code: 6014, - name: 'HeapMemoryCheckFailed', - msg: 'HeapMemoryCheckFailed', - }, - { - code: 6015, - name: 'InstructionNotCallable', - msg: 'The instruction is not callable', - }, - { - code: 6016, - name: 'ArithmeticUnderflow', - msg: 'ArithmeticUnderflow', - }, - { - code: 6017, - name: 'HashToFieldError', - msg: 'HashToFieldError', - }, - { - code: 6018, - name: 'InvalidAuthorityMint', - msg: 'Expected the authority to be also a mint authority', - }, - { - code: 6019, - name: 'InvalidFreezeAuthority', - msg: 'Provided authority is not the freeze authority', - }, - { - code: 6020, - name: 'InvalidDelegateIndex', - }, - { - code: 6021, - name: 'TokenPoolPdaUndefined', - }, - { - code: 6022, - name: 'IsTokenPoolPda', - msg: 'Compress or decompress recipient is the same account as the token pool pda.', - }, - { - code: 6023, - name: 'InvalidTokenPoolPda', - }, - { - code: 6024, - name: 'NoInputTokenAccountsProvided', - }, - { - code: 6025, - name: 'NoInputsProvided', - }, - { - code: 6026, - name: 'MintHasNoFreezeAuthority', - }, - { - code: 6027, - name: 'MintWithInvalidExtension', - }, - { - code: 6028, - name: 'InsufficientTokenAccountBalance', - msg: 'The token account balance is less than the remaining amount.', - }, - { - code: 6029, - name: 'InvalidTokenPoolBump', - msg: 'Max number of token pools reached.', - }, - { - code: 6030, - name: 'FailedToDecompress', - }, - { - code: 6031, - name: 'FailedToBurnSplTokensFromTokenPool', - }, - { - code: 6032, - name: 'NoMatchingBumpFound', - }, - ], -}; diff --git a/js/compressed-token/src/index.ts b/js/compressed-token/src/index.ts index 13ce6bee3c..a2fa8b6c6b 100644 --- a/js/compressed-token/src/index.ts +++ b/js/compressed-token/src/index.ts @@ -1,4 +1,3 @@ -export * from './idl'; export * from './instructions'; export * from './constants'; export * from './program'; diff --git a/js/compressed-token/src/instructions/pack-compressed-token-accounts.ts b/js/compressed-token/src/instructions/pack-compressed-token-accounts.ts index 5e6b279d11..2a15d388ab 100644 --- a/js/compressed-token/src/instructions/pack-compressed-token-accounts.ts +++ b/js/compressed-token/src/instructions/pack-compressed-token-accounts.ts @@ -4,10 +4,12 @@ import { getIndexOrAdd, bn, padOutputStateMerkleTrees, - TokenTransferOutputData, } from '@lightprotocol/stateless.js'; import { PublicKey, AccountMeta } from '@solana/web3.js'; -import { PackedTokenTransferOutputData } from '../types'; +import { + PackedTokenTransferOutputData, + TokenTransferOutputData, +} from '../types'; export type PackCompressedTokenAccountsParams = { /** Input state to be consumed */ diff --git a/js/compressed-token/src/layout.ts b/js/compressed-token/src/layout.ts new file mode 100644 index 0000000000..e3a890cb2b --- /dev/null +++ b/js/compressed-token/src/layout.ts @@ -0,0 +1,607 @@ +import { + struct, + option, + vec, + bool, + u64, + u8, + publicKey, + array, + u32, + u16, + vecU8, +} from '@coral-xyz/borsh'; +import { Buffer } from 'buffer'; + +import { AccountMeta, PublicKey } from '@solana/web3.js'; +import { CompressedTokenProgram } from './program'; +import BN from 'bn.js'; +import { + CompressedCpiContext, + CompressedTokenInstructionDataTransfer, +} from './types'; + +export const CREATE_TOKEN_POOL_DISCRIMINATOR = Buffer.from([ + 23, 169, 27, 122, 147, 169, 209, 152, +]); +const CompressedProofLayout = struct([ + array(u8(), 32, 'a'), + array(u8(), 64, 'b'), + array(u8(), 32, 'c'), +]); + +const PackedTokenTransferOutputDataLayout = struct([ + publicKey('owner'), + u64('amount'), + option(u64(), 'lamports'), + u8('merkleTreeIndex'), + option(vecU8(), 'tlv'), +]); + +const QueueIndexLayout = struct([u8('queueId'), u16('index')]); + +const InputTokenDataWithContextLayout = struct([ + u64('amount'), + option(u8(), 'delegateIndex'), + struct( + [ + u8('merkleTreePubkeyIndex'), + u8('nullifierQueuePubkeyIndex'), + u32('leafIndex'), + option(QueueIndexLayout, 'QueueIndex'), + ], + 'merkleContext', + ), + u16('rootIndex'), + option(u64(), 'lamports'), + option(vecU8(), 'tlv'), +]); + +export const DelegatedTransferLayout = struct([ + publicKey('owner'), + option(u8(), 'delegateChangeAccountIndex'), +]); + +export const CpiContextLayout = struct([ + bool('setContext'), + bool('firstSetContext'), + u8('cpiContextAccountIndex'), +]); + +export const CompressedTokenInstructionDataTransferLayout = struct([ + option(CompressedProofLayout, 'proof'), + publicKey('mint'), + option(DelegatedTransferLayout, 'delegatedTransfer'), + vec(InputTokenDataWithContextLayout, 'inputTokenDataWithContext'), + vec(PackedTokenTransferOutputDataLayout, 'outputCompressedAccounts'), + bool('isCompress'), + option(u64(), 'compressOrDecompressAmount'), + option(CpiContextLayout, 'cpiContext'), + option(u8(), 'lamportsChangeAccountMerkleTreeIndex'), +]); + +export const mintToLayout = struct([ + vec(publicKey(), 'recipients'), + vec(u64(), 'amounts'), + option(u64(), 'lamports'), +]); + +export const compressSplTokenAccountInstructionDataLayout = struct([ + publicKey('owner'), + option(u64(), 'remainingAmount'), + option(CpiContextLayout, 'cpiContext'), +]); + +const MINT_TO_DISCRIMINATOR = Buffer.from([ + 241, 34, 48, 186, 37, 179, 123, 192, +]); +export const TRANSFER_DISCRIMINATOR = Buffer.from([ + 163, 52, 200, 231, 140, 3, 69, 186, +]); +export function encodeMintToInstructionData( + recipients: PublicKey[], + amounts: BN[], + lamports: BN | null, +): Buffer { + const buffer = Buffer.alloc(1000); + const len = mintToLayout.encode( + { + recipients, + amounts, + lamports, + }, + buffer, + ); + return Buffer.concat([MINT_TO_DISCRIMINATOR, buffer.slice(0, len)]); +} + +export const COMPRESS_SPL_TOKEN_ACCOUNT_DISCRIMINATOR = Buffer.from([ + 112, 230, 105, 101, 145, 202, 157, 97, +]); + +export function encodeCompressSplTokenAccountInstructionData( + owner: PublicKey, + remainingAmount: BN | null, + cpiContext: CompressedCpiContext | null, +): Buffer { + const buffer = Buffer.alloc(1000); + const len = compressSplTokenAccountInstructionDataLayout.encode( + { + owner, + remainingAmount, + cpiContext, + }, + buffer, + ); + return Buffer.concat([ + COMPRESS_SPL_TOKEN_ACCOUNT_DISCRIMINATOR, + buffer.slice(0, len), + ]); +} + +export function encodeCompressedTokenInstructionDataTransfer( + data: CompressedTokenInstructionDataTransfer, +): Buffer { + const buffer = Buffer.alloc(1000); + + const len = CompressedTokenInstructionDataTransferLayout.encode( + data, + buffer, + ); + + const lengthBuffer = Buffer.alloc(4); + lengthBuffer.writeUInt32LE(len, 0); + + return Buffer.concat([ + TRANSFER_DISCRIMINATOR, + lengthBuffer, + buffer.slice(0, len), + ]); +} + +export type createTokenPoolAccountsLayoutParams = { + feePayer: PublicKey; + tokenPoolPda: PublicKey; + systemProgram: PublicKey; + mint: PublicKey; + tokenProgram: PublicKey; + cpiAuthorityPda: PublicKey; +}; + +export const createTokenPoolAccountsLayout = ( + accounts: createTokenPoolAccountsLayoutParams, +): AccountMeta[] => { + const { + feePayer, + tokenPoolPda, + systemProgram, + mint, + tokenProgram, + cpiAuthorityPda, + } = accounts; + + return [ + { pubkey: feePayer, isSigner: true, isWritable: true }, + { pubkey: tokenPoolPda, isSigner: false, isWritable: true }, + { pubkey: systemProgram, isSigner: false, isWritable: false }, + { pubkey: mint, isSigner: false, isWritable: true }, + { pubkey: tokenProgram, isSigner: false, isWritable: false }, + { pubkey: cpiAuthorityPda, isSigner: false, isWritable: false }, + ]; +}; + +export type mintToAccountsLayoutParams = { + feePayer: PublicKey; + authority: PublicKey; + cpiAuthorityPda: PublicKey; + mint: PublicKey; + tokenPoolPda: PublicKey; + tokenProgram: PublicKey; + lightSystemProgram: PublicKey; + registeredProgramPda: PublicKey; + noopProgram: PublicKey; + accountCompressionAuthority: PublicKey; + accountCompressionProgram: PublicKey; + merkleTree: PublicKey; + selfProgram: PublicKey; + systemProgram: PublicKey; + solPoolPda: PublicKey | null; +}; + +export const mintToAccountsLayout = ( + accounts: mintToAccountsLayoutParams, +): AccountMeta[] => { + const defaultPubkey = CompressedTokenProgram.programId; + const { + feePayer, + authority, + cpiAuthorityPda, + mint, + tokenPoolPda, + tokenProgram, + lightSystemProgram, + registeredProgramPda, + noopProgram, + accountCompressionAuthority, + accountCompressionProgram, + merkleTree, + selfProgram, + systemProgram, + solPoolPda, + } = accounts; + + const accountsList: AccountMeta[] = [ + { pubkey: feePayer, isSigner: true, isWritable: true }, + { pubkey: authority, isSigner: true, isWritable: false }, + { pubkey: cpiAuthorityPda, isSigner: false, isWritable: false }, + { pubkey: mint, isSigner: false, isWritable: true }, + { pubkey: tokenPoolPda, isSigner: false, isWritable: true }, + { pubkey: tokenProgram, isSigner: false, isWritable: false }, + { pubkey: lightSystemProgram, isSigner: false, isWritable: false }, + { pubkey: registeredProgramPda, isSigner: false, isWritable: false }, + { pubkey: noopProgram, isSigner: false, isWritable: false }, + { + pubkey: accountCompressionAuthority, + isSigner: false, + isWritable: false, + }, + { + pubkey: accountCompressionProgram, + isSigner: false, + isWritable: false, + }, + { pubkey: merkleTree, isSigner: false, isWritable: true }, + { pubkey: selfProgram, isSigner: false, isWritable: false }, + { pubkey: systemProgram, isSigner: false, isWritable: false }, + { + pubkey: solPoolPda ?? defaultPubkey, + isSigner: false, + isWritable: true, + }, + ]; + + return accountsList; +}; + +export type compressSplTokenAccountAccountsLayoutParams = { + feePayer: PublicKey; + authority: PublicKey; + cpiAuthorityPda: PublicKey; + lightSystemProgram: PublicKey; + registeredProgramPda: PublicKey; + noopProgram: PublicKey; + accountCompressionAuthority: PublicKey; + accountCompressionProgram: PublicKey; + selfProgram: PublicKey; + tokenPoolPda?: PublicKey; + compressOrDecompressTokenAccount?: PublicKey; + tokenProgram?: PublicKey; + systemProgram: PublicKey; +}; + +export const compressSplTokenAccountAccountsLayout = ( + accounts: compressSplTokenAccountAccountsLayoutParams, +): AccountMeta[] => { + const defaultPubkey = CompressedTokenProgram.programId; + const { + feePayer, + authority, + cpiAuthorityPda, + lightSystemProgram, + registeredProgramPda, + noopProgram, + accountCompressionAuthority, + accountCompressionProgram, + selfProgram, + tokenPoolPda, + compressOrDecompressTokenAccount, + tokenProgram, + systemProgram, + } = accounts; + + const accountsList: AccountMeta[] = [ + { pubkey: feePayer, isSigner: true, isWritable: true }, + { pubkey: authority, isSigner: true, isWritable: false }, + { pubkey: cpiAuthorityPda, isSigner: false, isWritable: false }, + { pubkey: lightSystemProgram, isSigner: false, isWritable: false }, + { pubkey: registeredProgramPda, isSigner: false, isWritable: false }, + { pubkey: noopProgram, isSigner: false, isWritable: false }, + { + pubkey: accountCompressionAuthority, + isSigner: false, + isWritable: false, + }, + { + pubkey: accountCompressionProgram, + isSigner: false, + isWritable: false, + }, + { pubkey: selfProgram, isSigner: false, isWritable: false }, + { + pubkey: tokenPoolPda ?? defaultPubkey, + isSigner: false, + isWritable: true, + }, + { + pubkey: compressOrDecompressTokenAccount ?? defaultPubkey, + isSigner: false, + isWritable: true, + }, + { + pubkey: tokenProgram ?? defaultPubkey, + isSigner: false, + isWritable: false, + }, + { pubkey: systemProgram, isSigner: false, isWritable: false }, + ]; + + return accountsList; +}; + +export const compressSplTokenAccountArgsLayout = struct( + [ + publicKey('owner'), + option(u64(), 'remainingAmount'), + option(struct([], 'CompressedCpiContext'), 'cpiContext'), + ], + 'compressSplTokenAccountArgs', +); + +export interface transferAccountsLayoutParams { + feePayer: PublicKey; + authority: PublicKey; + cpiAuthorityPda: PublicKey; + lightSystemProgram: PublicKey; + registeredProgramPda: PublicKey; + noopProgram: PublicKey; + accountCompressionAuthority: PublicKey; + accountCompressionProgram: PublicKey; + selfProgram: PublicKey; + tokenPoolPda?: PublicKey; + compressOrDecompressTokenAccount?: PublicKey; + tokenProgram?: PublicKey; + systemProgram: PublicKey; +} + +export const transferAccountsLayout = ( + accounts: transferAccountsLayoutParams, +): AccountMeta[] => { + const defaultPubkey = CompressedTokenProgram.programId; + const { + feePayer, + authority, + cpiAuthorityPda, + lightSystemProgram, + registeredProgramPda, + noopProgram, + accountCompressionAuthority, + accountCompressionProgram, + selfProgram, + tokenPoolPda, + compressOrDecompressTokenAccount, + tokenProgram, + systemProgram, + } = accounts; + + const accountsList: AccountMeta[] = [ + { pubkey: feePayer, isSigner: true, isWritable: true }, + { pubkey: authority, isSigner: true, isWritable: false }, + { pubkey: cpiAuthorityPda, isSigner: false, isWritable: false }, + { pubkey: lightSystemProgram, isSigner: false, isWritable: false }, + { pubkey: registeredProgramPda, isSigner: false, isWritable: false }, + { pubkey: noopProgram, isSigner: false, isWritable: false }, + { + pubkey: accountCompressionAuthority, + isSigner: false, + isWritable: false, + }, + { + pubkey: accountCompressionProgram, + isSigner: false, + isWritable: false, + }, + { pubkey: selfProgram, isSigner: false, isWritable: false }, + { + pubkey: tokenPoolPda ?? defaultPubkey, + isSigner: false, + isWritable: true, + }, + { + pubkey: compressOrDecompressTokenAccount ?? defaultPubkey, + isSigner: false, + isWritable: true, + }, + { + pubkey: tokenProgram ?? defaultPubkey, + isSigner: false, + isWritable: false, + }, + { pubkey: systemProgram, isSigner: false, isWritable: false }, + ]; + + return accountsList; +}; + +export type compressSplTokenAccountLayoutParams = { + feePayer: PublicKey; + authority: PublicKey; + cpiAuthorityPda: PublicKey; + lightSystemProgram: PublicKey; + registeredProgramPda: PublicKey; + noopProgram: PublicKey; + accountCompressionAuthority: PublicKey; + accountCompressionProgram: PublicKey; + selfProgram: PublicKey; + tokenPoolPda?: PublicKey; + compressOrDecompressTokenAccount?: PublicKey; + tokenProgram?: PublicKey; + systemProgram: PublicKey; +}; + +export const compressSplTokenAccountLayout = ( + accounts: compressSplTokenAccountLayoutParams, +): AccountMeta[] => { + const defaultPubkey = CompressedTokenProgram.programId; + const { + feePayer, + authority, + cpiAuthorityPda, + lightSystemProgram, + registeredProgramPda, + noopProgram, + accountCompressionAuthority, + accountCompressionProgram, + selfProgram, + tokenPoolPda, + compressOrDecompressTokenAccount, + tokenProgram, + systemProgram, + } = accounts; + + return [ + { pubkey: feePayer, isSigner: true, isWritable: true }, + { pubkey: authority, isSigner: true, isWritable: false }, + { pubkey: cpiAuthorityPda, isSigner: false, isWritable: false }, + { pubkey: lightSystemProgram, isSigner: false, isWritable: false }, + { pubkey: registeredProgramPda, isSigner: false, isWritable: false }, + { pubkey: noopProgram, isSigner: false, isWritable: false }, + { + pubkey: accountCompressionAuthority, + isSigner: false, + isWritable: false, + }, + { + pubkey: accountCompressionProgram, + isSigner: false, + isWritable: false, + }, + { pubkey: selfProgram, isSigner: false, isWritable: false }, + { + pubkey: tokenPoolPda ?? defaultPubkey, + isSigner: false, + isWritable: true, + }, + { + pubkey: compressOrDecompressTokenAccount ?? defaultPubkey, + isSigner: false, + isWritable: true, + }, + { + pubkey: tokenProgram ?? defaultPubkey, + isSigner: false, + isWritable: false, + }, + { pubkey: systemProgram, isSigner: false, isWritable: false }, + ]; +}; + +export type approveAccountsLayoutParams = { + feePayer: PublicKey; + authority: PublicKey; + cpiAuthorityPda: PublicKey; + lightSystemProgram: PublicKey; + registeredProgramPda: PublicKey; + noopProgram: PublicKey; + accountCompressionAuthority: PublicKey; + accountCompressionProgram: PublicKey; + selfProgram: PublicKey; + systemProgram: PublicKey; +}; + +export const approveAccountsLayout = ( + accounts: approveAccountsLayoutParams, +): AccountMeta[] => { + const { + feePayer, + authority, + cpiAuthorityPda, + lightSystemProgram, + registeredProgramPda, + noopProgram, + accountCompressionAuthority, + accountCompressionProgram, + selfProgram, + systemProgram, + } = accounts; + + return [ + { pubkey: feePayer, isSigner: true, isWritable: true }, + { pubkey: authority, isSigner: true, isWritable: false }, + { pubkey: cpiAuthorityPda, isSigner: false, isWritable: false }, + { pubkey: lightSystemProgram, isSigner: false, isWritable: false }, + { pubkey: registeredProgramPda, isSigner: false, isWritable: false }, + { pubkey: noopProgram, isSigner: false, isWritable: false }, + { + pubkey: accountCompressionAuthority, + isSigner: false, + isWritable: false, + }, + { + pubkey: accountCompressionProgram, + isSigner: false, + isWritable: false, + }, + { pubkey: selfProgram, isSigner: false, isWritable: false }, + { pubkey: systemProgram, isSigner: false, isWritable: false }, + ]; +}; + +export type revokeAccountsLayoutParams = approveAccountsLayoutParams; +export const revokeAccountsLayout = approveAccountsLayout; + +export type freezeAccountsLayoutParams = { + feePayer: PublicKey; + authority: PublicKey; + cpiAuthorityPda: PublicKey; + lightSystemProgram: PublicKey; + registeredProgramPda: PublicKey; + noopProgram: PublicKey; + accountCompressionAuthority: PublicKey; + accountCompressionProgram: PublicKey; + selfProgram: PublicKey; + systemProgram: PublicKey; + mint: PublicKey; +}; + +export const freezeAccountsLayout = ( + accounts: freezeAccountsLayoutParams, +): AccountMeta[] => { + const { + feePayer, + authority, + cpiAuthorityPda, + lightSystemProgram, + registeredProgramPda, + noopProgram, + accountCompressionAuthority, + accountCompressionProgram, + selfProgram, + systemProgram, + mint, + } = accounts; + + return [ + { pubkey: feePayer, isSigner: true, isWritable: true }, + { pubkey: authority, isSigner: true, isWritable: false }, + { pubkey: cpiAuthorityPda, isSigner: false, isWritable: false }, + { pubkey: lightSystemProgram, isSigner: false, isWritable: false }, + { pubkey: registeredProgramPda, isSigner: false, isWritable: false }, + { pubkey: noopProgram, isSigner: false, isWritable: false }, + { + pubkey: accountCompressionAuthority, + isSigner: false, + isWritable: false, + }, + { + pubkey: accountCompressionProgram, + isSigner: false, + isWritable: false, + }, + { pubkey: selfProgram, isSigner: false, isWritable: false }, + { pubkey: systemProgram, isSigner: false, isWritable: false }, + { pubkey: mint, isSigner: false, isWritable: false }, + ]; +}; + +export type thawAccountsLayoutParams = freezeAccountsLayoutParams; +export const thawAccountsLayout = freezeAccountsLayout; diff --git a/js/compressed-token/src/program.ts b/js/compressed-token/src/program.ts index f92ea299cb..ccae5ea002 100644 --- a/js/compressed-token/src/program.ts +++ b/js/compressed-token/src/program.ts @@ -1,26 +1,21 @@ import { PublicKey, - Keypair, TransactionInstruction, SystemProgram, Connection, AddressLookupTableProgram, AccountMeta, } from '@solana/web3.js'; -import { BN, Program, AnchorProvider, setProvider } from '@coral-xyz/anchor'; -import { IDL, LightCompressedToken } from './idl/light_compressed_token'; +import { Buffer } from 'buffer'; +import BN from 'bn.js'; import { CompressedProof, LightSystemProgram, ParsedTokenAccount, - TokenTransferOutputData, bn, - confirmConfig, - CompressedTokenInstructionDataTransfer, defaultStaticAccountsStruct, sumUpLamports, toArray, - useWallet, validateSameOwner, validateSufficientBalance, defaultTestStateTreeAccounts, @@ -34,6 +29,19 @@ import { } from '@solana/spl-token'; import { CPI_AUTHORITY_SEED, POOL_SEED } from './constants'; import { packCompressedTokenAccounts } from './instructions/pack-compressed-token-accounts'; +import { + CREATE_TOKEN_POOL_DISCRIMINATOR, + createTokenPoolAccountsLayout, + encodeCompressedTokenInstructionDataTransfer, + encodeCompressSplTokenAccountInstructionData, + encodeMintToInstructionData, + mintToAccountsLayout, + transferAccountsLayout, +} from './layout'; +import { + CompressedTokenInstructionDataTransfer, + TokenTransferOutputData, +} from './types'; export type CompressParams = { /** @@ -518,42 +526,6 @@ export class CompressedTokenProgram { typeof programId === 'string' ? new PublicKey(programId) : programId; - // Reset program when programId changes - this._program = null; - } - - private static _program: Program | null = null; - - /** @internal */ - static get program(): Program { - if (!this._program) { - this.initializeProgram(); - } - return this._program!; - } - - /** - * @internal - * Initializes the program statically if not already initialized. - */ - private static initializeProgram() { - if (!this._program) { - /// Note: We can use a mock connection because we're using the - /// program only for serde and building instructions, not for - /// interacting with the network. - const mockKeypair = Keypair.generate(); - const mockConnection = new Connection( - 'http://127.0.0.1:8899', - 'confirmed', - ); - const mockProvider = new AnchorProvider( - mockConnection, - useWallet(mockKeypair), - confirmConfig, - ); - setProvider(mockProvider); - this._program = new Program(IDL, this.programId, mockProvider); - } } /** @internal */ @@ -638,19 +610,20 @@ export class CompressedTokenProgram { const tokenPoolPda = this.deriveTokenPoolPda(mint); - const ix = await this.program.methods - .createTokenPool() - .accounts({ - mint, - feePayer, - tokenPoolPda, - systemProgram: SystemProgram.programId, - tokenProgram, - cpiAuthorityPda: this.deriveCpiAuthorityPda, - }) - .instruction(); - - return ix; + const keys = createTokenPoolAccountsLayout({ + mint, + feePayer, + tokenPoolPda, + tokenProgram, + cpiAuthorityPda: this.deriveCpiAuthorityPda, + systemProgram: SystemProgram.programId, + }); + + return new TransactionInstruction({ + programId: this.programId, + keys, + data: CREATE_TOKEN_POOL_DISCRIMINATOR, + }); } /** @@ -681,29 +654,31 @@ export class CompressedTokenProgram { 'Amount and toPubkey arrays must have the same length', ); } + const keys = mintToAccountsLayout({ + mint, + feePayer, + authority, + cpiAuthorityPda: this.deriveCpiAuthorityPda, + tokenProgram, + tokenPoolPda, + lightSystemProgram: LightSystemProgram.programId, + registeredProgramPda: systemKeys.registeredProgramPda, + noopProgram: systemKeys.noopProgram, + accountCompressionAuthority: systemKeys.accountCompressionAuthority, + accountCompressionProgram: systemKeys.accountCompressionProgram, + merkleTree: merkleTree ?? defaultTestStateTreeAccounts().merkleTree, + selfProgram: this.programId, + systemProgram: SystemProgram.programId, + solPoolPda: null, // TODO: add lamports support + }); - const instruction = await this.program.methods - .mintTo(toPubkeys, amounts, null) - .accounts({ - feePayer, - authority, - cpiAuthorityPda: this.deriveCpiAuthorityPda, - mint, - tokenPoolPda, - tokenProgram, - lightSystemProgram: LightSystemProgram.programId, - registeredProgramPda: systemKeys.registeredProgramPda, - noopProgram: systemKeys.noopProgram, - accountCompressionAuthority: - systemKeys.accountCompressionAuthority, - accountCompressionProgram: systemKeys.accountCompressionProgram, - merkleTree: - merkleTree ?? defaultTestStateTreeAccounts().merkleTree, - selfProgram: this.programId, - solPoolPda: null, - }) - .instruction(); - return instruction; + const data = encodeMintToInstructionData(toPubkeys, amounts, null); + + return new TransactionInstruction({ + programId: this.programId, + keys, + data, + }); } /** @@ -783,7 +758,7 @@ export class CompressedTokenProgram { inputCompressedTokenAccounts, ); - const data: CompressedTokenInstructionDataTransfer = { + const rawData: CompressedTokenInstructionDataTransfer = { proof: recentValidityProof, mint, delegatedTransfer: null, // TODO: implement @@ -795,10 +770,7 @@ export class CompressedTokenProgram { lamportsChangeAccountMerkleTreeIndex: null, }; - const encodedData = this.program.coder.types.encode( - 'CompressedTokenInstructionDataTransfer', - data, - ); + const data = encodeCompressedTokenInstructionDataTransfer(rawData); const { accountCompressionAuthority, @@ -806,27 +778,29 @@ export class CompressedTokenProgram { registeredProgramPda, accountCompressionProgram, } = defaultStaticAccountsStruct(); + const keys = transferAccountsLayout({ + feePayer: payer, + authority: currentOwner, + cpiAuthorityPda: this.deriveCpiAuthorityPda, + lightSystemProgram: LightSystemProgram.programId, + registeredProgramPda: registeredProgramPda, + noopProgram: noopProgram, + accountCompressionAuthority: accountCompressionAuthority, + accountCompressionProgram: accountCompressionProgram, + selfProgram: this.programId, + tokenPoolPda: undefined, + compressOrDecompressTokenAccount: undefined, + tokenProgram: undefined, + systemProgram: SystemProgram.programId, + }); - const instruction = await this.program.methods - .transfer(encodedData) - .accounts({ - feePayer: payer!, - authority: currentOwner!, - cpiAuthorityPda: this.deriveCpiAuthorityPda, - lightSystemProgram: LightSystemProgram.programId, - registeredProgramPda: registeredProgramPda, - noopProgram: noopProgram, - accountCompressionAuthority: accountCompressionAuthority, - accountCompressionProgram: accountCompressionProgram, - selfProgram: this.programId, - tokenPoolPda: null, - compressOrDecompressTokenAccount: null, - tokenProgram: null, - }) - .remainingAccounts(remainingAccountMetas) - .instruction(); - - return instruction; + keys.push(...remainingAccountMetas); + + return new TransactionInstruction({ + programId: this.programId, + keys, + data, + }); } /** @@ -945,7 +919,7 @@ export class CompressedTokenProgram { tokenTransferOutputs, }); - const data: CompressedTokenInstructionDataTransfer = { + const rawData: CompressedTokenInstructionDataTransfer = { proof: null, mint, delegatedTransfer: null, // TODO: implement @@ -961,35 +935,30 @@ export class CompressedTokenProgram { lamportsChangeAccountMerkleTreeIndex: null, }; - const encodedData = this.program.coder.types.encode( - 'CompressedTokenInstructionDataTransfer', - data, - ); + const data = encodeCompressedTokenInstructionDataTransfer(rawData); + const tokenProgram = tokenProgramId ?? TOKEN_PROGRAM_ID; - const instruction = await this.program.methods - .transfer(encodedData) - .accounts({ - feePayer: payer, - authority: owner, - cpiAuthorityPda: this.deriveCpiAuthorityPda, - lightSystemProgram: LightSystemProgram.programId, - registeredProgramPda: - defaultStaticAccountsStruct().registeredProgramPda, - noopProgram: defaultStaticAccountsStruct().noopProgram, - accountCompressionAuthority: - defaultStaticAccountsStruct().accountCompressionAuthority, - accountCompressionProgram: - defaultStaticAccountsStruct().accountCompressionProgram, - selfProgram: this.programId, - tokenPoolPda: this.deriveTokenPoolPda(mint), - compressOrDecompressTokenAccount: source, // token - tokenProgram, - }) - .remainingAccounts(remainingAccountMetas) - .instruction(); - - return instruction; + const keys = transferAccountsLayout({ + ...defaultStaticAccountsStruct(), + feePayer: payer, + authority: owner, + cpiAuthorityPda: this.deriveCpiAuthorityPda, + lightSystemProgram: LightSystemProgram.programId, + selfProgram: this.programId, + systemProgram: SystemProgram.programId, + tokenPoolPda: this.deriveTokenPoolPda(mint), + compressOrDecompressTokenAccount: source, + tokenProgram, + }); + + keys.push(...remainingAccountMetas); + + return new TransactionInstruction({ + programId: this.programId, + keys, + data, + }); } /** @@ -1030,7 +999,7 @@ export class CompressedTokenProgram { inputCompressedTokenAccounts, ); - const data: CompressedTokenInstructionDataTransfer = { + const rawData: CompressedTokenInstructionDataTransfer = { proof: recentValidityProof, mint, delegatedTransfer: null, // TODO: implement @@ -1041,12 +1010,8 @@ export class CompressedTokenProgram { cpiContext: null, lamportsChangeAccountMerkleTreeIndex: null, }; - - const encodedData = this.program.coder.types.encode( - 'CompressedTokenInstructionDataTransfer', - data, - ); - + const data = encodeCompressedTokenInstructionDataTransfer(rawData); + const tokenProgram = tokenProgramId ?? TOKEN_PROGRAM_ID; const { accountCompressionAuthority, noopProgram, @@ -1054,28 +1019,29 @@ export class CompressedTokenProgram { accountCompressionProgram, } = defaultStaticAccountsStruct(); - const tokenProgram = tokenProgramId ?? TOKEN_PROGRAM_ID; + const keys = transferAccountsLayout({ + feePayer: payer, + authority: currentOwner, + cpiAuthorityPda: this.deriveCpiAuthorityPda, + lightSystemProgram: LightSystemProgram.programId, + registeredProgramPda: registeredProgramPda, + noopProgram: noopProgram, + accountCompressionAuthority: accountCompressionAuthority, + accountCompressionProgram: accountCompressionProgram, + selfProgram: this.programId, + tokenPoolPda: this.deriveTokenPoolPda(mint), + compressOrDecompressTokenAccount: toAddress, + tokenProgram, + systemProgram: SystemProgram.programId, + }); + + keys.push(...remainingAccountMetas); - const instruction = await this.program.methods - .transfer(encodedData) - .accounts({ - feePayer: payer, - authority: currentOwner, - cpiAuthorityPda: this.deriveCpiAuthorityPda, - lightSystemProgram: LightSystemProgram.programId, - registeredProgramPda: registeredProgramPda, - noopProgram: noopProgram, - accountCompressionAuthority: accountCompressionAuthority, - accountCompressionProgram: accountCompressionProgram, - selfProgram: this.programId, - tokenPoolPda: this.deriveTokenPoolPda(mint), - compressOrDecompressTokenAccount: toAddress, - tokenProgram, - }) - .remainingAccounts(remainingAccountMetas) - .instruction(); - - return instruction; + return new TransactionInstruction({ + programId: this.programId, + keys, + data, + }); } static async mergeTokenAccounts( @@ -1132,30 +1098,40 @@ export class CompressedTokenProgram { }, ]; - const instruction = await this.program.methods - .compressSplTokenAccount(authority, remainingAmount ?? null, null) - .accounts({ - feePayer, - authority, - cpiAuthorityPda: this.deriveCpiAuthorityPda, - lightSystemProgram: LightSystemProgram.programId, - registeredProgramPda: - defaultStaticAccountsStruct().registeredProgramPda, - noopProgram: defaultStaticAccountsStruct().noopProgram, - accountCompressionAuthority: - defaultStaticAccountsStruct().accountCompressionAuthority, - accountCompressionProgram: - defaultStaticAccountsStruct().accountCompressionProgram, - selfProgram: this.programId, - tokenPoolPda: this.deriveTokenPoolPda(mint), - compressOrDecompressTokenAccount: tokenAccount, - tokenProgram, - systemProgram: SystemProgram.programId, - }) - .remainingAccounts(remainingAccountMetas) - .instruction(); - - return instruction; + const data = encodeCompressSplTokenAccountInstructionData( + authority, + remainingAmount ?? null, + null, + ); + const { + accountCompressionAuthority, + noopProgram, + registeredProgramPda, + accountCompressionProgram, + } = defaultStaticAccountsStruct(); + const keys = transferAccountsLayout({ + feePayer, + authority, + cpiAuthorityPda: this.deriveCpiAuthorityPda, + lightSystemProgram: LightSystemProgram.programId, + registeredProgramPda: registeredProgramPda, + noopProgram: noopProgram, + accountCompressionAuthority: accountCompressionAuthority, + accountCompressionProgram: accountCompressionProgram, + selfProgram: this.programId, + tokenPoolPda: this.deriveTokenPoolPda(mint), + compressOrDecompressTokenAccount: tokenAccount, + tokenProgram, + systemProgram: SystemProgram.programId, + }); + + keys.push(...remainingAccountMetas); + + return new TransactionInstruction({ + programId: this.programId, + keys, + data, + }); } static async get_mint_program_id( diff --git a/js/compressed-token/src/types.ts b/js/compressed-token/src/types.ts index d5852a6618..8247dcee25 100644 --- a/js/compressed-token/src/types.ts +++ b/js/compressed-token/src/types.ts @@ -1,7 +1,15 @@ import { PublicKey } from '@solana/web3.js'; -import { BN } from '@coral-xyz/anchor'; -import { CompressedProof } from '@lightprotocol/stateless.js'; +import BN from 'bn.js'; +import { + CompressedProof, + PackedMerkleContext, +} from '@lightprotocol/stateless.js'; +export type CompressedCpiContext = { + setContext: boolean; + firstSetContext: boolean; + cpiContextAccountIndex: number; // u8 +}; /// TODO: remove index_mt_account on-chain. passed as part of /// CompressedTokenInstructionDataInvoke export type TokenTransferOutputData = { @@ -47,45 +55,24 @@ export type PackedTokenTransferOutputData = { }; export type InputTokenDataWithContext = { - /** - * The amount of tokens to transfer - */ amount: BN; - /** - * Optional: The index of the delegate in remaining accounts - */ delegateIndex: number | null; - /** - * The index of the merkle tree address in remaining accounts - */ - merkleTreePubkeyIndex: number; - /** - * The index of the nullifier queue address in remaining accounts - */ - nullifierQueuePubkeyIndex: number; - /** - * The index of the leaf in the merkle tree - */ - leafIndex: number; - /** - * Lamports in the input token account. - */ + merkleContext: PackedMerkleContext; + rootIndex: number; lamports: BN | null; - /** - * TokenExtension tlv - */ tlv: Buffer | null; }; -export type CompressedTokenInstructionDataInvoke = { +export type DelegatedTransfer = { + owner: PublicKey; + delegateChangeAccountIndex: number | null; +}; + +export type CompressedTokenInstructionDataTransfer = { /** * Validity proof */ proof: CompressedProof | null; - /** - * The root indices of the transfer - */ - rootIndices: number[]; /** * The mint of the transfer */ @@ -94,7 +81,7 @@ export type CompressedTokenInstructionDataInvoke = { * Whether the signer is a delegate * TODO: implement delegated transfer struct */ - delegatedTransfer: null; + delegatedTransfer: DelegatedTransfer | null; /** * Input token data with packed merkle context */ @@ -102,12 +89,20 @@ export type CompressedTokenInstructionDataInvoke = { /** * Data of the output token accounts */ - outputCompressedAccounts: TokenTransferOutputData[]; + outputCompressedAccounts: PackedTokenTransferOutputData[]; + /** + * Whether it's a compress or decompress action if compressOrDecompressAmount is non-null + */ + isCompress: boolean; + /** + * If null, it's a transfer. + * If some, the amount that is being deposited into (compress) or withdrawn from (decompress) the token escrow + */ + compressOrDecompressAmount: BN | null; /** - * The indices of the output state merkle tree accounts in 'remaining - * accounts' + * CPI context if */ - outputStateMerkleTreeAccountIndices: Buffer; + cpiContext: CompressedCpiContext | null; /** * The index of the Merkle tree for a lamport change account. */ diff --git a/js/compressed-token/tests/e2e/approve-and-mint-to.test.ts b/js/compressed-token/tests/e2e/approve-and-mint-to.test.ts index ccce1e68b6..63576b0f3b 100644 --- a/js/compressed-token/tests/e2e/approve-and-mint-to.test.ts +++ b/js/compressed-token/tests/e2e/approve-and-mint-to.test.ts @@ -17,7 +17,7 @@ import { getTestRpc, } from '@lightprotocol/stateless.js'; import { WasmFactory } from '@lightprotocol/hasher.rs'; -import { BN } from '@coral-xyz/anchor'; +import BN from 'bn.js'; async function createTestSplMint( rpc: Rpc, diff --git a/js/compressed-token/tests/e2e/compress.test.ts b/js/compressed-token/tests/e2e/compress.test.ts index 7751db9f04..5ae12b879a 100644 --- a/js/compressed-token/tests/e2e/compress.test.ts +++ b/js/compressed-token/tests/e2e/compress.test.ts @@ -5,7 +5,7 @@ import { Signer, ComputeBudgetProgram, } from '@solana/web3.js'; -import { BN } from '@coral-xyz/anchor'; +import BN from 'bn.js'; import { ParsedTokenAccount, Rpc, diff --git a/js/compressed-token/tests/e2e/create-mint.test.ts b/js/compressed-token/tests/e2e/create-mint.test.ts index 4489c2b26c..e105790421 100644 --- a/js/compressed-token/tests/e2e/create-mint.test.ts +++ b/js/compressed-token/tests/e2e/create-mint.test.ts @@ -44,6 +44,7 @@ async function assertCreateMint( expect(unpackedPoolAccount.delegate).toBe(null); } +console.log('TEST_TOKEN_DECIMALS'); const TEST_TOKEN_DECIMALS = 2; describe('createMint', () => { let rpc: Rpc; @@ -52,12 +53,16 @@ describe('createMint', () => { let mintAuthority: Keypair; beforeAll(async () => { + console.log('beforeAll'); const lightWasm = await WasmFactory.getInstance(); + console.log('lightWasm', lightWasm); rpc = await getTestRpc(lightWasm); + console.log('TESTrpc', rpc); payer = await newAccountWithLamports(rpc, 1e9); + console.log('payer', payer); }); - it('should create mint', async () => { + it.only('should create mint', async () => { mintAuthority = Keypair.generate(); const mintKeypair = Keypair.generate(); diff --git a/js/compressed-token/tests/e2e/custom-program-id.test.ts b/js/compressed-token/tests/e2e/custom-program-id.test.ts deleted file mode 100644 index 56a1681a9a..0000000000 --- a/js/compressed-token/tests/e2e/custom-program-id.test.ts +++ /dev/null @@ -1,42 +0,0 @@ -import { describe, it, expect } from 'vitest'; -import { CompressedTokenProgram } from '../../src/program'; -import { PublicKey } from '@solana/web3.js'; - -describe('custom programId', () => { - it('should switch programId', async () => { - const defaultProgramId = new PublicKey( - 'cTokenmWW8bLPjZEBAUgYy3zKxQZW6VKi7bqNFEVv3m', - ); - const solMint = new PublicKey( - 'So11111111111111111111111111111111111111112', - ); - const expectedPoolPda = new PublicKey( - '3EJpXEsHL6JxNoPJWjF4QTKuvFvxzsUPbf1xF8iMbnL7', - ); - const newProgramId = new PublicKey( - '2WpGefPmpKMbkyLewupcfb8DuJ1ZMSPkMSu5WEvDMpF4', - ); - - // Check default program ID - expect(CompressedTokenProgram.programId).toEqual(defaultProgramId); - expect(CompressedTokenProgram.deriveTokenPoolPda(solMint)).toEqual( - expectedPoolPda, - ); - expect(CompressedTokenProgram.program.programId).toEqual( - defaultProgramId, - ); - - // Set new program ID - CompressedTokenProgram.setProgramId(newProgramId); - - // Verify program ID was updated - expect(CompressedTokenProgram.programId).toEqual(newProgramId); - expect(CompressedTokenProgram.deriveTokenPoolPda(solMint)).not.toEqual( - expectedPoolPda, - ); - expect(CompressedTokenProgram.program.programId).toEqual(newProgramId); - - // Reset program ID - CompressedTokenProgram.setProgramId(defaultProgramId); - }); -}); diff --git a/js/compressed-token/tests/e2e/decompress.test.ts b/js/compressed-token/tests/e2e/decompress.test.ts index 7d0846dd95..791dc23874 100644 --- a/js/compressed-token/tests/e2e/decompress.test.ts +++ b/js/compressed-token/tests/e2e/decompress.test.ts @@ -1,6 +1,6 @@ import { describe, it, expect, beforeAll } from 'vitest'; import { PublicKey, Keypair, Signer } from '@solana/web3.js'; -import { BN } from '@coral-xyz/anchor'; +import BN from 'bn.js'; import { ParsedTokenAccount, Rpc, diff --git a/js/compressed-token/tests/e2e/layout.test.ts b/js/compressed-token/tests/e2e/layout.test.ts new file mode 100644 index 0000000000..c81baa02b0 --- /dev/null +++ b/js/compressed-token/tests/e2e/layout.test.ts @@ -0,0 +1,61 @@ +import { describe, it, expect } from 'vitest'; +import { PublicKey } from '@solana/web3.js'; +import BN from 'bn.js'; +import { + CompressedTokenInstructionDataTransferLayout, + TRANSFER_DISCRIMINATOR, +} from '../../src/layout'; +import { CompressedTokenInstructionDataTransfer } from '../../../stateless.js/src'; + +describe('layout', () => { + it('encode CompressedTokenInstructionDataTransfer', () => { + const data: CompressedTokenInstructionDataTransfer = { + proof: null, + mint: new PublicKey('CXzk7xBgfzwSrZincWbJPGMPFz8aut3V6JjXp5n3XvGQ'), + delegatedTransfer: null, + inputTokenDataWithContext: [], + outputCompressedAccounts: [ + { + owner: new PublicKey( + '7gpbzzu2Aj2sE7LFdEQKUoZLqxVAK3eQ9LoeKQ5zCxQJ', + ), + amount: new BN(700), + lamports: null, + merkleTreeIndex: 0, + tlv: null, + }, + ], + isCompress: true, + compressOrDecompressAmount: new BN(700), + cpiContext: null, + lamportsChangeAccountMerkleTreeIndex: null, + }; + + const buffer = Buffer.alloc(1000); + const len = CompressedTokenInstructionDataTransferLayout.encode( + data, + buffer, + ); + + const lengthBuffer = Buffer.alloc(4); + lengthBuffer.writeUInt32LE(len, 0); + + const encoded = Buffer.concat([ + TRANSFER_DISCRIMINATOR, + lengthBuffer, + buffer.slice(0, len), + ]); + + expect(encoded.length).toBeGreaterThan(0); + expect(encoded.slice(0, 8)).toEqual(TRANSFER_DISCRIMINATOR); + expect(Array.from(encoded.slice(0, -8))).toEqual([ + 163, 52, 200, 231, 140, 3, 69, 186, 97, 0, 0, 0, 0, 171, 97, 69, + 108, 86, 192, 2, 185, 79, 47, 215, 58, 29, 81, 87, 205, 244, 20, + 157, 24, 221, 133, 48, 179, 204, 116, 15, 94, 62, 203, 8, 97, 0, 0, + 0, 0, 0, 1, 0, 0, 0, 99, 89, 153, 55, 109, 114, 208, 114, 149, 17, + 69, 25, 230, 251, 164, 56, 142, 112, 116, 91, 104, 218, 126, 175, + 171, 134, 147, 64, 101, 207, 16, 139, 188, 2, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 1, 1, 188, + ]); + }); +}); diff --git a/js/compressed-token/tests/e2e/mint-to.test.ts b/js/compressed-token/tests/e2e/mint-to.test.ts index 010db22709..28299e5aa4 100644 --- a/js/compressed-token/tests/e2e/mint-to.test.ts +++ b/js/compressed-token/tests/e2e/mint-to.test.ts @@ -5,7 +5,7 @@ import { Keypair, ComputeBudgetProgram, } from '@solana/web3.js'; -import { BN } from '@coral-xyz/anchor'; +import BN from 'bn.js'; import { createMint, createTokenProgramLookupTable, diff --git a/js/compressed-token/tests/e2e/rpc-token-interop.test.ts b/js/compressed-token/tests/e2e/rpc-token-interop.test.ts index e98953d044..2c7c8ea14a 100644 --- a/js/compressed-token/tests/e2e/rpc-token-interop.test.ts +++ b/js/compressed-token/tests/e2e/rpc-token-interop.test.ts @@ -15,7 +15,7 @@ const TEST_TOKEN_DECIMALS = 2; describe('rpc-interop token', () => { let rpc: Rpc; - let testRpc: TestRpc; + let testRpc: TestRpc | Rpc; let payer: Signer; let bob: Signer; let charlie: Signer; diff --git a/js/compressed-token/tests/e2e/transfer.test.ts b/js/compressed-token/tests/e2e/transfer.test.ts index a177f4aff4..c014bd0429 100644 --- a/js/compressed-token/tests/e2e/transfer.test.ts +++ b/js/compressed-token/tests/e2e/transfer.test.ts @@ -1,6 +1,6 @@ import { describe, it, expect, beforeAll, beforeEach, assert } from 'vitest'; import { PublicKey, Keypair, Signer } from '@solana/web3.js'; -import { BN } from '@coral-xyz/anchor'; +import BN from 'bn.js'; import { ParsedTokenAccount, Rpc, diff --git a/js/compressed-token/tsconfig.json b/js/compressed-token/tsconfig.json index 0995cc57fb..f3440f50d0 100644 --- a/js/compressed-token/tsconfig.json +++ b/js/compressed-token/tsconfig.json @@ -12,7 +12,8 @@ "moduleResolution": "Node", "lib": ["ESNext", "DOM"], "types": ["node"], - "skipLibCheck": false + "skipLibCheck": false, + "typeRoots": ["types/", "./node_modules/@types"] }, "include": ["./src/**/*.ts", "rollup.config.js"] } diff --git a/js/compressed-token/types/buffer-layout/index.d.ts b/js/compressed-token/types/buffer-layout/index.d.ts new file mode 100644 index 0000000000..f047cbb1fd --- /dev/null +++ b/js/compressed-token/types/buffer-layout/index.d.ts @@ -0,0 +1,88 @@ +// From https://github.com/coral-xyz/anchor/blob/master/ts/packages/anchor/types/buffer-layout/index.d.ts +declare module 'buffer-layout' { + // TODO: remove `any`. + export class Layout { + span: number; + property?: string; + + constructor(span: number, property?: string); + + decode(b: Buffer | string, offset?: number): T; + encode(src: T, b: Buffer, offset?: number): number; + getSpan(b: Buffer, offset?: number): number; + replicate(name: string): this; + } + // TODO: remove any. + export class Structure extends Layout { + span: any; + } + export function greedy( + elementSpan?: number, + property?: string, + ): Layout; + export function offset( + layout: Layout, + offset?: number, + property?: string, + ): Layout; + export function u8(property?: string): Layout; + export function u16(property?: string): Layout; + export function u24(property?: string): Layout; + export function u32(property?: string): Layout; + export function u40(property?: string): Layout; + export function u48(property?: string): Layout; + export function nu64(property?: string): Layout; + export function u16be(property?: string): Layout; + export function u24be(property?: string): Layout; + export function u32be(property?: string): Layout; + export function u40be(property?: string): Layout; + export function u48be(property?: string): Layout; + export function nu64be(property?: string): Layout; + export function s8(property?: string): Layout; + export function s16(property?: string): Layout; + export function s24(property?: string): Layout; + export function s32(property?: string): Layout; + export function s40(property?: string): Layout; + export function s48(property?: string): Layout; + export function ns64(property?: string): Layout; + export function s16be(property?: string): Layout; + export function s24be(property?: string): Layout; + export function s32be(property?: string): Layout; + export function s40be(property?: string): Layout; + export function s48be(property?: string): Layout; + export function ns64be(property?: string): Layout; + export function f32(property?: string): Layout; + export function f32be(property?: string): Layout; + export function f64(property?: string): Layout; + export function f64be(property?: string): Layout; + export function struct( + fields: Layout[], + property?: string, + decodePrefixes?: boolean, + ): Layout; + export function bits( + word: Layout, + msb?: boolean, + property?: string, + ): any; + export function seq( + elementLayout: Layout, + count: number | Layout, + property?: string, + ): Layout; + export function union( + discr: Layout, + defaultLayout?: any, + property?: string, + ): any; + export function unionLayoutDiscriminator( + layout: Layout, + property?: string, + ): any; + export function blob( + length: number | Layout, + property?: string, + ): Layout; + export function cstr(property?: string): Layout; + export function utf8(maxSpan: number, property?: string): Layout; +} diff --git a/js/stateless.js/README.md b/js/stateless.js/README.md index a0a65b7bf3..bf72b20d1c 100644 --- a/js/stateless.js/README.md +++ b/js/stateless.js/README.md @@ -45,6 +45,14 @@ Feel free to ask in the [Light](https://discord.gg/CYvjBgzRFP) and [Helius](http - A code example that we can use to test and debug (if possible). Use [CodeSandbox](https://codesandbox.io/p/sandbox/vanilla-ts) or any other live environment provider. - A description or context of any errors you are encountering with stacktraces if available. +### Source Maps + +We provide `index.js.map` for debugging. Exclude in production: + +**Webpack:** Set `devtool` to `false`. +**Rollup:** Set `sourcemap` to `false`. +**TypeScript:** Set `sourceMap` to `false`. + ## Contributing Light and ZK Compression are open source protocols and very much welcome contributions. If you have a contribution, do not hesitate to send a PR to the respective repository or discuss in the linked developer Discord servers. diff --git a/js/stateless.js/package.json b/js/stateless.js/package.json index e56ea3d363..42a4a1954e 100644 --- a/js/stateless.js/package.json +++ b/js/stateless.js/package.json @@ -1,7 +1,7 @@ { "name": "@lightprotocol/stateless.js", - "version": "0.17.1", - "description": "JavaScript API for Light and ZK Compression", + "version": "0.17.2-alpha.1", + "description": "JavaScript API for Light & ZK Compression", "sideEffects": false, "main": "dist/cjs/node/index.cjs", "type": "module", @@ -9,7 +9,7 @@ ".": { "require": "./dist/cjs/node/index.cjs", "types": "./dist/types/index.d.ts", - "default": "./dist/cjs/node/index.cjs" + "import": "./dist/es/browser/index.js" }, "./browser": { "import": "./dist/es/browser/index.js", @@ -34,17 +34,22 @@ } ], "license": "Apache-2.0", + "peerDependencies": { + "@solana/web3.js": ">=1.73.5" + }, "dependencies": { - "@coral-xyz/anchor": "0.29.0", - "@solana/web3.js": "1.95.3", + "@coral-xyz/borsh": "^0.29.0", "@noble/hashes": "1.5.0", + "bn.js": "^5.2.1", + "bs58": "^6.0.0", "buffer": "6.0.3", - "superstruct": "2.0.2", - "tweetnacl": "1.0.3" + "buffer-layout": "^1.2.2", + "camelcase": "^8.0.0", + "superstruct": "2.0.2" }, "devDependencies": { - "@lightprotocol/hasher.rs": "0.2.1", "@esbuild-plugins/node-globals-polyfill": "^0.2.3", + "@lightprotocol/hasher.rs": "0.2.1", "@lightprotocol/programs": "workspace:*", "@playwright/test": "^1.47.1", "@rollup/plugin-babel": "^6.0.4", @@ -54,6 +59,7 @@ "@rollup/plugin-replace": "^5.0.7", "@rollup/plugin-terser": "^0.4.4", "@rollup/plugin-typescript": "^11.1.6", + "@solana/web3.js": "1.98.0", "@types/bn.js": "^5.1.5", "@types/node": "^22.5.5", "@typescript-eslint/eslint-plugin": "^7.13.1", @@ -71,13 +77,14 @@ "rollup-plugin-polyfill-node": "^0.13.0", "ts-node": "^10.9.2", "tslib": "^2.7.0", + "tweetnacl": "1.0.3", "typescript": "^5.6.2", "vitest": "^2.1.1" }, "scripts": { "test": "pnpm test:unit:all && pnpm test:e2e:all", "test-all": "vitest run", - "test:unit:all": "vitest run tests/unit", + "test:unit:all": "vitest run tests/unit --reporter=verbose", "test-validator": "./../../cli/test_bin/run test-validator --prover-run-mode rpc", "test:e2e:transfer": "pnpm test-validator && vitest run tests/e2e/transfer.test.ts --reporter=verbose", "test:e2e:compress": "pnpm test-validator && vitest run tests/e2e/compress.test.ts --reporter=verbose", @@ -86,11 +93,11 @@ "test:e2e:browser": "pnpm playwright test", "test:e2e:all": "pnpm test-validator && vitest run tests/e2e/test-rpc.test.ts && vitest run tests/e2e/compress.test.ts && vitest run tests/e2e/transfer.test.ts && vitest run tests/e2e/rpc-interop.test.ts", "test:index": "vitest run tests/e2e/program.test.ts", - "test:e2e:serde": "vitest run tests/e2e/serde.test.ts", + "test:e2e:serde": "vitest run tests/e2e/serde.test.ts --reporter=verbose", "test:verbose": "vitest run --reporter=verbose", "test:testnet": "vitest run tests/e2e/testnet.test.ts --reporter=verbose", "pull-idls": "../../scripts/push-stateless-js-idls.sh && ../../scripts/push-compressed-token-idl.sh", - "build": "rimraf dist && pnpm pull-idls && pnpm build:bundle", + "build": "rimraf dist && pnpm build:bundle", "build:bundle": "rollup -c", "format": "prettier --write .", "lint": "eslint ." diff --git a/js/stateless.js/rollup.config.js b/js/stateless.js/rollup.config.js index 94f7a61391..8a3f386e8d 100644 --- a/js/stateless.js/rollup.config.js +++ b/js/stateless.js/rollup.config.js @@ -3,6 +3,7 @@ import nodePolyfills from 'rollup-plugin-polyfill-node'; import dts from 'rollup-plugin-dts'; import resolve from '@rollup/plugin-node-resolve'; import commonjs from '@rollup/plugin-commonjs'; +import terser from '@rollup/plugin-terser'; const rolls = (fmt, env) => ({ input: 'src/index.ts', @@ -13,12 +14,12 @@ const rolls = (fmt, env) => ({ sourcemap: true, }, external: [ - '@coral-xyz/anchor', '@solana/web3.js', - '@noble/hashes', + // '@coral-xyz/borsh', + // '@noble/hashes', 'buffer', 'superstruct', - 'tweetnacl', + 'buffer-layout', ], plugins: [ typescript({ @@ -32,6 +33,26 @@ const rolls = (fmt, env) => ({ preferBuiltins: env === 'node', }), env === 'browser' ? nodePolyfills() : undefined, + terser({ + compress: { + drop_console: true, + drop_debugger: true, + passes: 3, + pure_funcs: ['console.log', 'console.error', 'console.warn'], + booleans_as_integers: true, + keep_fargs: false, + keep_fnames: false, + keep_infinity: true, + reduce_funcs: true, + reduce_vars: true, + }, + mangle: { + toplevel: true, + }, + output: { + comments: false, + }, + }), ].filter(Boolean), onwarn(warning, warn) { if (warning.code !== 'CIRCULAR_DEPENDENCY') { diff --git a/js/stateless.js/src/actions/compress.ts b/js/stateless.js/src/actions/compress.ts index 40f0a4fa83..982d1131b2 100644 --- a/js/stateless.js/src/actions/compress.ts +++ b/js/stateless.js/src/actions/compress.ts @@ -9,7 +9,7 @@ import { import { LightSystemProgram } from '../programs'; import { Rpc } from '../rpc'; import { buildAndSignTx, sendAndConfirmTx } from '../utils'; -import { BN } from '@coral-xyz/anchor'; +import BN from 'bn.js'; import { defaultTestStateTreeAccounts } from '../constants'; /** diff --git a/js/stateless.js/src/actions/create-account.ts b/js/stateless.js/src/actions/create-account.ts index 5e423c22ee..a1b94e7ebf 100644 --- a/js/stateless.js/src/actions/create-account.ts +++ b/js/stateless.js/src/actions/create-account.ts @@ -19,7 +19,7 @@ import { } from '../utils'; import { defaultTestStateTreeAccounts } from '../constants'; import { bn } from '../state'; -import { BN } from '@coral-xyz/anchor'; +import BN from 'bn.js'; /** * Create compressed account with address diff --git a/js/stateless.js/src/actions/decompress.ts b/js/stateless.js/src/actions/decompress.ts index 5de8036abf..ca848c4ce0 100644 --- a/js/stateless.js/src/actions/decompress.ts +++ b/js/stateless.js/src/actions/decompress.ts @@ -8,7 +8,7 @@ import { import { LightSystemProgram, sumUpLamports } from '../programs'; import { Rpc } from '../rpc'; import { buildAndSignTx, sendAndConfirmTx } from '../utils'; -import { BN } from '@coral-xyz/anchor'; +import BN from 'bn.js'; import { CompressedAccountWithMerkleContext, bn } from '../state'; /** diff --git a/js/stateless.js/src/actions/transfer.ts b/js/stateless.js/src/actions/transfer.ts index 551f9b6540..d43eded3c6 100644 --- a/js/stateless.js/src/actions/transfer.ts +++ b/js/stateless.js/src/actions/transfer.ts @@ -6,7 +6,7 @@ import { TransactionSignature, } from '@solana/web3.js'; -import { BN } from '@coral-xyz/anchor'; +import BN from 'bn.js'; import { LightSystemProgram, selectMinCompressedSolAccountsForTransfer, diff --git a/js/stateless.js/src/connection-interface.ts b/js/stateless.js/src/connection-interface.ts new file mode 100644 index 0000000000..6dce862deb --- /dev/null +++ b/js/stateless.js/src/connection-interface.ts @@ -0,0 +1,545 @@ +// import { +// PublicKey, +// Commitment, +// ConnectionConfig, +// GetBalanceConfig, +// RpcResponseAndContext, +// Supply, +// TokenAmount, +// GetSupplyConfig, +// TokenAccountsFilter, +// GetProgramAccountsResponse, +// GetTokenAccountsByOwnerConfig, +// AccountInfo, +// ParsedAccountData, +// GetLargestAccountsConfig, +// AccountBalancePair, +// TokenAccountBalancePair, +// GetAccountInfoConfig, +// GetMultipleAccountsConfig, +// StakeActivationData, +// GetBlockHeightConfig, +// GetBlockProductionConfig, +// BlockProduction, +// GetLatestBlockhashConfig, +// BlockhashWithExpiryBlockHeight, +// SimulatedTransactionResponse, +// SimulateTransactionConfig, +// SendOptions, +// TransactionSignature, +// AddressLookupTableAccount, +// GetParsedProgramAccountsConfig, +// Finality, +// GetVersionedBlockConfig, +// VersionedBlockResponse, +// VersionedAccountsModeBlockResponse, +// VersionedNoneModeBlockResponse, +// ParsedAccountsModeBlockResponse, +// ParsedNoneModeBlockResponse, +// ParsedTransactionWithMeta, +// VersionedTransaction, +// VersionedTransactionResponse, +// ConfirmedBlock, +// ConfirmedSignatureInfo, +// ConfirmedSignaturesForAddress2Options, +// SignatureStatusConfig, +// SignatureStatus, +// Version, +// VoteAccountStatus, +// GetSlotConfig, +// GetSlotLeaderConfig, +// GetProgramAccountsConfig, +// SignatureResult, +// TransactionConfirmationStrategy, +// AccountChangeCallback, +// ProgramAccountChangeCallback, +// LogsCallback, +// SlotChangeCallback, +// SlotUpdateCallback, +// SignatureResultCallback, +// SignatureSubscriptionCallback, +// SignatureSubscriptionOptions, +// RootChangeCallback, +// GetStakeActivationConfig, +// InflationGovernor, +// GetTransactionCountConfig, +// GetInflationRewardConfig, +// InflationReward, +// InflationRate, +// GetEpochInfoConfig, +// EpochInfo, +// EpochSchedule, +// LeaderSchedule, +// Blockhash, +// FeeCalculator, +// PerfSample, +// VersionedMessage, +// GetRecentPrioritizationFeesConfig, +// RecentPrioritizationFees, +// IsBlockhashValidConfig, +// GetVersionedTransactionConfig, +// ParsedConfirmedTransaction, +// ConfirmedTransaction, +// BlockSignatures, +// SignaturesForAddressOptions, +// GetNonceAndContextConfig, +// NonceAccount, +// GetNonceConfig, +// GetStakeMinimumDelegationConfig, +// AccountSubscriptionConfig, +// ProgramAccountSubscriptionConfig, +// LogsFilter, +// ContactInfo, +// } from '@solana/web3.js'; + +// export type ClientSubscriptionId = number; + +// export interface ConnectionInterface { +// readonly commitment?: Commitment; +// readonly rpcEndpoint: string; + +// getBalanceAndContext( +// publicKey: PublicKey, +// commitmentOrConfig?: Commitment | GetBalanceConfig, +// ): Promise>; + +// getBalance( +// publicKey: PublicKey, +// commitmentOrConfig?: Commitment | GetBalanceConfig, +// ): Promise; + +// getBlockTime(slot: number): Promise; + +// getMinimumLedgerSlot(): Promise; + +// getFirstAvailableBlock(): Promise; + +// getSupply( +// config?: GetSupplyConfig | Commitment, +// ): Promise>; + +// getTokenSupply( +// tokenMintAddress: PublicKey, +// commitment?: Commitment, +// ): Promise>; + +// getTokenAccountBalance( +// tokenAddress: PublicKey, +// commitment?: Commitment, +// ): Promise>; + +// getTokenAccountsByOwner( +// ownerAddress: PublicKey, +// filter: TokenAccountsFilter, +// commitmentOrConfig?: Commitment | GetTokenAccountsByOwnerConfig, +// ): Promise>; + +// getParsedTokenAccountsByOwner( +// ownerAddress: PublicKey, +// filter: TokenAccountsFilter, +// commitment?: Commitment, +// ): Promise< +// RpcResponseAndContext< +// Array<{ +// pubkey: PublicKey; +// account: AccountInfo; +// }> +// > +// >; + +// getLargestAccounts( +// config?: GetLargestAccountsConfig, +// ): Promise>>; + +// getTokenLargestAccounts( +// mintAddress: PublicKey, +// commitment?: Commitment, +// ): Promise>>; + +// getAccountInfoAndContext( +// publicKey: PublicKey, +// commitmentOrConfig?: Commitment | GetAccountInfoConfig, +// ): Promise | null>>; + +// getParsedAccountInfo( +// publicKey: PublicKey, +// commitmentOrConfig?: Commitment | GetAccountInfoConfig, +// ): Promise< +// RpcResponseAndContext | null> +// >; + +// getAccountInfo( +// publicKey: PublicKey, +// commitmentOrConfig?: Commitment | GetAccountInfoConfig, +// ): Promise | null>; + +// getMultipleParsedAccounts( +// publicKeys: PublicKey[], +// rawConfig?: GetMultipleAccountsConfig, +// ): Promise< +// RpcResponseAndContext< +// (AccountInfo | null)[] +// > +// >; + +// getMultipleAccountsInfoAndContext( +// publicKeys: PublicKey[], +// commitmentOrConfig?: Commitment | GetMultipleAccountsConfig, +// ): Promise | null)[]>>; + +// getMultipleAccountsInfo( +// publicKeys: PublicKey[], +// commitmentOrConfig?: Commitment | GetMultipleAccountsConfig, +// ): Promise<(AccountInfo | null)[]>; + +// getStakeActivation( +// publicKey: PublicKey, +// commitmentOrConfig?: Commitment | GetStakeActivationConfig, +// epoch?: number, +// ): Promise; + +// getProgramAccounts( +// programId: PublicKey, +// configOrCommitment?: GetProgramAccountsConfig | Commitment, +// ): Promise; + +// getProgramAccounts( +// programId: PublicKey, +// configOrCommitment: GetProgramAccountsConfig & { withContext: true }, +// ): Promise>; + +// getParsedProgramAccounts( +// programId: PublicKey, +// configOrCommitment?: GetParsedProgramAccountsConfig | Commitment, +// ): Promise< +// Array<{ +// pubkey: PublicKey; +// account: AccountInfo; +// }> +// >; + +// confirmTransaction( +// strategy: TransactionConfirmationStrategy, +// commitment?: Commitment, +// ): Promise>; + +// confirmTransaction( +// strategy: TransactionSignature, +// commitment?: Commitment, +// ): Promise>; + +// getClusterNodes(): Promise>; + +// getVoteAccounts(commitment?: Commitment): Promise; + +// getSlot(commitmentOrConfig?: Commitment | GetSlotConfig): Promise; + +// getSlotLeader( +// commitmentOrConfig?: Commitment | GetSlotLeaderConfig, +// ): Promise; + +// getSlotLeaders(startSlot: number, limit: number): Promise>; + +// getSignatureStatus( +// signature: TransactionSignature, +// config?: SignatureStatusConfig, +// ): Promise>; + +// getSignatureStatuses( +// signatures: Array, +// config?: SignatureStatusConfig, +// ): Promise>>; + +// getTransactionCount( +// commitmentOrConfig?: Commitment | GetTransactionCountConfig, +// ): Promise; + +// getTotalSupply(commitment?: Commitment): Promise; + +// getInflationGovernor(commitment?: Commitment): Promise; + +// getInflationReward( +// addresses: PublicKey[], +// epoch?: number, +// commitmentOrConfig?: Commitment | GetInflationRewardConfig, +// ): Promise<(InflationReward | null)[]>; + +// getInflationRate(): Promise; + +// getEpochInfo( +// commitmentOrConfig?: Commitment | GetEpochInfoConfig, +// ): Promise; + +// getEpochSchedule(): Promise; + +// getLeaderSchedule(): Promise; + +// getMinimumBalanceForRentExemption( +// dataLength: number, +// commitment?: Commitment, +// ): Promise; + +// getRecentBlockhashAndContext(commitment?: Commitment): Promise< +// RpcResponseAndContext<{ +// blockhash: Blockhash; +// feeCalculator: FeeCalculator; +// }> +// >; + +// getRecentPerformanceSamples(limit?: number): Promise>; + +// getFeeCalculatorForBlockhash( +// blockhash: Blockhash, +// commitment?: Commitment, +// ): Promise>; + +// getFeeForMessage( +// message: VersionedMessage, +// commitment?: Commitment, +// ): Promise>; + +// getRecentPrioritizationFees( +// config?: GetRecentPrioritizationFeesConfig, +// ): Promise; + +// getRecentBlockhash( +// commitment?: Commitment, +// ): Promise<{ blockhash: Blockhash; feeCalculator: FeeCalculator }>; + +// getLatestBlockhash( +// commitmentOrConfig?: Commitment | GetLatestBlockhashConfig, +// ): Promise; + +// getLatestBlockhashAndContext( +// commitmentOrConfig?: Commitment | GetLatestBlockhashConfig, +// ): Promise>; + +// isBlockhashValid( +// blockhash: Blockhash, +// rawConfig?: IsBlockhashValidConfig, +// ): Promise>; + +// getVersion(): Promise; + +// getGenesisHash(): Promise; + +// getBlock( +// slot: number, +// rawConfig?: GetVersionedBlockConfig, +// ): Promise; + +// getBlock( +// slot: number, +// rawConfig: GetVersionedBlockConfig & { transactionDetails: 'accounts' }, +// ): Promise; + +// getBlock( +// slot: number, +// rawConfig: GetVersionedBlockConfig & { transactionDetails: 'none' }, +// ): Promise; + +// getParsedBlock( +// slot: number, +// rawConfig?: GetVersionedBlockConfig, +// ): Promise; + +// getParsedBlock( +// slot: number, +// rawConfig: GetVersionedBlockConfig & { transactionDetails: 'accounts' }, +// ): Promise; + +// getParsedBlock( +// slot: number, +// rawConfig: GetVersionedBlockConfig & { transactionDetails: 'none' }, +// ): Promise; + +// getBlockHeight( +// commitmentOrConfig?: Commitment | GetBlockHeightConfig, +// ): Promise; + +// getBlockProduction( +// configOrCommitment?: GetBlockProductionConfig | Commitment, +// ): Promise>; + +// getTransaction( +// signature: string, +// rawConfig?: GetVersionedTransactionConfig, +// ): Promise; + +// getParsedTransaction( +// signature: TransactionSignature, +// commitmentOrConfig?: GetVersionedTransactionConfig | Finality, +// ): Promise; + +// getParsedTransactions( +// signatures: TransactionSignature[], +// commitmentOrConfig?: GetVersionedTransactionConfig | Finality, +// ): Promise<(ParsedTransactionWithMeta | null)[]>; + +// getTransactions( +// signatures: TransactionSignature[], +// commitmentOrConfig: GetVersionedTransactionConfig | Finality, +// ): Promise<(VersionedTransactionResponse | null)[]>; + +// getConfirmedBlock( +// slot: number, +// commitment?: Finality, +// ): Promise; + +// getBlocks( +// startSlot: number, +// endSlot?: number, +// commitment?: Finality, +// ): Promise>; + +// getBlockSignatures( +// slot: number, +// commitment?: Finality, +// ): Promise; + +// getConfirmedBlockSignatures( +// slot: number, +// commitment?: Finality, +// ): Promise; + +// getConfirmedTransaction( +// signature: TransactionSignature, +// commitment?: Finality, +// ): Promise; + +// getParsedConfirmedTransaction( +// signature: TransactionSignature, +// commitment?: Finality, +// ): Promise; + +// getParsedConfirmedTransactions( +// signatures: TransactionSignature[], +// commitment?: Finality, +// ): Promise<(ParsedConfirmedTransaction | null)[]>; + +// getConfirmedSignaturesForAddress( +// address: PublicKey, +// startSlot: number, +// endSlot: number, +// ): Promise>; + +// getConfirmedSignaturesForAddress2( +// address: PublicKey, +// options?: ConfirmedSignaturesForAddress2Options, +// commitment?: Finality, +// ): Promise>; + +// getSignaturesForAddress( +// address: PublicKey, +// options?: SignaturesForAddressOptions, +// commitment?: Finality, +// ): Promise>; + +// getAddressLookupTable( +// accountKey: PublicKey, +// config?: GetAccountInfoConfig, +// ): Promise>; + +// getNonceAndContext( +// nonceAccount: PublicKey, +// commitmentOrConfig?: Commitment | GetNonceAndContextConfig, +// ): Promise>; + +// getNonce( +// nonceAccount: PublicKey, +// commitmentOrConfig?: Commitment | GetNonceConfig, +// ): Promise; + +// requestAirdrop( +// to: PublicKey, +// lamports: number, +// ): Promise; + +// getStakeMinimumDelegation( +// config?: GetStakeMinimumDelegationConfig, +// ): Promise>; + +// simulateTransaction( +// transaction: VersionedTransaction, +// config?: SimulateTransactionConfig, +// ): Promise>; + +// sendTransaction( +// transaction: VersionedTransaction, +// options?: SendOptions, +// ): Promise; + +// sendRawTransaction( +// rawTransaction: Buffer | Uint8Array | Array, +// options?: SendOptions, +// ): Promise; + +// sendEncodedTransaction( +// encodedTransaction: string, +// options?: SendOptions, +// ): Promise; + +// onAccountChange( +// publicKey: PublicKey, +// callback: AccountChangeCallback, +// config?: AccountSubscriptionConfig, +// ): ClientSubscriptionId; + +// onProgramAccountChange( +// programId: PublicKey, +// callback: ProgramAccountChangeCallback, +// config?: ProgramAccountSubscriptionConfig, +// ): ClientSubscriptionId; + +// onLogs( +// filter: LogsFilter, +// callback: LogsCallback, +// commitment?: Commitment, +// ): ClientSubscriptionId; + +// onSlotChange(callback: SlotChangeCallback): ClientSubscriptionId; + +// onSlotUpdate(callback: SlotUpdateCallback): ClientSubscriptionId; + +// onSignature( +// signature: TransactionSignature, +// callback: SignatureResultCallback, +// commitment?: Commitment, +// ): ClientSubscriptionId; + +// onSignatureWithOptions( +// signature: TransactionSignature, +// callback: SignatureSubscriptionCallback, +// options?: SignatureSubscriptionOptions, +// ): ClientSubscriptionId; + +// onRootChange(callback: RootChangeCallback): ClientSubscriptionId; + +// removeAccountChangeListener( +// clientSubscriptionId: ClientSubscriptionId, +// ): Promise; + +// removeProgramAccountChangeListener( +// clientSubscriptionId: ClientSubscriptionId, +// ): Promise; + +// removeOnLogsListener( +// clientSubscriptionId: ClientSubscriptionId, +// ): Promise; + +// removeSlotChangeListener( +// clientSubscriptionId: ClientSubscriptionId, +// ): Promise; + +// removeSlotUpdateListener( +// clientSubscriptionId: ClientSubscriptionId, +// ): Promise; + +// removeSignatureListener( +// clientSubscriptionId: ClientSubscriptionId, +// ): Promise; + +// removeRootChangeListener( +// clientSubscriptionId: ClientSubscriptionId, +// ): Promise; +// } diff --git a/js/stateless.js/src/constants.ts b/js/stateless.js/src/constants.ts index ca4eabe452..b4dc6ee02e 100644 --- a/js/stateless.js/src/constants.ts +++ b/js/stateless.js/src/constants.ts @@ -1,4 +1,4 @@ -import { BN } from '@coral-xyz/anchor'; +import BN from 'bn.js'; import { Buffer } from 'buffer'; import { ConfirmOptions, PublicKey } from '@solana/web3.js'; diff --git a/js/stateless.js/src/idls/account_compression.ts b/js/stateless.js/src/idls/account_compression.ts deleted file mode 100644 index f90f8a4ad2..0000000000 --- a/js/stateless.js/src/idls/account_compression.ts +++ /dev/null @@ -1,2797 +0,0 @@ -export type AccountCompression = { - version: '1.2.0'; - name: 'account_compression'; - constants: [ - { - name: 'CPI_AUTHORITY_PDA_SEED'; - type: 'bytes'; - value: '[99, 112, 105, 95, 97, 117, 116, 104, 111, 114, 105, 116, 121]'; - }, - { - name: 'GROUP_AUTHORITY_SEED'; - type: 'bytes'; - value: '[103, 114, 111, 117, 112, 95, 97, 117, 116, 104, 111, 114, 105, 116, 121]'; - }, - { - name: 'STATE_MERKLE_TREE_HEIGHT'; - type: 'u64'; - value: '26'; - }, - { - name: 'STATE_MERKLE_TREE_CHANGELOG'; - type: 'u64'; - value: '1400'; - }, - { - name: 'STATE_MERKLE_TREE_ROOTS'; - type: 'u64'; - value: '2400'; - }, - { - name: 'STATE_MERKLE_TREE_CANOPY_DEPTH'; - type: 'u64'; - value: '10'; - }, - { - name: 'STATE_NULLIFIER_QUEUE_VALUES'; - type: 'u16'; - value: '28_807'; - }, - { - name: 'STATE_NULLIFIER_QUEUE_SEQUENCE_THRESHOLD'; - type: 'u64'; - value: '2400'; - }, - { - name: 'ADDRESS_MERKLE_TREE_HEIGHT'; - type: 'u64'; - value: '26'; - }, - { - name: 'ADDRESS_MERKLE_TREE_CHANGELOG'; - type: 'u64'; - value: '1400'; - }, - { - name: 'ADDRESS_MERKLE_TREE_ROOTS'; - type: 'u64'; - value: '2400'; - }, - { - name: 'ADDRESS_MERKLE_TREE_CANOPY_DEPTH'; - type: 'u64'; - value: '10'; - }, - { - name: 'ADDRESS_MERKLE_TREE_INDEXED_CHANGELOG'; - type: 'u64'; - value: '1400'; - }, - { - name: 'ADDRESS_QUEUE_VALUES'; - type: 'u16'; - value: '28_807'; - }, - { - name: 'ADDRESS_QUEUE_SEQUENCE_THRESHOLD'; - type: 'u64'; - value: '2400'; - }, - { - name: 'NOOP_PUBKEY'; - type: { - array: ['u8', 32]; - }; - value: '[11 , 188 , 15 , 192 , 187 , 71 , 202 , 47 , 116 , 196 , 17 , 46 , 148 , 171 , 19 , 207 , 163 , 198 , 52 , 229 , 220 , 23 , 234 , 203 , 3 , 205 , 26 , 35 , 205 , 126 , 120 , 124 ,]'; - }, - ]; - instructions: [ - { - name: 'initializeBatchedStateMerkleTree'; - accounts: [ - { - name: 'authority'; - isMut: true; - isSigner: true; - }, - { - name: 'merkleTree'; - isMut: true; - isSigner: false; - }, - { - name: 'queue'; - isMut: true; - isSigner: false; - }, - { - name: 'registeredProgramPda'; - isMut: false; - isSigner: false; - isOptional: true; - }, - ]; - args: [ - { - name: 'bytes'; - type: 'bytes'; - }, - ]; - }, - { - name: 'initializeAddressMerkleTreeAndQueue'; - accounts: [ - { - name: 'authority'; - isMut: true; - isSigner: true; - }, - { - name: 'merkleTree'; - isMut: true; - isSigner: false; - }, - { - name: 'queue'; - isMut: true; - isSigner: false; - }, - { - name: 'registeredProgramPda'; - isMut: false; - isSigner: false; - isOptional: true; - }, - ]; - args: [ - { - name: 'index'; - type: 'u64'; - }, - { - name: 'programOwner'; - type: { - option: 'publicKey'; - }; - }, - { - name: 'forester'; - type: { - option: 'publicKey'; - }; - }, - { - name: 'addressMerkleTreeConfig'; - type: { - defined: 'AddressMerkleTreeConfig'; - }; - }, - { - name: 'addressQueueConfig'; - type: { - defined: 'AddressQueueConfig'; - }; - }, - ]; - }, - { - name: 'insertAddresses'; - accounts: [ - { - name: 'feePayer'; - isMut: true; - isSigner: true; - docs: ['Fee payer pays rollover fee.']; - }, - { - name: 'authority'; - isMut: false; - isSigner: true; - }, - { - name: 'registeredProgramPda'; - isMut: false; - isSigner: false; - isOptional: true; - }, - { - name: 'systemProgram'; - isMut: false; - isSigner: false; - }, - ]; - args: [ - { - name: 'addresses'; - type: { - vec: { - array: ['u8', 32]; - }; - }; - }, - ]; - }, - { - name: 'updateAddressMerkleTree'; - docs: ['Updates the address Merkle tree with a new address.']; - accounts: [ - { - name: 'authority'; - isMut: false; - isSigner: true; - }, - { - name: 'registeredProgramPda'; - isMut: false; - isSigner: false; - isOptional: true; - }, - { - name: 'queue'; - isMut: true; - isSigner: false; - }, - { - name: 'merkleTree'; - isMut: true; - isSigner: false; - }, - { - name: 'logWrapper'; - isMut: false; - isSigner: false; - }, - ]; - args: [ - { - name: 'changelogIndex'; - type: 'u16'; - }, - { - name: 'indexedChangelogIndex'; - type: 'u16'; - }, - { - name: 'value'; - type: 'u16'; - }, - { - name: 'lowAddressIndex'; - type: 'u64'; - }, - { - name: 'lowAddressValue'; - type: { - array: ['u8', 32]; - }; - }, - { - name: 'lowAddressNextIndex'; - type: 'u64'; - }, - { - name: 'lowAddressNextValue'; - type: { - array: ['u8', 32]; - }; - }, - { - name: 'lowAddressProof'; - type: { - array: [ - { - array: ['u8', 32]; - }, - 16, - ]; - }; - }, - ]; - }, - { - name: 'rolloverAddressMerkleTreeAndQueue'; - accounts: [ - { - name: 'feePayer'; - isMut: true; - isSigner: true; - docs: [ - 'Signer used to receive rollover accounts rentexemption reimbursement.', - ]; - }, - { - name: 'authority'; - isMut: false; - isSigner: true; - }, - { - name: 'registeredProgramPda'; - isMut: false; - isSigner: false; - isOptional: true; - }, - { - name: 'newAddressMerkleTree'; - isMut: true; - isSigner: false; - }, - { - name: 'newQueue'; - isMut: true; - isSigner: false; - }, - { - name: 'oldAddressMerkleTree'; - isMut: true; - isSigner: false; - }, - { - name: 'oldQueue'; - isMut: true; - isSigner: false; - }, - ]; - args: []; - }, - { - name: 'initializeGroupAuthority'; - docs: [ - 'initialize group (a group can be used to give multiple programs access', - 'to the same Merkle trees by registering the programs to the group)', - ]; - accounts: [ - { - name: 'authority'; - isMut: true; - isSigner: true; - }, - { - name: 'seed'; - isMut: false; - isSigner: true; - docs: [ - 'Seed public key used to derive the group authority.', - ]; - }, - { - name: 'groupAuthority'; - isMut: true; - isSigner: false; - }, - { - name: 'systemProgram'; - isMut: false; - isSigner: false; - }, - ]; - args: [ - { - name: 'authority'; - type: 'publicKey'; - }, - ]; - }, - { - name: 'updateGroupAuthority'; - accounts: [ - { - name: 'authority'; - isMut: false; - isSigner: true; - }, - { - name: 'groupAuthority'; - isMut: true; - isSigner: false; - }, - ]; - args: [ - { - name: 'authority'; - type: 'publicKey'; - }, - ]; - }, - { - name: 'registerProgramToGroup'; - accounts: [ - { - name: 'authority'; - isMut: true; - isSigner: true; - }, - { - name: 'programToBeRegistered'; - isMut: false; - isSigner: true; - }, - { - name: 'registeredProgramPda'; - isMut: true; - isSigner: false; - }, - { - name: 'groupAuthorityPda'; - isMut: false; - isSigner: false; - }, - { - name: 'systemProgram'; - isMut: false; - isSigner: false; - }, - ]; - args: []; - }, - { - name: 'deregisterProgram'; - accounts: [ - { - name: 'authority'; - isMut: true; - isSigner: true; - }, - { - name: 'registeredProgramPda'; - isMut: true; - isSigner: false; - }, - { - name: 'groupAuthorityPda'; - isMut: false; - isSigner: false; - }, - { - name: 'closeRecipient'; - isMut: true; - isSigner: false; - }, - ]; - args: []; - }, - { - name: 'initializeStateMerkleTreeAndNullifierQueue'; - docs: [ - 'Initializes a new Merkle tree from config bytes.', - 'Index is an optional identifier and not checked by the program.', - ]; - accounts: [ - { - name: 'authority'; - isMut: true; - isSigner: true; - }, - { - name: 'merkleTree'; - isMut: true; - isSigner: false; - }, - { - name: 'nullifierQueue'; - isMut: true; - isSigner: false; - }, - { - name: 'registeredProgramPda'; - isMut: false; - isSigner: false; - isOptional: true; - }, - ]; - args: [ - { - name: 'index'; - type: 'u64'; - }, - { - name: 'programOwner'; - type: { - option: 'publicKey'; - }; - }, - { - name: 'forester'; - type: { - option: 'publicKey'; - }; - }, - { - name: 'stateMerkleTreeConfig'; - type: { - defined: 'StateMerkleTreeConfig'; - }; - }, - { - name: 'nullifierQueueConfig'; - type: { - defined: 'NullifierQueueConfig'; - }; - }, - { - name: 'additionalBytes'; - type: 'u64'; - }, - ]; - }, - { - name: 'appendLeavesToMerkleTrees'; - accounts: [ - { - name: 'feePayer'; - isMut: true; - isSigner: true; - docs: ['Fee payer pays rollover fee.']; - }, - { - name: 'authority'; - isMut: false; - isSigner: true; - docs: [ - 'Checked whether instruction is accessed by a registered program or owner = authority.', - ]; - }, - { - name: 'registeredProgramPda'; - isMut: false; - isSigner: false; - isOptional: true; - docs: [ - 'Some assumes that the Merkle trees are accessed by a registered program.', - 'None assumes that the Merkle trees are accessed by its owner.', - ]; - }, - { - name: 'systemProgram'; - isMut: false; - isSigner: false; - }, - ]; - args: [ - { - name: 'leaves'; - type: { - vec: { - defined: '(u8,[u8;32])'; - }; - }; - }, - ]; - }, - { - name: 'nullifyLeaves'; - accounts: [ - { - name: 'authority'; - isMut: false; - isSigner: true; - }, - { - name: 'registeredProgramPda'; - isMut: false; - isSigner: false; - isOptional: true; - }, - { - name: 'logWrapper'; - isMut: false; - isSigner: false; - }, - { - name: 'merkleTree'; - isMut: true; - isSigner: false; - }, - { - name: 'nullifierQueue'; - isMut: true; - isSigner: false; - }, - ]; - args: [ - { - name: 'changeLogIndices'; - type: { - vec: 'u64'; - }; - }, - { - name: 'leavesQueueIndices'; - type: { - vec: 'u16'; - }; - }, - { - name: 'leafIndices'; - type: { - vec: 'u64'; - }; - }, - { - name: 'proofs'; - type: { - vec: { - vec: { - array: ['u8', 32]; - }; - }; - }; - }, - ]; - }, - { - name: 'insertIntoNullifierQueues'; - accounts: [ - { - name: 'feePayer'; - isMut: true; - isSigner: true; - docs: ['Fee payer pays rollover fee.']; - }, - { - name: 'authority'; - isMut: false; - isSigner: true; - }, - { - name: 'registeredProgramPda'; - isMut: false; - isSigner: false; - isOptional: true; - }, - { - name: 'systemProgram'; - isMut: false; - isSigner: false; - }, - ]; - args: [ - { - name: 'nullifiers'; - type: { - vec: { - array: ['u8', 32]; - }; - }; - }, - { - name: 'leafIndices'; - type: { - vec: 'u32'; - }; - }, - { - name: 'txHash'; - type: { - option: { - array: ['u8', 32]; - }; - }; - }, - ]; - }, - { - name: 'rolloverStateMerkleTreeAndNullifierQueue'; - accounts: [ - { - name: 'feePayer'; - isMut: true; - isSigner: true; - docs: [ - 'Signer used to receive rollover accounts rentexemption reimbursement.', - ]; - }, - { - name: 'authority'; - isMut: false; - isSigner: true; - }, - { - name: 'registeredProgramPda'; - isMut: false; - isSigner: false; - isOptional: true; - }, - { - name: 'newStateMerkleTree'; - isMut: true; - isSigner: false; - }, - { - name: 'newNullifierQueue'; - isMut: true; - isSigner: false; - }, - { - name: 'oldStateMerkleTree'; - isMut: true; - isSigner: false; - }, - { - name: 'oldNullifierQueue'; - isMut: true; - isSigner: false; - }, - ]; - args: []; - }, - { - name: 'batchNullify'; - accounts: [ - { - name: 'authority'; - isMut: false; - isSigner: true; - }, - { - name: 'registeredProgramPda'; - isMut: false; - isSigner: false; - isOptional: true; - }, - { - name: 'logWrapper'; - isMut: false; - isSigner: false; - }, - { - name: 'merkleTree'; - isMut: true; - isSigner: false; - }, - ]; - args: [ - { - name: 'data'; - type: 'bytes'; - }, - ]; - }, - { - name: 'batchAppend'; - accounts: [ - { - name: 'authority'; - isMut: false; - isSigner: true; - }, - { - name: 'registeredProgramPda'; - isMut: false; - isSigner: false; - isOptional: true; - }, - { - name: 'logWrapper'; - isMut: false; - isSigner: false; - }, - { - name: 'merkleTree'; - isMut: true; - isSigner: false; - }, - { - name: 'outputQueue'; - isMut: true; - isSigner: false; - }, - ]; - args: [ - { - name: 'data'; - type: 'bytes'; - }, - ]; - }, - { - name: 'batchUpdateAddressTree'; - accounts: [ - { - name: 'authority'; - isMut: false; - isSigner: true; - }, - { - name: 'registeredProgramPda'; - isMut: false; - isSigner: false; - isOptional: true; - }, - { - name: 'logWrapper'; - isMut: false; - isSigner: false; - }, - { - name: 'merkleTree'; - isMut: true; - isSigner: false; - }, - ]; - args: [ - { - name: 'data'; - type: 'bytes'; - }, - ]; - }, - { - name: 'intializeBatchedAddressMerkleTree'; - accounts: [ - { - name: 'authority'; - isMut: true; - isSigner: true; - }, - { - name: 'merkleTree'; - isMut: true; - isSigner: false; - }, - { - name: 'registeredProgramPda'; - isMut: false; - isSigner: false; - isOptional: true; - }, - ]; - args: [ - { - name: 'bytes'; - type: 'bytes'; - }, - ]; - }, - { - name: 'rolloverBatchAddressMerkleTree'; - accounts: [ - { - name: 'feePayer'; - isMut: true; - isSigner: true; - docs: [ - 'Signer used to receive rollover accounts rentexemption reimbursement.', - ]; - }, - { - name: 'authority'; - isMut: false; - isSigner: true; - }, - { - name: 'registeredProgramPda'; - isMut: false; - isSigner: false; - isOptional: true; - }, - { - name: 'newAddressMerkleTree'; - isMut: true; - isSigner: false; - }, - { - name: 'oldAddressMerkleTree'; - isMut: true; - isSigner: false; - }, - ]; - args: [ - { - name: 'networkFee'; - type: { - option: 'u64'; - }; - }, - ]; - }, - { - name: 'rolloverBatchStateMerkleTree'; - accounts: [ - { - name: 'feePayer'; - isMut: true; - isSigner: true; - docs: [ - 'Signer used to receive rollover accounts rentexemption reimbursement.', - ]; - }, - { - name: 'authority'; - isMut: false; - isSigner: true; - }, - { - name: 'registeredProgramPda'; - isMut: false; - isSigner: false; - isOptional: true; - }, - { - name: 'newStateMerkleTree'; - isMut: true; - isSigner: false; - }, - { - name: 'oldStateMerkleTree'; - isMut: true; - isSigner: false; - }, - { - name: 'newOutputQueue'; - isMut: true; - isSigner: false; - }, - { - name: 'oldOutputQueue'; - isMut: true; - isSigner: false; - }, - ]; - args: [ - { - name: 'additionalBytes'; - type: 'u64'; - }, - { - name: 'networkFee'; - type: { - option: 'u64'; - }; - }, - ]; - }, - { - name: 'migrateState'; - accounts: [ - { - name: 'authority'; - isMut: false; - isSigner: true; - }, - { - name: 'registeredProgramPda'; - isMut: false; - isSigner: false; - isOptional: true; - }, - { - name: 'logWrapper'; - isMut: false; - isSigner: false; - }, - { - name: 'merkleTree'; - isMut: true; - isSigner: false; - }, - { - name: 'outputQueue'; - isMut: true; - isSigner: false; - }, - ]; - args: [ - { - name: 'input'; - type: { - defined: 'MigrateLeafParams'; - }; - }, - ]; - }, - ]; - accounts: [ - { - name: 'registeredProgram'; - type: { - kind: 'struct'; - fields: [ - { - name: 'registeredProgramId'; - type: 'publicKey'; - }, - { - name: 'groupAuthorityPda'; - type: 'publicKey'; - }, - ]; - }; - }, - { - name: 'addressMerkleTreeAccount'; - type: { - kind: 'struct'; - fields: [ - { - name: 'metadata'; - type: { - defined: 'MerkleTreeMetadata'; - }; - }, - ]; - }; - }, - { - name: 'groupAuthority'; - type: { - kind: 'struct'; - fields: [ - { - name: 'authority'; - type: 'publicKey'; - }, - { - name: 'seed'; - type: 'publicKey'; - }, - ]; - }; - }, - { - name: 'stateMerkleTreeAccount'; - docs: [ - 'Concurrent state Merkle tree used for public compressed transactions.', - ]; - type: { - kind: 'struct'; - fields: [ - { - name: 'metadata'; - type: { - defined: 'MerkleTreeMetadata'; - }; - }, - ]; - }; - }, - { - name: 'queueAccount'; - type: { - kind: 'struct'; - fields: [ - { - name: 'metadata'; - type: { - defined: 'QueueMetadata'; - }; - }, - ]; - }; - }, - ]; - types: [ - { - name: 'ZeroOutLeafIndex'; - type: { - kind: 'struct'; - fields: [ - { - name: 'treeIndex'; - type: 'u8'; - }, - { - name: 'batchIndex'; - type: 'u8'; - }, - { - name: 'leafIndex'; - type: 'u16'; - }, - ]; - }; - }, - { - name: 'AddressMerkleTreeConfig'; - type: { - kind: 'struct'; - fields: [ - { - name: 'height'; - type: 'u32'; - }, - { - name: 'changelogSize'; - type: 'u64'; - }, - { - name: 'rootsSize'; - type: 'u64'; - }, - { - name: 'canopyDepth'; - type: 'u64'; - }, - { - name: 'addressChangelogSize'; - type: 'u64'; - }, - { - name: 'networkFee'; - type: { - option: 'u64'; - }; - }, - { - name: 'rolloverThreshold'; - type: { - option: 'u64'; - }; - }, - { - name: 'closeThreshold'; - type: { - option: 'u64'; - }; - }, - ]; - }; - }, - { - name: 'StateMerkleTreeConfig'; - type: { - kind: 'struct'; - fields: [ - { - name: 'height'; - type: 'u32'; - }, - { - name: 'changelogSize'; - type: 'u64'; - }, - { - name: 'rootsSize'; - type: 'u64'; - }, - { - name: 'canopyDepth'; - type: 'u64'; - }, - { - name: 'networkFee'; - type: { - option: 'u64'; - }; - }, - { - name: 'rolloverThreshold'; - type: { - option: 'u64'; - }; - }, - { - name: 'closeThreshold'; - type: { - option: 'u64'; - }; - }, - ]; - }; - }, - { - name: 'NullifierQueueConfig'; - type: { - kind: 'struct'; - fields: [ - { - name: 'capacity'; - type: 'u16'; - }, - { - name: 'sequenceThreshold'; - type: 'u64'; - }, - { - name: 'networkFee'; - type: { - option: 'u64'; - }; - }, - ]; - }; - }, - { - name: 'MigrateLeafParams'; - type: { - kind: 'struct'; - fields: [ - { - name: 'changeLogIndex'; - type: 'u64'; - }, - { - name: 'leaf'; - type: { - array: ['u8', 32]; - }; - }, - { - name: 'leafIndex'; - type: 'u64'; - }, - { - name: 'proof'; - type: { - array: [ - { - array: ['u8', 32]; - }, - 16, - ]; - }; - }, - ]; - }; - }, - { - name: 'AddressQueueConfig'; - type: { - kind: 'alias'; - value: { - defined: 'NullifierQueueConfig'; - }; - }; - }, - ]; - errors: [ - { - code: 6000; - name: 'IntegerOverflow'; - msg: 'Integer overflow'; - }, - { - code: 6001; - name: 'InvalidAuthority'; - msg: 'InvalidAuthority'; - }, - { - code: 6002; - name: 'NumberOfLeavesMismatch'; - msg: 'Leaves <> remaining accounts mismatch. The number of remaining accounts must match the number of leaves.'; - }, - { - code: 6003; - name: 'InvalidNoopPubkey'; - msg: 'Provided noop program public key is invalid'; - }, - { - code: 6004; - name: 'NumberOfChangeLogIndicesMismatch'; - msg: 'Number of change log indices mismatch'; - }, - { - code: 6005; - name: 'NumberOfIndicesMismatch'; - msg: 'Number of indices mismatch'; - }, - { - code: 6006; - name: 'NumberOfProofsMismatch'; - msg: 'NumberOfProofsMismatch'; - }, - { - code: 6007; - name: 'InvalidMerkleProof'; - msg: 'InvalidMerkleProof'; - }, - { - code: 6008; - name: 'LeafNotFound'; - msg: 'Could not find the leaf in the queue'; - }, - { - code: 6009; - name: 'MerkleTreeAndQueueNotAssociated'; - msg: 'MerkleTreeAndQueueNotAssociated'; - }, - { - code: 6010; - name: 'MerkleTreeAlreadyRolledOver'; - msg: 'MerkleTreeAlreadyRolledOver'; - }, - { - code: 6011; - name: 'NotReadyForRollover'; - msg: 'NotReadyForRollover'; - }, - { - code: 6012; - name: 'RolloverNotConfigured'; - msg: 'RolloverNotConfigured'; - }, - { - code: 6013; - name: 'NotAllLeavesProcessed'; - msg: 'NotAllLeavesProcessed'; - }, - { - code: 6014; - name: 'InvalidQueueType'; - msg: 'InvalidQueueType'; - }, - { - code: 6015; - name: 'InputElementsEmpty'; - msg: 'InputElementsEmpty'; - }, - { - code: 6016; - name: 'NoLeavesForMerkleTree'; - msg: 'NoLeavesForMerkleTree'; - }, - { - code: 6017; - name: 'InvalidAccountSize'; - msg: 'InvalidAccountSize'; - }, - { - code: 6018; - name: 'InsufficientRolloverFee'; - msg: 'InsufficientRolloverFee'; - }, - { - code: 6019; - name: 'UnsupportedHeight'; - msg: 'Unsupported Merkle tree height'; - }, - { - code: 6020; - name: 'UnsupportedCanopyDepth'; - msg: 'Unsupported canopy depth'; - }, - { - code: 6021; - name: 'InvalidSequenceThreshold'; - msg: 'Invalid sequence threshold'; - }, - { - code: 6022; - name: 'UnsupportedCloseThreshold'; - msg: 'Unsupported close threshold'; - }, - { - code: 6023; - name: 'InvalidAccountBalance'; - msg: 'InvalidAccountBalance'; - }, - { - code: 6024; - name: 'UnsupportedAdditionalBytes'; - }, - { - code: 6025; - name: 'InvalidGroup'; - }, - { - code: 6026; - name: 'ProofLengthMismatch'; - }, - { - code: 6027; - name: 'TxHashUndefined'; - }, - { - code: 6028; - name: 'InputDeserializationFailed'; - }, - { - code: 6029; - name: 'UnsupportedParameters'; - }, - { - code: 6030; - name: 'AddressMerkleTreeAccountDiscriminatorMismatch'; - }, - { - code: 6031; - name: 'StateMerkleTreeAccountDiscriminatorMismatch'; - }, - { - code: 6032; - name: 'RegistryProgramIsNone'; - }, - { - code: 6033; - name: 'EmptyLeaf'; - }, - ]; -}; - -export const IDL: AccountCompression = { - version: '1.2.0', - name: 'account_compression', - constants: [ - { - name: 'CPI_AUTHORITY_PDA_SEED', - type: 'bytes', - value: '[99, 112, 105, 95, 97, 117, 116, 104, 111, 114, 105, 116, 121]', - }, - { - name: 'GROUP_AUTHORITY_SEED', - type: 'bytes', - value: '[103, 114, 111, 117, 112, 95, 97, 117, 116, 104, 111, 114, 105, 116, 121]', - }, - { - name: 'STATE_MERKLE_TREE_HEIGHT', - type: 'u64', - value: '26', - }, - { - name: 'STATE_MERKLE_TREE_CHANGELOG', - type: 'u64', - value: '1400', - }, - { - name: 'STATE_MERKLE_TREE_ROOTS', - type: 'u64', - value: '2400', - }, - { - name: 'STATE_MERKLE_TREE_CANOPY_DEPTH', - type: 'u64', - value: '10', - }, - { - name: 'STATE_NULLIFIER_QUEUE_VALUES', - type: 'u16', - value: '28_807', - }, - { - name: 'STATE_NULLIFIER_QUEUE_SEQUENCE_THRESHOLD', - type: 'u64', - value: '2400', - }, - { - name: 'ADDRESS_MERKLE_TREE_HEIGHT', - type: 'u64', - value: '26', - }, - { - name: 'ADDRESS_MERKLE_TREE_CHANGELOG', - type: 'u64', - value: '1400', - }, - { - name: 'ADDRESS_MERKLE_TREE_ROOTS', - type: 'u64', - value: '2400', - }, - { - name: 'ADDRESS_MERKLE_TREE_CANOPY_DEPTH', - type: 'u64', - value: '10', - }, - { - name: 'ADDRESS_MERKLE_TREE_INDEXED_CHANGELOG', - type: 'u64', - value: '1400', - }, - { - name: 'ADDRESS_QUEUE_VALUES', - type: 'u16', - value: '28_807', - }, - { - name: 'ADDRESS_QUEUE_SEQUENCE_THRESHOLD', - type: 'u64', - value: '2400', - }, - { - name: 'NOOP_PUBKEY', - type: { - array: ['u8', 32], - }, - value: '[11 , 188 , 15 , 192 , 187 , 71 , 202 , 47 , 116 , 196 , 17 , 46 , 148 , 171 , 19 , 207 , 163 , 198 , 52 , 229 , 220 , 23 , 234 , 203 , 3 , 205 , 26 , 35 , 205 , 126 , 120 , 124 ,]', - }, - ], - instructions: [ - { - name: 'initializeBatchedStateMerkleTree', - accounts: [ - { - name: 'authority', - isMut: true, - isSigner: true, - }, - { - name: 'merkleTree', - isMut: true, - isSigner: false, - }, - { - name: 'queue', - isMut: true, - isSigner: false, - }, - { - name: 'registeredProgramPda', - isMut: false, - isSigner: false, - isOptional: true, - }, - ], - args: [ - { - name: 'bytes', - type: 'bytes', - }, - ], - }, - { - name: 'initializeAddressMerkleTreeAndQueue', - accounts: [ - { - name: 'authority', - isMut: true, - isSigner: true, - }, - { - name: 'merkleTree', - isMut: true, - isSigner: false, - }, - { - name: 'queue', - isMut: true, - isSigner: false, - }, - { - name: 'registeredProgramPda', - isMut: false, - isSigner: false, - isOptional: true, - }, - ], - args: [ - { - name: 'index', - type: 'u64', - }, - { - name: 'programOwner', - type: { - option: 'publicKey', - }, - }, - { - name: 'forester', - type: { - option: 'publicKey', - }, - }, - { - name: 'addressMerkleTreeConfig', - type: { - defined: 'AddressMerkleTreeConfig', - }, - }, - { - name: 'addressQueueConfig', - type: { - defined: 'AddressQueueConfig', - }, - }, - ], - }, - { - name: 'insertAddresses', - accounts: [ - { - name: 'feePayer', - isMut: true, - isSigner: true, - docs: ['Fee payer pays rollover fee.'], - }, - { - name: 'authority', - isMut: false, - isSigner: true, - }, - { - name: 'registeredProgramPda', - isMut: false, - isSigner: false, - isOptional: true, - }, - { - name: 'systemProgram', - isMut: false, - isSigner: false, - }, - ], - args: [ - { - name: 'addresses', - type: { - vec: { - array: ['u8', 32], - }, - }, - }, - ], - }, - { - name: 'updateAddressMerkleTree', - docs: ['Updates the address Merkle tree with a new address.'], - accounts: [ - { - name: 'authority', - isMut: false, - isSigner: true, - }, - { - name: 'registeredProgramPda', - isMut: false, - isSigner: false, - isOptional: true, - }, - { - name: 'queue', - isMut: true, - isSigner: false, - }, - { - name: 'merkleTree', - isMut: true, - isSigner: false, - }, - { - name: 'logWrapper', - isMut: false, - isSigner: false, - }, - ], - args: [ - { - name: 'changelogIndex', - type: 'u16', - }, - { - name: 'indexedChangelogIndex', - type: 'u16', - }, - { - name: 'value', - type: 'u16', - }, - { - name: 'lowAddressIndex', - type: 'u64', - }, - { - name: 'lowAddressValue', - type: { - array: ['u8', 32], - }, - }, - { - name: 'lowAddressNextIndex', - type: 'u64', - }, - { - name: 'lowAddressNextValue', - type: { - array: ['u8', 32], - }, - }, - { - name: 'lowAddressProof', - type: { - array: [ - { - array: ['u8', 32], - }, - 16, - ], - }, - }, - ], - }, - { - name: 'rolloverAddressMerkleTreeAndQueue', - accounts: [ - { - name: 'feePayer', - isMut: true, - isSigner: true, - docs: [ - 'Signer used to receive rollover accounts rentexemption reimbursement.', - ], - }, - { - name: 'authority', - isMut: false, - isSigner: true, - }, - { - name: 'registeredProgramPda', - isMut: false, - isSigner: false, - isOptional: true, - }, - { - name: 'newAddressMerkleTree', - isMut: true, - isSigner: false, - }, - { - name: 'newQueue', - isMut: true, - isSigner: false, - }, - { - name: 'oldAddressMerkleTree', - isMut: true, - isSigner: false, - }, - { - name: 'oldQueue', - isMut: true, - isSigner: false, - }, - ], - args: [], - }, - { - name: 'initializeGroupAuthority', - docs: [ - 'initialize group (a group can be used to give multiple programs access', - 'to the same Merkle trees by registering the programs to the group)', - ], - accounts: [ - { - name: 'authority', - isMut: true, - isSigner: true, - }, - { - name: 'seed', - isMut: false, - isSigner: true, - docs: [ - 'Seed public key used to derive the group authority.', - ], - }, - { - name: 'groupAuthority', - isMut: true, - isSigner: false, - }, - { - name: 'systemProgram', - isMut: false, - isSigner: false, - }, - ], - args: [ - { - name: 'authority', - type: 'publicKey', - }, - ], - }, - { - name: 'updateGroupAuthority', - accounts: [ - { - name: 'authority', - isMut: false, - isSigner: true, - }, - { - name: 'groupAuthority', - isMut: true, - isSigner: false, - }, - ], - args: [ - { - name: 'authority', - type: 'publicKey', - }, - ], - }, - { - name: 'registerProgramToGroup', - accounts: [ - { - name: 'authority', - isMut: true, - isSigner: true, - }, - { - name: 'programToBeRegistered', - isMut: false, - isSigner: true, - }, - { - name: 'registeredProgramPda', - isMut: true, - isSigner: false, - }, - { - name: 'groupAuthorityPda', - isMut: false, - isSigner: false, - }, - { - name: 'systemProgram', - isMut: false, - isSigner: false, - }, - ], - args: [], - }, - { - name: 'deregisterProgram', - accounts: [ - { - name: 'authority', - isMut: true, - isSigner: true, - }, - { - name: 'registeredProgramPda', - isMut: true, - isSigner: false, - }, - { - name: 'groupAuthorityPda', - isMut: false, - isSigner: false, - }, - { - name: 'closeRecipient', - isMut: true, - isSigner: false, - }, - ], - args: [], - }, - { - name: 'initializeStateMerkleTreeAndNullifierQueue', - docs: [ - 'Initializes a new Merkle tree from config bytes.', - 'Index is an optional identifier and not checked by the program.', - ], - accounts: [ - { - name: 'authority', - isMut: true, - isSigner: true, - }, - { - name: 'merkleTree', - isMut: true, - isSigner: false, - }, - { - name: 'nullifierQueue', - isMut: true, - isSigner: false, - }, - { - name: 'registeredProgramPda', - isMut: false, - isSigner: false, - isOptional: true, - }, - ], - args: [ - { - name: 'index', - type: 'u64', - }, - { - name: 'programOwner', - type: { - option: 'publicKey', - }, - }, - { - name: 'forester', - type: { - option: 'publicKey', - }, - }, - { - name: 'stateMerkleTreeConfig', - type: { - defined: 'StateMerkleTreeConfig', - }, - }, - { - name: 'nullifierQueueConfig', - type: { - defined: 'NullifierQueueConfig', - }, - }, - { - name: 'additionalBytes', - type: 'u64', - }, - ], - }, - { - name: 'appendLeavesToMerkleTrees', - accounts: [ - { - name: 'feePayer', - isMut: true, - isSigner: true, - docs: ['Fee payer pays rollover fee.'], - }, - { - name: 'authority', - isMut: false, - isSigner: true, - docs: [ - 'Checked whether instruction is accessed by a registered program or owner = authority.', - ], - }, - { - name: 'registeredProgramPda', - isMut: false, - isSigner: false, - isOptional: true, - docs: [ - 'Some assumes that the Merkle trees are accessed by a registered program.', - 'None assumes that the Merkle trees are accessed by its owner.', - ], - }, - { - name: 'systemProgram', - isMut: false, - isSigner: false, - }, - ], - args: [ - { - name: 'leaves', - type: { - vec: { - defined: '(u8,[u8;32])', - }, - }, - }, - ], - }, - { - name: 'nullifyLeaves', - accounts: [ - { - name: 'authority', - isMut: false, - isSigner: true, - }, - { - name: 'registeredProgramPda', - isMut: false, - isSigner: false, - isOptional: true, - }, - { - name: 'logWrapper', - isMut: false, - isSigner: false, - }, - { - name: 'merkleTree', - isMut: true, - isSigner: false, - }, - { - name: 'nullifierQueue', - isMut: true, - isSigner: false, - }, - ], - args: [ - { - name: 'changeLogIndices', - type: { - vec: 'u64', - }, - }, - { - name: 'leavesQueueIndices', - type: { - vec: 'u16', - }, - }, - { - name: 'leafIndices', - type: { - vec: 'u64', - }, - }, - { - name: 'proofs', - type: { - vec: { - vec: { - array: ['u8', 32], - }, - }, - }, - }, - ], - }, - { - name: 'insertIntoNullifierQueues', - accounts: [ - { - name: 'feePayer', - isMut: true, - isSigner: true, - docs: ['Fee payer pays rollover fee.'], - }, - { - name: 'authority', - isMut: false, - isSigner: true, - }, - { - name: 'registeredProgramPda', - isMut: false, - isSigner: false, - isOptional: true, - }, - { - name: 'systemProgram', - isMut: false, - isSigner: false, - }, - ], - args: [ - { - name: 'nullifiers', - type: { - vec: { - array: ['u8', 32], - }, - }, - }, - { - name: 'leafIndices', - type: { - vec: 'u32', - }, - }, - { - name: 'txHash', - type: { - option: { - array: ['u8', 32], - }, - }, - }, - ], - }, - { - name: 'rolloverStateMerkleTreeAndNullifierQueue', - accounts: [ - { - name: 'feePayer', - isMut: true, - isSigner: true, - docs: [ - 'Signer used to receive rollover accounts rentexemption reimbursement.', - ], - }, - { - name: 'authority', - isMut: false, - isSigner: true, - }, - { - name: 'registeredProgramPda', - isMut: false, - isSigner: false, - isOptional: true, - }, - { - name: 'newStateMerkleTree', - isMut: true, - isSigner: false, - }, - { - name: 'newNullifierQueue', - isMut: true, - isSigner: false, - }, - { - name: 'oldStateMerkleTree', - isMut: true, - isSigner: false, - }, - { - name: 'oldNullifierQueue', - isMut: true, - isSigner: false, - }, - ], - args: [], - }, - { - name: 'batchNullify', - accounts: [ - { - name: 'authority', - isMut: false, - isSigner: true, - }, - { - name: 'registeredProgramPda', - isMut: false, - isSigner: false, - isOptional: true, - }, - { - name: 'logWrapper', - isMut: false, - isSigner: false, - }, - { - name: 'merkleTree', - isMut: true, - isSigner: false, - }, - ], - args: [ - { - name: 'data', - type: 'bytes', - }, - ], - }, - { - name: 'batchAppend', - accounts: [ - { - name: 'authority', - isMut: false, - isSigner: true, - }, - { - name: 'registeredProgramPda', - isMut: false, - isSigner: false, - isOptional: true, - }, - { - name: 'logWrapper', - isMut: false, - isSigner: false, - }, - { - name: 'merkleTree', - isMut: true, - isSigner: false, - }, - { - name: 'outputQueue', - isMut: true, - isSigner: false, - }, - ], - args: [ - { - name: 'data', - type: 'bytes', - }, - ], - }, - { - name: 'batchUpdateAddressTree', - accounts: [ - { - name: 'authority', - isMut: false, - isSigner: true, - }, - { - name: 'registeredProgramPda', - isMut: false, - isSigner: false, - isOptional: true, - }, - { - name: 'logWrapper', - isMut: false, - isSigner: false, - }, - { - name: 'merkleTree', - isMut: true, - isSigner: false, - }, - ], - args: [ - { - name: 'data', - type: 'bytes', - }, - ], - }, - { - name: 'intializeBatchedAddressMerkleTree', - accounts: [ - { - name: 'authority', - isMut: true, - isSigner: true, - }, - { - name: 'merkleTree', - isMut: true, - isSigner: false, - }, - { - name: 'registeredProgramPda', - isMut: false, - isSigner: false, - isOptional: true, - }, - ], - args: [ - { - name: 'bytes', - type: 'bytes', - }, - ], - }, - { - name: 'rolloverBatchAddressMerkleTree', - accounts: [ - { - name: 'feePayer', - isMut: true, - isSigner: true, - docs: [ - 'Signer used to receive rollover accounts rentexemption reimbursement.', - ], - }, - { - name: 'authority', - isMut: false, - isSigner: true, - }, - { - name: 'registeredProgramPda', - isMut: false, - isSigner: false, - isOptional: true, - }, - { - name: 'newAddressMerkleTree', - isMut: true, - isSigner: false, - }, - { - name: 'oldAddressMerkleTree', - isMut: true, - isSigner: false, - }, - ], - args: [ - { - name: 'networkFee', - type: { - option: 'u64', - }, - }, - ], - }, - { - name: 'rolloverBatchStateMerkleTree', - accounts: [ - { - name: 'feePayer', - isMut: true, - isSigner: true, - docs: [ - 'Signer used to receive rollover accounts rentexemption reimbursement.', - ], - }, - { - name: 'authority', - isMut: false, - isSigner: true, - }, - { - name: 'registeredProgramPda', - isMut: false, - isSigner: false, - isOptional: true, - }, - { - name: 'newStateMerkleTree', - isMut: true, - isSigner: false, - }, - { - name: 'oldStateMerkleTree', - isMut: true, - isSigner: false, - }, - { - name: 'newOutputQueue', - isMut: true, - isSigner: false, - }, - { - name: 'oldOutputQueue', - isMut: true, - isSigner: false, - }, - ], - args: [ - { - name: 'additionalBytes', - type: 'u64', - }, - { - name: 'networkFee', - type: { - option: 'u64', - }, - }, - ], - }, - { - name: 'migrateState', - accounts: [ - { - name: 'authority', - isMut: false, - isSigner: true, - }, - { - name: 'registeredProgramPda', - isMut: false, - isSigner: false, - isOptional: true, - }, - { - name: 'logWrapper', - isMut: false, - isSigner: false, - }, - { - name: 'merkleTree', - isMut: true, - isSigner: false, - }, - { - name: 'outputQueue', - isMut: true, - isSigner: false, - }, - ], - args: [ - { - name: 'input', - type: { - defined: 'MigrateLeafParams', - }, - }, - ], - }, - ], - accounts: [ - { - name: 'registeredProgram', - type: { - kind: 'struct', - fields: [ - { - name: 'registeredProgramId', - type: 'publicKey', - }, - { - name: 'groupAuthorityPda', - type: 'publicKey', - }, - ], - }, - }, - { - name: 'addressMerkleTreeAccount', - type: { - kind: 'struct', - fields: [ - { - name: 'metadata', - type: { - defined: 'MerkleTreeMetadata', - }, - }, - ], - }, - }, - { - name: 'groupAuthority', - type: { - kind: 'struct', - fields: [ - { - name: 'authority', - type: 'publicKey', - }, - { - name: 'seed', - type: 'publicKey', - }, - ], - }, - }, - { - name: 'stateMerkleTreeAccount', - docs: [ - 'Concurrent state Merkle tree used for public compressed transactions.', - ], - type: { - kind: 'struct', - fields: [ - { - name: 'metadata', - type: { - defined: 'MerkleTreeMetadata', - }, - }, - ], - }, - }, - { - name: 'queueAccount', - type: { - kind: 'struct', - fields: [ - { - name: 'metadata', - type: { - defined: 'QueueMetadata', - }, - }, - ], - }, - }, - ], - types: [ - { - name: 'ZeroOutLeafIndex', - type: { - kind: 'struct', - fields: [ - { - name: 'treeIndex', - type: 'u8', - }, - { - name: 'batchIndex', - type: 'u8', - }, - { - name: 'leafIndex', - type: 'u16', - }, - ], - }, - }, - { - name: 'AddressMerkleTreeConfig', - type: { - kind: 'struct', - fields: [ - { - name: 'height', - type: 'u32', - }, - { - name: 'changelogSize', - type: 'u64', - }, - { - name: 'rootsSize', - type: 'u64', - }, - { - name: 'canopyDepth', - type: 'u64', - }, - { - name: 'addressChangelogSize', - type: 'u64', - }, - { - name: 'networkFee', - type: { - option: 'u64', - }, - }, - { - name: 'rolloverThreshold', - type: { - option: 'u64', - }, - }, - { - name: 'closeThreshold', - type: { - option: 'u64', - }, - }, - ], - }, - }, - { - name: 'StateMerkleTreeConfig', - type: { - kind: 'struct', - fields: [ - { - name: 'height', - type: 'u32', - }, - { - name: 'changelogSize', - type: 'u64', - }, - { - name: 'rootsSize', - type: 'u64', - }, - { - name: 'canopyDepth', - type: 'u64', - }, - { - name: 'networkFee', - type: { - option: 'u64', - }, - }, - { - name: 'rolloverThreshold', - type: { - option: 'u64', - }, - }, - { - name: 'closeThreshold', - type: { - option: 'u64', - }, - }, - ], - }, - }, - { - name: 'NullifierQueueConfig', - type: { - kind: 'struct', - fields: [ - { - name: 'capacity', - type: 'u16', - }, - { - name: 'sequenceThreshold', - type: 'u64', - }, - { - name: 'networkFee', - type: { - option: 'u64', - }, - }, - ], - }, - }, - { - name: 'MigrateLeafParams', - type: { - kind: 'struct', - fields: [ - { - name: 'changeLogIndex', - type: 'u64', - }, - { - name: 'leaf', - type: { - array: ['u8', 32], - }, - }, - { - name: 'leafIndex', - type: 'u64', - }, - { - name: 'proof', - type: { - array: [ - { - array: ['u8', 32], - }, - 16, - ], - }, - }, - ], - }, - }, - { - name: 'AddressQueueConfig', - type: { - kind: 'alias', - value: { - defined: 'NullifierQueueConfig', - }, - }, - }, - ], - errors: [ - { - code: 6000, - name: 'IntegerOverflow', - msg: 'Integer overflow', - }, - { - code: 6001, - name: 'InvalidAuthority', - msg: 'InvalidAuthority', - }, - { - code: 6002, - name: 'NumberOfLeavesMismatch', - msg: 'Leaves <> remaining accounts mismatch. The number of remaining accounts must match the number of leaves.', - }, - { - code: 6003, - name: 'InvalidNoopPubkey', - msg: 'Provided noop program public key is invalid', - }, - { - code: 6004, - name: 'NumberOfChangeLogIndicesMismatch', - msg: 'Number of change log indices mismatch', - }, - { - code: 6005, - name: 'NumberOfIndicesMismatch', - msg: 'Number of indices mismatch', - }, - { - code: 6006, - name: 'NumberOfProofsMismatch', - msg: 'NumberOfProofsMismatch', - }, - { - code: 6007, - name: 'InvalidMerkleProof', - msg: 'InvalidMerkleProof', - }, - { - code: 6008, - name: 'LeafNotFound', - msg: 'Could not find the leaf in the queue', - }, - { - code: 6009, - name: 'MerkleTreeAndQueueNotAssociated', - msg: 'MerkleTreeAndQueueNotAssociated', - }, - { - code: 6010, - name: 'MerkleTreeAlreadyRolledOver', - msg: 'MerkleTreeAlreadyRolledOver', - }, - { - code: 6011, - name: 'NotReadyForRollover', - msg: 'NotReadyForRollover', - }, - { - code: 6012, - name: 'RolloverNotConfigured', - msg: 'RolloverNotConfigured', - }, - { - code: 6013, - name: 'NotAllLeavesProcessed', - msg: 'NotAllLeavesProcessed', - }, - { - code: 6014, - name: 'InvalidQueueType', - msg: 'InvalidQueueType', - }, - { - code: 6015, - name: 'InputElementsEmpty', - msg: 'InputElementsEmpty', - }, - { - code: 6016, - name: 'NoLeavesForMerkleTree', - msg: 'NoLeavesForMerkleTree', - }, - { - code: 6017, - name: 'InvalidAccountSize', - msg: 'InvalidAccountSize', - }, - { - code: 6018, - name: 'InsufficientRolloverFee', - msg: 'InsufficientRolloverFee', - }, - { - code: 6019, - name: 'UnsupportedHeight', - msg: 'Unsupported Merkle tree height', - }, - { - code: 6020, - name: 'UnsupportedCanopyDepth', - msg: 'Unsupported canopy depth', - }, - { - code: 6021, - name: 'InvalidSequenceThreshold', - msg: 'Invalid sequence threshold', - }, - { - code: 6022, - name: 'UnsupportedCloseThreshold', - msg: 'Unsupported close threshold', - }, - { - code: 6023, - name: 'InvalidAccountBalance', - msg: 'InvalidAccountBalance', - }, - { - code: 6024, - name: 'UnsupportedAdditionalBytes', - }, - { - code: 6025, - name: 'InvalidGroup', - }, - { - code: 6026, - name: 'ProofLengthMismatch', - }, - { - code: 6027, - name: 'TxHashUndefined', - }, - { - code: 6028, - name: 'InputDeserializationFailed', - }, - { - code: 6029, - name: 'UnsupportedParameters', - }, - { - code: 6030, - name: 'AddressMerkleTreeAccountDiscriminatorMismatch', - }, - { - code: 6031, - name: 'StateMerkleTreeAccountDiscriminatorMismatch', - }, - { - code: 6032, - name: 'RegistryProgramIsNone', - }, - { - code: 6033, - name: 'EmptyLeaf', - }, - ], -}; diff --git a/js/stateless.js/src/idls/index.ts b/js/stateless.js/src/idls/index.ts deleted file mode 100644 index a4c0de64e8..0000000000 --- a/js/stateless.js/src/idls/index.ts +++ /dev/null @@ -1,26 +0,0 @@ -import { - IDL as AccountCompressionIDL, - AccountCompression, -} from './account_compression'; - -import { IDL as LightRegistryIDL, LightRegistry } from './light_registry'; -import { - IDL as LightSystemIDL, - LightSystemProgram as LightSystem, -} from './light_system_program'; - -import { - IDL as LightCompressedTokenIDL, - LightCompressedToken, -} from './light_compressed_token'; - -export { - AccountCompressionIDL, - AccountCompression, - LightRegistryIDL, - LightRegistry, - LightSystemIDL, - LightSystem, - LightCompressedTokenIDL, - LightCompressedToken, -}; diff --git a/js/stateless.js/src/idls/light_compressed_token.ts b/js/stateless.js/src/idls/light_compressed_token.ts deleted file mode 100644 index 3dc084e1b3..0000000000 --- a/js/stateless.js/src/idls/light_compressed_token.ts +++ /dev/null @@ -1,3481 +0,0 @@ -export type LightCompressedToken = { - version: '1.2.0'; - name: 'light_compressed_token'; - instructions: [ - { - name: 'createTokenPool'; - docs: [ - 'This instruction creates a token pool for a given mint. Every spl mint', - 'can have one token pool. When a token is compressed the tokens are', - 'transferrred to the token pool, and their compressed equivalent is', - 'minted into a Merkle tree.', - ]; - accounts: [ - { - name: 'feePayer'; - isMut: true; - isSigner: true; - docs: ['UNCHECKED: only pays fees.']; - }, - { - name: 'tokenPoolPda'; - isMut: true; - isSigner: false; - }, - { - name: 'systemProgram'; - isMut: false; - isSigner: false; - }, - { - name: 'mint'; - isMut: true; - isSigner: false; - }, - { - name: 'tokenProgram'; - isMut: false; - isSigner: false; - }, - { - name: 'cpiAuthorityPda'; - isMut: false; - isSigner: false; - }, - ]; - args: []; - }, - { - name: 'addTokenPool'; - docs: [ - 'This instruction creates an additional token pool for a given mint.', - 'The maximum number of token pools per mint is 5.', - ]; - accounts: [ - { - name: 'feePayer'; - isMut: true; - isSigner: true; - docs: ['UNCHECKED: only pays fees.']; - }, - { - name: 'tokenPoolPda'; - isMut: true; - isSigner: false; - }, - { - name: 'existingTokenPoolPda'; - isMut: false; - isSigner: false; - }, - { - name: 'systemProgram'; - isMut: false; - isSigner: false; - }, - { - name: 'mint'; - isMut: true; - isSigner: false; - }, - { - name: 'tokenProgram'; - isMut: false; - isSigner: false; - }, - { - name: 'cpiAuthorityPda'; - isMut: false; - isSigner: false; - }, - ]; - args: [ - { - name: 'tokenPoolBump'; - type: 'u8'; - }, - ]; - }, - { - name: 'mintTo'; - docs: [ - 'Mints tokens from an spl token mint to a list of compressed accounts.', - 'Minted tokens are transferred to a pool account owned by the compressed', - 'token program. The instruction creates one compressed output account for', - 'every amount and pubkey input pair. A constant amount of lamports can be', - 'transferred to each output account to enable. A use case to add lamports', - 'to a compressed token account is to prevent spam. This is the only way', - 'to add lamports to a compressed token account.', - ]; - accounts: [ - { - name: 'feePayer'; - isMut: true; - isSigner: true; - docs: ['UNCHECKED: only pays fees.']; - }, - { - name: 'authority'; - isMut: false; - isSigner: true; - }, - { - name: 'cpiAuthorityPda'; - isMut: false; - isSigner: false; - }, - { - name: 'mint'; - isMut: true; - isSigner: false; - }, - { - name: 'tokenPoolPda'; - isMut: true; - isSigner: false; - }, - { - name: 'tokenProgram'; - isMut: false; - isSigner: false; - }, - { - name: 'lightSystemProgram'; - isMut: false; - isSigner: false; - }, - { - name: 'registeredProgramPda'; - isMut: false; - isSigner: false; - }, - { - name: 'noopProgram'; - isMut: false; - isSigner: false; - docs: ['programs']; - }, - { - name: 'accountCompressionAuthority'; - isMut: false; - isSigner: false; - }, - { - name: 'accountCompressionProgram'; - isMut: false; - isSigner: false; - }, - { - name: 'merkleTree'; - isMut: true; - isSigner: false; - }, - { - name: 'selfProgram'; - isMut: false; - isSigner: false; - }, - { - name: 'systemProgram'; - isMut: false; - isSigner: false; - }, - { - name: 'solPoolPda'; - isMut: true; - isSigner: false; - isOptional: true; - }, - ]; - args: [ - { - name: 'publicKeys'; - type: { - vec: 'publicKey'; - }; - }, - { - name: 'amounts'; - type: { - vec: 'u64'; - }; - }, - { - name: 'lamports'; - type: { - option: 'u64'; - }; - }, - ]; - }, - { - name: 'compressSplTokenAccount'; - docs: [ - 'Compresses the balance of an spl token account sub an optional remaining', - 'amount. This instruction does not close the spl token account. To close', - 'the account bundle a close spl account instruction in your transaction.', - ]; - accounts: [ - { - name: 'feePayer'; - isMut: true; - isSigner: true; - docs: ['UNCHECKED: only pays fees.']; - }, - { - name: 'authority'; - isMut: false; - isSigner: true; - docs: [ - 'Authority is verified through proof since both owner and delegate', - 'are included in the token data hash, which is a public input to the', - 'validity proof.', - ]; - }, - { - name: 'cpiAuthorityPda'; - isMut: false; - isSigner: false; - }, - { - name: 'lightSystemProgram'; - isMut: false; - isSigner: false; - }, - { - name: 'registeredProgramPda'; - isMut: false; - isSigner: false; - }, - { - name: 'noopProgram'; - isMut: false; - isSigner: false; - }, - { - name: 'accountCompressionAuthority'; - isMut: false; - isSigner: false; - }, - { - name: 'accountCompressionProgram'; - isMut: false; - isSigner: false; - }, - { - name: 'selfProgram'; - isMut: false; - isSigner: false; - docs: ['this program is the signer of the cpi.']; - }, - { - name: 'tokenPoolPda'; - isMut: true; - isSigner: false; - isOptional: true; - }, - { - name: 'compressOrDecompressTokenAccount'; - isMut: true; - isSigner: false; - isOptional: true; - }, - { - name: 'tokenProgram'; - isMut: false; - isSigner: false; - isOptional: true; - }, - { - name: 'systemProgram'; - isMut: false; - isSigner: false; - }, - ]; - args: [ - { - name: 'owner'; - type: 'publicKey'; - }, - { - name: 'remainingAmount'; - type: { - option: 'u64'; - }; - }, - { - name: 'cpiContext'; - type: { - option: { - defined: 'CompressedCpiContext'; - }; - }; - }, - ]; - }, - { - name: 'transfer'; - docs: [ - 'Transfers compressed tokens from one account to another. All accounts', - 'must be of the same mint. Additional spl tokens can be compressed or', - 'decompressed. In one transaction only compression or decompression is', - 'possible. Lamports can be transferred alongside tokens. If output token', - 'accounts specify less lamports than inputs the remaining lamports are', - 'transferred to an output compressed account. Signer must be owner or', - 'delegate. If a delegated token account is transferred the delegate is', - 'not preserved.', - ]; - accounts: [ - { - name: 'feePayer'; - isMut: true; - isSigner: true; - docs: ['UNCHECKED: only pays fees.']; - }, - { - name: 'authority'; - isMut: false; - isSigner: true; - docs: [ - 'Authority is verified through proof since both owner and delegate', - 'are included in the token data hash, which is a public input to the', - 'validity proof.', - ]; - }, - { - name: 'cpiAuthorityPda'; - isMut: false; - isSigner: false; - }, - { - name: 'lightSystemProgram'; - isMut: false; - isSigner: false; - }, - { - name: 'registeredProgramPda'; - isMut: false; - isSigner: false; - }, - { - name: 'noopProgram'; - isMut: false; - isSigner: false; - }, - { - name: 'accountCompressionAuthority'; - isMut: false; - isSigner: false; - }, - { - name: 'accountCompressionProgram'; - isMut: false; - isSigner: false; - }, - { - name: 'selfProgram'; - isMut: false; - isSigner: false; - docs: ['this program is the signer of the cpi.']; - }, - { - name: 'tokenPoolPda'; - isMut: true; - isSigner: false; - isOptional: true; - }, - { - name: 'compressOrDecompressTokenAccount'; - isMut: true; - isSigner: false; - isOptional: true; - }, - { - name: 'tokenProgram'; - isMut: false; - isSigner: false; - isOptional: true; - }, - { - name: 'systemProgram'; - isMut: false; - isSigner: false; - }, - ]; - args: [ - { - name: 'inputs'; - type: 'bytes'; - }, - ]; - }, - { - name: 'approve'; - docs: [ - 'Delegates an amount to a delegate. A compressed token account is either', - 'completely delegated or not. Prior delegates are not preserved. Cannot', - 'be called by a delegate.', - 'The instruction creates two output accounts:', - '1. one account with delegated amount', - '2. one account with remaining(change) amount', - ]; - accounts: [ - { - name: 'feePayer'; - isMut: true; - isSigner: true; - docs: ['UNCHECKED: only pays fees.']; - }, - { - name: 'authority'; - isMut: false; - isSigner: true; - docs: [ - 'Authority is verified through proof since both owner and delegate', - 'are included in the token data hash, which is a public input to the', - 'validity proof.', - ]; - }, - { - name: 'cpiAuthorityPda'; - isMut: false; - isSigner: false; - }, - { - name: 'lightSystemProgram'; - isMut: false; - isSigner: false; - }, - { - name: 'registeredProgramPda'; - isMut: false; - isSigner: false; - }, - { - name: 'noopProgram'; - isMut: false; - isSigner: false; - }, - { - name: 'accountCompressionAuthority'; - isMut: false; - isSigner: false; - }, - { - name: 'accountCompressionProgram'; - isMut: false; - isSigner: false; - }, - { - name: 'selfProgram'; - isMut: false; - isSigner: false; - docs: ['this program is the signer of the cpi.']; - }, - { - name: 'systemProgram'; - isMut: false; - isSigner: false; - }, - ]; - args: [ - { - name: 'inputs'; - type: 'bytes'; - }, - ]; - }, - { - name: 'revoke'; - docs: [ - 'Revokes a delegation. The instruction merges all inputs into one output', - 'account. Cannot be called by a delegate. Delegates are not preserved.', - ]; - accounts: [ - { - name: 'feePayer'; - isMut: true; - isSigner: true; - docs: ['UNCHECKED: only pays fees.']; - }, - { - name: 'authority'; - isMut: false; - isSigner: true; - docs: [ - 'Authority is verified through proof since both owner and delegate', - 'are included in the token data hash, which is a public input to the', - 'validity proof.', - ]; - }, - { - name: 'cpiAuthorityPda'; - isMut: false; - isSigner: false; - }, - { - name: 'lightSystemProgram'; - isMut: false; - isSigner: false; - }, - { - name: 'registeredProgramPda'; - isMut: false; - isSigner: false; - }, - { - name: 'noopProgram'; - isMut: false; - isSigner: false; - }, - { - name: 'accountCompressionAuthority'; - isMut: false; - isSigner: false; - }, - { - name: 'accountCompressionProgram'; - isMut: false; - isSigner: false; - }, - { - name: 'selfProgram'; - isMut: false; - isSigner: false; - docs: ['this program is the signer of the cpi.']; - }, - { - name: 'systemProgram'; - isMut: false; - isSigner: false; - }, - ]; - args: [ - { - name: 'inputs'; - type: 'bytes'; - }, - ]; - }, - { - name: 'freeze'; - docs: [ - 'Freezes compressed token accounts. Inputs must not be frozen. Creates as', - 'many outputs as inputs. Balances and delegates are preserved.', - ]; - accounts: [ - { - name: 'feePayer'; - isMut: true; - isSigner: true; - docs: ['UNCHECKED: only pays fees.']; - }, - { - name: 'authority'; - isMut: false; - isSigner: true; - }, - { - name: 'cpiAuthorityPda'; - isMut: false; - isSigner: false; - }, - { - name: 'lightSystemProgram'; - isMut: false; - isSigner: false; - }, - { - name: 'registeredProgramPda'; - isMut: false; - isSigner: false; - }, - { - name: 'noopProgram'; - isMut: false; - isSigner: false; - }, - { - name: 'accountCompressionAuthority'; - isMut: false; - isSigner: false; - }, - { - name: 'accountCompressionProgram'; - isMut: false; - isSigner: false; - }, - { - name: 'selfProgram'; - isMut: false; - isSigner: false; - docs: ['that this program is the signer of the cpi.']; - }, - { - name: 'systemProgram'; - isMut: false; - isSigner: false; - }, - { - name: 'mint'; - isMut: false; - isSigner: false; - }, - ]; - args: [ - { - name: 'inputs'; - type: 'bytes'; - }, - ]; - }, - { - name: 'thaw'; - docs: [ - 'Thaws frozen compressed token accounts. Inputs must be frozen. Creates', - 'as many outputs as inputs. Balances and delegates are preserved.', - ]; - accounts: [ - { - name: 'feePayer'; - isMut: true; - isSigner: true; - docs: ['UNCHECKED: only pays fees.']; - }, - { - name: 'authority'; - isMut: false; - isSigner: true; - }, - { - name: 'cpiAuthorityPda'; - isMut: false; - isSigner: false; - }, - { - name: 'lightSystemProgram'; - isMut: false; - isSigner: false; - }, - { - name: 'registeredProgramPda'; - isMut: false; - isSigner: false; - }, - { - name: 'noopProgram'; - isMut: false; - isSigner: false; - }, - { - name: 'accountCompressionAuthority'; - isMut: false; - isSigner: false; - }, - { - name: 'accountCompressionProgram'; - isMut: false; - isSigner: false; - }, - { - name: 'selfProgram'; - isMut: false; - isSigner: false; - docs: ['that this program is the signer of the cpi.']; - }, - { - name: 'systemProgram'; - isMut: false; - isSigner: false; - }, - { - name: 'mint'; - isMut: false; - isSigner: false; - }, - ]; - args: [ - { - name: 'inputs'; - type: 'bytes'; - }, - ]; - }, - { - name: 'burn'; - docs: [ - 'Burns compressed tokens and spl tokens from the pool account. Delegates', - 'can burn tokens. The output compressed token account remains delegated.', - 'Creates one output compressed token account.', - ]; - accounts: [ - { - name: 'feePayer'; - isMut: true; - isSigner: true; - docs: ['UNCHECKED: only pays fees.']; - }, - { - name: 'authority'; - isMut: false; - isSigner: true; - docs: [ - 'Authority is verified through proof since both owner and delegate', - 'are included in the token data hash, which is a public input to the', - 'validity proof.', - ]; - }, - { - name: 'cpiAuthorityPda'; - isMut: false; - isSigner: false; - }, - { - name: 'mint'; - isMut: true; - isSigner: false; - }, - { - name: 'tokenPoolPda'; - isMut: true; - isSigner: false; - }, - { - name: 'tokenProgram'; - isMut: false; - isSigner: false; - }, - { - name: 'lightSystemProgram'; - isMut: false; - isSigner: false; - }, - { - name: 'registeredProgramPda'; - isMut: false; - isSigner: false; - }, - { - name: 'noopProgram'; - isMut: false; - isSigner: false; - }, - { - name: 'accountCompressionAuthority'; - isMut: false; - isSigner: false; - }, - { - name: 'accountCompressionProgram'; - isMut: false; - isSigner: false; - }, - { - name: 'selfProgram'; - isMut: false; - isSigner: false; - }, - { - name: 'systemProgram'; - isMut: false; - isSigner: false; - }, - ]; - args: [ - { - name: 'inputs'; - type: 'bytes'; - }, - ]; - }, - { - name: 'stubIdlBuild'; - docs: [ - 'This function is a stub to allow Anchor to include the input types in', - 'the IDL. It should not be included in production builds nor be called in', - 'practice.', - ]; - accounts: [ - { - name: 'feePayer'; - isMut: true; - isSigner: true; - docs: ['UNCHECKED: only pays fees.']; - }, - { - name: 'authority'; - isMut: false; - isSigner: true; - docs: [ - 'Authority is verified through proof since both owner and delegate', - 'are included in the token data hash, which is a public input to the', - 'validity proof.', - ]; - }, - { - name: 'cpiAuthorityPda'; - isMut: false; - isSigner: false; - }, - { - name: 'lightSystemProgram'; - isMut: false; - isSigner: false; - }, - { - name: 'registeredProgramPda'; - isMut: false; - isSigner: false; - }, - { - name: 'noopProgram'; - isMut: false; - isSigner: false; - }, - { - name: 'accountCompressionAuthority'; - isMut: false; - isSigner: false; - }, - { - name: 'accountCompressionProgram'; - isMut: false; - isSigner: false; - }, - { - name: 'selfProgram'; - isMut: false; - isSigner: false; - docs: ['this program is the signer of the cpi.']; - }, - { - name: 'tokenPoolPda'; - isMut: true; - isSigner: false; - isOptional: true; - }, - { - name: 'compressOrDecompressTokenAccount'; - isMut: true; - isSigner: false; - isOptional: true; - }, - { - name: 'tokenProgram'; - isMut: false; - isSigner: false; - isOptional: true; - }, - { - name: 'systemProgram'; - isMut: false; - isSigner: false; - }, - ]; - args: [ - { - name: 'inputs1'; - type: { - defined: 'CompressedTokenInstructionDataTransfer'; - }; - }, - { - name: 'inputs2'; - type: { - defined: 'TokenData'; - }; - }, - ]; - }, - ]; - types: [ - { - name: 'AccountState'; - type: { - kind: 'enum'; - variants: [ - { - name: 'Initialized'; - }, - { - name: 'Frozen'; - }, - ]; - }; - }, - { - name: 'CompressedAccount'; - type: { - kind: 'struct'; - fields: [ - { - name: 'owner'; - type: 'publicKey'; - }, - { - name: 'lamports'; - type: 'u64'; - }, - { - name: 'address'; - type: { - option: { - array: ['u8', 32]; - }; - }; - }, - { - name: 'data'; - type: { - option: { - defined: 'CompressedAccountData'; - }; - }; - }, - ]; - }; - }, - { - name: 'CompressedAccountData'; - type: { - kind: 'struct'; - fields: [ - { - name: 'discriminator'; - type: { - array: ['u8', 8]; - }; - }, - { - name: 'data'; - type: 'bytes'; - }, - { - name: 'dataHash'; - type: { - array: ['u8', 32]; - }; - }, - ]; - }; - }, - { - name: 'CompressedCpiContext'; - type: { - kind: 'struct'; - fields: [ - { - name: 'setContext'; - docs: [ - 'Is set by the program that is invoking the CPI to signal that is should', - 'set the cpi context.', - ]; - type: 'bool'; - }, - { - name: 'firstSetContext'; - docs: [ - 'Is set to wipe the cpi context since someone could have set it before', - 'with unrelated data.', - ]; - type: 'bool'; - }, - { - name: 'cpiContextAccountIndex'; - docs: [ - 'Index of cpi context account in remaining accounts.', - ]; - type: 'u8'; - }, - ]; - }; - }, - { - name: 'CompressedProof'; - type: { - kind: 'struct'; - fields: [ - { - name: 'a'; - type: { - array: ['u8', 32]; - }; - }, - { - name: 'b'; - type: { - array: ['u8', 64]; - }; - }, - { - name: 'c'; - type: { - array: ['u8', 32]; - }; - }, - ]; - }; - }, - { - name: 'CompressedTokenInstructionDataTransfer'; - type: { - kind: 'struct'; - fields: [ - { - name: 'proof'; - type: { - option: { - defined: 'CompressedProof'; - }; - }; - }, - { - name: 'mint'; - type: 'publicKey'; - }, - { - name: 'delegatedTransfer'; - docs: [ - 'Is required if the signer is delegate,', - '-> delegate is authority account,', - 'owner = Some(owner) is the owner of the token account.', - ]; - type: { - option: { - defined: 'DelegatedTransfer'; - }; - }; - }, - { - name: 'inputTokenDataWithContext'; - type: { - vec: { - defined: 'InputTokenDataWithContext'; - }; - }; - }, - { - name: 'outputCompressedAccounts'; - type: { - vec: { - defined: 'PackedTokenTransferOutputData'; - }; - }; - }, - { - name: 'isCompress'; - type: 'bool'; - }, - { - name: 'compressOrDecompressAmount'; - type: { - option: 'u64'; - }; - }, - { - name: 'cpiContext'; - type: { - option: { - defined: 'CompressedCpiContext'; - }; - }; - }, - { - name: 'lamportsChangeAccountMerkleTreeIndex'; - type: { - option: 'u8'; - }; - }, - ]; - }; - }, - { - name: 'DelegatedTransfer'; - docs: [ - 'Struct to provide the owner when the delegate is signer of the transaction.', - ]; - type: { - kind: 'struct'; - fields: [ - { - name: 'owner'; - type: 'publicKey'; - }, - { - name: 'delegateChangeAccountIndex'; - docs: [ - 'Index of change compressed account in output compressed accounts. In', - "case that the delegate didn't spend the complete delegated compressed", - 'account balance the change compressed account will be delegated to her', - 'as well.', - ]; - type: { - option: 'u8'; - }; - }, - ]; - }; - }, - { - name: 'InputTokenDataWithContext'; - type: { - kind: 'struct'; - fields: [ - { - name: 'amount'; - type: 'u64'; - }, - { - name: 'delegateIndex'; - type: { - option: 'u8'; - }; - }, - { - name: 'merkleContext'; - type: { - defined: 'PackedMerkleContext'; - }; - }, - { - name: 'rootIndex'; - type: 'u16'; - }, - { - name: 'lamports'; - type: { - option: 'u64'; - }; - }, - { - name: 'tlv'; - docs: [ - 'Placeholder for TokenExtension tlv data (unimplemented)', - ]; - type: { - option: 'bytes'; - }; - }, - ]; - }; - }, - { - name: 'InstructionDataInvoke'; - type: { - kind: 'struct'; - fields: [ - { - name: 'proof'; - type: { - option: { - defined: 'CompressedProof'; - }; - }; - }, - { - name: 'inputCompressedAccountsWithMerkleContext'; - type: { - vec: { - defined: 'PackedCompressedAccountWithMerkleContext'; - }; - }; - }, - { - name: 'outputCompressedAccounts'; - type: { - vec: { - defined: 'OutputCompressedAccountWithPackedContext'; - }; - }; - }, - { - name: 'relayFee'; - type: { - option: 'u64'; - }; - }, - { - name: 'newAddressParams'; - type: { - vec: { - defined: 'NewAddressParamsPacked'; - }; - }; - }, - { - name: 'compressOrDecompressLamports'; - type: { - option: 'u64'; - }; - }, - { - name: 'isCompress'; - type: 'bool'; - }, - ]; - }; - }, - { - name: 'InstructionDataInvokeCpi'; - type: { - kind: 'struct'; - fields: [ - { - name: 'proof'; - type: { - option: { - defined: 'CompressedProof'; - }; - }; - }, - { - name: 'newAddressParams'; - type: { - vec: { - defined: 'NewAddressParamsPacked'; - }; - }; - }, - { - name: 'inputCompressedAccountsWithMerkleContext'; - type: { - vec: { - defined: 'PackedCompressedAccountWithMerkleContext'; - }; - }; - }, - { - name: 'outputCompressedAccounts'; - type: { - vec: { - defined: 'OutputCompressedAccountWithPackedContext'; - }; - }; - }, - { - name: 'relayFee'; - type: { - option: 'u64'; - }; - }, - { - name: 'compressOrDecompressLamports'; - type: { - option: 'u64'; - }; - }, - { - name: 'isCompress'; - type: 'bool'; - }, - { - name: 'cpiContext'; - type: { - option: { - defined: 'CompressedCpiContext'; - }; - }; - }, - ]; - }; - }, - { - name: 'MerkleTreeSequenceNumber'; - type: { - kind: 'struct'; - fields: [ - { - name: 'pubkey'; - type: 'publicKey'; - }, - { - name: 'seq'; - type: 'u64'; - }, - ]; - }; - }, - { - name: 'NewAddressParamsPacked'; - type: { - kind: 'struct'; - fields: [ - { - name: 'seed'; - type: { - array: ['u8', 32]; - }; - }, - { - name: 'addressQueueAccountIndex'; - type: 'u8'; - }, - { - name: 'addressMerkleTreeAccountIndex'; - type: 'u8'; - }, - { - name: 'addressMerkleTreeRootIndex'; - type: 'u16'; - }, - ]; - }; - }, - { - name: 'OutputCompressedAccountWithPackedContext'; - type: { - kind: 'struct'; - fields: [ - { - name: 'compressedAccount'; - type: { - defined: 'CompressedAccount'; - }; - }, - { - name: 'merkleTreeIndex'; - type: 'u8'; - }, - ]; - }; - }, - { - name: 'PackedCompressedAccountWithMerkleContext'; - type: { - kind: 'struct'; - fields: [ - { - name: 'compressedAccount'; - type: { - defined: 'CompressedAccount'; - }; - }, - { - name: 'merkleContext'; - type: { - defined: 'PackedMerkleContext'; - }; - }, - { - name: 'rootIndex'; - docs: [ - 'Index of root used in inclusion validity proof.', - ]; - type: 'u16'; - }, - { - name: 'readOnly'; - docs: [ - 'Placeholder to mark accounts read-only unimplemented set to false.', - ]; - type: 'bool'; - }, - ]; - }; - }, - { - name: 'PackedMerkleContext'; - type: { - kind: 'struct'; - fields: [ - { - name: 'merkleTreePubkeyIndex'; - type: 'u8'; - }, - { - name: 'nullifierQueuePubkeyIndex'; - type: 'u8'; - }, - { - name: 'leafIndex'; - type: 'u32'; - }, - { - name: 'queueIndex'; - type: { - option: { - defined: 'QueueIndex'; - }; - }; - }, - ]; - }; - }, - { - name: 'PackedTokenTransferOutputData'; - type: { - kind: 'struct'; - fields: [ - { - name: 'owner'; - type: 'publicKey'; - }, - { - name: 'amount'; - type: 'u64'; - }, - { - name: 'lamports'; - type: { - option: 'u64'; - }; - }, - { - name: 'merkleTreeIndex'; - type: 'u8'; - }, - { - name: 'tlv'; - docs: [ - 'Placeholder for TokenExtension tlv data (unimplemented)', - ]; - type: { - option: 'bytes'; - }; - }, - ]; - }; - }, - { - name: 'PublicTransactionEvent'; - type: { - kind: 'struct'; - fields: [ - { - name: 'inputCompressedAccountHashes'; - type: { - vec: { - array: ['u8', 32]; - }; - }; - }, - { - name: 'outputCompressedAccountHashes'; - type: { - vec: { - array: ['u8', 32]; - }; - }; - }, - { - name: 'outputCompressedAccounts'; - type: { - vec: { - defined: 'OutputCompressedAccountWithPackedContext'; - }; - }; - }, - { - name: 'outputLeafIndices'; - type: { - vec: 'u32'; - }; - }, - { - name: 'sequenceNumbers'; - type: { - vec: { - defined: 'MerkleTreeSequenceNumber'; - }; - }; - }, - { - name: 'relayFee'; - type: { - option: 'u64'; - }; - }, - { - name: 'isCompress'; - type: 'bool'; - }, - { - name: 'compressOrDecompressLamports'; - type: { - option: 'u64'; - }; - }, - { - name: 'pubkeyArray'; - type: { - vec: 'publicKey'; - }; - }, - { - name: 'message'; - type: { - option: 'bytes'; - }; - }, - ]; - }; - }, - { - name: 'QueueIndex'; - type: { - kind: 'struct'; - fields: [ - { - name: 'queueId'; - docs: ['Id of queue in queue account.']; - type: 'u8'; - }, - { - name: 'index'; - docs: ['Index of compressed account hash in queue.']; - type: 'u16'; - }, - ]; - }; - }, - { - name: 'TokenData'; - type: { - kind: 'struct'; - fields: [ - { - name: 'mint'; - docs: ['The mint associated with this account']; - type: 'publicKey'; - }, - { - name: 'owner'; - docs: ['The owner of this account.']; - type: 'publicKey'; - }, - { - name: 'amount'; - docs: ['The amount of tokens this account holds.']; - type: 'u64'; - }, - { - name: 'delegate'; - docs: [ - 'If `delegate` is `Some` then `delegated_amount` represents', - 'the amount authorized by the delegate', - ]; - type: { - option: 'publicKey'; - }; - }, - { - name: 'state'; - docs: ["The account's state"]; - type: { - defined: 'AccountState'; - }; - }, - { - name: 'tlv'; - docs: [ - 'Placeholder for TokenExtension tlv data (unimplemented)', - ]; - type: { - option: 'bytes'; - }; - }, - ]; - }; - }, - ]; - errors: [ - { - code: 6000; - name: 'PublicKeyAmountMissmatch'; - msg: 'public keys and amounts must be of same length'; - }, - { - code: 6001; - name: 'ComputeInputSumFailed'; - msg: 'ComputeInputSumFailed'; - }, - { - code: 6002; - name: 'ComputeOutputSumFailed'; - msg: 'ComputeOutputSumFailed'; - }, - { - code: 6003; - name: 'ComputeCompressSumFailed'; - msg: 'ComputeCompressSumFailed'; - }, - { - code: 6004; - name: 'ComputeDecompressSumFailed'; - msg: 'ComputeDecompressSumFailed'; - }, - { - code: 6005; - name: 'SumCheckFailed'; - msg: 'SumCheckFailed'; - }, - { - code: 6006; - name: 'DecompressRecipientUndefinedForDecompress'; - msg: 'DecompressRecipientUndefinedForDecompress'; - }, - { - code: 6007; - name: 'CompressedPdaUndefinedForDecompress'; - msg: 'CompressedPdaUndefinedForDecompress'; - }, - { - code: 6008; - name: 'DeCompressAmountUndefinedForDecompress'; - msg: 'DeCompressAmountUndefinedForDecompress'; - }, - { - code: 6009; - name: 'CompressedPdaUndefinedForCompress'; - msg: 'CompressedPdaUndefinedForCompress'; - }, - { - code: 6010; - name: 'DeCompressAmountUndefinedForCompress'; - msg: 'DeCompressAmountUndefinedForCompress'; - }, - { - code: 6011; - name: 'DelegateSignerCheckFailed'; - msg: 'DelegateSignerCheckFailed'; - }, - { - code: 6012; - name: 'MintTooLarge'; - msg: 'Minted amount greater than u64::MAX'; - }, - { - code: 6013; - name: 'SplTokenSupplyMismatch'; - msg: 'SplTokenSupplyMismatch'; - }, - { - code: 6014; - name: 'HeapMemoryCheckFailed'; - msg: 'HeapMemoryCheckFailed'; - }, - { - code: 6015; - name: 'InstructionNotCallable'; - msg: 'The instruction is not callable'; - }, - { - code: 6016; - name: 'ArithmeticUnderflow'; - msg: 'ArithmeticUnderflow'; - }, - { - code: 6017; - name: 'HashToFieldError'; - msg: 'HashToFieldError'; - }, - { - code: 6018; - name: 'InvalidAuthorityMint'; - msg: 'Expected the authority to be also a mint authority'; - }, - { - code: 6019; - name: 'InvalidFreezeAuthority'; - msg: 'Provided authority is not the freeze authority'; - }, - { - code: 6020; - name: 'InvalidDelegateIndex'; - }, - { - code: 6021; - name: 'TokenPoolPdaUndefined'; - }, - { - code: 6022; - name: 'IsTokenPoolPda'; - msg: 'Compress or decompress recipient is the same account as the token pool pda.'; - }, - { - code: 6023; - name: 'InvalidTokenPoolPda'; - }, - { - code: 6024; - name: 'NoInputTokenAccountsProvided'; - }, - { - code: 6025; - name: 'NoInputsProvided'; - }, - { - code: 6026; - name: 'MintHasNoFreezeAuthority'; - }, - { - code: 6027; - name: 'MintWithInvalidExtension'; - }, - { - code: 6028; - name: 'InsufficientTokenAccountBalance'; - msg: 'The token account balance is less than the remaining amount.'; - }, - { - code: 6029; - name: 'InvalidTokenPoolBump'; - msg: 'Max number of token pools reached.'; - }, - { - code: 6030; - name: 'FailedToDecompress'; - }, - { - code: 6031; - name: 'FailedToBurnSplTokensFromTokenPool'; - }, - { - code: 6032; - name: 'NoMatchingBumpFound'; - }, - ]; -}; -export const IDL: LightCompressedToken = { - version: '1.2.0', - name: 'light_compressed_token', - instructions: [ - { - name: 'createTokenPool', - docs: [ - 'This instruction creates a token pool for a given mint. Every spl mint', - 'can have one token pool. When a token is compressed the tokens are', - 'transferrred to the token pool, and their compressed equivalent is', - 'minted into a Merkle tree.', - ], - accounts: [ - { - name: 'feePayer', - isMut: true, - isSigner: true, - docs: ['UNCHECKED: only pays fees.'], - }, - { - name: 'tokenPoolPda', - isMut: true, - isSigner: false, - }, - { - name: 'systemProgram', - isMut: false, - isSigner: false, - }, - { - name: 'mint', - isMut: true, - isSigner: false, - }, - { - name: 'tokenProgram', - isMut: false, - isSigner: false, - }, - { - name: 'cpiAuthorityPda', - isMut: false, - isSigner: false, - }, - ], - args: [], - }, - { - name: 'addTokenPool', - docs: [ - 'This instruction creates an additional token pool for a given mint.', - 'The maximum number of token pools per mint is 5.', - ], - accounts: [ - { - name: 'feePayer', - isMut: true, - isSigner: true, - docs: ['UNCHECKED: only pays fees.'], - }, - { - name: 'tokenPoolPda', - isMut: true, - isSigner: false, - }, - { - name: 'existingTokenPoolPda', - isMut: false, - isSigner: false, - }, - { - name: 'systemProgram', - isMut: false, - isSigner: false, - }, - { - name: 'mint', - isMut: true, - isSigner: false, - }, - { - name: 'tokenProgram', - isMut: false, - isSigner: false, - }, - { - name: 'cpiAuthorityPda', - isMut: false, - isSigner: false, - }, - ], - args: [ - { - name: 'tokenPoolBump', - type: 'u8', - }, - ], - }, - { - name: 'mintTo', - docs: [ - 'Mints tokens from an spl token mint to a list of compressed accounts.', - 'Minted tokens are transferred to a pool account owned by the compressed', - 'token program. The instruction creates one compressed output account for', - 'every amount and pubkey input pair. A constant amount of lamports can be', - 'transferred to each output account to enable. A use case to add lamports', - 'to a compressed token account is to prevent spam. This is the only way', - 'to add lamports to a compressed token account.', - ], - accounts: [ - { - name: 'feePayer', - isMut: true, - isSigner: true, - docs: ['UNCHECKED: only pays fees.'], - }, - { - name: 'authority', - isMut: false, - isSigner: true, - }, - { - name: 'cpiAuthorityPda', - isMut: false, - isSigner: false, - }, - { - name: 'mint', - isMut: true, - isSigner: false, - }, - { - name: 'tokenPoolPda', - isMut: true, - isSigner: false, - }, - { - name: 'tokenProgram', - isMut: false, - isSigner: false, - }, - { - name: 'lightSystemProgram', - isMut: false, - isSigner: false, - }, - { - name: 'registeredProgramPda', - isMut: false, - isSigner: false, - }, - { - name: 'noopProgram', - isMut: false, - isSigner: false, - docs: ['programs'], - }, - { - name: 'accountCompressionAuthority', - isMut: false, - isSigner: false, - }, - { - name: 'accountCompressionProgram', - isMut: false, - isSigner: false, - }, - { - name: 'merkleTree', - isMut: true, - isSigner: false, - }, - { - name: 'selfProgram', - isMut: false, - isSigner: false, - }, - { - name: 'systemProgram', - isMut: false, - isSigner: false, - }, - { - name: 'solPoolPda', - isMut: true, - isSigner: false, - isOptional: true, - }, - ], - args: [ - { - name: 'publicKeys', - type: { - vec: 'publicKey', - }, - }, - { - name: 'amounts', - type: { - vec: 'u64', - }, - }, - { - name: 'lamports', - type: { - option: 'u64', - }, - }, - ], - }, - { - name: 'compressSplTokenAccount', - docs: [ - 'Compresses the balance of an spl token account sub an optional remaining', - 'amount. This instruction does not close the spl token account. To close', - 'the account bundle a close spl account instruction in your transaction.', - ], - accounts: [ - { - name: 'feePayer', - isMut: true, - isSigner: true, - docs: ['UNCHECKED: only pays fees.'], - }, - { - name: 'authority', - isMut: false, - isSigner: true, - docs: [ - 'Authority is verified through proof since both owner and delegate', - 'are included in the token data hash, which is a public input to the', - 'validity proof.', - ], - }, - { - name: 'cpiAuthorityPda', - isMut: false, - isSigner: false, - }, - { - name: 'lightSystemProgram', - isMut: false, - isSigner: false, - }, - { - name: 'registeredProgramPda', - isMut: false, - isSigner: false, - }, - { - name: 'noopProgram', - isMut: false, - isSigner: false, - }, - { - name: 'accountCompressionAuthority', - isMut: false, - isSigner: false, - }, - { - name: 'accountCompressionProgram', - isMut: false, - isSigner: false, - }, - { - name: 'selfProgram', - isMut: false, - isSigner: false, - docs: ['this program is the signer of the cpi.'], - }, - { - name: 'tokenPoolPda', - isMut: true, - isSigner: false, - isOptional: true, - }, - { - name: 'compressOrDecompressTokenAccount', - isMut: true, - isSigner: false, - isOptional: true, - }, - { - name: 'tokenProgram', - isMut: false, - isSigner: false, - isOptional: true, - }, - { - name: 'systemProgram', - isMut: false, - isSigner: false, - }, - ], - args: [ - { - name: 'owner', - type: 'publicKey', - }, - { - name: 'remainingAmount', - type: { - option: 'u64', - }, - }, - { - name: 'cpiContext', - type: { - option: { - defined: 'CompressedCpiContext', - }, - }, - }, - ], - }, - { - name: 'transfer', - docs: [ - 'Transfers compressed tokens from one account to another. All accounts', - 'must be of the same mint. Additional spl tokens can be compressed or', - 'decompressed. In one transaction only compression or decompression is', - 'possible. Lamports can be transferred alongside tokens. If output token', - 'accounts specify less lamports than inputs the remaining lamports are', - 'transferred to an output compressed account. Signer must be owner or', - 'delegate. If a delegated token account is transferred the delegate is', - 'not preserved.', - ], - accounts: [ - { - name: 'feePayer', - isMut: true, - isSigner: true, - docs: ['UNCHECKED: only pays fees.'], - }, - { - name: 'authority', - isMut: false, - isSigner: true, - docs: [ - 'Authority is verified through proof since both owner and delegate', - 'are included in the token data hash, which is a public input to the', - 'validity proof.', - ], - }, - { - name: 'cpiAuthorityPda', - isMut: false, - isSigner: false, - }, - { - name: 'lightSystemProgram', - isMut: false, - isSigner: false, - }, - { - name: 'registeredProgramPda', - isMut: false, - isSigner: false, - }, - { - name: 'noopProgram', - isMut: false, - isSigner: false, - }, - { - name: 'accountCompressionAuthority', - isMut: false, - isSigner: false, - }, - { - name: 'accountCompressionProgram', - isMut: false, - isSigner: false, - }, - { - name: 'selfProgram', - isMut: false, - isSigner: false, - docs: ['this program is the signer of the cpi.'], - }, - { - name: 'tokenPoolPda', - isMut: true, - isSigner: false, - isOptional: true, - }, - { - name: 'compressOrDecompressTokenAccount', - isMut: true, - isSigner: false, - isOptional: true, - }, - { - name: 'tokenProgram', - isMut: false, - isSigner: false, - isOptional: true, - }, - { - name: 'systemProgram', - isMut: false, - isSigner: false, - }, - ], - args: [ - { - name: 'inputs', - type: 'bytes', - }, - ], - }, - { - name: 'approve', - docs: [ - 'Delegates an amount to a delegate. A compressed token account is either', - 'completely delegated or not. Prior delegates are not preserved. Cannot', - 'be called by a delegate.', - 'The instruction creates two output accounts:', - '1. one account with delegated amount', - '2. one account with remaining(change) amount', - ], - accounts: [ - { - name: 'feePayer', - isMut: true, - isSigner: true, - docs: ['UNCHECKED: only pays fees.'], - }, - { - name: 'authority', - isMut: false, - isSigner: true, - docs: [ - 'Authority is verified through proof since both owner and delegate', - 'are included in the token data hash, which is a public input to the', - 'validity proof.', - ], - }, - { - name: 'cpiAuthorityPda', - isMut: false, - isSigner: false, - }, - { - name: 'lightSystemProgram', - isMut: false, - isSigner: false, - }, - { - name: 'registeredProgramPda', - isMut: false, - isSigner: false, - }, - { - name: 'noopProgram', - isMut: false, - isSigner: false, - }, - { - name: 'accountCompressionAuthority', - isMut: false, - isSigner: false, - }, - { - name: 'accountCompressionProgram', - isMut: false, - isSigner: false, - }, - { - name: 'selfProgram', - isMut: false, - isSigner: false, - docs: ['this program is the signer of the cpi.'], - }, - { - name: 'systemProgram', - isMut: false, - isSigner: false, - }, - ], - args: [ - { - name: 'inputs', - type: 'bytes', - }, - ], - }, - { - name: 'revoke', - docs: [ - 'Revokes a delegation. The instruction merges all inputs into one output', - 'account. Cannot be called by a delegate. Delegates are not preserved.', - ], - accounts: [ - { - name: 'feePayer', - isMut: true, - isSigner: true, - docs: ['UNCHECKED: only pays fees.'], - }, - { - name: 'authority', - isMut: false, - isSigner: true, - docs: [ - 'Authority is verified through proof since both owner and delegate', - 'are included in the token data hash, which is a public input to the', - 'validity proof.', - ], - }, - { - name: 'cpiAuthorityPda', - isMut: false, - isSigner: false, - }, - { - name: 'lightSystemProgram', - isMut: false, - isSigner: false, - }, - { - name: 'registeredProgramPda', - isMut: false, - isSigner: false, - }, - { - name: 'noopProgram', - isMut: false, - isSigner: false, - }, - { - name: 'accountCompressionAuthority', - isMut: false, - isSigner: false, - }, - { - name: 'accountCompressionProgram', - isMut: false, - isSigner: false, - }, - { - name: 'selfProgram', - isMut: false, - isSigner: false, - docs: ['this program is the signer of the cpi.'], - }, - { - name: 'systemProgram', - isMut: false, - isSigner: false, - }, - ], - args: [ - { - name: 'inputs', - type: 'bytes', - }, - ], - }, - { - name: 'freeze', - docs: [ - 'Freezes compressed token accounts. Inputs must not be frozen. Creates as', - 'many outputs as inputs. Balances and delegates are preserved.', - ], - accounts: [ - { - name: 'feePayer', - isMut: true, - isSigner: true, - docs: ['UNCHECKED: only pays fees.'], - }, - { - name: 'authority', - isMut: false, - isSigner: true, - }, - { - name: 'cpiAuthorityPda', - isMut: false, - isSigner: false, - }, - { - name: 'lightSystemProgram', - isMut: false, - isSigner: false, - }, - { - name: 'registeredProgramPda', - isMut: false, - isSigner: false, - }, - { - name: 'noopProgram', - isMut: false, - isSigner: false, - }, - { - name: 'accountCompressionAuthority', - isMut: false, - isSigner: false, - }, - { - name: 'accountCompressionProgram', - isMut: false, - isSigner: false, - }, - { - name: 'selfProgram', - isMut: false, - isSigner: false, - docs: ['that this program is the signer of the cpi.'], - }, - { - name: 'systemProgram', - isMut: false, - isSigner: false, - }, - { - name: 'mint', - isMut: false, - isSigner: false, - }, - ], - args: [ - { - name: 'inputs', - type: 'bytes', - }, - ], - }, - { - name: 'thaw', - docs: [ - 'Thaws frozen compressed token accounts. Inputs must be frozen. Creates', - 'as many outputs as inputs. Balances and delegates are preserved.', - ], - accounts: [ - { - name: 'feePayer', - isMut: true, - isSigner: true, - docs: ['UNCHECKED: only pays fees.'], - }, - { - name: 'authority', - isMut: false, - isSigner: true, - }, - { - name: 'cpiAuthorityPda', - isMut: false, - isSigner: false, - }, - { - name: 'lightSystemProgram', - isMut: false, - isSigner: false, - }, - { - name: 'registeredProgramPda', - isMut: false, - isSigner: false, - }, - { - name: 'noopProgram', - isMut: false, - isSigner: false, - }, - { - name: 'accountCompressionAuthority', - isMut: false, - isSigner: false, - }, - { - name: 'accountCompressionProgram', - isMut: false, - isSigner: false, - }, - { - name: 'selfProgram', - isMut: false, - isSigner: false, - docs: ['that this program is the signer of the cpi.'], - }, - { - name: 'systemProgram', - isMut: false, - isSigner: false, - }, - { - name: 'mint', - isMut: false, - isSigner: false, - }, - ], - args: [ - { - name: 'inputs', - type: 'bytes', - }, - ], - }, - { - name: 'burn', - docs: [ - 'Burns compressed tokens and spl tokens from the pool account. Delegates', - 'can burn tokens. The output compressed token account remains delegated.', - 'Creates one output compressed token account.', - ], - accounts: [ - { - name: 'feePayer', - isMut: true, - isSigner: true, - docs: ['UNCHECKED: only pays fees.'], - }, - { - name: 'authority', - isMut: false, - isSigner: true, - docs: [ - 'Authority is verified through proof since both owner and delegate', - 'are included in the token data hash, which is a public input to the', - 'validity proof.', - ], - }, - { - name: 'cpiAuthorityPda', - isMut: false, - isSigner: false, - }, - { - name: 'mint', - isMut: true, - isSigner: false, - }, - { - name: 'tokenPoolPda', - isMut: true, - isSigner: false, - }, - { - name: 'tokenProgram', - isMut: false, - isSigner: false, - }, - { - name: 'lightSystemProgram', - isMut: false, - isSigner: false, - }, - { - name: 'registeredProgramPda', - isMut: false, - isSigner: false, - }, - { - name: 'noopProgram', - isMut: false, - isSigner: false, - }, - { - name: 'accountCompressionAuthority', - isMut: false, - isSigner: false, - }, - { - name: 'accountCompressionProgram', - isMut: false, - isSigner: false, - }, - { - name: 'selfProgram', - isMut: false, - isSigner: false, - }, - { - name: 'systemProgram', - isMut: false, - isSigner: false, - }, - ], - args: [ - { - name: 'inputs', - type: 'bytes', - }, - ], - }, - { - name: 'stubIdlBuild', - docs: [ - 'This function is a stub to allow Anchor to include the input types in', - 'the IDL. It should not be included in production builds nor be called in', - 'practice.', - ], - accounts: [ - { - name: 'feePayer', - isMut: true, - isSigner: true, - docs: ['UNCHECKED: only pays fees.'], - }, - { - name: 'authority', - isMut: false, - isSigner: true, - docs: [ - 'Authority is verified through proof since both owner and delegate', - 'are included in the token data hash, which is a public input to the', - 'validity proof.', - ], - }, - { - name: 'cpiAuthorityPda', - isMut: false, - isSigner: false, - }, - { - name: 'lightSystemProgram', - isMut: false, - isSigner: false, - }, - { - name: 'registeredProgramPda', - isMut: false, - isSigner: false, - }, - { - name: 'noopProgram', - isMut: false, - isSigner: false, - }, - { - name: 'accountCompressionAuthority', - isMut: false, - isSigner: false, - }, - { - name: 'accountCompressionProgram', - isMut: false, - isSigner: false, - }, - { - name: 'selfProgram', - isMut: false, - isSigner: false, - docs: ['this program is the signer of the cpi.'], - }, - { - name: 'tokenPoolPda', - isMut: true, - isSigner: false, - isOptional: true, - }, - { - name: 'compressOrDecompressTokenAccount', - isMut: true, - isSigner: false, - isOptional: true, - }, - { - name: 'tokenProgram', - isMut: false, - isSigner: false, - isOptional: true, - }, - { - name: 'systemProgram', - isMut: false, - isSigner: false, - }, - ], - args: [ - { - name: 'inputs1', - type: { - defined: 'CompressedTokenInstructionDataTransfer', - }, - }, - { - name: 'inputs2', - type: { - defined: 'TokenData', - }, - }, - ], - }, - ], - types: [ - { - name: 'AccountState', - type: { - kind: 'enum', - variants: [ - { - name: 'Initialized', - }, - { - name: 'Frozen', - }, - ], - }, - }, - { - name: 'CompressedAccount', - type: { - kind: 'struct', - fields: [ - { - name: 'owner', - type: 'publicKey', - }, - { - name: 'lamports', - type: 'u64', - }, - { - name: 'address', - type: { - option: { - array: ['u8', 32], - }, - }, - }, - { - name: 'data', - type: { - option: { - defined: 'CompressedAccountData', - }, - }, - }, - ], - }, - }, - { - name: 'CompressedAccountData', - type: { - kind: 'struct', - fields: [ - { - name: 'discriminator', - type: { - array: ['u8', 8], - }, - }, - { - name: 'data', - type: 'bytes', - }, - { - name: 'dataHash', - type: { - array: ['u8', 32], - }, - }, - ], - }, - }, - { - name: 'CompressedCpiContext', - type: { - kind: 'struct', - fields: [ - { - name: 'setContext', - docs: [ - 'Is set by the program that is invoking the CPI to signal that is should', - 'set the cpi context.', - ], - type: 'bool', - }, - { - name: 'firstSetContext', - docs: [ - 'Is set to wipe the cpi context since someone could have set it before', - 'with unrelated data.', - ], - type: 'bool', - }, - { - name: 'cpiContextAccountIndex', - docs: [ - 'Index of cpi context account in remaining accounts.', - ], - type: 'u8', - }, - ], - }, - }, - { - name: 'CompressedProof', - type: { - kind: 'struct', - fields: [ - { - name: 'a', - type: { - array: ['u8', 32], - }, - }, - { - name: 'b', - type: { - array: ['u8', 64], - }, - }, - { - name: 'c', - type: { - array: ['u8', 32], - }, - }, - ], - }, - }, - { - name: 'CompressedTokenInstructionDataTransfer', - type: { - kind: 'struct', - fields: [ - { - name: 'proof', - type: { - option: { - defined: 'CompressedProof', - }, - }, - }, - { - name: 'mint', - type: 'publicKey', - }, - { - name: 'delegatedTransfer', - docs: [ - 'Is required if the signer is delegate,', - '-> delegate is authority account,', - 'owner = Some(owner) is the owner of the token account.', - ], - type: { - option: { - defined: 'DelegatedTransfer', - }, - }, - }, - { - name: 'inputTokenDataWithContext', - type: { - vec: { - defined: 'InputTokenDataWithContext', - }, - }, - }, - { - name: 'outputCompressedAccounts', - type: { - vec: { - defined: 'PackedTokenTransferOutputData', - }, - }, - }, - { - name: 'isCompress', - type: 'bool', - }, - { - name: 'compressOrDecompressAmount', - type: { - option: 'u64', - }, - }, - { - name: 'cpiContext', - type: { - option: { - defined: 'CompressedCpiContext', - }, - }, - }, - { - name: 'lamportsChangeAccountMerkleTreeIndex', - type: { - option: 'u8', - }, - }, - ], - }, - }, - { - name: 'DelegatedTransfer', - docs: [ - 'Struct to provide the owner when the delegate is signer of the transaction.', - ], - type: { - kind: 'struct', - fields: [ - { - name: 'owner', - type: 'publicKey', - }, - { - name: 'delegateChangeAccountIndex', - docs: [ - 'Index of change compressed account in output compressed accounts. In', - "case that the delegate didn't spend the complete delegated compressed", - 'account balance the change compressed account will be delegated to her', - 'as well.', - ], - type: { - option: 'u8', - }, - }, - ], - }, - }, - { - name: 'InputTokenDataWithContext', - type: { - kind: 'struct', - fields: [ - { - name: 'amount', - type: 'u64', - }, - { - name: 'delegateIndex', - type: { - option: 'u8', - }, - }, - { - name: 'merkleContext', - type: { - defined: 'PackedMerkleContext', - }, - }, - { - name: 'rootIndex', - type: 'u16', - }, - { - name: 'lamports', - type: { - option: 'u64', - }, - }, - { - name: 'tlv', - docs: [ - 'Placeholder for TokenExtension tlv data (unimplemented)', - ], - type: { - option: 'bytes', - }, - }, - ], - }, - }, - { - name: 'InstructionDataInvoke', - type: { - kind: 'struct', - fields: [ - { - name: 'proof', - type: { - option: { - defined: 'CompressedProof', - }, - }, - }, - { - name: 'inputCompressedAccountsWithMerkleContext', - type: { - vec: { - defined: - 'PackedCompressedAccountWithMerkleContext', - }, - }, - }, - { - name: 'outputCompressedAccounts', - type: { - vec: { - defined: - 'OutputCompressedAccountWithPackedContext', - }, - }, - }, - { - name: 'relayFee', - type: { - option: 'u64', - }, - }, - { - name: 'newAddressParams', - type: { - vec: { - defined: 'NewAddressParamsPacked', - }, - }, - }, - { - name: 'compressOrDecompressLamports', - type: { - option: 'u64', - }, - }, - { - name: 'isCompress', - type: 'bool', - }, - ], - }, - }, - { - name: 'InstructionDataInvokeCpi', - type: { - kind: 'struct', - fields: [ - { - name: 'proof', - type: { - option: { - defined: 'CompressedProof', - }, - }, - }, - { - name: 'newAddressParams', - type: { - vec: { - defined: 'NewAddressParamsPacked', - }, - }, - }, - { - name: 'inputCompressedAccountsWithMerkleContext', - type: { - vec: { - defined: - 'PackedCompressedAccountWithMerkleContext', - }, - }, - }, - { - name: 'outputCompressedAccounts', - type: { - vec: { - defined: - 'OutputCompressedAccountWithPackedContext', - }, - }, - }, - { - name: 'relayFee', - type: { - option: 'u64', - }, - }, - { - name: 'compressOrDecompressLamports', - type: { - option: 'u64', - }, - }, - { - name: 'isCompress', - type: 'bool', - }, - { - name: 'cpiContext', - type: { - option: { - defined: 'CompressedCpiContext', - }, - }, - }, - ], - }, - }, - { - name: 'MerkleTreeSequenceNumber', - type: { - kind: 'struct', - fields: [ - { - name: 'pubkey', - type: 'publicKey', - }, - { - name: 'seq', - type: 'u64', - }, - ], - }, - }, - { - name: 'NewAddressParamsPacked', - type: { - kind: 'struct', - fields: [ - { - name: 'seed', - type: { - array: ['u8', 32], - }, - }, - { - name: 'addressQueueAccountIndex', - type: 'u8', - }, - { - name: 'addressMerkleTreeAccountIndex', - type: 'u8', - }, - { - name: 'addressMerkleTreeRootIndex', - type: 'u16', - }, - ], - }, - }, - { - name: 'OutputCompressedAccountWithPackedContext', - type: { - kind: 'struct', - fields: [ - { - name: 'compressedAccount', - type: { - defined: 'CompressedAccount', - }, - }, - { - name: 'merkleTreeIndex', - type: 'u8', - }, - ], - }, - }, - { - name: 'PackedCompressedAccountWithMerkleContext', - type: { - kind: 'struct', - fields: [ - { - name: 'compressedAccount', - type: { - defined: 'CompressedAccount', - }, - }, - { - name: 'merkleContext', - type: { - defined: 'PackedMerkleContext', - }, - }, - { - name: 'rootIndex', - docs: [ - 'Index of root used in inclusion validity proof.', - ], - type: 'u16', - }, - { - name: 'readOnly', - docs: [ - 'Placeholder to mark accounts read-only unimplemented set to false.', - ], - type: 'bool', - }, - ], - }, - }, - { - name: 'PackedMerkleContext', - type: { - kind: 'struct', - fields: [ - { - name: 'merkleTreePubkeyIndex', - type: 'u8', - }, - { - name: 'nullifierQueuePubkeyIndex', - type: 'u8', - }, - { - name: 'leafIndex', - type: 'u32', - }, - { - name: 'queueIndex', - type: { - option: { - defined: 'QueueIndex', - }, - }, - }, - ], - }, - }, - { - name: 'PackedTokenTransferOutputData', - type: { - kind: 'struct', - fields: [ - { - name: 'owner', - type: 'publicKey', - }, - { - name: 'amount', - type: 'u64', - }, - { - name: 'lamports', - type: { - option: 'u64', - }, - }, - { - name: 'merkleTreeIndex', - type: 'u8', - }, - { - name: 'tlv', - docs: [ - 'Placeholder for TokenExtension tlv data (unimplemented)', - ], - type: { - option: 'bytes', - }, - }, - ], - }, - }, - { - name: 'PublicTransactionEvent', - type: { - kind: 'struct', - fields: [ - { - name: 'inputCompressedAccountHashes', - type: { - vec: { - array: ['u8', 32], - }, - }, - }, - { - name: 'outputCompressedAccountHashes', - type: { - vec: { - array: ['u8', 32], - }, - }, - }, - { - name: 'outputCompressedAccounts', - type: { - vec: { - defined: - 'OutputCompressedAccountWithPackedContext', - }, - }, - }, - { - name: 'outputLeafIndices', - type: { - vec: 'u32', - }, - }, - { - name: 'sequenceNumbers', - type: { - vec: { - defined: 'MerkleTreeSequenceNumber', - }, - }, - }, - { - name: 'relayFee', - type: { - option: 'u64', - }, - }, - { - name: 'isCompress', - type: 'bool', - }, - { - name: 'compressOrDecompressLamports', - type: { - option: 'u64', - }, - }, - { - name: 'pubkeyArray', - type: { - vec: 'publicKey', - }, - }, - { - name: 'message', - type: { - option: 'bytes', - }, - }, - ], - }, - }, - { - name: 'QueueIndex', - type: { - kind: 'struct', - fields: [ - { - name: 'queueId', - docs: ['Id of queue in queue account.'], - type: 'u8', - }, - { - name: 'index', - docs: ['Index of compressed account hash in queue.'], - type: 'u16', - }, - ], - }, - }, - { - name: 'TokenData', - type: { - kind: 'struct', - fields: [ - { - name: 'mint', - docs: ['The mint associated with this account'], - type: 'publicKey', - }, - { - name: 'owner', - docs: ['The owner of this account.'], - type: 'publicKey', - }, - { - name: 'amount', - docs: ['The amount of tokens this account holds.'], - type: 'u64', - }, - { - name: 'delegate', - docs: [ - 'If `delegate` is `Some` then `delegated_amount` represents', - 'the amount authorized by the delegate', - ], - type: { - option: 'publicKey', - }, - }, - { - name: 'state', - docs: ["The account's state"], - type: { - defined: 'AccountState', - }, - }, - { - name: 'tlv', - docs: [ - 'Placeholder for TokenExtension tlv data (unimplemented)', - ], - type: { - option: 'bytes', - }, - }, - ], - }, - }, - ], - errors: [ - { - code: 6000, - name: 'PublicKeyAmountMissmatch', - msg: 'public keys and amounts must be of same length', - }, - { - code: 6001, - name: 'ComputeInputSumFailed', - msg: 'ComputeInputSumFailed', - }, - { - code: 6002, - name: 'ComputeOutputSumFailed', - msg: 'ComputeOutputSumFailed', - }, - { - code: 6003, - name: 'ComputeCompressSumFailed', - msg: 'ComputeCompressSumFailed', - }, - { - code: 6004, - name: 'ComputeDecompressSumFailed', - msg: 'ComputeDecompressSumFailed', - }, - { - code: 6005, - name: 'SumCheckFailed', - msg: 'SumCheckFailed', - }, - { - code: 6006, - name: 'DecompressRecipientUndefinedForDecompress', - msg: 'DecompressRecipientUndefinedForDecompress', - }, - { - code: 6007, - name: 'CompressedPdaUndefinedForDecompress', - msg: 'CompressedPdaUndefinedForDecompress', - }, - { - code: 6008, - name: 'DeCompressAmountUndefinedForDecompress', - msg: 'DeCompressAmountUndefinedForDecompress', - }, - { - code: 6009, - name: 'CompressedPdaUndefinedForCompress', - msg: 'CompressedPdaUndefinedForCompress', - }, - { - code: 6010, - name: 'DeCompressAmountUndefinedForCompress', - msg: 'DeCompressAmountUndefinedForCompress', - }, - { - code: 6011, - name: 'DelegateSignerCheckFailed', - msg: 'DelegateSignerCheckFailed', - }, - { - code: 6012, - name: 'MintTooLarge', - msg: 'Minted amount greater than u64::MAX', - }, - { - code: 6013, - name: 'SplTokenSupplyMismatch', - msg: 'SplTokenSupplyMismatch', - }, - { - code: 6014, - name: 'HeapMemoryCheckFailed', - msg: 'HeapMemoryCheckFailed', - }, - { - code: 6015, - name: 'InstructionNotCallable', - msg: 'The instruction is not callable', - }, - { - code: 6016, - name: 'ArithmeticUnderflow', - msg: 'ArithmeticUnderflow', - }, - { - code: 6017, - name: 'HashToFieldError', - msg: 'HashToFieldError', - }, - { - code: 6018, - name: 'InvalidAuthorityMint', - msg: 'Expected the authority to be also a mint authority', - }, - { - code: 6019, - name: 'InvalidFreezeAuthority', - msg: 'Provided authority is not the freeze authority', - }, - { - code: 6020, - name: 'InvalidDelegateIndex', - }, - { - code: 6021, - name: 'TokenPoolPdaUndefined', - }, - { - code: 6022, - name: 'IsTokenPoolPda', - msg: 'Compress or decompress recipient is the same account as the token pool pda.', - }, - { - code: 6023, - name: 'InvalidTokenPoolPda', - }, - { - code: 6024, - name: 'NoInputTokenAccountsProvided', - }, - { - code: 6025, - name: 'NoInputsProvided', - }, - { - code: 6026, - name: 'MintHasNoFreezeAuthority', - }, - { - code: 6027, - name: 'MintWithInvalidExtension', - }, - { - code: 6028, - name: 'InsufficientTokenAccountBalance', - msg: 'The token account balance is less than the remaining amount.', - }, - { - code: 6029, - name: 'InvalidTokenPoolBump', - msg: 'Max number of token pools reached.', - }, - { - code: 6030, - name: 'FailedToDecompress', - }, - { - code: 6031, - name: 'FailedToBurnSplTokensFromTokenPool', - }, - { - code: 6032, - name: 'NoMatchingBumpFound', - }, - ], -}; diff --git a/js/stateless.js/src/idls/light_registry.ts b/js/stateless.js/src/idls/light_registry.ts deleted file mode 100644 index 05d9e23e78..0000000000 --- a/js/stateless.js/src/idls/light_registry.ts +++ /dev/null @@ -1,3483 +0,0 @@ -export type LightRegistry = { - version: '1.2.0'; - name: 'light_registry'; - constants: [ - { - name: 'FORESTER_SEED'; - type: 'bytes'; - value: '[102, 111, 114, 101, 115, 116, 101, 114]'; - }, - { - name: 'FORESTER_EPOCH_SEED'; - type: 'bytes'; - value: '[102, 111, 114, 101, 115, 116, 101, 114, 95, 101, 112, 111, 99, 104]'; - }, - { - name: 'PROTOCOL_CONFIG_PDA_SEED'; - type: 'bytes'; - value: '[97, 117, 116, 104, 111, 114, 105, 116, 121]'; - }, - { - name: 'DEFAULT_WORK_V1'; - type: 'u64'; - value: '1'; - }, - ]; - instructions: [ - { - name: 'initializeProtocolConfig'; - docs: [ - 'Initializes the protocol config pda. Can only be called once by the', - 'program account keypair.', - ]; - accounts: [ - { - name: 'feePayer'; - isMut: true; - isSigner: true; - }, - { - name: 'authority'; - isMut: false; - isSigner: true; - }, - { - name: 'protocolConfigPda'; - isMut: true; - isSigner: false; - }, - { - name: 'systemProgram'; - isMut: false; - isSigner: false; - }, - { - name: 'selfProgram'; - isMut: false; - isSigner: false; - }, - ]; - args: [ - { - name: 'bump'; - type: 'u8'; - }, - { - name: 'protocolConfig'; - type: { - defined: 'ProtocolConfig'; - }; - }, - ]; - }, - { - name: 'updateProtocolConfig'; - accounts: [ - { - name: 'feePayer'; - isMut: false; - isSigner: true; - }, - { - name: 'authority'; - isMut: false; - isSigner: true; - }, - { - name: 'protocolConfigPda'; - isMut: true; - isSigner: false; - }, - { - name: 'newAuthority'; - isMut: false; - isSigner: true; - isOptional: true; - }, - ]; - args: [ - { - name: 'protocolConfig'; - type: { - option: { - defined: 'ProtocolConfig'; - }; - }; - }, - ]; - }, - { - name: 'registerSystemProgram'; - accounts: [ - { - name: 'authority'; - isMut: true; - isSigner: true; - }, - { - name: 'protocolConfigPda'; - isMut: true; - isSigner: false; - }, - { - name: 'cpiAuthority'; - isMut: true; - isSigner: false; - }, - { - name: 'groupPda'; - isMut: true; - isSigner: false; - }, - { - name: 'accountCompressionProgram'; - isMut: false; - isSigner: false; - }, - { - name: 'systemProgram'; - isMut: false; - isSigner: false; - }, - { - name: 'registeredProgramPda'; - isMut: true; - isSigner: false; - }, - { - name: 'programToBeRegistered'; - isMut: false; - isSigner: true; - docs: [ - '- is signer so that only the program deployer can register a program.', - ]; - }, - ]; - args: [ - { - name: 'bump'; - type: 'u8'; - }, - ]; - }, - { - name: 'deregisterSystemProgram'; - accounts: [ - { - name: 'authority'; - isMut: true; - isSigner: true; - }, - { - name: 'protocolConfigPda'; - isMut: true; - isSigner: false; - }, - { - name: 'cpiAuthority'; - isMut: true; - isSigner: false; - }, - { - name: 'groupPda'; - isMut: true; - isSigner: false; - }, - { - name: 'accountCompressionProgram'; - isMut: false; - isSigner: false; - }, - { - name: 'registeredProgramPda'; - isMut: true; - isSigner: false; - }, - ]; - args: [ - { - name: 'bump'; - type: 'u8'; - }, - ]; - }, - { - name: 'registerForester'; - accounts: [ - { - name: 'feePayer'; - isMut: true; - isSigner: true; - }, - { - name: 'authority'; - isMut: false; - isSigner: true; - }, - { - name: 'protocolConfigPda'; - isMut: false; - isSigner: false; - }, - { - name: 'foresterPda'; - isMut: true; - isSigner: false; - }, - { - name: 'systemProgram'; - isMut: false; - isSigner: false; - }, - ]; - args: [ - { - name: 'bump'; - type: 'u8'; - }, - { - name: 'authority'; - type: 'publicKey'; - }, - { - name: 'config'; - type: { - defined: 'ForesterConfig'; - }; - }, - { - name: 'weight'; - type: { - option: 'u64'; - }; - }, - ]; - }, - { - name: 'updateForesterPda'; - accounts: [ - { - name: 'authority'; - isMut: false; - isSigner: true; - }, - { - name: 'foresterPda'; - isMut: true; - isSigner: false; - }, - { - name: 'newAuthority'; - isMut: false; - isSigner: true; - isOptional: true; - }, - ]; - args: [ - { - name: 'config'; - type: { - option: { - defined: 'ForesterConfig'; - }; - }; - }, - ]; - }, - { - name: 'updateForesterPdaWeight'; - accounts: [ - { - name: 'authority'; - isMut: false; - isSigner: true; - }, - { - name: 'protocolConfigPda'; - isMut: false; - isSigner: false; - }, - { - name: 'foresterPda'; - isMut: true; - isSigner: false; - }, - ]; - args: [ - { - name: 'newWeight'; - type: 'u64'; - }, - ]; - }, - { - name: 'registerForesterEpoch'; - docs: [ - 'Registers the forester for the epoch.', - '1. Only the forester can register herself for the epoch.', - '2. Protocol config is copied.', - '3. Epoch account is created if needed.', - ]; - accounts: [ - { - name: 'feePayer'; - isMut: true; - isSigner: true; - }, - { - name: 'authority'; - isMut: false; - isSigner: true; - }, - { - name: 'foresterPda'; - isMut: false; - isSigner: false; - }, - { - name: 'foresterEpochPda'; - isMut: true; - isSigner: false; - docs: [ - 'Instruction checks that current_epoch is the the current epoch and that', - 'the epoch is in registration phase.', - ]; - }, - { - name: 'protocolConfig'; - isMut: false; - isSigner: false; - }, - { - name: 'epochPda'; - isMut: true; - isSigner: false; - }, - { - name: 'systemProgram'; - isMut: false; - isSigner: false; - }, - ]; - args: [ - { - name: 'epoch'; - type: 'u64'; - }, - ]; - }, - { - name: 'finalizeRegistration'; - docs: [ - 'This transaction can be included as additional instruction in the first', - 'work instructions during the active phase.', - 'Registration Period must be over.', - ]; - accounts: [ - { - name: 'authority'; - isMut: false; - isSigner: true; - }, - { - name: 'foresterEpochPda'; - isMut: true; - isSigner: false; - }, - { - name: 'epochPda'; - isMut: false; - isSigner: false; - }, - ]; - args: []; - }, - { - name: 'reportWork'; - accounts: [ - { - name: 'authority'; - isMut: false; - isSigner: true; - }, - { - name: 'foresterEpochPda'; - isMut: true; - isSigner: false; - }, - { - name: 'epochPda'; - isMut: true; - isSigner: false; - }, - ]; - args: []; - }, - { - name: 'initializeAddressMerkleTree'; - accounts: [ - { - name: 'authority'; - isMut: true; - isSigner: true; - docs: [ - 'Anyone can create new trees just the fees cannot be set arbitrarily.', - ]; - }, - { - name: 'merkleTree'; - isMut: true; - isSigner: false; - }, - { - name: 'queue'; - isMut: true; - isSigner: false; - }, - { - name: 'registeredProgramPda'; - isMut: false; - isSigner: false; - }, - { - name: 'cpiAuthority'; - isMut: true; - isSigner: false; - }, - { - name: 'accountCompressionProgram'; - isMut: false; - isSigner: false; - }, - { - name: 'protocolConfigPda'; - isMut: false; - isSigner: false; - }, - { - name: 'cpiContextAccount'; - isMut: false; - isSigner: false; - isOptional: true; - }, - { - name: 'lightSystemProgram'; - isMut: false; - isSigner: false; - isOptional: true; - }, - ]; - args: [ - { - name: 'bump'; - type: 'u8'; - }, - { - name: 'programOwner'; - type: { - option: 'publicKey'; - }; - }, - { - name: 'forester'; - type: { - option: 'publicKey'; - }; - }, - { - name: 'merkleTreeConfig'; - type: { - defined: 'AddressMerkleTreeConfig'; - }; - }, - { - name: 'queueConfig'; - type: { - defined: 'AddressQueueConfig'; - }; - }, - ]; - }, - { - name: 'initializeStateMerkleTree'; - accounts: [ - { - name: 'authority'; - isMut: true; - isSigner: true; - docs: [ - 'Anyone can create new trees just the fees cannot be set arbitrarily.', - ]; - }, - { - name: 'merkleTree'; - isMut: true; - isSigner: false; - }, - { - name: 'queue'; - isMut: true; - isSigner: false; - }, - { - name: 'registeredProgramPda'; - isMut: false; - isSigner: false; - }, - { - name: 'cpiAuthority'; - isMut: true; - isSigner: false; - }, - { - name: 'accountCompressionProgram'; - isMut: false; - isSigner: false; - }, - { - name: 'protocolConfigPda'; - isMut: false; - isSigner: false; - }, - { - name: 'cpiContextAccount'; - isMut: false; - isSigner: false; - isOptional: true; - }, - { - name: 'lightSystemProgram'; - isMut: false; - isSigner: false; - isOptional: true; - }, - ]; - args: [ - { - name: 'bump'; - type: 'u8'; - }, - { - name: 'programOwner'; - type: { - option: 'publicKey'; - }; - }, - { - name: 'forester'; - type: { - option: 'publicKey'; - }; - }, - { - name: 'merkleTreeConfig'; - type: { - defined: 'StateMerkleTreeConfig'; - }; - }, - { - name: 'queueConfig'; - type: { - defined: 'NullifierQueueConfig'; - }; - }, - ]; - }, - { - name: 'nullify'; - accounts: [ - { - name: 'registeredForesterPda'; - isMut: true; - isSigner: false; - isOptional: true; - }, - { - name: 'authority'; - isMut: false; - isSigner: true; - }, - { - name: 'cpiAuthority'; - isMut: false; - isSigner: false; - }, - { - name: 'registeredProgramPda'; - isMut: false; - isSigner: false; - }, - { - name: 'accountCompressionProgram'; - isMut: false; - isSigner: false; - }, - { - name: 'logWrapper'; - isMut: false; - isSigner: false; - }, - { - name: 'merkleTree'; - isMut: true; - isSigner: false; - }, - { - name: 'nullifierQueue'; - isMut: true; - isSigner: false; - }, - ]; - args: [ - { - name: 'bump'; - type: 'u8'; - }, - { - name: 'changeLogIndices'; - type: { - vec: 'u64'; - }; - }, - { - name: 'leavesQueueIndices'; - type: { - vec: 'u16'; - }; - }, - { - name: 'indices'; - type: { - vec: 'u64'; - }; - }, - { - name: 'proofs'; - type: { - vec: { - vec: { - array: ['u8', 32]; - }; - }; - }; - }, - ]; - }, - { - name: 'updateAddressMerkleTree'; - accounts: [ - { - name: 'registeredForesterPda'; - isMut: true; - isSigner: false; - isOptional: true; - }, - { - name: 'authority'; - isMut: false; - isSigner: true; - }, - { - name: 'cpiAuthority'; - isMut: false; - isSigner: false; - }, - { - name: 'registeredProgramPda'; - isMut: false; - isSigner: false; - }, - { - name: 'accountCompressionProgram'; - isMut: false; - isSigner: false; - }, - { - name: 'queue'; - isMut: true; - isSigner: false; - }, - { - name: 'merkleTree'; - isMut: true; - isSigner: false; - }, - { - name: 'logWrapper'; - isMut: false; - isSigner: false; - }, - ]; - args: [ - { - name: 'bump'; - type: 'u8'; - }, - { - name: 'changelogIndex'; - type: 'u16'; - }, - { - name: 'indexedChangelogIndex'; - type: 'u16'; - }, - { - name: 'value'; - type: 'u16'; - }, - { - name: 'lowAddressIndex'; - type: 'u64'; - }, - { - name: 'lowAddressValue'; - type: { - array: ['u8', 32]; - }; - }, - { - name: 'lowAddressNextIndex'; - type: 'u64'; - }, - { - name: 'lowAddressNextValue'; - type: { - array: ['u8', 32]; - }; - }, - { - name: 'lowAddressProof'; - type: { - array: [ - { - array: ['u8', 32]; - }, - 16, - ]; - }; - }, - ]; - }, - { - name: 'rolloverAddressMerkleTreeAndQueue'; - accounts: [ - { - name: 'registeredForesterPda'; - isMut: true; - isSigner: false; - isOptional: true; - }, - { - name: 'authority'; - isMut: true; - isSigner: true; - }, - { - name: 'cpiAuthority'; - isMut: false; - isSigner: false; - }, - { - name: 'registeredProgramPda'; - isMut: false; - isSigner: false; - }, - { - name: 'accountCompressionProgram'; - isMut: false; - isSigner: false; - }, - { - name: 'newMerkleTree'; - isMut: true; - isSigner: false; - }, - { - name: 'newQueue'; - isMut: true; - isSigner: false; - }, - { - name: 'oldMerkleTree'; - isMut: true; - isSigner: false; - }, - { - name: 'oldQueue'; - isMut: true; - isSigner: false; - }, - ]; - args: [ - { - name: 'bump'; - type: 'u8'; - }, - ]; - }, - { - name: 'rolloverStateMerkleTreeAndQueue'; - accounts: [ - { - name: 'registeredForesterPda'; - isMut: true; - isSigner: false; - isOptional: true; - }, - { - name: 'authority'; - isMut: true; - isSigner: true; - }, - { - name: 'cpiAuthority'; - isMut: false; - isSigner: false; - }, - { - name: 'registeredProgramPda'; - isMut: false; - isSigner: false; - }, - { - name: 'accountCompressionProgram'; - isMut: false; - isSigner: false; - }, - { - name: 'newMerkleTree'; - isMut: true; - isSigner: false; - }, - { - name: 'newQueue'; - isMut: true; - isSigner: false; - }, - { - name: 'oldMerkleTree'; - isMut: true; - isSigner: false; - }, - { - name: 'oldQueue'; - isMut: true; - isSigner: false; - }, - { - name: 'cpiContextAccount'; - isMut: false; - isSigner: false; - }, - { - name: 'lightSystemProgram'; - isMut: false; - isSigner: false; - }, - { - name: 'protocolConfigPda'; - isMut: false; - isSigner: false; - }, - ]; - args: [ - { - name: 'bump'; - type: 'u8'; - }, - ]; - }, - { - name: 'initializeBatchedStateMerkleTree'; - accounts: [ - { - name: 'authority'; - isMut: true; - isSigner: true; - }, - { - name: 'merkleTree'; - isMut: true; - isSigner: false; - }, - { - name: 'queue'; - isMut: true; - isSigner: false; - }, - { - name: 'registeredProgramPda'; - isMut: false; - isSigner: false; - }, - { - name: 'cpiAuthority'; - isMut: true; - isSigner: false; - }, - { - name: 'accountCompressionProgram'; - isMut: false; - isSigner: false; - }, - { - name: 'protocolConfigPda'; - isMut: false; - isSigner: false; - }, - { - name: 'cpiContextAccount'; - isMut: false; - isSigner: false; - }, - { - name: 'lightSystemProgram'; - isMut: false; - isSigner: false; - }, - ]; - args: [ - { - name: 'bump'; - type: 'u8'; - }, - { - name: 'params'; - type: 'bytes'; - }, - ]; - }, - { - name: 'batchNullify'; - accounts: [ - { - name: 'registeredForesterPda'; - isMut: true; - isSigner: false; - isOptional: true; - }, - { - name: 'authority'; - isMut: false; - isSigner: true; - }, - { - name: 'cpiAuthority'; - isMut: false; - isSigner: false; - }, - { - name: 'registeredProgramPda'; - isMut: false; - isSigner: false; - }, - { - name: 'accountCompressionProgram'; - isMut: false; - isSigner: false; - }, - { - name: 'logWrapper'; - isMut: false; - isSigner: false; - }, - { - name: 'merkleTree'; - isMut: true; - isSigner: false; - }, - ]; - args: [ - { - name: 'bump'; - type: 'u8'; - }, - { - name: 'data'; - type: 'bytes'; - }, - ]; - }, - { - name: 'batchAppend'; - accounts: [ - { - name: 'registeredForesterPda'; - isMut: true; - isSigner: false; - isOptional: true; - }, - { - name: 'authority'; - isMut: false; - isSigner: true; - }, - { - name: 'cpiAuthority'; - isMut: false; - isSigner: false; - }, - { - name: 'registeredProgramPda'; - isMut: false; - isSigner: false; - }, - { - name: 'accountCompressionProgram'; - isMut: false; - isSigner: false; - }, - { - name: 'logWrapper'; - isMut: false; - isSigner: false; - }, - { - name: 'merkleTree'; - isMut: true; - isSigner: false; - }, - { - name: 'outputQueue'; - isMut: true; - isSigner: false; - }, - ]; - args: [ - { - name: 'bump'; - type: 'u8'; - }, - { - name: 'data'; - type: 'bytes'; - }, - ]; - }, - { - name: 'initializeBatchedAddressMerkleTree'; - accounts: [ - { - name: 'authority'; - isMut: true; - isSigner: true; - }, - { - name: 'merkleTree'; - isMut: true; - isSigner: false; - }, - { - name: 'registeredProgramPda'; - isMut: false; - isSigner: false; - }, - { - name: 'cpiAuthority'; - isMut: true; - isSigner: false; - }, - { - name: 'accountCompressionProgram'; - isMut: false; - isSigner: false; - }, - { - name: 'protocolConfigPda'; - isMut: false; - isSigner: false; - }, - ]; - args: [ - { - name: 'bump'; - type: 'u8'; - }, - { - name: 'params'; - type: 'bytes'; - }, - ]; - }, - { - name: 'batchUpdateAddressTree'; - accounts: [ - { - name: 'registeredForesterPda'; - isMut: true; - isSigner: false; - isOptional: true; - }, - { - name: 'authority'; - isMut: false; - isSigner: true; - }, - { - name: 'cpiAuthority'; - isMut: false; - isSigner: false; - }, - { - name: 'registeredProgramPda'; - isMut: false; - isSigner: false; - }, - { - name: 'accountCompressionProgram'; - isMut: false; - isSigner: false; - }, - { - name: 'logWrapper'; - isMut: false; - isSigner: false; - }, - { - name: 'merkleTree'; - isMut: true; - isSigner: false; - }, - ]; - args: [ - { - name: 'bump'; - type: 'u8'; - }, - { - name: 'data'; - type: 'bytes'; - }, - ]; - }, - { - name: 'rolloverBatchAddressMerkleTree'; - accounts: [ - { - name: 'registeredForesterPda'; - isMut: true; - isSigner: false; - isOptional: true; - }, - { - name: 'authority'; - isMut: true; - isSigner: true; - }, - { - name: 'newAddressMerkleTree'; - isMut: true; - isSigner: false; - }, - { - name: 'oldAddressMerkleTree'; - isMut: true; - isSigner: false; - }, - { - name: 'registeredProgramPda'; - isMut: false; - isSigner: false; - }, - { - name: 'cpiAuthority'; - isMut: true; - isSigner: false; - }, - { - name: 'accountCompressionProgram'; - isMut: false; - isSigner: false; - }, - { - name: 'protocolConfigPda'; - isMut: false; - isSigner: false; - }, - ]; - args: [ - { - name: 'bump'; - type: 'u8'; - }, - ]; - }, - { - name: 'rolloverBatchStateMerkleTree'; - accounts: [ - { - name: 'registeredForesterPda'; - isMut: true; - isSigner: false; - isOptional: true; - }, - { - name: 'authority'; - isMut: true; - isSigner: true; - }, - { - name: 'newStateMerkleTree'; - isMut: true; - isSigner: false; - }, - { - name: 'oldStateMerkleTree'; - isMut: true; - isSigner: false; - }, - { - name: 'newOutputQueue'; - isMut: true; - isSigner: false; - }, - { - name: 'oldOutputQueue'; - isMut: true; - isSigner: false; - }, - { - name: 'cpiContextAccount'; - isMut: false; - isSigner: false; - }, - { - name: 'registeredProgramPda'; - isMut: false; - isSigner: false; - }, - { - name: 'cpiAuthority'; - isMut: true; - isSigner: false; - }, - { - name: 'accountCompressionProgram'; - isMut: false; - isSigner: false; - }, - { - name: 'protocolConfigPda'; - isMut: false; - isSigner: false; - }, - { - name: 'lightSystemProgram'; - isMut: false; - isSigner: false; - }, - ]; - args: [ - { - name: 'bump'; - type: 'u8'; - }, - ]; - }, - { - name: 'migrateState'; - accounts: [ - { - name: 'registeredForesterPda'; - isMut: true; - isSigner: false; - }, - { - name: 'authority'; - isMut: false; - isSigner: true; - }, - { - name: 'cpiAuthority'; - isMut: false; - isSigner: false; - }, - { - name: 'registeredProgramPda'; - isMut: false; - isSigner: false; - }, - { - name: 'accountCompressionProgram'; - isMut: false; - isSigner: false; - }, - { - name: 'logWrapper'; - isMut: false; - isSigner: false; - }, - { - name: 'merkleTree'; - isMut: true; - isSigner: false; - }, - { - name: 'outputQueue'; - isMut: true; - isSigner: false; - }, - ]; - args: [ - { - name: 'bump'; - type: 'u8'; - }, - { - name: 'inputs'; - type: { - defined: 'MigrateLeafParams'; - }; - }, - ]; - }, - ]; - accounts: [ - { - name: 'epochPda'; - docs: ['Is used for tallying and rewards calculation']; - type: { - kind: 'struct'; - fields: [ - { - name: 'epoch'; - type: 'u64'; - }, - { - name: 'protocolConfig'; - type: { - defined: 'ProtocolConfig'; - }; - }, - { - name: 'totalWork'; - type: 'u64'; - }, - { - name: 'registeredWeight'; - type: 'u64'; - }, - ]; - }; - }, - { - name: 'foresterEpochPda'; - type: { - kind: 'struct'; - fields: [ - { - name: 'authority'; - type: 'publicKey'; - }, - { - name: 'config'; - type: { - defined: 'ForesterConfig'; - }; - }, - { - name: 'epoch'; - type: 'u64'; - }, - { - name: 'weight'; - type: 'u64'; - }, - { - name: 'workCounter'; - type: 'u64'; - }, - { - name: 'hasReportedWork'; - docs: [ - 'Work can be reported in an extra round to earn extra performance based', - 'rewards.', - ]; - type: 'bool'; - }, - { - name: 'foresterIndex'; - docs: [ - 'Start index of the range that determines when the forester is eligible to perform work.', - 'End index is forester_start_index + weight', - ]; - type: 'u64'; - }, - { - name: 'epochActivePhaseStartSlot'; - type: 'u64'; - }, - { - name: 'totalEpochWeight'; - docs: [ - 'Total epoch weight is registered weight of the epoch account after', - 'registration is concluded and active epoch period starts.', - ]; - type: { - option: 'u64'; - }; - }, - { - name: 'protocolConfig'; - type: { - defined: 'ProtocolConfig'; - }; - }, - { - name: 'finalizeCounter'; - docs: [ - 'Incremented every time finalize registration is called.', - ]; - type: 'u64'; - }, - ]; - }; - }, - { - name: 'protocolConfigPda'; - type: { - kind: 'struct'; - fields: [ - { - name: 'authority'; - type: 'publicKey'; - }, - { - name: 'bump'; - type: 'u8'; - }, - { - name: 'config'; - type: { - defined: 'ProtocolConfig'; - }; - }, - ]; - }; - }, - { - name: 'foresterPda'; - type: { - kind: 'struct'; - fields: [ - { - name: 'authority'; - type: 'publicKey'; - }, - { - name: 'config'; - type: { - defined: 'ForesterConfig'; - }; - }, - { - name: 'activeWeight'; - type: 'u64'; - }, - { - name: 'pendingWeight'; - docs: [ - 'Pending weight which will get active once the next epoch starts.', - ]; - type: 'u64'; - }, - { - name: 'currentEpoch'; - type: 'u64'; - }, - { - name: 'lastCompressedForesterEpochPdaHash'; - docs: [ - 'Link to previous compressed forester epoch account hash.', - ]; - type: { - array: ['u8', 32]; - }; - }, - { - name: 'lastRegisteredEpoch'; - type: 'u64'; - }, - ]; - }; - }, - ]; - types: [ - { - name: 'ProtocolConfig'; - docs: [ - 'Epoch Phases:', - '1. Registration', - '2. Active', - '3. Report Work', - '4. Post (Epoch has ended, and rewards can be claimed.)', - '- There is always an active phase in progress, registration and report work', - 'phases run in parallel to a currently active phase.', - ]; - type: { - kind: 'struct'; - fields: [ - { - name: 'genesisSlot'; - docs: [ - 'Solana slot when the protocol starts operating.', - ]; - type: 'u64'; - }, - { - name: 'minWeight'; - docs: [ - 'Minimum weight required for a forester to register to an epoch.', - ]; - type: 'u64'; - }, - { - name: 'slotLength'; - docs: ['Light protocol slot length.']; - type: 'u64'; - }, - { - name: 'registrationPhaseLength'; - docs: ['Foresters can register for this phase.']; - type: 'u64'; - }, - { - name: 'activePhaseLength'; - docs: ['Foresters can perform work in this phase.']; - type: 'u64'; - }, - { - name: 'reportWorkPhaseLength'; - docs: [ - 'Foresters can report work to receive performance based rewards in this', - 'phase.', - ]; - type: 'u64'; - }, - { - name: 'networkFee'; - type: 'u64'; - }, - { - name: 'cpiContextSize'; - type: 'u64'; - }, - { - name: 'finalizeCounterLimit'; - type: 'u64'; - }, - { - name: 'placeHolder'; - docs: ['Placeholder for future protocol updates.']; - type: 'publicKey'; - }, - { - name: 'placeHolderA'; - type: 'u64'; - }, - { - name: 'placeHolderB'; - type: 'u64'; - }, - { - name: 'placeHolderC'; - type: 'u64'; - }, - { - name: 'placeHolderD'; - type: 'u64'; - }, - { - name: 'placeHolderE'; - type: 'u64'; - }, - { - name: 'placeHolderF'; - type: 'u64'; - }, - ]; - }; - }, - { - name: 'ForesterConfig'; - type: { - kind: 'struct'; - fields: [ - { - name: 'fee'; - docs: ['Fee in percentage points.']; - type: 'u64'; - }, - ]; - }; - }, - { - name: 'EpochState'; - type: { - kind: 'enum'; - variants: [ - { - name: 'Registration'; - }, - { - name: 'Active'; - }, - { - name: 'ReportWork'; - }, - { - name: 'Post'; - }, - { - name: 'Pre'; - }, - ]; - }; - }, - ]; - errors: [ - { - code: 6000; - name: 'InvalidForester'; - msg: 'InvalidForester'; - }, - { - code: 6001; - name: 'NotInReportWorkPhase'; - }, - { - code: 6002; - name: 'StakeAccountAlreadySynced'; - }, - { - code: 6003; - name: 'EpochEnded'; - }, - { - code: 6004; - name: 'ForesterNotEligible'; - }, - { - code: 6005; - name: 'NotInRegistrationPeriod'; - }, - { - code: 6006; - name: 'WeightInsuffient'; - }, - { - code: 6007; - name: 'ForesterAlreadyRegistered'; - }, - { - code: 6008; - name: 'InvalidEpochAccount'; - }, - { - code: 6009; - name: 'InvalidEpoch'; - }, - { - code: 6010; - name: 'EpochStillInProgress'; - }, - { - code: 6011; - name: 'NotInActivePhase'; - }, - { - code: 6012; - name: 'ForesterAlreadyReportedWork'; - }, - { - code: 6013; - name: 'InvalidNetworkFee'; - }, - { - code: 6014; - name: 'FinalizeCounterExceeded'; - }, - { - code: 6015; - name: 'CpiContextAccountMissing'; - }, - { - code: 6016; - name: 'ArithmeticUnderflow'; - }, - { - code: 6017; - name: 'RegistrationNotFinalized'; - }, - { - code: 6018; - name: 'CpiContextAccountInvalidDataLen'; - }, - { - code: 6019; - name: 'InvalidConfigUpdate'; - }, - { - code: 6020; - name: 'InvalidSigner'; - }, - { - code: 6021; - name: 'GetLatestRegisterEpochFailed'; - }, - { - code: 6022; - name: 'GetCurrentActiveEpochFailed'; - }, - { - code: 6023; - name: 'ForesterUndefined'; - }, - { - code: 6024; - name: 'ForesterDefined'; - }, - ]; -}; - -export const IDL: LightRegistry = { - version: '1.2.0', - name: 'light_registry', - constants: [ - { - name: 'FORESTER_SEED', - type: 'bytes', - value: '[102, 111, 114, 101, 115, 116, 101, 114]', - }, - { - name: 'FORESTER_EPOCH_SEED', - type: 'bytes', - value: '[102, 111, 114, 101, 115, 116, 101, 114, 95, 101, 112, 111, 99, 104]', - }, - { - name: 'PROTOCOL_CONFIG_PDA_SEED', - type: 'bytes', - value: '[97, 117, 116, 104, 111, 114, 105, 116, 121]', - }, - { - name: 'DEFAULT_WORK_V1', - type: 'u64', - value: '1', - }, - ], - instructions: [ - { - name: 'initializeProtocolConfig', - docs: [ - 'Initializes the protocol config pda. Can only be called once by the', - 'program account keypair.', - ], - accounts: [ - { - name: 'feePayer', - isMut: true, - isSigner: true, - }, - { - name: 'authority', - isMut: false, - isSigner: true, - }, - { - name: 'protocolConfigPda', - isMut: true, - isSigner: false, - }, - { - name: 'systemProgram', - isMut: false, - isSigner: false, - }, - { - name: 'selfProgram', - isMut: false, - isSigner: false, - }, - ], - args: [ - { - name: 'bump', - type: 'u8', - }, - { - name: 'protocolConfig', - type: { - defined: 'ProtocolConfig', - }, - }, - ], - }, - { - name: 'updateProtocolConfig', - accounts: [ - { - name: 'feePayer', - isMut: false, - isSigner: true, - }, - { - name: 'authority', - isMut: false, - isSigner: true, - }, - { - name: 'protocolConfigPda', - isMut: true, - isSigner: false, - }, - { - name: 'newAuthority', - isMut: false, - isSigner: true, - isOptional: true, - }, - ], - args: [ - { - name: 'protocolConfig', - type: { - option: { - defined: 'ProtocolConfig', - }, - }, - }, - ], - }, - { - name: 'registerSystemProgram', - accounts: [ - { - name: 'authority', - isMut: true, - isSigner: true, - }, - { - name: 'protocolConfigPda', - isMut: true, - isSigner: false, - }, - { - name: 'cpiAuthority', - isMut: true, - isSigner: false, - }, - { - name: 'groupPda', - isMut: true, - isSigner: false, - }, - { - name: 'accountCompressionProgram', - isMut: false, - isSigner: false, - }, - { - name: 'systemProgram', - isMut: false, - isSigner: false, - }, - { - name: 'registeredProgramPda', - isMut: true, - isSigner: false, - }, - { - name: 'programToBeRegistered', - isMut: false, - isSigner: true, - docs: [ - '- is signer so that only the program deployer can register a program.', - ], - }, - ], - args: [ - { - name: 'bump', - type: 'u8', - }, - ], - }, - { - name: 'deregisterSystemProgram', - accounts: [ - { - name: 'authority', - isMut: true, - isSigner: true, - }, - { - name: 'protocolConfigPda', - isMut: true, - isSigner: false, - }, - { - name: 'cpiAuthority', - isMut: true, - isSigner: false, - }, - { - name: 'groupPda', - isMut: true, - isSigner: false, - }, - { - name: 'accountCompressionProgram', - isMut: false, - isSigner: false, - }, - { - name: 'registeredProgramPda', - isMut: true, - isSigner: false, - }, - ], - args: [ - { - name: 'bump', - type: 'u8', - }, - ], - }, - { - name: 'registerForester', - accounts: [ - { - name: 'feePayer', - isMut: true, - isSigner: true, - }, - { - name: 'authority', - isMut: false, - isSigner: true, - }, - { - name: 'protocolConfigPda', - isMut: false, - isSigner: false, - }, - { - name: 'foresterPda', - isMut: true, - isSigner: false, - }, - { - name: 'systemProgram', - isMut: false, - isSigner: false, - }, - ], - args: [ - { - name: 'bump', - type: 'u8', - }, - { - name: 'authority', - type: 'publicKey', - }, - { - name: 'config', - type: { - defined: 'ForesterConfig', - }, - }, - { - name: 'weight', - type: { - option: 'u64', - }, - }, - ], - }, - { - name: 'updateForesterPda', - accounts: [ - { - name: 'authority', - isMut: false, - isSigner: true, - }, - { - name: 'foresterPda', - isMut: true, - isSigner: false, - }, - { - name: 'newAuthority', - isMut: false, - isSigner: true, - isOptional: true, - }, - ], - args: [ - { - name: 'config', - type: { - option: { - defined: 'ForesterConfig', - }, - }, - }, - ], - }, - { - name: 'updateForesterPdaWeight', - accounts: [ - { - name: 'authority', - isMut: false, - isSigner: true, - }, - { - name: 'protocolConfigPda', - isMut: false, - isSigner: false, - }, - { - name: 'foresterPda', - isMut: true, - isSigner: false, - }, - ], - args: [ - { - name: 'newWeight', - type: 'u64', - }, - ], - }, - { - name: 'registerForesterEpoch', - docs: [ - 'Registers the forester for the epoch.', - '1. Only the forester can register herself for the epoch.', - '2. Protocol config is copied.', - '3. Epoch account is created if needed.', - ], - accounts: [ - { - name: 'feePayer', - isMut: true, - isSigner: true, - }, - { - name: 'authority', - isMut: false, - isSigner: true, - }, - { - name: 'foresterPda', - isMut: false, - isSigner: false, - }, - { - name: 'foresterEpochPda', - isMut: true, - isSigner: false, - docs: [ - 'Instruction checks that current_epoch is the the current epoch and that', - 'the epoch is in registration phase.', - ], - }, - { - name: 'protocolConfig', - isMut: false, - isSigner: false, - }, - { - name: 'epochPda', - isMut: true, - isSigner: false, - }, - { - name: 'systemProgram', - isMut: false, - isSigner: false, - }, - ], - args: [ - { - name: 'epoch', - type: 'u64', - }, - ], - }, - { - name: 'finalizeRegistration', - docs: [ - 'This transaction can be included as additional instruction in the first', - 'work instructions during the active phase.', - 'Registration Period must be over.', - ], - accounts: [ - { - name: 'authority', - isMut: false, - isSigner: true, - }, - { - name: 'foresterEpochPda', - isMut: true, - isSigner: false, - }, - { - name: 'epochPda', - isMut: false, - isSigner: false, - }, - ], - args: [], - }, - { - name: 'reportWork', - accounts: [ - { - name: 'authority', - isMut: false, - isSigner: true, - }, - { - name: 'foresterEpochPda', - isMut: true, - isSigner: false, - }, - { - name: 'epochPda', - isMut: true, - isSigner: false, - }, - ], - args: [], - }, - { - name: 'initializeAddressMerkleTree', - accounts: [ - { - name: 'authority', - isMut: true, - isSigner: true, - docs: [ - 'Anyone can create new trees just the fees cannot be set arbitrarily.', - ], - }, - { - name: 'merkleTree', - isMut: true, - isSigner: false, - }, - { - name: 'queue', - isMut: true, - isSigner: false, - }, - { - name: 'registeredProgramPda', - isMut: false, - isSigner: false, - }, - { - name: 'cpiAuthority', - isMut: true, - isSigner: false, - }, - { - name: 'accountCompressionProgram', - isMut: false, - isSigner: false, - }, - { - name: 'protocolConfigPda', - isMut: false, - isSigner: false, - }, - { - name: 'cpiContextAccount', - isMut: false, - isSigner: false, - isOptional: true, - }, - { - name: 'lightSystemProgram', - isMut: false, - isSigner: false, - isOptional: true, - }, - ], - args: [ - { - name: 'bump', - type: 'u8', - }, - { - name: 'programOwner', - type: { - option: 'publicKey', - }, - }, - { - name: 'forester', - type: { - option: 'publicKey', - }, - }, - { - name: 'merkleTreeConfig', - type: { - defined: 'AddressMerkleTreeConfig', - }, - }, - { - name: 'queueConfig', - type: { - defined: 'AddressQueueConfig', - }, - }, - ], - }, - { - name: 'initializeStateMerkleTree', - accounts: [ - { - name: 'authority', - isMut: true, - isSigner: true, - docs: [ - 'Anyone can create new trees just the fees cannot be set arbitrarily.', - ], - }, - { - name: 'merkleTree', - isMut: true, - isSigner: false, - }, - { - name: 'queue', - isMut: true, - isSigner: false, - }, - { - name: 'registeredProgramPda', - isMut: false, - isSigner: false, - }, - { - name: 'cpiAuthority', - isMut: true, - isSigner: false, - }, - { - name: 'accountCompressionProgram', - isMut: false, - isSigner: false, - }, - { - name: 'protocolConfigPda', - isMut: false, - isSigner: false, - }, - { - name: 'cpiContextAccount', - isMut: false, - isSigner: false, - isOptional: true, - }, - { - name: 'lightSystemProgram', - isMut: false, - isSigner: false, - isOptional: true, - }, - ], - args: [ - { - name: 'bump', - type: 'u8', - }, - { - name: 'programOwner', - type: { - option: 'publicKey', - }, - }, - { - name: 'forester', - type: { - option: 'publicKey', - }, - }, - { - name: 'merkleTreeConfig', - type: { - defined: 'StateMerkleTreeConfig', - }, - }, - { - name: 'queueConfig', - type: { - defined: 'NullifierQueueConfig', - }, - }, - ], - }, - { - name: 'nullify', - accounts: [ - { - name: 'registeredForesterPda', - isMut: true, - isSigner: false, - isOptional: true, - }, - { - name: 'authority', - isMut: false, - isSigner: true, - }, - { - name: 'cpiAuthority', - isMut: false, - isSigner: false, - }, - { - name: 'registeredProgramPda', - isMut: false, - isSigner: false, - }, - { - name: 'accountCompressionProgram', - isMut: false, - isSigner: false, - }, - { - name: 'logWrapper', - isMut: false, - isSigner: false, - }, - { - name: 'merkleTree', - isMut: true, - isSigner: false, - }, - { - name: 'nullifierQueue', - isMut: true, - isSigner: false, - }, - ], - args: [ - { - name: 'bump', - type: 'u8', - }, - { - name: 'changeLogIndices', - type: { - vec: 'u64', - }, - }, - { - name: 'leavesQueueIndices', - type: { - vec: 'u16', - }, - }, - { - name: 'indices', - type: { - vec: 'u64', - }, - }, - { - name: 'proofs', - type: { - vec: { - vec: { - array: ['u8', 32], - }, - }, - }, - }, - ], - }, - { - name: 'updateAddressMerkleTree', - accounts: [ - { - name: 'registeredForesterPda', - isMut: true, - isSigner: false, - isOptional: true, - }, - { - name: 'authority', - isMut: false, - isSigner: true, - }, - { - name: 'cpiAuthority', - isMut: false, - isSigner: false, - }, - { - name: 'registeredProgramPda', - isMut: false, - isSigner: false, - }, - { - name: 'accountCompressionProgram', - isMut: false, - isSigner: false, - }, - { - name: 'queue', - isMut: true, - isSigner: false, - }, - { - name: 'merkleTree', - isMut: true, - isSigner: false, - }, - { - name: 'logWrapper', - isMut: false, - isSigner: false, - }, - ], - args: [ - { - name: 'bump', - type: 'u8', - }, - { - name: 'changelogIndex', - type: 'u16', - }, - { - name: 'indexedChangelogIndex', - type: 'u16', - }, - { - name: 'value', - type: 'u16', - }, - { - name: 'lowAddressIndex', - type: 'u64', - }, - { - name: 'lowAddressValue', - type: { - array: ['u8', 32], - }, - }, - { - name: 'lowAddressNextIndex', - type: 'u64', - }, - { - name: 'lowAddressNextValue', - type: { - array: ['u8', 32], - }, - }, - { - name: 'lowAddressProof', - type: { - array: [ - { - array: ['u8', 32], - }, - 16, - ], - }, - }, - ], - }, - { - name: 'rolloverAddressMerkleTreeAndQueue', - accounts: [ - { - name: 'registeredForesterPda', - isMut: true, - isSigner: false, - isOptional: true, - }, - { - name: 'authority', - isMut: true, - isSigner: true, - }, - { - name: 'cpiAuthority', - isMut: false, - isSigner: false, - }, - { - name: 'registeredProgramPda', - isMut: false, - isSigner: false, - }, - { - name: 'accountCompressionProgram', - isMut: false, - isSigner: false, - }, - { - name: 'newMerkleTree', - isMut: true, - isSigner: false, - }, - { - name: 'newQueue', - isMut: true, - isSigner: false, - }, - { - name: 'oldMerkleTree', - isMut: true, - isSigner: false, - }, - { - name: 'oldQueue', - isMut: true, - isSigner: false, - }, - ], - args: [ - { - name: 'bump', - type: 'u8', - }, - ], - }, - { - name: 'rolloverStateMerkleTreeAndQueue', - accounts: [ - { - name: 'registeredForesterPda', - isMut: true, - isSigner: false, - isOptional: true, - }, - { - name: 'authority', - isMut: true, - isSigner: true, - }, - { - name: 'cpiAuthority', - isMut: false, - isSigner: false, - }, - { - name: 'registeredProgramPda', - isMut: false, - isSigner: false, - }, - { - name: 'accountCompressionProgram', - isMut: false, - isSigner: false, - }, - { - name: 'newMerkleTree', - isMut: true, - isSigner: false, - }, - { - name: 'newQueue', - isMut: true, - isSigner: false, - }, - { - name: 'oldMerkleTree', - isMut: true, - isSigner: false, - }, - { - name: 'oldQueue', - isMut: true, - isSigner: false, - }, - { - name: 'cpiContextAccount', - isMut: false, - isSigner: false, - }, - { - name: 'lightSystemProgram', - isMut: false, - isSigner: false, - }, - { - name: 'protocolConfigPda', - isMut: false, - isSigner: false, - }, - ], - args: [ - { - name: 'bump', - type: 'u8', - }, - ], - }, - { - name: 'initializeBatchedStateMerkleTree', - accounts: [ - { - name: 'authority', - isMut: true, - isSigner: true, - }, - { - name: 'merkleTree', - isMut: true, - isSigner: false, - }, - { - name: 'queue', - isMut: true, - isSigner: false, - }, - { - name: 'registeredProgramPda', - isMut: false, - isSigner: false, - }, - { - name: 'cpiAuthority', - isMut: true, - isSigner: false, - }, - { - name: 'accountCompressionProgram', - isMut: false, - isSigner: false, - }, - { - name: 'protocolConfigPda', - isMut: false, - isSigner: false, - }, - { - name: 'cpiContextAccount', - isMut: false, - isSigner: false, - }, - { - name: 'lightSystemProgram', - isMut: false, - isSigner: false, - }, - ], - args: [ - { - name: 'bump', - type: 'u8', - }, - { - name: 'params', - type: 'bytes', - }, - ], - }, - { - name: 'batchNullify', - accounts: [ - { - name: 'registeredForesterPda', - isMut: true, - isSigner: false, - isOptional: true, - }, - { - name: 'authority', - isMut: false, - isSigner: true, - }, - { - name: 'cpiAuthority', - isMut: false, - isSigner: false, - }, - { - name: 'registeredProgramPda', - isMut: false, - isSigner: false, - }, - { - name: 'accountCompressionProgram', - isMut: false, - isSigner: false, - }, - { - name: 'logWrapper', - isMut: false, - isSigner: false, - }, - { - name: 'merkleTree', - isMut: true, - isSigner: false, - }, - ], - args: [ - { - name: 'bump', - type: 'u8', - }, - { - name: 'data', - type: 'bytes', - }, - ], - }, - { - name: 'batchAppend', - accounts: [ - { - name: 'registeredForesterPda', - isMut: true, - isSigner: false, - isOptional: true, - }, - { - name: 'authority', - isMut: false, - isSigner: true, - }, - { - name: 'cpiAuthority', - isMut: false, - isSigner: false, - }, - { - name: 'registeredProgramPda', - isMut: false, - isSigner: false, - }, - { - name: 'accountCompressionProgram', - isMut: false, - isSigner: false, - }, - { - name: 'logWrapper', - isMut: false, - isSigner: false, - }, - { - name: 'merkleTree', - isMut: true, - isSigner: false, - }, - { - name: 'outputQueue', - isMut: true, - isSigner: false, - }, - ], - args: [ - { - name: 'bump', - type: 'u8', - }, - { - name: 'data', - type: 'bytes', - }, - ], - }, - { - name: 'initializeBatchedAddressMerkleTree', - accounts: [ - { - name: 'authority', - isMut: true, - isSigner: true, - }, - { - name: 'merkleTree', - isMut: true, - isSigner: false, - }, - { - name: 'registeredProgramPda', - isMut: false, - isSigner: false, - }, - { - name: 'cpiAuthority', - isMut: true, - isSigner: false, - }, - { - name: 'accountCompressionProgram', - isMut: false, - isSigner: false, - }, - { - name: 'protocolConfigPda', - isMut: false, - isSigner: false, - }, - ], - args: [ - { - name: 'bump', - type: 'u8', - }, - { - name: 'params', - type: 'bytes', - }, - ], - }, - { - name: 'batchUpdateAddressTree', - accounts: [ - { - name: 'registeredForesterPda', - isMut: true, - isSigner: false, - isOptional: true, - }, - { - name: 'authority', - isMut: false, - isSigner: true, - }, - { - name: 'cpiAuthority', - isMut: false, - isSigner: false, - }, - { - name: 'registeredProgramPda', - isMut: false, - isSigner: false, - }, - { - name: 'accountCompressionProgram', - isMut: false, - isSigner: false, - }, - { - name: 'logWrapper', - isMut: false, - isSigner: false, - }, - { - name: 'merkleTree', - isMut: true, - isSigner: false, - }, - ], - args: [ - { - name: 'bump', - type: 'u8', - }, - { - name: 'data', - type: 'bytes', - }, - ], - }, - { - name: 'rolloverBatchAddressMerkleTree', - accounts: [ - { - name: 'registeredForesterPda', - isMut: true, - isSigner: false, - isOptional: true, - }, - { - name: 'authority', - isMut: true, - isSigner: true, - }, - { - name: 'newAddressMerkleTree', - isMut: true, - isSigner: false, - }, - { - name: 'oldAddressMerkleTree', - isMut: true, - isSigner: false, - }, - { - name: 'registeredProgramPda', - isMut: false, - isSigner: false, - }, - { - name: 'cpiAuthority', - isMut: true, - isSigner: false, - }, - { - name: 'accountCompressionProgram', - isMut: false, - isSigner: false, - }, - { - name: 'protocolConfigPda', - isMut: false, - isSigner: false, - }, - ], - args: [ - { - name: 'bump', - type: 'u8', - }, - ], - }, - { - name: 'rolloverBatchStateMerkleTree', - accounts: [ - { - name: 'registeredForesterPda', - isMut: true, - isSigner: false, - isOptional: true, - }, - { - name: 'authority', - isMut: true, - isSigner: true, - }, - { - name: 'newStateMerkleTree', - isMut: true, - isSigner: false, - }, - { - name: 'oldStateMerkleTree', - isMut: true, - isSigner: false, - }, - { - name: 'newOutputQueue', - isMut: true, - isSigner: false, - }, - { - name: 'oldOutputQueue', - isMut: true, - isSigner: false, - }, - { - name: 'cpiContextAccount', - isMut: false, - isSigner: false, - }, - { - name: 'registeredProgramPda', - isMut: false, - isSigner: false, - }, - { - name: 'cpiAuthority', - isMut: true, - isSigner: false, - }, - { - name: 'accountCompressionProgram', - isMut: false, - isSigner: false, - }, - { - name: 'protocolConfigPda', - isMut: false, - isSigner: false, - }, - { - name: 'lightSystemProgram', - isMut: false, - isSigner: false, - }, - ], - args: [ - { - name: 'bump', - type: 'u8', - }, - ], - }, - { - name: 'migrateState', - accounts: [ - { - name: 'registeredForesterPda', - isMut: true, - isSigner: false, - }, - { - name: 'authority', - isMut: false, - isSigner: true, - }, - { - name: 'cpiAuthority', - isMut: false, - isSigner: false, - }, - { - name: 'registeredProgramPda', - isMut: false, - isSigner: false, - }, - { - name: 'accountCompressionProgram', - isMut: false, - isSigner: false, - }, - { - name: 'logWrapper', - isMut: false, - isSigner: false, - }, - { - name: 'merkleTree', - isMut: true, - isSigner: false, - }, - { - name: 'outputQueue', - isMut: true, - isSigner: false, - }, - ], - args: [ - { - name: 'bump', - type: 'u8', - }, - { - name: 'inputs', - type: { - defined: 'MigrateLeafParams', - }, - }, - ], - }, - ], - accounts: [ - { - name: 'epochPda', - docs: ['Is used for tallying and rewards calculation'], - type: { - kind: 'struct', - fields: [ - { - name: 'epoch', - type: 'u64', - }, - { - name: 'protocolConfig', - type: { - defined: 'ProtocolConfig', - }, - }, - { - name: 'totalWork', - type: 'u64', - }, - { - name: 'registeredWeight', - type: 'u64', - }, - ], - }, - }, - { - name: 'foresterEpochPda', - type: { - kind: 'struct', - fields: [ - { - name: 'authority', - type: 'publicKey', - }, - { - name: 'config', - type: { - defined: 'ForesterConfig', - }, - }, - { - name: 'epoch', - type: 'u64', - }, - { - name: 'weight', - type: 'u64', - }, - { - name: 'workCounter', - type: 'u64', - }, - { - name: 'hasReportedWork', - docs: [ - 'Work can be reported in an extra round to earn extra performance based', - 'rewards.', - ], - type: 'bool', - }, - { - name: 'foresterIndex', - docs: [ - 'Start index of the range that determines when the forester is eligible to perform work.', - 'End index is forester_start_index + weight', - ], - type: 'u64', - }, - { - name: 'epochActivePhaseStartSlot', - type: 'u64', - }, - { - name: 'totalEpochWeight', - docs: [ - 'Total epoch weight is registered weight of the epoch account after', - 'registration is concluded and active epoch period starts.', - ], - type: { - option: 'u64', - }, - }, - { - name: 'protocolConfig', - type: { - defined: 'ProtocolConfig', - }, - }, - { - name: 'finalizeCounter', - docs: [ - 'Incremented every time finalize registration is called.', - ], - type: 'u64', - }, - ], - }, - }, - { - name: 'protocolConfigPda', - type: { - kind: 'struct', - fields: [ - { - name: 'authority', - type: 'publicKey', - }, - { - name: 'bump', - type: 'u8', - }, - { - name: 'config', - type: { - defined: 'ProtocolConfig', - }, - }, - ], - }, - }, - { - name: 'foresterPda', - type: { - kind: 'struct', - fields: [ - { - name: 'authority', - type: 'publicKey', - }, - { - name: 'config', - type: { - defined: 'ForesterConfig', - }, - }, - { - name: 'activeWeight', - type: 'u64', - }, - { - name: 'pendingWeight', - docs: [ - 'Pending weight which will get active once the next epoch starts.', - ], - type: 'u64', - }, - { - name: 'currentEpoch', - type: 'u64', - }, - { - name: 'lastCompressedForesterEpochPdaHash', - docs: [ - 'Link to previous compressed forester epoch account hash.', - ], - type: { - array: ['u8', 32], - }, - }, - { - name: 'lastRegisteredEpoch', - type: 'u64', - }, - ], - }, - }, - ], - types: [ - { - name: 'ProtocolConfig', - docs: [ - 'Epoch Phases:', - '1. Registration', - '2. Active', - '3. Report Work', - '4. Post (Epoch has ended, and rewards can be claimed.)', - '- There is always an active phase in progress, registration and report work', - 'phases run in parallel to a currently active phase.', - ], - type: { - kind: 'struct', - fields: [ - { - name: 'genesisSlot', - docs: [ - 'Solana slot when the protocol starts operating.', - ], - type: 'u64', - }, - { - name: 'minWeight', - docs: [ - 'Minimum weight required for a forester to register to an epoch.', - ], - type: 'u64', - }, - { - name: 'slotLength', - docs: ['Light protocol slot length.'], - type: 'u64', - }, - { - name: 'registrationPhaseLength', - docs: ['Foresters can register for this phase.'], - type: 'u64', - }, - { - name: 'activePhaseLength', - docs: ['Foresters can perform work in this phase.'], - type: 'u64', - }, - { - name: 'reportWorkPhaseLength', - docs: [ - 'Foresters can report work to receive performance based rewards in this', - 'phase.', - ], - type: 'u64', - }, - { - name: 'networkFee', - type: 'u64', - }, - { - name: 'cpiContextSize', - type: 'u64', - }, - { - name: 'finalizeCounterLimit', - type: 'u64', - }, - { - name: 'placeHolder', - docs: ['Placeholder for future protocol updates.'], - type: 'publicKey', - }, - { - name: 'placeHolderA', - type: 'u64', - }, - { - name: 'placeHolderB', - type: 'u64', - }, - { - name: 'placeHolderC', - type: 'u64', - }, - { - name: 'placeHolderD', - type: 'u64', - }, - { - name: 'placeHolderE', - type: 'u64', - }, - { - name: 'placeHolderF', - type: 'u64', - }, - ], - }, - }, - { - name: 'ForesterConfig', - type: { - kind: 'struct', - fields: [ - { - name: 'fee', - docs: ['Fee in percentage points.'], - type: 'u64', - }, - ], - }, - }, - { - name: 'EpochState', - type: { - kind: 'enum', - variants: [ - { - name: 'Registration', - }, - { - name: 'Active', - }, - { - name: 'ReportWork', - }, - { - name: 'Post', - }, - { - name: 'Pre', - }, - ], - }, - }, - ], - errors: [ - { - code: 6000, - name: 'InvalidForester', - msg: 'InvalidForester', - }, - { - code: 6001, - name: 'NotInReportWorkPhase', - }, - { - code: 6002, - name: 'StakeAccountAlreadySynced', - }, - { - code: 6003, - name: 'EpochEnded', - }, - { - code: 6004, - name: 'ForesterNotEligible', - }, - { - code: 6005, - name: 'NotInRegistrationPeriod', - }, - { - code: 6006, - name: 'WeightInsuffient', - }, - { - code: 6007, - name: 'ForesterAlreadyRegistered', - }, - { - code: 6008, - name: 'InvalidEpochAccount', - }, - { - code: 6009, - name: 'InvalidEpoch', - }, - { - code: 6010, - name: 'EpochStillInProgress', - }, - { - code: 6011, - name: 'NotInActivePhase', - }, - { - code: 6012, - name: 'ForesterAlreadyReportedWork', - }, - { - code: 6013, - name: 'InvalidNetworkFee', - }, - { - code: 6014, - name: 'FinalizeCounterExceeded', - }, - { - code: 6015, - name: 'CpiContextAccountMissing', - }, - { - code: 6016, - name: 'ArithmeticUnderflow', - }, - { - code: 6017, - name: 'RegistrationNotFinalized', - }, - { - code: 6018, - name: 'CpiContextAccountInvalidDataLen', - }, - { - code: 6019, - name: 'InvalidConfigUpdate', - }, - { - code: 6020, - name: 'InvalidSigner', - }, - { - code: 6021, - name: 'GetLatestRegisterEpochFailed', - }, - { - code: 6022, - name: 'GetCurrentActiveEpochFailed', - }, - { - code: 6023, - name: 'ForesterUndefined', - }, - { - code: 6024, - name: 'ForesterDefined', - }, - ], -}; diff --git a/js/stateless.js/src/idls/light_system_program.ts b/js/stateless.js/src/idls/light_system_program.ts deleted file mode 100644 index b552e537f4..0000000000 --- a/js/stateless.js/src/idls/light_system_program.ts +++ /dev/null @@ -1,2034 +0,0 @@ -export type LightSystemProgram = { - version: '1.2.0'; - name: 'light_system_program'; - constants: [ - { - name: 'SOL_POOL_PDA_SEED'; - type: 'bytes'; - value: '[115, 111, 108, 95, 112, 111, 111, 108, 95, 112, 100, 97]'; - }, - ]; - instructions: [ - { - name: 'initCpiContextAccount'; - accounts: [ - { - name: 'feePayer'; - isMut: true; - isSigner: true; - }, - { - name: 'cpiContextAccount'; - isMut: true; - isSigner: false; - }, - { - name: 'associatedMerkleTree'; - isMut: false; - isSigner: false; - }, - ]; - args: []; - }, - { - name: 'invoke'; - accounts: [ - { - name: 'feePayer'; - isMut: true; - isSigner: true; - docs: [ - 'Fee payer needs to be mutable to pay rollover and protocol fees.', - ]; - }, - { - name: 'authority'; - isMut: false; - isSigner: true; - }, - { - name: 'registeredProgramPda'; - isMut: false; - isSigner: false; - }, - { - name: 'noopProgram'; - isMut: false; - isSigner: false; - }, - { - name: 'accountCompressionAuthority'; - isMut: false; - isSigner: false; - docs: [ - 'This pda is used to invoke the account compression program.', - ]; - }, - { - name: 'accountCompressionProgram'; - isMut: false; - isSigner: false; - docs: ['Merkle trees.']; - }, - { - name: 'solPoolPda'; - isMut: true; - isSigner: false; - isOptional: true; - docs: [ - 'Sol pool pda is used to store the native sol that has been compressed.', - "It's only required when compressing or decompressing sol.", - ]; - }, - { - name: 'decompressionRecipient'; - isMut: true; - isSigner: false; - isOptional: true; - docs: [ - 'Only needs to be provided for decompression as a recipient for the', - 'decompressed sol.', - 'Compressed sol originate from authority.', - ]; - }, - { - name: 'systemProgram'; - isMut: false; - isSigner: false; - }, - ]; - args: [ - { - name: 'inputs'; - type: 'bytes'; - }, - ]; - }, - { - name: 'invokeCpi'; - accounts: [ - { - name: 'feePayer'; - isMut: true; - isSigner: true; - docs: [ - 'Fee payer needs to be mutable to pay rollover and protocol fees.', - ]; - }, - { - name: 'authority'; - isMut: false; - isSigner: true; - }, - { - name: 'registeredProgramPda'; - isMut: false; - isSigner: false; - }, - { - name: 'noopProgram'; - isMut: false; - isSigner: false; - }, - { - name: 'accountCompressionAuthority'; - isMut: false; - isSigner: false; - }, - { - name: 'accountCompressionProgram'; - isMut: false; - isSigner: false; - }, - { - name: 'invokingProgram'; - isMut: false; - isSigner: false; - }, - { - name: 'solPoolPda'; - isMut: true; - isSigner: false; - isOptional: true; - }, - { - name: 'decompressionRecipient'; - isMut: true; - isSigner: false; - isOptional: true; - }, - { - name: 'systemProgram'; - isMut: false; - isSigner: false; - }, - { - name: 'cpiContextAccount'; - isMut: true; - isSigner: false; - isOptional: true; - }, - ]; - args: [ - { - name: 'inputs'; - type: 'bytes'; - }, - ]; - }, - { - name: 'invokeCpiWithReadOnly'; - accounts: [ - { - name: 'feePayer'; - isMut: true; - isSigner: true; - docs: [ - 'Fee payer needs to be mutable to pay rollover and protocol fees.', - ]; - }, - { - name: 'authority'; - isMut: false; - isSigner: true; - }, - { - name: 'registeredProgramPda'; - isMut: false; - isSigner: false; - }, - { - name: 'noopProgram'; - isMut: false; - isSigner: false; - }, - { - name: 'accountCompressionAuthority'; - isMut: false; - isSigner: false; - }, - { - name: 'accountCompressionProgram'; - isMut: false; - isSigner: false; - }, - { - name: 'invokingProgram'; - isMut: false; - isSigner: false; - }, - { - name: 'solPoolPda'; - isMut: true; - isSigner: false; - isOptional: true; - }, - { - name: 'decompressionRecipient'; - isMut: true; - isSigner: false; - isOptional: true; - }, - { - name: 'systemProgram'; - isMut: false; - isSigner: false; - }, - { - name: 'cpiContextAccount'; - isMut: true; - isSigner: false; - isOptional: true; - }, - ]; - args: [ - { - name: 'inputs'; - type: 'bytes'; - }, - ]; - }, - { - name: 'stubIdlBuild'; - docs: [ - 'This function is a stub to allow Anchor to include the input types in', - 'the IDL. It should not be included in production builds nor be called in', - 'practice.', - ]; - accounts: [ - { - name: 'feePayer'; - isMut: true; - isSigner: true; - docs: [ - 'Fee payer needs to be mutable to pay rollover and protocol fees.', - ]; - }, - { - name: 'authority'; - isMut: false; - isSigner: true; - }, - { - name: 'registeredProgramPda'; - isMut: false; - isSigner: false; - }, - { - name: 'noopProgram'; - isMut: false; - isSigner: false; - }, - { - name: 'accountCompressionAuthority'; - isMut: false; - isSigner: false; - docs: [ - 'This pda is used to invoke the account compression program.', - ]; - }, - { - name: 'accountCompressionProgram'; - isMut: false; - isSigner: false; - docs: ['Merkle trees.']; - }, - { - name: 'solPoolPda'; - isMut: true; - isSigner: false; - isOptional: true; - docs: [ - 'Sol pool pda is used to store the native sol that has been compressed.', - "It's only required when compressing or decompressing sol.", - ]; - }, - { - name: 'decompressionRecipient'; - isMut: true; - isSigner: false; - isOptional: true; - docs: [ - 'Only needs to be provided for decompression as a recipient for the', - 'decompressed sol.', - 'Compressed sol originate from authority.', - ]; - }, - { - name: 'systemProgram'; - isMut: false; - isSigner: false; - }, - ]; - args: [ - { - name: 'inputs1'; - type: { - defined: 'InstructionDataInvoke'; - }; - }, - { - name: 'inputs2'; - type: { - defined: 'InstructionDataInvokeCpi'; - }; - }, - { - name: 'inputs3'; - type: { - defined: 'PublicTransactionEvent'; - }; - }, - ]; - }, - ]; - accounts: [ - { - name: 'cpiContextAccount'; - docs: [ - 'Collects instruction data without executing a compressed transaction.', - 'Signer checks are performed on instruction data.', - 'Collected instruction data is combined with the instruction data of the executing cpi,', - 'and executed as a single transaction.', - 'This enables to use input compressed accounts that are owned by multiple programs,', - 'with one zero-knowledge proof.', - ]; - type: { - kind: 'struct'; - fields: [ - { - name: 'feePayer'; - type: 'publicKey'; - }, - { - name: 'associatedMerkleTree'; - type: 'publicKey'; - }, - { - name: 'context'; - type: { - vec: { - defined: 'InstructionDataInvokeCpi'; - }; - }; - }, - ]; - }; - }, - ]; - types: [ - { - name: 'InstructionDataInvoke'; - type: { - kind: 'struct'; - fields: [ - { - name: 'proof'; - type: { - option: { - defined: 'CompressedProof'; - }; - }; - }, - { - name: 'inputCompressedAccountsWithMerkleContext'; - type: { - vec: { - defined: 'PackedCompressedAccountWithMerkleContext'; - }; - }; - }, - { - name: 'outputCompressedAccounts'; - type: { - vec: { - defined: 'OutputCompressedAccountWithPackedContext'; - }; - }; - }, - { - name: 'relayFee'; - type: { - option: 'u64'; - }; - }, - { - name: 'newAddressParams'; - type: { - vec: { - defined: 'NewAddressParamsPacked'; - }; - }; - }, - { - name: 'compressOrDecompressLamports'; - type: { - option: 'u64'; - }; - }, - { - name: 'isCompress'; - type: 'bool'; - }, - ]; - }; - }, - { - name: 'NewAddressParamsPacked'; - type: { - kind: 'struct'; - fields: [ - { - name: 'seed'; - type: { - array: ['u8', 32]; - }; - }, - { - name: 'addressQueueAccountIndex'; - type: 'u8'; - }, - { - name: 'addressMerkleTreeAccountIndex'; - type: 'u8'; - }, - { - name: 'addressMerkleTreeRootIndex'; - type: 'u16'; - }, - ]; - }; - }, - { - name: 'OutputCompressedAccountWithPackedContext'; - type: { - kind: 'struct'; - fields: [ - { - name: 'compressedAccount'; - type: { - defined: 'CompressedAccount'; - }; - }, - { - name: 'merkleTreeIndex'; - type: 'u8'; - }, - ]; - }; - }, - { - name: 'CompressedProof'; - type: { - kind: 'struct'; - fields: [ - { - name: 'a'; - type: { - array: ['u8', 32]; - }; - }, - { - name: 'b'; - type: { - array: ['u8', 64]; - }; - }, - { - name: 'c'; - type: { - array: ['u8', 32]; - }; - }, - ]; - }; - }, - { - name: 'InstructionDataInvokeCpi'; - type: { - kind: 'struct'; - fields: [ - { - name: 'proof'; - type: { - option: { - defined: 'CompressedProof'; - }; - }; - }, - { - name: 'newAddressParams'; - type: { - vec: { - defined: 'NewAddressParamsPacked'; - }; - }; - }, - { - name: 'inputCompressedAccountsWithMerkleContext'; - type: { - vec: { - defined: 'PackedCompressedAccountWithMerkleContext'; - }; - }; - }, - { - name: 'outputCompressedAccounts'; - type: { - vec: { - defined: 'OutputCompressedAccountWithPackedContext'; - }; - }; - }, - { - name: 'relayFee'; - type: { - option: 'u64'; - }; - }, - { - name: 'compressOrDecompressLamports'; - type: { - option: 'u64'; - }; - }, - { - name: 'isCompress'; - type: 'bool'; - }, - { - name: 'cpiContext'; - type: { - option: { - defined: 'CompressedCpiContext'; - }; - }; - }, - ]; - }; - }, - { - name: 'CompressedCpiContext'; - type: { - kind: 'struct'; - fields: [ - { - name: 'setContext'; - docs: [ - 'Is set by the program that is invoking the CPI to signal that is should', - 'set the cpi context.', - ]; - type: 'bool'; - }, - { - name: 'firstSetContext'; - docs: [ - 'Is set to wipe the cpi context since someone could have set it before', - 'with unrelated data.', - ]; - type: 'bool'; - }, - { - name: 'cpiContextAccountIndex'; - docs: [ - 'Index of cpi context account in remaining accounts.', - ]; - type: 'u8'; - }, - ]; - }; - }, - { - name: 'CompressedAccount'; - type: { - kind: 'struct'; - fields: [ - { - name: 'owner'; - type: 'publicKey'; - }, - { - name: 'lamports'; - type: 'u64'; - }, - { - name: 'address'; - type: { - option: { - array: ['u8', 32]; - }; - }; - }, - { - name: 'data'; - type: { - option: { - defined: 'CompressedAccountData'; - }; - }; - }, - ]; - }; - }, - { - name: 'CompressedAccountData'; - type: { - kind: 'struct'; - fields: [ - { - name: 'discriminator'; - type: { - array: ['u8', 8]; - }; - }, - { - name: 'data'; - type: 'bytes'; - }, - { - name: 'dataHash'; - type: { - array: ['u8', 32]; - }; - }, - ]; - }; - }, - { - name: 'PackedCompressedAccountWithMerkleContext'; - type: { - kind: 'struct'; - fields: [ - { - name: 'compressedAccount'; - type: { - defined: 'CompressedAccount'; - }; - }, - { - name: 'merkleContext'; - type: { - defined: 'PackedMerkleContext'; - }; - }, - { - name: 'rootIndex'; - docs: [ - 'Index of root used in inclusion validity proof.', - ]; - type: 'u16'; - }, - { - name: 'readOnly'; - docs: [ - 'Placeholder to mark accounts read-only unimplemented set to false.', - ]; - type: 'bool'; - }, - ]; - }; - }, - { - name: 'PackedMerkleContext'; - type: { - kind: 'struct'; - fields: [ - { - name: 'merkleTreePubkeyIndex'; - type: 'u8'; - }, - { - name: 'nullifierQueuePubkeyIndex'; - type: 'u8'; - }, - { - name: 'leafIndex'; - type: 'u32'; - }, - { - name: 'queueIndex'; - type: { - option: { - defined: 'QueueIndex'; - }; - }; - }, - ]; - }; - }, - { - name: 'QueueIndex'; - type: { - kind: 'struct'; - fields: [ - { - name: 'queueId'; - docs: ['Id of queue in queue account.']; - type: 'u8'; - }, - { - name: 'index'; - docs: ['Index of compressed account hash in queue.']; - type: 'u16'; - }, - ]; - }; - }, - { - name: 'MerkleTreeSequenceNumber'; - type: { - kind: 'struct'; - fields: [ - { - name: 'pubkey'; - type: 'publicKey'; - }, - { - name: 'seq'; - type: 'u64'; - }, - ]; - }; - }, - { - name: 'PublicTransactionEvent'; - type: { - kind: 'struct'; - fields: [ - { - name: 'inputCompressedAccountHashes'; - type: { - vec: { - array: ['u8', 32]; - }; - }; - }, - { - name: 'outputCompressedAccountHashes'; - type: { - vec: { - array: ['u8', 32]; - }; - }; - }, - { - name: 'outputCompressedAccounts'; - type: { - vec: { - defined: 'OutputCompressedAccountWithPackedContext'; - }; - }; - }, - { - name: 'outputLeafIndices'; - type: { - vec: 'u32'; - }; - }, - { - name: 'sequenceNumbers'; - type: { - vec: { - defined: 'MerkleTreeSequenceNumber'; - }; - }; - }, - { - name: 'relayFee'; - type: { - option: 'u64'; - }; - }, - { - name: 'isCompress'; - type: 'bool'; - }, - { - name: 'compressOrDecompressLamports'; - type: { - option: 'u64'; - }; - }, - { - name: 'pubkeyArray'; - type: { - vec: 'publicKey'; - }; - }, - { - name: 'message'; - type: { - option: 'bytes'; - }; - }, - ]; - }; - }, - ]; - errors: [ - { - code: 6000; - name: 'SumCheckFailed'; - msg: 'Sum check failed'; - }, - { - code: 6001; - name: 'SignerCheckFailed'; - msg: 'Signer check failed'; - }, - { - code: 6002; - name: 'CpiSignerCheckFailed'; - msg: 'Cpi signer check failed'; - }, - { - code: 6003; - name: 'ComputeInputSumFailed'; - msg: 'Computing input sum failed.'; - }, - { - code: 6004; - name: 'ComputeOutputSumFailed'; - msg: 'Computing output sum failed.'; - }, - { - code: 6005; - name: 'ComputeRpcSumFailed'; - msg: 'Computing rpc sum failed.'; - }, - { - code: 6006; - name: 'InvalidAddress'; - msg: 'InvalidAddress'; - }, - { - code: 6007; - name: 'DeriveAddressError'; - msg: 'DeriveAddressError'; - }, - { - code: 6008; - name: 'CompressedSolPdaUndefinedForCompressSol'; - msg: 'CompressedSolPdaUndefinedForCompressSol'; - }, - { - code: 6009; - name: 'DeCompressLamportsUndefinedForCompressSol'; - msg: 'DeCompressLamportsUndefinedForCompressSol'; - }, - { - code: 6010; - name: 'CompressedSolPdaUndefinedForDecompressSol'; - msg: 'CompressedSolPdaUndefinedForDecompressSol'; - }, - { - code: 6011; - name: 'DeCompressLamportsUndefinedForDecompressSol'; - msg: 'DeCompressLamportsUndefinedForDecompressSol'; - }, - { - code: 6012; - name: 'DecompressRecipientUndefinedForDecompressSol'; - msg: 'DecompressRecipientUndefinedForDecompressSol'; - }, - { - code: 6013; - name: 'WriteAccessCheckFailed'; - msg: 'WriteAccessCheckFailed'; - }, - { - code: 6014; - name: 'InvokingProgramNotProvided'; - msg: 'InvokingProgramNotProvided'; - }, - { - code: 6015; - name: 'InvalidCapacity'; - msg: 'InvalidCapacity'; - }, - { - code: 6016; - name: 'InvalidMerkleTreeOwner'; - msg: 'InvalidMerkleTreeOwner'; - }, - { - code: 6017; - name: 'ProofIsNone'; - msg: 'ProofIsNone'; - }, - { - code: 6018; - name: 'ProofIsSome'; - msg: 'Proof is some but no input compressed accounts or new addresses provided.'; - }, - { - code: 6019; - name: 'EmptyInputs'; - msg: 'EmptyInputs'; - }, - { - code: 6020; - name: 'CpiContextAccountUndefined'; - msg: 'CpiContextAccountUndefined'; - }, - { - code: 6021; - name: 'CpiContextEmpty'; - msg: 'CpiContextEmpty'; - }, - { - code: 6022; - name: 'CpiContextMissing'; - msg: 'CpiContextMissing'; - }, - { - code: 6023; - name: 'DecompressionRecipientDefined'; - msg: 'DecompressionRecipientDefined'; - }, - { - code: 6024; - name: 'SolPoolPdaDefined'; - msg: 'SolPoolPdaDefined'; - }, - { - code: 6025; - name: 'AppendStateFailed'; - msg: 'AppendStateFailed'; - }, - { - code: 6026; - name: 'InstructionNotCallable'; - msg: 'The instruction is not callable'; - }, - { - code: 6027; - name: 'CpiContextFeePayerMismatch'; - msg: 'CpiContextFeePayerMismatch'; - }, - { - code: 6028; - name: 'CpiContextAssociatedMerkleTreeMismatch'; - msg: 'CpiContextAssociatedMerkleTreeMismatch'; - }, - { - code: 6029; - name: 'NoInputs'; - msg: 'NoInputs'; - }, - { - code: 6030; - name: 'InputMerkleTreeIndicesNotInOrder'; - msg: 'Input merkle tree indices are not in ascending order.'; - }, - { - code: 6031; - name: 'OutputMerkleTreeIndicesNotInOrder'; - msg: 'Output merkle tree indices are not in ascending order.'; - }, - { - code: 6032; - name: 'OutputMerkleTreeNotUnique'; - }, - { - code: 6033; - name: 'DataFieldUndefined'; - }, - { - code: 6034; - name: 'ReadOnlyAddressAlreadyExists'; - }, - { - code: 6035; - name: 'ReadOnlyAccountDoesNotExist'; - }, - { - code: 6036; - name: 'HashChainInputsLenghtInconsistent'; - }, - { - code: 6037; - name: 'InvalidAddressTreeHeight'; - }, - ]; -}; - -export const IDL: LightSystemProgram = { - version: '1.2.0', - name: 'light_system_program', - constants: [ - { - name: 'SOL_POOL_PDA_SEED', - type: 'bytes', - value: '[115, 111, 108, 95, 112, 111, 111, 108, 95, 112, 100, 97]', - }, - ], - instructions: [ - { - name: 'initCpiContextAccount', - accounts: [ - { - name: 'feePayer', - isMut: true, - isSigner: true, - }, - { - name: 'cpiContextAccount', - isMut: true, - isSigner: false, - }, - { - name: 'associatedMerkleTree', - isMut: false, - isSigner: false, - }, - ], - args: [], - }, - { - name: 'invoke', - accounts: [ - { - name: 'feePayer', - isMut: true, - isSigner: true, - docs: [ - 'Fee payer needs to be mutable to pay rollover and protocol fees.', - ], - }, - { - name: 'authority', - isMut: false, - isSigner: true, - }, - { - name: 'registeredProgramPda', - isMut: false, - isSigner: false, - }, - { - name: 'noopProgram', - isMut: false, - isSigner: false, - }, - { - name: 'accountCompressionAuthority', - isMut: false, - isSigner: false, - docs: [ - 'This pda is used to invoke the account compression program.', - ], - }, - { - name: 'accountCompressionProgram', - isMut: false, - isSigner: false, - docs: ['Merkle trees.'], - }, - { - name: 'solPoolPda', - isMut: true, - isSigner: false, - isOptional: true, - docs: [ - 'Sol pool pda is used to store the native sol that has been compressed.', - "It's only required when compressing or decompressing sol.", - ], - }, - { - name: 'decompressionRecipient', - isMut: true, - isSigner: false, - isOptional: true, - docs: [ - 'Only needs to be provided for decompression as a recipient for the', - 'decompressed sol.', - 'Compressed sol originate from authority.', - ], - }, - { - name: 'systemProgram', - isMut: false, - isSigner: false, - }, - ], - args: [ - { - name: 'inputs', - type: 'bytes', - }, - ], - }, - { - name: 'invokeCpi', - accounts: [ - { - name: 'feePayer', - isMut: true, - isSigner: true, - docs: [ - 'Fee payer needs to be mutable to pay rollover and protocol fees.', - ], - }, - { - name: 'authority', - isMut: false, - isSigner: true, - }, - { - name: 'registeredProgramPda', - isMut: false, - isSigner: false, - }, - { - name: 'noopProgram', - isMut: false, - isSigner: false, - }, - { - name: 'accountCompressionAuthority', - isMut: false, - isSigner: false, - }, - { - name: 'accountCompressionProgram', - isMut: false, - isSigner: false, - }, - { - name: 'invokingProgram', - isMut: false, - isSigner: false, - }, - { - name: 'solPoolPda', - isMut: true, - isSigner: false, - isOptional: true, - }, - { - name: 'decompressionRecipient', - isMut: true, - isSigner: false, - isOptional: true, - }, - { - name: 'systemProgram', - isMut: false, - isSigner: false, - }, - { - name: 'cpiContextAccount', - isMut: true, - isSigner: false, - isOptional: true, - }, - ], - args: [ - { - name: 'inputs', - type: 'bytes', - }, - ], - }, - { - name: 'invokeCpiWithReadOnly', - accounts: [ - { - name: 'feePayer', - isMut: true, - isSigner: true, - docs: [ - 'Fee payer needs to be mutable to pay rollover and protocol fees.', - ], - }, - { - name: 'authority', - isMut: false, - isSigner: true, - }, - { - name: 'registeredProgramPda', - isMut: false, - isSigner: false, - }, - { - name: 'noopProgram', - isMut: false, - isSigner: false, - }, - { - name: 'accountCompressionAuthority', - isMut: false, - isSigner: false, - }, - { - name: 'accountCompressionProgram', - isMut: false, - isSigner: false, - }, - { - name: 'invokingProgram', - isMut: false, - isSigner: false, - }, - { - name: 'solPoolPda', - isMut: true, - isSigner: false, - isOptional: true, - }, - { - name: 'decompressionRecipient', - isMut: true, - isSigner: false, - isOptional: true, - }, - { - name: 'systemProgram', - isMut: false, - isSigner: false, - }, - { - name: 'cpiContextAccount', - isMut: true, - isSigner: false, - isOptional: true, - }, - ], - args: [ - { - name: 'inputs', - type: 'bytes', - }, - ], - }, - { - name: 'stubIdlBuild', - docs: [ - 'This function is a stub to allow Anchor to include the input types in', - 'the IDL. It should not be included in production builds nor be called in', - 'practice.', - ], - accounts: [ - { - name: 'feePayer', - isMut: true, - isSigner: true, - docs: [ - 'Fee payer needs to be mutable to pay rollover and protocol fees.', - ], - }, - { - name: 'authority', - isMut: false, - isSigner: true, - }, - { - name: 'registeredProgramPda', - isMut: false, - isSigner: false, - }, - { - name: 'noopProgram', - isMut: false, - isSigner: false, - }, - { - name: 'accountCompressionAuthority', - isMut: false, - isSigner: false, - docs: [ - 'This pda is used to invoke the account compression program.', - ], - }, - { - name: 'accountCompressionProgram', - isMut: false, - isSigner: false, - docs: ['Merkle trees.'], - }, - { - name: 'solPoolPda', - isMut: true, - isSigner: false, - isOptional: true, - docs: [ - 'Sol pool pda is used to store the native sol that has been compressed.', - "It's only required when compressing or decompressing sol.", - ], - }, - { - name: 'decompressionRecipient', - isMut: true, - isSigner: false, - isOptional: true, - docs: [ - 'Only needs to be provided for decompression as a recipient for the', - 'decompressed sol.', - 'Compressed sol originate from authority.', - ], - }, - { - name: 'systemProgram', - isMut: false, - isSigner: false, - }, - ], - args: [ - { - name: 'inputs1', - type: { - defined: 'InstructionDataInvoke', - }, - }, - { - name: 'inputs2', - type: { - defined: 'InstructionDataInvokeCpi', - }, - }, - { - name: 'inputs3', - type: { - defined: 'PublicTransactionEvent', - }, - }, - ], - }, - ], - accounts: [ - { - name: 'cpiContextAccount', - docs: [ - 'Collects instruction data without executing a compressed transaction.', - 'Signer checks are performed on instruction data.', - 'Collected instruction data is combined with the instruction data of the executing cpi,', - 'and executed as a single transaction.', - 'This enables to use input compressed accounts that are owned by multiple programs,', - 'with one zero-knowledge proof.', - ], - type: { - kind: 'struct', - fields: [ - { - name: 'feePayer', - type: 'publicKey', - }, - { - name: 'associatedMerkleTree', - type: 'publicKey', - }, - { - name: 'context', - type: { - vec: { - defined: 'InstructionDataInvokeCpi', - }, - }, - }, - ], - }, - }, - ], - types: [ - { - name: 'InstructionDataInvoke', - type: { - kind: 'struct', - fields: [ - { - name: 'proof', - type: { - option: { - defined: 'CompressedProof', - }, - }, - }, - { - name: 'inputCompressedAccountsWithMerkleContext', - type: { - vec: { - defined: - 'PackedCompressedAccountWithMerkleContext', - }, - }, - }, - { - name: 'outputCompressedAccounts', - type: { - vec: { - defined: - 'OutputCompressedAccountWithPackedContext', - }, - }, - }, - { - name: 'relayFee', - type: { - option: 'u64', - }, - }, - { - name: 'newAddressParams', - type: { - vec: { - defined: 'NewAddressParamsPacked', - }, - }, - }, - { - name: 'compressOrDecompressLamports', - type: { - option: 'u64', - }, - }, - { - name: 'isCompress', - type: 'bool', - }, - ], - }, - }, - { - name: 'NewAddressParamsPacked', - type: { - kind: 'struct', - fields: [ - { - name: 'seed', - type: { - array: ['u8', 32], - }, - }, - { - name: 'addressQueueAccountIndex', - type: 'u8', - }, - { - name: 'addressMerkleTreeAccountIndex', - type: 'u8', - }, - { - name: 'addressMerkleTreeRootIndex', - type: 'u16', - }, - ], - }, - }, - { - name: 'OutputCompressedAccountWithPackedContext', - type: { - kind: 'struct', - fields: [ - { - name: 'compressedAccount', - type: { - defined: 'CompressedAccount', - }, - }, - { - name: 'merkleTreeIndex', - type: 'u8', - }, - ], - }, - }, - { - name: 'CompressedProof', - type: { - kind: 'struct', - fields: [ - { - name: 'a', - type: { - array: ['u8', 32], - }, - }, - { - name: 'b', - type: { - array: ['u8', 64], - }, - }, - { - name: 'c', - type: { - array: ['u8', 32], - }, - }, - ], - }, - }, - { - name: 'InstructionDataInvokeCpi', - type: { - kind: 'struct', - fields: [ - { - name: 'proof', - type: { - option: { - defined: 'CompressedProof', - }, - }, - }, - { - name: 'newAddressParams', - type: { - vec: { - defined: 'NewAddressParamsPacked', - }, - }, - }, - { - name: 'inputCompressedAccountsWithMerkleContext', - type: { - vec: { - defined: - 'PackedCompressedAccountWithMerkleContext', - }, - }, - }, - { - name: 'outputCompressedAccounts', - type: { - vec: { - defined: - 'OutputCompressedAccountWithPackedContext', - }, - }, - }, - { - name: 'relayFee', - type: { - option: 'u64', - }, - }, - { - name: 'compressOrDecompressLamports', - type: { - option: 'u64', - }, - }, - { - name: 'isCompress', - type: 'bool', - }, - { - name: 'cpiContext', - type: { - option: { - defined: 'CompressedCpiContext', - }, - }, - }, - ], - }, - }, - { - name: 'CompressedCpiContext', - type: { - kind: 'struct', - fields: [ - { - name: 'setContext', - docs: [ - 'Is set by the program that is invoking the CPI to signal that is should', - 'set the cpi context.', - ], - type: 'bool', - }, - { - name: 'firstSetContext', - docs: [ - 'Is set to wipe the cpi context since someone could have set it before', - 'with unrelated data.', - ], - type: 'bool', - }, - { - name: 'cpiContextAccountIndex', - docs: [ - 'Index of cpi context account in remaining accounts.', - ], - type: 'u8', - }, - ], - }, - }, - { - name: 'CompressedAccount', - type: { - kind: 'struct', - fields: [ - { - name: 'owner', - type: 'publicKey', - }, - { - name: 'lamports', - type: 'u64', - }, - { - name: 'address', - type: { - option: { - array: ['u8', 32], - }, - }, - }, - { - name: 'data', - type: { - option: { - defined: 'CompressedAccountData', - }, - }, - }, - ], - }, - }, - { - name: 'CompressedAccountData', - type: { - kind: 'struct', - fields: [ - { - name: 'discriminator', - type: { - array: ['u8', 8], - }, - }, - { - name: 'data', - type: 'bytes', - }, - { - name: 'dataHash', - type: { - array: ['u8', 32], - }, - }, - ], - }, - }, - { - name: 'PackedCompressedAccountWithMerkleContext', - type: { - kind: 'struct', - fields: [ - { - name: 'compressedAccount', - type: { - defined: 'CompressedAccount', - }, - }, - { - name: 'merkleContext', - type: { - defined: 'PackedMerkleContext', - }, - }, - { - name: 'rootIndex', - docs: [ - 'Index of root used in inclusion validity proof.', - ], - type: 'u16', - }, - { - name: 'readOnly', - docs: [ - 'Placeholder to mark accounts read-only unimplemented set to false.', - ], - type: 'bool', - }, - ], - }, - }, - { - name: 'PackedMerkleContext', - type: { - kind: 'struct', - fields: [ - { - name: 'merkleTreePubkeyIndex', - type: 'u8', - }, - { - name: 'nullifierQueuePubkeyIndex', - type: 'u8', - }, - { - name: 'leafIndex', - type: 'u32', - }, - { - name: 'queueIndex', - type: { - option: { - defined: 'QueueIndex', - }, - }, - }, - ], - }, - }, - { - name: 'QueueIndex', - type: { - kind: 'struct', - fields: [ - { - name: 'queueId', - docs: ['Id of queue in queue account.'], - type: 'u8', - }, - { - name: 'index', - docs: ['Index of compressed account hash in queue.'], - type: 'u16', - }, - ], - }, - }, - { - name: 'MerkleTreeSequenceNumber', - type: { - kind: 'struct', - fields: [ - { - name: 'pubkey', - type: 'publicKey', - }, - { - name: 'seq', - type: 'u64', - }, - ], - }, - }, - { - name: 'PublicTransactionEvent', - type: { - kind: 'struct', - fields: [ - { - name: 'inputCompressedAccountHashes', - type: { - vec: { - array: ['u8', 32], - }, - }, - }, - { - name: 'outputCompressedAccountHashes', - type: { - vec: { - array: ['u8', 32], - }, - }, - }, - { - name: 'outputCompressedAccounts', - type: { - vec: { - defined: - 'OutputCompressedAccountWithPackedContext', - }, - }, - }, - { - name: 'outputLeafIndices', - type: { - vec: 'u32', - }, - }, - { - name: 'sequenceNumbers', - type: { - vec: { - defined: 'MerkleTreeSequenceNumber', - }, - }, - }, - { - name: 'relayFee', - type: { - option: 'u64', - }, - }, - { - name: 'isCompress', - type: 'bool', - }, - { - name: 'compressOrDecompressLamports', - type: { - option: 'u64', - }, - }, - { - name: 'pubkeyArray', - type: { - vec: 'publicKey', - }, - }, - { - name: 'message', - type: { - option: 'bytes', - }, - }, - ], - }, - }, - ], - errors: [ - { - code: 6000, - name: 'SumCheckFailed', - msg: 'Sum check failed', - }, - { - code: 6001, - name: 'SignerCheckFailed', - msg: 'Signer check failed', - }, - { - code: 6002, - name: 'CpiSignerCheckFailed', - msg: 'Cpi signer check failed', - }, - { - code: 6003, - name: 'ComputeInputSumFailed', - msg: 'Computing input sum failed.', - }, - { - code: 6004, - name: 'ComputeOutputSumFailed', - msg: 'Computing output sum failed.', - }, - { - code: 6005, - name: 'ComputeRpcSumFailed', - msg: 'Computing rpc sum failed.', - }, - { - code: 6006, - name: 'InvalidAddress', - msg: 'InvalidAddress', - }, - { - code: 6007, - name: 'DeriveAddressError', - msg: 'DeriveAddressError', - }, - { - code: 6008, - name: 'CompressedSolPdaUndefinedForCompressSol', - msg: 'CompressedSolPdaUndefinedForCompressSol', - }, - { - code: 6009, - name: 'DeCompressLamportsUndefinedForCompressSol', - msg: 'DeCompressLamportsUndefinedForCompressSol', - }, - { - code: 6010, - name: 'CompressedSolPdaUndefinedForDecompressSol', - msg: 'CompressedSolPdaUndefinedForDecompressSol', - }, - { - code: 6011, - name: 'DeCompressLamportsUndefinedForDecompressSol', - msg: 'DeCompressLamportsUndefinedForDecompressSol', - }, - { - code: 6012, - name: 'DecompressRecipientUndefinedForDecompressSol', - msg: 'DecompressRecipientUndefinedForDecompressSol', - }, - { - code: 6013, - name: 'WriteAccessCheckFailed', - msg: 'WriteAccessCheckFailed', - }, - { - code: 6014, - name: 'InvokingProgramNotProvided', - msg: 'InvokingProgramNotProvided', - }, - { - code: 6015, - name: 'InvalidCapacity', - msg: 'InvalidCapacity', - }, - { - code: 6016, - name: 'InvalidMerkleTreeOwner', - msg: 'InvalidMerkleTreeOwner', - }, - { - code: 6017, - name: 'ProofIsNone', - msg: 'ProofIsNone', - }, - { - code: 6018, - name: 'ProofIsSome', - msg: 'Proof is some but no input compressed accounts or new addresses provided.', - }, - { - code: 6019, - name: 'EmptyInputs', - msg: 'EmptyInputs', - }, - { - code: 6020, - name: 'CpiContextAccountUndefined', - msg: 'CpiContextAccountUndefined', - }, - { - code: 6021, - name: 'CpiContextEmpty', - msg: 'CpiContextEmpty', - }, - { - code: 6022, - name: 'CpiContextMissing', - msg: 'CpiContextMissing', - }, - { - code: 6023, - name: 'DecompressionRecipientDefined', - msg: 'DecompressionRecipientDefined', - }, - { - code: 6024, - name: 'SolPoolPdaDefined', - msg: 'SolPoolPdaDefined', - }, - { - code: 6025, - name: 'AppendStateFailed', - msg: 'AppendStateFailed', - }, - { - code: 6026, - name: 'InstructionNotCallable', - msg: 'The instruction is not callable', - }, - { - code: 6027, - name: 'CpiContextFeePayerMismatch', - msg: 'CpiContextFeePayerMismatch', - }, - { - code: 6028, - name: 'CpiContextAssociatedMerkleTreeMismatch', - msg: 'CpiContextAssociatedMerkleTreeMismatch', - }, - { - code: 6029, - name: 'NoInputs', - msg: 'NoInputs', - }, - { - code: 6030, - name: 'InputMerkleTreeIndicesNotInOrder', - msg: 'Input merkle tree indices are not in ascending order.', - }, - { - code: 6031, - name: 'OutputMerkleTreeIndicesNotInOrder', - msg: 'Output merkle tree indices are not in ascending order.', - }, - { - code: 6032, - name: 'OutputMerkleTreeNotUnique', - }, - { - code: 6033, - name: 'DataFieldUndefined', - }, - { - code: 6034, - name: 'ReadOnlyAddressAlreadyExists', - }, - { - code: 6035, - name: 'ReadOnlyAccountDoesNotExist', - }, - { - code: 6036, - name: 'HashChainInputsLenghtInconsistent', - }, - { - code: 6037, - name: 'InvalidAddressTreeHeight', - }, - ], -}; diff --git a/js/stateless.js/src/index.ts b/js/stateless.js/src/index.ts index 17f3c3e12a..b04b9221e5 100644 --- a/js/stateless.js/src/index.ts +++ b/js/stateless.js/src/index.ts @@ -1,10 +1,8 @@ export * from './actions'; -export * from './idls'; export * from './instruction'; export * from './programs'; export * from './state'; export * from './utils'; -export * from './wallet'; export * from './constants'; export * from './errors'; export * from './rpc-interface'; diff --git a/js/stateless.js/src/programs/index.ts b/js/stateless.js/src/programs/index.ts index 4b58cda615..6d5d8dd768 100644 --- a/js/stateless.js/src/programs/index.ts +++ b/js/stateless.js/src/programs/index.ts @@ -1 +1,2 @@ export * from './system'; +export * from './layout'; diff --git a/js/stateless.js/src/programs/layout.ts b/js/stateless.js/src/programs/layout.ts new file mode 100644 index 0000000000..ad1fa9ab5f --- /dev/null +++ b/js/stateless.js/src/programs/layout.ts @@ -0,0 +1,213 @@ +import { Buffer } from 'buffer'; +import { PublicKey, AccountMeta } from '@solana/web3.js'; +import { + struct, + u8, + u64, + bool, + vec, + option, + publicKey, + array, + u16, + u32, + Layout, + vecU8, +} from '@coral-xyz/borsh'; +import { InstructionDataInvoke, PublicTransactionEvent } from '../state'; +import { LightSystemProgram } from './system'; +export const CompressedAccountLayout = struct( + [ + publicKey('owner'), + u64('lamports'), + option(array(u8(), 32), 'address'), + option( + struct([ + array(u8(), 8, 'discriminator'), + vecU8('data'), + array(u8(), 32, 'dataHash'), + ]), + 'data', + ), + ], + 'compressedAccount', +); + +export const MerkleContextLayout = struct( + [ + u8('merkleTreePubkeyIndex'), + u8('nullifierQueuePubkeyIndex'), + u32('leafIndex'), + option(struct([u8('queueId'), u16('index')]), 'queueIndex'), + ], + 'merkleContext', +); + +export const NewAddressParamsLayout = struct( + [ + array(u8(), 32, 'seed'), + u8('addressQueueAccountIndex'), + u8('addressMerkleTreeAccountIndex'), + u16('addressMerkleTreeRootIndex'), + ], + 'newAddressParams', +); + +// Use the defined structs in the main layout with field names +export const InstructionDataInvokeLayout: Layout = + struct([ + option( + struct([ + array(u8(), 32, 'a'), + array(u8(), 64, 'b'), + array(u8(), 32, 'c'), + ]), + 'proof', + ), + vec( + struct([ + CompressedAccountLayout, + MerkleContextLayout, + u16('rootIndex'), + bool('readOnly'), + ]), + 'inputCompressedAccountsWithMerkleContext', + ), + vec( + struct([CompressedAccountLayout, u8('merkleTreeIndex')]), + 'outputCompressedAccounts', + ), + option(u64(), 'relayFee'), + vec(NewAddressParamsLayout, 'newAddressParams'), + option(u64(), 'compressOrDecompressLamports'), + bool('isCompress'), + ]); + +export function encodeInstructionDataInvoke( + data: InstructionDataInvoke, +): Buffer { + const buffer = Buffer.alloc(1000); + const len = InstructionDataInvokeLayout.encode(data, buffer); + const dataBuffer = Buffer.from(buffer.slice(0, len)); + + const lengthBuffer = Buffer.alloc(4); + lengthBuffer.writeUInt32LE(len, 0); + + return Buffer.concat([ + Buffer.from([26, 16, 169, 7, 21, 202, 242, 25]), + lengthBuffer, + dataBuffer, + ]); +} + +export function decodeInstructionDataInvoke( + buffer: Buffer, +): InstructionDataInvoke { + return InstructionDataInvokeLayout.decode(buffer); +} + +export type invokeAccountsLayoutParams = { + feePayer: PublicKey; + authority: PublicKey; + registeredProgramPda: PublicKey; + noopProgram: PublicKey; + accountCompressionAuthority: PublicKey; + accountCompressionProgram: PublicKey; + solPoolPda: PublicKey | null; + decompressionRecipient: PublicKey | null; + systemProgram: PublicKey; +}; + +export const invokeAccountsLayout = ( + accounts: invokeAccountsLayoutParams, +): AccountMeta[] => { + const defaultPubkey = LightSystemProgram.programId; + const { + feePayer, + authority, + registeredProgramPda, + noopProgram, + accountCompressionAuthority, + accountCompressionProgram, + solPoolPda, + decompressionRecipient, + systemProgram, + } = accounts; + + return [ + { pubkey: feePayer, isSigner: true, isWritable: true }, + { pubkey: authority, isSigner: true, isWritable: false }, + { pubkey: registeredProgramPda, isSigner: false, isWritable: false }, + { pubkey: noopProgram, isSigner: false, isWritable: false }, + { + pubkey: accountCompressionAuthority, + isSigner: false, + isWritable: false, + }, + { + pubkey: accountCompressionProgram, + isSigner: false, + isWritable: false, + }, + { + pubkey: solPoolPda ?? defaultPubkey, + isSigner: false, + isWritable: solPoolPda !== null, + }, + { + pubkey: decompressionRecipient ?? defaultPubkey, + isSigner: false, + isWritable: true, + }, + { pubkey: systemProgram, isSigner: false, isWritable: false }, + ]; +}; + +export const PublicTransactionEventLayout: Layout = + struct([ + vec(array(u8(), 32), 'inputCompressedAccountHashes'), + vec(array(u8(), 32), 'outputCompressedAccountHashes'), + vec( + struct([ + struct( + [ + publicKey('owner'), + u64('lamports'), + option(array(u8(), 32), 'address'), + option( + struct([ + array(u8(), 8, 'discriminator'), + vecU8('data'), + array(u8(), 32, 'dataHash'), + ]), + 'data', + ), + ], + 'compressedAccount', + ), + u8('merkleTreeIndex'), + ]), + 'outputCompressedAccounts', + ), + vec(u32(), 'outputLeafIndices'), + vec(struct([publicKey('pubkey'), u64('seq')]), 'sequenceNumbers'), + option(u64(), 'relayFee'), + bool('isCompress'), + option(u64(), 'compressOrDecompressLamports'), + vec(publicKey(), 'pubkeyArray'), + option(vecU8(), 'message'), + ]); + +export function encodePublicTransactionEvent( + data: PublicTransactionEvent, +): Buffer { + const buffer = Buffer.alloc(1000); + const len = PublicTransactionEventLayout.encode(data, buffer); + return buffer.slice(0, len); +} + +export function decodePublicTransactionEvent( + buffer: Buffer, +): PublicTransactionEvent { + return PublicTransactionEventLayout.decode(buffer); +} diff --git a/js/stateless.js/src/programs/system.ts b/js/stateless.js/src/programs/system.ts index bc019faf5d..6b9594474b 100644 --- a/js/stateless.js/src/programs/system.ts +++ b/js/stateless.js/src/programs/system.ts @@ -1,18 +1,10 @@ -import { Program, AnchorProvider, setProvider, BN } from '@coral-xyz/anchor'; +import BN from 'bn.js'; import { PublicKey, - Keypair, - Connection, TransactionInstruction, SystemProgram, } from '@solana/web3.js'; import { Buffer } from 'buffer'; - -import { - IDL, - LightSystemProgram as LightSystemProgramIDL, -} from '../idls/light_system_program'; -import { useWallet } from '../wallet'; import { CompressedAccount, CompressedAccountWithMerkleContext, @@ -22,15 +14,13 @@ import { createCompressedAccount, } from '../state'; import { packCompressedAccounts, toAccountMetas } from '../instruction'; -import { - defaultStaticAccountsStruct, - defaultTestStateTreeAccounts, -} from '../constants'; +import { defaultStaticAccountsStruct } from '../constants'; import { validateSameOwner, validateSufficientBalance, } from '../utils/validation'; import { packNewAddressParams, NewAddressParams } from '../utils'; +import { encodeInstructionDataInvoke, invokeAccountsLayout } from './layout'; export const sumUpLamports = ( accounts: CompressedAccountWithMerkleContext[], @@ -201,19 +191,9 @@ export class LightSystemProgram { * Public key that identifies the CompressedPda program */ static programId: PublicKey = new PublicKey( - // TODO: can add check to ensure its consistent with the idl 'SySTEM1eSU2p4BGQfQpimFEWWSC1XDFeun3Nqzz3rT7', ); - private static _program: Program | null = null; - - static get program(): Program { - if (!this._program) { - this.initializeProgram(); - } - return this._program!; - } - /** * @internal * Cwct1kQLwJm8Z3HetLu8m4SXkhD6FZ5fXbJQCxTxPnGY @@ -228,29 +208,6 @@ export class LightSystemProgram { return address; } - /** - * Initializes the program statically if not already initialized. - */ - private static initializeProgram() { - if (!this._program) { - const mockKeypair = Keypair.generate(); - const mockConnection = new Connection( - 'http://127.0.0.1:8899', - 'confirmed', - ); - const mockProvider = new AnchorProvider( - mockConnection, - useWallet(mockKeypair), - { - commitment: 'confirmed', - preflightCommitment: 'confirmed', - }, - ); - setProvider(mockProvider); - this._program = new Program(IDL, this.programId, mockProvider); - } - } - static createTransferOutputState( inputCompressedAccounts: CompressedAccountWithMerkleContext[], toAddress: PublicKey, @@ -384,28 +341,23 @@ export class LightSystemProgram { compressOrDecompressLamports: null, isCompress: false, }; + const data = encodeInstructionDataInvoke(rawData); + + const accounts = invokeAccountsLayout({ + ...defaultStaticAccountsStruct(), + feePayer: payer, + authority: payer, + solPoolPda: null, + decompressionRecipient: null, + systemProgram: SystemProgram.programId, + }); + const keys = [...accounts, ...toAccountMetas(remainingAccounts)]; - /// Encode instruction data - const ixData = this.program.coder.types.encode( - 'InstructionDataInvoke', - rawData, - ); - - /// Build anchor instruction - const instruction = await this.program.methods - .invoke(ixData) - .accounts({ - ...defaultStaticAccountsStruct(), - feePayer: payer, - authority: payer, - solPoolPda: null, - decompressionRecipient: null, - systemProgram: SystemProgram.programId, - }) - .remainingAccounts(toAccountMetas(remainingAccounts)) - .instruction(); - - return instruction; + return new TransactionInstruction({ + programId: this.programId, + keys, + data, + }); } /** @@ -439,33 +391,33 @@ export class LightSystemProgram { outputStateTrees, ); /// Encode instruction data - const data = this.program.coder.types.encode('InstructionDataInvoke', { + const rawInputs: InstructionDataInvoke = { proof: recentValidityProof, inputCompressedAccountsWithMerkleContext: packedInputCompressedAccounts, outputCompressedAccounts: packedOutputCompressedAccounts, relayFee: null, - /// TODO: here and on-chain: option or similar. newAddressParams: [], compressOrDecompressLamports: null, isCompress: false, + }; + const data = encodeInstructionDataInvoke(rawInputs); + + const accounts = invokeAccountsLayout({ + ...defaultStaticAccountsStruct(), + feePayer: payer, + authority: payer, + solPoolPda: null, + decompressionRecipient: null, + systemProgram: SystemProgram.programId, }); + const keys = [...accounts, ...toAccountMetas(remainingAccounts)]; - /// Build anchor instruction - const instruction = await this.program.methods - .invoke(data) - .accounts({ - ...defaultStaticAccountsStruct(), - feePayer: payer, - authority: payer, - solPoolPda: null, - decompressionRecipient: null, - systemProgram: SystemProgram.programId, - }) - .remainingAccounts(toAccountMetas(remainingAccounts)) - .instruction(); - - return instruction; + return new TransactionInstruction({ + programId: this.programId, + keys, + data, + }); } /** @@ -512,26 +464,23 @@ export class LightSystemProgram { isCompress: true, }; - const data = this.program.coder.types.encode( - 'InstructionDataInvoke', - rawInputs, - ); + const data = encodeInstructionDataInvoke(rawInputs); - /// Build anchor instruction - const instruction = await this.program.methods - .invoke(data) - .accounts({ - ...defaultStaticAccountsStruct(), - feePayer: payer, - authority: payer, - solPoolPda: this.deriveCompressedSolPda(), - decompressionRecipient: null, - systemProgram: SystemProgram.programId, - }) - .remainingAccounts(toAccountMetas(remainingAccounts)) - .instruction(); - - return instruction; + const accounts = invokeAccountsLayout({ + ...defaultStaticAccountsStruct(), + feePayer: payer, + authority: payer, + solPoolPda: this.deriveCompressedSolPda(), + decompressionRecipient: null, + systemProgram: SystemProgram.programId, + }); + const keys = [...accounts, ...toAccountMetas(remainingAccounts)]; + + return new TransactionInstruction({ + programId: this.programId, + keys, + data, + }); } /** @@ -567,33 +516,33 @@ export class LightSystemProgram { outputStateTree, ); /// Encode instruction data - const data = this.program.coder.types.encode('InstructionDataInvoke', { + const rawInputs: InstructionDataInvoke = { proof: recentValidityProof, inputCompressedAccountsWithMerkleContext: packedInputCompressedAccounts, outputCompressedAccounts: packedOutputCompressedAccounts, relayFee: null, - /// TODO: here and on-chain: option or similar. newAddressParams: [], compressOrDecompressLamports: lamports, isCompress: false, + }; + const data = encodeInstructionDataInvoke(rawInputs); + + const accounts = invokeAccountsLayout({ + ...defaultStaticAccountsStruct(), + feePayer: payer, + authority: payer, + solPoolPda: this.deriveCompressedSolPda(), + decompressionRecipient: toAddress, + systemProgram: SystemProgram.programId, }); + const keys = [...accounts, ...toAccountMetas(remainingAccounts)]; - /// Build anchor instruction - const instruction = await this.program.methods - .invoke(data) - .accounts({ - ...defaultStaticAccountsStruct(), - feePayer: payer, - authority: payer, - solPoolPda: this.deriveCompressedSolPda(), - decompressionRecipient: toAddress, - systemProgram: SystemProgram.programId, - }) - .remainingAccounts(toAccountMetas(remainingAccounts)) - .instruction(); - - return instruction; + return new TransactionInstruction({ + programId: this.programId, + keys, + data, + }); } } diff --git a/js/stateless.js/src/rpc-interface.ts b/js/stateless.js/src/rpc-interface.ts index 0e5455378a..3d280eeb11 100644 --- a/js/stateless.js/src/rpc-interface.ts +++ b/js/stateless.js/src/rpc-interface.ts @@ -1,4 +1,11 @@ -import { PublicKey, MemcmpFilter, DataSlice } from '@solana/web3.js'; +import { + PublicKey, + MemcmpFilter, + DataSlice, + RpcResponseAndContext, + Commitment, + SignatureResult, +} from '@solana/web3.js'; import { type as pick, number, @@ -23,7 +30,41 @@ import { bn, TokenData, } from './state'; -import { BN } from '@coral-xyz/anchor'; +import BN from 'bn.js'; + +export class BaseRpc { + private async getCancellationPromise() { + throw new Error( + 'getCancellationPromise not supported in rpc. it is a stub that is marked as private in web3.js Connection', + ); + } + private async getTransactionConfirmationPromise() { + throw new Error( + 'getTransactionConfirmationPromise not supported in rpc. it is a stub that is marked as private in web3.js Connection', + ); + } + private async confirmTransactionUsingBlockHeightExceedanceStrategy() { + throw new Error( + 'confirmTransactionUsingBlockHeightExceedanceStrategy not supported in rpc. it is a stub that is marked as private in web3.js Connection', + ); + } + private async confirmTransactionUsingDurableNonceStrategy() { + throw new Error( + 'confirmTransactionUsingDurableNonceStrategy not supported in rpc. it is a stub that is marked as private in web3.js Connection', + ); + } + private async confirmTransactionUsingLegacyTimeoutStrategy({ + commitment, + signature, + }: { + commitment?: Commitment; + signature: string; + }): Promise> { + throw new Error( + 'confirmTransactionUsingLegacyTimeoutStrategy not supported in rpc. it is a stub that is marked as private in web3.js Connection', + ); + } +} export interface LatestNonVotingSignatures { context: { slot: number }; diff --git a/js/stateless.js/src/rpc.ts b/js/stateless.js/src/rpc.ts index b5b11fe5ce..8dfdbcbd86 100644 --- a/js/stateless.js/src/rpc.ts +++ b/js/stateless.js/src/rpc.ts @@ -1,8 +1,8 @@ import { Connection, ConnectionConfig, - SolanaJSONRPCError, PublicKey, + SolanaJSONRPCError, } from '@solana/web3.js'; import { Buffer } from 'buffer'; import { @@ -44,6 +44,7 @@ import { TokenBalance, TokenBalanceListResultV2, PaginatedOptions, + BaseRpc, } from './rpc-interface'; import { MerkleContextWithMerkleProof, @@ -58,9 +59,19 @@ import { } from './state'; import { array, create, nullable } from 'superstruct'; import { defaultTestStateTreeAccounts } from './constants'; -import { BN } from '@coral-xyz/anchor'; +import BN from 'bn.js'; import { toCamelCase, toHex } from './utils/conversion'; -import { WasmFactory } from '@lightprotocol/hasher.rs'; + +type ClientSubscriptionId = number; + +// // Define an interface that includes the methods you need from Connection +// interface ConnectionInterface { +// sendTransaction(transaction: any, options?: any): Promise; +// getLatestBlockhash(): Promise; +// confirmTransaction(signature: string, commitment?: string): Promise; +// commitment: string; +// // Add other methods and properties as needed +// } import { proofFromJsonStruct, @@ -425,6 +436,7 @@ export function convertNonInclusionMerkleProofInputsToHex( return inputs; } import { LightWasm } from './test-helpers'; +// import { ConnectionInterface } from './connection-interface'; function calculateTwoInputsHashChain( hashesFirst: BN[], @@ -496,6 +508,7 @@ const mockAddressQueue = defaultTestStateTreeAccounts().addressQueue; * */ export class Rpc extends Connection implements CompressionApiInterface { + // connection: Connection; compressionApiEndpoint: string; proverEndpoint: string; @@ -514,10 +527,816 @@ export class Rpc extends Connection implements CompressionApiInterface { config?: ConnectionConfig, ) { super(endpoint, config || 'confirmed'); + + // this.connection = new Connection(endpoint, config || 'confirmed'); this.compressionApiEndpoint = compressionApiEndpoint; this.proverEndpoint = proverEndpoint; } + // get commitment(): Commitment | undefined { + // return this.connection.commitment; + // } + + // get rpcEndpoint(): string { + // return this.connection.rpcEndpoint; + // } + + // // === Connection Methods Delegated === + + // async getBalanceAndContext( + // publicKey: PublicKey, + // commitmentOrConfig?: Commitment | GetBalanceConfig, + // ): Promise> { + // return this.connection.getBalanceAndContext( + // publicKey, + // commitmentOrConfig, + // ); + // } + + // async getBalance( + // publicKey: PublicKey, + // commitmentOrConfig?: Commitment | GetBalanceConfig, + // ): Promise { + // return this.connection.getBalance(publicKey, commitmentOrConfig); + // } + + // async getBlockTime(slot: number): Promise { + // return this.connection.getBlockTime(slot); + // } + + // async getMinimumLedgerSlot(): Promise { + // return this.connection.getMinimumLedgerSlot(); + // } + + // async getFirstAvailableBlock(): Promise { + // return this.connection.getFirstAvailableBlock(); + // } + + // async getSupply( + // config?: GetSupplyConfig | Commitment, + // ): Promise> { + // return this.connection.getSupply(config); + // } + + // async getTokenSupply( + // tokenMintAddress: PublicKey, + // commitment?: Commitment, + // ): Promise> { + // return this.connection.getTokenSupply(tokenMintAddress, commitment); + // } + + // async getTokenAccountBalance( + // tokenAddress: PublicKey, + // commitment?: Commitment, + // ): Promise> { + // return this.connection.getTokenAccountBalance(tokenAddress, commitment); + // } + + // async getTokenAccountsByOwner( + // ownerAddress: PublicKey, + // filter: TokenAccountsFilter, + // commitmentOrConfig?: Commitment | GetTokenAccountsByOwnerConfig, + // ): Promise> { + // return this.connection.getTokenAccountsByOwner( + // ownerAddress, + // filter, + // commitmentOrConfig, + // ); + // } + + // async getParsedTokenAccountsByOwner( + // ownerAddress: PublicKey, + // filter: TokenAccountsFilter, + // commitment?: Commitment, + // ): Promise< + // RpcResponseAndContext< + // Array<{ + // pubkey: PublicKey; + // account: AccountInfo; + // }> + // > + // > { + // return this.connection.getParsedTokenAccountsByOwner( + // ownerAddress, + // filter, + // commitment, + // ); + // } + + // async getLargestAccounts( + // config?: GetLargestAccountsConfig, + // ): Promise>> { + // return this.connection.getLargestAccounts(config); + // } + + // async getTokenLargestAccounts( + // mintAddress: PublicKey, + // commitment?: Commitment, + // ): Promise>> { + // return this.connection.getTokenLargestAccounts(mintAddress, commitment); + // } + + // async getAccountInfoAndContext( + // publicKey: PublicKey, + // commitmentOrConfig?: Commitment | GetAccountInfoConfig, + // ): Promise | null>> { + // return this.connection.getAccountInfoAndContext( + // publicKey, + // commitmentOrConfig, + // ); + // } + + // async getParsedAccountInfo( + // publicKey: PublicKey, + // commitmentOrConfig?: Commitment | GetAccountInfoConfig, + // ): Promise< + // RpcResponseAndContext | null> + // > { + // return this.connection.getParsedAccountInfo( + // publicKey, + // commitmentOrConfig, + // ); + // } + + // async getAccountInfo( + // publicKey: PublicKey, + // commitmentOrConfig?: Commitment | GetAccountInfoConfig, + // ): Promise | null> { + // return this.connection.getAccountInfo(publicKey, commitmentOrConfig); + // } + + // async getMultipleParsedAccounts( + // publicKeys: PublicKey[], + // rawConfig?: GetMultipleAccountsConfig, + // ): Promise< + // RpcResponseAndContext< + // (AccountInfo | null)[] + // > + // > { + // return this.connection.getMultipleParsedAccounts(publicKeys, rawConfig); + // } + + // async getMultipleAccountsInfoAndContext( + // publicKeys: PublicKey[], + // commitmentOrConfig?: Commitment | GetMultipleAccountsConfig, + // ): Promise | null)[]>> { + // return this.connection.getMultipleAccountsInfoAndContext( + // publicKeys, + // commitmentOrConfig, + // ); + // } + + // async getMultipleAccountsInfo( + // publicKeys: PublicKey[], + // commitmentOrConfig?: Commitment | GetMultipleAccountsConfig, + // ): Promise<(AccountInfo | null)[]> { + // return this.connection.getMultipleAccountsInfo( + // publicKeys, + // commitmentOrConfig, + // ); + // } + + // async getStakeActivation( + // publicKey: PublicKey, + // commitmentOrConfig?: Commitment | GetStakeActivationConfig, + // epoch?: number, + // ): Promise { + // return this.connection.getStakeActivation( + // publicKey, + // commitmentOrConfig, + // epoch, + // ); + // } + + // async getProgramAccounts( + // programId: PublicKey, + // configOrCommitment?: GetProgramAccountsConfig | Commitment, + // ): Promise; + + // async getProgramAccounts( + // programId: PublicKey, + // configOrCommitment: GetProgramAccountsConfig & { withContext: true }, + // ): Promise>; + + // async getProgramAccounts( + // programId: PublicKey, + // configOrCommitment?: GetProgramAccountsConfig | Commitment, + // ): Promise< + // | GetProgramAccountsResponse + // | RpcResponseAndContext + // > { + // return this.connection.getProgramAccounts( + // programId, + // configOrCommitment, + // ); + // } + + // async getParsedProgramAccounts( + // programId: PublicKey, + // configOrCommitment?: GetParsedProgramAccountsConfig | Commitment, + // ): Promise< + // Array<{ + // pubkey: PublicKey; + // account: AccountInfo; + // }> + // > { + // return this.connection.getParsedProgramAccounts( + // programId, + // configOrCommitment, + // ); + // } + + // === Subscription Methods === + + // onAccountChange( + // publicKey: PublicKey, + // callback: AccountChangeCallback, + // config?: AccountSubscriptionConfig, + // ): ClientSubscriptionId { + // return this.connection.onAccountChange(publicKey, callback, config); + // } + + // async removeAccountChangeListener( + // clientSubscriptionId: ClientSubscriptionId, + // ): Promise { + // return this.connection.removeAccountChangeListener( + // clientSubscriptionId, + // ); + // } + + // onProgramAccountChange( + // programId: PublicKey, + // callback: ProgramAccountChangeCallback, + // config?: ProgramAccountSubscriptionConfig, + // ): ClientSubscriptionId { + // return this.connection.onProgramAccountChange( + // programId, + // callback, + // config, + // ); + // } + + // async removeProgramAccountChangeListener( + // clientSubscriptionId: ClientSubscriptionId, + // ): Promise { + // return this.connection.removeProgramAccountChangeListener( + // clientSubscriptionId, + // ); + // } + + // onLogs( + // filter: LogsFilter, + // callback: LogsCallback, + // commitment?: Commitment, + // ): ClientSubscriptionId { + // return this.connection.onLogs(filter, callback, commitment); + // } + + // async removeOnLogsListener( + // clientSubscriptionId: ClientSubscriptionId, + // ): Promise { + // return this.connection.removeOnLogsListener(clientSubscriptionId); + // } + + // onSlotChange(callback: SlotChangeCallback): ClientSubscriptionId { + // return this.connection.onSlotChange(callback); + // } + + // async removeSlotChangeListener( + // clientSubscriptionId: ClientSubscriptionId, + // ): Promise { + // return this.connection.removeSlotChangeListener(clientSubscriptionId); + // } + + // onSlotUpdate(callback: SlotUpdateCallback): ClientSubscriptionId { + // return this.connection.onSlotUpdate(callback); + // } + + // async removeSlotUpdateListener( + // clientSubscriptionId: ClientSubscriptionId, + // ): Promise { + // return this.connection.removeSlotUpdateListener(clientSubscriptionId); + // } + + // onSignature( + // signature: TransactionSignature, + // callback: SignatureResultCallback, + // commitment?: Commitment, + // ): ClientSubscriptionId { + // return this.connection.onSignature(signature, callback, commitment); + // } + + // onSignatureWithOptions( + // signature: TransactionSignature, + // callback: SignatureSubscriptionCallback, + // options?: SignatureSubscriptionOptions, + // ): ClientSubscriptionId { + // return this.connection.onSignatureWithOptions( + // signature, + // callback, + // options, + // ); + // } + + // async removeSignatureListener( + // clientSubscriptionId: ClientSubscriptionId, + // ): Promise { + // return this.connection.removeSignatureListener(clientSubscriptionId); + // } + + // onRootChange(callback: RootChangeCallback): ClientSubscriptionId { + // return this.connection.onRootChange(callback); + // } + + // async removeRootChangeListener( + // clientSubscriptionId: ClientSubscriptionId, + // ): Promise { + // return this.connection.removeRootChangeListener(clientSubscriptionId); + // } + + // // === Transaction Methods === + + // async sendTransaction( + // transaction: VersionedTransaction, + // options?: SendOptions, + // ): Promise { + // return this.connection.sendTransaction(transaction, options); + // } + + // async sendRawTransaction( + // rawTransaction: Buffer | Uint8Array | Array, + // options?: SendOptions, + // ): Promise { + // return this.connection.sendRawTransaction(rawTransaction, options); + // } + + // async sendEncodedTransaction( + // encodedTransaction: string, + // options?: SendOptions, + // ): Promise { + // return this.connection.sendEncodedTransaction( + // encodedTransaction, + // options, + // ); + // } + + // async simulateTransaction( + // transaction: VersionedTransaction, + // config?: SimulateTransactionConfig, + // ): Promise> { + // return this.connection.simulateTransaction(transaction, config); + // } + + // async requestAirdrop( + // to: PublicKey, + // lamports: number, + // ): Promise { + // return this.connection.requestAirdrop(to, lamports); + // } + + // async getStakeMinimumDelegation( + // config?: GetStakeMinimumDelegationConfig, + // ): Promise> { + // return this.connection.getStakeMinimumDelegation(config); + // } + + // async getTransactions( + // signatures: TransactionSignature[], + // commitmentOrConfig?: GetTransactionConfig | Finality, + // ): Promise<(VersionedTransactionResponse | null)[]> { + // return this.connection.getTransactions(signatures, commitmentOrConfig); + // } + + // async getTransaction( + // signature: string, + // rawConfig?: GetTransactionConfig, + // ): Promise { + // return this.connection.getTransaction(signature, rawConfig); + // } + + // async getParsedTransaction( + // signature: TransactionSignature, + // commitmentOrConfig?: GetVersionedTransactionConfig | Finality, + // ): Promise { + // return this.connection.getParsedTransaction( + // signature, + // commitmentOrConfig, + // ); + // } + + // async getParsedTransactions( + // signatures: TransactionSignature[], + // commitmentOrConfig?: GetVersionedTransactionConfig | Finality, + // ): Promise<(ParsedTransactionWithMeta | null)[]> { + // return this.connection.getParsedTransactions( + // signatures, + // commitmentOrConfig, + // ); + // } + + // async getConfirmedBlock( + // slot: number, + // commitment?: Finality, + // ): Promise { + // return this.connection.getConfirmedBlock(slot, commitment); + // } + + // async getBlocks( + // startSlot: number, + // endSlot?: number, + // commitment?: Finality, + // ): Promise> { + // return this.connection.getBlocks(startSlot, endSlot, commitment); + // } + + // async getBlockSignatures( + // slot: number, + // commitment?: Finality, + // ): Promise { + // return this.connection.getBlockSignatures(slot, commitment); + // } + + // async getConfirmedBlockSignatures( + // slot: number, + // commitment?: Finality, + // ): Promise { + // return this.connection.getConfirmedBlockSignatures(slot, commitment); + // } + + // confirmTransaction( + // strategy: TransactionConfirmationStrategy, + // commitment?: Commitment, + // ): Promise>; + + // /** @deprecated Instead, call `confirmTransaction` and pass in {@link TransactionConfirmationStrategy} */ + // // eslint-disable-next-line no-dupe-class-members + // confirmTransaction( + // strategy: TransactionSignature, + // commitment?: Commitment, + // ): Promise>; + + // async confirmTransaction( + // strategy: TransactionConfirmationStrategy | TransactionSignature, + // commitment?: Commitment, + // ): Promise> { + // // @ts-ignore + // return this.connection.confirmTransaction(strategy, commitment); + // } + + // // private async getCancellationPromise() { + // // throw new Error( + // // 'getCancellationPromise not supported in rpc. it is a stub that is marked as private in web3.js Connection', + // // ); + // // } + // // private async getTransactionConfirmationPromise() { + // // throw new Error( + // // 'getTransactionConfirmationPromise not supported in rpc. it is a stub that is marked as private in web3.js Connection', + // // ); + // // } + // // private async confirmTransactionUsingBlockHeightExceedanceStrategy() { + // // throw new Error( + // // 'confirmTransactionUsingBlockHeightExceedanceStrategy not supported in rpc. it is a stub that is marked as private in web3.js Connection', + // // ); + // // } + // // async confirmTransactionUsingDurableNonceStrategy() { + // // throw new Error( + // // 'confirmTransactionUsingDurableNonceStrategy not supported in rpc. it is a stub that is marked as private in web3.js Connection', + // // ); + // // } + // // private async confirmTransactionUsingLegacyTimeoutStrategy({ + // // commitment, + // // signature, + // // }: { + // // commitment?: Commitment; + // // signature: string; + // // }): Promise> { + // // throw new Error( + // // 'confirmTransactionUsingLegacyTimeoutStrategy not supported in rpc. it is a stub that is marked as private in web3.js Connection', + // // ); + // // } + // // _buildArgs( + // // args: Array, + // // override?: Commitment, + // // encoding?: 'jsonParsed' | 'base64', + // // extra?: any, + // // ): Array { + // // const commitment = override || this.connection.commitment; + // // if (commitment || encoding || extra) { + // // let options: any = {}; + // // if (encoding) { + // // options.encoding = encoding; + // // } + // // if (commitment) { + // // options.commitment = commitment; + // // } + // // if (extra) { + // // options = Object.assign(options, extra); + // // } + // // args.push(options); + // // } + // // return args; + // // } + + // async getClusterNodes(): Promise> { + // return this.connection.getClusterNodes(); + // } + + // async getVoteAccounts(commitment?: Commitment): Promise { + // return this.connection.getVoteAccounts(commitment); + // } + + // async getSlot( + // commitmentOrConfig?: Commitment | GetSlotConfig, + // ): Promise { + // return this.connection.getSlot(commitmentOrConfig); + // } + + // async getSlotLeader( + // commitmentOrConfig?: Commitment | GetSlotLeaderConfig, + // ): Promise { + // return this.connection.getSlotLeader(commitmentOrConfig); + // } + + // async getSlotLeaders( + // startSlot: number, + // limit: number, + // ): Promise> { + // return this.connection.getSlotLeaders(startSlot, limit); + // } + + // async getSignatureStatus( + // signature: TransactionSignature, + // config?: SignatureStatusConfig, + // ): Promise> { + // return this.connection.getSignatureStatus(signature, config); + // } + + // async getSignatureStatuses( + // signatures: Array, + // config?: SignatureStatusConfig, + // ): Promise>> { + // return this.connection.getSignatureStatuses(signatures, config); + // } + + // async getTotalSupply(commitment?: Commitment): Promise { + // return this.connection.getTotalSupply(commitment); + // } + + // async getBlockHeight(config?: GetBlockHeightConfig): Promise { + // return this.connection.getBlockHeight(config); + // } + + // async getBlockProduction( + // configOrCommitment?: GetBlockProductionConfig | Commitment, + // ): Promise> { + // return this.connection.getBlockProduction(configOrCommitment); + // } + + // async getTransactionCount( + // config?: GetTransactionCountConfig, + // ): Promise { + // return this.connection.getTransactionCount(config); + // } + + // async getInflationGovernor(): Promise { + // return this.connection.getInflationGovernor(); + // } + + // async getInflationReward( + // addresses: PublicKey[], + // epochs?: number, + // config?: GetInflationRewardConfig, + // ): Promise> { + // return this.connection.getInflationReward(addresses, epochs, config); + // } + + // async getInflationRate(): Promise { + // return this.connection.getInflationRate(); + // } + + // async getEpochInfo(config?: GetEpochInfoConfig): Promise { + // return this.connection.getEpochInfo(config); + // } + + // async getEpochSchedule(): Promise { + // return this.connection.getEpochSchedule(); + // } + + // async getLeaderSchedule(): Promise { + // return this.connection.getLeaderSchedule(); + // } + + // async getRecentBlockhashAndContext(commitment?: Commitment): Promise< + // RpcResponseAndContext<{ + // blockhash: Blockhash; + // feeCalculator: FeeCalculator; + // }> + // > { + // return this.connection.getRecentBlockhashAndContext(commitment); + // } + + // async getRecentPerformanceSamples( + // limit?: number, + // ): Promise> { + // return this.connection.getRecentPerformanceSamples(limit); + // } + + // async getFeeCalculatorForBlockhash( + // blockhash: Blockhash, + // commitment?: Commitment, + // ): Promise> { + // return this.connection.getFeeCalculatorForBlockhash( + // blockhash, + // commitment, + // ); + // } + + // async getFeeForMessage( + // message: VersionedMessage, + // commitment?: Commitment, + // ): Promise> { + // return this.connection.getFeeForMessage(message, commitment); + // } + + // async getMinimumBalanceForRentExemption( + // dataLength: number, + // commitment?: Commitment, + // ): Promise { + // return this.connection.getMinimumBalanceForRentExemption( + // dataLength, + // commitment, + // ); + // } + + // async getRecentBlockhash( + // commitment?: Commitment, + // ): Promise<{ blockhash: Blockhash; feeCalculator: FeeCalculator }> { + // return this.connection.getRecentBlockhash(commitment); + // } + + // async getGenesisHash(): Promise { + // return this.connection.getGenesisHash(); + // } + // async getBlock( + // slot: number, + // rawConfig?: GetVersionedBlockConfig, + // ): Promise; + // async getBlock( + // slot: number, + // rawConfig: GetVersionedBlockConfig & { transactionDetails: 'accounts' }, + // ): Promise; + // async getBlock( + // slot: number, + // rawConfig: GetVersionedBlockConfig & { transactionDetails: 'none' }, + // ): Promise; + // async getBlock( + // slot: number, + // rawConfig?: GetVersionedBlockConfig, + // ): Promise< + // | VersionedBlockResponse + // | VersionedAccountsModeBlockResponse + // | VersionedNoneModeBlockResponse + // | null + // > { + // return this.connection.getBlock(slot, rawConfig); + // } + + // async getParsedBlock( + // slot: number, + // rawConfig?: GetVersionedBlockConfig, + // ): Promise; + // async getParsedBlock( + // slot: number, + // rawConfig: GetVersionedBlockConfig & { transactionDetails: 'accounts' }, + // ): Promise; + // async getParsedBlock( + // slot: number, + // rawConfig: GetVersionedBlockConfig & { transactionDetails: 'none' }, + // ): Promise; + // async getParsedBlock( + // slot: number, + // rawConfig?: GetVersionedBlockConfig, + // ): Promise< + // ParsedAccountsModeBlockResponse | ParsedNoneModeBlockResponse | null + // > { + // return this.connection.getParsedBlock(slot, rawConfig); + // } + + // async getConfirmedTransaction( + // signature: TransactionSignature, + // commitment?: Finality, + // ): Promise { + // return this.connection.getConfirmedTransaction(signature, commitment); + // } + + // async getParsedConfirmedTransaction( + // signature: TransactionSignature, + // commitment?: Finality, + // ): Promise { + // return this.connection.getParsedConfirmedTransaction( + // signature, + // commitment, + // ); + // } + + // async getParsedConfirmedTransactions( + // signatures: TransactionSignature[], + // commitment?: Finality, + // ): Promise<(ParsedConfirmedTransaction | null)[]> { + // return this.connection.getParsedConfirmedTransactions( + // signatures, + // commitment, + // ); + // } + + // async getConfirmedSignaturesForAddress( + // address: PublicKey, + // startSlot: number, + // endSlot: number, + // ): Promise> { + // return this.connection.getConfirmedSignaturesForAddress( + // address, + // startSlot, + // endSlot, + // ); + // } + + // async getConfirmedSignaturesForAddress2( + // address: PublicKey, + // options?: ConfirmedSignaturesForAddress2Options, + // commitment?: Finality, + // ): Promise> { + // return this.connection.getConfirmedSignaturesForAddress2( + // address, + // options, + // commitment, + // ); + // } + + // async getSignaturesForAddress( + // address: PublicKey, + // options?: SignaturesForAddressOptions, + // commitment?: Finality, + // ): Promise> { + // return this.connection.getSignaturesForAddress( + // address, + // options, + // commitment, + // ); + // } + + // async getRecentPrioritizationFees( + // config?: GetRecentPrioritizationFeesConfig, + // ): Promise { + // return this.connection.getRecentPrioritizationFees(config); + // } + + // async getLatestBlockhash( + // config?: GetLatestBlockhashConfig, + // ): Promise { + // return this.connection.getLatestBlockhash(config); + // } + // async getLatestBlockhashAndContext( + // commitmentOrConfig?: Commitment | GetLatestBlockhashConfig, + // ): Promise> { + // return this.connection.getLatestBlockhashAndContext(commitmentOrConfig); + // } + + // async isBlockhashValid( + // blockhash: Blockhash, + // config?: IsBlockhashValidConfig, + // ): Promise> { + // return this.connection.isBlockhashValid(blockhash, config); + // } + + // async getVersion(): Promise { + // return this.connection.getVersion(); + // } + + // async getAddressLookupTable( + // accountKey: PublicKey, + // config?: GetAccountInfoConfig, + // ): Promise> { + // return this.connection.getAddressLookupTable(accountKey, config); + // } + + // async getNonceAndContext( + // nonceAccount: PublicKey, + // commitmentOrConfig?: Commitment | GetNonceAndContextConfig, + // ): Promise> { + // return this.connection.getNonceAndContext( + // nonceAccount, + // commitmentOrConfig, + // ); + // } + + // async getNonce( + // nonceAccount: PublicKey, + // commitmentOrConfig?: Commitment | GetNonceConfig, + // ): Promise { + // return this.connection.getNonce(nonceAccount, commitmentOrConfig); + // } + /** * Fetch the compressed account for the specified account address or hash */ diff --git a/js/stateless.js/src/state/BN254.ts b/js/stateless.js/src/state/BN254.ts index 908f5d2ebd..78c33dff06 100644 --- a/js/stateless.js/src/state/BN254.ts +++ b/js/stateless.js/src/state/BN254.ts @@ -4,8 +4,8 @@ import { FIELD_SIZE } from '../constants'; import { PublicKey } from '@solana/web3.js'; -import { BN } from '@coral-xyz/anchor'; -import { bs58 } from '@coral-xyz/anchor/dist/esm/utils/bytes'; +import BN from 'bn.js'; +import bs58 from 'bs58'; import { Buffer } from 'buffer'; /** diff --git a/js/stateless.js/src/state/compressed-account.ts b/js/stateless.js/src/state/compressed-account.ts index e2c9f50fa6..6ba72eb262 100644 --- a/js/stateless.js/src/state/compressed-account.ts +++ b/js/stateless.js/src/state/compressed-account.ts @@ -1,4 +1,4 @@ -import { BN } from '@coral-xyz/anchor'; +import BN from 'bn.js'; import { PublicKey } from '@solana/web3.js'; import { CompressedAccount, CompressedAccountData } from './types'; import { BN254, bn } from './BN254'; diff --git a/js/stateless.js/src/state/types.ts b/js/stateless.js/src/state/types.ts index 2764c5c68e..d9ae34a2f5 100644 --- a/js/stateless.js/src/state/types.ts +++ b/js/stateless.js/src/state/types.ts @@ -1,4 +1,4 @@ -import { BN } from '@coral-xyz/anchor'; +import BN from 'bn.js'; import { PublicKey } from '@solana/web3.js'; import { Buffer } from 'buffer'; import { NewAddressParamsPacked } from '../utils'; @@ -83,32 +83,6 @@ export interface CompressedProof { c: number[]; // [u8; 32] } -/** - * Compressed-token types - * - * TODO: Token-related code should ideally not have to go into stateless.js. - * Find a better altnerative way to extend the RPC. - * - */ -export type TokenTransferOutputData = { - owner: PublicKey; - amount: BN; - lamports: BN | null; - tlv: Buffer | null; -}; - -export type CompressedTokenInstructionDataTransfer = { - proof: CompressedProof | null; - mint: PublicKey; - delegatedTransfer: null; - inputTokenDataWithContext: InputTokenDataWithContext[]; - outputCompressedAccounts: TokenTransferOutputData[]; - isCompress: boolean; - compressOrDecompressAmount: BN | null; - cpiContext: null; - lamportsChangeAccountMerkleTreeIndex: number | null; -}; - export interface InputTokenDataWithContext { amount: BN; delegateIndex: number | null; // Option diff --git a/js/stateless.js/src/test-helpers/merkle-tree/indexed-array.ts b/js/stateless.js/src/test-helpers/merkle-tree/indexed-array.ts index ef6d6f5fa3..d27b7b662d 100644 --- a/js/stateless.js/src/test-helpers/merkle-tree/indexed-array.ts +++ b/js/stateless.js/src/test-helpers/merkle-tree/indexed-array.ts @@ -1,5 +1,5 @@ import { LightWasm } from '../test-rpc/test-rpc'; -import { BN } from '@coral-xyz/anchor'; +import BN from 'bn.js'; import { bn } from '../../state'; import { HIGHEST_ADDRESS_PLUS_ONE } from '../../constants'; diff --git a/js/stateless.js/src/test-helpers/test-rpc/get-compressed-accounts.ts b/js/stateless.js/src/test-helpers/test-rpc/get-compressed-accounts.ts index df52f35871..d87be0d809 100644 --- a/js/stateless.js/src/test-helpers/test-rpc/get-compressed-accounts.ts +++ b/js/stateless.js/src/test-helpers/test-rpc/get-compressed-accounts.ts @@ -1,6 +1,6 @@ import { PublicKey } from '@solana/web3.js'; -import { BN } from '@coral-xyz/anchor'; +import BN from 'bn.js'; import { getParsedEvents } from './get-parsed-events'; import { defaultTestStateTreeAccounts } from '../../constants'; import { Rpc } from '../../rpc'; diff --git a/js/stateless.js/src/test-helpers/test-rpc/get-compressed-token-accounts.ts b/js/stateless.js/src/test-helpers/test-rpc/get-compressed-token-accounts.ts index 38eaec6366..a6a72ee5f9 100644 --- a/js/stateless.js/src/test-helpers/test-rpc/get-compressed-token-accounts.ts +++ b/js/stateless.js/src/test-helpers/test-rpc/get-compressed-token-accounts.ts @@ -1,8 +1,6 @@ import { PublicKey } from '@solana/web3.js'; import { getParsedEvents } from './get-parsed-events'; -import { BN, BorshCoder } from '@coral-xyz/anchor'; - -import { IDL } from '../../idls/light_compressed_token'; +import BN from 'bn.js'; import { defaultTestStateTreeAccounts } from '../../constants'; import { Rpc } from '../../rpc'; import { ParsedTokenAccount, WithCursor } from '../../rpc-interface'; @@ -13,9 +11,17 @@ import { createCompressedAccountWithMerkleContext, bn, } from '../../state'; +import { + struct, + publicKey, + u64, + option, + vecU8, + u8, + Layout, +} from '@coral-xyz/borsh'; const tokenProgramId: PublicKey = new PublicKey( - // TODO: can add check to ensure its consistent with the idl 'cTokenmWW8bLPjZEBAUgYy3zKxQZW6VKi7bqNFEVv3m', ); @@ -28,6 +34,16 @@ type TokenData = { tlv: Buffer | null; }; +// for test-rpc +export const TokenDataLayout: Layout = struct([ + publicKey('mint'), + publicKey('owner'), + u64('amount'), + option(publicKey(), 'delegate'), + u8('state'), + option(vecU8(), 'tlv'), +]); + export type EventWithParsedTokenTlvData = { inputCompressedAccountHashes: number[][]; outputCompressedAccounts: ParsedTokenAccount[]; @@ -51,12 +67,7 @@ export function parseTokenLayoutWithIdl( `Invalid owner ${compressedAccount.owner.toBase58()} for token layout`, ); } - const decodedLayout = new BorshCoder(IDL).types.decode( - 'TokenData', - Buffer.from(data), - ); - - return decodedLayout; + return TokenDataLayout.decode(Buffer.from(data)); } /** diff --git a/js/stateless.js/src/test-helpers/test-rpc/get-parsed-events.ts b/js/stateless.js/src/test-helpers/test-rpc/get-parsed-events.ts index dae297dee8..bf4aefd5cb 100644 --- a/js/stateless.js/src/test-helpers/test-rpc/get-parsed-events.ts +++ b/js/stateless.js/src/test-helpers/test-rpc/get-parsed-events.ts @@ -2,11 +2,12 @@ import { ParsedMessageAccount, ParsedTransactionWithMeta, } from '@solana/web3.js'; -import { bs58 } from '@coral-xyz/anchor/dist/cjs/utils/bytes'; +import bs58 from 'bs58'; import { defaultStaticAccountsStruct } from '../../constants'; import { LightSystemProgram } from '../../programs'; import { Rpc } from '../../rpc'; import { PublicTransactionEvent } from '../../state'; +import { decodePublicTransactionEvent } from '../../programs/layout'; type Deserializer = (data: Buffer, tx: ParsedTransactionWithMeta) => T; @@ -116,10 +117,7 @@ export const parsePublicTransactionEventWithIdl = ( const numericData = Buffer.from(data.map(byte => byte)); try { - return LightSystemProgram.program.coder.types.decode( - 'PublicTransactionEvent', - numericData, - ); + return decodePublicTransactionEvent(numericData); } catch (error) { console.error('Error deserializing event:', error); return null; diff --git a/js/stateless.js/src/test-helpers/test-rpc/test-rpc.ts b/js/stateless.js/src/test-helpers/test-rpc/test-rpc.ts index 86c170d0a1..7547a4efdf 100644 --- a/js/stateless.js/src/test-helpers/test-rpc/test-rpc.ts +++ b/js/stateless.js/src/test-helpers/test-rpc/test-rpc.ts @@ -1,5 +1,5 @@ import { Connection, ConnectionConfig, PublicKey } from '@solana/web3.js'; -import { BN } from '@coral-xyz/anchor'; +import BN from 'bn.js'; import { getCompressedAccountByHashTest, getCompressedAccountsByOwnerTest, @@ -26,6 +26,7 @@ import { SignatureWithMetadata, WithContext, WithCursor, + BaseRpc, } from '../../rpc-interface'; import { CompressedProofWithContext, @@ -44,11 +45,12 @@ import { import { IndexedArray } from '../merkle-tree'; import { MerkleContextWithNewAddressProof, + Rpc, convertMerkleProofsWithContextToHex, convertNonInclusionMerkleProofInputsToHex, - getPublicInputHash, proverRequest, } from '../../rpc'; +// import { ConnectionInterface } from '../../connection-interface'; export interface TestRpcConfig { /** @@ -79,6 +81,7 @@ export interface TestRpcConfig { addressQueueAddress?: PublicKey; } +export type ClientSubscriptionId = number; export interface LightWasm { blakeHash(input: string | Uint8Array, hashLength: number): Uint8Array; poseidonHash(input: string[] | BN[]): Uint8Array; @@ -138,6 +141,7 @@ export async function getTestRpc( * For advanced testing use photon: https://github.com/helius-labs/photon */ export class TestRpc extends Connection implements CompressionApiInterface { + // connection: Connection; compressionApiEndpoint: string; proverEndpoint: string; merkleTreeAddress: PublicKey; @@ -169,6 +173,11 @@ export class TestRpc extends Connection implements CompressionApiInterface { testRpcConfig?: TestRpcConfig, ) { super(endpoint, connectionConfig || 'confirmed'); + + // this.connection = new Connection( + // endpoint, + // connectionConfig || 'confirmed', + // ); this.compressionApiEndpoint = compressionApiEndpoint; this.proverEndpoint = proverEndpoint; @@ -198,6 +207,811 @@ export class TestRpc extends Connection implements CompressionApiInterface { this.log = log ?? false; } + // get commitment(): Commitment | undefined { + // return this.connection.commitment; + // } + + // get rpcEndpoint(): string { + // return this.connection.rpcEndpoint; + // } + + // // === Connection Methods Delegated === + + // async getBalanceAndContext( + // publicKey: PublicKey, + // commitmentOrConfig?: Commitment | GetBalanceConfig, + // ): Promise> { + // return this.connection.getBalanceAndContext( + // publicKey, + // commitmentOrConfig, + // ); + // } + + // async getBalance( + // publicKey: PublicKey, + // commitmentOrConfig?: Commitment | GetBalanceConfig, + // ): Promise { + // return this.connection.getBalance(publicKey, commitmentOrConfig); + // } + + // async getBlockTime(slot: number): Promise { + // return this.connection.getBlockTime(slot); + // } + + // async getMinimumLedgerSlot(): Promise { + // return this.connection.getMinimumLedgerSlot(); + // } + + // async getFirstAvailableBlock(): Promise { + // return this.connection.getFirstAvailableBlock(); + // } + + // async getSupply( + // config?: GetSupplyConfig | Commitment, + // ): Promise> { + // return this.connection.getSupply(config); + // } + + // async getTokenSupply( + // tokenMintAddress: PublicKey, + // commitment?: Commitment, + // ): Promise> { + // return this.connection.getTokenSupply(tokenMintAddress, commitment); + // } + + // async getTokenAccountBalance( + // tokenAddress: PublicKey, + // commitment?: Commitment, + // ): Promise> { + // return this.connection.getTokenAccountBalance(tokenAddress, commitment); + // } + + // async getTokenAccountsByOwner( + // ownerAddress: PublicKey, + // filter: TokenAccountsFilter, + // commitmentOrConfig?: Commitment | GetTokenAccountsByOwnerConfig, + // ): Promise> { + // return this.connection.getTokenAccountsByOwner( + // ownerAddress, + // filter, + // commitmentOrConfig, + // ); + // } + + // async getParsedTokenAccountsByOwner( + // ownerAddress: PublicKey, + // filter: TokenAccountsFilter, + // commitment?: Commitment, + // ): Promise< + // RpcResponseAndContext< + // Array<{ + // pubkey: PublicKey; + // account: AccountInfo; + // }> + // > + // > { + // return this.connection.getParsedTokenAccountsByOwner( + // ownerAddress, + // filter, + // commitment, + // ); + // } + + // async getLargestAccounts( + // config?: GetLargestAccountsConfig, + // ): Promise>> { + // return this.connection.getLargestAccounts(config); + // } + + // async getTokenLargestAccounts( + // mintAddress: PublicKey, + // commitment?: Commitment, + // ): Promise>> { + // return this.connection.getTokenLargestAccounts(mintAddress, commitment); + // } + + // async getAccountInfoAndContext( + // publicKey: PublicKey, + // commitmentOrConfig?: Commitment | GetAccountInfoConfig, + // ): Promise | null>> { + // return this.connection.getAccountInfoAndContext( + // publicKey, + // commitmentOrConfig, + // ); + // } + + // async getParsedAccountInfo( + // publicKey: PublicKey, + // commitmentOrConfig?: Commitment | GetAccountInfoConfig, + // ): Promise< + // RpcResponseAndContext | null> + // > { + // return this.connection.getParsedAccountInfo( + // publicKey, + // commitmentOrConfig, + // ); + // } + + // async getAccountInfo( + // publicKey: PublicKey, + // commitmentOrConfig?: Commitment | GetAccountInfoConfig, + // ): Promise | null> { + // return this.connection.getAccountInfo(publicKey, commitmentOrConfig); + // } + + // async getMultipleParsedAccounts( + // publicKeys: PublicKey[], + // rawConfig?: GetMultipleAccountsConfig, + // ): Promise< + // RpcResponseAndContext< + // (AccountInfo | null)[] + // > + // > { + // return this.connection.getMultipleParsedAccounts(publicKeys, rawConfig); + // } + + // async getMultipleAccountsInfoAndContext( + // publicKeys: PublicKey[], + // commitmentOrConfig?: Commitment | GetMultipleAccountsConfig, + // ): Promise | null)[]>> { + // return this.connection.getMultipleAccountsInfoAndContext( + // publicKeys, + // commitmentOrConfig, + // ); + // } + + // async getMultipleAccountsInfo( + // publicKeys: PublicKey[], + // commitmentOrConfig?: Commitment | GetMultipleAccountsConfig, + // ): Promise<(AccountInfo | null)[]> { + // return this.connection.getMultipleAccountsInfo( + // publicKeys, + // commitmentOrConfig, + // ); + // } + + // async getStakeActivation( + // publicKey: PublicKey, + // commitmentOrConfig?: Commitment | GetStakeActivationConfig, + // epoch?: number, + // ): Promise { + // return this.connection.getStakeActivation( + // publicKey, + // commitmentOrConfig, + // epoch, + // ); + // } + + // async getProgramAccounts( + // programId: PublicKey, + // configOrCommitment?: GetProgramAccountsConfig | Commitment, + // ): Promise; + + // async getProgramAccounts( + // programId: PublicKey, + // configOrCommitment: GetProgramAccountsConfig & { withContext: true }, + // ): Promise>; + + // async getProgramAccounts( + // programId: PublicKey, + // configOrCommitment?: GetProgramAccountsConfig | Commitment, + // ): Promise< + // | GetProgramAccountsResponse + // | RpcResponseAndContext + // > { + // return this.connection.getProgramAccounts( + // programId, + // configOrCommitment, + // ); + // } + + // async getParsedProgramAccounts( + // programId: PublicKey, + // configOrCommitment?: GetParsedProgramAccountsConfig | Commitment, + // ): Promise< + // Array<{ + // pubkey: PublicKey; + // account: AccountInfo; + // }> + // > { + // return this.connection.getParsedProgramAccounts( + // programId, + // configOrCommitment, + // ); + // } + + // // === Subscription Methods === + + // onAccountChange( + // publicKey: PublicKey, + // callback: AccountChangeCallback, + // config?: AccountSubscriptionConfig, + // ): ClientSubscriptionId { + // return this.connection.onAccountChange(publicKey, callback, config); + // } + + // async removeAccountChangeListener( + // clientSubscriptionId: ClientSubscriptionId, + // ): Promise { + // return this.connection.removeAccountChangeListener( + // clientSubscriptionId, + // ); + // } + + // onProgramAccountChange( + // programId: PublicKey, + // callback: ProgramAccountChangeCallback, + // config?: ProgramAccountSubscriptionConfig, + // ): ClientSubscriptionId { + // return this.connection.onProgramAccountChange( + // programId, + // callback, + // config, + // ); + // } + + // async removeProgramAccountChangeListener( + // clientSubscriptionId: ClientSubscriptionId, + // ): Promise { + // return this.connection.removeProgramAccountChangeListener( + // clientSubscriptionId, + // ); + // } + + // onLogs( + // filter: LogsFilter, + // callback: LogsCallback, + // commitment?: Commitment, + // ): ClientSubscriptionId { + // return this.connection.onLogs(filter, callback, commitment); + // } + + // async removeOnLogsListener( + // clientSubscriptionId: ClientSubscriptionId, + // ): Promise { + // return this.connection.removeOnLogsListener(clientSubscriptionId); + // } + + // onSlotChange(callback: SlotChangeCallback): ClientSubscriptionId { + // return this.connection.onSlotChange(callback); + // } + + // async removeSlotChangeListener( + // clientSubscriptionId: ClientSubscriptionId, + // ): Promise { + // return this.connection.removeSlotChangeListener(clientSubscriptionId); + // } + + // onSlotUpdate(callback: SlotUpdateCallback): ClientSubscriptionId { + // return this.connection.onSlotUpdate(callback); + // } + + // async removeSlotUpdateListener( + // clientSubscriptionId: ClientSubscriptionId, + // ): Promise { + // return this.connection.removeSlotUpdateListener(clientSubscriptionId); + // } + + // onSignature( + // signature: TransactionSignature, + // callback: SignatureResultCallback, + // commitment?: Commitment, + // ): ClientSubscriptionId { + // return this.connection.onSignature(signature, callback, commitment); + // } + + // onSignatureWithOptions( + // signature: TransactionSignature, + // callback: SignatureSubscriptionCallback, + // options?: SignatureSubscriptionOptions, + // ): ClientSubscriptionId { + // return this.connection.onSignatureWithOptions( + // signature, + // callback, + // options, + // ); + // } + + // async removeSignatureListener( + // clientSubscriptionId: ClientSubscriptionId, + // ): Promise { + // return this.connection.removeSignatureListener(clientSubscriptionId); + // } + + // onRootChange(callback: RootChangeCallback): ClientSubscriptionId { + // return this.connection.onRootChange(callback); + // } + + // async removeRootChangeListener( + // clientSubscriptionId: ClientSubscriptionId, + // ): Promise { + // return this.connection.removeRootChangeListener(clientSubscriptionId); + // } + + // // === Transaction Methods === + + // async sendTransaction( + // transaction: VersionedTransaction, + // options?: SendOptions, + // ): Promise { + // return this.connection.sendTransaction(transaction, options); + // } + + // async sendRawTransaction( + // rawTransaction: Buffer | Uint8Array | Array, + // options?: SendOptions, + // ): Promise { + // return this.connection.sendRawTransaction(rawTransaction, options); + // } + + // async sendEncodedTransaction( + // encodedTransaction: string, + // options?: SendOptions, + // ): Promise { + // return this.connection.sendEncodedTransaction( + // encodedTransaction, + // options, + // ); + // } + + // async simulateTransaction( + // transaction: VersionedTransaction, + // config?: SimulateTransactionConfig, + // ): Promise> { + // return this.connection.simulateTransaction(transaction, config); + // } + + // async requestAirdrop( + // to: PublicKey, + // lamports: number, + // ): Promise { + // return this.connection.requestAirdrop(to, lamports); + // } + + // async getStakeMinimumDelegation( + // config?: GetStakeMinimumDelegationConfig, + // ): Promise> { + // return this.connection.getStakeMinimumDelegation(config); + // } + + // async getTransactions( + // signatures: TransactionSignature[], + // commitmentOrConfig?: GetTransactionConfig | Finality, + // ): Promise<(VersionedTransactionResponse | null)[]> { + // return this.connection.getTransactions(signatures, commitmentOrConfig); + // } + + // async getTransaction( + // signature: string, + // rawConfig?: GetTransactionConfig, + // ): Promise { + // return this.connection.getTransaction(signature, rawConfig); + // } + + // async getParsedTransaction( + // signature: TransactionSignature, + // commitmentOrConfig?: GetVersionedTransactionConfig | Finality, + // ): Promise { + // return this.connection.getParsedTransaction( + // signature, + // commitmentOrConfig, + // ); + // } + + // async getParsedTransactions( + // signatures: TransactionSignature[], + // commitmentOrConfig?: GetVersionedTransactionConfig | Finality, + // ): Promise<(ParsedTransactionWithMeta | null)[]> { + // return this.connection.getParsedTransactions( + // signatures, + // commitmentOrConfig, + // ); + // } + + // async getConfirmedBlock( + // slot: number, + // commitment?: Finality, + // ): Promise { + // return this.connection.getConfirmedBlock(slot, commitment); + // } + + // async getBlocks( + // startSlot: number, + // endSlot?: number, + // commitment?: Finality, + // ): Promise> { + // return this.connection.getBlocks(startSlot, endSlot, commitment); + // } + + // async getBlockSignatures( + // slot: number, + // commitment?: Finality, + // ): Promise { + // return this.connection.getBlockSignatures(slot, commitment); + // } + + // async getConfirmedBlockSignatures( + // slot: number, + // commitment?: Finality, + // ): Promise { + // return this.connection.getConfirmedBlockSignatures(slot, commitment); + // } + + // confirmTransaction( + // strategy: TransactionConfirmationStrategy, + // commitment?: Commitment, + // ): Promise>; + + // /** @deprecated Instead, call `confirmTransaction` and pass in {@link TransactionConfirmationStrategy} */ + // // eslint-disable-next-line no-dupe-class-members + // confirmTransaction( + // strategy: TransactionSignature, + // commitment?: Commitment, + // ): Promise>; + + // async confirmTransaction( + // strategy: TransactionConfirmationStrategy | TransactionSignature, + // commitment?: Commitment, + // ): Promise> { + // // @ts-ignore + // return this.connection.confirmTransaction(strategy, commitment); + // } + + // async getClusterNodes(): Promise> { + // return this.connection.getClusterNodes(); + // } + + // async getVoteAccounts(commitment?: Commitment): Promise { + // return this.connection.getVoteAccounts(commitment); + // } + + // async getSlot( + // commitmentOrConfig?: Commitment | GetSlotConfig, + // ): Promise { + // return this.connection.getSlot(commitmentOrConfig); + // } + + // async getSlotLeader( + // commitmentOrConfig?: Commitment | GetSlotLeaderConfig, + // ): Promise { + // return this.connection.getSlotLeader(commitmentOrConfig); + // } + + // async getSlotLeaders( + // startSlot: number, + // limit: number, + // ): Promise> { + // return this.connection.getSlotLeaders(startSlot, limit); + // } + + // async getSignatureStatus( + // signature: TransactionSignature, + // config?: SignatureStatusConfig, + // ): Promise> { + // return this.connection.getSignatureStatus(signature, config); + // } + + // async getSignatureStatuses( + // signatures: Array, + // config?: SignatureStatusConfig, + // ): Promise>> { + // return this.connection.getSignatureStatuses(signatures, config); + // } + + // async getTotalSupply(commitment?: Commitment): Promise { + // return this.connection.getTotalSupply(commitment); + // } + + // async getBlockHeight(config?: GetBlockHeightConfig): Promise { + // return this.connection.getBlockHeight(config); + // } + + // async getBlockProduction( + // configOrCommitment?: GetBlockProductionConfig | Commitment, + // ): Promise> { + // return this.connection.getBlockProduction(configOrCommitment); + // } + + // async getTransactionCount( + // config?: GetTransactionCountConfig, + // ): Promise { + // return this.connection.getTransactionCount(config); + // } + + // async getInflationGovernor(): Promise { + // return this.connection.getInflationGovernor(); + // } + + // async getInflationReward( + // addresses: PublicKey[], + // epochs?: number, + // config?: GetInflationRewardConfig, + // ): Promise> { + // return this.connection.getInflationReward(addresses, epochs, config); + // } + + // async getInflationRate(): Promise { + // return this.connection.getInflationRate(); + // } + + // async getEpochInfo(config?: GetEpochInfoConfig): Promise { + // return this.connection.getEpochInfo(config); + // } + + // async getEpochSchedule(): Promise { + // return this.connection.getEpochSchedule(); + // } + + // async getLeaderSchedule(): Promise { + // return this.connection.getLeaderSchedule(); + // } + + // async getRecentBlockhashAndContext(commitment?: Commitment): Promise< + // RpcResponseAndContext<{ + // blockhash: Blockhash; + // feeCalculator: FeeCalculator; + // }> + // > { + // return this.connection.getRecentBlockhashAndContext(commitment); + // } + + // async getRecentPerformanceSamples( + // limit?: number, + // ): Promise> { + // return this.connection.getRecentPerformanceSamples(limit); + // } + + // async getFeeCalculatorForBlockhash( + // blockhash: Blockhash, + // commitment?: Commitment, + // ): Promise> { + // return this.connection.getFeeCalculatorForBlockhash( + // blockhash, + // commitment, + // ); + // } + + // async getFeeForMessage( + // message: VersionedMessage, + // commitment?: Commitment, + // ): Promise> { + // return this.connection.getFeeForMessage(message, commitment); + // } + + // async getMinimumBalanceForRentExemption( + // dataLength: number, + // commitment?: Commitment, + // ): Promise { + // return this.connection.getMinimumBalanceForRentExemption( + // dataLength, + // commitment, + // ); + // } + + // async getRecentBlockhash( + // commitment?: Commitment, + // ): Promise<{ blockhash: Blockhash; feeCalculator: FeeCalculator }> { + // return this.connection.getRecentBlockhash(commitment); + // } + + // async getGenesisHash(): Promise { + // return this.connection.getGenesisHash(); + // } + // async getBlock( + // slot: number, + // rawConfig?: GetVersionedBlockConfig, + // ): Promise; + // async getBlock( + // slot: number, + // rawConfig: GetVersionedBlockConfig & { transactionDetails: 'accounts' }, + // ): Promise; + // async getBlock( + // slot: number, + // rawConfig: GetVersionedBlockConfig & { transactionDetails: 'none' }, + // ): Promise; + // async getBlock( + // slot: number, + // rawConfig?: GetVersionedBlockConfig, + // ): Promise< + // | VersionedBlockResponse + // | VersionedAccountsModeBlockResponse + // | VersionedNoneModeBlockResponse + // | null + // > { + // return this.connection.getBlock(slot, rawConfig); + // } + + // async getParsedBlock( + // slot: number, + // rawConfig?: GetVersionedBlockConfig, + // ): Promise; + // async getParsedBlock( + // slot: number, + // rawConfig: GetVersionedBlockConfig & { transactionDetails: 'accounts' }, + // ): Promise; + // async getParsedBlock( + // slot: number, + // rawConfig: GetVersionedBlockConfig & { transactionDetails: 'none' }, + // ): Promise; + // async getParsedBlock( + // slot: number, + // rawConfig?: GetVersionedBlockConfig, + // ): Promise< + // ParsedAccountsModeBlockResponse | ParsedNoneModeBlockResponse | null + // > { + // return this.connection.getParsedBlock(slot, rawConfig); + // } + + // async getConfirmedTransaction( + // signature: TransactionSignature, + // commitment?: Finality, + // ): Promise { + // return this.connection.getConfirmedTransaction(signature, commitment); + // } + + // async getParsedConfirmedTransaction( + // signature: TransactionSignature, + // commitment?: Finality, + // ): Promise { + // return this.connection.getParsedConfirmedTransaction( + // signature, + // commitment, + // ); + // } + + // async getParsedConfirmedTransactions( + // signatures: TransactionSignature[], + // commitment?: Finality, + // ): Promise<(ParsedConfirmedTransaction | null)[]> { + // return this.connection.getParsedConfirmedTransactions( + // signatures, + // commitment, + // ); + // } + + // async getConfirmedSignaturesForAddress( + // address: PublicKey, + // startSlot: number, + // endSlot: number, + // ): Promise> { + // return this.connection.getConfirmedSignaturesForAddress( + // address, + // startSlot, + // endSlot, + // ); + // } + + // async getConfirmedSignaturesForAddress2( + // address: PublicKey, + // options?: ConfirmedSignaturesForAddress2Options, + // commitment?: Finality, + // ): Promise> { + // return this.connection.getConfirmedSignaturesForAddress2( + // address, + // options, + // commitment, + // ); + // } + + // async getSignaturesForAddress( + // address: PublicKey, + // options?: SignaturesForAddressOptions, + // commitment?: Finality, + // ): Promise> { + // return this.connection.getSignaturesForAddress( + // address, + // options, + // commitment, + // ); + // } + + // async getRecentPrioritizationFees( + // config?: GetRecentPrioritizationFeesConfig, + // ): Promise { + // return this.connection.getRecentPrioritizationFees(config); + // } + + // async getLatestBlockhash( + // config?: GetLatestBlockhashConfig, + // ): Promise { + // return this.connection.getLatestBlockhash(config); + // } + // async getLatestBlockhashAndContext( + // commitmentOrConfig?: Commitment | GetLatestBlockhashConfig, + // ): Promise> { + // return this.connection.getLatestBlockhashAndContext(commitmentOrConfig); + // } + + // async isBlockhashValid( + // blockhash: Blockhash, + // config?: IsBlockhashValidConfig, + // ): Promise> { + // return this.connection.isBlockhashValid(blockhash, config); + // } + + // async getVersion(): Promise { + // return this.connection.getVersion(); + // } + + // async getAddressLookupTable( + // accountKey: PublicKey, + // config?: GetAccountInfoConfig, + // ): Promise> { + // return this.connection.getAddressLookupTable(accountKey, config); + // } + + // async getNonceAndContext( + // nonceAccount: PublicKey, + // commitmentOrConfig?: Commitment | GetNonceAndContextConfig, + // ): Promise> { + // return this.connection.getNonceAndContext( + // nonceAccount, + // commitmentOrConfig, + // ); + // } + + // async getNonce( + // nonceAccount: PublicKey, + // commitmentOrConfig?: Commitment | GetNonceConfig, + // ): Promise { + // return this.connection.getNonce(nonceAccount, commitmentOrConfig); + // } + + // _buildArgs( + // args: Array, + // override?: Commitment, + // encoding?: 'jsonParsed' | 'base64', + // extra?: any, + // ): Array { + // const commitment = override || this.connection.commitment; + // if (commitment || encoding || extra) { + // let options: any = {}; + // if (encoding) { + // options.encoding = encoding; + // } + // if (commitment) { + // options.commitment = commitment; + // } + // if (extra) { + // options = Object.assign(options, extra); + // } + // args.push(options); + // } + // return args; + // } + + // private async getCancellationPromise() { + // throw new Error( + // 'getCancellationPromise not supported in rpc. it is a stub that is marked as private in web3.js Connection', + // ); + // } + // private async getTransactionConfirmationPromise() { + // throw new Error( + // 'getTransactionConfirmationPromise not supported in rpc. it is a stub that is marked as private in web3.js Connection', + // ); + // } + // private async confirmTransactionUsingBlockHeightExceedanceStrategy() { + // throw new Error( + // 'confirmTransactionUsingBlockHeightExceedanceStrategy not supported in rpc. it is a stub that is marked as private in web3.js Connection', + // ); + // } + // async confirmTransactionUsingDurableNonceStrategy() { + // throw new Error( + // 'confirmTransactionUsingDurableNonceStrategy not supported in rpc. it is a stub that is marked as private in web3.js Connection', + // ); + // } + // private async confirmTransactionUsingLegacyTimeoutStrategy({ + // commitment, + // signature, + // }: { + // commitment?: Commitment; + // signature: string; + // }): Promise> { + // throw new Error( + // 'confirmTransactionUsingLegacyTimeoutStrategy not supported in rpc. it is a stub that is marked as private in web3.js Connection', + // ); + // } + /** * Fetch the compressed account for the specified account hash */ @@ -211,6 +1025,7 @@ export class TestRpc extends Connection implements CompressionApiInterface { if (!hash) { throw new Error('hash is required'); } + // @ts-ignore const account = await getCompressedAccountByHashTest(this, hash); return account ?? null; } @@ -225,6 +1040,7 @@ export class TestRpc extends Connection implements CompressionApiInterface { if (!hash) { throw new Error('hash is required'); } + // @ts-ignore const account = await getCompressedAccountByHashTest(this, hash); if (!account) { throw new Error('Account not found'); @@ -261,6 +1077,7 @@ export class TestRpc extends Connection implements CompressionApiInterface { async getMultipleCompressedAccounts( hashes: BN254[], ): Promise { + // @ts-ignore return await getMultipleCompressedAccountsByHashTest(this, hashes); } /** @@ -278,6 +1095,7 @@ export class TestRpc extends Connection implements CompressionApiInterface { ): Promise { /// Build tree const events: PublicTransactionEvent[] = await getParsedEvents( + // @ts-ignore this, ).then(events => events.reverse()); const allLeaves: number[][] = []; @@ -343,13 +1161,7 @@ export class TestRpc extends Connection implements CompressionApiInterface { owner: PublicKey, _config?: GetCompressedAccountsByOwnerConfig, ): Promise> { - // TODO(swen): revisit - // if (_config) { - // throw new Error( - // 'dataSlice or filters are not supported in test-rpc. Please use rpc.ts instead.', - // ); - // } - + // @ts-ignore const accounts = await getCompressedAccountsByOwnerTest(this, owner); return { items: accounts, @@ -389,6 +1201,7 @@ export class TestRpc extends Connection implements CompressionApiInterface { options: GetCompressedTokenAccountsByOwnerOrDelegateOptions, ): Promise> { return await getCompressedTokenAccountsByOwnerTest( + // @ts-ignore this, owner, options!.mint!, @@ -403,6 +1216,7 @@ export class TestRpc extends Connection implements CompressionApiInterface { options: GetCompressedTokenAccountsByOwnerOrDelegateOptions, ): Promise> { return await getCompressedTokenAccountsByDelegateTest( + // @ts-ignore this, delegate, options.mint!, @@ -415,6 +1229,7 @@ export class TestRpc extends Connection implements CompressionApiInterface { async getCompressedTokenAccountBalance( hash: BN254, ): Promise<{ amount: BN }> { + // @ts-ignore const account = await getCompressedTokenAccountByHashTest(this, hash); return { amount: bn(account.parsed.amount) }; } @@ -429,6 +1244,7 @@ export class TestRpc extends Connection implements CompressionApiInterface { options: GetCompressedTokenAccountsByOwnerOrDelegateOptions, ): Promise> { const accounts = await getCompressedTokenAccountsByOwnerTest( + // @ts-ignore this, publicKey, options.mint!, @@ -451,6 +1267,7 @@ export class TestRpc extends Connection implements CompressionApiInterface { options: GetCompressedTokenAccountsByOwnerOrDelegateOptions, ): Promise>> { const accounts = await getCompressedTokenAccountsByOwnerTest( + // @ts-ignore this, publicKey, options.mint!, diff --git a/js/stateless.js/src/utils/conversion.ts b/js/stateless.js/src/utils/conversion.ts index 57f2fa19b5..b32eda3a72 100644 --- a/js/stateless.js/src/utils/conversion.ts +++ b/js/stateless.js/src/utils/conversion.ts @@ -3,7 +3,7 @@ import { bn, createBN254 } from '../state/BN254'; import { FIELD_SIZE } from '../constants'; import { keccak_256 } from '@noble/hashes/sha3'; import { Keypair } from '@solana/web3.js'; -import { BN } from '@coral-xyz/anchor'; +import BN from 'bn.js'; export function byteArrayToKeypair(byteArray: number[]): Keypair { return Keypair.fromSecretKey(Uint8Array.from(byteArray)); diff --git a/js/stateless.js/src/utils/parse-validity-proof.ts b/js/stateless.js/src/utils/parse-validity-proof.ts index 5ed1b92f09..3bce8ef4e2 100644 --- a/js/stateless.js/src/utils/parse-validity-proof.ts +++ b/js/stateless.js/src/utils/parse-validity-proof.ts @@ -1,4 +1,4 @@ -import { BN } from '@coral-xyz/anchor'; +import BN from 'bn.js'; import { FIELD_SIZE } from '../constants'; import { CompressedProof } from '../state'; diff --git a/js/stateless.js/src/utils/validation.ts b/js/stateless.js/src/utils/validation.ts index 94d2f5cb6b..1289d4a5a0 100644 --- a/js/stateless.js/src/utils/validation.ts +++ b/js/stateless.js/src/utils/validation.ts @@ -1,4 +1,4 @@ -import { BN } from '@coral-xyz/anchor'; +import BN from 'bn.js'; import { CompressedAccount, CompressedAccountWithMerkleContext, diff --git a/js/stateless.js/src/wallet/index.ts b/js/stateless.js/src/wallet/index.ts deleted file mode 100644 index aa9f5f581c..0000000000 --- a/js/stateless.js/src/wallet/index.ts +++ /dev/null @@ -1 +0,0 @@ -export * from './use-wallet'; diff --git a/js/stateless.js/src/wallet/interface.ts b/js/stateless.js/src/wallet/interface.ts deleted file mode 100644 index 0ed0a21a6b..0000000000 --- a/js/stateless.js/src/wallet/interface.ts +++ /dev/null @@ -1,85 +0,0 @@ -/// TODO: extract wallet into its own npm package -import { - Commitment, - Connection, - Keypair, - VersionedTransaction, - sendAndConfirmTransaction, -} from '@solana/web3.js'; -import { PublicKey, Transaction } from '@solana/web3.js'; -import nacl from 'tweetnacl'; -const { sign } = nacl; - -export type InclusionProofPublicInputs = { - root: string; - leaf: string; -}; -export type InclusionProofPrivateInputs = { - merkleProof: string[]; - leaf: string; - leafIndex: string; -}; - -/// On the system level, we're proving simple inclusion proofs in a -/// state tree, for each utxo used as input into a transaction. -export type InclusionProofInputs = (InclusionProofPublicInputs & - InclusionProofPrivateInputs)[]; - -/// Mock Solana web3 library -export class Wallet { - _publicKey: PublicKey; - _keypair: Keypair; - _connection: Connection; - _url: string; - _commitment: Commitment; - - constructor(keypair: Keypair, url: string, commitment: Commitment) { - this._publicKey = keypair.publicKey; - this._keypair = keypair; - this._connection = new Connection(url); - this._url = url; - this._commitment = commitment; - } - - signTransaction = async (tx: any): Promise => { - await tx.sign([this._keypair!]); - return tx; - }; - - sendTransaction = async ( - transaction: VersionedTransaction, - ): Promise => { - const signature = await this._connection.sendTransaction(transaction); - return signature; - }; - - signAllTransactions = async ( - transactions: T[], - ): Promise => { - const signedTxs = await Promise.all( - transactions.map(async tx => { - return await this.signTransaction(tx); - }), - ); - return signedTxs; - }; - - signMessage = async (message: Uint8Array): Promise => { - return sign.detached(message, this._keypair.secretKey); - }; - - sendAndConfirmTransaction = async ( - transaction: Transaction, - signers = [], - ): Promise => { - const response = await sendAndConfirmTransaction( - this._connection, - transaction, - [this._keypair, ...signers], - { - commitment: this._commitment, - }, - ); - return response; - }; -} diff --git a/js/stateless.js/src/wallet/use-wallet.ts b/js/stateless.js/src/wallet/use-wallet.ts deleted file mode 100644 index 88b0841767..0000000000 --- a/js/stateless.js/src/wallet/use-wallet.ts +++ /dev/null @@ -1,20 +0,0 @@ -import { Keypair, Commitment } from '@solana/web3.js'; -import { Wallet } from './interface'; - -// TODO consider adding isNodeWallet -export const useWallet = ( - keypair: Keypair, - url: string = 'http://127.0.0.1:8899', - commitment: Commitment = 'confirmed', -) => { - url = url !== 'mock' ? url : 'http://127.0.0.1:8899'; - const wallet = new Wallet(keypair, url, commitment); - return { - publicKey: wallet._publicKey, - sendAndConfirmTransaction: wallet.sendAndConfirmTransaction, - signMessage: wallet.signMessage, - signTransaction: wallet.signTransaction, - signAllTransactions: wallet.signAllTransactions, - sendTransaction: wallet.sendTransaction, - }; -}; diff --git a/js/stateless.js/tests/e2e/rpc-interop.test.ts b/js/stateless.js/tests/e2e/rpc-interop.test.ts index fc3e170580..6c08b7633d 100644 --- a/js/stateless.js/tests/e2e/rpc-interop.test.ts +++ b/js/stateless.js/tests/e2e/rpc-interop.test.ts @@ -104,7 +104,13 @@ describe('rpc-interop', () => { executedTxs++; /// Executes a transfer using a 'validityProof' directly from a prover. - await transfer(testRpc, payer, 1e5, payer, bob.publicKey); + await transfer( + testRpc as unknown as Rpc, + payer, + 1e5, + payer, + bob.publicKey, + ); executedTxs++; }); @@ -170,7 +176,7 @@ describe('rpc-interop', () => { /// Creates a compressed account with address using a (non-inclusion) /// 'validityProof' directly from a prover. await createAccount( - testRpc, + testRpc as unknown as Rpc, payer, newAddressSeeds, LightSystemProgram.programId, diff --git a/js/stateless.js/tests/e2e/serde.test.ts b/js/stateless.js/tests/e2e/serde.test.ts index 35583771fe..7bf6e59a71 100644 --- a/js/stateless.js/tests/e2e/serde.test.ts +++ b/js/stateless.js/tests/e2e/serde.test.ts @@ -1,61 +1,28 @@ import { describe, it, expect } from 'vitest'; -import { LightSystemProgram } from '../../src/programs'; +import { PublicTransactionEvent, bn } from '../../src'; import { - CompressedAccount, - PublicTransactionEvent, - bn, - useWallet, -} from '../../src'; -import { Connection, Keypair, PublicKey } from '@solana/web3.js'; -import { AnchorProvider, Program, setProvider } from '@coral-xyz/anchor'; -import { IDL } from '../../src/idls/account_compression'; - -describe('account compression program', () => { - it('instantiate using IDL', async () => { - const mockKeypair = Keypair.generate(); - const mockConnection = new Connection( - 'http://127.0.0.1:8899', - 'confirmed', - ); - const mockProvider = new AnchorProvider( - mockConnection, - useWallet(mockKeypair), - { - commitment: 'confirmed', - preflightCommitment: 'confirmed', - }, - ); - setProvider(mockProvider); - const program = new Program( - IDL, - new PublicKey('5QPEJ5zDsVou9FQS3KCauKswM3VwBEBu4dpL9xTqkWwN'), - mockProvider, - ); - - expect(program).toBeDefined(); - }); -}); + CompressedAccountLayout, + decodePublicTransactionEvent, +} from '../../src/programs/layout'; describe('serde', () => { - it('decode output compressed account ', async () => { - const compressedAccount = [ - 88, 8, 48, 185, 124, 227, 14, 195, 230, 152, 61, 39, 56, 191, 13, - 126, 54, 43, 47, 131, 175, 16, 52, 167, 129, 174, 200, 118, 174, 9, - 254, 80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - ]; + // it('decode output compressed account', async () => { + // const compressedAccount = [ + // 88, 8, 48, 185, 124, 227, 14, 195, 230, 152, 61, 39, 56, 191, 13, + // 126, 54, 43, 47, 131, 175, 16, 52, 167, 129, 174, 200, 118, 174, 9, + // 254, 80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + // ]; - const deserializedCompressedAccount: CompressedAccount = - LightSystemProgram.program.coder.types.decode( - 'CompressedAccount', - Buffer.from(compressedAccount), - ); + // const deserializedCompressedAccount = CompressedAccountLayout.decode( + // Buffer.from(compressedAccount), + // ); - expect(deserializedCompressedAccount.data).toBe(null); - expect(deserializedCompressedAccount.address).toBe(null); - expect(deserializedCompressedAccount.lamports.eq(bn(0))).toBe(true); - }); + // expect(deserializedCompressedAccount.data).toBe(null); + // expect(deserializedCompressedAccount.address).toBe(null); + // expect(deserializedCompressedAccount.lamports.eq(bn(0))).toBe(true); + // }); - it('decode event ', async () => { + it('decode event', async () => { const data = [ 0, 0, 0, 0, 1, 0, 0, 0, 33, 32, 204, 221, 5, 83, 170, 139, 228, 191, 81, 173, 10, 116, 229, 191, 155, 209, 23, 164, 28, 64, 188, 34, 248, @@ -67,21 +34,17 @@ describe('serde', () => { 44, 121, 118, 153, 17, 179, 183, 115, 34, 163, 127, 102, 214, 1, 87, 175, 177, 95, 49, 65, 69, 0, ]; - const event: PublicTransactionEvent = - LightSystemProgram.program.coder.types.decode( - 'PublicTransactionEvent', - Buffer.from(data), - ); + + const event = decodePublicTransactionEvent(Buffer.from(data)); const refOutputCompressedAccountHash = [ 33, 32, 204, 221, 5, 83, 170, 139, 228, 191, 81, 173, 10, 116, 229, 191, 155, 209, 23, 164, 28, 64, 188, 34, 248, 127, 110, 97, 26, 188, 139, 164, ]; - expect( - bn(event.outputCompressedAccountHashes[0]).eq( - bn(refOutputCompressedAccountHash), - ), - ).toBe(true); + + expect(event.outputCompressedAccountHashes[0]).toEqual( + Buffer.from(refOutputCompressedAccountHash), + ); }); }); diff --git a/js/stateless.js/tsconfig.json b/js/stateless.js/tsconfig.json index c661b81dfd..7b54864442 100644 --- a/js/stateless.js/tsconfig.json +++ b/js/stateless.js/tsconfig.json @@ -12,7 +12,8 @@ "moduleResolution": "Node", "lib": ["ESNext", "DOM"], "types": ["node"], - "skipLibCheck": false + "skipLibCheck": false, + "typeRoots": ["types/", "./node_modules/@types"] }, "include": ["./src/**/*.ts", "playwright.config.ts", "rollup.config.js"] } diff --git a/js/stateless.js/types/buffer-layout/index.d.ts b/js/stateless.js/types/buffer-layout/index.d.ts new file mode 100644 index 0000000000..f047cbb1fd --- /dev/null +++ b/js/stateless.js/types/buffer-layout/index.d.ts @@ -0,0 +1,88 @@ +// From https://github.com/coral-xyz/anchor/blob/master/ts/packages/anchor/types/buffer-layout/index.d.ts +declare module 'buffer-layout' { + // TODO: remove `any`. + export class Layout { + span: number; + property?: string; + + constructor(span: number, property?: string); + + decode(b: Buffer | string, offset?: number): T; + encode(src: T, b: Buffer, offset?: number): number; + getSpan(b: Buffer, offset?: number): number; + replicate(name: string): this; + } + // TODO: remove any. + export class Structure extends Layout { + span: any; + } + export function greedy( + elementSpan?: number, + property?: string, + ): Layout; + export function offset( + layout: Layout, + offset?: number, + property?: string, + ): Layout; + export function u8(property?: string): Layout; + export function u16(property?: string): Layout; + export function u24(property?: string): Layout; + export function u32(property?: string): Layout; + export function u40(property?: string): Layout; + export function u48(property?: string): Layout; + export function nu64(property?: string): Layout; + export function u16be(property?: string): Layout; + export function u24be(property?: string): Layout; + export function u32be(property?: string): Layout; + export function u40be(property?: string): Layout; + export function u48be(property?: string): Layout; + export function nu64be(property?: string): Layout; + export function s8(property?: string): Layout; + export function s16(property?: string): Layout; + export function s24(property?: string): Layout; + export function s32(property?: string): Layout; + export function s40(property?: string): Layout; + export function s48(property?: string): Layout; + export function ns64(property?: string): Layout; + export function s16be(property?: string): Layout; + export function s24be(property?: string): Layout; + export function s32be(property?: string): Layout; + export function s40be(property?: string): Layout; + export function s48be(property?: string): Layout; + export function ns64be(property?: string): Layout; + export function f32(property?: string): Layout; + export function f32be(property?: string): Layout; + export function f64(property?: string): Layout; + export function f64be(property?: string): Layout; + export function struct( + fields: Layout[], + property?: string, + decodePrefixes?: boolean, + ): Layout; + export function bits( + word: Layout, + msb?: boolean, + property?: string, + ): any; + export function seq( + elementLayout: Layout, + count: number | Layout, + property?: string, + ): Layout; + export function union( + discr: Layout, + defaultLayout?: any, + property?: string, + ): any; + export function unionLayoutDiscriminator( + layout: Layout, + property?: string, + ): any; + export function blob( + length: number | Layout, + property?: string, + ): Layout; + export function cstr(property?: string): Layout; + export function utf8(maxSpan: number, property?: string): Layout; +} diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 30d5ca4e29..06eee5c34f 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -63,8 +63,8 @@ importers: specifier: ^1.5.1 version: 1.5.1(bufferutil@4.0.8)(utf-8-validate@5.0.10) '@solana/web3.js': - specifier: 1.95.3 - version: 1.95.3(bufferutil@4.0.8)(utf-8-validate@5.0.10) + specifier: 1.95.5 + version: 1.95.5(bufferutil@4.0.8)(utf-8-validate@5.0.10) axios: specifier: ^1.6.8 version: 1.6.8 @@ -113,7 +113,7 @@ importers: version: 2.3.9(@types/node@20.12.11)(typescript@5.5.3) '@solana/spl-token': specifier: ^0.3.11 - version: 0.3.11(@solana/web3.js@1.95.3(bufferutil@4.0.8)(utf-8-validate@5.0.10))(bufferutil@4.0.8)(fastestsmallesttextencoderdecoder@1.0.22)(utf-8-validate@5.0.10) + version: 0.3.11(@solana/web3.js@1.95.5(bufferutil@4.0.8)(utf-8-validate@5.0.10))(bufferutil@4.0.8)(fastestsmallesttextencoderdecoder@1.0.22)(utf-8-validate@5.0.10) '@types/bn.js': specifier: ^5.1.5 version: 5.1.5 @@ -194,19 +194,19 @@ importers: version: link:../../../js/stateless.js '@solana/wallet-adapter-base': specifier: ^0.9.23 - version: 0.9.23(@solana/web3.js@1.95.3(bufferutil@4.0.8)(utf-8-validate@5.0.10)) + version: 0.9.23(@solana/web3.js@1.95.5(bufferutil@4.0.8)(utf-8-validate@5.0.10)) '@solana/wallet-adapter-react': specifier: ^0.15.35 - version: 0.15.35(@solana/web3.js@1.95.3(bufferutil@4.0.8)(utf-8-validate@5.0.10))(bs58@6.0.0)(react-native@0.72.14(@babel/core@7.24.5)(@babel/preset-env@7.24.5(@babel/core@7.24.5))(bufferutil@4.0.8)(react@19.0.0)(utf-8-validate@5.0.10))(react@19.0.0) + version: 0.15.35(@solana/web3.js@1.95.5(bufferutil@4.0.8)(utf-8-validate@5.0.10))(bs58@6.0.0)(react-native@0.72.14(@babel/core@7.24.5)(@babel/preset-env@7.24.5(@babel/core@7.24.5))(bufferutil@4.0.8)(react@19.0.0)(utf-8-validate@5.0.10))(react@19.0.0) '@solana/wallet-adapter-react-ui': specifier: ^0.9.35 - version: 0.9.35(@solana/web3.js@1.95.3(bufferutil@4.0.8)(utf-8-validate@5.0.10))(bs58@6.0.0)(react-dom@19.0.0(react@19.0.0))(react-native@0.72.14(@babel/core@7.24.5)(@babel/preset-env@7.24.5(@babel/core@7.24.5))(bufferutil@4.0.8)(react@19.0.0)(utf-8-validate@5.0.10))(react@19.0.0) + version: 0.9.35(@solana/web3.js@1.95.5(bufferutil@4.0.8)(utf-8-validate@5.0.10))(bs58@6.0.0)(react-dom@19.0.0(react@19.0.0))(react-native@0.72.14(@babel/core@7.24.5)(@babel/preset-env@7.24.5(@babel/core@7.24.5))(bufferutil@4.0.8)(react@19.0.0)(utf-8-validate@5.0.10))(react@19.0.0) '@solana/wallet-adapter-unsafe-burner': specifier: ^0.1.7 - version: 0.1.7(@solana/web3.js@1.95.3(bufferutil@4.0.8)(utf-8-validate@5.0.10)) + version: 0.1.7(@solana/web3.js@1.95.5(bufferutil@4.0.8)(utf-8-validate@5.0.10)) '@solana/web3.js': - specifier: ^1.95.3 - version: 1.95.3(bufferutil@4.0.8)(utf-8-validate@5.0.10) + specifier: ^1.95.5 + version: 1.95.5(bufferutil@4.0.8)(utf-8-validate@5.0.10) bs58: specifier: ^6.0.0 version: 6.0.0 @@ -243,7 +243,7 @@ importers: dependencies: '@coral-xyz/anchor': specifier: ^0.29.0 - version: 0.29.0(bufferutil@4.0.8)(utf-8-validate@5.0.10) + version: 0.29.0 devDependencies: '@lightprotocol/zk-compression-cli': specifier: workspace:* @@ -282,8 +282,8 @@ importers: specifier: workspace:* version: link:../../../js/stateless.js '@solana/web3.js': - specifier: ^1.95.3 - version: 1.95.3(bufferutil@4.0.8)(utf-8-validate@5.0.10) + specifier: ^1.95.5 + version: 1.95.5(bufferutil@4.0.8)(utf-8-validate@5.0.10) devDependencies: '@types/node': specifier: ^22.10.2 @@ -296,7 +296,7 @@ importers: dependencies: '@coral-xyz/anchor': specifier: 0.29.0 - version: 0.29.0(bufferutil@4.0.8)(utf-8-validate@5.0.10) + version: 0.29.0 devDependencies: '@types/bn.js': specifier: ^5.1.6 @@ -331,24 +331,18 @@ importers: js/compressed-token: dependencies: - '@coral-xyz/anchor': - specifier: 0.29.0 - version: 0.29.0(bufferutil@4.0.8)(utf-8-validate@5.0.10) + '@coral-xyz/borsh': + specifier: ^0.29.0 + version: 0.29.0(@solana/web3.js@1.98.0(bufferutil@4.0.8)(utf-8-validate@5.0.10)) '@lightprotocol/stateless.js': specifier: workspace:* version: link:../stateless.js - '@solana/spl-token': - specifier: 0.4.8 - version: 0.4.8(@solana/web3.js@1.95.3(bufferutil@4.0.8)(utf-8-validate@5.0.10))(bufferutil@4.0.8)(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.6.2)(utf-8-validate@5.0.10) - '@solana/web3.js': - specifier: 1.95.3 - version: 1.95.3(bufferutil@4.0.8)(utf-8-validate@5.0.10) + bn.js: + specifier: ^5.2.1 + version: 5.2.1 buffer: specifier: 6.0.3 version: 6.0.3 - tweetnacl: - specifier: 1.0.3 - version: 1.0.3 devDependencies: '@esbuild-plugins/node-globals-polyfill': specifier: ^0.2.3 @@ -383,6 +377,15 @@ importers: '@rollup/plugin-typescript': specifier: ^11.1.6 version: 11.1.6(rollup@4.21.3)(tslib@2.7.0)(typescript@5.6.2) + '@solana/spl-token': + specifier: 0.4.8 + version: 0.4.8(@solana/web3.js@1.98.0(bufferutil@4.0.8)(utf-8-validate@5.0.10))(bufferutil@4.0.8)(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.6.2)(utf-8-validate@5.0.10) + '@solana/web3.js': + specifier: 1.98.0 + version: 1.98.0(bufferutil@4.0.8)(utf-8-validate@5.0.10) + '@types/bn.js': + specifier: ^5.1.5 + version: 5.1.5 '@types/node': specifier: ^22.5.5 version: 22.5.5 @@ -449,24 +452,30 @@ importers: js/stateless.js: dependencies: - '@coral-xyz/anchor': - specifier: 0.29.0 - version: 0.29.0(bufferutil@4.0.8)(utf-8-validate@5.0.10) + '@coral-xyz/borsh': + specifier: ^0.29.0 + version: 0.29.0(@solana/web3.js@1.98.0(bufferutil@4.0.8)(utf-8-validate@5.0.10)) '@noble/hashes': specifier: 1.5.0 version: 1.5.0 - '@solana/web3.js': - specifier: 1.95.3 - version: 1.95.3(bufferutil@4.0.8)(utf-8-validate@5.0.10) + bn.js: + specifier: ^5.2.1 + version: 5.2.1 + bs58: + specifier: ^6.0.0 + version: 6.0.0 buffer: specifier: 6.0.3 version: 6.0.3 + buffer-layout: + specifier: ^1.2.2 + version: 1.2.2 + camelcase: + specifier: ^8.0.0 + version: 8.0.0 superstruct: specifier: 2.0.2 version: 2.0.2 - tweetnacl: - specifier: 1.0.3 - version: 1.0.3 devDependencies: '@esbuild-plugins/node-globals-polyfill': specifier: ^0.2.3 @@ -501,6 +510,9 @@ importers: '@rollup/plugin-typescript': specifier: ^11.1.6 version: 11.1.6(rollup@4.21.3)(tslib@2.7.0)(typescript@5.6.2) + '@solana/web3.js': + specifier: 1.98.0 + version: 1.98.0(bufferutil@4.0.8)(utf-8-validate@5.0.10) '@types/bn.js': specifier: ^5.1.5 version: 5.1.5 @@ -552,6 +564,9 @@ importers: tslib: specifier: ^2.7.0 version: 2.7.0 + tweetnacl: + specifier: 1.0.3 + version: 1.0.3 typescript: specifier: ^5.6.2 version: 5.6.2 @@ -567,7 +582,7 @@ importers: dependencies: '@coral-xyz/anchor': specifier: ^0.29.0 - version: 0.29.0(bufferutil@4.0.8)(utf-8-validate@5.0.10) + version: 0.29.0 devDependencies: '@lightprotocol/zk-compression-cli': specifier: workspace:* @@ -1521,8 +1536,8 @@ packages: peerDependencies: '@solana/web3.js': ^1.68.0 - '@coral-xyz/borsh@0.30.0': - resolution: {integrity: sha512-OrcV+7N10cChhgDRUxM4iEIuwxUHHs52XD85R8cFCUqE0vbLYrcoPPPs+VF6kZ9DhdJGVW2I6DHJOp5TykyZog==} + '@coral-xyz/borsh@0.30.1': + resolution: {integrity: sha512-aaxswpPrCFKl8vZTbxLssA2RvwX2zmKLlRCIktJOwW+VpVwYtXRtlWiIP+c2pPRKneiTiWCN2GEMSH9j1zTlWQ==} engines: {node: '>=10'} peerDependencies: '@solana/web3.js': ^1.68.0 @@ -2976,15 +2991,15 @@ packages: '@solana/wallet-adapter-base': '*' react: '*' - '@solana/web3.js@1.95.3': - resolution: {integrity: sha512-O6rPUN0w2fkNqx/Z3QJMB9L225Ex10PRDH8bTaIUPZXMPV0QP8ZpPvjQnXK+upUczlRgzHzd6SjKIha1p+I6og==} + '@solana/web3.js@1.95.5': + resolution: {integrity: sha512-hU9cBrbg1z6gEjLH9vwIckGBVB78Ijm0iZFNk4ocm5OD82piPwuk3MeQ1rfiKD9YQtr95krrcaopb49EmQJlRg==} + + '@solana/web3.js@1.98.0': + resolution: {integrity: sha512-nz3Q5OeyGFpFCR+erX2f6JPt3sKhzhYcSycBCSPkWjzSVDh/Rr1FqTVMRe58FKO16/ivTUcuJjeS5MyBvpkbzA==} '@swc/counter@0.1.3': resolution: {integrity: sha512-e2BR4lsJkkRlKZ/qCHPw9ZaSxc0MVUd7gtbtaB7aMvHeJVYe8sOB8DBZkP2DtISHGSku9sCK6T6cnY0CtXrOCQ==} - '@swc/helpers@0.5.11': - resolution: {integrity: sha512-YNlnKRWF2sVojTpIyzwou9XoTNbzbzONwRhOoniEioF1AtaitTvVZblaQRrAzChWQ1bLYyYSWzM18y4WwgzJ+A==} - '@swc/helpers@0.5.13': resolution: {integrity: sha512-UoKGxQ3r5kYI9dALKJapMmuK+1zWM/H17Z1+iwnNmzcJRnfFuevZs375TA5rW31pu4BS4NoSy1fRsexDXfWn5w==} @@ -3805,6 +3820,10 @@ packages: resolution: {integrity: sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==} engines: {node: '>=10'} + camelcase@8.0.0: + resolution: {integrity: sha512-8WB3Jcas3swSvjIeA2yvCJ+Miyz5l1ZmB6HFb9R1317dt9LCQoswg/BGrmAmkWVEszSrrg4RwmO46qIm2OEnSA==} + engines: {node: '>=16'} + caniuse-lite@1.0.30001617: resolution: {integrity: sha512-mLyjzNI9I+Pix8zwcrpxEbGlfqOkF9kM3ptzmKNw5tizSyYwMe+nGLTqMK9cO+0E+Bh6TsBxNAaHWEM8xwSsmA==} @@ -9425,11 +9444,32 @@ snapshots: '@babel/helper-validator-identifier': 7.24.5 to-fast-properties: 2.0.0 + '@coral-xyz/anchor@0.29.0': + dependencies: + '@coral-xyz/borsh': 0.29.0(@solana/web3.js@1.95.5) + '@noble/hashes': 1.5.0 + '@solana/web3.js': 1.95.5(bufferutil@4.0.8)(utf-8-validate@5.0.10) + bn.js: 5.2.1 + bs58: 4.0.1 + buffer-layout: 1.2.2 + camelcase: 6.3.0 + cross-fetch: 3.1.8 + crypto-hash: 1.3.0 + eventemitter3: 4.0.7 + pako: 2.1.0 + snake-case: 3.0.4 + superstruct: 0.15.5 + toml: 3.0.0 + transitivePeerDependencies: + - bufferutil + - encoding + - utf-8-validate + '@coral-xyz/anchor@0.29.0(bufferutil@4.0.8)(utf-8-validate@5.0.10)': dependencies: - '@coral-xyz/borsh': 0.29.0(@solana/web3.js@1.95.3) - '@noble/hashes': 1.4.0 - '@solana/web3.js': 1.95.3(bufferutil@4.0.8)(utf-8-validate@5.0.10) + '@coral-xyz/borsh': 0.29.0(@solana/web3.js@1.95.5(bufferutil@4.0.8)(utf-8-validate@5.0.10)) + '@noble/hashes': 1.5.0 + '@solana/web3.js': 1.95.5(bufferutil@4.0.8)(utf-8-validate@5.0.10) bn.js: 5.2.1 bs58: 4.0.1 buffer-layout: 1.2.2 @@ -9448,9 +9488,9 @@ snapshots: '@coral-xyz/anchor@0.30.0(bufferutil@4.0.8)(utf-8-validate@5.0.10)': dependencies: - '@coral-xyz/borsh': 0.30.0(@solana/web3.js@1.95.3(bufferutil@4.0.8)(utf-8-validate@5.0.10)) - '@noble/hashes': 1.4.0 - '@solana/web3.js': 1.95.3(bufferutil@4.0.8)(utf-8-validate@5.0.10) + '@coral-xyz/borsh': 0.30.1(@solana/web3.js@1.95.5(bufferutil@4.0.8)(utf-8-validate@5.0.10)) + '@noble/hashes': 1.5.0 + '@solana/web3.js': 1.95.5(bufferutil@4.0.8)(utf-8-validate@5.0.10) bn.js: 5.2.1 bs58: 4.0.1 buffer-layout: 1.2.2 @@ -9467,15 +9507,27 @@ snapshots: - encoding - utf-8-validate - '@coral-xyz/borsh@0.29.0(@solana/web3.js@1.95.3)': + '@coral-xyz/borsh@0.29.0(@solana/web3.js@1.95.5(bufferutil@4.0.8)(utf-8-validate@5.0.10))': + dependencies: + '@solana/web3.js': 1.95.5(bufferutil@4.0.8)(utf-8-validate@5.0.10) + bn.js: 5.2.1 + buffer-layout: 1.2.2 + + '@coral-xyz/borsh@0.29.0(@solana/web3.js@1.95.5)': + dependencies: + '@solana/web3.js': 1.95.5(bufferutil@4.0.8)(utf-8-validate@5.0.10) + bn.js: 5.2.1 + buffer-layout: 1.2.2 + + '@coral-xyz/borsh@0.29.0(@solana/web3.js@1.98.0(bufferutil@4.0.8)(utf-8-validate@5.0.10))': dependencies: - '@solana/web3.js': 1.95.3(bufferutil@4.0.8)(utf-8-validate@5.0.10) + '@solana/web3.js': 1.98.0(bufferutil@4.0.8)(utf-8-validate@5.0.10) bn.js: 5.2.1 buffer-layout: 1.2.2 - '@coral-xyz/borsh@0.30.0(@solana/web3.js@1.95.3(bufferutil@4.0.8)(utf-8-validate@5.0.10))': + '@coral-xyz/borsh@0.30.1(@solana/web3.js@1.95.5(bufferutil@4.0.8)(utf-8-validate@5.0.10))': dependencies: - '@solana/web3.js': 1.95.3(bufferutil@4.0.8)(utf-8-validate@5.0.10) + '@solana/web3.js': 1.95.5(bufferutil@4.0.8)(utf-8-validate@5.0.10) bn.js: 5.2.1 buffer-layout: 1.2.2 @@ -10845,7 +10897,7 @@ snapshots: '@solana-developers/helpers@1.5.1(bufferutil@4.0.8)(utf-8-validate@5.0.10)': dependencies: - '@solana/web3.js': 1.95.3(bufferutil@4.0.8)(utf-8-validate@5.0.10) + '@solana/web3.js': 1.95.5(bufferutil@4.0.8)(utf-8-validate@5.0.10) bs58: 5.0.0 dotenv: 16.4.5 prettier: 3.3.3 @@ -10855,10 +10907,10 @@ snapshots: - encoding - utf-8-validate - '@solana-mobile/mobile-wallet-adapter-protocol-web3js@2.0.2(@solana/web3.js@1.95.3(bufferutil@4.0.8)(utf-8-validate@5.0.10))(react-native@0.72.14(@babel/core@7.24.5)(@babel/preset-env@7.24.5(@babel/core@7.24.5))(bufferutil@4.0.8)(react@19.0.0)(utf-8-validate@5.0.10))': + '@solana-mobile/mobile-wallet-adapter-protocol-web3js@2.0.2(@solana/web3.js@1.95.5(bufferutil@4.0.8)(utf-8-validate@5.0.10))(react-native@0.72.14(@babel/core@7.24.5)(@babel/preset-env@7.24.5(@babel/core@7.24.5))(bufferutil@4.0.8)(react@19.0.0)(utf-8-validate@5.0.10))': dependencies: '@solana-mobile/mobile-wallet-adapter-protocol': 2.0.1(react-native@0.72.14(@babel/core@7.24.5)(@babel/preset-env@7.24.5(@babel/core@7.24.5))(bufferutil@4.0.8)(react@19.0.0)(utf-8-validate@5.0.10)) - '@solana/web3.js': 1.95.3(bufferutil@4.0.8)(utf-8-validate@5.0.10) + '@solana/web3.js': 1.95.5(bufferutil@4.0.8)(utf-8-validate@5.0.10) bs58: 5.0.0 js-base64: 3.7.5 transitivePeerDependencies: @@ -10868,12 +10920,12 @@ snapshots: dependencies: react-native: 0.72.14(@babel/core@7.24.5)(@babel/preset-env@7.24.5(@babel/core@7.24.5))(bufferutil@4.0.8)(react@19.0.0)(utf-8-validate@5.0.10) - '@solana-mobile/wallet-adapter-mobile@2.0.1(@solana/web3.js@1.95.3(bufferutil@4.0.8)(utf-8-validate@5.0.10))(react-native@0.72.14(@babel/core@7.24.5)(@babel/preset-env@7.24.5(@babel/core@7.24.5))(bufferutil@4.0.8)(react@19.0.0)(utf-8-validate@5.0.10))': + '@solana-mobile/wallet-adapter-mobile@2.0.1(@solana/web3.js@1.95.5(bufferutil@4.0.8)(utf-8-validate@5.0.10))(react-native@0.72.14(@babel/core@7.24.5)(@babel/preset-env@7.24.5(@babel/core@7.24.5))(bufferutil@4.0.8)(react@19.0.0)(utf-8-validate@5.0.10))': dependencies: '@react-native-async-storage/async-storage': 1.19.5(react-native@0.72.14(@babel/core@7.24.5)(@babel/preset-env@7.24.5(@babel/core@7.24.5))(bufferutil@4.0.8)(react@19.0.0)(utf-8-validate@5.0.10)) - '@solana-mobile/mobile-wallet-adapter-protocol-web3js': 2.0.2(@solana/web3.js@1.95.3(bufferutil@4.0.8)(utf-8-validate@5.0.10))(react-native@0.72.14(@babel/core@7.24.5)(@babel/preset-env@7.24.5(@babel/core@7.24.5))(bufferutil@4.0.8)(react@19.0.0)(utf-8-validate@5.0.10)) - '@solana/wallet-adapter-base': 0.9.23(@solana/web3.js@1.95.3(bufferutil@4.0.8)(utf-8-validate@5.0.10)) - '@solana/web3.js': 1.95.3(bufferutil@4.0.8)(utf-8-validate@5.0.10) + '@solana-mobile/mobile-wallet-adapter-protocol-web3js': 2.0.2(@solana/web3.js@1.95.5(bufferutil@4.0.8)(utf-8-validate@5.0.10))(react-native@0.72.14(@babel/core@7.24.5)(@babel/preset-env@7.24.5(@babel/core@7.24.5))(bufferutil@4.0.8)(react@19.0.0)(utf-8-validate@5.0.10)) + '@solana/wallet-adapter-base': 0.9.23(@solana/web3.js@1.95.5(bufferutil@4.0.8)(utf-8-validate@5.0.10)) + '@solana/web3.js': 1.95.5(bufferutil@4.0.8)(utf-8-validate@5.0.10) js-base64: 3.7.5 transitivePeerDependencies: - react-native @@ -10881,7 +10933,7 @@ snapshots: '@solana/buffer-layout-utils@0.2.0(bufferutil@4.0.8)(utf-8-validate@5.0.10)': dependencies: '@solana/buffer-layout': 4.0.1 - '@solana/web3.js': 1.95.3(bufferutil@4.0.8)(utf-8-validate@5.0.10) + '@solana/web3.js': 1.98.0(bufferutil@4.0.8)(utf-8-validate@5.0.10) bigint-buffer: 1.1.5 bignumber.js: 9.1.2 transitivePeerDependencies: @@ -11023,16 +11075,16 @@ snapshots: transitivePeerDependencies: - fastestsmallesttextencoderdecoder - '@solana/spl-token-group@0.0.5(@solana/web3.js@1.95.3(bufferutil@4.0.8)(utf-8-validate@5.0.10))(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.6.2)': + '@solana/spl-token-group@0.0.5(@solana/web3.js@1.98.0(bufferutil@4.0.8)(utf-8-validate@5.0.10))(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.6.2)': dependencies: '@solana/codecs': 2.0.0-preview.4(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.6.2) '@solana/spl-type-length-value': 0.1.0 - '@solana/web3.js': 1.95.3(bufferutil@4.0.8)(utf-8-validate@5.0.10) + '@solana/web3.js': 1.98.0(bufferutil@4.0.8)(utf-8-validate@5.0.10) transitivePeerDependencies: - fastestsmallesttextencoderdecoder - typescript - '@solana/spl-token-metadata@0.1.2(@solana/web3.js@1.95.3(bufferutil@4.0.8)(utf-8-validate@5.0.10))(fastestsmallesttextencoderdecoder@1.0.22)': + '@solana/spl-token-metadata@0.1.2(@solana/web3.js@1.95.5(bufferutil@4.0.8)(utf-8-validate@5.0.10))(fastestsmallesttextencoderdecoder@1.0.22)': dependencies: '@solana/codecs-core': 2.0.0-experimental.8618508 '@solana/codecs-data-structures': 2.0.0-experimental.8618508 @@ -11040,25 +11092,25 @@ snapshots: '@solana/codecs-strings': 2.0.0-experimental.8618508(fastestsmallesttextencoderdecoder@1.0.22) '@solana/options': 2.0.0-experimental.8618508 '@solana/spl-type-length-value': 0.1.0 - '@solana/web3.js': 1.95.3(bufferutil@4.0.8)(utf-8-validate@5.0.10) + '@solana/web3.js': 1.95.5(bufferutil@4.0.8)(utf-8-validate@5.0.10) transitivePeerDependencies: - fastestsmallesttextencoderdecoder - '@solana/spl-token-metadata@0.1.5(@solana/web3.js@1.95.3(bufferutil@4.0.8)(utf-8-validate@5.0.10))(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.6.2)': + '@solana/spl-token-metadata@0.1.5(@solana/web3.js@1.98.0(bufferutil@4.0.8)(utf-8-validate@5.0.10))(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.6.2)': dependencies: '@solana/codecs': 2.0.0-rc.1(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.6.2) '@solana/spl-type-length-value': 0.1.0 - '@solana/web3.js': 1.95.3(bufferutil@4.0.8)(utf-8-validate@5.0.10) + '@solana/web3.js': 1.98.0(bufferutil@4.0.8)(utf-8-validate@5.0.10) transitivePeerDependencies: - fastestsmallesttextencoderdecoder - typescript - '@solana/spl-token@0.3.11(@solana/web3.js@1.95.3(bufferutil@4.0.8)(utf-8-validate@5.0.10))(bufferutil@4.0.8)(fastestsmallesttextencoderdecoder@1.0.22)(utf-8-validate@5.0.10)': + '@solana/spl-token@0.3.11(@solana/web3.js@1.95.5(bufferutil@4.0.8)(utf-8-validate@5.0.10))(bufferutil@4.0.8)(fastestsmallesttextencoderdecoder@1.0.22)(utf-8-validate@5.0.10)': dependencies: '@solana/buffer-layout': 4.0.1 '@solana/buffer-layout-utils': 0.2.0(bufferutil@4.0.8)(utf-8-validate@5.0.10) - '@solana/spl-token-metadata': 0.1.2(@solana/web3.js@1.95.3(bufferutil@4.0.8)(utf-8-validate@5.0.10))(fastestsmallesttextencoderdecoder@1.0.22) - '@solana/web3.js': 1.95.3(bufferutil@4.0.8)(utf-8-validate@5.0.10) + '@solana/spl-token-metadata': 0.1.2(@solana/web3.js@1.95.5(bufferutil@4.0.8)(utf-8-validate@5.0.10))(fastestsmallesttextencoderdecoder@1.0.22) + '@solana/web3.js': 1.95.5(bufferutil@4.0.8)(utf-8-validate@5.0.10) buffer: 6.0.3 transitivePeerDependencies: - bufferutil @@ -11066,13 +11118,13 @@ snapshots: - fastestsmallesttextencoderdecoder - utf-8-validate - '@solana/spl-token@0.4.8(@solana/web3.js@1.95.3(bufferutil@4.0.8)(utf-8-validate@5.0.10))(bufferutil@4.0.8)(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.6.2)(utf-8-validate@5.0.10)': + '@solana/spl-token@0.4.8(@solana/web3.js@1.98.0(bufferutil@4.0.8)(utf-8-validate@5.0.10))(bufferutil@4.0.8)(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.6.2)(utf-8-validate@5.0.10)': dependencies: '@solana/buffer-layout': 4.0.1 '@solana/buffer-layout-utils': 0.2.0(bufferutil@4.0.8)(utf-8-validate@5.0.10) - '@solana/spl-token-group': 0.0.5(@solana/web3.js@1.95.3(bufferutil@4.0.8)(utf-8-validate@5.0.10))(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.6.2) - '@solana/spl-token-metadata': 0.1.5(@solana/web3.js@1.95.3(bufferutil@4.0.8)(utf-8-validate@5.0.10))(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.6.2) - '@solana/web3.js': 1.95.3(bufferutil@4.0.8)(utf-8-validate@5.0.10) + '@solana/spl-token-group': 0.0.5(@solana/web3.js@1.98.0(bufferutil@4.0.8)(utf-8-validate@5.0.10))(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.6.2) + '@solana/spl-token-metadata': 0.1.5(@solana/web3.js@1.98.0(bufferutil@4.0.8)(utf-8-validate@5.0.10))(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.6.2) + '@solana/web3.js': 1.98.0(bufferutil@4.0.8)(utf-8-validate@5.0.10) buffer: 6.0.3 transitivePeerDependencies: - bufferutil @@ -11085,53 +11137,53 @@ snapshots: dependencies: buffer: 6.0.3 - '@solana/wallet-adapter-base-ui@0.1.2(@solana/web3.js@1.95.3(bufferutil@4.0.8)(utf-8-validate@5.0.10))(bs58@6.0.0)(react-native@0.72.14(@babel/core@7.24.5)(@babel/preset-env@7.24.5(@babel/core@7.24.5))(bufferutil@4.0.8)(react@19.0.0)(utf-8-validate@5.0.10))(react@19.0.0)': + '@solana/wallet-adapter-base-ui@0.1.2(@solana/web3.js@1.95.5(bufferutil@4.0.8)(utf-8-validate@5.0.10))(bs58@6.0.0)(react-native@0.72.14(@babel/core@7.24.5)(@babel/preset-env@7.24.5(@babel/core@7.24.5))(bufferutil@4.0.8)(react@19.0.0)(utf-8-validate@5.0.10))(react@19.0.0)': dependencies: - '@solana/wallet-adapter-react': 0.15.35(@solana/web3.js@1.95.3(bufferutil@4.0.8)(utf-8-validate@5.0.10))(bs58@6.0.0)(react-native@0.72.14(@babel/core@7.24.5)(@babel/preset-env@7.24.5(@babel/core@7.24.5))(bufferutil@4.0.8)(react@19.0.0)(utf-8-validate@5.0.10))(react@19.0.0) - '@solana/web3.js': 1.95.3(bufferutil@4.0.8)(utf-8-validate@5.0.10) + '@solana/wallet-adapter-react': 0.15.35(@solana/web3.js@1.95.5(bufferutil@4.0.8)(utf-8-validate@5.0.10))(bs58@6.0.0)(react-native@0.72.14(@babel/core@7.24.5)(@babel/preset-env@7.24.5(@babel/core@7.24.5))(bufferutil@4.0.8)(react@19.0.0)(utf-8-validate@5.0.10))(react@19.0.0) + '@solana/web3.js': 1.95.5(bufferutil@4.0.8)(utf-8-validate@5.0.10) react: 19.0.0 transitivePeerDependencies: - bs58 - react-native - '@solana/wallet-adapter-base@0.9.23(@solana/web3.js@1.95.3(bufferutil@4.0.8)(utf-8-validate@5.0.10))': + '@solana/wallet-adapter-base@0.9.23(@solana/web3.js@1.95.5(bufferutil@4.0.8)(utf-8-validate@5.0.10))': dependencies: '@solana/wallet-standard-features': 1.1.0 - '@solana/web3.js': 1.95.3(bufferutil@4.0.8)(utf-8-validate@5.0.10) + '@solana/web3.js': 1.95.5(bufferutil@4.0.8)(utf-8-validate@5.0.10) '@wallet-standard/base': 1.0.1 '@wallet-standard/features': 1.0.3 eventemitter3: 4.0.7 - '@solana/wallet-adapter-react-ui@0.9.35(@solana/web3.js@1.95.3(bufferutil@4.0.8)(utf-8-validate@5.0.10))(bs58@6.0.0)(react-dom@19.0.0(react@19.0.0))(react-native@0.72.14(@babel/core@7.24.5)(@babel/preset-env@7.24.5(@babel/core@7.24.5))(bufferutil@4.0.8)(react@19.0.0)(utf-8-validate@5.0.10))(react@19.0.0)': + '@solana/wallet-adapter-react-ui@0.9.35(@solana/web3.js@1.95.5(bufferutil@4.0.8)(utf-8-validate@5.0.10))(bs58@6.0.0)(react-dom@19.0.0(react@19.0.0))(react-native@0.72.14(@babel/core@7.24.5)(@babel/preset-env@7.24.5(@babel/core@7.24.5))(bufferutil@4.0.8)(react@19.0.0)(utf-8-validate@5.0.10))(react@19.0.0)': dependencies: - '@solana/wallet-adapter-base': 0.9.23(@solana/web3.js@1.95.3(bufferutil@4.0.8)(utf-8-validate@5.0.10)) - '@solana/wallet-adapter-base-ui': 0.1.2(@solana/web3.js@1.95.3(bufferutil@4.0.8)(utf-8-validate@5.0.10))(bs58@6.0.0)(react-native@0.72.14(@babel/core@7.24.5)(@babel/preset-env@7.24.5(@babel/core@7.24.5))(bufferutil@4.0.8)(react@19.0.0)(utf-8-validate@5.0.10))(react@19.0.0) - '@solana/wallet-adapter-react': 0.15.35(@solana/web3.js@1.95.3(bufferutil@4.0.8)(utf-8-validate@5.0.10))(bs58@6.0.0)(react-native@0.72.14(@babel/core@7.24.5)(@babel/preset-env@7.24.5(@babel/core@7.24.5))(bufferutil@4.0.8)(react@19.0.0)(utf-8-validate@5.0.10))(react@19.0.0) - '@solana/web3.js': 1.95.3(bufferutil@4.0.8)(utf-8-validate@5.0.10) + '@solana/wallet-adapter-base': 0.9.23(@solana/web3.js@1.95.5(bufferutil@4.0.8)(utf-8-validate@5.0.10)) + '@solana/wallet-adapter-base-ui': 0.1.2(@solana/web3.js@1.95.5(bufferutil@4.0.8)(utf-8-validate@5.0.10))(bs58@6.0.0)(react-native@0.72.14(@babel/core@7.24.5)(@babel/preset-env@7.24.5(@babel/core@7.24.5))(bufferutil@4.0.8)(react@19.0.0)(utf-8-validate@5.0.10))(react@19.0.0) + '@solana/wallet-adapter-react': 0.15.35(@solana/web3.js@1.95.5(bufferutil@4.0.8)(utf-8-validate@5.0.10))(bs58@6.0.0)(react-native@0.72.14(@babel/core@7.24.5)(@babel/preset-env@7.24.5(@babel/core@7.24.5))(bufferutil@4.0.8)(react@19.0.0)(utf-8-validate@5.0.10))(react@19.0.0) + '@solana/web3.js': 1.95.5(bufferutil@4.0.8)(utf-8-validate@5.0.10) react: 19.0.0 react-dom: 19.0.0(react@19.0.0) transitivePeerDependencies: - bs58 - react-native - '@solana/wallet-adapter-react@0.15.35(@solana/web3.js@1.95.3(bufferutil@4.0.8)(utf-8-validate@5.0.10))(bs58@6.0.0)(react-native@0.72.14(@babel/core@7.24.5)(@babel/preset-env@7.24.5(@babel/core@7.24.5))(bufferutil@4.0.8)(react@19.0.0)(utf-8-validate@5.0.10))(react@19.0.0)': + '@solana/wallet-adapter-react@0.15.35(@solana/web3.js@1.95.5(bufferutil@4.0.8)(utf-8-validate@5.0.10))(bs58@6.0.0)(react-native@0.72.14(@babel/core@7.24.5)(@babel/preset-env@7.24.5(@babel/core@7.24.5))(bufferutil@4.0.8)(react@19.0.0)(utf-8-validate@5.0.10))(react@19.0.0)': dependencies: - '@solana-mobile/wallet-adapter-mobile': 2.0.1(@solana/web3.js@1.95.3(bufferutil@4.0.8)(utf-8-validate@5.0.10))(react-native@0.72.14(@babel/core@7.24.5)(@babel/preset-env@7.24.5(@babel/core@7.24.5))(bufferutil@4.0.8)(react@19.0.0)(utf-8-validate@5.0.10)) - '@solana/wallet-adapter-base': 0.9.23(@solana/web3.js@1.95.3(bufferutil@4.0.8)(utf-8-validate@5.0.10)) - '@solana/wallet-standard-wallet-adapter-react': 1.1.1(@solana/wallet-adapter-base@0.9.23(@solana/web3.js@1.95.3(bufferutil@4.0.8)(utf-8-validate@5.0.10)))(@solana/web3.js@1.95.3(bufferutil@4.0.8)(utf-8-validate@5.0.10))(bs58@6.0.0)(react@19.0.0) - '@solana/web3.js': 1.95.3(bufferutil@4.0.8)(utf-8-validate@5.0.10) + '@solana-mobile/wallet-adapter-mobile': 2.0.1(@solana/web3.js@1.95.5(bufferutil@4.0.8)(utf-8-validate@5.0.10))(react-native@0.72.14(@babel/core@7.24.5)(@babel/preset-env@7.24.5(@babel/core@7.24.5))(bufferutil@4.0.8)(react@19.0.0)(utf-8-validate@5.0.10)) + '@solana/wallet-adapter-base': 0.9.23(@solana/web3.js@1.95.5(bufferutil@4.0.8)(utf-8-validate@5.0.10)) + '@solana/wallet-standard-wallet-adapter-react': 1.1.1(@solana/wallet-adapter-base@0.9.23(@solana/web3.js@1.95.5(bufferutil@4.0.8)(utf-8-validate@5.0.10)))(@solana/web3.js@1.95.5(bufferutil@4.0.8)(utf-8-validate@5.0.10))(bs58@6.0.0)(react@19.0.0) + '@solana/web3.js': 1.95.5(bufferutil@4.0.8)(utf-8-validate@5.0.10) react: 19.0.0 transitivePeerDependencies: - bs58 - react-native - '@solana/wallet-adapter-unsafe-burner@0.1.7(@solana/web3.js@1.95.3(bufferutil@4.0.8)(utf-8-validate@5.0.10))': + '@solana/wallet-adapter-unsafe-burner@0.1.7(@solana/web3.js@1.95.5(bufferutil@4.0.8)(utf-8-validate@5.0.10))': dependencies: '@noble/curves': 1.4.0 - '@solana/wallet-adapter-base': 0.9.23(@solana/web3.js@1.95.3(bufferutil@4.0.8)(utf-8-validate@5.0.10)) + '@solana/wallet-adapter-base': 0.9.23(@solana/web3.js@1.95.5(bufferutil@4.0.8)(utf-8-validate@5.0.10)) '@solana/wallet-standard-features': 1.1.0 '@solana/wallet-standard-util': 1.1.0 - '@solana/web3.js': 1.95.3(bufferutil@4.0.8)(utf-8-validate@5.0.10) + '@solana/web3.js': 1.95.5(bufferutil@4.0.8)(utf-8-validate@5.0.10) '@solana/wallet-standard-chains@1.1.0': dependencies: @@ -11148,23 +11200,23 @@ snapshots: '@solana/wallet-standard-chains': 1.1.0 '@solana/wallet-standard-features': 1.1.0 - '@solana/wallet-standard-wallet-adapter-base@1.1.1(@solana/web3.js@1.95.3(bufferutil@4.0.8)(utf-8-validate@5.0.10))(bs58@6.0.0)': + '@solana/wallet-standard-wallet-adapter-base@1.1.1(@solana/web3.js@1.95.5(bufferutil@4.0.8)(utf-8-validate@5.0.10))(bs58@6.0.0)': dependencies: - '@solana/wallet-adapter-base': 0.9.23(@solana/web3.js@1.95.3(bufferutil@4.0.8)(utf-8-validate@5.0.10)) + '@solana/wallet-adapter-base': 0.9.23(@solana/web3.js@1.95.5(bufferutil@4.0.8)(utf-8-validate@5.0.10)) '@solana/wallet-standard-chains': 1.1.0 '@solana/wallet-standard-features': 1.1.0 '@solana/wallet-standard-util': 1.1.0 - '@solana/web3.js': 1.95.3(bufferutil@4.0.8)(utf-8-validate@5.0.10) + '@solana/web3.js': 1.95.5(bufferutil@4.0.8)(utf-8-validate@5.0.10) '@wallet-standard/app': 1.0.1 '@wallet-standard/base': 1.0.1 '@wallet-standard/features': 1.0.3 '@wallet-standard/wallet': 1.0.1 bs58: 6.0.0 - '@solana/wallet-standard-wallet-adapter-react@1.1.1(@solana/wallet-adapter-base@0.9.23(@solana/web3.js@1.95.3(bufferutil@4.0.8)(utf-8-validate@5.0.10)))(@solana/web3.js@1.95.3(bufferutil@4.0.8)(utf-8-validate@5.0.10))(bs58@6.0.0)(react@19.0.0)': + '@solana/wallet-standard-wallet-adapter-react@1.1.1(@solana/wallet-adapter-base@0.9.23(@solana/web3.js@1.95.5(bufferutil@4.0.8)(utf-8-validate@5.0.10)))(@solana/web3.js@1.95.5(bufferutil@4.0.8)(utf-8-validate@5.0.10))(bs58@6.0.0)(react@19.0.0)': dependencies: - '@solana/wallet-adapter-base': 0.9.23(@solana/web3.js@1.95.3(bufferutil@4.0.8)(utf-8-validate@5.0.10)) - '@solana/wallet-standard-wallet-adapter-base': 1.1.1(@solana/web3.js@1.95.3(bufferutil@4.0.8)(utf-8-validate@5.0.10))(bs58@6.0.0) + '@solana/wallet-adapter-base': 0.9.23(@solana/web3.js@1.95.5(bufferutil@4.0.8)(utf-8-validate@5.0.10)) + '@solana/wallet-standard-wallet-adapter-base': 1.1.1(@solana/web3.js@1.95.5(bufferutil@4.0.8)(utf-8-validate@5.0.10))(bs58@6.0.0) '@wallet-standard/app': 1.0.1 '@wallet-standard/base': 1.0.1 react: 19.0.0 @@ -11172,7 +11224,7 @@ snapshots: - '@solana/web3.js' - bs58 - '@solana/web3.js@1.95.3(bufferutil@4.0.8)(utf-8-validate@5.0.10)': + '@solana/web3.js@1.95.5(bufferutil@4.0.8)(utf-8-validate@5.0.10)': dependencies: '@babel/runtime': 7.25.6 '@noble/curves': 1.4.2 @@ -11194,11 +11246,29 @@ snapshots: - encoding - utf-8-validate - '@swc/counter@0.1.3': {} - - '@swc/helpers@0.5.11': + '@solana/web3.js@1.98.0(bufferutil@4.0.8)(utf-8-validate@5.0.10)': dependencies: - tslib: 2.7.0 + '@babel/runtime': 7.25.6 + '@noble/curves': 1.4.2 + '@noble/hashes': 1.5.0 + '@solana/buffer-layout': 4.0.1 + agentkeepalive: 4.5.0 + bigint-buffer: 1.1.5 + bn.js: 5.2.1 + borsh: 0.7.0 + bs58: 4.0.1 + buffer: 6.0.3 + fast-stable-stringify: 1.0.0 + jayson: 4.1.2(bufferutil@4.0.8)(utf-8-validate@5.0.10) + node-fetch: 2.7.0 + rpc-websockets: 9.0.2 + superstruct: 2.0.2 + transitivePeerDependencies: + - bufferutil + - encoding + - utf-8-validate + + '@swc/counter@0.1.3': {} '@swc/helpers@0.5.13': dependencies: @@ -12360,6 +12430,8 @@ snapshots: camelcase@6.3.0: {} + camelcase@8.0.0: {} + caniuse-lite@1.0.30001617: {} capital-case@1.0.4: @@ -16278,7 +16350,7 @@ snapshots: rpc-websockets@9.0.2: dependencies: - '@swc/helpers': 0.5.11 + '@swc/helpers': 0.5.13 '@types/uuid': 8.3.4 '@types/ws': 8.5.10 buffer: 6.0.3 diff --git a/programs/package.json b/programs/package.json index dbd3c18f70..bd54cfd7fb 100644 --- a/programs/package.json +++ b/programs/package.json @@ -3,9 +3,7 @@ "version": "0.3.0", "license": "Apache-2.0", "scripts": { - "push-idls": "../scripts/push-stateless-js-idls.sh && ../scripts/push-compressed-token-idl.sh", "build": "anchor build", - "build-idls": "anchor build && pnpm build-system && pnpm build-compressed-token && pnpm push-idls", "build-system": "anchor build --program-name light_system_program -- --features idl-build custom-heap", "build-compressed-token": "anchor build --program-name light_compressed_token -- --features idl-build custom-heap", "test": "pnpm test-account-compression && pnpm test-system && pnpm test-compressed-token && pnpm test-registry", diff --git a/scripts/bump-versions-and-publish-npm.sh b/scripts/bump-versions-and-publish-npm.sh index b84a3b7db9..a0a622e962 100755 --- a/scripts/bump-versions-and-publish-npm.sh +++ b/scripts/bump-versions-and-publish-npm.sh @@ -1,4 +1,8 @@ #!/usr/bin/env bash +# Examples: +# ./scripts/bump-versions-and-publish-npm.sh minor +# ./scripts/bump-versions-and-publish-npm.sh patch @lightprotocol/stateless.js @lightprotocol/compressed-token +# ./scripts/bump-versions-and-publish-npm.sh alpha @lightprotocol/stateless.js cd "$(git rev-parse --show-toplevel)" @@ -32,9 +36,16 @@ publish_package() { find "cli/bin" -type f -exec chmod +x {} + sleep 5 - if ! (cd "${package_dir}" && pnpm version "${version_type}" && pnpm publish --access public --no-git-checks); then - echo "Error occurred while publishing ${package_name}." - return 1 + if [ "$version_type" == "alpha" ]; then + if ! (cd "${package_dir}" && pnpm version prerelease --preid alpha && pnpm publish --tag alpha --access private --no-git-checks); then + echo "Error occurred while publishing ${package_name}." + return 1 + fi + else + if ! (cd "${package_dir}" && pnpm version "${version_type}" && pnpm publish --access public --no-git-checks); then + echo "Error occurred while publishing ${package_name}." + return 1 + fi fi } @@ -46,9 +57,16 @@ error_occurred=0 if [ "$#" -eq 0 ]; then echo "Bumping ${version_type} version for all packages..." - if ! pnpm -r exec -- pnpm version "${version_type}" || ! pnpm -r exec -- pnpm publish --access public; then - echo "Error occurred during bulk version bump and publish." - error_occurred=1 + if [ "$version_type" == "alpha" ]; then + if ! pnpm -r exec -- pnpm version prerelease --preid alpha || ! pnpm -r exec -- pnpm publish --tag alpha --access private; then + echo "Error occurred during bulk version bump and publish." + error_occurred=1 + fi + else + if ! pnpm -r exec -- pnpm version "${version_type}" || ! pnpm -r exec -- pnpm publish --access public; then + echo "Error occurred during bulk version bump and publish." + error_occurred=1 + fi fi else # If specific packages are provided, bump version for those packages From eadcc4051a2edddab448a6ded610600e37d39e10 Mon Sep 17 00:00:00 2001 From: Swenschaeferjohann Date: Sat, 4 Jan 2025 20:51:33 +0000 Subject: [PATCH 02/19] wip --- cli/package.json | 2 +- examples/browser/nextjs/package.json | 2 +- examples/node/esm/package.json | 2 +- js/stateless.js/package.json | 2 +- js/stateless.js/rollup.config.js | 28 +--- pnpm-lock.yaml | 192 ++++++++++----------------- 6 files changed, 73 insertions(+), 155 deletions(-) diff --git a/cli/package.json b/cli/package.json index 19350a2edb..b13ea97860 100644 --- a/cli/package.json +++ b/cli/package.json @@ -42,7 +42,7 @@ "@oclif/plugin-not-found": "^3.1.2", "@oclif/plugin-plugins": "^5.0.7", "@solana-developers/helpers": "^1.5.1", - "@solana/web3.js": "1.95.5", + "@solana/web3.js": "1.98.0", "axios": "^1.6.8", "case-anything": "^2.1.13", "cli-progress": "^3.12.0", diff --git a/examples/browser/nextjs/package.json b/examples/browser/nextjs/package.json index 734a618b73..c8a55afd72 100644 --- a/examples/browser/nextjs/package.json +++ b/examples/browser/nextjs/package.json @@ -19,7 +19,7 @@ "@solana/wallet-adapter-react": "^0.15.35", "@solana/wallet-adapter-react-ui": "^0.9.35", "@solana/wallet-adapter-unsafe-burner": "^0.1.7", - "@solana/web3.js": "^1.95.5", + "@solana/web3.js": "1.98.0", "next": "15.0.4", "react": "^19", "react-dom": "^19" diff --git a/examples/node/esm/package.json b/examples/node/esm/package.json index 700c76d8d5..0ea2c56039 100644 --- a/examples/node/esm/package.json +++ b/examples/node/esm/package.json @@ -18,7 +18,7 @@ }, "dependencies": { "@coral-xyz/anchor": "^0.30.0", - "@solana/web3.js": "^1.95.5", + "@solana/web3.js": "1.98.0", "@lightprotocol/stateless.js": "workspace:*" } } diff --git a/js/stateless.js/package.json b/js/stateless.js/package.json index 42a4a1954e..a1feae8fa2 100644 --- a/js/stateless.js/package.json +++ b/js/stateless.js/package.json @@ -9,7 +9,7 @@ ".": { "require": "./dist/cjs/node/index.cjs", "types": "./dist/types/index.d.ts", - "import": "./dist/es/browser/index.js" + "default": "./dist/cjs/node/index.cjs" }, "./browser": { "import": "./dist/es/browser/index.js", diff --git a/js/stateless.js/rollup.config.js b/js/stateless.js/rollup.config.js index 8a3f386e8d..f4336924bc 100644 --- a/js/stateless.js/rollup.config.js +++ b/js/stateless.js/rollup.config.js @@ -3,8 +3,8 @@ import nodePolyfills from 'rollup-plugin-polyfill-node'; import dts from 'rollup-plugin-dts'; import resolve from '@rollup/plugin-node-resolve'; import commonjs from '@rollup/plugin-commonjs'; -import terser from '@rollup/plugin-terser'; +import json from '@rollup/plugin-json'; const rolls = (fmt, env) => ({ input: 'src/index.ts', output: { @@ -15,11 +15,6 @@ const rolls = (fmt, env) => ({ }, external: [ '@solana/web3.js', - // '@coral-xyz/borsh', - // '@noble/hashes', - 'buffer', - 'superstruct', - 'buffer-layout', ], plugins: [ typescript({ @@ -33,26 +28,7 @@ const rolls = (fmt, env) => ({ preferBuiltins: env === 'node', }), env === 'browser' ? nodePolyfills() : undefined, - terser({ - compress: { - drop_console: true, - drop_debugger: true, - passes: 3, - pure_funcs: ['console.log', 'console.error', 'console.warn'], - booleans_as_integers: true, - keep_fargs: false, - keep_fnames: false, - keep_infinity: true, - reduce_funcs: true, - reduce_vars: true, - }, - mangle: { - toplevel: true, - }, - output: { - comments: false, - }, - }), + json(), ].filter(Boolean), onwarn(warning, warn) { if (warning.code !== 'CIRCULAR_DEPENDENCY') { diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 06eee5c34f..ad1884fc4e 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -63,8 +63,8 @@ importers: specifier: ^1.5.1 version: 1.5.1(bufferutil@4.0.8)(utf-8-validate@5.0.10) '@solana/web3.js': - specifier: 1.95.5 - version: 1.95.5(bufferutil@4.0.8)(utf-8-validate@5.0.10) + specifier: 1.98.0 + version: 1.98.0(bufferutil@4.0.8)(utf-8-validate@5.0.10) axios: specifier: ^1.6.8 version: 1.6.8 @@ -113,7 +113,7 @@ importers: version: 2.3.9(@types/node@20.12.11)(typescript@5.5.3) '@solana/spl-token': specifier: ^0.3.11 - version: 0.3.11(@solana/web3.js@1.95.5(bufferutil@4.0.8)(utf-8-validate@5.0.10))(bufferutil@4.0.8)(fastestsmallesttextencoderdecoder@1.0.22)(utf-8-validate@5.0.10) + version: 0.3.11(@solana/web3.js@1.98.0(bufferutil@4.0.8)(utf-8-validate@5.0.10))(bufferutil@4.0.8)(fastestsmallesttextencoderdecoder@1.0.22)(utf-8-validate@5.0.10) '@types/bn.js': specifier: ^5.1.5 version: 5.1.5 @@ -194,19 +194,19 @@ importers: version: link:../../../js/stateless.js '@solana/wallet-adapter-base': specifier: ^0.9.23 - version: 0.9.23(@solana/web3.js@1.95.5(bufferutil@4.0.8)(utf-8-validate@5.0.10)) + version: 0.9.23(@solana/web3.js@1.98.0(bufferutil@4.0.8)(utf-8-validate@5.0.10)) '@solana/wallet-adapter-react': specifier: ^0.15.35 - version: 0.15.35(@solana/web3.js@1.95.5(bufferutil@4.0.8)(utf-8-validate@5.0.10))(bs58@6.0.0)(react-native@0.72.14(@babel/core@7.24.5)(@babel/preset-env@7.24.5(@babel/core@7.24.5))(bufferutil@4.0.8)(react@19.0.0)(utf-8-validate@5.0.10))(react@19.0.0) + version: 0.15.35(@solana/web3.js@1.98.0(bufferutil@4.0.8)(utf-8-validate@5.0.10))(bs58@6.0.0)(react-native@0.72.14(@babel/core@7.24.5)(@babel/preset-env@7.24.5(@babel/core@7.24.5))(bufferutil@4.0.8)(react@19.0.0)(utf-8-validate@5.0.10))(react@19.0.0) '@solana/wallet-adapter-react-ui': specifier: ^0.9.35 - version: 0.9.35(@solana/web3.js@1.95.5(bufferutil@4.0.8)(utf-8-validate@5.0.10))(bs58@6.0.0)(react-dom@19.0.0(react@19.0.0))(react-native@0.72.14(@babel/core@7.24.5)(@babel/preset-env@7.24.5(@babel/core@7.24.5))(bufferutil@4.0.8)(react@19.0.0)(utf-8-validate@5.0.10))(react@19.0.0) + version: 0.9.35(@solana/web3.js@1.98.0(bufferutil@4.0.8)(utf-8-validate@5.0.10))(bs58@6.0.0)(react-dom@19.0.0(react@19.0.0))(react-native@0.72.14(@babel/core@7.24.5)(@babel/preset-env@7.24.5(@babel/core@7.24.5))(bufferutil@4.0.8)(react@19.0.0)(utf-8-validate@5.0.10))(react@19.0.0) '@solana/wallet-adapter-unsafe-burner': specifier: ^0.1.7 - version: 0.1.7(@solana/web3.js@1.95.5(bufferutil@4.0.8)(utf-8-validate@5.0.10)) + version: 0.1.7(@solana/web3.js@1.98.0(bufferutil@4.0.8)(utf-8-validate@5.0.10)) '@solana/web3.js': - specifier: ^1.95.5 - version: 1.95.5(bufferutil@4.0.8)(utf-8-validate@5.0.10) + specifier: 1.98.0 + version: 1.98.0(bufferutil@4.0.8)(utf-8-validate@5.0.10) bs58: specifier: ^6.0.0 version: 6.0.0 @@ -243,7 +243,7 @@ importers: dependencies: '@coral-xyz/anchor': specifier: ^0.29.0 - version: 0.29.0 + version: 0.29.0(bufferutil@4.0.8)(utf-8-validate@5.0.10) devDependencies: '@lightprotocol/zk-compression-cli': specifier: workspace:* @@ -282,8 +282,8 @@ importers: specifier: workspace:* version: link:../../../js/stateless.js '@solana/web3.js': - specifier: ^1.95.5 - version: 1.95.5(bufferutil@4.0.8)(utf-8-validate@5.0.10) + specifier: 1.98.0 + version: 1.98.0(bufferutil@4.0.8)(utf-8-validate@5.0.10) devDependencies: '@types/node': specifier: ^22.10.2 @@ -296,7 +296,7 @@ importers: dependencies: '@coral-xyz/anchor': specifier: 0.29.0 - version: 0.29.0 + version: 0.29.0(bufferutil@4.0.8)(utf-8-validate@5.0.10) devDependencies: '@types/bn.js': specifier: ^5.1.6 @@ -333,7 +333,7 @@ importers: dependencies: '@coral-xyz/borsh': specifier: ^0.29.0 - version: 0.29.0(@solana/web3.js@1.98.0(bufferutil@4.0.8)(utf-8-validate@5.0.10)) + version: 0.29.0(@solana/web3.js@1.98.0) '@lightprotocol/stateless.js': specifier: workspace:* version: link:../stateless.js @@ -454,7 +454,7 @@ importers: dependencies: '@coral-xyz/borsh': specifier: ^0.29.0 - version: 0.29.0(@solana/web3.js@1.98.0(bufferutil@4.0.8)(utf-8-validate@5.0.10)) + version: 0.29.0(@solana/web3.js@1.98.0) '@noble/hashes': specifier: 1.5.0 version: 1.5.0 @@ -574,15 +574,13 @@ importers: specifier: ^2.1.1 version: 2.1.1(@types/node@22.5.5)(terser@5.31.0) - programs: {} - program-tests: {} program-tests/sdk-test-program: dependencies: '@coral-xyz/anchor': specifier: ^0.29.0 - version: 0.29.0 + version: 0.29.0(bufferutil@4.0.8)(utf-8-validate@5.0.10) devDependencies: '@lightprotocol/zk-compression-cli': specifier: workspace:* @@ -612,6 +610,8 @@ importers: specifier: ^5.7.2 version: 5.7.2 + programs: {} + tsconfig: {} packages: @@ -2991,9 +2991,6 @@ packages: '@solana/wallet-adapter-base': '*' react: '*' - '@solana/web3.js@1.95.5': - resolution: {integrity: sha512-hU9cBrbg1z6gEjLH9vwIckGBVB78Ijm0iZFNk4ocm5OD82piPwuk3MeQ1rfiKD9YQtr95krrcaopb49EmQJlRg==} - '@solana/web3.js@1.98.0': resolution: {integrity: sha512-nz3Q5OeyGFpFCR+erX2f6JPt3sKhzhYcSycBCSPkWjzSVDh/Rr1FqTVMRe58FKO16/ivTUcuJjeS5MyBvpkbzA==} @@ -9444,32 +9441,11 @@ snapshots: '@babel/helper-validator-identifier': 7.24.5 to-fast-properties: 2.0.0 - '@coral-xyz/anchor@0.29.0': - dependencies: - '@coral-xyz/borsh': 0.29.0(@solana/web3.js@1.95.5) - '@noble/hashes': 1.5.0 - '@solana/web3.js': 1.95.5(bufferutil@4.0.8)(utf-8-validate@5.0.10) - bn.js: 5.2.1 - bs58: 4.0.1 - buffer-layout: 1.2.2 - camelcase: 6.3.0 - cross-fetch: 3.1.8 - crypto-hash: 1.3.0 - eventemitter3: 4.0.7 - pako: 2.1.0 - snake-case: 3.0.4 - superstruct: 0.15.5 - toml: 3.0.0 - transitivePeerDependencies: - - bufferutil - - encoding - - utf-8-validate - '@coral-xyz/anchor@0.29.0(bufferutil@4.0.8)(utf-8-validate@5.0.10)': dependencies: - '@coral-xyz/borsh': 0.29.0(@solana/web3.js@1.95.5(bufferutil@4.0.8)(utf-8-validate@5.0.10)) + '@coral-xyz/borsh': 0.29.0(@solana/web3.js@1.98.0) '@noble/hashes': 1.5.0 - '@solana/web3.js': 1.95.5(bufferutil@4.0.8)(utf-8-validate@5.0.10) + '@solana/web3.js': 1.98.0(bufferutil@4.0.8)(utf-8-validate@5.0.10) bn.js: 5.2.1 bs58: 4.0.1 buffer-layout: 1.2.2 @@ -9488,9 +9464,9 @@ snapshots: '@coral-xyz/anchor@0.30.0(bufferutil@4.0.8)(utf-8-validate@5.0.10)': dependencies: - '@coral-xyz/borsh': 0.30.1(@solana/web3.js@1.95.5(bufferutil@4.0.8)(utf-8-validate@5.0.10)) + '@coral-xyz/borsh': 0.30.1(@solana/web3.js@1.98.0(bufferutil@4.0.8)(utf-8-validate@5.0.10)) '@noble/hashes': 1.5.0 - '@solana/web3.js': 1.95.5(bufferutil@4.0.8)(utf-8-validate@5.0.10) + '@solana/web3.js': 1.98.0(bufferutil@4.0.8)(utf-8-validate@5.0.10) bn.js: 5.2.1 bs58: 4.0.1 buffer-layout: 1.2.2 @@ -9507,27 +9483,15 @@ snapshots: - encoding - utf-8-validate - '@coral-xyz/borsh@0.29.0(@solana/web3.js@1.95.5(bufferutil@4.0.8)(utf-8-validate@5.0.10))': - dependencies: - '@solana/web3.js': 1.95.5(bufferutil@4.0.8)(utf-8-validate@5.0.10) - bn.js: 5.2.1 - buffer-layout: 1.2.2 - - '@coral-xyz/borsh@0.29.0(@solana/web3.js@1.95.5)': - dependencies: - '@solana/web3.js': 1.95.5(bufferutil@4.0.8)(utf-8-validate@5.0.10) - bn.js: 5.2.1 - buffer-layout: 1.2.2 - - '@coral-xyz/borsh@0.29.0(@solana/web3.js@1.98.0(bufferutil@4.0.8)(utf-8-validate@5.0.10))': + '@coral-xyz/borsh@0.29.0(@solana/web3.js@1.98.0)': dependencies: '@solana/web3.js': 1.98.0(bufferutil@4.0.8)(utf-8-validate@5.0.10) bn.js: 5.2.1 buffer-layout: 1.2.2 - '@coral-xyz/borsh@0.30.1(@solana/web3.js@1.95.5(bufferutil@4.0.8)(utf-8-validate@5.0.10))': + '@coral-xyz/borsh@0.30.1(@solana/web3.js@1.98.0(bufferutil@4.0.8)(utf-8-validate@5.0.10))': dependencies: - '@solana/web3.js': 1.95.5(bufferutil@4.0.8)(utf-8-validate@5.0.10) + '@solana/web3.js': 1.98.0(bufferutil@4.0.8)(utf-8-validate@5.0.10) bn.js: 5.2.1 buffer-layout: 1.2.2 @@ -10897,7 +10861,7 @@ snapshots: '@solana-developers/helpers@1.5.1(bufferutil@4.0.8)(utf-8-validate@5.0.10)': dependencies: - '@solana/web3.js': 1.95.5(bufferutil@4.0.8)(utf-8-validate@5.0.10) + '@solana/web3.js': 1.98.0(bufferutil@4.0.8)(utf-8-validate@5.0.10) bs58: 5.0.0 dotenv: 16.4.5 prettier: 3.3.3 @@ -10907,10 +10871,10 @@ snapshots: - encoding - utf-8-validate - '@solana-mobile/mobile-wallet-adapter-protocol-web3js@2.0.2(@solana/web3.js@1.95.5(bufferutil@4.0.8)(utf-8-validate@5.0.10))(react-native@0.72.14(@babel/core@7.24.5)(@babel/preset-env@7.24.5(@babel/core@7.24.5))(bufferutil@4.0.8)(react@19.0.0)(utf-8-validate@5.0.10))': + '@solana-mobile/mobile-wallet-adapter-protocol-web3js@2.0.2(@solana/web3.js@1.98.0(bufferutil@4.0.8)(utf-8-validate@5.0.10))(react-native@0.72.14(@babel/core@7.24.5)(@babel/preset-env@7.24.5(@babel/core@7.24.5))(bufferutil@4.0.8)(react@19.0.0)(utf-8-validate@5.0.10))': dependencies: '@solana-mobile/mobile-wallet-adapter-protocol': 2.0.1(react-native@0.72.14(@babel/core@7.24.5)(@babel/preset-env@7.24.5(@babel/core@7.24.5))(bufferutil@4.0.8)(react@19.0.0)(utf-8-validate@5.0.10)) - '@solana/web3.js': 1.95.5(bufferutil@4.0.8)(utf-8-validate@5.0.10) + '@solana/web3.js': 1.98.0(bufferutil@4.0.8)(utf-8-validate@5.0.10) bs58: 5.0.0 js-base64: 3.7.5 transitivePeerDependencies: @@ -10920,12 +10884,12 @@ snapshots: dependencies: react-native: 0.72.14(@babel/core@7.24.5)(@babel/preset-env@7.24.5(@babel/core@7.24.5))(bufferutil@4.0.8)(react@19.0.0)(utf-8-validate@5.0.10) - '@solana-mobile/wallet-adapter-mobile@2.0.1(@solana/web3.js@1.95.5(bufferutil@4.0.8)(utf-8-validate@5.0.10))(react-native@0.72.14(@babel/core@7.24.5)(@babel/preset-env@7.24.5(@babel/core@7.24.5))(bufferutil@4.0.8)(react@19.0.0)(utf-8-validate@5.0.10))': + '@solana-mobile/wallet-adapter-mobile@2.0.1(@solana/web3.js@1.98.0(bufferutil@4.0.8)(utf-8-validate@5.0.10))(react-native@0.72.14(@babel/core@7.24.5)(@babel/preset-env@7.24.5(@babel/core@7.24.5))(bufferutil@4.0.8)(react@19.0.0)(utf-8-validate@5.0.10))': dependencies: '@react-native-async-storage/async-storage': 1.19.5(react-native@0.72.14(@babel/core@7.24.5)(@babel/preset-env@7.24.5(@babel/core@7.24.5))(bufferutil@4.0.8)(react@19.0.0)(utf-8-validate@5.0.10)) - '@solana-mobile/mobile-wallet-adapter-protocol-web3js': 2.0.2(@solana/web3.js@1.95.5(bufferutil@4.0.8)(utf-8-validate@5.0.10))(react-native@0.72.14(@babel/core@7.24.5)(@babel/preset-env@7.24.5(@babel/core@7.24.5))(bufferutil@4.0.8)(react@19.0.0)(utf-8-validate@5.0.10)) - '@solana/wallet-adapter-base': 0.9.23(@solana/web3.js@1.95.5(bufferutil@4.0.8)(utf-8-validate@5.0.10)) - '@solana/web3.js': 1.95.5(bufferutil@4.0.8)(utf-8-validate@5.0.10) + '@solana-mobile/mobile-wallet-adapter-protocol-web3js': 2.0.2(@solana/web3.js@1.98.0(bufferutil@4.0.8)(utf-8-validate@5.0.10))(react-native@0.72.14(@babel/core@7.24.5)(@babel/preset-env@7.24.5(@babel/core@7.24.5))(bufferutil@4.0.8)(react@19.0.0)(utf-8-validate@5.0.10)) + '@solana/wallet-adapter-base': 0.9.23(@solana/web3.js@1.98.0(bufferutil@4.0.8)(utf-8-validate@5.0.10)) + '@solana/web3.js': 1.98.0(bufferutil@4.0.8)(utf-8-validate@5.0.10) js-base64: 3.7.5 transitivePeerDependencies: - react-native @@ -11084,7 +11048,7 @@ snapshots: - fastestsmallesttextencoderdecoder - typescript - '@solana/spl-token-metadata@0.1.2(@solana/web3.js@1.95.5(bufferutil@4.0.8)(utf-8-validate@5.0.10))(fastestsmallesttextencoderdecoder@1.0.22)': + '@solana/spl-token-metadata@0.1.2(@solana/web3.js@1.98.0(bufferutil@4.0.8)(utf-8-validate@5.0.10))(fastestsmallesttextencoderdecoder@1.0.22)': dependencies: '@solana/codecs-core': 2.0.0-experimental.8618508 '@solana/codecs-data-structures': 2.0.0-experimental.8618508 @@ -11092,7 +11056,7 @@ snapshots: '@solana/codecs-strings': 2.0.0-experimental.8618508(fastestsmallesttextencoderdecoder@1.0.22) '@solana/options': 2.0.0-experimental.8618508 '@solana/spl-type-length-value': 0.1.0 - '@solana/web3.js': 1.95.5(bufferutil@4.0.8)(utf-8-validate@5.0.10) + '@solana/web3.js': 1.98.0(bufferutil@4.0.8)(utf-8-validate@5.0.10) transitivePeerDependencies: - fastestsmallesttextencoderdecoder @@ -11105,12 +11069,12 @@ snapshots: - fastestsmallesttextencoderdecoder - typescript - '@solana/spl-token@0.3.11(@solana/web3.js@1.95.5(bufferutil@4.0.8)(utf-8-validate@5.0.10))(bufferutil@4.0.8)(fastestsmallesttextencoderdecoder@1.0.22)(utf-8-validate@5.0.10)': + '@solana/spl-token@0.3.11(@solana/web3.js@1.98.0(bufferutil@4.0.8)(utf-8-validate@5.0.10))(bufferutil@4.0.8)(fastestsmallesttextencoderdecoder@1.0.22)(utf-8-validate@5.0.10)': dependencies: '@solana/buffer-layout': 4.0.1 '@solana/buffer-layout-utils': 0.2.0(bufferutil@4.0.8)(utf-8-validate@5.0.10) - '@solana/spl-token-metadata': 0.1.2(@solana/web3.js@1.95.5(bufferutil@4.0.8)(utf-8-validate@5.0.10))(fastestsmallesttextencoderdecoder@1.0.22) - '@solana/web3.js': 1.95.5(bufferutil@4.0.8)(utf-8-validate@5.0.10) + '@solana/spl-token-metadata': 0.1.2(@solana/web3.js@1.98.0(bufferutil@4.0.8)(utf-8-validate@5.0.10))(fastestsmallesttextencoderdecoder@1.0.22) + '@solana/web3.js': 1.98.0(bufferutil@4.0.8)(utf-8-validate@5.0.10) buffer: 6.0.3 transitivePeerDependencies: - bufferutil @@ -11137,53 +11101,53 @@ snapshots: dependencies: buffer: 6.0.3 - '@solana/wallet-adapter-base-ui@0.1.2(@solana/web3.js@1.95.5(bufferutil@4.0.8)(utf-8-validate@5.0.10))(bs58@6.0.0)(react-native@0.72.14(@babel/core@7.24.5)(@babel/preset-env@7.24.5(@babel/core@7.24.5))(bufferutil@4.0.8)(react@19.0.0)(utf-8-validate@5.0.10))(react@19.0.0)': + '@solana/wallet-adapter-base-ui@0.1.2(@solana/web3.js@1.98.0(bufferutil@4.0.8)(utf-8-validate@5.0.10))(bs58@6.0.0)(react-native@0.72.14(@babel/core@7.24.5)(@babel/preset-env@7.24.5(@babel/core@7.24.5))(bufferutil@4.0.8)(react@19.0.0)(utf-8-validate@5.0.10))(react@19.0.0)': dependencies: - '@solana/wallet-adapter-react': 0.15.35(@solana/web3.js@1.95.5(bufferutil@4.0.8)(utf-8-validate@5.0.10))(bs58@6.0.0)(react-native@0.72.14(@babel/core@7.24.5)(@babel/preset-env@7.24.5(@babel/core@7.24.5))(bufferutil@4.0.8)(react@19.0.0)(utf-8-validate@5.0.10))(react@19.0.0) - '@solana/web3.js': 1.95.5(bufferutil@4.0.8)(utf-8-validate@5.0.10) + '@solana/wallet-adapter-react': 0.15.35(@solana/web3.js@1.98.0(bufferutil@4.0.8)(utf-8-validate@5.0.10))(bs58@6.0.0)(react-native@0.72.14(@babel/core@7.24.5)(@babel/preset-env@7.24.5(@babel/core@7.24.5))(bufferutil@4.0.8)(react@19.0.0)(utf-8-validate@5.0.10))(react@19.0.0) + '@solana/web3.js': 1.98.0(bufferutil@4.0.8)(utf-8-validate@5.0.10) react: 19.0.0 transitivePeerDependencies: - bs58 - react-native - '@solana/wallet-adapter-base@0.9.23(@solana/web3.js@1.95.5(bufferutil@4.0.8)(utf-8-validate@5.0.10))': + '@solana/wallet-adapter-base@0.9.23(@solana/web3.js@1.98.0(bufferutil@4.0.8)(utf-8-validate@5.0.10))': dependencies: '@solana/wallet-standard-features': 1.1.0 - '@solana/web3.js': 1.95.5(bufferutil@4.0.8)(utf-8-validate@5.0.10) + '@solana/web3.js': 1.98.0(bufferutil@4.0.8)(utf-8-validate@5.0.10) '@wallet-standard/base': 1.0.1 '@wallet-standard/features': 1.0.3 eventemitter3: 4.0.7 - '@solana/wallet-adapter-react-ui@0.9.35(@solana/web3.js@1.95.5(bufferutil@4.0.8)(utf-8-validate@5.0.10))(bs58@6.0.0)(react-dom@19.0.0(react@19.0.0))(react-native@0.72.14(@babel/core@7.24.5)(@babel/preset-env@7.24.5(@babel/core@7.24.5))(bufferutil@4.0.8)(react@19.0.0)(utf-8-validate@5.0.10))(react@19.0.0)': + '@solana/wallet-adapter-react-ui@0.9.35(@solana/web3.js@1.98.0(bufferutil@4.0.8)(utf-8-validate@5.0.10))(bs58@6.0.0)(react-dom@19.0.0(react@19.0.0))(react-native@0.72.14(@babel/core@7.24.5)(@babel/preset-env@7.24.5(@babel/core@7.24.5))(bufferutil@4.0.8)(react@19.0.0)(utf-8-validate@5.0.10))(react@19.0.0)': dependencies: - '@solana/wallet-adapter-base': 0.9.23(@solana/web3.js@1.95.5(bufferutil@4.0.8)(utf-8-validate@5.0.10)) - '@solana/wallet-adapter-base-ui': 0.1.2(@solana/web3.js@1.95.5(bufferutil@4.0.8)(utf-8-validate@5.0.10))(bs58@6.0.0)(react-native@0.72.14(@babel/core@7.24.5)(@babel/preset-env@7.24.5(@babel/core@7.24.5))(bufferutil@4.0.8)(react@19.0.0)(utf-8-validate@5.0.10))(react@19.0.0) - '@solana/wallet-adapter-react': 0.15.35(@solana/web3.js@1.95.5(bufferutil@4.0.8)(utf-8-validate@5.0.10))(bs58@6.0.0)(react-native@0.72.14(@babel/core@7.24.5)(@babel/preset-env@7.24.5(@babel/core@7.24.5))(bufferutil@4.0.8)(react@19.0.0)(utf-8-validate@5.0.10))(react@19.0.0) - '@solana/web3.js': 1.95.5(bufferutil@4.0.8)(utf-8-validate@5.0.10) + '@solana/wallet-adapter-base': 0.9.23(@solana/web3.js@1.98.0(bufferutil@4.0.8)(utf-8-validate@5.0.10)) + '@solana/wallet-adapter-base-ui': 0.1.2(@solana/web3.js@1.98.0(bufferutil@4.0.8)(utf-8-validate@5.0.10))(bs58@6.0.0)(react-native@0.72.14(@babel/core@7.24.5)(@babel/preset-env@7.24.5(@babel/core@7.24.5))(bufferutil@4.0.8)(react@19.0.0)(utf-8-validate@5.0.10))(react@19.0.0) + '@solana/wallet-adapter-react': 0.15.35(@solana/web3.js@1.98.0(bufferutil@4.0.8)(utf-8-validate@5.0.10))(bs58@6.0.0)(react-native@0.72.14(@babel/core@7.24.5)(@babel/preset-env@7.24.5(@babel/core@7.24.5))(bufferutil@4.0.8)(react@19.0.0)(utf-8-validate@5.0.10))(react@19.0.0) + '@solana/web3.js': 1.98.0(bufferutil@4.0.8)(utf-8-validate@5.0.10) react: 19.0.0 react-dom: 19.0.0(react@19.0.0) transitivePeerDependencies: - bs58 - react-native - '@solana/wallet-adapter-react@0.15.35(@solana/web3.js@1.95.5(bufferutil@4.0.8)(utf-8-validate@5.0.10))(bs58@6.0.0)(react-native@0.72.14(@babel/core@7.24.5)(@babel/preset-env@7.24.5(@babel/core@7.24.5))(bufferutil@4.0.8)(react@19.0.0)(utf-8-validate@5.0.10))(react@19.0.0)': + '@solana/wallet-adapter-react@0.15.35(@solana/web3.js@1.98.0(bufferutil@4.0.8)(utf-8-validate@5.0.10))(bs58@6.0.0)(react-native@0.72.14(@babel/core@7.24.5)(@babel/preset-env@7.24.5(@babel/core@7.24.5))(bufferutil@4.0.8)(react@19.0.0)(utf-8-validate@5.0.10))(react@19.0.0)': dependencies: - '@solana-mobile/wallet-adapter-mobile': 2.0.1(@solana/web3.js@1.95.5(bufferutil@4.0.8)(utf-8-validate@5.0.10))(react-native@0.72.14(@babel/core@7.24.5)(@babel/preset-env@7.24.5(@babel/core@7.24.5))(bufferutil@4.0.8)(react@19.0.0)(utf-8-validate@5.0.10)) - '@solana/wallet-adapter-base': 0.9.23(@solana/web3.js@1.95.5(bufferutil@4.0.8)(utf-8-validate@5.0.10)) - '@solana/wallet-standard-wallet-adapter-react': 1.1.1(@solana/wallet-adapter-base@0.9.23(@solana/web3.js@1.95.5(bufferutil@4.0.8)(utf-8-validate@5.0.10)))(@solana/web3.js@1.95.5(bufferutil@4.0.8)(utf-8-validate@5.0.10))(bs58@6.0.0)(react@19.0.0) - '@solana/web3.js': 1.95.5(bufferutil@4.0.8)(utf-8-validate@5.0.10) + '@solana-mobile/wallet-adapter-mobile': 2.0.1(@solana/web3.js@1.98.0(bufferutil@4.0.8)(utf-8-validate@5.0.10))(react-native@0.72.14(@babel/core@7.24.5)(@babel/preset-env@7.24.5(@babel/core@7.24.5))(bufferutil@4.0.8)(react@19.0.0)(utf-8-validate@5.0.10)) + '@solana/wallet-adapter-base': 0.9.23(@solana/web3.js@1.98.0(bufferutil@4.0.8)(utf-8-validate@5.0.10)) + '@solana/wallet-standard-wallet-adapter-react': 1.1.1(@solana/wallet-adapter-base@0.9.23(@solana/web3.js@1.98.0(bufferutil@4.0.8)(utf-8-validate@5.0.10)))(@solana/web3.js@1.98.0(bufferutil@4.0.8)(utf-8-validate@5.0.10))(bs58@6.0.0)(react@19.0.0) + '@solana/web3.js': 1.98.0(bufferutil@4.0.8)(utf-8-validate@5.0.10) react: 19.0.0 transitivePeerDependencies: - bs58 - react-native - '@solana/wallet-adapter-unsafe-burner@0.1.7(@solana/web3.js@1.95.5(bufferutil@4.0.8)(utf-8-validate@5.0.10))': + '@solana/wallet-adapter-unsafe-burner@0.1.7(@solana/web3.js@1.98.0(bufferutil@4.0.8)(utf-8-validate@5.0.10))': dependencies: '@noble/curves': 1.4.0 - '@solana/wallet-adapter-base': 0.9.23(@solana/web3.js@1.95.5(bufferutil@4.0.8)(utf-8-validate@5.0.10)) + '@solana/wallet-adapter-base': 0.9.23(@solana/web3.js@1.98.0(bufferutil@4.0.8)(utf-8-validate@5.0.10)) '@solana/wallet-standard-features': 1.1.0 '@solana/wallet-standard-util': 1.1.0 - '@solana/web3.js': 1.95.5(bufferutil@4.0.8)(utf-8-validate@5.0.10) + '@solana/web3.js': 1.98.0(bufferutil@4.0.8)(utf-8-validate@5.0.10) '@solana/wallet-standard-chains@1.1.0': dependencies: @@ -11200,23 +11164,23 @@ snapshots: '@solana/wallet-standard-chains': 1.1.0 '@solana/wallet-standard-features': 1.1.0 - '@solana/wallet-standard-wallet-adapter-base@1.1.1(@solana/web3.js@1.95.5(bufferutil@4.0.8)(utf-8-validate@5.0.10))(bs58@6.0.0)': + '@solana/wallet-standard-wallet-adapter-base@1.1.1(@solana/web3.js@1.98.0(bufferutil@4.0.8)(utf-8-validate@5.0.10))(bs58@6.0.0)': dependencies: - '@solana/wallet-adapter-base': 0.9.23(@solana/web3.js@1.95.5(bufferutil@4.0.8)(utf-8-validate@5.0.10)) + '@solana/wallet-adapter-base': 0.9.23(@solana/web3.js@1.98.0(bufferutil@4.0.8)(utf-8-validate@5.0.10)) '@solana/wallet-standard-chains': 1.1.0 '@solana/wallet-standard-features': 1.1.0 '@solana/wallet-standard-util': 1.1.0 - '@solana/web3.js': 1.95.5(bufferutil@4.0.8)(utf-8-validate@5.0.10) + '@solana/web3.js': 1.98.0(bufferutil@4.0.8)(utf-8-validate@5.0.10) '@wallet-standard/app': 1.0.1 '@wallet-standard/base': 1.0.1 '@wallet-standard/features': 1.0.3 '@wallet-standard/wallet': 1.0.1 bs58: 6.0.0 - '@solana/wallet-standard-wallet-adapter-react@1.1.1(@solana/wallet-adapter-base@0.9.23(@solana/web3.js@1.95.5(bufferutil@4.0.8)(utf-8-validate@5.0.10)))(@solana/web3.js@1.95.5(bufferutil@4.0.8)(utf-8-validate@5.0.10))(bs58@6.0.0)(react@19.0.0)': + '@solana/wallet-standard-wallet-adapter-react@1.1.1(@solana/wallet-adapter-base@0.9.23(@solana/web3.js@1.98.0(bufferutil@4.0.8)(utf-8-validate@5.0.10)))(@solana/web3.js@1.98.0(bufferutil@4.0.8)(utf-8-validate@5.0.10))(bs58@6.0.0)(react@19.0.0)': dependencies: - '@solana/wallet-adapter-base': 0.9.23(@solana/web3.js@1.95.5(bufferutil@4.0.8)(utf-8-validate@5.0.10)) - '@solana/wallet-standard-wallet-adapter-base': 1.1.1(@solana/web3.js@1.95.5(bufferutil@4.0.8)(utf-8-validate@5.0.10))(bs58@6.0.0) + '@solana/wallet-adapter-base': 0.9.23(@solana/web3.js@1.98.0(bufferutil@4.0.8)(utf-8-validate@5.0.10)) + '@solana/wallet-standard-wallet-adapter-base': 1.1.1(@solana/web3.js@1.98.0(bufferutil@4.0.8)(utf-8-validate@5.0.10))(bs58@6.0.0) '@wallet-standard/app': 1.0.1 '@wallet-standard/base': 1.0.1 react: 19.0.0 @@ -11224,28 +11188,6 @@ snapshots: - '@solana/web3.js' - bs58 - '@solana/web3.js@1.95.5(bufferutil@4.0.8)(utf-8-validate@5.0.10)': - dependencies: - '@babel/runtime': 7.25.6 - '@noble/curves': 1.4.2 - '@noble/hashes': 1.5.0 - '@solana/buffer-layout': 4.0.1 - agentkeepalive: 4.5.0 - bigint-buffer: 1.1.5 - bn.js: 5.2.1 - borsh: 0.7.0 - bs58: 4.0.1 - buffer: 6.0.3 - fast-stable-stringify: 1.0.0 - jayson: 4.1.2(bufferutil@4.0.8)(utf-8-validate@5.0.10) - node-fetch: 2.7.0 - rpc-websockets: 9.0.2 - superstruct: 2.0.2 - transitivePeerDependencies: - - bufferutil - - encoding - - utf-8-validate - '@solana/web3.js@1.98.0(bufferutil@4.0.8)(utf-8-validate@5.0.10)': dependencies: '@babel/runtime': 7.25.6 @@ -13274,7 +13216,7 @@ snapshots: '@typescript-eslint/parser': 7.13.1(eslint@9.17.0)(typescript@5.7.2) eslint: 9.17.0 eslint-import-resolver-node: 0.3.9 - eslint-import-resolver-typescript: 3.6.1(@typescript-eslint/parser@7.13.1(eslint@9.17.0)(typescript@5.7.2))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.31.0)(eslint@9.17.0) + eslint-import-resolver-typescript: 3.6.1(@typescript-eslint/parser@7.13.1(eslint@9.17.0)(typescript@5.7.2))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.31.0(@typescript-eslint/parser@7.13.1(eslint@9.17.0)(typescript@5.7.2))(eslint@9.17.0))(eslint@9.17.0) eslint-plugin-import: 2.31.0(@typescript-eslint/parser@7.13.1(eslint@9.17.0)(typescript@5.7.2))(eslint-import-resolver-typescript@3.6.1)(eslint@9.17.0) eslint-plugin-jsx-a11y: 6.10.2(eslint@9.17.0) eslint-plugin-react: 7.37.2(eslint@9.17.0) @@ -13354,12 +13296,12 @@ snapshots: - eslint-import-resolver-webpack - supports-color - eslint-import-resolver-typescript@3.6.1(@typescript-eslint/parser@7.13.1(eslint@9.17.0)(typescript@5.7.2))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.31.0)(eslint@9.17.0): + eslint-import-resolver-typescript@3.6.1(@typescript-eslint/parser@7.13.1(eslint@9.17.0)(typescript@5.7.2))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.31.0(@typescript-eslint/parser@7.13.1(eslint@9.17.0)(typescript@5.7.2))(eslint@9.17.0))(eslint@9.17.0): dependencies: debug: 4.3.7(supports-color@8.1.1) enhanced-resolve: 5.17.1 eslint: 9.17.0 - eslint-module-utils: 2.12.0(@typescript-eslint/parser@7.13.1(eslint@9.17.0)(typescript@5.7.2))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.1(@typescript-eslint/parser@7.13.1(eslint@9.17.0)(typescript@5.7.2))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.31.0)(eslint@9.17.0))(eslint@9.17.0) + eslint-module-utils: 2.12.0(@typescript-eslint/parser@7.13.1(eslint@9.17.0)(typescript@5.7.2))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.1(@typescript-eslint/parser@7.13.1(eslint@9.17.0)(typescript@5.7.2))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.31.0(@typescript-eslint/parser@7.13.1(eslint@9.17.0)(typescript@5.7.2))(eslint@9.17.0))(eslint@9.17.0))(eslint@9.17.0) eslint-plugin-import: 2.31.0(@typescript-eslint/parser@7.13.1(eslint@9.17.0)(typescript@5.7.2))(eslint-import-resolver-typescript@3.6.1)(eslint@9.17.0) fast-glob: 3.3.2 get-tsconfig: 4.7.2 @@ -13391,14 +13333,14 @@ snapshots: transitivePeerDependencies: - supports-color - eslint-module-utils@2.12.0(@typescript-eslint/parser@7.13.1(eslint@9.17.0)(typescript@5.7.2))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.1(@typescript-eslint/parser@7.13.1(eslint@9.17.0)(typescript@5.7.2))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.31.0)(eslint@9.17.0))(eslint@9.17.0): + eslint-module-utils@2.12.0(@typescript-eslint/parser@7.13.1(eslint@9.17.0)(typescript@5.7.2))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.1(@typescript-eslint/parser@7.13.1(eslint@9.17.0)(typescript@5.7.2))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.31.0(@typescript-eslint/parser@7.13.1(eslint@9.17.0)(typescript@5.7.2))(eslint@9.17.0))(eslint@9.17.0))(eslint@9.17.0): dependencies: debug: 3.2.7 optionalDependencies: '@typescript-eslint/parser': 7.13.1(eslint@9.17.0)(typescript@5.7.2) eslint: 9.17.0 eslint-import-resolver-node: 0.3.9 - eslint-import-resolver-typescript: 3.6.1(@typescript-eslint/parser@7.13.1(eslint@9.17.0)(typescript@5.7.2))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.31.0)(eslint@9.17.0) + eslint-import-resolver-typescript: 3.6.1(@typescript-eslint/parser@7.13.1(eslint@9.17.0)(typescript@5.7.2))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.31.0(@typescript-eslint/parser@7.13.1(eslint@9.17.0)(typescript@5.7.2))(eslint@9.17.0))(eslint@9.17.0) transitivePeerDependencies: - supports-color @@ -13491,7 +13433,7 @@ snapshots: doctrine: 2.1.0 eslint: 9.17.0 eslint-import-resolver-node: 0.3.9 - eslint-module-utils: 2.12.0(@typescript-eslint/parser@7.13.1(eslint@9.17.0)(typescript@5.7.2))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.1(@typescript-eslint/parser@7.13.1(eslint@9.17.0)(typescript@5.7.2))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.31.0)(eslint@9.17.0))(eslint@9.17.0) + eslint-module-utils: 2.12.0(@typescript-eslint/parser@7.13.1(eslint@9.17.0)(typescript@5.7.2))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.1(@typescript-eslint/parser@7.13.1(eslint@9.17.0)(typescript@5.7.2))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.31.0(@typescript-eslint/parser@7.13.1(eslint@9.17.0)(typescript@5.7.2))(eslint@9.17.0))(eslint@9.17.0))(eslint@9.17.0) hasown: 2.0.2 is-core-module: 2.15.1 is-glob: 4.0.3 From 26f71e7a31290e95aef23d000dd9477d6060e52e Mon Sep 17 00:00:00 2001 From: Swenschaeferjohann Date: Sat, 4 Jan 2025 21:26:15 +0000 Subject: [PATCH 03/19] clean --- js/compressed-token/src/program.ts | 1 - .../tests/e2e/create-mint.test.ts | 7 +- .../tests/e2e/rpc-token-interop.test.ts | 3 +- js/stateless.js/src/connection-interface.ts | 545 ------------ js/stateless.js/src/rpc-interface.ts | 43 +- js/stateless.js/src/rpc.ts | 805 ----------------- .../src/test-helpers/test-rpc/test-rpc.ts | 806 ------------------ js/stateless.js/tests/e2e/serde.test.ts | 22 +- 8 files changed, 4 insertions(+), 2228 deletions(-) delete mode 100644 js/stateless.js/src/connection-interface.ts diff --git a/js/compressed-token/src/program.ts b/js/compressed-token/src/program.ts index ccae5ea002..f77da8a55c 100644 --- a/js/compressed-token/src/program.ts +++ b/js/compressed-token/src/program.ts @@ -6,7 +6,6 @@ import { AddressLookupTableProgram, AccountMeta, } from '@solana/web3.js'; -import { Buffer } from 'buffer'; import BN from 'bn.js'; import { CompressedProof, diff --git a/js/compressed-token/tests/e2e/create-mint.test.ts b/js/compressed-token/tests/e2e/create-mint.test.ts index e105790421..4489c2b26c 100644 --- a/js/compressed-token/tests/e2e/create-mint.test.ts +++ b/js/compressed-token/tests/e2e/create-mint.test.ts @@ -44,7 +44,6 @@ async function assertCreateMint( expect(unpackedPoolAccount.delegate).toBe(null); } -console.log('TEST_TOKEN_DECIMALS'); const TEST_TOKEN_DECIMALS = 2; describe('createMint', () => { let rpc: Rpc; @@ -53,16 +52,12 @@ describe('createMint', () => { let mintAuthority: Keypair; beforeAll(async () => { - console.log('beforeAll'); const lightWasm = await WasmFactory.getInstance(); - console.log('lightWasm', lightWasm); rpc = await getTestRpc(lightWasm); - console.log('TESTrpc', rpc); payer = await newAccountWithLamports(rpc, 1e9); - console.log('payer', payer); }); - it.only('should create mint', async () => { + it('should create mint', async () => { mintAuthority = Keypair.generate(); const mintKeypair = Keypair.generate(); diff --git a/js/compressed-token/tests/e2e/rpc-token-interop.test.ts b/js/compressed-token/tests/e2e/rpc-token-interop.test.ts index 2c7c8ea14a..37d98f0d76 100644 --- a/js/compressed-token/tests/e2e/rpc-token-interop.test.ts +++ b/js/compressed-token/tests/e2e/rpc-token-interop.test.ts @@ -6,7 +6,6 @@ import { bn, createRpc, getTestRpc, - TestRpc, } from '@lightprotocol/stateless.js'; import { WasmFactory } from '@lightprotocol/hasher.rs'; import { createMint, mintTo, transfer } from '../../src/actions'; @@ -15,7 +14,7 @@ const TEST_TOKEN_DECIMALS = 2; describe('rpc-interop token', () => { let rpc: Rpc; - let testRpc: TestRpc | Rpc; + let testRpc: Rpc; let payer: Signer; let bob: Signer; let charlie: Signer; diff --git a/js/stateless.js/src/connection-interface.ts b/js/stateless.js/src/connection-interface.ts deleted file mode 100644 index 6dce862deb..0000000000 --- a/js/stateless.js/src/connection-interface.ts +++ /dev/null @@ -1,545 +0,0 @@ -// import { -// PublicKey, -// Commitment, -// ConnectionConfig, -// GetBalanceConfig, -// RpcResponseAndContext, -// Supply, -// TokenAmount, -// GetSupplyConfig, -// TokenAccountsFilter, -// GetProgramAccountsResponse, -// GetTokenAccountsByOwnerConfig, -// AccountInfo, -// ParsedAccountData, -// GetLargestAccountsConfig, -// AccountBalancePair, -// TokenAccountBalancePair, -// GetAccountInfoConfig, -// GetMultipleAccountsConfig, -// StakeActivationData, -// GetBlockHeightConfig, -// GetBlockProductionConfig, -// BlockProduction, -// GetLatestBlockhashConfig, -// BlockhashWithExpiryBlockHeight, -// SimulatedTransactionResponse, -// SimulateTransactionConfig, -// SendOptions, -// TransactionSignature, -// AddressLookupTableAccount, -// GetParsedProgramAccountsConfig, -// Finality, -// GetVersionedBlockConfig, -// VersionedBlockResponse, -// VersionedAccountsModeBlockResponse, -// VersionedNoneModeBlockResponse, -// ParsedAccountsModeBlockResponse, -// ParsedNoneModeBlockResponse, -// ParsedTransactionWithMeta, -// VersionedTransaction, -// VersionedTransactionResponse, -// ConfirmedBlock, -// ConfirmedSignatureInfo, -// ConfirmedSignaturesForAddress2Options, -// SignatureStatusConfig, -// SignatureStatus, -// Version, -// VoteAccountStatus, -// GetSlotConfig, -// GetSlotLeaderConfig, -// GetProgramAccountsConfig, -// SignatureResult, -// TransactionConfirmationStrategy, -// AccountChangeCallback, -// ProgramAccountChangeCallback, -// LogsCallback, -// SlotChangeCallback, -// SlotUpdateCallback, -// SignatureResultCallback, -// SignatureSubscriptionCallback, -// SignatureSubscriptionOptions, -// RootChangeCallback, -// GetStakeActivationConfig, -// InflationGovernor, -// GetTransactionCountConfig, -// GetInflationRewardConfig, -// InflationReward, -// InflationRate, -// GetEpochInfoConfig, -// EpochInfo, -// EpochSchedule, -// LeaderSchedule, -// Blockhash, -// FeeCalculator, -// PerfSample, -// VersionedMessage, -// GetRecentPrioritizationFeesConfig, -// RecentPrioritizationFees, -// IsBlockhashValidConfig, -// GetVersionedTransactionConfig, -// ParsedConfirmedTransaction, -// ConfirmedTransaction, -// BlockSignatures, -// SignaturesForAddressOptions, -// GetNonceAndContextConfig, -// NonceAccount, -// GetNonceConfig, -// GetStakeMinimumDelegationConfig, -// AccountSubscriptionConfig, -// ProgramAccountSubscriptionConfig, -// LogsFilter, -// ContactInfo, -// } from '@solana/web3.js'; - -// export type ClientSubscriptionId = number; - -// export interface ConnectionInterface { -// readonly commitment?: Commitment; -// readonly rpcEndpoint: string; - -// getBalanceAndContext( -// publicKey: PublicKey, -// commitmentOrConfig?: Commitment | GetBalanceConfig, -// ): Promise>; - -// getBalance( -// publicKey: PublicKey, -// commitmentOrConfig?: Commitment | GetBalanceConfig, -// ): Promise; - -// getBlockTime(slot: number): Promise; - -// getMinimumLedgerSlot(): Promise; - -// getFirstAvailableBlock(): Promise; - -// getSupply( -// config?: GetSupplyConfig | Commitment, -// ): Promise>; - -// getTokenSupply( -// tokenMintAddress: PublicKey, -// commitment?: Commitment, -// ): Promise>; - -// getTokenAccountBalance( -// tokenAddress: PublicKey, -// commitment?: Commitment, -// ): Promise>; - -// getTokenAccountsByOwner( -// ownerAddress: PublicKey, -// filter: TokenAccountsFilter, -// commitmentOrConfig?: Commitment | GetTokenAccountsByOwnerConfig, -// ): Promise>; - -// getParsedTokenAccountsByOwner( -// ownerAddress: PublicKey, -// filter: TokenAccountsFilter, -// commitment?: Commitment, -// ): Promise< -// RpcResponseAndContext< -// Array<{ -// pubkey: PublicKey; -// account: AccountInfo; -// }> -// > -// >; - -// getLargestAccounts( -// config?: GetLargestAccountsConfig, -// ): Promise>>; - -// getTokenLargestAccounts( -// mintAddress: PublicKey, -// commitment?: Commitment, -// ): Promise>>; - -// getAccountInfoAndContext( -// publicKey: PublicKey, -// commitmentOrConfig?: Commitment | GetAccountInfoConfig, -// ): Promise | null>>; - -// getParsedAccountInfo( -// publicKey: PublicKey, -// commitmentOrConfig?: Commitment | GetAccountInfoConfig, -// ): Promise< -// RpcResponseAndContext | null> -// >; - -// getAccountInfo( -// publicKey: PublicKey, -// commitmentOrConfig?: Commitment | GetAccountInfoConfig, -// ): Promise | null>; - -// getMultipleParsedAccounts( -// publicKeys: PublicKey[], -// rawConfig?: GetMultipleAccountsConfig, -// ): Promise< -// RpcResponseAndContext< -// (AccountInfo | null)[] -// > -// >; - -// getMultipleAccountsInfoAndContext( -// publicKeys: PublicKey[], -// commitmentOrConfig?: Commitment | GetMultipleAccountsConfig, -// ): Promise | null)[]>>; - -// getMultipleAccountsInfo( -// publicKeys: PublicKey[], -// commitmentOrConfig?: Commitment | GetMultipleAccountsConfig, -// ): Promise<(AccountInfo | null)[]>; - -// getStakeActivation( -// publicKey: PublicKey, -// commitmentOrConfig?: Commitment | GetStakeActivationConfig, -// epoch?: number, -// ): Promise; - -// getProgramAccounts( -// programId: PublicKey, -// configOrCommitment?: GetProgramAccountsConfig | Commitment, -// ): Promise; - -// getProgramAccounts( -// programId: PublicKey, -// configOrCommitment: GetProgramAccountsConfig & { withContext: true }, -// ): Promise>; - -// getParsedProgramAccounts( -// programId: PublicKey, -// configOrCommitment?: GetParsedProgramAccountsConfig | Commitment, -// ): Promise< -// Array<{ -// pubkey: PublicKey; -// account: AccountInfo; -// }> -// >; - -// confirmTransaction( -// strategy: TransactionConfirmationStrategy, -// commitment?: Commitment, -// ): Promise>; - -// confirmTransaction( -// strategy: TransactionSignature, -// commitment?: Commitment, -// ): Promise>; - -// getClusterNodes(): Promise>; - -// getVoteAccounts(commitment?: Commitment): Promise; - -// getSlot(commitmentOrConfig?: Commitment | GetSlotConfig): Promise; - -// getSlotLeader( -// commitmentOrConfig?: Commitment | GetSlotLeaderConfig, -// ): Promise; - -// getSlotLeaders(startSlot: number, limit: number): Promise>; - -// getSignatureStatus( -// signature: TransactionSignature, -// config?: SignatureStatusConfig, -// ): Promise>; - -// getSignatureStatuses( -// signatures: Array, -// config?: SignatureStatusConfig, -// ): Promise>>; - -// getTransactionCount( -// commitmentOrConfig?: Commitment | GetTransactionCountConfig, -// ): Promise; - -// getTotalSupply(commitment?: Commitment): Promise; - -// getInflationGovernor(commitment?: Commitment): Promise; - -// getInflationReward( -// addresses: PublicKey[], -// epoch?: number, -// commitmentOrConfig?: Commitment | GetInflationRewardConfig, -// ): Promise<(InflationReward | null)[]>; - -// getInflationRate(): Promise; - -// getEpochInfo( -// commitmentOrConfig?: Commitment | GetEpochInfoConfig, -// ): Promise; - -// getEpochSchedule(): Promise; - -// getLeaderSchedule(): Promise; - -// getMinimumBalanceForRentExemption( -// dataLength: number, -// commitment?: Commitment, -// ): Promise; - -// getRecentBlockhashAndContext(commitment?: Commitment): Promise< -// RpcResponseAndContext<{ -// blockhash: Blockhash; -// feeCalculator: FeeCalculator; -// }> -// >; - -// getRecentPerformanceSamples(limit?: number): Promise>; - -// getFeeCalculatorForBlockhash( -// blockhash: Blockhash, -// commitment?: Commitment, -// ): Promise>; - -// getFeeForMessage( -// message: VersionedMessage, -// commitment?: Commitment, -// ): Promise>; - -// getRecentPrioritizationFees( -// config?: GetRecentPrioritizationFeesConfig, -// ): Promise; - -// getRecentBlockhash( -// commitment?: Commitment, -// ): Promise<{ blockhash: Blockhash; feeCalculator: FeeCalculator }>; - -// getLatestBlockhash( -// commitmentOrConfig?: Commitment | GetLatestBlockhashConfig, -// ): Promise; - -// getLatestBlockhashAndContext( -// commitmentOrConfig?: Commitment | GetLatestBlockhashConfig, -// ): Promise>; - -// isBlockhashValid( -// blockhash: Blockhash, -// rawConfig?: IsBlockhashValidConfig, -// ): Promise>; - -// getVersion(): Promise; - -// getGenesisHash(): Promise; - -// getBlock( -// slot: number, -// rawConfig?: GetVersionedBlockConfig, -// ): Promise; - -// getBlock( -// slot: number, -// rawConfig: GetVersionedBlockConfig & { transactionDetails: 'accounts' }, -// ): Promise; - -// getBlock( -// slot: number, -// rawConfig: GetVersionedBlockConfig & { transactionDetails: 'none' }, -// ): Promise; - -// getParsedBlock( -// slot: number, -// rawConfig?: GetVersionedBlockConfig, -// ): Promise; - -// getParsedBlock( -// slot: number, -// rawConfig: GetVersionedBlockConfig & { transactionDetails: 'accounts' }, -// ): Promise; - -// getParsedBlock( -// slot: number, -// rawConfig: GetVersionedBlockConfig & { transactionDetails: 'none' }, -// ): Promise; - -// getBlockHeight( -// commitmentOrConfig?: Commitment | GetBlockHeightConfig, -// ): Promise; - -// getBlockProduction( -// configOrCommitment?: GetBlockProductionConfig | Commitment, -// ): Promise>; - -// getTransaction( -// signature: string, -// rawConfig?: GetVersionedTransactionConfig, -// ): Promise; - -// getParsedTransaction( -// signature: TransactionSignature, -// commitmentOrConfig?: GetVersionedTransactionConfig | Finality, -// ): Promise; - -// getParsedTransactions( -// signatures: TransactionSignature[], -// commitmentOrConfig?: GetVersionedTransactionConfig | Finality, -// ): Promise<(ParsedTransactionWithMeta | null)[]>; - -// getTransactions( -// signatures: TransactionSignature[], -// commitmentOrConfig: GetVersionedTransactionConfig | Finality, -// ): Promise<(VersionedTransactionResponse | null)[]>; - -// getConfirmedBlock( -// slot: number, -// commitment?: Finality, -// ): Promise; - -// getBlocks( -// startSlot: number, -// endSlot?: number, -// commitment?: Finality, -// ): Promise>; - -// getBlockSignatures( -// slot: number, -// commitment?: Finality, -// ): Promise; - -// getConfirmedBlockSignatures( -// slot: number, -// commitment?: Finality, -// ): Promise; - -// getConfirmedTransaction( -// signature: TransactionSignature, -// commitment?: Finality, -// ): Promise; - -// getParsedConfirmedTransaction( -// signature: TransactionSignature, -// commitment?: Finality, -// ): Promise; - -// getParsedConfirmedTransactions( -// signatures: TransactionSignature[], -// commitment?: Finality, -// ): Promise<(ParsedConfirmedTransaction | null)[]>; - -// getConfirmedSignaturesForAddress( -// address: PublicKey, -// startSlot: number, -// endSlot: number, -// ): Promise>; - -// getConfirmedSignaturesForAddress2( -// address: PublicKey, -// options?: ConfirmedSignaturesForAddress2Options, -// commitment?: Finality, -// ): Promise>; - -// getSignaturesForAddress( -// address: PublicKey, -// options?: SignaturesForAddressOptions, -// commitment?: Finality, -// ): Promise>; - -// getAddressLookupTable( -// accountKey: PublicKey, -// config?: GetAccountInfoConfig, -// ): Promise>; - -// getNonceAndContext( -// nonceAccount: PublicKey, -// commitmentOrConfig?: Commitment | GetNonceAndContextConfig, -// ): Promise>; - -// getNonce( -// nonceAccount: PublicKey, -// commitmentOrConfig?: Commitment | GetNonceConfig, -// ): Promise; - -// requestAirdrop( -// to: PublicKey, -// lamports: number, -// ): Promise; - -// getStakeMinimumDelegation( -// config?: GetStakeMinimumDelegationConfig, -// ): Promise>; - -// simulateTransaction( -// transaction: VersionedTransaction, -// config?: SimulateTransactionConfig, -// ): Promise>; - -// sendTransaction( -// transaction: VersionedTransaction, -// options?: SendOptions, -// ): Promise; - -// sendRawTransaction( -// rawTransaction: Buffer | Uint8Array | Array, -// options?: SendOptions, -// ): Promise; - -// sendEncodedTransaction( -// encodedTransaction: string, -// options?: SendOptions, -// ): Promise; - -// onAccountChange( -// publicKey: PublicKey, -// callback: AccountChangeCallback, -// config?: AccountSubscriptionConfig, -// ): ClientSubscriptionId; - -// onProgramAccountChange( -// programId: PublicKey, -// callback: ProgramAccountChangeCallback, -// config?: ProgramAccountSubscriptionConfig, -// ): ClientSubscriptionId; - -// onLogs( -// filter: LogsFilter, -// callback: LogsCallback, -// commitment?: Commitment, -// ): ClientSubscriptionId; - -// onSlotChange(callback: SlotChangeCallback): ClientSubscriptionId; - -// onSlotUpdate(callback: SlotUpdateCallback): ClientSubscriptionId; - -// onSignature( -// signature: TransactionSignature, -// callback: SignatureResultCallback, -// commitment?: Commitment, -// ): ClientSubscriptionId; - -// onSignatureWithOptions( -// signature: TransactionSignature, -// callback: SignatureSubscriptionCallback, -// options?: SignatureSubscriptionOptions, -// ): ClientSubscriptionId; - -// onRootChange(callback: RootChangeCallback): ClientSubscriptionId; - -// removeAccountChangeListener( -// clientSubscriptionId: ClientSubscriptionId, -// ): Promise; - -// removeProgramAccountChangeListener( -// clientSubscriptionId: ClientSubscriptionId, -// ): Promise; - -// removeOnLogsListener( -// clientSubscriptionId: ClientSubscriptionId, -// ): Promise; - -// removeSlotChangeListener( -// clientSubscriptionId: ClientSubscriptionId, -// ): Promise; - -// removeSlotUpdateListener( -// clientSubscriptionId: ClientSubscriptionId, -// ): Promise; - -// removeSignatureListener( -// clientSubscriptionId: ClientSubscriptionId, -// ): Promise; - -// removeRootChangeListener( -// clientSubscriptionId: ClientSubscriptionId, -// ): Promise; -// } diff --git a/js/stateless.js/src/rpc-interface.ts b/js/stateless.js/src/rpc-interface.ts index 3d280eeb11..9b49901c8e 100644 --- a/js/stateless.js/src/rpc-interface.ts +++ b/js/stateless.js/src/rpc-interface.ts @@ -1,11 +1,4 @@ -import { - PublicKey, - MemcmpFilter, - DataSlice, - RpcResponseAndContext, - Commitment, - SignatureResult, -} from '@solana/web3.js'; +import { PublicKey, MemcmpFilter, DataSlice } from '@solana/web3.js'; import { type as pick, number, @@ -32,40 +25,6 @@ import { } from './state'; import BN from 'bn.js'; -export class BaseRpc { - private async getCancellationPromise() { - throw new Error( - 'getCancellationPromise not supported in rpc. it is a stub that is marked as private in web3.js Connection', - ); - } - private async getTransactionConfirmationPromise() { - throw new Error( - 'getTransactionConfirmationPromise not supported in rpc. it is a stub that is marked as private in web3.js Connection', - ); - } - private async confirmTransactionUsingBlockHeightExceedanceStrategy() { - throw new Error( - 'confirmTransactionUsingBlockHeightExceedanceStrategy not supported in rpc. it is a stub that is marked as private in web3.js Connection', - ); - } - private async confirmTransactionUsingDurableNonceStrategy() { - throw new Error( - 'confirmTransactionUsingDurableNonceStrategy not supported in rpc. it is a stub that is marked as private in web3.js Connection', - ); - } - private async confirmTransactionUsingLegacyTimeoutStrategy({ - commitment, - signature, - }: { - commitment?: Commitment; - signature: string; - }): Promise> { - throw new Error( - 'confirmTransactionUsingLegacyTimeoutStrategy not supported in rpc. it is a stub that is marked as private in web3.js Connection', - ); - } -} - export interface LatestNonVotingSignatures { context: { slot: number }; value: { diff --git a/js/stateless.js/src/rpc.ts b/js/stateless.js/src/rpc.ts index 8dfdbcbd86..6f4f483d93 100644 --- a/js/stateless.js/src/rpc.ts +++ b/js/stateless.js/src/rpc.ts @@ -44,7 +44,6 @@ import { TokenBalance, TokenBalanceListResultV2, PaginatedOptions, - BaseRpc, } from './rpc-interface'; import { MerkleContextWithMerkleProof, @@ -533,810 +532,6 @@ export class Rpc extends Connection implements CompressionApiInterface { this.proverEndpoint = proverEndpoint; } - // get commitment(): Commitment | undefined { - // return this.connection.commitment; - // } - - // get rpcEndpoint(): string { - // return this.connection.rpcEndpoint; - // } - - // // === Connection Methods Delegated === - - // async getBalanceAndContext( - // publicKey: PublicKey, - // commitmentOrConfig?: Commitment | GetBalanceConfig, - // ): Promise> { - // return this.connection.getBalanceAndContext( - // publicKey, - // commitmentOrConfig, - // ); - // } - - // async getBalance( - // publicKey: PublicKey, - // commitmentOrConfig?: Commitment | GetBalanceConfig, - // ): Promise { - // return this.connection.getBalance(publicKey, commitmentOrConfig); - // } - - // async getBlockTime(slot: number): Promise { - // return this.connection.getBlockTime(slot); - // } - - // async getMinimumLedgerSlot(): Promise { - // return this.connection.getMinimumLedgerSlot(); - // } - - // async getFirstAvailableBlock(): Promise { - // return this.connection.getFirstAvailableBlock(); - // } - - // async getSupply( - // config?: GetSupplyConfig | Commitment, - // ): Promise> { - // return this.connection.getSupply(config); - // } - - // async getTokenSupply( - // tokenMintAddress: PublicKey, - // commitment?: Commitment, - // ): Promise> { - // return this.connection.getTokenSupply(tokenMintAddress, commitment); - // } - - // async getTokenAccountBalance( - // tokenAddress: PublicKey, - // commitment?: Commitment, - // ): Promise> { - // return this.connection.getTokenAccountBalance(tokenAddress, commitment); - // } - - // async getTokenAccountsByOwner( - // ownerAddress: PublicKey, - // filter: TokenAccountsFilter, - // commitmentOrConfig?: Commitment | GetTokenAccountsByOwnerConfig, - // ): Promise> { - // return this.connection.getTokenAccountsByOwner( - // ownerAddress, - // filter, - // commitmentOrConfig, - // ); - // } - - // async getParsedTokenAccountsByOwner( - // ownerAddress: PublicKey, - // filter: TokenAccountsFilter, - // commitment?: Commitment, - // ): Promise< - // RpcResponseAndContext< - // Array<{ - // pubkey: PublicKey; - // account: AccountInfo; - // }> - // > - // > { - // return this.connection.getParsedTokenAccountsByOwner( - // ownerAddress, - // filter, - // commitment, - // ); - // } - - // async getLargestAccounts( - // config?: GetLargestAccountsConfig, - // ): Promise>> { - // return this.connection.getLargestAccounts(config); - // } - - // async getTokenLargestAccounts( - // mintAddress: PublicKey, - // commitment?: Commitment, - // ): Promise>> { - // return this.connection.getTokenLargestAccounts(mintAddress, commitment); - // } - - // async getAccountInfoAndContext( - // publicKey: PublicKey, - // commitmentOrConfig?: Commitment | GetAccountInfoConfig, - // ): Promise | null>> { - // return this.connection.getAccountInfoAndContext( - // publicKey, - // commitmentOrConfig, - // ); - // } - - // async getParsedAccountInfo( - // publicKey: PublicKey, - // commitmentOrConfig?: Commitment | GetAccountInfoConfig, - // ): Promise< - // RpcResponseAndContext | null> - // > { - // return this.connection.getParsedAccountInfo( - // publicKey, - // commitmentOrConfig, - // ); - // } - - // async getAccountInfo( - // publicKey: PublicKey, - // commitmentOrConfig?: Commitment | GetAccountInfoConfig, - // ): Promise | null> { - // return this.connection.getAccountInfo(publicKey, commitmentOrConfig); - // } - - // async getMultipleParsedAccounts( - // publicKeys: PublicKey[], - // rawConfig?: GetMultipleAccountsConfig, - // ): Promise< - // RpcResponseAndContext< - // (AccountInfo | null)[] - // > - // > { - // return this.connection.getMultipleParsedAccounts(publicKeys, rawConfig); - // } - - // async getMultipleAccountsInfoAndContext( - // publicKeys: PublicKey[], - // commitmentOrConfig?: Commitment | GetMultipleAccountsConfig, - // ): Promise | null)[]>> { - // return this.connection.getMultipleAccountsInfoAndContext( - // publicKeys, - // commitmentOrConfig, - // ); - // } - - // async getMultipleAccountsInfo( - // publicKeys: PublicKey[], - // commitmentOrConfig?: Commitment | GetMultipleAccountsConfig, - // ): Promise<(AccountInfo | null)[]> { - // return this.connection.getMultipleAccountsInfo( - // publicKeys, - // commitmentOrConfig, - // ); - // } - - // async getStakeActivation( - // publicKey: PublicKey, - // commitmentOrConfig?: Commitment | GetStakeActivationConfig, - // epoch?: number, - // ): Promise { - // return this.connection.getStakeActivation( - // publicKey, - // commitmentOrConfig, - // epoch, - // ); - // } - - // async getProgramAccounts( - // programId: PublicKey, - // configOrCommitment?: GetProgramAccountsConfig | Commitment, - // ): Promise; - - // async getProgramAccounts( - // programId: PublicKey, - // configOrCommitment: GetProgramAccountsConfig & { withContext: true }, - // ): Promise>; - - // async getProgramAccounts( - // programId: PublicKey, - // configOrCommitment?: GetProgramAccountsConfig | Commitment, - // ): Promise< - // | GetProgramAccountsResponse - // | RpcResponseAndContext - // > { - // return this.connection.getProgramAccounts( - // programId, - // configOrCommitment, - // ); - // } - - // async getParsedProgramAccounts( - // programId: PublicKey, - // configOrCommitment?: GetParsedProgramAccountsConfig | Commitment, - // ): Promise< - // Array<{ - // pubkey: PublicKey; - // account: AccountInfo; - // }> - // > { - // return this.connection.getParsedProgramAccounts( - // programId, - // configOrCommitment, - // ); - // } - - // === Subscription Methods === - - // onAccountChange( - // publicKey: PublicKey, - // callback: AccountChangeCallback, - // config?: AccountSubscriptionConfig, - // ): ClientSubscriptionId { - // return this.connection.onAccountChange(publicKey, callback, config); - // } - - // async removeAccountChangeListener( - // clientSubscriptionId: ClientSubscriptionId, - // ): Promise { - // return this.connection.removeAccountChangeListener( - // clientSubscriptionId, - // ); - // } - - // onProgramAccountChange( - // programId: PublicKey, - // callback: ProgramAccountChangeCallback, - // config?: ProgramAccountSubscriptionConfig, - // ): ClientSubscriptionId { - // return this.connection.onProgramAccountChange( - // programId, - // callback, - // config, - // ); - // } - - // async removeProgramAccountChangeListener( - // clientSubscriptionId: ClientSubscriptionId, - // ): Promise { - // return this.connection.removeProgramAccountChangeListener( - // clientSubscriptionId, - // ); - // } - - // onLogs( - // filter: LogsFilter, - // callback: LogsCallback, - // commitment?: Commitment, - // ): ClientSubscriptionId { - // return this.connection.onLogs(filter, callback, commitment); - // } - - // async removeOnLogsListener( - // clientSubscriptionId: ClientSubscriptionId, - // ): Promise { - // return this.connection.removeOnLogsListener(clientSubscriptionId); - // } - - // onSlotChange(callback: SlotChangeCallback): ClientSubscriptionId { - // return this.connection.onSlotChange(callback); - // } - - // async removeSlotChangeListener( - // clientSubscriptionId: ClientSubscriptionId, - // ): Promise { - // return this.connection.removeSlotChangeListener(clientSubscriptionId); - // } - - // onSlotUpdate(callback: SlotUpdateCallback): ClientSubscriptionId { - // return this.connection.onSlotUpdate(callback); - // } - - // async removeSlotUpdateListener( - // clientSubscriptionId: ClientSubscriptionId, - // ): Promise { - // return this.connection.removeSlotUpdateListener(clientSubscriptionId); - // } - - // onSignature( - // signature: TransactionSignature, - // callback: SignatureResultCallback, - // commitment?: Commitment, - // ): ClientSubscriptionId { - // return this.connection.onSignature(signature, callback, commitment); - // } - - // onSignatureWithOptions( - // signature: TransactionSignature, - // callback: SignatureSubscriptionCallback, - // options?: SignatureSubscriptionOptions, - // ): ClientSubscriptionId { - // return this.connection.onSignatureWithOptions( - // signature, - // callback, - // options, - // ); - // } - - // async removeSignatureListener( - // clientSubscriptionId: ClientSubscriptionId, - // ): Promise { - // return this.connection.removeSignatureListener(clientSubscriptionId); - // } - - // onRootChange(callback: RootChangeCallback): ClientSubscriptionId { - // return this.connection.onRootChange(callback); - // } - - // async removeRootChangeListener( - // clientSubscriptionId: ClientSubscriptionId, - // ): Promise { - // return this.connection.removeRootChangeListener(clientSubscriptionId); - // } - - // // === Transaction Methods === - - // async sendTransaction( - // transaction: VersionedTransaction, - // options?: SendOptions, - // ): Promise { - // return this.connection.sendTransaction(transaction, options); - // } - - // async sendRawTransaction( - // rawTransaction: Buffer | Uint8Array | Array, - // options?: SendOptions, - // ): Promise { - // return this.connection.sendRawTransaction(rawTransaction, options); - // } - - // async sendEncodedTransaction( - // encodedTransaction: string, - // options?: SendOptions, - // ): Promise { - // return this.connection.sendEncodedTransaction( - // encodedTransaction, - // options, - // ); - // } - - // async simulateTransaction( - // transaction: VersionedTransaction, - // config?: SimulateTransactionConfig, - // ): Promise> { - // return this.connection.simulateTransaction(transaction, config); - // } - - // async requestAirdrop( - // to: PublicKey, - // lamports: number, - // ): Promise { - // return this.connection.requestAirdrop(to, lamports); - // } - - // async getStakeMinimumDelegation( - // config?: GetStakeMinimumDelegationConfig, - // ): Promise> { - // return this.connection.getStakeMinimumDelegation(config); - // } - - // async getTransactions( - // signatures: TransactionSignature[], - // commitmentOrConfig?: GetTransactionConfig | Finality, - // ): Promise<(VersionedTransactionResponse | null)[]> { - // return this.connection.getTransactions(signatures, commitmentOrConfig); - // } - - // async getTransaction( - // signature: string, - // rawConfig?: GetTransactionConfig, - // ): Promise { - // return this.connection.getTransaction(signature, rawConfig); - // } - - // async getParsedTransaction( - // signature: TransactionSignature, - // commitmentOrConfig?: GetVersionedTransactionConfig | Finality, - // ): Promise { - // return this.connection.getParsedTransaction( - // signature, - // commitmentOrConfig, - // ); - // } - - // async getParsedTransactions( - // signatures: TransactionSignature[], - // commitmentOrConfig?: GetVersionedTransactionConfig | Finality, - // ): Promise<(ParsedTransactionWithMeta | null)[]> { - // return this.connection.getParsedTransactions( - // signatures, - // commitmentOrConfig, - // ); - // } - - // async getConfirmedBlock( - // slot: number, - // commitment?: Finality, - // ): Promise { - // return this.connection.getConfirmedBlock(slot, commitment); - // } - - // async getBlocks( - // startSlot: number, - // endSlot?: number, - // commitment?: Finality, - // ): Promise> { - // return this.connection.getBlocks(startSlot, endSlot, commitment); - // } - - // async getBlockSignatures( - // slot: number, - // commitment?: Finality, - // ): Promise { - // return this.connection.getBlockSignatures(slot, commitment); - // } - - // async getConfirmedBlockSignatures( - // slot: number, - // commitment?: Finality, - // ): Promise { - // return this.connection.getConfirmedBlockSignatures(slot, commitment); - // } - - // confirmTransaction( - // strategy: TransactionConfirmationStrategy, - // commitment?: Commitment, - // ): Promise>; - - // /** @deprecated Instead, call `confirmTransaction` and pass in {@link TransactionConfirmationStrategy} */ - // // eslint-disable-next-line no-dupe-class-members - // confirmTransaction( - // strategy: TransactionSignature, - // commitment?: Commitment, - // ): Promise>; - - // async confirmTransaction( - // strategy: TransactionConfirmationStrategy | TransactionSignature, - // commitment?: Commitment, - // ): Promise> { - // // @ts-ignore - // return this.connection.confirmTransaction(strategy, commitment); - // } - - // // private async getCancellationPromise() { - // // throw new Error( - // // 'getCancellationPromise not supported in rpc. it is a stub that is marked as private in web3.js Connection', - // // ); - // // } - // // private async getTransactionConfirmationPromise() { - // // throw new Error( - // // 'getTransactionConfirmationPromise not supported in rpc. it is a stub that is marked as private in web3.js Connection', - // // ); - // // } - // // private async confirmTransactionUsingBlockHeightExceedanceStrategy() { - // // throw new Error( - // // 'confirmTransactionUsingBlockHeightExceedanceStrategy not supported in rpc. it is a stub that is marked as private in web3.js Connection', - // // ); - // // } - // // async confirmTransactionUsingDurableNonceStrategy() { - // // throw new Error( - // // 'confirmTransactionUsingDurableNonceStrategy not supported in rpc. it is a stub that is marked as private in web3.js Connection', - // // ); - // // } - // // private async confirmTransactionUsingLegacyTimeoutStrategy({ - // // commitment, - // // signature, - // // }: { - // // commitment?: Commitment; - // // signature: string; - // // }): Promise> { - // // throw new Error( - // // 'confirmTransactionUsingLegacyTimeoutStrategy not supported in rpc. it is a stub that is marked as private in web3.js Connection', - // // ); - // // } - // // _buildArgs( - // // args: Array, - // // override?: Commitment, - // // encoding?: 'jsonParsed' | 'base64', - // // extra?: any, - // // ): Array { - // // const commitment = override || this.connection.commitment; - // // if (commitment || encoding || extra) { - // // let options: any = {}; - // // if (encoding) { - // // options.encoding = encoding; - // // } - // // if (commitment) { - // // options.commitment = commitment; - // // } - // // if (extra) { - // // options = Object.assign(options, extra); - // // } - // // args.push(options); - // // } - // // return args; - // // } - - // async getClusterNodes(): Promise> { - // return this.connection.getClusterNodes(); - // } - - // async getVoteAccounts(commitment?: Commitment): Promise { - // return this.connection.getVoteAccounts(commitment); - // } - - // async getSlot( - // commitmentOrConfig?: Commitment | GetSlotConfig, - // ): Promise { - // return this.connection.getSlot(commitmentOrConfig); - // } - - // async getSlotLeader( - // commitmentOrConfig?: Commitment | GetSlotLeaderConfig, - // ): Promise { - // return this.connection.getSlotLeader(commitmentOrConfig); - // } - - // async getSlotLeaders( - // startSlot: number, - // limit: number, - // ): Promise> { - // return this.connection.getSlotLeaders(startSlot, limit); - // } - - // async getSignatureStatus( - // signature: TransactionSignature, - // config?: SignatureStatusConfig, - // ): Promise> { - // return this.connection.getSignatureStatus(signature, config); - // } - - // async getSignatureStatuses( - // signatures: Array, - // config?: SignatureStatusConfig, - // ): Promise>> { - // return this.connection.getSignatureStatuses(signatures, config); - // } - - // async getTotalSupply(commitment?: Commitment): Promise { - // return this.connection.getTotalSupply(commitment); - // } - - // async getBlockHeight(config?: GetBlockHeightConfig): Promise { - // return this.connection.getBlockHeight(config); - // } - - // async getBlockProduction( - // configOrCommitment?: GetBlockProductionConfig | Commitment, - // ): Promise> { - // return this.connection.getBlockProduction(configOrCommitment); - // } - - // async getTransactionCount( - // config?: GetTransactionCountConfig, - // ): Promise { - // return this.connection.getTransactionCount(config); - // } - - // async getInflationGovernor(): Promise { - // return this.connection.getInflationGovernor(); - // } - - // async getInflationReward( - // addresses: PublicKey[], - // epochs?: number, - // config?: GetInflationRewardConfig, - // ): Promise> { - // return this.connection.getInflationReward(addresses, epochs, config); - // } - - // async getInflationRate(): Promise { - // return this.connection.getInflationRate(); - // } - - // async getEpochInfo(config?: GetEpochInfoConfig): Promise { - // return this.connection.getEpochInfo(config); - // } - - // async getEpochSchedule(): Promise { - // return this.connection.getEpochSchedule(); - // } - - // async getLeaderSchedule(): Promise { - // return this.connection.getLeaderSchedule(); - // } - - // async getRecentBlockhashAndContext(commitment?: Commitment): Promise< - // RpcResponseAndContext<{ - // blockhash: Blockhash; - // feeCalculator: FeeCalculator; - // }> - // > { - // return this.connection.getRecentBlockhashAndContext(commitment); - // } - - // async getRecentPerformanceSamples( - // limit?: number, - // ): Promise> { - // return this.connection.getRecentPerformanceSamples(limit); - // } - - // async getFeeCalculatorForBlockhash( - // blockhash: Blockhash, - // commitment?: Commitment, - // ): Promise> { - // return this.connection.getFeeCalculatorForBlockhash( - // blockhash, - // commitment, - // ); - // } - - // async getFeeForMessage( - // message: VersionedMessage, - // commitment?: Commitment, - // ): Promise> { - // return this.connection.getFeeForMessage(message, commitment); - // } - - // async getMinimumBalanceForRentExemption( - // dataLength: number, - // commitment?: Commitment, - // ): Promise { - // return this.connection.getMinimumBalanceForRentExemption( - // dataLength, - // commitment, - // ); - // } - - // async getRecentBlockhash( - // commitment?: Commitment, - // ): Promise<{ blockhash: Blockhash; feeCalculator: FeeCalculator }> { - // return this.connection.getRecentBlockhash(commitment); - // } - - // async getGenesisHash(): Promise { - // return this.connection.getGenesisHash(); - // } - // async getBlock( - // slot: number, - // rawConfig?: GetVersionedBlockConfig, - // ): Promise; - // async getBlock( - // slot: number, - // rawConfig: GetVersionedBlockConfig & { transactionDetails: 'accounts' }, - // ): Promise; - // async getBlock( - // slot: number, - // rawConfig: GetVersionedBlockConfig & { transactionDetails: 'none' }, - // ): Promise; - // async getBlock( - // slot: number, - // rawConfig?: GetVersionedBlockConfig, - // ): Promise< - // | VersionedBlockResponse - // | VersionedAccountsModeBlockResponse - // | VersionedNoneModeBlockResponse - // | null - // > { - // return this.connection.getBlock(slot, rawConfig); - // } - - // async getParsedBlock( - // slot: number, - // rawConfig?: GetVersionedBlockConfig, - // ): Promise; - // async getParsedBlock( - // slot: number, - // rawConfig: GetVersionedBlockConfig & { transactionDetails: 'accounts' }, - // ): Promise; - // async getParsedBlock( - // slot: number, - // rawConfig: GetVersionedBlockConfig & { transactionDetails: 'none' }, - // ): Promise; - // async getParsedBlock( - // slot: number, - // rawConfig?: GetVersionedBlockConfig, - // ): Promise< - // ParsedAccountsModeBlockResponse | ParsedNoneModeBlockResponse | null - // > { - // return this.connection.getParsedBlock(slot, rawConfig); - // } - - // async getConfirmedTransaction( - // signature: TransactionSignature, - // commitment?: Finality, - // ): Promise { - // return this.connection.getConfirmedTransaction(signature, commitment); - // } - - // async getParsedConfirmedTransaction( - // signature: TransactionSignature, - // commitment?: Finality, - // ): Promise { - // return this.connection.getParsedConfirmedTransaction( - // signature, - // commitment, - // ); - // } - - // async getParsedConfirmedTransactions( - // signatures: TransactionSignature[], - // commitment?: Finality, - // ): Promise<(ParsedConfirmedTransaction | null)[]> { - // return this.connection.getParsedConfirmedTransactions( - // signatures, - // commitment, - // ); - // } - - // async getConfirmedSignaturesForAddress( - // address: PublicKey, - // startSlot: number, - // endSlot: number, - // ): Promise> { - // return this.connection.getConfirmedSignaturesForAddress( - // address, - // startSlot, - // endSlot, - // ); - // } - - // async getConfirmedSignaturesForAddress2( - // address: PublicKey, - // options?: ConfirmedSignaturesForAddress2Options, - // commitment?: Finality, - // ): Promise> { - // return this.connection.getConfirmedSignaturesForAddress2( - // address, - // options, - // commitment, - // ); - // } - - // async getSignaturesForAddress( - // address: PublicKey, - // options?: SignaturesForAddressOptions, - // commitment?: Finality, - // ): Promise> { - // return this.connection.getSignaturesForAddress( - // address, - // options, - // commitment, - // ); - // } - - // async getRecentPrioritizationFees( - // config?: GetRecentPrioritizationFeesConfig, - // ): Promise { - // return this.connection.getRecentPrioritizationFees(config); - // } - - // async getLatestBlockhash( - // config?: GetLatestBlockhashConfig, - // ): Promise { - // return this.connection.getLatestBlockhash(config); - // } - // async getLatestBlockhashAndContext( - // commitmentOrConfig?: Commitment | GetLatestBlockhashConfig, - // ): Promise> { - // return this.connection.getLatestBlockhashAndContext(commitmentOrConfig); - // } - - // async isBlockhashValid( - // blockhash: Blockhash, - // config?: IsBlockhashValidConfig, - // ): Promise> { - // return this.connection.isBlockhashValid(blockhash, config); - // } - - // async getVersion(): Promise { - // return this.connection.getVersion(); - // } - - // async getAddressLookupTable( - // accountKey: PublicKey, - // config?: GetAccountInfoConfig, - // ): Promise> { - // return this.connection.getAddressLookupTable(accountKey, config); - // } - - // async getNonceAndContext( - // nonceAccount: PublicKey, - // commitmentOrConfig?: Commitment | GetNonceAndContextConfig, - // ): Promise> { - // return this.connection.getNonceAndContext( - // nonceAccount, - // commitmentOrConfig, - // ); - // } - - // async getNonce( - // nonceAccount: PublicKey, - // commitmentOrConfig?: Commitment | GetNonceConfig, - // ): Promise { - // return this.connection.getNonce(nonceAccount, commitmentOrConfig); - // } - /** * Fetch the compressed account for the specified account address or hash */ diff --git a/js/stateless.js/src/test-helpers/test-rpc/test-rpc.ts b/js/stateless.js/src/test-helpers/test-rpc/test-rpc.ts index 7547a4efdf..eab1e6b554 100644 --- a/js/stateless.js/src/test-helpers/test-rpc/test-rpc.ts +++ b/js/stateless.js/src/test-helpers/test-rpc/test-rpc.ts @@ -26,7 +26,6 @@ import { SignatureWithMetadata, WithContext, WithCursor, - BaseRpc, } from '../../rpc-interface'; import { CompressedProofWithContext, @@ -207,811 +206,6 @@ export class TestRpc extends Connection implements CompressionApiInterface { this.log = log ?? false; } - // get commitment(): Commitment | undefined { - // return this.connection.commitment; - // } - - // get rpcEndpoint(): string { - // return this.connection.rpcEndpoint; - // } - - // // === Connection Methods Delegated === - - // async getBalanceAndContext( - // publicKey: PublicKey, - // commitmentOrConfig?: Commitment | GetBalanceConfig, - // ): Promise> { - // return this.connection.getBalanceAndContext( - // publicKey, - // commitmentOrConfig, - // ); - // } - - // async getBalance( - // publicKey: PublicKey, - // commitmentOrConfig?: Commitment | GetBalanceConfig, - // ): Promise { - // return this.connection.getBalance(publicKey, commitmentOrConfig); - // } - - // async getBlockTime(slot: number): Promise { - // return this.connection.getBlockTime(slot); - // } - - // async getMinimumLedgerSlot(): Promise { - // return this.connection.getMinimumLedgerSlot(); - // } - - // async getFirstAvailableBlock(): Promise { - // return this.connection.getFirstAvailableBlock(); - // } - - // async getSupply( - // config?: GetSupplyConfig | Commitment, - // ): Promise> { - // return this.connection.getSupply(config); - // } - - // async getTokenSupply( - // tokenMintAddress: PublicKey, - // commitment?: Commitment, - // ): Promise> { - // return this.connection.getTokenSupply(tokenMintAddress, commitment); - // } - - // async getTokenAccountBalance( - // tokenAddress: PublicKey, - // commitment?: Commitment, - // ): Promise> { - // return this.connection.getTokenAccountBalance(tokenAddress, commitment); - // } - - // async getTokenAccountsByOwner( - // ownerAddress: PublicKey, - // filter: TokenAccountsFilter, - // commitmentOrConfig?: Commitment | GetTokenAccountsByOwnerConfig, - // ): Promise> { - // return this.connection.getTokenAccountsByOwner( - // ownerAddress, - // filter, - // commitmentOrConfig, - // ); - // } - - // async getParsedTokenAccountsByOwner( - // ownerAddress: PublicKey, - // filter: TokenAccountsFilter, - // commitment?: Commitment, - // ): Promise< - // RpcResponseAndContext< - // Array<{ - // pubkey: PublicKey; - // account: AccountInfo; - // }> - // > - // > { - // return this.connection.getParsedTokenAccountsByOwner( - // ownerAddress, - // filter, - // commitment, - // ); - // } - - // async getLargestAccounts( - // config?: GetLargestAccountsConfig, - // ): Promise>> { - // return this.connection.getLargestAccounts(config); - // } - - // async getTokenLargestAccounts( - // mintAddress: PublicKey, - // commitment?: Commitment, - // ): Promise>> { - // return this.connection.getTokenLargestAccounts(mintAddress, commitment); - // } - - // async getAccountInfoAndContext( - // publicKey: PublicKey, - // commitmentOrConfig?: Commitment | GetAccountInfoConfig, - // ): Promise | null>> { - // return this.connection.getAccountInfoAndContext( - // publicKey, - // commitmentOrConfig, - // ); - // } - - // async getParsedAccountInfo( - // publicKey: PublicKey, - // commitmentOrConfig?: Commitment | GetAccountInfoConfig, - // ): Promise< - // RpcResponseAndContext | null> - // > { - // return this.connection.getParsedAccountInfo( - // publicKey, - // commitmentOrConfig, - // ); - // } - - // async getAccountInfo( - // publicKey: PublicKey, - // commitmentOrConfig?: Commitment | GetAccountInfoConfig, - // ): Promise | null> { - // return this.connection.getAccountInfo(publicKey, commitmentOrConfig); - // } - - // async getMultipleParsedAccounts( - // publicKeys: PublicKey[], - // rawConfig?: GetMultipleAccountsConfig, - // ): Promise< - // RpcResponseAndContext< - // (AccountInfo | null)[] - // > - // > { - // return this.connection.getMultipleParsedAccounts(publicKeys, rawConfig); - // } - - // async getMultipleAccountsInfoAndContext( - // publicKeys: PublicKey[], - // commitmentOrConfig?: Commitment | GetMultipleAccountsConfig, - // ): Promise | null)[]>> { - // return this.connection.getMultipleAccountsInfoAndContext( - // publicKeys, - // commitmentOrConfig, - // ); - // } - - // async getMultipleAccountsInfo( - // publicKeys: PublicKey[], - // commitmentOrConfig?: Commitment | GetMultipleAccountsConfig, - // ): Promise<(AccountInfo | null)[]> { - // return this.connection.getMultipleAccountsInfo( - // publicKeys, - // commitmentOrConfig, - // ); - // } - - // async getStakeActivation( - // publicKey: PublicKey, - // commitmentOrConfig?: Commitment | GetStakeActivationConfig, - // epoch?: number, - // ): Promise { - // return this.connection.getStakeActivation( - // publicKey, - // commitmentOrConfig, - // epoch, - // ); - // } - - // async getProgramAccounts( - // programId: PublicKey, - // configOrCommitment?: GetProgramAccountsConfig | Commitment, - // ): Promise; - - // async getProgramAccounts( - // programId: PublicKey, - // configOrCommitment: GetProgramAccountsConfig & { withContext: true }, - // ): Promise>; - - // async getProgramAccounts( - // programId: PublicKey, - // configOrCommitment?: GetProgramAccountsConfig | Commitment, - // ): Promise< - // | GetProgramAccountsResponse - // | RpcResponseAndContext - // > { - // return this.connection.getProgramAccounts( - // programId, - // configOrCommitment, - // ); - // } - - // async getParsedProgramAccounts( - // programId: PublicKey, - // configOrCommitment?: GetParsedProgramAccountsConfig | Commitment, - // ): Promise< - // Array<{ - // pubkey: PublicKey; - // account: AccountInfo; - // }> - // > { - // return this.connection.getParsedProgramAccounts( - // programId, - // configOrCommitment, - // ); - // } - - // // === Subscription Methods === - - // onAccountChange( - // publicKey: PublicKey, - // callback: AccountChangeCallback, - // config?: AccountSubscriptionConfig, - // ): ClientSubscriptionId { - // return this.connection.onAccountChange(publicKey, callback, config); - // } - - // async removeAccountChangeListener( - // clientSubscriptionId: ClientSubscriptionId, - // ): Promise { - // return this.connection.removeAccountChangeListener( - // clientSubscriptionId, - // ); - // } - - // onProgramAccountChange( - // programId: PublicKey, - // callback: ProgramAccountChangeCallback, - // config?: ProgramAccountSubscriptionConfig, - // ): ClientSubscriptionId { - // return this.connection.onProgramAccountChange( - // programId, - // callback, - // config, - // ); - // } - - // async removeProgramAccountChangeListener( - // clientSubscriptionId: ClientSubscriptionId, - // ): Promise { - // return this.connection.removeProgramAccountChangeListener( - // clientSubscriptionId, - // ); - // } - - // onLogs( - // filter: LogsFilter, - // callback: LogsCallback, - // commitment?: Commitment, - // ): ClientSubscriptionId { - // return this.connection.onLogs(filter, callback, commitment); - // } - - // async removeOnLogsListener( - // clientSubscriptionId: ClientSubscriptionId, - // ): Promise { - // return this.connection.removeOnLogsListener(clientSubscriptionId); - // } - - // onSlotChange(callback: SlotChangeCallback): ClientSubscriptionId { - // return this.connection.onSlotChange(callback); - // } - - // async removeSlotChangeListener( - // clientSubscriptionId: ClientSubscriptionId, - // ): Promise { - // return this.connection.removeSlotChangeListener(clientSubscriptionId); - // } - - // onSlotUpdate(callback: SlotUpdateCallback): ClientSubscriptionId { - // return this.connection.onSlotUpdate(callback); - // } - - // async removeSlotUpdateListener( - // clientSubscriptionId: ClientSubscriptionId, - // ): Promise { - // return this.connection.removeSlotUpdateListener(clientSubscriptionId); - // } - - // onSignature( - // signature: TransactionSignature, - // callback: SignatureResultCallback, - // commitment?: Commitment, - // ): ClientSubscriptionId { - // return this.connection.onSignature(signature, callback, commitment); - // } - - // onSignatureWithOptions( - // signature: TransactionSignature, - // callback: SignatureSubscriptionCallback, - // options?: SignatureSubscriptionOptions, - // ): ClientSubscriptionId { - // return this.connection.onSignatureWithOptions( - // signature, - // callback, - // options, - // ); - // } - - // async removeSignatureListener( - // clientSubscriptionId: ClientSubscriptionId, - // ): Promise { - // return this.connection.removeSignatureListener(clientSubscriptionId); - // } - - // onRootChange(callback: RootChangeCallback): ClientSubscriptionId { - // return this.connection.onRootChange(callback); - // } - - // async removeRootChangeListener( - // clientSubscriptionId: ClientSubscriptionId, - // ): Promise { - // return this.connection.removeRootChangeListener(clientSubscriptionId); - // } - - // // === Transaction Methods === - - // async sendTransaction( - // transaction: VersionedTransaction, - // options?: SendOptions, - // ): Promise { - // return this.connection.sendTransaction(transaction, options); - // } - - // async sendRawTransaction( - // rawTransaction: Buffer | Uint8Array | Array, - // options?: SendOptions, - // ): Promise { - // return this.connection.sendRawTransaction(rawTransaction, options); - // } - - // async sendEncodedTransaction( - // encodedTransaction: string, - // options?: SendOptions, - // ): Promise { - // return this.connection.sendEncodedTransaction( - // encodedTransaction, - // options, - // ); - // } - - // async simulateTransaction( - // transaction: VersionedTransaction, - // config?: SimulateTransactionConfig, - // ): Promise> { - // return this.connection.simulateTransaction(transaction, config); - // } - - // async requestAirdrop( - // to: PublicKey, - // lamports: number, - // ): Promise { - // return this.connection.requestAirdrop(to, lamports); - // } - - // async getStakeMinimumDelegation( - // config?: GetStakeMinimumDelegationConfig, - // ): Promise> { - // return this.connection.getStakeMinimumDelegation(config); - // } - - // async getTransactions( - // signatures: TransactionSignature[], - // commitmentOrConfig?: GetTransactionConfig | Finality, - // ): Promise<(VersionedTransactionResponse | null)[]> { - // return this.connection.getTransactions(signatures, commitmentOrConfig); - // } - - // async getTransaction( - // signature: string, - // rawConfig?: GetTransactionConfig, - // ): Promise { - // return this.connection.getTransaction(signature, rawConfig); - // } - - // async getParsedTransaction( - // signature: TransactionSignature, - // commitmentOrConfig?: GetVersionedTransactionConfig | Finality, - // ): Promise { - // return this.connection.getParsedTransaction( - // signature, - // commitmentOrConfig, - // ); - // } - - // async getParsedTransactions( - // signatures: TransactionSignature[], - // commitmentOrConfig?: GetVersionedTransactionConfig | Finality, - // ): Promise<(ParsedTransactionWithMeta | null)[]> { - // return this.connection.getParsedTransactions( - // signatures, - // commitmentOrConfig, - // ); - // } - - // async getConfirmedBlock( - // slot: number, - // commitment?: Finality, - // ): Promise { - // return this.connection.getConfirmedBlock(slot, commitment); - // } - - // async getBlocks( - // startSlot: number, - // endSlot?: number, - // commitment?: Finality, - // ): Promise> { - // return this.connection.getBlocks(startSlot, endSlot, commitment); - // } - - // async getBlockSignatures( - // slot: number, - // commitment?: Finality, - // ): Promise { - // return this.connection.getBlockSignatures(slot, commitment); - // } - - // async getConfirmedBlockSignatures( - // slot: number, - // commitment?: Finality, - // ): Promise { - // return this.connection.getConfirmedBlockSignatures(slot, commitment); - // } - - // confirmTransaction( - // strategy: TransactionConfirmationStrategy, - // commitment?: Commitment, - // ): Promise>; - - // /** @deprecated Instead, call `confirmTransaction` and pass in {@link TransactionConfirmationStrategy} */ - // // eslint-disable-next-line no-dupe-class-members - // confirmTransaction( - // strategy: TransactionSignature, - // commitment?: Commitment, - // ): Promise>; - - // async confirmTransaction( - // strategy: TransactionConfirmationStrategy | TransactionSignature, - // commitment?: Commitment, - // ): Promise> { - // // @ts-ignore - // return this.connection.confirmTransaction(strategy, commitment); - // } - - // async getClusterNodes(): Promise> { - // return this.connection.getClusterNodes(); - // } - - // async getVoteAccounts(commitment?: Commitment): Promise { - // return this.connection.getVoteAccounts(commitment); - // } - - // async getSlot( - // commitmentOrConfig?: Commitment | GetSlotConfig, - // ): Promise { - // return this.connection.getSlot(commitmentOrConfig); - // } - - // async getSlotLeader( - // commitmentOrConfig?: Commitment | GetSlotLeaderConfig, - // ): Promise { - // return this.connection.getSlotLeader(commitmentOrConfig); - // } - - // async getSlotLeaders( - // startSlot: number, - // limit: number, - // ): Promise> { - // return this.connection.getSlotLeaders(startSlot, limit); - // } - - // async getSignatureStatus( - // signature: TransactionSignature, - // config?: SignatureStatusConfig, - // ): Promise> { - // return this.connection.getSignatureStatus(signature, config); - // } - - // async getSignatureStatuses( - // signatures: Array, - // config?: SignatureStatusConfig, - // ): Promise>> { - // return this.connection.getSignatureStatuses(signatures, config); - // } - - // async getTotalSupply(commitment?: Commitment): Promise { - // return this.connection.getTotalSupply(commitment); - // } - - // async getBlockHeight(config?: GetBlockHeightConfig): Promise { - // return this.connection.getBlockHeight(config); - // } - - // async getBlockProduction( - // configOrCommitment?: GetBlockProductionConfig | Commitment, - // ): Promise> { - // return this.connection.getBlockProduction(configOrCommitment); - // } - - // async getTransactionCount( - // config?: GetTransactionCountConfig, - // ): Promise { - // return this.connection.getTransactionCount(config); - // } - - // async getInflationGovernor(): Promise { - // return this.connection.getInflationGovernor(); - // } - - // async getInflationReward( - // addresses: PublicKey[], - // epochs?: number, - // config?: GetInflationRewardConfig, - // ): Promise> { - // return this.connection.getInflationReward(addresses, epochs, config); - // } - - // async getInflationRate(): Promise { - // return this.connection.getInflationRate(); - // } - - // async getEpochInfo(config?: GetEpochInfoConfig): Promise { - // return this.connection.getEpochInfo(config); - // } - - // async getEpochSchedule(): Promise { - // return this.connection.getEpochSchedule(); - // } - - // async getLeaderSchedule(): Promise { - // return this.connection.getLeaderSchedule(); - // } - - // async getRecentBlockhashAndContext(commitment?: Commitment): Promise< - // RpcResponseAndContext<{ - // blockhash: Blockhash; - // feeCalculator: FeeCalculator; - // }> - // > { - // return this.connection.getRecentBlockhashAndContext(commitment); - // } - - // async getRecentPerformanceSamples( - // limit?: number, - // ): Promise> { - // return this.connection.getRecentPerformanceSamples(limit); - // } - - // async getFeeCalculatorForBlockhash( - // blockhash: Blockhash, - // commitment?: Commitment, - // ): Promise> { - // return this.connection.getFeeCalculatorForBlockhash( - // blockhash, - // commitment, - // ); - // } - - // async getFeeForMessage( - // message: VersionedMessage, - // commitment?: Commitment, - // ): Promise> { - // return this.connection.getFeeForMessage(message, commitment); - // } - - // async getMinimumBalanceForRentExemption( - // dataLength: number, - // commitment?: Commitment, - // ): Promise { - // return this.connection.getMinimumBalanceForRentExemption( - // dataLength, - // commitment, - // ); - // } - - // async getRecentBlockhash( - // commitment?: Commitment, - // ): Promise<{ blockhash: Blockhash; feeCalculator: FeeCalculator }> { - // return this.connection.getRecentBlockhash(commitment); - // } - - // async getGenesisHash(): Promise { - // return this.connection.getGenesisHash(); - // } - // async getBlock( - // slot: number, - // rawConfig?: GetVersionedBlockConfig, - // ): Promise; - // async getBlock( - // slot: number, - // rawConfig: GetVersionedBlockConfig & { transactionDetails: 'accounts' }, - // ): Promise; - // async getBlock( - // slot: number, - // rawConfig: GetVersionedBlockConfig & { transactionDetails: 'none' }, - // ): Promise; - // async getBlock( - // slot: number, - // rawConfig?: GetVersionedBlockConfig, - // ): Promise< - // | VersionedBlockResponse - // | VersionedAccountsModeBlockResponse - // | VersionedNoneModeBlockResponse - // | null - // > { - // return this.connection.getBlock(slot, rawConfig); - // } - - // async getParsedBlock( - // slot: number, - // rawConfig?: GetVersionedBlockConfig, - // ): Promise; - // async getParsedBlock( - // slot: number, - // rawConfig: GetVersionedBlockConfig & { transactionDetails: 'accounts' }, - // ): Promise; - // async getParsedBlock( - // slot: number, - // rawConfig: GetVersionedBlockConfig & { transactionDetails: 'none' }, - // ): Promise; - // async getParsedBlock( - // slot: number, - // rawConfig?: GetVersionedBlockConfig, - // ): Promise< - // ParsedAccountsModeBlockResponse | ParsedNoneModeBlockResponse | null - // > { - // return this.connection.getParsedBlock(slot, rawConfig); - // } - - // async getConfirmedTransaction( - // signature: TransactionSignature, - // commitment?: Finality, - // ): Promise { - // return this.connection.getConfirmedTransaction(signature, commitment); - // } - - // async getParsedConfirmedTransaction( - // signature: TransactionSignature, - // commitment?: Finality, - // ): Promise { - // return this.connection.getParsedConfirmedTransaction( - // signature, - // commitment, - // ); - // } - - // async getParsedConfirmedTransactions( - // signatures: TransactionSignature[], - // commitment?: Finality, - // ): Promise<(ParsedConfirmedTransaction | null)[]> { - // return this.connection.getParsedConfirmedTransactions( - // signatures, - // commitment, - // ); - // } - - // async getConfirmedSignaturesForAddress( - // address: PublicKey, - // startSlot: number, - // endSlot: number, - // ): Promise> { - // return this.connection.getConfirmedSignaturesForAddress( - // address, - // startSlot, - // endSlot, - // ); - // } - - // async getConfirmedSignaturesForAddress2( - // address: PublicKey, - // options?: ConfirmedSignaturesForAddress2Options, - // commitment?: Finality, - // ): Promise> { - // return this.connection.getConfirmedSignaturesForAddress2( - // address, - // options, - // commitment, - // ); - // } - - // async getSignaturesForAddress( - // address: PublicKey, - // options?: SignaturesForAddressOptions, - // commitment?: Finality, - // ): Promise> { - // return this.connection.getSignaturesForAddress( - // address, - // options, - // commitment, - // ); - // } - - // async getRecentPrioritizationFees( - // config?: GetRecentPrioritizationFeesConfig, - // ): Promise { - // return this.connection.getRecentPrioritizationFees(config); - // } - - // async getLatestBlockhash( - // config?: GetLatestBlockhashConfig, - // ): Promise { - // return this.connection.getLatestBlockhash(config); - // } - // async getLatestBlockhashAndContext( - // commitmentOrConfig?: Commitment | GetLatestBlockhashConfig, - // ): Promise> { - // return this.connection.getLatestBlockhashAndContext(commitmentOrConfig); - // } - - // async isBlockhashValid( - // blockhash: Blockhash, - // config?: IsBlockhashValidConfig, - // ): Promise> { - // return this.connection.isBlockhashValid(blockhash, config); - // } - - // async getVersion(): Promise { - // return this.connection.getVersion(); - // } - - // async getAddressLookupTable( - // accountKey: PublicKey, - // config?: GetAccountInfoConfig, - // ): Promise> { - // return this.connection.getAddressLookupTable(accountKey, config); - // } - - // async getNonceAndContext( - // nonceAccount: PublicKey, - // commitmentOrConfig?: Commitment | GetNonceAndContextConfig, - // ): Promise> { - // return this.connection.getNonceAndContext( - // nonceAccount, - // commitmentOrConfig, - // ); - // } - - // async getNonce( - // nonceAccount: PublicKey, - // commitmentOrConfig?: Commitment | GetNonceConfig, - // ): Promise { - // return this.connection.getNonce(nonceAccount, commitmentOrConfig); - // } - - // _buildArgs( - // args: Array, - // override?: Commitment, - // encoding?: 'jsonParsed' | 'base64', - // extra?: any, - // ): Array { - // const commitment = override || this.connection.commitment; - // if (commitment || encoding || extra) { - // let options: any = {}; - // if (encoding) { - // options.encoding = encoding; - // } - // if (commitment) { - // options.commitment = commitment; - // } - // if (extra) { - // options = Object.assign(options, extra); - // } - // args.push(options); - // } - // return args; - // } - - // private async getCancellationPromise() { - // throw new Error( - // 'getCancellationPromise not supported in rpc. it is a stub that is marked as private in web3.js Connection', - // ); - // } - // private async getTransactionConfirmationPromise() { - // throw new Error( - // 'getTransactionConfirmationPromise not supported in rpc. it is a stub that is marked as private in web3.js Connection', - // ); - // } - // private async confirmTransactionUsingBlockHeightExceedanceStrategy() { - // throw new Error( - // 'confirmTransactionUsingBlockHeightExceedanceStrategy not supported in rpc. it is a stub that is marked as private in web3.js Connection', - // ); - // } - // async confirmTransactionUsingDurableNonceStrategy() { - // throw new Error( - // 'confirmTransactionUsingDurableNonceStrategy not supported in rpc. it is a stub that is marked as private in web3.js Connection', - // ); - // } - // private async confirmTransactionUsingLegacyTimeoutStrategy({ - // commitment, - // signature, - // }: { - // commitment?: Commitment; - // signature: string; - // }): Promise> { - // throw new Error( - // 'confirmTransactionUsingLegacyTimeoutStrategy not supported in rpc. it is a stub that is marked as private in web3.js Connection', - // ); - // } - /** * Fetch the compressed account for the specified account hash */ diff --git a/js/stateless.js/tests/e2e/serde.test.ts b/js/stateless.js/tests/e2e/serde.test.ts index 7bf6e59a71..b37111c445 100644 --- a/js/stateless.js/tests/e2e/serde.test.ts +++ b/js/stateless.js/tests/e2e/serde.test.ts @@ -1,27 +1,7 @@ import { describe, it, expect } from 'vitest'; -import { PublicTransactionEvent, bn } from '../../src'; -import { - CompressedAccountLayout, - decodePublicTransactionEvent, -} from '../../src/programs/layout'; +import { decodePublicTransactionEvent } from '../../src/programs/layout'; describe('serde', () => { - // it('decode output compressed account', async () => { - // const compressedAccount = [ - // 88, 8, 48, 185, 124, 227, 14, 195, 230, 152, 61, 39, 56, 191, 13, - // 126, 54, 43, 47, 131, 175, 16, 52, 167, 129, 174, 200, 118, 174, 9, - // 254, 80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - // ]; - - // const deserializedCompressedAccount = CompressedAccountLayout.decode( - // Buffer.from(compressedAccount), - // ); - - // expect(deserializedCompressedAccount.data).toBe(null); - // expect(deserializedCompressedAccount.address).toBe(null); - // expect(deserializedCompressedAccount.lamports.eq(bn(0))).toBe(true); - // }); - it('decode event', async () => { const data = [ 0, 0, 0, 0, 1, 0, 0, 0, 33, 32, 204, 221, 5, 83, 170, 139, 228, 191, From 6e83ceefa0372142f276b62ce0eeabe4e2a730f8 Mon Sep 17 00:00:00 2001 From: Swenschaeferjohann Date: Sat, 4 Jan 2025 22:13:59 +0000 Subject: [PATCH 04/19] clean --- js/stateless.js/src/rpc.ts | 13 ------------- .../src/test-helpers/test-rpc/test-rpc.ts | 5 ----- 2 files changed, 18 deletions(-) diff --git a/js/stateless.js/src/rpc.ts b/js/stateless.js/src/rpc.ts index 6f4f483d93..3cc1e66666 100644 --- a/js/stateless.js/src/rpc.ts +++ b/js/stateless.js/src/rpc.ts @@ -61,17 +61,6 @@ import { defaultTestStateTreeAccounts } from './constants'; import BN from 'bn.js'; import { toCamelCase, toHex } from './utils/conversion'; -type ClientSubscriptionId = number; - -// // Define an interface that includes the methods you need from Connection -// interface ConnectionInterface { -// sendTransaction(transaction: any, options?: any): Promise; -// getLatestBlockhash(): Promise; -// confirmTransaction(signature: string, commitment?: string): Promise; -// commitment: string; -// // Add other methods and properties as needed -// } - import { proofFromJsonStruct, negateAndCompressProof, @@ -507,7 +496,6 @@ const mockAddressQueue = defaultTestStateTreeAccounts().addressQueue; * */ export class Rpc extends Connection implements CompressionApiInterface { - // connection: Connection; compressionApiEndpoint: string; proverEndpoint: string; @@ -527,7 +515,6 @@ export class Rpc extends Connection implements CompressionApiInterface { ) { super(endpoint, config || 'confirmed'); - // this.connection = new Connection(endpoint, config || 'confirmed'); this.compressionApiEndpoint = compressionApiEndpoint; this.proverEndpoint = proverEndpoint; } diff --git a/js/stateless.js/src/test-helpers/test-rpc/test-rpc.ts b/js/stateless.js/src/test-helpers/test-rpc/test-rpc.ts index eab1e6b554..89cc956ccd 100644 --- a/js/stateless.js/src/test-helpers/test-rpc/test-rpc.ts +++ b/js/stateless.js/src/test-helpers/test-rpc/test-rpc.ts @@ -140,7 +140,6 @@ export async function getTestRpc( * For advanced testing use photon: https://github.com/helius-labs/photon */ export class TestRpc extends Connection implements CompressionApiInterface { - // connection: Connection; compressionApiEndpoint: string; proverEndpoint: string; merkleTreeAddress: PublicKey; @@ -173,10 +172,6 @@ export class TestRpc extends Connection implements CompressionApiInterface { ) { super(endpoint, connectionConfig || 'confirmed'); - // this.connection = new Connection( - // endpoint, - // connectionConfig || 'confirmed', - // ); this.compressionApiEndpoint = compressionApiEndpoint; this.proverEndpoint = proverEndpoint; From 336f27e1306633c8bc51f220e5dca421995a95e6 Mon Sep 17 00:00:00 2001 From: Swenschaeferjohann Date: Sun, 5 Jan 2025 17:06:55 +0000 Subject: [PATCH 05/19] clean layout, add unit tests --- js/compressed-token/src/constants.ts | 13 + js/compressed-token/src/index.ts | 1 + js/compressed-token/src/layout.ts | 488 ++++++------------ js/compressed-token/src/program.ts | 33 +- js/compressed-token/src/types.ts | 11 + js/compressed-token/tests/e2e/layout.test.ts | 168 +++++- js/stateless.js/package.json | 2 +- js/stateless.js/src/constants.ts | 4 + js/stateless.js/src/programs/layout.ts | 8 +- js/stateless.js/src/rpc.ts | 1 - .../src/test-helpers/test-rpc/test-rpc.ts | 13 +- js/stateless.js/src/utils/test-utils.ts | 49 ++ js/stateless.js/tests/e2e/layout.test.ts | 79 +++ js/stateless.js/tests/e2e/rpc-interop.test.ts | 10 +- js/stateless.js/tests/e2e/serde.test.ts | 30 -- 15 files changed, 489 insertions(+), 421 deletions(-) create mode 100644 js/stateless.js/tests/e2e/layout.test.ts delete mode 100644 js/stateless.js/tests/e2e/serde.test.ts diff --git a/js/compressed-token/src/constants.ts b/js/compressed-token/src/constants.ts index 2e741fa86a..74acb9e2ca 100644 --- a/js/compressed-token/src/constants.ts +++ b/js/compressed-token/src/constants.ts @@ -3,3 +3,16 @@ export const POOL_SEED = Buffer.from('pool'); export const CPI_AUTHORITY_SEED = Buffer.from('cpi_authority'); export const SPL_TOKEN_MINT_RENT_EXEMPT_BALANCE = 1461600; + +export const CREATE_TOKEN_POOL_DISCRIMINATOR = Buffer.from([ + 23, 169, 27, 122, 147, 169, 209, 152, +]); +export const MINT_TO_DISCRIMINATOR = Buffer.from([ + 241, 34, 48, 186, 37, 179, 123, 192, +]); +export const TRANSFER_DISCRIMINATOR = Buffer.from([ + 163, 52, 200, 231, 140, 3, 69, 186, +]); +export const COMPRESS_SPL_TOKEN_ACCOUNT_DISCRIMINATOR = Buffer.from([ + 112, 230, 105, 101, 145, 202, 157, 97, +]); diff --git a/js/compressed-token/src/index.ts b/js/compressed-token/src/index.ts index a2fa8b6c6b..1f8eed140c 100644 --- a/js/compressed-token/src/index.ts +++ b/js/compressed-token/src/index.ts @@ -3,3 +3,4 @@ export * from './constants'; export * from './program'; export * from './types'; export * from './actions'; +export * from './layout'; diff --git a/js/compressed-token/src/layout.ts b/js/compressed-token/src/layout.ts index e3a890cb2b..000bb8c853 100644 --- a/js/compressed-token/src/layout.ts +++ b/js/compressed-token/src/layout.ts @@ -12,18 +12,19 @@ import { vecU8, } from '@coral-xyz/borsh'; import { Buffer } from 'buffer'; - import { AccountMeta, PublicKey } from '@solana/web3.js'; import { CompressedTokenProgram } from './program'; -import BN from 'bn.js'; import { - CompressedCpiContext, CompressedTokenInstructionDataTransfer, + CompressSplTokenAccountInstructionData, + MintToInstructionData, } from './types'; +import { + COMPRESS_SPL_TOKEN_ACCOUNT_DISCRIMINATOR, + MINT_TO_DISCRIMINATOR, + TRANSFER_DISCRIMINATOR, +} from './constants'; -export const CREATE_TOKEN_POOL_DISCRIMINATOR = Buffer.from([ - 23, 169, 27, 122, 147, 169, 209, 152, -]); const CompressedProofLayout = struct([ array(u8(), 32, 'a'), array(u8(), 64, 'b'), @@ -92,44 +93,43 @@ export const compressSplTokenAccountInstructionDataLayout = struct([ option(CpiContextLayout, 'cpiContext'), ]); -const MINT_TO_DISCRIMINATOR = Buffer.from([ - 241, 34, 48, 186, 37, 179, 123, 192, -]); -export const TRANSFER_DISCRIMINATOR = Buffer.from([ - 163, 52, 200, 231, 140, 3, 69, 186, -]); export function encodeMintToInstructionData( - recipients: PublicKey[], - amounts: BN[], - lamports: BN | null, + data: MintToInstructionData, ): Buffer { const buffer = Buffer.alloc(1000); const len = mintToLayout.encode( { - recipients, - amounts, - lamports, + recipients: data.recipients, + amounts: data.amounts, + lamports: data.lamports, }, buffer, ); return Buffer.concat([MINT_TO_DISCRIMINATOR, buffer.slice(0, len)]); } -export const COMPRESS_SPL_TOKEN_ACCOUNT_DISCRIMINATOR = Buffer.from([ - 112, 230, 105, 101, 145, 202, 157, 97, -]); +export function decodeMintToInstructionData( + buffer: Buffer, +): MintToInstructionData { + const data: any = mintToLayout.decode( + buffer.slice(MINT_TO_DISCRIMINATOR.length), + ); + return { + recipients: data.recipients, + amounts: data.amounts, + lamports: data.lamports, + }; +} export function encodeCompressSplTokenAccountInstructionData( - owner: PublicKey, - remainingAmount: BN | null, - cpiContext: CompressedCpiContext | null, + data: CompressSplTokenAccountInstructionData, ): Buffer { const buffer = Buffer.alloc(1000); const len = compressSplTokenAccountInstructionDataLayout.encode( { - owner, - remainingAmount, - cpiContext, + owner: data.owner, + remainingAmount: data.remainingAmount, + cpiContext: data.cpiContext, }, buffer, ); @@ -139,7 +139,19 @@ export function encodeCompressSplTokenAccountInstructionData( ]); } -export function encodeCompressedTokenInstructionDataTransfer( +export function decodeCompressSplTokenAccountInstructionData( + buffer: Buffer, +): CompressSplTokenAccountInstructionData { + const data: any = compressSplTokenAccountInstructionDataLayout.decode( + buffer.slice(COMPRESS_SPL_TOKEN_ACCOUNT_DISCRIMINATOR.length), + ); + return { + owner: data.owner, + remainingAmount: data.remainingAmount, + cpiContext: data.cpiContext, + }; +} +export function encodeTransferInstructionData( data: CompressedTokenInstructionDataTransfer, ): Buffer { const buffer = Buffer.alloc(1000); @@ -159,6 +171,26 @@ export function encodeCompressedTokenInstructionDataTransfer( ]); } +export function decodeTransferInstructionData( + buffer: Buffer, +): CompressedTokenInstructionDataTransfer { + return CompressedTokenInstructionDataTransferLayout.decode( + buffer.slice(TRANSFER_DISCRIMINATOR.length + 4), + ) as CompressedTokenInstructionDataTransfer; +} + +interface BaseAccountsLayoutParams { + feePayer: PublicKey; + authority: PublicKey; + cpiAuthorityPda: PublicKey; + lightSystemProgram: PublicKey; + registeredProgramPda: PublicKey; + noopProgram: PublicKey; + accountCompressionAuthority: PublicKey; + accountCompressionProgram: PublicKey; + selfProgram: PublicKey; + systemProgram: PublicKey; +} export type createTokenPoolAccountsLayoutParams = { feePayer: PublicKey; tokenPoolPda: PublicKey; @@ -167,6 +199,24 @@ export type createTokenPoolAccountsLayoutParams = { tokenProgram: PublicKey; cpiAuthorityPda: PublicKey; }; +export type mintToAccountsLayoutParams = BaseAccountsLayoutParams & { + mint: PublicKey; + tokenPoolPda: PublicKey; + tokenProgram: PublicKey; + merkleTree: PublicKey; + solPoolPda: PublicKey | null; +}; +export type transferAccountsLayoutParams = BaseAccountsLayoutParams & { + tokenPoolPda?: PublicKey; + compressOrDecompressTokenAccount?: PublicKey; + tokenProgram?: PublicKey; +}; +export type approveAccountsLayoutParams = BaseAccountsLayoutParams; +export type revokeAccountsLayoutParams = approveAccountsLayoutParams; +export type freezeAccountsLayoutParams = BaseAccountsLayoutParams & { + mint: PublicKey; +}; +export type thawAccountsLayoutParams = freezeAccountsLayoutParams; export const createTokenPoolAccountsLayout = ( accounts: createTokenPoolAccountsLayoutParams, @@ -190,24 +240,6 @@ export const createTokenPoolAccountsLayout = ( ]; }; -export type mintToAccountsLayoutParams = { - feePayer: PublicKey; - authority: PublicKey; - cpiAuthorityPda: PublicKey; - mint: PublicKey; - tokenPoolPda: PublicKey; - tokenProgram: PublicKey; - lightSystemProgram: PublicKey; - registeredProgramPda: PublicKey; - noopProgram: PublicKey; - accountCompressionAuthority: PublicKey; - accountCompressionProgram: PublicKey; - merkleTree: PublicKey; - selfProgram: PublicKey; - systemProgram: PublicKey; - solPoolPda: PublicKey | null; -}; - export const mintToAccountsLayout = ( accounts: mintToAccountsLayoutParams, ): AccountMeta[] => { @@ -263,106 +295,6 @@ export const mintToAccountsLayout = ( return accountsList; }; -export type compressSplTokenAccountAccountsLayoutParams = { - feePayer: PublicKey; - authority: PublicKey; - cpiAuthorityPda: PublicKey; - lightSystemProgram: PublicKey; - registeredProgramPda: PublicKey; - noopProgram: PublicKey; - accountCompressionAuthority: PublicKey; - accountCompressionProgram: PublicKey; - selfProgram: PublicKey; - tokenPoolPda?: PublicKey; - compressOrDecompressTokenAccount?: PublicKey; - tokenProgram?: PublicKey; - systemProgram: PublicKey; -}; - -export const compressSplTokenAccountAccountsLayout = ( - accounts: compressSplTokenAccountAccountsLayoutParams, -): AccountMeta[] => { - const defaultPubkey = CompressedTokenProgram.programId; - const { - feePayer, - authority, - cpiAuthorityPda, - lightSystemProgram, - registeredProgramPda, - noopProgram, - accountCompressionAuthority, - accountCompressionProgram, - selfProgram, - tokenPoolPda, - compressOrDecompressTokenAccount, - tokenProgram, - systemProgram, - } = accounts; - - const accountsList: AccountMeta[] = [ - { pubkey: feePayer, isSigner: true, isWritable: true }, - { pubkey: authority, isSigner: true, isWritable: false }, - { pubkey: cpiAuthorityPda, isSigner: false, isWritable: false }, - { pubkey: lightSystemProgram, isSigner: false, isWritable: false }, - { pubkey: registeredProgramPda, isSigner: false, isWritable: false }, - { pubkey: noopProgram, isSigner: false, isWritable: false }, - { - pubkey: accountCompressionAuthority, - isSigner: false, - isWritable: false, - }, - { - pubkey: accountCompressionProgram, - isSigner: false, - isWritable: false, - }, - { pubkey: selfProgram, isSigner: false, isWritable: false }, - { - pubkey: tokenPoolPda ?? defaultPubkey, - isSigner: false, - isWritable: true, - }, - { - pubkey: compressOrDecompressTokenAccount ?? defaultPubkey, - isSigner: false, - isWritable: true, - }, - { - pubkey: tokenProgram ?? defaultPubkey, - isSigner: false, - isWritable: false, - }, - { pubkey: systemProgram, isSigner: false, isWritable: false }, - ]; - - return accountsList; -}; - -export const compressSplTokenAccountArgsLayout = struct( - [ - publicKey('owner'), - option(u64(), 'remainingAmount'), - option(struct([], 'CompressedCpiContext'), 'cpiContext'), - ], - 'compressSplTokenAccountArgs', -); - -export interface transferAccountsLayoutParams { - feePayer: PublicKey; - authority: PublicKey; - cpiAuthorityPda: PublicKey; - lightSystemProgram: PublicKey; - registeredProgramPda: PublicKey; - noopProgram: PublicKey; - accountCompressionAuthority: PublicKey; - accountCompressionProgram: PublicKey; - selfProgram: PublicKey; - tokenPoolPda?: PublicKey; - compressOrDecompressTokenAccount?: PublicKey; - tokenProgram?: PublicKey; - systemProgram: PublicKey; -} - export const transferAccountsLayout = ( accounts: transferAccountsLayoutParams, ): AccountMeta[] => { @@ -422,186 +354,84 @@ export const transferAccountsLayout = ( return accountsList; }; -export type compressSplTokenAccountLayoutParams = { - feePayer: PublicKey; - authority: PublicKey; - cpiAuthorityPda: PublicKey; - lightSystemProgram: PublicKey; - registeredProgramPda: PublicKey; - noopProgram: PublicKey; - accountCompressionAuthority: PublicKey; - accountCompressionProgram: PublicKey; - selfProgram: PublicKey; - tokenPoolPda?: PublicKey; - compressOrDecompressTokenAccount?: PublicKey; - tokenProgram?: PublicKey; - systemProgram: PublicKey; -}; - -export const compressSplTokenAccountLayout = ( - accounts: compressSplTokenAccountLayoutParams, -): AccountMeta[] => { - const defaultPubkey = CompressedTokenProgram.programId; - const { - feePayer, - authority, - cpiAuthorityPda, - lightSystemProgram, - registeredProgramPda, - noopProgram, - accountCompressionAuthority, - accountCompressionProgram, - selfProgram, - tokenPoolPda, - compressOrDecompressTokenAccount, - tokenProgram, - systemProgram, - } = accounts; - - return [ - { pubkey: feePayer, isSigner: true, isWritable: true }, - { pubkey: authority, isSigner: true, isWritable: false }, - { pubkey: cpiAuthorityPda, isSigner: false, isWritable: false }, - { pubkey: lightSystemProgram, isSigner: false, isWritable: false }, - { pubkey: registeredProgramPda, isSigner: false, isWritable: false }, - { pubkey: noopProgram, isSigner: false, isWritable: false }, - { - pubkey: accountCompressionAuthority, - isSigner: false, - isWritable: false, - }, - { - pubkey: accountCompressionProgram, - isSigner: false, - isWritable: false, - }, - { pubkey: selfProgram, isSigner: false, isWritable: false }, - { - pubkey: tokenPoolPda ?? defaultPubkey, - isSigner: false, - isWritable: true, - }, - { - pubkey: compressOrDecompressTokenAccount ?? defaultPubkey, - isSigner: false, - isWritable: true, - }, - { - pubkey: tokenProgram ?? defaultPubkey, - isSigner: false, - isWritable: false, - }, - { pubkey: systemProgram, isSigner: false, isWritable: false }, - ]; -}; - -export type approveAccountsLayoutParams = { - feePayer: PublicKey; - authority: PublicKey; - cpiAuthorityPda: PublicKey; - lightSystemProgram: PublicKey; - registeredProgramPda: PublicKey; - noopProgram: PublicKey; - accountCompressionAuthority: PublicKey; - accountCompressionProgram: PublicKey; - selfProgram: PublicKey; - systemProgram: PublicKey; -}; - -export const approveAccountsLayout = ( - accounts: approveAccountsLayoutParams, -): AccountMeta[] => { - const { - feePayer, - authority, - cpiAuthorityPda, - lightSystemProgram, - registeredProgramPda, - noopProgram, - accountCompressionAuthority, - accountCompressionProgram, - selfProgram, - systemProgram, - } = accounts; - - return [ - { pubkey: feePayer, isSigner: true, isWritable: true }, - { pubkey: authority, isSigner: true, isWritable: false }, - { pubkey: cpiAuthorityPda, isSigner: false, isWritable: false }, - { pubkey: lightSystemProgram, isSigner: false, isWritable: false }, - { pubkey: registeredProgramPda, isSigner: false, isWritable: false }, - { pubkey: noopProgram, isSigner: false, isWritable: false }, - { - pubkey: accountCompressionAuthority, - isSigner: false, - isWritable: false, - }, - { - pubkey: accountCompressionProgram, - isSigner: false, - isWritable: false, - }, - { pubkey: selfProgram, isSigner: false, isWritable: false }, - { pubkey: systemProgram, isSigner: false, isWritable: false }, - ]; -}; - -export type revokeAccountsLayoutParams = approveAccountsLayoutParams; -export const revokeAccountsLayout = approveAccountsLayout; - -export type freezeAccountsLayoutParams = { - feePayer: PublicKey; - authority: PublicKey; - cpiAuthorityPda: PublicKey; - lightSystemProgram: PublicKey; - registeredProgramPda: PublicKey; - noopProgram: PublicKey; - accountCompressionAuthority: PublicKey; - accountCompressionProgram: PublicKey; - selfProgram: PublicKey; - systemProgram: PublicKey; - mint: PublicKey; -}; - -export const freezeAccountsLayout = ( - accounts: freezeAccountsLayoutParams, -): AccountMeta[] => { - const { - feePayer, - authority, - cpiAuthorityPda, - lightSystemProgram, - registeredProgramPda, - noopProgram, - accountCompressionAuthority, - accountCompressionProgram, - selfProgram, - systemProgram, - mint, - } = accounts; - - return [ - { pubkey: feePayer, isSigner: true, isWritable: true }, - { pubkey: authority, isSigner: true, isWritable: false }, - { pubkey: cpiAuthorityPda, isSigner: false, isWritable: false }, - { pubkey: lightSystemProgram, isSigner: false, isWritable: false }, - { pubkey: registeredProgramPda, isSigner: false, isWritable: false }, - { pubkey: noopProgram, isSigner: false, isWritable: false }, - { - pubkey: accountCompressionAuthority, - isSigner: false, - isWritable: false, - }, - { - pubkey: accountCompressionProgram, - isSigner: false, - isWritable: false, - }, - { pubkey: selfProgram, isSigner: false, isWritable: false }, - { pubkey: systemProgram, isSigner: false, isWritable: false }, - { pubkey: mint, isSigner: false, isWritable: false }, - ]; -}; - -export type thawAccountsLayoutParams = freezeAccountsLayoutParams; -export const thawAccountsLayout = freezeAccountsLayout; +// export const approveAccountsLayout = ( +// accounts: approveAccountsLayoutParams, +// ): AccountMeta[] => { +// const { +// feePayer, +// authority, +// cpiAuthorityPda, +// lightSystemProgram, +// registeredProgramPda, +// noopProgram, +// accountCompressionAuthority, +// accountCompressionProgram, +// selfProgram, +// systemProgram, +// } = accounts; + +// return [ +// { pubkey: feePayer, isSigner: true, isWritable: true }, +// { pubkey: authority, isSigner: true, isWritable: false }, +// { pubkey: cpiAuthorityPda, isSigner: false, isWritable: false }, +// { pubkey: lightSystemProgram, isSigner: false, isWritable: false }, +// { pubkey: registeredProgramPda, isSigner: false, isWritable: false }, +// { pubkey: noopProgram, isSigner: false, isWritable: false }, +// { +// pubkey: accountCompressionAuthority, +// isSigner: false, +// isWritable: false, +// }, +// { +// pubkey: accountCompressionProgram, +// isSigner: false, +// isWritable: false, +// }, +// { pubkey: selfProgram, isSigner: false, isWritable: false }, +// { pubkey: systemProgram, isSigner: false, isWritable: false }, +// ]; +// }; + +// export const revokeAccountsLayout = approveAccountsLayout; + +// export const freezeAccountsLayout = ( +// accounts: freezeAccountsLayoutParams, +// ): AccountMeta[] => { +// const { +// feePayer, +// authority, +// cpiAuthorityPda, +// lightSystemProgram, +// registeredProgramPda, +// noopProgram, +// accountCompressionAuthority, +// accountCompressionProgram, +// selfProgram, +// systemProgram, +// mint, +// } = accounts; + +// return [ +// { pubkey: feePayer, isSigner: true, isWritable: true }, +// { pubkey: authority, isSigner: true, isWritable: false }, +// { pubkey: cpiAuthorityPda, isSigner: false, isWritable: false }, +// { pubkey: lightSystemProgram, isSigner: false, isWritable: false }, +// { pubkey: registeredProgramPda, isSigner: false, isWritable: false }, +// { pubkey: noopProgram, isSigner: false, isWritable: false }, +// { +// pubkey: accountCompressionAuthority, +// isSigner: false, +// isWritable: false, +// }, +// { +// pubkey: accountCompressionProgram, +// isSigner: false, +// isWritable: false, +// }, +// { pubkey: selfProgram, isSigner: false, isWritable: false }, +// { pubkey: systemProgram, isSigner: false, isWritable: false }, +// { pubkey: mint, isSigner: false, isWritable: false }, +// ]; +// }; + +// export const thawAccountsLayout = freezeAccountsLayout; diff --git a/js/compressed-token/src/program.ts b/js/compressed-token/src/program.ts index f77da8a55c..9fe622b488 100644 --- a/js/compressed-token/src/program.ts +++ b/js/compressed-token/src/program.ts @@ -26,14 +26,17 @@ import { createInitializeMint2Instruction, createMintToInstruction, } from '@solana/spl-token'; -import { CPI_AUTHORITY_SEED, POOL_SEED } from './constants'; -import { packCompressedTokenAccounts } from './instructions/pack-compressed-token-accounts'; import { + CPI_AUTHORITY_SEED, + POOL_SEED, CREATE_TOKEN_POOL_DISCRIMINATOR, - createTokenPoolAccountsLayout, - encodeCompressedTokenInstructionDataTransfer, +} from './constants'; +import { packCompressedTokenAccounts } from './instructions/pack-compressed-token-accounts'; +import { + encodeTransferInstructionData, encodeCompressSplTokenAccountInstructionData, encodeMintToInstructionData, + createTokenPoolAccountsLayout, mintToAccountsLayout, transferAccountsLayout, } from './layout'; @@ -671,7 +674,11 @@ export class CompressedTokenProgram { solPoolPda: null, // TODO: add lamports support }); - const data = encodeMintToInstructionData(toPubkeys, amounts, null); + const data = encodeMintToInstructionData({ + recipients: toPubkeys, + amounts, + lamports: null, + }); return new TransactionInstruction({ programId: this.programId, @@ -769,7 +776,7 @@ export class CompressedTokenProgram { lamportsChangeAccountMerkleTreeIndex: null, }; - const data = encodeCompressedTokenInstructionDataTransfer(rawData); + const data = encodeTransferInstructionData(rawData); const { accountCompressionAuthority, @@ -934,7 +941,7 @@ export class CompressedTokenProgram { lamportsChangeAccountMerkleTreeIndex: null, }; - const data = encodeCompressedTokenInstructionDataTransfer(rawData); + const data = encodeTransferInstructionData(rawData); const tokenProgram = tokenProgramId ?? TOKEN_PROGRAM_ID; @@ -1009,7 +1016,7 @@ export class CompressedTokenProgram { cpiContext: null, lamportsChangeAccountMerkleTreeIndex: null, }; - const data = encodeCompressedTokenInstructionDataTransfer(rawData); + const data = encodeTransferInstructionData(rawData); const tokenProgram = tokenProgramId ?? TOKEN_PROGRAM_ID; const { accountCompressionAuthority, @@ -1097,11 +1104,11 @@ export class CompressedTokenProgram { }, ]; - const data = encodeCompressSplTokenAccountInstructionData( - authority, - remainingAmount ?? null, - null, - ); + const data = encodeCompressSplTokenAccountInstructionData({ + owner: authority, + remainingAmount: remainingAmount ?? null, + cpiContext: null, + }); const { accountCompressionAuthority, noopProgram, diff --git a/js/compressed-token/src/types.ts b/js/compressed-token/src/types.ts index 8247dcee25..a8016585ed 100644 --- a/js/compressed-token/src/types.ts +++ b/js/compressed-token/src/types.ts @@ -68,6 +68,17 @@ export type DelegatedTransfer = { delegateChangeAccountIndex: number | null; }; +export type MintToInstructionData = { + recipients: PublicKey[]; + amounts: BN[]; + lamports: BN | null; +}; +export type CompressSplTokenAccountInstructionData = { + owner: PublicKey; + remainingAmount: BN | null; + cpiContext: CompressedCpiContext | null; +}; + export type CompressedTokenInstructionDataTransfer = { /** * Validity proof diff --git a/js/compressed-token/tests/e2e/layout.test.ts b/js/compressed-token/tests/e2e/layout.test.ts index c81baa02b0..78de4e59e8 100644 --- a/js/compressed-token/tests/e2e/layout.test.ts +++ b/js/compressed-token/tests/e2e/layout.test.ts @@ -3,12 +3,118 @@ import { PublicKey } from '@solana/web3.js'; import BN from 'bn.js'; import { CompressedTokenInstructionDataTransferLayout, - TRANSFER_DISCRIMINATOR, -} from '../../src/layout'; -import { CompressedTokenInstructionDataTransfer } from '../../../stateless.js/src'; + CompressedTokenInstructionDataTransfer, + mintToLayout, + compressSplTokenAccountInstructionDataLayout, + encodeMintToInstructionData, + decodeMintToInstructionData, + encodeCompressSplTokenAccountInstructionData, + decodeCompressSplTokenAccountInstructionData, + encodeTransferInstructionData, + decodeTransferInstructionData, + MintToInstructionData, + CompressSplTokenAccountInstructionData, +} from '../../src/'; + +function deepEqual(ref: any, val: any) { + if (typeof ref !== typeof val) { + console.log(`Type mismatch: ${typeof ref} !== ${typeof val}`); + return false; + } + + if (ref instanceof BN && val instanceof BN) { + return ref.eq(val); + } + + if (typeof ref === 'object' && ref !== null && val !== null) { + const refKeys = Object.keys(ref); + const valKeys = Object.keys(val); + + if (refKeys.length !== valKeys.length) { + console.log( + `Key length mismatch: ${refKeys.length} !== ${valKeys.length}`, + ); + return false; + } + + for (let key of refKeys) { + if (!valKeys.includes(key)) { + console.log(`Key ${key} not found in value`); + return false; + } + if (!deepEqual(ref[key], val[key])) { + console.log(`Value mismatch at key ${key}`); + return false; + } + } + return true; + } + + if (ref !== val) { + console.log(`Value mismatch: ${ref} !== ${val}`); + } + + return ref === val; +} describe('layout', () => { - it('encode CompressedTokenInstructionDataTransfer', () => { + it('encode/decode CompressedTokenInstructionDataTransfer', () => { + const data: CompressedTokenInstructionDataTransfer = { + proof: null, + mint: new PublicKey('CXzk7xBgfzwSrZincWbJPGMPFz8aut3V6JjXp5n3XvGQ'), + delegatedTransfer: null, + inputTokenDataWithContext: [], + outputCompressedAccounts: [ + { + owner: new PublicKey( + '7gpbzzu2Aj2sE7LFdEQKUoZLqxVAK3eQ9LoeKQ5zCxQJ', + ), + amount: new BN(700), + lamports: null, + merkleTreeIndex: 0, + tlv: null, + }, + ], + isCompress: true, + compressOrDecompressAmount: new BN(700), + cpiContext: null, + lamportsChangeAccountMerkleTreeIndex: null, + }; + + const encoded = encodeTransferInstructionData(data); + const decoded = decodeTransferInstructionData(encoded); + expect(deepEqual(decoded, data)).toBe(true); + }); + + it('encode/decode MintToInstructionData', () => { + const data = { + recipients: [ + new PublicKey('CXzk7xBgfzwSrZincWbJPGMPFz8aut3V6JjXp5n3XvGQ'), + ], + amounts: [new BN(1000)], + lamports: new BN(500), + }; + + const encoded = encodeMintToInstructionData(data); + const decoded = decodeMintToInstructionData(encoded); + expect(deepEqual(decoded, data)).toBe(true); + }); + + it('encode/decode CompressSplTokenAccountInstructionData', () => { + const data = { + owner: new PublicKey( + 'CXzk7xBgfzwSrZincWbJPGMPFz8aut3V6JjXp5n3XvGQ', + ), + remainingAmount: new BN(1000), + cpiContext: null, + }; + + const encoded = encodeCompressSplTokenAccountInstructionData(data); + const decoded = decodeCompressSplTokenAccountInstructionData(encoded); + expect(deepEqual(decoded, data)).toBe(true); + }); + + it('validate CompressedTokenInstructionDataTransferLayout', () => { const data: CompressedTokenInstructionDataTransfer = { proof: null, mint: new PublicKey('CXzk7xBgfzwSrZincWbJPGMPFz8aut3V6JjXp5n3XvGQ'), @@ -36,26 +142,44 @@ describe('layout', () => { data, buffer, ); + const decoded = CompressedTokenInstructionDataTransferLayout.decode( + buffer.slice(0, len), + ); + expect(deepEqual(decoded, data)).toBe(true); + }); + + it('validate mintToLayout', () => { + const data: MintToInstructionData = { + recipients: [ + new PublicKey('CXzk7xBgfzwSrZincWbJPGMPFz8aut3V6JjXp5n3XvGQ'), + ], + amounts: [new BN(1000)], + lamports: new BN(500), + }; + + const buffer = Buffer.alloc(1000); + const len = mintToLayout.encode(data, buffer); + const decoded = mintToLayout.decode(buffer.slice(0, len)); + expect(deepEqual(decoded, data)).toBe(true); + }); - const lengthBuffer = Buffer.alloc(4); - lengthBuffer.writeUInt32LE(len, 0); + it('validate compressSplTokenAccountInstructionDataLayout', () => { + const data: CompressSplTokenAccountInstructionData = { + owner: new PublicKey( + 'CXzk7xBgfzwSrZincWbJPGMPFz8aut3V6JjXp5n3XvGQ', + ), + remainingAmount: new BN(1000), + cpiContext: null, + }; - const encoded = Buffer.concat([ - TRANSFER_DISCRIMINATOR, - lengthBuffer, + const buffer = Buffer.alloc(1000); + const len = compressSplTokenAccountInstructionDataLayout.encode( + data, + buffer, + ); + const decoded = compressSplTokenAccountInstructionDataLayout.decode( buffer.slice(0, len), - ]); - - expect(encoded.length).toBeGreaterThan(0); - expect(encoded.slice(0, 8)).toEqual(TRANSFER_DISCRIMINATOR); - expect(Array.from(encoded.slice(0, -8))).toEqual([ - 163, 52, 200, 231, 140, 3, 69, 186, 97, 0, 0, 0, 0, 171, 97, 69, - 108, 86, 192, 2, 185, 79, 47, 215, 58, 29, 81, 87, 205, 244, 20, - 157, 24, 221, 133, 48, 179, 204, 116, 15, 94, 62, 203, 8, 97, 0, 0, - 0, 0, 0, 1, 0, 0, 0, 99, 89, 153, 55, 109, 114, 208, 114, 149, 17, - 69, 25, 230, 251, 164, 56, 142, 112, 116, 91, 104, 218, 126, 175, - 171, 134, 147, 64, 101, 207, 16, 139, 188, 2, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 1, 1, 188, - ]); + ); + expect(deepEqual(decoded, data)).toBe(true); }); }); diff --git a/js/stateless.js/package.json b/js/stateless.js/package.json index a1feae8fa2..96fdf2cdbd 100644 --- a/js/stateless.js/package.json +++ b/js/stateless.js/package.json @@ -93,7 +93,7 @@ "test:e2e:browser": "pnpm playwright test", "test:e2e:all": "pnpm test-validator && vitest run tests/e2e/test-rpc.test.ts && vitest run tests/e2e/compress.test.ts && vitest run tests/e2e/transfer.test.ts && vitest run tests/e2e/rpc-interop.test.ts", "test:index": "vitest run tests/e2e/program.test.ts", - "test:e2e:serde": "vitest run tests/e2e/serde.test.ts --reporter=verbose", + "test:e2e:layout": "vitest run tests/e2e/layout.test.ts --reporter=verbose", "test:verbose": "vitest run --reporter=verbose", "test:testnet": "vitest run tests/e2e/testnet.test.ts --reporter=verbose", "pull-idls": "../../scripts/push-stateless-js-idls.sh && ../../scripts/push-compressed-token-idl.sh", diff --git a/js/stateless.js/src/constants.ts b/js/stateless.js/src/constants.ts index b4dc6ee02e..83185b6007 100644 --- a/js/stateless.js/src/constants.ts +++ b/js/stateless.js/src/constants.ts @@ -9,6 +9,10 @@ export const HIGHEST_ADDRESS_PLUS_ONE = new BN( '452312848583266388373324160190187140051835877600158453279131187530910662655', ); +export const INVOKE_DISCRIMINATOR = Buffer.from([ + 26, 16, 169, 7, 21, 202, 242, 25, +]); + // TODO: implement properly export const noopProgram = 'noopb9bkMVfRPU8AsbpTUg8AQkHtKwMYZiFUjNRtMmV'; export const lightProgram = 'SySTEM1eSU2p4BGQfQpimFEWWSC1XDFeun3Nqzz3rT7'; diff --git a/js/stateless.js/src/programs/layout.ts b/js/stateless.js/src/programs/layout.ts index ad1fa9ab5f..86bfb4ec1d 100644 --- a/js/stateless.js/src/programs/layout.ts +++ b/js/stateless.js/src/programs/layout.ts @@ -16,6 +16,7 @@ import { } from '@coral-xyz/borsh'; import { InstructionDataInvoke, PublicTransactionEvent } from '../state'; import { LightSystemProgram } from './system'; +import { INVOKE_DISCRIMINATOR } from '../constants'; export const CompressedAccountLayout = struct( [ publicKey('owner'), @@ -53,7 +54,6 @@ export const NewAddressParamsLayout = struct( 'newAddressParams', ); -// Use the defined structs in the main layout with field names export const InstructionDataInvokeLayout: Layout = struct([ option( @@ -93,11 +93,7 @@ export function encodeInstructionDataInvoke( const lengthBuffer = Buffer.alloc(4); lengthBuffer.writeUInt32LE(len, 0); - return Buffer.concat([ - Buffer.from([26, 16, 169, 7, 21, 202, 242, 25]), - lengthBuffer, - dataBuffer, - ]); + return Buffer.concat([INVOKE_DISCRIMINATOR, lengthBuffer, dataBuffer]); } export function decodeInstructionDataInvoke( diff --git a/js/stateless.js/src/rpc.ts b/js/stateless.js/src/rpc.ts index 3cc1e66666..2304634473 100644 --- a/js/stateless.js/src/rpc.ts +++ b/js/stateless.js/src/rpc.ts @@ -424,7 +424,6 @@ export function convertNonInclusionMerkleProofInputsToHex( return inputs; } import { LightWasm } from './test-helpers'; -// import { ConnectionInterface } from './connection-interface'; function calculateTwoInputsHashChain( hashesFirst: BN[], diff --git a/js/stateless.js/src/test-helpers/test-rpc/test-rpc.ts b/js/stateless.js/src/test-helpers/test-rpc/test-rpc.ts index 89cc956ccd..aaf95d0c77 100644 --- a/js/stateless.js/src/test-helpers/test-rpc/test-rpc.ts +++ b/js/stateless.js/src/test-helpers/test-rpc/test-rpc.ts @@ -49,7 +49,6 @@ import { convertNonInclusionMerkleProofInputsToHex, proverRequest, } from '../../rpc'; -// import { ConnectionInterface } from '../../connection-interface'; export interface TestRpcConfig { /** @@ -214,7 +213,7 @@ export class TestRpc extends Connection implements CompressionApiInterface { if (!hash) { throw new Error('hash is required'); } - // @ts-ignore + const account = await getCompressedAccountByHashTest(this, hash); return account ?? null; } @@ -229,7 +228,7 @@ export class TestRpc extends Connection implements CompressionApiInterface { if (!hash) { throw new Error('hash is required'); } - // @ts-ignore + const account = await getCompressedAccountByHashTest(this, hash); if (!account) { throw new Error('Account not found'); @@ -266,7 +265,6 @@ export class TestRpc extends Connection implements CompressionApiInterface { async getMultipleCompressedAccounts( hashes: BN254[], ): Promise { - // @ts-ignore return await getMultipleCompressedAccountsByHashTest(this, hashes); } /** @@ -284,7 +282,6 @@ export class TestRpc extends Connection implements CompressionApiInterface { ): Promise { /// Build tree const events: PublicTransactionEvent[] = await getParsedEvents( - // @ts-ignore this, ).then(events => events.reverse()); const allLeaves: number[][] = []; @@ -350,7 +347,6 @@ export class TestRpc extends Connection implements CompressionApiInterface { owner: PublicKey, _config?: GetCompressedAccountsByOwnerConfig, ): Promise> { - // @ts-ignore const accounts = await getCompressedAccountsByOwnerTest(this, owner); return { items: accounts, @@ -390,7 +386,6 @@ export class TestRpc extends Connection implements CompressionApiInterface { options: GetCompressedTokenAccountsByOwnerOrDelegateOptions, ): Promise> { return await getCompressedTokenAccountsByOwnerTest( - // @ts-ignore this, owner, options!.mint!, @@ -405,7 +400,6 @@ export class TestRpc extends Connection implements CompressionApiInterface { options: GetCompressedTokenAccountsByOwnerOrDelegateOptions, ): Promise> { return await getCompressedTokenAccountsByDelegateTest( - // @ts-ignore this, delegate, options.mint!, @@ -418,7 +412,6 @@ export class TestRpc extends Connection implements CompressionApiInterface { async getCompressedTokenAccountBalance( hash: BN254, ): Promise<{ amount: BN }> { - // @ts-ignore const account = await getCompressedTokenAccountByHashTest(this, hash); return { amount: bn(account.parsed.amount) }; } @@ -433,7 +426,6 @@ export class TestRpc extends Connection implements CompressionApiInterface { options: GetCompressedTokenAccountsByOwnerOrDelegateOptions, ): Promise> { const accounts = await getCompressedTokenAccountsByOwnerTest( - // @ts-ignore this, publicKey, options.mint!, @@ -456,7 +448,6 @@ export class TestRpc extends Connection implements CompressionApiInterface { options: GetCompressedTokenAccountsByOwnerOrDelegateOptions, ): Promise>> { const accounts = await getCompressedTokenAccountsByOwnerTest( - // @ts-ignore this, publicKey, options.mint!, diff --git a/js/stateless.js/src/utils/test-utils.ts b/js/stateless.js/src/utils/test-utils.ts index 2a081763ed..f57e707ac0 100644 --- a/js/stateless.js/src/utils/test-utils.ts +++ b/js/stateless.js/src/utils/test-utils.ts @@ -1,6 +1,7 @@ import { Connection, Keypair, Signer } from '@solana/web3.js'; import { confirmTx } from '../utils/send-and-confirm'; import { Rpc } from '../rpc'; +import BN from 'bn.js'; let c = 1; @@ -9,6 +10,54 @@ export const BOB = getTestKeypair(254); export const CHARLIE = getTestKeypair(253); export const DAVE = getTestKeypair(252); +/** + * Deep comparison of two objects. Handles BN comparison correctly. + * + * @param ref - The reference object to compare. + * @param val - The value object to compare. + * @returns True if the objects are deeply equal, false otherwise. + */ +export function deepEqual(ref: any, val: any) { + if (typeof ref !== typeof val) { + console.log(`Type mismatch: ${typeof ref} !== ${typeof val}`); + return false; + } + + if (ref instanceof BN && val instanceof BN) { + return ref.eq(val); + } + + if (typeof ref === 'object' && ref !== null && val !== null) { + const refKeys = Object.keys(ref); + const valKeys = Object.keys(val); + + if (refKeys.length !== valKeys.length) { + console.log( + `Key length mismatch: ${refKeys.length} !== ${valKeys.length}`, + ); + return false; + } + + for (let key of refKeys) { + if (!valKeys.includes(key)) { + console.log(`Key ${key} not found in value`); + return false; + } + if (!deepEqual(ref[key], val[key])) { + console.log(`Value mismatch at key ${key}`); + return false; + } + } + return true; + } + + if (ref !== val) { + console.log(`Value mismatch: ${ref} !== ${val}`); + } + + return ref === val; +} + /** * Create a new account and airdrop lamports to it * diff --git a/js/stateless.js/tests/e2e/layout.test.ts b/js/stateless.js/tests/e2e/layout.test.ts new file mode 100644 index 0000000000..daad549e0b --- /dev/null +++ b/js/stateless.js/tests/e2e/layout.test.ts @@ -0,0 +1,79 @@ +import { decodePublicTransactionEvent } from '../../src/programs/layout'; +import { describe, it, expect } from 'vitest'; +import { PublicKey } from '@solana/web3.js'; +import BN from 'bn.js'; +import { InstructionDataInvoke } from '../../src/state'; + +function deepEqual(ref: any, val: any) { + if (typeof ref !== typeof val) { + console.log(`Type mismatch: ${typeof ref} !== ${typeof val}`); + return false; + } + + if (ref instanceof BN && val instanceof BN) { + return ref.eq(val); + } + + if (typeof ref === 'object' && ref !== null && val !== null) { + const refKeys = Object.keys(ref); + const valKeys = Object.keys(val); + + if (refKeys.length !== valKeys.length) { + console.log( + `Key length mismatch: ${refKeys.length} !== ${valKeys.length}`, + ); + return false; + } + + for (let key of refKeys) { + if (!valKeys.includes(key)) { + console.log(`Key ${key} not found in value`); + return false; + } + if (!deepEqual(ref[key], val[key])) { + console.log(`Value mismatch at key ${key}`); + return false; + } + } + return true; + } + + if (ref !== val) { + console.log(`Value mismatch: ${ref} !== ${val}`); + } + + return ref === val; +} + +describe('layout', () => { + it('decode event', async () => { + const data = [ + 0, 0, 0, 0, 1, 0, 0, 0, 33, 32, 204, 221, 5, 83, 170, 139, 228, 191, + 81, 173, 10, 116, 229, 191, 155, 209, 23, 164, 28, 64, 188, 34, 248, + 127, 110, 97, 26, 188, 139, 164, 0, 0, 0, 0, 1, 0, 0, 0, 22, 143, + 135, 215, 254, 121, 58, 95, 241, 202, 91, 53, 255, 47, 224, 255, 67, + 218, 48, 172, 51, 208, 29, 102, 177, 187, 207, 73, 108, 18, 59, 255, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 1, 0, 0, 0, 68, 77, 125, 32, 76, 128, 61, 180, 1, 207, 69, + 44, 121, 118, 153, 17, 179, 183, 115, 34, 163, 127, 102, 214, 1, 87, + 175, 177, 95, 49, 65, 69, 0, + ]; + + const event = decodePublicTransactionEvent(Buffer.from(data)); + + const refOutputCompressedAccountHash = [ + 33, 32, 204, 221, 5, 83, 170, 139, 228, 191, 81, 173, 10, 116, 229, + 191, 155, 209, 23, 164, 28, 64, 188, 34, 248, 127, 110, 97, 26, 188, + 139, 164, + ]; + + expect(event.outputCompressedAccountHashes[0]).toEqual( + Buffer.from(refOutputCompressedAccountHash), + ); + }); + it('encode/decode CompressedTokenInstructionDataTransfer', () => { + const data: InstructionDataInvoke = {}; + + expect(deepEqual(decoded, data)).toBe(true); + }); +}); diff --git a/js/stateless.js/tests/e2e/rpc-interop.test.ts b/js/stateless.js/tests/e2e/rpc-interop.test.ts index 6c08b7633d..fc3e170580 100644 --- a/js/stateless.js/tests/e2e/rpc-interop.test.ts +++ b/js/stateless.js/tests/e2e/rpc-interop.test.ts @@ -104,13 +104,7 @@ describe('rpc-interop', () => { executedTxs++; /// Executes a transfer using a 'validityProof' directly from a prover. - await transfer( - testRpc as unknown as Rpc, - payer, - 1e5, - payer, - bob.publicKey, - ); + await transfer(testRpc, payer, 1e5, payer, bob.publicKey); executedTxs++; }); @@ -176,7 +170,7 @@ describe('rpc-interop', () => { /// Creates a compressed account with address using a (non-inclusion) /// 'validityProof' directly from a prover. await createAccount( - testRpc as unknown as Rpc, + testRpc, payer, newAddressSeeds, LightSystemProgram.programId, diff --git a/js/stateless.js/tests/e2e/serde.test.ts b/js/stateless.js/tests/e2e/serde.test.ts deleted file mode 100644 index b37111c445..0000000000 --- a/js/stateless.js/tests/e2e/serde.test.ts +++ /dev/null @@ -1,30 +0,0 @@ -import { describe, it, expect } from 'vitest'; -import { decodePublicTransactionEvent } from '../../src/programs/layout'; - -describe('serde', () => { - it('decode event', async () => { - const data = [ - 0, 0, 0, 0, 1, 0, 0, 0, 33, 32, 204, 221, 5, 83, 170, 139, 228, 191, - 81, 173, 10, 116, 229, 191, 155, 209, 23, 164, 28, 64, 188, 34, 248, - 127, 110, 97, 26, 188, 139, 164, 0, 0, 0, 0, 1, 0, 0, 0, 22, 143, - 135, 215, 254, 121, 58, 95, 241, 202, 91, 53, 255, 47, 224, 255, 67, - 218, 48, 172, 51, 208, 29, 102, 177, 187, 207, 73, 108, 18, 59, 255, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 1, 0, 0, 0, 68, 77, 125, 32, 76, 128, 61, 180, 1, 207, 69, - 44, 121, 118, 153, 17, 179, 183, 115, 34, 163, 127, 102, 214, 1, 87, - 175, 177, 95, 49, 65, 69, 0, - ]; - - const event = decodePublicTransactionEvent(Buffer.from(data)); - - const refOutputCompressedAccountHash = [ - 33, 32, 204, 221, 5, 83, 170, 139, 228, 191, 81, 173, 10, 116, 229, - 191, 155, 209, 23, 164, 28, 64, 188, 34, 248, 127, 110, 97, 26, 188, - 139, 164, - ]; - - expect(event.outputCompressedAccountHashes[0]).toEqual( - Buffer.from(refOutputCompressedAccountHash), - ); - }); -}); From 8723a0f8c4b8819bb5dee737f3005d4a153ecbef Mon Sep 17 00:00:00 2001 From: Swenschaeferjohann Date: Mon, 6 Jan 2025 19:26:02 +0000 Subject: [PATCH 06/19] add unit tests for codec/layout.ts files --- js/compressed-token/package.json | 7 +- js/compressed-token/src/idl.ts | 3481 ++++++++++++++++++ js/compressed-token/src/index.ts | 1 + js/compressed-token/src/layout.ts | 4 +- js/compressed-token/src/program.ts | 7 +- js/compressed-token/tests/e2e/layout.test.ts | 767 +++- js/stateless.js/package.json | 1 + js/stateless.js/rollup.config.js | 4 +- js/stateless.js/src/idl.ts | 2034 ++++++++++ js/stateless.js/src/index.ts | 1 + js/stateless.js/src/programs/layout.ts | 5 +- js/stateless.js/src/state/types.ts | 5 + js/stateless.js/src/utils/test-utils.ts | 2 +- js/stateless.js/tests/e2e/layout.test.ts | 308 +- pnpm-lock.yaml | 30 +- 15 files changed, 6487 insertions(+), 170 deletions(-) create mode 100644 js/compressed-token/src/idl.ts create mode 100644 js/stateless.js/src/idl.ts diff --git a/js/compressed-token/package.json b/js/compressed-token/package.json index c483112f53..0bc944db00 100644 --- a/js/compressed-token/package.json +++ b/js/compressed-token/package.json @@ -30,8 +30,8 @@ "license": "Apache-2.0", "peerDependencies": { "@lightprotocol/stateless.js": "workspace:*", - "@solana/web3.js": ">=1.73.5", - "@solana/spl-token": ">=0.3.9" + "@solana/spl-token": ">=0.3.9", + "@solana/web3.js": ">=1.73.5" }, "dependencies": { "@coral-xyz/borsh": "^0.29.0", @@ -39,6 +39,7 @@ "buffer": "6.0.3" }, "devDependencies": { + "@coral-xyz/anchor": "^0.29.0", "@esbuild-plugins/node-globals-polyfill": "^0.2.3", "@lightprotocol/hasher.rs": "0.2.1", "@lightprotocol/programs": "workspace:*", @@ -50,8 +51,8 @@ "@rollup/plugin-replace": "^5.0.7", "@rollup/plugin-terser": "^0.4.4", "@rollup/plugin-typescript": "^11.1.6", - "@solana/web3.js": "1.98.0", "@solana/spl-token": "0.4.8", + "@solana/web3.js": "1.98.0", "@types/bn.js": "^5.1.5", "@types/node": "^22.5.5", "@typescript-eslint/eslint-plugin": "^7.13.1", diff --git a/js/compressed-token/src/idl.ts b/js/compressed-token/src/idl.ts new file mode 100644 index 0000000000..3dc084e1b3 --- /dev/null +++ b/js/compressed-token/src/idl.ts @@ -0,0 +1,3481 @@ +export type LightCompressedToken = { + version: '1.2.0'; + name: 'light_compressed_token'; + instructions: [ + { + name: 'createTokenPool'; + docs: [ + 'This instruction creates a token pool for a given mint. Every spl mint', + 'can have one token pool. When a token is compressed the tokens are', + 'transferrred to the token pool, and their compressed equivalent is', + 'minted into a Merkle tree.', + ]; + accounts: [ + { + name: 'feePayer'; + isMut: true; + isSigner: true; + docs: ['UNCHECKED: only pays fees.']; + }, + { + name: 'tokenPoolPda'; + isMut: true; + isSigner: false; + }, + { + name: 'systemProgram'; + isMut: false; + isSigner: false; + }, + { + name: 'mint'; + isMut: true; + isSigner: false; + }, + { + name: 'tokenProgram'; + isMut: false; + isSigner: false; + }, + { + name: 'cpiAuthorityPda'; + isMut: false; + isSigner: false; + }, + ]; + args: []; + }, + { + name: 'addTokenPool'; + docs: [ + 'This instruction creates an additional token pool for a given mint.', + 'The maximum number of token pools per mint is 5.', + ]; + accounts: [ + { + name: 'feePayer'; + isMut: true; + isSigner: true; + docs: ['UNCHECKED: only pays fees.']; + }, + { + name: 'tokenPoolPda'; + isMut: true; + isSigner: false; + }, + { + name: 'existingTokenPoolPda'; + isMut: false; + isSigner: false; + }, + { + name: 'systemProgram'; + isMut: false; + isSigner: false; + }, + { + name: 'mint'; + isMut: true; + isSigner: false; + }, + { + name: 'tokenProgram'; + isMut: false; + isSigner: false; + }, + { + name: 'cpiAuthorityPda'; + isMut: false; + isSigner: false; + }, + ]; + args: [ + { + name: 'tokenPoolBump'; + type: 'u8'; + }, + ]; + }, + { + name: 'mintTo'; + docs: [ + 'Mints tokens from an spl token mint to a list of compressed accounts.', + 'Minted tokens are transferred to a pool account owned by the compressed', + 'token program. The instruction creates one compressed output account for', + 'every amount and pubkey input pair. A constant amount of lamports can be', + 'transferred to each output account to enable. A use case to add lamports', + 'to a compressed token account is to prevent spam. This is the only way', + 'to add lamports to a compressed token account.', + ]; + accounts: [ + { + name: 'feePayer'; + isMut: true; + isSigner: true; + docs: ['UNCHECKED: only pays fees.']; + }, + { + name: 'authority'; + isMut: false; + isSigner: true; + }, + { + name: 'cpiAuthorityPda'; + isMut: false; + isSigner: false; + }, + { + name: 'mint'; + isMut: true; + isSigner: false; + }, + { + name: 'tokenPoolPda'; + isMut: true; + isSigner: false; + }, + { + name: 'tokenProgram'; + isMut: false; + isSigner: false; + }, + { + name: 'lightSystemProgram'; + isMut: false; + isSigner: false; + }, + { + name: 'registeredProgramPda'; + isMut: false; + isSigner: false; + }, + { + name: 'noopProgram'; + isMut: false; + isSigner: false; + docs: ['programs']; + }, + { + name: 'accountCompressionAuthority'; + isMut: false; + isSigner: false; + }, + { + name: 'accountCompressionProgram'; + isMut: false; + isSigner: false; + }, + { + name: 'merkleTree'; + isMut: true; + isSigner: false; + }, + { + name: 'selfProgram'; + isMut: false; + isSigner: false; + }, + { + name: 'systemProgram'; + isMut: false; + isSigner: false; + }, + { + name: 'solPoolPda'; + isMut: true; + isSigner: false; + isOptional: true; + }, + ]; + args: [ + { + name: 'publicKeys'; + type: { + vec: 'publicKey'; + }; + }, + { + name: 'amounts'; + type: { + vec: 'u64'; + }; + }, + { + name: 'lamports'; + type: { + option: 'u64'; + }; + }, + ]; + }, + { + name: 'compressSplTokenAccount'; + docs: [ + 'Compresses the balance of an spl token account sub an optional remaining', + 'amount. This instruction does not close the spl token account. To close', + 'the account bundle a close spl account instruction in your transaction.', + ]; + accounts: [ + { + name: 'feePayer'; + isMut: true; + isSigner: true; + docs: ['UNCHECKED: only pays fees.']; + }, + { + name: 'authority'; + isMut: false; + isSigner: true; + docs: [ + 'Authority is verified through proof since both owner and delegate', + 'are included in the token data hash, which is a public input to the', + 'validity proof.', + ]; + }, + { + name: 'cpiAuthorityPda'; + isMut: false; + isSigner: false; + }, + { + name: 'lightSystemProgram'; + isMut: false; + isSigner: false; + }, + { + name: 'registeredProgramPda'; + isMut: false; + isSigner: false; + }, + { + name: 'noopProgram'; + isMut: false; + isSigner: false; + }, + { + name: 'accountCompressionAuthority'; + isMut: false; + isSigner: false; + }, + { + name: 'accountCompressionProgram'; + isMut: false; + isSigner: false; + }, + { + name: 'selfProgram'; + isMut: false; + isSigner: false; + docs: ['this program is the signer of the cpi.']; + }, + { + name: 'tokenPoolPda'; + isMut: true; + isSigner: false; + isOptional: true; + }, + { + name: 'compressOrDecompressTokenAccount'; + isMut: true; + isSigner: false; + isOptional: true; + }, + { + name: 'tokenProgram'; + isMut: false; + isSigner: false; + isOptional: true; + }, + { + name: 'systemProgram'; + isMut: false; + isSigner: false; + }, + ]; + args: [ + { + name: 'owner'; + type: 'publicKey'; + }, + { + name: 'remainingAmount'; + type: { + option: 'u64'; + }; + }, + { + name: 'cpiContext'; + type: { + option: { + defined: 'CompressedCpiContext'; + }; + }; + }, + ]; + }, + { + name: 'transfer'; + docs: [ + 'Transfers compressed tokens from one account to another. All accounts', + 'must be of the same mint. Additional spl tokens can be compressed or', + 'decompressed. In one transaction only compression or decompression is', + 'possible. Lamports can be transferred alongside tokens. If output token', + 'accounts specify less lamports than inputs the remaining lamports are', + 'transferred to an output compressed account. Signer must be owner or', + 'delegate. If a delegated token account is transferred the delegate is', + 'not preserved.', + ]; + accounts: [ + { + name: 'feePayer'; + isMut: true; + isSigner: true; + docs: ['UNCHECKED: only pays fees.']; + }, + { + name: 'authority'; + isMut: false; + isSigner: true; + docs: [ + 'Authority is verified through proof since both owner and delegate', + 'are included in the token data hash, which is a public input to the', + 'validity proof.', + ]; + }, + { + name: 'cpiAuthorityPda'; + isMut: false; + isSigner: false; + }, + { + name: 'lightSystemProgram'; + isMut: false; + isSigner: false; + }, + { + name: 'registeredProgramPda'; + isMut: false; + isSigner: false; + }, + { + name: 'noopProgram'; + isMut: false; + isSigner: false; + }, + { + name: 'accountCompressionAuthority'; + isMut: false; + isSigner: false; + }, + { + name: 'accountCompressionProgram'; + isMut: false; + isSigner: false; + }, + { + name: 'selfProgram'; + isMut: false; + isSigner: false; + docs: ['this program is the signer of the cpi.']; + }, + { + name: 'tokenPoolPda'; + isMut: true; + isSigner: false; + isOptional: true; + }, + { + name: 'compressOrDecompressTokenAccount'; + isMut: true; + isSigner: false; + isOptional: true; + }, + { + name: 'tokenProgram'; + isMut: false; + isSigner: false; + isOptional: true; + }, + { + name: 'systemProgram'; + isMut: false; + isSigner: false; + }, + ]; + args: [ + { + name: 'inputs'; + type: 'bytes'; + }, + ]; + }, + { + name: 'approve'; + docs: [ + 'Delegates an amount to a delegate. A compressed token account is either', + 'completely delegated or not. Prior delegates are not preserved. Cannot', + 'be called by a delegate.', + 'The instruction creates two output accounts:', + '1. one account with delegated amount', + '2. one account with remaining(change) amount', + ]; + accounts: [ + { + name: 'feePayer'; + isMut: true; + isSigner: true; + docs: ['UNCHECKED: only pays fees.']; + }, + { + name: 'authority'; + isMut: false; + isSigner: true; + docs: [ + 'Authority is verified through proof since both owner and delegate', + 'are included in the token data hash, which is a public input to the', + 'validity proof.', + ]; + }, + { + name: 'cpiAuthorityPda'; + isMut: false; + isSigner: false; + }, + { + name: 'lightSystemProgram'; + isMut: false; + isSigner: false; + }, + { + name: 'registeredProgramPda'; + isMut: false; + isSigner: false; + }, + { + name: 'noopProgram'; + isMut: false; + isSigner: false; + }, + { + name: 'accountCompressionAuthority'; + isMut: false; + isSigner: false; + }, + { + name: 'accountCompressionProgram'; + isMut: false; + isSigner: false; + }, + { + name: 'selfProgram'; + isMut: false; + isSigner: false; + docs: ['this program is the signer of the cpi.']; + }, + { + name: 'systemProgram'; + isMut: false; + isSigner: false; + }, + ]; + args: [ + { + name: 'inputs'; + type: 'bytes'; + }, + ]; + }, + { + name: 'revoke'; + docs: [ + 'Revokes a delegation. The instruction merges all inputs into one output', + 'account. Cannot be called by a delegate. Delegates are not preserved.', + ]; + accounts: [ + { + name: 'feePayer'; + isMut: true; + isSigner: true; + docs: ['UNCHECKED: only pays fees.']; + }, + { + name: 'authority'; + isMut: false; + isSigner: true; + docs: [ + 'Authority is verified through proof since both owner and delegate', + 'are included in the token data hash, which is a public input to the', + 'validity proof.', + ]; + }, + { + name: 'cpiAuthorityPda'; + isMut: false; + isSigner: false; + }, + { + name: 'lightSystemProgram'; + isMut: false; + isSigner: false; + }, + { + name: 'registeredProgramPda'; + isMut: false; + isSigner: false; + }, + { + name: 'noopProgram'; + isMut: false; + isSigner: false; + }, + { + name: 'accountCompressionAuthority'; + isMut: false; + isSigner: false; + }, + { + name: 'accountCompressionProgram'; + isMut: false; + isSigner: false; + }, + { + name: 'selfProgram'; + isMut: false; + isSigner: false; + docs: ['this program is the signer of the cpi.']; + }, + { + name: 'systemProgram'; + isMut: false; + isSigner: false; + }, + ]; + args: [ + { + name: 'inputs'; + type: 'bytes'; + }, + ]; + }, + { + name: 'freeze'; + docs: [ + 'Freezes compressed token accounts. Inputs must not be frozen. Creates as', + 'many outputs as inputs. Balances and delegates are preserved.', + ]; + accounts: [ + { + name: 'feePayer'; + isMut: true; + isSigner: true; + docs: ['UNCHECKED: only pays fees.']; + }, + { + name: 'authority'; + isMut: false; + isSigner: true; + }, + { + name: 'cpiAuthorityPda'; + isMut: false; + isSigner: false; + }, + { + name: 'lightSystemProgram'; + isMut: false; + isSigner: false; + }, + { + name: 'registeredProgramPda'; + isMut: false; + isSigner: false; + }, + { + name: 'noopProgram'; + isMut: false; + isSigner: false; + }, + { + name: 'accountCompressionAuthority'; + isMut: false; + isSigner: false; + }, + { + name: 'accountCompressionProgram'; + isMut: false; + isSigner: false; + }, + { + name: 'selfProgram'; + isMut: false; + isSigner: false; + docs: ['that this program is the signer of the cpi.']; + }, + { + name: 'systemProgram'; + isMut: false; + isSigner: false; + }, + { + name: 'mint'; + isMut: false; + isSigner: false; + }, + ]; + args: [ + { + name: 'inputs'; + type: 'bytes'; + }, + ]; + }, + { + name: 'thaw'; + docs: [ + 'Thaws frozen compressed token accounts. Inputs must be frozen. Creates', + 'as many outputs as inputs. Balances and delegates are preserved.', + ]; + accounts: [ + { + name: 'feePayer'; + isMut: true; + isSigner: true; + docs: ['UNCHECKED: only pays fees.']; + }, + { + name: 'authority'; + isMut: false; + isSigner: true; + }, + { + name: 'cpiAuthorityPda'; + isMut: false; + isSigner: false; + }, + { + name: 'lightSystemProgram'; + isMut: false; + isSigner: false; + }, + { + name: 'registeredProgramPda'; + isMut: false; + isSigner: false; + }, + { + name: 'noopProgram'; + isMut: false; + isSigner: false; + }, + { + name: 'accountCompressionAuthority'; + isMut: false; + isSigner: false; + }, + { + name: 'accountCompressionProgram'; + isMut: false; + isSigner: false; + }, + { + name: 'selfProgram'; + isMut: false; + isSigner: false; + docs: ['that this program is the signer of the cpi.']; + }, + { + name: 'systemProgram'; + isMut: false; + isSigner: false; + }, + { + name: 'mint'; + isMut: false; + isSigner: false; + }, + ]; + args: [ + { + name: 'inputs'; + type: 'bytes'; + }, + ]; + }, + { + name: 'burn'; + docs: [ + 'Burns compressed tokens and spl tokens from the pool account. Delegates', + 'can burn tokens. The output compressed token account remains delegated.', + 'Creates one output compressed token account.', + ]; + accounts: [ + { + name: 'feePayer'; + isMut: true; + isSigner: true; + docs: ['UNCHECKED: only pays fees.']; + }, + { + name: 'authority'; + isMut: false; + isSigner: true; + docs: [ + 'Authority is verified through proof since both owner and delegate', + 'are included in the token data hash, which is a public input to the', + 'validity proof.', + ]; + }, + { + name: 'cpiAuthorityPda'; + isMut: false; + isSigner: false; + }, + { + name: 'mint'; + isMut: true; + isSigner: false; + }, + { + name: 'tokenPoolPda'; + isMut: true; + isSigner: false; + }, + { + name: 'tokenProgram'; + isMut: false; + isSigner: false; + }, + { + name: 'lightSystemProgram'; + isMut: false; + isSigner: false; + }, + { + name: 'registeredProgramPda'; + isMut: false; + isSigner: false; + }, + { + name: 'noopProgram'; + isMut: false; + isSigner: false; + }, + { + name: 'accountCompressionAuthority'; + isMut: false; + isSigner: false; + }, + { + name: 'accountCompressionProgram'; + isMut: false; + isSigner: false; + }, + { + name: 'selfProgram'; + isMut: false; + isSigner: false; + }, + { + name: 'systemProgram'; + isMut: false; + isSigner: false; + }, + ]; + args: [ + { + name: 'inputs'; + type: 'bytes'; + }, + ]; + }, + { + name: 'stubIdlBuild'; + docs: [ + 'This function is a stub to allow Anchor to include the input types in', + 'the IDL. It should not be included in production builds nor be called in', + 'practice.', + ]; + accounts: [ + { + name: 'feePayer'; + isMut: true; + isSigner: true; + docs: ['UNCHECKED: only pays fees.']; + }, + { + name: 'authority'; + isMut: false; + isSigner: true; + docs: [ + 'Authority is verified through proof since both owner and delegate', + 'are included in the token data hash, which is a public input to the', + 'validity proof.', + ]; + }, + { + name: 'cpiAuthorityPda'; + isMut: false; + isSigner: false; + }, + { + name: 'lightSystemProgram'; + isMut: false; + isSigner: false; + }, + { + name: 'registeredProgramPda'; + isMut: false; + isSigner: false; + }, + { + name: 'noopProgram'; + isMut: false; + isSigner: false; + }, + { + name: 'accountCompressionAuthority'; + isMut: false; + isSigner: false; + }, + { + name: 'accountCompressionProgram'; + isMut: false; + isSigner: false; + }, + { + name: 'selfProgram'; + isMut: false; + isSigner: false; + docs: ['this program is the signer of the cpi.']; + }, + { + name: 'tokenPoolPda'; + isMut: true; + isSigner: false; + isOptional: true; + }, + { + name: 'compressOrDecompressTokenAccount'; + isMut: true; + isSigner: false; + isOptional: true; + }, + { + name: 'tokenProgram'; + isMut: false; + isSigner: false; + isOptional: true; + }, + { + name: 'systemProgram'; + isMut: false; + isSigner: false; + }, + ]; + args: [ + { + name: 'inputs1'; + type: { + defined: 'CompressedTokenInstructionDataTransfer'; + }; + }, + { + name: 'inputs2'; + type: { + defined: 'TokenData'; + }; + }, + ]; + }, + ]; + types: [ + { + name: 'AccountState'; + type: { + kind: 'enum'; + variants: [ + { + name: 'Initialized'; + }, + { + name: 'Frozen'; + }, + ]; + }; + }, + { + name: 'CompressedAccount'; + type: { + kind: 'struct'; + fields: [ + { + name: 'owner'; + type: 'publicKey'; + }, + { + name: 'lamports'; + type: 'u64'; + }, + { + name: 'address'; + type: { + option: { + array: ['u8', 32]; + }; + }; + }, + { + name: 'data'; + type: { + option: { + defined: 'CompressedAccountData'; + }; + }; + }, + ]; + }; + }, + { + name: 'CompressedAccountData'; + type: { + kind: 'struct'; + fields: [ + { + name: 'discriminator'; + type: { + array: ['u8', 8]; + }; + }, + { + name: 'data'; + type: 'bytes'; + }, + { + name: 'dataHash'; + type: { + array: ['u8', 32]; + }; + }, + ]; + }; + }, + { + name: 'CompressedCpiContext'; + type: { + kind: 'struct'; + fields: [ + { + name: 'setContext'; + docs: [ + 'Is set by the program that is invoking the CPI to signal that is should', + 'set the cpi context.', + ]; + type: 'bool'; + }, + { + name: 'firstSetContext'; + docs: [ + 'Is set to wipe the cpi context since someone could have set it before', + 'with unrelated data.', + ]; + type: 'bool'; + }, + { + name: 'cpiContextAccountIndex'; + docs: [ + 'Index of cpi context account in remaining accounts.', + ]; + type: 'u8'; + }, + ]; + }; + }, + { + name: 'CompressedProof'; + type: { + kind: 'struct'; + fields: [ + { + name: 'a'; + type: { + array: ['u8', 32]; + }; + }, + { + name: 'b'; + type: { + array: ['u8', 64]; + }; + }, + { + name: 'c'; + type: { + array: ['u8', 32]; + }; + }, + ]; + }; + }, + { + name: 'CompressedTokenInstructionDataTransfer'; + type: { + kind: 'struct'; + fields: [ + { + name: 'proof'; + type: { + option: { + defined: 'CompressedProof'; + }; + }; + }, + { + name: 'mint'; + type: 'publicKey'; + }, + { + name: 'delegatedTransfer'; + docs: [ + 'Is required if the signer is delegate,', + '-> delegate is authority account,', + 'owner = Some(owner) is the owner of the token account.', + ]; + type: { + option: { + defined: 'DelegatedTransfer'; + }; + }; + }, + { + name: 'inputTokenDataWithContext'; + type: { + vec: { + defined: 'InputTokenDataWithContext'; + }; + }; + }, + { + name: 'outputCompressedAccounts'; + type: { + vec: { + defined: 'PackedTokenTransferOutputData'; + }; + }; + }, + { + name: 'isCompress'; + type: 'bool'; + }, + { + name: 'compressOrDecompressAmount'; + type: { + option: 'u64'; + }; + }, + { + name: 'cpiContext'; + type: { + option: { + defined: 'CompressedCpiContext'; + }; + }; + }, + { + name: 'lamportsChangeAccountMerkleTreeIndex'; + type: { + option: 'u8'; + }; + }, + ]; + }; + }, + { + name: 'DelegatedTransfer'; + docs: [ + 'Struct to provide the owner when the delegate is signer of the transaction.', + ]; + type: { + kind: 'struct'; + fields: [ + { + name: 'owner'; + type: 'publicKey'; + }, + { + name: 'delegateChangeAccountIndex'; + docs: [ + 'Index of change compressed account in output compressed accounts. In', + "case that the delegate didn't spend the complete delegated compressed", + 'account balance the change compressed account will be delegated to her', + 'as well.', + ]; + type: { + option: 'u8'; + }; + }, + ]; + }; + }, + { + name: 'InputTokenDataWithContext'; + type: { + kind: 'struct'; + fields: [ + { + name: 'amount'; + type: 'u64'; + }, + { + name: 'delegateIndex'; + type: { + option: 'u8'; + }; + }, + { + name: 'merkleContext'; + type: { + defined: 'PackedMerkleContext'; + }; + }, + { + name: 'rootIndex'; + type: 'u16'; + }, + { + name: 'lamports'; + type: { + option: 'u64'; + }; + }, + { + name: 'tlv'; + docs: [ + 'Placeholder for TokenExtension tlv data (unimplemented)', + ]; + type: { + option: 'bytes'; + }; + }, + ]; + }; + }, + { + name: 'InstructionDataInvoke'; + type: { + kind: 'struct'; + fields: [ + { + name: 'proof'; + type: { + option: { + defined: 'CompressedProof'; + }; + }; + }, + { + name: 'inputCompressedAccountsWithMerkleContext'; + type: { + vec: { + defined: 'PackedCompressedAccountWithMerkleContext'; + }; + }; + }, + { + name: 'outputCompressedAccounts'; + type: { + vec: { + defined: 'OutputCompressedAccountWithPackedContext'; + }; + }; + }, + { + name: 'relayFee'; + type: { + option: 'u64'; + }; + }, + { + name: 'newAddressParams'; + type: { + vec: { + defined: 'NewAddressParamsPacked'; + }; + }; + }, + { + name: 'compressOrDecompressLamports'; + type: { + option: 'u64'; + }; + }, + { + name: 'isCompress'; + type: 'bool'; + }, + ]; + }; + }, + { + name: 'InstructionDataInvokeCpi'; + type: { + kind: 'struct'; + fields: [ + { + name: 'proof'; + type: { + option: { + defined: 'CompressedProof'; + }; + }; + }, + { + name: 'newAddressParams'; + type: { + vec: { + defined: 'NewAddressParamsPacked'; + }; + }; + }, + { + name: 'inputCompressedAccountsWithMerkleContext'; + type: { + vec: { + defined: 'PackedCompressedAccountWithMerkleContext'; + }; + }; + }, + { + name: 'outputCompressedAccounts'; + type: { + vec: { + defined: 'OutputCompressedAccountWithPackedContext'; + }; + }; + }, + { + name: 'relayFee'; + type: { + option: 'u64'; + }; + }, + { + name: 'compressOrDecompressLamports'; + type: { + option: 'u64'; + }; + }, + { + name: 'isCompress'; + type: 'bool'; + }, + { + name: 'cpiContext'; + type: { + option: { + defined: 'CompressedCpiContext'; + }; + }; + }, + ]; + }; + }, + { + name: 'MerkleTreeSequenceNumber'; + type: { + kind: 'struct'; + fields: [ + { + name: 'pubkey'; + type: 'publicKey'; + }, + { + name: 'seq'; + type: 'u64'; + }, + ]; + }; + }, + { + name: 'NewAddressParamsPacked'; + type: { + kind: 'struct'; + fields: [ + { + name: 'seed'; + type: { + array: ['u8', 32]; + }; + }, + { + name: 'addressQueueAccountIndex'; + type: 'u8'; + }, + { + name: 'addressMerkleTreeAccountIndex'; + type: 'u8'; + }, + { + name: 'addressMerkleTreeRootIndex'; + type: 'u16'; + }, + ]; + }; + }, + { + name: 'OutputCompressedAccountWithPackedContext'; + type: { + kind: 'struct'; + fields: [ + { + name: 'compressedAccount'; + type: { + defined: 'CompressedAccount'; + }; + }, + { + name: 'merkleTreeIndex'; + type: 'u8'; + }, + ]; + }; + }, + { + name: 'PackedCompressedAccountWithMerkleContext'; + type: { + kind: 'struct'; + fields: [ + { + name: 'compressedAccount'; + type: { + defined: 'CompressedAccount'; + }; + }, + { + name: 'merkleContext'; + type: { + defined: 'PackedMerkleContext'; + }; + }, + { + name: 'rootIndex'; + docs: [ + 'Index of root used in inclusion validity proof.', + ]; + type: 'u16'; + }, + { + name: 'readOnly'; + docs: [ + 'Placeholder to mark accounts read-only unimplemented set to false.', + ]; + type: 'bool'; + }, + ]; + }; + }, + { + name: 'PackedMerkleContext'; + type: { + kind: 'struct'; + fields: [ + { + name: 'merkleTreePubkeyIndex'; + type: 'u8'; + }, + { + name: 'nullifierQueuePubkeyIndex'; + type: 'u8'; + }, + { + name: 'leafIndex'; + type: 'u32'; + }, + { + name: 'queueIndex'; + type: { + option: { + defined: 'QueueIndex'; + }; + }; + }, + ]; + }; + }, + { + name: 'PackedTokenTransferOutputData'; + type: { + kind: 'struct'; + fields: [ + { + name: 'owner'; + type: 'publicKey'; + }, + { + name: 'amount'; + type: 'u64'; + }, + { + name: 'lamports'; + type: { + option: 'u64'; + }; + }, + { + name: 'merkleTreeIndex'; + type: 'u8'; + }, + { + name: 'tlv'; + docs: [ + 'Placeholder for TokenExtension tlv data (unimplemented)', + ]; + type: { + option: 'bytes'; + }; + }, + ]; + }; + }, + { + name: 'PublicTransactionEvent'; + type: { + kind: 'struct'; + fields: [ + { + name: 'inputCompressedAccountHashes'; + type: { + vec: { + array: ['u8', 32]; + }; + }; + }, + { + name: 'outputCompressedAccountHashes'; + type: { + vec: { + array: ['u8', 32]; + }; + }; + }, + { + name: 'outputCompressedAccounts'; + type: { + vec: { + defined: 'OutputCompressedAccountWithPackedContext'; + }; + }; + }, + { + name: 'outputLeafIndices'; + type: { + vec: 'u32'; + }; + }, + { + name: 'sequenceNumbers'; + type: { + vec: { + defined: 'MerkleTreeSequenceNumber'; + }; + }; + }, + { + name: 'relayFee'; + type: { + option: 'u64'; + }; + }, + { + name: 'isCompress'; + type: 'bool'; + }, + { + name: 'compressOrDecompressLamports'; + type: { + option: 'u64'; + }; + }, + { + name: 'pubkeyArray'; + type: { + vec: 'publicKey'; + }; + }, + { + name: 'message'; + type: { + option: 'bytes'; + }; + }, + ]; + }; + }, + { + name: 'QueueIndex'; + type: { + kind: 'struct'; + fields: [ + { + name: 'queueId'; + docs: ['Id of queue in queue account.']; + type: 'u8'; + }, + { + name: 'index'; + docs: ['Index of compressed account hash in queue.']; + type: 'u16'; + }, + ]; + }; + }, + { + name: 'TokenData'; + type: { + kind: 'struct'; + fields: [ + { + name: 'mint'; + docs: ['The mint associated with this account']; + type: 'publicKey'; + }, + { + name: 'owner'; + docs: ['The owner of this account.']; + type: 'publicKey'; + }, + { + name: 'amount'; + docs: ['The amount of tokens this account holds.']; + type: 'u64'; + }, + { + name: 'delegate'; + docs: [ + 'If `delegate` is `Some` then `delegated_amount` represents', + 'the amount authorized by the delegate', + ]; + type: { + option: 'publicKey'; + }; + }, + { + name: 'state'; + docs: ["The account's state"]; + type: { + defined: 'AccountState'; + }; + }, + { + name: 'tlv'; + docs: [ + 'Placeholder for TokenExtension tlv data (unimplemented)', + ]; + type: { + option: 'bytes'; + }; + }, + ]; + }; + }, + ]; + errors: [ + { + code: 6000; + name: 'PublicKeyAmountMissmatch'; + msg: 'public keys and amounts must be of same length'; + }, + { + code: 6001; + name: 'ComputeInputSumFailed'; + msg: 'ComputeInputSumFailed'; + }, + { + code: 6002; + name: 'ComputeOutputSumFailed'; + msg: 'ComputeOutputSumFailed'; + }, + { + code: 6003; + name: 'ComputeCompressSumFailed'; + msg: 'ComputeCompressSumFailed'; + }, + { + code: 6004; + name: 'ComputeDecompressSumFailed'; + msg: 'ComputeDecompressSumFailed'; + }, + { + code: 6005; + name: 'SumCheckFailed'; + msg: 'SumCheckFailed'; + }, + { + code: 6006; + name: 'DecompressRecipientUndefinedForDecompress'; + msg: 'DecompressRecipientUndefinedForDecompress'; + }, + { + code: 6007; + name: 'CompressedPdaUndefinedForDecompress'; + msg: 'CompressedPdaUndefinedForDecompress'; + }, + { + code: 6008; + name: 'DeCompressAmountUndefinedForDecompress'; + msg: 'DeCompressAmountUndefinedForDecompress'; + }, + { + code: 6009; + name: 'CompressedPdaUndefinedForCompress'; + msg: 'CompressedPdaUndefinedForCompress'; + }, + { + code: 6010; + name: 'DeCompressAmountUndefinedForCompress'; + msg: 'DeCompressAmountUndefinedForCompress'; + }, + { + code: 6011; + name: 'DelegateSignerCheckFailed'; + msg: 'DelegateSignerCheckFailed'; + }, + { + code: 6012; + name: 'MintTooLarge'; + msg: 'Minted amount greater than u64::MAX'; + }, + { + code: 6013; + name: 'SplTokenSupplyMismatch'; + msg: 'SplTokenSupplyMismatch'; + }, + { + code: 6014; + name: 'HeapMemoryCheckFailed'; + msg: 'HeapMemoryCheckFailed'; + }, + { + code: 6015; + name: 'InstructionNotCallable'; + msg: 'The instruction is not callable'; + }, + { + code: 6016; + name: 'ArithmeticUnderflow'; + msg: 'ArithmeticUnderflow'; + }, + { + code: 6017; + name: 'HashToFieldError'; + msg: 'HashToFieldError'; + }, + { + code: 6018; + name: 'InvalidAuthorityMint'; + msg: 'Expected the authority to be also a mint authority'; + }, + { + code: 6019; + name: 'InvalidFreezeAuthority'; + msg: 'Provided authority is not the freeze authority'; + }, + { + code: 6020; + name: 'InvalidDelegateIndex'; + }, + { + code: 6021; + name: 'TokenPoolPdaUndefined'; + }, + { + code: 6022; + name: 'IsTokenPoolPda'; + msg: 'Compress or decompress recipient is the same account as the token pool pda.'; + }, + { + code: 6023; + name: 'InvalidTokenPoolPda'; + }, + { + code: 6024; + name: 'NoInputTokenAccountsProvided'; + }, + { + code: 6025; + name: 'NoInputsProvided'; + }, + { + code: 6026; + name: 'MintHasNoFreezeAuthority'; + }, + { + code: 6027; + name: 'MintWithInvalidExtension'; + }, + { + code: 6028; + name: 'InsufficientTokenAccountBalance'; + msg: 'The token account balance is less than the remaining amount.'; + }, + { + code: 6029; + name: 'InvalidTokenPoolBump'; + msg: 'Max number of token pools reached.'; + }, + { + code: 6030; + name: 'FailedToDecompress'; + }, + { + code: 6031; + name: 'FailedToBurnSplTokensFromTokenPool'; + }, + { + code: 6032; + name: 'NoMatchingBumpFound'; + }, + ]; +}; +export const IDL: LightCompressedToken = { + version: '1.2.0', + name: 'light_compressed_token', + instructions: [ + { + name: 'createTokenPool', + docs: [ + 'This instruction creates a token pool for a given mint. Every spl mint', + 'can have one token pool. When a token is compressed the tokens are', + 'transferrred to the token pool, and their compressed equivalent is', + 'minted into a Merkle tree.', + ], + accounts: [ + { + name: 'feePayer', + isMut: true, + isSigner: true, + docs: ['UNCHECKED: only pays fees.'], + }, + { + name: 'tokenPoolPda', + isMut: true, + isSigner: false, + }, + { + name: 'systemProgram', + isMut: false, + isSigner: false, + }, + { + name: 'mint', + isMut: true, + isSigner: false, + }, + { + name: 'tokenProgram', + isMut: false, + isSigner: false, + }, + { + name: 'cpiAuthorityPda', + isMut: false, + isSigner: false, + }, + ], + args: [], + }, + { + name: 'addTokenPool', + docs: [ + 'This instruction creates an additional token pool for a given mint.', + 'The maximum number of token pools per mint is 5.', + ], + accounts: [ + { + name: 'feePayer', + isMut: true, + isSigner: true, + docs: ['UNCHECKED: only pays fees.'], + }, + { + name: 'tokenPoolPda', + isMut: true, + isSigner: false, + }, + { + name: 'existingTokenPoolPda', + isMut: false, + isSigner: false, + }, + { + name: 'systemProgram', + isMut: false, + isSigner: false, + }, + { + name: 'mint', + isMut: true, + isSigner: false, + }, + { + name: 'tokenProgram', + isMut: false, + isSigner: false, + }, + { + name: 'cpiAuthorityPda', + isMut: false, + isSigner: false, + }, + ], + args: [ + { + name: 'tokenPoolBump', + type: 'u8', + }, + ], + }, + { + name: 'mintTo', + docs: [ + 'Mints tokens from an spl token mint to a list of compressed accounts.', + 'Minted tokens are transferred to a pool account owned by the compressed', + 'token program. The instruction creates one compressed output account for', + 'every amount and pubkey input pair. A constant amount of lamports can be', + 'transferred to each output account to enable. A use case to add lamports', + 'to a compressed token account is to prevent spam. This is the only way', + 'to add lamports to a compressed token account.', + ], + accounts: [ + { + name: 'feePayer', + isMut: true, + isSigner: true, + docs: ['UNCHECKED: only pays fees.'], + }, + { + name: 'authority', + isMut: false, + isSigner: true, + }, + { + name: 'cpiAuthorityPda', + isMut: false, + isSigner: false, + }, + { + name: 'mint', + isMut: true, + isSigner: false, + }, + { + name: 'tokenPoolPda', + isMut: true, + isSigner: false, + }, + { + name: 'tokenProgram', + isMut: false, + isSigner: false, + }, + { + name: 'lightSystemProgram', + isMut: false, + isSigner: false, + }, + { + name: 'registeredProgramPda', + isMut: false, + isSigner: false, + }, + { + name: 'noopProgram', + isMut: false, + isSigner: false, + docs: ['programs'], + }, + { + name: 'accountCompressionAuthority', + isMut: false, + isSigner: false, + }, + { + name: 'accountCompressionProgram', + isMut: false, + isSigner: false, + }, + { + name: 'merkleTree', + isMut: true, + isSigner: false, + }, + { + name: 'selfProgram', + isMut: false, + isSigner: false, + }, + { + name: 'systemProgram', + isMut: false, + isSigner: false, + }, + { + name: 'solPoolPda', + isMut: true, + isSigner: false, + isOptional: true, + }, + ], + args: [ + { + name: 'publicKeys', + type: { + vec: 'publicKey', + }, + }, + { + name: 'amounts', + type: { + vec: 'u64', + }, + }, + { + name: 'lamports', + type: { + option: 'u64', + }, + }, + ], + }, + { + name: 'compressSplTokenAccount', + docs: [ + 'Compresses the balance of an spl token account sub an optional remaining', + 'amount. This instruction does not close the spl token account. To close', + 'the account bundle a close spl account instruction in your transaction.', + ], + accounts: [ + { + name: 'feePayer', + isMut: true, + isSigner: true, + docs: ['UNCHECKED: only pays fees.'], + }, + { + name: 'authority', + isMut: false, + isSigner: true, + docs: [ + 'Authority is verified through proof since both owner and delegate', + 'are included in the token data hash, which is a public input to the', + 'validity proof.', + ], + }, + { + name: 'cpiAuthorityPda', + isMut: false, + isSigner: false, + }, + { + name: 'lightSystemProgram', + isMut: false, + isSigner: false, + }, + { + name: 'registeredProgramPda', + isMut: false, + isSigner: false, + }, + { + name: 'noopProgram', + isMut: false, + isSigner: false, + }, + { + name: 'accountCompressionAuthority', + isMut: false, + isSigner: false, + }, + { + name: 'accountCompressionProgram', + isMut: false, + isSigner: false, + }, + { + name: 'selfProgram', + isMut: false, + isSigner: false, + docs: ['this program is the signer of the cpi.'], + }, + { + name: 'tokenPoolPda', + isMut: true, + isSigner: false, + isOptional: true, + }, + { + name: 'compressOrDecompressTokenAccount', + isMut: true, + isSigner: false, + isOptional: true, + }, + { + name: 'tokenProgram', + isMut: false, + isSigner: false, + isOptional: true, + }, + { + name: 'systemProgram', + isMut: false, + isSigner: false, + }, + ], + args: [ + { + name: 'owner', + type: 'publicKey', + }, + { + name: 'remainingAmount', + type: { + option: 'u64', + }, + }, + { + name: 'cpiContext', + type: { + option: { + defined: 'CompressedCpiContext', + }, + }, + }, + ], + }, + { + name: 'transfer', + docs: [ + 'Transfers compressed tokens from one account to another. All accounts', + 'must be of the same mint. Additional spl tokens can be compressed or', + 'decompressed. In one transaction only compression or decompression is', + 'possible. Lamports can be transferred alongside tokens. If output token', + 'accounts specify less lamports than inputs the remaining lamports are', + 'transferred to an output compressed account. Signer must be owner or', + 'delegate. If a delegated token account is transferred the delegate is', + 'not preserved.', + ], + accounts: [ + { + name: 'feePayer', + isMut: true, + isSigner: true, + docs: ['UNCHECKED: only pays fees.'], + }, + { + name: 'authority', + isMut: false, + isSigner: true, + docs: [ + 'Authority is verified through proof since both owner and delegate', + 'are included in the token data hash, which is a public input to the', + 'validity proof.', + ], + }, + { + name: 'cpiAuthorityPda', + isMut: false, + isSigner: false, + }, + { + name: 'lightSystemProgram', + isMut: false, + isSigner: false, + }, + { + name: 'registeredProgramPda', + isMut: false, + isSigner: false, + }, + { + name: 'noopProgram', + isMut: false, + isSigner: false, + }, + { + name: 'accountCompressionAuthority', + isMut: false, + isSigner: false, + }, + { + name: 'accountCompressionProgram', + isMut: false, + isSigner: false, + }, + { + name: 'selfProgram', + isMut: false, + isSigner: false, + docs: ['this program is the signer of the cpi.'], + }, + { + name: 'tokenPoolPda', + isMut: true, + isSigner: false, + isOptional: true, + }, + { + name: 'compressOrDecompressTokenAccount', + isMut: true, + isSigner: false, + isOptional: true, + }, + { + name: 'tokenProgram', + isMut: false, + isSigner: false, + isOptional: true, + }, + { + name: 'systemProgram', + isMut: false, + isSigner: false, + }, + ], + args: [ + { + name: 'inputs', + type: 'bytes', + }, + ], + }, + { + name: 'approve', + docs: [ + 'Delegates an amount to a delegate. A compressed token account is either', + 'completely delegated or not. Prior delegates are not preserved. Cannot', + 'be called by a delegate.', + 'The instruction creates two output accounts:', + '1. one account with delegated amount', + '2. one account with remaining(change) amount', + ], + accounts: [ + { + name: 'feePayer', + isMut: true, + isSigner: true, + docs: ['UNCHECKED: only pays fees.'], + }, + { + name: 'authority', + isMut: false, + isSigner: true, + docs: [ + 'Authority is verified through proof since both owner and delegate', + 'are included in the token data hash, which is a public input to the', + 'validity proof.', + ], + }, + { + name: 'cpiAuthorityPda', + isMut: false, + isSigner: false, + }, + { + name: 'lightSystemProgram', + isMut: false, + isSigner: false, + }, + { + name: 'registeredProgramPda', + isMut: false, + isSigner: false, + }, + { + name: 'noopProgram', + isMut: false, + isSigner: false, + }, + { + name: 'accountCompressionAuthority', + isMut: false, + isSigner: false, + }, + { + name: 'accountCompressionProgram', + isMut: false, + isSigner: false, + }, + { + name: 'selfProgram', + isMut: false, + isSigner: false, + docs: ['this program is the signer of the cpi.'], + }, + { + name: 'systemProgram', + isMut: false, + isSigner: false, + }, + ], + args: [ + { + name: 'inputs', + type: 'bytes', + }, + ], + }, + { + name: 'revoke', + docs: [ + 'Revokes a delegation. The instruction merges all inputs into one output', + 'account. Cannot be called by a delegate. Delegates are not preserved.', + ], + accounts: [ + { + name: 'feePayer', + isMut: true, + isSigner: true, + docs: ['UNCHECKED: only pays fees.'], + }, + { + name: 'authority', + isMut: false, + isSigner: true, + docs: [ + 'Authority is verified through proof since both owner and delegate', + 'are included in the token data hash, which is a public input to the', + 'validity proof.', + ], + }, + { + name: 'cpiAuthorityPda', + isMut: false, + isSigner: false, + }, + { + name: 'lightSystemProgram', + isMut: false, + isSigner: false, + }, + { + name: 'registeredProgramPda', + isMut: false, + isSigner: false, + }, + { + name: 'noopProgram', + isMut: false, + isSigner: false, + }, + { + name: 'accountCompressionAuthority', + isMut: false, + isSigner: false, + }, + { + name: 'accountCompressionProgram', + isMut: false, + isSigner: false, + }, + { + name: 'selfProgram', + isMut: false, + isSigner: false, + docs: ['this program is the signer of the cpi.'], + }, + { + name: 'systemProgram', + isMut: false, + isSigner: false, + }, + ], + args: [ + { + name: 'inputs', + type: 'bytes', + }, + ], + }, + { + name: 'freeze', + docs: [ + 'Freezes compressed token accounts. Inputs must not be frozen. Creates as', + 'many outputs as inputs. Balances and delegates are preserved.', + ], + accounts: [ + { + name: 'feePayer', + isMut: true, + isSigner: true, + docs: ['UNCHECKED: only pays fees.'], + }, + { + name: 'authority', + isMut: false, + isSigner: true, + }, + { + name: 'cpiAuthorityPda', + isMut: false, + isSigner: false, + }, + { + name: 'lightSystemProgram', + isMut: false, + isSigner: false, + }, + { + name: 'registeredProgramPda', + isMut: false, + isSigner: false, + }, + { + name: 'noopProgram', + isMut: false, + isSigner: false, + }, + { + name: 'accountCompressionAuthority', + isMut: false, + isSigner: false, + }, + { + name: 'accountCompressionProgram', + isMut: false, + isSigner: false, + }, + { + name: 'selfProgram', + isMut: false, + isSigner: false, + docs: ['that this program is the signer of the cpi.'], + }, + { + name: 'systemProgram', + isMut: false, + isSigner: false, + }, + { + name: 'mint', + isMut: false, + isSigner: false, + }, + ], + args: [ + { + name: 'inputs', + type: 'bytes', + }, + ], + }, + { + name: 'thaw', + docs: [ + 'Thaws frozen compressed token accounts. Inputs must be frozen. Creates', + 'as many outputs as inputs. Balances and delegates are preserved.', + ], + accounts: [ + { + name: 'feePayer', + isMut: true, + isSigner: true, + docs: ['UNCHECKED: only pays fees.'], + }, + { + name: 'authority', + isMut: false, + isSigner: true, + }, + { + name: 'cpiAuthorityPda', + isMut: false, + isSigner: false, + }, + { + name: 'lightSystemProgram', + isMut: false, + isSigner: false, + }, + { + name: 'registeredProgramPda', + isMut: false, + isSigner: false, + }, + { + name: 'noopProgram', + isMut: false, + isSigner: false, + }, + { + name: 'accountCompressionAuthority', + isMut: false, + isSigner: false, + }, + { + name: 'accountCompressionProgram', + isMut: false, + isSigner: false, + }, + { + name: 'selfProgram', + isMut: false, + isSigner: false, + docs: ['that this program is the signer of the cpi.'], + }, + { + name: 'systemProgram', + isMut: false, + isSigner: false, + }, + { + name: 'mint', + isMut: false, + isSigner: false, + }, + ], + args: [ + { + name: 'inputs', + type: 'bytes', + }, + ], + }, + { + name: 'burn', + docs: [ + 'Burns compressed tokens and spl tokens from the pool account. Delegates', + 'can burn tokens. The output compressed token account remains delegated.', + 'Creates one output compressed token account.', + ], + accounts: [ + { + name: 'feePayer', + isMut: true, + isSigner: true, + docs: ['UNCHECKED: only pays fees.'], + }, + { + name: 'authority', + isMut: false, + isSigner: true, + docs: [ + 'Authority is verified through proof since both owner and delegate', + 'are included in the token data hash, which is a public input to the', + 'validity proof.', + ], + }, + { + name: 'cpiAuthorityPda', + isMut: false, + isSigner: false, + }, + { + name: 'mint', + isMut: true, + isSigner: false, + }, + { + name: 'tokenPoolPda', + isMut: true, + isSigner: false, + }, + { + name: 'tokenProgram', + isMut: false, + isSigner: false, + }, + { + name: 'lightSystemProgram', + isMut: false, + isSigner: false, + }, + { + name: 'registeredProgramPda', + isMut: false, + isSigner: false, + }, + { + name: 'noopProgram', + isMut: false, + isSigner: false, + }, + { + name: 'accountCompressionAuthority', + isMut: false, + isSigner: false, + }, + { + name: 'accountCompressionProgram', + isMut: false, + isSigner: false, + }, + { + name: 'selfProgram', + isMut: false, + isSigner: false, + }, + { + name: 'systemProgram', + isMut: false, + isSigner: false, + }, + ], + args: [ + { + name: 'inputs', + type: 'bytes', + }, + ], + }, + { + name: 'stubIdlBuild', + docs: [ + 'This function is a stub to allow Anchor to include the input types in', + 'the IDL. It should not be included in production builds nor be called in', + 'practice.', + ], + accounts: [ + { + name: 'feePayer', + isMut: true, + isSigner: true, + docs: ['UNCHECKED: only pays fees.'], + }, + { + name: 'authority', + isMut: false, + isSigner: true, + docs: [ + 'Authority is verified through proof since both owner and delegate', + 'are included in the token data hash, which is a public input to the', + 'validity proof.', + ], + }, + { + name: 'cpiAuthorityPda', + isMut: false, + isSigner: false, + }, + { + name: 'lightSystemProgram', + isMut: false, + isSigner: false, + }, + { + name: 'registeredProgramPda', + isMut: false, + isSigner: false, + }, + { + name: 'noopProgram', + isMut: false, + isSigner: false, + }, + { + name: 'accountCompressionAuthority', + isMut: false, + isSigner: false, + }, + { + name: 'accountCompressionProgram', + isMut: false, + isSigner: false, + }, + { + name: 'selfProgram', + isMut: false, + isSigner: false, + docs: ['this program is the signer of the cpi.'], + }, + { + name: 'tokenPoolPda', + isMut: true, + isSigner: false, + isOptional: true, + }, + { + name: 'compressOrDecompressTokenAccount', + isMut: true, + isSigner: false, + isOptional: true, + }, + { + name: 'tokenProgram', + isMut: false, + isSigner: false, + isOptional: true, + }, + { + name: 'systemProgram', + isMut: false, + isSigner: false, + }, + ], + args: [ + { + name: 'inputs1', + type: { + defined: 'CompressedTokenInstructionDataTransfer', + }, + }, + { + name: 'inputs2', + type: { + defined: 'TokenData', + }, + }, + ], + }, + ], + types: [ + { + name: 'AccountState', + type: { + kind: 'enum', + variants: [ + { + name: 'Initialized', + }, + { + name: 'Frozen', + }, + ], + }, + }, + { + name: 'CompressedAccount', + type: { + kind: 'struct', + fields: [ + { + name: 'owner', + type: 'publicKey', + }, + { + name: 'lamports', + type: 'u64', + }, + { + name: 'address', + type: { + option: { + array: ['u8', 32], + }, + }, + }, + { + name: 'data', + type: { + option: { + defined: 'CompressedAccountData', + }, + }, + }, + ], + }, + }, + { + name: 'CompressedAccountData', + type: { + kind: 'struct', + fields: [ + { + name: 'discriminator', + type: { + array: ['u8', 8], + }, + }, + { + name: 'data', + type: 'bytes', + }, + { + name: 'dataHash', + type: { + array: ['u8', 32], + }, + }, + ], + }, + }, + { + name: 'CompressedCpiContext', + type: { + kind: 'struct', + fields: [ + { + name: 'setContext', + docs: [ + 'Is set by the program that is invoking the CPI to signal that is should', + 'set the cpi context.', + ], + type: 'bool', + }, + { + name: 'firstSetContext', + docs: [ + 'Is set to wipe the cpi context since someone could have set it before', + 'with unrelated data.', + ], + type: 'bool', + }, + { + name: 'cpiContextAccountIndex', + docs: [ + 'Index of cpi context account in remaining accounts.', + ], + type: 'u8', + }, + ], + }, + }, + { + name: 'CompressedProof', + type: { + kind: 'struct', + fields: [ + { + name: 'a', + type: { + array: ['u8', 32], + }, + }, + { + name: 'b', + type: { + array: ['u8', 64], + }, + }, + { + name: 'c', + type: { + array: ['u8', 32], + }, + }, + ], + }, + }, + { + name: 'CompressedTokenInstructionDataTransfer', + type: { + kind: 'struct', + fields: [ + { + name: 'proof', + type: { + option: { + defined: 'CompressedProof', + }, + }, + }, + { + name: 'mint', + type: 'publicKey', + }, + { + name: 'delegatedTransfer', + docs: [ + 'Is required if the signer is delegate,', + '-> delegate is authority account,', + 'owner = Some(owner) is the owner of the token account.', + ], + type: { + option: { + defined: 'DelegatedTransfer', + }, + }, + }, + { + name: 'inputTokenDataWithContext', + type: { + vec: { + defined: 'InputTokenDataWithContext', + }, + }, + }, + { + name: 'outputCompressedAccounts', + type: { + vec: { + defined: 'PackedTokenTransferOutputData', + }, + }, + }, + { + name: 'isCompress', + type: 'bool', + }, + { + name: 'compressOrDecompressAmount', + type: { + option: 'u64', + }, + }, + { + name: 'cpiContext', + type: { + option: { + defined: 'CompressedCpiContext', + }, + }, + }, + { + name: 'lamportsChangeAccountMerkleTreeIndex', + type: { + option: 'u8', + }, + }, + ], + }, + }, + { + name: 'DelegatedTransfer', + docs: [ + 'Struct to provide the owner when the delegate is signer of the transaction.', + ], + type: { + kind: 'struct', + fields: [ + { + name: 'owner', + type: 'publicKey', + }, + { + name: 'delegateChangeAccountIndex', + docs: [ + 'Index of change compressed account in output compressed accounts. In', + "case that the delegate didn't spend the complete delegated compressed", + 'account balance the change compressed account will be delegated to her', + 'as well.', + ], + type: { + option: 'u8', + }, + }, + ], + }, + }, + { + name: 'InputTokenDataWithContext', + type: { + kind: 'struct', + fields: [ + { + name: 'amount', + type: 'u64', + }, + { + name: 'delegateIndex', + type: { + option: 'u8', + }, + }, + { + name: 'merkleContext', + type: { + defined: 'PackedMerkleContext', + }, + }, + { + name: 'rootIndex', + type: 'u16', + }, + { + name: 'lamports', + type: { + option: 'u64', + }, + }, + { + name: 'tlv', + docs: [ + 'Placeholder for TokenExtension tlv data (unimplemented)', + ], + type: { + option: 'bytes', + }, + }, + ], + }, + }, + { + name: 'InstructionDataInvoke', + type: { + kind: 'struct', + fields: [ + { + name: 'proof', + type: { + option: { + defined: 'CompressedProof', + }, + }, + }, + { + name: 'inputCompressedAccountsWithMerkleContext', + type: { + vec: { + defined: + 'PackedCompressedAccountWithMerkleContext', + }, + }, + }, + { + name: 'outputCompressedAccounts', + type: { + vec: { + defined: + 'OutputCompressedAccountWithPackedContext', + }, + }, + }, + { + name: 'relayFee', + type: { + option: 'u64', + }, + }, + { + name: 'newAddressParams', + type: { + vec: { + defined: 'NewAddressParamsPacked', + }, + }, + }, + { + name: 'compressOrDecompressLamports', + type: { + option: 'u64', + }, + }, + { + name: 'isCompress', + type: 'bool', + }, + ], + }, + }, + { + name: 'InstructionDataInvokeCpi', + type: { + kind: 'struct', + fields: [ + { + name: 'proof', + type: { + option: { + defined: 'CompressedProof', + }, + }, + }, + { + name: 'newAddressParams', + type: { + vec: { + defined: 'NewAddressParamsPacked', + }, + }, + }, + { + name: 'inputCompressedAccountsWithMerkleContext', + type: { + vec: { + defined: + 'PackedCompressedAccountWithMerkleContext', + }, + }, + }, + { + name: 'outputCompressedAccounts', + type: { + vec: { + defined: + 'OutputCompressedAccountWithPackedContext', + }, + }, + }, + { + name: 'relayFee', + type: { + option: 'u64', + }, + }, + { + name: 'compressOrDecompressLamports', + type: { + option: 'u64', + }, + }, + { + name: 'isCompress', + type: 'bool', + }, + { + name: 'cpiContext', + type: { + option: { + defined: 'CompressedCpiContext', + }, + }, + }, + ], + }, + }, + { + name: 'MerkleTreeSequenceNumber', + type: { + kind: 'struct', + fields: [ + { + name: 'pubkey', + type: 'publicKey', + }, + { + name: 'seq', + type: 'u64', + }, + ], + }, + }, + { + name: 'NewAddressParamsPacked', + type: { + kind: 'struct', + fields: [ + { + name: 'seed', + type: { + array: ['u8', 32], + }, + }, + { + name: 'addressQueueAccountIndex', + type: 'u8', + }, + { + name: 'addressMerkleTreeAccountIndex', + type: 'u8', + }, + { + name: 'addressMerkleTreeRootIndex', + type: 'u16', + }, + ], + }, + }, + { + name: 'OutputCompressedAccountWithPackedContext', + type: { + kind: 'struct', + fields: [ + { + name: 'compressedAccount', + type: { + defined: 'CompressedAccount', + }, + }, + { + name: 'merkleTreeIndex', + type: 'u8', + }, + ], + }, + }, + { + name: 'PackedCompressedAccountWithMerkleContext', + type: { + kind: 'struct', + fields: [ + { + name: 'compressedAccount', + type: { + defined: 'CompressedAccount', + }, + }, + { + name: 'merkleContext', + type: { + defined: 'PackedMerkleContext', + }, + }, + { + name: 'rootIndex', + docs: [ + 'Index of root used in inclusion validity proof.', + ], + type: 'u16', + }, + { + name: 'readOnly', + docs: [ + 'Placeholder to mark accounts read-only unimplemented set to false.', + ], + type: 'bool', + }, + ], + }, + }, + { + name: 'PackedMerkleContext', + type: { + kind: 'struct', + fields: [ + { + name: 'merkleTreePubkeyIndex', + type: 'u8', + }, + { + name: 'nullifierQueuePubkeyIndex', + type: 'u8', + }, + { + name: 'leafIndex', + type: 'u32', + }, + { + name: 'queueIndex', + type: { + option: { + defined: 'QueueIndex', + }, + }, + }, + ], + }, + }, + { + name: 'PackedTokenTransferOutputData', + type: { + kind: 'struct', + fields: [ + { + name: 'owner', + type: 'publicKey', + }, + { + name: 'amount', + type: 'u64', + }, + { + name: 'lamports', + type: { + option: 'u64', + }, + }, + { + name: 'merkleTreeIndex', + type: 'u8', + }, + { + name: 'tlv', + docs: [ + 'Placeholder for TokenExtension tlv data (unimplemented)', + ], + type: { + option: 'bytes', + }, + }, + ], + }, + }, + { + name: 'PublicTransactionEvent', + type: { + kind: 'struct', + fields: [ + { + name: 'inputCompressedAccountHashes', + type: { + vec: { + array: ['u8', 32], + }, + }, + }, + { + name: 'outputCompressedAccountHashes', + type: { + vec: { + array: ['u8', 32], + }, + }, + }, + { + name: 'outputCompressedAccounts', + type: { + vec: { + defined: + 'OutputCompressedAccountWithPackedContext', + }, + }, + }, + { + name: 'outputLeafIndices', + type: { + vec: 'u32', + }, + }, + { + name: 'sequenceNumbers', + type: { + vec: { + defined: 'MerkleTreeSequenceNumber', + }, + }, + }, + { + name: 'relayFee', + type: { + option: 'u64', + }, + }, + { + name: 'isCompress', + type: 'bool', + }, + { + name: 'compressOrDecompressLamports', + type: { + option: 'u64', + }, + }, + { + name: 'pubkeyArray', + type: { + vec: 'publicKey', + }, + }, + { + name: 'message', + type: { + option: 'bytes', + }, + }, + ], + }, + }, + { + name: 'QueueIndex', + type: { + kind: 'struct', + fields: [ + { + name: 'queueId', + docs: ['Id of queue in queue account.'], + type: 'u8', + }, + { + name: 'index', + docs: ['Index of compressed account hash in queue.'], + type: 'u16', + }, + ], + }, + }, + { + name: 'TokenData', + type: { + kind: 'struct', + fields: [ + { + name: 'mint', + docs: ['The mint associated with this account'], + type: 'publicKey', + }, + { + name: 'owner', + docs: ['The owner of this account.'], + type: 'publicKey', + }, + { + name: 'amount', + docs: ['The amount of tokens this account holds.'], + type: 'u64', + }, + { + name: 'delegate', + docs: [ + 'If `delegate` is `Some` then `delegated_amount` represents', + 'the amount authorized by the delegate', + ], + type: { + option: 'publicKey', + }, + }, + { + name: 'state', + docs: ["The account's state"], + type: { + defined: 'AccountState', + }, + }, + { + name: 'tlv', + docs: [ + 'Placeholder for TokenExtension tlv data (unimplemented)', + ], + type: { + option: 'bytes', + }, + }, + ], + }, + }, + ], + errors: [ + { + code: 6000, + name: 'PublicKeyAmountMissmatch', + msg: 'public keys and amounts must be of same length', + }, + { + code: 6001, + name: 'ComputeInputSumFailed', + msg: 'ComputeInputSumFailed', + }, + { + code: 6002, + name: 'ComputeOutputSumFailed', + msg: 'ComputeOutputSumFailed', + }, + { + code: 6003, + name: 'ComputeCompressSumFailed', + msg: 'ComputeCompressSumFailed', + }, + { + code: 6004, + name: 'ComputeDecompressSumFailed', + msg: 'ComputeDecompressSumFailed', + }, + { + code: 6005, + name: 'SumCheckFailed', + msg: 'SumCheckFailed', + }, + { + code: 6006, + name: 'DecompressRecipientUndefinedForDecompress', + msg: 'DecompressRecipientUndefinedForDecompress', + }, + { + code: 6007, + name: 'CompressedPdaUndefinedForDecompress', + msg: 'CompressedPdaUndefinedForDecompress', + }, + { + code: 6008, + name: 'DeCompressAmountUndefinedForDecompress', + msg: 'DeCompressAmountUndefinedForDecompress', + }, + { + code: 6009, + name: 'CompressedPdaUndefinedForCompress', + msg: 'CompressedPdaUndefinedForCompress', + }, + { + code: 6010, + name: 'DeCompressAmountUndefinedForCompress', + msg: 'DeCompressAmountUndefinedForCompress', + }, + { + code: 6011, + name: 'DelegateSignerCheckFailed', + msg: 'DelegateSignerCheckFailed', + }, + { + code: 6012, + name: 'MintTooLarge', + msg: 'Minted amount greater than u64::MAX', + }, + { + code: 6013, + name: 'SplTokenSupplyMismatch', + msg: 'SplTokenSupplyMismatch', + }, + { + code: 6014, + name: 'HeapMemoryCheckFailed', + msg: 'HeapMemoryCheckFailed', + }, + { + code: 6015, + name: 'InstructionNotCallable', + msg: 'The instruction is not callable', + }, + { + code: 6016, + name: 'ArithmeticUnderflow', + msg: 'ArithmeticUnderflow', + }, + { + code: 6017, + name: 'HashToFieldError', + msg: 'HashToFieldError', + }, + { + code: 6018, + name: 'InvalidAuthorityMint', + msg: 'Expected the authority to be also a mint authority', + }, + { + code: 6019, + name: 'InvalidFreezeAuthority', + msg: 'Provided authority is not the freeze authority', + }, + { + code: 6020, + name: 'InvalidDelegateIndex', + }, + { + code: 6021, + name: 'TokenPoolPdaUndefined', + }, + { + code: 6022, + name: 'IsTokenPoolPda', + msg: 'Compress or decompress recipient is the same account as the token pool pda.', + }, + { + code: 6023, + name: 'InvalidTokenPoolPda', + }, + { + code: 6024, + name: 'NoInputTokenAccountsProvided', + }, + { + code: 6025, + name: 'NoInputsProvided', + }, + { + code: 6026, + name: 'MintHasNoFreezeAuthority', + }, + { + code: 6027, + name: 'MintWithInvalidExtension', + }, + { + code: 6028, + name: 'InsufficientTokenAccountBalance', + msg: 'The token account balance is less than the remaining amount.', + }, + { + code: 6029, + name: 'InvalidTokenPoolBump', + msg: 'Max number of token pools reached.', + }, + { + code: 6030, + name: 'FailedToDecompress', + }, + { + code: 6031, + name: 'FailedToBurnSplTokensFromTokenPool', + }, + { + code: 6032, + name: 'NoMatchingBumpFound', + }, + ], +}; diff --git a/js/compressed-token/src/index.ts b/js/compressed-token/src/index.ts index 1f8eed140c..3df507112b 100644 --- a/js/compressed-token/src/index.ts +++ b/js/compressed-token/src/index.ts @@ -4,3 +4,4 @@ export * from './program'; export * from './types'; export * from './actions'; export * from './layout'; +export * from './idl'; diff --git a/js/compressed-token/src/layout.ts b/js/compressed-token/src/layout.ts index 000bb8c853..827fffddbb 100644 --- a/js/compressed-token/src/layout.ts +++ b/js/compressed-token/src/layout.ts @@ -49,7 +49,7 @@ const InputTokenDataWithContextLayout = struct([ u8('merkleTreePubkeyIndex'), u8('nullifierQueuePubkeyIndex'), u32('leafIndex'), - option(QueueIndexLayout, 'QueueIndex'), + option(QueueIndexLayout, 'queueIndex'), ], 'merkleContext', ), @@ -105,6 +105,7 @@ export function encodeMintToInstructionData( }, buffer, ); + return Buffer.concat([MINT_TO_DISCRIMINATOR, buffer.slice(0, len)]); } @@ -133,6 +134,7 @@ export function encodeCompressSplTokenAccountInstructionData( }, buffer, ); + return Buffer.concat([ COMPRESS_SPL_TOKEN_ACCOUNT_DISCRIMINATOR, buffer.slice(0, len), diff --git a/js/compressed-token/src/program.ts b/js/compressed-token/src/program.ts index 9fe622b488..e63d694e64 100644 --- a/js/compressed-token/src/program.ts +++ b/js/compressed-token/src/program.ts @@ -775,7 +775,7 @@ export class CompressedTokenProgram { cpiContext: null, lamportsChangeAccountMerkleTreeIndex: null, }; - + console.log('TRANSFER'); const data = encodeTransferInstructionData(rawData); const { @@ -940,7 +940,7 @@ export class CompressedTokenProgram { cpiContext: null, lamportsChangeAccountMerkleTreeIndex: null, }; - + console.log('COMPRESS'); const data = encodeTransferInstructionData(rawData); const tokenProgram = tokenProgramId ?? TOKEN_PROGRAM_ID; @@ -1016,6 +1016,7 @@ export class CompressedTokenProgram { cpiContext: null, lamportsChangeAccountMerkleTreeIndex: null, }; + console.log('DECOMPRESS'); const data = encodeTransferInstructionData(rawData); const tokenProgram = tokenProgramId ?? TOKEN_PROGRAM_ID; const { @@ -1065,7 +1066,7 @@ export class CompressedTokenProgram { if (inputCompressedTokenAccounts.length > 3) { throw new Error('Cannot merge more than 3 token accounts at once'); } - + console.log('MERGE'); const ix = await this.transfer({ payer, inputCompressedTokenAccounts, diff --git a/js/compressed-token/tests/e2e/layout.test.ts b/js/compressed-token/tests/e2e/layout.test.ts index 78de4e59e8..b6f20d8714 100644 --- a/js/compressed-token/tests/e2e/layout.test.ts +++ b/js/compressed-token/tests/e2e/layout.test.ts @@ -1,20 +1,45 @@ import { describe, it, expect } from 'vitest'; import { PublicKey } from '@solana/web3.js'; +import { + Program, + AnchorProvider, + setProvider, + Wallet, +} from '@coral-xyz/anchor'; import BN from 'bn.js'; import { - CompressedTokenInstructionDataTransferLayout, - CompressedTokenInstructionDataTransfer, - mintToLayout, - compressSplTokenAccountInstructionDataLayout, encodeMintToInstructionData, decodeMintToInstructionData, encodeCompressSplTokenAccountInstructionData, decodeCompressSplTokenAccountInstructionData, encodeTransferInstructionData, decodeTransferInstructionData, - MintToInstructionData, - CompressSplTokenAccountInstructionData, + IDL, + LightCompressedToken, + mintToAccountsLayout, + createTokenPoolAccountsLayout, + transferAccountsLayout, } from '../../src/'; +import { Keypair } from '@solana/web3.js'; +import { Connection } from '@solana/web3.js'; + +const getTestProgram = (): Program => { + const mockKeypair = Keypair.generate(); + const mockConnection = new Connection('http://127.0.0.1:8899', 'confirmed'); + const mockProvider = new AnchorProvider( + mockConnection, + new Wallet(mockKeypair), + { + commitment: 'confirmed', + }, + ); + setProvider(mockProvider); + return new Program( + IDL, + new PublicKey('cTokenmWW8bLPjZEBAUgYy3zKxQZW6VKi7bqNFEVv3m'), + mockProvider, + ); +}; function deepEqual(ref: any, val: any) { if (typeof ref !== typeof val) { @@ -37,7 +62,7 @@ function deepEqual(ref: any, val: any) { return false; } - for (let key of refKeys) { + for (const key of refKeys) { if (!valKeys.includes(key)) { console.log(`Key ${key} not found in value`); return false; @@ -57,129 +82,633 @@ function deepEqual(ref: any, val: any) { return ref === val; } +const IX_DISCRIMINATOR = 8; +const LENGTH_DISCRIMINATOR = 4; + describe('layout', () => { - it('encode/decode CompressedTokenInstructionDataTransfer', () => { - const data: CompressedTokenInstructionDataTransfer = { - proof: null, - mint: new PublicKey('CXzk7xBgfzwSrZincWbJPGMPFz8aut3V6JjXp5n3XvGQ'), - delegatedTransfer: null, - inputTokenDataWithContext: [], - outputCompressedAccounts: [ - { - owner: new PublicKey( - '7gpbzzu2Aj2sE7LFdEQKUoZLqxVAK3eQ9LoeKQ5zCxQJ', + describe('encode/decode transfer/compress/decompress', () => { + const testCases = [ + { + description: 'default case', + data: { + proof: { + a: [ + 32, 3, 117, 58, 153, 131, 148, 196, 202, 221, 250, + 146, 196, 209, 8, 192, 211, 235, 57, 47, 234, 98, + 152, 195, 227, 9, 16, 156, 194, 41, 247, 89, + ], + b: [ + 22, 192, 18, 134, 24, 94, 169, 42, 151, 182, 237, + 164, 250, 163, 253, 24, 51, 142, 37, 55, 141, 92, + 198, 146, 177, 23, 113, 12, 122, 27, 143, 64, 26, + 191, 99, 235, 113, 154, 23, 234, 173, 101, 16, 34, + 192, 108, 61, 10, 206, 251, 84, 242, 238, 92, 131, + 107, 252, 227, 70, 181, 35, 236, 195, 209, + ], + c: [ + 166, 160, 56, 185, 41, 239, 140, 4, 255, 144, 213, + 185, 153, 246, 199, 206, 47, 210, 17, 10, 66, 68, + 132, 229, 12, 67, 166, 168, 229, 156, 90, 30, + ], + }, + mint: new PublicKey( + 'Bwuvv7NXd59zXRvWRCXcPLvwZ2dfedyQ9XZyqDghRFxv', ), - amount: new BN(700), - lamports: null, - merkleTreeIndex: 0, - tlv: null, - }, - ], - isCompress: true, - compressOrDecompressAmount: new BN(700), - cpiContext: null, - lamportsChangeAccountMerkleTreeIndex: null, - }; - - const encoded = encodeTransferInstructionData(data); - const decoded = decodeTransferInstructionData(encoded); - expect(deepEqual(decoded, data)).toBe(true); - }); + delegatedTransfer: null, + inputTokenDataWithContext: [ + { + amount: new BN('03e8', 16), + delegateIndex: null, + merkleContext: { + merkleTreePubkeyIndex: 0, + nullifierQueuePubkeyIndex: 1, + leafIndex: 10, + queueIndex: null, + }, + rootIndex: 11, + lamports: null, + tlv: null, + }, + ], + outputCompressedAccounts: [ + { + owner: new PublicKey( + 'ARaDUvjovQDvFTMqaNAu9f2j1MpqJ5rhDAnDFrnyKbwg', + ), + amount: new BN('012c', 16), + lamports: null, + merkleTreeIndex: 0, + tlv: null, + }, + { + owner: new PublicKey( + 'GWYLPLzCCAVxq12UvBSpU4F8pcsmmRYQobPxkGz67ZVx', + ), + amount: new BN('02bc', 16), + lamports: null, + merkleTreeIndex: 0, + tlv: null, + }, + ], + compressOrDecompressAmount: null, + isCompress: false, + cpiContext: null, + lamportsChangeAccountMerkleTreeIndex: null, + }, + }, + { + description: 'with compressOrDecompressAmount', + data: { + proof: null, + mint: new PublicKey( + 'Bwuvv7NXd59zXRvWRCXcPLvwZ2dfedyQ9XZyqDghRFxv', + ), + delegatedTransfer: null, + inputTokenDataWithContext: [], + outputCompressedAccounts: [], + compressOrDecompressAmount: new BN(500), + isCompress: true, + cpiContext: null, + lamportsChangeAccountMerkleTreeIndex: null, + }, + }, + { + description: 'with delegatedTransfer', + data: { + proof: null, + mint: new PublicKey( + 'Bwuvv7NXd59zXRvWRCXcPLvwZ2dfedyQ9XZyqDghRFxv', + ), + delegatedTransfer: { + owner: new PublicKey( + 'ARaDUvjovQDvFTMqaNAu9f2j1MpqJ5rhDAnDFrnyKbwg', + ), + delegateChangeAccountIndex: 1, + }, + inputTokenDataWithContext: [], + outputCompressedAccounts: [], + compressOrDecompressAmount: null, + isCompress: false, + cpiContext: null, + lamportsChangeAccountMerkleTreeIndex: null, + }, + }, + { + description: 'with proof none', + data: { + proof: null, + mint: new PublicKey( + 'Bwuvv7NXd59zXRvWRCXcPLvwZ2dfedyQ9XZyqDghRFxv', + ), + delegatedTransfer: null, + inputTokenDataWithContext: [], + outputCompressedAccounts: [], + compressOrDecompressAmount: null, + isCompress: false, + cpiContext: null, + lamportsChangeAccountMerkleTreeIndex: null, + }, + }, + { + description: 'with various inputTokenDataWithContext', + data: { + proof: null, + mint: new PublicKey( + 'Bwuvv7NXd59zXRvWRCXcPLvwZ2dfedyQ9XZyqDghRFxv', + ), + delegatedTransfer: null, + inputTokenDataWithContext: [ + { + amount: new BN(1000), + delegateIndex: 2, + merkleContext: { + merkleTreePubkeyIndex: 1, + nullifierQueuePubkeyIndex: 2, + leafIndex: 3, + queueIndex: { queueId: 0, index: 4 }, + }, + rootIndex: 5, + lamports: new BN(2000), + tlv: Buffer.from([1, 2, 3]), + }, + ], + outputCompressedAccounts: [], + compressOrDecompressAmount: null, + isCompress: false, + cpiContext: null, + lamportsChangeAccountMerkleTreeIndex: null, + }, + }, + { + description: 'with various outputCompressedAccounts', + data: { + proof: null, + mint: new PublicKey( + 'Bwuvv7NXd59zXRvWRCXcPLvwZ2dfedyQ9XZyqDghRFxv', + ), + delegatedTransfer: null, + inputTokenDataWithContext: [], + outputCompressedAccounts: [ + { + owner: new PublicKey( + 'ARaDUvjovQDvFTMqaNAu9f2j1MpqJ5rhDAnDFrnyKbwg', + ), + amount: new BN(3000), + lamports: new BN(4000), + merkleTreeIndex: 1, + tlv: Buffer.from([4, 5, 6]), + }, + ], + compressOrDecompressAmount: null, + isCompress: false, + cpiContext: null, + lamportsChangeAccountMerkleTreeIndex: null, + }, + }, + { + description: 'with isCompress true', + data: { + proof: null, + mint: new PublicKey( + 'Bwuvv7NXd59zXRvWRCXcPLvwZ2dfedyQ9XZyqDghRFxv', + ), + delegatedTransfer: null, + inputTokenDataWithContext: [], + outputCompressedAccounts: [], + compressOrDecompressAmount: null, + isCompress: true, + cpiContext: null, + lamportsChangeAccountMerkleTreeIndex: null, + }, + }, + { + description: 'with lamportsChangeAccountMerkleTreeIndex', + data: { + proof: null, + mint: new PublicKey( + 'Bwuvv7NXd59zXRvWRCXcPLvwZ2dfedyQ9XZyqDghRFxv', + ), + delegatedTransfer: null, + inputTokenDataWithContext: [], + outputCompressedAccounts: [], + compressOrDecompressAmount: null, + isCompress: false, + cpiContext: null, + lamportsChangeAccountMerkleTreeIndex: 5, + }, + }, + { + description: 'with cpiContext', + data: { + proof: null, + mint: new PublicKey( + 'Bwuvv7NXd59zXRvWRCXcPLvwZ2dfedyQ9XZyqDghRFxv', + ), + delegatedTransfer: null, + inputTokenDataWithContext: [], + outputCompressedAccounts: [], + compressOrDecompressAmount: null, + isCompress: false, + cpiContext: { + setContext: true, + firstSetContext: false, + cpiContextAccountIndex: 2, + }, + lamportsChangeAccountMerkleTreeIndex: null, + }, + }, + ]; - it('encode/decode MintToInstructionData', () => { - const data = { - recipients: [ - new PublicKey('CXzk7xBgfzwSrZincWbJPGMPFz8aut3V6JjXp5n3XvGQ'), - ], - amounts: [new BN(1000)], - lamports: new BN(500), - }; - - const encoded = encodeMintToInstructionData(data); - const decoded = decodeMintToInstructionData(encoded); - expect(deepEqual(decoded, data)).toBe(true); + testCases.forEach(({ description, data }) => { + it(`should encode/decode transfer: ${description}`, () => { + const anchorEncodedData = getTestProgram().coder.types.encode( + 'CompressedTokenInstructionDataTransfer', + data, + ); + const encoded = encodeTransferInstructionData(data); + const decoded = decodeTransferInstructionData(encoded); + expect(deepEqual(decoded, data)).toBe(true); + expect(anchorEncodedData).toEqual( + encoded.slice(IX_DISCRIMINATOR + LENGTH_DISCRIMINATOR), + ); + }); + }); }); - it('encode/decode CompressSplTokenAccountInstructionData', () => { - const data = { - owner: new PublicKey( - 'CXzk7xBgfzwSrZincWbJPGMPFz8aut3V6JjXp5n3XvGQ', - ), - remainingAmount: new BN(1000), - cpiContext: null, - }; - - const encoded = encodeCompressSplTokenAccountInstructionData(data); - const decoded = decodeCompressSplTokenAccountInstructionData(encoded); - expect(deepEqual(decoded, data)).toBe(true); + describe('encode/decode MintToInstructionData', () => { + const testCases = [ + { + description: 'default case', + data: { + recipients: [ + new PublicKey( + '6ASf5EcmmEHTgDJ4X4ZT5vT6iHVJBXPg5AN5YoTCpGWt', + ), + ], + amounts: [new BN(1000)], + lamports: null, + }, + }, + { + description: 'with multiple recipients', + data: { + recipients: [ + new PublicKey( + '6ASf5EcmmEHTgDJ4X4ZT5vT6iHVJBXPg5AN5YoTCpGWt', + ), + new PublicKey( + '8ASf5EcmmEHTgDJ4X4ZT5vT6iHVJBXPg5AN5YoTCpGWs', + ), + ], + amounts: [new BN(1000), new BN(2000)], + lamports: null, + }, + }, + { + description: 'with lamports', + data: { + recipients: [ + new PublicKey( + '6ASf5EcmmEHTgDJ4X4ZT5vT6iHVJBXPg5AN5YoTCpGWt', + ), + ], + amounts: [new BN(1000)], + lamports: new BN(500), + }, + }, + ]; + + testCases.forEach(async ({ description, data }) => { + it(description, async () => { + const encoded = encodeMintToInstructionData(data); + const decoded = decodeMintToInstructionData(encoded); + expect(deepEqual(decoded, data)).toBe(true); + + const instruction = await getTestProgram() + .methods.mintTo( + data.recipients, + data.amounts, + data.lamports, + ) + .accounts({ + feePayer: PublicKey.default, + authority: PublicKey.default, + cpiAuthorityPda: PublicKey.default, + mint: PublicKey.default, + tokenPoolPda: PublicKey.default, + tokenProgram: PublicKey.default, + lightSystemProgram: PublicKey.default, + registeredProgramPda: PublicKey.default, + noopProgram: PublicKey.default, + accountCompressionAuthority: PublicKey.default, + accountCompressionProgram: PublicKey.default, + merkleTree: PublicKey.default, + selfProgram: PublicKey.default, + solPoolPda: null, + }) + .instruction(); + expect(instruction.data).toEqual(encoded); + }); + }); }); - it('validate CompressedTokenInstructionDataTransferLayout', () => { - const data: CompressedTokenInstructionDataTransfer = { - proof: null, - mint: new PublicKey('CXzk7xBgfzwSrZincWbJPGMPFz8aut3V6JjXp5n3XvGQ'), - delegatedTransfer: null, - inputTokenDataWithContext: [], - outputCompressedAccounts: [ - { + describe('encode/decode CompressSplTokenAccountInstructionData', () => { + const testCases = [ + { + description: 'default case', + data: { owner: new PublicKey( - '7gpbzzu2Aj2sE7LFdEQKUoZLqxVAK3eQ9LoeKQ5zCxQJ', + 'CPMzHV9PsUeb5pFmyrj9nEoDwtL8CcyUKQzJXJxYRnT7', ), - amount: new BN(700), - lamports: null, - merkleTreeIndex: 0, - tlv: null, - }, - ], - isCompress: true, - compressOrDecompressAmount: new BN(700), - cpiContext: null, - lamportsChangeAccountMerkleTreeIndex: null, - }; - - const buffer = Buffer.alloc(1000); - const len = CompressedTokenInstructionDataTransferLayout.encode( - data, - buffer, - ); - const decoded = CompressedTokenInstructionDataTransferLayout.decode( - buffer.slice(0, len), - ); - expect(deepEqual(decoded, data)).toBe(true); - }); + remainingAmount: new BN(110), + cpiContext: null, + }, + }, + { + description: 'with cpiContext', + data: { + owner: new PublicKey( + 'CPMzHV9PsUeb5pFmyrj9nEoDwtL8CcyUKQzJXJxYRnT7', + ), + remainingAmount: new BN(110), + cpiContext: { + setContext: true, + firstSetContext: true, + cpiContextAccountIndex: 0, + }, + }, + }, + { + description: 'without remainingAmount', + data: { + owner: new PublicKey( + 'CPMzHV9PsUeb5pFmyrj9nEoDwtL8CcyUKQzJXJxYRnT7', + ), + remainingAmount: null, + cpiContext: null, + }, + }, + ]; + + testCases.forEach(async ({ description, data }) => { + it(description, async () => { + const encoded = + encodeCompressSplTokenAccountInstructionData(data); + const decoded = + decodeCompressSplTokenAccountInstructionData(encoded); + expect(deepEqual(decoded, data)).toBe(true); - it('validate mintToLayout', () => { - const data: MintToInstructionData = { - recipients: [ - new PublicKey('CXzk7xBgfzwSrZincWbJPGMPFz8aut3V6JjXp5n3XvGQ'), - ], - amounts: [new BN(1000)], - lamports: new BN(500), - }; - - const buffer = Buffer.alloc(1000); - const len = mintToLayout.encode(data, buffer); - const decoded = mintToLayout.decode(buffer.slice(0, len)); - expect(deepEqual(decoded, data)).toBe(true); + const instruction = await getTestProgram() + .methods.compressSplTokenAccount( + data.owner, + data.remainingAmount, + data.cpiContext, + ) + .accounts({ + feePayer: PublicKey.default, + authority: PublicKey.default, + cpiAuthorityPda: PublicKey.default, + lightSystemProgram: PublicKey.default, + registeredProgramPda: PublicKey.default, + noopProgram: PublicKey.default, + accountCompressionAuthority: PublicKey.default, + accountCompressionProgram: PublicKey.default, + selfProgram: PublicKey.default, + tokenPoolPda: PublicKey.default, + compressOrDecompressTokenAccount: PublicKey.default, + tokenProgram: PublicKey.default, + systemProgram: PublicKey.default, + }) + .instruction(); + + expect(instruction.data).toEqual(encoded); + }); + }); }); + describe('Accounts Layout Helper Functions', () => { + it('createTokenPoolAccountsLayout should return correct AccountMeta array', () => { + const accounts = { + feePayer: PublicKey.default, + tokenPoolPda: PublicKey.default, + systemProgram: PublicKey.default, + mint: PublicKey.default, + tokenProgram: PublicKey.default, + cpiAuthorityPda: PublicKey.default, + }; + + const expected = [ + { pubkey: PublicKey.default, isSigner: true, isWritable: true }, + { + pubkey: PublicKey.default, + isSigner: false, + isWritable: true, + }, + { + pubkey: PublicKey.default, + isSigner: false, + isWritable: false, + }, + { + pubkey: PublicKey.default, + isSigner: false, + isWritable: true, + }, + { + pubkey: PublicKey.default, + isSigner: false, + isWritable: false, + }, + { + pubkey: PublicKey.default, + isSigner: false, + isWritable: false, + }, + ]; + + const result = createTokenPoolAccountsLayout(accounts); + expect(result).toEqual(expected); + }); + + it('mintToAccountsLayout should return correct AccountMeta array', () => { + const accounts = { + feePayer: PublicKey.default, + authority: PublicKey.default, + cpiAuthorityPda: PublicKey.default, + mint: PublicKey.default, + tokenPoolPda: PublicKey.default, + tokenProgram: PublicKey.default, + lightSystemProgram: PublicKey.default, + registeredProgramPda: PublicKey.default, + noopProgram: PublicKey.default, + accountCompressionAuthority: PublicKey.default, + accountCompressionProgram: PublicKey.default, + merkleTree: PublicKey.default, + selfProgram: PublicKey.default, + systemProgram: PublicKey.default, + solPoolPda: PublicKey.default, + }; + + const expected = [ + { pubkey: PublicKey.default, isSigner: true, isWritable: true }, + { + pubkey: PublicKey.default, + isSigner: true, + isWritable: false, + }, + { + pubkey: PublicKey.default, + isSigner: false, + isWritable: false, + }, + { + pubkey: PublicKey.default, + isSigner: false, + isWritable: true, + }, + { + pubkey: PublicKey.default, + isSigner: false, + isWritable: true, + }, + { + pubkey: PublicKey.default, + isSigner: false, + isWritable: false, + }, + { + pubkey: PublicKey.default, + isSigner: false, + isWritable: false, + }, + { + pubkey: PublicKey.default, + isSigner: false, + isWritable: false, + }, + { + pubkey: PublicKey.default, + isSigner: false, + isWritable: false, + }, + { + pubkey: PublicKey.default, + isSigner: false, + isWritable: false, + }, + { + pubkey: PublicKey.default, + isSigner: false, + isWritable: false, + }, + { + pubkey: PublicKey.default, + isSigner: false, + isWritable: true, + }, + { + pubkey: PublicKey.default, + isSigner: false, + isWritable: false, + }, + { + pubkey: PublicKey.default, + isSigner: false, + isWritable: false, + }, + { + pubkey: PublicKey.default, + isSigner: false, + isWritable: true, + }, + ]; + + const result = mintToAccountsLayout(accounts); + expect(result).toEqual(expected); + }); + + it('transferAccountsLayout should return correct AccountMeta array', () => { + const accounts = { + feePayer: PublicKey.default, + authority: PublicKey.default, + cpiAuthorityPda: PublicKey.default, + lightSystemProgram: PublicKey.default, + registeredProgramPda: PublicKey.default, + noopProgram: PublicKey.default, + accountCompressionAuthority: PublicKey.default, + accountCompressionProgram: PublicKey.default, + selfProgram: PublicKey.default, + tokenPoolPda: PublicKey.default, + compressOrDecompressTokenAccount: PublicKey.default, + tokenProgram: PublicKey.default, + systemProgram: PublicKey.default, + }; + + const expected = [ + { pubkey: PublicKey.default, isSigner: true, isWritable: true }, + { + pubkey: PublicKey.default, + isSigner: true, + isWritable: false, + }, + { + pubkey: PublicKey.default, + isSigner: false, + isWritable: false, + }, + { + pubkey: PublicKey.default, + isSigner: false, + isWritable: false, + }, + { + pubkey: PublicKey.default, + isSigner: false, + isWritable: false, + }, + { + pubkey: PublicKey.default, + isSigner: false, + isWritable: false, + }, + { + pubkey: PublicKey.default, + isSigner: false, + isWritable: false, + }, + { + pubkey: PublicKey.default, + isSigner: false, + isWritable: false, + }, + { + pubkey: PublicKey.default, + isSigner: false, + isWritable: false, + }, + { + pubkey: PublicKey.default, + isSigner: false, + isWritable: true, + }, + { + pubkey: PublicKey.default, + isSigner: false, + isWritable: true, + }, + { + pubkey: PublicKey.default, + isSigner: false, + isWritable: false, + }, + { + pubkey: PublicKey.default, + isSigner: false, + isWritable: false, + }, + ]; - it('validate compressSplTokenAccountInstructionDataLayout', () => { - const data: CompressSplTokenAccountInstructionData = { - owner: new PublicKey( - 'CXzk7xBgfzwSrZincWbJPGMPFz8aut3V6JjXp5n3XvGQ', - ), - remainingAmount: new BN(1000), - cpiContext: null, - }; - - const buffer = Buffer.alloc(1000); - const len = compressSplTokenAccountInstructionDataLayout.encode( - data, - buffer, - ); - const decoded = compressSplTokenAccountInstructionDataLayout.decode( - buffer.slice(0, len), - ); - expect(deepEqual(decoded, data)).toBe(true); + const result = transferAccountsLayout(accounts); + expect(result).toEqual(expected); + }); }); }); diff --git a/js/stateless.js/package.json b/js/stateless.js/package.json index 96fdf2cdbd..56e9a6cdae 100644 --- a/js/stateless.js/package.json +++ b/js/stateless.js/package.json @@ -48,6 +48,7 @@ "superstruct": "2.0.2" }, "devDependencies": { + "@coral-xyz/anchor": "0.29.0", "@esbuild-plugins/node-globals-polyfill": "^0.2.3", "@lightprotocol/hasher.rs": "0.2.1", "@lightprotocol/programs": "workspace:*", diff --git a/js/stateless.js/rollup.config.js b/js/stateless.js/rollup.config.js index f4336924bc..90ac4f534a 100644 --- a/js/stateless.js/rollup.config.js +++ b/js/stateless.js/rollup.config.js @@ -13,9 +13,7 @@ const rolls = (fmt, env) => ({ entryFileNames: `[name].${fmt === 'cjs' ? 'cjs' : 'js'}`, sourcemap: true, }, - external: [ - '@solana/web3.js', - ], + external: ['@solana/web3.js'], plugins: [ typescript({ target: fmt === 'es' ? 'ES2022' : 'ES2017', diff --git a/js/stateless.js/src/idl.ts b/js/stateless.js/src/idl.ts new file mode 100644 index 0000000000..b552e537f4 --- /dev/null +++ b/js/stateless.js/src/idl.ts @@ -0,0 +1,2034 @@ +export type LightSystemProgram = { + version: '1.2.0'; + name: 'light_system_program'; + constants: [ + { + name: 'SOL_POOL_PDA_SEED'; + type: 'bytes'; + value: '[115, 111, 108, 95, 112, 111, 111, 108, 95, 112, 100, 97]'; + }, + ]; + instructions: [ + { + name: 'initCpiContextAccount'; + accounts: [ + { + name: 'feePayer'; + isMut: true; + isSigner: true; + }, + { + name: 'cpiContextAccount'; + isMut: true; + isSigner: false; + }, + { + name: 'associatedMerkleTree'; + isMut: false; + isSigner: false; + }, + ]; + args: []; + }, + { + name: 'invoke'; + accounts: [ + { + name: 'feePayer'; + isMut: true; + isSigner: true; + docs: [ + 'Fee payer needs to be mutable to pay rollover and protocol fees.', + ]; + }, + { + name: 'authority'; + isMut: false; + isSigner: true; + }, + { + name: 'registeredProgramPda'; + isMut: false; + isSigner: false; + }, + { + name: 'noopProgram'; + isMut: false; + isSigner: false; + }, + { + name: 'accountCompressionAuthority'; + isMut: false; + isSigner: false; + docs: [ + 'This pda is used to invoke the account compression program.', + ]; + }, + { + name: 'accountCompressionProgram'; + isMut: false; + isSigner: false; + docs: ['Merkle trees.']; + }, + { + name: 'solPoolPda'; + isMut: true; + isSigner: false; + isOptional: true; + docs: [ + 'Sol pool pda is used to store the native sol that has been compressed.', + "It's only required when compressing or decompressing sol.", + ]; + }, + { + name: 'decompressionRecipient'; + isMut: true; + isSigner: false; + isOptional: true; + docs: [ + 'Only needs to be provided for decompression as a recipient for the', + 'decompressed sol.', + 'Compressed sol originate from authority.', + ]; + }, + { + name: 'systemProgram'; + isMut: false; + isSigner: false; + }, + ]; + args: [ + { + name: 'inputs'; + type: 'bytes'; + }, + ]; + }, + { + name: 'invokeCpi'; + accounts: [ + { + name: 'feePayer'; + isMut: true; + isSigner: true; + docs: [ + 'Fee payer needs to be mutable to pay rollover and protocol fees.', + ]; + }, + { + name: 'authority'; + isMut: false; + isSigner: true; + }, + { + name: 'registeredProgramPda'; + isMut: false; + isSigner: false; + }, + { + name: 'noopProgram'; + isMut: false; + isSigner: false; + }, + { + name: 'accountCompressionAuthority'; + isMut: false; + isSigner: false; + }, + { + name: 'accountCompressionProgram'; + isMut: false; + isSigner: false; + }, + { + name: 'invokingProgram'; + isMut: false; + isSigner: false; + }, + { + name: 'solPoolPda'; + isMut: true; + isSigner: false; + isOptional: true; + }, + { + name: 'decompressionRecipient'; + isMut: true; + isSigner: false; + isOptional: true; + }, + { + name: 'systemProgram'; + isMut: false; + isSigner: false; + }, + { + name: 'cpiContextAccount'; + isMut: true; + isSigner: false; + isOptional: true; + }, + ]; + args: [ + { + name: 'inputs'; + type: 'bytes'; + }, + ]; + }, + { + name: 'invokeCpiWithReadOnly'; + accounts: [ + { + name: 'feePayer'; + isMut: true; + isSigner: true; + docs: [ + 'Fee payer needs to be mutable to pay rollover and protocol fees.', + ]; + }, + { + name: 'authority'; + isMut: false; + isSigner: true; + }, + { + name: 'registeredProgramPda'; + isMut: false; + isSigner: false; + }, + { + name: 'noopProgram'; + isMut: false; + isSigner: false; + }, + { + name: 'accountCompressionAuthority'; + isMut: false; + isSigner: false; + }, + { + name: 'accountCompressionProgram'; + isMut: false; + isSigner: false; + }, + { + name: 'invokingProgram'; + isMut: false; + isSigner: false; + }, + { + name: 'solPoolPda'; + isMut: true; + isSigner: false; + isOptional: true; + }, + { + name: 'decompressionRecipient'; + isMut: true; + isSigner: false; + isOptional: true; + }, + { + name: 'systemProgram'; + isMut: false; + isSigner: false; + }, + { + name: 'cpiContextAccount'; + isMut: true; + isSigner: false; + isOptional: true; + }, + ]; + args: [ + { + name: 'inputs'; + type: 'bytes'; + }, + ]; + }, + { + name: 'stubIdlBuild'; + docs: [ + 'This function is a stub to allow Anchor to include the input types in', + 'the IDL. It should not be included in production builds nor be called in', + 'practice.', + ]; + accounts: [ + { + name: 'feePayer'; + isMut: true; + isSigner: true; + docs: [ + 'Fee payer needs to be mutable to pay rollover and protocol fees.', + ]; + }, + { + name: 'authority'; + isMut: false; + isSigner: true; + }, + { + name: 'registeredProgramPda'; + isMut: false; + isSigner: false; + }, + { + name: 'noopProgram'; + isMut: false; + isSigner: false; + }, + { + name: 'accountCompressionAuthority'; + isMut: false; + isSigner: false; + docs: [ + 'This pda is used to invoke the account compression program.', + ]; + }, + { + name: 'accountCompressionProgram'; + isMut: false; + isSigner: false; + docs: ['Merkle trees.']; + }, + { + name: 'solPoolPda'; + isMut: true; + isSigner: false; + isOptional: true; + docs: [ + 'Sol pool pda is used to store the native sol that has been compressed.', + "It's only required when compressing or decompressing sol.", + ]; + }, + { + name: 'decompressionRecipient'; + isMut: true; + isSigner: false; + isOptional: true; + docs: [ + 'Only needs to be provided for decompression as a recipient for the', + 'decompressed sol.', + 'Compressed sol originate from authority.', + ]; + }, + { + name: 'systemProgram'; + isMut: false; + isSigner: false; + }, + ]; + args: [ + { + name: 'inputs1'; + type: { + defined: 'InstructionDataInvoke'; + }; + }, + { + name: 'inputs2'; + type: { + defined: 'InstructionDataInvokeCpi'; + }; + }, + { + name: 'inputs3'; + type: { + defined: 'PublicTransactionEvent'; + }; + }, + ]; + }, + ]; + accounts: [ + { + name: 'cpiContextAccount'; + docs: [ + 'Collects instruction data without executing a compressed transaction.', + 'Signer checks are performed on instruction data.', + 'Collected instruction data is combined with the instruction data of the executing cpi,', + 'and executed as a single transaction.', + 'This enables to use input compressed accounts that are owned by multiple programs,', + 'with one zero-knowledge proof.', + ]; + type: { + kind: 'struct'; + fields: [ + { + name: 'feePayer'; + type: 'publicKey'; + }, + { + name: 'associatedMerkleTree'; + type: 'publicKey'; + }, + { + name: 'context'; + type: { + vec: { + defined: 'InstructionDataInvokeCpi'; + }; + }; + }, + ]; + }; + }, + ]; + types: [ + { + name: 'InstructionDataInvoke'; + type: { + kind: 'struct'; + fields: [ + { + name: 'proof'; + type: { + option: { + defined: 'CompressedProof'; + }; + }; + }, + { + name: 'inputCompressedAccountsWithMerkleContext'; + type: { + vec: { + defined: 'PackedCompressedAccountWithMerkleContext'; + }; + }; + }, + { + name: 'outputCompressedAccounts'; + type: { + vec: { + defined: 'OutputCompressedAccountWithPackedContext'; + }; + }; + }, + { + name: 'relayFee'; + type: { + option: 'u64'; + }; + }, + { + name: 'newAddressParams'; + type: { + vec: { + defined: 'NewAddressParamsPacked'; + }; + }; + }, + { + name: 'compressOrDecompressLamports'; + type: { + option: 'u64'; + }; + }, + { + name: 'isCompress'; + type: 'bool'; + }, + ]; + }; + }, + { + name: 'NewAddressParamsPacked'; + type: { + kind: 'struct'; + fields: [ + { + name: 'seed'; + type: { + array: ['u8', 32]; + }; + }, + { + name: 'addressQueueAccountIndex'; + type: 'u8'; + }, + { + name: 'addressMerkleTreeAccountIndex'; + type: 'u8'; + }, + { + name: 'addressMerkleTreeRootIndex'; + type: 'u16'; + }, + ]; + }; + }, + { + name: 'OutputCompressedAccountWithPackedContext'; + type: { + kind: 'struct'; + fields: [ + { + name: 'compressedAccount'; + type: { + defined: 'CompressedAccount'; + }; + }, + { + name: 'merkleTreeIndex'; + type: 'u8'; + }, + ]; + }; + }, + { + name: 'CompressedProof'; + type: { + kind: 'struct'; + fields: [ + { + name: 'a'; + type: { + array: ['u8', 32]; + }; + }, + { + name: 'b'; + type: { + array: ['u8', 64]; + }; + }, + { + name: 'c'; + type: { + array: ['u8', 32]; + }; + }, + ]; + }; + }, + { + name: 'InstructionDataInvokeCpi'; + type: { + kind: 'struct'; + fields: [ + { + name: 'proof'; + type: { + option: { + defined: 'CompressedProof'; + }; + }; + }, + { + name: 'newAddressParams'; + type: { + vec: { + defined: 'NewAddressParamsPacked'; + }; + }; + }, + { + name: 'inputCompressedAccountsWithMerkleContext'; + type: { + vec: { + defined: 'PackedCompressedAccountWithMerkleContext'; + }; + }; + }, + { + name: 'outputCompressedAccounts'; + type: { + vec: { + defined: 'OutputCompressedAccountWithPackedContext'; + }; + }; + }, + { + name: 'relayFee'; + type: { + option: 'u64'; + }; + }, + { + name: 'compressOrDecompressLamports'; + type: { + option: 'u64'; + }; + }, + { + name: 'isCompress'; + type: 'bool'; + }, + { + name: 'cpiContext'; + type: { + option: { + defined: 'CompressedCpiContext'; + }; + }; + }, + ]; + }; + }, + { + name: 'CompressedCpiContext'; + type: { + kind: 'struct'; + fields: [ + { + name: 'setContext'; + docs: [ + 'Is set by the program that is invoking the CPI to signal that is should', + 'set the cpi context.', + ]; + type: 'bool'; + }, + { + name: 'firstSetContext'; + docs: [ + 'Is set to wipe the cpi context since someone could have set it before', + 'with unrelated data.', + ]; + type: 'bool'; + }, + { + name: 'cpiContextAccountIndex'; + docs: [ + 'Index of cpi context account in remaining accounts.', + ]; + type: 'u8'; + }, + ]; + }; + }, + { + name: 'CompressedAccount'; + type: { + kind: 'struct'; + fields: [ + { + name: 'owner'; + type: 'publicKey'; + }, + { + name: 'lamports'; + type: 'u64'; + }, + { + name: 'address'; + type: { + option: { + array: ['u8', 32]; + }; + }; + }, + { + name: 'data'; + type: { + option: { + defined: 'CompressedAccountData'; + }; + }; + }, + ]; + }; + }, + { + name: 'CompressedAccountData'; + type: { + kind: 'struct'; + fields: [ + { + name: 'discriminator'; + type: { + array: ['u8', 8]; + }; + }, + { + name: 'data'; + type: 'bytes'; + }, + { + name: 'dataHash'; + type: { + array: ['u8', 32]; + }; + }, + ]; + }; + }, + { + name: 'PackedCompressedAccountWithMerkleContext'; + type: { + kind: 'struct'; + fields: [ + { + name: 'compressedAccount'; + type: { + defined: 'CompressedAccount'; + }; + }, + { + name: 'merkleContext'; + type: { + defined: 'PackedMerkleContext'; + }; + }, + { + name: 'rootIndex'; + docs: [ + 'Index of root used in inclusion validity proof.', + ]; + type: 'u16'; + }, + { + name: 'readOnly'; + docs: [ + 'Placeholder to mark accounts read-only unimplemented set to false.', + ]; + type: 'bool'; + }, + ]; + }; + }, + { + name: 'PackedMerkleContext'; + type: { + kind: 'struct'; + fields: [ + { + name: 'merkleTreePubkeyIndex'; + type: 'u8'; + }, + { + name: 'nullifierQueuePubkeyIndex'; + type: 'u8'; + }, + { + name: 'leafIndex'; + type: 'u32'; + }, + { + name: 'queueIndex'; + type: { + option: { + defined: 'QueueIndex'; + }; + }; + }, + ]; + }; + }, + { + name: 'QueueIndex'; + type: { + kind: 'struct'; + fields: [ + { + name: 'queueId'; + docs: ['Id of queue in queue account.']; + type: 'u8'; + }, + { + name: 'index'; + docs: ['Index of compressed account hash in queue.']; + type: 'u16'; + }, + ]; + }; + }, + { + name: 'MerkleTreeSequenceNumber'; + type: { + kind: 'struct'; + fields: [ + { + name: 'pubkey'; + type: 'publicKey'; + }, + { + name: 'seq'; + type: 'u64'; + }, + ]; + }; + }, + { + name: 'PublicTransactionEvent'; + type: { + kind: 'struct'; + fields: [ + { + name: 'inputCompressedAccountHashes'; + type: { + vec: { + array: ['u8', 32]; + }; + }; + }, + { + name: 'outputCompressedAccountHashes'; + type: { + vec: { + array: ['u8', 32]; + }; + }; + }, + { + name: 'outputCompressedAccounts'; + type: { + vec: { + defined: 'OutputCompressedAccountWithPackedContext'; + }; + }; + }, + { + name: 'outputLeafIndices'; + type: { + vec: 'u32'; + }; + }, + { + name: 'sequenceNumbers'; + type: { + vec: { + defined: 'MerkleTreeSequenceNumber'; + }; + }; + }, + { + name: 'relayFee'; + type: { + option: 'u64'; + }; + }, + { + name: 'isCompress'; + type: 'bool'; + }, + { + name: 'compressOrDecompressLamports'; + type: { + option: 'u64'; + }; + }, + { + name: 'pubkeyArray'; + type: { + vec: 'publicKey'; + }; + }, + { + name: 'message'; + type: { + option: 'bytes'; + }; + }, + ]; + }; + }, + ]; + errors: [ + { + code: 6000; + name: 'SumCheckFailed'; + msg: 'Sum check failed'; + }, + { + code: 6001; + name: 'SignerCheckFailed'; + msg: 'Signer check failed'; + }, + { + code: 6002; + name: 'CpiSignerCheckFailed'; + msg: 'Cpi signer check failed'; + }, + { + code: 6003; + name: 'ComputeInputSumFailed'; + msg: 'Computing input sum failed.'; + }, + { + code: 6004; + name: 'ComputeOutputSumFailed'; + msg: 'Computing output sum failed.'; + }, + { + code: 6005; + name: 'ComputeRpcSumFailed'; + msg: 'Computing rpc sum failed.'; + }, + { + code: 6006; + name: 'InvalidAddress'; + msg: 'InvalidAddress'; + }, + { + code: 6007; + name: 'DeriveAddressError'; + msg: 'DeriveAddressError'; + }, + { + code: 6008; + name: 'CompressedSolPdaUndefinedForCompressSol'; + msg: 'CompressedSolPdaUndefinedForCompressSol'; + }, + { + code: 6009; + name: 'DeCompressLamportsUndefinedForCompressSol'; + msg: 'DeCompressLamportsUndefinedForCompressSol'; + }, + { + code: 6010; + name: 'CompressedSolPdaUndefinedForDecompressSol'; + msg: 'CompressedSolPdaUndefinedForDecompressSol'; + }, + { + code: 6011; + name: 'DeCompressLamportsUndefinedForDecompressSol'; + msg: 'DeCompressLamportsUndefinedForDecompressSol'; + }, + { + code: 6012; + name: 'DecompressRecipientUndefinedForDecompressSol'; + msg: 'DecompressRecipientUndefinedForDecompressSol'; + }, + { + code: 6013; + name: 'WriteAccessCheckFailed'; + msg: 'WriteAccessCheckFailed'; + }, + { + code: 6014; + name: 'InvokingProgramNotProvided'; + msg: 'InvokingProgramNotProvided'; + }, + { + code: 6015; + name: 'InvalidCapacity'; + msg: 'InvalidCapacity'; + }, + { + code: 6016; + name: 'InvalidMerkleTreeOwner'; + msg: 'InvalidMerkleTreeOwner'; + }, + { + code: 6017; + name: 'ProofIsNone'; + msg: 'ProofIsNone'; + }, + { + code: 6018; + name: 'ProofIsSome'; + msg: 'Proof is some but no input compressed accounts or new addresses provided.'; + }, + { + code: 6019; + name: 'EmptyInputs'; + msg: 'EmptyInputs'; + }, + { + code: 6020; + name: 'CpiContextAccountUndefined'; + msg: 'CpiContextAccountUndefined'; + }, + { + code: 6021; + name: 'CpiContextEmpty'; + msg: 'CpiContextEmpty'; + }, + { + code: 6022; + name: 'CpiContextMissing'; + msg: 'CpiContextMissing'; + }, + { + code: 6023; + name: 'DecompressionRecipientDefined'; + msg: 'DecompressionRecipientDefined'; + }, + { + code: 6024; + name: 'SolPoolPdaDefined'; + msg: 'SolPoolPdaDefined'; + }, + { + code: 6025; + name: 'AppendStateFailed'; + msg: 'AppendStateFailed'; + }, + { + code: 6026; + name: 'InstructionNotCallable'; + msg: 'The instruction is not callable'; + }, + { + code: 6027; + name: 'CpiContextFeePayerMismatch'; + msg: 'CpiContextFeePayerMismatch'; + }, + { + code: 6028; + name: 'CpiContextAssociatedMerkleTreeMismatch'; + msg: 'CpiContextAssociatedMerkleTreeMismatch'; + }, + { + code: 6029; + name: 'NoInputs'; + msg: 'NoInputs'; + }, + { + code: 6030; + name: 'InputMerkleTreeIndicesNotInOrder'; + msg: 'Input merkle tree indices are not in ascending order.'; + }, + { + code: 6031; + name: 'OutputMerkleTreeIndicesNotInOrder'; + msg: 'Output merkle tree indices are not in ascending order.'; + }, + { + code: 6032; + name: 'OutputMerkleTreeNotUnique'; + }, + { + code: 6033; + name: 'DataFieldUndefined'; + }, + { + code: 6034; + name: 'ReadOnlyAddressAlreadyExists'; + }, + { + code: 6035; + name: 'ReadOnlyAccountDoesNotExist'; + }, + { + code: 6036; + name: 'HashChainInputsLenghtInconsistent'; + }, + { + code: 6037; + name: 'InvalidAddressTreeHeight'; + }, + ]; +}; + +export const IDL: LightSystemProgram = { + version: '1.2.0', + name: 'light_system_program', + constants: [ + { + name: 'SOL_POOL_PDA_SEED', + type: 'bytes', + value: '[115, 111, 108, 95, 112, 111, 111, 108, 95, 112, 100, 97]', + }, + ], + instructions: [ + { + name: 'initCpiContextAccount', + accounts: [ + { + name: 'feePayer', + isMut: true, + isSigner: true, + }, + { + name: 'cpiContextAccount', + isMut: true, + isSigner: false, + }, + { + name: 'associatedMerkleTree', + isMut: false, + isSigner: false, + }, + ], + args: [], + }, + { + name: 'invoke', + accounts: [ + { + name: 'feePayer', + isMut: true, + isSigner: true, + docs: [ + 'Fee payer needs to be mutable to pay rollover and protocol fees.', + ], + }, + { + name: 'authority', + isMut: false, + isSigner: true, + }, + { + name: 'registeredProgramPda', + isMut: false, + isSigner: false, + }, + { + name: 'noopProgram', + isMut: false, + isSigner: false, + }, + { + name: 'accountCompressionAuthority', + isMut: false, + isSigner: false, + docs: [ + 'This pda is used to invoke the account compression program.', + ], + }, + { + name: 'accountCompressionProgram', + isMut: false, + isSigner: false, + docs: ['Merkle trees.'], + }, + { + name: 'solPoolPda', + isMut: true, + isSigner: false, + isOptional: true, + docs: [ + 'Sol pool pda is used to store the native sol that has been compressed.', + "It's only required when compressing or decompressing sol.", + ], + }, + { + name: 'decompressionRecipient', + isMut: true, + isSigner: false, + isOptional: true, + docs: [ + 'Only needs to be provided for decompression as a recipient for the', + 'decompressed sol.', + 'Compressed sol originate from authority.', + ], + }, + { + name: 'systemProgram', + isMut: false, + isSigner: false, + }, + ], + args: [ + { + name: 'inputs', + type: 'bytes', + }, + ], + }, + { + name: 'invokeCpi', + accounts: [ + { + name: 'feePayer', + isMut: true, + isSigner: true, + docs: [ + 'Fee payer needs to be mutable to pay rollover and protocol fees.', + ], + }, + { + name: 'authority', + isMut: false, + isSigner: true, + }, + { + name: 'registeredProgramPda', + isMut: false, + isSigner: false, + }, + { + name: 'noopProgram', + isMut: false, + isSigner: false, + }, + { + name: 'accountCompressionAuthority', + isMut: false, + isSigner: false, + }, + { + name: 'accountCompressionProgram', + isMut: false, + isSigner: false, + }, + { + name: 'invokingProgram', + isMut: false, + isSigner: false, + }, + { + name: 'solPoolPda', + isMut: true, + isSigner: false, + isOptional: true, + }, + { + name: 'decompressionRecipient', + isMut: true, + isSigner: false, + isOptional: true, + }, + { + name: 'systemProgram', + isMut: false, + isSigner: false, + }, + { + name: 'cpiContextAccount', + isMut: true, + isSigner: false, + isOptional: true, + }, + ], + args: [ + { + name: 'inputs', + type: 'bytes', + }, + ], + }, + { + name: 'invokeCpiWithReadOnly', + accounts: [ + { + name: 'feePayer', + isMut: true, + isSigner: true, + docs: [ + 'Fee payer needs to be mutable to pay rollover and protocol fees.', + ], + }, + { + name: 'authority', + isMut: false, + isSigner: true, + }, + { + name: 'registeredProgramPda', + isMut: false, + isSigner: false, + }, + { + name: 'noopProgram', + isMut: false, + isSigner: false, + }, + { + name: 'accountCompressionAuthority', + isMut: false, + isSigner: false, + }, + { + name: 'accountCompressionProgram', + isMut: false, + isSigner: false, + }, + { + name: 'invokingProgram', + isMut: false, + isSigner: false, + }, + { + name: 'solPoolPda', + isMut: true, + isSigner: false, + isOptional: true, + }, + { + name: 'decompressionRecipient', + isMut: true, + isSigner: false, + isOptional: true, + }, + { + name: 'systemProgram', + isMut: false, + isSigner: false, + }, + { + name: 'cpiContextAccount', + isMut: true, + isSigner: false, + isOptional: true, + }, + ], + args: [ + { + name: 'inputs', + type: 'bytes', + }, + ], + }, + { + name: 'stubIdlBuild', + docs: [ + 'This function is a stub to allow Anchor to include the input types in', + 'the IDL. It should not be included in production builds nor be called in', + 'practice.', + ], + accounts: [ + { + name: 'feePayer', + isMut: true, + isSigner: true, + docs: [ + 'Fee payer needs to be mutable to pay rollover and protocol fees.', + ], + }, + { + name: 'authority', + isMut: false, + isSigner: true, + }, + { + name: 'registeredProgramPda', + isMut: false, + isSigner: false, + }, + { + name: 'noopProgram', + isMut: false, + isSigner: false, + }, + { + name: 'accountCompressionAuthority', + isMut: false, + isSigner: false, + docs: [ + 'This pda is used to invoke the account compression program.', + ], + }, + { + name: 'accountCompressionProgram', + isMut: false, + isSigner: false, + docs: ['Merkle trees.'], + }, + { + name: 'solPoolPda', + isMut: true, + isSigner: false, + isOptional: true, + docs: [ + 'Sol pool pda is used to store the native sol that has been compressed.', + "It's only required when compressing or decompressing sol.", + ], + }, + { + name: 'decompressionRecipient', + isMut: true, + isSigner: false, + isOptional: true, + docs: [ + 'Only needs to be provided for decompression as a recipient for the', + 'decompressed sol.', + 'Compressed sol originate from authority.', + ], + }, + { + name: 'systemProgram', + isMut: false, + isSigner: false, + }, + ], + args: [ + { + name: 'inputs1', + type: { + defined: 'InstructionDataInvoke', + }, + }, + { + name: 'inputs2', + type: { + defined: 'InstructionDataInvokeCpi', + }, + }, + { + name: 'inputs3', + type: { + defined: 'PublicTransactionEvent', + }, + }, + ], + }, + ], + accounts: [ + { + name: 'cpiContextAccount', + docs: [ + 'Collects instruction data without executing a compressed transaction.', + 'Signer checks are performed on instruction data.', + 'Collected instruction data is combined with the instruction data of the executing cpi,', + 'and executed as a single transaction.', + 'This enables to use input compressed accounts that are owned by multiple programs,', + 'with one zero-knowledge proof.', + ], + type: { + kind: 'struct', + fields: [ + { + name: 'feePayer', + type: 'publicKey', + }, + { + name: 'associatedMerkleTree', + type: 'publicKey', + }, + { + name: 'context', + type: { + vec: { + defined: 'InstructionDataInvokeCpi', + }, + }, + }, + ], + }, + }, + ], + types: [ + { + name: 'InstructionDataInvoke', + type: { + kind: 'struct', + fields: [ + { + name: 'proof', + type: { + option: { + defined: 'CompressedProof', + }, + }, + }, + { + name: 'inputCompressedAccountsWithMerkleContext', + type: { + vec: { + defined: + 'PackedCompressedAccountWithMerkleContext', + }, + }, + }, + { + name: 'outputCompressedAccounts', + type: { + vec: { + defined: + 'OutputCompressedAccountWithPackedContext', + }, + }, + }, + { + name: 'relayFee', + type: { + option: 'u64', + }, + }, + { + name: 'newAddressParams', + type: { + vec: { + defined: 'NewAddressParamsPacked', + }, + }, + }, + { + name: 'compressOrDecompressLamports', + type: { + option: 'u64', + }, + }, + { + name: 'isCompress', + type: 'bool', + }, + ], + }, + }, + { + name: 'NewAddressParamsPacked', + type: { + kind: 'struct', + fields: [ + { + name: 'seed', + type: { + array: ['u8', 32], + }, + }, + { + name: 'addressQueueAccountIndex', + type: 'u8', + }, + { + name: 'addressMerkleTreeAccountIndex', + type: 'u8', + }, + { + name: 'addressMerkleTreeRootIndex', + type: 'u16', + }, + ], + }, + }, + { + name: 'OutputCompressedAccountWithPackedContext', + type: { + kind: 'struct', + fields: [ + { + name: 'compressedAccount', + type: { + defined: 'CompressedAccount', + }, + }, + { + name: 'merkleTreeIndex', + type: 'u8', + }, + ], + }, + }, + { + name: 'CompressedProof', + type: { + kind: 'struct', + fields: [ + { + name: 'a', + type: { + array: ['u8', 32], + }, + }, + { + name: 'b', + type: { + array: ['u8', 64], + }, + }, + { + name: 'c', + type: { + array: ['u8', 32], + }, + }, + ], + }, + }, + { + name: 'InstructionDataInvokeCpi', + type: { + kind: 'struct', + fields: [ + { + name: 'proof', + type: { + option: { + defined: 'CompressedProof', + }, + }, + }, + { + name: 'newAddressParams', + type: { + vec: { + defined: 'NewAddressParamsPacked', + }, + }, + }, + { + name: 'inputCompressedAccountsWithMerkleContext', + type: { + vec: { + defined: + 'PackedCompressedAccountWithMerkleContext', + }, + }, + }, + { + name: 'outputCompressedAccounts', + type: { + vec: { + defined: + 'OutputCompressedAccountWithPackedContext', + }, + }, + }, + { + name: 'relayFee', + type: { + option: 'u64', + }, + }, + { + name: 'compressOrDecompressLamports', + type: { + option: 'u64', + }, + }, + { + name: 'isCompress', + type: 'bool', + }, + { + name: 'cpiContext', + type: { + option: { + defined: 'CompressedCpiContext', + }, + }, + }, + ], + }, + }, + { + name: 'CompressedCpiContext', + type: { + kind: 'struct', + fields: [ + { + name: 'setContext', + docs: [ + 'Is set by the program that is invoking the CPI to signal that is should', + 'set the cpi context.', + ], + type: 'bool', + }, + { + name: 'firstSetContext', + docs: [ + 'Is set to wipe the cpi context since someone could have set it before', + 'with unrelated data.', + ], + type: 'bool', + }, + { + name: 'cpiContextAccountIndex', + docs: [ + 'Index of cpi context account in remaining accounts.', + ], + type: 'u8', + }, + ], + }, + }, + { + name: 'CompressedAccount', + type: { + kind: 'struct', + fields: [ + { + name: 'owner', + type: 'publicKey', + }, + { + name: 'lamports', + type: 'u64', + }, + { + name: 'address', + type: { + option: { + array: ['u8', 32], + }, + }, + }, + { + name: 'data', + type: { + option: { + defined: 'CompressedAccountData', + }, + }, + }, + ], + }, + }, + { + name: 'CompressedAccountData', + type: { + kind: 'struct', + fields: [ + { + name: 'discriminator', + type: { + array: ['u8', 8], + }, + }, + { + name: 'data', + type: 'bytes', + }, + { + name: 'dataHash', + type: { + array: ['u8', 32], + }, + }, + ], + }, + }, + { + name: 'PackedCompressedAccountWithMerkleContext', + type: { + kind: 'struct', + fields: [ + { + name: 'compressedAccount', + type: { + defined: 'CompressedAccount', + }, + }, + { + name: 'merkleContext', + type: { + defined: 'PackedMerkleContext', + }, + }, + { + name: 'rootIndex', + docs: [ + 'Index of root used in inclusion validity proof.', + ], + type: 'u16', + }, + { + name: 'readOnly', + docs: [ + 'Placeholder to mark accounts read-only unimplemented set to false.', + ], + type: 'bool', + }, + ], + }, + }, + { + name: 'PackedMerkleContext', + type: { + kind: 'struct', + fields: [ + { + name: 'merkleTreePubkeyIndex', + type: 'u8', + }, + { + name: 'nullifierQueuePubkeyIndex', + type: 'u8', + }, + { + name: 'leafIndex', + type: 'u32', + }, + { + name: 'queueIndex', + type: { + option: { + defined: 'QueueIndex', + }, + }, + }, + ], + }, + }, + { + name: 'QueueIndex', + type: { + kind: 'struct', + fields: [ + { + name: 'queueId', + docs: ['Id of queue in queue account.'], + type: 'u8', + }, + { + name: 'index', + docs: ['Index of compressed account hash in queue.'], + type: 'u16', + }, + ], + }, + }, + { + name: 'MerkleTreeSequenceNumber', + type: { + kind: 'struct', + fields: [ + { + name: 'pubkey', + type: 'publicKey', + }, + { + name: 'seq', + type: 'u64', + }, + ], + }, + }, + { + name: 'PublicTransactionEvent', + type: { + kind: 'struct', + fields: [ + { + name: 'inputCompressedAccountHashes', + type: { + vec: { + array: ['u8', 32], + }, + }, + }, + { + name: 'outputCompressedAccountHashes', + type: { + vec: { + array: ['u8', 32], + }, + }, + }, + { + name: 'outputCompressedAccounts', + type: { + vec: { + defined: + 'OutputCompressedAccountWithPackedContext', + }, + }, + }, + { + name: 'outputLeafIndices', + type: { + vec: 'u32', + }, + }, + { + name: 'sequenceNumbers', + type: { + vec: { + defined: 'MerkleTreeSequenceNumber', + }, + }, + }, + { + name: 'relayFee', + type: { + option: 'u64', + }, + }, + { + name: 'isCompress', + type: 'bool', + }, + { + name: 'compressOrDecompressLamports', + type: { + option: 'u64', + }, + }, + { + name: 'pubkeyArray', + type: { + vec: 'publicKey', + }, + }, + { + name: 'message', + type: { + option: 'bytes', + }, + }, + ], + }, + }, + ], + errors: [ + { + code: 6000, + name: 'SumCheckFailed', + msg: 'Sum check failed', + }, + { + code: 6001, + name: 'SignerCheckFailed', + msg: 'Signer check failed', + }, + { + code: 6002, + name: 'CpiSignerCheckFailed', + msg: 'Cpi signer check failed', + }, + { + code: 6003, + name: 'ComputeInputSumFailed', + msg: 'Computing input sum failed.', + }, + { + code: 6004, + name: 'ComputeOutputSumFailed', + msg: 'Computing output sum failed.', + }, + { + code: 6005, + name: 'ComputeRpcSumFailed', + msg: 'Computing rpc sum failed.', + }, + { + code: 6006, + name: 'InvalidAddress', + msg: 'InvalidAddress', + }, + { + code: 6007, + name: 'DeriveAddressError', + msg: 'DeriveAddressError', + }, + { + code: 6008, + name: 'CompressedSolPdaUndefinedForCompressSol', + msg: 'CompressedSolPdaUndefinedForCompressSol', + }, + { + code: 6009, + name: 'DeCompressLamportsUndefinedForCompressSol', + msg: 'DeCompressLamportsUndefinedForCompressSol', + }, + { + code: 6010, + name: 'CompressedSolPdaUndefinedForDecompressSol', + msg: 'CompressedSolPdaUndefinedForDecompressSol', + }, + { + code: 6011, + name: 'DeCompressLamportsUndefinedForDecompressSol', + msg: 'DeCompressLamportsUndefinedForDecompressSol', + }, + { + code: 6012, + name: 'DecompressRecipientUndefinedForDecompressSol', + msg: 'DecompressRecipientUndefinedForDecompressSol', + }, + { + code: 6013, + name: 'WriteAccessCheckFailed', + msg: 'WriteAccessCheckFailed', + }, + { + code: 6014, + name: 'InvokingProgramNotProvided', + msg: 'InvokingProgramNotProvided', + }, + { + code: 6015, + name: 'InvalidCapacity', + msg: 'InvalidCapacity', + }, + { + code: 6016, + name: 'InvalidMerkleTreeOwner', + msg: 'InvalidMerkleTreeOwner', + }, + { + code: 6017, + name: 'ProofIsNone', + msg: 'ProofIsNone', + }, + { + code: 6018, + name: 'ProofIsSome', + msg: 'Proof is some but no input compressed accounts or new addresses provided.', + }, + { + code: 6019, + name: 'EmptyInputs', + msg: 'EmptyInputs', + }, + { + code: 6020, + name: 'CpiContextAccountUndefined', + msg: 'CpiContextAccountUndefined', + }, + { + code: 6021, + name: 'CpiContextEmpty', + msg: 'CpiContextEmpty', + }, + { + code: 6022, + name: 'CpiContextMissing', + msg: 'CpiContextMissing', + }, + { + code: 6023, + name: 'DecompressionRecipientDefined', + msg: 'DecompressionRecipientDefined', + }, + { + code: 6024, + name: 'SolPoolPdaDefined', + msg: 'SolPoolPdaDefined', + }, + { + code: 6025, + name: 'AppendStateFailed', + msg: 'AppendStateFailed', + }, + { + code: 6026, + name: 'InstructionNotCallable', + msg: 'The instruction is not callable', + }, + { + code: 6027, + name: 'CpiContextFeePayerMismatch', + msg: 'CpiContextFeePayerMismatch', + }, + { + code: 6028, + name: 'CpiContextAssociatedMerkleTreeMismatch', + msg: 'CpiContextAssociatedMerkleTreeMismatch', + }, + { + code: 6029, + name: 'NoInputs', + msg: 'NoInputs', + }, + { + code: 6030, + name: 'InputMerkleTreeIndicesNotInOrder', + msg: 'Input merkle tree indices are not in ascending order.', + }, + { + code: 6031, + name: 'OutputMerkleTreeIndicesNotInOrder', + msg: 'Output merkle tree indices are not in ascending order.', + }, + { + code: 6032, + name: 'OutputMerkleTreeNotUnique', + }, + { + code: 6033, + name: 'DataFieldUndefined', + }, + { + code: 6034, + name: 'ReadOnlyAddressAlreadyExists', + }, + { + code: 6035, + name: 'ReadOnlyAccountDoesNotExist', + }, + { + code: 6036, + name: 'HashChainInputsLenghtInconsistent', + }, + { + code: 6037, + name: 'InvalidAddressTreeHeight', + }, + ], +}; diff --git a/js/stateless.js/src/index.ts b/js/stateless.js/src/index.ts index b04b9221e5..e6c43e9623 100644 --- a/js/stateless.js/src/index.ts +++ b/js/stateless.js/src/index.ts @@ -8,3 +8,4 @@ export * from './errors'; export * from './rpc-interface'; export * from './rpc'; export * from './test-helpers'; +export { LightSystemProgram as LightSystemProgramIDL, IDL } from './idl'; diff --git a/js/stateless.js/src/programs/layout.ts b/js/stateless.js/src/programs/layout.ts index 86bfb4ec1d..883bf4f5fb 100644 --- a/js/stateless.js/src/programs/layout.ts +++ b/js/stateless.js/src/programs/layout.ts @@ -99,7 +99,9 @@ export function encodeInstructionDataInvoke( export function decodeInstructionDataInvoke( buffer: Buffer, ): InstructionDataInvoke { - return InstructionDataInvokeLayout.decode(buffer); + return InstructionDataInvokeLayout.decode( + buffer.slice(INVOKE_DISCRIMINATOR.length + 4), + ); } export type invokeAccountsLayoutParams = { @@ -199,6 +201,7 @@ export function encodePublicTransactionEvent( ): Buffer { const buffer = Buffer.alloc(1000); const len = PublicTransactionEventLayout.encode(data, buffer); + return buffer.slice(0, len); } diff --git a/js/stateless.js/src/state/types.ts b/js/stateless.js/src/state/types.ts index d9ae34a2f5..67b615a2ec 100644 --- a/js/stateless.js/src/state/types.ts +++ b/js/stateless.js/src/state/types.ts @@ -54,12 +54,17 @@ export interface CompressedAccountData { data: Buffer; // bytes dataHash: number[]; // [u8; 32] } +export interface MerkleTreeSequenceNumber { + pubkey: PublicKey; + seq: BN; +} export interface PublicTransactionEvent { inputCompressedAccountHashes: number[][]; // Vec<[u8; 32]> outputCompressedAccountHashes: number[][]; // Vec<[u8; 32]> outputCompressedAccounts: OutputCompressedAccountWithPackedContext[]; outputLeafIndices: number[]; // Vec + sequenceNumbers: MerkleTreeSequenceNumber[]; // Vec relayFee: BN | null; // Option isCompress: boolean; // bool compressOrDecompressLamports: BN | null; // Option diff --git a/js/stateless.js/src/utils/test-utils.ts b/js/stateless.js/src/utils/test-utils.ts index f57e707ac0..ae6d4cbcfc 100644 --- a/js/stateless.js/src/utils/test-utils.ts +++ b/js/stateless.js/src/utils/test-utils.ts @@ -38,7 +38,7 @@ export function deepEqual(ref: any, val: any) { return false; } - for (let key of refKeys) { + for (const key of refKeys) { if (!valKeys.includes(key)) { console.log(`Key ${key} not found in value`); return false; diff --git a/js/stateless.js/tests/e2e/layout.test.ts b/js/stateless.js/tests/e2e/layout.test.ts index daad549e0b..8c651e340a 100644 --- a/js/stateless.js/tests/e2e/layout.test.ts +++ b/js/stateless.js/tests/e2e/layout.test.ts @@ -1,8 +1,40 @@ -import { decodePublicTransactionEvent } from '../../src/programs/layout'; import { describe, it, expect } from 'vitest'; -import { PublicKey } from '@solana/web3.js'; +import { Connection, Keypair, PublicKey } from '@solana/web3.js'; import BN from 'bn.js'; -import { InstructionDataInvoke } from '../../src/state'; +import { + Program, + AnchorProvider, + setProvider, + Wallet, +} from '@coral-xyz/anchor'; +import { + encodeInstructionDataInvoke, + decodeInstructionDataInvoke, + encodePublicTransactionEvent, + decodePublicTransactionEvent, + invokeAccountsLayout, +} from '../../src/programs/layout'; +import { InstructionDataInvoke, PublicTransactionEvent } from '../../src/state'; +import { Buffer } from 'buffer'; +import { IDL, LightSystemProgram, LightSystemProgramIDL } from '../../src'; + +const getTestProgram = (): Program => { + const mockKeypair = Keypair.generate(); + const mockConnection = new Connection('http://127.0.0.1:8899', 'confirmed'); + const mockProvider = new AnchorProvider( + mockConnection, + new Wallet(mockKeypair), + { + commitment: 'confirmed', + }, + ); + setProvider(mockProvider); + return new Program( + IDL, + new PublicKey('cTokenmWW8bLPjZEBAUgYy3zKxQZW6VKi7bqNFEVv3m'), + mockProvider, + ); +}; function deepEqual(ref: any, val: any) { if (typeof ref !== typeof val) { @@ -25,7 +57,7 @@ function deepEqual(ref: any, val: any) { return false; } - for (let key of refKeys) { + for (const key of refKeys) { if (!valKeys.includes(key)) { console.log(`Key ${key} not found in value`); return false; @@ -46,34 +78,256 @@ function deepEqual(ref: any, val: any) { } describe('layout', () => { - it('decode event', async () => { - const data = [ - 0, 0, 0, 0, 1, 0, 0, 0, 33, 32, 204, 221, 5, 83, 170, 139, 228, 191, - 81, 173, 10, 116, 229, 191, 155, 209, 23, 164, 28, 64, 188, 34, 248, - 127, 110, 97, 26, 188, 139, 164, 0, 0, 0, 0, 1, 0, 0, 0, 22, 143, - 135, 215, 254, 121, 58, 95, 241, 202, 91, 53, 255, 47, 224, 255, 67, - 218, 48, 172, 51, 208, 29, 102, 177, 187, 207, 73, 108, 18, 59, 255, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 1, 0, 0, 0, 68, 77, 125, 32, 76, 128, 61, 180, 1, 207, 69, - 44, 121, 118, 153, 17, 179, 183, 115, 34, 163, 127, 102, 214, 1, 87, - 175, 177, 95, 49, 65, 69, 0, + describe('encode/decode InstructionDataInvoke', () => { + const testCases = [ + { + description: 'default case', + data: { + proof: null, + inputCompressedAccountsWithMerkleContext: [], + outputCompressedAccounts: [], + relayFee: null, + newAddressParams: [], + compressOrDecompressLamports: null, + isCompress: true, + }, + }, + { + description: 'with proof', + data: { + proof: { + a: [ + 32, 3, 117, 58, 153, 131, 148, 196, 202, 221, 250, + 146, 196, 209, 8, 192, 211, 235, 57, 47, 234, 98, + 152, 195, 227, 9, 16, 156, 194, 41, 247, 89, + ], + b: [ + 22, 192, 18, 134, 24, 94, 169, 42, 151, 182, 237, + 164, 250, 163, 253, 24, 51, 142, 37, 55, 141, 92, + 198, 146, 177, 23, 113, 12, 122, 27, 143, 64, 26, + 191, 99, 235, 113, 154, 23, 234, 173, 101, 16, 34, + 192, 108, 61, 10, 206, 251, 84, 242, 238, 92, 131, + 107, 252, 227, 70, 181, 35, 236, 195, 209, + ], + c: [ + 166, 160, 56, 185, 41, 239, 140, 4, 255, 144, 213, + 185, 153, 246, 199, 206, 47, 210, 17, 10, 66, 68, + 132, 229, 12, 67, 166, 168, 229, 156, 90, 30, + ], + }, + inputCompressedAccountsWithMerkleContext: [], + outputCompressedAccounts: [], + relayFee: null, + newAddressParams: [], + compressOrDecompressLamports: null, + isCompress: true, + }, + }, + { + description: 'with inputCompressedAccountsWithMerkleContext', + data: { + proof: null, + inputCompressedAccountsWithMerkleContext: [ + { + compressedAccount: { + owner: new PublicKey( + '6ASf5EcmmEHTgDJ4X4ZT5vT6iHVJBXPg5AN5YoTCpGWt', + ), + lamports: new BN(0), + address: null, + data: null, + }, + merkleContext: { + merkleTreePubkeyIndex: 0, + nullifierQueuePubkeyIndex: 1, + leafIndex: 10, + queueIndex: null, + }, + rootIndex: 0, + readOnly: false, + }, + ], + outputCompressedAccounts: [], + relayFee: null, + newAddressParams: [], + compressOrDecompressLamports: null, + isCompress: true, + }, + }, + { + description: 'with outputCompressedAccounts', + data: { + proof: null, + inputCompressedAccountsWithMerkleContext: [], + outputCompressedAccounts: [ + { + compressedAccount: { + owner: new PublicKey( + 'ARaDUvjovQDvFTMqaNAu9f2j1MpqJ5rhDAnDFrnyKbwg', + ), + lamports: new BN(0), + address: null, + data: null, + }, + merkleTreeIndex: 0, + }, + ], + relayFee: null, + newAddressParams: [], + compressOrDecompressLamports: null, + isCompress: true, + }, + }, + { + description: 'with relayFee', + data: { + proof: null, + inputCompressedAccountsWithMerkleContext: [], + outputCompressedAccounts: [], + relayFee: new BN(500), + newAddressParams: [], + compressOrDecompressLamports: null, + isCompress: true, + }, + }, + { + description: 'with newAddressParams', + data: { + proof: null, + inputCompressedAccountsWithMerkleContext: [], + outputCompressedAccounts: [], + relayFee: null, + newAddressParams: [ + { + seed: Array.from({ length: 32 }, () => + Math.floor(Math.random() * 256), + ), + addressQueueAccountIndex: 0, + addressMerkleTreeAccountIndex: 0, + addressMerkleTreeRootIndex: 0, + }, + ], + compressOrDecompressLamports: null, + isCompress: true, + }, + }, ]; - const event = decodePublicTransactionEvent(Buffer.from(data)); + testCases.forEach(({ description, data }) => { + it(`should encode/decode InstructionDataInvoke: ${description}`, () => { + const encoded = encodeInstructionDataInvoke(data); + const decoded = decodeInstructionDataInvoke(encoded); - const refOutputCompressedAccountHash = [ - 33, 32, 204, 221, 5, 83, 170, 139, 228, 191, 81, 173, 10, 116, 229, - 191, 155, 209, 23, 164, 28, 64, 188, 34, 248, 127, 110, 97, 26, 188, - 139, 164, - ]; + expect(deepEqual(decoded, data)).toBe(true); - expect(event.outputCompressedAccountHashes[0]).toEqual( - Buffer.from(refOutputCompressedAccountHash), - ); + const anchordata = getTestProgram().coder.types.encode( + 'InstructionDataInvoke', + data, + ); + expect(anchordata).toEqual(encoded.slice(12)); + }); + }); }); - it('encode/decode CompressedTokenInstructionDataTransfer', () => { - const data: InstructionDataInvoke = {}; - expect(deepEqual(decoded, data)).toBe(true); + describe('encode/decode PublicTransactionEvent', () => { + it('should encode and decode PublicTransactionEvent correctly', () => { + const data: PublicTransactionEvent = { + inputCompressedAccountHashes: [], + outputCompressedAccountHashes: [], + outputCompressedAccounts: [], + outputLeafIndices: [], + sequenceNumbers: [], + relayFee: null, + isCompress: true, + compressOrDecompressLamports: null, + pubkeyArray: [], + message: null, + }; + + const encoded = encodePublicTransactionEvent(data); + + const decoded = decodePublicTransactionEvent(encoded); + + const anchordata = getTestProgram().coder.types.encode( + 'PublicTransactionEvent', + data, + ); + expect(anchordata).toEqual(encoded); + + expect(deepEqual(decoded, data)).toBe(true); + }); + }); + + describe('invokeAccountsLayout', () => { + it('should return correct AccountMeta array', () => { + const accounts = { + feePayer: new PublicKey('11111111111111111111111111111111'), + authority: new PublicKey('11111111111111111111111111111111'), + registeredProgramPda: new PublicKey( + '11111111111111111111111111111111', + ), + noopProgram: new PublicKey('11111111111111111111111111111111'), + accountCompressionAuthority: new PublicKey( + '11111111111111111111111111111111', + ), + accountCompressionProgram: new PublicKey( + '11111111111111111111111111111111', + ), + solPoolPda: null, + decompressionRecipient: null, + systemProgram: new PublicKey( + '11111111111111111111111111111111', + ), + }; + + const expected = [ + { pubkey: accounts.feePayer, isSigner: true, isWritable: true }, + { + pubkey: accounts.authority, + isSigner: true, + isWritable: false, + }, + { + pubkey: accounts.registeredProgramPda, + isSigner: false, + isWritable: false, + }, + { + pubkey: accounts.noopProgram, + isSigner: false, + isWritable: false, + }, + { + pubkey: accounts.accountCompressionAuthority, + isSigner: false, + isWritable: false, + }, + { + pubkey: accounts.accountCompressionProgram, + isSigner: false, + isWritable: false, + }, + { + pubkey: accounts.solPoolPda ?? LightSystemProgram.programId, + isSigner: false, + isWritable: false, + }, + { + pubkey: + accounts.decompressionRecipient ?? + LightSystemProgram.programId, + isSigner: false, + isWritable: true, + }, + { + pubkey: accounts.systemProgram, + isSigner: false, + isWritable: false, + }, + ]; + + const result = invokeAccountsLayout(accounts); + expect(result).toEqual(expected); + }); }); }); diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index ad1884fc4e..c3c9081a08 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -333,7 +333,7 @@ importers: dependencies: '@coral-xyz/borsh': specifier: ^0.29.0 - version: 0.29.0(@solana/web3.js@1.98.0) + version: 0.29.0(@solana/web3.js@1.98.0(bufferutil@4.0.8)(utf-8-validate@5.0.10)) '@lightprotocol/stateless.js': specifier: workspace:* version: link:../stateless.js @@ -344,6 +344,9 @@ importers: specifier: 6.0.3 version: 6.0.3 devDependencies: + '@coral-xyz/anchor': + specifier: ^0.29.0 + version: 0.29.0(bufferutil@4.0.8)(utf-8-validate@5.0.10) '@esbuild-plugins/node-globals-polyfill': specifier: ^0.2.3 version: 0.2.3(esbuild@0.21.1) @@ -454,7 +457,7 @@ importers: dependencies: '@coral-xyz/borsh': specifier: ^0.29.0 - version: 0.29.0(@solana/web3.js@1.98.0) + version: 0.29.0(@solana/web3.js@1.98.0(bufferutil@4.0.8)(utf-8-validate@5.0.10)) '@noble/hashes': specifier: 1.5.0 version: 1.5.0 @@ -477,6 +480,9 @@ importers: specifier: 2.0.2 version: 2.0.2 devDependencies: + '@coral-xyz/anchor': + specifier: 0.29.0 + version: 0.29.0(bufferutil@4.0.8)(utf-8-validate@5.0.10) '@esbuild-plugins/node-globals-polyfill': specifier: ^0.2.3 version: 0.2.3(esbuild@0.21.1) @@ -9443,7 +9449,7 @@ snapshots: '@coral-xyz/anchor@0.29.0(bufferutil@4.0.8)(utf-8-validate@5.0.10)': dependencies: - '@coral-xyz/borsh': 0.29.0(@solana/web3.js@1.98.0) + '@coral-xyz/borsh': 0.29.0(@solana/web3.js@1.98.0(bufferutil@4.0.8)(utf-8-validate@5.0.10)) '@noble/hashes': 1.5.0 '@solana/web3.js': 1.98.0(bufferutil@4.0.8)(utf-8-validate@5.0.10) bn.js: 5.2.1 @@ -9483,7 +9489,7 @@ snapshots: - encoding - utf-8-validate - '@coral-xyz/borsh@0.29.0(@solana/web3.js@1.98.0)': + '@coral-xyz/borsh@0.29.0(@solana/web3.js@1.98.0(bufferutil@4.0.8)(utf-8-validate@5.0.10))': dependencies: '@solana/web3.js': 1.98.0(bufferutil@4.0.8)(utf-8-validate@5.0.10) bn.js: 5.2.1 @@ -13216,7 +13222,7 @@ snapshots: '@typescript-eslint/parser': 7.13.1(eslint@9.17.0)(typescript@5.7.2) eslint: 9.17.0 eslint-import-resolver-node: 0.3.9 - eslint-import-resolver-typescript: 3.6.1(@typescript-eslint/parser@7.13.1(eslint@9.17.0)(typescript@5.7.2))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.31.0(@typescript-eslint/parser@7.13.1(eslint@9.17.0)(typescript@5.7.2))(eslint@9.17.0))(eslint@9.17.0) + eslint-import-resolver-typescript: 3.6.1(@typescript-eslint/parser@7.13.1(eslint@9.17.0)(typescript@5.7.2))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.31.0)(eslint@9.17.0) eslint-plugin-import: 2.31.0(@typescript-eslint/parser@7.13.1(eslint@9.17.0)(typescript@5.7.2))(eslint-import-resolver-typescript@3.6.1)(eslint@9.17.0) eslint-plugin-jsx-a11y: 6.10.2(eslint@9.17.0) eslint-plugin-react: 7.37.2(eslint@9.17.0) @@ -13296,12 +13302,12 @@ snapshots: - eslint-import-resolver-webpack - supports-color - eslint-import-resolver-typescript@3.6.1(@typescript-eslint/parser@7.13.1(eslint@9.17.0)(typescript@5.7.2))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.31.0(@typescript-eslint/parser@7.13.1(eslint@9.17.0)(typescript@5.7.2))(eslint@9.17.0))(eslint@9.17.0): + eslint-import-resolver-typescript@3.6.1(@typescript-eslint/parser@7.13.1(eslint@9.17.0)(typescript@5.7.2))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.31.0)(eslint@9.17.0): dependencies: debug: 4.3.7(supports-color@8.1.1) enhanced-resolve: 5.17.1 eslint: 9.17.0 - eslint-module-utils: 2.12.0(@typescript-eslint/parser@7.13.1(eslint@9.17.0)(typescript@5.7.2))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.1(@typescript-eslint/parser@7.13.1(eslint@9.17.0)(typescript@5.7.2))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.31.0(@typescript-eslint/parser@7.13.1(eslint@9.17.0)(typescript@5.7.2))(eslint@9.17.0))(eslint@9.17.0))(eslint@9.17.0) + eslint-module-utils: 2.12.0(@typescript-eslint/parser@7.13.1(eslint@9.17.0)(typescript@5.7.2))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.1(@typescript-eslint/parser@7.13.1(eslint@9.17.0)(typescript@5.7.2))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.31.0)(eslint@9.17.0))(eslint@9.17.0) eslint-plugin-import: 2.31.0(@typescript-eslint/parser@7.13.1(eslint@9.17.0)(typescript@5.7.2))(eslint-import-resolver-typescript@3.6.1)(eslint@9.17.0) fast-glob: 3.3.2 get-tsconfig: 4.7.2 @@ -13333,14 +13339,14 @@ snapshots: transitivePeerDependencies: - supports-color - eslint-module-utils@2.12.0(@typescript-eslint/parser@7.13.1(eslint@9.17.0)(typescript@5.7.2))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.1(@typescript-eslint/parser@7.13.1(eslint@9.17.0)(typescript@5.7.2))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.31.0(@typescript-eslint/parser@7.13.1(eslint@9.17.0)(typescript@5.7.2))(eslint@9.17.0))(eslint@9.17.0))(eslint@9.17.0): + eslint-module-utils@2.12.0(@typescript-eslint/parser@7.13.1(eslint@9.17.0)(typescript@5.7.2))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.1(@typescript-eslint/parser@7.13.1(eslint@9.17.0)(typescript@5.7.2))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.31.0)(eslint@9.17.0))(eslint@9.17.0): dependencies: debug: 3.2.7 optionalDependencies: '@typescript-eslint/parser': 7.13.1(eslint@9.17.0)(typescript@5.7.2) eslint: 9.17.0 eslint-import-resolver-node: 0.3.9 - eslint-import-resolver-typescript: 3.6.1(@typescript-eslint/parser@7.13.1(eslint@9.17.0)(typescript@5.7.2))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.31.0(@typescript-eslint/parser@7.13.1(eslint@9.17.0)(typescript@5.7.2))(eslint@9.17.0))(eslint@9.17.0) + eslint-import-resolver-typescript: 3.6.1(@typescript-eslint/parser@7.13.1(eslint@9.17.0)(typescript@5.7.2))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.31.0)(eslint@9.17.0) transitivePeerDependencies: - supports-color @@ -13433,7 +13439,7 @@ snapshots: doctrine: 2.1.0 eslint: 9.17.0 eslint-import-resolver-node: 0.3.9 - eslint-module-utils: 2.12.0(@typescript-eslint/parser@7.13.1(eslint@9.17.0)(typescript@5.7.2))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.1(@typescript-eslint/parser@7.13.1(eslint@9.17.0)(typescript@5.7.2))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.31.0(@typescript-eslint/parser@7.13.1(eslint@9.17.0)(typescript@5.7.2))(eslint@9.17.0))(eslint@9.17.0))(eslint@9.17.0) + eslint-module-utils: 2.12.0(@typescript-eslint/parser@7.13.1(eslint@9.17.0)(typescript@5.7.2))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.1(@typescript-eslint/parser@7.13.1(eslint@9.17.0)(typescript@5.7.2))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.31.0)(eslint@9.17.0))(eslint@9.17.0) hasown: 2.0.2 is-core-module: 2.15.1 is-glob: 4.0.3 @@ -14616,7 +14622,7 @@ snapshots: isobject@3.0.1: {} - isomorphic-ws@4.0.1(ws@7.5.10): + isomorphic-ws@4.0.1(ws@7.5.10(bufferutil@4.0.8)(utf-8-validate@5.0.10)): dependencies: ws: 7.5.10(bufferutil@4.0.8)(utf-8-validate@5.0.10) @@ -14658,7 +14664,7 @@ snapshots: delay: 5.0.0 es6-promisify: 5.0.0 eyes: 0.1.8 - isomorphic-ws: 4.0.1(ws@7.5.10) + isomorphic-ws: 4.0.1(ws@7.5.10(bufferutil@4.0.8)(utf-8-validate@5.0.10)) json-stringify-safe: 5.0.1 uuid: 8.3.2 ws: 7.5.10(bufferutil@4.0.8)(utf-8-validate@5.0.10) From d5017c9d8cc7048d796880037a83149e81505826 Mon Sep 17 00:00:00 2001 From: Swenschaeferjohann Date: Mon, 6 Jan 2025 19:35:01 +0000 Subject: [PATCH 07/19] add todo --- js/compressed-token/src/layout.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/js/compressed-token/src/layout.ts b/js/compressed-token/src/layout.ts index 827fffddbb..edf13f57e0 100644 --- a/js/compressed-token/src/layout.ts +++ b/js/compressed-token/src/layout.ts @@ -356,6 +356,7 @@ export const transferAccountsLayout = ( return accountsList; }; +// TODO: use this layout for approve/revoke/freeze/thaw once we add them // export const approveAccountsLayout = ( // accounts: approveAccountsLayoutParams, // ): AccountMeta[] => { From 2129b5e7856143d7a0a6cb302941a50cd57ce5cb Mon Sep 17 00:00:00 2001 From: Swenschaeferjohann Date: Mon, 6 Jan 2025 19:35:37 +0000 Subject: [PATCH 08/19] clean --- js/compressed-token/src/program.ts | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/js/compressed-token/src/program.ts b/js/compressed-token/src/program.ts index e63d694e64..997d225b54 100644 --- a/js/compressed-token/src/program.ts +++ b/js/compressed-token/src/program.ts @@ -775,7 +775,6 @@ export class CompressedTokenProgram { cpiContext: null, lamportsChangeAccountMerkleTreeIndex: null, }; - console.log('TRANSFER'); const data = encodeTransferInstructionData(rawData); const { @@ -940,7 +939,6 @@ export class CompressedTokenProgram { cpiContext: null, lamportsChangeAccountMerkleTreeIndex: null, }; - console.log('COMPRESS'); const data = encodeTransferInstructionData(rawData); const tokenProgram = tokenProgramId ?? TOKEN_PROGRAM_ID; @@ -1016,7 +1014,6 @@ export class CompressedTokenProgram { cpiContext: null, lamportsChangeAccountMerkleTreeIndex: null, }; - console.log('DECOMPRESS'); const data = encodeTransferInstructionData(rawData); const tokenProgram = tokenProgramId ?? TOKEN_PROGRAM_ID; const { @@ -1066,7 +1063,7 @@ export class CompressedTokenProgram { if (inputCompressedTokenAccounts.length > 3) { throw new Error('Cannot merge more than 3 token accounts at once'); } - console.log('MERGE'); + const ix = await this.transfer({ payer, inputCompressedTokenAccounts, From 0977905d318d67c21012b2cd9829db5d365fca86 Mon Sep 17 00:00:00 2001 From: Swenschaeferjohann Date: Mon, 6 Jan 2025 20:07:42 +0000 Subject: [PATCH 09/19] rm es bundles --- js/compressed-token/rollup.config.js | 2 +- js/stateless.js/rollup.config.js | 23 ++++++++++++++++++++++- 2 files changed, 23 insertions(+), 2 deletions(-) diff --git a/js/compressed-token/rollup.config.js b/js/compressed-token/rollup.config.js index 4e32f1c568..18c5680ec4 100644 --- a/js/compressed-token/rollup.config.js +++ b/js/compressed-token/rollup.config.js @@ -81,7 +81,7 @@ const typesConfig = { export default [ rolls('cjs', 'browser'), - rolls('es', 'browser'), + // rolls('es', 'browser'), rolls('cjs', 'node'), typesConfig, ]; diff --git a/js/stateless.js/rollup.config.js b/js/stateless.js/rollup.config.js index 90ac4f534a..765f66fa3f 100644 --- a/js/stateless.js/rollup.config.js +++ b/js/stateless.js/rollup.config.js @@ -3,6 +3,7 @@ import nodePolyfills from 'rollup-plugin-polyfill-node'; import dts from 'rollup-plugin-dts'; import resolve from '@rollup/plugin-node-resolve'; import commonjs from '@rollup/plugin-commonjs'; +import terser from '@rollup/plugin-terser'; import json from '@rollup/plugin-json'; const rolls = (fmt, env) => ({ @@ -27,6 +28,26 @@ const rolls = (fmt, env) => ({ }), env === 'browser' ? nodePolyfills() : undefined, json(), + terser({ + compress: { + drop_console: true, + drop_debugger: true, + passes: 3, + pure_funcs: ['console.log', 'console.error', 'console.warn'], + booleans_as_integers: true, + keep_fargs: false, + keep_fnames: false, + keep_infinity: true, + reduce_funcs: true, + reduce_vars: true, + }, + mangle: { + toplevel: true, + }, + output: { + comments: false, + }, + }), ].filter(Boolean), onwarn(warning, warn) { if (warning.code !== 'CIRCULAR_DEPENDENCY') { @@ -43,7 +64,7 @@ const typesConfig = { export default [ rolls('cjs', 'browser'), - rolls('es', 'browser'), + // rolls('es', 'browser'), rolls('cjs', 'node'), typesConfig, ]; From f6758bc02f8408bdfb4ebccf62cdf28897a47070 Mon Sep 17 00:00:00 2001 From: Swenschaeferjohann Date: Mon, 6 Jan 2025 20:09:55 +0000 Subject: [PATCH 10/19] bump --- js/compressed-token/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/js/compressed-token/package.json b/js/compressed-token/package.json index 0bc944db00..78f3054b94 100644 --- a/js/compressed-token/package.json +++ b/js/compressed-token/package.json @@ -1,6 +1,6 @@ { "name": "@lightprotocol/compressed-token", - "version": "0.17.2-alpha.0", + "version": "0.17.2-alpha.1", "description": "JS client to interact with the compressed-token program", "sideEffects": false, "main": "dist/cjs/node/index.cjs", From 53345c693c821e6995c2d41d0872e90d1e14e31e Mon Sep 17 00:00:00 2001 From: Swenschaeferjohann Date: Mon, 6 Jan 2025 22:20:00 +0000 Subject: [PATCH 11/19] wip - debug ct --- js/compressed-token/src/layout.ts | 1 - js/compressed-token/src/program.ts | 7 +++ .../tests/e2e/create-token-pool.test.ts | 50 ++++++++++++++++++- js/stateless.js/package.json | 2 +- 4 files changed, 57 insertions(+), 3 deletions(-) diff --git a/js/compressed-token/src/layout.ts b/js/compressed-token/src/layout.ts index edf13f57e0..ed691ab6c8 100644 --- a/js/compressed-token/src/layout.ts +++ b/js/compressed-token/src/layout.ts @@ -231,7 +231,6 @@ export const createTokenPoolAccountsLayout = ( tokenProgram, cpiAuthorityPda, } = accounts; - return [ { pubkey: feePayer, isSigner: true, isWritable: true }, { pubkey: tokenPoolPda, isSigner: false, isWritable: true }, diff --git a/js/compressed-token/src/program.ts b/js/compressed-token/src/program.ts index 997d225b54..e531ba608a 100644 --- a/js/compressed-token/src/program.ts +++ b/js/compressed-token/src/program.ts @@ -621,6 +621,13 @@ export class CompressedTokenProgram { systemProgram: SystemProgram.programId, }); + console.log( + 'createTokenPool - deriveCpiAuthorityPda', + this.deriveCpiAuthorityPda, + ); + console.log('createTokenPool - tokenPoolPda', tokenPoolPda); + console.log('createTokenPool - Keys', keys); + return new TransactionInstruction({ programId: this.programId, keys, diff --git a/js/compressed-token/tests/e2e/create-token-pool.test.ts b/js/compressed-token/tests/e2e/create-token-pool.test.ts index 249af5e38a..43046b3beb 100644 --- a/js/compressed-token/tests/e2e/create-token-pool.test.ts +++ b/js/compressed-token/tests/e2e/create-token-pool.test.ts @@ -18,6 +18,7 @@ import { getTestRpc, } from '@lightprotocol/stateless.js'; import { WasmFactory } from '@lightprotocol/hasher.rs'; +import { TOKEN_2022_PROGRAM_ID } from '@solana/spl-token'; /** * Assert that createTokenPool() creates system-pool account for external mint, @@ -58,6 +59,7 @@ async function createTestSplMint( payer: Signer, mintKeypair: Signer, mintAuthority: Keypair, + isToken22?: boolean, ) { const rentExemptBalance = await rpc.getMinimumBalanceForRentExemption(MINT_SIZE); @@ -74,7 +76,7 @@ async function createTestSplMint( TEST_TOKEN_DECIMALS, mintAuthority.publicKey, null, - TOKEN_PROGRAM_ID, + isToken22 ? TOKEN_2022_PROGRAM_ID : TOKEN_PROGRAM_ID, ); const { blockhash } = await rpc.getLatestBlockhash(); @@ -136,6 +138,52 @@ describe('createTokenPool', () => { /// Mint already registered await expect(createTokenPool(rpc, payer, mint)).rejects.toThrow(); }); + it.only('should register existing spl token22 mint', async () => { + const token22MintKeypair = Keypair.generate(); + const token22Mint = token22MintKeypair.publicKey; + const token22MintAuthority = Keypair.generate(); + + /// Create external SPL Token 2022 mint + await createTestSplMint( + rpc, + payer, + token22MintKeypair, + token22MintAuthority, + ); + + const poolAccount = + CompressedTokenProgram.deriveTokenPoolPda(token22Mint); + + assert(token22Mint.equals(token22MintKeypair.publicKey)); + console.log('token22Mint', token22Mint.toString()); + /// Mint already exists externally + await expect( + createMint( + rpc, + payer, + token22MintAuthority.publicKey, + TEST_TOKEN_DECIMALS, + token22MintKeypair, + undefined, + true, + ), + ).rejects.toThrow(); + + await createTokenPool(rpc, payer, token22Mint); + + await assertRegisterMint( + token22Mint, + token22MintAuthority.publicKey, + rpc, + TEST_TOKEN_DECIMALS, + poolAccount, + ); + + /// Mint already registered + await expect( + createTokenPool(rpc, payer, token22Mint), + ).rejects.toThrow(); + }); it('should create mint with payer as authority', async () => { /// Create new external SPL mint with payer === authority diff --git a/js/stateless.js/package.json b/js/stateless.js/package.json index 56e9a6cdae..12837658b1 100644 --- a/js/stateless.js/package.json +++ b/js/stateless.js/package.json @@ -1,6 +1,6 @@ { "name": "@lightprotocol/stateless.js", - "version": "0.17.2-alpha.1", + "version": "0.17.2-alpha.2", "description": "JavaScript API for Light & ZK Compression", "sideEffects": false, "main": "dist/cjs/node/index.cjs", From c07353fe42dbfb9c71a9a10387406fa10941cf78 Mon Sep 17 00:00:00 2001 From: Swenschaeferjohann Date: Mon, 6 Jan 2025 22:21:09 +0000 Subject: [PATCH 12/19] wip --- js/compressed-token/rollup.config.js | 40 ++++++++++++++-------------- 1 file changed, 20 insertions(+), 20 deletions(-) diff --git a/js/compressed-token/rollup.config.js b/js/compressed-token/rollup.config.js index 18c5680ec4..7785aa4ce4 100644 --- a/js/compressed-token/rollup.config.js +++ b/js/compressed-token/rollup.config.js @@ -45,26 +45,26 @@ const rolls = (fmt, env) => ({ ], }), env === 'browser' ? nodePolyfills() : undefined, - terser({ - compress: { - drop_console: true, - drop_debugger: true, - passes: 3, - pure_funcs: ['console.log', 'console.error', 'console.warn'], - booleans_as_integers: true, - keep_fargs: false, - keep_fnames: false, - keep_infinity: true, - reduce_funcs: true, - reduce_vars: true, - }, - mangle: { - toplevel: true, - }, - output: { - comments: false, - }, - }), + // terser({ + // compress: { + // drop_console: true, + // drop_debugger: true, + // passes: 3, + // pure_funcs: ['console.log', 'console.error', 'console.warn'], + // booleans_as_integers: true, + // keep_fargs: false, + // keep_fnames: false, + // keep_infinity: true, + // reduce_funcs: true, + // reduce_vars: true, + // }, + // mangle: { + // toplevel: true, + // }, + // output: { + // comments: false, + // }, + // }), ].filter(Boolean), onwarn(warning, warn) { if (warning.code !== 'CIRCULAR_DEPENDENCY') { From b8b5761044fb2ddd41ac97aa4fdecad63fa12165 Mon Sep 17 00:00:00 2001 From: Swenschaeferjohann Date: Mon, 6 Jan 2025 22:23:23 +0000 Subject: [PATCH 13/19] wiop --- js/compressed-token/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/js/compressed-token/package.json b/js/compressed-token/package.json index 78f3054b94..7353f8d908 100644 --- a/js/compressed-token/package.json +++ b/js/compressed-token/package.json @@ -1,6 +1,6 @@ { "name": "@lightprotocol/compressed-token", - "version": "0.17.2-alpha.1", + "version": "0.17.2-alpha.2", "description": "JS client to interact with the compressed-token program", "sideEffects": false, "main": "dist/cjs/node/index.cjs", From ed606f628c87d14a9c47b09219fb1e5abc331626 Mon Sep 17 00:00:00 2001 From: Swenschaeferjohann Date: Mon, 6 Jan 2025 23:15:27 +0000 Subject: [PATCH 14/19] rm logs --- js/compressed-token/package.json | 2 +- js/compressed-token/rollup.config.js | 40 +++++++++---------- js/compressed-token/src/program.ts | 7 ---- .../tests/e2e/create-token-pool.test.ts | 2 +- 4 files changed, 22 insertions(+), 29 deletions(-) diff --git a/js/compressed-token/package.json b/js/compressed-token/package.json index 7353f8d908..6564bc7eaa 100644 --- a/js/compressed-token/package.json +++ b/js/compressed-token/package.json @@ -1,6 +1,6 @@ { "name": "@lightprotocol/compressed-token", - "version": "0.17.2-alpha.2", + "version": "0.17.2-alpha.3", "description": "JS client to interact with the compressed-token program", "sideEffects": false, "main": "dist/cjs/node/index.cjs", diff --git a/js/compressed-token/rollup.config.js b/js/compressed-token/rollup.config.js index 7785aa4ce4..18c5680ec4 100644 --- a/js/compressed-token/rollup.config.js +++ b/js/compressed-token/rollup.config.js @@ -45,26 +45,26 @@ const rolls = (fmt, env) => ({ ], }), env === 'browser' ? nodePolyfills() : undefined, - // terser({ - // compress: { - // drop_console: true, - // drop_debugger: true, - // passes: 3, - // pure_funcs: ['console.log', 'console.error', 'console.warn'], - // booleans_as_integers: true, - // keep_fargs: false, - // keep_fnames: false, - // keep_infinity: true, - // reduce_funcs: true, - // reduce_vars: true, - // }, - // mangle: { - // toplevel: true, - // }, - // output: { - // comments: false, - // }, - // }), + terser({ + compress: { + drop_console: true, + drop_debugger: true, + passes: 3, + pure_funcs: ['console.log', 'console.error', 'console.warn'], + booleans_as_integers: true, + keep_fargs: false, + keep_fnames: false, + keep_infinity: true, + reduce_funcs: true, + reduce_vars: true, + }, + mangle: { + toplevel: true, + }, + output: { + comments: false, + }, + }), ].filter(Boolean), onwarn(warning, warn) { if (warning.code !== 'CIRCULAR_DEPENDENCY') { diff --git a/js/compressed-token/src/program.ts b/js/compressed-token/src/program.ts index e531ba608a..997d225b54 100644 --- a/js/compressed-token/src/program.ts +++ b/js/compressed-token/src/program.ts @@ -621,13 +621,6 @@ export class CompressedTokenProgram { systemProgram: SystemProgram.programId, }); - console.log( - 'createTokenPool - deriveCpiAuthorityPda', - this.deriveCpiAuthorityPda, - ); - console.log('createTokenPool - tokenPoolPda', tokenPoolPda); - console.log('createTokenPool - Keys', keys); - return new TransactionInstruction({ programId: this.programId, keys, diff --git a/js/compressed-token/tests/e2e/create-token-pool.test.ts b/js/compressed-token/tests/e2e/create-token-pool.test.ts index 43046b3beb..454227e7f0 100644 --- a/js/compressed-token/tests/e2e/create-token-pool.test.ts +++ b/js/compressed-token/tests/e2e/create-token-pool.test.ts @@ -155,7 +155,7 @@ describe('createTokenPool', () => { CompressedTokenProgram.deriveTokenPoolPda(token22Mint); assert(token22Mint.equals(token22MintKeypair.publicKey)); - console.log('token22Mint', token22Mint.toString()); + /// Mint already exists externally await expect( createMint( From 537a04478f16be5341c9b4dfafbce37751e1ce34 Mon Sep 17 00:00:00 2001 From: Swenschaeferjohann Date: Mon, 6 Jan 2025 23:18:53 +0000 Subject: [PATCH 15/19] bump js releases to 0.18.0 --- js/compressed-token/package.json | 2 +- js/stateless.js/package.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/js/compressed-token/package.json b/js/compressed-token/package.json index 6564bc7eaa..9f5fa4b360 100644 --- a/js/compressed-token/package.json +++ b/js/compressed-token/package.json @@ -1,6 +1,6 @@ { "name": "@lightprotocol/compressed-token", - "version": "0.17.2-alpha.3", + "version": "0.18.0", "description": "JS client to interact with the compressed-token program", "sideEffects": false, "main": "dist/cjs/node/index.cjs", diff --git a/js/stateless.js/package.json b/js/stateless.js/package.json index 12837658b1..cee6df0be0 100644 --- a/js/stateless.js/package.json +++ b/js/stateless.js/package.json @@ -1,6 +1,6 @@ { "name": "@lightprotocol/stateless.js", - "version": "0.17.2-alpha.2", + "version": "0.18.0", "description": "JavaScript API for Light & ZK Compression", "sideEffects": false, "main": "dist/cjs/node/index.cjs", From aa0257dd61464ffb69f5a63924bf415b98b96e82 Mon Sep 17 00:00:00 2001 From: Swenschaeferjohann Date: Mon, 6 Jan 2025 23:22:33 +0000 Subject: [PATCH 16/19] rm only --- js/compressed-token/rollup.config.js | 1 - js/compressed-token/tests/e2e/create-token-pool.test.ts | 2 +- js/stateless.js/rollup.config.js | 1 - 3 files changed, 1 insertion(+), 3 deletions(-) diff --git a/js/compressed-token/rollup.config.js b/js/compressed-token/rollup.config.js index 18c5680ec4..6f02c4084b 100644 --- a/js/compressed-token/rollup.config.js +++ b/js/compressed-token/rollup.config.js @@ -81,7 +81,6 @@ const typesConfig = { export default [ rolls('cjs', 'browser'), - // rolls('es', 'browser'), rolls('cjs', 'node'), typesConfig, ]; diff --git a/js/compressed-token/tests/e2e/create-token-pool.test.ts b/js/compressed-token/tests/e2e/create-token-pool.test.ts index 454227e7f0..1e285a3b66 100644 --- a/js/compressed-token/tests/e2e/create-token-pool.test.ts +++ b/js/compressed-token/tests/e2e/create-token-pool.test.ts @@ -138,7 +138,7 @@ describe('createTokenPool', () => { /// Mint already registered await expect(createTokenPool(rpc, payer, mint)).rejects.toThrow(); }); - it.only('should register existing spl token22 mint', async () => { + it('should register existing spl token22 mint', async () => { const token22MintKeypair = Keypair.generate(); const token22Mint = token22MintKeypair.publicKey; const token22MintAuthority = Keypair.generate(); diff --git a/js/stateless.js/rollup.config.js b/js/stateless.js/rollup.config.js index 765f66fa3f..72140f365f 100644 --- a/js/stateless.js/rollup.config.js +++ b/js/stateless.js/rollup.config.js @@ -64,7 +64,6 @@ const typesConfig = { export default [ rolls('cjs', 'browser'), - // rolls('es', 'browser'), rolls('cjs', 'node'), typesConfig, ]; From 7b3127c49ba7997b42ff6b528152bb4426f99e1e Mon Sep 17 00:00:00 2001 From: Swenschaeferjohann Date: Mon, 6 Jan 2025 23:26:57 +0000 Subject: [PATCH 17/19] add layout.test.ts to pnpm test --- js/compressed-token/package.json | 2 +- js/stateless.js/package.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/js/compressed-token/package.json b/js/compressed-token/package.json index 9f5fa4b360..9d26e45e98 100644 --- a/js/compressed-token/package.json +++ b/js/compressed-token/package.json @@ -93,7 +93,7 @@ "test:e2e:compress-spl-token-account": "pnpm test-validator && vitest run tests/e2e/compress-spl-token-account.test.ts --reporter=verbose", "test:e2e:decompress": "pnpm test-validator && vitest run tests/e2e/decompress.test.ts --reporter=verbose", "test:e2e:rpc-token-interop": "pnpm test-validator && vitest run tests/e2e/rpc-token-interop.test.ts --reporter=verbose", - "test:e2e:all": "pnpm test-validator && vitest run tests/e2e/create-mint.test.ts && vitest run tests/e2e/mint-to.test.ts && vitest run tests/e2e/transfer.test.ts && vitest run tests/e2e/compress.test.ts && vitest run tests/e2e/compress-spl-token-account.test.ts && vitest run tests/e2e/decompress.test.ts && vitest run tests/e2e/create-token-pool.test.ts && vitest run tests/e2e/approve-and-mint-to.test.ts && vitest run tests/e2e/rpc-token-interop.test.ts", + "test:e2e:all": "pnpm test-validator && vitest run tests/e2e/create-mint.test.ts && vitest run tests/e2e/mint-to.test.ts && vitest run tests/e2e/transfer.test.ts && vitest run tests/e2e/compress.test.ts && vitest run tests/e2e/compress-spl-token-account.test.ts && vitest run tests/e2e/decompress.test.ts && vitest run tests/e2e/create-token-pool.test.ts && vitest run tests/e2e/approve-and-mint-to.test.ts && vitest run tests/e2e/rpc-token-interop.test.ts && vitest run tests/e2e/layout.test.ts", "pull-idl": "../../scripts/push-compressed-token-idl.sh", "build": "rimraf dist && pnpm build:bundle", "build:bundle": "rollup -c", diff --git a/js/stateless.js/package.json b/js/stateless.js/package.json index cee6df0be0..59898a3d0b 100644 --- a/js/stateless.js/package.json +++ b/js/stateless.js/package.json @@ -92,7 +92,7 @@ "test:e2e:test-rpc": "pnpm test-validator && vitest run tests/e2e/test-rpc.test.ts", "test:e2e:rpc-interop": "pnpm test-validator && vitest run tests/e2e/rpc-interop.test.ts", "test:e2e:browser": "pnpm playwright test", - "test:e2e:all": "pnpm test-validator && vitest run tests/e2e/test-rpc.test.ts && vitest run tests/e2e/compress.test.ts && vitest run tests/e2e/transfer.test.ts && vitest run tests/e2e/rpc-interop.test.ts", + "test:e2e:all": "pnpm test-validator && vitest run tests/e2e/test-rpc.test.ts && vitest run tests/e2e/compress.test.ts && vitest run tests/e2e/transfer.test.ts && vitest run tests/e2e/rpc-interop.test.ts && vitest run tests/e2e/layout.test.ts", "test:index": "vitest run tests/e2e/program.test.ts", "test:e2e:layout": "vitest run tests/e2e/layout.test.ts --reporter=verbose", "test:verbose": "vitest run --reporter=verbose", From 623a71c6d311863583286b267a5546edc235e7b0 Mon Sep 17 00:00:00 2001 From: Swenschaeferjohann Date: Mon, 6 Jan 2025 23:37:34 +0000 Subject: [PATCH 18/19] layout test with real keys --- js/compressed-token/tests/e2e/layout.test.ts | 163 +++++++++++-------- 1 file changed, 95 insertions(+), 68 deletions(-) diff --git a/js/compressed-token/tests/e2e/layout.test.ts b/js/compressed-token/tests/e2e/layout.test.ts index b6f20d8714..f198509db2 100644 --- a/js/compressed-token/tests/e2e/layout.test.ts +++ b/js/compressed-token/tests/e2e/layout.test.ts @@ -19,9 +19,16 @@ import { mintToAccountsLayout, createTokenPoolAccountsLayout, transferAccountsLayout, + CompressedTokenProgram, } from '../../src/'; import { Keypair } from '@solana/web3.js'; import { Connection } from '@solana/web3.js'; +import { TOKEN_2022_PROGRAM_ID } from '@solana/spl-token'; +import { SystemProgram } from '@solana/web3.js'; +import { + defaultStaticAccountsStruct, + LightSystemProgram, +} from '@lightprotocol/stateless.js'; const getTestProgram = (): Program => { const mockKeypair = Keypair.generate(); @@ -86,6 +93,24 @@ const IX_DISCRIMINATOR = 8; const LENGTH_DISCRIMINATOR = 4; describe('layout', () => { + const mint = Keypair.generate().publicKey; + const feePayer = Keypair.generate().publicKey; + const authority = Keypair.generate().publicKey; + const cpiAuthorityPda = CompressedTokenProgram.deriveCpiAuthorityPda; + const tokenPoolPda = CompressedTokenProgram.deriveTokenPoolPda(mint); + const tokenProgram = TOKEN_2022_PROGRAM_ID; + const lightSystemProgram = LightSystemProgram.programId; + const registeredProgramPda = + defaultStaticAccountsStruct().registeredProgramPda; + const noopProgram = defaultStaticAccountsStruct().noopProgram; + const accountCompressionAuthority = + defaultStaticAccountsStruct().accountCompressionAuthority; + const accountCompressionProgram = + defaultStaticAccountsStruct().accountCompressionProgram; + const merkleTree = PublicKey.default; + const selfProgram = CompressedTokenProgram.programId; + const systemProgram = SystemProgram.programId; + const solPoolPda = LightSystemProgram.deriveCompressedSolPda(); describe('encode/decode transfer/compress/decompress', () => { const testCases = [ { @@ -488,38 +513,38 @@ describe('layout', () => { describe('Accounts Layout Helper Functions', () => { it('createTokenPoolAccountsLayout should return correct AccountMeta array', () => { const accounts = { - feePayer: PublicKey.default, - tokenPoolPda: PublicKey.default, - systemProgram: PublicKey.default, - mint: PublicKey.default, - tokenProgram: PublicKey.default, - cpiAuthorityPda: PublicKey.default, + feePayer, + tokenPoolPda, + systemProgram, + mint, + tokenProgram, + cpiAuthorityPda, }; const expected = [ - { pubkey: PublicKey.default, isSigner: true, isWritable: true }, + { pubkey: feePayer, isSigner: true, isWritable: true }, { - pubkey: PublicKey.default, + pubkey: tokenPoolPda, isSigner: false, isWritable: true, }, { - pubkey: PublicKey.default, + pubkey: systemProgram, isSigner: false, isWritable: false, }, { - pubkey: PublicKey.default, + pubkey: mint, isSigner: false, isWritable: true, }, { - pubkey: PublicKey.default, + pubkey: tokenProgram, isSigner: false, isWritable: false, }, { - pubkey: PublicKey.default, + pubkey: cpiAuthorityPda, isSigner: false, isWritable: false, }, @@ -531,92 +556,92 @@ describe('layout', () => { it('mintToAccountsLayout should return correct AccountMeta array', () => { const accounts = { - feePayer: PublicKey.default, - authority: PublicKey.default, - cpiAuthorityPda: PublicKey.default, - mint: PublicKey.default, - tokenPoolPda: PublicKey.default, - tokenProgram: PublicKey.default, - lightSystemProgram: PublicKey.default, - registeredProgramPda: PublicKey.default, - noopProgram: PublicKey.default, - accountCompressionAuthority: PublicKey.default, - accountCompressionProgram: PublicKey.default, - merkleTree: PublicKey.default, - selfProgram: PublicKey.default, - systemProgram: PublicKey.default, - solPoolPda: PublicKey.default, + feePayer, + authority, + cpiAuthorityPda, + mint, + tokenPoolPda, + tokenProgram, + lightSystemProgram, + registeredProgramPda, + noopProgram, + accountCompressionAuthority, + accountCompressionProgram, + merkleTree, + selfProgram, + systemProgram, + solPoolPda, }; const expected = [ - { pubkey: PublicKey.default, isSigner: true, isWritable: true }, + { pubkey: feePayer, isSigner: true, isWritable: true }, { - pubkey: PublicKey.default, + pubkey: authority, isSigner: true, isWritable: false, }, { - pubkey: PublicKey.default, + pubkey: cpiAuthorityPda, isSigner: false, isWritable: false, }, { - pubkey: PublicKey.default, + pubkey: mint, isSigner: false, isWritable: true, }, { - pubkey: PublicKey.default, + pubkey: tokenPoolPda, isSigner: false, isWritable: true, }, { - pubkey: PublicKey.default, + pubkey: tokenProgram, isSigner: false, isWritable: false, }, { - pubkey: PublicKey.default, + pubkey: lightSystemProgram, isSigner: false, isWritable: false, }, { - pubkey: PublicKey.default, + pubkey: registeredProgramPda, isSigner: false, isWritable: false, }, { - pubkey: PublicKey.default, + pubkey: noopProgram, isSigner: false, isWritable: false, }, { - pubkey: PublicKey.default, + pubkey: accountCompressionAuthority, isSigner: false, isWritable: false, }, { - pubkey: PublicKey.default, + pubkey: accountCompressionProgram, isSigner: false, isWritable: false, }, { - pubkey: PublicKey.default, + pubkey: merkleTree, isSigner: false, isWritable: true, }, { - pubkey: PublicKey.default, + pubkey: selfProgram, isSigner: false, isWritable: false, }, { - pubkey: PublicKey.default, + pubkey: systemProgram, isSigner: false, isWritable: false, }, { - pubkey: PublicKey.default, + pubkey: solPoolPda, isSigner: false, isWritable: true, }, @@ -627,81 +652,83 @@ describe('layout', () => { }); it('transferAccountsLayout should return correct AccountMeta array', () => { + const compressOrDecompressTokenAccount = + Keypair.generate().publicKey; const accounts = { - feePayer: PublicKey.default, - authority: PublicKey.default, - cpiAuthorityPda: PublicKey.default, - lightSystemProgram: PublicKey.default, - registeredProgramPda: PublicKey.default, - noopProgram: PublicKey.default, - accountCompressionAuthority: PublicKey.default, - accountCompressionProgram: PublicKey.default, - selfProgram: PublicKey.default, - tokenPoolPda: PublicKey.default, - compressOrDecompressTokenAccount: PublicKey.default, - tokenProgram: PublicKey.default, - systemProgram: PublicKey.default, + feePayer, + authority, + cpiAuthorityPda, + lightSystemProgram, + registeredProgramPda, + noopProgram, + accountCompressionAuthority, + accountCompressionProgram, + selfProgram, + tokenPoolPda, + compressOrDecompressTokenAccount, + tokenProgram, + systemProgram, }; const expected = [ - { pubkey: PublicKey.default, isSigner: true, isWritable: true }, + { pubkey: feePayer, isSigner: true, isWritable: true }, { - pubkey: PublicKey.default, + pubkey: authority, isSigner: true, isWritable: false, }, { - pubkey: PublicKey.default, + pubkey: cpiAuthorityPda, isSigner: false, isWritable: false, }, { - pubkey: PublicKey.default, + pubkey: lightSystemProgram, isSigner: false, isWritable: false, }, { - pubkey: PublicKey.default, + pubkey: registeredProgramPda, isSigner: false, isWritable: false, }, { - pubkey: PublicKey.default, + pubkey: noopProgram, isSigner: false, isWritable: false, }, { - pubkey: PublicKey.default, + pubkey: accountCompressionAuthority, isSigner: false, isWritable: false, }, { - pubkey: PublicKey.default, + pubkey: accountCompressionProgram, isSigner: false, isWritable: false, }, { - pubkey: PublicKey.default, + pubkey: selfProgram, isSigner: false, isWritable: false, }, { - pubkey: PublicKey.default, + pubkey: tokenPoolPda, isSigner: false, isWritable: true, }, { - pubkey: PublicKey.default, + pubkey: compressOrDecompressTokenAccount, isSigner: false, isWritable: true, }, { - pubkey: PublicKey.default, + pubkey: tokenProgram, isSigner: false, isWritable: false, }, { - pubkey: PublicKey.default, + pubkey: systemProgram, isSigner: false, isWritable: false, }, From 1332c2f7d8be159b11976bf29c685b62a331a627 Mon Sep 17 00:00:00 2001 From: Swenschaeferjohann Date: Mon, 6 Jan 2025 23:43:24 +0000 Subject: [PATCH 19/19] real keys for layout.test.ts in stateless.js --- js/stateless.js/tests/e2e/layout.test.ts | 149 ++++++++++++++++++----- 1 file changed, 118 insertions(+), 31 deletions(-) diff --git a/js/stateless.js/tests/e2e/layout.test.ts b/js/stateless.js/tests/e2e/layout.test.ts index 8c651e340a..1ccd832ad5 100644 --- a/js/stateless.js/tests/e2e/layout.test.ts +++ b/js/stateless.js/tests/e2e/layout.test.ts @@ -1,5 +1,5 @@ import { describe, it, expect } from 'vitest'; -import { Connection, Keypair, PublicKey } from '@solana/web3.js'; +import { Connection, Keypair, PublicKey, SystemProgram } from '@solana/web3.js'; import BN from 'bn.js'; import { Program, @@ -16,7 +16,12 @@ import { } from '../../src/programs/layout'; import { InstructionDataInvoke, PublicTransactionEvent } from '../../src/state'; import { Buffer } from 'buffer'; -import { IDL, LightSystemProgram, LightSystemProgramIDL } from '../../src'; +import { + defaultStaticAccountsStruct, + IDL, + LightSystemProgram, + LightSystemProgramIDL, +} from '../../src'; const getTestProgram = (): Program => { const mockKeypair = Keypair.generate(); @@ -259,71 +264,153 @@ describe('layout', () => { }); describe('invokeAccountsLayout', () => { - it('should return correct AccountMeta array', () => { + const feePayer = new Keypair().publicKey; + const authority = new Keypair().publicKey; + const registeredProgramPda = + defaultStaticAccountsStruct().registeredProgramPda; + const noopProgram = defaultStaticAccountsStruct().noopProgram; + const accountCompressionAuthority = + defaultStaticAccountsStruct().accountCompressionAuthority; + const accountCompressionProgram = + defaultStaticAccountsStruct().accountCompressionProgram; + const solPoolPda = LightSystemProgram.deriveCompressedSolPda(); + const decompressionRecipient = + LightSystemProgram.deriveCompressedSolPda(); + const systemProgram = SystemProgram.programId; + + it('should return correct AccountMeta array with null solPoodPda', () => { const accounts = { - feePayer: new PublicKey('11111111111111111111111111111111'), - authority: new PublicKey('11111111111111111111111111111111'), - registeredProgramPda: new PublicKey( - '11111111111111111111111111111111', - ), - noopProgram: new PublicKey('11111111111111111111111111111111'), - accountCompressionAuthority: new PublicKey( - '11111111111111111111111111111111', - ), - accountCompressionProgram: new PublicKey( - '11111111111111111111111111111111', - ), + feePayer, + authority, + registeredProgramPda, + noopProgram, + accountCompressionAuthority, + accountCompressionProgram, solPoolPda: null, - decompressionRecipient: null, - systemProgram: new PublicKey( - '11111111111111111111111111111111', - ), + decompressionRecipient, + systemProgram, }; const expected = [ - { pubkey: accounts.feePayer, isSigner: true, isWritable: true }, + { pubkey: feePayer, isSigner: true, isWritable: true }, + { pubkey: authority, isSigner: true, isWritable: false }, { - pubkey: accounts.authority, - isSigner: true, + pubkey: registeredProgramPda, + isSigner: false, isWritable: false, }, + { pubkey: noopProgram, isSigner: false, isWritable: false }, { - pubkey: accounts.registeredProgramPda, + pubkey: accountCompressionAuthority, isSigner: false, isWritable: false, }, { - pubkey: accounts.noopProgram, + pubkey: accountCompressionProgram, isSigner: false, isWritable: false, }, { - pubkey: accounts.accountCompressionAuthority, + pubkey: LightSystemProgram.programId, isSigner: false, isWritable: false, }, { - pubkey: accounts.accountCompressionProgram, + pubkey: decompressionRecipient, + isSigner: false, + isWritable: true, + }, + { pubkey: systemProgram, isSigner: false, isWritable: false }, + ]; + + const result = invokeAccountsLayout(accounts); + expect(result).toEqual(expected); + }); + + it('should return correct AccountMeta array with non-null solPoolPda', () => { + const accounts = { + feePayer, + authority, + registeredProgramPda, + noopProgram, + accountCompressionAuthority, + accountCompressionProgram, + solPoolPda, + decompressionRecipient, + systemProgram, + }; + + const expected = [ + { pubkey: feePayer, isSigner: true, isWritable: true }, + { pubkey: authority, isSigner: true, isWritable: false }, + { + pubkey: registeredProgramPda, isSigner: false, isWritable: false, }, + { pubkey: noopProgram, isSigner: false, isWritable: false }, { - pubkey: accounts.solPoolPda ?? LightSystemProgram.programId, + pubkey: accountCompressionAuthority, isSigner: false, isWritable: false, }, { - pubkey: - accounts.decompressionRecipient ?? - LightSystemProgram.programId, + pubkey: accountCompressionProgram, + isSigner: false, + isWritable: false, + }, + { pubkey: solPoolPda, isSigner: false, isWritable: true }, + { + pubkey: decompressionRecipient, isSigner: false, isWritable: true, }, + { pubkey: systemProgram, isSigner: false, isWritable: false }, + ]; + + const result = invokeAccountsLayout(accounts); + expect(result).toEqual(expected); + }); + + it('should return correct AccountMeta array with null decompressionRecipient', () => { + const accounts = { + feePayer, + authority, + registeredProgramPda, + noopProgram, + accountCompressionAuthority, + accountCompressionProgram, + solPoolPda, + decompressionRecipient: null, + systemProgram, + }; + + const expected = [ + { pubkey: feePayer, isSigner: true, isWritable: true }, + { pubkey: authority, isSigner: true, isWritable: false }, + { + pubkey: registeredProgramPda, + isSigner: false, + isWritable: false, + }, + { pubkey: noopProgram, isSigner: false, isWritable: false }, { - pubkey: accounts.systemProgram, + pubkey: accountCompressionAuthority, isSigner: false, isWritable: false, }, + { + pubkey: accountCompressionProgram, + isSigner: false, + isWritable: false, + }, + { pubkey: solPoolPda, isSigner: false, isWritable: true }, + { + pubkey: LightSystemProgram.programId, + isSigner: false, + isWritable: true, + }, + { pubkey: systemProgram, isSigner: false, isWritable: false }, ]; const result = invokeAccountsLayout(accounts);