From d4fe489ae9f759ae637e1126c05943991c20fa5b Mon Sep 17 00:00:00 2001 From: JosueBrenes Date: Tue, 30 Jun 2026 14:52:40 -0600 Subject: [PATCH] fix(did): pin did-stellar registry + RPC per network for mainnet registration The published @acta-team/did-stellar@0.1.0 ships an empty mainnet registry default, so registering a DID on mainnet failed with 'no default registry contract is configured for network mainnet'. Pass registryContractId and rpcUrl explicitly per network (testnet did-stellar-registry v0.1.0, mainnet v0.2.0), overridable via NEXT_PUBLIC_DID_REGISTRY_CONTRACT_ID_* and NEXT_PUBLIC_STELLAR_RPC_URL_*, mirroring how the ACTA API base URL is pinned. --- .../modules/did/hooks/useDidStellar.ts | 5 ++ src/lib/didStellar.ts | 50 +++++++++++++++++++ 2 files changed, 55 insertions(+) diff --git a/src/components/modules/did/hooks/useDidStellar.ts b/src/components/modules/did/hooks/useDidStellar.ts index 4be9f74..198c254 100644 --- a/src/components/modules/did/hooks/useDidStellar.ts +++ b/src/components/modules/did/hooks/useDidStellar.ts @@ -16,6 +16,7 @@ import { import { StrKey } from '@stellar/stellar-sdk'; import { useWalletContext } from '@/providers/wallet.provider'; import { useNetwork } from '@/providers/network.provider'; +import { getDidRegistryContractId, getStellarRpcUrl } from '@/lib/didStellar'; const didClient = new ActaDidClient({ baseUrl: 'https://did.acta.build' }); @@ -79,6 +80,10 @@ export function useDidStellar() { const prepared = await prepareRegisterDidXdr({ did, sourcePublicKey: walletAddress, + // Pin the registry + RPC per network so registration never depends on + // the published SDK's built-in defaults (which may lag a deployment). + registryContractId: getDidRegistryContractId(stellarNetwork), + rpcUrl: getStellarRpcUrl(stellarNetwork), record: { controller: walletAddress, authentication: [{ publicKeyMultibase }], diff --git a/src/lib/didStellar.ts b/src/lib/didStellar.ts index 70f40b5..ff6e7ef 100644 --- a/src/lib/didStellar.ts +++ b/src/lib/didStellar.ts @@ -1,3 +1,53 @@ +type DidNetwork = 'testnet' | 'mainnet'; + +/** + * Canonical `did-stellar-registry` contract IDs per network. + * + * The SDK ships its own defaults, but the published `@acta-team/did-stellar` + * may lag behind a new deployment, so the dApp passes these explicitly to the + * prepare helpers (the same way it pins the ACTA API base URL per network). + * Keep these in sync with `contracts-acta/docs/deployments/{network}.md` and + * with the registry that `did.acta.build` resolves against for each network: + * - testnet: did-stellar-registry v0.1.0 + * - mainnet: did-stellar-registry v0.2.0 + */ +const DEFAULT_DID_REGISTRY_CONTRACT_ID: Record = { + testnet: 'CB7ATU7SF5QUKJMSULJDJVWJZVDXC23HTZX6NFUDTSFPVT6MA575NNZJ', + mainnet: 'CD6LSWW5ZSXOO5WAIHKQLQ262TW7BPI37PNEVMMA273BAPC65NN2AYXQ', +}; + +const DEFAULT_STELLAR_RPC_URL: Record = { + testnet: 'https://soroban-testnet.stellar.org', + mainnet: 'https://mainnet.sorobanrpc.com', +}; + +function asDidNetwork(network: string): DidNetwork { + return network === 'mainnet' ? 'mainnet' : 'testnet'; +} + +/** Registry contract ID for `network`, overridable per network via env. */ +export function getDidRegistryContractId(network: string): string { + const net = asDidNetwork(network); + const envValue = + net === 'mainnet' + ? process.env.NEXT_PUBLIC_DID_REGISTRY_CONTRACT_ID_MAINNET + : process.env.NEXT_PUBLIC_DID_REGISTRY_CONTRACT_ID_TESTNET; + if (envValue && typeof envValue === 'string' && envValue.trim()) return envValue.trim(); + return DEFAULT_DID_REGISTRY_CONTRACT_ID[net]; +} + +/** Soroban RPC URL for `network`, overridable per network via env. */ +export function getStellarRpcUrl(network: string): string { + const net = asDidNetwork(network); + const envValue = + net === 'mainnet' + ? process.env.NEXT_PUBLIC_STELLAR_RPC_URL_MAINNET + : process.env.NEXT_PUBLIC_STELLAR_RPC_URL_TESTNET; + if (envValue && typeof envValue === 'string' && envValue.trim()) + return envValue.trim().replace(/\/$/, ''); + return DEFAULT_STELLAR_RPC_URL[net]; +} + /** * Reads the user's registered did:stellar DID from localStorage. * Returns null if no DID has been created yet.