From 615d09aec79e1b260aeacd1727217dcd46cb35be Mon Sep 17 00:00:00 2001 From: Daveeee-tech Date: Fri, 16 Oct 2026 01:06:21 +0100 Subject: [PATCH] fix: correct native Stellar SAC defaults --- .env.example | 14 +++++++------- src/__tests__/multiNetworkIndexer.test.ts | 6 ++++++ src/__tests__/sacDetect.test.ts | 13 ++++++++----- src/indexer.ts | 4 ++-- src/indexer/sac-detect.ts | 4 ++-- 5 files changed, 25 insertions(+), 16 deletions(-) diff --git a/.env.example b/.env.example index 1d8ed5ef1..2f773a89d 100644 --- a/.env.example +++ b/.env.example @@ -45,8 +45,8 @@ POLL_INTERVAL_MS=6000 # ─── SAC Contract IDs ──────────────────────────────────────── # Comma-separated list of Soroban SAC (Stellar Asset Contract) IDs to watch. # When unset, defaults to the native XLM SAC for the configured STELLAR_NETWORK: -# testnet → CDMLFMKMMD7MWZP3FKUBZPVHTUEDLSX4BYGYKH4GCESXYHS3IHQ4EIG4 -# mainnet → CDLZFC3SYJYDZT7K67VZ75HPJVIEUVNIXF47ZG2FB2RMQQVU2HHGCYSC +# testnet → CDLZFC3SYJYDZT7K67VZ75HPJVIEUVNIXF47ZG2FB2RMQQVU2HHGCYSC +# mainnet → CAS3J7GYLGXMF6TDJBBYYSE3HQ6BBSMLNUQ34T6TZMYMW2EVH34XOWMA # # How to derive a SAC address for any Stellar asset: # import { Asset, Networks } from '@stellar/stellar-sdk'; @@ -57,15 +57,15 @@ POLL_INTERVAL_MS=6000 # .contractId(Networks.PUBLIC); # # Known mainnet SAC addresses: -# XLM (native): CDLZFC3SYJYDZT7K67VZ75HPJVIEUVNIXF47ZG2FB2RMQQVU2HHGCYSC -# USDC (Centre): CBIELTK6YBZJU5UP2WWQEUCYKLPU6AUNZ2BQ4WWFEIE3USCIHMXQDAMA +# XLM (native): CAS3J7GYLGXMF6TDJBBYYSE3HQ6BBSMLNUQ34T6TZMYMW2EVH34XOWMA +# USDC (Centre): CCW67TSZV3SSS2HXMBQ5JFGCKJNXKZM7UQUWUZPUTHXSTZLEO7SJMI75 # # Example (watch XLM + USDC on mainnet): -# SAC_CONTRACT_IDS=CDLZFC3SYJYDZT7K67VZ75HPJVIEUVNIXF47ZG2FB2RMQQVU2HHGCYSC,CBIELTK6YBZJU5UP2WWQEUCYKLPU6AUNZ2BQ4WWFEIE3USCIHMXQDAMA +# SAC_CONTRACT_IDS=CAS3J7GYLGXMF6TDJBBYYSE3HQ6BBSMLNUQ34T6TZMYMW2EVH34XOWMA,CCW67TSZV3SSS2HXMBQ5JFGCKJNXKZM7UQUWUZPUTHXSTZLEO7SJMI75 # # Per-network watch lists (for dual-network deployments when NETWORKS=testnet,mainnet): -# SAC_CONTRACT_IDS_TESTNET=CDMLFMKMMD7MWZP3FKUBZPVHTUEDLSX4BYGYKH4GCESXYHS3IHQ4EIG4 -# SAC_CONTRACT_IDS_MAINNET=CDLZFC3SYJYDZT7K67VZ75HPJVIEUVNIXF47ZG2FB2RMQQVU2HHGCYSC +# SAC_CONTRACT_IDS_TESTNET=CDLZFC3SYJYDZT7K67VZ75HPJVIEUVNIXF47ZG2FB2RMQQVU2HHGCYSC +# SAC_CONTRACT_IDS_MAINNET=CAS3J7GYLGXMF6TDJBBYYSE3HQ6BBSMLNUQ34T6TZMYMW2EVH34XOWMA # # Soroban RPC's getEvents accepts multiple contract IDs in a single request — # there is no N+1 query penalty for watching multiple contracts. diff --git a/src/__tests__/multiNetworkIndexer.test.ts b/src/__tests__/multiNetworkIndexer.test.ts index 289683856..5bad02bc6 100644 --- a/src/__tests__/multiNetworkIndexer.test.ts +++ b/src/__tests__/multiNetworkIndexer.test.ts @@ -17,6 +17,7 @@ import { runningNetworks, _resetIndexerLoops, } from "../indexer"; +import { Asset, Networks } from "@stellar/stellar-sdk"; import { getRpc, validateNetworkConfig, _resetRpcClients } from "../rpc"; import { currentNetwork, enabledNetworks, parseNetwork } from "../network"; @@ -82,6 +83,11 @@ describe("enabledNetworks", () => { }); describe("per-network watch lists", () => { + it("matches the Stellar SDK's native SAC derivation", () => { + expect(DEFAULT_XLM_SAC_MAINNET).toBe(Asset.native().contractId(Networks.PUBLIC)); + expect(DEFAULT_XLM_SAC_TESTNET).toBe(Asset.native().contractId(Networks.TESTNET)); + }); + it("defaults each network to its own native XLM SAC", () => { // The bug this prevents: reading STELLAR_NETWORK inside the resolver, so // both loops watch the same chain's SAC and one indexes nothing. diff --git a/src/__tests__/sacDetect.test.ts b/src/__tests__/sacDetect.test.ts index 8082d6d7f..d2c761d91 100644 --- a/src/__tests__/sacDetect.test.ts +++ b/src/__tests__/sacDetect.test.ts @@ -7,6 +7,7 @@ */ import { xdr } from "@stellar/stellar-sdk"; +import { DEFAULT_XLM_SAC_MAINNET, DEFAULT_XLM_SAC_TESTNET } from "../indexer"; import { executableIsSac, instanceValIsSac, @@ -17,9 +18,6 @@ import { type InstanceFetcher, } from "../indexer/sac-detect"; -// The native XLM SACs are hard-coded as known SACs in the module. -const TESTNET_XLM_SAC = "CDMLFMKMMD7MWZP3FKUBZPVHTUEDLSX4BYGYKH4GCESXYHS3IHQ4EIG4"; - function sacInstanceVal(): xdr.ScVal { return xdr.ScVal.scvContractInstance( new xdr.ScContractInstance({ @@ -67,9 +65,14 @@ describe("instanceValIsSac", () => { }); describe("detectSac", () => { - it("returns true for a known native XLM SAC without fetching", async () => { + it("returns true for known native XLM SACs without fetching", async () => { const fetcher = jest.fn, [string]>(); - await expect(detectSac(TESTNET_XLM_SAC, fetcher)).resolves.toBe(true); + await expect( + Promise.all([ + detectSac(DEFAULT_XLM_SAC_MAINNET, fetcher), + detectSac(DEFAULT_XLM_SAC_TESTNET, fetcher), + ]), + ).resolves.toEqual([true, true]); expect(fetcher).not.toHaveBeenCalled(); }); diff --git a/src/indexer.ts b/src/indexer.ts index 03363be74..c9e4a8597 100644 --- a/src/indexer.ts +++ b/src/indexer.ts @@ -34,9 +34,9 @@ export function resolveNftContractIds(network?: Network): string[] { // These are derived from Asset.native().contractId(Networks.PUBLIC / Networks.TESTNET) // and serve as the backwards-compatible default when SAC_CONTRACT_IDS is unset. export const DEFAULT_XLM_SAC_MAINNET = - "CDLZFC3SYJYDZT7K67VZ75HPJVIEUVNIXF47ZG2FB2RMQQVU2HHGCYSC"; + "CAS3J7GYLGXMF6TDJBBYYSE3HQ6BBSMLNUQ34T6TZMYMW2EVH34XOWMA"; export const DEFAULT_XLM_SAC_TESTNET = - "CDMLFMKMMD7MWZP3FKUBZPVHTUEDLSX4BYGYKH4GCESXYHS3IHQ4EIG4"; + "CDLZFC3SYJYDZT7K67VZ75HPJVIEUVNIXF47ZG2FB2RMQQVU2HHGCYSC"; /** * Resolve the list of SAC contract IDs to watch. diff --git a/src/indexer/sac-detect.ts b/src/indexer/sac-detect.ts index 6687e6ae3..a1a934a84 100644 --- a/src/indexer/sac-detect.ts +++ b/src/indexer/sac-detect.ts @@ -26,8 +26,8 @@ import { resolveNetwork, type Network } from "../network"; // The native XLM SAC on mainnet and testnet. These are fixed by the network and // never change, so we short-circuit detection (and any RPC call) for them. const KNOWN_SAC_IDS = new Set([ - "CDLZFC3SYJYDZT7K67VZ75HPJVIEUVNIXF47ZG2FB2RMQQVU2HHGCYSC", // mainnet native XLM - "CDMLFMKMMD7MWZP3FKUBZPVHTUEDLSX4BYGYKH4GCESXYHS3IHQ4EIG4", // testnet native XLM + "CAS3J7GYLGXMF6TDJBBYYSE3HQ6BBSMLNUQ34T6TZMYMW2EVH34XOWMA", // mainnet native XLM + "CDLZFC3SYJYDZT7K67VZ75HPJVIEUVNIXF47ZG2FB2RMQQVU2HHGCYSC", // testnet native XLM ]); // ─── Pure helpers ─────────────────────────────────────────────────────────────