UNPKG

@privy-io/cross-app-connect

Version:

Privy cross app wallet connectors for wagmi and RainbowKit

2 lines 11.5 kB
let e=require("viem"),t=require("@privy-io/popup"),n=require("@noble/curves/secp256k1"),r=require("@scure/base"),i=require("buffer"),a=require("fflate"),o=require("@privy-io/encoding");async function s({providerAppId:e,apiUrl:t}){let{custom_connect_url:n,custom_transact_url:r,custom_api_url:i,icon_url:a,name:o}=await(await fetch(`${t}/api/v1/apps/${e}/cross-app/details`,{method:`GET`,headers:{"Content-Type":`application/json`}})).json();return{url:i,customConnectUrl:n,customTransactUrl:r,name:o,iconUrl:a}}const c=120*1e3;function l(){let e=n.secp256k1.utils.randomPrivateKey(),t=n.secp256k1.getPublicKey(e);return{privateKey:r.base64.encode(e),publicKey:r.base64.encode(t)}}function u({privateKey:e,publicKey:t}){let i=n.secp256k1.getSharedSecret(r.base64.decode(e),r.base64.decode(t)).slice(1);return r.base64.encode(i)}async function d(e,t){let n=JSON.stringify(e),r=(0,a.zlibSync)(o.encoding.utf8.toBytes(n)),i=o.encoding.base64.toBytes(t),s=await crypto.subtle.importKey(`raw`,i,{name:`AES-GCM`},!0,[`encrypt`]),c=crypto.getRandomValues(new Uint8Array(12)),l=await crypto.subtle.encrypt({name:`AES-GCM`,iv:c},s,new Uint8Array(r));return{iv:o.encoding.base64.fromBytes(c),encryptedRequest:o.encoding.base64.fromBytes(new Uint8Array(l))}}async function f({encryptedResult:e,iv:t,sharedSecret:n}){let r=o.encoding.base64.toBytes(n),s=o.encoding.base64.toBytes(t),c=await crypto.subtle.importKey(`raw`,r,{name:`AES-GCM`},!0,[`decrypt`]),l=o.encoding.base64.toBytes(e),u=await crypto.subtle.decrypt({name:`AES-GCM`,iv:s},c,l),d=(0,a.unzlibSync)(i.Buffer.from(u));return o.encoding.utf8.fromBytes(d)}async function p({request:e,apiUrl:n,publicKey:r,sharedSecret:i,providerAppId:a,timeout:o=c}){let s=(0,t.trigger)();if(!s)throw Error(`Failed to initialize request`);let l=new URL(n),{encryptedRequest:u,iv:p}=await d(e,i);return l.searchParams.set(`requester_public_key`,r),l.searchParams.set(`encrypted_request`,u),l.searchParams.set(`requester_origin`,window.location.origin),l.searchParams.set(`iv`,p),l.searchParams.set(`provider_app_id`,a),l.searchParams.set(`signout_enabled`,`true`),l.searchParams.set(`v`,`1`),s.location=l.href,new Promise((e,t)=>{let n=setTimeout(()=>{c(),t(new m(`Request timeout`))},o),r=setInterval(()=>{s.closed&&(c(),t(new m(`User rejected request`)))},300),a=async n=>{n.data&&(n.data.type===`PRIVY_CROSS_APP_ACTION_RESPONSE`&&n.data.encryptedResult&&(c(),e(await f({encryptedResult:n.data.encryptedResult,iv:n.data.iv,sharedSecret:i}))),n.data.type===`PRIVY_CROSS_APP_ACTION_ERROR`&&n.data.error&&(c(),t(new m(n.data.error,{mwp:n.data.mwp,code:n.data?.errorCode}))))};window.addEventListener(`message`,a);let c=()=>{s.close(),clearInterval(r),clearTimeout(n),window.removeEventListener(`message`,a)}})}var m=class extends Error{action;code;constructor(e,t){super(e),t?.mwp?.action&&(this.action=t.mwp.action),t?.code&&(this.code=t.code)}};async function h({url:e,timeout:n=c}){let r=(0,t.trigger)({location:e.href});if(!r)throw Error(``);return new Promise((e,t)=>{let i=setTimeout(()=>{t(Error(`Authorization request timed out after ${n} ms.`)),a()},n);function a(){r?.close(),window.removeEventListener(`message`,c)}let o,s=setInterval(()=>{r?.closed&&!o&&(a(),clearInterval(s),clearTimeout(i),t(Error(`User rejected request`)))},300);function c(n){n.data&&(n.data.type===`PRIVY_CROSS_APP_CONNECT_RESPONSE`&&(e(n.data),r?.close()),n.data.type===`PRIVY_CROSS_APP_ACTION_ERROR`&&(clearTimeout(i),t(Error(n.data.error)),a()),n.data.type===`PRIVY_OAUTH_USE_BROADCAST_CHANNEL`&&(o=new BroadcastChannel(`popup-privy-oauth`),o.onmessage=c))}window.addEventListener(`message`,c)})}async function g({providerAppId:e,providerUrl:t,connectionOpts:n,defaultPopupTimeout:r}){let i=new URL(t),{privateKey:a,publicKey:o}=l();i.searchParams.set(`requester_public_key`,o),i.searchParams.set(`connect`,`true`),i.searchParams.set(`provider_app_id`,e),i.searchParams.set(`requester_origin`,window.location.origin),i.searchParams.set(`smart_wallet_mode`,n?.smartWalletMode?`true`:`false`);let{address:s,providerPublicKey:c,exp:d}=await h({url:i,timeout:r});return{address:s,sharedSecret:u({privateKey:a,publicKey:c}),publicKey:o,exp:d}}var _=class{_cache={};get(e){return this._cache[e]}put(e,t){t===void 0?this.del(e):this._cache[e]=t}del(e){delete this._cache[e]}getKeys(){return Object.keys(this._cache)}},v=class{get(e){let t=localStorage.getItem(e);return t===null?void 0:JSON.parse(t)}put(e,t){t===void 0?this.del(e):localStorage.setItem(e,JSON.stringify(t))}del(e){localStorage.removeItem(e)}getKeys(){return Object.entries(localStorage).map(([e])=>e)}};function y(){return typeof window<`u`&&window.localStorage?new v:new _}var b=y();const x=({providerAppId:e,chains:t,chainId:n,apiUrl:r,connectionOpts:i,defaultPopupTimeout:a,overrideConnectUrl:o,overrideTransactUrl:s})=>new S(e,t,n,r,i,a,o,s);var S=class{providerAppId;_apiUrl;chainId;_providerDetailsLoaded=!1;_providerConnectUrl;_providerTransactUrl;_connectionOpts;chains;_sharedSecret;_publicKey;_address;_defaultPopupTimeout;_overrideConnectUrl;_overrideTransactUrl;constructor(e,t,n,r,i,a,o,s){this.providerAppId=e,this.chains=t,this._apiUrl=r??`https://auth.privy.io`,this._connectionOpts=i,this._defaultPopupTimeout=a,this._overrideConnectUrl=o,this._overrideTransactUrl=s;let c=b.get(this.STORAGE_CONNECTION_KEY),l=c&&c.exp>new Date().getTime(),u=b.get(this.STORAGE_CHAIN_ID_KEY);this.chainId=n??u??t[0].id,l?(this._sharedSecret=c.sharedSecret,this._publicKey=c.publicKey,this._address=c.address):this.clearConnection(),typeof window<`u`&&this.loadProviderDetails()}get STORAGE_CONNECTION_KEY(){let{smartWalletMode:e}=this._connectionOpts??{};return`privy-caw:${this.providerAppId}:connection${e?`:smart-wallet`:``}`}get STORAGE_CHAIN_ID_KEY(){let{smartWalletMode:e}=this._connectionOpts??{};return`privy-caw:${this.providerAppId}:connection_chain_id${e?`:smart-wallet`:``}`}async loadProviderDetails(){if(!this._providerDetailsLoaded){let{url:e,customConnectUrl:t,customTransactUrl:n}=await s({providerAppId:this.providerAppId,apiUrl:this._apiUrl});this._providerConnectUrl=this._overrideConnectUrl||t||`${e}/cross-app/connect`,this._providerTransactUrl=this._overrideTransactUrl||n||`${e}/cross-app/transact`,this._providerDetailsLoaded=!0}}async getProviderConnectUrl(){return await this.loadProviderDetails(),this._providerConnectUrl}async getProviderTransactUrl(){return await this.loadProviderDetails(),this._providerTransactUrl}clearConnection(){this._sharedSecret=void 0,this._publicKey=void 0,this._address=void 0,b.del(this.STORAGE_CONNECTION_KEY),b.del(this.STORAGE_CHAIN_ID_KEY)}get chain(){return this.chains.find(({id:e})=>e===this.chainId)}get address(){return this._address}async requestConnection(){let{address:e,sharedSecret:t,publicKey:n,exp:r}=await g({providerAppId:this.providerAppId,providerUrl:await this.getProviderConnectUrl(),connectionOpts:this._connectionOpts,defaultPopupTimeout:this._defaultPopupTimeout});b.put(this.STORAGE_CONNECTION_KEY,{address:e,sharedSecret:t,publicKey:n,exp:r}),this._address=e,this._sharedSecret=t,this._publicKey=n}switchChain({id:e}){this.chainId=e,b.put(this.STORAGE_CHAIN_ID_KEY,this.chainId)}async sendRequest(e,t){if(!this._sharedSecret||!this._publicKey)throw Error(`Must call 'eth_requestAccounts' before ${e}`);try{return await p({request:{method:e,params:t,chainId:this.chainId},apiUrl:await this.getProviderTransactUrl(),publicKey:this._publicKey,providerAppId:this.providerAppId,sharedSecret:this._sharedSecret,timeout:this._defaultPopupTimeout})}catch(e){throw e instanceof m&&e.action===`clear`&&this.clearConnection(),e}}};const C=t=>{let n=x({providerAppId:t.providerAppId,chains:t.chains,chainId:t.chainId,apiUrl:t.apiUrl,connectionOpts:{smartWalletMode:t.smartWalletMode},defaultPopupTimeout:t.defaultPopupTimeout,overrideConnectUrl:t.overrideConnectUrl,overrideTransactUrl:t.overrideTransactUrl}),r=(0,e.createPublicClient)({chain:n.chain,transport:t.transports?.[n.chain.id]??(0,e.http)()}),i={accountsChanged:[],connect:[],chainChanged:[],disconnect:[],message:[]},a=()=>{n.clearConnection(),i.accountsChanged?.forEach(e=>e([]))};return{on:(e,t)=>{i[e].push(t)},removeListener:(e,t)=>{let n=i[e].indexOf(t);n>-1&&i[e].splice(n)},request:(async o=>{t.smartWalletMode&&(o.method===`eth_sendTransaction`&&(o.method=`privy_sendSmartWalletTx`),o.method===`eth_signTransaction`&&(o.method=`privy_signSmartWalletTx`),o.method===`personal_sign`&&(o.method=`privy_signSmartWalletMessage`),o.method===`eth_signTypedData_v4`&&(o.method=`privy_signSmartWalletTypedData`));let{method:s,params:c}=o;if(console.debug(`PrivyWalletProvider.request`,{method:s,params:c}),s===`wallet_requestPermissions`||s===`eth_requestAccounts`&&!n.address){await n.requestConnection(),i.accountsChanged?.forEach(e=>e([n.address])),i.connect?.forEach(e=>e({chainId:w(n.chain.id)}));return}if(s===`eth_chainId`)return n.chain.id;if(E(s))return r.request({method:s,params:c});switch(s){case`eth_requestAccounts`:case`eth_accounts`:return n.address?[n.address]:[];case`wallet_switchEthereumChain`:return n.switchChain({id:Number(c[0].chainId)}),r=(0,e.createPublicClient)({chain:n.chain,transport:t.transports?.[n.chain.id]??(0,e.http)()}),i.chainChanged.forEach(e=>e(w(n.chain.id))),null;case`wallet_revokePermissions`:a();return;case`eth_sendTransaction`:case`eth_signTransaction`:case`eth_signTypedData_v4`:case`eth_sign`:case`privy_signSmartWalletMessage`:case`privy_signSmartWalletTypedData`:case`privy_signSmartWalletTx`:case`privy_sendSmartWalletTx`:case`personal_sign`:[`eth_sendTransaction`,`eth_signTransaction`,`privy_sendSmartWalletTx`,`privy_signSmartWalletTx`].includes(s)&&(c[0].chainId??=n.chain.id);try{return await n.sendRequest(s,c)}catch(t){throw t instanceof m&&(t.action===`clear`&&a(),t.code===void 0&&t.message===`User rejected request`)?new e.ProviderRpcError(Error(`User rejected request`),{code:4001,shortMessage:`User rejected request`}):new e.ProviderRpcError(t,{code:t.code??-1,shortMessage:t.message})}default:throw new e.ProviderRpcError(Error(`Unsupported method`),{code:4200,shortMessage:`Unsupported method: ${s}`})}})}},w=e=>`0x${e.toString(16)}`,T={web3_clientVersion:!0,web3_sha3:!0,net_listening:!0,net_peerCount:!0,net_version:!0,eth_blobBaseFee:!0,eth_blockNumber:!0,eth_call:!0,eth_chainId:!0,eth_coinbase:!0,eth_estimateGas:!0,eth_feeHistory:!0,eth_fillTransaction:!0,eth_gasPrice:!0,eth_getBalance:!0,eth_getBlockByHash:!0,eth_getBlockByNumber:!0,eth_getBlockReceipts:!0,eth_getBlockTransactionCountByHash:!0,eth_getBlockTransactionCountByNumber:!0,eth_getCode:!0,eth_getFilterChanges:!0,eth_getFilterLogs:!0,eth_getLogs:!0,eth_getProof:!0,eth_getRawTransactionByHash:!0,eth_getStorageAt:!0,eth_getTransactionByBlockHashAndIndex:!0,eth_getTransactionByBlockNumberAndIndex:!0,eth_getTransactionByHash:!0,eth_getTransactionBySenderAndNonce:!0,eth_getTransactionCount:!0,eth_getTransactionReceipt:!0,eth_getUncleByBlockHashAndIndex:!0,eth_getUncleByBlockNumberAndIndex:!0,eth_getUncleCountByBlockHash:!0,eth_getUncleCountByBlockNumber:!0,eth_maxPriorityFeePerGas:!0,eth_newBlockFilter:!0,eth_newFilter:!0,eth_newPendingTransactionFilter:!0,eth_protocolVersion:!0,eth_sendRawTransaction:!0,eth_uninstallFilter:!0,zks_estimateFee:!0,eth_createAccessList:!0,eth_simulateV1:!0},E=e=>!!T[e];Object.defineProperty(exports,"n",{enumerable:!0,get:function(){return x}}),Object.defineProperty(exports,"t",{enumerable:!0,get:function(){return C}}); //# sourceMappingURL=provider-B1HdA1aS.js.map