Skip to main content

openauth_plugins/siwe/
schema.rs

1use indexmap::IndexMap;
2use openauth_core::db::{DbField, DbFieldType, DbTable, ForeignKey, OnDelete};
3use openauth_core::plugin::PluginSchemaContribution;
4
5#[derive(Debug, Clone, Default, PartialEq, Eq)]
6pub struct SiweSchemaOptions {
7    table_name: Option<String>,
8    field_names: IndexMap<String, String>,
9}
10
11impl SiweSchemaOptions {
12    pub fn new() -> Self {
13        Self::default()
14    }
15
16    #[must_use]
17    pub fn table_name(mut self, table_name: impl Into<String>) -> Self {
18        self.table_name = Some(table_name.into());
19        self
20    }
21
22    #[must_use]
23    pub fn field_name(
24        mut self,
25        logical_name: impl Into<String>,
26        db_name: impl Into<String>,
27    ) -> Self {
28        self.field_names.insert(logical_name.into(), db_name.into());
29        self
30    }
31
32    fn table_name_or_default(&self) -> String {
33        self.table_name
34            .clone()
35            .unwrap_or_else(|| "wallet_addresses".to_owned())
36    }
37
38    fn field_name_or_default(&self, logical_name: &str) -> String {
39        self.field_names
40            .get(logical_name)
41            .cloned()
42            .unwrap_or_else(|| logical_name.to_owned())
43    }
44
45    pub(crate) fn metadata(&self) -> serde_json::Value {
46        let mut fields = serde_json::Map::new();
47        for logical_name in ["userId", "address", "chainId", "isPrimary", "createdAt"] {
48            if let Some(db_name) = self.field_names.get(logical_name) {
49                fields.insert(
50                    logical_name.to_owned(),
51                    serde_json::Value::String(db_name.clone()),
52                );
53            }
54        }
55        serde_json::json!({
56            "walletAddress": {
57                "modelName": self.table_name_or_default(),
58                "fields": fields,
59            }
60        })
61    }
62}
63
64pub(crate) fn wallet_address_schema(options: &SiweSchemaOptions) -> PluginSchemaContribution {
65    let mut fields = IndexMap::new();
66    fields.insert(
67        "id".to_owned(),
68        DbField::new("id", DbFieldType::String).generated(),
69    );
70    fields.insert(
71        "userId".to_owned(),
72        DbField::new(options.field_name_or_default("userId"), DbFieldType::String)
73            .indexed()
74            .references(ForeignKey::new("users", "id", OnDelete::Cascade)),
75    );
76    fields.insert(
77        "address".to_owned(),
78        DbField::new(
79            options.field_name_or_default("address"),
80            DbFieldType::String,
81        ),
82    );
83    fields.insert(
84        "chainId".to_owned(),
85        DbField::new(
86            options.field_name_or_default("chainId"),
87            DbFieldType::Number,
88        ),
89    );
90    fields.insert(
91        "isPrimary".to_owned(),
92        DbField::new(
93            options.field_name_or_default("isPrimary"),
94            DbFieldType::Boolean,
95        ),
96    );
97    fields.insert(
98        "createdAt".to_owned(),
99        DbField::new(
100            options.field_name_or_default("createdAt"),
101            DbFieldType::Timestamp,
102        )
103        .generated(),
104    );
105
106    PluginSchemaContribution::table(
107        "walletAddress",
108        DbTable {
109            name: options.table_name_or_default(),
110            fields,
111            order: Some(20),
112        },
113    )
114}