Compare commits

..

No commits in common. "84bb370415315dfcd0bc89d9583db0e9b8280a88" and "11f16d5ce974bd79febe20fc9ccc02f83c26d4fe" have entirely different histories.

4 changed files with 55 additions and 166 deletions

View File

@ -1,32 +0,0 @@
name: Workflow push to Dappbundle
on: [push]
jobs:
build:
name: Build
runs-on: self-hosted
steps:
- name: Executing remote command
uses: appleboy/ssh-action@v1.0.0
with:
host: ${{ secrets.R_HOST }}
username: ${{ secrets.P_USERNAME }}
password: ${{ secrets.P_PASSWORD }}
port: ${{ secrets.SSH_PORT }}
script: |
if [ -d "${{ secrets.DEPLOYMENT_LOCATION}}/dappbundle" ]; then
echo "Folder exists. Skipping Git clone."
else
echo "Folder does not exist. Cloning repository..."
cd ${{ secrets.DEPLOYMENT_LOCATION}}/ && git clone https://github.com/ranchimall/dappbundle.git
fi
if [ -d "${{ secrets.DEPLOYMENT_LOCATION}}/dappbundle/${{ github.event.repository.name }}" ]; then
echo "Repository exists. Remove folder "
rm -r "${{ secrets.DEPLOYMENT_LOCATION}}/dappbundle/${{ github.event.repository.name }}"
fi
echo "Cloning repository..."
cd ${{ secrets.DEPLOYMENT_LOCATION}}/dappbundle && git clone https://github.com/ranchimall/${{ github.event.repository.name }}
cd "${{ secrets.DEPLOYMENT_LOCATION}}/dappbundle/${{ github.event.repository.name }}" && rm -rf .gitattributes .git .github .gitignore
cd ${{ secrets.DEPLOYMENT_LOCATION}}/dappbundle/ && git add . && git commit -m "Workflow updating files of ${{ github.event.repository.name }}" && git push "https://saketongit:${{ secrets.RM_ACCESS_TOKEN }}@github.com/ranchimall/dappbundle.git"

View File

@ -417,14 +417,9 @@
<div class="balance-display">
<div class="balance-amount" id="send-balance">0 <span class="currency">XLM</span></div>
</div>
<div class="detail-row">
<label>From Address</label>
<div class="detail-value-wrapper">
<code id="send-from-address" class="detail-value">-</code>
<button class="input-action-btn clear-btn" onclick="copyToClipboard('send-from-address')" title="Copy address">
<i class="fa-regular fa-copy"></i>
</button>
</div>
<div class="address-display">
<span class="address-label">Address:</span>
<span class="address-value" id="send-from-address">-</span>
</div>
</div>
@ -1021,7 +1016,7 @@
balance = accountInfo.balanceXlm;
const balanceEl = document.getElementById('xlm-balance');
balanceEl.innerHTML = balance.toFixed(6) + ' <span class="currency">XLM</span>';
balanceEl.innerHTML = balance.toFixed(6) + ' <span class="currency">xlm</span>';
txNextToken = null;
await loadTransactions(true);
@ -1031,7 +1026,7 @@
// Show 0 balance for inactive accounts
const balanceEl = document.getElementById('xlm-balance');
balanceEl.innerHTML = '0 <span class="currency">XLM</span>';
balanceEl.innerHTML = '0 <span class="currency">xlm</span>';
document.getElementById('tx-history').innerHTML = '<div class="tx-empty">Account is inactive or not funded yet</div>';
}
@ -1160,7 +1155,7 @@
const balanceEl = document.getElementById('send-balance');
balanceEl.innerHTML = accountInfo.balanceXlm.toFixed(7) + ' <span class="currency">XLM</span>';
document.getElementById('send-from-address').textContent = address;
document.getElementById('send-from-address').textContent = address.substring(0, 12) + '...' + address.substring(address.length - 12);
document.getElementById('send-wallet-info').style.display = 'block';
} catch (error) {
document.getElementById('send-wallet-info').style.display = 'none';
@ -1208,39 +1203,19 @@
hasMoreTransactions = true;
}
// Load transactions - fetch one extra to check if there's more
// Load only one batch of transactions
if (hasMoreTransactions) {
// Fetch ITEMS_PER_PAGE + 1 to check if there's a next page
const result = await xlmAPI.getTransactions(currentxlmAddress, {
limit: ITEMS_PER_PAGE + 1,
limit: 10,
next: txNextToken
});
// Get all fetched transactions
const fetchedTransactions = result.transactions || [];
// Add all fetched transactions to our array
allTransactions = [...allTransactions, ...fetchedTransactions];
// Determine if there are more transactions:
// If we got exactly limit+1 transactions, there might be more
// Also check the API's hasMore flag
if (fetchedTransactions.length === ITEMS_PER_PAGE + 1 && result.hasMore) {
hasMoreTransactions = true;
txNextToken = result.nextToken;
} else {
hasMoreTransactions = false;
txNextToken = null;
}
allTransactions = [...allTransactions, ...result.transactions];
txNextToken = result.nextToken;
hasMoreTransactions = result.hasMore;
}
// If we have no transactions at all
if (allTransactions.length === 0) {
hasMoreTransactions = false;
}
totalPages = Math.ceil(allTransactions.length / ITEMS_PER_PAGE) || 1;
totalPages = Math.ceil(allTransactions.length / ITEMS_PER_PAGE);
if (hasMoreTransactions) {
totalPages++; // Add one more page to show "next" is available
}
@ -1292,9 +1267,8 @@
// Update button states
document.getElementById('prev-page-btn').disabled = currentPage <= 1;
// Disable next button if we're on the last page AND there are no more transactions to load
const isLastPage = currentPage >= totalPages;
document.getElementById('next-page-btn').disabled = isLastPage && !hasMoreTransactions;
// Enable next button if we're not on last page OR if there are more transactions to load
document.getElementById('next-page-btn').disabled = currentPage >= totalPages && !hasMoreTransactions;
paginationEl.style.display = filteredTransactions.length > 0 ? 'flex' : 'none';
}
@ -1618,15 +1592,15 @@
</div>
<div class="tx-detail-row">
<span class="detail-label">Transaction Fee</span>
<span class="detail-value fee">${feeXlm.toFixed(6)} XLM</span>
<span class="detail-value fee">${feeXLM.toFixed(6)} XLM</span>
</div>
<div class="tx-detail-row highlight" style="color: var(--error-color);">
<span class="detail-label">Total Required</span>
<span class="detail-value">${totalXlm.toFixed(6)} XLM</span>
<span class="detail-value">${totalXLM.toFixed(6)} XLM</span>
</div>
<div class="tx-detail-row" style="color: var(--error-color); font-weight: 600;">
<span class="detail-label">Shortfall</span>
<span class="detail-value">${(totalXlm - currentBalance).toFixed(6)} XLM</span>
<span class="detail-value">${(totalXLM - currentBalance).toFixed(6)} XLM</span>
</div>
</div>
</div>

View File

@ -247,9 +247,7 @@
// Get fee stats
const feeStats = await server.feeStats();
// fee_charged.mode is typically 100 stroops (0.00001 XLM)
const fee = feeStats.fee_charged?.mode || feeStats.last_ledger_base_fee || '100';
const fee = feeStats.max_fee.mode || (StellarSdk.BASE_FEE || '100');
// Build transaction
let transaction = new StellarSdk.TransactionBuilder(sourceAccount, {
@ -313,23 +311,12 @@
}
try {
// Parse the XDR back to a transaction using TransactionBuilder
const transaction = StellarSdk.TransactionBuilder.fromXDR(transactionXDR, StellarSdk.Networks.PUBLIC);
console.log('Submitting transaction to Stellar network...');
// Parse the XDR back to a transaction
const transaction = new StellarSdk.Transaction(transactionXDR, StellarSdk.Networks.PUBLIC);
// Submit to network
const result = await server.submitTransaction(transaction);
console.log('✅ Transaction submitted successfully!');
console.log('Transaction Details:', {
hash: result.hash,
ledger: result.ledger,
successful: result.successful,
envelope_xdr: result.envelope_xdr,
result_xdr: result.result_xdr
});
return {
hash: result.hash,
ledger: result.ledger,
@ -337,7 +324,7 @@
txId: result.hash
};
} catch (error) {
console.error('Error submitting transaction:', error);
console.error('Error submitting transaction:', error);
// Parse Stellar error
if (error.response && error.response.data) {

View File

@ -28,22 +28,6 @@
};
}
// Calculate CRC16-XModem checksum (shared function)
function crc16XModem(data) {
let crc = 0x0000;
for (let i = 0; i < data.length; i++) {
crc ^= data[i] << 8;
for (let j = 0; j < 8; j++) {
if (crc & 0x8000) {
crc = (crc << 1) ^ 0x1021;
} else {
crc = crc << 1;
}
}
}
return crc & 0xFFFF;
}
// --- Multi-chain Generator (BTC, FLO, XLM) ---
stellarCrypto.generateMultiChain = async function (inputWif) {
const versions = {
@ -90,35 +74,19 @@
}
const decodedBytes = new Uint8Array(decoded);
// Validate checksum
if (decodedBytes.length < 35) {
throw new Error('Invalid Stellar secret key: too short');
}
// Extract components: [version(1)] + [seed(32)] + [checksum(2)]
const payload = decodedBytes.slice(0, 33); // version + seed
const providedChecksum = (decodedBytes[34] << 8) | decodedBytes[33]; // little-endian
// Calculate expected checksum
const expectedChecksum = crc16XModem(payload);
// Verify checksum matches
if (providedChecksum !== expectedChecksum) {
throw new Error(`Invalid Stellar secret key: checksum mismatch (expected ${expectedChecksum.toString(16)}, got ${providedChecksum.toString(16)})`);
}
// Verify version byte
if (decodedBytes[0] !== 0x90) {
throw new Error(`Invalid Stellar secret key: wrong version byte (expected 0x90, got 0x${decodedBytes[0].toString(16)})`);
}
// Extract seed (skip version byte, take 32 bytes)
// Extract seed (skip version byte 0x90, take 32 bytes, ignore checksum)
const seed = decodedBytes.slice(1, 33);
privKeyHex = bytesToHex(seed);
} catch (e) {
console.error("Invalid Stellar secret key:", e.message);
throw new Error(`Failed to recover Stellar secret key: ${e.message}`);
console.warn("Invalid Stellar secret key:", e);
// Fall through to generate new key
const newKey = generateNewID();
const decode = Bitcoin.Base58.decode(newKey.privKey);
const keyWithVersion = decode.slice(0, decode.length - 4);
let key = keyWithVersion.slice(1);
if (key.length >= 33 && key[key.length - 1] === 0x01)
key = key.slice(0, key.length - 1);
privKeyHex = bytesToHex(key);
}
} else if (hexOnly && (trimmedInput.length === 64 || trimmedInput.length === 128)) {
privKeyHex =
@ -126,36 +94,6 @@
} else {
try {
const decode = Bitcoin.Base58.decode(trimmedInput);
// Validate WIF checksum
if (decode.length < 37) {
throw new Error('Invalid WIF key: too short');
}
// WIF format: [version(1)] + [private_key(32)] + [compression_flag(0-1)] + [checksum(4)]
const payload = decode.slice(0, decode.length - 4);
const providedChecksum = decode.slice(decode.length - 4);
// Calculate expected checksum using double SHA256
const hash1 = Crypto.SHA256(payload, { asBytes: true });
const hash2 = Crypto.SHA256(hash1, { asBytes: true });
const expectedChecksum = hash2.slice(0, 4);
// Verify checksum matches
let checksumMatch = true;
for (let i = 0; i < 4; i++) {
if (providedChecksum[i] !== expectedChecksum[i]) {
checksumMatch = false;
break;
}
}
if (!checksumMatch) {
const providedHex = providedChecksum.map(b => b.toString(16).padStart(2, '0')).join('');
const expectedHex = expectedChecksum.map(b => b.toString(16).padStart(2, '0')).join('');
throw new Error(`Invalid WIF key: checksum mismatch (expected ${expectedHex}, got ${providedHex})`);
}
const keyWithVersion = decode.slice(0, decode.length - 4);
let key = keyWithVersion.slice(1);
if (key.length >= 33 && key[key.length - 1] === 0x01) {
@ -164,8 +102,14 @@
}
privKeyHex = bytesToHex(key);
} catch (e) {
console.error("Invalid WIF key:", e.message);
throw new Error(`Failed to recover from WIF key: ${e.message}`);
console.warn("Invalid WIF, generating new key:", e);
const newKey = generateNewID();
const decode = Bitcoin.Base58.decode(newKey.privKey);
const keyWithVersion = decode.slice(0, decode.length - 4);
let key = keyWithVersion.slice(1);
if (key.length >= 33 && key[key.length - 1] === 0x01)
key = key.slice(0, key.length - 1);
privKeyHex = bytesToHex(key);
}
}
} else {
@ -209,6 +153,22 @@
const versionByte = 0x30; // Results in 'G' prefix for public keys
const payload = new Uint8Array([versionByte, ...pubKey]);
// Calculate CRC16-XModem checksum
function crc16XModem(data) {
let crc = 0x0000;
for (let i = 0; i < data.length; i++) {
crc ^= data[i] << 8;
for (let j = 0; j < 8; j++) {
if (crc & 0x8000) {
crc = (crc << 1) ^ 0x1021;
} else {
crc = crc << 1;
}
}
}
return crc & 0xFFFF;
}
const checksum = crc16XModem(payload);
// Checksum is stored in little-endian format
const checksumBytes = new Uint8Array([checksum & 0xFF, (checksum >> 8) & 0xFF]);