Skip to content

Commit

Permalink
Merge branch 'feat/solana/tokens/base' into fix/solana/tokens/qa-bugs
Browse files Browse the repository at this point in the history
  • Loading branch information
muzaffarbhat07 authored Jan 24, 2025
2 parents 7e83d63 + 11b0b6c commit 567b8a0
Show file tree
Hide file tree
Showing 11 changed files with 110 additions and 39 deletions.
5 changes: 5 additions & 0 deletions .changeset/itchy-months-accept.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@cypherock/coin-support-solana': patch
---

Add signature status api
13 changes: 13 additions & 0 deletions apps/desktop/extraResources/RELEASE_NOTES.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,16 @@
# v2.0.17

### 🚀 Features

- **Token Support on Solana Network**: Seamlessly manage your SPL tokens directly in cySync — view balances, send, and receive your tokens with ease.

# v2.0.16

### 🐛 Bugfixes

- **Tron Energy Warning**: Alerts if energy is insufficient for transactions.
- **Backup API Call**: Ensures accurate fee estimation in Tron when the first attempt fails.

# v2.0.15

### 🚀 Features
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,19 +3,23 @@ import {
insertOrUpdateTransactions,
} from '@cypherock/coin-support-utils';
import { solanaCoinList } from '@cypherock/coins';
import { BigNumber } from '@cypherock/cysync-utils';
import { BigNumber, sleep } from '@cypherock/cysync-utils';
import {
AccountTypeMap,
ITransaction,
TransactionStatusMap,
TransactionTypeMap,
} from '@cypherock/db-interfaces';

import { broadcastTransactionToBlockchain } from '../../services';
import {
broadcastTransactionToBlockchain,
checkTransactionStatus,
} from '../../services';

import { InstructionType } from '../../services/helpers';

import { IBroadcastSolanaTransactionParams } from './types';
import logger from '../../utils/logger';

export const broadcastTransaction = async (
params: IBroadcastSolanaTransactionParams,
Expand All @@ -35,6 +39,15 @@ export const broadcastTransaction = async (
coin.id,
);

// Wait for 30 seconds to confirm the status of transaction before adding it to the data base
await sleep(30000);
try {
await checkTransactionStatus(txnHash, coin.id); // throws error if transaction didn't succeed
} catch (e) {
logger.error(JSON.stringify(e));
throw new Error('Could not get the transaction status on blockchain');
}

const isTokenAccount = account.type === AccountTypeMap.subAccount;

const parsedTransaction: ITransaction = {
Expand Down
24 changes: 24 additions & 0 deletions packages/coin-support-solana/src/services/api/transaction.ts
Original file line number Diff line number Diff line change
Expand Up @@ -154,3 +154,27 @@ export const broadcastTransactionToBlockchain = async (

return response.data.signature;
};

export const checkTransactionStatus = async (
signature: string,
assetId: string,
): Promise<string> => {
const url = `${baseURL}/signature-status`;
const response = await makePostRequest(
url,
{
signatures: [signature],
network: solanaCoinList[assetId].network,
},
{
maxTries: 0,
},
);

assert(
response.data.status,
new Error('Server: Invalid transaction status from server'),
);

return response.data.status;
};
76 changes: 44 additions & 32 deletions packages/coin-support-solana/tests/07.broadcastTransaction.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,40 +31,52 @@ describe('07. Broadcast Transaction', () => {

describe('should be able to broadcast transaction', () => {
testData.valid.forEach(testCase => {
test(testCase.name, async () => {
const getOneAccountMock = jest
.fn()
.mockReturnValue(testCase.mocks.account);
const db = {
account: {
getOne: getOneAccountMock,
},
transaction: {
getOne: getOneTransactionMock,
insert: insertTransactionMock,
},
} as any;
serviceMock.broadcastTransactionToBlockchain.mockReturnValue(
Promise.resolve(testCase.output.hash),
);
insertTransactionMock.mockReturnValue(Promise.resolve(testCase.output));
global.Date.now = jest.fn(() => testCase.output.timestamp);
test(
testCase.name,
async () => {
const getOneAccountMock = jest
.fn()
.mockReturnValue(testCase.mocks.account);
const db = {
account: {
getOne: getOneAccountMock,
},
transaction: {
getOne: getOneTransactionMock,
insert: insertTransactionMock,
},
} as any;
serviceMock.broadcastTransactionToBlockchain.mockReturnValue(
Promise.resolve(testCase.output.hash),
);
serviceMock.getTransactions.mockReturnValue(
Promise.resolve(testCase.output.hash),
);
serviceMock.checkTransactionStatus.mockReturnValue(
Promise.resolve('confirmed'),
);
insertTransactionMock.mockReturnValue(
Promise.resolve(testCase.output),
);
global.Date.now = jest.fn(() => testCase.output.timestamp);

const preparedTransaction = await support.broadcastTransaction({
db,
transaction: testCase.txn,
signedTransaction: '',
});
const preparedTransaction = await support.broadcastTransaction({
db,
transaction: testCase.txn,
signedTransaction: '',
});

expect(preparedTransaction).toBeDefined();
expect(insertTransactionMock.mock.calls.length).toEqual(1);
expect(
insertTransactionMock.mock.calls[0].map((t: any) =>
lodash.omit(t, ['__id']),
),
).toEqual([preparedTransaction]);
expect(preparedTransaction).toEqual(testCase.output);
});
expect(preparedTransaction).toBeDefined();
expect(insertTransactionMock.mock.calls.length).toEqual(1);
expect(
insertTransactionMock.mock.calls[0].map((t: any) =>
lodash.omit(t, ['__id']),
),
).toEqual([preparedTransaction]);
expect(preparedTransaction).toEqual(testCase.output);
},
35 * 1000,
);
});
});
});
4 changes: 4 additions & 0 deletions packages/coin-support-solana/tests/__mocks__/services.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,9 @@ export const getSimulationComputeUnits = jest
export const broadcastTransactionToBlockchain = jest
.fn()
.mockReturnValue(Promise.resolve('test'));
export const checkTransactionStatus = jest
.fn()
.mockReturnValue(Promise.resolve('confirmed'));

jest.mock('../../src/services', () => ({
__esModule: true,
Expand All @@ -21,4 +24,5 @@ jest.mock('../../src/services', () => ({
getPriorityFees,
getSimulationComputeUnits,
broadcastTransactionToBlockchain,
checkTransactionStatus,
}));
2 changes: 1 addition & 1 deletion packages/cysync-core-constants/src/i18n/lang/ar-AE.json
Original file line number Diff line number Diff line change
Expand Up @@ -305,7 +305,7 @@
"error": "قيمة مرتفعة جدًا"
},
"feeBelowMinError": "المعاملة ذات الرسوم الأقل من الحد الأدنى ستفشل",
"rentExemptFeeWarning": "يتطلب حساب المستلم حدًا أدنى من الرصيد لاستثناء الإيجار في Solana، وهذا مشمول في رسوم الشبكة"
"rentExemptFeeWarning": "استلام رمز على سولانا لأول مرة يستلزم رسوم إعفاء من الإيجار، وتشمل إجمالي الرسوم."
},
"summary": {
"title": "ملخص",
Expand Down
2 changes: 1 addition & 1 deletion packages/cysync-core-constants/src/i18n/lang/de-DE.json
Original file line number Diff line number Diff line change
Expand Up @@ -305,7 +305,7 @@
"error": "Wert zu hoch"
},
"feeBelowMinError": "Transaktion mit fee unter dem Minimum wird fehlschlagen",
"rentExemptFeeWarning": "Das Empfängerkonto benötigt ein Mindestguthaben für die Miete befreit von Solana, dies ist in den Netzwerkgebühren enthalten"
"rentExemptFeeWarning": "Das erstmalige Empfangen eines Tokens auf Solana zieht Mietbefreiungsgebühren nach sich, die in den Gesamtgebühren enthalten sind."
},
"summary": {
"title": "Zusammenfassung",
Expand Down
2 changes: 1 addition & 1 deletion packages/cysync-core-constants/src/i18n/lang/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -305,7 +305,7 @@
"error": "Value too high"
},
"feeBelowMinError": "Transaction with fee lesser than minimum will fail",
"rentExemptFeeWarning": "The recipient account requires a minimum balance for Solana's rent exemption, this is included in the network fees"
"rentExemptFeeWarning": "Receiving a token on solana for the first time incurs rent exemption fees, included in total fees."
},
"summary": {
"title": "Summary",
Expand Down
2 changes: 1 addition & 1 deletion packages/cysync-core-constants/src/i18n/lang/id-ID.json
Original file line number Diff line number Diff line change
Expand Up @@ -305,7 +305,7 @@
"error": "Nilai terlalu tinggi"
},
"feeBelowMinError": "Transaksi dengan biaya lebih rendah dari minimum akan gagal",
"rentExemptFeeWarning": "Akun penerima memerlukan saldo minimum untuk pengecualian sewa Solana, ini termasuk dalam biaya jaringan"
"rentExemptFeeWarning": "Menerima token di Solana untuk pertama kali akan dikenakan biaya pembebasan sewa, yang termasuk dalam total biaya."
},
"summary": {
"title": "Ringkasan",
Expand Down
2 changes: 1 addition & 1 deletion packages/cysync-core-constants/src/i18n/lang/zh-CN.json
Original file line number Diff line number Diff line change
Expand Up @@ -305,7 +305,7 @@
"error": "值过高"
},
"feeBelowMinError": "低于最低 fee 的交易将失败",
"rentExemptFeeWarning": "收款账户需要为 Solana 的租金豁免保留最低余额,这包含在网络费用中"
"rentExemptFeeWarning": "首次在 Solana 上接收代币会产生租金豁免费用,已包含在总费用中。"
},
"summary": {
"title": "摘要",
Expand Down

0 comments on commit 567b8a0

Please sign in to comment.