@sip-protocol/sdk 0.3.2 → 0.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (64) hide show
  1. package/dist/browser.d.mts +2 -2
  2. package/dist/browser.d.ts +2 -2
  3. package/dist/browser.js +2881 -295
  4. package/dist/browser.mjs +62 -2
  5. package/dist/chunk-AOZIY3GU.mjs +12995 -0
  6. package/dist/chunk-BCLIX5T2.mjs +12940 -0
  7. package/dist/chunk-DMHBKRWV.mjs +14712 -0
  8. package/dist/chunk-FKXPHKYD.mjs +12955 -0
  9. package/dist/chunk-HGU6HZRC.mjs +231 -0
  10. package/dist/chunk-J4Q4NJ2U.mjs +13544 -0
  11. package/dist/chunk-OPQ2GQIO.mjs +13013 -0
  12. package/dist/chunk-W2B7T6WU.mjs +14714 -0
  13. package/dist/index-5jAdWMA-.d.ts +8973 -0
  14. package/dist/index-B9Vkpaao.d.mts +8973 -0
  15. package/dist/index-BcWNakUD.d.ts +7990 -0
  16. package/dist/index-BsKY3Hr0.d.mts +7990 -0
  17. package/dist/index.d.mts +2 -2
  18. package/dist/index.d.ts +2 -2
  19. package/dist/index.js +2852 -266
  20. package/dist/index.mjs +62 -2
  21. package/dist/proofs/noir.mjs +1 -1
  22. package/package.json +2 -1
  23. package/src/adapters/near-intents.ts +8 -0
  24. package/src/bitcoin/index.ts +51 -0
  25. package/src/bitcoin/silent-payments.ts +865 -0
  26. package/src/bitcoin/taproot.ts +590 -0
  27. package/src/compliance/compliance-manager.ts +87 -0
  28. package/src/compliance/conditional-threshold.ts +379 -0
  29. package/src/compliance/conditional.ts +382 -0
  30. package/src/compliance/derivation.ts +489 -0
  31. package/src/compliance/index.ts +50 -8
  32. package/src/compliance/pdf.ts +365 -0
  33. package/src/compliance/reports.ts +644 -0
  34. package/src/compliance/threshold.ts +529 -0
  35. package/src/compliance/types.ts +223 -0
  36. package/src/cosmos/ibc-stealth.ts +825 -0
  37. package/src/cosmos/index.ts +83 -0
  38. package/src/cosmos/stealth.ts +487 -0
  39. package/src/errors.ts +8 -0
  40. package/src/index.ts +80 -1
  41. package/src/move/aptos.ts +369 -0
  42. package/src/move/index.ts +35 -0
  43. package/src/move/sui.ts +367 -0
  44. package/src/oracle/types.ts +8 -0
  45. package/src/settlement/backends/direct-chain.ts +8 -0
  46. package/src/stealth.ts +3 -3
  47. package/src/validation.ts +42 -1
  48. package/src/wallet/aptos/adapter.ts +422 -0
  49. package/src/wallet/aptos/index.ts +10 -0
  50. package/src/wallet/aptos/mock.ts +410 -0
  51. package/src/wallet/aptos/types.ts +278 -0
  52. package/src/wallet/bitcoin/adapter.ts +470 -0
  53. package/src/wallet/bitcoin/index.ts +38 -0
  54. package/src/wallet/bitcoin/mock.ts +516 -0
  55. package/src/wallet/bitcoin/types.ts +274 -0
  56. package/src/wallet/cosmos/adapter.ts +484 -0
  57. package/src/wallet/cosmos/index.ts +63 -0
  58. package/src/wallet/cosmos/mock.ts +596 -0
  59. package/src/wallet/cosmos/types.ts +462 -0
  60. package/src/wallet/index.ts +127 -0
  61. package/src/wallet/sui/adapter.ts +471 -0
  62. package/src/wallet/sui/index.ts +10 -0
  63. package/src/wallet/sui/mock.ts +439 -0
  64. package/src/wallet/sui/types.ts +245 -0
@@ -0,0 +1,365 @@
1
+ /**
2
+ * PDF Export Utilities
3
+ *
4
+ * Lightweight PDF generation for audit reports without external dependencies.
5
+ * Generates PDF 1.4 format documents with professional formatting.
6
+ */
7
+
8
+ import type { AuditReport, PdfExportOptions } from './types'
9
+
10
+ /**
11
+ * Generate a PDF document from an audit report
12
+ *
13
+ * Creates a professionally formatted PDF report with:
14
+ * - Header with report metadata
15
+ * - Summary statistics
16
+ * - Optional transaction details table
17
+ * - Footer with generation timestamp
18
+ *
19
+ * This implementation uses PDF 1.4 format and works in both Node.js and browsers.
20
+ *
21
+ * @param report - The audit report to export
22
+ * @param options - PDF export options
23
+ * @returns PDF document as Uint8Array
24
+ *
25
+ * @example
26
+ * ```typescript
27
+ * const report = await reporter.generateAuditReport({...})
28
+ * const pdfBytes = generatePdfReport(report, {
29
+ * title: 'Q1 2025 Audit Report',
30
+ * organization: 'ACME Corp',
31
+ * })
32
+ *
33
+ * // Save to file (Node.js)
34
+ * fs.writeFileSync('audit-report.pdf', pdfBytes)
35
+ *
36
+ * // Download in browser
37
+ * const blob = new Blob([pdfBytes], { type: 'application/pdf' })
38
+ * const url = URL.createObjectURL(blob)
39
+ * const a = document.createElement('a')
40
+ * a.href = url
41
+ * a.download = 'audit-report.pdf'
42
+ * a.click()
43
+ * ```
44
+ */
45
+ export function generatePdfReport(
46
+ report: AuditReport,
47
+ options: PdfExportOptions = {}
48
+ ): Uint8Array {
49
+ const {
50
+ title = 'SIP Protocol Audit Report',
51
+ organization = '',
52
+ includeTransactions = true,
53
+ maxTransactions = 100,
54
+ } = options
55
+
56
+ // Build PDF content
57
+ const content = buildPdfContent(report, {
58
+ title,
59
+ organization,
60
+ includeTransactions,
61
+ maxTransactions,
62
+ })
63
+
64
+ // Generate PDF binary
65
+ return generatePdfBinary(content, title)
66
+ }
67
+
68
+ /**
69
+ * Build PDF content structure
70
+ */
71
+ function buildPdfContent(
72
+ report: AuditReport,
73
+ options: Required<PdfExportOptions>
74
+ ): string {
75
+ const lines: string[] = []
76
+
77
+ // Header
78
+ lines.push(options.title)
79
+ if (options.organization && options.organization.trim() !== '') {
80
+ lines.push(`Organization: ${options.organization}`)
81
+ }
82
+ lines.push(`Report ID: ${report.reportId}`)
83
+ lines.push(
84
+ `Generated: ${report.generatedAt.toISOString().replace('T', ' ').slice(0, 19)} UTC`
85
+ )
86
+ lines.push('')
87
+
88
+ // Period
89
+ lines.push('Report Period')
90
+ lines.push(` Start: ${formatDate(report.period.start)}`)
91
+ lines.push(` End: ${formatDate(report.period.end)}`)
92
+ lines.push('')
93
+
94
+ // Summary Statistics
95
+ lines.push('Summary Statistics')
96
+ lines.push(` Total Transactions: ${report.summary.transactionCount}`)
97
+ lines.push(
98
+ ` Total Volume: ${formatBigInt(report.summary.totalVolume)}`
99
+ )
100
+ lines.push(
101
+ ` Unique Counterparties: ${report.summary.uniqueCounterparties}`
102
+ )
103
+ lines.push('')
104
+
105
+ // Transaction Details
106
+ if (options.includeTransactions && report.transactions.length > 0) {
107
+ lines.push('Transaction Details')
108
+ lines.push('')
109
+
110
+ const txToShow = Math.min(
111
+ report.transactions.length,
112
+ options.maxTransactions
113
+ )
114
+
115
+ for (let i = 0; i < txToShow; i++) {
116
+ const tx = report.transactions[i]
117
+ lines.push(`Transaction ${i + 1}/${report.transactions.length}`)
118
+ lines.push(` ID: ${tx.id}`)
119
+ lines.push(` Sender: ${truncateAddress(tx.sender)}`)
120
+ lines.push(` Recipient: ${truncateAddress(tx.recipient)}`)
121
+ lines.push(` Amount: ${formatAmount(tx.amount)}`)
122
+ lines.push(
123
+ ` Timestamp: ${formatTimestamp(tx.timestamp)}`
124
+ )
125
+
126
+ if (tx.txHash) {
127
+ lines.push(` Tx Hash: ${truncateHash(tx.txHash)}`)
128
+ }
129
+
130
+ if (tx.metadata && Object.keys(tx.metadata).length > 0) {
131
+ lines.push(` Metadata: ${JSON.stringify(tx.metadata)}`)
132
+ }
133
+
134
+ lines.push('')
135
+ }
136
+
137
+ if (report.transactions.length > options.maxTransactions) {
138
+ lines.push(
139
+ `... and ${report.transactions.length - options.maxTransactions} more transactions`
140
+ )
141
+ lines.push('')
142
+ }
143
+ }
144
+
145
+ // Footer
146
+ lines.push('---')
147
+ lines.push(
148
+ 'This report was generated by SIP Protocol compliance tools.'
149
+ )
150
+ lines.push('For verification, please contact your compliance officer.')
151
+
152
+ return lines.join('\n')
153
+ }
154
+
155
+ /**
156
+ * Generate PDF binary from text content
157
+ *
158
+ * Creates a minimal but valid PDF 1.4 document.
159
+ * Uses Courier font for consistent monospace rendering.
160
+ */
161
+ function generatePdfBinary(content: string, title: string): Uint8Array {
162
+ // PDF object catalog
163
+ const objects: string[] = []
164
+
165
+ // Object 1: Catalog
166
+ objects.push(
167
+ '1 0 obj\n<< /Type /Catalog /Pages 2 0 R >>\nendobj'
168
+ )
169
+
170
+ // Object 2: Pages
171
+ objects.push(
172
+ '2 0 obj\n<< /Type /Pages /Kids [3 0 R] /Count 1 >>\nendobj'
173
+ )
174
+
175
+ // Object 3: Page
176
+ objects.push(
177
+ '3 0 obj\n<< /Type /Page /Parent 2 0 R /Resources 4 0 R /MediaBox [0 0 612 792] /Contents 5 0 R >>\nendobj'
178
+ )
179
+
180
+ // Object 4: Resources
181
+ objects.push(
182
+ '4 0 obj\n<< /Font << /F1 << /Type /Font /Subtype /Type1 /BaseFont /Courier >> >> >>\nendobj'
183
+ )
184
+
185
+ // Object 5: Content stream
186
+ const contentStream = buildContentStream(content)
187
+ objects.push(
188
+ `5 0 obj\n<< /Length ${contentStream.length} >>\nstream\n${contentStream}\nendstream\nendobj`
189
+ )
190
+
191
+ // Object 6: Info
192
+ const now = new Date()
193
+ const pdfDate = formatPdfDate(now)
194
+ objects.push(
195
+ `6 0 obj\n<< /Title (${title}) /Author (SIP Protocol) /Creator (SIP SDK) /CreationDate (${pdfDate}) >>\nendobj`
196
+ )
197
+
198
+ // Build PDF structure
199
+ const pdfParts: string[] = []
200
+
201
+ // Header
202
+ pdfParts.push('%PDF-1.4\n%\xE2\xE3\xCF\xD3\n')
203
+
204
+ // Objects
205
+ const xrefOffsets: number[] = [0] // Offset 0 for object 0 (null)
206
+ let currentOffset = pdfParts.join('').length
207
+
208
+ for (const obj of objects) {
209
+ xrefOffsets.push(currentOffset)
210
+ pdfParts.push(obj + '\n')
211
+ currentOffset = pdfParts.join('').length
212
+ }
213
+
214
+ // Cross-reference table
215
+ const xrefStart = currentOffset
216
+ pdfParts.push('xref\n')
217
+ pdfParts.push(`0 ${xrefOffsets.length}\n`)
218
+
219
+ for (let i = 0; i < xrefOffsets.length; i++) {
220
+ if (i === 0) {
221
+ pdfParts.push('0000000000 65535 f \n')
222
+ } else {
223
+ const offset = String(xrefOffsets[i]).padStart(10, '0')
224
+ pdfParts.push(`${offset} 00000 n \n`)
225
+ }
226
+ }
227
+
228
+ // Trailer
229
+ pdfParts.push('trailer\n')
230
+ pdfParts.push(
231
+ `<< /Size ${xrefOffsets.length} /Root 1 0 R /Info 6 0 R >>\n`
232
+ )
233
+ pdfParts.push('startxref\n')
234
+ pdfParts.push(`${xrefStart}\n`)
235
+ pdfParts.push('%%EOF')
236
+
237
+ // Convert to Uint8Array
238
+ const pdfString = pdfParts.join('')
239
+ const encoder = new TextEncoder()
240
+ return encoder.encode(pdfString)
241
+ }
242
+
243
+ /**
244
+ * Build PDF content stream with text positioning
245
+ */
246
+ function buildContentStream(text: string): string {
247
+ const lines = text.split('\n')
248
+ const commands: string[] = []
249
+
250
+ // Begin text
251
+ commands.push('BT')
252
+
253
+ // Set font and size
254
+ commands.push('/F1 10 Tf')
255
+
256
+ // Set leading (line height)
257
+ commands.push('12 TL')
258
+
259
+ // Start position (left margin: 50, top margin: 50 from bottom)
260
+ let y = 742 // Start from top (792 - 50)
261
+
262
+ for (const line of lines) {
263
+ // Move to position
264
+ commands.push(`50 ${y} Td`)
265
+
266
+ // Escape special characters in line
267
+ const escaped = escapePdfString(line)
268
+
269
+ // Show text
270
+ commands.push(`(${escaped}) Tj`)
271
+
272
+ // Move to next line
273
+ y -= 12
274
+
275
+ // Add new page if needed (simplified - just truncate for now)
276
+ if (y < 50) {
277
+ break
278
+ }
279
+ }
280
+
281
+ // End text
282
+ commands.push('ET')
283
+
284
+ return commands.join('\n')
285
+ }
286
+
287
+ /**
288
+ * Escape special characters for PDF strings
289
+ */
290
+ function escapePdfString(str: string): string {
291
+ return str
292
+ .replace(/\\/g, '\\\\')
293
+ .replace(/\(/g, '\\(')
294
+ .replace(/\)/g, '\\)')
295
+ .replace(/\r/g, '\\r')
296
+ .replace(/\n/g, '\\n')
297
+ }
298
+
299
+ /**
300
+ * Format date for PDF metadata (D:YYYYMMDDHHmmSS)
301
+ */
302
+ function formatPdfDate(date: Date): string {
303
+ const year = date.getUTCFullYear()
304
+ const month = String(date.getUTCMonth() + 1).padStart(2, '0')
305
+ const day = String(date.getUTCDate()).padStart(2, '0')
306
+ const hour = String(date.getUTCHours()).padStart(2, '0')
307
+ const minute = String(date.getUTCMinutes()).padStart(2, '0')
308
+ const second = String(date.getUTCSeconds()).padStart(2, '0')
309
+
310
+ return `D:${year}${month}${day}${hour}${minute}${second}Z`
311
+ }
312
+
313
+ /**
314
+ * Format date for display (YYYY-MM-DD)
315
+ */
316
+ function formatDate(date: Date): string {
317
+ return date.toISOString().split('T')[0]
318
+ }
319
+
320
+ /**
321
+ * Format bigint for display with thousands separator
322
+ */
323
+ function formatBigInt(value: bigint): string {
324
+ return value.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ',')
325
+ }
326
+
327
+ /**
328
+ * Format amount string with thousands separator
329
+ */
330
+ function formatAmount(amount: string): string {
331
+ try {
332
+ const num = BigInt(amount)
333
+ return formatBigInt(num)
334
+ } catch {
335
+ return amount
336
+ }
337
+ }
338
+
339
+ /**
340
+ * Format Unix timestamp to readable date
341
+ */
342
+ function formatTimestamp(timestamp: number): string {
343
+ const date = new Date(timestamp * 1000)
344
+ return date.toISOString().replace('T', ' ').slice(0, 19) + ' UTC'
345
+ }
346
+
347
+ /**
348
+ * Truncate address for display (0x1234...5678)
349
+ */
350
+ function truncateAddress(address: string): string {
351
+ if (address.length <= 12) {
352
+ return address
353
+ }
354
+ return `${address.slice(0, 6)}...${address.slice(-4)}`
355
+ }
356
+
357
+ /**
358
+ * Truncate hash for display
359
+ */
360
+ function truncateHash(hash: string): string {
361
+ if (hash.length <= 16) {
362
+ return hash
363
+ }
364
+ return `${hash.slice(0, 8)}...${hash.slice(-8)}`
365
+ }