+
Your white paper is attached.
+
+ Thanks for requesting the ZeroAuth white paper. The PDF is attached to this
+ message — 36 pages covering the cryptographic construction, the security
+ reductions, the on-chain anchoring model, and the recommended deployment
+ topology.
+
+
+ The underlying protocol is Pramaan (Indian Patent IN202311041001),
+ the zero-knowledge biometric identity scheme that powers ZeroAuth.
+
+
+ If you have questions after reading, reply to this email or open an issue
+ at github.com/zeroauth-dev/ZeroAuth/issues.
+
+
+ Useful next steps:
+
+
+ ${FOOTER_HTML}
+
+ `;
+
+ const text = `Your white paper is attached.
+
+Thanks for requesting the ZeroAuth white paper. The PDF is attached to this
+message — 36 pages covering the cryptographic construction, the security
+reductions, the on-chain anchoring model, and the recommended deployment
+topology.
+
+The underlying protocol is Pramaan (Indian Patent IN202311041001), the
+zero-knowledge biometric identity scheme that powers ZeroAuth.
+
+If you have questions after reading, reply to this email or open an issue at
+https://github.com/zeroauth-dev/ZeroAuth/issues
+
+Useful next steps:
+- Read the Quickstart: https://zeroauth.dev/docs/getting-started/quickstart/
+- Browse the API reference: https://zeroauth.dev/docs/reference/api-reference
+- Self-host the reference implementation: https://github.com/zeroauth-dev/ZeroAuth
+${FOOTER_TEXT}`;
+
+ return { subject, html, text };
+}
+
/**
* Minimal HTML escape for user-supplied strings landing in templates.
* Don't use a full library for this — the surface is tiny (operator email
diff --git a/src/services/email.ts b/src/services/email.ts
index 8c780df..1e3d63b 100644
--- a/src/services/email.ts
+++ b/src/services/email.ts
@@ -41,6 +41,17 @@ function getTransporter(): Transporter | null {
return transporter;
}
+export interface SendMailAttachment {
+ /** File name as the recipient will see it. */
+ filename: string;
+ /** Absolute path on disk, OR provide `content` instead. */
+ path?: string;
+ /** Raw bytes / string if path is unavailable. */
+ content?: Buffer | string;
+ /** MIME type. Inferred when possible; pass explicitly for non-obvious files. */
+ contentType?: string;
+}
+
export interface SendMailInput {
to: string;
subject: string;
@@ -49,6 +60,8 @@ export interface SendMailInput {
text: string;
/** Optional Reply-To override. Defaults to EMAIL_FROM. */
replyTo?: string;
+ /** Optional file attachments — used for whitepaper delivery, audit-pack exports, etc. */
+ attachments?: SendMailAttachment[];
}
export interface SendMailResult {
@@ -86,6 +99,7 @@ export async function sendMail(input: SendMailInput): Promise