@strkfarm/sdk 1.0.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cli.js +636 -0
- package/dist/cli.mjs +613 -0
- package/dist/index.browser.global.js +33487 -0
- package/dist/index.d.ts +360 -0
- package/dist/index.js +1003 -0
- package/dist/index.mjs +948 -0
- package/package.json +58 -0
- package/src/cli.ts +160 -0
- package/src/data/pragma.abi.json +96 -0
- package/src/data/tokens.json +72 -0
- package/src/dataTypes/address.ts +38 -0
- package/src/dataTypes/bignumber.ts +53 -0
- package/src/dataTypes/index.ts +2 -0
- package/src/global.ts +73 -0
- package/src/index.browser.ts +6 -0
- package/src/index.ts +9 -0
- package/src/interfaces/common.ts +33 -0
- package/src/interfaces/index.ts +3 -0
- package/src/interfaces/initializable.ts +21 -0
- package/src/interfaces/lending.ts +75 -0
- package/src/modules/index.ts +3 -0
- package/src/modules/pragma.ts +22 -0
- package/src/modules/pricer.ts +125 -0
- package/src/modules/zkLend.ts +162 -0
- package/src/node/index.ts +1 -0
- package/src/node/pricer-redis.ts +71 -0
- package/src/notifs/index.ts +1 -0
- package/src/notifs/telegram.ts +48 -0
- package/src/strategies/autoCompounderStrk.ts +71 -0
- package/src/strategies/index.ts +1 -0
- package/src/utils/encrypt.ts +68 -0
- package/src/utils/index.ts +12 -0
- package/src/utils/store.ts +173 -0
package/package.json
ADDED
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@strkfarm/sdk",
|
|
3
|
+
"version": "1.0.6",
|
|
4
|
+
"description": "STRKFarm TS SDK (Meant for our internal use, but feel free to use it)",
|
|
5
|
+
"typings": "dist/index.d.ts",
|
|
6
|
+
"main": "dist/index.js",
|
|
7
|
+
"types": "dist/index.d.ts",
|
|
8
|
+
"bin": {
|
|
9
|
+
"accountsecure": "./dist/cli.js"
|
|
10
|
+
},
|
|
11
|
+
"exports": {
|
|
12
|
+
".": {
|
|
13
|
+
"import": "./dist/index.mjs",
|
|
14
|
+
"require": "./dist/index.js",
|
|
15
|
+
"browser": "./dist/index.global.js",
|
|
16
|
+
"types": "./dist/index.d.ts"
|
|
17
|
+
}
|
|
18
|
+
},
|
|
19
|
+
"files": [
|
|
20
|
+
"dist",
|
|
21
|
+
"src"
|
|
22
|
+
],
|
|
23
|
+
"scripts": {
|
|
24
|
+
"test": "jest",
|
|
25
|
+
"build": "tsup --clean && pnpm run build:esm && npm run build:dts && npm run build:iife && npm run build-cli",
|
|
26
|
+
"build:esm": "tsup --clean false --format esm --platform node",
|
|
27
|
+
"build-cli:esm": "tsup ./src/cli.ts --clean false --format esm --platform node",
|
|
28
|
+
"build-cli": "tsup ./src/cli.ts --clean false && pnpm run build-cli:esm",
|
|
29
|
+
"build:dts": "tsup --clean false --dts-only",
|
|
30
|
+
"build:iife": "tsup --clean false --format iife --platform browser"
|
|
31
|
+
},
|
|
32
|
+
"keywords": [],
|
|
33
|
+
"author": "",
|
|
34
|
+
"license": "ISC",
|
|
35
|
+
"devDependencies": {
|
|
36
|
+
"@types/jest": "^29.5.12",
|
|
37
|
+
"@types/node-telegram-bot-api": "^0.64.7",
|
|
38
|
+
"jest": "^29.7.0",
|
|
39
|
+
"jest-environment-jsdom": "^29.7.0",
|
|
40
|
+
"ts-jest": "^29.1.5",
|
|
41
|
+
"ts-node": "^10.9.2",
|
|
42
|
+
"tsup": "^8.1.0",
|
|
43
|
+
"typedoc": "^0.26.3",
|
|
44
|
+
"typescript": "^5.5.3"
|
|
45
|
+
},
|
|
46
|
+
"dependencies": {
|
|
47
|
+
"axios": "^1.7.2",
|
|
48
|
+
"bignumber.js": "4.0.4",
|
|
49
|
+
"browser-assert": "^1.2.1",
|
|
50
|
+
"chalk": "^4.1.2",
|
|
51
|
+
"commander": "^12.1.0",
|
|
52
|
+
"inquirer": "^10.1.2",
|
|
53
|
+
"node-telegram-bot-api": "^0.66.0",
|
|
54
|
+
"redis": "^4.7.0",
|
|
55
|
+
"starknet": "^6.11.0",
|
|
56
|
+
"winston": "^3.13.0"
|
|
57
|
+
}
|
|
58
|
+
}
|
package/src/cli.ts
ADDED
|
@@ -0,0 +1,160 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
import { Command } from 'commander';
|
|
4
|
+
import inquirer from 'inquirer';
|
|
5
|
+
import { Store, getDefaultStoreConfig } from './utils/store';
|
|
6
|
+
import chalk from 'chalk';
|
|
7
|
+
import { IConfig, Network } from './interfaces';
|
|
8
|
+
import { RpcProvider } from 'starknet';
|
|
9
|
+
|
|
10
|
+
const program = new Command();
|
|
11
|
+
|
|
12
|
+
const getConfig = (network: Network) => {
|
|
13
|
+
return {
|
|
14
|
+
provider: new RpcProvider({
|
|
15
|
+
nodeUrl: 'https://starknet-mainnet.public.blastapi.io',
|
|
16
|
+
}),
|
|
17
|
+
network: network,
|
|
18
|
+
stage: 'production',
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
async function createStore() {
|
|
23
|
+
console.log(chalk.blue.bold('Welcome to the Account Secure project for Starknet!'));
|
|
24
|
+
const networkAnswers = await (<any>inquirer).prompt([
|
|
25
|
+
{
|
|
26
|
+
type: 'list',
|
|
27
|
+
name: 'network',
|
|
28
|
+
message: chalk.yellow('What is the network?'),
|
|
29
|
+
choices: ['mainnet', 'sepolia', 'devnet'],
|
|
30
|
+
},
|
|
31
|
+
]);
|
|
32
|
+
const network: Network = networkAnswers.network as Network;
|
|
33
|
+
const defaultStoreConfig = getDefaultStoreConfig(network);
|
|
34
|
+
|
|
35
|
+
const storeConfigAnswers = await (<any>inquirer).prompt([
|
|
36
|
+
{
|
|
37
|
+
type: 'input',
|
|
38
|
+
name: 'secrets_folder',
|
|
39
|
+
message: chalk.yellow(`What is your secrets folder? (${defaultStoreConfig.SECRET_FILE_FOLDER})`),
|
|
40
|
+
default: defaultStoreConfig.SECRET_FILE_FOLDER,
|
|
41
|
+
validate: (input: string) => true,
|
|
42
|
+
},
|
|
43
|
+
{
|
|
44
|
+
type: 'input',
|
|
45
|
+
name: 'accounts_file',
|
|
46
|
+
message: chalk.yellow(`What is your accounts file? (${defaultStoreConfig.ACCOUNTS_FILE_NAME})`),
|
|
47
|
+
default: defaultStoreConfig.ACCOUNTS_FILE_NAME,
|
|
48
|
+
validate: (input: string) => true,
|
|
49
|
+
},
|
|
50
|
+
{
|
|
51
|
+
type: 'input',
|
|
52
|
+
name: 'encryption_password',
|
|
53
|
+
message: chalk.yellow(`What is your decryption password? (To generate one, press enter)`),
|
|
54
|
+
default: defaultStoreConfig.PASSWORD,
|
|
55
|
+
validate: (input: string) => true,
|
|
56
|
+
}
|
|
57
|
+
]);
|
|
58
|
+
|
|
59
|
+
const config = getConfig(network);
|
|
60
|
+
|
|
61
|
+
const secrets_folder = storeConfigAnswers.secrets_folder;
|
|
62
|
+
const accounts_file = storeConfigAnswers.accounts_file;
|
|
63
|
+
const encryption_password = storeConfigAnswers.encryption_password;
|
|
64
|
+
|
|
65
|
+
const store = new Store(config, {
|
|
66
|
+
SECRET_FILE_FOLDER: secrets_folder,
|
|
67
|
+
ACCOUNTS_FILE_NAME: accounts_file,
|
|
68
|
+
PASSWORD: storeConfigAnswers.encryption_password,
|
|
69
|
+
NETWORK: network,
|
|
70
|
+
});
|
|
71
|
+
|
|
72
|
+
if (defaultStoreConfig.PASSWORD === encryption_password) {
|
|
73
|
+
Store.logPassword(encryption_password);
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
return store;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
program
|
|
80
|
+
.version('1.0.0')
|
|
81
|
+
.description('Manage accounts securely on your disk with encryption');
|
|
82
|
+
|
|
83
|
+
program
|
|
84
|
+
.description('Add accounts securely to your disk with encryption')
|
|
85
|
+
.command('add-account')
|
|
86
|
+
.action(async (options) => {
|
|
87
|
+
const store = await createStore();
|
|
88
|
+
|
|
89
|
+
const existingAccountKeys = store.listAccounts();
|
|
90
|
+
|
|
91
|
+
const accountAnswers = await (<any>inquirer).prompt([
|
|
92
|
+
{
|
|
93
|
+
type: 'input',
|
|
94
|
+
name: 'account_key',
|
|
95
|
+
message: chalk.yellow(`Provide a unique account key`),
|
|
96
|
+
validate: (input: string) => (input.length > 0 && !existingAccountKeys.includes(input)) || 'Please enter a unique account key',
|
|
97
|
+
},
|
|
98
|
+
{
|
|
99
|
+
type: 'input',
|
|
100
|
+
name: 'address',
|
|
101
|
+
message: chalk.yellow(`What is your account address?`),
|
|
102
|
+
validate: (input: string) => input.length > 0 || 'Please enter a valid address',
|
|
103
|
+
},
|
|
104
|
+
{
|
|
105
|
+
type: 'input',
|
|
106
|
+
name: 'pk',
|
|
107
|
+
message: chalk.yellow(`What is your account private key?`),
|
|
108
|
+
validate: (input: string) => input.length > 0 || 'Please enter a valid pk',
|
|
109
|
+
},
|
|
110
|
+
]);
|
|
111
|
+
|
|
112
|
+
const address = accountAnswers.address;
|
|
113
|
+
const pk = accountAnswers.pk;
|
|
114
|
+
const account_key = accountAnswers.account_key;
|
|
115
|
+
|
|
116
|
+
store.addAccount(account_key, address, pk);
|
|
117
|
+
|
|
118
|
+
console.log(`${chalk.blue("Account added:")} ${account_key} to network: ${store.config.network}`);
|
|
119
|
+
});
|
|
120
|
+
|
|
121
|
+
program
|
|
122
|
+
.description('List account names of a network')
|
|
123
|
+
.command('list-accounts')
|
|
124
|
+
.action(async (options) => {
|
|
125
|
+
const store = await createStore();
|
|
126
|
+
const accounts = store.listAccounts();
|
|
127
|
+
console.log(`${chalk.blue("Account keys:")} ${accounts.join(', ')}`);
|
|
128
|
+
})
|
|
129
|
+
|
|
130
|
+
program
|
|
131
|
+
.description('List account names of a network')
|
|
132
|
+
.command('get-account')
|
|
133
|
+
.action(async (options) => {
|
|
134
|
+
const store = await createStore();
|
|
135
|
+
const existingAccountKeys = store.listAccounts();
|
|
136
|
+
const accountAnswers = await (<any>inquirer).prompt([
|
|
137
|
+
{
|
|
138
|
+
type: 'input',
|
|
139
|
+
name: 'account_key',
|
|
140
|
+
message: chalk.yellow(`Provide a unique account key`),
|
|
141
|
+
validate: (input: string) => (input.length > 0 && existingAccountKeys.includes(input)) || 'Please enter a value account key',
|
|
142
|
+
},
|
|
143
|
+
]);
|
|
144
|
+
|
|
145
|
+
const account = store.getAccount(accountAnswers.account_key);
|
|
146
|
+
console.log(`${chalk.blue("Account Address:")} ${account.address}`);
|
|
147
|
+
})
|
|
148
|
+
|
|
149
|
+
// Default action if no command is provided
|
|
150
|
+
program
|
|
151
|
+
.action(() => {
|
|
152
|
+
program.help(); // Show help if no command is provided
|
|
153
|
+
});
|
|
154
|
+
|
|
155
|
+
program.parse(process.argv);
|
|
156
|
+
|
|
157
|
+
// Show help if no command is provided
|
|
158
|
+
if (!process.argv.slice(2).length) {
|
|
159
|
+
program.outputHelp();
|
|
160
|
+
}
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
[
|
|
2
|
+
{
|
|
3
|
+
"data": [
|
|
4
|
+
{
|
|
5
|
+
"name": "previousOwner",
|
|
6
|
+
"type": "felt"
|
|
7
|
+
},
|
|
8
|
+
{
|
|
9
|
+
"name": "newOwner",
|
|
10
|
+
"type": "felt"
|
|
11
|
+
}
|
|
12
|
+
],
|
|
13
|
+
"keys": [],
|
|
14
|
+
"name": "OwnershipTransferred",
|
|
15
|
+
"type": "event"
|
|
16
|
+
},
|
|
17
|
+
{
|
|
18
|
+
"data": [
|
|
19
|
+
{
|
|
20
|
+
"name": "token",
|
|
21
|
+
"type": "felt"
|
|
22
|
+
},
|
|
23
|
+
{
|
|
24
|
+
"name": "source",
|
|
25
|
+
"type": "felt"
|
|
26
|
+
}
|
|
27
|
+
],
|
|
28
|
+
"keys": [],
|
|
29
|
+
"name": "TokenSourceChanged",
|
|
30
|
+
"type": "event"
|
|
31
|
+
},
|
|
32
|
+
{
|
|
33
|
+
"name": "constructor",
|
|
34
|
+
"type": "constructor",
|
|
35
|
+
"inputs": [
|
|
36
|
+
{
|
|
37
|
+
"name": "owner",
|
|
38
|
+
"type": "felt"
|
|
39
|
+
}
|
|
40
|
+
],
|
|
41
|
+
"outputs": []
|
|
42
|
+
},
|
|
43
|
+
{
|
|
44
|
+
"name": "get_price",
|
|
45
|
+
"type": "function",
|
|
46
|
+
"inputs": [
|
|
47
|
+
{
|
|
48
|
+
"name": "token",
|
|
49
|
+
"type": "felt"
|
|
50
|
+
}
|
|
51
|
+
],
|
|
52
|
+
"outputs": [
|
|
53
|
+
{
|
|
54
|
+
"name": "price",
|
|
55
|
+
"type": "felt"
|
|
56
|
+
}
|
|
57
|
+
],
|
|
58
|
+
"stateMutability": "view"
|
|
59
|
+
},
|
|
60
|
+
{
|
|
61
|
+
"name": "get_price_with_time",
|
|
62
|
+
"type": "function",
|
|
63
|
+
"inputs": [
|
|
64
|
+
{
|
|
65
|
+
"name": "token",
|
|
66
|
+
"type": "felt"
|
|
67
|
+
}
|
|
68
|
+
],
|
|
69
|
+
"outputs": [
|
|
70
|
+
{
|
|
71
|
+
"name": "price",
|
|
72
|
+
"type": "felt"
|
|
73
|
+
},
|
|
74
|
+
{
|
|
75
|
+
"name": "update_time",
|
|
76
|
+
"type": "felt"
|
|
77
|
+
}
|
|
78
|
+
],
|
|
79
|
+
"stateMutability": "view"
|
|
80
|
+
},
|
|
81
|
+
{
|
|
82
|
+
"name": "set_token_source",
|
|
83
|
+
"type": "function",
|
|
84
|
+
"inputs": [
|
|
85
|
+
{
|
|
86
|
+
"name": "token",
|
|
87
|
+
"type": "felt"
|
|
88
|
+
},
|
|
89
|
+
{
|
|
90
|
+
"name": "source",
|
|
91
|
+
"type": "felt"
|
|
92
|
+
}
|
|
93
|
+
],
|
|
94
|
+
"outputs": []
|
|
95
|
+
}
|
|
96
|
+
]
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
[
|
|
2
|
+
{
|
|
3
|
+
"name": "Ether",
|
|
4
|
+
"symbol": "ETH",
|
|
5
|
+
"address": "0x049d36570d4e46f48e99674bd3fcc84644ddd6b96f7c741b1562b82f9e004dc7",
|
|
6
|
+
"decimals": 18,
|
|
7
|
+
"pricerKey": "ETH-USDT"
|
|
8
|
+
},
|
|
9
|
+
{
|
|
10
|
+
"name": "USD Coin",
|
|
11
|
+
"symbol": "USDC",
|
|
12
|
+
"address": "0x053c91253bc9682c04929ca02ed00b3e423f6710d2ee7e0d5ebb06f3ecf368a8",
|
|
13
|
+
"decimals": 6,
|
|
14
|
+
"pricerKey": "USDC-USDT"
|
|
15
|
+
},
|
|
16
|
+
{
|
|
17
|
+
"name": "Wrapped BTC",
|
|
18
|
+
"symbol": "WBTC",
|
|
19
|
+
"address": "0x03fe2b97c1fd336e750087d68b9b867997fd64a2661ff3ca5a7c771641e8e7ac",
|
|
20
|
+
"decimals": 8,
|
|
21
|
+
"pricerKey": "WBTC-USDT"
|
|
22
|
+
},
|
|
23
|
+
{
|
|
24
|
+
"name": "Tether USD",
|
|
25
|
+
"symbol": "USDT",
|
|
26
|
+
"address": "0x068f5c6a61780768455de69077e07e89787839bf8166decfbf92b645209c0fb8",
|
|
27
|
+
"decimals": 6,
|
|
28
|
+
"pricerKey": "USDT-USDT"
|
|
29
|
+
},
|
|
30
|
+
{
|
|
31
|
+
"name": "Dai Stablecoin",
|
|
32
|
+
"symbol": "DAIv0",
|
|
33
|
+
"address": "",
|
|
34
|
+
"decimals": 18,
|
|
35
|
+
"pricerKey": "DAI-USDT"
|
|
36
|
+
},
|
|
37
|
+
{
|
|
38
|
+
"name": "Starknet Wrapped Staked Ether",
|
|
39
|
+
"symbol": "wstETH",
|
|
40
|
+
"address": "0x042b8f0484674ca266ac5d08e4ac6a3fe65bd3129795def2dca5c34ecc5f96d2",
|
|
41
|
+
"decimals": 18,
|
|
42
|
+
"pricerKey": "wstETH-USDT"
|
|
43
|
+
},
|
|
44
|
+
{
|
|
45
|
+
"name": "Starknet Token",
|
|
46
|
+
"symbol": "STRK",
|
|
47
|
+
"address": "0x04718f5a0fc34cc1af16a1cdee98ffb20c31f5cd61d6ab07201858f4287c938d",
|
|
48
|
+
"decimals": 18,
|
|
49
|
+
"pricerKey": "STRK-USDT"
|
|
50
|
+
},
|
|
51
|
+
{
|
|
52
|
+
"name": "zkLend Token",
|
|
53
|
+
"symbol": "ZEND",
|
|
54
|
+
"address": "",
|
|
55
|
+
"decimals": 18,
|
|
56
|
+
"pricerKey": "ZEND-USDT"
|
|
57
|
+
},
|
|
58
|
+
{
|
|
59
|
+
"name": "Dai Stablecoin",
|
|
60
|
+
"symbol": "DAI",
|
|
61
|
+
"address": "",
|
|
62
|
+
"decimals": 18,
|
|
63
|
+
"pricerKey": "DAI-USDT"
|
|
64
|
+
},
|
|
65
|
+
{
|
|
66
|
+
"name": "Ekubo Protocol",
|
|
67
|
+
"symbol": "EKUBO",
|
|
68
|
+
"address": "",
|
|
69
|
+
"decimals": 18,
|
|
70
|
+
"pricerKey": "DAI-USDT"
|
|
71
|
+
}
|
|
72
|
+
]
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import { num } from "starknet";
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* A simple wrapper around a contract address that is universally comparable
|
|
5
|
+
* - Helps avoid padding issues
|
|
6
|
+
*/
|
|
7
|
+
export class ContractAddr {
|
|
8
|
+
readonly address: string;
|
|
9
|
+
|
|
10
|
+
constructor(address: string) {
|
|
11
|
+
this.address = ContractAddr.standardise(address);
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
static from(address: string) {
|
|
15
|
+
return new ContractAddr(address);
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
eq(other: ContractAddr) {
|
|
19
|
+
return this.address === other.address;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
eqString(other: string) {
|
|
23
|
+
return this.address === ContractAddr.standardise(other);
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
static standardise(address: string | bigint) {
|
|
27
|
+
let _a = address;
|
|
28
|
+
if (!address) {
|
|
29
|
+
_a = "0";
|
|
30
|
+
}
|
|
31
|
+
const a = num.getHexString(num.getDecimalString(_a.toString()));
|
|
32
|
+
return a;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
static eqString(a: string, b: string) {
|
|
36
|
+
return ContractAddr.standardise(a) === ContractAddr.standardise(b);
|
|
37
|
+
}
|
|
38
|
+
}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import BigNumber from "bignumber.js";
|
|
2
|
+
// import { inspect } from 'util';
|
|
3
|
+
// const customInspectSymbol = inspect.custom || Symbol.for('nodejs.util.inspect.custom');
|
|
4
|
+
|
|
5
|
+
function isNode() {
|
|
6
|
+
// Check for the presence of the `window` object, which is undefined in Node.js
|
|
7
|
+
return typeof window === 'undefined';
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
export class Web3Number extends BigNumber {
|
|
11
|
+
decimals: number;
|
|
12
|
+
|
|
13
|
+
constructor(value: string | number, decimals: number) {
|
|
14
|
+
super(value);
|
|
15
|
+
this.decimals = decimals;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
static fromWei(weiNumber: string | number, decimals: number) {
|
|
19
|
+
const bn = (new Web3Number(weiNumber, decimals)).dividedBy(10 ** decimals)
|
|
20
|
+
return new Web3Number(bn.toString(), decimals);
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
toWei() {
|
|
24
|
+
return this.mul(10 ** this.decimals).toFixed(0);
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
multipliedBy(value: string | number) {
|
|
28
|
+
return new Web3Number(this.mul(value).toString(), this.decimals);
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
dividedBy(value: string | number) {
|
|
32
|
+
return new Web3Number(this.div(value).toString(), this.decimals);
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
plus(value: string | number) {
|
|
36
|
+
return new Web3Number(this.add(value).toString(), this.decimals);
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
minus(n: number | string, base?: number): Web3Number {
|
|
40
|
+
return new Web3Number(super.minus(n, base).toString(), this.decimals);
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
toString(base?: number | undefined): string {
|
|
44
|
+
return super.toString(base);
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
// [customInspectSymbol](depth: any, inspectOptions: any, inspect: any) {
|
|
48
|
+
// return this.toString();
|
|
49
|
+
// }
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
BigNumber.config({ DECIMAL_PLACES: 18 })
|
|
53
|
+
Web3Number.config({ DECIMAL_PLACES: 18 })
|
package/src/global.ts
ADDED
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
import { TokenInfo } from './interfaces';
|
|
2
|
+
import TOKENS from '@/data/tokens.json';
|
|
3
|
+
|
|
4
|
+
const colors = {
|
|
5
|
+
error: 'red',
|
|
6
|
+
warn: 'yellow',
|
|
7
|
+
info: 'blue',
|
|
8
|
+
verbose: 'white',
|
|
9
|
+
debug: 'white',
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
// Add custom colors to Winston
|
|
13
|
+
// winston.addColors(colors);
|
|
14
|
+
|
|
15
|
+
// export const logger = createLogger({
|
|
16
|
+
// level: 'verbose', // Set the minimum logging level
|
|
17
|
+
// format: format.combine(
|
|
18
|
+
// format.colorize({ all: true }), // Apply custom colors
|
|
19
|
+
// format.timestamp({ format: 'YYYY-MM-DD HH:mm:ss' }), // Add timestamp to log messages
|
|
20
|
+
// format.printf(({ timestamp, level, message }) => {
|
|
21
|
+
// return `${timestamp} ${level}: ${message}`;
|
|
22
|
+
// })
|
|
23
|
+
// ),
|
|
24
|
+
// transports: [
|
|
25
|
+
// // new transports.Console() // Output logs to the console
|
|
26
|
+
// ]
|
|
27
|
+
// });
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
export const logger = {
|
|
31
|
+
...console,
|
|
32
|
+
verbose(message: string) {
|
|
33
|
+
console.log(`[VERBOSE] ${message}`);
|
|
34
|
+
}
|
|
35
|
+
};
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
export class FatalError extends Error {
|
|
39
|
+
constructor(message: string, err?: Error) {
|
|
40
|
+
super(message);
|
|
41
|
+
logger.error(message);
|
|
42
|
+
if (err)
|
|
43
|
+
logger.error(err.message);
|
|
44
|
+
this.name = "FatalError";
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
/** Contains globally useful functions.
|
|
48
|
+
* - fatalError: Things to do when a fatal error occurs
|
|
49
|
+
*/
|
|
50
|
+
export class Global {
|
|
51
|
+
static fatalError(message: string, err?: Error) {
|
|
52
|
+
logger.error(message);
|
|
53
|
+
console.error(message, err);
|
|
54
|
+
if (err)
|
|
55
|
+
console.error(err);
|
|
56
|
+
process.exit(1);
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
static httpError(url: string, err: Error, message?: string) {
|
|
60
|
+
logger.error(`${url}: ${message}`);
|
|
61
|
+
console.error(err);
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
static async getTokens(): Promise<TokenInfo[]> {
|
|
65
|
+
return TOKENS;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
static assert(condition: any, message: string) {
|
|
69
|
+
if (!condition) {
|
|
70
|
+
throw new FatalError(message);
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
}
|
package/src/index.ts
ADDED
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
// contains all modules that can run in node
|
|
2
|
+
export * from './modules';
|
|
3
|
+
export * from './interfaces';
|
|
4
|
+
export * from './dataTypes';
|
|
5
|
+
export * from './global';
|
|
6
|
+
export * from './strategies';
|
|
7
|
+
export * from './notifs';
|
|
8
|
+
export * from './utils';
|
|
9
|
+
export * from './node';
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { BlockIdentifier, RpcProvider } from "starknet"
|
|
2
|
+
|
|
3
|
+
export interface TokenInfo {
|
|
4
|
+
name: string,
|
|
5
|
+
symbol: string,
|
|
6
|
+
address: string,
|
|
7
|
+
decimals: number,
|
|
8
|
+
pricerKey?: string
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
export enum Network {
|
|
12
|
+
mainnet = "mainnet",
|
|
13
|
+
sepolia = "sepolia",
|
|
14
|
+
devnet = "devnet"
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
export interface IConfig {
|
|
18
|
+
provider: RpcProvider,
|
|
19
|
+
network: Network,
|
|
20
|
+
stage: 'production' | 'staging',
|
|
21
|
+
heartbeatUrl?: string
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
export function getMainnetConfig(rpcUrl = "https://starknet-mainnet.public.blastapi.io", blockIdentifier: BlockIdentifier = 'pending'): IConfig {
|
|
25
|
+
return {
|
|
26
|
+
provider: new RpcProvider({
|
|
27
|
+
nodeUrl: rpcUrl,
|
|
28
|
+
blockIdentifier: blockIdentifier
|
|
29
|
+
}),
|
|
30
|
+
stage: "production",
|
|
31
|
+
network: Network.mainnet
|
|
32
|
+
}
|
|
33
|
+
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
export abstract class Initializable {
|
|
2
|
+
protected initialized: boolean;
|
|
3
|
+
|
|
4
|
+
constructor() {
|
|
5
|
+
this.initialized = false;
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
abstract init(): Promise<void>;
|
|
9
|
+
|
|
10
|
+
async waitForInitilisation() {
|
|
11
|
+
return new Promise<void>((resolve, reject) => {
|
|
12
|
+
const interval = setInterval(() => {
|
|
13
|
+
if (this.initialized) {
|
|
14
|
+
console.log('Initialised');
|
|
15
|
+
clearInterval(interval);
|
|
16
|
+
resolve();
|
|
17
|
+
}
|
|
18
|
+
}, 1000);
|
|
19
|
+
});
|
|
20
|
+
}
|
|
21
|
+
}
|