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.