Skip to content

Commit

Permalink
Merge branch 'onekey' into fix/inpageInject
Browse files Browse the repository at this point in the history
  • Loading branch information
huhuanming authored Mar 12, 2024
2 parents cc99e0e + e2c8369 commit 8bb931f
Show file tree
Hide file tree
Showing 3 changed files with 94 additions and 11 deletions.
58 changes: 47 additions & 11 deletions packages/engine/src/vaults/impl/sol/Vault.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ import {
getAssociatedTokenAddressSync,
} from '@solana/spl-token';
import {
ComputeBudgetProgram,
PublicKey,
SYSVAR_INSTRUCTIONS_PUBKEY,
SystemInstruction,
Expand Down Expand Up @@ -84,6 +85,7 @@ import {
import { ClientSol, PARAMS_ENCODINGS } from './sdk';
import settings from './settings';
import {
MIN_PRIORITY_FEE,
TOKEN_AUTH_RULES_ID,
TOKEN_METADATA_PROGRAM_ID,
masterEditionAddress,
Expand Down Expand Up @@ -121,6 +123,7 @@ import type {
} from '../../types';
import type {
AssociatedTokenInfo,
IEncodedTxSol,
INativeTxSol,
ParsedAccountInfo,
} from './types';
Expand Down Expand Up @@ -584,16 +587,16 @@ export default class Vault extends VaultBase {
let lastRpcErrorMessage = '';
const maxRetryTimes = 5;
const client = await this.getClient();
const accountAddress = await this.getAccountAddress();
const transferInfo = transferInfos[0];
const { from, to: firstReceiver, isNFT } = transferInfo;

const source = new PublicKey(from);
const nativeTx = new Transaction();

const doGetFee = async () => {
const doGetRecentBlockHash = async () => {
try {
const [, recentBlockhash] = await client.getFees();
return recentBlockhash;
return await client.getLatestBlockHash();
} catch (error: any) {
const rpcErrorData = error?.data as
| {
Expand All @@ -612,16 +615,30 @@ export default class Vault extends VaultBase {
retryTime += 1;
if (retryTime > maxRetryTimes) {
throw new Error(
`Solana getFees retry times exceeded: ${lastRpcErrorMessage || ''}`,
`Solana getLatestBlockHash retry times exceeded: ${
lastRpcErrorMessage || ''
}`,
);
}
const recentBlockhash = await doGetFee();
nativeTx.recentBlockhash = recentBlockhash;
const resp = await doGetRecentBlockHash();
nativeTx.recentBlockhash = resp?.blockhash;
nativeTx.lastValidBlockHeight = resp?.lastValidBlockHeight;
await wait(1000);
} while (!nativeTx.recentBlockhash);

nativeTx.feePayer = source;

// To make sure tx can be processed
const prioritizationFee = await client.getRecentMaxPrioritizationFees([
accountAddress,
]);

const addPriorityFee = ComputeBudgetProgram.setComputeUnitPrice({
microLamports: Math.max(MIN_PRIORITY_FEE, prioritizationFee),
});

nativeTx.add(addPriorityFee);

for (let i = 0; i < transferInfos.length; i += 1) {
const {
token: tokenAddress,
Expand Down Expand Up @@ -1237,13 +1254,28 @@ export default class Vault extends VaultBase {
return client.getFeePricePerUnit();
}

override async fetchFeeInfo(encodedTx: IEncodedTx): Promise<IFeeInfo> {
const [network, { prices }, nativeTx] = await Promise.all([
override async fetchFeeInfo(encodedTx: IEncodedTxSol): Promise<IFeeInfo> {
const client = await this.getClient();
const nativeTx = await this.helper.parseToNativeTx(encodedTx);
const isVersionedTransaction = nativeTx instanceof VersionedTransaction;
let message = '';
if (isVersionedTransaction) {
message = Buffer.from(nativeTx.message.serialize()).toString('base64');
} else {
message = (nativeTx as Transaction)
.compileMessage()
.serialize()
.toString('base64');
}
const [network, feePerSig] = await Promise.all([
this.getNetwork(),
this.engine.getGasInfo(this.networkId),
this.helper.parseToNativeTx(encodedTx),
client.getFeesForMessage(message),
]);

const prices = [
new BigNumber(feePerSig).shiftedBy(-network.feeDecimals).toFixed(),
];

return {
nativeSymbol: network.symbol,
nativeDecimals: network.decimals,
Expand Down Expand Up @@ -1486,7 +1518,11 @@ export default class Vault extends VaultBase {
transaction,
);
const client = await this.getClient();
[, nativeTx.recentBlockhash] = await client.getFees();
const { blockhash, lastValidBlockHeight } =
await client.getLatestBlockHash();

nativeTx.recentBlockhash = blockhash;
nativeTx.lastValidBlockHeight = lastValidBlockHeight;

return bs58.encode(nativeTx.serialize({ requireAllSignatures: false }));
}
Expand Down
45 changes: 45 additions & 0 deletions packages/engine/src/vaults/impl/sol/sdk/ClientSol.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
// eslint-disable-next-line @typescript-eslint/naming-convention
import { TOKEN_PROGRAM_ID } from '@solana/spl-token';
import BigNumber from 'bignumber.js';
import { map, max } from 'lodash';

import { BaseClient } from '@onekeyhq/engine/src/client/BaseClient';
import { JsonRPCRequest } from '@onekeyhq/shared/src/request/JsonRPCRequest';
Expand All @@ -24,8 +25,11 @@ export enum RPC_METHODS {
GET_ACCOUNT_INFO = 'getAccountInfo',
GET_TOKEN_ACCOUNTS_BY_OWNER = 'getTokenAccountsByOwner',
GET_FEES = 'getFees',
GET_FEES_FOR_MESSAGE = 'getFeeForMessage',
GET_RECENT_PRIORITIZATION_FEES = 'getRecentPrioritizationFees',
GET_TRANSACTION = 'getTransaction',
GET_MINIMUM_BALANCE_FOR_RENT_EXEMPTION = 'getMinimumBalanceForRentExemption',
GET_LATEST_BLOCK_HASH = 'getLatestBlockhash',
}
// eslint-disable-next-line @typescript-eslint/naming-convention
export enum PARAMS_ENCODINGS {
Expand Down Expand Up @@ -214,6 +218,47 @@ export class ClientSol extends BaseClient {
return [feePerSig, recentBlockhash];
}

async getFeesForMessage(message: string) {
const resp = await this.rpc.call<{
value: number;
}>(RPC_METHODS.GET_FEES_FOR_MESSAGE, [
message,
{
commitment: 'confirmed',
},
]);

return resp.value;
}

async getRecentPrioritizationFees(accountAddresses: string[]) {
const resp = await this.rpc.call<
{ slot: number; prioritizationFee: number }[]
>(RPC_METHODS.GET_RECENT_PRIORITIZATION_FEES, [accountAddresses]);

return resp;
}

async getRecentMaxPrioritizationFees(accountAddress: string[]) {
const resp = await this.getRecentPrioritizationFees(accountAddress);
return max(map(resp, 'prioritizationFee')) || 0;
}

async getLatestBlockHash() {
const resp = await this.rpc.call<{
value: { blockhash: string; lastValidBlockHeight: number };
}>(RPC_METHODS.GET_LATEST_BLOCK_HASH, [
{
commitment: 'confirmed',
},
]);

return {
blockhash: resp.value.blockhash,
lastValidBlockHeight: resp.value.lastValidBlockHeight,
};
}

async getTransactionStatuses(
txids: string[],
): Promise<Array<TransactionStatus | undefined>> {
Expand Down
2 changes: 2 additions & 0 deletions packages/engine/src/vaults/impl/sol/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@ export const TOKEN_AUTH_RULES_ID = new PublicKey(
'auth9SigNpDKz4sJJ1DfCTuZrZNSAgh9sFD3rboVmgg',
);

export const MIN_PRIORITY_FEE = 1000;

export function metadataAddress(mint: PublicKey): PublicKey {
return PublicKey.findProgramAddressSync(
[
Expand Down

0 comments on commit 8bb931f

Please sign in to comment.