mirror of
https://github.com/sonr-io/sonr.git
synced 2026-08-02 17:31:39 +00:00
204 lines
6.2 KiB
Go
204 lines
6.2 KiB
Go
// Package plugin provides a high-level interface for interacting with the Motor WebAssembly enclave plugin.
|
|
//
|
|
// The Motor plugin operates as an MPC-based UCAN (User-Controlled Authorization Networks)
|
|
// KeyshareSource, providing sophisticated decentralized authorization capabilities. This package abstracts the
|
|
// underlying WASM implementation and provides type-safe method calls for:
|
|
//
|
|
// - UCAN token creation and delegation
|
|
// - MPC-based cryptographic signing and verification
|
|
// - DID generation and identity management
|
|
// - Secure enclave configuration and management
|
|
//
|
|
// # Usage Example
|
|
//
|
|
// Basic usage with enclave configuration:
|
|
//
|
|
// ctx := context.Background()
|
|
// enclaveData, _ := json.Marshal(&mpc.EnclaveData{...})
|
|
// plugin, err := LoadPluginWithEnclave(ctx, "sonr-testnet-1", enclaveData, nil)
|
|
// if err != nil {
|
|
// log.Fatal(err)
|
|
// }
|
|
//
|
|
// // Create UCAN token
|
|
// req := &NewOriginTokenRequest{
|
|
// AudienceDID: "did:sonr:audience",
|
|
// Attenuations: []map[string]any{
|
|
// {"can": []string{"sign"}, "with": "vault://example"},
|
|
// },
|
|
// }
|
|
// resp, err := plugin.NewOriginToken(req)
|
|
package plugin
|
|
|
|
import (
|
|
"context"
|
|
"encoding/json"
|
|
"fmt"
|
|
|
|
extism "github.com/extism/go-sdk"
|
|
)
|
|
|
|
// Plugin defines the interface for cryptographic operations provided by the WebAssembly enclave.
|
|
// It abstracts the underlying WASM implementation and provides type-safe method calls.
|
|
// Updated to match the refactored MPC-based UCAN KeyshareSource Motor plugin.
|
|
type Plugin interface {
|
|
// UCAN Token Operations
|
|
|
|
// NewOriginToken creates a new UCAN origin token using MPC signing.
|
|
NewOriginToken(req *NewOriginTokenRequest) (*UCANTokenResponse, error)
|
|
|
|
// NewAttenuatedToken creates a delegated UCAN token with attenuated permissions.
|
|
NewAttenuatedToken(req *NewAttenuatedTokenRequest) (*UCANTokenResponse, error)
|
|
|
|
// Cryptographic Operations
|
|
|
|
// SignData signs arbitrary data using the MPC enclave.
|
|
SignData(req *SignDataRequest) (*SignDataResponse, error)
|
|
|
|
// VerifyData verifies a signature against data using the MPC enclave.
|
|
VerifyData(req *VerifyDataRequest) (*VerifyDataResponse, error)
|
|
|
|
// Identity Operations
|
|
|
|
// GetIssuerDID retrieves the issuer DID, address, and chain code from the enclave.
|
|
GetIssuerDID() (*GetIssuerDIDResponse, error)
|
|
}
|
|
|
|
// LoadPluginWithEnclave initializes and loads the WebAssembly MPC-based UCAN enclave plugin
|
|
// with the specified enclave configuration. This method provides basic enclave configuration
|
|
// but does not include advanced features like health monitoring and automatic recovery.
|
|
//
|
|
// For production use, consider LoadPluginWithManager which provides enhanced lifecycle management.
|
|
//
|
|
// Parameters:
|
|
// - ctx: Context for plugin initialization
|
|
// - chainID: Chain ID for the enclave (e.g., "sonr-testnet-1")
|
|
// - enclaveData: JSON-encoded MPC enclave data
|
|
// - vaultConfig: Optional vault configuration parameters
|
|
//
|
|
// Returns a Plugin interface for UCAN token operations and MPC cryptographic functions.
|
|
func LoadPluginWithEnclave(
|
|
ctx context.Context,
|
|
chainID string,
|
|
enclaveData []byte,
|
|
vaultConfig map[string]any,
|
|
) (Plugin, error) {
|
|
// Verify WASM integrity before loading
|
|
if err := VerifyPluginIntegrity(motrPluginBytes); err != nil {
|
|
return nil, fmt.Errorf("WASM integrity verification failed: %w", err)
|
|
}
|
|
|
|
manifest := GetManifestWithEnclave(chainID, enclaveData, vaultConfig)
|
|
cfg := GetPluginConfig()
|
|
plugin, err := extism.NewPlugin(ctx, manifest, cfg, []extism.HostFunction{})
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
return &pluginImpl{plugin: plugin}, nil
|
|
}
|
|
|
|
// LoadPluginWithManager loads a Motor plugin using the enhanced plugin manager.
|
|
// This is the recommended method for production use as it provides:
|
|
// - Health monitoring and automatic recovery
|
|
// - Plugin instance caching and reuse
|
|
// - Comprehensive configuration validation
|
|
// - Background cleanup of expired instances
|
|
//
|
|
// Parameters:
|
|
// - ctx: Context for plugin initialization
|
|
// - config: Complete enclave configuration including timeouts, security settings, etc.
|
|
//
|
|
// Returns a managed Plugin interface with enhanced error handling and recovery.
|
|
func LoadPluginWithManager(ctx context.Context, config *EnclaveConfig) (Plugin, error) {
|
|
return DefaultManager.LoadPlugin(ctx, config)
|
|
}
|
|
|
|
type pluginImpl struct {
|
|
plugin *extism.Plugin
|
|
}
|
|
|
|
// UCAN Token Operations - Primary interface for the refactored Motor plugin
|
|
|
|
func (p *pluginImpl) NewOriginToken(req *NewOriginTokenRequest) (*UCANTokenResponse, error) {
|
|
reqBytes, err := json.Marshal(req)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
_, r, err := p.plugin.Call("new_origin_token", reqBytes)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
var resp UCANTokenResponse
|
|
if err := json.Unmarshal(r, &resp); err != nil {
|
|
return nil, err
|
|
}
|
|
return &resp, nil
|
|
}
|
|
|
|
// NewAttenuatedToken creates an attenuated UCAN token by delegating from a parent token.
|
|
func (p *pluginImpl) NewAttenuatedToken(
|
|
req *NewAttenuatedTokenRequest,
|
|
) (*UCANTokenResponse, error) {
|
|
reqBytes, err := json.Marshal(req)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
_, r, err := p.plugin.Call("new_attenuated_token", reqBytes)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
var resp UCANTokenResponse
|
|
if err := json.Unmarshal(r, &resp); err != nil {
|
|
return nil, err
|
|
}
|
|
return &resp, nil
|
|
}
|
|
|
|
// Cryptographic Operations
|
|
|
|
func (p *pluginImpl) SignData(req *SignDataRequest) (*SignDataResponse, error) {
|
|
reqBytes, err := json.Marshal(req)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
_, r, err := p.plugin.Call("sign_data", reqBytes)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
var resp SignDataResponse
|
|
if err := json.Unmarshal(r, &resp); err != nil {
|
|
return nil, err
|
|
}
|
|
return &resp, nil
|
|
}
|
|
|
|
func (p *pluginImpl) VerifyData(req *VerifyDataRequest) (*VerifyDataResponse, error) {
|
|
reqBytes, err := json.Marshal(req)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
_, r, err := p.plugin.Call("verify_data", reqBytes)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
var resp VerifyDataResponse
|
|
if err := json.Unmarshal(r, &resp); err != nil {
|
|
return nil, err
|
|
}
|
|
return &resp, nil
|
|
}
|
|
|
|
// Identity Operations
|
|
|
|
func (p *pluginImpl) GetIssuerDID() (*GetIssuerDIDResponse, error) {
|
|
_, r, err := p.plugin.Call("get_issuer_did", []byte{})
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
var resp GetIssuerDIDResponse
|
|
if err := json.Unmarshal(r, &resp); err != nil {
|
|
return nil, err
|
|
}
|
|
return &resp, nil
|
|
}
|