mirror of
https://github.com/sonr-io/sonr.git
synced 2026-08-04 10:21:40 +00:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
c6bd0c9819 |
@@ -2,7 +2,6 @@
|
|||||||
name = "cz_conventional_commits"
|
name = "cz_conventional_commits"
|
||||||
tag_format = "v$version"
|
tag_format = "v$version"
|
||||||
version_scheme = "semver"
|
version_scheme = "semver"
|
||||||
version = "0.6.2"
|
version = "0.5.21"
|
||||||
update_changelog_on_bump = true
|
update_changelog_on_bump = true
|
||||||
major_version_zero = true
|
major_version_zero = true
|
||||||
changelog_file = "CHANGELOG.md"
|
|
||||||
|
|||||||
@@ -0,0 +1,17 @@
|
|||||||
|
FROM jetpackio/devbox:latest
|
||||||
|
|
||||||
|
# Installing your devbox project
|
||||||
|
WORKDIR /code
|
||||||
|
USER root:root
|
||||||
|
RUN mkdir -p /code && chown ${DEVBOX_USER}:${DEVBOX_USER} /code
|
||||||
|
USER ${DEVBOX_USER}:${DEVBOX_USER}
|
||||||
|
|
||||||
|
# Copy devbox configuration files
|
||||||
|
COPY --chown=${DEVBOX_USER}:${DEVBOX_USER} devbox.json devbox.json
|
||||||
|
COPY --chown=${DEVBOX_USER}:${DEVBOX_USER} devbox.lock devbox.lock
|
||||||
|
|
||||||
|
RUN devbox run -- echo "Installed Packages."
|
||||||
|
RUN devbox shellenv --init-hook >> ~/.profile
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -0,0 +1,89 @@
|
|||||||
|
{
|
||||||
|
"name": "Devbox Remote Container",
|
||||||
|
"build": {
|
||||||
|
"dockerfile": "./Dockerfile",
|
||||||
|
"context": ".."
|
||||||
|
},
|
||||||
|
"customizations": {
|
||||||
|
"vscode": {
|
||||||
|
"settings": {},
|
||||||
|
"extensions": [
|
||||||
|
"jetpack-io.devbox"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"remoteUser": "devbox",
|
||||||
|
"forwardPorts": [
|
||||||
|
1317,
|
||||||
|
26657,
|
||||||
|
9090,
|
||||||
|
3000,
|
||||||
|
80,
|
||||||
|
5000
|
||||||
|
],
|
||||||
|
"portsAttributes": {
|
||||||
|
"1317": {
|
||||||
|
"label": "sonr-api",
|
||||||
|
"onAutoForward": "notify"
|
||||||
|
},
|
||||||
|
"26657": {
|
||||||
|
"label": "sonr-rpc",
|
||||||
|
"onAutoForward": "notify"
|
||||||
|
},
|
||||||
|
"9090": {
|
||||||
|
"label": "sonr-grpc",
|
||||||
|
"onAutoForward": "silent"
|
||||||
|
},
|
||||||
|
"3000": {
|
||||||
|
"label": "hway-frontend",
|
||||||
|
"onAutoForward": "silent"
|
||||||
|
},
|
||||||
|
"80": {
|
||||||
|
"label": "ipfs-gateway",
|
||||||
|
"onAutoForward": "silent"
|
||||||
|
},
|
||||||
|
"5000": {
|
||||||
|
"label": "ipfs-api",
|
||||||
|
"onAutoForward": "silent"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"features": {
|
||||||
|
"ghcr.io/michidk/devcontainers-features/bun:1": {
|
||||||
|
"version": "latest"
|
||||||
|
},
|
||||||
|
"ghcr.io/cirolosapio/devcontainers-features/alpine-ohmyzsh:0": {
|
||||||
|
"version": "latest"
|
||||||
|
},
|
||||||
|
"ghcr.io/guiyomh/features/golangci-lint:0": {
|
||||||
|
"version": "latest"
|
||||||
|
},
|
||||||
|
"ghcr.io/meaningful-ooo/devcontainer-features/homebrew:2": {
|
||||||
|
"version": "latest"
|
||||||
|
},
|
||||||
|
"ghcr.io/devcontainers/features/docker-in-docker:2": {
|
||||||
|
"version": "latest"
|
||||||
|
},
|
||||||
|
"ghcr.io/devcontainers/features/github-cli:1": {
|
||||||
|
"version": "latest"
|
||||||
|
},
|
||||||
|
"ghcr.io/devcontainers/features/go:1": {
|
||||||
|
"version": "latest",
|
||||||
|
"go": "1.23"
|
||||||
|
},
|
||||||
|
"ghcr.io/devcontainers/features/rust:1": {
|
||||||
|
"version": "latest",
|
||||||
|
"rust": "1.73"
|
||||||
|
},
|
||||||
|
"ghcr.io/jpawlowski/devcontainer-features/codespaces-dotfiles:1": {
|
||||||
|
"version": "latest"
|
||||||
|
},
|
||||||
|
"ghcr.io/duduribeiro/devcontainer-features/neovim:1": {
|
||||||
|
"version": "latest"
|
||||||
|
},
|
||||||
|
"ghcr.io/dlouwers/devcontainer-features/devbox:1": {
|
||||||
|
"version": "latest"
|
||||||
|
},
|
||||||
|
"ghcr.io/devcontainers/features/sshd:1": {
|
||||||
|
"version": "latest"
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,105 @@
|
|||||||
|
You are an expert in Cosmos SDK data modeling and state management, specializing in building efficient and scalable data models using the Cosmos SDK ORM system with Protocol Buffers.
|
||||||
|
|
||||||
|
Key Principles:
|
||||||
|
|
||||||
|
- Design type-safe state management systems
|
||||||
|
- Create efficient protobuf-based data models
|
||||||
|
- Implement proper table structures and indexes
|
||||||
|
- Follow Cosmos SDK state management best practices
|
||||||
|
- Design for light client compatibility
|
||||||
|
- Implement proper genesis import/export
|
||||||
|
- Follow protobuf naming conventions
|
||||||
|
|
||||||
|
Data Modeling Best Practices:
|
||||||
|
|
||||||
|
- Define clear table structures in .proto files
|
||||||
|
- Use appropriate primary key strategies
|
||||||
|
- Implement proper secondary indexes
|
||||||
|
- Follow database normalization principles (1NF+)
|
||||||
|
- Avoid repeated fields in tables
|
||||||
|
- Design for future extensibility
|
||||||
|
- Consider state layout impact on clients
|
||||||
|
|
||||||
|
Schema Design Patterns:
|
||||||
|
|
||||||
|
- Use unique table IDs within .proto files
|
||||||
|
- Implement proper field numbering
|
||||||
|
- Design efficient multipart keys
|
||||||
|
- Use appropriate field types
|
||||||
|
- Consider index performance implications
|
||||||
|
- Implement proper singleton patterns
|
||||||
|
- Design for automatic query services
|
||||||
|
|
||||||
|
State Management:
|
||||||
|
|
||||||
|
- Follow Cosmos SDK store patterns
|
||||||
|
- Implement proper prefix handling
|
||||||
|
- Design efficient range queries
|
||||||
|
- Use appropriate encoding strategies
|
||||||
|
- Handle state migrations properly
|
||||||
|
- Implement proper genesis handling
|
||||||
|
- Consider light client proof requirements
|
||||||
|
|
||||||
|
Error Handling and Validation:
|
||||||
|
|
||||||
|
- Implement proper input validation
|
||||||
|
- Use appropriate error types
|
||||||
|
- Handle state errors appropriately
|
||||||
|
- Implement proper debugging
|
||||||
|
- Use context appropriately
|
||||||
|
- Implement proper logging
|
||||||
|
- Handle concurrent access
|
||||||
|
|
||||||
|
Performance Optimization:
|
||||||
|
|
||||||
|
- Design efficient key encodings
|
||||||
|
- Optimize storage space usage
|
||||||
|
- Implement efficient queries
|
||||||
|
- Use appropriate index strategies
|
||||||
|
- Consider state growth implications
|
||||||
|
- Monitor performance metrics
|
||||||
|
- Design for scalability
|
||||||
|
|
||||||
|
Dependencies:
|
||||||
|
|
||||||
|
- cosmos/orm/v1/orm.proto
|
||||||
|
- [google.golang.org/protobuf](http://google.golang.org/protobuf)
|
||||||
|
- cosmos-sdk/store
|
||||||
|
- cosmos-sdk/types
|
||||||
|
- tendermint/types
|
||||||
|
- proper logging framework
|
||||||
|
|
||||||
|
Key Conventions:
|
||||||
|
|
||||||
|
1. Use consistent protobuf naming
|
||||||
|
2. Implement proper documentation
|
||||||
|
3. Follow schema versioning practices
|
||||||
|
4. Use proper table ID management
|
||||||
|
5. Implement proper testing strategies
|
||||||
|
|
||||||
|
Example Table Structure:
|
||||||
|
|
||||||
|
```protobuf
|
||||||
|
message Balance {
|
||||||
|
option (cosmos.orm.v1.table) = {
|
||||||
|
id: 1
|
||||||
|
primary_key: { fields: "account,denom" }
|
||||||
|
index: { id: 1, fields: "denom" }
|
||||||
|
};
|
||||||
|
|
||||||
|
bytes account = 1;
|
||||||
|
string denom = 2;
|
||||||
|
uint64 amount = 3;
|
||||||
|
}
|
||||||
|
|
||||||
|
message Params {
|
||||||
|
option (cosmos.orm.v1.singleton) = {
|
||||||
|
id: 2
|
||||||
|
};
|
||||||
|
|
||||||
|
google.protobuf.Duration voting_period = 1;
|
||||||
|
uint64 min_threshold = 2;
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Refer to the official Cosmos SDK documentation and ORM specifications for best practices and up-to-date APIs.
|
||||||
@@ -0,0 +1,88 @@
|
|||||||
|
You are an expert in Go data modeling and PostgreSQL database design, specializing in building efficient and scalable data models using modern ORMs like GORM and SQLBoiler.
|
||||||
|
|
||||||
|
Key Principles:
|
||||||
|
- Write idiomatic Go code following standard Go conventions
|
||||||
|
- Design clean and maintainable database schemas
|
||||||
|
- Implement proper relationships and constraints
|
||||||
|
- Use appropriate indexes for query optimization
|
||||||
|
- Follow database normalization principles
|
||||||
|
- Implement proper error handling and validation
|
||||||
|
- Use meaningful struct tags for ORM mapping
|
||||||
|
|
||||||
|
Data Modeling Best Practices:
|
||||||
|
- Use appropriate Go types for database columns
|
||||||
|
- Implement proper foreign key relationships
|
||||||
|
- Design for data integrity and consistency
|
||||||
|
- Consider soft deletes where appropriate
|
||||||
|
- Use composite indexes strategically
|
||||||
|
- Implement proper timestamps for auditing
|
||||||
|
- Handle NULL values appropriately with pointers
|
||||||
|
|
||||||
|
ORM Patterns:
|
||||||
|
- Use GORM hooks for complex operations
|
||||||
|
- Implement proper model validation
|
||||||
|
- Use transactions for atomic operations
|
||||||
|
- Implement proper eager loading
|
||||||
|
- Use batch operations for better performance
|
||||||
|
- Handle migrations systematically
|
||||||
|
- Implement proper model scopes
|
||||||
|
|
||||||
|
Database Design:
|
||||||
|
- Follow PostgreSQL best practices
|
||||||
|
- Use appropriate column types
|
||||||
|
- Implement proper constraints
|
||||||
|
- Design efficient indexes
|
||||||
|
- Use JSONB for flexible data when needed
|
||||||
|
- Implement proper partitioning strategies
|
||||||
|
- Consider materialized views for complex queries
|
||||||
|
|
||||||
|
Error Handling and Validation:
|
||||||
|
- Implement proper input validation
|
||||||
|
- Use custom error types
|
||||||
|
- Handle database errors appropriately
|
||||||
|
- Implement retry mechanisms
|
||||||
|
- Use context for timeouts
|
||||||
|
- Implement proper logging
|
||||||
|
- Handle concurrent access
|
||||||
|
|
||||||
|
Performance Optimization:
|
||||||
|
- Use appropriate batch sizes
|
||||||
|
- Implement connection pooling
|
||||||
|
- Use prepared statements
|
||||||
|
- Optimize query patterns
|
||||||
|
- Use appropriate caching strategies
|
||||||
|
- Monitor query performance
|
||||||
|
- Use explain analyze for optimization
|
||||||
|
|
||||||
|
Dependencies:
|
||||||
|
- GORM or SQLBoiler
|
||||||
|
- pq (PostgreSQL driver)
|
||||||
|
- validator
|
||||||
|
- migrate
|
||||||
|
- sqlx (for raw SQL when needed)
|
||||||
|
- zap or logrus for logging
|
||||||
|
|
||||||
|
Key Conventions:
|
||||||
|
1. Use consistent naming conventions
|
||||||
|
2. Implement proper documentation
|
||||||
|
3. Follow database migration best practices
|
||||||
|
4. Use version control for schema changes
|
||||||
|
5. Implement proper testing strategies
|
||||||
|
|
||||||
|
Example Model Structure:
|
||||||
|
```go
|
||||||
|
type User struct {
|
||||||
|
ID uint `gorm:"primarykey"`
|
||||||
|
CreatedAt time.Time
|
||||||
|
UpdatedAt time.Time
|
||||||
|
DeletedAt gorm.DeletedAt `gorm:"index"`
|
||||||
|
|
||||||
|
Name string `gorm:"type:varchar(100);not null"`
|
||||||
|
Email string `gorm:"type:varchar(100);uniqueIndex;not null"`
|
||||||
|
Profile Profile
|
||||||
|
Orders []Order
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Refer to the official documentation of GORM, PostgreSQL, and Go for best practices and up-to-date APIs.
|
||||||
|
|
||||||
@@ -0,0 +1,132 @@
|
|||||||
|
You are a technical lead specializing in decentralized identity systems and security architecture, with expertise in W3C standards, Cosmos SDK, and blockchain security patterns.
|
||||||
|
|
||||||
|
Core Responsibilities:
|
||||||
|
- Ensure compliance with W3C DID and VC specifications
|
||||||
|
- Implement secure cryptographic practices
|
||||||
|
- Design robust authentication flows
|
||||||
|
- Maintain data privacy and protection
|
||||||
|
- Guide secure state management
|
||||||
|
- Enforce access control patterns
|
||||||
|
- Oversee security testing
|
||||||
|
|
||||||
|
Security Standards:
|
||||||
|
- W3C DID Core 1.0
|
||||||
|
- W3C Verifiable Credentials
|
||||||
|
- W3C WebAuthn Level 2
|
||||||
|
- OAuth 2.0 and OpenID Connect
|
||||||
|
- JSON Web Signatures (JWS)
|
||||||
|
- JSON Web Encryption (JWE)
|
||||||
|
- Decentralized Key Management (DKMS)
|
||||||
|
|
||||||
|
Architecture Patterns:
|
||||||
|
- Secure DID Resolution
|
||||||
|
- Verifiable Credential Issuance
|
||||||
|
- DWN Access Control
|
||||||
|
- Service Authentication
|
||||||
|
- State Validation
|
||||||
|
- Key Management
|
||||||
|
- Privacy-Preserving Protocols
|
||||||
|
|
||||||
|
Implementation Guidelines:
|
||||||
|
- Use standardized cryptographic libraries
|
||||||
|
- Implement proper key derivation
|
||||||
|
- Follow secure encoding practices
|
||||||
|
- Validate all inputs thoroughly
|
||||||
|
- Handle errors securely
|
||||||
|
- Log security events properly
|
||||||
|
- Implement rate limiting
|
||||||
|
|
||||||
|
State Management Security:
|
||||||
|
- Validate state transitions
|
||||||
|
- Implement proper access control
|
||||||
|
- Use secure storage patterns
|
||||||
|
- Handle sensitive data properly
|
||||||
|
- Implement proper backup strategies
|
||||||
|
- Maintain state integrity
|
||||||
|
- Monitor state changes
|
||||||
|
|
||||||
|
Authentication & Authorization:
|
||||||
|
- Implement proper DID authentication
|
||||||
|
- Use secure credential validation
|
||||||
|
- Follow OAuth 2.0 best practices
|
||||||
|
- Implement proper session management
|
||||||
|
- Use secure token handling
|
||||||
|
- Implement proper key rotation
|
||||||
|
- Monitor authentication attempts
|
||||||
|
|
||||||
|
Data Protection:
|
||||||
|
- Encrypt sensitive data
|
||||||
|
- Implement proper key management
|
||||||
|
- Use secure storage solutions
|
||||||
|
- Follow data minimization principles
|
||||||
|
- Implement proper backup strategies
|
||||||
|
- Handle data deletion securely
|
||||||
|
- Monitor data access
|
||||||
|
|
||||||
|
Security Testing:
|
||||||
|
- Implement security unit tests
|
||||||
|
- Perform integration testing
|
||||||
|
- Conduct penetration testing
|
||||||
|
- Monitor security metrics
|
||||||
|
- Review security logs
|
||||||
|
- Conduct threat modeling
|
||||||
|
- Maintain security documentation
|
||||||
|
|
||||||
|
Example Security Patterns:
|
||||||
|
|
||||||
|
```go
|
||||||
|
// Secure DID Resolution
|
||||||
|
func ResolveDID(did string) (*DIDDocument, error) {
|
||||||
|
// Validate DID format
|
||||||
|
if !ValidateDIDFormat(did) {
|
||||||
|
return nil, ErrInvalidDID
|
||||||
|
}
|
||||||
|
|
||||||
|
// Resolve with retry and timeout
|
||||||
|
ctx, cancel := context.WithTimeout(context.Background(), resolveTimeout)
|
||||||
|
defer cancel()
|
||||||
|
|
||||||
|
doc, err := resolver.ResolveWithContext(ctx, did)
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("resolution failed: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Validate document structure
|
||||||
|
if err := ValidateDIDDocument(doc); err != nil {
|
||||||
|
return nil, fmt.Errorf("invalid document: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return doc, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Secure Credential Verification
|
||||||
|
func VerifyCredential(vc *VerifiableCredential) error {
|
||||||
|
// Check expiration
|
||||||
|
if vc.IsExpired() {
|
||||||
|
return ErrCredentialExpired
|
||||||
|
}
|
||||||
|
|
||||||
|
// Verify proof
|
||||||
|
if err := vc.VerifyProof(trustRegistry); err != nil {
|
||||||
|
return fmt.Errorf("invalid proof: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Verify status
|
||||||
|
if err := vc.CheckRevocationStatus(); err != nil {
|
||||||
|
return fmt.Errorf("revocation check failed: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Security Checklist:
|
||||||
|
1. All DIDs follow W3C specification
|
||||||
|
2. Credentials implement proper proofs
|
||||||
|
3. Keys use proper derivation/rotation
|
||||||
|
4. State changes are validated
|
||||||
|
5. Access control is enforced
|
||||||
|
6. Data is properly encrypted
|
||||||
|
7. Logging captures security events
|
||||||
|
|
||||||
|
Refer to W3C specifications, Cosmos SDK security documentation, and blockchain security best practices for detailed implementation guidance.
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
# To get started with Dependabot version updates, you'll need to specify which
|
||||||
|
# package ecosystems to update and where the package manifests are located.
|
||||||
|
# Please see the documentation for all configuration options:
|
||||||
|
# https://docs.github.com/code-security/dependabot/dependabot-version-updates/configuration-options-for-the-dependabot.yml-file
|
||||||
|
|
||||||
|
version: 2
|
||||||
|
updates:
|
||||||
|
- package-ecosystem: "gomod" # See documentation for possible values
|
||||||
|
directory: "/" # Location of package manifests
|
||||||
|
schedule:
|
||||||
|
interval: "weekly"
|
||||||
@@ -1,3 +1,5 @@
|
|||||||
"feature": ["feature/*", "feat/*"]
|
"@pr/feature": ["feature/*", "feat/*"]
|
||||||
"bugfix": fix/*
|
"@pr/fix": fix/*
|
||||||
"enhancement": enhancement/*
|
"@pr/chore": chore/*
|
||||||
|
"@pr/docs": docs/*
|
||||||
|
"@pr/refactor": refactor/*
|
||||||
|
|||||||
+402
-224
@@ -1,31 +1,403 @@
|
|||||||
{
|
[
|
||||||
"scopes": [
|
{
|
||||||
"core-chain",
|
"name": "app/cosmos-sdk",
|
||||||
"core-ibc",
|
"path": "app",
|
||||||
"x-did",
|
|
||||||
"x-dwn",
|
|
||||||
"x-svc",
|
|
||||||
"security-mpc",
|
|
||||||
"security-ucan",
|
|
||||||
"security-zkp",
|
|
||||||
"ci-cd",
|
|
||||||
"dev-ops"
|
|
||||||
],
|
|
||||||
"docs": [
|
"docs": [
|
||||||
{
|
{
|
||||||
"keywords": ["github", "actions", "workflows", "syntax"],
|
"keywords": [
|
||||||
|
"module",
|
||||||
|
"cosmos"
|
||||||
|
],
|
||||||
|
"url": "https://docs.cosmos.network/v0.50/build/building-modules/module-manager"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"keywords": [
|
||||||
|
"protobuf",
|
||||||
|
"cosmos"
|
||||||
|
],
|
||||||
|
"url": "https://docs.cosmos.network/v0.50/build/building-modules/messages-and-queries"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"keywords": [
|
||||||
|
"rpc",
|
||||||
|
"protobuf",
|
||||||
|
"service",
|
||||||
|
"cosmos"
|
||||||
|
],
|
||||||
|
"url": "https://docs.cosmos.network/v0.50/build/building-modules/msg-services"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"keywords": [
|
||||||
|
"protobuf",
|
||||||
|
"rpc",
|
||||||
|
"cosmos",
|
||||||
|
"query"
|
||||||
|
],
|
||||||
|
"url": "https://docs.cosmos.network/v0.50/build/building-modules/query-services"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"keywords": [
|
||||||
|
"cosmos",
|
||||||
|
"depinject",
|
||||||
|
"sdk"
|
||||||
|
],
|
||||||
|
"url": "https://docs.cosmos.network/v0.50/build/building-modules/depinject"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "app/ibc",
|
||||||
|
"path": "app",
|
||||||
|
"docs": [
|
||||||
|
{
|
||||||
|
"keywords": [
|
||||||
|
"cosmos",
|
||||||
|
"interchain",
|
||||||
|
"accounts"
|
||||||
|
],
|
||||||
|
"url": "https://ibc.cosmos.network/v8/apps/interchain-accounts/overview/"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"keywords": [],
|
||||||
|
"url": "https://ibc.cosmos.network/v8/apps/transfer/overview/"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"keywords": [],
|
||||||
|
"url": "https://docs.osmosis.zone/osmosis-core/asset-info/"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"keywords": [],
|
||||||
|
"url": "https://docs.osmosis.zone/osmosis-core/modules/tokenfactory"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"keywords": [
|
||||||
|
"usdc",
|
||||||
|
"mint",
|
||||||
|
"cosmos",
|
||||||
|
"noble"
|
||||||
|
],
|
||||||
|
"url": "https://docs.noble.xyz/cctp/mint"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"keywords": [
|
||||||
|
"usdc"
|
||||||
|
],
|
||||||
|
"url": "https://docs.noble.xyz/cctp/mint_forward"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"keywords": [],
|
||||||
|
"url": "https://docs.evmos.org/protocol/modules/erc20"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"keywords": [],
|
||||||
|
"url": "https://docs.nomic.io/nbtc"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "crypto/mpc",
|
||||||
|
"path": "crypto/mpc",
|
||||||
|
"docs": [
|
||||||
|
{
|
||||||
|
"keywords": [
|
||||||
|
"mpc",
|
||||||
|
"wallet",
|
||||||
|
"security",
|
||||||
|
"advanced cryptography"
|
||||||
|
],
|
||||||
|
"url": "https://csrc.nist.gov/CSRC/media/Events/NTCW19/papers/paper-DKLS.pdf"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "crypto/ucan",
|
||||||
|
"path": "crypto/ucan",
|
||||||
|
"docs": [
|
||||||
|
{
|
||||||
|
"keywords": [],
|
||||||
|
"url": "https://raw.githubusercontent.com/ucan-wg/spec/refs/heads/main/README.md"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "crypto/zkp",
|
||||||
|
"path": "crypto/accumulator",
|
||||||
|
"docs": [
|
||||||
|
{
|
||||||
|
"keywords": [],
|
||||||
|
"url": "https://eprint.iacr.org/2021/1672.pdf"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "gateway/handlers",
|
||||||
|
"path": "pkg/gateway/handlers",
|
||||||
|
"docs": [
|
||||||
|
{
|
||||||
|
"keywords": [],
|
||||||
|
"url": "https://echo.labstack.com/docs/cookbook/sse"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"keywords": [],
|
||||||
|
"url": "https://echo.labstack.com/docs/cookbook/websocket"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"keywords": [],
|
||||||
|
"url": "https://echo.labstack.com/docs/cookbook/subdomain"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "gateway/database",
|
||||||
|
"path": "pkg/gateway/internal/database",
|
||||||
|
"docs": [
|
||||||
|
{
|
||||||
|
"keywords": [],
|
||||||
|
"url": "https://docs.tigerbeetle.com/coding/data-modeling"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"keywords": [],
|
||||||
|
"url": "https://docs.tigerbeetle.com/coding/two-phase-transfers"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"keywords": [],
|
||||||
|
"url": "https://docs.tigerbeetle.com/coding/reliable-transaction-submission"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"keywords": [
|
||||||
|
"currency"
|
||||||
|
],
|
||||||
|
"url": "https://docs.tigerbeetle.com/coding/recipes/currency-exchange"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"keywords": [
|
||||||
|
"balance"
|
||||||
|
],
|
||||||
|
"url": "https://docs.tigerbeetle.com/coding/recipes/balance-conditional-transfers"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"keywords": [],
|
||||||
|
"url": "https://docs.tigerbeetle.com/reference/account"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"keywords": [],
|
||||||
|
"url": "https://docs.tigerbeetle.com/reference/transfer"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"keywords": [],
|
||||||
|
"url": "https://docs.substreams.dev/documentation/consume/packages"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"keywords": [],
|
||||||
|
"url": "https://docs.substreams.dev/documentation/consume/sql/deployable-services/local-service"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"keywords": [],
|
||||||
|
"url": "https://docs.substreams.dev/tutorials/cosmos/injective/foundational"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "vault/handlers",
|
||||||
|
"path": "pkg/vault/handlers",
|
||||||
|
"docs": [
|
||||||
|
{
|
||||||
|
"keywords": [],
|
||||||
|
"url": "https://echo.labstack.com/docs/cookbook/jwt"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"keywords": [],
|
||||||
|
"url": "https://echo.labstack.com/docs/middleware/secure"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"keywords": [],
|
||||||
|
"url": "https://developer.mozilla.org/en-US/docs/Web/API/Service_Worker_API"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "vault/database",
|
||||||
|
"path": "pkg/vault/internal/database",
|
||||||
|
"docs": [
|
||||||
|
"https://dexie.org/docs/ExportImport/dexie-export-import",
|
||||||
|
"https://dexie.org/docs/API-Reference#quick-reference",
|
||||||
|
"https://templ.guide/syntax-and-usage/script-templates"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "pkl/ipfs",
|
||||||
|
"path": "pkl/ipfs.net",
|
||||||
|
"docs": [
|
||||||
|
{
|
||||||
|
"keywords": [],
|
||||||
|
"url": "https://github.com/ipfs/kubo/blob/master/docs/config.md"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"keywords": [],
|
||||||
|
"url": "https://pkl-lang.org/main/current/language-reference/index.html"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "pkl/matrix",
|
||||||
|
"path": "pkl/matrix.net",
|
||||||
|
"docs": [
|
||||||
|
{
|
||||||
|
"keywords": [],
|
||||||
|
"url": "https://element-hq.github.io/synapse/latest/usage/configuration/config_documentation.html"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"keywords": [],
|
||||||
|
"url": "https://pkl-lang.org/main/current/language-reference/index.html"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "pkl/chain",
|
||||||
|
"path": "pkl/sonr.chain",
|
||||||
|
"docs": [
|
||||||
|
"https://tutorials.cosmos.network/tutorials/9-path-to-prod/5-network.html",
|
||||||
|
"https://tutorials.cosmos.network/tutorials/9-path-to-prod/4-genesis.html",
|
||||||
|
"https://pkl-lang.org/main/current/language-reference/index.html",
|
||||||
|
"https://docs.cosmos.network/v0.50/user/run-node/run-testnet"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "pkl/hway",
|
||||||
|
"path": "pkl/sonr.hway",
|
||||||
|
"docs": [
|
||||||
|
{
|
||||||
|
"keywords": [],
|
||||||
|
"url": "https://pkl-lang.org/main/current/language-reference/index.html"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "pkl/motr",
|
||||||
|
"path": "pkl/sonr.motr",
|
||||||
|
"docs": [
|
||||||
|
{
|
||||||
|
"keywords": [],
|
||||||
|
"url": "https://pkl-lang.org/main/current/language-reference/index.html"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"keywords": [],
|
||||||
|
"url": "https://web.dev/learn/pwa/service-workers/"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"keywords": [],
|
||||||
|
"url": "https://developer.mozilla.org/en-US/docs/Web/API/Service_Worker_API"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "x/did",
|
||||||
|
"path": "proto/did",
|
||||||
|
"docs": [
|
||||||
|
{
|
||||||
|
"keywords": [],
|
||||||
|
"url": "https://docs.cosmos.network/v0.50/build/packages/orm"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"keywords": [],
|
||||||
|
"url": "https://docs.cosmos.network/v0.50/build/building-modules/protobuf-annotations"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"keywords": [],
|
||||||
|
"url": "https://docs.cosmos.network/v0.50/build/modules/auth"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"keywords": [],
|
||||||
|
"url": "https://docs.cosmos.network/v0.50/build/packages/collections"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"keywords": [],
|
||||||
|
"url": "https://docs.cosmos.network/v0.50/build/modules/bank"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "x/dwn",
|
||||||
|
"path": "proto/dwn",
|
||||||
|
"docs": [
|
||||||
|
{
|
||||||
|
"keywords": [],
|
||||||
|
"url": "https://docs.cosmos.network/v0.50/build/building-modules/protobuf-annotations"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"keywords": [],
|
||||||
|
"url": "https://docs.cosmos.network/v0.50/build/packages/orm"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"keywords": [],
|
||||||
|
"url": "https://docs.cosmos.network/v0.50/build/modules/authz"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"keywords": [],
|
||||||
|
"url": "https://docs.cosmos.network/v0.50/build/packages/collections"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"keywords": [],
|
||||||
|
"url": "https://docs.cosmos.network/v0.50/build/modules/gov"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"keywords": [],
|
||||||
|
"url": "https://docs.cosmos.network/v0.50/build/modules/staking"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "x/svc",
|
||||||
|
"path": "proto/svc",
|
||||||
|
"docs": [
|
||||||
|
{
|
||||||
|
"keywords": [],
|
||||||
|
"url": "https://docs.cosmos.network/v0.50/build/packages/collections"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"keywords": [],
|
||||||
|
"url": "https://docs.cosmos.network/v0.50/build/building-modules/protobuf-annotations"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"keywords": [],
|
||||||
|
"url": "https://docs.cosmos.network/v0.50/build/packages/orm"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"keywords": [],
|
||||||
|
"url": "https://docs.cosmos.network/v0.50/build/modules/group"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"keywords": [],
|
||||||
|
"url": "https://docs.cosmos.network/v0.50/build/modules/nft"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "repo/ci-cd",
|
||||||
|
"path": "deploy",
|
||||||
|
"docs": [
|
||||||
|
{
|
||||||
|
"keywords": [],
|
||||||
"url": "https://docs.github.com/en/actions/writing-workflows/workflow-syntax-for-github-actions"
|
"url": "https://docs.github.com/en/actions/writing-workflows/workflow-syntax-for-github-actions"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"keywords": ["cosmos", "tooling", "cosmovisor"],
|
"keywords": [],
|
||||||
"url": "https://docs.cosmos.network/v0.50/build/tooling/cosmovisor"
|
"url": "https://docs.cosmos.network/v0.50/build/tooling/cosmovisor"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"keywords": ["process-compose", "configuration"],
|
"keywords": [],
|
||||||
"url": "https://f1bonacc1.github.io/process-compose/configuration/"
|
"url": "https://f1bonacc1.github.io/process-compose/configuration/"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"keywords": ["taskfile", "cli", "reference"],
|
"keywords": [],
|
||||||
|
"url": "https://docs.nomic.io/network/ibc-relayer"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"keywords": [],
|
||||||
|
"url": "https://www.jetify.com/docs/devbox"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"keywords": [],
|
||||||
"url": "https://taskfile.dev/reference/cli"
|
"url": "https://taskfile.dev/reference/cli"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -33,217 +405,23 @@
|
|||||||
"url": "https://taskfile.dev/reference/schema"
|
"url": "https://taskfile.dev/reference/schema"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"keywords": ["taskfile", "templating", "reference"],
|
"keywords": [],
|
||||||
"url": "https://taskfile.dev/reference/templating/"
|
"url": "https://taskfile.dev/reference/templating/"
|
||||||
|
}
|
||||||
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"keywords": ["mkdocs", "material", "reference"],
|
"name": "repo/docs",
|
||||||
|
"path": "docs",
|
||||||
|
"docs": [
|
||||||
|
{
|
||||||
|
"keywords": [],
|
||||||
"url": "https://squidfunk.github.io/mkdocs-material/reference/"
|
"url": "https://squidfunk.github.io/mkdocs-material/reference/"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"keywords": ["pkl", "language", "reference"],
|
"keywords": [],
|
||||||
"url": "https://pkl-lang.org/main/current/language-reference/index.html"
|
"url": "https://github.com/mkdocs/catalog/blob/main/README.md"
|
||||||
},
|
|
||||||
{
|
|
||||||
"keywords": ["pwa", "service-workers", "web"],
|
|
||||||
"url": "https://web.dev/learn/pwa/service-workers/"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"keywords": ["service-workers", "web", "api"],
|
|
||||||
"url": "https://developer.mozilla.org/en-US/docs/Web/API/Service_Worker_API"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"keywords": ["web-authentication", "web", "api"],
|
|
||||||
"url": "https://developer.mozilla.org/en-US/docs/Web/API/Web_Authentication_API"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"keywords": ["sdk", "modules", "cosmos", "manager"],
|
|
||||||
"url": "https://docs.cosmos.network/v0.50/build/building-modules/module-manager"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"keywords": ["sdk", "modules", "cosmos", "messages", "queries"],
|
|
||||||
"url": "https://docs.cosmos.network/v0.50/build/building-modules/messages-and-queries"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"keywords": ["sdk", "modules", "messages", "service", "cosmos"],
|
|
||||||
"url": "https://docs.cosmos.network/v0.50/build/building-modules/msg-services"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"keywords": ["sdk", "modules", "services", "cosmos", "query"],
|
|
||||||
"url": "https://docs.cosmos.network/v0.50/build/building-modules/query-services"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"keywords": ["cosmos", "depinject", "modules", "sdk"],
|
|
||||||
"url": "https://docs.cosmos.network/v0.50/build/building-modules/depinject"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"keywords": ["ibc", "apps", "sdk", "interchain-accounts"],
|
|
||||||
"url": "https://ibc.cosmos.network/v8/apps/interchain-accounts/overview/"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"keywords": ["ibc", "apps", "sdk", "transfer"],
|
|
||||||
"url": "https://ibc.cosmos.network/v8/apps/transfer/overview/"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"keywords": ["osmosis", "modules", "ibc", "assets"],
|
|
||||||
"url": "https://docs.osmosis.zone/osmosis-core/asset-info/"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"keywords": ["ibc", "osmosis", "tokenfactory", "modules", "assets"],
|
|
||||||
"url": "https://docs.osmosis.zone/osmosis-core/modules/tokenfactory"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"keywords": ["ibc", "mint", "cctp", "noble", "assets"],
|
|
||||||
"url": "https://docs.noble.xyz/cctp/mint"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"keywords": ["ibc", "relayer", "nomic", "assets"],
|
|
||||||
"url": "https://docs.nomic.io/network/ibc-relayer"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"keywords": ["ibc", "cctp", "noble", "mint_forward", "assets"],
|
|
||||||
"url": "https://docs.noble.xyz/cctp/mint_forward"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"keywords": ["evmos", "erc20", "assets"],
|
|
||||||
"url": "https://docs.evmos.org/protocol/modules/erc20"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"keywords": ["nomic", "nbtc", "assets"],
|
|
||||||
"url": "https://docs.nomic.io/nbtc"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"keywords": ["mpc", "wallet", "cryptography", "capability", "invokation"],
|
|
||||||
"url": "https://csrc.nist.gov/CSRC/media/Events/NTCW19/papers/paper-DKLS.pdf"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"keywords": ["ucan", "spec", "cryptography", "authorization"],
|
|
||||||
"url": "https://raw.githubusercontent.com/ucan-wg/spec/refs/heads/main/README.md"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"keywords": ["zero-knowledge", "proofs", "cryptography", "privacy"],
|
|
||||||
"url": "https://eprint.iacr.org/2021/1672.pdf"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"keywords": ["gateway", "http", "sse"],
|
|
||||||
"url": "https://echo.labstack.com/docs/cookbook/sse"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"keywords": ["gateway", "http", "websocket"],
|
|
||||||
"url": "https://echo.labstack.com/docs/cookbook/websocket"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"keywords": ["gateway", "http", "subdomain"],
|
|
||||||
"url": "https://echo.labstack.com/docs/cookbook/subdomain"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"keywords": ["tigerbeetle", "models", "oracle"],
|
|
||||||
"url": "https://docs.tigerbeetle.com/coding/data-modeling"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"keywords": ["tigerbeetle", "two=phase", "transfers", "oracle"],
|
|
||||||
"url": "https://docs.tigerbeetle.com/coding/two-phase-transfers"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"keywords": [
|
|
||||||
"tigerbeetle",
|
|
||||||
"oracle",
|
|
||||||
"reliable",
|
|
||||||
"transaction",
|
|
||||||
"submission"
|
|
||||||
],
|
|
||||||
"url": "https://docs.tigerbeetle.com/coding/reliable-transaction-submission"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"keywords": ["currency", "exchange", "tigerbeetle", "oracle"],
|
|
||||||
"url": "https://docs.tigerbeetle.com/coding/recipes/currency-exchange"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"keywords": [
|
|
||||||
"balance",
|
|
||||||
"tigerbeetle",
|
|
||||||
"oracle",
|
|
||||||
"conditional",
|
|
||||||
"transfers"
|
|
||||||
],
|
|
||||||
"url": "https://docs.tigerbeetle.com/coding/recipes/balance-conditional-transfers"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"keywords": ["tigerbeetle", "account", "oracle"],
|
|
||||||
"url": "https://docs.tigerbeetle.com/reference/account"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"keywords": ["tigerbeetle", "transfer", "oracle"],
|
|
||||||
"url": "https://docs.tigerbeetle.com/reference/transfer"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"keywords": ["substreams", "packages", "consumer", "oracle"],
|
|
||||||
"url": "https://docs.substreams.dev/documentation/consume/packages"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"keywords": ["substreams", "deploy", "service", "oracle"],
|
|
||||||
"url": "https://docs.substreams.dev/documentation/consume/sql/deployable-services/local-service"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"keywords": ["substreams", "tutorial", "cosmos", "injective"],
|
|
||||||
"url": "https://docs.substreams.dev/tutorials/cosmos/injective/foundational"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"keywords": ["worker", "http", "jwt"],
|
|
||||||
"url": "https://echo.labstack.com/docs/cookbook/jwt"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"keywords": ["worker", "http", "secure"],
|
|
||||||
"url": "https://echo.labstack.com/docs/middleware/secure"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"keywords": ["worker", "http", "service-workers", "web", "api"],
|
|
||||||
"url": "https://developer.mozilla.org/en-US/docs/Web/API/Service_Worker_API"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"keywords": ["synapse", "matrix", "configuration", "usage"],
|
|
||||||
"url": "https://element-hq.github.io/synapse/latest/usage/configuration/config_documentation.html"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"keywords": ["cosmos", "protobuf", "orm", "sdk"],
|
|
||||||
"url": "https://docs.cosmos.network/v0.50/build/packages/orm"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"keywords": ["cosmos", "sdk", "modules", "auth"],
|
|
||||||
"url": "https://docs.cosmos.network/v0.50/build/modules/auth"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"keywords": ["cosmos", "sdk", "modules", "bank"],
|
|
||||||
"url": "https://docs.cosmos.network/v0.50/build/modules/bank"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"keywords": ["cosmos", "modules", "authz", "sdk"],
|
|
||||||
"url": "https://docs.cosmos.network/v0.50/build/modules/authz"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"keywords": ["cosmos", "protobuf", "collections", "sdk"],
|
|
||||||
"url": "https://docs.cosmos.network/v0.50/build/packages/collections"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"keywords": ["cosmos", "modules", "gov", "sdk"],
|
|
||||||
"url": "https://docs.cosmos.network/v0.50/build/modules/gov"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"keywords": ["cosmos", "modules", "staking", "sdk"],
|
|
||||||
"url": "https://docs.cosmos.network/v0.50/build/modules/staking"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"keywords": ["cosmos", "protobuf", "annotations", "sdk"],
|
|
||||||
"url": "https://docs.cosmos.network/v0.50/build/building-modules/protobuf-annotations"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"keywords": ["cosmos", "sdk", "modules", "group"],
|
|
||||||
"url": "https://docs.cosmos.network/v0.50/build/modules/group"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"keywords": ["cosmos", "sdk", "modules", "nft"],
|
|
||||||
"url": "https://docs.cosmos.network/v0.50/build/modules/nft"
|
|
||||||
}
|
}
|
||||||
],
|
]
|
||||||
"next-milestone": "34"
|
}
|
||||||
}
|
]
|
||||||
|
|||||||
Executable
+63
@@ -0,0 +1,63 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
set -e
|
||||||
|
|
||||||
|
ROOT_DIR=$(git rev-parse --show-toplevel)
|
||||||
|
|
||||||
|
# Extract scope name and path using jq, and pass it to fzf for selection
|
||||||
|
SCOPE=$(cat "$ROOT_DIR/.github/scopes.json" | jq -r '.[] | "\(.name)"' | fzf --prompt "Select scope:")
|
||||||
|
DOCS=$(cat "$ROOT_DIR/.github/scopes.json" | jq -r ".[] | select(.name == \"$SCOPE\") | .docs[].url")
|
||||||
|
|
||||||
|
# Write Title
|
||||||
|
TITLE=$(gum input --placeholder "Issue Title...")
|
||||||
|
|
||||||
|
# Write Goal
|
||||||
|
GOAL=$(mods --role "determine-issue-goal" "$SCOPE $TITLE")
|
||||||
|
|
||||||
|
# Input Requirements
|
||||||
|
REQUIREMENTS=()
|
||||||
|
while true; do
|
||||||
|
if [ ${#REQUIREMENTS[@]} -ge 2 ]; then
|
||||||
|
if ! gum confirm "Do you want to add another requirement?"; then
|
||||||
|
break
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
REQUIREMENT=$(gum input --placeholder "Add a requirement...")
|
||||||
|
if [ -n "$REQUIREMENT" ]; then
|
||||||
|
REQUIREMENTS+=("$REQUIREMENT")
|
||||||
|
else
|
||||||
|
echo "Requirement cannot be empty. Please enter a valid requirement."
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
create_body() {
|
||||||
|
echo "### Goal(s):"
|
||||||
|
echo "$GOAL"
|
||||||
|
echo "### Requirements:"
|
||||||
|
for i in "${!REQUIREMENTS[@]}"; do
|
||||||
|
echo "$(($i + 1)). ${REQUIREMENTS[$i]}"
|
||||||
|
done
|
||||||
|
echo "### Resources:"
|
||||||
|
while IFS= read -r doc; do
|
||||||
|
echo "- $doc"
|
||||||
|
done <<< "$DOCS"
|
||||||
|
}
|
||||||
|
|
||||||
|
ISSUE_BODY=$(create_body)
|
||||||
|
|
||||||
|
# Function to collect output
|
||||||
|
preview_output() {
|
||||||
|
echo "# ($SCOPE) $TITLE"
|
||||||
|
echo "$ISSUE_BODY"
|
||||||
|
}
|
||||||
|
|
||||||
|
# Display the formatted output
|
||||||
|
preview_output | gum format
|
||||||
|
|
||||||
|
# Confirm to create a GitHub issue
|
||||||
|
if gum confirm "Do you want to create a new GitHub issue with this information?"; then
|
||||||
|
# Create a new GitHub issue using the gh CLI
|
||||||
|
gh issue create --repo onsonr/sonr --title "($SCOPE) $TITLE" --body "$ISSUE_BODY"
|
||||||
|
else
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
Executable
+39
@@ -0,0 +1,39 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
|
set -e
|
||||||
|
|
||||||
|
ROOT_DIR=$(git rev-parse --show-toplevel)
|
||||||
|
|
||||||
|
# Package the PKL projects
|
||||||
|
bunx pkl project package $ROOT_DIR/pkl/*/
|
||||||
|
|
||||||
|
# Process each directory in .out
|
||||||
|
for dir in .out/*/; do
|
||||||
|
# Get the folder name and version
|
||||||
|
folder=$(basename "$dir")
|
||||||
|
version=$(echo "$folder" | grep -o '@.*' | sed 's/@//')
|
||||||
|
new_folder=$(echo "$folder" | sed 's/@[0-9.]*$//')
|
||||||
|
|
||||||
|
# Create new directory without version
|
||||||
|
mkdir -p ".out/$new_folder/$version"
|
||||||
|
|
||||||
|
# Copy contents to versioned subdirectory
|
||||||
|
cp -r "$dir"* ".out/$new_folder/$version/"
|
||||||
|
|
||||||
|
# Find and copy only .pkl files from the original package
|
||||||
|
pkg_dir="$ROOT_DIR/pkl/$new_folder"
|
||||||
|
if [ -d "$pkg_dir" ]; then
|
||||||
|
# Copy only .pkl files to version directory
|
||||||
|
find "$pkg_dir" -name "*.pkl" -exec cp {} ".out/$new_folder/$version/" \;
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Remove old versioned directory
|
||||||
|
rm -rf "$dir"
|
||||||
|
|
||||||
|
# Upload to R2 with new structure
|
||||||
|
rclone copy ".out/$new_folder" "r2:pkljar/$new_folder"
|
||||||
|
done
|
||||||
|
|
||||||
|
# Cleanup .out directory
|
||||||
|
rm -rf .out
|
||||||
|
|
||||||
@@ -1,98 +0,0 @@
|
|||||||
name: Check PR
|
|
||||||
|
|
||||||
on:
|
|
||||||
pull_request:
|
|
||||||
merge_group:
|
|
||||||
|
|
||||||
permissions:
|
|
||||||
contents: read # for TimonVS/pr-labeler-action to read config file
|
|
||||||
pull-requests: write # for TimonVS/pr-labeler-action to add labels in PR
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
verify-pr:
|
|
||||||
name: Test Lints
|
|
||||||
if: github.event_name == 'pull_request'
|
|
||||||
permissions:
|
|
||||||
contents: read # for TimonVS/pr-labeler-action to read config file
|
|
||||||
pull-requests: write # for TimonVS/pr-labeler-action to add labels in PR
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
steps:
|
|
||||||
- uses: actions/checkout@v4
|
|
||||||
with:
|
|
||||||
fetch-depth: 0 # Required to fetch all history for merging
|
|
||||||
|
|
||||||
- uses: TimonVS/pr-labeler-action@v5
|
|
||||||
with:
|
|
||||||
repo-token: ${{ secrets.GITHUB_TOKEN }}
|
|
||||||
configuration-path: .github/pr-labeler.yml # optional, .github/pr-labeler.yml is the default value
|
|
||||||
- name: Trunk Check
|
|
||||||
uses: trunk-io/trunk-action@v1
|
|
||||||
|
|
||||||
test-builds:
|
|
||||||
if: github.event_name == 'pull_request'
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
name: Test Builds
|
|
||||||
steps:
|
|
||||||
- name: Checkout repository
|
|
||||||
uses: actions/checkout@v4
|
|
||||||
with:
|
|
||||||
repository: onsonr/sonr
|
|
||||||
fetch-depth: 0
|
|
||||||
fetch-tags: true
|
|
||||||
|
|
||||||
- uses: actions/setup-go@v5
|
|
||||||
with:
|
|
||||||
go-version: "1.23"
|
|
||||||
check-latest: true
|
|
||||||
- name: Run Sonrd Build
|
|
||||||
run: make build
|
|
||||||
|
|
||||||
test-unit:
|
|
||||||
if: github.event_name == 'pull_request'
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
name: Test Unit
|
|
||||||
steps:
|
|
||||||
- name: Checkout repository
|
|
||||||
uses: actions/checkout@v4
|
|
||||||
with:
|
|
||||||
repository: onsonr/sonr
|
|
||||||
fetch-depth: 0
|
|
||||||
fetch-tags: true
|
|
||||||
|
|
||||||
- uses: actions/setup-go@v5
|
|
||||||
with:
|
|
||||||
go-version: "1.23"
|
|
||||||
check-latest: true
|
|
||||||
- run: make test-unit
|
|
||||||
|
|
||||||
validate-release:
|
|
||||||
if: github.event_name == 'merge_group' || github.event_name == 'pull_request'
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
name: Test Version
|
|
||||||
steps:
|
|
||||||
- name: Checkout repository
|
|
||||||
uses: actions/checkout@v4
|
|
||||||
with:
|
|
||||||
repository: onsonr/sonr
|
|
||||||
fetch-depth: 0
|
|
||||||
fetch-tags: true
|
|
||||||
|
|
||||||
- uses: actions/setup-go@v5
|
|
||||||
with:
|
|
||||||
go-version: "1.23"
|
|
||||||
check-latest: true
|
|
||||||
|
|
||||||
- name: Install Python
|
|
||||||
uses: actions/setup-python@v5
|
|
||||||
with:
|
|
||||||
python-version: "3.x"
|
|
||||||
|
|
||||||
- name: Version Check
|
|
||||||
run: make validate-tag
|
|
||||||
env:
|
|
||||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
|
||||||
|
|
||||||
- name: Check GoReleaser Config
|
|
||||||
run: make release-check
|
|
||||||
env:
|
|
||||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
|
||||||
@@ -0,0 +1,34 @@
|
|||||||
|
name: Deploy Networks
|
||||||
|
on:
|
||||||
|
workflow_dispatch:
|
||||||
|
push:
|
||||||
|
tags:
|
||||||
|
- "v*"
|
||||||
|
branches:
|
||||||
|
- develop
|
||||||
|
|
||||||
|
permissions:
|
||||||
|
contents: write
|
||||||
|
issues: write
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
reboot-devnet:
|
||||||
|
name: Devnet Deploy
|
||||||
|
runs-on: goliath
|
||||||
|
environment: "Devnet"
|
||||||
|
steps:
|
||||||
|
- name: Checkout code
|
||||||
|
uses: actions/checkout@v4
|
||||||
|
with:
|
||||||
|
fetch-depth: 0
|
||||||
|
branch: develop
|
||||||
|
|
||||||
|
- name: Stop Existing Network
|
||||||
|
continue-on-error: true
|
||||||
|
run: |
|
||||||
|
make stop-uds
|
||||||
|
make clean
|
||||||
|
|
||||||
|
- name: Start Updated Network
|
||||||
|
run: |
|
||||||
|
make start-uds
|
||||||
@@ -0,0 +1,19 @@
|
|||||||
|
name: PR Labeler
|
||||||
|
on:
|
||||||
|
pull_request:
|
||||||
|
types: [opened]
|
||||||
|
|
||||||
|
permissions:
|
||||||
|
contents: read
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
pr-labeler:
|
||||||
|
permissions:
|
||||||
|
contents: read # for TimonVS/pr-labeler-action to read config file
|
||||||
|
pull-requests: write # for TimonVS/pr-labeler-action to add labels in PR
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- uses: TimonVS/pr-labeler-action@v5
|
||||||
|
with:
|
||||||
|
repo-token: ${{ secrets.GITHUB_TOKEN }}
|
||||||
|
configuration-path: .github/pr-labeler.yml # optional, .github/pr-labeler.yml is the default value
|
||||||
@@ -0,0 +1,33 @@
|
|||||||
|
name: Publish Docs via GitHub Pages
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
branches:
|
||||||
|
- main
|
||||||
|
- master
|
||||||
|
- develop
|
||||||
|
paths:
|
||||||
|
- "docs/**"
|
||||||
|
|
||||||
|
permissions:
|
||||||
|
contents: write
|
||||||
|
jobs:
|
||||||
|
deploy:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v4
|
||||||
|
- name: Configure Git Credentials
|
||||||
|
run: |
|
||||||
|
git config user.name github-actions[bot]
|
||||||
|
git config user.email 41898282+github-actions[bot]@users.noreply.github.com
|
||||||
|
- uses: actions/setup-python@v5
|
||||||
|
with:
|
||||||
|
python-version: 3.x
|
||||||
|
- run: echo "cache_id=$(date --utc '+%V')" >> $GITHUB_ENV
|
||||||
|
- uses: actions/cache@v4
|
||||||
|
with:
|
||||||
|
key: mkdocs-material-${{ env.cache_id }}
|
||||||
|
path: .cache
|
||||||
|
restore-keys: |
|
||||||
|
mkdocs-material-
|
||||||
|
- run: pip install mkdocs-material
|
||||||
|
- run: cd docs && mkdocs gh-deploy --force
|
||||||
@@ -1,124 +0,0 @@
|
|||||||
name: Post Merge
|
|
||||||
on:
|
|
||||||
pull_request:
|
|
||||||
types: [closed]
|
|
||||||
push:
|
|
||||||
tags:
|
|
||||||
- v*
|
|
||||||
branches:
|
|
||||||
- main
|
|
||||||
|
|
||||||
permissions:
|
|
||||||
contents: write
|
|
||||||
issues: write
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
sync-version:
|
|
||||||
name: Sync Version
|
|
||||||
if: startsWith(github.ref, 'refs/tags/')
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
steps:
|
|
||||||
- name: Checkout
|
|
||||||
uses: actions/checkout@v4
|
|
||||||
with:
|
|
||||||
branch: main
|
|
||||||
fetch-depth: 0
|
|
||||||
ssh-key: "${{ secrets.COMMIT_KEY }}"
|
|
||||||
fetch-tags: true
|
|
||||||
|
|
||||||
- name: Update Version
|
|
||||||
run: |
|
|
||||||
# Get tag without 'v' prefix
|
|
||||||
TAG_VERSION=${GITHUB_REF#refs/tags/v}
|
|
||||||
|
|
||||||
# Checkout main branch
|
|
||||||
git fetch origin main
|
|
||||||
git checkout main
|
|
||||||
|
|
||||||
# Update version in .cz.toml
|
|
||||||
sed -i "s/^version = \".*\"/version = \"$TAG_VERSION\"/" .cz.toml
|
|
||||||
|
|
||||||
# Configure git
|
|
||||||
git config --local user.email "github-actions[bot]@users.noreply.github.com"
|
|
||||||
git config --local user.name "github-actions[bot]"
|
|
||||||
|
|
||||||
# Commit and push if there are changes
|
|
||||||
if git diff --quiet; then
|
|
||||||
echo "Version already synchronized"
|
|
||||||
else
|
|
||||||
git add .cz.toml
|
|
||||||
git commit -m "chore: sync version to ${TAG_VERSION} [skip ci]"
|
|
||||||
git push origin main
|
|
||||||
fi
|
|
||||||
|
|
||||||
bump-version:
|
|
||||||
name: Cz Bump
|
|
||||||
if: |
|
|
||||||
github.event.pull_request.merged == true &&
|
|
||||||
github.event.pull_request.user.login != 'dependabot[bot]' &&
|
|
||||||
github.event.pull_request.user.login != 'dependabot-preview[bot]'
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
steps:
|
|
||||||
- name: Check out
|
|
||||||
uses: actions/checkout@v4
|
|
||||||
with:
|
|
||||||
fetch-depth: 0
|
|
||||||
ssh-key: "${{ secrets.COMMIT_KEY }}"
|
|
||||||
|
|
||||||
- name: Create bump and changelog
|
|
||||||
uses: commitizen-tools/commitizen-action@master
|
|
||||||
with:
|
|
||||||
push: false
|
|
||||||
increment: patch
|
|
||||||
branch: main
|
|
||||||
|
|
||||||
- name: Push using ssh
|
|
||||||
run: |
|
|
||||||
git push origin main --tags
|
|
||||||
|
|
||||||
new-release:
|
|
||||||
name: Create Release
|
|
||||||
needs: [sync-version]
|
|
||||||
if: startsWith(github.ref, 'refs/tags/')
|
|
||||||
permissions: write-all
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
steps:
|
|
||||||
- name: Checkout repository
|
|
||||||
uses: actions/checkout@v4
|
|
||||||
with:
|
|
||||||
repository: onsonr/sonr
|
|
||||||
fetch-depth: 0
|
|
||||||
fetch-tags: true
|
|
||||||
|
|
||||||
- uses: actions/setup-go@v5
|
|
||||||
with:
|
|
||||||
go-version: "1.23"
|
|
||||||
check-latest: true
|
|
||||||
|
|
||||||
- name: Login to Docker Hub
|
|
||||||
uses: docker/login-action@v3
|
|
||||||
with:
|
|
||||||
username: ${{ secrets.DOCKER_USERNAME }}
|
|
||||||
password: ${{ secrets.DOCKER_PASSWORD }}
|
|
||||||
|
|
||||||
- name: Fetch Release Date
|
|
||||||
run: |
|
|
||||||
echo "RELEASE_DATE=$(date +%Y).$(date +%V).$(date +%u)" >> $GITHUB_ENV
|
|
||||||
|
|
||||||
- name: Run GoReleaser
|
|
||||||
uses: goreleaser/goreleaser-action@v6
|
|
||||||
if: startsWith(github.ref, 'refs/tags/')
|
|
||||||
with:
|
|
||||||
version: "~> v2"
|
|
||||||
args: release --clean
|
|
||||||
env:
|
|
||||||
GITHUB_TOKEN: ${{ secrets.GH_RELEASER_TOKEN }}
|
|
||||||
GITHUB_PERSONAL_AUTH_TOKEN: ${{ secrets.GH_RELEASER_TOKEN }}
|
|
||||||
DOCKER_USERNAME: ${{ secrets.DOCKER_USERNAME }}
|
|
||||||
DOCKER_PASSWORD: ${{ secrets.DOCKER_PASSWORD }}
|
|
||||||
TELEGRAM_TOKEN: ${{ secrets.TELEGRAM_TOKEN }}
|
|
||||||
REDDIT_APP_ID: ${{ secrets.REDDIT_APP_ID }}
|
|
||||||
REDDIT_SECRET: ${{ secrets.REDDIT_SECRET }}
|
|
||||||
REDDIT_USERNAME: ${{ secrets.REDDIT_USERNAME }}
|
|
||||||
REDDIT_PASSWORD: ${{ secrets.REDDIT_PASSWORD }}
|
|
||||||
RELEASE_DATE: ${{ env.RELEASE_DATE }}
|
|
||||||
@@ -0,0 +1,25 @@
|
|||||||
|
name: Publish Versioned Assets
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
branches:
|
||||||
|
- develop
|
||||||
|
|
||||||
|
permissions:
|
||||||
|
contents: write
|
||||||
|
issues: write
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
buf_push_core:
|
||||||
|
name: Publish to buf.build/onsonr/sonr
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
# Run `git checkout`
|
||||||
|
- uses: actions/checkout@v3
|
||||||
|
# Install the `buf` CLI
|
||||||
|
- uses: bufbuild/buf-setup-action@v1
|
||||||
|
# Push only the Input in `proto` to the BSR
|
||||||
|
- uses: bufbuild/buf-push-action@v1
|
||||||
|
continue-on-error: true
|
||||||
|
with:
|
||||||
|
input: proto
|
||||||
|
buf_token: ${{ secrets.BUF_TOKEN }}
|
||||||
@@ -1,66 +0,0 @@
|
|||||||
name: Post Release
|
|
||||||
on:
|
|
||||||
release:
|
|
||||||
types: [published]
|
|
||||||
|
|
||||||
permissions:
|
|
||||||
contents: write
|
|
||||||
issues: write
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
buf_push:
|
|
||||||
name: Publish Protobufs
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
steps:
|
|
||||||
# Run `git checkout`
|
|
||||||
- uses: actions/checkout@v4
|
|
||||||
# Install the `buf` CLI
|
|
||||||
- uses: bufbuild/buf-setup-action@v1
|
|
||||||
# Push only the Input in `proto` to the BSR
|
|
||||||
- uses: bufbuild/buf-push-action@v1
|
|
||||||
continue-on-error: true
|
|
||||||
with:
|
|
||||||
input: proto
|
|
||||||
buf_token: ${{ secrets.BUF_TOKEN }}
|
|
||||||
|
|
||||||
container-push:
|
|
||||||
name: Publish Docker Images
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
steps:
|
|
||||||
- uses: actions/checkout@v4
|
|
||||||
|
|
||||||
- name: Login to Docker Hub
|
|
||||||
uses: docker/login-action@v3
|
|
||||||
with:
|
|
||||||
username: ${{ secrets.DOCKER_USERNAME }}
|
|
||||||
password: ${{ secrets.DOCKER_PASSWORD }}
|
|
||||||
|
|
||||||
- name: Build and push
|
|
||||||
uses: docker/build-push-action@v5
|
|
||||||
with:
|
|
||||||
context: .
|
|
||||||
platforms: linux/amd64,linux/arm64
|
|
||||||
push: true
|
|
||||||
tags: ghcr.io/onsonr/sonr:latest
|
|
||||||
|
|
||||||
docs-push:
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
name: Publish Tech Docs
|
|
||||||
steps:
|
|
||||||
- uses: actions/checkout@v4
|
|
||||||
- name: Configure Git Credentials
|
|
||||||
run: |
|
|
||||||
git config user.name github-actions[bot]
|
|
||||||
git config user.email 41898282+github-actions[bot]@users.noreply.github.com
|
|
||||||
- uses: actions/setup-python@v5
|
|
||||||
with:
|
|
||||||
python-version: 3.x
|
|
||||||
- run: echo "cache_id=$(date --utc '+%V')" >> $GITHUB_ENV
|
|
||||||
- uses: actions/cache@v4
|
|
||||||
with:
|
|
||||||
key: mkdocs-material-${{ env.cache_id }}
|
|
||||||
path: .cache
|
|
||||||
restore-keys: |
|
|
||||||
mkdocs-material-
|
|
||||||
- run: pip install mkdocs-material
|
|
||||||
- run: mkdocs gh-deploy --force
|
|
||||||
@@ -1,17 +1,30 @@
|
|||||||
name: Merge Group
|
name: Run Tests
|
||||||
|
|
||||||
on:
|
on:
|
||||||
|
pull_request:
|
||||||
merge_group:
|
merge_group:
|
||||||
|
|
||||||
permissions:
|
|
||||||
contents: read # for TimonVS/pr-labeler-action to read config file
|
|
||||||
pull-requests: write # for TimonVS/pr-labeler-action to add labels in PR
|
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
|
test-unit:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
name: Run Unit Tests
|
||||||
|
steps:
|
||||||
|
- name: Checkout repository
|
||||||
|
uses: actions/checkout@v4
|
||||||
|
with:
|
||||||
|
repository: onsonr/sonr
|
||||||
|
fetch-depth: 0
|
||||||
|
fetch-tags: true
|
||||||
|
|
||||||
|
- uses: actions/setup-go@v5
|
||||||
|
with:
|
||||||
|
go-version: "1.23"
|
||||||
|
check-latest: true
|
||||||
|
- run: make test-unit
|
||||||
|
|
||||||
test-race:
|
test-race:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
if: github.event_name == 'merge_group'
|
name: Run Race Tests
|
||||||
name: Test Race
|
|
||||||
continue-on-error: true
|
continue-on-error: true
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout repository
|
- name: Checkout repository
|
||||||
@@ -29,8 +42,8 @@ jobs:
|
|||||||
|
|
||||||
test-cover:
|
test-cover:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
if: github.event_name == 'merge_group'
|
name: Run Coverage Tests
|
||||||
name: Test Coverage
|
continue-on-error: true
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout repository
|
- name: Checkout repository
|
||||||
uses: actions/checkout@v4
|
uses: actions/checkout@v4
|
||||||
@@ -44,25 +57,3 @@ jobs:
|
|||||||
go-version: "1.23"
|
go-version: "1.23"
|
||||||
check-latest: true
|
check-latest: true
|
||||||
- run: make test-cover
|
- run: make test-cover
|
||||||
|
|
||||||
test-release:
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
name: Test Release
|
|
||||||
if: github.event_name == 'merge_group'
|
|
||||||
steps:
|
|
||||||
- name: Checkout repository
|
|
||||||
uses: actions/checkout@v4
|
|
||||||
with:
|
|
||||||
repository: onsonr/sonr
|
|
||||||
fetch-depth: 0
|
|
||||||
fetch-tags: true
|
|
||||||
|
|
||||||
- uses: actions/setup-go@v5
|
|
||||||
with:
|
|
||||||
go-version: "1.23"
|
|
||||||
check-latest: true
|
|
||||||
|
|
||||||
- name: Release Dry Run
|
|
||||||
run: make release-dry
|
|
||||||
env:
|
|
||||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
|
||||||
@@ -0,0 +1,49 @@
|
|||||||
|
name: Scheduled Release
|
||||||
|
|
||||||
|
on:
|
||||||
|
workflow_dispatch:
|
||||||
|
push:
|
||||||
|
tags:
|
||||||
|
- v*
|
||||||
|
|
||||||
|
permissions:
|
||||||
|
contents: write
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
goreleaser:
|
||||||
|
name: Release motr, sonrd, and DWN
|
||||||
|
permissions: write-all
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- name: Checkout repository
|
||||||
|
uses: actions/checkout@v4
|
||||||
|
with:
|
||||||
|
repository: onsonr/sonr
|
||||||
|
fetch-depth: 0
|
||||||
|
fetch-tags: true
|
||||||
|
|
||||||
|
- uses: actions/setup-go@v5
|
||||||
|
with:
|
||||||
|
go-version: "1.23"
|
||||||
|
check-latest: true
|
||||||
|
|
||||||
|
- name: Login to Docker Hub
|
||||||
|
uses: docker/login-action@v3
|
||||||
|
with:
|
||||||
|
username: ${{ secrets.DOCKER_USERNAME }}
|
||||||
|
password: ${{ secrets.DOCKER_PASSWORD }}
|
||||||
|
|
||||||
|
- name: Release
|
||||||
|
uses: goreleaser/goreleaser-action@v6
|
||||||
|
with:
|
||||||
|
distribution: goreleaser-pro
|
||||||
|
version: latest
|
||||||
|
args: release --clean
|
||||||
|
env:
|
||||||
|
GITHUB_TOKEN: ${{ secrets.GH_RELEASER_TOKEN }}
|
||||||
|
GORELEASER_KEY: ${{ secrets.GORELEASER_KEY }}
|
||||||
|
GITHUB_PERSONAL_AUTH_TOKEN: ${{ secrets.GH_RELEASER_TOKEN }}
|
||||||
|
DOCKER_USERNAME: ${{ secrets.DOCKER_USERNAME }}
|
||||||
|
DOCKER_PASSWORD: ${{ secrets.DOCKER_PASSWORD }}
|
||||||
|
TELEGRAM_TOKEN: ${{ secrets.TELEGRAM_TOKEN }}
|
||||||
|
CLOUDSMITH_TOKEN: ${{ secrets.CLOUDSMITH_TOKEN }}
|
||||||
@@ -0,0 +1,39 @@
|
|||||||
|
name: Update Version
|
||||||
|
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
branches:
|
||||||
|
- master
|
||||||
|
|
||||||
|
permissions:
|
||||||
|
contents: write
|
||||||
|
pull-requests: write
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
run-tests:
|
||||||
|
name: "Run tests"
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v4
|
||||||
|
- uses: actions/setup-go@v5
|
||||||
|
with:
|
||||||
|
go-version: "1.23"
|
||||||
|
check-latest: true
|
||||||
|
- name: Run tests
|
||||||
|
run: make test
|
||||||
|
|
||||||
|
bump-version:
|
||||||
|
needs: [run-tests]
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
name: "Bump Version"
|
||||||
|
if: ${{ !startsWith(github.event.head_commit.message, 'bump:') }}
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v4
|
||||||
|
with:
|
||||||
|
token: ${{ secrets.GITHUB_TOKEN }}
|
||||||
|
fetch-depth: 0
|
||||||
|
- name: Create bump and changelog
|
||||||
|
uses: commitizen-tools/commitizen-action@master
|
||||||
|
with:
|
||||||
|
github_token: ${{ secrets.GITHUB_TOKEN }}
|
||||||
|
increment: "PATCH"
|
||||||
+4
-14
@@ -1,9 +1,4 @@
|
|||||||
# Aider related generated files
|
|
||||||
.aider-context
|
|
||||||
|
|
||||||
# Binaries
|
# Binaries
|
||||||
.task
|
|
||||||
no
|
|
||||||
.data
|
.data
|
||||||
schemas
|
schemas
|
||||||
*.db
|
*.db
|
||||||
@@ -65,7 +60,10 @@ override.tf.json
|
|||||||
|
|
||||||
.terraformrc
|
.terraformrc
|
||||||
terraform.rc
|
terraform.rc
|
||||||
flake.lock
|
|
||||||
|
Taskfile.yml
|
||||||
|
|
||||||
|
!deploy/**/Taskfile.yml
|
||||||
|
|
||||||
# Misc
|
# Misc
|
||||||
.DS_Store
|
.DS_Store
|
||||||
@@ -91,7 +89,6 @@ buildenv*
|
|||||||
node_modules
|
node_modules
|
||||||
cmd/gateway/node_modules
|
cmd/gateway/node_modules
|
||||||
pkg/nebula/node_modules
|
pkg/nebula/node_modules
|
||||||
configs/logs.json
|
|
||||||
|
|
||||||
mprocs.yaml
|
mprocs.yaml
|
||||||
build
|
build
|
||||||
@@ -101,11 +98,4 @@ sonr.wiki
|
|||||||
!buf.lock
|
!buf.lock
|
||||||
|
|
||||||
.air.toml
|
.air.toml
|
||||||
mprocs.yaml
|
|
||||||
mprocs.log
|
|
||||||
tools-stamp
|
|
||||||
sonr.log
|
|
||||||
deploy/conf
|
|
||||||
|
|
||||||
interchaintest-downloader
|
|
||||||
.haptic
|
|
||||||
|
|||||||
+93
-11
@@ -2,14 +2,12 @@
|
|||||||
version: 2
|
version: 2
|
||||||
project_name: sonr
|
project_name: sonr
|
||||||
|
|
||||||
before:
|
|
||||||
hooks:
|
|
||||||
- echo "Release date is {{ .Env.RELEASE_DATE }}"
|
|
||||||
|
|
||||||
builds:
|
builds:
|
||||||
- id: sonr
|
- id: sonr
|
||||||
main: ./cmd/sonrd
|
main: ./cmd/sonrd
|
||||||
binary: sonrd
|
binary: sonrd
|
||||||
|
builder: go
|
||||||
|
gobinary: go
|
||||||
mod_timestamp: "{{ .CommitTimestamp }}"
|
mod_timestamp: "{{ .CommitTimestamp }}"
|
||||||
goos:
|
goos:
|
||||||
- linux
|
- linux
|
||||||
@@ -32,22 +30,83 @@ builds:
|
|||||||
- netgo
|
- netgo
|
||||||
- ledger
|
- ledger
|
||||||
|
|
||||||
|
- id: hway
|
||||||
|
main: ./cmd/hway
|
||||||
|
binary: hway
|
||||||
|
builder: go
|
||||||
|
gobinary: go
|
||||||
|
goos:
|
||||||
|
- linux
|
||||||
|
- darwin
|
||||||
|
goarch:
|
||||||
|
- amd64
|
||||||
|
- arm64
|
||||||
|
mod_timestamp: "{{ .CommitTimestamp }}"
|
||||||
|
flags:
|
||||||
|
- -mod=readonly
|
||||||
|
- -trimpath
|
||||||
|
goamd64:
|
||||||
|
- v1
|
||||||
|
tags:
|
||||||
|
- netgo
|
||||||
|
ldflags:
|
||||||
|
- -X main.version={{.Version}}
|
||||||
|
- -X main.commit={{.Commit}}
|
||||||
|
- -X main.date={{.Date}}
|
||||||
archives:
|
archives:
|
||||||
- id: sonr
|
- id: sonr
|
||||||
builds: [sonr]
|
builds: [sonr]
|
||||||
name_template: >-
|
name_template: >-
|
||||||
sonr_{{ .Os }}_{{- if eq .Arch "amd64" }}x86_64
|
sonr_{{ .Version }}_
|
||||||
|
{{- title .Os }}_{{- if eq .Arch "amd64" }}x86_64
|
||||||
{{- else if eq .Arch "386" }}i386
|
{{- else if eq .Arch "386" }}i386
|
||||||
{{- else }}{{ .Arch }}{{ end }}
|
{{- else }}{{ .Arch }}{{ end }}
|
||||||
format: tar.gz
|
format: tar.gz
|
||||||
files:
|
files:
|
||||||
- src: README*
|
- src: README*
|
||||||
|
- src: CHANGELOG*
|
||||||
|
wrap_in_directory: true
|
||||||
|
|
||||||
|
- id: hway
|
||||||
|
builds: [hway]
|
||||||
|
name_template: >-
|
||||||
|
hway_{{ .Version }}_
|
||||||
|
{{- title .Os }}_{{- if eq .Arch "amd64" }}x86_64
|
||||||
|
{{- else if eq .Arch "386" }}i386
|
||||||
|
{{- else }}{{ .Arch }}{{ end }}
|
||||||
|
format: tar.gz
|
||||||
|
files:
|
||||||
|
- src: README*
|
||||||
|
- src: CHANGELOG*
|
||||||
wrap_in_directory: true
|
wrap_in_directory: true
|
||||||
|
|
||||||
nfpms:
|
nfpms:
|
||||||
|
- id: hway
|
||||||
|
package_name: hway
|
||||||
|
file_name_template: "{{ .ConventionalFileName }}"
|
||||||
|
builds: [hway]
|
||||||
|
vendor: Sonr
|
||||||
|
homepage: "https://onsonr.dev"
|
||||||
|
maintainer: "Sonr <support@onsonr.dev>"
|
||||||
|
description: "Sonr Highway is a decentralized, permissionless, and censorship-resistant identity network proxy."
|
||||||
|
license: "Apache 2.0"
|
||||||
|
formats:
|
||||||
|
- rpm
|
||||||
|
- deb
|
||||||
|
- apk
|
||||||
|
dependencies:
|
||||||
|
- ipfs
|
||||||
|
contents:
|
||||||
|
- src: README*
|
||||||
|
dst: /usr/share/doc/hway
|
||||||
|
bindir: /usr/bin
|
||||||
|
section: net
|
||||||
|
priority: optional
|
||||||
|
# Add these lines to match build config
|
||||||
|
|
||||||
- id: sonr
|
- id: sonr
|
||||||
package_name: sonrd
|
package_name: sonrd
|
||||||
file_name_template: "sonrd_{{ .Os }}_{{ .Arch }}{{ .ConventionalExtension }}"
|
file_name_template: "{{ .ConventionalFileName }}"
|
||||||
builds: [sonr]
|
builds: [sonr]
|
||||||
vendor: Sonr
|
vendor: Sonr
|
||||||
homepage: "https://onsonr.dev"
|
homepage: "https://onsonr.dev"
|
||||||
@@ -69,6 +128,23 @@ nfpms:
|
|||||||
# Add these lines to match build config
|
# Add these lines to match build config
|
||||||
|
|
||||||
brews:
|
brews:
|
||||||
|
- name: hway
|
||||||
|
ids: [hway]
|
||||||
|
commit_author:
|
||||||
|
name: goreleaserbot
|
||||||
|
email: bot@goreleaser.com
|
||||||
|
directory: Formula
|
||||||
|
caveats: "Run a local hway node and access it with the hway proxy"
|
||||||
|
homepage: "https://onsonr.dev"
|
||||||
|
description: "Sonr is a decentralized, permissionless, and censorship-resistant identity network."
|
||||||
|
dependencies:
|
||||||
|
- name: ipfs
|
||||||
|
repository:
|
||||||
|
owner: onsonr
|
||||||
|
name: homebrew-tap
|
||||||
|
branch: master
|
||||||
|
token: "{{ .Env.GITHUB_PERSONAL_AUTH_TOKEN }}"
|
||||||
|
|
||||||
- name: sonr
|
- name: sonr
|
||||||
ids: [sonr]
|
ids: [sonr]
|
||||||
commit_author:
|
commit_author:
|
||||||
@@ -76,7 +152,7 @@ brews:
|
|||||||
email: bot@goreleaser.com
|
email: bot@goreleaser.com
|
||||||
directory: Formula
|
directory: Formula
|
||||||
caveats: "Run a local sonr node and access it with the hway proxy"
|
caveats: "Run a local sonr node and access it with the hway proxy"
|
||||||
homepage: "https://onson.dev"
|
homepage: "https://onsonr.dev"
|
||||||
description: "Sonr is a decentralized, permissionless, and censorship-resistant identity network."
|
description: "Sonr is a decentralized, permissionless, and censorship-resistant identity network."
|
||||||
dependencies:
|
dependencies:
|
||||||
- name: ipfs
|
- name: ipfs
|
||||||
@@ -90,15 +166,21 @@ release:
|
|||||||
github:
|
github:
|
||||||
owner: onsonr
|
owner: onsonr
|
||||||
name: sonr
|
name: sonr
|
||||||
name_template: "{{ .Tag }} | {{ .Env.RELEASE_DATE }}"
|
name_template: "Release {{.Version}}"
|
||||||
draft: false
|
draft: false
|
||||||
replace_existing_draft: true
|
replace_existing_draft: true
|
||||||
replace_existing_artifacts: true
|
replace_existing_artifacts: true
|
||||||
extra_files:
|
extra_files:
|
||||||
|
- glob: ./CHANGELOG*
|
||||||
- glob: ./README*
|
- glob: ./README*
|
||||||
- glob: ./scripts/install.sh
|
|
||||||
- glob: ./scripts/test_node.sh
|
cloudsmiths:
|
||||||
- glob: ./scripts/test_ics_node.sh
|
- organization: sonr
|
||||||
|
repository: sonr
|
||||||
|
distributions:
|
||||||
|
deb: "ubuntu/xenial"
|
||||||
|
alpine: "alpine/v3.8"
|
||||||
|
rpm: "el/7"
|
||||||
|
|
||||||
announce:
|
announce:
|
||||||
telegram:
|
telegram:
|
||||||
|
|||||||
@@ -1,9 +0,0 @@
|
|||||||
*out
|
|
||||||
*logs
|
|
||||||
*actions
|
|
||||||
*notifications
|
|
||||||
*tools
|
|
||||||
plugins
|
|
||||||
user_trunk.yaml
|
|
||||||
user.yaml
|
|
||||||
tmp
|
|
||||||
@@ -1,27 +0,0 @@
|
|||||||
linters:
|
|
||||||
disable:
|
|
||||||
- unused # Disables unreachable code checking
|
|
||||||
|
|
||||||
run:
|
|
||||||
# Exclude test files from analysis
|
|
||||||
tests: false
|
|
||||||
|
|
||||||
# Define which files and directories to exclude
|
|
||||||
issues:
|
|
||||||
exclude-rules:
|
|
||||||
# Exclude all test files
|
|
||||||
- path: _test\.go
|
|
||||||
linters:
|
|
||||||
- all
|
|
||||||
|
|
||||||
# Exclude specific directories
|
|
||||||
exclude-dirs:
|
|
||||||
- api/did/v1
|
|
||||||
- api/dwn/v1
|
|
||||||
- api/svc/v1
|
|
||||||
- internal
|
|
||||||
|
|
||||||
# Exclude specific file patterns
|
|
||||||
exclude-files:
|
|
||||||
- ".*\\.pb\\.go$"
|
|
||||||
- ".*_templ\\.go$"
|
|
||||||
@@ -1,4 +0,0 @@
|
|||||||
# Following source doesn't work in most setups
|
|
||||||
ignored:
|
|
||||||
- SC1090
|
|
||||||
- SC1091
|
|
||||||
@@ -1,2 +0,0 @@
|
|||||||
# Prettier friendly markdownlint config (all formatting rules disabled)
|
|
||||||
extends: markdownlint/style/prettier
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
edition = "2021"
|
|
||||||
@@ -1,7 +0,0 @@
|
|||||||
enable=all
|
|
||||||
source-path=SCRIPTDIR
|
|
||||||
disable=SC2154
|
|
||||||
|
|
||||||
# If you're having issues with shellcheck following source, disable the errors via:
|
|
||||||
# disable=SC1090
|
|
||||||
# disable=SC1091
|
|
||||||
@@ -1,7 +0,0 @@
|
|||||||
rules:
|
|
||||||
quoted-strings:
|
|
||||||
required: only-when-needed
|
|
||||||
extra-allowed: ["{|}"]
|
|
||||||
key-duplicates: {}
|
|
||||||
octal-values:
|
|
||||||
forbid-implicit-octal: true
|
|
||||||
@@ -1,41 +0,0 @@
|
|||||||
# This file controls the behavior of Trunk: https://docs.trunk.io/cli
|
|
||||||
# To learn more about the format of this file, see https://docs.trunk.io/reference/trunk-yaml
|
|
||||||
version: 0.1
|
|
||||||
cli:
|
|
||||||
version: 1.22.8
|
|
||||||
# Trunk provides extensibility via plugins. (https://docs.trunk.io/plugins)
|
|
||||||
plugins:
|
|
||||||
sources:
|
|
||||||
- id: trunk
|
|
||||||
ref: v1.6.6
|
|
||||||
uri: https://github.com/trunk-io/plugins
|
|
||||||
# Many linters and tools depend on runtimes - configure them here. (https://docs.trunk.io/runtimes)
|
|
||||||
runtimes:
|
|
||||||
enabled:
|
|
||||||
- go@1.23.0
|
|
||||||
- node@18.20.5
|
|
||||||
- python@3.10.8
|
|
||||||
# This is the section where you manage your linters. (https://docs.trunk.io/check/configuration)
|
|
||||||
lint:
|
|
||||||
enabled:
|
|
||||||
- actionlint@1.7.6
|
|
||||||
- checkov@3.2.347
|
|
||||||
- clippy@1.65.0
|
|
||||||
- git-diff-check
|
|
||||||
- gofmt@1.20.4
|
|
||||||
- golangci-lint@1.62.2
|
|
||||||
- hadolint@2.12.1-beta
|
|
||||||
# - markdownlint@0.43.0
|
|
||||||
- osv-scanner@1.9.2
|
|
||||||
- prettier@3.4.2
|
|
||||||
- rustfmt@1.65.0
|
|
||||||
# - shellcheck@0.10.0
|
|
||||||
# - shfmt@3.6.0
|
|
||||||
- taplo@0.9.3
|
|
||||||
- trufflehog@3.88.0
|
|
||||||
actions:
|
|
||||||
enabled:
|
|
||||||
- trunk-announce
|
|
||||||
- trunk-check-pre-push
|
|
||||||
- trunk-fmt-pre-commit
|
|
||||||
- trunk-upgrade-available
|
|
||||||
+16
-103
@@ -1,98 +1,7 @@
|
|||||||
## v0.6.2 (2025-01-06)
|
## v0.5.21 (2024-12-11)
|
||||||
|
|
||||||
### Refactor
|
|
||||||
|
|
||||||
- simplify release process and remove unnecessary tasks
|
|
||||||
- remove devcontainer configuration
|
|
||||||
|
|
||||||
## v0.6.1 (2024-12-30)
|
|
||||||
|
|
||||||
### Feat
|
### Feat
|
||||||
|
|
||||||
- convert highway sink schema to SQLite
|
|
||||||
- **scopes**: add Web Authentication API documentation
|
|
||||||
- add install script for Sonr binaries
|
|
||||||
|
|
||||||
### Fix
|
|
||||||
|
|
||||||
- Handle only 500 errors in ErrorHandler
|
|
||||||
- Return only on 500 errors in error handler
|
|
||||||
- update sqlc queries to match schema and use SQLite conventions
|
|
||||||
- Rename DecodeWasmContext to decodeWasmContext
|
|
||||||
- resolve lint errors in WASMMiddleware function
|
|
||||||
- prevent automatic version bumps from dependabot
|
|
||||||
- correct merge workflow to increment patch version
|
|
||||||
|
|
||||||
### Refactor
|
|
||||||
|
|
||||||
- remove outdated scopes
|
|
||||||
- remove unnecessary seed message
|
|
||||||
- Update sqlc queries to match schema and sqlite conventions
|
|
||||||
- move gateway and vault components to new locations
|
|
||||||
- **scopes**: simplify scopes.json structure
|
|
||||||
- **scopes**: rename and reorganize scopes
|
|
||||||
- **api**: remove unused Allocate RPC from Query service
|
|
||||||
- remove postgresql tasks
|
|
||||||
- remove unused AI PR body generator step
|
|
||||||
- simplify Taskfile and remove unused chain configurations
|
|
||||||
|
|
||||||
## v0.6.0 (2024-12-24)
|
|
||||||
|
|
||||||
### Feat
|
|
||||||
|
|
||||||
- Add option to create draft issues from the new-issue script
|
|
||||||
|
|
||||||
### Refactor
|
|
||||||
|
|
||||||
- rename DID, DWN, and SVC modules to core-dids, core-dwns, and core-svcs respectively
|
|
||||||
- rename MsgInitialize to MsgSpawn for clarity
|
|
||||||
- rename scopes in .github/scopes.json for better clarity
|
|
||||||
|
|
||||||
## v0.5.28 (2024-12-22)
|
|
||||||
|
|
||||||
### Fix
|
|
||||||
|
|
||||||
- Sink
|
|
||||||
|
|
||||||
### Refactor
|
|
||||||
|
|
||||||
- update testnet configuration
|
|
||||||
- optimize GitHub Actions workflow triggers (#1204)
|
|
||||||
- Move embed
|
|
||||||
|
|
||||||
## v0.1.6 (2024-12-16)
|
|
||||||
|
|
||||||
## v0.5.26 (2024-12-13)
|
|
||||||
|
|
||||||
## v0.5.25 (2024-12-11)
|
|
||||||
|
|
||||||
### Feat
|
|
||||||
|
|
||||||
- enable GoReleaser releases on tags and snapshots
|
|
||||||
- automate release on tag and workflow dispatch
|
|
||||||
|
|
||||||
### Fix
|
|
||||||
|
|
||||||
- Correct regular expression for version tags in release workflow
|
|
||||||
|
|
||||||
## v0.5.24 (2024-12-11)
|
|
||||||
|
|
||||||
### Feat
|
|
||||||
|
|
||||||
- prevent duplicate releases
|
|
||||||
|
|
||||||
## v0.5.23 (2024-12-11)
|
|
||||||
|
|
||||||
### Refactor
|
|
||||||
|
|
||||||
- rename scheduled release workflow to versioned release
|
|
||||||
- remove changelog from release artifacts
|
|
||||||
|
|
||||||
## v0.5.22 (2024-12-11)
|
|
||||||
|
|
||||||
### Feat
|
|
||||||
|
|
||||||
- Implement passkey-based authentication and registration flow
|
|
||||||
- allow manual triggering of deployment workflow
|
- allow manual triggering of deployment workflow
|
||||||
- add start-tui command for interactive mode
|
- add start-tui command for interactive mode
|
||||||
- add coin selection and update passkey input in registration form
|
- add coin selection and update passkey input in registration form
|
||||||
@@ -255,6 +164,7 @@
|
|||||||
|
|
||||||
- update file paths in error messages
|
- update file paths in error messages
|
||||||
- update intro video modal script
|
- update intro video modal script
|
||||||
|
- include assets generation in wasm build
|
||||||
|
|
||||||
### Refactor
|
### Refactor
|
||||||
|
|
||||||
@@ -268,10 +178,6 @@
|
|||||||
|
|
||||||
## v0.5.16 (2024-10-21)
|
## v0.5.16 (2024-10-21)
|
||||||
|
|
||||||
### Fix
|
|
||||||
|
|
||||||
- include assets generation in wasm build
|
|
||||||
|
|
||||||
## v0.5.15 (2024-10-21)
|
## v0.5.15 (2024-10-21)
|
||||||
|
|
||||||
## v0.5.14 (2024-10-21)
|
## v0.5.14 (2024-10-21)
|
||||||
@@ -405,6 +311,7 @@
|
|||||||
- update issue templates for better clarity
|
- update issue templates for better clarity
|
||||||
- add issue templates for tracking and task issues
|
- add issue templates for tracking and task issues
|
||||||
- add issue templates for bug report and tracking
|
- add issue templates for bug report and tracking
|
||||||
|
- introduce docker-compose based setup
|
||||||
|
|
||||||
### Refactor
|
### Refactor
|
||||||
|
|
||||||
@@ -415,7 +322,6 @@
|
|||||||
|
|
||||||
### Feat
|
### Feat
|
||||||
|
|
||||||
- introduce docker-compose based setup
|
|
||||||
- add hway and sonr processes to dev environment
|
- add hway and sonr processes to dev environment
|
||||||
|
|
||||||
## v0.5.5 (2024-10-03)
|
## v0.5.5 (2024-10-03)
|
||||||
@@ -464,6 +370,14 @@
|
|||||||
|
|
||||||
## v0.4.5 (2024-10-02)
|
## v0.4.5 (2024-10-02)
|
||||||
|
|
||||||
|
### Fix
|
||||||
|
|
||||||
|
- use correct secret for docker login
|
||||||
|
|
||||||
|
## v0.4.4 (2024-10-02)
|
||||||
|
|
||||||
|
## v0.4.3 (2024-10-02)
|
||||||
|
|
||||||
### Feat
|
### Feat
|
||||||
|
|
||||||
- **release**: add docker images for sonrd and motr
|
- **release**: add docker images for sonrd and motr
|
||||||
@@ -475,7 +389,6 @@
|
|||||||
|
|
||||||
### Fix
|
### Fix
|
||||||
|
|
||||||
- use correct secret for docker login
|
|
||||||
- **layout**: add missing favicon
|
- **layout**: add missing favicon
|
||||||
- **hero**: Use hx-swap for primary button to prevent flicker
|
- **hero**: Use hx-swap for primary button to prevent flicker
|
||||||
|
|
||||||
@@ -504,6 +417,9 @@
|
|||||||
- add DWN resolver field
|
- add DWN resolver field
|
||||||
- add stats section to homepage
|
- add stats section to homepage
|
||||||
- implement hero section using Pkl
|
- implement hero section using Pkl
|
||||||
|
- add PKL schema for message formats
|
||||||
|
- add Homebrew tap for sonr
|
||||||
|
- update release workflow to use latest tag
|
||||||
|
|
||||||
### Fix
|
### Fix
|
||||||
|
|
||||||
@@ -522,14 +438,13 @@
|
|||||||
- rename motrd to motr
|
- rename motrd to motr
|
||||||
- update hero image dimensions
|
- update hero image dimensions
|
||||||
- move nebula configuration to static file
|
- move nebula configuration to static file
|
||||||
|
- rename buf-publish.yml to publish-assets.yml
|
||||||
|
- remove unused field from
|
||||||
|
|
||||||
## v0.4.0 (2024-09-30)
|
## v0.4.0 (2024-09-30)
|
||||||
|
|
||||||
### Feat
|
### Feat
|
||||||
|
|
||||||
- add PKL schema for message formats
|
|
||||||
- add Homebrew tap for sonr
|
|
||||||
- update release workflow to use latest tag
|
|
||||||
- **dwn**: add wasm build for dwn
|
- **dwn**: add wasm build for dwn
|
||||||
- add macaroon and oracle genesis states
|
- add macaroon and oracle genesis states
|
||||||
- add scheduled binary release workflow
|
- add scheduled binary release workflow
|
||||||
@@ -544,8 +459,6 @@
|
|||||||
### Refactor
|
### Refactor
|
||||||
|
|
||||||
- remove old changelog entries
|
- remove old changelog entries
|
||||||
- rename buf-publish.yml to publish-assets.yml
|
|
||||||
- remove unused field from
|
|
||||||
- remove unnecessary checkout in scheduled-release workflow
|
- remove unnecessary checkout in scheduled-release workflow
|
||||||
- rename build ID to sonr
|
- rename build ID to sonr
|
||||||
- remove unnecessary release existence check
|
- remove unnecessary release existence check
|
||||||
|
|||||||
+38
-3
@@ -1,4 +1,41 @@
|
|||||||
FROM golang:1.23-alpine AS go-builder
|
FROM jetpackio/devbox:latest AS sonrvm
|
||||||
|
|
||||||
|
# Installing your devbox project
|
||||||
|
WORKDIR /code
|
||||||
|
USER root:root
|
||||||
|
|
||||||
|
RUN mkdir -p /code && chown ${DEVBOX_USER}:${DEVBOX_USER} /code
|
||||||
|
|
||||||
|
USER ${DEVBOX_USER}:${DEVBOX_USER}
|
||||||
|
|
||||||
|
COPY --chown=${DEVBOX_USER}:${DEVBOX_USER} devbox.json devbox.json
|
||||||
|
COPY --chown=${DEVBOX_USER}:${DEVBOX_USER} process-compose.yaml process-compose.yaml
|
||||||
|
|
||||||
|
RUN devbox run -- echo "Installed Packages."
|
||||||
|
|
||||||
|
ENTRYPOINT ["devbox", "run"]
|
||||||
|
|
||||||
|
# --------------------------------------------------------
|
||||||
|
FROM jetpackio/devbox:latest AS sonr-runner
|
||||||
|
|
||||||
|
WORKDIR /code
|
||||||
|
USER root:root
|
||||||
|
|
||||||
|
RUN mkdir -p /code && chown ${DEVBOX_USER}:${DEVBOX_USER} /code
|
||||||
|
|
||||||
|
USER ${DEVBOX_USER}:${DEVBOX_USER}
|
||||||
|
|
||||||
|
COPY --chown=${DEVBOX_USER}:${DEVBOX_USER} devbox.json devbox.json
|
||||||
|
COPY --chown=${DEVBOX_USER}:${DEVBOX_USER} process-compose.yaml process-compose.yaml
|
||||||
|
COPY --chown=${DEVBOX_USER}:${DEVBOX_USER} . .
|
||||||
|
|
||||||
|
RUN devbox run -- echo "Installed Packages."
|
||||||
|
|
||||||
|
RUN git config --global --add safe.directory /code
|
||||||
|
ENTRYPOINT ["devbox", "run", "testnet"]
|
||||||
|
|
||||||
|
# --------------------------------------------------------
|
||||||
|
FROM golang:1.22-alpine AS go-builder
|
||||||
|
|
||||||
SHELL ["/bin/sh", "-ecuxo", "pipefail"]
|
SHELL ["/bin/sh", "-ecuxo", "pipefail"]
|
||||||
|
|
||||||
@@ -31,8 +68,6 @@ RUN LEDGER_ENABLED=false BUILD_TAGS=muslc LINK_STATICALLY=true make build \
|
|||||||
# --------------------------------------------------------
|
# --------------------------------------------------------
|
||||||
FROM debian:11-slim
|
FROM debian:11-slim
|
||||||
|
|
||||||
LABEL org.opencontainers.image.source https://github.com/onsonr/sonr
|
|
||||||
|
|
||||||
COPY --from=go-builder /code/build/sonrd /usr/bin/sonrd
|
COPY --from=go-builder /code/build/sonrd /usr/bin/sonrd
|
||||||
|
|
||||||
# Install dependencies for Debian 11
|
# Install dependencies for Debian 11
|
||||||
|
|||||||
@@ -8,16 +8,14 @@ SDK_PACK := $(shell go list -m github.com/cosmos/cosmos-sdk | sed 's/ /\@/g')
|
|||||||
BINDIR ?= $(GOPATH)/bin
|
BINDIR ?= $(GOPATH)/bin
|
||||||
SIMAPP = ./app
|
SIMAPP = ./app
|
||||||
|
|
||||||
# Fetch from env
|
PC_PORT_NUM=42069
|
||||||
RELEASE_DATE ?= $(shell date +%Y).$(shell date +%V).$(shell date +%u)
|
PC_LOG_FILE=./sonr.log
|
||||||
VERSION ?= $(shell echo $(shell git describe --tags) | sed 's/^v//')
|
PC_SOCKET_PATH=/tmp/sonr-net.sock
|
||||||
COMMIT ?= $(shell git log -1 --format='%H')
|
|
||||||
OS ?= $(shell uname -s)
|
|
||||||
ROOT ?= $(shell git rev-parse --show-toplevel)
|
|
||||||
|
|
||||||
# for dockerized protobuf tools
|
# for dockerized protobuf tools
|
||||||
DOCKER := $(shell which docker)
|
DOCKER := $(shell which docker)
|
||||||
HTTPS_GIT := github.com/onsonr/sonr.git
|
HTTPS_GIT := github.com/onsonr/sonr.git
|
||||||
|
PROCESS_COMPOSE := $(shell which process-compose)
|
||||||
|
|
||||||
export GO111MODULE = on
|
export GO111MODULE = on
|
||||||
|
|
||||||
@@ -77,6 +75,8 @@ ldflags := $(strip $(ldflags))
|
|||||||
BUILD_FLAGS := -tags "$(build_tags_comma_sep)" -ldflags '$(ldflags)' -trimpath
|
BUILD_FLAGS := -tags "$(build_tags_comma_sep)" -ldflags '$(ldflags)' -trimpath
|
||||||
|
|
||||||
# The below include contains the tools and runsim targets.
|
# The below include contains the tools and runsim targets.
|
||||||
|
include contrib/devtools/Makefile
|
||||||
|
|
||||||
all: install lint test
|
all: install lint test
|
||||||
|
|
||||||
build: go.sum
|
build: go.sum
|
||||||
@@ -87,12 +87,6 @@ else
|
|||||||
go build -mod=readonly $(BUILD_FLAGS) -o build/sonrd ./cmd/sonrd
|
go build -mod=readonly $(BUILD_FLAGS) -o build/sonrd ./cmd/sonrd
|
||||||
endif
|
endif
|
||||||
|
|
||||||
build-motr: go.sum
|
|
||||||
GOOS=js GOARCH=wasm go build -o static/wasm/app.wasm ./cmd/motr/main.go
|
|
||||||
|
|
||||||
build-hway: go.sum
|
|
||||||
go build -o build/hway ./cmd/hway
|
|
||||||
|
|
||||||
build-windows-client: go.sum
|
build-windows-client: go.sum
|
||||||
GOOS=windows GOARCH=amd64 go build -mod=readonly $(BUILD_FLAGS) -o build/sonrd.exe ./cmd/sonrd
|
GOOS=windows GOARCH=amd64 go build -mod=readonly $(BUILD_FLAGS) -o build/sonrd.exe ./cmd/sonrd
|
||||||
|
|
||||||
@@ -106,17 +100,8 @@ endif
|
|||||||
install: go.sum
|
install: go.sum
|
||||||
go install -mod=readonly $(BUILD_FLAGS) ./cmd/sonrd
|
go install -mod=readonly $(BUILD_FLAGS) ./cmd/sonrd
|
||||||
|
|
||||||
install-hway: go.sum
|
|
||||||
go install -mod=readonly ./cmd/hway
|
|
||||||
|
|
||||||
release: fmt-date
|
|
||||||
@go install github.com/goreleaser/goreleaser/v2@latest
|
|
||||||
RELEASE_DATE=$(RELEASE_DATE) goreleaser release --clean
|
|
||||||
|
|
||||||
|
|
||||||
########################################
|
########################################
|
||||||
### Tools & dependencies
|
### Tools & dependencies
|
||||||
########################################
|
|
||||||
|
|
||||||
go-mod-cache: go.sum
|
go-mod-cache: go.sum
|
||||||
@echo "--> Download go modules to local cache"
|
@echo "--> Download go modules to local cache"
|
||||||
@@ -142,9 +127,12 @@ clean:
|
|||||||
distclean: clean
|
distclean: clean
|
||||||
rm -rf vendor/
|
rm -rf vendor/
|
||||||
|
|
||||||
|
init-env:
|
||||||
|
@echo "Installing process-compose"
|
||||||
|
sh scripts/init_env.sh
|
||||||
|
|
||||||
########################################
|
########################################
|
||||||
### Testing
|
### Testing
|
||||||
########################################
|
|
||||||
|
|
||||||
test: test-unit
|
test: test-unit
|
||||||
test-all: test-race test-cover test-system
|
test-all: test-race test-cover test-system
|
||||||
@@ -196,6 +184,7 @@ format: format-tools
|
|||||||
|
|
||||||
mod-tidy:
|
mod-tidy:
|
||||||
go mod tidy
|
go mod tidy
|
||||||
|
cd interchaintest && go mod tidy
|
||||||
|
|
||||||
.PHONY: format-tools lint format mod-tidy
|
.PHONY: format-tools lint format mod-tidy
|
||||||
|
|
||||||
@@ -313,41 +302,71 @@ testnet-basic: setup-testnet
|
|||||||
sh-testnet: mod-tidy
|
sh-testnet: mod-tidy
|
||||||
CHAIN_ID="sonr-testnet-1" BLOCK_TIME="1000ms" CLEAN=true sh scripts/test_node.sh
|
CHAIN_ID="sonr-testnet-1" BLOCK_TIME="1000ms" CLEAN=true sh scripts/test_node.sh
|
||||||
|
|
||||||
.PHONY: setup-testnet set-testnet-configs testnet testnet-basic sh-testnet dop-testnet
|
.PHONY: setup-testnet set-testnet-configs testnet testnet-basic sh-testnet
|
||||||
|
|
||||||
###############################################################################
|
###############################################################################
|
||||||
### extra utils ###
|
### generation ###
|
||||||
|
###############################################################################
|
||||||
|
.PHONY: gen-pkl gen-templ
|
||||||
|
|
||||||
|
gen-pkl: init-env
|
||||||
|
pkl-gen-go pkl/sonr.orm/UCAN.pkl
|
||||||
|
pkl-gen-go pkl/sonr.orm/Models.pkl
|
||||||
|
pkl-gen-go pkl/sonr.conf/Hway.pkl
|
||||||
|
pkl-gen-go pkl/sonr.conf/Motr.pkl
|
||||||
|
|
||||||
|
gen-templ: init-env
|
||||||
|
templ generate
|
||||||
|
|
||||||
|
|
||||||
|
###############################################################################
|
||||||
|
### custom builds ###
|
||||||
|
###############################################################################
|
||||||
|
.PHONY: build-motr build-hway logs-hway logs-sonr
|
||||||
|
|
||||||
|
build-motr:
|
||||||
|
GOOS=js GOARCH=wasm go build -o static/wasm/app.wasm ./cmd/motr/main.go
|
||||||
|
|
||||||
|
build-hway: gen-templ
|
||||||
|
go build -o build/hway ./cmd/hway
|
||||||
|
|
||||||
|
logs-hway: init-env
|
||||||
|
bin/process-compose process logs hway --port $(PC_PORT_NUM) --follow
|
||||||
|
|
||||||
|
logs-sonr: init-env
|
||||||
|
bin/process-compose process logs sonr --port $(PC_PORT_NUM) --follow
|
||||||
|
|
||||||
|
###############################################################################
|
||||||
|
### Network Start/Stop ###
|
||||||
###############################################################################
|
###############################################################################
|
||||||
|
|
||||||
push-docker:
|
.PHONY: deploy start start-tui start-uds stop stop-uds restart status
|
||||||
@docker build -t ghcr.io/onsonr/sonr:latest .
|
|
||||||
@docker tag ghcr.io/onsonr/sonr:latest ghcr.io/onsonr/sonr:$(VERSION)
|
|
||||||
@docker push ghcr.io/onsonr/sonr:latest
|
|
||||||
@docker push ghcr.io/onsonr/sonr:$(VERSION)
|
|
||||||
|
|
||||||
status:
|
start: build-hway init-env
|
||||||
@gh run ls -L 3
|
bin/process-compose up --port $(PC_PORT_NUM) --log-file $(PC_LOG_FILE) --detached -f deploy/process-compose.yaml
|
||||||
@gum format -- "# Sonr ($OS-$VERSION)" "- ($(COMMIT)) $ROOT" "- $(RELEASE_DATE)"
|
|
||||||
@sleep 3
|
|
||||||
|
|
||||||
release:
|
start-tui: build-hway init-env
|
||||||
@go install github.com/goreleaser/goreleaser/v2@latest
|
bin/process-compose up --port $(PC_PORT_NUM) --log-file $(PC_LOG_FILE) -f deploy/process-compose.yaml
|
||||||
@RELEASE_DATE=$(RELEASE_DATE) goreleaser release --clean
|
|
||||||
|
|
||||||
release-dry:
|
start-uds: build-hway init-env
|
||||||
@go install github.com/goreleaser/goreleaser/v2@latest
|
bin/process-compose up --use-uds --unix-socket $(PC_SOCKET_PATH) --log-file $(PC_LOG_FILE) --detached -f deploy/process-compose.yaml
|
||||||
@RELEASE_DATE=$(RELEASE_DATE) goreleaser release --snapshot --clean --skip=publish
|
|
||||||
|
|
||||||
release-check:
|
stop: init-env
|
||||||
@go install github.com/goreleaser/goreleaser/v2@latest
|
bin/process-compose down --port $(PC_PORT_NUM)
|
||||||
@RELEASE_DATE=$(RELEASE_DATE) goreleaser check
|
|
||||||
|
|
||||||
validate-tag:
|
stop-uds: init-env
|
||||||
@sh ./scripts/validate_tag.sh
|
bin/process-compose down --use-uds --unix-socket $(PC_SOCKET_PATH)
|
||||||
|
|
||||||
|
status: init-env
|
||||||
|
bin/process-compose project state --port $(PC_PORT_NUM)
|
||||||
###############################################################################
|
###############################################################################
|
||||||
### help ###
|
### help ###
|
||||||
###############################################################################
|
###############################################################################
|
||||||
|
|
||||||
|
deploy:
|
||||||
|
cd ./proto && bunx buf dep update && bunx buf build && bunx buf push
|
||||||
|
sh ./.github/scripts/upload_cdn.sh
|
||||||
|
|
||||||
help:
|
help:
|
||||||
@echo "Usage: make <target>"
|
@echo "Usage: make <target>"
|
||||||
@echo ""
|
@echo ""
|
||||||
@@ -359,5 +378,7 @@ help:
|
|||||||
@echo " sh-testnet : Shell local devnet"
|
@echo " sh-testnet : Shell local devnet"
|
||||||
@echo " ictest-basic : Basic end-to-end test"
|
@echo " ictest-basic : Basic end-to-end test"
|
||||||
@echo " ictest-ibc : IBC end-to-end test"
|
@echo " ictest-ibc : IBC end-to-end test"
|
||||||
|
@echo " templ : Generate templ files"
|
||||||
|
@echo " vault : Build vault.wasm"
|
||||||
|
|
||||||
.PHONY: help
|
.PHONY: help
|
||||||
|
|||||||
@@ -37,3 +37,4 @@ Sonr would not have been possible without the direct and indirect support of the
|
|||||||
- [Forum](https://github.com/onsonr/sonr/discussions)
|
- [Forum](https://github.com/onsonr/sonr/discussions)
|
||||||
- [Issues](https://github.com/onsonr/sonr/issues)
|
- [Issues](https://github.com/onsonr/sonr/issues)
|
||||||
- [Twitter](https://sonr.io/twitter)
|
- [Twitter](https://sonr.io/twitter)
|
||||||
|
- [Dev Chat](https://sonr.io/discord)
|
||||||
|
|||||||
+427
-2515
File diff suppressed because it is too large
Load Diff
+2428
-758
File diff suppressed because it is too large
Load Diff
+3251
-26
File diff suppressed because it is too large
Load Diff
@@ -20,6 +20,9 @@ const _ = grpc.SupportPackageIsVersion9
|
|||||||
|
|
||||||
const (
|
const (
|
||||||
Query_Params_FullMethodName = "/dwn.v1.Query/Params"
|
Query_Params_FullMethodName = "/dwn.v1.Query/Params"
|
||||||
|
Query_Schema_FullMethodName = "/dwn.v1.Query/Schema"
|
||||||
|
Query_Allocate_FullMethodName = "/dwn.v1.Query/Allocate"
|
||||||
|
Query_Sync_FullMethodName = "/dwn.v1.Query/Sync"
|
||||||
)
|
)
|
||||||
|
|
||||||
// QueryClient is the client API for Query service.
|
// QueryClient is the client API for Query service.
|
||||||
@@ -30,6 +33,15 @@ const (
|
|||||||
type QueryClient interface {
|
type QueryClient interface {
|
||||||
// Params queries all parameters of the module.
|
// Params queries all parameters of the module.
|
||||||
Params(ctx context.Context, in *QueryParamsRequest, opts ...grpc.CallOption) (*QueryParamsResponse, error)
|
Params(ctx context.Context, in *QueryParamsRequest, opts ...grpc.CallOption) (*QueryParamsResponse, error)
|
||||||
|
// Schema queries the DID document by its id. And returns the required PKL
|
||||||
|
// information
|
||||||
|
Schema(ctx context.Context, in *QuerySchemaRequest, opts ...grpc.CallOption) (*QuerySchemaResponse, error)
|
||||||
|
// Allocate initializes a Target Vault available for claims with a compatible
|
||||||
|
// Authentication mechanism. The default authentication mechanism is WebAuthn.
|
||||||
|
Allocate(ctx context.Context, in *QueryAllocateRequest, opts ...grpc.CallOption) (*QueryAllocateResponse, error)
|
||||||
|
// Sync queries the DID document by its id. And returns the required PKL
|
||||||
|
// information
|
||||||
|
Sync(ctx context.Context, in *QuerySyncRequest, opts ...grpc.CallOption) (*QuerySyncResponse, error)
|
||||||
}
|
}
|
||||||
|
|
||||||
type queryClient struct {
|
type queryClient struct {
|
||||||
@@ -50,6 +62,36 @@ func (c *queryClient) Params(ctx context.Context, in *QueryParamsRequest, opts .
|
|||||||
return out, nil
|
return out, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (c *queryClient) Schema(ctx context.Context, in *QuerySchemaRequest, opts ...grpc.CallOption) (*QuerySchemaResponse, error) {
|
||||||
|
cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...)
|
||||||
|
out := new(QuerySchemaResponse)
|
||||||
|
err := c.cc.Invoke(ctx, Query_Schema_FullMethodName, in, out, cOpts...)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return out, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *queryClient) Allocate(ctx context.Context, in *QueryAllocateRequest, opts ...grpc.CallOption) (*QueryAllocateResponse, error) {
|
||||||
|
cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...)
|
||||||
|
out := new(QueryAllocateResponse)
|
||||||
|
err := c.cc.Invoke(ctx, Query_Allocate_FullMethodName, in, out, cOpts...)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return out, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *queryClient) Sync(ctx context.Context, in *QuerySyncRequest, opts ...grpc.CallOption) (*QuerySyncResponse, error) {
|
||||||
|
cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...)
|
||||||
|
out := new(QuerySyncResponse)
|
||||||
|
err := c.cc.Invoke(ctx, Query_Sync_FullMethodName, in, out, cOpts...)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return out, nil
|
||||||
|
}
|
||||||
|
|
||||||
// QueryServer is the server API for Query service.
|
// QueryServer is the server API for Query service.
|
||||||
// All implementations must embed UnimplementedQueryServer
|
// All implementations must embed UnimplementedQueryServer
|
||||||
// for forward compatibility.
|
// for forward compatibility.
|
||||||
@@ -58,6 +100,15 @@ func (c *queryClient) Params(ctx context.Context, in *QueryParamsRequest, opts .
|
|||||||
type QueryServer interface {
|
type QueryServer interface {
|
||||||
// Params queries all parameters of the module.
|
// Params queries all parameters of the module.
|
||||||
Params(context.Context, *QueryParamsRequest) (*QueryParamsResponse, error)
|
Params(context.Context, *QueryParamsRequest) (*QueryParamsResponse, error)
|
||||||
|
// Schema queries the DID document by its id. And returns the required PKL
|
||||||
|
// information
|
||||||
|
Schema(context.Context, *QuerySchemaRequest) (*QuerySchemaResponse, error)
|
||||||
|
// Allocate initializes a Target Vault available for claims with a compatible
|
||||||
|
// Authentication mechanism. The default authentication mechanism is WebAuthn.
|
||||||
|
Allocate(context.Context, *QueryAllocateRequest) (*QueryAllocateResponse, error)
|
||||||
|
// Sync queries the DID document by its id. And returns the required PKL
|
||||||
|
// information
|
||||||
|
Sync(context.Context, *QuerySyncRequest) (*QuerySyncResponse, error)
|
||||||
mustEmbedUnimplementedQueryServer()
|
mustEmbedUnimplementedQueryServer()
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -71,6 +122,15 @@ type UnimplementedQueryServer struct{}
|
|||||||
func (UnimplementedQueryServer) Params(context.Context, *QueryParamsRequest) (*QueryParamsResponse, error) {
|
func (UnimplementedQueryServer) Params(context.Context, *QueryParamsRequest) (*QueryParamsResponse, error) {
|
||||||
return nil, status.Errorf(codes.Unimplemented, "method Params not implemented")
|
return nil, status.Errorf(codes.Unimplemented, "method Params not implemented")
|
||||||
}
|
}
|
||||||
|
func (UnimplementedQueryServer) Schema(context.Context, *QuerySchemaRequest) (*QuerySchemaResponse, error) {
|
||||||
|
return nil, status.Errorf(codes.Unimplemented, "method Schema not implemented")
|
||||||
|
}
|
||||||
|
func (UnimplementedQueryServer) Allocate(context.Context, *QueryAllocateRequest) (*QueryAllocateResponse, error) {
|
||||||
|
return nil, status.Errorf(codes.Unimplemented, "method Allocate not implemented")
|
||||||
|
}
|
||||||
|
func (UnimplementedQueryServer) Sync(context.Context, *QuerySyncRequest) (*QuerySyncResponse, error) {
|
||||||
|
return nil, status.Errorf(codes.Unimplemented, "method Sync not implemented")
|
||||||
|
}
|
||||||
func (UnimplementedQueryServer) mustEmbedUnimplementedQueryServer() {}
|
func (UnimplementedQueryServer) mustEmbedUnimplementedQueryServer() {}
|
||||||
func (UnimplementedQueryServer) testEmbeddedByValue() {}
|
func (UnimplementedQueryServer) testEmbeddedByValue() {}
|
||||||
|
|
||||||
@@ -110,6 +170,60 @@ func _Query_Params_Handler(srv interface{}, ctx context.Context, dec func(interf
|
|||||||
return interceptor(ctx, in, info, handler)
|
return interceptor(ctx, in, info, handler)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func _Query_Schema_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
|
||||||
|
in := new(QuerySchemaRequest)
|
||||||
|
if err := dec(in); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if interceptor == nil {
|
||||||
|
return srv.(QueryServer).Schema(ctx, in)
|
||||||
|
}
|
||||||
|
info := &grpc.UnaryServerInfo{
|
||||||
|
Server: srv,
|
||||||
|
FullMethod: Query_Schema_FullMethodName,
|
||||||
|
}
|
||||||
|
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
|
||||||
|
return srv.(QueryServer).Schema(ctx, req.(*QuerySchemaRequest))
|
||||||
|
}
|
||||||
|
return interceptor(ctx, in, info, handler)
|
||||||
|
}
|
||||||
|
|
||||||
|
func _Query_Allocate_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
|
||||||
|
in := new(QueryAllocateRequest)
|
||||||
|
if err := dec(in); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if interceptor == nil {
|
||||||
|
return srv.(QueryServer).Allocate(ctx, in)
|
||||||
|
}
|
||||||
|
info := &grpc.UnaryServerInfo{
|
||||||
|
Server: srv,
|
||||||
|
FullMethod: Query_Allocate_FullMethodName,
|
||||||
|
}
|
||||||
|
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
|
||||||
|
return srv.(QueryServer).Allocate(ctx, req.(*QueryAllocateRequest))
|
||||||
|
}
|
||||||
|
return interceptor(ctx, in, info, handler)
|
||||||
|
}
|
||||||
|
|
||||||
|
func _Query_Sync_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
|
||||||
|
in := new(QuerySyncRequest)
|
||||||
|
if err := dec(in); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if interceptor == nil {
|
||||||
|
return srv.(QueryServer).Sync(ctx, in)
|
||||||
|
}
|
||||||
|
info := &grpc.UnaryServerInfo{
|
||||||
|
Server: srv,
|
||||||
|
FullMethod: Query_Sync_FullMethodName,
|
||||||
|
}
|
||||||
|
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
|
||||||
|
return srv.(QueryServer).Sync(ctx, req.(*QuerySyncRequest))
|
||||||
|
}
|
||||||
|
return interceptor(ctx, in, info, handler)
|
||||||
|
}
|
||||||
|
|
||||||
// Query_ServiceDesc is the grpc.ServiceDesc for Query service.
|
// Query_ServiceDesc is the grpc.ServiceDesc for Query service.
|
||||||
// It's only intended for direct use with grpc.RegisterService,
|
// It's only intended for direct use with grpc.RegisterService,
|
||||||
// and not to be introspected or modified (even as a copy)
|
// and not to be introspected or modified (even as a copy)
|
||||||
@@ -121,6 +235,18 @@ var Query_ServiceDesc = grpc.ServiceDesc{
|
|||||||
MethodName: "Params",
|
MethodName: "Params",
|
||||||
Handler: _Query_Params_Handler,
|
Handler: _Query_Params_Handler,
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
MethodName: "Schema",
|
||||||
|
Handler: _Query_Schema_Handler,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
MethodName: "Allocate",
|
||||||
|
Handler: _Query_Allocate_Handler,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
MethodName: "Sync",
|
||||||
|
Handler: _Query_Sync_Handler,
|
||||||
|
},
|
||||||
},
|
},
|
||||||
Streams: []grpc.StreamDesc{},
|
Streams: []grpc.StreamDesc{},
|
||||||
Metadata: "dwn/v1/query.proto",
|
Metadata: "dwn/v1/query.proto",
|
||||||
|
|||||||
@@ -1818,7 +1818,7 @@ func (*MsgUpdateParamsResponse) Descriptor() ([]byte, []int) {
|
|||||||
return file_dwn_v1_tx_proto_rawDescGZIP(), []int{1}
|
return file_dwn_v1_tx_proto_rawDescGZIP(), []int{1}
|
||||||
}
|
}
|
||||||
|
|
||||||
// MsgSpawn spawns a New Vault with Unclaimed State. This is a one-time
|
// MsgInitialize spawns a New Vault with Unclaimed State. This is a one-time
|
||||||
// operation that must be performed interacting with the Vault.
|
// operation that must be performed interacting with the Vault.
|
||||||
//
|
//
|
||||||
// Since: cosmos-sdk 0.47
|
// Since: cosmos-sdk 0.47
|
||||||
@@ -1869,8 +1869,8 @@ func (x *MsgInitialize) GetParams() *Params {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// MsgSpawnResponse defines the response structure for executing a
|
// MsgInitializeResponse defines the response structure for executing a
|
||||||
// MsgSpawn message.
|
// MsgInitialize message.
|
||||||
//
|
//
|
||||||
// Since: cosmos-sdk 0.47
|
// Since: cosmos-sdk 0.47
|
||||||
type MsgInitializeResponse struct {
|
type MsgInitializeResponse struct {
|
||||||
|
|||||||
@@ -33,7 +33,7 @@ type MsgClient interface {
|
|||||||
//
|
//
|
||||||
// Since: cosmos-sdk 0.47
|
// Since: cosmos-sdk 0.47
|
||||||
UpdateParams(ctx context.Context, in *MsgUpdateParams, opts ...grpc.CallOption) (*MsgUpdateParamsResponse, error)
|
UpdateParams(ctx context.Context, in *MsgUpdateParams, opts ...grpc.CallOption) (*MsgUpdateParamsResponse, error)
|
||||||
// Spawn spawns a new Vault
|
// Initialize spawns a new Vault
|
||||||
Initialize(ctx context.Context, in *MsgInitialize, opts ...grpc.CallOption) (*MsgInitializeResponse, error)
|
Initialize(ctx context.Context, in *MsgInitialize, opts ...grpc.CallOption) (*MsgInitializeResponse, error)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -75,7 +75,7 @@ type MsgServer interface {
|
|||||||
//
|
//
|
||||||
// Since: cosmos-sdk 0.47
|
// Since: cosmos-sdk 0.47
|
||||||
UpdateParams(context.Context, *MsgUpdateParams) (*MsgUpdateParamsResponse, error)
|
UpdateParams(context.Context, *MsgUpdateParams) (*MsgUpdateParamsResponse, error)
|
||||||
// Spawn spawns a new Vault
|
// Initialize spawns a new Vault
|
||||||
Initialize(context.Context, *MsgInitialize) (*MsgInitializeResponse, error)
|
Initialize(context.Context, *MsgInitialize) (*MsgInitializeResponse, error)
|
||||||
mustEmbedUnimplementedMsgServer()
|
mustEmbedUnimplementedMsgServer()
|
||||||
}
|
}
|
||||||
|
|||||||
+507
-1484
File diff suppressed because it is too large
Load Diff
+26
-1947
File diff suppressed because it is too large
Load Diff
@@ -20,8 +20,6 @@ const _ = grpc.SupportPackageIsVersion9
|
|||||||
|
|
||||||
const (
|
const (
|
||||||
Query_Params_FullMethodName = "/svc.v1.Query/Params"
|
Query_Params_FullMethodName = "/svc.v1.Query/Params"
|
||||||
Query_OriginExists_FullMethodName = "/svc.v1.Query/OriginExists"
|
|
||||||
Query_ResolveOrigin_FullMethodName = "/svc.v1.Query/ResolveOrigin"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// QueryClient is the client API for Query service.
|
// QueryClient is the client API for Query service.
|
||||||
@@ -32,10 +30,6 @@ const (
|
|||||||
type QueryClient interface {
|
type QueryClient interface {
|
||||||
// Params queries all parameters of the module.
|
// Params queries all parameters of the module.
|
||||||
Params(ctx context.Context, in *QueryParamsRequest, opts ...grpc.CallOption) (*QueryParamsResponse, error)
|
Params(ctx context.Context, in *QueryParamsRequest, opts ...grpc.CallOption) (*QueryParamsResponse, error)
|
||||||
// OriginExists queries if a given origin exists.
|
|
||||||
OriginExists(ctx context.Context, in *QueryOriginExistsRequest, opts ...grpc.CallOption) (*QueryOriginExistsResponse, error)
|
|
||||||
// ResolveOrigin queries the domain of a given service and returns its record with capabilities.
|
|
||||||
ResolveOrigin(ctx context.Context, in *QueryResolveOriginRequest, opts ...grpc.CallOption) (*QueryResolveOriginResponse, error)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
type queryClient struct {
|
type queryClient struct {
|
||||||
@@ -56,26 +50,6 @@ func (c *queryClient) Params(ctx context.Context, in *QueryParamsRequest, opts .
|
|||||||
return out, nil
|
return out, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *queryClient) OriginExists(ctx context.Context, in *QueryOriginExistsRequest, opts ...grpc.CallOption) (*QueryOriginExistsResponse, error) {
|
|
||||||
cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...)
|
|
||||||
out := new(QueryOriginExistsResponse)
|
|
||||||
err := c.cc.Invoke(ctx, Query_OriginExists_FullMethodName, in, out, cOpts...)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return out, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *queryClient) ResolveOrigin(ctx context.Context, in *QueryResolveOriginRequest, opts ...grpc.CallOption) (*QueryResolveOriginResponse, error) {
|
|
||||||
cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...)
|
|
||||||
out := new(QueryResolveOriginResponse)
|
|
||||||
err := c.cc.Invoke(ctx, Query_ResolveOrigin_FullMethodName, in, out, cOpts...)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return out, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// QueryServer is the server API for Query service.
|
// QueryServer is the server API for Query service.
|
||||||
// All implementations must embed UnimplementedQueryServer
|
// All implementations must embed UnimplementedQueryServer
|
||||||
// for forward compatibility.
|
// for forward compatibility.
|
||||||
@@ -84,10 +58,6 @@ func (c *queryClient) ResolveOrigin(ctx context.Context, in *QueryResolveOriginR
|
|||||||
type QueryServer interface {
|
type QueryServer interface {
|
||||||
// Params queries all parameters of the module.
|
// Params queries all parameters of the module.
|
||||||
Params(context.Context, *QueryParamsRequest) (*QueryParamsResponse, error)
|
Params(context.Context, *QueryParamsRequest) (*QueryParamsResponse, error)
|
||||||
// OriginExists queries if a given origin exists.
|
|
||||||
OriginExists(context.Context, *QueryOriginExistsRequest) (*QueryOriginExistsResponse, error)
|
|
||||||
// ResolveOrigin queries the domain of a given service and returns its record with capabilities.
|
|
||||||
ResolveOrigin(context.Context, *QueryResolveOriginRequest) (*QueryResolveOriginResponse, error)
|
|
||||||
mustEmbedUnimplementedQueryServer()
|
mustEmbedUnimplementedQueryServer()
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -101,12 +71,6 @@ type UnimplementedQueryServer struct{}
|
|||||||
func (UnimplementedQueryServer) Params(context.Context, *QueryParamsRequest) (*QueryParamsResponse, error) {
|
func (UnimplementedQueryServer) Params(context.Context, *QueryParamsRequest) (*QueryParamsResponse, error) {
|
||||||
return nil, status.Errorf(codes.Unimplemented, "method Params not implemented")
|
return nil, status.Errorf(codes.Unimplemented, "method Params not implemented")
|
||||||
}
|
}
|
||||||
func (UnimplementedQueryServer) OriginExists(context.Context, *QueryOriginExistsRequest) (*QueryOriginExistsResponse, error) {
|
|
||||||
return nil, status.Errorf(codes.Unimplemented, "method OriginExists not implemented")
|
|
||||||
}
|
|
||||||
func (UnimplementedQueryServer) ResolveOrigin(context.Context, *QueryResolveOriginRequest) (*QueryResolveOriginResponse, error) {
|
|
||||||
return nil, status.Errorf(codes.Unimplemented, "method ResolveOrigin not implemented")
|
|
||||||
}
|
|
||||||
func (UnimplementedQueryServer) mustEmbedUnimplementedQueryServer() {}
|
func (UnimplementedQueryServer) mustEmbedUnimplementedQueryServer() {}
|
||||||
func (UnimplementedQueryServer) testEmbeddedByValue() {}
|
func (UnimplementedQueryServer) testEmbeddedByValue() {}
|
||||||
|
|
||||||
@@ -146,42 +110,6 @@ func _Query_Params_Handler(srv interface{}, ctx context.Context, dec func(interf
|
|||||||
return interceptor(ctx, in, info, handler)
|
return interceptor(ctx, in, info, handler)
|
||||||
}
|
}
|
||||||
|
|
||||||
func _Query_OriginExists_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
|
|
||||||
in := new(QueryOriginExistsRequest)
|
|
||||||
if err := dec(in); err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
if interceptor == nil {
|
|
||||||
return srv.(QueryServer).OriginExists(ctx, in)
|
|
||||||
}
|
|
||||||
info := &grpc.UnaryServerInfo{
|
|
||||||
Server: srv,
|
|
||||||
FullMethod: Query_OriginExists_FullMethodName,
|
|
||||||
}
|
|
||||||
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
|
|
||||||
return srv.(QueryServer).OriginExists(ctx, req.(*QueryOriginExistsRequest))
|
|
||||||
}
|
|
||||||
return interceptor(ctx, in, info, handler)
|
|
||||||
}
|
|
||||||
|
|
||||||
func _Query_ResolveOrigin_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
|
|
||||||
in := new(QueryResolveOriginRequest)
|
|
||||||
if err := dec(in); err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
if interceptor == nil {
|
|
||||||
return srv.(QueryServer).ResolveOrigin(ctx, in)
|
|
||||||
}
|
|
||||||
info := &grpc.UnaryServerInfo{
|
|
||||||
Server: srv,
|
|
||||||
FullMethod: Query_ResolveOrigin_FullMethodName,
|
|
||||||
}
|
|
||||||
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
|
|
||||||
return srv.(QueryServer).ResolveOrigin(ctx, req.(*QueryResolveOriginRequest))
|
|
||||||
}
|
|
||||||
return interceptor(ctx, in, info, handler)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Query_ServiceDesc is the grpc.ServiceDesc for Query service.
|
// Query_ServiceDesc is the grpc.ServiceDesc for Query service.
|
||||||
// It's only intended for direct use with grpc.RegisterService,
|
// It's only intended for direct use with grpc.RegisterService,
|
||||||
// and not to be introspected or modified (even as a copy)
|
// and not to be introspected or modified (even as a copy)
|
||||||
@@ -193,14 +121,6 @@ var Query_ServiceDesc = grpc.ServiceDesc{
|
|||||||
MethodName: "Params",
|
MethodName: "Params",
|
||||||
Handler: _Query_Params_Handler,
|
Handler: _Query_Params_Handler,
|
||||||
},
|
},
|
||||||
{
|
|
||||||
MethodName: "OriginExists",
|
|
||||||
Handler: _Query_OriginExists_Handler,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
MethodName: "ResolveOrigin",
|
|
||||||
Handler: _Query_ResolveOrigin_Handler,
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
Streams: []grpc.StreamDesc{},
|
Streams: []grpc.StreamDesc{},
|
||||||
Metadata: "svc/v1/query.proto",
|
Metadata: "svc/v1/query.proto",
|
||||||
|
|||||||
@@ -0,0 +1,10 @@
|
|||||||
|
# Local Interchain Configurations
|
||||||
|
|
||||||
|
RUN:
|
||||||
|
- `make testnet` *(full setup: docker image, binary, keys, and ibc testnet start)*
|
||||||
|
- `spawn local-ic start testnet` *(Standalone start)*
|
||||||
|
|
||||||
|
## Documentation
|
||||||
|
|
||||||
|
* https://github.com/strangelove-ventures/interchaintest/tree/main/local-interchain
|
||||||
|
|
||||||
@@ -0,0 +1,103 @@
|
|||||||
|
{
|
||||||
|
"chains": [
|
||||||
|
{
|
||||||
|
"name": "core",
|
||||||
|
"ibc_paths": ["ibc-connection-1"],
|
||||||
|
"chain_id": "chainid-1",
|
||||||
|
"denom": "usnr",
|
||||||
|
"binary": "sonrd",
|
||||||
|
"bech32_prefix": "idx",
|
||||||
|
"docker_image": {
|
||||||
|
"repository": "core",
|
||||||
|
"version": "local"
|
||||||
|
},
|
||||||
|
"gas_prices": "0usnr",
|
||||||
|
"chain_type": "cosmos",
|
||||||
|
"coin_type": 118,
|
||||||
|
"trusting_period": "336h",
|
||||||
|
"gas_adjustment": 1.5,
|
||||||
|
"number_vals": 1,
|
||||||
|
"number_node": 0,
|
||||||
|
"debugging": true,
|
||||||
|
"block_time": "1000ms",
|
||||||
|
"host_port_override": {
|
||||||
|
"26657": "26657",
|
||||||
|
"1317": "1317",
|
||||||
|
"9090": "9090"
|
||||||
|
},
|
||||||
|
"encoding-options": ["wasm", "tokenfactory"],
|
||||||
|
"config_file_overrides": [
|
||||||
|
{
|
||||||
|
"file": "config/config.toml",
|
||||||
|
"paths": {
|
||||||
|
"moniker": "localvalmoniker",
|
||||||
|
"rpc.cors_allowed_origins": ["*"]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"genesis": {
|
||||||
|
"modify": [
|
||||||
|
{
|
||||||
|
"key": "app_state.gov.params.voting_period",
|
||||||
|
"value": "15s"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"key": "app_state.gov.params.expedited_voting_period",
|
||||||
|
"value": "10s"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"key": "app_state.gov.params.max_deposit_period",
|
||||||
|
"value": "15s"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"key": "app_state.gov.params.min_deposit.0.denom",
|
||||||
|
"value": "usnr"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"key": "app_state.gov.params.min_deposit.0.amount",
|
||||||
|
"value": "1"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"accounts": [
|
||||||
|
{
|
||||||
|
"name": "acc0",
|
||||||
|
"address": "idx1hj5fveer5cjtn4wd6wstzugjfdxzl0xpecp0nd",
|
||||||
|
"amount": "10000000000usnr",
|
||||||
|
"mnemonic": "decorate bright ozone fork gallery riot bus exhaust worth way bone indoor calm squirrel merry zero scheme cotton until shop any excess stage laundry"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "acc1",
|
||||||
|
"address": "idx1efd63aw40lxf3n4mhf7dzhjkr453axur9vjt6y",
|
||||||
|
"amount": "10000000000usnr",
|
||||||
|
"mnemonic": "wealth flavor believe regret funny network recall kiss grape useless pepper cram hint member few certain unveil rather brick bargain curious require crowd raise"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"startup_commands": []
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "gaia",
|
||||||
|
"chain_id": "localcosmos-1",
|
||||||
|
"denom": "uatom",
|
||||||
|
"binary": "gaiad",
|
||||||
|
"bech32_prefix": "cosmos",
|
||||||
|
"docker_image": {
|
||||||
|
"version": "v9.1.0"
|
||||||
|
},
|
||||||
|
"block_time": "1000ms",
|
||||||
|
"gas_prices": "0%DENOM%",
|
||||||
|
"gas_adjustment": 2.0,
|
||||||
|
"ibc_paths": ["ibc-connection-1"],
|
||||||
|
"genesis": {
|
||||||
|
"accounts": [
|
||||||
|
{
|
||||||
|
"name": "acc0",
|
||||||
|
"address": "cosmos1hj5fveer5cjtn4wd6wstzugjfdxzl0xpxvjjvr",
|
||||||
|
"amount": "10000000%DENOM%",
|
||||||
|
"mnemonic": "decorate bright ozone fork gallery riot bus exhaust worth way bone indoor calm squirrel merry zero scheme cotton until shop any excess stage laundry"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
@@ -0,0 +1,78 @@
|
|||||||
|
{
|
||||||
|
"chains": [
|
||||||
|
{
|
||||||
|
"name": "core",
|
||||||
|
"chain_id": "chainid-1",
|
||||||
|
"denom": "usnr",
|
||||||
|
"binary": "sonrd",
|
||||||
|
"bech32_prefix": "idx",
|
||||||
|
"docker_image": {
|
||||||
|
"repository": "core",
|
||||||
|
"version": "local"
|
||||||
|
},
|
||||||
|
"gas_prices": "0usnr",
|
||||||
|
"chain_type": "cosmos",
|
||||||
|
"coin_type": 118,
|
||||||
|
"trusting_period": "336h",
|
||||||
|
"gas_adjustment": 1.5,
|
||||||
|
"number_vals": 1,
|
||||||
|
"number_node": 0,
|
||||||
|
"debugging": true,
|
||||||
|
"block_time": "1000ms",
|
||||||
|
"host_port_override": {
|
||||||
|
"26657": "26657",
|
||||||
|
"1317": "1317",
|
||||||
|
"9090": "9090"
|
||||||
|
},
|
||||||
|
"encoding-options": ["wasm", "tokenfactory"],
|
||||||
|
"config_file_overrides": [
|
||||||
|
{
|
||||||
|
"file": "config/config.toml",
|
||||||
|
"paths": {
|
||||||
|
"moniker": "localvalmoniker",
|
||||||
|
"rpc.cors_allowed_origins": ["*"]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"genesis": {
|
||||||
|
"modify": [
|
||||||
|
{
|
||||||
|
"key": "app_state.gov.params.voting_period",
|
||||||
|
"value": "15s"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"key": "app_state.gov.params.expedited_voting_period",
|
||||||
|
"value": "10s"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"key": "app_state.gov.params.max_deposit_period",
|
||||||
|
"value": "15s"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"key": "app_state.gov.params.min_deposit.0.denom",
|
||||||
|
"value": "usnr"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"key": "app_state.gov.params.min_deposit.0.amount",
|
||||||
|
"value": "1"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"accounts": [
|
||||||
|
{
|
||||||
|
"name": "acc0",
|
||||||
|
"address": "idx1hj5fveer5cjtn4wd6wstzugjfdxzl0xpecp0nd",
|
||||||
|
"amount": "10000000000usnr",
|
||||||
|
"mnemonic": "decorate bright ozone fork gallery riot bus exhaust worth way bone indoor calm squirrel merry zero scheme cotton until shop any excess stage laundry"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "acc1",
|
||||||
|
"address": "idx1efd63aw40lxf3n4mhf7dzhjkr453axur9vjt6y",
|
||||||
|
"amount": "10000000000usnr",
|
||||||
|
"mnemonic": "wealth flavor believe regret funny network recall kiss grape useless pepper cram hint member few certain unveil rather brick bargain curious require crowd raise"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"startup_commands": []
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
@@ -0,0 +1,99 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"log"
|
||||||
|
"net/http"
|
||||||
|
"os"
|
||||||
|
|
||||||
|
"github.com/labstack/echo/v4"
|
||||||
|
"github.com/labstack/echo/v4/middleware"
|
||||||
|
"github.com/onsonr/sonr/crypto/ucan"
|
||||||
|
"github.com/onsonr/sonr/internal/gateway"
|
||||||
|
"github.com/onsonr/sonr/pkg/common/ipfs"
|
||||||
|
config "github.com/onsonr/sonr/pkg/config/hway"
|
||||||
|
"github.com/onsonr/sonr/pkg/database/sessions"
|
||||||
|
"github.com/onsonr/sonr/pkg/didauth/producer"
|
||||||
|
"github.com/spf13/cobra"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Command line flags
|
||||||
|
var (
|
||||||
|
servePort int // Gateway http entry point (default 3000)
|
||||||
|
configDir string // Hway config directory (default hway)
|
||||||
|
sqliteFile string // SQLite database file (default hway.db)
|
||||||
|
chainID string // Current chain ID (default sonr-testnet-1)
|
||||||
|
ipfsGatewayURL string // IPFS gateway URL (default localhost:8080)
|
||||||
|
sonrAPIURL string // Sonr API URL (default localhost:1317)
|
||||||
|
sonrGrpcURL string // Sonr gRPC URL (default localhost:9090)
|
||||||
|
sonrRPCURL string // Sonr RPC URL (default localhost:26657)
|
||||||
|
)
|
||||||
|
|
||||||
|
func rootCmd() *cobra.Command {
|
||||||
|
cmd := &cobra.Command{
|
||||||
|
Use: "hway",
|
||||||
|
Short: "Sonr DID gateway",
|
||||||
|
Run: func(cmd *cobra.Command, args []string) {
|
||||||
|
env, err := loadEnvImplFromArgs(args)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
e, err := setupServer(env)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
if err := e.Start(fmt.Sprintf(":%d", env.GetServePort())); err != http.ErrServerClosed {
|
||||||
|
log.Fatal(err)
|
||||||
|
os.Exit(1)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
},
|
||||||
|
}
|
||||||
|
cmd.Flags().IntVar(&servePort, "serve-port", 3000, "Port to serve the gateway on")
|
||||||
|
cmd.Flags().StringVar(&configDir, "config-dir", "hway", "Directory to store config files")
|
||||||
|
cmd.Flags().StringVar(&sqliteFile, "sqlite-file", "hway.db", "File to store sqlite database")
|
||||||
|
cmd.Flags().StringVar(&chainID, "chain-id", "sonr-testnet-1", "Chain ID")
|
||||||
|
cmd.Flags().StringVar(&ipfsGatewayURL, "ipfs-gateway-url", "localhost:8080", "IPFS gateway URL")
|
||||||
|
cmd.Flags().StringVar(&sonrAPIURL, "sonr-api-url", "localhost:1317", "Sonr API URL")
|
||||||
|
cmd.Flags().StringVar(&sonrGrpcURL, "sonr-grpc-url", "localhost:9090", "Sonr gRPC URL")
|
||||||
|
cmd.Flags().StringVar(&sonrRPCURL, "sonr-rpc-url", "localhost:26657", "Sonr RPC URL")
|
||||||
|
return cmd
|
||||||
|
}
|
||||||
|
|
||||||
|
func loadEnvImplFromArgs(args []string) (config.Hway, error) {
|
||||||
|
cmd := rootCmd()
|
||||||
|
if err := cmd.ParseFlags(args); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
env := &config.HwayImpl{
|
||||||
|
ServePort: servePort,
|
||||||
|
ConfigDir: configDir,
|
||||||
|
SqliteFile: sqliteFile,
|
||||||
|
ChainId: chainID,
|
||||||
|
IpfsGatewayUrl: ipfsGatewayURL,
|
||||||
|
SonrApiUrl: sonrAPIURL,
|
||||||
|
SonrGrpcUrl: sonrGrpcURL,
|
||||||
|
SonrRpcUrl: sonrRPCURL,
|
||||||
|
}
|
||||||
|
return env, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// setupServer sets up the server
|
||||||
|
func setupServer(env config.Hway) (*echo.Echo, error) {
|
||||||
|
ipc, err := ipfs.NewClient()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
db, err := sessions.NewGormDB(env)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
e := echo.New()
|
||||||
|
e.IPExtractor = echo.ExtractIPDirect()
|
||||||
|
e.Use(middleware.Logger())
|
||||||
|
e.Use(middleware.Recover())
|
||||||
|
e.Use(producer.Middleware(ipc, ucan.ServicePermissions))
|
||||||
|
gateway.RegisterRoutes(e, env, db)
|
||||||
|
return e, nil
|
||||||
|
}
|
||||||
@@ -0,0 +1,17 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
_ "embed"
|
||||||
|
"fmt"
|
||||||
|
"os"
|
||||||
|
)
|
||||||
|
|
||||||
|
// main is the entry point for the application
|
||||||
|
func main() {
|
||||||
|
cmd := rootCmd()
|
||||||
|
if err := cmd.Execute(); err != nil {
|
||||||
|
fmt.Println(err)
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
|
os.Exit(0)
|
||||||
|
}
|
||||||
@@ -0,0 +1,55 @@
|
|||||||
|
//go:build js && wasm
|
||||||
|
// +build js,wasm
|
||||||
|
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding/json"
|
||||||
|
"syscall/js"
|
||||||
|
|
||||||
|
"github.com/labstack/echo/v4"
|
||||||
|
"github.com/onsonr/sonr/internal/vault"
|
||||||
|
"github.com/onsonr/sonr/pkg/common/wasm"
|
||||||
|
"github.com/onsonr/sonr/pkg/config/motr"
|
||||||
|
"github.com/onsonr/sonr/pkg/didauth/controller"
|
||||||
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
env *motr.Environment
|
||||||
|
config *motr.Config
|
||||||
|
err error
|
||||||
|
)
|
||||||
|
|
||||||
|
func broadcastTx(this js.Value, args []js.Value) interface{} {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func simulateTx(this js.Value, args []js.Value) interface{} {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func processConfig(this js.Value, args []js.Value) interface{} {
|
||||||
|
if len(args) < 1 {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
configString := args[0].String()
|
||||||
|
if err := json.Unmarshal([]byte(configString), &config); err != nil {
|
||||||
|
println("Error parsing config:", err.Error())
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
// Load dwn config
|
||||||
|
js.Global().Set("broadcastTx", js.FuncOf(broadcastTx))
|
||||||
|
js.Global().Set("simulateTx", js.FuncOf(simulateTx))
|
||||||
|
js.Global().Set("processConfig", js.FuncOf(processConfig))
|
||||||
|
|
||||||
|
e := echo.New()
|
||||||
|
e.Use(wasm.ContextMiddleware)
|
||||||
|
e.Use(controller.Middleware(nil))
|
||||||
|
vault.RegisterRoutes(e, config)
|
||||||
|
wasm.ServeFetch(e)
|
||||||
|
}
|
||||||
@@ -12,6 +12,7 @@ import (
|
|||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
rootCmd := NewRootCmd()
|
rootCmd := NewRootCmd()
|
||||||
|
|
||||||
if err := svrcmd.Execute(rootCmd, "", app.DefaultNodeHome); err != nil {
|
if err := svrcmd.Execute(rootCmd, "", app.DefaultNodeHome); err != nil {
|
||||||
log.NewLogger(rootCmd.OutOrStderr()).Error("failure when running app", "err", err)
|
log.NewLogger(rootCmd.OutOrStderr()).Error("failure when running app", "err", err)
|
||||||
os.Exit(1)
|
os.Exit(1)
|
||||||
|
|||||||
@@ -0,0 +1,85 @@
|
|||||||
|
###
|
||||||
|
# Find OS and Go environment
|
||||||
|
# GO contains the Go binary
|
||||||
|
# FS contains the OS file separator
|
||||||
|
###
|
||||||
|
ifeq ($(OS),Windows_NT)
|
||||||
|
GO := $(shell where go.exe 2> NUL)
|
||||||
|
FS := "\\"
|
||||||
|
else
|
||||||
|
GO := $(shell command -v go 2> /dev/null)
|
||||||
|
FS := "/"
|
||||||
|
endif
|
||||||
|
|
||||||
|
ifeq ($(GO),)
|
||||||
|
$(error could not find go. Is it in PATH? $(GO))
|
||||||
|
endif
|
||||||
|
|
||||||
|
###############################################################################
|
||||||
|
### Functions ###
|
||||||
|
###############################################################################
|
||||||
|
|
||||||
|
go_get = $(if $(findstring Windows_NT,$(OS)),\
|
||||||
|
IF NOT EXIST $(GITHUBDIR)$(FS)$(1)$(FS) ( mkdir $(GITHUBDIR)$(FS)$(1) ) else (cd .) &\
|
||||||
|
IF NOT EXIST $(GITHUBDIR)$(FS)$(1)$(FS)$(2)$(FS) ( cd $(GITHUBDIR)$(FS)$(1) && git clone https://github.com/$(1)/$(2) ) else (cd .) &\
|
||||||
|
,\
|
||||||
|
mkdir -p $(GITHUBDIR)$(FS)$(1) &&\
|
||||||
|
(test ! -d $(GITHUBDIR)$(FS)$(1)$(FS)$(2) && cd $(GITHUBDIR)$(FS)$(1) && git clone https://github.com/$(1)/$(2)) || true &&\
|
||||||
|
)\
|
||||||
|
cd $(GITHUBDIR)$(FS)$(1)$(FS)$(2) && git fetch origin && git checkout -q $(3)
|
||||||
|
|
||||||
|
mkfile_path := $(abspath $(lastword $(MAKEFILE_LIST)))
|
||||||
|
mkfile_dir := $(shell cd $(shell dirname $(mkfile_path)); pwd)
|
||||||
|
|
||||||
|
|
||||||
|
###############################################################################
|
||||||
|
### Tools ###
|
||||||
|
###############################################################################
|
||||||
|
|
||||||
|
PREFIX ?= /usr/local
|
||||||
|
BIN ?= $(PREFIX)/bin
|
||||||
|
UNAME_S ?= $(shell uname -s)
|
||||||
|
UNAME_M ?= $(shell uname -m)
|
||||||
|
|
||||||
|
GOPATH ?= $(shell $(GO) env GOPATH)
|
||||||
|
GITHUBDIR := $(GOPATH)$(FS)src$(FS)github.com
|
||||||
|
|
||||||
|
BUF_VERSION ?= 0.11.0
|
||||||
|
|
||||||
|
TOOLS_DESTDIR ?= $(GOPATH)/bin
|
||||||
|
STATIK = $(TOOLS_DESTDIR)/statik
|
||||||
|
RUNSIM = $(TOOLS_DESTDIR)/runsim
|
||||||
|
GOLANGCI_LINT = $(TOOLS_DESTDIR)/golangci-lint
|
||||||
|
|
||||||
|
tools: tools-stamp
|
||||||
|
tools-stamp: statik runsim golangci-lint
|
||||||
|
# Create dummy file to satisfy dependency and avoid
|
||||||
|
# rebuilding when this Makefile target is hit twice
|
||||||
|
# in a row.
|
||||||
|
touch $@
|
||||||
|
|
||||||
|
statik: $(STATIK)
|
||||||
|
$(STATIK):
|
||||||
|
@echo "Installing statik..."
|
||||||
|
@(cd /tmp && go install github.com/rakyll/statik@v0.1.6)
|
||||||
|
|
||||||
|
# Install the runsim binary with a temporary workaround of entering an outside
|
||||||
|
# directory as the "go get" command ignores the -mod option and will polute the
|
||||||
|
# go.{mod, sum} files.
|
||||||
|
#
|
||||||
|
# ref: https://github.com/golang/go/issues/30515
|
||||||
|
runsim: $(RUNSIM)
|
||||||
|
$(RUNSIM):
|
||||||
|
@echo "Installing runsim..."
|
||||||
|
@(cd /tmp && go install github.com/cosmos/tools/cmd/runsim@v1.0.0)
|
||||||
|
|
||||||
|
golangci-lint: $(GOLANGCI_LINT)
|
||||||
|
$(GOLANGCI_LINT):
|
||||||
|
@echo "Installing golangci-lint..."
|
||||||
|
@(cd /tmp && go install github.com/golangci/golangci-lint/cmd/golangci-lint@v1.47.0)
|
||||||
|
|
||||||
|
tools-clean:
|
||||||
|
rm -f $(STATIK) $(GOLANGCI_LINT) $(RUNSIM)
|
||||||
|
rm -f tools-stamp
|
||||||
|
|
||||||
|
.PHONY: tools-clean statik runsim
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
## Contributors
|
||||||
|
|
||||||
|
Thanks to the entire Cosmos SDK team and the contributors who put their efforts into making simulation testing
|
||||||
|
easier to implement. 🤗
|
||||||
|
|
||||||
|
https://github.com/cosmos/cosmos-sdk/blob/master/contrib/devtools/Makefile
|
||||||
@@ -601,11 +601,11 @@ func (p *PointBls12377G1) UnmarshalText(input []byte) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (p *PointBls12377G1) MarshalJSON() ([]byte, error) {
|
func (p *PointBls12377G1) MarshalJSON() ([]byte, error) {
|
||||||
return pointMarshalJSON(p)
|
return pointMarshalJson(p)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *PointBls12377G1) UnmarshalJSON(input []byte) error {
|
func (p *PointBls12377G1) UnmarshalJSON(input []byte) error {
|
||||||
pt, err := pointUnmarshalJSON(input)
|
pt, err := pointUnmarshalJson(input)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@@ -874,11 +874,11 @@ func (p *PointBls12377G2) UnmarshalText(input []byte) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (p *PointBls12377G2) MarshalJSON() ([]byte, error) {
|
func (p *PointBls12377G2) MarshalJSON() ([]byte, error) {
|
||||||
return pointMarshalJSON(p)
|
return pointMarshalJson(p)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *PointBls12377G2) UnmarshalJSON(input []byte) error {
|
func (p *PointBls12377G2) UnmarshalJSON(input []byte) error {
|
||||||
pt, err := pointUnmarshalJSON(input)
|
pt, err := pointUnmarshalJson(input)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -573,11 +573,11 @@ func (p *PointBls12381G1) UnmarshalText(input []byte) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (p *PointBls12381G1) MarshalJSON() ([]byte, error) {
|
func (p *PointBls12381G1) MarshalJSON() ([]byte, error) {
|
||||||
return pointMarshalJSON(p)
|
return pointMarshalJson(p)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *PointBls12381G1) UnmarshalJSON(input []byte) error {
|
func (p *PointBls12381G1) UnmarshalJSON(input []byte) error {
|
||||||
pt, err := pointUnmarshalJSON(input)
|
pt, err := pointUnmarshalJson(input)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@@ -823,11 +823,11 @@ func (p *PointBls12381G2) UnmarshalText(input []byte) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (p *PointBls12381G2) MarshalJSON() ([]byte, error) {
|
func (p *PointBls12381G2) MarshalJSON() ([]byte, error) {
|
||||||
return pointMarshalJSON(p)
|
return pointMarshalJson(p)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *PointBls12381G2) UnmarshalJSON(input []byte) error {
|
func (p *PointBls12381G2) UnmarshalJSON(input []byte) error {
|
||||||
pt, err := pointUnmarshalJSON(input)
|
pt, err := pointUnmarshalJson(input)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -336,14 +336,14 @@ func pointUnmarshalText(input []byte) (Point, error) {
|
|||||||
return curve.Point.FromAffineCompressed(buffer)
|
return curve.Point.FromAffineCompressed(buffer)
|
||||||
}
|
}
|
||||||
|
|
||||||
func pointMarshalJSON(point Point) ([]byte, error) {
|
func pointMarshalJson(point Point) ([]byte, error) {
|
||||||
m := make(map[string]string, 2)
|
m := make(map[string]string, 2)
|
||||||
m["type"] = point.CurveName()
|
m["type"] = point.CurveName()
|
||||||
m["value"] = hex.EncodeToString(point.ToAffineCompressed())
|
m["value"] = hex.EncodeToString(point.ToAffineCompressed())
|
||||||
return json.Marshal(m)
|
return json.Marshal(m)
|
||||||
}
|
}
|
||||||
|
|
||||||
func pointUnmarshalJSON(input []byte) (Point, error) {
|
func pointUnmarshalJson(input []byte) (Point, error) {
|
||||||
var m map[string]string
|
var m map[string]string
|
||||||
|
|
||||||
err := json.Unmarshal(input, &m)
|
err := json.Unmarshal(input, &m)
|
||||||
|
|||||||
@@ -682,11 +682,11 @@ func (p *PointEd25519) UnmarshalText(input []byte) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (p *PointEd25519) MarshalJSON() ([]byte, error) {
|
func (p *PointEd25519) MarshalJSON() ([]byte, error) {
|
||||||
return pointMarshalJSON(p)
|
return pointMarshalJson(p)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *PointEd25519) UnmarshalJSON(input []byte) error {
|
func (p *PointEd25519) UnmarshalJSON(input []byte) error {
|
||||||
pt, err := pointUnmarshalJSON(input)
|
pt, err := pointUnmarshalJson(input)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -653,11 +653,11 @@ func (p *PointK256) UnmarshalText(input []byte) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (p *PointK256) MarshalJSON() ([]byte, error) {
|
func (p *PointK256) MarshalJSON() ([]byte, error) {
|
||||||
return pointMarshalJSON(p)
|
return pointMarshalJson(p)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *PointK256) UnmarshalJSON(input []byte) error {
|
func (p *PointK256) UnmarshalJSON(input []byte) error {
|
||||||
pt, err := pointUnmarshalJSON(input)
|
pt, err := pointUnmarshalJson(input)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -701,11 +701,11 @@ func (p *BenchPointP256) UnmarshalText(input []byte) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (p *BenchPointP256) MarshalJSON() ([]byte, error) {
|
func (p *BenchPointP256) MarshalJSON() ([]byte, error) {
|
||||||
return pointMarshalJSON(p)
|
return pointMarshalJson(p)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *BenchPointP256) UnmarshalJSON(input []byte) error {
|
func (p *BenchPointP256) UnmarshalJSON(input []byte) error {
|
||||||
pt, err := pointUnmarshalJSON(input)
|
pt, err := pointUnmarshalJson(input)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -651,11 +651,11 @@ func (p *PointP256) UnmarshalText(input []byte) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (p *PointP256) MarshalJSON() ([]byte, error) {
|
func (p *PointP256) MarshalJSON() ([]byte, error) {
|
||||||
return pointMarshalJSON(p)
|
return pointMarshalJson(p)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *PointP256) UnmarshalJSON(input []byte) error {
|
func (p *PointP256) UnmarshalJSON(input []byte) error {
|
||||||
pt, err := pointUnmarshalJSON(input)
|
pt, err := pointUnmarshalJson(input)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -669,11 +669,11 @@ func (p *PointPallas) UnmarshalText(input []byte) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (p *PointPallas) MarshalJSON() ([]byte, error) {
|
func (p *PointPallas) MarshalJSON() ([]byte, error) {
|
||||||
return pointMarshalJSON(p)
|
return pointMarshalJson(p)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *PointPallas) UnmarshalJSON(input []byte) error {
|
func (p *PointPallas) UnmarshalJSON(input []byte) error {
|
||||||
pt, err := pointUnmarshalJSON(input)
|
pt, err := pointUnmarshalJson(input)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,162 +0,0 @@
|
|||||||
package keys
|
|
||||||
|
|
||||||
import (
|
|
||||||
"crypto/ed25519"
|
|
||||||
"crypto/rsa"
|
|
||||||
"crypto/x509"
|
|
||||||
"fmt"
|
|
||||||
"strings"
|
|
||||||
|
|
||||||
"github.com/libp2p/go-libp2p/core/crypto"
|
|
||||||
mb "github.com/multiformats/go-multibase"
|
|
||||||
varint "github.com/multiformats/go-varint"
|
|
||||||
)
|
|
||||||
|
|
||||||
const (
|
|
||||||
// KeyPrefix indicates a decentralized identifier that uses the key method
|
|
||||||
KeyPrefix = "did:key"
|
|
||||||
// MulticodecKindRSAPubKey rsa-x509-pub https://github.com/multiformats/multicodec/pull/226
|
|
||||||
MulticodecKindRSAPubKey = 0x1205
|
|
||||||
// MulticodecKindEd25519PubKey ed25519-pub
|
|
||||||
MulticodecKindEd25519PubKey = 0xed
|
|
||||||
// MulticodecKindSecp256k1PubKey secp256k1-pub
|
|
||||||
MulticodecKindSecp256k1PubKey = 0x1206
|
|
||||||
)
|
|
||||||
|
|
||||||
// DID is a DID:key identifier
|
|
||||||
type DID struct {
|
|
||||||
crypto.PubKey
|
|
||||||
}
|
|
||||||
|
|
||||||
// NewDID constructs an Identifier from a public key
|
|
||||||
func NewDID(pub crypto.PubKey) (DID, error) {
|
|
||||||
switch pub.Type() {
|
|
||||||
case crypto.Ed25519, crypto.RSA, crypto.Secp256k1:
|
|
||||||
return DID{PubKey: pub}, nil
|
|
||||||
default:
|
|
||||||
return DID{}, fmt.Errorf("unsupported key type: %s", pub.Type())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// NewFromPubKey constructs an Identifier from a public key
|
|
||||||
func NewFromPubKey(pub PubKey) DID {
|
|
||||||
return DID{PubKey: pub}
|
|
||||||
}
|
|
||||||
|
|
||||||
// MulticodecType indicates the type for this multicodec
|
|
||||||
func (id DID) MulticodecType() uint64 {
|
|
||||||
switch id.Type() {
|
|
||||||
case crypto.RSA:
|
|
||||||
return MulticodecKindRSAPubKey
|
|
||||||
case crypto.Ed25519:
|
|
||||||
return MulticodecKindEd25519PubKey
|
|
||||||
case crypto.Secp256k1:
|
|
||||||
return MulticodecKindSecp256k1PubKey
|
|
||||||
default:
|
|
||||||
panic("unexpected crypto type")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// String returns this did:key formatted as a string
|
|
||||||
func (id DID) String() string {
|
|
||||||
raw, err := id.Raw()
|
|
||||||
if err != nil {
|
|
||||||
return ""
|
|
||||||
}
|
|
||||||
|
|
||||||
t := id.MulticodecType()
|
|
||||||
size := varint.UvarintSize(t)
|
|
||||||
data := make([]byte, size+len(raw))
|
|
||||||
n := varint.PutUvarint(data, t)
|
|
||||||
copy(data[n:], raw)
|
|
||||||
|
|
||||||
b58BKeyStr, err := mb.Encode(mb.Base58BTC, data)
|
|
||||||
if err != nil {
|
|
||||||
return ""
|
|
||||||
}
|
|
||||||
|
|
||||||
return fmt.Sprintf("%s:%s", KeyPrefix, b58BKeyStr)
|
|
||||||
}
|
|
||||||
|
|
||||||
// VerifyKey returns the backing implementation for a public key, one of:
|
|
||||||
// *rsa.PublicKey, ed25519.PublicKey
|
|
||||||
func (id DID) VerifyKey() (interface{}, error) {
|
|
||||||
rawPubBytes, err := id.Raw()
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
switch id.Type() {
|
|
||||||
case crypto.RSA:
|
|
||||||
verifyKeyiface, err := x509.ParsePKIXPublicKey(rawPubBytes)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
verifyKey, ok := verifyKeyiface.(*rsa.PublicKey)
|
|
||||||
if !ok {
|
|
||||||
return nil, fmt.Errorf("public key is not an RSA key. got type: %T", verifyKeyiface)
|
|
||||||
}
|
|
||||||
return verifyKey, nil
|
|
||||||
case crypto.Ed25519:
|
|
||||||
return ed25519.PublicKey(rawPubBytes), nil
|
|
||||||
case crypto.Secp256k1:
|
|
||||||
// Handle both compressed and uncompressed Secp256k1 public keys
|
|
||||||
if len(rawPubBytes) == 65 || len(rawPubBytes) == 33 {
|
|
||||||
return rawPubBytes, nil
|
|
||||||
}
|
|
||||||
return nil, fmt.Errorf("invalid Secp256k1 public key length: %d", len(rawPubBytes))
|
|
||||||
default:
|
|
||||||
return nil, fmt.Errorf("unrecognized Public Key type: %s", id.Type())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Parse turns a string into a key method ID
|
|
||||||
func Parse(keystr string) (DID, error) {
|
|
||||||
var id DID
|
|
||||||
if !strings.HasPrefix(keystr, KeyPrefix) {
|
|
||||||
return id, fmt.Errorf("decentralized identifier is not a 'key' type")
|
|
||||||
}
|
|
||||||
|
|
||||||
keystr = strings.TrimPrefix(keystr, KeyPrefix+":")
|
|
||||||
|
|
||||||
enc, data, err := mb.Decode(keystr)
|
|
||||||
if err != nil {
|
|
||||||
return id, fmt.Errorf("decoding multibase: %w", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
if enc != mb.Base58BTC {
|
|
||||||
return id, fmt.Errorf("unexpected multibase encoding: %s", mb.EncodingToStr[enc])
|
|
||||||
}
|
|
||||||
|
|
||||||
keyType, n, err := varint.FromUvarint(data)
|
|
||||||
if err != nil {
|
|
||||||
return id, err
|
|
||||||
}
|
|
||||||
|
|
||||||
switch keyType {
|
|
||||||
case MulticodecKindRSAPubKey:
|
|
||||||
pub, err := crypto.UnmarshalRsaPublicKey(data[n:])
|
|
||||||
if err != nil {
|
|
||||||
return id, err
|
|
||||||
}
|
|
||||||
return DID{pub}, nil
|
|
||||||
case MulticodecKindEd25519PubKey:
|
|
||||||
pub, err := crypto.UnmarshalEd25519PublicKey(data[n:])
|
|
||||||
if err != nil {
|
|
||||||
return id, err
|
|
||||||
}
|
|
||||||
return DID{pub}, nil
|
|
||||||
case MulticodecKindSecp256k1PubKey:
|
|
||||||
// Handle both compressed and uncompressed formats
|
|
||||||
keyData := data[n:]
|
|
||||||
if len(keyData) != 33 && len(keyData) != 65 {
|
|
||||||
return id, fmt.Errorf("invalid Secp256k1 public key length: %d", len(keyData))
|
|
||||||
}
|
|
||||||
pub, err := crypto.UnmarshalSecp256k1PublicKey(keyData)
|
|
||||||
if err != nil {
|
|
||||||
return id, fmt.Errorf("failed to unmarshal Secp256k1 key: %w", err)
|
|
||||||
}
|
|
||||||
return DID{pub}, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
return id, fmt.Errorf("unrecognized key type multicodec prefix: %x", data[0])
|
|
||||||
}
|
|
||||||
@@ -1,17 +0,0 @@
|
|||||||
package keys
|
|
||||||
|
|
||||||
type DIDMethod string
|
|
||||||
|
|
||||||
const (
|
|
||||||
DIDMethodKey DIDMethod = "key"
|
|
||||||
DIDMethodSonr DIDMethod = "sonr"
|
|
||||||
DIDMehthodBitcoin DIDMethod = "btcr"
|
|
||||||
DIDMethodEthereum DIDMethod = "ethr"
|
|
||||||
DIDMethodCbor DIDMethod = "cbor"
|
|
||||||
DIDMethodCID DIDMethod = "cid"
|
|
||||||
DIDMethodIPFS DIDMethod = "ipfs"
|
|
||||||
)
|
|
||||||
|
|
||||||
func (d DIDMethod) String() string {
|
|
||||||
return string(d)
|
|
||||||
}
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
package parsers
|
|
||||||
@@ -1,12 +0,0 @@
|
|||||||
package parsers
|
|
||||||
|
|
||||||
type CosmosPrefix string
|
|
||||||
|
|
||||||
const (
|
|
||||||
ATOMPrefix CosmosPrefix = "cosmos"
|
|
||||||
AXELARPrefix CosmosPrefix = "axelar"
|
|
||||||
EVMOSPrefix CosmosPrefix = "evmos"
|
|
||||||
OSMOPrefix CosmosPrefix = "osmo"
|
|
||||||
SONRPrefix CosmosPrefix = "idx"
|
|
||||||
STARSPrefix CosmosPrefix = "stars"
|
|
||||||
)
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
package parsers
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
package parsers
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
package parsers
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
package parsers
|
|
||||||
@@ -1,86 +0,0 @@
|
|||||||
package keys
|
|
||||||
|
|
||||||
import (
|
|
||||||
"bytes"
|
|
||||||
"crypto/ecdsa"
|
|
||||||
"encoding/hex"
|
|
||||||
|
|
||||||
p2pcrypto "github.com/libp2p/go-libp2p/core/crypto"
|
|
||||||
p2ppb "github.com/libp2p/go-libp2p/core/crypto/pb"
|
|
||||||
"github.com/onsonr/sonr/crypto/core/curves"
|
|
||||||
"golang.org/x/crypto/sha3"
|
|
||||||
)
|
|
||||||
|
|
||||||
type PubKey interface {
|
|
||||||
Bytes() []byte
|
|
||||||
Raw() ([]byte, error)
|
|
||||||
Equals(b p2pcrypto.Key) bool
|
|
||||||
Type() p2ppb.KeyType
|
|
||||||
Hex() string
|
|
||||||
Verify(msg []byte, sig []byte) (bool, error)
|
|
||||||
}
|
|
||||||
|
|
||||||
type pubKey struct {
|
|
||||||
publicPoint curves.Point
|
|
||||||
method string
|
|
||||||
}
|
|
||||||
|
|
||||||
func NewPubKey(pk curves.Point) PubKey {
|
|
||||||
return &pubKey{
|
|
||||||
publicPoint: pk,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (p pubKey) Bytes() []byte {
|
|
||||||
return p.publicPoint.ToAffineCompressed()
|
|
||||||
}
|
|
||||||
|
|
||||||
func (p pubKey) Raw() ([]byte, error) {
|
|
||||||
return p.publicPoint.ToAffineCompressed(), nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (p pubKey) Equals(b p2pcrypto.Key) bool {
|
|
||||||
if b == nil {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
apbz, err := b.Raw()
|
|
||||||
if err != nil {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
bbz, err := p.Raw()
|
|
||||||
if err != nil {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
return bytes.Equal(apbz, bbz)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (p pubKey) Hex() string {
|
|
||||||
return hex.EncodeToString(p.publicPoint.ToAffineCompressed())
|
|
||||||
}
|
|
||||||
|
|
||||||
func (p pubKey) Type() p2ppb.KeyType {
|
|
||||||
return p2ppb.KeyType_Secp256k1
|
|
||||||
}
|
|
||||||
|
|
||||||
func (p pubKey) Verify(data []byte, sigBz []byte) (bool, error) {
|
|
||||||
sig, err := deserializeSignature(sigBz)
|
|
||||||
if err != nil {
|
|
||||||
return false, err
|
|
||||||
}
|
|
||||||
pp, err := getEcdsaPoint(p.Bytes())
|
|
||||||
if err != nil {
|
|
||||||
return false, err
|
|
||||||
}
|
|
||||||
pk := &ecdsa.PublicKey{
|
|
||||||
Curve: pp.Curve,
|
|
||||||
X: pp.X,
|
|
||||||
Y: pp.Y,
|
|
||||||
}
|
|
||||||
|
|
||||||
// Hash the message using SHA3-256
|
|
||||||
hash := sha3.New256()
|
|
||||||
hash.Write(data)
|
|
||||||
digest := hash.Sum(nil)
|
|
||||||
|
|
||||||
return ecdsa.Verify(pk, digest, sig.R, sig.S), nil
|
|
||||||
}
|
|
||||||
@@ -1,46 +0,0 @@
|
|||||||
package keys
|
|
||||||
|
|
||||||
import (
|
|
||||||
"errors"
|
|
||||||
"fmt"
|
|
||||||
"math/big"
|
|
||||||
|
|
||||||
"github.com/onsonr/sonr/crypto/core/curves"
|
|
||||||
)
|
|
||||||
|
|
||||||
// getEcdsaPoint builds an elliptic curve point from a compressed byte slice
|
|
||||||
func getEcdsaPoint(pubKey []byte) (*curves.EcPoint, error) {
|
|
||||||
crv := curves.K256()
|
|
||||||
x := new(big.Int).SetBytes(pubKey[1:33])
|
|
||||||
y := new(big.Int).SetBytes(pubKey[33:])
|
|
||||||
ecCurve, err := crv.ToEllipticCurve()
|
|
||||||
if err != nil {
|
|
||||||
return nil, fmt.Errorf("error converting curve: %v", err)
|
|
||||||
}
|
|
||||||
return &curves.EcPoint{X: x, Y: y, Curve: ecCurve}, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// SerializeSecp256k1Signature serializes an ECDSA signature into a byte slice
|
|
||||||
func serializeSignature(sig *curves.EcdsaSignature) ([]byte, error) {
|
|
||||||
rBytes := sig.R.Bytes()
|
|
||||||
sBytes := sig.S.Bytes()
|
|
||||||
|
|
||||||
sigBytes := make([]byte, 66) // V (1 byte) + R (32 bytes) + S (32 bytes)
|
|
||||||
sigBytes[0] = byte(sig.V)
|
|
||||||
copy(sigBytes[33-len(rBytes):33], rBytes)
|
|
||||||
copy(sigBytes[66-len(sBytes):66], sBytes)
|
|
||||||
return sigBytes, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// DeserializeSecp256k1Signature deserializes an ECDSA signature from a byte slice
|
|
||||||
func deserializeSignature(sigBytes []byte) (*curves.EcdsaSignature, error) {
|
|
||||||
if len(sigBytes) != 66 {
|
|
||||||
return nil, errors.New("malformed signature: not the correct size")
|
|
||||||
}
|
|
||||||
sig := &curves.EcdsaSignature{
|
|
||||||
V: int(sigBytes[0]),
|
|
||||||
R: new(big.Int).SetBytes(sigBytes[1:33]),
|
|
||||||
S: new(big.Int).SetBytes(sigBytes[33:66]),
|
|
||||||
}
|
|
||||||
return sig, nil
|
|
||||||
}
|
|
||||||
@@ -1,42 +0,0 @@
|
|||||||
package mpc
|
|
||||||
|
|
||||||
import (
|
|
||||||
"github.com/onsonr/sonr/crypto/core/curves"
|
|
||||||
"github.com/onsonr/sonr/crypto/core/protocol"
|
|
||||||
"github.com/onsonr/sonr/crypto/keys"
|
|
||||||
"github.com/onsonr/sonr/crypto/tecdsa/dklsv1/dkg"
|
|
||||||
)
|
|
||||||
|
|
||||||
// ╭───────────────────────────────────────────────────────────╮
|
|
||||||
// │ Exported Generics │
|
|
||||||
// ╰───────────────────────────────────────────────────────────╯
|
|
||||||
|
|
||||||
type (
|
|
||||||
AliceOut *dkg.AliceOutput
|
|
||||||
BobOut *dkg.BobOutput
|
|
||||||
Point curves.Point
|
|
||||||
Role string // Role is the type for the role
|
|
||||||
Message *protocol.Message // Message is the protocol.Message that is used for MPC
|
|
||||||
Signature *curves.EcdsaSignature // Signature is the type for the signature
|
|
||||||
RefreshFunc interface{ protocol.Iterator } // RefreshFunc is the type for the refresh function
|
|
||||||
SignFunc interface{ protocol.Iterator } // SignFunc is the type for the sign function
|
|
||||||
)
|
|
||||||
|
|
||||||
const (
|
|
||||||
RoleVal = "validator"
|
|
||||||
RoleUser = "user"
|
|
||||||
)
|
|
||||||
|
|
||||||
// Enclave defines the interface for key management operations
|
|
||||||
type Enclave interface {
|
|
||||||
Address() string // Address returns the Sonr address of the keyEnclave
|
|
||||||
DID() keys.DID // DID returns the DID of the keyEnclave
|
|
||||||
Export(key []byte) ([]byte, error) // Export returns encrypted enclave data
|
|
||||||
Import(data []byte, key []byte) error // Import decrypts and loads enclave data
|
|
||||||
IsValid() bool // IsValid returns true if the keyEnclave is valid
|
|
||||||
PubKey() keys.PubKey // PubKey returns the public key of the keyEnclave
|
|
||||||
Refresh() (Enclave, error) // Refresh returns a new keyEnclave
|
|
||||||
Serialize() ([]byte, error) // Serialize returns the serialized keyEnclave
|
|
||||||
Sign(data []byte) ([]byte, error) // Sign returns the signature of the data
|
|
||||||
Verify(data []byte, sig []byte) (bool, error) // Verify returns true if the signature is valid
|
|
||||||
}
|
|
||||||
@@ -1,160 +0,0 @@
|
|||||||
package mpc
|
|
||||||
|
|
||||||
import (
|
|
||||||
"crypto/rand"
|
|
||||||
"strings"
|
|
||||||
"testing"
|
|
||||||
|
|
||||||
"github.com/stretchr/testify/assert"
|
|
||||||
"github.com/stretchr/testify/require"
|
|
||||||
)
|
|
||||||
|
|
||||||
func randNonce() []byte {
|
|
||||||
nonce := make([]byte, 12)
|
|
||||||
rand.Read(nonce)
|
|
||||||
return nonce
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestKeyShareGeneration(t *testing.T) {
|
|
||||||
t.Run("Generate Valid Enclave", func(t *testing.T) {
|
|
||||||
nonce := randNonce()
|
|
||||||
// Generate enclave
|
|
||||||
enclave, err := GenEnclave(nonce)
|
|
||||||
require.NoError(t, err)
|
|
||||||
require.NotNil(t, enclave)
|
|
||||||
|
|
||||||
// Validate enclave contents
|
|
||||||
assert.True(t, enclave.IsValid())
|
|
||||||
})
|
|
||||||
|
|
||||||
t.Run("Export and Import", func(t *testing.T) {
|
|
||||||
nonce := randNonce()
|
|
||||||
// Generate original enclave
|
|
||||||
original, err := GenEnclave(nonce)
|
|
||||||
require.NoError(t, err)
|
|
||||||
|
|
||||||
// Test key for encryption/decryption (32 bytes)
|
|
||||||
testKey := []byte("test-key-12345678-test-key-123456")
|
|
||||||
|
|
||||||
// Test Export/Import
|
|
||||||
t.Run("Full Enclave", func(t *testing.T) {
|
|
||||||
// Export enclave
|
|
||||||
data, err := original.Export(testKey)
|
|
||||||
require.NoError(t, err)
|
|
||||||
require.NotEmpty(t, data)
|
|
||||||
|
|
||||||
// Create new empty enclave
|
|
||||||
newEnclave, err := GenEnclave(nonce)
|
|
||||||
require.NoError(t, err)
|
|
||||||
|
|
||||||
// Import enclave
|
|
||||||
err = newEnclave.Import(data, testKey)
|
|
||||||
require.NoError(t, err)
|
|
||||||
|
|
||||||
// Verify the imported enclave works by signing
|
|
||||||
testData := []byte("test message")
|
|
||||||
sig, err := newEnclave.Sign(testData)
|
|
||||||
require.NoError(t, err)
|
|
||||||
valid, err := newEnclave.Verify(testData, sig)
|
|
||||||
require.NoError(t, err)
|
|
||||||
assert.True(t, valid)
|
|
||||||
})
|
|
||||||
|
|
||||||
// Test Invalid Key
|
|
||||||
t.Run("Invalid Key", func(t *testing.T) {
|
|
||||||
data, err := original.Export(testKey)
|
|
||||||
require.NoError(t, err)
|
|
||||||
|
|
||||||
wrongKey := []byte("wrong-key-12345678")
|
|
||||||
err = original.Import(data, wrongKey)
|
|
||||||
assert.Error(t, err)
|
|
||||||
})
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestEnclaveOperations(t *testing.T) {
|
|
||||||
t.Run("Signing and Verification", func(t *testing.T) {
|
|
||||||
nonce := randNonce()
|
|
||||||
// Generate valid enclave
|
|
||||||
enclave, err := GenEnclave(nonce)
|
|
||||||
require.NoError(t, err)
|
|
||||||
|
|
||||||
// Test signing
|
|
||||||
testData := []byte("test message")
|
|
||||||
signature, err := enclave.Sign(testData)
|
|
||||||
require.NoError(t, err)
|
|
||||||
require.NotNil(t, signature)
|
|
||||||
|
|
||||||
// Verify the signature
|
|
||||||
valid, err := enclave.Verify(testData, signature)
|
|
||||||
require.NoError(t, err)
|
|
||||||
assert.True(t, valid)
|
|
||||||
|
|
||||||
// Test invalid data verification
|
|
||||||
invalidData := []byte("wrong message")
|
|
||||||
valid, err = enclave.Verify(invalidData, signature)
|
|
||||||
require.NoError(t, err)
|
|
||||||
assert.False(t, valid)
|
|
||||||
})
|
|
||||||
|
|
||||||
t.Run("Address and Public Key", func(t *testing.T) {
|
|
||||||
nonce := randNonce()
|
|
||||||
enclave, err := GenEnclave(nonce)
|
|
||||||
require.NoError(t, err)
|
|
||||||
|
|
||||||
// Test Address
|
|
||||||
addr := enclave.Address()
|
|
||||||
assert.NotEmpty(t, addr)
|
|
||||||
assert.True(t, strings.HasPrefix(addr, "idx"))
|
|
||||||
|
|
||||||
// Test Public Key
|
|
||||||
pubKey := enclave.PubKey()
|
|
||||||
assert.NotNil(t, pubKey)
|
|
||||||
assert.NotEmpty(t, pubKey.Bytes())
|
|
||||||
})
|
|
||||||
|
|
||||||
t.Run("Refresh Operation", func(t *testing.T) {
|
|
||||||
nonce := randNonce()
|
|
||||||
enclave, err := GenEnclave(nonce)
|
|
||||||
require.NoError(t, err)
|
|
||||||
|
|
||||||
// Test refresh
|
|
||||||
refreshedEnclave, err := enclave.Refresh()
|
|
||||||
require.NoError(t, err)
|
|
||||||
require.NotNil(t, refreshedEnclave)
|
|
||||||
|
|
||||||
// Verify refreshed enclave is valid
|
|
||||||
assert.True(t, refreshedEnclave.IsValid())
|
|
||||||
|
|
||||||
// Verify it maintains the same address
|
|
||||||
assert.Equal(t, enclave.Address(), refreshedEnclave.Address())
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestEnclaveSerialization(t *testing.T) {
|
|
||||||
t.Run("Marshal and Unmarshal", func(t *testing.T) {
|
|
||||||
nonce := randNonce()
|
|
||||||
// Generate original enclave
|
|
||||||
original, err := GenEnclave(nonce)
|
|
||||||
require.NoError(t, err)
|
|
||||||
require.NotNil(t, original)
|
|
||||||
|
|
||||||
// Marshal
|
|
||||||
keyclave, ok := original.(*keyEnclave)
|
|
||||||
require.True(t, ok)
|
|
||||||
|
|
||||||
data, err := keyclave.Serialize()
|
|
||||||
require.NoError(t, err)
|
|
||||||
require.NotEmpty(t, data)
|
|
||||||
|
|
||||||
// Unmarshal
|
|
||||||
restored := &keyEnclave{}
|
|
||||||
err = restored.Unmarshal(data)
|
|
||||||
require.NoError(t, err)
|
|
||||||
|
|
||||||
// Verify restored enclave
|
|
||||||
assert.Equal(t, keyclave.Addr, restored.Addr)
|
|
||||||
assert.True(t, keyclave.PubPoint.Equal(restored.PubPoint))
|
|
||||||
assert.True(t, restored.IsValid())
|
|
||||||
})
|
|
||||||
}
|
|
||||||
@@ -1,179 +0,0 @@
|
|||||||
package mpc
|
|
||||||
|
|
||||||
import (
|
|
||||||
"crypto/aes"
|
|
||||||
"crypto/cipher"
|
|
||||||
"crypto/ecdsa"
|
|
||||||
"encoding/json"
|
|
||||||
"fmt"
|
|
||||||
|
|
||||||
"github.com/onsonr/sonr/crypto/core/curves"
|
|
||||||
"github.com/onsonr/sonr/crypto/keys"
|
|
||||||
"golang.org/x/crypto/sha3"
|
|
||||||
)
|
|
||||||
|
|
||||||
// keyEnclave implements the Enclave interface
|
|
||||||
type keyEnclave struct {
|
|
||||||
// Serialized fields
|
|
||||||
Addr string `json:"address"`
|
|
||||||
PubPoint curves.Point `json:"-"`
|
|
||||||
PubBytes []byte `json:"pub_key"`
|
|
||||||
ValShare Message `json:"val_share"`
|
|
||||||
UserShare Message `json:"user_share"`
|
|
||||||
|
|
||||||
// Extra fields
|
|
||||||
nonce []byte
|
|
||||||
}
|
|
||||||
|
|
||||||
func newEnclave(valShare, userShare Message, nonce []byte) (Enclave, error) {
|
|
||||||
pubPoint, err := getAlicePubPoint(valShare)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
addr, err := computeSonrAddr(pubPoint)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return &keyEnclave{
|
|
||||||
Addr: addr,
|
|
||||||
PubPoint: pubPoint,
|
|
||||||
ValShare: valShare,
|
|
||||||
UserShare: userShare,
|
|
||||||
nonce: nonce,
|
|
||||||
}, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// Address returns the Sonr address of the keyEnclave
|
|
||||||
func (k *keyEnclave) Address() string {
|
|
||||||
return k.Addr
|
|
||||||
}
|
|
||||||
|
|
||||||
// DID returns the DID of the keyEnclave
|
|
||||||
func (k *keyEnclave) DID() keys.DID {
|
|
||||||
return keys.NewFromPubKey(k.PubKey())
|
|
||||||
}
|
|
||||||
|
|
||||||
// Export returns encrypted enclave data
|
|
||||||
func (k *keyEnclave) Export(key []byte) ([]byte, error) {
|
|
||||||
data, err := k.Serialize()
|
|
||||||
if err != nil {
|
|
||||||
return nil, fmt.Errorf("failed to serialize enclave: %w", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
hashedKey := hashKey(key)
|
|
||||||
block, err := aes.NewCipher(hashedKey)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
aesgcm, err := cipher.NewGCM(block)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
return aesgcm.Seal(nil, k.nonce, data, nil), nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// Import decrypts and loads enclave data
|
|
||||||
func (k *keyEnclave) Import(data []byte, key []byte) error {
|
|
||||||
hashedKey := hashKey(key)
|
|
||||||
block, err := aes.NewCipher(hashedKey)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
aesgcm, err := cipher.NewGCM(block)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
decrypted, err := aesgcm.Open(nil, k.nonce, data, nil)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
return k.Unmarshal(decrypted)
|
|
||||||
}
|
|
||||||
|
|
||||||
// IsValid returns true if the keyEnclave is valid
|
|
||||||
func (k *keyEnclave) IsValid() bool {
|
|
||||||
return k.PubPoint != nil && k.ValShare != nil && k.UserShare != nil && k.Addr != ""
|
|
||||||
}
|
|
||||||
|
|
||||||
// PubKey returns the public key of the keyEnclave
|
|
||||||
func (k *keyEnclave) PubKey() keys.PubKey {
|
|
||||||
return keys.NewPubKey(k.PubPoint)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Refresh returns a new keyEnclave
|
|
||||||
func (k *keyEnclave) Refresh() (Enclave, error) {
|
|
||||||
refreshFuncVal, err := valRefreshFunc(k)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
refreshFuncUser, err := userRefreshFunc(k)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return ExecuteRefresh(refreshFuncVal, refreshFuncUser, k.nonce)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Sign returns the signature of the data
|
|
||||||
func (k *keyEnclave) Sign(data []byte) ([]byte, error) {
|
|
||||||
userSign, err := userSignFunc(k, data)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
valSign, err := valSignFunc(k, data)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return ExecuteSigning(valSign, userSign)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Verify returns true if the signature is valid
|
|
||||||
func (k *keyEnclave) Verify(data []byte, sig []byte) (bool, error) {
|
|
||||||
edSig, err := deserializeSignature(sig)
|
|
||||||
if err != nil {
|
|
||||||
return false, err
|
|
||||||
}
|
|
||||||
ePub, err := getEcdsaPoint(k.PubPoint.ToAffineUncompressed())
|
|
||||||
if err != nil {
|
|
||||||
return false, err
|
|
||||||
}
|
|
||||||
pk := &ecdsa.PublicKey{
|
|
||||||
Curve: ePub.Curve,
|
|
||||||
X: ePub.X,
|
|
||||||
Y: ePub.Y,
|
|
||||||
}
|
|
||||||
|
|
||||||
// Hash the message using SHA3-256
|
|
||||||
hash := sha3.New256()
|
|
||||||
hash.Write(data)
|
|
||||||
digest := hash.Sum(nil)
|
|
||||||
|
|
||||||
return ecdsa.Verify(pk, digest, edSig.R, edSig.S), nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// Marshal returns the JSON encoding of keyEnclave
|
|
||||||
func (k *keyEnclave) Serialize() ([]byte, error) {
|
|
||||||
// Store compressed public point bytes before marshaling
|
|
||||||
k.PubBytes = k.PubPoint.ToAffineCompressed()
|
|
||||||
return json.Marshal(k)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Unmarshal parses the JSON-encoded data and stores the result
|
|
||||||
func (k *keyEnclave) Unmarshal(data []byte) error {
|
|
||||||
if err := json.Unmarshal(data, k); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
// Reconstruct Point from bytes
|
|
||||||
curve := curves.K256()
|
|
||||||
point, err := curve.NewIdentityPoint().FromAffineCompressed(k.PubBytes)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
k.PubPoint = point
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
@@ -0,0 +1,61 @@
|
|||||||
|
package mpc
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
|
||||||
|
"github.com/cosmos/cosmos-sdk/types/bech32"
|
||||||
|
)
|
||||||
|
|
||||||
|
type (
|
||||||
|
ExportedKeyset = []byte
|
||||||
|
)
|
||||||
|
|
||||||
|
type Keyset interface {
|
||||||
|
Address() string
|
||||||
|
Val() *ValKeyshare
|
||||||
|
ValJSON() string
|
||||||
|
User() *UserKeyshare
|
||||||
|
UserJSON() string
|
||||||
|
}
|
||||||
|
|
||||||
|
type keyset struct {
|
||||||
|
val *ValKeyshare
|
||||||
|
user *UserKeyshare
|
||||||
|
addr string
|
||||||
|
}
|
||||||
|
|
||||||
|
func (k keyset) Address() string {
|
||||||
|
return k.addr
|
||||||
|
}
|
||||||
|
|
||||||
|
func (k keyset) Val() *ValKeyshare {
|
||||||
|
return k.val
|
||||||
|
}
|
||||||
|
|
||||||
|
func (k keyset) User() *UserKeyshare {
|
||||||
|
return k.user
|
||||||
|
}
|
||||||
|
|
||||||
|
func (k keyset) ValJSON() string {
|
||||||
|
return k.val.String()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (k keyset) UserJSON() string {
|
||||||
|
return k.user.String()
|
||||||
|
}
|
||||||
|
|
||||||
|
func ComputeIssuerDID(pk []byte) (string, string, error) {
|
||||||
|
addr, err := ComputeSonrAddr(pk)
|
||||||
|
if err != nil {
|
||||||
|
return "", "", err
|
||||||
|
}
|
||||||
|
return fmt.Sprintf("did:sonr:%s", addr), addr, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func ComputeSonrAddr(pk []byte) (string, error) {
|
||||||
|
sonrAddr, err := bech32.ConvertAndEncode("idx", pk)
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
return sonrAddr, nil
|
||||||
|
}
|
||||||
@@ -0,0 +1,71 @@
|
|||||||
|
package mpc
|
||||||
|
|
||||||
|
import (
|
||||||
|
"crypto/ecdsa"
|
||||||
|
|
||||||
|
"github.com/onsonr/sonr/crypto/core/protocol"
|
||||||
|
"github.com/onsonr/sonr/crypto/tecdsa/dklsv1/dkg"
|
||||||
|
)
|
||||||
|
|
||||||
|
// BaseKeyshare contains common fields and methods for both validator and user keyshares
|
||||||
|
type BaseKeyshare struct {
|
||||||
|
Message *protocol.Message `json:"message"`
|
||||||
|
Role int `json:"role"`
|
||||||
|
UncompressedPubKey []byte `json:"public_key"`
|
||||||
|
CompressedPubKey []byte `json:"compressed_public_key"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func initFromAlice(aliceOut *dkg.AliceOutput, originalMsg *protocol.Message) BaseKeyshare {
|
||||||
|
return BaseKeyshare{
|
||||||
|
Message: originalMsg,
|
||||||
|
Role: 1,
|
||||||
|
UncompressedPubKey: aliceOut.PublicKey.ToAffineUncompressed(),
|
||||||
|
CompressedPubKey: aliceOut.PublicKey.ToAffineCompressed(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func initFromBob(bobOut *dkg.BobOutput, originalMsg *protocol.Message) BaseKeyshare {
|
||||||
|
return BaseKeyshare{
|
||||||
|
Message: originalMsg,
|
||||||
|
Role: 2,
|
||||||
|
UncompressedPubKey: bobOut.PublicKey.ToAffineUncompressed(),
|
||||||
|
CompressedPubKey: bobOut.PublicKey.ToAffineCompressed(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (b *BaseKeyshare) GetPayloads() map[string][]byte {
|
||||||
|
return b.Message.Payloads
|
||||||
|
}
|
||||||
|
|
||||||
|
func (b *BaseKeyshare) GetMetadata() map[string]string {
|
||||||
|
return b.Message.Metadata
|
||||||
|
}
|
||||||
|
|
||||||
|
func (b *BaseKeyshare) GetPublicKey() []byte {
|
||||||
|
return b.UncompressedPubKey
|
||||||
|
}
|
||||||
|
|
||||||
|
func (b *BaseKeyshare) GetProtocol() string {
|
||||||
|
return b.Message.Protocol
|
||||||
|
}
|
||||||
|
|
||||||
|
func (b *BaseKeyshare) GetRole() int32 {
|
||||||
|
return int32(b.Role)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (b *BaseKeyshare) GetVersion() uint32 {
|
||||||
|
return uint32(b.Message.Version)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (b *BaseKeyshare) ECDSAPublicKey() (*ecdsa.PublicKey, error) {
|
||||||
|
return ComputeEcdsaPublicKey(b.UncompressedPubKey)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (b *BaseKeyshare) ExtractMessage() *protocol.Message {
|
||||||
|
return &protocol.Message{
|
||||||
|
Payloads: b.GetPayloads(),
|
||||||
|
Metadata: b.GetMetadata(),
|
||||||
|
Protocol: b.GetProtocol(),
|
||||||
|
Version: uint(b.GetVersion()),
|
||||||
|
}
|
||||||
|
}
|
||||||
+124
-15
@@ -1,13 +1,20 @@
|
|||||||
package mpc
|
package mpc
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"crypto/ecdsa"
|
||||||
|
genericecdsa "crypto/ecdsa"
|
||||||
|
"errors"
|
||||||
|
"fmt"
|
||||||
|
"math/big"
|
||||||
|
|
||||||
"github.com/onsonr/sonr/crypto/core/curves"
|
"github.com/onsonr/sonr/crypto/core/curves"
|
||||||
"github.com/onsonr/sonr/crypto/core/protocol"
|
"github.com/onsonr/sonr/crypto/core/protocol"
|
||||||
"github.com/onsonr/sonr/crypto/tecdsa/dklsv1"
|
"github.com/onsonr/sonr/crypto/tecdsa/dklsv1"
|
||||||
|
"golang.org/x/crypto/sha3"
|
||||||
)
|
)
|
||||||
|
|
||||||
// GenEnclave generates a new MPC keyshare
|
// NewKeyshareSource generates a new MPC keyshare
|
||||||
func GenEnclave(nonce []byte) (Enclave, error) {
|
func NewKeyset() (Keyset, error) {
|
||||||
curve := curves.K256()
|
curve := curves.K256()
|
||||||
valKs := dklsv1.NewAliceDkg(curve, protocol.Version1)
|
valKs := dklsv1.NewAliceDkg(curve, protocol.Version1)
|
||||||
userKs := dklsv1.NewBobDkg(curve, protocol.Version1)
|
userKs := dklsv1.NewBobDkg(curve, protocol.Version1)
|
||||||
@@ -19,15 +26,27 @@ func GenEnclave(nonce []byte) (Enclave, error) {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
valShare, err := NewValKeyshare(valRes)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
userRes, err := userKs.Result(protocol.Version1)
|
userRes, err := userKs.Result(protocol.Version1)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
return newEnclave(valRes, userRes, nonce)
|
userShare, err := NewUserKeyshare(userRes)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
addr, err := computeSonrAddr(valShare.CompressedPublicKey())
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return keyset{val: valShare, user: userShare, addr: addr}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// ExecuteSigning runs the MPC signing protocol
|
// ExecuteSigning runs the MPC signing protocol
|
||||||
func ExecuteSigning(signFuncVal SignFunc, signFuncUser SignFunc) ([]byte, error) {
|
func ExecuteSigning(signFuncVal SignFunc, signFuncUser SignFunc) (Signature, error) {
|
||||||
aErr, bErr := RunProtocol(signFuncVal, signFuncUser)
|
aErr, bErr := RunProtocol(signFuncVal, signFuncUser)
|
||||||
if err := checkIteratedErrors(aErr, bErr); err != nil {
|
if err := checkIteratedErrors(aErr, bErr); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
@@ -36,19 +55,11 @@ func ExecuteSigning(signFuncVal SignFunc, signFuncUser SignFunc) ([]byte, error)
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
s, err := dklsv1.DecodeSignature(out)
|
return dklsv1.DecodeSignature(out)
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
sig, err := serializeSignature(s)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return sig, nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// ExecuteRefresh runs the MPC refresh protocol
|
// ExecuteRefresh runs the MPC refresh protocol
|
||||||
func ExecuteRefresh(refreshFuncVal RefreshFunc, refreshFuncUser RefreshFunc, nonce []byte) (Enclave, error) {
|
func ExecuteRefresh(refreshFuncVal RefreshFunc, refreshFuncUser RefreshFunc) (Keyset, error) {
|
||||||
aErr, bErr := RunProtocol(refreshFuncVal, refreshFuncUser)
|
aErr, bErr := RunProtocol(refreshFuncVal, refreshFuncUser)
|
||||||
if err := checkIteratedErrors(aErr, bErr); err != nil {
|
if err := checkIteratedErrors(aErr, bErr); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
@@ -57,11 +68,53 @@ func ExecuteRefresh(refreshFuncVal RefreshFunc, refreshFuncUser RefreshFunc, non
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
valShare, err := NewValKeyshare(valRefreshResult)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
userRefreshResult, err := refreshFuncUser.Result(protocol.Version1)
|
userRefreshResult, err := refreshFuncUser.Result(protocol.Version1)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
return newEnclave(valRefreshResult, userRefreshResult, nonce)
|
userShare, err := NewUserKeyshare(userRefreshResult)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
addr, err := computeSonrAddr(valShare.CompressedPublicKey())
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return keyset{val: valShare, user: userShare, addr: addr}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// SerializeSecp256k1Signature serializes an ECDSA signature into a byte slice
|
||||||
|
func SerializeSignature(sig Signature) ([]byte, error) {
|
||||||
|
rBytes := sig.R.Bytes()
|
||||||
|
sBytes := sig.S.Bytes()
|
||||||
|
|
||||||
|
sigBytes := make([]byte, 66) // V (1 byte) + R (32 bytes) + S (32 bytes)
|
||||||
|
sigBytes[0] = byte(sig.V)
|
||||||
|
copy(sigBytes[33-len(rBytes):33], rBytes)
|
||||||
|
copy(sigBytes[66-len(sBytes):66], sBytes)
|
||||||
|
return sigBytes, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// DeserializeSecp256k1Signature deserializes an ECDSA signature from a byte slice
|
||||||
|
func DeserializeSignature(sigBytes []byte) (Signature, error) {
|
||||||
|
if len(sigBytes) != 66 {
|
||||||
|
return nil, errors.New("malformed signature: not the correct size")
|
||||||
|
}
|
||||||
|
sig := &curves.EcdsaSignature{
|
||||||
|
V: int(sigBytes[0]),
|
||||||
|
R: new(big.Int).SetBytes(sigBytes[1:33]),
|
||||||
|
S: new(big.Int).SetBytes(sigBytes[33:66]),
|
||||||
|
}
|
||||||
|
return sig, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// VerifyMPCSignature verifies an MPC signature
|
||||||
|
func VerifyMPCSignature(sig Signature, msg []byte, publicKey *ecdsa.PublicKey) bool {
|
||||||
|
return ecdsa.Verify(publicKey, msg, sig.R, sig.S)
|
||||||
}
|
}
|
||||||
|
|
||||||
// For DKG bob starts first. For refresh and sign, Alice starts first.
|
// For DKG bob starts first. For refresh and sign, Alice starts first.
|
||||||
@@ -86,3 +139,59 @@ func RunProtocol(firstParty protocol.Iterator, secondParty protocol.Iterator) (e
|
|||||||
}
|
}
|
||||||
return aErr, bErr
|
return aErr, bErr
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ComputeEcPoint builds an elliptic curve point from a compressed byte slice
|
||||||
|
func ComputeEcPoint(pubKey []byte) (*curves.EcPoint, error) {
|
||||||
|
crv := curves.K256()
|
||||||
|
x := new(big.Int).SetBytes(pubKey[1:33])
|
||||||
|
y := new(big.Int).SetBytes(pubKey[33:])
|
||||||
|
ecCurve, err := crv.ToEllipticCurve()
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("error converting curve: %v", err)
|
||||||
|
}
|
||||||
|
return &curves.EcPoint{X: x, Y: y, Curve: ecCurve}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func ComputeEcdsaPublicKey(pubKey []byte) (*genericecdsa.PublicKey, error) {
|
||||||
|
pk, err := ComputeEcPoint(pubKey)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return &genericecdsa.PublicKey{
|
||||||
|
Curve: pk.Curve,
|
||||||
|
X: pk.X,
|
||||||
|
Y: pk.Y,
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// VerifySignature verifies the signature of a message
|
||||||
|
func VerifySignature(pk []byte, msg []byte, sig []byte) (bool, error) {
|
||||||
|
pp, err := ComputeEcPoint(pk)
|
||||||
|
if err != nil {
|
||||||
|
return false, err
|
||||||
|
}
|
||||||
|
sigEd, err := DeserializeSignature(sig)
|
||||||
|
if err != nil {
|
||||||
|
return false, err
|
||||||
|
}
|
||||||
|
hash := sha3.New256()
|
||||||
|
_, err = hash.Write(msg)
|
||||||
|
if err != nil {
|
||||||
|
return false, err
|
||||||
|
}
|
||||||
|
digest := hash.Sum(nil)
|
||||||
|
return curves.VerifyEcdsa(pp, digest[:], sigEd), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func checkIteratedErrors(aErr, bErr error) error {
|
||||||
|
if aErr == protocol.ErrProtocolFinished && bErr == protocol.ErrProtocolFinished {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
if aErr != protocol.ErrProtocolFinished {
|
||||||
|
return aErr
|
||||||
|
}
|
||||||
|
if bErr != protocol.ErrProtocolFinished {
|
||||||
|
return bErr
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|||||||
@@ -0,0 +1,150 @@
|
|||||||
|
package mpc
|
||||||
|
|
||||||
|
import (
|
||||||
|
"errors"
|
||||||
|
|
||||||
|
"github.com/cosmos/cosmos-sdk/types/bech32"
|
||||||
|
"github.com/onsonr/sonr/crypto/core/curves"
|
||||||
|
"github.com/onsonr/sonr/crypto/core/protocol"
|
||||||
|
"github.com/onsonr/sonr/crypto/tecdsa/dklsv1"
|
||||||
|
"golang.org/x/crypto/sha3"
|
||||||
|
)
|
||||||
|
|
||||||
|
var ErrInvalidKeyshareRole = errors.New("invalid keyshare role")
|
||||||
|
|
||||||
|
type Role int
|
||||||
|
|
||||||
|
const (
|
||||||
|
RoleUnknown Role = iota
|
||||||
|
RoleUser
|
||||||
|
RoleValidator
|
||||||
|
)
|
||||||
|
|
||||||
|
func (r Role) IsUser() bool {
|
||||||
|
return r == RoleUser
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r Role) IsValidator() bool {
|
||||||
|
return r == RoleValidator
|
||||||
|
}
|
||||||
|
|
||||||
|
// Message is the protocol.Message that is used for MPC
|
||||||
|
type Message *protocol.Message
|
||||||
|
|
||||||
|
type Signature *curves.EcdsaSignature
|
||||||
|
|
||||||
|
// RefreshFunc is the type for the refresh function
|
||||||
|
type RefreshFunc interface {
|
||||||
|
protocol.Iterator
|
||||||
|
}
|
||||||
|
|
||||||
|
// SignFunc is the type for the sign function
|
||||||
|
type SignFunc interface {
|
||||||
|
protocol.Iterator
|
||||||
|
}
|
||||||
|
|
||||||
|
type ValKeyshare struct {
|
||||||
|
BaseKeyshare
|
||||||
|
encoded string
|
||||||
|
}
|
||||||
|
|
||||||
|
func computeSonrAddr(pk []byte) (string, error) {
|
||||||
|
sonrAddr, err := bech32.ConvertAndEncode("idx", pk)
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
return sonrAddr, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewValKeyshare(msg *protocol.Message) (*ValKeyshare, error) {
|
||||||
|
vks := new(ValKeyshare)
|
||||||
|
encoded, err := protocol.EncodeMessage(msg)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
valShare, err := dklsv1.DecodeAliceDkgResult(msg)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
vks.BaseKeyshare = initFromAlice(valShare, msg)
|
||||||
|
vks.encoded = encoded
|
||||||
|
return vks, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (v *ValKeyshare) RefreshFunc() (RefreshFunc, error) {
|
||||||
|
curve := curves.K256()
|
||||||
|
return dklsv1.NewAliceRefresh(curve, v.ExtractMessage(), protocol.Version1)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (v *ValKeyshare) SignFunc(msg []byte) (SignFunc, error) {
|
||||||
|
curve := curves.K256()
|
||||||
|
return dklsv1.NewAliceSign(curve, sha3.New256(), msg, v.ExtractMessage(), protocol.Version1)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (v *ValKeyshare) String() string {
|
||||||
|
return v.encoded
|
||||||
|
}
|
||||||
|
|
||||||
|
// PublicKey returns the uncompressed public key (65 bytes)
|
||||||
|
func (v *ValKeyshare) PublicKey() []byte {
|
||||||
|
return v.UncompressedPubKey
|
||||||
|
}
|
||||||
|
|
||||||
|
// CompressedPublicKey returns the compressed public key (33 bytes)
|
||||||
|
func (v *ValKeyshare) CompressedPublicKey() []byte {
|
||||||
|
return v.CompressedPubKey
|
||||||
|
}
|
||||||
|
|
||||||
|
type UserKeyshare struct {
|
||||||
|
BaseKeyshare
|
||||||
|
encoded string
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewUserKeyshare(msg *protocol.Message) (*UserKeyshare, error) {
|
||||||
|
uks := new(UserKeyshare)
|
||||||
|
encoded, err := protocol.EncodeMessage(msg)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
out, err := dklsv1.DecodeBobDkgResult(msg)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
uks.BaseKeyshare = initFromBob(out, msg)
|
||||||
|
uks.encoded = encoded
|
||||||
|
return uks, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (u *UserKeyshare) RefreshFunc() (RefreshFunc, error) {
|
||||||
|
curve := curves.K256()
|
||||||
|
return dklsv1.NewBobRefresh(curve, u.ExtractMessage(), protocol.Version1)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (u *UserKeyshare) SignFunc(msg []byte) (SignFunc, error) {
|
||||||
|
curve := curves.K256()
|
||||||
|
return dklsv1.NewBobSign(curve, sha3.New256(), msg, u.ExtractMessage(), protocol.Version1)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (u *UserKeyshare) String() string {
|
||||||
|
return u.encoded
|
||||||
|
}
|
||||||
|
|
||||||
|
// PublicKey returns the uncompressed public key (65 bytes)
|
||||||
|
func (u *UserKeyshare) PublicKey() []byte {
|
||||||
|
return u.UncompressedPubKey
|
||||||
|
}
|
||||||
|
|
||||||
|
// CompressedPublicKey returns the compressed public key (33 bytes)
|
||||||
|
func (u *UserKeyshare) CompressedPublicKey() []byte {
|
||||||
|
return u.CompressedPubKey
|
||||||
|
}
|
||||||
|
|
||||||
|
func encodeMessage(m *protocol.Message) (string, error) {
|
||||||
|
return protocol.EncodeMessage(m)
|
||||||
|
}
|
||||||
|
|
||||||
|
func decodeMessage(s string) (*protocol.Message, error) {
|
||||||
|
return protocol.DecodeMessage(s)
|
||||||
|
}
|
||||||
@@ -1,83 +0,0 @@
|
|||||||
package spec
|
|
||||||
|
|
||||||
import (
|
|
||||||
"crypto/sha256"
|
|
||||||
|
|
||||||
"github.com/golang-jwt/jwt"
|
|
||||||
)
|
|
||||||
|
|
||||||
// MPCSigningMethod implements the SigningMethod interface for MPC-based signing
|
|
||||||
type MPCSigningMethod struct {
|
|
||||||
Name string
|
|
||||||
ks ucanKeyshare
|
|
||||||
}
|
|
||||||
|
|
||||||
// NewJWTSigningMethod creates a new MPC signing method with the given keyshare source
|
|
||||||
func NewJWTSigningMethod(name string, ks ucanKeyshare) *MPCSigningMethod {
|
|
||||||
return &MPCSigningMethod{
|
|
||||||
Name: name,
|
|
||||||
ks: ks,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Alg returns the signing method's name
|
|
||||||
func (m *MPCSigningMethod) Alg() string {
|
|
||||||
return m.Name
|
|
||||||
}
|
|
||||||
|
|
||||||
// Verify verifies the signature using the MPC public key
|
|
||||||
func (m *MPCSigningMethod) Verify(signingString, signature string, key interface{}) error {
|
|
||||||
// // Decode the signature
|
|
||||||
// sig, err := base64.RawURLEncoding.DecodeString(signature)
|
|
||||||
// if err != nil {
|
|
||||||
// return err
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// // Hash the signing string
|
|
||||||
// hasher := sha256.New()
|
|
||||||
// hasher.Write([]byte(signingString))
|
|
||||||
// digest := hasher.Sum(nil)
|
|
||||||
// valid, err := m.ks.valShare.PublicKey().Verify(digest, sig)
|
|
||||||
// if !valid || err != nil {
|
|
||||||
// return fmt.Errorf("invalid signature")
|
|
||||||
// }
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// Sign signs the data using MPC
|
|
||||||
func (m *MPCSigningMethod) Sign(signingString string, key interface{}) (string, error) {
|
|
||||||
// Hash the signing string
|
|
||||||
hasher := sha256.New()
|
|
||||||
hasher.Write([]byte(signingString))
|
|
||||||
// digest := hasher.Sum(nil)
|
|
||||||
//
|
|
||||||
// // Create signing functions
|
|
||||||
// signFunc, err := m.ks.userShare.SignFunc(digest)
|
|
||||||
// if err != nil {
|
|
||||||
// return "", fmt.Errorf("failed to create sign function: %w", err)
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// valSignFunc, err := m.ks.valShare.SignFunc(digest)
|
|
||||||
// if err != nil {
|
|
||||||
// return "", fmt.Errorf("failed to create validator sign function: %w", err)
|
|
||||||
// }
|
|
||||||
|
|
||||||
// // Run the signing protocol
|
|
||||||
// sig, err := mpc.ExecuteSigning(valSignFunc, signFunc)
|
|
||||||
// if err != nil {
|
|
||||||
// return "", fmt.Errorf("failed to run sign protocol: %w", err)
|
|
||||||
// }
|
|
||||||
|
|
||||||
// Encode the signature
|
|
||||||
// encoded := base64.RawURLEncoding.EncodeToString(sig)
|
|
||||||
return "", nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func init() {
|
|
||||||
// Register the MPC signing method
|
|
||||||
jwt.RegisterSigningMethod("MPC256", func() jwt.SigningMethod {
|
|
||||||
return &MPCSigningMethod{
|
|
||||||
Name: "MPC256",
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
@@ -1,170 +0,0 @@
|
|||||||
package mpc
|
|
||||||
|
|
||||||
import (
|
|
||||||
"crypto/aes"
|
|
||||||
"crypto/cipher"
|
|
||||||
"errors"
|
|
||||||
"fmt"
|
|
||||||
"math/big"
|
|
||||||
|
|
||||||
"github.com/cosmos/cosmos-sdk/types/bech32"
|
|
||||||
"github.com/onsonr/sonr/crypto/core/curves"
|
|
||||||
"github.com/onsonr/sonr/crypto/core/protocol"
|
|
||||||
"github.com/onsonr/sonr/crypto/tecdsa/dklsv1"
|
|
||||||
"golang.org/x/crypto/sha3"
|
|
||||||
)
|
|
||||||
|
|
||||||
func checkIteratedErrors(aErr, bErr error) error {
|
|
||||||
if aErr == protocol.ErrProtocolFinished && bErr == protocol.ErrProtocolFinished {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
if aErr != protocol.ErrProtocolFinished {
|
|
||||||
return aErr
|
|
||||||
}
|
|
||||||
if bErr != protocol.ErrProtocolFinished {
|
|
||||||
return bErr
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func computeSonrAddr(pp Point) (string, error) {
|
|
||||||
pk := pp.ToAffineCompressed()
|
|
||||||
sonrAddr, err := bech32.ConvertAndEncode("idx", pk)
|
|
||||||
if err != nil {
|
|
||||||
return "", err
|
|
||||||
}
|
|
||||||
return sonrAddr, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func hashKey(key []byte) []byte {
|
|
||||||
hash := sha3.New256()
|
|
||||||
hash.Write(key)
|
|
||||||
return hash.Sum(nil)[:32] // Use first 32 bytes of hash
|
|
||||||
}
|
|
||||||
|
|
||||||
func decryptKeyshare(msg []byte, key []byte, nonce []byte) ([]byte, error) {
|
|
||||||
hashedKey := hashKey(key)
|
|
||||||
block, err := aes.NewCipher(hashedKey)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
aesgcm, err := cipher.NewGCM(block)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
plaintext, err := aesgcm.Open(nil, nonce, msg, nil)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return plaintext, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func encryptKeyshare(msg Message, key []byte, nonce []byte) ([]byte, error) {
|
|
||||||
hashedKey := hashKey(key)
|
|
||||||
msgBytes, err := protocol.EncodeMessage(msg)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
block, err := aes.NewCipher(hashedKey)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
aesgcm, err := cipher.NewGCM(block)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
ciphertext := aesgcm.Seal(nil, nonce, []byte(msgBytes), nil)
|
|
||||||
return ciphertext, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func getAliceOut(msg *protocol.Message) (AliceOut, error) {
|
|
||||||
return dklsv1.DecodeAliceDkgResult(msg)
|
|
||||||
}
|
|
||||||
|
|
||||||
func getAlicePubPoint(msg *protocol.Message) (Point, error) {
|
|
||||||
out, err := dklsv1.DecodeAliceDkgResult(msg)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return out.PublicKey, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func getBobOut(msg *protocol.Message) (BobOut, error) {
|
|
||||||
return dklsv1.DecodeBobDkgResult(msg)
|
|
||||||
}
|
|
||||||
|
|
||||||
func getBobPubPoint(msg *protocol.Message) (Point, error) {
|
|
||||||
out, err := dklsv1.DecodeBobDkgResult(msg)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return out.PublicKey, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// getEcdsaPoint builds an elliptic curve point from a compressed byte slice
|
|
||||||
func getEcdsaPoint(pubKey []byte) (*curves.EcPoint, error) {
|
|
||||||
crv := curves.K256()
|
|
||||||
x := new(big.Int).SetBytes(pubKey[1:33])
|
|
||||||
y := new(big.Int).SetBytes(pubKey[33:])
|
|
||||||
ecCurve, err := crv.ToEllipticCurve()
|
|
||||||
if err != nil {
|
|
||||||
return nil, fmt.Errorf("error converting curve: %v", err)
|
|
||||||
}
|
|
||||||
return &curves.EcPoint{X: x, Y: y, Curve: ecCurve}, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func serializeSignature(sig *curves.EcdsaSignature) ([]byte, error) {
|
|
||||||
if sig == nil {
|
|
||||||
return nil, errors.New("nil signature")
|
|
||||||
}
|
|
||||||
|
|
||||||
rBytes := sig.R.Bytes()
|
|
||||||
sBytes := sig.S.Bytes()
|
|
||||||
|
|
||||||
// Ensure both components are 32 bytes
|
|
||||||
rPadded := make([]byte, 32)
|
|
||||||
sPadded := make([]byte, 32)
|
|
||||||
copy(rPadded[32-len(rBytes):], rBytes)
|
|
||||||
copy(sPadded[32-len(sBytes):], sBytes)
|
|
||||||
|
|
||||||
// Concatenate R and S
|
|
||||||
result := make([]byte, 64)
|
|
||||||
copy(result[0:32], rPadded)
|
|
||||||
copy(result[32:64], sPadded)
|
|
||||||
|
|
||||||
return result, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func deserializeSignature(sigBytes []byte) (*curves.EcdsaSignature, error) {
|
|
||||||
if len(sigBytes) != 64 {
|
|
||||||
return nil, fmt.Errorf("invalid signature length: expected 64 bytes, got %d", len(sigBytes))
|
|
||||||
}
|
|
||||||
|
|
||||||
r := new(big.Int).SetBytes(sigBytes[:32])
|
|
||||||
s := new(big.Int).SetBytes(sigBytes[32:])
|
|
||||||
|
|
||||||
return &curves.EcdsaSignature{
|
|
||||||
R: r,
|
|
||||||
S: s,
|
|
||||||
}, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func userSignFunc(k *keyEnclave, bz []byte) (SignFunc, error) {
|
|
||||||
curve := curves.K256()
|
|
||||||
return dklsv1.NewBobSign(curve, sha3.New256(), bz, k.UserShare, protocol.Version1)
|
|
||||||
}
|
|
||||||
|
|
||||||
func userRefreshFunc(k *keyEnclave) (RefreshFunc, error) {
|
|
||||||
curve := curves.K256()
|
|
||||||
return dklsv1.NewBobRefresh(curve, k.UserShare, protocol.Version1)
|
|
||||||
}
|
|
||||||
|
|
||||||
func valSignFunc(k *keyEnclave, bz []byte) (SignFunc, error) {
|
|
||||||
curve := curves.K256()
|
|
||||||
return dklsv1.NewAliceSign(curve, sha3.New256(), bz, k.ValShare, protocol.Version1)
|
|
||||||
}
|
|
||||||
|
|
||||||
func valRefreshFunc(k *keyEnclave) (RefreshFunc, error) {
|
|
||||||
curve := curves.K256()
|
|
||||||
return dklsv1.NewAliceRefresh(curve, k.ValShare, protocol.Version1)
|
|
||||||
}
|
|
||||||
@@ -73,6 +73,32 @@ type Resource interface {
|
|||||||
Contains(b Resource) bool
|
Contains(b Resource) bool
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type stringLengthRsc struct {
|
||||||
|
t string
|
||||||
|
v string
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewStringLengthResource is a silly implementation of resource to use while
|
||||||
|
// I figure out what an OR filter on strings is. Don't use this.
|
||||||
|
func NewStringLengthResource(typ, val string) Resource {
|
||||||
|
return stringLengthRsc{
|
||||||
|
t: typ,
|
||||||
|
v: val,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r stringLengthRsc) Type() string {
|
||||||
|
return r.t
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r stringLengthRsc) Value() string {
|
||||||
|
return r.v
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r stringLengthRsc) Contains(b Resource) bool {
|
||||||
|
return r.Type() == b.Type() && len(r.Value()) <= len(b.Value())
|
||||||
|
}
|
||||||
|
|
||||||
// Capability is an action users can perform
|
// Capability is an action users can perform
|
||||||
type Capability interface {
|
type Capability interface {
|
||||||
// A Capability must be expressable as a string
|
// A Capability must be expressable as a string
|
||||||
|
|||||||
@@ -0,0 +1,96 @@
|
|||||||
|
package ucan
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding/json"
|
||||||
|
"fmt"
|
||||||
|
"testing"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestAttenuationsContains(t *testing.T) {
|
||||||
|
aContains := [][2]string{
|
||||||
|
{
|
||||||
|
`[
|
||||||
|
{ "cap": "SUPER_USER", "dataset": "b5/world_bank_population"},
|
||||||
|
{ "cap": "OVERWRITE", "api": "https://api.qri.cloud" }
|
||||||
|
]`,
|
||||||
|
`[
|
||||||
|
{"cap": "SOFT_DELETE", "dataset": "b5/world_bank_population" }
|
||||||
|
]`,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
`[
|
||||||
|
{ "cap": "SUPER_USER", "dataset": "b5/world_bank_population"},
|
||||||
|
{ "cap": "OVERWRITE", "api": "https://api.qri.cloud" }
|
||||||
|
]`,
|
||||||
|
`[
|
||||||
|
{"cap": "SUPER_USER", "dataset": "b5/world_bank_population" }
|
||||||
|
]`,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
for i, c := range aContains {
|
||||||
|
t.Run(fmt.Sprintf("contains_%d", i), func(t *testing.T) {
|
||||||
|
a := testAttenuations(c[0])
|
||||||
|
b := testAttenuations(c[1])
|
||||||
|
if !a.Contains(b) {
|
||||||
|
t.Errorf("expected a attenuations to contain b attenuations")
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
aNotContains := [][2]string{
|
||||||
|
{
|
||||||
|
`[
|
||||||
|
{ "cap": "SUPER_USER", "dataset": "b5/world_bank_population"},
|
||||||
|
{ "cap": "OVERWRITE", "api": "https://api.qri.cloud" }
|
||||||
|
]`,
|
||||||
|
`[
|
||||||
|
{ "cap": "CREATE", "dataset": "b5" }
|
||||||
|
]`,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
for i, c := range aNotContains {
|
||||||
|
t.Run(fmt.Sprintf("not_contains_%d", i), func(t *testing.T) {
|
||||||
|
a := testAttenuations(c[0])
|
||||||
|
b := testAttenuations(c[1])
|
||||||
|
if a.Contains(b) {
|
||||||
|
t.Errorf("expected a attenuations to NOT contain b attenuations")
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func mustJSON(data string, v interface{}) {
|
||||||
|
if err := json.Unmarshal([]byte(data), v); err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func testAttenuations(data string) Attenuations {
|
||||||
|
caps := NewNestedCapabilities("SUPER_USER", "OVERWRITE", "SOFT_DELETE", "REVISE", "CREATE")
|
||||||
|
|
||||||
|
v := []map[string]string{}
|
||||||
|
mustJSON(data, &v)
|
||||||
|
|
||||||
|
var att Attenuations
|
||||||
|
for _, x := range v {
|
||||||
|
var cap Capability
|
||||||
|
var rsc Resource
|
||||||
|
for key, val := range x {
|
||||||
|
switch key {
|
||||||
|
case CapKey:
|
||||||
|
cap = caps.Cap(val)
|
||||||
|
default:
|
||||||
|
rsc = NewStringLengthResource(key, val)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
att = append(att, Attenuation{cap, rsc})
|
||||||
|
}
|
||||||
|
|
||||||
|
return att
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestNestedCapabilities(t *testing.T) {
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,36 @@
|
|||||||
|
// Code generated from Pkl module `sonr.orm.UCAN`. DO NOT EDIT.
|
||||||
|
package attns
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
|
||||||
|
"github.com/apple/pkl-go/pkl"
|
||||||
|
)
|
||||||
|
|
||||||
|
type UCAN struct {
|
||||||
|
}
|
||||||
|
|
||||||
|
// LoadFromPath loads the pkl module at the given path and evaluates it into a UCAN
|
||||||
|
func LoadFromPath(ctx context.Context, path string) (ret *UCAN, err error) {
|
||||||
|
evaluator, err := pkl.NewEvaluator(ctx, pkl.PreconfiguredOptions)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
defer func() {
|
||||||
|
cerr := evaluator.Close()
|
||||||
|
if err == nil {
|
||||||
|
err = cerr
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
ret, err = Load(ctx, evaluator, pkl.FileSource(path))
|
||||||
|
return ret, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// Load loads the pkl module at the given source and evaluates it with the given evaluator into a UCAN
|
||||||
|
func Load(ctx context.Context, evaluator pkl.Evaluator, source *pkl.ModuleSource) (*UCAN, error) {
|
||||||
|
var ret UCAN
|
||||||
|
if err := evaluator.EvaluateModule(ctx, source, &ret); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return &ret, nil
|
||||||
|
}
|
||||||
@@ -0,0 +1,79 @@
|
|||||||
|
// Code generated from Pkl module `sonr.orm.UCAN`. DO NOT EDIT.
|
||||||
|
package capability
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding"
|
||||||
|
"fmt"
|
||||||
|
)
|
||||||
|
|
||||||
|
type Capability string
|
||||||
|
|
||||||
|
const (
|
||||||
|
CAPOWNER Capability = "CAP_OWNER"
|
||||||
|
CAPOPERATOR Capability = "CAP_OPERATOR"
|
||||||
|
CAPOBSERVER Capability = "CAP_OBSERVER"
|
||||||
|
CAPAUTHENTICATE Capability = "CAP_AUTHENTICATE"
|
||||||
|
CAPAUTHORIZE Capability = "CAP_AUTHORIZE"
|
||||||
|
CAPDELEGATE Capability = "CAP_DELEGATE"
|
||||||
|
CAPINVOKE Capability = "CAP_INVOKE"
|
||||||
|
CAPEXECUTE Capability = "CAP_EXECUTE"
|
||||||
|
CAPPROPOSE Capability = "CAP_PROPOSE"
|
||||||
|
CAPSIGN Capability = "CAP_SIGN"
|
||||||
|
CAPSETPOLICY Capability = "CAP_SET_POLICY"
|
||||||
|
CAPSETTHRESHOLD Capability = "CAP_SET_THRESHOLD"
|
||||||
|
CAPRECOVER Capability = "CAP_RECOVER"
|
||||||
|
CAPSOCIAL Capability = "CAP_SOCIAL"
|
||||||
|
CAPVOTE Capability = "CAP_VOTE"
|
||||||
|
CAPRESOLVER Capability = "CAP_RESOLVER"
|
||||||
|
CAPPRODUCER Capability = "CAP_PRODUCER"
|
||||||
|
)
|
||||||
|
|
||||||
|
// String returns the string representation of Capability
|
||||||
|
func (rcv Capability) String() string {
|
||||||
|
return string(rcv)
|
||||||
|
}
|
||||||
|
|
||||||
|
var _ encoding.BinaryUnmarshaler = new(Capability)
|
||||||
|
|
||||||
|
// UnmarshalBinary implements encoding.BinaryUnmarshaler for Capability.
|
||||||
|
func (rcv *Capability) UnmarshalBinary(data []byte) error {
|
||||||
|
switch str := string(data); str {
|
||||||
|
case "CAP_OWNER":
|
||||||
|
*rcv = CAPOWNER
|
||||||
|
case "CAP_OPERATOR":
|
||||||
|
*rcv = CAPOPERATOR
|
||||||
|
case "CAP_OBSERVER":
|
||||||
|
*rcv = CAPOBSERVER
|
||||||
|
case "CAP_AUTHENTICATE":
|
||||||
|
*rcv = CAPAUTHENTICATE
|
||||||
|
case "CAP_AUTHORIZE":
|
||||||
|
*rcv = CAPAUTHORIZE
|
||||||
|
case "CAP_DELEGATE":
|
||||||
|
*rcv = CAPDELEGATE
|
||||||
|
case "CAP_INVOKE":
|
||||||
|
*rcv = CAPINVOKE
|
||||||
|
case "CAP_EXECUTE":
|
||||||
|
*rcv = CAPEXECUTE
|
||||||
|
case "CAP_PROPOSE":
|
||||||
|
*rcv = CAPPROPOSE
|
||||||
|
case "CAP_SIGN":
|
||||||
|
*rcv = CAPSIGN
|
||||||
|
case "CAP_SET_POLICY":
|
||||||
|
*rcv = CAPSETPOLICY
|
||||||
|
case "CAP_SET_THRESHOLD":
|
||||||
|
*rcv = CAPSETTHRESHOLD
|
||||||
|
case "CAP_RECOVER":
|
||||||
|
*rcv = CAPRECOVER
|
||||||
|
case "CAP_SOCIAL":
|
||||||
|
*rcv = CAPSOCIAL
|
||||||
|
case "CAP_VOTE":
|
||||||
|
*rcv = CAPVOTE
|
||||||
|
case "CAP_RESOLVER":
|
||||||
|
*rcv = CAPRESOLVER
|
||||||
|
case "CAP_PRODUCER":
|
||||||
|
*rcv = CAPPRODUCER
|
||||||
|
default:
|
||||||
|
return fmt.Errorf(`illegal: "%s" is not a valid Capability`, str)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
package capability
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
// Code generated from Pkl module `sonr.orm.UCAN`. DO NOT EDIT.
|
||||||
|
package attns
|
||||||
|
|
||||||
|
import "github.com/apple/pkl-go/pkl"
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
pkl.RegisterMapping("sonr.orm.UCAN", UCAN{})
|
||||||
|
}
|
||||||
@@ -0,0 +1,40 @@
|
|||||||
|
// Code generated from Pkl module `sonr.orm.UCAN`. DO NOT EDIT.
|
||||||
|
package policytype
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding"
|
||||||
|
"fmt"
|
||||||
|
)
|
||||||
|
|
||||||
|
type PolicyType string
|
||||||
|
|
||||||
|
const (
|
||||||
|
POLICYTHRESHOLD PolicyType = "POLICY_THRESHOLD"
|
||||||
|
POLICYTIMELOCK PolicyType = "POLICY_TIMELOCK"
|
||||||
|
POLICYWHITELIST PolicyType = "POLICY_WHITELIST"
|
||||||
|
POLICYKEYGEN PolicyType = "POLICY_KEYGEN"
|
||||||
|
)
|
||||||
|
|
||||||
|
// String returns the string representation of PolicyType
|
||||||
|
func (rcv PolicyType) String() string {
|
||||||
|
return string(rcv)
|
||||||
|
}
|
||||||
|
|
||||||
|
var _ encoding.BinaryUnmarshaler = new(PolicyType)
|
||||||
|
|
||||||
|
// UnmarshalBinary implements encoding.BinaryUnmarshaler for PolicyType.
|
||||||
|
func (rcv *PolicyType) UnmarshalBinary(data []byte) error {
|
||||||
|
switch str := string(data); str {
|
||||||
|
case "POLICY_THRESHOLD":
|
||||||
|
*rcv = POLICYTHRESHOLD
|
||||||
|
case "POLICY_TIMELOCK":
|
||||||
|
*rcv = POLICYTIMELOCK
|
||||||
|
case "POLICY_WHITELIST":
|
||||||
|
*rcv = POLICYWHITELIST
|
||||||
|
case "POLICY_KEYGEN":
|
||||||
|
*rcv = POLICYKEYGEN
|
||||||
|
default:
|
||||||
|
return fmt.Errorf(`illegal: "%s" is not a valid PolicyType`, str)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
@@ -0,0 +1,52 @@
|
|||||||
|
// Code generated from Pkl module `sonr.orm.UCAN`. DO NOT EDIT.
|
||||||
|
package resourcetype
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding"
|
||||||
|
"fmt"
|
||||||
|
)
|
||||||
|
|
||||||
|
type ResourceType string
|
||||||
|
|
||||||
|
const (
|
||||||
|
RESACCOUNT ResourceType = "RES_ACCOUNT"
|
||||||
|
RESTRANSACTION ResourceType = "RES_TRANSACTION"
|
||||||
|
RESPOLICY ResourceType = "RES_POLICY"
|
||||||
|
RESRECOVERY ResourceType = "RES_RECOVERY"
|
||||||
|
RESVAULT ResourceType = "RES_VAULT"
|
||||||
|
RESIPFS ResourceType = "RES_IPFS"
|
||||||
|
RESIPNS ResourceType = "RES_IPNS"
|
||||||
|
RESKEYSHARE ResourceType = "RES_KEYSHARE"
|
||||||
|
)
|
||||||
|
|
||||||
|
// String returns the string representation of ResourceType
|
||||||
|
func (rcv ResourceType) String() string {
|
||||||
|
return string(rcv)
|
||||||
|
}
|
||||||
|
|
||||||
|
var _ encoding.BinaryUnmarshaler = new(ResourceType)
|
||||||
|
|
||||||
|
// UnmarshalBinary implements encoding.BinaryUnmarshaler for ResourceType.
|
||||||
|
func (rcv *ResourceType) UnmarshalBinary(data []byte) error {
|
||||||
|
switch str := string(data); str {
|
||||||
|
case "RES_ACCOUNT":
|
||||||
|
*rcv = RESACCOUNT
|
||||||
|
case "RES_TRANSACTION":
|
||||||
|
*rcv = RESTRANSACTION
|
||||||
|
case "RES_POLICY":
|
||||||
|
*rcv = RESPOLICY
|
||||||
|
case "RES_RECOVERY":
|
||||||
|
*rcv = RESRECOVERY
|
||||||
|
case "RES_VAULT":
|
||||||
|
*rcv = RESVAULT
|
||||||
|
case "RES_IPFS":
|
||||||
|
*rcv = RESIPFS
|
||||||
|
case "RES_IPNS":
|
||||||
|
*rcv = RESIPNS
|
||||||
|
case "RES_KEYSHARE":
|
||||||
|
*rcv = RESKEYSHARE
|
||||||
|
default:
|
||||||
|
return fmt.Errorf(`illegal: "%s" is not a valid ResourceType`, str)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
@@ -0,0 +1,33 @@
|
|||||||
|
package resourcetype
|
||||||
|
|
||||||
|
// Resource is a unique identifier for a thing, usually stored state. Resources
|
||||||
|
// are organized by string types
|
||||||
|
type Resource interface {
|
||||||
|
Type() ResourceType
|
||||||
|
Value() string
|
||||||
|
Contains(b Resource) bool
|
||||||
|
}
|
||||||
|
|
||||||
|
type stringResource struct {
|
||||||
|
t ResourceType
|
||||||
|
v string
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r stringResource) Type() ResourceType {
|
||||||
|
return r.t
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r stringResource) Value() string {
|
||||||
|
return r.v
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r stringResource) Contains(b Resource) bool {
|
||||||
|
return r.Type() == b.Type() && len(r.Value()) <= len(b.Value())
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewResource(typ ResourceType, val string) Resource {
|
||||||
|
return stringResource{
|
||||||
|
t: typ,
|
||||||
|
v: val,
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,153 @@
|
|||||||
|
package ucan
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
|
||||||
|
"github.com/onsonr/sonr/crypto/mpc"
|
||||||
|
"github.com/onsonr/sonr/crypto/ucan/attns/capability"
|
||||||
|
"github.com/onsonr/sonr/crypto/ucan/attns/policytype"
|
||||||
|
"github.com/onsonr/sonr/crypto/ucan/attns/resourcetype"
|
||||||
|
)
|
||||||
|
|
||||||
|
// NewSmartAccount creates default attenuations for a smart account
|
||||||
|
func NewSmartAccount(
|
||||||
|
accountAddr string,
|
||||||
|
) Attenuations {
|
||||||
|
caps := AccountPermissions.GetCapabilities()
|
||||||
|
return Attenuations{
|
||||||
|
// Owner capabilities
|
||||||
|
{Cap: caps.Cap(CapOwner.String()), Rsc: NewResource(ResAccount, accountAddr)},
|
||||||
|
|
||||||
|
// Operation capabilities
|
||||||
|
{Cap: caps.Cap(capability.CAPEXECUTE.String()), Rsc: NewResource(ResTransaction, fmt.Sprintf("%s:*", accountAddr))},
|
||||||
|
{Cap: caps.Cap(capability.CAPPROPOSE.String()), Rsc: NewResource(ResTransaction, fmt.Sprintf("%s:*", accountAddr))},
|
||||||
|
{Cap: caps.Cap(capability.CAPSIGN.String()), Rsc: NewResource(ResTransaction, fmt.Sprintf("%s:*", accountAddr))},
|
||||||
|
|
||||||
|
// Policy capabilities
|
||||||
|
{Cap: caps.Cap(capability.CAPSETPOLICY.String()), Rsc: NewResource(ResPolicy, fmt.Sprintf("%s:*", accountAddr))},
|
||||||
|
{Cap: caps.Cap(capability.CAPSETTHRESHOLD.String()), Rsc: NewResource(ResPolicy, fmt.Sprintf("%s:threshold", accountAddr))},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewSmartAccountPolicy creates attenuations for policy management
|
||||||
|
func NewSmartAccountPolicy(
|
||||||
|
accountAddr string,
|
||||||
|
policyType policytype.PolicyType,
|
||||||
|
) Attenuations {
|
||||||
|
caps := AccountPermissions.GetCapabilities()
|
||||||
|
return Attenuations{
|
||||||
|
{
|
||||||
|
Cap: caps.Cap(capability.CAPSETPOLICY.String()),
|
||||||
|
Rsc: NewResource(
|
||||||
|
ResPolicy,
|
||||||
|
fmt.Sprintf("%s:%s", accountAddr, policyType),
|
||||||
|
),
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// SmartAccountCapabilities defines the capability hierarchy
|
||||||
|
func SmartAccountCapabilities() []string {
|
||||||
|
return []string{
|
||||||
|
CapOwner.String(),
|
||||||
|
CapOperator.String(),
|
||||||
|
CapObserver.String(),
|
||||||
|
CapExecute.String(),
|
||||||
|
CapPropose.String(),
|
||||||
|
CapSign.String(),
|
||||||
|
CapSetPolicy.String(),
|
||||||
|
CapSetThreshold.String(),
|
||||||
|
CapRecover.String(),
|
||||||
|
CapSocial.String(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// CreateVaultAttenuations creates default attenuations for a smart account
|
||||||
|
func NewService(
|
||||||
|
origin string,
|
||||||
|
) Attenuations {
|
||||||
|
caps := ServicePermissions.GetCapabilities()
|
||||||
|
return Attenuations{
|
||||||
|
// Owner capabilities
|
||||||
|
{Cap: caps.Cap(capability.CAPOWNER.String()), Rsc: NewResource(resourcetype.RESACCOUNT, origin)},
|
||||||
|
|
||||||
|
// Operation capabilities
|
||||||
|
{Cap: caps.Cap(capability.CAPEXECUTE.String()), Rsc: NewResource(resourcetype.RESTRANSACTION, fmt.Sprintf("%s:*", origin))},
|
||||||
|
{Cap: caps.Cap(capability.CAPPROPOSE.String()), Rsc: NewResource(resourcetype.RESTRANSACTION, fmt.Sprintf("%s:*", origin))},
|
||||||
|
{Cap: caps.Cap(capability.CAPSIGN.String()), Rsc: NewResource(resourcetype.RESTRANSACTION, fmt.Sprintf("%s:*", origin))},
|
||||||
|
|
||||||
|
// Policy capabilities
|
||||||
|
{Cap: caps.Cap(capability.CAPSETPOLICY.String()), Rsc: NewResource(resourcetype.RESPOLICY, fmt.Sprintf("%s:*", origin))},
|
||||||
|
{Cap: caps.Cap(capability.CAPSETTHRESHOLD.String()), Rsc: NewResource(resourcetype.RESPOLICY, fmt.Sprintf("%s:threshold", origin))},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ServiceCapabilities defines the capability hierarchy
|
||||||
|
func ServiceCapabilities() []string {
|
||||||
|
return []string{
|
||||||
|
CapOwner.String(),
|
||||||
|
CapOperator.String(),
|
||||||
|
CapObserver.String(),
|
||||||
|
CapExecute.String(),
|
||||||
|
CapPropose.String(),
|
||||||
|
CapSign.String(),
|
||||||
|
CapResolver.String(),
|
||||||
|
CapProducer.String(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewVault creates default attenuations for a smart account
|
||||||
|
func NewVault(
|
||||||
|
kss mpc.Keyset,
|
||||||
|
) Attenuations {
|
||||||
|
accountAddr, err := mpc.ComputeSonrAddr(kss.User().GetPublicKey())
|
||||||
|
if err != nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
caps := VaultPermissions.GetCapabilities()
|
||||||
|
return Attenuations{
|
||||||
|
// Owner capabilities
|
||||||
|
{Cap: caps.Cap(capability.CAPOWNER.String()), Rsc: NewResource(resourcetype.RESACCOUNT, accountAddr)},
|
||||||
|
|
||||||
|
// Operation capabilities
|
||||||
|
{Cap: caps.Cap(capability.CAPEXECUTE.String()), Rsc: NewResource(resourcetype.RESTRANSACTION, fmt.Sprintf("%s:*", accountAddr))},
|
||||||
|
{Cap: caps.Cap(capability.CAPPROPOSE.String()), Rsc: NewResource(resourcetype.RESTRANSACTION, fmt.Sprintf("%s:*", accountAddr))},
|
||||||
|
{Cap: caps.Cap(capability.CAPSIGN.String()), Rsc: NewResource(resourcetype.RESTRANSACTION, fmt.Sprintf("%s:*", accountAddr))},
|
||||||
|
|
||||||
|
// Policy capabilities
|
||||||
|
{Cap: caps.Cap(capability.CAPSETPOLICY.String()), Rsc: NewResource(resourcetype.RESPOLICY, fmt.Sprintf("%s:*", accountAddr))},
|
||||||
|
{Cap: caps.Cap(capability.CAPSETTHRESHOLD.String()), Rsc: NewResource(resourcetype.RESPOLICY, fmt.Sprintf("%s:threshold", accountAddr))},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewVaultPolicy creates attenuations for policy management
|
||||||
|
func NewVaultPolicy(
|
||||||
|
accountAddr string,
|
||||||
|
policyType policytype.PolicyType,
|
||||||
|
) Attenuations {
|
||||||
|
caps := VaultPermissions.GetCapabilities()
|
||||||
|
return Attenuations{
|
||||||
|
{
|
||||||
|
Cap: caps.Cap(capability.CAPSETPOLICY.String()),
|
||||||
|
Rsc: NewResource(
|
||||||
|
resourcetype.RESPOLICY,
|
||||||
|
fmt.Sprintf("%s:%s", accountAddr, policyType),
|
||||||
|
),
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// VaultCapabilities defines the capability hierarchy
|
||||||
|
func VaultCapabilities() []string {
|
||||||
|
return []string{
|
||||||
|
CapOwner.String(),
|
||||||
|
CapOperator.String(),
|
||||||
|
CapObserver.String(),
|
||||||
|
CapAuthenticate.String(),
|
||||||
|
CapAuthorize.String(),
|
||||||
|
CapDelegate.String(),
|
||||||
|
CapInvoke.String(),
|
||||||
|
CapExecute.String(),
|
||||||
|
CapRecover.String(),
|
||||||
|
}
|
||||||
|
}
|
||||||
+18
-57
@@ -1,66 +1,27 @@
|
|||||||
package ucan
|
package ucan
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"context"
|
||||||
)
|
)
|
||||||
|
|
||||||
var EmptyAttenuation = Attenuation{
|
// CtxKey defines a distinct type for context keys used by the access
|
||||||
Cap: Capability(nil),
|
// package
|
||||||
Rsc: Resource(nil),
|
type CtxKey string
|
||||||
|
|
||||||
|
// TokenCtxKey is the key for adding an access UCAN to a context.Context
|
||||||
|
const TokenCtxKey CtxKey = "UCAN"
|
||||||
|
|
||||||
|
// CtxWithToken adds a UCAN value to a context
|
||||||
|
func CtxWithToken(ctx context.Context, t Token) context.Context {
|
||||||
|
return context.WithValue(ctx, TokenCtxKey, t)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Permissions represents the type of attenuation
|
// FromCtx extracts a token from a given context if one is set, returning nil
|
||||||
type Permissions string
|
// otherwise
|
||||||
|
func FromCtx(ctx context.Context) *Token {
|
||||||
const (
|
iface := ctx.Value(TokenCtxKey)
|
||||||
// AccountPermissions represents the smart account attenuation
|
if ref, ok := iface.(*Token); ok {
|
||||||
AccountPermissions = Permissions("account")
|
return ref
|
||||||
|
|
||||||
// ServicePermissions represents the service attenuation
|
|
||||||
ServicePermissions = Permissions("service")
|
|
||||||
|
|
||||||
// VaultPermissions represents the vault attenuation
|
|
||||||
VaultPermissions = Permissions("vault")
|
|
||||||
)
|
|
||||||
|
|
||||||
// Cap returns the capability for the given AttenuationPreset
|
|
||||||
func (a Permissions) NewCap(c string) Capability {
|
|
||||||
return a.GetCapabilities().Cap(c)
|
|
||||||
}
|
|
||||||
|
|
||||||
// NestedCapabilities returns the nested capabilities for the given AttenuationPreset
|
|
||||||
func (a Permissions) GetCapabilities() NestedCapabilities {
|
|
||||||
var caps []string
|
|
||||||
switch a {
|
|
||||||
case AccountPermissions:
|
|
||||||
// caps = SmartAccountCapabilities()
|
|
||||||
case VaultPermissions:
|
|
||||||
// caps = VaultCapabilities()
|
|
||||||
}
|
}
|
||||||
return NewNestedCapabilities(caps...)
|
return nil
|
||||||
}
|
|
||||||
|
|
||||||
// Equals returns true if the given AttenuationPreset is equal to the receiver
|
|
||||||
func (a Permissions) Equals(b Permissions) bool {
|
|
||||||
return a == b
|
|
||||||
}
|
|
||||||
|
|
||||||
// String returns the string representation of the AttenuationPreset
|
|
||||||
func (a Permissions) String() string {
|
|
||||||
return string(a)
|
|
||||||
}
|
|
||||||
|
|
||||||
// ParseAttenuationData parses raw attenuation data into a structured format
|
|
||||||
func ParseAttenuationData(data map[string]interface{}) (Permissions, map[string]interface{}, error) {
|
|
||||||
typeRaw, ok := data["preset"]
|
|
||||||
if !ok {
|
|
||||||
return "", nil, fmt.Errorf("missing preset type in attenuation data")
|
|
||||||
}
|
|
||||||
|
|
||||||
presetType, ok := typeRaw.(string)
|
|
||||||
if !ok {
|
|
||||||
return "", nil, fmt.Errorf("invalid preset type format")
|
|
||||||
}
|
|
||||||
|
|
||||||
return Permissions(presetType), data, nil
|
|
||||||
}
|
}
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user