mirror of
https://github.com/sonr-io/sonr.git
synced 2026-08-03 01:41:44 +00:00
(no commit message provided)
This commit is contained in:
@@ -0,0 +1,448 @@
|
||||
//go:build (linux || darwin || windows || freebsd || illumos) && !sqlite3_nosys
|
||||
|
||||
package main
|
||||
|
||||
import (
|
||||
"database/sql"
|
||||
"fmt"
|
||||
|
||||
"github.com/onsonr/hway/crypto"
|
||||
"github.com/onsonr/hway/crypto/secret"
|
||||
|
||||
_ "github.com/ncruces/go-sqlite3/driver"
|
||||
_ "github.com/ncruces/go-sqlite3/embed"
|
||||
)
|
||||
|
||||
const kVaultDBFileName = "file:demo.db?_pragma=busy_timeout(10000)"
|
||||
|
||||
type Database interface {
|
||||
ExistsCredential(did string) bool
|
||||
ExistsProfile(did string) bool
|
||||
ExistsWallet(did string) bool
|
||||
|
||||
GetCredential(did string) (*Credential, error)
|
||||
GetProfile(did string) (*Profile, error)
|
||||
GetWallet(did string) (*Wallet, error)
|
||||
|
||||
InsertCredentials(credentials ...*Credential) error
|
||||
InsertProfiles(profiles ...*Profile) error
|
||||
InsertWallets(wallets ...*Wallet) error
|
||||
|
||||
ListCredentials() ([]*Credential, error)
|
||||
ListProfiles() ([]*Profile, error)
|
||||
ListWallets() ([]*Wallet, error)
|
||||
}
|
||||
|
||||
type Credential struct {
|
||||
Transport string
|
||||
Origin string
|
||||
Controller string
|
||||
DID string
|
||||
DisplayName string
|
||||
AttestationType string
|
||||
Attachment string
|
||||
AAGUID []byte
|
||||
PublicKey []byte
|
||||
CredentialID []byte
|
||||
ID int64
|
||||
SignCount uint32
|
||||
BackupEligible bool
|
||||
BackupState bool
|
||||
UserVerified bool
|
||||
UserPresent bool
|
||||
}
|
||||
|
||||
type Profile struct {
|
||||
DID string
|
||||
DisplayName string
|
||||
Name string
|
||||
Origin string
|
||||
Controller string
|
||||
ID int64
|
||||
}
|
||||
|
||||
type Wallet struct {
|
||||
Address string
|
||||
Controller string
|
||||
Name string
|
||||
ChainID string
|
||||
Network string
|
||||
Label string
|
||||
DID string
|
||||
PublicKey []byte
|
||||
ID int64
|
||||
Index int
|
||||
CoinType int64
|
||||
}
|
||||
|
||||
func seedDB() (Database, error) {
|
||||
db, err := sql.Open("sqlite", kVaultDBFileName)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// Create tables
|
||||
_, err = db.Exec(`
|
||||
CREATE TABLE IF NOT EXISTS credentials (
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
display_name TEXT,
|
||||
origin TEXT,
|
||||
controller TEXT,
|
||||
attestation_type TEXT,
|
||||
did TEXT UNIQUE,
|
||||
credential_id BLOB,
|
||||
public_key BLOB,
|
||||
transport TEXT,
|
||||
user_present BOOLEAN,
|
||||
user_verified BOOLEAN,
|
||||
backup_eligible BOOLEAN,
|
||||
backup_state BOOLEAN,
|
||||
aaguid BLOB,
|
||||
sign_count INTEGER,
|
||||
attachment TEXT
|
||||
);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS profiles (
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
did TEXT UNIQUE,
|
||||
display_name TEXT,
|
||||
name TEXT,
|
||||
origin TEXT,
|
||||
controller TEXT
|
||||
);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS wallets (
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
address TEXT,
|
||||
controller TEXT,
|
||||
name TEXT,
|
||||
chain_id TEXT,
|
||||
network TEXT,
|
||||
label TEXT,
|
||||
did TEXT UNIQUE,
|
||||
public_key BLOB,
|
||||
index_num INTEGER,
|
||||
coin_type INTEGER
|
||||
);
|
||||
`)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &embedDB{DB: db}, nil
|
||||
}
|
||||
|
||||
type embedDB struct {
|
||||
DB *sql.DB
|
||||
}
|
||||
|
||||
func (db *embedDB) GetCredential(did string) (*Credential, error) {
|
||||
credential := new(Credential)
|
||||
err := db.DB.QueryRow("SELECT * FROM credentials WHERE did = ?", did).Scan(
|
||||
&credential.ID, &credential.DisplayName, &credential.Origin, &credential.Controller,
|
||||
&credential.AttestationType, &credential.DID, &credential.CredentialID, &credential.PublicKey,
|
||||
&credential.Transport, &credential.UserPresent, &credential.UserVerified,
|
||||
&credential.BackupEligible, &credential.BackupState, &credential.AAGUID,
|
||||
&credential.SignCount, &credential.Attachment,
|
||||
)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return credential, nil
|
||||
}
|
||||
|
||||
func (db *embedDB) GetProfile(did string) (*Profile, error) {
|
||||
profile := new(Profile)
|
||||
err := db.DB.QueryRow("SELECT * FROM profiles WHERE did = ?", did).Scan(
|
||||
&profile.ID, &profile.DID, &profile.DisplayName, &profile.Name,
|
||||
&profile.Origin, &profile.Controller,
|
||||
)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return profile, nil
|
||||
}
|
||||
|
||||
func (db *embedDB) GetWallet(did string) (*Wallet, error) {
|
||||
wallet := new(Wallet)
|
||||
err := db.DB.QueryRow("SELECT * FROM wallets WHERE did = ?", did).Scan(
|
||||
&wallet.ID, &wallet.Address, &wallet.Controller, &wallet.Name,
|
||||
&wallet.ChainID, &wallet.Network, &wallet.Label, &wallet.DID,
|
||||
&wallet.PublicKey, &wallet.Index, &wallet.CoinType,
|
||||
)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return wallet, nil
|
||||
}
|
||||
|
||||
func (db *embedDB) ExistsCredential(did string) bool {
|
||||
var count int
|
||||
db.DB.QueryRow("SELECT COUNT(*) FROM credentials WHERE did = ?", did).Scan(&count)
|
||||
return count > 0
|
||||
}
|
||||
|
||||
func (db *embedDB) ExistsProfile(did string) bool {
|
||||
var count int
|
||||
db.DB.QueryRow("SELECT COUNT(*) FROM profiles WHERE did = ?", did).Scan(&count)
|
||||
return count > 0
|
||||
}
|
||||
|
||||
func (db *embedDB) ExistsWallet(did string) bool {
|
||||
var count int
|
||||
db.DB.QueryRow("SELECT COUNT(*) FROM wallets WHERE did = ?", did).Scan(&count)
|
||||
return count > 0
|
||||
}
|
||||
|
||||
func (db *embedDB) InsertCredentials(credentials ...*Credential) error {
|
||||
tx, err := db.DB.Begin()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer tx.Rollback()
|
||||
|
||||
stmt, err := tx.Prepare(`
|
||||
INSERT INTO credentials (
|
||||
display_name, origin, controller, attestation_type, did, credential_id,
|
||||
public_key, transport, user_present, user_verified, backup_eligible,
|
||||
backup_state, aaguid, sign_count, attachment
|
||||
) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
|
||||
`)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer stmt.Close()
|
||||
|
||||
for _, c := range credentials {
|
||||
_, err = stmt.Exec(
|
||||
c.DisplayName, c.Origin, c.Controller, c.AttestationType, c.DID, c.CredentialID,
|
||||
c.PublicKey, c.Transport, c.UserPresent, c.UserVerified, c.BackupEligible,
|
||||
c.BackupState, c.AAGUID, c.SignCount, c.Attachment,
|
||||
)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return tx.Commit()
|
||||
}
|
||||
|
||||
func (db *embedDB) InsertProfiles(profiles ...*Profile) error {
|
||||
tx, err := db.DB.Begin()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer tx.Rollback()
|
||||
|
||||
stmt, err := tx.Prepare(`
|
||||
INSERT INTO profiles (did, display_name, name, origin, controller)
|
||||
VALUES (?, ?, ?, ?, ?)
|
||||
`)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer stmt.Close()
|
||||
|
||||
for _, p := range profiles {
|
||||
_, err = stmt.Exec(p.DID, p.DisplayName, p.Name, p.Origin, p.Controller)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return tx.Commit()
|
||||
}
|
||||
|
||||
func (db *embedDB) InsertWallets(wallets ...*Wallet) error {
|
||||
tx, err := db.DB.Begin()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer tx.Rollback()
|
||||
|
||||
stmt, err := tx.Prepare(`
|
||||
INSERT INTO wallets (
|
||||
address, controller, name, chain_id, network, label, did,
|
||||
public_key, index_num, coin_type
|
||||
) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
|
||||
`)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer stmt.Close()
|
||||
|
||||
for _, w := range wallets {
|
||||
_, err = stmt.Exec(
|
||||
w.Address, w.Controller, w.Name, w.ChainID, w.Network, w.Label, w.DID,
|
||||
w.PublicKey, w.Index, w.CoinType,
|
||||
)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return tx.Commit()
|
||||
}
|
||||
|
||||
func (db *embedDB) ListCredentials() ([]*Credential, error) {
|
||||
rows, err := db.DB.Query("SELECT * FROM credentials")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer rows.Close()
|
||||
|
||||
var credentials []*Credential
|
||||
for rows.Next() {
|
||||
c := new(Credential)
|
||||
err := rows.Scan(
|
||||
&c.ID, &c.DisplayName, &c.Origin, &c.Controller, &c.AttestationType,
|
||||
&c.DID, &c.CredentialID, &c.PublicKey, &c.Transport, &c.UserPresent,
|
||||
&c.UserVerified, &c.BackupEligible, &c.BackupState, &c.AAGUID,
|
||||
&c.SignCount, &c.Attachment,
|
||||
)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
credentials = append(credentials, c)
|
||||
}
|
||||
return credentials, nil
|
||||
}
|
||||
|
||||
func (db *embedDB) ListProfiles() ([]*Profile, error) {
|
||||
rows, err := db.DB.Query("SELECT * FROM profiles")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer rows.Close()
|
||||
|
||||
var profiles []*Profile
|
||||
for rows.Next() {
|
||||
p := new(Profile)
|
||||
err := rows.Scan(&p.ID, &p.DID, &p.DisplayName, &p.Name, &p.Origin, &p.Controller)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
profiles = append(profiles, p)
|
||||
}
|
||||
return profiles, nil
|
||||
}
|
||||
|
||||
func (db *embedDB) ListWallets() ([]*Wallet, error) {
|
||||
rows, err := db.DB.Query("SELECT * FROM wallets")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer rows.Close()
|
||||
|
||||
var wallets []*Wallet
|
||||
for rows.Next() {
|
||||
w := new(Wallet)
|
||||
err := rows.Scan(
|
||||
&w.ID, &w.Address, &w.Controller, &w.Name, &w.ChainID, &w.Network,
|
||||
&w.Label, &w.DID, &w.PublicKey, &w.Index, &w.CoinType,
|
||||
)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
wallets = append(wallets, w)
|
||||
}
|
||||
return wallets, nil
|
||||
}
|
||||
|
||||
func (db *embedDB) WitnessCredential(publicKey crypto.PublicKey, did string) ([]byte, error) {
|
||||
if !db.ExistsCredential(did) {
|
||||
return nil, fmt.Errorf("credential with DID %s does not exist", did)
|
||||
}
|
||||
|
||||
pk, err := secret.NewKey("credentials", publicKey)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
creds, err := db.ListCredentials()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
credIDStrs := make([]string, len(creds))
|
||||
for i, c := range creds {
|
||||
credIDStrs[i] = c.DID
|
||||
}
|
||||
|
||||
acc, err := pk.CreateAccumulator(credIDStrs...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
witness, err := pk.CreateWitness(acc, did)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return witness.MarshalBinary()
|
||||
}
|
||||
|
||||
func (db *embedDB) WitnessProfile(publicKey crypto.PublicKey, did string) ([]byte, error) {
|
||||
if !db.ExistsProfile(did) {
|
||||
return nil, fmt.Errorf("profile with DID %s does not exist", did)
|
||||
}
|
||||
|
||||
pk, err := secret.NewKey("profiles", publicKey)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
profiles, err := db.ListProfiles()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
profileIDs := make([]string, len(profiles))
|
||||
for i, p := range profiles {
|
||||
profileIDs[i] = p.DID
|
||||
}
|
||||
|
||||
acc, err := pk.CreateAccumulator(profileIDs...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
witness, err := pk.CreateWitness(acc, did)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return witness.MarshalBinary()
|
||||
}
|
||||
|
||||
func (db *embedDB) WitnessWallet(publicKey crypto.PublicKey, did string) ([]byte, error) {
|
||||
if !db.ExistsWallet(did) {
|
||||
return nil, fmt.Errorf("wallet with DID %s does not exist", did)
|
||||
}
|
||||
|
||||
pk, err := secret.NewKey("wallets", publicKey)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
wallets, err := db.ListWallets()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
walletIDs := make([]string, len(wallets))
|
||||
for i, w := range wallets {
|
||||
walletIDs[i] = w.DID
|
||||
}
|
||||
|
||||
acc, err := pk.CreateAccumulator(walletIDs...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
witness, err := pk.CreateWitness(acc, did)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return witness.MarshalBinary()
|
||||
}
|
||||
|
||||
func main() {}
|
||||
@@ -0,0 +1,10 @@
|
||||
module dwn
|
||||
|
||||
replace github.com/onsonr/hway => ../../
|
||||
|
||||
go 1.22.3
|
||||
|
||||
require (
|
||||
github.com/onsonr/hway v0.0.0-00010101000000-000000000000
|
||||
github.com/ncruces/go-sqlite3 v0.16.3
|
||||
)
|
||||
@@ -0,0 +1,95 @@
|
||||
cosmossdk.io/math v1.3.0 h1:RC+jryuKeytIiictDslBP9i1fhkVm6ZDmZEoNP316zE=
|
||||
cosmossdk.io/math v1.3.0/go.mod h1:vnRTxewy+M7BtXBNFybkuhSH4WfedVAAnERHgVFhp3k=
|
||||
filippo.io/edwards25519 v1.0.0 h1:0wAIcmJUqRdI8IJ/3eGi5/HwXZWPujYXXlkrQogz0Ek=
|
||||
filippo.io/edwards25519 v1.0.0/go.mod h1:N1IkdkCkiLB6tki+MYJoSx2JTY9NUlxZE7eHn5EwJns=
|
||||
git.sr.ht/~sircmpwn/getopt v0.0.0-20191230200459-23622cc906b3/go.mod h1:wMEGFFFNuPos7vHmWXfszqImLppbc0wEhh6JBfJIUgw=
|
||||
git.sr.ht/~sircmpwn/go-bare v0.0.0-20210406120253-ab86bc2846d9 h1:Ahny8Ud1LjVMMAlt8utUFKhhxJtwBAualvsbc/Sk7cE=
|
||||
git.sr.ht/~sircmpwn/go-bare v0.0.0-20210406120253-ab86bc2846d9/go.mod h1:BVJwbDfVjCjoFiKrhkei6NdGcZYpkDkdyCdg1ukytRA=
|
||||
github.com/bits-and-blooms/bitset v1.13.0 h1:bAQ9OPNFYbGHV6Nez0tmNI0RiEu7/hxlYJRUA0wFAVE=
|
||||
github.com/bits-and-blooms/bitset v1.13.0/go.mod h1:7hO7Gc7Pp1vODcmWvKMRA9BNmbv6a/7QIWpPxHddWR8=
|
||||
github.com/btcsuite/btcd/btcec/v2 v2.3.3 h1:6+iXlDKE8RMtKsvK0gshlXIuPbyWM/h84Ensb7o3sC0=
|
||||
github.com/btcsuite/btcd/btcec/v2 v2.3.3/go.mod h1:zYzJ8etWJQIv1Ogk7OzpWjowwOdXY1W/17j2MW85J04=
|
||||
github.com/bwesterb/go-ristretto v1.2.3 h1:1w53tCkGhCQ5djbat3+MH0BAQ5Kfgbt56UZQ/JMzngw=
|
||||
github.com/bwesterb/go-ristretto v1.2.3/go.mod h1:fUIoIZaG73pV5biE2Blr2xEzDoMj7NFEuV9ekS419A0=
|
||||
github.com/cloudflare/circl v1.3.9 h1:QFrlgFYf2Qpi8bSpVPK1HBvWpx16v/1TZivyo7pGuBE=
|
||||
github.com/cloudflare/circl v1.3.9/go.mod h1:PDRU+oXvdD7KCtgKxW95M5Z8BpSCJXQORiZFnBQS5QU=
|
||||
github.com/cometbft/cometbft v0.38.8 h1:XyJ9Cu3xqap6xtNxiemrO8roXZ+KS2Zlu7qQ0w1trvU=
|
||||
github.com/cometbft/cometbft v0.38.8/go.mod h1:xOoGZrtUT+A5izWfHSJgl0gYZUE7lu7Z2XIS1vWG/QQ=
|
||||
github.com/consensys/bavard v0.1.13 h1:oLhMLOFGTLdlda/kma4VOJazblc7IM5y5QPd2A/YjhQ=
|
||||
github.com/consensys/bavard v0.1.13/go.mod h1:9ItSMtA/dXMAiL7BG6bqW2m3NdSEObYWoH223nGHukI=
|
||||
github.com/consensys/gnark-crypto v0.12.1 h1:lHH39WuuFgVHONRl3J0LRBtuYdQTumFSDtJF7HpyG8M=
|
||||
github.com/consensys/gnark-crypto v0.12.1/go.mod h1:v2Gy7L/4ZRosZ7Ivs+9SfUDr0f5UlG+EM5t7MPHiLuY=
|
||||
github.com/cosmos/cosmos-sdk v0.50.5 h1:MOEi+DKYgW67YaPgB+Pf+nHbD3V9S/ayitRKJYLfGIA=
|
||||
github.com/cosmos/cosmos-sdk v0.50.5/go.mod h1:oV/k6GJgXV9QPoM2fsYDPPsyPBgQbdotv532O6Mz1OQ=
|
||||
github.com/cosmos/gogoproto v1.4.11 h1:LZcMHrx4FjUgrqQSWeaGC1v/TeuVFqSLa43CC6aWR2g=
|
||||
github.com/cosmos/gogoproto v1.4.11/go.mod h1:/g39Mh8m17X8Q/GDEs5zYTSNaNnInBSohtaxzQnYq1Y=
|
||||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM=
|
||||
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/decred/dcrd/dcrec/secp256k1/v4 v4.3.0 h1:rpfIENRNNilwHwZeG5+P150SMrnNEcHYvcCuK6dPZSg=
|
||||
github.com/decred/dcrd/dcrec/secp256k1/v4 v4.3.0/go.mod h1:v57UDF4pDQJcEfFUCRop3lJL149eHGSe9Jvczhzjo/0=
|
||||
github.com/ethereum/go-ethereum v1.14.5 h1:szuFzO1MhJmweXjoM5nSAeDvjNUH3vIQoMzzQnfvjpw=
|
||||
github.com/ethereum/go-ethereum v1.14.5/go.mod h1:VEDGGhSxY7IEjn98hJRFXl/uFvpRgbIIf2PpXiyGGgc=
|
||||
github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI=
|
||||
github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
|
||||
github.com/google/subcommands v1.2.0/go.mod h1:ZjhPrFU+Olkh9WazFPsl27BQ4UPiG37m3yTrtFlrHVk=
|
||||
github.com/ipfs/go-cid v0.4.1 h1:A/T3qGvxi4kpKWWcPC/PgbvDA2bjVLO7n4UeVwnbs/s=
|
||||
github.com/ipfs/go-cid v0.4.1/go.mod h1:uQHwDeX4c6CtyrFwdqyhpNcxVewur1M7l7fNU7LKwZk=
|
||||
github.com/klauspost/cpuid/v2 v2.2.7 h1:ZWSB3igEs+d0qvnxR/ZBzXVmxkgt8DdzP6m9pfuVLDM=
|
||||
github.com/klauspost/cpuid/v2 v2.2.7/go.mod h1:Lcz8mBdAVJIBVzewtcLocK12l3Y+JytZYpaMropDUws=
|
||||
github.com/leanovate/gopter v0.2.9 h1:fQjYxZaynp97ozCzfOyOuAGOU4aU/z37zf/tOujFk7c=
|
||||
github.com/leanovate/gopter v0.2.9/go.mod h1:U2L/78B+KVFIx2VmW6onHJQzXtFb+p5y3y2Sh+Jxxv8=
|
||||
github.com/minio/sha256-simd v1.0.1 h1:6kaan5IFmwTNynnKKpDHe6FWHohJOHhCPchzK49dzMM=
|
||||
github.com/minio/sha256-simd v1.0.1/go.mod h1:Pz6AKMiUdngCLpeTL/RJY1M9rUuPMYujV5xJjtbRSN8=
|
||||
github.com/mmcloughlin/addchain v0.4.0 h1:SobOdjm2xLj1KkXN5/n0xTIWyZA2+s99UCY1iPfkHRY=
|
||||
github.com/mmcloughlin/addchain v0.4.0/go.mod h1:A86O+tHqZLMNO4w6ZZ4FlVQEadcoqkyU72HC5wJ4RlU=
|
||||
github.com/mmcloughlin/profile v0.1.1/go.mod h1:IhHD7q1ooxgwTgjxQYkACGA77oFTDdFVejUS1/tS/qU=
|
||||
github.com/mr-tron/base58 v1.2.0 h1:T/HDJBh4ZCPbU39/+c3rRvE0uKBQlU27+QI8LJ4t64o=
|
||||
github.com/mr-tron/base58 v1.2.0/go.mod h1:BinMc/sQntlIE1frQmRFPUoPA1Zkr8VRgBdjWI2mNwc=
|
||||
github.com/multiformats/go-base32 v0.1.0 h1:pVx9xoSPqEIQG8o+UbAe7DNi51oej1NtK+aGkbLYxPE=
|
||||
github.com/multiformats/go-base32 v0.1.0/go.mod h1:Kj3tFY6zNr+ABYMqeUNeGvkIC/UYgtWibDcT0rExnbI=
|
||||
github.com/multiformats/go-base36 v0.2.0 h1:lFsAbNOGeKtuKozrtBsAkSVhv1p9D0/qedU9rQyccr0=
|
||||
github.com/multiformats/go-base36 v0.2.0/go.mod h1:qvnKE++v+2MWCfePClUEjE78Z7P2a1UV0xHgWc0hkp4=
|
||||
github.com/multiformats/go-multibase v0.2.0 h1:isdYCVLvksgWlMW9OZRYJEa9pZETFivncJHmHnnd87g=
|
||||
github.com/multiformats/go-multibase v0.2.0/go.mod h1:bFBZX4lKCA/2lyOFSAoKH5SS6oPyjtnzK/XTFDPkNuk=
|
||||
github.com/multiformats/go-multihash v0.2.3 h1:7Lyc8XfX/IY2jWb/gI7JP+o7JEq9hOa7BFvVU9RSh+U=
|
||||
github.com/multiformats/go-multihash v0.2.3/go.mod h1:dXgKXCXjBzdscBLk9JkjINiEsCKRVch90MdaGiKsvSM=
|
||||
github.com/multiformats/go-varint v0.0.7 h1:sWSGR+f/eu5ABZA2ZpYKBILXTTs9JWpdEM/nEGOHFS8=
|
||||
github.com/multiformats/go-varint v0.0.7/go.mod h1:r8PUYw/fD/SjBCiKOoDlGF6QawOELpZAu9eioSos/OU=
|
||||
github.com/ncruces/go-sqlite3 v0.16.3 h1:Ky0denOdmAGOoCE6lQlw6GCJNMD8gTikNWe8rpu+Gjc=
|
||||
github.com/ncruces/go-sqlite3 v0.16.3/go.mod h1:sAU/vQwBmZ2hq5BlW/KTzqRFizL43bv2JQoBLgXhcMI=
|
||||
github.com/ncruces/julianday v1.0.0 h1:fH0OKwa7NWvniGQtxdJRxAgkBMolni2BjDHaWTxqt7M=
|
||||
github.com/ncruces/julianday v1.0.0/go.mod h1:Dusn2KvZrrovOMJuOt0TNXL6tB7U2E8kvza5fFc9G7g=
|
||||
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
|
||||
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U=
|
||||
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||
github.com/spaolacci/murmur3 v1.1.0 h1:7c1g84S4BPRrfL5Xrdp6fOJ206sU9y293DDHaoy0bLI=
|
||||
github.com/spaolacci/murmur3 v1.1.0/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA=
|
||||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
|
||||
github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||
github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg=
|
||||
github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
|
||||
github.com/tetratelabs/wazero v1.7.3 h1:PBH5KVahrt3S2AHgEjKu4u+LlDbbk+nsGE3KLucy6Rw=
|
||||
github.com/tetratelabs/wazero v1.7.3/go.mod h1:ytl6Zuh20R/eROuyDaGPkp82O9C/DJfXAwJfQ3X6/7Y=
|
||||
golang.org/x/crypto v0.24.0 h1:mnl8DM0o513X8fdIkmyFE/5hTYxbwYOjDS/+rK6qpRI=
|
||||
golang.org/x/crypto v0.24.0/go.mod h1:Z1PMYSOR5nyMcyAVAIQSKCDwalqy85Aqn1x3Ws4L5DM=
|
||||
golang.org/x/exp v0.0.0-20240222234643-814bf88cf225 h1:LfspQV/FYTatPTr/3HzIcmiUFH7PGP+OQ6mgDYo3yuQ=
|
||||
golang.org/x/exp v0.0.0-20240222234643-814bf88cf225/go.mod h1:CxmFvTBINI24O/j8iY7H1xHzx2i4OsyguNBmN/uPtqc=
|
||||
golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.21.0 h1:rF+pYz3DAGSQAxAu1CbC7catZg4ebC4UIeIhKxBZvws=
|
||||
golang.org/x/sys v0.21.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||
golang.org/x/text v0.16.0 h1:a94ExnEXNtEwYLGJSIUxnWoxoRz/ZcCsV63ROupILh4=
|
||||
golang.org/x/text v0.16.0/go.mod h1:GhwF1Be+LQoKShO3cGOHzqOgRrGaYc9AvblQOmPVHnI=
|
||||
google.golang.org/protobuf v1.33.0 h1:uNO2rsAINq/JlFpSdYEKIZ0uKD/R9cpdv0T+yoGwGmI=
|
||||
google.golang.org/protobuf v1.33.0/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
|
||||
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
lukechampine.com/blake3 v1.2.2 h1:wEAbSg0IVU4ih44CVlpMqMZMpzr5hf/6aqodLlevd/w=
|
||||
lukechampine.com/blake3 v1.2.2/go.mod h1:0OFRp7fBtAylGVCO40o87sbupkyIGgbpv1+M1k1LM6k=
|
||||
rsc.io/tmplfunc v0.0.3 h1:53XFQh69AfOa8Tw0Jm7t+GV7KZhOi6jzsCzTtKbMvzU=
|
||||
rsc.io/tmplfunc v0.0.3/go.mod h1:AG3sTPzElb1Io3Yg4voV9AGZJuleGAwaVRxL9M49PhA=
|
||||
Vendored
+23
@@ -0,0 +1,23 @@
|
||||
package env
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/go-webauthn/webauthn/protocol"
|
||||
)
|
||||
|
||||
// Default Key in gRPC Metadata for the Session ID
|
||||
const MetadataSessionIDKey = "sonr-session-id"
|
||||
|
||||
// SonrContext is the context for the Sonr API
|
||||
type SonrContext struct {
|
||||
Context context.Context
|
||||
SessionID string `json:"session_id"`
|
||||
UserAddress string `json:"user_address"`
|
||||
ValidatorAddress string `json:"validator_address"`
|
||||
ServiceOrigin string `json:"service_origin"`
|
||||
PeerID string `json:"peer_id"`
|
||||
ChainID string `json:"chain_id"`
|
||||
Token string `json:"token"`
|
||||
Challenge protocol.URLEncodedBase64 `json:"challenge"`
|
||||
}
|
||||
Vendored
+37
@@ -0,0 +1,37 @@
|
||||
package env
|
||||
|
||||
import (
|
||||
"github.com/ipfs/kubo/client/rpc"
|
||||
)
|
||||
|
||||
var (
|
||||
ChainID = "testnet"
|
||||
ValAddr = "val1"
|
||||
NodeDir = ".sonr"
|
||||
)
|
||||
|
||||
// Initialize initializes the local configuration values
|
||||
func init() {
|
||||
}
|
||||
|
||||
// SetLocalContextSessionID sets the session ID for the local context
|
||||
func SetLocalValidatorAddress(address string) {
|
||||
ValAddr = address
|
||||
}
|
||||
|
||||
// SetLocalContextChainID sets the chain ID for the local
|
||||
func SetLocalChainID(id string) {
|
||||
ChainID = id
|
||||
}
|
||||
|
||||
// IPFSClient is an interface for interacting with an IPFS node.
|
||||
type IPFSClient = *rpc.HttpApi
|
||||
|
||||
// NewLocalClient creates a new IPFS client that connects to the local IPFS node.
|
||||
func GetIPFSClient() (IPFSClient, error) {
|
||||
rpcClient, err := rpc.NewLocalApi()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return rpcClient, nil
|
||||
}
|
||||
@@ -0,0 +1,68 @@
|
||||
package js
|
||||
|
||||
templ Credentials() {
|
||||
}
|
||||
|
||||
script CreateCredential(formId string) {
|
||||
// Base64 encoding and decoding functions
|
||||
function arrayBufferToBase64(buffer) {
|
||||
return btoa(String.fromCharCode.apply(null, new Uint8Array(buffer)))
|
||||
.replace(/\+/g, "-")
|
||||
.replace(/\//g, "_")
|
||||
.replace(/=/g, "");
|
||||
}
|
||||
|
||||
function base64ToArrayBuffer(base64) {
|
||||
const binary = atob(base64.replace(/-/g, "+").replace(/_/g, "/"));
|
||||
const bytes = new Uint8Array(binary.length);
|
||||
for (let i = 0; i < binary.length; i++) {
|
||||
bytes[i] = binary.charCodeAt(i);
|
||||
}
|
||||
return bytes.buffer;
|
||||
}
|
||||
|
||||
// Check if the form is valid
|
||||
const form = document.getElementById(formId);
|
||||
if (!form.checkValidity()) {
|
||||
form.reportValidity();
|
||||
return;
|
||||
}
|
||||
|
||||
// Get user information from the form
|
||||
const name = document.getElementById('name').value;
|
||||
const handle = document.getElementById('handle').value;
|
||||
|
||||
let credential = navigator.credentials.create({
|
||||
publicKey: {
|
||||
challenge: new Uint8Array([117, 61, 252, 231, 191, 241]),
|
||||
rp: { name: "ACME Corporation" },
|
||||
user: {
|
||||
id: new Uint8Array([79, 252, 83, 72, 214, 7, 89, 26]),
|
||||
name: handle,
|
||||
displayName: name
|
||||
},
|
||||
pubKeyCredParams: [{ type: "public-key", alg: -7 }]
|
||||
}
|
||||
}).then(credential => {
|
||||
// Prepare the credential data
|
||||
let credentialData = {
|
||||
id: credential.id,
|
||||
type: credential.type,
|
||||
rawId: arrayBufferToBase64(credential.rawId),
|
||||
response: {
|
||||
clientDataJSON: arrayBufferToBase64(credential.response.clientDataJSON),
|
||||
attestationObject: arrayBufferToBase64(credential.response.attestationObject)
|
||||
},
|
||||
clientExtensionResults: credential.getClientExtensionResults()
|
||||
};
|
||||
|
||||
// Set the serialized credential data as the form value
|
||||
document.getElementById('credentialData').value = JSON.stringify(credentialData);
|
||||
|
||||
// Submit the form
|
||||
form.submit();
|
||||
}).catch(error => {
|
||||
console.error('Error creating credential:', error);
|
||||
// Handle the error (e.g., show an error message to the user)
|
||||
});
|
||||
}
|
||||
@@ -0,0 +1,101 @@
|
||||
// Code generated by templ - DO NOT EDIT.
|
||||
|
||||
// templ: version: v0.2.731
|
||||
package js
|
||||
|
||||
//lint:file-ignore SA4006 This context is only used if a nested component is present.
|
||||
|
||||
import "github.com/a-h/templ"
|
||||
import templruntime "github.com/a-h/templ/runtime"
|
||||
|
||||
func Credentials() templ.Component {
|
||||
return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {
|
||||
templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context
|
||||
templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)
|
||||
if !templ_7745c5c3_IsBuffer {
|
||||
defer func() {
|
||||
templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)
|
||||
if templ_7745c5c3_Err == nil {
|
||||
templ_7745c5c3_Err = templ_7745c5c3_BufErr
|
||||
}
|
||||
}()
|
||||
}
|
||||
ctx = templ.InitializeContext(ctx)
|
||||
templ_7745c5c3_Var1 := templ.GetChildren(ctx)
|
||||
if templ_7745c5c3_Var1 == nil {
|
||||
templ_7745c5c3_Var1 = templ.NopComponent
|
||||
}
|
||||
ctx = templ.ClearChildren(ctx)
|
||||
return templ_7745c5c3_Err
|
||||
})
|
||||
}
|
||||
|
||||
func createCredential(formId string) templ.ComponentScript {
|
||||
return templ.ComponentScript{
|
||||
Name: `__templ_createCredential_190e`,
|
||||
Function: `function __templ_createCredential_190e(formId){// Base64 encoding and decoding functions
|
||||
function arrayBufferToBase64(buffer) {
|
||||
return btoa(String.fromCharCode.apply(null, new Uint8Array(buffer)))
|
||||
.replace(/\+/g, "-")
|
||||
.replace(/\//g, "_")
|
||||
.replace(/=/g, "");
|
||||
}
|
||||
|
||||
function base64ToArrayBuffer(base64) {
|
||||
const binary = atob(base64.replace(/-/g, "+").replace(/_/g, "/"));
|
||||
const bytes = new Uint8Array(binary.length);
|
||||
for (let i = 0; i < binary.length; i++) {
|
||||
bytes[i] = binary.charCodeAt(i);
|
||||
}
|
||||
return bytes.buffer;
|
||||
}
|
||||
|
||||
// Check if the form is valid
|
||||
const form = document.getElementById(formId);
|
||||
if (!form.checkValidity()) {
|
||||
form.reportValidity();
|
||||
return;
|
||||
}
|
||||
|
||||
// Get user information from the form
|
||||
const name = document.getElementById('name').value;
|
||||
const handle = document.getElementById('handle').value;
|
||||
|
||||
let credential = navigator.credentials.create({
|
||||
publicKey: {
|
||||
challenge: new Uint8Array([117, 61, 252, 231, 191, 241]),
|
||||
rp: { name: "ACME Corporation" },
|
||||
user: {
|
||||
id: new Uint8Array([79, 252, 83, 72, 214, 7, 89, 26]),
|
||||
name: handle,
|
||||
displayName: name
|
||||
},
|
||||
pubKeyCredParams: [{ type: "public-key", alg: -7 }]
|
||||
}
|
||||
}).then(credential => {
|
||||
// Prepare the credential data
|
||||
let credentialData = {
|
||||
id: credential.id,
|
||||
type: credential.type,
|
||||
rawId: arrayBufferToBase64(credential.rawId),
|
||||
response: {
|
||||
clientDataJSON: arrayBufferToBase64(credential.response.clientDataJSON),
|
||||
attestationObject: arrayBufferToBase64(credential.response.attestationObject)
|
||||
},
|
||||
clientExtensionResults: credential.getClientExtensionResults()
|
||||
};
|
||||
|
||||
// Set the serialized credential data as the form value
|
||||
document.getElementById('credentialData').value = JSON.stringify(credentialData);
|
||||
|
||||
// Submit the form
|
||||
form.submit();
|
||||
}).catch(error => {
|
||||
console.error('Error creating credential:', error);
|
||||
// Handle the error (e.g., show an error message to the user)
|
||||
});
|
||||
}`,
|
||||
Call: templ.SafeScript(`__templ_createCredential_190e`, formId),
|
||||
CallInline: templ.SafeScriptInline(`__templ_createCredential_190e`, formId),
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,4 @@
|
||||
package js
|
||||
|
||||
templ Storage() {
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
// Code generated by templ - DO NOT EDIT.
|
||||
|
||||
// templ: version: v0.2.731
|
||||
package js
|
||||
|
||||
//lint:file-ignore SA4006 This context is only used if a nested component is present.
|
||||
|
||||
import "github.com/a-h/templ"
|
||||
import templruntime "github.com/a-h/templ/runtime"
|
||||
|
||||
func Storage() templ.Component {
|
||||
return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {
|
||||
templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context
|
||||
templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)
|
||||
if !templ_7745c5c3_IsBuffer {
|
||||
defer func() {
|
||||
templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)
|
||||
if templ_7745c5c3_Err == nil {
|
||||
templ_7745c5c3_Err = templ_7745c5c3_BufErr
|
||||
}
|
||||
}()
|
||||
}
|
||||
ctx = templ.InitializeContext(ctx)
|
||||
templ_7745c5c3_Var1 := templ.GetChildren(ctx)
|
||||
if templ_7745c5c3_Var1 == nil {
|
||||
templ_7745c5c3_Var1 = templ.NopComponent
|
||||
}
|
||||
ctx = templ.ClearChildren(ctx)
|
||||
return templ_7745c5c3_Err
|
||||
})
|
||||
}
|
||||
@@ -0,0 +1,44 @@
|
||||
package orm
|
||||
|
||||
import "github.com/go-webauthn/webauthn/protocol"
|
||||
|
||||
// Authenticator contains all needed information about an authenticator for storage.
|
||||
type Authenticator struct {
|
||||
Attachment protocol.AuthenticatorAttachment `json:"attachment"`
|
||||
AAGUID []byte `json:"AAGUID"`
|
||||
SignCount uint32 `json:"signCount"`
|
||||
CloneWarning bool `json:"cloneWarning"`
|
||||
}
|
||||
|
||||
// SelectAuthenticator allow for easy marshaling of authenticator options that are provided to the user.
|
||||
func SelectAuthenticator(att string, rrk *bool, uv string) protocol.AuthenticatorSelection {
|
||||
return protocol.AuthenticatorSelection{
|
||||
AuthenticatorAttachment: protocol.AuthenticatorAttachment(att),
|
||||
RequireResidentKey: rrk,
|
||||
UserVerification: protocol.UserVerificationRequirement(uv),
|
||||
}
|
||||
}
|
||||
|
||||
// UpdateCounter updates the authenticator and either sets the clone warning value or the sign count.
|
||||
//
|
||||
// Step 17 of §7.2. about verifying attestation. If the signature counter value authData.signCount
|
||||
// is nonzero or the value stored in conjunction with credential’s id attribute is nonzero, then
|
||||
// run the following sub-step:
|
||||
//
|
||||
// If the signature counter value authData.signCount is
|
||||
//
|
||||
// → Greater than the signature counter value stored in conjunction with credential’s id attribute.
|
||||
// Update the stored signature counter value, associated with credential’s id attribute, to be the value of
|
||||
// authData.signCount.
|
||||
//
|
||||
// → Less than or equal to the signature counter value stored in conjunction with credential’s id attribute.
|
||||
// This is a signal that the authenticator may be cloned, see CloneWarning above for more information.
|
||||
func (a *Authenticator) UpdateCounter(authDataCount uint32) {
|
||||
if authDataCount <= a.SignCount && (authDataCount != 0 || a.SignCount != 0) {
|
||||
a.CloneWarning = true
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
a.SignCount = authDataCount
|
||||
}
|
||||
@@ -0,0 +1,67 @@
|
||||
package orm
|
||||
|
||||
import (
|
||||
"github.com/go-webauthn/webauthn/protocol"
|
||||
"gorm.io/gorm"
|
||||
)
|
||||
|
||||
type CredentialFlags struct {
|
||||
// Flag UP indicates the users presence.
|
||||
UserPresent bool `json:"userPresent"`
|
||||
|
||||
// Flag UV indicates the user performed verification.
|
||||
UserVerified bool `json:"userVerified"`
|
||||
|
||||
// Flag BE indicates the credential is able to be backed up and/or sync'd between devices. This should NEVER change.
|
||||
BackupEligible bool `json:"backupEligible"`
|
||||
|
||||
// Flag BS indicates the credential has been backed up and/or sync'd. This value can change but it's recommended
|
||||
// that RP's keep track of this value.
|
||||
BackupState bool `json:"backupState"`
|
||||
}
|
||||
|
||||
// Credential contains all needed information about a WebAuthn credential for storage.
|
||||
type Credential struct {
|
||||
gorm.Model
|
||||
DisplayName string
|
||||
Origin string
|
||||
Controller string
|
||||
AttestationType string `json:"attestationType"`
|
||||
DID string
|
||||
ID []byte `json:"id"`
|
||||
PublicKey []byte `json:"publicKey"`
|
||||
Transport []protocol.AuthenticatorTransport `json:"transport"`
|
||||
Authenticator Authenticator `json:"authenticator"`
|
||||
Flags CredentialFlags `json:"flags"`
|
||||
}
|
||||
|
||||
// MakeNewCredential will return a credential pointer on successful validation of a registration response.
|
||||
func MakeNewCredential(c *protocol.ParsedCredentialCreationData) *Credential {
|
||||
return &Credential{
|
||||
ID: c.Response.AttestationObject.AuthData.AttData.CredentialID,
|
||||
PublicKey: c.Response.AttestationObject.AuthData.AttData.CredentialPublicKey,
|
||||
AttestationType: c.Response.AttestationObject.Format,
|
||||
Transport: c.Response.Transports,
|
||||
Flags: CredentialFlags{
|
||||
UserPresent: c.Response.AttestationObject.AuthData.Flags.HasUserPresent(),
|
||||
UserVerified: c.Response.AttestationObject.AuthData.Flags.HasUserVerified(),
|
||||
BackupEligible: c.Response.AttestationObject.AuthData.Flags.HasBackupEligible(),
|
||||
BackupState: c.Response.AttestationObject.AuthData.Flags.HasBackupState(),
|
||||
},
|
||||
Authenticator: Authenticator{
|
||||
AAGUID: c.Response.AttestationObject.AuthData.AttData.AAGUID,
|
||||
SignCount: c.Response.AttestationObject.AuthData.Counter,
|
||||
Attachment: c.AuthenticatorAttachment,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
// Descriptor converts a Credential into a protocol.CredentialDescriptor.
|
||||
func (c *Credential) Descriptor() protocol.CredentialDescriptor {
|
||||
return protocol.CredentialDescriptor{
|
||||
Type: protocol.PublicKeyCredentialType,
|
||||
CredentialID: c.ID,
|
||||
Transport: c.Transport,
|
||||
AttestationType: c.AttestationType,
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,49 @@
|
||||
package orm
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
|
||||
"github.com/onsonr/hway/crypto"
|
||||
fs "github.com/onsonr/hway/internal/vfs"
|
||||
"github.com/ipfs/boxo/path"
|
||||
)
|
||||
|
||||
// Metadata represents metadata of a resource
|
||||
type Metadata struct {
|
||||
PublicKey crypto.PublicKey `json:"publicKey"`
|
||||
Path path.Path `json:"path"`
|
||||
Address string `json:"address"`
|
||||
ChainID string `json:"chainId"`
|
||||
ValAddress string `json:"valAddress"`
|
||||
RPCEndpoint string `json:"rpcEndpoint"`
|
||||
APIEndpoint string `json:"apiEndpoint"`
|
||||
IPFSEndpoint string `json:"ipfsEndpoint"`
|
||||
PeerID string `json:"peerId"`
|
||||
SupportedDenominations []string `json:"supportedDenominations"`
|
||||
Number int `json:"number"`
|
||||
}
|
||||
|
||||
// CreateMetadata returns a new Metadata
|
||||
func CreateMetadata(ctx context.Context) *Metadata {
|
||||
return &Metadata{}
|
||||
}
|
||||
|
||||
// Marshal returns the JSON encoding of the Metadata
|
||||
func (i *Metadata) Marshal() ([]byte, error) {
|
||||
return json.Marshal(i)
|
||||
}
|
||||
|
||||
// Unmarshal parses the JSON-encoded data and stores the result in the Metadata
|
||||
func (i *Metadata) Unmarshal(data []byte) error {
|
||||
return json.Unmarshal(data, i)
|
||||
}
|
||||
|
||||
// Save writes the JSON encoding of the Metadata to the provided file
|
||||
func (i *Metadata) Save(file fs.File) error {
|
||||
bz, err := i.Marshal()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return file.Write(bz)
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
package orm
|
||||
|
||||
type UserInfo struct {
|
||||
DID string
|
||||
Sub string `json:"sub"`
|
||||
Name string `json:"name,omitempty"`
|
||||
Email string `json:"email,omitempty"`
|
||||
// Add other claims as needed
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
package orm
|
||||
|
||||
import "gorm.io/gorm"
|
||||
|
||||
type Profile struct {
|
||||
gorm.Model
|
||||
DID string
|
||||
DisplayName string
|
||||
Name string
|
||||
Origin string
|
||||
Controller string
|
||||
Credentials []Credential
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
package orm
|
||||
|
||||
import (
|
||||
"github.com/onsonr/hway/crypto"
|
||||
"github.com/onsonr/hway/crypto/bip32"
|
||||
"github.com/onsonr/hway/pkg/coins"
|
||||
"gorm.io/gorm"
|
||||
)
|
||||
|
||||
// Wallet is a struct that contains the information of a wallet account
|
||||
type Wallet struct {
|
||||
gorm.Model
|
||||
Address string `json:"address"`
|
||||
Controller string `json:"controller"`
|
||||
Name string `json:"name"`
|
||||
ChainID string `json:"chainId"`
|
||||
Network string `json:"network"`
|
||||
Label string `json:"label"`
|
||||
DID string `json:"did"`
|
||||
PublicKey []byte `json:"publicKey"`
|
||||
Index int `json:"index"`
|
||||
CoinType int64 `json:"coinType"`
|
||||
}
|
||||
|
||||
// NewWallet creates a new account from a public key, coin, and index
|
||||
func NewWallet(pubkey crypto.PublicKey, coin coins.Coin, index int) (*Wallet, error) {
|
||||
expbz := pubkey.Bytes()
|
||||
pubBz, err := bip32.ComputePublicKey(expbz, coin.GetPath(), index)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
addr, err := coin.FormatAddress(pubBz)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &Wallet{
|
||||
PublicKey: pubBz,
|
||||
Index: index,
|
||||
Address: addr,
|
||||
CoinType: coin.GetIndex(),
|
||||
}, nil
|
||||
}
|
||||
Reference in New Issue
Block a user