+
Skip to content

sonr-io/common

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

3 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

# Sonr Common Package [![Go Version](https://img.shields.io/badge/go-1.25-blue.svg)](https://golang.org) [![License](https://img.shields.io/badge/license-MIT-green.svg)](LICENSE) The `common` package provides high-level, simplified interfaces for IPFS and WebAuthn functionality, designed for easy integration into external libraries and applications within the Sonr network. ## Features - **IPFS Integration**: Simple, high-level API for storing and retrieving data from IPFS - **WebAuthn Support**: Comprehensive WebAuthn credential management and verification - **Helper Functions**: Convenient wrapper functions that abstract complexity - **Well-Tested**: Comprehensive test coverage with unit and integration tests - **Production-Ready**: Battle-tested implementations with proper error handling ## Table of Contents - [Installation](#installation) - [Quick Start](#quick-start) - [IPFS Module](#ipfs-module) - [WebAuthn Module](#webauthn-module) - [Helper Functions](#helper-functions) - [Testing](#testing) - [Examples](#examples) - [Contributing](#contributing) ## Installation ```bash go get github.com/sonr-io/common ``` ## Quick Start ### IPFS Example ```go package main import ( "fmt" "github.com/sonr-io/common" ) func main() { // Check if IPFS daemon is running if !common.IsIPFSDaemonRunning() { panic("IPFS daemon is not running") } // Store data data := []byte("Hello, IPFS!") cid, err := common.StoreData(data) if err != nil { panic(err) } fmt.Printf("Stored data with CID: %s\n", cid) // Retrieve data retrieved, err := common.RetrieveData(cid) if err != nil { panic(err) } fmt.Printf("Retrieved: %s\n", string(retrieved)) } ``` ### WebAuthn Example ```go package main import ( "fmt" "github.com/sonr-io/common" ) func main() { // Generate a challenge for WebAuthn ceremony challenge, err := common.NewChallenge() if err != nil { panic(err) } fmt.Printf("Challenge: %s\n", challenge) // Verify origin origin := "https://example.com" allowedOrigins := []string{"https://example.com", "https://app.example.com"} if err := common.VerifyOrigin(origin, allowedOrigins); err != nil { panic(err) } fmt.Println("Origin verified successfully!") } ``` ## IPFS Module The IPFS module (`ipfs/`) provides a high-level interface for interacting with IPFS nodes. ### Core Functions #### Client Management ```go // Create a new IPFS client client, err := common.NewIPFSClient() // Or use the panic version for critical scenarios client := common.MustGetIPFSClient() // Check if daemon is running if common.IsIPFSDaemonRunning() { // Daemon is available } ``` #### Data Storage ```go // Store raw bytes cid, err := common.StoreData([]byte("data")) // Store a file with metadata cid, err := common.StoreFile("document.txt", fileData) // Store multiple files as a folder files := map[string][]byte{ "file1.txt": []byte("content 1"), "file2.txt": []byte("content 2"), } cid, err := common.StoreFolder(files) ``` #### Data Retrieval ```go // Retrieve data by CID data, err := common.RetrieveData("QmXxx...") // Using client directly for advanced operations client, _ := common.NewIPFSClient() exists, err := client.Exists("QmXxx...") entries, err := client.Ls("QmXxx...") ``` ### Advanced IPFS Usage ```go import "github.com/sonr-io/common/ipfs" client, _ := ipfs.GetClient() // Pin content err := client.Pin("QmXxx...", "my-important-data") // Unpin content err := client.Unpin("QmXxx...") // Check if pinned pinned, err := client.IsPinned("ipns-name") // Get node status status, err := client.NodeStatus() fmt.Printf("Peer ID: %s\n", status.PeerID) fmt.Printf("Connected Peers: %d\n", status.ConnectedPeers) ``` ## WebAuthn Module The WebAuthn module (`webauthn/`) provides comprehensive support for WebAuthn authentication. ### Challenge Generation ```go // Generate a cryptographic challenge (32 bytes, base64url encoded) challenge, err := common.NewChallenge() // Get the standard challenge length length := common.ChallengeLength() // Returns 32 ``` ### Origin Verification ```go // Verify origin against allowed list allowedOrigins := []string{ "https://example.com", "https://app.example.com:8080", } err := common.VerifyOrigin("https://example.com", allowedOrigins) ``` ### Base64 URL Encoding ```go // Encode data to URL-safe base64 (no padding) encoded := common.EncodeBase64URL([]byte("data")) // Decode URL-safe base64 decoded, err := common.DecodeBase64URL(encoded) ``` ### Credential Management #### Credential Creation (Registration) ```go // Unmarshal credential creation response from client credData := []byte(`{"id":"...","type":"public-key",...}`) credResponse, err := common.UnmarshalCredentialCreation(credData) // Parse and validate credential creation parsedCred, err := common.ParseCredentialCreation(credData) // Marshal credential for storage jsonData, err := common.MarshalCredentialCreation(credResponse) ``` #### Credential Assertion (Authentication) ```go // Unmarshal assertion response from client assertionData := []byte(`{"id":"...","type":"public-key",...}`) assertionResponse, err := common.UnmarshalCredentialAssertion(assertionData) // Parse and validate assertion parsedAssertion, err := common.ParseCredentialAssertion(assertionData) // Marshal assertion for storage jsonData, err := common.MarshalCredentialAssertion(assertionResponse) ``` ### Advanced WebAuthn Usage ```go import "github.com/sonr-io/common/webauthn" // Create registration options options := &webauthn.PublicKeyCredentialCreationOptions{ RelyingParty: webauthn.RelyingPartyEntity{ Name: "Example Corp", ID: "example.com", }, User: webauthn.UserEntity{ ID: []byte("user-id"), Name: "user@example.com", DisplayName: "User Name", }, Challenge: challenge, Parameters: []webauthn.CredentialParameter{ {Type: webauthn.PublicKeyCredentialType, Algorithm: -7}, // ES256 }, } // Verify credential creation clientDataHash, err := parsedCred.Verify( storedChallenge, verifyUser, verifyUserPresence, relyingPartyID, rpOrigins, rpTopOrigins, rpTopOriginsVerify, metadataProvider, credParams, ) // Verify credential assertion err = parsedAssertion.Verify( storedChallenge, relyingPartyID, rpOrigins, rpTopOrigins, rpTopOriginsVerify, appID, verifyUser, verifyUserPresence, credentialPublicKey, ) ``` ## Helper Functions ### IPFS Helpers | Function | Description | |----------|-------------| | `NewIPFSClient()` | Create IPFS client with detailed error messages | | `MustGetIPFSClient()` | Panic version for critical initialization | | `StoreData(data)` | Store raw bytes and return CID | | `RetrieveData(cid)` | Retrieve content by CID | | `IsIPFSDaemonRunning()` | Check if IPFS daemon is accessible | | `StoreFile(name, data)` | Store file with metadata | | `StoreFolder(files)` | Store multiple files as a folder | ### WebAuthn Helpers | Function | Description | |----------|-------------| | `NewChallenge()` | Generate 32-byte cryptographic challenge | | `ChallengeLength()` | Get standard challenge length (32) | | `VerifyOrigin(origin, allowed)` | Verify origin against allowed list | | `EncodeBase64URL(data)` | Encode to URL-safe base64 | | `DecodeBase64URL(encoded)` | Decode URL-safe base64 | | `UnmarshalCredentialCreation(data)` | Parse credential creation response | | `MarshalCredentialCreation(ccr)` | Serialize credential creation | | `ParseCredentialCreation(data)` | Parse and validate creation response | | `UnmarshalCredentialAssertion(data)` | Parse assertion response | | `MarshalCredentialAssertion(car)` | Serialize assertion response | | `ParseCredentialAssertion(data)` | Parse and validate assertion | ## Testing The package includes a comprehensive Makefile for testing and development tasks. ### Available Make Targets ```bash # Run all tests make test # Run tests for specific modules make test-ipfs make test-webauthn # Generate coverage reports make coverage # Show coverage summary make coverage-ipfs # IPFS module coverage make coverage-webauthn # WebAuthn module coverage make coverage-all # HTML coverage report # Code quality make fmt # Format code make vet # Run go vet make lint # Run golangci-lint # Performance make bench # Run benchmarks make test-race # Run tests with race detector # Maintenance make clean # Clean test cache and coverage files make deps # Install dependencies # Quick check make check # Run fmt, vet, and test ``` ### Running Tests Manually ```bash # Run all tests go test ./... # Run tests with coverage go test -cover ./... # Run specific tests go test -v -run TestNewChallenge # Run benchmarks go test -bench=. -benchmem ./... ``` ### Test Coverage Current test coverage: - **Common package**: 49.4% - **WebAuthn module**: Comprehensive (50+ tests) - **IPFS module**: Core functionality tested ## Examples ### Complete IPFS Example ```go package main import ( "fmt" "log" "github.com/sonr-io/common" "github.com/sonr-io/common/ipfs" ) func main() { // Check daemon availability if !common.IsIPFSDaemonRunning() { log.Fatal("IPFS daemon is not running. Start it with: ipfs daemon") } // Get client for advanced operations client, err := common.NewIPFSClient() if err != nil { log.Fatal(err) } // Store a file fileData := []byte("This is my important document") cid, err := common.StoreFile("document.txt", fileData) if err != nil { log.Fatal(err) } fmt.Printf("Stored file with CID: %s\n", cid) // Pin the content if err := client.Pin(cid, "important-document"); err != nil { log.Fatal(err) } fmt.Println("Content pinned successfully") // Check if content exists exists, err := client.Exists(cid) if err != nil { log.Fatal(err) } fmt.Printf("Content exists: %v\n", exists) // Get node status status, err := client.NodeStatus() if err != nil { log.Fatal(err) } fmt.Printf("Node Status:\n") fmt.Printf(" Peer ID: %s\n", status.PeerID) fmt.Printf(" Connected Peers: %d\n", status.ConnectedPeers) fmt.Printf(" Version: %s\n", status.Version) // Store multiple files as a folder folder := map[string][]byte{ "readme.md": []byte("# Project\nThis is a test project"), "main.go": []byte("package main\n\nfunc main() {}"), "config.yml": []byte("port: 8080\nhost: localhost"), } folderCID, err := common.StoreFolder(folder) if err != nil { log.Fatal(err) } fmt.Printf("Stored folder with CID: %s\n", folderCID) // List folder contents entries, err := client.Ls(folderCID) if err != nil { log.Fatal(err) } fmt.Println("Folder contents:") for _, entry := range entries { fmt.Printf(" - %s\n", entry) } } ``` ### Complete WebAuthn Example ```go package main import ( "fmt" "log" "github.com/sonr-io/common" "github.com/sonr-io/common/webauthn" ) func main() { // Generate challenge for registration challenge, err := common.NewChallenge() if err != nil { log.Fatal(err) } fmt.Printf("Registration Challenge: %s\n", challenge) // Verify request origin origin := "https://example.com" allowedOrigins := []string{ "https://example.com", "https://app.example.com", } if err := common.VerifyOrigin(origin, allowedOrigins); err != nil { log.Fatalf("Origin verification failed: %v", err) } fmt.Println("Origin verified!") // Simulate receiving credential creation response from client // In a real scenario, this would come from the browser credentialJSON := []byte(`{ "id": "base64-credential-id", "type": "public-key", "rawId": "base64-raw-id", "response": { "clientDataJSON": "base64-client-data", "attestationObject": "base64-attestation" } }`) // Parse credential creation response credResponse, err := common.UnmarshalCredentialCreation(credentialJSON) if err != nil { log.Printf("Parse error (expected in demo): %v", err) } // For authentication, generate a new challenge authChallenge, err := common.NewChallenge() if err != nil { log.Fatal(err) } fmt.Printf("Authentication Challenge: %s\n", authChallenge) // Encode/decode example secretData := []byte("secret-session-data") encoded := common.EncodeBase64URL(secretData) fmt.Printf("Encoded: %s\n", encoded) decoded, err := common.DecodeBase64URL(encoded) if err != nil { log.Fatal(err) } fmt.Printf("Decoded: %s\n", string(decoded)) // Challenge length validation expectedLength := common.ChallengeLength() fmt.Printf("Expected challenge length: %d bytes\n", expectedLength) } ``` ## Module Structure ``` common/ � common.go # Helper functions and simplified API � common_test.go # Comprehensive test suite � Makefile # Testing and development tasks � README.md # This file � go.mod # Go module definition � ipfs/ # IPFS module � � client.go # IPFS client implementation � � file.go # File operations � � folder.go # Folder operations � webauthn/ # WebAuthn module � client.go # WebAuthn client operations � credential.go # Credential types � assertion.go # Authentication assertions � attestation.go # Registration attestation � challenge.go # Challenge generation � base64.go # Base64 URL encoding � decoder.go # JSON decoding utilities � ... # Additional WebAuthn components ``` ## Requirements - Go 1.25 or higher - IPFS daemon running (for IPFS operations) - Dependencies managed via `go.mod` ## Contributing We welcome contributions! Please follow these guidelines: 1. **Fork** the repository 2. **Create** a feature branch (`git checkout -b feature/amazing-feature`) 3. **Test** your changes (`make test`) 4. **Format** your code (`make fmt`) 5. **Commit** your changes (`git commit -m 'Add amazing feature'`) 6. **Push** to the branch (`git push origin feature/amazing-feature`) 7. **Open** a Pull Request ### Development Workflow ```bash # Install dependencies make deps # Run tests during development make test # Check code quality make check # Generate coverage report make coverage-all # Run benchmarks make bench ``` ## License This project is part of the Sonr network. See the LICENSE file for details. ## Support For issues, questions, or contributions, please visit: - GitHub: https://github.com/sonr-io/common - Documentation: https://docs.sonr.io ## Acknowledgments - Built on [Kubo](https://github.com/ipfs/kubo) for IPFS functionality - WebAuthn implementation based on [W3C WebAuthn specification](https://www.w3.org/TR/webauthn/)

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Packages

No packages published
点击 这是indexloc提供的php浏览器服务,不要输入任何密码和下载