mirror of
https://github.com/onsonr/sonr.git
synced 2025-03-10 04:57:08 +00:00
* feat: add docs and CI workflow for publishing to onsonr.dev * (refactor): Move hway,motr executables to their own repos * feat: simplify devnet and testnet configurations * refactor: update import path for didcrypto package * docs(networks): Add README with project overview, architecture, and community links * refactor: Move network configurations to deploy directory * build: update golang version to 1.23 * refactor: move logger interface to appropriate package * refactor: Move devnet configuration to networks/devnet * chore: improve release process with date variable * (chore): Move Crypto Library * refactor: improve code structure and readability in DID module * feat: integrate Trunk CI checks * ci: optimize CI workflow by removing redundant build jobs --------- Co-authored-by: Darp Alakun <i@prad.nu>
125 lines
4.2 KiB
Go
125 lines
4.2 KiB
Go
package accounts
|
|
|
|
import (
|
|
"context"
|
|
"encoding/binary"
|
|
|
|
"cosmossdk.io/collections"
|
|
"cosmossdk.io/core/store"
|
|
sdk "github.com/cosmos/cosmos-sdk/types"
|
|
|
|
"github.com/onsonr/sonr/internal/prefixstore"
|
|
"github.com/onsonr/sonr/internal/transaction"
|
|
)
|
|
|
|
var AccountStatePrefix = collections.NewPrefix(255)
|
|
|
|
type (
|
|
ModuleExecFunc = func(ctx context.Context, sender []byte, msg transaction.Msg) (transaction.Msg, error)
|
|
ModuleQueryFunc = func(ctx context.Context, queryReq transaction.Msg) (transaction.Msg, error)
|
|
)
|
|
|
|
type contextKey struct{}
|
|
|
|
type contextValue struct {
|
|
store store.KVStore // store is the prefixed store for the account.
|
|
sender []byte // sender is the address of the entity invoking the account action.
|
|
whoami []byte // whoami is the address of the account being invoked.
|
|
funds sdk.Coins // funds reports the coins sent alongside the request.
|
|
parentContext context.Context // parentContext that was used to build the account context.
|
|
moduleExec ModuleExecFunc // moduleExec is a function that executes a module message, when the resp type is unknown.
|
|
moduleQuery ModuleQueryFunc // moduleQuery is a function that queries a module.
|
|
}
|
|
|
|
func addCtx(ctx context.Context, value contextValue) context.Context {
|
|
return context.WithValue(ctx, contextKey{}, value)
|
|
}
|
|
|
|
func getCtx(ctx context.Context) contextValue {
|
|
return ctx.Value(contextKey{}).(contextValue)
|
|
}
|
|
|
|
// MakeAccountContext creates a new account execution context given:
|
|
// storeSvc: which fetches the x/accounts module store.
|
|
// accountAddr: the address of the account being invoked, which is used to give the
|
|
// account a prefixed storage.
|
|
// sender: the address of entity invoking the account action.
|
|
// moduleExec: a function that executes a module message.
|
|
// moduleQuery: a function that queries a module.
|
|
func MakeAccountContext(
|
|
ctx context.Context,
|
|
storeSvc store.KVStoreService,
|
|
accNumber uint64,
|
|
accountAddr []byte,
|
|
sender []byte,
|
|
funds sdk.Coins,
|
|
moduleExec ModuleExecFunc,
|
|
moduleQuery ModuleQueryFunc,
|
|
) context.Context {
|
|
return addCtx(ctx, contextValue{
|
|
store: makeAccountStore(ctx, storeSvc, accNumber),
|
|
sender: sender,
|
|
whoami: accountAddr,
|
|
funds: funds,
|
|
parentContext: ctx,
|
|
moduleExec: moduleExec,
|
|
moduleQuery: moduleQuery,
|
|
})
|
|
}
|
|
|
|
func SetSender(ctx context.Context, sender []byte) context.Context {
|
|
v := getCtx(ctx)
|
|
v.sender = sender
|
|
return addCtx(v.parentContext, v)
|
|
}
|
|
|
|
// makeAccountStore creates the prefixed store for the account.
|
|
// It uses the number of the account, this gives constant size
|
|
// bytes prefixes for the account state.
|
|
func makeAccountStore(ctx context.Context, storeSvc store.KVStoreService, accNum uint64) store.KVStore {
|
|
prefix := make([]byte, 8)
|
|
binary.BigEndian.PutUint64(prefix, accNum)
|
|
return prefixstore.New(storeSvc.OpenKVStore(ctx), append(AccountStatePrefix, prefix...))
|
|
}
|
|
|
|
// ExecModule can be used to execute a message towards a module, when the response type is unknown.
|
|
func ExecModule(ctx context.Context, msg transaction.Msg) (transaction.Msg, error) {
|
|
// get sender
|
|
v := getCtx(ctx)
|
|
|
|
resp, err := v.moduleExec(v.parentContext, v.whoami, msg)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
return resp, nil
|
|
}
|
|
|
|
// QueryModule can be used by an account to execute a module query.
|
|
func QueryModule(ctx context.Context, req transaction.Msg) (transaction.Msg, error) {
|
|
// we do not need to check the sender in a query because it is not a state transition.
|
|
// we also unwrap the original context.
|
|
v := getCtx(ctx)
|
|
resp, err := v.moduleQuery(v.parentContext, req)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
return resp, nil
|
|
}
|
|
|
|
// openKVStore returns the prefixed store for the account given the context.
|
|
func openKVStore(ctx context.Context) store.KVStore { return getCtx(ctx).store }
|
|
|
|
// Sender returns the address of the entity invoking the account action.
|
|
func Sender(ctx context.Context) []byte {
|
|
return getCtx(ctx).sender
|
|
}
|
|
|
|
// Whoami returns the address of the account being invoked.
|
|
func Whoami(ctx context.Context) []byte {
|
|
return getCtx(ctx).whoami
|
|
}
|
|
|
|
// Funds returns the funds associated with the execution context.
|
|
func Funds(ctx context.Context) sdk.Coins { return getCtx(ctx).funds }
|