UNPKG

@argent/x-sessions

Version:

Manage sessions for Argent X wallets

2 lines (1 loc) 13.5 kB
(function(d,n){typeof exports=="object"&&typeof module<"u"?n(exports,require("starknet")):typeof define=="function"&&define.amd?define(["exports","starknet"],n):(d=typeof globalThis<"u"?globalThis:d||self,n(d.sessions={},d.starknet))})(this,function(d,n){"use strict";var ce=Object.defineProperty;var de=(d,n,f)=>n in d?ce(d,n,{enumerable:!0,configurable:!0,writable:!0,value:f}):d[n]=f;var U=(d,n,f)=>de(d,typeof n!="symbol"?n+"":n,f);const f={ACTIVE:"1"},x="https://cloud.argent-api.com/v1";class H extends Error{constructor(t,s){super(t),this.cause=s,Error.captureStackTrace(this,this.constructor)}}const W=async({sessionKey:e,authorisationSignature:t,argentSessionServiceBaseUrl:s=x,calls:a,transactionsDetail:o,sessionTypedData:r,sessionSignature:i,cacheAuthorisation:c})=>{var w,v;const u=n.transaction.getExecuteCalldata(a,o.cairoVersion),S=n.typedData.getMessageHash(r,o.walletAddress),h=n.stark.formatSignature(t),g={session:{sessionHash:S,sessionAuthorisation:h,cacheAuthorisation:c,sessionSignature:{type:"StarknetKey",signer:{publicKey:e.publicKey,r:i[0].toString(),s:i[1].toString()}}}};if(Object.values(n.RPC.ETransactionVersion2).includes(o.version)){const l=o;g.transaction={contractAddress:l.walletAddress,calldata:u,maxFee:l.maxFee.toString(),nonce:l.nonce.toString(),version:n.num.toBigInt(l.version).toString(10),chainId:n.num.toBigInt(l.chainId).toString(10)}}else if(Object.values(n.RPC.ETransactionVersion3).includes(o.version)){const l=o;g.transaction={sender_address:l.walletAddress,calldata:u,nonce:l.nonce.toString(),version:n.num.toBigInt(l.version).toString(10),chain_id:n.num.toBigInt(l.chainId).toString(10),resource_bounds:{l1_gas:{max_amount:l.resourceBounds.l1_gas.max_amount.toString(),max_price_per_unit:l.resourceBounds.l1_gas.max_price_per_unit.toString()},l1_data_gas:{max_amount:((w=l.resourceBounds.l1_data_gas)==null?void 0:w.max_amount.toString())||"0",max_price_per_unit:((v=l.resourceBounds.l1_data_gas)==null?void 0:v.max_price_per_unit.toString())||"0"},l2_gas:{max_amount:l.resourceBounds.l2_gas.max_amount.toString(),max_price_per_unit:l.resourceBounds.l2_gas.max_price_per_unit.toString()}},tip:l.tip.toString(),paymaster_data:l.paymasterData.map(E=>E.toString()),account_deployment_data:l.accountDeploymentData,nonce_data_availability_mode:l.nonceDataAvailabilityMode,fee_data_availability_mode:l.feeDataAvailabilityMode}}else throw Error("unsupported signTransaction version");const m=await fetch(`${s}/cosigner/signSession`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(g)});if(!m.ok){const l=await m.json();throw new H("Sign session error",l.status)}return(await m.json()).signature},F=async({sessionKey:e,authorisationSignature:t,argentSessionServiceBaseUrl:s=x,sessionTokenToSign:a,accountAddress:o,currentTypedData:r,sessionSignature:i,cacheAuthorisation:c,chainId:u,network:S="mainnet"})=>{const h=n.typedData.getMessageHash(A(a,u),o),p=n.stark.formatSignature(t),y={session:{sessionHash:h,sessionAuthorisation:p,cacheAuthorisation:c,sessionSignature:{type:"StarknetKey",signer:{publicKey:e.publicKey,r:i[0].toString(),s:i[1].toString()}}},message:{type:"eip712",accountAddress:o,chain:"starknet",message:r,network:S}},w=JSON.stringify(y,(E,D)=>typeof D=="bigint"?D.toString():D),v=await fetch(`${s}/cosigner/signSessionEFO`,{method:"POST",headers:{"Content-Type":"application/json"},body:w});if(!v.ok){const E=await v.json();throw new H("Sign session error",E.status)}return(await v.json()).signature};class G extends n.Signer{constructor(t){super(),this.signTransactionCallback=t}async signRaw(t){throw new Error("Method not implemented.")}async signTransaction(t,s){return this.signTransactionCallback(t,s)}}var _=(e=>(e[e.Starknet=0]="Starknet",e[e.Secp256k1=1]="Secp256k1",e[e.Secp256r1=2]="Secp256r1",e[e.Eip191=3]="Eip191",e[e.Webauthn=4]="Webauthn",e))(_||{});const L=(e,t)=>{const s={Starknet:void 0,Secp256k1:void 0,Secp256r1:void 0,Eip191:void 0,Webauthn:void 0};if(e===_.Starknet)s.Starknet=t;else if(e===_.Secp256k1)s.Secp256k1=t;else if(e===_.Secp256r1)s.Secp256r1=t;else if(e===_.Eip191)s.Eip191=t;else if(e===_.Webauthn)s.Webauthn=t;else throw new Error("Unknown SignerType");return new n.CairoCustomEnum(s)},M=e=>{const t=e.allowed_methods.map(s=>n.hash.computePoseidonHashOnElements([P,s["Contract Address"],n.selector.getSelectorFromName(s.selector)]));return new n.merkle.MerkleTree(t,n.hash.computePoseidonHash)},O=e=>{const t=n.byteArray.byteArrayFromString(e.metadata),s=[t.data.length,...t.data,t.pending_word,t.pending_word_len],a=n.hash.computePoseidonHashOnElements(s);return{expires_at:e.expires_at,allowed_methods_root:M(e).root.toString(),metadata_hash:a,session_key_guid:e.session_key_guid}},R=(e,t)=>{const s=M(e);return t.map(a=>{const o=e.allowed_methods.findIndex(r=>n.num.hexToDecimalString(r["Contract Address"])===n.num.hexToDecimalString(a.contractAddress)&&r.selector==a.entrypoint);return s.getProof(s.leaves[o],s.leaves)})},I=(e,t)=>L(_.Starknet,{pubkey:e,r:t[0],s:t[1]}),K=async(e,t,s,a,o,r,i,c)=>({session:e,cache_authorization:c,session_authorization:r,sessionSignature:I(s.publicKey,o),guardianSignature:I(i.publicKey,[i.r,i.s]),proofs:R(t,a)}),B=(e,t,s,a,o)=>{const r=n.typedData.getMessageHash(s,t),i=n.hash.computePoseidonHashOnElements([e,r,+a]),c=n.ec.starkCurve.sign(i,o.privateKey);return[c.r,c.s]},J=n.shortString.encodeShortString("session-token");class ${constructor(t,s,a=x){U(this,"argentSessionServiceUrl");this.session=t,this.sessionKey=s,this.argentSessionServiceUrl=a}getAccountWithSessionSigner({provider:t,session:s,cacheAuthorisation:a=!1}){const o=new G((r,i)=>this.signTransaction(n.stark.formatSignature(s.authorisationSignature),s,r,i,a));return new n.Account(t,s.address,o)}async signTransaction(t,s,a,o,r){const i=n.transaction.getExecuteCalldata(a,o.cairoVersion);let c;if(Object.values(n.RPC.ETransactionVersion2).includes(o.version)){const u=o;c=n.hash.calculateInvokeTransactionHash({...u,senderAddress:u.walletAddress,compiledCalldata:i,version:u.version})}else if(Object.values(n.RPC.ETransactionVersion3).includes(o.version)){const u=o;c=n.hash.calculateInvokeTransactionHash({...u,senderAddress:u.walletAddress,compiledCalldata:i,version:u.version,nonceDataAvailabilityMode:n.stark.intDAM(u.nonceDataAvailabilityMode),feeDataAvailabilityMode:n.stark.intDAM(u.feeDataAvailabilityMode)})}else throw Error("unsupported signTransaction version");return this.getSessionSignatureForTransaction({sessionAuthorizationSignature:t,session:s,transactionHash:c,calls:a,accountAddress:o.walletAddress,invocationSignerDetails:o,cacheAuthorisation:r})}async getSessionSignatureForTransaction({sessionAuthorizationSignature:t,session:s,transactionHash:a,calls:o,accountAddress:r,invocationSignerDetails:i,cacheAuthorisation:c}){const u={allowed_methods:s.allowedMethods,expires_at:s.expiresAt,metadata:s.metadata,session_key_guid:s.sessionKeyGuid},S=O(u),h=A(u,this.session.chainId),p=B(a,r,h,c,this.sessionKey),g=await W({sessionKey:this.sessionKey,authorisationSignature:this.session.authorisationSignature,argentSessionServiceBaseUrl:this.argentSessionServiceUrl,calls:o,transactionsDetail:i,sessionTypedData:h,sessionSignature:p,cacheAuthorisation:c}),m=await K(S,u,this.sessionKey,o,p,t,g,c);return[J,...n.CallData.compile(m)]}}const T={StarknetDomain:[{name:"name",type:"shortstring"},{name:"version",type:"shortstring"},{name:"chainId",type:"shortstring"},{name:"revision",type:"shortstring"}],"Allowed Method":[{name:"Contract Address",type:"ContractAddress"},{name:"selector",type:"selector"}],Session:[{name:"Expires At",type:"timestamp"},{name:"Allowed Methods",type:"merkletree",contains:"Allowed Method"},{name:"Metadata",type:"string"},{name:"Session Key",type:"felt"}]},P=n.typedData.getTypeHash(T,"Allowed Method",f.ACTIVE),j=e=>({name:"SessionAccount.session",version:n.shortString.encodeShortString("1"),chainId:e,revision:"1"}),A=(e,t)=>({types:T,primaryType:"Session",domain:j(t),message:{"Expires At":e.expires_at,"Allowed Methods":e.allowed_methods,Metadata:e.metadata,"Session Key":e.session_key_guid}}),N=(e,t,s,a)=>({expires_at:Number(t),allowed_methods:e,metadata:JSON.stringify(s),session_key_guid:n.hash.computePoseidonHash(n.shortString.encodeShortString("Starknet Signer"),a)}),k=async({session:e,sessionKey:t,provider:s,argentSessionServiceBaseUrl:a,useCacheAuthorisation:o})=>new $(e,t,a).getAccountWithSessionSigner({provider:s,session:e,cacheAuthorisation:o}),Y=({chainId:e,sessionParams:t})=>{const{allowedMethods:s,expiry:a=BigInt(Date.now())+10000n,sessionKey:o,metaData:r}=t;if(!o||!o.publicKey)throw new Error("sessionPublicKey is required");const i=N(s,a,r,o.publicKey);return{sessionTypedData:A(i,e),offchainSession:i,sessionKey:o}},z=async({address:e,authorisationSignature:t,sessionRequest:s,chainId:a})=>{const{sessionKey:o,sessionTypedData:r,offchainSession:i}=s;if(!o||!o.publicKey)throw new Error("sessionPublicKey is required");return{authorisationSignature:t,address:e,chainId:a,hash:n.typedData.getMessageHash(r,e),version:n.shortString.encodeShortString("1"),expiresAt:i.expires_at,allowedMethods:i.allowed_methods,metadata:i.metadata,sessionKeyGuid:i.session_key_guid,sessionKey:o}},Q=({session:e,sessionKey:t})=>{const s={allowed_methods:e.allowedMethods,expires_at:e.expiresAt,metadata:e.metadata,session_key_guid:e.sessionKeyGuid},a=A(s,e.chainId),o=n.typedData.getMessageHash(a,e.address);return n.ec.starkCurve.sign(e.hash,t.privateKey)&&e.hash===o},X=e=>n.encode.addHexPrefix(n.encode.buf2hex(e)),Z=e=>{const s=n.encode.removeHexPrefix(e).match(/.{1,2}/g);if(!s)throw new Error("Invalid hex string");return Uint8Array.from(s.map(a=>parseInt(a,16)))};/*! noble-curves - MIT License (c) 2022 Paul Miller (paulmillr.com) */function q(e){return e instanceof Uint8Array||ArrayBuffer.isView(e)&&e.constructor.name==="Uint8Array"}function ee(e){if(!q(e))throw new Error("Uint8Array expected")}const te=Array.from({length:256},(e,t)=>t.toString(16).padStart(2,"0"));function ne(e){ee(e);let t="";for(let s=0;s<e.length;s++)t+=te[e[s]];return t}const se={StarknetDomain:[{name:"name",type:"shortstring"},{name:"version",type:"shortstring"},{name:"chainId",type:"shortstring"},{name:"revision",type:"shortstring"}],OutsideExecution:[{name:"Caller",type:"ContractAddress"},{name:"Nonce",type:"felt"},{name:"Execute After",type:"u128"},{name:"Execute Before",type:"u128"},{name:"Calls",type:"Call*"}],Call:[{name:"To",type:"ContractAddress"},{name:"Selector",type:"selector"},{name:"Calldata",type:"felt*"}]};function oe(e,t="1"){return{name:"Account.execute_from_outside",version:t,chainId:e,revision:"1"}}function ae(e){return{to:e.contractAddress,selector:n.hash.getSelectorFromName(e.entrypoint),calldata:e.calldata??[]}}const b=(e,t,s,a,o)=>{const r=n.shortString.encodeShortString("ANY_CALLER"),i=n.encode.addHexPrefix(ne(n.ec.starkCurve.utils.randomPrivateKey())),c=Date.now(),u=Math.floor((c+6e4*20)/1e3),S=Math.floor((c-6e4*10)/1e3);return{caller:t||r,nonce:o||i,execute_after:s||S,execute_before:a||u,calls:e.map(h=>ae(h))}},ie=async({session:e,sessionKey:t,cacheAuthorisation:s,calls:a,outsideExecutionParams:o,argentSessionServiceUrl:r=x,network:i="mainnet"})=>{const{caller:c,execute_after:u,execute_before:S,nonce:h,version:p}=o||{},g=b(a,c,u,S,h),m=V({outsideExecution:g,chainId:e.chainId,version:p||"2"}),y=await C({session:e,sessionKey:t,argentSessionServiceUrl:r,outsideExecutionTypedData:m,cacheAuthorisation:s,calls:a,network:i});return{contractAddress:e.address,entrypoint:"execute_from_outside_v2",calldata:n.CallData.compile({...g,signature:y})}},re=async({session:e,sessionKey:t,cacheAuthorisation:s,calls:a,outsideExecutionParams:o,argentSessionServiceUrl:r=x,network:i="mainnet"})=>{const{caller:c,execute_after:u,execute_before:S,nonce:h,version:p}=o||{},g=b(a,c,u,S,h),m=V({outsideExecution:g,chainId:e.chainId,version:p||"1"}),y=await C({argentSessionServiceUrl:r,cacheAuthorisation:s,calls:a,outsideExecutionTypedData:m,session:e,sessionKey:t,network:i});return{outsideExecutionTypedData:m,signature:y}},V=({outsideExecution:e,chainId:t,version:s="1"})=>({types:se,primaryType:"OutsideExecution",domain:oe(t,s),message:{Caller:e.caller,Nonce:e.nonce,"Execute After":e.execute_after,"Execute Before":e.execute_before,Calls:e.calls.map(a=>({To:a.to,Selector:a.selector,Calldata:a.calldata}))}}),C=async({session:e,sessionKey:t,outsideExecutionTypedData:s,argentSessionServiceUrl:a=x,cacheAuthorisation:o=!1,calls:r,network:i="mainnet"})=>{const c={expires_at:e.expiresAt,allowed_methods:e.allowedMethods,metadata:e.metadata,session_key_guid:e.sessionKeyGuid},u=n.shortString.encodeShortString("session-token"),S=O(c),h=A(c,e.chainId),p=n.typedData.getMessageHash(s,e.address),g=B(p,e.address,h,o,t),m=await F({sessionKey:t,authorisationSignature:e.authorisationSignature,argentSessionServiceBaseUrl:a,sessionTokenToSign:c,accountAddress:e.address,currentTypedData:s,sessionSignature:g,cacheAuthorisation:o,chainId:e.chainId,network:i}),y=await K(S,c,t,r,g,n.stark.formatSignature(e.authorisationSignature),m,o);return[u,...n.CallData.compile(y)].map(w=>n.num.toHex(w))};d.ALLOWED_METHOD_HASH=P,d.buildOutsideExecution=b,d.buildSessionAccount=k,d.bytesToHexString=X,d.createOffchainSession=N,d.createOutsideExecutionCall=ie,d.createOutsideExecutionTypedData=re,d.createSession=z,d.createSessionRequest=Y,d.getSessionDomain=j,d.getSessionTypedData=A,d.hexStringToBytes=Z,d.sessionTypes=T,d.signOutsideExecution=C,d.verifySession=Q,Object.defineProperty(d,Symbol.toStringTag,{value:"Module"})});