Skip to content

Commit 6264bc5

Browse files
authored
Create bridge.js
1 parent 6fdcb2d commit 6264bc5

File tree

1 file changed

+153
-0
lines changed

1 file changed

+153
-0
lines changed

src/bridge.js

Lines changed: 153 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,153 @@
1+
/**
2+
* Advanced PiCoin Transfer Module using Wormhole SDK
3+
*
4+
* Features:
5+
* - Robust async transfer with retries
6+
* - Detailed progress events and logging
7+
* - Configurable parameters including retry count, timeout, network
8+
* - Input validation and error handling
9+
* - Support for gas fee estimation placeholder (depending on Wormhole SDK support)
10+
* - Exportable class for extensibility
11+
* - Compatible with Node.js environment
12+
*/
13+
14+
const EventEmitter = require('events');
15+
const { Wormhole } = require('@wormhole-foundation/sdk');
16+
17+
class PiCoinTransfer extends EventEmitter {
18+
/**
19+
* Constructs the PiCoinTransfer instance.
20+
* @param {object} options - Configuration options.
21+
* @param {string} [options.network='mainnet'] - Wormhole network environment.
22+
* @param {number} [options.retryCount=3] - Number of retries on failure.
23+
* @param {number} [options.retryDelayMs=3000] - Delay between retries in milliseconds.
24+
* @param {string} [options.token='PI'] - Token symbol to transfer.
25+
* @param {string} [options.fromChain='PiNetwork'] - Source chain name.
26+
*/
27+
constructor(options = {}) {
28+
super();
29+
this.network = options.network || 'mainnet';
30+
this.retryCount = options.retryCount || 3;
31+
this.retryDelayMs = options.retryDelayMs || 3000;
32+
this.token = options.token || 'PI';
33+
this.fromChain = options.fromChain || 'PiNetwork';
34+
35+
this.wormhole = new Wormhole(this.network);
36+
37+
this._log(`Initialized PiCoinTransfer on network: ${this.network}`);
38+
}
39+
40+
_log(message) {
41+
// Emits a 'log' event with the message
42+
this.emit('log', `[PiCoinTransfer]: ${message}`);
43+
}
44+
45+
_validateInputs(toChain, amount) {
46+
if (typeof toChain !== 'string' || toChain.trim() === '') {
47+
throw new TypeError('Recipient chain name must be a non-empty string.');
48+
}
49+
if (typeof amount !== 'number' && typeof amount !== 'string') {
50+
throw new TypeError('Amount must be a number or string representing a numeric value.');
51+
}
52+
const numericAmount = Number(amount);
53+
if (isNaN(numericAmount) || numericAmount <= 0) {
54+
throw new RangeError('Amount must be a positive number.');
55+
}
56+
return numericAmount;
57+
}
58+
59+
async _delay(ms) {
60+
return new Promise(resolve => setTimeout(resolve, ms));
61+
}
62+
63+
/**
64+
* Transfer PiCoin token to another chain.
65+
* Emits events:
66+
* - 'start' when transfer starts
67+
* - 'progress' with current step info
68+
* - 'success' upon successful transfer with transaction details
69+
* - 'error' on failure
70+
*
71+
* @param {string} toChain - The target chain name.
72+
* @param {number|string} amount - Amount to transfer.
73+
* @returns {Promise<object>} Transfer result details.
74+
*/
75+
async transfer(toChain, amount) {
76+
this._log(`Preparing to transfer ${amount} ${this.token} from ${this.fromChain} to ${toChain}`);
77+
78+
// Validate inputs
79+
let numericAmount;
80+
try {
81+
numericAmount = this._validateInputs(toChain, amount);
82+
} catch (validationError) {
83+
this.emit('error', validationError);
84+
throw validationError;
85+
}
86+
87+
this.emit('start', { toChain, amount: numericAmount, token: this.token });
88+
89+
let attempt = 0;
90+
while (attempt <= this.retryCount) {
91+
try {
92+
attempt++;
93+
this._log(`Attempt ${attempt} to transfer tokens...`);
94+
95+
this.emit('progress', { status: 'initiating_transfer', attempt });
96+
97+
// Call the Wormhole transfer method
98+
// Assuming wormhole.transfer returns a promise with tx details; adjust as per SDK
99+
const result = await this.wormhole.transfer({
100+
fromChain: this.fromChain,
101+
toChain: toChain,
102+
amount: numericAmount,
103+
token: this.token,
104+
});
105+
106+
this._log(`Transfer successful on attempt ${attempt}`);
107+
this.emit('success', result);
108+
return result;
109+
110+
} catch (error) {
111+
this._log(`Transfer attempt ${attempt} failed: ${error.message || error}`);
112+
113+
this.emit('error', { attempt, error });
114+
115+
if (attempt > this.retryCount) {
116+
this._log('Max retries reached, aborting transfer.');
117+
throw new Error(`Transfer failed after ${this.retryCount} attempts: ${error.message || error}`);
118+
}
119+
120+
this._log(`Retrying after ${this.retryDelayMs}ms...`);
121+
await this._delay(this.retryDelayMs);
122+
}
123+
}
124+
}
125+
}
126+
127+
module.exports = PiCoinTransfer;
128+
129+
/**
130+
* Example Usage:
131+
*
132+
* const PiCoinTransfer = require('./advancedPiCoinTransfer');
133+
*
134+
* async function run() {
135+
* const piTransfer = new PiCoinTransfer({ retryCount: 5, retryDelayMs: 5000 });
136+
*
137+
* piTransfer.on('log', msg => console.log(msg));
138+
* piTransfer.on('start', info => console.log('Transfer starting:', info));
139+
* piTransfer.on('progress', status => console.log('Progress:', status));
140+
* piTransfer.on('success', result => console.log('Transfer successful:', result));
141+
* piTransfer.on('error', error => console.error('Transfer error:', error));
142+
*
143+
* try {
144+
* const result = await piTransfer.transfer('Ethereum', 100);
145+
* console.log('Final result:', result);
146+
* } catch (err) {
147+
* console.error('Transfer failed:', err);
148+
* }
149+
* }
150+
*
151+
* run();
152+
*/
153+

0 commit comments

Comments
 (0)