pda-explorer-react 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +159 -0
- package/dist/components/AccountNode.d.ts +17 -0
- package/dist/components/PdaExplorer.d.ts +29 -0
- package/dist/components/PdaGraph.d.ts +18 -0
- package/dist/components/SeedPanel.d.ts +11 -0
- package/dist/components/index.d.ts +5 -0
- package/dist/index.cjs +48 -0
- package/dist/index.d.ts +4 -0
- package/dist/index.js +11957 -0
- package/dist/styles.css +1 -0
- package/dist/types/graph.d.ts +29 -0
- package/dist/types/index.d.ts +2 -0
- package/dist/types/schema.d.ts +84 -0
- package/package.json +64 -0
package/dist/styles.css
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
*,:after,:before{--tw-border-spacing-x:0;--tw-border-spacing-y:0;--tw-translate-x:0;--tw-translate-y:0;--tw-rotate:0;--tw-skew-x:0;--tw-skew-y:0;--tw-scale-x:1;--tw-scale-y:1;--tw-pan-x: ;--tw-pan-y: ;--tw-pinch-zoom: ;--tw-scroll-snap-strictness:proximity;--tw-gradient-from-position: ;--tw-gradient-via-position: ;--tw-gradient-to-position: ;--tw-ordinal: ;--tw-slashed-zero: ;--tw-numeric-figure: ;--tw-numeric-spacing: ;--tw-numeric-fraction: ;--tw-ring-inset: ;--tw-ring-offset-width:0px;--tw-ring-offset-color:#fff;--tw-ring-color:rgba(59,130,246,.5);--tw-ring-offset-shadow:0 0 #0000;--tw-ring-shadow:0 0 #0000;--tw-shadow:0 0 #0000;--tw-shadow-colored:0 0 #0000;--tw-blur: ;--tw-brightness: ;--tw-contrast: ;--tw-grayscale: ;--tw-hue-rotate: ;--tw-invert: ;--tw-saturate: ;--tw-sepia: ;--tw-drop-shadow: ;--tw-backdrop-blur: ;--tw-backdrop-brightness: ;--tw-backdrop-contrast: ;--tw-backdrop-grayscale: ;--tw-backdrop-hue-rotate: ;--tw-backdrop-invert: ;--tw-backdrop-opacity: ;--tw-backdrop-saturate: ;--tw-backdrop-sepia: ;--tw-contain-size: ;--tw-contain-layout: ;--tw-contain-paint: ;--tw-contain-style: }::backdrop{--tw-border-spacing-x:0;--tw-border-spacing-y:0;--tw-translate-x:0;--tw-translate-y:0;--tw-rotate:0;--tw-skew-x:0;--tw-skew-y:0;--tw-scale-x:1;--tw-scale-y:1;--tw-pan-x: ;--tw-pan-y: ;--tw-pinch-zoom: ;--tw-scroll-snap-strictness:proximity;--tw-gradient-from-position: ;--tw-gradient-via-position: ;--tw-gradient-to-position: ;--tw-ordinal: ;--tw-slashed-zero: ;--tw-numeric-figure: ;--tw-numeric-spacing: ;--tw-numeric-fraction: ;--tw-ring-inset: ;--tw-ring-offset-width:0px;--tw-ring-offset-color:#fff;--tw-ring-color:rgba(59,130,246,.5);--tw-ring-offset-shadow:0 0 #0000;--tw-ring-shadow:0 0 #0000;--tw-shadow:0 0 #0000;--tw-shadow-colored:0 0 #0000;--tw-blur: ;--tw-brightness: ;--tw-contrast: ;--tw-grayscale: ;--tw-hue-rotate: ;--tw-invert: ;--tw-saturate: ;--tw-sepia: ;--tw-drop-shadow: ;--tw-backdrop-blur: ;--tw-backdrop-brightness: ;--tw-backdrop-contrast: ;--tw-backdrop-grayscale: ;--tw-backdrop-hue-rotate: ;--tw-backdrop-invert: ;--tw-backdrop-opacity: ;--tw-backdrop-saturate: ;--tw-backdrop-sepia: ;--tw-contain-size: ;--tw-contain-layout: ;--tw-contain-paint: ;--tw-contain-style: }/*! tailwindcss v3.4.19 | MIT License | https://tailwindcss.com*/*,:after,:before{box-sizing:border-box;border:0 solid #e5e7eb}:after,:before{--tw-content:""}:host,html{line-height:1.5;-webkit-text-size-adjust:100%;-moz-tab-size:4;-o-tab-size:4;tab-size:4;font-family:ui-sans-serif,system-ui,sans-serif,Apple Color Emoji,Segoe UI Emoji,Segoe UI Symbol,Noto Color Emoji;font-feature-settings:normal;font-variation-settings:normal;-webkit-tap-highlight-color:transparent}body{margin:0;line-height:inherit}hr{height:0;color:inherit;border-top-width:1px}abbr:where([title]){-webkit-text-decoration:underline dotted;text-decoration:underline dotted}h1,h2,h3,h4,h5,h6{font-size:inherit;font-weight:inherit}a{color:inherit;text-decoration:inherit}b,strong{font-weight:bolder}code,kbd,pre,samp{font-family:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,monospace;font-feature-settings:normal;font-variation-settings:normal;font-size:1em}small{font-size:80%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sub{bottom:-.25em}sup{top:-.5em}table{text-indent:0;border-color:inherit;border-collapse:collapse}button,input,optgroup,select,textarea{font-family:inherit;font-feature-settings:inherit;font-variation-settings:inherit;font-size:100%;font-weight:inherit;line-height:inherit;letter-spacing:inherit;color:inherit;margin:0;padding:0}button,select{text-transform:none}button,input:where([type=button]),input:where([type=reset]),input:where([type=submit]){-webkit-appearance:button;background-color:transparent;background-image:none}:-moz-focusring{outline:auto}:-moz-ui-invalid{box-shadow:none}progress{vertical-align:baseline}::-webkit-inner-spin-button,::-webkit-outer-spin-button{height:auto}[type=search]{-webkit-appearance:textfield;outline-offset:-2px}::-webkit-search-decoration{-webkit-appearance:none}::-webkit-file-upload-button{-webkit-appearance:button;font:inherit}summary{display:list-item}blockquote,dd,dl,figure,h1,h2,h3,h4,h5,h6,hr,p,pre{margin:0}fieldset{margin:0}fieldset,legend{padding:0}menu,ol,ul{list-style:none;margin:0;padding:0}dialog{padding:0}textarea{resize:vertical}input::-moz-placeholder,textarea::-moz-placeholder{opacity:1;color:#9ca3af}input::placeholder,textarea::placeholder{opacity:1;color:#9ca3af}[role=button],button{cursor:pointer}:disabled{cursor:default}audio,canvas,embed,iframe,img,object,svg,video{display:block;vertical-align:middle}img,video{max-width:100%;height:auto}[hidden]:where(:not([hidden=until-found])){display:none}.container{width:100%}@media (min-width:640px){.container{max-width:640px}}@media (min-width:768px){.container{max-width:768px}}@media (min-width:1024px){.container{max-width:1024px}}@media (min-width:1280px){.container{max-width:1280px}}@media (min-width:1536px){.container{max-width:1536px}}.static{position:static}.mx-auto{margin-left:auto;margin-right:auto}.mb-2{margin-bottom:.5rem}.mb-3{margin-bottom:.75rem}.mb-4{margin-bottom:1rem}.mt-1{margin-top:.25rem}.mt-2{margin-top:.5rem}.mt-4{margin-top:1rem}.flex{display:flex}.inline-flex{display:inline-flex}.\!h-3{height:.75rem!important}.h-12{height:3rem}.h-2{height:.5rem}.h-3{height:.75rem}.h-4{height:1rem}.h-full{height:100%}.min-h-0{min-height:0}.min-h-screen{min-height:100vh}.\!w-3{width:.75rem!important}.w-12{width:3rem}.w-16{width:4rem}.w-2{width:.5rem}.w-3{width:.75rem}.w-4{width:1rem}.w-full{width:100%}.min-w-\[160px\]{min-width:160px}.max-w-7xl{max-width:80rem}.flex-1{flex:1 1 0%}.cursor-pointer{cursor:pointer}.flex-col{flex-direction:column}.flex-wrap{flex-wrap:wrap}.items-start{align-items:flex-start}.items-center{align-items:center}.justify-center{justify-content:center}.justify-between{justify-content:space-between}.gap-1{gap:.25rem}.gap-1\.5{gap:.375rem}.gap-2{gap:.5rem}.gap-3{gap:.75rem}.gap-4{gap:1rem}.space-y-2>:not([hidden])~:not([hidden]){--tw-space-y-reverse:0;margin-top:calc(.5rem*(1 - var(--tw-space-y-reverse)));margin-bottom:calc(.5rem*var(--tw-space-y-reverse))}.space-y-3>:not([hidden])~:not([hidden]){--tw-space-y-reverse:0;margin-top:calc(.75rem*(1 - var(--tw-space-y-reverse)));margin-bottom:calc(.75rem*var(--tw-space-y-reverse))}.space-y-6>:not([hidden])~:not([hidden]){--tw-space-y-reverse:0;margin-top:calc(1.5rem*(1 - var(--tw-space-y-reverse)));margin-bottom:calc(1.5rem*var(--tw-space-y-reverse))}.overflow-hidden{overflow:hidden}.overflow-y-auto{overflow-y:auto}.\!rounded-lg{border-radius:.5rem!important}.rounded{border-radius:.25rem}.rounded-full{border-radius:9999px}.rounded-lg{border-radius:.5rem}.rounded-sm{border-radius:.125rem}.\!border-2{border-width:2px!important}.border{border-width:1px}.border-2{border-width:2px}.\!border-gray-700{--tw-border-opacity:1!important;border-color:rgb(55 65 81/var(--tw-border-opacity,1))!important}.border-gray-700{--tw-border-opacity:1;border-color:rgb(55 65 81/var(--tw-border-opacity,1))}.\!bg-gray-400{--tw-bg-opacity:1!important;background-color:rgb(156 163 175/var(--tw-bg-opacity,1))!important}.\!bg-gray-800{--tw-bg-opacity:1!important;background-color:rgb(31 41 55/var(--tw-bg-opacity,1))!important}.bg-blue-900\/30{background-color:rgba(30,58,138,.3)}.bg-blue-900\/50{background-color:rgba(30,58,138,.5)}.bg-gray-800{--tw-bg-opacity:1;background-color:rgb(31 41 55/var(--tw-bg-opacity,1))}.bg-gray-800\/50{background-color:rgba(31,41,55,.5)}.bg-gray-900{--tw-bg-opacity:1;background-color:rgb(17 24 39/var(--tw-bg-opacity,1))}.bg-green-900\/50{background-color:rgba(20,83,45,.5)}.bg-purple-900\/50{background-color:rgba(88,28,135,.5)}.p-3{padding:.75rem}.p-4{padding:1rem}.p-8{padding:2rem}.px-1{padding-left:.25rem;padding-right:.25rem}.px-2{padding-left:.5rem;padding-right:.5rem}.px-4{padding-left:1rem;padding-right:1rem}.py-0\.5{padding-top:.125rem;padding-bottom:.125rem}.py-1{padding-top:.25rem;padding-bottom:.25rem}.py-3{padding-top:.75rem;padding-bottom:.75rem}.pt-0\.5{padding-top:.125rem}.text-center{text-align:center}.font-mono{font-family:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,monospace}.text-2xl{font-size:1.5rem;line-height:2rem}.text-sm{font-size:.875rem;line-height:1.25rem}.text-xl{font-size:1.25rem;line-height:1.75rem}.text-xs{font-size:.75rem;line-height:1rem}.font-bold{font-weight:700}.font-semibold{font-weight:600}.uppercase{text-transform:uppercase}.italic{font-style:italic}.leading-relaxed{line-height:1.625}.tracking-wide{letter-spacing:.025em}.text-blue-400{--tw-text-opacity:1;color:rgb(96 165 250/var(--tw-text-opacity,1))}.text-gray-300{--tw-text-opacity:1;color:rgb(209 213 219/var(--tw-text-opacity,1))}.text-gray-400{--tw-text-opacity:1;color:rgb(156 163 175/var(--tw-text-opacity,1))}.text-gray-500{--tw-text-opacity:1;color:rgb(107 114 128/var(--tw-text-opacity,1))}.text-gray-600{--tw-text-opacity:1;color:rgb(75 85 99/var(--tw-text-opacity,1))}.text-green-400{--tw-text-opacity:1;color:rgb(74 222 128/var(--tw-text-opacity,1))}.text-purple-400{--tw-text-opacity:1;color:rgb(192 132 252/var(--tw-text-opacity,1))}.text-white{--tw-text-opacity:1;color:rgb(255 255 255/var(--tw-text-opacity,1))}.ring-2{--tw-ring-offset-shadow:var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow:var(--tw-ring-inset) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color);box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow,0 0 #0000)}.ring-white{--tw-ring-opacity:1;--tw-ring-color:rgb(255 255 255/var(--tw-ring-opacity,1))}.ring-offset-1{--tw-ring-offset-width:1px}.ring-offset-2{--tw-ring-offset-width:2px}.ring-offset-gray-900{--tw-ring-offset-color:#111827}.filter{filter:var(--tw-blur) var(--tw-brightness) var(--tw-contrast) var(--tw-grayscale) var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate) var(--tw-sepia) var(--tw-drop-shadow)}.transition-all{transition-property:all;transition-timing-function:cubic-bezier(.4,0,.2,1)}.duration-150,.transition-all{transition-duration:.15s}.duration-200{transition-duration:.2s}.pda-explorer{font-family:system-ui,-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Helvetica Neue,Arial,sans-serif}.pda-explorer-node{font-family:inherit}.pda-explorer-panel::-webkit-scrollbar{width:6px}.pda-explorer-panel::-webkit-scrollbar-track{background:transparent}.pda-explorer-panel::-webkit-scrollbar-thumb{background:#4b5563;border-radius:3px}.pda-explorer-panel::-webkit-scrollbar-thumb:hover{background:#6b7280}.pda-explorer-graph .react-flow__controls button{background:#1f2937;border-color:#374151;color:#9ca3af}.pda-explorer-graph .react-flow__controls button:hover{background:#374151}.pda-explorer-graph .react-flow__controls button svg{fill:currentColor}.hover\:bg-gray-800:hover{--tw-bg-opacity:1;background-color:rgb(31 41 55/var(--tw-bg-opacity,1))}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { Node, Edge } from '@xyflow/react';
|
|
2
|
+
import { PdaAccountType, SeedComponent } from './schema';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Data attached to each node in the graph
|
|
6
|
+
*/
|
|
7
|
+
export interface PdaNodeData extends Record<string, unknown> {
|
|
8
|
+
accountType: PdaAccountType;
|
|
9
|
+
label: string;
|
|
10
|
+
}
|
|
11
|
+
/**
|
|
12
|
+
* Custom node type for React Flow
|
|
13
|
+
*/
|
|
14
|
+
export type PdaNode = Node<PdaNodeData, "account">;
|
|
15
|
+
/**
|
|
16
|
+
* Edge data for relationships between PDAs
|
|
17
|
+
*/
|
|
18
|
+
export interface PdaEdgeData extends Record<string, unknown> {
|
|
19
|
+
relationship: "parent-child" | "reference";
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* Custom edge type for React Flow
|
|
23
|
+
*/
|
|
24
|
+
export type PdaEdge = Edge<PdaEdgeData>;
|
|
25
|
+
/**
|
|
26
|
+
* Seed type display configuration
|
|
27
|
+
*/
|
|
28
|
+
export declare const SEED_TYPE_COLORS: Record<SeedComponent["type"], string>;
|
|
29
|
+
export declare const SEED_TYPE_LABELS: Record<SeedComponent["type"], string>;
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* PDA Schema Types
|
|
3
|
+
*
|
|
4
|
+
* These types define the schema format for describing a Solana program's
|
|
5
|
+
* PDA (Program Derived Address) hierarchy. Any Solana program can define
|
|
6
|
+
* its account model using this schema.
|
|
7
|
+
*/
|
|
8
|
+
/**
|
|
9
|
+
* Seed component types
|
|
10
|
+
* - literal: A static string/bytes value (e.g., "board", "membership")
|
|
11
|
+
* - pubkey: A 32-byte public key
|
|
12
|
+
* - u8/u16/u32/u64: Unsigned integers (stored as little-endian bytes)
|
|
13
|
+
*/
|
|
14
|
+
export type SeedType = "literal" | "pubkey" | "u8" | "u16" | "u32" | "u64";
|
|
15
|
+
/**
|
|
16
|
+
* A single component of a PDA seed
|
|
17
|
+
*/
|
|
18
|
+
export interface SeedComponent {
|
|
19
|
+
/** Name of this seed component (for display) */
|
|
20
|
+
name: string;
|
|
21
|
+
/** Type of the seed value */
|
|
22
|
+
type: SeedType;
|
|
23
|
+
/** For literal seeds: the actual string value */
|
|
24
|
+
value?: string;
|
|
25
|
+
/** Human-readable description of where this value comes from */
|
|
26
|
+
source?: string;
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Definition of a single PDA account type
|
|
30
|
+
*/
|
|
31
|
+
export interface PdaAccountType {
|
|
32
|
+
/** Unique identifier for this account type */
|
|
33
|
+
id: string;
|
|
34
|
+
/** Human-readable display name */
|
|
35
|
+
name: string;
|
|
36
|
+
/** Seed components used to derive this PDA */
|
|
37
|
+
seeds: SeedComponent[];
|
|
38
|
+
/** ID of the parent account type (null for root-level accounts) */
|
|
39
|
+
parent: string | null;
|
|
40
|
+
/** IDs of child account types */
|
|
41
|
+
children: string[];
|
|
42
|
+
/** Description of what this account stores */
|
|
43
|
+
description: string;
|
|
44
|
+
/** Color for visualization (hex or Tailwind color) */
|
|
45
|
+
color: string;
|
|
46
|
+
/** Optional: Name of the TypeScript/Rust function that derives this PDA */
|
|
47
|
+
deriveFunctionName?: string;
|
|
48
|
+
/** Optional: Additional metadata */
|
|
49
|
+
metadata?: Record<string, unknown>;
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* Complete PDA schema for a Solana program
|
|
53
|
+
*/
|
|
54
|
+
export interface PdaSchema {
|
|
55
|
+
/** Name of the program */
|
|
56
|
+
programName: string;
|
|
57
|
+
/** Program ID (base58 encoded) */
|
|
58
|
+
programId?: string;
|
|
59
|
+
/** Description of the program */
|
|
60
|
+
description?: string;
|
|
61
|
+
/** Account type definitions keyed by ID */
|
|
62
|
+
accounts: Record<string, PdaAccountType>;
|
|
63
|
+
}
|
|
64
|
+
/**
|
|
65
|
+
* Helper: Get all root-level accounts (no parent)
|
|
66
|
+
*/
|
|
67
|
+
export declare function getRootAccounts(schema: PdaSchema): PdaAccountType[];
|
|
68
|
+
/**
|
|
69
|
+
* Helper: Get children of a specific account type
|
|
70
|
+
*/
|
|
71
|
+
export declare function getChildren(schema: PdaSchema, accountId: string): PdaAccountType[];
|
|
72
|
+
/**
|
|
73
|
+
* Helper: Get the parent of a specific account type
|
|
74
|
+
*/
|
|
75
|
+
export declare function getParent(schema: PdaSchema, accountId: string): PdaAccountType | null;
|
|
76
|
+
/**
|
|
77
|
+
* Helper: Format seed pattern as display string
|
|
78
|
+
* Example: ["board", pubkey, u64_le]
|
|
79
|
+
*/
|
|
80
|
+
export declare function formatSeedPattern(account: PdaAccountType): string;
|
|
81
|
+
/**
|
|
82
|
+
* Helper: Validate a PDA schema
|
|
83
|
+
*/
|
|
84
|
+
export declare function validateSchema(schema: PdaSchema): string[];
|
package/package.json
ADDED
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "pda-explorer-react",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "Interactive visualization tool for Solana Program Derived Address (PDA) hierarchies",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"main": "./dist/index.cjs",
|
|
7
|
+
"module": "./dist/index.js",
|
|
8
|
+
"types": "./dist/index.d.ts",
|
|
9
|
+
"exports": {
|
|
10
|
+
".": {
|
|
11
|
+
"import": "./dist/index.js",
|
|
12
|
+
"require": "./dist/index.cjs",
|
|
13
|
+
"types": "./dist/index.d.ts"
|
|
14
|
+
},
|
|
15
|
+
"./styles.css": "./dist/styles.css"
|
|
16
|
+
},
|
|
17
|
+
"files": [
|
|
18
|
+
"dist"
|
|
19
|
+
],
|
|
20
|
+
"scripts": {
|
|
21
|
+
"dev": "vite",
|
|
22
|
+
"build": "tsc && vite build && npm run build:css",
|
|
23
|
+
"build:css": "tailwindcss -i ./src/styles.css -o ./dist/styles.css --minify",
|
|
24
|
+
"preview": "vite preview",
|
|
25
|
+
"lint": "eslint src --ext ts,tsx",
|
|
26
|
+
"prepublishOnly": "npm run build"
|
|
27
|
+
},
|
|
28
|
+
"peerDependencies": {
|
|
29
|
+
"react": ">=17.0.0",
|
|
30
|
+
"react-dom": ">=17.0.0"
|
|
31
|
+
},
|
|
32
|
+
"dependencies": {
|
|
33
|
+
"@xyflow/react": "^12.0.0",
|
|
34
|
+
"dagre": "^0.8.5"
|
|
35
|
+
},
|
|
36
|
+
"devDependencies": {
|
|
37
|
+
"@types/dagre": "^0.7.52",
|
|
38
|
+
"@types/react": "^18.2.0",
|
|
39
|
+
"@types/react-dom": "^18.2.0",
|
|
40
|
+
"@vitejs/plugin-react": "^4.2.0",
|
|
41
|
+
"autoprefixer": "^10.4.17",
|
|
42
|
+
"postcss": "^8.4.35",
|
|
43
|
+
"react": "^18.2.0",
|
|
44
|
+
"react-dom": "^18.2.0",
|
|
45
|
+
"tailwindcss": "^3.4.1",
|
|
46
|
+
"typescript": "^5.3.0",
|
|
47
|
+
"vite": "^5.0.0",
|
|
48
|
+
"vite-plugin-dts": "^3.7.0"
|
|
49
|
+
},
|
|
50
|
+
"repository": {
|
|
51
|
+
"type": "git",
|
|
52
|
+
"url": "https://github.com/gzakhar/pda-explorer.git"
|
|
53
|
+
},
|
|
54
|
+
"keywords": [
|
|
55
|
+
"solana",
|
|
56
|
+
"pda",
|
|
57
|
+
"program-derived-address",
|
|
58
|
+
"visualization",
|
|
59
|
+
"react",
|
|
60
|
+
"developer-tools"
|
|
61
|
+
],
|
|
62
|
+
"author": "George Zakharov",
|
|
63
|
+
"license": "MIT"
|
|
64
|
+
}
|