@avalabs/avalanche-module 0.0.13 → 0.0.15

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.
@@ -1,5 +1,5 @@
1
1
 
2
- > @avalabs/avalanche-module@0.0.13 build /home/runner/work/vm-modules/vm-modules/packages/avalanche-module
2
+ > @avalabs/avalanche-module@0.0.15 build /home/runner/work/vm-modules/vm-modules/packages/avalanche-module
3
3
  > tsup
4
4
 
5
5
  CLI Building entry: ./src/index.ts
@@ -10,13 +10,13 @@
10
10
  CLI Cleaning output folder
11
11
  CJS Build start
12
12
  ESM Build start
13
- CJS dist/index.cjs 1.50 KB
14
- CJS dist/index.cjs.map 4.25 KB
15
- CJS ⚡️ Build success in 392ms
16
- ESM dist/index.js 1.47 KB
17
- ESM dist/index.js.map 4.25 KB
18
- ESM ⚡️ Build success in 393ms
13
+ CJS dist/index.cjs 8.03 KB
14
+ CJS dist/index.cjs.map 26.46 KB
15
+ CJS ⚡️ Build success in 890ms
16
+ ESM dist/index.js 7.50 KB
17
+ ESM dist/index.js.map 26.46 KB
18
+ ESM ⚡️ Build success in 896ms
19
19
  DTS Build start
20
- DTS ⚡️ Build success in 7411ms
21
- DTS dist/index.d.cts 752.00 B
22
- DTS dist/index.d.ts 752.00 B
20
+ DTS ⚡️ Build success in 9781ms
21
+ DTS dist/index.d.cts 1.10 KB
22
+ DTS dist/index.d.ts 1.10 KB
@@ -1,4 +1,4 @@
1
1
 
2
- > @avalabs/avalanche-module@0.0.13 lint /home/runner/work/vm-modules/vm-modules/packages/avalanche-module
2
+ > @avalabs/avalanche-module@0.0.15 lint /home/runner/work/vm-modules/vm-modules/packages/avalanche-module
3
3
  > eslint "src/**/*.ts"
4
4
 
@@ -1,13 +1,13 @@
1
1
 
2
- > @avalabs/avalanche-module@0.0.13 test /home/runner/work/vm-modules/vm-modules/packages/avalanche-module
2
+ > @avalabs/avalanche-module@0.0.15 test /home/runner/work/vm-modules/vm-modules/packages/avalanche-module
3
3
  > jest
4
4
 
5
- PASS src/handlers/get-network-fee.test.ts (11.96 s)
5
+ PASS src/handlers/get-network-fee.test.ts (13.085 s)
6
6
  get-network-fee
7
- ✓ should return fixed network fees (3 ms)
7
+ ✓ should return fixed network fees (4 ms)
8
8
 
9
9
  Test Suites: 1 passed, 1 total
10
10
  Tests: 1 passed, 1 total
11
11
  Snapshots: 0 total
12
- Time: 12.168 s
12
+ Time: 13.303 s
13
13
  Ran all test suites.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,22 @@
1
1
  # @avalabs/avalanche-module
2
2
 
3
+ ## 0.0.15
4
+
5
+ ### Patch Changes
6
+
7
+ - Updated dependencies [f536d58]
8
+ - @avalabs/vm-module-types@0.0.15
9
+ - @internal/utils@0.0.3
10
+
11
+ ## 0.0.14
12
+
13
+ ### Patch Changes
14
+
15
+ - 0593258: add getBalances to evm-module
16
+ - Updated dependencies [0593258]
17
+ - @avalabs/vm-module-types@0.0.14
18
+ - @internal/utils@0.0.2
19
+
3
20
  ## 0.0.13
4
21
 
5
22
  ### Patch Changes
package/dist/index.cjs CHANGED
@@ -2,9 +2,16 @@
2
2
 
3
3
  var vmModuleTypes = require('@avalabs/vm-module-types');
4
4
  var rpcErrors = require('@metamask/rpc-errors');
5
+ var glacierSdk = require('@avalabs/glacier-sdk');
6
+ var u = require('big.js');
7
+ var walletsSdk = require('@avalabs/wallets-sdk');
5
8
 
6
- var r={name:"Avalanche",description:"",version:"0.0.1",sources:{module:{checksum:"",location:{npm:{filePath:"dist/bundle.js",packageName:"@avalabs/avalanche-module",registry:"https://registry.npmjs.org"}}},provider:{checksum:"",location:{npm:{filePath:"dist/provider.js",packageName:"@avalabs/avalanche-module",registry:"https://registry.npmjs.org"}}}},network:{chainIds:["avax:2oYMBNV4eNHyqk2fjjV5nVQLDbtmNJzq5s3qs3Lo6ftnC6FByM","avax:2JVSBoinj9C2J33VntvzYtVJNZdN2NKiwwKjcumHUWEb5DbBrm","avax:11111111111111111111111111111111LpoYY"],namespaces:["avax"]},cointype:"60",permissions:{rpc:{dapps:!0,methods:["avalanche_sendTransaction","avalanche_*"]}},manifestVersion:"0.0"};async function t(){return {baseFee:BigInt(1e6),low:{maxFeePerGas:BigInt(1e6)},medium:{maxFeePerGas:BigInt(1e6)},high:{maxFeePerGas:BigInt(1e6)},isFixedFee:!0}}var s=class{getAddress(){return Promise.resolve("Avalanche address")}getBalances(){return Promise.resolve("Avalanche balances")}getManifest(){let e=vmModuleTypes.parseManifest(r);return e.success?e.data:void 0}getNetworkFee(e){return t()}getTransactionHistory(e){return Promise.resolve({transactions:[]})}getTokens(e){return Promise.resolve([])}async onRpcRequest(e,m){switch(e.method){default:return {error:rpcErrors.rpcErrors.methodNotSupported(`Method ${e.method} not supported`)}}}};
9
+ function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
7
10
 
8
- exports.AvalancheModule = s;
11
+ var u__default = /*#__PURE__*/_interopDefault(u);
12
+
13
+ var J=Object.defineProperty;var q=(e,t,n)=>t in e?J(e,t,{enumerable:!0,configurable:!0,writable:!0,value:n}):e[t]=n;var g=(e,t,n)=>(q(e,typeof t!="symbol"?t+"":t,n),n),I=(e,t,n)=>{if(!t.has(e))throw TypeError("Cannot "+n)};var B=(e,t,n)=>(I(e,t,"read from private field"),n?n.call(e):t.get(e)),P=(e,t,n)=>{if(t.has(e))throw TypeError("Cannot add the same private member more than once");t instanceof WeakSet?t.add(e):t.set(e,n);},b=(e,t,n,o)=>(I(e,t,"write to private field"),o?o.call(e,n):t.set(e,n),n);var L={name:"Avalanche",description:"",version:"0.0.1",sources:{module:{checksum:"",location:{npm:{filePath:"dist/bundle.js",packageName:"@avalabs/avalanche-module",registry:"https://registry.npmjs.org"}}},provider:{checksum:"",location:{npm:{filePath:"dist/provider.js",packageName:"@avalabs/avalanche-module",registry:"https://registry.npmjs.org"}}}},network:{chainIds:["avax:2oYMBNV4eNHyqk2fjjV5nVQLDbtmNJzq5s3qs3Lo6ftnC6FByM","avax:2JVSBoinj9C2J33VntvzYtVJNZdN2NKiwwKjcumHUWEb5DbBrm","avax:11111111111111111111111111111111LpoYY"],namespaces:["avax"]},cointype:"60",permissions:{rpc:{dapps:!0,methods:["avalanche_sendTransaction","avalanche_*"]}},manifestVersion:"0.0"};async function S(){return {baseFee:BigInt(1e6),low:{maxFeePerGas:BigInt(1e6)},medium:{maxFeePerGas:BigInt(1e6)},high:{maxFeePerGas:BigInt(1e6)},isFixedFee:!0}}var U=e=>e.chainInfo.chainName===glacierSdk.PrimaryNetworkChainName.P_CHAIN,H=e=>e.chainInfo.chainName===glacierSdk.PrimaryNetworkChainName.X_CHAIN;function f(e,t,n="tx"){return `${e}/${n}/${t}`}function h({amount:e,decimals:t}){return e===void 0?new u__default.default(0):new u__default.default(e/10**t)}function F({tx:e,address:t,networkToken:n,chainId:o,explorerUrl:r,isTestnet:c}){let i=new Set(e.consumedUtxos.flatMap(a=>a.addresses)||[]),p=new Set(e.emittedUtxos.flatMap(a=>a.addresses)||[]),s=Y({tx:e,isTestnet:c,networkToken:n,froms:i}),l=$({tx:e,isTestnet:c,networkToken:n}),d=t.toLowerCase().startsWith("p-")?t.slice(2):t,m=i.has(d);return {hash:e.txHash,isContractCall:!1,isIncoming:!m,isOutgoing:m,from:[...i.values()].join(","),to:[...p.values()].join(","),isSender:m,timestamp:e.blockTimestamp*1e3,tokens:[{decimal:n.decimals.toString(),name:n.name,symbol:n.symbol,type:vmModuleTypes.TokenType.NATIVE,amount:s.toString()}],gasUsed:l.toString(),explorerLink:f(r??"",e.txHash,"tx"),txType:e.txType,chainId:o.toString()}}function Y({tx:e,isTestnet:t,networkToken:n,froms:o}){let r=["ImportTx","ExportTx"].includes(e.txType),c=e.txType==="BaseTx",i=e.emittedUtxos.filter(a=>a.asset.assetId===x(!!t)&&!a.addresses.some(T=>o.has(T))).reduce((a,T)=>a.add(T.asset.amount),new u__default.default(0)),p=e.value.find(a=>a.assetId===x(!!t))?.amount,s=i.gt(new u__default.default(0))?i:p?new u__default.default(p):new u__default.default(0)??new u__default.default(0),l=t?walletsSdk.Avalanche.FujiContext.pBlockchainID:walletsSdk.Avalanche.MainnetContext.pBlockchainID,d=e.emittedUtxos.filter(a=>a.asset.assetId===x(!!t)&&(e.txType==="ImportTx"&&a.consumedOnChainId===l||e.txType==="ExportTx"&&a.consumedOnChainId!==l)).reduce((a,T)=>a.add(T.amount),new u__default.default(0)),m=c?s:r?d:e.amountStaked.length===0?G(e.value,!!t):G(e.amountStaked,!!t);return h({amount:m?.toNumber(),decimals:n.decimals})}function $({tx:e,isTestnet:t,networkToken:n}){let o=e.amountBurned?.filter(r=>r.assetId===x(!!t)).reduce((r,c)=>r.add(c.amount),new u__default.default(0));return h({amount:o?.toNumber(),decimals:n.decimals})}function G(e,t){return e.filter(n=>n.assetId===x(t)).reduce((n,o)=>n.add(o.amount),new u__default.default(0))}function x(e){return e?walletsSdk.Avalanche.FujiContext.avaxAssetID:walletsSdk.Avalanche.MainnetContext.avaxAssetID}function X({tx:e,address:t,networkToken:n,chainId:o,explorerUrl:r,isTestnet:c}){let i=new Set(e.consumedUtxos.flatMap(a=>a.addresses)||[]),p=new Set(e.emittedUtxos.flatMap(a=>a.addresses)||[]),s=Q({tx:e,isTestnet:c,networkToken:n}),l=Z({isTestnet:c,tx:e,totalAmountCreated:s,networkToken:n}),d=t.toLowerCase().startsWith("x-")?t.slice(2):t,m=i.has(d);return {hash:e.txHash,isContractCall:!1,isIncoming:!m,isOutgoing:m,from:[...i.values()].join(","),to:[...p.values()].join(","),isSender:m,timestamp:e.timestamp*1e3,tokens:[{decimal:n.decimals.toString(),name:n.name,symbol:n.symbol,type:vmModuleTypes.TokenType.NATIVE,amount:s.toString()}],gasUsed:l.toString(),explorerLink:f(r??"",e.txHash,"tx"),txType:e.txType,chainId:o.toString()}}function Q({tx:e,isTestnet:t,networkToken:n}){let o=["ImportTx","ExportTx"].includes(e.txType),r=t?walletsSdk.Avalanche.FujiContext.xBlockchainID:walletsSdk.Avalanche.MainnetContext.xBlockchainID,c=e.emittedUtxos.filter(s=>s.asset.assetId===A(!!t)&&(e.txType==="ImportTx"&&s.consumedOnChainId===r||e.txType==="ExportTx"&&s.consumedOnChainId!==r)).reduce((s,l)=>s.add(l.asset.amount),new u__default.default(0)),i=e.amountCreated.filter(s=>s.assetId===A(!!t)).reduce((s,l)=>s.add(l.amount),new u__default.default(0));return h({amount:(o?c:i).toNumber(),decimals:n.decimals})}function Z({isTestnet:e,tx:t,totalAmountCreated:n,networkToken:o}){let c=t.amountUnlocked.filter(i=>i.assetId===A(!!e)).reduce((i,p)=>i.add(p.amount),new u__default.default(0)).minus(n);return h({amount:c.toNumber(),decimals:o.decimals})}function A(e){return e?walletsSdk.Avalanche.FujiContext.avaxAssetID:walletsSdk.Avalanche.MainnetContext.avaxAssetID}var V=async({address:e,nextPageToken:t,offset:n,network:o,glacierService:r})=>{let{isTestnet:c,networkToken:i,explorerUrl:p,chainId:s}=o;if(!r.isHealthy())return {transactions:[],nextPageToken:""};let d=await r.listLatestPrimaryNetworkTransactions({addresses:e,blockchainId:te(e),network:c?glacierSdk.Network.FUJI:glacierSdk.Network.MAINNET,pageSize:n,pageToken:t,sortOrder:glacierSdk.SortOrder.DESC}),m=[];return U(d)&&(m=d.transactions.map(a=>F({tx:a,isTestnet:c,address:e,networkToken:i,explorerUrl:p,chainId:s}))),H(d)&&(m=d.transactions.map(a=>X({tx:a,isTestnet:c,address:e,networkToken:i,explorerUrl:p,chainId:s}))),{transactions:m,nextPageToken:d.nextPageToken}},te=e=>e.split(",")[0]?.toLowerCase().startsWith("p-")?glacierSdk.BlockchainId.P_CHAIN:glacierSdk.BlockchainId.X_CHAIN;var ne={glacierApiUrl:"https://glacier-api.avax.network",proxyApiUrl:"https://proxy-api.avax.network"},ae={glacierApiUrl:"https://glacier-api-dev.avax.network",proxyApiUrl:"https://proxy-api-dev.avax.network"},O=e=>{switch(e){case vmModuleTypes.Environment.PRODUCTION:return ne;case vmModuleTypes.Environment.DEV:return ae}};var N=class extends Error{constructor(){super(...arguments);g(this,"message","Glacier is unhealthy. Try again later.");}},C=class{constructor({glacierApiUrl:t}){g(this,"glacierSdk");g(this,"isGlacierHealthy",!0);g(this,"isHealthy",()=>this.isGlacierHealthy);this.glacierSdk=new glacierSdk.Glacier({BASE:t});}setGlacierToUnhealthy(){this.isGlacierHealthy=!1,setTimeout(()=>{this.isGlacierHealthy=!0;},5*60*1e3);}async listLatestPrimaryNetworkTransactions(t){try{return this.glacierSdk.primaryNetworkTransactions.listLatestPrimaryNetworkTransactions(t)}catch(n){throw n instanceof N&&this.setGlacierToUnhealthy(),n}}};var y,_=class{constructor({environment:t}){P(this,y,void 0);let{glacierApiUrl:n}=O(t);b(this,y,new C({glacierApiUrl:n}));}getAddress(){return Promise.resolve("Avalanche address")}getBalances(t){return Promise.resolve({})}getManifest(){let t=vmModuleTypes.parseManifest(L);return t.success?t.data:void 0}getNetworkFee(t){return S()}getTransactionHistory({network:t,address:n,nextPageToken:o,offset:r}){return V({network:t,address:n,nextPageToken:o,offset:r,glacierService:B(this,y)})}getTokens(t){return Promise.resolve([])}async onRpcRequest(t,n){switch(t.method){default:return {error:rpcErrors.rpcErrors.methodNotSupported(`Method ${t.method} not supported`)}}}};y=new WeakMap;
14
+
15
+ exports.AvalancheModule = _;
9
16
  //# sourceMappingURL=out.js.map
10
17
  //# sourceMappingURL=index.cjs.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/module.ts","../manifest.json","../src/handlers/get-network-fee.ts"],"names":["parseManifest","rpcErrors","manifest_default","getNetworkFee","AvalancheModule","result","_","request","_network"],"mappings":"AAQA,OAAS,iBAAAA,MAAqB,2BAC9B,OAAS,aAAAC,MAAiB,uBCT1B,IAAAC,EAAA,CACE,KAAQ,YACR,YAAe,GACf,QAAW,QACX,QAAW,CACT,OAAU,CACR,SAAY,GACZ,SAAY,CACV,IAAO,CACL,SAAY,iBACZ,YAAe,4BACf,SAAY,4BACd,CACF,CACF,EACA,SAAY,CACV,SAAY,GACZ,SAAY,CACV,IAAO,CACL,SAAY,mBACZ,YAAe,4BACf,SAAY,4BACd,CACF,CACF,CACF,EACA,QAAW,CACT,SAAY,CACV,0DACA,0DACA,4CACF,EACA,WAAc,CAAC,MAAM,CACvB,EACA,SAAY,KACZ,YAAe,CACb,IAAO,CACL,MAAS,GACT,QAAW,CAAC,4BAA6B,aAAa,CACxD,CACF,EACA,gBAAmB,KACrB,ECrCA,eAAsBC,GAAsC,CAE1D,MAAO,CACL,QAAS,OAAO,GAAO,EACvB,IAAK,CACH,aAAc,OAAO,GAAO,CAC9B,EACA,OAAQ,CACN,aAAc,OAAO,GAAO,CAC9B,EACA,KAAM,CACJ,aAAc,OAAO,GAAO,CAC9B,EACA,WAAY,EACd,CACF,CFPO,IAAMC,EAAN,KAAwC,CAC7C,YAA8B,CAC5B,OAAO,QAAQ,QAAQ,mBAAmB,CAC5C,CAEA,aAA+B,CAC7B,OAAO,QAAQ,QAAQ,oBAAoB,CAC7C,CAEA,aAAoC,CAClC,IAAMC,EAASL,EAAcE,CAAY,EACzC,OAAOG,EAAO,QAAUA,EAAO,KAAO,MACxC,CAEA,cAAcC,EAAkC,CAC9C,OAAOH,EAAc,CACvB,CAEA,sBAAsBG,EAA0B,CAC9C,OAAO,QAAQ,QAAQ,CAAE,aAAc,CAAC,CAAE,CAAC,CAC7C,CAEA,UAAUA,EAAY,CACpB,OAAO,QAAQ,QAAQ,CAAC,CAAC,CAC3B,CAEA,MAAM,aAAaC,EAAqBC,EAAmB,CACzD,OAAQD,EAAQ,OAAQ,CACtB,QACE,MAAO,CAAE,MAAON,EAAU,mBAAmB,UAAUM,EAAQ,MAAM,gBAAgB,CAAE,CAC3F,CACF,CACF","sourcesContent":["import type {\n Module,\n Manifest,\n NetworkFees,\n GetTransactionHistory,\n RpcRequest,\n Network,\n} from '@avalabs/vm-module-types';\nimport { parseManifest } from '@avalabs/vm-module-types';\nimport { rpcErrors } from '@metamask/rpc-errors';\nimport ManifestJson from '../manifest.json';\nimport { getNetworkFee } from './handlers/get-network-fee';\n\nexport class AvalancheModule implements Module {\n getAddress(): Promise<string> {\n return Promise.resolve('Avalanche address');\n }\n\n getBalances(): Promise<string> {\n return Promise.resolve('Avalanche balances');\n }\n\n getManifest(): Manifest | undefined {\n const result = parseManifest(ManifestJson);\n return result.success ? result.data : undefined;\n }\n\n getNetworkFee(_: Network): Promise<NetworkFees> {\n return getNetworkFee();\n }\n\n getTransactionHistory(_: GetTransactionHistory) {\n return Promise.resolve({ transactions: [] });\n }\n\n getTokens(_: Network) {\n return Promise.resolve([]);\n }\n\n async onRpcRequest(request: RpcRequest, _network: Network) {\n switch (request.method) {\n default:\n return { error: rpcErrors.methodNotSupported(`Method ${request.method} not supported`) };\n }\n }\n}\n","{\n \"name\": \"Avalanche\",\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/avalanche-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/avalanche-module\",\n \"registry\": \"https://registry.npmjs.org\"\n }\n }\n }\n },\n \"network\": {\n \"chainIds\": [\n \"avax:2oYMBNV4eNHyqk2fjjV5nVQLDbtmNJzq5s3qs3Lo6ftnC6FByM\",\n \"avax:2JVSBoinj9C2J33VntvzYtVJNZdN2NKiwwKjcumHUWEb5DbBrm\",\n \"avax:11111111111111111111111111111111LpoYY\"\n ],\n \"namespaces\": [\"avax\"]\n },\n \"cointype\": \"60\",\n \"permissions\": {\n \"rpc\": {\n \"dapps\": true,\n \"methods\": [\"avalanche_sendTransaction\", \"avalanche_*\"]\n }\n },\n \"manifestVersion\": \"0.0\"\n}\n","import type { NetworkFees } from '@avalabs/vm-module-types';\n\n/**\n * Returns {@link NetworkFees} based on a fixed fee.\n */\nexport async function getNetworkFee(): Promise<NetworkFees> {\n // this is 0.001 Avax denominated in nAvax, taken from https://docs.avax.network/reference/standards/guides/txn-fees#fee-schedule\n return {\n baseFee: BigInt(1000000),\n low: {\n maxFeePerGas: BigInt(1000000),\n },\n medium: {\n maxFeePerGas: BigInt(1000000),\n },\n high: {\n maxFeePerGas: BigInt(1000000),\n },\n isFixedFee: true,\n };\n}\n"]}
1
+ {"version":3,"sources":["../src/module.ts","../manifest.json","../src/handlers/get-network-fee.ts","../src/handlers/get-transaction-history/get-transaction-history.ts","../src/handlers/get-transaction-history/utils.ts","../src/handlers/get-transaction-history/convert-p-chain-transaction.ts","../src/handlers/get-transaction-history/convert-x-chain-transaction.ts","../src/env.ts","../src/services/glacier-service/glacier-service.ts"],"names":["parseManifest","rpcErrors","manifest_default","getNetworkFee","BlockchainId","Network","SortOrder","PrimaryNetworkChainName","Big","isPChainTransactions","value","isXChainTransactions","getExplorerAddressByNetwork","explorerUrl","hash","hashType","getTokenValue","amount","decimals","Avalanche","TokenType","convertPChainTransaction","tx","address","networkToken","chainId","isTestnet","froms","utxo","tos","getAmount","avaxBurnedAmount","getBurnedAmount","chainAddress","isSender","isImportExport","isBaseTx","nonChangeEmittedUtxosAmt","getAvaxAssetId","addr","agg","txValue","val","baseTxValue","pBlockchainId","importExportAmount","nAvaxAmount","aggregateValue","nAvaxFee","accumulator","value_","convertXChainTransaction","xBlockchainId","totalAmountCreated","asset","getTransactionHistory","nextPageToken","offset","network","glacierService","response","getBlockchainIdByAddress","transactions","Environment","prodEnv","devEnv","getEnv","environment","Glacier","GlacierUnhealthyError","__publicField","AvalancheGlacierService","glacierApiUrl","params","error","_glacierService","AvalancheModule","__privateAdd","__privateSet","_","result","__privateGet","request","_network"],"mappings":"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","sourcesContent":["import type {\n Module,\n Manifest,\n NetworkFees,\n GetTransactionHistory,\n RpcRequest,\n Network,\n GetBalancesParams,\n GetBalancesResponse,\n Environment,\n} from '@avalabs/vm-module-types';\nimport { parseManifest } from '@avalabs/vm-module-types';\nimport { rpcErrors } from '@metamask/rpc-errors';\nimport ManifestJson from '../manifest.json';\nimport { getNetworkFee } from './handlers/get-network-fee';\nimport { getTransactionHistory } from './handlers/get-transaction-history/get-transaction-history';\nimport { getEnv } from './env';\nimport { AvalancheGlacierService } from './services/glacier-service/glacier-service';\n\nexport class AvalancheModule implements Module {\n #glacierService: AvalancheGlacierService;\n\n constructor({ environment }: { environment: Environment }) {\n const { glacierApiUrl } = getEnv(environment);\n this.#glacierService = new AvalancheGlacierService({ glacierApiUrl });\n }\n\n getAddress(): Promise<string> {\n return Promise.resolve('Avalanche address');\n }\n\n getBalances(_: GetBalancesParams): Promise<GetBalancesResponse> {\n return Promise.resolve({});\n }\n\n getManifest(): Manifest | undefined {\n const result = parseManifest(ManifestJson);\n return result.success ? result.data : undefined;\n }\n\n getNetworkFee(_: Network): Promise<NetworkFees> {\n return getNetworkFee();\n }\n\n getTransactionHistory({ network, address, nextPageToken, offset }: GetTransactionHistory) {\n return getTransactionHistory({ network, address, nextPageToken, offset, glacierService: this.#glacierService });\n }\n\n getTokens(_: Network) {\n return Promise.resolve([]);\n }\n\n async onRpcRequest(request: RpcRequest, _network: Network) {\n switch (request.method) {\n default:\n return { error: rpcErrors.methodNotSupported(`Method ${request.method} not supported`) };\n }\n }\n}\n","{\n \"name\": \"Avalanche\",\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/avalanche-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/avalanche-module\",\n \"registry\": \"https://registry.npmjs.org\"\n }\n }\n }\n },\n \"network\": {\n \"chainIds\": [\n \"avax:2oYMBNV4eNHyqk2fjjV5nVQLDbtmNJzq5s3qs3Lo6ftnC6FByM\",\n \"avax:2JVSBoinj9C2J33VntvzYtVJNZdN2NKiwwKjcumHUWEb5DbBrm\",\n \"avax:11111111111111111111111111111111LpoYY\"\n ],\n \"namespaces\": [\"avax\"]\n },\n \"cointype\": \"60\",\n \"permissions\": {\n \"rpc\": {\n \"dapps\": true,\n \"methods\": [\"avalanche_sendTransaction\", \"avalanche_*\"]\n }\n },\n \"manifestVersion\": \"0.0\"\n}\n","import type { NetworkFees } from '@avalabs/vm-module-types';\n\n/**\n * Returns {@link NetworkFees} based on a fixed fee.\n */\nexport async function getNetworkFee(): Promise<NetworkFees> {\n // this is 0.001 Avax denominated in nAvax, taken from https://docs.avax.network/reference/standards/guides/txn-fees#fee-schedule\n return {\n baseFee: BigInt(1000000),\n low: {\n maxFeePerGas: BigInt(1000000),\n },\n medium: {\n maxFeePerGas: BigInt(1000000),\n },\n high: {\n maxFeePerGas: BigInt(1000000),\n },\n isFixedFee: true,\n };\n}\n","import type { GetTransactionHistory, Transaction, TransactionHistoryResponse } from '@avalabs/vm-module-types';\nimport { BlockchainId, Network, SortOrder } from '@avalabs/glacier-sdk';\nimport { isPChainTransactions, isXChainTransactions } from './utils';\nimport { convertPChainTransaction } from './convert-p-chain-transaction';\nimport { convertXChainTransaction } from './convert-x-chain-transaction';\nimport type { AvalancheGlacierService } from '../../services/glacier-service/glacier-service';\n\nexport const getTransactionHistory = async ({\n address,\n nextPageToken,\n offset,\n network,\n glacierService,\n}: GetTransactionHistory & { glacierService: AvalancheGlacierService }): Promise<TransactionHistoryResponse> => {\n const { isTestnet, networkToken, explorerUrl, chainId } = network;\n const isHealthy = glacierService.isHealthy();\n if (!isHealthy) {\n return {\n transactions: [],\n nextPageToken: '',\n };\n }\n\n const response = await glacierService.listLatestPrimaryNetworkTransactions({\n addresses: address,\n blockchainId: getBlockchainIdByAddress(address),\n network: isTestnet ? Network.FUJI : Network.MAINNET,\n pageSize: offset,\n pageToken: nextPageToken,\n sortOrder: SortOrder.DESC,\n });\n\n let transactions: Transaction[] = [];\n if (isPChainTransactions(response)) {\n transactions = response.transactions.map((value) =>\n convertPChainTransaction({ tx: value, isTestnet, address, networkToken, explorerUrl, chainId }),\n );\n }\n if (isXChainTransactions(response)) {\n transactions = response.transactions.map((value) =>\n convertXChainTransaction({ tx: value, isTestnet, address, networkToken, explorerUrl, chainId }),\n );\n }\n\n return {\n transactions,\n nextPageToken: response.nextPageToken,\n };\n};\n\nconst getBlockchainIdByAddress = (address: string) => {\n // A comma separated list of X-Chain or P-Chain wallet addresses,\n // starting with \"avax\"/\"fuji\", \"P-avax\"/\"P-fuji\" or \"X-avax\"/\"X-fuji\"\n const firstAddress = address.split(',')[0];\n if (firstAddress?.toLowerCase().startsWith('p-')) {\n return BlockchainId.P_CHAIN;\n }\n return BlockchainId.X_CHAIN;\n};\n","import {\n PrimaryNetworkChainName,\n type ListCChainAtomicTransactionsResponse,\n type ListPChainTransactionsResponse,\n type ListXChainTransactionsResponse,\n} from '@avalabs/glacier-sdk';\nimport Big from 'big.js';\n\nexport const isPChainTransactions = (\n value: ListPChainTransactionsResponse | ListXChainTransactionsResponse | ListCChainAtomicTransactionsResponse,\n): value is ListPChainTransactionsResponse => {\n return value.chainInfo.chainName === PrimaryNetworkChainName.P_CHAIN;\n};\n\nexport const isXChainTransactions = (\n value: ListPChainTransactionsResponse | ListXChainTransactionsResponse | ListCChainAtomicTransactionsResponse,\n): value is ListXChainTransactionsResponse => {\n return value.chainInfo.chainName === PrimaryNetworkChainName.X_CHAIN;\n};\n\nexport function getExplorerAddressByNetwork(\n explorerUrl: string,\n hash: string,\n hashType: 'address' | 'tx' = 'tx',\n): string {\n return `${explorerUrl}/${hashType}/${hash}`;\n}\n\nexport function getTokenValue({ amount, decimals }: { decimals: number; amount?: number }): Big {\n return amount === undefined ? new Big(0) : new Big(amount / 10 ** decimals);\n}\n","import { type PChainTransaction, type NetworkToken } from '@avalabs/glacier-sdk';\nimport Big from 'big.js';\nimport { Avalanche } from '@avalabs/wallets-sdk';\nimport { TokenType, type Transaction } from '@avalabs/vm-module-types';\nimport { getExplorerAddressByNetwork, getTokenValue } from './utils';\n\nexport function convertPChainTransaction({\n tx,\n address,\n networkToken,\n chainId,\n explorerUrl,\n isTestnet,\n}: {\n tx: PChainTransaction;\n address: string;\n networkToken: NetworkToken;\n chainId: number;\n explorerUrl?: string;\n isTestnet?: boolean;\n}): Transaction {\n const froms = new Set(tx.consumedUtxos.flatMap((utxo) => utxo.addresses) || []);\n const tos = new Set(tx.emittedUtxos.flatMap((utxo) => utxo.addresses) || []);\n\n const amount = getAmount({\n tx,\n isTestnet,\n networkToken,\n froms,\n });\n\n const avaxBurnedAmount = getBurnedAmount({ tx, isTestnet, networkToken });\n const chainAddress = address.toLowerCase().startsWith('p-') ? address.slice(2) : address;\n const isSender = froms.has(chainAddress);\n\n return {\n hash: tx.txHash,\n isContractCall: false,\n isIncoming: !isSender,\n isOutgoing: isSender,\n from: [...froms.values()].join(','),\n to: [...tos.values()].join(','),\n isSender,\n timestamp: tx.blockTimestamp * 1000, // to millis\n tokens: [\n {\n decimal: networkToken.decimals.toString(),\n name: networkToken.name,\n symbol: networkToken.symbol,\n type: TokenType.NATIVE,\n amount: amount.toString(),\n },\n ],\n gasUsed: avaxBurnedAmount.toString(),\n explorerLink: getExplorerAddressByNetwork(explorerUrl ?? '', tx.txHash, 'tx'),\n txType: tx.txType,\n chainId: chainId.toString(),\n };\n}\n\nfunction getAmount({\n tx,\n isTestnet,\n networkToken,\n froms,\n}: {\n tx: PChainTransaction;\n isTestnet?: boolean;\n networkToken: NetworkToken;\n froms: Set<string>;\n}): Big {\n const isImportExport = ['ImportTx', 'ExportTx'].includes(tx.txType);\n const isBaseTx = tx.txType === 'BaseTx';\n\n const nonChangeEmittedUtxosAmt = tx.emittedUtxos\n .filter(\n (utxo) => utxo.asset.assetId === getAvaxAssetId(!!isTestnet) && !utxo.addresses.some((addr) => froms.has(addr)),\n )\n .reduce((agg, utxo) => agg.add(utxo.asset.amount), new Big(0));\n const txValue = tx.value.find((val) => val.assetId === getAvaxAssetId(!!isTestnet))?.amount;\n // This ternary attempts to cover the case where users send themselves AVAX\n // in which case the senders are the recipients and we should use the total tx value.\n const baseTxValue = nonChangeEmittedUtxosAmt.gt(new Big(0))\n ? nonChangeEmittedUtxosAmt\n : txValue\n ? new Big(txValue)\n : new Big(0) ?? new Big(0);\n\n const pBlockchainId = isTestnet ? Avalanche.FujiContext.pBlockchainID : Avalanche.MainnetContext.pBlockchainID;\n\n const importExportAmount = tx.emittedUtxos\n .filter(\n (utxo) =>\n utxo.asset.assetId === getAvaxAssetId(!!isTestnet) &&\n ((tx.txType === 'ImportTx' && utxo.consumedOnChainId === pBlockchainId) ||\n (tx.txType === 'ExportTx' && utxo.consumedOnChainId !== pBlockchainId)),\n )\n .reduce((agg, utxo) => agg.add(utxo.amount), new Big(0));\n const nAvaxAmount = isBaseTx\n ? baseTxValue\n : isImportExport\n ? importExportAmount\n : tx.amountStaked.length === 0\n ? aggregateValue(tx.value, !!isTestnet)\n : aggregateValue(tx.amountStaked, !!isTestnet);\n return getTokenValue({ amount: nAvaxAmount?.toNumber(), decimals: networkToken.decimals });\n}\n\nfunction getBurnedAmount({\n tx,\n isTestnet,\n networkToken,\n}: {\n tx: PChainTransaction;\n isTestnet?: boolean;\n networkToken: NetworkToken;\n}): Big {\n const nAvaxFee = tx.amountBurned\n ?.filter((value) => value.assetId === getAvaxAssetId(!!isTestnet))\n .reduce((accumulator, value) => accumulator.add(value.amount), new Big(0));\n return getTokenValue({ amount: nAvaxFee?.toNumber(), decimals: networkToken.decimals });\n}\n\nfunction aggregateValue(value: PChainTransaction['value'], isTestnet: boolean): Big | undefined {\n return value\n .filter((value_) => value_.assetId === getAvaxAssetId(isTestnet))\n .reduce((accumulator, value_) => accumulator.add(value_.amount), new Big(0));\n}\n\nfunction getAvaxAssetId(isTestnet: boolean): string {\n return isTestnet ? Avalanche.FujiContext.avaxAssetID : Avalanche.MainnetContext.avaxAssetID;\n}\n","import { type NetworkToken, XChainNonLinearTransaction, XChainLinearTransaction } from '@avalabs/glacier-sdk';\nimport Big from 'big.js';\nimport { Avalanche } from '@avalabs/wallets-sdk';\nimport { TokenType, type Transaction } from '@avalabs/vm-module-types';\nimport { getExplorerAddressByNetwork, getTokenValue } from './utils';\n\nexport function convertXChainTransaction({\n tx,\n address,\n networkToken,\n chainId,\n explorerUrl,\n isTestnet,\n}: {\n tx: XChainNonLinearTransaction | XChainLinearTransaction;\n address: string;\n networkToken: NetworkToken;\n chainId: number;\n isTestnet?: boolean;\n explorerUrl?: string;\n}): Transaction {\n const froms = new Set(tx.consumedUtxos.flatMap((utxo) => utxo.addresses) || []);\n const tos = new Set(tx.emittedUtxos.flatMap((utxo) => utxo.addresses) || []);\n\n const amount = getAmount({\n tx,\n isTestnet,\n networkToken,\n });\n const avaxBurnedAmount = getBurnedAmount({ isTestnet, tx, totalAmountCreated: amount, networkToken });\n const chainAddress = address.toLowerCase().startsWith('x-') ? address.slice(2) : address;\n const isSender = froms.has(chainAddress);\n\n return {\n hash: tx.txHash,\n isContractCall: false,\n isIncoming: !isSender,\n isOutgoing: isSender,\n from: [...froms.values()].join(','),\n to: [...tos.values()].join(','),\n isSender,\n timestamp: tx.timestamp * 1000, // to millis\n tokens: [\n {\n decimal: networkToken.decimals.toString(),\n name: networkToken.name,\n symbol: networkToken.symbol,\n type: TokenType.NATIVE,\n amount: amount.toString(),\n },\n ],\n gasUsed: avaxBurnedAmount.toString(),\n explorerLink: getExplorerAddressByNetwork(explorerUrl ?? '', tx.txHash, 'tx'),\n txType: tx.txType,\n chainId: chainId.toString(),\n };\n}\n\nfunction getAmount({\n tx,\n isTestnet,\n networkToken,\n}: {\n tx: XChainNonLinearTransaction | XChainLinearTransaction;\n isTestnet?: boolean;\n networkToken: NetworkToken;\n}): Big {\n const isImportExport = ['ImportTx', 'ExportTx'].includes(tx.txType);\n const xBlockchainId = isTestnet ? Avalanche.FujiContext.xBlockchainID : Avalanche.MainnetContext.xBlockchainID;\n const importExportAmount = tx.emittedUtxos\n .filter(\n (utxo) =>\n utxo.asset.assetId === getAvaxAssetId(!!isTestnet) &&\n ((tx.txType === 'ImportTx' && utxo.consumedOnChainId === xBlockchainId) ||\n (tx.txType === 'ExportTx' && utxo.consumedOnChainId !== xBlockchainId)),\n )\n .reduce((agg, utxo) => agg.add(utxo.asset.amount), new Big(0));\n\n const totalAmountCreated = tx.amountCreated\n .filter((asset) => asset.assetId === getAvaxAssetId(!!isTestnet))\n .reduce((accumulator, asset) => accumulator.add(asset.amount), new Big(0));\n const nAvaxAmt = isImportExport ? importExportAmount : totalAmountCreated;\n return getTokenValue({ amount: nAvaxAmt.toNumber(), decimals: networkToken.decimals });\n}\n\nfunction getBurnedAmount({\n isTestnet,\n tx,\n totalAmountCreated,\n networkToken,\n}: {\n isTestnet?: boolean;\n tx: XChainNonLinearTransaction | XChainLinearTransaction;\n totalAmountCreated: Big;\n networkToken: NetworkToken;\n}): Big {\n const totalAmountUnlocked = tx.amountUnlocked\n .filter((asset) => asset.assetId === getAvaxAssetId(!!isTestnet))\n .reduce((accumulator, asset) => accumulator.add(asset.amount), new Big(0));\n const nAvaxFee = totalAmountUnlocked.minus(totalAmountCreated);\n return getTokenValue({ amount: nAvaxFee.toNumber(), decimals: networkToken.decimals });\n}\n\nfunction getAvaxAssetId(isTestnet: boolean): string {\n return isTestnet ? Avalanche.FujiContext.avaxAssetID : Avalanche.MainnetContext.avaxAssetID;\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 BlockchainId,\n Glacier,\n type ListCChainAtomicTransactionsResponse,\n type ListPChainTransactionsResponse,\n type ListXChainTransactionsResponse,\n Network,\n PrimaryNetworkTxType,\n SortOrder,\n} from '@avalabs/glacier-sdk';\n\nclass GlacierUnhealthyError extends Error {\n override message = 'Glacier is unhealthy. Try again later.';\n}\n\nexport class AvalancheGlacierService {\n glacierSdk: Glacier;\n isGlacierHealthy = true;\n\n constructor({ glacierApiUrl }: { glacierApiUrl: string }) {\n this.glacierSdk = new Glacier({ BASE: glacierApiUrl });\n }\n\n isHealthy = (): boolean => this.isGlacierHealthy;\n\n setGlacierToUnhealthy(): void {\n this.isGlacierHealthy = false;\n setTimeout(\n () => {\n this.isGlacierHealthy = true;\n },\n 5 * 60 * 1000,\n ); // 5 minutes\n }\n\n async listLatestPrimaryNetworkTransactions(params: {\n blockchainId: BlockchainId;\n network: Network;\n addresses?: string;\n txTypes?: Array<PrimaryNetworkTxType>;\n startTimestamp?: number;\n endTimestamp?: number;\n pageToken?: string;\n pageSize?: number;\n sortOrder?: SortOrder;\n }): Promise<ListPChainTransactionsResponse | ListXChainTransactionsResponse | ListCChainAtomicTransactionsResponse> {\n try {\n return this.glacierSdk.primaryNetworkTransactions.listLatestPrimaryNetworkTransactions(params);\n } catch (error) {\n if (error instanceof GlacierUnhealthyError) {\n this.setGlacierToUnhealthy();\n }\n throw error;\n }\n }\n}\n"]}
package/dist/index.d.cts CHANGED
@@ -1,14 +1,17 @@
1
1
  import * as _metamask_rpc_errors from '@metamask/rpc-errors';
2
- import { Module, Manifest, Network, NetworkFees, GetTransactionHistory, RpcRequest } from '@avalabs/vm-module-types';
2
+ import * as _avalabs_vm_module_types_dist_transaction_history from '@avalabs/vm-module-types/dist/transaction-history';
3
+ import { Module, Environment, GetBalancesParams, GetBalancesResponse, Manifest, Network, NetworkFees, GetTransactionHistory, RpcRequest } from '@avalabs/vm-module-types';
3
4
 
4
5
  declare class AvalancheModule implements Module {
6
+ #private;
7
+ constructor({ environment }: {
8
+ environment: Environment;
9
+ });
5
10
  getAddress(): Promise<string>;
6
- getBalances(): Promise<string>;
11
+ getBalances(_: GetBalancesParams): Promise<GetBalancesResponse>;
7
12
  getManifest(): Manifest | undefined;
8
13
  getNetworkFee(_: Network): Promise<NetworkFees>;
9
- getTransactionHistory(_: GetTransactionHistory): Promise<{
10
- transactions: never[];
11
- }>;
14
+ getTransactionHistory({ network, address, nextPageToken, offset }: GetTransactionHistory): Promise<_avalabs_vm_module_types_dist_transaction_history.TransactionHistoryResponse>;
12
15
  getTokens(_: Network): Promise<never[]>;
13
16
  onRpcRequest(request: RpcRequest, _network: Network): Promise<{
14
17
  error: _metamask_rpc_errors.JsonRpcError<_metamask_rpc_errors.OptionalDataWithOptionalCause>;
package/dist/index.d.ts CHANGED
@@ -1,14 +1,17 @@
1
1
  import * as _metamask_rpc_errors from '@metamask/rpc-errors';
2
- import { Module, Manifest, Network, NetworkFees, GetTransactionHistory, RpcRequest } from '@avalabs/vm-module-types';
2
+ import * as _avalabs_vm_module_types_dist_transaction_history from '@avalabs/vm-module-types/dist/transaction-history';
3
+ import { Module, Environment, GetBalancesParams, GetBalancesResponse, Manifest, Network, NetworkFees, GetTransactionHistory, RpcRequest } from '@avalabs/vm-module-types';
3
4
 
4
5
  declare class AvalancheModule implements Module {
6
+ #private;
7
+ constructor({ environment }: {
8
+ environment: Environment;
9
+ });
5
10
  getAddress(): Promise<string>;
6
- getBalances(): Promise<string>;
11
+ getBalances(_: GetBalancesParams): Promise<GetBalancesResponse>;
7
12
  getManifest(): Manifest | undefined;
8
13
  getNetworkFee(_: Network): Promise<NetworkFees>;
9
- getTransactionHistory(_: GetTransactionHistory): Promise<{
10
- transactions: never[];
11
- }>;
14
+ getTransactionHistory({ network, address, nextPageToken, offset }: GetTransactionHistory): Promise<_avalabs_vm_module_types_dist_transaction_history.TransactionHistoryResponse>;
12
15
  getTokens(_: Network): Promise<never[]>;
13
16
  onRpcRequest(request: RpcRequest, _network: Network): Promise<{
14
17
  error: _metamask_rpc_errors.JsonRpcError<_metamask_rpc_errors.OptionalDataWithOptionalCause>;
package/dist/index.js CHANGED
@@ -1,8 +1,11 @@
1
- import { parseManifest } from '@avalabs/vm-module-types';
1
+ import { parseManifest, Environment, TokenType } from '@avalabs/vm-module-types';
2
2
  import { rpcErrors } from '@metamask/rpc-errors';
3
+ import { Network, SortOrder, BlockchainId, Glacier, PrimaryNetworkChainName } from '@avalabs/glacier-sdk';
4
+ import u from 'big.js';
5
+ import { Avalanche } from '@avalabs/wallets-sdk';
3
6
 
4
- var r={name:"Avalanche",description:"",version:"0.0.1",sources:{module:{checksum:"",location:{npm:{filePath:"dist/bundle.js",packageName:"@avalabs/avalanche-module",registry:"https://registry.npmjs.org"}}},provider:{checksum:"",location:{npm:{filePath:"dist/provider.js",packageName:"@avalabs/avalanche-module",registry:"https://registry.npmjs.org"}}}},network:{chainIds:["avax:2oYMBNV4eNHyqk2fjjV5nVQLDbtmNJzq5s3qs3Lo6ftnC6FByM","avax:2JVSBoinj9C2J33VntvzYtVJNZdN2NKiwwKjcumHUWEb5DbBrm","avax:11111111111111111111111111111111LpoYY"],namespaces:["avax"]},cointype:"60",permissions:{rpc:{dapps:!0,methods:["avalanche_sendTransaction","avalanche_*"]}},manifestVersion:"0.0"};async function t(){return {baseFee:BigInt(1e6),low:{maxFeePerGas:BigInt(1e6)},medium:{maxFeePerGas:BigInt(1e6)},high:{maxFeePerGas:BigInt(1e6)},isFixedFee:!0}}var s=class{getAddress(){return Promise.resolve("Avalanche address")}getBalances(){return Promise.resolve("Avalanche balances")}getManifest(){let e=parseManifest(r);return e.success?e.data:void 0}getNetworkFee(e){return t()}getTransactionHistory(e){return Promise.resolve({transactions:[]})}getTokens(e){return Promise.resolve([])}async onRpcRequest(e,m){switch(e.method){default:return {error:rpcErrors.methodNotSupported(`Method ${e.method} not supported`)}}}};
7
+ var J=Object.defineProperty;var q=(e,t,n)=>t in e?J(e,t,{enumerable:!0,configurable:!0,writable:!0,value:n}):e[t]=n;var g=(e,t,n)=>(q(e,typeof t!="symbol"?t+"":t,n),n),I=(e,t,n)=>{if(!t.has(e))throw TypeError("Cannot "+n)};var B=(e,t,n)=>(I(e,t,"read from private field"),n?n.call(e):t.get(e)),P=(e,t,n)=>{if(t.has(e))throw TypeError("Cannot add the same private member more than once");t instanceof WeakSet?t.add(e):t.set(e,n);},b=(e,t,n,o)=>(I(e,t,"write to private field"),o?o.call(e,n):t.set(e,n),n);var L={name:"Avalanche",description:"",version:"0.0.1",sources:{module:{checksum:"",location:{npm:{filePath:"dist/bundle.js",packageName:"@avalabs/avalanche-module",registry:"https://registry.npmjs.org"}}},provider:{checksum:"",location:{npm:{filePath:"dist/provider.js",packageName:"@avalabs/avalanche-module",registry:"https://registry.npmjs.org"}}}},network:{chainIds:["avax:2oYMBNV4eNHyqk2fjjV5nVQLDbtmNJzq5s3qs3Lo6ftnC6FByM","avax:2JVSBoinj9C2J33VntvzYtVJNZdN2NKiwwKjcumHUWEb5DbBrm","avax:11111111111111111111111111111111LpoYY"],namespaces:["avax"]},cointype:"60",permissions:{rpc:{dapps:!0,methods:["avalanche_sendTransaction","avalanche_*"]}},manifestVersion:"0.0"};async function S(){return {baseFee:BigInt(1e6),low:{maxFeePerGas:BigInt(1e6)},medium:{maxFeePerGas:BigInt(1e6)},high:{maxFeePerGas:BigInt(1e6)},isFixedFee:!0}}var U=e=>e.chainInfo.chainName===PrimaryNetworkChainName.P_CHAIN,H=e=>e.chainInfo.chainName===PrimaryNetworkChainName.X_CHAIN;function f(e,t,n="tx"){return `${e}/${n}/${t}`}function h({amount:e,decimals:t}){return e===void 0?new u(0):new u(e/10**t)}function F({tx:e,address:t,networkToken:n,chainId:o,explorerUrl:r,isTestnet:c}){let i=new Set(e.consumedUtxos.flatMap(a=>a.addresses)||[]),p=new Set(e.emittedUtxos.flatMap(a=>a.addresses)||[]),s=Y({tx:e,isTestnet:c,networkToken:n,froms:i}),l=$({tx:e,isTestnet:c,networkToken:n}),d=t.toLowerCase().startsWith("p-")?t.slice(2):t,m=i.has(d);return {hash:e.txHash,isContractCall:!1,isIncoming:!m,isOutgoing:m,from:[...i.values()].join(","),to:[...p.values()].join(","),isSender:m,timestamp:e.blockTimestamp*1e3,tokens:[{decimal:n.decimals.toString(),name:n.name,symbol:n.symbol,type:TokenType.NATIVE,amount:s.toString()}],gasUsed:l.toString(),explorerLink:f(r??"",e.txHash,"tx"),txType:e.txType,chainId:o.toString()}}function Y({tx:e,isTestnet:t,networkToken:n,froms:o}){let r=["ImportTx","ExportTx"].includes(e.txType),c=e.txType==="BaseTx",i=e.emittedUtxos.filter(a=>a.asset.assetId===x(!!t)&&!a.addresses.some(T=>o.has(T))).reduce((a,T)=>a.add(T.asset.amount),new u(0)),p=e.value.find(a=>a.assetId===x(!!t))?.amount,s=i.gt(new u(0))?i:p?new u(p):new u(0)??new u(0),l=t?Avalanche.FujiContext.pBlockchainID:Avalanche.MainnetContext.pBlockchainID,d=e.emittedUtxos.filter(a=>a.asset.assetId===x(!!t)&&(e.txType==="ImportTx"&&a.consumedOnChainId===l||e.txType==="ExportTx"&&a.consumedOnChainId!==l)).reduce((a,T)=>a.add(T.amount),new u(0)),m=c?s:r?d:e.amountStaked.length===0?G(e.value,!!t):G(e.amountStaked,!!t);return h({amount:m?.toNumber(),decimals:n.decimals})}function $({tx:e,isTestnet:t,networkToken:n}){let o=e.amountBurned?.filter(r=>r.assetId===x(!!t)).reduce((r,c)=>r.add(c.amount),new u(0));return h({amount:o?.toNumber(),decimals:n.decimals})}function G(e,t){return e.filter(n=>n.assetId===x(t)).reduce((n,o)=>n.add(o.amount),new u(0))}function x(e){return e?Avalanche.FujiContext.avaxAssetID:Avalanche.MainnetContext.avaxAssetID}function X({tx:e,address:t,networkToken:n,chainId:o,explorerUrl:r,isTestnet:c}){let i=new Set(e.consumedUtxos.flatMap(a=>a.addresses)||[]),p=new Set(e.emittedUtxos.flatMap(a=>a.addresses)||[]),s=Q({tx:e,isTestnet:c,networkToken:n}),l=Z({isTestnet:c,tx:e,totalAmountCreated:s,networkToken:n}),d=t.toLowerCase().startsWith("x-")?t.slice(2):t,m=i.has(d);return {hash:e.txHash,isContractCall:!1,isIncoming:!m,isOutgoing:m,from:[...i.values()].join(","),to:[...p.values()].join(","),isSender:m,timestamp:e.timestamp*1e3,tokens:[{decimal:n.decimals.toString(),name:n.name,symbol:n.symbol,type:TokenType.NATIVE,amount:s.toString()}],gasUsed:l.toString(),explorerLink:f(r??"",e.txHash,"tx"),txType:e.txType,chainId:o.toString()}}function Q({tx:e,isTestnet:t,networkToken:n}){let o=["ImportTx","ExportTx"].includes(e.txType),r=t?Avalanche.FujiContext.xBlockchainID:Avalanche.MainnetContext.xBlockchainID,c=e.emittedUtxos.filter(s=>s.asset.assetId===A(!!t)&&(e.txType==="ImportTx"&&s.consumedOnChainId===r||e.txType==="ExportTx"&&s.consumedOnChainId!==r)).reduce((s,l)=>s.add(l.asset.amount),new u(0)),i=e.amountCreated.filter(s=>s.assetId===A(!!t)).reduce((s,l)=>s.add(l.amount),new u(0));return h({amount:(o?c:i).toNumber(),decimals:n.decimals})}function Z({isTestnet:e,tx:t,totalAmountCreated:n,networkToken:o}){let c=t.amountUnlocked.filter(i=>i.assetId===A(!!e)).reduce((i,p)=>i.add(p.amount),new u(0)).minus(n);return h({amount:c.toNumber(),decimals:o.decimals})}function A(e){return e?Avalanche.FujiContext.avaxAssetID:Avalanche.MainnetContext.avaxAssetID}var V=async({address:e,nextPageToken:t,offset:n,network:o,glacierService:r})=>{let{isTestnet:c,networkToken:i,explorerUrl:p,chainId:s}=o;if(!r.isHealthy())return {transactions:[],nextPageToken:""};let d=await r.listLatestPrimaryNetworkTransactions({addresses:e,blockchainId:te(e),network:c?Network.FUJI:Network.MAINNET,pageSize:n,pageToken:t,sortOrder:SortOrder.DESC}),m=[];return U(d)&&(m=d.transactions.map(a=>F({tx:a,isTestnet:c,address:e,networkToken:i,explorerUrl:p,chainId:s}))),H(d)&&(m=d.transactions.map(a=>X({tx:a,isTestnet:c,address:e,networkToken:i,explorerUrl:p,chainId:s}))),{transactions:m,nextPageToken:d.nextPageToken}},te=e=>e.split(",")[0]?.toLowerCase().startsWith("p-")?BlockchainId.P_CHAIN:BlockchainId.X_CHAIN;var ne={glacierApiUrl:"https://glacier-api.avax.network",proxyApiUrl:"https://proxy-api.avax.network"},ae={glacierApiUrl:"https://glacier-api-dev.avax.network",proxyApiUrl:"https://proxy-api-dev.avax.network"},O=e=>{switch(e){case Environment.PRODUCTION:return ne;case Environment.DEV:return ae}};var N=class extends Error{constructor(){super(...arguments);g(this,"message","Glacier is unhealthy. Try again later.");}},C=class{constructor({glacierApiUrl:t}){g(this,"glacierSdk");g(this,"isGlacierHealthy",!0);g(this,"isHealthy",()=>this.isGlacierHealthy);this.glacierSdk=new Glacier({BASE:t});}setGlacierToUnhealthy(){this.isGlacierHealthy=!1,setTimeout(()=>{this.isGlacierHealthy=!0;},5*60*1e3);}async listLatestPrimaryNetworkTransactions(t){try{return this.glacierSdk.primaryNetworkTransactions.listLatestPrimaryNetworkTransactions(t)}catch(n){throw n instanceof N&&this.setGlacierToUnhealthy(),n}}};var y,_=class{constructor({environment:t}){P(this,y,void 0);let{glacierApiUrl:n}=O(t);b(this,y,new C({glacierApiUrl:n}));}getAddress(){return Promise.resolve("Avalanche address")}getBalances(t){return Promise.resolve({})}getManifest(){let t=parseManifest(L);return t.success?t.data:void 0}getNetworkFee(t){return S()}getTransactionHistory({network:t,address:n,nextPageToken:o,offset:r}){return V({network:t,address:n,nextPageToken:o,offset:r,glacierService:B(this,y)})}getTokens(t){return Promise.resolve([])}async onRpcRequest(t,n){switch(t.method){default:return {error:rpcErrors.methodNotSupported(`Method ${t.method} not supported`)}}}};y=new WeakMap;
5
8
 
6
- export { s as AvalancheModule };
9
+ export { _ as AvalancheModule };
7
10
  //# sourceMappingURL=out.js.map
8
11
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/module.ts","../manifest.json","../src/handlers/get-network-fee.ts"],"names":["parseManifest","rpcErrors","manifest_default","getNetworkFee","AvalancheModule","result","_","request","_network"],"mappings":"AAQA,OAAS,iBAAAA,MAAqB,2BAC9B,OAAS,aAAAC,MAAiB,uBCT1B,IAAAC,EAAA,CACE,KAAQ,YACR,YAAe,GACf,QAAW,QACX,QAAW,CACT,OAAU,CACR,SAAY,GACZ,SAAY,CACV,IAAO,CACL,SAAY,iBACZ,YAAe,4BACf,SAAY,4BACd,CACF,CACF,EACA,SAAY,CACV,SAAY,GACZ,SAAY,CACV,IAAO,CACL,SAAY,mBACZ,YAAe,4BACf,SAAY,4BACd,CACF,CACF,CACF,EACA,QAAW,CACT,SAAY,CACV,0DACA,0DACA,4CACF,EACA,WAAc,CAAC,MAAM,CACvB,EACA,SAAY,KACZ,YAAe,CACb,IAAO,CACL,MAAS,GACT,QAAW,CAAC,4BAA6B,aAAa,CACxD,CACF,EACA,gBAAmB,KACrB,ECrCA,eAAsBC,GAAsC,CAE1D,MAAO,CACL,QAAS,OAAO,GAAO,EACvB,IAAK,CACH,aAAc,OAAO,GAAO,CAC9B,EACA,OAAQ,CACN,aAAc,OAAO,GAAO,CAC9B,EACA,KAAM,CACJ,aAAc,OAAO,GAAO,CAC9B,EACA,WAAY,EACd,CACF,CFPO,IAAMC,EAAN,KAAwC,CAC7C,YAA8B,CAC5B,OAAO,QAAQ,QAAQ,mBAAmB,CAC5C,CAEA,aAA+B,CAC7B,OAAO,QAAQ,QAAQ,oBAAoB,CAC7C,CAEA,aAAoC,CAClC,IAAMC,EAASL,EAAcE,CAAY,EACzC,OAAOG,EAAO,QAAUA,EAAO,KAAO,MACxC,CAEA,cAAcC,EAAkC,CAC9C,OAAOH,EAAc,CACvB,CAEA,sBAAsBG,EAA0B,CAC9C,OAAO,QAAQ,QAAQ,CAAE,aAAc,CAAC,CAAE,CAAC,CAC7C,CAEA,UAAUA,EAAY,CACpB,OAAO,QAAQ,QAAQ,CAAC,CAAC,CAC3B,CAEA,MAAM,aAAaC,EAAqBC,EAAmB,CACzD,OAAQD,EAAQ,OAAQ,CACtB,QACE,MAAO,CAAE,MAAON,EAAU,mBAAmB,UAAUM,EAAQ,MAAM,gBAAgB,CAAE,CAC3F,CACF,CACF","sourcesContent":["import type {\n Module,\n Manifest,\n NetworkFees,\n GetTransactionHistory,\n RpcRequest,\n Network,\n} from '@avalabs/vm-module-types';\nimport { parseManifest } from '@avalabs/vm-module-types';\nimport { rpcErrors } from '@metamask/rpc-errors';\nimport ManifestJson from '../manifest.json';\nimport { getNetworkFee } from './handlers/get-network-fee';\n\nexport class AvalancheModule implements Module {\n getAddress(): Promise<string> {\n return Promise.resolve('Avalanche address');\n }\n\n getBalances(): Promise<string> {\n return Promise.resolve('Avalanche balances');\n }\n\n getManifest(): Manifest | undefined {\n const result = parseManifest(ManifestJson);\n return result.success ? result.data : undefined;\n }\n\n getNetworkFee(_: Network): Promise<NetworkFees> {\n return getNetworkFee();\n }\n\n getTransactionHistory(_: GetTransactionHistory) {\n return Promise.resolve({ transactions: [] });\n }\n\n getTokens(_: Network) {\n return Promise.resolve([]);\n }\n\n async onRpcRequest(request: RpcRequest, _network: Network) {\n switch (request.method) {\n default:\n return { error: rpcErrors.methodNotSupported(`Method ${request.method} not supported`) };\n }\n }\n}\n","{\n \"name\": \"Avalanche\",\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/avalanche-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/avalanche-module\",\n \"registry\": \"https://registry.npmjs.org\"\n }\n }\n }\n },\n \"network\": {\n \"chainIds\": [\n \"avax:2oYMBNV4eNHyqk2fjjV5nVQLDbtmNJzq5s3qs3Lo6ftnC6FByM\",\n \"avax:2JVSBoinj9C2J33VntvzYtVJNZdN2NKiwwKjcumHUWEb5DbBrm\",\n \"avax:11111111111111111111111111111111LpoYY\"\n ],\n \"namespaces\": [\"avax\"]\n },\n \"cointype\": \"60\",\n \"permissions\": {\n \"rpc\": {\n \"dapps\": true,\n \"methods\": [\"avalanche_sendTransaction\", \"avalanche_*\"]\n }\n },\n \"manifestVersion\": \"0.0\"\n}\n","import type { NetworkFees } from '@avalabs/vm-module-types';\n\n/**\n * Returns {@link NetworkFees} based on a fixed fee.\n */\nexport async function getNetworkFee(): Promise<NetworkFees> {\n // this is 0.001 Avax denominated in nAvax, taken from https://docs.avax.network/reference/standards/guides/txn-fees#fee-schedule\n return {\n baseFee: BigInt(1000000),\n low: {\n maxFeePerGas: BigInt(1000000),\n },\n medium: {\n maxFeePerGas: BigInt(1000000),\n },\n high: {\n maxFeePerGas: BigInt(1000000),\n },\n isFixedFee: true,\n };\n}\n"]}
1
+ {"version":3,"sources":["../src/module.ts","../manifest.json","../src/handlers/get-network-fee.ts","../src/handlers/get-transaction-history/get-transaction-history.ts","../src/handlers/get-transaction-history/utils.ts","../src/handlers/get-transaction-history/convert-p-chain-transaction.ts","../src/handlers/get-transaction-history/convert-x-chain-transaction.ts","../src/env.ts","../src/services/glacier-service/glacier-service.ts"],"names":["parseManifest","rpcErrors","manifest_default","getNetworkFee","BlockchainId","Network","SortOrder","PrimaryNetworkChainName","Big","isPChainTransactions","value","isXChainTransactions","getExplorerAddressByNetwork","explorerUrl","hash","hashType","getTokenValue","amount","decimals","Avalanche","TokenType","convertPChainTransaction","tx","address","networkToken","chainId","isTestnet","froms","utxo","tos","getAmount","avaxBurnedAmount","getBurnedAmount","chainAddress","isSender","isImportExport","isBaseTx","nonChangeEmittedUtxosAmt","getAvaxAssetId","addr","agg","txValue","val","baseTxValue","pBlockchainId","importExportAmount","nAvaxAmount","aggregateValue","nAvaxFee","accumulator","value_","convertXChainTransaction","xBlockchainId","totalAmountCreated","asset","getTransactionHistory","nextPageToken","offset","network","glacierService","response","getBlockchainIdByAddress","transactions","Environment","prodEnv","devEnv","getEnv","environment","Glacier","GlacierUnhealthyError","__publicField","AvalancheGlacierService","glacierApiUrl","params","error","_glacierService","AvalancheModule","__privateAdd","__privateSet","_","result","__privateGet","request","_network"],"mappings":"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","sourcesContent":["import type {\n Module,\n Manifest,\n NetworkFees,\n GetTransactionHistory,\n RpcRequest,\n Network,\n GetBalancesParams,\n GetBalancesResponse,\n Environment,\n} from '@avalabs/vm-module-types';\nimport { parseManifest } from '@avalabs/vm-module-types';\nimport { rpcErrors } from '@metamask/rpc-errors';\nimport ManifestJson from '../manifest.json';\nimport { getNetworkFee } from './handlers/get-network-fee';\nimport { getTransactionHistory } from './handlers/get-transaction-history/get-transaction-history';\nimport { getEnv } from './env';\nimport { AvalancheGlacierService } from './services/glacier-service/glacier-service';\n\nexport class AvalancheModule implements Module {\n #glacierService: AvalancheGlacierService;\n\n constructor({ environment }: { environment: Environment }) {\n const { glacierApiUrl } = getEnv(environment);\n this.#glacierService = new AvalancheGlacierService({ glacierApiUrl });\n }\n\n getAddress(): Promise<string> {\n return Promise.resolve('Avalanche address');\n }\n\n getBalances(_: GetBalancesParams): Promise<GetBalancesResponse> {\n return Promise.resolve({});\n }\n\n getManifest(): Manifest | undefined {\n const result = parseManifest(ManifestJson);\n return result.success ? result.data : undefined;\n }\n\n getNetworkFee(_: Network): Promise<NetworkFees> {\n return getNetworkFee();\n }\n\n getTransactionHistory({ network, address, nextPageToken, offset }: GetTransactionHistory) {\n return getTransactionHistory({ network, address, nextPageToken, offset, glacierService: this.#glacierService });\n }\n\n getTokens(_: Network) {\n return Promise.resolve([]);\n }\n\n async onRpcRequest(request: RpcRequest, _network: Network) {\n switch (request.method) {\n default:\n return { error: rpcErrors.methodNotSupported(`Method ${request.method} not supported`) };\n }\n }\n}\n","{\n \"name\": \"Avalanche\",\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/avalanche-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/avalanche-module\",\n \"registry\": \"https://registry.npmjs.org\"\n }\n }\n }\n },\n \"network\": {\n \"chainIds\": [\n \"avax:2oYMBNV4eNHyqk2fjjV5nVQLDbtmNJzq5s3qs3Lo6ftnC6FByM\",\n \"avax:2JVSBoinj9C2J33VntvzYtVJNZdN2NKiwwKjcumHUWEb5DbBrm\",\n \"avax:11111111111111111111111111111111LpoYY\"\n ],\n \"namespaces\": [\"avax\"]\n },\n \"cointype\": \"60\",\n \"permissions\": {\n \"rpc\": {\n \"dapps\": true,\n \"methods\": [\"avalanche_sendTransaction\", \"avalanche_*\"]\n }\n },\n \"manifestVersion\": \"0.0\"\n}\n","import type { NetworkFees } from '@avalabs/vm-module-types';\n\n/**\n * Returns {@link NetworkFees} based on a fixed fee.\n */\nexport async function getNetworkFee(): Promise<NetworkFees> {\n // this is 0.001 Avax denominated in nAvax, taken from https://docs.avax.network/reference/standards/guides/txn-fees#fee-schedule\n return {\n baseFee: BigInt(1000000),\n low: {\n maxFeePerGas: BigInt(1000000),\n },\n medium: {\n maxFeePerGas: BigInt(1000000),\n },\n high: {\n maxFeePerGas: BigInt(1000000),\n },\n isFixedFee: true,\n };\n}\n","import type { GetTransactionHistory, Transaction, TransactionHistoryResponse } from '@avalabs/vm-module-types';\nimport { BlockchainId, Network, SortOrder } from '@avalabs/glacier-sdk';\nimport { isPChainTransactions, isXChainTransactions } from './utils';\nimport { convertPChainTransaction } from './convert-p-chain-transaction';\nimport { convertXChainTransaction } from './convert-x-chain-transaction';\nimport type { AvalancheGlacierService } from '../../services/glacier-service/glacier-service';\n\nexport const getTransactionHistory = async ({\n address,\n nextPageToken,\n offset,\n network,\n glacierService,\n}: GetTransactionHistory & { glacierService: AvalancheGlacierService }): Promise<TransactionHistoryResponse> => {\n const { isTestnet, networkToken, explorerUrl, chainId } = network;\n const isHealthy = glacierService.isHealthy();\n if (!isHealthy) {\n return {\n transactions: [],\n nextPageToken: '',\n };\n }\n\n const response = await glacierService.listLatestPrimaryNetworkTransactions({\n addresses: address,\n blockchainId: getBlockchainIdByAddress(address),\n network: isTestnet ? Network.FUJI : Network.MAINNET,\n pageSize: offset,\n pageToken: nextPageToken,\n sortOrder: SortOrder.DESC,\n });\n\n let transactions: Transaction[] = [];\n if (isPChainTransactions(response)) {\n transactions = response.transactions.map((value) =>\n convertPChainTransaction({ tx: value, isTestnet, address, networkToken, explorerUrl, chainId }),\n );\n }\n if (isXChainTransactions(response)) {\n transactions = response.transactions.map((value) =>\n convertXChainTransaction({ tx: value, isTestnet, address, networkToken, explorerUrl, chainId }),\n );\n }\n\n return {\n transactions,\n nextPageToken: response.nextPageToken,\n };\n};\n\nconst getBlockchainIdByAddress = (address: string) => {\n // A comma separated list of X-Chain or P-Chain wallet addresses,\n // starting with \"avax\"/\"fuji\", \"P-avax\"/\"P-fuji\" or \"X-avax\"/\"X-fuji\"\n const firstAddress = address.split(',')[0];\n if (firstAddress?.toLowerCase().startsWith('p-')) {\n return BlockchainId.P_CHAIN;\n }\n return BlockchainId.X_CHAIN;\n};\n","import {\n PrimaryNetworkChainName,\n type ListCChainAtomicTransactionsResponse,\n type ListPChainTransactionsResponse,\n type ListXChainTransactionsResponse,\n} from '@avalabs/glacier-sdk';\nimport Big from 'big.js';\n\nexport const isPChainTransactions = (\n value: ListPChainTransactionsResponse | ListXChainTransactionsResponse | ListCChainAtomicTransactionsResponse,\n): value is ListPChainTransactionsResponse => {\n return value.chainInfo.chainName === PrimaryNetworkChainName.P_CHAIN;\n};\n\nexport const isXChainTransactions = (\n value: ListPChainTransactionsResponse | ListXChainTransactionsResponse | ListCChainAtomicTransactionsResponse,\n): value is ListXChainTransactionsResponse => {\n return value.chainInfo.chainName === PrimaryNetworkChainName.X_CHAIN;\n};\n\nexport function getExplorerAddressByNetwork(\n explorerUrl: string,\n hash: string,\n hashType: 'address' | 'tx' = 'tx',\n): string {\n return `${explorerUrl}/${hashType}/${hash}`;\n}\n\nexport function getTokenValue({ amount, decimals }: { decimals: number; amount?: number }): Big {\n return amount === undefined ? new Big(0) : new Big(amount / 10 ** decimals);\n}\n","import { type PChainTransaction, type NetworkToken } from '@avalabs/glacier-sdk';\nimport Big from 'big.js';\nimport { Avalanche } from '@avalabs/wallets-sdk';\nimport { TokenType, type Transaction } from '@avalabs/vm-module-types';\nimport { getExplorerAddressByNetwork, getTokenValue } from './utils';\n\nexport function convertPChainTransaction({\n tx,\n address,\n networkToken,\n chainId,\n explorerUrl,\n isTestnet,\n}: {\n tx: PChainTransaction;\n address: string;\n networkToken: NetworkToken;\n chainId: number;\n explorerUrl?: string;\n isTestnet?: boolean;\n}): Transaction {\n const froms = new Set(tx.consumedUtxos.flatMap((utxo) => utxo.addresses) || []);\n const tos = new Set(tx.emittedUtxos.flatMap((utxo) => utxo.addresses) || []);\n\n const amount = getAmount({\n tx,\n isTestnet,\n networkToken,\n froms,\n });\n\n const avaxBurnedAmount = getBurnedAmount({ tx, isTestnet, networkToken });\n const chainAddress = address.toLowerCase().startsWith('p-') ? address.slice(2) : address;\n const isSender = froms.has(chainAddress);\n\n return {\n hash: tx.txHash,\n isContractCall: false,\n isIncoming: !isSender,\n isOutgoing: isSender,\n from: [...froms.values()].join(','),\n to: [...tos.values()].join(','),\n isSender,\n timestamp: tx.blockTimestamp * 1000, // to millis\n tokens: [\n {\n decimal: networkToken.decimals.toString(),\n name: networkToken.name,\n symbol: networkToken.symbol,\n type: TokenType.NATIVE,\n amount: amount.toString(),\n },\n ],\n gasUsed: avaxBurnedAmount.toString(),\n explorerLink: getExplorerAddressByNetwork(explorerUrl ?? '', tx.txHash, 'tx'),\n txType: tx.txType,\n chainId: chainId.toString(),\n };\n}\n\nfunction getAmount({\n tx,\n isTestnet,\n networkToken,\n froms,\n}: {\n tx: PChainTransaction;\n isTestnet?: boolean;\n networkToken: NetworkToken;\n froms: Set<string>;\n}): Big {\n const isImportExport = ['ImportTx', 'ExportTx'].includes(tx.txType);\n const isBaseTx = tx.txType === 'BaseTx';\n\n const nonChangeEmittedUtxosAmt = tx.emittedUtxos\n .filter(\n (utxo) => utxo.asset.assetId === getAvaxAssetId(!!isTestnet) && !utxo.addresses.some((addr) => froms.has(addr)),\n )\n .reduce((agg, utxo) => agg.add(utxo.asset.amount), new Big(0));\n const txValue = tx.value.find((val) => val.assetId === getAvaxAssetId(!!isTestnet))?.amount;\n // This ternary attempts to cover the case where users send themselves AVAX\n // in which case the senders are the recipients and we should use the total tx value.\n const baseTxValue = nonChangeEmittedUtxosAmt.gt(new Big(0))\n ? nonChangeEmittedUtxosAmt\n : txValue\n ? new Big(txValue)\n : new Big(0) ?? new Big(0);\n\n const pBlockchainId = isTestnet ? Avalanche.FujiContext.pBlockchainID : Avalanche.MainnetContext.pBlockchainID;\n\n const importExportAmount = tx.emittedUtxos\n .filter(\n (utxo) =>\n utxo.asset.assetId === getAvaxAssetId(!!isTestnet) &&\n ((tx.txType === 'ImportTx' && utxo.consumedOnChainId === pBlockchainId) ||\n (tx.txType === 'ExportTx' && utxo.consumedOnChainId !== pBlockchainId)),\n )\n .reduce((agg, utxo) => agg.add(utxo.amount), new Big(0));\n const nAvaxAmount = isBaseTx\n ? baseTxValue\n : isImportExport\n ? importExportAmount\n : tx.amountStaked.length === 0\n ? aggregateValue(tx.value, !!isTestnet)\n : aggregateValue(tx.amountStaked, !!isTestnet);\n return getTokenValue({ amount: nAvaxAmount?.toNumber(), decimals: networkToken.decimals });\n}\n\nfunction getBurnedAmount({\n tx,\n isTestnet,\n networkToken,\n}: {\n tx: PChainTransaction;\n isTestnet?: boolean;\n networkToken: NetworkToken;\n}): Big {\n const nAvaxFee = tx.amountBurned\n ?.filter((value) => value.assetId === getAvaxAssetId(!!isTestnet))\n .reduce((accumulator, value) => accumulator.add(value.amount), new Big(0));\n return getTokenValue({ amount: nAvaxFee?.toNumber(), decimals: networkToken.decimals });\n}\n\nfunction aggregateValue(value: PChainTransaction['value'], isTestnet: boolean): Big | undefined {\n return value\n .filter((value_) => value_.assetId === getAvaxAssetId(isTestnet))\n .reduce((accumulator, value_) => accumulator.add(value_.amount), new Big(0));\n}\n\nfunction getAvaxAssetId(isTestnet: boolean): string {\n return isTestnet ? Avalanche.FujiContext.avaxAssetID : Avalanche.MainnetContext.avaxAssetID;\n}\n","import { type NetworkToken, XChainNonLinearTransaction, XChainLinearTransaction } from '@avalabs/glacier-sdk';\nimport Big from 'big.js';\nimport { Avalanche } from '@avalabs/wallets-sdk';\nimport { TokenType, type Transaction } from '@avalabs/vm-module-types';\nimport { getExplorerAddressByNetwork, getTokenValue } from './utils';\n\nexport function convertXChainTransaction({\n tx,\n address,\n networkToken,\n chainId,\n explorerUrl,\n isTestnet,\n}: {\n tx: XChainNonLinearTransaction | XChainLinearTransaction;\n address: string;\n networkToken: NetworkToken;\n chainId: number;\n isTestnet?: boolean;\n explorerUrl?: string;\n}): Transaction {\n const froms = new Set(tx.consumedUtxos.flatMap((utxo) => utxo.addresses) || []);\n const tos = new Set(tx.emittedUtxos.flatMap((utxo) => utxo.addresses) || []);\n\n const amount = getAmount({\n tx,\n isTestnet,\n networkToken,\n });\n const avaxBurnedAmount = getBurnedAmount({ isTestnet, tx, totalAmountCreated: amount, networkToken });\n const chainAddress = address.toLowerCase().startsWith('x-') ? address.slice(2) : address;\n const isSender = froms.has(chainAddress);\n\n return {\n hash: tx.txHash,\n isContractCall: false,\n isIncoming: !isSender,\n isOutgoing: isSender,\n from: [...froms.values()].join(','),\n to: [...tos.values()].join(','),\n isSender,\n timestamp: tx.timestamp * 1000, // to millis\n tokens: [\n {\n decimal: networkToken.decimals.toString(),\n name: networkToken.name,\n symbol: networkToken.symbol,\n type: TokenType.NATIVE,\n amount: amount.toString(),\n },\n ],\n gasUsed: avaxBurnedAmount.toString(),\n explorerLink: getExplorerAddressByNetwork(explorerUrl ?? '', tx.txHash, 'tx'),\n txType: tx.txType,\n chainId: chainId.toString(),\n };\n}\n\nfunction getAmount({\n tx,\n isTestnet,\n networkToken,\n}: {\n tx: XChainNonLinearTransaction | XChainLinearTransaction;\n isTestnet?: boolean;\n networkToken: NetworkToken;\n}): Big {\n const isImportExport = ['ImportTx', 'ExportTx'].includes(tx.txType);\n const xBlockchainId = isTestnet ? Avalanche.FujiContext.xBlockchainID : Avalanche.MainnetContext.xBlockchainID;\n const importExportAmount = tx.emittedUtxos\n .filter(\n (utxo) =>\n utxo.asset.assetId === getAvaxAssetId(!!isTestnet) &&\n ((tx.txType === 'ImportTx' && utxo.consumedOnChainId === xBlockchainId) ||\n (tx.txType === 'ExportTx' && utxo.consumedOnChainId !== xBlockchainId)),\n )\n .reduce((agg, utxo) => agg.add(utxo.asset.amount), new Big(0));\n\n const totalAmountCreated = tx.amountCreated\n .filter((asset) => asset.assetId === getAvaxAssetId(!!isTestnet))\n .reduce((accumulator, asset) => accumulator.add(asset.amount), new Big(0));\n const nAvaxAmt = isImportExport ? importExportAmount : totalAmountCreated;\n return getTokenValue({ amount: nAvaxAmt.toNumber(), decimals: networkToken.decimals });\n}\n\nfunction getBurnedAmount({\n isTestnet,\n tx,\n totalAmountCreated,\n networkToken,\n}: {\n isTestnet?: boolean;\n tx: XChainNonLinearTransaction | XChainLinearTransaction;\n totalAmountCreated: Big;\n networkToken: NetworkToken;\n}): Big {\n const totalAmountUnlocked = tx.amountUnlocked\n .filter((asset) => asset.assetId === getAvaxAssetId(!!isTestnet))\n .reduce((accumulator, asset) => accumulator.add(asset.amount), new Big(0));\n const nAvaxFee = totalAmountUnlocked.minus(totalAmountCreated);\n return getTokenValue({ amount: nAvaxFee.toNumber(), decimals: networkToken.decimals });\n}\n\nfunction getAvaxAssetId(isTestnet: boolean): string {\n return isTestnet ? Avalanche.FujiContext.avaxAssetID : Avalanche.MainnetContext.avaxAssetID;\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 BlockchainId,\n Glacier,\n type ListCChainAtomicTransactionsResponse,\n type ListPChainTransactionsResponse,\n type ListXChainTransactionsResponse,\n Network,\n PrimaryNetworkTxType,\n SortOrder,\n} from '@avalabs/glacier-sdk';\n\nclass GlacierUnhealthyError extends Error {\n override message = 'Glacier is unhealthy. Try again later.';\n}\n\nexport class AvalancheGlacierService {\n glacierSdk: Glacier;\n isGlacierHealthy = true;\n\n constructor({ glacierApiUrl }: { glacierApiUrl: string }) {\n this.glacierSdk = new Glacier({ BASE: glacierApiUrl });\n }\n\n isHealthy = (): boolean => this.isGlacierHealthy;\n\n setGlacierToUnhealthy(): void {\n this.isGlacierHealthy = false;\n setTimeout(\n () => {\n this.isGlacierHealthy = true;\n },\n 5 * 60 * 1000,\n ); // 5 minutes\n }\n\n async listLatestPrimaryNetworkTransactions(params: {\n blockchainId: BlockchainId;\n network: Network;\n addresses?: string;\n txTypes?: Array<PrimaryNetworkTxType>;\n startTimestamp?: number;\n endTimestamp?: number;\n pageToken?: string;\n pageSize?: number;\n sortOrder?: SortOrder;\n }): Promise<ListPChainTransactionsResponse | ListXChainTransactionsResponse | ListCChainAtomicTransactionsResponse> {\n try {\n return this.glacierSdk.primaryNetworkTransactions.listLatestPrimaryNetworkTransactions(params);\n } catch (error) {\n if (error instanceof GlacierUnhealthyError) {\n this.setGlacierToUnhealthy();\n }\n throw error;\n }\n }\n}\n"]}
package/package.json CHANGED
@@ -1,19 +1,19 @@
1
1
  {
2
2
  "name": "@avalabs/avalanche-module",
3
- "version": "0.0.13",
3
+ "version": "0.0.15",
4
4
  "main": "dist/index.cjs",
5
5
  "module": "dist/index.js",
6
6
  "typings": "dist/index.d.ts",
7
7
  "type": "module",
8
8
  "dependencies": {
9
- "@avalabs/vm-module-types": "0.0.13",
9
+ "@avalabs/vm-module-types": "0.0.15",
10
10
  "@metamask/rpc-errors": "6.3.0",
11
- "@avalabs/utils-sdk": "v2.8.0-alpha.187",
12
- "@avalabs/chains-sdk": "v2.8.0-alpha.187",
13
- "@avalabs/etherscan-sdk": "v2.8.0-alpha.187",
14
- "@avalabs/glacier-sdk": "v2.8.0-alpha.187",
15
- "@avalabs/wallets-sdk": "v2.8.0-alpha.187",
16
- "big.js": "6.2.1"
11
+ "@avalabs/utils-sdk": "v2.8.0-alpha.193",
12
+ "@avalabs/etherscan-sdk": "v2.8.0-alpha.193",
13
+ "@avalabs/glacier-sdk": "v2.8.0-alpha.193",
14
+ "@avalabs/wallets-sdk": "v2.8.0-alpha.193",
15
+ "big.js": "6.2.1",
16
+ "@internal/utils": "0.0.3"
17
17
  },
18
18
  "devDependencies": {
19
19
  "@types/jest": "29.5.7",
@@ -22,7 +22,7 @@
22
22
  "tsup": "7.2.0",
23
23
  "@types/big.js": "6.2.2",
24
24
  "@internal/tsup-config": "0.0.1",
25
- "eslint-config-custom": "0.0.2"
25
+ "eslint-config-custom": "0.0.3"
26
26
  },
27
27
  "scripts": {
28
28
  "build": "tsup",
package/src/env.ts ADDED
@@ -0,0 +1,25 @@
1
+ import { Environment } from '@avalabs/vm-module-types';
2
+
3
+ type Env = {
4
+ glacierApiUrl: string;
5
+ proxyApiUrl: string;
6
+ };
7
+
8
+ export const prodEnv: Env = {
9
+ glacierApiUrl: 'https://glacier-api.avax.network',
10
+ proxyApiUrl: 'https://proxy-api.avax.network',
11
+ };
12
+
13
+ export const devEnv: Env = {
14
+ glacierApiUrl: 'https://glacier-api-dev.avax.network',
15
+ proxyApiUrl: 'https://proxy-api-dev.avax.network',
16
+ };
17
+
18
+ export const getEnv = (environment: Environment): Env => {
19
+ switch (environment) {
20
+ case Environment.PRODUCTION:
21
+ return prodEnv;
22
+ case Environment.DEV:
23
+ return devEnv;
24
+ }
25
+ };
@@ -4,14 +4,21 @@ import { Avalanche } from '@avalabs/wallets-sdk';
4
4
  import { TokenType, type Transaction } from '@avalabs/vm-module-types';
5
5
  import { getExplorerAddressByNetwork, getTokenValue } from './utils';
6
6
 
7
- export function convertPChainTransaction(
8
- tx: PChainTransaction,
9
- isTestnet: boolean,
10
- address: string,
11
- networkToken: NetworkToken,
12
- explorerUrl: string,
13
- chainId: number,
14
- ): Transaction {
7
+ export function convertPChainTransaction({
8
+ tx,
9
+ address,
10
+ networkToken,
11
+ chainId,
12
+ explorerUrl,
13
+ isTestnet,
14
+ }: {
15
+ tx: PChainTransaction;
16
+ address: string;
17
+ networkToken: NetworkToken;
18
+ chainId: number;
19
+ explorerUrl?: string;
20
+ isTestnet?: boolean;
21
+ }): Transaction {
15
22
  const froms = new Set(tx.consumedUtxos.flatMap((utxo) => utxo.addresses) || []);
16
23
  const tos = new Set(tx.emittedUtxos.flatMap((utxo) => utxo.addresses) || []);
17
24
 
@@ -45,7 +52,7 @@ export function convertPChainTransaction(
45
52
  },
46
53
  ],
47
54
  gasUsed: avaxBurnedAmount.toString(),
48
- explorerLink: getExplorerAddressByNetwork(explorerUrl, tx.txHash, 'tx'),
55
+ explorerLink: getExplorerAddressByNetwork(explorerUrl ?? '', tx.txHash, 'tx'),
49
56
  txType: tx.txType,
50
57
  chainId: chainId.toString(),
51
58
  };
@@ -58,7 +65,7 @@ function getAmount({
58
65
  froms,
59
66
  }: {
60
67
  tx: PChainTransaction;
61
- isTestnet: boolean;
68
+ isTestnet?: boolean;
62
69
  networkToken: NetworkToken;
63
70
  froms: Set<string>;
64
71
  }): Big {
@@ -105,7 +112,7 @@ function getBurnedAmount({
105
112
  networkToken,
106
113
  }: {
107
114
  tx: PChainTransaction;
108
- isTestnet: boolean;
115
+ isTestnet?: boolean;
109
116
  networkToken: NetworkToken;
110
117
  }): Big {
111
118
  const nAvaxFee = tx.amountBurned
@@ -4,14 +4,21 @@ import { Avalanche } from '@avalabs/wallets-sdk';
4
4
  import { TokenType, type Transaction } from '@avalabs/vm-module-types';
5
5
  import { getExplorerAddressByNetwork, getTokenValue } from './utils';
6
6
 
7
- export function convertXChainTransaction(
8
- tx: XChainNonLinearTransaction | XChainLinearTransaction,
9
- isTestnet: boolean,
10
- address: string,
11
- networkToken: NetworkToken,
12
- explorerUrl: string,
13
- chainId: number,
14
- ): Transaction {
7
+ export function convertXChainTransaction({
8
+ tx,
9
+ address,
10
+ networkToken,
11
+ chainId,
12
+ explorerUrl,
13
+ isTestnet,
14
+ }: {
15
+ tx: XChainNonLinearTransaction | XChainLinearTransaction;
16
+ address: string;
17
+ networkToken: NetworkToken;
18
+ chainId: number;
19
+ isTestnet?: boolean;
20
+ explorerUrl?: string;
21
+ }): Transaction {
15
22
  const froms = new Set(tx.consumedUtxos.flatMap((utxo) => utxo.addresses) || []);
16
23
  const tos = new Set(tx.emittedUtxos.flatMap((utxo) => utxo.addresses) || []);
17
24
 
@@ -43,7 +50,7 @@ export function convertXChainTransaction(
43
50
  },
44
51
  ],
45
52
  gasUsed: avaxBurnedAmount.toString(),
46
- explorerLink: getExplorerAddressByNetwork(explorerUrl, tx.txHash, 'tx'),
53
+ explorerLink: getExplorerAddressByNetwork(explorerUrl ?? '', tx.txHash, 'tx'),
47
54
  txType: tx.txType,
48
55
  chainId: chainId.toString(),
49
56
  };
@@ -55,7 +62,7 @@ function getAmount({
55
62
  networkToken,
56
63
  }: {
57
64
  tx: XChainNonLinearTransaction | XChainLinearTransaction;
58
- isTestnet: boolean;
65
+ isTestnet?: boolean;
59
66
  networkToken: NetworkToken;
60
67
  }): Big {
61
68
  const isImportExport = ['ImportTx', 'ExportTx'].includes(tx.txType);
@@ -82,7 +89,7 @@ function getBurnedAmount({
82
89
  totalAmountCreated,
83
90
  networkToken,
84
91
  }: {
85
- isTestnet: boolean;
92
+ isTestnet?: boolean;
86
93
  tx: XChainNonLinearTransaction | XChainLinearTransaction;
87
94
  totalAmountCreated: Big;
88
95
  networkToken: NetworkToken;
@@ -1,22 +1,27 @@
1
1
  import type { GetTransactionHistory, Transaction, TransactionHistoryResponse } from '@avalabs/vm-module-types';
2
- import { BlockchainId, Network, SortOrder, Glacier } from '@avalabs/glacier-sdk';
2
+ import { BlockchainId, Network, SortOrder } from '@avalabs/glacier-sdk';
3
3
  import { isPChainTransactions, isXChainTransactions } from './utils';
4
4
  import { convertPChainTransaction } from './convert-p-chain-transaction';
5
5
  import { convertXChainTransaction } from './convert-x-chain-transaction';
6
+ import type { AvalancheGlacierService } from '../../services/glacier-service/glacier-service';
6
7
 
7
8
  export const getTransactionHistory = async ({
8
- isTestnet,
9
9
  address,
10
10
  nextPageToken,
11
11
  offset,
12
- glacierApiUrl,
13
- networkToken,
14
- explorerUrl,
15
- chainId,
16
- }: GetTransactionHistory): Promise<TransactionHistoryResponse> => {
17
- const glacierSdk = new Glacier({ BASE: glacierApiUrl });
12
+ network,
13
+ glacierService,
14
+ }: GetTransactionHistory & { glacierService: AvalancheGlacierService }): Promise<TransactionHistoryResponse> => {
15
+ const { isTestnet, networkToken, explorerUrl, chainId } = network;
16
+ const isHealthy = glacierService.isHealthy();
17
+ if (!isHealthy) {
18
+ return {
19
+ transactions: [],
20
+ nextPageToken: '',
21
+ };
22
+ }
18
23
 
19
- const response = await glacierSdk.primaryNetworkTransactions.listLatestPrimaryNetworkTransactions({
24
+ const response = await glacierService.listLatestPrimaryNetworkTransactions({
20
25
  addresses: address,
21
26
  blockchainId: getBlockchainIdByAddress(address),
22
27
  network: isTestnet ? Network.FUJI : Network.MAINNET,
@@ -28,12 +33,12 @@ export const getTransactionHistory = async ({
28
33
  let transactions: Transaction[] = [];
29
34
  if (isPChainTransactions(response)) {
30
35
  transactions = response.transactions.map((value) =>
31
- convertPChainTransaction(value, isTestnet, address, networkToken, explorerUrl, chainId),
36
+ convertPChainTransaction({ tx: value, isTestnet, address, networkToken, explorerUrl, chainId }),
32
37
  );
33
38
  }
34
39
  if (isXChainTransactions(response)) {
35
40
  transactions = response.transactions.map((value) =>
36
- convertXChainTransaction(value, isTestnet, address, networkToken, explorerUrl, chainId),
41
+ convertXChainTransaction({ tx: value, isTestnet, address, networkToken, explorerUrl, chainId }),
37
42
  );
38
43
  }
39
44
 
package/src/module.ts CHANGED
@@ -5,19 +5,32 @@ import type {
5
5
  GetTransactionHistory,
6
6
  RpcRequest,
7
7
  Network,
8
+ GetBalancesParams,
9
+ GetBalancesResponse,
10
+ Environment,
8
11
  } from '@avalabs/vm-module-types';
9
12
  import { parseManifest } from '@avalabs/vm-module-types';
10
13
  import { rpcErrors } from '@metamask/rpc-errors';
11
14
  import ManifestJson from '../manifest.json';
12
15
  import { getNetworkFee } from './handlers/get-network-fee';
16
+ import { getTransactionHistory } from './handlers/get-transaction-history/get-transaction-history';
17
+ import { getEnv } from './env';
18
+ import { AvalancheGlacierService } from './services/glacier-service/glacier-service';
13
19
 
14
20
  export class AvalancheModule implements Module {
21
+ #glacierService: AvalancheGlacierService;
22
+
23
+ constructor({ environment }: { environment: Environment }) {
24
+ const { glacierApiUrl } = getEnv(environment);
25
+ this.#glacierService = new AvalancheGlacierService({ glacierApiUrl });
26
+ }
27
+
15
28
  getAddress(): Promise<string> {
16
29
  return Promise.resolve('Avalanche address');
17
30
  }
18
31
 
19
- getBalances(): Promise<string> {
20
- return Promise.resolve('Avalanche balances');
32
+ getBalances(_: GetBalancesParams): Promise<GetBalancesResponse> {
33
+ return Promise.resolve({});
21
34
  }
22
35
 
23
36
  getManifest(): Manifest | undefined {
@@ -29,8 +42,8 @@ export class AvalancheModule implements Module {
29
42
  return getNetworkFee();
30
43
  }
31
44
 
32
- getTransactionHistory(_: GetTransactionHistory) {
33
- return Promise.resolve({ transactions: [] });
45
+ getTransactionHistory({ network, address, nextPageToken, offset }: GetTransactionHistory) {
46
+ return getTransactionHistory({ network, address, nextPageToken, offset, glacierService: this.#glacierService });
34
47
  }
35
48
 
36
49
  getTokens(_: Network) {
@@ -0,0 +1,56 @@
1
+ import {
2
+ BlockchainId,
3
+ Glacier,
4
+ type ListCChainAtomicTransactionsResponse,
5
+ type ListPChainTransactionsResponse,
6
+ type ListXChainTransactionsResponse,
7
+ Network,
8
+ PrimaryNetworkTxType,
9
+ SortOrder,
10
+ } from '@avalabs/glacier-sdk';
11
+
12
+ class GlacierUnhealthyError extends Error {
13
+ override message = 'Glacier is unhealthy. Try again later.';
14
+ }
15
+
16
+ export class AvalancheGlacierService {
17
+ glacierSdk: Glacier;
18
+ isGlacierHealthy = true;
19
+
20
+ constructor({ glacierApiUrl }: { glacierApiUrl: string }) {
21
+ this.glacierSdk = new Glacier({ BASE: glacierApiUrl });
22
+ }
23
+
24
+ isHealthy = (): boolean => this.isGlacierHealthy;
25
+
26
+ setGlacierToUnhealthy(): void {
27
+ this.isGlacierHealthy = false;
28
+ setTimeout(
29
+ () => {
30
+ this.isGlacierHealthy = true;
31
+ },
32
+ 5 * 60 * 1000,
33
+ ); // 5 minutes
34
+ }
35
+
36
+ async listLatestPrimaryNetworkTransactions(params: {
37
+ blockchainId: BlockchainId;
38
+ network: Network;
39
+ addresses?: string;
40
+ txTypes?: Array<PrimaryNetworkTxType>;
41
+ startTimestamp?: number;
42
+ endTimestamp?: number;
43
+ pageToken?: string;
44
+ pageSize?: number;
45
+ sortOrder?: SortOrder;
46
+ }): Promise<ListPChainTransactionsResponse | ListXChainTransactionsResponse | ListCChainAtomicTransactionsResponse> {
47
+ try {
48
+ return this.glacierSdk.primaryNetworkTransactions.listLatestPrimaryNetworkTransactions(params);
49
+ } catch (error) {
50
+ if (error instanceof GlacierUnhealthyError) {
51
+ this.setGlacierToUnhealthy();
52
+ }
53
+ throw error;
54
+ }
55
+ }
56
+ }