@mainnet-cash/postgresql-storage 2.1.0-alpha.5

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.
Files changed (44) hide show
  1. package/README.md +3 -0
  2. package/dist/module/SqlProvider.d.ts +30 -0
  3. package/dist/module/SqlProvider.js +159 -0
  4. package/dist/module/SqlProvider.js.map +1 -0
  5. package/dist/module/index.d.ts +2 -0
  6. package/dist/module/index.js +3 -0
  7. package/dist/module/index.js.map +1 -0
  8. package/dist/module/util.d.ts +7 -0
  9. package/dist/module/util.js +24 -0
  10. package/dist/module/util.js.map +1 -0
  11. package/dist/module/webhook/Webhook.d.ts +35 -0
  12. package/dist/module/webhook/Webhook.js +77 -0
  13. package/dist/module/webhook/Webhook.js.map +1 -0
  14. package/dist/module/webhook/WebhookBch.d.ts +13 -0
  15. package/dist/module/webhook/WebhookBch.js +141 -0
  16. package/dist/module/webhook/WebhookBch.js.map +1 -0
  17. package/dist/module/webhook/WebhookWorker.d.ts +22 -0
  18. package/dist/module/webhook/WebhookWorker.js +94 -0
  19. package/dist/module/webhook/WebhookWorker.js.map +1 -0
  20. package/dist/module/webhook/index.d.ts +4 -0
  21. package/dist/module/webhook/index.js +5 -0
  22. package/dist/module/webhook/index.js.map +1 -0
  23. package/dist/module/webhook/interface.d.ts +7 -0
  24. package/dist/module/webhook/interface.js +2 -0
  25. package/dist/module/webhook/interface.js.map +1 -0
  26. package/dist/tsconfig.browser.tsbuildinfo +1 -0
  27. package/package.json +34 -0
  28. package/src/SqlProvider.test.ts +264 -0
  29. package/src/SqlProvider.ts +233 -0
  30. package/src/Wallet.test.ts +571 -0
  31. package/src/createWallet.test.ts +158 -0
  32. package/src/index.test.ts +67 -0
  33. package/src/index.ts +2 -0
  34. package/src/util.ts +30 -0
  35. package/src/webhook/Webhook.test.ts +9 -0
  36. package/src/webhook/Webhook.ts +99 -0
  37. package/src/webhook/WebhookBch.test.ts +323 -0
  38. package/src/webhook/WebhookBch.ts +198 -0
  39. package/src/webhook/WebhookWorker.test.ts +94 -0
  40. package/src/webhook/WebhookWorker.ts +119 -0
  41. package/src/webhook/index.ts +4 -0
  42. package/src/webhook/interface.ts +7 -0
  43. package/tsconfig.browser.json +6 -0
  44. package/tsconfig.json +28 -0
@@ -0,0 +1,233 @@
1
+ import { StorageProvider, WalletI, TxI } from "mainnet-js";
2
+ import { RegisterWebhookParams } from "./webhook/interface.js";
3
+ import { getSslConfig } from "./util.js";
4
+ import parseDbUrl from "parse-database-url";
5
+ import pg from "pg";
6
+ import format from "pg-format";
7
+ import { Webhook, WebhookRecurrence, WebhookType } from "./webhook/index.js";
8
+
9
+ export default class SqlProvider implements StorageProvider {
10
+ private db;
11
+ private config;
12
+ private info;
13
+ private formatter;
14
+ private walletTable: string;
15
+ private webhookTable: string = "webhook";
16
+ private isInit = false;
17
+
18
+ public constructor(walletTable?: string) {
19
+ this.walletTable = walletTable ? walletTable : "wallet";
20
+ if (!process.env.DATABASE_URL) {
21
+ throw new Error(
22
+ "Named wallets and webhooks require a postgres DATABASE_URL environment variable to be set"
23
+ );
24
+ }
25
+ let dbConfig = parseDbUrl(process.env.DATABASE_URL);
26
+ let ssl = getSslConfig();
27
+ if (ssl) {
28
+ dbConfig.ssl = ssl;
29
+ }
30
+ this.config = dbConfig;
31
+
32
+ const Pool = pg.Pool;
33
+ this.db = new Pool(dbConfig);
34
+ this.formatter = format;
35
+ }
36
+
37
+ public getConfig() {
38
+ return this.config;
39
+ }
40
+
41
+ public async init(): Promise<StorageProvider> {
42
+ if (!this.isInit) {
43
+ this.isInit = true;
44
+ await this.db;
45
+ await this.formatter;
46
+
47
+ let createWalletTable = this.formatter(
48
+ "CREATE TABLE IF NOT EXISTS %I (id SERIAL, name TEXT PRIMARY KEY, wallet TEXT );",
49
+ this.walletTable
50
+ );
51
+ const resWallet = await this.db.query(createWalletTable);
52
+
53
+ let createWebhookTable = this.formatter(
54
+ "CREATE TABLE IF NOT EXISTS %I (" +
55
+ "id SERIAL PRIMARY KEY," +
56
+ "cashaddr TEXT," +
57
+ "type TEXT," +
58
+ "recurrence TEXT," +
59
+ "url TEXT," +
60
+ "status TEXT," +
61
+ "tx_seen JSON," +
62
+ "last_height INTEGER," +
63
+ "expires_at TIMESTAMPTZ" +
64
+ ");",
65
+ this.webhookTable
66
+ );
67
+ const resWebhook = await this.db.query(createWebhookTable);
68
+
69
+ if (!resWallet || !resWebhook)
70
+ throw new Error("Failed to init SqlProvider");
71
+ }
72
+
73
+ return this;
74
+ }
75
+
76
+ public async close(): Promise<StorageProvider> {
77
+ await this.db.end();
78
+ return this;
79
+ }
80
+
81
+ public getInfo(): string {
82
+ return this.info;
83
+ }
84
+
85
+ public async addWallet(name: string, walletId: string): Promise<boolean> {
86
+ let text = this.formatter(
87
+ "INSERT into %I (name,wallet) VALUES ($1, $2);",
88
+ this.walletTable
89
+ );
90
+ return await this.db.query(text, [name, walletId]);
91
+ }
92
+
93
+ public async getWallets(): Promise<Array<WalletI>> {
94
+ let text = this.formatter("SELECT * FROM %I;", this.walletTable);
95
+ let result = await this.db.query(text);
96
+ if (result) {
97
+ const WalletArray: WalletI[] = await Promise.all(
98
+ result.rows.map(async (obj: WalletI) => {
99
+ return obj;
100
+ })
101
+ );
102
+ return WalletArray;
103
+ } else {
104
+ return [];
105
+ }
106
+ }
107
+
108
+ public async getWallet(name: string): Promise<WalletI | undefined> {
109
+ let text = this.formatter(
110
+ "SELECT * FROM %I WHERE name = $1;",
111
+ this.walletTable
112
+ );
113
+ let result = await this.db.query(text, [name]);
114
+ let w = result.rows[0];
115
+ return w;
116
+ }
117
+
118
+ public async updateWallet(name: string, walletId: string): Promise<void> {
119
+ let text = this.formatter(
120
+ "UPDATE %I SET wallet = $1 WHERE name = $2;",
121
+ this.walletTable
122
+ );
123
+ await this.db.query(text, [walletId, name]);
124
+ }
125
+
126
+ public async walletExists(name: string): Promise<boolean> {
127
+ return (await this.getWallet(name)) !== undefined;
128
+ }
129
+
130
+ public async webhookFromDb(hook: Webhook) {
131
+ const { WebhookBch } = await import("./webhook/WebhookBch.js");
132
+ return new WebhookBch(hook);
133
+ }
134
+
135
+ public async addWebhook(params: RegisterWebhookParams): Promise<Webhook> {
136
+ // init db if it was not, useful for external api calls
137
+ await this.init();
138
+
139
+ params.type = params.type || WebhookType.transactionInOut;
140
+ params.recurrence = params.recurrence || WebhookRecurrence.once;
141
+ const expireTimeout =
142
+ Number(process.env.WEBHOOK_EXPIRE_TIMEOUT_SECONDS) || 86400;
143
+ params.duration_sec = params.duration_sec || expireTimeout;
144
+ params.duration_sec =
145
+ params.duration_sec > expireTimeout ? expireTimeout : params.duration_sec;
146
+
147
+ const expires_at = new Date(
148
+ new Date().getTime() + params.duration_sec * 1000
149
+ );
150
+ let text = this.formatter(
151
+ "INSERT into %I (cashaddr,type,recurrence,url,status,tx_seen,last_height,expires_at) VALUES ($1, $2, $3, $4, $5, $6, $7, $8) RETURNING *;",
152
+ this.webhookTable
153
+ );
154
+
155
+ const result = await this.db.query(text, [
156
+ params.cashaddr,
157
+ params.type,
158
+ params.recurrence,
159
+ params.url,
160
+ "",
161
+ "[]",
162
+ 0,
163
+ expires_at.toISOString(),
164
+ ]);
165
+ const hook = await this.webhookFromDb(result.rows[0]);
166
+ hook.db = this;
167
+ return hook;
168
+ }
169
+
170
+ public async getWebhooks(): Promise<Array<Webhook>> {
171
+ let text = this.formatter("SELECT * FROM %I;", this.webhookTable);
172
+ let result = await this.db.query(text);
173
+ if (result) {
174
+ const WebhookArray: Webhook[] = await Promise.all(
175
+ result.rows.map(async (obj: any) => {
176
+ obj = await this.webhookFromDb(obj);
177
+ obj.db = this;
178
+ return obj;
179
+ })
180
+ );
181
+ return WebhookArray;
182
+ } else {
183
+ return [];
184
+ }
185
+ }
186
+
187
+ public async getWebhook(id: number): Promise<Webhook | undefined> {
188
+ const text = this.formatter(
189
+ "SELECT * FROM %I WHERE id = $1;",
190
+ this.webhookTable
191
+ );
192
+ const result = await this.db.query(text, [id]);
193
+ let hook = result.rows[0];
194
+ if (hook) {
195
+ hook = this.webhookFromDb(hook);
196
+ hook.db = this;
197
+ }
198
+ return hook;
199
+ }
200
+
201
+ public async setWebhookStatus(id: number, status: string): Promise<void> {
202
+ let text = this.formatter(
203
+ "UPDATE %I SET status = $1 WHERE id = $2;",
204
+ this.webhookTable
205
+ );
206
+ await this.db.query(text, [status, id]);
207
+ }
208
+
209
+ public async setWebhookSeenTxLastHeight(
210
+ id: number,
211
+ tx_seen: Array<TxI>,
212
+ last_height: number
213
+ ): Promise<void> {
214
+ let text = this.formatter(
215
+ "UPDATE %I SET tx_seen = $1, last_height = $2 WHERE id = $3;",
216
+ this.webhookTable
217
+ );
218
+ await this.db.query(text, [JSON.stringify(tx_seen), last_height, id]);
219
+ }
220
+
221
+ public async deleteWebhook(id: number): Promise<void> {
222
+ let text = this.formatter(
223
+ "DELETE FROM %I WHERE id = $1;",
224
+ this.webhookTable
225
+ );
226
+ await this.db.query(text, [id]);
227
+ }
228
+
229
+ public async clearWebhooks(): Promise<void> {
230
+ let text = this.formatter("DELETE FROM %I;", this.webhookTable);
231
+ await this.db.query(text);
232
+ }
233
+ }