UNPKG

@coolwallet/sol

Version:
712 lines (648 loc) 26.5 kB
import crypto from 'node:crypto'; import { inspect } from 'node:util'; import * as bip39 from 'bip39'; import base58 from 'bs58'; import { Transport } from '@coolwallet/core'; import { createTransport } from '@coolwallet/transport-jre-http'; import { initialize, getTxDetail, DisplayBuilder, CURVE, HDWallet } from '@coolwallet/testing-library'; import { Keypair, Transaction, SystemProgram, PublicKey, StakeProgram, LAMPORTS_PER_SOL } from '@solana/web3.js'; import { createAssociatedTokenAccountInstruction, createTransferInstruction } from '@solana/spl-token'; import SOL, { ASSOCIATED_TOKEN_PROGRAM_ID, TOKEN_PROGRAM_ID } from '../src'; import * as stringUtil from '../src/utils/stringUtil'; import { TOKEN_INFO } from '../src/config/tokenInfos'; type PromiseValue<T> = T extends Promise<infer V> ? V : never; const sol = new SOL(); const mnemonic = bip39.generateMnemonic(); function omit<T extends Record<string, any>>(obj: T, key: keyof T) { return Object.keys(obj).reduce((o, k) => { if (k === key) return o; return { ...o, [k]: obj[k], }; }, {} as T); } describe('Test Solana SDK', () => { const tokens = Object.values(TOKEN_INFO); const getRandInt = (max: number) => Math.floor(Math.random() * max); const getRandToken = () => omit(tokens[getRandInt(tokens.length)], 'signature'); const getRandWallet = () => stringUtil.pubKeyToAddress(crypto.randomBytes(32).toString('hex')); let props: PromiseValue<ReturnType<typeof initialize>>; let transport: Transport; let walletAddress = ''; const wallet = new HDWallet(CURVE.ED25519); const bip32Path = (addressIndex: number) => `m/44'/501'/${addressIndex}'/0'`; beforeAll(async () => { transport = (await createTransport())!; props = await initialize(transport, mnemonic); const address = await sol.getAddress(transport, props.appPrivateKey, props.appId, 0); walletAddress = address; await wallet.setMnemonic(mnemonic); }); it('Test Get Address', async () => { const addressIndex = 0; const node = wallet.derivePath(bip32Path(addressIndex)); const expected = Keypair.fromSeed(node.privateKey); const publicKey = await node.getPublicKey(); expect(walletAddress).toEqual(stringUtil.pubKeyToAddress(publicKey?.toString('hex') ?? '')); expect(walletAddress).toEqual(expected.publicKey.toString()); expect(sol.isValidPublicKey(publicKey ?? '')).toBeTruthy(); const token = getRandWallet(); const [token_account] = sol.findProgramAddress( [publicKey!, TOKEN_PROGRAM_ID, base58.decode(token)], ASSOCIATED_TOKEN_PROGRAM_ID ); expect(sol.isValidPublicKey(token_account)).toBeFalsy(); }); it('Test Get Token Address', async () => { const fromPubkey = getRandWallet(); const token = getRandWallet(); const [result] = sol.findProgramAddress( [base58.decode(fromPubkey), TOKEN_PROGRAM_ID, base58.decode(token)], ASSOCIATED_TOKEN_PROGRAM_ID ); const [expected] = PublicKey.findProgramAddressSync( [base58.decode(fromPubkey), TOKEN_PROGRAM_ID, base58.decode(token)], new PublicKey(ASSOCIATED_TOKEN_PROGRAM_ID) ); expect(result).toEqual(expected.toString()); }); it('Test Normal Transfer', async () => { const addressIndex = 0; const node = wallet.derivePath(bip32Path(addressIndex)); const expectedWallet = Keypair.fromSeed(node.privateKey); const toPubkey = getRandWallet(); const recentBlockhash = getRandWallet(); const lamports = ((getRandInt(10000000) + 1) / 10000000.0) * LAMPORTS_PER_SOL; const signTxData = { transport, appPrivateKey: props.appPrivateKey, appId: props.appId, transaction: { toPubkey, recentBlockhash, lamports, }, addressIndex: 0, }; const signedTx = await sol.signTransferTransaction(signTxData); const recoveredTx = Transaction.from(Buffer.from(signedTx, 'hex')); const expectedTransaction = new Transaction({ feePayer: expectedWallet.publicKey, recentBlockhash, }).add( SystemProgram.transfer({ fromPubkey: expectedWallet.publicKey, toPubkey: new PublicKey(toPubkey), lamports, }) ); const message = expectedTransaction.compileMessage(); const expectedSignature = (await node.sign(message.serialize().toString('hex'))) ?? new Uint8Array(); expectedTransaction.addSignature(expectedWallet.publicKey, Buffer.from(expectedSignature)); try { expect(expectedTransaction.verifySignatures()).toEqual(true); expect(recoveredTx.verifySignatures()).toEqual(true); expect(recoveredTx.serialize().toString('hex')).toEqual(expectedTransaction.serialize().toString('hex')); } catch (e) { console.error('Test Normal Transfer params', signTxData.transaction); throw e; } const display = await getTxDetail(transport, props.appId); const expectedTxDetail = new DisplayBuilder() .messagePage('TEST') .messagePage('SOL') .addressPage(toPubkey) .amountPage(+lamports / LAMPORTS_PER_SOL) .wrapPage('PRESS', 'BUTToN') .finalize(); expect(display).toEqual(expectedTxDetail.toLowerCase()); }); it('Test Create Associate Account', async () => { const addressIndex = 0; const node = wallet.derivePath(bip32Path(addressIndex)); const expectedWallet = Keypair.fromSeed(node.privateKey); const associateAccount = getRandWallet(); const token = getRandToken(); const recentBlockhash = getRandWallet(); const signTxData = { transport, appPrivateKey: props.appPrivateKey, appId: props.appId, transaction: { owner: walletAddress, associateAccount, recentBlockhash, token: token.address, }, addressIndex: 0, }; const signedTx = await sol.signAssociateTokenAccount(signTxData); const recoveredTx = Transaction.from(Buffer.from(signedTx, 'hex')); const expectedTransaction = new Transaction({ feePayer: expectedWallet.publicKey, recentBlockhash, }); const instruction = createAssociatedTokenAccountInstruction( expectedWallet.publicKey, new PublicKey(associateAccount), new PublicKey(expectedWallet.publicKey), new PublicKey(token.address) ); expectedTransaction.instructions = [instruction]; const message = expectedTransaction.compileMessage(); const expectedSignature = (await node.sign(message.serialize().toString('hex'))) ?? new Uint8Array(); expectedTransaction.addSignature(expectedWallet.publicKey, Buffer.from(expectedSignature)); try { expect(recoveredTx.verifySignatures()).toEqual(true); expect(expectedTransaction.verifySignatures()).toEqual(true); expect(recoveredTx.serialize().toString('hex')).toEqual(expectedTransaction.serialize().toString('hex')); } catch (e) { console.error('Test Create Associate Account params', signTxData.transaction); throw e; } const display = await getTxDetail(transport, props.appId); const expectedTxDetail = new DisplayBuilder() .messagePage('TEST') .messagePage('SOL') .wrapPage('ToKEN', 'ACCoUNT') .addressPage(associateAccount) .wrapPage('PRESS', 'BUTToN') .finalize(); expect(display).toEqual(expectedTxDetail.toLowerCase()); }); it('Test SPL Token Transaction', async () => { const addressIndex = 0; const node = wallet.derivePath(bip32Path(addressIndex)); const expectedWallet = Keypair.fromSeed(node.privateKey); const fromTokenAccount = getRandWallet(); const toTokenAccount = getRandWallet(); const recentBlockhash = getRandWallet(); const tokenInfo = getRandToken(); const amount = getRandInt(10 * 10 ** tokenInfo.decimals) + 1; const signTxData = { transport, appPrivateKey: props.appPrivateKey, appId: props.appId, transaction: { walletAddress, fromTokenAccount, toTokenAccount, recentBlockhash, amount, tokenInfo, }, addressIndex: 0, }; const signedTx = await sol.signTransferSplTokenTransaction(signTxData); const recoveredTx = Transaction.from(Buffer.from(signedTx, 'hex')); const expectedTransaction = new Transaction({ feePayer: expectedWallet.publicKey, recentBlockhash, }); const instruction = createTransferInstruction( new PublicKey(fromTokenAccount), new PublicKey(toTokenAccount), new PublicKey(walletAddress), amount ); expectedTransaction.instructions = [instruction]; const message = expectedTransaction.compileMessage(); const expectedSignature = (await node.sign(message.serialize().toString('hex'))) ?? new Uint8Array(); expectedTransaction.addSignature(expectedWallet.publicKey, Buffer.from(expectedSignature)); try { expect(recoveredTx.verifySignatures()).toEqual(true); expect(expectedTransaction.verifySignatures()).toEqual(true); expect(recoveredTx.serialize().toString('hex')).toEqual(expectedTransaction.serialize().toString('hex')); } catch (e) { console.error('Test SPL Token Transaction params', signTxData.transaction); throw e; } const display = await getTxDetail(transport, props.appId); const expectedTxDetail = new DisplayBuilder() .messagePage('TEST') .messagePage('SOL') .messagePage(tokenInfo.symbol) .addressPage(toTokenAccount) .amountPage(amount / 10 ** tokenInfo.decimals) .wrapPage('PRESS', 'BUTToN') .finalize(); expect(display).toEqual(expectedTxDetail.toLowerCase()); }); it('Test Create Token Account and SPL Token Transfer', async () => { const addressIndex = 0; const node = wallet.derivePath(bip32Path(addressIndex)); const expectedWallet = Keypair.fromSeed(node.privateKey); const FROM_PUBKEY = await node.getPublicKey(); const TO_PUBKEY = getRandWallet(); const tokenInfo = getRandToken(); const [fromTokenAccount] = sol.findProgramAddress( [FROM_PUBKEY!, TOKEN_PROGRAM_ID, base58.decode(tokenInfo.address)], ASSOCIATED_TOKEN_PROGRAM_ID ); const [toTokenAccount] = sol.findProgramAddress( [base58.decode(TO_PUBKEY), TOKEN_PROGRAM_ID, base58.decode(tokenInfo.address)], ASSOCIATED_TOKEN_PROGRAM_ID ); const recentBlockhash = getRandWallet(); const amount = getRandInt(10 * 10 ** tokenInfo.decimals) + 1; const signTxData = { transport, appPrivateKey: props.appPrivateKey, appId: props.appId, transaction: { fromTokenAccount, toPubkey: TO_PUBKEY, toTokenAccount, recentBlockhash, amount, tokenInfo, }, addressIndex: 0, }; const signedTx = await sol.signCreateAndTransferSPLToken(signTxData); const recoveredTx = Transaction.from(Buffer.from(signedTx, 'hex')); const expectedTransaction = new Transaction({ feePayer: expectedWallet.publicKey, recentBlockhash, }) .add( createAssociatedTokenAccountInstruction( new PublicKey(FROM_PUBKEY!), new PublicKey(toTokenAccount), new PublicKey(TO_PUBKEY), new PublicKey(tokenInfo.address), new PublicKey(TOKEN_PROGRAM_ID), new PublicKey(ASSOCIATED_TOKEN_PROGRAM_ID) ) ) .add( createTransferInstruction( new PublicKey(fromTokenAccount), new PublicKey(toTokenAccount), new PublicKey(FROM_PUBKEY!), amount ) ); const message = expectedTransaction.compileMessage(); const expectedSignature = (await node.sign(message.serialize().toString('hex'))) ?? new Uint8Array(); expectedTransaction.addSignature(expectedWallet.publicKey, Buffer.from(expectedSignature)); try { expect(recoveredTx.verifySignatures()).toEqual(true); expect(expectedTransaction.verifySignatures()).toEqual(true); expect(recoveredTx.serialize().toString('hex')).toEqual(expectedTransaction.serialize().toString('hex')); } catch (e) { console.error( 'Expected Transaction:', inspect(expectedTransaction.compileMessage(), { showHidden: false, depth: null, colors: true, }) ); console.error( 'Result Transaction:', inspect(recoveredTx.compileMessage(), { showHidden: false, depth: null, colors: true, }) ); throw e; } const display = await getTxDetail(transport, props.appId); const expectedTxDetail = new DisplayBuilder() .messagePage('TEST') .messagePage('SOL') .messagePage(tokenInfo.symbol) .addressPage(TO_PUBKEY) .amountPage(amount / 10 ** tokenInfo.decimals) .wrapPage('PRESS', 'BUTToN') .finalize(); expect(display).toEqual(expectedTxDetail.toLowerCase()); }); it('Test Delegate', async () => { const addressIndex = 0; const node = wallet.derivePath(bip32Path(addressIndex)); const expectedWallet = Keypair.fromSeed(node.privateKey); const FROM_PUBKEY = expectedWallet.publicKey; const recentBlockhash = getRandWallet(); const SEED = 'stake:0'; const STAKE_ACCOUNT = await sol.createWithSeed(FROM_PUBKEY.toBuffer(), SEED, StakeProgram.programId.toBuffer()); const VALIDATOR = new PublicKey(getRandWallet()); const signTxData = { transport, appPrivateKey: props.appPrivateKey, appId: props.appId, transaction: { authorizedPubkey: FROM_PUBKEY.toString(), stakePubkey: STAKE_ACCOUNT.toString(), votePubkey: VALIDATOR.toString(), recentBlockhash, }, addressIndex: 0, }; const signedTx = await sol.signDelegate(signTxData); const recoveredTx = Transaction.from(Buffer.from(signedTx, 'hex')); const expectedTransaction = StakeProgram.delegate({ stakePubkey: new PublicKey(STAKE_ACCOUNT), authorizedPubkey: FROM_PUBKEY, votePubkey: VALIDATOR, }); expectedTransaction.feePayer = FROM_PUBKEY; expectedTransaction.recentBlockhash = recentBlockhash; const message = expectedTransaction.compileMessage(); const expectedSignature = (await node.sign(message.serialize().toString('hex'))) ?? new Uint8Array(); expectedTransaction.addSignature(FROM_PUBKEY, Buffer.from(expectedSignature)); try { expect(recoveredTx.verifySignatures()).toEqual(true); expect(expectedTransaction.verifySignatures()).toEqual(true); expect(recoveredTx.serialize().toString('hex')).toEqual(expectedTransaction.serialize().toString('hex')); } catch (e) { console.error('Test Delegate', signTxData.transaction); throw e; } const display = await getTxDetail(transport, props.appId); const expectedTxDetail = new DisplayBuilder() .messagePage('TEST') .messagePage('SOL') .messagePage('STAKE') .addressPage(VALIDATOR.toBase58()) .wrapPage('PRESS', 'BUTToN') .finalize(); expect(display).toEqual(expectedTxDetail.toLowerCase()); }); it('Test Undelegate', async () => { const addressIndex = 0; const node = wallet.derivePath(bip32Path(addressIndex)); const expectedWallet = Keypair.fromSeed(node.privateKey); const FROM_PUBKEY = expectedWallet.publicKey; const recentBlockhash = getRandWallet(); const SEED = 'stake:0'; const STAKE_ACCOUNT = await sol.createWithSeed(FROM_PUBKEY.toString(), SEED, StakeProgram.programId.toString()); const signTxData = { transport, appPrivateKey: props.appPrivateKey, appId: props.appId, transaction: { stakePubkey: STAKE_ACCOUNT.toString(), authorizedPubkey: walletAddress, recentBlockhash, }, addressIndex: 0, }; const signedTx = await sol.signUndelegate(signTxData); const recoveredTx = Transaction.from(Buffer.from(signedTx, 'hex')); const expectedTransaction = new Transaction({ feePayer: expectedWallet.publicKey, recentBlockhash, }).add( StakeProgram.deactivate({ authorizedPubkey: new PublicKey(walletAddress), stakePubkey: new PublicKey(STAKE_ACCOUNT), }) ); const message = expectedTransaction.compileMessage(); const expectedSignature = (await node.sign(message.serialize().toString('hex'))) ?? new Uint8Array(); expectedTransaction.addSignature(expectedWallet.publicKey, Buffer.from(expectedSignature)); try { expect(recoveredTx.verifySignatures()).toEqual(true); expect(expectedTransaction.verifySignatures()).toEqual(true); expect(recoveredTx.serialize().toString('hex')).toEqual(expectedTransaction.serialize().toString('hex')); } catch (e) { console.error('Test Undelegate params', signTxData.transaction); throw e; } const display = await getTxDetail(transport, props.appId); const expectedTxDetail = new DisplayBuilder() .messagePage('TEST') .messagePage('SOL') .messagePage('UnDel') .addressPage(walletAddress) .wrapPage('PRESS', 'BUTToN') .finalize(); expect(display).toEqual(expectedTxDetail.toLowerCase()); }); it('Test Delegate And CreateAccountWithSeed', async () => { const addressIndex = 0; const node = wallet.derivePath(bip32Path(addressIndex)); const expectedWallet = Keypair.fromSeed(node.privateKey); const FROM_PUBKEY = expectedWallet.publicKey; const recentBlockhash = getRandWallet(); const SEED = 'stake:0'; const STAKE_ACCOUNT = await sol.createWithSeed(FROM_PUBKEY.toString(), SEED, StakeProgram.programId.toString()); const VALIDATOR = new PublicKey(getRandWallet()); const lamports = ((getRandInt(10000000) + 1) / 10000000.0) * LAMPORTS_PER_SOL; const signTxData = { transport, appPrivateKey: props.appPrivateKey, appId: props.appId, transaction: { newAccountPubkey: STAKE_ACCOUNT, basePubkey: walletAddress, seed: SEED, votePubkey: VALIDATOR.toString(), lamports, recentBlockhash, }, addressIndex: 0, }; const signedTx = await sol.signDelegateAndCreateAccountWithSeed(signTxData); const recoveredTx = Transaction.from(Buffer.from(signedTx, 'hex')); const expectedTransaction = StakeProgram.createAccountWithSeed({ fromPubkey: FROM_PUBKEY, stakePubkey: new PublicKey(STAKE_ACCOUNT), basePubkey: FROM_PUBKEY, seed: SEED, authorized: { staker: FROM_PUBKEY, withdrawer: FROM_PUBKEY, }, lamports, }); expectedTransaction.feePayer = FROM_PUBKEY; expectedTransaction.recentBlockhash = recentBlockhash; const [delegateInstruction] = StakeProgram.delegate({ stakePubkey: new PublicKey(STAKE_ACCOUNT), authorizedPubkey: FROM_PUBKEY, votePubkey: VALIDATOR, }).instructions; expectedTransaction.add(delegateInstruction); const message = expectedTransaction.compileMessage(); const expectedSignature = (await node.sign(message.serialize().toString('hex'))) ?? new Uint8Array(); expectedTransaction.addSignature(FROM_PUBKEY, Buffer.from(expectedSignature)); try { expect(recoveredTx.verifySignatures()).toEqual(true); expect(expectedTransaction.verifySignatures()).toEqual(true); expect(recoveredTx.serialize().toString('hex')).toEqual(expectedTransaction.serialize().toString('hex')); } catch (e) { console.error('Test Delegate And CreateAccountWithSeed', signTxData.transaction); throw e; } const display = await getTxDetail(transport, props.appId); const expectedTxDetail = new DisplayBuilder() .messagePage('TEST') .messagePage('SOL') .messagePage('STAKE') .addressPage(VALIDATOR.toBase58()) .amountPage(+lamports / LAMPORTS_PER_SOL) .wrapPage('PRESS', 'BUTToN') .finalize(); expect(display).toEqual(expectedTxDetail.toLowerCase()); }); it('Test Normal Transfer With SignTransaction', async () => { const addressIndex = 0; const node = wallet.derivePath(bip32Path(addressIndex)); const expectedWallet = Keypair.fromSeed(node.privateKey); const toPubkey = getRandWallet(); const recentBlockhash = getRandWallet(); const lamports = ((getRandInt(10000000) + 1) / 10000000.0) * LAMPORTS_PER_SOL; const signTxData = { transport, appPrivateKey: props.appPrivateKey, appId: props.appId, transaction: { toPubkey, recentBlockhash, lamports, }, addressIndex: 0, }; const signedTx = await sol.signTransaction(signTxData); const recoveredTx = Transaction.from(Buffer.from(signedTx, 'hex')); const expectedTransaction = new Transaction({ feePayer: expectedWallet.publicKey, recentBlockhash, }).add( SystemProgram.transfer({ fromPubkey: expectedWallet.publicKey, toPubkey: new PublicKey(toPubkey), lamports, }) ); const message = expectedTransaction.compileMessage(); const expectedSignature = (await node.sign(message.serialize().toString('hex'))) ?? new Uint8Array(); expectedTransaction.addSignature(expectedWallet.publicKey, Buffer.from(expectedSignature)); try { expect(recoveredTx.verifySignatures()).toEqual(true); expect(expectedTransaction.verifySignatures()).toEqual(true); expect(recoveredTx.serialize().toString('hex')).toEqual(expectedTransaction.serialize().toString('hex')); } catch (e) { console.error('Test Normal Transfer params', signTxData.transaction); throw e; } const display = await getTxDetail(transport, props.appId); const expectedTxDetail = new DisplayBuilder() .messagePage('TEST') .messagePage('SOL') .addressPage(toPubkey) .amountPage(+lamports / LAMPORTS_PER_SOL) .wrapPage('PRESS', 'BUTToN') .finalize(); expect(display).toEqual(expectedTxDetail.toLowerCase()); }); it('Test Staking Withdraw with different toPubkey', async () => { const addressIndex = 0; const node = wallet.derivePath(bip32Path(addressIndex)); const expectedWallet = Keypair.fromSeed(node.privateKey); const lamports = ((getRandInt(10000000) + 1) / 10000000.0) * LAMPORTS_PER_SOL; const recentBlockhash = getRandWallet(); const stakePubkey = getRandWallet(); const withdrawToPubKey = getRandWallet(); const signTxData = { transport, appPrivateKey: props.appPrivateKey, appId: props.appId, transaction: { stakePubkey, withdrawToPubKey, recentBlockhash, lamports, }, addressIndex: 0, }; const signedTx = await sol.signTransaction(signTxData); const recoveredTx = Transaction.from(Buffer.from(signedTx, 'hex')); const expectedTransaction = StakeProgram.withdraw({ authorizedPubkey: expectedWallet.publicKey, lamports, stakePubkey: new PublicKey(stakePubkey), toPubkey: new PublicKey(withdrawToPubKey), }); expectedTransaction.feePayer = expectedWallet.publicKey; expectedTransaction.recentBlockhash = recentBlockhash; const message = expectedTransaction.compileMessage(); const expectedSignature = (await node.sign(message.serialize().toString('hex'))) ?? new Uint8Array(); expectedTransaction.addSignature(expectedWallet.publicKey, Buffer.from(expectedSignature)); try { expect(recoveredTx.verifySignatures()).toEqual(true); expect(expectedTransaction.verifySignatures()).toEqual(true); expect(recoveredTx.serialize().toString('hex')).toEqual(expectedTransaction.serialize().toString('hex')); } catch (e) { console.error('Test Staking Withdraw params', signTxData.transaction); throw e; } const display = await getTxDetail(transport, props.appId); const expectedTxDetail = new DisplayBuilder() .messagePage('TEST') .messagePage('SOL') .messagePage('Reward') .addressPage(withdrawToPubKey) .amountPage(+lamports / LAMPORTS_PER_SOL) .wrapPage('PRESS', 'BUTToN') .finalize(); expect(display).toEqual(expectedTxDetail.toLowerCase()); }); it('Test Staking Withdraw with Same toPubkey', async () => { const addressIndex = 0; const node = wallet.derivePath(bip32Path(addressIndex)); const expectedWallet = Keypair.fromSeed(node.privateKey); const lamports = ((getRandInt(10000000) + 1) / 10000000.0) * LAMPORTS_PER_SOL; const recentBlockhash = getRandWallet(); const stakePubkey = getRandWallet(); const withdrawToPubKey = expectedWallet.publicKey; const signTxData = { transport, appPrivateKey: props.appPrivateKey, appId: props.appId, transaction: { stakePubkey, withdrawToPubKey: withdrawToPubKey.toString(), recentBlockhash, lamports, }, addressIndex: 0, }; const signedTx = await sol.signTransaction(signTxData); const recoveredTx = Transaction.from(Buffer.from(signedTx, 'hex')); const expectedTransaction = StakeProgram.withdraw({ authorizedPubkey: withdrawToPubKey, lamports, stakePubkey: new PublicKey(stakePubkey), toPubkey: withdrawToPubKey, }); expectedTransaction.feePayer = expectedWallet.publicKey; expectedTransaction.recentBlockhash = recentBlockhash; const message = expectedTransaction.compileMessage(); const expectedSignature = (await node.sign(message.serialize().toString('hex'))) ?? new Uint8Array(); expectedTransaction.addSignature(expectedWallet.publicKey, Buffer.from(expectedSignature)); try { expect(recoveredTx.verifySignatures()).toEqual(true); expect(expectedTransaction.verifySignatures()).toEqual(true); expect(recoveredTx.serialize().toString('hex')).toEqual(expectedTransaction.serialize().toString('hex')); } catch (e) { console.error('Test Staking Withdraw params', signTxData.transaction); throw e; } const display = await getTxDetail(transport, props.appId); const expectedTxDetail = new DisplayBuilder() .messagePage('TEST') .messagePage('SOL') .messagePage('Reward') .addressPage(withdrawToPubKey.toString()) .amountPage(+lamports / LAMPORTS_PER_SOL) .wrapPage('PRESS', 'BUTToN') .finalize(); expect(display).toEqual(expectedTxDetail.toLowerCase()); }); });