[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"navigation":3,"\u002Fprotocol\u002Fsolana":260,"\u002Fprotocol\u002Fsolana-surround":2598},[4,22,105,148,177,186,243],{"title":5,"path":6,"stem":7,"children":8,"page":21},"Agents","\u002Fagents","agents",[9,13,17],{"title":10,"path":11,"stem":12},"LLMs.txt","\u002Fagents\u002Fllms-txt","agents\u002Fllms-txt",{"title":14,"path":15,"stem":16},"MCP Server","\u002Fagents\u002Fmcp-server","agents\u002Fmcp-server",{"title":18,"path":19,"stem":20},"Skills","\u002Fagents\u002Fskills","agents\u002Fskills",false,{"title":23,"path":24,"stem":25,"children":26,"page":21},"Api Reference","\u002Fapi-reference","api-reference",[27,31,35,68],{"title":28,"path":29,"stem":30},"Authentication","\u002Fapi-reference\u002Fauthentication","api-reference\u002Fauthentication",{"title":32,"path":33,"stem":34},"API Reference","\u002Fapi-reference\u002Fintroduction","api-reference\u002Fintroduction",{"title":36,"path":37,"stem":38,"children":39,"page":21},"Orchestration","\u002Fapi-reference\u002Forchestration","api-reference\u002Forchestration",[40,44,48,52,56,60,64],{"title":41,"path":42,"stem":43},"POST \u002Fcancel-order","\u002Fapi-reference\u002Forchestration\u002Fcancel-order","api-reference\u002Forchestration\u002Fcancel-order",{"title":45,"path":46,"stem":47},"GET \u002Forder-status\u002F{orderId}","\u002Fapi-reference\u002Forchestration\u002Forder-status","api-reference\u002Forchestration\u002Forder-status",{"title":49,"path":50,"stem":51},"GET \u002Forders","\u002Fapi-reference\u002Forchestration\u002Forders","api-reference\u002Forchestration\u002Forders",{"title":53,"path":54,"stem":55},"Orchestration API","\u002Fapi-reference\u002Forchestration\u002Foverview","api-reference\u002Forchestration\u002Foverview",{"title":57,"path":58,"stem":59},"POST \u002Fquote","\u002Fapi-reference\u002Forchestration\u002Fquote","api-reference\u002Forchestration\u002Fquote",{"title":61,"path":62,"stem":63},"GET \u002Fsupported-assets","\u002Fapi-reference\u002Forchestration\u002Fsupported-assets","api-reference\u002Forchestration\u002Fsupported-assets",{"title":65,"path":66,"stem":67},"TypeScript Type Generation","\u002Fapi-reference\u002Forchestration\u002Ftype-generation","api-reference\u002Forchestration\u002Ftype-generation",{"title":69,"path":70,"stem":71,"children":72,"page":21},"Recipes","\u002Fapi-reference\u002Frecipes","api-reference\u002Frecipes",[73,77,81,85,89,93,97,101],{"title":74,"path":75,"stem":76},"Collateral Composition","\u002Fapi-reference\u002Frecipes\u002Fcollateral-composition","api-reference\u002Frecipes\u002Fcollateral-composition",{"title":78,"path":79,"stem":80},"Daily Yields","\u002Fapi-reference\u002Frecipes\u002Fdaily-yields","api-reference\u002Frecipes\u002Fdaily-yields",{"title":82,"path":83,"stem":84},"Earner Rate History","\u002Fapi-reference\u002Frecipes\u002Fearner-rate-history","api-reference\u002Frecipes\u002Fearner-rate-history",{"title":86,"path":87,"stem":88},"Minter Daily Expenses","\u002Fapi-reference\u002Frecipes\u002Fminter-daily-expenses","api-reference\u002Frecipes\u002Fminter-daily-expenses",{"title":90,"path":91,"stem":92},"Network Supply","\u002Fapi-reference\u002Frecipes\u002Fnetwork-supply","api-reference\u002Frecipes\u002Fnetwork-supply",{"title":94,"path":95,"stem":96},"Protocol Configuration","\u002Fapi-reference\u002Frecipes\u002Fprotocol-config","api-reference\u002Frecipes\u002Fprotocol-config",{"title":98,"path":99,"stem":100},"Token Holders","\u002Fapi-reference\u002Frecipes\u002Ftoken-holders","api-reference\u002Frecipes\u002Ftoken-holders",{"title":102,"path":103,"stem":104},"Token Overview","\u002Fapi-reference\u002Frecipes\u002Ftoken-overview","api-reference\u002Frecipes\u002Ftoken-overview",{"title":106,"path":107,"stem":108,"children":109,"page":21},"Build","\u002Fbuild","build",[110,114,118,122,126,130,134,138,142,145],{"title":111,"path":112,"stem":113},"Integrating with the M0 Portals","\u002Fbuild\u002Fbridging-developer","build\u002Fbridging-developer",{"title":115,"path":116,"stem":117},"Bridging M And wM Tokens","\u002Fbuild\u002Fbridging-user","build\u002Fbridging-user",{"title":119,"path":120,"stem":121},"Stablecoin Extension Templates","\u002Fbuild\u002Fchoosing-your-model","build\u002Fchoosing-your-model",{"title":123,"path":124,"stem":125},"How to Design Your Stablecoin","\u002Fbuild\u002Foverview","build\u002Foverview",{"title":127,"path":128,"stem":129},"Implementation Guide: NoYield","\u002Fbuild\u002Fsvm-noyield-guide","build\u002Fsvm-noyield-guide",{"title":131,"path":132,"stem":133},"Getting started","\u002Fbuild\u002Fsvm-noyield-guide-overview","build\u002Fsvm-noyield-guide-overview",{"title":135,"path":136,"stem":137},"Implementation Guide: MYieldToOne (Onshore)","\u002Fbuild\u002Ftreasury-guide","build\u002Ftreasury-guide",{"title":139,"path":140,"stem":141},"Implementation Guide: JMI (Offshore)","\u002Fbuild\u002Ftreasury-jmi-guide","build\u002Ftreasury-jmi-guide",{"title":131,"path":143,"stem":144},"\u002Fbuild\u002Ftreasury-jmi-overview","build\u002Ftreasury-jmi-overview",{"title":131,"path":146,"stem":147},"\u002Fbuild\u002Ftreasury-model","build\u002Ftreasury-model",{"title":149,"path":150,"stem":151,"children":152,"page":21},"Get Started","\u002Fget-started","get-started",[153,157,161,165,169,173],{"title":154,"path":155,"stem":156},"Accessing Liquidity","\u002Fget-started\u002Faccessing-liquidity","get-started\u002Faccessing-liquidity",{"title":158,"path":159,"stem":160},"Cross Chain Interoperability","\u002Fget-started\u002Fcross-chain","get-started\u002Fcross-chain",{"title":162,"path":163,"stem":164},"Architecture Overview","\u002Fget-started\u002Fhow-it-works","get-started\u002Fhow-it-works",{"title":166,"path":167,"stem":168},"Overview","\u002Fget-started\u002Foverview","get-started\u002Foverview",{"title":170,"path":171,"stem":172},"Platform Mechanics & Reward Programmability","\u002Fget-started\u002Fprotocol-mechanics","get-started\u002Fprotocol-mechanics",{"title":174,"path":175,"stem":176},"Stablecoin Features","\u002Fget-started\u002Fstablecoin-features","get-started\u002Fstablecoin-features",{"title":178,"path":179,"stem":180,"children":181,"page":21},"Issuers","\u002Fissuers","issuers",[182],{"title":183,"path":184,"stem":185},"Issue Your Stablecoin","\u002Fissuers\u002Foverview","issuers\u002Foverview",{"title":187,"path":188,"stem":189,"children":190,"page":21},"Protocol","\u002Fprotocol","protocol",[191,195,199,203,207,211,215,219,223,227,231,235,239],{"title":192,"path":193,"stem":194},"Distribution Vault","\u002Fprotocol\u002Fdistribution-vault","protocol\u002Fdistribution-vault",{"title":196,"path":197,"stem":198},"M0 Extensions","\u002Fprotocol\u002Fextensions","protocol\u002Fextensions",{"title":200,"path":201,"stem":202},"Limit Order Protocol","\u002Fprotocol\u002Flimit-order-protocol","protocol\u002Flimit-order-protocol",{"title":204,"path":205,"stem":206},"M0 Portals","\u002Fprotocol\u002Fm-portals","protocol\u002Fm-portals",{"title":208,"path":209,"stem":210},"M Token","\u002Fprotocol\u002Fm-token","protocol\u002Fm-token",{"title":212,"path":213,"stem":214},"M Token Specification","\u002Fprotocol\u002Fm-token-spec","protocol\u002Fm-token-spec",{"title":216,"path":217,"stem":218},"Minting & Burning (MinterGateway)","\u002Fprotocol\u002Fminting-burning","protocol\u002Fminting-burning",{"title":220,"path":221,"stem":222},"Portal V2","\u002Fprotocol\u002Fportal-v2","protocol\u002Fportal-v2",{"title":224,"path":225,"stem":226},"Rate Models & Yield","\u002Fprotocol\u002Frate-models","protocol\u002Frate-models",{"title":228,"path":229,"stem":230},"Roles","\u002Fprotocol\u002Froles","protocol\u002Froles",{"title":232,"path":233,"stem":234},"M0 On Solana","\u002Fprotocol\u002Fsolana","protocol\u002Fsolana",{"title":236,"path":237,"stem":238},"Wrapped M (wM)","\u002Fprotocol\u002Fwrapped-m","protocol\u002Fwrapped-m",{"title":240,"path":241,"stem":242},"Wrapped M Specification","\u002Fprotocol\u002Fwrapped-m-spec","protocol\u002Fwrapped-m-spec",{"title":244,"path":245,"stem":246,"children":247,"page":21},"Resources","\u002Fresources","resources",[248,252,256],{"title":249,"path":250,"stem":251},"Deployments","\u002Fresources\u002Faddresses","resources\u002Faddresses",{"title":253,"path":254,"stem":255},"Audits","\u002Fresources\u002Faudits","resources\u002Faudits",{"title":257,"path":258,"stem":259},"Glossary","\u002Fresources\u002Fglossary","resources\u002Fglossary",{"id":261,"title":232,"body":262,"description":2592,"extension":2593,"links":2594,"meta":2595,"navigation":867,"path":233,"seo":2596,"stem":234,"__hash__":2597},"docs\u002Fprotocol\u002Fsolana.md",{"type":263,"value":264,"toc":2558},"minimark",[265,274,277,282,294,297,304,309,312,428,432,497,501,504,508,528,534,539,580,586,602,610,614,639,643,648,653,657,670,674,683,688,694,698,707,712,716,727,731,739,744,749,774,778,783,788,794,798,806,812,817,853,894,935,939,942,976,982,989,995,999,1005,1026,1033,1138,1145,1215,1225,1231,1235,1241,1267,1272,1302,1306,1311,1448,1453,1538,1542,1588,1592,1597,1605,1610,1623,1628,1668,1675,1680,1684,1738,1742,1799,1804,1819,1823,1827,1830,1865,1870,2182,2187,2372,2376,2379,2425,2429,2439,2443,2448,2453,2464,2469,2480,2490,2494,2528,2532,2554],[266,267,268,269,273],"p",{},"This document provides a detailed technical overview of the M0 Protocol's implementation on the Solana blockchain. It is intended for developers who want to integrate with or build on top of ",[270,271,272],"code",{},"$M"," and its extensions on Solana.",[266,275,276],{},"It assumes you are familiar with Solana's programming model (programs, accounts, CPIs) and have a conceptual understanding of M0's hub-and-spoke architecture.",[278,279,281],"h2",{"id":280},"architecture-core-components","Architecture & Core Components",[266,283,284,285,289,290,293],{},"M0's Solana deployment functions as a \"spoke\" in the cross-chain model, with Ethereum as the \"hub\". Communication and token transfers are managed by the ",[286,287,288],"strong",{},"M Portal",", which is a customized implementation of Wormhole's ",[286,291,292],{},"Native Token Transfer (NTT)"," framework.",[266,295,296],{},"The system is composed of three core onchain programs and several offchain services that work in concert.",[266,298,299],{},[300,301],"img",{"alt":302,"src":303},"M0 Solana Program Architecture","\u002Fimages\u002Ftechnical-documentations\u002Fsolana\u002Fsolana_m_programs.png",[305,306,308],"h3",{"id":307},"onchain-programs","Onchain Programs",[266,310,311],{},"The onchain logic is modular, distributed across three main Solana programs written in Rust using the Anchor framework.",[313,314,315,334],"table",{},[316,317,318],"thead",{},[319,320,321,325,328,331],"tr",{},[322,323,324],"th",{},"Program",[322,326,327],{},"Mainnet Program ID",[322,329,330],{},"Devnet Program ID",[322,332,333],{},"Description",[335,336,337,360,382,405],"tbody",{},[319,338,339,345,350,354],{},[340,341,342],"td",{},[286,343,344],{},"Portal",[340,346,347],{},[270,348,349],{},"mzp1q2j5Hr1QuLC3KFBCAUz5aUckT6qyuZKZ3WJnMmY",[340,351,352],{},[270,353,349],{},[340,355,356,357,359],{},"The gateway for bridging ",[270,358,272],{}," between EVM chains and Solana. A fork of Wormhole's NTT program with M0-specific payload support and executor integration.",[319,361,362,367,372,376],{},[340,363,364],{},[286,365,366],{},"Earn",[340,368,369],{},[270,370,371],{},"MzeRokYa9o1ZikH6XHRiSS5nD8mNjZyHpLCBRTBSY4c",[340,373,374],{},[270,375,371],{},[340,377,378,379,381],{},"Manages yield distribution and earner permissions for the base ",[270,380,272],{}," token with frozen-by-default security model.",[319,383,384,389,394,398],{},[340,385,386],{},[286,387,388],{},"M Extensions",[340,390,391],{},[270,392,393],{},"3C865D264L4NkAm78zfnDzQJJvXuU3fMjRUvRxyPi5da",[340,395,396],{},[270,397,393],{},[340,399,400,401,404],{},"Unified extension framework (",[270,402,403],{},"m_ext",") compiled with feature flags for NoYield, ScaledUi, and Crank models.",[319,406,407,412,417,421],{},[340,408,409],{},[286,410,411],{},"Swap Facility",[340,413,414],{},[270,415,416],{},"MSwapi3WhNKMUGm9YrxGhypgUEt7wYQH3ZgG32XoWzH",[340,418,419],{},[270,420,416],{},[340,422,423,424,427],{},"Permissioned router for atomic swaps between whitelisted M0 extensions (",[270,425,426],{},"ext_swap"," program).",[305,429,431],{"id":430},"key-onchain-assets","Key Onchain Assets",[313,433,434,449],{},[316,435,436],{},[319,437,438,441,444,447],{},[322,439,440],{},"Asset",[322,442,443],{},"Mainnet Mint Address",[322,445,446],{},"Devnet Mint Address",[322,448,333],{},[335,450,451,473],{},[319,452,453,460,465,470],{},[340,454,455],{},[286,456,457,459],{},[270,458,272],{}," Token",[340,461,462],{},[270,463,464],{},"mzerokyEX9TNDoK4o2YZQBDmMzjokAeN6M2g2S3pLJo",[340,466,467],{},[270,468,469],{},"mzeroZRGCah3j5xEWp2Nih3GDejSBbH1rbHoxDg8By6",[340,471,472],{},"The base yield-bearing stablecoin, implemented as a Token-2022 asset with frozen-by-default security.",[319,474,475,482,487,491],{},[340,476,477],{},[286,478,479,459],{},[270,480,481],{},"$wM",[340,483,484],{},[270,485,486],{},"mzeroXDoBpRVhnEXBra27qzAMdxgpWVY3DzQW7xMVJp",[340,488,489],{},[270,490,486],{},[340,492,493,494,496],{},"The wrapped, 1:1 ",[270,495,272],{},"-backed extension using the Crank model, also a Token-2022 asset.",[278,498,500],{"id":499},"v2-upgrades-what-changed","V2 Upgrades: What Changed",[266,502,503],{},"The V2 upgrade introduced seven major enhancements to the Solana implementation:",[305,505,507],{"id":506},"_1-direct-bridging-to-extensions","1. Direct Bridging to Extensions",[266,509,510,513,514,517,518,521,522,524,525,527],{},[286,511,512],{},"What Changed:"," The Portal now supports a ",[270,515,516],{},"destination_token"," field in the ",[270,519,520],{},"AdditionalPayload",", allowing users to bridge directly to extension tokens (like ",[270,523,481],{},") instead of only receiving base ",[270,526,272],{},".",[266,529,530,533],{},[286,531,532],{},"Why It Matters:"," Eliminates the need for a separate wrap transaction after bridging, improving UX and reducing costs.",[266,535,536],{},[286,537,538],{},"Technical Implementation:",[540,541,546],"pre",{"className":542,"code":543,"language":544,"meta":545,"style":545},"language-rust shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","pub struct AdditionalPayload {\n    pub index: u64,\n    pub destination_token: [u8; 32],  \u002F\u002F NEW: Target mint address (M or extension)\n    pub earner_root: Option\u003C[u8; 32]>,\n}\n","rust","",[270,547,548,556,562,568,574],{"__ignoreMap":545},[549,550,553],"span",{"class":551,"line":552},"line",1,[549,554,555],{},"pub struct AdditionalPayload {\n",[549,557,559],{"class":551,"line":558},2,[549,560,561],{},"    pub index: u64,\n",[549,563,565],{"class":551,"line":564},3,[549,566,567],{},"    pub destination_token: [u8; 32],  \u002F\u002F NEW: Target mint address (M or extension)\n",[549,569,571],{"class":551,"line":570},4,[549,572,573],{},"    pub earner_root: Option\u003C[u8; 32]>,\n",[549,575,577],{"class":551,"line":576},5,[549,578,579],{},"}\n",[305,581,583,584],{"id":582},"_2-frozen-by-default-m","2. Frozen-by-Default ",[270,585,272],{},[266,587,588,590,591,593,594,597,598,601],{},[286,589,512],{}," All new ",[270,592,272],{}," token accounts are initialized with ",[270,595,596],{},"AccountState::Frozen"," using Token-2022's ",[270,599,600],{},"DefaultAccountState"," extension.",[266,603,604,606,607,609],{},[286,605,532],{}," Enhances security by preventing unauthorized accounts from holding ",[270,608,272],{},". Only approved earners (verified via Merkle proof) can have their accounts thawed.",[266,611,612],{},[286,613,538],{},[540,615,617],{"className":542,"code":616,"language":544,"meta":545,"style":545},"\u002F\u002F $M mint is created with DefaultAccountState::Frozen\nlet default_state = DefaultAccountState {\n    state: AccountState::Frozen,\n};\n",[270,618,619,624,629,634],{"__ignoreMap":545},[549,620,621],{"class":551,"line":552},[549,622,623],{},"\u002F\u002F $M mint is created with DefaultAccountState::Frozen\n",[549,625,626],{"class":551,"line":558},[549,627,628],{},"let default_state = DefaultAccountState {\n",[549,630,631],{"class":551,"line":564},[549,632,633],{},"    state: AccountState::Frozen,\n",[549,635,636],{"class":551,"line":570},[549,637,638],{},"};\n",[305,640,642],{"id":641},"_3-onchain-yield-distribution","3. Onchain Yield Distribution",[266,644,645,647],{},[286,646,512],{}," Yield distribution is now fully onchain via the scaled-ui mechanism, replacing V1's centralized distribution.",[266,649,650,652],{},[286,651,532],{}," Increases transparency and decentralization. All yield calculations and distributions are verifiable onchain.",[266,654,655],{},[286,656,538],{},[658,659,660,664,667],"ul",{},[661,662,663],"li",{},"Yield distributed via scaled-ui mechanism",[661,665,666],{},"Index updates propagated onchain",[661,668,669],{},"Extensions automatically sync on wrap\u002Funwrap operations",[305,671,673],{"id":672},"_4-permissionless-index-updates","4. Permissionless Index Updates",[266,675,676,678,679,682],{},[286,677,512],{}," The ",[270,680,681],{},"sync()"," instruction for extension index updates is now permissionless -- anyone can call it. Additionally, anyone can bridge an index update, and extensions automatically sync on wrap\u002Funwrap operations.",[266,684,685,687],{},[286,686,532],{}," Enables keeper bots and users to ensure yield indices are always up-to-date without relying on centralized services.",[266,689,690,693],{},[286,691,692],{},"Who Can Call:"," Anyone (no signer required for sync, though accounts must be valid). Index updates can also be bridged permissionlessly.",[305,695,697],{"id":696},"_5-executor-support-for-generic-bridge-messages","5. Executor Support for Generic Bridge Messages",[266,699,700,702,703,706],{},[286,701,512],{}," Integration with Wormhole's executor pattern (",[270,704,705],{},"executor-account-resolver-svm",") enables arbitrary cross-chain instructions to be executed atomically with bridge transfers.",[266,708,709,711],{},[286,710,532],{}," Unlocks advanced cross-chain composability, such as \"bridge and stake\" or \"bridge and swap\" in a single transaction.",[266,713,714],{},[286,715,538],{},[658,717,718,721,724],{},[661,719,720],{},"Portal validates executor messages",[661,722,723],{},"Executor Account Resolver resolves required accounts",[661,725,726],{},"Arbitrary CPI instructions executed after mint",[305,728,730],{"id":729},"_6-unified-extension-framework","6. Unified Extension Framework",[266,732,733,735,736,738],{},[286,734,512],{}," All extensions (NoYield, ScaledUi, Crank) are now compiled from a single ",[270,737,403],{}," program using Rust feature flags.",[266,740,741,743],{},[286,742,532],{}," Reduces code duplication, simplifies auditing, and ensures consistent behavior across all extension types.",[266,745,746],{},[286,747,748],{},"Feature Flags:",[540,750,752],{"className":542,"code":751,"language":544,"meta":545,"style":545},"[features]\nno-yield = []\nscaled-ui = []\ncrank = []\n",[270,753,754,759,764,769],{"__ignoreMap":545},[549,755,756],{"class":551,"line":552},[549,757,758],{},"[features]\n",[549,760,761],{"class":551,"line":558},[549,762,763],{},"no-yield = []\n",[549,765,766],{"class":551,"line":564},[549,767,768],{},"scaled-ui = []\n",[549,770,771],{"class":551,"line":570},[549,772,773],{},"crank = []\n",[305,775,777],{"id":776},"_7-multi-network-support-fogo-compatibility","7. Multi-Network Support (Fogo Compatibility)",[266,779,780,782],{},[286,781,512],{}," V2 architecture is designed to support both Solana and Fogo (Wormhole's native rollup) with minimal changes.",[266,784,785,787],{},[286,786,532],{}," Future-proofs the protocol for multi-network deployment and leverages Wormhole's native cross-chain capabilities.",[266,789,790,793],{},[286,791,792],{},"Implementation:"," Feature flags enable Fogo-specific configurations without forking the codebase.",[278,795,797],{"id":796},"program-specifications","Program Specifications",[305,799,801,802,805],{"id":800},"_1-portal-program-programsportal","1. Portal Program (",[270,803,804],{},"programs\u002Fportal",")",[266,807,808,809,811],{},"The Portal is the entry and exit point for ",[270,810,272],{}," into the Solana ecosystem.",[813,814,816],"h4",{"id":815},"core-logic-custom-payload","Core Logic & Custom Payload",[658,818,819,836],{},[661,820,821,824,825,828,829,831,832,835],{},[286,822,823],{},"Core Logic:"," Based on Wormhole NTT, it validates Wormhole Verifiable Action Approvals (VAAs) and processes inbound\u002Foutbound transfers. The key inbound instruction is ",[270,826,827],{},"release_inbound_mint_multisig",", which mints tokens and makes a CPI to the ",[270,830,366],{}," program's ",[270,833,834],{},"propagate_index"," function.",[661,837,838,845,846,849,850,852],{},[286,839,840,841,844],{},"Custom Payload (",[270,842,843],{},"payloads\u002Ftoken_transfer.rs","):"," The standard ",[270,847,848],{},"NativeTokenTransfer"," struct is extended with an ",[270,851,520],{},". This is the most critical customization, allowing M0-specific data to be securely transmitted with every bridge transfer.",[540,854,856],{"className":542,"code":855,"language":544,"meta":545,"style":545},"\u002F\u002F programs\u002Fportal\u002Fsrc\u002Fpayloads\u002Ftoken_transfer.rs\n\npub struct AdditionalPayload {\n    pub index: u64,                      \u002F\u002F Latest $M Earning Index from Ethereum\n    pub destination_token: [u8; 32],     \u002F\u002F Target token mint (M or extension)\n    pub earner_root: Option\u003C[u8; 32]>,   \u002F\u002F Merkle root of approved earners\n}\n",[270,857,858,863,869,873,878,883,889],{"__ignoreMap":545},[549,859,860],{"class":551,"line":552},[549,861,862],{},"\u002F\u002F programs\u002Fportal\u002Fsrc\u002Fpayloads\u002Ftoken_transfer.rs\n",[549,864,865],{"class":551,"line":558},[549,866,868],{"emptyLinePlaceholder":867},true,"\n",[549,870,871],{"class":551,"line":564},[549,872,555],{},[549,874,875],{"class":551,"line":570},[549,876,877],{},"    pub index: u64,                      \u002F\u002F Latest $M Earning Index from Ethereum\n",[549,879,880],{"class":551,"line":576},[549,881,882],{},"    pub destination_token: [u8; 32],     \u002F\u002F Target token mint (M or extension)\n",[549,884,886],{"class":551,"line":885},6,[549,887,888],{},"    pub earner_root: Option\u003C[u8; 32]>,   \u002F\u002F Merkle root of approved earners\n",[549,890,892],{"class":551,"line":891},7,[549,893,579],{},[658,895,896,908,924],{},[661,897,898,904,905,907],{},[286,899,900,903],{},[270,901,902],{},"index",":"," The latest ",[270,906,272],{}," Earning Index from Ethereum.",[661,909,910,914,915,917,918,920,921],{},[286,911,912,903],{},[270,913,516],{}," The target token mint address on Solana (e.g., ",[270,916,272],{}," or ",[270,919,481],{},"). ",[286,922,923],{},"NEW in V2.",[661,925,926,931,932,934],{},[286,927,928,903],{},[270,929,930],{},"earner_root"," An optional Merkle root of the official ",[270,933,272],{}," earner list, as determined by M0 Governance on Ethereum.",[813,936,938],{"id":937},"executor-integration","Executor Integration",[266,940,941],{},"V2 Portal integrates with Wormhole's executor pattern to enable generic cross-chain instructions:",[540,943,945],{"className":542,"code":944,"language":544,"meta":545,"style":545},"\u002F\u002F Executor message structure\npub struct ExecutorMessage {\n    pub instruction_data: Vec\u003Cu8>,\n    pub program_id: Pubkey,\n    pub account_metas: Vec\u003CAccountMeta>,\n}\n",[270,946,947,952,957,962,967,972],{"__ignoreMap":545},[549,948,949],{"class":551,"line":552},[549,950,951],{},"\u002F\u002F Executor message structure\n",[549,953,954],{"class":551,"line":558},[549,955,956],{},"pub struct ExecutorMessage {\n",[549,958,959],{"class":551,"line":564},[549,960,961],{},"    pub instruction_data: Vec\u003Cu8>,\n",[549,963,964],{"class":551,"line":570},[549,965,966],{},"    pub program_id: Pubkey,\n",[549,968,969],{"class":551,"line":576},[549,970,971],{},"    pub account_metas: Vec\u003CAccountMeta>,\n",[549,973,974],{"class":551,"line":885},[549,975,579],{},[266,977,978,979,981],{},"The executor account resolver (",[270,980,705],{},") resolves required accounts and executes instructions atomically with bridge transfers.",[305,983,985,986,805],{"id":984},"_2-earn-program-programsearn","2. Earn Program (",[270,987,988],{},"programs\u002Fearn",[266,990,991,992,994],{},"This program manages yield and permissions for the base ",[270,993,272],{}," token on Solana.",[813,996,998],{"id":997},"v2-security-model-frozen-by-default","V2 Security Model: Frozen by Default",[266,1000,1001,1002,1004],{},"All token accounts are initialized with ",[270,1003,596],{},". Accounts are only thawed after:",[1006,1007,1008,1014,1020],"ol",{},[661,1009,1010,1011],{},"User submits Merkle proof via ",[270,1012,1013],{},"add_registrar_earner",[661,1015,1016,1017],{},"Proof is verified against ",[270,1018,1019],{},"earner_merkle_root",[661,1021,1022,1023],{},"Account state is updated to ",[270,1024,1025],{},"AccountState::Initialized",[813,1027,1029,1030,805],{"id":1028},"state-state","State (",[270,1031,1032],{},"state\u002F",[658,1034,1035,1104],{},[661,1036,1037,1046,1047,1050,1051],{},[286,1038,1039,1042,1043,844],{},[270,1040,1041],{},"Global"," Account (",[270,1044,1045],{},"state\u002Fglobal.rs"," A PDA seeded with ",[270,1048,1049],{},"b\"global\""," that stores the program's configuration.\n",[658,1052,1053,1059,1069,1077,1083,1093,1099],{},[661,1054,1055,1058],{},[270,1056,1057],{},"admin",": The administrative authority.",[661,1060,1061,1064,1065,1068],{},[270,1062,1063],{},"earn_authority",": A permissioned key that can call ",[270,1066,1067],{},"claim_for"," instructions.",[661,1070,1071,1073,1074,1076],{},[270,1072,902],{},": The most recently propagated ",[270,1075,272],{}," Earning Index.",[661,1078,1079,1082],{},[270,1080,1081],{},"claim_cooldown",": The minimum time between yield claim cycles.",[661,1084,1085,1088,1089,1092],{},[270,1086,1087],{},"max_yield"," & ",[270,1090,1091],{},"distributed",": Used to track and cap the amount of yield distributed in a cycle.",[661,1094,1095,1098],{},[270,1096,1097],{},"claim_complete",": A flag indicating if the current claim cycle has finished.",[661,1100,1101,1103],{},[270,1102,1019],{},": The Merkle root of the governance-approved earner list.",[661,1105,1106,1046,1114,1117,1118],{},[286,1107,1108,1042,1111,844],{},[270,1109,1110],{},"Earner",[270,1112,1113],{},"state\u002Fearner.rs",[270,1115,1116],{},"b\"earner\""," and the user's token account address. It tracks an individual's earning status.\n",[658,1119,1120,1126,1132],{},[661,1121,1122,1125],{},[270,1123,1124],{},"last_claim_index",": The index at which the user last received yield.",[661,1127,1128,1131],{},[270,1129,1130],{},"user",": The wallet address of the earner.",[661,1133,1134,1137],{},[270,1135,1136],{},"user_token_account",": The specific token account that is earning yield.",[813,1139,1141,1142,805],{"id":1140},"key-instructions-instructions","Key Instructions (",[270,1143,1144],{},"instructions\u002F",[658,1146,1147,1163,1180,1193,1204],{},[661,1148,1149,1153,1154,1156,1157,1159,1160,1162],{},[286,1150,1151,903],{},[270,1152,834],{}," Called by the Portal via CPI. It updates the ",[270,1155,1041],{}," account's ",[270,1158,902],{}," and ",[270,1161,1019],{},", and can initiate a new claim cycle if conditions are met (cooldown passed, new yield available).",[661,1164,1165,1169,1170,1173,1174,1176,1177],{},[286,1166,1167,903],{},[270,1168,1013],{}," A ",[286,1171,1172],{},"permissionless"," instruction allowing a user to prove their eligibility to earn yield. The user provides a Merkle proof that their address is included in the ",[270,1175,1019],{},". ",[286,1178,1179],{},"On success, thaws the frozen token account.",[661,1181,1182,1186,1187,1189,1190],{},[286,1183,1184,903],{},[270,1185,1067],{}," A permissioned instruction called by the ",[270,1188,1063],{},". It calculates the yield owed to a specific earner since their last claim and mints new tokens to their account. ",[286,1191,1192],{},"NEW in V2: fully onchain distribution.",[661,1194,1195,1200,1201,1203],{},[286,1196,1197,903],{},[270,1198,1199],{},"complete_claims"," Called by the ",[270,1202,1063],{}," to mark the end of a yield distribution cycle.",[661,1205,1206,1211,1212,1214],{},[286,1207,1208,903],{},[270,1209,1210],{},"sync"," ",[286,1213,923],{}," Permissionless instruction to update the earning index. Anyone can call this to keep indices current.",[305,1216,1218,1219,1221,1222,805],{"id":1217},"_3-m-extension-framework-programsm_ext","3. ",[270,1220,272],{}," Extension Framework (",[270,1223,1224],{},"programs\u002Fm_ext",[266,1226,1227,1230],{},[286,1228,1229],{},"NEW in V2:"," Unified extension framework replacing separate programs for each model.",[813,1232,1234],{"id":1233},"architecture","Architecture",[266,1236,1237,1238,1240],{},"All extension models are compiled from a single ",[270,1239,403],{}," program using Rust feature flags:",[540,1242,1244],{"className":542,"code":1243,"language":544,"meta":545,"style":545},"\u002F\u002F Cargo.toml\n[features]\nno-yield = []\nscaled-ui = []\ncrank = []\n",[270,1245,1246,1251,1255,1259,1263],{"__ignoreMap":545},[549,1247,1248],{"class":551,"line":552},[549,1249,1250],{},"\u002F\u002F Cargo.toml\n",[549,1252,1253],{"class":551,"line":558},[549,1254,758],{},[549,1256,1257],{"class":551,"line":564},[549,1258,763],{},[549,1260,1261],{"class":551,"line":570},[549,1262,768],{},[549,1264,1265],{"class":551,"line":576},[549,1266,773],{},[266,1268,1269],{},[286,1270,1271],{},"Deployed Instances:",[658,1273,1274,1283,1291],{},[661,1275,1276,1279,1280],{},[286,1277,1278],{},"NoYield Extensions:"," Compiled with ",[270,1281,1282],{},"--features no-yield",[661,1284,1285,1279,1288],{},[286,1286,1287],{},"ScaledUi Extensions:",[270,1289,1290],{},"--features scaled-ui",[661,1292,1293,1279,1296,1299,1300,805],{},[286,1294,1295],{},"Crank Extensions:",[270,1297,1298],{},"--features crank"," (used by ",[270,1301,481],{},[813,1303,1305],{"id":1304},"state-structures","State Structures",[266,1307,1308],{},[286,1309,1310],{},"ExtGlobal Account (shared across all models):",[540,1312,1314],{"className":542,"code":1313,"language":544,"meta":545,"style":545},"pub struct ExtGlobal {\n    pub admin: Pubkey,\n    pub earn_authority: Option\u003CPubkey>,  \u002F\u002F Only for Crank model\n    pub ext_mint: Pubkey,\n    pub m_mint: Pubkey,\n    pub m_earn_global_account: Pubkey,\n    pub bump: u8,\n    pub m_vault_bump: u8,\n    pub ext_mint_authority_bump: u8,\n    pub yield_config: YieldConfig,\n    pub wrap_authorities: Vec\u003CPubkey>,\n}\n\npub struct YieldConfig {\n    pub variant: YieldVariant,  \u002F\u002F NoYield | ScaledUi | Crank\n    pub last_m_index: u64,\n    pub last_ext_index: u64,\n}\n\npub enum YieldVariant {\n    NoYield,\n    ScaledUi,\n    Crank,\n}\n",[270,1315,1316,1321,1326,1331,1336,1341,1346,1351,1357,1363,1369,1375,1380,1385,1391,1397,1403,1409,1414,1419,1425,1431,1437,1443],{"__ignoreMap":545},[549,1317,1318],{"class":551,"line":552},[549,1319,1320],{},"pub struct ExtGlobal {\n",[549,1322,1323],{"class":551,"line":558},[549,1324,1325],{},"    pub admin: Pubkey,\n",[549,1327,1328],{"class":551,"line":564},[549,1329,1330],{},"    pub earn_authority: Option\u003CPubkey>,  \u002F\u002F Only for Crank model\n",[549,1332,1333],{"class":551,"line":570},[549,1334,1335],{},"    pub ext_mint: Pubkey,\n",[549,1337,1338],{"class":551,"line":576},[549,1339,1340],{},"    pub m_mint: Pubkey,\n",[549,1342,1343],{"class":551,"line":885},[549,1344,1345],{},"    pub m_earn_global_account: Pubkey,\n",[549,1347,1348],{"class":551,"line":891},[549,1349,1350],{},"    pub bump: u8,\n",[549,1352,1354],{"class":551,"line":1353},8,[549,1355,1356],{},"    pub m_vault_bump: u8,\n",[549,1358,1360],{"class":551,"line":1359},9,[549,1361,1362],{},"    pub ext_mint_authority_bump: u8,\n",[549,1364,1366],{"class":551,"line":1365},10,[549,1367,1368],{},"    pub yield_config: YieldConfig,\n",[549,1370,1372],{"class":551,"line":1371},11,[549,1373,1374],{},"    pub wrap_authorities: Vec\u003CPubkey>,\n",[549,1376,1378],{"class":551,"line":1377},12,[549,1379,579],{},[549,1381,1383],{"class":551,"line":1382},13,[549,1384,868],{"emptyLinePlaceholder":867},[549,1386,1388],{"class":551,"line":1387},14,[549,1389,1390],{},"pub struct YieldConfig {\n",[549,1392,1394],{"class":551,"line":1393},15,[549,1395,1396],{},"    pub variant: YieldVariant,  \u002F\u002F NoYield | ScaledUi | Crank\n",[549,1398,1400],{"class":551,"line":1399},16,[549,1401,1402],{},"    pub last_m_index: u64,\n",[549,1404,1406],{"class":551,"line":1405},17,[549,1407,1408],{},"    pub last_ext_index: u64,\n",[549,1410,1412],{"class":551,"line":1411},18,[549,1413,579],{},[549,1415,1417],{"class":551,"line":1416},19,[549,1418,868],{"emptyLinePlaceholder":867},[549,1420,1422],{"class":551,"line":1421},20,[549,1423,1424],{},"pub enum YieldVariant {\n",[549,1426,1428],{"class":551,"line":1427},21,[549,1429,1430],{},"    NoYield,\n",[549,1432,1434],{"class":551,"line":1433},22,[549,1435,1436],{},"    ScaledUi,\n",[549,1438,1440],{"class":551,"line":1439},23,[549,1441,1442],{},"    Crank,\n",[549,1444,1446],{"class":551,"line":1445},24,[549,1447,579],{},[266,1449,1450],{},[286,1451,1452],{},"Crank-Specific State:",[540,1454,1456],{"className":542,"code":1455,"language":544,"meta":545,"style":545},"\u002F\u002F Only present when compiled with 'crank' feature\npub struct EarnManager {\n    pub manager: Pubkey,\n    pub fee_bps: u64,\n    pub fee_token_account: Pubkey,\n    pub bump: u8,\n}\n\npub struct Earner {\n    pub user: Pubkey,\n    pub user_token_account: Pubkey,\n    pub recipient_token_account: Pubkey,\n    pub earn_manager: Pubkey,\n    pub last_balance: u64,\n    pub last_index: u64,\n    pub bump: u8,\n}\n",[270,1457,1458,1463,1468,1473,1478,1483,1487,1491,1495,1500,1505,1510,1515,1520,1525,1530,1534],{"__ignoreMap":545},[549,1459,1460],{"class":551,"line":552},[549,1461,1462],{},"\u002F\u002F Only present when compiled with 'crank' feature\n",[549,1464,1465],{"class":551,"line":558},[549,1466,1467],{},"pub struct EarnManager {\n",[549,1469,1470],{"class":551,"line":564},[549,1471,1472],{},"    pub manager: Pubkey,\n",[549,1474,1475],{"class":551,"line":570},[549,1476,1477],{},"    pub fee_bps: u64,\n",[549,1479,1480],{"class":551,"line":576},[549,1481,1482],{},"    pub fee_token_account: Pubkey,\n",[549,1484,1485],{"class":551,"line":885},[549,1486,1350],{},[549,1488,1489],{"class":551,"line":891},[549,1490,579],{},[549,1492,1493],{"class":551,"line":1353},[549,1494,868],{"emptyLinePlaceholder":867},[549,1496,1497],{"class":551,"line":1359},[549,1498,1499],{},"pub struct Earner {\n",[549,1501,1502],{"class":551,"line":1365},[549,1503,1504],{},"    pub user: Pubkey,\n",[549,1506,1507],{"class":551,"line":1371},[549,1508,1509],{},"    pub user_token_account: Pubkey,\n",[549,1511,1512],{"class":551,"line":1377},[549,1513,1514],{},"    pub recipient_token_account: Pubkey,\n",[549,1516,1517],{"class":551,"line":1382},[549,1518,1519],{},"    pub earn_manager: Pubkey,\n",[549,1521,1522],{"class":551,"line":1387},[549,1523,1524],{},"    pub last_balance: u64,\n",[549,1526,1527],{"class":551,"line":1393},[549,1528,1529],{},"    pub last_index: u64,\n",[549,1531,1532],{"class":551,"line":1399},[549,1533,1350],{},[549,1535,1536],{"class":551,"line":1405},[549,1537,579],{},[813,1539,1541],{"id":1540},"core-instructions-shared","Core Instructions (Shared)",[658,1543,1544,1552,1560,1568,1580],{},[661,1545,1546,1551],{},[286,1547,1548,903],{},[270,1549,1550],{},"initialize"," Sets up the extension's global state",[661,1553,1554,1559],{},[286,1555,1556,903],{},[270,1557,1558],{},"wrap(amount: u64)"," Wraps into extension token",[661,1561,1562,1567],{},[286,1563,1564,903],{},[270,1565,1566],{},"unwrap(amount: u64)"," Unwraps extension token back",[661,1569,1570,1579],{},[286,1571,1572,1575,1576,903],{},[270,1573,1574],{},"add_wrap_authority"," \u002F ",[270,1577,1578],{},"remove_wrap_authority"," Manage wrap permissions",[661,1581,1582,1587],{},[286,1583,1584,903],{},[270,1585,1586],{},"transfer_admin"," Transfer admin control",[813,1589,1591],{"id":1590},"model-specific-instructions","Model-Specific Instructions",[266,1593,1594],{},[286,1595,1596],{},"NoYield:",[658,1598,1599],{},[661,1600,1601,1604],{},[270,1602,1603],{},"claim_fees()",": Admin claims all accrued yield",[266,1606,1607],{},[286,1608,1609],{},"ScaledUi:",[658,1611,1612,1617],{},[661,1613,1614,1616],{},[270,1615,681],{},": Permissionless index update (updates scaled-ui rate)",[661,1618,1619,1622],{},[270,1620,1621],{},"set_fee(fee_bps: u64)",": Set optional fee (typically 0 for full pass-through)",[266,1624,1625],{},[286,1626,1627],{},"Crank:",[658,1629,1630,1639,1648,1654,1662],{},[661,1631,1632,1575,1635,1638],{},[270,1633,1634],{},"add_earn_manager",[270,1636,1637],{},"remove_earn_manager",": Admin manages earn managers",[661,1640,1641,1575,1644,1647],{},[270,1642,1643],{},"add_earner",[270,1645,1646],{},"remove_earner",": Earn manager manages earners",[661,1649,1650,1653],{},[270,1651,1652],{},"claim_for(user, snapshot_balance)",": Earn authority distributes yield",[661,1655,1656,1658,1659,1661],{},[270,1657,681],{},": Update extension index from base ",[270,1660,272],{}," program",[661,1663,1664,1667],{},[270,1665,1666],{},"set_recipient",": Earner sets custom yield recipient",[305,1669,1671,1672,805],{"id":1670},"_4-swap-facility-programsext_swap","4. Swap Facility (",[270,1673,1674],{},"programs\u002Fext_swap",[266,1676,1677,1679],{},[286,1678,1229],{}," Centralized router for atomic swaps between whitelisted extensions.",[813,1681,1683],{"id":1682},"global-state","Global State",[540,1685,1687],{"className":542,"code":1686,"language":544,"meta":545,"style":545},"pub struct SwapGlobal {\n    pub bump: u8,\n    pub admin: Pubkey,\n    pub whitelisted_unwrappers: Vec\u003CPubkey>,\n    pub whitelisted_extensions: Vec\u003CWhitelistedExtension>,\n}\n\npub struct WhitelistedExtension {\n    pub program_id: Pubkey,\n    pub ext_global: Pubkey,\n}\n",[270,1688,1689,1694,1698,1702,1707,1712,1716,1720,1725,1729,1734],{"__ignoreMap":545},[549,1690,1691],{"class":551,"line":552},[549,1692,1693],{},"pub struct SwapGlobal {\n",[549,1695,1696],{"class":551,"line":558},[549,1697,1350],{},[549,1699,1700],{"class":551,"line":564},[549,1701,1325],{},[549,1703,1704],{"class":551,"line":570},[549,1705,1706],{},"    pub whitelisted_unwrappers: Vec\u003CPubkey>,\n",[549,1708,1709],{"class":551,"line":576},[549,1710,1711],{},"    pub whitelisted_extensions: Vec\u003CWhitelistedExtension>,\n",[549,1713,1714],{"class":551,"line":885},[549,1715,579],{},[549,1717,1718],{"class":551,"line":891},[549,1719,868],{"emptyLinePlaceholder":867},[549,1721,1722],{"class":551,"line":1353},[549,1723,1724],{},"pub struct WhitelistedExtension {\n",[549,1726,1727],{"class":551,"line":1359},[549,1728,966],{},[549,1730,1731],{"class":551,"line":1365},[549,1732,1733],{},"    pub ext_global: Pubkey,\n",[549,1735,1736],{"class":551,"line":1371},[549,1737,579],{},[813,1739,1741],{"id":1740},"core-instructions","Core Instructions",[658,1743,1744,1752,1763,1777,1788],{},[661,1745,1746,1751],{},[286,1747,1748],{},[270,1749,1750],{},"swap(amount, remaining_accounts_split_idx)",": Atomic cross-extension swap",[661,1753,1754,1759,1760,1762],{},[286,1755,1756],{},[270,1757,1758],{},"wrap(amount)",": Convert ",[270,1761,272],{}," to extension",[661,1764,1765,1770,1771,1773,1774,805],{},[286,1766,1767],{},[270,1768,1769],{},"unwrap(amount)",": Convert extension to ",[270,1772,272],{}," (requires ",[270,1775,1776],{},"whitelisted_unwrapper",[661,1778,1779,1787],{},[286,1780,1781,1575,1784],{},[270,1782,1783],{},"whitelist_extension",[270,1785,1786],{},"remove_whitelisted_extension",": Admin manages extensions",[661,1789,1790,1798],{},[286,1791,1792,1575,1795],{},[270,1793,1794],{},"whitelist_unwrapper",[270,1796,1797],{},"remove_whitelisted_unwrapper",": Admin manages unwrap permissions",[266,1800,1801],{},[286,1802,1803],{},"Security Model:",[658,1805,1806,1809,1816],{},[661,1807,1808],{},"Only whitelisted extensions can participate in swaps",[661,1810,1811,1812,1815],{},"Only whitelisted unwrappers can call ",[270,1813,1814],{},"unwrap"," directly",[661,1817,1818],{},"All swaps maintain 1:1 peg",[278,1820,1822],{"id":1821},"developer-integration","Developer Integration",[305,1824,1826],{"id":1825},"interacting-via-sdk","Interacting via SDK",[266,1828,1829],{},"The recommended way to interact with the M0 Solana programs is through the official TypeScript SDK.",[658,1831,1832,1840],{},[661,1833,1834,1211,1837],{},[286,1835,1836],{},"Installation:",[270,1838,1839],{},"pnpm i @m0-foundation\u002Fsolana-m-sdk",[661,1841,1842,1845,1846],{},[286,1843,1844],{},"Core Classes:"," The SDK provides classes that abstract away the onchain complexity:\n",[658,1847,1848,1854,1860],{},[661,1849,1850,1853],{},[270,1851,1852],{},"EarnAuthority",": For admin-level actions like initiating claims and syncing indexes.",[661,1855,1856,1859],{},[270,1857,1858],{},"EarnManager",": For managing a set of earners within an extension (Crank model).",[661,1861,1862,1864],{},[270,1863,1110],{},": For user-level actions and querying an individual's yield status.",[266,1866,1867],{},[286,1868,1869],{},"Example: Building a Claim Transaction (V2 Crank Model)",[540,1871,1875],{"className":1872,"code":1873,"language":1874,"meta":545,"style":545},"language-tsx shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","import { EarnAuthority, Earner } from \"@m0-foundation\u002Fsolana-m-sdk\";\nimport { Connection, PublicKey } from \"@solana\u002Fweb3.js\";\nimport { createPublicClient, http } from \"viem\";\n\n\u002F\u002F Setup clients\nconst connection = new Connection(RPC_URL);\nconst evmClient = createPublicClient({ transport: http(EVM_RPC_URL) });\n\n\u002F\u002F Load authority and earner\nconst auth = await EarnAuthority.load(connection, evmClient, M_EXT_PROGRAM_ID);\nconst earners = await auth.getAllEarners();\nconst earnerToClaim = earners[0];\n\n\u002F\u002F Build the claim instruction\nconst claimIx = await auth.buildClaimInstruction(earnerToClaim);\n\nif (claimIx) {\n  \u002F\u002F build, sign, and send transaction with the instruction...\n}\n","tsx",[270,1876,1877,1916,1943,1970,1974,1980,2003,2038,2042,2047,2081,2105,2126,2130,2135,2158,2162,2173,2178],{"__ignoreMap":545},[549,1878,1879,1883,1887,1891,1894,1897,1900,1903,1906,1910,1913],{"class":551,"line":552},[549,1880,1882],{"class":1881},"s7zQu","import",[549,1884,1886],{"class":1885},"sMK4o"," {",[549,1888,1890],{"class":1889},"sTEyZ"," EarnAuthority",[549,1892,1893],{"class":1885},",",[549,1895,1896],{"class":1889}," Earner",[549,1898,1899],{"class":1885}," }",[549,1901,1902],{"class":1881}," from",[549,1904,1905],{"class":1885}," \"",[549,1907,1909],{"class":1908},"sfazB","@m0-foundation\u002Fsolana-m-sdk",[549,1911,1912],{"class":1885},"\"",[549,1914,1915],{"class":1885},";\n",[549,1917,1918,1920,1922,1925,1927,1930,1932,1934,1936,1939,1941],{"class":551,"line":558},[549,1919,1882],{"class":1881},[549,1921,1886],{"class":1885},[549,1923,1924],{"class":1889}," Connection",[549,1926,1893],{"class":1885},[549,1928,1929],{"class":1889}," PublicKey",[549,1931,1899],{"class":1885},[549,1933,1902],{"class":1881},[549,1935,1905],{"class":1885},[549,1937,1938],{"class":1908},"@solana\u002Fweb3.js",[549,1940,1912],{"class":1885},[549,1942,1915],{"class":1885},[549,1944,1945,1947,1949,1952,1954,1957,1959,1961,1963,1966,1968],{"class":551,"line":564},[549,1946,1882],{"class":1881},[549,1948,1886],{"class":1885},[549,1950,1951],{"class":1889}," createPublicClient",[549,1953,1893],{"class":1885},[549,1955,1956],{"class":1889}," http",[549,1958,1899],{"class":1885},[549,1960,1902],{"class":1881},[549,1962,1905],{"class":1885},[549,1964,1965],{"class":1908},"viem",[549,1967,1912],{"class":1885},[549,1969,1915],{"class":1885},[549,1971,1972],{"class":551,"line":570},[549,1973,868],{"emptyLinePlaceholder":867},[549,1975,1976],{"class":551,"line":576},[549,1977,1979],{"class":1978},"sHwdD","\u002F\u002F Setup clients\n",[549,1981,1982,1986,1989,1992,1995,1998,2001],{"class":551,"line":885},[549,1983,1985],{"class":1984},"spNyl","const",[549,1987,1988],{"class":1889}," connection ",[549,1990,1991],{"class":1885},"=",[549,1993,1994],{"class":1885}," new",[549,1996,1924],{"class":1997},"s2Zo4",[549,1999,2000],{"class":1889},"(RPC_URL)",[549,2002,1915],{"class":1885},[549,2004,2005,2007,2010,2012,2014,2017,2020,2024,2026,2028,2031,2034,2036],{"class":551,"line":891},[549,2006,1985],{"class":1984},[549,2008,2009],{"class":1889}," evmClient ",[549,2011,1991],{"class":1885},[549,2013,1951],{"class":1997},[549,2015,2016],{"class":1889},"(",[549,2018,2019],{"class":1885},"{",[549,2021,2023],{"class":2022},"swJcz"," transport",[549,2025,903],{"class":1885},[549,2027,1956],{"class":1997},[549,2029,2030],{"class":1889},"(EVM_RPC_URL) ",[549,2032,2033],{"class":1885},"}",[549,2035,805],{"class":1889},[549,2037,1915],{"class":1885},[549,2039,2040],{"class":551,"line":1353},[549,2041,868],{"emptyLinePlaceholder":867},[549,2043,2044],{"class":551,"line":1359},[549,2045,2046],{"class":1978},"\u002F\u002F Load authority and earner\n",[549,2048,2049,2051,2054,2056,2059,2061,2063,2066,2069,2071,2074,2076,2079],{"class":551,"line":1365},[549,2050,1985],{"class":1984},[549,2052,2053],{"class":1889}," auth ",[549,2055,1991],{"class":1885},[549,2057,2058],{"class":1881}," await",[549,2060,1890],{"class":1889},[549,2062,527],{"class":1885},[549,2064,2065],{"class":1997},"load",[549,2067,2068],{"class":1889},"(connection",[549,2070,1893],{"class":1885},[549,2072,2073],{"class":1889}," evmClient",[549,2075,1893],{"class":1885},[549,2077,2078],{"class":1889}," M_EXT_PROGRAM_ID)",[549,2080,1915],{"class":1885},[549,2082,2083,2085,2088,2090,2092,2095,2097,2100,2103],{"class":551,"line":1371},[549,2084,1985],{"class":1984},[549,2086,2087],{"class":1889}," earners ",[549,2089,1991],{"class":1885},[549,2091,2058],{"class":1881},[549,2093,2094],{"class":1889}," auth",[549,2096,527],{"class":1885},[549,2098,2099],{"class":1997},"getAllEarners",[549,2101,2102],{"class":1889},"()",[549,2104,1915],{"class":1885},[549,2106,2107,2109,2112,2114,2117,2121,2124],{"class":551,"line":1377},[549,2108,1985],{"class":1984},[549,2110,2111],{"class":1889}," earnerToClaim ",[549,2113,1991],{"class":1885},[549,2115,2116],{"class":1889}," earners[",[549,2118,2120],{"class":2119},"sbssI","0",[549,2122,2123],{"class":1889},"]",[549,2125,1915],{"class":1885},[549,2127,2128],{"class":551,"line":1382},[549,2129,868],{"emptyLinePlaceholder":867},[549,2131,2132],{"class":551,"line":1387},[549,2133,2134],{"class":1978},"\u002F\u002F Build the claim instruction\n",[549,2136,2137,2139,2142,2144,2146,2148,2150,2153,2156],{"class":551,"line":1393},[549,2138,1985],{"class":1984},[549,2140,2141],{"class":1889}," claimIx ",[549,2143,1991],{"class":1885},[549,2145,2058],{"class":1881},[549,2147,2094],{"class":1889},[549,2149,527],{"class":1885},[549,2151,2152],{"class":1997},"buildClaimInstruction",[549,2154,2155],{"class":1889},"(earnerToClaim)",[549,2157,1915],{"class":1885},[549,2159,2160],{"class":551,"line":1399},[549,2161,868],{"emptyLinePlaceholder":867},[549,2163,2164,2167,2170],{"class":551,"line":1405},[549,2165,2166],{"class":1881},"if",[549,2168,2169],{"class":1889}," (claimIx) ",[549,2171,2172],{"class":1885},"{\n",[549,2174,2175],{"class":551,"line":1411},[549,2176,2177],{"class":1978},"  \u002F\u002F build, sign, and send transaction with the instruction...\n",[549,2179,2180],{"class":551,"line":1416},[549,2181,579],{"class":1885},[266,2183,2184],{},[286,2185,2186],{},"Example: Permissionless Sync (V2 ScaledUi Model)",[540,2188,2190],{"className":1872,"code":2189,"language":1874,"meta":545,"style":545},"import { Program } from \"@coral-xyz\u002Fanchor\";\n\n\u002F\u002F Anyone can call sync to update yield indices\nconst tx = await program.methods\n  .sync()\n  .accounts({\n    extGlobal: extGlobalPDA,\n    extMint: extMintAddress,\n    mEarnGlobal: mEarnGlobalAddress,\n    mVault: mVaultPDA,\n    token2022Program: TOKEN_2022_PROGRAM_ID,\n  })\n  .rpc();\n\nconsole.log(\"Synced yield:\", tx);\n",[270,2191,2192,2214,2218,2223,2241,2251,2262,2275,2287,2299,2311,2323,2331,2342,2346],{"__ignoreMap":545},[549,2193,2194,2196,2198,2201,2203,2205,2207,2210,2212],{"class":551,"line":552},[549,2195,1882],{"class":1881},[549,2197,1886],{"class":1885},[549,2199,2200],{"class":1889}," Program",[549,2202,1899],{"class":1885},[549,2204,1902],{"class":1881},[549,2206,1905],{"class":1885},[549,2208,2209],{"class":1908},"@coral-xyz\u002Fanchor",[549,2211,1912],{"class":1885},[549,2213,1915],{"class":1885},[549,2215,2216],{"class":551,"line":558},[549,2217,868],{"emptyLinePlaceholder":867},[549,2219,2220],{"class":551,"line":564},[549,2221,2222],{"class":1978},"\u002F\u002F Anyone can call sync to update yield indices\n",[549,2224,2225,2227,2230,2232,2234,2236,2238],{"class":551,"line":570},[549,2226,1985],{"class":1984},[549,2228,2229],{"class":1889}," tx ",[549,2231,1991],{"class":1885},[549,2233,2058],{"class":1881},[549,2235,1661],{"class":1889},[549,2237,527],{"class":1885},[549,2239,2240],{"class":1889},"methods\n",[549,2242,2243,2246,2248],{"class":551,"line":576},[549,2244,2245],{"class":1885},"  .",[549,2247,1210],{"class":1997},[549,2249,2250],{"class":1889},"()\n",[549,2252,2253,2255,2258,2260],{"class":551,"line":885},[549,2254,2245],{"class":1885},[549,2256,2257],{"class":1997},"accounts",[549,2259,2016],{"class":1889},[549,2261,2172],{"class":1885},[549,2263,2264,2267,2269,2272],{"class":551,"line":891},[549,2265,2266],{"class":2022},"    extGlobal",[549,2268,903],{"class":1885},[549,2270,2271],{"class":1889}," extGlobalPDA",[549,2273,2274],{"class":1885},",\n",[549,2276,2277,2280,2282,2285],{"class":551,"line":1353},[549,2278,2279],{"class":2022},"    extMint",[549,2281,903],{"class":1885},[549,2283,2284],{"class":1889}," extMintAddress",[549,2286,2274],{"class":1885},[549,2288,2289,2292,2294,2297],{"class":551,"line":1359},[549,2290,2291],{"class":2022},"    mEarnGlobal",[549,2293,903],{"class":1885},[549,2295,2296],{"class":1889}," mEarnGlobalAddress",[549,2298,2274],{"class":1885},[549,2300,2301,2304,2306,2309],{"class":551,"line":1365},[549,2302,2303],{"class":2022},"    mVault",[549,2305,903],{"class":1885},[549,2307,2308],{"class":1889}," mVaultPDA",[549,2310,2274],{"class":1885},[549,2312,2313,2316,2318,2321],{"class":551,"line":1371},[549,2314,2315],{"class":2022},"    token2022Program",[549,2317,903],{"class":1885},[549,2319,2320],{"class":1889}," TOKEN_2022_PROGRAM_ID",[549,2322,2274],{"class":1885},[549,2324,2325,2328],{"class":551,"line":1377},[549,2326,2327],{"class":1885},"  }",[549,2329,2330],{"class":1889},")\n",[549,2332,2333,2335,2338,2340],{"class":551,"line":1382},[549,2334,2245],{"class":1885},[549,2336,2337],{"class":1997},"rpc",[549,2339,2102],{"class":1889},[549,2341,1915],{"class":1885},[549,2343,2344],{"class":551,"line":1387},[549,2345,868],{"emptyLinePlaceholder":867},[549,2347,2348,2351,2353,2356,2358,2360,2363,2365,2367,2370],{"class":551,"line":1393},[549,2349,2350],{"class":1889},"console",[549,2352,527],{"class":1885},[549,2354,2355],{"class":1997},"log",[549,2357,2016],{"class":1889},[549,2359,1912],{"class":1885},[549,2361,2362],{"class":1908},"Synced yield:",[549,2364,1912],{"class":1885},[549,2366,1893],{"class":1885},[549,2368,2369],{"class":1889}," tx)",[549,2371,1915],{"class":1885},[305,2373,2375],{"id":2374},"offchain-data-via-api","Offchain Data via API",[266,2377,2378],{},"For historical data, analytics, and building dashboards, use the M0 Solana API, which is powered by a Substreams indexer.",[658,2380,2381,2389,2397],{},[661,2382,2383,1211,2386],{},[286,2384,2385],{},"Base URL (Mainnet):",[270,2387,2388],{},"https:\u002F\u002Fapi-production-0046.up.railway.app",[661,2390,2391,1211,2394],{},[286,2392,2393],{},"SDK:",[270,2395,2396],{},"pnpm i @m0-foundation\u002Fsolana-m-api-sdk",[661,2398,2399,2402],{},[286,2400,2401],{},"Key Endpoints:",[658,2403,2404,2410,2419],{},[661,2405,2406,2409],{},[270,2407,2408],{},"\u002Fevents\u002Fbridges",": Get latest bridge events.",[661,2411,2412,2415,2416,2418],{},[270,2413,2414],{},"\u002Fevents\u002Findex-updates",": Get historical ",[270,2417,272],{}," Index updates.",[661,2420,2421,2424],{},[270,2422,2423],{},"\u002Ftoken-account\u002F{pubkey}\u002F{mint}\u002Fclaims",": Get yield claim history for a specific token account.",[305,2426,2428],{"id":2427},"onchain-addresses","Onchain Addresses",[266,2430,2431,2432,527],{},"A full list of program IDs, mints, and other key accounts for both Mainnet and Devnet can be found in the ",[2433,2434,2436],"a",{"href":2435},"\u002Fresources\u002Faddresses#solana",[286,2437,2438],{},"Addresses resource page",[278,2440,2442],{"id":2441},"fogo-network-support","Fogo Network Support",[266,2444,2445,2447],{},[286,2446,1229],{}," The architecture is designed to support Fogo, Wormhole's native rollup, alongside Solana.",[266,2449,2450],{},[286,2451,2452],{},"What is Fogo?",[658,2454,2455,2458,2461],{},[661,2456,2457],{},"Wormhole-native rollup optimized for cross-chain applications",[661,2459,2460],{},"SVM-compatible (runs Solana programs with minimal changes)",[661,2462,2463],{},"Optimized for low-latency cross-chain messaging",[266,2465,2466],{},[286,2467,2468],{},"M0 on Fogo:",[658,2470,2471,2474,2477],{},[661,2472,2473],{},"Same program logic as Solana deployment",[661,2475,2476],{},"Feature flags enable Fogo-specific optimizations",[661,2478,2479],{},"Seamless interoperability with Solana via Wormhole NTT",[266,2481,2482,2485,2486,2489],{},[286,2483,2484],{},"Deployment Status:"," Fogo support is live. Check the ",[2433,2487,2488],{"href":250},"Addresses page"," for Fogo-specific program IDs.",[278,2491,2493],{"id":2492},"source-code-audits","Source Code & Audits",[658,2495,2496,2507,2517],{},[661,2497,2498,1211,2501],{},[286,2499,2500],{},"Portal & Earn Programs:",[2433,2502,2506],{"href":2503,"rel":2504},"https:\u002F\u002Fgithub.com\u002Fm0-foundation\u002Fsolana-m",[2505],"nofollow","m0-foundation\u002Fsolana-m",[661,2508,2509,1211,2512],{},[286,2510,2511],{},"Extension Framework & Swap Facility:",[2433,2513,2516],{"href":2514,"rel":2515},"https:\u002F\u002Fgithub.com\u002Fm0-foundation\u002Fsolana-m-extensions",[2505],"m0-foundation\u002Fsolana-m-extensions",[661,2518,2519,2522,2523,527],{},[286,2520,2521],{},"Audits:"," Security audits for all programs can be found in the ",[2433,2524,2525],{"href":254},[286,2526,2527],{},"Audits resource page",[278,2529,2531],{"id":2530},"next-steps","Next Steps",[658,2533,2534,2545],{},[661,2535,2536,2541,2542,2544],{},[286,2537,2538,2539,903],{},"Build with ",[270,2540,272],{}," Integrate the base ",[270,2543,272],{}," token into your Solana dApp",[661,2546,2547,2550,2551,2553],{},[286,2548,2549],{},"Create an Extension:"," Deploy your own ",[270,2552,272],{},"-backed stablecoin using NoYield, ScaledUi, or Crank models",[2555,2556,2557],"style",{},"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);}html pre.shiki code .s7zQu, html code.shiki .s7zQu{--shiki-light:#39ADB5;--shiki-light-font-style:italic;--shiki-default:#89DDFF;--shiki-default-font-style:italic;--shiki-dark:#89DDFF;--shiki-dark-font-style:italic}html pre.shiki code .sMK4o, html code.shiki .sMK4o{--shiki-light:#39ADB5;--shiki-default:#89DDFF;--shiki-dark:#89DDFF}html pre.shiki code .sTEyZ, html code.shiki .sTEyZ{--shiki-light:#90A4AE;--shiki-default:#EEFFFF;--shiki-dark:#BABED8}html pre.shiki code .sfazB, html code.shiki .sfazB{--shiki-light:#91B859;--shiki-default:#C3E88D;--shiki-dark:#C3E88D}html pre.shiki code .sHwdD, html code.shiki .sHwdD{--shiki-light:#90A4AE;--shiki-light-font-style:italic;--shiki-default:#546E7A;--shiki-default-font-style:italic;--shiki-dark:#676E95;--shiki-dark-font-style:italic}html pre.shiki code .spNyl, html code.shiki .spNyl{--shiki-light:#9C3EDA;--shiki-default:#C792EA;--shiki-dark:#C792EA}html pre.shiki code .s2Zo4, html code.shiki .s2Zo4{--shiki-light:#6182B8;--shiki-default:#82AAFF;--shiki-dark:#82AAFF}html pre.shiki code .swJcz, html code.shiki .swJcz{--shiki-light:#E53935;--shiki-default:#F07178;--shiki-dark:#F07178}html pre.shiki code .sbssI, html code.shiki .sbssI{--shiki-light:#F76D47;--shiki-default:#F78C6C;--shiki-dark:#F78C6C}",{"title":545,"searchDepth":552,"depth":558,"links":2559},[2560,2564,2574,2584,2589,2590,2591],{"id":280,"depth":558,"text":281,"children":2561},[2562,2563],{"id":307,"depth":564,"text":308},{"id":430,"depth":564,"text":431},{"id":499,"depth":558,"text":500,"children":2565},[2566,2567,2569,2570,2571,2572,2573],{"id":506,"depth":564,"text":507},{"id":582,"depth":564,"text":2568},"2. Frozen-by-Default $M",{"id":641,"depth":564,"text":642},{"id":672,"depth":564,"text":673},{"id":696,"depth":564,"text":697},{"id":729,"depth":564,"text":730},{"id":776,"depth":564,"text":777},{"id":796,"depth":558,"text":797,"children":2575},[2576,2578,2580,2582],{"id":800,"depth":564,"text":2577},"1. Portal Program (programs\u002Fportal)",{"id":984,"depth":564,"text":2579},"2. Earn Program (programs\u002Fearn)",{"id":1217,"depth":564,"text":2581},"3. $M Extension Framework (programs\u002Fm_ext)",{"id":1670,"depth":564,"text":2583},"4. Swap Facility (programs\u002Fext_swap)",{"id":1821,"depth":558,"text":1822,"children":2585},[2586,2587,2588],{"id":1825,"depth":564,"text":1826},{"id":2374,"depth":564,"text":2375},{"id":2427,"depth":564,"text":2428},{"id":2441,"depth":558,"text":2442},{"id":2492,"depth":558,"text":2493},{"id":2530,"depth":558,"text":2531},"Technical deep dive into the M0 Protocol's implementation on the Solana blockchain, including program specifications, V2 upgrades, and developer integration guides.","md",null,{},{"title":232,"description":2592},"aRBg5lfCQw11t6YtoVjVswlz01gWVYNGVlG5ATwSBig",[2599,2601],{"title":228,"path":229,"stem":230,"description":2600,"children":-1},"Overview of the primary roles within the M0 ecosystem, their responsibilities, and how they interact with the protocol's core smart contracts.",{"title":236,"path":237,"stem":238,"description":2602,"children":-1},"Complete documentation of Wrapped M (wM), the non-rebasing ERC-20 wrapper that maintains yield-earning capabilities while providing DeFi compatibility."]