@layerzerolabs/framework-solana-anchor-trait 0.2.62 → 0.2.64
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/Cargo.toml +3 -0
- package/README.md +316 -0
- package/examples/shapes/Cargo.lock +4126 -0
- package/examples/shapes/Cargo.toml +16 -0
- package/examples/shapes/macros/src/audit.rs +15 -0
- package/examples/shapes/macros/src/instructions/clear.rs +19 -0
- package/examples/shapes/macros/src/instructions/compute_area.rs +18 -20
- package/examples/shapes/macros/src/instructions/compute_perimeter.rs +18 -20
- package/examples/shapes/macros/src/instructions/get_dimension.rs +19 -0
- package/examples/shapes/macros/src/instructions/get_dimension_count.rs +19 -17
- package/examples/shapes/macros/src/instructions/mod.rs +8 -0
- package/examples/shapes/macros/src/instructions/reset.rs +50 -0
- package/examples/shapes/macros/src/instructions/scale.rs +52 -0
- package/examples/shapes/macros/src/lib.rs +14 -11
- package/examples/shapes/macros/src/shapes.rs +21 -26
- package/examples/shapes/macros/src/state_types.rs +14 -0
- package/examples/shapes/programs/ellipse/Cargo.toml +7 -0
- package/examples/shapes/programs/ellipse/src/lib.rs +69 -17
- package/examples/shapes/programs/ellipse/tests/ellipse/helpers.rs +110 -0
- package/examples/shapes/programs/ellipse/tests/ellipse/negative.rs +49 -0
- package/examples/shapes/programs/ellipse/tests/ellipse/positive.rs +231 -0
- package/examples/shapes/programs/ellipse/tests/ellipse.rs +23 -0
- package/examples/shapes/programs/triangle/Cargo.toml +7 -0
- package/examples/shapes/programs/triangle/src/lib.rs +69 -16
- package/examples/shapes/programs/triangle/tests/triangle/helpers.rs +123 -0
- package/examples/shapes/programs/triangle/tests/triangle/negative.rs +49 -0
- package/examples/shapes/programs/triangle/tests/triangle/positive.rs +225 -0
- package/examples/shapes/programs/triangle/tests/triangle.rs +23 -0
- package/examples/shapes/target/deploy/shapes_ellipse-keypair.json +1 -0
- package/examples/shapes/target/deploy/shapes_ellipse.so +0 -0
- package/examples/shapes/target/deploy/shapes_triangle-keypair.json +1 -0
- package/examples/shapes/target/deploy/shapes_triangle.so +0 -0
- package/package.json +20 -9
- package/src/assembly.rs +41 -6
- package/src/generation.rs +108 -131
- package/src/lib.rs +6 -4
- package/src/overrides.rs +56 -81
- package/tests/assembly.rs +154 -23
- package/tests/common/mod.rs +68 -14
- package/tests/generation.rs +137 -65
- package/tests/override.rs +93 -55
- package/tests/snapshots/snapshots__tests__snapshot_all_defaults.snap +32 -5
- package/tests/snapshots/snapshots__tests__snapshot_full_override.snap +35 -7
- package/tests/snapshots/snapshots__tests__snapshot_handler_override.snap +37 -7
- package/tests/snapshots/snapshots__tests__snapshot_mixed_overrides.snap +40 -9
- package/tests/snapshots/snapshots__tests__snapshot_with_extend_macro.snap +82 -0
- package/tests/snapshots.rs +51 -18
- package/examples/shapes/Anchor.toml +0 -19
- package/examples/shapes/programs/ellipse/src/state.rs +0 -9
- package/examples/shapes/programs/triangle/src/state.rs +0 -9
package/tests/assembly.rs
CHANGED
|
@@ -3,9 +3,9 @@ mod common;
|
|
|
3
3
|
#[cfg(test)]
|
|
4
4
|
mod tests {
|
|
5
5
|
use super::common::*;
|
|
6
|
-
use anchor_trait::{generate_instructions, Assembly};
|
|
6
|
+
use anchor_trait::{generate_instructions, Assembly, GeneratedInstructions};
|
|
7
7
|
use proc_macro2::TokenStream;
|
|
8
|
-
use quote::{quote, ToTokens};
|
|
8
|
+
use quote::{format_ident, quote, ToTokens};
|
|
9
9
|
|
|
10
10
|
// -----------------------------------------------------------------------
|
|
11
11
|
// Helper
|
|
@@ -26,6 +26,7 @@ mod tests {
|
|
|
26
26
|
instructions,
|
|
27
27
|
extra_mod_attrs,
|
|
28
28
|
source_mod: module.clone(),
|
|
29
|
+
extend_macro_name: None,
|
|
29
30
|
};
|
|
30
31
|
syn::parse2(assembly.assemble()).expect("assembly output should parse")
|
|
31
32
|
}
|
|
@@ -48,7 +49,7 @@ mod tests {
|
|
|
48
49
|
syn::parse_quote! {
|
|
49
50
|
mod my_program {
|
|
50
51
|
#[test_instruction]
|
|
51
|
-
pub fn lz_receive(ctx: Context<MyReceive>, params: LzReceiveParams) -> Result<()> {
|
|
52
|
+
pub fn lz_receive(ctx: &mut Context<MyReceive>, params: &LzReceiveParams) -> Result<()> {
|
|
52
53
|
Ok(())
|
|
53
54
|
}
|
|
54
55
|
}
|
|
@@ -60,12 +61,12 @@ mod tests {
|
|
|
60
61
|
syn::parse_quote! {
|
|
61
62
|
mod my_program {
|
|
62
63
|
#[test_instruction]
|
|
63
|
-
pub fn set_peer(ctx: Context<MyCustomAccounts>, params: SetPeerParams) -> Result<()> {
|
|
64
|
+
pub fn set_peer(ctx: &mut Context<MyCustomAccounts>, params: &SetPeerParams) -> Result<()> {
|
|
64
65
|
Ok(())
|
|
65
66
|
}
|
|
66
67
|
|
|
67
68
|
#[test_instruction]
|
|
68
|
-
pub fn lz_receive(ctx: Context<MyReceive>, params: LzReceiveParams) -> Result<()> {
|
|
69
|
+
pub fn lz_receive(ctx: &mut Context<MyReceive>, params: &LzReceiveParams) -> Result<()> {
|
|
69
70
|
Ok(())
|
|
70
71
|
}
|
|
71
72
|
|
|
@@ -108,7 +109,6 @@ mod tests {
|
|
|
108
109
|
let file = assemble_ok(&module, quote! {}, quote! {});
|
|
109
110
|
let (mod_pos, _) = find_program_mod(&file).expect("module should exist");
|
|
110
111
|
|
|
111
|
-
// Wrapper module for the override should be outside and before the program module
|
|
112
112
|
let wrapper_pos = file
|
|
113
113
|
.items
|
|
114
114
|
.iter()
|
|
@@ -121,10 +121,9 @@ mod tests {
|
|
|
121
121
|
"wrapper defs (pos {wrapper_pos}) should come before module (pos {mod_pos})"
|
|
122
122
|
);
|
|
123
123
|
|
|
124
|
-
// Default
|
|
125
|
-
// set_peer is fully overridden so no StdSetPeer
|
|
124
|
+
// Default structs are always emitted for provided instructions, even when overridden.
|
|
126
125
|
let has_default_impl_outside = file.items[..mod_pos].iter().any(|item| {
|
|
127
|
-
matches!(item, syn::Item::Struct(s) if s.ident == "StdGetPeer" || s.ident == "StdToken")
|
|
126
|
+
matches!(item, syn::Item::Struct(s) if s.ident == "StdGetPeer" || s.ident == "StdToken" || s.ident == "StdSetPeer")
|
|
128
127
|
});
|
|
129
128
|
assert!(has_default_impl_outside, "default impls should be outside the module");
|
|
130
129
|
}
|
|
@@ -132,7 +131,7 @@ mod tests {
|
|
|
132
131
|
#[test]
|
|
133
132
|
fn extra_mod_attrs_applied_to_module() {
|
|
134
133
|
let module = module_with_required_only();
|
|
135
|
-
let file = assemble_ok(&module, quote! {}, quote! {
|
|
134
|
+
let file = assemble_ok(&module, quote! {}, quote! {});
|
|
136
135
|
let (_, m) = find_program_mod(&file).expect("module should exist");
|
|
137
136
|
|
|
138
137
|
let has_program_attr = m
|
|
@@ -148,12 +147,12 @@ mod tests {
|
|
|
148
147
|
#[some_custom_attr]
|
|
149
148
|
mod my_program {
|
|
150
149
|
#[test_instruction]
|
|
151
|
-
pub fn lz_receive(ctx: Context<MyReceive>, params: LzReceiveParams) -> Result<()> {
|
|
150
|
+
pub fn lz_receive(ctx: &mut Context<MyReceive>, params: &LzReceiveParams) -> Result<()> {
|
|
152
151
|
Ok(())
|
|
153
152
|
}
|
|
154
153
|
}
|
|
155
154
|
};
|
|
156
|
-
let file = assemble_ok(&module, quote! {}, quote! {
|
|
155
|
+
let file = assemble_ok(&module, quote! {}, quote! {});
|
|
157
156
|
let (_, m) = find_program_mod(&file).expect("module should exist");
|
|
158
157
|
|
|
159
158
|
let has_custom_attr = m.attrs.iter().any(|attr| {
|
|
@@ -169,9 +168,9 @@ mod tests {
|
|
|
169
168
|
let (_, m) = find_program_mod(&file).expect("module should exist");
|
|
170
169
|
let items = mod_items(m);
|
|
171
170
|
|
|
172
|
-
//
|
|
173
|
-
//
|
|
174
|
-
// calls inside entrypoints, so we
|
|
171
|
+
// The override handler is relocated to a wrapper module, so it should not appear
|
|
172
|
+
// as a function definition inside the program module. The name still appears in
|
|
173
|
+
// dispatch calls inside entrypoints, so we match on function definitions specifically.
|
|
175
174
|
let has_override_fn = items.iter().any(|item| {
|
|
176
175
|
matches!(item, syn::Item::Fn(f) if f.sig.ident == "set_peer"
|
|
177
176
|
&& f.block.to_token_stream().to_string().contains("MyCustomAccounts"))
|
|
@@ -181,7 +180,6 @@ mod tests {
|
|
|
181
180
|
"overridden handler with custom body should be filtered out of module body"
|
|
182
181
|
);
|
|
183
182
|
|
|
184
|
-
// Non-handler items should be preserved inside the module
|
|
185
183
|
let has_helper = items
|
|
186
184
|
.iter()
|
|
187
185
|
.any(|item| matches!(item, syn::Item::Fn(f) if f.sig.ident == "helper_function"));
|
|
@@ -228,7 +226,6 @@ mod tests {
|
|
|
228
226
|
let module = module_with_override_and_extras();
|
|
229
227
|
let file = assemble_ok(&module, quote! {}, quote! {});
|
|
230
228
|
|
|
231
|
-
// Find the wrapper module for set_peer in the assembled output
|
|
232
229
|
let wrapper = file
|
|
233
230
|
.items
|
|
234
231
|
.iter()
|
|
@@ -242,7 +239,6 @@ mod tests {
|
|
|
242
239
|
})
|
|
243
240
|
.expect("wrapper module for set_peer should exist in assembled output");
|
|
244
241
|
|
|
245
|
-
// The relocated handler should be inside the wrapper
|
|
246
242
|
let wrapper_items = mod_items(wrapper);
|
|
247
243
|
let has_handler = wrapper_items
|
|
248
244
|
.iter()
|
|
@@ -255,7 +251,7 @@ mod tests {
|
|
|
255
251
|
let module: syn::ItemMod = syn::parse_quote! {
|
|
256
252
|
pub mod my_program {
|
|
257
253
|
#[test_instruction]
|
|
258
|
-
pub fn lz_receive(ctx: Context<MyReceive>, params: LzReceiveParams) -> Result<()> {
|
|
254
|
+
pub fn lz_receive(ctx: &mut Context<MyReceive>, params: &LzReceiveParams) -> Result<()> {
|
|
259
255
|
Ok(())
|
|
260
256
|
}
|
|
261
257
|
}
|
|
@@ -282,10 +278,148 @@ mod tests {
|
|
|
282
278
|
assert!(has_use_super, "module should contain `use super::*`");
|
|
283
279
|
}
|
|
284
280
|
|
|
281
|
+
// -----------------------------------------------------------------------
|
|
282
|
+
// Tests — extend macro emission
|
|
283
|
+
// -----------------------------------------------------------------------
|
|
284
|
+
|
|
285
|
+
#[test]
|
|
286
|
+
fn extend_macro_emitted_when_configured() {
|
|
287
|
+
let module = module_with_required_only();
|
|
288
|
+
let overrides = collect_overrides(&module);
|
|
289
|
+
let instructions =
|
|
290
|
+
generate_instructions(&TestCtx, &overrides).expect("generate should succeed");
|
|
291
|
+
let assembly = Assembly {
|
|
292
|
+
prelude: quote! {},
|
|
293
|
+
overrides,
|
|
294
|
+
instructions,
|
|
295
|
+
extra_mod_attrs: quote! {},
|
|
296
|
+
source_mod: module.clone(),
|
|
297
|
+
extend_macro_name: Some(format_ident!("test_extend_accounts")),
|
|
298
|
+
};
|
|
299
|
+
let file: syn::File =
|
|
300
|
+
syn::parse2(assembly.assemble()).expect("assembly output should parse");
|
|
301
|
+
|
|
302
|
+
let has_macro = file.items.iter().any(|item| {
|
|
303
|
+
matches!(item, syn::Item::Macro(m) if m.ident.as_ref().is_some_and(|id| id == "test_extend_accounts"))
|
|
304
|
+
});
|
|
305
|
+
assert!(has_macro, "should emit macro_rules! test_extend_accounts");
|
|
306
|
+
}
|
|
307
|
+
|
|
308
|
+
#[test]
|
|
309
|
+
fn program_attr_already_present_is_not_duplicated() {
|
|
310
|
+
// If the source module already carries `#[program]` (from a prior macro pass),
|
|
311
|
+
// assembly must strip it before re-emitting it as the innermost attribute.
|
|
312
|
+
let module: syn::ItemMod = syn::parse_quote! {
|
|
313
|
+
#[program]
|
|
314
|
+
mod my_program {
|
|
315
|
+
#[test_instruction]
|
|
316
|
+
pub fn lz_receive(ctx: &mut Context<MyReceive>, params: &LzReceiveParams) -> Result<()> {
|
|
317
|
+
Ok(())
|
|
318
|
+
}
|
|
319
|
+
}
|
|
320
|
+
};
|
|
321
|
+
let file = assemble_ok(&module, quote! {}, quote! {});
|
|
322
|
+
let (_, m) = find_program_mod(&file).expect("module should exist");
|
|
323
|
+
|
|
324
|
+
let program_count = m.attrs.iter().filter(|a| a.path().is_ident("program")).count();
|
|
325
|
+
assert_eq!(
|
|
326
|
+
program_count, 1,
|
|
327
|
+
"#[program] should appear exactly once, not duplicated: {program_count}"
|
|
328
|
+
);
|
|
329
|
+
}
|
|
330
|
+
|
|
331
|
+
#[test]
|
|
332
|
+
fn extend_macro_omitted_when_extend_rules_empty() {
|
|
333
|
+
// `extend_macro_name = Some(name)` but no extend rules → no macro_rules! emitted.
|
|
334
|
+
let module = module_with_required_only();
|
|
335
|
+
let overrides = collect_overrides(&module);
|
|
336
|
+
let assembly = Assembly {
|
|
337
|
+
prelude: quote! {},
|
|
338
|
+
overrides,
|
|
339
|
+
instructions: GeneratedInstructions::default(),
|
|
340
|
+
extra_mod_attrs: quote! {},
|
|
341
|
+
source_mod: module.clone(),
|
|
342
|
+
extend_macro_name: Some(format_ident!("test_extend_accounts")),
|
|
343
|
+
};
|
|
344
|
+
let file: syn::File = syn::parse2(assembly.assemble()).expect("should parse");
|
|
345
|
+
|
|
346
|
+
let has_any_macro = file.items.iter().any(|item| matches!(item, syn::Item::Macro(_)));
|
|
347
|
+
assert!(
|
|
348
|
+
!has_any_macro,
|
|
349
|
+
"no macro_rules! should be emitted when extend_rules is empty, even when extend_macro_name is Some"
|
|
350
|
+
);
|
|
351
|
+
}
|
|
352
|
+
|
|
353
|
+
#[test]
|
|
354
|
+
fn extend_macro_omitted_when_none() {
|
|
355
|
+
let module = module_with_required_only();
|
|
356
|
+
let file = assemble_ok(&module, quote! {}, quote! {});
|
|
357
|
+
|
|
358
|
+
let has_any_macro = file.items.iter().any(|item| matches!(item, syn::Item::Macro(_)));
|
|
359
|
+
assert!(!has_any_macro, "no macro_rules! should be emitted when extend_macro_name is None");
|
|
360
|
+
}
|
|
361
|
+
|
|
362
|
+
#[test]
|
|
363
|
+
fn extend_macro_positioned_before_program_module() {
|
|
364
|
+
let module = module_with_required_only();
|
|
365
|
+
let overrides = collect_overrides(&module);
|
|
366
|
+
let instructions =
|
|
367
|
+
generate_instructions(&TestCtx, &overrides).expect("generate should succeed");
|
|
368
|
+
let assembly = Assembly {
|
|
369
|
+
prelude: quote! {},
|
|
370
|
+
overrides,
|
|
371
|
+
instructions,
|
|
372
|
+
extra_mod_attrs: quote! {},
|
|
373
|
+
source_mod: module.clone(),
|
|
374
|
+
extend_macro_name: Some(format_ident!("test_extend_accounts")),
|
|
375
|
+
};
|
|
376
|
+
let file: syn::File =
|
|
377
|
+
syn::parse2(assembly.assemble()).expect("assembly output should parse");
|
|
378
|
+
|
|
379
|
+
let macro_pos = file
|
|
380
|
+
.items
|
|
381
|
+
.iter()
|
|
382
|
+
.position(|item| matches!(item, syn::Item::Macro(_)))
|
|
383
|
+
.expect("extend macro should exist");
|
|
384
|
+
let (mod_pos, _) = find_program_mod(&file).expect("module should exist");
|
|
385
|
+
assert!(
|
|
386
|
+
macro_pos < mod_pos,
|
|
387
|
+
"extend macro (pos {macro_pos}) should come before program module (pos {mod_pos})"
|
|
388
|
+
);
|
|
389
|
+
}
|
|
390
|
+
|
|
391
|
+
#[test]
|
|
392
|
+
fn extend_macro_contains_rules_for_each_provided_instruction() {
|
|
393
|
+
let module = module_with_required_only();
|
|
394
|
+
let overrides = collect_overrides(&module);
|
|
395
|
+
let instructions =
|
|
396
|
+
generate_instructions(&TestCtx, &overrides).expect("generate should succeed");
|
|
397
|
+
let assembly = Assembly {
|
|
398
|
+
prelude: quote! {},
|
|
399
|
+
overrides,
|
|
400
|
+
instructions,
|
|
401
|
+
extra_mod_attrs: quote! {},
|
|
402
|
+
source_mod: module.clone(),
|
|
403
|
+
extend_macro_name: Some(format_ident!("test_extend_accounts")),
|
|
404
|
+
};
|
|
405
|
+
let output = assembly.assemble().to_string();
|
|
406
|
+
|
|
407
|
+
// Check for the rule-arm matcher pattern `(set_peer ,` rather than just the bare name.
|
|
408
|
+
// The bare name also appears in entrypoints and wrapper modules, making it a trivially
|
|
409
|
+
// weak check. The `(name ,` prefix is unique to the macro_rules! arm head.
|
|
410
|
+
assert!(output.contains("(set_peer ,"), "macro should contain set_peer rule arm: {output}");
|
|
411
|
+
assert!(output.contains("(get_peer ,"), "macro should contain get_peer rule arm: {output}");
|
|
412
|
+
assert!(output.contains("(token ,"), "macro should contain token rule arm: {output}");
|
|
413
|
+
}
|
|
414
|
+
|
|
415
|
+
// -----------------------------------------------------------------------
|
|
416
|
+
// Tests — full integration
|
|
417
|
+
// -----------------------------------------------------------------------
|
|
418
|
+
|
|
285
419
|
#[test]
|
|
286
420
|
fn full_assembly_integration() {
|
|
287
421
|
let module = module_with_override_and_extras();
|
|
288
|
-
let file = assemble_ok(&module, quote! { struct PreludeMarker; }, quote! {
|
|
422
|
+
let file = assemble_ok(&module, quote! { struct PreludeMarker; }, quote! {});
|
|
289
423
|
|
|
290
424
|
// Verify complete ordering: prelude → wrapper → default impls → module
|
|
291
425
|
let prelude_pos = file
|
|
@@ -312,19 +446,16 @@ mod tests {
|
|
|
312
446
|
|
|
313
447
|
let (mod_pos, m) = find_program_mod(&file).expect("module should exist");
|
|
314
448
|
|
|
315
|
-
// Ordering: prelude < wrapper < default impls < module
|
|
316
449
|
assert!(prelude_pos < wrapper_pos, "prelude before wrapper");
|
|
317
450
|
assert!(wrapper_pos < context_pos, "wrapper before default impls");
|
|
318
451
|
assert!(context_pos < mod_pos, "default impls before module");
|
|
319
452
|
|
|
320
|
-
// Module has #[program]
|
|
321
453
|
let has_program = m
|
|
322
454
|
.attrs
|
|
323
455
|
.iter()
|
|
324
456
|
.any(|attr| attr.path().segments.last().is_some_and(|seg| seg.ident == "program"));
|
|
325
457
|
assert!(has_program, "module should have #[program]");
|
|
326
458
|
|
|
327
|
-
// Entrypoints inside module
|
|
328
459
|
let items = mod_items(m);
|
|
329
460
|
let fn_names: Vec<_> = items
|
|
330
461
|
.iter()
|
package/tests/common/mod.rs
CHANGED
|
@@ -3,12 +3,14 @@
|
|
|
3
3
|
#![allow(dead_code)]
|
|
4
4
|
|
|
5
5
|
use anchor_trait::{
|
|
6
|
-
generate_instructions, DefaultImpl, GeneratedInstructions,
|
|
7
|
-
InstructionSet, InstructionSpec, OverrideConfig,
|
|
6
|
+
generate_instructions, DefaultAccounts, DefaultImpl, GeneratedInstructions,
|
|
7
|
+
InstructionOverrides, InstructionSet, InstructionSpec, OverrideConfig,
|
|
8
8
|
};
|
|
9
9
|
use proc_macro2::TokenStream;
|
|
10
10
|
use quote::{format_ident, quote, ToTokens};
|
|
11
|
-
use syn::{
|
|
11
|
+
use syn::{
|
|
12
|
+
parse_quote, FnArg, GenericArgument, ItemFn, ItemStruct, Pat, PatIdent, PathArguments, Type,
|
|
13
|
+
};
|
|
12
14
|
|
|
13
15
|
// ---------------------------------------------------------------------------
|
|
14
16
|
// Test instruction set
|
|
@@ -31,11 +33,66 @@ pub enum TestIx {
|
|
|
31
33
|
/// Dummy codegen context.
|
|
32
34
|
pub struct TestCtx;
|
|
33
35
|
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
let
|
|
38
|
-
|
|
36
|
+
fn gen_set_peer(_ctx: &TestCtx, spec: &InstructionSpec<TestCtx>) -> DefaultAccounts {
|
|
37
|
+
let handler_ident = &spec.default_impl.as_ref().unwrap().handler_ident;
|
|
38
|
+
let params_type = spec.params_type.as_ref().unwrap();
|
|
39
|
+
let return_type = &spec.return_type;
|
|
40
|
+
DefaultAccounts {
|
|
41
|
+
struct_type: parse_quote! {
|
|
42
|
+
#[derive(Accounts)]
|
|
43
|
+
pub struct StdSetPeer<'info> {
|
|
44
|
+
pub placeholder: UncheckedAccount<'info>,
|
|
45
|
+
}
|
|
46
|
+
},
|
|
47
|
+
impl_block: parse_quote! {
|
|
48
|
+
impl StdSetPeer<'_> {
|
|
49
|
+
pub fn #handler_ident(_ctx: &mut Context<Self>, _params: &#params_type) -> Result<#return_type> {
|
|
50
|
+
unimplemented!()
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
},
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
fn gen_get_peer(_ctx: &TestCtx, spec: &InstructionSpec<TestCtx>) -> DefaultAccounts {
|
|
58
|
+
let handler_ident = &spec.default_impl.as_ref().unwrap().handler_ident;
|
|
59
|
+
let params_type = spec.params_type.as_ref().unwrap();
|
|
60
|
+
let return_type = &spec.return_type;
|
|
61
|
+
DefaultAccounts {
|
|
62
|
+
struct_type: parse_quote! {
|
|
63
|
+
#[derive(Accounts)]
|
|
64
|
+
pub struct StdGetPeer<'info> {
|
|
65
|
+
pub placeholder: UncheckedAccount<'info>,
|
|
66
|
+
}
|
|
67
|
+
},
|
|
68
|
+
impl_block: parse_quote! {
|
|
69
|
+
impl StdGetPeer<'_> {
|
|
70
|
+
pub fn #handler_ident(_ctx: &Context<Self>, _params: &#params_type) -> Result<#return_type> {
|
|
71
|
+
unimplemented!()
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
},
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
fn gen_token(_ctx: &TestCtx, spec: &InstructionSpec<TestCtx>) -> DefaultAccounts {
|
|
79
|
+
let handler_ident = &spec.default_impl.as_ref().unwrap().handler_ident;
|
|
80
|
+
let return_type = &spec.return_type;
|
|
81
|
+
DefaultAccounts {
|
|
82
|
+
struct_type: parse_quote! {
|
|
83
|
+
#[derive(Accounts)]
|
|
84
|
+
pub struct StdToken<'info> {
|
|
85
|
+
pub placeholder: UncheckedAccount<'info>,
|
|
86
|
+
}
|
|
87
|
+
},
|
|
88
|
+
impl_block: parse_quote! {
|
|
89
|
+
impl StdToken<'_> {
|
|
90
|
+
pub fn #handler_ident(_ctx: &Context<Self>) -> Result<#return_type> {
|
|
91
|
+
unimplemented!()
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
},
|
|
95
|
+
}
|
|
39
96
|
}
|
|
40
97
|
|
|
41
98
|
impl InstructionSet for TestIx {
|
|
@@ -71,9 +128,8 @@ impl InstructionSet for TestIx {
|
|
|
71
128
|
return_type: quote!(()),
|
|
72
129
|
is_view: false,
|
|
73
130
|
default_impl: Some(DefaultImpl {
|
|
74
|
-
accounts_ident: format_ident!("StdSetPeer"),
|
|
75
131
|
handler_ident: format_ident!("apply"),
|
|
76
|
-
generator:
|
|
132
|
+
generator: gen_set_peer,
|
|
77
133
|
}),
|
|
78
134
|
},
|
|
79
135
|
Self::GetPeer => InstructionSpec {
|
|
@@ -81,9 +137,8 @@ impl InstructionSet for TestIx {
|
|
|
81
137
|
return_type: quote!([u8; 32]),
|
|
82
138
|
is_view: true,
|
|
83
139
|
default_impl: Some(DefaultImpl {
|
|
84
|
-
accounts_ident: format_ident!("StdGetPeer"),
|
|
85
140
|
handler_ident: format_ident!("apply"),
|
|
86
|
-
generator:
|
|
141
|
+
generator: gen_get_peer,
|
|
87
142
|
}),
|
|
88
143
|
},
|
|
89
144
|
Self::LzReceive => InstructionSpec {
|
|
@@ -97,9 +152,8 @@ impl InstructionSet for TestIx {
|
|
|
97
152
|
return_type: quote!(Pubkey),
|
|
98
153
|
is_view: true,
|
|
99
154
|
default_impl: Some(DefaultImpl {
|
|
100
|
-
accounts_ident: format_ident!("StdToken"),
|
|
101
155
|
handler_ident: format_ident!("apply"),
|
|
102
|
-
generator:
|
|
156
|
+
generator: gen_token,
|
|
103
157
|
}),
|
|
104
158
|
},
|
|
105
159
|
}
|