micro-stacks
Version:
Tiny libraries for building Stacks apps.
61 lines (56 loc) • 12.6 kB
JavaScript
;
Object.defineProperty(exports, '__esModule', { value: true });
var common = require('micro-stacks/common');
var crypto = require('micro-stacks/crypto');
var clarity = require('micro-stacks/clarity');
var transactions = require('micro-stacks/transactions');
var sha256 = require('@noble/hashes/sha256');
var cryptoSha = require('micro-stacks/crypto-sha');
var utils = require('@noble/hashes/utils');
var secp256k1 = require('@noble/secp256k1');
var connect = require('micro-stacks/connect');
var y=typeof document<"u",te=(r=>(r.SessionStorageKey="stacks-session",r.NetworkStorageKey="stacks-network",r))(te||{});var u=common.getGlobalObject("localStorage",{returnEmptyObject:!0}),M={setItem:(e,t)=>{if(y)return u==null?void 0:u.setItem(e,t)},getItem:e=>{if(y){let t=u==null?void 0:u.getItem(e);if(t===null)throw new Error("defaultStorageAdapter: no value stored");return t}},removeItem:e=>{if(y)return u==null?void 0:u.removeItem(e)}},c=e=>e?common.bytesToHex(crypto.getPublicKey(e,!0)):null;function K(e){return e==null?void 0:e.map(t=>typeof t!="string"?common.bytesToHex(transactions.serializePostCondition(t)):t)}var d=(e,t)=>t?new crypto.TokenSigner("ES256k",t).sign(e):crypto.createUnsecuredToken(e);var l=async(e,t)=>{let r={...e,postConditions:K(e.postConditions)};return d(r,t)};var ue=(n=>(n.ContractCall="contract_call",n.ContractDeploy="smart_contract",n.STXTransfer="token_transfer",n))(ue||{});async function wt({functionArgs:e,privateKey:t,...r}){let n=c(t),s={...r,functionArgs:e.map(o=>common.cleanHex(typeof o=="string"?o:clarity.cvToHex(o))),txType:"contract_call",publicKey:n};return l(s,t)}async function It({privateKey:e,...t}){let r={...t,publicKey:c(e),txType:"smart_contract"};return l(r,e)}async function Et({privateKey:e,...t}){let r={...t,amount:typeof t.amount=="bigint"?Number(t.amount).toString(10):t.amount,publicKey:c(e),txType:"token_transfer"};return l(r,e)}function ye(e){let t=e.split(":");if(t.length!==3)throw new TypeError("Decentralized IDs must have 3 parts");if(t[0].toLowerCase()!=="did")throw new TypeError('Decentralized IDs must start with "did"');return t[1].toLowerCase()}function fe(e){return e&&ye(e)==="btc-addr"?e.split(":")[2]:void 0}async function U(e,t){let r=crypto.decodeToken(e),s=r==null?void 0:r.payload,o;if(s.private_key)try{let i=common.hexToJSON(s.private_key);o=await crypto.decryptECIES({privateKey:t,cipherObject:i});}catch{console.error("[micro-stacks] failed to decrypt appPrivateKey");}return {addresses:s.profile.stxAddress,appPrivateKey:o,associationToken:s.associationToken,hubUrl:s.hubUrl,public_keys:s.public_keys,profile:s.profile,profile_url:s.profile_url,username:s.username,version:s.version,decentralizedID:s.iss,identityAddress:fe(s.iss)}}function f(){return common.getGlobalObject("StacksProvider",{returnEmptyObject:!1,usageDesc:"authenticate",throwIfUnavailable:!0})}async function Lt(e,t=M,r=JSON.stringify){var n,s;if(!e.appDetails)throw Error("[micro-stacks] authenticate error: `authOptions.appDetails` are required for authentication");try{let o=common.bytesToHex(crypto.getRandomBytes()),a=await we(e,o),i=await U(a,o);return (n=e==null?void 0:e.onFinish)==null||n.call(e,i),t.setItem("stacks-session",r(i)),i}catch(o){(s=e==null?void 0:e.onCancel)==null||s.call(e,o.message);}}function ke(e,t){if(!e.appDetails)throw Error("[micro-stacks] authenticate error: `authOptions.appDetails` are required for authentication");let r=e.scopes||[],n=common.getGlobalObject("location",{returnEmptyObject:!0}).origin;return {scopes:[...new Set(["store_write",...r])],redirect_uri:n,public_keys:[t],domain_name:n,appDetails:e.appDetails}}async function be(e,t){return new crypto.TokenSigner("ES256k",t).sign(e)}async function ve(e,t){let r=common.bytesToHex(crypto.getPublicKey(t)),n=ke(e,r);return be(n,t)}async function we(e,t){let r=f();if(!r)throw Error("This function can only be called on the client, and with the presence of StacksProvider");let n=await ve(e,t);return r.authenticationRequest(n)}function m(e){return async function(r){let{token:n,onFinish:s,onCancel:o}=r;try{let a=f();if(!a)throw new Error("[micro-stacks/connect] No Stacks provider");let i=a[e];if(typeof i!="function")throw new Error(`[micro-stacks/connect] StacksProvider method ${e} not found`);let g=await i(n);s==null||s(g);}catch(a){o==null||o(a==null?void 0:a.message);}}}var zt=m("transactionRequest"),F=m("signatureRequest"),H=m("structuredDataSignatureRequest"),$t=m("psbtRequest");var _=(s=>(s.Chrome="https://chrome.google.com/webstore/detail/hiro-wallet/ldinpeekobnhjjdofggfgjlcehhmanlj",s.Firefox="https://addons.mozilla.org/en-US/firefox/addon/hiro-wallet/",s.Mobile="https://www.xverse.app",s.Browser="https://www.hiro.so/wallet/install-web",s))(_||{});function Ae(){if(typeof document>"u")return;let e=!!window.chrome,t=window.navigator,r=t.vendor,n=typeof window.opr<"u",s=t.userAgent.includes("Edge");return /CriOS/.exec(t.userAgent)?!1:e!==null&&typeof e<"u"&&r==="Google Inc."&&!n&&!s}function W(){if(typeof document===void 0)return;let e=navigator.userAgent;return /(tablet|ipad|playbook|silk)|(android(?!.*mobi))/i.test(e)?!0:/Mobile|Android|iP(hone|od)|IEMobile|BlackBerry|Kindle|Silk-Accelerated|(hpw|web)OS|Opera M(obi|ini)/.test(e)}function Ce(){return typeof document>"u"?null:W()?"Mobile":Ae()?"Chrome":window.navigator.userAgent.includes("Firefox")?"Firefox":"Browser"}function De(e){switch(e){case"Chrome":return "https://chrome.google.com/webstore/detail/hiro-wallet/ldinpeekobnhjjdofggfgjlcehhmanlj";case"Firefox":return "https://addons.mozilla.org/en-US/firefox/addon/hiro-wallet/";case"Mobile":return "https://www.xverse.app";default:return "https://www.hiro.so/wallet/install-web"}}var V=async e=>{let t={stxAddress:e.stxAddress||null,message:e.message,appDetails:e.appDetails||null,publicKey:c(e.privateKey),network:e.network};return d(t,e.privateKey)},Ie=async e=>{try{let t=await V({message:e.message,network:e.network,privateKey:e.privateKey,stxAddress:e.stxAddress,authOrigin:e.authOrigin,appDetails:e.appDetails});return F({token:t,onFinish:e.onFinish,onCancel:e.onCancel})}catch(t){console.error("[micro-stacks] handleSignMessageRequest failed"),console.error(t);}};var Ke=Uint8Array.from([83,73,80,48,49,56]),S=e=>sha256.sha256(clarity.serializeCV(e)),h=(e,t,r)=>clarity.tupleCV({name:clarity.stringAsciiCV(e),version:clarity.stringAsciiCV(t),"chain-id":clarity.uintCV(r)}),P=(e,t)=>sha256.sha256(common.concatByteArrays([Ke,e,t])),T=e=>{let t=typeof e.message=="string"?clarity.hexToCV(e.message):e.message,r=h(e.domain.name,e.domain.version,e.domain.chainId??common.ChainID.Mainnet);return {message:S(t),domain:S(r)}},X=e=>{var o;let t=typeof e.message!="string"?clarity.cvToHex(e.message):e.message,r=h(e.domain.name,e.domain.version,e.domain.chainId??((o=e.network)==null?void 0:o.chainId)??common.ChainID.Mainnet),n=clarity.cvToHex(r),s={stxAddress:e.stxAddress||null,message:common.cleanHex(t),domain:common.cleanHex(n),appDetails:e.appDetails,publicKey:c(e.privateKey),network:e.network};return d(s,e==null?void 0:e.privateKey)},Ue=async e=>{try{let t=await X({message:e.message,domain:e.domain,privateKey:e.privateKey,stxAddress:e.stxAddress,authOrigin:e.authOrigin,appDetails:e.appDetails,network:e.network});return H({token:t,onFinish:e.onFinish,onCancel:e.onCancel})}catch(t){console.error("[micro-stacks] handleSignStructuredDataRequest failed"),console.error(t);}};var _e=9007199254740991;function v(e){if(e<0||e>_e||e%1!==0)throw new RangeError("value out of range")}var w=(e,t,r)=>{v(e);let n;if(t||(t=new Uint8Array(A(e))),!common.ensureUint8Array(t))throw new TypeError("uint8Array must be of Uint8Array type");return r||(r=0),e<253?(common.writeUInt8(t,e,r),n=1):e<=65535?(common.writeUInt8(t,253,r),common.writeUInt16LE(t,e,r+1),n=3):e<=4294967295?(common.writeUInt8(t,254,r),common.writeUInt32LE(t,e,r+1),n=5):(common.writeUInt8(t,255,r),common.writeUInt32LE(t,e>>>0,r+1),common.writeUInt32LE(t,e/4294967296|0,r+5),n=9),w.bytes=n,t},p=(e,t)=>{if(!common.ensureUint8Array(e))throw new TypeError("uint8Array must be of Uint8Array type");t||(t=0);let r=common.readUInt8(e,t);if(r<253)return p.bytes=1,r;if(r===253)return p.bytes=3,common.readUInt16LE(e,t+1);if(r===254)return p.bytes=5,common.readUInt32LE(e,t+1);{p.bytes=9;let n=common.readUInt32LE(e,t+1),o=common.readUInt32LE(e,t+5)*4294967296+n;return v(o),o}};function A(e){return v(e),e<253?1:e<=65535?3:e<=4294967295?5:9}var Ne=`Stacks Signed Message:
`,D=utils.utf8ToBytes(Ne),Je=`Stacks Message Signing:
`,I=utils.utf8ToBytes(Je);function O(e,t=D){return cryptoSha.hashSha256(z(e,t))}function z(e,t=D){let r=typeof e=="string"?utils.utf8ToBytes(e):e,n=w(r.length);return common.concatByteArrays([t,n,r])}function Le(e,t=D){let r=e.subarray(t.byteLength),n=p(r),s=A(n);return r.slice(s)}var R=32;function Qe(e){if(e.length<R*2*2+1)throw new Error("Invalid signature");let t=e.slice(0,2),r=e.slice(2,2+R*2),n=e.slice(2+R*2);return {recoveryBytes:common.hexToBigInt(t),r,s:n}}function Ze(e){return e.slice(-2)+e.slice(0,-2)}var Q=({hash:e,signature:t,recoveryBytes:r})=>secp256k1.recoverPublicKey(e,t,Number(r),!0),Z=e=>{let{signature:t,mode:r="rsv"}=e,{r:n,s,recoveryBytes:o}=Qe(r==="rsv"?Ze(t):t);return {signature:new secp256k1.Signature(common.hexToBigInt(n),common.hexToBigInt(s)),recoveryBytes:o}},E=e=>{if(!e.publicKey&&!e.stxAddress)throw Error("[micro-stacks/connect[ verifyMessageSignature -- You must pass `stxAddress` if you are recovering the public key from the signature");let{message:t,mode:r="rsv"}=e,n=e.publicKey;try{let s=typeof t=="string"?O(t,e.prefix):t,{signature:o,recoveryBytes:a}=Z({signature:e.signature,mode:r});if(!n){let[i]=crypto.c32addressDecode(e.stxAddress);n=common.bytesToHex(Q({hash:s,signature:o,recoveryBytes:a}));let g=crypto.publicKeyToStxAddress(n,i);if(g!==e.stxAddress)return console.error(`[micro-stacks/connect] verifyMessageSignature Stacks address is not correct. expected: ${e.stxAddress}, received: ${g}`),!1}return secp256k1.verify(o,s,n,{strict:!1})}catch(s){return console.error("[micro-stacks/connect] verifyMessageSignature failed",s),!1}},$=e=>{if(!e.publicKey&&!e.stxAddress)throw Error("[micro-stacks/connect[ verifyStructuredMessageSignature -- You must pass `stxAddress` if you are recovering the public key from the signature");let{domain:t,message:r}=T({domain:e.domain,message:e.message}),n=P(t,r);return E({message:n,signature:e.signature,publicKey:e.publicKey,stxAddress:e.stxAddress,mode:e.mode,prefix:e.prefix})},et=e=>E(e)||E({...e,prefix:I}),tt=e=>$(e)||$({...e,prefix:I});var ee=async e=>{let t={allowedSighash:e.allowedSighash||null,hex:e.hex||null,signAtIndex:e.signAtIndex||null,stxAddress:e.stxAddress||null,appDetails:e.appDetails||null,publicKey:connect.safeGetPublicKey(e.privateKey),network:e.network};return d(t,e.privateKey)},st=async e=>{try{let t=await ee({allowedSighash:e.allowedSighash,hex:e.hex,signAtIndex:e.signAtIndex,privateKey:e.privateKey,stxAddress:e.stxAddress,authOrigin:e.authOrigin,appDetails:e.appDetails});return connect.openPSBTPopup({token:t,onFinish:e.onFinish,onCancel:e.onCancel})}catch(t){console.error("[micro-stacks] handlePSBTRequest failed"),console.error(t);}};
exports.IS_BROWSER = y;
exports.PersistedDataKeys = te;
exports.TransactionTypes = ue;
exports.WALLET_INSTALL_URLS = _;
exports.authenticate = Lt;
exports.decodeAuthResponse = U;
exports.decodeMessage = Le;
exports.defaultStorageAdapter = M;
exports.encodeMessage = z;
exports.generateAuthRequestPayload = ke;
exports.generatePSBTMessagePayload = ee;
exports.generateSignMessagePayload = V;
exports.generateSignStructuredDataPayload = X;
exports.generateSignedAuthRequest = ve;
exports.genericTransactionPopupFactory = m;
exports.getAddressFromDID = fe;
exports.getBrowser = Ce;
exports.getDIDType = ye;
exports.getIsMobileDevice = W;
exports.getPublicKeyFromSignature = Q;
exports.getStructuredDataHashes = T;
exports.getWalletInstallUrl = De;
exports.handleAuthResponse = we;
exports.handlePSBTRequest = st;
exports.handleSignMessageRequest = Ie;
exports.handleSignStructuredDataRequest = Ue;
exports.hashMessage = O;
exports.makeClarityHash = S;
exports.makeContractCallToken = wt;
exports.makeContractDeployToken = It;
exports.makeDomainTuple = h;
exports.makeStructuredDataHash = P;
exports.makeStxTransferToken = Et;
exports.openPSBTPopup = $t;
exports.openSignMessagePopup = F;
exports.openSignStructuredDataPopup = H;
exports.openTransactionPopup = zt;
exports.recoverSignature = Z;
exports.safeGetPublicKey = c;
exports.signAuthRequest = be;
exports.verifyMessageSignature = et;
exports.verifyStructuredMessageSignature = tt;