w3pk 0.7.2 → 0.7.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.mts CHANGED
@@ -552,10 +552,6 @@ declare class Web3Passkey {
552
552
  * @param hours - Session duration in hours
553
553
  */
554
554
  setSessionDuration(hours: number): void;
555
- /**
556
- * SDK version
557
- */
558
- get version(): string;
559
555
  }
560
556
 
561
557
  /**
package/dist/index.d.ts CHANGED
@@ -552,10 +552,6 @@ declare class Web3Passkey {
552
552
  * @param hours - Session duration in hours
553
553
  */
554
554
  setSessionDuration(hours: number): void;
555
- /**
556
- * SDK version
557
- */
558
- get version(): string;
559
555
  }
560
556
 
561
557
  /**
package/dist/index.js CHANGED
@@ -1,4 +1,4 @@
1
- "use strict";var Rt=Object.create;var Z=Object.defineProperty;var xt=Object.getOwnPropertyDescriptor;var It=Object.getOwnPropertyNames;var Bt=Object.getPrototypeOf,Tt=Object.prototype.hasOwnProperty;var u=(s,e)=>()=>(s&&(e=s(s=0)),e);var S=(s,e)=>{for(var t in e)Z(s,t,{get:e[t],enumerable:!0})},Qe=(s,e,t,r)=>{if(e&&typeof e=="object"||typeof e=="function")for(let n of It(e))!Tt.call(s,n)&&n!==t&&Z(s,n,{get:()=>e[n],enumerable:!(r=xt(e,n))||r.enumerable});return s};var B=(s,e,t)=>(t=s!=null?Rt(Bt(s)):{},Qe(e||!s||!s.__esModule?Z(t,"default",{value:s,enumerable:!0}):t,s)),Dt=s=>Qe(Z({},"__esModule",{value:!0}),s);var g,k,T,d,y,h,X,w=u(()=>{"use strict";g=class extends Error{constructor(t,r,n){super(t);this.code=r;this.originalError=n;this.name="Web3PasskeyError"}},k=class extends g{constructor(e,t){super(e,"AUTHENTICATION_ERROR",t),this.name="AuthenticationError"}},T=class extends g{constructor(e,t){super(e,"REGISTRATION_ERROR",t),this.name="RegistrationError"}},d=class extends g{constructor(e,t){super(e,"WALLET_ERROR",t),this.name="WalletError"}},y=class extends g{constructor(e,t){super(e,"CRYPTO_ERROR",t),this.name="CryptoError"}},h=class extends g{constructor(e,t){super(e,"STORAGE_ERROR",t),this.name="StorageError"}},X=class extends g{constructor(t,r,n){super(t,"API_ERROR",n);this.statusCode=r;this.name="ApiError"}}});var _={};S(_,{CredentialStorage:()=>C});var re,ne,C,R=u(()=>{"use strict";w();re="w3pk_credential_",ne="w3pk_credential_index",C=class{constructor(e){if(e)this.storage=e;else if(typeof window<"u"&&window.localStorage)this.storage=window.localStorage;else throw new h("localStorage is not available")}saveCredential(e){try{let t=`${re}${e.id}`;this.storage.setItem(t,JSON.stringify(e)),this.addToIndex(e.id)}catch(t){throw new h("Failed to save credential",t)}}getCredentialById(e){try{let t=`${re}${e}`,r=this.storage.getItem(t);return r?JSON.parse(r):null}catch(t){throw new h("Failed to retrieve credential",t)}}getCredentialByUsername(e){try{return this.getAllCredentials().find(r=>r.username===e)||null}catch(t){throw new h("Failed to retrieve credential",t)}}getCredentialByAddress(e){try{return this.getAllCredentials().find(r=>r.ethereumAddress.toLowerCase()===e.toLowerCase())||null}catch(t){throw new h("Failed to retrieve credential",t)}}getAllCredentials(){try{return this.getIndex().map(t=>this.getCredentialById(t)).filter(t=>t!==null)}catch(e){throw new h("Failed to retrieve credentials",e)}}userExists(e){return this.getCredentialByUsername(e)!==null}updateLastUsed(e){try{let t=this.getCredentialById(e);t&&(t.lastUsed=Date.now(),this.saveCredential(t))}catch(t){throw new h("Failed to update timestamp",t)}}deleteCredential(e){try{let t=`${re}${e}`;this.storage.removeItem(t),this.removeFromIndex(e)}catch(t){throw new h("Failed to delete credential",t)}}clearAll(){try{this.getIndex().forEach(t=>{let r=`${re}${t}`;this.storage.removeItem(r)}),this.storage.removeItem(ne)}catch(e){throw new h("Failed to clear credentials",e)}}getIndex(){try{let e=this.storage.getItem(ne);return e?JSON.parse(e):[]}catch{return[]}}addToIndex(e){let t=this.getIndex();t.includes(e)||(t.push(e),this.storage.setItem(ne,JSON.stringify(t)))}removeFromIndex(e){let r=this.getIndex().filter(n=>n!==e);this.storage.setItem(ne,JSON.stringify(r))}}});var xe={};S(xe,{decryptData:()=>le,deriveEncryptionKey:()=>Lt,deriveEncryptionKeyFromSignature:()=>qt,deriveEncryptionKeyFromWebAuthn:()=>x,encryptData:()=>de,generateChallenge:()=>Gt});async function x(s,e){try{let t=e?`w3pk-v4:${s}:${e}`:`w3pk-v4:${s}`,r=await crypto.subtle.digest("SHA-256",new TextEncoder().encode(t)),n=await crypto.subtle.importKey("raw",r,{name:"PBKDF2"},!1,["deriveKey"]),o=await crypto.subtle.digest("SHA-256",new TextEncoder().encode("w3pk-salt-v4"));return crypto.subtle.deriveKey({name:"PBKDF2",salt:new Uint8Array(o),iterations:21e4,hash:"SHA-256"},n,{name:"AES-GCM",length:256},!1,["encrypt","decrypt"])}catch(t){throw new y("Failed to derive encryption key from WebAuthn",t)}}async function Lt(s,e){try{let t=e?`w3pk-v2:${s}:${e}`:`w3pk-v2:${s}`,r=await crypto.subtle.digest("SHA-256",new TextEncoder().encode(t)),n=await crypto.subtle.importKey("raw",r,{name:"PBKDF2"},!1,["deriveKey"]),o=await crypto.subtle.digest("SHA-256",new TextEncoder().encode("w3pk-salt-v2"));return crypto.subtle.deriveKey({name:"PBKDF2",salt:new Uint8Array(o),iterations:21e4,hash:"SHA-256"},n,{name:"AES-GCM",length:256},!1,["encrypt","decrypt"])}catch(t){throw new y("Failed to derive encryption key",t)}}async function qt(s,e){try{if(typeof window<"u"&&window.PublicKeyCredential)return x(e);let t=await crypto.subtle.digest("SHA-256",s),r=await crypto.subtle.importKey("raw",t,{name:"PBKDF2"},!1,["deriveKey"]),n=await crypto.subtle.digest("SHA-256",new TextEncoder().encode("w3pk-salt-v3:"+e));return crypto.subtle.deriveKey({name:"PBKDF2",salt:new Uint8Array(n),iterations:21e4,hash:"SHA-256"},r,{name:"AES-GCM",length:256},!1,["encrypt","decrypt"])}catch(t){throw new y("Failed to derive encryption key",t)}}function Gt(){let s=new Uint8Array(32);return crypto.getRandomValues(s),btoa(String.fromCharCode(...s)).replace(/\+/g,"-").replace(/\//g,"_").replace(/=/g,"")}async function de(s,e){try{let t=crypto.getRandomValues(new Uint8Array(12)),r=new TextEncoder().encode(s),n=await crypto.subtle.encrypt({name:"AES-GCM",iv:t},e,r),o=new Uint8Array(t.length+n.byteLength);return o.set(t),o.set(new Uint8Array(n),t.length),btoa(String.fromCharCode(...o))}catch(t){throw new y("Failed to encrypt data",t)}}async function le(s,e){try{if(!s||s.length<16)throw new Error("Invalid encrypted data: too small");let t=new Uint8Array(atob(s).split("").map(i=>i.charCodeAt(0)));if(t.length<12)throw new Error("Invalid encrypted data: missing IV");let r=t.slice(0,12),n=t.slice(12);if(n.length===0)throw new Error("Invalid encrypted data: no content");let o=await crypto.subtle.decrypt({name:"AES-GCM",iv:r},e,n);return new TextDecoder().decode(o)}catch(t){throw new y(`Data decryption failed: ${t instanceof Error?t.message:"Unknown error"}`,t)}}var ue=u(()=>{"use strict";w()});var A,Te=u(()=>{"use strict";A=class{constructor(){this.dbName="Web3PasskeyBackup";this.version=1;this.db=null}async init(){return typeof indexedDB>"u"?Promise.resolve():new Promise((e,t)=>{let r=indexedDB.open(this.dbName,this.version);r.onerror=()=>t(r.error),r.onsuccess=()=>{this.db=r.result,e()},r.onupgradeneeded=n=>{let o=n.target.result;if(!o.objectStoreNames.contains("backups")){let i=o.createObjectStore("backups",{keyPath:"id"});i.createIndex("ethereumAddress","ethereumAddress",{unique:!1}),i.createIndex("method","method",{unique:!1}),i.createIndex("createdAt","createdAt",{unique:!1})}}})}async storeBackupMetadata(e){return this.db||await this.init(),this.db?new Promise((t,r)=>{let i=this.db.transaction(["backups"],"readwrite").objectStore("backups").put(e);i.onsuccess=()=>t(),i.onerror=()=>r(i.error)}):Promise.resolve()}async getBackupsByAddress(e){return this.db||await this.init(),this.db?new Promise((t,r)=>{let c=this.db.transaction(["backups"],"readonly").objectStore("backups").index("ethereumAddress").getAll(e);c.onsuccess=()=>t(c.result),c.onerror=()=>r(c.error)}):Promise.resolve([])}async getBackupById(e){return this.db||await this.init(),this.db?new Promise((t,r)=>{let i=this.db.transaction(["backups"],"readonly").objectStore("backups").get(e);i.onsuccess=()=>t(i.result||null),i.onerror=()=>r(i.error)}):Promise.resolve(null)}async deleteBackup(e){return this.db||await this.init(),this.db?new Promise((t,r)=>{let i=this.db.transaction(["backups"],"readwrite").objectStore("backups").delete(e);i.onsuccess=()=>t(),i.onerror=()=>r(i.error)}):Promise.resolve()}async getBackupCountByMethod(e){return this.db||await this.init(),this.db?new Promise((t,r)=>{let c=this.db.transaction(["backups"],"readonly").objectStore("backups").index("method").count(e);c.onsuccess=()=>t(c.result),c.onerror=()=>r(c.error)}):Promise.resolve(0)}}});var Fe={};S(Fe,{decryptWithPassword:()=>lt,deriveAddressChecksum:()=>b,deriveKeyFromPassword:()=>ge,encryptWithPassword:()=>M,getDeviceFingerprint:()=>f,validatePasswordStrength:()=>fe});async function ge(s,e,t=31e4){let n=new TextEncoder().encode(s),o=await crypto.subtle.importKey("raw",n,"PBKDF2",!1,["deriveBits","deriveKey"]);return crypto.subtle.deriveKey({name:"PBKDF2",salt:e,iterations:t,hash:"SHA-256"},o,{name:"AES-GCM",length:256},!1,["encrypt","decrypt"])}async function M(s,e,t){let n=await ge(e,t,31e4),i=new TextEncoder().encode(s),c=crypto.getRandomValues(new Uint8Array(12)),a=await crypto.subtle.encrypt({name:"AES-GCM",iv:c},n,i);return{encrypted:j(a),iv:j(c),salt:j(t),iterations:31e4}}async function lt(s,e,t,r,n=31e4){let o=De(t),i=await ge(e,o,n),c=De(r),a=De(s),l=await crypto.subtle.decrypt({name:"AES-GCM",iv:c},i,a);return new TextDecoder().decode(l)}async function f(){let e=[navigator.userAgent,navigator.language,new Date().getTimezoneOffset().toString(),screen.width+"x"+screen.height,screen.colorDepth.toString()].join("|"),r=new TextEncoder().encode(e),n=await crypto.subtle.digest("SHA-256",r);return j(n)}async function b(s){let t=new TextEncoder().encode(s.toLowerCase()),r=await crypto.subtle.digest("SHA-256",t);return j(r).substring(0,16)}function fe(s){let e=[],t=0;return s.length<12?e.push("Password must be at least 12 characters"):t+=25,/[A-Z]/.test(s)?t+=15:e.push("Add at least one uppercase letter"),/[a-z]/.test(s)?t+=15:e.push("Add at least one lowercase letter"),/[0-9]/.test(s)?t+=15:e.push("Add at least one number"),/[!@#$%^&*()_+\-=\[\]{};':"\\|,.<>\/?]/.test(s)?t+=15:e.push("Add at least one special character"),s.length>=16&&(t+=10),s.length>=20&&(t+=5),["password","12345678","qwerty","abc123","password123","admin","letmein"].some(n=>s.toLowerCase().includes(n))&&(e.push("Password is too common"),t=Math.min(t,25)),{valid:t>=50&&e.length===0,score:Math.min(t,100),feedback:e}}function j(s){let e=s instanceof Uint8Array?s:new Uint8Array(s),t="";for(let r=0;r<e.byteLength;r++)t+=String.fromCharCode(e[r]);return btoa(t)}function De(s){let e=atob(s),t=new Uint8Array(e.length);for(let r=0;r<e.length;r++)t[r]=e.charCodeAt(r);return t}var E=u(()=>{"use strict"});var K,Me=u(()=>{"use strict";E();K=class{async createZipBackup(e,t,r){let n=fe(r.password);if(!n.valid)throw new Error(`Weak password: ${n.feedback.join(", ")}`);let o=crypto.getRandomValues(new Uint8Array(32)),i=await M(e,r.password,o),c=r.deviceBinding?await f():void 0,a={id:crypto.randomUUID(),ethereumAddress:t,method:"zip",createdAt:Date.now(),deviceFingerprint:c,addressChecksum:await b(t)},l={version:1,encrypted:i.encrypted,iv:i.iv,salt:i.salt,iterations:i.iterations,metadata:a,deviceFingerprint:c},p=new Map;return p.set("recovery-phrase.txt.enc",JSON.stringify(l,null,2)),p.set("metadata.json",JSON.stringify({address:t,createdAt:new Date(a.createdAt).toISOString(),backupId:a.id,addressChecksum:a.addressChecksum},null,2)),r.includeInstructions!==!1&&p.set("RECOVERY_INSTRUCTIONS.txt",this.getRecoveryInstructions()),{blob:await this.createSimpleZip(p),metadata:a}}async createSimpleZip(e){let t={};return e.forEach((r,n)=>{t[n]=r}),new Blob([JSON.stringify(t,null,2)],{type:"application/json"})}getRecoveryInstructions(){return`
1
+ "use strict";var Bt=Object.create;var re=Object.defineProperty;var Tt=Object.getOwnPropertyDescriptor;var Dt=Object.getOwnPropertyNames;var Ft=Object.getPrototypeOf,Mt=Object.prototype.hasOwnProperty;var u=(s,e)=>()=>(s&&(e=s(s=0)),e);var S=(s,e)=>{for(var t in e)re(s,t,{get:e[t],enumerable:!0})},ze=(s,e,t,r)=>{if(e&&typeof e=="object"||typeof e=="function")for(let n of Dt(e))!Mt.call(s,n)&&n!==t&&re(s,n,{get:()=>e[n],enumerable:!(r=Tt(e,n))||r.enumerable});return s};var T=(s,e,t)=>(t=s!=null?Bt(Ft(s)):{},ze(e||!s||!s.__esModule?re(t,"default",{value:s,enumerable:!0}):t,s)),Kt=s=>ze(re({},"__esModule",{value:!0}),s);var g,k,D,d,y,h,ne,w=u(()=>{"use strict";g=class extends Error{constructor(t,r,n){super(t);this.code=r;this.originalError=n;this.name="Web3PasskeyError"}},k=class extends g{constructor(e,t){super(e,"AUTHENTICATION_ERROR",t),this.name="AuthenticationError"}},D=class extends g{constructor(e,t){super(e,"REGISTRATION_ERROR",t),this.name="RegistrationError"}},d=class extends g{constructor(e,t){super(e,"WALLET_ERROR",t),this.name="WalletError"}},y=class extends g{constructor(e,t){super(e,"CRYPTO_ERROR",t),this.name="CryptoError"}},h=class extends g{constructor(e,t){super(e,"STORAGE_ERROR",t),this.name="StorageError"}},ne=class extends g{constructor(t,r,n){super(t,"API_ERROR",n);this.statusCode=r;this.name="ApiError"}}});var j={};S(j,{CredentialStorage:()=>C});var ie,ae,C,R=u(()=>{"use strict";w();ie="w3pk_credential_",ae="w3pk_credential_index",C=class{constructor(e){if(e)this.storage=e;else if(typeof window<"u"&&window.localStorage)this.storage=window.localStorage;else throw new h("localStorage is not available")}saveCredential(e){try{let t=`${ie}${e.id}`;this.storage.setItem(t,JSON.stringify(e)),this.addToIndex(e.id)}catch(t){throw new h("Failed to save credential",t)}}getCredentialById(e){try{let t=`${ie}${e}`,r=this.storage.getItem(t);return r?JSON.parse(r):null}catch(t){throw new h("Failed to retrieve credential",t)}}getCredentialByUsername(e){try{return this.getAllCredentials().find(r=>r.username===e)||null}catch(t){throw new h("Failed to retrieve credential",t)}}getCredentialByAddress(e){try{return this.getAllCredentials().find(r=>r.ethereumAddress.toLowerCase()===e.toLowerCase())||null}catch(t){throw new h("Failed to retrieve credential",t)}}getAllCredentials(){try{return this.getIndex().map(t=>this.getCredentialById(t)).filter(t=>t!==null)}catch(e){throw new h("Failed to retrieve credentials",e)}}userExists(e){return this.getCredentialByUsername(e)!==null}updateLastUsed(e){try{let t=this.getCredentialById(e);t&&(t.lastUsed=Date.now(),this.saveCredential(t))}catch(t){throw new h("Failed to update timestamp",t)}}deleteCredential(e){try{let t=`${ie}${e}`;this.storage.removeItem(t),this.removeFromIndex(e)}catch(t){throw new h("Failed to delete credential",t)}}clearAll(){try{this.getIndex().forEach(t=>{let r=`${ie}${t}`;this.storage.removeItem(r)}),this.storage.removeItem(ae)}catch(e){throw new h("Failed to clear credentials",e)}}getIndex(){try{let e=this.storage.getItem(ae);return e?JSON.parse(e):[]}catch{return[]}}addToIndex(e){let t=this.getIndex();t.includes(e)||(t.push(e),this.storage.setItem(ae,JSON.stringify(t)))}removeFromIndex(e){let r=this.getIndex().filter(n=>n!==e);this.storage.setItem(ae,JSON.stringify(r))}}});function x(s){try{let e=s.replace(/-/g,"+").replace(/_/g,"/"),t=(4-e.length%4)%4;e+="=".repeat(t);let r=atob(e),n=new Uint8Array(r.length);for(let o=0;o<r.length;o++)n[o]=r.charCodeAt(o);return n.buffer}catch(e){throw new Error(`Failed to decode base64url string: ${e instanceof Error?e.message:"Invalid format"}`)}}function F(s){let e=s instanceof Uint8Array?s:new Uint8Array(s),t="";for(let r=0;r<e.length;r++)t+=String.fromCharCode(e[r]);return btoa(t).replace(/\+/g,"-").replace(/\//g,"_").replace(/=/g,"")}function M(s){try{let e=s.replace(/-/g,"+").replace(/_/g,"/"),t=(4-e.length%4)%4;return e+="=".repeat(t),atob(e)}catch(e){throw new Error(`Failed to decode base64 string: ${e instanceof Error?e.message:"Invalid format"}`)}}var J=u(()=>{"use strict"});var Te={};S(Te,{decryptData:()=>he,deriveEncryptionKey:()=>Gt,deriveEncryptionKeyFromSignature:()=>$t,deriveEncryptionKeyFromWebAuthn:()=>I,encryptData:()=>pe,generateChallenge:()=>Yt});async function I(s,e){try{let t=e?`w3pk-v4:${s}:${e}`:`w3pk-v4:${s}`,r=await crypto.subtle.digest("SHA-256",new TextEncoder().encode(t)),n=await crypto.subtle.importKey("raw",r,{name:"PBKDF2"},!1,["deriveKey"]),o=await crypto.subtle.digest("SHA-256",new TextEncoder().encode("w3pk-salt-v4"));return crypto.subtle.deriveKey({name:"PBKDF2",salt:new Uint8Array(o),iterations:21e4,hash:"SHA-256"},n,{name:"AES-GCM",length:256},!1,["encrypt","decrypt"])}catch(t){throw new y("Failed to derive encryption key from WebAuthn",t)}}async function Gt(s,e){try{let t=e?`w3pk-v2:${s}:${e}`:`w3pk-v2:${s}`,r=await crypto.subtle.digest("SHA-256",new TextEncoder().encode(t)),n=await crypto.subtle.importKey("raw",r,{name:"PBKDF2"},!1,["deriveKey"]),o=await crypto.subtle.digest("SHA-256",new TextEncoder().encode("w3pk-salt-v2"));return crypto.subtle.deriveKey({name:"PBKDF2",salt:new Uint8Array(o),iterations:21e4,hash:"SHA-256"},n,{name:"AES-GCM",length:256},!1,["encrypt","decrypt"])}catch(t){throw new y("Failed to derive encryption key",t)}}async function $t(s,e){try{if(typeof window<"u"&&window.PublicKeyCredential)return I(e);let t=await crypto.subtle.digest("SHA-256",s),r=await crypto.subtle.importKey("raw",t,{name:"PBKDF2"},!1,["deriveKey"]),n=await crypto.subtle.digest("SHA-256",new TextEncoder().encode("w3pk-salt-v3:"+e));return crypto.subtle.deriveKey({name:"PBKDF2",salt:new Uint8Array(n),iterations:21e4,hash:"SHA-256"},r,{name:"AES-GCM",length:256},!1,["encrypt","decrypt"])}catch(t){throw new y("Failed to derive encryption key",t)}}function Yt(){let s=new Uint8Array(32);return crypto.getRandomValues(s),F(s)}async function pe(s,e){try{let t=crypto.getRandomValues(new Uint8Array(12)),r=new TextEncoder().encode(s),n=await crypto.subtle.encrypt({name:"AES-GCM",iv:t},e,r),o=new Uint8Array(t.length+n.byteLength);o.set(t),o.set(new Uint8Array(n),t.length);let i="";for(let a=0;a<o.length;a++)i+=String.fromCharCode(o[a]);return btoa(i)}catch(t){throw new y("Failed to encrypt data",t)}}async function he(s,e){try{if(!s||s.length<16)throw new Error("Invalid encrypted data: too small");let t=M(s),r=new Uint8Array(t.length);for(let a=0;a<t.length;a++)r[a]=t.charCodeAt(a);if(r.length<12)throw new Error("Invalid encrypted data: missing IV");let n=r.slice(0,12),o=r.slice(12);if(o.length===0)throw new Error("Invalid encrypted data: no content");let i=await crypto.subtle.decrypt({name:"AES-GCM",iv:n},e,o);return new TextDecoder().decode(i)}catch(t){throw new y(`Data decryption failed: ${t instanceof Error?t.message:"Unknown error"}`,t)}}var ye=u(()=>{"use strict";w();J()});var A,Me=u(()=>{"use strict";A=class{constructor(){this.dbName="Web3PasskeyBackup";this.version=1;this.db=null}async init(){return typeof indexedDB>"u"?Promise.resolve():new Promise((e,t)=>{let r=indexedDB.open(this.dbName,this.version);r.onerror=()=>t(r.error),r.onsuccess=()=>{this.db=r.result,e()},r.onupgradeneeded=n=>{let o=n.target.result;if(!o.objectStoreNames.contains("backups")){let i=o.createObjectStore("backups",{keyPath:"id"});i.createIndex("ethereumAddress","ethereumAddress",{unique:!1}),i.createIndex("method","method",{unique:!1}),i.createIndex("createdAt","createdAt",{unique:!1})}}})}async storeBackupMetadata(e){return this.db||await this.init(),this.db?new Promise((t,r)=>{let i=this.db.transaction(["backups"],"readwrite").objectStore("backups").put(e);i.onsuccess=()=>t(),i.onerror=()=>r(i.error)}):Promise.resolve()}async getBackupsByAddress(e){return this.db||await this.init(),this.db?new Promise((t,r)=>{let a=this.db.transaction(["backups"],"readonly").objectStore("backups").index("ethereumAddress").getAll(e);a.onsuccess=()=>t(a.result),a.onerror=()=>r(a.error)}):Promise.resolve([])}async getBackupById(e){return this.db||await this.init(),this.db?new Promise((t,r)=>{let i=this.db.transaction(["backups"],"readonly").objectStore("backups").get(e);i.onsuccess=()=>t(i.result||null),i.onerror=()=>r(i.error)}):Promise.resolve(null)}async deleteBackup(e){return this.db||await this.init(),this.db?new Promise((t,r)=>{let i=this.db.transaction(["backups"],"readwrite").objectStore("backups").delete(e);i.onsuccess=()=>t(),i.onerror=()=>r(i.error)}):Promise.resolve()}async getBackupCountByMethod(e){return this.db||await this.init(),this.db?new Promise((t,r)=>{let a=this.db.transaction(["backups"],"readonly").objectStore("backups").index("method").count(e);a.onsuccess=()=>t(a.result),a.onerror=()=>r(a.error)}):Promise.resolve(0)}}});var Oe={};S(Oe,{decryptWithPassword:()=>ht,deriveAddressChecksum:()=>b,deriveKeyFromPassword:()=>ve,encryptWithPassword:()=>U,getDeviceFingerprint:()=>f,validatePasswordStrength:()=>be});async function ve(s,e,t=31e4){let n=new TextEncoder().encode(s),o=await crypto.subtle.importKey("raw",n,"PBKDF2",!1,["deriveBits","deriveKey"]);return crypto.subtle.deriveKey({name:"PBKDF2",salt:e,iterations:t,hash:"SHA-256"},o,{name:"AES-GCM",length:256},!1,["encrypt","decrypt"])}async function U(s,e,t){let n=await ve(e,t,31e4),i=new TextEncoder().encode(s),a=crypto.getRandomValues(new Uint8Array(12)),c=await crypto.subtle.encrypt({name:"AES-GCM",iv:a},n,i);return{encrypted:X(c),iv:X(a),salt:X(t),iterations:31e4}}async function ht(s,e,t,r,n=31e4){let o=Ke(t),i=await ve(e,o,n),a=Ke(r),c=Ke(s),l=await crypto.subtle.decrypt({name:"AES-GCM",iv:a},i,c);return new TextDecoder().decode(l)}async function f(){let e=[navigator.userAgent,navigator.language,new Date().getTimezoneOffset().toString(),screen.width+"x"+screen.height,screen.colorDepth.toString()].join("|"),r=new TextEncoder().encode(e),n=await crypto.subtle.digest("SHA-256",r);return X(n)}async function b(s){let t=new TextEncoder().encode(s.toLowerCase()),r=await crypto.subtle.digest("SHA-256",t);return X(r).substring(0,16)}function be(s){let e=[],t=0;return s.length<12?e.push("Password must be at least 12 characters"):t+=25,/[A-Z]/.test(s)?t+=15:e.push("Add at least one uppercase letter"),/[a-z]/.test(s)?t+=15:e.push("Add at least one lowercase letter"),/[0-9]/.test(s)?t+=15:e.push("Add at least one number"),/[!@#$%^&*()_+\-=\[\]{};':"\\|,.<>\/?]/.test(s)?t+=15:e.push("Add at least one special character"),s.length>=16&&(t+=10),s.length>=20&&(t+=5),["password","12345678","qwerty","abc123","password123","admin","letmein"].some(n=>s.toLowerCase().includes(n))&&(e.push("Password is too common"),t=Math.min(t,25)),{valid:t>=50&&e.length===0,score:Math.min(t,100),feedback:e}}function X(s){let e=s instanceof Uint8Array?s:new Uint8Array(s),t="";for(let r=0;r<e.byteLength;r++)t+=String.fromCharCode(e[r]);return btoa(t)}function Ke(s){let e=M(s),t=new Uint8Array(e.length);for(let r=0;r<e.length;r++)t[r]=e.charCodeAt(r);return t}var E=u(()=>{"use strict";J()});var W,Ue=u(()=>{"use strict";E();W=class{async createZipBackup(e,t,r){let n=be(r.password);if(!n.valid)throw new Error(`Weak password: ${n.feedback.join(", ")}`);let o=crypto.getRandomValues(new Uint8Array(32)),i=await U(e,r.password,o),a=r.deviceBinding?await f():void 0,c={id:crypto.randomUUID(),ethereumAddress:t,method:"zip",createdAt:Date.now(),deviceFingerprint:a,addressChecksum:await b(t)},l={version:1,encrypted:i.encrypted,iv:i.iv,salt:i.salt,iterations:i.iterations,metadata:c,deviceFingerprint:a},p=new Map;return p.set("recovery-phrase.txt.enc",JSON.stringify(l,null,2)),p.set("metadata.json",JSON.stringify({address:t,createdAt:new Date(c.createdAt).toISOString(),backupId:c.id,addressChecksum:c.addressChecksum},null,2)),r.includeInstructions!==!1&&p.set("RECOVERY_INSTRUCTIONS.txt",this.getRecoveryInstructions()),{blob:await this.createSimpleZip(p),metadata:c}}async createSimpleZip(e){let t={};return e.forEach((r,n)=>{t[n]=r}),new Blob([JSON.stringify(t,null,2)],{type:"application/json"})}getRecoveryInstructions(){return`
2
2
  W3PK WALLET RECOVERY INSTRUCTIONS
3
3
  =================================
4
4
 
@@ -64,7 +64,7 @@ Visit: https://docs.w3pk.org/recovery
64
64
  Email: support@w3pk.org
65
65
 
66
66
  Generated: ${new Date().toISOString()}
67
- `}async restoreFromZipBackup(e,t){let r=JSON.parse(e);if(r.version!==1)throw new Error("Unsupported backup version");let{decryptWithPassword:n}=await Promise.resolve().then(()=>(E(),Fe)),o=await n(r.encrypted,t,r.salt,r.iv,r.iterations),{Wallet:i}=await import("ethers"),c=i.fromPhrase(o);if(await b(c.address)!==r.metadata.addressChecksum)throw new Error("Address checksum mismatch - corrupted backup or wrong password");return{mnemonic:o,metadata:r.metadata}}}});var O,Ke=u(()=>{"use strict";E();O=class{async createQRBackup(e,t,r={}){let n=r.errorCorrection||"H",o;if(r.password){let l=crypto.getRandomValues(new Uint8Array(32)),p=await M(e,r.password,l);o={version:1,type:"encrypted",data:p.encrypted,iv:p.iv,salt:p.salt,iterations:p.iterations,checksum:await b(t)}}else o={version:1,type:"plain",data:e,checksum:await b(t)};let i=JSON.stringify(o),c=await this.generateQRCode(i,n),a=this.getInstructions(t,!!r.password);return{qrCodeDataURL:c,rawData:i,instructions:a}}async generateQRCode(e,t){try{return await(await import("qrcode")).default.toDataURL(e,{errorCorrectionLevel:t,width:512,margin:2})}catch{return this.createFallbackQRDataURL(e)}}createFallbackQRDataURL(e){if(typeof document>"u")return`data:text/plain;base64,${Buffer.from(e).toString("base64")}`;let t=document.createElement("canvas");t.width=512,t.height=512;let r=t.getContext("2d");if(!r)throw new Error("Canvas not supported");r.fillStyle="white",r.fillRect(0,0,512,512),r.fillStyle="black",r.font="12px monospace",r.textAlign="center",r.textBaseline="middle";let n=this.wrapText(e,50),o=14,i=256-n.length*o/2;return n.forEach((c,a)=>{r.fillText(c,256,i+a*o)}),r.font="bold 16px sans-serif",r.fillText('Install "qrcode" package for QR codes',256,480),t.toDataURL("image/png")}wrapText(e,t){let r=[];for(let n=0;n<e.length;n+=t)r.push(e.substring(n,n+t));return r}getInstructions(e,t){return`
67
+ `}async restoreFromZipBackup(e,t){let r=JSON.parse(e);if(r.version!==1)throw new Error("Unsupported backup version");let{decryptWithPassword:n}=await Promise.resolve().then(()=>(E(),Oe)),o=await n(r.encrypted,t,r.salt,r.iv,r.iterations),{Wallet:i}=await import("ethers"),a=i.fromPhrase(o);if(await b(a.address)!==r.metadata.addressChecksum)throw new Error("Address checksum mismatch - corrupted backup or wrong password");return{mnemonic:o,metadata:r.metadata}}}});var N,We=u(()=>{"use strict";E();N=class{async createQRBackup(e,t,r={}){let n=r.errorCorrection||"H",o;if(r.password){let l=crypto.getRandomValues(new Uint8Array(32)),p=await U(e,r.password,l);o={version:1,type:"encrypted",data:p.encrypted,iv:p.iv,salt:p.salt,iterations:p.iterations,checksum:await b(t)}}else o={version:1,type:"plain",data:e,checksum:await b(t)};let i=JSON.stringify(o),a=await this.generateQRCode(i,n),c=this.getInstructions(t,!!r.password);return{qrCodeDataURL:a,rawData:i,instructions:c}}async generateQRCode(e,t){try{return await(await import("qrcode")).default.toDataURL(e,{errorCorrectionLevel:t,width:512,margin:2})}catch{return this.createFallbackQRDataURL(e)}}createFallbackQRDataURL(e){if(typeof document>"u")return`data:text/plain;base64,${Buffer.from(e).toString("base64")}`;let t=document.createElement("canvas");t.width=512,t.height=512;let r=t.getContext("2d");if(!r)throw new Error("Canvas not supported");r.fillStyle="white",r.fillRect(0,0,512,512),r.fillStyle="black",r.font="12px monospace",r.textAlign="center",r.textBaseline="middle";let n=this.wrapText(e,50),o=14,i=256-n.length*o/2;return n.forEach((a,c)=>{r.fillText(a,256,i+c*o)}),r.font="bold 16px sans-serif",r.fillText('Install "qrcode" package for QR codes',256,480),t.toDataURL("image/png")}wrapText(e,t){let r=[];for(let n=0;n<e.length;n+=t)r.push(e.substring(n,n+t));return r}getInstructions(e,t){return`
68
68
  W3PK QR CODE BACKUP
69
69
  ==================
70
70
 
@@ -140,13 +140,13 @@ If QR code is lost/damaged, you can still recover using:
140
140
 
141
141
  Generated by w3pk Recovery System
142
142
  https://docs.w3pk.org/recovery
143
- `}async restoreFromQR(e,t){let r=JSON.parse(e);if(r.version!==1)throw new Error("Unsupported QR backup version");let n;if(r.type==="encrypted"){if(!t)throw new Error("Password required for encrypted QR backup");let{decryptWithPassword:a}=await Promise.resolve().then(()=>(E(),Fe));n=await a(r.data,t,r.salt,r.iv,r.iterations)}else if(r.type==="plain")n=r.data;else throw new Error("Unknown QR backup type");let{Wallet:o}=await import("ethers"),i=o.fromPhrase(n);if(await b(i.address)!==r.checksum)throw new Error("Address checksum mismatch - corrupted QR or wrong password");return{mnemonic:n,ethereumAddress:i.address}}}});var U,ut=u(()=>{"use strict";Te();Me();Ke();U=class{constructor(){this.storage=new A,this.zipCreator=new K,this.qrCreator=new O}async getBackupStatus(e){let t=await this.storage.getBackupsByAddress(e),r=await this.detectPasskeySync(),n=t.map(i=>({id:i.id,method:i.method,location:"local",createdAt:i.createdAt,deviceFingerprint:i.deviceFingerprint}));return{passkeySync:r,recoveryPhrase:{verified:!1,verificationCount:0,encryptedBackups:n},securityScore:this.calculateSecurityScore(r,n)}}async detectPasskeySync(){if(typeof navigator>"u")return{enabled:!1,deviceCount:0,lastSyncTime:void 0,platform:"unknown"};let e=navigator.userAgent.toLowerCase(),t="unknown";e.includes("mac")||e.includes("iphone")||e.includes("ipad")?t="apple":e.includes("android")?t="google":e.includes("windows")&&(t="microsoft");let r=await this.checkResidentKeySupport();return{enabled:r,deviceCount:1,lastSyncTime:r?Date.now():void 0,platform:t}}async checkResidentKeySupport(){if(typeof window>"u"||!window.PublicKeyCredential)return!1;try{return await PublicKeyCredential.isUserVerifyingPlatformAuthenticatorAvailable()}catch{return!1}}calculateSecurityScore(e,t){let r={passkeyActive:e.enabled?20:0,passkeyMultiDevice:e.deviceCount>1?10:0,phraseVerified:0,encryptedBackup:t.length>0?20:0,socialRecovery:0},n=Object.values(r).reduce((c,a)=>c+a,0),o,i;return n<=20?(o="vulnerable",i='Create encrypted backup to reach "protected" (40+ pts)'):n<=50?(o="protected",i='Set up social recovery to reach "secured" (70+ pts)'):n<=80?(o="secured",i='Enable all methods to reach "fort-knox" (100 pts)'):(o="fort-knox",i="Maximum security achieved! \u{1F3C6}"),{total:n,breakdown:r,level:o,nextMilestone:i}}async createZipBackup(e,t,r){let{blob:n,metadata:o}=await this.zipCreator.createZipBackup(e,t,r);return await this.storage.storeBackupMetadata(o),n}async createQRBackup(e,t,r){let{qrCodeDataURL:n,rawData:o,instructions:i}=await this.qrCreator.createQRBackup(e,t,r),c={id:crypto.randomUUID(),ethereumAddress:t,method:"qr",createdAt:Date.now(),addressChecksum:JSON.parse(o).checksum};return await this.storage.storeBackupMetadata(c),{qrCodeDataURL:n,instructions:i}}async restoreFromZipBackup(e,t){let{mnemonic:r,metadata:n}=await this.zipCreator.restoreFromZipBackup(e,t);return{mnemonic:r,ethereumAddress:n.ethereumAddress}}async restoreFromQR(e,t){return await this.qrCreator.restoreFromQR(e,t)}async simulateRecoveryScenario(e,t){let r=[];switch(e.type){case"lost-device":t.passkeySync.enabled&&t.passkeySync.deviceCount>1&&r.push({method:"Passkey Sync (iCloud/Google)",success:!0,time:"5 minutes",requirements:["Sign in to cloud account","Authenticate on new device"]}),t.recoveryPhrase.encryptedBackups.length>0&&r.push({method:"Encrypted ZIP Backup",success:!0,time:"2 minutes",requirements:["Backup file","Password"]}),t.socialRecovery?.enabled&&r.push({method:"Social Recovery",success:!0,time:"24 hours",requirements:[`${t.socialRecovery.threshold} guardian shares`]});break;case"lost-phrase":t.passkeySync.enabled&&r.push({method:"Passkey (current device)",success:!0,time:"instant",requirements:["Current device","Biometric/PIN"]}),t.socialRecovery?.enabled&&r.push({method:"Social Recovery",success:!0,time:"24 hours",requirements:[`${t.socialRecovery.threshold} guardian shares`]});break;case"lost-both":t.passkeySync.enabled&&t.passkeySync.deviceCount>1&&r.push({method:"Passkey Sync",success:!0,time:"5 minutes",requirements:["Cloud account access","New device"]}),t.socialRecovery?.enabled&&r.push({method:"Social Recovery",success:!0,time:"24 hours",requirements:[`${t.socialRecovery.threshold} guardian shares`]});break;case"switch-platform":t.recoveryPhrase.encryptedBackups.length>0&&r.push({method:"Encrypted Backup",success:!0,time:"2 minutes",requirements:["Backup file","Password"]}),t.socialRecovery?.enabled&&r.push({method:"Social Recovery",success:!0,time:"24 hours",requirements:[`${t.socialRecovery.threshold} guardian shares`]});break}let n=r.length>0&&r.some(i=>i.success),o="";return n?(o=`\u2705 You're safe! ${r.length} way${r.length>1?"s":""} to recover.
143
+ `}async restoreFromQR(e,t){let r=JSON.parse(e);if(r.version!==1)throw new Error("Unsupported QR backup version");let n;if(r.type==="encrypted"){if(!t)throw new Error("Password required for encrypted QR backup");let{decryptWithPassword:c}=await Promise.resolve().then(()=>(E(),Oe));n=await c(r.data,t,r.salt,r.iv,r.iterations)}else if(r.type==="plain")n=r.data;else throw new Error("Unknown QR backup type");let{Wallet:o}=await import("ethers"),i=o.fromPhrase(n);if(await b(i.address)!==r.checksum)throw new Error("Address checksum mismatch - corrupted QR or wrong password");return{mnemonic:n,ethereumAddress:i.address}}}});var L,yt=u(()=>{"use strict";Me();Ue();We();L=class{constructor(){this.storage=new A,this.zipCreator=new W,this.qrCreator=new N}async getBackupStatus(e){let t=await this.storage.getBackupsByAddress(e),r=await this.detectPasskeySync(),n=t.map(i=>({id:i.id,method:i.method,location:"local",createdAt:i.createdAt,deviceFingerprint:i.deviceFingerprint}));return{passkeySync:r,recoveryPhrase:{verified:!1,verificationCount:0,encryptedBackups:n},securityScore:this.calculateSecurityScore(r,n)}}async detectPasskeySync(){if(typeof navigator>"u")return{enabled:!1,deviceCount:0,lastSyncTime:void 0,platform:"unknown"};let e=navigator.userAgent.toLowerCase(),t="unknown";e.includes("mac")||e.includes("iphone")||e.includes("ipad")?t="apple":e.includes("android")?t="google":e.includes("windows")&&(t="microsoft");let r=await this.checkResidentKeySupport();return{enabled:r,deviceCount:1,lastSyncTime:r?Date.now():void 0,platform:t}}async checkResidentKeySupport(){if(typeof window>"u"||!window.PublicKeyCredential)return!1;try{return await PublicKeyCredential.isUserVerifyingPlatformAuthenticatorAvailable()}catch{return!1}}calculateSecurityScore(e,t){let r={passkeyActive:e.enabled?20:0,passkeyMultiDevice:e.deviceCount>1?10:0,phraseVerified:0,encryptedBackup:t.length>0?20:0,socialRecovery:0},n=Object.values(r).reduce((a,c)=>a+c,0),o,i;return n<=20?(o="vulnerable",i='Create encrypted backup to reach "protected" (40+ pts)'):n<=50?(o="protected",i='Set up social recovery to reach "secured" (70+ pts)'):n<=80?(o="secured",i='Enable all methods to reach "fort-knox" (100 pts)'):(o="fort-knox",i="Maximum security achieved! \u{1F3C6}"),{total:n,breakdown:r,level:o,nextMilestone:i}}async createZipBackup(e,t,r){let{blob:n,metadata:o}=await this.zipCreator.createZipBackup(e,t,r);return await this.storage.storeBackupMetadata(o),n}async createQRBackup(e,t,r){let{qrCodeDataURL:n,rawData:o,instructions:i}=await this.qrCreator.createQRBackup(e,t,r),a={id:crypto.randomUUID(),ethereumAddress:t,method:"qr",createdAt:Date.now(),addressChecksum:JSON.parse(o).checksum};return await this.storage.storeBackupMetadata(a),{qrCodeDataURL:n,instructions:i}}async restoreFromZipBackup(e,t){let{mnemonic:r,metadata:n}=await this.zipCreator.restoreFromZipBackup(e,t);return{mnemonic:r,ethereumAddress:n.ethereumAddress}}async restoreFromQR(e,t){return await this.qrCreator.restoreFromQR(e,t)}async simulateRecoveryScenario(e,t){let r=[];switch(e.type){case"lost-device":t.passkeySync.enabled&&t.passkeySync.deviceCount>1&&r.push({method:"Passkey Sync (iCloud/Google)",success:!0,time:"5 minutes",requirements:["Sign in to cloud account","Authenticate on new device"]}),t.recoveryPhrase.encryptedBackups.length>0&&r.push({method:"Encrypted ZIP Backup",success:!0,time:"2 minutes",requirements:["Backup file","Password"]}),t.socialRecovery?.enabled&&r.push({method:"Social Recovery",success:!0,time:"24 hours",requirements:[`${t.socialRecovery.threshold} guardian shares`]});break;case"lost-phrase":t.passkeySync.enabled&&r.push({method:"Passkey (current device)",success:!0,time:"instant",requirements:["Current device","Biometric/PIN"]}),t.socialRecovery?.enabled&&r.push({method:"Social Recovery",success:!0,time:"24 hours",requirements:[`${t.socialRecovery.threshold} guardian shares`]});break;case"lost-both":t.passkeySync.enabled&&t.passkeySync.deviceCount>1&&r.push({method:"Passkey Sync",success:!0,time:"5 minutes",requirements:["Cloud account access","New device"]}),t.socialRecovery?.enabled&&r.push({method:"Social Recovery",success:!0,time:"24 hours",requirements:[`${t.socialRecovery.threshold} guardian shares`]});break;case"switch-platform":t.recoveryPhrase.encryptedBackups.length>0&&r.push({method:"Encrypted Backup",success:!0,time:"2 minutes",requirements:["Backup file","Password"]}),t.socialRecovery?.enabled&&r.push({method:"Social Recovery",success:!0,time:"24 hours",requirements:[`${t.socialRecovery.threshold} guardian shares`]});break}let n=r.length>0&&r.some(i=>i.success),o="";return n?(o=`\u2705 You're safe! ${r.length} way${r.length>1?"s":""} to recover.
144
144
 
145
145
  `,o+=`Available recovery methods:
146
146
  `,r.forEach(i=>{o+=`- ${i.method} (~${i.time})
147
147
  `})):(o=`\u274C Wallet cannot be recovered in this scenario.
148
148
 
149
- `,o+="Recommendation: Set up at least 2 backup methods to prevent total loss."),{scenario:e,success:n,availableMethods:r,timeEstimate:n?r[0].time:"N/A",educationalNote:o}}}});var pt=u(()=>{"use strict"});var W={};S(W,{BackupManager:()=>U,BackupStorage:()=>A,QRBackupCreator:()=>O,ZipBackupCreator:()=>K,decryptWithPassword:()=>lt,deriveAddressChecksum:()=>b,deriveKeyFromPassword:()=>ge,encryptWithPassword:()=>M,getDeviceFingerprint:()=>f,validatePasswordStrength:()=>fe});var I=u(()=>{"use strict";ut();Te();Me();Ke();pt();E()});function zt(){let s=new Uint8Array(1);return crypto.getRandomValues(s),s[0]}function Oe(s,e,t){if(e>t)throw new Error("Threshold cannot be greater than total shares");if(e<2)throw new Error("Threshold must be at least 2");if(t>255)throw new Error("Cannot create more than 255 shares");let r=[];for(let n=0;n<t;n++)r[n]=new Uint8Array(s.length+1),r[n][0]=n+1;for(let n=0;n<s.length;n++){let i=[s[n]];for(let c=1;c<e;c++)i.push(zt());for(let c=0;c<t;c++){let a=c+1,l=we.evaluatePolynomial(i,a);r[c][n+1]=l}}return r}function Ue(s,e){if(s.length<e)throw new Error(`Need at least ${e} shares to recover secret, got ${s.length}`);let t=s.slice(0,e),r=t[0].length;for(let i of t)if(i.length!==r)throw new Error("All shares must have the same length");let n=r-1,o=new Uint8Array(n);for(let i=0;i<n;i++){let c=[];for(let a of t)c.push({x:a[0],y:a[i+1]});o[i]=we.interpolate(c)}return o}function We(s){return new TextEncoder().encode(s)}function Ne(s){return new TextDecoder().decode(s)}function Le(s){return Array.from(s).map(e=>e.toString(16).padStart(2,"0")).join("")}function qe(s){let e=new Uint8Array(s.length/2);for(let t=0;t<s.length;t+=2)e[t/2]=parseInt(s.substring(t,t+2),16);return e}var P,we,Ge=u(()=>{"use strict";P=class P{static multiply(e,t){return e===0||t===0?0:this.EXP_TABLE[(this.LOG_TABLE[e]+this.LOG_TABLE[t])%255]}static divide(e,t){if(t===0)throw new Error("Division by zero in GF(256)");return e===0?0:this.EXP_TABLE[(this.LOG_TABLE[e]-this.LOG_TABLE[t]+255)%255]}static add(e,t){return e^t}static evaluatePolynomial(e,t){let r=0;for(let n=e.length-1;n>=0;n--)r=this.add(this.multiply(r,t),e[n]);return r}static interpolate(e){let t=0;for(let r=0;r<e.length;r++){let n=e[r].y,o=1;for(let i=0;i<e.length;i++)r!==i&&(n=this.multiply(n,e[i].x),o=this.multiply(o,this.add(e[r].x,e[i].x)));t=this.add(t,this.divide(n,o))}return t}};P.LOG_TABLE=[],P.EXP_TABLE=[],(()=>{let e=(r,n)=>{let o=0;for(let i=0;i<8;i++){n&1&&(o^=r);let c=r&128;r<<=1,c&&(r^=283),n>>=1}return o&255},t=1;for(let r=0;r<255;r++)P.EXP_TABLE[r]=t,P.LOG_TABLE[t]=r,t=e(t,3);P.EXP_TABLE[255]=P.EXP_TABLE[0]})();we=P});var ht,N,yt=u(()=>{"use strict";Ge();ht=new Map,N=class{constructor(){this.storageKey="w3pk_social_recovery"}getItem(e){return typeof localStorage<"u"?localStorage.getItem(e):ht.get(e)||null}setItem(e,t){typeof localStorage<"u"?localStorage.setItem(e,t):ht.set(e,t)}async setupSocialRecovery(e,t,r,n){if(n>r.length)throw new Error("Threshold cannot be greater than number of guardians");if(n<2)throw new Error("Threshold must be at least 2");if(r.length>255)throw new Error("Cannot have more than 255 guardians");let o=We(e),i=Oe(o,n,r.length),c=r.map((l,p)=>({id:crypto.randomUUID(),name:l.name,email:l.email,phone:l.phone,shareEncrypted:Le(i[p]),status:"pending",addedAt:Date.now()})),a={threshold:n,totalGuardians:r.length,guardians:c,createdAt:Date.now(),ethereumAddress:t};return this.setItem(this.storageKey,JSON.stringify(a)),c}getSocialRecoveryConfig(){let e=this.getItem(this.storageKey);if(!e)return null;try{return JSON.parse(e)}catch{return null}}async generateGuardianInvite(e){let t=this.getSocialRecoveryConfig();if(!t)throw new Error("Social recovery not configured");let r=t.guardians.findIndex(a=>a.id===e.id);if(r===-1)throw new Error("Guardian not found");let n={version:1,guardianId:e.id,guardianName:e.name,guardianIndex:r+1,totalGuardians:t.totalGuardians,threshold:t.threshold,share:e.shareEncrypted,ethereumAddress:t.ethereumAddress,createdAt:t.createdAt},o=JSON.stringify(n),i=await this.generateQRCode(o),c=this.getGuardianExplainer(e.name,r+1,t.totalGuardians,t.threshold);return{guardianId:e.id,qrCode:i,shareCode:o,explainer:c}}async generateQRCode(e){try{return await(await import("qrcode")).toDataURL(e,{errorCorrectionLevel:"H",width:512,margin:2})}catch{return this.createPlaceholderQR(e)}}createPlaceholderQR(e){if(typeof document>"u")return`data:text/plain;base64,${Buffer.from(e).toString("base64")}`;let t=document.createElement("canvas");t.width=512,t.height=512;let r=t.getContext("2d");return r?(r.fillStyle="white",r.fillRect(0,0,512,512),r.fillStyle="black",r.font="bold 20px sans-serif",r.textAlign="center",r.textBaseline="middle",r.fillText("Guardian Recovery Share",256,100),r.font="14px monospace",r.fillText('Install "qrcode" for QR codes',256,480),r.font="10px monospace",this.wrapText(e.substring(0,200)+"...",60).forEach((o,i)=>{r.fillText(o,256,150+i*12)}),t.toDataURL("image/png")):""}wrapText(e,t){let r=[];for(let n=0;n<e.length;n+=t)r.push(e.substring(n,n+t));return r}getGuardianExplainer(e,t,r,n){return`
149
+ `,o+="Recommendation: Set up at least 2 backup methods to prevent total loss."),{scenario:e,success:n,availableMethods:r,timeEstimate:n?r[0].time:"N/A",educationalNote:o}}}});var mt=u(()=>{"use strict"});var q={};S(q,{BackupManager:()=>L,BackupStorage:()=>A,QRBackupCreator:()=>N,ZipBackupCreator:()=>W,decryptWithPassword:()=>ht,deriveAddressChecksum:()=>b,deriveKeyFromPassword:()=>ve,encryptWithPassword:()=>U,getDeviceFingerprint:()=>f,validatePasswordStrength:()=>be});var B=u(()=>{"use strict";yt();Me();Ue();We();mt();E()});function Xt(){let s=new Uint8Array(1);return crypto.getRandomValues(s),s[0]}function Ne(s,e,t){if(e>t)throw new Error("Threshold cannot be greater than total shares");if(e<2)throw new Error("Threshold must be at least 2");if(t>255)throw new Error("Cannot create more than 255 shares");let r=[];for(let n=0;n<t;n++)r[n]=new Uint8Array(s.length+1),r[n][0]=n+1;for(let n=0;n<s.length;n++){let i=[s[n]];for(let a=1;a<e;a++)i.push(Xt());for(let a=0;a<t;a++){let c=a+1,l=Se.evaluatePolynomial(i,c);r[a][n+1]=l}}return r}function Le(s,e){if(s.length<e)throw new Error(`Need at least ${e} shares to recover secret, got ${s.length}`);let t=s.slice(0,e),r=t[0].length;for(let i of t)if(i.length!==r)throw new Error("All shares must have the same length");let n=r-1,o=new Uint8Array(n);for(let i=0;i<n;i++){let a=[];for(let c of t)a.push({x:c[0],y:c[i+1]});o[i]=Se.interpolate(a)}return o}function qe(s){return new TextEncoder().encode(s)}function Ge(s){return new TextDecoder().decode(s)}function $e(s){return Array.from(s).map(e=>e.toString(16).padStart(2,"0")).join("")}function Ye(s){let e=new Uint8Array(s.length/2);for(let t=0;t<s.length;t+=2)e[t/2]=parseInt(s.substring(t,t+2),16);return e}var P,Se,He=u(()=>{"use strict";P=class P{static multiply(e,t){return e===0||t===0?0:this.EXP_TABLE[(this.LOG_TABLE[e]+this.LOG_TABLE[t])%255]}static divide(e,t){if(t===0)throw new Error("Division by zero in GF(256)");return e===0?0:this.EXP_TABLE[(this.LOG_TABLE[e]-this.LOG_TABLE[t]+255)%255]}static add(e,t){return e^t}static evaluatePolynomial(e,t){let r=0;for(let n=e.length-1;n>=0;n--)r=this.add(this.multiply(r,t),e[n]);return r}static interpolate(e){let t=0;for(let r=0;r<e.length;r++){let n=e[r].y,o=1;for(let i=0;i<e.length;i++)r!==i&&(n=this.multiply(n,e[i].x),o=this.multiply(o,this.add(e[r].x,e[i].x)));t=this.add(t,this.divide(n,o))}return t}};P.LOG_TABLE=[],P.EXP_TABLE=[],(()=>{let e=(r,n)=>{let o=0;for(let i=0;i<8;i++){n&1&&(o^=r);let a=r&128;r<<=1,a&&(r^=283),n>>=1}return o&255},t=1;for(let r=0;r<255;r++)P.EXP_TABLE[r]=t,P.LOG_TABLE[t]=r,t=e(t,3);P.EXP_TABLE[255]=P.EXP_TABLE[0]})();Se=P});var gt,G,ft=u(()=>{"use strict";He();gt=new Map,G=class{constructor(){this.storageKey="w3pk_social_recovery"}getItem(e){return typeof localStorage<"u"?localStorage.getItem(e):gt.get(e)||null}setItem(e,t){typeof localStorage<"u"?localStorage.setItem(e,t):gt.set(e,t)}async setupSocialRecovery(e,t,r,n){if(n>r.length)throw new Error("Threshold cannot be greater than number of guardians");if(n<2)throw new Error("Threshold must be at least 2");if(r.length>255)throw new Error("Cannot have more than 255 guardians");let o=qe(e),i=Ne(o,n,r.length),a=r.map((l,p)=>({id:crypto.randomUUID(),name:l.name,email:l.email,phone:l.phone,shareEncrypted:$e(i[p]),status:"pending",addedAt:Date.now()})),c={threshold:n,totalGuardians:r.length,guardians:a,createdAt:Date.now(),ethereumAddress:t};return this.setItem(this.storageKey,JSON.stringify(c)),a}getSocialRecoveryConfig(){let e=this.getItem(this.storageKey);if(!e)return null;try{return JSON.parse(e)}catch{return null}}async generateGuardianInvite(e){let t=this.getSocialRecoveryConfig();if(!t)throw new Error("Social recovery not configured");let r=t.guardians.findIndex(c=>c.id===e.id);if(r===-1)throw new Error("Guardian not found");let n={version:1,guardianId:e.id,guardianName:e.name,guardianIndex:r+1,totalGuardians:t.totalGuardians,threshold:t.threshold,share:e.shareEncrypted,ethereumAddress:t.ethereumAddress,createdAt:t.createdAt},o=JSON.stringify(n),i=await this.generateQRCode(o),a=this.getGuardianExplainer(e.name,r+1,t.totalGuardians,t.threshold);return{guardianId:e.id,qrCode:i,shareCode:o,explainer:a}}async generateQRCode(e){try{return await(await import("qrcode")).toDataURL(e,{errorCorrectionLevel:"H",width:512,margin:2})}catch{return this.createPlaceholderQR(e)}}createPlaceholderQR(e){if(typeof document>"u")return`data:text/plain;base64,${Buffer.from(e).toString("base64")}`;let t=document.createElement("canvas");t.width=512,t.height=512;let r=t.getContext("2d");return r?(r.fillStyle="white",r.fillRect(0,0,512,512),r.fillStyle="black",r.font="bold 20px sans-serif",r.textAlign="center",r.textBaseline="middle",r.fillText("Guardian Recovery Share",256,100),r.font="14px monospace",r.fillText('Install "qrcode" for QR codes',256,480),r.font="10px monospace",this.wrapText(e.substring(0,200)+"...",60).forEach((o,i)=>{r.fillText(o,256,150+i*12)}),t.toDataURL("image/png")):""}wrapText(e,t){let r=[];for(let n=0;n<e.length;n+=t)r.push(e.substring(n,n+t));return r}getGuardianExplainer(e,t,r,n){return`
150
150
  \u{1F6E1}\uFE0F GUARDIAN RECOVERY SHARE
151
151
 
152
152
  Dear ${e},
@@ -234,7 +234,7 @@ Thank you for being a trusted guardian!
234
234
 
235
235
  NEED HELP?
236
236
  Visit: https://docs.w3pk.org/social-recovery
237
- `}async recoverFromGuardians(e){let t=this.getSocialRecoveryConfig();if(!t)throw new Error("Social recovery not configured");if(e.length<t.threshold)throw new Error(`Need at least ${t.threshold} shares, got ${e.length}`);let n=e.map(l=>{let p=JSON.parse(l);return{guardianId:p.guardianId,share:p.share,index:p.guardianIndex}}).map(l=>qe(l.share)),o=Ue(n,t.threshold),i=Ne(o),{Wallet:c}=await import("ethers"),a=c.fromPhrase(i);if(a.address.toLowerCase()!==t.ethereumAddress.toLowerCase())throw new Error("Recovered address does not match - invalid shares");return{mnemonic:i,ethereumAddress:a.address}}getRecoveryProgress(e){let t=this.getSocialRecoveryConfig();if(!t)throw new Error("Social recovery not configured");let r=new Set(e.map(n=>{try{return JSON.parse(n).guardianId}catch{return null}}).filter(Boolean));return{collected:r.size,required:t.threshold,guardians:t.guardians.map(n=>({id:n.id,name:n.name,hasProvided:r.has(n.id)})),canRecover:r.size>=t.threshold}}markGuardianVerified(e){let t=this.getSocialRecoveryConfig();if(!t)throw new Error("Social recovery not configured");let r=t.guardians.find(n=>n.id===e);if(!r)throw new Error("Guardian not found");r.status="active",r.lastVerified=Date.now(),this.setItem(this.storageKey,JSON.stringify(t))}revokeGuardian(e){let t=this.getSocialRecoveryConfig();if(!t)throw new Error("Social recovery not configured");let r=t.guardians.find(n=>n.id===e);if(!r)throw new Error("Guardian not found");r.status="revoked",this.setItem(this.storageKey,JSON.stringify(t))}async addGuardian(e,t){let r=this.getSocialRecoveryConfig();if(!r)throw new Error("Social recovery not configured");let n=[...r.guardians.filter(i=>i.status!=="revoked").map(i=>({name:i.name,email:i.email,phone:i.phone})),t],o=await this.setupSocialRecovery(e,r.ethereumAddress,n,r.threshold);return o[o.length-1]}}});var mt=u(()=>{"use strict"});var ve={};S(ve,{SocialRecoveryManager:()=>N,bytesToHex:()=>Le,bytesToString:()=>Ne,combineShares:()=>Ue,hexToBytes:()=>qe,splitSecret:()=>Oe,stringToBytes:()=>We});var J=u(()=>{"use strict";yt();Ge();mt()});var L,gt=u(()=>{"use strict";E();L=class{async createSyncPackage(e,t,r){let n=await f(),{deriveEncryptionKeyFromWebAuthn:o,encryptData:i}=await Promise.resolve().then(()=>(ue(),xe)),c=await o(t,r),a=await i(e,c),l=this.detectSyncMethod();return{id:crypto.randomUUID(),encryptedData:a,deviceFingerprints:[n],syncMethod:l,version:1,updatedAt:Date.now()}}detectSyncMethod(){let e=navigator.userAgent.toLowerCase();return e.includes("mac")||e.includes("iphone")||e.includes("ipad")?"icloud":e.includes("android")||e.includes("chrome")?"google":e.includes("windows")?"microsoft":"custom"}async restoreFromSync(e,t,r){let{deriveEncryptionKeyFromWebAuthn:n,decryptData:o}=await Promise.resolve().then(()=>(ue(),xe)),i=await n(t,r),c=await o(e.encryptedData,i),a=await f();return e.deviceFingerprints.includes(a)||(e.deviceFingerprints.push(a),e.updatedAt=Date.now()),c}async getSetupFlow(){return{success:!1,steps:[{title:"1. Authenticate on New Device",action:"Use Touch ID/Face ID",educational:"Your passkey is automatically synced via iCloud/Google",status:"waiting"},{title:"2. Decrypt Wallet Data",action:"System validates device",educational:"Only your trusted devices can decrypt the wallet",status:"waiting"},{title:"3. Verify Recovery",action:"Check partial address",educational:"Confirm address matches your wallet",status:"waiting"},{title:"4. Ready!",action:"Wallet synced",educational:"All devices now have access",status:"waiting"}]}}getSyncExplainer(){return`
237
+ `}async recoverFromGuardians(e){let t=this.getSocialRecoveryConfig();if(!t)throw new Error("Social recovery not configured");if(e.length<t.threshold)throw new Error(`Need at least ${t.threshold} shares, got ${e.length}`);let n=e.map(l=>{let p=JSON.parse(l);return{guardianId:p.guardianId,share:p.share,index:p.guardianIndex}}).map(l=>Ye(l.share)),o=Le(n,t.threshold),i=Ge(o),{Wallet:a}=await import("ethers"),c=a.fromPhrase(i);if(c.address.toLowerCase()!==t.ethereumAddress.toLowerCase())throw new Error("Recovered address does not match - invalid shares");return{mnemonic:i,ethereumAddress:c.address}}getRecoveryProgress(e){let t=this.getSocialRecoveryConfig();if(!t)throw new Error("Social recovery not configured");let r=new Set(e.map(n=>{try{return JSON.parse(n).guardianId}catch{return null}}).filter(Boolean));return{collected:r.size,required:t.threshold,guardians:t.guardians.map(n=>({id:n.id,name:n.name,hasProvided:r.has(n.id)})),canRecover:r.size>=t.threshold}}markGuardianVerified(e){let t=this.getSocialRecoveryConfig();if(!t)throw new Error("Social recovery not configured");let r=t.guardians.find(n=>n.id===e);if(!r)throw new Error("Guardian not found");r.status="active",r.lastVerified=Date.now(),this.setItem(this.storageKey,JSON.stringify(t))}revokeGuardian(e){let t=this.getSocialRecoveryConfig();if(!t)throw new Error("Social recovery not configured");let r=t.guardians.find(n=>n.id===e);if(!r)throw new Error("Guardian not found");r.status="revoked",this.setItem(this.storageKey,JSON.stringify(t))}async addGuardian(e,t){let r=this.getSocialRecoveryConfig();if(!r)throw new Error("Social recovery not configured");let n=[...r.guardians.filter(i=>i.status!=="revoked").map(i=>({name:i.name,email:i.email,phone:i.phone})),t],o=await this.setupSocialRecovery(e,r.ethereumAddress,n,r.threshold);return o[o.length-1]}}});var wt=u(()=>{"use strict"});var ke={};S(ke,{SocialRecoveryManager:()=>G,bytesToHex:()=>$e,bytesToString:()=>Ge,combineShares:()=>Le,hexToBytes:()=>Ye,splitSecret:()=>Ne,stringToBytes:()=>qe});var ee=u(()=>{"use strict";ft();He();wt()});var $,vt=u(()=>{"use strict";E();$=class{async createSyncPackage(e,t,r){let n=await f(),{deriveEncryptionKeyFromWebAuthn:o,encryptData:i}=await Promise.resolve().then(()=>(ye(),Te)),a=await o(t,r),c=await i(e,a),l=this.detectSyncMethod();return{id:crypto.randomUUID(),encryptedData:c,deviceFingerprints:[n],syncMethod:l,version:1,updatedAt:Date.now()}}detectSyncMethod(){let e=navigator.userAgent.toLowerCase();return e.includes("mac")||e.includes("iphone")||e.includes("ipad")?"icloud":e.includes("android")||e.includes("chrome")?"google":e.includes("windows")?"microsoft":"custom"}async restoreFromSync(e,t,r){let{deriveEncryptionKeyFromWebAuthn:n,decryptData:o}=await Promise.resolve().then(()=>(ye(),Te)),i=await n(t,r),a=await o(e.encryptedData,i),c=await f();return e.deviceFingerprints.includes(c)||(e.deviceFingerprints.push(c),e.updatedAt=Date.now()),a}async getSetupFlow(){return{success:!1,steps:[{title:"1. Authenticate on New Device",action:"Use Touch ID/Face ID",educational:"Your passkey is automatically synced via iCloud/Google",status:"waiting"},{title:"2. Decrypt Wallet Data",action:"System validates device",educational:"Only your trusted devices can decrypt the wallet",status:"waiting"},{title:"3. Verify Recovery",action:"Check partial address",educational:"Confirm address matches your wallet",status:"waiting"},{title:"4. Ready!",action:"Wallet synced",educational:"All devices now have access",status:"waiting"}]}}getSyncExplainer(){return`
238
238
  HOW CROSS-DEVICE SYNC WORKS
239
239
  ===========================
240
240
 
@@ -315,14 +315,14 @@ If passkey doesn't sync:
315
315
  Think of it like:
316
316
  \u{1F511} Passkey = Your car key (syncs via keychain)
317
317
  \u{1F697} Wallet = Your car (locked, needs key to start)
318
- `}}});var q,ft=u(()=>{"use strict";E();q=class{constructor(){this.storageKey="w3pk_devices"}async registerDevice(){let e={id:await f(),name:this.getDeviceName(),platform:this.detectPlatform(),lastActive:Date.now(),trusted:!0,canRevoke:!1},t=await this.getDevices(),r=t.find(n=>n.id===e.id);return r?(r.lastActive=Date.now(),localStorage.setItem(this.storageKey,JSON.stringify(t))):(t.push(e),localStorage.setItem(this.storageKey,JSON.stringify(t))),e}async getDevices(){let e=localStorage.getItem(this.storageKey);if(!e)return[];try{return JSON.parse(e)}catch{return[]}}async getSyncStatus(){let e=await this.getDevices(),t=await f();e.forEach(o=>{o.canRevoke=o.id!==t}),e.sort((o,i)=>i.lastActive-o.lastActive);let r=this.detectPlatform(),n=e.length>1?Math.max(...e.map(o=>o.lastActive)):void 0;return{enabled:e.length>1,devices:e,lastSyncTime:n,platform:this.getPlatformName(r)}}async revokeDevice(e){let t=await this.getDevices(),r=await f();if(e===r)throw new Error("Cannot revoke current device");let n=t.filter(o=>o.id!==e);localStorage.setItem(this.storageKey,JSON.stringify(n))}async updateLastActive(){let e=await this.getDevices(),t=await f(),r=e.find(n=>n.id===t);r&&(r.lastActive=Date.now(),localStorage.setItem(this.storageKey,JSON.stringify(e)))}getDeviceName(){let e=this.detectPlatform(),t=navigator.userAgent;if(e==="ios")return t.includes("iPhone")?"iPhone":t.includes("iPad")?"iPad":t.includes("iPod")?"iPod":"iOS Device";if(e==="android"){let r=t.match(/Android.*;\s([^)]+)\)/);return r?r[1]:"Android Device"}return e==="macos"?"Mac":e==="windows"?"Windows PC":e==="linux"?"Linux PC":"Unknown Device"}detectPlatform(){let e=navigator.userAgent.toLowerCase();return e.includes("iphone")||e.includes("ipad")||e.includes("ipod")?"ios":e.includes("android")?"android":e.includes("mac")?"macos":e.includes("windows")?"windows":e.includes("linux")?"linux":"unknown"}getPlatformName(e){switch(e){case"ios":return"iOS (iCloud Keychain)";case"android":return"Android (Google)";case"macos":return"macOS (iCloud Keychain)";case"windows":return"Windows (Microsoft)";case"linux":return"Linux";default:return"Unknown"}}async getDeviceListFormatted(){let e=await this.getSyncStatus();if(e.devices.length===0)return"No devices registered";let t=`Your Devices (${e.devices.length}):
318
+ `}}});var Y,bt=u(()=>{"use strict";E();Y=class{constructor(){this.storageKey="w3pk_devices"}async registerDevice(){let e={id:await f(),name:this.getDeviceName(),platform:this.detectPlatform(),lastActive:Date.now(),trusted:!0,canRevoke:!1},t=await this.getDevices(),r=t.find(n=>n.id===e.id);return r?(r.lastActive=Date.now(),localStorage.setItem(this.storageKey,JSON.stringify(t))):(t.push(e),localStorage.setItem(this.storageKey,JSON.stringify(t))),e}async getDevices(){let e=localStorage.getItem(this.storageKey);if(!e)return[];try{return JSON.parse(e)}catch{return[]}}async getSyncStatus(){let e=await this.getDevices(),t=await f();e.forEach(o=>{o.canRevoke=o.id!==t}),e.sort((o,i)=>i.lastActive-o.lastActive);let r=this.detectPlatform(),n=e.length>1?Math.max(...e.map(o=>o.lastActive)):void 0;return{enabled:e.length>1,devices:e,lastSyncTime:n,platform:this.getPlatformName(r)}}async revokeDevice(e){let t=await this.getDevices(),r=await f();if(e===r)throw new Error("Cannot revoke current device");let n=t.filter(o=>o.id!==e);localStorage.setItem(this.storageKey,JSON.stringify(n))}async updateLastActive(){let e=await this.getDevices(),t=await f(),r=e.find(n=>n.id===t);r&&(r.lastActive=Date.now(),localStorage.setItem(this.storageKey,JSON.stringify(e)))}getDeviceName(){let e=this.detectPlatform(),t=navigator.userAgent;if(e==="ios")return t.includes("iPhone")?"iPhone":t.includes("iPad")?"iPad":t.includes("iPod")?"iPod":"iOS Device";if(e==="android"){let r=t.match(/Android.*;\s([^)]+)\)/);return r?r[1]:"Android Device"}return e==="macos"?"Mac":e==="windows"?"Windows PC":e==="linux"?"Linux PC":"Unknown Device"}detectPlatform(){let e=navigator.userAgent.toLowerCase();return e.includes("iphone")||e.includes("ipad")||e.includes("ipod")?"ios":e.includes("android")?"android":e.includes("mac")?"macos":e.includes("windows")?"windows":e.includes("linux")?"linux":"unknown"}getPlatformName(e){switch(e){case"ios":return"iOS (iCloud Keychain)";case"android":return"Android (Google)";case"macos":return"macOS (iCloud Keychain)";case"windows":return"Windows (Microsoft)";case"linux":return"Linux";default:return"Unknown"}}async getDeviceListFormatted(){let e=await this.getSyncStatus();if(e.devices.length===0)return"No devices registered";let t=`Your Devices (${e.devices.length}):
319
319
 
320
320
  `;return e.devices.forEach((r,n)=>{let o=Date.now()-r.lastActive,i=this.formatTimeDiff(o);t+=`${n+1}. ${r.name}
321
321
  `,t+=` Platform: ${this.getPlatformName(r.platform)}
322
322
  `,t+=` Last active: ${i}
323
323
  `,t+=` ${r.canRevoke?"":"(Current device)"}
324
324
 
325
- `}),t}formatTimeDiff(e){let t=Math.floor(e/1e3),r=Math.floor(t/60),n=Math.floor(r/60),o=Math.floor(n/24);return o>0?`${o} day${o>1?"s":""} ago`:n>0?`${n} hour${n>1?"s":""} ago`:r>0?`${r} minute${r>1?"s":""} ago`:"just now"}}});var G,wt=u(()=>{"use strict";G=class{async detectSyncCapabilities(){let e=this.detectPlatform(),t=await this.checkPasskeySync(),r=this.estimateDeviceCount();return{passkeysSync:t,platform:e,estimatedDevices:r,syncEnabled:t&&e!=="none"}}detectPlatform(){let e=navigator.userAgent.toLowerCase();return e.includes("mac")||e.includes("iphone")||e.includes("ipad")||e.includes("ipod")?"apple":e.includes("android")?"google":e.includes("windows")?"microsoft":"none"}async checkPasskeySync(){if(!window.PublicKeyCredential)return!1;try{return await PublicKeyCredential.isUserVerifyingPlatformAuthenticatorAvailable()}catch{return!1}}estimateDeviceCount(){return 1}getPlatformEducation(e){switch(e){case"apple":return`
325
+ `}),t}formatTimeDiff(e){let t=Math.floor(e/1e3),r=Math.floor(t/60),n=Math.floor(r/60),o=Math.floor(n/24);return o>0?`${o} day${o>1?"s":""} ago`:n>0?`${n} hour${n>1?"s":""} ago`:r>0?`${r} minute${r>1?"s":""} ago`:"just now"}}});var H,St=u(()=>{"use strict";H=class{async detectSyncCapabilities(){let e=this.detectPlatform(),t=await this.checkPasskeySync(),r=this.estimateDeviceCount();return{passkeysSync:t,platform:e,estimatedDevices:r,syncEnabled:t&&e!=="none"}}detectPlatform(){let e=navigator.userAgent.toLowerCase();return e.includes("mac")||e.includes("iphone")||e.includes("ipad")||e.includes("ipod")?"apple":e.includes("android")?"google":e.includes("windows")?"microsoft":"none"}async checkPasskeySync(){if(!window.PublicKeyCredential)return!1;try{return await PublicKeyCredential.isUserVerifyingPlatformAuthenticatorAvailable()}catch{return!1}}estimateDeviceCount(){return 1}getPlatformEducation(e){switch(e){case"apple":return`
326
326
  \u{1F34E} Apple iCloud Keychain
327
327
 
328
328
  Your passkey automatically syncs across:
@@ -401,7 +401,7 @@ This ensures you can recover if:
401
401
  - Device is lost/stolen
402
402
  - Device is damaged
403
403
  - You switch devices
404
- `}}getSyncInstructions(e){switch(e){case"apple":return["Open Settings on your iPhone/iPad/Mac","Tap your name at the top",'Tap "iCloud"','Enable "Keychain"','Enable "iCloud Backup" (recommended)'];case"google":return["Open Chrome Settings",'Click "You and Google"','Enable "Sync"','Ensure "Passwords" is checked',"Sign in on other devices with same Google account"];case"microsoft":return["Windows Hello sync is limited","Consider using:","- Encrypted ZIP backup","- Social recovery","- Cloud backup (password-protected)"];case"none":return["Platform sync not available","Use alternative backup methods:","- Create encrypted ZIP backup","- Set up social recovery","- Save recovery phrase securely"]}}}});var vt=u(()=>{"use strict"});var $e={};S($e,{DeviceManager:()=>q,PlatformDetector:()=>G,VaultSync:()=>L});var be=u(()=>{"use strict";gt();ft();wt();vt()});var $,bt=u(()=>{"use strict";$=class{getScenarios(){return[{type:"lost-device",description:"Your phone fell in the ocean"},{type:"lost-phrase",description:"Your paper backup burned in a fire"},{type:"lost-both",description:"Phone stolen AND forgot recovery phrase"},{type:"switch-platform",description:"Switching from iPhone to Android"}]}async simulateScenario(e,t){let r=[];switch(e.type){case"lost-device":t.passkeySync.enabled&&t.passkeySync.deviceCount>1&&r.push({method:`Passkey Sync (${t.passkeySync.platform})`,success:!0,time:"5 minutes",requirements:["Sign in to cloud account on new device","Authenticate with biometric/PIN"]}),t.recoveryPhrase.encryptedBackups.length>0&&t.recoveryPhrase.encryptedBackups.forEach(i=>{r.push({method:`Encrypted ${i.method.toUpperCase()} Backup`,success:!0,time:"2 minutes",requirements:["Backup file/QR code","Backup password"]})}),t.socialRecovery?.enabled&&r.push({method:"Social Recovery",success:!0,time:"24 hours",requirements:[`Contact ${t.socialRecovery.threshold} guardians`,"Collect shares from guardians","Verify identity with each guardian"]});break;case"lost-phrase":t.passkeySync.enabled&&r.push({method:"Passkey (current device)",success:!0,time:"Instant",requirements:["Access to current device","Biometric/PIN authentication"]}),t.passkeySync.deviceCount>1&&r.push({method:"Passkey Sync",success:!0,time:"5 minutes",requirements:["Any synced device","Biometric authentication"]}),t.recoveryPhrase.encryptedBackups.length>0&&r.push({method:"Encrypted Backup",success:!0,time:"2 minutes",requirements:["Backup file","Password"]}),t.socialRecovery?.enabled&&r.push({method:"Social Recovery",success:!0,time:"24 hours",requirements:[`${t.socialRecovery.threshold} guardian shares`]});break;case"lost-both":t.passkeySync.deviceCount>1&&r.push({method:"Passkey Sync",success:!0,time:"5 minutes",requirements:["Cloud account access","New device","Biometric setup"]}),t.socialRecovery?.enabled&&r.push({method:"Social Recovery",success:!0,time:"24 hours",requirements:[`${t.socialRecovery.threshold} guardian shares`,"Identity verification with guardians"]});break;case"switch-platform":t.recoveryPhrase.encryptedBackups.length>0&&r.push({method:"Encrypted Backup",success:!0,time:"2 minutes",requirements:["Backup file","Password"]}),t.socialRecovery?.enabled&&r.push({method:"Social Recovery",success:!0,time:"24 hours",requirements:[`${t.socialRecovery.threshold} guardian shares`]});break}let n=r.length>0,o=this.getEducationalNote(e,r,t);return{scenario:e,success:n,availableMethods:r,timeEstimate:n?this.estimateFastestRecovery(r):"Cannot recover",educationalNote:o}}estimateFastestRecovery(e){let t=e.map(r=>r.time.toLowerCase());if(t.some(r=>r.includes("instant")))return"Instant";if(t.some(r=>r.includes("minute"))){let r=t.filter(n=>n.includes("minute")).map(n=>parseInt(n));return`${Math.min(...r)} minutes`}return t.some(r=>r.includes("hour"))?"24 hours":"Unknown"}getEducationalNote(e,t,r){if(t.length===0)return`
404
+ `}}getSyncInstructions(e){switch(e){case"apple":return["Open Settings on your iPhone/iPad/Mac","Tap your name at the top",'Tap "iCloud"','Enable "Keychain"','Enable "iCloud Backup" (recommended)'];case"google":return["Open Chrome Settings",'Click "You and Google"','Enable "Sync"','Ensure "Passwords" is checked',"Sign in on other devices with same Google account"];case"microsoft":return["Windows Hello sync is limited","Consider using:","- Encrypted ZIP backup","- Social recovery","- Cloud backup (password-protected)"];case"none":return["Platform sync not available","Use alternative backup methods:","- Create encrypted ZIP backup","- Set up social recovery","- Save recovery phrase securely"]}}}});var kt=u(()=>{"use strict"});var _e={};S(_e,{DeviceManager:()=>Y,PlatformDetector:()=>H,VaultSync:()=>$});var Ae=u(()=>{"use strict";vt();bt();St();kt()});var _,At=u(()=>{"use strict";_=class{getScenarios(){return[{type:"lost-device",description:"Your phone fell in the ocean"},{type:"lost-phrase",description:"Your paper backup burned in a fire"},{type:"lost-both",description:"Phone stolen AND forgot recovery phrase"},{type:"switch-platform",description:"Switching from iPhone to Android"}]}async simulateScenario(e,t){let r=[];switch(e.type){case"lost-device":t.passkeySync.enabled&&t.passkeySync.deviceCount>1&&r.push({method:`Passkey Sync (${t.passkeySync.platform})`,success:!0,time:"5 minutes",requirements:["Sign in to cloud account on new device","Authenticate with biometric/PIN"]}),t.recoveryPhrase.encryptedBackups.length>0&&t.recoveryPhrase.encryptedBackups.forEach(i=>{r.push({method:`Encrypted ${i.method.toUpperCase()} Backup`,success:!0,time:"2 minutes",requirements:["Backup file/QR code","Backup password"]})}),t.socialRecovery?.enabled&&r.push({method:"Social Recovery",success:!0,time:"24 hours",requirements:[`Contact ${t.socialRecovery.threshold} guardians`,"Collect shares from guardians","Verify identity with each guardian"]});break;case"lost-phrase":t.passkeySync.enabled&&r.push({method:"Passkey (current device)",success:!0,time:"Instant",requirements:["Access to current device","Biometric/PIN authentication"]}),t.passkeySync.deviceCount>1&&r.push({method:"Passkey Sync",success:!0,time:"5 minutes",requirements:["Any synced device","Biometric authentication"]}),t.recoveryPhrase.encryptedBackups.length>0&&r.push({method:"Encrypted Backup",success:!0,time:"2 minutes",requirements:["Backup file","Password"]}),t.socialRecovery?.enabled&&r.push({method:"Social Recovery",success:!0,time:"24 hours",requirements:[`${t.socialRecovery.threshold} guardian shares`]});break;case"lost-both":t.passkeySync.deviceCount>1&&r.push({method:"Passkey Sync",success:!0,time:"5 minutes",requirements:["Cloud account access","New device","Biometric setup"]}),t.socialRecovery?.enabled&&r.push({method:"Social Recovery",success:!0,time:"24 hours",requirements:[`${t.socialRecovery.threshold} guardian shares`,"Identity verification with guardians"]});break;case"switch-platform":t.recoveryPhrase.encryptedBackups.length>0&&r.push({method:"Encrypted Backup",success:!0,time:"2 minutes",requirements:["Backup file","Password"]}),t.socialRecovery?.enabled&&r.push({method:"Social Recovery",success:!0,time:"24 hours",requirements:[`${t.socialRecovery.threshold} guardian shares`]});break}let n=r.length>0,o=this.getEducationalNote(e,r,t);return{scenario:e,success:n,availableMethods:r,timeEstimate:n?this.estimateFastestRecovery(r):"Cannot recover",educationalNote:o}}estimateFastestRecovery(e){let t=e.map(r=>r.time.toLowerCase());if(t.some(r=>r.includes("instant")))return"Instant";if(t.some(r=>r.includes("minute"))){let r=t.filter(n=>n.includes("minute")).map(n=>parseInt(n));return`${Math.min(...r)} minutes`}return t.some(r=>r.includes("hour"))?"24 hours":"Unknown"}getEducationalNote(e,t,r){if(t.length===0)return`
405
405
  \u274C WALLET CANNOT BE RECOVERED
406
406
 
407
407
  Scenario: ${e.description}
@@ -445,7 +445,7 @@ Scenario: ${e.description}
445
445
  `,t.forEach((o,i)=>{n+=`${i+1}. ${o.method}
446
446
  `,n+=` \u23F1 Time: ~${o.time}
447
447
  `,n+=` Requirements:
448
- `,o.requirements.forEach(c=>{n+=` - ${c}
448
+ `,o.requirements.forEach(a=>{n+=` - ${a}
449
449
  `}),n+=`
450
450
  `}),n+=`
451
451
  RECOMMENDATIONS:
@@ -457,7 +457,7 @@ RECOMMENDATIONS:
457
457
  `,r.socialRecovery?.enabled||(n+=` Consider adding social recovery for maximum security.
458
458
  `)):(n+=`\u{1F7E2} Excellent! You have ${t.length} recovery methods.
459
459
  `,n+=` Your wallet is well-protected!
460
- `),n}async runInteractiveTest(e){let t=this.getScenarios(),r=[];for(let c of t){let a=await this.simulateScenario(c,e);r.push(a)}let n=r.filter(c=>c.success).length,o=n/t.length*100,i="";return o===100?i=`\u{1F3C6} PERFECT SCORE!
460
+ `),n}async runInteractiveTest(e){let t=this.getScenarios(),r=[];for(let a of t){let c=await this.simulateScenario(a,e);r.push(c)}let n=r.filter(a=>a.success).length,o=n/t.length*100,i="";return o===100?i=`\u{1F3C6} PERFECT SCORE!
461
461
 
462
462
  You can recover in ALL scenarios.
463
463
  Your wallet is extremely well-protected!`:o>=75?i=`\u{1F7E2} GREAT JOB!
@@ -469,7 +469,7 @@ You can recover in ${n}/${t.length} scenarios.
469
469
  Add more backup methods to improve security.`:i=`\u26A0\uFE0F AT RISK!
470
470
 
471
471
  You can only recover in ${n}/${t.length} scenarios.
472
- Urgently add backup methods to protect your wallet!`,{scenarios:r,overallScore:o,feedback:i}}}});function Ye(s){return Se[s]||null}function He(){return Object.keys(Se)}function _e(s){let e=s.toLowerCase();return Object.values(Se).filter(t=>t.title.toLowerCase().includes(e)||t.content.toLowerCase().includes(e))}var Se,St=u(()=>{"use strict";Se={whatIsPasskey:{title:"What is a Passkey?",content:`
472
+ Urgently add backup methods to protect your wallet!`,{scenarios:r,overallScore:o,feedback:i}}}});function Ve(s){return Ee[s]||null}function Qe(){return Object.keys(Ee)}function je(s){let e=s.toLowerCase();return Object.values(Ee).filter(t=>t.title.toLowerCase().includes(e)||t.content.toLowerCase().includes(e))}var Ee,Et=u(()=>{"use strict";Ee={whatIsPasskey:{title:"What is a Passkey?",content:`
473
473
  Think of a passkey like your house smart lock:
474
474
 
475
475
  \u{1F511} Traditional Key (Password):
@@ -773,5 +773,5 @@ STORAGE OPTIONS:
773
773
  - Email to yourself
774
774
 
775
775
  The encryption makes it safe even in cloud!
776
- `}}});var ke={};S(ke,{RecoverySimulator:()=>$,educationalModules:()=>Se,getAllTopics:()=>He,getExplainer:()=>Ye,searchExplainers:()=>_e});var z=u(()=>{"use strict";bt();St()});var Xt={};S(Xt,{ApiError:()=>X,AuthenticationError:()=>k,BackupManager:()=>U,BackupStorage:()=>A,CryptoError:()=>y,DeviceManager:()=>q,PlatformDetector:()=>G,RecoverySimulator:()=>$,RegistrationError:()=>T,SocialRecoveryManager:()=>N,StealthAddressModule:()=>F,StorageError:()=>h,VaultSync:()=>L,WalletError:()=>d,Web3Passkey:()=>Y,Web3PasskeyError:()=>g,assertEthereumAddress:()=>ee,assertMnemonic:()=>je,assertUsername:()=>te,canControlStealthAddress:()=>it,checkStealthAddress:()=>Q,computeStealthPrivateKey:()=>he,createWalletFromMnemonic:()=>et,createWeb3Passkey:()=>kt,default:()=>Zt,deriveStealthKeys:()=>D,deriveWalletFromMnemonic:()=>ce,generateBIP39Wallet:()=>ae,generateStealthAddress:()=>pe,getAllTopics:()=>He,getExplainer:()=>Ye,isStrongPassword:()=>Je,searchExplainers:()=>_e,validateEthereumAddress:()=>Pe,validateMnemonic:()=>Re,validateUsername:()=>Ce});module.exports=Dt(Xt);var ze=require("@simplewebauthn/browser");w();function Pe(s){return/^0x[a-fA-F0-9]{40}$/.test(s)}function Ce(s){return s.length>=3&&s.length<=50}function Re(s){let e=s.trim().split(/\s+/);return e.length===12||e.length===24}function ee(s){if(!Pe(s))throw new Error("Invalid Ethereum address format")}function te(s){if(!Ce(s))throw new Error("Username must be between 3 and 50 characters")}function je(s){if(!Re(s))throw new Error("Invalid mnemonic: must be 12 or 24 words")}function Je(s){if(s.length<12)return!1;let e=/[A-Z]/.test(s),t=/[a-z]/.test(s),r=/[0-9]/.test(s),n=/[!@#$%^&*()_+\-=\[\]{};':"\\|,.<>\/?]/.test(s);return!(!e||!t||!r||!n||["password","12345678","qwerty","abc123","password123","admin","letmein"].some(i=>s.toLowerCase().includes(i)))}R();function Ft(){let s=new Uint8Array(32);return crypto.getRandomValues(s),btoa(String.fromCharCode(...s)).replace(/\+/g,"-").replace(/\//g,"_").replace(/=/g,"")}async function Ze(s){try{let{username:e,ethereumAddress:t}=s;te(e),ee(t);let r=new C;if(r.userExists(e))throw new Error("Username already registered");let o={challenge:Ft(),rp:{name:"w3pk",id:window.location.hostname},user:{id:e,name:e,displayName:e},pubKeyCredParams:[{type:"public-key",alg:-7},{type:"public-key",alg:-257}],authenticatorSelection:{authenticatorAttachment:"platform",userVerification:"required",residentKey:"required",requireResidentKey:!0},timeout:6e4,attestation:"none"},i=await(0,ze.startRegistration)({optionsJSON:o}),c=i.response.publicKey;if(!c)throw new Error("Public key not returned from authenticator");r.saveCredential({id:i.id,publicKey:c,username:e,ethereumAddress:t,createdAt:Date.now(),lastUsed:Date.now()}),console.log("[register] Credential response:",i.response);let a=i.response.attestationObject;if(console.log("[register] Attestation object:",a),!a)throw new Error("Attestation object not returned from authenticator");let l=Mt(a);return console.log("[register] Attestation buffer length:",l.byteLength),{signature:l}}catch(e){throw new T(e instanceof Error?e.message:"Registration failed",e)}}function Mt(s){let e=s.replace(/-/g,"+").replace(/_/g,"/"),t=atob(e),r=new Uint8Array(t.length);for(let n=0;n<t.length;n++)r[n]=t.charCodeAt(n);return r.buffer}var Xe=require("@simplewebauthn/browser");w();R();function Kt(){let s=new Uint8Array(32);return crypto.getRandomValues(s),btoa(String.fromCharCode(...s)).replace(/\+/g,"-").replace(/\//g,"_").replace(/=/g,"")}async function oe(){try{let s=new C,t={challenge:Kt(),rpId:window.location.hostname,userVerification:"required",timeout:6e4},r=await(0,Xe.startAuthentication)({optionsJSON:t}),n=s.getCredentialById(r.id);if(!n)throw new Error("Credential not found");if(!await Ot(r,n))throw new Error("Signature verification failed");s.updateLastUsed(n.id);let i=se(r.response.signature);return{verified:!0,user:{username:n.username,ethereumAddress:n.ethereumAddress,credentialId:n.id},signature:i}}catch(s){throw new k(s instanceof Error?s.message:"Authentication failed",s)}}async function Ot(s,e){try{let t=se(e.publicKey),r=await crypto.subtle.importKey("spki",t,{name:"ECDSA",namedCurve:"P-256"},!1,["verify"]),n=se(s.response.authenticatorData),o=s.response.clientDataJSON,i;o.startsWith("eyJ")?i=atob(o.replace(/-/g,"+").replace(/_/g,"/")):i=o;let c=await crypto.subtle.digest("SHA-256",new TextEncoder().encode(i)),a=new Uint8Array(n.byteLength+c.byteLength);a.set(new Uint8Array(n),0),a.set(new Uint8Array(c),n.byteLength);let l=se(s.response.signature),p=Ut(new Uint8Array(l));return await crypto.subtle.verify({name:"ECDSA",hash:"SHA-256"},r,p,a)}catch(t){return console.error("Signature verification error:",t),!1}}function se(s){let e=s.replace(/-/g,"+").replace(/_/g,"/"),t=atob(e),r=new Uint8Array(t.length);for(let n=0;n<t.length;n++)r[n]=t.charCodeAt(n);return r.buffer}function Ut(s){let e=2;e++;let t=s[e++];t>32&&(e++,t--);let r=s.slice(e,e+t);e+=t,e++;let n=s[e++];n>32&&(e++,n--);let o=s.slice(e,e+n),i=new Uint8Array(64);return i.set(r,32-r.length),i.set(o,64-o.length),i.buffer}w();var Wt="Web3PasskeyWallet",Nt=1,v="wallets",ie=class{constructor(){this.db=null}async init(){return new Promise((e,t)=>{let r=indexedDB.open(Wt,Nt);r.onerror=()=>t(new h("Failed to open database",r.error)),r.onsuccess=()=>{this.db=r.result,e()},r.onupgradeneeded=()=>{let n=r.result;n.objectStoreNames.contains(v)||n.createObjectStore(v,{keyPath:"ethereumAddress"})}})}async store(e){return this.db||await this.init(),new Promise((t,r)=>{let i=this.db.transaction([v],"readwrite").objectStore(v).put(e);i.onerror=()=>r(new h("Failed to store wallet data",i.error)),i.onsuccess=()=>t()})}async retrieve(e){return this.db||await this.init(),new Promise((t,r)=>{let i=this.db.transaction([v],"readonly").objectStore(v).get(e);i.onerror=()=>r(new h("Failed to retrieve wallet data",i.error)),i.onsuccess=()=>t(i.result||null)})}async delete(e){return this.db||await this.init(),new Promise((t,r)=>{let i=this.db.transaction([v],"readwrite").objectStore(v).delete(e);i.onerror=()=>r(new h("Failed to delete wallet data",i.error)),i.onsuccess=()=>t()})}async clear(){return this.db||await this.init(),new Promise((e,t)=>{let o=this.db.transaction([v],"readwrite").objectStore(v).clear();o.onerror=()=>t(new h("Failed to clear wallet data",o.error)),o.onsuccess=()=>e()})}};var V=require("ethers");w();function ae(){try{let s=V.ethers.Wallet.createRandom().mnemonic;if(!s)throw new Error("Failed to generate mnemonic");let e=s.phrase;return{address:V.ethers.HDNodeWallet.fromPhrase(e,void 0,"m/44'/60'/0'/0/0").address,mnemonic:e}}catch(s){throw new d("Wallet generation failed",s)}}function et(s){try{if(!s||s.trim().split(/\s+/).length<12)throw new Error("Invalid mnemonic: must be at least 12 words");return V.ethers.HDNodeWallet.fromPhrase(s.trim(),void 0,"m/44'/60'/0'/0/0")}catch(e){throw new d(`Wallet creation failed: ${e instanceof Error?e.message:"Invalid mnemonic"}`,e)}}function ce(s,e=0){try{if(!s||s.trim().split(/\s+/).length<12)throw new Error("Invalid mnemonic: must be at least 12 words");if(e<0||!Number.isInteger(e))throw new Error("Index must be a non-negative integer");let t=`m/44'/60'/0'/0/${e}`,r=V.ethers.HDNodeWallet.fromPhrase(s.trim(),void 0,t);return{address:r.address,privateKey:r.privateKey}}catch(t){throw new d(`HD wallet derivation failed: ${t instanceof Error?t.message:"Unknown error"}`,t)}}ue();w();var m=require("ethers");w();function D(s){try{let e=m.ethers.HDNodeWallet.fromPhrase(s,void 0,"m/44'/60'/1'/0/0"),t=m.ethers.HDNodeWallet.fromPhrase(s,void 0,"m/44'/60'/1'/0/1"),r=t.signingKey.compressedPublicKey,n=e.signingKey.compressedPublicKey,o=r+n.slice(2),i=Yt(e.signingKey.publicKey,t.signingKey.publicKey);return{stealthMetaAddress:o,spendingPubKey:r,viewingPubKey:n,viewingKey:e.privateKey,spendingKey:t.privateKey,metaAddress:i}}catch(e){throw new y("Failed to derive stealth keys",e)}}function pe(s){try{let e="0x"+s.slice(2,68),t="0x"+s.slice(68),r=m.ethers.Wallet.createRandom(),n=r.signingKey.compressedPublicKey,o=Ie(r.privateKey,t),i=m.ethers.keccak256(o),c="0x"+i.slice(2,4),a=st(e,nt(i));return{stealthAddress:ot(a),ephemeralPubKey:n,viewTag:c,ephemeralPubkey:n}}catch(e){throw new y("Failed to generate stealth address",e)}}function Q(s,e,t,r,n){try{let o=Ie(s,t),i=m.ethers.keccak256(o);if(n&&("0x"+i.slice(2,4)).toLowerCase()!==n.toLowerCase())return{isForUser:!1};let c=st(e,nt(i)),a=ot(c);return a.toLowerCase()!==r.toLowerCase()?{isForUser:!1}:{isForUser:!0,stealthAddress:a}}catch{return{isForUser:!1}}}function he(s,e,t){try{let r=Ie(s,t),n=m.ethers.keccak256(r);return $t(e,n)}catch(r){throw new y("Failed to compute stealth private key",r)}}function Ie(s,e){try{return new m.ethers.Wallet(s).signingKey.computeSharedSecret(e)}catch(t){throw new y("Failed to compute shared secret",t)}}function nt(s){try{return new m.ethers.Wallet(s).signingKey.compressedPublicKey}catch(e){throw new y("Failed to multiply generator by scalar",e)}}function st(s,e){try{let t=m.ethers.SigningKey.computePublicKey(s,!1),r=m.ethers.SigningKey.computePublicKey(e,!1),n=BigInt("0x"+t.slice(4,68)),o=BigInt("0x"+t.slice(68)),i=BigInt("0x"+r.slice(4,68)),c=BigInt("0x"+r.slice(68)),a=BigInt("0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFC2F");if(n===i&&o===c){let Et=3n*n*n%a,Pt=2n*o%a,Ee=Et*rt(Pt,a)%a,Ve=(Ee*Ee-2n*n)%a,Ct=(Ee*(n-Ve)-o)%a;return tt((Ve+a)%a,(Ct+a)%a)}let l=((c-o)%a+a)%a,p=((i-n)%a+a)%a,H=l*rt(p,a)%a,Ae=(H*H-n-i)%a,At=(H*(n-Ae)-o)%a;return tt((Ae+a)%a,(At+a)%a)}catch(t){throw new y("Failed to add public keys",t)}}function $t(s,e){try{let t=BigInt("0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141"),r=BigInt(s),n=BigInt(e);return"0x"+((r+n)%t).toString(16).padStart(64,"0")}catch(t){throw new y("Failed to add private keys",t)}}function tt(s,e){return"0x"+(e%2n===0n?"02":"03")+s.toString(16).padStart(64,"0")}function rt(s,e){s=(s%e+e)%e;let[t,r]=[s,e],[n,o]=[1n,0n];for(;r!==0n;){let i=t/r;[t,r]=[r,t-i*r],[n,o]=[o,n-i*o]}return(n%e+e)%e}function ot(s){try{let e=m.ethers.SigningKey.computePublicKey(s,!1),t=m.ethers.keccak256("0x"+e.slice(4));return m.ethers.getAddress("0x"+t.slice(-40))}catch(e){throw new y("Failed to derive address from public key",e)}}function Yt(s,e){let t=m.ethers.solidityPackedKeccak256(["bytes","bytes"],[s,e]);return m.ethers.getAddress("0x"+t.slice(26))}function it(s,e,t,r){let n=new m.ethers.Wallet(e);return Q(s,n.signingKey.compressedPublicKey,t,r).isForUser}var F=class{constructor(e,t){this.getMnemonic=t}async generateStealthAddress(e){try{let t=await this.getMnemonic(e?.requireAuth),r=D(t),n=pe(r.stealthMetaAddress);return{stealthAddress:n.stealthAddress,ephemeralPublicKey:n.ephemeralPubKey,viewTag:n.viewTag}}catch(t){throw new g("Failed to generate stealth address","STEALTH_GENERATION_ERROR",t)}}async parseAnnouncement(e,t){try{let r=await this.getMnemonic(t?.requireAuth),n=D(r),o=Q(n.viewingKey,n.spendingPubKey,e.ephemeralPublicKey,e.stealthAddress,e.viewTag);if(!o.isForUser)return{isForUser:!1};let i=he(n.viewingKey,n.spendingKey,e.ephemeralPublicKey);return{isForUser:!0,stealthAddress:o.stealthAddress,stealthPrivateKey:i}}catch(r){throw new g("Failed to parse announcement","ANNOUNCEMENT_PARSE_ERROR",r)}}async scanAnnouncements(e,t){let r=[];for(let n of e){let o=await this.parseAnnouncement(n,t);o.isForUser&&r.push(o)}return r}async getKeys(e){try{let t=await this.getMnemonic(e?.requireAuth);return D(t)}catch(t){throw new g("Failed to get stealth keys","STEALTH_KEYS_ERROR",t)}}async getStealthMetaAddress(e){try{return(await this.getKeys(e)).stealthMetaAddress}catch(t){throw new g("Failed to get stealth meta-address","STEALTH_META_ADDRESS_ERROR",t)}}get isAvailable(){return!0}};var ye=class{constructor(e=1){this.session=null;this.sessionDuration=e*60*60*1e3}startSession(e,t){let r=Date.now()+this.sessionDuration;this.session={mnemonic:e,expiresAt:r,credentialId:t}}getMnemonic(){return this.session?Date.now()>this.session.expiresAt?(this.clearSession(),null):this.session.mnemonic:null}getCredentialId(){return this.session?Date.now()>this.session.expiresAt?(this.clearSession(),null):this.session.credentialId:null}isActive(){return this.getMnemonic()!==null}getRemainingTime(){return this.session?Date.now()>this.session.expiresAt?(this.clearSession(),0):Math.floor((this.session.expiresAt-Date.now())/1e3):0}extendSession(){if(!this.session)throw new Error("No active session to extend");if(Date.now()>this.session.expiresAt)throw this.clearSession(),new Error("Session expired, cannot extend");this.session.expiresAt=Date.now()+this.sessionDuration}clearSession(){this.session&&(this.session.mnemonic="0".repeat(this.session.mnemonic.length)),this.session=null}setSessionDuration(e){this.sessionDuration=e*60*60*1e3}};var Be={debug:!1,sessionDuration:1,onError:s=>{Be.debug&&console.error("[w3pk]",s)}};w();var at="https://chainid.network/chains.json";var me=null,Ht=[/\$\{[\w_]+\}/i,/\{[\w_]+\}/i,/<[\w_]+>/i,/YOUR[-_]?API[-_]?KEY/i,/INSERT[-_]?API[-_]?KEY/i,/API[-_]?KEY[-_]?HERE/i];function _t(s){return Ht.some(e=>e.test(s))}async function Vt(s=at){let e=await fetch(s);if(!e.ok)throw new Error(`Failed to fetch chains data: ${e.status} ${e.statusText}`);return await e.json()}async function Qt(s){let e=s?.chainsJsonUrl??at,t=s?.cacheDuration??36e5,r=Date.now();if(me&&r-me.timestamp<t)return me.data;let n=await Vt(e);return me={data:n,timestamp:r},n}async function ct(s,e){let r=(await Qt(e)).find(n=>n.chainId===s);return r?r.rpc.filter(n=>!_t(n)&&!n.startsWith("wss://")&&!n.startsWith("ws://")):[]}var jt=new Set([1,10,8453,42161,57073,100,42220,137,42,15,40,41,44,46,47,50,51,56,61,71,82,83,95,97,112,123,130,146,151,153,171,180,183,185,195,215,228,247,248,252,261,267,291,293,311,332,336,395,401,416,466,480,488,510,545,634,647,648,747,831,919,938,945,957,964,970,980,995,997,1001,1003,1024,1030,1114,1125,1135,1149,1188,1284,1285,1287,1300,1301,1315,1337,1338,1339,1424,1514,1687,1727,1729,1740,1750,1829,1868,1946,1961,1962,1969,1989,1995,2017,2020,2031,2043,2109,2241,2340,2345,2440,2522,2559,2649,3068,3109,3338,3502,3799,3888,3889,4e3,4048,4078,4162,4201,4202,4460,4488,4661,4689,4690,4888,5e3,5003,5124,5234,5330,5424,5522,6283,6342,6398,6678,6806,6934,6942,6969,7117,7171,7200,7208,7368,7518,7668,7672,7744,7771,7869,7897,8008,8118,8217,8408,8700,8726,8727,8844,8880,8881,8882,8889,9372,9496,9700,9745,9746,9899,9990,9996,10011,10085,10143,10200,11221,11501,11504,11891,13370,14853,16602,16661,17e3,18880,18881,19991,21e3,21816,21912,25327,32323,33401,34443,41923,42170,43111,44787,47805,48898,48900,49049,49088,5e4,50312,53302,53456,53457,55244,56288,59141,60808,60850,62320,62850,64002,71402,72080,73114,73115,75338,78281,80002,80008,80069,80094,80451,80931,84532,88899,91342,92278,94524,96970,97476,97477,98985,100021,100501,101010,102030,102031,102032,112358,120893,121212,121213,121214,121215,129399,161803,175188,192940,193939,198989,212013,222222,240241,325e3,355110,355113,421614,555777,560048,656476,713715,743111,747474,763373,763375,777777,806582,808813,810180,839999,888991,2019775,2222222,4278608,5734951,6666689,6985385,7080969,7777777,9999999,11142220,11155111,11155420,11155931,16969696,19850818,20180427,20250825,28122024,34949059,37084624,52164803,61022448,79479957,96969696,420420421,420420422,888888888,974399131,999999999,1020352220,1273227453,1313161560,1350216234,1380996178,1417429182,1444673419,1482601649,1564830818,2046399126,11297108099,11297108109,88153591557,123420000220,123420001114]);async function Jt(s,e=1e4){try{let t=new AbortController,r=setTimeout(()=>t.abort(),e),n=await fetch(s,{method:"POST",headers:{"Content-Type":"application/json"},signal:t.signal,body:JSON.stringify({jsonrpc:"2.0",method:"eth_estimateGas",params:[{from:"0xdeadbeef00000000000000000000000000000000",to:"0xdeadbeef00000000000000000000000000000000",data:"0x0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",value:"0x0"},"latest",{"0xdeadbeef00000000000000000000000000000000":{code:"0xef01000000000000000000000000000000000000000001"}}],id:1})});if(clearTimeout(r),!n.ok)return!1;let o=await n.json();if(o.error){let i=(o.error.message||"").toLowerCase();return!["unsupported","not supported","unknown","invalid","unrecognized","does not support","not implemented"].some(a=>i.includes(a))}return o.result!==void 0}catch{return!1}}async function dt(s,e,t){if(jt.has(s))return!0;let r=t?.maxEndpoints||3,n=t?.timeout||1e4;try{let o=await e(s);if(o.length===0)return!1;let i=o.slice(0,r);for(let c of i)if(await Jt(c,n))return!0;return!1}catch{return!1}}var Y=class{constructor(e={}){this.currentUser=null;this.currentWallet=null;this.config={...Be,...e},this.walletStorage=new ie,this.sessionManager=new ye(e.sessionDuration||1),e.stealthAddresses!==void 0&&(this.stealth=new F(e.stealthAddresses,t=>this.getMnemonicFromSession(t)))}async loadZKModule(){if(this.zkModule)return this.zkModule;try{let e=new Function("path","return import(path)"),{ZKProofModule:t}=await e("w3pk/zk"),r=this.config.zkProofs||{};return this.zkModule=new t(r),this.zkModule}catch{throw new Error("ZK module not available. Install dependencies: npm install snarkjs circomlibjs")}}async getMnemonicFromSession(e=!1){if(!e){let l=this.sessionManager.getMnemonic();if(l)return l}if(!this.currentUser)throw new d("Must be authenticated. Call login() first.");let t=await this.walletStorage.retrieve(this.currentUser.ethereumAddress);if(!t)throw new d("No wallet found. Generate a wallet first.");if(!(await oe()).user)throw new d("Authentication failed");let i=new(await Promise.resolve().then(()=>(R(),_))).CredentialStorage().getCredentialById(t.credentialId)?.publicKey,c=await x(t.credentialId,i),a=await le(t.encryptedMnemonic,c);return this.sessionManager.startSession(a,t.credentialId),a}async register(e){try{this.currentWallet?.address||await this.generateWallet();let t=this.currentWallet.address,r=this.currentWallet.mnemonic;await Ze({username:e.username,ethereumAddress:t}),this.currentUser={id:t,username:e.username,displayName:e.username,ethereumAddress:t};let o=new(await Promise.resolve().then(()=>(R(),_))).CredentialStorage().getCredentialByAddress(t);if(!o)throw new d("Credential not found after registration");let i=o.id,c=o.publicKey,a=await x(i,c),l=await de(r,a);return await this.walletStorage.store({ethereumAddress:this.currentUser.ethereumAddress,encryptedMnemonic:l,credentialId:i,createdAt:Date.now()}),this.sessionManager.startSession(r,i),this.currentWallet={address:t,mnemonic:r},this.config.onAuthStateChanged?.(!0,this.currentUser),{address:t,username:e.username}}catch(t){throw this.config.onError?.(t),t}}async login(){try{let e=await oe();if(!e.verified||!e.user)throw new k("Login failed");this.currentUser={id:e.user.ethereumAddress,username:e.user.username,displayName:e.user.username,ethereumAddress:e.user.ethereumAddress};let t=await this.walletStorage.retrieve(this.currentUser.ethereumAddress);if(!t)throw new d("No wallet found for this user. You may need to register first.");let o=new(await Promise.resolve().then(()=>(R(),_))).CredentialStorage().getCredentialById(t.credentialId)?.publicKey,i=await x(t.credentialId,o),c=await le(t.encryptedMnemonic,i);return this.sessionManager.startSession(c,t.credentialId),this.config.onAuthStateChanged?.(!0,this.currentUser),this.currentUser}catch(e){throw this.config.onError?.(e),e}}async logout(){this.currentUser=null,this.currentWallet=null,this.sessionManager.clearSession(),this.config.onAuthStateChanged?.(!1,void 0)}get isAuthenticated(){return this.currentUser!==null}get user(){return this.currentUser}async generateWallet(){try{let e=ae();return this.currentWallet={address:e.address,mnemonic:e.mnemonic},{mnemonic:e.mnemonic}}catch(e){throw this.config.onError?.(e),new d("Failed to generate wallet",e)}}async deriveWallet(e,t){try{if(!this.currentUser)throw new d("Must be authenticated to derive wallet");let r=await this.getMnemonicFromSession(t?.requireAuth),n=ce(r,e);return{address:n.address,privateKey:n.privateKey}}catch(r){throw this.config.onError?.(r),new d("Failed to derive wallet",r)}}async exportMnemonic(e){try{if(!this.currentUser)throw new d("Must be authenticated to export mnemonic");return await this.getMnemonicFromSession(e?.requireAuth)}catch(t){throw this.config.onError?.(t),new d("Failed to export mnemonic",t)}}async importMnemonic(e){try{if(!this.currentUser)throw new d("Must be authenticated to import mnemonic");if(!e||e.trim().split(/\s+/).length<12)throw new d("Invalid mnemonic: must be at least 12 words");let t=await oe();if(!t.user)throw new d("Authentication failed");let r=t.user.credentialId,i=new(await Promise.resolve().then(()=>(R(),_))).CredentialStorage().getCredentialById(r)?.publicKey,c=await x(r,i),a=await de(e.trim(),c);await this.walletStorage.store({ethereumAddress:this.currentUser.ethereumAddress,encryptedMnemonic:a,credentialId:r,createdAt:Date.now()}),this.currentWallet={address:this.currentUser.ethereumAddress,mnemonic:e.trim()},this.sessionManager.startSession(e.trim(),r)}catch(t){throw this.config.onError?.(t),new d("Failed to import mnemonic",t)}}async signMessage(e,t){try{if(!this.currentUser)throw new d("Must be authenticated to sign message");let r=await this.getMnemonicFromSession(t?.requireAuth),{Wallet:n}=await import("ethers");return await n.fromPhrase(r).signMessage(e)}catch(r){throw this.config.onError?.(r),new d("Failed to sign message",r)}}async getEndpoints(e){return ct(e)}async supportsEIP7702(e,t){return dt(e,this.getEndpoints.bind(this),t)}get zk(){return new Proxy({},{get:(e,t)=>async(...r)=>(await this.loadZKModule())[t](...r)})}async getBackupStatus(){if(!this.currentUser)throw new d("Must be authenticated to check backup status");let{BackupManager:e}=await Promise.resolve().then(()=>(I(),W));return new e().getBackupStatus(this.currentUser.ethereumAddress)}async createZipBackup(e,t){if(!this.currentUser)throw new d("Must be authenticated to create backup");let r=await this.getMnemonicFromSession(!0),{BackupManager:n}=await Promise.resolve().then(()=>(I(),W));return new n().createZipBackup(r,this.currentUser.ethereumAddress,{password:e,...t})}async createQRBackup(e,t){if(!this.currentUser)throw new d("Must be authenticated to create backup");let r=await this.getMnemonicFromSession(!0),{BackupManager:n}=await Promise.resolve().then(()=>(I(),W));return new n().createQRBackup(r,this.currentUser.ethereumAddress,{password:e,...t})}async setupSocialRecovery(e,t){if(!this.currentUser)throw new d("Must be authenticated to set up social recovery");let r=await this.getMnemonicFromSession(!0),{SocialRecoveryManager:n}=await Promise.resolve().then(()=>(J(),ve));return new n().setupSocialRecovery(r,this.currentUser.ethereumAddress,e,t)}async generateGuardianInvite(e){let{SocialRecoveryManager:t}=await Promise.resolve().then(()=>(J(),ve)),r=new t,n=r.getSocialRecoveryConfig();if(!n)throw new d("Social recovery not configured");let o=n.guardians.find(i=>i.id===e);if(!o)throw new d("Guardian not found");return r.generateGuardianInvite(o)}async recoverFromGuardians(e){let{SocialRecoveryManager:t}=await Promise.resolve().then(()=>(J(),ve));return new t().recoverFromGuardians(e)}async restoreFromBackup(e,t){let{BackupManager:r}=await Promise.resolve().then(()=>(I(),W));return new r().restoreFromZipBackup(e,t)}async restoreFromQR(e,t){let{BackupManager:r}=await Promise.resolve().then(()=>(I(),W));return new r().restoreFromQR(e,t)}async getSyncStatus(){let{DeviceManager:e}=await Promise.resolve().then(()=>(be(),$e));return new e().getSyncStatus()}async detectSyncCapabilities(){let{PlatformDetector:e}=await Promise.resolve().then(()=>(be(),$e));return new e().detectSyncCapabilities()}async simulateRecoveryScenario(e){if(!this.currentUser)throw new d("Must be authenticated to run recovery simulation");let t=await this.getBackupStatus(),{RecoverySimulator:r}=await Promise.resolve().then(()=>(z(),ke));return new r().simulateScenario(e,t)}async runRecoveryTest(){if(!this.currentUser)throw new d("Must be authenticated to run recovery test");let e=await this.getBackupStatus(),{RecoverySimulator:t}=await Promise.resolve().then(()=>(z(),ke));return new t().runInteractiveTest(e)}async getEducation(e){let{getExplainer:t}=await Promise.resolve().then(()=>(z(),ke)),r=t(e);if(!r)throw new d(`Unknown education topic: ${e}`);return r}hasActiveSession(){return this.sessionManager.isActive()}getSessionRemainingTime(){return this.sessionManager.getRemainingTime()}extendSession(){try{this.sessionManager.extendSession()}catch(e){throw new d("Cannot extend session",e)}}clearSession(){this.sessionManager.clearSession()}setSessionDuration(e){this.sessionManager.setSessionDuration(e)}get version(){return"0.7.2"}};w();I();J();be();z();function kt(s={}){return new Y(s)}var Zt=kt;
776
+ `}}});var Pe={};S(Pe,{RecoverySimulator:()=>_,educationalModules:()=>Ee,getAllTopics:()=>Qe,getExplainer:()=>Ve,searchExplainers:()=>je});var te=u(()=>{"use strict";At();Et()});var tr={};S(tr,{ApiError:()=>ne,AuthenticationError:()=>k,BackupManager:()=>L,BackupStorage:()=>A,CryptoError:()=>y,DeviceManager:()=>Y,PlatformDetector:()=>H,RecoverySimulator:()=>_,RegistrationError:()=>D,SocialRecoveryManager:()=>G,StealthAddressModule:()=>O,StorageError:()=>h,VaultSync:()=>$,WalletError:()=>d,Web3Passkey:()=>V,Web3PasskeyError:()=>g,assertEthereumAddress:()=>se,assertMnemonic:()=>Ze,assertUsername:()=>oe,canControlStealthAddress:()=>dt,checkStealthAddress:()=>Z,computeStealthPrivateKey:()=>ge,createWalletFromMnemonic:()=>nt,createWeb3Passkey:()=>Pt,default:()=>er,deriveStealthKeys:()=>K,deriveWalletFromMnemonic:()=>ue,generateBIP39Wallet:()=>le,generateStealthAddress:()=>me,getAllTopics:()=>Qe,getExplainer:()=>Ve,isStrongPassword:()=>Xe,searchExplainers:()=>je,validateEthereumAddress:()=>xe,validateMnemonic:()=>Be,validateUsername:()=>Ie});module.exports=Kt(tr);var et=require("@simplewebauthn/browser");w();function xe(s){return/^0x[a-fA-F0-9]{40}$/.test(s)}function Ie(s){return s.length>=3&&s.length<=50}function Be(s){let e=s.trim().split(/\s+/);return e.length===12||e.length===24}function se(s){if(!xe(s))throw new Error("Invalid Ethereum address format")}function oe(s){if(!Ie(s))throw new Error("Username must be between 3 and 50 characters")}function Ze(s){if(!Be(s))throw new Error("Invalid mnemonic: must be 12 or 24 words")}function Xe(s){if(s.length<12)return!1;let e=/[A-Z]/.test(s),t=/[a-z]/.test(s),r=/[0-9]/.test(s),n=/[!@#$%^&*()_+\-=\[\]{};':"\\|,.<>\/?]/.test(s);return!(!e||!t||!r||!n||["password","12345678","qwerty","abc123","password123","admin","letmein"].some(i=>s.toLowerCase().includes(i)))}R();J();function Ot(){let s=new Uint8Array(32);return crypto.getRandomValues(s),F(s)}async function tt(s){try{let{username:e,ethereumAddress:t}=s;oe(e),se(t);let r=new C;if(r.userExists(e))throw new Error("Username already registered");let o={challenge:Ot(),rp:{name:"w3pk",id:window.location.hostname},user:{id:e,name:e,displayName:e},pubKeyCredParams:[{type:"public-key",alg:-7},{type:"public-key",alg:-257}],authenticatorSelection:{authenticatorAttachment:"platform",userVerification:"required",residentKey:"required",requireResidentKey:!0},timeout:6e4,attestation:"none"},i=await(0,et.startRegistration)({optionsJSON:o}),a=i.response.publicKey;if(!a)throw new Error("Public key not returned from authenticator");r.saveCredential({id:i.id,publicKey:a,username:e,ethereumAddress:t,createdAt:Date.now(),lastUsed:Date.now()}),console.log("[register] Credential response:",i.response);let c=i.response.attestationObject;if(console.log("[register] Attestation object:",c),!c)throw new Error("Attestation object not returned from authenticator");let l=x(c);return console.log("[register] Attestation buffer length:",l.byteLength),{signature:l}}catch(e){throw new D(e instanceof Error?e.message:"Registration failed",e)}}var rt=require("@simplewebauthn/browser");w();R();J();function Ut(){let s=new Uint8Array(32);return crypto.getRandomValues(s),F(s)}async function ce(){try{let s=new C,t={challenge:Ut(),rpId:window.location.hostname,userVerification:"required",timeout:6e4},r=await(0,rt.startAuthentication)({optionsJSON:t}),n=s.getCredentialById(r.id);if(!n)throw new Error("Credential not found");if(!await Wt(r,n))throw new Error("Signature verification failed");s.updateLastUsed(n.id);let i=x(r.response.signature);return{verified:!0,user:{username:n.username,ethereumAddress:n.ethereumAddress,credentialId:n.id},signature:i}}catch(s){throw new k(s instanceof Error?s.message:"Authentication failed",s)}}async function Wt(s,e){try{let t=x(e.publicKey),r=await crypto.subtle.importKey("spki",t,{name:"ECDSA",namedCurve:"P-256"},!1,["verify"]),n=x(s.response.authenticatorData),o=s.response.clientDataJSON,i;o.startsWith("eyJ")?i=M(o):i=o;let a=await crypto.subtle.digest("SHA-256",new TextEncoder().encode(i)),c=new Uint8Array(n.byteLength+a.byteLength);c.set(new Uint8Array(n),0),c.set(new Uint8Array(a),n.byteLength);let l=x(s.response.signature),p=Nt(new Uint8Array(l));return await crypto.subtle.verify({name:"ECDSA",hash:"SHA-256"},r,p,c)}catch(t){return console.error("Signature verification error:",t),!1}}function Nt(s){let e=2;e++;let t=s[e++];t>32&&(e++,t--);let r=s.slice(e,e+t);e+=t,e++;let n=s[e++];n>32&&(e++,n--);let o=s.slice(e,e+n),i=new Uint8Array(64);return i.set(r,32-r.length),i.set(o,64-o.length),i.buffer}w();var Lt="Web3PasskeyWallet",qt=1,v="wallets",de=class{constructor(){this.db=null}async init(){return new Promise((e,t)=>{let r=indexedDB.open(Lt,qt);r.onerror=()=>t(new h("Failed to open database",r.error)),r.onsuccess=()=>{this.db=r.result,e()},r.onupgradeneeded=()=>{let n=r.result;n.objectStoreNames.contains(v)||n.createObjectStore(v,{keyPath:"ethereumAddress"})}})}async store(e){return this.db||await this.init(),new Promise((t,r)=>{let i=this.db.transaction([v],"readwrite").objectStore(v).put(e);i.onerror=()=>r(new h("Failed to store wallet data",i.error)),i.onsuccess=()=>t()})}async retrieve(e){return this.db||await this.init(),new Promise((t,r)=>{let i=this.db.transaction([v],"readonly").objectStore(v).get(e);i.onerror=()=>r(new h("Failed to retrieve wallet data",i.error)),i.onsuccess=()=>t(i.result||null)})}async delete(e){return this.db||await this.init(),new Promise((t,r)=>{let i=this.db.transaction([v],"readwrite").objectStore(v).delete(e);i.onerror=()=>r(new h("Failed to delete wallet data",i.error)),i.onsuccess=()=>t()})}async clear(){return this.db||await this.init(),new Promise((e,t)=>{let o=this.db.transaction([v],"readwrite").objectStore(v).clear();o.onerror=()=>t(new h("Failed to clear wallet data",o.error)),o.onsuccess=()=>e()})}};var z=require("ethers");w();function le(){try{let s=z.ethers.Wallet.createRandom().mnemonic;if(!s)throw new Error("Failed to generate mnemonic");let e=s.phrase;return{address:z.ethers.HDNodeWallet.fromPhrase(e,void 0,"m/44'/60'/0'/0/0").address,mnemonic:e}}catch(s){throw new d("Wallet generation failed",s)}}function nt(s){try{if(!s||s.trim().split(/\s+/).length<12)throw new Error("Invalid mnemonic: must be at least 12 words");return z.ethers.HDNodeWallet.fromPhrase(s.trim(),void 0,"m/44'/60'/0'/0/0")}catch(e){throw new d(`Wallet creation failed: ${e instanceof Error?e.message:"Invalid mnemonic"}`,e)}}function ue(s,e=0){try{if(!s||s.trim().split(/\s+/).length<12)throw new Error("Invalid mnemonic: must be at least 12 words");if(e<0||!Number.isInteger(e))throw new Error("Index must be a non-negative integer");let t=`m/44'/60'/0'/0/${e}`,r=z.ethers.HDNodeWallet.fromPhrase(s.trim(),void 0,t);return{address:r.address,privateKey:r.privateKey}}catch(t){throw new d(`HD wallet derivation failed: ${t instanceof Error?t.message:"Unknown error"}`,t)}}ye();w();var m=require("ethers");w();function K(s){try{let e=m.ethers.HDNodeWallet.fromPhrase(s,void 0,"m/44'/60'/1'/0/0"),t=m.ethers.HDNodeWallet.fromPhrase(s,void 0,"m/44'/60'/1'/0/1"),r=t.signingKey.compressedPublicKey,n=e.signingKey.compressedPublicKey,o=r+n.slice(2),i=_t(e.signingKey.publicKey,t.signingKey.publicKey);return{stealthMetaAddress:o,spendingPubKey:r,viewingPubKey:n,viewingKey:e.privateKey,spendingKey:t.privateKey,metaAddress:i}}catch(e){throw new y("Failed to derive stealth keys",e)}}function me(s){try{let e="0x"+s.slice(2,68),t="0x"+s.slice(68),r=m.ethers.Wallet.createRandom(),n=r.signingKey.compressedPublicKey,o=De(r.privateKey,t),i=m.ethers.keccak256(o),a="0x"+i.slice(2,4),c=at(e,it(i));return{stealthAddress:ct(c),ephemeralPubKey:n,viewTag:a,ephemeralPubkey:n}}catch(e){throw new y("Failed to generate stealth address",e)}}function Z(s,e,t,r,n){try{let o=De(s,t),i=m.ethers.keccak256(o);if(n&&("0x"+i.slice(2,4)).toLowerCase()!==n.toLowerCase())return{isForUser:!1};let a=at(e,it(i)),c=ct(a);return c.toLowerCase()!==r.toLowerCase()?{isForUser:!1}:{isForUser:!0,stealthAddress:c}}catch{return{isForUser:!1}}}function ge(s,e,t){try{let r=De(s,t),n=m.ethers.keccak256(r);return Ht(e,n)}catch(r){throw new y("Failed to compute stealth private key",r)}}function De(s,e){try{return new m.ethers.Wallet(s).signingKey.computeSharedSecret(e)}catch(t){throw new y("Failed to compute shared secret",t)}}function it(s){try{return new m.ethers.Wallet(s).signingKey.compressedPublicKey}catch(e){throw new y("Failed to multiply generator by scalar",e)}}function at(s,e){try{let t=m.ethers.SigningKey.computePublicKey(s,!1),r=m.ethers.SigningKey.computePublicKey(e,!1),n=BigInt("0x"+t.slice(4,68)),o=BigInt("0x"+t.slice(68)),i=BigInt("0x"+r.slice(4,68)),a=BigInt("0x"+r.slice(68)),c=BigInt("0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFC2F");if(n===i&&o===a){let Rt=3n*n*n%c,xt=2n*o%c,Re=Rt*ot(xt,c)%c,Je=(Re*Re-2n*n)%c,It=(Re*(n-Je)-o)%c;return st((Je+c)%c,(It+c)%c)}let l=((a-o)%c+c)%c,p=((i-n)%c+c)%c,Q=l*ot(p,c)%c,Ce=(Q*Q-n-i)%c,Ct=(Q*(n-Ce)-o)%c;return st((Ce+c)%c,(Ct+c)%c)}catch(t){throw new y("Failed to add public keys",t)}}function Ht(s,e){try{let t=BigInt("0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141"),r=BigInt(s),n=BigInt(e);return"0x"+((r+n)%t).toString(16).padStart(64,"0")}catch(t){throw new y("Failed to add private keys",t)}}function st(s,e){return"0x"+(e%2n===0n?"02":"03")+s.toString(16).padStart(64,"0")}function ot(s,e){s=(s%e+e)%e;let[t,r]=[s,e],[n,o]=[1n,0n];for(;r!==0n;){let i=t/r;[t,r]=[r,t-i*r],[n,o]=[o,n-i*o]}return(n%e+e)%e}function ct(s){try{let e=m.ethers.SigningKey.computePublicKey(s,!1),t=m.ethers.keccak256("0x"+e.slice(4));return m.ethers.getAddress("0x"+t.slice(-40))}catch(e){throw new y("Failed to derive address from public key",e)}}function _t(s,e){let t=m.ethers.solidityPackedKeccak256(["bytes","bytes"],[s,e]);return m.ethers.getAddress("0x"+t.slice(26))}function dt(s,e,t,r){let n=new m.ethers.Wallet(e);return Z(s,n.signingKey.compressedPublicKey,t,r).isForUser}var O=class{constructor(e,t){this.getMnemonic=t}async generateStealthAddress(e){try{let t=await this.getMnemonic(e?.requireAuth),r=K(t),n=me(r.stealthMetaAddress);return{stealthAddress:n.stealthAddress,ephemeralPublicKey:n.ephemeralPubKey,viewTag:n.viewTag}}catch(t){throw new g("Failed to generate stealth address","STEALTH_GENERATION_ERROR",t)}}async parseAnnouncement(e,t){try{let r=await this.getMnemonic(t?.requireAuth),n=K(r),o=Z(n.viewingKey,n.spendingPubKey,e.ephemeralPublicKey,e.stealthAddress,e.viewTag);if(!o.isForUser)return{isForUser:!1};let i=ge(n.viewingKey,n.spendingKey,e.ephemeralPublicKey);return{isForUser:!0,stealthAddress:o.stealthAddress,stealthPrivateKey:i}}catch(r){throw new g("Failed to parse announcement","ANNOUNCEMENT_PARSE_ERROR",r)}}async scanAnnouncements(e,t){let r=[];for(let n of e){let o=await this.parseAnnouncement(n,t);o.isForUser&&r.push(o)}return r}async getKeys(e){try{let t=await this.getMnemonic(e?.requireAuth);return K(t)}catch(t){throw new g("Failed to get stealth keys","STEALTH_KEYS_ERROR",t)}}async getStealthMetaAddress(e){try{return(await this.getKeys(e)).stealthMetaAddress}catch(t){throw new g("Failed to get stealth meta-address","STEALTH_META_ADDRESS_ERROR",t)}}get isAvailable(){return!0}};var fe=class{constructor(e=1){this.session=null;this.sessionDuration=e*60*60*1e3}startSession(e,t){let r=Date.now()+this.sessionDuration;this.session={mnemonic:e,expiresAt:r,credentialId:t}}getMnemonic(){return this.session?Date.now()>this.session.expiresAt?(this.clearSession(),null):this.session.mnemonic:null}getCredentialId(){return this.session?Date.now()>this.session.expiresAt?(this.clearSession(),null):this.session.credentialId:null}isActive(){return this.getMnemonic()!==null}getRemainingTime(){return this.session?Date.now()>this.session.expiresAt?(this.clearSession(),0):Math.floor((this.session.expiresAt-Date.now())/1e3):0}extendSession(){if(!this.session)throw new Error("No active session to extend");if(Date.now()>this.session.expiresAt)throw this.clearSession(),new Error("Session expired, cannot extend");this.session.expiresAt=Date.now()+this.sessionDuration}clearSession(){this.session&&(this.session.mnemonic="0".repeat(this.session.mnemonic.length)),this.session=null}setSessionDuration(e){this.sessionDuration=e*60*60*1e3}};var Fe={debug:!1,sessionDuration:1,onError:s=>{Fe.debug&&console.error("[w3pk]",s)}};w();var lt="https://chainid.network/chains.json";var we=null,Vt=[/\$\{[\w_]+\}/i,/\{[\w_]+\}/i,/<[\w_]+>/i,/YOUR[-_]?API[-_]?KEY/i,/INSERT[-_]?API[-_]?KEY/i,/API[-_]?KEY[-_]?HERE/i];function Qt(s){return Vt.some(e=>e.test(s))}async function jt(s=lt){let e=await fetch(s);if(!e.ok)throw new Error(`Failed to fetch chains data: ${e.status} ${e.statusText}`);return await e.json()}async function Jt(s){let e=s?.chainsJsonUrl??lt,t=s?.cacheDuration??36e5,r=Date.now();if(we&&r-we.timestamp<t)return we.data;let n=await jt(e);return we={data:n,timestamp:r},n}async function ut(s,e){let r=(await Jt(e)).find(n=>n.chainId===s);return r?r.rpc.filter(n=>!Qt(n)&&!n.startsWith("wss://")&&!n.startsWith("ws://")):[]}var zt=new Set([1,10,8453,42161,57073,100,42220,137,42,15,40,41,44,46,47,50,51,56,61,71,82,83,95,97,112,123,130,146,151,153,171,180,183,185,195,215,228,247,248,252,261,267,291,293,311,332,336,395,401,416,466,480,488,510,545,634,647,648,747,831,919,938,945,957,964,970,980,995,997,1001,1003,1024,1030,1114,1125,1135,1149,1188,1284,1285,1287,1300,1301,1315,1337,1338,1339,1424,1514,1687,1727,1729,1740,1750,1829,1868,1946,1961,1962,1969,1989,1995,2017,2020,2031,2043,2109,2241,2340,2345,2440,2522,2559,2649,3068,3109,3338,3502,3799,3888,3889,4e3,4048,4078,4162,4201,4202,4460,4488,4661,4689,4690,4888,5e3,5003,5124,5234,5330,5424,5522,6283,6342,6398,6678,6806,6934,6942,6969,7117,7171,7200,7208,7368,7518,7668,7672,7744,7771,7869,7897,8008,8118,8217,8408,8700,8726,8727,8844,8880,8881,8882,8889,9372,9496,9700,9745,9746,9899,9990,9996,10011,10085,10143,10200,11221,11501,11504,11891,13370,14853,16602,16661,17e3,18880,18881,19991,21e3,21816,21912,25327,32323,33401,34443,41923,42170,43111,44787,47805,48898,48900,49049,49088,5e4,50312,53302,53456,53457,55244,56288,59141,60808,60850,62320,62850,64002,71402,72080,73114,73115,75338,78281,80002,80008,80069,80094,80451,80931,84532,88899,91342,92278,94524,96970,97476,97477,98985,100021,100501,101010,102030,102031,102032,112358,120893,121212,121213,121214,121215,129399,161803,175188,192940,193939,198989,212013,222222,240241,325e3,355110,355113,421614,555777,560048,656476,713715,743111,747474,763373,763375,777777,806582,808813,810180,839999,888991,2019775,2222222,4278608,5734951,6666689,6985385,7080969,7777777,9999999,11142220,11155111,11155420,11155931,16969696,19850818,20180427,20250825,28122024,34949059,37084624,52164803,61022448,79479957,96969696,420420421,420420422,888888888,974399131,999999999,1020352220,1273227453,1313161560,1350216234,1380996178,1417429182,1444673419,1482601649,1564830818,2046399126,11297108099,11297108109,88153591557,123420000220,123420001114]);async function Zt(s,e=1e4){try{let t=new AbortController,r=setTimeout(()=>t.abort(),e),n=await fetch(s,{method:"POST",headers:{"Content-Type":"application/json"},signal:t.signal,body:JSON.stringify({jsonrpc:"2.0",method:"eth_estimateGas",params:[{from:"0xdeadbeef00000000000000000000000000000000",to:"0xdeadbeef00000000000000000000000000000000",data:"0x0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",value:"0x0"},"latest",{"0xdeadbeef00000000000000000000000000000000":{code:"0xef01000000000000000000000000000000000000000001"}}],id:1})});if(clearTimeout(r),!n.ok)return!1;let o=await n.json();if(o.error){let i=(o.error.message||"").toLowerCase();return!["unsupported","not supported","unknown","invalid","unrecognized","does not support","not implemented"].some(c=>i.includes(c))}return o.result!==void 0}catch{return!1}}async function pt(s,e,t){if(zt.has(s))return!0;let r=t?.maxEndpoints||3,n=t?.timeout||1e4;try{let o=await e(s);if(o.length===0)return!1;let i=o.slice(0,r);for(let a of i)if(await Zt(a,n))return!0;return!1}catch{return!1}}var V=class{constructor(e={}){this.currentUser=null;this.currentWallet=null;this.config={...Fe,...e},this.walletStorage=new de,this.sessionManager=new fe(e.sessionDuration||1),e.stealthAddresses!==void 0&&(this.stealth=new O(e.stealthAddresses,t=>this.getMnemonicFromSession(t)))}async loadZKModule(){if(this.zkModule)return this.zkModule;try{let e=new Function("path","return import(path)"),{ZKProofModule:t}=await e("w3pk/zk"),r=this.config.zkProofs||{};return this.zkModule=new t(r),this.zkModule}catch{throw new Error("ZK module not available. Install dependencies: npm install snarkjs circomlibjs")}}async getMnemonicFromSession(e=!1){if(!e){let l=this.sessionManager.getMnemonic();if(l)return l}if(!this.currentUser)throw new d("Must be authenticated. Call login() first.");let t=await this.walletStorage.retrieve(this.currentUser.ethereumAddress);if(!t)throw new d("No wallet found. Generate a wallet first.");if(!(await ce()).user)throw new d("Authentication failed");let i=new(await Promise.resolve().then(()=>(R(),j))).CredentialStorage().getCredentialById(t.credentialId)?.publicKey,a=await I(t.credentialId,i),c=await he(t.encryptedMnemonic,a);return this.sessionManager.startSession(c,t.credentialId),c}async register(e){try{this.currentWallet?.address||await this.generateWallet();let t=this.currentWallet.address,r=this.currentWallet.mnemonic;await tt({username:e.username,ethereumAddress:t}),this.currentUser={id:t,username:e.username,displayName:e.username,ethereumAddress:t};let o=new(await Promise.resolve().then(()=>(R(),j))).CredentialStorage().getCredentialByAddress(t);if(!o)throw new d("Credential not found after registration");let i=o.id,a=o.publicKey,c=await I(i,a),l=await pe(r,c);return await this.walletStorage.store({ethereumAddress:this.currentUser.ethereumAddress,encryptedMnemonic:l,credentialId:i,createdAt:Date.now()}),this.sessionManager.startSession(r,i),this.currentWallet={address:t,mnemonic:r},this.config.onAuthStateChanged?.(!0,this.currentUser),{address:t,username:e.username}}catch(t){throw this.config.onError?.(t),t}}async login(){try{let e=await ce();if(!e.verified||!e.user)throw new k("Login failed");this.currentUser={id:e.user.ethereumAddress,username:e.user.username,displayName:e.user.username,ethereumAddress:e.user.ethereumAddress};let t=await this.walletStorage.retrieve(this.currentUser.ethereumAddress);if(!t)throw new d("No wallet found for this user. You may need to register first.");let o=new(await Promise.resolve().then(()=>(R(),j))).CredentialStorage().getCredentialById(t.credentialId)?.publicKey,i=await I(t.credentialId,o),a=await he(t.encryptedMnemonic,i);return this.sessionManager.startSession(a,t.credentialId),this.config.onAuthStateChanged?.(!0,this.currentUser),this.currentUser}catch(e){throw this.config.onError?.(e),e}}async logout(){this.currentUser=null,this.currentWallet=null,this.sessionManager.clearSession(),this.config.onAuthStateChanged?.(!1,void 0)}get isAuthenticated(){return this.currentUser!==null}get user(){return this.currentUser}async generateWallet(){try{let e=le();return this.currentWallet={address:e.address,mnemonic:e.mnemonic},{mnemonic:e.mnemonic}}catch(e){throw this.config.onError?.(e),new d("Failed to generate wallet",e)}}async deriveWallet(e,t){try{if(!this.currentUser)throw new d("Must be authenticated to derive wallet");let r=await this.getMnemonicFromSession(t?.requireAuth),n=ue(r,e);return{address:n.address,privateKey:n.privateKey}}catch(r){throw this.config.onError?.(r),new d("Failed to derive wallet",r)}}async exportMnemonic(e){try{if(!this.currentUser)throw new d("Must be authenticated to export mnemonic");return await this.getMnemonicFromSession(e?.requireAuth)}catch(t){throw this.config.onError?.(t),new d("Failed to export mnemonic",t)}}async importMnemonic(e){try{if(!this.currentUser)throw new d("Must be authenticated to import mnemonic");if(!e||e.trim().split(/\s+/).length<12)throw new d("Invalid mnemonic: must be at least 12 words");let t=await ce();if(!t.user)throw new d("Authentication failed");let r=t.user.credentialId,i=new(await Promise.resolve().then(()=>(R(),j))).CredentialStorage().getCredentialById(r)?.publicKey,a=await I(r,i),c=await pe(e.trim(),a);await this.walletStorage.store({ethereumAddress:this.currentUser.ethereumAddress,encryptedMnemonic:c,credentialId:r,createdAt:Date.now()}),this.currentWallet={address:this.currentUser.ethereumAddress,mnemonic:e.trim()},this.sessionManager.startSession(e.trim(),r)}catch(t){throw this.config.onError?.(t),new d("Failed to import mnemonic",t)}}async signMessage(e,t){try{if(!this.currentUser)throw new d("Must be authenticated to sign message");let r=await this.getMnemonicFromSession(t?.requireAuth),{Wallet:n}=await import("ethers");return await n.fromPhrase(r).signMessage(e)}catch(r){throw this.config.onError?.(r),new d("Failed to sign message",r)}}async getEndpoints(e){return ut(e)}async supportsEIP7702(e,t){return pt(e,this.getEndpoints.bind(this),t)}get zk(){return new Proxy({},{get:(e,t)=>async(...r)=>(await this.loadZKModule())[t](...r)})}async getBackupStatus(){if(!this.currentUser)throw new d("Must be authenticated to check backup status");let{BackupManager:e}=await Promise.resolve().then(()=>(B(),q));return new e().getBackupStatus(this.currentUser.ethereumAddress)}async createZipBackup(e,t){if(!this.currentUser)throw new d("Must be authenticated to create backup");let r=await this.getMnemonicFromSession(!0),{BackupManager:n}=await Promise.resolve().then(()=>(B(),q));return new n().createZipBackup(r,this.currentUser.ethereumAddress,{password:e,...t})}async createQRBackup(e,t){if(!this.currentUser)throw new d("Must be authenticated to create backup");let r=await this.getMnemonicFromSession(!0),{BackupManager:n}=await Promise.resolve().then(()=>(B(),q));return new n().createQRBackup(r,this.currentUser.ethereumAddress,{password:e,...t})}async setupSocialRecovery(e,t){if(!this.currentUser)throw new d("Must be authenticated to set up social recovery");let r=await this.getMnemonicFromSession(!0),{SocialRecoveryManager:n}=await Promise.resolve().then(()=>(ee(),ke));return new n().setupSocialRecovery(r,this.currentUser.ethereumAddress,e,t)}async generateGuardianInvite(e){let{SocialRecoveryManager:t}=await Promise.resolve().then(()=>(ee(),ke)),r=new t,n=r.getSocialRecoveryConfig();if(!n)throw new d("Social recovery not configured");let o=n.guardians.find(i=>i.id===e);if(!o)throw new d("Guardian not found");return r.generateGuardianInvite(o)}async recoverFromGuardians(e){let{SocialRecoveryManager:t}=await Promise.resolve().then(()=>(ee(),ke));return new t().recoverFromGuardians(e)}async restoreFromBackup(e,t){let{BackupManager:r}=await Promise.resolve().then(()=>(B(),q));return new r().restoreFromZipBackup(e,t)}async restoreFromQR(e,t){let{BackupManager:r}=await Promise.resolve().then(()=>(B(),q));return new r().restoreFromQR(e,t)}async getSyncStatus(){let{DeviceManager:e}=await Promise.resolve().then(()=>(Ae(),_e));return new e().getSyncStatus()}async detectSyncCapabilities(){let{PlatformDetector:e}=await Promise.resolve().then(()=>(Ae(),_e));return new e().detectSyncCapabilities()}async simulateRecoveryScenario(e){if(!this.currentUser)throw new d("Must be authenticated to run recovery simulation");let t=await this.getBackupStatus(),{RecoverySimulator:r}=await Promise.resolve().then(()=>(te(),Pe));return new r().simulateScenario(e,t)}async runRecoveryTest(){if(!this.currentUser)throw new d("Must be authenticated to run recovery test");let e=await this.getBackupStatus(),{RecoverySimulator:t}=await Promise.resolve().then(()=>(te(),Pe));return new t().runInteractiveTest(e)}async getEducation(e){let{getExplainer:t}=await Promise.resolve().then(()=>(te(),Pe)),r=t(e);if(!r)throw new d(`Unknown education topic: ${e}`);return r}hasActiveSession(){return this.sessionManager.isActive()}getSessionRemainingTime(){return this.sessionManager.getRemainingTime()}extendSession(){try{this.sessionManager.extendSession()}catch(e){throw new d("Cannot extend session",e)}}clearSession(){this.sessionManager.clearSession()}setSessionDuration(e){this.sessionManager.setSessionDuration(e)}};w();B();ee();Ae();te();function Pt(s={}){return new V(s)}var er=Pt;
777
777
  //# sourceMappingURL=index.js.map