Search Apps Documentation Source Content File Folder Download Copy Actions Download

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