-
Notifications
You must be signed in to change notification settings - Fork 5
/
explorer.ts
101 lines (86 loc) · 3.14 KB
/
explorer.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
import axios, { AxiosInstance, AxiosPromise, AxiosResponse } from 'axios';
import { Address } from './models/address';
import { ErgoBox } from './models/ergoBox';
import { IIdObject } from './models/IIdObject';
import { Transaction } from './models/transaction';
/**
* Class to interact with explorer
*/
export class Explorer {
public static readonly testnet: Explorer = new Explorer('https://api-testnet.ergoplatform.com');
public static readonly mainnet: Explorer = new Explorer('https://api.ergoplatform.com');
public readonly apiClient: AxiosInstance;
protected url: string;
protected timeout: number = 1000 * 5;
protected headers = {
'Content-Type': 'application/json',
};
constructor(url: string) {
this.url = url;
this.apiClient = axios.create({
baseURL: url,
headers: this.headers,
timeout: this.timeout,
});
this.apiClient.interceptors.response.use(
response => Promise.resolve(response),
error => Promise.reject(new Error(error.response || {})),
);
}
public async getCurrentHeight(): Promise<number> {
const {
data: { items },
} = await this.getRequest(`/blocks?limit=1`);
return items[0].height;
}
public async getUnspentOutputs(address: Address): Promise<ErgoBox[]> {
const { data } = await this.getRequest(`/transactions/boxes/byAddress/unspent/${address.address}`);
return this.uniqueById(data.map(o => ErgoBox.formObject(o)));
}
public async getUnconfirmed(address?: Address): Promise<Transaction[]> {
let data;
if (address === undefined) {
data = (await this.getRequest(`/transactions/unconfirmed`)).data;
} else {
data = (await this.getRequest(`/transactions/unconfirmed/byAddress/${address.address}`)).data;
}
return this.uniqueById(data.map(o => Transaction.formObject(o)));
}
public async getTransactions(address: Address): Promise<Transaction[]> {
const { data } = await this.getRequest(`/addresses/${address.address}/transactions`);
return data.items.map(o => Transaction.formObject(o));
}
public async getTokenInfo(tokenId: string): Promise<ErgoBox> {
const { data } = await this.getRequest(`/transactions/boxes/${tokenId}`);
const {
data: { outputs },
} = await this.getRequest(`/transactions/${data.spentTransactionId}`);
const parsedOutputs: ErgoBox[] = outputs.map(o => ErgoBox.formObject(o));
return parsedOutputs.find(o => o.assets.find(a => a.tokenId === tokenId) !== undefined);
}
public async broadcastTx(signedTransaction: Transaction) {
return await this.postRequest('/transactions/send', signedTransaction);
}
protected async postRequest(url: string, data): Promise<AxiosResponse> {
return await this.apiClient({
data: data,
method: 'POST',
url: url,
});
}
protected async getRequest(url: string) {
return await this.apiClient({
method: 'GET',
url,
});
}
private uniqueById<T extends IIdObject>(elements: T[]): T[] {
const uniqueBoxes = [];
elements.forEach(b => {
if (uniqueBoxes.find(x => x.id === b.id) === undefined) {
uniqueBoxes.push(b);
}
});
return uniqueBoxes;
}
}