4 lines
28 KiB
JavaScript
4 lines
28 KiB
JavaScript
|
|
import{c as yt}from"./chunks/core-CvwXoH-U.js";const F="contractlessWallet",M="contractlessWallets",V="contractlessSettings",L="contractlessAutoLock",K="contractlessUnlockedWallet",j="contractlessApplicationSessions",ct=12e4,vt=10,bt={apiUrl:"https://api.contractless.dev",autoLockMinutes:60};let s;const J="pending-provider-approvals";async function k(){const e=await chrome.storage.local.get(V);return{...bt,...e[V]??{}}}function lt(e){const t=JSON.parse(e);if(typeof t.short_address!="string"||typeof t.public_key!="string")throw new Error("The encrypted wallet metadata is invalid.");return{address:t.short_address,publicKey:t.public_key}}async function $(){const e=await chrome.storage.local.get([M,F]),t=e[M];if((t==null?void 0:t.version)===1&&Array.isArray(t.wallets))return t;const a=e[F];if(typeof a!="string")return{version:1,wallets:[]};const i=lt(a),d={id:crypto.randomUUID(),label:"Contractless Account 1",address:i.address,publicKey:i.publicKey,walletJson:a},l={version:1,activeWalletId:d.id,wallets:[d]};return await chrome.storage.local.set({[M]:l}),await chrome.storage.local.remove(F),l}async function H(e){await chrome.storage.local.set({[M]:e})}function P(e){return e.wallets.find(t=>t.id===e.activeWalletId)??e.wallets[0]}async function X(e){const t=await $(),a=lt(e),i=t.wallets.find(l=>l.address===a.address);if(i)return i.walletJson=e,i.publicKey=a.publicKey,t.activeWalletId=i.id,await H(t),i;const d={id:crypto.randomUUID(),label:`Contractless Account ${t.wallets.length+1}`,address:a.address,publicKey:a.publicKey,walletJson:e};return t.wallets.push(d),t.activeWalletId=d.id,await H(t),d}async function E(){await dt();const e=await $(),t=P(e),a=await k();return{exists:e.wallets.length>0,unlocked:!!(s&&s.walletId===(t==null?void 0:t.id)),activeWalletId:t==null?void 0:t.id,activeWalletLabel:t==null?void 0:t.label,address:s==null?void 0:s.short_address,publicKey:s==null?void 0:s.public_key,wallets:e.wallets.map(i=>({id:i.id,label:i.label,address:i.address,publicKey:i.publicKey,active:i.id===(t==null?void 0:t.id)})),apiUrl:a.apiUrl,autoLockMinutes:a.autoLockMinutes}}async function b(){if(!s)return;const e=await k();s.expiresAt=Date.now()+e.autoLockMinutes*6e4,await chrome.storage.session.set({[K]:s}),await chrome.alarms.clear(L),await chrome.alarms.create(L,{when:s.expiresAt})}function kt(e,t){const a=new Uint8Array(e);let i="";const d=32768;for(let l=0;l<a.length;l+=d)i+=String.fromCharCode(...a.subarray(l,l+d));return`data:${t};base64,${btoa(i)}`}async function W(e){await wt(),s={...e,sessionId:crypto.randomUUID(),expiresAt:0},await b()}async function Y(e,t){const a=JSON.parse(e.create_wallet_registration_from_keys(t.short_address,t.public_key,t.private_key)),i=e.create_handshake_proof(t.public_key,t.private_key),d=await k(),l=await fetch(`${d.apiUrl}/api/v1/addresses/register`,{method:"POST",headers:{"Content-Type":"application/json","X-Contractless-Address":t.short_address,"X-Contractless-Public-Key":t.public_key,"X-Contractless-Signature":i},body:JSON.stringify({address:a.short_address,public_key:a.public_key,signature:a.signature})}),f=await l.json().catch(()=>{});if(!l.ok||(f==null?void 0:f.success)!==!0)throw new Error((f==null?void 0:f.error)??`Wallet registration failed with HTTP ${l.status}.`);return f.data}async function St(e,t){var f;const a=await k(),i=e.create_handshake_proof(t.public_key,t.private_key),d=await fetch(`${a.apiUrl}/api/v1/addresses/registration?address=${encodeURIComponent(t.short_address)}`,{headers:{"X-Contractless-Address":t.short_address,"X-Contractless-Public-Key":t.public_key,"X-Contractless-Signature":i}}),l=await d.json().catch(()=>{});if(!d.ok||(l==null?void 0:l.success)!==!0)throw new Error((l==null?void 0:l.error)??`Wallet registration lookup failed with HTTP ${d.status}.`);((f=l.data)==null?void 0:f.registered)!==!0&&await Y(e,t)}async function dt(){if(s){if(s.expiresAt>Date.now())return;await R();return}const t=(await chrome.storage.session.get(K))[K];if(!t||t.expiresAt<=Date.now()){await chrome.storage.session.remove(K);return}t.sessionId||(t.sessionId=crypto.randomUUID(),await wt(
|
||
|
|
`),A=JSON.parse(e.sign_message_request(JSON.stringify({origin:t.origin,message:U,nonce:f,issued_at:S,expires_at:x}),s.private_key,s.public_key)),I={origin:t.origin,appId:d,accessKey:y,walletId:s.walletId,unlockSessionId:s.sessionId,createdAt:Date.now()},r=await Q();return r.push(I),await pt(r),{address:s.short_address,publicKey:s.public_key,signature:A.signature,proof:A,accessKey:y,appId:d,origin:t.origin,sessionExpiresAt:s.expiresAt}}case"contractless_signMessage":{const a=O(t);await N(a,t.origin);const i=Math.floor(Date.now()/1e3),d=Number(a.expires_at??i+300),l=C(a.appId),f={origin:t.origin,message:["Contractless application message",`Application ID: ${l}`,`Message: ${ft(a.message)}`].join(`
|
||
|
|
`),nonce:String(a.nonce??""),issued_at:i,expires_at:d};return JSON.parse(e.sign_message_request(JSON.stringify(f),s.private_key,s.public_key))}case"contractless_sendTransaction":{const a=O(t);await N(a,t.origin);const i=_t(a.transaction),d=JSON.parse(e.sign_transaction_request(JSON.stringify(i),s.private_key,s.public_key,1));return mt(e,d)}case"contractless_signDualTransaction":{const a=O(t);await N(a,t.origin);const i=z(a.transaction),d=Number(a.signerSlot);if(d!==1&&d!==2)throw new Error("The signer slot must be 1 or 2.");const l=JSON.parse(e.sign_transaction_request(JSON.stringify(i),s.private_key,s.public_key,d));return{complete:!1,txid:l.hash,unsignedBytes:l.unsigned_bytes_hex,canonicalUnsignedJson:JSON.parse(e.inspect_transaction_request(JSON.stringify(i))).canonical_unsigned_json,signedTransaction:l.signed_transaction,signature:d===1?l.signature1:l.signature2,signature1:l.signature1,signature2:l.signature2,signerSlot:d,signerPublicKey:s.public_key}}default:throw new Error("The website requested an unsupported wallet method.")}}async function It(e,t){var i,d,l,f,v,y,T,S,x,U,A,I;const a=await yt();switch(await dt(),e.type){case"status":return E();case"create-wallet":{const r=String(e.password),o=a.generate_browser_wallet(r),n=JSON.parse(a.unlock_browser_wallet(o,r));await Y(a,n);const u=await X(o);return await W({walletId:u.id,...n}),E()}case"import-wallet":{const r=a.import_legacy_wallet(String(e.walletJson),String(e.legacyPassword),String(e.password)),o=await X(r),n=JSON.parse(a.unlock_browser_wallet(r,String(e.password)));return await W({walletId:o.id,...n}),E()}case"import-wallet-image":{const r=String(e.password),o=a.import_private_key_image(String(e.imageBase64),String(e.imagePassword),r),n=await X(o),u=JSON.parse(a.unlock_browser_wallet(o,r));return await W({walletId:n.id,...u}),E()}case"import-private-key":{const r=String(e.password),o=a.import_private_key(String(e.privateKey),r),n=await X(o),u=JSON.parse(a.unlock_browser_wallet(o,r));return await W({walletId:n.id,...u}),E()}case"unlock":{const r=await $(),o=P(r);if(!o)throw new Error("No wallet exists.");const n=JSON.parse(a.unlock_browser_wallet(o.walletJson,String(e.password)));await W({walletId:o.id,...n});try{await St(a,n)}catch(u){console.warn("Automatic wallet registration failed during unlock.",u)}return E()}case"switch-wallet":{const r=await $(),o=String(e.walletId);if(!r.wallets.some(n=>n.id===o))throw new Error("The selected wallet does not exist.");return await R(),r.activeWalletId=o,await H(r),E()}case"rename-wallet":{const r=await $(),o=r.wallets.find(u=>u.id===String(e.walletId));if(!o)throw new Error("The selected wallet does not exist.");const n=String(e.label).trim();if(n.length<1||n.length>40)throw new Error("Wallet labels must contain between 1 and 40 characters.");return o.label=n,await H(r),E()}case"lock":return await R(),E();case"save-settings":{const r={apiUrl:String(e.apiUrl).replace(/\/+$/,""),autoLockMinutes:Math.max(1,Number(e.autoLockMinutes))};return await chrome.storage.local.set({[V]:r}),await b(),E()}case"register-wallet":{if(!s)throw new Error("Wallet is locked.");const r=await Y(a,s);return await b(),r}case"wallet-balances":{if(!s)throw new Error("Wallet is locked.");const r=await k(),o=a.create_handshake_proof(s.public_key,s.private_key),n={"X-Contractless-Address":s.short_address,"X-Contractless-Public-Key":s.public_key,"X-Contractless-Signature":o},u=encodeURIComponent(s.short_address),[c,h,w]=await Promise.all([fetch(`${r.apiUrl}/api/v1/balances?address=${u}`,{headers:n}),fetch(`${r.apiUrl}/api/v1/tokens`,{headers:n}),fetch(`${r.apiUrl}/api/v1/nfts`,{headers:n})]),[p,_,g]=await Promise.all([c.json().catch(()=>{}),h.json().catch(()=>{}),w.json().catch(()=>{})]);if(!c.ok||(p==null?void 0:p.success)!==!0)throw new Error((p==null?void 0:p.error)??`Balance lookup failed with HTTP ${c.status}.`);return await b(),{address:s.short_address,balances:((i=p.data)==null?void 0:i.balances)??[],tokens:h.ok&&(_==null?void 0:_.success)===!0?((d=_.data)==null?void 0:d.tokens)??[]:[],nfts:w.ok&&(g==null?void 0:g.success)===!0?((l=g.data)
|