refactor: move dwn wasm build to pkg directory

This commit is contained in:
Prad Nukala
2024-09-30 00:13:58 -04:00
parent 9fcdfe5243
commit 4a76f105af
9 changed files with 9 additions and 12 deletions
Binary file not shown.
-78
View File
@@ -1,78 +0,0 @@
package vault
import (
"bytes"
"context"
_ "embed"
"encoding/json"
"github.com/a-h/templ"
"github.com/ipfs/boxo/files"
"github.com/onsonr/sonr/pkg/dwn"
)
//go:embed app.wasm
var dwnWasmData []byte
//go:embed motr.mjs
var motrMJSData []byte
//go:embed sw.js
var swJSData []byte
var (
dwnWasmFile = files.NewBytesFile(dwnWasmData)
motrMJSFile = files.NewBytesFile(motrMJSData)
swJSFile = files.NewBytesFile(swJSData)
)
// NewVaultDirectory creates a new directory with the default files
func NewVaultDirectory(cnfg *dwn.Config) (files.Node, error) {
dwnJSON, err := json.Marshal(cnfg)
if err != nil {
return nil, err
}
dwnStr, err := templ.JSONString(cnfg)
if err != nil {
return nil, err
}
w := bytes.NewBuffer(nil)
err = indexFile(dwnStr).Render(context.Background(), w)
if err != nil {
return nil, err
}
fileMap := map[string]files.Node{
"config.json": files.NewBytesFile(dwnJSON),
"motr.mjs": motrMJSFile,
"sw.js": swJSFile,
"app.wasm": dwnWasmFile,
"index.html": files.NewBytesFile(w.Bytes()),
}
return files.NewMapDirectory(fileMap), nil
}
// Use IndexHTML template to generate the index file
func IndexHTMLFile(c *dwn.Config) (files.Node, error) {
str, err := templ.JSONString(c)
if err != nil {
return nil, err
}
w := bytes.NewBuffer(nil)
err = indexFile(str).Render(context.Background(), w)
if err != nil {
return nil, err
}
indexData := w.Bytes()
return files.NewBytesFile(indexData), nil
}
// MarshalConfigFile uses the config template to generate the dwn config file
func MarshalConfigFile(c *dwn.Config) (files.Node, error) {
dwnConfigData, err := json.Marshal(c)
if err != nil {
return nil, err
}
return files.NewBytesFile(dwnConfigData), nil
}
-104
View File
@@ -1,104 +0,0 @@
package vault
var motrHandle = templ.NewOnceHandle()
templ importScripts() {
<script src="https://cdn.sonr.io/js/htmx.min.js"></script>
<script src="https://cdn.tailwindcss.com"></script>
<script src="https://unpkg.com/alpinejs" defer></script>
}
templ indexFile(cfg string) {
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8"/>
<meta http-equiv="X-UA-Compatible" content="IE=edge"/>
<meta name="viewport" content="width=device-width, initial-scale=1.0"/>
<link href="https://cdn.sonr.io/stylesheet.css" rel="stylesheet"/>
@importScripts()
<style>
[x-cloak] {
display: none;
}
</style>
<title>Sonr DWN</title>
<script>
if ("serviceWorker" in navigator) {
window.addEventListener("load", function() {
navigator.serviceWorker
.register("/sw.js")
.then(function (registration) {
console.log("Service Worker registered with scope:", registration.scope);
})
.catch(function (error) {
console.log("Service Worker registration failed:", error);
});
});
}
</script>
</head>
<body class="flex items-center justify-center h-full bg-neutral-50 lg:p-24 md:16 p-4">
<main class="flex-row items-center justify-center mx-auto w-fit max-w-screen-sm gap-y-3">
<div id="output">Loading...</div>
</main>
@motrHandle.Once() {
<script src="/assets/main.js" type="module"></script>
@initializeMotr(cfg)
}
</body>
</html>
}
script initializeMotr(config string) {
const motr = new Motr(JSON.parse(config));
async function demo() {
try {
// Insert a new account
const accountId = await motr.insertAccount({
name: 'John Doe',
address: '0x1234567890123456789012345678901234567890',
publicKey: 'sample_public_key',
chainCode: 'SONR',
index: 0,
controller: 'sample_controller',
createdAt: new Date()
});
console.log('Inserted account with ID:', accountId);
// Retrieve the account
const account = await motr.getAccount(accountId);
console.log('Retrieved account:', account);
// Insert a new credential
const credentialId = await motr.insertCredential({
subject: 'john@example.com',
label: 'John\'s Device',
controller: 'sample_controller',
attestationType: 'platform',
origin: 'https://app.sonr.io'
});
console.log('Inserted credential with ID:', credentialId);
// Retrieve the credential
const credential = await motr.getCredential(credentialId);
console.log('Retrieved credential:', credential);
document.getElementById('output').innerHTML = `
<h2>Demo Results:</h2>
<p>Inserted account ID: ${accountId}</p>
<p>Retrieved account name: ${account.name}</p>
<p>Inserted credential ID: ${credentialId}</p>
<p>Retrieved credential subject: ${credential.subject}</p>
`;
} catch (error) {
console.error('Error in demo:', error);
document.getElementById('output').innerHTML = `<p>Error: ${error.message}</p>`;
}
}
// Run the demo when the page loads
window.onload = demo;
}
-168
View File
@@ -1,168 +0,0 @@
// Code generated by templ - DO NOT EDIT.
// templ: version: v0.2.778
package vault
//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"
var motrHandle = templ.NewOnceHandle()
func importScripts() 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
if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil {
return templ_7745c5c3_CtxErr
}
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)
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("<script src=\"https://cdn.sonr.io/js/htmx.min.js\"></script><script src=\"https://cdn.tailwindcss.com\"></script><script src=\"https://unpkg.com/alpinejs\" defer></script>")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
return templ_7745c5c3_Err
})
}
func indexFile(cfg string) 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
if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil {
return templ_7745c5c3_CtxErr
}
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_Var2 := templ.GetChildren(ctx)
if templ_7745c5c3_Var2 == nil {
templ_7745c5c3_Var2 = templ.NopComponent
}
ctx = templ.ClearChildren(ctx)
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("<!doctype html><html lang=\"en\"><head><meta charset=\"UTF-8\"><meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge\"><meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\"><link href=\"https://cdn.sonr.io/stylesheet.css\" rel=\"stylesheet\">")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = importScripts().Render(ctx, templ_7745c5c3_Buffer)
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("<style>\n [x-cloak] {\n display: none;\n }\n </style><title>Sonr DWN</title><script>\n if (\"serviceWorker\" in navigator) {\n window.addEventListener(\"load\", function() {\n navigator.serviceWorker\n .register(\"/sw.js\")\n .then(function (registration) {\n console.log(\"Service Worker registered with scope:\", registration.scope);\n })\n .catch(function (error) {\n console.log(\"Service Worker registration failed:\", error);\n });\n });\n }\n </script></head><body class=\"flex items-center justify-center h-full bg-neutral-50 lg:p-24 md:16 p-4\"><main class=\"flex-row items-center justify-center mx-auto w-fit max-w-screen-sm gap-y-3\"><div id=\"output\">Loading...</div></main>")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Var3 := 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_Err = templ_7745c5c3_Buffer.WriteString("<script src=\"/assets/main.js\" type=\"module\"></script> ")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = initializeMotr(cfg).Render(ctx, templ_7745c5c3_Buffer)
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
return templ_7745c5c3_Err
})
templ_7745c5c3_Err = motrHandle.Once().Render(templ.WithChildren(ctx, templ_7745c5c3_Var3), templ_7745c5c3_Buffer)
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("</body></html>")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
return templ_7745c5c3_Err
})
}
func initializeMotr(config string) templ.ComponentScript {
return templ.ComponentScript{
Name: `__templ_initializeMotr_d70f`,
Function: `function __templ_initializeMotr_d70f(config){const motr = new Motr(JSON.parse(config));
async function demo() {
try {
// Insert a new account
const accountId = await motr.insertAccount({
name: 'John Doe',
address: '0x1234567890123456789012345678901234567890',
publicKey: 'sample_public_key',
chainCode: 'SONR',
index: 0,
controller: 'sample_controller',
createdAt: new Date()
});
console.log('Inserted account with ID:', accountId);
// Retrieve the account
const account = await motr.getAccount(accountId);
console.log('Retrieved account:', account);
// Insert a new credential
const credentialId = await motr.insertCredential({
subject: 'john@example.com',
label: 'John\'s Device',
controller: 'sample_controller',
attestationType: 'platform',
origin: 'https://app.sonr.io'
});
console.log('Inserted credential with ID:', credentialId);
// Retrieve the credential
const credential = await motr.getCredential(credentialId);
console.log('Retrieved credential:', credential);
document.getElementById('output').innerHTML = ` + "`" + `
<h2>Demo Results:</h2>
<p>Inserted account ID: ${accountId}</p>
<p>Retrieved account name: ${account.name}</p>
<p>Inserted credential ID: ${credentialId}</p>
<p>Retrieved credential subject: ${credential.subject}</p>
` + "`" + `;
} catch (error) {
console.error('Error in demo:', error);
document.getElementById('output').innerHTML = ` + "`" + `<p>Error: ${error.message}</p>` + "`" + `;
}
}
// Run the demo when the page loads
window.onload = demo;
}`,
Call: templ.SafeScript(`__templ_initializeMotr_d70f`, config),
CallInline: templ.SafeScriptInline(`__templ_initializeMotr_d70f`, config),
}
}
var _ = templruntime.GeneratedTemplate
-253
View File
@@ -1,253 +0,0 @@
// motr.mjs
import Dexie from "dexie";
export class Motr {
constructor(config) {
this.config = config;
this.vault = null;
this.initializeVault();
}
initializeVault() {
const { schema } = this.config;
this.vault = new Dexie("Vault");
this.vault.version(schema.version).stores(schema);
}
// Account methods
async insertAccount(accountData) {
return this.vault.account.add(accountData);
}
async getAccount(id) {
return this.vault.account.get(id);
}
async updateAccount(id, accountData) {
return this.vault.account.update(id, accountData);
}
async deleteAccount(id) {
return this.vault.account.delete(id);
}
// Asset methods
async insertAsset(assetData) {
return this.vault.asset.add(assetData);
}
async getAsset(id) {
return this.vault.asset.get(id);
}
async updateAsset(id, assetData) {
return this.vault.asset.update(id, assetData);
}
async deleteAsset(id) {
return this.vault.asset.delete(id);
}
// Chain methods
async insertChain(chainData) {
return this.vault.chain.add(chainData);
}
async getChain(id) {
return this.vault.chain.get(id);
}
async updateChain(id, chainData) {
return this.vault.chain.update(id, chainData);
}
async deleteChain(id) {
return this.vault.chain.delete(id);
}
// Credential methods
async insertCredential(credentialData) {
const publicKey = await this.createPublicKeyCredential(credentialData);
credentialData.credentialId = publicKey.id;
credentialData.publicKey = publicKey.publicKey;
return this.vault.credential.add(credentialData);
}
async getCredential(id) {
return this.vault.credential.get(id);
}
async updateCredential(id, credentialData) {
return this.vault.credential.update(id, credentialData);
}
async deleteCredential(id) {
return this.vault.credential.delete(id);
}
// JWK methods
async insertJwk(jwkData) {
return this.vault.jwk.add(jwkData);
}
async getJwk(id) {
return this.vault.jwk.get(id);
}
async updateJwk(id, jwkData) {
return this.vault.jwk.update(id, jwkData);
}
async deleteJwk(id) {
return this.vault.jwk.delete(id);
}
// Grant methods
async insertGrant(grantData) {
return this.vault.grant.add(grantData);
}
async getGrant(id) {
return this.vault.grant.get(id);
}
async updateGrant(id, grantData) {
return this.vault.grant.update(id, grantData);
}
async deleteGrant(id) {
return this.vault.grant.delete(id);
}
// Keyshare methods
async insertKeyshare(keyshareData) {
return this.vault.keyshare.add(keyshareData);
}
async getKeyshare(id) {
return this.vault.keyshare.get(id);
}
async updateKeyshare(id, keyshareData) {
return this.vault.keyshare.update(id, keyshareData);
}
async deleteKeyshare(id) {
return this.vault.keyshare.delete(id);
}
// PublicKey methods
async insertPublicKey(publicKeyData) {
return this.vault.publicKey.add(publicKeyData);
}
async getPublicKey(id) {
return this.vault.publicKey.get(id);
}
async updatePublicKey(id, publicKeyData) {
return this.vault.publicKey.update(id, publicKeyData);
}
async deletePublicKey(id) {
return this.vault.publicKey.delete(id);
}
// Profile methods
async insertProfile(profileData) {
return this.vault.profile.add(profileData);
}
async getProfile(id) {
return this.vault.profile.get(id);
}
async updateProfile(id, profileData) {
return this.vault.profile.update(id, profileData);
}
async deleteProfile(id) {
return this.vault.profile.delete(id);
}
// WebAuthn methods
async createPublicKeyCredential(options) {
const publicKeyCredentialCreationOptions = {
challenge: new Uint8Array(32),
rp: {
name: this.config.motr.origin,
id: new URL(this.config.motr.origin).hostname,
},
user: {
id: new TextEncoder().encode(options.subject),
name: options.subject,
displayName: options.label,
},
pubKeyCredParams: [
{ alg: -7, type: "public-key" },
{ alg: -257, type: "public-key" },
],
authenticatorSelection: {
authenticatorAttachment: "platform",
userVerification: "required",
},
timeout: 60000,
attestation: "direct",
};
try {
const credential = await navigator.credentials.create({
publicKey: publicKeyCredentialCreationOptions,
});
const publicKeyJwk = await crypto.subtle.exportKey(
"jwk",
credential.response.getPublicKey(),
);
return {
id: credential.id,
publicKey: publicKeyJwk,
type: credential.type,
transports: credential.response.getTransports(),
};
} catch (error) {
console.error("Error creating credential:", error);
throw error;
}
}
async getPublicKeyCredential(options) {
const publicKeyCredentialRequestOptions = {
challenge: new Uint8Array(32),
rpId: new URL(this.config.motr.origin).hostname,
allowCredentials: options.allowCredentials || [],
userVerification: "required",
timeout: 60000,
};
try {
const assertion = await navigator.credentials.get({
publicKey: publicKeyCredentialRequestOptions,
});
return {
id: assertion.id,
type: assertion.type,
rawId: new Uint8Array(assertion.rawId),
response: {
authenticatorData: new Uint8Array(
assertion.response.authenticatorData,
),
clientDataJSON: new Uint8Array(assertion.response.clientDataJSON),
signature: new Uint8Array(assertion.response.signature),
userHandle: new Uint8Array(assertion.response.userHandle),
},
};
} catch (error) {
console.error("Error getting credential:", error);
throw error;
}
}
}
-16
View File
@@ -1,16 +0,0 @@
importScripts(
"https://cdn.jsdelivr.net/gh/golang/go@go1.22.5/misc/wasm/wasm_exec.js",
"https://cdn.jsdelivr.net/gh/nlepage/go-wasm-http-server@v1.1.0/sw.js",
);
registerWasmHTTPListener("/app.wasm");
// Skip installed stage and jump to activating stage
self.addEventListener("install", (event) => {
event.waitUntil(skipWaiting());
});
// Start controlling clients as soon as the SW is activated
self.addEventListener("activate", (event) => {
event.waitUntil(clients.claim());
});
+1 -2
View File
@@ -4,7 +4,6 @@ import (
"github.com/ipfs/boxo/files"
"github.com/onsonr/sonr/pkg/dwn"
vault "github.com/onsonr/sonr/x/vault/types/internal"
)
type Vault struct {
@@ -18,7 +17,7 @@ func NewVault(keyshareJSON string, adddress string, chainID string, schema *dwn.
Sonr: defaultSonrConfig(chainID),
Schema: schema,
}
fileMap, err := vault.NewVaultDirectory(dwnCfg)
fileMap, err := dwn.NewVaultDirectory(dwnCfg)
if err != nil {
return nil, err
}