├── .eslintrc.json ├── anchor ├── tsconfig.json ├── programs │ └── devotion │ │ ├── Xargo.toml │ │ ├── Cargo.toml │ │ └── src │ │ └── lib.rs ├── .prettierignore ├── src │ ├── index.ts │ └── devotion-exports.ts ├── .gitignore ├── Cargo.toml ├── migrations │ └── deploy.ts ├── Anchor.toml ├── tests │ └── devotion.spec.ts ├── target │ ├── idl │ │ └── devotion.json │ └── types │ │ └── devotion.ts └── Cargo.lock ├── public └── logo.png ├── src ├── app │ ├── favicon.ico │ ├── api │ │ └── hello │ │ │ └── route.ts │ ├── clusters │ │ └── page.tsx │ ├── page.tsx │ ├── devotion │ │ └── page.tsx │ ├── account │ │ ├── page.tsx │ │ └── [address] │ │ │ └── page.tsx │ ├── globals.css │ ├── react-query-provider.tsx │ └── layout.tsx └── components │ ├── account │ ├── account-list-feature.tsx │ ├── account-detail-feature.tsx │ ├── account-data-access.tsx │ └── account-ui.tsx │ ├── cluster │ ├── cluster-feature.tsx │ ├── cluster-data-access.tsx │ └── cluster-ui.tsx │ ├── dashboard │ └── dashboard-feature.tsx │ ├── devotion │ ├── devotion-feature.tsx │ ├── devotion-data-access.tsx │ └── devotion-ui.tsx │ ├── solana │ └── solana-provider.tsx │ └── ui │ └── ui-layout.tsx ├── next.config.mjs ├── postcss.config.mjs ├── tailwind.config.ts ├── .gitignore ├── .github └── workflows │ ├── test-web.yml │ └── test-anchor.yml ├── tsconfig.json ├── LICENSE ├── package.json └── README.md /.eslintrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "next/core-web-vitals" 3 | } 4 | -------------------------------------------------------------------------------- /anchor/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../tsconfig.json" 3 | } 4 | -------------------------------------------------------------------------------- /public/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Gods-fun/Devotion/HEAD/public/logo.png -------------------------------------------------------------------------------- /src/app/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Gods-fun/Devotion/HEAD/src/app/favicon.ico -------------------------------------------------------------------------------- /anchor/programs/devotion/Xargo.toml: -------------------------------------------------------------------------------- 1 | [target.bpfel-unknown-unknown.dependencies.std] 2 | features = [] 3 | -------------------------------------------------------------------------------- /anchor/.prettierignore: -------------------------------------------------------------------------------- 1 | .anchor 2 | .DS_Store 3 | target 4 | node_modules 5 | dist 6 | build 7 | test-ledger 8 | -------------------------------------------------------------------------------- /next.config.mjs: -------------------------------------------------------------------------------- 1 | /** @type {import('next').NextConfig} */ 2 | const nextConfig = {}; 3 | 4 | export default nextConfig; 5 | -------------------------------------------------------------------------------- /src/app/api/hello/route.ts: -------------------------------------------------------------------------------- 1 | export async function GET(request: Request) { 2 | return new Response('Hello, from API!') 3 | } 4 | -------------------------------------------------------------------------------- /anchor/src/index.ts: -------------------------------------------------------------------------------- 1 | // This file was generated by preset-anchor. Programs are exported from this file. 2 | 3 | export * from './devotion-exports' 4 | -------------------------------------------------------------------------------- /src/app/clusters/page.tsx: -------------------------------------------------------------------------------- 1 | import ClusterFeature from '@/components/cluster/cluster-feature' 2 | 3 | export default function Page() { 4 | return 5 | } 6 | -------------------------------------------------------------------------------- /src/app/page.tsx: -------------------------------------------------------------------------------- 1 | import DashboardFeature from '@/components/dashboard/dashboard-feature' 2 | 3 | export default function Page() { 4 | return 5 | } 6 | -------------------------------------------------------------------------------- /src/app/devotion/page.tsx: -------------------------------------------------------------------------------- 1 | import DevotionFeature from '@/components/devotion/devotion-feature' 2 | 3 | export default function Page() { 4 | return 5 | } 6 | -------------------------------------------------------------------------------- /postcss.config.mjs: -------------------------------------------------------------------------------- 1 | /** @type {import('postcss-load-config').Config} */ 2 | const config = { 3 | plugins: { 4 | tailwindcss: {}, 5 | }, 6 | }; 7 | 8 | export default config; 9 | -------------------------------------------------------------------------------- /src/app/account/page.tsx: -------------------------------------------------------------------------------- 1 | import AccountListFeature from '@/components/account/account-list-feature' 2 | 3 | export default function Page() { 4 | return 5 | } 6 | -------------------------------------------------------------------------------- /src/app/account/[address]/page.tsx: -------------------------------------------------------------------------------- 1 | import AccountDetailFeature from '@/components/account/account-detail-feature' 2 | 3 | export default function Page() { 4 | return 5 | } 6 | -------------------------------------------------------------------------------- /anchor/.gitignore: -------------------------------------------------------------------------------- 1 | .anchor 2 | .DS_Store 3 | target/debug 4 | target/deploy 5 | target/release 6 | target/sbf-solana-solana 7 | target/test-ledger 8 | target/.rustc_info.json 9 | **/*.rs.bk 10 | node_modules 11 | test-ledger 12 | .yarn 13 | -------------------------------------------------------------------------------- /anchor/Cargo.toml: -------------------------------------------------------------------------------- 1 | [workspace] 2 | members = [ 3 | "programs/*" 4 | ] 5 | resolver = "2" 6 | 7 | [profile.release] 8 | overflow-checks = true 9 | lto = "fat" 10 | codegen-units = 1 11 | [profile.release.build-override] 12 | opt-level = 3 13 | incremental = false 14 | codegen-units = 1 15 | -------------------------------------------------------------------------------- /tailwind.config.ts: -------------------------------------------------------------------------------- 1 | import type {Config} from "tailwindcss"; 2 | 3 | const config: Config = { 4 | content: [ 5 | "./src/pages/**/*.{js,ts,jsx,tsx,mdx}", 6 | "./src/components/**/*.{js,ts,jsx,tsx,mdx}", 7 | "./src/app/**/*.{js,ts,jsx,tsx,mdx}", 8 | ], 9 | theme: { 10 | extend: {}, 11 | }, 12 | plugins: [require('daisyui')], 13 | }; 14 | export default config; 15 | -------------------------------------------------------------------------------- /src/app/globals.css: -------------------------------------------------------------------------------- 1 | @tailwind base; 2 | @tailwind components; 3 | @tailwind utilities; 4 | 5 | html, 6 | body { 7 | height: 100%; 8 | } 9 | 10 | .wallet-adapter-button-trigger { 11 | background: rgb(100, 26, 230) !important; 12 | border-radius: 8px !important; 13 | padding-left: 16px !important; 14 | padding-right: 16px !important; 15 | } 16 | .wallet-adapter-dropdown-list, 17 | .wallet-adapter-button { 18 | font-family: inherit !important; 19 | } 20 | -------------------------------------------------------------------------------- /anchor/migrations/deploy.ts: -------------------------------------------------------------------------------- 1 | // Migrations are an early feature. Currently, they're nothing more than this 2 | // single deploy script that's invoked from the CLI, injecting a provider 3 | // configured from the workspace's Anchor.toml. 4 | 5 | const anchor = require("@coral-xyz/anchor"); 6 | import { AnchorProvider } from '@coral-xyz/anchor' 7 | 8 | module.exports = async function (provider: AnchorProvider) { 9 | // Configure client to use the provider. 10 | anchor.setProvider(provider); 11 | 12 | // Add your deploy script here. 13 | }; 14 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files. 2 | 3 | # dependencies 4 | /node_modules 5 | /.pnp 6 | .pnp.js 7 | .yarn/install-state.gz 8 | 9 | # testing 10 | /coverage 11 | 12 | # next.js 13 | /.next/ 14 | /out/ 15 | 16 | # production 17 | /build 18 | 19 | # misc 20 | .DS_Store 21 | *.pem 22 | 23 | # debug 24 | npm-debug.log* 25 | yarn-debug.log* 26 | yarn-error.log* 27 | 28 | # local env files 29 | .env*.local 30 | 31 | # vercel 32 | .vercel 33 | 34 | # typescript 35 | *.tsbuildinfo 36 | next-env.d.ts 37 | tmp 38 | -------------------------------------------------------------------------------- /anchor/programs/devotion/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "devotion" 3 | version = "0.1.0" 4 | description = "Created with Anchor" 5 | edition = "2021" 6 | 7 | [lib] 8 | crate-type = ["cdylib", "lib"] 9 | name = "devotion" 10 | 11 | [features] 12 | default = [] 13 | cpi = ["no-entrypoint"] 14 | no-entrypoint = [] 15 | no-idl = [] 16 | no-log-ix-name = [] 17 | idl-build = [ 18 | "anchor-lang/idl-build", 19 | "anchor-spl/idl-build", 20 | ] 21 | 22 | [dependencies] 23 | anchor-lang = { version = "0.30.1", features = ["init-if-needed"] } 24 | anchor-spl = "0.30.1" 25 | -------------------------------------------------------------------------------- /src/app/react-query-provider.tsx: -------------------------------------------------------------------------------- 1 | 'use client' 2 | 3 | import React, { ReactNode, useState } from 'react' 4 | import { ReactQueryStreamedHydration } from '@tanstack/react-query-next-experimental' 5 | import { QueryClientProvider, QueryClient } from '@tanstack/react-query' 6 | 7 | export function ReactQueryProvider({ children }: { children: ReactNode }) { 8 | const [client] = useState(new QueryClient()) 9 | 10 | return ( 11 | 12 | {children} 13 | 14 | ) 15 | } 16 | -------------------------------------------------------------------------------- /src/components/account/account-list-feature.tsx: -------------------------------------------------------------------------------- 1 | 'use client' 2 | 3 | import { useWallet } from '@solana/wallet-adapter-react' 4 | 5 | import { redirect } from 'next/navigation' 6 | import { WalletButton } from '../solana/solana-provider' 7 | 8 | export default function AccountListFeature() { 9 | const { publicKey } = useWallet() 10 | 11 | if (publicKey) { 12 | return redirect(`/account/${publicKey.toString()}`) 13 | } 14 | 15 | return ( 16 |
17 |
18 | 19 |
20 |
21 | ) 22 | } 23 | -------------------------------------------------------------------------------- /anchor/Anchor.toml: -------------------------------------------------------------------------------- 1 | [toolchain] 2 | anchor_version = "0.30.1" 3 | 4 | [features] 5 | resolution = true 6 | skip-lint = false 7 | 8 | [programs.localnet] 9 | devotion = "GodsAfuZbVYY79KADVMe39ZwybWuL5U6RFLvyzUD5qgw" 10 | 11 | [registry] 12 | url = "https://api.apr.dev" 13 | 14 | [provider] 15 | cluster = "Localnet" 16 | wallet = "~/.config/solana/id.json" 17 | 18 | [scripts] 19 | test = "../node_modules/.bin/jest --preset ts-jest" 20 | 21 | [test] 22 | startup_wait = 5000 23 | shutdown_wait = 2000 24 | upgradeable = false 25 | 26 | [test.validator] 27 | bind_address = "127.0.0.1" 28 | ledger = ".anchor/test-ledger" 29 | rpc_port = 8899 30 | -------------------------------------------------------------------------------- /.github/workflows/test-web.yml: -------------------------------------------------------------------------------- 1 | name: Test and Build Web 2 | 3 | on: 4 | pull_request: 5 | push: 6 | branches: ['main'] 7 | 8 | jobs: 9 | test-and-build: 10 | runs-on: ubuntu-latest 11 | 12 | steps: 13 | - name: Checkout 14 | uses: actions/checkout@v4 15 | 16 | - name: Install pnpm 17 | uses: pnpm/action-setup@v4 18 | with: 19 | run_install: false 20 | 21 | - name: Install Node.js 22 | uses: actions/setup-node@v4 23 | with: 24 | node-version: 20 25 | cache: 'pnpm' 26 | 27 | - name: Install dependencies 28 | run: pnpm install --frozen-lockfile 29 | 30 | - name: Build project 31 | run: pnpm build 32 | -------------------------------------------------------------------------------- /src/components/cluster/cluster-feature.tsx: -------------------------------------------------------------------------------- 1 | 'use client' 2 | 3 | import { useState } from 'react' 4 | import { AppHero } from '../ui/ui-layout' 5 | import { ClusterUiModal } from './cluster-ui' 6 | import { ClusterUiTable } from './cluster-ui' 7 | 8 | export default function ClusterFeature() { 9 | const [showModal, setShowModal] = useState(false) 10 | 11 | return ( 12 |
13 | 14 | setShowModal(false)} /> 15 | 18 | 19 | 20 |
21 | ) 22 | } 23 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "lib": ["dom", "dom.iterable", "esnext"], 4 | "types": ["jest", "node"], 5 | "allowJs": true, 6 | "skipLibCheck": true, 7 | "strict": true, 8 | "noEmit": true, 9 | "esModuleInterop": true, 10 | "module": "esnext", 11 | "moduleResolution": "bundler", 12 | "resolveJsonModule": true, 13 | "allowSyntheticDefaultImports": true, 14 | "isolatedModules": true, 15 | "jsx": "preserve", 16 | "incremental": true, 17 | "plugins": [ 18 | { 19 | "name": "next" 20 | } 21 | ], 22 | "baseUrl": ".", 23 | "paths": { 24 | "@project/anchor": ["anchor/src"], 25 | "@/*": ["./src/*"] 26 | } 27 | }, 28 | "include": ["next-env.d.ts", "**/*.ts", "**/*.spec.ts", "**/*.tsx", ".next/types/**/*.ts"], 29 | "exclude": ["node_modules"] 30 | } 31 | -------------------------------------------------------------------------------- /src/app/layout.tsx: -------------------------------------------------------------------------------- 1 | import './globals.css' 2 | import {ClusterProvider} from '@/components/cluster/cluster-data-access' 3 | import {SolanaProvider} from '@/components/solana/solana-provider' 4 | import {UiLayout} from '@/components/ui/ui-layout' 5 | import {ReactQueryProvider} from './react-query-provider' 6 | 7 | export const metadata = { 8 | title: 'devotion', 9 | description: 'Generated by create-solana-dapp', 10 | } 11 | 12 | const links: { label: string; path: string }[] = [ 13 | { label: 'Account', path: '/account' }, 14 | { label: 'Clusters', path: '/clusters' }, 15 | { label: 'Devotion Program', path: '/devotion' }, 16 | ] 17 | 18 | export default function RootLayout({ children }: { children: React.ReactNode }) { 19 | return ( 20 | 21 | 22 | 23 | 24 | 25 | {children} 26 | 27 | 28 | 29 | 30 | 31 | ) 32 | } 33 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2022-2024 Solana Foundation 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /src/components/dashboard/dashboard-feature.tsx: -------------------------------------------------------------------------------- 1 | 'use client' 2 | 3 | import { AppHero } from '../ui/ui-layout' 4 | 5 | const links: { label: string; href: string }[] = [ 6 | { label: 'Solana Docs', href: 'https://docs.solana.com/' }, 7 | { label: 'Solana Faucet', href: 'https://faucet.solana.com/' }, 8 | { label: 'Solana Cookbook', href: 'https://solanacookbook.com/' }, 9 | { label: 'Solana Stack Overflow', href: 'https://solana.stackexchange.com/' }, 10 | { label: 'Solana Developers GitHub', href: 'https://github.com/solana-developers/' }, 11 | ] 12 | 13 | export default function DashboardFeature() { 14 | return ( 15 |
16 | 17 |
18 |
19 |

Here are some helpful links to get you started.

20 | {links.map((link, index) => ( 21 | 26 | ))} 27 |
28 |
29 |
30 | ) 31 | } 32 | -------------------------------------------------------------------------------- /.github/workflows/test-anchor.yml: -------------------------------------------------------------------------------- 1 | name: Test and Build Anchor 2 | 3 | on: 4 | pull_request: 5 | push: 6 | branches: ['main'] 7 | 8 | jobs: 9 | test-and-build: 10 | runs-on: ubuntu-latest 11 | 12 | steps: 13 | - name: Checkout 14 | uses: actions/checkout@v4 15 | 16 | - name: Install pnpm 17 | uses: pnpm/action-setup@v4 18 | with: 19 | run_install: false 20 | 21 | - name: Install Node.js 22 | uses: actions/setup-node@v4 23 | with: 24 | node-version: 20 25 | cache: 'pnpm' 26 | 27 | - name: Install dependencies 28 | run: pnpm install --frozen-lockfile 29 | 30 | - uses: metadaoproject/setup-anchor@v2 31 | with: 32 | anchor-version: '0.30.1' 33 | node-version: '20' 34 | solana-cli-version: '1.18.9' 35 | 36 | - name: Generate new keypair 37 | run: solana-keygen new --no-bip39-passphrase 38 | 39 | - name: Set solana target cluster to local 40 | run: solana config set --url http://localhost:8899 41 | 42 | - name: Check solana config 43 | run: solana config get 44 | 45 | - run: pnpm run anchor build 46 | shell: bash 47 | 48 | - run: pnpm run anchor test 49 | shell: bash 50 | -------------------------------------------------------------------------------- /anchor/src/devotion-exports.ts: -------------------------------------------------------------------------------- 1 | // Here we export some useful types and functions for interacting with the Anchor program. 2 | import { AnchorProvider, Program } from '@coral-xyz/anchor' 3 | import { Cluster, PublicKey } from '@solana/web3.js' 4 | import DevotionIDL from '../target/idl/devotion.json' 5 | import type { Devotion } from '../target/types/devotion' 6 | 7 | // Re-export the generated IDL and type 8 | export { Devotion, DevotionIDL } 9 | 10 | // The programId is imported from the program IDL. 11 | export const DEVOTION_PROGRAM_ID = new PublicKey(DevotionIDL.address) 12 | 13 | // This is a helper function to get the Devotion Anchor program. 14 | export function getDevotionProgram(provider: AnchorProvider, address?: PublicKey) { 15 | return new Program({ ...DevotionIDL, address: address ? address.toBase58() : DevotionIDL.address } as Devotion, provider) 16 | } 17 | 18 | // This is a helper function to get the program ID for the Devotion program depending on the cluster. 19 | export function getDevotionProgramId(cluster: Cluster) { 20 | switch (cluster) { 21 | case 'devnet': 22 | case 'testnet': 23 | // This is the program ID for the Devotion program on devnet and testnet. 24 | return new PublicKey('GodsAfuZbVYY79KADVMe39ZwybWuL5U6RFLvyzUD5qgw') 25 | case 'mainnet-beta': 26 | default: 27 | return DEVOTION_PROGRAM_ID 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /src/components/devotion/devotion-feature.tsx: -------------------------------------------------------------------------------- 1 | 'use client' 2 | 3 | import { useWallet } from '@solana/wallet-adapter-react' 4 | import { WalletButton } from '../solana/solana-provider' 5 | import { AppHero, ellipsify } from '../ui/ui-layout' 6 | import { ExplorerLink } from '../cluster/cluster-ui' 7 | import { useDevotionProgram } from './devotion-data-access' 8 | import { DevotionCreate, DevotionList } from './devotion-ui' 9 | 10 | export default function DevotionFeature() { 11 | const { publicKey } = useWallet() 12 | const { programId } = useDevotionProgram() 13 | 14 | return publicKey ? ( 15 |
16 | 22 |

23 | 24 |

25 | 26 |
27 | 28 |
29 | ) : ( 30 |
31 |
32 |
33 | 34 |
35 |
36 |
37 | ) 38 | } 39 | -------------------------------------------------------------------------------- /src/components/account/account-detail-feature.tsx: -------------------------------------------------------------------------------- 1 | 'use client' 2 | 3 | import { PublicKey } from '@solana/web3.js' 4 | import { useMemo } from 'react' 5 | 6 | import { useParams } from 'next/navigation' 7 | 8 | import { ExplorerLink } from '../cluster/cluster-ui' 9 | import { AppHero, ellipsify } from '../ui/ui-layout' 10 | import { AccountBalance, AccountButtons, AccountTokens, AccountTransactions } from './account-ui' 11 | 12 | export default function AccountDetailFeature() { 13 | const params = useParams() 14 | const address = useMemo(() => { 15 | if (!params.address) { 16 | return 17 | } 18 | try { 19 | return new PublicKey(params.address) 20 | } catch (e) { 21 | console.log(`Invalid public key`, e) 22 | } 23 | }, [params]) 24 | if (!address) { 25 | return
Error loading account
26 | } 27 | 28 | return ( 29 |
30 | } 32 | subtitle={ 33 |
34 | 35 |
36 | } 37 | > 38 |
39 | 40 |
41 |
42 |
43 | 44 | 45 |
46 |
47 | ) 48 | } 49 | -------------------------------------------------------------------------------- /src/components/solana/solana-provider.tsx: -------------------------------------------------------------------------------- 1 | 'use client' 2 | 3 | import dynamic from 'next/dynamic' 4 | import { AnchorProvider } from '@coral-xyz/anchor' 5 | import { WalletError } from '@solana/wallet-adapter-base' 6 | import { 7 | AnchorWallet, 8 | useConnection, 9 | useWallet, 10 | ConnectionProvider, 11 | WalletProvider, 12 | } from '@solana/wallet-adapter-react' 13 | import { WalletModalProvider } from '@solana/wallet-adapter-react-ui' 14 | import { ReactNode, useCallback, useMemo } from 'react' 15 | import { useCluster } from '../cluster/cluster-data-access' 16 | 17 | require('@solana/wallet-adapter-react-ui/styles.css') 18 | 19 | export const WalletButton = dynamic(async () => (await import('@solana/wallet-adapter-react-ui')).WalletMultiButton, { 20 | ssr: false, 21 | }) 22 | 23 | export function SolanaProvider({ children }: { children: ReactNode }) { 24 | const { cluster } = useCluster() 25 | const endpoint = useMemo(() => cluster.endpoint, [cluster]) 26 | const onError = useCallback((error: WalletError) => { 27 | console.error(error) 28 | }, []) 29 | 30 | return ( 31 | 32 | 33 | {children} 34 | 35 | 36 | ) 37 | } 38 | 39 | export function useAnchorProvider() { 40 | const { connection } = useConnection() 41 | const wallet = useWallet() 42 | 43 | return new AnchorProvider(connection, wallet as AnchorWallet, { commitment: 'confirmed' }) 44 | } 45 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "template-next-tailwind-counter", 3 | "version": "0.1.0", 4 | "private": true, 5 | "scripts": { 6 | "anchor": "cd anchor && anchor", 7 | "anchor-build": "cd anchor && anchor build", 8 | "anchor-localnet": "cd anchor && anchor localnet", 9 | "anchor-test": "cd anchor && anchor test", 10 | "dev": "next dev", 11 | "build": "next build", 12 | "start": "next start", 13 | "lint": "next lint" 14 | }, 15 | "dependencies": { 16 | "@coral-xyz/anchor": "^0.30.1", 17 | "@solana/spl-token": "^0.4.8", 18 | "@solana/wallet-adapter-base": "^0.9.23", 19 | "@solana/wallet-adapter-react": "^0.15.35", 20 | "@solana/wallet-adapter-react-ui": "^0.9.35", 21 | "@solana/web3.js": "^1.95.1", 22 | "@tabler/icons-react": "^3.11.0", 23 | "@tanstack/react-query": "^5.51.11", 24 | "@tanstack/react-query-next-experimental": "^5.51.11", 25 | "daisyui": "^4.12.10", 26 | "jotai": "^2.9.1", 27 | "next": "14.2.5", 28 | "react": "^18", 29 | "react-dom": "^18", 30 | "react-hot-toast": "^2.4.1" 31 | }, 32 | "devDependencies": { 33 | "@types/bn.js": "^5.1.0", 34 | "@types/jest": "^29.0.3", 35 | "@types/node": "^20", 36 | "@types/react": "^18", 37 | "@types/react-dom": "^18", 38 | "eslint": "^8", 39 | "eslint-config-next": "14.2.5", 40 | "jest": "^29.0.3", 41 | "postcss": "^8", 42 | "tailwindcss": "^3.4.1", 43 | "ts-jest": "^29.0.2", 44 | "typescript": "^5" 45 | }, 46 | "packageManager": "pnpm@9.7.0+sha512.dc09430156b427f5ecfc79888899e1c39d2d690f004be70e05230b72cb173d96839587545d09429b55ac3c429c801b4dc3c0e002f653830a420fa2dd4e3cf9cf" 47 | } -------------------------------------------------------------------------------- /anchor/tests/devotion.spec.ts: -------------------------------------------------------------------------------- 1 | import * as anchor from '@coral-xyz/anchor' 2 | import {Program} from '@coral-xyz/anchor' 3 | import {Keypair} from '@solana/web3.js' 4 | import {Devotion} from '../target/types/devotion' 5 | 6 | describe('devotion', () => { 7 | // Configure the client to use the local cluster. 8 | const provider = anchor.AnchorProvider.env() 9 | anchor.setProvider(provider) 10 | const payer = provider.wallet as anchor.Wallet 11 | 12 | const program = anchor.workspace.Devotion as Program 13 | 14 | const devotionKeypair = Keypair.generate() 15 | 16 | it('Initialize Devotion', async () => { 17 | await program.methods 18 | .initialize() 19 | .accounts({ 20 | devotion: devotionKeypair.publicKey, 21 | payer: payer.publicKey, 22 | }) 23 | .signers([devotionKeypair]) 24 | .rpc() 25 | 26 | const currentCount = await program.account.devotion.fetch(devotionKeypair.publicKey) 27 | 28 | expect(currentCount.count).toEqual(0) 29 | }) 30 | 31 | it('Increment Devotion', async () => { 32 | await program.methods.increment().accounts({ devotion: devotionKeypair.publicKey }).rpc() 33 | 34 | const currentCount = await program.account.devotion.fetch(devotionKeypair.publicKey) 35 | 36 | expect(currentCount.count).toEqual(1) 37 | }) 38 | 39 | it('Increment Devotion Again', async () => { 40 | await program.methods.increment().accounts({ devotion: devotionKeypair.publicKey }).rpc() 41 | 42 | const currentCount = await program.account.devotion.fetch(devotionKeypair.publicKey) 43 | 44 | expect(currentCount.count).toEqual(2) 45 | }) 46 | 47 | it('Decrement Devotion', async () => { 48 | await program.methods.decrement().accounts({ devotion: devotionKeypair.publicKey }).rpc() 49 | 50 | const currentCount = await program.account.devotion.fetch(devotionKeypair.publicKey) 51 | 52 | expect(currentCount.count).toEqual(1) 53 | }) 54 | 55 | it('Set devotion value', async () => { 56 | await program.methods.set(42).accounts({ devotion: devotionKeypair.publicKey }).rpc() 57 | 58 | const currentCount = await program.account.devotion.fetch(devotionKeypair.publicKey) 59 | 60 | expect(currentCount.count).toEqual(42) 61 | }) 62 | 63 | it('Set close the devotion account', async () => { 64 | await program.methods 65 | .close() 66 | .accounts({ 67 | payer: payer.publicKey, 68 | devotion: devotionKeypair.publicKey, 69 | }) 70 | .rpc() 71 | 72 | // The account should no longer exist, returning null. 73 | const userAccount = await program.account.devotion.fetchNullable(devotionKeypair.publicKey) 74 | expect(userAccount).toBeNull() 75 | }) 76 | }) 77 | -------------------------------------------------------------------------------- /src/components/cluster/cluster-data-access.tsx: -------------------------------------------------------------------------------- 1 | 'use client' 2 | 3 | import { clusterApiUrl, Connection } from '@solana/web3.js' 4 | import { atom, useAtomValue, useSetAtom } from 'jotai' 5 | import { atomWithStorage } from 'jotai/utils' 6 | import { createContext, ReactNode, useContext } from 'react' 7 | import toast from 'react-hot-toast' 8 | 9 | export interface Cluster { 10 | name: string 11 | endpoint: string 12 | network?: ClusterNetwork 13 | active?: boolean 14 | } 15 | 16 | export enum ClusterNetwork { 17 | Mainnet = 'mainnet-beta', 18 | Testnet = 'testnet', 19 | Devnet = 'devnet', 20 | Custom = 'custom', 21 | } 22 | 23 | // By default, we don't configure the mainnet-beta cluster 24 | // The endpoint provided by clusterApiUrl('mainnet-beta') does not allow access from the browser due to CORS restrictions 25 | // To use the mainnet-beta cluster, provide a custom endpoint 26 | export const defaultClusters: Cluster[] = [ 27 | { 28 | name: 'devnet', 29 | endpoint: clusterApiUrl('devnet'), 30 | network: ClusterNetwork.Devnet, 31 | }, 32 | { name: 'local', endpoint: 'http://localhost:8899' }, 33 | { 34 | name: 'testnet', 35 | endpoint: clusterApiUrl('testnet'), 36 | network: ClusterNetwork.Testnet, 37 | }, 38 | ] 39 | 40 | const clusterAtom = atomWithStorage('solana-cluster', defaultClusters[0]) 41 | const clustersAtom = atomWithStorage('solana-clusters', defaultClusters) 42 | 43 | const activeClustersAtom = atom((get) => { 44 | const clusters = get(clustersAtom) 45 | const cluster = get(clusterAtom) 46 | return clusters.map((item) => ({ 47 | ...item, 48 | active: item.name === cluster.name, 49 | })) 50 | }) 51 | 52 | const activeClusterAtom = atom((get) => { 53 | const clusters = get(activeClustersAtom) 54 | 55 | return clusters.find((item) => item.active) || clusters[0] 56 | }) 57 | 58 | export interface ClusterProviderContext { 59 | cluster: Cluster 60 | clusters: Cluster[] 61 | addCluster: (cluster: Cluster) => void 62 | deleteCluster: (cluster: Cluster) => void 63 | setCluster: (cluster: Cluster) => void 64 | getExplorerUrl(path: string): string 65 | } 66 | 67 | const Context = createContext({} as ClusterProviderContext) 68 | 69 | export function ClusterProvider({ children }: { children: ReactNode }) { 70 | const cluster = useAtomValue(activeClusterAtom) 71 | const clusters = useAtomValue(activeClustersAtom) 72 | const setCluster = useSetAtom(clusterAtom) 73 | const setClusters = useSetAtom(clustersAtom) 74 | 75 | const value: ClusterProviderContext = { 76 | cluster, 77 | clusters: clusters.sort((a, b) => (a.name > b.name ? 1 : -1)), 78 | addCluster: (cluster: Cluster) => { 79 | try { 80 | new Connection(cluster.endpoint) 81 | setClusters([...clusters, cluster]) 82 | } catch (err) { 83 | toast.error(`${err}`) 84 | } 85 | }, 86 | deleteCluster: (cluster: Cluster) => { 87 | setClusters(clusters.filter((item) => item.name !== cluster.name)) 88 | }, 89 | setCluster: (cluster: Cluster) => setCluster(cluster), 90 | getExplorerUrl: (path: string) => `https://explorer.solana.com/${path}${getClusterUrlParam(cluster)}`, 91 | } 92 | return {children} 93 | } 94 | 95 | export function useCluster() { 96 | return useContext(Context) 97 | } 98 | 99 | function getClusterUrlParam(cluster: Cluster): string { 100 | let suffix = '' 101 | switch (cluster.network) { 102 | case ClusterNetwork.Devnet: 103 | suffix = 'devnet' 104 | break 105 | case ClusterNetwork.Mainnet: 106 | suffix = '' 107 | break 108 | case ClusterNetwork.Testnet: 109 | suffix = 'testnet' 110 | break 111 | default: 112 | suffix = `custom&customUrl=${encodeURIComponent(cluster.endpoint)}` 113 | break 114 | } 115 | 116 | return suffix.length ? `?cluster=${suffix}` : '' 117 | } 118 | -------------------------------------------------------------------------------- /src/components/ui/ui-layout.tsx: -------------------------------------------------------------------------------- 1 | 'use client' 2 | 3 | import Link from 'next/link' 4 | import {usePathname} from 'next/navigation' 5 | import * as React from 'react' 6 | import {ReactNode, Suspense, useEffect, useRef} from 'react' 7 | import toast, {Toaster} from 'react-hot-toast' 8 | 9 | import {AccountChecker} from '../account/account-ui' 10 | import {ClusterChecker, ClusterUiSelect, ExplorerLink} from '../cluster/cluster-ui' 11 | import {WalletButton} from '../solana/solana-provider' 12 | 13 | export function UiLayout({ children, links }: { children: ReactNode; links: { label: string; path: string }[] }) { 14 | const pathname = usePathname() 15 | 16 | return ( 17 |
18 |
19 |
20 | 21 | Logo 22 | 23 |
    24 | {links.map(({ label, path }) => ( 25 |
  • 26 | 27 | {label} 28 | 29 |
  • 30 | ))} 31 |
32 |
33 |
34 | 35 | 36 |
37 |
38 | 39 | 40 | 41 |
42 | 45 | 46 |
47 | } 48 | > 49 | {children} 50 | 51 | 52 |
53 | 68 | 69 | ) 70 | } 71 | 72 | export function AppModal({ 73 | children, 74 | title, 75 | hide, 76 | show, 77 | submit, 78 | submitDisabled, 79 | submitLabel, 80 | }: { 81 | children: ReactNode 82 | title: string 83 | hide: () => void 84 | show: boolean 85 | submit?: () => void 86 | submitDisabled?: boolean 87 | submitLabel?: string 88 | }) { 89 | const dialogRef = useRef(null) 90 | 91 | useEffect(() => { 92 | if (!dialogRef.current) return 93 | if (show) { 94 | dialogRef.current.showModal() 95 | } else { 96 | dialogRef.current.close() 97 | } 98 | }, [show, dialogRef]) 99 | 100 | return ( 101 | 102 |
103 |

{title}

104 | {children} 105 |
106 |
107 | {submit ? ( 108 | 111 | ) : null} 112 | 115 |
116 |
117 |
118 |
119 | ) 120 | } 121 | 122 | export function AppHero({ 123 | children, 124 | title, 125 | subtitle, 126 | }: { 127 | children?: ReactNode 128 | title: ReactNode 129 | subtitle: ReactNode 130 | }) { 131 | return ( 132 |
133 |
134 |
135 | {typeof title === 'string' ?

{title}

: title} 136 | {typeof subtitle === 'string' ?

{subtitle}

: subtitle} 137 | {children} 138 |
139 |
140 |
141 | ) 142 | } 143 | 144 | export function ellipsify(str = '', len = 4) { 145 | if (str.length > 30) { 146 | return str.substring(0, len) + '..' + str.substring(str.length - len, str.length) 147 | } 148 | return str 149 | } 150 | 151 | export function useTransactionToast() { 152 | return (signature: string) => { 153 | toast.success( 154 |
155 |
Transaction sent
156 | 157 |
, 158 | ) 159 | } 160 | } 161 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | When you use the devotion program and dapp [please tag us in your launch announcement.](https://x.com/godsdotfun) 2 | 3 | Join the [Gods Telegram channel!](http://gods.fun) 4 | 5 | Join [ai16z Discord!](https://discord.gg/478N45NWQ6) 6 | 7 | ![lina_devotion1](https://github.com/user-attachments/assets/65315cbc-99a1-4f40-9f6b-9effa94768ae) 8 | 9 | --- 10 | 11 | # ⚠️ Disclaimer 12 | 13 | **This program has not been audited.** 14 | 15 | Use this software at your own risk. It may contain bugs, vulnerabilities, or unintended behaviors. **Loss of funds is possible.** 16 | 17 | The maintainers of this repository are not responsible for any losses, damages, or other consequences arising from the use of this program. 18 | 19 | --- 20 | 21 | ## Setup 22 | 23 | - Clone the repo `git clone https://github.com/Gods-fun/Devotion.git` 24 | - [Here are instructions for setting up your environment with Solana CLI tools.](https://solana.com/docs/intro/installation) You will need to install Rust, Solana and Anchor. 25 | - [If you don't have Node and NPM you will need to install those as well.](https://nodejs.org/en/download) 26 | - Install your dependencies from the root directory `./devotion` `npm install` 27 | 28 | ## Keys 29 | 30 | You will have two keypairs for this: 31 | 32 | 1. Your deployer address key. 33 | 2. A special key specifically to deploy and/or upgrade the devotion program. 34 | 35 | - Generate a new keypair for your program: 36 | ``` 37 | # For starts-with pattern: 38 | solana-keygen grind --starts-with 39 | 40 | # For ends-with pattern: 41 | solana-keygen grind --ends-with 42 | 43 | # You can also specify number of threads to speed up the process 44 | solana-keygen grind --starts-with --num-threads 4 45 | ``` 46 | 47 | - Move your new keypair to `.anchor/target/deploy/devotion-keypair.json`: 48 | 49 | ``` 50 | solana-keygen new -o ./anchor/target/deploy/devotion-keypair.json 51 | ``` 52 | 53 | - You can always inspect a keypair.json file: 54 | 55 | ``` 56 | solana-keygen pubkey ./target/deploy/devotion-keypair.json 57 | ``` 58 | 59 | - Check your listed keys: 60 | 61 | ``` 62 | solana address 63 | # or for more details including file paths 64 | solana config get 65 | ``` 66 | 67 | - If you don't have a default key yet: 68 | 69 | ``` 70 | solana-keygen new 71 | ``` 72 | 73 | - Set our provider cluster to devnet: 74 | 75 | ``` 76 | $ solana config set --url https://api.devnet.solana.com 77 | ``` 78 | 79 | - Fund your default key: 80 | ``` 81 | solana airdrop 5 82 | ``` 83 | 84 | ![lina_devotion5](https://github.com/user-attachments/assets/3dd418d8-87c7-4799-83ed-3932fbf2aa6b) 85 | 86 | ## Check and Set Your ProgramId 87 | 88 | - Double triple quadruple check this key: `./anchor/target/deploy/devotion-keypair.json` double check this keypair's public key as it will become your new program's upgrade key and the programId. 89 | 90 | - If you do not generate a fresh key and closely follow the next steps - you will likely have a broken program or app with non-sensical errors. 91 | 92 | - Set this new program keypair's public address as the programId in the `declareId!()` macro at the top of the Devotion Rust program `./anchor/program/devotion/src/lib.rs` 93 | 94 | - Run `anchor keys sync` and then check that the correct programId has been placed in: 95 | - `./anchor/anchor.toml` 96 | - `./anchor/target/idl/devotion.json` 97 | - `./anchor/target/types/devotion.ts` 98 | - **THIS DOESN'T SYNC:** You always manually have to update the programId here. `./anchor/src/devotion-exports.ts` 99 | 100 | - Run `anchor build` from the `./anchor/` folder. 101 | 102 | ## Deploy 103 | 104 | - Now we can deploy our program to devnet or to localnet `anchor deploy --provider.cluster devnet` 105 | 106 | - If all of your programIds were not synced before you deployed your program, your Solana program might be bricked and you are currently ripping your hair out. 107 | 108 | ![lina_devotion3](https://github.com/user-attachments/assets/56f01f21-391e-401d-93c8-dc12b5466f15) 109 | 110 | ## Deploy a Test Token 111 | 112 | - [The Solana SPL-Token docs can be found here.](https://spl.solana.com/token) 113 | 114 | - Deploy a new token for testing `spl-token create-token` 115 | - Create a token account for your wallet for holding the new token: `spl-token create-account ` 116 | - Mint some of the new token to your account: `spl-token mint 1000000` 117 | - Airdrop Solana wallet to a test wallet from a Solana wallet in your browser (my favorite is Phantom wallet): `solana airdrop 5 ` 118 | - Transfer tokens and create an account for your test wallet: `spl-token transfer --fund-recipient 1000000 ` 119 | 120 | 121 | ## Running the Dapp 122 | 123 | - Fire up the Dapp by running `npm run dev` 124 | - Go to a browser and checkout the app on your local host most likely `http://localhost:3000/` 125 | - In the Devotion Program tab you will see the options to initialize your devotion program: 126 | 127 | 1. Input your new test tokens address. 128 | 2. The interval is the length of time in seconds required to charge 1 point of devotion when you have staked 1 token. 129 | 3. The max_devotion_charge is the number of seconds your devotion will accumulate before it is capped. 130 | 131 | ### Functions: 132 | 133 | - `devote` to add tokens and start gaining a devotion score. 134 | - You can devote more tokens at any time. 135 | - `waver` to remove staked tokens but be careful because wavering will reset your devotion to zero - even if you only unstake one token. 136 | - `heresy` to remove all staked tokens and close your account - you will receive a SOL refund from your unused account rent. 137 | 138 | ![lina_devotion4](https://github.com/user-attachments/assets/86b76203-dc63-4f99-824b-fc60fad730f1) 139 | 140 | If you get stuck trying to make this work or you need help please @ me; st4rgard3n in the [ai16z Discord](https://discord.gg/478N45NWQ6) 141 | -------------------------------------------------------------------------------- /src/components/account/account-data-access.tsx: -------------------------------------------------------------------------------- 1 | 'use client' 2 | 3 | import {TOKEN_2022_PROGRAM_ID, TOKEN_PROGRAM_ID} from '@solana/spl-token' 4 | import {useConnection, useWallet} from '@solana/wallet-adapter-react' 5 | import { 6 | Connection, 7 | LAMPORTS_PER_SOL, 8 | PublicKey, 9 | SystemProgram, 10 | TransactionMessage, 11 | TransactionSignature, 12 | VersionedTransaction, 13 | } from '@solana/web3.js' 14 | import {useMutation, useQuery, useQueryClient} from '@tanstack/react-query' 15 | import toast from 'react-hot-toast' 16 | import {useTransactionToast} from '../ui/ui-layout' 17 | 18 | export function useGetBalance({ address }: { address: PublicKey }) { 19 | const { connection } = useConnection() 20 | 21 | return useQuery({ 22 | queryKey: ['get-balance', { endpoint: connection.rpcEndpoint, address }], 23 | queryFn: () => connection.getBalance(address), 24 | }) 25 | } 26 | 27 | export function useGetSignatures({ address }: { address: PublicKey }) { 28 | const { connection } = useConnection() 29 | 30 | return useQuery({ 31 | queryKey: ['get-signatures', { endpoint: connection.rpcEndpoint, address }], 32 | queryFn: () => connection.getSignaturesForAddress(address), 33 | }) 34 | } 35 | 36 | export function useGetTokenAccounts({ address }: { address: PublicKey }) { 37 | const { connection } = useConnection() 38 | 39 | return useQuery({ 40 | queryKey: ['get-token-accounts', { endpoint: connection.rpcEndpoint, address }], 41 | queryFn: async () => { 42 | const [tokenAccounts, token2022Accounts] = await Promise.all([ 43 | connection.getParsedTokenAccountsByOwner(address, { 44 | programId: TOKEN_PROGRAM_ID, 45 | }), 46 | connection.getParsedTokenAccountsByOwner(address, { 47 | programId: TOKEN_2022_PROGRAM_ID, 48 | }), 49 | ]) 50 | return [...tokenAccounts.value, ...token2022Accounts.value] 51 | }, 52 | }) 53 | } 54 | 55 | export function useTransferSol({ address }: { address: PublicKey }) { 56 | const { connection } = useConnection() 57 | const transactionToast = useTransactionToast() 58 | const wallet = useWallet() 59 | const client = useQueryClient() 60 | 61 | return useMutation({ 62 | mutationKey: ['transfer-sol', { endpoint: connection.rpcEndpoint, address }], 63 | mutationFn: async (input: { destination: PublicKey; amount: number }) => { 64 | let signature: TransactionSignature = '' 65 | try { 66 | const { transaction, latestBlockhash } = await createTransaction({ 67 | publicKey: address, 68 | destination: input.destination, 69 | amount: input.amount, 70 | connection, 71 | }) 72 | 73 | // Send transaction and await for signature 74 | signature = await wallet.sendTransaction(transaction, connection) 75 | 76 | // Send transaction and await for signature 77 | await connection.confirmTransaction({ signature, ...latestBlockhash }, 'confirmed') 78 | 79 | console.log(signature) 80 | return signature 81 | } catch (error: unknown) { 82 | console.log('error', `Transaction failed! ${error}`, signature) 83 | 84 | return 85 | } 86 | }, 87 | onSuccess: (signature) => { 88 | if (signature) { 89 | transactionToast(signature) 90 | } 91 | return Promise.all([ 92 | client.invalidateQueries({ 93 | queryKey: ['get-balance', { endpoint: connection.rpcEndpoint, address }], 94 | }), 95 | client.invalidateQueries({ 96 | queryKey: ['get-signatures', { endpoint: connection.rpcEndpoint, address }], 97 | }), 98 | ]) 99 | }, 100 | onError: (error: unknown) => { 101 | toast.error(`Transaction failed! ${error}`) 102 | }, 103 | }) 104 | } 105 | 106 | export function useRequestAirdrop({ address }: { address: PublicKey }) { 107 | const { connection } = useConnection() 108 | const transactionToast = useTransactionToast() 109 | const client = useQueryClient() 110 | 111 | return useMutation({ 112 | mutationKey: ['airdrop', { endpoint: connection.rpcEndpoint, address }], 113 | mutationFn: async (amount: number = 1) => { 114 | const [latestBlockhash, signature] = await Promise.all([ 115 | connection.getLatestBlockhash(), 116 | connection.requestAirdrop(address, amount * LAMPORTS_PER_SOL), 117 | ]) 118 | 119 | await connection.confirmTransaction({ signature, ...latestBlockhash }, 'confirmed') 120 | return signature 121 | }, 122 | onSuccess: (signature) => { 123 | transactionToast(signature) 124 | return Promise.all([ 125 | client.invalidateQueries({ 126 | queryKey: ['get-balance', { endpoint: connection.rpcEndpoint, address }], 127 | }), 128 | client.invalidateQueries({ 129 | queryKey: ['get-signatures', { endpoint: connection.rpcEndpoint, address }], 130 | }), 131 | ]) 132 | }, 133 | }) 134 | } 135 | 136 | async function createTransaction({ 137 | publicKey, 138 | destination, 139 | amount, 140 | connection, 141 | }: { 142 | publicKey: PublicKey 143 | destination: PublicKey 144 | amount: number 145 | connection: Connection 146 | }): Promise<{ 147 | transaction: VersionedTransaction 148 | latestBlockhash: { blockhash: string; lastValidBlockHeight: number } 149 | }> { 150 | // Get the latest blockhash to use in our transaction 151 | const latestBlockhash = await connection.getLatestBlockhash() 152 | 153 | // Create instructions to send, in this case a simple transfer 154 | const instructions = [ 155 | SystemProgram.transfer({ 156 | fromPubkey: publicKey, 157 | toPubkey: destination, 158 | lamports: amount * LAMPORTS_PER_SOL, 159 | }), 160 | ] 161 | 162 | // Create a new TransactionMessage with version and compile it to legacy 163 | const messageLegacy = new TransactionMessage({ 164 | payerKey: publicKey, 165 | recentBlockhash: latestBlockhash.blockhash, 166 | instructions, 167 | }).compileToLegacyMessage() 168 | 169 | // Create a new VersionedTransaction which supports legacy and v0 170 | const transaction = new VersionedTransaction(messageLegacy) 171 | 172 | return { 173 | transaction, 174 | latestBlockhash, 175 | } 176 | } 177 | -------------------------------------------------------------------------------- /src/components/cluster/cluster-ui.tsx: -------------------------------------------------------------------------------- 1 | 'use client' 2 | 3 | import { useConnection } from '@solana/wallet-adapter-react' 4 | import { IconTrash } from '@tabler/icons-react' 5 | import { useQuery } from '@tanstack/react-query' 6 | import { ReactNode, useState } from 'react' 7 | import { AppModal } from '../ui/ui-layout' 8 | import { ClusterNetwork, useCluster } from './cluster-data-access' 9 | import { Connection } from '@solana/web3.js' 10 | 11 | export function ExplorerLink({ path, label, className }: { path: string; label: string; className?: string }) { 12 | const { getExplorerUrl } = useCluster() 13 | return ( 14 | 20 | {label} 21 | 22 | ) 23 | } 24 | 25 | export function ClusterChecker({ children }: { children: ReactNode }) { 26 | const { cluster } = useCluster() 27 | const { connection } = useConnection() 28 | 29 | const query = useQuery({ 30 | queryKey: ['version', { cluster, endpoint: connection.rpcEndpoint }], 31 | queryFn: () => connection.getVersion(), 32 | retry: 1, 33 | }) 34 | if (query.isLoading) { 35 | return null 36 | } 37 | if (query.isError || !query.data) { 38 | return ( 39 |
40 | 41 | Error connecting to cluster {cluster.name} 42 | 43 | 46 |
47 | ) 48 | } 49 | return children 50 | } 51 | 52 | export function ClusterUiSelect() { 53 | const { clusters, setCluster, cluster } = useCluster() 54 | return ( 55 |
56 | 59 |
    60 | {clusters.map((item) => ( 61 |
  • 62 | 68 |
  • 69 | ))} 70 |
71 |
72 | ) 73 | } 74 | 75 | export function ClusterUiModal({ hideModal, show }: { hideModal: () => void; show: boolean }) { 76 | const { addCluster } = useCluster() 77 | const [name, setName] = useState('') 78 | const [network, setNetwork] = useState() 79 | const [endpoint, setEndpoint] = useState('') 80 | 81 | return ( 82 | { 87 | try { 88 | new Connection(endpoint) 89 | if (name) { 90 | addCluster({ name, network, endpoint }) 91 | hideModal() 92 | } else { 93 | console.log('Invalid cluster name') 94 | } 95 | } catch { 96 | console.log('Invalid cluster endpoint') 97 | } 98 | }} 99 | submitLabel="Save" 100 | > 101 | setName(e.target.value)} 107 | /> 108 | setEndpoint(e.target.value)} 114 | /> 115 | 125 | 126 | ) 127 | } 128 | 129 | export function ClusterUiTable() { 130 | const { clusters, setCluster, deleteCluster } = useCluster() 131 | return ( 132 |
133 | 134 | 135 | 136 | 137 | 138 | 139 | 140 | 141 | {clusters.map((item) => ( 142 | 143 | 158 | 170 | 171 | ))} 172 | 173 |
Name/ Network / EndpointActions
144 |
145 | 146 | {item?.active ? ( 147 | item.name 148 | ) : ( 149 | 152 | )} 153 | 154 |
155 | Network: {item.network ?? 'custom'} 156 |
{item.endpoint}
157 |
159 | 169 |
174 |
175 | ) 176 | } 177 | -------------------------------------------------------------------------------- /src/components/devotion/devotion-data-access.tsx: -------------------------------------------------------------------------------- 1 | 'use client' 2 | 3 | import { getDevotionProgram, getDevotionProgramId } from '@project/anchor' 4 | import { useConnection } from '@solana/wallet-adapter-react' 5 | import { Cluster, Keypair, PublicKey } from '@solana/web3.js' 6 | import { useMutation, useQuery } from '@tanstack/react-query' 7 | import { useMemo } from 'react' 8 | import toast from 'react-hot-toast' 9 | import { useCluster } from '../cluster/cluster-data-access' 10 | import { useAnchorProvider } from '../solana/solana-provider' 11 | import { useTransactionToast } from '../ui/ui-layout' 12 | import { BN } from '@coral-xyz/anchor' 13 | import { useWallet } from '@solana/wallet-adapter-react' 14 | 15 | interface InitializeArgs { 16 | interval: number 17 | maxDevotionCharge: number 18 | mint: string 19 | } 20 | 21 | interface DevoteArgs { 22 | amount: number 23 | } 24 | 25 | interface WaverArgs { 26 | amount: number 27 | } 28 | 29 | export function useDevotionProgram() { 30 | const { connection } = useConnection() 31 | const { cluster } = useCluster() 32 | const { publicKey } = useWallet() 33 | const transactionToast = useTransactionToast() 34 | const provider = useAnchorProvider() 35 | const programId = useMemo(() => getDevotionProgramId(cluster.network as Cluster), [cluster]) 36 | const program = useMemo(() => getDevotionProgram(provider, programId), [provider, programId]) 37 | 38 | const stateAccount = useQuery({ 39 | queryKey: ['devotion', 'state', { cluster }], 40 | queryFn: () => program.account.stakeState.fetch( 41 | PublicKey.findProgramAddressSync( 42 | [Buffer.from("state")], 43 | programId 44 | )[0] 45 | ), 46 | }) 47 | 48 | const getProgramAccount = useQuery({ 49 | queryKey: ['get-program-account', { cluster }], 50 | queryFn: () => connection.getParsedAccountInfo(programId), 51 | }) 52 | 53 | const initialize = useMutation({ 54 | mutationKey: ['devotion', 'initialize', { cluster }], 55 | mutationFn: ({ interval, maxDevotionCharge, mint }: InitializeArgs) => 56 | program.methods 57 | .initialize(new BN(interval), new BN(maxDevotionCharge)) 58 | .accounts({ stakeMint: new PublicKey(mint) }) 59 | .rpc(), 60 | onSuccess: (signature) => { 61 | transactionToast(signature) 62 | return stateAccount.refetch() 63 | }, 64 | onError: () => toast.error('Failed to initialize account'), 65 | }) 66 | 67 | const userDevotedAccount = useQuery({ 68 | queryKey: ['devotion', 'user-account', { cluster, publicKey }], 69 | queryFn: async () => { 70 | if (!publicKey) return null; 71 | 72 | const accounts = await program.account.devoted.all([ 73 | { 74 | memcmp: { 75 | offset: 8, 76 | bytes: publicKey.toBase58() 77 | } 78 | } 79 | ]); 80 | 81 | return accounts[0] || null; 82 | }, 83 | enabled: !!publicKey, 84 | }); 85 | 86 | return { 87 | program, 88 | programId, 89 | getProgramAccount, 90 | initialize, 91 | stateAccount, 92 | userDevotedAccount, 93 | } 94 | } 95 | 96 | export function useDevotionProgramAccount({ account }: { account: PublicKey }) { 97 | const { cluster } = useCluster() 98 | const transactionToast = useTransactionToast() 99 | const { program, stateAccount, userDevotedAccount } = useDevotionProgram() 100 | 101 | const devotionQuery = useQuery({ 102 | queryKey: ['devotion', 'fetch', { cluster, account }], 103 | queryFn: () => program.account.devoted.fetch(account), 104 | retry: false 105 | }) 106 | 107 | const devoteMutation = useMutation({ 108 | mutationKey: ['devotion', 'devote', { cluster, account }], 109 | mutationFn: ({ amount }: DevoteArgs) => { 110 | if (!stateAccount.data?.stakeMint) throw new Error('Stake mint not found'); 111 | 112 | const decimals = stateAccount.data.decimals; 113 | const scaledAmount = new BN(amount * Math.pow(10, decimals)); 114 | 115 | console.log('Devoting amount:', amount, 'Scaled amount:', scaledAmount.toString()); 116 | 117 | return program.methods 118 | .devote(scaledAmount) 119 | .accounts({ stakeMint: stateAccount.data.stakeMint }) 120 | .rpc(); 121 | }, 122 | onSuccess: async (tx) => { 123 | transactionToast(tx) 124 | await Promise.all([ 125 | devotionQuery.refetch(), 126 | userDevotedAccount.refetch() 127 | ]) 128 | }, 129 | onError: (error) => { 130 | console.error('Devote error:', error); 131 | toast.error('Failed to devote'); 132 | }, 133 | }) 134 | 135 | const waverMutation = useMutation({ 136 | mutationKey: ['devotion', 'waver', { cluster, account }], 137 | mutationFn: ({ amount }: WaverArgs) => { 138 | if (!stateAccount.data?.stakeMint) throw new Error('Stake mint not found'); 139 | 140 | const decimals = stateAccount.data.decimals; 141 | const scaledAmount = new BN(amount * Math.pow(10, decimals)); 142 | 143 | console.log('Wavering amount:', amount, 'Scaled amount:', scaledAmount.toString()); 144 | 145 | return program.methods 146 | .waver(scaledAmount) 147 | .accounts({ stakeMint: stateAccount.data.stakeMint }) 148 | .rpc(); 149 | }, 150 | onSuccess: (tx) => { 151 | transactionToast(tx) 152 | return devotionQuery.refetch() 153 | }, 154 | onError: (error) => { 155 | console.error('Waver error:', error); 156 | toast.error('Failed to waver'); 157 | }, 158 | }) 159 | 160 | const heresyMutation = useMutation({ 161 | mutationKey: ['devotion', 'heresy', { cluster, account }], 162 | mutationFn: () => { 163 | if (!stateAccount.data?.stakeMint) throw new Error('Stake mint not found'); 164 | return program.methods.heresy().accounts({ stakeMint: stateAccount.data?.stakeMint }).rpc(); 165 | }, 166 | onSuccess: async (tx) => { 167 | transactionToast(tx) 168 | await Promise.all([ 169 | devotionQuery.refetch(), 170 | userDevotedAccount.refetch() 171 | ]) 172 | }, 173 | onError: (error) => { 174 | console.error('Heresy error:', error) 175 | toast.error('Failed to commit heresy') 176 | } 177 | }) 178 | 179 | return { 180 | devotionQuery, 181 | devoteMutation, 182 | waverMutation, 183 | heresyMutation, 184 | } 185 | } 186 | -------------------------------------------------------------------------------- /src/components/devotion/devotion-ui.tsx: -------------------------------------------------------------------------------- 1 | 'use client' 2 | 3 | import { PublicKey } from '@solana/web3.js' 4 | import { useMemo, useState, useEffect } from 'react' 5 | import { ellipsify } from '../ui/ui-layout' 6 | import { ExplorerLink } from '../cluster/cluster-ui' 7 | import { useDevotionProgram, useDevotionProgramAccount } from './devotion-data-access' 8 | import { useWallet } from '@solana/wallet-adapter-react' 9 | import { BN } from '@coral-xyz/anchor' 10 | 11 | export function DevotionCreate() { 12 | const { initialize, stateAccount } = useDevotionProgram() 13 | const { publicKey } = useWallet() 14 | const [interval, setInterval] = useState('') 15 | const [maxDevotionCharge, setMaxDevotionCharge] = useState('') 16 | const [mint, setMint] = useState('') 17 | 18 | const isFormValid = interval.length > 0 && maxDevotionCharge.length > 0 && mint.length > 0 19 | 20 | // If loading, show loading spinner 21 | if (stateAccount.isLoading) { 22 | return ( 23 |
24 | 25 |
26 | ) 27 | } 28 | 29 | // If program is already initialized, don't show the form 30 | if (stateAccount.data) { 31 | return ( 32 |
33 | Program has already been initialized. 34 |
35 | ) 36 | } 37 | 38 | if (!publicKey) { 39 | return

Connect your wallet

40 | } 41 | 42 | const handleSubmit = async () => { 43 | try { 44 | await initialize.mutateAsync({ 45 | interval: parseInt(interval), 46 | maxDevotionCharge: parseInt(maxDevotionCharge), 47 | mint, 48 | }) 49 | } catch (error) { 50 | console.error('Failed to initialize:', error) 51 | } 52 | } 53 | 54 | return ( 55 |
56 | setInterval(e.target.value)} 61 | className="input input-bordered w-full max-w-xs" 62 | /> 63 | setMaxDevotionCharge(e.target.value)} 68 | className="input input-bordered w-full max-w-xs" 69 | /> 70 | setMint(e.target.value)} 75 | className="input input-bordered w-full max-w-xs" 76 | /> 77 | 84 |
85 | ) 86 | } 87 | 88 | export function DevotionList() { 89 | const { publicKey } = useWallet() 90 | const { getProgramAccount, stateAccount, userDevotedAccount } = useDevotionProgram() 91 | 92 | if (getProgramAccount.isLoading || userDevotedAccount.isLoading) { 93 | return ( 94 |
95 | 96 |
97 | ) 98 | } 99 | 100 | if (!getProgramAccount.data?.value) { 101 | return ( 102 |
103 | Program account not found. 104 |
105 | ) 106 | } 107 | 108 | if (!stateAccount.data) { 109 | return ( 110 |
111 | Program not initialized. Please initialize it first. 112 |
113 | ) 114 | } 115 | 116 | return ( 117 |
118 | {publicKey ? ( 119 | userDevotedAccount.data ? ( 120 | 121 | ) : ( 122 | 123 | ) 124 | ) : ( 125 |
126 |

Connect Wallet

127 |

Connect your wallet to view or create devotion accounts.

128 |
129 | )} 130 |
131 | ) 132 | } 133 | 134 | function NewDevotionCard() { 135 | const [amount, setAmount] = useState('') 136 | const { publicKey } = useWallet() 137 | const { stateAccount } = useDevotionProgram() 138 | 139 | const account = useMemo(() => { 140 | if (!publicKey) return null 141 | return PublicKey.findProgramAddressSync( 142 | [Buffer.from("devoted"), publicKey.toBuffer()], 143 | stateAccount.data?.stakeMint ?? PublicKey.default 144 | )[0] 145 | }, [publicKey, stateAccount.data?.stakeMint]) 146 | 147 | const { devoteMutation } = useDevotionProgramAccount({ 148 | account: account ?? PublicKey.default, 149 | }) 150 | 151 | if (!account) return null 152 | 153 | return ( 154 |
155 |
156 |

Devote

157 |
158 | setAmount(e.target.value)} 163 | className="input input-bordered w-full" 164 | /> 165 | 176 |
177 |
178 |
179 | ) 180 | } 181 | 182 | function DevotionScore({ devoted, stakeState }: { devoted: any; stakeState: any }) { 183 | const [currentDevotion, setCurrentDevotion] = useState('0.00') 184 | 185 | useEffect(() => { 186 | const calculateDevotion = () => { 187 | if (!devoted || !stakeState) return '0.00' 188 | 189 | const currentTime = Math.floor(Date.now() / 1000) 190 | const secondsStaked = Math.max(0, currentTime - devoted.lastStakeTimestamp.toNumber()) 191 | 192 | // Cap the seconds at maximum multiplier 193 | const cappedSeconds = Math.min(secondsStaked, stakeState.maxDevotionCharge.toNumber()) 194 | 195 | // Calculate using the same logic as the Rust program 196 | const decimalsMultiplier = new BN(10).pow(new BN(stakeState.decimals)) 197 | 198 | // Calculate current devotion 199 | // Formula: (cappedSeconds * amount) / (decimalsMultiplier * interval) 200 | const devotion = new BN(cappedSeconds) 201 | .mul(new BN(devoted.amount)) 202 | .div(decimalsMultiplier) 203 | .div(new BN(stakeState.interval)) 204 | 205 | // Calculate max devotion 206 | // Formula: (amount * maxDevotionCharge) / (decimalsMultiplier * interval) 207 | const maxDevotion = new BN(devoted.amount) 208 | .mul(new BN(stakeState.maxDevotionCharge)) 209 | .div(decimalsMultiplier) 210 | .div(new BN(stakeState.interval)) 211 | 212 | // Add residual devotion 213 | const totalDevotion = devotion.add(new BN(devoted.residualDevotion)) 214 | 215 | // Get the minimum of total devotion and max devotion 216 | const finalDevotion = BN.min(totalDevotion, maxDevotion) 217 | 218 | return finalDevotion.toString() 219 | } 220 | 221 | // Update every second 222 | const interval = setInterval(() => { 223 | setCurrentDevotion(calculateDevotion()) 224 | }, 1000) 225 | 226 | // Initial calculation 227 | setCurrentDevotion(calculateDevotion()) 228 | 229 | return () => clearInterval(interval) 230 | }, [devoted, stakeState]) 231 | 232 | return ( 233 |
234 |
Current Devotion
235 |
{currentDevotion}
236 |
237 | ) 238 | } 239 | 240 | function DevotionCard({ account }: { account: PublicKey }) { 241 | const { devotionQuery, devoteMutation, waverMutation, heresyMutation } = useDevotionProgramAccount({ 242 | account, 243 | }) 244 | const { stateAccount } = useDevotionProgram() 245 | const [devoteAmount, setDevoteAmount] = useState('') 246 | const [waverAmount, setWaverAmount] = useState('') 247 | 248 | if (devotionQuery.isLoading) { 249 | return ( 250 |
251 | 252 |
253 | ) 254 | } 255 | 256 | if (devotionQuery.isError || !devotionQuery.data) { 257 | return null; 258 | } 259 | 260 | const decimals = stateAccount.data?.decimals ?? 0 261 | const displayAmount = (amount: BN | number) => { 262 | const numberAmount = amount instanceof BN ? amount.toNumber() : amount 263 | return (numberAmount / Math.pow(10, decimals)).toFixed(2) 264 | } 265 | 266 | const handleHeresy = async () => { 267 | try { 268 | await heresyMutation.mutateAsync() 269 | } catch (error) { 270 | console.error('Heresy error:', error) 271 | } 272 | } 273 | 274 | return ( 275 |
276 |
277 |

Your Devotion

278 | 279 |
280 | 284 |
285 |
Devoted Amount
286 |
{displayAmount(devotionQuery.data.amount)}
287 |
288 |
289 | 290 |
291 | {/* Devote more tokens */} 292 |
293 | setDevoteAmount(e.target.value)} 299 | className="input input-bordered w-full" 300 | /> 301 | 308 |
309 | 310 | {/* Waver (unstake) tokens */} 311 |
312 | setWaverAmount(e.target.value)} 318 | className="input input-bordered w-full" 319 | /> 320 | 327 |
328 | 329 | {/* Heresy (close account) */} 330 | 337 |
338 | 339 |
340 | 341 |
342 |
343 |
344 | ) 345 | } 346 | -------------------------------------------------------------------------------- /src/components/account/account-ui.tsx: -------------------------------------------------------------------------------- 1 | 'use client' 2 | 3 | import { useWallet } from '@solana/wallet-adapter-react' 4 | import { LAMPORTS_PER_SOL, PublicKey } from '@solana/web3.js' 5 | import { IconRefresh } from '@tabler/icons-react' 6 | import { useQueryClient } from '@tanstack/react-query' 7 | import { useMemo, useState } from 'react' 8 | import { AppModal, ellipsify } from '../ui/ui-layout' 9 | import { useCluster } from '../cluster/cluster-data-access' 10 | import { ExplorerLink } from '../cluster/cluster-ui' 11 | import { 12 | useGetBalance, 13 | useGetSignatures, 14 | useGetTokenAccounts, 15 | useRequestAirdrop, 16 | useTransferSol, 17 | } from './account-data-access' 18 | 19 | export function AccountBalance({ address }: { address: PublicKey }) { 20 | const query = useGetBalance({ address }) 21 | 22 | return ( 23 |
24 |

query.refetch()}> 25 | {query.data ? : '...'} SOL 26 |

27 |
28 | ) 29 | } 30 | export function AccountChecker() { 31 | const { publicKey } = useWallet() 32 | if (!publicKey) { 33 | return null 34 | } 35 | return 36 | } 37 | export function AccountBalanceCheck({ address }: { address: PublicKey }) { 38 | const { cluster } = useCluster() 39 | const mutation = useRequestAirdrop({ address }) 40 | const query = useGetBalance({ address }) 41 | 42 | if (query.isLoading) { 43 | return null 44 | } 45 | if (query.isError || !query.data) { 46 | return ( 47 |
48 | 49 | You are connected to {cluster.name} but your account is not found on this cluster. 50 | 51 | 57 |
58 | ) 59 | } 60 | return null 61 | } 62 | 63 | export function AccountButtons({ address }: { address: PublicKey }) { 64 | const wallet = useWallet() 65 | const { cluster } = useCluster() 66 | const [showAirdropModal, setShowAirdropModal] = useState(false) 67 | const [showReceiveModal, setShowReceiveModal] = useState(false) 68 | const [showSendModal, setShowSendModal] = useState(false) 69 | 70 | return ( 71 |
72 | setShowAirdropModal(false)} address={address} show={showAirdropModal} /> 73 | setShowReceiveModal(false)} /> 74 | setShowSendModal(false)} /> 75 |
76 | 83 | 90 | 93 |
94 |
95 | ) 96 | } 97 | 98 | export function AccountTokens({ address }: { address: PublicKey }) { 99 | const [showAll, setShowAll] = useState(false) 100 | const query = useGetTokenAccounts({ address }) 101 | const client = useQueryClient() 102 | const items = useMemo(() => { 103 | if (showAll) return query.data 104 | return query.data?.slice(0, 5) 105 | }, [query.data, showAll]) 106 | 107 | return ( 108 |
109 |
110 |
111 |

Token Accounts

112 |
113 | {query.isLoading ? ( 114 | 115 | ) : ( 116 | 127 | )} 128 |
129 |
130 |
131 | {query.isError &&
Error: {query.error?.message.toString()}
} 132 | {query.isSuccess && ( 133 |
134 | {query.data.length === 0 ? ( 135 |
No token accounts found.
136 | ) : ( 137 | 138 | 139 | 140 | 141 | 142 | 143 | 144 | 145 | 146 | {items?.map(({ account, pubkey }) => ( 147 | 148 | 155 | 165 | 168 | 169 | ))} 170 | 171 | {(query.data?.length ?? 0) > 5 && ( 172 | 173 | 178 | 179 | )} 180 | 181 |
Public KeyMintBalance
149 |
150 | 151 | 152 | 153 |
154 |
156 |
157 | 158 | 162 | 163 |
164 |
166 | {account.data.parsed.info.tokenAmount.uiAmount} 167 |
174 | 177 |
182 | )} 183 |
184 | )} 185 |
186 | ) 187 | } 188 | 189 | export function AccountTransactions({ address }: { address: PublicKey }) { 190 | const query = useGetSignatures({ address }) 191 | const [showAll, setShowAll] = useState(false) 192 | 193 | const items = useMemo(() => { 194 | if (showAll) return query.data 195 | return query.data?.slice(0, 5) 196 | }, [query.data, showAll]) 197 | 198 | return ( 199 |
200 |
201 |

Transaction History

202 |
203 | {query.isLoading ? ( 204 | 205 | ) : ( 206 | 209 | )} 210 |
211 |
212 | {query.isError &&
Error: {query.error?.message.toString()}
} 213 | {query.isSuccess && ( 214 |
215 | {query.data.length === 0 ? ( 216 |
No transactions found.
217 | ) : ( 218 | 219 | 220 | 221 | 222 | 223 | 224 | 225 | 226 | 227 | 228 | {items?.map((item) => ( 229 | 230 | 233 | 236 | 237 | 246 | 247 | ))} 248 | {(query.data?.length ?? 0) > 5 && ( 249 | 250 | 255 | 256 | )} 257 | 258 |
SignatureSlotBlock TimeStatus
231 | 232 | 234 | 235 | {new Date((item.blockTime ?? 0) * 1000).toISOString()} 238 | {item.err ? ( 239 |
240 | Failed 241 |
242 | ) : ( 243 |
Success
244 | )} 245 |
251 | 254 |
259 | )} 260 |
261 | )} 262 |
263 | ) 264 | } 265 | 266 | function BalanceSol({ balance }: { balance: number }) { 267 | return {Math.round((balance / LAMPORTS_PER_SOL) * 100000) / 100000} 268 | } 269 | 270 | function ModalReceive({ hide, show, address }: { hide: () => void; show: boolean; address: PublicKey }) { 271 | return ( 272 | 273 |

Receive assets by sending them to your public key:

274 | {address.toString()} 275 |
276 | ) 277 | } 278 | 279 | function ModalAirdrop({ hide, show, address }: { hide: () => void; show: boolean; address: PublicKey }) { 280 | const mutation = useRequestAirdrop({ address }) 281 | const [amount, setAmount] = useState('2') 282 | 283 | return ( 284 | mutation.mutateAsync(parseFloat(amount)).then(() => hide())} 291 | > 292 | setAmount(e.target.value)} 301 | /> 302 | 303 | ) 304 | } 305 | 306 | function ModalSend({ hide, show, address }: { hide: () => void; show: boolean; address: PublicKey }) { 307 | const wallet = useWallet() 308 | const mutation = useTransferSol({ address }) 309 | const [destination, setDestination] = useState('') 310 | const [amount, setAmount] = useState('1') 311 | 312 | if (!address || !wallet.sendTransaction) { 313 | return
Wallet not connected
314 | } 315 | 316 | return ( 317 | { 324 | mutation 325 | .mutateAsync({ 326 | destination: new PublicKey(destination), 327 | amount: parseFloat(amount), 328 | }) 329 | .then(() => hide()) 330 | }} 331 | > 332 | setDestination(e.target.value)} 339 | /> 340 | setAmount(e.target.value)} 349 | /> 350 | 351 | ) 352 | } 353 | -------------------------------------------------------------------------------- /anchor/programs/devotion/src/lib.rs: -------------------------------------------------------------------------------- 1 | use anchor_lang::prelude::*; 2 | use anchor_spl::token::{Mint, Token, TokenAccount, Transfer, transfer}; 3 | 4 | declare_id!("GodsAfuZbVYY79KADVMe39ZwybWuL5U6RFLvyzUD5qgw"); 5 | 6 | #[program] 7 | pub mod devotion { 8 | use super::*; 9 | 10 | // initialization of the program state checks the safety of max devotion 11 | pub fn initialize( 12 | ctx: Context, 13 | interval: i64, 14 | max_devotion_charge: i64, 15 | ) -> Result<()> { 16 | // Validate interval and max_devotion_charge 17 | if interval <= 0 { 18 | return Err(ErrorCode::InvalidInterval.into()); 19 | } 20 | if max_devotion_charge <= 0 { 21 | return Err(ErrorCode::InvalidMaxDevotionCharge.into()); 22 | } 23 | 24 | // Check if max_devotion calculation could overflow using u128 25 | let decimals_multiplier = 10u128.pow(ctx.accounts.stake_mint.decimals as u32); 26 | 27 | // Check if max_devotion_charge * U64::MAX would overflow when converted to u128 28 | (u128::from(u64::MAX)) 29 | .checked_mul(max_devotion_charge as u128) 30 | .ok_or(ErrorCode::MaxDevotionOverflow)? 31 | .checked_div(decimals_multiplier) 32 | .ok_or(ErrorCode::DivError)? 33 | .checked_div(interval as u128) 34 | .ok_or(ErrorCode::DivError)?; 35 | 36 | let state = &mut ctx.accounts.stake_state; 37 | state.admin = ctx.accounts.admin.key(); 38 | state.stake_mint = ctx.accounts.stake_mint.key(); 39 | state.decimals = ctx.accounts.stake_mint.decimals; 40 | state.interval = interval; 41 | state.max_devotion_charge = max_devotion_charge; 42 | 43 | // Initialize total devoted 44 | let total_devoted = &mut ctx.accounts.total_devoted; 45 | total_devoted.total_tokens = 0; 46 | 47 | Ok(()) 48 | } 49 | 50 | pub fn devote(ctx: Context, amount: u64) -> Result<()> { 51 | if amount == 0 { 52 | return Err(ErrorCode::AmountZero.into()); 53 | } 54 | 55 | let devoted = &mut ctx.accounts.devoted; 56 | 57 | // Calculate current devotion before adding new tokens 58 | if devoted.amount > 0 { 59 | let current_time = Clock::get()?.unix_timestamp; 60 | let seconds_staked = current_time.saturating_sub(devoted.last_stake_timestamp); 61 | 62 | // Cap the seconds at maximum multiplier using stake_state value 63 | let capped_seconds = std::cmp::min(seconds_staked, ctx.accounts.stake_state.max_devotion_charge); 64 | 65 | // Calculate current devotion using u128 66 | let decimals_multiplier = 10u128.pow(ctx.accounts.stake_state.decimals as u32); 67 | let calculated_devotion = (capped_seconds as u128) 68 | .checked_mul(devoted.amount as u128) 69 | .ok_or(ErrorCode::MathOverflow)? 70 | .checked_div(decimals_multiplier) 71 | .ok_or(ErrorCode::DivError)? 72 | .checked_div(ctx.accounts.stake_state.interval as u128) 73 | .ok_or(ErrorCode::DivError)?; 74 | 75 | // Add residual_devotion to get current_devotion 76 | let current_devotion = calculated_devotion 77 | .checked_add(devoted.residual_devotion) 78 | .ok_or(ErrorCode::MathOverflow)?; 79 | 80 | // Calculate max_devotion using u128 81 | // This might be redundant as we're already capping the seconds at max_devotion_charge 82 | let max_devotion = (devoted.amount as u128) 83 | .checked_mul(ctx.accounts.stake_state.max_devotion_charge as u128) 84 | .ok_or(ErrorCode::MathOverflow)? 85 | .checked_div(decimals_multiplier) 86 | .ok_or(ErrorCode::DivError)? 87 | .checked_div(ctx.accounts.stake_state.interval as u128) 88 | .ok_or(ErrorCode::DivError)?; 89 | 90 | // Store the capped current_devotion as residual_devotion 91 | devoted.residual_devotion = std::cmp::min(current_devotion, max_devotion); 92 | } else { 93 | // Initialize user data if this is their first stake 94 | devoted.user = ctx.accounts.user.key(); 95 | } 96 | 97 | // Transfer tokens from user to their vault 98 | let cpi_accounts = Transfer { 99 | from: ctx.accounts.user_token_account.to_account_info(), 100 | to: ctx.accounts.user_vault.to_account_info(), 101 | authority: ctx.accounts.user.to_account_info(), 102 | }; 103 | 104 | let cpi_program = ctx.accounts.token_program.to_account_info(); 105 | let cpi_ctx = CpiContext::new(cpi_program, cpi_accounts); 106 | transfer(cpi_ctx, amount)?; 107 | 108 | // Update user's stake info 109 | devoted.amount = devoted.amount 110 | .checked_add(amount) 111 | .ok_or(ErrorCode::MathOverflow)?; 112 | devoted.last_stake_timestamp = Clock::get()?.unix_timestamp; 113 | 114 | // Update total devoted 115 | let total_devoted = &mut ctx.accounts.total_devoted; 116 | total_devoted.total_tokens = total_devoted.total_tokens 117 | .checked_add(amount) 118 | .ok_or(ErrorCode::MathOverflow)?; 119 | 120 | Ok(()) 121 | } 122 | 123 | pub fn waver(ctx: Context, amount: u64) -> Result<()> { 124 | 125 | if amount == 0 { 126 | // custom error 127 | return Err(ErrorCode::AmountZero.into()); 128 | } 129 | 130 | // Transfer from user's vault to user 131 | let devoted_binding = &ctx.accounts.devoted; 132 | let seeds = &[ 133 | b"devoted".as_ref(), 134 | devoted_binding.user.as_ref(), 135 | &[ctx.bumps.devoted], 136 | ]; 137 | let signer = [&seeds[..]]; 138 | 139 | let cpi_accounts = Transfer { 140 | from: ctx.accounts.user_vault.to_account_info(), 141 | to: ctx.accounts.user_token_account.to_account_info(), 142 | authority: ctx.accounts.devoted.to_account_info(), 143 | }; 144 | 145 | let cpi_program = ctx.accounts.token_program.to_account_info(); 146 | let cpi_ctx = CpiContext::new_with_signer(cpi_program, cpi_accounts, &signer); 147 | transfer(cpi_ctx, amount)?; 148 | 149 | // Update user's stake info 150 | let devoted = &mut ctx.accounts.devoted; 151 | devoted.amount = devoted.amount 152 | .checked_sub(amount) 153 | .ok_or(ErrorCode::InsufficientFunds)?; 154 | 155 | // Reset timestamp to current time 156 | devoted.last_stake_timestamp = Clock::get()?.unix_timestamp; 157 | 158 | // Always reset residual_devotion to 0 159 | devoted.residual_devotion = 0; 160 | 161 | // Update total devoted 162 | let total_devoted = &mut ctx.accounts.total_devoted; 163 | total_devoted.total_tokens = total_devoted.total_tokens 164 | .checked_sub(amount) 165 | .ok_or(ErrorCode::MathUnderflow)?; 166 | 167 | Ok(()) 168 | } 169 | 170 | pub fn heresy(ctx: Context) -> Result<()> { 171 | if ctx.accounts.user_vault.amount == 0 { 172 | // custom error 173 | return Err(ErrorCode::VaultZero.into()); 174 | } 175 | 176 | if ctx.accounts.devoted.amount == 0 { 177 | // custom error 178 | return Err(ErrorCode::DevotionZero.into()); 179 | } 180 | 181 | // If there are tokens in the vault, transfer them back to user 182 | if ctx.accounts.user_vault.amount > 0 { 183 | // Transfer all tokens from vault to user 184 | let devoted_binding = &ctx.accounts.devoted; 185 | let seeds = &[ 186 | b"devoted".as_ref(), 187 | devoted_binding.user.as_ref(), 188 | &[ctx.bumps.devoted], 189 | ]; 190 | let signer = [&seeds[..]]; 191 | 192 | let cpi_accounts = Transfer { 193 | from: ctx.accounts.user_vault.to_account_info(), 194 | to: ctx.accounts.user_token_account.to_account_info(), 195 | authority: ctx.accounts.devoted.to_account_info(), 196 | }; 197 | 198 | let cpi_program = ctx.accounts.token_program.to_account_info(); 199 | let cpi_ctx = CpiContext::new_with_signer(cpi_program, cpi_accounts, &signer); 200 | transfer(cpi_ctx, ctx.accounts.user_vault.amount)?; 201 | 202 | // Update total devoted 203 | let total_devoted = &mut ctx.accounts.total_devoted; 204 | total_devoted.total_tokens = total_devoted.total_tokens 205 | .checked_sub(ctx.accounts.user_vault.amount) 206 | .ok_or(ErrorCode::MathUnderflow)?; 207 | } 208 | 209 | Ok(()) 210 | } 211 | 212 | pub fn check_devotion(ctx: Context) -> Result { 213 | let devoted = &ctx.accounts.devoted; 214 | let stake_state = &ctx.accounts.stake_state; 215 | let current_time = Clock::get()?.unix_timestamp; 216 | let seconds_staked = current_time.saturating_sub(devoted.last_stake_timestamp); 217 | 218 | // Cap the seconds at maximum multiplier using stake_state value 219 | let capped_seconds = std::cmp::min(seconds_staked, stake_state.max_devotion_charge); 220 | 221 | // Calculate using u128 222 | let decimals_multiplier = 10u128.pow(stake_state.decimals as u32); 223 | let max_devotion = (devoted.amount as u128) 224 | .checked_mul(stake_state.max_devotion_charge as u128) 225 | .ok_or(ErrorCode::MathOverflow)? 226 | .checked_div(decimals_multiplier) 227 | .ok_or(ErrorCode::DivError)? 228 | .checked_div(stake_state.interval as u128) 229 | .ok_or(ErrorCode::DivError)?; 230 | 231 | // Calculate current devotion 232 | let devotion = (capped_seconds as u128) 233 | .checked_mul(devoted.amount as u128) 234 | .ok_or(ErrorCode::MathOverflow)? 235 | .checked_div(decimals_multiplier) 236 | .ok_or(ErrorCode::DivError)? 237 | .checked_div(stake_state.interval as u128) 238 | .ok_or(ErrorCode::DivError)?; 239 | 240 | let total_devotion = devotion 241 | .checked_add(devoted.residual_devotion) 242 | .ok_or(ErrorCode::MathOverflow)?; 243 | 244 | // Return the minimum of total_devotion and max_devotion 245 | Ok(std::cmp::min(total_devotion, max_devotion)) 246 | } 247 | } 248 | 249 | #[account] 250 | #[derive(InitSpace)] 251 | pub struct StakeState { 252 | pub admin: Pubkey, 253 | pub stake_mint: Pubkey, 254 | pub interval: i64, 255 | pub max_devotion_charge: i64, 256 | pub decimals: u8, 257 | } 258 | 259 | #[account] 260 | #[derive(InitSpace)] 261 | pub struct Devoted { 262 | pub user: Pubkey, 263 | pub amount: u64, 264 | pub residual_devotion: u128, 265 | pub last_stake_timestamp: i64, 266 | pub bump: u8, 267 | } 268 | 269 | #[account] 270 | #[derive(InitSpace)] 271 | pub struct TotalDevoted { 272 | pub total_tokens: u64, 273 | } 274 | 275 | #[derive(Accounts)] 276 | pub struct Initialize<'info> { 277 | #[account(mut)] 278 | pub admin: Signer<'info>, 279 | 280 | pub stake_mint: Account<'info, Mint>, 281 | 282 | #[account( 283 | init, 284 | payer = admin, 285 | space = 8 + StakeState::INIT_SPACE, 286 | seeds = [b"state"], 287 | bump, 288 | )] 289 | pub stake_state: Account<'info, StakeState>, 290 | 291 | #[account( 292 | init, 293 | payer = admin, 294 | space = 8 + TotalDevoted::INIT_SPACE, 295 | seeds = [b"total_devoted"], 296 | bump, 297 | )] 298 | pub total_devoted: Account<'info, TotalDevoted>, 299 | 300 | pub system_program: Program<'info, System>, 301 | pub rent: Sysvar<'info, Rent>, 302 | } 303 | 304 | #[derive(Accounts)] 305 | pub struct Devote<'info> { 306 | #[account(mut)] 307 | pub user: Signer<'info>, 308 | 309 | #[account( 310 | seeds = [b"state"], 311 | bump, 312 | constraint = stake_state.stake_mint == stake_mint.key(), 313 | )] 314 | pub stake_state: Account<'info, StakeState>, 315 | 316 | #[account( 317 | init_if_needed, 318 | payer = user, 319 | seeds = [b"vault", user.key().as_ref()], 320 | bump, 321 | token::mint = stake_mint, 322 | token::authority = devoted, 323 | )] 324 | pub user_vault: Account<'info, TokenAccount>, 325 | 326 | #[account( 327 | mut, 328 | associated_token::mint = stake_mint, 329 | associated_token::authority = user, 330 | )] 331 | pub user_token_account: Account<'info, TokenAccount>, 332 | 333 | #[account( 334 | constraint = stake_state.stake_mint == stake_mint.key() 335 | )] 336 | pub stake_mint: Account<'info, Mint>, 337 | 338 | #[account( 339 | init_if_needed, 340 | payer = user, 341 | space = 8 + Devoted::INIT_SPACE, 342 | seeds = [b"devoted", user.key().as_ref()], 343 | bump, 344 | )] 345 | pub devoted: Account<'info, Devoted>, 346 | 347 | #[account( 348 | mut, 349 | seeds = [b"total_devoted"], 350 | bump 351 | )] 352 | pub total_devoted: Account<'info, TotalDevoted>, 353 | 354 | pub system_program: Program<'info, System>, 355 | pub token_program: Program<'info, Token>, 356 | } 357 | 358 | #[derive(Accounts)] 359 | pub struct Waver<'info> { 360 | #[account(mut)] 361 | pub user: Signer<'info>, 362 | 363 | #[account( 364 | seeds = [b"state"], 365 | bump, 366 | constraint = stake_state.stake_mint == stake_mint.key(), 367 | )] 368 | pub stake_state: Account<'info, StakeState>, 369 | 370 | #[account( 371 | mut, 372 | seeds = [b"vault", user.key().as_ref()], 373 | bump, 374 | token::mint = stake_mint, 375 | token::authority = devoted, 376 | )] 377 | pub user_vault: Account<'info, TokenAccount>, 378 | 379 | #[account( 380 | mut, 381 | associated_token::mint = stake_mint, 382 | associated_token::authority = user, 383 | )] 384 | pub user_token_account: Account<'info, TokenAccount>, 385 | 386 | #[account(constraint = stake_state.stake_mint == stake_mint.key())] 387 | pub stake_mint: Account<'info, Mint>, 388 | 389 | #[account( 390 | mut, 391 | seeds = [b"devoted", user.key().as_ref()], 392 | bump, 393 | )] 394 | pub devoted: Account<'info, Devoted>, 395 | 396 | #[account( 397 | mut, 398 | seeds = [b"total_devoted"], 399 | bump, 400 | )] 401 | pub total_devoted: Account<'info, TotalDevoted>, 402 | 403 | pub token_program: Program<'info, Token>, 404 | pub system_program: Program<'info, System>, 405 | } 406 | 407 | #[derive(Accounts)] 408 | pub struct CheckDevotion<'info> { 409 | pub devoted: Account<'info, Devoted>, 410 | #[account( 411 | seeds = [b"state"], 412 | bump 413 | )] 414 | pub stake_state: Account<'info, StakeState>, 415 | } 416 | 417 | #[derive(Accounts)] 418 | pub struct Heresy<'info> { 419 | #[account(mut)] 420 | pub user: Signer<'info>, 421 | 422 | #[account( 423 | mut, 424 | seeds = [b"vault", user.key().as_ref()], 425 | bump, 426 | token::mint = stake_mint, 427 | token::authority = devoted, 428 | )] 429 | pub user_vault: Account<'info, TokenAccount>, 430 | 431 | #[account( 432 | mut, 433 | associated_token::mint = stake_mint, 434 | associated_token::authority = user, 435 | )] 436 | pub user_token_account: Account<'info, TokenAccount>, 437 | 438 | // maybe we need a stake mint constraint here like the other functions? 439 | pub stake_mint: Account<'info, Mint>, 440 | 441 | #[account( 442 | mut, 443 | seeds = [b"devoted", user.key().as_ref()], 444 | bump, 445 | close = user 446 | )] 447 | pub devoted: Account<'info, Devoted>, 448 | 449 | #[account( 450 | mut, 451 | seeds = [b"total_devoted"], 452 | bump, 453 | )] 454 | pub total_devoted: Account<'info, TotalDevoted>, 455 | 456 | pub token_program: Program<'info, Token>, 457 | pub system_program: Program<'info, System>, 458 | } 459 | 460 | // error codes 461 | #[error_code] 462 | pub enum ErrorCode { 463 | #[msg("Amount cannot be zero")] 464 | AmountZero, 465 | 466 | #[msg("Vault cannot be zero")] 467 | VaultZero, 468 | 469 | #[msg("Devotion cannot be zero")] 470 | DevotionZero, 471 | 472 | #[msg("Math operation overflow")] 473 | MathOverflow, 474 | 475 | #[msg("Math operation underflow")] 476 | MathUnderflow, 477 | 478 | #[msg("Insufficient funds for operation")] 479 | InsufficientFunds, 480 | 481 | #[msg("Division error")] 482 | DivError, 483 | 484 | #[msg("Invalid interval value")] 485 | InvalidInterval, 486 | 487 | #[msg("Invalid max devotion charge value")] 488 | InvalidMaxDevotionCharge, 489 | 490 | #[msg("Max devotion calculation would overflow")] 491 | MaxDevotionOverflow, 492 | } -------------------------------------------------------------------------------- /anchor/target/idl/devotion.json: -------------------------------------------------------------------------------- 1 | { 2 | "address": "GodsAfuZbVYY79KADVMe39ZwybWuL5U6RFLvyzUD5qgw", 3 | "metadata": { 4 | "name": "devotion", 5 | "version": "0.1.0", 6 | "spec": "0.1.0", 7 | "description": "Created with Anchor" 8 | }, 9 | "instructions": [ 10 | { 11 | "name": "check_devotion", 12 | "discriminator": [ 13 | 74, 14 | 218, 15 | 250, 16 | 114, 17 | 46, 18 | 175, 19 | 77, 20 | 119 21 | ], 22 | "accounts": [ 23 | { 24 | "name": "devoted" 25 | }, 26 | { 27 | "name": "stake_state", 28 | "pda": { 29 | "seeds": [ 30 | { 31 | "kind": "const", 32 | "value": [ 33 | 115, 34 | 116, 35 | 97, 36 | 116, 37 | 101 38 | ] 39 | } 40 | ] 41 | } 42 | } 43 | ], 44 | "args": [], 45 | "returns": "u128" 46 | }, 47 | { 48 | "name": "devote", 49 | "discriminator": [ 50 | 98, 51 | 206, 52 | 165, 53 | 170, 54 | 11, 55 | 114, 56 | 207, 57 | 225 58 | ], 59 | "accounts": [ 60 | { 61 | "name": "user", 62 | "writable": true, 63 | "signer": true 64 | }, 65 | { 66 | "name": "stake_state", 67 | "pda": { 68 | "seeds": [ 69 | { 70 | "kind": "const", 71 | "value": [ 72 | 115, 73 | 116, 74 | 97, 75 | 116, 76 | 101 77 | ] 78 | } 79 | ] 80 | } 81 | }, 82 | { 83 | "name": "user_vault", 84 | "writable": true, 85 | "pda": { 86 | "seeds": [ 87 | { 88 | "kind": "const", 89 | "value": [ 90 | 118, 91 | 97, 92 | 117, 93 | 108, 94 | 116 95 | ] 96 | }, 97 | { 98 | "kind": "account", 99 | "path": "user" 100 | } 101 | ] 102 | } 103 | }, 104 | { 105 | "name": "user_token_account", 106 | "writable": true, 107 | "pda": { 108 | "seeds": [ 109 | { 110 | "kind": "account", 111 | "path": "user" 112 | }, 113 | { 114 | "kind": "const", 115 | "value": [ 116 | 6, 117 | 221, 118 | 246, 119 | 225, 120 | 215, 121 | 101, 122 | 161, 123 | 147, 124 | 217, 125 | 203, 126 | 225, 127 | 70, 128 | 206, 129 | 235, 130 | 121, 131 | 172, 132 | 28, 133 | 180, 134 | 133, 135 | 237, 136 | 95, 137 | 91, 138 | 55, 139 | 145, 140 | 58, 141 | 140, 142 | 245, 143 | 133, 144 | 126, 145 | 255, 146 | 0, 147 | 169 148 | ] 149 | }, 150 | { 151 | "kind": "account", 152 | "path": "stake_mint" 153 | } 154 | ], 155 | "program": { 156 | "kind": "const", 157 | "value": [ 158 | 140, 159 | 151, 160 | 37, 161 | 143, 162 | 78, 163 | 36, 164 | 137, 165 | 241, 166 | 187, 167 | 61, 168 | 16, 169 | 41, 170 | 20, 171 | 142, 172 | 13, 173 | 131, 174 | 11, 175 | 90, 176 | 19, 177 | 153, 178 | 218, 179 | 255, 180 | 16, 181 | 132, 182 | 4, 183 | 142, 184 | 123, 185 | 216, 186 | 219, 187 | 233, 188 | 248, 189 | 89 190 | ] 191 | } 192 | } 193 | }, 194 | { 195 | "name": "stake_mint" 196 | }, 197 | { 198 | "name": "devoted", 199 | "writable": true, 200 | "pda": { 201 | "seeds": [ 202 | { 203 | "kind": "const", 204 | "value": [ 205 | 100, 206 | 101, 207 | 118, 208 | 111, 209 | 116, 210 | 101, 211 | 100 212 | ] 213 | }, 214 | { 215 | "kind": "account", 216 | "path": "user" 217 | } 218 | ] 219 | } 220 | }, 221 | { 222 | "name": "total_devoted", 223 | "writable": true, 224 | "pda": { 225 | "seeds": [ 226 | { 227 | "kind": "const", 228 | "value": [ 229 | 116, 230 | 111, 231 | 116, 232 | 97, 233 | 108, 234 | 95, 235 | 100, 236 | 101, 237 | 118, 238 | 111, 239 | 116, 240 | 101, 241 | 100 242 | ] 243 | } 244 | ] 245 | } 246 | }, 247 | { 248 | "name": "system_program", 249 | "address": "11111111111111111111111111111111" 250 | }, 251 | { 252 | "name": "token_program", 253 | "address": "TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA" 254 | } 255 | ], 256 | "args": [ 257 | { 258 | "name": "amount", 259 | "type": "u64" 260 | } 261 | ] 262 | }, 263 | { 264 | "name": "heresy", 265 | "discriminator": [ 266 | 121, 267 | 236, 268 | 39, 269 | 94, 270 | 176, 271 | 160, 272 | 223, 273 | 111 274 | ], 275 | "accounts": [ 276 | { 277 | "name": "user", 278 | "writable": true, 279 | "signer": true 280 | }, 281 | { 282 | "name": "user_vault", 283 | "writable": true, 284 | "pda": { 285 | "seeds": [ 286 | { 287 | "kind": "const", 288 | "value": [ 289 | 118, 290 | 97, 291 | 117, 292 | 108, 293 | 116 294 | ] 295 | }, 296 | { 297 | "kind": "account", 298 | "path": "user" 299 | } 300 | ] 301 | } 302 | }, 303 | { 304 | "name": "user_token_account", 305 | "writable": true, 306 | "pda": { 307 | "seeds": [ 308 | { 309 | "kind": "account", 310 | "path": "user" 311 | }, 312 | { 313 | "kind": "const", 314 | "value": [ 315 | 6, 316 | 221, 317 | 246, 318 | 225, 319 | 215, 320 | 101, 321 | 161, 322 | 147, 323 | 217, 324 | 203, 325 | 225, 326 | 70, 327 | 206, 328 | 235, 329 | 121, 330 | 172, 331 | 28, 332 | 180, 333 | 133, 334 | 237, 335 | 95, 336 | 91, 337 | 55, 338 | 145, 339 | 58, 340 | 140, 341 | 245, 342 | 133, 343 | 126, 344 | 255, 345 | 0, 346 | 169 347 | ] 348 | }, 349 | { 350 | "kind": "account", 351 | "path": "stake_mint" 352 | } 353 | ], 354 | "program": { 355 | "kind": "const", 356 | "value": [ 357 | 140, 358 | 151, 359 | 37, 360 | 143, 361 | 78, 362 | 36, 363 | 137, 364 | 241, 365 | 187, 366 | 61, 367 | 16, 368 | 41, 369 | 20, 370 | 142, 371 | 13, 372 | 131, 373 | 11, 374 | 90, 375 | 19, 376 | 153, 377 | 218, 378 | 255, 379 | 16, 380 | 132, 381 | 4, 382 | 142, 383 | 123, 384 | 216, 385 | 219, 386 | 233, 387 | 248, 388 | 89 389 | ] 390 | } 391 | } 392 | }, 393 | { 394 | "name": "stake_mint" 395 | }, 396 | { 397 | "name": "devoted", 398 | "writable": true, 399 | "pda": { 400 | "seeds": [ 401 | { 402 | "kind": "const", 403 | "value": [ 404 | 100, 405 | 101, 406 | 118, 407 | 111, 408 | 116, 409 | 101, 410 | 100 411 | ] 412 | }, 413 | { 414 | "kind": "account", 415 | "path": "user" 416 | } 417 | ] 418 | } 419 | }, 420 | { 421 | "name": "total_devoted", 422 | "writable": true, 423 | "pda": { 424 | "seeds": [ 425 | { 426 | "kind": "const", 427 | "value": [ 428 | 116, 429 | 111, 430 | 116, 431 | 97, 432 | 108, 433 | 95, 434 | 100, 435 | 101, 436 | 118, 437 | 111, 438 | 116, 439 | 101, 440 | 100 441 | ] 442 | } 443 | ] 444 | } 445 | }, 446 | { 447 | "name": "token_program", 448 | "address": "TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA" 449 | }, 450 | { 451 | "name": "system_program", 452 | "address": "11111111111111111111111111111111" 453 | } 454 | ], 455 | "args": [] 456 | }, 457 | { 458 | "name": "initialize", 459 | "discriminator": [ 460 | 175, 461 | 175, 462 | 109, 463 | 31, 464 | 13, 465 | 152, 466 | 155, 467 | 237 468 | ], 469 | "accounts": [ 470 | { 471 | "name": "admin", 472 | "writable": true, 473 | "signer": true 474 | }, 475 | { 476 | "name": "stake_mint" 477 | }, 478 | { 479 | "name": "stake_state", 480 | "writable": true, 481 | "pda": { 482 | "seeds": [ 483 | { 484 | "kind": "const", 485 | "value": [ 486 | 115, 487 | 116, 488 | 97, 489 | 116, 490 | 101 491 | ] 492 | } 493 | ] 494 | } 495 | }, 496 | { 497 | "name": "total_devoted", 498 | "writable": true, 499 | "pda": { 500 | "seeds": [ 501 | { 502 | "kind": "const", 503 | "value": [ 504 | 116, 505 | 111, 506 | 116, 507 | 97, 508 | 108, 509 | 95, 510 | 100, 511 | 101, 512 | 118, 513 | 111, 514 | 116, 515 | 101, 516 | 100 517 | ] 518 | } 519 | ] 520 | } 521 | }, 522 | { 523 | "name": "system_program", 524 | "address": "11111111111111111111111111111111" 525 | }, 526 | { 527 | "name": "rent", 528 | "address": "SysvarRent111111111111111111111111111111111" 529 | } 530 | ], 531 | "args": [ 532 | { 533 | "name": "interval", 534 | "type": "i64" 535 | }, 536 | { 537 | "name": "max_devotion_charge", 538 | "type": "i64" 539 | } 540 | ] 541 | }, 542 | { 543 | "name": "waver", 544 | "discriminator": [ 545 | 172, 546 | 77, 547 | 79, 548 | 212, 549 | 134, 550 | 152, 551 | 94, 552 | 187 553 | ], 554 | "accounts": [ 555 | { 556 | "name": "user", 557 | "writable": true, 558 | "signer": true 559 | }, 560 | { 561 | "name": "stake_state", 562 | "pda": { 563 | "seeds": [ 564 | { 565 | "kind": "const", 566 | "value": [ 567 | 115, 568 | 116, 569 | 97, 570 | 116, 571 | 101 572 | ] 573 | } 574 | ] 575 | } 576 | }, 577 | { 578 | "name": "user_vault", 579 | "writable": true, 580 | "pda": { 581 | "seeds": [ 582 | { 583 | "kind": "const", 584 | "value": [ 585 | 118, 586 | 97, 587 | 117, 588 | 108, 589 | 116 590 | ] 591 | }, 592 | { 593 | "kind": "account", 594 | "path": "user" 595 | } 596 | ] 597 | } 598 | }, 599 | { 600 | "name": "user_token_account", 601 | "writable": true, 602 | "pda": { 603 | "seeds": [ 604 | { 605 | "kind": "account", 606 | "path": "user" 607 | }, 608 | { 609 | "kind": "const", 610 | "value": [ 611 | 6, 612 | 221, 613 | 246, 614 | 225, 615 | 215, 616 | 101, 617 | 161, 618 | 147, 619 | 217, 620 | 203, 621 | 225, 622 | 70, 623 | 206, 624 | 235, 625 | 121, 626 | 172, 627 | 28, 628 | 180, 629 | 133, 630 | 237, 631 | 95, 632 | 91, 633 | 55, 634 | 145, 635 | 58, 636 | 140, 637 | 245, 638 | 133, 639 | 126, 640 | 255, 641 | 0, 642 | 169 643 | ] 644 | }, 645 | { 646 | "kind": "account", 647 | "path": "stake_mint" 648 | } 649 | ], 650 | "program": { 651 | "kind": "const", 652 | "value": [ 653 | 140, 654 | 151, 655 | 37, 656 | 143, 657 | 78, 658 | 36, 659 | 137, 660 | 241, 661 | 187, 662 | 61, 663 | 16, 664 | 41, 665 | 20, 666 | 142, 667 | 13, 668 | 131, 669 | 11, 670 | 90, 671 | 19, 672 | 153, 673 | 218, 674 | 255, 675 | 16, 676 | 132, 677 | 4, 678 | 142, 679 | 123, 680 | 216, 681 | 219, 682 | 233, 683 | 248, 684 | 89 685 | ] 686 | } 687 | } 688 | }, 689 | { 690 | "name": "stake_mint" 691 | }, 692 | { 693 | "name": "devoted", 694 | "writable": true, 695 | "pda": { 696 | "seeds": [ 697 | { 698 | "kind": "const", 699 | "value": [ 700 | 100, 701 | 101, 702 | 118, 703 | 111, 704 | 116, 705 | 101, 706 | 100 707 | ] 708 | }, 709 | { 710 | "kind": "account", 711 | "path": "user" 712 | } 713 | ] 714 | } 715 | }, 716 | { 717 | "name": "total_devoted", 718 | "writable": true, 719 | "pda": { 720 | "seeds": [ 721 | { 722 | "kind": "const", 723 | "value": [ 724 | 116, 725 | 111, 726 | 116, 727 | 97, 728 | 108, 729 | 95, 730 | 100, 731 | 101, 732 | 118, 733 | 111, 734 | 116, 735 | 101, 736 | 100 737 | ] 738 | } 739 | ] 740 | } 741 | }, 742 | { 743 | "name": "token_program", 744 | "address": "TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA" 745 | }, 746 | { 747 | "name": "system_program", 748 | "address": "11111111111111111111111111111111" 749 | } 750 | ], 751 | "args": [ 752 | { 753 | "name": "amount", 754 | "type": "u64" 755 | } 756 | ] 757 | } 758 | ], 759 | "accounts": [ 760 | { 761 | "name": "Devoted", 762 | "discriminator": [ 763 | 138, 764 | 234, 765 | 229, 766 | 80, 767 | 235, 768 | 129, 769 | 125, 770 | 103 771 | ] 772 | }, 773 | { 774 | "name": "StakeState", 775 | "discriminator": [ 776 | 108, 777 | 10, 778 | 236, 779 | 72, 780 | 1, 781 | 88, 782 | 133, 783 | 92 784 | ] 785 | }, 786 | { 787 | "name": "TotalDevoted", 788 | "discriminator": [ 789 | 205, 790 | 57, 791 | 85, 792 | 213, 793 | 154, 794 | 119, 795 | 102, 796 | 238 797 | ] 798 | } 799 | ], 800 | "errors": [ 801 | { 802 | "code": 6000, 803 | "name": "AmountZero", 804 | "msg": "Amount cannot be zero" 805 | }, 806 | { 807 | "code": 6001, 808 | "name": "VaultZero", 809 | "msg": "Vault cannot be zero" 810 | }, 811 | { 812 | "code": 6002, 813 | "name": "DevotionZero", 814 | "msg": "Devotion cannot be zero" 815 | }, 816 | { 817 | "code": 6003, 818 | "name": "MathOverflow", 819 | "msg": "Math operation overflow" 820 | }, 821 | { 822 | "code": 6004, 823 | "name": "MathUnderflow", 824 | "msg": "Math operation underflow" 825 | }, 826 | { 827 | "code": 6005, 828 | "name": "InsufficientFunds", 829 | "msg": "Insufficient funds for operation" 830 | }, 831 | { 832 | "code": 6006, 833 | "name": "DivError", 834 | "msg": "Division error" 835 | }, 836 | { 837 | "code": 6007, 838 | "name": "InvalidInterval", 839 | "msg": "Invalid interval value" 840 | }, 841 | { 842 | "code": 6008, 843 | "name": "InvalidMaxDevotionCharge", 844 | "msg": "Invalid max devotion charge value" 845 | }, 846 | { 847 | "code": 6009, 848 | "name": "MaxDevotionOverflow", 849 | "msg": "Max devotion calculation would overflow" 850 | } 851 | ], 852 | "types": [ 853 | { 854 | "name": "Devoted", 855 | "type": { 856 | "kind": "struct", 857 | "fields": [ 858 | { 859 | "name": "user", 860 | "type": "pubkey" 861 | }, 862 | { 863 | "name": "amount", 864 | "type": "u64" 865 | }, 866 | { 867 | "name": "residual_devotion", 868 | "type": "u128" 869 | }, 870 | { 871 | "name": "last_stake_timestamp", 872 | "type": "i64" 873 | }, 874 | { 875 | "name": "bump", 876 | "type": "u8" 877 | } 878 | ] 879 | } 880 | }, 881 | { 882 | "name": "StakeState", 883 | "type": { 884 | "kind": "struct", 885 | "fields": [ 886 | { 887 | "name": "admin", 888 | "type": "pubkey" 889 | }, 890 | { 891 | "name": "stake_mint", 892 | "type": "pubkey" 893 | }, 894 | { 895 | "name": "interval", 896 | "type": "i64" 897 | }, 898 | { 899 | "name": "max_devotion_charge", 900 | "type": "i64" 901 | }, 902 | { 903 | "name": "decimals", 904 | "type": "u8" 905 | } 906 | ] 907 | } 908 | }, 909 | { 910 | "name": "TotalDevoted", 911 | "type": { 912 | "kind": "struct", 913 | "fields": [ 914 | { 915 | "name": "total_tokens", 916 | "type": "u64" 917 | } 918 | ] 919 | } 920 | } 921 | ] 922 | } -------------------------------------------------------------------------------- /anchor/target/types/devotion.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Program IDL in camelCase format in order to be used in JS/TS. 3 | * 4 | * Note that this is only a type helper and is not the actual IDL. The original 5 | * IDL can be found at `target/idl/devotion.json`. 6 | */ 7 | export type Devotion = { 8 | "address": "GodsAfuZbVYY79KADVMe39ZwybWuL5U6RFLvyzUD5qgw", 9 | "metadata": { 10 | "name": "devotion", 11 | "version": "0.1.0", 12 | "spec": "0.1.0", 13 | "description": "Created with Anchor" 14 | }, 15 | "instructions": [ 16 | { 17 | "name": "checkDevotion", 18 | "discriminator": [ 19 | 74, 20 | 218, 21 | 250, 22 | 114, 23 | 46, 24 | 175, 25 | 77, 26 | 119 27 | ], 28 | "accounts": [ 29 | { 30 | "name": "devoted" 31 | }, 32 | { 33 | "name": "stakeState", 34 | "pda": { 35 | "seeds": [ 36 | { 37 | "kind": "const", 38 | "value": [ 39 | 115, 40 | 116, 41 | 97, 42 | 116, 43 | 101 44 | ] 45 | } 46 | ] 47 | } 48 | } 49 | ], 50 | "args": [], 51 | "returns": "u128" 52 | }, 53 | { 54 | "name": "devote", 55 | "discriminator": [ 56 | 98, 57 | 206, 58 | 165, 59 | 170, 60 | 11, 61 | 114, 62 | 207, 63 | 225 64 | ], 65 | "accounts": [ 66 | { 67 | "name": "user", 68 | "writable": true, 69 | "signer": true 70 | }, 71 | { 72 | "name": "stakeState", 73 | "pda": { 74 | "seeds": [ 75 | { 76 | "kind": "const", 77 | "value": [ 78 | 115, 79 | 116, 80 | 97, 81 | 116, 82 | 101 83 | ] 84 | } 85 | ] 86 | } 87 | }, 88 | { 89 | "name": "userVault", 90 | "writable": true, 91 | "pda": { 92 | "seeds": [ 93 | { 94 | "kind": "const", 95 | "value": [ 96 | 118, 97 | 97, 98 | 117, 99 | 108, 100 | 116 101 | ] 102 | }, 103 | { 104 | "kind": "account", 105 | "path": "user" 106 | } 107 | ] 108 | } 109 | }, 110 | { 111 | "name": "userTokenAccount", 112 | "writable": true, 113 | "pda": { 114 | "seeds": [ 115 | { 116 | "kind": "account", 117 | "path": "user" 118 | }, 119 | { 120 | "kind": "const", 121 | "value": [ 122 | 6, 123 | 221, 124 | 246, 125 | 225, 126 | 215, 127 | 101, 128 | 161, 129 | 147, 130 | 217, 131 | 203, 132 | 225, 133 | 70, 134 | 206, 135 | 235, 136 | 121, 137 | 172, 138 | 28, 139 | 180, 140 | 133, 141 | 237, 142 | 95, 143 | 91, 144 | 55, 145 | 145, 146 | 58, 147 | 140, 148 | 245, 149 | 133, 150 | 126, 151 | 255, 152 | 0, 153 | 169 154 | ] 155 | }, 156 | { 157 | "kind": "account", 158 | "path": "stakeMint" 159 | } 160 | ], 161 | "program": { 162 | "kind": "const", 163 | "value": [ 164 | 140, 165 | 151, 166 | 37, 167 | 143, 168 | 78, 169 | 36, 170 | 137, 171 | 241, 172 | 187, 173 | 61, 174 | 16, 175 | 41, 176 | 20, 177 | 142, 178 | 13, 179 | 131, 180 | 11, 181 | 90, 182 | 19, 183 | 153, 184 | 218, 185 | 255, 186 | 16, 187 | 132, 188 | 4, 189 | 142, 190 | 123, 191 | 216, 192 | 219, 193 | 233, 194 | 248, 195 | 89 196 | ] 197 | } 198 | } 199 | }, 200 | { 201 | "name": "stakeMint" 202 | }, 203 | { 204 | "name": "devoted", 205 | "writable": true, 206 | "pda": { 207 | "seeds": [ 208 | { 209 | "kind": "const", 210 | "value": [ 211 | 100, 212 | 101, 213 | 118, 214 | 111, 215 | 116, 216 | 101, 217 | 100 218 | ] 219 | }, 220 | { 221 | "kind": "account", 222 | "path": "user" 223 | } 224 | ] 225 | } 226 | }, 227 | { 228 | "name": "totalDevoted", 229 | "writable": true, 230 | "pda": { 231 | "seeds": [ 232 | { 233 | "kind": "const", 234 | "value": [ 235 | 116, 236 | 111, 237 | 116, 238 | 97, 239 | 108, 240 | 95, 241 | 100, 242 | 101, 243 | 118, 244 | 111, 245 | 116, 246 | 101, 247 | 100 248 | ] 249 | } 250 | ] 251 | } 252 | }, 253 | { 254 | "name": "systemProgram", 255 | "address": "11111111111111111111111111111111" 256 | }, 257 | { 258 | "name": "tokenProgram", 259 | "address": "TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA" 260 | } 261 | ], 262 | "args": [ 263 | { 264 | "name": "amount", 265 | "type": "u64" 266 | } 267 | ] 268 | }, 269 | { 270 | "name": "heresy", 271 | "discriminator": [ 272 | 121, 273 | 236, 274 | 39, 275 | 94, 276 | 176, 277 | 160, 278 | 223, 279 | 111 280 | ], 281 | "accounts": [ 282 | { 283 | "name": "user", 284 | "writable": true, 285 | "signer": true 286 | }, 287 | { 288 | "name": "userVault", 289 | "writable": true, 290 | "pda": { 291 | "seeds": [ 292 | { 293 | "kind": "const", 294 | "value": [ 295 | 118, 296 | 97, 297 | 117, 298 | 108, 299 | 116 300 | ] 301 | }, 302 | { 303 | "kind": "account", 304 | "path": "user" 305 | } 306 | ] 307 | } 308 | }, 309 | { 310 | "name": "userTokenAccount", 311 | "writable": true, 312 | "pda": { 313 | "seeds": [ 314 | { 315 | "kind": "account", 316 | "path": "user" 317 | }, 318 | { 319 | "kind": "const", 320 | "value": [ 321 | 6, 322 | 221, 323 | 246, 324 | 225, 325 | 215, 326 | 101, 327 | 161, 328 | 147, 329 | 217, 330 | 203, 331 | 225, 332 | 70, 333 | 206, 334 | 235, 335 | 121, 336 | 172, 337 | 28, 338 | 180, 339 | 133, 340 | 237, 341 | 95, 342 | 91, 343 | 55, 344 | 145, 345 | 58, 346 | 140, 347 | 245, 348 | 133, 349 | 126, 350 | 255, 351 | 0, 352 | 169 353 | ] 354 | }, 355 | { 356 | "kind": "account", 357 | "path": "stakeMint" 358 | } 359 | ], 360 | "program": { 361 | "kind": "const", 362 | "value": [ 363 | 140, 364 | 151, 365 | 37, 366 | 143, 367 | 78, 368 | 36, 369 | 137, 370 | 241, 371 | 187, 372 | 61, 373 | 16, 374 | 41, 375 | 20, 376 | 142, 377 | 13, 378 | 131, 379 | 11, 380 | 90, 381 | 19, 382 | 153, 383 | 218, 384 | 255, 385 | 16, 386 | 132, 387 | 4, 388 | 142, 389 | 123, 390 | 216, 391 | 219, 392 | 233, 393 | 248, 394 | 89 395 | ] 396 | } 397 | } 398 | }, 399 | { 400 | "name": "stakeMint" 401 | }, 402 | { 403 | "name": "devoted", 404 | "writable": true, 405 | "pda": { 406 | "seeds": [ 407 | { 408 | "kind": "const", 409 | "value": [ 410 | 100, 411 | 101, 412 | 118, 413 | 111, 414 | 116, 415 | 101, 416 | 100 417 | ] 418 | }, 419 | { 420 | "kind": "account", 421 | "path": "user" 422 | } 423 | ] 424 | } 425 | }, 426 | { 427 | "name": "totalDevoted", 428 | "writable": true, 429 | "pda": { 430 | "seeds": [ 431 | { 432 | "kind": "const", 433 | "value": [ 434 | 116, 435 | 111, 436 | 116, 437 | 97, 438 | 108, 439 | 95, 440 | 100, 441 | 101, 442 | 118, 443 | 111, 444 | 116, 445 | 101, 446 | 100 447 | ] 448 | } 449 | ] 450 | } 451 | }, 452 | { 453 | "name": "tokenProgram", 454 | "address": "TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA" 455 | }, 456 | { 457 | "name": "systemProgram", 458 | "address": "11111111111111111111111111111111" 459 | } 460 | ], 461 | "args": [] 462 | }, 463 | { 464 | "name": "initialize", 465 | "discriminator": [ 466 | 175, 467 | 175, 468 | 109, 469 | 31, 470 | 13, 471 | 152, 472 | 155, 473 | 237 474 | ], 475 | "accounts": [ 476 | { 477 | "name": "admin", 478 | "writable": true, 479 | "signer": true 480 | }, 481 | { 482 | "name": "stakeMint" 483 | }, 484 | { 485 | "name": "stakeState", 486 | "writable": true, 487 | "pda": { 488 | "seeds": [ 489 | { 490 | "kind": "const", 491 | "value": [ 492 | 115, 493 | 116, 494 | 97, 495 | 116, 496 | 101 497 | ] 498 | } 499 | ] 500 | } 501 | }, 502 | { 503 | "name": "totalDevoted", 504 | "writable": true, 505 | "pda": { 506 | "seeds": [ 507 | { 508 | "kind": "const", 509 | "value": [ 510 | 116, 511 | 111, 512 | 116, 513 | 97, 514 | 108, 515 | 95, 516 | 100, 517 | 101, 518 | 118, 519 | 111, 520 | 116, 521 | 101, 522 | 100 523 | ] 524 | } 525 | ] 526 | } 527 | }, 528 | { 529 | "name": "systemProgram", 530 | "address": "11111111111111111111111111111111" 531 | }, 532 | { 533 | "name": "rent", 534 | "address": "SysvarRent111111111111111111111111111111111" 535 | } 536 | ], 537 | "args": [ 538 | { 539 | "name": "interval", 540 | "type": "i64" 541 | }, 542 | { 543 | "name": "maxDevotionCharge", 544 | "type": "i64" 545 | } 546 | ] 547 | }, 548 | { 549 | "name": "waver", 550 | "discriminator": [ 551 | 172, 552 | 77, 553 | 79, 554 | 212, 555 | 134, 556 | 152, 557 | 94, 558 | 187 559 | ], 560 | "accounts": [ 561 | { 562 | "name": "user", 563 | "writable": true, 564 | "signer": true 565 | }, 566 | { 567 | "name": "stakeState", 568 | "pda": { 569 | "seeds": [ 570 | { 571 | "kind": "const", 572 | "value": [ 573 | 115, 574 | 116, 575 | 97, 576 | 116, 577 | 101 578 | ] 579 | } 580 | ] 581 | } 582 | }, 583 | { 584 | "name": "userVault", 585 | "writable": true, 586 | "pda": { 587 | "seeds": [ 588 | { 589 | "kind": "const", 590 | "value": [ 591 | 118, 592 | 97, 593 | 117, 594 | 108, 595 | 116 596 | ] 597 | }, 598 | { 599 | "kind": "account", 600 | "path": "user" 601 | } 602 | ] 603 | } 604 | }, 605 | { 606 | "name": "userTokenAccount", 607 | "writable": true, 608 | "pda": { 609 | "seeds": [ 610 | { 611 | "kind": "account", 612 | "path": "user" 613 | }, 614 | { 615 | "kind": "const", 616 | "value": [ 617 | 6, 618 | 221, 619 | 246, 620 | 225, 621 | 215, 622 | 101, 623 | 161, 624 | 147, 625 | 217, 626 | 203, 627 | 225, 628 | 70, 629 | 206, 630 | 235, 631 | 121, 632 | 172, 633 | 28, 634 | 180, 635 | 133, 636 | 237, 637 | 95, 638 | 91, 639 | 55, 640 | 145, 641 | 58, 642 | 140, 643 | 245, 644 | 133, 645 | 126, 646 | 255, 647 | 0, 648 | 169 649 | ] 650 | }, 651 | { 652 | "kind": "account", 653 | "path": "stakeMint" 654 | } 655 | ], 656 | "program": { 657 | "kind": "const", 658 | "value": [ 659 | 140, 660 | 151, 661 | 37, 662 | 143, 663 | 78, 664 | 36, 665 | 137, 666 | 241, 667 | 187, 668 | 61, 669 | 16, 670 | 41, 671 | 20, 672 | 142, 673 | 13, 674 | 131, 675 | 11, 676 | 90, 677 | 19, 678 | 153, 679 | 218, 680 | 255, 681 | 16, 682 | 132, 683 | 4, 684 | 142, 685 | 123, 686 | 216, 687 | 219, 688 | 233, 689 | 248, 690 | 89 691 | ] 692 | } 693 | } 694 | }, 695 | { 696 | "name": "stakeMint" 697 | }, 698 | { 699 | "name": "devoted", 700 | "writable": true, 701 | "pda": { 702 | "seeds": [ 703 | { 704 | "kind": "const", 705 | "value": [ 706 | 100, 707 | 101, 708 | 118, 709 | 111, 710 | 116, 711 | 101, 712 | 100 713 | ] 714 | }, 715 | { 716 | "kind": "account", 717 | "path": "user" 718 | } 719 | ] 720 | } 721 | }, 722 | { 723 | "name": "totalDevoted", 724 | "writable": true, 725 | "pda": { 726 | "seeds": [ 727 | { 728 | "kind": "const", 729 | "value": [ 730 | 116, 731 | 111, 732 | 116, 733 | 97, 734 | 108, 735 | 95, 736 | 100, 737 | 101, 738 | 118, 739 | 111, 740 | 116, 741 | 101, 742 | 100 743 | ] 744 | } 745 | ] 746 | } 747 | }, 748 | { 749 | "name": "tokenProgram", 750 | "address": "TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA" 751 | }, 752 | { 753 | "name": "systemProgram", 754 | "address": "11111111111111111111111111111111" 755 | } 756 | ], 757 | "args": [ 758 | { 759 | "name": "amount", 760 | "type": "u64" 761 | } 762 | ] 763 | } 764 | ], 765 | "accounts": [ 766 | { 767 | "name": "devoted", 768 | "discriminator": [ 769 | 138, 770 | 234, 771 | 229, 772 | 80, 773 | 235, 774 | 129, 775 | 125, 776 | 103 777 | ] 778 | }, 779 | { 780 | "name": "stakeState", 781 | "discriminator": [ 782 | 108, 783 | 10, 784 | 236, 785 | 72, 786 | 1, 787 | 88, 788 | 133, 789 | 92 790 | ] 791 | }, 792 | { 793 | "name": "totalDevoted", 794 | "discriminator": [ 795 | 205, 796 | 57, 797 | 85, 798 | 213, 799 | 154, 800 | 119, 801 | 102, 802 | 238 803 | ] 804 | } 805 | ], 806 | "errors": [ 807 | { 808 | "code": 6000, 809 | "name": "amountZero", 810 | "msg": "Amount cannot be zero" 811 | }, 812 | { 813 | "code": 6001, 814 | "name": "vaultZero", 815 | "msg": "Vault cannot be zero" 816 | }, 817 | { 818 | "code": 6002, 819 | "name": "devotionZero", 820 | "msg": "Devotion cannot be zero" 821 | }, 822 | { 823 | "code": 6003, 824 | "name": "mathOverflow", 825 | "msg": "Math operation overflow" 826 | }, 827 | { 828 | "code": 6004, 829 | "name": "mathUnderflow", 830 | "msg": "Math operation underflow" 831 | }, 832 | { 833 | "code": 6005, 834 | "name": "insufficientFunds", 835 | "msg": "Insufficient funds for operation" 836 | }, 837 | { 838 | "code": 6006, 839 | "name": "divError", 840 | "msg": "Division error" 841 | }, 842 | { 843 | "code": 6007, 844 | "name": "invalidInterval", 845 | "msg": "Invalid interval value" 846 | }, 847 | { 848 | "code": 6008, 849 | "name": "invalidMaxDevotionCharge", 850 | "msg": "Invalid max devotion charge value" 851 | }, 852 | { 853 | "code": 6009, 854 | "name": "maxDevotionOverflow", 855 | "msg": "Max devotion calculation would overflow" 856 | } 857 | ], 858 | "types": [ 859 | { 860 | "name": "devoted", 861 | "type": { 862 | "kind": "struct", 863 | "fields": [ 864 | { 865 | "name": "user", 866 | "type": "pubkey" 867 | }, 868 | { 869 | "name": "amount", 870 | "type": "u64" 871 | }, 872 | { 873 | "name": "residualDevotion", 874 | "type": "u128" 875 | }, 876 | { 877 | "name": "lastStakeTimestamp", 878 | "type": "i64" 879 | }, 880 | { 881 | "name": "bump", 882 | "type": "u8" 883 | } 884 | ] 885 | } 886 | }, 887 | { 888 | "name": "stakeState", 889 | "type": { 890 | "kind": "struct", 891 | "fields": [ 892 | { 893 | "name": "admin", 894 | "type": "pubkey" 895 | }, 896 | { 897 | "name": "stakeMint", 898 | "type": "pubkey" 899 | }, 900 | { 901 | "name": "interval", 902 | "type": "i64" 903 | }, 904 | { 905 | "name": "maxDevotionCharge", 906 | "type": "i64" 907 | }, 908 | { 909 | "name": "decimals", 910 | "type": "u8" 911 | } 912 | ] 913 | } 914 | }, 915 | { 916 | "name": "totalDevoted", 917 | "type": { 918 | "kind": "struct", 919 | "fields": [ 920 | { 921 | "name": "totalTokens", 922 | "type": "u64" 923 | } 924 | ] 925 | } 926 | } 927 | ] 928 | }; 929 | -------------------------------------------------------------------------------- /anchor/Cargo.lock: -------------------------------------------------------------------------------- 1 | # This file is automatically @generated by Cargo. 2 | # It is not intended for manual editing. 3 | version = 3 4 | 5 | [[package]] 6 | name = "aead" 7 | version = "0.4.3" 8 | source = "registry+https://github.com/rust-lang/crates.io-index" 9 | checksum = "0b613b8e1e3cf911a086f53f03bf286f52fd7a7258e4fa606f0ef220d39d8877" 10 | dependencies = [ 11 | "generic-array", 12 | ] 13 | 14 | [[package]] 15 | name = "aes" 16 | version = "0.7.5" 17 | source = "registry+https://github.com/rust-lang/crates.io-index" 18 | checksum = "9e8b47f52ea9bae42228d07ec09eb676433d7c4ed1ebdf0f1d1c29ed446f1ab8" 19 | dependencies = [ 20 | "cfg-if", 21 | "cipher", 22 | "cpufeatures", 23 | "opaque-debug", 24 | ] 25 | 26 | [[package]] 27 | name = "aes-gcm-siv" 28 | version = "0.10.3" 29 | source = "registry+https://github.com/rust-lang/crates.io-index" 30 | checksum = "589c637f0e68c877bbd59a4599bbe849cac8e5f3e4b5a3ebae8f528cd218dcdc" 31 | dependencies = [ 32 | "aead", 33 | "aes", 34 | "cipher", 35 | "ctr", 36 | "polyval", 37 | "subtle", 38 | "zeroize", 39 | ] 40 | 41 | [[package]] 42 | name = "ahash" 43 | version = "0.7.8" 44 | source = "registry+https://github.com/rust-lang/crates.io-index" 45 | checksum = "891477e0c6a8957309ee5c45a6368af3ae14bb510732d2684ffa19af310920f9" 46 | dependencies = [ 47 | "getrandom 0.2.15", 48 | "once_cell", 49 | "version_check", 50 | ] 51 | 52 | [[package]] 53 | name = "ahash" 54 | version = "0.8.11" 55 | source = "registry+https://github.com/rust-lang/crates.io-index" 56 | checksum = "e89da841a80418a9b391ebaea17f5c112ffaaa96f621d2c285b5174da76b9011" 57 | dependencies = [ 58 | "cfg-if", 59 | "once_cell", 60 | "version_check", 61 | "zerocopy", 62 | ] 63 | 64 | [[package]] 65 | name = "aho-corasick" 66 | version = "1.1.3" 67 | source = "registry+https://github.com/rust-lang/crates.io-index" 68 | checksum = "8e60d3430d3a69478ad0993f19238d2df97c507009a52b3c10addcd7f6bcb916" 69 | dependencies = [ 70 | "memchr", 71 | ] 72 | 73 | [[package]] 74 | name = "anchor-attribute-access-control" 75 | version = "0.30.1" 76 | source = "registry+https://github.com/rust-lang/crates.io-index" 77 | checksum = "47fe28365b33e8334dd70ae2f34a43892363012fe239cf37d2ee91693575b1f8" 78 | dependencies = [ 79 | "anchor-syn", 80 | "proc-macro2", 81 | "quote", 82 | "syn 1.0.109", 83 | ] 84 | 85 | [[package]] 86 | name = "anchor-attribute-account" 87 | version = "0.30.1" 88 | source = "registry+https://github.com/rust-lang/crates.io-index" 89 | checksum = "3c288d496168268d198d9b53ee9f4f9d260a55ba4df9877ea1d4486ad6109e0f" 90 | dependencies = [ 91 | "anchor-syn", 92 | "bs58 0.5.1", 93 | "proc-macro2", 94 | "quote", 95 | "syn 1.0.109", 96 | ] 97 | 98 | [[package]] 99 | name = "anchor-attribute-constant" 100 | version = "0.30.1" 101 | source = "registry+https://github.com/rust-lang/crates.io-index" 102 | checksum = "49b77b6948d0eeaaa129ce79eea5bbbb9937375a9241d909ca8fb9e006bb6e90" 103 | dependencies = [ 104 | "anchor-syn", 105 | "quote", 106 | "syn 1.0.109", 107 | ] 108 | 109 | [[package]] 110 | name = "anchor-attribute-error" 111 | version = "0.30.1" 112 | source = "registry+https://github.com/rust-lang/crates.io-index" 113 | checksum = "4d20bb569c5a557c86101b944721d865e1fd0a4c67c381d31a44a84f07f84828" 114 | dependencies = [ 115 | "anchor-syn", 116 | "quote", 117 | "syn 1.0.109", 118 | ] 119 | 120 | [[package]] 121 | name = "anchor-attribute-event" 122 | version = "0.30.1" 123 | source = "registry+https://github.com/rust-lang/crates.io-index" 124 | checksum = "4cebd8d0671a3a9dc3160c48598d652c34c77de6be4d44345b8b514323284d57" 125 | dependencies = [ 126 | "anchor-syn", 127 | "proc-macro2", 128 | "quote", 129 | "syn 1.0.109", 130 | ] 131 | 132 | [[package]] 133 | name = "anchor-attribute-program" 134 | version = "0.30.1" 135 | source = "registry+https://github.com/rust-lang/crates.io-index" 136 | checksum = "efb2a5eb0860e661ab31aff7bb5e0288357b176380e985bade4ccb395981b42d" 137 | dependencies = [ 138 | "anchor-lang-idl", 139 | "anchor-syn", 140 | "anyhow", 141 | "bs58 0.5.1", 142 | "heck", 143 | "proc-macro2", 144 | "quote", 145 | "serde_json", 146 | "syn 1.0.109", 147 | ] 148 | 149 | [[package]] 150 | name = "anchor-derive-accounts" 151 | version = "0.30.1" 152 | source = "registry+https://github.com/rust-lang/crates.io-index" 153 | checksum = "04368b5abef4266250ca8d1d12f4dff860242681e4ec22b885dcfe354fd35aa1" 154 | dependencies = [ 155 | "anchor-syn", 156 | "quote", 157 | "syn 1.0.109", 158 | ] 159 | 160 | [[package]] 161 | name = "anchor-derive-serde" 162 | version = "0.30.1" 163 | source = "registry+https://github.com/rust-lang/crates.io-index" 164 | checksum = "e0bb0e0911ad4a70cab880cdd6287fe1e880a1a9d8e4e6defa8e9044b9796a6c" 165 | dependencies = [ 166 | "anchor-syn", 167 | "borsh-derive-internal 0.10.3", 168 | "proc-macro2", 169 | "quote", 170 | "syn 1.0.109", 171 | ] 172 | 173 | [[package]] 174 | name = "anchor-derive-space" 175 | version = "0.30.1" 176 | source = "registry+https://github.com/rust-lang/crates.io-index" 177 | checksum = "5ef415ff156dc82e9ecb943189b0cb241b3a6bfc26a180234dc21bd3ef3ce0cb" 178 | dependencies = [ 179 | "proc-macro2", 180 | "quote", 181 | "syn 1.0.109", 182 | ] 183 | 184 | [[package]] 185 | name = "anchor-lang" 186 | version = "0.30.1" 187 | source = "registry+https://github.com/rust-lang/crates.io-index" 188 | checksum = "6620c9486d9d36a4389cab5e37dc34a42ed0bfaa62e6a75a2999ce98f8f2e373" 189 | dependencies = [ 190 | "anchor-attribute-access-control", 191 | "anchor-attribute-account", 192 | "anchor-attribute-constant", 193 | "anchor-attribute-error", 194 | "anchor-attribute-event", 195 | "anchor-attribute-program", 196 | "anchor-derive-accounts", 197 | "anchor-derive-serde", 198 | "anchor-derive-space", 199 | "anchor-lang-idl", 200 | "arrayref", 201 | "base64 0.21.7", 202 | "bincode", 203 | "borsh 0.10.3", 204 | "bytemuck", 205 | "getrandom 0.2.15", 206 | "solana-program", 207 | "thiserror", 208 | ] 209 | 210 | [[package]] 211 | name = "anchor-lang-idl" 212 | version = "0.1.1" 213 | source = "registry+https://github.com/rust-lang/crates.io-index" 214 | checksum = "31cf97b4e6f7d6144a05e435660fcf757dbc3446d38d0e2b851d11ed13625bba" 215 | dependencies = [ 216 | "anchor-lang-idl-spec", 217 | "anyhow", 218 | "heck", 219 | "regex", 220 | "serde", 221 | "serde_json", 222 | "sha2 0.10.8", 223 | ] 224 | 225 | [[package]] 226 | name = "anchor-lang-idl-spec" 227 | version = "0.1.0" 228 | source = "registry+https://github.com/rust-lang/crates.io-index" 229 | checksum = "2bdf143115440fe621bdac3a29a1f7472e09f6cd82b2aa569429a0c13f103838" 230 | dependencies = [ 231 | "anyhow", 232 | "serde", 233 | ] 234 | 235 | [[package]] 236 | name = "anchor-spl" 237 | version = "0.30.1" 238 | source = "registry+https://github.com/rust-lang/crates.io-index" 239 | checksum = "04bd077c34449319a1e4e0bc21cea572960c9ae0d0fefda0dd7c52fcc3c647a3" 240 | dependencies = [ 241 | "anchor-lang", 242 | "spl-associated-token-account", 243 | "spl-pod", 244 | "spl-token", 245 | "spl-token-2022", 246 | "spl-token-group-interface", 247 | "spl-token-metadata-interface", 248 | ] 249 | 250 | [[package]] 251 | name = "anchor-syn" 252 | version = "0.30.1" 253 | source = "registry+https://github.com/rust-lang/crates.io-index" 254 | checksum = "f99daacb53b55cfd37ce14d6c9905929721137fd4c67bbab44a19802aecb622f" 255 | dependencies = [ 256 | "anyhow", 257 | "bs58 0.5.1", 258 | "cargo_toml", 259 | "heck", 260 | "proc-macro2", 261 | "quote", 262 | "serde", 263 | "serde_json", 264 | "sha2 0.10.8", 265 | "syn 1.0.109", 266 | "thiserror", 267 | ] 268 | 269 | [[package]] 270 | name = "anyhow" 271 | version = "1.0.86" 272 | source = "registry+https://github.com/rust-lang/crates.io-index" 273 | checksum = "b3d1d046238990b9cf5bcde22a3fb3584ee5cf65fb2765f454ed428c7a0063da" 274 | 275 | [[package]] 276 | name = "ark-bn254" 277 | version = "0.4.0" 278 | source = "registry+https://github.com/rust-lang/crates.io-index" 279 | checksum = "a22f4561524cd949590d78d7d4c5df8f592430d221f7f3c9497bbafd8972120f" 280 | dependencies = [ 281 | "ark-ec", 282 | "ark-ff", 283 | "ark-std", 284 | ] 285 | 286 | [[package]] 287 | name = "ark-ec" 288 | version = "0.4.2" 289 | source = "registry+https://github.com/rust-lang/crates.io-index" 290 | checksum = "defd9a439d56ac24968cca0571f598a61bc8c55f71d50a89cda591cb750670ba" 291 | dependencies = [ 292 | "ark-ff", 293 | "ark-poly", 294 | "ark-serialize", 295 | "ark-std", 296 | "derivative", 297 | "hashbrown 0.13.2", 298 | "itertools", 299 | "num-traits", 300 | "zeroize", 301 | ] 302 | 303 | [[package]] 304 | name = "ark-ff" 305 | version = "0.4.2" 306 | source = "registry+https://github.com/rust-lang/crates.io-index" 307 | checksum = "ec847af850f44ad29048935519032c33da8aa03340876d351dfab5660d2966ba" 308 | dependencies = [ 309 | "ark-ff-asm", 310 | "ark-ff-macros", 311 | "ark-serialize", 312 | "ark-std", 313 | "derivative", 314 | "digest 0.10.7", 315 | "itertools", 316 | "num-bigint", 317 | "num-traits", 318 | "paste", 319 | "rustc_version", 320 | "zeroize", 321 | ] 322 | 323 | [[package]] 324 | name = "ark-ff-asm" 325 | version = "0.4.2" 326 | source = "registry+https://github.com/rust-lang/crates.io-index" 327 | checksum = "3ed4aa4fe255d0bc6d79373f7e31d2ea147bcf486cba1be5ba7ea85abdb92348" 328 | dependencies = [ 329 | "quote", 330 | "syn 1.0.109", 331 | ] 332 | 333 | [[package]] 334 | name = "ark-ff-macros" 335 | version = "0.4.2" 336 | source = "registry+https://github.com/rust-lang/crates.io-index" 337 | checksum = "7abe79b0e4288889c4574159ab790824d0033b9fdcb2a112a3182fac2e514565" 338 | dependencies = [ 339 | "num-bigint", 340 | "num-traits", 341 | "proc-macro2", 342 | "quote", 343 | "syn 1.0.109", 344 | ] 345 | 346 | [[package]] 347 | name = "ark-poly" 348 | version = "0.4.2" 349 | source = "registry+https://github.com/rust-lang/crates.io-index" 350 | checksum = "d320bfc44ee185d899ccbadfa8bc31aab923ce1558716e1997a1e74057fe86bf" 351 | dependencies = [ 352 | "ark-ff", 353 | "ark-serialize", 354 | "ark-std", 355 | "derivative", 356 | "hashbrown 0.13.2", 357 | ] 358 | 359 | [[package]] 360 | name = "ark-serialize" 361 | version = "0.4.2" 362 | source = "registry+https://github.com/rust-lang/crates.io-index" 363 | checksum = "adb7b85a02b83d2f22f89bd5cac66c9c89474240cb6207cb1efc16d098e822a5" 364 | dependencies = [ 365 | "ark-serialize-derive", 366 | "ark-std", 367 | "digest 0.10.7", 368 | "num-bigint", 369 | ] 370 | 371 | [[package]] 372 | name = "ark-serialize-derive" 373 | version = "0.4.2" 374 | source = "registry+https://github.com/rust-lang/crates.io-index" 375 | checksum = "ae3281bc6d0fd7e549af32b52511e1302185bd688fd3359fa36423346ff682ea" 376 | dependencies = [ 377 | "proc-macro2", 378 | "quote", 379 | "syn 1.0.109", 380 | ] 381 | 382 | [[package]] 383 | name = "ark-std" 384 | version = "0.4.0" 385 | source = "registry+https://github.com/rust-lang/crates.io-index" 386 | checksum = "94893f1e0c6eeab764ade8dc4c0db24caf4fe7cbbaafc0eba0a9030f447b5185" 387 | dependencies = [ 388 | "num-traits", 389 | "rand 0.8.5", 390 | ] 391 | 392 | [[package]] 393 | name = "arrayref" 394 | version = "0.3.8" 395 | source = "registry+https://github.com/rust-lang/crates.io-index" 396 | checksum = "9d151e35f61089500b617991b791fc8bfd237ae50cd5950803758a179b41e67a" 397 | 398 | [[package]] 399 | name = "arrayvec" 400 | version = "0.7.4" 401 | source = "registry+https://github.com/rust-lang/crates.io-index" 402 | checksum = "96d30a06541fbafbc7f82ed10c06164cfbd2c401138f6addd8404629c4b16711" 403 | 404 | [[package]] 405 | name = "assert_matches" 406 | version = "1.5.0" 407 | source = "registry+https://github.com/rust-lang/crates.io-index" 408 | checksum = "9b34d609dfbaf33d6889b2b7106d3ca345eacad44200913df5ba02bfd31d2ba9" 409 | 410 | [[package]] 411 | name = "atty" 412 | version = "0.2.14" 413 | source = "registry+https://github.com/rust-lang/crates.io-index" 414 | checksum = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8" 415 | dependencies = [ 416 | "hermit-abi", 417 | "libc", 418 | "winapi", 419 | ] 420 | 421 | [[package]] 422 | name = "autocfg" 423 | version = "1.3.0" 424 | source = "registry+https://github.com/rust-lang/crates.io-index" 425 | checksum = "0c4b4d0bd25bd0b74681c0ad21497610ce1b7c91b1022cd21c80c6fbdd9476b0" 426 | 427 | [[package]] 428 | name = "base64" 429 | version = "0.12.3" 430 | source = "registry+https://github.com/rust-lang/crates.io-index" 431 | checksum = "3441f0f7b02788e948e47f457ca01f1d7e6d92c693bc132c22b087d3141c03ff" 432 | 433 | [[package]] 434 | name = "base64" 435 | version = "0.21.7" 436 | source = "registry+https://github.com/rust-lang/crates.io-index" 437 | checksum = "9d297deb1925b89f2ccc13d7635fa0714f12c87adce1c75356b39ca9b7178567" 438 | 439 | [[package]] 440 | name = "bincode" 441 | version = "1.3.3" 442 | source = "registry+https://github.com/rust-lang/crates.io-index" 443 | checksum = "b1f45e9417d87227c7a56d22e471c6206462cba514c7590c09aff4cf6d1ddcad" 444 | dependencies = [ 445 | "serde", 446 | ] 447 | 448 | [[package]] 449 | name = "bitflags" 450 | version = "2.6.0" 451 | source = "registry+https://github.com/rust-lang/crates.io-index" 452 | checksum = "b048fb63fd8b5923fc5aa7b340d8e156aec7ec02f0c78fa8a6ddc2613f6f71de" 453 | dependencies = [ 454 | "serde", 455 | ] 456 | 457 | [[package]] 458 | name = "bitmaps" 459 | version = "2.1.0" 460 | source = "registry+https://github.com/rust-lang/crates.io-index" 461 | checksum = "031043d04099746d8db04daf1fa424b2bc8bd69d92b25962dcde24da39ab64a2" 462 | dependencies = [ 463 | "typenum", 464 | ] 465 | 466 | [[package]] 467 | name = "blake3" 468 | version = "1.5.1" 469 | source = "registry+https://github.com/rust-lang/crates.io-index" 470 | checksum = "30cca6d3674597c30ddf2c587bf8d9d65c9a84d2326d941cc79c9842dfe0ef52" 471 | dependencies = [ 472 | "arrayref", 473 | "arrayvec", 474 | "cc", 475 | "cfg-if", 476 | "constant_time_eq", 477 | "digest 0.10.7", 478 | ] 479 | 480 | [[package]] 481 | name = "block-buffer" 482 | version = "0.9.0" 483 | source = "registry+https://github.com/rust-lang/crates.io-index" 484 | checksum = "4152116fd6e9dadb291ae18fc1ec3575ed6d84c29642d97890f4b4a3417297e4" 485 | dependencies = [ 486 | "block-padding", 487 | "generic-array", 488 | ] 489 | 490 | [[package]] 491 | name = "block-buffer" 492 | version = "0.10.4" 493 | source = "registry+https://github.com/rust-lang/crates.io-index" 494 | checksum = "3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71" 495 | dependencies = [ 496 | "generic-array", 497 | ] 498 | 499 | [[package]] 500 | name = "block-padding" 501 | version = "0.2.1" 502 | source = "registry+https://github.com/rust-lang/crates.io-index" 503 | checksum = "8d696c370c750c948ada61c69a0ee2cbbb9c50b1019ddb86d9317157a99c2cae" 504 | 505 | [[package]] 506 | name = "borsh" 507 | version = "0.9.3" 508 | source = "registry+https://github.com/rust-lang/crates.io-index" 509 | checksum = "15bf3650200d8bffa99015595e10f1fbd17de07abbc25bb067da79e769939bfa" 510 | dependencies = [ 511 | "borsh-derive 0.9.3", 512 | "hashbrown 0.11.2", 513 | ] 514 | 515 | [[package]] 516 | name = "borsh" 517 | version = "0.10.3" 518 | source = "registry+https://github.com/rust-lang/crates.io-index" 519 | checksum = "4114279215a005bc675e386011e594e1d9b800918cea18fcadadcce864a2046b" 520 | dependencies = [ 521 | "borsh-derive 0.10.3", 522 | "hashbrown 0.13.2", 523 | ] 524 | 525 | [[package]] 526 | name = "borsh" 527 | version = "1.5.1" 528 | source = "registry+https://github.com/rust-lang/crates.io-index" 529 | checksum = "a6362ed55def622cddc70a4746a68554d7b687713770de539e59a739b249f8ed" 530 | dependencies = [ 531 | "borsh-derive 1.5.1", 532 | "cfg_aliases", 533 | ] 534 | 535 | [[package]] 536 | name = "borsh-derive" 537 | version = "0.9.3" 538 | source = "registry+https://github.com/rust-lang/crates.io-index" 539 | checksum = "6441c552f230375d18e3cc377677914d2ca2b0d36e52129fe15450a2dce46775" 540 | dependencies = [ 541 | "borsh-derive-internal 0.9.3", 542 | "borsh-schema-derive-internal 0.9.3", 543 | "proc-macro-crate 0.1.5", 544 | "proc-macro2", 545 | "syn 1.0.109", 546 | ] 547 | 548 | [[package]] 549 | name = "borsh-derive" 550 | version = "0.10.3" 551 | source = "registry+https://github.com/rust-lang/crates.io-index" 552 | checksum = "0754613691538d51f329cce9af41d7b7ca150bc973056f1156611489475f54f7" 553 | dependencies = [ 554 | "borsh-derive-internal 0.10.3", 555 | "borsh-schema-derive-internal 0.10.3", 556 | "proc-macro-crate 0.1.5", 557 | "proc-macro2", 558 | "syn 1.0.109", 559 | ] 560 | 561 | [[package]] 562 | name = "borsh-derive" 563 | version = "1.5.1" 564 | source = "registry+https://github.com/rust-lang/crates.io-index" 565 | checksum = "c3ef8005764f53cd4dca619f5bf64cafd4664dada50ece25e4d81de54c80cc0b" 566 | dependencies = [ 567 | "once_cell", 568 | "proc-macro-crate 3.1.0", 569 | "proc-macro2", 570 | "quote", 571 | "syn 2.0.72", 572 | "syn_derive", 573 | ] 574 | 575 | [[package]] 576 | name = "borsh-derive-internal" 577 | version = "0.9.3" 578 | source = "registry+https://github.com/rust-lang/crates.io-index" 579 | checksum = "5449c28a7b352f2d1e592a8a28bf139bc71afb0764a14f3c02500935d8c44065" 580 | dependencies = [ 581 | "proc-macro2", 582 | "quote", 583 | "syn 1.0.109", 584 | ] 585 | 586 | [[package]] 587 | name = "borsh-derive-internal" 588 | version = "0.10.3" 589 | source = "registry+https://github.com/rust-lang/crates.io-index" 590 | checksum = "afb438156919598d2c7bad7e1c0adf3d26ed3840dbc010db1a882a65583ca2fb" 591 | dependencies = [ 592 | "proc-macro2", 593 | "quote", 594 | "syn 1.0.109", 595 | ] 596 | 597 | [[package]] 598 | name = "borsh-schema-derive-internal" 599 | version = "0.9.3" 600 | source = "registry+https://github.com/rust-lang/crates.io-index" 601 | checksum = "cdbd5696d8bfa21d53d9fe39a714a18538bad11492a42d066dbbc395fb1951c0" 602 | dependencies = [ 603 | "proc-macro2", 604 | "quote", 605 | "syn 1.0.109", 606 | ] 607 | 608 | [[package]] 609 | name = "borsh-schema-derive-internal" 610 | version = "0.10.3" 611 | source = "registry+https://github.com/rust-lang/crates.io-index" 612 | checksum = "634205cc43f74a1b9046ef87c4540ebda95696ec0f315024860cad7c5b0f5ccd" 613 | dependencies = [ 614 | "proc-macro2", 615 | "quote", 616 | "syn 1.0.109", 617 | ] 618 | 619 | [[package]] 620 | name = "bs58" 621 | version = "0.4.0" 622 | source = "registry+https://github.com/rust-lang/crates.io-index" 623 | checksum = "771fe0050b883fcc3ea2359b1a96bcfbc090b7116eae7c3c512c7a083fdf23d3" 624 | 625 | [[package]] 626 | name = "bs58" 627 | version = "0.5.1" 628 | source = "registry+https://github.com/rust-lang/crates.io-index" 629 | checksum = "bf88ba1141d185c399bee5288d850d63b8369520c1eafc32a0430b5b6c287bf4" 630 | dependencies = [ 631 | "tinyvec", 632 | ] 633 | 634 | [[package]] 635 | name = "bumpalo" 636 | version = "3.16.0" 637 | source = "registry+https://github.com/rust-lang/crates.io-index" 638 | checksum = "79296716171880943b8470b5f8d03aa55eb2e645a4874bdbb28adb49162e012c" 639 | 640 | [[package]] 641 | name = "bv" 642 | version = "0.11.1" 643 | source = "registry+https://github.com/rust-lang/crates.io-index" 644 | checksum = "8834bb1d8ee5dc048ee3124f2c7c1afcc6bc9aed03f11e9dfd8c69470a5db340" 645 | dependencies = [ 646 | "feature-probe", 647 | "serde", 648 | ] 649 | 650 | [[package]] 651 | name = "bytemuck" 652 | version = "1.16.1" 653 | source = "registry+https://github.com/rust-lang/crates.io-index" 654 | checksum = "b236fc92302c97ed75b38da1f4917b5cdda4984745740f153a5d3059e48d725e" 655 | dependencies = [ 656 | "bytemuck_derive", 657 | ] 658 | 659 | [[package]] 660 | name = "bytemuck_derive" 661 | version = "1.7.0" 662 | source = "registry+https://github.com/rust-lang/crates.io-index" 663 | checksum = "1ee891b04274a59bd38b412188e24b849617b2e45a0fd8d057deb63e7403761b" 664 | dependencies = [ 665 | "proc-macro2", 666 | "quote", 667 | "syn 2.0.72", 668 | ] 669 | 670 | [[package]] 671 | name = "byteorder" 672 | version = "1.5.0" 673 | source = "registry+https://github.com/rust-lang/crates.io-index" 674 | checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" 675 | 676 | [[package]] 677 | name = "cargo_toml" 678 | version = "0.19.2" 679 | source = "registry+https://github.com/rust-lang/crates.io-index" 680 | checksum = "a98356df42a2eb1bd8f1793ae4ee4de48e384dd974ce5eac8eee802edb7492be" 681 | dependencies = [ 682 | "serde", 683 | "toml 0.8.15", 684 | ] 685 | 686 | [[package]] 687 | name = "cc" 688 | version = "1.1.6" 689 | source = "registry+https://github.com/rust-lang/crates.io-index" 690 | checksum = "2aba8f4e9906c7ce3c73463f62a7f0c65183ada1a2d47e397cc8810827f9694f" 691 | dependencies = [ 692 | "jobserver", 693 | "libc", 694 | ] 695 | 696 | [[package]] 697 | name = "cfg-if" 698 | version = "1.0.0" 699 | source = "registry+https://github.com/rust-lang/crates.io-index" 700 | checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" 701 | 702 | [[package]] 703 | name = "cfg_aliases" 704 | version = "0.2.1" 705 | source = "registry+https://github.com/rust-lang/crates.io-index" 706 | checksum = "613afe47fcd5fac7ccf1db93babcb082c5994d996f20b8b159f2ad1658eb5724" 707 | 708 | [[package]] 709 | name = "chrono" 710 | version = "0.4.39" 711 | source = "registry+https://github.com/rust-lang/crates.io-index" 712 | checksum = "7e36cc9d416881d2e24f9a963be5fb1cd90966419ac844274161d10488b3e825" 713 | dependencies = [ 714 | "num-traits", 715 | ] 716 | 717 | [[package]] 718 | name = "cipher" 719 | version = "0.3.0" 720 | source = "registry+https://github.com/rust-lang/crates.io-index" 721 | checksum = "7ee52072ec15386f770805afd189a01c8841be8696bed250fa2f13c4c0d6dfb7" 722 | dependencies = [ 723 | "generic-array", 724 | ] 725 | 726 | [[package]] 727 | name = "console_error_panic_hook" 728 | version = "0.1.7" 729 | source = "registry+https://github.com/rust-lang/crates.io-index" 730 | checksum = "a06aeb73f470f66dcdbf7223caeebb85984942f22f1adb2a088cf9668146bbbc" 731 | dependencies = [ 732 | "cfg-if", 733 | "wasm-bindgen", 734 | ] 735 | 736 | [[package]] 737 | name = "console_log" 738 | version = "0.2.2" 739 | source = "registry+https://github.com/rust-lang/crates.io-index" 740 | checksum = "e89f72f65e8501878b8a004d5a1afb780987e2ce2b4532c562e367a72c57499f" 741 | dependencies = [ 742 | "log", 743 | "web-sys", 744 | ] 745 | 746 | [[package]] 747 | name = "constant_time_eq" 748 | version = "0.3.0" 749 | source = "registry+https://github.com/rust-lang/crates.io-index" 750 | checksum = "f7144d30dcf0fafbce74250a3963025d8d52177934239851c917d29f1df280c2" 751 | 752 | [[package]] 753 | name = "cpufeatures" 754 | version = "0.2.12" 755 | source = "registry+https://github.com/rust-lang/crates.io-index" 756 | checksum = "53fe5e26ff1b7aef8bca9c6080520cfb8d9333c7568e1829cef191a9723e5504" 757 | dependencies = [ 758 | "libc", 759 | ] 760 | 761 | [[package]] 762 | name = "crossbeam-deque" 763 | version = "0.8.5" 764 | source = "registry+https://github.com/rust-lang/crates.io-index" 765 | checksum = "613f8cc01fe9cf1a3eb3d7f488fd2fa8388403e97039e2f73692932e291a770d" 766 | dependencies = [ 767 | "crossbeam-epoch", 768 | "crossbeam-utils", 769 | ] 770 | 771 | [[package]] 772 | name = "crossbeam-epoch" 773 | version = "0.9.18" 774 | source = "registry+https://github.com/rust-lang/crates.io-index" 775 | checksum = "5b82ac4a3c2ca9c3460964f020e1402edd5753411d7737aa39c3714ad1b5420e" 776 | dependencies = [ 777 | "crossbeam-utils", 778 | ] 779 | 780 | [[package]] 781 | name = "crossbeam-utils" 782 | version = "0.8.20" 783 | source = "registry+https://github.com/rust-lang/crates.io-index" 784 | checksum = "22ec99545bb0ed0ea7bb9b8e1e9122ea386ff8a48c0922e43f36d45ab09e0e80" 785 | 786 | [[package]] 787 | name = "crunchy" 788 | version = "0.2.2" 789 | source = "registry+https://github.com/rust-lang/crates.io-index" 790 | checksum = "7a81dae078cea95a014a339291cec439d2f232ebe854a9d672b796c6afafa9b7" 791 | 792 | [[package]] 793 | name = "crypto-common" 794 | version = "0.1.6" 795 | source = "registry+https://github.com/rust-lang/crates.io-index" 796 | checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3" 797 | dependencies = [ 798 | "generic-array", 799 | "typenum", 800 | ] 801 | 802 | [[package]] 803 | name = "crypto-mac" 804 | version = "0.8.0" 805 | source = "registry+https://github.com/rust-lang/crates.io-index" 806 | checksum = "b584a330336237c1eecd3e94266efb216c56ed91225d634cb2991c5f3fd1aeab" 807 | dependencies = [ 808 | "generic-array", 809 | "subtle", 810 | ] 811 | 812 | [[package]] 813 | name = "ctr" 814 | version = "0.8.0" 815 | source = "registry+https://github.com/rust-lang/crates.io-index" 816 | checksum = "049bb91fb4aaf0e3c7efa6cd5ef877dbbbd15b39dad06d9948de4ec8a75761ea" 817 | dependencies = [ 818 | "cipher", 819 | ] 820 | 821 | [[package]] 822 | name = "curve25519-dalek" 823 | version = "3.2.1" 824 | source = "registry+https://github.com/rust-lang/crates.io-index" 825 | checksum = "90f9d052967f590a76e62eb387bd0bbb1b000182c3cefe5364db6b7211651bc0" 826 | dependencies = [ 827 | "byteorder", 828 | "digest 0.9.0", 829 | "rand_core 0.5.1", 830 | "serde", 831 | "subtle", 832 | "zeroize", 833 | ] 834 | 835 | [[package]] 836 | name = "darling" 837 | version = "0.20.10" 838 | source = "registry+https://github.com/rust-lang/crates.io-index" 839 | checksum = "6f63b86c8a8826a49b8c21f08a2d07338eec8d900540f8630dc76284be802989" 840 | dependencies = [ 841 | "darling_core", 842 | "darling_macro", 843 | ] 844 | 845 | [[package]] 846 | name = "darling_core" 847 | version = "0.20.10" 848 | source = "registry+https://github.com/rust-lang/crates.io-index" 849 | checksum = "95133861a8032aaea082871032f5815eb9e98cef03fa916ab4500513994df9e5" 850 | dependencies = [ 851 | "fnv", 852 | "ident_case", 853 | "proc-macro2", 854 | "quote", 855 | "strsim", 856 | "syn 2.0.72", 857 | ] 858 | 859 | [[package]] 860 | name = "darling_macro" 861 | version = "0.20.10" 862 | source = "registry+https://github.com/rust-lang/crates.io-index" 863 | checksum = "d336a2a514f6ccccaa3e09b02d41d35330c07ddf03a62165fcec10bb561c7806" 864 | dependencies = [ 865 | "darling_core", 866 | "quote", 867 | "syn 2.0.72", 868 | ] 869 | 870 | [[package]] 871 | name = "derivation-path" 872 | version = "0.2.0" 873 | source = "registry+https://github.com/rust-lang/crates.io-index" 874 | checksum = "6e5c37193a1db1d8ed868c03ec7b152175f26160a5b740e5e484143877e0adf0" 875 | 876 | [[package]] 877 | name = "derivative" 878 | version = "2.2.0" 879 | source = "registry+https://github.com/rust-lang/crates.io-index" 880 | checksum = "fcc3dd5e9e9c0b295d6e1e4d811fb6f157d5ffd784b8d202fc62eac8035a770b" 881 | dependencies = [ 882 | "proc-macro2", 883 | "quote", 884 | "syn 1.0.109", 885 | ] 886 | 887 | [[package]] 888 | name = "devotion" 889 | version = "0.1.0" 890 | dependencies = [ 891 | "anchor-lang", 892 | "anchor-spl", 893 | ] 894 | 895 | [[package]] 896 | name = "digest" 897 | version = "0.9.0" 898 | source = "registry+https://github.com/rust-lang/crates.io-index" 899 | checksum = "d3dd60d1080a57a05ab032377049e0591415d2b31afd7028356dbf3cc6dcb066" 900 | dependencies = [ 901 | "generic-array", 902 | ] 903 | 904 | [[package]] 905 | name = "digest" 906 | version = "0.10.7" 907 | source = "registry+https://github.com/rust-lang/crates.io-index" 908 | checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292" 909 | dependencies = [ 910 | "block-buffer 0.10.4", 911 | "crypto-common", 912 | "subtle", 913 | ] 914 | 915 | [[package]] 916 | name = "ed25519" 917 | version = "1.5.3" 918 | source = "registry+https://github.com/rust-lang/crates.io-index" 919 | checksum = "91cff35c70bba8a626e3185d8cd48cc11b5437e1a5bcd15b9b5fa3c64b6dfee7" 920 | dependencies = [ 921 | "signature", 922 | ] 923 | 924 | [[package]] 925 | name = "ed25519-dalek" 926 | version = "1.0.1" 927 | source = "registry+https://github.com/rust-lang/crates.io-index" 928 | checksum = "c762bae6dcaf24c4c84667b8579785430908723d5c889f469d76a41d59cc7a9d" 929 | dependencies = [ 930 | "curve25519-dalek", 931 | "ed25519", 932 | "rand 0.7.3", 933 | "serde", 934 | "sha2 0.9.9", 935 | "zeroize", 936 | ] 937 | 938 | [[package]] 939 | name = "ed25519-dalek-bip32" 940 | version = "0.2.0" 941 | source = "registry+https://github.com/rust-lang/crates.io-index" 942 | checksum = "9d2be62a4061b872c8c0873ee4fc6f101ce7b889d039f019c5fa2af471a59908" 943 | dependencies = [ 944 | "derivation-path", 945 | "ed25519-dalek", 946 | "hmac 0.12.1", 947 | "sha2 0.10.8", 948 | ] 949 | 950 | [[package]] 951 | name = "either" 952 | version = "1.13.0" 953 | source = "registry+https://github.com/rust-lang/crates.io-index" 954 | checksum = "60b1af1c220855b6ceac025d3f6ecdd2b7c4894bfe9cd9bda4fbb4bc7c0d4cf0" 955 | 956 | [[package]] 957 | name = "env_logger" 958 | version = "0.9.3" 959 | source = "registry+https://github.com/rust-lang/crates.io-index" 960 | checksum = "a12e6657c4c97ebab115a42dcee77225f7f482cdd841cf7088c657a42e9e00e7" 961 | dependencies = [ 962 | "atty", 963 | "humantime", 964 | "log", 965 | "regex", 966 | "termcolor", 967 | ] 968 | 969 | [[package]] 970 | name = "equivalent" 971 | version = "1.0.1" 972 | source = "registry+https://github.com/rust-lang/crates.io-index" 973 | checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5" 974 | 975 | [[package]] 976 | name = "feature-probe" 977 | version = "0.1.1" 978 | source = "registry+https://github.com/rust-lang/crates.io-index" 979 | checksum = "835a3dc7d1ec9e75e2b5fb4ba75396837112d2060b03f7d43bc1897c7f7211da" 980 | 981 | [[package]] 982 | name = "fnv" 983 | version = "1.0.7" 984 | source = "registry+https://github.com/rust-lang/crates.io-index" 985 | checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" 986 | 987 | [[package]] 988 | name = "generic-array" 989 | version = "0.14.7" 990 | source = "registry+https://github.com/rust-lang/crates.io-index" 991 | checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a" 992 | dependencies = [ 993 | "serde", 994 | "typenum", 995 | "version_check", 996 | ] 997 | 998 | [[package]] 999 | name = "getrandom" 1000 | version = "0.1.16" 1001 | source = "registry+https://github.com/rust-lang/crates.io-index" 1002 | checksum = "8fc3cb4d91f53b50155bdcfd23f6a4c39ae1969c2ae85982b135750cccaf5fce" 1003 | dependencies = [ 1004 | "cfg-if", 1005 | "js-sys", 1006 | "libc", 1007 | "wasi 0.9.0+wasi-snapshot-preview1", 1008 | "wasm-bindgen", 1009 | ] 1010 | 1011 | [[package]] 1012 | name = "getrandom" 1013 | version = "0.2.15" 1014 | source = "registry+https://github.com/rust-lang/crates.io-index" 1015 | checksum = "c4567c8db10ae91089c99af84c68c38da3ec2f087c3f82960bcdbf3656b6f4d7" 1016 | dependencies = [ 1017 | "cfg-if", 1018 | "js-sys", 1019 | "libc", 1020 | "wasi 0.11.0+wasi-snapshot-preview1", 1021 | "wasm-bindgen", 1022 | ] 1023 | 1024 | [[package]] 1025 | name = "hashbrown" 1026 | version = "0.11.2" 1027 | source = "registry+https://github.com/rust-lang/crates.io-index" 1028 | checksum = "ab5ef0d4909ef3724cc8cce6ccc8572c5c817592e9285f5464f8e86f8bd3726e" 1029 | dependencies = [ 1030 | "ahash 0.7.8", 1031 | ] 1032 | 1033 | [[package]] 1034 | name = "hashbrown" 1035 | version = "0.13.2" 1036 | source = "registry+https://github.com/rust-lang/crates.io-index" 1037 | checksum = "43a3c133739dddd0d2990f9a4bdf8eb4b21ef50e4851ca85ab661199821d510e" 1038 | dependencies = [ 1039 | "ahash 0.8.11", 1040 | ] 1041 | 1042 | [[package]] 1043 | name = "hashbrown" 1044 | version = "0.14.5" 1045 | source = "registry+https://github.com/rust-lang/crates.io-index" 1046 | checksum = "e5274423e17b7c9fc20b6e7e208532f9b19825d82dfd615708b70edd83df41f1" 1047 | 1048 | [[package]] 1049 | name = "heck" 1050 | version = "0.3.3" 1051 | source = "registry+https://github.com/rust-lang/crates.io-index" 1052 | checksum = "6d621efb26863f0e9924c6ac577e8275e5e6b77455db64ffa6c65c904e9e132c" 1053 | dependencies = [ 1054 | "unicode-segmentation", 1055 | ] 1056 | 1057 | [[package]] 1058 | name = "hermit-abi" 1059 | version = "0.1.19" 1060 | source = "registry+https://github.com/rust-lang/crates.io-index" 1061 | checksum = "62b467343b94ba476dcb2500d242dadbb39557df889310ac77c5d99100aaac33" 1062 | dependencies = [ 1063 | "libc", 1064 | ] 1065 | 1066 | [[package]] 1067 | name = "hmac" 1068 | version = "0.8.1" 1069 | source = "registry+https://github.com/rust-lang/crates.io-index" 1070 | checksum = "126888268dcc288495a26bf004b38c5fdbb31682f992c84ceb046a1f0fe38840" 1071 | dependencies = [ 1072 | "crypto-mac", 1073 | "digest 0.9.0", 1074 | ] 1075 | 1076 | [[package]] 1077 | name = "hmac" 1078 | version = "0.12.1" 1079 | source = "registry+https://github.com/rust-lang/crates.io-index" 1080 | checksum = "6c49c37c09c17a53d937dfbb742eb3a961d65a994e6bcdcf37e7399d0cc8ab5e" 1081 | dependencies = [ 1082 | "digest 0.10.7", 1083 | ] 1084 | 1085 | [[package]] 1086 | name = "hmac-drbg" 1087 | version = "0.3.0" 1088 | source = "registry+https://github.com/rust-lang/crates.io-index" 1089 | checksum = "17ea0a1394df5b6574da6e0c1ade9e78868c9fb0a4e5ef4428e32da4676b85b1" 1090 | dependencies = [ 1091 | "digest 0.9.0", 1092 | "generic-array", 1093 | "hmac 0.8.1", 1094 | ] 1095 | 1096 | [[package]] 1097 | name = "humantime" 1098 | version = "2.1.0" 1099 | source = "registry+https://github.com/rust-lang/crates.io-index" 1100 | checksum = "9a3a5bfb195931eeb336b2a7b4d761daec841b97f947d34394601737a7bba5e4" 1101 | 1102 | [[package]] 1103 | name = "ident_case" 1104 | version = "1.0.1" 1105 | source = "registry+https://github.com/rust-lang/crates.io-index" 1106 | checksum = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39" 1107 | 1108 | [[package]] 1109 | name = "im" 1110 | version = "15.1.0" 1111 | source = "registry+https://github.com/rust-lang/crates.io-index" 1112 | checksum = "d0acd33ff0285af998aaf9b57342af478078f53492322fafc47450e09397e0e9" 1113 | dependencies = [ 1114 | "bitmaps", 1115 | "rand_core 0.6.4", 1116 | "rand_xoshiro", 1117 | "rayon", 1118 | "serde", 1119 | "sized-chunks", 1120 | "typenum", 1121 | "version_check", 1122 | ] 1123 | 1124 | [[package]] 1125 | name = "indexmap" 1126 | version = "2.2.6" 1127 | source = "registry+https://github.com/rust-lang/crates.io-index" 1128 | checksum = "168fb715dda47215e360912c096649d23d58bf392ac62f73919e831745e40f26" 1129 | dependencies = [ 1130 | "equivalent", 1131 | "hashbrown 0.14.5", 1132 | ] 1133 | 1134 | [[package]] 1135 | name = "itertools" 1136 | version = "0.10.5" 1137 | source = "registry+https://github.com/rust-lang/crates.io-index" 1138 | checksum = "b0fd2260e829bddf4cb6ea802289de2f86d6a7a690192fbe91b3f46e0f2c8473" 1139 | dependencies = [ 1140 | "either", 1141 | ] 1142 | 1143 | [[package]] 1144 | name = "itoa" 1145 | version = "1.0.11" 1146 | source = "registry+https://github.com/rust-lang/crates.io-index" 1147 | checksum = "49f1f14873335454500d59611f1cf4a4b0f786f9ac11f4312a78e4cf2566695b" 1148 | 1149 | [[package]] 1150 | name = "jobserver" 1151 | version = "0.1.31" 1152 | source = "registry+https://github.com/rust-lang/crates.io-index" 1153 | checksum = "d2b099aaa34a9751c5bf0878add70444e1ed2dd73f347be99003d4577277de6e" 1154 | dependencies = [ 1155 | "libc", 1156 | ] 1157 | 1158 | [[package]] 1159 | name = "js-sys" 1160 | version = "0.3.69" 1161 | source = "registry+https://github.com/rust-lang/crates.io-index" 1162 | checksum = "29c15563dc2726973df627357ce0c9ddddbea194836909d655df6a75d2cf296d" 1163 | dependencies = [ 1164 | "wasm-bindgen", 1165 | ] 1166 | 1167 | [[package]] 1168 | name = "keccak" 1169 | version = "0.1.5" 1170 | source = "registry+https://github.com/rust-lang/crates.io-index" 1171 | checksum = "ecc2af9a1119c51f12a14607e783cb977bde58bc069ff0c3da1095e635d70654" 1172 | dependencies = [ 1173 | "cpufeatures", 1174 | ] 1175 | 1176 | [[package]] 1177 | name = "lazy_static" 1178 | version = "1.5.0" 1179 | source = "registry+https://github.com/rust-lang/crates.io-index" 1180 | checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe" 1181 | 1182 | [[package]] 1183 | name = "libc" 1184 | version = "0.2.155" 1185 | source = "registry+https://github.com/rust-lang/crates.io-index" 1186 | checksum = "97b3888a4aecf77e811145cadf6eef5901f4782c53886191b2f693f24761847c" 1187 | 1188 | [[package]] 1189 | name = "libsecp256k1" 1190 | version = "0.6.0" 1191 | source = "registry+https://github.com/rust-lang/crates.io-index" 1192 | checksum = "c9d220bc1feda2ac231cb78c3d26f27676b8cf82c96971f7aeef3d0cf2797c73" 1193 | dependencies = [ 1194 | "arrayref", 1195 | "base64 0.12.3", 1196 | "digest 0.9.0", 1197 | "hmac-drbg", 1198 | "libsecp256k1-core", 1199 | "libsecp256k1-gen-ecmult", 1200 | "libsecp256k1-gen-genmult", 1201 | "rand 0.7.3", 1202 | "serde", 1203 | "sha2 0.9.9", 1204 | "typenum", 1205 | ] 1206 | 1207 | [[package]] 1208 | name = "libsecp256k1-core" 1209 | version = "0.2.2" 1210 | source = "registry+https://github.com/rust-lang/crates.io-index" 1211 | checksum = "d0f6ab710cec28cef759c5f18671a27dae2a5f952cdaaee1d8e2908cb2478a80" 1212 | dependencies = [ 1213 | "crunchy", 1214 | "digest 0.9.0", 1215 | "subtle", 1216 | ] 1217 | 1218 | [[package]] 1219 | name = "libsecp256k1-gen-ecmult" 1220 | version = "0.2.1" 1221 | source = "registry+https://github.com/rust-lang/crates.io-index" 1222 | checksum = "ccab96b584d38fac86a83f07e659f0deafd0253dc096dab5a36d53efe653c5c3" 1223 | dependencies = [ 1224 | "libsecp256k1-core", 1225 | ] 1226 | 1227 | [[package]] 1228 | name = "libsecp256k1-gen-genmult" 1229 | version = "0.2.1" 1230 | source = "registry+https://github.com/rust-lang/crates.io-index" 1231 | checksum = "67abfe149395e3aa1c48a2beb32b068e2334402df8181f818d3aee2b304c4f5d" 1232 | dependencies = [ 1233 | "libsecp256k1-core", 1234 | ] 1235 | 1236 | [[package]] 1237 | name = "light-poseidon" 1238 | version = "0.2.0" 1239 | source = "registry+https://github.com/rust-lang/crates.io-index" 1240 | checksum = "3c9a85a9752c549ceb7578064b4ed891179d20acd85f27318573b64d2d7ee7ee" 1241 | dependencies = [ 1242 | "ark-bn254", 1243 | "ark-ff", 1244 | "num-bigint", 1245 | "thiserror", 1246 | ] 1247 | 1248 | [[package]] 1249 | name = "lock_api" 1250 | version = "0.4.12" 1251 | source = "registry+https://github.com/rust-lang/crates.io-index" 1252 | checksum = "07af8b9cdd281b7915f413fa73f29ebd5d55d0d3f0155584dade1ff18cea1b17" 1253 | dependencies = [ 1254 | "autocfg", 1255 | "scopeguard", 1256 | ] 1257 | 1258 | [[package]] 1259 | name = "log" 1260 | version = "0.4.22" 1261 | source = "registry+https://github.com/rust-lang/crates.io-index" 1262 | checksum = "a7a70ba024b9dc04c27ea2f0c0548feb474ec5c54bba33a7f72f873a39d07b24" 1263 | 1264 | [[package]] 1265 | name = "memchr" 1266 | version = "2.7.4" 1267 | source = "registry+https://github.com/rust-lang/crates.io-index" 1268 | checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3" 1269 | 1270 | [[package]] 1271 | name = "memmap2" 1272 | version = "0.5.10" 1273 | source = "registry+https://github.com/rust-lang/crates.io-index" 1274 | checksum = "83faa42c0a078c393f6b29d5db232d8be22776a891f8f56e5284faee4a20b327" 1275 | dependencies = [ 1276 | "libc", 1277 | ] 1278 | 1279 | [[package]] 1280 | name = "memoffset" 1281 | version = "0.9.1" 1282 | source = "registry+https://github.com/rust-lang/crates.io-index" 1283 | checksum = "488016bfae457b036d996092f6cb448677611ce4449e970ceaf42695203f218a" 1284 | dependencies = [ 1285 | "autocfg", 1286 | ] 1287 | 1288 | [[package]] 1289 | name = "merlin" 1290 | version = "3.0.0" 1291 | source = "registry+https://github.com/rust-lang/crates.io-index" 1292 | checksum = "58c38e2799fc0978b65dfff8023ec7843e2330bb462f19198840b34b6582397d" 1293 | dependencies = [ 1294 | "byteorder", 1295 | "keccak", 1296 | "rand_core 0.6.4", 1297 | "zeroize", 1298 | ] 1299 | 1300 | [[package]] 1301 | name = "num-bigint" 1302 | version = "0.4.6" 1303 | source = "registry+https://github.com/rust-lang/crates.io-index" 1304 | checksum = "a5e44f723f1133c9deac646763579fdb3ac745e418f2a7af9cd0c431da1f20b9" 1305 | dependencies = [ 1306 | "num-integer", 1307 | "num-traits", 1308 | ] 1309 | 1310 | [[package]] 1311 | name = "num-derive" 1312 | version = "0.4.2" 1313 | source = "registry+https://github.com/rust-lang/crates.io-index" 1314 | checksum = "ed3955f1a9c7c0c15e092f9c887db08b1fc683305fdf6eb6684f22555355e202" 1315 | dependencies = [ 1316 | "proc-macro2", 1317 | "quote", 1318 | "syn 2.0.72", 1319 | ] 1320 | 1321 | [[package]] 1322 | name = "num-integer" 1323 | version = "0.1.46" 1324 | source = "registry+https://github.com/rust-lang/crates.io-index" 1325 | checksum = "7969661fd2958a5cb096e56c8e1ad0444ac2bbcd0061bd28660485a44879858f" 1326 | dependencies = [ 1327 | "num-traits", 1328 | ] 1329 | 1330 | [[package]] 1331 | name = "num-traits" 1332 | version = "0.2.19" 1333 | source = "registry+https://github.com/rust-lang/crates.io-index" 1334 | checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841" 1335 | dependencies = [ 1336 | "autocfg", 1337 | ] 1338 | 1339 | [[package]] 1340 | name = "num_enum" 1341 | version = "0.7.3" 1342 | source = "registry+https://github.com/rust-lang/crates.io-index" 1343 | checksum = "4e613fc340b2220f734a8595782c551f1250e969d87d3be1ae0579e8d4065179" 1344 | dependencies = [ 1345 | "num_enum_derive", 1346 | ] 1347 | 1348 | [[package]] 1349 | name = "num_enum_derive" 1350 | version = "0.7.3" 1351 | source = "registry+https://github.com/rust-lang/crates.io-index" 1352 | checksum = "af1844ef2428cc3e1cb900be36181049ef3d3193c63e43026cfe202983b27a56" 1353 | dependencies = [ 1354 | "proc-macro-crate 3.1.0", 1355 | "proc-macro2", 1356 | "quote", 1357 | "syn 2.0.72", 1358 | ] 1359 | 1360 | [[package]] 1361 | name = "once_cell" 1362 | version = "1.19.0" 1363 | source = "registry+https://github.com/rust-lang/crates.io-index" 1364 | checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92" 1365 | 1366 | [[package]] 1367 | name = "opaque-debug" 1368 | version = "0.3.1" 1369 | source = "registry+https://github.com/rust-lang/crates.io-index" 1370 | checksum = "c08d65885ee38876c4f86fa503fb49d7b507c2b62552df7c70b2fce627e06381" 1371 | 1372 | [[package]] 1373 | name = "parking_lot" 1374 | version = "0.12.3" 1375 | source = "registry+https://github.com/rust-lang/crates.io-index" 1376 | checksum = "f1bf18183cf54e8d6059647fc3063646a1801cf30896933ec2311622cc4b9a27" 1377 | dependencies = [ 1378 | "lock_api", 1379 | "parking_lot_core", 1380 | ] 1381 | 1382 | [[package]] 1383 | name = "parking_lot_core" 1384 | version = "0.9.10" 1385 | source = "registry+https://github.com/rust-lang/crates.io-index" 1386 | checksum = "1e401f977ab385c9e4e3ab30627d6f26d00e2c73eef317493c4ec6d468726cf8" 1387 | dependencies = [ 1388 | "cfg-if", 1389 | "libc", 1390 | "redox_syscall", 1391 | "smallvec", 1392 | "windows-targets", 1393 | ] 1394 | 1395 | [[package]] 1396 | name = "paste" 1397 | version = "1.0.15" 1398 | source = "registry+https://github.com/rust-lang/crates.io-index" 1399 | checksum = "57c0d7b74b563b49d38dae00a0c37d4d6de9b432382b2892f0574ddcae73fd0a" 1400 | 1401 | [[package]] 1402 | name = "pbkdf2" 1403 | version = "0.4.0" 1404 | source = "registry+https://github.com/rust-lang/crates.io-index" 1405 | checksum = "216eaa586a190f0a738f2f918511eecfa90f13295abec0e457cdebcceda80cbd" 1406 | dependencies = [ 1407 | "crypto-mac", 1408 | ] 1409 | 1410 | [[package]] 1411 | name = "pbkdf2" 1412 | version = "0.11.0" 1413 | source = "registry+https://github.com/rust-lang/crates.io-index" 1414 | checksum = "83a0692ec44e4cf1ef28ca317f14f8f07da2d95ec3fa01f86e4467b725e60917" 1415 | dependencies = [ 1416 | "digest 0.10.7", 1417 | ] 1418 | 1419 | [[package]] 1420 | name = "percent-encoding" 1421 | version = "2.3.1" 1422 | source = "registry+https://github.com/rust-lang/crates.io-index" 1423 | checksum = "e3148f5046208a5d56bcfc03053e3ca6334e51da8dfb19b6cdc8b306fae3283e" 1424 | 1425 | [[package]] 1426 | name = "polyval" 1427 | version = "0.5.3" 1428 | source = "registry+https://github.com/rust-lang/crates.io-index" 1429 | checksum = "8419d2b623c7c0896ff2d5d96e2cb4ede590fed28fcc34934f4c33c036e620a1" 1430 | dependencies = [ 1431 | "cfg-if", 1432 | "cpufeatures", 1433 | "opaque-debug", 1434 | "universal-hash", 1435 | ] 1436 | 1437 | [[package]] 1438 | name = "ppv-lite86" 1439 | version = "0.2.17" 1440 | source = "registry+https://github.com/rust-lang/crates.io-index" 1441 | checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de" 1442 | 1443 | [[package]] 1444 | name = "proc-macro-crate" 1445 | version = "0.1.5" 1446 | source = "registry+https://github.com/rust-lang/crates.io-index" 1447 | checksum = "1d6ea3c4595b96363c13943497db34af4460fb474a95c43f4446ad341b8c9785" 1448 | dependencies = [ 1449 | "toml 0.5.11", 1450 | ] 1451 | 1452 | [[package]] 1453 | name = "proc-macro-crate" 1454 | version = "3.1.0" 1455 | source = "registry+https://github.com/rust-lang/crates.io-index" 1456 | checksum = "6d37c51ca738a55da99dc0c4a34860fd675453b8b36209178c2249bb13651284" 1457 | dependencies = [ 1458 | "toml_edit 0.21.1", 1459 | ] 1460 | 1461 | [[package]] 1462 | name = "proc-macro-error" 1463 | version = "1.0.4" 1464 | source = "registry+https://github.com/rust-lang/crates.io-index" 1465 | checksum = "da25490ff9892aab3fcf7c36f08cfb902dd3e71ca0f9f9517bea02a73a5ce38c" 1466 | dependencies = [ 1467 | "proc-macro-error-attr", 1468 | "proc-macro2", 1469 | "quote", 1470 | "version_check", 1471 | ] 1472 | 1473 | [[package]] 1474 | name = "proc-macro-error-attr" 1475 | version = "1.0.4" 1476 | source = "registry+https://github.com/rust-lang/crates.io-index" 1477 | checksum = "a1be40180e52ecc98ad80b184934baf3d0d29f979574e439af5a55274b35f869" 1478 | dependencies = [ 1479 | "proc-macro2", 1480 | "quote", 1481 | "version_check", 1482 | ] 1483 | 1484 | [[package]] 1485 | name = "proc-macro2" 1486 | version = "1.0.86" 1487 | source = "registry+https://github.com/rust-lang/crates.io-index" 1488 | checksum = "5e719e8df665df0d1c8fbfd238015744736151d4445ec0836b8e628aae103b77" 1489 | dependencies = [ 1490 | "unicode-ident", 1491 | ] 1492 | 1493 | [[package]] 1494 | name = "qstring" 1495 | version = "0.7.2" 1496 | source = "registry+https://github.com/rust-lang/crates.io-index" 1497 | checksum = "d464fae65fff2680baf48019211ce37aaec0c78e9264c84a3e484717f965104e" 1498 | dependencies = [ 1499 | "percent-encoding", 1500 | ] 1501 | 1502 | [[package]] 1503 | name = "qualifier_attr" 1504 | version = "0.2.2" 1505 | source = "registry+https://github.com/rust-lang/crates.io-index" 1506 | checksum = "9e2e25ee72f5b24d773cae88422baddefff7714f97aab68d96fe2b6fc4a28fb2" 1507 | dependencies = [ 1508 | "proc-macro2", 1509 | "quote", 1510 | "syn 2.0.72", 1511 | ] 1512 | 1513 | [[package]] 1514 | name = "quote" 1515 | version = "1.0.36" 1516 | source = "registry+https://github.com/rust-lang/crates.io-index" 1517 | checksum = "0fa76aaf39101c457836aec0ce2316dbdc3ab723cdda1c6bd4e6ad4208acaca7" 1518 | dependencies = [ 1519 | "proc-macro2", 1520 | ] 1521 | 1522 | [[package]] 1523 | name = "rand" 1524 | version = "0.7.3" 1525 | source = "registry+https://github.com/rust-lang/crates.io-index" 1526 | checksum = "6a6b1679d49b24bbfe0c803429aa1874472f50d9b363131f0e89fc356b544d03" 1527 | dependencies = [ 1528 | "getrandom 0.1.16", 1529 | "libc", 1530 | "rand_chacha 0.2.2", 1531 | "rand_core 0.5.1", 1532 | "rand_hc", 1533 | ] 1534 | 1535 | [[package]] 1536 | name = "rand" 1537 | version = "0.8.5" 1538 | source = "registry+https://github.com/rust-lang/crates.io-index" 1539 | checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" 1540 | dependencies = [ 1541 | "libc", 1542 | "rand_chacha 0.3.1", 1543 | "rand_core 0.6.4", 1544 | ] 1545 | 1546 | [[package]] 1547 | name = "rand_chacha" 1548 | version = "0.2.2" 1549 | source = "registry+https://github.com/rust-lang/crates.io-index" 1550 | checksum = "f4c8ed856279c9737206bf725bf36935d8666ead7aa69b52be55af369d193402" 1551 | dependencies = [ 1552 | "ppv-lite86", 1553 | "rand_core 0.5.1", 1554 | ] 1555 | 1556 | [[package]] 1557 | name = "rand_chacha" 1558 | version = "0.3.1" 1559 | source = "registry+https://github.com/rust-lang/crates.io-index" 1560 | checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" 1561 | dependencies = [ 1562 | "ppv-lite86", 1563 | "rand_core 0.6.4", 1564 | ] 1565 | 1566 | [[package]] 1567 | name = "rand_core" 1568 | version = "0.5.1" 1569 | source = "registry+https://github.com/rust-lang/crates.io-index" 1570 | checksum = "90bde5296fc891b0cef12a6d03ddccc162ce7b2aff54160af9338f8d40df6d19" 1571 | dependencies = [ 1572 | "getrandom 0.1.16", 1573 | ] 1574 | 1575 | [[package]] 1576 | name = "rand_core" 1577 | version = "0.6.4" 1578 | source = "registry+https://github.com/rust-lang/crates.io-index" 1579 | checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" 1580 | dependencies = [ 1581 | "getrandom 0.2.15", 1582 | ] 1583 | 1584 | [[package]] 1585 | name = "rand_hc" 1586 | version = "0.2.0" 1587 | source = "registry+https://github.com/rust-lang/crates.io-index" 1588 | checksum = "ca3129af7b92a17112d59ad498c6f81eaf463253766b90396d39ea7a39d6613c" 1589 | dependencies = [ 1590 | "rand_core 0.5.1", 1591 | ] 1592 | 1593 | [[package]] 1594 | name = "rand_xoshiro" 1595 | version = "0.6.0" 1596 | source = "registry+https://github.com/rust-lang/crates.io-index" 1597 | checksum = "6f97cdb2a36ed4183de61b2f824cc45c9f1037f28afe0a322e9fff4c108b5aaa" 1598 | dependencies = [ 1599 | "rand_core 0.6.4", 1600 | ] 1601 | 1602 | [[package]] 1603 | name = "rayon" 1604 | version = "1.10.0" 1605 | source = "registry+https://github.com/rust-lang/crates.io-index" 1606 | checksum = "b418a60154510ca1a002a752ca9714984e21e4241e804d32555251faf8b78ffa" 1607 | dependencies = [ 1608 | "either", 1609 | "rayon-core", 1610 | ] 1611 | 1612 | [[package]] 1613 | name = "rayon-core" 1614 | version = "1.12.1" 1615 | source = "registry+https://github.com/rust-lang/crates.io-index" 1616 | checksum = "1465873a3dfdaa8ae7cb14b4383657caab0b3e8a0aa9ae8e04b044854c8dfce2" 1617 | dependencies = [ 1618 | "crossbeam-deque", 1619 | "crossbeam-utils", 1620 | ] 1621 | 1622 | [[package]] 1623 | name = "redox_syscall" 1624 | version = "0.5.3" 1625 | source = "registry+https://github.com/rust-lang/crates.io-index" 1626 | checksum = "2a908a6e00f1fdd0dfd9c0eb08ce85126f6d8bbda50017e74bc4a4b7d4a926a4" 1627 | dependencies = [ 1628 | "bitflags", 1629 | ] 1630 | 1631 | [[package]] 1632 | name = "regex" 1633 | version = "1.10.5" 1634 | source = "registry+https://github.com/rust-lang/crates.io-index" 1635 | checksum = "b91213439dad192326a0d7c6ee3955910425f441d7038e0d6933b0aec5c4517f" 1636 | dependencies = [ 1637 | "aho-corasick", 1638 | "memchr", 1639 | "regex-automata", 1640 | "regex-syntax", 1641 | ] 1642 | 1643 | [[package]] 1644 | name = "regex-automata" 1645 | version = "0.4.7" 1646 | source = "registry+https://github.com/rust-lang/crates.io-index" 1647 | checksum = "38caf58cc5ef2fed281f89292ef23f6365465ed9a41b7a7754eb4e26496c92df" 1648 | dependencies = [ 1649 | "aho-corasick", 1650 | "memchr", 1651 | "regex-syntax", 1652 | ] 1653 | 1654 | [[package]] 1655 | name = "regex-syntax" 1656 | version = "0.8.4" 1657 | source = "registry+https://github.com/rust-lang/crates.io-index" 1658 | checksum = "7a66a03ae7c801facd77a29370b4faec201768915ac14a721ba36f20bc9c209b" 1659 | 1660 | [[package]] 1661 | name = "rustc-hash" 1662 | version = "1.1.0" 1663 | source = "registry+https://github.com/rust-lang/crates.io-index" 1664 | checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2" 1665 | 1666 | [[package]] 1667 | name = "rustc_version" 1668 | version = "0.4.0" 1669 | source = "registry+https://github.com/rust-lang/crates.io-index" 1670 | checksum = "bfa0f585226d2e68097d4f95d113b15b83a82e819ab25717ec0590d9584ef366" 1671 | dependencies = [ 1672 | "semver", 1673 | ] 1674 | 1675 | [[package]] 1676 | name = "rustversion" 1677 | version = "1.0.17" 1678 | source = "registry+https://github.com/rust-lang/crates.io-index" 1679 | checksum = "955d28af4278de8121b7ebeb796b6a45735dc01436d898801014aced2773a3d6" 1680 | 1681 | [[package]] 1682 | name = "ryu" 1683 | version = "1.0.18" 1684 | source = "registry+https://github.com/rust-lang/crates.io-index" 1685 | checksum = "f3cb5ba0dc43242ce17de99c180e96db90b235b8a9fdc9543c96d2209116bd9f" 1686 | 1687 | [[package]] 1688 | name = "scopeguard" 1689 | version = "1.2.0" 1690 | source = "registry+https://github.com/rust-lang/crates.io-index" 1691 | checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" 1692 | 1693 | [[package]] 1694 | name = "semver" 1695 | version = "1.0.23" 1696 | source = "registry+https://github.com/rust-lang/crates.io-index" 1697 | checksum = "61697e0a1c7e512e84a621326239844a24d8207b4669b41bc18b32ea5cbf988b" 1698 | 1699 | [[package]] 1700 | name = "serde" 1701 | version = "1.0.204" 1702 | source = "registry+https://github.com/rust-lang/crates.io-index" 1703 | checksum = "bc76f558e0cbb2a839d37354c575f1dc3fdc6546b5be373ba43d95f231bf7c12" 1704 | dependencies = [ 1705 | "serde_derive", 1706 | ] 1707 | 1708 | [[package]] 1709 | name = "serde_bytes" 1710 | version = "0.11.15" 1711 | source = "registry+https://github.com/rust-lang/crates.io-index" 1712 | checksum = "387cc504cb06bb40a96c8e04e951fe01854cf6bc921053c954e4a606d9675c6a" 1713 | dependencies = [ 1714 | "serde", 1715 | ] 1716 | 1717 | [[package]] 1718 | name = "serde_derive" 1719 | version = "1.0.204" 1720 | source = "registry+https://github.com/rust-lang/crates.io-index" 1721 | checksum = "e0cd7e117be63d3c3678776753929474f3b04a43a080c744d6b0ae2a8c28e222" 1722 | dependencies = [ 1723 | "proc-macro2", 1724 | "quote", 1725 | "syn 2.0.72", 1726 | ] 1727 | 1728 | [[package]] 1729 | name = "serde_json" 1730 | version = "1.0.120" 1731 | source = "registry+https://github.com/rust-lang/crates.io-index" 1732 | checksum = "4e0d21c9a8cae1235ad58a00c11cb40d4b1e5c784f1ef2c537876ed6ffd8b7c5" 1733 | dependencies = [ 1734 | "itoa", 1735 | "ryu", 1736 | "serde", 1737 | ] 1738 | 1739 | [[package]] 1740 | name = "serde_spanned" 1741 | version = "0.6.6" 1742 | source = "registry+https://github.com/rust-lang/crates.io-index" 1743 | checksum = "79e674e01f999af37c49f70a6ede167a8a60b2503e56c5599532a65baa5969a0" 1744 | dependencies = [ 1745 | "serde", 1746 | ] 1747 | 1748 | [[package]] 1749 | name = "serde_with" 1750 | version = "2.3.3" 1751 | source = "registry+https://github.com/rust-lang/crates.io-index" 1752 | checksum = "07ff71d2c147a7b57362cead5e22f772cd52f6ab31cfcd9edcd7f6aeb2a0afbe" 1753 | dependencies = [ 1754 | "serde", 1755 | "serde_with_macros", 1756 | ] 1757 | 1758 | [[package]] 1759 | name = "serde_with_macros" 1760 | version = "2.3.3" 1761 | source = "registry+https://github.com/rust-lang/crates.io-index" 1762 | checksum = "881b6f881b17d13214e5d494c939ebab463d01264ce1811e9d4ac3a882e7695f" 1763 | dependencies = [ 1764 | "darling", 1765 | "proc-macro2", 1766 | "quote", 1767 | "syn 2.0.72", 1768 | ] 1769 | 1770 | [[package]] 1771 | name = "sha2" 1772 | version = "0.9.9" 1773 | source = "registry+https://github.com/rust-lang/crates.io-index" 1774 | checksum = "4d58a1e1bf39749807d89cf2d98ac2dfa0ff1cb3faa38fbb64dd88ac8013d800" 1775 | dependencies = [ 1776 | "block-buffer 0.9.0", 1777 | "cfg-if", 1778 | "cpufeatures", 1779 | "digest 0.9.0", 1780 | "opaque-debug", 1781 | ] 1782 | 1783 | [[package]] 1784 | name = "sha2" 1785 | version = "0.10.8" 1786 | source = "registry+https://github.com/rust-lang/crates.io-index" 1787 | checksum = "793db75ad2bcafc3ffa7c68b215fee268f537982cd901d132f89c6343f3a3dc8" 1788 | dependencies = [ 1789 | "cfg-if", 1790 | "cpufeatures", 1791 | "digest 0.10.7", 1792 | ] 1793 | 1794 | [[package]] 1795 | name = "sha3" 1796 | version = "0.9.1" 1797 | source = "registry+https://github.com/rust-lang/crates.io-index" 1798 | checksum = "f81199417d4e5de3f04b1e871023acea7389672c4135918f05aa9cbf2f2fa809" 1799 | dependencies = [ 1800 | "block-buffer 0.9.0", 1801 | "digest 0.9.0", 1802 | "keccak", 1803 | "opaque-debug", 1804 | ] 1805 | 1806 | [[package]] 1807 | name = "sha3" 1808 | version = "0.10.8" 1809 | source = "registry+https://github.com/rust-lang/crates.io-index" 1810 | checksum = "75872d278a8f37ef87fa0ddbda7802605cb18344497949862c0d4dcb291eba60" 1811 | dependencies = [ 1812 | "digest 0.10.7", 1813 | "keccak", 1814 | ] 1815 | 1816 | [[package]] 1817 | name = "signature" 1818 | version = "1.6.4" 1819 | source = "registry+https://github.com/rust-lang/crates.io-index" 1820 | checksum = "74233d3b3b2f6d4b006dc19dee745e73e2a6bfb6f93607cd3b02bd5b00797d7c" 1821 | 1822 | [[package]] 1823 | name = "siphasher" 1824 | version = "0.3.11" 1825 | source = "registry+https://github.com/rust-lang/crates.io-index" 1826 | checksum = "38b58827f4464d87d377d175e90bf58eb00fd8716ff0a62f80356b5e61555d0d" 1827 | 1828 | [[package]] 1829 | name = "sized-chunks" 1830 | version = "0.6.5" 1831 | source = "registry+https://github.com/rust-lang/crates.io-index" 1832 | checksum = "16d69225bde7a69b235da73377861095455d298f2b970996eec25ddbb42b3d1e" 1833 | dependencies = [ 1834 | "bitmaps", 1835 | "typenum", 1836 | ] 1837 | 1838 | [[package]] 1839 | name = "smallvec" 1840 | version = "1.13.2" 1841 | source = "registry+https://github.com/rust-lang/crates.io-index" 1842 | checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67" 1843 | 1844 | [[package]] 1845 | name = "solana-frozen-abi" 1846 | version = "1.18.19" 1847 | source = "registry+https://github.com/rust-lang/crates.io-index" 1848 | checksum = "d836521fc3fe09fbc45ccf194c7524a73865e2fa4f2f3316c987e33ffad037ec" 1849 | dependencies = [ 1850 | "block-buffer 0.10.4", 1851 | "bs58 0.4.0", 1852 | "bv", 1853 | "either", 1854 | "generic-array", 1855 | "im", 1856 | "lazy_static", 1857 | "log", 1858 | "memmap2", 1859 | "rustc_version", 1860 | "serde", 1861 | "serde_bytes", 1862 | "serde_derive", 1863 | "sha2 0.10.8", 1864 | "solana-frozen-abi-macro", 1865 | "subtle", 1866 | "thiserror", 1867 | ] 1868 | 1869 | [[package]] 1870 | name = "solana-frozen-abi-macro" 1871 | version = "1.18.19" 1872 | source = "registry+https://github.com/rust-lang/crates.io-index" 1873 | checksum = "ce5a9e8a27bce6104994ca8b0fa16b496260fe9e093f76e68c4301fcf93de2d4" 1874 | dependencies = [ 1875 | "proc-macro2", 1876 | "quote", 1877 | "rustc_version", 1878 | "syn 2.0.72", 1879 | ] 1880 | 1881 | [[package]] 1882 | name = "solana-logger" 1883 | version = "1.18.19" 1884 | source = "registry+https://github.com/rust-lang/crates.io-index" 1885 | checksum = "dd7b9835d78974f576628a6ae7858813a69e106850a8d3df96f6e5624cc9c5b1" 1886 | dependencies = [ 1887 | "env_logger", 1888 | "lazy_static", 1889 | "log", 1890 | ] 1891 | 1892 | [[package]] 1893 | name = "solana-program" 1894 | version = "1.18.19" 1895 | source = "registry+https://github.com/rust-lang/crates.io-index" 1896 | checksum = "4b359778df37b366b137d51ba7cdd884ffb23df7d7602bf1a27f8593df19a290" 1897 | dependencies = [ 1898 | "ark-bn254", 1899 | "ark-ec", 1900 | "ark-ff", 1901 | "ark-serialize", 1902 | "base64 0.21.7", 1903 | "bincode", 1904 | "bitflags", 1905 | "blake3", 1906 | "borsh 0.10.3", 1907 | "borsh 0.9.3", 1908 | "borsh 1.5.1", 1909 | "bs58 0.4.0", 1910 | "bv", 1911 | "bytemuck", 1912 | "cc", 1913 | "console_error_panic_hook", 1914 | "console_log", 1915 | "curve25519-dalek", 1916 | "getrandom 0.2.15", 1917 | "itertools", 1918 | "js-sys", 1919 | "lazy_static", 1920 | "libc", 1921 | "libsecp256k1", 1922 | "light-poseidon", 1923 | "log", 1924 | "memoffset", 1925 | "num-bigint", 1926 | "num-derive", 1927 | "num-traits", 1928 | "parking_lot", 1929 | "rand 0.8.5", 1930 | "rustc_version", 1931 | "rustversion", 1932 | "serde", 1933 | "serde_bytes", 1934 | "serde_derive", 1935 | "serde_json", 1936 | "sha2 0.10.8", 1937 | "sha3 0.10.8", 1938 | "solana-frozen-abi", 1939 | "solana-frozen-abi-macro", 1940 | "solana-sdk-macro", 1941 | "thiserror", 1942 | "tiny-bip39", 1943 | "wasm-bindgen", 1944 | "zeroize", 1945 | ] 1946 | 1947 | [[package]] 1948 | name = "solana-sdk" 1949 | version = "1.18.19" 1950 | source = "registry+https://github.com/rust-lang/crates.io-index" 1951 | checksum = "dea6dfe2df7cb0ab6a4e5b5c17653e9cdd9b4bda779f867807dd24fb37821681" 1952 | dependencies = [ 1953 | "assert_matches", 1954 | "base64 0.21.7", 1955 | "bincode", 1956 | "bitflags", 1957 | "borsh 1.5.1", 1958 | "bs58 0.4.0", 1959 | "bytemuck", 1960 | "byteorder", 1961 | "chrono", 1962 | "derivation-path", 1963 | "digest 0.10.7", 1964 | "ed25519-dalek", 1965 | "ed25519-dalek-bip32", 1966 | "generic-array", 1967 | "hmac 0.12.1", 1968 | "itertools", 1969 | "js-sys", 1970 | "lazy_static", 1971 | "libsecp256k1", 1972 | "log", 1973 | "memmap2", 1974 | "num-derive", 1975 | "num-traits", 1976 | "num_enum", 1977 | "pbkdf2 0.11.0", 1978 | "qstring", 1979 | "qualifier_attr", 1980 | "rand 0.7.3", 1981 | "rand 0.8.5", 1982 | "rustc_version", 1983 | "rustversion", 1984 | "serde", 1985 | "serde_bytes", 1986 | "serde_derive", 1987 | "serde_json", 1988 | "serde_with", 1989 | "sha2 0.10.8", 1990 | "sha3 0.10.8", 1991 | "siphasher", 1992 | "solana-frozen-abi", 1993 | "solana-frozen-abi-macro", 1994 | "solana-logger", 1995 | "solana-program", 1996 | "solana-sdk-macro", 1997 | "thiserror", 1998 | "uriparse", 1999 | "wasm-bindgen", 2000 | ] 2001 | 2002 | [[package]] 2003 | name = "solana-sdk-macro" 2004 | version = "1.18.19" 2005 | source = "registry+https://github.com/rust-lang/crates.io-index" 2006 | checksum = "91222f769514bbeb30af1cbe05e6904e8364286dc6253017b1630e7835855b41" 2007 | dependencies = [ 2008 | "bs58 0.4.0", 2009 | "proc-macro2", 2010 | "quote", 2011 | "rustversion", 2012 | "syn 2.0.72", 2013 | ] 2014 | 2015 | [[package]] 2016 | name = "solana-security-txt" 2017 | version = "1.1.1" 2018 | source = "registry+https://github.com/rust-lang/crates.io-index" 2019 | checksum = "468aa43b7edb1f9b7b7b686d5c3aeb6630dc1708e86e31343499dd5c4d775183" 2020 | 2021 | [[package]] 2022 | name = "solana-zk-token-sdk" 2023 | version = "1.18.19" 2024 | source = "registry+https://github.com/rust-lang/crates.io-index" 2025 | checksum = "922f5998e2ceb3d64f64f297445c3ed442320569e4d22a940a7e855bde2a90f5" 2026 | dependencies = [ 2027 | "aes-gcm-siv", 2028 | "base64 0.21.7", 2029 | "bincode", 2030 | "bytemuck", 2031 | "byteorder", 2032 | "curve25519-dalek", 2033 | "getrandom 0.1.16", 2034 | "itertools", 2035 | "lazy_static", 2036 | "merlin", 2037 | "num-derive", 2038 | "num-traits", 2039 | "rand 0.7.3", 2040 | "serde", 2041 | "serde_json", 2042 | "sha3 0.9.1", 2043 | "solana-program", 2044 | "solana-sdk", 2045 | "subtle", 2046 | "thiserror", 2047 | "zeroize", 2048 | ] 2049 | 2050 | [[package]] 2051 | name = "spl-associated-token-account" 2052 | version = "3.0.4" 2053 | source = "registry+https://github.com/rust-lang/crates.io-index" 2054 | checksum = "143109d789171379e6143ef23191786dfaac54289ad6e7917cfb26b36c432b10" 2055 | dependencies = [ 2056 | "assert_matches", 2057 | "borsh 1.5.1", 2058 | "num-derive", 2059 | "num-traits", 2060 | "solana-program", 2061 | "spl-token", 2062 | "spl-token-2022", 2063 | "thiserror", 2064 | ] 2065 | 2066 | [[package]] 2067 | name = "spl-discriminator" 2068 | version = "0.2.5" 2069 | source = "registry+https://github.com/rust-lang/crates.io-index" 2070 | checksum = "210101376962bb22bb13be6daea34656ea1cbc248fce2164b146e39203b55e03" 2071 | dependencies = [ 2072 | "bytemuck", 2073 | "solana-program", 2074 | "spl-discriminator-derive", 2075 | ] 2076 | 2077 | [[package]] 2078 | name = "spl-discriminator-derive" 2079 | version = "0.2.0" 2080 | source = "registry+https://github.com/rust-lang/crates.io-index" 2081 | checksum = "d9e8418ea6269dcfb01c712f0444d2c75542c04448b480e87de59d2865edc750" 2082 | dependencies = [ 2083 | "quote", 2084 | "spl-discriminator-syn", 2085 | "syn 2.0.72", 2086 | ] 2087 | 2088 | [[package]] 2089 | name = "spl-discriminator-syn" 2090 | version = "0.2.0" 2091 | source = "registry+https://github.com/rust-lang/crates.io-index" 2092 | checksum = "8c1f05593b7ca9eac7caca309720f2eafb96355e037e6d373b909a80fe7b69b9" 2093 | dependencies = [ 2094 | "proc-macro2", 2095 | "quote", 2096 | "sha2 0.10.8", 2097 | "syn 2.0.72", 2098 | "thiserror", 2099 | ] 2100 | 2101 | [[package]] 2102 | name = "spl-memo" 2103 | version = "4.0.4" 2104 | source = "registry+https://github.com/rust-lang/crates.io-index" 2105 | checksum = "a49f49f95f2d02111ded31696ab38a081fab623d4c76bd4cb074286db4560836" 2106 | dependencies = [ 2107 | "solana-program", 2108 | ] 2109 | 2110 | [[package]] 2111 | name = "spl-pod" 2112 | version = "0.2.5" 2113 | source = "registry+https://github.com/rust-lang/crates.io-index" 2114 | checksum = "c52d84c55efeef8edcc226743dc089d7e3888b8e3474569aa3eff152b37b9996" 2115 | dependencies = [ 2116 | "borsh 1.5.1", 2117 | "bytemuck", 2118 | "solana-program", 2119 | "solana-zk-token-sdk", 2120 | "spl-program-error", 2121 | ] 2122 | 2123 | [[package]] 2124 | name = "spl-program-error" 2125 | version = "0.4.4" 2126 | source = "registry+https://github.com/rust-lang/crates.io-index" 2127 | checksum = "e45a49acb925db68aa501b926096b2164adbdcade7a0c24152af9f0742d0a602" 2128 | dependencies = [ 2129 | "num-derive", 2130 | "num-traits", 2131 | "solana-program", 2132 | "spl-program-error-derive", 2133 | "thiserror", 2134 | ] 2135 | 2136 | [[package]] 2137 | name = "spl-program-error-derive" 2138 | version = "0.4.1" 2139 | source = "registry+https://github.com/rust-lang/crates.io-index" 2140 | checksum = "e6d375dd76c517836353e093c2dbb490938ff72821ab568b545fd30ab3256b3e" 2141 | dependencies = [ 2142 | "proc-macro2", 2143 | "quote", 2144 | "sha2 0.10.8", 2145 | "syn 2.0.72", 2146 | ] 2147 | 2148 | [[package]] 2149 | name = "spl-tlv-account-resolution" 2150 | version = "0.6.5" 2151 | source = "registry+https://github.com/rust-lang/crates.io-index" 2152 | checksum = "fab8edfd37be5fa17c9e42c1bff86abbbaf0494b031b37957f2728ad2ff842ba" 2153 | dependencies = [ 2154 | "bytemuck", 2155 | "solana-program", 2156 | "spl-discriminator", 2157 | "spl-pod", 2158 | "spl-program-error", 2159 | "spl-type-length-value", 2160 | ] 2161 | 2162 | [[package]] 2163 | name = "spl-token" 2164 | version = "4.0.3" 2165 | source = "registry+https://github.com/rust-lang/crates.io-index" 2166 | checksum = "b9eb465e4bf5ce1d498f05204c8089378c1ba34ef2777ea95852fc53a1fd4fb2" 2167 | dependencies = [ 2168 | "arrayref", 2169 | "bytemuck", 2170 | "num-derive", 2171 | "num-traits", 2172 | "num_enum", 2173 | "solana-program", 2174 | "thiserror", 2175 | ] 2176 | 2177 | [[package]] 2178 | name = "spl-token-2022" 2179 | version = "3.0.5" 2180 | source = "registry+https://github.com/rust-lang/crates.io-index" 2181 | checksum = "4c39e416aeb1ea0b22f3b2bbecaf7e38a92a1aa8f4a0c5785c94179694e846a0" 2182 | dependencies = [ 2183 | "arrayref", 2184 | "bytemuck", 2185 | "num-derive", 2186 | "num-traits", 2187 | "num_enum", 2188 | "solana-program", 2189 | "solana-security-txt", 2190 | "solana-zk-token-sdk", 2191 | "spl-memo", 2192 | "spl-pod", 2193 | "spl-token", 2194 | "spl-token-group-interface", 2195 | "spl-token-metadata-interface", 2196 | "spl-transfer-hook-interface", 2197 | "spl-type-length-value", 2198 | "thiserror", 2199 | ] 2200 | 2201 | [[package]] 2202 | name = "spl-token-group-interface" 2203 | version = "0.2.5" 2204 | source = "registry+https://github.com/rust-lang/crates.io-index" 2205 | checksum = "014817d6324b1e20c4bbc883e8ee30a5faa13e59d91d1b2b95df98b920150c17" 2206 | dependencies = [ 2207 | "bytemuck", 2208 | "solana-program", 2209 | "spl-discriminator", 2210 | "spl-pod", 2211 | "spl-program-error", 2212 | ] 2213 | 2214 | [[package]] 2215 | name = "spl-token-metadata-interface" 2216 | version = "0.3.5" 2217 | source = "registry+https://github.com/rust-lang/crates.io-index" 2218 | checksum = "f3da00495b602ebcf5d8ba8b3ecff1ee454ce4c125c9077747be49c2d62335ba" 2219 | dependencies = [ 2220 | "borsh 1.5.1", 2221 | "solana-program", 2222 | "spl-discriminator", 2223 | "spl-pod", 2224 | "spl-program-error", 2225 | "spl-type-length-value", 2226 | ] 2227 | 2228 | [[package]] 2229 | name = "spl-transfer-hook-interface" 2230 | version = "0.6.5" 2231 | source = "registry+https://github.com/rust-lang/crates.io-index" 2232 | checksum = "a9b5c08a89838e5a2931f79b17f611857f281a14a2100968a3ccef352cb7414b" 2233 | dependencies = [ 2234 | "arrayref", 2235 | "bytemuck", 2236 | "solana-program", 2237 | "spl-discriminator", 2238 | "spl-pod", 2239 | "spl-program-error", 2240 | "spl-tlv-account-resolution", 2241 | "spl-type-length-value", 2242 | ] 2243 | 2244 | [[package]] 2245 | name = "spl-type-length-value" 2246 | version = "0.4.6" 2247 | source = "registry+https://github.com/rust-lang/crates.io-index" 2248 | checksum = "c872f93d0600e743116501eba2d53460e73a12c9a496875a42a7d70e034fe06d" 2249 | dependencies = [ 2250 | "bytemuck", 2251 | "solana-program", 2252 | "spl-discriminator", 2253 | "spl-pod", 2254 | "spl-program-error", 2255 | ] 2256 | 2257 | [[package]] 2258 | name = "strsim" 2259 | version = "0.11.1" 2260 | source = "registry+https://github.com/rust-lang/crates.io-index" 2261 | checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f" 2262 | 2263 | [[package]] 2264 | name = "subtle" 2265 | version = "2.4.1" 2266 | source = "registry+https://github.com/rust-lang/crates.io-index" 2267 | checksum = "6bdef32e8150c2a081110b42772ffe7d7c9032b606bc226c8260fd97e0976601" 2268 | 2269 | [[package]] 2270 | name = "syn" 2271 | version = "1.0.109" 2272 | source = "registry+https://github.com/rust-lang/crates.io-index" 2273 | checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" 2274 | dependencies = [ 2275 | "proc-macro2", 2276 | "quote", 2277 | "unicode-ident", 2278 | ] 2279 | 2280 | [[package]] 2281 | name = "syn" 2282 | version = "2.0.72" 2283 | source = "registry+https://github.com/rust-lang/crates.io-index" 2284 | checksum = "dc4b9b9bf2add8093d3f2c0204471e951b2285580335de42f9d2534f3ae7a8af" 2285 | dependencies = [ 2286 | "proc-macro2", 2287 | "quote", 2288 | "unicode-ident", 2289 | ] 2290 | 2291 | [[package]] 2292 | name = "syn_derive" 2293 | version = "0.1.8" 2294 | source = "registry+https://github.com/rust-lang/crates.io-index" 2295 | checksum = "1329189c02ff984e9736652b1631330da25eaa6bc639089ed4915d25446cbe7b" 2296 | dependencies = [ 2297 | "proc-macro-error", 2298 | "proc-macro2", 2299 | "quote", 2300 | "syn 2.0.72", 2301 | ] 2302 | 2303 | [[package]] 2304 | name = "termcolor" 2305 | version = "1.4.1" 2306 | source = "registry+https://github.com/rust-lang/crates.io-index" 2307 | checksum = "06794f8f6c5c898b3275aebefa6b8a1cb24cd2c6c79397ab15774837a0bc5755" 2308 | dependencies = [ 2309 | "winapi-util", 2310 | ] 2311 | 2312 | [[package]] 2313 | name = "thiserror" 2314 | version = "1.0.63" 2315 | source = "registry+https://github.com/rust-lang/crates.io-index" 2316 | checksum = "c0342370b38b6a11b6cc11d6a805569958d54cfa061a29969c3b5ce2ea405724" 2317 | dependencies = [ 2318 | "thiserror-impl", 2319 | ] 2320 | 2321 | [[package]] 2322 | name = "thiserror-impl" 2323 | version = "1.0.63" 2324 | source = "registry+https://github.com/rust-lang/crates.io-index" 2325 | checksum = "a4558b58466b9ad7ca0f102865eccc95938dca1a74a856f2b57b6629050da261" 2326 | dependencies = [ 2327 | "proc-macro2", 2328 | "quote", 2329 | "syn 2.0.72", 2330 | ] 2331 | 2332 | [[package]] 2333 | name = "tiny-bip39" 2334 | version = "0.8.2" 2335 | source = "registry+https://github.com/rust-lang/crates.io-index" 2336 | checksum = "ffc59cb9dfc85bb312c3a78fd6aa8a8582e310b0fa885d5bb877f6dcc601839d" 2337 | dependencies = [ 2338 | "anyhow", 2339 | "hmac 0.8.1", 2340 | "once_cell", 2341 | "pbkdf2 0.4.0", 2342 | "rand 0.7.3", 2343 | "rustc-hash", 2344 | "sha2 0.9.9", 2345 | "thiserror", 2346 | "unicode-normalization", 2347 | "wasm-bindgen", 2348 | "zeroize", 2349 | ] 2350 | 2351 | [[package]] 2352 | name = "tinyvec" 2353 | version = "1.8.0" 2354 | source = "registry+https://github.com/rust-lang/crates.io-index" 2355 | checksum = "445e881f4f6d382d5f27c034e25eb92edd7c784ceab92a0937db7f2e9471b938" 2356 | dependencies = [ 2357 | "tinyvec_macros", 2358 | ] 2359 | 2360 | [[package]] 2361 | name = "tinyvec_macros" 2362 | version = "0.1.1" 2363 | source = "registry+https://github.com/rust-lang/crates.io-index" 2364 | checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" 2365 | 2366 | [[package]] 2367 | name = "toml" 2368 | version = "0.5.11" 2369 | source = "registry+https://github.com/rust-lang/crates.io-index" 2370 | checksum = "f4f7f0dd8d50a853a531c426359045b1998f04219d88799810762cd4ad314234" 2371 | dependencies = [ 2372 | "serde", 2373 | ] 2374 | 2375 | [[package]] 2376 | name = "toml" 2377 | version = "0.8.15" 2378 | source = "registry+https://github.com/rust-lang/crates.io-index" 2379 | checksum = "ac2caab0bf757388c6c0ae23b3293fdb463fee59434529014f85e3263b995c28" 2380 | dependencies = [ 2381 | "serde", 2382 | "serde_spanned", 2383 | "toml_datetime", 2384 | "toml_edit 0.22.16", 2385 | ] 2386 | 2387 | [[package]] 2388 | name = "toml_datetime" 2389 | version = "0.6.6" 2390 | source = "registry+https://github.com/rust-lang/crates.io-index" 2391 | checksum = "4badfd56924ae69bcc9039335b2e017639ce3f9b001c393c1b2d1ef846ce2cbf" 2392 | dependencies = [ 2393 | "serde", 2394 | ] 2395 | 2396 | [[package]] 2397 | name = "toml_edit" 2398 | version = "0.21.1" 2399 | source = "registry+https://github.com/rust-lang/crates.io-index" 2400 | checksum = "6a8534fd7f78b5405e860340ad6575217ce99f38d4d5c8f2442cb5ecb50090e1" 2401 | dependencies = [ 2402 | "indexmap", 2403 | "toml_datetime", 2404 | "winnow 0.5.40", 2405 | ] 2406 | 2407 | [[package]] 2408 | name = "toml_edit" 2409 | version = "0.22.16" 2410 | source = "registry+https://github.com/rust-lang/crates.io-index" 2411 | checksum = "278f3d518e152219c994ce877758516bca5e118eaed6996192a774fb9fbf0788" 2412 | dependencies = [ 2413 | "indexmap", 2414 | "serde", 2415 | "serde_spanned", 2416 | "toml_datetime", 2417 | "winnow 0.6.15", 2418 | ] 2419 | 2420 | [[package]] 2421 | name = "typenum" 2422 | version = "1.17.0" 2423 | source = "registry+https://github.com/rust-lang/crates.io-index" 2424 | checksum = "42ff0bf0c66b8238c6f3b578df37d0b7848e55df8577b3f74f92a69acceeb825" 2425 | 2426 | [[package]] 2427 | name = "unicode-ident" 2428 | version = "1.0.12" 2429 | source = "registry+https://github.com/rust-lang/crates.io-index" 2430 | checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" 2431 | 2432 | [[package]] 2433 | name = "unicode-normalization" 2434 | version = "0.1.23" 2435 | source = "registry+https://github.com/rust-lang/crates.io-index" 2436 | checksum = "a56d1686db2308d901306f92a263857ef59ea39678a5458e7cb17f01415101f5" 2437 | dependencies = [ 2438 | "tinyvec", 2439 | ] 2440 | 2441 | [[package]] 2442 | name = "unicode-segmentation" 2443 | version = "1.11.0" 2444 | source = "registry+https://github.com/rust-lang/crates.io-index" 2445 | checksum = "d4c87d22b6e3f4a18d4d40ef354e97c90fcb14dd91d7dc0aa9d8a1172ebf7202" 2446 | 2447 | [[package]] 2448 | name = "universal-hash" 2449 | version = "0.4.1" 2450 | source = "registry+https://github.com/rust-lang/crates.io-index" 2451 | checksum = "9f214e8f697e925001e66ec2c6e37a4ef93f0f78c2eed7814394e10c62025b05" 2452 | dependencies = [ 2453 | "generic-array", 2454 | "subtle", 2455 | ] 2456 | 2457 | [[package]] 2458 | name = "uriparse" 2459 | version = "0.6.4" 2460 | source = "registry+https://github.com/rust-lang/crates.io-index" 2461 | checksum = "0200d0fc04d809396c2ad43f3c95da3582a2556eba8d453c1087f4120ee352ff" 2462 | dependencies = [ 2463 | "fnv", 2464 | "lazy_static", 2465 | ] 2466 | 2467 | [[package]] 2468 | name = "version_check" 2469 | version = "0.9.4" 2470 | source = "registry+https://github.com/rust-lang/crates.io-index" 2471 | checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" 2472 | 2473 | [[package]] 2474 | name = "wasi" 2475 | version = "0.9.0+wasi-snapshot-preview1" 2476 | source = "registry+https://github.com/rust-lang/crates.io-index" 2477 | checksum = "cccddf32554fecc6acb585f82a32a72e28b48f8c4c1883ddfeeeaa96f7d8e519" 2478 | 2479 | [[package]] 2480 | name = "wasi" 2481 | version = "0.11.0+wasi-snapshot-preview1" 2482 | source = "registry+https://github.com/rust-lang/crates.io-index" 2483 | checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" 2484 | 2485 | [[package]] 2486 | name = "wasm-bindgen" 2487 | version = "0.2.92" 2488 | source = "registry+https://github.com/rust-lang/crates.io-index" 2489 | checksum = "4be2531df63900aeb2bca0daaaddec08491ee64ceecbee5076636a3b026795a8" 2490 | dependencies = [ 2491 | "cfg-if", 2492 | "wasm-bindgen-macro", 2493 | ] 2494 | 2495 | [[package]] 2496 | name = "wasm-bindgen-backend" 2497 | version = "0.2.92" 2498 | source = "registry+https://github.com/rust-lang/crates.io-index" 2499 | checksum = "614d787b966d3989fa7bb98a654e369c762374fd3213d212cfc0251257e747da" 2500 | dependencies = [ 2501 | "bumpalo", 2502 | "log", 2503 | "once_cell", 2504 | "proc-macro2", 2505 | "quote", 2506 | "syn 2.0.72", 2507 | "wasm-bindgen-shared", 2508 | ] 2509 | 2510 | [[package]] 2511 | name = "wasm-bindgen-macro" 2512 | version = "0.2.92" 2513 | source = "registry+https://github.com/rust-lang/crates.io-index" 2514 | checksum = "a1f8823de937b71b9460c0c34e25f3da88250760bec0ebac694b49997550d726" 2515 | dependencies = [ 2516 | "quote", 2517 | "wasm-bindgen-macro-support", 2518 | ] 2519 | 2520 | [[package]] 2521 | name = "wasm-bindgen-macro-support" 2522 | version = "0.2.92" 2523 | source = "registry+https://github.com/rust-lang/crates.io-index" 2524 | checksum = "e94f17b526d0a461a191c78ea52bbce64071ed5c04c9ffe424dcb38f74171bb7" 2525 | dependencies = [ 2526 | "proc-macro2", 2527 | "quote", 2528 | "syn 2.0.72", 2529 | "wasm-bindgen-backend", 2530 | "wasm-bindgen-shared", 2531 | ] 2532 | 2533 | [[package]] 2534 | name = "wasm-bindgen-shared" 2535 | version = "0.2.92" 2536 | source = "registry+https://github.com/rust-lang/crates.io-index" 2537 | checksum = "af190c94f2773fdb3729c55b007a722abb5384da03bc0986df4c289bf5567e96" 2538 | 2539 | [[package]] 2540 | name = "web-sys" 2541 | version = "0.3.69" 2542 | source = "registry+https://github.com/rust-lang/crates.io-index" 2543 | checksum = "77afa9a11836342370f4817622a2f0f418b134426d91a82dfb48f532d2ec13ef" 2544 | dependencies = [ 2545 | "js-sys", 2546 | "wasm-bindgen", 2547 | ] 2548 | 2549 | [[package]] 2550 | name = "winapi" 2551 | version = "0.3.9" 2552 | source = "registry+https://github.com/rust-lang/crates.io-index" 2553 | checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" 2554 | dependencies = [ 2555 | "winapi-i686-pc-windows-gnu", 2556 | "winapi-x86_64-pc-windows-gnu", 2557 | ] 2558 | 2559 | [[package]] 2560 | name = "winapi-i686-pc-windows-gnu" 2561 | version = "0.4.0" 2562 | source = "registry+https://github.com/rust-lang/crates.io-index" 2563 | checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" 2564 | 2565 | [[package]] 2566 | name = "winapi-util" 2567 | version = "0.1.9" 2568 | source = "registry+https://github.com/rust-lang/crates.io-index" 2569 | checksum = "cf221c93e13a30d793f7645a0e7762c55d169dbb0a49671918a2319d289b10bb" 2570 | dependencies = [ 2571 | "windows-sys", 2572 | ] 2573 | 2574 | [[package]] 2575 | name = "winapi-x86_64-pc-windows-gnu" 2576 | version = "0.4.0" 2577 | source = "registry+https://github.com/rust-lang/crates.io-index" 2578 | checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" 2579 | 2580 | [[package]] 2581 | name = "windows-sys" 2582 | version = "0.59.0" 2583 | source = "registry+https://github.com/rust-lang/crates.io-index" 2584 | checksum = "1e38bc4d79ed67fd075bcc251a1c39b32a1776bbe92e5bef1f0bf1f8c531853b" 2585 | dependencies = [ 2586 | "windows-targets", 2587 | ] 2588 | 2589 | [[package]] 2590 | name = "windows-targets" 2591 | version = "0.52.6" 2592 | source = "registry+https://github.com/rust-lang/crates.io-index" 2593 | checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973" 2594 | dependencies = [ 2595 | "windows_aarch64_gnullvm", 2596 | "windows_aarch64_msvc", 2597 | "windows_i686_gnu", 2598 | "windows_i686_gnullvm", 2599 | "windows_i686_msvc", 2600 | "windows_x86_64_gnu", 2601 | "windows_x86_64_gnullvm", 2602 | "windows_x86_64_msvc", 2603 | ] 2604 | 2605 | [[package]] 2606 | name = "windows_aarch64_gnullvm" 2607 | version = "0.52.6" 2608 | source = "registry+https://github.com/rust-lang/crates.io-index" 2609 | checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3" 2610 | 2611 | [[package]] 2612 | name = "windows_aarch64_msvc" 2613 | version = "0.52.6" 2614 | source = "registry+https://github.com/rust-lang/crates.io-index" 2615 | checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469" 2616 | 2617 | [[package]] 2618 | name = "windows_i686_gnu" 2619 | version = "0.52.6" 2620 | source = "registry+https://github.com/rust-lang/crates.io-index" 2621 | checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b" 2622 | 2623 | [[package]] 2624 | name = "windows_i686_gnullvm" 2625 | version = "0.52.6" 2626 | source = "registry+https://github.com/rust-lang/crates.io-index" 2627 | checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66" 2628 | 2629 | [[package]] 2630 | name = "windows_i686_msvc" 2631 | version = "0.52.6" 2632 | source = "registry+https://github.com/rust-lang/crates.io-index" 2633 | checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66" 2634 | 2635 | [[package]] 2636 | name = "windows_x86_64_gnu" 2637 | version = "0.52.6" 2638 | source = "registry+https://github.com/rust-lang/crates.io-index" 2639 | checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78" 2640 | 2641 | [[package]] 2642 | name = "windows_x86_64_gnullvm" 2643 | version = "0.52.6" 2644 | source = "registry+https://github.com/rust-lang/crates.io-index" 2645 | checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d" 2646 | 2647 | [[package]] 2648 | name = "windows_x86_64_msvc" 2649 | version = "0.52.6" 2650 | source = "registry+https://github.com/rust-lang/crates.io-index" 2651 | checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" 2652 | 2653 | [[package]] 2654 | name = "winnow" 2655 | version = "0.5.40" 2656 | source = "registry+https://github.com/rust-lang/crates.io-index" 2657 | checksum = "f593a95398737aeed53e489c785df13f3618e41dbcd6718c6addbf1395aa6876" 2658 | dependencies = [ 2659 | "memchr", 2660 | ] 2661 | 2662 | [[package]] 2663 | name = "winnow" 2664 | version = "0.6.15" 2665 | source = "registry+https://github.com/rust-lang/crates.io-index" 2666 | checksum = "557404e450152cd6795bb558bca69e43c585055f4606e3bcae5894fc6dac9ba0" 2667 | dependencies = [ 2668 | "memchr", 2669 | ] 2670 | 2671 | [[package]] 2672 | name = "zerocopy" 2673 | version = "0.7.35" 2674 | source = "registry+https://github.com/rust-lang/crates.io-index" 2675 | checksum = "1b9b4fd18abc82b8136838da5d50bae7bdea537c574d8dc1a34ed098d6c166f0" 2676 | dependencies = [ 2677 | "zerocopy-derive", 2678 | ] 2679 | 2680 | [[package]] 2681 | name = "zerocopy-derive" 2682 | version = "0.7.35" 2683 | source = "registry+https://github.com/rust-lang/crates.io-index" 2684 | checksum = "fa4f8080344d4671fb4e831a13ad1e68092748387dfc4f55e356242fae12ce3e" 2685 | dependencies = [ 2686 | "proc-macro2", 2687 | "quote", 2688 | "syn 2.0.72", 2689 | ] 2690 | 2691 | [[package]] 2692 | name = "zeroize" 2693 | version = "1.3.0" 2694 | source = "registry+https://github.com/rust-lang/crates.io-index" 2695 | checksum = "4756f7db3f7b5574938c3eb1c117038b8e07f95ee6718c0efad4ac21508f1efd" 2696 | dependencies = [ 2697 | "zeroize_derive", 2698 | ] 2699 | 2700 | [[package]] 2701 | name = "zeroize_derive" 2702 | version = "1.4.2" 2703 | source = "registry+https://github.com/rust-lang/crates.io-index" 2704 | checksum = "ce36e65b0d2999d2aafac989fb249189a141aee1f53c612c1f37d72631959f69" 2705 | dependencies = [ 2706 | "proc-macro2", 2707 | "quote", 2708 | "syn 2.0.72", 2709 | ] 2710 | --------------------------------------------------------------------------------