<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: BlazePhoenix</title>
    <description>The latest articles on DEV Community by BlazePhoenix (@blazephoenix_0bfac717a952).</description>
    <link>https://dev.to/blazephoenix_0bfac717a952</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F4180070%2F9dbaabd2-ca3f-4e59-b99f-9790b1eea7dd.png</url>
      <title>DEV Community: BlazePhoenix</title>
      <link>https://dev.to/blazephoenix_0bfac717a952</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/blazephoenix_0bfac717a952"/>
    <language>en</language>
    <item>
      <title>For bot builders: would you take an on-chain quote over a quote API?</title>
      <dc:creator>BlazePhoenix</dc:creator>
      <pubDate>Mon, 12 Oct 2026 20:36:48 +0000</pubDate>
      <link>https://dev.to/blazephoenix_0bfac717a952/for-bot-builders-would-you-take-an-on-chain-quote-over-a-quote-api-1efd</link>
      <guid>https://dev.to/blazephoenix_0bfac717a952/for-bot-builders-would-you-take-an-on-chain-quote-over-a-quote-api-1efd</guid>
      <description>&lt;p&gt;Looking for blunt feedback from people who run bots or backends that swap.&lt;/p&gt;

&lt;p&gt;Context: I'm on the BlazePhoenix team. We are a small team building an on-chain DEX aggregator. Our quotes come from a contract (the Quoter), so you read them with a plain &lt;code&gt;eth_call&lt;/code&gt; on your own RPC. No API key, no account. There is also an SDK (&lt;code&gt;npm i @blazephoenix/sdk&lt;/code&gt;) and an MCP endpoint if you are wiring up agents.&lt;/p&gt;

&lt;p&gt;The trade-offs as I see them:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;For the eth_call approach&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;no key to rotate, no vendor rate limit&lt;/li&gt;
&lt;li&gt;deterministic per block, so you can replay a quote when a fill looks wrong&lt;/li&gt;
&lt;li&gt;the swap computes its route inside the executing transaction and reverts below your signed minimum&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Against it&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;you depend on your own RPC being healthy&lt;/li&gt;
&lt;li&gt;on-chain route search has to fit in gas, so it cannot be as wide as an off-chain solver&lt;/li&gt;
&lt;li&gt;we are pre-launch, and the contracts are not yet audited by an external firm; an independent external audit is scheduled&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;So the question: if you run a bot today, what would make you move one call path from a hosted API to an &lt;code&gt;eth_call&lt;/code&gt;? Or what would stop you, regardless?&lt;/p&gt;

&lt;p&gt;Not trying to recruit anyone. I would rather hear "this is pointless because X" now than after we have built the wrong thing.&lt;/p&gt;

</description>
      <category>discuss</category>
      <category>web3</category>
      <category>ethereum</category>
      <category>bots</category>
    </item>
    <item>
      <title>Stop Calling Quote APIs. Make an eth_call</title>
      <dc:creator>BlazePhoenix</dc:creator>
      <pubDate>Mon, 12 Oct 2026 20:34:39 +0000</pubDate>
      <link>https://dev.to/blazephoenix_0bfac717a952/stop-calling-quote-apis-make-an-ethcall-4k8k</link>
      <guid>https://dev.to/blazephoenix_0bfac717a952/stop-calling-quote-apis-make-an-ethcall-4k8k</guid>
      <description>&lt;p&gt;Look at your swap integration and find the line that fetches a quote.&lt;/p&gt;

&lt;p&gt;There is a good chance it is an HTTPS request to someone else's server, with an API key in a header and a rate limit you discovered in production.&lt;/p&gt;

&lt;p&gt;That line is the least decentralised thing in your stack.&lt;/p&gt;

&lt;h2&gt;
  
  
  What that dependency really costs
&lt;/h2&gt;

&lt;p&gt;A quote API gives you three problems you did not ask for:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Availability.&lt;/strong&gt; Their outage is your outage. Their rate limit is your ceiling.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Identity.&lt;/strong&gt; An API key ties every request to an account. For a bot, a backend or an agent, that is a credential to store, rotate and leak.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Verifiability.&lt;/strong&gt; The response is a JSON number. Your code cannot tell a correct quote from a wrong one. It can only trust it.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The third one is the expensive one. You built on a chain so you would not have to trust a server, and then you put a server in front of your most important number.&lt;/p&gt;

&lt;h2&gt;
  
  
  The alternative: the quote is a view
&lt;/h2&gt;

&lt;p&gt;If the quote is computed by a contract, fetching it is a read call. No account, no key, no vendor. Your RPC, your block, your result.&lt;/p&gt;

&lt;p&gt;That is how BlazePhoenix works. (Disclosure: I am on the team.) Quotes are computed on-chain by the Quoter contract, and you can read them three ways:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;a plain &lt;code&gt;eth_call&lt;/code&gt; on your own RPC;&lt;/li&gt;
&lt;li&gt;the SDK: &lt;code&gt;npm i @blazephoenix/sdk&lt;/code&gt;;&lt;/li&gt;
&lt;li&gt;the MCP server at &lt;code&gt;https://blazephoenix.xyz/mcp&lt;/code&gt;, if the caller is an AI agent.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;None of them needs an API key or a signup.&lt;/p&gt;

&lt;h2&gt;
  
  
  The shape of the call
&lt;/h2&gt;

&lt;p&gt;Here is the pattern with viem. Treat the names in capitals as placeholders: the addresses and ABI for each chain come from the project docs, starting at &lt;a href="https://blazephoenix.xyz/llms.txt" rel="noopener noreferrer"&gt;llms.txt&lt;/a&gt;, or from the SDK.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;createPublicClient&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;http&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;encodeFunctionData&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;decodeFunctionResult&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;viem&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;base&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;viem/chains&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;client&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;createPublicClient&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;chain&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;base&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;transport&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nf"&gt;http&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;MY_RPC_URL&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;data&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;encodeFunctionData&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;abi&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;QUOTER_ABI&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;functionName&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;QUOTE_FUNCTION&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;args&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;QUOTE_ARGS&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="c1"&gt;// tokenIn, tokenOut, amountIn, ...&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;

&lt;span class="c1"&gt;// Pin the block so the result is reproducible.&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;data&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;raw&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;client&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;call&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;to&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;QUOTER_ADDRESS&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;blockNumber&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;BLOCK&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;quote&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;decodeFunctionResult&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;abi&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;QUOTER_ABI&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;functionName&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;QUOTE_FUNCTION&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;data&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;raw&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Three things changed compared to the REST version:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;the request went to &lt;strong&gt;your&lt;/strong&gt; node;&lt;/li&gt;
&lt;li&gt;the result is &lt;strong&gt;deterministic&lt;/strong&gt; for a given block: anyone running the same call gets the same answer;&lt;/li&gt;
&lt;li&gt;there is &lt;strong&gt;nothing to authenticate&lt;/strong&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  What the call does not solve
&lt;/h2&gt;

&lt;p&gt;A quote is still a snapshot. State can move before your swap lands. The difference here is what happens next: on BlazePhoenix the route is computed inside the transaction that executes it, and the swap reverts unless the recipient gets at least the minimum signed. Surplus from a better fill goes to the user. The protocol fee is 0.28 % per swap, a constant in the core contract.&lt;/p&gt;

&lt;p&gt;And honestly: the protocol is pre-launch. The contracts are not yet audited by an external firm; an independent external audit is scheduled. If you integrate early, integrate the way you would integrate anything unaudited.&lt;/p&gt;

&lt;h2&gt;
  
  
  Try it
&lt;/h2&gt;

&lt;p&gt;Swap one REST call for one &lt;code&gt;eth_call&lt;/code&gt; in a test branch. Start from the guide at &lt;a href="https://blazephoenix.xyz/llms.txt" rel="noopener noreferrer"&gt;blazephoenix.xyz/llms.txt&lt;/a&gt;. Then delete an API key from your secrets manager, which is a nice feeling.&lt;/p&gt;

</description>
      <category>ethereum</category>
      <category>web3</category>
      <category>solidity</category>
      <category>javascript</category>
    </item>
    <item>
      <title>One evaluator for the quote and the execution: a map of how BlazePhoenix routes swaps on chain</title>
      <dc:creator>BlazePhoenix</dc:creator>
      <pubDate>Mon, 12 Oct 2026 17:37:58 +0000</pubDate>
      <link>https://dev.to/blazephoenix_0bfac717a952/one-evaluator-for-the-quote-and-the-execution-a-map-of-how-blazephoenix-routes-swaps-on-chain-1jl2</link>
      <guid>https://dev.to/blazephoenix_0bfac717a952/one-evaluator-for-the-quote-and-the-execution-a-map-of-how-blazephoenix-routes-swaps-on-chain-1jl2</guid>
      <description>&lt;p&gt;Most DEX aggregators quote a number on a server and then ask your wallet to sign a transaction that a router contract executes later, against whatever the pools look like at that moment. The quote and the execution are two separate computations, and the difference between them is where drift comes from.&lt;/p&gt;

&lt;p&gt;BlazePhoenix is a pre-launch on-chain DEX aggregator (Base, Ethereum, Optimism, Arbitrum and Robinhood Chain) built around a different premise: the quote and the execution are one computation. The route is derived inside the transaction that executes it, from public pool state, by code anyone can re-run. This post is a short map of how that is put together. The long version, with the equations, is the canonical article linked at the end.&lt;/p&gt;

&lt;h2&gt;
  
  
  One evaluator, two frames
&lt;/h2&gt;

&lt;p&gt;The core idea (innovation I-1 in the whitepaper) is that the same dispatcher, called Omega, runs twice:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;in the planning call, as a free &lt;code&gt;eth_call&lt;/code&gt; on a view function, and&lt;/li&gt;
&lt;li&gt;again in the executing frame, against live state.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The minimum output the swap must deliver is not copied from the plan. It is re-derived inside the executing transaction from values measured in that frame. If the pools moved, the floor moves with them, and the swap reverts unless the user receives at least the minimum they signed.&lt;/p&gt;

&lt;p&gt;The article reports a study in which 64 out of 64 quotes settled at exactly their prediction. Treat that as the author's measurement, not as a promise about future trades.&lt;/p&gt;

&lt;h2&gt;
  
  
  The route is scored as a product
&lt;/h2&gt;

&lt;p&gt;Route selection is one &lt;code&gt;argmax&lt;/code&gt; (the Meta-Equation, E1 in the whitepaper):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;R* = argmax_R  net(R) · ∏ Ψ̂_ℓ · 1[net ≥ Φ] · Ξ
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Four factors are multiplied rather than added:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Factor&lt;/th&gt;
&lt;th&gt;Role&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;net(R)&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;output after fees and gas&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;Ψ̂_ℓ&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;standing of each pool on the route (depth, bridge, concentration)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;1[net ≥ Φ]&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;the floor gate&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;Ξ&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;the screen that removes hostile venues&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;The reason for a product is a property of the arithmetic: in a weighted sum a route that fails one test can still win on the strength of the others, while in a product any zero factor gives the whole route a score of zero, and the &lt;code&gt;argmax&lt;/code&gt; never selects it.&lt;/p&gt;

&lt;h2&gt;
  
  
  Two details worth reading
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Uniswap V4 handled in the same frame.&lt;/strong&gt; V4 pools have no address of their own and answer no calls. The design derives pool ids, checks each against the PoolManager storage, reads the tick book through &lt;code&gt;extsload&lt;/code&gt;, settles through the singleton, and screens hooks with a bit test on the hook address (&lt;code&gt;hookAddr &amp;amp; 0x3FFF &amp;amp; 0b1100 != 0&lt;/code&gt; means refuse).&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;A floor computed on chain.&lt;/strong&gt; The minimum output is derived from measured price impact and route concentration. The article gives the form &lt;code&gt;floorBps = max(9,600 - shave - impact - sigma, 8,000)&lt;/code&gt; and states that, for a trade of about 1% of pool depth, it caps a sandwich at roughly 2.7% of the trade and refuses beyond that, where the attacker's round trip turns negative. Caller data cannot loosen it.&lt;/p&gt;

&lt;h2&gt;
  
  
  What this is for
&lt;/h2&gt;

&lt;p&gt;The eighteen mechanisms are described as removing parties you would otherwise have to rely on: the quoting server, the factory as an address oracle, the route as the source of its own protection, and the admin key (a one-way &lt;code&gt;renounceControl&lt;/code&gt; that is written true once and never false). What is left is arithmetic that a reader can re-run on their own RPC.&lt;/p&gt;

&lt;p&gt;Quotes are readable without an API key or signup, through the SDK (&lt;code&gt;npm i @blazephoenix/sdk&lt;/code&gt;), through an MCP server for AI agents (&lt;a href="https://blazephoenix.xyz/mcp" rel="noopener noreferrer"&gt;https://blazephoenix.xyz/mcp&lt;/a&gt;), or through a plain &lt;code&gt;eth_call&lt;/code&gt;. The protocol fee is 0.28% per swap, a constant in the contract (&lt;code&gt;PROTOCOL_FEE_BPS = 28&lt;/code&gt;) with no setter.&lt;/p&gt;

&lt;h2&gt;
  
  
  Status
&lt;/h2&gt;

&lt;p&gt;BlazePhoenix is pre-launch. It is not yet audited by an external firm; an independent external audit is scheduled. Read the article and the whitepaper critically and check the claims you care about.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Canonical article, with all eighteen mechanisms and their equations: &lt;a href="https://blazephoenix.xyz/learn/the-eighteen-innovations/" rel="noopener noreferrer"&gt;https://blazephoenix.xyz/learn/the-eighteen-innovations/&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Whitepaper (DOI 10.5281/zenodo.23084091): &lt;a href="https://blazephoenix.xyz/docs/BlazePhoenix_Whitepaper.pdf" rel="noopener noreferrer"&gt;https://blazephoenix.xyz/docs/BlazePhoenix_Whitepaper.pdf&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Guide for models and agents: &lt;a href="https://blazephoenix.xyz/llms.txt" rel="noopener noreferrer"&gt;https://blazephoenix.xyz/llms.txt&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>defi</category>
      <category>ethereum</category>
      <category>solidity</category>
      <category>web3</category>
    </item>
  </channel>
</rss>
