@avalabs/evm-module 0.0.11 → 0.0.12
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/.turbo/turbo-build.log +10 -10
- package/.turbo/turbo-lint.log +1 -1
- package/.turbo/turbo-test.log +36 -5
- package/CHANGELOG.md +12 -0
- package/dist/index.cjs +7 -4
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +30 -12
- package/dist/index.d.ts +30 -12
- package/dist/index.js +6 -4
- package/dist/index.js.map +1 -1
- package/package.json +5 -3
- package/src/env.ts +25 -0
- package/src/handlers/eth-send-transaction/eth-send-transaction.test.ts +333 -0
- package/src/handlers/eth-send-transaction/eth-send-transaction.ts +170 -0
- package/src/handlers/eth-send-transaction/schema.test.ts +240 -0
- package/src/handlers/eth-send-transaction/schema.ts +20 -0
- package/src/handlers/get-network-fee/get-network-fee.test.ts +1 -1
- package/src/handlers/get-network-fee/get-network-fee.ts +9 -11
- package/src/handlers/get-tokens/get-tokens.ts +2 -1
- package/src/handlers/get-transaction-history/converters/etherscan-transaction-converter/get-transaction-from-etherscan.ts +11 -3
- package/src/handlers/get-transaction-history/converters/evm-transaction-converter/get-transaction-from-glacier.test.ts +1 -5
- package/src/handlers/get-transaction-history/converters/evm-transaction-converter/get-transactions-from-glacier.ts +12 -3
- package/src/handlers/get-transaction-history/get-transaction-history.test.ts +2 -0
- package/src/handlers/get-transaction-history/get-transaction-history.ts +11 -3
- package/src/index.ts +2 -72
- package/src/module.ts +95 -0
- package/src/types.ts +13 -0
- package/src/utils/estimate-gas-limit.ts +27 -0
- package/src/utils/get-chain-id.ts +12 -0
- package/src/utils/get-nonce.ts +11 -0
- package/src/utils/get-provider.ts +18 -23
- package/tsconfig.json +1 -5
package/.turbo/turbo-build.log
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
|
|
2
|
-
> @avalabs/evm-module@0.0.
|
|
2
|
+
> @avalabs/evm-module@0.0.12 build /home/runner/work/vm-modules/vm-modules/packages/evm-module
|
|
3
3
|
> tsup
|
|
4
4
|
|
|
5
5
|
[34mCLI[39m Building entry: ./src/index.ts
|
|
@@ -10,13 +10,13 @@
|
|
|
10
10
|
[34mCLI[39m Cleaning output folder
|
|
11
11
|
[34mCJS[39m Build start
|
|
12
12
|
[34mESM[39m Build start
|
|
13
|
-
[
|
|
14
|
-
[
|
|
15
|
-
[
|
|
16
|
-
[
|
|
17
|
-
[
|
|
18
|
-
[
|
|
13
|
+
[32mESM[39m [1mdist/index.js [22m[32m13.08 KB[39m
|
|
14
|
+
[32mESM[39m [1mdist/index.js.map [22m[32m53.79 KB[39m
|
|
15
|
+
[32mESM[39m ⚡️ Build success in 1103ms
|
|
16
|
+
[32mCJS[39m [1mdist/index.cjs [22m[32m13.83 KB[39m
|
|
17
|
+
[32mCJS[39m [1mdist/index.cjs.map [22m[32m53.79 KB[39m
|
|
18
|
+
[32mCJS[39m ⚡️ Build success in 1104ms
|
|
19
19
|
[34mDTS[39m Build start
|
|
20
|
-
[32mDTS[39m ⚡️ Build success in
|
|
21
|
-
[32mDTS[39m [1mdist/index.d.cts [22m[
|
|
22
|
-
[32mDTS[39m [1mdist/index.d.ts [22m[
|
|
20
|
+
[32mDTS[39m ⚡️ Build success in 8087ms
|
|
21
|
+
[32mDTS[39m [1mdist/index.d.cts [22m[32m1.53 KB[39m
|
|
22
|
+
[32mDTS[39m [1mdist/index.d.ts [22m[32m1.53 KB[39m
|
package/.turbo/turbo-lint.log
CHANGED
package/.turbo/turbo-test.log
CHANGED
|
@@ -1,15 +1,46 @@
|
|
|
1
1
|
|
|
2
|
-
> @avalabs/evm-module@0.0.
|
|
2
|
+
> @avalabs/evm-module@0.0.12 test /home/runner/work/vm-modules/vm-modules/packages/evm-module
|
|
3
3
|
> jest
|
|
4
4
|
|
|
5
|
-
PASS src/handlers/
|
|
5
|
+
PASS src/handlers/eth-send-transaction/eth-send-transaction.test.ts (10.594 s)
|
|
6
|
+
● Console
|
|
7
|
+
|
|
8
|
+
console.error
|
|
9
|
+
Error: Invalid params
|
|
10
|
+
at Object.<anonymous> (/home/runner/work/vm-modules/vm-modules/packages/evm-module/src/handlers/eth-send-transaction/eth-send-transaction.test.ts:117:14)
|
|
11
|
+
at Promise.then.completed (/home/runner/work/vm-modules/vm-modules/node_modules/.pnpm/jest-circus@29.7.0/node_modules/jest-circus/build/utils.js:298:28)
|
|
12
|
+
at new Promise (<anonymous>)
|
|
13
|
+
at callAsyncCircusFn (/home/runner/work/vm-modules/vm-modules/node_modules/.pnpm/jest-circus@29.7.0/node_modules/jest-circus/build/utils.js:231:10)
|
|
14
|
+
at _callCircusTest (/home/runner/work/vm-modules/vm-modules/node_modules/.pnpm/jest-circus@29.7.0/node_modules/jest-circus/build/run.js:316:40)
|
|
15
|
+
at _runTest (/home/runner/work/vm-modules/vm-modules/node_modules/.pnpm/jest-circus@29.7.0/node_modules/jest-circus/build/run.js:252:3)
|
|
16
|
+
at _runTestsForDescribeBlock (/home/runner/work/vm-modules/vm-modules/node_modules/.pnpm/jest-circus@29.7.0/node_modules/jest-circus/build/run.js:126:9)
|
|
17
|
+
at _runTestsForDescribeBlock (/home/runner/work/vm-modules/vm-modules/node_modules/.pnpm/jest-circus@29.7.0/node_modules/jest-circus/build/run.js:121:9)
|
|
18
|
+
at run (/home/runner/work/vm-modules/vm-modules/node_modules/.pnpm/jest-circus@29.7.0/node_modules/jest-circus/build/run.js:71:3)
|
|
19
|
+
at runAndTransformResultsToJestFormat (/home/runner/work/vm-modules/vm-modules/node_modules/.pnpm/jest-circus@29.7.0/node_modules/jest-circus/build/legacy-code-todo-rewrite/jestAdapterInit.js:122:21)
|
|
20
|
+
at jestAdapter (/home/runner/work/vm-modules/vm-modules/node_modules/.pnpm/jest-circus@29.7.0/node_modules/jest-circus/build/legacy-code-todo-rewrite/jestAdapter.js:79:19)
|
|
21
|
+
at runTestInternal (/home/runner/work/vm-modules/vm-modules/node_modules/.pnpm/jest-runner@29.7.0/node_modules/jest-runner/build/runTest.js:367:16)
|
|
22
|
+
at runTest (/home/runner/work/vm-modules/vm-modules/node_modules/.pnpm/jest-runner@29.7.0/node_modules/jest-runner/build/runTest.js:444:34)
|
|
23
|
+
|
|
24
|
+
[0m [90m 30 |[39m
|
|
25
|
+
[90m 31 |[39m [36mif[39m ([33m![39mresult[33m.[39msuccess) {
|
|
26
|
+
[31m[1m>[22m[39m[90m 32 |[39m console[33m.[39merror(result[33m.[39merror)[33m;[39m
|
|
27
|
+
[90m |[39m [31m[1m^[22m[39m
|
|
28
|
+
[90m 33 |[39m [36mreturn[39m {
|
|
29
|
+
[90m 34 |[39m error[33m:[39m rpcErrors[33m.[39minvalidParams([32m'Transaction params are invalid'[39m)[33m,[39m
|
|
30
|
+
[90m 35 |[39m }[33m;[39m[0m
|
|
31
|
+
|
|
32
|
+
at ethSendTransaction (src/handlers/eth-send-transaction/eth-send-transaction.ts:32:13)
|
|
33
|
+
at Object.<anonymous> (src/handlers/eth-send-transaction/eth-send-transaction.test.ts:120:46)
|
|
34
|
+
|
|
35
|
+
PASS src/handlers/eth-send-transaction/schema.test.ts
|
|
36
|
+
PASS src/handlers/get-transaction-history/converters/evm-transaction-converter/get-transaction-from-glacier.test.ts
|
|
6
37
|
PASS src/handlers/get-transaction-history/converters/etherscan-transaction-converter/get-transaction-from-etherscan.test.ts
|
|
7
38
|
PASS src/handlers/get-tokens/get-tokens.test.ts
|
|
8
39
|
PASS src/handlers/get-transaction-history/get-transaction-history.test.ts
|
|
9
40
|
PASS src/handlers/get-network-fee/get-network-fee.test.ts
|
|
10
41
|
|
|
11
|
-
Test Suites:
|
|
12
|
-
Tests:
|
|
42
|
+
Test Suites: 7 passed, 7 total
|
|
43
|
+
Tests: 27 passed, 27 total
|
|
13
44
|
Snapshots: 0 total
|
|
14
|
-
Time:
|
|
45
|
+
Time: 12.862 s
|
|
15
46
|
Ran all test suites.
|
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,17 @@
|
|
|
1
1
|
# @avalabs/evm-module
|
|
2
2
|
|
|
3
|
+
## 0.0.12
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- d0c2cc9: make module interface more consistent
|
|
8
|
+
- 3d8a9a5: test auto sign commit
|
|
9
|
+
- 7bc6c6e: add eth_sendTransaction handler
|
|
10
|
+
- Updated dependencies [cd97708]
|
|
11
|
+
- Updated dependencies [d0c2cc9]
|
|
12
|
+
- Updated dependencies [7bc6c6e]
|
|
13
|
+
- @avalabs/vm-module-types@0.0.12
|
|
14
|
+
|
|
3
15
|
## 0.0.11
|
|
4
16
|
|
|
5
17
|
### Patch Changes
|
package/dist/index.cjs
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
+
var rpcErrors = require('@metamask/rpc-errors');
|
|
3
4
|
var vmModuleTypes = require('@avalabs/vm-module-types');
|
|
4
5
|
var walletsSdk = require('@avalabs/wallets-sdk');
|
|
5
6
|
var ethers = require('ethers');
|
|
@@ -7,14 +8,16 @@ var utilsSdk = require('@avalabs/utils-sdk');
|
|
|
7
8
|
var bn_js = require('bn.js');
|
|
8
9
|
var etherscanSdk = require('@avalabs/etherscan-sdk');
|
|
9
10
|
var glacierSdk = require('@avalabs/glacier-sdk');
|
|
10
|
-
var
|
|
11
|
+
var St = require('lodash.startcase');
|
|
12
|
+
var zod = require('zod');
|
|
11
13
|
|
|
12
14
|
function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
|
|
13
15
|
|
|
14
|
-
var
|
|
16
|
+
var St__default = /*#__PURE__*/_interopDefault(St);
|
|
15
17
|
|
|
16
|
-
var H=(t,e,o)=>{if(!e.has(t))throw TypeError("Cannot "+o)};var N=(t,e,o)=>(H(t,e,"read from private field"),o?o.call(t):e.get(t)),R=(t,e,o)=>{if(e.has(t))throw TypeError("Cannot add the same private member more than once");e instanceof WeakSet?e.add(t):e.set(t,o);},P=(t,e,o,n)=>(H(t,e,"write to private field"),n?n.call(t,o):e.set(t,o),o);var L=({glacierApiKey:t,chainId:e,chainName:o,rpcUrl:n,multiContractAddress:s})=>{if(!e||!o||!n)throw new Error("Missing required parameters");let a=e.split(":")[1];if(!a||isNaN(Number(a)))throw new Error("Invalid chainId");let r=new walletsSdk.JsonRpcBatchInternal({maxCalls:40,multiContractAddress:s},ct(n,t),new ethers.Network(o,Number(a)));return r.pollingInterval=2e3,r},mt=["glacier-api.avax.network","proxy-api.avax.network"];function ct(t,e){let o=new URL(t);if(e&&mt.includes(o.hostname)){let n=o.searchParams;return n.set("token",e),o.search=n.toString(),o.toString()}return t}var F={LOW:1n,MEDIUM:4n,HIGH:6n},I=500000000n;async function M({glacierApiUrl:t,glacierApiKey:e,chainId:o,chainName:n,rpcUrl:s,multiContractAddress:a}){let r=L({glacierApiUrl:t,glacierApiKey:e,chainId:o,chainName:n,rpcUrl:s,multiContractAddress:a}),{maxFeePerGas:i}=await r.getFeeData();if(!i)throw new Error("Pre-EIP-1559 networks are not supported");let m=I*F.LOW,c=I*F.MEDIUM,l=I*F.HIGH;return {baseFee:i,low:{maxFeePerGas:i+m,maxPriorityFeePerGas:m},medium:{maxFeePerGas:i+c,maxPriorityFeePerGas:c},high:{maxFeePerGas:i+l,maxPriorityFeePerGas:l}}}function E(t,e,o="tx"){return `${t}/${o}/${e}`}var G=({tx:t,networkToken:e,chainId:o,explorerUrl:n,address:s})=>{let a=t.from.toLowerCase()===s.toLowerCase(),r=parseInt(t.timeStamp)*1e3,i=e.decimals,m=new bn_js.BN(t.value),c=utilsSdk.balanceToDisplayValue(m,i),l=a?vmModuleTypes.TransactionType.SEND:vmModuleTypes.TransactionType.RECEIVE,{from:p,to:g,gasPrice:d,gasUsed:T,hash:u}=t,y=E(n,u);return {isIncoming:!a,isOutgoing:a,isContractCall:gt(t),timestamp:r,hash:u,isSender:a,from:p,to:g,tokens:[{decimal:i.toString(),name:e.name,symbol:e.symbol,amount:c,type:vmModuleTypes.TokenType.NATIVE}],gasUsed:T,gasPrice:d,chainId:o.toString(),txType:l,explorerLink:y}};function gt(t){return t.input!=="0x"}function _({tx:t,address:e,explorerUrl:o,chainId:n}){let s=t.from.toLowerCase()===e.toLowerCase(),a=parseInt(t.timeStamp)*1e3,r=parseInt(t.tokenDecimal),i=new bn_js.BN(t.value),m=utilsSdk.balanceToDisplayValue(i,r),{from:c,to:l,gasPrice:p,gasUsed:g,hash:d,tokenDecimal:T,tokenName:u,tokenSymbol:y}=t,x=s?vmModuleTypes.TransactionType.SEND:vmModuleTypes.TransactionType.RECEIVE,S=E(o,d);return {isIncoming:!s,isOutgoing:s,isContractCall:!1,timestamp:a,hash:d,isSender:s,from:c,to:l,tokens:[{decimal:T,name:u,symbol:y,type:vmModuleTypes.TokenType.ERC20,amount:m}],gasUsed:g,gasPrice:p,chainId:n.toString(),txType:x,explorerLink:S}}var O=async({isTestnet:t,chainId:e,networkToken:o,explorerUrl:n,address:s,nextPageToken:a,offset:r})=>{let i=a?JSON.parse(a):void 0,m=i?.page||1,c=i?.queries||["normal","erc20"],l=(c.includes("normal")?await etherscanSdk.getNormalTxs(s,!t,{page:m,offset:r}):[]).map(u=>G({tx:u,chainId:e,networkToken:o,explorerUrl:n,address:s})),p=(c.includes("erc20")?await etherscanSdk.getErc20Txs(s,!t,void 0,{page:m,offset:r}):[]).map(u=>_({tx:u,address:s,explorerUrl:n,chainId:e})),g=p.map(u=>u.hash),d=l.filter(u=>!g.includes(u.hash)),T={queries:[],page:m+1};return l.length&&T.queries.push("normal"),p.length&&T.queries.push("erc20"),{transactions:[...d,...p],nextPageToken:T.queries.length?JSON.stringify(T):""}};var B=t=>t===1||t===5||t===4||t===11155111;var q=({nativeTransaction:t,erc20Transfers:e,erc721Transfers:o},n,s)=>{let a=!e&&!o,r=kt(t.method?.methodName),i=n.toLowerCase(),m=r.toLowerCase().includes("swap"),c=a&&t.from.address.toLowerCase()===i,l=a&&t.to.address.toLowerCase()===i,p=r==="Market Buy Orders With Eth"||r==="Buy NFT",g=r==="Approve",d=r.toLowerCase().includes("transfer"),T=r.toLowerCase().includes("airdrop"),u=r.toLowerCase().includes("unwrap"),y=r==="Fill Order",x=d&&!!s[0]&&W(s[0].type)&&s[0].from?.address.toLowerCase()===i,S=d&&!!s[0]&&W(s[0].type)&&s[0].to?.address.toLowerCase()===i;return m?vmModuleTypes.TransactionType.SWAP:c?vmModuleTypes.TransactionType.SEND:l?vmModuleTypes.TransactionType.RECEIVE:p?vmModuleTypes.TransactionType.NFT_BUY:g?vmModuleTypes.TransactionType.APPROVE:x?vmModuleTypes.TransactionType.NFT_SEND:S?vmModuleTypes.TransactionType.NFT_RECEIVE:d?vmModuleTypes.TransactionType.TRANSFER:T?vmModuleTypes.TransactionType.AIRDROP:u?vmModuleTypes.TransactionType.UNWRAP:y?vmModuleTypes.TransactionType.FILL_ORDER:vmModuleTypes.TransactionType.UNKNOWN};function W(t){return t===vmModuleTypes.TokenType.ERC721||t===vmModuleTypes.TokenType.ERC1155}var kt=(t="")=>t.includes("(")?ht__default.default(t.split("(",1)[0]):t;var $=(t,{nativeTransaction:e,erc20Transfers:o,erc721Transfers:n},s)=>{let a=t===vmModuleTypes.TransactionType.TRANSFER,r=t===vmModuleTypes.TransactionType.SEND,i=t===vmModuleTypes.TransactionType.RECEIVE,m=e?.from?.address,c=e?.to?.address;a&&o&&o[0]&&(m=o[0].from.address,c=o[0].to.address),a&&n&&n[0]&&(m=n[0].from.address,c=n[0].to.address);let l=r||a&&m.toLowerCase()===s.toLowerCase(),p=i||a&&c.toLowerCase()===s.toLowerCase();return {isOutgoing:l,isIncoming:p,isSender:m===s,from:m,to:c}};async function j(t){try{return t.then(e=>[e,null]).catch(e=>[null,e])}catch(e){return Promise.resolve([null,e])}}var wt="https://cloudflare-ipfs.com";function h(t,e=wt){if(!t)return "";try{return utilsSdk.ipfsResolver(t,e)}catch{return t}}async function vt(t,e=5e3){let o=new AbortController;return setTimeout(()=>o.abort(),e),fetch(t,{signal:o.signal})}async function K(t){let e={};if(t)if(t.startsWith("data:application/json;base64,")){let o=t.substring(29);try{let n=Buffer.from(o,"base64").toString();e=JSON.parse(n);}catch{e={};}}else e=await vt(h(t)).then(o=>o.json()).catch(()=>({}));else return {};return e}var xt="https://image-proxy.svc.prod.covalenthq.com/cdn-cgi/image";function J(t,e="256"){let o=h(t);return `${xt}/width=${e},fit/${o}`}var Q=async({nativeTransaction:t,erc20Transfers:e,erc721Transfers:o,erc1155Transfers:n},s)=>{let a=[];if(t.value!=="0"){let r=s.decimals,i=new bn_js.BN(t.value),m=utilsSdk.balanceToDisplayValue(i,r);a.push({decimal:r.toString(),name:s.name,symbol:s.symbol,amount:m,from:t.from,to:t.to,type:vmModuleTypes.TokenType.NATIVE});}return e?.forEach(r=>{let i=r.erc20Token.decimals,m=new bn_js.BN(r.value),c=utilsSdk.balanceToDisplayValue(m,i);a.push({decimal:i.toString(),name:r.erc20Token.name,symbol:r.erc20Token.symbol,amount:c,from:r.from,to:r.to,imageUri:r.erc20Token.logoUri,type:vmModuleTypes.TokenType.ERC20});}),o&&await Promise.allSettled(o.map(async r=>{let i=r.erc721Token,m=await Z(i.tokenUri,i.metadata.imageUri);a.push({name:r.erc721Token.name,symbol:r.erc721Token.symbol,amount:"1",imageUri:m,from:r.from,to:r.to,collectableTokenId:r.erc721Token.tokenId,type:vmModuleTypes.TokenType.ERC721});})),n&&await Promise.allSettled(n.map(async r=>{let i=r.erc1155Token,m=await Z(i.tokenUri,i.metadata.imageUri);a.push({name:r.erc1155Token.metadata.name??"",symbol:r.erc1155Token.metadata.symbol??"",amount:r.value,imageUri:m,from:r.from,to:r.to,collectableTokenId:r.erc1155Token.tokenId,type:vmModuleTypes.TokenType.ERC1155});})),a},Z=async(t,e)=>{if(e)return e.startsWith("ipfs://")?h(e):e;{let[o,n]=await j(K(t));return n?"":o.image?J(o.image):""}};var X=[vmModuleTypes.TransactionType.SEND,vmModuleTypes.TransactionType.RECEIVE,vmModuleTypes.TransactionType.TRANSFER];var tt=async({transactions:t,explorerUrl:e,networkToken:o,chainId:n,address:s})=>{let a=await Q(t,o),r=q(t,s,a),{isOutgoing:i,isIncoming:m,isSender:c,from:l,to:p}=$(r,t,s),{blockTimestamp:g,txHash:d,gasPrice:T,gasUsed:u}=t.nativeTransaction,y=E(e,d);return {isContractCall:!X.includes(r),isIncoming:m,isOutgoing:i,isSender:c,timestamp:g*1e3,hash:d,from:l,to:p,tokens:a,gasPrice:T,gasUsed:u,chainId:n.toString(),txType:r,explorerLink:y}};var et=async({chainId:t,explorerUrl:e,networkToken:o,address:n,nextPageToken:s,offset:a,glacierApiUrl:r})=>{if(!r)throw new Error("Glacier API URL is required");let i=new glacierSdk.Glacier({BASE:r});try{let m=await i.evmTransactions.listTransactions({chainId:t.toString(),address:n,pageToken:s,pageSize:a});return {transactions:(await Promise.all(m.transactions.filter(p=>p.nativeTransaction.txStatus==="1").map(p=>tt({transactions:p,explorerUrl:e,networkToken:o,chainId:t,address:n}).then(g=>g)))).filter(p=>p.tokens.find(g=>Number(g.amount)!==0)),nextPageToken:m.nextPageToken}}catch{return {transactions:[],nextPageToken:""}}};var ot=async({chainId:t,isTestnet:e,networkToken:o,explorerUrl:n,address:s,nextPageToken:a,offset:r,glacierApiUrl:i})=>B(t)?O({isTestnet:e,networkToken:o,explorerUrl:n,chainId:t,address:s,nextPageToken:a,offset:r}):et({isTestnet:e,networkToken:o,explorerUrl:n,chainId:t,address:s,nextPageToken:a,offset:r,glacierApiUrl:i});async function rt({chainId:t,proxyApiUrl:e}){let o=await fetch(`${e}/tokens?evmChainId=${t}`);if(!o.ok)throw new Error(`Failed to fetch tokens for chainId ${t}`);return o.json()}var nt={name:"EVM",description:"",version:"0.0.1",sources:{module:{checksum:"",location:{npm:{filePath:"dist/bundle.js",packageName:"@avalabs/evm-module",registry:"https://registry.npmjs.org"}}},provider:{checksum:"",location:{npm:{filePath:"dist/provider.js",packageName:"@avalabs/evm-module",registry:"https://registry.npmjs.org"}}}},network:{chainIds:["eip155:1","eip155:43114","eip155:43113"],namespaces:["eip155"]},cointype:"60",permissions:{rpc:{dapps:!0,methods:["eth_sendTransaction","eth_*","getTransactionHistory"]}},manifestVersion:"0.0"};var k,w,v,st=class{constructor({glacierApiUrl:e,glacierApiKey:o,proxyApiUrl:n}){R(this,k,void 0);R(this,w,void 0);R(this,v,void 0);P(this,k,e),P(this,w,o),P(this,v,n);}getAddress(){return Promise.resolve("EVM address")}getBalances(){return Promise.resolve("EVM balances")}getManifest(){let e=vmModuleTypes.parseManifest(nt);return e.success?e.data:void 0}getNetworkFee({chainId:e,chainName:o,rpcUrl:n,multiContractAddress:s}){return M({glacierApiUrl:N(this,k),glacierApiKey:N(this,w),chainId:e,chainName:o,rpcUrl:n,multiContractAddress:s})}getTransactionHistory(e){return ot({...e,glacierApiUrl:N(this,k)})}getTokens(e){return rt({chainId:e,proxyApiUrl:N(this,v)})}async onRpcRequest(e){switch(e.method){default:return {error:new Error(`Method ${e.method} not supported`)}}}};k=new WeakMap,w=new WeakMap,v=new WeakMap;
|
|
18
|
+
var H=(t,e,o)=>{if(!e.has(t))throw TypeError("Cannot "+o)};var N=(t,e,o)=>(H(t,e,"read from private field"),o?o.call(t):e.get(t)),P=(t,e,o)=>{if(e.has(t))throw TypeError("Cannot add the same private member more than once");e instanceof WeakSet?e.add(t):e.set(t,o);},I=(t,e,o,n)=>(H(t,e,"write to private field"),n?n.call(t,o):e.set(t,o),o);async function M({chainId:t,proxyApiUrl:e}){let o=await fetch(`${e}/tokens?evmChainId=${t}`);if(!o.ok)throw rpcErrors.rpcErrors.internal(`Failed to fetch tokens for chainId ${t}`);return o.json()}var yt=process.env.GLACIER_API_KEY,b=t=>{let{chainId:e,chainName:o,rpcUrl:n,multiContractAddress:a,pollingInterval:s=2e3}=t,r=new walletsSdk.JsonRpcBatchInternal({maxCalls:40,multiContractAddress:a},Et(n,yt),new ethers.Network(o,e));return r.pollingInterval=s,r},ht=["glacier-api.avax.network","proxy-api.avax.network"];function Et(t,e){let o=new URL(t);if(e&&ht.includes(o.hostname)){let n=o.searchParams;return n.set("token",e),o.search=n.toString(),o.toString()}return t}var U={LOW:1n,MEDIUM:4n,HIGH:6n},F=500000000n;async function _({chainId:t,chainName:e,rpcUrl:o,multiContractAddress:n}){let a=b({chainId:t,chainName:e,rpcUrl:o,multiContractAddress:n}),{maxFeePerGas:s}=await a.getFeeData();if(!s)throw rpcErrors.rpcErrors.internal("Pre-EIP-1559 networks are not supported");let r=F*U.LOW,i=F*U.MEDIUM,c=F*U.HIGH;return {baseFee:s,low:{maxFeePerGas:s+r,maxPriorityFeePerGas:r},medium:{maxFeePerGas:s+i,maxPriorityFeePerGas:i},high:{maxFeePerGas:s+c,maxPriorityFeePerGas:c}}}function E(t,e,o="tx"){return `${t}/${o}/${e}`}var B=({tx:t,networkToken:e,chainId:o,explorerUrl:n,address:a})=>{let s=t.from.toLowerCase()===a.toLowerCase(),r=parseInt(t.timeStamp)*1e3,i=e.decimals,c=new bn_js.BN(t.value),m=utilsSdk.balanceToDisplayValue(c,i),u=s?vmModuleTypes.TransactionType.SEND:vmModuleTypes.TransactionType.RECEIVE,{from:p,to:l,gasPrice:d,gasUsed:f,hash:g}=t,h=E(n,g);return {isIncoming:!s,isOutgoing:s,isContractCall:wt(t),timestamp:r,hash:g,isSender:s,from:p,to:l,tokens:[{decimal:i.toString(),name:e.name,symbol:e.symbol,amount:m,type:vmModuleTypes.TokenType.NATIVE}],gasUsed:f,gasPrice:d,chainId:o.toString(),txType:u,explorerLink:h}};function wt(t){return t.input!=="0x"}function V({tx:t,address:e,explorerUrl:o,chainId:n}){let a=t.from.toLowerCase()===e.toLowerCase(),s=parseInt(t.timeStamp)*1e3,r=parseInt(t.tokenDecimal),i=new bn_js.BN(t.value),c=utilsSdk.balanceToDisplayValue(i,r),{from:m,to:u,gasPrice:p,gasUsed:l,hash:d,tokenDecimal:f,tokenName:g,tokenSymbol:h}=t,R=a?vmModuleTypes.TransactionType.SEND:vmModuleTypes.TransactionType.RECEIVE,A=E(o,d);return {isIncoming:!a,isOutgoing:a,isContractCall:!1,timestamp:s,hash:d,isSender:a,from:m,to:u,tokens:[{decimal:f,name:g,symbol:h,type:vmModuleTypes.TokenType.ERC20,amount:c}],gasUsed:l,gasPrice:p,chainId:n.toString(),txType:R,explorerLink:A}}var W=async({isTestnet:t,networkToken:e,explorerUrl:o,chainId:n,address:a,nextPageToken:s,offset:r})=>{let i=s?JSON.parse(s):void 0,c=i?.page||1,m=i?.queries||["normal","erc20"],u=(m.includes("normal")?await etherscanSdk.getNormalTxs(a,!t,{page:c,offset:r}):[]).map(g=>B({tx:g,chainId:n,networkToken:e,explorerUrl:o,address:a})),p=(m.includes("erc20")?await etherscanSdk.getErc20Txs(a,!t,void 0,{page:c,offset:r}):[]).map(g=>V({tx:g,address:a,explorerUrl:o,chainId:n})),l=p.map(g=>g.hash),d=u.filter(g=>!l.includes(g.hash)),f={queries:[],page:c+1};return u.length&&f.queries.push("normal"),p.length&&f.queries.push("erc20"),{transactions:[...d,...p],nextPageToken:f.queries.length?JSON.stringify(f):""}};var q=t=>t===1||t===5||t===4||t===11155111;var $=({nativeTransaction:t,erc20Transfers:e,erc721Transfers:o},n,a)=>{let s=!e&&!o,r=At(t.method?.methodName),i=n.toLowerCase(),c=r.toLowerCase().includes("swap"),m=s&&t.from.address.toLowerCase()===i,u=s&&t.to.address.toLowerCase()===i,p=r==="Market Buy Orders With Eth"||r==="Buy NFT",l=r==="Approve",d=r.toLowerCase().includes("transfer"),f=r.toLowerCase().includes("airdrop"),g=r.toLowerCase().includes("unwrap"),h=r==="Fill Order",R=d&&!!a[0]&&j(a[0].type)&&a[0].from?.address.toLowerCase()===i,A=d&&!!a[0]&&j(a[0].type)&&a[0].to?.address.toLowerCase()===i;return c?vmModuleTypes.TransactionType.SWAP:m?vmModuleTypes.TransactionType.SEND:u?vmModuleTypes.TransactionType.RECEIVE:p?vmModuleTypes.TransactionType.NFT_BUY:l?vmModuleTypes.TransactionType.APPROVE:R?vmModuleTypes.TransactionType.NFT_SEND:A?vmModuleTypes.TransactionType.NFT_RECEIVE:d?vmModuleTypes.TransactionType.TRANSFER:f?vmModuleTypes.TransactionType.AIRDROP:g?vmModuleTypes.TransactionType.UNWRAP:h?vmModuleTypes.TransactionType.FILL_ORDER:vmModuleTypes.TransactionType.UNKNOWN};function j(t){return t===vmModuleTypes.TokenType.ERC721||t===vmModuleTypes.TokenType.ERC1155}var At=(t="")=>t.includes("(")?St__default.default(t.split("(",1)[0]):t;var Y=(t,{nativeTransaction:e,erc20Transfers:o,erc721Transfers:n},a)=>{let s=t===vmModuleTypes.TransactionType.TRANSFER,r=t===vmModuleTypes.TransactionType.SEND,i=t===vmModuleTypes.TransactionType.RECEIVE,c=e?.from?.address,m=e?.to?.address;s&&o&&o[0]&&(c=o[0].from.address,m=o[0].to.address),s&&n&&n[0]&&(c=n[0].from.address,m=n[0].to.address);let u=r||s&&c.toLowerCase()===a.toLowerCase(),p=i||s&&m.toLowerCase()===a.toLowerCase();return {isOutgoing:u,isIncoming:p,isSender:c===a,from:c,to:m}};async function K(t){try{return t.then(e=>[e,null]).catch(e=>[null,e])}catch(e){return Promise.resolve([null,e])}}var Ft="https://cloudflare-ipfs.com";function v(t,e=Ft){if(!t)return "";try{return utilsSdk.ipfsResolver(t,e)}catch{return t}}async function Dt(t,e=5e3){let o=new AbortController;return setTimeout(()=>o.abort(),e),fetch(t,{signal:o.signal})}async function z(t){let e={};if(t)if(t.startsWith("data:application/json;base64,")){let o=t.substring(29);try{let n=Buffer.from(o,"base64").toString();e=JSON.parse(n);}catch{e={};}}else e=await Dt(v(t)).then(o=>o.json()).catch(()=>({}));else return {};return e}var Lt="https://image-proxy.svc.prod.covalenthq.com/cdn-cgi/image";function Z(t,e="256"){let o=v(t);return `${Lt}/width=${e},fit/${o}`}var et=async({nativeTransaction:t,erc20Transfers:e,erc721Transfers:o,erc1155Transfers:n},a)=>{let s=[];if(t.value!=="0"){let r=a.decimals,i=new bn_js.BN(t.value),c=utilsSdk.balanceToDisplayValue(i,r);s.push({decimal:r.toString(),name:a.name,symbol:a.symbol,amount:c,from:t.from,to:t.to,type:vmModuleTypes.TokenType.NATIVE});}return e?.forEach(r=>{let i=r.erc20Token.decimals,c=new bn_js.BN(r.value),m=utilsSdk.balanceToDisplayValue(c,i);s.push({decimal:i.toString(),name:r.erc20Token.name,symbol:r.erc20Token.symbol,amount:m,from:r.from,to:r.to,imageUri:r.erc20Token.logoUri,type:vmModuleTypes.TokenType.ERC20});}),o&&await Promise.allSettled(o.map(async r=>{let i=r.erc721Token,c=await tt(i.tokenUri,i.metadata.imageUri);s.push({name:r.erc721Token.name,symbol:r.erc721Token.symbol,amount:"1",imageUri:c,from:r.from,to:r.to,collectableTokenId:r.erc721Token.tokenId,type:vmModuleTypes.TokenType.ERC721});})),n&&await Promise.allSettled(n.map(async r=>{let i=r.erc1155Token,c=await tt(i.tokenUri,i.metadata.imageUri);s.push({name:r.erc1155Token.metadata.name??"",symbol:r.erc1155Token.metadata.symbol??"",amount:r.value,imageUri:c,from:r.from,to:r.to,collectableTokenId:r.erc1155Token.tokenId,type:vmModuleTypes.TokenType.ERC1155});})),s},tt=async(t,e)=>{if(e)return e.startsWith("ipfs://")?v(e):e;{let[o,n]=await K(z(t));return n?"":o.image?Z(o.image):""}};var rt=[vmModuleTypes.TransactionType.SEND,vmModuleTypes.TransactionType.RECEIVE,vmModuleTypes.TransactionType.TRANSFER];var ot=async({transactions:t,explorerUrl:e,networkToken:o,chainId:n,address:a})=>{let s=await et(t,o),r=$(t,a,s),{isOutgoing:i,isIncoming:c,isSender:m,from:u,to:p}=Y(r,t,a),{blockTimestamp:l,txHash:d,gasPrice:f,gasUsed:g}=t.nativeTransaction,h=E(e,d);return {isContractCall:!rt.includes(r),isIncoming:c,isOutgoing:i,isSender:m,timestamp:l*1e3,hash:d,from:u,to:p,tokens:s,gasPrice:f,gasUsed:g,chainId:n.toString(),txType:r,explorerLink:h}};var nt=async({chainId:t,explorerUrl:e,networkToken:o,address:n,nextPageToken:a,offset:s,glacierApiUrl:r})=>{if(!r)throw rpcErrors.rpcErrors.invalidParams("Glacier API URL is required");let i=new glacierSdk.Glacier({BASE:r});try{let c=await i.evmTransactions.listTransactions({chainId:t.toString(),address:n,pageToken:a,pageSize:s});return {transactions:(await Promise.all(c.transactions.filter(p=>p.nativeTransaction.txStatus==="1").map(p=>ot({transactions:p,explorerUrl:e,networkToken:o,chainId:t,address:n}).then(l=>l)))).filter(p=>p.tokens.find(l=>Number(l.amount)!==0)),nextPageToken:c.nextPageToken}}catch{return {transactions:[],nextPageToken:""}}};var at=async({chainId:t,isTestnet:e,networkToken:o,explorerUrl:n,address:a,nextPageToken:s,offset:r,glacierApiUrl:i})=>q(t)?W({isTestnet:e,networkToken:o,explorerUrl:n,chainId:t,address:a,nextPageToken:s,offset:r}):nt({networkToken:o,explorerUrl:n,chainId:t,address:a,nextPageToken:s,offset:r,glacierApiUrl:i});var st={name:"EVM",description:"",version:"0.0.1",sources:{module:{checksum:"",location:{npm:{filePath:"dist/bundle.js",packageName:"@avalabs/evm-module",registry:"https://registry.npmjs.org"}}},provider:{checksum:"",location:{npm:{filePath:"dist/provider.js",packageName:"@avalabs/evm-module",registry:"https://registry.npmjs.org"}}}},network:{chainIds:["eip155:1","eip155:43114","eip155:43113"],namespaces:["eip155"]},cointype:"60",permissions:{rpc:{dapps:!0,methods:["eth_sendTransaction","eth_*","getTransactionHistory"]}},manifestVersion:"0.0"};var Ot={glacierApiUrl:"https://glacier-api.avax.network",proxyApiUrl:"https://proxy-api.avax.network"},Bt={glacierApiUrl:"https://glacier-api-dev.avax.network",proxyApiUrl:"https://proxy-api-dev.avax.network"},ct=t=>{switch(t){case vmModuleTypes.Environment.PRODUCTION:return Ot;case vmModuleTypes.Environment.DEV:return Bt}};var Gt=zod.z.object({from:zod.z.string().length(42),to:zod.z.string().length(42),data:zod.z.string().optional(),value:zod.z.string().startsWith("0x").optional(),gas:zod.z.string().startsWith("0x").optional(),gasPrice:zod.z.string().startsWith("0x").optional(),maxFeePerGas:zod.z.string().startsWith("0x").optional(),maxPriorityFeePerGas:zod.z.string().startsWith("0x").optional(),nonce:zod.z.string().optional(),chainId:zod.z.string().optional()}),Vt=zod.z.array(Gt).length(1),mt=t=>Vt.safeParse(t);var pt=async({transactionParams:{from:t,to:e,data:o,value:n},provider:a})=>{let s=await a.getTransactionCount(t);return Number(await a.estimateGas({from:t,to:e,nonce:s,data:o,value:n}))};var lt=async({from:t,provider:e})=>e.getTransactionCount(t);var ut=async({request:t,network:e,approvalController:o})=>{let{dappInfo:n,params:a}=t,s=mt(a);if(!s.success)return console.error(s.error),{error:rpcErrors.rpcErrors.invalidParams("Transaction params are invalid")};let r=s.data[0];if(!r)return {error:rpcErrors.rpcErrors.invalidParams("Transaction params are invalid")};let i=b({chainId:e.chainId,chainName:e.chainName,rpcUrl:e.rpcUrl,multiContractAddress:e.utilityAddresses?.multicall,pollingInterval:1e3});if(!r.gas||Number(r.gas)<0)try{let l=await pt({transactionParams:{from:r.from,to:r.to,data:r.data,value:r.value},provider:i});r.gas="0x"+l.toString(16);}catch{return {error:rpcErrors.rpcErrors.internal("Unable to calculate gas limit")}}if(!r.nonce)try{let l=await lt({from:r.from,provider:i});r.nonce=String(l);}catch{return {error:rpcErrors.rpcErrors.internal("Unable to calculate nonce")}}let c={title:"Approve Transaction",network:{chainId:e.chainId,name:e.chainName,logoUrl:e.logoUrl},transactionDetails:{website:new URL(n.url).hostname,from:r.from,to:r.to,data:r.data},networkFeeSelector:!0},m={type:vmModuleTypes.SigningDataType.EVM_TRANSACTION,account:r.from,chainId:e.chainId,data:{type:2,nonce:Number(r.nonce),gasLimit:Number(r.gas),to:r.to,from:r.from,data:r.data,value:r.value,chainId:r.chainId}},u=await o.requestApproval({request:t,displayData:c,signingData:m});if("error"in u)return {error:u.error};let p=await i.send("eth_sendRawTransaction",[u.result]);return qt({provider:i,txHash:p,onTransactionConfirmed:o.onTransactionConfirmed,onTransactionReverted:o.onTransactionReverted}),{result:p}},qt=async({provider:t,txHash:e,onTransactionConfirmed:o,onTransactionReverted:n})=>{(await t.waitForTransaction(e))?.status===1?o(e):n(e);};var k,x,w,gt=class{constructor({approvalController:e,environment:o}){P(this,k,void 0);P(this,x,void 0);P(this,w,void 0);let{glacierApiUrl:n,proxyApiUrl:a}=ct(o);I(this,k,n),I(this,x,a),I(this,w,e);}getAddress(){return Promise.resolve("EVM address")}getBalances(){return Promise.resolve("EVM balances")}getManifest(){let e=vmModuleTypes.parseManifest(st);return e.success?e.data:void 0}getNetworkFee(e){let{chainId:o,chainName:n,rpcUrl:a,utilityAddresses:s}=e;return _({chainId:o,chainName:n,rpcUrl:a,multiContractAddress:s?.multicall,glacierApiUrl:N(this,k)})}getTransactionHistory(e){let{network:o,address:n,nextPageToken:a,offset:s}=e,{chainId:r,isTestnet:i,networkToken:c,explorerUrl:m=""}=o;return at({chainId:r,isTestnet:i,networkToken:c,explorerUrl:m,address:n,nextPageToken:a,offset:s,glacierApiUrl:N(this,k)})}getTokens(e){let{chainId:o}=e;return M({chainId:o,proxyApiUrl:N(this,x)})}async onRpcRequest(e,o){switch(e.method){case vmModuleTypes.RpcMethod.ETH_SEND_TRANSACTION:return ut({request:e,network:o,approvalController:N(this,w)});default:return {error:rpcErrors.rpcErrors.methodNotSupported(`Method ${e.method} not supported`)}}}};k=new WeakMap,x=new WeakMap,w=new WeakMap;
|
|
17
19
|
|
|
18
|
-
exports.EvmModule =
|
|
20
|
+
exports.EvmModule = gt;
|
|
21
|
+
exports.NonContractCallTypes = rt;
|
|
19
22
|
//# sourceMappingURL=out.js.map
|
|
20
23
|
//# sourceMappingURL=index.cjs.map
|
package/dist/index.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.ts","../src/utils/get-provider.ts","../src/handlers/get-network-fee/get-network-fee.ts","../src/handlers/get-transaction-history/converters/etherscan-transaction-converter/convert-transaction-normal.ts","../src/handlers/get-transaction-history/utils/get-explorer-address-by-network.ts","../src/handlers/get-transaction-history/converters/etherscan-transaction-converter/convert-transaction-erc20.ts","../src/handlers/get-transaction-history/converters/etherscan-transaction-converter/get-transaction-from-etherscan.ts","../src/handlers/get-transaction-history/utils/is-ethereum-chain-id.ts","../src/handlers/get-transaction-history/converters/evm-transaction-converter/get-transactions-from-glacier.ts","../src/handlers/get-transaction-history/converters/evm-transaction-converter/get-tx-type.ts","../src/handlers/get-transaction-history/converters/evm-transaction-converter/get-sender-info.ts","../src/handlers/get-transaction-history/converters/evm-transaction-converter/get-tokens.ts","../src/handlers/get-transaction-history/utils/resolve.ts","../src/handlers/get-transaction-history/utils/ipfs-resolver-with-fallback.ts","../src/handlers/get-transaction-history/converters/evm-transaction-converter/get-nft-metadata.ts","../src/handlers/get-transaction-history/utils/get-small-image-for-nft.ts","../src/types.ts","../src/handlers/get-transaction-history/converters/evm-transaction-converter/convert-transaction.ts","../src/handlers/get-transaction-history/get-transaction-history.ts","../src/handlers/get-tokens/get-tokens.ts","../src/manifest.json"],"names":["parseManifest","JsonRpcBatchInternal","Network","getProvider","glacierApiKey","caip2ChainId","chainName","rpcUrl","multiContractAddress","chainId","provider","addGlacierAPIKeyIfNeeded","knownHosts","url","urlObj","search_params","DEFAULT_PRESETS","BASE_PRIORITY_FEE_WEI","getNetworkFee","glacierApiUrl","maxFeePerGasInWei","lowMaxTip","mediumMaxTip","highMaxTip","TokenType","TransactionType","balanceToDisplayValue","BN","getExplorerAddressByNetwork","explorerUrl","hash","hashType","convertTransactionNormal","tx","networkToken","address","isSender","timestamp","decimals","amountBN","amountDisplayValue","txType","from","to","gasPrice","gasUsed","explorerLink","isContractCall","convertTransactionERC20","tokenDecimal","tokenName","tokenSymbol","getErc20Txs","getNormalTxs","getTransactionFromEtherscan","isTestnet","nextPageToken","offset","parsedPageToken","page","queries","normalHist","erc20Hist","erc20TxHashes","filteredNormalTxs","next","isEthereumChainId","Glacier","startCase","getTxType","nativeTransaction","erc20Transfers","erc721Transfers","userAddress","tokens","nativeOnly","method","parseRawMethod","isSwap","isNativeSend","isNativeReceive","isNFTPurchase","isApprove","isTransfer","isAirdrop","isUnwrap","isFillOrder","isNFTSend","isNFT","isNFTReceive","tokenType","getSenderInfo","isOutgoing","isIncoming","resolve","promise","res","err","ipfsResolver","CLOUDFLARE_IPFS_URL","ipfsResolverWithFallback","sourceUrl","desiredGatewayPrefix","fetchWithTimeout","uri","timeout","controller","getNftMetadata","tokenUri","data","value","json","r","COVALENT_IMG_SIZER","getSmallImageForNFT","imgUrl","imageSize","getTokens","erc1155Transfers","result","decimal","erc20Transfer","erc721Transfer","token","imageUri","getImageUri","erc1155Transfer","metadata","error","NonContractCallTypes","convertTransaction","transactions","blockTimestamp","getTransactionsFromGlacier","glacierSdk","response","tranasaction","transaction","getTransactionHistory","proxyApiUrl","manifest_default","_glacierApiUrl","_glacierApiKey","_proxyApiUrl","EvmModule","__privateAdd","__privateSet","__privateGet","params","request"],"mappings":"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","sourcesContent":["import type {\n Module,\n Manifest,\n NetworkFees,\n GetTransactionHistory,\n RpcRequest,\n GetNetworkFeeParams,\n} from '@avalabs/vm-module-types';\nimport { parseManifest } from '@avalabs/vm-module-types';\nimport { getNetworkFee } from './handlers/get-network-fee/get-network-fee';\nimport { getTransactionHistory } from './handlers/get-transaction-history/get-transaction-history';\nimport { getTokens } from './handlers/get-tokens/get-tokens';\nimport ManifestJson from './manifest.json';\n\nexport class EvmModule implements Module {\n #glacierApiUrl: string;\n #glacierApiKey?: string;\n #proxyApiUrl: string;\n\n constructor({\n glacierApiUrl,\n glacierApiKey,\n proxyApiUrl,\n }: {\n glacierApiUrl: string;\n glacierApiKey?: string;\n proxyApiUrl: string;\n }) {\n this.#glacierApiUrl = glacierApiUrl;\n this.#glacierApiKey = glacierApiKey;\n this.#proxyApiUrl = proxyApiUrl;\n }\n getAddress(): Promise<string> {\n return Promise.resolve('EVM address');\n }\n\n getBalances(): Promise<string> {\n return Promise.resolve('EVM balances');\n }\n\n getManifest(): Manifest | undefined {\n const result = parseManifest(ManifestJson);\n return result.success ? result.data : undefined;\n }\n\n getNetworkFee({ chainId, chainName, rpcUrl, multiContractAddress }: GetNetworkFeeParams): Promise<NetworkFees> {\n return getNetworkFee({\n glacierApiUrl: this.#glacierApiUrl,\n glacierApiKey: this.#glacierApiKey,\n chainId,\n chainName,\n rpcUrl,\n multiContractAddress,\n });\n }\n\n getTransactionHistory(params: GetTransactionHistory) {\n return getTransactionHistory({ ...params, glacierApiUrl: this.#glacierApiUrl });\n }\n\n getTokens(chainId: number) {\n return getTokens({ chainId, proxyApiUrl: this.#proxyApiUrl });\n }\n\n async onRpcRequest(request: RpcRequest) {\n // TODO implement the RPC request handler\n switch (request.method) {\n default:\n return { error: new Error(`Method ${request.method} not supported`) };\n }\n }\n}\n","import type { GetNetworkFeeParams } from '@avalabs/vm-module-types';\nimport { JsonRpcBatchInternal } from '@avalabs/wallets-sdk';\nimport { Network } from 'ethers';\n\nexport const getProvider = ({\n glacierApiKey,\n chainId: caip2ChainId,\n chainName,\n rpcUrl,\n multiContractAddress,\n}: GetNetworkFeeParams & {\n glacierApiUrl: string;\n glacierApiKey?: string;\n}): JsonRpcBatchInternal => {\n if (!caip2ChainId || !chainName || !rpcUrl) {\n throw new Error('Missing required parameters');\n }\n\n const chainId = caip2ChainId.split(':')[1];\n if (!chainId || isNaN(Number(chainId))) {\n throw new Error('Invalid chainId');\n }\n\n const provider = new JsonRpcBatchInternal(\n { maxCalls: 40, multiContractAddress },\n addGlacierAPIKeyIfNeeded(rpcUrl, glacierApiKey),\n new Network(chainName, Number(chainId)),\n );\n\n provider.pollingInterval = 2000;\n\n return provider;\n};\n\n// RPC urls returned in the token list are always using the production URL\nconst knownHosts = ['glacier-api.avax.network', 'proxy-api.avax.network'];\n\n/**\n * Glacier needs an API key for development, this adds the key if needed.\n */\nexport function addGlacierAPIKeyIfNeeded(url: string, glacierApiKey?: string): string {\n const urlObj = new URL(url);\n\n if (glacierApiKey && knownHosts.includes(urlObj.hostname)) {\n const search_params = urlObj.searchParams; // copy, does not update the URL\n search_params.set('token', glacierApiKey);\n urlObj.search = search_params.toString();\n return urlObj.toString();\n }\n return url;\n}\n","import type { GetNetworkFeeParams, NetworkFees } from '@avalabs/vm-module-types';\nimport { getProvider } from '../../utils/get-provider';\n\nconst DEFAULT_PRESETS = {\n LOW: 1n,\n MEDIUM: 4n,\n HIGH: 6n,\n};\n\nconst BASE_PRIORITY_FEE_WEI = 500000000n; //0.5 GWei\n\n/**\n * Returns {@link NetworkFees} based on {@link DEFAULT_PRESETS} multipliers.\n * @param glacierApiUrl\n * @param glacierApiKey\n * @params GetNetworkFeeParams\n * @throws Error if provider does not support eip-1559\n */\nexport async function getNetworkFee({\n glacierApiUrl,\n glacierApiKey,\n chainId,\n chainName,\n rpcUrl,\n multiContractAddress,\n}: GetNetworkFeeParams & {\n glacierApiUrl: string;\n glacierApiKey?: string;\n}): Promise<NetworkFees> {\n const provider = getProvider({\n glacierApiUrl,\n glacierApiKey,\n chainId,\n chainName,\n rpcUrl,\n multiContractAddress,\n });\n const { maxFeePerGas: maxFeePerGasInWei } = await provider.getFeeData();\n if (!maxFeePerGasInWei) {\n throw new Error('Pre-EIP-1559 networks are not supported');\n }\n\n const lowMaxTip = BASE_PRIORITY_FEE_WEI * DEFAULT_PRESETS.LOW;\n const mediumMaxTip = BASE_PRIORITY_FEE_WEI * DEFAULT_PRESETS.MEDIUM;\n const highMaxTip = BASE_PRIORITY_FEE_WEI * DEFAULT_PRESETS.HIGH;\n return {\n baseFee: maxFeePerGasInWei,\n low: {\n maxFeePerGas: maxFeePerGasInWei + lowMaxTip,\n maxPriorityFeePerGas: lowMaxTip,\n },\n medium: {\n maxFeePerGas: maxFeePerGasInWei + mediumMaxTip,\n maxPriorityFeePerGas: mediumMaxTip,\n },\n high: {\n maxFeePerGas: maxFeePerGasInWei + highMaxTip,\n maxPriorityFeePerGas: highMaxTip,\n },\n };\n}\n","import type { NormalTx } from '@avalabs/etherscan-sdk';\nimport { TokenType, TransactionType, type NetworkToken, type Transaction } from '@avalabs/vm-module-types';\nimport { balanceToDisplayValue } from '@avalabs/utils-sdk';\nimport { BN } from 'bn.js';\nimport { getExplorerAddressByNetwork } from '../../utils/get-explorer-address-by-network';\n\nexport const convertTransactionNormal = ({\n tx,\n networkToken,\n chainId,\n explorerUrl,\n address,\n}: {\n tx: NormalTx;\n networkToken: NetworkToken;\n chainId: number;\n explorerUrl: string;\n address: string;\n}): Transaction => {\n const isSender = tx.from.toLowerCase() === address.toLowerCase();\n const timestamp = parseInt(tx.timeStamp) * 1000;\n const decimals = networkToken.decimals;\n const amountBN = new BN(tx.value);\n const amountDisplayValue = balanceToDisplayValue(amountBN, decimals);\n const txType = isSender ? TransactionType.SEND : TransactionType.RECEIVE;\n\n const { from, to, gasPrice, gasUsed, hash } = tx;\n const explorerLink = getExplorerAddressByNetwork(explorerUrl, hash);\n\n return {\n isIncoming: !isSender,\n isOutgoing: isSender,\n isContractCall: isContractCall(tx),\n timestamp,\n hash,\n isSender,\n from,\n to,\n tokens: [\n {\n decimal: decimals.toString(),\n name: networkToken.name,\n symbol: networkToken.symbol,\n amount: amountDisplayValue,\n type: TokenType.NATIVE,\n },\n ],\n gasUsed,\n gasPrice,\n chainId: chainId.toString(),\n txType,\n explorerLink,\n };\n};\n\nfunction isContractCall(tx: NormalTx): boolean {\n return tx.input !== '0x';\n}\n","export function getExplorerAddressByNetwork(\n explorerUrl: string,\n hash: string,\n hashType: 'address' | 'tx' = 'tx',\n): string {\n return `${explorerUrl}/${hashType}/${hash}`;\n}\n","import type { Erc20Tx } from '@avalabs/etherscan-sdk';\nimport { TokenType, TransactionType, type Transaction } from '@avalabs/vm-module-types';\nimport { balanceToDisplayValue } from '@avalabs/utils-sdk';\nimport { getExplorerAddressByNetwork } from '../../utils/get-explorer-address-by-network';\nimport { BN } from 'bn.js';\n\nexport function convertTransactionERC20({\n tx,\n address,\n explorerUrl,\n chainId,\n}: {\n tx: Erc20Tx;\n address: string;\n chainId: number;\n explorerUrl: string;\n}): Transaction {\n const isSender = tx.from.toLowerCase() === address.toLowerCase();\n const timestamp = parseInt(tx.timeStamp) * 1000;\n const decimals = parseInt(tx.tokenDecimal);\n const amountBN = new BN(tx.value);\n const amountDisplayValue = balanceToDisplayValue(amountBN, decimals);\n const { from, to, gasPrice, gasUsed, hash, tokenDecimal, tokenName, tokenSymbol } = tx;\n const txType = isSender ? TransactionType.SEND : TransactionType.RECEIVE;\n const explorerLink = getExplorerAddressByNetwork(explorerUrl, hash);\n\n return {\n isIncoming: !isSender,\n isOutgoing: isSender,\n isContractCall: false,\n timestamp,\n hash,\n isSender,\n from,\n to,\n tokens: [\n {\n decimal: tokenDecimal,\n name: tokenName,\n symbol: tokenSymbol,\n type: TokenType.ERC20,\n amount: amountDisplayValue,\n },\n ],\n gasUsed,\n gasPrice,\n chainId: chainId.toString(),\n txType,\n explorerLink,\n };\n}\n","import { convertTransactionNormal } from './convert-transaction-normal';\nimport { convertTransactionERC20 } from './convert-transaction-erc20';\nimport type { GetTransactionHistory, TransactionHistoryResponse } from '@avalabs/vm-module-types';\nimport { getErc20Txs, getNormalTxs } from '@avalabs/etherscan-sdk';\n\ninterface EtherscanPagination {\n queries: ('normal' | 'erc20')[];\n page?: number;\n}\n\nexport const getTransactionFromEtherscan = async ({\n isTestnet,\n chainId,\n networkToken,\n explorerUrl,\n address,\n nextPageToken,\n offset,\n}: GetTransactionHistory): Promise<TransactionHistoryResponse> => {\n /*\n Using JSON for nextPageToken because this function is managing both the Normal\n and ERC20 queries. It encodes the current page and the queries that should be\n run. For example, if 'normal' has no more records to fetch then it will be\n excluded from the list and the JSON will be something like:\n { page: 3, queries: ['erc20'] }\n */\n const parsedPageToken = nextPageToken ? (JSON.parse(nextPageToken) as EtherscanPagination) : undefined;\n const page = parsedPageToken?.page || 1;\n const queries = parsedPageToken?.queries || ['normal', 'erc20'];\n\n const normalHist = (queries.includes('normal') ? await getNormalTxs(address, !isTestnet, { page, offset }) : []).map(\n (tx) => convertTransactionNormal({ tx, chainId, networkToken, explorerUrl, address }),\n );\n\n const erc20Hist = (\n queries.includes('erc20')\n ? await getErc20Txs(address, !isTestnet, undefined, {\n page,\n offset,\n })\n : []\n ).map((tx) =>\n convertTransactionERC20({\n tx,\n address,\n explorerUrl,\n chainId,\n }),\n );\n\n // Filter erc20 transactions from normal tx list\n const erc20TxHashes = erc20Hist.map((tx) => tx.hash);\n const filteredNormalTxs = normalHist.filter((tx) => {\n return !erc20TxHashes.includes(tx.hash);\n });\n\n const next: EtherscanPagination = { queries: [], page: page + 1 };\n if (normalHist.length) next.queries.push('normal');\n if (erc20Hist.length) next.queries.push('erc20');\n\n return {\n transactions: [...filteredNormalTxs, ...erc20Hist],\n nextPageToken: next.queries.length ? JSON.stringify(next) : '', // stop pagination\n };\n};\n","enum ChainId {\n ETHEREUM_HOMESTEAD = 1,\n ETHEREUM_TEST_RINKEBY = 4,\n ETHEREUM_TEST_GOERLY = 5,\n ETHEREUM_TEST_SEPOLIA = 11155111,\n}\n\nexport const isEthereumChainId = (chainId: number): boolean => {\n return (\n ChainId.ETHEREUM_HOMESTEAD === chainId ||\n ChainId.ETHEREUM_TEST_GOERLY === chainId ||\n ChainId.ETHEREUM_TEST_RINKEBY === chainId ||\n ChainId.ETHEREUM_TEST_SEPOLIA === chainId\n );\n};\n","import type { GetTransactionHistory, TransactionHistoryResponse } from '@avalabs/vm-module-types';\nimport { Glacier } from '@avalabs/glacier-sdk';\nimport { convertTransaction } from './convert-transaction';\n\nexport const getTransactionsFromGlacier = async ({\n chainId,\n explorerUrl,\n networkToken,\n address,\n nextPageToken,\n offset,\n glacierApiUrl,\n}: GetTransactionHistory): Promise<TransactionHistoryResponse> => {\n if (!glacierApiUrl) {\n throw new Error('Glacier API URL is required');\n }\n\n const glacierSdk = new Glacier({ BASE: glacierApiUrl });\n\n try {\n const response = await glacierSdk.evmTransactions.listTransactions({\n chainId: chainId.toString(),\n address,\n pageToken: nextPageToken,\n pageSize: offset,\n });\n\n const convertedTxs = await Promise.all(\n response.transactions\n .filter(\n // Currently not showing failed tx\n (tranasaction) => tranasaction.nativeTransaction.txStatus === '1',\n )\n .map((transactions) =>\n convertTransaction({\n transactions,\n explorerUrl,\n networkToken,\n chainId,\n address,\n }).then((tx) => tx),\n ),\n );\n\n const transactions = convertedTxs.filter(\n // Filtering txs with 0 value since there is no change in balance\n (transaction) => transaction.tokens.find((token) => Number(token.amount) !== 0),\n );\n\n return {\n transactions,\n nextPageToken: response.nextPageToken,\n };\n } catch {\n return {\n transactions: [],\n nextPageToken: '',\n };\n }\n};\n","import type { TransactionDetails } from '@avalabs/glacier-sdk';\nimport { TokenType, TransactionType, type TxToken } from '@avalabs/vm-module-types';\nimport startCase from 'lodash.startcase';\n\nexport const getTxType = (\n { nativeTransaction, erc20Transfers, erc721Transfers }: TransactionDetails,\n userAddress: string,\n tokens: TxToken[],\n): TransactionType => {\n const nativeOnly = !erc20Transfers && !erc721Transfers;\n const method = parseRawMethod(nativeTransaction.method?.methodName);\n\n const address = userAddress.toLowerCase();\n\n const isSwap = method.toLowerCase().includes('swap');\n const isNativeSend = nativeOnly && nativeTransaction.from.address.toLowerCase() === address;\n const isNativeReceive = nativeOnly && nativeTransaction.to.address.toLowerCase() === address;\n const isNFTPurchase = method === 'Market Buy Orders With Eth' || method === 'Buy NFT';\n const isApprove = method === 'Approve';\n const isTransfer = method.toLowerCase().includes('transfer');\n const isAirdrop = method.toLowerCase().includes('airdrop');\n const isUnwrap = method.toLowerCase().includes('unwrap');\n const isFillOrder = method === 'Fill Order';\n const isNFTSend =\n isTransfer && !!tokens[0] && isNFT(tokens[0].type) && tokens[0].from?.address.toLowerCase() === address;\n const isNFTReceive =\n isTransfer && !!tokens[0] && isNFT(tokens[0].type) && tokens[0].to?.address.toLowerCase() === address;\n\n if (isSwap) return TransactionType.SWAP;\n if (isNativeSend) return TransactionType.SEND;\n if (isNativeReceive) return TransactionType.RECEIVE;\n if (isNFTPurchase) return TransactionType.NFT_BUY;\n if (isApprove) return TransactionType.APPROVE;\n if (isNFTSend) return TransactionType.NFT_SEND;\n if (isNFTReceive) return TransactionType.NFT_RECEIVE;\n if (isTransfer) return TransactionType.TRANSFER;\n if (isAirdrop) return TransactionType.AIRDROP;\n if (isUnwrap) return TransactionType.UNWRAP;\n if (isFillOrder) return TransactionType.FILL_ORDER;\n return TransactionType.UNKNOWN;\n};\n\nfunction isNFT(tokenType: TokenType) {\n return tokenType === TokenType.ERC721 || tokenType === TokenType.ERC1155;\n}\n\nconst parseRawMethod = (method = ''): string => {\n if (method.includes('(')) {\n return startCase(method.split('(', 1)[0]);\n }\n return method;\n};\n","import type { TransactionDetails } from '@avalabs/glacier-sdk';\nimport { TransactionType } from '@avalabs/vm-module-types';\n\nexport const getSenderInfo = (\n txType: TransactionType,\n { nativeTransaction, erc20Transfers, erc721Transfers }: TransactionDetails,\n address: string,\n): { isOutgoing: boolean; isIncoming: boolean; isSender: boolean; from: string; to: string } => {\n const isTransfer = txType === TransactionType.TRANSFER;\n const isNativeSend = txType === TransactionType.SEND;\n const isNativeReceive = txType === TransactionType.RECEIVE;\n let from = nativeTransaction?.from?.address;\n let to = nativeTransaction?.to?.address;\n\n // Until multi tokens transaction is supported in UI, using from and to of the only token is helpful for UI\n if (isTransfer && erc20Transfers && erc20Transfers[0]) {\n from = erc20Transfers[0].from.address;\n to = erc20Transfers[0].to.address;\n }\n\n if (isTransfer && erc721Transfers && erc721Transfers[0]) {\n from = erc721Transfers[0].from.address;\n to = erc721Transfers[0].to.address;\n }\n\n const isOutgoing = isNativeSend || (isTransfer && from.toLowerCase() === address.toLowerCase());\n const isIncoming = isNativeReceive || (isTransfer && to.toLowerCase() === address.toLowerCase());\n\n const isSender = from === address;\n\n return {\n isOutgoing,\n isIncoming,\n isSender,\n from,\n to,\n };\n};\n","import type { TransactionDetails } from '@avalabs/glacier-sdk';\nimport { balanceToDisplayValue } from '@avalabs/utils-sdk';\nimport { BN } from 'bn.js';\nimport type { TxToken, NetworkToken } from '@avalabs/vm-module-types';\nimport { TokenType } from '@avalabs/vm-module-types';\nimport { resolve } from '../../utils/resolve';\nimport { getNftMetadata } from './get-nft-metadata';\nimport { getSmallImageForNFT } from '../../utils/get-small-image-for-nft';\nimport { ipfsResolverWithFallback } from '../../utils/ipfs-resolver-with-fallback';\n\nexport const getTokens = async (\n { nativeTransaction, erc20Transfers, erc721Transfers, erc1155Transfers }: TransactionDetails,\n networkToken: NetworkToken,\n): Promise<TxToken[]> => {\n const result: TxToken[] = [];\n\n if (nativeTransaction.value !== '0') {\n const decimal = networkToken.decimals;\n const amountBN = new BN(nativeTransaction.value);\n const amountDisplayValue = balanceToDisplayValue(amountBN, decimal);\n result.push({\n decimal: decimal.toString(),\n name: networkToken.name,\n symbol: networkToken.symbol,\n amount: amountDisplayValue,\n from: nativeTransaction.from,\n to: nativeTransaction.to,\n type: TokenType.NATIVE,\n });\n }\n\n erc20Transfers?.forEach((erc20Transfer) => {\n const decimals = erc20Transfer.erc20Token.decimals;\n const amountBN = new BN(erc20Transfer.value);\n const amountDisplayValue = balanceToDisplayValue(amountBN, decimals);\n\n result.push({\n decimal: decimals.toString(),\n name: erc20Transfer.erc20Token.name,\n symbol: erc20Transfer.erc20Token.symbol,\n amount: amountDisplayValue,\n from: erc20Transfer.from,\n to: erc20Transfer.to,\n imageUri: erc20Transfer.erc20Token.logoUri,\n type: TokenType.ERC20,\n });\n });\n\n if (erc721Transfers) {\n await Promise.allSettled(\n erc721Transfers.map(async (erc721Transfer) => {\n const token = erc721Transfer.erc721Token;\n const imageUri = await getImageUri(token.tokenUri, token.metadata.imageUri);\n\n result.push({\n name: erc721Transfer.erc721Token.name,\n symbol: erc721Transfer.erc721Token.symbol,\n amount: '1',\n imageUri,\n from: erc721Transfer.from,\n to: erc721Transfer.to,\n collectableTokenId: erc721Transfer.erc721Token.tokenId,\n type: TokenType.ERC721,\n });\n }),\n );\n }\n\n if (erc1155Transfers) {\n await Promise.allSettled(\n erc1155Transfers.map(async (erc1155Transfer) => {\n const token = erc1155Transfer.erc1155Token;\n const imageUri = await getImageUri(token.tokenUri, token.metadata.imageUri);\n\n result.push({\n name: erc1155Transfer.erc1155Token.metadata.name ?? '',\n symbol: erc1155Transfer.erc1155Token.metadata.symbol ?? '',\n amount: erc1155Transfer.value,\n imageUri,\n from: erc1155Transfer.from,\n to: erc1155Transfer.to,\n collectableTokenId: erc1155Transfer.erc1155Token.tokenId,\n type: TokenType.ERC1155,\n });\n }),\n );\n }\n\n return result;\n};\n\nconst getImageUri = async (tokenUri: string, imageUri?: string): Promise<string> => {\n if (imageUri) {\n if (imageUri.startsWith('ipfs://')) {\n return ipfsResolverWithFallback(imageUri);\n } else {\n return imageUri;\n }\n } else {\n const [metadata, error] = await resolve(getNftMetadata(tokenUri));\n if (error) {\n return '';\n } else {\n return metadata.image ? getSmallImageForNFT(metadata.image) : '';\n }\n }\n};\n","export async function resolve<T = unknown>(promise: Promise<T>) {\n try {\n return promise.then((res) => [res, null]).catch((err) => [null, err]);\n } catch (err) {\n return Promise.resolve([null, err]);\n }\n}\n","import { ipfsResolver } from '@avalabs/utils-sdk';\n\nexport const CLOUDFLARE_IPFS_URL = 'https://cloudflare-ipfs.com';\n\nexport function ipfsResolverWithFallback(\n sourceUrl: string | undefined,\n desiredGatewayPrefix: string = CLOUDFLARE_IPFS_URL,\n) {\n if (!sourceUrl) {\n return '';\n }\n\n try {\n return ipfsResolver(sourceUrl, desiredGatewayPrefix);\n } catch {\n return sourceUrl;\n }\n}\n","import { ipfsResolverWithFallback } from '../../utils/ipfs-resolver-with-fallback';\n\ninterface NftMetadata {\n attributes?: string;\n name?: string;\n image?: string;\n description?: string;\n}\n\nasync function fetchWithTimeout(uri: string, timeout = 5000) {\n const controller = new AbortController();\n setTimeout(() => controller.abort(), timeout);\n\n return fetch(uri, { signal: controller.signal });\n}\n\nexport async function getNftMetadata(tokenUri: string) {\n let data: NftMetadata = {};\n if (!tokenUri) {\n return {};\n } else if (tokenUri.startsWith('data:application/json;base64,')) {\n const value = tokenUri.substring(29);\n try {\n const json = Buffer.from(value, 'base64').toString();\n data = JSON.parse(json);\n } catch {\n data = {};\n }\n } else {\n data = await fetchWithTimeout(ipfsResolverWithFallback(tokenUri))\n .then((r) => r.json())\n .catch(() => ({}));\n }\n return data;\n}\n","import { ipfsResolverWithFallback } from './ipfs-resolver-with-fallback';\n\nconst COVALENT_IMG_SIZER = 'https://image-proxy.svc.prod.covalenthq.com/cdn-cgi/image';\n\n/**\n * Covalent has an on the fly image resizer, it resolves image urls then resizes the image.\n *\n * This allows us to request smaller images depending on the UI needs\n *\n * @param imgUrl the url of the image to convert to size\n * @returns The url to the image which is sized at the time of request\n */\nexport function getSmallImageForNFT(imgUrl: string, imageSize: '256' | '512' | '1024' = '256') {\n const url = ipfsResolverWithFallback(imgUrl);\n return `${COVALENT_IMG_SIZER}/width=${imageSize},fit/${url}`;\n}\n","import { TransactionType } from '@avalabs/vm-module-types';\n\nexport const NonContractCallTypes = [TransactionType.SEND, TransactionType.RECEIVE, TransactionType.TRANSFER];\n","import type { Transaction, NetworkToken } from '@avalabs/vm-module-types';\nimport { getTxType } from './get-tx-type';\nimport { getSenderInfo } from './get-sender-info';\nimport { getTokens } from './get-tokens';\nimport { getExplorerAddressByNetwork } from '../../utils/get-explorer-address-by-network';\nimport type { TransactionDetails } from '@avalabs/glacier-sdk';\nimport { NonContractCallTypes } from '../../../../types';\n\ntype ConvertTransactionParams = {\n transactions: TransactionDetails;\n explorerUrl: string;\n networkToken: NetworkToken;\n chainId: number;\n address: string;\n};\n\nexport const convertTransaction = async ({\n transactions,\n explorerUrl,\n networkToken,\n chainId,\n address,\n}: ConvertTransactionParams): Promise<Transaction> => {\n const tokens = await getTokens(transactions, networkToken);\n const txType = getTxType(transactions, address, tokens);\n const { isOutgoing, isIncoming, isSender, from, to } = getSenderInfo(txType, transactions, address);\n const { blockTimestamp, txHash: hash, gasPrice, gasUsed } = transactions.nativeTransaction;\n const explorerLink = getExplorerAddressByNetwork(explorerUrl, hash);\n const isContractCall = !NonContractCallTypes.includes(txType);\n\n return {\n isContractCall,\n isIncoming,\n isOutgoing,\n isSender,\n timestamp: blockTimestamp * 1000, // s to ms\n hash,\n from,\n to,\n tokens,\n gasPrice,\n gasUsed,\n chainId: chainId.toString(),\n txType,\n explorerLink,\n };\n};\n","import { getTransactionFromEtherscan } from './converters/etherscan-transaction-converter/get-transaction-from-etherscan';\nimport { isEthereumChainId } from './utils/is-ethereum-chain-id';\nimport type { GetTransactionHistory, TransactionHistoryResponse } from '@avalabs/vm-module-types';\nimport { getTransactionsFromGlacier } from './converters/evm-transaction-converter/get-transactions-from-glacier';\n\nexport const getTransactionHistory = async ({\n chainId,\n isTestnet,\n networkToken,\n explorerUrl,\n address,\n nextPageToken,\n offset,\n glacierApiUrl,\n}: GetTransactionHistory): Promise<TransactionHistoryResponse> => {\n if (isEthereumChainId(chainId)) {\n return getTransactionFromEtherscan({\n isTestnet,\n networkToken,\n explorerUrl,\n chainId,\n address,\n nextPageToken,\n offset,\n });\n }\n return getTransactionsFromGlacier({\n isTestnet,\n networkToken,\n explorerUrl,\n chainId,\n address,\n nextPageToken,\n offset,\n glacierApiUrl,\n });\n};\n","import type { NetworkContractToken } from '@avalabs/vm-module-types';\n\nexport async function getTokens({\n chainId,\n proxyApiUrl,\n}: {\n chainId: number;\n proxyApiUrl: string;\n}): Promise<NetworkContractToken[]> {\n const response = await fetch(`${proxyApiUrl}/tokens?evmChainId=${chainId}`);\n\n if (!response.ok) {\n throw new Error(`Failed to fetch tokens for chainId ${chainId}`);\n }\n\n return response.json();\n}\n","{\n \"name\": \"EVM\",\n \"description\": \"\",\n \"version\": \"0.0.1\",\n \"sources\": {\n \"module\": {\n \"checksum\": \"\",\n \"location\": {\n \"npm\": {\n \"filePath\": \"dist/bundle.js\",\n \"packageName\": \"@avalabs/evm-module\",\n \"registry\": \"https://registry.npmjs.org\"\n }\n }\n },\n \"provider\": {\n \"checksum\": \"\",\n \"location\": {\n \"npm\": {\n \"filePath\": \"dist/provider.js\",\n \"packageName\": \"@avalabs/evm-module\",\n \"registry\": \"https://registry.npmjs.org\"\n }\n }\n }\n },\n \"network\": {\n \"chainIds\": [\"eip155:1\", \"eip155:43114\", \"eip155:43113\"],\n \"namespaces\": [\"eip155\"]\n },\n \"cointype\": \"60\",\n \"permissions\": {\n \"rpc\": {\n \"dapps\": true,\n \"methods\": [\"eth_sendTransaction\", \"eth_*\", \"getTransactionHistory\"]\n }\n },\n \"manifestVersion\": \"0.0\"\n}\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/module.ts","../src/handlers/get-tokens/get-tokens.ts","../src/utils/get-provider.ts","../src/handlers/get-network-fee/get-network-fee.ts","../src/handlers/get-transaction-history/converters/etherscan-transaction-converter/convert-transaction-normal.ts","../src/handlers/get-transaction-history/utils/get-explorer-address-by-network.ts","../src/handlers/get-transaction-history/converters/etherscan-transaction-converter/convert-transaction-erc20.ts","../src/handlers/get-transaction-history/converters/etherscan-transaction-converter/get-transaction-from-etherscan.ts","../src/handlers/get-transaction-history/utils/is-ethereum-chain-id.ts","../src/handlers/get-transaction-history/converters/evm-transaction-converter/get-transactions-from-glacier.ts","../src/handlers/get-transaction-history/converters/evm-transaction-converter/get-tx-type.ts","../src/handlers/get-transaction-history/converters/evm-transaction-converter/get-sender-info.ts","../src/handlers/get-transaction-history/converters/evm-transaction-converter/get-tokens.ts","../src/handlers/get-transaction-history/utils/resolve.ts","../src/handlers/get-transaction-history/utils/ipfs-resolver-with-fallback.ts","../src/handlers/get-transaction-history/converters/evm-transaction-converter/get-nft-metadata.ts","../src/handlers/get-transaction-history/utils/get-small-image-for-nft.ts","../src/types.ts","../src/handlers/get-transaction-history/converters/evm-transaction-converter/convert-transaction.ts","../src/handlers/get-transaction-history/get-transaction-history.ts","../src/manifest.json","../src/env.ts","../src/handlers/eth-send-transaction/eth-send-transaction.ts","../src/handlers/eth-send-transaction/schema.ts","../src/utils/estimate-gas-limit.ts","../src/utils/get-nonce.ts"],"names":["rpcErrors","RpcMethod","parseManifest","getTokens","chainId","proxyApiUrl","response","JsonRpcBatchInternal","EVMNetwork","GLACIER_API_KEY","getProvider","params","chainName","rpcUrl","multiContractAddress","pollingInterval","provider","addGlacierAPIKeyIfNeeded","knownHosts","url","glacierApiKey","urlObj","search_params","DEFAULT_PRESETS","BASE_PRIORITY_FEE_WEI","getNetworkFee","maxFeePerGasInWei","lowMaxTip","mediumMaxTip","highMaxTip","TokenType","TransactionType","balanceToDisplayValue","BN","getExplorerAddressByNetwork","explorerUrl","hash","hashType","convertTransactionNormal","tx","networkToken","address","isSender","timestamp","decimals","amountBN","amountDisplayValue","txType","from","to","gasPrice","gasUsed","explorerLink","isContractCall","convertTransactionERC20","tokenDecimal","tokenName","tokenSymbol","getErc20Txs","getNormalTxs","getTransactionFromEtherscan","isTestnet","nextPageToken","offset","parsedPageToken","page","queries","normalHist","erc20Hist","erc20TxHashes","filteredNormalTxs","next","isEthereumChainId","Glacier","startCase","getTxType","nativeTransaction","erc20Transfers","erc721Transfers","userAddress","tokens","nativeOnly","method","parseRawMethod","isSwap","isNativeSend","isNativeReceive","isNFTPurchase","isApprove","isTransfer","isAirdrop","isUnwrap","isFillOrder","isNFTSend","isNFT","isNFTReceive","tokenType","getSenderInfo","isOutgoing","isIncoming","resolve","promise","res","err","ipfsResolver","CLOUDFLARE_IPFS_URL","ipfsResolverWithFallback","sourceUrl","desiredGatewayPrefix","fetchWithTimeout","uri","timeout","controller","getNftMetadata","tokenUri","data","value","json","r","COVALENT_IMG_SIZER","getSmallImageForNFT","imgUrl","imageSize","erc1155Transfers","result","decimal","erc20Transfer","erc721Transfer","token","imageUri","getImageUri","erc1155Transfer","metadata","error","NonContractCallTypes","convertTransaction","transactions","blockTimestamp","getTransactionsFromGlacier","glacierApiUrl","glacierSdk","tranasaction","transaction","getTransactionHistory","manifest_default","Environment","prodEnv","devEnv","getEnv","environment","SigningDataType","z","transactionSchema","paramsSchema","parseRequestParams","estimateGasLimit","nonce","getNonce","ethSendTransaction","request","network","approvalController","dappInfo","gasLimit","displayData","signingData","txHash","waitForTransactionReceipt","onTransactionConfirmed","onTransactionReverted","_glacierApiUrl","_proxyApiUrl","_approvalController","EvmModule","__privateAdd","__privateSet","utilityAddresses","__privateGet"],"mappings":"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","sourcesContent":["import type {\n Module,\n Manifest,\n NetworkFees,\n GetTransactionHistory,\n RpcRequest,\n Environment,\n Network,\n ApprovalController,\n} from '@avalabs/vm-module-types';\nimport { rpcErrors } from '@metamask/rpc-errors';\nimport { RpcMethod, parseManifest } from '@avalabs/vm-module-types';\nimport { getTokens } from './handlers/get-tokens/get-tokens';\nimport { getNetworkFee } from './handlers/get-network-fee/get-network-fee';\nimport { getTransactionHistory } from './handlers/get-transaction-history/get-transaction-history';\nimport ManifestJson from './manifest.json';\nimport { getEnv } from './env';\nimport { ethSendTransaction } from './handlers/eth-send-transaction/eth-send-transaction';\n\nexport class EvmModule implements Module {\n #glacierApiUrl: string;\n #proxyApiUrl: string;\n #approvalController: ApprovalController;\n\n constructor({\n approvalController,\n environment,\n }: {\n approvalController: ApprovalController;\n environment: Environment;\n }) {\n const { glacierApiUrl, proxyApiUrl } = getEnv(environment);\n this.#glacierApiUrl = glacierApiUrl;\n this.#proxyApiUrl = proxyApiUrl;\n this.#approvalController = approvalController;\n }\n\n getAddress(): Promise<string> {\n return Promise.resolve('EVM address');\n }\n\n getBalances(): Promise<string> {\n return Promise.resolve('EVM balances');\n }\n\n getManifest(): Manifest | undefined {\n const result = parseManifest(ManifestJson);\n return result.success ? result.data : undefined;\n }\n\n getNetworkFee(network: Network): Promise<NetworkFees> {\n const { chainId, chainName, rpcUrl, utilityAddresses } = network;\n return getNetworkFee({\n chainId,\n chainName,\n rpcUrl,\n multiContractAddress: utilityAddresses?.multicall,\n glacierApiUrl: this.#glacierApiUrl,\n });\n }\n\n getTransactionHistory(params: GetTransactionHistory) {\n const { network, address, nextPageToken, offset } = params;\n const { chainId, isTestnet, networkToken, explorerUrl = '' } = network;\n\n return getTransactionHistory({\n chainId,\n isTestnet,\n networkToken,\n explorerUrl,\n address,\n nextPageToken,\n offset,\n glacierApiUrl: this.#glacierApiUrl,\n });\n }\n\n getTokens(network: Network) {\n const { chainId } = network;\n return getTokens({ chainId, proxyApiUrl: this.#proxyApiUrl });\n }\n\n async onRpcRequest(request: RpcRequest, network: Network) {\n switch (request.method) {\n case RpcMethod.ETH_SEND_TRANSACTION:\n return ethSendTransaction({\n request,\n network,\n approvalController: this.#approvalController,\n });\n default:\n return { error: rpcErrors.methodNotSupported(`Method ${request.method} not supported`) };\n }\n }\n}\n","import type { NetworkContractToken } from '@avalabs/vm-module-types';\nimport { rpcErrors } from '@metamask/rpc-errors';\n\nexport async function getTokens({\n chainId,\n proxyApiUrl,\n}: {\n chainId: number;\n proxyApiUrl: string;\n}): Promise<NetworkContractToken[]> {\n const response = await fetch(`${proxyApiUrl}/tokens?evmChainId=${chainId}`);\n\n if (!response.ok) {\n throw rpcErrors.internal(`Failed to fetch tokens for chainId ${chainId}`);\n }\n\n return response.json();\n}\n","import { JsonRpcBatchInternal } from '@avalabs/wallets-sdk';\nimport { Network as EVMNetwork } from 'ethers';\n\n// this key is only needed in development to bypass rate limit\n// it should never be used in production\nconst GLACIER_API_KEY = process.env.GLACIER_API_KEY;\n\ntype ProviderParams = {\n chainId: number;\n chainName: string;\n rpcUrl: string;\n multiContractAddress?: string;\n pollingInterval?: number;\n};\n\nexport const getProvider = (params: ProviderParams): JsonRpcBatchInternal => {\n const { chainId, chainName, rpcUrl, multiContractAddress, pollingInterval = 2000 } = params;\n\n const provider = new JsonRpcBatchInternal(\n { maxCalls: 40, multiContractAddress },\n addGlacierAPIKeyIfNeeded(rpcUrl, GLACIER_API_KEY),\n new EVMNetwork(chainName, chainId),\n );\n\n provider.pollingInterval = pollingInterval;\n\n return provider;\n};\n\n// RPC urls returned in the token list are always using the production URL\nconst knownHosts = ['glacier-api.avax.network', 'proxy-api.avax.network'];\n\n/**\n * Glacier needs an API key for development, this adds the key if needed.\n */\nexport function addGlacierAPIKeyIfNeeded(url: string, glacierApiKey?: string): string {\n const urlObj = new URL(url);\n\n if (glacierApiKey && knownHosts.includes(urlObj.hostname)) {\n const search_params = urlObj.searchParams; // copy, does not update the URL\n search_params.set('token', glacierApiKey);\n urlObj.search = search_params.toString();\n return urlObj.toString();\n }\n return url;\n}\n","import type { NetworkFees } from '@avalabs/vm-module-types';\nimport { getProvider } from '../../utils/get-provider';\nimport { rpcErrors } from '@metamask/rpc-errors';\n\nconst DEFAULT_PRESETS = {\n LOW: 1n,\n MEDIUM: 4n,\n HIGH: 6n,\n};\n\nconst BASE_PRIORITY_FEE_WEI = 500000000n; //0.5 GWei\n\n/**\n * Returns {@link NetworkFees} based on {@link DEFAULT_PRESETS} multipliers.\n * @throws Error if provider does not support eip-1559\n */\nexport async function getNetworkFee({\n chainId,\n chainName,\n rpcUrl,\n multiContractAddress,\n}: {\n chainId: number;\n chainName: string;\n rpcUrl: string;\n glacierApiUrl: string;\n multiContractAddress?: string;\n}): Promise<NetworkFees> {\n const provider = getProvider({\n chainId,\n chainName,\n rpcUrl,\n multiContractAddress,\n });\n\n const { maxFeePerGas: maxFeePerGasInWei } = await provider.getFeeData();\n if (!maxFeePerGasInWei) {\n throw rpcErrors.internal('Pre-EIP-1559 networks are not supported');\n }\n\n const lowMaxTip = BASE_PRIORITY_FEE_WEI * DEFAULT_PRESETS.LOW;\n const mediumMaxTip = BASE_PRIORITY_FEE_WEI * DEFAULT_PRESETS.MEDIUM;\n const highMaxTip = BASE_PRIORITY_FEE_WEI * DEFAULT_PRESETS.HIGH;\n return {\n baseFee: maxFeePerGasInWei,\n low: {\n maxFeePerGas: maxFeePerGasInWei + lowMaxTip,\n maxPriorityFeePerGas: lowMaxTip,\n },\n medium: {\n maxFeePerGas: maxFeePerGasInWei + mediumMaxTip,\n maxPriorityFeePerGas: mediumMaxTip,\n },\n high: {\n maxFeePerGas: maxFeePerGasInWei + highMaxTip,\n maxPriorityFeePerGas: highMaxTip,\n },\n };\n}\n","import type { NormalTx } from '@avalabs/etherscan-sdk';\nimport { TokenType, TransactionType, type NetworkToken, type Transaction } from '@avalabs/vm-module-types';\nimport { balanceToDisplayValue } from '@avalabs/utils-sdk';\nimport { BN } from 'bn.js';\nimport { getExplorerAddressByNetwork } from '../../utils/get-explorer-address-by-network';\n\nexport const convertTransactionNormal = ({\n tx,\n networkToken,\n chainId,\n explorerUrl,\n address,\n}: {\n tx: NormalTx;\n networkToken: NetworkToken;\n chainId: number;\n explorerUrl: string;\n address: string;\n}): Transaction => {\n const isSender = tx.from.toLowerCase() === address.toLowerCase();\n const timestamp = parseInt(tx.timeStamp) * 1000;\n const decimals = networkToken.decimals;\n const amountBN = new BN(tx.value);\n const amountDisplayValue = balanceToDisplayValue(amountBN, decimals);\n const txType = isSender ? TransactionType.SEND : TransactionType.RECEIVE;\n\n const { from, to, gasPrice, gasUsed, hash } = tx;\n const explorerLink = getExplorerAddressByNetwork(explorerUrl, hash);\n\n return {\n isIncoming: !isSender,\n isOutgoing: isSender,\n isContractCall: isContractCall(tx),\n timestamp,\n hash,\n isSender,\n from,\n to,\n tokens: [\n {\n decimal: decimals.toString(),\n name: networkToken.name,\n symbol: networkToken.symbol,\n amount: amountDisplayValue,\n type: TokenType.NATIVE,\n },\n ],\n gasUsed,\n gasPrice,\n chainId: chainId.toString(),\n txType,\n explorerLink,\n };\n};\n\nfunction isContractCall(tx: NormalTx): boolean {\n return tx.input !== '0x';\n}\n","export function getExplorerAddressByNetwork(\n explorerUrl: string,\n hash: string,\n hashType: 'address' | 'tx' = 'tx',\n): string {\n return `${explorerUrl}/${hashType}/${hash}`;\n}\n","import type { Erc20Tx } from '@avalabs/etherscan-sdk';\nimport { TokenType, TransactionType, type Transaction } from '@avalabs/vm-module-types';\nimport { balanceToDisplayValue } from '@avalabs/utils-sdk';\nimport { getExplorerAddressByNetwork } from '../../utils/get-explorer-address-by-network';\nimport { BN } from 'bn.js';\n\nexport function convertTransactionERC20({\n tx,\n address,\n explorerUrl,\n chainId,\n}: {\n tx: Erc20Tx;\n address: string;\n chainId: number;\n explorerUrl: string;\n}): Transaction {\n const isSender = tx.from.toLowerCase() === address.toLowerCase();\n const timestamp = parseInt(tx.timeStamp) * 1000;\n const decimals = parseInt(tx.tokenDecimal);\n const amountBN = new BN(tx.value);\n const amountDisplayValue = balanceToDisplayValue(amountBN, decimals);\n const { from, to, gasPrice, gasUsed, hash, tokenDecimal, tokenName, tokenSymbol } = tx;\n const txType = isSender ? TransactionType.SEND : TransactionType.RECEIVE;\n const explorerLink = getExplorerAddressByNetwork(explorerUrl, hash);\n\n return {\n isIncoming: !isSender,\n isOutgoing: isSender,\n isContractCall: false,\n timestamp,\n hash,\n isSender,\n from,\n to,\n tokens: [\n {\n decimal: tokenDecimal,\n name: tokenName,\n symbol: tokenSymbol,\n type: TokenType.ERC20,\n amount: amountDisplayValue,\n },\n ],\n gasUsed,\n gasPrice,\n chainId: chainId.toString(),\n txType,\n explorerLink,\n };\n}\n","import { convertTransactionNormal } from './convert-transaction-normal';\nimport { convertTransactionERC20 } from './convert-transaction-erc20';\nimport type { NetworkToken, TransactionHistoryResponse } from '@avalabs/vm-module-types';\nimport { getErc20Txs, getNormalTxs } from '@avalabs/etherscan-sdk';\n\ninterface EtherscanPagination {\n queries: ('normal' | 'erc20')[];\n page?: number;\n}\n\nexport const getTransactionFromEtherscan = async ({\n isTestnet,\n networkToken,\n explorerUrl,\n chainId,\n address,\n nextPageToken,\n offset,\n}: {\n isTestnet?: boolean;\n networkToken: NetworkToken;\n explorerUrl: string;\n chainId: number;\n address: string;\n nextPageToken?: string;\n offset?: number;\n}): Promise<TransactionHistoryResponse> => {\n /*\n Using JSON for nextPageToken because this function is managing both the Normal\n and ERC20 queries. It encodes the current page and the queries that should be\n run. For example, if 'normal' has no more records to fetch then it will be\n excluded from the list and the JSON will be something like:\n { page: 3, queries: ['erc20'] }\n */\n const parsedPageToken = nextPageToken ? (JSON.parse(nextPageToken) as EtherscanPagination) : undefined;\n const page = parsedPageToken?.page || 1;\n const queries = parsedPageToken?.queries || ['normal', 'erc20'];\n\n const normalHist = (queries.includes('normal') ? await getNormalTxs(address, !isTestnet, { page, offset }) : []).map(\n (tx) => convertTransactionNormal({ tx, chainId, networkToken, explorerUrl, address }),\n );\n\n const erc20Hist = (\n queries.includes('erc20')\n ? await getErc20Txs(address, !isTestnet, undefined, {\n page,\n offset,\n })\n : []\n ).map((tx) =>\n convertTransactionERC20({\n tx,\n address,\n explorerUrl,\n chainId,\n }),\n );\n\n // Filter erc20 transactions from normal tx list\n const erc20TxHashes = erc20Hist.map((tx) => tx.hash);\n const filteredNormalTxs = normalHist.filter((tx) => {\n return !erc20TxHashes.includes(tx.hash);\n });\n\n const next: EtherscanPagination = { queries: [], page: page + 1 };\n if (normalHist.length) next.queries.push('normal');\n if (erc20Hist.length) next.queries.push('erc20');\n\n return {\n transactions: [...filteredNormalTxs, ...erc20Hist],\n nextPageToken: next.queries.length ? JSON.stringify(next) : '', // stop pagination\n };\n};\n","enum ChainId {\n ETHEREUM_HOMESTEAD = 1,\n ETHEREUM_TEST_RINKEBY = 4,\n ETHEREUM_TEST_GOERLY = 5,\n ETHEREUM_TEST_SEPOLIA = 11155111,\n}\n\nexport const isEthereumChainId = (chainId: number): boolean => {\n return (\n ChainId.ETHEREUM_HOMESTEAD === chainId ||\n ChainId.ETHEREUM_TEST_GOERLY === chainId ||\n ChainId.ETHEREUM_TEST_RINKEBY === chainId ||\n ChainId.ETHEREUM_TEST_SEPOLIA === chainId\n );\n};\n","import type { NetworkToken, TransactionHistoryResponse } from '@avalabs/vm-module-types';\nimport { Glacier } from '@avalabs/glacier-sdk';\nimport { rpcErrors } from '@metamask/rpc-errors';\nimport { convertTransaction } from './convert-transaction';\n\nexport const getTransactionsFromGlacier = async ({\n chainId,\n explorerUrl,\n networkToken,\n address,\n nextPageToken,\n offset,\n glacierApiUrl,\n}: {\n chainId: number;\n explorerUrl: string;\n networkToken: NetworkToken;\n address: string;\n nextPageToken?: string;\n offset?: number;\n glacierApiUrl: string;\n}): Promise<TransactionHistoryResponse> => {\n if (!glacierApiUrl) {\n throw rpcErrors.invalidParams('Glacier API URL is required');\n }\n\n const glacierSdk = new Glacier({ BASE: glacierApiUrl });\n\n try {\n const response = await glacierSdk.evmTransactions.listTransactions({\n chainId: chainId.toString(),\n address,\n pageToken: nextPageToken,\n pageSize: offset,\n });\n\n const convertedTxs = await Promise.all(\n response.transactions\n .filter(\n // Currently not showing failed tx\n (tranasaction) => tranasaction.nativeTransaction.txStatus === '1',\n )\n .map((transactions) =>\n convertTransaction({\n transactions,\n explorerUrl,\n networkToken,\n chainId,\n address,\n }).then((tx) => tx),\n ),\n );\n\n const transactions = convertedTxs.filter(\n // Filtering txs with 0 value since there is no change in balance\n (transaction) => transaction.tokens.find((token) => Number(token.amount) !== 0),\n );\n\n return {\n transactions,\n nextPageToken: response.nextPageToken,\n };\n } catch {\n return {\n transactions: [],\n nextPageToken: '',\n };\n }\n};\n","import type { TransactionDetails } from '@avalabs/glacier-sdk';\nimport { TokenType, TransactionType, type TxToken } from '@avalabs/vm-module-types';\nimport startCase from 'lodash.startcase';\n\nexport const getTxType = (\n { nativeTransaction, erc20Transfers, erc721Transfers }: TransactionDetails,\n userAddress: string,\n tokens: TxToken[],\n): TransactionType => {\n const nativeOnly = !erc20Transfers && !erc721Transfers;\n const method = parseRawMethod(nativeTransaction.method?.methodName);\n\n const address = userAddress.toLowerCase();\n\n const isSwap = method.toLowerCase().includes('swap');\n const isNativeSend = nativeOnly && nativeTransaction.from.address.toLowerCase() === address;\n const isNativeReceive = nativeOnly && nativeTransaction.to.address.toLowerCase() === address;\n const isNFTPurchase = method === 'Market Buy Orders With Eth' || method === 'Buy NFT';\n const isApprove = method === 'Approve';\n const isTransfer = method.toLowerCase().includes('transfer');\n const isAirdrop = method.toLowerCase().includes('airdrop');\n const isUnwrap = method.toLowerCase().includes('unwrap');\n const isFillOrder = method === 'Fill Order';\n const isNFTSend =\n isTransfer && !!tokens[0] && isNFT(tokens[0].type) && tokens[0].from?.address.toLowerCase() === address;\n const isNFTReceive =\n isTransfer && !!tokens[0] && isNFT(tokens[0].type) && tokens[0].to?.address.toLowerCase() === address;\n\n if (isSwap) return TransactionType.SWAP;\n if (isNativeSend) return TransactionType.SEND;\n if (isNativeReceive) return TransactionType.RECEIVE;\n if (isNFTPurchase) return TransactionType.NFT_BUY;\n if (isApprove) return TransactionType.APPROVE;\n if (isNFTSend) return TransactionType.NFT_SEND;\n if (isNFTReceive) return TransactionType.NFT_RECEIVE;\n if (isTransfer) return TransactionType.TRANSFER;\n if (isAirdrop) return TransactionType.AIRDROP;\n if (isUnwrap) return TransactionType.UNWRAP;\n if (isFillOrder) return TransactionType.FILL_ORDER;\n return TransactionType.UNKNOWN;\n};\n\nfunction isNFT(tokenType: TokenType) {\n return tokenType === TokenType.ERC721 || tokenType === TokenType.ERC1155;\n}\n\nconst parseRawMethod = (method = ''): string => {\n if (method.includes('(')) {\n return startCase(method.split('(', 1)[0]);\n }\n return method;\n};\n","import type { TransactionDetails } from '@avalabs/glacier-sdk';\nimport { TransactionType } from '@avalabs/vm-module-types';\n\nexport const getSenderInfo = (\n txType: TransactionType,\n { nativeTransaction, erc20Transfers, erc721Transfers }: TransactionDetails,\n address: string,\n): { isOutgoing: boolean; isIncoming: boolean; isSender: boolean; from: string; to: string } => {\n const isTransfer = txType === TransactionType.TRANSFER;\n const isNativeSend = txType === TransactionType.SEND;\n const isNativeReceive = txType === TransactionType.RECEIVE;\n let from = nativeTransaction?.from?.address;\n let to = nativeTransaction?.to?.address;\n\n // Until multi tokens transaction is supported in UI, using from and to of the only token is helpful for UI\n if (isTransfer && erc20Transfers && erc20Transfers[0]) {\n from = erc20Transfers[0].from.address;\n to = erc20Transfers[0].to.address;\n }\n\n if (isTransfer && erc721Transfers && erc721Transfers[0]) {\n from = erc721Transfers[0].from.address;\n to = erc721Transfers[0].to.address;\n }\n\n const isOutgoing = isNativeSend || (isTransfer && from.toLowerCase() === address.toLowerCase());\n const isIncoming = isNativeReceive || (isTransfer && to.toLowerCase() === address.toLowerCase());\n\n const isSender = from === address;\n\n return {\n isOutgoing,\n isIncoming,\n isSender,\n from,\n to,\n };\n};\n","import type { TransactionDetails } from '@avalabs/glacier-sdk';\nimport { balanceToDisplayValue } from '@avalabs/utils-sdk';\nimport { BN } from 'bn.js';\nimport type { TxToken, NetworkToken } from '@avalabs/vm-module-types';\nimport { TokenType } from '@avalabs/vm-module-types';\nimport { resolve } from '../../utils/resolve';\nimport { getNftMetadata } from './get-nft-metadata';\nimport { getSmallImageForNFT } from '../../utils/get-small-image-for-nft';\nimport { ipfsResolverWithFallback } from '../../utils/ipfs-resolver-with-fallback';\n\nexport const getTokens = async (\n { nativeTransaction, erc20Transfers, erc721Transfers, erc1155Transfers }: TransactionDetails,\n networkToken: NetworkToken,\n): Promise<TxToken[]> => {\n const result: TxToken[] = [];\n\n if (nativeTransaction.value !== '0') {\n const decimal = networkToken.decimals;\n const amountBN = new BN(nativeTransaction.value);\n const amountDisplayValue = balanceToDisplayValue(amountBN, decimal);\n result.push({\n decimal: decimal.toString(),\n name: networkToken.name,\n symbol: networkToken.symbol,\n amount: amountDisplayValue,\n from: nativeTransaction.from,\n to: nativeTransaction.to,\n type: TokenType.NATIVE,\n });\n }\n\n erc20Transfers?.forEach((erc20Transfer) => {\n const decimals = erc20Transfer.erc20Token.decimals;\n const amountBN = new BN(erc20Transfer.value);\n const amountDisplayValue = balanceToDisplayValue(amountBN, decimals);\n\n result.push({\n decimal: decimals.toString(),\n name: erc20Transfer.erc20Token.name,\n symbol: erc20Transfer.erc20Token.symbol,\n amount: amountDisplayValue,\n from: erc20Transfer.from,\n to: erc20Transfer.to,\n imageUri: erc20Transfer.erc20Token.logoUri,\n type: TokenType.ERC20,\n });\n });\n\n if (erc721Transfers) {\n await Promise.allSettled(\n erc721Transfers.map(async (erc721Transfer) => {\n const token = erc721Transfer.erc721Token;\n const imageUri = await getImageUri(token.tokenUri, token.metadata.imageUri);\n\n result.push({\n name: erc721Transfer.erc721Token.name,\n symbol: erc721Transfer.erc721Token.symbol,\n amount: '1',\n imageUri,\n from: erc721Transfer.from,\n to: erc721Transfer.to,\n collectableTokenId: erc721Transfer.erc721Token.tokenId,\n type: TokenType.ERC721,\n });\n }),\n );\n }\n\n if (erc1155Transfers) {\n await Promise.allSettled(\n erc1155Transfers.map(async (erc1155Transfer) => {\n const token = erc1155Transfer.erc1155Token;\n const imageUri = await getImageUri(token.tokenUri, token.metadata.imageUri);\n\n result.push({\n name: erc1155Transfer.erc1155Token.metadata.name ?? '',\n symbol: erc1155Transfer.erc1155Token.metadata.symbol ?? '',\n amount: erc1155Transfer.value,\n imageUri,\n from: erc1155Transfer.from,\n to: erc1155Transfer.to,\n collectableTokenId: erc1155Transfer.erc1155Token.tokenId,\n type: TokenType.ERC1155,\n });\n }),\n );\n }\n\n return result;\n};\n\nconst getImageUri = async (tokenUri: string, imageUri?: string): Promise<string> => {\n if (imageUri) {\n if (imageUri.startsWith('ipfs://')) {\n return ipfsResolverWithFallback(imageUri);\n } else {\n return imageUri;\n }\n } else {\n const [metadata, error] = await resolve(getNftMetadata(tokenUri));\n if (error) {\n return '';\n } else {\n return metadata.image ? getSmallImageForNFT(metadata.image) : '';\n }\n }\n};\n","export async function resolve<T = unknown>(promise: Promise<T>) {\n try {\n return promise.then((res) => [res, null]).catch((err) => [null, err]);\n } catch (err) {\n return Promise.resolve([null, err]);\n }\n}\n","import { ipfsResolver } from '@avalabs/utils-sdk';\n\nexport const CLOUDFLARE_IPFS_URL = 'https://cloudflare-ipfs.com';\n\nexport function ipfsResolverWithFallback(\n sourceUrl: string | undefined,\n desiredGatewayPrefix: string = CLOUDFLARE_IPFS_URL,\n) {\n if (!sourceUrl) {\n return '';\n }\n\n try {\n return ipfsResolver(sourceUrl, desiredGatewayPrefix);\n } catch {\n return sourceUrl;\n }\n}\n","import { ipfsResolverWithFallback } from '../../utils/ipfs-resolver-with-fallback';\n\ninterface NftMetadata {\n attributes?: string;\n name?: string;\n image?: string;\n description?: string;\n}\n\nasync function fetchWithTimeout(uri: string, timeout = 5000) {\n const controller = new AbortController();\n setTimeout(() => controller.abort(), timeout);\n\n return fetch(uri, { signal: controller.signal });\n}\n\nexport async function getNftMetadata(tokenUri: string) {\n let data: NftMetadata = {};\n if (!tokenUri) {\n return {};\n } else if (tokenUri.startsWith('data:application/json;base64,')) {\n const value = tokenUri.substring(29);\n try {\n const json = Buffer.from(value, 'base64').toString();\n data = JSON.parse(json);\n } catch {\n data = {};\n }\n } else {\n data = await fetchWithTimeout(ipfsResolverWithFallback(tokenUri))\n .then((r) => r.json())\n .catch(() => ({}));\n }\n return data;\n}\n","import { ipfsResolverWithFallback } from './ipfs-resolver-with-fallback';\n\nconst COVALENT_IMG_SIZER = 'https://image-proxy.svc.prod.covalenthq.com/cdn-cgi/image';\n\n/**\n * Covalent has an on the fly image resizer, it resolves image urls then resizes the image.\n *\n * This allows us to request smaller images depending on the UI needs\n *\n * @param imgUrl the url of the image to convert to size\n * @returns The url to the image which is sized at the time of request\n */\nexport function getSmallImageForNFT(imgUrl: string, imageSize: '256' | '512' | '1024' = '256') {\n const url = ipfsResolverWithFallback(imgUrl);\n return `${COVALENT_IMG_SIZER}/width=${imageSize},fit/${url}`;\n}\n","import { TransactionType } from '@avalabs/vm-module-types';\n\nexport const NonContractCallTypes = [TransactionType.SEND, TransactionType.RECEIVE, TransactionType.TRANSFER];\n\nexport type TransactionParams = {\n from: string;\n to: string;\n data?: string;\n value?: string;\n gas?: string;\n gasPrice?: string;\n maxFeePerGas?: string;\n maxPriorityFeePerGas?: string;\n nonce?: string;\n chainId?: string;\n};\n","import type { Transaction, NetworkToken } from '@avalabs/vm-module-types';\nimport { getTxType } from './get-tx-type';\nimport { getSenderInfo } from './get-sender-info';\nimport { getTokens } from './get-tokens';\nimport { getExplorerAddressByNetwork } from '../../utils/get-explorer-address-by-network';\nimport type { TransactionDetails } from '@avalabs/glacier-sdk';\nimport { NonContractCallTypes } from '../../../../types';\n\ntype ConvertTransactionParams = {\n transactions: TransactionDetails;\n explorerUrl: string;\n networkToken: NetworkToken;\n chainId: number;\n address: string;\n};\n\nexport const convertTransaction = async ({\n transactions,\n explorerUrl,\n networkToken,\n chainId,\n address,\n}: ConvertTransactionParams): Promise<Transaction> => {\n const tokens = await getTokens(transactions, networkToken);\n const txType = getTxType(transactions, address, tokens);\n const { isOutgoing, isIncoming, isSender, from, to } = getSenderInfo(txType, transactions, address);\n const { blockTimestamp, txHash: hash, gasPrice, gasUsed } = transactions.nativeTransaction;\n const explorerLink = getExplorerAddressByNetwork(explorerUrl, hash);\n const isContractCall = !NonContractCallTypes.includes(txType);\n\n return {\n isContractCall,\n isIncoming,\n isOutgoing,\n isSender,\n timestamp: blockTimestamp * 1000, // s to ms\n hash,\n from,\n to,\n tokens,\n gasPrice,\n gasUsed,\n chainId: chainId.toString(),\n txType,\n explorerLink,\n };\n};\n","import { getTransactionFromEtherscan } from './converters/etherscan-transaction-converter/get-transaction-from-etherscan';\nimport { isEthereumChainId } from './utils/is-ethereum-chain-id';\nimport type { NetworkToken, TransactionHistoryResponse } from '@avalabs/vm-module-types';\nimport { getTransactionsFromGlacier } from './converters/evm-transaction-converter/get-transactions-from-glacier';\n\nexport const getTransactionHistory = async ({\n chainId,\n isTestnet,\n networkToken,\n explorerUrl,\n address,\n nextPageToken,\n offset,\n glacierApiUrl,\n}: {\n chainId: number;\n isTestnet?: boolean;\n networkToken: NetworkToken;\n explorerUrl: string;\n address: string;\n nextPageToken?: string;\n offset?: number;\n glacierApiUrl: string;\n}): Promise<TransactionHistoryResponse> => {\n if (isEthereumChainId(chainId)) {\n return getTransactionFromEtherscan({\n isTestnet,\n networkToken,\n explorerUrl,\n chainId,\n address,\n nextPageToken,\n offset,\n });\n }\n return getTransactionsFromGlacier({\n networkToken,\n explorerUrl,\n chainId,\n address,\n nextPageToken,\n offset,\n glacierApiUrl,\n });\n};\n","{\n \"name\": \"EVM\",\n \"description\": \"\",\n \"version\": \"0.0.1\",\n \"sources\": {\n \"module\": {\n \"checksum\": \"\",\n \"location\": {\n \"npm\": {\n \"filePath\": \"dist/bundle.js\",\n \"packageName\": \"@avalabs/evm-module\",\n \"registry\": \"https://registry.npmjs.org\"\n }\n }\n },\n \"provider\": {\n \"checksum\": \"\",\n \"location\": {\n \"npm\": {\n \"filePath\": \"dist/provider.js\",\n \"packageName\": \"@avalabs/evm-module\",\n \"registry\": \"https://registry.npmjs.org\"\n }\n }\n }\n },\n \"network\": {\n \"chainIds\": [\"eip155:1\", \"eip155:43114\", \"eip155:43113\"],\n \"namespaces\": [\"eip155\"]\n },\n \"cointype\": \"60\",\n \"permissions\": {\n \"rpc\": {\n \"dapps\": true,\n \"methods\": [\"eth_sendTransaction\", \"eth_*\", \"getTransactionHistory\"]\n }\n },\n \"manifestVersion\": \"0.0\"\n}\n","import { Environment } from '@avalabs/vm-module-types';\n\ntype Env = {\n glacierApiUrl: string;\n proxyApiUrl: string;\n};\n\nexport const prodEnv: Env = {\n glacierApiUrl: 'https://glacier-api.avax.network',\n proxyApiUrl: 'https://proxy-api.avax.network',\n};\n\nexport const devEnv: Env = {\n glacierApiUrl: 'https://glacier-api-dev.avax.network',\n proxyApiUrl: 'https://proxy-api-dev.avax.network',\n};\n\nexport const getEnv = (environment: Environment): Env => {\n switch (environment) {\n case Environment.PRODUCTION:\n return prodEnv;\n case Environment.DEV:\n return devEnv;\n }\n};\n","import {\n type Network,\n type Hex,\n type RpcRequest,\n type ApprovalController,\n type DisplayData,\n type SigningData,\n SigningDataType,\n} from '@avalabs/vm-module-types';\nimport { parseRequestParams } from './schema';\nimport { estimateGasLimit } from '../../utils/estimate-gas-limit';\nimport { getNonce } from '../../utils/get-nonce';\nimport { rpcErrors } from '@metamask/rpc-errors';\nimport { getProvider } from '../../utils/get-provider';\nimport type { JsonRpcBatchInternal } from '@avalabs/wallets-sdk';\n\nexport const ethSendTransaction = async ({\n request,\n network,\n approvalController,\n}: {\n request: RpcRequest;\n network: Network;\n approvalController: ApprovalController;\n}) => {\n const { dappInfo, params } = request;\n\n // validate params\n const result = parseRequestParams(params);\n\n if (!result.success) {\n console.error(result.error);\n return {\n error: rpcErrors.invalidParams('Transaction params are invalid'),\n };\n }\n\n const transaction = result.data[0];\n\n if (!transaction) {\n return {\n error: rpcErrors.invalidParams('Transaction params are invalid'),\n };\n }\n\n const provider = getProvider({\n chainId: network.chainId,\n chainName: network.chainName,\n rpcUrl: network.rpcUrl,\n multiContractAddress: network.utilityAddresses?.multicall,\n pollingInterval: 1000,\n });\n\n // calculate gas limit if not provided/invalid\n if (!transaction.gas || Number(transaction.gas) < 0) {\n try {\n const gasLimit = await estimateGasLimit({\n transactionParams: {\n from: transaction.from,\n to: transaction.to,\n data: transaction.data,\n value: transaction.value,\n },\n provider,\n });\n\n transaction.gas = '0x' + gasLimit.toString(16);\n } catch (error) {\n return {\n error: rpcErrors.internal('Unable to calculate gas limit'),\n };\n }\n }\n\n // calculate nonce if not provided\n if (!transaction.nonce) {\n try {\n const nonce = await getNonce({\n from: transaction.from,\n provider,\n });\n transaction.nonce = String(nonce);\n } catch (error) {\n return {\n error: rpcErrors.internal('Unable to calculate nonce'),\n };\n }\n }\n\n // TODO: validate + simulate transaction\n // https://ava-labs.atlassian.net/browse/CP-8870\n\n // generate display and signing data\n // TODO adjust title for different transaction types\n // https://ava-labs.atlassian.net/browse/CP-8870\n const displayData: DisplayData = {\n title: 'Approve Transaction',\n network: {\n chainId: network.chainId,\n name: network.chainName,\n logoUrl: network.logoUrl,\n },\n transactionDetails: {\n website: new URL(dappInfo.url).hostname,\n from: transaction.from,\n to: transaction.to,\n data: transaction.data,\n },\n networkFeeSelector: true,\n };\n\n const signingData: SigningData = {\n type: SigningDataType.EVM_TRANSACTION,\n account: transaction.from,\n chainId: network.chainId,\n data: {\n type: 2, // hardcoding to 2 for now as we only support EIP-1559\n nonce: Number(transaction.nonce),\n gasLimit: Number(transaction.gas),\n to: transaction.to,\n from: transaction.from,\n data: transaction.data,\n value: transaction.value,\n chainId: transaction.chainId,\n },\n };\n\n // prompt user for approval\n const response = await approvalController.requestApproval({ request, displayData, signingData });\n\n if ('error' in response) {\n return {\n error: response.error,\n };\n }\n\n // broadcast the signed transaction\n const txHash = await provider.send('eth_sendRawTransaction', [response.result]);\n\n waitForTransactionReceipt({\n provider,\n txHash,\n onTransactionConfirmed: approvalController.onTransactionConfirmed,\n onTransactionReverted: approvalController.onTransactionReverted,\n });\n\n return { result: txHash };\n};\n\nconst waitForTransactionReceipt = async ({\n provider,\n txHash,\n onTransactionConfirmed,\n onTransactionReverted,\n}: {\n provider: JsonRpcBatchInternal;\n txHash: Hex;\n onTransactionConfirmed: (txHash: Hex) => void;\n onTransactionReverted: (txHash: Hex) => void;\n}) => {\n const receipt = await provider.waitForTransaction(txHash);\n\n const success = receipt?.status === 1; // 1 indicates success, 0 indicates revert\n\n if (success) {\n onTransactionConfirmed(txHash);\n } else {\n onTransactionReverted(txHash);\n }\n};\n","import { z } from 'zod';\n\nconst transactionSchema = z.object({\n from: z.string().length(42),\n to: z.string().length(42),\n data: z.string().optional(),\n value: z.string().startsWith('0x').optional(),\n gas: z.string().startsWith('0x').optional(),\n gasPrice: z.string().startsWith('0x').optional(),\n maxFeePerGas: z.string().startsWith('0x').optional(),\n maxPriorityFeePerGas: z.string().startsWith('0x').optional(),\n nonce: z.string().optional(),\n chainId: z.string().optional(),\n});\n\nconst paramsSchema = z.array(transactionSchema).length(1);\n\nexport const parseRequestParams = (params: unknown) => {\n return paramsSchema.safeParse(params);\n};\n","import { JsonRpcBatchInternal } from '@avalabs/wallets-sdk';\nimport type { BigNumberish } from 'ethers';\n\nexport const estimateGasLimit = async ({\n transactionParams: { from, to, data, value },\n provider,\n}: {\n transactionParams: {\n from: string;\n to: string;\n data?: string;\n value?: BigNumberish;\n };\n provider: JsonRpcBatchInternal;\n}): Promise<number> => {\n const nonce = await provider.getTransactionCount(from);\n\n return Number(\n await provider.estimateGas({\n from,\n to,\n nonce,\n data,\n value,\n }),\n );\n};\n","import { JsonRpcBatchInternal } from '@avalabs/wallets-sdk';\n\nexport const getNonce = async ({\n from,\n provider,\n}: {\n from: string;\n provider: JsonRpcBatchInternal;\n}): Promise<number> => {\n return provider.getTransactionCount(from);\n};\n"]}
|
package/dist/index.d.cts
CHANGED
|
@@ -1,22 +1,40 @@
|
|
|
1
|
-
import * as
|
|
2
|
-
import
|
|
1
|
+
import * as _metamask_rpc_errors from '@metamask/rpc-errors';
|
|
2
|
+
import * as _avalabs_vm_module_types_dist_types from '@avalabs/vm-module-types/dist/types';
|
|
3
|
+
import { Module, ApprovalController, Environment, Manifest, Network, NetworkFees, GetTransactionHistory, RpcRequest, TransactionType } from '@avalabs/vm-module-types';
|
|
3
4
|
|
|
4
5
|
declare class EvmModule implements Module {
|
|
5
6
|
#private;
|
|
6
|
-
constructor({
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
proxyApiUrl: string;
|
|
7
|
+
constructor({ approvalController, environment, }: {
|
|
8
|
+
approvalController: ApprovalController;
|
|
9
|
+
environment: Environment;
|
|
10
10
|
});
|
|
11
11
|
getAddress(): Promise<string>;
|
|
12
12
|
getBalances(): Promise<string>;
|
|
13
13
|
getManifest(): Manifest | undefined;
|
|
14
|
-
getNetworkFee(
|
|
15
|
-
getTransactionHistory(params: GetTransactionHistory): Promise<
|
|
16
|
-
getTokens(
|
|
17
|
-
onRpcRequest(request: RpcRequest): Promise<{
|
|
18
|
-
error:
|
|
14
|
+
getNetworkFee(network: Network): Promise<NetworkFees>;
|
|
15
|
+
getTransactionHistory(params: GetTransactionHistory): Promise<_avalabs_vm_module_types_dist_types.TransactionHistoryResponse>;
|
|
16
|
+
getTokens(network: Network): Promise<_avalabs_vm_module_types_dist_types.NetworkContractToken[]>;
|
|
17
|
+
onRpcRequest(request: RpcRequest, network: Network): Promise<{
|
|
18
|
+
error: _metamask_rpc_errors.JsonRpcError<_metamask_rpc_errors.OptionalDataWithOptionalCause>;
|
|
19
|
+
result?: undefined;
|
|
20
|
+
} | {
|
|
21
|
+
result: any;
|
|
22
|
+
error?: undefined;
|
|
19
23
|
}>;
|
|
20
24
|
}
|
|
21
25
|
|
|
22
|
-
|
|
26
|
+
declare const NonContractCallTypes: TransactionType[];
|
|
27
|
+
type TransactionParams = {
|
|
28
|
+
from: string;
|
|
29
|
+
to: string;
|
|
30
|
+
data?: string;
|
|
31
|
+
value?: string;
|
|
32
|
+
gas?: string;
|
|
33
|
+
gasPrice?: string;
|
|
34
|
+
maxFeePerGas?: string;
|
|
35
|
+
maxPriorityFeePerGas?: string;
|
|
36
|
+
nonce?: string;
|
|
37
|
+
chainId?: string;
|
|
38
|
+
};
|
|
39
|
+
|
|
40
|
+
export { EvmModule, NonContractCallTypes, TransactionParams };
|
package/dist/index.d.ts
CHANGED
|
@@ -1,22 +1,40 @@
|
|
|
1
|
-
import * as
|
|
2
|
-
import
|
|
1
|
+
import * as _metamask_rpc_errors from '@metamask/rpc-errors';
|
|
2
|
+
import * as _avalabs_vm_module_types_dist_types from '@avalabs/vm-module-types/dist/types';
|
|
3
|
+
import { Module, ApprovalController, Environment, Manifest, Network, NetworkFees, GetTransactionHistory, RpcRequest, TransactionType } from '@avalabs/vm-module-types';
|
|
3
4
|
|
|
4
5
|
declare class EvmModule implements Module {
|
|
5
6
|
#private;
|
|
6
|
-
constructor({
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
proxyApiUrl: string;
|
|
7
|
+
constructor({ approvalController, environment, }: {
|
|
8
|
+
approvalController: ApprovalController;
|
|
9
|
+
environment: Environment;
|
|
10
10
|
});
|
|
11
11
|
getAddress(): Promise<string>;
|
|
12
12
|
getBalances(): Promise<string>;
|
|
13
13
|
getManifest(): Manifest | undefined;
|
|
14
|
-
getNetworkFee(
|
|
15
|
-
getTransactionHistory(params: GetTransactionHistory): Promise<
|
|
16
|
-
getTokens(
|
|
17
|
-
onRpcRequest(request: RpcRequest): Promise<{
|
|
18
|
-
error:
|
|
14
|
+
getNetworkFee(network: Network): Promise<NetworkFees>;
|
|
15
|
+
getTransactionHistory(params: GetTransactionHistory): Promise<_avalabs_vm_module_types_dist_types.TransactionHistoryResponse>;
|
|
16
|
+
getTokens(network: Network): Promise<_avalabs_vm_module_types_dist_types.NetworkContractToken[]>;
|
|
17
|
+
onRpcRequest(request: RpcRequest, network: Network): Promise<{
|
|
18
|
+
error: _metamask_rpc_errors.JsonRpcError<_metamask_rpc_errors.OptionalDataWithOptionalCause>;
|
|
19
|
+
result?: undefined;
|
|
20
|
+
} | {
|
|
21
|
+
result: any;
|
|
22
|
+
error?: undefined;
|
|
19
23
|
}>;
|
|
20
24
|
}
|
|
21
25
|
|
|
22
|
-
|
|
26
|
+
declare const NonContractCallTypes: TransactionType[];
|
|
27
|
+
type TransactionParams = {
|
|
28
|
+
from: string;
|
|
29
|
+
to: string;
|
|
30
|
+
data?: string;
|
|
31
|
+
value?: string;
|
|
32
|
+
gas?: string;
|
|
33
|
+
gasPrice?: string;
|
|
34
|
+
maxFeePerGas?: string;
|
|
35
|
+
maxPriorityFeePerGas?: string;
|
|
36
|
+
nonce?: string;
|
|
37
|
+
chainId?: string;
|
|
38
|
+
};
|
|
39
|
+
|
|
40
|
+
export { EvmModule, NonContractCallTypes, TransactionParams };
|