@mainnet-cash/postgresql-storage 4.0.0-next.0 → 4.0.0-next.11
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/module/SqlProvider.d.ts +2 -2
- package/dist/module/SqlProvider.js +1 -1
- package/dist/module/SqlProvider.js.map +1 -1
- package/dist/module/webhook/Webhook.d.ts +1 -7
- package/dist/module/webhook/Webhook.js +8 -41
- package/dist/module/webhook/Webhook.js.map +1 -1
- package/dist/module/webhook/WebhookBch.d.ts +1 -2
- package/dist/module/webhook/WebhookBch.js +2 -1
- package/dist/module/webhook/WebhookBch.js.map +1 -1
- package/dist/module/webhook/WebhookMock.d.ts +6 -0
- package/dist/module/webhook/WebhookMock.js +26 -0
- package/dist/module/webhook/WebhookMock.js.map +1 -0
- package/dist/module/webhook/WebhookWorker.d.ts +1 -1
- package/dist/module/webhook/WebhookWorker.js.map +1 -1
- package/dist/module/webhook/index.d.ts +2 -2
- package/dist/module/webhook/index.js +2 -2
- package/dist/module/webhook/index.js.map +1 -1
- package/package.json +17 -11
- package/dist/tsconfig.browser.tsbuildinfo +0 -1
- package/src/SqlProvider.test.ts +0 -265
- package/src/SqlProvider.ts +0 -233
- package/src/Wallet.test.ts +0 -537
- package/src/createWallet.test.ts +0 -168
- package/src/index.test.ts +0 -93
- package/src/index.ts +0 -2
- package/src/util.ts +0 -32
- package/src/webhook/Webhook.test.ts +0 -9
- package/src/webhook/Webhook.ts +0 -99
- package/src/webhook/WebhookBch.test.ts +0 -315
- package/src/webhook/WebhookBch.ts +0 -191
- package/src/webhook/WebhookWorker.test.ts +0 -94
- package/src/webhook/WebhookWorker.ts +0 -119
- package/src/webhook/index.ts +0 -4
- package/src/webhook/interface.ts +0 -7
- package/tsconfig.browser.json +0 -6
- package/tsconfig.json +0 -32
package/src/index.test.ts
DELETED
|
@@ -1,93 +0,0 @@
|
|
|
1
|
-
import {
|
|
2
|
-
BaseWallet,
|
|
3
|
-
binToHex,
|
|
4
|
-
RegTestWallet,
|
|
5
|
-
TestNetWallet,
|
|
6
|
-
Wallet,
|
|
7
|
-
WalletTypeEnum,
|
|
8
|
-
} from "mainnet-js";
|
|
9
|
-
import { default as SqlProvider } from "./SqlProvider";
|
|
10
|
-
|
|
11
|
-
BaseWallet.StorageProvider = SqlProvider;
|
|
12
|
-
|
|
13
|
-
/**
|
|
14
|
-
* @jest-environment jsdom
|
|
15
|
-
*/
|
|
16
|
-
test("Store and retrieve a Regtest wallet", async () => {
|
|
17
|
-
let w1 = await RegTestWallet.named("Basic Regtest");
|
|
18
|
-
expect(w1.name).toBe("Basic Regtest");
|
|
19
|
-
expect(w1.network).toBe("regtest");
|
|
20
|
-
expect(w1.walletType).toBe("seed");
|
|
21
|
-
expect(w1.toString()).toBe("named:regtest:Basic Regtest");
|
|
22
|
-
expect(w1.toDbString()).toMatch(/seed:regtest:(\w+\s){11}\w+/);
|
|
23
|
-
let w1Again = await RegTestWallet.named("Basic Regtest");
|
|
24
|
-
|
|
25
|
-
expect(w1.name).toBe(w1Again.name);
|
|
26
|
-
expect(w1.network).toBe(w1Again.network);
|
|
27
|
-
expect(w1.cashaddr).toBe(w1Again.cashaddr);
|
|
28
|
-
expect(w1.privateKeyWif).toBe(w1Again.privateKeyWif);
|
|
29
|
-
expect(w1.toString()).toBe(w1Again.toString());
|
|
30
|
-
});
|
|
31
|
-
|
|
32
|
-
test("Store and retrieve a TestNet wallet", async () => {
|
|
33
|
-
let w1 = await TestNetWallet.named("Basic Testnet Wallet", "db-test");
|
|
34
|
-
expect(w1.name).toBe("Basic Testnet Wallet");
|
|
35
|
-
expect(w1.network).toBe("testnet");
|
|
36
|
-
expect(w1.walletType).toBe("seed");
|
|
37
|
-
expect(w1.toDbString()).toMatch(/seed:testnet:(\w+\s){11}\w+/);
|
|
38
|
-
expect(w1.toString()).toBe("named:testnet:Basic Testnet Wallet");
|
|
39
|
-
let w1Again = await TestNetWallet.named("Basic Testnet Wallet", "db-test");
|
|
40
|
-
|
|
41
|
-
expect(w1.name).toBe(w1Again.name);
|
|
42
|
-
expect(w1.network).toBe(w1Again.network);
|
|
43
|
-
expect(w1.cashaddr).toBe(w1Again.cashaddr);
|
|
44
|
-
expect(w1.privateKeyWif).toBe(w1Again.privateKeyWif);
|
|
45
|
-
expect(w1.toString()).toBe(w1Again.toString());
|
|
46
|
-
});
|
|
47
|
-
|
|
48
|
-
test("Store and retrieve a private key wallet", async () => {
|
|
49
|
-
const privkey = "00".repeat(31) + "01";
|
|
50
|
-
|
|
51
|
-
let w1 = await Wallet.fromPrivateKey(privkey);
|
|
52
|
-
expect(w1.network).toBe("mainnet");
|
|
53
|
-
expect(w1.walletType).toBe(WalletTypeEnum.PrivateKey);
|
|
54
|
-
expect(w1.toDbString()).toBe(`privkey:mainnet:${privkey}`);
|
|
55
|
-
expect(w1.toString()).toBe(`privkey:mainnet:${privkey}`);
|
|
56
|
-
|
|
57
|
-
let w1Again = await Wallet.fromId(w1.toDbString());
|
|
58
|
-
|
|
59
|
-
expect(w1.name).toBe(w1Again.name);
|
|
60
|
-
expect(w1.network).toBe(w1Again.network);
|
|
61
|
-
expect(w1.cashaddr).toBe(w1Again.cashaddr);
|
|
62
|
-
expect(binToHex(w1.privateKey)).toBe(binToHex(w1Again.privateKey));
|
|
63
|
-
expect(w1.privateKeyWif).toBe(w1Again.privateKeyWif);
|
|
64
|
-
expect(w1.toString()).toBe(w1Again.toString());
|
|
65
|
-
});
|
|
66
|
-
|
|
67
|
-
test("Store and retrieve a seed wallet", async () => {
|
|
68
|
-
let w1 = await Wallet.named("Seed Wallet", "db-test");
|
|
69
|
-
expect(w1.name).toBe("Seed Wallet");
|
|
70
|
-
expect(w1.network).toBe("mainnet");
|
|
71
|
-
expect(w1.walletType).toBe("seed");
|
|
72
|
-
expect(w1.toDbString()).toMatch(/seed:mainnet:(\w+\s){11}\w+/);
|
|
73
|
-
expect(w1.toString()).toBe("named:mainnet:Seed Wallet");
|
|
74
|
-
let w1Again = await Wallet.named("Seed Wallet", "db-test");
|
|
75
|
-
|
|
76
|
-
expect(w1.name).toBe(w1Again.name);
|
|
77
|
-
expect(w1.network).toBe(w1Again.network);
|
|
78
|
-
expect(w1.cashaddr).toBe(w1Again.cashaddr);
|
|
79
|
-
expect(w1.privateKeyWif).toBe(w1Again.privateKeyWif);
|
|
80
|
-
expect(w1.toString()).toBe(w1Again.toString());
|
|
81
|
-
});
|
|
82
|
-
|
|
83
|
-
test("Expect Error passing mainnet wallet to error", async () => {
|
|
84
|
-
expect.assertions(1);
|
|
85
|
-
try {
|
|
86
|
-
process.env.ALLOW_MAINNET_USER_WALLETS = "false";
|
|
87
|
-
await Wallet.named("Seed Wallet", "db-test");
|
|
88
|
-
} catch (e: any) {
|
|
89
|
-
expect(e.message).toBe(
|
|
90
|
-
'Refusing to save wallet in an open public database, remove ALLOW_MAINNET_USER_WALLETS="false", if this service is secure and private'
|
|
91
|
-
);
|
|
92
|
-
}
|
|
93
|
-
});
|
package/src/index.ts
DELETED
package/src/util.ts
DELETED
|
@@ -1,32 +0,0 @@
|
|
|
1
|
-
import { base64ToBin, binToUtf8 } from "@bitauth/libauth";
|
|
2
|
-
|
|
3
|
-
export interface sslConfigI {
|
|
4
|
-
rejectUnauthorized: boolean;
|
|
5
|
-
ca?: string;
|
|
6
|
-
key?: string;
|
|
7
|
-
cert?: string;
|
|
8
|
-
}
|
|
9
|
-
|
|
10
|
-
export function getSslConfig(): sslConfigI | undefined {
|
|
11
|
-
const ca = process.env.DATABASE_SSL_CA
|
|
12
|
-
? binToUtf8(base64ToBin(process.env.DATABASE_SSL_CA))
|
|
13
|
-
: undefined;
|
|
14
|
-
const key = process.env.DATABASE_SSL_KEY
|
|
15
|
-
? binToUtf8(base64ToBin(process.env.DATABASE_SSL_KEY))
|
|
16
|
-
: undefined;
|
|
17
|
-
const cert = process.env.DATABASE_SSL_CERT
|
|
18
|
-
? binToUtf8(base64ToBin(process.env.DATABASE_SSL_CERT))
|
|
19
|
-
: undefined;
|
|
20
|
-
let ssl: sslConfigI = {
|
|
21
|
-
rejectUnauthorized:
|
|
22
|
-
process.env.DATABASE_SSL_REJECT_UNAUTHORIZED == "false" ? false : true,
|
|
23
|
-
ca: ca,
|
|
24
|
-
key: key,
|
|
25
|
-
cert: cert,
|
|
26
|
-
};
|
|
27
|
-
if (ssl.ca || ssl.cert || ssl.key) {
|
|
28
|
-
return ssl;
|
|
29
|
-
} else {
|
|
30
|
-
return;
|
|
31
|
-
}
|
|
32
|
-
}
|
package/src/webhook/Webhook.ts
DELETED
|
@@ -1,99 +0,0 @@
|
|
|
1
|
-
import SqlProvider from "../SqlProvider.js";
|
|
2
|
-
import { TxI } from "mainnet-js";
|
|
3
|
-
|
|
4
|
-
import axios from "axios";
|
|
5
|
-
|
|
6
|
-
export enum WebhookType {
|
|
7
|
-
transactionIn = "transaction:in",
|
|
8
|
-
transactionOut = "transaction:out",
|
|
9
|
-
transactionInOut = "transaction:in,out",
|
|
10
|
-
balance = "balance",
|
|
11
|
-
}
|
|
12
|
-
|
|
13
|
-
export enum WebhookRecurrence {
|
|
14
|
-
once = "once",
|
|
15
|
-
recurrent = "recurrent",
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
export class Webhook {
|
|
19
|
-
id?: number;
|
|
20
|
-
cashaddr!: string;
|
|
21
|
-
type!: string;
|
|
22
|
-
recurrence!: string;
|
|
23
|
-
url!: string;
|
|
24
|
-
status!: string;
|
|
25
|
-
last_height!: number;
|
|
26
|
-
tx_seen!: TxI[];
|
|
27
|
-
expires_at!: Date;
|
|
28
|
-
|
|
29
|
-
db!: SqlProvider;
|
|
30
|
-
|
|
31
|
-
constructor(hook: Webhook | Object) {
|
|
32
|
-
Object.assign(this, hook);
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
// abstract, empty implementation
|
|
36
|
-
async start(): Promise<void> {}
|
|
37
|
-
|
|
38
|
-
// abstract, empty implementation
|
|
39
|
-
async stop(): Promise<void> {}
|
|
40
|
-
|
|
41
|
-
async destroy(): Promise<void> {
|
|
42
|
-
if (this.id) {
|
|
43
|
-
await this.db.deleteWebhook(this.id);
|
|
44
|
-
}
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
async post(data: any): Promise<boolean> {
|
|
48
|
-
try {
|
|
49
|
-
await axios.post(this.url, data);
|
|
50
|
-
// console.debug("Posted webhook", this.url, data);
|
|
51
|
-
return true;
|
|
52
|
-
} catch (e: any) {
|
|
53
|
-
if (e.message && e.message.status === 200) {
|
|
54
|
-
return true;
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
// console.debug("Failed to post webhook", this.url, e);
|
|
58
|
-
return false;
|
|
59
|
-
}
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
//#region debug
|
|
63
|
-
public static debug = class {
|
|
64
|
-
static setupAxiosMocks() {
|
|
65
|
-
axios.interceptors.request.use((config) => {
|
|
66
|
-
const url = config.url!;
|
|
67
|
-
if (!url.startsWith("http://example.com")) {
|
|
68
|
-
return config;
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
let response;
|
|
72
|
-
if (url === "http://example.com/fail") {
|
|
73
|
-
response = { status: 503 };
|
|
74
|
-
} else {
|
|
75
|
-
response = { status: 200 };
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
if (url in this.responses) {
|
|
79
|
-
this.responses[url].push(response);
|
|
80
|
-
} else {
|
|
81
|
-
this.responses[url] = [response];
|
|
82
|
-
}
|
|
83
|
-
|
|
84
|
-
// cancel actual http request
|
|
85
|
-
return {
|
|
86
|
-
...config,
|
|
87
|
-
cancelToken: new axios.CancelToken((cancel) => cancel(response)),
|
|
88
|
-
};
|
|
89
|
-
});
|
|
90
|
-
}
|
|
91
|
-
|
|
92
|
-
static reset() {
|
|
93
|
-
this.responses = {};
|
|
94
|
-
}
|
|
95
|
-
|
|
96
|
-
static responses: any = {};
|
|
97
|
-
};
|
|
98
|
-
//#endregion
|
|
99
|
-
}
|
|
@@ -1,315 +0,0 @@
|
|
|
1
|
-
import WebhookWorker from "../webhook/WebhookWorker";
|
|
2
|
-
import { RegTestWallet } from "mainnet-js";
|
|
3
|
-
import { mine } from "mainnet-js";
|
|
4
|
-
import { Webhook, WebhookRecurrence, WebhookType } from "./Webhook";
|
|
5
|
-
|
|
6
|
-
let worker: WebhookWorker;
|
|
7
|
-
let alice;
|
|
8
|
-
let aliceWif;
|
|
9
|
-
|
|
10
|
-
/**
|
|
11
|
-
* @jest-environment jsdom
|
|
12
|
-
*/
|
|
13
|
-
describe("Webhook worker tests", () => {
|
|
14
|
-
beforeAll(async () => {
|
|
15
|
-
try {
|
|
16
|
-
if (process.env.PRIVATE_WIF) {
|
|
17
|
-
alice = process.env.ADDRESS!;
|
|
18
|
-
aliceWif = `wif:regtest:${process.env.PRIVATE_WIF!}`;
|
|
19
|
-
} else {
|
|
20
|
-
console.error("regtest env vars not set");
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
Webhook.debug.setupAxiosMocks();
|
|
24
|
-
worker = await WebhookWorker.instance();
|
|
25
|
-
} catch (e: any) {
|
|
26
|
-
throw e;
|
|
27
|
-
}
|
|
28
|
-
});
|
|
29
|
-
|
|
30
|
-
beforeEach(async () => {
|
|
31
|
-
await worker.deleteAllWebhooks();
|
|
32
|
-
});
|
|
33
|
-
|
|
34
|
-
afterEach(async () => {
|
|
35
|
-
Webhook.debug.reset();
|
|
36
|
-
});
|
|
37
|
-
|
|
38
|
-
afterAll(async () => {
|
|
39
|
-
await worker.destroy();
|
|
40
|
-
await worker.db.close();
|
|
41
|
-
});
|
|
42
|
-
|
|
43
|
-
test("Test non-recurrent hook to be deleted after successful call", async () => {
|
|
44
|
-
try {
|
|
45
|
-
const aliceWallet = await RegTestWallet.fromId(aliceWif);
|
|
46
|
-
const bobWallet = await RegTestWallet.newRandom();
|
|
47
|
-
await worker.registerWebhook({
|
|
48
|
-
cashaddr: bobWallet.cashaddr!,
|
|
49
|
-
url: "http://example.com/success",
|
|
50
|
-
type: WebhookType.transactionIn,
|
|
51
|
-
recurrence: WebhookRecurrence.once,
|
|
52
|
-
});
|
|
53
|
-
|
|
54
|
-
await Promise.all([
|
|
55
|
-
aliceWallet.send([
|
|
56
|
-
{
|
|
57
|
-
cashaddr: bobWallet.cashaddr!,
|
|
58
|
-
value: 1000n,
|
|
59
|
-
},
|
|
60
|
-
]),
|
|
61
|
-
bobWallet.waitForTransaction(),
|
|
62
|
-
]);
|
|
63
|
-
|
|
64
|
-
// return funds
|
|
65
|
-
// let sendResponse2 = await bobWallet.sendMax(aliceWallet.cashaddr!);
|
|
66
|
-
|
|
67
|
-
await new Promise((resolve) =>
|
|
68
|
-
setTimeout(async () => {
|
|
69
|
-
expect(
|
|
70
|
-
Webhook.debug.responses["http://example.com/success"].length
|
|
71
|
-
).toBe(1);
|
|
72
|
-
expect(worker.activeHooks.size).toBe(0);
|
|
73
|
-
|
|
74
|
-
resolve(true);
|
|
75
|
-
}, 3000)
|
|
76
|
-
);
|
|
77
|
-
} catch (e: any) {
|
|
78
|
-
console.log(e, e.stack, e.message);
|
|
79
|
-
throw e;
|
|
80
|
-
}
|
|
81
|
-
}, 20000);
|
|
82
|
-
|
|
83
|
-
test("Test non-recurrent hook to be not deleted after failed call", async () => {
|
|
84
|
-
try {
|
|
85
|
-
const aliceWallet = await RegTestWallet.fromId(aliceWif);
|
|
86
|
-
const bobWallet = await RegTestWallet.newRandom();
|
|
87
|
-
await worker.registerWebhook({
|
|
88
|
-
cashaddr: bobWallet.cashaddr!,
|
|
89
|
-
url: "http://example.com/fail",
|
|
90
|
-
type: WebhookType.transactionIn,
|
|
91
|
-
recurrence: WebhookRecurrence.once,
|
|
92
|
-
});
|
|
93
|
-
|
|
94
|
-
await Promise.all([
|
|
95
|
-
aliceWallet.send([
|
|
96
|
-
{
|
|
97
|
-
cashaddr: bobWallet.cashaddr!,
|
|
98
|
-
value: 1000n,
|
|
99
|
-
},
|
|
100
|
-
]),
|
|
101
|
-
bobWallet.waitForTransaction(),
|
|
102
|
-
]);
|
|
103
|
-
|
|
104
|
-
await new Promise((resolve) =>
|
|
105
|
-
setTimeout(async () => {
|
|
106
|
-
expect(
|
|
107
|
-
Webhook.debug.responses["http://example.com/fail"].length
|
|
108
|
-
).toBe(1);
|
|
109
|
-
expect(worker.activeHooks.size).toBe(1);
|
|
110
|
-
|
|
111
|
-
// return funds
|
|
112
|
-
// let sendResponse2 = await bobWallet.sendMax(aliceWallet.cashaddr!);
|
|
113
|
-
resolve(true);
|
|
114
|
-
}, 3000)
|
|
115
|
-
);
|
|
116
|
-
} catch (e: any) {
|
|
117
|
-
console.log(e, e.stack, e.message);
|
|
118
|
-
throw e;
|
|
119
|
-
}
|
|
120
|
-
}, 20000);
|
|
121
|
-
|
|
122
|
-
test("Test recurrent hook for incoming transaction", async () => {
|
|
123
|
-
try {
|
|
124
|
-
const aliceWallet = await RegTestWallet.fromId(aliceWif);
|
|
125
|
-
const bobWallet = await RegTestWallet.newRandom();
|
|
126
|
-
await worker.registerWebhook({
|
|
127
|
-
cashaddr: bobWallet.cashaddr!,
|
|
128
|
-
url: "http://example.com/bob",
|
|
129
|
-
type: WebhookType.transactionIn,
|
|
130
|
-
recurrence: WebhookRecurrence.recurrent,
|
|
131
|
-
});
|
|
132
|
-
|
|
133
|
-
await Promise.all([
|
|
134
|
-
aliceWallet.send([
|
|
135
|
-
{
|
|
136
|
-
cashaddr: bobWallet.cashaddr!,
|
|
137
|
-
value: 1000n,
|
|
138
|
-
},
|
|
139
|
-
]),
|
|
140
|
-
bobWallet.waitForTransaction(),
|
|
141
|
-
]);
|
|
142
|
-
|
|
143
|
-
// return funds
|
|
144
|
-
// let sendResponse2 = await bobWallet.sendMax(aliceWallet.cashaddr!);
|
|
145
|
-
|
|
146
|
-
await new Promise((resolve) =>
|
|
147
|
-
setTimeout(async () => {
|
|
148
|
-
expect(Webhook.debug.responses["http://example.com/bob"].length).toBe(
|
|
149
|
-
1
|
|
150
|
-
);
|
|
151
|
-
expect(worker.activeHooks.size).toBe(1);
|
|
152
|
-
|
|
153
|
-
resolve(true);
|
|
154
|
-
}, 3000)
|
|
155
|
-
);
|
|
156
|
-
} catch (e: any) {
|
|
157
|
-
console.log(e, e.stack, e.message);
|
|
158
|
-
throw e;
|
|
159
|
-
}
|
|
160
|
-
}, 20000);
|
|
161
|
-
|
|
162
|
-
test("Test recurrent hook for outgoing transactions", async () => {
|
|
163
|
-
try {
|
|
164
|
-
const aliceWallet = await RegTestWallet.fromId(aliceWif);
|
|
165
|
-
const bobWallet = await RegTestWallet.newRandom();
|
|
166
|
-
await worker.registerWebhook({
|
|
167
|
-
cashaddr: bobWallet.cashaddr!,
|
|
168
|
-
url: "http://example.com/bob",
|
|
169
|
-
type: WebhookType.transactionOut,
|
|
170
|
-
recurrence: WebhookRecurrence.recurrent,
|
|
171
|
-
});
|
|
172
|
-
|
|
173
|
-
await Promise.all([
|
|
174
|
-
aliceWallet.send([
|
|
175
|
-
{
|
|
176
|
-
cashaddr: bobWallet.cashaddr!,
|
|
177
|
-
value: 1000n,
|
|
178
|
-
},
|
|
179
|
-
]),
|
|
180
|
-
bobWallet.waitForTransaction(),
|
|
181
|
-
]);
|
|
182
|
-
|
|
183
|
-
// return funds
|
|
184
|
-
await Promise.all([
|
|
185
|
-
bobWallet.sendMax(aliceWallet.cashaddr!),
|
|
186
|
-
aliceWallet.waitForTransaction(),
|
|
187
|
-
]);
|
|
188
|
-
|
|
189
|
-
await new Promise((resolve) =>
|
|
190
|
-
setTimeout(async () => {
|
|
191
|
-
expect(Webhook.debug.responses["http://example.com/bob"].length).toBe(
|
|
192
|
-
1
|
|
193
|
-
);
|
|
194
|
-
expect(worker.activeHooks.size).toBe(1);
|
|
195
|
-
|
|
196
|
-
resolve(true);
|
|
197
|
-
}, 3000)
|
|
198
|
-
);
|
|
199
|
-
} catch (e: any) {
|
|
200
|
-
console.log(e, e.stack, e.message);
|
|
201
|
-
throw e;
|
|
202
|
-
}
|
|
203
|
-
}, 20000);
|
|
204
|
-
|
|
205
|
-
test("Test should pickup transactions happened while offline", async () => {
|
|
206
|
-
try {
|
|
207
|
-
const aliceWallet = await RegTestWallet.fromId(aliceWif);
|
|
208
|
-
const bobWallet = await RegTestWallet.newRandom();
|
|
209
|
-
const minerWallet = await RegTestWallet.newRandom();
|
|
210
|
-
const hookId = await worker.registerWebhook({
|
|
211
|
-
cashaddr: bobWallet.cashaddr!,
|
|
212
|
-
url: "http://example.com/bob",
|
|
213
|
-
type: WebhookType.transactionIn,
|
|
214
|
-
recurrence: WebhookRecurrence.recurrent,
|
|
215
|
-
});
|
|
216
|
-
|
|
217
|
-
// initial transaction
|
|
218
|
-
await aliceWallet.send([
|
|
219
|
-
{
|
|
220
|
-
cashaddr: bobWallet.cashaddr!,
|
|
221
|
-
value: 1000n,
|
|
222
|
-
},
|
|
223
|
-
]);
|
|
224
|
-
|
|
225
|
-
// wait worker to process, updating the status of the hook
|
|
226
|
-
await new Promise((resolve) => setTimeout(resolve, 5000));
|
|
227
|
-
|
|
228
|
-
let hook = await worker.getWebhook(hookId);
|
|
229
|
-
expect(hook!.status).not.toBe("");
|
|
230
|
-
expect(hook!.tx_seen).not.toBe([]);
|
|
231
|
-
hook!.tx_seen[0];
|
|
232
|
-
expect(Webhook.debug.responses["http://example.com/bob"].length).toBe(1);
|
|
233
|
-
|
|
234
|
-
// shutdown
|
|
235
|
-
await worker.destroy();
|
|
236
|
-
expect(worker.activeHooks.size).toBe(0);
|
|
237
|
-
|
|
238
|
-
// also mine a block while offline)
|
|
239
|
-
await mine({ cashaddr: minerWallet.cashaddr!, blocks: 1 });
|
|
240
|
-
|
|
241
|
-
// make two more transactions "offline"
|
|
242
|
-
await aliceWallet.send([
|
|
243
|
-
{
|
|
244
|
-
cashaddr: bobWallet.cashaddr!,
|
|
245
|
-
value: 1000n,
|
|
246
|
-
},
|
|
247
|
-
]);
|
|
248
|
-
await aliceWallet.send([
|
|
249
|
-
{
|
|
250
|
-
cashaddr: bobWallet.cashaddr!,
|
|
251
|
-
value: 2000n,
|
|
252
|
-
},
|
|
253
|
-
]);
|
|
254
|
-
await mine({ cashaddr: minerWallet.cashaddr!, blocks: 1 });
|
|
255
|
-
await new Promise((resolve) => setTimeout(resolve, 5000));
|
|
256
|
-
|
|
257
|
-
// wait worker to process the transactions occured while offline
|
|
258
|
-
await worker.init();
|
|
259
|
-
|
|
260
|
-
await new Promise((resolve) =>
|
|
261
|
-
setTimeout(async () => {
|
|
262
|
-
expect(worker.activeHooks.size).toBe(1);
|
|
263
|
-
expect(Webhook.debug.responses["http://example.com/bob"].length).toBe(
|
|
264
|
-
3
|
|
265
|
-
);
|
|
266
|
-
|
|
267
|
-
resolve(true);
|
|
268
|
-
}, 10000)
|
|
269
|
-
);
|
|
270
|
-
} catch (e: any) {
|
|
271
|
-
console.log(e, e.stack, e.message);
|
|
272
|
-
throw e;
|
|
273
|
-
}
|
|
274
|
-
}, 30000);
|
|
275
|
-
|
|
276
|
-
test("Test non-recurrent watch balance hook", async () => {
|
|
277
|
-
try {
|
|
278
|
-
const aliceWallet = await RegTestWallet.fromId(aliceWif);
|
|
279
|
-
const bobWallet = await RegTestWallet.newRandom();
|
|
280
|
-
await worker.registerWebhook({
|
|
281
|
-
cashaddr: bobWallet.cashaddr!,
|
|
282
|
-
url: "http://example.com/watchBalance",
|
|
283
|
-
type: WebhookType.balance,
|
|
284
|
-
recurrence: WebhookRecurrence.once,
|
|
285
|
-
});
|
|
286
|
-
|
|
287
|
-
await Promise.all([
|
|
288
|
-
aliceWallet.send([
|
|
289
|
-
{
|
|
290
|
-
cashaddr: bobWallet.cashaddr!,
|
|
291
|
-
value: 1000n,
|
|
292
|
-
},
|
|
293
|
-
]),
|
|
294
|
-
bobWallet.waitForTransaction(),
|
|
295
|
-
]);
|
|
296
|
-
|
|
297
|
-
// return funds
|
|
298
|
-
// let sendResponse2 = await bobWallet.sendMax(aliceWallet.cashaddr!);
|
|
299
|
-
|
|
300
|
-
await new Promise((resolve) =>
|
|
301
|
-
setTimeout(async () => {
|
|
302
|
-
expect(
|
|
303
|
-
Webhook.debug.responses["http://example.com/watchBalance"].length
|
|
304
|
-
).toBe(1);
|
|
305
|
-
expect(worker.activeHooks.size).toBe(0);
|
|
306
|
-
|
|
307
|
-
resolve(true);
|
|
308
|
-
}, 3000)
|
|
309
|
-
);
|
|
310
|
-
} catch (e: any) {
|
|
311
|
-
console.log(e, e.stack, e.message);
|
|
312
|
-
throw e;
|
|
313
|
-
}
|
|
314
|
-
}, 20000);
|
|
315
|
-
});
|