@rosen-bridge/abstract-extractor 2.0.1 → 2.0.3-52fc0239
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/CHANGELOG.md +14 -0
- package/dist/ergo/AbstractErgoExtractor.d.ts.map +1 -1
- package/dist/ergo/AbstractErgoExtractor.js +3 -2
- package/dist/ergo/AbstractErgoExtractorAction.d.ts +1 -1
- package/dist/ergo/AbstractErgoExtractorAction.d.ts.map +1 -1
- package/dist/ergo/AbstractErgoExtractorAction.js +23 -9
- package/dist/ergo/AbstractErgoExtractorEntity.js +2 -2
- package/dist/ergo/initializable/AbstractInitializableAction.d.ts +1 -1
- package/dist/ergo/initializable/AbstractInitializableAction.d.ts.map +1 -1
- package/dist/ergo/initializable/AbstractInitializableAction.js +4 -2
- package/dist/lib/abstractExtractor.d.ts +25 -0
- package/dist/lib/abstractExtractor.d.ts.map +1 -0
- package/dist/lib/abstractExtractor.js +3 -0
- package/dist/lib/constants.d.ts +4 -0
- package/dist/lib/constants.d.ts.map +1 -0
- package/dist/lib/constants.js +4 -0
- package/dist/lib/ergo/AbstractErgoExtractor.d.ts +80 -0
- package/dist/lib/ergo/AbstractErgoExtractor.d.ts.map +1 -0
- package/dist/lib/ergo/AbstractErgoExtractor.js +143 -0
- package/dist/lib/ergo/AbstractErgoExtractorAction.d.ts +87 -0
- package/dist/lib/ergo/AbstractErgoExtractorAction.d.ts.map +1 -0
- package/dist/lib/ergo/AbstractErgoExtractorAction.js +222 -0
- package/dist/lib/ergo/AbstractErgoExtractorEntity.d.ts +11 -0
- package/dist/lib/ergo/AbstractErgoExtractorEntity.d.ts.map +1 -0
- package/dist/lib/ergo/AbstractErgoExtractorEntity.js +57 -0
- package/dist/lib/ergo/index.d.ts +10 -0
- package/dist/lib/ergo/index.d.ts.map +1 -0
- package/dist/lib/ergo/index.js +10 -0
- package/dist/lib/ergo/initializable/AbstractInitializable.d.ts +48 -0
- package/dist/lib/ergo/initializable/AbstractInitializable.d.ts.map +1 -0
- package/dist/lib/ergo/initializable/AbstractInitializable.js +163 -0
- package/dist/lib/ergo/initializable/AbstractInitializableAction.d.ts +14 -0
- package/dist/lib/ergo/initializable/AbstractInitializableAction.d.ts.map +1 -0
- package/dist/lib/ergo/initializable/AbstractInitializableAction.js +16 -0
- package/dist/lib/ergo/initializable/index.d.ts +3 -0
- package/dist/lib/ergo/initializable/index.d.ts.map +1 -0
- package/dist/lib/ergo/initializable/index.js +3 -0
- package/dist/lib/ergo/interfaces.d.ts +47 -0
- package/dist/lib/ergo/interfaces.d.ts.map +1 -0
- package/dist/lib/ergo/interfaces.js +8 -0
- package/dist/lib/ergo/network/AbstractNetwork.d.ts +26 -0
- package/dist/lib/ergo/network/AbstractNetwork.d.ts.map +1 -0
- package/dist/lib/ergo/network/AbstractNetwork.js +3 -0
- package/dist/lib/ergo/network/ExplorerNetwork.d.ts +74 -0
- package/dist/lib/ergo/network/ExplorerNetwork.d.ts.map +1 -0
- package/dist/lib/ergo/network/ExplorerNetwork.js +185 -0
- package/dist/lib/ergo/network/NodeNetwork.d.ts +60 -0
- package/dist/lib/ergo/network/NodeNetwork.d.ts.map +1 -0
- package/dist/lib/ergo/network/NodeNetwork.js +131 -0
- package/dist/lib/ergo/utils.d.ts +8 -0
- package/dist/lib/ergo/utils.d.ts.map +1 -0
- package/dist/lib/ergo/utils.js +16 -0
- package/dist/lib/index.d.ts +4 -0
- package/dist/lib/index.d.ts.map +1 -0
- package/dist/lib/index.js +4 -0
- package/dist/tests/AbstractErgoExtractor.mock.d.ts +11 -0
- package/dist/tests/AbstractErgoExtractor.mock.d.ts.map +1 -0
- package/dist/tests/AbstractErgoExtractor.mock.js +13 -0
- package/dist/tests/AbstractErgoExtractor.spec.d.ts +2 -0
- package/dist/tests/AbstractErgoExtractor.spec.d.ts.map +1 -0
- package/dist/tests/AbstractErgoExtractor.spec.js +241 -0
- package/dist/tests/AbstractErgoExtractorAction.mock.d.ts +15 -0
- package/dist/tests/AbstractErgoExtractorAction.mock.d.ts.map +1 -0
- package/dist/tests/AbstractErgoExtractorAction.mock.js +27 -0
- package/dist/tests/AbstractErgoExtractorAction.spec.d.ts +2 -0
- package/dist/tests/AbstractErgoExtractorAction.spec.d.ts.map +1 -0
- package/dist/tests/AbstractErgoExtractorAction.spec.js +222 -0
- package/dist/tests/initializable/AbstractInitializable.mock.d.ts +60 -0
- package/dist/tests/initializable/AbstractInitializable.mock.d.ts.map +1 -0
- package/dist/tests/initializable/AbstractInitializable.mock.js +22 -0
- package/dist/tests/initializable/AbstractInitializable.spec.d.ts +2 -0
- package/dist/tests/initializable/AbstractInitializable.spec.d.ts.map +1 -0
- package/dist/tests/initializable/AbstractInitializable.spec.js +300 -0
- package/dist/tests/initializable/AbstractInitializableAction.mock.d.ts +15 -0
- package/dist/tests/initializable/AbstractInitializableAction.mock.d.ts.map +1 -0
- package/dist/tests/initializable/AbstractInitializableAction.mock.js +27 -0
- package/dist/tests/initializable/AbstractInitializableAction.spec.d.ts +2 -0
- package/dist/tests/initializable/AbstractInitializableAction.spec.d.ts.map +1 -0
- package/dist/tests/initializable/AbstractInitializableAction.spec.js +55 -0
- package/dist/tests/initializable/testData.d.ts +94 -0
- package/dist/tests/initializable/testData.d.ts.map +1 -0
- package/dist/tests/initializable/testData.js +235 -0
- package/dist/tests/network/ExplorerNetwork.spec.d.ts +2 -0
- package/dist/tests/network/ExplorerNetwork.spec.d.ts.map +1 -0
- package/dist/tests/network/ExplorerNetwork.spec.js +62 -0
- package/dist/tests/network/NodeNetwork.spec.d.ts +2 -0
- package/dist/tests/network/NodeNetwork.spec.d.ts.map +1 -0
- package/dist/tests/network/NodeNetwork.spec.js +49 -0
- package/dist/tests/network/testData.d.ts +752 -0
- package/dist/tests/network/testData.d.ts.map +1 -0
- package/dist/tests/network/testData.js +1401 -0
- package/dist/tests/testData.d.ts +32 -0
- package/dist/tests/testData.d.ts.map +1 -0
- package/dist/tests/testData.js +121 -0
- package/dist/tests/testUtils.d.ts +9 -0
- package/dist/tests/testUtils.d.ts.map +1 -0
- package/dist/tests/testUtils.js +31 -0
- package/dist/tsconfig.tsbuildinfo +1 -0
- package/dist/vitest.config.d.ts +3 -0
- package/dist/vitest.config.d.ts.map +1 -0
- package/dist/vitest.config.js +17 -0
- package/lib/ergo/AbstractErgoExtractor.ts +3 -1
- package/lib/ergo/AbstractErgoExtractorAction.ts +47 -36
- package/lib/ergo/AbstractErgoExtractorEntity.ts +1 -1
- package/lib/ergo/initializable/AbstractInitializableAction.ts +4 -2
- package/package.json +9 -14
- package/tests/AbstractErgoExtractor.mock.ts +4 -2
- package/tests/AbstractErgoExtractorAction.mock.ts +1 -1
- package/tests/AbstractErgoExtractorAction.spec.ts +1 -1
- package/tests/initializable/AbstractInitializable.mock.ts +13 -4
- package/tests/initializable/AbstractInitializable.spec.ts +1 -9
- package/tests/initializable/AbstractInitializableAction.mock.ts +1 -1
- package/tests/initializable/AbstractInitializableAction.spec.ts +1 -1
- package/tests/testUtils.ts +1 -1
- package/tsconfig.build.tsbuildinfo +1 -1
|
@@ -0,0 +1,185 @@
|
|
|
1
|
+
import ergoExplorerClientFactory from '@rosen-clients/ergo-explorer';
|
|
2
|
+
import { AbstractNetwork } from './AbstractNetwork';
|
|
3
|
+
import { mapValues, pick } from 'lodash-es';
|
|
4
|
+
import { API_LIMIT } from '../../constants';
|
|
5
|
+
export class ExplorerNetwork extends AbstractNetwork {
|
|
6
|
+
api;
|
|
7
|
+
constructor(url) {
|
|
8
|
+
super();
|
|
9
|
+
this.api = ergoExplorerClientFactory(url);
|
|
10
|
+
}
|
|
11
|
+
/**
|
|
12
|
+
* return spending information of a specified box by having spendTxId
|
|
13
|
+
* @param boxId
|
|
14
|
+
* @param spendTxId
|
|
15
|
+
*/
|
|
16
|
+
getSpendingInfo = async (boxId, spendTxId) => {
|
|
17
|
+
const tx = await this.api.v1.getApiV1TransactionsP1(spendTxId);
|
|
18
|
+
const spendIndex = tx.inputs?.findIndex((box) => box.boxId === boxId);
|
|
19
|
+
if (spendIndex == undefined)
|
|
20
|
+
throw Error(`Impossible behavior, the box [${boxId}] should have been spent in tx [${spendTxId}]`);
|
|
21
|
+
return {
|
|
22
|
+
hash: tx.blockId,
|
|
23
|
+
height: tx.inclusionHeight,
|
|
24
|
+
spendIndex,
|
|
25
|
+
};
|
|
26
|
+
};
|
|
27
|
+
/**
|
|
28
|
+
* convert explorer api boxes to ErgoBox interface
|
|
29
|
+
* @param box
|
|
30
|
+
* @returns ErgoBox
|
|
31
|
+
*/
|
|
32
|
+
convertBox = async (box) => {
|
|
33
|
+
const spendInfo = box.spentTransactionId
|
|
34
|
+
? await this.getSpendingInfo(box.boxId, box.spentTransactionId)
|
|
35
|
+
: undefined;
|
|
36
|
+
return {
|
|
37
|
+
blockId: box.blockId,
|
|
38
|
+
boxId: box.boxId,
|
|
39
|
+
creationHeight: box.creationHeight,
|
|
40
|
+
inclusionHeight: box.settlementHeight,
|
|
41
|
+
ergoTree: box.ergoTree,
|
|
42
|
+
index: box.index,
|
|
43
|
+
transactionId: box.transactionId,
|
|
44
|
+
value: box.value,
|
|
45
|
+
additionalRegisters: mapValues(box.additionalRegisters, 'serializedValue'),
|
|
46
|
+
assets: box.assets?.map((asset) => pick(asset, ['tokenId', 'amount'])) ?? [],
|
|
47
|
+
spentHeight: spendInfo?.height,
|
|
48
|
+
spentBlockId: spendInfo?.hash,
|
|
49
|
+
spentTransactionId: box.spentTransactionId,
|
|
50
|
+
spentIndex: spendInfo?.spendIndex,
|
|
51
|
+
};
|
|
52
|
+
};
|
|
53
|
+
/**
|
|
54
|
+
* convert explorer transaction to extractor transaction type
|
|
55
|
+
* @param tx
|
|
56
|
+
*/
|
|
57
|
+
convertTransaction = (tx) => {
|
|
58
|
+
return {
|
|
59
|
+
id: tx.id,
|
|
60
|
+
inclusionHeight: tx.inclusionHeight,
|
|
61
|
+
blockId: tx.blockId,
|
|
62
|
+
dataInputs: tx.dataInputs?.map((dataInput) => ({
|
|
63
|
+
boxId: dataInput.boxId,
|
|
64
|
+
})) ?? [],
|
|
65
|
+
// TODO: Add input extension to explorer local/ergo/rosen-bridge/scanner/-/issues/156
|
|
66
|
+
inputs: tx.inputs?.map((input) => ({ boxId: input.boxId })) ?? [],
|
|
67
|
+
outputs: tx.outputs?.map((output) => ({
|
|
68
|
+
boxId: output.boxId,
|
|
69
|
+
transactionId: output.transactionId,
|
|
70
|
+
additionalRegisters: mapValues(output.additionalRegisters, 'serializedValue'),
|
|
71
|
+
assets: output.assets?.map((asset) => pick(asset, ['tokenId', 'amount'])) ??
|
|
72
|
+
[],
|
|
73
|
+
ergoTree: output.ergoTree,
|
|
74
|
+
creationHeight: output.creationHeight,
|
|
75
|
+
index: output.index,
|
|
76
|
+
value: output.value,
|
|
77
|
+
})) ?? [],
|
|
78
|
+
};
|
|
79
|
+
};
|
|
80
|
+
/**
|
|
81
|
+
* convert explorer block transaction to transaction type
|
|
82
|
+
* @param tx
|
|
83
|
+
*/
|
|
84
|
+
convertBlockTransaction = (tx) => {
|
|
85
|
+
return {
|
|
86
|
+
id: tx.id,
|
|
87
|
+
dataInputs: tx.dataInputs?.map((dataInput) => ({
|
|
88
|
+
boxId: dataInput.id,
|
|
89
|
+
})) ?? [],
|
|
90
|
+
// TODO: Add input extension local/ergo/rosen-bridge/scanner/-/issues/156
|
|
91
|
+
inputs: tx.inputs?.map((input) => ({ boxId: input.id })) ?? [],
|
|
92
|
+
outputs: tx.outputs?.map((output) => ({
|
|
93
|
+
boxId: output.id,
|
|
94
|
+
transactionId: output.txId,
|
|
95
|
+
additionalRegisters: output.additionalRegisters,
|
|
96
|
+
assets: output.assets?.map((asset) => pick(asset, ['tokenId', 'amount'])) ??
|
|
97
|
+
[],
|
|
98
|
+
ergoTree: output.ergoTree,
|
|
99
|
+
creationHeight: output.creationHeight,
|
|
100
|
+
index: output.index,
|
|
101
|
+
value: output.value,
|
|
102
|
+
})) ?? [],
|
|
103
|
+
};
|
|
104
|
+
};
|
|
105
|
+
/**
|
|
106
|
+
* use explorer api to return related transactions of the specified address in the height range
|
|
107
|
+
* @param tokenId
|
|
108
|
+
* @param offset
|
|
109
|
+
* @param limit
|
|
110
|
+
* @returns related transactions
|
|
111
|
+
*/
|
|
112
|
+
getAddressTransactionsWithHeight = async (address, fromHeight, toHeight) => {
|
|
113
|
+
const txs = await this.api.v1.getApiV1AddressesP1Transactions(address, {
|
|
114
|
+
fromHeight,
|
|
115
|
+
toHeight,
|
|
116
|
+
limit: API_LIMIT,
|
|
117
|
+
});
|
|
118
|
+
if (!txs.items)
|
|
119
|
+
throw new Error('Explorer AddressTransactions api expected to have items');
|
|
120
|
+
return txs.items.map((tx) => this.convertTransaction(tx));
|
|
121
|
+
};
|
|
122
|
+
/**
|
|
123
|
+
* use explorer api to get the block id at the specified height
|
|
124
|
+
* @param height
|
|
125
|
+
* @returns block id
|
|
126
|
+
*/
|
|
127
|
+
getBlockIdAtHeight = async (height) => {
|
|
128
|
+
const id = await this.api.v0.getApiV0BlocksAtP1(height);
|
|
129
|
+
return id[0];
|
|
130
|
+
};
|
|
131
|
+
/**
|
|
132
|
+
* use explorer api to return all transactions in a block
|
|
133
|
+
* @param blockId
|
|
134
|
+
* @returns converted transactions
|
|
135
|
+
*/
|
|
136
|
+
getBlockTxs = async (blockId) => {
|
|
137
|
+
const block = await this.api.v1.getApiV1BlocksP1(blockId);
|
|
138
|
+
if (!block.block.blockTransactions) {
|
|
139
|
+
throw new Error(`Expected explorer block api to include block transactions for block ${blockId}`);
|
|
140
|
+
}
|
|
141
|
+
return block.block.blockTransactions.map((tx) => this.convertBlockTransaction(tx));
|
|
142
|
+
};
|
|
143
|
+
/**
|
|
144
|
+
* use explorer api to return related boxes by specified address
|
|
145
|
+
* @param address
|
|
146
|
+
* @param offset
|
|
147
|
+
* @param limit
|
|
148
|
+
* @returns related boxes
|
|
149
|
+
*/
|
|
150
|
+
getBoxesByAddress = async (address, offset, limit) => {
|
|
151
|
+
const boxes = await this.api.v1.getApiV1BoxesUnspentByaddressP1(address, {
|
|
152
|
+
offset: offset,
|
|
153
|
+
limit: limit,
|
|
154
|
+
sortDirection: 'desc',
|
|
155
|
+
});
|
|
156
|
+
if (!boxes.items)
|
|
157
|
+
throw new Error('Explorer BoxesByAddress api expected to have items');
|
|
158
|
+
const resultBoxes = [];
|
|
159
|
+
for (const box of boxes.items) {
|
|
160
|
+
resultBoxes.push(await this.convertBox(box));
|
|
161
|
+
}
|
|
162
|
+
return { boxes: resultBoxes, hasNextBatch: boxes.total > offset + limit };
|
|
163
|
+
};
|
|
164
|
+
/**
|
|
165
|
+
* use explorer api to return related boxes by specified token id
|
|
166
|
+
* @param tokenId
|
|
167
|
+
* @param offset
|
|
168
|
+
* @param limit
|
|
169
|
+
* @returns related boxes
|
|
170
|
+
*/
|
|
171
|
+
getBoxesByTokenId = async (tokenId, offset, limit) => {
|
|
172
|
+
const boxes = await this.api.v1.getApiV1BoxesBytokenidP1(tokenId, {
|
|
173
|
+
offset: offset,
|
|
174
|
+
limit: limit,
|
|
175
|
+
});
|
|
176
|
+
if (!boxes.items)
|
|
177
|
+
throw new Error('Explorer BoxesByTokeId api expected to have items');
|
|
178
|
+
const resultBoxes = [];
|
|
179
|
+
for (const box of boxes.items) {
|
|
180
|
+
resultBoxes.push(await this.convertBox(box));
|
|
181
|
+
}
|
|
182
|
+
return { boxes: resultBoxes, hasNextBatch: boxes.total > offset + limit };
|
|
183
|
+
};
|
|
184
|
+
}
|
|
185
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiRXhwbG9yZXJOZXR3b3JrLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vbGliL2VyZ28vbmV0d29yay9FeHBsb3Jlck5ldHdvcmsudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyx5QkFBeUIsTUFBTSw4QkFBOEIsQ0FBQztBQUNyRSxPQUFPLEVBQUUsZUFBZSxFQUFFLE1BQU0sbUJBQW1CLENBQUM7QUFLcEQsT0FBTyxFQUFFLFNBQVMsRUFBRSxJQUFJLEVBQUUsTUFBTSxXQUFXLENBQUM7QUFDNUMsT0FBTyxFQUFFLFNBQVMsRUFBRSxNQUFNLGlCQUFpQixDQUFDO0FBRTVDLE1BQU0sT0FBTyxlQUFnQixTQUFRLGVBQWU7SUFDMUMsR0FBRyxDQUFDO0lBRVosWUFBWSxHQUFXO1FBQ3JCLEtBQUssRUFBRSxDQUFDO1FBQ1IsSUFBSSxDQUFDLEdBQUcsR0FBRyx5QkFBeUIsQ0FBQyxHQUFHLENBQUMsQ0FBQztJQUM1QyxDQUFDO0lBRUQ7Ozs7T0FJRztJQUNILGVBQWUsR0FBRyxLQUFLLEVBQ3JCLEtBQWEsRUFDYixTQUFpQixFQUM0QixFQUFFO1FBQy9DLE1BQU0sRUFBRSxHQUFHLE1BQU0sSUFBSSxDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUMsc0JBQXNCLENBQUMsU0FBUyxDQUFDLENBQUM7UUFDL0QsTUFBTSxVQUFVLEdBQUcsRUFBRSxDQUFDLE1BQU0sRUFBRSxTQUFTLENBQUMsQ0FBQyxHQUFHLEVBQUUsRUFBRSxDQUFDLEdBQUcsQ0FBQyxLQUFLLEtBQUssS0FBSyxDQUFDLENBQUM7UUFDdEUsSUFBSSxVQUFVLElBQUksU0FBUztZQUN6QixNQUFNLEtBQUssQ0FDVCxpQ0FBaUMsS0FBSyxtQ0FBbUMsU0FBUyxHQUFHLENBQ3RGLENBQUM7UUFDSixPQUFPO1lBQ0wsSUFBSSxFQUFFLEVBQUUsQ0FBQyxPQUFPO1lBQ2hCLE1BQU0sRUFBRSxFQUFFLENBQUMsZUFBZTtZQUMxQixVQUFVO1NBQ1gsQ0FBQztJ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RSxNQUFNLFdBQVcsR0FBbUIsRUFBRSxDQUFDO1FBQ3ZDLEtBQUssTUFBTSxHQUFHLElBQUksS0FBSyxDQUFDLEtBQUssRUFBRSxDQUFDO1lBQzlCLFdBQVcsQ0FBQyxJQUFJLENBQUMsTUFBTSxJQUFJLENBQUMsVUFBVSxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUM7UUFDL0MsQ0FBQztRQUNELE9BQU8sRUFBRSxLQUFLLEVBQUUsV0FBVyxFQUFFLFlBQVksRUFBRSxLQUFLLENBQUMsS0FBSyxHQUFHLE1BQU0sR0FBRyxLQUFLLEVBQUUsQ0FBQztJQUM1RSxDQUFDLENBQUM7Q0FDSCIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCBlcmdvRXhwbG9yZXJDbGllbnRGYWN0b3J5IGZyb20gJ0Byb3Nlbi1jbGllbnRzL2VyZ28tZXhwbG9yZXInO1xuaW1wb3J0IHsgQWJzdHJhY3ROZXR3b3JrIH0gZnJvbSAnLi9BYnN0cmFjdE5ldHdvcmsnO1xuaW1wb3J0IHsgVjEgfSBmcm9tICdAcm9zZW4tY2xpZW50cy9lcmdvLWV4cGxvcmVyJztcbmltcG9ydCB7IEJsb2NrSW5mbywgVHJhbnNhY3Rpb24gfSBmcm9tICdAcm9zZW4tYnJpZGdlL3NjYW5uZXItaW50ZXJmYWNlcyc7XG5cbmltcG9ydCB7IEVyZ29Cb3gsIEV4dGVuZGVkVHJhbnNhY3Rpb24gfSBmcm9tICcuLi9pbnRlcmZhY2VzJztcbmltcG9ydCB7IG1hcFZhbHVlcywgcGljayB9IGZyb20gJ2xvZGFzaC1lcyc7XG5pbXBvcnQgeyBBUElfTElNSVQgfSBmcm9tICcuLi8uLi9jb25zdGFudHMnO1xuXG5leHBvcnQgY2xhc3MgRXhwbG9yZXJOZXR3b3JrIGV4dGVuZHMgQWJzdHJhY3ROZXR3b3JrIHtcbiAgcHJpdmF0ZSBhcGk7XG5cbiAgY29uc3RydWN0b3IodXJsOiBzdHJpbmcpIHtcbiAgICBzdXBlcigpO1xuICAgIHRoaXMuYXBpID0gZXJnb0V4cGxvcmVyQ2xpZW50RmFjdG9yeSh1cmwpO1xuICB9XG5cbiAgLyoqXG4gICAqIHJldHVybiBzcGVuZGluZyBpbmZvcm1hdGlvbiBvZiBhIHNwZWNpZmllZCBib3ggYnkgaGF2aW5nIHNwZW5kVHhJZFxuICAgKiBAcGFyYW0gYm94SWRcbiAgICogQHBhcmFtIHNwZW5kVHhJZFxuICAgKi9cbiAgZ2V0U3BlbmRpbmdJbmZvID0gYXN5bmMgKFxuICAgIGJveElkOiBzdHJpbmcsXG4gICAgc3BlbmRUeElkOiBzdHJpbmdcbiAgKTogUHJvbWlzZTxCbG9ja0luZm8gJiB7IHNwZW5kSW5kZXg6IG51bWJlciB9PiA9PiB7XG4gICAgY29uc3QgdHggPSBhd2FpdCB0aGlzLmFwaS52MS5nZXRBcGlWMVRyYW5zYWN0aW9uc1AxKHNwZW5kVHhJZCk7XG4gICAgY29uc3Qgc3BlbmRJbmRleCA9IHR4LmlucHV0cz8uZmluZEluZGV4KChib3gpID0+IGJveC5ib3hJZCA9PT0gYm94SWQpO1xuICAgIGlmIChzcGVuZEluZGV4ID09IHVuZGVmaW5lZClcbiAgICAgIHRocm93IEVycm9yKFxuICAgICAgICBgSW1wb3NzaWJsZSBiZWhhdmlvciwgdGhlIGJveCBbJHtib3hJZH1dIHNob3VsZCBoYXZlIGJlZW4gc3BlbnQgaW4gdHggWyR7c3BlbmRUeElkfV1gXG4gICAgICApO1xuICAgIHJldHVybiB7XG4gICAgICBoYXNoOiB0eC5ibG9ja0lkLFxuICAgICAgaGVpZ2h0OiB0eC5pbmNsdXNpb25IZWlnaHQsXG4gICAgICBzcGVuZEluZGV4LFxuICAgIH07XG4gIH07XG5cbiAgLyoqXG4gICAqIGNvbnZlcnQgZXhwbG9yZXIgYXBpIGJveGVzIHRvIEVyZ29Cb3ggaW50ZXJmYWNlXG4gICAqIEBwYXJhbSBib3hcbiAgICogQHJldHVybnMgRXJnb0JveFxuICAgKi9cbiAgcHJpdmF0ZSBjb252ZXJ0Qm94ID0gYXN5bmMgKGJveDogVjEuT3V0cHV0SW5mbyk6IFByb21pc2U8RXJnb0JveD4gPT4ge1xuICAgIGNvbnN0IHNwZW5kSW5mbyA9IGJveC5zcGVudFRyYW5zYWN0aW9uSWRcbiAgICAgID8gYXdhaXQgdGhpcy5nZXRTcGVuZGluZ0luZm8oYm94LmJveElkLCBib3guc3BlbnRUcmFuc2FjdGlvbklkKVxuICAgICAgOiB1bmRlZmluZWQ7XG4gICAgcmV0dXJuIHtcbiAgICAgIGJsb2NrSWQ6IGJveC5ibG9ja0lkLFxuICAgICAgYm94SWQ6IGJveC5ib3hJZCxcbiAgICAgIGNyZWF0aW9uSGVpZ2h0OiBib3guY3JlYXRpb25IZWlnaHQsXG4gICAgICBpbmNsdXNpb25IZWlnaHQ6IGJveC5zZXR0bGVtZW50SGVpZ2h0LFxuICAgICAgZXJnb1RyZWU6IGJveC5lcmdvVHJlZSxcbiAgICAgIGluZGV4OiBib3guaW5kZXgsXG4gICAgICB0cmFuc2FjdGlvbklkOiBib3gudHJhbnNhY3Rpb25JZCxcbiAgICAgIHZhbHVlOiBib3gudmFsdWUsXG4gICAgICBhZGRpdGlvbmFsUmVnaXN0ZXJzOiBtYXBWYWx1ZXMoXG4gICAgICAgIGJveC5hZGRpdGlvbmFsUmVnaXN0ZXJzLFxuICAgICAgICAnc2VyaWFsaXplZFZhbHVlJ1xuICAgICAgKSxcbiAgICAgIGFzc2V0czpcbiAgICAgICAgYm94LmFzc2V0cz8ubWFwKChhc3NldCkgPT4gcGljayhhc3NldCwgWyd0b2tlbklkJywgJ2Ftb3VudCddKSkgPz8gW10sXG4gICAgICBzcGVudEhlaWdodDogc3BlbmRJbmZvPy5oZWlnaHQsXG4gICAgICBzcGVudEJsb2NrSWQ6IHNwZW5kSW5mbz8uaGFzaCxcbiAgICAgIHNwZW50VHJhbnNhY3Rpb25JZDogYm94LnNwZW50VHJhbnNhY3Rpb25JZCxcbiAgICAgIHNwZW50SW5kZXg6IHNwZW5kSW5mbz8uc3BlbmRJbmRleCxcbiAgICB9O1xuICB9O1xuXG4gIC8qKlxuICAgKiBjb252ZXJ0IGV4cGxvcmVyIHRyYW5zYWN0aW9uIHRvIGV4dHJhY3RvciB0cmFuc2FjdGlvbiB0eXBlXG4gICAqIEBwYXJhbSB0eFxuICAgKi9cbiAgcHJpdmF0ZSBjb252ZXJ0VHJhbnNhY3Rpb24gPSAoXG4gICAgdHg6IFYxLlRyYW5zYWN0aW9uSW5mb1xuICApOiBFeHRlbmRlZFRyYW5zYWN0aW9uID0+IHtcbiAgICByZXR1cm4ge1xuICAgICAgaWQ6IHR4LmlkLFxuICAgICAgaW5jbHVzaW9uSGVpZ2h0OiB0eC5pbmNsdXNpb25IZWlnaHQsXG4gICAgICBibG9ja0lkOiB0eC5ibG9ja0lkLFxuICAgICAgZGF0YUlucHV0czpcbiAgICAgICAgdHguZGF0YUlucHV0cz8ubWFwKChkYXRhSW5wdXQpID0+ICh7XG4gICAgICAgICAgYm94SWQ6IGRhdGFJbnB1dC5ib3hJZCxcbiAgICAgICAgfSkpID8/IFtdLFxuICAgICAgLy8gVE9ETzogQWRkIGlucHV0IGV4dGVuc2lvbiB0byBleHBsb3JlciBsb2NhbC9lcmdvL3Jvc2VuLWJyaWRnZS9zY2FubmVyLy0vaXNzdWVzLzE1NlxuICAgICAgaW5wdXRzOiB0eC5pbnB1dHM/Lm1hcCgoaW5wdXQpID0+ICh7IGJveElkOiBpbnB1dC5ib3hJZCB9KSkgPz8gW10sXG4gICAgICBvdXRwdXRzOlxuICAgICAgICB0eC5vdXRwdXRzPy5tYXAoKG91dHB1dCkgPT4gKHtcbiAgICAgICAgICBib3hJZDogb3V0cHV0LmJveElkLFxuICAgICAgICAgIHRyYW5zYWN0aW9uSWQ6IG91dHB1dC50cmFuc2FjdGlvbklkLFxuICAgICAgICAgIGFkZGl0aW9uYWxSZWdpc3RlcnM6IG1hcFZhbHVlcyhcbiAgICAgICAgICAgIG91dHB1dC5hZGRpdGlvbmFsUmVnaXN0ZXJzLFxuICAgICAgICAgICAgJ3NlcmlhbGl6ZWRWYWx1ZSdcbiAgICAgICAgICApLFxuICAgICAgICAgIGFzc2V0czpcbiAgICAgICAgICAgIG91dHB1dC5hc3NldHM/Lm1hcCgoYXNzZXQpID0+IHBpY2soYXNzZXQsIFsndG9rZW5JZCcsICdhbW91bnQnXSkpID8/XG4gICAgICAgICAgICBbXSxcbiAgICAgICAgICBlcmdvVHJlZTogb3V0cHV0LmVyZ29UcmVlLFxuICAgICAgICAgIGNyZWF0aW9uSGVpZ2h0OiBvdXRwdXQuY3JlYXRpb25IZWlnaHQsXG4gICAgICAgICAgaW5kZXg6IG91dHB1dC5pbmRleCxcbiAgICAgICAgICB2YWx1ZTogb3V0cHV0LnZhbHVlLFxuICAgICAgICB9KSkgPz8gW10sXG4gICAgfTtcbiAgfTtcblxuICAvKipcbiAgICogY29udmVydCBleHBsb3JlciBibG9jayB0cmFuc2FjdGlvbiB0byB0cmFuc2FjdGlvbiB0eXBlXG4gICAqIEBwYXJhbSB0eFxuICAgKi9cbiAgcHJpdmF0ZSBjb252ZXJ0QmxvY2tUcmFuc2FjdGlvbiA9ICh0eDogVjEuVHJhbnNhY3Rpb25JbmZvMSk6IFRyYW5zYWN0aW9uID0+IHtcbiAgICByZXR1cm4ge1xuICAgICAgaWQ6IHR4LmlkLFxuICAgICAgZGF0YUlucHV0czpcbiAgICAgICAgdHguZGF0YUlucHV0cz8ubWFwKChkYXRhSW5wdXQpID0+ICh7XG4gICAgICAgICAgYm94SWQ6IGRhdGFJbnB1dC5pZCxcbiAgICAgICAgfSkpID8/IFtdLFxuICAgICAgLy8gVE9ETzogQWRkIGlucHV0IGV4dGVuc2lvbiBsb2NhbC9lcmdvL3Jvc2VuLWJyaWRnZS9zY2FubmVyLy0vaXNzdWVzLzE1NlxuICAgICAgaW5wdXRzOiB0eC5pbnB1dHM/Lm1hcCgoaW5wdXQpID0+ICh7IGJveElkOiBpbnB1dC5pZCB9KSkgPz8gW10sXG4gICAgICBvdXRwdXRzOlxuICAgICAgICB0eC5vdXRwdXRzPy5tYXAoKG91dHB1dCkgPT4gKHtcbiAgICAgICAgICBib3hJZDogb3V0cHV0LmlkLFxuICAgICAgICAgIHRyYW5zYWN0aW9uSWQ6IG91dHB1dC50eElkLFxuICAgICAgICAgIGFkZGl0aW9uYWxSZWdpc3RlcnM6IG91dHB1dC5hZGRpdGlvbmFsUmVnaXN0ZXJzLFxuICAgICAgICAgIGFzc2V0czpcbiAgICAgICAgICAgIG91dHB1dC5hc3NldHM/Lm1hcCgoYXNzZXQpID0+IHBpY2soYXNzZXQsIFsndG9rZW5JZCcsICdhbW91bnQnXSkpID8/XG4gICAgICAgICAgICBbXSxcbiAgICAgICAgICBlcmdvVHJlZTogb3V0cHV0LmVyZ29UcmVlLFxuICAgICAgICAgIGNyZWF0aW9uSGVpZ2h0OiBvdXRwdXQuY3JlYXRpb25IZWlnaHQsXG4gICAgICAgICAgaW5kZXg6IG91dHB1dC5pbmRleCxcbiAgICAgICAgICB2YWx1ZTogb3V0cHV0LnZhbHVlLFxuICAgICAgICB9KSkgPz8gW10sXG4gICAgfTtcbiAgfTtcblxuICAvKipcbiAgICogdXNlIGV4cGxvcmVyIGFwaSB0byByZXR1cm4gcmVsYXRlZCB0cmFuc2FjdGlvbnMgb2YgdGhlIHNwZWNpZmllZCBhZGRyZXNzIGluIHRoZSBoZWlnaHQgcmFuZ2VcbiAgICogQHBhcmFtIHRva2VuSWRcbiAgICogQHBhcmFtIG9mZnNldFxuICAgKiBAcGFyYW0gbGltaXRcbiAgICogQHJldHVybnMgcmVsYXRlZCB0cmFuc2FjdGlvbnNcbiAgICovXG4gIGdldEFkZHJlc3NUcmFuc2FjdGlvbnNXaXRoSGVpZ2h0ID0gYXN5bmMgKFxuICAgIGFkZHJlc3M6IHN0cmluZyxcbiAgICBmcm9tSGVpZ2h0OiBudW1iZXIsXG4gICAgdG9IZWlnaHQ6IG51bWJlclxuICApOiBQcm9taXNlPEFycmF5PEV4dGVuZGVkVHJhbnNhY3Rpb24+PiA9PiB7XG4gICAgY29uc3QgdHhzID0gYXdhaXQgdGhpcy5hcGkudjEuZ2V0QXBpVjFBZGRyZXNzZXNQMVRyYW5zYWN0aW9ucyhhZGRyZXNzLCB7XG4gICAgICBmcm9tSGVpZ2h0LFxuICAgICAgdG9IZWlnaHQsXG4gICAgICBsaW1pdDogQVBJX0xJTUlULFxuICAgIH0pO1xuICAgIGlmICghdHhzLml0ZW1zKVxuICAgICAgdGhyb3cgbmV3IEVycm9yKFxuICAgICAgICAnRXhwbG9yZXIgQWRkcmVzc1RyYW5zYWN0aW9ucyBhcGkgZXhwZWN0ZWQgdG8gaGF2ZSBpdGVtcydcbiAgICAgICk7XG4gICAgcmV0dXJuIHR4cy5pdGVtcy5tYXAoKHR4KSA9PiB0aGlzLmNvbnZlcnRUcmFuc2FjdGlvbih0eCkpO1xuICB9O1xuXG4gIC8qKlxuICAgKiB1c2UgZXhwbG9yZXIgYXBpIHRvIGdldCB0aGUgYmxvY2sgaWQgYXQgdGhlIHNwZWNpZmllZCBoZWlnaHRcbiAgICogQHBhcmFtIGhlaWdodFxuICAgKiBAcmV0dXJucyBibG9jayBpZFxuICAgKi9cbiAgZ2V0QmxvY2tJZEF0SGVpZ2h0ID0gYXN5bmMgKGhlaWdodDogbnVtYmVyKTogUHJvbWlzZTxzdHJpbmc+ID0+IHtcbiAgICBjb25zdCBpZCA9IGF3YWl0IHRoaXMuYXBpLnYwLmdldEFwaVYwQmxvY2tzQXRQMShoZWlnaHQpO1xuICAgIHJldHVybiBpZFswXTtcbiAgfTtcblxuICAvKipcbiAgICogdXNlIGV4cGxvcmVyIGFwaSB0byByZXR1cm4gYWxsIHRyYW5zYWN0aW9ucyBpbiBhIGJsb2NrXG4gICAqIEBwYXJhbSBibG9ja0lkXG4gICAqIEByZXR1cm5zIGNvbnZlcnRlZCB0cmFuc2FjdGlvbnNcbiAgICovXG4gIGdldEJsb2NrVHhzID0gYXN5bmMgKGJsb2NrSWQ6IHN0cmluZyk6IFByb21pc2U8QXJyYXk8VHJhbnNhY3Rpb24+PiA9PiB7XG4gICAgY29uc3QgYmxvY2sgPSBhd2FpdCB0aGlzLmFwaS52MS5nZXRBcGlWMUJsb2Nrc1AxKGJsb2NrSWQpO1xuICAgIGlmICghYmxvY2suYmxvY2suYmxvY2tUcmFuc2FjdGlvbnMpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihcbiAgICAgICAgYEV4cGVjdGVkIGV4cGxvcmVyIGJsb2NrIGFwaSB0byBpbmNsdWRlIGJsb2NrIHRyYW5zYWN0aW9ucyBmb3IgYmxvY2sgJHtibG9ja0lkfWBcbiAgICAgICk7XG4gICAgfVxuICAgIHJldHVybiBibG9jay5ibG9jay5ibG9ja1RyYW5zYWN0aW9ucy5tYXAoKHR4KSA9PlxuICAgICAgdGhpcy5jb252ZXJ0QmxvY2tUcmFuc2FjdGlvbih0eClcbiAgICApO1xuICB9O1xuXG4gIC8qKlxuICAgKiB1c2UgZXhwbG9yZXIgYXBpIHRvIHJldHVybiByZWxhdGVkIGJveGVzIGJ5IHNwZWNpZmllZCBhZGRyZXNzXG4gICAqIEBwYXJhbSBhZGRyZXNzXG4gICAqIEBwYXJhbSBvZmZzZXRcbiAgICogQHBhcmFtIGxpbWl0XG4gICAqIEByZXR1cm5zIHJlbGF0ZWQgYm94ZXNcbiAgICovXG4gIGdldEJveGVzQnlBZGRyZXNzID0gYXN5bmMgKFxuICAgIGFkZHJlc3M6IHN0cmluZyxcbiAgICBvZmZzZXQ6IG51bWJlcixcbiAgICBsaW1pdDogbnVtYmVyXG4gICk6IFByb21pc2U8eyBib3hlczogRXJnb0JveFtdOyBoYXNOZXh0QmF0Y2g6IGJvb2xlYW4gfT4gPT4ge1xuICAgIGNvbnN0IGJveGVzID0gYXdhaXQgdGhpcy5hcGkudjEuZ2V0QXBpVjFCb3hlc1Vuc3BlbnRCeWFkZHJlc3NQMShhZGRyZXNzLCB7XG4gICAgICBvZmZzZXQ6IG9mZnNldCxcbiAgICAgIGxpbWl0OiBsaW1pdCxcbiAgICAgIHNvcnREaXJlY3Rpb246ICdkZXNjJyxcbiAgICB9KTtcbiAgICBpZiAoIWJveGVzLml0ZW1zKVxuICAgICAgdGhyb3cgbmV3IEVycm9yKCdFeHBsb3JlciBCb3hlc0J5QWRkcmVzcyBhcGkgZXhwZWN0ZWQgdG8gaGF2ZSBpdGVtcycpO1xuICAgIGNvbnN0IHJlc3VsdEJveGVzOiBBcnJheTxFcmdvQm94PiA9IFtdO1xuICAgIGZvciAoY29uc3QgYm94IG9mIGJveGVzLml0ZW1zKSB7XG4gICAgICByZXN1bHRCb3hlcy5wdXNoKGF3YWl0IHRoaXMuY29udmVydEJveChib3gpKTtcbiAgICB9XG4gICAgcmV0dXJuIHsgYm94ZXM6IHJlc3VsdEJveGVzLCBoYXNOZXh0QmF0Y2g6IGJveGVzLnRvdGFsID4gb2Zmc2V0ICsgbGltaXQgfTtcbiAgfTtcblxuICAvKipcbiAgICogdXNlIGV4cGxvcmVyIGFwaSB0byByZXR1cm4gcmVsYXRlZCBib3hlcyBieSBzcGVjaWZpZWQgdG9rZW4gaWRcbiAgICogQHBhcmFtIHRva2VuSWRcbiAgICogQHBhcmFtIG9mZnNldFxuICAgKiBAcGFyYW0gbGltaXRcbiAgICogQHJldHVybnMgcmVsYXRlZCBib3hlc1xuICAgKi9cbiAgZ2V0Qm94ZXNCeVRva2VuSWQgPSBhc3luYyAoXG4gICAgdG9rZW5JZDogc3RyaW5nLFxuICAgIG9mZnNldDogbnVtYmVyLFxuICAgIGxpbWl0OiBudW1iZXJcbiAgKTogUHJvbWlzZTx7IGJveGVzOiBFcmdvQm94W107IGhhc05leHRCYXRjaDogYm9vbGVhbiB9PiA9PiB7XG4gICAgY29uc3QgYm94ZXMgPSBhd2FpdCB0aGlzLmFwaS52MS5nZXRBcGlWMUJveGVzQnl0b2tlbmlkUDEodG9rZW5JZCwge1xuICAgICAgb2Zmc2V0OiBvZmZzZXQsXG4gICAgICBsaW1pdDogbGltaXQsXG4gICAgfSk7XG4gICAgaWYgKCFib3hlcy5pdGVtcylcbiAgICAgIHRocm93IG5ldyBFcnJvcignRXhwbG9yZXIgQm94ZXNCeVRva2VJZCBhcGkgZXhwZWN0ZWQgdG8gaGF2ZSBpdGVtcycpO1xuICAgIGNvbnN0IHJlc3VsdEJveGVzOiBBcnJheTxFcmdvQm94PiA9IFtdO1xuICAgIGZvciAoY29uc3QgYm94IG9mIGJveGVzLml0ZW1zKSB7XG4gICAgICByZXN1bHRCb3hlcy5wdXNoKGF3YWl0IHRoaXMuY29udmVydEJveChib3gpKTtcbiAgICB9XG4gICAgcmV0dXJuIHsgYm94ZXM6IHJlc3VsdEJveGVzLCBoYXNOZXh0QmF0Y2g6IGJveGVzLnRvdGFsID4gb2Zmc2V0ICsgbGltaXQgfTtcbiAgfTtcbn1cbiJdfQ==
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
import { BlockInfo } from '@rosen-bridge/scanner-interfaces';
|
|
2
|
+
import { ErgoBox, ExtendedTransaction } from '../interfaces';
|
|
3
|
+
import { AbstractNetwork } from './AbstractNetwork';
|
|
4
|
+
export declare class NodeNetwork extends AbstractNetwork {
|
|
5
|
+
private api;
|
|
6
|
+
constructor(url: string);
|
|
7
|
+
/**
|
|
8
|
+
* convert node api boxes to ErgoBox interface
|
|
9
|
+
* @param box
|
|
10
|
+
* @returns ErgoBox
|
|
11
|
+
*/
|
|
12
|
+
private convertBox;
|
|
13
|
+
/**
|
|
14
|
+
* convert Node transaction to extractor transaction type
|
|
15
|
+
* @param tx
|
|
16
|
+
*/
|
|
17
|
+
private convertTransaction;
|
|
18
|
+
/**
|
|
19
|
+
* return spending information of a specified box by having spendTxId
|
|
20
|
+
* @param boxId
|
|
21
|
+
* @param spendTxId
|
|
22
|
+
*/
|
|
23
|
+
getSpendingInfo: (boxId: string, spendTxId: string) => Promise<BlockInfo & {
|
|
24
|
+
spendIndex: number;
|
|
25
|
+
}>;
|
|
26
|
+
/**
|
|
27
|
+
* use node api to return related boxes by specified address
|
|
28
|
+
* @param address
|
|
29
|
+
* @param offset
|
|
30
|
+
* @param limit
|
|
31
|
+
* @returns related boxes
|
|
32
|
+
*/
|
|
33
|
+
getBoxesByAddress: (address: string, offset: number, limit: number) => Promise<{
|
|
34
|
+
boxes: ErgoBox[];
|
|
35
|
+
hasNextBatch: boolean;
|
|
36
|
+
}>;
|
|
37
|
+
/**
|
|
38
|
+
* use node api to return related boxes by specified token id
|
|
39
|
+
* @param tokenId
|
|
40
|
+
* @param offset
|
|
41
|
+
* @param limit
|
|
42
|
+
* @returns related boxes
|
|
43
|
+
*/
|
|
44
|
+
getBoxesByTokenId: (tokenId: string, offset: number, limit: number) => Promise<{
|
|
45
|
+
boxes: ErgoBox[];
|
|
46
|
+
hasNextBatch: boolean;
|
|
47
|
+
}>;
|
|
48
|
+
/**
|
|
49
|
+
* use node api to return related transactions of the specified address with limit offset
|
|
50
|
+
* @param tokenId
|
|
51
|
+
* @param offset
|
|
52
|
+
* @param limit
|
|
53
|
+
* @returns related transactions
|
|
54
|
+
*/
|
|
55
|
+
getAddressTransactionsWithOffsetLimit: (address: string, offset: number, limit: number) => Promise<{
|
|
56
|
+
items: Array<ExtendedTransaction>;
|
|
57
|
+
total: number;
|
|
58
|
+
}>;
|
|
59
|
+
}
|
|
60
|
+
//# sourceMappingURL=NodeNetwork.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"NodeNetwork.d.ts","sourceRoot":"","sources":["../../../../lib/ergo/network/NodeNetwork.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,SAAS,EAAE,MAAM,kCAAkC,CAAC;AAE7D,OAAO,EAAE,OAAO,EAAE,mBAAmB,EAAE,MAAM,eAAe,CAAC;AAC7D,OAAO,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AAEpD,qBAAa,WAAY,SAAQ,eAAe;IAC9C,OAAO,CAAC,GAAG,CAAC;gBAEA,GAAG,EAAE,MAAM;IAKvB;;;;OAIG;IACH,OAAO,CAAC,UAAU,CAqBhB;IAEF;;;OAGG;IACH,OAAO,CAAC,kBAAkB,CAqBxB;IAEF;;;;OAIG;IACH,eAAe,UACN,MAAM,aACF,MAAM;oBACkB,MAAM;OAYzC;IAEF;;;;;;OAMG;IACH,iBAAiB,YACN,MAAM,UACP,MAAM,SACP,MAAM;eACK,OAAO,EAAE;sBAAgB,OAAO;OAYlD;IAEF;;;;;;OAMG;IACH,iBAAiB,YACN,MAAM,UACP,MAAM,SACP,MAAM;eACK,OAAO,EAAE;sBAAgB,OAAO;OAWlD;IAEF;;;;;;OAMG;IACH,qCAAqC,YAC1B,MAAM,UACP,MAAM,SACP,MAAM,KACZ,QAAQ;QAAE,KAAK,EAAE,MAAM,mBAAmB,CAAC,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,CAAC,CAa9D;CACH"}
|
|
@@ -0,0 +1,131 @@
|
|
|
1
|
+
import ergoNodeClientFactory from '@rosen-clients/ergo-node';
|
|
2
|
+
import { AbstractNetwork } from './AbstractNetwork';
|
|
3
|
+
export class NodeNetwork extends AbstractNetwork {
|
|
4
|
+
api;
|
|
5
|
+
constructor(url) {
|
|
6
|
+
super();
|
|
7
|
+
this.api = ergoNodeClientFactory(url);
|
|
8
|
+
}
|
|
9
|
+
/**
|
|
10
|
+
* convert node api boxes to ErgoBox interface
|
|
11
|
+
* @param box
|
|
12
|
+
* @returns ErgoBox
|
|
13
|
+
*/
|
|
14
|
+
convertBox = async (box) => {
|
|
15
|
+
const tx = await await this.api.getTxById(box.transactionId);
|
|
16
|
+
const spendInfo = box.spentTransactionId
|
|
17
|
+
? await this.getSpendingInfo(box.boxId, box.spentTransactionId)
|
|
18
|
+
: undefined;
|
|
19
|
+
return {
|
|
20
|
+
transactionId: box.transactionId || '',
|
|
21
|
+
index: box.index || 0,
|
|
22
|
+
value: box.value || 0n,
|
|
23
|
+
ergoTree: box.ergoTree || '',
|
|
24
|
+
creationHeight: box.creationHeight || 0,
|
|
25
|
+
inclusionHeight: tx.inclusionHeight,
|
|
26
|
+
assets: box.assets || [],
|
|
27
|
+
additionalRegisters: box.additionalRegisters,
|
|
28
|
+
boxId: box.boxId || '',
|
|
29
|
+
blockId: tx.blockId,
|
|
30
|
+
spentBlockId: spendInfo?.hash,
|
|
31
|
+
spentHeight: spendInfo?.height,
|
|
32
|
+
spentTransactionId: box.spentTransactionId,
|
|
33
|
+
spentIndex: spendInfo?.spendIndex,
|
|
34
|
+
};
|
|
35
|
+
};
|
|
36
|
+
/**
|
|
37
|
+
* convert Node transaction to extractor transaction type
|
|
38
|
+
* @param tx
|
|
39
|
+
*/
|
|
40
|
+
convertTransaction = (tx) => {
|
|
41
|
+
return {
|
|
42
|
+
id: tx.id || '',
|
|
43
|
+
inclusionHeight: tx.inclusionHeight,
|
|
44
|
+
blockId: tx.blockId,
|
|
45
|
+
outputs: tx.outputs.map((output) => ({
|
|
46
|
+
transactionId: output.transactionId || '',
|
|
47
|
+
index: output.index || 0,
|
|
48
|
+
value: output.value || 0n,
|
|
49
|
+
ergoTree: output.ergoTree || '',
|
|
50
|
+
creationHeight: output.creationHeight || 0,
|
|
51
|
+
assets: output.assets || [],
|
|
52
|
+
additionalRegisters: output.additionalRegisters,
|
|
53
|
+
boxId: output.boxId || '',
|
|
54
|
+
})),
|
|
55
|
+
// TODO: Add input extension local/ergo/rosen-bridge/scanner/-/issues/156
|
|
56
|
+
inputs: tx.inputs.map((input) => ({ boxId: input.boxId })) ?? [],
|
|
57
|
+
dataInputs: tx.dataInputs,
|
|
58
|
+
};
|
|
59
|
+
};
|
|
60
|
+
/**
|
|
61
|
+
* return spending information of a specified box by having spendTxId
|
|
62
|
+
* @param boxId
|
|
63
|
+
* @param spendTxId
|
|
64
|
+
*/
|
|
65
|
+
getSpendingInfo = async (boxId, spendTxId) => {
|
|
66
|
+
const tx = await this.api.getTxById(spendTxId);
|
|
67
|
+
const spendIndex = tx.inputs?.findIndex((box) => box.boxId == boxId);
|
|
68
|
+
if (spendIndex == undefined)
|
|
69
|
+
throw Error(`Impossible behavior, the box [${boxId}] should have been spent in tx [${spendTxId}]`);
|
|
70
|
+
return {
|
|
71
|
+
hash: tx.blockId,
|
|
72
|
+
height: tx.inclusionHeight,
|
|
73
|
+
spendIndex,
|
|
74
|
+
};
|
|
75
|
+
};
|
|
76
|
+
/**
|
|
77
|
+
* use node api to return related boxes by specified address
|
|
78
|
+
* @param address
|
|
79
|
+
* @param offset
|
|
80
|
+
* @param limit
|
|
81
|
+
* @returns related boxes
|
|
82
|
+
*/
|
|
83
|
+
getBoxesByAddress = async (address, offset, limit) => {
|
|
84
|
+
const boxes = await this.api.getBoxesByAddressUnspent(address, {
|
|
85
|
+
offset: offset,
|
|
86
|
+
limit: limit,
|
|
87
|
+
sortDirection: 'desc',
|
|
88
|
+
});
|
|
89
|
+
if (!boxes)
|
|
90
|
+
throw new Error('Ergo node BoxesByAddress api expected to have items');
|
|
91
|
+
const ergoBoxes = await Promise.all(boxes.map(async (box) => await this.convertBox(box)));
|
|
92
|
+
return { boxes: ergoBoxes, hasNextBatch: boxes.length > 0 };
|
|
93
|
+
};
|
|
94
|
+
/**
|
|
95
|
+
* use node api to return related boxes by specified token id
|
|
96
|
+
* @param tokenId
|
|
97
|
+
* @param offset
|
|
98
|
+
* @param limit
|
|
99
|
+
* @returns related boxes
|
|
100
|
+
*/
|
|
101
|
+
getBoxesByTokenId = async (tokenId, offset, limit) => {
|
|
102
|
+
const boxes = await this.api.getBoxesByTokenId(tokenId, {
|
|
103
|
+
offset: offset,
|
|
104
|
+
limit: limit,
|
|
105
|
+
});
|
|
106
|
+
if (!boxes.items)
|
|
107
|
+
throw new Error('Ergo node BoxesByTokenId api expected to have items');
|
|
108
|
+
const ergoBoxes = await Promise.all(boxes.items.map(async (box) => await this.convertBox(box)));
|
|
109
|
+
return { boxes: ergoBoxes, hasNextBatch: boxes.items.length > 0 };
|
|
110
|
+
};
|
|
111
|
+
/**
|
|
112
|
+
* use node api to return related transactions of the specified address with limit offset
|
|
113
|
+
* @param tokenId
|
|
114
|
+
* @param offset
|
|
115
|
+
* @param limit
|
|
116
|
+
* @returns related transactions
|
|
117
|
+
*/
|
|
118
|
+
getAddressTransactionsWithOffsetLimit = async (address, offset, limit) => {
|
|
119
|
+
const txs = await this.api.getTxsByAddress(address, {
|
|
120
|
+
offset,
|
|
121
|
+
limit,
|
|
122
|
+
});
|
|
123
|
+
if (!txs.items)
|
|
124
|
+
throw new Error('Explorer AddressTransactions api expected to have items');
|
|
125
|
+
return {
|
|
126
|
+
items: txs.items.map((tx) => this.convertTransaction(tx)),
|
|
127
|
+
total: txs.total,
|
|
128
|
+
};
|
|
129
|
+
};
|
|
130
|
+
}
|
|
131
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiTm9kZU5ldHdvcmsuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi9saWIvZXJnby9uZXR3b3JrL05vZGVOZXR3b3JrLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8scUJBR04sTUFBTSwwQkFBMEIsQ0FBQztBQUlsQyxPQUFPLEVBQUUsZUFBZSxFQUFFLE1BQU0sbUJBQW1CLENBQUM7QUFFcEQsTUFBTSxPQUFPLFdBQVksU0FBUSxlQUFlO0lBQ3RDLEdBQUcsQ0FBQztJQUVaLFlBQVksR0FBVztRQUNyQixLQUFLLEVBQUUsQ0FBQztRQUNSLElBQUksQ0FBQyxHQUFHLEdBQUcscUJBQXFCLENBQUMsR0FBRyxDQUFDLENBQUM7SUFDeEMsQ0FBQztJQUVEOzs7O09BSUc7SUFDSyxVQUFVLEdBQUcsS0FBSyxFQUFFLEdBQW1CLEVBQW9CLEVBQUU7UUFDbkUsTUFBTSxFQUFFLEdBQUcsTUFBTSxNQUFNLElBQUksQ0FBQyxHQUFHLENBQUMsU0FBUyxDQUFDLEdBQUcsQ0FBQyxhQUFjLENBQUMsQ0FBQztRQUM5RCxNQUFNLFNBQVMsR0FBRyxHQUFHLENBQUMsa0JBQWtCO1lBQ3RDLENBQUMsQ0FBQyxNQUFNLElBQUksQ0FBQyxlQUFlLENBQUMsR0FBRyxDQUFDLEtBQU0sRUFBRSxHQUFHLENBQUMsa0JBQWtCLENBQUM7WUFDaEUsQ0FBQyxDQUFDLFNBQVMsQ0FBQztRQUNkLE9BQU87WUFDTCxhQUFhLEVBQUUsR0FBRyxDQUFDLGFBQWEsSUFBSSxFQUFFO1lBQ3RDLEtBQUssRUFBRSxHQUFHLENBQUMsS0FBSyxJQUFJLENBQUM7WUFDckIsS0FBSyxFQUFFLEdBQUcsQ0FBQyxLQUFLLElBQUksRUFBRTtZQUN0QixRQUFRLEVBQUUsR0FBRyxDQUFDLFFBQVEsSUFBSSxFQUFFO1lBQzVCLGNBQWMsRUFBRSxHQUFHLENBQUMsY0FBYyxJQUFJLENBQUM7WUFDdkMsZUFBZSxFQUFFLEVBQUUsQ0FBQyxlQUFlO1lBQ25DLE1BQU0s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QyxHQUFHLENBQUMsZUFBZSxDQUFDLE9BQU8sRUFBRTtZQUNsRCxNQUFNO1lBQ04sS0FBSztTQUNOLENBQUMsQ0FBQztRQUNILElBQUksQ0FBQyxHQUFHLENBQUMsS0FBSztZQUNaLE1BQU0sSUFBSSxLQUFLLENBQ2IseURBQXlELENBQzFELENBQUM7UUFDSixPQUFPO1lBQ0wsS0FBSyxFQUFFLEdBQUcsQ0FBQyxLQUFLLENBQUMsR0FBRyxDQUFDLENBQUMsRUFBRSxFQUFFLEVBQUUsQ0FBQyxJQUFJLENBQUMsa0JBQWtCLENBQUMsRUFBRSxDQUFDLENBQUM7WUFDekQsS0FBSyxFQUFFLEdBQUcsQ0FBQyxLQUFNO1NBQ2xCLENBQUM7SUFDSixDQUFDLENBQUM7Q0FDSCIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCBlcmdvTm9kZUNsaWVudEZhY3RvcnksIHtcbiAgSW5kZXhlZEVyZ29Cb3gsXG4gIEluZGV4ZWRFcmdvVHJhbnNhY3Rpb24sXG59IGZyb20gJ0Byb3Nlbi1jbGllbnRzL2VyZ28tbm9kZSc7XG5pbXBvcnQgeyBCbG9ja0luZm8gfSBmcm9tICdAcm9zZW4tYnJpZGdlL3NjYW5uZXItaW50ZXJmYWNlcyc7XG5cbmltcG9ydCB7IEVyZ29Cb3gsIEV4dGVuZGVkVHJhbnNhY3Rpb24gfSBmcm9tICcuLi9pbnRlcmZhY2VzJztcbmltcG9ydCB7IEFic3RyYWN0TmV0d29yayB9IGZyb20gJy4vQWJzdHJhY3ROZXR3b3JrJztcblxuZXhwb3J0IGNsYXNzIE5vZGVOZXR3b3JrIGV4dGVuZHMgQWJzdHJhY3ROZXR3b3JrIHtcbiAgcHJpdmF0ZSBhcGk7XG5cbiAgY29uc3RydWN0b3IodXJsOiBzdHJpbmcpIHtcbiAgICBzdXBlcigpO1xuICAgIHRoaXMuYXBpID0gZXJnb05vZGVDbGllbnRGYWN0b3J5KHVybCk7XG4gIH1cblxuICAvKipcbiAgICogY29udmVydCBub2RlIGFwaSBib3hlcyB0byBFcmdvQm94IGludGVyZmFjZVxuICAgKiBAcGFyYW0gYm94XG4gICAqIEByZXR1cm5zIEVyZ29Cb3hcbiAgICovXG4gIHByaXZhdGUgY29udmVydEJveCA9IGFzeW5jIChib3g6IEluZGV4ZWRFcmdvQm94KTogUHJvbWlzZTxFcmdvQm94PiA9PiB7XG4gICAgY29uc3QgdHggPSBhd2FpdCBhd2FpdCB0aGlzLmFwaS5nZXRUeEJ5SWQoYm94LnRyYW5zYWN0aW9uSWQhKTtcbiAgICBjb25zdCBzcGVuZEluZm8gPSBib3guc3BlbnRUcmFuc2FjdGlvbklkXG4gICAgICA/IGF3YWl0IHRoaXMuZ2V0U3BlbmRpbmdJbmZvKGJveC5ib3hJZCEsIGJveC5zcGVudFRyYW5zYWN0aW9uSWQpXG4gICAgICA6IHVuZGVmaW5lZDtcbiAgICByZXR1cm4ge1xuICAgICAgdHJhbnNhY3Rpb25JZDogYm94LnRyYW5zYWN0aW9uSWQgfHwgJycsXG4gICAgICBpbmRleDogYm94LmluZGV4IHx8IDAsXG4gICAgICB2YWx1ZTogYm94LnZhbHVlIHx8IDBuLFxuICAgICAgZXJnb1RyZWU6IGJveC5lcmdvVHJlZSB8fCAnJyxcbiAgICAgIGNyZWF0aW9uSGVpZ2h0OiBib3guY3JlYXRpb25IZWlnaHQgfHwgMCxcbiAgICAgIGluY2x1c2lvbkhlaWdodDogdHguaW5jbHVzaW9uSGVpZ2h0LFxuICAgICAgYXNzZXRzOiBib3guYXNzZXRzIHx8IFtdLFxuICAgICAgYWRkaXRpb25hbFJlZ2lzdGVyczogYm94LmFkZGl0aW9uYWxSZWdpc3RlcnMsXG4gICAgICBib3hJZDogYm94LmJveElkIHx8ICcnLFxuICAgICAgYmxvY2tJZDogdHguYmxvY2tJZCxcbiAgICAgIHNwZW50QmxvY2tJZDogc3BlbmRJbmZvPy5oYXNoLFxuICAgICAgc3BlbnRIZWlnaHQ6IHNwZW5kSW5mbz8uaGVpZ2h0LFxuICAgICAgc3BlbnRUcmFuc2FjdGlvbklkOiBib3guc3BlbnRUcmFuc2FjdGlvbklkLFxuICAgICAgc3BlbnRJbmRleDogc3BlbmRJbmZvPy5zcGVuZEluZGV4LFxuICAgIH07XG4gIH07XG5cbiAgLyoqXG4gICAqIGNvbnZlcnQgTm9kZSB0cmFuc2FjdGlvbiB0byBleHRyYWN0b3IgdHJhbnNhY3Rpb24gdHlwZVxuICAgKiBAcGFyYW0gdHhcbiAgICovXG4gIHByaXZhdGUgY29udmVydFRyYW5zYWN0aW9uID0gKFxuICAgIHR4OiBJbmRleGVkRXJnb1RyYW5zYWN0aW9uXG4gICk6IEV4dGVuZGVkVHJhbnNhY3Rpb24gPT4ge1xuICAgIHJldHVybiB7XG4gICAgICBpZDogdHguaWQgfHwgJycsXG4gICAgICBpbmNsdXNpb25IZWlnaHQ6IHR4LmluY2x1c2lvbkhlaWdodCxcbiAgICAgIGJsb2NrSWQ6IHR4LmJsb2NrSWQsXG4gICAgICBvdXRwdXRzOiB0eC5vdXRwdXRzLm1hcCgob3V0cHV0KSA9PiAoe1xuICAgICAgICB0cmFuc2FjdGlvbklkOiBvdXRwdXQudHJhbnNhY3Rpb25JZCB8fCAnJyxcbiAgICAgICAgaW5kZXg6IG91dHB1dC5pbmRleCB8fCAwLFxuICAgICAgICB2YWx1ZTogb3V0cHV0LnZhbHVlIHx8IDBuLFxuICAgICAgICBlcmdvVHJlZTogb3V0cHV0LmVyZ29UcmVlIHx8ICcnLFxuICAgICAgICBjcmVhdGlvbkhlaWdodDogb3V0cHV0LmNyZWF0aW9uSGVpZ2h0IHx8IDAsXG4gICAgICAgIGFzc2V0czogb3V0cHV0LmFzc2V0cyB8fCBbXSxcbiAgICAgICAgYWRkaXRpb25hbFJlZ2lzdGVyczogb3V0cHV0LmFkZGl0aW9uYWxSZWdpc3RlcnMsXG4gICAgICAgIGJveElkOiBvdXRwdXQuYm94SWQgfHwgJycsXG4gICAgICB9KSksXG4gICAgICAvLyBUT0RPOiBBZGQgaW5wdXQgZXh0ZW5zaW9uIGxvY2FsL2VyZ28vcm9zZW4tYnJpZGdlL3NjYW5uZXIvLS9pc3N1ZXMvMTU2XG4gICAgICBpbnB1dHM6IHR4LmlucHV0cy5tYXAoKGlucHV0KSA9PiAoeyBib3hJZDogaW5wdXQuYm94SWQhIH0pKSA/PyBbXSxcbiAgICAgIGRhdGFJbnB1dHM6IHR4LmRhdGFJbnB1dHMsXG4gICAgfTtcbiAgfTtcblxuICAvKipcbiAgICogcmV0dXJuIHNwZW5kaW5nIGluZm9ybWF0aW9uIG9mIGEgc3BlY2lmaWVkIGJveCBieSBoYXZpbmcgc3BlbmRUeElkXG4gICAqIEBwYXJhbSBib3hJZFxuICAgKiBAcGFyYW0gc3BlbmRUeElkXG4gICAqL1xuICBnZXRTcGVuZGluZ0luZm8gPSBhc3luYyAoXG4gICAgYm94SWQ6IHN0cmluZyxcbiAgICBzcGVuZFR4SWQ6IHN0cmluZ1xuICApOiBQcm9taXNlPEJsb2NrSW5mbyAmIHsgc3BlbmRJbmRleDogbnVtYmVyIH0+ID0+IHtcbiAgICBjb25zdCB0eCA9IGF3YWl0IHRoaXMuYXBpLmdldFR4QnlJZChzcGVuZFR4SWQpO1xuICAgIGNvbnN0IHNwZW5kSW5kZXggPSB0eC5pbnB1dHM/LmZpbmRJbmRleCgoYm94KSA9PiBib3guYm94SWQgPT0gYm94SWQpO1xuICAgIGlmIChzcGVuZEluZGV4ID09IHVuZGVmaW5lZClcbiAgICAgIHRocm93IEVycm9yKFxuICAgICAgICBgSW1wb3NzaWJsZSBiZWhhdmlvciwgdGhlIGJveCBbJHtib3hJZH1dIHNob3VsZCBoYXZlIGJlZW4gc3BlbnQgaW4gdHggWyR7c3BlbmRUeElkfV1gXG4gICAgICApO1xuICAgIHJldHVybiB7XG4gICAgICBoYXNoOiB0eC5ibG9ja0lkLFxuICAgICAgaGVpZ2h0OiB0eC5pbmNsdXNpb25IZWlnaHQsXG4gICAgICBzcGVuZEluZGV4LFxuICAgIH07XG4gIH07XG5cbiAgLyoqXG4gICAqIHVzZSBub2RlIGFwaSB0byByZXR1cm4gcmVsYXRlZCBib3hlcyBieSBzcGVjaWZpZWQgYWRkcmVzc1xuICAgKiBAcGFyYW0gYWRkcmVzc1xuICAgKiBAcGFyYW0gb2Zmc2V0XG4gICAqIEBwYXJhbSBsaW1pdFxuICAgKiBAcmV0dXJucyByZWxhdGVkIGJveGVzXG4gICAqL1xuICBnZXRCb3hlc0J5QWRkcmVzcyA9IGFzeW5jIChcbiAgICBhZGRyZXNzOiBzdHJpbmcsXG4gICAgb2Zmc2V0OiBudW1iZXIsXG4gICAgbGltaXQ6IG51bWJlclxuICApOiBQcm9taXNlPHsgYm94ZXM6IEVyZ29Cb3hbXTsgaGFzTmV4dEJhdGNoOiBib29sZWFuIH0+ID0+IHtcbiAgICBjb25zdCBib3hlcyA9IGF3YWl0IHRoaXMuYXBpLmdldEJveGVzQnlBZGRyZXNzVW5zcGVudChhZGRyZXNzLCB7XG4gICAgICBvZmZzZXQ6IG9mZnNldCxcbiAgICAgIGxpbWl0OiBsaW1pdCxcbiAgICAgIHNvcnREaXJlY3Rpb246ICdkZXNjJyxcbiAgICB9KTtcbiAgICBpZiAoIWJveGVzKVxuICAgICAgdGhyb3cgbmV3IEVycm9yKCdFcmdvIG5vZGUgQm94ZXNCeUFkZHJlc3MgYXBpIGV4cGVjdGVkIHRvIGhhdmUgaXRlbXMnKTtcbiAgICBjb25zdCBlcmdvQm94ZXMgPSBhd2FpdCBQcm9taXNlLmFsbChcbiAgICAgIGJveGVzLm1hcChhc3luYyAoYm94KSA9PiBhd2FpdCB0aGlzLmNvbnZlcnRCb3goYm94KSlcbiAgICApO1xuICAgIHJldHVybiB7IGJveGVzOiBlcmdvQm94ZXMsIGhhc05leHRCYXRjaDogYm94ZXMubGVuZ3RoID4gMCB9O1xuICB9O1xuXG4gIC8qKlxuICAgKiB1c2Ugbm9kZSBhcGkgdG8gcmV0dXJuIHJlbGF0ZWQgYm94ZXMgYnkgc3BlY2lmaWVkIHRva2VuIGlkXG4gICAqIEBwYXJhbSB0b2tlbklkXG4gICAqIEBwYXJhbSBvZmZzZXRcbiAgICogQHBhcmFtIGxpbWl0XG4gICAqIEByZXR1cm5zIHJlbGF0ZWQgYm94ZXNcbiAgICovXG4gIGdldEJveGVzQnlUb2tlbklkID0gYXN5bmMgKFxuICAgIHRva2VuSWQ6IHN0cmluZyxcbiAgICBvZmZzZXQ6IG51bWJlcixcbiAgICBsaW1pdDogbnVtYmVyXG4gICk6IFByb21pc2U8eyBib3hlczogRXJnb0JveFtdOyBoYXNOZXh0QmF0Y2g6IGJvb2xlYW4gfT4gPT4ge1xuICAgIGNvbnN0IGJveGVzID0gYXdhaXQgdGhpcy5hcGkuZ2V0Qm94ZXNCeVRva2VuSWQodG9rZW5JZCwge1xuICAgICAgb2Zmc2V0OiBvZmZzZXQsXG4gICAgICBsaW1pdDogbGltaXQsXG4gICAgfSk7XG4gICAgaWYgKCFib3hlcy5pdGVtcylcbiAgICAgIHRocm93IG5ldyBFcnJvcignRXJnbyBub2RlIEJveGVzQnlUb2tlbklkIGFwaSBleHBlY3RlZCB0byBoYXZlIGl0ZW1zJyk7XG4gICAgY29uc3QgZXJnb0JveGVzID0gYXdhaXQgUHJvbWlzZS5hbGwoXG4gICAgICBib3hlcy5pdGVtcy5tYXAoYXN5bmMgKGJveCkgPT4gYXdhaXQgdGhpcy5jb252ZXJ0Qm94KGJveCkpXG4gICAgKTtcbiAgICByZXR1cm4geyBib3hlczogZXJnb0JveGVzLCBoYXNOZXh0QmF0Y2g6IGJveGVzLml0ZW1zLmxlbmd0aCA+IDAgfTtcbiAgfTtcblxuICAvKipcbiAgICogdXNlIG5vZGUgYXBpIHRvIHJldHVybiByZWxhdGVkIHRyYW5zYWN0aW9ucyBvZiB0aGUgc3BlY2lmaWVkIGFkZHJlc3Mgd2l0aCBsaW1pdCBvZmZzZXRcbiAgICogQHBhcmFtIHRva2VuSWRcbiAgICogQHBhcmFtIG9mZnNldFxuICAgKiBAcGFyYW0gbGltaXRcbiAgICogQHJldHVybnMgcmVsYXRlZCB0cmFuc2FjdGlvbnNcbiAgICovXG4gIGdldEFkZHJlc3NUcmFuc2FjdGlvbnNXaXRoT2Zmc2V0TGltaXQgPSBhc3luYyAoXG4gICAgYWRkcmVzczogc3RyaW5nLFxuICAgIG9mZnNldDogbnVtYmVyLFxuICAgIGxpbWl0OiBudW1iZXJcbiAgKTogUHJvbWlzZTx7IGl0ZW1zOiBBcnJheTxFeHRlbmRlZFRyYW5zYWN0aW9uPjsgdG90YWw6IG51bWJlciB9PiA9PiB7XG4gICAgY29uc3QgdHhzID0gYXdhaXQgdGhpcy5hcGkuZ2V0VHhzQnlBZGRyZXNzKGFkZHJlc3MsIHtcbiAgICAgIG9mZnNldCxcbiAgICAgIGxpbWl0LFxuICAgIH0pO1xuICAgIGlmICghdHhzLml0ZW1zKVxuICAgICAgdGhyb3cgbmV3IEVycm9yKFxuICAgICAgICAnRXhwbG9yZXIgQWRkcmVzc1RyYW5zYWN0aW9ucyBhcGkgZXhwZWN0ZWQgdG8gaGF2ZSBpdGVtcydcbiAgICAgICk7XG4gICAgcmV0dXJuIHtcbiAgICAgIGl0ZW1zOiB0eHMuaXRlbXMubWFwKCh0eCkgPT4gdGhpcy5jb252ZXJ0VHJhbnNhY3Rpb24odHgpKSxcbiAgICAgIHRvdGFsOiB0eHMudG90YWwhLFxuICAgIH07XG4gIH07XG59XG4iXX0=
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { OutputBox } from '@rosen-bridge/scanner-interfaces';
|
|
2
|
+
/**
|
|
3
|
+
* Check box to have specified tokens
|
|
4
|
+
* @param box
|
|
5
|
+
* @return true if box has the required token and false otherwise
|
|
6
|
+
*/
|
|
7
|
+
export declare const boxHasToken: (box: OutputBox, tokenIds: string[]) => boolean;
|
|
8
|
+
//# sourceMappingURL=utils.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../../lib/ergo/utils.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,SAAS,EAAE,MAAM,kCAAkC,CAAC;AAE7D;;;;GAIG;AACH,eAAO,MAAM,WAAW,QAAS,SAAS,YAAY,MAAM,EAAE,YAM7D,CAAC"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { intersection } from 'lodash-es';
|
|
2
|
+
/**
|
|
3
|
+
* Check box to have specified tokens
|
|
4
|
+
* @param box
|
|
5
|
+
* @return true if box has the required token and false otherwise
|
|
6
|
+
*/
|
|
7
|
+
export const boxHasToken = (box, tokenIds) => {
|
|
8
|
+
if (!box.assets)
|
|
9
|
+
return false;
|
|
10
|
+
const boxTokens = box.assets.map((token) => token.tokenId);
|
|
11
|
+
const requiredTokens = intersection(tokenIds, boxTokens);
|
|
12
|
+
if (requiredTokens.length == tokenIds.length)
|
|
13
|
+
return true;
|
|
14
|
+
return false;
|
|
15
|
+
};
|
|
16
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidXRpbHMuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi9saWIvZXJnby91dGlscy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUUsWUFBWSxFQUFFLE1BQU0sV0FBVyxDQUFDO0FBR3pDOzs7O0dBSUc7QUFDSCxNQUFNLENBQUMsTUFBTSxXQUFXLEdBQUcsQ0FBQyxHQUFjLEVBQUUsUUFBa0IsRUFBRSxFQUFFO0lBQ2hFLElBQUksQ0FBQyxHQUFHLENBQUMsTUFBTTtRQUFFLE9BQU8sS0FBSyxDQUFDO0lBQzlCLE1BQU0sU0FBUyxHQUFHLEdBQUcsQ0FBQyxNQUFNLENBQUMsR0FBRyxDQUFDLENBQUMsS0FBSyxFQUFFLEVBQUUsQ0FBQyxLQUFLLENBQUMsT0FBTyxDQUFDLENBQUM7SUFDM0QsTUFBTSxjQUFjLEdBQUcsWUFBWSxDQUFDLFFBQVEsRUFBRSxTQUFTLENBQUMsQ0FBQztJQUN6RCxJQUFJLGNBQWMsQ0FBQyxNQUFNLElBQUksUUFBUSxDQUFDLE1BQU07UUFBRSxPQUFPLElBQUksQ0FBQztJQUMxRCxPQUFPLEtBQUssQ0FBQztBQUNmLENBQUMsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IGludGVyc2VjdGlvbiB9IGZyb20gJ2xvZGFzaC1lcyc7XG5pbXBvcnQgeyBPdXRwdXRCb3ggfSBmcm9tICdAcm9zZW4tYnJpZGdlL3NjYW5uZXItaW50ZXJmYWNlcyc7XG5cbi8qKlxuICogQ2hlY2sgYm94IHRvIGhhdmUgc3BlY2lmaWVkIHRva2Vuc1xuICogQHBhcmFtIGJveFxuICogQHJldHVybiB0cnVlIGlmIGJveCBoYXMgdGhlIHJlcXVpcmVkIHRva2VuIGFuZCBmYWxzZSBvdGhlcndpc2VcbiAqL1xuZXhwb3J0IGNvbnN0IGJveEhhc1Rva2VuID0gKGJveDogT3V0cHV0Qm94LCB0b2tlbklkczogc3RyaW5nW10pID0+IHtcbiAgaWYgKCFib3guYXNzZXRzKSByZXR1cm4gZmFsc2U7XG4gIGNvbnN0IGJveFRva2VucyA9IGJveC5hc3NldHMubWFwKCh0b2tlbikgPT4gdG9rZW4udG9rZW5JZCk7XG4gIGNvbnN0IHJlcXVpcmVkVG9rZW5zID0gaW50ZXJzZWN0aW9uKHRva2VuSWRzLCBib3hUb2tlbnMpO1xuICBpZiAocmVxdWlyZWRUb2tlbnMubGVuZ3RoID09IHRva2VuSWRzLmxlbmd0aCkgcmV0dXJuIHRydWU7XG4gIHJldHVybiBmYWxzZTtcbn07XG4iXX0=
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../lib/index.ts"],"names":[],"mappings":"AAAA,cAAc,QAAQ,CAAC;AACvB,cAAc,aAAa,CAAC;AAC5B,cAAc,qBAAqB,CAAC"}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
export * from './ergo';
|
|
2
|
+
export * from './constants';
|
|
3
|
+
export * from './abstractExtractor';
|
|
4
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9saWIvaW5kZXgudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsY0FBYyxRQUFRLENBQUM7QUFDdkIsY0FBYyxhQUFhLENBQUM7QUFDNUIsY0FBYyxxQkFBcUIsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbImV4cG9ydCAqIGZyb20gJy4vZXJnbyc7XG5leHBvcnQgKiBmcm9tICcuL2NvbnN0YW50cyc7XG5leHBvcnQgKiBmcm9tICcuL2Fic3RyYWN0RXh0cmFjdG9yJztcbiJdfQ==
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { V1 } from '@rosen-clients/ergo-explorer';
|
|
2
|
+
import { BlockInfo, OutputBox } from '@rosen-bridge/scanner-interfaces';
|
|
3
|
+
import { AbstractErgoExtractor, AbstractBoxData, AbstractErgoExtractorAction, AbstractErgoExtractorEntity } from '../lib';
|
|
4
|
+
export declare class MockedErgoExtractor extends AbstractErgoExtractor<AbstractBoxData, AbstractErgoExtractorEntity> {
|
|
5
|
+
actions: AbstractErgoExtractorAction<AbstractBoxData, AbstractErgoExtractorEntity>;
|
|
6
|
+
getId: () => string;
|
|
7
|
+
initializeBoxes: (initialBlock: BlockInfo) => Promise<void>;
|
|
8
|
+
hasData: (box: V1.OutputInfo | OutputBox) => boolean;
|
|
9
|
+
extractBoxData: (box: V1.OutputInfo | OutputBox) => AbstractBoxData | undefined;
|
|
10
|
+
}
|
|
11
|
+
//# sourceMappingURL=AbstractErgoExtractor.mock.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"AbstractErgoExtractor.mock.d.ts","sourceRoot":"","sources":["../../tests/AbstractErgoExtractor.mock.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,EAAE,EAAE,MAAM,8BAA8B,CAAC;AAClD,OAAO,EAAE,SAAS,EAAE,SAAS,EAAE,MAAM,kCAAkC,CAAC;AAExE,OAAO,EACL,qBAAqB,EACrB,eAAe,EACf,2BAA2B,EAC3B,2BAA2B,EAC5B,MAAM,QAAQ,CAAC;AAEhB,qBAAa,mBAAoB,SAAQ,qBAAqB,CAC5D,eAAe,EACf,2BAA2B,CAC5B;IACC,OAAO,EAAE,2BAA2B,CAClC,eAAe,EACf,2BAA2B,CAC5B,CAAC;IAEF,KAAK,eAAgB;IAErB,eAAe,EAAE,CAAC,YAAY,EAAE,SAAS,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IAE5D,OAAO,QACA,GAAG,UAAU,GAAG,SAAS,aACrB;IAEX,cAAc,QACP,GAAG,UAAU,GAAG,SAAS,KAC7B,eAAe,GAAG,SAAS,CAE5B;CACH"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { AbstractErgoExtractor, } from '../lib';
|
|
2
|
+
export class MockedErgoExtractor extends AbstractErgoExtractor {
|
|
3
|
+
actions;
|
|
4
|
+
getId = () => 'Test';
|
|
5
|
+
initializeBoxes;
|
|
6
|
+
hasData = (box // eslint-disable-line @typescript-eslint/no-unused-vars
|
|
7
|
+
) => false;
|
|
8
|
+
extractBoxData = (box // eslint-disable-line @typescript-eslint/no-unused-vars
|
|
9
|
+
) => {
|
|
10
|
+
return undefined;
|
|
11
|
+
};
|
|
12
|
+
}
|
|
13
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiQWJzdHJhY3RFcmdvRXh0cmFjdG9yLm1vY2suanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi90ZXN0cy9BYnN0cmFjdEVyZ29FeHRyYWN0b3IubW9jay50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFHQSxPQUFPLEVBQ0wscUJBQXFCLEdBSXRCLE1BQU0sUUFBUSxDQUFDO0FBRWhCLE1BQU0sT0FBTyxtQkFBb0IsU0FBUSxxQkFHeEM7SUFDQyxPQUFPLENBR0w7SUFFRixLQUFLLEdBQUcsR0FBRyxFQUFFLENBQUMsTUFBTSxDQUFDO0lBRXJCLGVBQWUsQ0FBNkM7SUFFNUQsT0FBTyxHQUFHLENBQ1IsR0FBOEIsQ0FBQyx3REFBd0Q7TUFDdkYsRUFBRSxDQUFDLEtBQUssQ0FBQztJQUVYLGNBQWMsR0FBRyxDQUNmLEdBQThCLENBQUMsd0RBQXdEO01BQzFELEVBQUU7UUFDL0IsT0FBTyxTQUFTLENBQUM7SUFDbkIsQ0FBQyxDQUFDO0NBQ0giLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBWMSB9IGZyb20gJ0Byb3Nlbi1jbGllbnRzL2VyZ28tZXhwbG9yZXInO1xuaW1wb3J0IHsgQmxvY2tJbmZvLCBPdXRwdXRCb3ggfSBmcm9tICdAcm9zZW4tYnJpZGdlL3NjYW5uZXItaW50ZXJmYWNlcyc7XG5cbmltcG9ydCB7XG4gIEFic3RyYWN0RXJnb0V4dHJhY3RvcixcbiAgQWJzdHJhY3RCb3hEYXRhLFxuICBBYnN0cmFjdEVyZ29FeHRyYWN0b3JBY3Rpb24sXG4gIEFic3RyYWN0RXJnb0V4dHJhY3RvckVudGl0eSxcbn0gZnJvbSAnLi4vbGliJztcblxuZXhwb3J0IGNsYXNzIE1vY2tlZEVyZ29FeHRyYWN0b3IgZXh0ZW5kcyBBYnN0cmFjdEVyZ29FeHRyYWN0b3I8XG4gIEFic3RyYWN0Qm94RGF0YSxcbiAgQWJzdHJhY3RFcmdvRXh0cmFjdG9yRW50aXR5XG4+IHtcbiAgYWN0aW9uczogQWJzdHJhY3RFcmdvRXh0cmFjdG9yQWN0aW9uPFxuICAgIEFic3RyYWN0Qm94RGF0YSxcbiAgICBBYnN0cmFjdEVyZ29FeHRyYWN0b3JFbnRpdHlcbiAgPjtcblxuICBnZXRJZCA9ICgpID0+ICdUZXN0JztcblxuICBpbml0aWFsaXplQm94ZXM6IChpbml0aWFsQmxvY2s6IEJsb2NrSW5mbykgPT4gUHJvbWlzZTx2b2lkPjtcblxuICBoYXNEYXRhID0gKFxuICAgIGJveDogVjEuT3V0cHV0SW5mbyB8IE91dHB1dEJveCAvLyBlc2xpbnQtZGlzYWJsZS1saW5lIEB0eXBlc2NyaXB0LWVzbGludC9uby11bnVzZWQtdmFyc1xuICApID0+IGZhbHNlO1xuXG4gIGV4dHJhY3RCb3hEYXRhID0gKFxuICAgIGJveDogVjEuT3V0cHV0SW5mbyB8IE91dHB1dEJveCAvLyBlc2xpbnQtZGlzYWJsZS1saW5lIEB0eXBlc2NyaXB0LWVzbGludC9uby11bnVzZWQtdmFyc1xuICApOiBBYnN0cmFjdEJveERhdGEgfCB1bmRlZmluZWQgPT4ge1xuICAgIHJldHVybiB1bmRlZmluZWQ7XG4gIH07XG59XG4iXX0=
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"AbstractErgoExtractor.spec.d.ts","sourceRoot":"","sources":["../../tests/AbstractErgoExtractor.spec.ts"],"names":[],"mappings":""}
|