UNPKG

@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) 30.8 kB
var hr=Object.create;var Ze=Object.defineProperty;var Sr=Object.getOwnPropertyDescriptor;var yr=Object.getOwnPropertyNames;var Rr=Object.getPrototypeOf,gr=Object.prototype.hasOwnProperty;var Ir=(t,e)=>()=>(e||t((e={exports:{}}).exports,e),e.exports);var Cr=(t,e,r,s)=>{if(e&&typeof e=="object"||typeof e=="function")for(let o of yr(e))!gr.call(t,o)&&o!==r&&Ze(t,o,{get:()=>e[o],enumerable:!(s=Sr(e,o))||s.enumerable});return t};var _r=(t,e,r)=>(r=t!=null?hr(Rr(t)):{},Cr(e||!t||!t.__esModule?Ze(r,"default",{value:t,enumerable:!0}):r,t));var Mt=Ir((tn,Xr)=>{Xr.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 Ge,isNullish as re,nonNullish as ur}from"@dfinity/utils";var B="icrc21_call_consent_message",b="icrc25_request_permissions",se="icrc25_permissions",oe="icrc25_supported_standards",P="icrc27_accounts",ne="icrc29_status",A="icrc49_call_canister",L="granted",k="denied",v="ask_on_use",Qe="ICRC-21",Ye="ICRC-25",Je="ICRC-27",Xe="ICRC-29",et="ICRC-49";import*as ae from"zod/v4";var Pr=ae.enum([B,b,se,oe,P,ne,A]),M=Pr.extract([P,A]),ce=ae.enum([L,k,v]),J=ae.enum([Qe,Ye,Je,Xe,et]);var tt=Object.values(J.enum).map(t=>({name:t,url:`https://github.com/dfinity/ICRC/blob/main/ICRCs/${t}/${t}.md`})),rt=Object.values(M.enum).map(t=>({scope:{method:t},state:v})),st=7*24*60*60*1e3;import*as u from"zod/v4";var w="2.0",Ar=u.literal(w),X=u.union([u.string(),u.number(),u.null()]),ot=u.object({jsonrpc:Ar,id:u.optional(X)}),U=ot.extend({id:X}).merge(u.object({method:u.string(),params:u.optional(u.any())})).strict(),ee=({method:t})=>U.omit({method:!0,params:!0}).strict().extend({id:X,method:u.literal(t)}),Ae=({params:t,method:e})=>U.omit({method:!0}).extend({id:X,method:u.literal(e)}).merge(u.object({params:t})),Gs=U.omit({id:!0}).strict(),nt=(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))(nt||{}),xr=u.union([u.number(),u.nativeEnum(nt)]),at=u.object({code:xr,message:u.string(),data:u.optional(u.never())}),Nr=ot.extend({id:X}),wr=Nr.extend({error:at}).strict(),F=t=>wr.omit({error:!0}).merge(u.object({result:t,error:at}).partial()).strict().refine(({result:e,error:r})=>e!==void 0||r!==void 0,"Either result or error should be provided."),Vs=F(u.any());var C=({id:t,error:e,origin:r})=>{j({msg:{jsonrpc:w,id:t,error:e},origin:r})},j=({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."}})},xe=({message:t,...e})=>{C({...e,error:{code:4e3,message:t}})},Ne=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."}})},ct=t=>{C({...t,error:{code:502,message:"The sender must match the owner of the signer."}})},it=t=>{C({...t,error:{code:503,message:"The signer is currently processing a request and cannot handle new requests at this time."}})};var pt=({id:t,origin:e})=>{j({msg:{jsonrpc:w,id:t,result:"ready"},origin:e})},mt=({id:t,origin:e})=>{j({msg:{jsonrpc:w,id:t,result:{supportedStandards:tt}},origin:e})},ut=({id:t,origin:e,scopes:r})=>{j({msg:{jsonrpc:w,id:t,result:{scopes:r}},origin:e})},dt=({id:t,origin:e,accounts:r})=>{j({msg:{jsonrpc:w,id:t,result:{accounts:r}},origin:e})},lt=({id:t,origin:e,result:r})=>{j({msg:{jsonrpc:w,id:t,result:r},origin:e})};import{uint8ToBuf as rs}from"@dfinity/agent";import{mapTokenMetadata as ss}from"@dfinity/ledger-icrc";import{Principal as os}from"@dfinity/principal";import{base64ToUint8Array as Dt,isNullish as De,notEmptyString as $t}from"@dfinity/utils";import{encode as Br,encodeWithSelfDescribedTag as Lr}from"@dfinity/cbor";import{IcrcLedgerCanister as Hr}from"@dfinity/ledger-icrc";import{Principal as Gr}from"@dfinity/principal";import{uint8ArrayToBase64 as xt}from"@dfinity/utils";import{Expiry as Tr}from"@dfinity/agent";import{nonNullish as Or}from"@dfinity/utils";import{Principal as Er}from"@dfinity/principal";import{z as we}from"zod/v4";var ft=we.strictObject({_isPrincipal:we.literal(!0),_arr:we.instanceof(Uint8Array)}).transform(t=>Er.from(t));var ht=(t,e)=>{if(e==="ingress_expiry"&&Or(t)&&t instanceof Tr)return t._value;if(["sender","canister_id"].includes(e??"")){let{success:r,data:s}=ft.safeParse(t);if(r)return s.toUint8Array()}return t};import{Actor as jr}from"@dfinity/agent";import{Principal as Dr}from"@dfinity/principal";import{isNullish as $r}from"@dfinity/utils";var St=({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}),p=t.Variant({GenericError:t.Record({description:t.Text,error_code:t.Nat}),InsufficientPayment:n,UnsupportedCanisterCall:n,ConsentMessageUnavailable:n}),m=t.Variant({Ok:c,Err:p});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 At}from"@dfinity/utils";import{Certificate as zr,HttpAgent as qr,defaultStrategy as kr,lookupResultToBuffer as It,pollForResponse as Ur,uint8ToBuf as Ct}from"@dfinity/agent";import{bufFromBufLike as Fr}from"@dfinity/candid";import{Principal as _t}from"@dfinity/principal";import{base64ToUint8Array as Pt,isNullish as Ee,nonNullish as ue}from"@dfinity/utils";import{hashObject as br,isNullish as yt,nowInBigIntNanoSeconds as vr,uint8ArrayToBase64 as Rt}from"@dfinity/utils";var gt=()=>{let t=new Map;return async e=>{let{canister_id:r,sender:s,method_name:o,arg:c,ingress_expiry:n,nonce:p}=e.body;if(yt(p))return e;let m={canisterId:r.toString(),sender:s.toString(),method:o,arg:Rt(c),nonce:Rt(p)},d=await br(m),f=t.get(d);if(yt(f))return t.set(d,n),e;if(f._value<=vr())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 Mr}from"@dfinity/agent";var H=class t{_agent;constructor(e){this._agent=e}static async create(e){let r=await Mr.create(e);return new t(r)}get agent(){return this._agent}};var Te=class extends Error{},Oe=class extends Error{},be=class extends Error{},ve=class extends Error{},Me=class extends Error{},de=class t extends H{constructor(e){super(e),this._agent.addTransform("update",gt())}static async create(e){let r=await qr.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:Ct(Pt(e)),effectiveCanisterId:r,nonce:ue(o)?Pt(o):void 0});if(this.assertRequestDetails(c),Ee(c))throw new Te;let p=await this.readResponse({callResponse:{requestDetails:c,...n},canisterId:r});if(ue(p))return p;let{response:{status:m}}=n;if(m===202)return await this.pollForResponse({callResponse:{requestDetails:c,...n},canisterId:r});throw new Oe};async readResponse({callResponse:{requestId:e,response:{body:r,status:s},requestDetails:o},canisterId:c}){if(Ee(r)||!("certificate"in r))return;if(s!==200)throw new ve;let{certificate:n}=r;if(Ee(this._agent.rootKey))throw new Me;let p=await zr.create({certificate:Fr(n),rootKey:this._agent.rootKey,canisterId:_t.fromText(c)}),{result:m}=this.assertReply({certificate:p,requestId:e});if(m!=="valid")throw new be;return{certificate:p,requestDetails:o}}assertRequestDetails(e){return ue(e)}assertReply({certificate:e,requestId:r}){let s=[Ct(new TextEncoder().encode("request_status")),r];switch(new TextDecoder().decode(It(e.lookup([...s,"status"])))){case"replied":let c=It(e.lookup([...s,"reply"]));return{result:ue(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 Ur(this._agent,_t.fromText(s),e,kr());return{certificate:o,requestDetails:r}}};var ze="https://icp-api.io";var le=class{#e=void 0;async getAgent({options:e,type:r}){let{owner:s}=e,o=`${s.getPrincipal().toText()}_${r}`;if(At(this.#e)||At(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??ze),c=["localhost","127.0.0.1"].includes(o),n={identity:e,host:r??ze,shouldFetchRootKey:c};return s==="default"?await H.create(n):await de.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 fe=class extends le{#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 Dr?e.toText():e,{[s]:o}=this.#e??{[s]:void 0};if($r(o)){let c=await this.createActor({canisterId:e,idlFactory:St,...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 jr.createActor(r,{agent:c,canisterId:e})}};var he=class extends fe{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}=Hr.create({agent:o,canisterId:Gr.fromText(s)});return await c({certified:!0})}encodeResult({requestDetails:e,certificate:r}){let s=xt(Lr(r.cert)),o=xt(Br(e,ht));return{certificate:s,contentMap:o}}};import{encodeIcrcAccount as D}from"@dfinity/ledger-icrc";import{fromNullable as R,isNullish as es,nonNullish as zt}from"@dfinity/utils";import{IDL as l}from"@dfinity/candid";var Nt=l.Vec(l.Nat8),Vr=l.Record({owner:l.Principal,subaccount:l.Opt(Nt)}),wt=l.Nat64,Et=l.Record({to:Vr,fee:l.Opt(l.Nat),memo:l.Opt(l.Vec(l.Nat8)),from_subaccount:l.Opt(Nt),created_at_time:l.Opt(wt),amount:l.Nat}),Wr=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:wt}),TooOld:l.Null,InsufficientFunds:l.Record({balance:l.Nat})}),Bo=l.Variant({Ok:l.Nat,Err:Wr});import{IDL as a}from"@dfinity/candid";var qe=a.Record({owner:a.Principal,subaccount:a.Opt(a.Vec(a.Nat8))}),Tt=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:qe}),Ot=a.Record({to:qe,fee:a.Opt(a.Nat),spender_subaccount:a.Opt(a.Vec(a.Nat8)),from:qe,memo:a.Opt(a.Vec(a.Nat8)),created_at_time:a.Opt(a.Nat64),amount:a.Nat}),Kr=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})}),Zr=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})}),Go=a.Variant({Ok:a.Nat,Err:Kr}),Vo=a.Variant({Ok:a.Nat,Err:Zr});import{arrayOfNumberToUint8Array as Qr,uint8ArrayToHexString as Yr}from"@dfinity/utils";var bt=t=>{let e=t instanceof Uint8Array?t:Qr(t);try{return new TextDecoder("utf-8").decode(e)}catch{return`0x${Yr(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)},vt=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 Jr}from"@dfinity/candid";import{uint8ArrayToBase64 as Xo}from"@dfinity/utils";var Se=({recordClass:t,bytes:e})=>{let r=Jr.decode([t],e);if(r.length!==1)throw new Error("More than one object returned. This is unexpected.");let[s]=r;return s};var qt=async({arg:t,owner:e,token:{symbol:r,decimals:s,fee:o}})=>await je({arg:t,fn:n=>{let{amount:p,from_subaccount:m,to:{owner:d,subaccount:f},fee:h,memo:O}=Se({recordClass:Et,bytes:t}),{core:{amount:x,from:q,to:V,fee:W},icrc1_transfer:{title:K}}=n,N=[`# ${K}`];N.push(`${S(x)} ${E({amount:p,decimals:s})} ${r}`);let Z=R(m),Q=D({owner:e,subaccount:Z});N.push(`${S(q)} ${Q}`);let _=D({owner:d,subaccount:R(f)});N.push(`${S(V)} ${_}`),N.push(`${S(W)} ${E({amount:R(h)??o,decimals:s})} ${r}`);let Y=Fe({memo:O,en:n});return{message:[...N,...Y]}}}),kt=async({arg:t,owner:e,token:{symbol:r,decimals:s,fee:o}})=>await je({arg:t,fn:n=>{let{spender:{owner:p,subaccount:m},from_subaccount:d,amount:f,expected_allowance:h,expires_at:O,fee:x,memo:q}=Se({recordClass:Tt,bytes:t}),{icrc2_approve:{title:V,address_is_allowed:W,your_account:K,requested_withdrawal_allowance:N,withdrawal_allowance:{none:Z,some:Q},expiration_date:{title:_,none:Y},approval_fee:Ce,approver_account_transaction_fees:_e}}=n,I=[`# ${V}`],Pe=D({owner:p,subaccount:R(m)});I.push(`${S(W)} ${Pe}`);let lr=R(d),Ve=D({owner:e,subaccount:lr});I.push(`${S(K)} ${Ve}`),I.push(`${S(N)} ${E({amount:f,decimals:s})} ${r}`);let We=R(h);zt(We)?I.push(`${S(Q)} ${E({amount:We,decimals:s})} ${r}`):I.push(`\u26A0 ${Z.replace("{amount}",E({amount:f,decimals:s})).replace("{symbol}",r)}`);let Ke=R(O);I.push(`${S(_)} ${zt(Ke)?vt(Ke):Y}`),I.push(`${S(Ce)} ${E({amount:R(x)??o,decimals:s})} ${r}`),I.push(`${S(_e)} ${Ve}`);let fr=Fe({memo:q,en:n});return{message:[...I,...fr]}}}),Ut=async({arg:t,owner:e,token:{symbol:r,decimals:s,fee:o}})=>await je({arg:t,fn:n=>{let{from:{owner:p,subaccount:m},to:{owner:d,subaccount:f},spender_subaccount:h,amount:O,fee:x,memo:q}=Se({recordClass:Ot,bytes:t}),{core:{to:V},icrc2_transfer_from:{title:W,withdrawal_account:K,sending_the_transfer_request:N,amount_to_withdraw:Z,fee_paid_by_withdrawal_account:Q}}=n,_=[`# ${W}`],Y=D({owner:p,subaccount:R(m)});_.push(`${S(K)} ${Y}`);let Ce=R(h),_e=D({owner:e,subaccount:Ce});_.push(`${S(N)} ${_e}`),_.push(`${S(Z)} ${E({amount:O,decimals:s})} ${r}`);let I=D({owner:d,subaccount:R(f)});_.push(`${S(V)} ${I}`),_.push(`${S(Q)} ${E({amount:R(x)??o,decimals:s})} ${r}`);let Pe=Fe({memo:q,en:n});return{message:[..._,...Pe]}}}),S=t=>`**${t}:**`,Fe=({memo:t,en:e})=>{let r=R(t);if(es(r))return[];let{core:{memo:s}}=e;return[`${S(s)} ${bt(r)}`]},je=async({fn:t,arg:e})=>{try{ts({arg:e});let{default:r}=await Promise.resolve().then(()=>_r(Mt(),1)),{message:s}=t(r);return{Ok:{metadata:{language:"en",utc_offset_minutes:[]},consent_message:{GenericDisplayMessage:s.join(` `)}}}}catch(r){return{Err:r}}},ke=class extends Error{},ts=({arg:t})=>{if(t.byteLength>Ue)throw new ke(`The argument size is too large. The maximum allowed size is ${Ue} bytes.`)};var Ue=500,Ft={icrc1_transfer:qt,icrc2_approve:kt,icrc2_transfer_from:Ut};var jt=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 ye=class{#e=new he;async assertAndPromptConsentMessage({params:{sender:e,...r},prompt:s,notify:o,options:{owner:c,host:n}}){let{result:p}=this.assertSender({sender:e,owner:c,notify:o});if(p==="invalid")return{result:"error"};if(De(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:jt(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 lt({...s,result:n}),r?.({origin:c,status:"result",...n}),{result:"success"}}catch(n){return r?.({origin:c,status:"error",details:n}),xe({...s,message:n instanceof Error&&$t(n.message)?n.message:"An unknown error occurred"}),{result:"error"}}}assertSender({notify:e,owner:r,sender:s}){return r.getPrincipal().toText()===os.fromText(s).toText()?{result:"valid"}:(ct(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:Dt(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}),xe({...r,message:e instanceof Error&&$t(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=Ft[e];if(De(n))return{NoFallback:null};try{let p=await this.#e.ledgerMetadata({params:{canisterId:s},host:c,owner:o}),m=ss(p);if(De(m))return{Err:new Error("Incomplete token metadata.")};let d=await n({arg:rs(Dt(r)),token:m,owner:o.getPrincipal()});return"Err"in d?{Err:d.Err}:{Warn:{consentInfo:d.Ok,method:e,arg:r,canisterId:s}}}catch(p){return{Err:p}}}};import{isNullish as as}from"@dfinity/utils";import{nonNullish as ns}from"@dfinity/utils";var Bt=({key:t,value:e})=>{try{localStorage.setItem(t,JSON.stringify(e))}catch(r){console.error(r)}};var $e=({key:t})=>{try{let e=localStorage.getItem(t);return ns(e)?JSON.parse(e):void 0}catch(e){console.error(e);return}};var cs="oisy_signer",Lt=({owner:t,origin:e})=>`${cs}_${e}_${t.toText()}`,Ht=({scopes:t,...e})=>{let r=Lt(e),s=$e({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 O=(s?.scopes??[]).find(({scope:{method:x}})=>x===d);return[...m,{...h,scope:{...f,method:d},createdAt:O?.createdAt??c,updatedAt:c}]},[]),p={scopes:[...o,...n],createdAt:s?.createdAt??c,updatedAt:c};Bt({key:r,value:p})},Be=({sessionOptions:t,...e})=>{let r=$e({key:Lt(e)});if(!as(r))return r.scopes.filter(({updatedAt:s})=>s>=Date.now()-(t?.sessionPermissionExpirationInMilliseconds??st)).map(({updatedAt:s,createdAt:o,...c})=>({...c}))},Gt=({method:t,...e})=>Be(e)?.find(({scope:{method:s}})=>s===t)?.state??v;import{base64ToUint8Array as is,isNullish as ps}from"@dfinity/utils";import{PrincipalTextSchema as Wt}from"@dfinity/zod-schemas";import*as g from"zod/v4";import*as Vt from"zod/v4";var z=Vt.string().refine(t=>{try{return btoa(atob(t))===t}catch{return!1}},{message:"Invalid base64 string"});var jn=g.object({scopes:g.array(g.object({method:M})).min(1)}),ms=g.object({scopes:g.array(g.object({method:g.string()})).min(1)}),Kt=Ae({method:b,params:ms}),Zt=ee({method:se}),Qt=ee({method:oe}),Yt=ee({method:ne}),Jt=ee({method:P}),us=g.string().trim().min(1),Le=g.object({canisterId:Wt,sender:Wt,method:us,arg:z,nonce:z.optional().refine(t=>{try{return ps(t)||is(t).length<=32}catch{return!1}},{message:"Nonce must be a Uint8Array with a maximum length of 32 bytes"})}),Xt=Ae({method:A,params:Le});var G=class extends Error{};import*as i from"zod/v4";import*as er from"zod/v4";var T=t=>er.custom(e=>t.implement(e));import{base64ToUint8Array as ds}from"@dfinity/utils";import{PrincipalTextSchema as ls}from"@dfinity/zod-schemas";import*as Re from"zod/v4";var fs=z.refine(t=>{try{return ds(t).length===32}catch{return!1}},{message:"Subaccount must be exactly 32 bytes long."}),hs=Re.object({owner:ls,subaccount:fs.optional()}).strict(),ge=Re.array(hs).min(1);import{UrlSchema as Ss}from"@dfinity/zod-schemas";import*as y from"zod/v4";var ys=y.object({method:M}),Rs=y.object({scope:ys,state:ce}).strict(),Ie=y.array(Rs),gs=y.object({scopes:Ie}).strict(),Jn=F(gs),Is=/^https:\/\/github\.com\/dfinity\/ICRC\/blob\/main\/ICRCs\/ICRC-\d+\/ICRC-\d+\.md$/,Cs=y.url().regex(Is).refine(t=>{try{Ss.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.enum).includes(s)},{message:"The URL does not match any of the IcrcStandard values."}),_s=y.array(y.object({name:J,url:Cs}).strict()).min(1),Xn=F(y.object({supportedStandards:_s})),ea=F(y.literal("ready")),ta=F(y.object({accounts:ge})),He=y.object({contentMap:z,certificate:z}).strict(),ra=F(He.strict());import{UrlSchema as Ps}from"@dfinity/zod-schemas";var tr=Ps;var da=i.enum([B,b,P,A]),$=i.object({origin:tr}),rr=T(i.function({output:i.void()})),te=i.enum(["result","error"]),sr=$.extend({status:i.literal(te.enum.error),details:i.unknown().optional()}),As=T(i.function({input:i.tuple([Ie]),output:i.void()})),xs=$.extend({requestedScopes:Ie,confirm:As}),or=T(i.function({input:i.tuple([xs]),output:i.void()})),Ns=T(i.function({input:i.tuple([ge]),output:i.void()})),ws=$.extend({approve:Ns,reject:rr}),nr=T(i.function({input:i.tuple([ws]),output:i.void()})),Es=T(i.function({output:i.void()})),ar=i.enum(["loading"]),la=ar.or(te),Ts=$.extend({status:i.literal(ar.enum.loading)}),cr=i.custom(),Os=i.object({Ok:cr}),bs=i.object({Warn:Le.pick({canisterId:!0,method:!0,arg:!0}).extend({consentInfo:cr})}),vs=i.union([Os,bs]),Ms=$.extend({status:i.literal(te.enum.result),consentInfo:vs,approve:Es,reject:rr}),zs=i.union([Ts,Ms,sr]),ir=T(i.function({input:i.tuple([zs]),output:i.void()})),pr=i.enum(["executing"]),fa=pr.or(te),qs=$.extend({status:i.literal(pr.enum.executing)}),ks=i.intersection($.extend({status:i.literal(te.enum.result)}),He),Us=i.union([qs,ks,sr]),mr=T(i.function({input:i.tuple([Us]),output:i.void()}));var dr=class t{#e;#t;#r;#s;#n;#a;#o=!1;#c=new ye;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}=U.safeParse(r);if(!o)return;let{handled:n}=this.handleReadOnlyMessage(e);if(n)return;let{busy:p}=this.assertNotBusy(e);if(p)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}){ur(this.#t)||(this.#t=e)}assertUndefinedOrSameOrigin({data:e,origin:r}){if(ur(this.#t)&&this.#t!==r){let{data:s}=U.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?(it({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}=U.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 B:{ir.parse(r),this.#n=r;return}case b:{or.parse(r),this.#r=r;return}case P:{nr.parse(r),this.#s=r;return}case A:{mr.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}=Yt.safeParse(e);if(o){let{valid:n}=this.assertUndefinedOrSameOrigin({data:e,origin:r,...s});if(!n)return{handled:!0};let{id:p}=c;return pt({id:p,origin:r}),this.setWalletOrigin({origin:r}),{handled:!0}}return{handled:!1}}handleSupportedStandards({data:e,origin:r}){let{success:s,data:o}=Qt.safeParse(e);if(s){let{id:c}=o;return mt({id:c,origin:r}),{handled:!0}}return{handled:!1}}handlePermissionsRequest({data:e}){let{success:r,data:s}=Zt.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}=Kt.safeParse(e);if(!o)return{handled:!1};let{id:n,params:{scopes:p}}=c;if(re(this.#r))return this.assertWalletOriginAndNotifyMissingPromptError(n),{handled:!0};let m=p.filter(({method:f})=>M.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 G);return}this.#r({...e,confirm:c})})}emitPermissions({id:e}){Ge(this.#t,"The relying party's origin is unknown.");let{owner:r,sessionOptions:s}=this.#e,o=Be({owner:r.getPrincipal(),origin:this.#t,sessionOptions:s}),c=[...o??[],...rt.filter(({scope:{method:n}})=>(o??[]).find(({scope:{method:p}})=>p===n)===void 0)];ut({id:e,origin:this.#t,scopes:c})}assertWalletOriginAndNotifyMissingPromptError(e){Ge(this.#t,"The relying party's origin is unknown."),me({id:e??null,origin:this.#t})}savePermissions({scopes:e}){Ge(this.#t,"The relying party's origin is unknown.");let{owner:r}=this.#e;Ht({owner:r.getPrincipal(),origin:this.#t,scopes:e})}async handleAccounts({data:e,origin:r}){let s=async()=>{let{success:o,data:c}=Jt.safeParse(e);if(!o)return{handled:!1};let{id:n}=c,p=async()=>{let d=async()=>{let{result:f,accounts:h}=await this.promptAccounts({origin:r});if(f==="rejected"){pe({id:n,origin:r});return}dt({accounts:h,id:n,origin:r})};await this.prompt({requestId:n,promptFn:d})};switch(await this.assertAndPromptPermissions({method:P,requestId:n,origin:r})){case k:{Ne({id:n??null,origin:r});break}case L:{await p();break}}return{handled:!0}};return await this.handleWithBusy(s)}async prompt({requestId:e,promptFn:r}){try{await r()}catch(s){if(s instanceof G){this.assertWalletOriginAndNotifyMissingPromptError(e);return}throw s}}async promptAccounts(e){return await new Promise((s,o)=>{let c=()=>{s({result:"rejected",accounts:[]})},n=p=>{s({result:"approved",accounts:p})};if(re(this.#s)){o(new G);return}this.#s({approve:n,reject:c,...e})})}async handleCallCanister({data:e,origin:r}){let s=async()=>{let{success:o,data:c}=Xt.safeParse(e);if(!o)return{handled:!1};let{id:n,params:p}=c;if(await this.assertAndPromptPermissions({method:A,requestId:n,origin:r})===k)return Ne({id:n??null,origin:r}),{handled:!0};let d={id:n,origin:r},{result:f}=await this.#c.assertAndPromptConsentMessage({notify:d,params:p,prompt:this.#n,options:this.#e});return f!=="approved"?{handled:!0}:(await this.#c.callCanister({notify:d,params:p,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=Gt({owner:o.getPrincipal(),origin:r,method:e});switch(c){case v:return await new Promise((p,m)=>{let d=async()=>{let f=[{scope:{method:e},state:k}],h=await this.promptPermissions({requestedScopes:f,origin:r});if(this.savePermissions({scopes:h}),h.find(({scope:{method:x},state:q})=>x===e&&q===L)!==void 0){p(L);return}p(k)};this.prompt({requestId:s,promptFn:d}).catch(f=>{m(f)})});default:return c}}};export{dr as Signer}; //# sourceMappingURL=signer.js.map