@elisym/commerce 0.1.0 → 0.3.0

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/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/constants.ts","../src/caip.ts","../src/wallet-proof.ts","../src/tags.ts","../src/domain.ts","../src/events/payto.ts","../src/events/store-auth.ts","../src/events/store-profile.ts","../src/events/product.ts","../src/orders/messages.ts","../src/verify.ts","../src/orders/gift-wrap.ts","../src/verify-offer.ts"],"names":["UTF8","base58","keccak_256","hex","nip19","CURRENCY_RE"],"mappings":"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","file":"index.js","sourcesContent":["/** Store profile (NIP-01), signed by the store key. */\nexport const KIND_STORE_PROFILE = 0;\n/** Payout addresses (NIP-A3 `payto` plus the elisym `accept` extension), signed by the owner key. */\nexport const KIND_PAYTO = 10133;\n/**\n * \"Store key S acts for owner O\", signed by the owner key. Addressable, `d` = the\n * store pubkey.\n *\n * PROVISIONAL: the number is not registered yet (spec, open question 1). It is\n * named in one place so that fixing it is a one-line change.\n */\nexport const KIND_STORE_AUTH = 30490;\n/** Product listing (NIP-99, Gamma Markets), signed by the store key. */\nexport const KIND_PRODUCT = 30402;\n/** Inbox relays for gift-wrapped messages (NIP-17). */\nexport const KIND_INBOX_RELAYS = 10050;\n/** Order message inside a gift wrap: `type` 1 order, 2 payment request, 3 status (Gamma Markets). */\nexport const KIND_ORDER_MESSAGE = 16;\n/** Payment receipt inside a gift wrap (Gamma Markets). */\nexport const KIND_PAYMENT_RECEIPT = 17;\n/** NIP-09 deletion: an `a` tag on the owner's AUTH address revokes it, like `mode` revoked. */\nexport const KIND_DELETION = 5;\nexport const KIND_SEAL = 13;\nexport const KIND_GIFT_WRAP = 1059;\n\n/** Opt-in tag value that lists a product in the elisym aggregator. */\nexport const ELISYM_NETWORK_TAG = 'elisym';\n\n/**\n * What a payout wallet signs to prove it belongs to the owner. The owner pubkey\n * and the CAIP-19 id are both inside, so a proof made for one owner or one asset\n * cannot be replayed for another.\n */\nexport const PAYTO_PROOF_PREFIX = 'elisym-payto:v1';\n\nexport const DELIVERY_METHODS = ['download', 'license', 'access', 'webhook', 'api'] as const;\nexport type DeliveryMethod = (typeof DELIVERY_METHODS)[number];\n\nexport const ORDER_STATUSES = ['pending', 'confirmed', 'completed', 'cancelled'] as const;\nexport type OrderStatus = (typeof ORDER_STATUSES)[number];\n\n/** Gamma Markets visibility values under which a product can be bought. */\nexport const PURCHASABLE_VISIBILITIES = ['on-sale', 'pre-order'] as const;\n\n/** A payout address younger than this is flagged: the owner key may have been taken over. */\nexport const PAYOUT_COOLDOWN_SECS = 72 * 60 * 60;\n\n/** How far in the future an event's `created_at` may sit before it is ignored. */\nexport const MAX_FUTURE_SKEW_SECS = 15 * 60;\n\nexport const LIMITS = {\n MAX_ORDER_ID_LENGTH: 64,\n MAX_TAG_VALUE_LENGTH: 1024,\n MAX_CONTENT_LENGTH: 64 * 1024,\n MAX_ITEMS_PER_ORDER: 50,\n MAX_NIP05_DOCUMENT_BYTES: 64 * 1024,\n} as const;\n","import {\n type Asset,\n type ChainConfig,\n assetsFor,\n chainByCaip2,\n isEvmWireAddress,\n isVirtualEvmAddress,\n} from '@elisym/pay-core';\nimport { keccak_256 } from '@noble/hashes/sha3.js';\nimport { base58, hex } from '@scure/base';\n\nconst SOLANA_ADDRESS_RE = /^[1-9A-HJ-NP-Za-km-z]{32,44}$/;\nconst CAIP19_RE = /^([a-z0-9-]{3,8}:[-_a-zA-Z0-9]{1,32})\\/(token|erc20):([-.%a-zA-Z0-9]{1,128})$/;\n\nconst SOLANA_PUBLIC_KEY_BYTES = 32;\n/** 32 zero bytes (the System Program id): no one holds its key, so a payment there is burnt. */\nconst SOLANA_ZERO_KEY = '1'.repeat(32);\nconst EVM_ZERO_ADDRESS = `0x${'0'.repeat(40)}`;\nconst UTF8 = new TextEncoder();\n\nfunction isSolanaPublicKey(address: string): boolean {\n try {\n return base58.decode(address).length === SOLANA_PUBLIC_KEY_BYTES;\n } catch {\n return false;\n }\n}\n\nexport interface Caip19 {\n /** The full id, exactly as written. */\n id: string;\n caip2: string;\n chain: ChainConfig;\n /** The registry coin it names, on that chain's environment. */\n asset: Asset;\n}\n\n/**\n * Parse a CAIP-19 id for a coin the payment registry knows: `solana:<ref>/token:<mint>`\n * or `eip155:<id>/erc20:<lowercase contract>`. Anything else - an unknown chain,\n * a namespace that does not fit the chain, a coin the registry does not hold -\n * is `undefined`: an asset nothing can pay in is not an asset.\n */\nexport function parseCaip19(id: string): Caip19 | undefined {\n const match = CAIP19_RE.exec(id);\n const caip2 = match?.[1];\n const namespace = match?.[2];\n const reference = match?.[3];\n if (!caip2 || !namespace || !reference) {\n return undefined;\n }\n const chain = chainByCaip2(caip2);\n if (!chain) {\n return undefined;\n }\n const expectedNamespace = chain.family === 'solana' ? 'token' : 'erc20';\n if (namespace !== expectedNamespace) {\n return undefined;\n }\n if (chain.family === 'evm' && !isEvmWireAddress(reference)) {\n return undefined;\n }\n const asset = assetsFor(chain.slug, chain.network).find((coin) => coin.mint === reference);\n if (!asset) {\n return undefined;\n }\n return { id, caip2, chain, asset };\n}\n\n/**\n * Whether a mixed-case EVM address carries a valid EIP-55 checksum. An address\n * in one case has none to check and passes; a mixed-case one with a wrong\n * checksum is a typo.\n */\nexport function hasValidEvmChecksum(address: string): boolean {\n const body = address.slice(2);\n if (body === body.toLowerCase() || body === body.toUpperCase()) {\n return true;\n }\n const digest = hex.encode(keccak_256(UTF8.encode(body.toLowerCase())));\n for (let i = 0; i < body.length; i++) {\n const char = body[i] ?? '';\n const nibble = Number.parseInt(digest[i] ?? '0', 16);\n const expected = nibble >= 8 ? char.toUpperCase() : char.toLowerCase();\n if (char !== expected) {\n return false;\n }\n }\n return true;\n}\n\n/**\n * The one canonical spelling of a payout address on a chain, or `undefined` if it\n * is not one. EVM addresses are lowercase on the wire, so every comparison is\n * plain equality; a virtual (TIP-1022) address is refused, as the payment rail does.\n */\nexport function canonicalPayoutAddress(chain: ChainConfig, address: string): string | undefined {\n if (chain.family === 'solana') {\n return SOLANA_ADDRESS_RE.test(address) &&\n isSolanaPublicKey(address) &&\n address !== SOLANA_ZERO_KEY\n ? address\n : undefined;\n }\n const lowered = address.toLowerCase();\n // The zero address burns whatever is sent to it.\n if (!isEvmWireAddress(lowered) || isVirtualEvmAddress(lowered) || lowered === EVM_ZERO_ADDRESS) {\n return undefined;\n }\n return lowered;\n}\n","import type { ChainConfig } from '@elisym/pay-core';\nimport { ed25519 } from '@noble/curves/ed25519.js';\nimport { secp256k1 } from '@noble/curves/secp256k1.js';\nimport { keccak_256 } from '@noble/hashes/sha3.js';\nimport { base58, hex } from '@scure/base';\nimport { PAYTO_PROOF_PREFIX } from './constants';\n\nconst EVM_SIGNATURE_RE = /^0x[0-9a-fA-F]{130}$/;\nconst ED25519_SIGNATURE_BYTES = 64;\nconst ED25519_PUBLIC_KEY_BYTES = 32;\nconst UTF8 = new TextEncoder();\n\n/**\n * The exact text a payout wallet signs for an `accept` tag. A Solana wallet signs\n * its UTF-8 bytes with `signMessage`; an EVM wallet signs it with `personal_sign`\n * (EIP-191).\n */\nexport function paytoProofMessage(ownerPubkey: string, caip19: string): string {\n return `${PAYTO_PROOF_PREFIX}:${ownerPubkey}:${caip19}`;\n}\n\n/**\n * Whether `signature` proves that the wallet at `address` agreed to receive\n * `caip19` payments for `ownerPubkey`.\n *\n * Encodings, one per family and nothing else: Solana - the 64-byte ed25519\n * signature in base58, `address` the base58 public key; EVM - the 65-byte\n * `r || s || v` signature as `0x` hex, as `personal_sign` returns it, `address`\n * lowercase. Any malformed input is `false`, never a throw.\n */\nexport function verifyPaytoProof(params: {\n chain: ChainConfig;\n address: string;\n ownerPubkey: string;\n caip19: string;\n signature: string;\n}): boolean {\n const message = UTF8.encode(paytoProofMessage(params.ownerPubkey, params.caip19));\n try {\n return params.chain.family === 'solana'\n ? verifyEd25519(message, params.signature, params.address)\n : verifyEip191(message, params.signature, params.address);\n } catch {\n return false;\n }\n}\n\nfunction verifyEd25519(message: Uint8Array, signature: string, address: string): boolean {\n const signatureBytes = base58.decode(signature);\n const publicKey = base58.decode(address);\n if (\n signatureBytes.length !== ED25519_SIGNATURE_BYTES ||\n publicKey.length !== ED25519_PUBLIC_KEY_BYTES\n ) {\n return false;\n }\n // zip215: false is the strict RFC 8032 check, which is what Solana wallets produce.\n return ed25519.verify(signatureBytes, message, publicKey, { zip215: false });\n}\n\n/** keccak256(\"\\x19Ethereum Signed Message:\\n\" + len(message) + message). */\nexport function eip191Hash(message: Uint8Array): Uint8Array {\n const prefix = UTF8.encode(`\\x19Ethereum Signed Message:\\n${message.length}`);\n const payload = new Uint8Array(prefix.length + message.length);\n payload.set(prefix, 0);\n payload.set(message, prefix.length);\n return keccak_256(payload);\n}\n\nfunction verifyEip191(message: Uint8Array, signature: string, address: string): boolean {\n if (!EVM_SIGNATURE_RE.test(signature)) {\n return false;\n }\n const bytes = hex.decode(signature.slice(2).toLowerCase());\n const recoveryByte = bytes[64];\n if (recoveryByte === undefined) {\n return false;\n }\n // Wallets write v as 27/28; some write the bare recovery id 0/1.\n const recovery = recoveryByte >= 27 ? recoveryByte - 27 : recoveryByte;\n if (recovery !== 0 && recovery !== 1) {\n return false;\n }\n // noble's 'recovered' format puts the recovery id FIRST: [v, r, s].\n const recovered = new Uint8Array(65);\n recovered[0] = recovery;\n recovered.set(bytes.subarray(0, 64), 1);\n const publicKey = secp256k1.recoverPublicKey(recovered, eip191Hash(message), {\n prehash: false,\n });\n return evmAddressOf(publicKey) === address.toLowerCase();\n}\n\nfunction evmAddressOf(publicKey: Uint8Array): string {\n const uncompressed = secp256k1.Point.fromBytes(publicKey).toBytes(false);\n const digest = keccak_256(uncompressed.subarray(1));\n return `0x${hex.encode(digest.subarray(12))}`;\n}\n","export type Tags = readonly (readonly string[])[];\n\nexport const HEX_PUBKEY_RE = /^[0-9a-f]{64}$/;\n\nexport function tagValue(tags: Tags, name: string): string | undefined {\n return tags.find((tag) => tag[0] === name)?.[1];\n}\n\nexport function tagsNamed(tags: Tags, name: string): (readonly string[])[] {\n return tags.filter((tag) => tag[0] === name);\n}\n\nexport function tagValues(tags: Tags, name: string): string[] {\n return tagsNamed(tags, name)\n .map((tag) => tag[1])\n .filter((value): value is string => value !== undefined);\n}\n\nconst EXPIRATION_RE = /^\\d{1,12}$/;\n\n/**\n * An event's NIP-40 expiration at `now`. Strict: two tags, a tag with no value,\n * or a value that is not whole seconds is `malformed`, never \"does not expire\".\n */\nexport function expirationState(\n tags: Tags,\n now: number,\n): 'none' | 'active' | 'expired' | 'malformed' {\n const expirationTags = tagsNamed(tags, 'expiration');\n if (expirationTags.length === 0) {\n return 'none';\n }\n const expiration = expirationTags[0]?.[1] ?? '';\n if (expirationTags.length > 1 || !EXPIRATION_RE.test(expiration)) {\n return 'malformed';\n }\n return Number(expiration) <= now ? 'expired' : 'active';\n}\n\nexport function nowSecs(): number {\n return Math.floor(Date.now() / 1000);\n}\n","import * as nip19 from 'nostr-tools/nip19';\nimport { LIMITS } from './constants';\nimport { HEX_PUBKEY_RE } from './tags';\n\nconst HOSTNAME_LABEL_RE = /^[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?$/;\nconst LOCAL_PART_RE = /^[a-z0-9._-]{1,64}$/;\nconst MAX_HOSTNAME_LENGTH = 253;\n/** Names that resolve to this machine or a private network, never to a public host (RFC 6761 and kin). */\nconst SPECIAL_USE_TOP_LEVELS: readonly string[] = [\n 'localhost',\n 'local',\n 'internal',\n 'arpa',\n 'test',\n 'invalid',\n 'onion',\n 'lan',\n 'home',\n 'corp',\n 'intranet',\n 'private',\n];\nconst OWNER_NAME = 'owner';\nconst TXT_PREFIX = 'v=elisym1';\nconst DEFAULT_TIMEOUT_MS = 5_000;\nconst DEFAULT_DOH_ENDPOINT = 'https://cloudflare-dns.com/dns-query';\nconst DNS_TYPE_TXT = 16;\n\n/** The keys a merchant's domain vouches for. */\nexport interface DomainKeys {\n domain: string;\n /**\n * The NIP-05 name that was looked up (`_` for the domain itself). The answer\n * vouches for that name only: a profile under another name cannot borrow it.\n */\n name: string;\n storePubkey?: string;\n ownerPubkey?: string;\n source: 'nostr.json' | 'dns';\n}\n\nexport type FetchLike = (input: string, init?: RequestInit) => Promise<Response>;\n\n/**\n * A public DNS name: lowercase labels, at least two, no IP literal, no port. The\n * domain comes from a store's own profile - attacker-controlled - so nothing\n * else is fetched.\n */\nexport function isPublicHostname(hostname: string): boolean {\n if (hostname.length === 0 || hostname.length > MAX_HOSTNAME_LENGTH) {\n return false;\n }\n const labels = hostname.split('.');\n if (labels.length < 2 || !labels.every((label) => HOSTNAME_LABEL_RE.test(label))) {\n return false;\n }\n const topLevel = labels[labels.length - 1] ?? '';\n // A URL parser reads a name whose last label is a number - decimal or `0x` hex -\n // as an IPv4 literal (`127.0.0.0x1` is 127.0.0.1), never a public name.\n return !/^(\\d+|0x[0-9a-f]*)$/.test(topLevel) && !SPECIAL_USE_TOP_LEVELS.includes(topLevel);\n}\n\n/** Split `local@domain` (NIP-05; a bare domain means `_@domain`), lowercased, or `undefined`. */\nexport function splitNip05(identifier: string): { local: string; domain: string } | undefined {\n const lowered = identifier.trim().toLowerCase();\n const at = lowered.lastIndexOf('@');\n const local = at === -1 ? '_' : lowered.slice(0, at);\n const domain = at === -1 ? lowered : lowered.slice(at + 1);\n if (!LOCAL_PART_RE.test(local) || !isPublicHostname(domain)) {\n return undefined;\n }\n return { local, domain };\n}\n\nfunction readHexKey(value: unknown): string | undefined {\n return typeof value === 'string' && HEX_PUBKEY_RE.test(value) ? value : undefined;\n}\n\n/** The store (under `local`) and the owner (under `owner`) a `nostr.json` names. */\nexport function readNostrJson(\n document: unknown,\n local: string,\n): Pick<DomainKeys, 'storePubkey' | 'ownerPubkey'> {\n const names = fieldOf(document, 'names');\n if (typeof names !== 'object' || names === null) {\n return {};\n }\n const entries: Record<string, unknown> = { ...names };\n const keys: Pick<DomainKeys, 'storePubkey' | 'ownerPubkey'> = {};\n const storePubkey = readHexKey(entries[local]);\n const ownerPubkey = readHexKey(entries[OWNER_NAME]);\n if (storePubkey) {\n keys.storePubkey = storePubkey;\n }\n if (ownerPubkey) {\n keys.ownerPubkey = ownerPubkey;\n }\n return keys;\n}\n\nfunction npubToHex(value: string | undefined): string | undefined {\n if (value === undefined) {\n return undefined;\n }\n if (HEX_PUBKEY_RE.test(value)) {\n return value;\n }\n try {\n const decoded = nip19.decode(value);\n return decoded.type === 'npub' ? decoded.data : undefined;\n } catch {\n return undefined;\n }\n}\n\n/** `v=elisym1; owner=npub1...; store=npub1...` - the DNS record for sites that cannot serve `/.well-known`. */\nexport function readElisymTxt(record: string): Pick<DomainKeys, 'storePubkey' | 'ownerPubkey'> {\n const parts = record.split(';').map((part) => part.trim());\n if (parts[0] !== TXT_PREFIX) {\n return {};\n }\n const fields = new Map<string, string>();\n for (const part of parts.slice(1)) {\n const eq = part.indexOf('=');\n if (eq > 0) {\n const name = part.slice(0, eq).trim();\n // A key given twice vouches for nothing, as records that disagree do not.\n if (fields.has(name)) {\n return {};\n }\n fields.set(name, part.slice(eq + 1).trim());\n }\n }\n const keys: Pick<DomainKeys, 'storePubkey' | 'ownerPubkey'> = {};\n const storePubkey = npubToHex(fields.get('store'));\n const ownerPubkey = npubToHex(fields.get('owner'));\n if (storePubkey) {\n keys.storePubkey = storePubkey;\n }\n if (ownerPubkey) {\n keys.ownerPubkey = ownerPubkey;\n }\n return keys;\n}\n\n/** Read at most the byte cap, cancelling the stream past it: the host is not ours to trust. */\nasync function readCappedJson(response: Response): Promise<unknown> {\n const reader = response.body?.getReader();\n if (!reader) {\n return undefined;\n }\n const chunks: Uint8Array[] = [];\n let total = 0;\n for (;;) {\n const { done, value } = await reader.read();\n if (done) {\n break;\n }\n total += value.byteLength;\n if (total > LIMITS.MAX_NIP05_DOCUMENT_BYTES) {\n await reader.cancel();\n return undefined;\n }\n chunks.push(value);\n }\n const bytes = new Uint8Array(total);\n let offset = 0;\n for (const chunk of chunks) {\n bytes.set(chunk, offset);\n offset += chunk.byteLength;\n }\n try {\n return JSON.parse(new TextDecoder().decode(bytes));\n } catch {\n return undefined;\n }\n}\n\nfunction fieldOf(value: unknown, name: string): unknown {\n if (typeof value !== 'object' || value === null) {\n return undefined;\n }\n const record: Record<string, unknown> = { ...value };\n return record[name];\n}\n\nfunction timeoutSignal(timeoutMs: number): AbortSignal {\n return AbortSignal.timeout(timeoutMs);\n}\n\nasync function fetchNostrJson(\n name: string,\n domain: string,\n fetchImpl: FetchLike,\n timeoutMs: number,\n): Promise<Pick<DomainKeys, 'storePubkey' | 'ownerPubkey'>> {\n const url = `https://${domain}/.well-known/nostr.json?name=${encodeURIComponent(name)}`;\n // NIP-05: a redirect must not be followed - it would let another host answer for this one.\n const response = await fetchImpl(url, {\n redirect: 'error',\n signal: timeoutSignal(timeoutMs),\n headers: { accept: 'application/json' },\n });\n if (!response.ok) {\n await response.body?.cancel();\n return {};\n }\n return readNostrJson(await readCappedJson(response), name);\n}\n\nasync function fetchNostrJsonKeys(\n local: string,\n domain: string,\n fetchImpl: FetchLike,\n timeoutMs: number,\n): Promise<DomainKeys | undefined> {\n const keys = await fetchNostrJson(local, domain, fetchImpl, timeoutMs);\n // Without the store under the asked name this answer vouches for nothing:\n // let the TXT record speak instead.\n if (!keys.storePubkey) {\n return undefined;\n }\n // A server that answers only the name asked for never lists `owner` beside `_`.\n if (!keys.ownerPubkey && local === '_') {\n try {\n const owner = await fetchNostrJson(OWNER_NAME, domain, fetchImpl, timeoutMs);\n if (owner.ownerPubkey) {\n keys.ownerPubkey = owner.ownerPubkey;\n }\n } catch {\n // The store entry still stands without the owner.\n }\n }\n return { domain, name: local, source: 'nostr.json', ...keys };\n}\n\nasync function fetchTxtKeys(\n domain: string,\n name: string,\n fetchImpl: FetchLike,\n timeoutMs: number,\n dohEndpoint: string,\n): Promise<DomainKeys | undefined> {\n const url = new URL(dohEndpoint);\n url.searchParams.set('name', `_elisym.${domain}`);\n url.searchParams.set('type', 'TXT');\n const response = await fetchImpl(url.toString(), {\n signal: timeoutSignal(timeoutMs),\n headers: { accept: 'application/dns-json' },\n });\n if (!response.ok) {\n await response.body?.cancel();\n return undefined;\n }\n const answers = fieldOf(await readCappedJson(response), 'Answer');\n if (!Array.isArray(answers)) {\n return undefined;\n }\n let found: Pick<DomainKeys, 'storePubkey' | 'ownerPubkey'> | undefined;\n for (const answer of answers) {\n const type = fieldOf(answer, 'type');\n const data = fieldOf(answer, 'data');\n if (type !== DNS_TYPE_TXT || typeof data !== 'string') {\n continue;\n }\n // DoH JSON quotes each character-string; a long record is split in several.\n const record = data.replace(/\"\\s*\"/g, '').replace(/^\"|\"$/g, '');\n const keys = readElisymTxt(record);\n if (!keys.storePubkey) {\n continue;\n }\n // Answer order is not guaranteed: records that disagree vouch for nothing,\n // rather than for whichever one came first this time.\n if (\n found !== undefined &&\n (found.storePubkey !== keys.storePubkey || found.ownerPubkey !== keys.ownerPubkey)\n ) {\n return undefined;\n }\n found = keys;\n }\n return found === undefined ? undefined : { domain, name, source: 'dns', ...found };\n}\n\nexport interface ResolveDomainOptions {\n /**\n * Defaults to the global `fetch`. A SERVER (resolver, merchant node) must pass\n * a fetch that refuses private addresses: the domain comes from a store's\n * profile, and an unguarded fetch is an SSRF.\n */\n fetch?: FetchLike;\n timeoutMs?: number;\n dohEndpoint?: string;\n}\n\n/**\n * The keys `nip05` vouches for, from `/.well-known/nostr.json` and then from the\n * `_elisym` TXT record. `undefined` when the domain answers neither - which is\n * not the same as vouching for OTHER keys, and the caller keeps the two apart.\n */\nexport async function resolveDomainKeys(\n nip05: string,\n options: ResolveDomainOptions = {},\n): Promise<DomainKeys | undefined> {\n const parts = splitNip05(nip05);\n if (!parts) {\n return undefined;\n }\n const fetchImpl = options.fetch ?? ((input, init) => fetch(input, init));\n const timeoutMs = options.timeoutMs ?? DEFAULT_TIMEOUT_MS;\n try {\n const fromJson = await fetchNostrJsonKeys(parts.local, parts.domain, fetchImpl, timeoutMs);\n if (fromJson) {\n return fromJson;\n }\n } catch {\n // Fall through to DNS: a site builder may serve no /.well-known at all.\n }\n try {\n return await fetchTxtKeys(\n parts.domain,\n parts.local,\n fetchImpl,\n timeoutMs,\n options.dohEndpoint ?? DEFAULT_DOH_ENDPOINT,\n );\n } catch {\n return undefined;\n }\n}\n","import type { EventTemplate, NostrEvent } from 'nostr-tools';\nimport { canonicalPayoutAddress, hasValidEvmChecksum, parseCaip19, type Caip19 } from '../caip';\nimport { KIND_PAYTO } from '../constants';\nimport { HEX_PUBKEY_RE, nowSecs, tagsNamed } from '../tags';\nimport { verifyPaytoProof } from '../wallet-proof';\n\n/** One payout address for one asset, as the owner published it. */\nexport interface PayoutTarget {\n caip19: Caip19;\n /** Canonical spelling (lowercase on EVM). */\n address: string;\n /** The wallet signed the proof message for this owner and asset, and it checks out. */\n walletSigned: boolean;\n}\n\nexport interface PaytoInput {\n /** NIP-A3 `payto` entries, e.g. `{ type: 'solana', authority: '<address>' }`. */\n payto?: readonly { type: string; authority: string }[];\n accept: readonly { caip19: string; address: string; signature?: string }[];\n /**\n * The owner key that will sign the event. Required with any wallet signature:\n * a proof made for another owner or asset is checked here, since every reader\n * would drop that address.\n */\n ownerPubkey?: string;\n createdAt?: number;\n}\n\n/** Build the owner's kind 10133 event. The caller signs it with the OWNER key. */\nexport function buildPaytoEvent(input: PaytoInput): EventTemplate {\n const tags: string[][] = [];\n for (const entry of input.payto ?? []) {\n tags.push(['payto', entry.type, entry.authority]);\n }\n for (const entry of input.accept) {\n const caip19 = parseCaip19(entry.caip19);\n if (!caip19) {\n throw new Error(`Not a payable CAIP-19 asset: ${entry.caip19}`);\n }\n const address = canonicalPayoutAddress(caip19.chain, entry.address);\n if (!address) {\n throw new Error(`Not a ${caip19.chain.family} address: ${entry.address}`);\n }\n // The wire form is lowercase, so the checksum is checked here or never.\n if (caip19.chain.family === 'evm' && !hasValidEvmChecksum(entry.address)) {\n throw new Error(`EIP-55 checksum mismatch, likely a typo: ${entry.address}`);\n }\n if (entry.signature !== undefined) {\n if (input.ownerPubkey === undefined || !HEX_PUBKEY_RE.test(input.ownerPubkey)) {\n throw new Error('A wallet signature needs ownerPubkey as 64 lowercase hex characters');\n }\n const proven = verifyPaytoProof({\n chain: caip19.chain,\n address,\n ownerPubkey: input.ownerPubkey,\n caip19: caip19.id,\n signature: entry.signature,\n });\n if (!proven) {\n throw new Error(`The wallet signature does not prove ${address} for this owner and asset`);\n }\n }\n tags.push(\n entry.signature === undefined\n ? ['accept', entry.caip19, address]\n : ['accept', entry.caip19, address, entry.signature],\n );\n }\n return { kind: KIND_PAYTO, created_at: input.createdAt ?? nowSecs(), tags, content: '' };\n}\n\nexport interface ParsedPayto {\n targets: PayoutTarget[];\n /** `accept` entries dropped: an unknown asset, a malformed address, or a proof that fails. */\n rejected: { tag: readonly string[]; reason: 'unknown_asset' | 'bad_address' | 'bad_proof' }[];\n}\n\n/**\n * The payout targets an owner's 10133 declares, from its `accept` tags only.\n *\n * A bare NIP-A3 `payto` tag names no asset and no network environment, so it is\n * shown to generic clients but never paid to by elisym: a payment always goes to\n * an `accept` address for the exact CAIP-19 id. An `accept` tag whose wallet\n * proof is present but wrong is DROPPED, not downgraded - a wrong proof is\n * evidence of a mistake or of tampering, and neither is an address to pay.\n *\n * The caller has already checked the event's signature and that its author is\n * the owner.\n */\nexport function parsePayto(event: Pick<NostrEvent, 'pubkey' | 'tags'>): ParsedPayto {\n const candidates = new Map<string, PayoutTarget>();\n const badProof = new Set<string>();\n const rejected: ParsedPayto['rejected'] = [];\n for (const tag of tagsNamed(event.tags, 'accept')) {\n const [, caip19Id, rawAddress, signature] = tag;\n const caip19 = caip19Id === undefined ? undefined : parseCaip19(caip19Id);\n if (!caip19) {\n rejected.push({ tag, reason: 'unknown_asset' });\n continue;\n }\n const address =\n rawAddress === undefined ? undefined : canonicalPayoutAddress(caip19.chain, rawAddress);\n if (!address) {\n rejected.push({ tag, reason: 'bad_address' });\n continue;\n }\n const key = `${caip19.id}|${address}`;\n let walletSigned = false;\n if (signature !== undefined && signature !== '') {\n walletSigned = verifyPaytoProof({\n chain: caip19.chain,\n address,\n ownerPubkey: event.pubkey,\n caip19: caip19.id,\n signature,\n });\n if (!walletSigned) {\n rejected.push({ tag, reason: 'bad_proof' });\n badProof.add(key);\n continue;\n }\n }\n // Repeats of one address count once: signed if any copy carries a good proof.\n const earlier = candidates.get(key);\n if (earlier === undefined) {\n candidates.set(key, { caip19, address, walletSigned });\n } else if (walletSigned) {\n earlier.walletSigned = true;\n }\n }\n // A wrong proof anywhere condemns the address, whatever other copies say.\n const targets = [...candidates.entries()]\n .filter(([key]) => !badProof.has(key))\n .map(([, target]) => target);\n return { targets, rejected };\n}\n","import type { EventTemplate, NostrEvent } from 'nostr-tools';\nimport { KIND_STORE_AUTH } from '../constants';\nimport { HEX_PUBKEY_RE, expirationState, nowSecs, tagValue, tagsNamed } from '../tags';\n\nexport type StoreAuthMode = 'self-host' | 'hosted' | 'revoked';\n\nconst STORE_AUTH_MODES: readonly string[] = ['self-host', 'hosted', 'revoked'];\n/** The reader takes at most 12 digits: past that it is milliseconds, not seconds. */\nconst MAX_EXPIRATION_SECS = 1e12;\n\nfunction isStoreAuthMode(value: string | undefined): value is StoreAuthMode {\n return value !== undefined && STORE_AUTH_MODES.includes(value);\n}\n\nexport interface StoreAuthInput {\n storePubkey: string;\n mode: Exclude<StoreAuthMode, 'revoked'>;\n /** Hosted mode: who runs the store, e.g. `elisym.network`. */\n operator?: string;\n /** Unix seconds (NIP-40). Short windows limit the damage of a stolen store key. */\n expiresAt?: number;\n createdAt?: number;\n}\n\n/** `<kind>:<owner>:<store>`, the address a NIP-09 deletion names to revoke an AUTH. */\nexport function storeAuthAddress(ownerPubkey: string, storePubkey: string): string {\n return `${KIND_STORE_AUTH}:${ownerPubkey}:${storePubkey}`;\n}\n\n/** Build the owner's authorization of a store key. The caller signs it with the OWNER key. */\nexport function buildStoreAuthEvent(input: StoreAuthInput): EventTemplate {\n if (!HEX_PUBKEY_RE.test(input.storePubkey)) {\n throw new Error('storePubkey must be 64 lowercase hex characters');\n }\n // A plain-JS caller could pass `revoked` or a typo: revoke with buildStoreRevocationEvent.\n if (input.mode !== 'self-host' && input.mode !== 'hosted') {\n throw new Error(`Invalid store mode: ${String(input.mode)}`);\n }\n const tags: string[][] = [\n ['d', input.storePubkey],\n ['p', input.storePubkey],\n input.operator === undefined ? ['mode', input.mode] : ['mode', input.mode, input.operator],\n ];\n if (input.expiresAt !== undefined) {\n // Whole seconds that `readStoreAuth` reads back: a millisecond timestamp\n // would sign an AUTH every reader calls malformed.\n if (\n !Number.isSafeInteger(input.expiresAt) ||\n input.expiresAt <= 0 ||\n input.expiresAt >= MAX_EXPIRATION_SECS\n ) {\n throw new Error('expiresAt must be a unix time in whole seconds');\n }\n tags.push(['expiration', String(input.expiresAt)]);\n }\n return { kind: KIND_STORE_AUTH, created_at: input.createdAt ?? nowSecs(), tags, content: '' };\n}\n\n/** Revoke a store key: the same address (`d`), `mode` revoked. Newest wins. */\nexport function buildStoreRevocationEvent(storePubkey: string, createdAt?: number): EventTemplate {\n if (!HEX_PUBKEY_RE.test(storePubkey)) {\n throw new Error('storePubkey must be 64 lowercase hex characters');\n }\n return {\n kind: KIND_STORE_AUTH,\n created_at: createdAt ?? nowSecs(),\n tags: [\n ['d', storePubkey],\n ['p', storePubkey],\n ['mode', 'revoked'],\n ],\n content: '',\n };\n}\n\nexport type StoreAuthState =\n | { status: 'active'; mode: Exclude<StoreAuthMode, 'revoked'>; operator?: string }\n | { status: 'revoked' }\n | { status: 'expired' }\n | { status: 'malformed' };\n\n/**\n * What an owner's newest AUTH event for `storePubkey` says at `now`. The caller\n * has checked the signature and the author, and picked the newest event for the\n * address. An event whose `d` or `p` names another store is malformed, never active.\n */\nexport function readStoreAuth(\n event: Pick<NostrEvent, 'kind' | 'tags'>,\n storePubkey: string,\n now: number = nowSecs(),\n): StoreAuthState {\n const tags = event.tags;\n if (event.kind !== KIND_STORE_AUTH || tagValue(tags, 'd') !== storePubkey) {\n return { status: 'malformed' };\n }\n const modeTags = tagsNamed(tags, 'mode');\n // Two modes say two things: nothing reads them as one.\n if (modeTags.length !== 1) {\n return { status: 'malformed' };\n }\n const modeTag = modeTags[0];\n const mode = modeTag?.[1];\n if (!isStoreAuthMode(mode)) {\n return { status: 'malformed' };\n }\n // A revocation needs only its address and the mode (spec 2.4): taking the\n // store's key away must never hinge on a tag that only granting needs.\n if (mode === 'revoked') {\n return { status: 'revoked' };\n }\n if (!tagsNamed(tags, 'p').some((tag) => tag[1] === storePubkey)) {\n return { status: 'malformed' };\n }\n const expiration = expirationState(tags, now);\n if (expiration === 'malformed') {\n return { status: 'malformed' };\n }\n if (expiration === 'expired') {\n return { status: 'expired' };\n }\n const operator = modeTag?.[2];\n return operator === undefined ? { status: 'active', mode } : { status: 'active', mode, operator };\n}\n","import type { EventTemplate, NostrEvent } from 'nostr-tools';\nimport { KIND_STORE_PROFILE, LIMITS } from '../constants';\nimport { HEX_PUBKEY_RE, nowSecs, tagValue } from '../tags';\n\nconst PROFILE_FIELDS = ['name', 'about', 'picture', 'website', 'nip05'] as const;\ntype ProfileField = (typeof PROFILE_FIELDS)[number];\n\n/** Rendered as links or images: `https:` only, never a `javascript:` or `data:` URL. */\nconst URL_FIELDS: readonly ProfileField[] = ['picture', 'website'];\n\n/** Longest value kept per field. A kind 0 is shared with other clients, so a field past it is dropped, not the profile. */\nconst PROFILE_FIELD_LIMITS: Record<ProfileField, number> = {\n name: LIMITS.MAX_TAG_VALUE_LENGTH,\n about: LIMITS.MAX_CONTENT_LENGTH,\n picture: LIMITS.MAX_TAG_VALUE_LENGTH,\n website: LIMITS.MAX_TAG_VALUE_LENGTH,\n nip05: LIMITS.MAX_TAG_VALUE_LENGTH,\n};\n\n/** What `parseStoreProfile` keeps, and so all that `buildStoreProfileEvent` will write. */\nfunction isReadableField(key: ProfileField, value: string): boolean {\n return (\n value.length <= PROFILE_FIELD_LIMITS[key] &&\n (!URL_FIELDS.includes(key) || value.startsWith('https://'))\n );\n}\n\nexport interface StoreProfile {\n name?: string;\n about?: string;\n picture?: string;\n website?: string;\n nip05?: string;\n /** The owner pubkey the store points at (tag `owner`). One half of the two-way link. */\n ownerPubkey?: string;\n}\n\nexport interface StoreProfileInput extends Omit<StoreProfile, 'ownerPubkey'> {\n ownerPubkey: string;\n createdAt?: number;\n}\n\n/** Build the store's kind 0. The caller signs it with the STORE key. */\nexport function buildStoreProfileEvent(input: StoreProfileInput): EventTemplate {\n if (!HEX_PUBKEY_RE.test(input.ownerPubkey)) {\n throw new Error('ownerPubkey must be 64 lowercase hex characters');\n }\n const content: Record<string, string> = {};\n for (const key of PROFILE_FIELDS) {\n const value = input[key];\n if (value === undefined) {\n continue;\n }\n if (!isReadableField(key, value)) {\n throw new Error(`Profile ${key} is too long or, for a link, not https`);\n }\n content[key] = value;\n }\n return {\n kind: KIND_STORE_PROFILE,\n created_at: input.createdAt ?? nowSecs(),\n tags: [['owner', input.ownerPubkey]],\n content: JSON.stringify(content),\n };\n}\n\n/**\n * Read a store's kind 0, or `undefined` when its content is not a JSON object.\n * A field of the wrong type or past its limit is dropped on its own: other\n * clients edit the same kind 0, and one odd field is not a missing profile.\n */\nexport function parseStoreProfile(\n event: Pick<NostrEvent, 'content' | 'tags'>,\n): StoreProfile | undefined {\n let raw: unknown;\n try {\n raw = JSON.parse(event.content);\n } catch {\n return undefined;\n }\n if (typeof raw !== 'object' || raw === null || Array.isArray(raw)) {\n return undefined;\n }\n const fields: Record<string, unknown> = { ...raw };\n const owner = tagValue(event.tags, 'owner');\n const profile: StoreProfile = {};\n for (const key of PROFILE_FIELDS) {\n const value = Object.hasOwn(fields, key) ? fields[key] : undefined;\n if (typeof value === 'string' && isReadableField(key, value)) {\n profile[key] = value;\n }\n }\n if (owner !== undefined && HEX_PUBKEY_RE.test(owner)) {\n profile.ownerPubkey = owner;\n }\n return profile;\n}\n","import { type Asset, parseAssetAmount } from '@elisym/pay-core';\nimport Decimal from 'decimal.js-light';\nimport type { EventTemplate, NostrEvent } from 'nostr-tools';\nimport * as nip19 from 'nostr-tools/nip19';\nimport { z } from 'zod';\nimport { parseCaip19 } from '../caip';\nimport {\n DELIVERY_METHODS,\n type DeliveryMethod,\n ELISYM_NETWORK_TAG,\n KIND_PRODUCT,\n LIMITS,\n PURCHASABLE_VISIBILITIES,\n} from '../constants';\nimport { HEX_PUBKEY_RE, type Tags, nowSecs, tagValue, tagValues, tagsNamed } from '../tags';\n\nconst PRICE_AMOUNT_RE = /^(0|[1-9]\\d{0,11})(\\.\\d{1,18})?$/;\nconst CURRENCY_RE = /^[A-Z]{3}$/;\nconst D_TAG_RE = /^[A-Za-z0-9._:-]{1,128}$/;\nconst FREQUENCIES = ['hour', 'day', 'week', 'month', 'year'] as const;\nconst ENDPOINT_TYPES = ['x402', 'mpp'] as const;\n\n/** USD-pegged coins a `USD` price is paid in at 1:1. */\nconst USD_STABLE_TOKENS: readonly string[] = ['usdc', 'usdce', 'pathusd'];\n\nexport type PriceFrequency = (typeof FREQUENCIES)[number];\nexport type EndpointType = (typeof ENDPOINT_TYPES)[number];\n\nexport interface ProductPrice {\n /** Decimal string, exactly as published: never a float. */\n amount: string;\n /** ISO 4217, e.g. `USD`. */\n currency: string;\n /** Subscriptions only (NIP-99). */\n frequency?: PriceFrequency;\n}\n\nexport interface Product {\n storePubkey: string;\n d: string;\n title: string;\n summary?: string;\n description: string;\n price: ProductPrice;\n images: string[];\n topics: string[];\n /** Gamma Markets visibility; absent means on sale. */\n visibility: string;\n delivery?: DeliveryMethod;\n /** Opted into the elisym aggregator (`[\"network\", \"elisym\"]`). */\n listedOnElisym: boolean;\n /** HTTP 402 entry points for agents. Never trusted on their own: a challenge must pay a 10133 address. */\n endpoints: { type: EndpointType; url: string }[];\n /** CAIP-19 ids of the assets the store accepts. Addresses come from the owner's 10133 only. */\n accept: string[];\n createdAt: number;\n}\n\nconst ProductInputSchema = z.object({\n d: z.string().regex(D_TAG_RE),\n title: z.string().min(1).max(LIMITS.MAX_TAG_VALUE_LENGTH),\n summary: z.string().max(LIMITS.MAX_TAG_VALUE_LENGTH).optional(),\n description: z.string().max(LIMITS.MAX_CONTENT_LENGTH),\n price: z.object({\n amount: z.string().regex(PRICE_AMOUNT_RE),\n currency: z.string().regex(CURRENCY_RE),\n frequency: z.enum(FREQUENCIES).optional(),\n }),\n images: z\n .array(z.string().url().startsWith('https://').max(LIMITS.MAX_TAG_VALUE_LENGTH))\n .default([]),\n topics: z.array(z.string().min(1).max(64)).default([]),\n visibility: z.string().min(1).max(32).default('on-sale'),\n delivery: z.enum(DELIVERY_METHODS).optional(),\n listedOnElisym: z.boolean().default(false),\n endpoints: z\n .array(z.object({ type: z.enum(ENDPOINT_TYPES), url: z.string().url().startsWith('https://') }))\n .default([]),\n accept: z.array(z.string()).min(1),\n createdAt: z.number().int().positive().optional(),\n});\n\nexport type ProductInput = z.input<typeof ProductInputSchema>;\n\n/** Build a kind 30402 listing. The caller signs it with the STORE key. */\nexport function buildProductEvent(input: ProductInput): EventTemplate {\n const product = ProductInputSchema.parse(input);\n for (const caip19 of product.accept) {\n if (!parseCaip19(caip19)) {\n throw new Error(`Not a payable CAIP-19 asset: ${caip19}`);\n }\n }\n const tags: string[][] = [\n ['d', product.d],\n ['title', product.title],\n ];\n if (product.summary !== undefined) {\n tags.push(['summary', product.summary]);\n }\n tags.push(\n product.price.frequency === undefined\n ? ['price', product.price.amount, product.price.currency]\n : ['price', product.price.amount, product.price.currency, product.price.frequency],\n );\n for (const image of product.images) {\n tags.push(['image', image]);\n }\n for (const topic of product.topics) {\n tags.push(['t', topic]);\n }\n tags.push(['visibility', product.visibility]);\n if (product.delivery !== undefined) {\n tags.push(['delivery', product.delivery]);\n }\n if (product.listedOnElisym) {\n tags.push(['network', ELISYM_NETWORK_TAG]);\n }\n for (const endpoint of product.endpoints) {\n tags.push(['endpoint', endpoint.type, endpoint.url]);\n }\n for (const caip19 of product.accept) {\n tags.push(['accept', caip19]);\n }\n return {\n kind: KIND_PRODUCT,\n created_at: product.createdAt ?? nowSecs(),\n tags,\n content: product.description,\n };\n}\n\nfunction parsePrice(tags: Tags): ProductPrice | undefined {\n const tag = tagsNamed(tags, 'price')[0];\n const amount = tag?.[1];\n const currency = tag?.[2];\n const frequency = tag?.[3];\n if (!amount || !PRICE_AMOUNT_RE.test(amount) || !currency || !CURRENCY_RE.test(currency)) {\n return undefined;\n }\n if (frequency === undefined || frequency === '') {\n return { amount, currency };\n }\n const known = FREQUENCIES.find((candidate) => candidate === frequency);\n return known ? { amount, currency, frequency: known } : undefined;\n}\n\n/**\n * Read a kind 30402 listing, or `undefined` when it lacks what a sale needs (a\n * `d`, a title, a price). Unknown extras are ignored, so a plain NIP-99 listing\n * from another client still reads - it just accepts nothing elisym can pay.\n * The caller has checked the signature.\n */\nexport function parseProduct(\n event: Pick<NostrEvent, 'kind' | 'pubkey' | 'tags' | 'content' | 'created_at'>,\n): Product | undefined {\n if (event.kind !== KIND_PRODUCT || event.content.length > LIMITS.MAX_CONTENT_LENGTH) {\n return undefined;\n }\n const tags = event.tags;\n const d = tagValue(tags, 'd');\n const title = tagValue(tags, 'title');\n const price = parsePrice(tags);\n if (d === undefined || !D_TAG_RE.test(d) || !title || !price) {\n return undefined;\n }\n const deliveryValue = tagValue(tags, 'delivery');\n const delivery = DELIVERY_METHODS.find((method) => method === deliveryValue);\n const endpoints: Product['endpoints'] = [];\n for (const tag of tagsNamed(tags, 'endpoint')) {\n const type = ENDPOINT_TYPES.find((candidate) => candidate === tag[1]);\n const url = tag[2];\n if (type && url?.startsWith('https://')) {\n endpoints.push({ type, url });\n }\n }\n const summary = tagValue(tags, 'summary');\n const product: Product = {\n storePubkey: event.pubkey,\n d,\n title,\n description: event.content,\n price,\n // Only `https:` images, as the builder writes: never a `javascript:` or `data:` URL to render.\n images: tagValues(tags, 'image').filter((image) => image.startsWith('https://')),\n topics: tagValues(tags, 't'),\n visibility: tagValue(tags, 'visibility') ?? 'on-sale',\n listedOnElisym: tagValues(tags, 'network').includes(ELISYM_NETWORK_TAG),\n endpoints,\n accept: tagValues(tags, 'accept'),\n createdAt: event.created_at,\n };\n if (summary !== undefined) {\n product.summary = summary;\n }\n if (delivery !== undefined) {\n product.delivery = delivery;\n }\n return product;\n}\n\nexport function isPurchasable(product: Pick<Product, 'visibility'>): boolean {\n return PURCHASABLE_VISIBILITIES.some((visibility) => visibility === product.visibility);\n}\n\n/** `30402:<store>:<d>`, the address an order's `item` tag names. */\nexport function productAddress(product: Pick<Product, 'storePubkey' | 'd'>): string {\n return `${KIND_PRODUCT}:${product.storePubkey}:${product.d}`;\n}\n\nexport function encodeProductNaddr(\n product: Pick<Product, 'storePubkey' | 'd'>,\n relays: string[] = [],\n): string {\n return nip19.naddrEncode({\n kind: KIND_PRODUCT,\n pubkey: product.storePubkey,\n identifier: product.d,\n relays,\n });\n}\n\nexport interface ProductPointer {\n storePubkey: string;\n d: string;\n relays: string[];\n}\n\n/** Decode a product `naddr`, or `undefined` when it is not one. */\nexport function decodeProductNaddr(naddr: string): ProductPointer | undefined {\n try {\n const decoded = nip19.decode(naddr);\n if (\n decoded.type !== 'naddr' ||\n decoded.data.kind !== KIND_PRODUCT ||\n !HEX_PUBKEY_RE.test(decoded.data.pubkey) ||\n !D_TAG_RE.test(decoded.data.identifier)\n ) {\n return undefined;\n }\n return {\n storePubkey: decoded.data.pubkey,\n d: decoded.data.identifier,\n relays: decoded.data.relays ?? [],\n };\n } catch {\n return undefined;\n }\n}\n\n/**\n * The price in `asset` subunits. Only a one-off `USD` price paid in a USD-pegged\n * coin at 1:1 has one; any other pairing needs a quote (quoted mode), so it is\n * refused here rather than converted at a guessed rate.\n */\nexport function priceInSubunits(price: ProductPrice, asset: Asset): bigint {\n if (price.frequency !== undefined) {\n throw new Error('A subscription price has no one-off amount');\n }\n if (price.currency !== 'USD' || !USD_STABLE_TOKENS.includes(asset.token)) {\n throw new Error(`A ${price.currency} price cannot be paid in ${asset.symbol} without a quote`);\n }\n // Trailing zeros past the asset's decimals (`49.0000000` in a 6-decimal coin) are the same price.\n return parseAssetAmount(asset, new Decimal(price.amount).toFixed());\n}\n","import type { EventTemplate } from 'nostr-tools';\nimport {\n DELIVERY_METHODS,\n type DeliveryMethod,\n KIND_ORDER_MESSAGE,\n KIND_PAYMENT_RECEIPT,\n KIND_PRODUCT,\n LIMITS,\n ORDER_STATUSES,\n type OrderStatus,\n} from '../constants';\nimport { HEX_PUBKEY_RE, type Tags, nowSecs, tagValue, tagsNamed } from '../tags';\n\nconst ORDER_ID_RE = new RegExp(`^[A-Za-z0-9-]{8,${LIMITS.MAX_ORDER_ID_LENGTH}}$`);\nconst ITEM_ADDRESS_RE = new RegExp(`^${KIND_PRODUCT}:[0-9a-f]{64}:[A-Za-z0-9._:-]{1,128}$`);\nconst QUANTITY_RE = /^[1-9]\\d{0,3}$/;\nconst AMOUNT_RE = /^(0|[1-9]\\d{0,11})(\\.\\d{1,18})?$/;\nconst SUBUNITS_RE = /^(0|[1-9]\\d{0,38})$/;\nconst CURRENCY_RE = /^[A-Z]{3}$/;\nconst MEDIUM_RE = /^[a-z0-9-]{1,32}$/;\nconst TX_RE = /^[A-Za-z0-9]{1,128}$/;\nconst EMAIL_RE = /^[^\\s@]{1,64}@[^\\s@]{1,255}$/;\n\nconst ORDER_MESSAGE_TYPES: readonly string[] = ['order', 'payment_request', 'status', 'receipt'];\n\n/** Gamma Markets `type` values for kind 16. */\nconst TYPE_ORDER = '1';\nconst TYPE_PAYMENT_REQUEST = '2';\nconst TYPE_STATUS = '3';\n\nexport interface OrderItem {\n /** `30402:<store>:<d>` */\n product: string;\n quantity: number;\n}\n\nexport interface Money {\n /** Decimal string, never a float. */\n amount: string;\n currency: string;\n}\n\n/** Buyer -> store: kind 16, type 1. */\nexport interface OrderRequest {\n type: 'order';\n storePubkey: string;\n orderId: string;\n items: OrderItem[];\n total: Money;\n email?: string;\n}\n\n/** Store -> buyer: kind 16, type 2 (quoted mode). `payload` is opaque here: the payer parses it with pay-core. */\nexport interface PaymentRequestMessage {\n type: 'payment_request';\n buyerPubkey: string;\n orderId: string;\n total: Money;\n options: { medium: string; payload: string }[];\n}\n\n/** Store -> buyer: kind 16, type 3. Signed by the store, so it is the proof of purchase. */\nexport interface OrderStatusMessage {\n type: 'status';\n buyerPubkey: string;\n orderId: string;\n status: OrderStatus;\n /** Store-supplied and unchecked: show it as text, or open it only as an `https:` link. */\n delivery?: { method: DeliveryMethod; value: string };\n /** The payment the store credited: amounts in subunits of the paid asset. */\n receipt?: { medium: string; tx: string; amount: string; fee: string };\n refund?: { tx: string; amount: string };\n}\n\n/**\n * Buyer -> store: kind 17. A HINT that says where to look, never proof: the\n * store verifies the transaction on chain before it credits anything.\n */\nexport interface PaymentReceipt {\n type: 'receipt';\n storePubkey: string;\n orderId: string;\n payment: { medium: string; reference: string; tx: string };\n}\n\nexport type OrderMessage =\n | OrderRequest\n | PaymentRequestMessage\n | OrderStatusMessage\n | PaymentReceipt;\n\nfunction assertPubkey(value: string, name: string): void {\n if (!HEX_PUBKEY_RE.test(value)) {\n throw new Error(`${name} must be 64 lowercase hex characters`);\n }\n}\n\nfunction assertMatches(value: string, pattern: RegExp, name: string): void {\n if (!pattern.test(value)) {\n throw new Error(`Invalid ${name}: ${value}`);\n }\n}\n\nfunction assertMoney(money: Money): void {\n assertMatches(money.amount, AMOUNT_RE, 'amount');\n assertMatches(money.currency, CURRENCY_RE, 'currency');\n}\n\n/**\n * The unsigned rumor for an order message. It is never published as is: it goes\n * through `wrapOrderMessage`, which seals it with the sender's key.\n */\nexport function buildOrderMessage(\n message: OrderMessage,\n createdAt: number = nowSecs(),\n): EventTemplate {\n // A plain-JS caller gets a clear error here, not `undefined` from the switch.\n if (!ORDER_MESSAGE_TYPES.some((known) => known === message.type)) {\n throw new Error(`Unknown order message type: ${String(message.type)}`);\n }\n assertMatches(message.orderId, ORDER_ID_RE, 'order id');\n switch (message.type) {\n case 'order': {\n assertPubkey(message.storePubkey, 'storePubkey');\n assertMoney(message.total);\n if (message.items.length === 0 || message.items.length > LIMITS.MAX_ITEMS_PER_ORDER) {\n throw new Error(`An order holds 1 to ${LIMITS.MAX_ITEMS_PER_ORDER} items`);\n }\n const tags: string[][] = [\n ['p', message.storePubkey],\n ['subject', 'order'],\n ['type', TYPE_ORDER],\n ['order', message.orderId],\n ];\n for (const item of message.items) {\n assertMatches(item.product, ITEM_ADDRESS_RE, 'item');\n assertMatches(String(item.quantity), QUANTITY_RE, 'quantity');\n tags.push(['item', item.product, String(item.quantity)]);\n }\n tags.push(['amount', message.total.amount, message.total.currency]);\n if (message.email !== undefined) {\n assertMatches(message.email, EMAIL_RE, 'email');\n tags.push(['email', message.email]);\n }\n return { kind: KIND_ORDER_MESSAGE, created_at: createdAt, tags, content: '' };\n }\n case 'payment_request': {\n assertPubkey(message.buyerPubkey, 'buyerPubkey');\n assertMoney(message.total);\n if (message.options.length === 0) {\n throw new Error('A payment request offers at least one way to pay');\n }\n const tags: string[][] = [\n ['p', message.buyerPubkey],\n ['type', TYPE_PAYMENT_REQUEST],\n ['order', message.orderId],\n ['amount', message.total.amount, message.total.currency],\n ];\n for (const option of message.options) {\n assertMatches(option.medium, MEDIUM_RE, 'payment medium');\n if (\n option.payload.length === 0 ||\n option.payload.length > LIMITS.MAX_TAG_VALUE_LENGTH * 4\n ) {\n throw new Error('Payment payload is empty or too long');\n }\n tags.push(['payment', option.medium, option.payload]);\n }\n return { kind: KIND_ORDER_MESSAGE, created_at: createdAt, tags, content: '' };\n }\n case 'status': {\n assertPubkey(message.buyerPubkey, 'buyerPubkey');\n if (!ORDER_STATUSES.some((status) => status === message.status)) {\n throw new Error(`Invalid order status: ${message.status}`);\n }\n const tags: string[][] = [\n ['p', message.buyerPubkey],\n ['type', TYPE_STATUS],\n ['order', message.orderId],\n ['status', message.status],\n ];\n if (message.delivery !== undefined) {\n const { method, value } = message.delivery;\n if (!DELIVERY_METHODS.some((known) => known === method)) {\n throw new Error(`Invalid delivery method: ${method}`);\n }\n if (value.length === 0 || value.length > LIMITS.MAX_TAG_VALUE_LENGTH) {\n throw new Error('Delivery value is empty or too long');\n }\n tags.push(['delivery', message.delivery.method, message.delivery.value]);\n }\n if (message.receipt !== undefined) {\n assertMatches(message.receipt.medium, MEDIUM_RE, 'receipt medium');\n assertMatches(message.receipt.tx, TX_RE, 'receipt tx');\n assertMatches(message.receipt.amount, SUBUNITS_RE, 'receipt amount');\n assertMatches(message.receipt.fee, SUBUNITS_RE, 'receipt fee');\n tags.push([\n 'receipt',\n message.receipt.medium,\n message.receipt.tx,\n message.receipt.amount,\n message.receipt.fee,\n ]);\n }\n if (message.refund !== undefined) {\n assertMatches(message.refund.tx, TX_RE, 'refund tx');\n assertMatches(message.refund.amount, SUBUNITS_RE, 'refund amount');\n tags.push(['refund', message.refund.tx, message.refund.amount]);\n }\n return { kind: KIND_ORDER_MESSAGE, created_at: createdAt, tags, content: '' };\n }\n case 'receipt': {\n assertPubkey(message.storePubkey, 'storePubkey');\n assertMatches(message.payment.medium, MEDIUM_RE, 'payment medium');\n assertMatches(message.payment.reference, TX_RE, 'payment reference');\n assertMatches(message.payment.tx, TX_RE, 'payment tx');\n return {\n kind: KIND_PAYMENT_RECEIPT,\n created_at: createdAt,\n tags: [\n ['p', message.storePubkey],\n ['order', message.orderId],\n ['payment', message.payment.medium, message.payment.reference, message.payment.tx],\n ],\n content: '',\n };\n }\n }\n}\n\nfunction readMoney(tags: Tags): Money | undefined {\n const tag = tagsNamed(tags, 'amount')[0];\n const amount = tag?.[1];\n const currency = tag?.[2];\n if (!amount || !AMOUNT_RE.test(amount) || !currency || !CURRENCY_RE.test(currency)) {\n return undefined;\n }\n return { amount, currency };\n}\n\nfunction readPubkey(tags: Tags): string | undefined {\n const value = tagValue(tags, 'p');\n return value !== undefined && HEX_PUBKEY_RE.test(value) ? value : undefined;\n}\n\nfunction readOrderRequest(tags: Tags, orderId: string): OrderRequest | undefined {\n const storePubkey = readPubkey(tags);\n const total = readMoney(tags);\n const itemTags = tagsNamed(tags, 'item');\n if (\n !storePubkey ||\n !total ||\n itemTags.length === 0 ||\n itemTags.length > LIMITS.MAX_ITEMS_PER_ORDER\n ) {\n return undefined;\n }\n const items: OrderItem[] = [];\n for (const tag of itemTags) {\n const product = tag[1];\n const quantity = tag[2] ?? '1';\n if (!product || !ITEM_ADDRESS_RE.test(product) || !QUANTITY_RE.test(quantity)) {\n return undefined;\n }\n items.push({ product, quantity: Number(quantity) });\n }\n const order: OrderRequest = { type: 'order', storePubkey, orderId, items, total };\n const email = tagValue(tags, 'email');\n if (email !== undefined && EMAIL_RE.test(email)) {\n order.email = email;\n }\n return order;\n}\n\nfunction readPaymentRequest(tags: Tags, orderId: string): PaymentRequestMessage | undefined {\n const buyerPubkey = readPubkey(tags);\n const total = readMoney(tags);\n if (!buyerPubkey || !total) {\n return undefined;\n }\n const options: PaymentRequestMessage['options'] = [];\n for (const tag of tagsNamed(tags, 'payment')) {\n const medium = tag[1];\n const payload = tag[2];\n if (medium && MEDIUM_RE.test(medium) && payload) {\n options.push({ medium, payload });\n }\n }\n if (options.length === 0) {\n return undefined;\n }\n return { type: 'payment_request', buyerPubkey, orderId, total, options };\n}\n\nfunction readStatus(tags: Tags, orderId: string): OrderStatusMessage | undefined {\n const buyerPubkey = readPubkey(tags);\n const statusValue = tagValue(tags, 'status');\n const status = ORDER_STATUSES.find((candidate) => candidate === statusValue);\n if (!buyerPubkey || !status) {\n return undefined;\n }\n const message: OrderStatusMessage = { type: 'status', buyerPubkey, orderId, status };\n const deliveryTag = tagsNamed(tags, 'delivery')[0];\n const method = DELIVERY_METHODS.find((candidate) => candidate === deliveryTag?.[1]);\n const deliveryValue = deliveryTag?.[2];\n if (method && deliveryValue && deliveryValue.length <= LIMITS.MAX_TAG_VALUE_LENGTH) {\n message.delivery = { method, value: deliveryValue };\n }\n const receiptTag = tagsNamed(tags, 'receipt')[0];\n const [, medium, tx, amount, fee] = receiptTag ?? [];\n if (\n medium &&\n MEDIUM_RE.test(medium) &&\n tx &&\n TX_RE.test(tx) &&\n amount &&\n SUBUNITS_RE.test(amount) &&\n fee &&\n SUBUNITS_RE.test(fee)\n ) {\n message.receipt = { medium, tx, amount, fee };\n }\n const refundTag = tagsNamed(tags, 'refund')[0];\n const [, refundTx, refundAmount] = refundTag ?? [];\n if (refundTx && TX_RE.test(refundTx) && refundAmount && SUBUNITS_RE.test(refundAmount)) {\n message.refund = { tx: refundTx, amount: refundAmount };\n }\n return message;\n}\n\nfunction readReceipt(tags: Tags, orderId: string): PaymentReceipt | undefined {\n const storePubkey = readPubkey(tags);\n const [, medium, reference, tx] = tagsNamed(tags, 'payment')[0] ?? [];\n if (\n !storePubkey ||\n !medium ||\n !MEDIUM_RE.test(medium) ||\n !reference ||\n !TX_RE.test(reference) ||\n !tx ||\n !TX_RE.test(tx)\n ) {\n return undefined;\n }\n return { type: 'receipt', storePubkey, orderId, payment: { medium, reference, tx } };\n}\n\n/**\n * Read an unwrapped rumor as an order message, or `undefined` when it is not a\n * well-formed one. Who SENT it is not checked here: `unwrapOrderMessage` gives\n * the authenticated sender, and the caller matches it against the role (a status\n * must come from the store, an order from the buyer who pays).\n */\nexport function parseOrderMessage(rumor: { kind: number; tags: Tags }): OrderMessage | undefined {\n const orderId = tagValue(rumor.tags, 'order');\n if (orderId === undefined || !ORDER_ID_RE.test(orderId)) {\n return undefined;\n }\n if (rumor.kind === KIND_PAYMENT_RECEIPT) {\n return readReceipt(rumor.tags, orderId);\n }\n if (rumor.kind !== KIND_ORDER_MESSAGE) {\n return undefined;\n }\n switch (tagValue(rumor.tags, 'type')) {\n case TYPE_ORDER:\n return readOrderRequest(rumor.tags, orderId);\n case TYPE_PAYMENT_REQUEST:\n return readPaymentRequest(rumor.tags, orderId);\n case TYPE_STATUS:\n return readStatus(rumor.tags, orderId);\n default:\n return undefined;\n }\n}\n","import type { NostrEvent } from 'nostr-tools';\nimport { verifyEvent } from 'nostr-tools/pure';\n\n/**\n * Whether an event's id is its hash and its signature is genuine - checked every\n * time. `verifyEvent` caches its verdict on the object under a symbol, and an\n * object spread copies symbols too: `{ ...genuine, content: 'tampered' }` would\n * pass on the cached `true`. A fresh object with only the NIP-01 fields cannot\n * carry that cache.\n */\nexport function isGenuineEvent(event: NostrEvent): boolean {\n if (!isEventShaped(event)) {\n return false;\n }\n return verifyEvent({\n id: event.id,\n pubkey: event.pubkey,\n created_at: event.created_at,\n kind: event.kind,\n tags: event.tags,\n content: event.content,\n sig: event.sig,\n });\n}\n\n/**\n * Whether a value from a relay or a resolver has the NIP-01 field types. Typed\n * as `NostrEvent` is not the same as being one: a malformed entry must be\n * skipped, not crash whoever reads its tags.\n */\nexport function isEventShaped(event: unknown): event is NostrEvent {\n if (typeof event !== 'object' || event === null) {\n return false;\n }\n const record: Record<string, unknown> = { ...event };\n const { id, pubkey, created_at: createdAt, kind, tags, content, sig } = record;\n return (\n typeof id === 'string' &&\n typeof pubkey === 'string' &&\n typeof createdAt === 'number' &&\n Number.isInteger(createdAt) &&\n typeof kind === 'number' &&\n Number.isInteger(kind) &&\n typeof content === 'string' &&\n typeof sig === 'string' &&\n Array.isArray(tags) &&\n tags.every((tag) => Array.isArray(tag) && tag.every((item) => typeof item === 'string'))\n );\n}\n","import type { EventTemplate, NostrEvent } from 'nostr-tools';\nimport * as nip44 from 'nostr-tools/nip44';\nimport * as nip59 from 'nostr-tools/nip59';\nimport { getEventHash, getPublicKey } from 'nostr-tools/pure';\nimport {\n KIND_GIFT_WRAP,\n KIND_ORDER_MESSAGE,\n KIND_PAYMENT_RECEIPT,\n KIND_SEAL,\n LIMITS,\n MAX_FUTURE_SKEW_SECS,\n} from '../constants';\nimport { HEX_PUBKEY_RE, nowSecs, tagValue } from '../tags';\nimport { isGenuineEvent } from '../verify';\nimport { type OrderMessage, parseOrderMessage } from './messages';\n\nexport interface WrappedOrderMessage {\n /** Publish to the recipient's inbox relays (kind 10050). */\n recipientWrap: NostrEvent;\n /** The sender's own copy, for its history on another device. */\n selfWrap: NostrEvent;\n /** The rumor id: the same in both wraps, the key to dedupe on. */\n rumorId: string;\n}\n\n/**\n * Seal and gift-wrap an order message (NIP-59) for `recipientPubkey`, plus a copy\n * for the sender. Relays see neither the content nor who talks to whom.\n */\nexport function wrapOrderMessage(\n rumor: EventTemplate,\n senderSecretKey: Uint8Array,\n recipientPubkey: string,\n): WrappedOrderMessage {\n if (!HEX_PUBKEY_RE.test(recipientPubkey)) {\n throw new Error('recipientPubkey must be 64 lowercase hex characters');\n }\n if (rumor.kind !== KIND_ORDER_MESSAGE && rumor.kind !== KIND_PAYMENT_RECEIPT) {\n throw new Error(`Not an order message kind: ${rumor.kind}`);\n }\n // The rumor carries its own created_at: nip59 rebuilds it per wrap, and a\n // clock read per build could split the rumor id across the two wraps.\n const wraps = nip59.wrapManyEvents(rumor, senderSecretKey, [recipientPubkey]);\n const selfWrap = wraps[0];\n const recipientWrap = wraps[1];\n if (!selfWrap || !recipientWrap) {\n throw new Error('Unexpected wrap count from nip59.wrapManyEvents');\n }\n const rumorId = getEventHash({ ...rumor, pubkey: getPublicKey(senderSecretKey) });\n return { recipientWrap, selfWrap, rumorId };\n}\n\nexport interface UnwrappedOrderMessage {\n rumorId: string;\n /** Authenticated by the seal signature. */\n senderPubkey: string;\n /** The `p` tag of the rumor: who the message is addressed to. */\n recipientPubkey: string;\n createdAt: number;\n message: OrderMessage;\n}\n\ninterface ParsedEvent {\n id: string;\n pubkey: string;\n created_at: number;\n kind: number;\n tags: string[][];\n content: string;\n sig?: string;\n}\n\nfunction isStringArrayArray(value: unknown): value is string[][] {\n return (\n Array.isArray(value) &&\n value.every((entry) => Array.isArray(entry) && entry.every((item) => typeof item === 'string'))\n );\n}\n\nfunction parseEventJson(json: string): ParsedEvent | undefined {\n let shape: unknown;\n try {\n shape = JSON.parse(json);\n } catch {\n return undefined;\n }\n if (typeof shape !== 'object' || shape === null) {\n return undefined;\n }\n const record: Record<string, unknown> = { ...shape };\n const { id, pubkey, created_at: createdAt, kind, tags, content, sig } = record;\n if (\n typeof id !== 'string' ||\n typeof pubkey !== 'string' ||\n typeof createdAt !== 'number' ||\n !Number.isInteger(createdAt) ||\n createdAt < 0 ||\n typeof kind !== 'number' ||\n typeof content !== 'string' ||\n content.length > LIMITS.MAX_CONTENT_LENGTH ||\n !isStringArrayArray(tags)\n ) {\n return undefined;\n }\n const parsed: ParsedEvent = { id, pubkey, created_at: createdAt, kind, tags, content };\n if (typeof sig === 'string') {\n parsed.sig = sig;\n }\n return parsed;\n}\n\nfunction decrypt(payload: string, secretKey: Uint8Array, senderPubkey: string): string {\n return nip44.v2.decrypt(payload, nip44.v2.utils.getConversationKey(secretKey, senderPubkey));\n}\n\n/**\n * Open a gift wrap addressed to `recipientSecretKey` and read the order message\n * inside, or `undefined` for anything that is not a genuine one.\n *\n * This replaces `nip59.unwrapEvent`, which verifies nothing: it would take a seal\n * signed by anyone and report whatever `pubkey` the rumor claims. Here the wrap\n * and the seal signatures are checked, the rumor must claim the seal's signer,\n * and its id must be its hash.\n */\nexport function unwrapOrderMessage(\n wrap: NostrEvent,\n recipientSecretKey: Uint8Array,\n): UnwrappedOrderMessage | undefined {\n try {\n if (wrap.kind !== KIND_GIFT_WRAP || !isGenuineEvent(wrap)) {\n return undefined;\n }\n const seal = parseEventJson(decrypt(wrap.content, recipientSecretKey, wrap.pubkey));\n // NIP-59: a seal carries no tags.\n if (!seal || seal.kind !== KIND_SEAL || seal.sig === undefined || seal.tags.length > 0) {\n return undefined;\n }\n const signedSeal: NostrEvent = { ...seal, sig: seal.sig };\n if (!isGenuineEvent(signedSeal)) {\n return undefined;\n }\n const rumor = parseEventJson(decrypt(seal.content, recipientSecretKey, seal.pubkey));\n // A rumor is unsigned (NIP-59): a signed one could be replayed as a public event.\n if (\n !rumor ||\n rumor.sig !== undefined ||\n rumor.pubkey !== seal.pubkey ||\n rumor.id !== getEventHash(rumor)\n ) {\n return undefined;\n }\n if (rumor.created_at > nowSecs() + MAX_FUTURE_SKEW_SECS) {\n return undefined;\n }\n const recipientPubkey = tagValue(rumor.tags, 'p');\n const message = parseOrderMessage(rumor);\n if (recipientPubkey === undefined || !message) {\n return undefined;\n }\n return {\n rumorId: rumor.id,\n senderPubkey: rumor.pubkey,\n recipientPubkey,\n createdAt: rumor.created_at,\n message,\n };\n } catch {\n return undefined;\n }\n}\n","import type { Filter, NostrEvent } from 'nostr-tools';\nimport { canonicalPayoutAddress, parseCaip19 } from './caip';\nimport {\n KIND_DELETION,\n KIND_PAYTO,\n KIND_PRODUCT,\n KIND_STORE_AUTH,\n KIND_STORE_PROFILE,\n MAX_FUTURE_SKEW_SECS,\n PAYOUT_COOLDOWN_SECS,\n} from './constants';\nimport {\n type DomainKeys,\n type ResolveDomainOptions,\n resolveDomainKeys,\n splitNip05,\n} from './domain';\nimport { type PayoutTarget, parsePayto } from './events/payto';\nimport {\n type Product,\n decodeProductNaddr,\n isPurchasable,\n parseProduct,\n productAddress,\n} from './events/product';\nimport { readStoreAuth, storeAuthAddress } from './events/store-auth';\nimport { type StoreProfile, parseStoreProfile } from './events/store-profile';\nimport { expirationState, nowSecs, tagValue, tagValues } from './tags';\nimport { isEventShaped, isGenuineEvent } from './verify';\n\n/**\n * A: the merchant's domain names both the store and the owner.\n * B: a hosted name (e.g. `shop@elisym.shop`) - trust in the name registrar.\n * C: keys only - the owner is pinned on first use.\n */\nexport type TrustLevel = 'A' | 'B' | 'C';\n\nexport type OfferRefusal =\n | 'bad_pointer'\n | 'product_missing'\n | 'product_not_on_sale'\n | 'store_profile_missing'\n | 'owner_unknown'\n | 'owner_mismatch'\n | 'owner_pin_mismatch'\n | 'domain_mismatch'\n | 'store_auth_missing'\n | 'store_auth_revoked'\n | 'store_auth_expired'\n | 'origin_mismatch'\n | 'payto_missing'\n | 'no_payout_for_accepted_assets';\n\nexport type OfferWarning =\n /** The profile names a domain that did not vouch for both keys; trust fell back to level C. */\n | 'domain_unverified'\n /** The page embedding the widget is not on the merchant's domain. */\n | 'origin_mismatch'\n /** No domain to compare the page with (levels B and C). */\n | 'origin_unverifiable'\n /** The newest payout event is younger than the cool-down: the owner key may be in new hands. */\n | 'payout_recently_changed'\n /** A payout address is not among the `knownPayouts` of earlier purchases. */\n | 'payout_changed'\n /** A payout address carries no wallet proof. */\n | 'payout_unsigned'\n /**\n * No `pinnedOwnerPubkey` (a first purchase): nothing but this bundle names the\n * owner, and a stolen store key can name a new one - at level A through a\n * domain of its own. Pin the owner after paying and pass it next time.\n */\n | 'owner_unpinned';\n\nexport interface VerifiedOffer {\n level: TrustLevel;\n /** Levels A and B: the domain that vouches for the store. */\n domain?: string;\n storePubkey: string;\n ownerPubkey: string;\n profile: StoreProfile;\n product: Product;\n /** Where a payment for this offer may go: the owner's 10133 addresses for the assets the product accepts. */\n payouts: PayoutTarget[];\n paytoCreatedAt: number;\n warnings: OfferWarning[];\n}\n\nexport type OfferVerification =\n | { ok: true; offer: VerifiedOffer }\n | { ok: false; refusal: OfferRefusal; message: string };\n\n/**\n * The signed events one offer rests on, as relays (or a resolver) handed them\n * over. Nothing here is trusted: every event is checked for its signature, its\n * author and its kind before it counts, and extras are ignored.\n */\nexport interface OfferBundle {\n events: readonly NostrEvent[];\n /**\n * What the store's `nip05` domain vouches for: keys, `'unreachable'` when it\n * answered nothing, or absent when the profile names no domain or it was not\n * looked up. The answer is unsigned: take it from the client's own lookup,\n * never from a resolver.\n */\n domain?: DomainKeys | 'unreachable';\n}\n\nexport interface EvaluateOfferOptions {\n now?: number;\n /** The origin of the page embedding the checkout (from `postMessage`'s `event.origin`). */\n pageOrigin?: string;\n /** Refuse, rather than warn, when the page is not on the merchant's domain - or its origin is not given. */\n strictOrigin?: boolean;\n /** Domains that issue hosted names (level B), e.g. `['elisym.shop']`. */\n hostedDomains?: readonly string[];\n /** The owner pinned at the first purchase from this store (TOFU). A new owner then needs a re-pin. */\n pinnedOwnerPubkey?: string;\n cooldownSecs?: number;\n /**\n * When an index (resolver, relay) first saw the newest 10133. The cool-down\n * counts from the later of this and the event's own `created_at`, which the\n * signer picks and can back-date.\n */\n paytoFirstSeenAt?: number;\n /**\n * Payout addresses paid at earlier purchases from this store (TOFU). A payout\n * outside this set is flagged `payout_changed`, however old its event claims to be.\n * Leave it out on a first purchase: an empty list flags every address.\n */\n knownPayouts?: readonly { caip19: string; address: string }[];\n}\n\nfunction refuse(refusal: OfferRefusal, message: string): OfferVerification {\n return { ok: false, refusal, message };\n}\n\n/** The newest event of `kind` by `author` (and `d`, when given) that is genuinely signed. */\nfunction newestSigned(\n events: readonly NostrEvent[],\n kind: number,\n author: string,\n now: number,\n d?: string,\n): NostrEvent | undefined {\n let newest: NostrEvent | undefined;\n for (const event of events) {\n if (\n !isEventShaped(event) ||\n event.kind !== kind ||\n event.pubkey !== author ||\n event.created_at > now + MAX_FUTURE_SKEW_SECS ||\n (d !== undefined && tagValue(event.tags, 'd') !== d)\n ) {\n continue;\n }\n // Ties on created_at go to the lowest id (NIP-01), so every reader picks the same one.\n if (\n newest &&\n (event.created_at < newest.created_at ||\n (event.created_at === newest.created_at && event.id >= newest.id))\n ) {\n continue;\n }\n if (isGenuineEvent(event)) {\n newest = event;\n }\n }\n return newest;\n}\n\n/**\n * For evidence that can only refuse (revocations, deletions): no future-date\n * window, so a signer's fast clock cannot delay it.\n */\nconst NO_FUTURE_LIMIT = Number.POSITIVE_INFINITY;\n\n/** The newest genuine NIP-09 deletion by `author` that names the addressable `address`. */\nfunction newestDeletion(\n events: readonly NostrEvent[],\n address: string,\n author: string,\n now: number,\n): NostrEvent | undefined {\n return newestSigned(\n events.filter((event) => isEventShaped(event) && tagValues(event.tags, 'a').includes(address)),\n KIND_DELETION,\n author,\n now,\n );\n}\n\n/** NIP-40: past its `expiration`, or with one that cannot be read. */\nfunction isLapsed(event: NostrEvent, now: number): boolean {\n const state = expirationState(event.tags, now);\n return state === 'expired' || state === 'malformed';\n}\n\nfunction originMatchesDomain(pageOrigin: string, domain: string): boolean {\n let url: URL;\n try {\n url = new URL(pageOrigin);\n } catch {\n return false;\n }\n if (url.protocol !== 'https:') {\n return false;\n }\n const host = url.hostname.toLowerCase();\n return host === domain || host.endsWith(`.${domain}`);\n}\n\ninterface Anchor {\n level: TrustLevel;\n domain?: string;\n ownerPubkey: string;\n /** The domain named the owner itself, so a missing AUTH is not a gap. */\n ownerFromDomain: boolean;\n warnings: OfferWarning[];\n}\n\nfunction resolveAnchor(\n storePubkey: string,\n profile: StoreProfile,\n bundle: OfferBundle,\n options: EvaluateOfferOptions,\n): Anchor | OfferVerification {\n const warnings: OfferWarning[] = [];\n const nip05 = profile.nip05 === undefined ? undefined : splitNip05(profile.nip05);\n const hosted = nip05 !== undefined && (options.hostedDomains ?? []).includes(nip05.domain);\n const keys = typeof bundle.domain === 'object' ? bundle.domain : undefined;\n let hostedDomain: string | undefined;\n // The TXT record names the domain's own (`_`) store. Under another name a\n // different store there is no verdict on this one - the nostr.json that would\n // have named it just did not answer.\n const txtForAnotherName =\n nip05 !== undefined &&\n keys !== undefined &&\n keys.source === 'dns' &&\n nip05.local !== '_' &&\n keys.storePubkey !== storePubkey;\n\n // An answer that names no store at all is no verdict either (a custom resolver may return one).\n // The answer must be for this very name: one looked up for `alice@` says\n // nothing about a profile that now claims `_@` on the same domain.\n if (\n nip05 &&\n keys &&\n keys.domain === nip05.domain &&\n keys.name === nip05.local &&\n keys.storePubkey !== undefined &&\n !txtForAnotherName\n ) {\n // A domain that answers and names ANOTHER store is not a failed lookup: it\n // says this profile is not the store it claims to be.\n if (keys.storePubkey !== storePubkey) {\n return refuse('domain_mismatch', `${nip05.domain} does not name this store`);\n }\n // Only the domain's own entries speak for the domain: `_` in nostr.json, or\n // the `_elisym` TXT record. Under any other name (`alice@provider.com`) the\n // `owner` entry is whoever registered `owner@` on a shared host.\n const domainWide = nip05.local === '_' || keys.source === 'dns';\n // The store-signed profile must name the same owner: the domain answer is\n // unsigned, so on its own whoever relays it (a resolver) could pick the owner.\n if (!hosted && domainWide && keys.ownerPubkey && profile.ownerPubkey !== undefined) {\n if (profile.ownerPubkey !== keys.ownerPubkey) {\n return refuse('owner_mismatch', 'The store profile and its domain name different owners');\n }\n return {\n level: 'A',\n domain: nip05.domain,\n ownerPubkey: keys.ownerPubkey,\n ownerFromDomain: true,\n warnings,\n };\n }\n if (hosted) {\n hostedDomain = nip05.domain;\n } else {\n warnings.push('domain_unverified');\n }\n } else if (profile.nip05 !== undefined) {\n // Also a nip05 that is not a public name at all: it claimed a domain and has none.\n warnings.push('domain_unverified');\n }\n\n if (!profile.ownerPubkey) {\n return refuse('owner_unknown', 'The store profile names no owner');\n }\n if (hostedDomain !== undefined) {\n return {\n level: 'B',\n domain: hostedDomain,\n ownerPubkey: profile.ownerPubkey,\n ownerFromDomain: false,\n warnings,\n };\n }\n return { level: 'C', ownerPubkey: profile.ownerPubkey, ownerFromDomain: false, warnings };\n}\n\n/**\n * Verify an offer from its signed events (spec section 3, steps 2-7 and 9's\n * address set). Pure: no network, so the same code runs on relay results and\n * on a resolver bundle, and a test feeds it exactly what it needs.\n *\n * The protocol fee (step 8) is not read here: the payer reads it from chain with\n * `@elisym/pay-core` when it builds the payment.\n */\nexport function evaluateOffer(\n pointer: { storePubkey: string; d: string },\n bundle: OfferBundle,\n options: EvaluateOfferOptions = {},\n): OfferVerification {\n const now = options.now ?? nowSecs();\n const { storePubkey } = pointer;\n\n const productEvent = newestSigned(bundle.events, KIND_PRODUCT, storePubkey, now, pointer.d);\n const product =\n productEvent && !isLapsed(productEvent, now) ? parseProduct(productEvent) : undefined;\n if (!product) {\n return refuse('product_missing', 'No valid, unexpired listing signed by the store');\n }\n // NIP-09: the store deleted the listing, and a relay that kept it does not bring it back.\n const productDeletion = newestDeletion(\n bundle.events,\n productAddress(product),\n storePubkey,\n NO_FUTURE_LIMIT,\n );\n if (productDeletion !== undefined && productDeletion.created_at >= product.createdAt) {\n return refuse('product_missing', 'The store deleted this listing');\n }\n if (!isPurchasable(product)) {\n return refuse('product_not_on_sale', `The listing is ${product.visibility}`);\n }\n\n const profileEvent = newestSigned(bundle.events, KIND_STORE_PROFILE, storePubkey, now);\n const profile =\n profileEvent && !isLapsed(profileEvent, now) ? parseStoreProfile(profileEvent) : undefined;\n if (!profile) {\n return refuse('store_profile_missing', 'No valid, unexpired profile signed by the store');\n }\n\n const anchor = resolveAnchor(storePubkey, profile, bundle, options);\n if ('ok' in anchor) {\n return anchor;\n }\n const { ownerPubkey } = anchor;\n const warnings = [...anchor.warnings];\n // At every level: a stolen store key can point the profile at a new owner, and\n // at a domain of the thief's own that names that owner too.\n if (options.pinnedOwnerPubkey !== undefined && options.pinnedOwnerPubkey !== ownerPubkey) {\n return refuse(\n 'owner_pin_mismatch',\n 'The store now names a different owner than at the first purchase',\n );\n }\n // Level A included: a stolen store key can point the profile at a domain of\n // the thief's own, so a first purchase is on trust at every level.\n if (options.pinnedOwnerPubkey === undefined) {\n warnings.push('owner_unpinned');\n }\n\n // The owner's newest word on this store wins. Level A does not NEED an AUTH -\n // the domain already links the two - but a revocation still stands.\n const authEvent = newestSigned(bundle.events, KIND_STORE_AUTH, ownerPubkey, now, storePubkey);\n const auth = authEvent ? readStoreAuth(authEvent, storePubkey, now) : undefined;\n // NIP-09: a deletion that names the AUTH address removes every version up to its own date.\n const deletion = newestDeletion(\n bundle.events,\n storeAuthAddress(ownerPubkey, storePubkey),\n ownerPubkey,\n NO_FUTURE_LIMIT,\n );\n // A revocation dated past the skew window (a fast clock) still revokes: the\n // window stops an event from pinning itself as newest, and this can only refuse.\n const revocation = newestSigned(\n bundle.events.filter(\n (event) =>\n isEventShaped(event) && readStoreAuth(event, storePubkey, now).status === 'revoked',\n ),\n KIND_STORE_AUTH,\n ownerPubkey,\n NO_FUTURE_LIMIT,\n storePubkey,\n );\n const revokedAfter = (event: NostrEvent | undefined): boolean =>\n event !== undefined && (!authEvent || event.created_at >= authEvent.created_at);\n if (auth?.status === 'revoked' || revokedAfter(deletion) || revokedAfter(revocation)) {\n return refuse('store_auth_revoked', 'The owner revoked this store key');\n }\n if (auth?.status === 'expired') {\n return refuse('store_auth_expired', \"The owner's authorization of this store key expired\");\n }\n // The owner's newest word on this store cannot be read: fail closed at every\n // level, as it may be a revocation or an expiry written some other way.\n if (auth?.status === 'malformed') {\n return refuse(\n 'store_auth_missing',\n \"The owner's newest authorization of this store key is malformed\",\n );\n }\n if (!anchor.ownerFromDomain && auth?.status !== 'active') {\n return refuse('store_auth_missing', 'The owner has not authorized this store key');\n }\n\n if (options.strictOrigin && options.pageOrigin === undefined) {\n return refuse('origin_mismatch', 'Strict mode needs the origin of the embedding page');\n }\n if (options.pageOrigin !== undefined) {\n if (anchor.level !== 'A' || anchor.domain === undefined) {\n // Strict mode must not be escaped by dropping the domain from the profile.\n if (options.strictOrigin) {\n return refuse('origin_mismatch', 'The store has no verified domain to match this page');\n }\n warnings.push('origin_unverifiable');\n } else if (!originMatchesDomain(options.pageOrigin, anchor.domain)) {\n if (options.strictOrigin) {\n return refuse('origin_mismatch', `This page is not on ${anchor.domain}`);\n }\n warnings.push('origin_mismatch');\n }\n }\n\n const paytoEvent = newestSigned(bundle.events, KIND_PAYTO, ownerPubkey, now);\n // An expired 10133 still served by a relay that ignores NIP-40 names wallets\n // the owner has stopped vouching for: nothing replaces it, so nothing is paid.\n if (!paytoEvent || isLapsed(paytoEvent, now)) {\n return refuse('payto_missing', 'The owner has no current payout addresses');\n }\n const accepted = new Set(product.accept);\n const payouts = parsePayto(paytoEvent).targets.filter((target) => accepted.has(target.caip19.id));\n if (payouts.length === 0) {\n return refuse(\n 'no_payout_for_accepted_assets',\n 'The owner has no payout address for any asset this product accepts',\n );\n }\n // `created_at` is whatever the signer wrote, so a thief with the owner key can\n // back-date a new 10133 past the cool-down. A first-seen time from an index,\n // and the addresses paid before, are what the signer cannot choose.\n const paytoAge = now - Math.max(paytoEvent.created_at, options.paytoFirstSeenAt ?? 0);\n if (paytoAge < (options.cooldownSecs ?? PAYOUT_COOLDOWN_SECS)) {\n warnings.push('payout_recently_changed');\n }\n const knownPayouts = options.knownPayouts;\n if (\n knownPayouts !== undefined &&\n payouts.some(\n (target) =>\n !knownPayouts.some(\n (known) =>\n known.caip19 === target.caip19.id &&\n canonicalPayoutAddress(target.caip19.chain, known.address) === target.address,\n ),\n )\n ) {\n warnings.push('payout_changed');\n }\n if (payouts.some((target) => !target.walletSigned)) {\n warnings.push('payout_unsigned');\n }\n\n const offer: VerifiedOffer = {\n level: anchor.level,\n storePubkey,\n ownerPubkey,\n profile,\n product,\n payouts,\n paytoCreatedAt: paytoEvent.created_at,\n warnings,\n };\n if (anchor.domain !== undefined) {\n offer.domain = anchor.domain;\n }\n return { ok: true, offer };\n}\n\n/**\n * Step 9: whether a recipient named by ANY other source - a payment request, an\n * x402 `payTo`, an MPP challenge - is one of the owner's payout addresses for\n * that asset. Anything else must not be paid.\n */\nexport function isOfferPayout(offer: VerifiedOffer, caip19: string, recipient: string): boolean {\n const asset = parseCaip19(caip19);\n if (!asset) {\n return false;\n }\n const canonical = canonicalPayoutAddress(asset.chain, recipient);\n return (\n canonical !== undefined &&\n offer.payouts.some((target) => target.caip19.id === caip19 && target.address === canonical)\n );\n}\n\nexport interface VerifyOfferDeps extends ResolveDomainOptions {\n /**\n * Query relays (or a resolver). The spec asks for at least two relays so one\n * cannot hide the newest payout event; that is this function's job, and its\n * results are all checked again here.\n */\n fetchEvents: (filters: Filter[]) => Promise<NostrEvent[]>;\n /**\n * Replace the domain lookup. It must be the client's OWN nostr.json / DoH\n * lookup: the answer is unsigned, so a resolver's copy is not evidence.\n */\n resolveDomain?: (nip05: string) => Promise<DomainKeys | undefined>;\n}\n\n/** A lookup that throws answered nothing, like one that returned nothing. */\nasync function resolveOrUnreachable(\n resolve: (nip05: string) => Promise<DomainKeys | undefined>,\n nip05: string,\n): Promise<DomainKeys | undefined> {\n try {\n return await resolve(nip05);\n } catch {\n return undefined;\n }\n}\n\n/** Collect an offer's events from relays and verify it (spec section 3). */\nexport async function verifyOffer(\n naddr: string,\n deps: VerifyOfferDeps,\n options: EvaluateOfferOptions = {},\n): Promise<OfferVerification> {\n const pointer = decodeProductNaddr(naddr);\n if (!pointer) {\n return refuse('bad_pointer', 'Not a product naddr');\n }\n const { storePubkey, d } = pointer;\n const storeEvents = await deps.fetchEvents([\n { kinds: [KIND_PRODUCT], authors: [storePubkey], '#d': [d] },\n { kinds: [KIND_STORE_PROFILE], authors: [storePubkey] },\n { kinds: [KIND_DELETION], authors: [storePubkey], '#a': [productAddress({ storePubkey, d })] },\n ]);\n const now = options.now ?? nowSecs();\n const profileEvent = newestSigned(storeEvents, KIND_STORE_PROFILE, storePubkey, now);\n const profile = profileEvent ? parseStoreProfile(profileEvent) : undefined;\n\n let domain: OfferBundle['domain'];\n if (profile?.nip05 !== undefined) {\n // The name is store-controlled: a custom resolver never sees one that is\n // not a public host (loopback, a private IP), as the default lookup never fetches it.\n const resolve = deps.resolveDomain ?? ((nip05: string) => resolveDomainKeys(nip05, deps));\n domain =\n splitNip05(profile.nip05) === undefined\n ? 'unreachable'\n : ((await resolveOrUnreachable(resolve, profile.nip05)) ?? 'unreachable');\n }\n\n const owners = new Set<string>();\n if (profile?.ownerPubkey) {\n owners.add(profile.ownerPubkey);\n }\n if (typeof domain === 'object' && domain.ownerPubkey) {\n owners.add(domain.ownerPubkey);\n }\n const ownerEvents =\n owners.size === 0\n ? []\n : await deps.fetchEvents([\n { kinds: [KIND_PAYTO], authors: [...owners] },\n { kinds: [KIND_STORE_AUTH], authors: [...owners], '#d': [storePubkey] },\n {\n kinds: [KIND_DELETION],\n authors: [...owners],\n '#a': [...owners].map((owner) => storeAuthAddress(owner, storePubkey)),\n },\n ]);\n\n // The owner query brings the owner's word only: a store event that rides\n // along could swap in another profile than the one whose domain was looked up.\n const ownerKinds: readonly number[] = [KIND_PAYTO, KIND_STORE_AUTH, KIND_DELETION];\n const ownerOnly = ownerEvents.filter(\n (event) => isEventShaped(event) && owners.has(event.pubkey) && ownerKinds.includes(event.kind),\n );\n const bundle: OfferBundle = { events: [...storeEvents, ...ownerOnly] };\n if (domain !== undefined) {\n bundle.domain = domain;\n }\n // One clock for both passes: the profile picked here is the one judged there.\n return evaluateOffer({ storePubkey, d }, bundle, { ...options, now });\n}\n"]}
1
+ {"version":3,"sources":[],"names":[],"mappings":"","file":"index.js"}