blog.logrocket.com Open in urlscan Pro
2606:4700:10::6816:494  Public Scan

URL: https://blog.logrocket.com/how-to-market-make-transact-hashflow
Submission: On December 20 via api from US — Scanned from DE

Form analysis 4 forms found in the DOM

<form id="commentform" class="comment-form">
  <iframe title="Comment Form"
    src="https://jetpack.wordpress.com/jetpack-comment/?blogid=217016018&amp;postid=126272&amp;comment_registration=0&amp;require_name_email=1&amp;stc_enabled=1&amp;stb_enabled=1&amp;show_avatars=1&amp;avatar_default=mystery&amp;greeting=Leave+a+Reply&amp;jetpack_comments_nonce=7510150a09&amp;greeting_reply=Leave+a+Reply+to+%25s&amp;color_scheme=light&amp;lang=en_US&amp;jetpack_version=14.0&amp;iframe_unique_id=1&amp;show_cookie_consent=10&amp;has_cookie_consent=0&amp;is_current_user_subscribed=0&amp;token_key=%3Bnormal%3B&amp;sig=2f55815097ba14884686cec49f1390f1ca87081b#parent=https%3A%2F%2Fblog.logrocket.com%2Fhow-to-market-make-transact-hashflow"
    name="jetpack_remote_comment" style="width: 100%; height: 2px; border: 0px;" class="jetpack_remote_comment" id="jetpack_remote_comment" sandbox="allow-same-origin allow-top-navigation allow-scripts allow-forms allow-popups" scrolling="no">
  </iframe>
  <!--[if !IE]><!-->
  <script>
    document.addEventListener('DOMContentLoaded', function() {
      var commentForms = document.getElementsByClassName('jetpack_remote_comment');
      for (var i = 0; i < commentForms.length; i++) {
        commentForms[i].allowTransparency = false;
        commentForms[i].scrolling = 'no';
      }
    });
  </script>
  <!--<![endif]-->
</form>

<form id="jp-carousel-comment-form">
  <label for="jp-carousel-comment-form-comment-field" class="screen-reader-text">Write a Comment...</label>
  <textarea name="comment" class="jp-carousel-comment-form-field jp-carousel-comment-form-textarea" id="jp-carousel-comment-form-comment-field" placeholder="Write a Comment..."></textarea>
  <div id="jp-carousel-comment-form-submit-and-info-wrapper">
    <div id="jp-carousel-comment-form-commenting-as">
      <fieldset>
        <label for="jp-carousel-comment-form-email-field">Email (Required)</label>
        <input type="text" name="email" class="jp-carousel-comment-form-field jp-carousel-comment-form-text-field" id="jp-carousel-comment-form-email-field">
      </fieldset>
      <fieldset>
        <label for="jp-carousel-comment-form-author-field">Name (Required)</label>
        <input type="text" name="author" class="jp-carousel-comment-form-field jp-carousel-comment-form-text-field" id="jp-carousel-comment-form-author-field">
      </fieldset>
      <fieldset>
        <label for="jp-carousel-comment-form-url-field">Website</label>
        <input type="text" name="url" class="jp-carousel-comment-form-field jp-carousel-comment-form-text-field" id="jp-carousel-comment-form-url-field">
      </fieldset>
    </div>
    <input type="submit" name="submit" class="jp-carousel-comment-form-button" id="jp-carousel-comment-form-button-submit" value="Post Comment">
  </div>
</form>

<form id="mktoForm_1107" style="display: none; font-family: Helvetica, Arial, sans-serif; font-size: 13px; color: rgb(51, 51, 51); width: 1px;" novalidate="novalidate" class="mktoForm mktoHasWidth mktoLayoutLeft">
  <style type="text/css">
    .mktoForm .mktoButtonWrap.mktoSimple .mktoButton {
      color: #fff;
      border: 1px solid #75ae4c;
      padding: 0.4em 1em;
      font-size: 1em;
      background-color: #99c47c;
      background-image: -webkit-gradient(linear, left top, left bottom, from(#99c47c), to(#75ae4c));
      background-image: -webkit-linear-gradient(top, #99c47c, #75ae4c);
      background-image: -moz-linear-gradient(top, #99c47c, #75ae4c);
      background-image: linear-gradient(to bottom, #99c47c, #75ae4c);
    }

    .mktoForm .mktoButtonWrap.mktoSimple .mktoButton:hover {
      border: 1px solid #447f19;
    }

    .mktoForm .mktoButtonWrap.mktoSimple .mktoButton:focus {
      outline: none;
      border: 1px solid #447f19;
    }

    .mktoForm .mktoButtonWrap.mktoSimple .mktoButton:active {
      background-color: #75ae4c;
      background-image: -webkit-gradient(linear, left top, left bottom, from(#75ae4c), to(#99c47c));
      background-image: -webkit-linear-gradient(top, #75ae4c, #99c47c);
      background-image: -moz-linear-gradient(top, #75ae4c, #99c47c);
      background-image: linear-gradient(to bottom, #75ae4c, #99c47c);
    }
  </style>
  <div class="mktoFormRow">
    <div class="mktoFieldDescriptor mktoFormCol" style="margin-bottom: 10px;">
      <div class="mktoOffset" style="width: 10px;"></div>
      <div class="mktoFieldWrap"><label for="FirstName" id="LblFirstName" class="mktoLabel mktoHasWidth" style="width: 100px;">
          <div class="mktoAsterix">*</div>First Name:
        </label>
        <div class="mktoGutter mktoHasWidth" style="width: 10px;"></div><input id="FirstName" name="FirstName" maxlength="255" aria-labelledby="LblFirstName InstructFirstName" type="text" class="mktoField mktoTextField mktoHasWidth"
          style="width: 150px;"><span id="InstructFirstName" tabindex="-1" class="mktoInstruction"></span>
        <div class="mktoClear"></div>
      </div>
      <div class="mktoClear"></div>
    </div>
    <div class="mktoClear"></div>
  </div>
  <div class="mktoFormRow">
    <div class="mktoFieldDescriptor mktoFormCol" style="margin-bottom: 10px;">
      <div class="mktoOffset" style="width: 10px;"></div>
      <div class="mktoFieldWrap"><label for="LastName" id="LblLastName" class="mktoLabel mktoHasWidth" style="width: 100px;">
          <div class="mktoAsterix">*</div>Last Name:
        </label>
        <div class="mktoGutter mktoHasWidth" style="width: 10px;"></div><input id="LastName" name="LastName" maxlength="255" aria-labelledby="LblLastName InstructLastName" type="text" class="mktoField mktoTextField mktoHasWidth"
          style="width: 150px;"><span id="InstructLastName" tabindex="-1" class="mktoInstruction"></span>
        <div class="mktoClear"></div>
      </div>
      <div class="mktoClear"></div>
    </div>
    <div class="mktoClear"></div>
  </div>
  <div class="mktoFormRow">
    <div class="mktoFieldDescriptor mktoFormCol" style="margin-bottom: 10px;">
      <div class="mktoOffset" style="width: 10px;"></div>
      <div class="mktoFieldWrap"><label for="Email" id="LblEmail" class="mktoLabel mktoHasWidth" style="width: 100px;">
          <div class="mktoAsterix">*</div>Email Address:
        </label>
        <div class="mktoGutter mktoHasWidth" style="width: 10px;"></div><input id="Email" name="Email" maxlength="255" aria-labelledby="LblEmail InstructEmail" type="email" class="mktoField mktoEmailField mktoHasWidth" style="width: 150px;"><span
          id="InstructEmail" tabindex="-1" class="mktoInstruction"></span>
        <div class="mktoClear"></div>
      </div>
      <div class="mktoClear"></div>
    </div>
    <div class="mktoClear"></div>
  </div>
  <div class="mktoButtonRow"><span class="mktoButtonWrap mktoSimple" style="margin-left: 120px;"><button type="submit" class="mktoButton">Submit</button></span></div><input type="hidden" name="formid" class="mktoField mktoFieldDescriptor"
    value="1107"><input type="hidden" name="munchkinId" class="mktoField mktoFieldDescriptor" value="740-LKM-263">
</form>

<form style="display: none; font-family: Helvetica, Arial, sans-serif; font-size: 13px; color: rgb(51, 51, 51); visibility: hidden; position: absolute; top: -500px; left: -1000px; width: 1600px;" novalidate="novalidate"
  class="mktoForm mktoHasWidth mktoLayoutLeft"></form>

Text Content

ADVISORY BOARDS AREN’T ONLY FOR EXECUTIVES. JOIN THE LOGROCKET CONTENT ADVISORY
BOARD TODAY →

 * Blog
   * Dev
   * Product Management
   * UX Design
   * Podcast
 * Features
 * Solutions
   * Solve User-Reported Issues
   * Find Issues Faster
   * Optimize Conversion and Adoption

 * Start Monitoring for Free
 * Sign In

2022-07-29
1924
#web3
Victor Jonah
126272

Jul 29, 2022 ⋅ 6 min read


HOW TO MARKET MAKE AND TRANSACT WITH HASHFLOW

Victor Jonah I am a Software Developer with over three years of experience
working with JavaScript and its frameworks. I currently work as a remote
software developer for a tech agency.
Table of contents
 * What is Hashflow and what is its goal?
 * How Hashflow works
 * Hashflow tokens
 * How to market make
 * Connect to WebSocket
 * Create a Pool
 * Receive RFQ and respond with a quote
 * Support signing quotes
 * Get the first signed RFQ
 * Conclusion

Introducing Galileo AI
LogRocket’s Galileo AI watches every session, surfacing impactful user struggle
and key behavior patterns.
READ THE
BLOG POST


SEE HOW LOGROCKET'S AI-POWERED ERROR TRACKING WORKS


NO SIGNUP REQUIRED

Check it out
close this ✕


There has been a rise in the amount of DeFi traders in recent years which has
resulted in more decentralized exchanges (DEXs) being brought to the market as
well.

Web3 is increasing its impact on major industries, and the trading industry is
no exception. We had seen the deficiencies in centralized exchanges like a lack
of transparency, insecurity, financial exclusiveness, and privacy, and this has
provided the need for DEXs.

DEX is a way of exchanging cryptocurrencies without any intermediary like
brokers or third parties. They follow a different approach from centralized
exchanges by relying on smart contracts to handle transactions peer-to-peer.

The business model focuses on privacy for its users where transactions are
carried out anonymously, even though the transaction details are stored on the
blockchain.

We have a lot of DEX platforms on the market, like Coinbase and Binance, but in
this article, we will focus on Hashflow.

We will look at how traders are connected with pinpoints via a Hashflow token,
how it works differently from others, how to market make, and how to trade.

 * What is Hashflow and what is its goal?
 * How Hashflow works
 * Hashflow tokens
 * How to market make
 * Connect to WebSocket
 * Create a Pool
 * Receive RFQ and respond with quote
 * Support signing quotes
 * Get the first signed RFQ


WHAT IS HASHFLOW AND WHAT IS ITS GOAL?

First of all, Hashflow is known for its bridge-less cross-chain swaps, which
means it is highly interoperable, has zero slippage, and has no MEV.

This is possible because Hashflow ensures market makers sign the price quotes so
it remains unchanged during the trade.

Liquidity providers and traders are connected with professional market makers on
Hashflow and its core features offer better flexibility for its market makers —
no slippage, MEV-resistant, better price quotes, and a cheaper trading fee are
all advantages of it.

All the above mentioned are only possible because of the architecture Hashflow
uses, which is the Pool-based architecture.


HOW HASHFLOW WORKS

Starting with a transaction, the user has to connect his wallet to Hashflow,
input a number they would like to trade, and then a quote is displayed to them.

--------------------------------------------------------------------------------


OVER 200K DEVELOPERS USE LOGROCKET TO CREATE BETTER DIGITAL EXPERIENCES

Learn more →

--------------------------------------------------------------------------------

If the user accepts, the order is submitted and that transaction is verified and
added to the Hashflow network (or blockchain). On the other end, there are maker
markets that deal with the issuing of price quotes that the user had already
accepted.

The market maker then signs the trade and it is executed without slippage
(whatever order was submitted by the user stands). Unlike other DEXs, which do
usually have AMMs (Automated Market Maker) that handles market making and assets
pricing on-chain using Lazy Liquidity Provision, Hashflow goes traditionally
just like the order-book mechanism.

The pricing is done off-chain but the trade is executed on-chain.

Hashflow was in 2021 and has grown significantly, offering the best prices
because of its optimized gas fee and zero slippage. As of the time of this
article being published, Hashflow currently supports bridge-less cross-chain
swaps which makes you initiate a swap on EVM-compatible chains, and it is
expected to include Solana integration, smart order Routing, gasless trading,
limit orders, and Hashverse in future.

In summary, Hashflow is a DeFi protocol that serves as a decentralized exchange
running on the Ethereum blockchain.


HASHFLOW TOKENS

Hashflow provides its token called the HFT (Hashflow token), which is an ERC-20
on the Ethereum chain deployed on December 22, 2021. With one billion units of
HFT in supply, Hashflow distributed this cryptocurrency in this manner: 19% to
the core team; 25% to the early investors; and 56% to the ecosystem. A further
6.75% will be given to early users as a reward.



The Hashflow NFT, which is also called the Hashbots, will be used in the
Hashverse that will be released in the future. NFT holders will receive HFT that
tallies to the value of the NFT, because each NFT will have an HFT value. And
Hashflow states that after four years, 5% of HFT will be issued to the
community.


HOW TO MARKET MAKE

Market markers are essentially important in Hashflow and in the market as a
whole. They are the liquidity providers that make the market functional by
buying and selling assets. This doesn’t mean that they can buy and sell at any
time right away, but they are always on standby, ready to buy and sell.

In most decentralized exchanges, the market makers are automatic and smart
contracts are deployed to find market pairs in AMMs (Automatic Market Makers)
but they are prone to attacks and also a bit laggy because the price quotes are
handled on-chain.

--------------------------------------------------------------------------------


MORE GREAT ARTICLES FROM LOGROCKET:

 * Don't miss a moment with The Replay, a curated newsletter from LogRocket
 * Learn how LogRocket's Galileo cuts through the noise to proactively resolve
   issues in your app
 * Use React's useEffect to optimize your application's performance
 * Switch between multiple versions of Node
 * Discover how to use the React children prop with TypeScript
 * Explore creating a custom mouse cursor with CSS
 * Advisory boards aren’t just for executives. Join LogRocket’s Content Advisory
   Board. You’ll help inform the type of content we create and get access to
   exclusive meetups, social accreditation, and swag.

--------------------------------------------------------------------------------

In Hashflow, the market makers are firms, institutions, or individuals that are
given the privilege to make these market decisions using their professionalism,
and this is done off-chain, which in turn reduces gas fees and slippage, as
mentioned earlier.

To market make on Hashflow, we will follow the steps below. Integrating with
Hashflow as a market maker is quite simple.


CONNECT TO WEBSOCKET

You will need to connect to the WebSocket from Hashflow API just as you see on
line 10 below, and you may need to contact the team on Telegram or Discord to be
added to the “allowlist” makers.

const PING_PONG_INTERVAL_MS = 30000;
const PING_PONG_GRACE_PERIOD_MS = 1000;

function getWebsocketConnection(
  marketMakerName,
  onMessageCallBack,
  onCloseCallback,
  onHeartbeatCallback,
) {
  const ws = new WebSocket(`${process.env.HASHFLOW_WS_API}/maker/v1`, {
    headers: { marketmaker: marketMakerName, }
  });
  const heartbeat = () => {
    if (ws.pingTimeout) {
      clearTimeout(ws.pingTimeout);
    }
    ws.pingTimeout = setTimeout(() => {
      ws.terminate();
    }, PING_PONG_INTERVAL_MS + PING_PONG_GRACE_PERIOD_MS);

    onHeartbeatCallback();
  }
  ws.on('open', heartbeat);
  ws.on('ping', heartbeat);
  ws.on('message', message => onMessageCallBack(message));

  ws.on('close', () => {
    if (ws.pingTimeout) {
      clearTimeout(ws.pingTimeout);
    }
    setTimeout(() => {
      ws.removeAllListeners();
      onCloseCallback();
    }, 5000);
  });

  ws.on('error', err => {});

  ws.on('unexpected-response', (_, res) => {
    let message = '';
    res.on('data', (chunk) => {
      message += chunk;
    });
    res.on('end', () => {
      if (res.statusCode === 401) {
        logger.error(`WS access not authorized. ${message}`);
      } else {
        logger.error(`Unexpexted response from server: [${res.statusCode}] ${message}.`);
      }
      ws.close()
    });
  });
  return ws;
}

And Hashflow is connected to you, as seen in the following:

// TODO: Replace this with your market maker name (once added to the backend)
const MARKET_MAKER_NAME = 'TestMM';
// TODO: Set true if you want to MM on 1inch, etc – and have signed legal agreements
const SUPPORT_AGGREGATORS = false;
const levelsInterval = SUPPORT_AGGREGATORS 
  ? setInterval(() => publishPriceLevels(mainSocket), 1000)
  : undefined;
const onMessageCallback = message => processMessage(mainSocket, message);
const onHeartbeatCallback = () => {
  for (const networkId of Object.keys(SUPPORTED_PAIRS)) {
    sendMessage(mainSocket, 'subscribeToTrades', { networkId, pool: POOL });
  }
};
const onCloseCallback = () => {
  if (SUPPORT_AGGREGATORS) {
    clearInterval(levelsInterval);
  }
  mainSocket = connectToHashflow();
};

const connectToHashflow = () => {
  return getWebsocketConnection(
    MARKET_MAKER_NAME,
    onMessageCallback,
    onCloseCallback,
    onHeartbeatCallback,
  );
}
let mainSocket = connectToHashflow();

The ‘TestMM’ is replaced with yours after contacting the team. You should also
refer to this sample codebase to see how to connect to the WebSocket from
Hashflow.


CREATE A POOL

You will need to connect to your wallet after connecting to the WebServer to
create a Pool that will offer quotes.

To do this, head over using this link and fill in your Pool name, signer
address, and finally identify if you want your Pool to be public or private.
After completing the process, you should get a page like this:




RECEIVE RFQ AND RESPOND WITH A QUOTE

Now to the interesting part; Hashflow receives a request-for-quote from a user
when they want to trade to our server which then supplies the data to the
specified market maker:

{
  "messageType": "rfq",
  "message": {
    // This is a unique RFQ ID -- you need to use this when sending back a quote.
    "rfqId": string,

    // This will be something like: hashflow, 1inch. This is useful
    // since 1inch charge fees for their trades
    "source": string,

    // 1 for ETH L1
    "networkId": number,

    // Base token (the token the trader sells).
    "baseToken": string,  // contract address
    "baseTokenName": string,  // token name (e.g. USDC, ETH, ...)
    "baseTokenNumDecimals": number,  // token decimals (e.g. DAI: 18, USDC: 6)

    // Quote token (the token the trader buys).
    "quoteToken": string,  // contract address
    "quoteTokenName": string,  // token name (e.g. USDC, ETH, ...)
    "quoteTokenNumDecimals": number,  // token decimals (e.g. DAI: 18, USDC: 6)


    // Exactly one of the following fields will be present in the RFQ.
    // If baseTokenAmount is present, quoteTokenAmount needs to be filled by the quote.
    // If quoteTokenAmount is present, baseTokenAmount needs to be filled by the quore.
    // Amounts are in decimals, e.g. "1000000" for 1 USDT.
    "baseTokenAmount": ?string,
    "quoteTokenAmount": ?string,

    // The trader wallet address that will swap with the contract. This can be a proxy
    // contract (e.g. 1inch)
    "trader": string,

    // The wallet address of the actual trader (e.g. end user wallet for 1inch).
    // This is helpful in order to understand user behavior.
    // If effectiveTrader is not present, you can assume that trader == effectiveTrader.
    "effectiveTrader": ?string,
  }
}

And based on your implemented logic in your codebase, a quote is returned to the
user in this format as well:

{
  "messageType": "quote",
  "message": {
    "rfqId": string,  // This should be the same rfqId that was sent by the server
    "pool": string,  // This should be the contract address of the pool.

    // This is optional. If using an EOA (externally owned account), this should 
    // contain the wallet address of the EOA. 
    // The EOA needs to have allowance set to the Pool.
    "eoa": ?string,

    // Same as RFQ
    "baseToken": string,
    "quoteToken": string,

    // Amounts are in decimals.
    "baseTokenAmount": string,
    "quoteTokenAmount": string,

    // Set this to "0" for private pool / EOA trading.
    "fees": string,

    // The unix timestamp when the quote expires, in seconds.
    "quoteExpiry": number,
  }
}


SUPPORT SIGNING QUOTES

This only happens if the user doesn’t supply a specific market maker, and in
that context, Hashflow will make a request for a quote from all market makers
and picks the best one.

When the best quote is picked, we send a signQuote message type back to the
market maker for them to sign (get a signature from them). The request is also
in this format:

  "messageType": "signQuote",
  "message": {
    // The RFQ ID that generated the quote.
    "rfqId": string,
    "networkId": number,  // The chain ID (e.g. 1 for Ethereum mainnet)
    "quoteData": {
      "txid": string,  // Unique identifier of the quote -- different from the RFQ ID.

      "pool": string,
      "eoa": string,

      "baseToken": string,
      "quoteToken": string,

      "baseTokenAmount": string,
      "quoteTokenAmount": string,

      "fees": string,

      "quoteExpiry": number,

      // The account that will be executing the swap. For 1inch, this is the 1inch proxy.
      "trader": string,
      // Trader actually executing the swap, if different from 'trader'.
      "effectiveTrader": ?string,

      // The following parameter is internal to hashflow contracts.
      // It is leveraged to mitigate quote replay.
      "nonce": number
    }
  }
}


GET THE FIRST SIGNED RFQ

You can test your WebServer to see if you get a signed RFQ from it by making a
request to Hashflow’s staging API with the following body params as a sample:

POST https://api-staging.hashflow.com/taker/v1/quote/signedRfq


{
    "networkId": 42,  // 42 is Kovan, 1 is Mainnet
    "source": "hashflow", 
    "baseToken": "0x07de306ff27a2b630b1141956844eb1552b956b5",  // USDT (Kovan)
    "quoteToken": "0xa0a5ad2296b38bd3e3eb59aaeaf1589e8d9a29a9",  // WBTC (Kovan)
    "trader": "0x2150DD462B496bd5e4A37b5411c13319427BE83E",
    "baseTokenAmount": "1000000",
    "marketMaker": "TestMM"  // don't forget to change this
}

Once you get a response, then your market maker is set. You should also refer to
the documentation for more edge cases.


CONCLUSION

In this article, we focused on demystifying the connection between Hashflow, its
users, and market makers and the key aspects of Hashflow — namely, that it
offers bridgeless cross-chain swaps and off-chain market decisions; i.e., quotes
are done without automated makers.

Hashflow is bringing the multichain world closer to us just as Vitalik of
Ethereum had speculated. We are hoping to get more Hashflow support for other
chains as this is currently under mass adoption. To also view its metric, head
over to this dashboard.


JOIN ORGANIZATIONS LIKE BITSO AND COINSQUARE WHO USE LOGROCKET TO PROACTIVELY
MONITOR THEIR WEB3 APPS

Client-side issues that impact users’ ability to activate and transact in your
apps can drastically affect your bottom line. If you’re interested in monitoring
UX issues, automatically surfacing JavaScript errors, and tracking slow network
requests and component load time, try LogRocket.https://logrocket.com/signup/

LogRocket is like a DVR for web and mobile apps, recording everything that
happens in your web app or site. Instead of guessing why problems happen, you
can aggregate and report on key frontend performance metrics, replay user
sessions along with application state, log network requests, and automatically
surface all errors.

Modernize how you debug web and mobile apps — Start monitoring for free.


SHARE THIS:

 * Click to share on Twitter (Opens in new window)
 * Click to share on Reddit (Opens in new window)
 * Click to share on LinkedIn (Opens in new window)
 * Click to share on Facebook (Opens in new window)
 * 

 * #web3

Hey there, want to help make our blog better?

Yea No Thanks

Join LogRocket’s Content Advisory Board. You’ll help inform the type of content
we create and get access to exclusive meetups, social accreditation, and swag.

Sign up now


STOP GUESSING ABOUT YOUR DIGITAL EXPERIENCE WITH LOGROCKET

Get started for free

RECENT POSTS:

WORKING WITH URLS IN JAVASCRIPT

Break down the parts of a URL and explore APIs for working with them in
JavaScript, parsing them, building query strings, checking their validity, etc.

Joe Attardi
Dec 19, 2024 ⋅ 6 min read

LAZY LOADING VS. EAGER LOADING

In this guide, explore lazy loading and error loading as two techniques for
fetching data in React apps.

Njong Emy
Dec 18, 2024 ⋅ 5 min read

HOW TO MIGRATE YOUR NODE.JS APP TO DENO 2.0

Deno is a popular JavaScript runtime, and it recently launched version 2.0 with
several new features, bug fixes, and improvements […]

Yashodhan Joshi
Dec 17, 2024 ⋅ 7 min read

GENERATING OPENAPI API CLIENTS FOR ANGULAR

Generate OpenAPI API clients in Angular to speed up frontend development, reduce
errors, and ensure consistency with this hands-on guide.

Shalitha Suranga
Dec 16, 2024 ⋅ 9 min read
View all posts


LEAVE A REPLYCANCEL REPLY



 

Loading Comments...

 

Write a Comment...
Email (Required) Name (Required) Website

*
First Name:




*
Last Name:




*
Email Address:




Submit