hive-stream 3.0.2 → 3.0.3
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/DOCUMENTATION.md +50 -2
- package/README.md +44 -3
- package/dist/adapters/base.adapter.d.ts +5 -0
- package/dist/adapters/base.adapter.js +9 -0
- package/dist/adapters/base.adapter.js.map +1 -1
- package/dist/adapters/mongodb.adapter.d.ts +6 -6
- package/dist/adapters/mongodb.adapter.js +36 -21
- package/dist/adapters/mongodb.adapter.js.map +1 -1
- package/dist/adapters/postgresql.adapter.d.ts +7 -0
- package/dist/adapters/postgresql.adapter.js +46 -19
- package/dist/adapters/postgresql.adapter.js.map +1 -1
- package/dist/adapters/sqlite.adapter.d.ts +4 -0
- package/dist/adapters/sqlite.adapter.js +10 -0
- package/dist/adapters/sqlite.adapter.js.map +1 -1
- package/dist/api.d.ts +13 -3
- package/dist/api.js +96 -62
- package/dist/api.js.map +1 -1
- package/dist/config.d.ts +7 -1
- package/dist/config.js +7 -1
- package/dist/config.js.map +1 -1
- package/dist/contracts/auctionhouse.contract.d.ts +4 -0
- package/dist/contracts/auctionhouse.contract.js +234 -0
- package/dist/contracts/auctionhouse.contract.js.map +1 -0
- package/dist/contracts/booking.contract.d.ts +4 -0
- package/dist/contracts/booking.contract.js +225 -0
- package/dist/contracts/booking.contract.js.map +1 -0
- package/dist/contracts/bountyboard.contract.d.ts +4 -0
- package/dist/contracts/bountyboard.contract.js +233 -0
- package/dist/contracts/bountyboard.contract.js.map +1 -0
- package/dist/contracts/bundlemarketplace.contract.d.ts +4 -0
- package/dist/contracts/bundlemarketplace.contract.js +195 -0
- package/dist/contracts/bundlemarketplace.contract.js.map +1 -0
- package/dist/contracts/charitymatch.contract.d.ts +4 -0
- package/dist/contracts/charitymatch.contract.js +172 -0
- package/dist/contracts/charitymatch.contract.js.map +1 -0
- package/dist/contracts/coinflip.contract.js +7 -1
- package/dist/contracts/coinflip.contract.js.map +1 -1
- package/dist/contracts/crowdfund.contract.d.ts +4 -0
- package/dist/contracts/crowdfund.contract.js +290 -0
- package/dist/contracts/crowdfund.contract.js.map +1 -0
- package/dist/contracts/dcabot.contract.d.ts +4 -0
- package/dist/contracts/dcabot.contract.js +217 -0
- package/dist/contracts/dcabot.contract.js.map +1 -0
- package/dist/contracts/dice.contract.js +7 -1
- package/dist/contracts/dice.contract.js.map +1 -1
- package/dist/contracts/domainregistry.contract.d.ts +4 -0
- package/dist/contracts/domainregistry.contract.js +232 -0
- package/dist/contracts/domainregistry.contract.js.map +1 -0
- package/dist/contracts/exchange.contract.js +209 -168
- package/dist/contracts/exchange.contract.js.map +1 -1
- package/dist/contracts/fanclub.contract.d.ts +4 -0
- package/dist/contracts/fanclub.contract.js +193 -0
- package/dist/contracts/fanclub.contract.js.map +1 -0
- package/dist/contracts/giftcard.contract.d.ts +4 -0
- package/dist/contracts/giftcard.contract.js +158 -0
- package/dist/contracts/giftcard.contract.js.map +1 -0
- package/dist/contracts/grantrounds.contract.d.ts +4 -0
- package/dist/contracts/grantrounds.contract.js +265 -0
- package/dist/contracts/grantrounds.contract.js.map +1 -0
- package/dist/contracts/groupbuy.contract.d.ts +4 -0
- package/dist/contracts/groupbuy.contract.js +198 -0
- package/dist/contracts/groupbuy.contract.js.map +1 -0
- package/dist/contracts/helpers.d.ts +64 -0
- package/dist/contracts/helpers.js +159 -0
- package/dist/contracts/helpers.js.map +1 -0
- package/dist/contracts/insurancepool.contract.d.ts +4 -0
- package/dist/contracts/insurancepool.contract.js +281 -0
- package/dist/contracts/insurancepool.contract.js.map +1 -0
- package/dist/contracts/invoice.contract.d.ts +4 -0
- package/dist/contracts/invoice.contract.js +193 -0
- package/dist/contracts/invoice.contract.js.map +1 -0
- package/dist/contracts/launchpad.contract.d.ts +4 -0
- package/dist/contracts/launchpad.contract.js +225 -0
- package/dist/contracts/launchpad.contract.js.map +1 -0
- package/dist/contracts/lotto.contract.js +53 -37
- package/dist/contracts/lotto.contract.js.map +1 -1
- package/dist/contracts/multisigtreasury.contract.d.ts +4 -0
- package/dist/contracts/multisigtreasury.contract.js +245 -0
- package/dist/contracts/multisigtreasury.contract.js.map +1 -0
- package/dist/contracts/nft.contract.d.ts +1 -0
- package/dist/contracts/nft.contract.js +236 -192
- package/dist/contracts/nft.contract.js.map +1 -1
- package/dist/contracts/oraclebounty.contract.d.ts +4 -0
- package/dist/contracts/oraclebounty.contract.js +250 -0
- package/dist/contracts/oraclebounty.contract.js.map +1 -0
- package/dist/contracts/payroll.contract.d.ts +4 -0
- package/dist/contracts/payroll.contract.js +232 -0
- package/dist/contracts/payroll.contract.js.map +1 -0
- package/dist/contracts/paywall.contract.d.ts +4 -0
- package/dist/contracts/paywall.contract.js +185 -0
- package/dist/contracts/paywall.contract.js.map +1 -0
- package/dist/contracts/poll.contract.js +2 -0
- package/dist/contracts/poll.contract.js.map +1 -1
- package/dist/contracts/predictionmarket.contract.d.ts +4 -0
- package/dist/contracts/predictionmarket.contract.js +213 -0
- package/dist/contracts/predictionmarket.contract.js.map +1 -0
- package/dist/contracts/proposaltimelock.contract.d.ts +4 -0
- package/dist/contracts/proposaltimelock.contract.js +250 -0
- package/dist/contracts/proposaltimelock.contract.js.map +1 -0
- package/dist/contracts/questpass.contract.d.ts +4 -0
- package/dist/contracts/questpass.contract.js +214 -0
- package/dist/contracts/questpass.contract.js.map +1 -0
- package/dist/contracts/referral.contract.d.ts +4 -0
- package/dist/contracts/referral.contract.js +238 -0
- package/dist/contracts/referral.contract.js.map +1 -0
- package/dist/contracts/rental.contract.d.ts +4 -0
- package/dist/contracts/rental.contract.js +221 -0
- package/dist/contracts/rental.contract.js.map +1 -0
- package/dist/contracts/revenuesplit.contract.d.ts +4 -0
- package/dist/contracts/revenuesplit.contract.js +211 -0
- package/dist/contracts/revenuesplit.contract.js.map +1 -0
- package/dist/contracts/rps.contract.js +17 -1
- package/dist/contracts/rps.contract.js.map +1 -1
- package/dist/contracts/savings.contract.d.ts +4 -0
- package/dist/contracts/savings.contract.js +208 -0
- package/dist/contracts/savings.contract.js.map +1 -0
- package/dist/contracts/subscription.contract.d.ts +4 -0
- package/dist/contracts/subscription.contract.js +241 -0
- package/dist/contracts/subscription.contract.js.map +1 -0
- package/dist/contracts/sweepstakes.contract.d.ts +4 -0
- package/dist/contracts/sweepstakes.contract.js +209 -0
- package/dist/contracts/sweepstakes.contract.js.map +1 -0
- package/dist/contracts/ticketing.contract.d.ts +4 -0
- package/dist/contracts/ticketing.contract.js +185 -0
- package/dist/contracts/ticketing.contract.js.map +1 -0
- package/dist/contracts/tipjar.contract.js +2 -0
- package/dist/contracts/tipjar.contract.js.map +1 -1
- package/dist/contracts/token.contract.js +135 -125
- package/dist/contracts/token.contract.js.map +1 -1
- package/dist/index.d.ts +39 -0
- package/dist/index.js +71 -1
- package/dist/index.js.map +1 -1
- package/dist/metadata.d.ts +7 -0
- package/dist/metadata.js +64 -1
- package/dist/metadata.js.map +1 -1
- package/dist/providers/block-provider.d.ts +22 -0
- package/dist/providers/block-provider.js +3 -0
- package/dist/providers/block-provider.js.map +1 -0
- package/dist/providers/haf-client.d.ts +30 -0
- package/dist/providers/haf-client.js +119 -0
- package/dist/providers/haf-client.js.map +1 -0
- package/dist/providers/haf-provider.d.ts +49 -0
- package/dist/providers/haf-provider.js +256 -0
- package/dist/providers/haf-provider.js.map +1 -0
- package/dist/providers/hive-provider.d.ts +13 -0
- package/dist/providers/hive-provider.js +25 -0
- package/dist/providers/hive-provider.js.map +1 -0
- package/dist/providers/index.d.ts +4 -0
- package/dist/providers/index.js +21 -0
- package/dist/providers/index.js.map +1 -0
- package/dist/streamer.d.ts +21 -1
- package/dist/streamer.js +187 -62
- package/dist/streamer.js.map +1 -1
- package/dist/utils.js +11 -2
- package/dist/utils.js.map +1 -1
- package/package.json +16 -1
- package/.claude/settings.local.json +0 -12
- package/.env.example +0 -3
- package/.travis.yml +0 -11
- package/AGENTS.md +0 -35
- package/CLAUDE.md +0 -75
- package/ecosystem.config.js +0 -17
- package/examples/contracts/README.md +0 -8
- package/examples/contracts/exchange.ts +0 -38
- package/examples/contracts/poll.ts +0 -21
- package/examples/contracts/rps.ts +0 -19
- package/examples/contracts/tipjar.ts +0 -19
- package/jest.config.js +0 -9
- package/test-contract-block.md +0 -19
- package/tests/actions.spec.ts +0 -252
- package/tests/adapters/actions-persistence.spec.ts +0 -144
- package/tests/adapters/postgresql.adapter.spec.ts +0 -127
- package/tests/adapters/sqlite.adapter.spec.ts +0 -181
- package/tests/config-input.spec.ts +0 -90
- package/tests/contracts/coinflip.contract.spec.ts +0 -94
- package/tests/contracts/dice.contract.spec.ts +0 -87
- package/tests/contracts/entrants.json +0 -729
- package/tests/contracts/exchange.contract.spec.ts +0 -84
- package/tests/contracts/lotto.contract.spec.ts +0 -59
- package/tests/contracts/nft.contract.spec.ts +0 -948
- package/tests/contracts/token.contract.spec.ts +0 -90
- package/tests/exchanges/coingecko.exchange.spec.ts +0 -169
- package/tests/exchanges/exchange.base.spec.ts +0 -246
- package/tests/helpers/mock-adapter.ts +0 -214
- package/tests/helpers/mock-fetch.ts +0 -165
- package/tests/hive-chain-features.spec.ts +0 -319
- package/tests/hive-rates.spec.ts +0 -443
- package/tests/integration/hive-rates.integration.spec.ts +0 -35
- package/tests/metadata.spec.ts +0 -63
- package/tests/setup.ts +0 -30
- package/tests/streamer-actions.spec.ts +0 -274
- package/tests/streamer.spec.ts +0 -342
- package/tests/types/rates.spec.ts +0 -216
- package/tests/utils.spec.ts +0 -113
- package/tsconfig.build.json +0 -4
- package/tslint.json +0 -21
- package/wallaby.js +0 -26
|
@@ -1,214 +0,0 @@
|
|
|
1
|
-
import { AdapterBase } from '../../src/adapters/base.adapter';
|
|
2
|
-
|
|
3
|
-
export class MockAdapter extends AdapterBase {
|
|
4
|
-
public queries: string[] = [];
|
|
5
|
-
public events: any[] = [];
|
|
6
|
-
private queryResults: any[][] = [];
|
|
7
|
-
private currentQueryIndex = 0;
|
|
8
|
-
private testContext: any = {};
|
|
9
|
-
public async create(): Promise<boolean> {
|
|
10
|
-
return true;
|
|
11
|
-
}
|
|
12
|
-
|
|
13
|
-
public async destroy(): Promise<boolean> {
|
|
14
|
-
return true;
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
public async loadActions() {
|
|
18
|
-
return [];
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
public async loadState() {
|
|
22
|
-
return { lastBlockNumber: 0, actions: [] };
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
public async saveState(data: any): Promise<boolean> {
|
|
26
|
-
return true;
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
public async processBlock(block: any): Promise<any> {
|
|
30
|
-
return true;
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
public async processOperation(op: any, blockNumber: number, blockId: string, prevBlockId: string, trxId: string, blockTime: Date): Promise<any> {
|
|
34
|
-
return true;
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
public async processTransfer(operation: any, payload: any, metadata: any): Promise<boolean> {
|
|
38
|
-
return true;
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
public async processCustomJson(operation: any, payload: any, metadata: any): Promise<boolean> {
|
|
42
|
-
return true;
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
public async find(table: string, queryObject: Record<string, any>): Promise<any> {
|
|
46
|
-
return [];
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
public async findOne(table: string, queryObject: Record<string, any>): Promise<any> {
|
|
50
|
-
return null;
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
public async insert(table: string, data: any): Promise<any> {
|
|
54
|
-
return true;
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
public async replace(table: string, queryObject: Record<string, any>, data: any): Promise<any> {
|
|
58
|
-
return data;
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
public async addEvent(date: string | Date, contract: string, action: string, payload: any, data: any): Promise<boolean> {
|
|
62
|
-
this.events.push({ date, contract, action, payload, data });
|
|
63
|
-
return true;
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
public async query(sql: string, params?: any[]): Promise<any[]> {
|
|
67
|
-
this.queries.push(sql);
|
|
68
|
-
|
|
69
|
-
// Handle specific queries with predetermined responses
|
|
70
|
-
if (sql.includes('CREATE TABLE')) {
|
|
71
|
-
return [];
|
|
72
|
-
}
|
|
73
|
-
|
|
74
|
-
if (sql.includes('SELECT precision FROM tokens WHERE symbol = ?')) {
|
|
75
|
-
const symbol = params?.[0];
|
|
76
|
-
if (this.testContext.nonExistentToken === symbol) {
|
|
77
|
-
return [];
|
|
78
|
-
}
|
|
79
|
-
return [{ precision: 3 }];
|
|
80
|
-
}
|
|
81
|
-
|
|
82
|
-
if (sql.includes('SELECT balance FROM token_balances WHERE account = ? AND symbol = ?')) {
|
|
83
|
-
const account = params?.[0];
|
|
84
|
-
const symbol = params?.[1];
|
|
85
|
-
|
|
86
|
-
// Handle test scenarios
|
|
87
|
-
if (this.testContext.insufficientBalance && account === 'alice') {
|
|
88
|
-
return [{ balance: '50' }];
|
|
89
|
-
}
|
|
90
|
-
if (this.testContext.zeroBalance && account === 'alice') {
|
|
91
|
-
return [];
|
|
92
|
-
}
|
|
93
|
-
if (this.testContext.noExistingBalance) {
|
|
94
|
-
return [];
|
|
95
|
-
}
|
|
96
|
-
|
|
97
|
-
// Default balances
|
|
98
|
-
if (account === 'alice') {
|
|
99
|
-
return [{ balance: '1000' }];
|
|
100
|
-
} else if (account === 'bob') {
|
|
101
|
-
return [{ balance: '50' }];
|
|
102
|
-
}
|
|
103
|
-
return [];
|
|
104
|
-
}
|
|
105
|
-
|
|
106
|
-
if (sql.includes('SELECT * FROM tokens WHERE symbol = ?')) {
|
|
107
|
-
const symbol = params?.[0];
|
|
108
|
-
if (this.testContext.nonExistentToken === symbol) {
|
|
109
|
-
return [];
|
|
110
|
-
}
|
|
111
|
-
|
|
112
|
-
// Handle max supply exceeded test
|
|
113
|
-
if (this.testContext.maxSupplyExceeded) {
|
|
114
|
-
return [{
|
|
115
|
-
symbol: 'TEST',
|
|
116
|
-
name: 'Test Token',
|
|
117
|
-
creator: 'alice',
|
|
118
|
-
precision: 3,
|
|
119
|
-
max_supply: '1000000',
|
|
120
|
-
current_supply: '999999'
|
|
121
|
-
}];
|
|
122
|
-
}
|
|
123
|
-
|
|
124
|
-
// Return token info for existing tokens
|
|
125
|
-
return [{
|
|
126
|
-
symbol: 'TEST',
|
|
127
|
-
name: 'Test Token',
|
|
128
|
-
url: 'https://example.com/token',
|
|
129
|
-
precision: 3,
|
|
130
|
-
max_supply: '1000000',
|
|
131
|
-
current_supply: '500000',
|
|
132
|
-
creator: 'alice',
|
|
133
|
-
created_at: new Date()
|
|
134
|
-
}];
|
|
135
|
-
}
|
|
136
|
-
|
|
137
|
-
if (sql.includes('SELECT symbol FROM tokens WHERE symbol = ?')) {
|
|
138
|
-
const symbol = params?.[0];
|
|
139
|
-
if (this.testContext.existingToken === symbol) {
|
|
140
|
-
return [{ symbol }];
|
|
141
|
-
}
|
|
142
|
-
return [];
|
|
143
|
-
}
|
|
144
|
-
|
|
145
|
-
// Use sequential results for other queries
|
|
146
|
-
if (this.queryResults.length > this.currentQueryIndex) {
|
|
147
|
-
return this.queryResults[this.currentQueryIndex++];
|
|
148
|
-
}
|
|
149
|
-
return [];
|
|
150
|
-
}
|
|
151
|
-
|
|
152
|
-
public setQueryResult(result: any[], index?: number): void {
|
|
153
|
-
if (index !== undefined) {
|
|
154
|
-
this.queryResults[index] = result;
|
|
155
|
-
} else {
|
|
156
|
-
this.queryResults.push(result);
|
|
157
|
-
}
|
|
158
|
-
}
|
|
159
|
-
|
|
160
|
-
public setQueryResults(results: any[][]): void {
|
|
161
|
-
this.queryResults = results;
|
|
162
|
-
this.currentQueryIndex = 0;
|
|
163
|
-
}
|
|
164
|
-
|
|
165
|
-
public reset(): void {
|
|
166
|
-
this.queries = [];
|
|
167
|
-
this.events = [];
|
|
168
|
-
this.queryResults = [];
|
|
169
|
-
this.currentQueryIndex = 0;
|
|
170
|
-
this.testContext = {};
|
|
171
|
-
}
|
|
172
|
-
|
|
173
|
-
public setTestContext(context: any): void {
|
|
174
|
-
this.testContext = context;
|
|
175
|
-
}
|
|
176
|
-
|
|
177
|
-
public async getTransfers() {
|
|
178
|
-
return [];
|
|
179
|
-
}
|
|
180
|
-
|
|
181
|
-
public async getEvents() {
|
|
182
|
-
return [];
|
|
183
|
-
}
|
|
184
|
-
|
|
185
|
-
public async getJson() {
|
|
186
|
-
return [];
|
|
187
|
-
}
|
|
188
|
-
|
|
189
|
-
public async getTransfersByContract(contract: string) {
|
|
190
|
-
return [];
|
|
191
|
-
}
|
|
192
|
-
|
|
193
|
-
public async getTransfersByAccount(account: string) {
|
|
194
|
-
return [];
|
|
195
|
-
}
|
|
196
|
-
|
|
197
|
-
public async getTransfersByBlockid(blockId: any) {
|
|
198
|
-
return [];
|
|
199
|
-
}
|
|
200
|
-
|
|
201
|
-
public async getJsonByContract(contract: string) {
|
|
202
|
-
return [];
|
|
203
|
-
}
|
|
204
|
-
|
|
205
|
-
public async getJsonByAccount(account: string) {
|
|
206
|
-
return [];
|
|
207
|
-
}
|
|
208
|
-
|
|
209
|
-
public async getJsonByBlockid(blockId: any) {
|
|
210
|
-
return [];
|
|
211
|
-
}
|
|
212
|
-
}
|
|
213
|
-
|
|
214
|
-
export const createMockAdapter = () => new MockAdapter();
|
|
@@ -1,165 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Test utilities for mocking fetch and external APIs
|
|
3
|
-
*/
|
|
4
|
-
|
|
5
|
-
import { jest } from '@jest/globals';
|
|
6
|
-
|
|
7
|
-
// Mock Response class that properly implements the Response interface
|
|
8
|
-
export class MockResponse {
|
|
9
|
-
public readonly status: number;
|
|
10
|
-
public readonly statusText: string;
|
|
11
|
-
public readonly ok: boolean;
|
|
12
|
-
public readonly headers: Headers;
|
|
13
|
-
public readonly redirected: boolean = false;
|
|
14
|
-
public readonly type: ResponseType = 'default';
|
|
15
|
-
public readonly url: string = '';
|
|
16
|
-
public readonly body: ReadableStream<Uint8Array> | null = null;
|
|
17
|
-
public readonly bodyUsed: boolean = false;
|
|
18
|
-
|
|
19
|
-
private data: any;
|
|
20
|
-
|
|
21
|
-
constructor(data: any, options: { status?: number; statusText?: string; headers?: HeadersInit } = {}) {
|
|
22
|
-
this.data = data;
|
|
23
|
-
this.status = options.status || 200;
|
|
24
|
-
this.statusText = options.statusText || 'OK';
|
|
25
|
-
this.ok = this.status >= 200 && this.status < 300;
|
|
26
|
-
this.headers = new Headers(options.headers);
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
async json(): Promise<any> {
|
|
30
|
-
return this.data;
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
async text(): Promise<string> {
|
|
34
|
-
return typeof this.data === 'string' ? this.data : JSON.stringify(this.data);
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
async arrayBuffer(): Promise<ArrayBuffer> {
|
|
38
|
-
throw new Error('arrayBuffer not implemented in mock');
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
async blob(): Promise<Blob> {
|
|
42
|
-
throw new Error('blob not implemented in mock');
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
async formData(): Promise<FormData> {
|
|
46
|
-
throw new Error('formData not implemented in mock');
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
async bytes(): Promise<Uint8Array> {
|
|
50
|
-
throw new Error('bytes not implemented in mock');
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
clone(): MockResponse {
|
|
54
|
-
return new MockResponse(this.data, {
|
|
55
|
-
status: this.status,
|
|
56
|
-
statusText: this.statusText,
|
|
57
|
-
headers: this.headers
|
|
58
|
-
});
|
|
59
|
-
}
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
/**
|
|
63
|
-
* Create a mock fetch function with predefined responses
|
|
64
|
-
*/
|
|
65
|
-
export function createMockFetch(responses: { [url: string]: any } = {}) {
|
|
66
|
-
return jest.fn().mockImplementation((...args: any[]) => {
|
|
67
|
-
const url = args[0] as string;
|
|
68
|
-
|
|
69
|
-
// Handle URL patterns
|
|
70
|
-
if (url.includes('coingecko.com')) {
|
|
71
|
-
return Promise.resolve(new MockResponse({
|
|
72
|
-
hive: { usd: 0.25 },
|
|
73
|
-
'hive_dollar': { usd: 1.00 }
|
|
74
|
-
}));
|
|
75
|
-
}
|
|
76
|
-
|
|
77
|
-
if (url.includes('fawazahmed0.github.io') && url.includes('/latest/currencies/usd.json')) {
|
|
78
|
-
return Promise.resolve(new MockResponse({
|
|
79
|
-
usd: {
|
|
80
|
-
eur: 0.85,
|
|
81
|
-
gbp: 0.73,
|
|
82
|
-
jpy: 110.0,
|
|
83
|
-
cad: 1.25,
|
|
84
|
-
aud: 1.35
|
|
85
|
-
}
|
|
86
|
-
}));
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
// Handle specific URLs from responses object
|
|
90
|
-
if (responses[url]) {
|
|
91
|
-
return Promise.resolve(new MockResponse(responses[url]));
|
|
92
|
-
}
|
|
93
|
-
|
|
94
|
-
// Default error response
|
|
95
|
-
return Promise.reject(new Error(`Unmocked URL: ${url}`));
|
|
96
|
-
});
|
|
97
|
-
}
|
|
98
|
-
|
|
99
|
-
/**
|
|
100
|
-
* Mock successful API responses for all endpoints
|
|
101
|
-
*/
|
|
102
|
-
export function mockSuccessfulApis() {
|
|
103
|
-
const mockFetch = createMockFetch();
|
|
104
|
-
global.fetch = mockFetch as any;
|
|
105
|
-
return mockFetch;
|
|
106
|
-
}
|
|
107
|
-
|
|
108
|
-
/**
|
|
109
|
-
* Mock network errors for testing error handling
|
|
110
|
-
*/
|
|
111
|
-
export function mockNetworkErrors() {
|
|
112
|
-
const mockFetch = jest.fn().mockImplementation(() =>
|
|
113
|
-
Promise.reject(new Error('Network error'))
|
|
114
|
-
);
|
|
115
|
-
global.fetch = mockFetch as any;
|
|
116
|
-
return mockFetch;
|
|
117
|
-
}
|
|
118
|
-
|
|
119
|
-
/**
|
|
120
|
-
* Mock timeout errors
|
|
121
|
-
*/
|
|
122
|
-
export function mockTimeoutErrors() {
|
|
123
|
-
const mockFetch = jest.fn().mockImplementation(() =>
|
|
124
|
-
new Promise((_, reject) => {
|
|
125
|
-
setTimeout(() => reject(new Error('Request timeout')), 100);
|
|
126
|
-
})
|
|
127
|
-
);
|
|
128
|
-
global.fetch = mockFetch as any;
|
|
129
|
-
return mockFetch;
|
|
130
|
-
}
|
|
131
|
-
|
|
132
|
-
/**
|
|
133
|
-
* Mock invalid JSON responses
|
|
134
|
-
*/
|
|
135
|
-
export function mockInvalidResponses() {
|
|
136
|
-
const mockFetch = jest.fn().mockImplementation(() =>
|
|
137
|
-
Promise.resolve(new MockResponse('invalid json', { status: 200 }))
|
|
138
|
-
);
|
|
139
|
-
global.fetch = mockFetch as any;
|
|
140
|
-
return mockFetch;
|
|
141
|
-
}
|
|
142
|
-
|
|
143
|
-
/**
|
|
144
|
-
* Mock HTTP error responses
|
|
145
|
-
*/
|
|
146
|
-
export function mockHttpErrors(status: number = 500) {
|
|
147
|
-
const mockFetch = jest.fn().mockImplementation(() =>
|
|
148
|
-
Promise.resolve(
|
|
149
|
-
new MockResponse({ error: 'Server error' }, { status, statusText: 'Internal Server Error' })
|
|
150
|
-
)
|
|
151
|
-
);
|
|
152
|
-
global.fetch = mockFetch as any;
|
|
153
|
-
return mockFetch;
|
|
154
|
-
}
|
|
155
|
-
|
|
156
|
-
/**
|
|
157
|
-
* Clean up mocks after tests
|
|
158
|
-
*/
|
|
159
|
-
export function cleanupMocks() {
|
|
160
|
-
jest.clearAllMocks();
|
|
161
|
-
// Reset fetch to original if needed
|
|
162
|
-
if (global.fetch && 'mockRestore' in global.fetch) {
|
|
163
|
-
(global.fetch as any).mockRestore();
|
|
164
|
-
}
|
|
165
|
-
}
|
|
@@ -1,319 +0,0 @@
|
|
|
1
|
-
import { PrivateKey } from '@hiveio/dhive';
|
|
2
|
-
import { Streamer } from '../src/streamer';
|
|
3
|
-
import { Utils } from '../src/utils';
|
|
4
|
-
import { action, defineContract } from '../src/contracts/contract';
|
|
5
|
-
import { createMockAdapter } from './helpers/mock-adapter';
|
|
6
|
-
|
|
7
|
-
describe('Hive chain features', () => {
|
|
8
|
-
const activeKey = PrivateKey.fromSeed('hive-stream-active').toString();
|
|
9
|
-
|
|
10
|
-
afterEach(() => {
|
|
11
|
-
jest.restoreAllMocks();
|
|
12
|
-
});
|
|
13
|
-
|
|
14
|
-
describe('Utils multisig + escrow helpers', () => {
|
|
15
|
-
test('broadcastMultiSigOperations signs with multiple keys', async () => {
|
|
16
|
-
const keyOne = PrivateKey.fromSeed('key-one').toString();
|
|
17
|
-
const keyTwo = PrivateKey.fromSeed('key-two').toString();
|
|
18
|
-
const sendOperations = jest.fn().mockResolvedValue({ id: 'tx-id' });
|
|
19
|
-
const client = {
|
|
20
|
-
broadcast: {
|
|
21
|
-
sendOperations
|
|
22
|
-
},
|
|
23
|
-
database: {
|
|
24
|
-
getAccounts: jest.fn().mockResolvedValue([{
|
|
25
|
-
memo_key: 'STMmemo',
|
|
26
|
-
json_metadata: '{}',
|
|
27
|
-
posting_json_metadata: '{}'
|
|
28
|
-
}])
|
|
29
|
-
}
|
|
30
|
-
} as any;
|
|
31
|
-
|
|
32
|
-
await Utils.broadcastMultiSigOperations(client, [['vote', { voter: 'alice' }]], [keyOne, keyTwo]);
|
|
33
|
-
|
|
34
|
-
const passedKeys = sendOperations.mock.calls[0][1];
|
|
35
|
-
expect(Array.isArray(passedKeys)).toBe(true);
|
|
36
|
-
expect(passedKeys).toHaveLength(2);
|
|
37
|
-
});
|
|
38
|
-
|
|
39
|
-
test('updateAccountAuthorities uses account_update2 when posting JSON metadata is provided', async () => {
|
|
40
|
-
const sendOperations = jest.fn().mockResolvedValue({ id: 'tx-id' });
|
|
41
|
-
const client = {
|
|
42
|
-
broadcast: {
|
|
43
|
-
sendOperations
|
|
44
|
-
},
|
|
45
|
-
database: {
|
|
46
|
-
getAccounts: jest.fn().mockResolvedValue([{
|
|
47
|
-
memo_key: 'STMmemo',
|
|
48
|
-
json_metadata: '{}',
|
|
49
|
-
posting_json_metadata: '{}'
|
|
50
|
-
}])
|
|
51
|
-
}
|
|
52
|
-
} as any;
|
|
53
|
-
|
|
54
|
-
await Utils.updateAccountAuthorities(client, { ACTIVE_KEY: activeKey }, 'alice', {
|
|
55
|
-
active: Utils.createAuthority([[`STM${'1'.repeat(50)}`, 1]], [], 1),
|
|
56
|
-
posting_json_metadata: '{}'
|
|
57
|
-
});
|
|
58
|
-
|
|
59
|
-
const operation = sendOperations.mock.calls[0][0][0];
|
|
60
|
-
expect(operation[0]).toBe('account_update2');
|
|
61
|
-
});
|
|
62
|
-
|
|
63
|
-
test('escrowTransfer builds and broadcasts escrow_transfer operation', async () => {
|
|
64
|
-
const sendOperations = jest.fn().mockResolvedValue({ id: 'tx-id' });
|
|
65
|
-
const client = {
|
|
66
|
-
broadcast: {
|
|
67
|
-
sendOperations
|
|
68
|
-
}
|
|
69
|
-
} as any;
|
|
70
|
-
|
|
71
|
-
await Utils.escrowTransfer(client, { ACTIVE_KEY: activeKey }, {
|
|
72
|
-
from: 'alice',
|
|
73
|
-
to: 'bob',
|
|
74
|
-
agent: 'escrow.agent',
|
|
75
|
-
escrow_id: 42,
|
|
76
|
-
hive_amount: '1.000 HIVE',
|
|
77
|
-
hbd_amount: '0.000 HBD',
|
|
78
|
-
fee: '0.001 HIVE',
|
|
79
|
-
ratification_deadline: new Date('2025-01-01T00:00:00.000Z'),
|
|
80
|
-
escrow_expiration: new Date('2025-01-02T00:00:00.000Z'),
|
|
81
|
-
json_meta: { test: true }
|
|
82
|
-
});
|
|
83
|
-
|
|
84
|
-
const operation = sendOperations.mock.calls[0][0][0];
|
|
85
|
-
expect(operation[0]).toBe('escrow_transfer');
|
|
86
|
-
expect(operation[1].escrow_id).toBe(42);
|
|
87
|
-
expect(operation[1].json_meta).toBe(JSON.stringify({ test: true }));
|
|
88
|
-
expect(operation[1].ratification_deadline).toBe('2025-01-01T00:00:00');
|
|
89
|
-
expect(operation[1].escrow_expiration).toBe('2025-01-02T00:00:00');
|
|
90
|
-
});
|
|
91
|
-
});
|
|
92
|
-
|
|
93
|
-
describe('Streamer operation behavior', () => {
|
|
94
|
-
let streamer: Streamer;
|
|
95
|
-
|
|
96
|
-
beforeEach(async () => {
|
|
97
|
-
streamer = new Streamer({
|
|
98
|
-
ACTIVE_KEY: activeKey,
|
|
99
|
-
JSON_ID: 'testing',
|
|
100
|
-
PAYLOAD_IDENTIFIER: 'hive_stream',
|
|
101
|
-
DEBUG_MODE: false
|
|
102
|
-
});
|
|
103
|
-
|
|
104
|
-
await streamer.registerAdapter(createMockAdapter());
|
|
105
|
-
});
|
|
106
|
-
|
|
107
|
-
afterEach(async () => {
|
|
108
|
-
await streamer.stop();
|
|
109
|
-
});
|
|
110
|
-
|
|
111
|
-
test('transferHiveEngineTokens forwards quantity and symbol in correct order', () => {
|
|
112
|
-
const spy = jest.spyOn(Utils, 'transferHiveEngineTokens').mockResolvedValue({} as any);
|
|
113
|
-
|
|
114
|
-
streamer.transferHiveEngineTokens('alice', 'bob', 'TEST', '1.500', 'memo');
|
|
115
|
-
|
|
116
|
-
expect(spy).toHaveBeenCalledWith(
|
|
117
|
-
expect.anything(),
|
|
118
|
-
expect.anything(),
|
|
119
|
-
'alice',
|
|
120
|
-
'bob',
|
|
121
|
-
'1.500',
|
|
122
|
-
'TEST',
|
|
123
|
-
'memo'
|
|
124
|
-
);
|
|
125
|
-
});
|
|
126
|
-
|
|
127
|
-
test('onCustomJsonId only fires callbacks for the matching id', async () => {
|
|
128
|
-
const matching = jest.fn();
|
|
129
|
-
const nonMatching = jest.fn();
|
|
130
|
-
|
|
131
|
-
streamer.onCustomJsonId(matching, 'target-id');
|
|
132
|
-
streamer.onCustomJsonId(nonMatching, 'other-id');
|
|
133
|
-
|
|
134
|
-
await streamer.processOperation([
|
|
135
|
-
'custom_json',
|
|
136
|
-
{
|
|
137
|
-
id: 'target-id',
|
|
138
|
-
json: '{}',
|
|
139
|
-
required_auths: ['alice'],
|
|
140
|
-
required_posting_auths: []
|
|
141
|
-
}
|
|
142
|
-
], 10, 'block-id', 'prev-id', 'trx-id', new Date());
|
|
143
|
-
|
|
144
|
-
expect(matching).toHaveBeenCalledTimes(1);
|
|
145
|
-
expect(nonMatching).not.toHaveBeenCalled();
|
|
146
|
-
});
|
|
147
|
-
|
|
148
|
-
test('onHiveEngine still fires when tx verification lookup fails', async () => {
|
|
149
|
-
const handler = jest.fn();
|
|
150
|
-
const consoleError = jest.spyOn(console, 'error').mockImplementation(() => undefined);
|
|
151
|
-
const getTransactionInfo = jest.spyOn(streamer['hive'], 'getTransactionInfo')
|
|
152
|
-
.mockRejectedValue(new Error('temporary hive engine outage'));
|
|
153
|
-
|
|
154
|
-
streamer.onHiveEngine(handler);
|
|
155
|
-
|
|
156
|
-
await streamer.processOperation([
|
|
157
|
-
'custom_json',
|
|
158
|
-
{
|
|
159
|
-
id: 'ssc-mainnet-hive',
|
|
160
|
-
json: JSON.stringify({
|
|
161
|
-
contractName: 'tokens',
|
|
162
|
-
contractAction: 'transfer',
|
|
163
|
-
contractPayload: {
|
|
164
|
-
symbol: 'TEST',
|
|
165
|
-
to: 'target',
|
|
166
|
-
quantity: '1.000',
|
|
167
|
-
memo: 'memo'
|
|
168
|
-
}
|
|
169
|
-
}),
|
|
170
|
-
required_auths: ['alice'],
|
|
171
|
-
required_posting_auths: []
|
|
172
|
-
}
|
|
173
|
-
], 20, 'block-20', 'block-19', 'trx-20', new Date('2025-01-01T00:00:00.000Z'));
|
|
174
|
-
|
|
175
|
-
expect(getTransactionInfo).toHaveBeenCalledWith('trx-20');
|
|
176
|
-
expect(handler).toHaveBeenCalledWith(
|
|
177
|
-
'tokens',
|
|
178
|
-
'transfer',
|
|
179
|
-
{
|
|
180
|
-
symbol: 'TEST',
|
|
181
|
-
to: 'target',
|
|
182
|
-
quantity: '1.000',
|
|
183
|
-
memo: 'memo'
|
|
184
|
-
},
|
|
185
|
-
'alice',
|
|
186
|
-
expect.objectContaining({ id: 'ssc-mainnet-hive' }),
|
|
187
|
-
20,
|
|
188
|
-
'block-20',
|
|
189
|
-
'block-19',
|
|
190
|
-
'trx-20',
|
|
191
|
-
expect.any(Date)
|
|
192
|
-
);
|
|
193
|
-
|
|
194
|
-
consoleError.mockRestore();
|
|
195
|
-
});
|
|
196
|
-
|
|
197
|
-
test('onHiveEngine does not fire when tx verification reports contract errors', async () => {
|
|
198
|
-
const handler = jest.fn();
|
|
199
|
-
jest.spyOn(streamer['hive'], 'getTransactionInfo').mockResolvedValue({
|
|
200
|
-
logs: JSON.stringify({
|
|
201
|
-
errors: ['boom']
|
|
202
|
-
})
|
|
203
|
-
} as any);
|
|
204
|
-
|
|
205
|
-
streamer.onHiveEngine(handler);
|
|
206
|
-
|
|
207
|
-
await streamer.processOperation([
|
|
208
|
-
'custom_json',
|
|
209
|
-
{
|
|
210
|
-
id: 'ssc-mainnet-hive',
|
|
211
|
-
json: JSON.stringify({
|
|
212
|
-
contractName: 'tokens',
|
|
213
|
-
contractAction: 'transfer',
|
|
214
|
-
contractPayload: {
|
|
215
|
-
symbol: 'TEST',
|
|
216
|
-
to: 'target',
|
|
217
|
-
quantity: '1.000',
|
|
218
|
-
memo: 'memo'
|
|
219
|
-
}
|
|
220
|
-
}),
|
|
221
|
-
required_auths: ['alice'],
|
|
222
|
-
required_posting_auths: []
|
|
223
|
-
}
|
|
224
|
-
], 21, 'block-21', 'block-20', 'trx-21', new Date('2025-01-01T00:00:00.000Z'));
|
|
225
|
-
|
|
226
|
-
expect(handler).not.toHaveBeenCalled();
|
|
227
|
-
});
|
|
228
|
-
|
|
229
|
-
test('processTransfer forwards block metadata into adapter', async () => {
|
|
230
|
-
const adapter = createMockAdapter();
|
|
231
|
-
const processTransferSpy = jest.spyOn(adapter, 'processTransfer');
|
|
232
|
-
await streamer.registerAdapter(adapter);
|
|
233
|
-
await streamer.registerContract(defineContract({
|
|
234
|
-
name: 'sample',
|
|
235
|
-
actions: {
|
|
236
|
-
pay: action(jest.fn(), { trigger: 'transfer' })
|
|
237
|
-
}
|
|
238
|
-
}));
|
|
239
|
-
|
|
240
|
-
await streamer.processOperation([
|
|
241
|
-
'transfer',
|
|
242
|
-
{
|
|
243
|
-
from: 'alice',
|
|
244
|
-
to: 'bob',
|
|
245
|
-
amount: '1.000 HIVE',
|
|
246
|
-
memo: JSON.stringify({
|
|
247
|
-
hive_stream: {
|
|
248
|
-
contract: 'sample',
|
|
249
|
-
action: 'pay',
|
|
250
|
-
payload: { value: 1 }
|
|
251
|
-
}
|
|
252
|
-
})
|
|
253
|
-
}
|
|
254
|
-
], 55, 'block-55', 'block-54', 'trx-55', new Date('2025-01-01T00:00:00.000Z'));
|
|
255
|
-
|
|
256
|
-
expect(processTransferSpy).toHaveBeenCalledWith(
|
|
257
|
-
expect.anything(),
|
|
258
|
-
expect.anything(),
|
|
259
|
-
expect.objectContaining({
|
|
260
|
-
blockNumber: 55,
|
|
261
|
-
blockId: 'block-55',
|
|
262
|
-
previousBlockId: 'block-54',
|
|
263
|
-
transactionId: 'trx-55'
|
|
264
|
-
})
|
|
265
|
-
);
|
|
266
|
-
});
|
|
267
|
-
|
|
268
|
-
test('escrow transfer can trigger a contract action via json_meta payload', async () => {
|
|
269
|
-
const handler = jest.fn();
|
|
270
|
-
const escrowSub = jest.fn();
|
|
271
|
-
|
|
272
|
-
await streamer.registerContract(defineContract({
|
|
273
|
-
name: 'escrowcontract',
|
|
274
|
-
actions: {
|
|
275
|
-
create: action(handler, { trigger: 'escrow_transfer' })
|
|
276
|
-
}
|
|
277
|
-
}));
|
|
278
|
-
|
|
279
|
-
streamer.onEscrowTransfer(escrowSub);
|
|
280
|
-
|
|
281
|
-
await streamer.processOperation([
|
|
282
|
-
'escrow_transfer',
|
|
283
|
-
{
|
|
284
|
-
from: 'alice',
|
|
285
|
-
to: 'bob',
|
|
286
|
-
agent: 'escrow.agent',
|
|
287
|
-
escrow_id: 99,
|
|
288
|
-
hive_amount: '1.000 HIVE',
|
|
289
|
-
hbd_amount: '0.000 HBD',
|
|
290
|
-
fee: '0.001 HIVE',
|
|
291
|
-
ratification_deadline: '2025-01-01T00:00:00',
|
|
292
|
-
escrow_expiration: '2025-01-02T00:00:00',
|
|
293
|
-
json_meta: JSON.stringify({
|
|
294
|
-
hive_stream: {
|
|
295
|
-
contract: 'escrowcontract',
|
|
296
|
-
action: 'create',
|
|
297
|
-
payload: {
|
|
298
|
-
orderId: 'A-1'
|
|
299
|
-
}
|
|
300
|
-
}
|
|
301
|
-
})
|
|
302
|
-
}
|
|
303
|
-
], 100, 'block-100', 'block-99', 'trx-100', new Date('2025-01-01T00:00:00.000Z'));
|
|
304
|
-
|
|
305
|
-
expect(handler).toHaveBeenCalledWith(
|
|
306
|
-
{ orderId: 'A-1' },
|
|
307
|
-
expect.objectContaining({
|
|
308
|
-
trigger: 'escrow_transfer',
|
|
309
|
-
sender: 'alice',
|
|
310
|
-
escrow: expect.objectContaining({
|
|
311
|
-
type: 'escrow_transfer',
|
|
312
|
-
escrowId: 99
|
|
313
|
-
})
|
|
314
|
-
})
|
|
315
|
-
);
|
|
316
|
-
expect(escrowSub).toHaveBeenCalledTimes(1);
|
|
317
|
-
});
|
|
318
|
-
});
|
|
319
|
-
});
|