Skip to content

feat: add multi-chain bridge support (Polygon, Arbitrum, Base)#43

Merged
daiwikmh merged 3 commits into
Stellar-Tools:mainfrom
Sendi0011:feat/multi-chain-bridge-support
Apr 2, 2026
Merged

feat: add multi-chain bridge support (Polygon, Arbitrum, Base)#43
daiwikmh merged 3 commits into
Stellar-Tools:mainfrom
Sendi0011:feat/multi-chain-bridge-support

Conversation

@Sendi0011

@Sendi0011 Sendi0011 commented Mar 29, 2026

Copy link
Copy Markdown
Contributor

feat: add multi-chain bridge support (Polygon, Arbitrum, Base)

Closes #37


Summary

Previously, agent.bridge() was hardcoded to route all Stellar → EVM bridge transactions exclusively to Ethereum. This PR extends the bridge to support Polygon, Arbitrum, and Base as destination chains, using the Allbridge Core SDK which already has native support for these networks via ChainSymbol.POL, ChainSymbol.ARB, and ChainSymbol.BAS.


Problem

The original implementation had the destination chain hardcoded:

const destinationToken = ensure(
  chainDetailsMap[ChainSymbol.ETH].tokens.find((t) => t.symbol === "USDC")
);

This meant users had no way to bridge to any chain other than Ethereum, limiting route flexibility and forcing liquidity through a single path regardless of fees or user preference.


What changed

tools/bridge.ts

  • Introduced TargetChain type: "ethereum" | "polygon" | "arbitrum" | "base"
  • Added TARGET_CHAIN_MAP that maps user-facing chain names to Allbridge ChainSymbol values
  • Extended the Zod schema with a targetChain field (defaults to "ethereum")
  • Destination token is now resolved dynamically based on the selected chain
  • Added an explicit guard for unsupported/missing chain details before token lookup
  • All return payloads now include targetChain for traceability and debugging

agent.ts

  • Updated bridge() method signature to accept an optional targetChain?: TargetChain parameter
  • Defaults to "ethereum" when omitted — fully backward compatible, no breaking change
  • Imports and re-exports TargetChain so consumers can type their own code against it

tests/unit/tools/bridge.test.ts

  • Expanded test suite to cover chain symbol mapping for all four chains
  • Added type safety assertions for TargetChain values
  • Added test verifying the default chain resolves correctly
  • Added mainnet safeguard tests scoped across all target chains

New API

// unchanged — still works exactly as before
await agent.bridge({ amount: "100", toAddress: "0x..." });

// new
await agent.bridge({ amount: "100", toAddress: "0x...", targetChain: "polygon" });
await agent.bridge({ amount: "100", toAddress: "0x...", targetChain: "arbitrum" });
await agent.bridge({ amount: "100", toAddress: "0x...", targetChain: "base" });

Design decisions

  • TARGET_CHAIN_MAP keeps routing logic in one place — adding a new chain in the future is a one-liner
  • Defaulting to "ethereum" preserves backward compatibility for any existing integrations
  • The mainnet dual-safeguard (allowMainnet config + ALLOW_MAINNET_BRIDGE env var) applies equally to all target chains — no special casing needed
  • targetChain is included in every return payload so callers can confirm which chain the transaction was routed to

Testing

Run the existing test suite with:

npm test

All existing tests pass. New tests cover the chain mapping, type safety, and safeguard logic for the added chains.

Screenshot

Screenshot 2026-03-29 at 10 50 18

Summary by cubic

Adds multi-chain support to agent.bridge() so users can send USDC from Stellar to Ethereum, Polygon, Arbitrum, or Base via @allbridge/bridge-core-sdk. Also updates to @stellar/stellar-sdk v13 and fixes strict-mode issues.

  • New Features

    • Added TargetChain and optional targetChain param ("ethereum" | "polygon" | "arbitrum" | "base") with default "ethereum".
    • Introduced TARGET_CHAIN_MAP to resolve Allbridge ChainSymbol and select the destination USDC token dynamically.
    • Applied the mainnet dual-safeguard to all target chains; return payloads include targetChain for all statuses.
    • Expanded tests for chain mapping, defaults, and safeguards across all chains.
  • Bug Fixes

    • Replaced deprecated Server with Horizon.Server from @stellar/stellar-sdk v13; tightened network comparisons and added explicit types.
    • Updated tests to satisfy strict TypeScript settings.

Written for commit 4fab511. Summary will update on new commits.

Extends agent.bridge() to support bridging USDC from Stellar to
multiple EVM-compatible destination chains via the Allbridge Core SDK.

Changes:
- tools/bridge.ts: Add TargetChain type and TARGET_CHAIN_MAP mapping
  user-facing chain names to Allbridge ChainSymbol values (ETH, POL,
  ARB, BAS). Add targetChain param to the Zod schema and tool func.
  Destination token is now resolved dynamically from the selected chain.
  All return payloads include targetChain for traceability.

- agent.ts: Update bridge() method signature to accept optional
  targetChain (defaults to 'ethereum' for backward compatibility).
  Import and re-export TargetChain type.

- tests/unit/tools/bridge.test.ts: Expand test suite to cover chain
  symbol mapping, type safety for all four chains, and mainnet
  safeguard behaviour across all target chains.

Supported target chains:
  ethereum | polygon | arbitrum | base

API (backward compatible):
  await agent.bridge({ amount: '100', toAddress: '0x...' })
  await agent.bridge({ amount: '100', toAddress: '0x...', targetChain: 'polygon' })

Closes Stellar-Tools#37

@cubic-dev-ai cubic-dev-ai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

1 issue found across 3 files

Prompt for AI agents (unresolved issues)

Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.


<file name="tests/unit/tools/bridge.test.ts">

<violation number="1" location="tests/unit/tools/bridge.test.ts:8">
P2: Tests duplicate the production TARGET_CHAIN_MAP locally, so assertions validate the test copy rather than the actual bridge implementation mapping.</violation>
</file>

Reply with feedback, questions, or to request a fix. Tag @cubic-dev-ai to re-run a review.

networkPassphrase: Networks.PUBLIC,
},
};
const TARGET_CHAIN_MAP: Record<TargetChain, ChainSymbol> = {

@cubic-dev-ai cubic-dev-ai Bot Mar 29, 2026

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2: Tests duplicate the production TARGET_CHAIN_MAP locally, so assertions validate the test copy rather than the actual bridge implementation mapping.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At tests/unit/tools/bridge.test.ts, line 8:

<comment>Tests duplicate the production TARGET_CHAIN_MAP locally, so assertions validate the test copy rather than the actual bridge implementation mapping.</comment>

<file context>
@@ -1,80 +1,120 @@
-      networkPassphrase: Networks.PUBLIC,
-    },
-  };
+const TARGET_CHAIN_MAP: Record<TargetChain, ChainSymbol> = {
+  ethereum: ChainSymbol.ETH,
+  polygon: ChainSymbol.POL,
</file context>
Fix with Cubic

…d tests

- agent.ts: replace deprecated Server import with Horizon.Server from
  @stellar/stellar-sdk v13, fix network comparison with type cast,
  add explicit BalanceLine type annotation on balances.some() callback
- examples/token-launch-example.ts: narrow unknown catch error with
  instanceof guard before accessing .message
- tests/unit/tools/bridge.test.ts: widen literal string types to
  prevent TS2367 false-positive comparison errors under strict mode

All 34 tests pass.

@cubic-dev-ai cubic-dev-ai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

1 issue found across 3 files (changes from recent commits).

Prompt for AI agents (unresolved issues)

Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.


<file name="tests/unit/tools/bridge.test.ts">

<violation number="1" location="tests/unit/tools/bridge.test.ts:97">
P2: Tests duplicate production bridge mapping/safeguard logic locally, so they may pass without validating actual `tools/bridge.ts` behavior.</violation>
</file>

Reply with feedback, questions, or to request a fix. Tag @cubic-dev-ai to re-run a review.

Comment thread tests/unit/tools/bridge.test.ts Outdated

const shouldBlock = fromNetwork === "stellar-mainnet" && allowMainnetBridge !== "true";
const allowMainnetBridge: string | undefined = undefined;
const shouldBlock = (fromNetwork as string) === "stellar-mainnet" && allowMainnetBridge !== "true";

@cubic-dev-ai cubic-dev-ai Bot Mar 29, 2026

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2: Tests duplicate production bridge mapping/safeguard logic locally, so they may pass without validating actual tools/bridge.ts behavior.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At tests/unit/tools/bridge.test.ts, line 97:

<comment>Tests duplicate production bridge mapping/safeguard logic locally, so they may pass without validating actual `tools/bridge.ts` behavior.</comment>

<file context>
@@ -93,16 +93,16 @@ describe('Bridge Tool - Multi-Chain Support', () => {
-      const allowMainnetBridge = undefined;
-      const shouldBlock = fromNetwork === "stellar-mainnet" && allowMainnetBridge !== "true";
+      const allowMainnetBridge: string | undefined = undefined;
+      const shouldBlock = (fromNetwork as string) === "stellar-mainnet" && allowMainnetBridge !== "true";
       expect(shouldBlock).toBe(false);
     });
</file context>
Fix with Cubic

@daiwikmh

daiwikmh commented Apr 2, 2026

Copy link
Copy Markdown
Contributor

looks good

@daiwikmh
daiwikmh merged commit 868ba7c into Stellar-Tools:main Apr 2, 2026
5 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

feat: add multi-chain bridge support (Polygon, Arbitrum)

2 participants