From da585dd28eb05fa1fef6f3f1e2fafffff0b37973 Mon Sep 17 00:00:00 2001 From: Doug Richar Date: Wed, 14 Jan 2026 15:32:48 -0500 Subject: [PATCH 1/2] fix(docs): revert documentation links to deflex-api and complete rebranding cleanup The Haystack Router documentation on Gitbook is not yet available, so external documentation links have been reverted to point to the existing deflex-api docs until the new documentation is published. Documentation link fixes: - Revert all gitbook links from haystack-router-api to deflex-api - Add note indicating Haystack Router documentation is coming soon - Fix bundlejs badge link that still referenced @txnlab/deflex Rebranding cleanup: - Update anchor links from #deflexclient* to #routerclient* - Update source code comments (composer.ts, middleware.ts) - Rename test variables from *Deflex* to *Swap* naming - Update MIDDLEWARE.md examples and keywords - Add migration note to .claude/CLAUDE.md --- .claude/CLAUDE.md | 2 ++ README.md | 4 +-- examples/README.md | 2 +- examples/node-cli/src/index.ts | 2 +- packages/haystack/MIDDLEWARE.md | 6 ++-- packages/haystack/README.md | 20 +++++------ packages/haystack/src/composer.ts | 6 ++-- packages/haystack/src/middleware.ts | 2 +- packages/haystack/tests/composer.test.ts | 44 ++++++++++++------------ 9 files changed, 45 insertions(+), 43 deletions(-) diff --git a/.claude/CLAUDE.md b/.claude/CLAUDE.md index ce32506..c55cd17 100644 --- a/.claude/CLAUDE.md +++ b/.claude/CLAUDE.md @@ -6,6 +6,8 @@ This file provides guidance to Claude Code (claude.ai/code) when working with co Haystack Router SDK is a TypeScript/JavaScript SDK for the Haystack Order Router - smart order routing and DEX aggregation on Algorand. This is a pnpm workspace monorepo containing the SDK package and example implementations. +> **Note:** This SDK was migrated from `@txnlab/deflex` (TxnLab/deflex-js) to `@txnlab/haystack-router` (TxnLab/haystack-js) as part of a rebranding effort. See [MIGRATION.md](../MIGRATION.md) for details on migrating from the old package. + ## Commands ```bash diff --git a/README.md b/README.md index bb84751..91d9b6c 100644 --- a/README.md +++ b/README.md @@ -8,7 +8,7 @@ This repository contains the Haystack Router SDK and example implementations for ### [@txnlab/haystack-router](./packages/haystack) -TypeScript/JavaScript SDK for [Haystack Order Router](https://txnlab.gitbook.io/haystack-router-api) - smart order routing and DEX aggregation on Algorand. +TypeScript/JavaScript SDK for [Haystack Order Router](https://txnlab.gitbook.io/deflex-api) - smart order routing and DEX aggregation on Algorand. - **Documentation**: [packages/haystack/README.md](./packages/haystack/README.md) - **npm**: [@txnlab/haystack-router](https://www.npmjs.com/package/@txnlab/haystack-router) @@ -160,7 +160,7 @@ Root-level scripts: - **SDK Documentation**: [packages/haystack/README.md](./packages/haystack/README.md) - **Examples Guide**: [examples/README.md](./examples/README.md) -- **Haystack Router API Docs**: [https://txnlab.gitbook.io/haystack-router-api](https://txnlab.gitbook.io/haystack-router-api) +- **API Docs**: [https://txnlab.gitbook.io/deflex-api](https://txnlab.gitbook.io/deflex-api) _(Haystack Router documentation coming soon)_ ## Contributing diff --git a/examples/README.md b/examples/README.md index eebf765..d02361b 100644 --- a/examples/README.md +++ b/examples/README.md @@ -124,4 +124,4 @@ The monorepo structure enables a smooth development workflow: - [GitHub Issues](https://github.com/TxnLab/haystack-js/issues) - [Discord](https://discord.gg/Ek3dNyzG) -- [Documentation](https://txnlab.gitbook.io/haystack-router-api) +- [Documentation](https://txnlab.gitbook.io/deflex-api) diff --git a/examples/node-cli/src/index.ts b/examples/node-cli/src/index.ts index a7e9062..3c1e5c4 100644 --- a/examples/node-cli/src/index.ts +++ b/examples/node-cli/src/index.ts @@ -90,7 +90,7 @@ async function executeSwap() { ) console.log(` Slippage: ${config.slippage}%\n`) - // Initialize Deflex client + // Initialize Haystack Router client const router = new RouterClient({ apiKey: config.apiKey, autoOptIn: true, diff --git a/packages/haystack/MIDDLEWARE.md b/packages/haystack/MIDDLEWARE.md index 05afa2a..40ca6a0 100644 --- a/packages/haystack/MIDDLEWARE.md +++ b/packages/haystack/MIDDLEWARE.md @@ -336,7 +336,7 @@ async beforeSwap(context: SwapContext): Promise { "default": "./dist/index.js" } }, - "keywords": ["deflex", "algorand", "dex", "middleware"], + "keywords": ["haystack-router", "algorand", "dex", "middleware"], "peerDependencies": { "@txnlab/haystack-router": "^1.2.0", "algosdk": "^3.0.0" @@ -351,7 +351,7 @@ Include clear usage instructions: ````markdown # CustomAsset Haystack Router Middleware -Middleware for swapping CustomAsset tokens via Deflex. +Middleware for swapping CustomAsset tokens via Haystack Router. ## Installation @@ -392,7 +392,7 @@ If your middleware adds ANY transactions via `beforeSwap()` or `afterSwap()`, yo **Why this is critical:** - Algorand has a hard limit of 16 transactions per atomic group - Haystack Router API will optimize routes to use as many transactions as the `maxGroupSize` allows -- If Deflex returns a 16-transaction route and you try to add more, the transaction will **fail** +- If Haystack Router returns a 16-transaction route and you try to add more, the transaction will **fail** **Example:** ```typescript diff --git a/packages/haystack/README.md b/packages/haystack/README.md index 047f4cc..d820d45 100644 --- a/packages/haystack/README.md +++ b/packages/haystack/README.md @@ -1,12 +1,12 @@ # Haystack Router SDK [![npm version](https://img.shields.io/npm/v/@txnlab/haystack-router.svg)](https://www.npmjs.com/package/@txnlab/haystack-router) -[![bundle size](https://deno.bundlejs.com/badge?q=@txnlab/haystack-router@latest&treeshake=[*])](https://bundlejs.com/?q=%40txnlab%2Fdeflex%40latest&treeshake=%5B*%5D) +[![bundle size](https://deno.bundlejs.com/badge?q=@txnlab/haystack-router@latest&treeshake=[*])](https://bundlejs.com/?q=%40txnlab%2Fhaystack-router%40latest&treeshake=%5B*%5D) [![CI](https://github.com/TxnLab/haystack-js/actions/workflows/ci.yml/badge.svg)](https://github.com/TxnLab/haystack-js/actions/workflows/ci.yml) [![License: MIT](https://img.shields.io/badge/License-MIT-blue.svg)](https://opensource.org/licenses/MIT) [![TypeScript](https://img.shields.io/badge/TypeScript-5.9-blue.svg)](https://www.typescriptlang.org/) -TypeScript/JavaScript SDK for [Haystack Order Router](https://txnlab.gitbook.io/haystack-router-api) - smart order routing and DEX aggregation on Algorand. +TypeScript/JavaScript SDK for [Haystack Order Router](https://txnlab.gitbook.io/deflex-api) - smart order routing and DEX aggregation on Algorand. ## Prerequisites @@ -83,11 +83,11 @@ const router = new RouterClient({ }) ``` -By providing your Algorand address as the `referrerAddress` when initializing the client, you can earn 25% of the swap fees generated through your integration. Set the `feeBps` parameter to specify the total fee charged to users (default: 0.15%, max: 3.00%). Learn more about the [Haystack Router Referral Program](https://txnlab.gitbook.io/haystack-router-api/referral-treasury/referral-program). +By providing your Algorand address as the `referrerAddress` when initializing the client, you can earn 25% of the swap fees generated through your integration. Set the `feeBps` parameter to specify the total fee charged to users (default: 0.15%, max: 3.00%). Learn more about the [Haystack Router Referral Program](https://txnlab.gitbook.io/deflex-api/referral-treasury/referral-program). ### Get a Swap Quote -The [`newQuote()`](#deflexclientnewquote) method returns a [`SwapQuote`](#deflexquote) object: +The [`newQuote()`](#routerclientnewquote) method returns a [`SwapQuote`](#swapquote) object: ```typescript // Basic quote @@ -101,7 +101,7 @@ const quote = await router.newQuote({ ### Execute a Swap -The [`newSwap()`](#deflexclientnewswap) method returns a [`SwapComposer`](#swapcomposer) instance: +The [`newSwap()`](#routerclientnewswap) method returns a [`SwapComposer`](#swapcomposer) instance: ```typescript import { useWallet } from '@txnlab/use-wallet-*' // react, vue, solid, or svelte @@ -381,11 +381,11 @@ new RouterClient(config: ConfigParams) | `autoOptIn` | Auto-detect and add required opt-in transactions | `boolean` | `false` | | `middleware` | Array of middleware for custom asset requirements | `SwapMiddleware[]` | `[]` | -> **Referral Program**: By providing a `referrerAddress`, you can earn 25% of the swap fees generated through your integration. The `feeBps` parameter sets the total fee charged (default: 0.15%). Learn more about the [Haystack Router Referral Program](https://txnlab.gitbook.io/haystack-router-api/referral-treasury/referral-program). +> **Referral Program**: By providing a `referrerAddress`, you can earn 25% of the swap fees generated through your integration. The `feeBps` parameter sets the total fee charged (default: 0.15%). Learn more about the [Haystack Router Referral Program](https://txnlab.gitbook.io/deflex-api/referral-treasury/referral-program). #### RouterClient.newQuote() -Fetch a swap quote and return a [`SwapQuote`](#deflexquote) object. +Fetch a swap quote and return a [`SwapQuote`](#swapquote) object. ```typescript async newQuote(params: FetchQuoteParams): Promise @@ -434,7 +434,7 @@ async needsAssetOptIn(address: string, assetId: bigint | number): Promise { logicSig, ) - const mockPreSignedDeflexTxn: SwapTransaction = { + const mockPreSignedSwapTxn: SwapTransaction = { data: Buffer.from( algosdk.encodeUnsignedTransaction(preSignedTxn), ).toString('base64'), @@ -981,14 +981,14 @@ describe('SwapComposer', () => { logicSigBlob: false, } - const mockUserDeflexTxn: SwapTransaction = createMockSwapTxn() + const mockUserSwapTxn: SwapTransaction = createMockSwapTxn() const composer = new SwapComposer({ quote: createMockQuote() as FetchQuoteResponse, swapTxns: [ - mockUserDeflexTxn, - mockPreSignedDeflexTxn, - mockUserDeflexTxn, + mockUserSwapTxn, + mockPreSignedSwapTxn, + mockUserSwapTxn, ], algodClient: mockAlgodClient, address: validAddress, @@ -1024,7 +1024,7 @@ describe('SwapComposer', () => { logicSig, ) - const mockPreSignedDeflexTxn: SwapTransaction = { + const mockPreSignedSwapTxn: SwapTransaction = { data: Buffer.from( algosdk.encodeUnsignedTransaction(preSignedTxn), ).toString('base64'), @@ -1038,14 +1038,14 @@ describe('SwapComposer', () => { logicSigBlob: false, } - const mockUserDeflexTxn: SwapTransaction = createMockSwapTxn() + const mockUserSwapTxn: SwapTransaction = createMockSwapTxn() const composer = new SwapComposer({ quote: createMockQuote() as FetchQuoteResponse, swapTxns: [ - mockUserDeflexTxn, - mockPreSignedDeflexTxn, - mockUserDeflexTxn, + mockUserSwapTxn, + mockPreSignedSwapTxn, + mockUserSwapTxn, ], algodClient: mockAlgodClient, address: validAddress, @@ -1552,7 +1552,7 @@ describe('SwapComposer', () => { const txn = createMockTransaction(appAddress.toString()) const signedTxn = algosdk.signLogicSigTransactionObject(txn, logicSig) - const mockDeflexLsigTxn: SwapTransaction = { + const mockLsigSwapTxn: SwapTransaction = { data: Buffer.from(algosdk.encodeUnsignedTransaction(txn)).toString( 'base64', ), @@ -1568,7 +1568,7 @@ describe('SwapComposer', () => { const composer = new SwapComposer({ quote: createMockQuote() as FetchQuoteResponse, - swapTxns: [mockDeflexLsigTxn], + swapTxns: [mockLsigSwapTxn], algodClient: mockAlgodClient, address: validAddress, signer: async (txns: algosdk.Transaction[]) => @@ -1586,7 +1586,7 @@ describe('SwapComposer', () => { const account = algosdk.generateAccount() const txn = createMockTransaction(account.addr.toString()) - const mockDeflexSkTxn: SwapTransaction = { + const mockSkSwapTxn: SwapTransaction = { data: Buffer.from(algosdk.encodeUnsignedTransaction(txn)).toString( 'base64', ), @@ -1602,7 +1602,7 @@ describe('SwapComposer', () => { const composer = new SwapComposer({ quote: createMockQuote() as FetchQuoteResponse, - swapTxns: [mockDeflexSkTxn], + swapTxns: [mockSkSwapTxn], algodClient: mockAlgodClient, address: validAddress, signer: async (txns: algosdk.Transaction[]) => @@ -1661,7 +1661,7 @@ describe('SwapComposer', () => { await composer.addSwapTransactions() - // Error happens during signing when the Deflex signer is called + // Error happens during signing when the swap signer is called await expect(composer.sign()).rejects.toThrow( 'Logic signature structure missing lsig field', ) @@ -1693,7 +1693,7 @@ describe('SwapComposer', () => { await composer.addSwapTransactions() - // Error happens during signing when the Deflex signer is called + // Error happens during signing when the swap signer is called await expect(composer.sign()).rejects.toThrow( 'Unsupported signature type', ) @@ -1770,7 +1770,7 @@ describe('SwapComposer', () => { logicSig, ) - const mockPreSignedDeflexTxn: SwapTransaction = { + const mockPreSignedSwapTxn: SwapTransaction = { data: Buffer.from( algosdk.encodeUnsignedTransaction(preSignedTxn), ).toString('base64'), @@ -1784,7 +1784,7 @@ describe('SwapComposer', () => { logicSigBlob: false, } - const mockUserDeflexTxn: SwapTransaction = { + const mockUserSwapTxn: SwapTransaction = { data: Buffer.from( algosdk.encodeUnsignedTransaction(createMockTransaction()), ).toString('base64'), @@ -1797,7 +1797,7 @@ describe('SwapComposer', () => { const composer = new SwapComposer({ quote: createMockQuote() as FetchQuoteResponse, - swapTxns: [mockPreSignedDeflexTxn, mockUserDeflexTxn], + swapTxns: [mockPreSignedSwapTxn, mockUserSwapTxn], algodClient: mockAlgodClient, address: validAddress, signer: async (txns: algosdk.Transaction[]) => @@ -2023,7 +2023,7 @@ describe('SwapComposer', () => { logicSig, ) - const mockPreSignedDeflexTxn: SwapTransaction = { + const mockPreSignedSwapTxn: SwapTransaction = { data: Buffer.from( algosdk.encodeUnsignedTransaction(preSignedTxn), ).toString('base64'), @@ -2037,7 +2037,7 @@ describe('SwapComposer', () => { logicSigBlob: false, } - const mockUserDeflexTxn: SwapTransaction = { + const mockUserSwapTxn: SwapTransaction = { data: Buffer.from( algosdk.encodeUnsignedTransaction(createMockTransaction()), ).toString('base64'), @@ -2048,7 +2048,7 @@ describe('SwapComposer', () => { const composer = new SwapComposer({ quote: createMockQuote() as FetchQuoteResponse, - swapTxns: [mockPreSignedDeflexTxn, mockUserDeflexTxn], + swapTxns: [mockPreSignedSwapTxn, mockUserSwapTxn], algodClient: mockAlgodClient, address: validAddress, signer: async (txns: algosdk.Transaction[]) => From 44fd19942d3433afea1cc6711788b60d78594f74 Mon Sep 17 00:00:00 2001 From: Doug Richar Date: Wed, 14 Jan 2026 16:25:08 -0500 Subject: [PATCH 2/2] style(tests): format swapTxns arrays to single line --- packages/haystack/tests/composer.test.ts | 12 ++---------- 1 file changed, 2 insertions(+), 10 deletions(-) diff --git a/packages/haystack/tests/composer.test.ts b/packages/haystack/tests/composer.test.ts index 9e4fcac..34c8498 100644 --- a/packages/haystack/tests/composer.test.ts +++ b/packages/haystack/tests/composer.test.ts @@ -985,11 +985,7 @@ describe('SwapComposer', () => { const composer = new SwapComposer({ quote: createMockQuote() as FetchQuoteResponse, - swapTxns: [ - mockUserSwapTxn, - mockPreSignedSwapTxn, - mockUserSwapTxn, - ], + swapTxns: [mockUserSwapTxn, mockPreSignedSwapTxn, mockUserSwapTxn], algodClient: mockAlgodClient, address: validAddress, signer: async ( @@ -1042,11 +1038,7 @@ describe('SwapComposer', () => { const composer = new SwapComposer({ quote: createMockQuote() as FetchQuoteResponse, - swapTxns: [ - mockUserSwapTxn, - mockPreSignedSwapTxn, - mockUserSwapTxn, - ], + swapTxns: [mockUserSwapTxn, mockPreSignedSwapTxn, mockUserSwapTxn], algodClient: mockAlgodClient, address: validAddress, signer: async (