Skip to content

Configurable explorer links, threshold/paste fixes, keyless mainnet RPC - #331

Merged
Valreb001 merged 6 commits into
Tx-wats:mainfrom
N-i-xx:main
Oct 19, 2026
Merged

Valreb001 merged 6 commits into
Tx-wats:mainfrom
N-i-xx:main

Conversation

@N-i-xx

@N-i-xx N-i-xx commented Oct 19, 2026

Copy link
Copy Markdown
Contributor

closes #269
closes #270
closes #271
closes #272

N-i-xx and others added 5 commits October 19, 2026 17:15
…RuleBadge

Several merges left these files unparsable, so the Add Contract page could
not build:

- app/contracts/new/page.tsx: duplicated state/hook declarations, an
  unclosed if in handleSave, two save paths, and three copies of the
  rules/test/wallet/buttons JSX. Collapse to one version; use
  validateWebhookUrl's { valid, message } result and webhookUrlMessage;
  import parseAlertRule from @/types (lib/alertRules does not exist);
  drop the call to the non-existent checkContractOnNetwork. Contract
  verification now comes only from ContractVerification (tri-state, its
  own override); the page-level boolean check and duplicate override
  checkbox are removed.
- components/RuleBuilder.tsx: leftover '=======' conflict marker.
- components/AlertRuleBadge.tsx: duplicate imports and style/label/
  description declarations; use getRuleMeta only.
- Page tests: remove duplicate imports and a truncated test, mock
  ToastProvider.

Page tests still fail on unrelated test-harness drift (vitest-axe is not
installed; the shared freighter-api mock lacks WatchWalletChanges).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Transaction and contract links were hard-coded to stellar.expert, so
teams on StellarChain, a self-hosted explorer or a private network could
not change them, and custom networks got no link at all.

Add lib/explorer.ts (which WebhookLogCard already imported but did not
exist) as the single source for explorer links, driven by
NEXT_PUBLIC_EXPLORER_URL_TEMPLATE_TX / _CONTRACT with {network} and {hash}
placeholders. Defaults to stellar.expert; invalid templates (non-http(s),
missing {hash}) fall back to it. Custom networks get a link only when a
template is configured. lib/stellar.ts re-exports the helpers.

WebhookLogCard now uses the shared helpers (fixing its swapped argument
order and inline stellar.expert URLs), hides the link when none can be
built, and imports truncateId from lib/stellar (lib/format has none).
Variables are documented in .env.example.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
RuleBuilder's hasValidPrecision counted decimals with
String(value).split('.')[1]. JavaScript prints small numbers in exponent
form (String(0.00000001) === '1e-8'), so 8-decimal thresholds passed, and
50000000000.0000001 parses to exactly the maximum, so the bound check
passed too.

Add validateThreshold to lib/formatAmount.ts: it validates the raw string
(plain decimals only, so '1e-7' is rejected with a hint), counts decimals
as typed, and checks the 50B XLM bound in integer stroops. RuleBuilder
uses it; hasValidPrecision and its duplicate MAX_XLM_* constants are
removed (the constants now live in lib/formatAmount.ts). In this tree,
validateXlmThreshold no longer existed, so there was only one copy to
delete.

Tests cover 0.00000001, 1e-7 and 50000000000.0000001, both in the
validator and through RuleBuilder.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Paste normalisation only recognised stellar.expert URLs, so links from
StellarChain, Stellar Lab or other explorers were upper-cased into an
invalid ID; any pasted text (even a sentence) was whitespace-stripped and
upper-cased, hiding what the user pasted; and a G… account or M… muxed
address only got the generic 'must start with C' error.

- URLs: extract the first checksum-valid C… contract ID anywhere in the
  URL and infer the network from stellar.expert paths, Stellar Lab's
  network$id, StellarChain subdomains (bare host = mainnet) or a
  network name in the URL. /contract(s)/<id> paths still work.
- Bare StrKeys (even split across lines) are joined and upper-cased.
- Anything else is returned untouched.
- New nonContractAddressHint(): the Add Contract page shows a specific
  hint (live and on validation) for valid account or muxed addresses.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…works

SOROBAN_RPC_URLS.mainnet pointed at Validation Cloud without a key. The
endpoint answers {"error":"invalid api key"}, so out of the box every
mainnet lookup fell back to 'unavailable'.

Switch the default to Gateway.fm's keyless public endpoint. Verified it
(and Lightsail, Ankr and sorobanrpc.com) answers getNetwork and
getLedgerEntries for the mainnet XLM contract, with CORS allowing browser
calls.

The middleware CSP also hard-coded the Validation Cloud host and allowed
only one Soroban host, so it blocked testnet/futurenet lookups and
per-network overrides (browsers enforce it alongside next.config.mjs's
policy). Both now build the allow-list from a shared networkOrigins()
helper covering every network's resolved Horizon and RPC origin.

README 'Network endpoints' documents provider choices, keyed endpoints,
the override variables, and the CORS/public-key caveats.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@drips-wave

drips-wave Bot commented Oct 19, 2026

Copy link
Copy Markdown

@N-i-xx Great news! 🎉 Based on an automated assessment of this PR, the linked Wave issue(s) no longer count against your application limits.

You can now already apply to more issues while waiting for a review of this PR. Keep up the great work! 🚀

Learn more about application limits

@Valreb001
Valreb001 merged commit 6887071 into Tx-wats:main Oct 19, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

2 participants