doc.gno
6.38 Kb ยท 171 lines
1// Package store provides a domain-specific key-value storage system with
2// permission-based access control for Gno smart contracts.
3//
4// ## Overview
5//
6// The store package implements a flexible KVStore interface that allows different
7// domains (e.g., pool, position, router, staker) to maintain isolated storage with
8// granular access control. Each domain creates its own KVStore instance with a
9// unique domain address that acts as the primary authority.
10//
11// Key components of this package include:
12//
13// 1. **KVStore Interface**: Defines the contract for domain-specific storage operations.
14// 2. **kvStore Implementation**: Concrete implementation of the KVStore interface with
15// permission management and data storage.
16// 3. **Permission System**: Three-level permission model (None, ReadOnly, Write) for
17// controlling access to storage operations.
18// 4. **Type-Safe Getters**: Strongly-typed getter methods with runtime type casting
19// and validation.
20//
21// ## Key Features
22//
23// - **Domain Isolation**: Each domain has its own isolated storage space identified
24// by its domain address.
25// - **Permission-Based Access Control**: Fine-grained permissions (None, ReadOnly, Write)
26// for authorized callers beyond the domain owner.
27// - **Type-Safe Operations**: Specialized getter methods (GetInt64, GetString, GetAddress,
28// etc.) with automatic type casting and error handling.
29// - **Runtime Permission Checks**: Automatic permission verification using runtime.CurrentRealm()
30// to ensure only authorized callers can read or write data.
31// - **Authorized Caller Management**: Dynamic addition, update, and removal of authorized
32// callers with specific permissions.
33//
34// ## Permission Model
35//
36// The package defines three permission levels:
37//
38// - **None (0)**: No access to the store.
39// - **ReadOnly (1)**: Can read data but cannot modify.
40// - **Write (2)**: Can both read and write data.
41//
42// The domain address (owner) always has full Write permission and cannot be removed.
43//
44// ## Workflow
45//
46// Typical usage of the store package includes the following steps:
47//
48// 1. **Initialization**: Create a new KVStore instance using `NewKVStore(domainAddress)`.
49// 2. **Data Operations**: Use Set/Get methods to store and retrieve data.
50// 3. **Permission Management**: Add authorized callers using `AddAuthorizedCaller`.
51// 4. **Type-Safe Retrieval**: Use typed getters like `GetInt64`, `GetString`, etc.
52//
53// ## Example Usage
54//
55// ```gno
56// package main
57//
58// import (
59//
60// "std"
61//
62// "gno.land/p/gnoswap/store"
63//
64// )
65//
66// func main() {
67// // Create a new KVStore for a pool domain
68// poolAddr := std.Address("g1pool...")
69// kvStore := store.NewKVStore(poolAddr)
70//
71// // Store various types of data
72// kvStore.Set("totalLiquidity", uint64(1000000))
73// kvStore.Set("poolName", "ETH-USDC")
74// kvStore.Set("isActive", true)
75// kvStore.Set("feeRate", int64(3000))
76//
77// // Retrieve data with type safety
78// liquidity, err := kvStore.GetUint64("totalLiquidity")
79// if err != nil {
80// panic(err)
81// }
82//
83// poolName, err := kvStore.GetString("poolName")
84// if err != nil {
85// panic(err)
86// }
87//
88// // Add an authorized caller with read-only permission
89// routerAddr := std.Address("g1router...")
90// if err := kvStore.AddAuthorizedCaller(routerAddr, store.ReadOnly); err != nil {
91// panic(err)
92// }
93//
94// // Update permission to write access
95// if err := kvStore.UpdateAuthorizedCaller(routerAddr, store.Write); err != nil {
96// panic(err)
97// }
98//
99// // Check permissions
100// if kvStore.IsWriteAuthorized(routerAddr) {
101// println("Router has write access")
102// }
103//
104// // Get all authorized callers
105// callers, err := kvStore.GetAuthorizedCallers()
106// if err != nil {
107// panic(err)
108// }
109//
110// // Remove an authorized caller
111// if err := kvStore.RemoveAuthorizedCaller(routerAddr); err != nil {
112// panic(err)
113// }
114// }
115//
116// ```
117//
118// ## Permission Checks
119//
120// The store automatically verifies permissions during operations:
121//
122// - **Read Operations**: `Get`, `GetInt64`, `GetString`, etc. check ReadOnly or Write permission.
123// - **Write Operations**: `Set` and `Delete` require Write permission.
124// - **Management Operations**: `AddAuthorizedCaller`, `UpdateAuthorizedCaller`, and
125// `RemoveAuthorizedCaller` can only be called by the domain address itself.
126//
127// ## Key Prefixing
128//
129// Internally, all keys are prefixed with the domain address to ensure isolation:
130//
131// Actual key: "{domainAddress}:{userKey}"
132//
133// This prevents key collisions between different domains.
134//
135// ## Error Handling
136//
137// The package defines several error types:
138//
139// - ErrKeyNotFound: Requested key does not exist in the store.
140// - ErrReadPermissionDenied: Caller lacks read permission.
141// - ErrWritePermissionDenied: Caller lacks write permission.
142// - ErrUpdatePermissionDenied: Only domain address can manage authorized callers.
143// - ErrAuthorizedCallerAlreadyRegistered: Attempting to add an already registered caller.
144// - ErrAuthorizedCallerNotFound: Attempting to update/remove a non-existent caller.
145// - ErrInvalidPermission: Attempting to assign an unsupported permission level.
146// - ErrFailedCast: Type casting failed during typed getter operations.
147//
148// ## Type Casting Utilities
149//
150// The package provides utility functions for safe type casting:
151//
152// - CastToInt64: Casts to int64 with error handling
153// - CastToUint64: Casts to uint64 with error handling
154// - CastToBool: Casts to bool with error handling
155// - CastToString: Casts to string with error handling
156// - CastToAddress: Casts to address with error handling
157// - CastToTree: Casts to *avl.Tree with error handling
158//
159// These utilities are used internally by typed getters but can also be used directly.
160//
161// ## Limitations and Considerations
162//
163// - All stored values are of type `any`, requiring runtime type casting for retrieval.
164// - Permission management can only be performed by the domain address itself.
165// - The domain address always has Write permission and cannot be removed from
166// authorized callers.
167// - Keys are automatically prefixed with the domain address for isolation.
168//
169// Package store is intended for use in Gno smart contracts requiring isolated,
170// permission-controlled storage for different protocol components.
171package store