@stellar-snaps/sdk 0.2.0 → 0.3.1
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/README.md +138 -1
- package/dist/index.d.mts +613 -64
- package/dist/index.d.ts +613 -64
- package/dist/index.js +722 -60
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +681 -61
- package/dist/index.mjs.map +1 -1
- package/package.json +13 -14
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/create-snap.ts","../src/create-payment-snap.ts","../src/constants.ts","../src/errors.ts","../src/create-transaction-snap.ts","../src/parse-snap-uri.ts","../src/validation.ts","../src/transaction.ts","../src/freighter.ts","../src/discovery.ts"],"names":["NETWORK_PASSPHRASES","StellarSdk","isConnected","isAllowed","getNetwork","setAllowed","getAddress","signTransaction","StellarSdk2"],"mappings":"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","file":"index.js","sourcesContent":["/**\n * Create Shareable Snap\n *\n * Creates a snap on a Stellar Snaps server and returns the shareable URL.\n * This is different from createPaymentSnap which only creates SEP-0007 URIs.\n */\n\nexport interface CreateSnapOptions {\n /** Creator's Stellar address (required) */\n creator: string;\n /** Display title for the snap (required) */\n title: string;\n /** Payment destination address (required) */\n destination: string;\n /** Optional description */\n description?: string;\n /** Payment amount (optional - if not set, payer enters amount) */\n amount?: string;\n /** Asset code (default: 'XLM') */\n assetCode?: string;\n /** Asset issuer (required for non-XLM assets) */\n assetIssuer?: string;\n /** Transaction memo */\n memo?: string;\n /** Memo type (default: 'MEMO_TEXT') */\n memoType?: 'MEMO_TEXT' | 'MEMO_ID' | 'MEMO_HASH' | 'MEMO_RETURN';\n /** Network (default: 'testnet') */\n network?: 'public' | 'testnet';\n /** Optional image URL for the snap */\n imageUrl?: string;\n /** Stellar Snaps server URL (default: 'https://stellarsnaps.com') */\n serverUrl?: string;\n}\n\nexport interface CreateSnapResult {\n /** The created snap ID */\n id: string;\n /** Full shareable URL */\n url: string;\n /** The snap data as stored */\n snap: {\n id: string;\n creator: string;\n title: string;\n description?: string;\n destination: string;\n amount?: string;\n assetCode: string;\n assetIssuer?: string;\n memo?: string;\n memoType: string;\n network: string;\n imageUrl?: string;\n createdAt: string;\n };\n}\n\n/**\n * Creates a shareable snap on a Stellar Snaps server.\n *\n * @example\n * ```typescript\n * const result = await createSnap({\n * creator: 'GCREATOR...',\n * title: 'Coffee Payment',\n * destination: 'GDEST...',\n * amount: '5',\n * serverUrl: 'https://your-stellar-snaps-instance.com'\n * });\n *\n * console.log(result.url);\n * // https://your-stellar-snaps-instance.com/s/nk1VNcxo\n * ```\n */\nexport async function createSnap(\n options: CreateSnapOptions\n): Promise<CreateSnapResult> {\n const {\n creator,\n title,\n destination,\n description,\n amount,\n assetCode = 'XLM',\n assetIssuer,\n memo,\n memoType = 'MEMO_TEXT',\n network = 'testnet',\n imageUrl,\n serverUrl = 'https://stellarsnaps.com',\n } = options;\n\n // Validate required fields\n if (!creator || creator.length !== 56 || !creator.startsWith('G')) {\n throw new Error('Invalid creator address');\n }\n\n if (!title || title.trim().length === 0) {\n throw new Error('Title is required');\n }\n\n if (!destination || destination.length !== 56 || !destination.startsWith('G')) {\n throw new Error('Invalid destination address');\n }\n\n if (assetCode !== 'XLM' && !assetIssuer) {\n throw new Error('Asset issuer is required for non-XLM assets');\n }\n\n // Build request body\n const body = {\n creator,\n title,\n destination,\n description,\n amount,\n assetCode,\n assetIssuer,\n memo,\n memoType,\n network,\n imageUrl,\n };\n\n // Make API request\n const response = await fetch(`${serverUrl}/api/snaps`, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n },\n body: JSON.stringify(body),\n });\n\n if (!response.ok) {\n const error = await response.json().catch(() => ({ error: 'Unknown error' }));\n throw new Error(error.error || `Failed to create snap: ${response.status}`);\n }\n\n const snap = await response.json();\n\n return {\n id: snap.id,\n url: `${serverUrl}/s/${snap.id}`,\n snap,\n };\n}\n\n/**\n * Fetches an existing snap by ID from a Stellar Snaps server.\n *\n * @example\n * ```typescript\n * const snap = await getSnap('nk1VNcxo', {\n * serverUrl: 'https://your-stellar-snaps-instance.com'\n * });\n * ```\n */\nexport async function getSnap(\n id: string,\n options: { serverUrl?: string } = {}\n): Promise<CreateSnapResult['snap'] | null> {\n const { serverUrl = 'https://stellarsnaps.com' } = options;\n\n const response = await fetch(`${serverUrl}/api/snaps/${id}`);\n\n if (response.status === 404) {\n return null;\n }\n\n if (!response.ok) {\n throw new Error(`Failed to fetch snap: ${response.status}`);\n }\n\n return response.json();\n}\n\n/**\n * Lists snaps created by a specific address.\n *\n * @example\n * ```typescript\n * const snaps = await listSnaps('GCREATOR...', {\n * serverUrl: 'https://your-stellar-snaps-instance.com'\n * });\n * ```\n */\nexport async function listSnaps(\n creator: string,\n options: { serverUrl?: string } = {}\n): Promise<CreateSnapResult['snap'][]> {\n const { serverUrl = 'https://stellarsnaps.com' } = options;\n\n const response = await fetch(`${serverUrl}/api/snaps?creator=${encodeURIComponent(creator)}`);\n\n if (!response.ok) {\n throw new Error(`Failed to list snaps: ${response.status}`);\n }\n\n return response.json();\n}\n\n/**\n * Deletes a snap by ID.\n *\n * @example\n * ```typescript\n * await deleteSnap('nk1VNcxo', {\n * serverUrl: 'https://your-stellar-snaps-instance.com'\n * });\n * ```\n */\nexport async function deleteSnap(\n id: string,\n options: { serverUrl?: string } = {}\n): Promise<void> {\n const { serverUrl = 'https://stellarsnaps.com' } = options;\n\n const response = await fetch(`${serverUrl}/api/snaps/${id}`, {\n method: 'DELETE',\n });\n\n if (!response.ok && response.status !== 404) {\n throw new Error(`Failed to delete snap: ${response.status}`);\n }\n}\n","export interface PaymentSnapOptions {\n destination: string;\n amount?: string;\n assetCode?: string;\n assetIssuer?: string;\n memo?: string;\n memoType?: 'MEMO_TEXT' | 'MEMO_ID' | 'MEMO_HASH' | 'MEMO_RETURN';\n message?: string;\n network?: 'public' | 'testnet';\n callback?: string;\n}\n\nexport interface PaymentSnapResult {\n uri: string;\n params: Record<string, string>;\n}\n\nconst NETWORK_PASSPHRASES = {\n public: 'Public Global Stellar Network ; September 2015',\n testnet: 'Test SDF Network ; September 2015',\n} as const;\n\nexport function createPaymentSnap(options: PaymentSnapOptions): PaymentSnapResult {\n const {\n destination,\n amount,\n assetCode,\n assetIssuer,\n memo,\n memoType = 'MEMO_TEXT',\n message,\n network,\n callback,\n } = options;\n\n if (!destination || destination.length !== 56 || !destination.startsWith('G')) {\n throw new Error('Invalid destination address');\n }\n\n const params: Record<string, string> = { destination };\n\n if (amount) {\n if (isNaN(Number(amount)) || Number(amount) <= 0) {\n throw new Error('Invalid amount');\n }\n params.amount = amount;\n }\n\n if (assetCode && assetCode !== 'XLM') {\n params.asset_code = assetCode;\n if (!assetIssuer) {\n throw new Error('asset_issuer required for non-XLM assets');\n }\n params.asset_issuer = assetIssuer;\n }\n\n if (memo) {\n params.memo = memo;\n params.memo_type = memoType;\n }\n\n if (message) {\n if (message.length > 300) {\n throw new Error('Message cannot exceed 300 characters');\n }\n params.msg = message;\n }\n\n if (network && network !== 'public') {\n params.network_passphrase = NETWORK_PASSPHRASES[network];\n }\n\n if (callback) {\n params.callback = `url:${callback}`;\n }\n\n const queryString = Object.entries(params)\n .map(([key, value]) => `${key}=${encodeURIComponent(value)}`)\n .join('&');\n\n return { uri: `web+stellar:pay?${queryString}`, params };\n}\n","/**\n * Stellar network passphrases used for transaction signing.\n * Each network has a unique passphrase that identifies it.\n */\nexport const NETWORK_PASSPHRASES = {\n public: 'Public Global Stellar Network ; September 2015',\n testnet: 'Test SDF Network ; September 2015',\n} as const;\n\n/**\n * Horizon API URLs for each Stellar network.\n * Horizon is the REST API for interacting with the Stellar network.\n */\nexport const HORIZON_URLS = {\n public: 'https://horizon.stellar.org',\n testnet: 'https://horizon-testnet.stellar.org',\n} as const;\n\n/**\n * Supported Stellar networks.\n * - `public`: The main Stellar network (real money)\n * - `testnet`: Test network for development (free test tokens)\n */\nexport type Network = 'public' | 'testnet';\n\n/**\n * Stellar memo types for attaching metadata to transactions.\n * - `MEMO_TEXT`: Plain text (max 28 bytes)\n * - `MEMO_ID`: 64-bit unsigned integer\n * - `MEMO_HASH`: 32-byte hash\n * - `MEMO_RETURN`: 32-byte hash (for returning payments)\n */\nexport type MemoType = 'MEMO_TEXT' | 'MEMO_ID' | 'MEMO_HASH' | 'MEMO_RETURN';\n","/**\n * Base error class for all Stellar Snaps SDK errors.\n * Includes an error code for programmatic error handling.\n */\nexport class StellarSnapError extends Error {\n constructor(\n message: string,\n public code: string\n ) {\n super(message);\n this.name = 'StellarSnapError';\n }\n}\n\n/**\n * Thrown when a Stellar address is invalid.\n * Valid addresses are 56 characters long and start with 'G'.\n */\nexport class InvalidAddressError extends StellarSnapError {\n constructor(address: string) {\n super(`Invalid Stellar address: ${address}`, 'INVALID_ADDRESS');\n this.name = 'InvalidAddressError';\n }\n}\n\n/**\n * Thrown when an amount is invalid.\n * Amounts must be positive numbers represented as strings.\n */\nexport class InvalidAmountError extends StellarSnapError {\n constructor(amount: string) {\n super(`Invalid amount: ${amount}. Must be a positive number.`, 'INVALID_AMOUNT');\n this.name = 'InvalidAmountError';\n }\n}\n\n/**\n * Thrown when an asset configuration is invalid.\n * Non-XLM assets require both a code and an issuer address.\n */\nexport class InvalidAssetError extends StellarSnapError {\n constructor(message: string) {\n super(message, 'INVALID_ASSET');\n this.name = 'InvalidAssetError';\n }\n}\n\n/**\n * Thrown when a SEP-0007 URI is invalid or malformed.\n */\nexport class InvalidUriError extends StellarSnapError {\n constructor(message: string) {\n super(message, 'INVALID_URI');\n this.name = 'InvalidUriError';\n }\n}\n","import { NETWORK_PASSPHRASES, type Network } from './constants';\nimport { InvalidUriError } from './errors';\n\n/**\n * Options for creating a transaction snap URI.\n * Used for advanced use cases where you need to sign arbitrary transactions,\n * not just simple payments.\n */\nexport interface TransactionSnapOptions {\n /** The transaction in XDR format (Stellar's binary encoding) */\n xdr: string;\n /** The network this transaction is for (default: 'public') */\n network?: Network;\n /** Human-readable message to show the user when signing */\n message?: string;\n /** URL to call after the transaction is signed */\n callback?: string;\n /** Public key of the required signer */\n pubkey?: string;\n}\n\n/**\n * Result of creating a transaction snap.\n */\nexport interface TransactionSnapResult {\n /** The complete SEP-0007 URI */\n uri: string;\n /** The parsed parameters */\n params: Record<string, string>;\n}\n\n/**\n * Creates a SEP-0007 transaction URI for signing arbitrary Stellar transactions.\n *\n * Unlike payment snaps which are for simple payments, transaction snaps can\n * encode any Stellar transaction (multi-operation, account creation, etc.).\n *\n * @param options - Transaction snap configuration\n * @returns The generated URI and parsed parameters\n * @throws {InvalidUriError} If the XDR is missing or invalid\n *\n * @example\n * ```typescript\n * const { uri } = createTransactionSnap({\n * xdr: 'AAAA...', // Your transaction XDR\n * network: 'testnet',\n * message: 'Please sign this transaction',\n * });\n * // => web+stellar:tx?xdr=AAAA...&network_passphrase=Test%20SDF%20Network...\n * ```\n */\nexport function createTransactionSnap(options: TransactionSnapOptions): TransactionSnapResult {\n const { xdr, network = 'public', message, callback, pubkey } = options;\n\n if (!xdr || typeof xdr !== 'string') {\n throw new InvalidUriError('XDR is required for transaction snaps');\n }\n\n const params: Record<string, string> = {\n xdr: xdr,\n };\n\n // Add network passphrase if not public (public is the default)\n if (network !== 'public') {\n params.network_passphrase = NETWORK_PASSPHRASES[network];\n }\n\n if (message) {\n if (message.length > 300) {\n throw new InvalidUriError('Message cannot exceed 300 characters');\n }\n params.msg = message;\n }\n\n if (callback) {\n params.callback = `url:${callback}`;\n }\n\n if (pubkey) {\n params.pubkey = pubkey;\n }\n\n const queryString = Object.entries(params)\n .map(([key, value]) => `${key}=${encodeURIComponent(value)}`)\n .join('&');\n\n return {\n uri: `web+stellar:tx?${queryString}`,\n params,\n };\n}\n","export interface ParsedSnap {\n type: 'pay' | 'tx';\n destination?: string;\n amount?: string;\n assetCode?: string;\n assetIssuer?: string;\n memo?: string;\n memoType?: string;\n message?: string;\n networkPassphrase?: string;\n callback?: string;\n xdr?: string;\n}\n\nexport function parseSnapUri(uri: string): ParsedSnap {\n if (!uri.startsWith('web+stellar:')) {\n throw new Error('Invalid SEP-0007 URI: must start with web+stellar:');\n }\n\n const withoutScheme = uri.replace('web+stellar:', '');\n const [operation, queryString] = withoutScheme.split('?');\n\n if (operation !== 'pay' && operation !== 'tx') {\n throw new Error(`Invalid operation: ${operation}. Must be 'pay' or 'tx'`);\n }\n\n const params = new URLSearchParams(queryString);\n const parsed: ParsedSnap = { type: operation };\n\n if (operation === 'pay') {\n const destination = params.get('destination');\n if (!destination) {\n throw new Error('Missing required parameter: destination');\n }\n parsed.destination = destination;\n\n if (params.has('amount')) parsed.amount = params.get('amount')!;\n if (params.has('asset_code')) parsed.assetCode = params.get('asset_code')!;\n if (params.has('asset_issuer')) parsed.assetIssuer = params.get('asset_issuer')!;\n if (params.has('memo')) parsed.memo = params.get('memo')!;\n if (params.has('memo_type')) parsed.memoType = params.get('memo_type')!;\n if (params.has('msg')) parsed.message = params.get('msg')!;\n if (params.has('network_passphrase')) parsed.networkPassphrase = params.get('network_passphrase')!;\n if (params.has('callback')) {\n const cb = params.get('callback')!;\n parsed.callback = cb.startsWith('url:') ? cb.slice(4) : cb;\n }\n } else {\n const xdr = params.get('xdr');\n if (!xdr) {\n throw new Error('Missing required parameter: xdr');\n }\n parsed.xdr = xdr;\n if (params.has('msg')) parsed.message = params.get('msg')!;\n if (params.has('network_passphrase')) parsed.networkPassphrase = params.get('network_passphrase')!;\n if (params.has('callback')) {\n const cb = params.get('callback')!;\n parsed.callback = cb.startsWith('url:') ? cb.slice(4) : cb;\n }\n }\n\n return parsed;\n}\n","/**\n * Validates a Stellar public address.\n * Valid addresses are 56 characters long and start with 'G'.\n *\n * @param address - The address to validate\n * @returns true if the address is valid\n *\n * @example\n * ```typescript\n * isValidStellarAddress('GDQP2KPQGKIHYJGXNUIYOMHARUARCA7DJT5FO2FFOOUJ3DTJE4QRK764');\n * // => true\n *\n * isValidStellarAddress('invalid');\n * // => false\n * ```\n */\nexport function isValidStellarAddress(address: string): boolean {\n if (!address || typeof address !== 'string') {\n return false;\n }\n return address.length === 56 && address.startsWith('G');\n}\n\n/**\n * Validates a Stellar asset code.\n * Asset codes are 1-12 alphanumeric characters.\n * \"XLM\" is the native asset and is always valid.\n *\n * @param code - The asset code to validate\n * @returns true if the asset code is valid\n *\n * @example\n * ```typescript\n * isValidAssetCode('USDC');\n * // => true\n *\n * isValidAssetCode('XLM');\n * // => true\n *\n * isValidAssetCode('ThisIsTooLongForAnAssetCode');\n * // => false\n * ```\n */\nexport function isValidAssetCode(code: string): boolean {\n if (!code || typeof code !== 'string') {\n return false;\n }\n // Asset codes are 1-12 alphanumeric characters\n return /^[a-zA-Z0-9]{1,12}$/.test(code);\n}\n\n/**\n * Validates a payment amount.\n * Amounts must be positive numbers represented as strings.\n * Stellar supports up to 7 decimal places.\n *\n * @param amount - The amount to validate\n * @returns true if the amount is valid\n *\n * @example\n * ```typescript\n * isValidAmount('10');\n * // => true\n *\n * isValidAmount('0.0000001');\n * // => true\n *\n * isValidAmount('-5');\n * // => false\n *\n * isValidAmount('0');\n * // => false\n * ```\n */\nexport function isValidAmount(amount: string): boolean {\n if (!amount || typeof amount !== 'string') {\n return false;\n }\n const num = Number(amount);\n return !isNaN(num) && num > 0 && isFinite(num);\n}\n","import * as StellarSdk from '@stellar/stellar-sdk';\nimport { NETWORK_PASSPHRASES, type Network, type MemoType } from './constants';\nimport { InvalidAddressError, InvalidAmountError, InvalidAssetError } from './errors';\nimport { isValidStellarAddress, isValidAmount } from './validation';\n\n/**\n * Options for building a payment transaction.\n */\nexport interface BuildPaymentOptions {\n /** The payer's Stellar public address */\n source: string;\n /** The account sequence number (prevents replay attacks) */\n sequence: string;\n /** The recipient's Stellar public address */\n destination: string;\n /** The amount to send (as a string for precision) */\n amount: string;\n /** The asset to send (defaults to XLM if not specified) */\n asset?: {\n /** Asset code, e.g., \"USDC\", \"XLM\" */\n code: string;\n /** Asset issuer address (required for non-XLM assets) */\n issuer?: string;\n };\n /** Optional memo to attach to the transaction */\n memo?: {\n /** The memo type */\n type: MemoType;\n /** The memo value */\n value: string;\n };\n /** The network to build for */\n network: Network;\n /** Transaction validity timeout in seconds (default: 180) */\n timeout?: number;\n}\n\n/**\n * Creates a Stellar Asset object.\n *\n * @param code - The asset code (e.g., \"XLM\", \"USDC\")\n * @param issuer - The asset issuer address (required for non-XLM assets)\n * @returns A Stellar Asset object\n * @throws {InvalidAssetError} If a non-XLM asset is missing an issuer\n *\n * @example\n * ```typescript\n * // Native XLM\n * const xlm = createAsset('XLM');\n *\n * // Custom asset\n * const usdc = createAsset('USDC', 'GA5ZSEJYB37JRC5AVCIA5MOP4RHTM335X2KGX3IHOJAPP5RE34K4KZVN');\n * ```\n */\nexport function createAsset(code: string, issuer?: string): StellarSdk.Asset {\n if (!code || code.toUpperCase() === 'XLM') {\n return StellarSdk.Asset.native();\n }\n\n if (!issuer) {\n throw new InvalidAssetError(`Asset issuer is required for non-XLM asset: ${code}`);\n }\n\n if (!isValidStellarAddress(issuer)) {\n throw new InvalidAssetError(`Invalid asset issuer address: ${issuer}`);\n }\n\n return new StellarSdk.Asset(code, issuer);\n}\n\n/**\n * Builds a Stellar payment transaction and returns the XDR.\n *\n * This function creates a complete unsigned transaction that can be\n * signed by a wallet like Freighter.\n *\n * @param options - The payment options\n * @returns The transaction XDR string\n * @throws {InvalidAddressError} If source or destination address is invalid\n * @throws {InvalidAmountError} If amount is invalid\n * @throws {InvalidAssetError} If asset configuration is invalid\n *\n * @example\n * ```typescript\n * const xdr = buildPaymentTransaction({\n * source: 'GDQP2K...',\n * sequence: '123456789',\n * destination: 'GBZX...',\n * amount: '10.5',\n * asset: { code: 'USDC', issuer: 'GA5ZS...' },\n * memo: { type: 'MEMO_TEXT', value: 'Payment for coffee' },\n * network: 'public',\n * });\n * ```\n */\nexport function buildPaymentTransaction(options: BuildPaymentOptions): string {\n const {\n source,\n sequence,\n destination,\n amount,\n asset,\n memo,\n network,\n timeout = 180,\n } = options;\n\n // Validate inputs\n if (!isValidStellarAddress(source)) {\n throw new InvalidAddressError(source);\n }\n\n if (!isValidStellarAddress(destination)) {\n throw new InvalidAddressError(destination);\n }\n\n if (!isValidAmount(amount)) {\n throw new InvalidAmountError(amount);\n }\n\n const networkPassphrase = NETWORK_PASSPHRASES[network];\n\n // Create a minimal account object for TransactionBuilder\n const sourceAccount = new StellarSdk.Account(source, sequence);\n\n // Build transaction\n const builder = new StellarSdk.TransactionBuilder(sourceAccount, {\n fee: StellarSdk.BASE_FEE,\n networkPassphrase,\n });\n\n // Determine asset\n const stellarAsset = asset\n ? createAsset(asset.code, asset.issuer)\n : StellarSdk.Asset.native();\n\n // Add payment operation\n builder.addOperation(\n StellarSdk.Operation.payment({\n destination,\n asset: stellarAsset,\n amount: String(amount),\n })\n );\n\n // Add memo if present\n if (memo) {\n switch (memo.type) {\n case 'MEMO_ID':\n builder.addMemo(StellarSdk.Memo.id(memo.value));\n break;\n case 'MEMO_HASH':\n builder.addMemo(StellarSdk.Memo.hash(memo.value));\n break;\n case 'MEMO_RETURN':\n builder.addMemo(StellarSdk.Memo.return(memo.value));\n break;\n case 'MEMO_TEXT':\n default:\n builder.addMemo(StellarSdk.Memo.text(memo.value));\n break;\n }\n }\n\n // Set timeout and build\n builder.setTimeout(timeout);\n const transaction = builder.build();\n\n return transaction.toXDR();\n}\n","import {\n isConnected,\n isAllowed,\n setAllowed,\n getAddress,\n getNetwork,\n signTransaction,\n} from '@stellar/freighter-api';\nimport * as StellarSdk from '@stellar/stellar-sdk';\nimport { NETWORK_PASSPHRASES, HORIZON_URLS, type Network } from './constants';\nimport { StellarSnapError } from './errors';\n\n/**\n * Result of connecting to Freighter wallet.\n */\nexport interface FreighterConnectionResult {\n /** The user's Stellar public address */\n publicKey: string;\n /** The network the wallet is connected to */\n network: Network;\n}\n\n/**\n * Result of submitting a transaction.\n */\nexport interface TransactionSubmitResult {\n /** The transaction hash (can be used in block explorers) */\n hash: string;\n /** Whether the transaction was successful */\n successful: boolean;\n /** The ledger number the transaction was included in */\n ledger?: number;\n}\n\n/**\n * Checks if Freighter wallet extension is installed and connected.\n *\n * @returns true if Freighter is installed and the user has granted access\n *\n * @example\n * ```typescript\n * if (await isFreighterConnected()) {\n * console.log('Ready to sign transactions!');\n * } else {\n * console.log('Please connect your Freighter wallet');\n * }\n * ```\n */\nexport async function isFreighterConnected(): Promise<boolean> {\n try {\n const connected = await isConnected();\n if (!connected) return false;\n\n const allowedResult = await isAllowed();\n return allowedResult.isAllowed;\n } catch {\n return false;\n }\n}\n\n/**\n * Gets the current network from Freighter wallet.\n *\n * @returns The network the user's wallet is connected to\n * @throws {StellarSnapError} If unable to get network\n *\n * @example\n * ```typescript\n * const network = await getFreighterNetwork();\n * console.log(`Connected to ${network}`); // 'public' or 'testnet'\n * ```\n */\nexport async function getFreighterNetwork(): Promise<Network> {\n try {\n const networkDetails = await getNetwork();\n const passphrase = networkDetails.networkPassphrase;\n\n if (passphrase === NETWORK_PASSPHRASES.public) {\n return 'public';\n } else if (passphrase === NETWORK_PASSPHRASES.testnet) {\n return 'testnet';\n }\n\n // Default to testnet for unknown networks\n return 'testnet';\n } catch (error) {\n throw new StellarSnapError(\n `Failed to get network from Freighter: ${error}`,\n 'FREIGHTER_NETWORK_ERROR'\n );\n }\n}\n\n/**\n * Connects to the Freighter wallet and returns the user's public key and network.\n *\n * This will prompt the user to grant access if they haven't already.\n *\n * @returns The user's public key and current network\n * @throws {StellarSnapError} If Freighter is not installed or connection fails\n *\n * @example\n * ```typescript\n * try {\n * const { publicKey, network } = await connectFreighter();\n * console.log(`Connected: ${publicKey} on ${network}`);\n * } catch (error) {\n * console.error('Failed to connect:', error.message);\n * }\n * ```\n */\nexport async function connectFreighter(): Promise<FreighterConnectionResult> {\n try {\n // Check if Freighter is installed\n const connected = await isConnected();\n if (!connected) {\n throw new StellarSnapError(\n 'Freighter wallet is not installed. Please install it from https://freighter.app',\n 'FREIGHTER_NOT_INSTALLED'\n );\n }\n\n // Request access if not already allowed\n const allowedResult = await isAllowed();\n if (!allowedResult.isAllowed) {\n await setAllowed();\n }\n\n // Get the user's address\n const addressResult = await getAddress();\n if (!addressResult.address) {\n throw new StellarSnapError(\n 'Failed to get address from Freighter',\n 'FREIGHTER_ADDRESS_ERROR'\n );\n }\n\n // Get the network\n const network = await getFreighterNetwork();\n\n return {\n publicKey: addressResult.address,\n network,\n };\n } catch (error) {\n if (error instanceof StellarSnapError) {\n throw error;\n }\n throw new StellarSnapError(\n `Failed to connect to Freighter: ${error}`,\n 'FREIGHTER_CONNECTION_ERROR'\n );\n }\n}\n\n/**\n * Signs a transaction using Freighter wallet.\n *\n * This will open the Freighter popup for the user to review and approve the transaction.\n *\n * @param xdr - The unsigned transaction XDR\n * @param network - The network the transaction is for\n * @returns The signed transaction XDR\n * @throws {StellarSnapError} If signing fails or user rejects\n *\n * @example\n * ```typescript\n * const unsignedXdr = buildPaymentTransaction({ ... });\n * const signedXdr = await signWithFreighter(unsignedXdr, 'public');\n * ```\n */\nexport async function signWithFreighter(\n xdr: string,\n network: Network\n): Promise<string> {\n try {\n const networkPassphrase = NETWORK_PASSPHRASES[network];\n const result = await signTransaction(xdr, {\n networkPassphrase,\n });\n\n if (!result.signedTxXdr) {\n throw new StellarSnapError(\n 'Transaction signing was cancelled or failed',\n 'FREIGHTER_SIGN_CANCELLED'\n );\n }\n\n return result.signedTxXdr;\n } catch (error) {\n if (error instanceof StellarSnapError) {\n throw error;\n }\n throw new StellarSnapError(\n `Failed to sign transaction: ${error}`,\n 'FREIGHTER_SIGN_ERROR'\n );\n }\n}\n\n/**\n * Submits a signed transaction to the Stellar network.\n *\n * @param signedXdr - The signed transaction XDR\n * @param network - The network to submit to\n * @returns The transaction result including hash and success status\n * @throws {StellarSnapError} If submission fails\n *\n * @example\n * ```typescript\n * const signedXdr = await signWithFreighter(unsignedXdr, 'public');\n * const result = await submitTransaction(signedXdr, 'public');\n *\n * if (result.successful) {\n * console.log(`Transaction successful! Hash: ${result.hash}`);\n * console.log(`View on explorer: https://stellar.expert/explorer/public/tx/${result.hash}`);\n * }\n * ```\n */\nexport async function submitTransaction(\n signedXdr: string,\n network: Network\n): Promise<TransactionSubmitResult> {\n try {\n const horizonUrl = HORIZON_URLS[network];\n const server = new StellarSdk.Horizon.Server(horizonUrl);\n const networkPassphrase = NETWORK_PASSPHRASES[network];\n\n // Parse the signed transaction\n const transaction = StellarSdk.TransactionBuilder.fromXDR(\n signedXdr,\n networkPassphrase\n );\n\n // Submit to the network\n const response = await server.submitTransaction(transaction);\n\n return {\n hash: response.hash,\n successful: response.successful,\n ledger: response.ledger,\n };\n } catch (error: unknown) {\n // Handle Horizon error responses\n const horizonError = error as { response?: { data?: { extras?: { result_codes?: unknown } } }; message?: string };\n if (horizonError.response?.data?.extras?.result_codes) {\n const resultCodes = horizonError.response.data.extras.result_codes;\n throw new StellarSnapError(\n `Transaction failed: ${JSON.stringify(resultCodes)}`,\n 'TRANSACTION_FAILED'\n );\n }\n\n throw new StellarSnapError(\n `Failed to submit transaction: ${horizonError.message || error}`,\n 'SUBMIT_ERROR'\n );\n }\n}\n","/**\n * A rule for matching URL paths to API endpoints.\n */\nexport interface DiscoveryRule {\n /**\n * URL path pattern with wildcards.\n * Use `*` as a wildcard that matches any characters.\n *\n * @example \"/s/*\" matches \"/s/abc123\"\n * @example \"/pay/*\" matches \"/pay/user123\"\n */\n pathPattern: string;\n\n /**\n * API endpoint path template.\n * Use `$1`, `$2`, etc. to insert captured wildcards.\n *\n * @example \"/api/snap/$1\" with pathPattern \"/s/*\" and URL \"/s/abc\"\n * resolves to \"/api/snap/abc\"\n */\n apiPath: string;\n}\n\n/**\n * Discovery file structure for Stellar Snaps.\n *\n * This file should be hosted at `/.well-known/stellar-snap.json` on your domain\n * to enable the browser extension to discover and render your snaps.\n */\nexport interface DiscoveryFile {\n /** The name of your application */\n name: string;\n\n /** A short description of your application */\n description?: string;\n\n /** URL to your application's icon (recommended: 128x128 PNG) */\n icon?: string;\n\n /** Rules for matching URLs to snap metadata endpoints */\n rules: DiscoveryRule[];\n}\n\n/**\n * Options for creating a discovery file.\n */\nexport interface CreateDiscoveryFileOptions {\n /** The name of your application */\n name: string;\n /** A short description of your application */\n description?: string;\n /** URL to your application's icon */\n icon?: string;\n /** Rules for matching URLs to snap metadata endpoints */\n rules: DiscoveryRule[];\n}\n\n/**\n * Creates a valid discovery file object.\n *\n * Use this to generate the JSON that should be hosted at\n * `/.well-known/stellar-snap.json` on your domain.\n *\n * @param options - The discovery file configuration\n * @returns A valid DiscoveryFile object\n *\n * @example\n * ```typescript\n * const discovery = createDiscoveryFile({\n * name: 'My Payment App',\n * description: 'Accept Stellar payments easily',\n * rules: [\n * { pathPattern: '/pay/*', apiPath: '/api/snap/$1' },\n * { pathPattern: '/donate/*', apiPath: '/api/donation/$1' },\n * ],\n * });\n *\n * // Save as /.well-known/stellar-snap.json\n * fs.writeFileSync(\n * 'public/.well-known/stellar-snap.json',\n * JSON.stringify(discovery, null, 2)\n * );\n * ```\n */\nexport function createDiscoveryFile(options: CreateDiscoveryFileOptions): DiscoveryFile {\n const { name, description, icon, rules } = options;\n\n if (!name || typeof name !== 'string') {\n throw new Error('Discovery file requires a name');\n }\n\n if (!rules || !Array.isArray(rules) || rules.length === 0) {\n throw new Error('Discovery file requires at least one rule');\n }\n\n // Validate rules\n for (const rule of rules) {\n if (!rule.pathPattern || typeof rule.pathPattern !== 'string') {\n throw new Error('Each rule requires a pathPattern');\n }\n if (!rule.apiPath || typeof rule.apiPath !== 'string') {\n throw new Error('Each rule requires an apiPath');\n }\n }\n\n const discoveryFile: DiscoveryFile = {\n name,\n rules,\n };\n\n if (description) {\n discoveryFile.description = description;\n }\n\n if (icon) {\n discoveryFile.icon = icon;\n }\n\n return discoveryFile;\n}\n\n/**\n * Validates that an unknown object is a valid discovery file.\n *\n * Use this to validate discovery files fetched from other domains.\n *\n * @param file - The object to validate\n * @returns true if the object is a valid DiscoveryFile\n *\n * @example\n * ```typescript\n * const response = await fetch('https://example.com/.well-known/stellar-snap.json');\n * const data = await response.json();\n *\n * if (validateDiscoveryFile(data)) {\n * console.log('Valid discovery file:', data.name);\n * } else {\n * console.error('Invalid discovery file');\n * }\n * ```\n */\nexport function validateDiscoveryFile(file: unknown): file is DiscoveryFile {\n if (!file || typeof file !== 'object') {\n return false;\n }\n\n const obj = file as Record<string, unknown>;\n\n // Check required fields\n if (typeof obj.name !== 'string' || !obj.name) {\n return false;\n }\n\n if (!Array.isArray(obj.rules) || obj.rules.length === 0) {\n return false;\n }\n\n // Validate each rule\n for (const rule of obj.rules) {\n if (!rule || typeof rule !== 'object') {\n return false;\n }\n const ruleObj = rule as Record<string, unknown>;\n if (typeof ruleObj.pathPattern !== 'string' || !ruleObj.pathPattern) {\n return false;\n }\n if (typeof ruleObj.apiPath !== 'string' || !ruleObj.apiPath) {\n return false;\n }\n }\n\n // Optional fields should be correct types if present\n if (obj.description !== undefined && typeof obj.description !== 'string') {\n return false;\n }\n\n if (obj.icon !== undefined && typeof obj.icon !== 'string') {\n return false;\n }\n\n return true;\n}\n\n/**\n * Matches a URL pathname against discovery rules and returns the API path.\n *\n * This is used to find which API endpoint to call for a given URL.\n *\n * @param pathname - The URL pathname to match (e.g., \"/s/abc123\")\n * @param rules - The discovery rules to match against\n * @returns The resolved API path, or null if no match\n *\n * @example\n * ```typescript\n * const rules = [\n * { pathPattern: '/s/*', apiPath: '/api/snap/$1' },\n * { pathPattern: '/pay/*', apiPath: '/api/payment/$1' },\n * ];\n *\n * matchUrlToRule('/s/abc123', rules);\n * // => '/api/snap/abc123'\n *\n * matchUrlToRule('/pay/user456', rules);\n * // => '/api/payment/user456'\n *\n * matchUrlToRule('/unknown/path', rules);\n * // => null\n * ```\n */\nexport function matchUrlToRule(\n pathname: string,\n rules: DiscoveryRule[]\n): string | null {\n for (const rule of rules) {\n // Convert pathPattern to regex\n // \"/s/*\" becomes /^\\/s\\/(.+)$/\n const pattern = rule.pathPattern\n .replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&') // Escape special regex chars\n .replace(/\\\\\\*/g, '(.+)'); // Convert \\* back to capture group\n\n const regex = new RegExp(`^${pattern}$`);\n const match = pathname.match(regex);\n\n if (match) {\n // Replace $1, $2, etc. with captured groups\n let apiPath = rule.apiPath;\n for (let i = 1; i < match.length; i++) {\n const captured = match[i];\n if (captured !== undefined) {\n apiPath = apiPath.replace(`$${i}`, captured);\n }\n }\n return apiPath;\n }\n }\n\n return null;\n}\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/errors.ts","../src/create-snap.ts","../src/snap-id.ts","../src/schema.ts","../src/create-payment-snap.ts","../src/constants.ts","../src/create-transaction-snap.ts","../src/parse-snap-uri.ts","../src/validation.ts","../src/transaction.ts","../src/freighter.ts","../src/discovery.ts","../src/url-resolver.ts","../src/registry.ts","../src/explorer.ts","../src/meta-tags.ts","../src/server.ts"],"names":["NETWORK_PASSPHRASES","StellarSdk","isConnected","isAllowed","getNetwork","setAllowed","getAddress","signTransaction","StellarSdk2"],"mappings":"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","file":"index.js","sourcesContent":["/**\n * Base error class for all Stellar Snaps SDK errors.\n * Includes an error code for programmatic error handling.\n */\nexport class StellarSnapError extends Error {\n constructor(\n message: string,\n public code: string\n ) {\n super(message);\n this.name = 'StellarSnapError';\n }\n}\n\n/**\n * Thrown when a Stellar address is invalid.\n * Valid addresses are 56 characters long and start with 'G'.\n */\nexport class InvalidAddressError extends StellarSnapError {\n constructor(address: string) {\n super(`Invalid Stellar address: ${address}`, 'INVALID_ADDRESS');\n this.name = 'InvalidAddressError';\n }\n}\n\n/**\n * Thrown when an amount is invalid.\n * Amounts must be positive numbers represented as strings.\n */\nexport class InvalidAmountError extends StellarSnapError {\n constructor(amount: string) {\n super(`Invalid amount: ${amount}. Must be a positive number.`, 'INVALID_AMOUNT');\n this.name = 'InvalidAmountError';\n }\n}\n\n/**\n * Thrown when an asset configuration is invalid.\n * Non-XLM assets require both a code and an issuer address.\n */\nexport class InvalidAssetError extends StellarSnapError {\n constructor(message: string) {\n super(message, 'INVALID_ASSET');\n this.name = 'InvalidAssetError';\n }\n}\n\n/**\n * Thrown when a SEP-0007 URI is invalid or malformed.\n */\nexport class InvalidUriError extends StellarSnapError {\n constructor(message: string) {\n super(message, 'INVALID_URI');\n this.name = 'InvalidUriError';\n }\n}\n\n/**\n * Thrown when a snap is not found (404 from API).\n */\nexport class SnapNotFoundError extends StellarSnapError {\n constructor(snapId: string) {\n super(`Snap not found: ${snapId}`, 'SNAP_NOT_FOUND');\n this.name = 'SnapNotFoundError';\n }\n}\n\n/**\n * Thrown when the caller is not authorized to perform the action (e.g. delete another user's snap).\n */\nexport class SnapUnauthorizedError extends StellarSnapError {\n constructor(message: string = 'Unauthorized') {\n super(message, 'SNAP_UNAUTHORIZED');\n this.name = 'SnapUnauthorizedError';\n }\n}\n\n/**\n * Thrown when the Stellar Snaps API returns an error.\n */\nexport class SnapApiError extends StellarSnapError {\n constructor(\n message: string,\n public statusCode?: number\n ) {\n super(message, 'SNAP_API_ERROR');\n this.name = 'SnapApiError';\n }\n}\n","/**\n * Shareable Snap API\n *\n * Functions that mirror the Stellar Snaps web app API. Create, fetch, list,\n * and delete database-backed snaps so developers get the same behavior as\n * the dashboard. Uses https://stellar-snaps.vercel.app by default.\n */\n\nimport {\n InvalidAddressError,\n SnapNotFoundError,\n SnapUnauthorizedError,\n SnapApiError,\n} from './errors';\n\nconst DEFAULT_BASE_URL = 'https://stellar-snaps.vercel.app';\n\n/** Snap as returned by the web app API (GET /api/snap/[id] omits creator; list/create include it). */\nexport interface Snap {\n id: string;\n creator?: string;\n title: string;\n description?: string | null;\n destination: string;\n amount?: string | null;\n assetCode: string;\n assetIssuer?: string | null;\n memo?: string | null;\n memoType?: string;\n network: string;\n imageUrl?: string | null;\n createdAt?: string;\n updatedAt?: string;\n}\n\nexport interface CreateSnapOptions {\n /** Creator's Stellar address (required) */\n creator: string;\n /** Display title for the snap (required) */\n title: string;\n /** Payment destination address (required) */\n destination: string;\n /** Optional description */\n description?: string;\n /** Payment amount (optional - if not set, payer enters amount) */\n amount?: string;\n /** Asset code (default: 'XLM') */\n assetCode?: string;\n /** Asset issuer (required for non-XLM assets) */\n assetIssuer?: string;\n /** Transaction memo */\n memo?: string;\n /** Memo type (default: 'MEMO_TEXT') */\n memoType?: 'MEMO_TEXT' | 'MEMO_ID' | 'MEMO_HASH' | 'MEMO_RETURN';\n /** Network (default: 'testnet') */\n network?: 'public' | 'testnet';\n /** Optional image URL for the snap */\n imageUrl?: string;\n /** Stellar Snaps server base URL (default: 'https://stellar-snaps.vercel.app') */\n baseUrl?: string;\n}\n\nexport interface CreateSnapResult {\n /** The created snap ID */\n id: string;\n /** Full shareable URL (e.g. https://stellar-snaps.vercel.app/s/abc123) */\n url: string;\n /** The snap data as returned by the API */\n snap: Snap;\n}\n\n/**\n * Creates a shareable snap on a Stellar Snaps server.\n *\n * @example\n * ```typescript\n * const result = await createSnap({\n * creator: 'GCREATOR...',\n * title: 'Coffee Payment',\n * destination: 'GDEST...',\n * amount: '5',\n * baseUrl: 'https://stellar-snaps.vercel.app'\n * });\n * console.log(result.url);\n * // https://stellar-snaps.vercel.app/s/abc12345\n * ```\n */\nexport async function createSnap(\n options: CreateSnapOptions\n): Promise<CreateSnapResult> {\n const baseUrl = options.baseUrl ?? DEFAULT_BASE_URL;\n const {\n creator,\n title,\n destination,\n description,\n amount,\n assetCode = 'XLM',\n assetIssuer,\n memo,\n memoType = 'MEMO_TEXT',\n network = 'testnet',\n imageUrl,\n } = options;\n\n if (!creator || creator.length !== 56 || !creator.startsWith('G')) {\n throw new InvalidAddressError(creator || '');\n }\n\n if (!title || title.trim().length === 0) {\n throw new SnapApiError('Title is required');\n }\n\n if (!destination || destination.length !== 56 || !destination.startsWith('G')) {\n throw new InvalidAddressError(destination || '');\n }\n\n if (assetCode !== 'XLM' && !assetIssuer) {\n throw new SnapApiError('Asset issuer is required for non-XLM assets');\n }\n\n const body = {\n creator,\n title,\n destination,\n description,\n amount,\n assetCode,\n assetIssuer,\n memo,\n memoType,\n network,\n imageUrl,\n };\n\n const response = await fetch(`${baseUrl}/api/snaps`, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify(body),\n });\n\n if (!response.ok) {\n const data = await response.json().catch(() => ({ error: 'Unknown error' }));\n const message = (data as { error?: string }).error || `Failed to create snap: ${response.status}`;\n throw new SnapApiError(message, response.status);\n }\n\n const snap: Snap = await response.json();\n\n return {\n id: snap.id,\n url: `${baseUrl}/s/${snap.id}`,\n snap,\n };\n}\n\n/**\n * Fetches a snap by ID from the Stellar Snaps server.\n * Uses GET /api/snap/[id] (singular path, same as web app).\n *\n * @throws SnapNotFoundError if the snap does not exist\n * @throws SnapApiError if the request fails\n */\nexport async function getSnap(\n id: string,\n options: { baseUrl?: string } = {}\n): Promise<Snap> {\n const baseUrl = options.baseUrl ?? DEFAULT_BASE_URL;\n\n const response = await fetch(`${baseUrl}/api/snap/${id}`);\n\n if (response.status === 404) {\n throw new SnapNotFoundError(id);\n }\n\n if (!response.ok) {\n const data = await response.json().catch(() => ({}));\n const message = (data as { error?: string }).error || `Failed to fetch snap: ${response.status}`;\n throw new SnapApiError(message, response.status);\n }\n\n return response.json();\n}\n\n/**\n * Lists snaps created by a specific address (GET /api/snaps?creator=...).\n */\nexport async function listSnaps(\n creator: string,\n options: { baseUrl?: string } = {}\n): Promise<Snap[]> {\n const baseUrl = options.baseUrl ?? DEFAULT_BASE_URL;\n\n const response = await fetch(\n `${baseUrl}/api/snaps?creator=${encodeURIComponent(creator)}`\n );\n\n if (!response.ok) {\n const data = await response.json().catch(() => ({}));\n const message = (data as { error?: string }).error || `Failed to list snaps: ${response.status}`;\n throw new SnapApiError(message, response.status);\n }\n\n return response.json();\n}\n\n/**\n * Deletes a snap by ID. Requires the creator's address (same as web app: DELETE /api/snaps?id=...&creator=...).\n *\n * @throws SnapNotFoundError if the snap does not exist\n * @throws SnapUnauthorizedError if the creator does not own the snap\n * @throws SnapApiError if the request fails\n */\nexport async function deleteSnap(\n id: string,\n creator: string,\n options: { baseUrl?: string } = {}\n): Promise<void> {\n const baseUrl = options.baseUrl ?? DEFAULT_BASE_URL;\n\n const url = `${baseUrl}/api/snaps?id=${encodeURIComponent(id)}&creator=${encodeURIComponent(creator)}`;\n const response = await fetch(url, { method: 'DELETE' });\n\n if (response.status === 404) {\n throw new SnapNotFoundError(id);\n }\n\n if (response.status === 403) {\n throw new SnapUnauthorizedError('You do not have permission to delete this snap');\n }\n\n if (!response.ok) {\n const data = await response.json().catch(() => ({}));\n const message = (data as { error?: string }).error || `Failed to delete snap: ${response.status}`;\n throw new SnapApiError(message, response.status);\n }\n}\n","/**\n * Snap ID Generation\n *\n * Generates unique, URL-safe IDs for snaps.\n */\n\n/** Characters used for ID generation (URL-safe) */\nconst ALPHABET =\n 'useandom-26T198340PX75pxJACKVERYMINDBUSHWOLF_GQZbfghjklqvwyzrict';\n\n/**\n * Generates a random snap ID.\n *\n * Uses a URL-safe alphabet similar to nanoid.\n * Default length is 8 characters (similar to YouTube video IDs).\n *\n * @example\n * ```typescript\n * const id = generateSnapId(); // 'nk1VNcxo'\n * const longId = generateSnapId(12); // 'nk1VNcxo4Abc'\n * ```\n */\nexport function generateSnapId(length: number = 8): string {\n let id = '';\n const randomValues = new Uint8Array(length);\n\n // Use crypto.getRandomValues if available (browser/Node 15+)\n if (typeof crypto !== 'undefined' && crypto.getRandomValues) {\n crypto.getRandomValues(randomValues);\n } else {\n // Fallback for older environments\n for (let i = 0; i < length; i++) {\n randomValues[i] = Math.floor(Math.random() * 256);\n }\n }\n\n for (let i = 0; i < length; i++) {\n id += ALPHABET[randomValues[i]! % ALPHABET.length];\n }\n\n return id;\n}\n\n/**\n * Validates a snap ID format.\n *\n * @example\n * ```typescript\n * isValidSnapId('nk1VNcxo'); // true\n * isValidSnapId(''); // false\n * isValidSnapId('has spaces'); // false\n * ```\n */\nexport function isValidSnapId(id: string): boolean {\n if (!id || typeof id !== 'string') return false;\n if (id.length < 4 || id.length > 32) return false;\n\n // Only allow URL-safe characters\n return /^[a-zA-Z0-9_-]+$/.test(id);\n}\n\n/**\n * Extracts a snap ID from a URL.\n *\n * @example\n * ```typescript\n * extractSnapId('https://stellarsnaps.com/s/nk1VNcxo'); // 'nk1VNcxo'\n * extractSnapId('https://example.com/pay/abc123'); // 'abc123'\n * ```\n */\nexport function extractSnapId(\n url: string,\n patterns: string[] = ['/s/', '/snap/', '/pay/']\n): string | null {\n try {\n const parsed = new URL(url);\n const path = parsed.pathname;\n\n for (const pattern of patterns) {\n const index = path.indexOf(pattern);\n if (index !== -1) {\n const idStart = index + pattern.length;\n const remaining = path.slice(idStart);\n // Extract ID (stop at next slash or end)\n const match = remaining.match(/^([a-zA-Z0-9_-]+)/);\n if (match && isValidSnapId(match[1]!)) {\n return match[1]!;\n }\n }\n }\n\n return null;\n } catch {\n return null;\n }\n}\n","/**\n * Database Schema Types\n *\n * Type definitions for snap storage. These types can be used\n * with any database (PostgreSQL, SQLite, MongoDB, etc.).\n */\n\nimport type { Network, MemoType } from './constants';\n\n/**\n * Snap record as stored in the database.\n */\nexport interface Snap {\n /** Unique snap ID (e.g., 'nk1VNcxo') */\n id: string;\n\n /** Creator's Stellar address */\n creator: string;\n\n /** Display title */\n title: string;\n\n /** Optional description */\n description?: string | null;\n\n /** Optional image URL */\n imageUrl?: string | null;\n\n /** Payment destination address */\n destination: string;\n\n /** Asset code (default: 'XLM') */\n assetCode: string;\n\n /** Asset issuer (required for non-XLM) */\n assetIssuer?: string | null;\n\n /** Fixed amount (null = payer chooses) */\n amount?: string | null;\n\n /** Transaction memo */\n memo?: string | null;\n\n /** Memo type */\n memoType: MemoType | string;\n\n /** Network ('public' or 'testnet') */\n network: Network | string;\n\n /** Creation timestamp */\n createdAt: Date | string;\n\n /** Last update timestamp */\n updatedAt: Date | string;\n}\n\n/**\n * Input for creating a new snap.\n */\nexport interface CreateSnapInput {\n /** Creator's Stellar address (required) */\n creator: string;\n\n /** Display title (required) */\n title: string;\n\n /** Payment destination address (required) */\n destination: string;\n\n /** Optional description */\n description?: string;\n\n /** Optional image URL */\n imageUrl?: string;\n\n /** Asset code (default: 'XLM') */\n assetCode?: string;\n\n /** Asset issuer (required for non-XLM) */\n assetIssuer?: string;\n\n /** Fixed amount */\n amount?: string;\n\n /** Transaction memo */\n memo?: string;\n\n /** Memo type (default: 'MEMO_TEXT') */\n memoType?: MemoType;\n\n /** Network (default: 'testnet') */\n network?: Network;\n}\n\n/**\n * Input for updating a snap.\n */\nexport interface UpdateSnapInput {\n /** Display title */\n title?: string;\n\n /** Description */\n description?: string | null;\n\n /** Image URL */\n imageUrl?: string | null;\n\n /** Payment amount */\n amount?: string | null;\n\n /** Transaction memo */\n memo?: string | null;\n\n /** Memo type */\n memoType?: MemoType;\n}\n\n/**\n * Validates snap input data.\n *\n * @throws Error if validation fails\n */\nexport function validateSnapInput(input: CreateSnapInput): void {\n // Validate creator\n if (!input.creator || input.creator.length !== 56 || !input.creator.startsWith('G')) {\n throw new Error('Invalid creator address');\n }\n\n // Validate destination\n if (!input.destination || input.destination.length !== 56 || !input.destination.startsWith('G')) {\n throw new Error('Invalid destination address');\n }\n\n // Validate title\n if (!input.title || input.title.trim().length === 0) {\n throw new Error('Title is required');\n }\n\n if (input.title.length > 100) {\n throw new Error('Title must be 100 characters or less');\n }\n\n // Validate description\n if (input.description && input.description.length > 500) {\n throw new Error('Description must be 500 characters or less');\n }\n\n // Validate asset\n if (input.assetCode && input.assetCode !== 'XLM' && !input.assetIssuer) {\n throw new Error('Asset issuer is required for non-XLM assets');\n }\n\n if (input.assetIssuer && (input.assetIssuer.length !== 56 || !input.assetIssuer.startsWith('G'))) {\n throw new Error('Invalid asset issuer address');\n }\n\n // Validate amount\n if (input.amount) {\n const amountNum = parseFloat(input.amount);\n if (isNaN(amountNum) || amountNum <= 0) {\n throw new Error('Amount must be a positive number');\n }\n }\n\n // Validate network\n if (input.network && !['public', 'testnet'].includes(input.network)) {\n throw new Error('Network must be \"public\" or \"testnet\"');\n }\n\n // Validate memo type\n if (input.memoType && !['MEMO_TEXT', 'MEMO_ID', 'MEMO_HASH', 'MEMO_RETURN'].includes(input.memoType)) {\n throw new Error('Invalid memo type');\n }\n}\n\n/**\n * Creates a snap object with defaults.\n */\nexport function createSnapObject(id: string, input: CreateSnapInput): Snap {\n validateSnapInput(input);\n\n const now = new Date().toISOString();\n\n return {\n id,\n creator: input.creator,\n title: input.title.trim(),\n description: input.description?.trim() || null,\n imageUrl: input.imageUrl || null,\n destination: input.destination,\n assetCode: input.assetCode || 'XLM',\n assetIssuer: input.assetIssuer || null,\n amount: input.amount || null,\n memo: input.memo || null,\n memoType: input.memoType || 'MEMO_TEXT',\n network: input.network || 'testnet',\n createdAt: now,\n updatedAt: now,\n };\n}\n\n/**\n * SQL schema for PostgreSQL.\n *\n * @example\n * ```typescript\n * // Run this SQL to create the snaps table:\n * await db.execute(POSTGRES_SCHEMA);\n * ```\n */\nexport const POSTGRES_SCHEMA = `\nCREATE TABLE IF NOT EXISTS snaps (\n id TEXT PRIMARY KEY,\n creator TEXT NOT NULL,\n title TEXT NOT NULL,\n description TEXT,\n image_url TEXT,\n destination TEXT NOT NULL,\n asset_code TEXT NOT NULL DEFAULT 'XLM',\n asset_issuer TEXT,\n amount TEXT,\n memo TEXT,\n memo_type TEXT NOT NULL DEFAULT 'MEMO_TEXT',\n network TEXT NOT NULL DEFAULT 'testnet',\n created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(),\n updated_at TIMESTAMP WITH TIME ZONE DEFAULT NOW()\n);\n\nCREATE INDEX IF NOT EXISTS idx_snaps_creator ON snaps(creator);\nCREATE INDEX IF NOT EXISTS idx_snaps_destination ON snaps(destination);\n`;\n\n/**\n * SQL schema for SQLite.\n */\nexport const SQLITE_SCHEMA = `\nCREATE TABLE IF NOT EXISTS snaps (\n id TEXT PRIMARY KEY,\n creator TEXT NOT NULL,\n title TEXT NOT NULL,\n description TEXT,\n image_url TEXT,\n destination TEXT NOT NULL,\n asset_code TEXT NOT NULL DEFAULT 'XLM',\n asset_issuer TEXT,\n amount TEXT,\n memo TEXT,\n memo_type TEXT NOT NULL DEFAULT 'MEMO_TEXT',\n network TEXT NOT NULL DEFAULT 'testnet',\n created_at TEXT DEFAULT (datetime('now')),\n updated_at TEXT DEFAULT (datetime('now'))\n);\n\nCREATE INDEX IF NOT EXISTS idx_snaps_creator ON snaps(creator);\nCREATE INDEX IF NOT EXISTS idx_snaps_destination ON snaps(destination);\n`;\n","export interface PaymentSnapOptions {\n destination: string;\n amount?: string;\n assetCode?: string;\n assetIssuer?: string;\n memo?: string;\n memoType?: 'MEMO_TEXT' | 'MEMO_ID' | 'MEMO_HASH' | 'MEMO_RETURN';\n message?: string;\n network?: 'public' | 'testnet';\n callback?: string;\n}\n\nexport interface PaymentSnapResult {\n uri: string;\n params: Record<string, string>;\n}\n\nconst NETWORK_PASSPHRASES = {\n public: 'Public Global Stellar Network ; September 2015',\n testnet: 'Test SDF Network ; September 2015',\n} as const;\n\nexport function createPaymentSnap(options: PaymentSnapOptions): PaymentSnapResult {\n const {\n destination,\n amount,\n assetCode,\n assetIssuer,\n memo,\n memoType = 'MEMO_TEXT',\n message,\n network,\n callback,\n } = options;\n\n if (!destination || destination.length !== 56 || !destination.startsWith('G')) {\n throw new Error('Invalid destination address');\n }\n\n const params: Record<string, string> = { destination };\n\n if (amount) {\n if (isNaN(Number(amount)) || Number(amount) <= 0) {\n throw new Error('Invalid amount');\n }\n params.amount = amount;\n }\n\n if (assetCode && assetCode !== 'XLM') {\n params.asset_code = assetCode;\n if (!assetIssuer) {\n throw new Error('asset_issuer required for non-XLM assets');\n }\n params.asset_issuer = assetIssuer;\n }\n\n if (memo) {\n params.memo = memo;\n params.memo_type = memoType;\n }\n\n if (message) {\n if (message.length > 300) {\n throw new Error('Message cannot exceed 300 characters');\n }\n params.msg = message;\n }\n\n if (network && network !== 'public') {\n params.network_passphrase = NETWORK_PASSPHRASES[network];\n }\n\n if (callback) {\n params.callback = `url:${callback}`;\n }\n\n const queryString = Object.entries(params)\n .map(([key, value]) => `${key}=${encodeURIComponent(value)}`)\n .join('&');\n\n return { uri: `web+stellar:pay?${queryString}`, params };\n}\n","/**\n * Stellar network passphrases used for transaction signing.\n * Each network has a unique passphrase that identifies it.\n */\nexport const NETWORK_PASSPHRASES = {\n public: 'Public Global Stellar Network ; September 2015',\n testnet: 'Test SDF Network ; September 2015',\n} as const;\n\n/**\n * Horizon API URLs for each Stellar network.\n * Horizon is the REST API for interacting with the Stellar network.\n */\nexport const HORIZON_URLS = {\n public: 'https://horizon.stellar.org',\n testnet: 'https://horizon-testnet.stellar.org',\n} as const;\n\n/**\n * Supported Stellar networks.\n * - `public`: The main Stellar network (real money)\n * - `testnet`: Test network for development (free test tokens)\n */\nexport type Network = 'public' | 'testnet';\n\n/**\n * Stellar memo types for attaching metadata to transactions.\n * - `MEMO_TEXT`: Plain text (max 28 bytes)\n * - `MEMO_ID`: 64-bit unsigned integer\n * - `MEMO_HASH`: 32-byte hash\n * - `MEMO_RETURN`: 32-byte hash (for returning payments)\n */\nexport type MemoType = 'MEMO_TEXT' | 'MEMO_ID' | 'MEMO_HASH' | 'MEMO_RETURN';\n","import { NETWORK_PASSPHRASES, type Network } from './constants';\nimport { InvalidUriError } from './errors';\n\n/**\n * Options for creating a transaction snap URI.\n * Used for advanced use cases where you need to sign arbitrary transactions,\n * not just simple payments.\n */\nexport interface TransactionSnapOptions {\n /** The transaction in XDR format (Stellar's binary encoding) */\n xdr: string;\n /** The network this transaction is for (default: 'public') */\n network?: Network;\n /** Human-readable message to show the user when signing */\n message?: string;\n /** URL to call after the transaction is signed */\n callback?: string;\n /** Public key of the required signer */\n pubkey?: string;\n}\n\n/**\n * Result of creating a transaction snap.\n */\nexport interface TransactionSnapResult {\n /** The complete SEP-0007 URI */\n uri: string;\n /** The parsed parameters */\n params: Record<string, string>;\n}\n\n/**\n * Creates a SEP-0007 transaction URI for signing arbitrary Stellar transactions.\n *\n * Unlike payment snaps which are for simple payments, transaction snaps can\n * encode any Stellar transaction (multi-operation, account creation, etc.).\n *\n * @param options - Transaction snap configuration\n * @returns The generated URI and parsed parameters\n * @throws {InvalidUriError} If the XDR is missing or invalid\n *\n * @example\n * ```typescript\n * const { uri } = createTransactionSnap({\n * xdr: 'AAAA...', // Your transaction XDR\n * network: 'testnet',\n * message: 'Please sign this transaction',\n * });\n * // => web+stellar:tx?xdr=AAAA...&network_passphrase=Test%20SDF%20Network...\n * ```\n */\nexport function createTransactionSnap(options: TransactionSnapOptions): TransactionSnapResult {\n const { xdr, network = 'public', message, callback, pubkey } = options;\n\n if (!xdr || typeof xdr !== 'string') {\n throw new InvalidUriError('XDR is required for transaction snaps');\n }\n\n const params: Record<string, string> = {\n xdr: xdr,\n };\n\n // Add network passphrase if not public (public is the default)\n if (network !== 'public') {\n params.network_passphrase = NETWORK_PASSPHRASES[network];\n }\n\n if (message) {\n if (message.length > 300) {\n throw new InvalidUriError('Message cannot exceed 300 characters');\n }\n params.msg = message;\n }\n\n if (callback) {\n params.callback = `url:${callback}`;\n }\n\n if (pubkey) {\n params.pubkey = pubkey;\n }\n\n const queryString = Object.entries(params)\n .map(([key, value]) => `${key}=${encodeURIComponent(value)}`)\n .join('&');\n\n return {\n uri: `web+stellar:tx?${queryString}`,\n params,\n };\n}\n","export interface ParsedSnap {\n type: 'pay' | 'tx';\n destination?: string;\n amount?: string;\n assetCode?: string;\n assetIssuer?: string;\n memo?: string;\n memoType?: string;\n message?: string;\n networkPassphrase?: string;\n callback?: string;\n xdr?: string;\n}\n\nexport function parseSnapUri(uri: string): ParsedSnap {\n if (!uri.startsWith('web+stellar:')) {\n throw new Error('Invalid SEP-0007 URI: must start with web+stellar:');\n }\n\n const withoutScheme = uri.replace('web+stellar:', '');\n const [operation, queryString] = withoutScheme.split('?');\n\n if (operation !== 'pay' && operation !== 'tx') {\n throw new Error(`Invalid operation: ${operation}. Must be 'pay' or 'tx'`);\n }\n\n const params = new URLSearchParams(queryString);\n const parsed: ParsedSnap = { type: operation };\n\n if (operation === 'pay') {\n const destination = params.get('destination');\n if (!destination) {\n throw new Error('Missing required parameter: destination');\n }\n parsed.destination = destination;\n\n if (params.has('amount')) parsed.amount = params.get('amount')!;\n if (params.has('asset_code')) parsed.assetCode = params.get('asset_code')!;\n if (params.has('asset_issuer')) parsed.assetIssuer = params.get('asset_issuer')!;\n if (params.has('memo')) parsed.memo = params.get('memo')!;\n if (params.has('memo_type')) parsed.memoType = params.get('memo_type')!;\n if (params.has('msg')) parsed.message = params.get('msg')!;\n if (params.has('network_passphrase')) parsed.networkPassphrase = params.get('network_passphrase')!;\n if (params.has('callback')) {\n const cb = params.get('callback')!;\n parsed.callback = cb.startsWith('url:') ? cb.slice(4) : cb;\n }\n } else {\n const xdr = params.get('xdr');\n if (!xdr) {\n throw new Error('Missing required parameter: xdr');\n }\n parsed.xdr = xdr;\n if (params.has('msg')) parsed.message = params.get('msg')!;\n if (params.has('network_passphrase')) parsed.networkPassphrase = params.get('network_passphrase')!;\n if (params.has('callback')) {\n const cb = params.get('callback')!;\n parsed.callback = cb.startsWith('url:') ? cb.slice(4) : cb;\n }\n }\n\n return parsed;\n}\n","/**\n * Validates a Stellar public address.\n * Valid addresses are 56 characters long and start with 'G'.\n *\n * @param address - The address to validate\n * @returns true if the address is valid\n *\n * @example\n * ```typescript\n * isValidStellarAddress('GDQP2KPQGKIHYJGXNUIYOMHARUARCA7DJT5FO2FFOOUJ3DTJE4QRK764');\n * // => true\n *\n * isValidStellarAddress('invalid');\n * // => false\n * ```\n */\nexport function isValidStellarAddress(address: string): boolean {\n if (!address || typeof address !== 'string') {\n return false;\n }\n return address.length === 56 && address.startsWith('G');\n}\n\n/**\n * Validates a Stellar asset code.\n * Asset codes are 1-12 alphanumeric characters.\n * \"XLM\" is the native asset and is always valid.\n *\n * @param code - The asset code to validate\n * @returns true if the asset code is valid\n *\n * @example\n * ```typescript\n * isValidAssetCode('USDC');\n * // => true\n *\n * isValidAssetCode('XLM');\n * // => true\n *\n * isValidAssetCode('ThisIsTooLongForAnAssetCode');\n * // => false\n * ```\n */\nexport function isValidAssetCode(code: string): boolean {\n if (!code || typeof code !== 'string') {\n return false;\n }\n // Asset codes are 1-12 alphanumeric characters\n return /^[a-zA-Z0-9]{1,12}$/.test(code);\n}\n\n/**\n * Validates a payment amount.\n * Amounts must be positive numbers represented as strings.\n * Stellar supports up to 7 decimal places.\n *\n * @param amount - The amount to validate\n * @returns true if the amount is valid\n *\n * @example\n * ```typescript\n * isValidAmount('10');\n * // => true\n *\n * isValidAmount('0.0000001');\n * // => true\n *\n * isValidAmount('-5');\n * // => false\n *\n * isValidAmount('0');\n * // => false\n * ```\n */\nexport function isValidAmount(amount: string): boolean {\n if (!amount || typeof amount !== 'string') {\n return false;\n }\n const num = Number(amount);\n return !isNaN(num) && num > 0 && isFinite(num);\n}\n","import * as StellarSdk from '@stellar/stellar-sdk';\nimport { NETWORK_PASSPHRASES, type Network, type MemoType } from './constants';\nimport { InvalidAddressError, InvalidAmountError, InvalidAssetError } from './errors';\nimport { isValidStellarAddress, isValidAmount } from './validation';\n\n/**\n * Options for building a payment transaction.\n */\nexport interface BuildPaymentOptions {\n /** The payer's Stellar public address */\n source: string;\n /** The account sequence number (prevents replay attacks) */\n sequence: string;\n /** The recipient's Stellar public address */\n destination: string;\n /** The amount to send (as a string for precision) */\n amount: string;\n /** The asset to send (defaults to XLM if not specified) */\n asset?: {\n /** Asset code, e.g., \"USDC\", \"XLM\" */\n code: string;\n /** Asset issuer address (required for non-XLM assets) */\n issuer?: string;\n };\n /** Optional memo to attach to the transaction */\n memo?: {\n /** The memo type */\n type: MemoType;\n /** The memo value */\n value: string;\n };\n /** The network to build for */\n network: Network;\n /** Transaction validity timeout in seconds (default: 180) */\n timeout?: number;\n}\n\n/**\n * Creates a Stellar Asset object.\n *\n * @param code - The asset code (e.g., \"XLM\", \"USDC\")\n * @param issuer - The asset issuer address (required for non-XLM assets)\n * @returns A Stellar Asset object\n * @throws {InvalidAssetError} If a non-XLM asset is missing an issuer\n *\n * @example\n * ```typescript\n * // Native XLM\n * const xlm = createAsset('XLM');\n *\n * // Custom asset\n * const usdc = createAsset('USDC', 'GA5ZSEJYB37JRC5AVCIA5MOP4RHTM335X2KGX3IHOJAPP5RE34K4KZVN');\n * ```\n */\nexport function createAsset(code: string, issuer?: string): StellarSdk.Asset {\n if (!code || code.toUpperCase() === 'XLM') {\n return StellarSdk.Asset.native();\n }\n\n if (!issuer) {\n throw new InvalidAssetError(`Asset issuer is required for non-XLM asset: ${code}`);\n }\n\n if (!isValidStellarAddress(issuer)) {\n throw new InvalidAssetError(`Invalid asset issuer address: ${issuer}`);\n }\n\n return new StellarSdk.Asset(code, issuer);\n}\n\n/**\n * Builds a Stellar payment transaction and returns the XDR.\n *\n * This function creates a complete unsigned transaction that can be\n * signed by a wallet like Freighter.\n *\n * @param options - The payment options\n * @returns The transaction XDR string\n * @throws {InvalidAddressError} If source or destination address is invalid\n * @throws {InvalidAmountError} If amount is invalid\n * @throws {InvalidAssetError} If asset configuration is invalid\n *\n * @example\n * ```typescript\n * const xdr = buildPaymentTransaction({\n * source: 'GDQP2K...',\n * sequence: '123456789',\n * destination: 'GBZX...',\n * amount: '10.5',\n * asset: { code: 'USDC', issuer: 'GA5ZS...' },\n * memo: { type: 'MEMO_TEXT', value: 'Payment for coffee' },\n * network: 'public',\n * });\n * ```\n */\nexport function buildPaymentTransaction(options: BuildPaymentOptions): string {\n const {\n source,\n sequence,\n destination,\n amount,\n asset,\n memo,\n network,\n timeout = 180,\n } = options;\n\n // Validate inputs\n if (!isValidStellarAddress(source)) {\n throw new InvalidAddressError(source);\n }\n\n if (!isValidStellarAddress(destination)) {\n throw new InvalidAddressError(destination);\n }\n\n if (!isValidAmount(amount)) {\n throw new InvalidAmountError(amount);\n }\n\n const networkPassphrase = NETWORK_PASSPHRASES[network];\n\n // Create a minimal account object for TransactionBuilder\n const sourceAccount = new StellarSdk.Account(source, sequence);\n\n // Build transaction\n const builder = new StellarSdk.TransactionBuilder(sourceAccount, {\n fee: StellarSdk.BASE_FEE,\n networkPassphrase,\n });\n\n // Determine asset\n const stellarAsset = asset\n ? createAsset(asset.code, asset.issuer)\n : StellarSdk.Asset.native();\n\n // Add payment operation\n builder.addOperation(\n StellarSdk.Operation.payment({\n destination,\n asset: stellarAsset,\n amount: String(amount),\n })\n );\n\n // Add memo if present\n if (memo) {\n switch (memo.type) {\n case 'MEMO_ID':\n builder.addMemo(StellarSdk.Memo.id(memo.value));\n break;\n case 'MEMO_HASH':\n builder.addMemo(StellarSdk.Memo.hash(memo.value));\n break;\n case 'MEMO_RETURN':\n builder.addMemo(StellarSdk.Memo.return(memo.value));\n break;\n case 'MEMO_TEXT':\n default:\n builder.addMemo(StellarSdk.Memo.text(memo.value));\n break;\n }\n }\n\n // Set timeout and build\n builder.setTimeout(timeout);\n const transaction = builder.build();\n\n return transaction.toXDR();\n}\n","import {\n isConnected,\n isAllowed,\n setAllowed,\n getAddress,\n getNetwork,\n signTransaction,\n} from '@stellar/freighter-api';\nimport * as StellarSdk from '@stellar/stellar-sdk';\nimport { NETWORK_PASSPHRASES, HORIZON_URLS, type Network } from './constants';\nimport { StellarSnapError } from './errors';\n\n/**\n * Result of connecting to Freighter wallet.\n */\nexport interface FreighterConnectionResult {\n /** The user's Stellar public address */\n publicKey: string;\n /** The network the wallet is connected to */\n network: Network;\n}\n\n/**\n * Result of submitting a transaction.\n */\nexport interface TransactionSubmitResult {\n /** The transaction hash (can be used in block explorers) */\n hash: string;\n /** Whether the transaction was successful */\n successful: boolean;\n /** The ledger number the transaction was included in */\n ledger?: number;\n}\n\n/**\n * Checks if Freighter wallet extension is installed and connected.\n *\n * @returns true if Freighter is installed and the user has granted access\n *\n * @example\n * ```typescript\n * if (await isFreighterConnected()) {\n * console.log('Ready to sign transactions!');\n * } else {\n * console.log('Please connect your Freighter wallet');\n * }\n * ```\n */\nexport async function isFreighterConnected(): Promise<boolean> {\n try {\n const connected = await isConnected();\n if (!connected) return false;\n\n const allowedResult = await isAllowed();\n return allowedResult.isAllowed;\n } catch {\n return false;\n }\n}\n\n/**\n * Gets the current network from Freighter wallet.\n *\n * @returns The network the user's wallet is connected to\n * @throws {StellarSnapError} If unable to get network\n *\n * @example\n * ```typescript\n * const network = await getFreighterNetwork();\n * console.log(`Connected to ${network}`); // 'public' or 'testnet'\n * ```\n */\nexport async function getFreighterNetwork(): Promise<Network> {\n try {\n const networkDetails = await getNetwork();\n const passphrase = networkDetails.networkPassphrase;\n\n if (passphrase === NETWORK_PASSPHRASES.public) {\n return 'public';\n } else if (passphrase === NETWORK_PASSPHRASES.testnet) {\n return 'testnet';\n }\n\n // Default to testnet for unknown networks\n return 'testnet';\n } catch (error) {\n throw new StellarSnapError(\n `Failed to get network from Freighter: ${error}`,\n 'FREIGHTER_NETWORK_ERROR'\n );\n }\n}\n\n/**\n * Connects to the Freighter wallet and returns the user's public key and network.\n *\n * This will prompt the user to grant access if they haven't already.\n *\n * @returns The user's public key and current network\n * @throws {StellarSnapError} If Freighter is not installed or connection fails\n *\n * @example\n * ```typescript\n * try {\n * const { publicKey, network } = await connectFreighter();\n * console.log(`Connected: ${publicKey} on ${network}`);\n * } catch (error) {\n * console.error('Failed to connect:', error.message);\n * }\n * ```\n */\nexport async function connectFreighter(): Promise<FreighterConnectionResult> {\n try {\n // Check if Freighter is installed\n const connected = await isConnected();\n if (!connected) {\n throw new StellarSnapError(\n 'Freighter wallet is not installed. Please install it from https://freighter.app',\n 'FREIGHTER_NOT_INSTALLED'\n );\n }\n\n // Request access if not already allowed\n const allowedResult = await isAllowed();\n if (!allowedResult.isAllowed) {\n await setAllowed();\n }\n\n // Get the user's address\n const addressResult = await getAddress();\n if (!addressResult.address) {\n throw new StellarSnapError(\n 'Failed to get address from Freighter',\n 'FREIGHTER_ADDRESS_ERROR'\n );\n }\n\n // Get the network\n const network = await getFreighterNetwork();\n\n return {\n publicKey: addressResult.address,\n network,\n };\n } catch (error) {\n if (error instanceof StellarSnapError) {\n throw error;\n }\n throw new StellarSnapError(\n `Failed to connect to Freighter: ${error}`,\n 'FREIGHTER_CONNECTION_ERROR'\n );\n }\n}\n\n/**\n * Signs a transaction using Freighter wallet.\n *\n * This will open the Freighter popup for the user to review and approve the transaction.\n *\n * @param xdr - The unsigned transaction XDR\n * @param network - The network the transaction is for\n * @returns The signed transaction XDR\n * @throws {StellarSnapError} If signing fails or user rejects\n *\n * @example\n * ```typescript\n * const unsignedXdr = buildPaymentTransaction({ ... });\n * const signedXdr = await signWithFreighter(unsignedXdr, 'public');\n * ```\n */\nexport async function signWithFreighter(\n xdr: string,\n network: Network\n): Promise<string> {\n try {\n const networkPassphrase = NETWORK_PASSPHRASES[network];\n const result = await signTransaction(xdr, {\n networkPassphrase,\n });\n\n if (!result.signedTxXdr) {\n throw new StellarSnapError(\n 'Transaction signing was cancelled or failed',\n 'FREIGHTER_SIGN_CANCELLED'\n );\n }\n\n return result.signedTxXdr;\n } catch (error) {\n if (error instanceof StellarSnapError) {\n throw error;\n }\n throw new StellarSnapError(\n `Failed to sign transaction: ${error}`,\n 'FREIGHTER_SIGN_ERROR'\n );\n }\n}\n\n/**\n * Submits a signed transaction to the Stellar network.\n *\n * @param signedXdr - The signed transaction XDR\n * @param network - The network to submit to\n * @returns The transaction result including hash and success status\n * @throws {StellarSnapError} If submission fails\n *\n * @example\n * ```typescript\n * const signedXdr = await signWithFreighter(unsignedXdr, 'public');\n * const result = await submitTransaction(signedXdr, 'public');\n *\n * if (result.successful) {\n * console.log(`Transaction successful! Hash: ${result.hash}`);\n * console.log(`View on explorer: https://stellar.expert/explorer/public/tx/${result.hash}`);\n * }\n * ```\n */\nexport async function submitTransaction(\n signedXdr: string,\n network: Network\n): Promise<TransactionSubmitResult> {\n try {\n const horizonUrl = HORIZON_URLS[network];\n const server = new StellarSdk.Horizon.Server(horizonUrl);\n const networkPassphrase = NETWORK_PASSPHRASES[network];\n\n // Parse the signed transaction\n const transaction = StellarSdk.TransactionBuilder.fromXDR(\n signedXdr,\n networkPassphrase\n );\n\n // Submit to the network\n const response = await server.submitTransaction(transaction);\n\n return {\n hash: response.hash,\n successful: response.successful,\n ledger: response.ledger,\n };\n } catch (error: unknown) {\n // Handle Horizon error responses\n const horizonError = error as { response?: { data?: { extras?: { result_codes?: unknown } } }; message?: string };\n if (horizonError.response?.data?.extras?.result_codes) {\n const resultCodes = horizonError.response.data.extras.result_codes;\n throw new StellarSnapError(\n `Transaction failed: ${JSON.stringify(resultCodes)}`,\n 'TRANSACTION_FAILED'\n );\n }\n\n throw new StellarSnapError(\n `Failed to submit transaction: ${horizonError.message || error}`,\n 'SUBMIT_ERROR'\n );\n }\n}\n","/**\n * A rule for matching URL paths to API endpoints.\n */\nexport interface DiscoveryRule {\n /**\n * URL path pattern with wildcards.\n * Use `*` as a wildcard that matches any characters.\n *\n * @example \"/s/*\" matches \"/s/abc123\"\n * @example \"/pay/*\" matches \"/pay/user123\"\n */\n pathPattern: string;\n\n /**\n * API endpoint path template.\n * Use `$1`, `$2`, etc. to insert captured wildcards.\n *\n * @example \"/api/snap/$1\" with pathPattern \"/s/*\" and URL \"/s/abc\"\n * resolves to \"/api/snap/abc\"\n */\n apiPath: string;\n}\n\n/**\n * Discovery file structure for Stellar Snaps.\n *\n * This file should be hosted at `/.well-known/stellar-snap.json` on your domain\n * to enable the browser extension to discover and render your snaps.\n */\nexport interface DiscoveryFile {\n /** The name of your application */\n name: string;\n\n /** A short description of your application */\n description?: string;\n\n /** URL to your application's icon (recommended: 128x128 PNG) */\n icon?: string;\n\n /** Rules for matching URLs to snap metadata endpoints */\n rules: DiscoveryRule[];\n}\n\n/**\n * Options for creating a discovery file.\n */\nexport interface CreateDiscoveryFileOptions {\n /** The name of your application */\n name: string;\n /** A short description of your application */\n description?: string;\n /** URL to your application's icon */\n icon?: string;\n /** Rules for matching URLs to snap metadata endpoints */\n rules: DiscoveryRule[];\n}\n\n/**\n * Creates a valid discovery file object.\n *\n * Use this to generate the JSON that should be hosted at\n * `/.well-known/stellar-snap.json` on your domain.\n *\n * @param options - The discovery file configuration\n * @returns A valid DiscoveryFile object\n *\n * @example\n * ```typescript\n * const discovery = createDiscoveryFile({\n * name: 'My Payment App',\n * description: 'Accept Stellar payments easily',\n * rules: [\n * { pathPattern: '/pay/*', apiPath: '/api/snap/$1' },\n * { pathPattern: '/donate/*', apiPath: '/api/donation/$1' },\n * ],\n * });\n *\n * // Save as /.well-known/stellar-snap.json\n * fs.writeFileSync(\n * 'public/.well-known/stellar-snap.json',\n * JSON.stringify(discovery, null, 2)\n * );\n * ```\n */\nexport function createDiscoveryFile(options: CreateDiscoveryFileOptions): DiscoveryFile {\n const { name, description, icon, rules } = options;\n\n if (!name || typeof name !== 'string') {\n throw new Error('Discovery file requires a name');\n }\n\n if (!rules || !Array.isArray(rules) || rules.length === 0) {\n throw new Error('Discovery file requires at least one rule');\n }\n\n // Validate rules\n for (const rule of rules) {\n if (!rule.pathPattern || typeof rule.pathPattern !== 'string') {\n throw new Error('Each rule requires a pathPattern');\n }\n if (!rule.apiPath || typeof rule.apiPath !== 'string') {\n throw new Error('Each rule requires an apiPath');\n }\n }\n\n const discoveryFile: DiscoveryFile = {\n name,\n rules,\n };\n\n if (description) {\n discoveryFile.description = description;\n }\n\n if (icon) {\n discoveryFile.icon = icon;\n }\n\n return discoveryFile;\n}\n\n/**\n * Validates that an unknown object is a valid discovery file.\n *\n * Use this to validate discovery files fetched from other domains.\n *\n * @param file - The object to validate\n * @returns true if the object is a valid DiscoveryFile\n *\n * @example\n * ```typescript\n * const response = await fetch('https://example.com/.well-known/stellar-snap.json');\n * const data = await response.json();\n *\n * if (validateDiscoveryFile(data)) {\n * console.log('Valid discovery file:', data.name);\n * } else {\n * console.error('Invalid discovery file');\n * }\n * ```\n */\nexport function validateDiscoveryFile(file: unknown): file is DiscoveryFile {\n if (!file || typeof file !== 'object') {\n return false;\n }\n\n const obj = file as Record<string, unknown>;\n\n // Check required fields\n if (typeof obj.name !== 'string' || !obj.name) {\n return false;\n }\n\n if (!Array.isArray(obj.rules) || obj.rules.length === 0) {\n return false;\n }\n\n // Validate each rule\n for (const rule of obj.rules) {\n if (!rule || typeof rule !== 'object') {\n return false;\n }\n const ruleObj = rule as Record<string, unknown>;\n if (typeof ruleObj.pathPattern !== 'string' || !ruleObj.pathPattern) {\n return false;\n }\n if (typeof ruleObj.apiPath !== 'string' || !ruleObj.apiPath) {\n return false;\n }\n }\n\n // Optional fields should be correct types if present\n if (obj.description !== undefined && typeof obj.description !== 'string') {\n return false;\n }\n\n if (obj.icon !== undefined && typeof obj.icon !== 'string') {\n return false;\n }\n\n return true;\n}\n\n/**\n * Matches a URL pathname against discovery rules and returns the API path.\n *\n * This is used to find which API endpoint to call for a given URL.\n *\n * @param pathname - The URL pathname to match (e.g., \"/s/abc123\")\n * @param rules - The discovery rules to match against\n * @returns The resolved API path, or null if no match\n *\n * @example\n * ```typescript\n * const rules = [\n * { pathPattern: '/s/*', apiPath: '/api/snap/$1' },\n * { pathPattern: '/pay/*', apiPath: '/api/payment/$1' },\n * ];\n *\n * matchUrlToRule('/s/abc123', rules);\n * // => '/api/snap/abc123'\n *\n * matchUrlToRule('/pay/user456', rules);\n * // => '/api/payment/user456'\n *\n * matchUrlToRule('/unknown/path', rules);\n * // => null\n * ```\n */\nexport function matchUrlToRule(\n pathname: string,\n rules: DiscoveryRule[]\n): string | null {\n for (const rule of rules) {\n // Convert pathPattern to regex\n // \"/s/*\" becomes /^\\/s\\/(.+)$/\n const pattern = rule.pathPattern\n .replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&') // Escape special regex chars\n .replace(/\\\\\\*/g, '(.+)'); // Convert \\* back to capture group\n\n const regex = new RegExp(`^${pattern}$`);\n const match = pathname.match(regex);\n\n if (match) {\n // Replace $1, $2, etc. with captured groups\n let apiPath = rule.apiPath;\n for (let i = 1; i < match.length; i++) {\n const captured = match[i];\n if (captured !== undefined) {\n apiPath = apiPath.replace(`$${i}`, captured);\n }\n }\n return apiPath;\n }\n }\n\n return null;\n}\n","/**\n * URL Resolution Utilities\n *\n * Handles shortened URL detection and resolution for snap links.\n */\n\n/** List of known URL shortener domains */\nexport const SHORTENER_DOMAINS = [\n 't.co',\n 'bit.ly',\n 'goo.gl',\n 'tinyurl.com',\n 'ow.ly',\n 'is.gd',\n 'buff.ly',\n 'adf.ly',\n 'bit.do',\n 'mcaf.ee',\n 'su.pr',\n 'twit.ac',\n 'tiny.cc',\n 'lnkd.in',\n 'db.tt',\n 'qr.ae',\n 'cur.lv',\n 'ity.im',\n 'q.gs',\n 'po.st',\n 'bc.vc',\n 'u.to',\n 'j.mp',\n 'buzurl.com',\n 'cutt.us',\n 'u.bb',\n 'yourls.org',\n 'x.co',\n 'prettylinkpro.com',\n 'viralurl.com',\n 'twitthis.com',\n 'shorturl.at',\n 'rb.gy',\n 'shorturl.com',\n] as const;\n\nexport interface ResolvedUrl {\n /** The final resolved URL after following redirects */\n url: string;\n /** The domain of the resolved URL */\n domain: string;\n /** The original URL before resolution */\n originalUrl: string;\n /** Whether the URL was shortened */\n wasShortened: boolean;\n}\n\n/**\n * Checks if a URL is from a known URL shortener.\n *\n * @example\n * ```typescript\n * isShortenerUrl('https://t.co/abc123'); // true\n * isShortenerUrl('https://stellarsnaps.com/s/abc'); // false\n * ```\n */\nexport function isShortenerUrl(url: string): boolean {\n try {\n const parsed = new URL(url);\n const domain = parsed.hostname.toLowerCase();\n return SHORTENER_DOMAINS.some(\n (shortener) => domain === shortener || domain.endsWith(`.${shortener}`)\n );\n } catch {\n return false;\n }\n}\n\n/**\n * Extracts the domain from a URL.\n *\n * @example\n * ```typescript\n * extractDomain('https://stellarsnaps.com/s/abc123'); // 'stellarsnaps.com'\n * ```\n */\nexport function extractDomain(url: string): string {\n try {\n const parsed = new URL(url);\n return parsed.hostname.toLowerCase();\n } catch {\n return '';\n }\n}\n\n/**\n * Extracts the path from a URL.\n *\n * @example\n * ```typescript\n * extractPath('https://stellarsnaps.com/s/abc123'); // '/s/abc123'\n * ```\n */\nexport function extractPath(url: string): string {\n try {\n const parsed = new URL(url);\n return parsed.pathname;\n } catch {\n return '';\n }\n}\n\n/**\n * Resolves a shortened URL by following redirects.\n * This is a server-side function that requires fetch with redirect following.\n *\n * @example\n * ```typescript\n * const resolved = await resolveUrl('https://t.co/abc123');\n * console.log(resolved.url); // 'https://stellarsnaps.com/s/xyz789'\n * ```\n */\nexport async function resolveUrl(url: string): Promise<ResolvedUrl> {\n const originalUrl = url;\n const wasShortened = isShortenerUrl(url);\n\n if (!wasShortened) {\n return {\n url,\n domain: extractDomain(url),\n originalUrl,\n wasShortened: false,\n };\n }\n\n try {\n // Follow redirects with HEAD request (lighter than GET)\n const response = await fetch(url, {\n method: 'HEAD',\n redirect: 'follow',\n });\n\n const finalUrl = response.url;\n\n return {\n url: finalUrl,\n domain: extractDomain(finalUrl),\n originalUrl,\n wasShortened: true,\n };\n } catch (error) {\n // If resolution fails, return original URL\n return {\n url,\n domain: extractDomain(url),\n originalUrl,\n wasShortened: true,\n };\n }\n}\n\n/**\n * Batch resolve multiple URLs.\n *\n * @example\n * ```typescript\n * const urls = ['https://t.co/a', 'https://bit.ly/b'];\n * const resolved = await resolveUrls(urls);\n * ```\n */\nexport async function resolveUrls(urls: string[]): Promise<ResolvedUrl[]> {\n return Promise.all(urls.map(resolveUrl));\n}\n","/**\n * Domain Registry\n *\n * Manages trusted/verified domains for snap hosting.\n */\n\nexport type DomainStatus = 'verified' | 'unverified' | 'blocked';\n\nexport interface DomainEntry {\n /** The domain name */\n domain: string;\n /** Trust status */\n status: DomainStatus;\n /** Optional display name */\n name?: string;\n /** Optional description */\n description?: string;\n /** When the domain was added */\n addedAt?: string;\n /** When the domain was last verified */\n verifiedAt?: string;\n}\n\nexport interface Registry {\n /** List of all domain entries */\n domains: DomainEntry[];\n /** When the registry was last updated */\n updatedAt: string;\n /** Registry version */\n version: string;\n}\n\n/**\n * Creates a new registry.\n *\n * @example\n * ```typescript\n * const registry = createRegistry([\n * { domain: 'stellarsnaps.com', status: 'verified', name: 'Stellar Snaps' },\n * { domain: 'example.com', status: 'unverified' },\n * ]);\n * ```\n */\nexport function createRegistry(domains: DomainEntry[] = []): Registry {\n return {\n domains,\n updatedAt: new Date().toISOString(),\n version: '1.0.0',\n };\n}\n\n/**\n * Adds a domain to the registry.\n */\nexport function addDomain(registry: Registry, entry: DomainEntry): Registry {\n const existing = registry.domains.findIndex((d) => d.domain === entry.domain);\n\n const newDomains =\n existing >= 0\n ? registry.domains.map((d, i) => (i === existing ? entry : d))\n : [...registry.domains, entry];\n\n return {\n ...registry,\n domains: newDomains,\n updatedAt: new Date().toISOString(),\n };\n}\n\n/**\n * Removes a domain from the registry.\n */\nexport function removeDomain(registry: Registry, domain: string): Registry {\n return {\n ...registry,\n domains: registry.domains.filter((d) => d.domain !== domain),\n updatedAt: new Date().toISOString(),\n };\n}\n\n/**\n * Gets the status of a domain.\n *\n * @example\n * ```typescript\n * const status = getDomainStatus(registry, 'stellarsnaps.com');\n * // { domain: 'stellarsnaps.com', status: 'verified', ... }\n * ```\n */\nexport function getDomainStatus(\n registry: Registry,\n domain: string\n): DomainEntry | null {\n // Normalize domain\n const normalizedDomain = domain.toLowerCase().replace(/^www\\./, '');\n\n // Check exact match\n const entry = registry.domains.find(\n (d) => d.domain.toLowerCase() === normalizedDomain\n );\n\n return entry || null;\n}\n\n/**\n * Checks if a domain is verified.\n */\nexport function isDomainVerified(registry: Registry, domain: string): boolean {\n const entry = getDomainStatus(registry, domain);\n return entry?.status === 'verified';\n}\n\n/**\n * Checks if a domain is blocked.\n */\nexport function isDomainBlocked(registry: Registry, domain: string): boolean {\n const entry = getDomainStatus(registry, domain);\n return entry?.status === 'blocked';\n}\n\n/**\n * Gets all verified domains.\n */\nexport function getVerifiedDomains(registry: Registry): DomainEntry[] {\n return registry.domains.filter((d) => d.status === 'verified');\n}\n\n/**\n * Gets all blocked domains.\n */\nexport function getBlockedDomains(registry: Registry): DomainEntry[] {\n return registry.domains.filter((d) => d.status === 'blocked');\n}\n\n/**\n * Validates a registry object.\n */\nexport function validateRegistry(registry: unknown): registry is Registry {\n if (!registry || typeof registry !== 'object') return false;\n\n const r = registry as Record<string, unknown>;\n\n if (!Array.isArray(r.domains)) return false;\n if (typeof r.updatedAt !== 'string') return false;\n if (typeof r.version !== 'string') return false;\n\n return r.domains.every((d: unknown) => {\n if (!d || typeof d !== 'object') return false;\n const entry = d as Record<string, unknown>;\n return (\n typeof entry.domain === 'string' &&\n ['verified', 'unverified', 'blocked'].includes(entry.status as string)\n );\n });\n}\n","/**\n * Blockchain Explorer Utilities\n *\n * Generate links to Stellar blockchain explorers.\n */\n\nimport type { Network } from './constants';\n\n/** Supported explorer types */\nexport type ExplorerType = 'stellar.expert' | 'stellarchain' | 'horizon';\n\n/** Explorer base URLs */\nexport const EXPLORER_URLS: Record<ExplorerType, Record<Network, string>> = {\n 'stellar.expert': {\n public: 'https://stellar.expert/explorer/public',\n testnet: 'https://stellar.expert/explorer/testnet',\n },\n stellarchain: {\n public: 'https://stellarchain.io',\n testnet: 'https://testnet.stellarchain.io',\n },\n horizon: {\n public: 'https://horizon.stellar.org',\n testnet: 'https://horizon-testnet.stellar.org',\n },\n};\n\n/**\n * Generates a transaction URL for a blockchain explorer.\n *\n * @example\n * ```typescript\n * getTransactionUrl('abc123...', 'testnet');\n * // 'https://stellar.expert/explorer/testnet/tx/abc123...'\n *\n * getTransactionUrl('abc123...', 'public', 'stellarchain');\n * // 'https://stellarchain.io/transactions/abc123...'\n * ```\n */\nexport function getTransactionUrl(\n hash: string,\n network: Network = 'testnet',\n explorer: ExplorerType = 'stellar.expert'\n): string {\n const baseUrl = EXPLORER_URLS[explorer][network];\n\n switch (explorer) {\n case 'stellar.expert':\n return `${baseUrl}/tx/${hash}`;\n case 'stellarchain':\n return `${baseUrl}/transactions/${hash}`;\n case 'horizon':\n return `${baseUrl}/transactions/${hash}`;\n default:\n return `${baseUrl}/tx/${hash}`;\n }\n}\n\n/**\n * Generates an account URL for a blockchain explorer.\n *\n * @example\n * ```typescript\n * getAccountUrl('GABC...', 'testnet');\n * // 'https://stellar.expert/explorer/testnet/account/GABC...'\n * ```\n */\nexport function getAccountUrl(\n address: string,\n network: Network = 'testnet',\n explorer: ExplorerType = 'stellar.expert'\n): string {\n const baseUrl = EXPLORER_URLS[explorer][network];\n\n switch (explorer) {\n case 'stellar.expert':\n return `${baseUrl}/account/${address}`;\n case 'stellarchain':\n return `${baseUrl}/accounts/${address}`;\n case 'horizon':\n return `${baseUrl}/accounts/${address}`;\n default:\n return `${baseUrl}/account/${address}`;\n }\n}\n\n/**\n * Generates an asset URL for a blockchain explorer.\n *\n * @example\n * ```typescript\n * getAssetUrl('USDC', 'GCNY...', 'public');\n * // 'https://stellar.expert/explorer/public/asset/USDC-GCNY...'\n * ```\n */\nexport function getAssetUrl(\n code: string,\n issuer: string,\n network: Network = 'testnet',\n explorer: ExplorerType = 'stellar.expert'\n): string {\n const baseUrl = EXPLORER_URLS[explorer][network];\n\n switch (explorer) {\n case 'stellar.expert':\n return `${baseUrl}/asset/${code}-${issuer}`;\n case 'stellarchain':\n return `${baseUrl}/assets/${code}:${issuer}`;\n case 'horizon':\n return `${baseUrl}/assets?asset_code=${code}&asset_issuer=${issuer}`;\n default:\n return `${baseUrl}/asset/${code}-${issuer}`;\n }\n}\n\n/**\n * Generates an operation URL for a blockchain explorer.\n */\nexport function getOperationUrl(\n operationId: string,\n network: Network = 'testnet',\n explorer: ExplorerType = 'stellar.expert'\n): string {\n const baseUrl = EXPLORER_URLS[explorer][network];\n\n switch (explorer) {\n case 'stellar.expert':\n return `${baseUrl}/op/${operationId}`;\n case 'stellarchain':\n return `${baseUrl}/operations/${operationId}`;\n case 'horizon':\n return `${baseUrl}/operations/${operationId}`;\n default:\n return `${baseUrl}/op/${operationId}`;\n }\n}\n","/**\n * Meta Tag Generation\n *\n * Generate OpenGraph and Twitter meta tags for snap pages.\n */\n\nexport interface SnapMetadata {\n /** Snap title */\n title: string;\n /** Snap description */\n description?: string;\n /** Image URL */\n imageUrl?: string;\n /** Payment amount */\n amount?: string;\n /** Asset code */\n assetCode?: string;\n /** Full snap URL */\n url: string;\n /** Site name */\n siteName?: string;\n}\n\nexport interface MetaTags {\n /** OpenGraph tags */\n og: Record<string, string>;\n /** Twitter card tags */\n twitter: Record<string, string>;\n /** Standard meta tags */\n standard: Record<string, string>;\n}\n\n/**\n * Generates meta tags for a snap page.\n *\n * @example\n * ```typescript\n * const tags = generateMetaTags({\n * title: 'Pay for Coffee',\n * description: 'Send 5 XLM for coffee',\n * amount: '5',\n * assetCode: 'XLM',\n * url: 'https://stellarsnaps.com/s/abc123',\n * });\n *\n * // Use in Next.js metadata:\n * export const metadata = {\n * title: tags.standard.title,\n * openGraph: tags.og,\n * twitter: tags.twitter,\n * };\n * ```\n */\nexport function generateMetaTags(metadata: SnapMetadata): MetaTags {\n const {\n title,\n description,\n imageUrl,\n amount,\n assetCode = 'XLM',\n url,\n siteName = 'Stellar Snaps',\n } = metadata;\n\n // Build description if not provided\n const autoDescription =\n description ||\n (amount\n ? `Pay ${amount} ${assetCode} - ${title}`\n : `Make a payment - ${title}`);\n\n return {\n og: {\n 'og:title': title,\n 'og:description': autoDescription,\n 'og:url': url,\n 'og:site_name': siteName,\n 'og:type': 'website',\n ...(imageUrl && { 'og:image': imageUrl }),\n },\n twitter: {\n 'twitter:card': imageUrl ? 'summary_large_image' : 'summary',\n 'twitter:title': title,\n 'twitter:description': autoDescription,\n ...(imageUrl && { 'twitter:image': imageUrl }),\n },\n standard: {\n title: `${title} | ${siteName}`,\n description: autoDescription,\n },\n };\n}\n\n/**\n * Converts meta tags to HTML string.\n *\n * @example\n * ```typescript\n * const html = metaTagsToHtml(tags);\n * // <meta property=\"og:title\" content=\"Pay for Coffee\" />\n * // <meta property=\"og:description\" content=\"...\" />\n * // ...\n * ```\n */\nexport function metaTagsToHtml(tags: MetaTags): string {\n const lines: string[] = [];\n\n // Standard tags\n if (tags.standard.title) {\n lines.push(`<title>${escapeHtml(tags.standard.title)}</title>`);\n }\n if (tags.standard.description) {\n lines.push(\n `<meta name=\"description\" content=\"${escapeHtml(tags.standard.description)}\" />`\n );\n }\n\n // OpenGraph tags\n for (const [property, content] of Object.entries(tags.og)) {\n lines.push(\n `<meta property=\"${escapeHtml(property)}\" content=\"${escapeHtml(content)}\" />`\n );\n }\n\n // Twitter tags\n for (const [name, content] of Object.entries(tags.twitter)) {\n lines.push(\n `<meta name=\"${escapeHtml(name)}\" content=\"${escapeHtml(content)}\" />`\n );\n }\n\n return lines.join('\\n');\n}\n\n/**\n * Escapes HTML special characters.\n */\nfunction escapeHtml(str: string): string {\n return str\n .replace(/&/g, '&')\n .replace(/</g, '<')\n .replace(/>/g, '>')\n .replace(/\"/g, '"')\n .replace(/'/g, ''');\n}\n\n/**\n * Generates JSON-LD structured data for a snap.\n *\n * @example\n * ```typescript\n * const jsonLd = generateJsonLd({\n * title: 'Pay for Coffee',\n * amount: '5',\n * assetCode: 'XLM',\n * url: 'https://stellarsnaps.com/s/abc123',\n * });\n * ```\n */\nexport function generateJsonLd(metadata: SnapMetadata): object {\n const { title, description, amount, assetCode = 'XLM', url, imageUrl } = metadata;\n\n return {\n '@context': 'https://schema.org',\n '@type': 'PaymentService',\n name: title,\n description: description || `Pay ${amount || 'any amount'} ${assetCode}`,\n url,\n ...(imageUrl && { image: imageUrl }),\n ...(amount && {\n offers: {\n '@type': 'Offer',\n price: amount,\n priceCurrency: assetCode,\n },\n }),\n };\n}\n","/**\n * Server Utilities\n *\n * Helper functions for building Stellar Snaps API endpoints.\n */\n\n/**\n * Standard CORS headers for API responses.\n */\nexport const CORS_HEADERS = {\n 'Access-Control-Allow-Origin': '*',\n 'Access-Control-Allow-Methods': 'GET, POST, PUT, DELETE, OPTIONS',\n 'Access-Control-Allow-Headers': 'Content-Type, Authorization',\n 'Access-Control-Max-Age': '86400',\n} as const;\n\n/**\n * Cache headers for different response types.\n */\nexport const CACHE_HEADERS = {\n /** No caching */\n none: {\n 'Cache-Control': 'no-store, no-cache, must-revalidate',\n },\n /** Short cache (1 minute) */\n short: {\n 'Cache-Control': 'public, max-age=60, stale-while-revalidate=30',\n },\n /** Medium cache (5 minutes) */\n medium: {\n 'Cache-Control': 'public, max-age=300, stale-while-revalidate=60',\n },\n /** Long cache (1 hour) */\n long: {\n 'Cache-Control': 'public, max-age=3600, stale-while-revalidate=300',\n },\n /** Immutable (1 year) */\n immutable: {\n 'Cache-Control': 'public, max-age=31536000, immutable',\n },\n} as const;\n\nexport interface ApiResponse<T = unknown> {\n success: boolean;\n data?: T;\n error?: string;\n code?: string;\n}\n\n/**\n * Creates a success API response.\n */\nexport function successResponse<T>(data: T): ApiResponse<T> {\n return {\n success: true,\n data,\n };\n}\n\n/**\n * Creates an error API response.\n */\nexport function errorResponse(\n message: string,\n code?: string\n): ApiResponse<never> {\n return {\n success: false,\n error: message,\n code,\n };\n}\n\n/**\n * Validates required fields in a request body.\n *\n * @throws Error if required fields are missing\n */\nexport function validateRequired(\n body: Record<string, unknown>,\n fields: string[]\n): void {\n for (const field of fields) {\n if (body[field] === undefined || body[field] === null || body[field] === '') {\n throw new Error(`Missing required field: ${field}`);\n }\n }\n}\n\n/**\n * Extracts query parameters from a URL.\n */\nexport function parseQueryParams(url: string): Record<string, string> {\n try {\n const parsed = new URL(url);\n const params: Record<string, string> = {};\n\n parsed.searchParams.forEach((value, key) => {\n params[key] = value;\n });\n\n return params;\n } catch {\n return {};\n }\n}\n\n/**\n * Builds a URL with query parameters.\n */\nexport function buildUrl(\n base: string,\n params: Record<string, string | undefined>\n): string {\n const url = new URL(base);\n\n for (const [key, value] of Object.entries(params)) {\n if (value !== undefined) {\n url.searchParams.set(key, value);\n }\n }\n\n return url.toString();\n}\n\n/**\n * Rate limiting bucket.\n */\nexport interface RateLimitBucket {\n count: number;\n resetAt: number;\n}\n\n/**\n * Simple in-memory rate limiter.\n *\n * @example\n * ```typescript\n * const limiter = createRateLimiter({ maxRequests: 100, windowMs: 60000 });\n *\n * // In your API handler:\n * if (!limiter.check(clientIp)) {\n * return { error: 'Rate limit exceeded' };\n * }\n * ```\n */\nexport function createRateLimiter(options: {\n maxRequests: number;\n windowMs: number;\n}) {\n const buckets = new Map<string, RateLimitBucket>();\n\n return {\n /**\n * Checks if a key is within rate limits.\n * Returns true if allowed, false if rate limited.\n */\n check(key: string): boolean {\n const now = Date.now();\n const bucket = buckets.get(key);\n\n // Clean up expired bucket\n if (bucket && bucket.resetAt <= now) {\n buckets.delete(key);\n }\n\n const current = buckets.get(key);\n\n if (!current) {\n buckets.set(key, {\n count: 1,\n resetAt: now + options.windowMs,\n });\n return true;\n }\n\n if (current.count >= options.maxRequests) {\n return false;\n }\n\n current.count++;\n return true;\n },\n\n /**\n * Gets remaining requests for a key.\n */\n remaining(key: string): number {\n const bucket = buckets.get(key);\n if (!bucket || bucket.resetAt <= Date.now()) {\n return options.maxRequests;\n }\n return Math.max(0, options.maxRequests - bucket.count);\n },\n\n /**\n * Resets the limiter for a key.\n */\n reset(key: string): void {\n buckets.delete(key);\n },\n\n /**\n * Clears all rate limit data.\n */\n clear(): void {\n buckets.clear();\n },\n };\n}\n\n/**\n * Parses a Stellar address from various formats.\n * Handles federation addresses, muxed accounts, etc.\n */\nexport function parseAddress(input: string): {\n address: string;\n muxedId?: string;\n federation?: string;\n} {\n const trimmed = input.trim();\n\n // Federation address (user*domain.com)\n if (trimmed.includes('*')) {\n return {\n address: trimmed,\n federation: trimmed,\n };\n }\n\n // Muxed account (M...)\n if (trimmed.startsWith('M') && trimmed.length === 69) {\n return {\n address: trimmed,\n muxedId: trimmed,\n };\n }\n\n // Standard G address\n if (trimmed.startsWith('G') && trimmed.length === 56) {\n return {\n address: trimmed,\n };\n }\n\n throw new Error('Invalid address format');\n}\n"]}
|