UNPKG

@ledgerhq/hw-app-starknet

Version:

Ledger Hardware Wallet Starknet Application API

2 lines (1 loc) 9.94 kB
"use strict";var D=Object.defineProperty;var m=(E,t,e)=>t in E?D(E,t,{enumerable:!0,configurable:!0,writable:!0,value:e}):E[t]=e;var U=(E,t,e)=>m(E,typeof t!="symbol"?t+"":t,e);Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const a=require("./helper.cjs"),r=require("./common.cjs"),p=require("starknet"),T=require("./node_modules/.pnpm/@starknet-io_types-js@0.8.1/node_modules/@starknet-io/types-js/dist/esm/api/constants.cjs");function G(E){let t=E.replace(/^0x0*/,"");if(t.length>r.HASH_MAX_LENGTH)throw"invalid hash length";return t="0".repeat(1+r.HASH_MAX_LENGTH-t.length).concat(t),t}function O(E){const t=[];for(let e=0;e<E.length;e+=2)t.push(parseInt(E.substring(e,e+2),16));return Uint8Array.from(t)}class P{constructor(t){U(this,"transport");if(this.transport=t,!t)throw new Error("Transport has not been defined")}async sendApdu(t=r.INS.GET_VERSION,e=0,o=0,s=new Uint8Array(0)){return this.transport.send(r.CLA,t,e,o,Buffer.from(s),[r.LedgerError.NoError,r.LedgerError.BadCla,r.LedgerError.BadIns,r.LedgerError.InvalidP1P2,r.LedgerError.UserRejected]).then(n=>{const _=n.subarray(-2),N=_[0]*256+_[1];let h=r.errorCodeToString(N);return{data:n.subarray(0,-2),returnCode:N,errorMessage:h}})}async getAppVersion(){const t=await this.sendApdu(r.INS.GET_VERSION);return{returnCode:t.returnCode,errorMessage:t.errorMessage,major:t.data[0],minor:t.data[1],patch:t.data[2]}}async getPubKey(t,e=!0){const o=a.serializePath(t);try{const s=await this.sendApdu(r.INS.GET_PUB_KEY,e?1:0,0,o);return{publicKey:s.data.slice(1,65),returnCode:s.returnCode,errorMessage:s.errorMessage}}catch{return console.warn("Caught error"),{publicKey:new Uint8Array(0),returnCode:r.LedgerError.ExecutionError,errorMessage:r.errorCodeToString(r.LedgerError.ExecutionError)}}}async getStarkKey(t,e=!0){const{publicKey:o,errorMessage:s,returnCode:n}=await this.getPubKey(t,e);return n!==r.LedgerError.NoError?{starkKey:o,returnCode:n,errorMessage:s}:{starkKey:o.slice(0,32),returnCode:n,errorMessage:s}}async signHash(t,e){const o=a.serializePath(t),s=O(G(e));try{let n=await this.sendApdu(r.INS.SIGN_HASH,0,0,o);return n=await this.sendApdu(r.INS.SIGN_HASH,1,0,s),n.returnCode!==r.LedgerError.NoError?{returnCode:n.returnCode,errorMessage:r.errorCodeToString(n.returnCode),r:new Uint8Array(0),s:new Uint8Array(0),v:0}:{returnCode:n.returnCode,errorMessage:n.errorMessage,r:n.data.subarray(1,33),s:n.data.subarray(33,65),v:n.data[65]}}catch{return{returnCode:r.LedgerError.ExecutionError,errorMessage:r.errorCodeToString(r.LedgerError.ExecutionError),r:new Uint8Array(0),s:new Uint8Array(0),v:0}}}async signTx(t,e,o){await this.sendApdu(r.INS.SIGN_TX,0,0,a.serializePath(t));const s=a.toBN(o.accountAddress),n=a.toBN(o.chainId),_=a.toBN(o.nonce),N=a.toBN(this.encodeDataAvailabilityMode(o.nonceDataAvailabilityMode,o.feeDataAvailabilityMode));let h=new Uint8Array([...s.toArray("be",32),...n.toArray("be",32),..._.toArray("be",32),...N.toArray("be",32)]);await this.sendApdu(r.INS.SIGN_TX,1,0,h);const y=a.toBN(o.tip),{l1_gas:l,l2_gas:u,l1_data_gas:I}=this.encodeResourceBounds(o.resourceBounds);h=new Uint8Array([...y.toArray("be",32),...l.toArray("be",32),...u.toArray("be",32),...I.toArray("be",32)]),await this.sendApdu(r.INS.SIGN_TX,2,0,h),await this.sendApdu(r.INS.SIGN_TX,3,0,new Uint8Array(0)),await this.sendApdu(r.INS.SIGN_TX,4,0,new Uint8Array(0));let S=a.toBN(e.length);h=new Uint8Array([...S.toArray("be",32)]),await this.sendApdu(r.INS.SIGN_TX,5,0,h);let d,i={returnCode:r.LedgerError.ExecutionError,errorMessage:"Execution Error",h:new Uint8Array(0),r:new Uint8Array(0),s:new Uint8Array(0),v:0};for(const C of e){const B=p.CallData.toCalldata(C.calldata);let g=new Uint8Array((3+B.length)*32);a.toBN(C.contractAddress).toArray("be",32).forEach((A,f)=>g[f]=A),a.toBN(p.hash.getSelectorFromName(C.entrypoint)).toArray("be",32).forEach((A,f)=>g[32+f]=A),a.toBN(B.length).toArray("be",32).forEach((A,f)=>g[64+f]=A),B.forEach((A,f)=>{a.toBN(A).toArray("be",32).forEach((M,v)=>g[96+32*f+v]=M)});let w=[];for(let A=0;A<g.length;A+=7*32)w.push(g.slice(A,A+7*32));if(w.length>1){if(d=await this.sendApdu(r.INS.SIGN_TX,6,0,w[0]),d.returnCode!==r.LedgerError.NoError)return i;for(const A of w.slice(1))if(d=await this.sendApdu(r.INS.SIGN_TX,6,1,A),d.returnCode!==r.LedgerError.NoError)return i}else if(d=await this.sendApdu(r.INS.SIGN_TX,6,0,w[0]),d.returnCode!==r.LedgerError.NoError)return i}return(d==null?void 0:d.returnCode)===r.LedgerError.NoError?{returnCode:d.returnCode,errorMessage:d.errorMessage,h:d.data.subarray(0,32),r:d.data.subarray(33,65),s:d.data.subarray(65,97),v:d.data[97]}:i}async signTxV1(t,e,o){await this.sendApdu(r.INS.SIGN_TX_V1,0,0,a.serializePath(t));const s=a.toBN(o.accountAddress),n=a.toBN(o.max_fee),_=a.toBN(o.chainId),N=a.toBN(o.nonce);let h=new Uint8Array([...s.toArray("be",32),...n.toArray("be",32),..._.toArray("be",32),...N.toArray("be",32)]);await this.sendApdu(r.INS.SIGN_TX_V1,1,0,h);let y=a.toBN(e.length);h=new Uint8Array([...y.toArray("be",32)]),await this.sendApdu(r.INS.SIGN_TX_V1,2,0,h);let l,u={returnCode:r.LedgerError.ExecutionError,errorMessage:"Execution Error",h:new Uint8Array(0),r:new Uint8Array(0),s:new Uint8Array(0),v:0};for(const I of e){const S=p.CallData.toCalldata(I.calldata);let d=new Uint8Array((3+S.length)*32);a.toBN(I.contractAddress).toArray("be",32).forEach((c,b)=>d[b]=c),a.toBN(p.hash.getSelectorFromName(I.entrypoint)).toArray("be",32).forEach((c,b)=>d[32+b]=c),a.toBN(S.length).toArray("be",32).forEach((c,b)=>d[64+b]=c),S.forEach((c,b)=>{a.toBN(c).toArray("be",32).forEach((w,A)=>d[96+32*b+A]=w)});let g=[];for(let c=0;c<d.length;c+=7*32)g.push(d.slice(c,c+7*32));if(g.length>1){if(l=await this.sendApdu(r.INS.SIGN_TX_V1,3,0,g[0]),l.returnCode!==r.LedgerError.NoError)return u;for(const c of g.slice(1))if(l=await this.sendApdu(r.INS.SIGN_TX_V1,3,1,c),l.returnCode!==r.LedgerError.NoError)return u}else if(l=await this.sendApdu(r.INS.SIGN_TX_V1,3,0,g[0]),l.returnCode!==r.LedgerError.NoError)return u}return(l==null?void 0:l.returnCode)===r.LedgerError.NoError?{returnCode:l.returnCode,errorMessage:l.errorMessage,h:l.data.subarray(0,32),r:l.data.subarray(33,65),s:l.data.subarray(65,97),v:l.data[97]}:u}async signDeployAccount(t,e){await this.sendApdu(r.INS.DEPLOY_ACCOUNT,0,0,a.serializePath(t));const o=a.toBN(e.contractAddress),s=a.toBN(e.chainId),n=a.toBN(e.nonce),_=a.toBN(this.encodeDataAvailabilityMode(e.nonceDataAvailabilityMode,e.feeDataAvailabilityMode)),N=a.toBN(e.class_hash),h=a.toBN(e.contract_address_salt);let y=new Uint8Array([...o.toArray("be",32),...s.toArray("be",32),...n.toArray("be",32),..._.toArray("be",32),...N.toArray("be",32),...h.toArray("be",32)]);await this.sendApdu(r.INS.DEPLOY_ACCOUNT,1,0,y);const l=a.toBN(e.tip),{l1_gas:u,l2_gas:I,l1_data_gas:S}=this.encodeResourceBounds(e.resourceBounds);y=new Uint8Array([...l.toArray("be",32),...u.toArray("be",32),...I.toArray("be",32),...S.toArray("be",32)]),await this.sendApdu(r.INS.DEPLOY_ACCOUNT,2,0,y),await this.sendApdu(r.INS.DEPLOY_ACCOUNT,3,0,new Uint8Array(0));let d=a.toBN(e.constructor_calldata.length);y=new Uint8Array([...d.toArray("be",32)]),await this.sendApdu(r.INS.DEPLOY_ACCOUNT,4,0,y);let i,C={returnCode:r.LedgerError.ExecutionError,errorMessage:"Execution Error",h:new Uint8Array(0),r:new Uint8Array(0),s:new Uint8Array(0),v:0},B=new Uint8Array(e.constructor_calldata.length*32);e.constructor_calldata.forEach((c,b)=>{a.toBN(c).toArray("be",32).forEach((w,A)=>B[32*b+A]=w)});let g=[];for(let c=0;c<B.length;c+=7*32)g.push(B.slice(c,c+7*32));for(const c of g)if(i=await this.sendApdu(r.INS.DEPLOY_ACCOUNT,5,0,c),i.returnCode!==r.LedgerError.NoError)return C;return(i==null?void 0:i.returnCode)===r.LedgerError.NoError?{returnCode:i.returnCode,errorMessage:i.errorMessage,h:i.data.subarray(0,32),r:i.data.subarray(33,65),s:i.data.subarray(65,97),v:i.data[97]}:C}async signDeployAccountV1(t,e){await this.sendApdu(r.INS.DEPLOY_ACCOUNT_V1,0,0,a.serializePath(t));const o=a.toBN(e.contractAddress),s=a.toBN(e.class_hash),n=a.toBN(e.contract_address_salt),_=a.toBN(e.max_fee),N=a.toBN(e.chainId),h=a.toBN(e.nonce);let y=new Uint8Array([...o.toArray("be",32),...s.toArray("be",32),...n.toArray("be",32),..._.toArray("be",32),...N.toArray("be",32),...h.toArray("be",32)]);await this.sendApdu(r.INS.DEPLOY_ACCOUNT_V1,1,0,y);let l=a.toBN(e.constructor_calldata.length);y=new Uint8Array([...l.toArray("be",32)]),await this.sendApdu(r.INS.DEPLOY_ACCOUNT_V1,2,0,y);let u,I={returnCode:r.LedgerError.ExecutionError,errorMessage:"Execution Error",h:new Uint8Array(0),r:new Uint8Array(0),s:new Uint8Array(0),v:0},S=new Uint8Array(e.constructor_calldata.length*32);e.constructor_calldata.forEach((i,C)=>{a.toBN(i).toArray("be",32).forEach((g,c)=>S[32*C+c]=g)});let d=[];for(let i=0;i<S.length;i+=7*32)d.push(S.slice(i,i+7*32));for(const i of d)if(u=await this.sendApdu(r.INS.DEPLOY_ACCOUNT_V1,3,0,i),u.returnCode!==r.LedgerError.NoError)return I;return(u==null?void 0:u.returnCode)===r.LedgerError.NoError?{returnCode:u.returnCode,errorMessage:u.errorMessage,h:u.data.subarray(0,32),r:u.data.subarray(33,65),s:u.data.subarray(65,97),v:u.data[97]}:I}async signMessage(t,e,o){const s=p.typedData.getMessageHash(e,o);return this.signHash(t,s)}encodeResourceBounds(t){const e=BigInt(64),o=BigInt(128),s=e+o,n=BigInt(p.shortString.encodeShortString("L1_GAS")),_=BigInt(p.shortString.encodeShortString("L2_GAS")),N=BigInt(p.shortString.encodeShortString("L1_DATA")),h=(n<<s)+(BigInt(t.l1_gas.max_amount)<<o)+BigInt(t.l1_gas.max_price_per_unit),y=(_<<s)+(BigInt(t.l2_gas.max_amount)<<o)+BigInt(t.l2_gas.max_price_per_unit),l=(N<<s)+(BigInt(t.l1_data_gas.max_amount)<<o)+BigInt(t.l1_data_gas.max_price_per_unit);return{l1_gas:a.toBN(h),l2_gas:a.toBN(y),l1_data_gas:a.toBN(l)}}encodeDataAvailabilityMode(t,e){const o=BigInt(32),s=t===T.EDataAvailabilityMode.L1?0:1,n=e===T.EDataAvailabilityMode.L1?0:1;return(BigInt(s)<<o)+BigInt(n)}}exports.LedgerError=r.LedgerError;exports.StarknetClient=P;