@@ -43,7 +43,7 @@ mod tests {
4343 & creator,
4444 & Vec :: from_array ( & env, [ recipient] ) ,
4545 & Vec :: from_array ( & env, [ 1000i128 ] ) ,
46- & token,
46+ & Vec :: from_array ( & env , [ token] ) ,
4747 & deadline,
4848 & default_options ( & env) ,
4949 ) ;
@@ -65,7 +65,7 @@ mod tests {
6565 let params = CreateInvoiceParams {
6666 recipients : Vec :: from_array ( & env, [ recipient. clone ( ) ] ) ,
6767 amounts : Vec :: from_array ( & env, [ 500i128 ] ) ,
68- token : token. clone ( ) ,
68+ tokens : Vec :: from_array ( & env , [ token. clone ( ) ] ) ,
6969 deadline,
7070 } ;
7171 let batch = Vec :: from_array ( & env, [ params. clone ( ) , params] ) ;
@@ -86,7 +86,7 @@ mod tests {
8686 & creator,
8787 & Vec :: from_array ( & env, [ recipient] ) ,
8888 & Vec :: from_array ( & env, [ 1000i128 ] ) ,
89- & token,
89+ & Vec :: from_array ( & env , [ token] ) ,
9090 & deadline,
9191 & default_options ( & env) ,
9292 ) ;
@@ -109,9 +109,11 @@ mod tests {
109109 let deadline = env. ledger ( ) . timestamp ( ) + 86400 ;
110110
111111 let id1 = client. create_invoice ( & creator, & Vec :: from_array ( & env, [ recipient. clone ( ) ] ) ,
112- & Vec :: from_array ( & env, [ 100i128 ] ) , & token, & deadline, & default_options ( & env) ) ;
112+ & Vec :: from_array ( & env, [ 100i128 ] ) , & Vec :: from_array ( & env, [ token. clone ( ) ] ) ,
113+ & deadline, & default_options ( & env) ) ;
113114 let id2 = client. create_invoice ( & creator, & Vec :: from_array ( & env, [ recipient] ) ,
114- & Vec :: from_array ( & env, [ 100i128 ] ) , & token, & deadline, & default_options ( & env) ) ;
115+ & Vec :: from_array ( & env, [ 100i128 ] ) , & Vec :: from_array ( & env, [ token] ) ,
116+ & deadline, & default_options ( & env) ) ;
115117
116118 assert_eq ! ( id2, id1 + 1 ) ;
117119 }
@@ -125,7 +127,8 @@ mod tests {
125127 let deadline = env. ledger ( ) . timestamp ( ) + 86400 ;
126128
127129 let id = client. create_invoice ( & creator, & Vec :: from_array ( & env, [ recipient. clone ( ) ] ) ,
128- & Vec :: from_array ( & env, [ 750i128 ] ) , & token, & deadline, & default_options ( & env) ) ;
130+ & Vec :: from_array ( & env, [ 750i128 ] ) , & Vec :: from_array ( & env, [ token] ) ,
131+ & deadline, & default_options ( & env) ) ;
129132
130133 let invoice = client. get_invoice ( & id) ;
131134 assert_eq ! ( invoice. creator, creator) ;
@@ -144,14 +147,13 @@ mod tests {
144147 let params = CreateInvoiceParams {
145148 recipients : Vec :: from_array ( & env, [ recipient] ) ,
146149 amounts : Vec :: from_array ( & env, [ 100i128 ] ) ,
147- token,
150+ tokens : Vec :: from_array ( & env , [ token] ) ,
148151 deadline,
149152 } ;
150153 let batch = Vec :: from_array ( & env, [ params. clone ( ) , params. clone ( ) , params] ) ;
151154 let ids = client. create_batch ( & creator, & batch) ;
152155
153156 assert_eq ! ( ids. len( ) , 3 ) ;
154- // IDs should be sequential
155157 let id0 = ids. get ( 0 ) . unwrap ( ) ;
156158 let id1 = ids. get ( 1 ) . unwrap ( ) ;
157159 let id2 = ids. get ( 2 ) . unwrap ( ) ;
@@ -168,7 +170,8 @@ mod tests {
168170 let deadline = env. ledger ( ) . timestamp ( ) + 86400 ;
169171
170172 let id = client. create_invoice ( & creator, & Vec :: from_array ( & env, [ recipient] ) ,
171- & Vec :: from_array ( & env, [ 500i128 ] ) , & token, & deadline, & default_options ( & env) ) ;
173+ & Vec :: from_array ( & env, [ 500i128 ] ) , & Vec :: from_array ( & env, [ token] ) ,
174+ & deadline, & default_options ( & env) ) ;
172175
173176 client. cancel_invoice ( & creator, & id) ;
174177 let log = client. get_audit_log ( & id) ;
@@ -184,12 +187,11 @@ mod tests {
184187 let deadline = env. ledger ( ) . timestamp ( ) + 86400 ;
185188
186189 let id = client. create_invoice ( & creator, & Vec :: from_array ( & env, [ recipient] ) ,
187- & Vec :: from_array ( & env, [ 500i128 ] ) , & token, & deadline, & default_options ( & env) ) ;
190+ & Vec :: from_array ( & env, [ 500i128 ] ) , & Vec :: from_array ( & env, [ token] ) ,
191+ & deadline, & default_options ( & env) ) ;
188192
189- // Simulate funded > 0 by patching: we test status is Cancelled when funded == 0
190193 client. cancel_invoice ( & creator, & id) ;
191194 let invoice = client. get_invoice ( & id) ;
192- // funded was 0, so status should be Cancelled not Refunded
193195 assert_eq ! ( invoice. status, InvoiceStatus :: Cancelled ) ;
194196 }
195197
@@ -205,10 +207,10 @@ mod tests {
205207 & creator,
206208 & Vec :: from_array ( & env, [ recipient] ) ,
207209 & Vec :: from_array ( & env, [ 1000i128 ] ) ,
208- & token,
210+ & Vec :: from_array ( & env , [ token] ) ,
209211 & deadline,
210- & ( 86400u64 * 30 ) , // 30 day interval
211- & 0u32 , // infinite
212+ & ( 86400u64 * 30 ) ,
213+ & 0u32 ,
212214 ) ;
213215
214216 let invoice = client. get_invoice ( & id) ;
@@ -228,13 +230,12 @@ mod tests {
228230 & creator,
229231 & Vec :: from_array ( & env, [ recipient] ) ,
230232 & Vec :: from_array ( & env, [ 500i128 ] ) ,
231- & token,
233+ & Vec :: from_array ( & env , [ token] ) ,
232234 & deadline,
233235 & ( 86400u64 ) ,
234236 & 0u32 ,
235237 ) ;
236238
237- // Before release, no next invoice exists
238239 assert ! ( client. get_next_recurring( & id) . is_none( ) ) ;
239240 }
240241
@@ -244,10 +245,11 @@ mod tests {
244245 let creator = Address :: generate ( & env) ;
245246 let recipient = Address :: generate ( & env) ;
246247 let token = Address :: generate ( & env) ;
247- let deadline = env. ledger ( ) . timestamp ( ) + 7 * 86400 ; // 7 days
248+ let deadline = env. ledger ( ) . timestamp ( ) + 7 * 86400 ;
248249
249250 let id = client. create_invoice ( & creator, & Vec :: from_array ( & env, [ recipient] ) ,
250- & Vec :: from_array ( & env, [ 100i128 ] ) , & token, & deadline, & default_options ( & env) ) ;
251+ & Vec :: from_array ( & env, [ 100i128 ] ) , & Vec :: from_array ( & env, [ token] ) ,
252+ & deadline, & default_options ( & env) ) ;
251253
252254 let invoice = client. get_invoice ( & id) ;
253255 assert_eq ! ( invoice. deadline, deadline) ;
@@ -269,7 +271,8 @@ mod tests {
269271 } ;
270272
271273 let id = client. create_invoice ( & creator, & Vec :: from_array ( & env, [ recipient] ) ,
272- & Vec :: from_array ( & env, [ 1000i128 ] ) , & token, & deadline, & options) ;
274+ & Vec :: from_array ( & env, [ 1000i128 ] ) , & Vec :: from_array ( & env, [ token] ) ,
275+ & deadline, & options) ;
273276
274277 let invoice = client. get_invoice ( & id) ;
275278 assert ! ( invoice. escrow_enabled) ;
@@ -283,21 +286,24 @@ mod tests {
283286 let r1 = Address :: generate ( & env) ;
284287 let r2 = Address :: generate ( & env) ;
285288 let r3 = Address :: generate ( & env) ;
286- let token = Address :: generate ( & env) ;
289+ let t1 = Address :: generate ( & env) ;
290+ let t2 = Address :: generate ( & env) ;
291+ let t3 = Address :: generate ( & env) ;
287292 let deadline = env. ledger ( ) . timestamp ( ) + 86400 ;
288293
289294 let id = client. create_invoice (
290295 & creator,
291296 & Vec :: from_array ( & env, [ r1. clone ( ) , r2. clone ( ) , r3. clone ( ) ] ) ,
292297 & Vec :: from_array ( & env, [ 300i128 , 300i128 , 400i128 ] ) ,
293- & token ,
298+ & Vec :: from_array ( & env , [ t1 , t2 , t3 ] ) ,
294299 & deadline,
295300 & default_options ( & env) ,
296301 ) ;
297302
298303 let invoice = client. get_invoice ( & id) ;
299304 assert_eq ! ( invoice. recipients. len( ) , 3 ) ;
300305 assert_eq ! ( invoice. amounts. get( 2 ) . unwrap( ) , 400i128 ) ;
306+ assert_eq ! ( invoice. tokens. len( ) , 3 ) ;
301307 }
302308
303309 #[ test]
@@ -310,7 +316,8 @@ mod tests {
310316 let deadline = env. ledger ( ) . timestamp ( ) + 86400 ;
311317
312318 let id = client. create_invoice ( & creator, & Vec :: from_array ( & env, [ recipient] ) ,
313- & Vec :: from_array ( & env, [ 500i128 ] ) , & token, & deadline, & default_options ( & env) ) ;
319+ & Vec :: from_array ( & env, [ 500i128 ] ) , & Vec :: from_array ( & env, [ token] ) ,
320+ & deadline, & default_options ( & env) ) ;
314321
315322 assert_eq ! ( client. get_payer_total( & id, & payer) , 0i128 ) ;
316323 }
@@ -326,15 +333,61 @@ mod tests {
326333 let deadline = env. ledger ( ) . timestamp ( ) + 86400 ;
327334
328335 let id1 = client. create_invoice ( & creator, & Vec :: from_array ( & env, [ recipient. clone ( ) ] ) ,
329- & Vec :: from_array ( & env, [ 200i128 ] ) , & token, & deadline, & default_options ( & env) ) ;
336+ & Vec :: from_array ( & env, [ 200i128 ] ) , & Vec :: from_array ( & env, [ token. clone ( ) ] ) ,
337+ & deadline, & default_options ( & env) ) ;
330338 let id2 = client. create_invoice ( & creator, & Vec :: from_array ( & env, [ recipient] ) ,
331- & Vec :: from_array ( & env, [ 300i128 ] ) , & token, & deadline, & default_options ( & env) ) ;
339+ & Vec :: from_array ( & env, [ 300i128 ] ) , & Vec :: from_array ( & env, [ token] ) ,
340+ & deadline, & default_options ( & env) ) ;
332341
333- // Overpayment on id1 should panic
334342 let payments = Vec :: from_array ( & env, [
335343 InvoicePayment { invoice_id : id1, amount : 999i128 } ,
336344 InvoicePayment { invoice_id : id2, amount : 100i128 } ,
337345 ] ) ;
338346 client. pool_pay ( & payer, & payments) ;
339347 }
348+
349+ #[ test]
350+ fn test_multi_token_invoice_stores_per_recipient_tokens ( ) {
351+ let ( env, client) = setup ( ) ;
352+ let creator = Address :: generate ( & env) ;
353+ let r1 = Address :: generate ( & env) ;
354+ let r2 = Address :: generate ( & env) ;
355+ let usdc = Address :: generate ( & env) ;
356+ let xlm = Address :: generate ( & env) ;
357+ let deadline = env. ledger ( ) . timestamp ( ) + 86400 ;
358+
359+ let id = client. create_invoice (
360+ & creator,
361+ & Vec :: from_array ( & env, [ r1, r2] ) ,
362+ & Vec :: from_array ( & env, [ 500i128 , 300i128 ] ) ,
363+ & Vec :: from_array ( & env, [ usdc. clone ( ) , xlm. clone ( ) ] ) ,
364+ & deadline,
365+ & default_options ( & env) ,
366+ ) ;
367+
368+ let invoice = client. get_invoice ( & id) ;
369+ assert_eq ! ( invoice. tokens. get( 0 ) . unwrap( ) , usdc) ;
370+ assert_eq ! ( invoice. tokens. get( 1 ) . unwrap( ) , xlm) ;
371+ }
372+
373+ #[ test]
374+ #[ should_panic]
375+ fn test_create_invoice_rejects_token_length_mismatch ( ) {
376+ let ( env, client) = setup ( ) ;
377+ let creator = Address :: generate ( & env) ;
378+ let r1 = Address :: generate ( & env) ;
379+ let r2 = Address :: generate ( & env) ;
380+ let token = Address :: generate ( & env) ;
381+ let deadline = env. ledger ( ) . timestamp ( ) + 86400 ;
382+
383+ // 2 recipients but only 1 token — should panic
384+ client. create_invoice (
385+ & creator,
386+ & Vec :: from_array ( & env, [ r1, r2] ) ,
387+ & Vec :: from_array ( & env, [ 500i128 , 300i128 ] ) ,
388+ & Vec :: from_array ( & env, [ token] ) ,
389+ & deadline,
390+ & default_options ( & env) ,
391+ ) ;
392+ }
340393}
0 commit comments