@seedprotocol/publish 0.7.9 → 0.7.10-next.1353.g74aeeed
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +8 -0
- package/dist/{chainConfig-CD-RgKkA.js → chainConfig-B8U89YJb.js} +1011 -1008
- package/dist/chainConfig-B8U89YJb.js.map +1 -0
- package/dist/{ensureAutomationSessionKey-CHXAuk8Q.js → ensureAutomationSessionKey-B19eVd1T.js} +3 -3
- package/dist/{ensureAutomationSessionKey-CHXAuk8Q.js.map → ensureAutomationSessionKey-B19eVd1T.js.map} +1 -1
- package/dist/{ensureModularPublishBootstrap-Cit8PlNN.js → ensureModularPublishBootstrap-COEV4BGz.js} +3 -3
- package/dist/{ensureModularPublishBootstrap-Cit8PlNN.js.map → ensureModularPublishBootstrap-COEV4BGz.js.map} +1 -1
- package/dist/{ensureSmartWalletThenPublish-C2FS784-.js → ensureSmartWalletThenPublish-DhWyUjt0.js} +2 -2
- package/dist/{ensureSmartWalletThenPublish-C2FS784-.js.map → ensureSmartWalletThenPublish-DhWyUjt0.js.map} +1 -1
- package/dist/helpers/publishItem.d.ts +1 -1
- package/dist/helpers/publishItem.d.ts.map +1 -1
- package/dist/hooks/usePublishCostEstimate.d.ts.map +1 -1
- package/dist/hooks/usePublishCostEstimate.test.d.ts +2 -0
- package/dist/hooks/usePublishCostEstimate.test.d.ts.map +1 -0
- package/dist/index.js +325 -293
- package/dist/index.js.map +1 -1
- package/dist/{managedAccountAdmin-BmO4USir.js → managedAccountAdmin-xZbC3bQ5.js} +2 -2
- package/dist/{managedAccountAdmin-BmO4USir.js.map → managedAccountAdmin-xZbC3bQ5.js.map} +1 -1
- package/dist/{publishAuthorization-D1HYOu23.js → publishAuthorization-CpmPRbpm.js} +2 -2
- package/dist/{publishAuthorization-D1HYOu23.js.map → publishAuthorization-CpmPRbpm.js.map} +1 -1
- package/dist/{resolveRevokeAccount-CK8SbaVn.js → resolveRevokeAccount-D08n9UTy.js} +2 -2
- package/dist/{resolveRevokeAccount-CK8SbaVn.js.map → resolveRevokeAccount-D08n9UTy.js.map} +1 -1
- package/dist/services/publish/actors/createAttestations.d.ts +4 -3
- package/dist/services/publish/actors/createAttestations.d.ts.map +1 -1
- package/dist/services/publish/actors/createAttestationsDirectToEas.d.ts.map +1 -1
- package/dist/services/publish/actors/utils.d.ts +5 -0
- package/dist/services/publish/actors/utils.d.ts.map +1 -1
- package/dist/services/publishCost/watchPublishCost.d.ts +19 -2
- package/dist/services/publishCost/watchPublishCost.d.ts.map +1 -1
- package/dist/thirdweb.js +5 -5
- package/dist/{worker-BlNDHv1o.js → worker-4DXDWw6E.js} +2 -2
- package/dist/{worker-BlNDHv1o.js.map → worker-4DXDWw6E.js.map} +1 -1
- package/package.json +9 -9
- package/dist/chainConfig-CD-RgKkA.js.map +0 -1
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","names":["SeedProvider","DOMAIN_OWNERSHIP_METHOD","RESOLVER_ADDRESS","REVOCABLE","resolveTxSender","sendAndWait","DOMAIN_OWNERSHIP_SCHEMA_DEF","DOMAIN_OWNERSHIP_SCHEMA_NAME","DOMAIN_OWNERSHIP_METHOD","isValidEasAttestationUid","PUBLISHED_BY_SCHEMA_DEF","PUBLISHED_BY_SCHEMA_NAME","isValidEasAttestationUid","hashPublishedByBatch","ZERO_ADDRESS","DEFAULT_TURBO_PAYMENT_URL","registerSchema","prepareEasMultiRevoke","getPublishPublicClient","PUBLISH_GAS_HEURISTICS","fromEthersWallet","ensureEasSchemasForItem","ZERO_ADDRESS$1","ensureManagedAccountEasConfigured","isSeedTxSender","assertExecutorModuleReadyForAccount","encodeSetEas","AttestationVerificationError","simulateCallFromAccount","readFactorySeedExecutor","PublishTransactionRevertedError","Eip7702ModularAccountPublishError","readGetEas","encodeEasMultiAttest","encodeEasMultiRevoke","prepareNameSchemaAttestation","getAttestationUidFromReceipt","encodeMultiPublish","stringifyUnderlyingCause","readIsActiveSigner","getArweave","brandTxSender","assertManagedAccountEasMatchesConfig","isSeedSigner","isContractDeployed","waitForPublishReceipt","isManagedAccountPublishError","isEip7702ModularAccountPublishError","isRouterNonModularCoreAccountError","estimatePublishCost","getPublishConfig","MANAGED_ACCOUNT_FACTORY_ADDRESSES","PUBLISH_AUTHORIZATION_HEADER","getCachedTokenPrices","asSeedTxSender","resolvePublishEasChain","SEED_PROTOCOL_CONTRACT_ADDRESS_OP_SEPOLIA","getTurboBalanceWinc","ensureWalletThenPublish","verifyDataItem","DEFAULT_TURBO_UPLOAD_URL","PublishChainConfigError","combinePublishCostEstimate","publishMachine","getConfigRef","DEFAULT_PUBLISH_CHAIN","encodeEasAttest","getSchemaRecord","prepareEasAttest","publishItem","getTurboPriceWinc","PublishManager","getPublishViemChain","resolvePublishPayment","initPublish","MULTI_PUBLISH_ABI_REFERENCE_ADDRESS_OP_SEPOLIA","PublishNotAuthorizedError","createPermissionlessTxSender","verifyPublishChain","ManagedAccountPublishError","configurePublish","resolvePublishSender","requireManagedAccountFactoryAddress","PublishMachineStates","InsufficientStorageCreditsError","getPublishChainName","PublishPaymentConfigError","waitForPublishActor","buildPublishAnchorBytes","getCachedMarketRates","asPublishWallet","heuristicPublishGas","isPublishWallet","resetTokenPriceCache","brandSigner","resetMarketRateCache","asSeedSigner","setPublishWallet","getPublishWallet","clearPublishWallet","attestPublishAuthorization","getPublishAuthorizationSchemaUid","usePublishConfig","PublishConfigContext","assessPublishAuthorizationLive","revokePublishAuthorization","PUBLISH_AUTHORIZATION_SCHEMA_NAME","encodePublishAuthorizationAttestationData","PUBLISH_AUTHORIZATION_SCOPES","ensurePublishAuthorizationSchema","PUBLISH_AUTHORIZATION_SCHEMA_DEF","collectPublishedBatch","uidsFromAttestationPairs","DOMAIN_OWNERSHIP_METHOD$1","DOMAIN_OWNERSHIP_SCHEMA_DEF$1","DOMAIN_OWNERSHIP_SCHEMA_NAME$1","PUBLISHED_BY_SCHEMA_DEF$1","PUBLISHED_BY_SCHEMA_NAME$1","hashPublishedByBatch$1","isValidEasAttestationUid$1","SeedProvider$1","seedTwinConfig","missing","twin","value","key","forkName","chain","defineChain","PublishModeButtons","ariaLabel","base","btn","active","disabled","onChange","PublishProvider","initializedConfig","useRef","config","fromEip1193Provider","options","address","accounts","provider","walletClient","createWalletClient","custom","message","tx","fromWindowEthereum","eth","useSeedWallet","session","setSession","useState","status","setStatus","connect","useCallback","wallet","input","payment","txSender","next","err","disconnect","DEFAULT_PRICE_REFRESH_MS","DEFAULT_ITEM_IDLE_MS","propertyFingerprintValue","snapshot","prop","itemPublishFingerprint","props","item","asError","watchPublishCost","priceRefreshMs","itemIdleMs","estimateFn","target","repriceFn","rates","prev","disposed","lastFingerprint","lastEstimate","isEstimating","isStale","error","runId","idleTimer","priceTimer","emit","runEstimate","id","scheduleItemEstimate","refresh","subscription","fingerprint","getDisplayStepId","machineValue","resolvePublishDisplayValue","publishProcess","record","getPublishMachineValueForUi","p","isTerminalDoneSnapshot","usePublishProcess","publishManager","useSelector","seedLocalId","lastPublishSnapshotRef","setMachineValue","terminalLatch","setTerminalLatch","db","BaseDb","latestProcessRowQuery","useMemo","publishProcesses","eq","desc","latestRecord","useLiveQuery","recordStatus","fromRow","useEffect","last","initial","sub","useCanPublishItem","canPublish","setCanPublish","addressRevision","useSeedAddressRevision","current","isItemOwned","owned","useArweaveL1Finalize","jobsQuery","arweaveL1FinalizeJobs","jobs","pending","j","confirmed","useItemPublishStatus","arweaveL1","usePublishProcessesQuery","usePublishProcessesQueryForSeed","usePublishProcessesState","query","records","r","usePublishProcesses","usePublishProcessesNonActiveCount","usePublishProcessesForSeed","usePublishProcessesStateForSeed","usePublishProcessesNonActiveCountForSeed","usePublishProcessById","isLoading","clearCompletedPublishProcesses","notInArray","clearCompletedPublishProcessesForSeed","and","clearAllPublishProcesses","clearAllUploadProcesses","uploadProcesses","deletePublishProcessesForSeed","deletePublishProcessById","deletePublishProcessesByIds","ids","inArray","getArweaveTransactionIds","at","getEasPayload","usePublishCostEstimate","estimate","setEstimate","setIsEstimating","setIsStale","setError","refreshRef","publishMode","handle","normalizeRegistrableDomain","normalized","toRegistrableDomain","normalizeHostname","lookupDomainRegistry","registrable","domain","result","lookup","fingerprintFromRegistrySnapshot","hashDomainRegistryFingerprint","randomBytes","bytes","size","base64Url","binary","byte","createDomainOwnershipChallenge","hostnameOnly","params","claimer","scope","DOMAIN_OWNERSHIP_SCOPE_HOSTNAME","DOMAIN_OWNERSHIP_SCOPE_REGISTRABLE","ttlMs","DOMAIN_OWNERSHIP_CHALLENGE_TTL_MS","now","expiresAt","token","challengeHash","hashDomainOwnershipChallenge","txtName","domainOwnershipTxtName","txtValue","buildDomainOwnershipTxtValue","lookupNodeDns","dnsPromises","name","chunks","lookupDoh","url","endpoint","res","source","body","a","defaultLookups","lookups","valuesMatchExpected","expectedParsed","parseDomainOwnershipTxtValue","expected","v","values","parsed","verifyDomainOwnershipDns","challenge","lookupFns","quorum","matchedSources","dnssecMatch","fn","ok","RESOLVER_ADDRESS$1","REVOCABLE$1","resolveTxSender$1","account","sendAndWait$1","getDomainOwnershipSchemaUid","SchemaRegistry","ensureDomainOwnershipSchema","sender","schemaUid","encodeDomainOwnershipAttestationData","SchemaEncoder","normalizeBytes32Hex","resolveExpirationTime","ms","DOMAIN_OWNERSHIP_DEFAULT_EXPIRATION_SECS","attestDomainOwnership","ZERO_BYTES32","verifiedAt","registryFingerprint","registryCreationDate","registryExpirationDate","method","expirationTime","data","receipt","uid","easContractAddress","revokeDomainOwnership","verifyDomainOwnershipChallenge","expectedHash","dns","registryLookup","registrySnapshot","verifyAndAttestDomainOwnership","verified","assessDomainOwnershipLive","row","getDomainOwnershipFromEas","decoded","decodeDomainOwnershipData","assessDomainOwnership","RESOLVER_ADDRESS","REVOCABLE","resolveTxSender","sendAndWait","getPublishedBySchemaUid","ensurePublishedBySchema","encodePublishedByAttestationData","u","attestPublishedBy","attestationUids","batchHash","seedUid","NO_EXPIRATION","revokePublishedBy","DOMAIN_OWNERSHIP_METHOD","DOMAIN_OWNERSHIP_SCHEMA_DEF","DOMAIN_OWNERSHIP_SCHEMA_NAME","EAS_CHAIN_DEPLOYMENTS","PUBLISHED_BY_SCHEMA_DEF","PUBLISHED_BY_SCHEMA_NAME","SeedProvider","getEasChainDeployment","hashPublishedByBatch"],"sources":["../src/helpers/seedTwin.ts","../src/react/PublishModeButtons.tsx","../src/react/PublishProvider.tsx","../src/helpers/adapters/eip1193.ts","../src/react/useSeedWallet.ts","../src/services/publishCost/watchPublishCost.ts","../src/helpers/publishDisplayHelpers.ts","../src/hooks/usePublishProcess.ts","../src/hooks/useCanPublishItem.ts","../src/hooks/useArweaveL1Finalize.ts","../src/hooks/useItemPublishStatus.ts","../src/hooks/usePublishProcesses.ts","../src/hooks/clearCompletedPublishProcesses.ts","../src/hooks/publishProcessHelpers.ts","../src/hooks/usePublishCostEstimate.ts","../src/services/domainOwnership/registry.ts","../src/services/domainOwnership/challenge.ts","../src/services/domainOwnership/dnsVerify.ts","../src/services/domainOwnership/index.ts","../src/services/publishedBy/index.ts"],"sourcesContent":["import { defineChain, type Chain } from 'viem'\nimport type { PublishConfig } from '../config'\n\n/**\n * The parts of seed-protocol's `.twin/twin.json` (written by `bun run twin:up`) that apps need.\n * Its test-account keys are deliberately not part of this type.\n */\nexport interface SeedTwinInfo {\n chainId: number\n rpcUrl: string\n bundlerUrl: string\n easGraphqlUrl: string\n contracts: {\n eas: string\n schemaRegistry: string\n managedAccountFactory: string\n seedProtocolExecutor: string\n }\n forkedFrom?: { chain?: string; chainId?: number; block?: number }\n}\n\nexport type SeedTwinPublishConfig = Pick<\n PublishConfig,\n | 'chain'\n | 'rpcUrl'\n | 'easContractAddress'\n | 'schemaRegistryAddress'\n | 'managedAccountFactoryAddress'\n | 'modularAccountModuleContract'\n | 'thirdweb'\n>\n\n/**\n * Publish and SDK settings for the protocol's local OP Sepolia twin, from its `twin.json`.\n * Spread `publish` into `initPublish` and `eas` into `SeedConfig`:\n *\n * ```ts\n * const twin = seedTwinConfig(twinJson)\n * initPublish({ ...twin.publish, uploadApiBaseUrl, thirdwebClientId, useModularExecutor: true })\n * client.init({ config: { ...config, eas: twin.eas, filesDir: `.seed-${twin.chain.id}` } })\n * ```\n *\n * The twin has no paymaster or Thirdweb EIP-7702 service, so `thirdweb` turns sponsorship off,\n * uses the twin's bundler and sends admin transactions from a plain EOA. Fund the ManagedAccount\n * and the in-app EOA with `bun run twin:fund` before publishing.\n */\nexport function seedTwinConfig(twin: SeedTwinInfo): {\n chain: Chain\n publish: SeedTwinPublishConfig\n eas: { chainId: number; indexerUrl: string }\n} {\n const missing = (\n [\n ['chainId', twin?.chainId],\n ['rpcUrl', twin?.rpcUrl],\n ['bundlerUrl', twin?.bundlerUrl],\n ['easGraphqlUrl', twin?.easGraphqlUrl],\n ['contracts.eas', twin?.contracts?.eas],\n ['contracts.schemaRegistry', twin?.contracts?.schemaRegistry],\n ['contracts.managedAccountFactory', twin?.contracts?.managedAccountFactory],\n ['contracts.seedProtocolExecutor', twin?.contracts?.seedProtocolExecutor],\n ] as const\n )\n .filter(([, value]) => value === undefined || value === null || value === '')\n .map(([key]) => key)\n if (missing.length > 0) {\n throw new Error(`seedTwinConfig: twin.json is missing ${missing.join(', ')}. Re-run twin:up.`)\n }\n\n const forkName = twin.forkedFrom?.chain ? ` (${twin.forkedFrom.chain} fork)` : ''\n const chain = defineChain({\n id: twin.chainId,\n name: `Seed twin${forkName}`,\n nativeCurrency: { name: 'Ether', symbol: 'ETH', decimals: 18 },\n rpcUrls: { default: { http: [twin.rpcUrl] } },\n testnet: true,\n })\n\n return {\n chain,\n publish: {\n chain,\n rpcUrl: twin.rpcUrl,\n easContractAddress: twin.contracts.eas,\n schemaRegistryAddress: twin.contracts.schemaRegistry,\n managedAccountFactoryAddress: twin.contracts.managedAccountFactory,\n modularAccountModuleContract: twin.contracts.seedProtocolExecutor,\n thirdweb: { bundlerUrl: twin.bundlerUrl, sponsorGas: false, modularWalletMode: 'EOA' },\n },\n eas: { chainId: twin.chainId, indexerUrl: twin.easGraphqlUrl },\n }\n}\n","import React, { type FC } from 'react'\nimport type { PublishMode } from '../types'\n\nexport type PublishModeButtonsProps = {\n value: PublishMode\n onChange: (mode: PublishMode) => void\n disabled?: boolean\n /** Accessible label for the group */\n 'aria-label'?: string\n}\n\n/**\n * Optional control to choose patch (same Version) vs new Version before calling\n * `ensureSmartWalletThenPublish(item, …, { publishMode })` or `PublishManager.createPublish(…, { publishMode })`.\n */\nexport const PublishModeButtons: FC<PublishModeButtonsProps> = ({\n value,\n onChange,\n disabled = false,\n 'aria-label': ariaLabel = 'Publish mode',\n}) => {\n const base: React.CSSProperties = {\n display: 'inline-flex',\n gap: 8,\n flexWrap: 'wrap',\n }\n const btn = (active: boolean): React.CSSProperties => ({\n padding: '8px 14px',\n fontSize: 13,\n borderRadius: 8,\n border: `1px solid ${active ? '#344054' : '#D0D5DD'}`,\n background: active ? '#101828' : '#fff',\n color: active ? '#fff' : '#344054',\n cursor: disabled ? 'not-allowed' : 'pointer',\n opacity: disabled ? 0.6 : 1,\n })\n\n return (\n <div role=\"group\" aria-label={ariaLabel} style={base}>\n <button\n type=\"button\"\n disabled={disabled}\n style={btn(value === 'patch')}\n onClick={() => onChange('patch')}\n >\n Publish updates\n </button>\n <button\n type=\"button\"\n disabled={disabled}\n style={btn(value === 'new_version')}\n onClick={() => onChange('new_version')}\n >\n New version\n </button>\n </div>\n )\n}\n","import React, { FC, useRef } from \"react\"\nimport type { MutableRefObject } from \"react\"\nimport type { QueryClient } from \"@tanstack/react-query\"\nimport { SeedProvider } from '@seedprotocol/react'\nimport { initPublish, getConfigRef, type PublishConfig } from \"../config\"\nimport { PublishConfigContext, usePublishConfig } from \"./PublishConfigContext\"\n\nexport { usePublishConfig }\nexport type { PublishConfig }\n\nexport interface PublishProviderProps {\n children: React.ReactNode\n /**\n * If provided, calls initPublish with this config.\n * Otherwise, assumes initPublish was already called elsewhere.\n */\n config?: PublishConfig\n /** Optional: use your own QueryClient for Seed hooks. If not provided, SeedProvider creates one. */\n queryClient?: QueryClient\n /** Optional: ref to receive the QueryClient instance (e.g. for tests). */\n queryClientRef?: MutableRefObject<QueryClient | null>\n}\n\n/**\n * Core PublishProvider — no Thirdweb dependency.\n * For in-app wallets / ConnectButton, use `@seedprotocol/publish/thirdweb`.\n */\nconst PublishProvider: FC<PublishProviderProps> = ({\n children,\n config,\n queryClient,\n queryClientRef,\n}) => {\n // During render, not in an effect: children such as ConnectButton read the config on their\n // first render, which runs before this provider's effects. Once per config object.\n const initializedConfig = useRef<PublishConfig | undefined>(undefined)\n if (config && initializedConfig.current !== config) {\n initPublish(config)\n initializedConfig.current = config\n }\n\n return (\n <PublishConfigContext.Provider value={config ?? getConfigRef()}>\n <SeedProvider queryClient={queryClient} queryClientRef={queryClientRef}>\n {children}\n </SeedProvider>\n </PublishConfigContext.Provider>\n )\n}\n\nexport default PublishProvider\n","import {\n createWalletClient,\n custom,\n type Address,\n type Chain,\n type EIP1193Provider,\n type Hex,\n} from 'viem'\nimport {\n brandSigner,\n brandTxSender,\n type PublishWallet,\n type SeedSigner,\n type SeedTxSender,\n} from '../seedSigner'\nimport { getPublishViemChain } from '../chainConfig'\n\nexport type FromEip1193Options = {\n chain?: Chain\n /** If omitted, uses the first account from eth_requestAccounts / eth_accounts. */\n address?: Address\n}\n\n/**\n * Build a PublishWallet from an EIP-1193 provider (MetaMask, Rabby, injected wallets, etc.).\n * Transaction sends are EOA (user pays gas). Pair with permissionless for sponsored EIP-7702.\n */\nexport async function fromEip1193Provider(\n provider: EIP1193Provider,\n options: FromEip1193Options = {},\n): Promise<PublishWallet> {\n const chain = options.chain ?? getPublishViemChain()\n let address = options.address\n if (!address) {\n const accounts = (await provider.request({ method: 'eth_requestAccounts' })) as string[]\n if (!accounts?.[0]) {\n throw new Error('@seedprotocol/publish: EIP-1193 provider returned no accounts')\n }\n address = accounts[0] as Address\n }\n\n const walletClient = createWalletClient({\n account: address,\n chain,\n transport: custom(provider),\n })\n\n const signer = brandSigner({\n address,\n signMessage: async ({ message }) => {\n return walletClient.signMessage({\n account: address!,\n message:\n typeof message === 'string'\n ? message\n : { raw: message.raw as Hex | Uint8Array },\n })\n },\n })\n\n const txSender = brandTxSender({\n address,\n sendTransaction: async (tx) => {\n const hash = await walletClient.sendTransaction({\n account: address!,\n chain,\n to: tx.to,\n data: tx.data,\n value: tx.value,\n gas: tx.gas,\n })\n return { transactionHash: hash }\n },\n })\n\n return { signer, txSender, kind: 'eoa' }\n}\n\n/** Convenience: wrap window.ethereum when present. */\nexport async function fromWindowEthereum(\n options: FromEip1193Options = {},\n): Promise<PublishWallet> {\n const eth = (globalThis as { ethereum?: EIP1193Provider }).ethereum\n if (!eth) {\n throw new Error('@seedprotocol/publish: window.ethereum is not available')\n }\n return fromEip1193Provider(eth, options)\n}\n\n/** Expose branded helpers for composing custom EIP-1193 senders. */\nexport function brandEip1193Parts(signer: SeedSigner, txSender: SeedTxSender): PublishWallet {\n return {\n signer: brandSigner(signer),\n txSender: brandTxSender(txSender),\n }\n}\n","import { useCallback, useEffect, useState } from 'react'\nimport type { Address, EIP1193Provider } from 'viem'\nimport {\n isPublishWallet,\n type PublishWallet,\n type SeedSigner,\n type SeedTxSender,\n} from '../helpers/seedSigner'\nimport {\n clearPublishWallet,\n getPublishWallet,\n setPublishWallet,\n type PublishWalletSession,\n} from '../helpers/publishWalletRegistry'\nimport { fromEip1193Provider } from '../helpers/adapters/eip1193'\nimport { getPublishConfig } from '../config'\nimport { createPermissionlessTxSender } from '../helpers/adapters/permissionlessTxSender'\nimport { resolvePublishPayment } from '../payment'\n\nexport type SeedWalletStatus = 'disconnected' | 'connecting' | 'connected'\n\nexport type UseSeedWalletResult = {\n address: Address | undefined\n signer: SeedSigner | undefined\n txSender: SeedTxSender | undefined\n status: SeedWalletStatus\n connect: (input: EIP1193Provider | PublishWallet) => Promise<PublishWallet>\n disconnect: () => void\n}\n\n/**\n * Headless wallet session for publish — no Thirdweb dependency.\n * Registers into {@link setPublishWallet} so createPublish / ensureWalletThenPublish work.\n */\nexport function useSeedWallet(): UseSeedWalletResult {\n const [session, setSession] = useState<PublishWalletSession | null>(() => getPublishWallet())\n const [status, setStatus] = useState<SeedWalletStatus>(() =>\n getPublishWallet() ? 'connected' : 'disconnected',\n )\n\n useEffect(() => {\n setSession(getPublishWallet())\n }, [])\n\n const connect = useCallback(async (input: EIP1193Provider | PublishWallet) => {\n setStatus('connecting')\n try {\n let wallet: PublishWallet\n if (isPublishWallet(input)) {\n wallet = input\n } else {\n wallet = await fromEip1193Provider(input)\n }\n\n const config = getPublishConfig()\n const payment = resolvePublishPayment(config)\n let txSender = wallet.txSender\n if (payment.sender === 'eip7702') {\n txSender = await createPermissionlessTxSender({\n signer: wallet.signer,\n bundlerUrl: config.bundlerUrl!,\n paymasterUrl: config.paymasterUrl,\n sponsored: payment.gas.payer === 'sponsored',\n })\n }\n\n const next: PublishWalletSession = {\n signer: wallet.signer,\n txSender,\n ownedAddresses: [wallet.signer.address, txSender.address],\n publisherAddress: wallet.signer.address,\n }\n await setPublishWallet(next)\n setSession(next)\n setStatus('connected')\n return next\n } catch (err) {\n setStatus('disconnected')\n throw err\n }\n }, [])\n\n const disconnect = useCallback(() => {\n void clearPublishWallet()\n setSession(null)\n setStatus('disconnected')\n }, [])\n\n return {\n address: session?.signer.address,\n signer: session?.signer,\n txSender: session?.txSender,\n status,\n connect,\n disconnect,\n }\n}\n","import type { IItem } from '@seedprotocol/sdk'\nimport { combinePublishCostEstimate } from './estimatePublishCost'\nimport { estimatePublishCost } from './estimatePublishCost'\nimport { getCachedMarketRates } from './marketRates'\nimport type { EstimatePublishCostOptions, PublishCostEstimate } from './types'\n\nexport type WatchPublishCostSnapshot = {\n estimate: PublishCostEstimate | null\n isEstimating: boolean\n isStale: boolean\n error: Error | null\n}\n\nexport type WatchPublishCostOptions = EstimatePublishCostOptions & {\n priceRefreshMs?: number\n /** Trailing idle before re-summarizing the item. 0 = re-estimate on every fingerprint change. */\n itemIdleMs?: number\n estimate?: (item: IItem<any>) => Promise<PublishCostEstimate>\n reprice?: (estimate: PublishCostEstimate) => Promise<PublishCostEstimate>\n}\n\nexport type WatchPublishCostHandle = {\n dispose: () => void\n refresh: () => void\n}\n\nconst DEFAULT_PRICE_REFRESH_MS = 60_000\nconst DEFAULT_ITEM_IDLE_MS = 15_000\n\nfunction propertyFingerprintValue(prop: { propertyName: string; uid?: string; value?: unknown; getService: () => { getSnapshot: () => unknown } }): string {\n const snapshot = prop.getService().getSnapshot()\n const context =\n snapshot && typeof snapshot === 'object' && 'context' in snapshot\n ? (snapshot as { context?: Record<string, unknown> }).context\n : undefined\n const value = context?.propertyValue ?? (prop as { value?: unknown }).value\n return `${prop.propertyName}:${prop.uid ?? ''}:${String(value ?? '')}`\n}\n\nexport function itemPublishFingerprint(item: IItem<any>): string {\n const props = item.properties ?? []\n const parts = [\n item.seedLocalId,\n item.seedUid ?? '',\n item.latestVersionLocalId ?? '',\n ...props.map(propertyFingerprintValue),\n ]\n return parts.join('|')\n}\n\nfunction asError(err: unknown): Error {\n return err instanceof Error ? err : new Error(String(err))\n}\n\n/**\n * Watches an item and emits USD publish-cost estimates.\n * First estimate is immediate. Later item edits restart a 15s idle timer.\n * Market rates refresh every 60s and reprice the last work without re-summarizing.\n */\nexport function watchPublishCost(\n item: IItem<any>,\n onChange: (snapshot: WatchPublishCostSnapshot & { refresh: () => void }) => void,\n options?: WatchPublishCostOptions,\n): WatchPublishCostHandle {\n const priceRefreshMs = options?.priceRefreshMs ?? DEFAULT_PRICE_REFRESH_MS\n const itemIdleMs = options?.itemIdleMs ?? DEFAULT_ITEM_IDLE_MS\n const estimateFn =\n options?.estimate ??\n ((target: IItem<any>) => estimatePublishCost(target, options))\n const repriceFn =\n options?.reprice ??\n (async (prev: PublishCostEstimate) => {\n const rates = await getCachedMarketRates({ forceRefresh: true })\n return combinePublishCostEstimate(prev.work, rates, {\n evmUserPays: prev.evm.userPays,\n arweavePath: prev.arweave.path,\n })\n })\n\n let disposed = false\n let lastFingerprint = itemPublishFingerprint(item)\n let lastEstimate: PublishCostEstimate | null = null\n let isEstimating = false\n let isStale = false\n let error: Error | null = null\n let runId = 0\n let idleTimer: ReturnType<typeof setTimeout> | null = null\n let priceTimer: ReturnType<typeof setInterval> | null = null\n\n const emit = () => {\n if (disposed) return\n onChange({\n estimate: lastEstimate,\n isEstimating,\n isStale,\n error,\n refresh,\n })\n }\n\n const runEstimate = async () => {\n const id = ++runId\n isEstimating = true\n error = null\n emit()\n try {\n const next = await estimateFn(item)\n if (disposed || id !== runId) return\n lastEstimate = next\n lastFingerprint = itemPublishFingerprint(item)\n isStale = false\n isEstimating = false\n error = null\n emit()\n } catch (err) {\n if (disposed || id !== runId) return\n isEstimating = false\n error = asError(err)\n emit()\n }\n }\n\n const scheduleItemEstimate = () => {\n if (lastEstimate) isStale = true\n if (itemIdleMs <= 0) {\n void runEstimate()\n return\n }\n if (idleTimer) clearTimeout(idleTimer)\n idleTimer = setTimeout(() => {\n idleTimer = null\n void runEstimate()\n }, itemIdleMs)\n emit()\n }\n\n const refresh = () => {\n if (idleTimer) {\n clearTimeout(idleTimer)\n idleTimer = null\n }\n void runEstimate()\n }\n\n void runEstimate()\n\n const subscription = item.subscribe(() => {\n if (disposed) return\n const fingerprint = itemPublishFingerprint(item)\n if (fingerprint === lastFingerprint) return\n lastFingerprint = fingerprint\n scheduleItemEstimate()\n })\n\n if (priceRefreshMs > 0) {\n priceTimer = setInterval(() => {\n if (disposed || !lastEstimate || isEstimating) return\n void (async () => {\n try {\n const next = await repriceFn(lastEstimate!)\n if (disposed) return\n lastEstimate = next\n emit()\n } catch (err) {\n if (disposed) return\n error = asError(err)\n emit()\n }\n })()\n }, priceRefreshMs)\n }\n\n return {\n refresh,\n dispose: () => {\n disposed = true\n subscription.unsubscribe()\n if (idleTimer) clearTimeout(idleTimer)\n if (priceTimer) clearInterval(priceTimer)\n },\n }\n}\n","import { PublishMachineStates } from '~/helpers/constants'\n\n/**\n * Maps internal publish machine state values to display step IDs for UI consistency.\n * The direct-EAS path uses `creatingAttestationsDirectToEas` internally, but UIs\n * typically show a single \"Creating attestations\" step. This helper normalizes the\n * machine value for display.\n */\nexport function getDisplayStepId(machineValue: string): string {\n if (machineValue === 'creatingAttestationsDirectToEas') {\n return 'creatingAttestations'\n }\n return machineValue\n}\n\ntype PublishRowStatus = 'in_progress' | 'completed' | 'failed' | 'interrupted'\n\n/**\n * Single source of truth for step UIs: the live machine while running; once the\n * actor is gone, prefer the DB row status so we never flash an intermediate\n * `persistedSnapshot` value (e.g. creatingAttestations) after a completed run.\n */\nexport function resolvePublishDisplayValue(\n publishProcess: unknown | null | undefined,\n record: { status: PublishRowStatus } | undefined,\n machineValue: string | undefined\n): string | undefined {\n if (publishProcess != null) return machineValue\n if (record?.status === 'completed') return PublishMachineStates.SUCCESS\n if (record?.status === 'failed') return PublishMachineStates.FAILURE\n if (record?.status === 'interrupted') return undefined\n return machineValue\n}\n\nexport type PublishRowForDisplay = {\n status: string\n persistedSnapshot: string\n completedAt?: number | null\n}\n\n/**\n * Derives the machine-state string for UI from the persisted DB row. Prefer\n * `status` / `completedAt` over raw `persistedSnapshot` JSON so a stale or\n * out-of-order snapshot write cannot force the UI back to an intermediate step\n * after a terminal save (common when consumers read `JSON.parse(persistedSnapshot).value`).\n */\nexport function getPublishMachineValueForUi(record: PublishRowForDisplay | undefined): string | undefined {\n if (!record) return undefined\n\n if (record.status === 'failed') return PublishMachineStates.FAILURE\n if (record.status === 'completed') return PublishMachineStates.SUCCESS\n if (record.status === 'interrupted') return undefined\n\n if (record.completedAt != null) {\n try {\n const p = JSON.parse(record.persistedSnapshot) as { value?: unknown; status?: string }\n if (p.status === 'done' && p.value === PublishMachineStates.FAILURE) {\n return PublishMachineStates.FAILURE\n }\n } catch {\n /* ignore */\n }\n return PublishMachineStates.SUCCESS\n }\n\n try {\n const p = JSON.parse(record.persistedSnapshot) as { value?: unknown; status?: string }\n if (p.status === 'done') {\n if (p.value === PublishMachineStates.SUCCESS) return PublishMachineStates.SUCCESS\n if (p.value === PublishMachineStates.FAILURE) return PublishMachineStates.FAILURE\n }\n if (typeof p.value === 'string') return p.value\n } catch {\n return undefined\n }\n return undefined\n}\n","import { useState, useEffect, useRef, useMemo } from 'react'\nimport { useSelector } from '@xstate/react'\nimport { useLiveQuery } from '@seedprotocol/react'\nimport { BaseDb, publishProcesses } from '@seedprotocol/sdk'\nimport { eq, desc } from 'drizzle-orm'\nimport { PublishManager } from '../services/publishManager'\nimport { PublishMachineStates } from '~/helpers/constants'\nimport { getPublishMachineValueForUi, resolvePublishDisplayValue } from '~/helpers/publishDisplayHelpers'\n\nfunction isTerminalDoneSnapshot(snapshot: { value?: unknown; status?: string } | null): snapshot is { value: string; status: 'done' } {\n if (!snapshot || snapshot.status !== 'done') return false\n return snapshot.value === PublishMachineStates.SUCCESS || snapshot.value === PublishMachineStates.FAILURE\n}\n\nexport function usePublishProcess(seedLocalId: string) {\n const publishManager = PublishManager.getService()\n\n const publishProcess = useSelector(publishManager, (snapshot) => {\n return snapshot?.context?.publishProcesses?.get(seedLocalId) ?? null\n })\n\n /** Last snapshot from the publish actor; survives removal from the manager map so we can keep terminal `value`. */\n const lastPublishSnapshotRef = useRef<{ value?: unknown; status?: string } | null>(null)\n\n useEffect(() => {\n lastPublishSnapshotRef.current = null\n }, [seedLocalId])\n\n const [machineValue, setMachineValue] = useState<string | undefined>(undefined)\n /**\n * Once we have observed a terminal outcome for this seed (machine done or DB row), keep\n * showing success/failure until a new publish actor is spawned. Prevents the UI from\n * flipping back to an intermediate step when live-query or row ordering briefly reports\n * in_progress or a stale persistedSnapshot after completion.\n */\n const [terminalLatch, setTerminalLatch] = useState<'success' | 'failure' | null>(null)\n\n const db = BaseDb.getAppDb()\n const latestProcessRowQuery = useMemo(\n () =>\n seedLocalId && db\n ? db\n .select()\n .from(publishProcesses)\n .where(eq(publishProcesses.seedLocalId, seedLocalId))\n .orderBy(desc(publishProcesses.startedAt))\n .limit(1)\n : null,\n [db, seedLocalId]\n )\n const latestRecords = useLiveQuery(latestProcessRowQuery)\n const latestRecord = latestRecords?.[0] as\n | { status: string; persistedSnapshot: string; completedAt?: number | null }\n | undefined\n const recordStatus = latestRecord?.status as\n | 'in_progress'\n | 'completed'\n | 'failed'\n | 'interrupted'\n | undefined\n\n const value = useMemo(() => {\n if (publishProcess != null) {\n return machineValue\n }\n if (terminalLatch === 'success' || terminalLatch === 'failure') {\n return terminalLatch\n }\n const fromRow = getPublishMachineValueForUi(latestRecord)\n if (fromRow === PublishMachineStates.SUCCESS || fromRow === PublishMachineStates.FAILURE) {\n return fromRow\n }\n return resolvePublishDisplayValue(\n publishProcess,\n recordStatus != null ? { status: recordStatus } : undefined,\n machineValue\n )\n }, [publishProcess, recordStatus, machineValue, terminalLatch, latestRecord])\n\n useEffect(() => {\n setTerminalLatch(null)\n }, [seedLocalId])\n\n useEffect(() => {\n if (publishProcess != null) {\n return\n }\n if (recordStatus === 'completed') {\n setTerminalLatch('success')\n } else if (recordStatus === 'failed') {\n setTerminalLatch('failure')\n }\n }, [recordStatus, publishProcess])\n\n useEffect(() => {\n if (publishProcess != null) {\n setTerminalLatch(null)\n }\n }, [publishProcess])\n\n useEffect(() => {\n if (!publishProcess) {\n const last = lastPublishSnapshotRef.current\n const preserve = isTerminalDoneSnapshot(last)\n if (preserve) {\n setMachineValue(last.value as string)\n if (last.value === PublishMachineStates.SUCCESS) {\n setTerminalLatch('success')\n } else if (last.value === PublishMachineStates.FAILURE) {\n setTerminalLatch('failure')\n }\n } else {\n setMachineValue(undefined)\n }\n return\n }\n const initial = publishProcess.getSnapshot()\n lastPublishSnapshotRef.current = { value: initial?.value, status: (initial as { status?: string }).status }\n setMachineValue(initial?.value as string | undefined)\n const sub = publishProcess.subscribe((snapshot: { value?: unknown; status?: string }) => {\n lastPublishSnapshotRef.current = { value: snapshot?.value, status: snapshot?.status }\n setMachineValue(snapshot?.value as string | undefined)\n })\n return () => {\n sub.unsubscribe()\n }\n }, [publishProcess, seedLocalId])\n\n return {\n publishProcess: publishProcess ?? null,\n value,\n }\n}\n","import { useState, useEffect } from 'react'\nimport { isItemOwned } from '@seedprotocol/sdk'\nimport type { Item } from '@seedprotocol/sdk'\nimport { useSeedAddressRevision } from '@seedprotocol/react'\n\n/**\n * Whether the client's addresses own `item`, so it can be published. False until the check has\n * finished, and checked again when the item or the owned addresses change (connect, disconnect,\n * setAddresses). A check overtaken by a newer one is ignored.\n */\nexport function useCanPublishItem(item: Item<any> | null | undefined): boolean {\n const [canPublish, setCanPublish] = useState(false)\n const addressRevision = useSeedAddressRevision()\n const seedLocalId = item?.seedLocalId\n\n useEffect(() => {\n if (!item) {\n setCanPublish(false)\n return\n }\n let current = true\n setCanPublish(false)\n isItemOwned(item)\n .then((owned) => {\n if (current) setCanPublish(owned)\n })\n .catch(() => {\n if (current) setCanPublish(false)\n })\n return () => {\n current = false\n }\n }, [seedLocalId, addressRevision])\n\n return canPublish\n}\n","import { useMemo } from 'react'\nimport { useLiveQuery } from '@seedprotocol/react'\nimport { arweaveL1FinalizeJobs, BaseDb } from '@seedprotocol/sdk'\nimport { eq, desc } from 'drizzle-orm'\n\nexport type ArweaveL1FinalizeJobRow = {\n id: number\n seedLocalId: string\n dataItemId: string\n l1TransactionId: string | null\n bundleId: string | null\n phase: string\n statusJson: string | null\n errorMessage: string | null\n versionLocalId: string | null\n itemPropertyName: string | null\n updatedAt: number | null\n}\n\n/**\n * Live L1 finalization jobs for a seed (bundler path). Empty when not using bundler or no jobs.\n */\nexport function useArweaveL1Finalize(seedLocalId: string | undefined) {\n const db = BaseDb.getAppDb()\n const jobsQuery = useMemo(\n () =>\n seedLocalId && db\n ? db\n .select()\n .from(arweaveL1FinalizeJobs)\n .where(eq(arweaveL1FinalizeJobs.seedLocalId, seedLocalId))\n .orderBy(desc(arweaveL1FinalizeJobs.updatedAt))\n : null,\n [db, seedLocalId]\n )\n const rows = useLiveQuery(jobsQuery)\n\n const jobs = (rows ?? []) as ArweaveL1FinalizeJobRow[]\n\n const summary = useMemo(() => {\n const pending = jobs.filter((j) => j.phase === 'pending_l1').length\n const confirmed = jobs.filter((j) => j.phase === 'confirmed').length\n return {\n hasPendingL1: pending > 0,\n pendingCount: pending,\n confirmedCount: confirmed,\n jobs,\n }\n }, [jobs])\n\n return summary\n}\n","import { useMemo } from 'react'\nimport { useLiveQuery } from '@seedprotocol/react'\nimport { BaseDb, publishProcesses } from '@seedprotocol/sdk'\nimport { eq, desc } from 'drizzle-orm'\nimport { usePublishProcess } from './usePublishProcess'\nimport { useArweaveL1Finalize } from './useArweaveL1Finalize'\n\nexport type PublishProcessStatus = 'in_progress' | 'completed' | 'failed' | 'interrupted'\n\nexport interface PublishProcessRecord {\n id: number\n seedLocalId: string\n modelName: string\n schemaId?: string\n status: PublishProcessStatus\n startedAt: number\n completedAt?: number\n errorMessage?: string\n errorStep?: string\n errorDetails?: string\n /** Stable error code (e.g. `ManagedAccountPublishError.code`) when the failure had one. */\n errorCode?: string\n persistedSnapshot: string\n createdAt?: number\n updatedAt?: number\n}\n\nexport function useItemPublishStatus(seedLocalId: string | undefined) {\n const { publishProcess, value } = usePublishProcess(seedLocalId ?? '')\n const arweaveL1 = useArweaveL1Finalize(seedLocalId)\n\n const db = BaseDb.getAppDb()\n const latestProcessRowQuery = useMemo(\n () =>\n seedLocalId && db\n ? db\n .select()\n .from(publishProcesses)\n .where(eq(publishProcesses.seedLocalId, seedLocalId))\n .orderBy(desc(publishProcesses.startedAt))\n .limit(1)\n : null,\n [db, seedLocalId]\n )\n const latestRecords = useLiveQuery(latestProcessRowQuery)\n\n const record = latestRecords?.[0] as PublishProcessRecord | undefined\n const isActive = !!publishProcess || record?.status === 'in_progress'\n\n return {\n latestRecord: record,\n publishProcess,\n isActive,\n publishValue: value,\n arweaveL1Pending: arweaveL1.hasPendingL1,\n arweaveL1Jobs: arweaveL1.jobs,\n arweaveL1Summary: arweaveL1,\n }\n}\n","import { useMemo } from 'react'\nimport { useLiveQuery } from '@seedprotocol/react'\nimport { BaseDb, publishProcesses } from '@seedprotocol/sdk'\nimport { desc, eq } from 'drizzle-orm'\nimport type { PublishProcessRecord } from './useItemPublishStatus'\n\nfunction usePublishProcessesQuery() {\n const db = BaseDb.getAppDb()\n return useMemo(\n () => (db ? db.select().from(publishProcesses).orderBy(desc(publishProcesses.startedAt)) : null),\n [db]\n )\n}\n\nfunction usePublishProcessesQueryForSeed(seedLocalId: string | undefined) {\n const db = BaseDb.getAppDb()\n return useMemo(\n () =>\n db && seedLocalId\n ? db\n .select()\n .from(publishProcesses)\n .where(eq(publishProcesses.seedLocalId, seedLocalId))\n .orderBy(desc(publishProcesses.startedAt))\n : null,\n [db, seedLocalId]\n )\n}\n\n/**\n * Single live subscription for the ordered publish_processes list plus a derived non-active count.\n * Prefer this when you need both values in one component so you do not combine\n * {@link usePublishProcesses} and {@link usePublishProcessesNonActiveCount} (which would subscribe twice).\n */\nexport function usePublishProcessesState(): {\n records: PublishProcessRecord[] | undefined\n nonActiveCount: number | undefined\n} {\n const query = usePublishProcessesQuery()\n const records = useLiveQuery(query) as PublishProcessRecord[] | undefined\n const nonActiveCount = useMemo(\n () => (records === undefined ? undefined : records.filter((r) => r.status !== 'in_progress').length),\n [records]\n )\n return { records, nonActiveCount }\n}\n\nexport function usePublishProcesses(): PublishProcessRecord[] | undefined {\n const query = usePublishProcessesQuery()\n return useLiveQuery(query) as PublishProcessRecord[] | undefined\n}\n\nexport function usePublishProcessesNonActiveCount(): number | undefined {\n return usePublishProcessesState().nonActiveCount\n}\n\n/**\n * Live query of `publish_processes` for one seed, ordered by `startedAt` descending.\n * Pass `undefined` to disable the query (returns `undefined`).\n */\nexport function usePublishProcessesForSeed(\n seedLocalId: string | undefined\n): PublishProcessRecord[] | undefined {\n const query = usePublishProcessesQueryForSeed(seedLocalId)\n return useLiveQuery(query) as PublishProcessRecord[] | undefined\n}\n\n/**\n * Same as {@link usePublishProcessesForSeed} plus a derived count of rows whose status is not\n * `in_progress`. Prefer this over combining {@link usePublishProcessesForSeed} and a separate\n * count hook so you only subscribe once.\n */\nexport function usePublishProcessesStateForSeed(seedLocalId: string | undefined): {\n records: PublishProcessRecord[] | undefined\n nonActiveCount: number | undefined\n} {\n const query = usePublishProcessesQueryForSeed(seedLocalId)\n const records = useLiveQuery(query) as PublishProcessRecord[] | undefined\n const nonActiveCount = useMemo(\n () => (records === undefined ? undefined : records.filter((r) => r.status !== 'in_progress').length),\n [records]\n )\n return { records, nonActiveCount }\n}\n\nexport function usePublishProcessesNonActiveCountForSeed(\n seedLocalId: string | undefined\n): number | undefined {\n return usePublishProcessesStateForSeed(seedLocalId).nonActiveCount\n}\n\nexport function usePublishProcessById(\n id: number | undefined\n): { record: PublishProcessRecord | null; isLoading: boolean } {\n const db = BaseDb.getAppDb()\n const query = useMemo(\n () =>\n id != null && db\n ? db.select().from(publishProcesses).where(eq(publishProcesses.id, id)).limit(1)\n : null,\n [db, id]\n )\n const records = useLiveQuery(query)\n const isLoading = records === undefined\n const record = records && records.length > 0 ? (records[0] as PublishProcessRecord) : null\n return { record, isLoading }\n}\n","import { BaseDb, publishProcesses, uploadProcesses } from '@seedprotocol/sdk'\nimport { and, notInArray, eq, inArray } from 'drizzle-orm'\n\n/** Remove every publish_processes row whose status is not `in_progress` (app-wide). */\nexport async function clearCompletedPublishProcesses(): Promise<void> {\n const db = BaseDb.getAppDb()\n if (!db) return\n\n await db\n .delete(publishProcesses)\n .where(notInArray(publishProcesses.status, ['in_progress']))\n}\n\n/**\n * Same semantics as {@link clearCompletedPublishProcesses}, but only for rows with the given\n * `seedLocalId`. Never deletes `in_progress` runs for that seed.\n */\nexport async function clearCompletedPublishProcessesForSeed(seedLocalId: string): Promise<void> {\n const db = BaseDb.getAppDb()\n if (!db) return\n\n await db\n .delete(publishProcesses)\n .where(\n and(eq(publishProcesses.seedLocalId, seedLocalId), notInArray(publishProcesses.status, ['in_progress']))\n )\n}\n\nexport async function clearAllPublishProcesses(): Promise<void> {\n const db = BaseDb.getAppDb()\n if (!db) return\n\n await db.delete(publishProcesses)\n}\n\nexport async function clearAllUploadProcesses(): Promise<void> {\n const db = BaseDb.getAppDb()\n if (!db) return\n\n await db.delete(uploadProcesses)\n}\n\n/**\n * Deletes **all** `publish_processes` rows for this seed (full history, including any\n * `in_progress` run). For removing individual runs, use {@link deletePublishProcessById} or\n * {@link deletePublishProcessesByIds}.\n */\nexport async function deletePublishProcessesForSeed(seedLocalId: string): Promise<void> {\n const db = BaseDb.getAppDb()\n if (!db) return\n\n await db.delete(publishProcesses).where(eq(publishProcesses.seedLocalId, seedLocalId))\n}\n\n/** Delete a single publish process record by id. */\nexport async function deletePublishProcessById(id: number): Promise<void> {\n const db = BaseDb.getAppDb()\n if (!db) return\n await db.delete(publishProcesses).where(eq(publishProcesses.id, id))\n}\n\n/** Delete multiple publish process records by ids. */\nexport async function deletePublishProcessesByIds(ids: number[]): Promise<void> {\n if (ids.length === 0) return\n const db = BaseDb.getAppDb()\n if (!db) return\n await db.delete(publishProcesses).where(inArray(publishProcesses.id, ids))\n}\n","/**\n * Extracts Arweave transaction IDs from a publish process record's persisted snapshot.\n * Returns an empty array on parse error or when no transactions exist.\n */\nexport function getArweaveTransactionIds(record: { persistedSnapshot: string }): string[] {\n try {\n const parsed = JSON.parse(record.persistedSnapshot) as {\n context?: { arweaveTransactions?: Array<{ transaction?: { id?: string } }> }\n }\n const txs = parsed.context?.arweaveTransactions ?? []\n return txs\n .map((at) => (at.transaction as { id?: string })?.id)\n .filter((id): id is string => typeof id === 'string')\n } catch {\n return []\n }\n}\n\n/**\n * Extracts the EAS attestation payload from a publish process record's persisted snapshot.\n * Returns undefined on parse error or when no payload was persisted.\n */\nexport function getEasPayload(record: { persistedSnapshot: string }): unknown {\n try {\n const parsed = JSON.parse(record.persistedSnapshot) as {\n context?: { easPayload?: unknown }\n }\n return parsed.context?.easPayload ?? undefined\n } catch {\n return undefined\n }\n}\n","import { useCallback, useEffect, useRef, useState } from 'react'\nimport type { IItem } from '@seedprotocol/sdk'\nimport {\n watchPublishCost,\n type WatchPublishCostOptions,\n} from '../services/publishCost/watchPublishCost'\nimport type { PublishCostEstimate } from '../services/publishCost/types'\n\nexport type UsePublishCostEstimateResult = {\n estimate: PublishCostEstimate | null\n isEstimating: boolean\n isStale: boolean\n error: Error | null\n refresh: () => void\n}\n\nexport function usePublishCostEstimate(\n item: IItem<any> | null | undefined,\n options?: WatchPublishCostOptions,\n): UsePublishCostEstimateResult {\n const [estimate, setEstimate] = useState<PublishCostEstimate | null>(null)\n const [isEstimating, setIsEstimating] = useState(false)\n const [isStale, setIsStale] = useState(false)\n const [error, setError] = useState<Error | null>(null)\n const refreshRef = useRef<() => void>(() => {})\n\n const publishMode = options?.publishMode\n const priceRefreshMs = options?.priceRefreshMs\n const itemIdleMs = options?.itemIdleMs\n\n useEffect(() => {\n if (!item) {\n setEstimate(null)\n setIsEstimating(false)\n setIsStale(false)\n setError(null)\n refreshRef.current = () => {}\n return\n }\n\n const handle = watchPublishCost(\n item,\n (snapshot) => {\n setEstimate(snapshot.estimate)\n setIsEstimating(snapshot.isEstimating)\n setIsStale(snapshot.isStale)\n setError(snapshot.error)\n refreshRef.current = snapshot.refresh\n },\n options,\n )\n\n return () => {\n handle.dispose()\n }\n // Primitive option fields only — avoid resubscribing on a new options object each render.\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [item, item?.seedLocalId, publishMode, priceRefreshMs, itemIdleMs])\n\n const refresh = useCallback(() => {\n refreshRef.current()\n }, [])\n\n return { estimate, isEstimating, isStale, error, refresh }\n}\n","import { lookup, toRegistrableDomain } from 'rdapper'\nimport {\n hashDomainRegistryFingerprint,\n type DomainRegistryFingerprintInput,\n} from '@seedprotocol/eas'\n\nexport type DomainRegistrySnapshot = DomainRegistryFingerprintInput & {\n expirationDate?: string\n updatedDate?: string\n registrarName?: string\n source?: string\n isRegistered?: boolean\n}\n\n/**\n * Normalize input to a registrable domain (eTLD+1). Throws when invalid.\n */\nexport function normalizeRegistrableDomain(input: string): string {\n const normalized = toRegistrableDomain(input)\n if (!normalized) {\n throw new Error(\n `@seedprotocol/publish: unable to resolve registrable domain for \"${input}\"`,\n )\n }\n return normalized.toLowerCase()\n}\n\n/** Lowercased hostname without a trailing dot. No eTLD+1 normalization. */\nexport function normalizeHostname(input: string): string {\n return input.trim().toLowerCase().replace(/\\.$/, '')\n}\n\n/**\n * Fetch RDAP/WHOIS registry snapshot and compute fingerprint inputs.\n */\nexport async function lookupDomainRegistry(\n domain: string,\n): Promise<DomainRegistrySnapshot | null> {\n const registrable = normalizeRegistrableDomain(domain)\n const result = await lookup(registrable)\n if (!result.ok || !result.record) {\n return null\n }\n const record = result.record\n return {\n domain: registrable,\n creationDate: record.creationDate ?? '',\n registrarIanaId: record.registrar?.ianaId ?? '',\n expirationDate: record.expirationDate,\n updatedDate: record.updatedDate,\n registrarName: record.registrar?.name,\n source: record.source,\n isRegistered: record.isRegistered,\n }\n}\n\nexport function fingerprintFromRegistrySnapshot(\n snapshot: DomainRegistryFingerprintInput,\n): `0x${string}` {\n return hashDomainRegistryFingerprint({\n domain: snapshot.domain,\n creationDate: snapshot.creationDate ?? '',\n registrarIanaId: snapshot.registrarIanaId ?? '',\n })\n}\n","import {\n DOMAIN_OWNERSHIP_CHALLENGE_TTL_MS,\n DOMAIN_OWNERSHIP_METHOD,\n DOMAIN_OWNERSHIP_SCOPE_HOSTNAME,\n DOMAIN_OWNERSHIP_SCOPE_REGISTRABLE,\n buildDomainOwnershipTxtValue,\n domainOwnershipTxtName,\n hashDomainOwnershipChallenge,\n} from '@seedprotocol/eas'\nimport { normalizeHostname, normalizeRegistrableDomain } from './registry'\n\nexport type DomainOwnershipChallenge = {\n /** Opaque id for caller correlation (not required by verify). */\n challengeId: string\n domain: string\n claimer: string\n scope: string\n method: typeof DOMAIN_OWNERSHIP_METHOD\n /** Raw challenge token (keep private until DNS publish; discard after verify). */\n token: string\n txtName: string\n txtValue: string\n challengeHash: `0x${string}`\n /** ISO-8601 expiry encoded in the TXT record. */\n expiresAt: string\n /** Suggested dig command for operators. */\n digHint: string\n}\n\nfunction randomBytes(size: number): Uint8Array {\n const bytes = new Uint8Array(size)\n crypto.getRandomValues(bytes)\n return bytes\n}\n\nfunction base64Url(bytes: Uint8Array): string {\n let binary = ''\n for (const byte of bytes) {\n binary += String.fromCharCode(byte)\n }\n return btoa(binary).replace(/\\+/g, '-').replace(/\\//g, '_').replace(/=+$/g, '')\n}\n\n/**\n * Create a caller-held DNS TXT challenge for domain ownership verification.\n * The caller must persist the returned object and pass it to verify.\n * Domains are normalized to eTLD+1 (registrable) by default.\n */\nexport function createDomainOwnershipChallenge(params: {\n domain: string\n claimer: string\n scope?: string\n /** Override challenge TTL (ms). Default 72h. */\n ttlMs?: number\n now?: number\n /**\n * When false, skip eTLD+1 normalization: the challenge is on the hostname as given, and the\n * scope defaults to {@link DOMAIN_OWNERSHIP_SCOPE_HOSTNAME}. Default true.\n */\n normalizeRegistrable?: boolean\n}): DomainOwnershipChallenge {\n const hostnameOnly = params.normalizeRegistrable === false\n const domain = hostnameOnly ? normalizeHostname(params.domain) : normalizeRegistrableDomain(params.domain)\n if (!domain || domain.includes(' ')) {\n throw new Error('@seedprotocol/publish: createDomainOwnershipChallenge requires a valid domain')\n }\n const claimer = params.claimer.trim()\n if (!/^0x[0-9a-fA-F]{40}$/.test(claimer)) {\n throw new Error(\n '@seedprotocol/publish: createDomainOwnershipChallenge requires a 20-byte hex claimer address',\n )\n }\n const scope =\n params.scope ?? (hostnameOnly ? DOMAIN_OWNERSHIP_SCOPE_HOSTNAME : DOMAIN_OWNERSHIP_SCOPE_REGISTRABLE)\n // A TXT record on a subdomain proves nothing about the rest of the registrable domain.\n if (scope === DOMAIN_OWNERSHIP_SCOPE_REGISTRABLE && domain !== normalizeRegistrableDomain(domain)) {\n throw new Error(\n `@seedprotocol/publish: createDomainOwnershipChallenge cannot use scope \"registrable\" for \"${domain}\", which is not a registrable domain. Use the hostname scope or challenge ${normalizeRegistrableDomain(domain)}.`,\n )\n }\n const ttlMs = params.ttlMs ?? DOMAIN_OWNERSHIP_CHALLENGE_TTL_MS\n const now = params.now ?? Date.now()\n const expiresAt = new Date(now + ttlMs).toISOString()\n const token = base64Url(randomBytes(32))\n const challengeHash = hashDomainOwnershipChallenge({\n domain,\n claimer,\n token,\n scope,\n })\n const txtName = domainOwnershipTxtName(domain)\n const txtValue = buildDomainOwnershipTxtValue({\n token,\n claimer,\n expiry: expiresAt,\n })\n const challengeId = base64Url(randomBytes(16))\n\n return {\n challengeId,\n domain,\n claimer,\n scope,\n method: DOMAIN_OWNERSHIP_METHOD,\n token,\n txtName,\n txtValue,\n challengeHash,\n expiresAt,\n digHint: `dig TXT ${txtName}`,\n }\n}\n","import {\n buildDomainOwnershipTxtValue,\n parseDomainOwnershipTxtValue,\n} from '@seedprotocol/eas'\nimport type { DomainOwnershipChallenge } from './challenge'\n\nexport type DnsTxtLookupResult = {\n source: string\n values: string[]\n dnssecAuthenticated?: boolean\n}\n\nexport type VerifyDomainOwnershipDnsResult = {\n ok: boolean\n matchedSources: string[]\n lookups: DnsTxtLookupResult[]\n error?: string\n}\n\ntype DohAnswer = { name?: string; type?: number; data?: string; TTL?: number }\ntype DohResponse = { Status?: number; AD?: boolean; Answer?: DohAnswer[] }\n\n/** Node-only DNS; dynamically imported so browser bundles never top-level-import `node:dns`. */\nasync function lookupNodeDns(name: string): Promise<DnsTxtLookupResult> {\n const { promises: dnsPromises } = await import('node:dns')\n const records = await dnsPromises.resolveTxt(name)\n const values = records.map((chunks) => chunks.join(''))\n return { source: 'node:dns', values }\n}\n\nasync function lookupDoh(\n name: string,\n source: string,\n endpoint: string,\n): Promise<DnsTxtLookupResult> {\n const url = `${endpoint}?name=${encodeURIComponent(name)}&type=TXT`\n const res = await fetch(url, {\n headers: { accept: 'application/dns-json' },\n })\n if (!res.ok) {\n throw new Error(`DoH ${source} HTTP ${res.status}`)\n }\n const body = (await res.json()) as DohResponse\n const values = (body.Answer ?? [])\n .filter((a) => a.type === 16 && typeof a.data === 'string')\n .map((a) => a.data!.replace(/^\"|\"$/g, ''))\n return {\n source,\n values,\n dnssecAuthenticated: Boolean(body.AD),\n }\n}\n\nfunction defaultLookups(): Array<(name: string) => Promise<DnsTxtLookupResult>> {\n const lookups: Array<(name: string) => Promise<DnsTxtLookupResult>> = [\n (name) => lookupDoh(name, 'cloudflare-doh', 'https://cloudflare-dns.com/dns-query'),\n (name) => lookupDoh(name, 'google-doh', 'https://dns.google/resolve'),\n ]\n // Skip node:dns in DOM runtimes (Vite externalizes it and top-level/eager use crashes).\n if (typeof document === 'undefined') {\n lookups.unshift((name) => lookupNodeDns(name))\n }\n return lookups\n}\n\nfunction valuesMatchExpected(values: string[], expected: string): boolean {\n const expectedParsed = parseDomainOwnershipTxtValue(expected)\n for (const v of values) {\n if (v === expected || v.replace(/^\"|\"$/g, '') === expected) return true\n const parsed = parseDomainOwnershipTxtValue(v)\n if (\n expectedParsed &&\n parsed &&\n parsed.token === expectedParsed.token &&\n parsed.claimer === expectedParsed.claimer\n ) {\n return true\n }\n }\n return false\n}\n\n/**\n * Verify that the challenge TXT is visible via multiple DNS vantage points.\n * Requires quorum (≥2 matching sources) when no DNSSEC-authenticated match is seen.\n */\nexport async function verifyDomainOwnershipDns(\n challenge: DomainOwnershipChallenge,\n options?: {\n lookups?: Array<(name: string) => Promise<DnsTxtLookupResult>>\n /** Minimum matching sources when DNSSEC AD is not observed (default 2). */\n quorum?: number\n now?: number\n },\n): Promise<VerifyDomainOwnershipDnsResult> {\n const now = options?.now ?? Date.now()\n if (Date.parse(challenge.expiresAt) <= now) {\n return {\n ok: false,\n matchedSources: [],\n lookups: [],\n error: 'Challenge expired',\n }\n }\n\n // Ensure expected TXT is canonical for this challenge material\n const expected = buildDomainOwnershipTxtValue({\n token: challenge.token,\n claimer: challenge.claimer,\n expiry: challenge.expiresAt,\n })\n if (expected !== challenge.txtValue) {\n return {\n ok: false,\n matchedSources: [],\n lookups: [],\n error: 'Challenge txtValue does not match token/claimer/expiry',\n }\n }\n\n const lookupFns = options?.lookups ?? defaultLookups()\n const quorum = options?.quorum ?? 2\n const lookups: DnsTxtLookupResult[] = []\n const matchedSources: string[] = []\n let dnssecMatch = false\n\n await Promise.all(\n lookupFns.map(async (fn) => {\n try {\n const result = await fn(challenge.txtName)\n lookups.push(result)\n if (valuesMatchExpected(result.values, expected)) {\n matchedSources.push(result.source)\n if (result.dnssecAuthenticated) dnssecMatch = true\n }\n } catch (err) {\n lookups.push({\n source: 'error',\n values: [],\n })\n void err\n }\n }),\n )\n\n const ok = dnssecMatch || matchedSources.length >= quorum\n return {\n ok,\n matchedSources,\n lookups,\n error: ok\n ? undefined\n : `DNS TXT not confirmed (matched ${matchedSources.length}/${quorum} sources)`,\n }\n}\n","import {\n DOMAIN_OWNERSHIP_DEFAULT_EXPIRATION_SECS,\n DOMAIN_OWNERSHIP_METHOD,\n DOMAIN_OWNERSHIP_SCHEMA_DEF,\n DOMAIN_OWNERSHIP_SCHEMA_NAME,\n DOMAIN_OWNERSHIP_SCOPE_REGISTRABLE,\n assessDomainOwnership,\n decodeDomainOwnershipData,\n getDomainOwnershipFromEas,\n hashDomainOwnershipChallenge,\n type DomainOwnershipAssessResult,\n type DomainOwnershipDecoded,\n} from '@seedprotocol/eas'\nimport { SchemaEncoder, ZERO_BYTES32 } from '@ethereum-attestation-service/eas-sdk'\nimport { SchemaRegistry } from '@ethereum-attestation-service/eas-sdk'\nimport { prepareEasAttest, prepareEasMultiRevoke } from '~/helpers/easDirect'\nimport { getSchemaRecord, registerSchema } from '~/helpers/schemaRegistry'\nimport { prepareNameSchemaAttestation } from '~/helpers/nameSchemaAttestation'\nimport { waitForPublishReceipt } from '~/helpers/chainClient'\nimport { getPublishConfig } from '~/config'\nimport {\n isPublishWallet,\n isSeedTxSender,\n type PublishWallet,\n type SeedTxSender,\n} from '~/helpers/seedSigner'\nimport { getAttestationUidFromReceipt } from '~/helpers/easDirect'\nimport { normalizeBytes32Hex, isValidEasAttestationUid } from '@seedprotocol/eas'\nimport {\n createDomainOwnershipChallenge,\n type DomainOwnershipChallenge,\n} from './challenge'\nimport { verifyDomainOwnershipDns, type VerifyDomainOwnershipDnsResult } from './dnsVerify'\nimport {\n fingerprintFromRegistrySnapshot,\n lookupDomainRegistry,\n normalizeHostname,\n normalizeRegistrableDomain,\n type DomainRegistrySnapshot,\n} from './registry'\n\nexport {\n DOMAIN_OWNERSHIP_SCHEMA_DEF,\n DOMAIN_OWNERSHIP_SCHEMA_NAME,\n DOMAIN_OWNERSHIP_METHOD,\n DOMAIN_OWNERSHIP_SCOPE_HOSTNAME,\n DOMAIN_OWNERSHIP_SCOPE_REGISTRABLE,\n} from '@seedprotocol/eas'\n\nexport { createDomainOwnershipChallenge }\nexport type { DomainOwnershipChallenge }\nexport { verifyDomainOwnershipDns }\nexport type { VerifyDomainOwnershipDnsResult }\nexport { lookupDomainRegistry, normalizeRegistrableDomain, fingerprintFromRegistrySnapshot }\nexport type { DomainRegistrySnapshot }\n\nconst RESOLVER_ADDRESS = '0x0000000000000000000000000000000000000000'\nconst REVOCABLE = true\n\nfunction resolveTxSender(account: PublishWallet | SeedTxSender): SeedTxSender {\n if (isPublishWallet(account)) return account.txSender\n if (isSeedTxSender(account)) return account\n throw new Error(\n '@seedprotocol/publish: domain ownership write APIs require a PublishWallet or SeedTxSender',\n )\n}\n\nasync function sendAndWait(\n txSender: SeedTxSender,\n tx: Parameters<SeedTxSender['sendTransaction']>[0],\n) {\n const result = await txSender.sendTransaction(tx)\n return waitForPublishReceipt(result.transactionHash)\n}\n\n/** Deterministic on-chain schema UID for {@link DOMAIN_OWNERSHIP_SCHEMA_DEF}. */\nexport function getDomainOwnershipSchemaUid(): `0x${string}` {\n return SchemaRegistry.getSchemaUID(\n DOMAIN_OWNERSHIP_SCHEMA_DEF,\n RESOLVER_ADDRESS as `0x${string}`,\n REVOCABLE,\n ) as `0x${string}`\n}\n\n/**\n * Registers the DomainOwnership EAS schema (if missing) and creates a Schema #1 name attestation.\n */\nexport async function ensureDomainOwnershipSchema(\n account: PublishWallet | SeedTxSender,\n): Promise<`0x${string}`> {\n const sender = resolveTxSender(account)\n const schemaUid = getDomainOwnershipSchemaUid()\n const onChain = await getSchemaRecord(schemaUid)\n if (!onChain) {\n await sendAndWait(\n sender,\n registerSchema({\n schema: DOMAIN_OWNERSHIP_SCHEMA_DEF,\n resolverAddress: RESOLVER_ADDRESS,\n revocable: REVOCABLE,\n }),\n )\n await sendAndWait(\n sender,\n prepareNameSchemaAttestation({\n schemaUid,\n schemaName: DOMAIN_OWNERSHIP_SCHEMA_NAME,\n }),\n )\n }\n return schemaUid\n}\n\nexport function encodeDomainOwnershipAttestationData(params: {\n domain: string\n claimer: string\n method: string\n challengeHash: string\n verifiedAt: number\n registryCreationDate: string\n registryExpirationDate: string\n registryFingerprint: string\n scope: string\n}): `0x${string}` {\n const schemaEncoder = new SchemaEncoder(DOMAIN_OWNERSHIP_SCHEMA_DEF)\n const encodedData = schemaEncoder.encodeData([\n { name: 'domain', value: params.domain, type: 'string' },\n { name: 'claimer', value: params.claimer as `0x${string}`, type: 'address' },\n { name: 'method', value: params.method, type: 'string' },\n {\n name: 'challengeHash',\n value: normalizeBytes32Hex(params.challengeHash) as `0x${string}`,\n type: 'bytes32',\n },\n { name: 'verifiedAt', value: params.verifiedAt, type: 'uint64' },\n { name: 'registryCreationDate', value: params.registryCreationDate, type: 'string' },\n {\n name: 'registryExpirationDate',\n value: params.registryExpirationDate,\n type: 'string',\n },\n {\n name: 'registryFingerprint',\n value: normalizeBytes32Hex(params.registryFingerprint) as `0x${string}`,\n type: 'bytes32',\n },\n { name: 'scope', value: params.scope, type: 'string' },\n ])\n return encodedData as `0x${string}`\n}\n\nexport type AttestDomainOwnershipParams = {\n wallet: PublishWallet | SeedTxSender\n domain: string\n claimer: string\n challengeHash: string\n registrySnapshot: DomainRegistrySnapshot\n scope?: string\n method?: string\n verifiedAt?: number\n /** When true (default), register + name the schema if missing. */\n ensureSchema?: boolean\n /** Override EAS expirationTime (unix seconds). */\n expirationTime?: number\n}\n\nexport type AttestDomainOwnershipResult = {\n uid: `0x${string}`\n schemaUid: `0x${string}`\n challengeHash: `0x${string}`\n registryFingerprint: `0x${string}`\n verifiedAt: number\n expirationTime: number\n}\n\nfunction resolveExpirationTime(params: {\n verifiedAt: number\n registryExpirationDate?: string\n override?: number\n}): number {\n if (typeof params.override === 'number' && params.override > 0) return params.override\n if (params.registryExpirationDate) {\n const ms = Date.parse(params.registryExpirationDate)\n if (Number.isFinite(ms) && ms > 0) return Math.floor(ms / 1000)\n }\n return params.verifiedAt + DOMAIN_OWNERSHIP_DEFAULT_EXPIRATION_SECS\n}\n\n/**\n * Tool wallet attests domain ownership after off-chain DNS + RDAP verification.\n */\nexport async function attestDomainOwnership(\n params: AttestDomainOwnershipParams,\n): Promise<AttestDomainOwnershipResult> {\n const sender = resolveTxSender(params.wallet)\n const schemaUid =\n params.ensureSchema === false\n ? getDomainOwnershipSchemaUid()\n : await ensureDomainOwnershipSchema(params.wallet)\n\n const scope = params.scope ?? DOMAIN_OWNERSHIP_SCOPE_REGISTRABLE\n // Record the domain the challenge was on: a hostname-scoped challenge must not be widened to\n // its registrable domain.\n const domain =\n scope === DOMAIN_OWNERSHIP_SCOPE_REGISTRABLE\n ? normalizeRegistrableDomain(params.domain)\n : normalizeHostname(params.domain)\n const claimer = params.claimer.trim()\n if (!/^0x[0-9a-fA-F]{40}$/.test(claimer)) {\n throw new Error('@seedprotocol/publish: attestDomainOwnership requires a valid claimer address')\n }\n\n const challengeHash = normalizeBytes32Hex(params.challengeHash) as `0x${string}`\n if (challengeHash === ZERO_BYTES32) {\n throw new Error('@seedprotocol/publish: attestDomainOwnership requires a non-zero challengeHash')\n }\n\n const verifiedAt = params.verifiedAt ?? Math.floor(Date.now() / 1000)\n const registryFingerprint = fingerprintFromRegistrySnapshot({\n domain,\n creationDate: params.registrySnapshot.creationDate ?? '',\n registrarIanaId: params.registrySnapshot.registrarIanaId ?? '',\n })\n const registryCreationDate = params.registrySnapshot.creationDate ?? ''\n const registryExpirationDate = params.registrySnapshot.expirationDate ?? ''\n const method = params.method ?? DOMAIN_OWNERSHIP_METHOD\n const expirationTime = resolveExpirationTime({\n verifiedAt,\n registryExpirationDate,\n override: params.expirationTime,\n })\n\n const data = encodeDomainOwnershipAttestationData({\n domain,\n claimer,\n method,\n challengeHash,\n verifiedAt,\n registryCreationDate,\n registryExpirationDate,\n registryFingerprint,\n scope,\n })\n\n const tx = prepareEasAttest({\n schema: schemaUid,\n data: {\n recipient: claimer as `0x${string}`,\n expirationTime: BigInt(expirationTime),\n revocable: true,\n refUID: ZERO_BYTES32 as `0x${string}`,\n data,\n value: 0n,\n },\n })\n\n const receipt = await sendAndWait(sender, tx)\n if (!receipt) {\n throw new Error('@seedprotocol/publish: attestDomainOwnership failed — no receipt')\n }\n const { easContractAddress } = getPublishConfig()\n const uid = getAttestationUidFromReceipt(receipt, easContractAddress)\n if (!uid || !isValidEasAttestationUid(uid)) {\n throw new Error(\n '@seedprotocol/publish: attestDomainOwnership failed — could not parse attestation UID',\n )\n }\n\n return {\n uid: uid as `0x${string}`,\n schemaUid,\n challengeHash,\n registryFingerprint,\n verifiedAt,\n expirationTime,\n }\n}\n\n/**\n * Revoke a DomainOwnership sidecar attestation (must be signed by the original tool attester).\n */\nexport async function revokeDomainOwnership(params: {\n wallet: PublishWallet | SeedTxSender\n uid: string\n schemaUid?: string\n}): Promise<void> {\n const sender = resolveTxSender(params.wallet)\n const schemaUid = (params.schemaUid ?? getDomainOwnershipSchemaUid()) as `0x${string}`\n const uid = normalizeBytes32Hex(params.uid) as `0x${string}`\n if (!isValidEasAttestationUid(uid)) {\n throw new Error('@seedprotocol/publish: revokeDomainOwnership requires a valid attestation uid')\n }\n\n const tx = prepareEasMultiRevoke([\n {\n schema: schemaUid,\n data: [{ uid }],\n },\n ])\n const receipt = await sendAndWait(sender, tx)\n if (!receipt) {\n throw new Error('@seedprotocol/publish: revokeDomainOwnership failed — no receipt')\n }\n}\n\nexport type VerifyDomainOwnershipChallengeResult = {\n ok: boolean\n dns: VerifyDomainOwnershipDnsResult\n registrySnapshot: DomainRegistrySnapshot | null\n challengeHash: `0x${string}`\n error?: string\n}\n\n/**\n * Verify DNS TXT for a caller-held challenge and fetch an RDAP registry snapshot.\n * Does not write an attestation.\n */\nexport async function verifyDomainOwnershipChallenge(params: {\n challenge: DomainOwnershipChallenge\n /** Injected DNS lookups for tests. */\n dnsLookups?: Array<\n (name: string) => Promise<{ source: string; values: string[]; dnssecAuthenticated?: boolean }>\n >\n /** Injected registry lookup for tests. */\n registryLookup?: (domain: string) => Promise<DomainRegistrySnapshot | null>\n now?: number\n}): Promise<VerifyDomainOwnershipChallengeResult> {\n const { challenge } = params\n const expectedHash = hashDomainOwnershipChallenge({\n domain: challenge.domain,\n claimer: challenge.claimer,\n token: challenge.token,\n scope: challenge.scope,\n })\n if (normalizeBytes32Hex(expectedHash) !== normalizeBytes32Hex(challenge.challengeHash)) {\n return {\n ok: false,\n dns: { ok: false, matchedSources: [], lookups: [], error: 'challengeHash mismatch' },\n registrySnapshot: null,\n challengeHash: expectedHash,\n error: 'Challenge hash does not match domain/claimer/token/scope',\n }\n }\n\n const dns = await verifyDomainOwnershipDns(challenge, {\n lookups: params.dnsLookups,\n now: params.now,\n })\n if (!dns.ok) {\n return {\n ok: false,\n dns,\n registrySnapshot: null,\n challengeHash: expectedHash,\n error: dns.error ?? 'DNS verification failed',\n }\n }\n\n const registryLookup = params.registryLookup ?? lookupDomainRegistry\n let registrySnapshot: DomainRegistrySnapshot | null\n try {\n registrySnapshot = await registryLookup(challenge.domain)\n } catch {\n registrySnapshot = null\n }\n\n if (!registrySnapshot) {\n return {\n ok: false,\n dns,\n registrySnapshot: null,\n challengeHash: expectedHash,\n error: 'Registry lookup failed',\n }\n }\n\n return {\n ok: true,\n dns,\n registrySnapshot,\n challengeHash: expectedHash,\n }\n}\n\nexport type VerifyAndAttestDomainOwnershipResult = AttestDomainOwnershipResult & {\n registrySnapshot: DomainRegistrySnapshot\n dns: VerifyDomainOwnershipDnsResult\n}\n\n/**\n * Verify DNS + RDAP, then attest from the tool wallet.\n */\nexport async function verifyAndAttestDomainOwnership(params: {\n challenge: DomainOwnershipChallenge\n wallet: PublishWallet | SeedTxSender\n ensureSchema?: boolean\n dnsLookups?: Array<\n (name: string) => Promise<{ source: string; values: string[]; dnssecAuthenticated?: boolean }>\n >\n registryLookup?: (domain: string) => Promise<DomainRegistrySnapshot | null>\n now?: number\n}): Promise<VerifyAndAttestDomainOwnershipResult> {\n const verified = await verifyDomainOwnershipChallenge({\n challenge: params.challenge,\n dnsLookups: params.dnsLookups,\n registryLookup: params.registryLookup,\n now: params.now,\n })\n if (!verified.ok || !verified.registrySnapshot) {\n throw new Error(\n `@seedprotocol/publish: verifyAndAttestDomainOwnership failed — ${verified.error ?? 'verification failed'}`,\n )\n }\n\n const attested = await attestDomainOwnership({\n wallet: params.wallet,\n domain: params.challenge.domain,\n claimer: params.challenge.claimer,\n challengeHash: verified.challengeHash,\n registrySnapshot: verified.registrySnapshot,\n scope: params.challenge.scope,\n method: params.challenge.method,\n ensureSchema: params.ensureSchema,\n })\n\n return {\n ...attested,\n registrySnapshot: verified.registrySnapshot,\n dns: verified.dns,\n }\n}\n\nexport type AssessDomainOwnershipLiveResult = DomainOwnershipAssessResult & {\n decoded: DomainOwnershipDecoded\n uid: string\n registrySnapshot: DomainRegistrySnapshot | null\n}\n\n/**\n * Load a DomainOwnership attestation (by UID via tool allowlist query) and recheck RDAP.\n */\nexport async function assessDomainOwnershipLive(params: {\n uid: string\n toolAddresses: string[]\n schemaUid?: string\n registryLookup?: (domain: string) => Promise<DomainRegistrySnapshot | null>\n now?: number\n}): Promise<AssessDomainOwnershipLiveResult> {\n const rows = await getDomainOwnershipFromEas({\n toolAddresses: params.toolAddresses,\n schemaUid: params.schemaUid,\n excludeRevoked: true,\n })\n const row = rows.find((r) => normalizeBytes32Hex(r.id) === normalizeBytes32Hex(params.uid))\n if (!row) {\n throw new Error(\n '@seedprotocol/publish: assessDomainOwnershipLive could not find attestation for uid/toolAddresses',\n )\n }\n const decoded = decodeDomainOwnershipData(row.decodedDataJson ?? '[]')\n const registryLookup = params.registryLookup ?? lookupDomainRegistry\n let registrySnapshot: DomainRegistrySnapshot | null\n try {\n registrySnapshot = await registryLookup(decoded.domain)\n } catch {\n registrySnapshot = null\n }\n\n const assessed = assessDomainOwnership({\n decoded,\n expirationTime: row.expirationTime,\n registrySnapshot,\n now: params.now,\n })\n\n return {\n ...assessed,\n decoded,\n uid: row.id,\n registrySnapshot,\n }\n}\n","import {\n PUBLISHED_BY_SCHEMA_DEF,\n PUBLISHED_BY_SCHEMA_NAME,\n hashPublishedByBatch,\n type PublishedByDecoded,\n} from '@seedprotocol/eas'\nimport { SchemaEncoder, NO_EXPIRATION, ZERO_BYTES32 } from '@ethereum-attestation-service/eas-sdk'\nimport { SchemaRegistry } from '@ethereum-attestation-service/eas-sdk'\nimport { prepareEasAttest, prepareEasMultiRevoke, ZERO_ADDRESS } from '~/helpers/easDirect'\nimport { getSchemaRecord, registerSchema } from '~/helpers/schemaRegistry'\nimport { prepareNameSchemaAttestation } from '~/helpers/nameSchemaAttestation'\nimport { waitForPublishReceipt } from '~/helpers/chainClient'\nimport { getPublishConfig } from '~/config'\nimport {\n isPublishWallet,\n isSeedTxSender,\n type PublishWallet,\n type SeedTxSender,\n} from '~/helpers/seedSigner'\nimport { getAttestationUidFromReceipt } from '~/helpers/easDirect'\nimport { normalizeBytes32Hex, isValidEasAttestationUid } from '@seedprotocol/eas'\n\nexport {\n PUBLISHED_BY_SCHEMA_DEF,\n PUBLISHED_BY_SCHEMA_NAME,\n hashPublishedByBatch,\n} from '@seedprotocol/eas'\n\nconst RESOLVER_ADDRESS = '0x0000000000000000000000000000000000000000'\nconst REVOCABLE = true\n\nexport type PublishedBatchResult = {\n seedUid: `0x${string}`\n versionUid?: `0x${string}`\n attestationUids: `0x${string}`[]\n}\n\nexport type OnPublishedCallback = (\n result: PublishedBatchResult & { seedLocalId: string },\n) => void | Promise<void>\n\nexport type AttestPublishedByUidsMode = {\n mode: 'uids'\n attestationUids: readonly string[]\n /** Optional override; defaults to hash of sorted attestationUids. */\n batchHash?: string\n}\n\nexport type AttestPublishedByHashMode = {\n mode: 'hash'\n batchHash: string\n /** On-chain array is empty; keep the full list off-chain for verification. */\n attestationUids?: never\n}\n\nexport type AttestPublishedByParams = {\n wallet: PublishWallet | SeedTxSender\n seedUid: string\n versionUid?: string\n toolName: string\n toolVersion: string\n /**\n * When true (default), register + name the PublishedBy schema if missing.\n */\n ensureSchema?: boolean\n} & (AttestPublishedByUidsMode | AttestPublishedByHashMode)\n\nexport type AttestPublishedByResult = {\n uid: `0x${string}`\n schemaUid: `0x${string}`\n batchHash: `0x${string}`\n attestationUids: `0x${string}`[]\n}\n\nfunction resolveTxSender(account: PublishWallet | SeedTxSender): SeedTxSender {\n if (isPublishWallet(account)) return account.txSender\n if (isSeedTxSender(account)) return account\n throw new Error(\n '@seedprotocol/publish: attestPublishedBy / revokePublishedBy require a PublishWallet or SeedTxSender',\n )\n}\n\nasync function sendAndWait(txSender: SeedTxSender, tx: Parameters<SeedTxSender['sendTransaction']>[0]) {\n const result = await txSender.sendTransaction(tx)\n return waitForPublishReceipt(result.transactionHash)\n}\n\n/** Deterministic on-chain schema UID for {@link PUBLISHED_BY_SCHEMA_DEF}. */\nexport function getPublishedBySchemaUid(): `0x${string}` {\n return SchemaRegistry.getSchemaUID(\n PUBLISHED_BY_SCHEMA_DEF,\n RESOLVER_ADDRESS as `0x${string}`,\n REVOCABLE,\n ) as `0x${string}`\n}\n\n/**\n * Registers the PublishedBy EAS schema (if missing) and creates a Schema #1 name attestation.\n */\nexport async function ensurePublishedBySchema(\n account: PublishWallet | SeedTxSender,\n): Promise<`0x${string}`> {\n const sender = resolveTxSender(account)\n const schemaUid = getPublishedBySchemaUid()\n const onChain = await getSchemaRecord(schemaUid)\n if (!onChain) {\n await sendAndWait(\n sender,\n registerSchema({\n schema: PUBLISHED_BY_SCHEMA_DEF,\n resolverAddress: RESOLVER_ADDRESS,\n revocable: REVOCABLE,\n }),\n )\n await sendAndWait(\n sender,\n prepareNameSchemaAttestation({\n schemaUid,\n schemaName: PUBLISHED_BY_SCHEMA_NAME,\n }),\n )\n }\n return schemaUid\n}\n\nexport function encodePublishedByAttestationData(params: {\n seedUid: string\n versionUid: string\n attestationUids: readonly string[]\n batchHash: string\n toolName: string\n toolVersion: string\n}): `0x${string}` {\n const schemaEncoder = new SchemaEncoder(PUBLISHED_BY_SCHEMA_DEF)\n const encodedData = schemaEncoder.encodeData([\n { name: 'seedUid', value: normalizeBytes32Hex(params.seedUid) as `0x${string}`, type: 'bytes32' },\n {\n name: 'versionUid',\n value: normalizeBytes32Hex(params.versionUid || ZERO_BYTES32) as `0x${string}`,\n type: 'bytes32',\n },\n {\n name: 'attestationUids',\n value: params.attestationUids.map((u) => normalizeBytes32Hex(u) as `0x${string}`),\n type: 'bytes32[]',\n },\n {\n name: 'batchHash',\n value: normalizeBytes32Hex(params.batchHash) as `0x${string}`,\n type: 'bytes32',\n },\n { name: 'toolName', value: params.toolName, type: 'string' },\n { name: 'toolVersion', value: params.toolVersion, type: 'string' },\n ])\n return encodedData as `0x${string}`\n}\n\n/**\n * Tool wallet attests a PublishedBy sidecar for a publish batch.\n * - `mode: 'uids'`: on-chain UID list + batchHash of sorted UIDs\n * - `mode: 'hash'`: empty UID list + caller-supplied batchHash (full list kept off-chain)\n */\nexport async function attestPublishedBy(\n params: AttestPublishedByParams,\n): Promise<AttestPublishedByResult> {\n const sender = resolveTxSender(params.wallet)\n const schemaUid =\n params.ensureSchema === false\n ? getPublishedBySchemaUid()\n : await ensurePublishedBySchema(params.wallet)\n\n let attestationUids: `0x${string}`[] = []\n let batchHash: `0x${string}`\n\n if (params.mode === 'uids') {\n attestationUids = params.attestationUids\n .map((u) => normalizeBytes32Hex(u) as `0x${string}`)\n .filter((u) => isValidEasAttestationUid(u))\n batchHash = (params.batchHash\n ? normalizeBytes32Hex(params.batchHash)\n : hashPublishedByBatch(attestationUids)) as `0x${string}`\n } else {\n if (!params.batchHash) {\n throw new Error('@seedprotocol/publish: attestPublishedBy hash mode requires batchHash')\n }\n batchHash = normalizeBytes32Hex(params.batchHash) as `0x${string}`\n if (batchHash === ZERO_BYTES32) {\n throw new Error('@seedprotocol/publish: attestPublishedBy hash mode requires a non-zero batchHash')\n }\n }\n\n const seedUid = normalizeBytes32Hex(params.seedUid) as `0x${string}`\n if (!isValidEasAttestationUid(seedUid)) {\n throw new Error('@seedprotocol/publish: attestPublishedBy requires a valid seedUid')\n }\n\n const versionUid = normalizeBytes32Hex(params.versionUid ?? ZERO_BYTES32) as `0x${string}`\n const data = encodePublishedByAttestationData({\n seedUid,\n versionUid,\n attestationUids,\n batchHash,\n toolName: params.toolName,\n toolVersion: params.toolVersion,\n })\n\n const tx = prepareEasAttest({\n schema: schemaUid,\n data: {\n recipient: ZERO_ADDRESS as `0x${string}`,\n expirationTime: BigInt(NO_EXPIRATION),\n revocable: true,\n refUID: seedUid,\n data,\n value: 0n,\n },\n })\n\n const receipt = await sendAndWait(sender, tx)\n if (!receipt) {\n throw new Error('@seedprotocol/publish: attestPublishedBy failed — no receipt')\n }\n const { easContractAddress } = getPublishConfig()\n const uid = getAttestationUidFromReceipt(receipt, easContractAddress)\n if (!uid || !isValidEasAttestationUid(uid)) {\n throw new Error('@seedprotocol/publish: attestPublishedBy failed — could not parse attestation UID')\n }\n\n return {\n uid: uid as `0x${string}`,\n schemaUid,\n batchHash,\n attestationUids,\n }\n}\n\n/**\n * Revoke a PublishedBy sidecar attestation (must be signed by the original tool attester).\n */\nexport async function revokePublishedBy(params: {\n wallet: PublishWallet | SeedTxSender\n uid: string\n schemaUid?: string\n}): Promise<void> {\n const sender = resolveTxSender(params.wallet)\n const schemaUid = (params.schemaUid ?? getPublishedBySchemaUid()) as `0x${string}`\n const uid = normalizeBytes32Hex(params.uid) as `0x${string}`\n if (!isValidEasAttestationUid(uid)) {\n throw new Error('@seedprotocol/publish: revokePublishedBy requires a valid attestation uid')\n }\n\n const tx = prepareEasMultiRevoke([\n {\n schema: schemaUid,\n data: [{ uid }],\n },\n ])\n const receipt = await sendAndWait(sender, tx)\n if (!receipt) {\n throw new Error('@seedprotocol/publish: revokePublishedBy failed — no receipt')\n }\n}\n\nexport type { PublishedByDecoded }\n\nexport { collectPublishedBatch, uidsFromAttestationPairs } from './collectBatchUids'\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.js","names":["SeedProvider","DOMAIN_OWNERSHIP_METHOD","RESOLVER_ADDRESS","REVOCABLE","resolveTxSender","sendAndWait","DOMAIN_OWNERSHIP_SCHEMA_DEF","DOMAIN_OWNERSHIP_SCHEMA_NAME","DOMAIN_OWNERSHIP_METHOD","isValidEasAttestationUid","PUBLISHED_BY_SCHEMA_DEF","PUBLISHED_BY_SCHEMA_NAME","isValidEasAttestationUid","hashPublishedByBatch","ZERO_ADDRESS","DEFAULT_TURBO_PAYMENT_URL","registerSchema","prepareEasMultiRevoke","getPublishPublicClient","PUBLISH_GAS_HEURISTICS","fromEthersWallet","ensureEasSchemasForItem","ZERO_ADDRESS$1","ensureManagedAccountEasConfigured","isSeedTxSender","assertExecutorModuleReadyForAccount","encodeSetEas","AttestationVerificationError","simulateCallFromAccount","readFactorySeedExecutor","PublishTransactionRevertedError","Eip7702ModularAccountPublishError","readGetEas","encodeEasMultiAttest","encodeEasMultiRevoke","prepareNameSchemaAttestation","getAttestationUidFromReceipt","encodeMultiPublish","stringifyUnderlyingCause","readIsActiveSigner","getArweave","brandTxSender","assertManagedAccountEasMatchesConfig","isSeedSigner","isContractDeployed","waitForPublishReceipt","isManagedAccountPublishError","isEip7702ModularAccountPublishError","isRouterNonModularCoreAccountError","estimatePublishCost","getPublishConfig","MANAGED_ACCOUNT_FACTORY_ADDRESSES","PUBLISH_AUTHORIZATION_HEADER","getCachedTokenPrices","asSeedTxSender","resolvePublishEasChain","SEED_PROTOCOL_CONTRACT_ADDRESS_OP_SEPOLIA","getTurboBalanceWinc","ensureWalletThenPublish","verifyDataItem","DEFAULT_TURBO_UPLOAD_URL","PublishChainConfigError","combinePublishCostEstimate","publishMachine","getConfigRef","DEFAULT_PUBLISH_CHAIN","encodeEasAttest","getSchemaRecord","prepareEasAttest","publishItem","getTurboPriceWinc","PublishManager","getPublishViemChain","resolvePublishPayment","initPublish","MULTI_PUBLISH_ABI_REFERENCE_ADDRESS_OP_SEPOLIA","PublishNotAuthorizedError","createPermissionlessTxSender","verifyPublishChain","ManagedAccountPublishError","configurePublish","resolvePublishSender","requireManagedAccountFactoryAddress","PublishMachineStates","InsufficientStorageCreditsError","getPublishChainName","PublishPaymentConfigError","waitForPublishActor","buildPublishAnchorBytes","getCachedMarketRates","asPublishWallet","heuristicPublishGas","isPublishWallet","resetTokenPriceCache","brandSigner","resetMarketRateCache","asSeedSigner","setPublishWallet","getPublishWallet","clearPublishWallet","attestPublishAuthorization","getPublishAuthorizationSchemaUid","usePublishConfig","PublishConfigContext","assessPublishAuthorizationLive","revokePublishAuthorization","PUBLISH_AUTHORIZATION_SCHEMA_NAME","encodePublishAuthorizationAttestationData","PUBLISH_AUTHORIZATION_SCOPES","ensurePublishAuthorizationSchema","PUBLISH_AUTHORIZATION_SCHEMA_DEF","collectPublishedBatch","uidsFromAttestationPairs","DOMAIN_OWNERSHIP_METHOD$1","DOMAIN_OWNERSHIP_SCHEMA_DEF$1","DOMAIN_OWNERSHIP_SCHEMA_NAME$1","PUBLISHED_BY_SCHEMA_DEF$1","PUBLISHED_BY_SCHEMA_NAME$1","hashPublishedByBatch$1","isValidEasAttestationUid$1","SeedProvider$1","seedTwinConfig","missing","twin","value","key","forkName","chain","defineChain","PublishModeButtons","ariaLabel","base","btn","active","disabled","onChange","PublishProvider","initializedConfig","useRef","config","fromEip1193Provider","options","address","accounts","provider","walletClient","createWalletClient","custom","message","tx","fromWindowEthereum","eth","useSeedWallet","session","setSession","useState","status","setStatus","connect","useCallback","wallet","input","payment","txSender","next","err","disconnect","DEFAULT_PRICE_REFRESH_MS","DEFAULT_ITEM_IDLE_MS","DEFAULT_FIRST_ESTIMATE_RETRY_MS","propertyFingerprintValue","snapshot","prop","itemPublishFingerprint","props","item","watchItemRowsByFeed","isChangeFeedRunning","watchEntityChanges","asError","watchPublishCost","priceRefreshMs","itemIdleMs","firstEstimateRetryMs","estimateFn","target","repriceFn","rates","prev","disposed","lastFingerprint","lastEstimate","isEstimating","isStale","hasEstimated","hasRetried","error","runId","idleTimer","priceTimer","retryTimer","emit","runEstimate","id","scheduleItemEstimate","refresh","subscription","fingerprint","unwatchRows","unwatch","getDisplayStepId","machineValue","resolvePublishDisplayValue","publishProcess","record","getPublishMachineValueForUi","p","isTerminalDoneSnapshot","usePublishProcess","publishManager","useSelector","seedLocalId","lastPublishSnapshotRef","setMachineValue","terminalLatch","setTerminalLatch","db","BaseDb","latestProcessRowQuery","useMemo","publishProcesses","eq","desc","latestRecord","useLiveQuery","recordStatus","fromRow","useEffect","last","initial","sub","useCanPublishItem","canPublish","setCanPublish","addressRevision","useSeedAddressRevision","current","isItemOwned","owned","useArweaveL1Finalize","jobsQuery","arweaveL1FinalizeJobs","jobs","pending","j","confirmed","useItemPublishStatus","arweaveL1","usePublishProcessesQuery","usePublishProcessesQueryForSeed","usePublishProcessesState","query","records","r","usePublishProcesses","usePublishProcessesNonActiveCount","usePublishProcessesForSeed","usePublishProcessesStateForSeed","usePublishProcessesNonActiveCountForSeed","usePublishProcessById","isLoading","clearCompletedPublishProcesses","notInArray","clearCompletedPublishProcessesForSeed","and","clearAllPublishProcesses","clearAllUploadProcesses","uploadProcesses","deletePublishProcessesForSeed","deletePublishProcessById","deletePublishProcessesByIds","ids","inArray","getArweaveTransactionIds","at","getEasPayload","usePublishCostEstimate","estimate","setEstimate","setIsEstimating","setIsStale","setError","refreshRef","lastEstimateRef","publishMode","previousEstimate","handle","normalizeRegistrableDomain","normalized","toRegistrableDomain","normalizeHostname","lookupDomainRegistry","registrable","domain","result","lookup","fingerprintFromRegistrySnapshot","hashDomainRegistryFingerprint","randomBytes","bytes","size","base64Url","binary","byte","createDomainOwnershipChallenge","hostnameOnly","params","claimer","scope","DOMAIN_OWNERSHIP_SCOPE_HOSTNAME","DOMAIN_OWNERSHIP_SCOPE_REGISTRABLE","ttlMs","DOMAIN_OWNERSHIP_CHALLENGE_TTL_MS","now","expiresAt","token","challengeHash","hashDomainOwnershipChallenge","txtName","domainOwnershipTxtName","txtValue","buildDomainOwnershipTxtValue","lookupNodeDns","dnsPromises","name","chunks","lookupDoh","url","endpoint","res","source","body","a","defaultLookups","lookups","valuesMatchExpected","expectedParsed","parseDomainOwnershipTxtValue","expected","v","values","parsed","verifyDomainOwnershipDns","challenge","lookupFns","quorum","matchedSources","dnssecMatch","fn","ok","RESOLVER_ADDRESS$1","REVOCABLE$1","resolveTxSender$1","account","sendAndWait$1","getDomainOwnershipSchemaUid","SchemaRegistry","ensureDomainOwnershipSchema","sender","schemaUid","encodeDomainOwnershipAttestationData","SchemaEncoder","normalizeBytes32Hex","resolveExpirationTime","ms","DOMAIN_OWNERSHIP_DEFAULT_EXPIRATION_SECS","attestDomainOwnership","ZERO_BYTES32","verifiedAt","registryFingerprint","registryCreationDate","registryExpirationDate","method","expirationTime","data","receipt","uid","easContractAddress","revokeDomainOwnership","verifyDomainOwnershipChallenge","expectedHash","dns","registryLookup","registrySnapshot","verifyAndAttestDomainOwnership","verified","assessDomainOwnershipLive","row","getDomainOwnershipFromEas","decoded","decodeDomainOwnershipData","assessDomainOwnership","RESOLVER_ADDRESS","REVOCABLE","resolveTxSender","sendAndWait","getPublishedBySchemaUid","ensurePublishedBySchema","encodePublishedByAttestationData","u","attestPublishedBy","attestationUids","batchHash","seedUid","NO_EXPIRATION","revokePublishedBy","DOMAIN_OWNERSHIP_METHOD","DOMAIN_OWNERSHIP_SCHEMA_DEF","DOMAIN_OWNERSHIP_SCHEMA_NAME","EAS_CHAIN_DEPLOYMENTS","PUBLISHED_BY_SCHEMA_DEF","PUBLISHED_BY_SCHEMA_NAME","SeedProvider","getEasChainDeployment","hashPublishedByBatch"],"sources":["../src/helpers/seedTwin.ts","../src/react/PublishModeButtons.tsx","../src/react/PublishProvider.tsx","../src/helpers/adapters/eip1193.ts","../src/react/useSeedWallet.ts","../src/services/publishCost/watchPublishCost.ts","../src/helpers/publishDisplayHelpers.ts","../src/hooks/usePublishProcess.ts","../src/hooks/useCanPublishItem.ts","../src/hooks/useArweaveL1Finalize.ts","../src/hooks/useItemPublishStatus.ts","../src/hooks/usePublishProcesses.ts","../src/hooks/clearCompletedPublishProcesses.ts","../src/hooks/publishProcessHelpers.ts","../src/hooks/usePublishCostEstimate.ts","../src/services/domainOwnership/registry.ts","../src/services/domainOwnership/challenge.ts","../src/services/domainOwnership/dnsVerify.ts","../src/services/domainOwnership/index.ts","../src/services/publishedBy/index.ts"],"sourcesContent":["import { defineChain, type Chain } from 'viem'\nimport type { PublishConfig } from '../config'\n\n/**\n * The parts of seed-protocol's `.twin/twin.json` (written by `bun run twin:up`) that apps need.\n * Its test-account keys are deliberately not part of this type.\n */\nexport interface SeedTwinInfo {\n chainId: number\n rpcUrl: string\n bundlerUrl: string\n easGraphqlUrl: string\n contracts: {\n eas: string\n schemaRegistry: string\n managedAccountFactory: string\n seedProtocolExecutor: string\n }\n forkedFrom?: { chain?: string; chainId?: number; block?: number }\n}\n\nexport type SeedTwinPublishConfig = Pick<\n PublishConfig,\n | 'chain'\n | 'rpcUrl'\n | 'easContractAddress'\n | 'schemaRegistryAddress'\n | 'managedAccountFactoryAddress'\n | 'modularAccountModuleContract'\n | 'thirdweb'\n>\n\n/**\n * Publish and SDK settings for the protocol's local OP Sepolia twin, from its `twin.json`.\n * Spread `publish` into `initPublish` and `eas` into `SeedConfig`:\n *\n * ```ts\n * const twin = seedTwinConfig(twinJson)\n * initPublish({ ...twin.publish, uploadApiBaseUrl, thirdwebClientId, useModularExecutor: true })\n * client.init({ config: { ...config, eas: twin.eas, filesDir: `.seed-${twin.chain.id}` } })\n * ```\n *\n * The twin has no paymaster or Thirdweb EIP-7702 service, so `thirdweb` turns sponsorship off,\n * uses the twin's bundler and sends admin transactions from a plain EOA. Fund the ManagedAccount\n * and the in-app EOA with `bun run twin:fund` before publishing.\n */\nexport function seedTwinConfig(twin: SeedTwinInfo): {\n chain: Chain\n publish: SeedTwinPublishConfig\n eas: { chainId: number; indexerUrl: string }\n} {\n const missing = (\n [\n ['chainId', twin?.chainId],\n ['rpcUrl', twin?.rpcUrl],\n ['bundlerUrl', twin?.bundlerUrl],\n ['easGraphqlUrl', twin?.easGraphqlUrl],\n ['contracts.eas', twin?.contracts?.eas],\n ['contracts.schemaRegistry', twin?.contracts?.schemaRegistry],\n ['contracts.managedAccountFactory', twin?.contracts?.managedAccountFactory],\n ['contracts.seedProtocolExecutor', twin?.contracts?.seedProtocolExecutor],\n ] as const\n )\n .filter(([, value]) => value === undefined || value === null || value === '')\n .map(([key]) => key)\n if (missing.length > 0) {\n throw new Error(`seedTwinConfig: twin.json is missing ${missing.join(', ')}. Re-run twin:up.`)\n }\n\n const forkName = twin.forkedFrom?.chain ? ` (${twin.forkedFrom.chain} fork)` : ''\n const chain = defineChain({\n id: twin.chainId,\n name: `Seed twin${forkName}`,\n nativeCurrency: { name: 'Ether', symbol: 'ETH', decimals: 18 },\n rpcUrls: { default: { http: [twin.rpcUrl] } },\n testnet: true,\n })\n\n return {\n chain,\n publish: {\n chain,\n rpcUrl: twin.rpcUrl,\n easContractAddress: twin.contracts.eas,\n schemaRegistryAddress: twin.contracts.schemaRegistry,\n managedAccountFactoryAddress: twin.contracts.managedAccountFactory,\n modularAccountModuleContract: twin.contracts.seedProtocolExecutor,\n thirdweb: { bundlerUrl: twin.bundlerUrl, sponsorGas: false, modularWalletMode: 'EOA' },\n },\n eas: { chainId: twin.chainId, indexerUrl: twin.easGraphqlUrl },\n }\n}\n","import React, { type FC } from 'react'\nimport type { PublishMode } from '../types'\n\nexport type PublishModeButtonsProps = {\n value: PublishMode\n onChange: (mode: PublishMode) => void\n disabled?: boolean\n /** Accessible label for the group */\n 'aria-label'?: string\n}\n\n/**\n * Optional control to choose patch (same Version) vs new Version before calling\n * `ensureSmartWalletThenPublish(item, …, { publishMode })` or `PublishManager.createPublish(…, { publishMode })`.\n */\nexport const PublishModeButtons: FC<PublishModeButtonsProps> = ({\n value,\n onChange,\n disabled = false,\n 'aria-label': ariaLabel = 'Publish mode',\n}) => {\n const base: React.CSSProperties = {\n display: 'inline-flex',\n gap: 8,\n flexWrap: 'wrap',\n }\n const btn = (active: boolean): React.CSSProperties => ({\n padding: '8px 14px',\n fontSize: 13,\n borderRadius: 8,\n border: `1px solid ${active ? '#344054' : '#D0D5DD'}`,\n background: active ? '#101828' : '#fff',\n color: active ? '#fff' : '#344054',\n cursor: disabled ? 'not-allowed' : 'pointer',\n opacity: disabled ? 0.6 : 1,\n })\n\n return (\n <div role=\"group\" aria-label={ariaLabel} style={base}>\n <button\n type=\"button\"\n disabled={disabled}\n style={btn(value === 'patch')}\n onClick={() => onChange('patch')}\n >\n Publish updates\n </button>\n <button\n type=\"button\"\n disabled={disabled}\n style={btn(value === 'new_version')}\n onClick={() => onChange('new_version')}\n >\n New version\n </button>\n </div>\n )\n}\n","import React, { FC, useRef } from \"react\"\nimport type { MutableRefObject } from \"react\"\nimport type { QueryClient } from \"@tanstack/react-query\"\nimport { SeedProvider } from '@seedprotocol/react'\nimport { initPublish, getConfigRef, type PublishConfig } from \"../config\"\nimport { PublishConfigContext, usePublishConfig } from \"./PublishConfigContext\"\n\nexport { usePublishConfig }\nexport type { PublishConfig }\n\nexport interface PublishProviderProps {\n children: React.ReactNode\n /**\n * If provided, calls initPublish with this config.\n * Otherwise, assumes initPublish was already called elsewhere.\n */\n config?: PublishConfig\n /** Optional: use your own QueryClient for Seed hooks. If not provided, SeedProvider creates one. */\n queryClient?: QueryClient\n /** Optional: ref to receive the QueryClient instance (e.g. for tests). */\n queryClientRef?: MutableRefObject<QueryClient | null>\n}\n\n/**\n * Core PublishProvider — no Thirdweb dependency.\n * For in-app wallets / ConnectButton, use `@seedprotocol/publish/thirdweb`.\n */\nconst PublishProvider: FC<PublishProviderProps> = ({\n children,\n config,\n queryClient,\n queryClientRef,\n}) => {\n // During render, not in an effect: children such as ConnectButton read the config on their\n // first render, which runs before this provider's effects. Once per config object.\n const initializedConfig = useRef<PublishConfig | undefined>(undefined)\n if (config && initializedConfig.current !== config) {\n initPublish(config)\n initializedConfig.current = config\n }\n\n return (\n <PublishConfigContext.Provider value={config ?? getConfigRef()}>\n <SeedProvider queryClient={queryClient} queryClientRef={queryClientRef}>\n {children}\n </SeedProvider>\n </PublishConfigContext.Provider>\n )\n}\n\nexport default PublishProvider\n","import {\n createWalletClient,\n custom,\n type Address,\n type Chain,\n type EIP1193Provider,\n type Hex,\n} from 'viem'\nimport {\n brandSigner,\n brandTxSender,\n type PublishWallet,\n type SeedSigner,\n type SeedTxSender,\n} from '../seedSigner'\nimport { getPublishViemChain } from '../chainConfig'\n\nexport type FromEip1193Options = {\n chain?: Chain\n /** If omitted, uses the first account from eth_requestAccounts / eth_accounts. */\n address?: Address\n}\n\n/**\n * Build a PublishWallet from an EIP-1193 provider (MetaMask, Rabby, injected wallets, etc.).\n * Transaction sends are EOA (user pays gas). Pair with permissionless for sponsored EIP-7702.\n */\nexport async function fromEip1193Provider(\n provider: EIP1193Provider,\n options: FromEip1193Options = {},\n): Promise<PublishWallet> {\n const chain = options.chain ?? getPublishViemChain()\n let address = options.address\n if (!address) {\n const accounts = (await provider.request({ method: 'eth_requestAccounts' })) as string[]\n if (!accounts?.[0]) {\n throw new Error('@seedprotocol/publish: EIP-1193 provider returned no accounts')\n }\n address = accounts[0] as Address\n }\n\n const walletClient = createWalletClient({\n account: address,\n chain,\n transport: custom(provider),\n })\n\n const signer = brandSigner({\n address,\n signMessage: async ({ message }) => {\n return walletClient.signMessage({\n account: address!,\n message:\n typeof message === 'string'\n ? message\n : { raw: message.raw as Hex | Uint8Array },\n })\n },\n })\n\n const txSender = brandTxSender({\n address,\n sendTransaction: async (tx) => {\n const hash = await walletClient.sendTransaction({\n account: address!,\n chain,\n to: tx.to,\n data: tx.data,\n value: tx.value,\n gas: tx.gas,\n })\n return { transactionHash: hash }\n },\n })\n\n return { signer, txSender, kind: 'eoa' }\n}\n\n/** Convenience: wrap window.ethereum when present. */\nexport async function fromWindowEthereum(\n options: FromEip1193Options = {},\n): Promise<PublishWallet> {\n const eth = (globalThis as { ethereum?: EIP1193Provider }).ethereum\n if (!eth) {\n throw new Error('@seedprotocol/publish: window.ethereum is not available')\n }\n return fromEip1193Provider(eth, options)\n}\n\n/** Expose branded helpers for composing custom EIP-1193 senders. */\nexport function brandEip1193Parts(signer: SeedSigner, txSender: SeedTxSender): PublishWallet {\n return {\n signer: brandSigner(signer),\n txSender: brandTxSender(txSender),\n }\n}\n","import { useCallback, useEffect, useState } from 'react'\nimport type { Address, EIP1193Provider } from 'viem'\nimport {\n isPublishWallet,\n type PublishWallet,\n type SeedSigner,\n type SeedTxSender,\n} from '../helpers/seedSigner'\nimport {\n clearPublishWallet,\n getPublishWallet,\n setPublishWallet,\n type PublishWalletSession,\n} from '../helpers/publishWalletRegistry'\nimport { fromEip1193Provider } from '../helpers/adapters/eip1193'\nimport { getPublishConfig } from '../config'\nimport { createPermissionlessTxSender } from '../helpers/adapters/permissionlessTxSender'\nimport { resolvePublishPayment } from '../payment'\n\nexport type SeedWalletStatus = 'disconnected' | 'connecting' | 'connected'\n\nexport type UseSeedWalletResult = {\n address: Address | undefined\n signer: SeedSigner | undefined\n txSender: SeedTxSender | undefined\n status: SeedWalletStatus\n connect: (input: EIP1193Provider | PublishWallet) => Promise<PublishWallet>\n disconnect: () => void\n}\n\n/**\n * Headless wallet session for publish — no Thirdweb dependency.\n * Registers into {@link setPublishWallet} so createPublish / ensureWalletThenPublish work.\n */\nexport function useSeedWallet(): UseSeedWalletResult {\n const [session, setSession] = useState<PublishWalletSession | null>(() => getPublishWallet())\n const [status, setStatus] = useState<SeedWalletStatus>(() =>\n getPublishWallet() ? 'connected' : 'disconnected',\n )\n\n useEffect(() => {\n setSession(getPublishWallet())\n }, [])\n\n const connect = useCallback(async (input: EIP1193Provider | PublishWallet) => {\n setStatus('connecting')\n try {\n let wallet: PublishWallet\n if (isPublishWallet(input)) {\n wallet = input\n } else {\n wallet = await fromEip1193Provider(input)\n }\n\n const config = getPublishConfig()\n const payment = resolvePublishPayment(config)\n let txSender = wallet.txSender\n if (payment.sender === 'eip7702') {\n txSender = await createPermissionlessTxSender({\n signer: wallet.signer,\n bundlerUrl: config.bundlerUrl!,\n paymasterUrl: config.paymasterUrl,\n sponsored: payment.gas.payer === 'sponsored',\n })\n }\n\n const next: PublishWalletSession = {\n signer: wallet.signer,\n txSender,\n ownedAddresses: [wallet.signer.address, txSender.address],\n publisherAddress: wallet.signer.address,\n }\n await setPublishWallet(next)\n setSession(next)\n setStatus('connected')\n return next\n } catch (err) {\n setStatus('disconnected')\n throw err\n }\n }, [])\n\n const disconnect = useCallback(() => {\n void clearPublishWallet()\n setSession(null)\n setStatus('disconnected')\n }, [])\n\n return {\n address: session?.signer.address,\n signer: session?.signer,\n txSender: session?.txSender,\n status,\n connect,\n disconnect,\n }\n}\n","import type { IItem } from '@seedprotocol/sdk'\nimport { combinePublishCostEstimate } from './estimatePublishCost'\nimport { estimatePublishCost } from './estimatePublishCost'\nimport { getCachedMarketRates } from './marketRates'\nimport type { EstimatePublishCostOptions, PublishCostEstimate } from './types'\n\nexport type WatchPublishCostSnapshot = {\n estimate: PublishCostEstimate | null\n isEstimating: boolean\n isStale: boolean\n error: Error | null\n}\n\nexport type WatchPublishCostOptions = EstimatePublishCostOptions & {\n priceRefreshMs?: number\n /** Trailing idle before re-summarizing the item. 0 = re-estimate on every fingerprint change. */\n itemIdleMs?: number\n estimate?: (item: IItem<any>) => Promise<PublishCostEstimate>\n reprice?: (estimate: PublishCostEstimate) => Promise<PublishCostEstimate>\n /**\n * Shown (as stale) until the first estimate arrives, e.g. the last estimate of a watcher this one\n * replaces for the same item.\n */\n previousEstimate?: PublishCostEstimate | null\n /** Delay before retrying once when the watcher's first estimate fails. 0 = no retry. */\n firstEstimateRetryMs?: number\n /**\n * Calls `onChange` after each write to the item's seed, version or property rows and returns the\n * unwatch function, or returns null when it can't watch rows. Defaults to the SDK's change feed,\n * which runs in the browser; when there is none (Node), the item's property values are compared\n * on each item update instead ({@link itemPublishFingerprint}).\n */\n watchRows?: (item: IItem<any>, onChange: () => void) => Promise<(() => void) | null>\n}\n\nexport type WatchPublishCostHandle = {\n dispose: () => void\n refresh: () => void\n}\n\nconst DEFAULT_PRICE_REFRESH_MS = 60_000\nconst DEFAULT_ITEM_IDLE_MS = 15_000\nconst DEFAULT_FIRST_ESTIMATE_RETRY_MS = 5_000\n\nfunction propertyFingerprintValue(prop: { propertyName: string; uid?: string; value?: unknown; getService: () => { getSnapshot: () => unknown } }): string {\n const snapshot = prop.getService().getSnapshot()\n const context =\n snapshot && typeof snapshot === 'object' && 'context' in snapshot\n ? (snapshot as { context?: Record<string, unknown> }).context\n : undefined\n const value = context?.propertyValue ?? (prop as { value?: unknown }).value\n return `${prop.propertyName}:${prop.uid ?? ''}:${String(value ?? '')}`\n}\n\nexport function itemPublishFingerprint(item: IItem<any>): string {\n const props = item.properties ?? []\n const parts = [\n item.seedLocalId,\n item.seedUid ?? '',\n item.latestVersionLocalId ?? '',\n ...props.map(propertyFingerprintValue),\n ]\n return parts.join('|')\n}\n\n/** The SDK's change feed for the item's rows, when this tab runs one. */\nasync function watchItemRowsByFeed(item: IItem<any>, onChange: () => void): Promise<(() => void) | null> {\n const { isChangeFeedRunning, watchEntityChanges } = await import('@seedprotocol/sdk')\n if (!isChangeFeedRunning()) return null\n return watchEntityChanges(\n { seedLocalId: item.seedLocalId, seedUid: item.seedUid, tables: ['seeds', 'versions', 'metadata'] },\n onChange,\n )\n}\n\nfunction asError(err: unknown): Error {\n return err instanceof Error ? err : new Error(String(err))\n}\n\n/**\n * Watches an item and emits USD publish-cost estimates, each summarized from the item's rows.\n * First estimate is immediate. Later writes to the item's rows (in Node, changes to its loaded\n * property values) restart a 15s idle timer.\n * Market rates refresh every 60s and reprice the last work without re-summarizing.\n * If the first estimate fails it is retried once after 5s, and the snapshot stays `isEstimating`\n * until the retry settles.\n */\nexport function watchPublishCost(\n item: IItem<any>,\n onChange: (snapshot: WatchPublishCostSnapshot & { refresh: () => void }) => void,\n options?: WatchPublishCostOptions,\n): WatchPublishCostHandle {\n const priceRefreshMs = options?.priceRefreshMs ?? DEFAULT_PRICE_REFRESH_MS\n const itemIdleMs = options?.itemIdleMs ?? DEFAULT_ITEM_IDLE_MS\n const firstEstimateRetryMs = options?.firstEstimateRetryMs ?? DEFAULT_FIRST_ESTIMATE_RETRY_MS\n const estimateFn =\n options?.estimate ??\n ((target: IItem<any>) => estimatePublishCost(target, options))\n const repriceFn =\n options?.reprice ??\n (async (prev: PublishCostEstimate) => {\n const rates = await getCachedMarketRates({ forceRefresh: true })\n return combinePublishCostEstimate(prev.work, rates, {\n evmUserPays: prev.evm.userPays,\n arweavePath: prev.arweave.path,\n })\n })\n\n let disposed = false\n let lastFingerprint = itemPublishFingerprint(item)\n let lastEstimate: PublishCostEstimate | null = options?.previousEstimate ?? null\n let isEstimating = false\n let isStale = lastEstimate !== null\n let hasEstimated = false\n let hasRetried = false\n let error: Error | null = null\n let runId = 0\n let idleTimer: ReturnType<typeof setTimeout> | null = null\n let priceTimer: ReturnType<typeof setInterval> | null = null\n let retryTimer: ReturnType<typeof setTimeout> | null = null\n\n const emit = () => {\n if (disposed) return\n onChange({\n estimate: lastEstimate,\n isEstimating,\n isStale,\n error,\n refresh,\n })\n }\n\n const runEstimate = async () => {\n const id = ++runId\n if (retryTimer) {\n clearTimeout(retryTimer)\n retryTimer = null\n }\n isEstimating = true\n error = null\n emit()\n try {\n const next = await estimateFn(item)\n if (disposed || id !== runId) return\n lastEstimate = next\n hasEstimated = true\n lastFingerprint = itemPublishFingerprint(item)\n isStale = false\n isEstimating = false\n error = null\n emit()\n } catch (err) {\n if (disposed || id !== runId) return\n if (!hasEstimated && !hasRetried && firstEstimateRetryMs > 0) {\n // Still estimating: a transient failure shouldn't blank the cost until the next edit.\n hasRetried = true\n retryTimer = setTimeout(() => {\n retryTimer = null\n void runEstimate()\n }, firstEstimateRetryMs)\n return\n }\n isEstimating = false\n error = asError(err)\n emit()\n }\n }\n\n const scheduleItemEstimate = () => {\n if (lastEstimate) isStale = true\n if (itemIdleMs <= 0) {\n void runEstimate()\n return\n }\n if (idleTimer) clearTimeout(idleTimer)\n idleTimer = setTimeout(() => {\n idleTimer = null\n void runEstimate()\n }, itemIdleMs)\n emit()\n }\n\n const refresh = () => {\n if (idleTimer) {\n clearTimeout(idleTimer)\n idleTimer = null\n }\n void runEstimate()\n }\n\n void runEstimate()\n\n // Edits are noticed by comparing the item's values until the row watch starts, and for good\n // when there is none.\n let subscription: { unsubscribe: () => void } | null = item.subscribe(() => {\n if (disposed) return\n const fingerprint = itemPublishFingerprint(item)\n if (fingerprint === lastFingerprint) return\n lastFingerprint = fingerprint\n scheduleItemEstimate()\n })\n let unwatchRows: (() => void) | null = null\n void (options?.watchRows ?? watchItemRowsByFeed)(item, () => {\n if (!disposed) scheduleItemEstimate()\n }).then(\n (unwatch) => {\n if (!unwatch) return\n if (disposed) return unwatch()\n unwatchRows = unwatch\n subscription?.unsubscribe()\n subscription = null\n },\n () => {},\n )\n\n if (priceRefreshMs > 0) {\n priceTimer = setInterval(() => {\n if (disposed || !lastEstimate || isEstimating) return\n void (async () => {\n try {\n const next = await repriceFn(lastEstimate!)\n if (disposed) return\n lastEstimate = next\n emit()\n } catch (err) {\n if (disposed) return\n error = asError(err)\n emit()\n }\n })()\n }, priceRefreshMs)\n }\n\n return {\n refresh,\n dispose: () => {\n disposed = true\n subscription?.unsubscribe()\n unwatchRows?.()\n if (idleTimer) clearTimeout(idleTimer)\n if (priceTimer) clearInterval(priceTimer)\n if (retryTimer) clearTimeout(retryTimer)\n },\n }\n}\n","import { PublishMachineStates } from '~/helpers/constants'\n\n/**\n * Maps internal publish machine state values to display step IDs for UI consistency.\n * The direct-EAS path uses `creatingAttestationsDirectToEas` internally, but UIs\n * typically show a single \"Creating attestations\" step. This helper normalizes the\n * machine value for display.\n */\nexport function getDisplayStepId(machineValue: string): string {\n if (machineValue === 'creatingAttestationsDirectToEas') {\n return 'creatingAttestations'\n }\n return machineValue\n}\n\ntype PublishRowStatus = 'in_progress' | 'completed' | 'failed' | 'interrupted'\n\n/**\n * Single source of truth for step UIs: the live machine while running; once the\n * actor is gone, prefer the DB row status so we never flash an intermediate\n * `persistedSnapshot` value (e.g. creatingAttestations) after a completed run.\n */\nexport function resolvePublishDisplayValue(\n publishProcess: unknown | null | undefined,\n record: { status: PublishRowStatus } | undefined,\n machineValue: string | undefined\n): string | undefined {\n if (publishProcess != null) return machineValue\n if (record?.status === 'completed') return PublishMachineStates.SUCCESS\n if (record?.status === 'failed') return PublishMachineStates.FAILURE\n if (record?.status === 'interrupted') return undefined\n return machineValue\n}\n\nexport type PublishRowForDisplay = {\n status: string\n persistedSnapshot: string\n completedAt?: number | null\n}\n\n/**\n * Derives the machine-state string for UI from the persisted DB row. Prefer\n * `status` / `completedAt` over raw `persistedSnapshot` JSON so a stale or\n * out-of-order snapshot write cannot force the UI back to an intermediate step\n * after a terminal save (common when consumers read `JSON.parse(persistedSnapshot).value`).\n */\nexport function getPublishMachineValueForUi(record: PublishRowForDisplay | undefined): string | undefined {\n if (!record) return undefined\n\n if (record.status === 'failed') return PublishMachineStates.FAILURE\n if (record.status === 'completed') return PublishMachineStates.SUCCESS\n if (record.status === 'interrupted') return undefined\n\n if (record.completedAt != null) {\n try {\n const p = JSON.parse(record.persistedSnapshot) as { value?: unknown; status?: string }\n if (p.status === 'done' && p.value === PublishMachineStates.FAILURE) {\n return PublishMachineStates.FAILURE\n }\n } catch {\n /* ignore */\n }\n return PublishMachineStates.SUCCESS\n }\n\n try {\n const p = JSON.parse(record.persistedSnapshot) as { value?: unknown; status?: string }\n if (p.status === 'done') {\n if (p.value === PublishMachineStates.SUCCESS) return PublishMachineStates.SUCCESS\n if (p.value === PublishMachineStates.FAILURE) return PublishMachineStates.FAILURE\n }\n if (typeof p.value === 'string') return p.value\n } catch {\n return undefined\n }\n return undefined\n}\n","import { useState, useEffect, useRef, useMemo } from 'react'\nimport { useSelector } from '@xstate/react'\nimport { useLiveQuery } from '@seedprotocol/react'\nimport { BaseDb, publishProcesses } from '@seedprotocol/sdk'\nimport { eq, desc } from 'drizzle-orm'\nimport { PublishManager } from '../services/publishManager'\nimport { PublishMachineStates } from '~/helpers/constants'\nimport { getPublishMachineValueForUi, resolvePublishDisplayValue } from '~/helpers/publishDisplayHelpers'\n\nfunction isTerminalDoneSnapshot(snapshot: { value?: unknown; status?: string } | null): snapshot is { value: string; status: 'done' } {\n if (!snapshot || snapshot.status !== 'done') return false\n return snapshot.value === PublishMachineStates.SUCCESS || snapshot.value === PublishMachineStates.FAILURE\n}\n\nexport function usePublishProcess(seedLocalId: string) {\n const publishManager = PublishManager.getService()\n\n const publishProcess = useSelector(publishManager, (snapshot) => {\n return snapshot?.context?.publishProcesses?.get(seedLocalId) ?? null\n })\n\n /** Last snapshot from the publish actor; survives removal from the manager map so we can keep terminal `value`. */\n const lastPublishSnapshotRef = useRef<{ value?: unknown; status?: string } | null>(null)\n\n useEffect(() => {\n lastPublishSnapshotRef.current = null\n }, [seedLocalId])\n\n const [machineValue, setMachineValue] = useState<string | undefined>(undefined)\n /**\n * Once we have observed a terminal outcome for this seed (machine done or DB row), keep\n * showing success/failure until a new publish actor is spawned. Prevents the UI from\n * flipping back to an intermediate step when live-query or row ordering briefly reports\n * in_progress or a stale persistedSnapshot after completion.\n */\n const [terminalLatch, setTerminalLatch] = useState<'success' | 'failure' | null>(null)\n\n const db = BaseDb.getAppDb()\n const latestProcessRowQuery = useMemo(\n () =>\n seedLocalId && db\n ? db\n .select()\n .from(publishProcesses)\n .where(eq(publishProcesses.seedLocalId, seedLocalId))\n .orderBy(desc(publishProcesses.startedAt))\n .limit(1)\n : null,\n [db, seedLocalId]\n )\n const latestRecords = useLiveQuery(latestProcessRowQuery)\n const latestRecord = latestRecords?.[0] as\n | { status: string; persistedSnapshot: string; completedAt?: number | null }\n | undefined\n const recordStatus = latestRecord?.status as\n | 'in_progress'\n | 'completed'\n | 'failed'\n | 'interrupted'\n | undefined\n\n const value = useMemo(() => {\n if (publishProcess != null) {\n return machineValue\n }\n if (terminalLatch === 'success' || terminalLatch === 'failure') {\n return terminalLatch\n }\n const fromRow = getPublishMachineValueForUi(latestRecord)\n if (fromRow === PublishMachineStates.SUCCESS || fromRow === PublishMachineStates.FAILURE) {\n return fromRow\n }\n return resolvePublishDisplayValue(\n publishProcess,\n recordStatus != null ? { status: recordStatus } : undefined,\n machineValue\n )\n }, [publishProcess, recordStatus, machineValue, terminalLatch, latestRecord])\n\n useEffect(() => {\n setTerminalLatch(null)\n }, [seedLocalId])\n\n useEffect(() => {\n if (publishProcess != null) {\n return\n }\n if (recordStatus === 'completed') {\n setTerminalLatch('success')\n } else if (recordStatus === 'failed') {\n setTerminalLatch('failure')\n }\n }, [recordStatus, publishProcess])\n\n useEffect(() => {\n if (publishProcess != null) {\n setTerminalLatch(null)\n }\n }, [publishProcess])\n\n useEffect(() => {\n if (!publishProcess) {\n const last = lastPublishSnapshotRef.current\n const preserve = isTerminalDoneSnapshot(last)\n if (preserve) {\n setMachineValue(last.value as string)\n if (last.value === PublishMachineStates.SUCCESS) {\n setTerminalLatch('success')\n } else if (last.value === PublishMachineStates.FAILURE) {\n setTerminalLatch('failure')\n }\n } else {\n setMachineValue(undefined)\n }\n return\n }\n const initial = publishProcess.getSnapshot()\n lastPublishSnapshotRef.current = { value: initial?.value, status: (initial as { status?: string }).status }\n setMachineValue(initial?.value as string | undefined)\n const sub = publishProcess.subscribe((snapshot: { value?: unknown; status?: string }) => {\n lastPublishSnapshotRef.current = { value: snapshot?.value, status: snapshot?.status }\n setMachineValue(snapshot?.value as string | undefined)\n })\n return () => {\n sub.unsubscribe()\n }\n }, [publishProcess, seedLocalId])\n\n return {\n publishProcess: publishProcess ?? null,\n value,\n }\n}\n","import { useState, useEffect } from 'react'\nimport { isItemOwned } from '@seedprotocol/sdk'\nimport type { Item } from '@seedprotocol/sdk'\nimport { useSeedAddressRevision } from '@seedprotocol/react'\n\n/**\n * Whether the client's addresses own `item`, so it can be published. False until the check has\n * finished, and checked again when the item or the owned addresses change (connect, disconnect,\n * setAddresses). A check overtaken by a newer one is ignored.\n */\nexport function useCanPublishItem(item: Item<any> | null | undefined): boolean {\n const [canPublish, setCanPublish] = useState(false)\n const addressRevision = useSeedAddressRevision()\n const seedLocalId = item?.seedLocalId\n\n useEffect(() => {\n if (!item) {\n setCanPublish(false)\n return\n }\n let current = true\n setCanPublish(false)\n isItemOwned(item)\n .then((owned) => {\n if (current) setCanPublish(owned)\n })\n .catch(() => {\n if (current) setCanPublish(false)\n })\n return () => {\n current = false\n }\n }, [seedLocalId, addressRevision])\n\n return canPublish\n}\n","import { useMemo } from 'react'\nimport { useLiveQuery } from '@seedprotocol/react'\nimport { arweaveL1FinalizeJobs, BaseDb } from '@seedprotocol/sdk'\nimport { eq, desc } from 'drizzle-orm'\n\nexport type ArweaveL1FinalizeJobRow = {\n id: number\n seedLocalId: string\n dataItemId: string\n l1TransactionId: string | null\n bundleId: string | null\n phase: string\n statusJson: string | null\n errorMessage: string | null\n versionLocalId: string | null\n itemPropertyName: string | null\n updatedAt: number | null\n}\n\n/**\n * Live L1 finalization jobs for a seed (bundler path). Empty when not using bundler or no jobs.\n */\nexport function useArweaveL1Finalize(seedLocalId: string | undefined) {\n const db = BaseDb.getAppDb()\n const jobsQuery = useMemo(\n () =>\n seedLocalId && db\n ? db\n .select()\n .from(arweaveL1FinalizeJobs)\n .where(eq(arweaveL1FinalizeJobs.seedLocalId, seedLocalId))\n .orderBy(desc(arweaveL1FinalizeJobs.updatedAt))\n : null,\n [db, seedLocalId]\n )\n const rows = useLiveQuery(jobsQuery)\n\n const jobs = (rows ?? []) as ArweaveL1FinalizeJobRow[]\n\n const summary = useMemo(() => {\n const pending = jobs.filter((j) => j.phase === 'pending_l1').length\n const confirmed = jobs.filter((j) => j.phase === 'confirmed').length\n return {\n hasPendingL1: pending > 0,\n pendingCount: pending,\n confirmedCount: confirmed,\n jobs,\n }\n }, [jobs])\n\n return summary\n}\n","import { useMemo } from 'react'\nimport { useLiveQuery } from '@seedprotocol/react'\nimport { BaseDb, publishProcesses } from '@seedprotocol/sdk'\nimport { eq, desc } from 'drizzle-orm'\nimport { usePublishProcess } from './usePublishProcess'\nimport { useArweaveL1Finalize } from './useArweaveL1Finalize'\n\nexport type PublishProcessStatus = 'in_progress' | 'completed' | 'failed' | 'interrupted'\n\nexport interface PublishProcessRecord {\n id: number\n seedLocalId: string\n modelName: string\n schemaId?: string\n status: PublishProcessStatus\n startedAt: number\n completedAt?: number\n errorMessage?: string\n errorStep?: string\n errorDetails?: string\n /** Stable error code (e.g. `ManagedAccountPublishError.code`) when the failure had one. */\n errorCode?: string\n persistedSnapshot: string\n createdAt?: number\n updatedAt?: number\n}\n\nexport function useItemPublishStatus(seedLocalId: string | undefined) {\n const { publishProcess, value } = usePublishProcess(seedLocalId ?? '')\n const arweaveL1 = useArweaveL1Finalize(seedLocalId)\n\n const db = BaseDb.getAppDb()\n const latestProcessRowQuery = useMemo(\n () =>\n seedLocalId && db\n ? db\n .select()\n .from(publishProcesses)\n .where(eq(publishProcesses.seedLocalId, seedLocalId))\n .orderBy(desc(publishProcesses.startedAt))\n .limit(1)\n : null,\n [db, seedLocalId]\n )\n const latestRecords = useLiveQuery(latestProcessRowQuery)\n\n const record = latestRecords?.[0] as PublishProcessRecord | undefined\n const isActive = !!publishProcess || record?.status === 'in_progress'\n\n return {\n latestRecord: record,\n publishProcess,\n isActive,\n publishValue: value,\n arweaveL1Pending: arweaveL1.hasPendingL1,\n arweaveL1Jobs: arweaveL1.jobs,\n arweaveL1Summary: arweaveL1,\n }\n}\n","import { useMemo } from 'react'\nimport { useLiveQuery } from '@seedprotocol/react'\nimport { BaseDb, publishProcesses } from '@seedprotocol/sdk'\nimport { desc, eq } from 'drizzle-orm'\nimport type { PublishProcessRecord } from './useItemPublishStatus'\n\nfunction usePublishProcessesQuery() {\n const db = BaseDb.getAppDb()\n return useMemo(\n () => (db ? db.select().from(publishProcesses).orderBy(desc(publishProcesses.startedAt)) : null),\n [db]\n )\n}\n\nfunction usePublishProcessesQueryForSeed(seedLocalId: string | undefined) {\n const db = BaseDb.getAppDb()\n return useMemo(\n () =>\n db && seedLocalId\n ? db\n .select()\n .from(publishProcesses)\n .where(eq(publishProcesses.seedLocalId, seedLocalId))\n .orderBy(desc(publishProcesses.startedAt))\n : null,\n [db, seedLocalId]\n )\n}\n\n/**\n * Single live subscription for the ordered publish_processes list plus a derived non-active count.\n * Prefer this when you need both values in one component so you do not combine\n * {@link usePublishProcesses} and {@link usePublishProcessesNonActiveCount} (which would subscribe twice).\n */\nexport function usePublishProcessesState(): {\n records: PublishProcessRecord[] | undefined\n nonActiveCount: number | undefined\n} {\n const query = usePublishProcessesQuery()\n const records = useLiveQuery(query) as PublishProcessRecord[] | undefined\n const nonActiveCount = useMemo(\n () => (records === undefined ? undefined : records.filter((r) => r.status !== 'in_progress').length),\n [records]\n )\n return { records, nonActiveCount }\n}\n\nexport function usePublishProcesses(): PublishProcessRecord[] | undefined {\n const query = usePublishProcessesQuery()\n return useLiveQuery(query) as PublishProcessRecord[] | undefined\n}\n\nexport function usePublishProcessesNonActiveCount(): number | undefined {\n return usePublishProcessesState().nonActiveCount\n}\n\n/**\n * Live query of `publish_processes` for one seed, ordered by `startedAt` descending.\n * Pass `undefined` to disable the query (returns `undefined`).\n */\nexport function usePublishProcessesForSeed(\n seedLocalId: string | undefined\n): PublishProcessRecord[] | undefined {\n const query = usePublishProcessesQueryForSeed(seedLocalId)\n return useLiveQuery(query) as PublishProcessRecord[] | undefined\n}\n\n/**\n * Same as {@link usePublishProcessesForSeed} plus a derived count of rows whose status is not\n * `in_progress`. Prefer this over combining {@link usePublishProcessesForSeed} and a separate\n * count hook so you only subscribe once.\n */\nexport function usePublishProcessesStateForSeed(seedLocalId: string | undefined): {\n records: PublishProcessRecord[] | undefined\n nonActiveCount: number | undefined\n} {\n const query = usePublishProcessesQueryForSeed(seedLocalId)\n const records = useLiveQuery(query) as PublishProcessRecord[] | undefined\n const nonActiveCount = useMemo(\n () => (records === undefined ? undefined : records.filter((r) => r.status !== 'in_progress').length),\n [records]\n )\n return { records, nonActiveCount }\n}\n\nexport function usePublishProcessesNonActiveCountForSeed(\n seedLocalId: string | undefined\n): number | undefined {\n return usePublishProcessesStateForSeed(seedLocalId).nonActiveCount\n}\n\nexport function usePublishProcessById(\n id: number | undefined\n): { record: PublishProcessRecord | null; isLoading: boolean } {\n const db = BaseDb.getAppDb()\n const query = useMemo(\n () =>\n id != null && db\n ? db.select().from(publishProcesses).where(eq(publishProcesses.id, id)).limit(1)\n : null,\n [db, id]\n )\n const records = useLiveQuery(query)\n const isLoading = records === undefined\n const record = records && records.length > 0 ? (records[0] as PublishProcessRecord) : null\n return { record, isLoading }\n}\n","import { BaseDb, publishProcesses, uploadProcesses } from '@seedprotocol/sdk'\nimport { and, notInArray, eq, inArray } from 'drizzle-orm'\n\n/** Remove every publish_processes row whose status is not `in_progress` (app-wide). */\nexport async function clearCompletedPublishProcesses(): Promise<void> {\n const db = BaseDb.getAppDb()\n if (!db) return\n\n await db\n .delete(publishProcesses)\n .where(notInArray(publishProcesses.status, ['in_progress']))\n}\n\n/**\n * Same semantics as {@link clearCompletedPublishProcesses}, but only for rows with the given\n * `seedLocalId`. Never deletes `in_progress` runs for that seed.\n */\nexport async function clearCompletedPublishProcessesForSeed(seedLocalId: string): Promise<void> {\n const db = BaseDb.getAppDb()\n if (!db) return\n\n await db\n .delete(publishProcesses)\n .where(\n and(eq(publishProcesses.seedLocalId, seedLocalId), notInArray(publishProcesses.status, ['in_progress']))\n )\n}\n\nexport async function clearAllPublishProcesses(): Promise<void> {\n const db = BaseDb.getAppDb()\n if (!db) return\n\n await db.delete(publishProcesses)\n}\n\nexport async function clearAllUploadProcesses(): Promise<void> {\n const db = BaseDb.getAppDb()\n if (!db) return\n\n await db.delete(uploadProcesses)\n}\n\n/**\n * Deletes **all** `publish_processes` rows for this seed (full history, including any\n * `in_progress` run). For removing individual runs, use {@link deletePublishProcessById} or\n * {@link deletePublishProcessesByIds}.\n */\nexport async function deletePublishProcessesForSeed(seedLocalId: string): Promise<void> {\n const db = BaseDb.getAppDb()\n if (!db) return\n\n await db.delete(publishProcesses).where(eq(publishProcesses.seedLocalId, seedLocalId))\n}\n\n/** Delete a single publish process record by id. */\nexport async function deletePublishProcessById(id: number): Promise<void> {\n const db = BaseDb.getAppDb()\n if (!db) return\n await db.delete(publishProcesses).where(eq(publishProcesses.id, id))\n}\n\n/** Delete multiple publish process records by ids. */\nexport async function deletePublishProcessesByIds(ids: number[]): Promise<void> {\n if (ids.length === 0) return\n const db = BaseDb.getAppDb()\n if (!db) return\n await db.delete(publishProcesses).where(inArray(publishProcesses.id, ids))\n}\n","/**\n * Extracts Arweave transaction IDs from a publish process record's persisted snapshot.\n * Returns an empty array on parse error or when no transactions exist.\n */\nexport function getArweaveTransactionIds(record: { persistedSnapshot: string }): string[] {\n try {\n const parsed = JSON.parse(record.persistedSnapshot) as {\n context?: { arweaveTransactions?: Array<{ transaction?: { id?: string } }> }\n }\n const txs = parsed.context?.arweaveTransactions ?? []\n return txs\n .map((at) => (at.transaction as { id?: string })?.id)\n .filter((id): id is string => typeof id === 'string')\n } catch {\n return []\n }\n}\n\n/**\n * Extracts the EAS attestation payload from a publish process record's persisted snapshot.\n * Returns undefined on parse error or when no payload was persisted.\n */\nexport function getEasPayload(record: { persistedSnapshot: string }): unknown {\n try {\n const parsed = JSON.parse(record.persistedSnapshot) as {\n context?: { easPayload?: unknown }\n }\n return parsed.context?.easPayload ?? undefined\n } catch {\n return undefined\n }\n}\n","import { useCallback, useEffect, useRef, useState } from 'react'\nimport type { IItem } from '@seedprotocol/sdk'\nimport {\n watchPublishCost,\n type WatchPublishCostOptions,\n} from '../services/publishCost/watchPublishCost'\nimport type { PublishCostEstimate } from '../services/publishCost/types'\n\nexport type UsePublishCostEstimateResult = {\n estimate: PublishCostEstimate | null\n isEstimating: boolean\n isStale: boolean\n error: Error | null\n refresh: () => void\n}\n\nexport function usePublishCostEstimate(\n item: IItem<any> | null | undefined,\n options?: WatchPublishCostOptions,\n): UsePublishCostEstimateResult {\n const [estimate, setEstimate] = useState<PublishCostEstimate | null>(null)\n const [isEstimating, setIsEstimating] = useState(false)\n const [isStale, setIsStale] = useState(false)\n const [error, setError] = useState<Error | null>(null)\n const refreshRef = useRef<() => void>(() => {})\n /** The last estimate and what it was for, handed to a watcher that replaces one for the same item. */\n const lastEstimateRef = useRef<{\n seedLocalId: string | undefined\n publishMode: WatchPublishCostOptions['publishMode']\n estimate: PublishCostEstimate | null\n } | null>(null)\n\n const publishMode = options?.publishMode\n const priceRefreshMs = options?.priceRefreshMs\n const itemIdleMs = options?.itemIdleMs\n\n useEffect(() => {\n if (!item) {\n setEstimate(null)\n setIsEstimating(false)\n setIsStale(false)\n setError(null)\n refreshRef.current = () => {}\n lastEstimateRef.current = null\n return\n }\n\n // A new Item instance for the same record (e.g. after the old one was evicted) keeps showing\n // the last estimate while the new watcher's first one runs.\n const seedLocalId = item.seedLocalId\n const last = lastEstimateRef.current\n const previousEstimate =\n last && last.seedLocalId === seedLocalId && last.publishMode === publishMode ? last.estimate : null\n\n const handle = watchPublishCost(\n item,\n (snapshot) => {\n lastEstimateRef.current = { seedLocalId, publishMode, estimate: snapshot.estimate }\n setEstimate(snapshot.estimate)\n setIsEstimating(snapshot.isEstimating)\n setIsStale(snapshot.isStale)\n setError(snapshot.error)\n refreshRef.current = snapshot.refresh\n },\n { ...options, previousEstimate },\n )\n\n return () => {\n handle.dispose()\n }\n // Primitive option fields only — avoid resubscribing on a new options object each render.\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [item, item?.seedLocalId, publishMode, priceRefreshMs, itemIdleMs])\n\n const refresh = useCallback(() => {\n refreshRef.current()\n }, [])\n\n return { estimate, isEstimating, isStale, error, refresh }\n}\n","import { lookup, toRegistrableDomain } from 'rdapper'\nimport {\n hashDomainRegistryFingerprint,\n type DomainRegistryFingerprintInput,\n} from '@seedprotocol/eas'\n\nexport type DomainRegistrySnapshot = DomainRegistryFingerprintInput & {\n expirationDate?: string\n updatedDate?: string\n registrarName?: string\n source?: string\n isRegistered?: boolean\n}\n\n/**\n * Normalize input to a registrable domain (eTLD+1). Throws when invalid.\n */\nexport function normalizeRegistrableDomain(input: string): string {\n const normalized = toRegistrableDomain(input)\n if (!normalized) {\n throw new Error(\n `@seedprotocol/publish: unable to resolve registrable domain for \"${input}\"`,\n )\n }\n return normalized.toLowerCase()\n}\n\n/** Lowercased hostname without a trailing dot. No eTLD+1 normalization. */\nexport function normalizeHostname(input: string): string {\n return input.trim().toLowerCase().replace(/\\.$/, '')\n}\n\n/**\n * Fetch RDAP/WHOIS registry snapshot and compute fingerprint inputs.\n */\nexport async function lookupDomainRegistry(\n domain: string,\n): Promise<DomainRegistrySnapshot | null> {\n const registrable = normalizeRegistrableDomain(domain)\n const result = await lookup(registrable)\n if (!result.ok || !result.record) {\n return null\n }\n const record = result.record\n return {\n domain: registrable,\n creationDate: record.creationDate ?? '',\n registrarIanaId: record.registrar?.ianaId ?? '',\n expirationDate: record.expirationDate,\n updatedDate: record.updatedDate,\n registrarName: record.registrar?.name,\n source: record.source,\n isRegistered: record.isRegistered,\n }\n}\n\nexport function fingerprintFromRegistrySnapshot(\n snapshot: DomainRegistryFingerprintInput,\n): `0x${string}` {\n return hashDomainRegistryFingerprint({\n domain: snapshot.domain,\n creationDate: snapshot.creationDate ?? '',\n registrarIanaId: snapshot.registrarIanaId ?? '',\n })\n}\n","import {\n DOMAIN_OWNERSHIP_CHALLENGE_TTL_MS,\n DOMAIN_OWNERSHIP_METHOD,\n DOMAIN_OWNERSHIP_SCOPE_HOSTNAME,\n DOMAIN_OWNERSHIP_SCOPE_REGISTRABLE,\n buildDomainOwnershipTxtValue,\n domainOwnershipTxtName,\n hashDomainOwnershipChallenge,\n} from '@seedprotocol/eas'\nimport { normalizeHostname, normalizeRegistrableDomain } from './registry'\n\nexport type DomainOwnershipChallenge = {\n /** Opaque id for caller correlation (not required by verify). */\n challengeId: string\n domain: string\n claimer: string\n scope: string\n method: typeof DOMAIN_OWNERSHIP_METHOD\n /** Raw challenge token (keep private until DNS publish; discard after verify). */\n token: string\n txtName: string\n txtValue: string\n challengeHash: `0x${string}`\n /** ISO-8601 expiry encoded in the TXT record. */\n expiresAt: string\n /** Suggested dig command for operators. */\n digHint: string\n}\n\nfunction randomBytes(size: number): Uint8Array {\n const bytes = new Uint8Array(size)\n crypto.getRandomValues(bytes)\n return bytes\n}\n\nfunction base64Url(bytes: Uint8Array): string {\n let binary = ''\n for (const byte of bytes) {\n binary += String.fromCharCode(byte)\n }\n return btoa(binary).replace(/\\+/g, '-').replace(/\\//g, '_').replace(/=+$/g, '')\n}\n\n/**\n * Create a caller-held DNS TXT challenge for domain ownership verification.\n * The caller must persist the returned object and pass it to verify.\n * Domains are normalized to eTLD+1 (registrable) by default.\n */\nexport function createDomainOwnershipChallenge(params: {\n domain: string\n claimer: string\n scope?: string\n /** Override challenge TTL (ms). Default 72h. */\n ttlMs?: number\n now?: number\n /**\n * When false, skip eTLD+1 normalization: the challenge is on the hostname as given, and the\n * scope defaults to {@link DOMAIN_OWNERSHIP_SCOPE_HOSTNAME}. Default true.\n */\n normalizeRegistrable?: boolean\n}): DomainOwnershipChallenge {\n const hostnameOnly = params.normalizeRegistrable === false\n const domain = hostnameOnly ? normalizeHostname(params.domain) : normalizeRegistrableDomain(params.domain)\n if (!domain || domain.includes(' ')) {\n throw new Error('@seedprotocol/publish: createDomainOwnershipChallenge requires a valid domain')\n }\n const claimer = params.claimer.trim()\n if (!/^0x[0-9a-fA-F]{40}$/.test(claimer)) {\n throw new Error(\n '@seedprotocol/publish: createDomainOwnershipChallenge requires a 20-byte hex claimer address',\n )\n }\n const scope =\n params.scope ?? (hostnameOnly ? DOMAIN_OWNERSHIP_SCOPE_HOSTNAME : DOMAIN_OWNERSHIP_SCOPE_REGISTRABLE)\n // A TXT record on a subdomain proves nothing about the rest of the registrable domain.\n if (scope === DOMAIN_OWNERSHIP_SCOPE_REGISTRABLE && domain !== normalizeRegistrableDomain(domain)) {\n throw new Error(\n `@seedprotocol/publish: createDomainOwnershipChallenge cannot use scope \"registrable\" for \"${domain}\", which is not a registrable domain. Use the hostname scope or challenge ${normalizeRegistrableDomain(domain)}.`,\n )\n }\n const ttlMs = params.ttlMs ?? DOMAIN_OWNERSHIP_CHALLENGE_TTL_MS\n const now = params.now ?? Date.now()\n const expiresAt = new Date(now + ttlMs).toISOString()\n const token = base64Url(randomBytes(32))\n const challengeHash = hashDomainOwnershipChallenge({\n domain,\n claimer,\n token,\n scope,\n })\n const txtName = domainOwnershipTxtName(domain)\n const txtValue = buildDomainOwnershipTxtValue({\n token,\n claimer,\n expiry: expiresAt,\n })\n const challengeId = base64Url(randomBytes(16))\n\n return {\n challengeId,\n domain,\n claimer,\n scope,\n method: DOMAIN_OWNERSHIP_METHOD,\n token,\n txtName,\n txtValue,\n challengeHash,\n expiresAt,\n digHint: `dig TXT ${txtName}`,\n }\n}\n","import {\n buildDomainOwnershipTxtValue,\n parseDomainOwnershipTxtValue,\n} from '@seedprotocol/eas'\nimport type { DomainOwnershipChallenge } from './challenge'\n\nexport type DnsTxtLookupResult = {\n source: string\n values: string[]\n dnssecAuthenticated?: boolean\n}\n\nexport type VerifyDomainOwnershipDnsResult = {\n ok: boolean\n matchedSources: string[]\n lookups: DnsTxtLookupResult[]\n error?: string\n}\n\ntype DohAnswer = { name?: string; type?: number; data?: string; TTL?: number }\ntype DohResponse = { Status?: number; AD?: boolean; Answer?: DohAnswer[] }\n\n/** Node-only DNS; dynamically imported so browser bundles never top-level-import `node:dns`. */\nasync function lookupNodeDns(name: string): Promise<DnsTxtLookupResult> {\n const { promises: dnsPromises } = await import('node:dns')\n const records = await dnsPromises.resolveTxt(name)\n const values = records.map((chunks) => chunks.join(''))\n return { source: 'node:dns', values }\n}\n\nasync function lookupDoh(\n name: string,\n source: string,\n endpoint: string,\n): Promise<DnsTxtLookupResult> {\n const url = `${endpoint}?name=${encodeURIComponent(name)}&type=TXT`\n const res = await fetch(url, {\n headers: { accept: 'application/dns-json' },\n })\n if (!res.ok) {\n throw new Error(`DoH ${source} HTTP ${res.status}`)\n }\n const body = (await res.json()) as DohResponse\n const values = (body.Answer ?? [])\n .filter((a) => a.type === 16 && typeof a.data === 'string')\n .map((a) => a.data!.replace(/^\"|\"$/g, ''))\n return {\n source,\n values,\n dnssecAuthenticated: Boolean(body.AD),\n }\n}\n\nfunction defaultLookups(): Array<(name: string) => Promise<DnsTxtLookupResult>> {\n const lookups: Array<(name: string) => Promise<DnsTxtLookupResult>> = [\n (name) => lookupDoh(name, 'cloudflare-doh', 'https://cloudflare-dns.com/dns-query'),\n (name) => lookupDoh(name, 'google-doh', 'https://dns.google/resolve'),\n ]\n // Skip node:dns in DOM runtimes (Vite externalizes it and top-level/eager use crashes).\n if (typeof document === 'undefined') {\n lookups.unshift((name) => lookupNodeDns(name))\n }\n return lookups\n}\n\nfunction valuesMatchExpected(values: string[], expected: string): boolean {\n const expectedParsed = parseDomainOwnershipTxtValue(expected)\n for (const v of values) {\n if (v === expected || v.replace(/^\"|\"$/g, '') === expected) return true\n const parsed = parseDomainOwnershipTxtValue(v)\n if (\n expectedParsed &&\n parsed &&\n parsed.token === expectedParsed.token &&\n parsed.claimer === expectedParsed.claimer\n ) {\n return true\n }\n }\n return false\n}\n\n/**\n * Verify that the challenge TXT is visible via multiple DNS vantage points.\n * Requires quorum (≥2 matching sources) when no DNSSEC-authenticated match is seen.\n */\nexport async function verifyDomainOwnershipDns(\n challenge: DomainOwnershipChallenge,\n options?: {\n lookups?: Array<(name: string) => Promise<DnsTxtLookupResult>>\n /** Minimum matching sources when DNSSEC AD is not observed (default 2). */\n quorum?: number\n now?: number\n },\n): Promise<VerifyDomainOwnershipDnsResult> {\n const now = options?.now ?? Date.now()\n if (Date.parse(challenge.expiresAt) <= now) {\n return {\n ok: false,\n matchedSources: [],\n lookups: [],\n error: 'Challenge expired',\n }\n }\n\n // Ensure expected TXT is canonical for this challenge material\n const expected = buildDomainOwnershipTxtValue({\n token: challenge.token,\n claimer: challenge.claimer,\n expiry: challenge.expiresAt,\n })\n if (expected !== challenge.txtValue) {\n return {\n ok: false,\n matchedSources: [],\n lookups: [],\n error: 'Challenge txtValue does not match token/claimer/expiry',\n }\n }\n\n const lookupFns = options?.lookups ?? defaultLookups()\n const quorum = options?.quorum ?? 2\n const lookups: DnsTxtLookupResult[] = []\n const matchedSources: string[] = []\n let dnssecMatch = false\n\n await Promise.all(\n lookupFns.map(async (fn) => {\n try {\n const result = await fn(challenge.txtName)\n lookups.push(result)\n if (valuesMatchExpected(result.values, expected)) {\n matchedSources.push(result.source)\n if (result.dnssecAuthenticated) dnssecMatch = true\n }\n } catch (err) {\n lookups.push({\n source: 'error',\n values: [],\n })\n void err\n }\n }),\n )\n\n const ok = dnssecMatch || matchedSources.length >= quorum\n return {\n ok,\n matchedSources,\n lookups,\n error: ok\n ? undefined\n : `DNS TXT not confirmed (matched ${matchedSources.length}/${quorum} sources)`,\n }\n}\n","import {\n DOMAIN_OWNERSHIP_DEFAULT_EXPIRATION_SECS,\n DOMAIN_OWNERSHIP_METHOD,\n DOMAIN_OWNERSHIP_SCHEMA_DEF,\n DOMAIN_OWNERSHIP_SCHEMA_NAME,\n DOMAIN_OWNERSHIP_SCOPE_REGISTRABLE,\n assessDomainOwnership,\n decodeDomainOwnershipData,\n getDomainOwnershipFromEas,\n hashDomainOwnershipChallenge,\n type DomainOwnershipAssessResult,\n type DomainOwnershipDecoded,\n} from '@seedprotocol/eas'\nimport { SchemaEncoder, ZERO_BYTES32 } from '@ethereum-attestation-service/eas-sdk'\nimport { SchemaRegistry } from '@ethereum-attestation-service/eas-sdk'\nimport { prepareEasAttest, prepareEasMultiRevoke } from '~/helpers/easDirect'\nimport { getSchemaRecord, registerSchema } from '~/helpers/schemaRegistry'\nimport { prepareNameSchemaAttestation } from '~/helpers/nameSchemaAttestation'\nimport { waitForPublishReceipt } from '~/helpers/chainClient'\nimport { getPublishConfig } from '~/config'\nimport {\n isPublishWallet,\n isSeedTxSender,\n type PublishWallet,\n type SeedTxSender,\n} from '~/helpers/seedSigner'\nimport { getAttestationUidFromReceipt } from '~/helpers/easDirect'\nimport { normalizeBytes32Hex, isValidEasAttestationUid } from '@seedprotocol/eas'\nimport {\n createDomainOwnershipChallenge,\n type DomainOwnershipChallenge,\n} from './challenge'\nimport { verifyDomainOwnershipDns, type VerifyDomainOwnershipDnsResult } from './dnsVerify'\nimport {\n fingerprintFromRegistrySnapshot,\n lookupDomainRegistry,\n normalizeHostname,\n normalizeRegistrableDomain,\n type DomainRegistrySnapshot,\n} from './registry'\n\nexport {\n DOMAIN_OWNERSHIP_SCHEMA_DEF,\n DOMAIN_OWNERSHIP_SCHEMA_NAME,\n DOMAIN_OWNERSHIP_METHOD,\n DOMAIN_OWNERSHIP_SCOPE_HOSTNAME,\n DOMAIN_OWNERSHIP_SCOPE_REGISTRABLE,\n} from '@seedprotocol/eas'\n\nexport { createDomainOwnershipChallenge }\nexport type { DomainOwnershipChallenge }\nexport { verifyDomainOwnershipDns }\nexport type { VerifyDomainOwnershipDnsResult }\nexport { lookupDomainRegistry, normalizeRegistrableDomain, fingerprintFromRegistrySnapshot }\nexport type { DomainRegistrySnapshot }\n\nconst RESOLVER_ADDRESS = '0x0000000000000000000000000000000000000000'\nconst REVOCABLE = true\n\nfunction resolveTxSender(account: PublishWallet | SeedTxSender): SeedTxSender {\n if (isPublishWallet(account)) return account.txSender\n if (isSeedTxSender(account)) return account\n throw new Error(\n '@seedprotocol/publish: domain ownership write APIs require a PublishWallet or SeedTxSender',\n )\n}\n\nasync function sendAndWait(\n txSender: SeedTxSender,\n tx: Parameters<SeedTxSender['sendTransaction']>[0],\n) {\n const result = await txSender.sendTransaction(tx)\n return waitForPublishReceipt(result.transactionHash)\n}\n\n/** Deterministic on-chain schema UID for {@link DOMAIN_OWNERSHIP_SCHEMA_DEF}. */\nexport function getDomainOwnershipSchemaUid(): `0x${string}` {\n return SchemaRegistry.getSchemaUID(\n DOMAIN_OWNERSHIP_SCHEMA_DEF,\n RESOLVER_ADDRESS as `0x${string}`,\n REVOCABLE,\n ) as `0x${string}`\n}\n\n/**\n * Registers the DomainOwnership EAS schema (if missing) and creates a Schema #1 name attestation.\n */\nexport async function ensureDomainOwnershipSchema(\n account: PublishWallet | SeedTxSender,\n): Promise<`0x${string}`> {\n const sender = resolveTxSender(account)\n const schemaUid = getDomainOwnershipSchemaUid()\n const onChain = await getSchemaRecord(schemaUid)\n if (!onChain) {\n await sendAndWait(\n sender,\n registerSchema({\n schema: DOMAIN_OWNERSHIP_SCHEMA_DEF,\n resolverAddress: RESOLVER_ADDRESS,\n revocable: REVOCABLE,\n }),\n )\n await sendAndWait(\n sender,\n prepareNameSchemaAttestation({\n schemaUid,\n schemaName: DOMAIN_OWNERSHIP_SCHEMA_NAME,\n }),\n )\n }\n return schemaUid\n}\n\nexport function encodeDomainOwnershipAttestationData(params: {\n domain: string\n claimer: string\n method: string\n challengeHash: string\n verifiedAt: number\n registryCreationDate: string\n registryExpirationDate: string\n registryFingerprint: string\n scope: string\n}): `0x${string}` {\n const schemaEncoder = new SchemaEncoder(DOMAIN_OWNERSHIP_SCHEMA_DEF)\n const encodedData = schemaEncoder.encodeData([\n { name: 'domain', value: params.domain, type: 'string' },\n { name: 'claimer', value: params.claimer as `0x${string}`, type: 'address' },\n { name: 'method', value: params.method, type: 'string' },\n {\n name: 'challengeHash',\n value: normalizeBytes32Hex(params.challengeHash) as `0x${string}`,\n type: 'bytes32',\n },\n { name: 'verifiedAt', value: params.verifiedAt, type: 'uint64' },\n { name: 'registryCreationDate', value: params.registryCreationDate, type: 'string' },\n {\n name: 'registryExpirationDate',\n value: params.registryExpirationDate,\n type: 'string',\n },\n {\n name: 'registryFingerprint',\n value: normalizeBytes32Hex(params.registryFingerprint) as `0x${string}`,\n type: 'bytes32',\n },\n { name: 'scope', value: params.scope, type: 'string' },\n ])\n return encodedData as `0x${string}`\n}\n\nexport type AttestDomainOwnershipParams = {\n wallet: PublishWallet | SeedTxSender\n domain: string\n claimer: string\n challengeHash: string\n registrySnapshot: DomainRegistrySnapshot\n scope?: string\n method?: string\n verifiedAt?: number\n /** When true (default), register + name the schema if missing. */\n ensureSchema?: boolean\n /** Override EAS expirationTime (unix seconds). */\n expirationTime?: number\n}\n\nexport type AttestDomainOwnershipResult = {\n uid: `0x${string}`\n schemaUid: `0x${string}`\n challengeHash: `0x${string}`\n registryFingerprint: `0x${string}`\n verifiedAt: number\n expirationTime: number\n}\n\nfunction resolveExpirationTime(params: {\n verifiedAt: number\n registryExpirationDate?: string\n override?: number\n}): number {\n if (typeof params.override === 'number' && params.override > 0) return params.override\n if (params.registryExpirationDate) {\n const ms = Date.parse(params.registryExpirationDate)\n if (Number.isFinite(ms) && ms > 0) return Math.floor(ms / 1000)\n }\n return params.verifiedAt + DOMAIN_OWNERSHIP_DEFAULT_EXPIRATION_SECS\n}\n\n/**\n * Tool wallet attests domain ownership after off-chain DNS + RDAP verification.\n */\nexport async function attestDomainOwnership(\n params: AttestDomainOwnershipParams,\n): Promise<AttestDomainOwnershipResult> {\n const sender = resolveTxSender(params.wallet)\n const schemaUid =\n params.ensureSchema === false\n ? getDomainOwnershipSchemaUid()\n : await ensureDomainOwnershipSchema(params.wallet)\n\n const scope = params.scope ?? DOMAIN_OWNERSHIP_SCOPE_REGISTRABLE\n // Record the domain the challenge was on: a hostname-scoped challenge must not be widened to\n // its registrable domain.\n const domain =\n scope === DOMAIN_OWNERSHIP_SCOPE_REGISTRABLE\n ? normalizeRegistrableDomain(params.domain)\n : normalizeHostname(params.domain)\n const claimer = params.claimer.trim()\n if (!/^0x[0-9a-fA-F]{40}$/.test(claimer)) {\n throw new Error('@seedprotocol/publish: attestDomainOwnership requires a valid claimer address')\n }\n\n const challengeHash = normalizeBytes32Hex(params.challengeHash) as `0x${string}`\n if (challengeHash === ZERO_BYTES32) {\n throw new Error('@seedprotocol/publish: attestDomainOwnership requires a non-zero challengeHash')\n }\n\n const verifiedAt = params.verifiedAt ?? Math.floor(Date.now() / 1000)\n const registryFingerprint = fingerprintFromRegistrySnapshot({\n domain,\n creationDate: params.registrySnapshot.creationDate ?? '',\n registrarIanaId: params.registrySnapshot.registrarIanaId ?? '',\n })\n const registryCreationDate = params.registrySnapshot.creationDate ?? ''\n const registryExpirationDate = params.registrySnapshot.expirationDate ?? ''\n const method = params.method ?? DOMAIN_OWNERSHIP_METHOD\n const expirationTime = resolveExpirationTime({\n verifiedAt,\n registryExpirationDate,\n override: params.expirationTime,\n })\n\n const data = encodeDomainOwnershipAttestationData({\n domain,\n claimer,\n method,\n challengeHash,\n verifiedAt,\n registryCreationDate,\n registryExpirationDate,\n registryFingerprint,\n scope,\n })\n\n const tx = prepareEasAttest({\n schema: schemaUid,\n data: {\n recipient: claimer as `0x${string}`,\n expirationTime: BigInt(expirationTime),\n revocable: true,\n refUID: ZERO_BYTES32 as `0x${string}`,\n data,\n value: 0n,\n },\n })\n\n const receipt = await sendAndWait(sender, tx)\n if (!receipt) {\n throw new Error('@seedprotocol/publish: attestDomainOwnership failed — no receipt')\n }\n const { easContractAddress } = getPublishConfig()\n const uid = getAttestationUidFromReceipt(receipt, easContractAddress)\n if (!uid || !isValidEasAttestationUid(uid)) {\n throw new Error(\n '@seedprotocol/publish: attestDomainOwnership failed — could not parse attestation UID',\n )\n }\n\n return {\n uid: uid as `0x${string}`,\n schemaUid,\n challengeHash,\n registryFingerprint,\n verifiedAt,\n expirationTime,\n }\n}\n\n/**\n * Revoke a DomainOwnership sidecar attestation (must be signed by the original tool attester).\n */\nexport async function revokeDomainOwnership(params: {\n wallet: PublishWallet | SeedTxSender\n uid: string\n schemaUid?: string\n}): Promise<void> {\n const sender = resolveTxSender(params.wallet)\n const schemaUid = (params.schemaUid ?? getDomainOwnershipSchemaUid()) as `0x${string}`\n const uid = normalizeBytes32Hex(params.uid) as `0x${string}`\n if (!isValidEasAttestationUid(uid)) {\n throw new Error('@seedprotocol/publish: revokeDomainOwnership requires a valid attestation uid')\n }\n\n const tx = prepareEasMultiRevoke([\n {\n schema: schemaUid,\n data: [{ uid }],\n },\n ])\n const receipt = await sendAndWait(sender, tx)\n if (!receipt) {\n throw new Error('@seedprotocol/publish: revokeDomainOwnership failed — no receipt')\n }\n}\n\nexport type VerifyDomainOwnershipChallengeResult = {\n ok: boolean\n dns: VerifyDomainOwnershipDnsResult\n registrySnapshot: DomainRegistrySnapshot | null\n challengeHash: `0x${string}`\n error?: string\n}\n\n/**\n * Verify DNS TXT for a caller-held challenge and fetch an RDAP registry snapshot.\n * Does not write an attestation.\n */\nexport async function verifyDomainOwnershipChallenge(params: {\n challenge: DomainOwnershipChallenge\n /** Injected DNS lookups for tests. */\n dnsLookups?: Array<\n (name: string) => Promise<{ source: string; values: string[]; dnssecAuthenticated?: boolean }>\n >\n /** Injected registry lookup for tests. */\n registryLookup?: (domain: string) => Promise<DomainRegistrySnapshot | null>\n now?: number\n}): Promise<VerifyDomainOwnershipChallengeResult> {\n const { challenge } = params\n const expectedHash = hashDomainOwnershipChallenge({\n domain: challenge.domain,\n claimer: challenge.claimer,\n token: challenge.token,\n scope: challenge.scope,\n })\n if (normalizeBytes32Hex(expectedHash) !== normalizeBytes32Hex(challenge.challengeHash)) {\n return {\n ok: false,\n dns: { ok: false, matchedSources: [], lookups: [], error: 'challengeHash mismatch' },\n registrySnapshot: null,\n challengeHash: expectedHash,\n error: 'Challenge hash does not match domain/claimer/token/scope',\n }\n }\n\n const dns = await verifyDomainOwnershipDns(challenge, {\n lookups: params.dnsLookups,\n now: params.now,\n })\n if (!dns.ok) {\n return {\n ok: false,\n dns,\n registrySnapshot: null,\n challengeHash: expectedHash,\n error: dns.error ?? 'DNS verification failed',\n }\n }\n\n const registryLookup = params.registryLookup ?? lookupDomainRegistry\n let registrySnapshot: DomainRegistrySnapshot | null\n try {\n registrySnapshot = await registryLookup(challenge.domain)\n } catch {\n registrySnapshot = null\n }\n\n if (!registrySnapshot) {\n return {\n ok: false,\n dns,\n registrySnapshot: null,\n challengeHash: expectedHash,\n error: 'Registry lookup failed',\n }\n }\n\n return {\n ok: true,\n dns,\n registrySnapshot,\n challengeHash: expectedHash,\n }\n}\n\nexport type VerifyAndAttestDomainOwnershipResult = AttestDomainOwnershipResult & {\n registrySnapshot: DomainRegistrySnapshot\n dns: VerifyDomainOwnershipDnsResult\n}\n\n/**\n * Verify DNS + RDAP, then attest from the tool wallet.\n */\nexport async function verifyAndAttestDomainOwnership(params: {\n challenge: DomainOwnershipChallenge\n wallet: PublishWallet | SeedTxSender\n ensureSchema?: boolean\n dnsLookups?: Array<\n (name: string) => Promise<{ source: string; values: string[]; dnssecAuthenticated?: boolean }>\n >\n registryLookup?: (domain: string) => Promise<DomainRegistrySnapshot | null>\n now?: number\n}): Promise<VerifyAndAttestDomainOwnershipResult> {\n const verified = await verifyDomainOwnershipChallenge({\n challenge: params.challenge,\n dnsLookups: params.dnsLookups,\n registryLookup: params.registryLookup,\n now: params.now,\n })\n if (!verified.ok || !verified.registrySnapshot) {\n throw new Error(\n `@seedprotocol/publish: verifyAndAttestDomainOwnership failed — ${verified.error ?? 'verification failed'}`,\n )\n }\n\n const attested = await attestDomainOwnership({\n wallet: params.wallet,\n domain: params.challenge.domain,\n claimer: params.challenge.claimer,\n challengeHash: verified.challengeHash,\n registrySnapshot: verified.registrySnapshot,\n scope: params.challenge.scope,\n method: params.challenge.method,\n ensureSchema: params.ensureSchema,\n })\n\n return {\n ...attested,\n registrySnapshot: verified.registrySnapshot,\n dns: verified.dns,\n }\n}\n\nexport type AssessDomainOwnershipLiveResult = DomainOwnershipAssessResult & {\n decoded: DomainOwnershipDecoded\n uid: string\n registrySnapshot: DomainRegistrySnapshot | null\n}\n\n/**\n * Load a DomainOwnership attestation (by UID via tool allowlist query) and recheck RDAP.\n */\nexport async function assessDomainOwnershipLive(params: {\n uid: string\n toolAddresses: string[]\n schemaUid?: string\n registryLookup?: (domain: string) => Promise<DomainRegistrySnapshot | null>\n now?: number\n}): Promise<AssessDomainOwnershipLiveResult> {\n const rows = await getDomainOwnershipFromEas({\n toolAddresses: params.toolAddresses,\n schemaUid: params.schemaUid,\n excludeRevoked: true,\n })\n const row = rows.find((r) => normalizeBytes32Hex(r.id) === normalizeBytes32Hex(params.uid))\n if (!row) {\n throw new Error(\n '@seedprotocol/publish: assessDomainOwnershipLive could not find attestation for uid/toolAddresses',\n )\n }\n const decoded = decodeDomainOwnershipData(row.decodedDataJson ?? '[]')\n const registryLookup = params.registryLookup ?? lookupDomainRegistry\n let registrySnapshot: DomainRegistrySnapshot | null\n try {\n registrySnapshot = await registryLookup(decoded.domain)\n } catch {\n registrySnapshot = null\n }\n\n const assessed = assessDomainOwnership({\n decoded,\n expirationTime: row.expirationTime,\n registrySnapshot,\n now: params.now,\n })\n\n return {\n ...assessed,\n decoded,\n uid: row.id,\n registrySnapshot,\n }\n}\n","import {\n PUBLISHED_BY_SCHEMA_DEF,\n PUBLISHED_BY_SCHEMA_NAME,\n hashPublishedByBatch,\n type PublishedByDecoded,\n} from '@seedprotocol/eas'\nimport { SchemaEncoder, NO_EXPIRATION, ZERO_BYTES32 } from '@ethereum-attestation-service/eas-sdk'\nimport { SchemaRegistry } from '@ethereum-attestation-service/eas-sdk'\nimport { prepareEasAttest, prepareEasMultiRevoke, ZERO_ADDRESS } from '~/helpers/easDirect'\nimport { getSchemaRecord, registerSchema } from '~/helpers/schemaRegistry'\nimport { prepareNameSchemaAttestation } from '~/helpers/nameSchemaAttestation'\nimport { waitForPublishReceipt } from '~/helpers/chainClient'\nimport { getPublishConfig } from '~/config'\nimport {\n isPublishWallet,\n isSeedTxSender,\n type PublishWallet,\n type SeedTxSender,\n} from '~/helpers/seedSigner'\nimport { getAttestationUidFromReceipt } from '~/helpers/easDirect'\nimport { normalizeBytes32Hex, isValidEasAttestationUid } from '@seedprotocol/eas'\n\nexport {\n PUBLISHED_BY_SCHEMA_DEF,\n PUBLISHED_BY_SCHEMA_NAME,\n hashPublishedByBatch,\n} from '@seedprotocol/eas'\n\nconst RESOLVER_ADDRESS = '0x0000000000000000000000000000000000000000'\nconst REVOCABLE = true\n\nexport type PublishedBatchResult = {\n seedUid: `0x${string}`\n versionUid?: `0x${string}`\n attestationUids: `0x${string}`[]\n}\n\nexport type OnPublishedCallback = (\n result: PublishedBatchResult & { seedLocalId: string },\n) => void | Promise<void>\n\nexport type AttestPublishedByUidsMode = {\n mode: 'uids'\n attestationUids: readonly string[]\n /** Optional override; defaults to hash of sorted attestationUids. */\n batchHash?: string\n}\n\nexport type AttestPublishedByHashMode = {\n mode: 'hash'\n batchHash: string\n /** On-chain array is empty; keep the full list off-chain for verification. */\n attestationUids?: never\n}\n\nexport type AttestPublishedByParams = {\n wallet: PublishWallet | SeedTxSender\n seedUid: string\n versionUid?: string\n toolName: string\n toolVersion: string\n /**\n * When true (default), register + name the PublishedBy schema if missing.\n */\n ensureSchema?: boolean\n} & (AttestPublishedByUidsMode | AttestPublishedByHashMode)\n\nexport type AttestPublishedByResult = {\n uid: `0x${string}`\n schemaUid: `0x${string}`\n batchHash: `0x${string}`\n attestationUids: `0x${string}`[]\n}\n\nfunction resolveTxSender(account: PublishWallet | SeedTxSender): SeedTxSender {\n if (isPublishWallet(account)) return account.txSender\n if (isSeedTxSender(account)) return account\n throw new Error(\n '@seedprotocol/publish: attestPublishedBy / revokePublishedBy require a PublishWallet or SeedTxSender',\n )\n}\n\nasync function sendAndWait(txSender: SeedTxSender, tx: Parameters<SeedTxSender['sendTransaction']>[0]) {\n const result = await txSender.sendTransaction(tx)\n return waitForPublishReceipt(result.transactionHash)\n}\n\n/** Deterministic on-chain schema UID for {@link PUBLISHED_BY_SCHEMA_DEF}. */\nexport function getPublishedBySchemaUid(): `0x${string}` {\n return SchemaRegistry.getSchemaUID(\n PUBLISHED_BY_SCHEMA_DEF,\n RESOLVER_ADDRESS as `0x${string}`,\n REVOCABLE,\n ) as `0x${string}`\n}\n\n/**\n * Registers the PublishedBy EAS schema (if missing) and creates a Schema #1 name attestation.\n */\nexport async function ensurePublishedBySchema(\n account: PublishWallet | SeedTxSender,\n): Promise<`0x${string}`> {\n const sender = resolveTxSender(account)\n const schemaUid = getPublishedBySchemaUid()\n const onChain = await getSchemaRecord(schemaUid)\n if (!onChain) {\n await sendAndWait(\n sender,\n registerSchema({\n schema: PUBLISHED_BY_SCHEMA_DEF,\n resolverAddress: RESOLVER_ADDRESS,\n revocable: REVOCABLE,\n }),\n )\n await sendAndWait(\n sender,\n prepareNameSchemaAttestation({\n schemaUid,\n schemaName: PUBLISHED_BY_SCHEMA_NAME,\n }),\n )\n }\n return schemaUid\n}\n\nexport function encodePublishedByAttestationData(params: {\n seedUid: string\n versionUid: string\n attestationUids: readonly string[]\n batchHash: string\n toolName: string\n toolVersion: string\n}): `0x${string}` {\n const schemaEncoder = new SchemaEncoder(PUBLISHED_BY_SCHEMA_DEF)\n const encodedData = schemaEncoder.encodeData([\n { name: 'seedUid', value: normalizeBytes32Hex(params.seedUid) as `0x${string}`, type: 'bytes32' },\n {\n name: 'versionUid',\n value: normalizeBytes32Hex(params.versionUid || ZERO_BYTES32) as `0x${string}`,\n type: 'bytes32',\n },\n {\n name: 'attestationUids',\n value: params.attestationUids.map((u) => normalizeBytes32Hex(u) as `0x${string}`),\n type: 'bytes32[]',\n },\n {\n name: 'batchHash',\n value: normalizeBytes32Hex(params.batchHash) as `0x${string}`,\n type: 'bytes32',\n },\n { name: 'toolName', value: params.toolName, type: 'string' },\n { name: 'toolVersion', value: params.toolVersion, type: 'string' },\n ])\n return encodedData as `0x${string}`\n}\n\n/**\n * Tool wallet attests a PublishedBy sidecar for a publish batch.\n * - `mode: 'uids'`: on-chain UID list + batchHash of sorted UIDs\n * - `mode: 'hash'`: empty UID list + caller-supplied batchHash (full list kept off-chain)\n */\nexport async function attestPublishedBy(\n params: AttestPublishedByParams,\n): Promise<AttestPublishedByResult> {\n const sender = resolveTxSender(params.wallet)\n const schemaUid =\n params.ensureSchema === false\n ? getPublishedBySchemaUid()\n : await ensurePublishedBySchema(params.wallet)\n\n let attestationUids: `0x${string}`[] = []\n let batchHash: `0x${string}`\n\n if (params.mode === 'uids') {\n attestationUids = params.attestationUids\n .map((u) => normalizeBytes32Hex(u) as `0x${string}`)\n .filter((u) => isValidEasAttestationUid(u))\n batchHash = (params.batchHash\n ? normalizeBytes32Hex(params.batchHash)\n : hashPublishedByBatch(attestationUids)) as `0x${string}`\n } else {\n if (!params.batchHash) {\n throw new Error('@seedprotocol/publish: attestPublishedBy hash mode requires batchHash')\n }\n batchHash = normalizeBytes32Hex(params.batchHash) as `0x${string}`\n if (batchHash === ZERO_BYTES32) {\n throw new Error('@seedprotocol/publish: attestPublishedBy hash mode requires a non-zero batchHash')\n }\n }\n\n const seedUid = normalizeBytes32Hex(params.seedUid) as `0x${string}`\n if (!isValidEasAttestationUid(seedUid)) {\n throw new Error('@seedprotocol/publish: attestPublishedBy requires a valid seedUid')\n }\n\n const versionUid = normalizeBytes32Hex(params.versionUid ?? ZERO_BYTES32) as `0x${string}`\n const data = encodePublishedByAttestationData({\n seedUid,\n versionUid,\n attestationUids,\n batchHash,\n toolName: params.toolName,\n toolVersion: params.toolVersion,\n })\n\n const tx = prepareEasAttest({\n schema: schemaUid,\n data: {\n recipient: ZERO_ADDRESS as `0x${string}`,\n expirationTime: BigInt(NO_EXPIRATION),\n revocable: true,\n refUID: seedUid,\n data,\n value: 0n,\n },\n })\n\n const receipt = await sendAndWait(sender, tx)\n if (!receipt) {\n throw new Error('@seedprotocol/publish: attestPublishedBy failed — no receipt')\n }\n const { easContractAddress } = getPublishConfig()\n const uid = getAttestationUidFromReceipt(receipt, easContractAddress)\n if (!uid || !isValidEasAttestationUid(uid)) {\n throw new Error('@seedprotocol/publish: attestPublishedBy failed — could not parse attestation UID')\n }\n\n return {\n uid: uid as `0x${string}`,\n schemaUid,\n batchHash,\n attestationUids,\n }\n}\n\n/**\n * Revoke a PublishedBy sidecar attestation (must be signed by the original tool attester).\n */\nexport async function revokePublishedBy(params: {\n wallet: PublishWallet | SeedTxSender\n uid: string\n schemaUid?: string\n}): Promise<void> {\n const sender = resolveTxSender(params.wallet)\n const schemaUid = (params.schemaUid ?? getPublishedBySchemaUid()) as `0x${string}`\n const uid = normalizeBytes32Hex(params.uid) as `0x${string}`\n if (!isValidEasAttestationUid(uid)) {\n throw new Error('@seedprotocol/publish: revokePublishedBy requires a valid attestation uid')\n }\n\n const tx = prepareEasMultiRevoke([\n {\n schema: schemaUid,\n data: [{ uid }],\n },\n ])\n const receipt = await sendAndWait(sender, tx)\n if (!receipt) {\n throw new Error('@seedprotocol/publish: revokePublishedBy failed — no receipt')\n }\n}\n\nexport type { PublishedByDecoded }\n\nexport { collectPublishedBatch, uidsFromAttestationPairs } from './collectBatchUids'\n"],"mappings":"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"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { t as e } from "./rolldown-runtime-Dy4uBu1J.js";
|
|
2
|
-
import { G as t, Q as n, _t as r, it as i, qt as a, t as o, zt as s } from "./chainConfig-
|
|
2
|
+
import { G as t, Q as n, _t as r, it as i, qt as a, t as o, zt as s } from "./chainConfig-B8U89YJb.js";
|
|
3
3
|
//#region src/helpers/managedAccountAdmin.ts
|
|
4
4
|
var c = /* @__PURE__ */ e({ getManagedAccountAdmin: () => l });
|
|
5
5
|
async function l(e) {
|
|
@@ -23,4 +23,4 @@ async function l(e) {
|
|
|
23
23
|
//#endregion
|
|
24
24
|
export { c as n, l as t };
|
|
25
25
|
|
|
26
|
-
//# sourceMappingURL=managedAccountAdmin-
|
|
26
|
+
//# sourceMappingURL=managedAccountAdmin-xZbC3bQ5.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"managedAccountAdmin-
|
|
1
|
+
{"version":3,"file":"managedAccountAdmin-xZbC3bQ5.js","names":["__exportAll","getModularAccountWallet","syncPublishInAppAuthToken","getPublishThirdwebChain","getClient","ManagedAccountPublishError","getPublishChainName","readIsAdmin","managedAccountAdmin_exports","getManagedAccountAdmin","wallet","admin","managedAddress","isAdmin","cause"],"sources":["../src/helpers/managedAccountAdmin.ts"],"sourcesContent":["import type { Address } from 'viem'\nimport type { Account } from 'thirdweb/wallets'\nimport { ManagedAccountPublishError } from '../errors'\nimport { getPublishChainName } from './chainConfig'\nimport { readIsAdmin } from './contracts'\nimport { getClient, getModularAccountWallet, syncPublishInAppAuthToken } from './thirdweb'\nimport { getPublishThirdwebChain } from './thirdwebChain'\n\n/**\n * Connects the user's in-app EOA, the ManagedAccount's admin, for admin-only transactions such as\n * `installSeedExecutor`. Those must come from the admin directly: the new contracts reject them as\n * self-calls from the smart account. `PublishConfig.thirdweb.modularWalletMode` decides whether\n * the EOA sends gas-sponsored EIP-7702 transactions (default) or plain funded ones.\n *\n * @throws ManagedAccountPublishError `MANAGED_ACCOUNT_UNAVAILABLE` when the wallet is not\n * connected or is not an admin of `managedAddress`\n */\nexport async function getManagedAccountAdmin(managedAddress: string): Promise<Account> {\n syncPublishInAppAuthToken()\n const wallet = getModularAccountWallet()\n await wallet.autoConnect({ client: getClient(), chain: getPublishThirdwebChain() })\n const admin = wallet.getAccount()\n if (!admin) {\n throw new ManagedAccountPublishError(\n `Could not connect the in-app wallet that administers your publishing account on ${getPublishChainName()}. Reconnect with the same sign-in method and try again.`,\n 'MANAGED_ACCOUNT_UNAVAILABLE',\n managedAddress,\n )\n }\n let isAdmin: boolean\n try {\n isAdmin = await readIsAdmin(managedAddress as Address, admin.address as Address)\n } catch (cause) {\n throw new ManagedAccountPublishError(\n `Could not check the admins of your publishing account on ${getPublishChainName()}.`,\n 'MANAGED_ACCOUNT_UNAVAILABLE',\n managedAddress,\n cause,\n )\n }\n if (!isAdmin) {\n throw new ManagedAccountPublishError(\n `The connected in-app wallet (${admin.address}) is not an admin of publishing account ${managedAddress}.`,\n 'MANAGED_ACCOUNT_UNAVAILABLE',\n managedAddress,\n )\n }\n return admin\n}\n"],"mappings":";;;;AAiBA,eAAsBS,EAAuB,GAA0C;CACrF,EAA0B;CAC1B,IAAMC,IAAST,EAAwB;CACvC,MAAMS,EAAO,YAAY;EAAE,QAAQN,EAAU;EAAG,OAAOD,EAAwB;CAAE,CAAC;CAClF,IAAMQ,IAAQD,EAAO,WAAW;CAChC,IAAI,CAACC,GACH,MAAM,IAAIN,EACR,mFAAmFC,EAAoB,EAAE,0DACzG,+BACAM,CACF;CAEF,IAAIC;CACJ,IAAI;EACF,IAAU,MAAMN,EAAYK,GAA2BD,EAAM,OAAkB;CACjF,SAASG,GAAO;EACd,MAAM,IAAIT,EACR,4DAA4DC,EAAoB,EAAE,IAClF,+BACAM,GACAE,CACF;CACF;CACA,IAAI,CAACD,GACH,MAAM,IAAIR,EACR,gCAAgCM,EAAM,QAAQ,0CAA0CC,EAAe,IACvG,+BACAA,CACF;CAEF,OAAOD;AACT"}
|