[{"data":1,"prerenderedAt":595},["ShallowReactive",2],{"navigation_docs":3,"-developer-zone-09-local-development":121,"-developer-zone-09-local-development-surround":590},[4,60],{"title":5,"icon":6,"path":7,"stem":8,"children":9,"page":6},"User Guide",false,"/getting-started","1.getting-started",[10,15,20,25,30,35,40,45,50,55],{"title":11,"path":12,"stem":13,"icon":14},"Contribute","/getting-started/contribute","1.getting-started/10.contribute","i-lucide-git-pull-request",{"title":16,"path":17,"stem":18,"icon":19},"FAQ","/getting-started/faq","1.getting-started/11.faq","i-lucide-circle-help",{"title":21,"path":22,"stem":23,"icon":24},"Introduction","/getting-started/introduction","1.getting-started/2.introduction","i-lucide-house",{"title":26,"path":27,"stem":28,"icon":29},"Install Salmon","/getting-started/installation","1.getting-started/3.installation","i-lucide-download",{"title":31,"path":32,"stem":33,"icon":34},"Create or Restore","/getting-started/wallet-setup","1.getting-started/4.wallet-setup","i-lucide-wallet-cards",{"title":36,"path":37,"stem":38,"icon":39},"Use the Wallet","/getting-started/using-salmon","1.getting-started/5.using-salmon","i-lucide-send",{"title":41,"path":42,"stem":43,"icon":44},"Accounts and Settings","/getting-started/settings","1.getting-started/6.settings","i-lucide-settings",{"title":46,"path":47,"stem":48,"icon":49},"Connect to dApps","/getting-started/dapps","1.getting-started/7.dapps","i-lucide-plug",{"title":51,"path":52,"stem":53,"icon":54},"Security and Self-Custody","/getting-started/self-custody","1.getting-started/8.self-custody","i-lucide-shield-check",{"title":56,"path":57,"stem":58,"icon":59},"Releases","/getting-started/release-notes","1.getting-started/9.release-notes","i-lucide-clipboard-list",{"title":61,"icon":62,"path":63,"stem":64,"children":65,"page":6},"Developer Guide","i-lucide-cpu","/developer-zone","2.developer-zone",[66,71,76,81,86,91,96,101,106,111,116],{"title":67,"path":68,"stem":69,"icon":70},"System Overview","/developer-zone/00_stack_and_contributing","2.developer-zone/00_stack_and_contributing","i-lucide-boxes",{"title":72,"path":73,"stem":74,"icon":75},"Frontend Architecture","/developer-zone/01_onboarding_flow","2.developer-zone/01_onboarding_flow","i-lucide-panels-top-left",{"title":77,"path":78,"stem":79,"icon":80},"UI and Design System","/developer-zone/02_ui_component_library","2.developer-zone/02_ui_component_library","i-lucide-layout-template",{"title":82,"path":83,"stem":84,"icon":85},"Product Flows","/developer-zone/03_route_navigation_system","2.developer-zone/03_route_navigation_system","i-lucide-route",{"title":87,"path":88,"stem":89,"icon":90},"State, Storage, and Vault","/developer-zone/04_appcontext","2.developer-zone/04_appcontext","i-lucide-database",{"title":92,"path":93,"stem":94,"icon":95},"Backend Architecture","/developer-zone/05_storage_and_persistence_layer","2.developer-zone/05_storage_and_persistence_layer","i-lucide-server",{"title":97,"path":98,"stem":99,"icon":100},"Internationalization","/developer-zone/06_translation_system","2.developer-zone/06_translation_system","i-lucide-languages",{"title":102,"path":103,"stem":104,"icon":105},"Blockchain Integration","/developer-zone/07_blockchain_account_abstraction","2.developer-zone/07_blockchain_account_abstraction","i-lucide-blocks",{"title":107,"path":108,"stem":109,"icon":110},"API and dApp Integration","/developer-zone/08_wallet_adapter_system","2.developer-zone/08_wallet_adapter_system","i-lucide-waypoints",{"title":112,"path":113,"stem":114,"icon":115},"Local Development","/developer-zone/09_local_development","2.developer-zone/09_local_development","i-lucide-terminal",{"title":117,"path":118,"stem":119,"icon":120},"Backend API Reference","/developer-zone/10_backend_api_reference","2.developer-zone/10_backend_api_reference","i-lucide-braces",{"id":122,"title":112,"body":123,"description":581,"extension":582,"links":583,"meta":584,"navigation":585,"path":113,"seo":586,"stem":114,"__hash__":589},"docs/2.developer-zone/09_local_development.md",{"type":124,"value":125,"toc":575},"minimark",[126,130,141,146,157,208,211,244,255,258,303,307,320,335,420,426,429,449,463,466,507,514,518,521,550,560,564,571],[127,128,129],"p",{},"Keep the three repositories beside each other:",[131,132,138],"pre",{"className":133,"code":135,"language":136,"meta":137},[134],"language-text","projects/\n├── salmon-wallet-frontend/\n├── salmon-wallet-backend/\n└── salmon-docs/\n","text","",[139,140,135],"code",{"__ignoreMap":137},[142,143,145],"h2",{"id":144},"frontend","Frontend",[127,147,148,149,152,153,156],{},"Requirements: Node.js ",[139,150,151],{},"^20.19.0"," or ",[139,154,155],{},"^22.12.0",", pnpm 9, and Corepack.",[131,158,162],{"className":159,"code":160,"language":161,"meta":137,"style":137},"language-bash shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","corepack enable\ncorepack prepare pnpm@9.0.0 --activate\npnpm install\npnpm dev\n","bash",[139,163,164,177,191,200],{"__ignoreMap":137},[165,166,169,173],"span",{"class":167,"line":168},"line",1,[165,170,172],{"class":171},"sBMFI","corepack",[165,174,176],{"class":175},"sfazB"," enable\n",[165,178,180,182,185,188],{"class":167,"line":179},2,[165,181,172],{"class":171},[165,183,184],{"class":175}," prepare",[165,186,187],{"class":175}," pnpm@9.0.0",[165,189,190],{"class":175}," --activate\n",[165,192,194,197],{"class":167,"line":193},3,[165,195,196],{"class":171},"pnpm",[165,198,199],{"class":175}," install\n",[165,201,203,205],{"class":167,"line":202},4,[165,204,196],{"class":171},[165,206,207],{"class":175}," dev\n",[127,209,210],{},"Useful targets:",[131,212,214],{"className":159,"code":213,"language":161,"meta":137,"style":137},"pnpm extension:dev\npnpm mobile:start\npnpm mobile:ios\npnpm mobile:android\n",[139,215,216,223,230,237],{"__ignoreMap":137},[165,217,218,220],{"class":167,"line":168},[165,219,196],{"class":171},[165,221,222],{"class":175}," extension:dev\n",[165,224,225,227],{"class":167,"line":179},[165,226,196],{"class":171},[165,228,229],{"class":175}," mobile:start\n",[165,231,232,234],{"class":167,"line":193},[165,233,196],{"class":171},[165,235,236],{"class":175}," mobile:ios\n",[165,238,239,241],{"class":167,"line":202},[165,240,196],{"class":171},[165,242,243],{"class":175}," mobile:android\n",[127,245,246,247,250,251,254],{},"Copy the relevant ",[139,248,249],{},".env.example"," for local development. Local application defaults target the sibling backend at ",[139,252,253],{},"http://127.0.0.1:3000/local",".",[127,256,257],{},"Before a pull request:",[131,259,261],{"className":159,"code":260,"language":161,"meta":137,"style":137},"pnpm format:check\npnpm turbo run typecheck lint test\npnpm check:i18n\npnpm check:parity\n",[139,262,263,270,289,296],{"__ignoreMap":137},[165,264,265,267],{"class":167,"line":168},[165,266,196],{"class":171},[165,268,269],{"class":175}," format:check\n",[165,271,272,274,277,280,283,286],{"class":167,"line":179},[165,273,196],{"class":171},[165,275,276],{"class":175}," turbo",[165,278,279],{"class":175}," run",[165,281,282],{"class":175}," typecheck",[165,284,285],{"class":175}," lint",[165,287,288],{"class":175}," test\n",[165,290,291,293],{"class":167,"line":193},[165,292,196],{"class":171},[165,294,295],{"class":175}," check:i18n\n",[165,297,298,300],{"class":167,"line":202},[165,299,196],{"class":171},[165,301,302],{"class":175}," check:parity\n",[142,304,306],{"id":305},"backend","Backend",[127,308,309,310,312,313,316,317,319],{},"Copy ",[139,311,249],{}," to ",[139,314,315],{},".env"," and configure the provider credentials needed by the routes you are testing. Local Solana functionality requires a valid RPC endpoint; it does not require Helius specifically. Keep RPC URLs, API keys, and tokens only in the ignored ",[139,318,315],{}," file and never commit them.",[127,321,322,323,326,327,330,331,334],{},"For Solana, ",[139,324,325],{},"TRITON_RPC_URL"," is the primary mainnet RPC setting. Despite its name, the backend accepts a complete compatible RPC URL here; ",[139,328,329],{},"TRITON_API_TOKEN"," is only needed when a Triton URL does not already contain its token. ",[139,332,333],{},"HELIUS_API_KEY"," enables the Helius fallback and enhanced API, but it is not required when the configured primary provider covers the functionality being tested.",[336,337,338,354],"table",{},[339,340,341],"thead",{},[342,343,344,348,351],"tr",{},[345,346,347],"th",{},"Variable",[345,349,350],{},"Required when",[345,352,353],{},"Purpose",[355,356,357,370,383,395,407],"tbody",{},[342,358,359,364,367],{},[360,361,362],"td",{},[139,363,325],{},[360,365,366],{},"Testing Solana mainnet through the primary path",[360,368,369],{},"Mainnet RPC and DAS endpoint",[342,371,372,377,380],{},[360,373,374],{},[139,375,376],{},"TRITON_RPC_URL_DEVNET",[360,378,379],{},"Using a private devnet provider",[360,381,382],{},"Optional devnet RPC; otherwise the public Solana devnet RPC is used for basic calls",[342,384,385,389,392],{},[360,386,387],{},[139,388,329],{},[360,390,391],{},"The configured Triton URL does not already embed its token",[360,393,394],{},"Appended to bare Triton URLs",[342,396,397,401,404],{},[360,398,399],{},[139,400,333],{},[360,402,403],{},"Testing Helius fallback or Helius-only enhanced functionality",[360,405,406],{},"Fallback RPC, DAS, and enhanced transactions",[342,408,409,414,417],{},[360,410,411],{},[139,412,413],{},"REDIS_*",[360,415,416],{},"Running routes that use cache or rate limiting",[360,418,419],{},"Local Redis connection",[127,421,422,423,425],{},"Start Redis with Docker Compose, then run the Serverless offline target as described in the backend README. By default, the API is available at ",[139,424,253],{},"; the frontend is already configured to use that URL during local development.",[127,427,428],{},"Verify the process and its dependencies separately:",[131,430,432],{"className":159,"code":431,"language":161,"meta":137,"style":137},"curl http://127.0.0.1:3000/local/status\ncurl http://127.0.0.1:3000/local/health\n",[139,433,434,442],{"__ignoreMap":137},[165,435,436,439],{"class":167,"line":168},[165,437,438],{"class":171},"curl",[165,440,441],{"class":175}," http://127.0.0.1:3000/local/status\n",[165,443,444,446],{"class":167,"line":179},[165,445,438],{"class":171},[165,447,448],{"class":175}," http://127.0.0.1:3000/local/health\n",[127,450,451,454,455,458,459,462],{},[139,452,453],{},"/status"," identifies the running build. ",[139,456,457],{},"/health"," also checks dependencies, including Redis, and can return ",[139,460,461],{},"500"," while the HTTP process itself is running.",[127,464,465],{},"Core checks:",[131,467,469],{"className":159,"code":468,"language":161,"meta":137,"style":137},"npm run lint:check\nnpm run format:check\nnpm run test:unit\nnpm run test:integration\n",[139,470,471,481,489,498],{"__ignoreMap":137},[165,472,473,476,478],{"class":167,"line":168},[165,474,475],{"class":171},"npm",[165,477,279],{"class":175},[165,479,480],{"class":175}," lint:check\n",[165,482,483,485,487],{"class":167,"line":179},[165,484,475],{"class":171},[165,486,279],{"class":175},[165,488,269],{"class":175},[165,490,491,493,495],{"class":167,"line":193},[165,492,475],{"class":171},[165,494,279],{"class":175},[165,496,497],{"class":175}," test:unit\n",[165,499,500,502,504],{"class":167,"line":202},[165,501,475],{"class":171},[165,503,279],{"class":175},[165,505,506],{"class":175}," test:integration\n",[127,508,509,510,513],{},"Integration tests can depend on local Redis or external providers. The backend repository's ",[139,511,512],{},"docs/TESTING.md"," documents hermetic and Docker-based options.",[142,515,517],{"id":516},"documentation","Documentation",[127,519,520],{},"Use Node 20 or Node 22–25.",[131,522,524],{"className":159,"code":523,"language":161,"meta":137,"style":137},"npm ci\nnpm run dev\nnpm run build\n",[139,525,526,533,541],{"__ignoreMap":137},[165,527,528,530],{"class":167,"line":168},[165,529,475],{"class":171},[165,531,532],{"class":175}," ci\n",[165,534,535,537,539],{"class":167,"line":179},[165,536,475],{"class":171},[165,538,279],{"class":175},[165,540,207],{"class":175},[165,542,543,545,547],{"class":167,"line":193},[165,544,475],{"class":171},[165,546,279],{"class":175},[165,548,549],{"class":175}," build\n",[127,551,552,553,556,557,254],{},"The preview runs at ",[139,554,555],{},"http://localhost:3000",". The production build is emitted to ",[139,558,559],{},".output",[142,561,563],{"id":562},"scope-checks","Scope checks",[127,565,566,567,570],{},"Read the closest ",[139,568,569],{},"AGENTS.md"," before changing source. Frontend package and application folders have scoped rules; backend layers and chain slices do as well. Run the smallest relevant checks first, then the repository-wide gates before submission.",[572,573,574],"style",{},"html pre.shiki code .sBMFI, html code.shiki .sBMFI{--shiki-light:#E2931D;--shiki-default:#FFCB6B;--shiki-dark:#FFCB6B}html pre.shiki code .sfazB, html code.shiki .sfazB{--shiki-light:#91B859;--shiki-default:#C3E88D;--shiki-dark:#C3E88D}html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}",{"title":137,"searchDepth":179,"depth":179,"links":576},[577,578,579,580],{"id":144,"depth":179,"text":145},{"id":305,"depth":179,"text":306},{"id":516,"depth":179,"text":517},{"id":562,"depth":179,"text":563},"Set up, run, test, and build the Salmon frontend, backend, and documentation.","md",null,{},{"icon":115},{"title":587,"description":588},"Salmon local development","Commands and verification checks for Salmon contributors.","LRAWLKFZO3m5TeTcjAcb0QVI0oe_dvsZa-ZP-rnY5V8",[591,593],{"title":107,"path":108,"stem":109,"description":592,"icon":110,"children":-1},"Public API endpoints and the extension's Solana Wallet Standard surface.",{"title":117,"path":118,"stem":119,"description":594,"icon":120,"children":-1},"Integrate with the Salmon HTTP API using its current endpoints, parameters, and error contracts.",1788556238842]