gn-provider 1.2.7 → 1.2.8

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.
@@ -5,6 +5,9 @@ declare enum ProviderEvent {
5
5
  Connected = "connected",
6
6
  NetworkChange = "networkChange"
7
7
  }
8
+ export interface GNProviderOptions {
9
+ bridgeUrl?: string;
10
+ }
8
11
  export declare class GNProvider extends Provider {
9
12
  emit: (event: ProviderEvent, ...args: any[]) => boolean;
10
13
  private _network;
@@ -13,10 +16,11 @@ export declare class GNProvider extends Provider {
13
16
  private _gorillaPoolApiKey;
14
17
  private apiPrefix;
15
18
  private _mapiURL;
19
+ private _bridgeUrl?;
16
20
  private _getHeaders;
17
21
  connect: () => Promise<this>;
18
22
  getFeePerKb: () => Promise<number>;
19
- constructor(network: scryptlib.bsv.Networks.Network, wocApiKey?: string, gpApiKey?: string);
23
+ constructor(network: scryptlib.bsv.Networks.Network, wocApiKey?: string, gpApiKey?: string, options?: GNProviderOptions);
20
24
  isConnected: () => boolean;
21
25
  updateNetwork: (network: scryptlib.bsv.Networks.Network) => void;
22
26
  getNetwork: () => scryptlib.bsv.Networks.Network;
@@ -53,11 +53,8 @@ var ProviderEvent;
53
53
  ProviderEvent["Connected"] = "connected";
54
54
  ProviderEvent["NetworkChange"] = "networkChange";
55
55
  })(ProviderEvent || (ProviderEvent = {}));
56
- /*export type UTXOWithHeight = UTXO & {
57
- height: number;
58
- };*/
59
56
  class GNProvider extends abstract_provider_1.Provider {
60
- constructor(network, wocApiKey = '', gpApiKey = '') {
57
+ constructor(network, wocApiKey = '', gpApiKey = '', options) {
61
58
  super();
62
59
  this._isConnected = false;
63
60
  this._getHeaders = () => {
@@ -221,24 +218,25 @@ class GNProvider extends abstract_provider_1.Provider {
221
218
  throw new Error(`GNProvider ERROR: ${error.message}`);
222
219
  }
223
220
  }*/
224
- this.sendRawTransaction = (rawTxHex) => __awaiter(this, void 0, void 0, function* () {
225
- var _a;
226
- yield this._ready();
221
+ /*EN USO
222
+ sendRawTransaction = async (rawTxHex: string): Promise<TxHash> => {
223
+ await this._ready();
227
224
  const headers = this._getHeaders();
228
225
  const size = Math.max(1, rawTxHex.length / 2 / 1024);
229
226
  const timeout = Math.max(10000, 1000 * size);
227
+
230
228
  try {
231
- const res = yield superagent.post(`${this.apiPrefix()}/tx/raw`)
229
+ const res = await superagent.post(`${this.apiPrefix()}/tx/raw`)
232
230
  .timeout({
233
- response: timeout,
234
- deadline: 60000
235
- })
231
+ response: timeout,
232
+ deadline: 60000
233
+ })
236
234
  .set(headers)
237
235
  .send({ txhex: rawTxHex });
236
+
238
237
  return res.body;
239
- }
240
- catch (error) {
241
- if ((_a = error.response) === null || _a === void 0 ? void 0 : _a.text) {
238
+ } catch (error: any) {
239
+ if (error.response?.text) {
242
240
  if (this.needIgnoreError(error.response.text)) {
243
241
  return new scryptlib.bsv.Transaction(rawTxHex).id;
244
242
  }
@@ -246,74 +244,48 @@ class GNProvider extends abstract_provider_1.Provider {
246
244
  }
247
245
  throw new Error(`GNProvider ERROR: ${error.message}`);
248
246
  }
249
- });
250
- /*sendRawTransaction = async (rawTxHex: string): Promise<TxHash> => {
251
- await this._ready();
252
- const headers = this._getHeaders();
253
- const size = Math.max(1, rawTxHex.length / 2 / 1024);
254
- const timeout = Math.max(15000, 1000 * size);
255
-
256
- const wocRequest = superagent.post(`${this.apiPrefix()}/tx/raw`)
257
- .timeout({ response: timeout, deadline: 60000 })
258
- .set(headers)
259
- .send({ txhex: rawTxHex });
260
-
261
- const gpRequest = superagent.post(this._mapiURL + 'tx')
262
- .timeout({ response: timeout, deadline: 60000 })
263
- .set('Content-Type', 'application/octet-stream')
264
- .send(Buffer.from(rawTxHex, 'hex'));
265
-
266
- if (this._gorillaPoolApiKey) {
267
- gpRequest.set('Authorization', `Bearer ${this._gorillaPoolApiKey}`);
268
- }
269
-
247
+ }*/
248
+ this.sendRawTransaction = (rawTxHex) => __awaiter(this, void 0, void 0, function* () {
249
+ var _a, _b;
250
+ yield this._ready();
251
+ const isUsingBridge = !!this._bridgeUrl;
252
+ const url = isUsingBridge
253
+ ? `${this._bridgeUrl}/broadcast`
254
+ : `${this.apiPrefix()}/tx/raw`;
270
255
  try {
271
- const responses = await Promise.allSettled([
272
- wocRequest.then(res => ({ source: 'WhatsOnChain', result: res.body })),
273
- gpRequest.then(res => {
274
- try {
275
- if (!res.body?.payload) {
276
- throw new Error('Respuesta inválida de GorillaPool: falta payload');
277
- }
278
-
279
- const payload = JSON.parse(res.body.payload);
280
-
281
- if (payload.returnResult === 'success') {
282
- return { source: 'GorillaPool', result: payload.txid };
283
- } else {
284
- throw new Error(`GorillaPool [${payload.returnResult || 'unknown'}]: ${payload.resultDescription || 'Sin descripción'}`);
285
- }
286
- } catch (parseError) {
287
- const message = parseError instanceof Error ? parseError.message : String(parseError);
288
- throw new Error(`GorillaPool: Error parsing response - ${message}`);
289
- }
290
- })
291
- ]);
292
-
293
- for (const response of responses) {
294
- if (response.status === 'fulfilled') {
295
- console.log(`✅ Transacción aceptada por: ${response.value.source}`);
296
- return response.value.result;
297
- }
298
- }
299
-
300
- const firstRejection = responses.find(r => r.status === 'rejected');
301
- if (firstRejection) {
302
- throw new Error(firstRejection.reason.message || firstRejection.reason);
256
+ console.log(`🚀 [GNProvider] Broadcasting via ${isUsingBridge ? 'GoldenNotes Bridge' : 'WhatsOnChain'}...`);
257
+ const res = yield superagent
258
+ .post(url)
259
+ .send({
260
+ txhex: rawTxHex,
261
+ network: this._network.name === scryptlib.bsv.Networks.mainnet.name ? 'main' : 'test'
262
+ })
263
+ .timeout(35000); // 35s para dar margen al polling del bridge
264
+ // Tu bridge devuelve el TXID como texto (res.text)
265
+ //const txid = typeof res.body === 'string' ? res.body : (res.text || res.body?.txid);
266
+ //const txid = res.text || (res.body && res.body.txid) || res.body;
267
+ const txid = isUsingBridge
268
+ ? (res.text || (res.body && res.body.txid) || res.body)
269
+ : res.body;
270
+ if (typeof txid !== 'string' || txid.length !== 64) {
271
+ return new scryptlib.bsv.Transaction(rawTxHex).id;
303
272
  }
304
-
305
- throw new Error('Todos los intentos de envío fallaron');
306
-
307
- } catch (error: any) {
308
- if (error.response?.text) {
309
- if (this.needIgnoreError(error.response.text)) {
310
- return new scryptlib.bsv.Transaction(rawTxHex).id;
311
- }
312
- throw new Error(`GNProvider ERROR: ${this.friendlyBIP22RejectionMsg(error.response.text)}`);
273
+ console.log(`✅ [GNProvider] Éxito: ${txid}`);
274
+ return txid;
275
+ }
276
+ catch (error) {
277
+ const errorMsg = ((_b = (_a = error.response) === null || _a === void 0 ? void 0 : _a.body) === null || _b === void 0 ? void 0 : _b.error) || error.message || "";
278
+ // --- LOGICA DE TOLERANCIA ---
279
+ // Si el bridge falla porque la TX ya existe, no detenemos el contrato.
280
+ if (this.needIgnoreError(errorMsg)) {
281
+ const recoveredTxid = new scryptlib.bsv.Transaction(rawTxHex).id;
282
+ console.log(`ℹ️ [GNProvider] La TX ya estaba en red. ID recuperado: ${recoveredTxid}`);
283
+ return recoveredTxid;
313
284
  }
314
- throw new Error(`GNProvider ERROR: ${error.message}`);
285
+ console.error(`❌ [GNProvider] Error crítico: ${errorMsg}`);
286
+ throw new Error(`GNProvider ERROR: ${this.friendlyBIP22RejectionMsg(errorMsg)}`);
315
287
  }
316
- }*/
288
+ });
317
289
  this.sendTransaction = (signedTx) => __awaiter(this, void 0, void 0, function* () {
318
290
  try {
319
291
  const txHex = signedTx.serialize({ disableIsFullySigned: true });
@@ -434,6 +406,7 @@ class GNProvider extends abstract_provider_1.Provider {
434
406
  const networkStr = this._network.name === scryptlib.bsv.Networks.mainnet.name ? 'main' : 'test';
435
407
  return `https://api.whatsonchain.com/v1/bsv/${networkStr}`;
436
408
  };
409
+ this._bridgeUrl = options === null || options === void 0 ? void 0 : options.bridgeUrl;
437
410
  Object.setPrototypeOf(this, events_1.EventEmitter.prototype);
438
411
  this.connect().catch(console.error);
439
412
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "gn-provider",
3
- "version": "1.2.7",
3
+ "version": "1.2.8",
4
4
  "files": [
5
5
  "dist",
6
6
  "scripts",