-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathDEPOSIT_API_CONTRACT.ts
More file actions
272 lines (220 loc) · 7.79 KB
/
Copy pathDEPOSIT_API_CONTRACT.ts
File metadata and controls
272 lines (220 loc) · 7.79 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
/**
* ✅ ShadowPay Deposit API Integration Test
*
* This file documents the correct API contract for deposits
* after removing all mocking and using Privacy Cash SDK
*/
// ============================================================================
// DEPOSIT REQUEST FORMAT (Frontend → Backend)
// ============================================================================
interface DepositRequest {
// Unique identifier for the payment link
linkId: string
// Transaction signature from Privacy Cash SDK
// This is the output of client.deposit({ lamports })
signedTransaction: string
// Amount in SOL (as string or number)
amount: string | number
// User's Solana public key
publicKey: string
// Optional: Referrer address for affiliate tracking
referrer?: string
}
// Example request:
const exampleRequest: DepositRequest = {
linkId: 'link-abc123',
signedTransaction: '4v3nG9Wo9Zw1qL2eR3tY4uI5oP6aS7dF8gH9jK0lM1nO2pQ3rS4tU5vW6xY7z8A9b',
amount: '1.5',
publicKey: '4zMMUHtBVexwNYkwWfrtXCVjYcUp8JRUt3V7wmbThdpm',
referrer: '9P8L7K6J5H4G3F2E1D0C9B8A7Z6Y5X4W3V2U1T0S9R8Q7P6O5N4M3L2K1J0I'
}
// ============================================================================
// DEPOSIT RESPONSE FORMAT (Backend → Frontend)
// ============================================================================
interface DepositResponse {
// Success flag
success: boolean
// Transaction signature from relayer
tx: string
transactionHash: string
// Amount that was deposited
amount: string | number
// User-friendly message
message: string
// Status: 'relayed' (submitted to Privacy Cash relayer)
status: 'relayed'
// Details about the transaction
details: {
// Whether transaction is encrypted
encrypted: boolean
// Whether ZK proof was generated
zkProof: boolean
// Whether relayer has submitted the transaction
relayerSubmitted: boolean
// Description for user
description: string
}
}
// Example response:
const exampleResponse: DepositResponse = {
success: true,
tx: '5jK3mL9oP2qR4sT7uV0wX1yZ3aB5cD7eF9gH1iJ3kL5mN7oP9qR1sT3uV5wX7y9zA1',
transactionHash: '5jK3mL9oP2qR4sT7uV0wX1yZ3aB5cD7eF9gH1iJ3kL5mN7oP9qR1sT3uV5wX7y9zA1',
amount: '1.5',
message: 'Deposit successful. Transaction relayed to Privacy Cash pool.',
status: 'relayed',
details: {
encrypted: true,
zkProof: true,
relayerSubmitted: true,
description: 'Your transaction is encrypted and submitted via Privacy Cash relayer.'
}
}
// ============================================================================
// ERROR RESPONSE FORMAT
// ============================================================================
interface DepositErrorResponse {
error: string
details?: string
}
// Example error responses:
const errorMissingField: DepositErrorResponse = {
error: 'signedTransaction required',
details: 'Frontend must sign transaction with Privacy Cash SDK before sending to backend'
}
const errorRelayFailed: DepositErrorResponse = {
error: 'Failed to relay to Privacy Cash',
details: 'Privacy Cash relayer error (502): Service unavailable'
}
const errorInvalidKey: DepositErrorResponse = {
error: 'Invalid publicKey format'
}
// ============================================================================
// FRONTEND INTEGRATION EXAMPLE
// ============================================================================
/*
// Step 1: Import Privacy Cash SDK client
import { PrivacyCashService } from '../services/privacyCashService'
// Step 2: Initialize client
const client = PrivacyCashService.getClient()
// Step 3: Call SDK deposit function
const sdkResponse = await client.deposit({
lamports: Math.round(1.5 * 1e9)
})
// Step 4: Extract signed transaction
const signedTransaction = sdkResponse.tx
// Step 5: Send to backend
const depositRequest: DepositRequest = {
linkId: 'user-generated-link-id',
signedTransaction,
amount: '1.5',
publicKey: wallet.publicKey.toString()
}
const response = await fetch('/api/deposit', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(depositRequest)
})
const data: DepositResponse = await response.json()
console.log('Transaction signature:', data.transactionHash)
*/
// ============================================================================
// BACKEND FLOW
// ============================================================================
/*
POST /api/deposit
├─ 1. Validate request format
│ ├─ linkId: required string
│ ├─ signedTransaction: required string (from Privacy Cash SDK)
│ ├─ amount: required number/string
│ ├─ publicKey: required valid Solana address
│ └─ referrer: optional referrer address
│
├─ 2. Find payment link in database
│ └─ Verify link exists and hasn't already been deposited
│
├─ 3. Relay to Privacy Cash relayer
│ ├─ URL: ${PRIVACY_CASH_RELAYER_URL}/deposit
│ ├─ Method: POST
│ ├─ Body: { signedTransaction, senderAddress, referralWalletAddress }
│ └─ Extract transaction signature from response
│
├─ 4. Update database
│ ├─ Update payment link with transaction hash
│ ├─ Create transaction record
│ └─ Store amount and asset type
│
└─ 5. Return response to frontend
└─ Include transaction hash and status
Error Handling:
- Missing fields → 400 Bad Request
- Link not found → 404 Not Found
- Already deposited → 400 Bad Request
- Relayer error → 502 Bad Gateway
- Other errors → 500 Internal Server Error
*/
// ============================================================================
// ENVIRONMENT VARIABLES
// ============================================================================
/*
Backend:
PRIVACY_CASH_RELAYER_URL=https://relayer.privacycash.org
ALLOW_MOCK_DEPOSITS=false // Set to 'true' only for development testing
Frontend:
VITE_BACKEND_URL=http://localhost:3000
(or production backend URL)
NO LONGER NEEDED:
- PRIVACY_CASH_API_KEY (removed)
- PRIVACY_CASH_API_URL (removed)
- Any direct API authentication
*/
// ============================================================================
// WHAT HAPPENS IN THE PRIVACY CASH SDK
// ============================================================================
/*
When client.deposit({ lamports }) is called:
1. Generate ZK Proof
- Proves knowledge of secret without revealing it
- Proves correct amount and encryption
2. Create Encrypted UTXOs
- Split amount into multiple UTXOs if needed
- Encrypt UTXOs with user's encryption key
- UTXO data visible only to user with correct key
3. Create Transaction
- Transaction data: encrypted UTXOs + ZK proof
- Metadata: sender, amount, timestamp
4. Sign Transaction
- User's wallet signs the transaction
- Signature proves authorization to spend
5. Return Result
- Returns: { tx: signature, ... }
- 'tx' is the signed transaction ready to relay
This is why the frontend can send 'signedTransaction' to the backend:
- It's not a Solana transaction
- It's a Privacy Cash-specific signed data structure
- The relayer knows how to process it
- The relayer submits the actual Solana transaction
*/
// ============================================================================
// REMOVED PATTERNS (DO NOT USE)
// ============================================================================
/*
❌ OLD: Sending raw UTXO objects
{
"linkId": "...",
"utxo": { "amount": ..., "blinding": ..., "pubkey": ... },
"signature": [...],
"amount": "1.5",
"publicKey": "..."
}
❌ OLD: Backend trying to create encrypted UTXOs
- No longer do this!
- Privacy Cash SDK already did it
❌ OLD: Using PRIVACY_CASH_API directly
- No longer needed!
- Use relayer endpoint instead
❌ OLD: Mock deposit logic
- All removed!
- Only exception: ALLOW_MOCK_DEPOSITS=true for development
*/
export {}