@bsv/sdk
Version:
BSV Blockchain Software Development Kit
181 lines • 6.52 kB
JavaScript
"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
const DefaultHttpClient_js_1 = require("../http/DefaultHttpClient.js");
const Random_js_1 = __importDefault(require("../../primitives/Random.js"));
const utils_js_1 = require("../../primitives/utils.js");
function defaultDeploymentId() {
return `ts-sdk-${(0, utils_js_1.toHex)((0, Random_js_1.default)(16))}`;
}
/**
* Represents an ARC transaction broadcaster.
*/
class ARC {
constructor(URL, config) {
this.URL = URL;
if (typeof config === 'string') {
this.apiKey = config;
this.httpClient = (0, DefaultHttpClient_js_1.defaultHttpClient)();
this.deploymentId = defaultDeploymentId();
this.callbackToken = undefined;
this.callbackUrl = undefined;
}
else {
const configObj = config ?? {};
const { apiKey, deploymentId, httpClient, callbackToken, callbackUrl, headers } = configObj;
this.apiKey = apiKey;
this.httpClient = httpClient ?? (0, DefaultHttpClient_js_1.defaultHttpClient)();
this.deploymentId = deploymentId ?? defaultDeploymentId();
this.callbackToken = callbackToken;
this.callbackUrl = callbackUrl;
this.headers = headers;
}
}
/**
* Constructs a dictionary of the default & supplied request headers.
*/
requestHeaders() {
const headers = {
'Content-Type': 'application/json',
'XDeployment-ID': this.deploymentId
};
if (this.apiKey != null && this.apiKey !== '') {
headers.Authorization = `Bearer ${this.apiKey}`;
}
if (this.callbackUrl != null && this.callbackUrl !== '') {
headers['X-CallbackUrl'] = this.callbackUrl;
}
if (this.callbackToken != null && this.callbackToken !== '') {
headers['X-CallbackToken'] = this.callbackToken;
}
if (this.headers != null) {
for (const key in this.headers) {
headers[key] = this.headers[key];
}
}
return headers;
}
/**
* Broadcasts a transaction via ARC.
*
* @param {Transaction} tx - The transaction to be broadcasted.
* @returns {Promise<BroadcastResponse | BroadcastFailure>} A promise that resolves to either a success or failure response.
*/
async broadcast(tx) {
let rawTx;
try {
rawTx = tx.toHexEF();
}
catch (error) {
if (error.message ===
'All inputs must have source transactions when serializing to EF format') {
rawTx = tx.toHex();
}
else {
throw error;
}
}
const requestOptions = {
method: 'POST',
headers: this.requestHeaders(),
data: { rawTx }
};
try {
const response = await this.httpClient.request(`${this.URL}/v1/tx`, requestOptions);
if (response.ok) {
const { txid, extraInfo, txStatus, competingTxs } = response.data;
const broadcastRes = {
status: 'success',
txid,
message: `${txStatus} ${extraInfo}`
};
if (competingTxs != null) {
broadcastRes.competingTxs = competingTxs;
}
return broadcastRes;
}
else {
const st = typeof response.status;
const r = {
status: 'error',
code: st === 'number' || st === 'string'
? response.status.toString()
: 'ERR_UNKNOWN',
description: 'Unknown error'
};
let d = response.data;
if (typeof d === 'string') {
try {
d = JSON.parse(response.data);
}
catch {
// Intentionally left empty
}
}
if (typeof d === 'object') {
if (d !== null) {
r.more = d;
}
if ((d != null) && typeof d.txid === 'string') {
r.txid = d.txid;
}
if ((d != null) && 'detail' in d && typeof d.detail === 'string') {
r.description = d.detail;
}
}
return r;
}
}
catch (error) {
return {
status: 'error',
code: '500',
description: typeof error.message === 'string'
? error.message
: 'Internal Server Error'
};
}
}
/**
* Broadcasts multiple transactions via ARC.
* Handles mixed responses where some transactions succeed and others fail.
*
* @param {Transaction[]} txs - Array of transactions to be broadcasted.
* @returns {Promise<Array<object>>} A promise that resolves to an array of objects.
*/
async broadcastMany(txs) {
const rawTxs = txs.map((tx) => {
try {
return { rawTx: tx.toHexEF() };
}
catch (error) {
if (error.message ===
'All inputs must have source transactions when serializing to EF format') {
return { rawTx: tx.toHex() };
}
throw error;
}
});
const requestOptions = {
method: 'POST',
headers: this.requestHeaders(),
data: rawTxs
};
try {
const response = await this.httpClient.request(`${this.URL}/v1/txs`, requestOptions);
return response.data;
}
catch (error) {
const errorResponse = {
status: 'error',
code: '500',
description: typeof error.message === 'string' ? error.message : 'Internal Server Error'
};
return txs.map(() => errorResponse);
}
}
}
exports.default = ARC;
//# sourceMappingURL=ARC.js.map