@rango-dev/signer-evm 0.5.1-next.0 → 0.5.1-next.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/helper.d.ts CHANGED
@@ -1,3 +1,4 @@
1
1
  import type { SignerError as SignerErrorType } from 'rango-types';
2
2
  export declare const cleanEvmError: (error: any) => SignerErrorType;
3
+ export declare function getTenderlyError(chainId: string | undefined, txHash: string): Promise<string | undefined>;
3
4
  //# sourceMappingURL=helper.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"helper.d.ts","sourceRoot":"","sources":["../src/helper.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,IAAI,eAAe,EAAE,MAAM,aAAa,CAAC;AAGlE,eAAO,MAAM,aAAa,UAAW,GAAG,KAAG,eAsB1C,CAAC"}
1
+ {"version":3,"file":"helper.d.ts","sourceRoot":"","sources":["../src/helper.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,IAAI,eAAe,EAAE,MAAM,aAAa,CAAC;AAGlE,eAAO,MAAM,aAAa,UAAW,GAAG,KAAG,eAsB1C,CAAC;AAMF,wBAAsB,gBAAgB,CACpC,OAAO,EAAE,MAAM,GAAG,SAAS,EAC3B,MAAM,EAAE,MAAM,GACb,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC,CAc7B"}
package/dist/index.js CHANGED
@@ -1,2 +1,2 @@
1
- var E=Object.defineProperty;var c=(t,r)=>E(t,"name",{value:r,configurable:!0});import{providers as m}from"ethers";import{SignerError as w,SignerErrorCode as f}from"rango-types";var p=c(t=>{let r;if(t&&Object.prototype.hasOwnProperty.call(t,"message")&&Object.prototype.hasOwnProperty.call(t,"code")&&Object.prototype.hasOwnProperty.call(t,"reason"))r=`Error sending the tx (code: ${t.code})`;else if(t&&Object.prototype.hasOwnProperty.call(t,"code")&&Object.prototype.hasOwnProperty.call(t,"message")&&t?.code===-32603)return new w(f.SEND_TX_ERROR,void 0,t.message);return new w(f.SEND_TX_ERROR,r,t)},"cleanEvmError");import{SignerError as g,SignerErrorCode as d}from"rango-types";var o=class{constructor(r){this.provider=new m.Web3Provider(r),this.signer=this.provider.getSigner()}async signMessage(r){try{return await this.signer.signMessage(r)}catch(e){throw new g(d.SIGN_TX_ERROR,void 0,e)}}async signAndSendTx(r,e,s){try{let a=o.buildTx(r),i=await this.signer.getChainId(),n=await this.signer.getAddress();if(s&&i&&i.toString().toLowerCase()!==s?.toLowerCase())throw new g(d.UNEXPECTED_BEHAVIOUR,`Signer chainId: '${i}' doesn't match with required chainId: '${s}' for tx.`);if(n&&e&&n.toLowerCase()!==e.toLowerCase())throw new g(d.UNEXPECTED_BEHAVIOUR,`Signer address: '${n.toLowerCase()}' doesn't match with required address: '${e.toLowerCase()}' for tx.`);let h=await this.signer.sendTransaction(a);return{hash:h.hash,response:h}}catch(a){throw p(a)}}async wait(r,e,s,a){try{if(s)return await s?.wait(a),{hash:r};if(!this.provider)return{hash:r};let i=await this.provider.getTransaction(r);if(!i)throw Error(`Transaction hash '${r}' not found in blockchain.`);return await i.wait(a),{hash:r}}catch(i){let n=i;if(n?.code==="TRANSACTION_REPLACED"&&n?.replacement)return{hash:n?.replacement?.hash,response:n?.replacement};throw p(n)}}static buildTx(r){let e={};return r.from&&(e={...e,from:r.from}),r.to&&(e={...e,to:r.to}),r.data&&(e={...e,data:r.data}),r.value&&(e={...e,value:r.value}),r.nonce&&(e={...e,nonce:r.nonce}),r.gasLimit&&(e={...e,gasLimit:r.gasLimit}),r.gasPrice&&(e={...e,gasPrice:"0x"+parseInt(r.gasPrice).toString(16)}),r.maxFeePerGas&&(e={...e,maxFeePerGas:r.maxFeePerGas}),r.maxPriorityFeePerGas&&(e={...e,maxPriorityFeePerGas:r.maxPriorityFeePerGas}),e}};c(o,"DefaultEvmSigner");export{o as DefaultEvmSigner};
1
+ var y=Object.defineProperty;var c=(t,r)=>y(t,"name",{value:r,configurable:!0});import{providers as E}from"ethers";import{SignerError as f,SignerErrorCode as u}from"rango-types";var h=c(t=>{let r;if(t&&Object.prototype.hasOwnProperty.call(t,"message")&&Object.prototype.hasOwnProperty.call(t,"code")&&Object.prototype.hasOwnProperty.call(t,"reason"))r=`Error sending the tx (code: ${t.code})`;else if(t&&Object.prototype.hasOwnProperty.call(t,"code")&&Object.prototype.hasOwnProperty.call(t,"message")&&t?.code===-32603)return new f(u.SEND_TX_ERROR,void 0,t.message);return new f(u.SEND_TX_ERROR,r,t)},"cleanEvmError");async function w(t,r){if(!t||!r)return;let n=parseInt(t);try{let e=`https://api.tenderly.co/api/v1/public-contract/${n}/tx/${r}`,s=await fetch(e,{method:"GET"});return s.ok?(await s.json())?.error_message:void 0}catch{return}}c(w,"getTenderlyError");import{SignerError as g,SignerErrorCode as d}from"rango-types";var P=c(t=>new Promise(r=>setTimeout(r,t)),"waitMs"),R=c(async(t,r,n,e)=>{let s=!1;return await Promise.race([(async()=>{await r.wait(e),s=!0})(),(async()=>{for(;!s;){if(await P(3e3),s)return null;try{if(!await t.getTransaction(n))return null}catch(o){return console.log({error:o}),null}}return null})()])},"waitWithMempoolCheck"),p=class{constructor(r){this.provider=new E.Web3Provider(r),this.signer=this.provider.getSigner()}async signMessage(r){try{return await this.signer.signMessage(r)}catch(n){throw new g(d.SIGN_TX_ERROR,void 0,n)}}async signAndSendTx(r,n,e){try{this.signer=this.provider.getSigner(r.from??void 0);let s=p.buildTx(r),o=await this.signer.getChainId(),i=await this.signer.getAddress();if(e&&o&&o!==parseInt(e))throw new g(d.UNEXPECTED_BEHAVIOUR,`Signer chainId: '${o}' doesn't match with required chainId: '${e}' for tx.`);if(i&&n&&i.toLowerCase()!==n.toLowerCase())throw new g(d.UNEXPECTED_BEHAVIOUR,`Signer address: '${i.toLowerCase()}' doesn't match with required address: '${n.toLowerCase()}' for tx.`);try{let a=await this.signer.sendTransaction(s);return{hash:a.hash,response:a}}catch(a){if(a?.message&&typeof a.message=="string"&&a.message.indexOf("EIP-1559")!==-1){console.log("retrying EIP-1559 error without v2 fields ...");let m=p.buildTx(r,!0),l=await this.signer.sendTransaction(m);return{hash:l.hash,response:l}}else throw a}}catch(s){throw h(s)}}async wait(r,n,e,s){try{if(e)return await e?.wait(s),{hash:r};if(!this.provider)return{hash:r};if(this.signer=this.provider.getSigner(),!n)return{hash:r};let o=await this.signer.getChainId();if(!o||parseInt(n)!=o)return{hash:r};let i=await this.provider.getTransaction(r);if(!i)throw Error(`Transaction hash '${r}' not found in blockchain.`);return await R(this.provider,i,r,s),{hash:r}}catch(o){let i=o;if(i?.code==="TRANSACTION_REPLACED"&&i?.replacement)return{hash:i?.replacement?.hash,response:i?.replacement};if(i?.code==="CALL_EXCEPTION"){let a=await w(n,r);if(a)throw new g(d.SEND_TX_ERROR,"Trannsaction failed in blockchain",a)}throw h(i)}}static buildTx(r,n=!1){let e={};return r.from&&(e={...e,from:r.from}),r.to&&(e={...e,to:r.to}),r.data&&(e={...e,data:r.data}),r.value&&(e={...e,value:r.value}),r.nonce&&(e={...e,nonce:r.nonce}),r.gasLimit&&(e={...e,gasLimit:r.gasLimit}),r.gasPrice&&(e={...e,gasPrice:"0x"+parseInt(r.gasPrice).toString(16)}),r.maxFeePerGas&&!n&&(e={...e,maxFeePerGas:r.maxFeePerGas}),r.maxPriorityFeePerGas&&!n&&(e={...e,maxPriorityFeePerGas:r.maxPriorityFeePerGas}),e}};c(p,"DefaultEvmSigner");export{p as DefaultEvmSigner};
2
2
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../src/signer.ts", "../src/helper.ts"],
4
- "sourcesContent": ["import {\n TransactionRequest,\n TransactionResponse,\n} from '@ethersproject/abstract-provider';\nimport type { GenericSigner } from 'rango-types';\nimport { EvmTransaction } from 'rango-types/lib/api/main';\nimport { providers } from 'ethers';\nimport { cleanEvmError } from './helper';\nimport { SignerError, SignerErrorCode } from 'rango-types';\n\nexport class DefaultEvmSigner implements GenericSigner<EvmTransaction> {\n private signer: providers.JsonRpcSigner;\n private provider: providers.Web3Provider;\n\n constructor(provider: providers.ExternalProvider) {\n this.provider = new providers.Web3Provider(provider);\n this.signer = this.provider.getSigner();\n }\n\n async signMessage(msg: string): Promise<string> {\n try {\n return await this.signer.signMessage(msg);\n } catch (error) {\n throw new SignerError(SignerErrorCode.SIGN_TX_ERROR, undefined, error);\n }\n }\n\n async signAndSendTx(\n tx: EvmTransaction,\n address: string,\n chainId: string | null\n ): Promise<{ hash: string; response: TransactionResponse }> {\n try {\n const transaction = DefaultEvmSigner.buildTx(tx);\n const signerChainId = await this.signer.getChainId();\n const signerAddress = await this.signer.getAddress();\n if (\n !!chainId &&\n !!signerChainId &&\n signerChainId.toString().toLowerCase() !== chainId?.toLowerCase()\n ) {\n throw new SignerError(\n SignerErrorCode.UNEXPECTED_BEHAVIOUR,\n `Signer chainId: '${signerChainId}' doesn't match with required chainId: '${chainId}' for tx.`\n );\n }\n if (\n !!signerAddress &&\n !!address &&\n signerAddress.toLowerCase() !== address.toLowerCase()\n ) {\n throw new SignerError(\n SignerErrorCode.UNEXPECTED_BEHAVIOUR,\n `Signer address: '${signerAddress.toLowerCase()}' doesn't match with required address: '${address.toLowerCase()}' for tx.`\n );\n }\n const response = await this.signer.sendTransaction(transaction);\n return { hash: response.hash, response };\n } catch (error) {\n throw cleanEvmError(error);\n }\n }\n\n async wait(\n txHash: string,\n _chainId: string,\n txResponse?: TransactionResponse,\n confirmations?: number | undefined\n ): Promise<{ hash: string; response?: TransactionResponse }> {\n try {\n if (txResponse) {\n await txResponse?.wait(confirmations);\n return { hash: txHash };\n }\n if (!this.provider) return { hash: txHash }; // wallet not connected yet\n const tx = await this.provider.getTransaction(txHash);\n if (!tx)\n throw Error(`Transaction hash '${txHash}' not found in blockchain.`);\n await tx.wait(confirmations);\n return { hash: txHash };\n } catch (err) {\n const error = err as any; // TODO find a proper type\n if (error?.code === 'TRANSACTION_REPLACED' && error?.replacement)\n return { hash: error?.replacement?.hash, response: error?.replacement };\n throw cleanEvmError(error);\n }\n }\n\n static buildTx(evmTx: EvmTransaction): TransactionRequest {\n let tx: TransactionRequest = {};\n if (evmTx.from) tx = { ...tx, from: evmTx.from };\n if (evmTx.to) tx = { ...tx, to: evmTx.to };\n if (evmTx.data) tx = { ...tx, data: evmTx.data };\n if (evmTx.value) tx = { ...tx, value: evmTx.value };\n if (evmTx.nonce) tx = { ...tx, nonce: evmTx.nonce };\n if (evmTx.gasLimit) tx = { ...tx, gasLimit: evmTx.gasLimit };\n if (evmTx.gasPrice)\n tx = {\n ...tx,\n gasPrice: '0x' + parseInt(evmTx.gasPrice).toString(16),\n };\n if (evmTx.maxFeePerGas) tx = { ...tx, maxFeePerGas: evmTx.maxFeePerGas };\n if (evmTx.maxPriorityFeePerGas)\n tx = { ...tx, maxPriorityFeePerGas: evmTx.maxPriorityFeePerGas };\n return tx;\n }\n}\n", "import type { SignerError as SignerErrorType } from 'rango-types';\nimport { SignerError, SignerErrorCode } from 'rango-types';\n\nexport const cleanEvmError = (error: any): SignerErrorType => {\n let message = undefined;\n if (\n error &&\n Object.prototype.hasOwnProperty.call(error, 'message') &&\n Object.prototype.hasOwnProperty.call(error, 'code') &&\n Object.prototype.hasOwnProperty.call(error, 'reason')\n ) {\n message = `Error sending the tx (code: ${(error as any).code})`;\n } else if (\n error &&\n Object.prototype.hasOwnProperty.call(error, 'code') &&\n Object.prototype.hasOwnProperty.call(error, 'message') &&\n (error as any)?.code === -32603\n ) {\n return new SignerError(\n SignerErrorCode.SEND_TX_ERROR,\n undefined,\n (error as any).message\n );\n }\n return new SignerError(SignerErrorCode.SEND_TX_ERROR, message, error);\n};\n"],
5
- "mappings": "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",
6
- "names": ["providers", "SignerError", "SignerErrorCode", "cleanEvmError", "__name", "error", "message", "SignerError", "SignerErrorCode", "SignerError", "SignerErrorCode", "DefaultEvmSigner", "provider", "providers", "msg", "error", "SignerError", "SignerErrorCode", "tx", "address", "chainId", "transaction", "signerChainId", "signerAddress", "response", "cleanEvmError", "txHash", "_chainId", "txResponse", "confirmations", "err", "evmTx", "__name"]
4
+ "sourcesContent": ["import {\n TransactionRequest,\n TransactionResponse,\n} from '@ethersproject/abstract-provider';\nimport type { GenericSigner } from 'rango-types';\nimport { EvmTransaction } from 'rango-types/lib/api/main';\nimport { providers } from 'ethers';\nimport { cleanEvmError, getTenderlyError } from './helper';\nimport { SignerError, SignerErrorCode } from 'rango-types';\n\nconst waitMs = (ms: number) =>\n new Promise((resolve) => setTimeout(resolve, ms));\n\nconst waitWithMempoolCheck = async (\n provider: providers.Web3Provider,\n tx: TransactionResponse,\n txHash: string,\n confirmations?: number\n) => {\n let finished = false;\n return await Promise.race([\n (async () => {\n await tx.wait(confirmations);\n finished = true;\n })(),\n (async () => {\n while (!finished) {\n await waitMs(3_000);\n if (finished) return null;\n try {\n const mempoolTx = await provider.getTransaction(txHash);\n if (!mempoolTx) return null;\n } catch (error) {\n console.log({ error });\n return null;\n }\n }\n return null;\n })(),\n ]);\n};\n\nexport class DefaultEvmSigner implements GenericSigner<EvmTransaction> {\n private signer: providers.JsonRpcSigner;\n private provider: providers.Web3Provider;\n\n constructor(provider: providers.ExternalProvider) {\n this.provider = new providers.Web3Provider(provider);\n this.signer = this.provider.getSigner();\n }\n\n async signMessage(msg: string): Promise<string> {\n try {\n return await this.signer.signMessage(msg);\n } catch (error) {\n throw new SignerError(SignerErrorCode.SIGN_TX_ERROR, undefined, error);\n }\n }\n\n async signAndSendTx(\n tx: EvmTransaction,\n address: string,\n chainId: string | null\n ): Promise<{ hash: string; response: TransactionResponse }> {\n try {\n this.signer = this.provider.getSigner(tx.from ?? undefined);\n const transaction = DefaultEvmSigner.buildTx(tx);\n const signerChainId = await this.signer.getChainId();\n const signerAddress = await this.signer.getAddress();\n if (!!chainId && !!signerChainId && signerChainId !== parseInt(chainId)) {\n throw new SignerError(\n SignerErrorCode.UNEXPECTED_BEHAVIOUR,\n `Signer chainId: '${signerChainId}' doesn't match with required chainId: '${chainId}' for tx.`\n );\n }\n if (\n !!signerAddress &&\n !!address &&\n signerAddress.toLowerCase() !== address.toLowerCase()\n ) {\n throw new SignerError(\n SignerErrorCode.UNEXPECTED_BEHAVIOUR,\n `Signer address: '${signerAddress.toLowerCase()}' doesn't match with required address: '${address.toLowerCase()}' for tx.`\n );\n }\n try {\n const response = await this.signer.sendTransaction(transaction);\n return { hash: response.hash, response };\n } catch (error: any) {\n // retrying EIP-1559 without v2 related fields\n if (\n !!error?.message &&\n typeof error.message === 'string' &&\n error.message.indexOf('EIP-1559') !== -1\n ) {\n console.log('retrying EIP-1559 error without v2 fields ...');\n const transaction = DefaultEvmSigner.buildTx(tx, true);\n const response = await this.signer.sendTransaction(transaction);\n return { hash: response.hash, response };\n } else {\n throw error;\n }\n }\n } catch (error) {\n throw cleanEvmError(error);\n }\n }\n\n async wait(\n txHash: string,\n chainId?: string,\n txResponse?: TransactionResponse,\n confirmations?: number\n ): Promise<{ hash: string; response?: TransactionResponse }> {\n try {\n // if we have transaction response, use that to wait\n // otherwise, try to get tx response from the wallet provider\n if (txResponse) {\n // if we use waitWithMempoolCheck here, we can't detect replaced tx anymore\n await txResponse?.wait(confirmations);\n return { hash: txHash };\n }\n\n // ignore wait if wallet not connected yet\n if (!this.provider) return { hash: txHash };\n this.signer = this.provider.getSigner();\n\n // don't proceed if signer chain changed or chain id is not specified\n // because if user change the wallet network, we receive null on getTransaction\n if (!chainId) return { hash: txHash };\n const signerChainId = await this.signer.getChainId();\n if (!signerChainId || parseInt(chainId) != signerChainId)\n return { hash: txHash };\n\n const tx = await this.provider.getTransaction(txHash);\n if (!tx)\n throw Error(`Transaction hash '${txHash}' not found in blockchain.`);\n\n await waitWithMempoolCheck(this.provider, tx, txHash, confirmations);\n return { hash: txHash };\n } catch (err) {\n const error = err as any; // TODO find a proper type\n if (error?.code === 'TRANSACTION_REPLACED' && error?.replacement)\n return { hash: error?.replacement?.hash, response: error?.replacement };\n else if (error?.code === 'CALL_EXCEPTION') {\n const tError = await getTenderlyError(chainId, txHash);\n if (!!tError)\n // TODO different Signer Error Code\n throw new SignerError(\n SignerErrorCode.SEND_TX_ERROR,\n 'Trannsaction failed in blockchain',\n tError\n );\n }\n throw cleanEvmError(error);\n }\n }\n\n static buildTx(evmTx: EvmTransaction, disableV2 = false): TransactionRequest {\n let tx: TransactionRequest = {};\n if (evmTx.from) tx = { ...tx, from: evmTx.from };\n if (evmTx.to) tx = { ...tx, to: evmTx.to };\n if (evmTx.data) tx = { ...tx, data: evmTx.data };\n if (evmTx.value) tx = { ...tx, value: evmTx.value };\n if (evmTx.nonce) tx = { ...tx, nonce: evmTx.nonce };\n if (evmTx.gasLimit) tx = { ...tx, gasLimit: evmTx.gasLimit };\n if (evmTx.gasPrice)\n tx = {\n ...tx,\n gasPrice: '0x' + parseInt(evmTx.gasPrice).toString(16),\n };\n if (evmTx.maxFeePerGas && !disableV2)\n tx = { ...tx, maxFeePerGas: evmTx.maxFeePerGas };\n if (evmTx.maxPriorityFeePerGas && !disableV2)\n tx = { ...tx, maxPriorityFeePerGas: evmTx.maxPriorityFeePerGas };\n return tx;\n }\n}\n", "import type { SignerError as SignerErrorType } from 'rango-types';\nimport { SignerError, SignerErrorCode } from 'rango-types';\n\nexport const cleanEvmError = (error: any): SignerErrorType => {\n let message = undefined;\n if (\n error &&\n Object.prototype.hasOwnProperty.call(error, 'message') &&\n Object.prototype.hasOwnProperty.call(error, 'code') &&\n Object.prototype.hasOwnProperty.call(error, 'reason')\n ) {\n message = `Error sending the tx (code: ${(error as any).code})`;\n } else if (\n error &&\n Object.prototype.hasOwnProperty.call(error, 'code') &&\n Object.prototype.hasOwnProperty.call(error, 'message') &&\n (error as any)?.code === -32603\n ) {\n return new SignerError(\n SignerErrorCode.SEND_TX_ERROR,\n undefined,\n (error as any).message\n );\n }\n return new SignerError(SignerErrorCode.SEND_TX_ERROR, message, error);\n};\n\ninterface TenderlyResponse {\n error_message: string;\n}\n\nexport async function getTenderlyError(\n chainId: string | undefined,\n txHash: string\n): Promise<string | undefined> {\n if (!chainId || !txHash) return;\n const chainIdInt = parseInt(chainId);\n try {\n const url = `https://api.tenderly.co/api/v1/public-contract/${chainIdInt}/tx/${txHash}`;\n const response = await fetch(url, {\n method: 'GET',\n });\n if (!response.ok) return;\n const data: TenderlyResponse = await response.json();\n return data?.error_message;\n } catch (error) {\n return;\n }\n}\n"],
5
+ "mappings": "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",
6
+ "names": ["providers", "SignerError", "SignerErrorCode", "cleanEvmError", "__name", "error", "message", "SignerError", "SignerErrorCode", "getTenderlyError", "chainId", "txHash", "chainIdInt", "url", "response", "SignerError", "SignerErrorCode", "waitMs", "__name", "ms", "resolve", "waitWithMempoolCheck", "provider", "tx", "txHash", "confirmations", "finished", "error", "DefaultEvmSigner", "providers", "msg", "SignerError", "SignerErrorCode", "address", "chainId", "transaction", "signerChainId", "signerAddress", "response", "cleanEvmError", "txResponse", "err", "tError", "getTenderlyError", "evmTx", "disableV2"]
7
7
  }
package/dist/signer.d.ts CHANGED
@@ -11,10 +11,10 @@ export declare class DefaultEvmSigner implements GenericSigner<EvmTransaction> {
11
11
  hash: string;
12
12
  response: TransactionResponse;
13
13
  }>;
14
- wait(txHash: string, _chainId: string, txResponse?: TransactionResponse, confirmations?: number | undefined): Promise<{
14
+ wait(txHash: string, chainId?: string, txResponse?: TransactionResponse, confirmations?: number): Promise<{
15
15
  hash: string;
16
16
  response?: TransactionResponse;
17
17
  }>;
18
- static buildTx(evmTx: EvmTransaction): TransactionRequest;
18
+ static buildTx(evmTx: EvmTransaction, disableV2?: boolean): TransactionRequest;
19
19
  }
20
20
  //# sourceMappingURL=signer.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"signer.d.ts","sourceRoot":"","sources":["../src/signer.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,kBAAkB,EAClB,mBAAmB,EACpB,MAAM,kCAAkC,CAAC;AAC1C,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AACjD,OAAO,EAAE,cAAc,EAAE,MAAM,0BAA0B,CAAC;AAC1D,OAAO,EAAE,SAAS,EAAE,MAAM,QAAQ,CAAC;AAInC,qBAAa,gBAAiB,YAAW,aAAa,CAAC,cAAc,CAAC;IACpE,OAAO,CAAC,MAAM,CAA0B;IACxC,OAAO,CAAC,QAAQ,CAAyB;gBAE7B,QAAQ,EAAE,SAAS,CAAC,gBAAgB;IAK1C,WAAW,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAQzC,aAAa,CACjB,EAAE,EAAE,cAAc,EAClB,OAAO,EAAE,MAAM,EACf,OAAO,EAAE,MAAM,GAAG,IAAI,GACrB,OAAO,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,mBAAmB,CAAA;KAAE,CAAC;IAgCrD,IAAI,CACR,MAAM,EAAE,MAAM,EACd,QAAQ,EAAE,MAAM,EAChB,UAAU,CAAC,EAAE,mBAAmB,EAChC,aAAa,CAAC,EAAE,MAAM,GAAG,SAAS,GACjC,OAAO,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,EAAE,mBAAmB,CAAA;KAAE,CAAC;IAoB5D,MAAM,CAAC,OAAO,CAAC,KAAK,EAAE,cAAc,GAAG,kBAAkB;CAkB1D"}
1
+ {"version":3,"file":"signer.d.ts","sourceRoot":"","sources":["../src/signer.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,kBAAkB,EAClB,mBAAmB,EACpB,MAAM,kCAAkC,CAAC;AAC1C,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AACjD,OAAO,EAAE,cAAc,EAAE,MAAM,0BAA0B,CAAC;AAC1D,OAAO,EAAE,SAAS,EAAE,MAAM,QAAQ,CAAC;AAoCnC,qBAAa,gBAAiB,YAAW,aAAa,CAAC,cAAc,CAAC;IACpE,OAAO,CAAC,MAAM,CAA0B;IACxC,OAAO,CAAC,QAAQ,CAAyB;gBAE7B,QAAQ,EAAE,SAAS,CAAC,gBAAgB;IAK1C,WAAW,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAQzC,aAAa,CACjB,EAAE,EAAE,cAAc,EAClB,OAAO,EAAE,MAAM,EACf,OAAO,EAAE,MAAM,GAAG,IAAI,GACrB,OAAO,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,mBAAmB,CAAA;KAAE,CAAC;IA6CrD,IAAI,CACR,MAAM,EAAE,MAAM,EACd,OAAO,CAAC,EAAE,MAAM,EAChB,UAAU,CAAC,EAAE,mBAAmB,EAChC,aAAa,CAAC,EAAE,MAAM,GACrB,OAAO,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,EAAE,mBAAmB,CAAA;KAAE,CAAC;IA6C5D,MAAM,CAAC,OAAO,CAAC,KAAK,EAAE,cAAc,EAAE,SAAS,UAAQ,GAAG,kBAAkB;CAmB7E"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rango-dev/signer-evm",
3
- "version": "0.5.1-next.0",
3
+ "version": "0.5.1-next.2",
4
4
  "license": "MIT",
5
5
  "type": "module",
6
6
  "module": "./dist/index.js",
package/src/helper.ts CHANGED
@@ -24,3 +24,26 @@ export const cleanEvmError = (error: any): SignerErrorType => {
24
24
  }
25
25
  return new SignerError(SignerErrorCode.SEND_TX_ERROR, message, error);
26
26
  };
27
+
28
+ interface TenderlyResponse {
29
+ error_message: string;
30
+ }
31
+
32
+ export async function getTenderlyError(
33
+ chainId: string | undefined,
34
+ txHash: string
35
+ ): Promise<string | undefined> {
36
+ if (!chainId || !txHash) return;
37
+ const chainIdInt = parseInt(chainId);
38
+ try {
39
+ const url = `https://api.tenderly.co/api/v1/public-contract/${chainIdInt}/tx/${txHash}`;
40
+ const response = await fetch(url, {
41
+ method: 'GET',
42
+ });
43
+ if (!response.ok) return;
44
+ const data: TenderlyResponse = await response.json();
45
+ return data?.error_message;
46
+ } catch (error) {
47
+ return;
48
+ }
49
+ }
package/src/signer.ts CHANGED
@@ -5,9 +5,41 @@ import {
5
5
  import type { GenericSigner } from 'rango-types';
6
6
  import { EvmTransaction } from 'rango-types/lib/api/main';
7
7
  import { providers } from 'ethers';
8
- import { cleanEvmError } from './helper';
8
+ import { cleanEvmError, getTenderlyError } from './helper';
9
9
  import { SignerError, SignerErrorCode } from 'rango-types';
10
10
 
11
+ const waitMs = (ms: number) =>
12
+ new Promise((resolve) => setTimeout(resolve, ms));
13
+
14
+ const waitWithMempoolCheck = async (
15
+ provider: providers.Web3Provider,
16
+ tx: TransactionResponse,
17
+ txHash: string,
18
+ confirmations?: number
19
+ ) => {
20
+ let finished = false;
21
+ return await Promise.race([
22
+ (async () => {
23
+ await tx.wait(confirmations);
24
+ finished = true;
25
+ })(),
26
+ (async () => {
27
+ while (!finished) {
28
+ await waitMs(3_000);
29
+ if (finished) return null;
30
+ try {
31
+ const mempoolTx = await provider.getTransaction(txHash);
32
+ if (!mempoolTx) return null;
33
+ } catch (error) {
34
+ console.log({ error });
35
+ return null;
36
+ }
37
+ }
38
+ return null;
39
+ })(),
40
+ ]);
41
+ };
42
+
11
43
  export class DefaultEvmSigner implements GenericSigner<EvmTransaction> {
12
44
  private signer: providers.JsonRpcSigner;
13
45
  private provider: providers.Web3Provider;
@@ -31,14 +63,11 @@ export class DefaultEvmSigner implements GenericSigner<EvmTransaction> {
31
63
  chainId: string | null
32
64
  ): Promise<{ hash: string; response: TransactionResponse }> {
33
65
  try {
66
+ this.signer = this.provider.getSigner(tx.from ?? undefined);
34
67
  const transaction = DefaultEvmSigner.buildTx(tx);
35
68
  const signerChainId = await this.signer.getChainId();
36
69
  const signerAddress = await this.signer.getAddress();
37
- if (
38
- !!chainId &&
39
- !!signerChainId &&
40
- signerChainId.toString().toLowerCase() !== chainId?.toLowerCase()
41
- ) {
70
+ if (!!chainId && !!signerChainId && signerChainId !== parseInt(chainId)) {
42
71
  throw new SignerError(
43
72
  SignerErrorCode.UNEXPECTED_BEHAVIOUR,
44
73
  `Signer chainId: '${signerChainId}' doesn't match with required chainId: '${chainId}' for tx.`
@@ -54,8 +83,24 @@ export class DefaultEvmSigner implements GenericSigner<EvmTransaction> {
54
83
  `Signer address: '${signerAddress.toLowerCase()}' doesn't match with required address: '${address.toLowerCase()}' for tx.`
55
84
  );
56
85
  }
57
- const response = await this.signer.sendTransaction(transaction);
58
- return { hash: response.hash, response };
86
+ try {
87
+ const response = await this.signer.sendTransaction(transaction);
88
+ return { hash: response.hash, response };
89
+ } catch (error: any) {
90
+ // retrying EIP-1559 without v2 related fields
91
+ if (
92
+ !!error?.message &&
93
+ typeof error.message === 'string' &&
94
+ error.message.indexOf('EIP-1559') !== -1
95
+ ) {
96
+ console.log('retrying EIP-1559 error without v2 fields ...');
97
+ const transaction = DefaultEvmSigner.buildTx(tx, true);
98
+ const response = await this.signer.sendTransaction(transaction);
99
+ return { hash: response.hash, response };
100
+ } else {
101
+ throw error;
102
+ }
103
+ }
59
104
  } catch (error) {
60
105
  throw cleanEvmError(error);
61
106
  }
@@ -63,30 +108,55 @@ export class DefaultEvmSigner implements GenericSigner<EvmTransaction> {
63
108
 
64
109
  async wait(
65
110
  txHash: string,
66
- _chainId: string,
111
+ chainId?: string,
67
112
  txResponse?: TransactionResponse,
68
- confirmations?: number | undefined
113
+ confirmations?: number
69
114
  ): Promise<{ hash: string; response?: TransactionResponse }> {
70
115
  try {
116
+ // if we have transaction response, use that to wait
117
+ // otherwise, try to get tx response from the wallet provider
71
118
  if (txResponse) {
119
+ // if we use waitWithMempoolCheck here, we can't detect replaced tx anymore
72
120
  await txResponse?.wait(confirmations);
73
121
  return { hash: txHash };
74
122
  }
75
- if (!this.provider) return { hash: txHash }; // wallet not connected yet
123
+
124
+ // ignore wait if wallet not connected yet
125
+ if (!this.provider) return { hash: txHash };
126
+ this.signer = this.provider.getSigner();
127
+
128
+ // don't proceed if signer chain changed or chain id is not specified
129
+ // because if user change the wallet network, we receive null on getTransaction
130
+ if (!chainId) return { hash: txHash };
131
+ const signerChainId = await this.signer.getChainId();
132
+ if (!signerChainId || parseInt(chainId) != signerChainId)
133
+ return { hash: txHash };
134
+
76
135
  const tx = await this.provider.getTransaction(txHash);
77
136
  if (!tx)
78
137
  throw Error(`Transaction hash '${txHash}' not found in blockchain.`);
79
- await tx.wait(confirmations);
138
+
139
+ await waitWithMempoolCheck(this.provider, tx, txHash, confirmations);
80
140
  return { hash: txHash };
81
141
  } catch (err) {
82
142
  const error = err as any; // TODO find a proper type
83
143
  if (error?.code === 'TRANSACTION_REPLACED' && error?.replacement)
84
144
  return { hash: error?.replacement?.hash, response: error?.replacement };
145
+ else if (error?.code === 'CALL_EXCEPTION') {
146
+ const tError = await getTenderlyError(chainId, txHash);
147
+ if (!!tError)
148
+ // TODO different Signer Error Code
149
+ throw new SignerError(
150
+ SignerErrorCode.SEND_TX_ERROR,
151
+ 'Trannsaction failed in blockchain',
152
+ tError
153
+ );
154
+ }
85
155
  throw cleanEvmError(error);
86
156
  }
87
157
  }
88
158
 
89
- static buildTx(evmTx: EvmTransaction): TransactionRequest {
159
+ static buildTx(evmTx: EvmTransaction, disableV2 = false): TransactionRequest {
90
160
  let tx: TransactionRequest = {};
91
161
  if (evmTx.from) tx = { ...tx, from: evmTx.from };
92
162
  if (evmTx.to) tx = { ...tx, to: evmTx.to };
@@ -99,8 +169,9 @@ export class DefaultEvmSigner implements GenericSigner<EvmTransaction> {
99
169
  ...tx,
100
170
  gasPrice: '0x' + parseInt(evmTx.gasPrice).toString(16),
101
171
  };
102
- if (evmTx.maxFeePerGas) tx = { ...tx, maxFeePerGas: evmTx.maxFeePerGas };
103
- if (evmTx.maxPriorityFeePerGas)
172
+ if (evmTx.maxFeePerGas && !disableV2)
173
+ tx = { ...tx, maxFeePerGas: evmTx.maxFeePerGas };
174
+ if (evmTx.maxPriorityFeePerGas && !disableV2)
104
175
  tx = { ...tx, maxPriorityFeePerGas: evmTx.maxPriorityFeePerGas };
105
176
  return tx;
106
177
  }