@dfinity/oisy-wallet-signer
Version:
A library designed to facilitate communication between a dApp and the OISY Wallet on the Internet Computer.
22 lines (20 loc) • 31.3 kB
JavaScript
var Rr=Object.create;var Xe=Object.defineProperty;var Ir=Object.getOwnPropertyDescriptor;var Cr=Object.getOwnPropertyNames;var _r=Object.getPrototypeOf,Pr=Object.prototype.hasOwnProperty;var Ar=(t,e)=>()=>(e||t((e={exports:{}}).exports,e),e.exports);var xr=(t,e,r,s)=>{if(e&&typeof e=="object"||typeof e=="function")for(let o of Cr(e))!Pr.call(t,o)&&o!==r&&Xe(t,o,{get:()=>e[o],enumerable:!(s=Ir(e,o))||s.enumerable});return t};var Nr=(t,e,r)=>(r=t!=null?Rr(_r(t)):{},xr(e||!t||!t.__esModule?Xe(r,"default",{value:t,enumerable:!0}):r,t));var kt=Ar((nn,rs)=>{rs.exports={core:{amount:"Amount",from:"From",to:"To",fee:"Fee",memo:"Memo"},icrc1_transfer:{title:"Approve the transfer of funds"},icrc2_approve:{title:"Authorize another address to withdraw from your account",address_is_allowed:"The following address is allowed to withdraw from your account",your_account:"Your account",requested_withdrawal_allowance:"Requested withdrawal allowance",withdrawal_allowance:{some:"Current withdrawal allowance",none:"The allowance will be set to {amount} {symbol} independently of any previous allowance. Until this transaction has been executed the spender can still exercise the previous allowance (if any) to it's full amount."},expiration_date:{title:"Expiration date",none:"No expiration."},approval_fee:"Approval fee",approver_account_transaction_fees:"Transaction fees to be paid by"},icrc2_transfer_from:{title:"Transfer from a withdrawal account",withdrawal_account:"Withdrawal account",sending_the_transfer_request:"Account sending the transfer request",amount_to_withdraw:"Amount to withdraw",fee_paid_by_withdrawal_account:"Fee paid by withdrawal account"}}});import{assertNonNullish as Qe,isNullish as re,nonNullish as hr}from"@dfinity/utils";var D="icrc21_call_consent_message",O="icrc25_request_permissions",se="icrc25_permissions",oe="icrc25_supported_standards",P="icrc27_accounts",ne="icrc29_status",A="icrc49_call_canister",H="granted",q="denied",T="ask_on_use",et="ICRC-21",tt="ICRC-25",rt="ICRC-27",st="ICRC-29",ot="ICRC-49";import*as ae from"zod";var wr=ae.enum([D,O,se,oe,P,ne,A]),v=wr.extract([P,A]),ce=ae.enum([H,q,T]),J=ae.enum([et,tt,rt,st,ot]);var nt=Object.values(J.Values).map(t=>({name:t,url:`https://github.com/dfinity/ICRC/blob/main/ICRCs/${t}/${t}.md`})),at=Object.values(v.Values).map(t=>({scope:{method:t},state:T})),ct=7*24*60*60*1e3;import*as u from"zod";var w="2.0",Er=u.literal(w),X=u.union([u.string(),u.number(),u.null()]),it=u.object({jsonrpc:Er,id:u.optional(X)}),B=it.extend({id:X}).merge(u.object({method:u.string(),params:u.optional(u.any())})).strict(),ee=({method:t})=>B.omit({method:!0,params:!0}).strict().extend({id:X,method:u.literal(t)}),xe=({params:t,method:e})=>B.omit({method:!0}).extend({id:X,method:u.literal(e)}).merge(u.object({params:t})),Ws=B.omit({id:!0}).strict(),pt=(n=>(n[n.PARSE_ERROR=-32700]="PARSE_ERROR",n[n.INVALID_REQUEST=-32600]="INVALID_REQUEST",n[n.METHOD_NOT_FOUND=-32601]="METHOD_NOT_FOUND",n[n.INVALID_PARAMS=-32602]="INVALID_PARAMS",n[n.INTERNAL_ERROR=-32603]="INTERNAL_ERROR",n[n.SERVER_ERROR=-32e3]="SERVER_ERROR",n))(pt||{}),br=u.union([u.number(),u.nativeEnum(pt)]),mt=u.object({code:br,message:u.string(),data:u.optional(u.never())}),Or=it.extend({id:X}),Tr=Or.extend({error:mt}).strict(),U=t=>Tr.omit({error:!0}).merge(u.object({result:t,error:mt}).partial()).strict().refine(({result:e,error:r})=>e!==void 0||r!==void 0,"Either result or error should be provided."),Ks=U(u.any());var C=({id:t,error:e,origin:r})=>{k({msg:{jsonrpc:w,id:t,error:e},origin:r})},k=({msg:t,origin:e})=>window.opener.postMessage(t,e);var ie=({message:t,...e})=>{C({...e,error:{code:2e3,message:t??"The request sent by the relying party is not supported by the signer."}})},pe=t=>{C({...t,error:{code:3001,message:"The signer has canceled the action requested by the relying party."}})},Ne=({message:t,...e})=>{C({...e,error:{code:4e3,message:t}})},we=t=>{C({...t,error:{code:3e3,message:"The signer has not granted the necessary permissions to process the request from the relying party."}})},me=t=>{C({...t,error:{code:501,message:"The signer has not registered a prompt to respond to permission requests."}})},ut=t=>{C({...t,error:{code:502,message:"The sender must match the owner of the signer."}})},dt=t=>{C({...t,error:{code:503,message:"The signer is currently processing a request and cannot handle new requests at this time."}})};var lt=({id:t,origin:e})=>{k({msg:{jsonrpc:w,id:t,result:"ready"},origin:e})},ft=({id:t,origin:e})=>{k({msg:{jsonrpc:w,id:t,result:{supportedStandards:nt}},origin:e})},ht=({id:t,origin:e,scopes:r})=>{k({msg:{jsonrpc:w,id:t,result:{scopes:r}},origin:e})},St=({id:t,origin:e,accounts:r})=>{k({msg:{jsonrpc:w,id:t,result:{accounts:r}},origin:e})},yt=({id:t,origin:e,result:r})=>{k({msg:{jsonrpc:w,id:t,result:r},origin:e})};import{mapTokenMetadata as ns}from"@dfinity/ledger-icrc";import{Principal as as}from"@dfinity/principal";import{base64ToUint8Array as Vt,isNullish as Le,notEmptyString as Gt}from"@dfinity/utils";import{IcrcLedgerCanister as Wr}from"@dfinity/ledger-icrc";import{Principal as Kr}from"@dfinity/principal";import{arrayBufferToUint8Array as bt,uint8ArrayToBase64 as Ot}from"@dfinity/utils";import{concat as vr,fromHex as gt,toHex as no}from"@dfinity/agent";import Mr from"borc";import*as F from"simple-cbor";import{SelfDescribeCborSerializer as zr}from"simple-cbor";var Ee=class{get name(){return"Principal"}get priority(){return 0}match(e){return e&&e._isPrincipal===!0}encode(e){return F.value.bytes(e.toUint8Array())}},be=class{get name(){return"Buffer"}get priority(){return 1}match(e){return e instanceof ArrayBuffer||ArrayBuffer.isView(e)}encode(e){return F.value.bytes(new Uint8Array(e))}},Oe=class{get name(){return"BigInt"}get priority(){return 1}match(e){return typeof e=="bigint"}encode(e){return e>BigInt(0)?F.value.tagged(2,F.value.bytes(gt(e.toString(16)))):F.value.tagged(3,F.value.bytes(gt((BigInt("-1")*e).toString(16))))}},ue=zr.withDefaultEncoders(!0);ue.addEncoder(new Ee);ue.addEncoder(new be);ue.addEncoder(new Oe);function Te(t){return ue.serialize(t)}var Rt=class extends Mr.Decoder{createByteString(e){return vr(...e)}createByteStringFromHeap(e,r){return e===r?new ArrayBuffer(0):new Uint8Array(this._heap.slice(e,r))}};import{Actor as Lr}from"@dfinity/agent";import{Principal as Vr}from"@dfinity/principal";import{isNullish as Gr}from"@dfinity/utils";var It=({IDL:t})=>{let e=t.Record({utc_offset_minutes:t.Opt(t.Int16),language:t.Text}),r=t.Record({metadata:e,device_spec:t.Opt(t.Variant({GenericDisplay:t.Null,LineDisplay:t.Record({characters_per_line:t.Nat16,lines_per_page:t.Nat16})}))}),s=t.Record({arg:t.Vec(t.Nat8),method:t.Text,user_preferences:r}),o=t.Variant({LineDisplayMessage:t.Record({pages:t.Vec(t.Record({lines:t.Vec(t.Text)}))}),GenericDisplayMessage:t.Text}),c=t.Record({metadata:e,consent_message:o}),n=t.Record({description:t.Text}),i=t.Variant({GenericError:t.Record({description:t.Text,error_code:t.Nat}),InsufficientPayment:n,UnsupportedCanisterCall:n,ConsentMessageUnavailable:n}),m=t.Variant({Ok:c,Err:i});return t.Service({icrc10_supported_standards:t.Func([],[t.Vec(t.Record({url:t.Text,name:t.Text}))],["query"]),icrc21_canister_call_consent_message:t.Func([s],[m],[])})};import{isNullish as Et}from"@dfinity/utils";import{Certificate as Fr,HttpAgent as $r,defaultStrategy as jr,lookupResultToBuffer as xt,pollForResponse as Dr}from"@dfinity/agent";import{bufFromBufLike as Hr}from"@dfinity/candid";import{Principal as Nt}from"@dfinity/principal";import{base64ToUint8Array as wt,isNullish as ve,nonNullish as de}from"@dfinity/utils";import{isNullish as _t,nowInBigIntNanoSeconds as Ur,uint8ArrayToBase64 as Pt}from"@dfinity/utils";import{jsonReplacer as qr,uint8ArrayToHexString as Br}from"@dfinity/utils";var Ct=async t=>{let e=JSON.stringify(t,qr),r=new TextEncoder().encode(e),s=await crypto.subtle.digest("SHA-256",r);return Br(new Uint8Array(s))};var At=()=>{let t=new Map;return async e=>{let{canister_id:r,sender:s,method_name:o,arg:c,ingress_expiry:n,nonce:i}=e.body;if(_t(i))return e;let m={canisterId:r.toString(),sender:s.toString(),method:o,arg:Pt(c),nonce:Pt(i)},d=await Ct(m),f=t.get(d);if(_t(f))return t.set(d,n),e;if(f._value<=Ur())throw Error("The request has expired and is no longer valid. Please try again with a new request.");return e.body.ingress_expiry=f,e}};import{HttpAgent as kr}from"@dfinity/agent";var L=class t{_agent;constructor(e){this._agent=e}static async create(e){let r=await kr.create(e);return new t(r)}get agent(){return this._agent}};var Me=class extends Error{},ze=class extends Error{},qe=class extends Error{},Be=class extends Error{},Ue=class extends Error{},le=class t extends L{constructor(e){super(e),this._agent.addTransform("update",At())}static async create(e){let r=await $r.create(e);return new t(r)}request=async({arg:e,canisterId:r,method:s,nonce:o})=>{let{requestDetails:c,...n}=await this._agent.call(r,{methodName:s,arg:wt(e),effectiveCanisterId:r,nonce:de(o)?wt(o):void 0});if(this.assertRequestDetails(c),ve(c))throw new Me;let i=await this.readResponse({callResponse:{requestDetails:c,...n},canisterId:r});if(de(i))return i;let{response:{status:m}}=n;if(m===202)return await this.pollForResponse({callResponse:{requestDetails:c,...n},canisterId:r});throw new ze};async readResponse({callResponse:{requestId:e,response:{body:r,status:s},requestDetails:o},canisterId:c}){if(ve(r)||!("certificate"in r))return;if(s!==200)throw new Be;let{certificate:n}=r;if(ve(this._agent.rootKey))throw new Ue;let i=await Fr.create({certificate:Hr(n),rootKey:this._agent.rootKey,canisterId:Nt.fromText(c)}),{result:m}=this.assertReply({certificate:i,requestId:e});if(m!=="valid")throw new qe;return{certificate:i,requestDetails:o}}assertRequestDetails(e){return de(e)}assertReply({certificate:e,requestId:r}){let s=[new TextEncoder().encode("request_status"),r];switch(new TextDecoder().decode(xt(e.lookup([...s,"status"])))){case"replied":let c=xt(e.lookup([...s,"reply"]));return{result:de(c)?"valid":"invalid"};case"rejected":return{result:"rejected"};default:return{result:"empty"}}}async pollForResponse({callResponse:{requestId:e,requestDetails:r},canisterId:s}){let{certificate:o}=await Dr(this._agent,Nt.fromText(s),e,jr());return{certificate:o,requestDetails:r}}};var ke="https://icp-api.io";var fe=class{#e=void 0;async getAgent({options:e,type:r}){let{owner:s}=e,o=`${s.getPrincipal().toText()}_${r}`;if(Et(this.#e)||Et(this.#e[o])){let c=await this.createAgent({options:e,type:r});return this.#e={...this.#e??{},[o]:c},c}return this.#e[o]}async createAgent({options:{owner:e,host:r},type:s}){let{hostname:o}=new URL(r??ke),c=["localhost","127.0.0.1"].includes(o),n={identity:e,host:r??ke,shouldFetchRootKey:c};return s==="default"?await L.create(n):await le.create(n)}async getDefaultAgent(e){return await this.getAgent({options:e,type:"default"})}async getCustomAgent(e){return await this.getAgent({options:e,type:"custom"})}};var he=class extends fe{#e;async consentMessage({request:e,...r}){let{icrc21_canister_call_consent_message:s}=await this.getIcrc21Actor(r);return await s(e)}async getIcrc21Actor({canisterId:e,...r}){let s=e instanceof Vr?e.toText():e,{[s]:o}=this.#e??{[s]:void 0};if(Gr(o)){let c=await this.createActor({canisterId:e,idlFactory:It,...r});return this.#e={...this.#e??{},[s]:c},c}return o}async createActor({canisterId:e,idlFactory:r,owner:s,host:o}){let{agent:c}=await this.getDefaultAgent({host:o,owner:s});return await Lr.createActor(r,{agent:c,canisterId:e})}};var Se=class extends he{async call({owner:e,host:r,params:{canisterId:s,method:o,arg:c,nonce:n}}){let m=await(await this.getCustomAgent({host:r,owner:e})).request({canisterId:s,method:o,arg:c,nonce:n});return this.encodeResult(m)}async ledgerMetadata({host:e,owner:r,params:{canisterId:s}}){let{agent:o}=await this.getDefaultAgent({host:e,owner:r}),{metadata:c}=Wr.create({agent:o,canisterId:Kr.fromText(s)});return await c({certified:!0})}encodeResult({requestDetails:e,certificate:r}){let s=Ot(bt(Te(r.cert))),o=Ot(bt(Te(e)));return{certificate:s,contentMap:o}}};import{encodeIcrcAccount as $}from"@dfinity/ledger-icrc";import{fromNullable as g,isNullish as ss,nonNullish as Ft}from"@dfinity/utils";import{IDL as l}from"@dfinity/candid";var Tt=l.Vec(l.Nat8),Qr=l.Record({owner:l.Principal,subaccount:l.Opt(Tt)}),vt=l.Nat64,Mt=l.Record({to:Qr,fee:l.Opt(l.Nat),memo:l.Opt(l.Vec(l.Nat8)),from_subaccount:l.Opt(Tt),created_at_time:l.Opt(vt),amount:l.Nat}),Yr=l.Variant({GenericError:l.Record({message:l.Text,error_code:l.Nat}),TemporarilyUnavailable:l.Null,BadBurn:l.Record({min_burn_amount:l.Nat}),Duplicate:l.Record({duplicate_of:l.Nat}),BadFee:l.Record({expected_fee:l.Nat}),CreatedInFuture:l.Record({ledger_time:vt}),TooOld:l.Null,InsufficientFunds:l.Record({balance:l.Nat})}),Go=l.Variant({Ok:l.Nat,Err:Yr});import{IDL as a}from"@dfinity/candid";var Fe=a.Record({owner:a.Principal,subaccount:a.Opt(a.Vec(a.Nat8))}),zt=a.Record({fee:a.Opt(a.Nat),memo:a.Opt(a.Vec(a.Nat8)),from_subaccount:a.Opt(a.Vec(a.Nat8)),created_at_time:a.Opt(a.Nat64),amount:a.Nat,expected_allowance:a.Opt(a.Nat),expires_at:a.Opt(a.Nat64),spender:Fe}),qt=a.Record({to:Fe,fee:a.Opt(a.Nat),spender_subaccount:a.Opt(a.Vec(a.Nat8)),from:Fe,memo:a.Opt(a.Vec(a.Nat8)),created_at_time:a.Opt(a.Nat64),amount:a.Nat}),Zr=a.Variant({GenericError:a.Record({message:a.Text,error_code:a.Nat}),TemporarilyUnavailable:a.Null,Duplicate:a.Record({duplicate_of:a.Nat}),BadFee:a.Record({expected_fee:a.Nat}),AllowanceChanged:a.Record({current_allowance:a.Nat}),CreatedInFuture:a.Record({ledger_time:a.Nat64}),TooOld:a.Null,Expired:a.Record({ledger_time:a.Nat64}),InsufficientFunds:a.Record({balance:a.Nat})}),Jr=a.Variant({GenericError:a.Record({message:a.Text,error_code:a.Nat}),TemporarilyUnavailable:a.Null,InsufficientAllowance:a.Record({allowance:a.Nat}),BadBurn:a.Record({min_burn_amount:a.Nat}),Duplicate:a.Record({duplicate_of:a.Nat}),BadFee:a.Record({expected_fee:a.Nat}),CreatedInFuture:a.Record({ledger_time:a.Nat64}),TooOld:a.Null,InsufficientFunds:a.Record({balance:a.Nat})}),Qo=a.Variant({Ok:a.Nat,Err:Zr}),Yo=a.Variant({Ok:a.Nat,Err:Jr});import{arrayOfNumberToUint8Array as Xr,uint8ArrayToHexString as es}from"@dfinity/utils";var Bt=t=>{let e=t instanceof Uint8Array?t:Xr(t);try{return new TextDecoder("utf-8").decode(e)}catch{return`0x${es(t)}`}};var E=({amount:t,decimals:e})=>{let r=Number(t)/10**e,s=e>=1?1:e;return new Intl.NumberFormat("en-US",{minimumFractionDigits:s,maximumFractionDigits:e}).format(r)},Ut=t=>{let e={weekday:"short",month:"short",day:"numeric",year:"numeric",hour:"2-digit",minute:"2-digit",second:"2-digit",hour12:!1,timeZone:"UTC",timeZoneName:"short"};return new Date(Number(t/1000000n)).toLocaleDateString("en",e)};import{IDL as ts}from"@dfinity/candid";import{uint8ArrayToBase64 as sn}from"@dfinity/utils";var ye=({recordClass:t,bytes:e})=>{let r=ts.decode([t],e);if(r.length!==1)throw new Error("More than one object returned. This is unexpected.");let[s]=r;return s};var $t=async({arg:t,owner:e,token:{symbol:r,decimals:s,fee:o}})=>await He({arg:t,fn:n=>{let{amount:i,from_subaccount:m,to:{owner:d,subaccount:f},fee:h,memo:b}=ye({recordClass:Mt,bytes:t}),{core:{amount:x,from:z,to:G,fee:W},icrc1_transfer:{title:K}}=n,N=[`# ${K}`];N.push(`${S(x)}
${E({amount:i,decimals:s})} ${r}`);let Q=g(m),Y=$({owner:e,subaccount:Q});N.push(`${S(z)}
${Y}`);let _=$({owner:d,subaccount:g(f)});N.push(`${S(G)}
${_}`),N.push(`${S(W)}
${E({amount:g(h)??o,decimals:s})} ${r}`);let Z=De({memo:b,en:n});return{message:[...N,...Z]}}}),jt=async({arg:t,owner:e,token:{symbol:r,decimals:s,fee:o}})=>await He({arg:t,fn:n=>{let{spender:{owner:i,subaccount:m},from_subaccount:d,amount:f,expected_allowance:h,expires_at:b,fee:x,memo:z}=ye({recordClass:zt,bytes:t}),{icrc2_approve:{title:G,address_is_allowed:W,your_account:K,requested_withdrawal_allowance:N,withdrawal_allowance:{none:Q,some:Y},expiration_date:{title:_,none:Z},approval_fee:_e,approver_account_transaction_fees:Pe}}=n,I=[`# ${G}`],Ae=$({owner:i,subaccount:g(m)});I.push(`${S(W)}
${Ae}`);let yr=g(d),Ye=$({owner:e,subaccount:yr});I.push(`${S(K)}
${Ye}`),I.push(`${S(N)}
${E({amount:f,decimals:s})} ${r}`);let Ze=g(h);Ft(Ze)?I.push(`${S(Y)}
${E({amount:Ze,decimals:s})} ${r}`):I.push(`\u26A0 ${Q.replace("{amount}",E({amount:f,decimals:s})).replace("{symbol}",r)}`);let Je=g(b);I.push(`${S(_)}
${Ft(Je)?Ut(Je):Z}`),I.push(`${S(_e)}
${E({amount:g(x)??o,decimals:s})} ${r}`),I.push(`${S(Pe)}
${Ye}`);let gr=De({memo:z,en:n});return{message:[...I,...gr]}}}),Dt=async({arg:t,owner:e,token:{symbol:r,decimals:s,fee:o}})=>await He({arg:t,fn:n=>{let{from:{owner:i,subaccount:m},to:{owner:d,subaccount:f},spender_subaccount:h,amount:b,fee:x,memo:z}=ye({recordClass:qt,bytes:t}),{core:{to:G},icrc2_transfer_from:{title:W,withdrawal_account:K,sending_the_transfer_request:N,amount_to_withdraw:Q,fee_paid_by_withdrawal_account:Y}}=n,_=[`# ${W}`],Z=$({owner:i,subaccount:g(m)});_.push(`${S(K)}
${Z}`);let _e=g(h),Pe=$({owner:e,subaccount:_e});_.push(`${S(N)}
${Pe}`),_.push(`${S(Q)}
${E({amount:b,decimals:s})} ${r}`);let I=$({owner:d,subaccount:g(f)});_.push(`${S(G)}
${I}`),_.push(`${S(Y)}
${E({amount:g(x)??o,decimals:s})} ${r}`);let Ae=De({memo:z,en:n});return{message:[..._,...Ae]}}}),S=t=>`**${t}:**`,De=({memo:t,en:e})=>{let r=g(t);if(ss(r))return[];let{core:{memo:s}}=e;return[`${S(s)}
${Bt(r)}`]},He=async({fn:t,arg:e})=>{try{os({arg:e});let{default:r}=await Promise.resolve().then(()=>Nr(kt(),1)),{message:s}=t(r);return{Ok:{metadata:{language:"en",utc_offset_minutes:[]},consent_message:{GenericDisplayMessage:s.join(`
`)}}}}catch(r){return{Err:r}}},$e=class extends Error{},os=({arg:t})=>{if(t.byteLength>je)throw new $e(`The argument size is too large. The maximum allowed size is ${je} bytes.`)};var je=500,Ht={icrc1_transfer:$t,icrc2_approve:jt,icrc2_transfer_from:Dt};var Lt=t=>"GenericError"in t?`Error: ${t.GenericError.description} (Code: ${t.GenericError.error_code})`:"InsufficientPayment"in t?`Insufficient Payment: ${t.InsufficientPayment.description}`:"UnsupportedCanisterCall"in t?`Unsupported Canister Call: ${t.UnsupportedCanisterCall.description}`:"ConsentMessageUnavailable"in t?`Consent Message Unavailable: ${t.ConsentMessageUnavailable.description}`:"Unknown error";var ge=class{#e=new Se;async assertAndPromptConsentMessage({params:{sender:e,...r},prompt:s,notify:o,options:{owner:c,host:n}}){let{result:i}=this.assertSender({sender:e,owner:c,notify:o});if(i==="invalid")return{result:"error"};if(Le(s))return me(o),{result:"error"};let{origin:m}=o;s({origin:m,status:"loading"});try{let d=await this.loadConsentMessage({params:r,options:{host:n,owner:c}});if("Err"in d){let{Err:h}=d;return s({origin:m,status:"error",details:h}),ie({...o,message:Lt(h)}),{result:"error"}}let{result:f}=await this.promptConsentMessage({consentInfo:d,prompt:s,origin:m});return f==="rejected"&&pe(o),{result:f}}catch(d){return this.notifyError({err:d,prompt:s,notify:o})}}async callCanister({params:e,prompt:r,notify:s,options:o}){let{origin:c}=s;r?.({origin:c,status:"executing"});try{let n=await this.#e.call({...o,params:e});return yt({...s,result:n}),r?.({origin:c,status:"result",...n}),{result:"success"}}catch(n){return r?.({origin:c,status:"error",details:n}),Ne({...s,message:n instanceof Error&&Gt(n.message)?n.message:"An unknown error occurred"}),{result:"error"}}}assertSender({notify:e,owner:r,sender:s}){return r.getPrincipal().toText()===as.fromText(s).toText()?{result:"valid"}:(ut(e),{result:"invalid"})}async callConsentMessage({params:{canisterId:e,method:r,arg:s},options:{owner:o,host:c}}){return await this.#e.consentMessage({owner:o,host:c,canisterId:e,request:{method:r,arg:Vt(s),user_preferences:{metadata:{language:"en",utc_offset_minutes:[]},device_spec:[]}}})}notifyError({err:e,notify:r,prompt:s}){let{origin:o}=r;return s({origin:o,status:"error",details:e}),Ne({...r,message:e instanceof Error&&Gt(e.message)?e.message:"An unknown error occurred"}),{result:"error"}}async promptConsentMessage({prompt:e,...r}){return await new Promise(o=>{e({status:"result",approve:()=>{o({result:"approved"})},reject:()=>{o({result:"rejected"})},...r})})}async loadConsentMessage(e){try{return await this.callConsentMessage(e)}catch(r){let s=await this.tryBuildConsentMessageOnError(e);if("Warn"in s)return s;throw r}}async tryBuildConsentMessageOnError({params:{method:e,arg:r,canisterId:s},options:{owner:o,host:c}}){let n=Ht[e];if(Le(n))return{NoFallback:null};try{let i=await this.#e.ledgerMetadata({params:{canisterId:s},host:c,owner:o}),m=ns(i);if(Le(m))return{Err:new Error("Incomplete token metadata.")};let d=await n({arg:Vt(r),token:m,owner:o.getPrincipal()});return"Err"in d?{Err:d.Err}:{Warn:{consentInfo:d.Ok,method:e,arg:r,canisterId:s}}}catch(i){return{Err:i}}}};import{isNullish as is}from"@dfinity/utils";import{nonNullish as cs}from"@dfinity/utils";var Wt=({key:t,value:e})=>{try{localStorage.setItem(t,JSON.stringify(e))}catch(r){console.error(r)}};var Ve=({key:t})=>{try{let e=localStorage.getItem(t);return cs(e)?JSON.parse(e):void 0}catch(e){console.error(e);return}};var ps="oisy_signer",Kt=({owner:t,origin:e})=>`${ps}_${e}_${t.toText()}`,Qt=({scopes:t,...e})=>{let r=Kt(e),s=Ve({key:r}),o=(s?.scopes??[]).filter(({scope:{method:m}})=>t.find(({scope:{method:d}})=>m===d)===void 0),c=Date.now(),n=t.reduce((m,{scope:{method:d,...f},...h})=>{let b=(s?.scopes??[]).find(({scope:{method:x}})=>x===d);return[...m,{...h,scope:{...f,method:d},createdAt:b?.createdAt??c,updatedAt:c}]},[]),i={scopes:[...o,...n],createdAt:s?.createdAt??c,updatedAt:c};Wt({key:r,value:i})},Ge=({sessionOptions:t,...e})=>{let r=Ve({key:Kt(e)});if(!is(r))return r.scopes.filter(({updatedAt:s})=>s>=Date.now()-(t?.sessionPermissionExpirationInMilliseconds??ct)).map(({updatedAt:s,createdAt:o,...c})=>({...c}))},Yt=({method:t,...e})=>Ge(e)?.find(({scope:{method:s}})=>s===t)?.state??T;import{base64ToUint8Array as ms,isNullish as us}from"@dfinity/utils";import{PrincipalTextSchema as Jt}from"@dfinity/zod-schemas";import*as R from"zod";import*as Zt from"zod";var M=Zt.string().refine(t=>{try{return btoa(atob(t))===t}catch{return!1}},{message:"Invalid base64 string"});var Dn=R.object({scopes:R.array(R.object({method:v})).min(1)}),ds=R.object({scopes:R.array(R.object({method:R.string()})).min(1)}),Xt=xe({method:O,params:ds}),er=ee({method:se}),tr=ee({method:oe}),rr=ee({method:ne}),sr=ee({method:P}),ls=R.string().trim().min(1),We=R.object({canisterId:Jt,sender:Jt,method:ls,arg:M,nonce:M.optional().refine(t=>{try{return us(t)||ms(t).length<=32}catch{return!1}},{message:"Nonce must be a Uint8Array with a maximum length of 32 bytes"})}),or=xe({method:A,params:We});var V=class extends Error{};import*as p from"zod";import{base64ToUint8Array as fs}from"@dfinity/utils";import{PrincipalTextSchema as hs}from"@dfinity/zod-schemas";import*as Re from"zod";var Ss=M.refine(t=>{try{return fs(t).length===32}catch{return!1}},{message:"Subaccount must be exactly 32 bytes long."}),ys=Re.object({owner:hs,subaccount:Ss.optional()}).strict(),Ie=Re.array(ys).min(1);import{UrlSchema as gs}from"@dfinity/zod-schemas";import*as y from"zod";var Rs=y.object({method:v}),Is=y.object({scope:Rs,state:ce}).strict(),Ce=y.array(Is),Cs=y.object({scopes:Ce}).strict(),ea=U(Cs),_s=/^https:\/\/github\.com\/dfinity\/ICRC\/blob\/main\/ICRCs\/ICRC-\d+\/ICRC-\d+\.md$/,Ps=y.string().url().regex(_s).refine(t=>{try{gs.parse(t)}catch{return!1}let e=/(ICRC-\d+)\.md/g.exec(t);if(e===null)return!1;let[r,s]=e;return Object.keys(J.Values).includes(s)},{message:"The URL does not match any of the IcrcStandard values."}),As=y.array(y.object({name:J,url:Ps}).strict()).min(1),ta=U(y.object({supportedStandards:As})),ra=U(y.literal("ready")),sa=U(y.object({accounts:Ie})),Ke=y.object({contentMap:M,certificate:M}).strict(),oa=U(Ke.strict());import{UrlSchema as xs}from"@dfinity/zod-schemas";var nr=xs;var la=p.enum([D,O,P,A]),j=p.object({origin:nr}),ar=p.function().returns(p.void()),te=p.enum(["result","error"]),cr=j.extend({status:p.literal(te.enum.error),details:p.unknown().optional()}),Ns=p.function().args(Ce).returns(p.void()),ws=j.extend({requestedScopes:Ce,confirm:Ns}),ir=p.function().args(ws).returns(p.void()),Es=p.function().args(Ie).returns(p.void()),bs=j.extend({approve:Es,reject:ar}),pr=p.function().args(bs).returns(p.void()),Os=p.function().returns(p.void()),mr=p.enum(["loading"]),fa=mr.or(te),Ts=j.extend({status:p.literal(mr.enum.loading)}),ur=p.custom(),vs=p.object({Ok:ur}),Ms=p.object({Warn:We.pick({canisterId:!0,method:!0,arg:!0}).extend({consentInfo:ur})}),zs=p.union([vs,Ms]),qs=j.extend({status:p.literal(te.enum.result),consentInfo:zs,approve:Os,reject:ar}),Bs=p.union([Ts,qs,cr]),dr=p.function().args(Bs).returns(p.void()),lr=p.enum(["executing"]),ha=lr.or(te),Us=j.extend({status:p.literal(lr.enum.executing)}),ks=p.intersection(j.extend({status:p.literal(te.enum.result)}),Ke),Fs=p.union([Us,ks,cr]),fr=p.function().args(Fs).returns(p.void());var Sr=class t{#e;#t;#r;#s;#n;#a;#o=!1;#c=new ge;constructor(e){this.#e=e,window.addEventListener("message",this.onMessageListener)}static init(e){return new t(e)}disconnect=()=>{window.removeEventListener("message",this.onMessageListener),this.#t=null};onMessageListener=e=>{this.onMessage(e)};onMessage=async e=>{let{data:r,origin:s}=e,{success:o,data:c}=B.safeParse(r);if(!o)return;let{handled:n}=this.handleReadOnlyMessage(e);if(n)return;let{busy:i}=this.assertNotBusy(e);if(i)return;let{handled:m}=await this.handleMessage(e);m||ie({id:c?.id??null,origin:s})};handleReadOnlyMessage(e){let{handled:r}=this.handleStatusRequest(e);if(r)return{handled:!0};let{handled:s}=this.handleSupportedStandards(e);return s?{handled:!0}:{handled:!1}}async handleMessage(e){let{valid:r}=this.assertNotUndefinedAndSameOrigin(e);if(!r)return{handled:!0};let{handled:s}=this.handlePermissionsRequest(e);if(s)return{handled:!0};let{handled:o}=await this.handleRequestPermissionsRequest(e);if(o)return{handled:!0};let{handled:c}=await this.handleAccounts(e);if(c)return{handled:!0};let{handled:n}=await this.handleCallCanister(e);return n?{handled:!0}:{handled:!1}}setWalletOrigin({origin:e}){hr(this.#t)||(this.#t=e)}assertUndefinedOrSameOrigin({data:e,origin:r}){if(hr(this.#t)&&this.#t!==r){let{data:s}=B.safeParse(e);return C({id:s?.id??null,origin:r,error:{code:500,message:"The relying party's origin is not permitted to obtain the status of the signer."}}),{valid:!1}}return{valid:!0}}assertNotBusy({data:e,origin:r}){return this.#o?(dt({id:e?.id??null,origin:r}),{busy:!0}):{busy:!1}}async handleWithBusy(e){this.#o=!0;try{return await e()}finally{this.setIdle()}}setIdle(){this.#o=!1}assertNotUndefinedAndSameOrigin({data:e,origin:r}){if(re(this.#t)||this.#t!==r){let{data:s}=B.safeParse(e);return C({id:s?.id??null,origin:r,error:{code:500,message:re(this.#t)?"The relying party has not established a connection to the signer.":"The relying party's origin is not allowed to interact with the signer."}}),{valid:!1}}return{valid:!0}}register=({method:e,prompt:r})=>{switch(e){case D:{dr.parse(r),this.#n=r;return}case O:{ir.parse(r),this.#r=r;return}case P:{pr.parse(r),this.#s=r;return}case A:{fr.parse(r),this.#a=r;return}}throw new Error("The specified method is not supported. Please ensure you are using a supported standard.")};handleStatusRequest({data:e,origin:r,...s}){let{success:o,data:c}=rr.safeParse(e);if(o){let{valid:n}=this.assertUndefinedOrSameOrigin({data:e,origin:r,...s});if(!n)return{handled:!0};let{id:i}=c;return lt({id:i,origin:r}),this.setWalletOrigin({origin:r}),{handled:!0}}return{handled:!1}}handleSupportedStandards({data:e,origin:r}){let{success:s,data:o}=tr.safeParse(e);if(s){let{id:c}=o;return ft({id:c,origin:r}),{handled:!0}}return{handled:!1}}handlePermissionsRequest({data:e}){let{success:r,data:s}=er.safeParse(e);if(r){let{id:o}=s;return this.emitPermissions({id:o}),{handled:!0}}return{handled:!1}}async handleRequestPermissionsRequest({data:e,origin:r}){let s=async()=>{let{success:o,data:c}=Xt.safeParse(e);if(!o)return{handled:!1};let{id:n,params:{scopes:i}}=c;if(re(this.#r))return this.assertWalletOriginAndNotifyMissingPromptError(n),{handled:!0};let m=i.filter(({method:f})=>v.safeParse(f).success).map(({method:f})=>({scope:{method:f},state:ce.enum.denied})).sort(({scope:{method:f}},{scope:{method:h}})=>f.localeCompare(h)),d=async()=>{let f=await this.promptPermissions({requestedScopes:m,origin:r});this.savePermissions({scopes:f}),this.emitPermissions({id:n})};return await this.prompt({requestId:n,promptFn:d}),{handled:!0}};return await this.handleWithBusy(s)}async promptPermissions(e){return await new Promise((s,o)=>{let c=n=>{s(n)};if(re(this.#r)){o(new V);return}this.#r({...e,confirm:c})})}emitPermissions({id:e}){Qe(this.#t,"The relying party's origin is unknown.");let{owner:r,sessionOptions:s}=this.#e,o=Ge({owner:r.getPrincipal(),origin:this.#t,sessionOptions:s}),c=[...o??[],...at.filter(({scope:{method:n}})=>(o??[]).find(({scope:{method:i}})=>i===n)===void 0)];ht({id:e,origin:this.#t,scopes:c})}assertWalletOriginAndNotifyMissingPromptError(e){Qe(this.#t,"The relying party's origin is unknown."),me({id:e??null,origin:this.#t})}savePermissions({scopes:e}){Qe(this.#t,"The relying party's origin is unknown.");let{owner:r}=this.#e;Qt({owner:r.getPrincipal(),origin:this.#t,scopes:e})}async handleAccounts({data:e,origin:r}){let s=async()=>{let{success:o,data:c}=sr.safeParse(e);if(!o)return{handled:!1};let{id:n}=c,i=async()=>{let d=async()=>{let{result:f,accounts:h}=await this.promptAccounts({origin:r});if(f==="rejected"){pe({id:n,origin:r});return}St({accounts:h,id:n,origin:r})};await this.prompt({requestId:n,promptFn:d})};switch(await this.assertAndPromptPermissions({method:P,requestId:n,origin:r})){case q:{we({id:n??null,origin:r});break}case H:{await i();break}}return{handled:!0}};return await this.handleWithBusy(s)}async prompt({requestId:e,promptFn:r}){try{await r()}catch(s){if(s instanceof V){this.assertWalletOriginAndNotifyMissingPromptError(e);return}throw s}}async promptAccounts(e){return await new Promise((s,o)=>{let c=()=>{s({result:"rejected",accounts:[]})},n=i=>{s({result:"approved",accounts:i})};if(re(this.#s)){o(new V);return}this.#s({approve:n,reject:c,...e})})}async handleCallCanister({data:e,origin:r}){let s=async()=>{let{success:o,data:c}=or.safeParse(e);if(!o)return{handled:!1};let{id:n,params:i}=c;if(await this.assertAndPromptPermissions({method:A,requestId:n,origin:r})===q)return we({id:n??null,origin:r}),{handled:!0};let d={id:n,origin:r},{result:f}=await this.#c.assertAndPromptConsentMessage({notify:d,params:i,prompt:this.#n,options:this.#e});return f!=="approved"?{handled:!0}:(await this.#c.callCanister({notify:d,params:i,options:this.#e,prompt:this.#a}),{handled:!0})};return await this.handleWithBusy(s)}async assertAndPromptPermissions({method:e,origin:r,requestId:s}){let{owner:o}=this.#e,c=Yt({owner:o.getPrincipal(),origin:r,method:e});switch(c){case T:return await new Promise((i,m)=>{let d=async()=>{let f=[{scope:{method:e},state:q}],h=await this.promptPermissions({requestedScopes:f,origin:r});if(this.savePermissions({scopes:h}),h.find(({scope:{method:x},state:z})=>x===e&&z===H)!==void 0){i(H);return}i(q)};this.prompt({requestId:s,promptFn:d}).catch(f=>{m(f)})});default:return c}}};export{Sr as Signer};
//# sourceMappingURL=signer.js.map