From cabffd4f8a35167d83d209cde58d9a050eb0d8c8 Mon Sep 17 00:00:00 2001 From: Michael Moffett Date: Sat, 24 Oct 2026 07:04:41 -0600 Subject: [PATCH 1/4] fix(types): load the Wrapped BTC row the CSV token cache drops MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Join the Wrapped BTC row in `crates/types/src/verified_tokens.csv` back into one line, and add two tests that pin the row count and the WBTC mint. The `5XZw…` icon URL has a newline inside its quotes. `csv.lines()` splits the row in two, `fields.len() < 5` skips both halves, and the mint is missing from `VERIFIED_TOKENS`. --- crates/types/src/verified_tokens.csv | 3 +-- crates/types/src/verified_tokens.rs | 20 +++++++++++++++++++- 2 files changed, 20 insertions(+), 3 deletions(-) diff --git a/crates/types/src/verified_tokens.csv b/crates/types/src/verified_tokens.csv index 6966e4553..69961e790 100644 --- a/crates/types/src/verified_tokens.csv +++ b/crates/types/src/verified_tokens.csv @@ -88,8 +88,7 @@ "7Y2TPeq3hqw21LRTCi4wBWoivDngCpNNJsN1hzhZpump","Sachicoin","SACHI","https://ipfs.io/ipfs/bafybeid7vmfzlijieyk2yjc5pq4e7dkbn2w7yadoojuf6qsqwably5w7nm",6,"GgniteFe3VjeJq1PraxoQsFKw4qHajBDpYViVTqggoq5",985127434.646622,985127434.646622,"TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA","","verified","2025-10-07T07:37:18Z",0.006875074890217659,"2025-12-08T21:49:24.619965854Z" "8x5VqbHA8D7NkD52uNuS5nnt3PwA8pLD34ymskeSo2Wn","zerebro","ZEREBRO","https://ipfs.io/ipfs/QmZ1HDSibY2LdEmC1tPHK36ApGCQACJENqsbPsT2nc29AD",6,"9zPxrXcor3gzTsg73LGBji6VVpfNYeiAq9T9GDPmKTHV",999952225.37906,999952225.37906,"TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA","","community|launchpad|moonshot-verified|verified","2024-10-25T05:55:11Z",0.03042315351134891,"2025-12-08T21:48:07.619745813Z" "LBTCgU4b3wsFKsPwBn1rRZDx5DoFutM6RPiEt1TPDsY","Lombard Staked BTC","LBTC","https://www.lombard.finance/lbtc/LBTC.png",8,"CuyPF5P5ZgAVKqiUTF29XiD76bUkG4jD71KuiJrLiwCt",955.63389127,955.63389127,"TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA","HzCyQqcAoxAHeqHAWH1RQbfw7GNUzinqSWideGj7ZtEE","community-assist|verified|major","2025-04-02T15:01:21Z",91142.22356340135,"2025-12-08T21:48:48.619784251Z" -"5XZw2LKTyrfvfiskJ78AMpackRjPcyCif1WhUsPDuVqQ","Wrapped BTC","WBTC","https://j73gp4w27ucraqtyzsqa5th4fwldfvqgq576cnceekfactgk4fla.arweave.net/T_Zn8tr9BRBCeMygDsz8LZYy1gaHf-E0RCKKAUzK4VY -",8,"3YDttErxTR3WNwhGkFm8QbpfHtbCEzG96E6U29jQWYuK",104.83190243,104.83190243,"TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA","3YDttErxTR3WNwhGkFm8QbpfHtbCEzG96E6U29jQWYuK","community-assist|verified|major","2025-04-28T07:00:50Z",90600.87361021532,"2025-12-08T21:45:47.620764281Z" +"5XZw2LKTyrfvfiskJ78AMpackRjPcyCif1WhUsPDuVqQ","Wrapped BTC","WBTC","https://j73gp4w27ucraqtyzsqa5th4fwldfvqgq576cnceekfactgk4fla.arweave.net/T_Zn8tr9BRBCeMygDsz8LZYy1gaHf-E0RCKKAUzK4VY",8,"3YDttErxTR3WNwhGkFm8QbpfHtbCEzG96E6U29jQWYuK",104.83190243,104.83190243,"TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA","3YDttErxTR3WNwhGkFm8QbpfHtbCEzG96E6U29jQWYuK","community-assist|verified|major","2025-04-28T07:00:50Z",90600.87361021532,"2025-12-08T21:45:47.620764281Z" "F7pB3ZdfBnyFw2LRHydWEn9BmhEa5XihXLjhySFRpump","You’ll own nothing & be happy","NOTHING","https://ipfs.io/ipfs/QmUrePFqpeW7AXZhFhexoCMFRcmyP3z5rrBF9RXGu32rFw",6,"GHgSVNjsWXyTc3ZNEEaEowF5xMT4wptUKFcerKSgSVtB",999931431.949414,999931431.949414,"TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA","","verified","2025-11-11T20:07:12Z",0.0016335744185029628,"2025-12-08T21:49:18.620061143Z" "3ThdFZQKM6kRyVGLG48kaPg5TRMhYMKY1iCRa9xop1WC","eUSX","eUSX","https://raw.githubusercontent.com/Solstice-Labs-Official/eusx-metadata/refs/heads/main/eusx.png",6,"5RabYeYt19sor9RvExkiRvv1T9rWje5hPW7xeYXB6quQ",129179166.045647,129179166.045647,"TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA","2aHdm37djj4c21ztMRBmmo4my6RtzN5Nn58Y39rpWbRM","community-assist|verified|stable","2025-06-24T14:47:50Z",1.016026466750484,"2025-12-08T21:49:07.619462473Z" "KENJSUYLASHUMfHyy5o4Hp2FdNqZg1AsUPhfH2kYvEP","test griffain.com","GRIFFAIN","https://griffain.com/logo.png",6,"KEN7s6mHAFpqmvppk7L9VaJW3htu3jz6z3dDjiaWdYT",999860138.921969,999860138.921969,"TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA","","birdeye-trending|community|launchpad|moonshot-verified|verified","2024-11-02T23:37:45Z",0.020462329233444255,"2025-12-08T21:48:03.629819082Z" diff --git a/crates/types/src/verified_tokens.rs b/crates/types/src/verified_tokens.rs index b3958e55d..101368409 100644 --- a/crates/types/src/verified_tokens.rs +++ b/crates/types/src/verified_tokens.rs @@ -92,7 +92,7 @@ pub static VERIFIED_TOKENS_BY_SYMBOL: Lazy> = Lazy::n #[cfg(test)] mod tests { - use super::parse_csv_line; + use super::{VERIFIED_TOKENS, parse_csv_line}; #[test] fn parse_csv_line_handles_quoted_fields() { @@ -107,4 +107,22 @@ mod tests { assert_eq!(fields[1], r#""quoted""#); } + + #[test] + fn loads_every_row() { + let rows = include_str!("verified_tokens.csv").lines().skip(1).count(); + + assert_eq!(VERIFIED_TOKENS.len(), rows); + } + + #[test] + fn loads_wbtc() { + let wbtc = VERIFIED_TOKENS + .iter() + .find(|token| token.address == "5XZw2LKTyrfvfiskJ78AMpackRjPcyCif1WhUsPDuVqQ") + .expect("WBTC row loads"); + + assert_eq!(wbtc.symbol, "WBTC"); + assert_eq!(wbtc.decimals, 8); + } } From 7de07f66ad07d41dd401d6d25e8bc7ac2a9ef8de Mon Sep 17 00:00:00 2001 From: Michael Moffett Date: Sat, 24 Oct 2026 07:04:43 -0600 Subject: [PATCH 2/4] greptile.json: review on request only --- greptile.json | 8 ++++++++ 1 file changed, 8 insertions(+) create mode 100644 greptile.json diff --git a/greptile.json b/greptile.json new file mode 100644 index 000000000..56c8d2bd1 --- /dev/null +++ b/greptile.json @@ -0,0 +1,8 @@ +{ + "autoReview": [], + "strictness": 1, + "customContext": { + "rules": [], + "files": [] + } +} From e1e87ff69d92caf1dfc28dc9a7a0691190914b5b Mon Sep 17 00:00:00 2001 From: Michael Moffett Date: Sat, 24 Oct 2026 08:30:55 -0600 Subject: [PATCH 3/4] fix(types): load the Wrapped BTC row the CSV token cache drops MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The `5XZw…` icon URL has a newline inside its quotes. `csv.lines()` splits the row in two, `fields.len() < 5` skips both halves, and the mint is missing from `VERIFIED_TOKENS`. --- crates/types/src/verified_tokens.csv | 3 +-- crates/types/src/verified_tokens.rs | 20 +++++++++++++++++++- 2 files changed, 20 insertions(+), 3 deletions(-) diff --git a/crates/types/src/verified_tokens.csv b/crates/types/src/verified_tokens.csv index 6966e4553..69961e790 100644 --- a/crates/types/src/verified_tokens.csv +++ b/crates/types/src/verified_tokens.csv @@ -88,8 +88,7 @@ "7Y2TPeq3hqw21LRTCi4wBWoivDngCpNNJsN1hzhZpump","Sachicoin","SACHI","https://ipfs.io/ipfs/bafybeid7vmfzlijieyk2yjc5pq4e7dkbn2w7yadoojuf6qsqwably5w7nm",6,"GgniteFe3VjeJq1PraxoQsFKw4qHajBDpYViVTqggoq5",985127434.646622,985127434.646622,"TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA","","verified","2025-10-07T07:37:18Z",0.006875074890217659,"2025-12-08T21:49:24.619965854Z" "8x5VqbHA8D7NkD52uNuS5nnt3PwA8pLD34ymskeSo2Wn","zerebro","ZEREBRO","https://ipfs.io/ipfs/QmZ1HDSibY2LdEmC1tPHK36ApGCQACJENqsbPsT2nc29AD",6,"9zPxrXcor3gzTsg73LGBji6VVpfNYeiAq9T9GDPmKTHV",999952225.37906,999952225.37906,"TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA","","community|launchpad|moonshot-verified|verified","2024-10-25T05:55:11Z",0.03042315351134891,"2025-12-08T21:48:07.619745813Z" "LBTCgU4b3wsFKsPwBn1rRZDx5DoFutM6RPiEt1TPDsY","Lombard Staked BTC","LBTC","https://www.lombard.finance/lbtc/LBTC.png",8,"CuyPF5P5ZgAVKqiUTF29XiD76bUkG4jD71KuiJrLiwCt",955.63389127,955.63389127,"TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA","HzCyQqcAoxAHeqHAWH1RQbfw7GNUzinqSWideGj7ZtEE","community-assist|verified|major","2025-04-02T15:01:21Z",91142.22356340135,"2025-12-08T21:48:48.619784251Z" -"5XZw2LKTyrfvfiskJ78AMpackRjPcyCif1WhUsPDuVqQ","Wrapped BTC","WBTC","https://j73gp4w27ucraqtyzsqa5th4fwldfvqgq576cnceekfactgk4fla.arweave.net/T_Zn8tr9BRBCeMygDsz8LZYy1gaHf-E0RCKKAUzK4VY -",8,"3YDttErxTR3WNwhGkFm8QbpfHtbCEzG96E6U29jQWYuK",104.83190243,104.83190243,"TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA","3YDttErxTR3WNwhGkFm8QbpfHtbCEzG96E6U29jQWYuK","community-assist|verified|major","2025-04-28T07:00:50Z",90600.87361021532,"2025-12-08T21:45:47.620764281Z" +"5XZw2LKTyrfvfiskJ78AMpackRjPcyCif1WhUsPDuVqQ","Wrapped BTC","WBTC","https://j73gp4w27ucraqtyzsqa5th4fwldfvqgq576cnceekfactgk4fla.arweave.net/T_Zn8tr9BRBCeMygDsz8LZYy1gaHf-E0RCKKAUzK4VY",8,"3YDttErxTR3WNwhGkFm8QbpfHtbCEzG96E6U29jQWYuK",104.83190243,104.83190243,"TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA","3YDttErxTR3WNwhGkFm8QbpfHtbCEzG96E6U29jQWYuK","community-assist|verified|major","2025-04-28T07:00:50Z",90600.87361021532,"2025-12-08T21:45:47.620764281Z" "F7pB3ZdfBnyFw2LRHydWEn9BmhEa5XihXLjhySFRpump","You’ll own nothing & be happy","NOTHING","https://ipfs.io/ipfs/QmUrePFqpeW7AXZhFhexoCMFRcmyP3z5rrBF9RXGu32rFw",6,"GHgSVNjsWXyTc3ZNEEaEowF5xMT4wptUKFcerKSgSVtB",999931431.949414,999931431.949414,"TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA","","verified","2025-11-11T20:07:12Z",0.0016335744185029628,"2025-12-08T21:49:18.620061143Z" "3ThdFZQKM6kRyVGLG48kaPg5TRMhYMKY1iCRa9xop1WC","eUSX","eUSX","https://raw.githubusercontent.com/Solstice-Labs-Official/eusx-metadata/refs/heads/main/eusx.png",6,"5RabYeYt19sor9RvExkiRvv1T9rWje5hPW7xeYXB6quQ",129179166.045647,129179166.045647,"TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA","2aHdm37djj4c21ztMRBmmo4my6RtzN5Nn58Y39rpWbRM","community-assist|verified|stable","2025-06-24T14:47:50Z",1.016026466750484,"2025-12-08T21:49:07.619462473Z" "KENJSUYLASHUMfHyy5o4Hp2FdNqZg1AsUPhfH2kYvEP","test griffain.com","GRIFFAIN","https://griffain.com/logo.png",6,"KEN7s6mHAFpqmvppk7L9VaJW3htu3jz6z3dDjiaWdYT",999860138.921969,999860138.921969,"TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA","","birdeye-trending|community|launchpad|moonshot-verified|verified","2024-11-02T23:37:45Z",0.020462329233444255,"2025-12-08T21:48:03.629819082Z" diff --git a/crates/types/src/verified_tokens.rs b/crates/types/src/verified_tokens.rs index b3958e55d..101368409 100644 --- a/crates/types/src/verified_tokens.rs +++ b/crates/types/src/verified_tokens.rs @@ -92,7 +92,7 @@ pub static VERIFIED_TOKENS_BY_SYMBOL: Lazy> = Lazy::n #[cfg(test)] mod tests { - use super::parse_csv_line; + use super::{VERIFIED_TOKENS, parse_csv_line}; #[test] fn parse_csv_line_handles_quoted_fields() { @@ -107,4 +107,22 @@ mod tests { assert_eq!(fields[1], r#""quoted""#); } + + #[test] + fn loads_every_row() { + let rows = include_str!("verified_tokens.csv").lines().skip(1).count(); + + assert_eq!(VERIFIED_TOKENS.len(), rows); + } + + #[test] + fn loads_wbtc() { + let wbtc = VERIFIED_TOKENS + .iter() + .find(|token| token.address == "5XZw2LKTyrfvfiskJ78AMpackRjPcyCif1WhUsPDuVqQ") + .expect("WBTC row loads"); + + assert_eq!(wbtc.symbol, "WBTC"); + assert_eq!(wbtc.decimals, 8); + } } From a6b59e5b2d2d03c5e5e6a0b391ff4bedbf2be0ba Mon Sep 17 00:00:00 2001 From: Michael Moffett Date: Sat, 24 Oct 2026 09:29:20 -0600 Subject: [PATCH 4/4] fix(types): load the Wrapped BTC row the CSV token cache drops MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Join the Wrapped BTC row in `crates/types/src/verified_tokens.csv` back into one line, and add two tests that pin the row count and the WBTC mint. The `5XZw…` icon URL has a newline inside its quotes. `csv.lines()` splits the row in two, `fields.len() < 5` skips both halves, and the mint is missing from `VERIFIED_TOKENS`. --- crates/mcp/src/surfpool/set_token_account.rs | 50 ++++++++++++++++++-- crates/types/src/lib.rs | 2 +- 2 files changed, 47 insertions(+), 5 deletions(-) diff --git a/crates/mcp/src/surfpool/set_token_account.rs b/crates/mcp/src/surfpool/set_token_account.rs index 25d1c1195..8253f5dfe 100644 --- a/crates/mcp/src/surfpool/set_token_account.rs +++ b/crates/mcp/src/surfpool/set_token_account.rs @@ -7,8 +7,8 @@ use solana_pubkey::Pubkey; use solana_signer::Signer as _; use spl_associated_token_account_interface::address::get_associated_token_address_with_program_id; use surfpool_types::{ + VERIFIED_TOKENS, VERIFIED_TOKENS_BY_SYMBOL, types::{AccountUpdate, TokenAccountUpdate}, - verified_tokens::VERIFIED_TOKENS_BY_SYMBOL, }; const SOL_DECIMALS: u32 = 9; @@ -187,10 +187,10 @@ pub async fn run( }) } else if let Ok(mint_pubkey) = Pubkey::try_from(token_identifier.as_str()) { let mint_str = mint_pubkey.to_string(); - let token_info = VERIFIED_TOKENS_BY_SYMBOL + let token_info = VERIFIED_TOKENS .iter() - .find(|(_, info)| info.address == mint_str) - .map(|(symbol, info)| (symbol.clone(), info.decimals as u32)); + .find(|info| info.address == mint_str) + .map(|info| (info.symbol.clone(), info.decimals as u32)); if let Some((symbol, decimals)) = token_info { Ok(TokenDetails { is_sol: false, @@ -363,3 +363,45 @@ pub async fn run( ), } } + +#[cfg(test)] +mod tests { + use std::{ + io::{Read, Write}, + net::TcpListener, + }; + + use super::*; + + #[tokio::test] + async fn portal_wbtc_mint_resolves_its_decimals() { + let listener = TcpListener::bind("127.0.0.1:0").expect("bind canned rpc"); + let addr = listener.local_addr().expect("local addr"); + std::thread::spawn(move || { + let (mut stream, _) = listener.accept().expect("accept"); + assert_ne!(stream.read(&mut [0u8; 16 * 1024]).expect("read request"), 0); + let body = r#"{"jsonrpc":"2.0","result":null,"id":1}"#; + write!( + stream, + "HTTP/1.1 200 OK\r\nContent-Type: application/json\r\nContent-Length: {}\r\nConnection: close\r\n\r\n{body}", + body.len() + ) + .expect("write response"); + }); + + let response = run( + format!("http://{addr}"), + SeededAccount::new(None), + Some("3NZ9JMVBmGAqocybic2c7LQCJScmgsAZ6vQqTDzcqmJh".to_string()), + Some(1), + None, + None, + ) + .await; + + let Some([SetAccountSuccess::Token(updated)]) = response.success.as_deref() else { + panic!("{:?}", response.error); + }; + assert_eq!(updated.token_amount, 100_000_000); + } +} diff --git a/crates/types/src/lib.rs b/crates/types/src/lib.rs index 5a25e6fd6..41f38a56f 100644 --- a/crates/types/src/lib.rs +++ b/crates/types/src/lib.rs @@ -16,4 +16,4 @@ pub use features::*; pub use jito_bundles::*; pub use scenarios::*; pub use types::*; -pub use verified_tokens::{TokenInfo, VERIFIED_TOKENS_BY_SYMBOL}; +pub use verified_tokens::{TokenInfo, VERIFIED_TOKENS, VERIFIED_TOKENS_BY_SYMBOL};