Skip to content

Commit

Permalink
Port @suite-common/wallet-core and @suite-common/wallet-utils to …
Browse files Browse the repository at this point in the history
…`@solana/web3.js` version 2

1. Corrected a decimal amount in one of the fixtures. That `amount` field is denominated in basis points.
2. Deleted most of the custom transaction instruction formatting code, in favour of the new auto-generated program clients for the System, Compute Budget, and Token programs.
3. Added a note that `lastValidBlockHeight` is sometimes `undefined` in tests
  • Loading branch information
steveluscher committed Nov 23, 2024
1 parent 85059a1 commit 2e47a86
Show file tree
Hide file tree
Showing 6 changed files with 269 additions and 220 deletions.
18 changes: 6 additions & 12 deletions suite-common/wallet-core/src/send/sendFormSolanaThunks.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@ import {
calculateTotal,
formatAmount,
getExternalComposeOutput,
getPubKeyFromAddress,
buildTransferTransaction,
buildTokenTransferTransaction,
getAssociatedTokenAccountAddress,
Expand Down Expand Up @@ -202,7 +201,7 @@ export const composeSolanaTransactionFeeLevelsThunk = createThunk<
// Since all the values don't have to be filled in the form at the time of this function call, we use dummy values
// for the estimation, since these values don't affect the final fee.
// The real transaction is constructed in `signTransaction`, this one is used solely for fee estimation and is never submitted.
const transactionMessage = (
const transferTx =
tokenTransferTxAndDestinationAddress != null
? tokenTransferTxAndDestinationAddress.transaction
: await buildTransferTransaction(
Expand All @@ -212,8 +211,7 @@ export const composeSolanaTransactionFeeLevelsThunk = createThunk<
blockhash,
lastValidBlockHeight,
dummyPriorityFeesForFeeEstimation,
)
).compileMessage();
);

const isCreatingAccount =
tokenInfo &&
Expand All @@ -225,7 +223,7 @@ export const composeSolanaTransactionFeeLevelsThunk = createThunk<
coin: account.symbol,
request: {
specific: {
data: transactionMessage.serialize().toString('hex'),
data: transferTx.serialize(),
isCreatingAccount,
},
},
Expand Down Expand Up @@ -376,8 +374,6 @@ export const signSolanaSendFormTransactionThunk = createThunk<
},
);

const serializedTx = tx.serializeMessage().toString('hex');

const response = await TrezorConnect.solanaSignTransaction({
device: {
path: device.path,
Expand All @@ -386,7 +382,7 @@ export const signSolanaSendFormTransactionThunk = createThunk<
},
useEmptyPassphrase: device.useEmptyPassphrase,
path: selectedAccount.path,
serializedTx,
serializedTx: tx.serializeMessage(),
additionalInfo:
tokenTransferTxAndDestinationAddress &&
tokenTransferTxAndDestinationAddress.tokenAccountInfo
Expand All @@ -407,10 +403,8 @@ export const signSolanaSendFormTransactionThunk = createThunk<
});
}

const signerPubKey = await getPubKeyFromAddress(selectedAccount.descriptor);
tx.addSignature(signerPubKey, Buffer.from(response.payload.signature, 'hex'));

const signedSerializedTx = tx.serialize().toString('hex');
await tx.addSignature(response.payload.signature);
const signedSerializedTx = tx.serialize();

return { serializedTx: signedSerializedTx };
},
Expand Down
3 changes: 3 additions & 0 deletions suite-common/wallet-utils/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,9 @@
},
"dependencies": {
"@mobily/ts-belt": "^3.13.1",
"@solana-program/compute-budget": "^0.6.1",
"@solana-program/system": "^0.6.2",
"@solana-program/token": "^0.4.1",
"@solana/buffer-layout": "^4.0.1",
"@solana/web3.js": "^2.0.0",
"@suite-common/fiat-services": "workspace:*",
Expand Down
78 changes: 38 additions & 40 deletions suite-common/wallet-utils/src/__fixtures__/solanaUtils.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import { AccountRole } from '@solana/web3.js';

import { BigNumber } from '@trezor/utils/src/bigNumber';
import {
TOKEN_PROGRAM_PUBLIC_KEY,
Expand Down Expand Up @@ -96,34 +98,33 @@ export const fixtures = {
from: 'CR6QfobBidQTSYdR6jihKTfMnHkRUtw8cLDCxENDVYmd',
to: 'GrwHUG2U6Nmr2CHjQ2kesKzbjMwvCNytcMAbhQxq1Jyd',
owner: 'ETxHeBBcuw9Yu4dGuP3oXrD12V5RECvmi8ogQ9PkjyVF',
amount: new BigNumber('0.1'),
amount: new BigNumber('1'),
mint: '6YuhWADZyAAxAaVKPm1G5N51RvDBXsnWo4SfsJ47wSoK',
decimals: 9,
},
expectedOutput: {
keys: [
{
pubkey: 'CR6QfobBidQTSYdR6jihKTfMnHkRUtw8cLDCxENDVYmd',
isSigner: false,
isWritable: true,
},
accounts: [
{
pubkey: '6YuhWADZyAAxAaVKPm1G5N51RvDBXsnWo4SfsJ47wSoK',
isSigner: false,
isWritable: false,
address: 'CR6QfobBidQTSYdR6jihKTfMnHkRUtw8cLDCxENDVYmd',
role: AccountRole.WRITABLE,
},
{
pubkey: 'GrwHUG2U6Nmr2CHjQ2kesKzbjMwvCNytcMAbhQxq1Jyd',
isSigner: false,
isWritable: true,
address: '6YuhWADZyAAxAaVKPm1G5N51RvDBXsnWo4SfsJ47wSoK',
role: AccountRole.READONLY,
},
{
pubkey: 'ETxHeBBcuw9Yu4dGuP3oXrD12V5RECvmi8ogQ9PkjyVF',
isSigner: true,
isWritable: false,
address: 'GrwHUG2U6Nmr2CHjQ2kesKzbjMwvCNytcMAbhQxq1Jyd',
role: AccountRole.WRITABLE,
},
expect.objectContaining({
address: 'ETxHeBBcuw9Yu4dGuP3oXrD12V5RECvmi8ogQ9PkjyVF',
role: AccountRole.READONLY_SIGNER,
signer: expect.objectContaining({
address: 'ETxHeBBcuw9Yu4dGuP3oXrD12V5RECvmi8ogQ9PkjyVF',
}),
}),
],
data: Buffer.from([12, 0, 0, 0, 0, 0, 0, 0, 0, 9]),
data: new Uint8Array([12, 1, 0, 0, 0, 0, 0, 0, 0, 9]),
},
},
],
Expand All @@ -137,39 +138,36 @@ export const fixtures = {
},
expectedOutput: {
pubkey: 'GrwHUG2U6Nmr2CHjQ2kesKzbjMwvCNytcMAbhQxq1Jyd',
keys: [
{
pubkey: 'ETxHeBBcuw9Yu4dGuP3oXrD12V5RECvmi8ogQ9PkjyVF',
isSigner: true,
isWritable: true,
},
accounts: [
expect.objectContaining({
address: 'ETxHeBBcuw9Yu4dGuP3oXrD12V5RECvmi8ogQ9PkjyVF',
role: AccountRole.WRITABLE_SIGNER,
signer: expect.objectContaining({
address: 'ETxHeBBcuw9Yu4dGuP3oXrD12V5RECvmi8ogQ9PkjyVF',
}),
}),
{
pubkey: 'GrwHUG2U6Nmr2CHjQ2kesKzbjMwvCNytcMAbhQxq1Jyd',
isSigner: false,
isWritable: true,
address: 'GrwHUG2U6Nmr2CHjQ2kesKzbjMwvCNytcMAbhQxq1Jyd',
role: AccountRole.WRITABLE,
},
{
pubkey: 'FAeNERRWGL8xtnwtM5dWBUs9Z1y5fenSJcawu55NQSWk',
isSigner: false,
isWritable: false,
address: 'FAeNERRWGL8xtnwtM5dWBUs9Z1y5fenSJcawu55NQSWk',
role: AccountRole.READONLY,
},
{
pubkey: '6YuhWADZyAAxAaVKPm1G5N51RvDBXsnWo4SfsJ47wSoK',
isSigner: false,
isWritable: false,
address: '6YuhWADZyAAxAaVKPm1G5N51RvDBXsnWo4SfsJ47wSoK',
role: AccountRole.READONLY,
},
{
pubkey: SYSTEM_PROGRAM_PUBLIC_KEY,
isSigner: false,
isWritable: false,
address: SYSTEM_PROGRAM_PUBLIC_KEY,
role: AccountRole.READONLY,
},
{
pubkey: TOKEN_PROGRAM_PUBLIC_KEY,
isSigner: false,
isWritable: false,
address: TOKEN_PROGRAM_PUBLIC_KEY,
role: AccountRole.READONLY,
},
],
data: Buffer.from([]),
data: new Uint8Array([0]),
},
},
],
Expand Down Expand Up @@ -198,7 +196,7 @@ export const fixtures = {
},
},
expectedOutput:
'01000609c80f8b50107e9f3e3c16a661b8c806df454a6deb293d5e8730a9d28f2f4998c6a99c9c4d0c7def9dd60a3a40dc5266faf41996310aa62ad6cbd9b64e1e2cca78ebaa24826cef9644c1ecf0dfcf955775b8438528e97820efc2b20ed46be1dc580000000000000000000000000000000000000000000000000000000000000000527706a12f3f7c3c852582f0f79b515c03c6ffbe6e3100044ba7c982eb5cf9f28c97258f4e2489f1bb3d1029148e0d830b5a1399daff1084048e7bd8dbe9f8590306466fe5211732ffecadba72c39be7bc8ce5bbc5f7126b2c439b3a40000000d27c181cb023db6239e22e49e4b67f7dd9ed13f3d7ed319f9e91b3bc64cec0a906ddf6e1d765a193d9cbe146ceeb79ac1cb485ed5f5b37913a8cf5857eff00a96772b7d36a2e66e52c817f385d7e94d3d4b6d47d7171c9f2dd86c6f1be1a93eb040600050250c3000006000903a0860100000000000506000207040308000804010402000a0c00e1f5050000000009',
'01000609c80f8b50107e9f3e3c16a661b8c806df454a6deb293d5e8730a9d28f2f4998c6a99c9c4d0c7def9dd60a3a40dc5266faf41996310aa62ad6cbd9b64e1e2cca78ebaa24826cef9644c1ecf0dfcf955775b8438528e97820efc2b20ed46be1dc580000000000000000000000000000000000000000000000000000000000000000527706a12f3f7c3c852582f0f79b515c03c6ffbe6e3100044ba7c982eb5cf9f28c97258f4e2489f1bb3d1029148e0d830b5a1399daff1084048e7bd8dbe9f8590306466fe5211732ffecadba72c39be7bc8ce5bbc5f7126b2c439b3a40000000d27c181cb023db6239e22e49e4b67f7dd9ed13f3d7ed319f9e91b3bc64cec0a906ddf6e1d765a193d9cbe146ceeb79ac1cb485ed5f5b37913a8cf5857eff00a96772b7d36a2e66e52c817f385d7e94d3d4b6d47d7171c9f2dd86c6f1be1a93eb040600050250c3000006000903a086010000000000050600020704030801000804010402000a0c00e1f5050000000009',
},
{
description:
Expand Down
12 changes: 4 additions & 8 deletions suite-common/wallet-utils/src/__tests__/solanaUtils.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,9 +34,7 @@ describe('solana utils', () => {
input.decimals,
);

const keys = txix.keys.map(key => ({ ...key, pubkey: key.pubkey.toString() }));

expect(keys).toEqual(expectedOutput.keys);
expect(txix.accounts).toEqual(expectedOutput.accounts);
expect(txix.data).toEqual(expectedOutput.data);
});
});
Expand All @@ -52,10 +50,8 @@ describe('solana utils', () => {
input.tokenMintAddress,
);

const keys = txix.keys.map(key => ({ ...key, pubkey: key.pubkey.toString() }));

expect(pubkey.toString()).toEqual(expectedOutput.pubkey);
expect(keys).toEqual(expectedOutput.keys);
expect(pubkey).toEqual(expectedOutput.pubkey);
expect(txix.accounts).toEqual(expectedOutput.accounts);
expect(txix.data).toEqual(expectedOutput.data);
});
},
Expand All @@ -78,7 +74,7 @@ describe('solana utils', () => {
input.lastValidBlockHeight,
input.priorityFees,
);
const message = tx.transaction.compileMessage().serialize().toString('hex');
const message = tx.transaction.serializeMessage();

expect(message).toEqual(expectedOutput);
});
Expand Down
Loading

0 comments on commit 2e47a86

Please sign in to comment.