sylvia 1.3.0

Framework for generating trait based CosmWasm smart contracts
Documentation
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
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
# Sylvia Framework

Sylvia is the old name meaning Spirit of The Wood.

Sylvia is the Roman goddess of the forest.

Sylvia is also a framework created to give you the abstraction-focused and
scalable solution for building your CosmWasm Smart Contracts. Find your way
into the forest of Cosmos ecosystem. We provide you with the toolset, so instead
of focusing on the raw structure of your contract, you can create it in proper
and idiomatic Rust and then just let cargo make sure that they are sound.

Learn more about `sylvia` in [the book](https://cosmwasm.github.io/sylvia-book/index.html)

## Sylvia contract template

The Sylvia template streamlines the development of CosmWasm smart contracts by providing a project scaffold that adheres to best practices and leverages the Sylvia framework's powerful features. It's designed to help developers focus more on their contract's business logic rather than boilerplate code.

Learn more here: [Sylvia Template on GitHub](https://github.com/CosmWasm/sylvia-template)

## The approach

[CosmWasm](https://cosmwasm.com/) ecosystem core provides the base building
blocks for smart contracts - the
[cosmwasm-std](https://crates.io/crates/cosmwasm-std) for basic CW bindings, the
[cw-storage-plus](https://crates.io/crates/cw-storage-plus) for easier state management,
and the [cw-multi-test](https://crates.io/crates/cw-multi-test) for testing them.
Sylvia framework is built on top of them, so for creating contracts, you don't
have to think about message structure, how their API is (de)serialized, or how
to handle message dispatching. Instead, the API of your contract is a set of
traits you implement on your contract type. The framework generates things like entry
point structures, functions dispatching the messages, or even helpers for multitest.
It allows for better control of interfaces, including validating their completeness
in compile time.

## Code generation

Sylvia macros generate code in the `sv` module. This means that every `contract` and
`interface` macro call must be made in a separate module to avoid collisions between
the generated modules.

## Contract type

In Sylvia, we define our contracts as structures:

```rust
use cw_storage_plus::Item;
use cosmwasm_schema::cw_serde;
use sylvia::types::QueryCtx;
use sylvia::cw_std::ensure;


/// Our new contract type.
///
struct MyContract<'a> {
    pub counter: Item<'a, u64>,
}


/// Response type returned by the
/// query method.
/// 
#[cw_serde]
pub struct CounterResp {
    pub counter: u64,
}

#[entry_points]
#[contract]
#[sv::error(ContractError)]
impl MyContract<'_> {
    pub fn new() -> Self {
        Self {
            counter: Item::new("counter")
        }
    }

    #[sv::msg(instantiate)]
    pub fn instantiate(&self, ctx: InstantiateCtx, counter: u64) -> StdResult<Response> {
        self.counter.save(ctx.deps.storage, &counter)?;
        Ok(Response::new())
    }

    #[sv::msg(exec)]
    pub fn increment(&self, ctx: ExecCtx) -> Result<Response, ContractError> {
        let counter = self.counter.load(ctx.deps.storage)?;
        ensure!(counter < 10, ContractError::LimitReached);
        self.counter.save(ctx.deps.storage, &(counter + 1))?;
        Ok(Response::new())
    }

    #[sv::msg(query)]
    pub fn counter(&self, ctx: QueryCtx) -> StdResult<CounterResp> {
        self
            .counter
            .load(ctx.deps.storage)
            .map(|counter| CounterResp { counter })
    }
}
```

Sylvia will generate the following new structures:

```rust
pub mod sv {
    use super::*;

    struct InstantiateMsg {
        counter: u64,
    }

    enum ExecMsg {
        Increment {}
    }

    enum ContractExecMsg {
        MyContract(ExecMsg)
    }

    enum QueryMsg {
        Counter {}
    }

    enum ContractQueryMsg {
        MyContract(QueryMsg)
    }

    // [...]
}

pub mod entry_points {
    use super::*;

    #[sylvia::cw_std::entry_point]
    pub fn instantiate(
        deps: sylvia::cw_std::DepsMut,
        env: sylvia::cw_std::Env,
        info: sylvia::cw_std::MessageInfo,
        msg: InstantiateMsg,
    ) -> Result<sylvia::cw_std::Response, StdError> {
        msg.dispatch(&MyContract::new(), (deps, env, info))
            .map_err(Into::into)
    }

    // [...]
}
```

`entry_points` macro generates `instantiate`, `execute`, `query` and `sudo` entry points.
All those methods call `dispatch` on the msg received and run proper logic defined for the sent
variant of the message.

What is essential - the field in the `InstantiateMsg` (and other messages) gets the same name as the
function argument.

The `ExecMsg` is the primary one you may use to send messages to the contract.
The `ContractExecMsg` is only an additional abstraction layer that would matter
later when we define traits for our contract.
Thanks to the `entry_point` macro it is already being used in the generated entry point and we don't
have to do it manually.

What you might notice - we can still use `StdResult` (so `StdError`) if we don't
need `ContractError` in a particular function. What is important is that the returned
result type has to implement `Into<ContractError>`, where `ContractError` is a contract
error type - it will all be commonized in the generated dispatching function (so
entry points have to return `ContractError` as its error variant).


## Interfaces

One of the fundamental ideas of the Sylvia framework is the interface, allowing the
grouping of messages into their semantical groups. Let's define a Sylvia interface:

```rust
pub mod group {
    use super::*;
    use sylvia::interface;
    use sylvia::types::ExecCtx;
    use sylvia::cw_std::StdError;

    #[cw_serde]
    pub struct IsMemberResp {
        pub is_member: bool,
    }

    #[interface]
    pub trait Group {
        type Error: From<StdError>;

        #[sv::msg(exec)]
        fn add_member(&self, ctx: ExecCtx, member: String) -> Result<Response, Self::Error>;

        #[sv::msg(query)]
        fn is_member(&self, ctx: QueryCtx, member: String) -> Result<IsMemberResp, Self::Error>;
    }
}
```

Then we need to implement the trait on the contract type:

```rust
use sylvia::cw_std::{Empty, Addr};
use cw_storage_plus::{Map, Item};

pub struct MyContract<'a> {
    counter: Item<'a, u64>,
    // New field added - remember to initialize it in `new`
    members: Map<'a, &'a Addr, Empty>,
}

impl group::Group for MyContract<'_> {
    type Error = ContractError;

    fn add_member(&self, ctx: ExecCtx, member: String) -> Result<Response, ContractError> {
        let member = ctx.deps.api.addr_validate(&member)?;
        self.members.save(ctx.deps.storage, &member, &Empty {})?;
        Ok(Response::new())
    }

    fn is_member(&self, ctx: QueryCtx, member: String) -> Result<group::IsMemberResp, ContractError> {
        let is_member = self.members.has(ctx.deps.storage, &Addr::unchecked(&member));
        let resp = group::IsMemberResp {
            is_member,
        };

        Ok(resp)
    }
}

#[contract]
#[sv::messages(group as Group)]
impl MyContract<'_> {
    // Nothing changed here
}
```

First, note that I defined the interface trait in its separate module with a name
matching the trait name, but written "snake_case" instead of CamelCase. Here I have the
`group` module for the `Group` trait, but the `CrossStaking` trait should be placed
in its own `cross_staking` module (note the underscore). This is a requirement right
now - Sylvia generates all the messages and boilerplate in this module and will try
to access them through this module. If the interface's name is a camel-case
version of the last module path's segment, the `as InterfaceName` can be omitted.
F.e. `#[sv::messages(cw1 as Cw1)]` can be reduced to `#[sv::messages(cw1)]`

Then there is the `Error` type embedded in the trait - it is also needed there,
and the trait bound here has to be at least `From<StdError>`, as Sylvia might
generate code returning the `StdError` in deserialization/dispatching implementation.
The trait can be more strict - this is the minimum.

Finally, the implementation block has an additional
`#[sv::messages(module as Identifier)]` attribute. Sylvia needs it to generate the dispatching
properly - there is the limitation that every macro has access only to its local
scope. In particular - we cannot see all traits implemented by a type and their
implementation from the `#[contract]` crate.

To solve this issue, we put this `#[sv::messages(...)]` attribute pointing to Sylvia
what is the module name where the interface is defined, and giving a unique name
for this interface (it would be used in generated code to provide proper enum variant).

## Macro attributes

```rust
struct MyMsg;
impl CustomMsg for MyMsg {}

struct MyQuery;
impl CustomQuery for MyMsg {}

#[entry_point]
#[contract]
#[sv::error(ContractError)]
#[sv::messages(interface as Interface)]
#[sv::messages(interface as InterfaceWithCustomType: custom(msg, query))]
#[sv::custom(msg=MyMsg, query=MyQuery)]
#[sv::msg_attr(exec, PartialOrd)]
#[sv::override_entry_point(sudo=crate::entry_points::sudo(crate::SudoMsg))]
impl MyContract {
    // ...
    #[sv::msg(query)]
    #[sv::attr(serde(rename(serialize = "CustomQueryMsg")))]
    fn query_msg(&self, _ctx: QueryCtx) -> StdResult<Response> {
        // ...
    }
}
```

 * `sv::error` is used by both `contract` and `entry_point` macros. It is necessary in case a custom
   error is being used by your contract. If omitted generated code will use `StdError`.

 * `sv::messages` is the attribute for the `contract` macro. Its purpose is to inform Sylvia
   about interfaces implemented for the contract. If the implemented interface does not use a
   default `Empty` message response for query and/or exec then the `: custom(query)`,
   `: custom(msg)` or `: custom(msg, query)` should be indicated.

 * `sv::override_entry_point` - refer to the `Overriding entry points` section.

 * `sv::custom` allows to define CustomMsg and CustomQuery for the contract. By default generated code
    will return `Response<Empty>` and will use `Deps<Empty>` and `DepsMut<Empty>`.

 * `sv::msg_attr` forwards any attribute to the message's type.

 * `sv::attr` forwards any attribute to the enum's variant.


## Usage in external crates

What is important is the possibility of using generated code in the external code.
First, let's start with generating the documentation of the crate:

```sh
cargo doc --document-private-items --open
```

This generates and opens documentation of the crate, including all generated structures.
`--document-private-item` is optional, but it will generate documentation of non-public
modules which is sometimes useful.

Going through the doc, you will see that all messages are generated in their structs/traits
modules. To send messages to the contract, we can just use them:

```rust
use sylvia::cw_std::{WasmMsg, to_json_binary};

fn some_handler(my_contract_addr: String) -> StdResult<Response> {
    let msg = my_contract_crate::sv::ExecMsg::Increment {};
    let msg = WasmMsg::ExecMsg {
        contract_addr: my_contract_addr,
        msg: to_json_binary(&msg)?,
        funds: vec![],
    }

    let resp = Response::new()
        .add_message(msg);
    Ok(resp)
}
```

We can use messages from traits in a similar way:

```rust
let msg = my_contract_crate::group::QueryMsg::IsMember {
    member: addr,
};

let is_member: my_contract_crate::group::IsMemberResp =
    deps.querier.query_wasm_smart(my_contract_addr, &msg)?;
```

It is important not to confuse the generated `ContractExecMsg/ContractQueryMsg`
with `ExecMsg/QueryMsg` - the former is generated only for contract, not for interfaces,
and is not meant to be used to send messages to the contract - their purpose is for proper
messages dispatching only, and should not be used besides the entry points.


## Query helpers

To make querying more user-friendly `Sylvia` provides users with `sylvia::types::BoundQuerier` and 
`sylvia::types::Remote` helpers. The latter is meant to store the address of some remote contract.
For each query method in the contract, Sylvia will add a method in a generated `sv::Querier` trait.
The `sv::Querier` is then implemented for `sylvia::types::BoundQuerier` so the user can call the method.

Let's modify the query from the previous paragraph. Currently, it will look as follows:

```rust
let is_member = Remote::<OtherContractType>::new(remote_addr)
    .querier(&ctx.deps.querier)
    .is_member(addr)?;
```

Your contract might communicate with some other contract regularly.
In such a case you might want to store it as a field in your Contract:

```rust
pub struct MyContract<'a> {
    counter: Item<'a, u64>,
    members: Map<'a, &'a Addr, Empty>,
    remote: Item<'a, Remote<'static, OtherContractType>>,
}

#[sv::msg(exec)]
pub fn evaluate_member(&self, ctx: ExecCtx, ...) -> StdResult<Response> {
    let is_member = self
        .remote
        .load(ctx.deps.storage)?
        .querier(&ctx.deps.querier)
        .is_member(addr)?;
}
```


## Executor message builder

Sylvia defines the
[`ExecutorBuilder`](https://docs.rs/sylvia/latest/sylvia/types/struct.ExecutorBuilder.html)
type, which can be accessed through
[`Remote::executor`](https://docs.rs/sylvia/latest/sylvia/types/struct.Remote.html#method.executor).
It's generic over the contract type and exposes execute methods from the
contract and every interface implemented on it through an auto-generated `Executor` traits.
Execute messages of other contracts can be built with `Remote` as well by
calling `executor` method. It returns a message builder that implements
auto-generated `Executor` traits of all Sylvia contracts.
Methods defined in the `Executor` traits constructs an execute message,
which variant corresponds to the method name.
The message is then wrapped in the `WasmMsg`, and returned once
[`ExecutorBuilder::build()`](https://docs.rs/sylvia/latest/sylvia/types/struct.ExecutorBuilder.html#method.build)
method is called.

```rust
use sylvia::types::Remote;
use other_contract::contract::OtherContract;
use other_contract::contract::sv::Executor;

let some_exec_msg: WasmMsg = Remote::<OtherContract>::new(remote_addr)
    .executor()
    .some_exec_method()?
    .build();
```

## Using unsupported entry points

If there's a need for an entry point that is not implemented in Sylvia, you can implement
it manually using the `#[entry_point]` macro. As an example, let's see how to implement
replies for messages:

```rust
use sylvia::cw_std::{DepsMut, Env, Reply, Response};

#[contract]
#[entry_point]
#[sv::error(ContractError)]
#[sv::messages(group as Group)]
impl MyContract<'_> {
    fn reply(&self, deps: DepsMut, env: Env, reply: Reply) -> Result<Response, ContractError> {
        todo!()
    }
    // [...]
}

#[entry_point]
fn reply(deps: DepsMut, env: Env, reply: Reply) -> Result<Response, ContractError> {
    &MyContract::new().reply(deps, env, reply)
}
```

It is important to create an entry function in the contract type - this way, it
gains access to all the state accessors defined on the type.

## Overriding entry points

There is a way to override an entry point or to add a custom-defined one.
Let's consider the following code:

```rust
#[cw_serde]
pub enum UserExecMsg {
    IncreaseByOne {},
}

pub fn increase_by_one(ctx: ExecCtx) -> StdResult<Response> {
    crate::COUNTER.update(ctx.deps.storage, |count| -> Result<u32, StdError> {
        Ok(count + 1)
    })?;
    Ok(Response::new())
}

#[cw_serde]
pub enum CustomExecMsg {
    ContractExec(crate::ContractExecMsg),
    CustomExec(UserExecMsg),
}

impl CustomExecMsg {
    pub fn dispatch(self, ctx: (DepsMut, Env, MessageInfo)) -> StdResult<Response> {
        match self {
            CustomExecMsg::ContractExec(msg) => {
                msg.dispatch(&crate::contract::Contract::new(), ctx)
            }
            CustomExecMsg::CustomExec(_) => increase_by_one(ctx.into()),
        }
    }
}

#[entry_point]
pub fn execute(
    deps: DepsMut,
    env: Env,
    info: MessageInfo,
    msg: CustomExecMsg,
) -> StdResult<Response> {
    msg.dispatch((deps, env, info))
}
```

It is possible to define a custom `exec` message that will dispatch over one generated
by your contract and one defined by you. To use this custom entry point with `contract` macro
you can add the `sv::override_entry_point(...)` attribute.

```rust    
#[contract]
#[sv::override_entry_point(exec=crate::entry_points::execute(crate::exec::CustomExecMsg))]
#[sv::override_entry_point(sudo=crate::entry_points::sudo(crate::SudoMsg))]
impl Contract {
    // ...
}
```

It is possible to override all message types like that. Next to the entry point path, you will
also have to provide the type of your custom message. It is required to deserialize the message
in the `multitest helpers`.

## Multitest

Sylvia also generates some helpers for testing contracts - it is hidden behind the
`mt` feature flag, which has to be enabled.

It is important to ensure no `mt` flag is set when the contract is built in `wasm`
target because of some dependencies it uses, which are not buildable on Wasm. The
recommendation is to add an extra `sylvia` entry with `mt` enabled in the
`dev-dependencies`, and also add the `mt` feature on your contract, which enables
mt utilities in other contract tests. An example `Cargo.toml`:

```toml
[package]
name = "my-contract"
version = "0.1.0"
edition = "2021"

[lib]
crate-type = ["cdylib", "rlib"]

[features]
library = []
mt = ["sylvia/mt"]

[dependencies]
sylvia = "0.10.0"

# [...]

[dev-dependencies]
sylvia = { version = "0.10.0", features = ["mt"] }
```

And the example code:

```rust
#[cfg(test)]
mod tests {
    use super::*;
    use sylvia::multitest::App;

    #[test]
    fn counter_test() {
        let app = App::default();

        let owner = "owner";

        let code_id = contract::CodeId::store_code(&app);

        let contract = code_id.instantiate(3)
            .with_label("My contract")
            .call(&owner)
            .unwrap();

        let counter = contract.counter().unwrap();
        assert_eq!(counter, contract::CounterResp { counter: 3});

        contract.increment().call(&owner).unwrap();

        let counter = contract.counter().unwrap();
        assert_eq!(counter, contract::CounterResp { counter: 4});
    }
}
```

Note the `contract` module I am using here - it is a slight change
that doesn't match the previous code - I assume here that all the contract code
sits in the `contract` module to make sure it is clear where the used type lies.
So if I use `contract::something`, it is `something` in the module of the original
contract (most probably Sylvia-generated).

First of all - we do not use `cw-multi-test` app directly. Instead, we use the `sylvia`
wrapper over it. It contains the original multi-test App internally, but it does
it in an internally mutable manner which makes it possible to avoid passing it
everywhere around. It adds some overhead, but it should not matter for testing code.

We are first using the `CodeId` type generated for every single Sylvia contract
separately. Its purpose is to abstract storing the contract in the blockchain. It
makes sure to create the contract object and pass it to the multitest.

A contract's `CodeId` type has one particularly interesting function - the `instantiate`,
which calls an instantiation function. It takes the same arguments as an instantiation
function in the contract, except for the context that Sylvia's utilities would provide.

The function doesn't instantiate contract immediately - instead, it returns what
is called `InstantiationProxy`. We decided that we don't want to force users to set
all the metadata - admin, label, and funds to send with every instantiation call,
as in the vast majority of cases, they are irrelevant. Instead, the
`InstantiationProxy` provides `with_label`, `with_funds`, and `with_amin` functions,
which set those meta fields in the builder pattern style.

When the instantiation is ready, we call the `call` function, passing the message
sender - we could add another `with_sender` function, but we decided that as the
sender has to be passed every single time, we can save some keystrokes on that.

The thing is similar when it comes to execution messages. The biggest difference
is that we don't call it on the `CodeId`, but on instantiated contracts instead.
We also have fewer fields to set on that - the proxy for execution provides only
the `with_funds` function.

All the instantiation and execution functions return the
`Result<cw_multi_test::AppResponse, ContractError>` type, where `ContractError`
is an error type of the contract.


## Interface items in multitest

Trait declaring all the interface methods is directly implemented on
the contracts Proxy type.

```rust
use contract::mt::Group;

#[test]
fn member_test() {
    let app = App::default();

    let owner = "owner";
    let member = "john";

    let code_id = contract::mt::CodeId::store_code(&app);

    let contract = code_id.instantiate(0)
        .with_label("My contract")
        .call(&owner);

    contract
        .add_member(member.to_owned())
        .call(&owner);

    let resp = contract
        .is_member(member.to_owned())

    assert_eq!(resp, group::IsMemberResp { is_member: true });
}
```

## Generics

### Interface

Defining associated types on an interface is as simple as defining them on a regular trait.

```rust
#[interface]
pub trait Generic {
    type Error: From<StdError>;
    type ExecParam: CustomMsg;
    type QueryParam: CustomMsg;
    type RetType: CustomMsg;

    #[sv::msg(exec)]
    fn generic_exec(
        &self,
        ctx: ExecCtx,
        msgs: Vec<CosmosMsg<Self::ExecParam>>,
    ) -> Result<Response, Self::Error>;

    #[sv::msg(query)]
    fn generic_query(&self, ctx: QueryCtx, param: Self::QueryParam) -> Result<Self::RetType, Self::Error>;
}
```

### Generic contract

Generics in a contract might be either used as generic field types or as generic parameters of return
types in the messages. When Sylvia generates the messages' enums, only generics used in respective methods
will be part of a given generated message type.


Example of usage:
```rust
pub struct GenericContract<
    InstantiateParam,
    ExecParam,
    FieldType,
> {
    _field: Item<'static, FieldType>,
    _phantom: std::marker::PhantomData<(
        InstantiateParam,
        ExecParam,
    )>,
}

#[contract]
impl<InstantiateParam, ExecParam, FieldType>
    GenericContract<InstantiateParam, ExecParam, FieldType>
where
    for<'msg_de> InstantiateParam: CustomMsg + Deserialize<'msg_de> + 'msg_de,
    ExecParam: CustomMsg + DeserializeOwned + 'static,
    FieldType: 'static,
{
    pub const fn new() -> Self {
        Self {
            _field: Item::new("field"),
            _phantom: std::marker::PhantomData,
        }
    }

    #[sv::msg(instantiate)]
    pub fn instantiate(
        &self,
        _ctx: InstantiateCtx,
        _msg: InstantiateParam,
    ) -> StdResult<Response> {
        Ok(Response::new())
    }

    #[sv::msg(exec)]
    pub fn contract_execute(
        &self,
        _ctx: ExecCtx,
        _msg: ExecParam,
    ) -> StdResult<Response> {
        Ok(Response::new())
    }
}
```

### Generics in entry_points

Entry points have to be generated with concrete types. Using the `entry_points` macro
on the generic contract we have to specify the types that have to be used.
We do that with `entry_points(generics<..>)`:

```rust
#[cfg_attr(not(feature = "library"), entry_points(generics<SvCustomMsg, SvCustomMsg, SvCustomMsg>))]
#[contract]
impl<InstantiateParam, ExecParam, FieldType>
    GenericContract<InstantiateParam, ExecParam, FieldType>
where
    for<'msg_de> InstantiateParam: CustomMsg + Deserialize<'msg_de> + 'msg_de,
    ExecParam: CustomMsg + DeserializeOwned + 'static,
    FieldType: 'static,
{
    ...
}
```

The contract might define a generic type in place of a custom message and query.
In such case we have to inform `entry_points` macro using `custom`:

```rust
#[cfg_attr(not(feature = "library"), entry_points(generics<SvCustomMsg, SvCustomMsg, SvCustomMsg>, custom(msg=SvCustomMsg, query=SvCustomQuery))]
#[contract]
#[sv::custom(msg=MsgT, query=QueryT)]
impl<InstantiateParam, ExecParam, FieldType, MsgT, QueryT>
    GenericContract<InstantiateParam, ExecParam, FieldType, MsgT, QueryT>
where
    for<'msg_de> InstantiateParam: CustomMsg + Deserialize<'msg_de> + 'msg_de,
    ExecParam: CustomMsg + DeserializeOwned + 'static,
    FieldType: 'static,
{
    ...
}
```


## Generating schema

Sylvia is designed to generate all the code that `cosmwasm-schema` relies on - this
makes it very easy to generate schema for the contract. Just add a `bin/schema.rs`
module, which would be recognized as a binary, and add a simple main function there:

```rust
use cosmwasm_schema::write_api;

use my_contract_crate::contract::{ContractExecMsg, ContractQueryMsg, InstantiateMsg};

fn main() {
    write_api! {
        instantiate: InstantiateMsg,
        execute: ContractExecMsg,
        query: ContractQueryMsg,
    }
}
```

## Road map

Sylvia is in the adoption stage right now, but we are still working on more and more
features for you. Here is a rough roadmap for the coming months:

- Replies - Sylvia still needs support for essential CosmWasm messages, which are
  replies. We want to make them smart, so expressing the correlation between the sent
  message and the executed handler is more direct and not hidden in the reply dispatcher.
- Migrations - Another important message we don't support, but the reason is similar
  to replies - we want them to be smart. We want to give you a nice way to provide
  upgrading Api for your contract, which would take care of its versioning.
- IBC - we want to give you a nice IBC Api too! However, expect it to be a
  while - we must first understand the best patterns here.
- Better tooling support - The biggest Sylvia issue is that the code it generates
  is not trivial, and not all the tooling handles it well. We are working on improving
  user experience in that regard.

## Troubleshooting

For more descriptive error messages, consider using the nightly toolchain (add `+nightly`
argument for cargo)

- Missing messages from an interface on your contract - You may be missing the
  `#[sv::messages(interface as Interface)]` attribute.