fizen-evm-networks 1.0.0
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/README.md +1 -0
- package/lib/constants/chainIds.d.ts +73 -0
- package/lib/constants/chainIds.js +75 -0
- package/lib/constants/rpcs.json +1039 -0
- package/lib/index.d.ts +1 -0
- package/lib/index.js +163 -0
- package/lib/lib/pubsub.d.ts +24 -0
- package/lib/lib/pubsub.js +46 -0
- package/lib/store/actions.d.ts +5 -0
- package/lib/store/actions.js +10 -0
- package/lib/store/index.d.ts +3 -0
- package/lib/store/index.js +14 -0
- package/lib/store/mutations.d.ts +5 -0
- package/lib/store/mutations.js +12 -0
- package/lib/store/state.d.ts +4 -0
- package/lib/store/state.js +5 -0
- package/lib/store/store.d.ts +35 -0
- package/lib/store/store.js +102 -0
- package/lib/utils/index.d.ts +3 -0
- package/lib/utils/index.js +39 -0
- package/package.json +34 -0
package/lib/index.d.ts
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
export {};
|
package/lib/index.js
ADDED
@@ -0,0 +1,163 @@
|
|
1
|
+
"use strict";
|
2
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
3
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
4
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
5
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
6
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
7
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
8
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
9
|
+
});
|
10
|
+
};
|
11
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
12
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
13
|
+
};
|
14
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
15
|
+
const axios_1 = __importDefault(require("axios"));
|
16
|
+
const utils_1 = require("./utils");
|
17
|
+
class FizenEvmNetworks {
|
18
|
+
constructor(ids) {
|
19
|
+
this._chains = [];
|
20
|
+
this.formatData = (url, data) => {
|
21
|
+
var _a, _b, _c;
|
22
|
+
let height = (_b = (_a = data === null || data === void 0 ? void 0 : data.result) === null || _a === void 0 ? void 0 : _a.number) !== null && _b !== void 0 ? _b : null;
|
23
|
+
let latency = (_c = data === null || data === void 0 ? void 0 : data.latency) !== null && _c !== void 0 ? _c : null;
|
24
|
+
if (height) {
|
25
|
+
const hexString = height.toString(16);
|
26
|
+
height = parseInt(hexString, 16);
|
27
|
+
}
|
28
|
+
else {
|
29
|
+
latency = null;
|
30
|
+
}
|
31
|
+
return { url, height, latency };
|
32
|
+
};
|
33
|
+
this._whiteListChainIds = ids;
|
34
|
+
}
|
35
|
+
init() {
|
36
|
+
return __awaiter(this, void 0, void 0, function* () {
|
37
|
+
this._chains = yield this._fetchChains();
|
38
|
+
this._internalFetchChains();
|
39
|
+
});
|
40
|
+
}
|
41
|
+
setWhiteListchainIds(ids) {
|
42
|
+
this._whiteListChainIds = ids;
|
43
|
+
}
|
44
|
+
_internalFetchChains() {
|
45
|
+
for (let chain of this._chains) {
|
46
|
+
this._fetchRPCData(chain.chainId, chain.rpc);
|
47
|
+
}
|
48
|
+
}
|
49
|
+
_fetchChains() {
|
50
|
+
return __awaiter(this, void 0, void 0, function* () {
|
51
|
+
const chains = yield (0, utils_1.fetcher)("https://chainid.network/chains.json");
|
52
|
+
const chainTvls = yield (0, utils_1.fetcher)("https://api.llama.fi/chains");
|
53
|
+
const sortedChains = chains
|
54
|
+
.filter((c) => c.name !== "420coin") // same chainId as ronin
|
55
|
+
.filter((c) => this._whiteListChainIds.includes(c.chainId))
|
56
|
+
.map((chain) => (0, utils_1.populateChain)(chain, chainTvls))
|
57
|
+
.sort((a, b) => {
|
58
|
+
var _a, _b;
|
59
|
+
return ((_a = b.tvl) !== null && _a !== void 0 ? _a : 0) - ((_b = a.tvl) !== null && _b !== void 0 ? _b : 0);
|
60
|
+
});
|
61
|
+
return sortedChains;
|
62
|
+
});
|
63
|
+
}
|
64
|
+
_fetchRPCData(chainId, urls) {
|
65
|
+
const queries = urls.map((url) => url.includes("wss://")
|
66
|
+
? this._socketQuery(chainId, url)
|
67
|
+
: this._httpQuery(chainId, url));
|
68
|
+
return queries;
|
69
|
+
}
|
70
|
+
_socketQuery(chainId, url) { }
|
71
|
+
_httpQuery(chainId, url) {
|
72
|
+
setInterval(() => __awaiter(this, void 0, void 0, function* () {
|
73
|
+
const data = yield this._fetchChain(url);
|
74
|
+
const dataFormated = this.formatData(url, data);
|
75
|
+
const chainFound = this._chains.find((chain) => chain.chainId === chainId);
|
76
|
+
if (chainFound) {
|
77
|
+
const found = chainFound.rpcsScore.find((rpc) => rpc.url === url);
|
78
|
+
if (found) {
|
79
|
+
found.latency = dataFormated.latency;
|
80
|
+
found.height = dataFormated.height;
|
81
|
+
}
|
82
|
+
}
|
83
|
+
}), 5000);
|
84
|
+
}
|
85
|
+
_fetchChain(url) {
|
86
|
+
return __awaiter(this, void 0, void 0, function* () {
|
87
|
+
if (url.includes("API_KEY"))
|
88
|
+
return null;
|
89
|
+
try {
|
90
|
+
let API = axios_1.default.create({
|
91
|
+
url,
|
92
|
+
headers: {
|
93
|
+
"Content-Type": "application/json",
|
94
|
+
},
|
95
|
+
});
|
96
|
+
API.interceptors.request.use(function (request) {
|
97
|
+
request.requestStart = Date.now();
|
98
|
+
return request;
|
99
|
+
});
|
100
|
+
API.interceptors.response.use(function (response) {
|
101
|
+
response.latency =
|
102
|
+
Date.now() - response.config.requestStart;
|
103
|
+
return response;
|
104
|
+
}, function (error) {
|
105
|
+
console.log(error);
|
106
|
+
if (error.response) {
|
107
|
+
error.response.latency = null;
|
108
|
+
}
|
109
|
+
return Promise.reject(error);
|
110
|
+
});
|
111
|
+
const rpcBody = JSON.stringify({
|
112
|
+
jsonrpc: "2.0",
|
113
|
+
method: "eth_getBlockByNumber",
|
114
|
+
params: ["latest", false],
|
115
|
+
id: 1,
|
116
|
+
});
|
117
|
+
const res = yield API.post(url, rpcBody);
|
118
|
+
let { data, latency } = res;
|
119
|
+
return Object.assign(Object.assign({}, data), { latency });
|
120
|
+
}
|
121
|
+
catch (error) {
|
122
|
+
return null;
|
123
|
+
}
|
124
|
+
});
|
125
|
+
}
|
126
|
+
getChains() {
|
127
|
+
return this._chains;
|
128
|
+
}
|
129
|
+
getLowestLatencyChain(chainId) {
|
130
|
+
const chain = this._chains.find((c) => c.chainId === chainId);
|
131
|
+
if (!chain)
|
132
|
+
return null;
|
133
|
+
const rpcsScore = chain.rpcsScore
|
134
|
+
.sort((a, b) => {
|
135
|
+
return a.latency - b.latency;
|
136
|
+
})
|
137
|
+
.filter((rpc) => rpc.latency !== null);
|
138
|
+
return rpcsScore[0];
|
139
|
+
}
|
140
|
+
}
|
141
|
+
// (async () => {
|
142
|
+
// const a = new FizenEvmNetworks([80001]);
|
143
|
+
// // const a = new FizenEvmNetworks([1, 137, 80001, 56, 97]);
|
144
|
+
// await a.init();
|
145
|
+
// let chains = a.getLowestLatencyChain(80001);
|
146
|
+
// console.log(chains);
|
147
|
+
// // Sleep for 5 seconds
|
148
|
+
// await new Promise((resolve) => setTimeout(resolve, 5000));
|
149
|
+
// chains = a.getLowestLatencyChain(80001);
|
150
|
+
// console.log(chains);
|
151
|
+
// await new Promise((resolve) => setTimeout(resolve, 5000));
|
152
|
+
// chains = a.getLowestLatencyChain(80001);
|
153
|
+
// console.log(chains);
|
154
|
+
// await new Promise((resolve) => setTimeout(resolve, 5000));
|
155
|
+
// chains = a.getLowestLatencyChain(80001);
|
156
|
+
// console.log(chains);
|
157
|
+
// await new Promise((resolve) => setTimeout(resolve, 5000));
|
158
|
+
// chains = a.getLowestLatencyChain(80001);
|
159
|
+
// console.log(chains);
|
160
|
+
// await new Promise((resolve) => setTimeout(resolve, 5000));
|
161
|
+
// chains = a.getLowestLatencyChain(80001);
|
162
|
+
// console.log(chains);
|
163
|
+
// })();
|
@@ -0,0 +1,24 @@
|
|
1
|
+
export default class PubSub {
|
2
|
+
private events;
|
3
|
+
constructor();
|
4
|
+
/**
|
5
|
+
* Either create a new event instance for passed `event` name
|
6
|
+
* or push a new callback into the existing collection
|
7
|
+
*
|
8
|
+
* @param {string} event
|
9
|
+
* @param {function} callback
|
10
|
+
* @returns {number} A count of callbacks for this event
|
11
|
+
* @memberof PubSub
|
12
|
+
*/
|
13
|
+
subscribe(event: string, callback: Function): any;
|
14
|
+
/**
|
15
|
+
* If the passed event has callbacks attached to it, loop through each one
|
16
|
+
* and call it
|
17
|
+
*
|
18
|
+
* @param {string} event
|
19
|
+
* @param {object} [data={}]
|
20
|
+
* @returns {array} The callbacks for this event, or an empty array if no event exits
|
21
|
+
* @memberof PubSub
|
22
|
+
*/
|
23
|
+
publish(event: string, data?: {}): any;
|
24
|
+
}
|
@@ -0,0 +1,46 @@
|
|
1
|
+
"use strict";
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
3
|
+
class PubSub {
|
4
|
+
constructor() {
|
5
|
+
this.events = {};
|
6
|
+
}
|
7
|
+
/**
|
8
|
+
* Either create a new event instance for passed `event` name
|
9
|
+
* or push a new callback into the existing collection
|
10
|
+
*
|
11
|
+
* @param {string} event
|
12
|
+
* @param {function} callback
|
13
|
+
* @returns {number} A count of callbacks for this event
|
14
|
+
* @memberof PubSub
|
15
|
+
*/
|
16
|
+
subscribe(event, callback) {
|
17
|
+
let self = this;
|
18
|
+
// If there's not already an event with this name set in our collection
|
19
|
+
// go ahead and create a new one and set it with an empty array, so we don't
|
20
|
+
// have to type check it later down-the-line
|
21
|
+
if (!self.events.hasOwnProperty(event)) {
|
22
|
+
self.events[event] = [];
|
23
|
+
}
|
24
|
+
// We know we've got an array for this event, so push our callback in there with no fuss
|
25
|
+
return self.events[event].push(callback);
|
26
|
+
}
|
27
|
+
/**
|
28
|
+
* If the passed event has callbacks attached to it, loop through each one
|
29
|
+
* and call it
|
30
|
+
*
|
31
|
+
* @param {string} event
|
32
|
+
* @param {object} [data={}]
|
33
|
+
* @returns {array} The callbacks for this event, or an empty array if no event exits
|
34
|
+
* @memberof PubSub
|
35
|
+
*/
|
36
|
+
publish(event, data = {}) {
|
37
|
+
let self = this;
|
38
|
+
// There's no event to publish to, so bail out
|
39
|
+
if (!self.events.hasOwnProperty(event)) {
|
40
|
+
return [];
|
41
|
+
}
|
42
|
+
// Get each subscription and call its callback with the passed data
|
43
|
+
return self.events[event].map((callback) => callback(data));
|
44
|
+
}
|
45
|
+
}
|
46
|
+
exports.default = PubSub;
|
@@ -0,0 +1,14 @@
|
|
1
|
+
"use strict";
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
4
|
+
};
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
6
|
+
const actions_js_1 = __importDefault(require("./actions.js"));
|
7
|
+
const mutations_js_1 = __importDefault(require("./mutations.js"));
|
8
|
+
const state_js_1 = __importDefault(require("./state.js"));
|
9
|
+
const store_js_1 = __importDefault(require("./store.js"));
|
10
|
+
exports.default = new store_js_1.default({
|
11
|
+
actions: actions_js_1.default,
|
12
|
+
mutations: mutations_js_1.default,
|
13
|
+
state: state_js_1.default,
|
14
|
+
});
|
@@ -0,0 +1,12 @@
|
|
1
|
+
"use strict";
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
3
|
+
exports.default = {
|
4
|
+
addItem(state, payload) {
|
5
|
+
state.items.push(payload);
|
6
|
+
return state;
|
7
|
+
},
|
8
|
+
clearItem(state, payload) {
|
9
|
+
state.items.splice(payload.index, 1);
|
10
|
+
return state;
|
11
|
+
},
|
12
|
+
};
|
@@ -0,0 +1,35 @@
|
|
1
|
+
export default class Store {
|
2
|
+
private actions;
|
3
|
+
private mutations;
|
4
|
+
private state;
|
5
|
+
private status;
|
6
|
+
private events;
|
7
|
+
constructor(params: {
|
8
|
+
state: any;
|
9
|
+
actions: any;
|
10
|
+
mutations: any;
|
11
|
+
plugins?: any;
|
12
|
+
middleware?: any;
|
13
|
+
pubsub?: any;
|
14
|
+
});
|
15
|
+
/**
|
16
|
+
* A dispatcher for actions that looks in the actions
|
17
|
+
* collection and runs the action if it can find it
|
18
|
+
*
|
19
|
+
* @param {string} actionKey
|
20
|
+
* @param {mixed} payload
|
21
|
+
* @returns {boolean}
|
22
|
+
* @memberof Store
|
23
|
+
*/
|
24
|
+
dispatch(actionKey: string, payload: any): boolean;
|
25
|
+
/**
|
26
|
+
* Look for a mutation and modify the state object
|
27
|
+
* if that mutation exists by calling it
|
28
|
+
*
|
29
|
+
* @param {string} mutationKey
|
30
|
+
* @param {mixed} payload
|
31
|
+
* @returns {boolean}
|
32
|
+
* @memberof Store
|
33
|
+
*/
|
34
|
+
commit(mutationKey: string, payload: any): boolean;
|
35
|
+
}
|
@@ -0,0 +1,102 @@
|
|
1
|
+
"use strict";
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
4
|
+
};
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
6
|
+
const pubsub_js_1 = __importDefault(require("../lib/pubsub.js"));
|
7
|
+
class Store {
|
8
|
+
constructor(params) {
|
9
|
+
this.status = "resting";
|
10
|
+
this.events = new pubsub_js_1.default();
|
11
|
+
let self = this;
|
12
|
+
// Add some default objects to hold our actions, mutations and state
|
13
|
+
self.actions = {};
|
14
|
+
self.mutations = {};
|
15
|
+
self.state = {};
|
16
|
+
// A status enum to set during actions and mutations
|
17
|
+
self.status = "resting";
|
18
|
+
// Attach our PubSub module as an `events` element
|
19
|
+
self.events = new pubsub_js_1.default();
|
20
|
+
// Look in the passed params object for actions and mutations
|
21
|
+
// that might have been passed in
|
22
|
+
if (params.hasOwnProperty("actions")) {
|
23
|
+
self.actions = params.actions;
|
24
|
+
}
|
25
|
+
if (params.hasOwnProperty("mutations")) {
|
26
|
+
self.mutations = params.mutations;
|
27
|
+
}
|
28
|
+
// Set our state to be a Proxy. We are setting the default state by
|
29
|
+
// checking the params and defaulting to an empty object if no default
|
30
|
+
// state is passed in
|
31
|
+
self.state = new Proxy(params.state || {}, {
|
32
|
+
set: function (state, key, value) {
|
33
|
+
// Set the value as we would normally
|
34
|
+
state[key] = value;
|
35
|
+
// Trace out to the console. This will be grouped by the related action
|
36
|
+
console.log(`stateChange: ${key}: ${value}`);
|
37
|
+
// Publish the change event for the components that are listening
|
38
|
+
self.events.publish("stateChange", self.state);
|
39
|
+
// Give the user a little telling off if they set a value directly
|
40
|
+
if (self.status !== "mutation") {
|
41
|
+
console.warn(`You should use a mutation to set ${key}`);
|
42
|
+
}
|
43
|
+
// Reset the status ready for the next operation
|
44
|
+
self.status = "resting";
|
45
|
+
return true;
|
46
|
+
},
|
47
|
+
});
|
48
|
+
}
|
49
|
+
/**
|
50
|
+
* A dispatcher for actions that looks in the actions
|
51
|
+
* collection and runs the action if it can find it
|
52
|
+
*
|
53
|
+
* @param {string} actionKey
|
54
|
+
* @param {mixed} payload
|
55
|
+
* @returns {boolean}
|
56
|
+
* @memberof Store
|
57
|
+
*/
|
58
|
+
dispatch(actionKey, payload) {
|
59
|
+
let self = this;
|
60
|
+
// Run a quick check to see if the action actually exists
|
61
|
+
// before we try to run it
|
62
|
+
if (typeof self.actions[actionKey] !== "function") {
|
63
|
+
console.error(`Action "${actionKey} doesn't exist.`);
|
64
|
+
return false;
|
65
|
+
}
|
66
|
+
// Create a console group which will contain the logs from our Proxy etc
|
67
|
+
console.groupCollapsed(`ACTION: ${actionKey}`);
|
68
|
+
// Let anything that's watching the status know that we're dispatching an action
|
69
|
+
self.status = "action";
|
70
|
+
// Actually call the action and pass it the Store context and whatever payload was passed
|
71
|
+
self.actions[actionKey](self, payload);
|
72
|
+
// Close our console group to keep things nice and neat
|
73
|
+
console.groupEnd();
|
74
|
+
return true;
|
75
|
+
}
|
76
|
+
/**
|
77
|
+
* Look for a mutation and modify the state object
|
78
|
+
* if that mutation exists by calling it
|
79
|
+
*
|
80
|
+
* @param {string} mutationKey
|
81
|
+
* @param {mixed} payload
|
82
|
+
* @returns {boolean}
|
83
|
+
* @memberof Store
|
84
|
+
*/
|
85
|
+
commit(mutationKey, payload) {
|
86
|
+
let self = this;
|
87
|
+
// Run a quick check to see if this mutation actually exists
|
88
|
+
// before trying to run it
|
89
|
+
if (typeof self.mutations[mutationKey] !== "function") {
|
90
|
+
console.log(`Mutation "${mutationKey}" doesn't exist`);
|
91
|
+
return false;
|
92
|
+
}
|
93
|
+
// Let anything that's watching the status know that we're mutating state
|
94
|
+
self.status = "mutation";
|
95
|
+
// Get a new version of the state by running the mutation and storing the result of it
|
96
|
+
let newState = self.mutations[mutationKey](self.state, payload);
|
97
|
+
// Merge the old and new together to create a new state and set it
|
98
|
+
self.state = Object.assign(self.state, newState);
|
99
|
+
return true;
|
100
|
+
}
|
101
|
+
}
|
102
|
+
exports.default = Store;
|
@@ -0,0 +1,39 @@
|
|
1
|
+
"use strict";
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
4
|
+
};
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
6
|
+
exports.populateChain = exports.fetcher = void 0;
|
7
|
+
const rpcs_json_1 = __importDefault(require("../constants/rpcs.json"));
|
8
|
+
const chainIds_1 = __importDefault(require("../constants/chainIds"));
|
9
|
+
const node_fetch_1 = __importDefault(require("node-fetch"));
|
10
|
+
const fetcher = (...args) => (0, node_fetch_1.default)(...args).then((res) => res.json());
|
11
|
+
exports.fetcher = fetcher;
|
12
|
+
function removeEndingSlash(rpc) {
|
13
|
+
return rpc.endsWith("/") ? rpc.substr(0, rpc.length - 1) : rpc;
|
14
|
+
}
|
15
|
+
function populateChain(chain, chainTvls) {
|
16
|
+
var _a;
|
17
|
+
const extraRpcs = (_a = rpcs_json_1.default[chain.chainId]) === null || _a === void 0 ? void 0 : _a.rpcs;
|
18
|
+
if (extraRpcs !== undefined) {
|
19
|
+
const rpcs = new Set(chain.rpc
|
20
|
+
.map(removeEndingSlash)
|
21
|
+
.filter((rpc) => !rpc.includes("${INFURA_API_KEY}")));
|
22
|
+
extraRpcs.forEach((rpc) => rpcs.add(removeEndingSlash(rpc)));
|
23
|
+
chain.rpc = Array.from(rpcs);
|
24
|
+
chain.rpcsScore = chain.rpc.map((url) => ({
|
25
|
+
url: url,
|
26
|
+
height: null,
|
27
|
+
latency: null,
|
28
|
+
}));
|
29
|
+
}
|
30
|
+
const chainSlug = chainIds_1.default[chain.chainId];
|
31
|
+
if (chainSlug !== undefined) {
|
32
|
+
const defiChain = chainTvls.find((c) => c.name.toLowerCase() === chainSlug);
|
33
|
+
return defiChain === undefined
|
34
|
+
? chain
|
35
|
+
: Object.assign(Object.assign({}, chain), { tvl: defiChain.tvl, chainSlug });
|
36
|
+
}
|
37
|
+
return chain;
|
38
|
+
}
|
39
|
+
exports.populateChain = populateChain;
|
package/package.json
ADDED
@@ -0,0 +1,34 @@
|
|
1
|
+
{
|
2
|
+
"name": "fizen-evm-networks",
|
3
|
+
"version": "1.0.0",
|
4
|
+
"description": "",
|
5
|
+
"scripts": {
|
6
|
+
"build": "tsc",
|
7
|
+
"test": "echo \"Error: no test specified\" && exit 1"
|
8
|
+
},
|
9
|
+
"repository": {
|
10
|
+
"type": "git",
|
11
|
+
"url": "git+https://github.com/sotanext-team/fizen-evm-networks.git"
|
12
|
+
},
|
13
|
+
"devDependencies": {
|
14
|
+
"@types/node": "^18.7.1",
|
15
|
+
"@types/node-fetch": "^2.6.2",
|
16
|
+
"typescript": "^4.7.4"
|
17
|
+
},
|
18
|
+
"author": "Nora",
|
19
|
+
"license": "ISC",
|
20
|
+
"bugs": {
|
21
|
+
"url": "https://github.com/sotanext-team/fizen-evm-networks/issues"
|
22
|
+
},
|
23
|
+
"homepage": "https://github.com/sotanext-team/fizen-evm-networks#readme",
|
24
|
+
"main": "lib/index.js",
|
25
|
+
"types": "lib/index.d.ts",
|
26
|
+
"files": [
|
27
|
+
"lib"
|
28
|
+
],
|
29
|
+
"dependencies": {
|
30
|
+
"axios": "^0.27.2",
|
31
|
+
"node-fetch": "^2.5.12",
|
32
|
+
"ts-node": "^10.9.1"
|
33
|
+
}
|
34
|
+
}
|