chore: update Connection to non-deprecated endpoints (#22800)
* chore: remove usage of `getConfirmedTransaction` * chore: use `getBlock` instead of `getConfirmedBlock` * chore: add `getLatestBlockhash` and test
This commit is contained in:
@ -504,8 +504,15 @@ export type TokenBalance = {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Metadata for a parsed confirmed transaction on the ledger
|
* Metadata for a parsed confirmed transaction on the ledger
|
||||||
|
*
|
||||||
|
* @deprecated Deprecated since Solana v1.8.0. Please use {@link ParsedTransactionMeta} instead.
|
||||||
*/
|
*/
|
||||||
export type ParsedConfirmedTransactionMeta = {
|
export type ParsedConfirmedTransactionMeta = ParsedTransactionMeta;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Metadata for a parsed transaction on the ledger
|
||||||
|
*/
|
||||||
|
export type ParsedTransactionMeta = {
|
||||||
/** The fee charged for processing the transaction */
|
/** The fee charged for processing the transaction */
|
||||||
fee: number;
|
fee: number;
|
||||||
/** An array of cross program invoked parsed instructions */
|
/** An array of cross program invoked parsed instructions */
|
||||||
@ -644,14 +651,21 @@ export type ParsedTransaction = {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* A parsed and confirmed transaction on the ledger
|
* A parsed and confirmed transaction on the ledger
|
||||||
|
*
|
||||||
|
* @deprecated Deprecated since Solana v1.8.0. Please use {@link ParsedTransactionWithMeta} instead.
|
||||||
*/
|
*/
|
||||||
export type ParsedConfirmedTransaction = {
|
export type ParsedConfirmedTransaction = ParsedTransactionWithMeta;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A parsed transaction on the ledger with meta
|
||||||
|
*/
|
||||||
|
export type ParsedTransactionWithMeta = {
|
||||||
/** The slot during which the transaction was processed */
|
/** The slot during which the transaction was processed */
|
||||||
slot: number;
|
slot: number;
|
||||||
/** The details of the transaction */
|
/** The details of the transaction */
|
||||||
transaction: ParsedTransaction;
|
transaction: ParsedTransaction;
|
||||||
/** Metadata produced from the transaction */
|
/** Metadata produced from the transaction */
|
||||||
meta: ParsedConfirmedTransactionMeta | null;
|
meta: ParsedTransactionMeta | null;
|
||||||
/** The unix timestamp of when the transaction was processed */
|
/** The unix timestamp of when the transaction was processed */
|
||||||
blockTime?: number | null;
|
blockTime?: number | null;
|
||||||
};
|
};
|
||||||
@ -720,9 +734,9 @@ export type ConfirmedBlock = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A ConfirmedBlock on the ledger with signatures only
|
* A Block on the ledger with signatures only
|
||||||
*/
|
*/
|
||||||
export type ConfirmedBlockSignatures = {
|
export type BlockSignatures = {
|
||||||
/** Blockhash of this block */
|
/** Blockhash of this block */
|
||||||
blockhash: Blockhash;
|
blockhash: Blockhash;
|
||||||
/** Blockhash of this block's parent */
|
/** Blockhash of this block's parent */
|
||||||
@ -1494,8 +1508,41 @@ const ParsedConfirmedTransactionMetaResult = pick({
|
|||||||
postTokenBalances: optional(nullable(array(TokenBalanceResult))),
|
postTokenBalances: optional(nullable(array(TokenBalanceResult))),
|
||||||
});
|
});
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Expected JSON RPC response for the "getBlock" message
|
||||||
|
*/
|
||||||
|
const GetBlockRpcResult = jsonRpcResult(
|
||||||
|
nullable(
|
||||||
|
pick({
|
||||||
|
blockhash: string(),
|
||||||
|
previousBlockhash: string(),
|
||||||
|
parentSlot: number(),
|
||||||
|
transactions: array(
|
||||||
|
pick({
|
||||||
|
transaction: ConfirmedTransactionResult,
|
||||||
|
meta: nullable(ConfirmedTransactionMetaResult),
|
||||||
|
}),
|
||||||
|
),
|
||||||
|
rewards: optional(
|
||||||
|
array(
|
||||||
|
pick({
|
||||||
|
pubkey: string(),
|
||||||
|
lamports: number(),
|
||||||
|
postBalance: nullable(number()),
|
||||||
|
rewardType: nullable(string()),
|
||||||
|
}),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
blockTime: nullable(number()),
|
||||||
|
blockHeight: nullable(number()),
|
||||||
|
}),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Expected JSON RPC response for the "getConfirmedBlock" message
|
* Expected JSON RPC response for the "getConfirmedBlock" message
|
||||||
|
*
|
||||||
|
* @deprecated Deprecated since Solana v1.8.0. Please use {@link GetBlockRpcResult} instead.
|
||||||
*/
|
*/
|
||||||
const GetConfirmedBlockRpcResult = jsonRpcResult(
|
const GetConfirmedBlockRpcResult = jsonRpcResult(
|
||||||
nullable(
|
nullable(
|
||||||
@ -1525,9 +1572,9 @@ const GetConfirmedBlockRpcResult = jsonRpcResult(
|
|||||||
);
|
);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Expected JSON RPC response for the "getConfirmedBlockSignatures" message
|
* Expected JSON RPC response for the "getBlock" message
|
||||||
*/
|
*/
|
||||||
const GetConfirmedBlockSignaturesRpcResult = jsonRpcResult(
|
const GetBlockSignaturesRpcResult = jsonRpcResult(
|
||||||
nullable(
|
nullable(
|
||||||
pick({
|
pick({
|
||||||
blockhash: string(),
|
blockhash: string(),
|
||||||
@ -1540,9 +1587,9 @@ const GetConfirmedBlockSignaturesRpcResult = jsonRpcResult(
|
|||||||
);
|
);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Expected JSON RPC response for the "getConfirmedTransaction" message
|
* Expected JSON RPC response for the "getTransaction" message
|
||||||
*/
|
*/
|
||||||
const GetConfirmedTransactionRpcResult = jsonRpcResult(
|
const GetTransactionRpcResult = jsonRpcResult(
|
||||||
nullable(
|
nullable(
|
||||||
pick({
|
pick({
|
||||||
slot: number(),
|
slot: number(),
|
||||||
@ -1554,9 +1601,9 @@ const GetConfirmedTransactionRpcResult = jsonRpcResult(
|
|||||||
);
|
);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Expected JSON RPC response for the "getConfirmedTransaction" message
|
* Expected parsed JSON RPC response for the "getTransaction" message
|
||||||
*/
|
*/
|
||||||
const GetParsedConfirmedTransactionRpcResult = jsonRpcResult(
|
const GetParsedTransactionRpcResult = jsonRpcResult(
|
||||||
nullable(
|
nullable(
|
||||||
pick({
|
pick({
|
||||||
slot: number(),
|
slot: number(),
|
||||||
@ -1569,6 +1616,8 @@ const GetParsedConfirmedTransactionRpcResult = jsonRpcResult(
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Expected JSON RPC response for the "getRecentBlockhash" message
|
* Expected JSON RPC response for the "getRecentBlockhash" message
|
||||||
|
*
|
||||||
|
* @deprecated Deprecated since Solana v1.8.0. Please use {@link GetLatestBlockhashRpcResult} instead.
|
||||||
*/
|
*/
|
||||||
const GetRecentBlockhashAndContextRpcResult = jsonRpcResultAndContext(
|
const GetRecentBlockhashAndContextRpcResult = jsonRpcResultAndContext(
|
||||||
pick({
|
pick({
|
||||||
@ -1579,6 +1628,16 @@ const GetRecentBlockhashAndContextRpcResult = jsonRpcResultAndContext(
|
|||||||
}),
|
}),
|
||||||
);
|
);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Expected JSON RPC response for the "getLatestBlockhash" message
|
||||||
|
*/
|
||||||
|
const GetLatestBlockhashRpcResult = jsonRpcResultAndContext(
|
||||||
|
pick({
|
||||||
|
blockhash: string(),
|
||||||
|
lastValidBlockHeight: number(),
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
|
||||||
const PerfSampleResult = pick({
|
const PerfSampleResult = pick({
|
||||||
slot: number(),
|
slot: number(),
|
||||||
numTransactions: number(),
|
numTransactions: number(),
|
||||||
@ -2962,6 +3021,8 @@ export class Connection {
|
|||||||
/**
|
/**
|
||||||
* Fetch a recent blockhash from the cluster, return with context
|
* Fetch a recent blockhash from the cluster, return with context
|
||||||
* @return {Promise<RpcResponseAndContext<{blockhash: Blockhash, feeCalculator: FeeCalculator}>>}
|
* @return {Promise<RpcResponseAndContext<{blockhash: Blockhash, feeCalculator: FeeCalculator}>>}
|
||||||
|
*
|
||||||
|
* @deprecated Deprecated since Solana v1.8.0. Please use {@link getLatestBlockhash} instead.
|
||||||
*/
|
*/
|
||||||
async getRecentBlockhashAndContext(
|
async getRecentBlockhashAndContext(
|
||||||
commitment?: Commitment,
|
commitment?: Commitment,
|
||||||
@ -3001,6 +3062,8 @@ export class Connection {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Fetch the fee calculator for a recent blockhash from the cluster, return with context
|
* Fetch the fee calculator for a recent blockhash from the cluster, return with context
|
||||||
|
*
|
||||||
|
* @deprecated Deprecated since Solana v1.8.0. Please use {@link getFeeForMessage} instead.
|
||||||
*/
|
*/
|
||||||
async getFeeCalculatorForBlockhash(
|
async getFeeCalculatorForBlockhash(
|
||||||
blockhash: Blockhash,
|
blockhash: Blockhash,
|
||||||
@ -3047,6 +3110,8 @@ export class Connection {
|
|||||||
/**
|
/**
|
||||||
* Fetch a recent blockhash from the cluster
|
* Fetch a recent blockhash from the cluster
|
||||||
* @return {Promise<{blockhash: Blockhash, feeCalculator: FeeCalculator}>}
|
* @return {Promise<{blockhash: Blockhash, feeCalculator: FeeCalculator}>}
|
||||||
|
*
|
||||||
|
* @deprecated Deprecated since Solana v1.8.0. Please use {@link getLatestBlockhash} instead.
|
||||||
*/
|
*/
|
||||||
async getRecentBlockhash(
|
async getRecentBlockhash(
|
||||||
commitment?: Commitment,
|
commitment?: Commitment,
|
||||||
@ -3059,6 +3124,39 @@ export class Connection {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Fetch the latest blockhash from the cluster
|
||||||
|
* @return {Promise<{blockhash: Blockhash, lastValidBlockHeight: number}>}
|
||||||
|
*/
|
||||||
|
async getLatestBlockhash(
|
||||||
|
commitment?: Commitment,
|
||||||
|
): Promise<{blockhash: Blockhash; lastValidBlockHeight: number}> {
|
||||||
|
try {
|
||||||
|
const res = await this.getLatestBlockhashAndContext(commitment);
|
||||||
|
return res.value;
|
||||||
|
} catch (e) {
|
||||||
|
throw new Error('failed to get recent blockhash: ' + e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Fetch the latest blockhash from the cluster
|
||||||
|
* @return {Promise<{blockhash: Blockhash, lastValidBlockHeight: number}>}
|
||||||
|
*/
|
||||||
|
async getLatestBlockhashAndContext(
|
||||||
|
commitment?: Commitment,
|
||||||
|
): Promise<
|
||||||
|
RpcResponseAndContext<{blockhash: Blockhash; lastValidBlockHeight: number}>
|
||||||
|
> {
|
||||||
|
const args = this._buildArgs([], commitment);
|
||||||
|
const unsafeRes = await this._rpcRequest('getLatestBlockhash', args);
|
||||||
|
const res = create(unsafeRes, GetLatestBlockhashRpcResult);
|
||||||
|
if ('error' in res) {
|
||||||
|
throw new Error('failed to get latest blockhash: ' + res.error.message);
|
||||||
|
}
|
||||||
|
return res.result;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Fetch the node version
|
* Fetch the node version
|
||||||
*/
|
*/
|
||||||
@ -3094,8 +3192,8 @@ export class Connection {
|
|||||||
[slot],
|
[slot],
|
||||||
opts && opts.commitment,
|
opts && opts.commitment,
|
||||||
);
|
);
|
||||||
const unsafeRes = await this._rpcRequest('getConfirmedBlock', args);
|
const unsafeRes = await this._rpcRequest('getBlock', args);
|
||||||
const res = create(unsafeRes, GetConfirmedBlockRpcResult);
|
const res = create(unsafeRes, GetBlockRpcResult);
|
||||||
|
|
||||||
if ('error' in res) {
|
if ('error' in res) {
|
||||||
throw new Error('failed to get confirmed block: ' + res.error.message);
|
throw new Error('failed to get confirmed block: ' + res.error.message);
|
||||||
@ -3120,7 +3218,7 @@ export class Connection {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Fetch a processed transaction from the cluster.
|
* Fetch a confirmed or finalized transaction from the cluster.
|
||||||
*/
|
*/
|
||||||
async getTransaction(
|
async getTransaction(
|
||||||
signature: string,
|
signature: string,
|
||||||
@ -3130,12 +3228,10 @@ export class Connection {
|
|||||||
[signature],
|
[signature],
|
||||||
opts && opts.commitment,
|
opts && opts.commitment,
|
||||||
);
|
);
|
||||||
const unsafeRes = await this._rpcRequest('getConfirmedTransaction', args);
|
const unsafeRes = await this._rpcRequest('getTransaction', args);
|
||||||
const res = create(unsafeRes, GetConfirmedTransactionRpcResult);
|
const res = create(unsafeRes, GetTransactionRpcResult);
|
||||||
if ('error' in res) {
|
if ('error' in res) {
|
||||||
throw new Error(
|
throw new Error('failed to get transaction: ' + res.error.message);
|
||||||
'failed to get confirmed transaction: ' + res.error.message,
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const result = res.result;
|
const result = res.result;
|
||||||
@ -3150,6 +3246,57 @@ export class Connection {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Fetch parsed transaction details for a confirmed or finalized transaction
|
||||||
|
*/
|
||||||
|
async getParsedTransaction(
|
||||||
|
signature: TransactionSignature,
|
||||||
|
commitment?: Finality,
|
||||||
|
): Promise<ParsedConfirmedTransaction | null> {
|
||||||
|
const args = this._buildArgsAtLeastConfirmed(
|
||||||
|
[signature],
|
||||||
|
commitment,
|
||||||
|
'jsonParsed',
|
||||||
|
);
|
||||||
|
const unsafeRes = await this._rpcRequest('getTransaction', args);
|
||||||
|
const res = create(unsafeRes, GetParsedTransactionRpcResult);
|
||||||
|
if ('error' in res) {
|
||||||
|
throw new Error('failed to get transaction: ' + res.error.message);
|
||||||
|
}
|
||||||
|
return res.result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Fetch parsed transaction details for a batch of confirmed transactions
|
||||||
|
*/
|
||||||
|
async getParsedTransactions(
|
||||||
|
signatures: TransactionSignature[],
|
||||||
|
commitment?: Finality,
|
||||||
|
): Promise<(ParsedConfirmedTransaction | null)[]> {
|
||||||
|
const batch = signatures.map(signature => {
|
||||||
|
const args = this._buildArgsAtLeastConfirmed(
|
||||||
|
[signature],
|
||||||
|
commitment,
|
||||||
|
'jsonParsed',
|
||||||
|
);
|
||||||
|
return {
|
||||||
|
methodName: 'getTransaction',
|
||||||
|
args,
|
||||||
|
};
|
||||||
|
});
|
||||||
|
|
||||||
|
const unsafeRes = await this._rpcBatchRequest(batch);
|
||||||
|
const res = unsafeRes.map((unsafeRes: any) => {
|
||||||
|
const res = create(unsafeRes, GetParsedTransactionRpcResult);
|
||||||
|
if ('error' in res) {
|
||||||
|
throw new Error('failed to get transactions: ' + res.error.message);
|
||||||
|
}
|
||||||
|
return res.result;
|
||||||
|
});
|
||||||
|
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Fetch a list of Transactions and transaction statuses from the cluster
|
* Fetch a list of Transactions and transaction statuses from the cluster
|
||||||
* for a confirmed block.
|
* for a confirmed block.
|
||||||
@ -3160,14 +3307,36 @@ export class Connection {
|
|||||||
slot: number,
|
slot: number,
|
||||||
commitment?: Finality,
|
commitment?: Finality,
|
||||||
): Promise<ConfirmedBlock> {
|
): Promise<ConfirmedBlock> {
|
||||||
const result = await this.getBlock(slot, {commitment});
|
const args = this._buildArgsAtLeastConfirmed([slot], commitment);
|
||||||
|
const unsafeRes = await this._rpcRequest('getConfirmedBlock', args);
|
||||||
|
const res = create(unsafeRes, GetConfirmedBlockRpcResult);
|
||||||
|
|
||||||
|
if ('error' in res) {
|
||||||
|
throw new Error('failed to get confirmed block: ' + res.error.message);
|
||||||
|
}
|
||||||
|
|
||||||
|
const result = res.result;
|
||||||
if (!result) {
|
if (!result) {
|
||||||
throw new Error('Confirmed block ' + slot + ' not found');
|
throw new Error('Confirmed block ' + slot + ' not found');
|
||||||
}
|
}
|
||||||
|
|
||||||
return {
|
const block = {
|
||||||
...result,
|
...result,
|
||||||
transactions: result.transactions.map(({transaction, meta}) => {
|
transactions: result.transactions.map(({transaction, meta}) => {
|
||||||
|
const message = new Message(transaction.message);
|
||||||
|
return {
|
||||||
|
meta,
|
||||||
|
transaction: {
|
||||||
|
...transaction,
|
||||||
|
message,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
}),
|
||||||
|
};
|
||||||
|
|
||||||
|
return {
|
||||||
|
...block,
|
||||||
|
transactions: block.transactions.map(({transaction, meta}) => {
|
||||||
return {
|
return {
|
||||||
meta,
|
meta,
|
||||||
transaction: Transaction.populate(
|
transaction: Transaction.populate(
|
||||||
@ -3191,7 +3360,7 @@ export class Connection {
|
|||||||
endSlot !== undefined ? [startSlot, endSlot] : [startSlot],
|
endSlot !== undefined ? [startSlot, endSlot] : [startSlot],
|
||||||
commitment,
|
commitment,
|
||||||
);
|
);
|
||||||
const unsafeRes = await this._rpcRequest('getConfirmedBlocks', args);
|
const unsafeRes = await this._rpcRequest('getBlocks', args);
|
||||||
const res = create(unsafeRes, jsonRpcResult(array(number())));
|
const res = create(unsafeRes, jsonRpcResult(array(number())));
|
||||||
if ('error' in res) {
|
if ('error' in res) {
|
||||||
throw new Error('failed to get blocks: ' + res.error.message);
|
throw new Error('failed to get blocks: ' + res.error.message);
|
||||||
@ -3199,13 +3368,43 @@ export class Connection {
|
|||||||
return res.result;
|
return res.result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Fetch a list of Signatures from the cluster for a block, excluding rewards
|
||||||
|
*/
|
||||||
|
async getBlockSignatures(
|
||||||
|
slot: number,
|
||||||
|
commitment?: Finality,
|
||||||
|
): Promise<BlockSignatures> {
|
||||||
|
const args = this._buildArgsAtLeastConfirmed(
|
||||||
|
[slot],
|
||||||
|
commitment,
|
||||||
|
undefined,
|
||||||
|
{
|
||||||
|
transactionDetails: 'signatures',
|
||||||
|
rewards: false,
|
||||||
|
},
|
||||||
|
);
|
||||||
|
const unsafeRes = await this._rpcRequest('getBlock', args);
|
||||||
|
const res = create(unsafeRes, GetBlockSignaturesRpcResult);
|
||||||
|
if ('error' in res) {
|
||||||
|
throw new Error('failed to get block: ' + res.error.message);
|
||||||
|
}
|
||||||
|
const result = res.result;
|
||||||
|
if (!result) {
|
||||||
|
throw new Error('Block ' + slot + ' not found');
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Fetch a list of Signatures from the cluster for a confirmed block, excluding rewards
|
* Fetch a list of Signatures from the cluster for a confirmed block, excluding rewards
|
||||||
|
*
|
||||||
|
* @deprecated Deprecated since Solana v1.8.0. Please use {@link getBlockSignatures} instead.
|
||||||
*/
|
*/
|
||||||
async getConfirmedBlockSignatures(
|
async getConfirmedBlockSignatures(
|
||||||
slot: number,
|
slot: number,
|
||||||
commitment?: Finality,
|
commitment?: Finality,
|
||||||
): Promise<ConfirmedBlockSignatures> {
|
): Promise<BlockSignatures> {
|
||||||
const args = this._buildArgsAtLeastConfirmed(
|
const args = this._buildArgsAtLeastConfirmed(
|
||||||
[slot],
|
[slot],
|
||||||
commitment,
|
commitment,
|
||||||
@ -3216,7 +3415,7 @@ export class Connection {
|
|||||||
},
|
},
|
||||||
);
|
);
|
||||||
const unsafeRes = await this._rpcRequest('getConfirmedBlock', args);
|
const unsafeRes = await this._rpcRequest('getConfirmedBlock', args);
|
||||||
const res = create(unsafeRes, GetConfirmedBlockSignaturesRpcResult);
|
const res = create(unsafeRes, GetBlockSignaturesRpcResult);
|
||||||
if ('error' in res) {
|
if ('error' in res) {
|
||||||
throw new Error('failed to get confirmed block: ' + res.error.message);
|
throw new Error('failed to get confirmed block: ' + res.error.message);
|
||||||
}
|
}
|
||||||
@ -3229,14 +3428,25 @@ export class Connection {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Fetch a transaction details for a confirmed transaction
|
* Fetch a transaction details for a confirmed transaction
|
||||||
|
*
|
||||||
|
* @deprecated Deprecated since Solana v1.8.0. Please use {@link getTransaction} instead.
|
||||||
*/
|
*/
|
||||||
async getConfirmedTransaction(
|
async getConfirmedTransaction(
|
||||||
signature: TransactionSignature,
|
signature: TransactionSignature,
|
||||||
commitment?: Finality,
|
commitment?: Finality,
|
||||||
): Promise<ConfirmedTransaction | null> {
|
): Promise<ConfirmedTransaction | null> {
|
||||||
const result = await this.getTransaction(signature, {commitment});
|
const args = this._buildArgsAtLeastConfirmed([signature], commitment);
|
||||||
|
const unsafeRes = await this._rpcRequest('getConfirmedTransaction', args);
|
||||||
|
const res = create(unsafeRes, GetTransactionRpcResult);
|
||||||
|
if ('error' in res) {
|
||||||
|
throw new Error('failed to get transaction: ' + res.error.message);
|
||||||
|
}
|
||||||
|
|
||||||
|
const result = res.result;
|
||||||
if (!result) return result;
|
if (!result) return result;
|
||||||
const {message, signatures} = result.transaction;
|
|
||||||
|
const message = new Message(result.transaction.message);
|
||||||
|
const signatures = result.transaction.signatures;
|
||||||
return {
|
return {
|
||||||
...result,
|
...result,
|
||||||
transaction: Transaction.populate(message, signatures),
|
transaction: Transaction.populate(message, signatures),
|
||||||
@ -3245,6 +3455,8 @@ export class Connection {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Fetch parsed transaction details for a confirmed transaction
|
* Fetch parsed transaction details for a confirmed transaction
|
||||||
|
*
|
||||||
|
* @deprecated Deprecated since Solana v1.8.0. Please use {@link getParsedTransaction} instead.
|
||||||
*/
|
*/
|
||||||
async getParsedConfirmedTransaction(
|
async getParsedConfirmedTransaction(
|
||||||
signature: TransactionSignature,
|
signature: TransactionSignature,
|
||||||
@ -3256,7 +3468,7 @@ export class Connection {
|
|||||||
'jsonParsed',
|
'jsonParsed',
|
||||||
);
|
);
|
||||||
const unsafeRes = await this._rpcRequest('getConfirmedTransaction', args);
|
const unsafeRes = await this._rpcRequest('getConfirmedTransaction', args);
|
||||||
const res = create(unsafeRes, GetParsedConfirmedTransactionRpcResult);
|
const res = create(unsafeRes, GetParsedTransactionRpcResult);
|
||||||
if ('error' in res) {
|
if ('error' in res) {
|
||||||
throw new Error(
|
throw new Error(
|
||||||
'failed to get confirmed transaction: ' + res.error.message,
|
'failed to get confirmed transaction: ' + res.error.message,
|
||||||
@ -3267,6 +3479,8 @@ export class Connection {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Fetch parsed transaction details for a batch of confirmed transactions
|
* Fetch parsed transaction details for a batch of confirmed transactions
|
||||||
|
*
|
||||||
|
* @deprecated Deprecated since Solana v1.8.0. Please use {@link getParsedTransactions} instead.
|
||||||
*/
|
*/
|
||||||
async getParsedConfirmedTransactions(
|
async getParsedConfirmedTransactions(
|
||||||
signatures: TransactionSignature[],
|
signatures: TransactionSignature[],
|
||||||
@ -3286,7 +3500,7 @@ export class Connection {
|
|||||||
|
|
||||||
const unsafeRes = await this._rpcBatchRequest(batch);
|
const unsafeRes = await this._rpcBatchRequest(batch);
|
||||||
const res = unsafeRes.map((unsafeRes: any) => {
|
const res = unsafeRes.map((unsafeRes: any) => {
|
||||||
const res = create(unsafeRes, GetParsedConfirmedTransactionRpcResult);
|
const res = create(unsafeRes, GetParsedTransactionRpcResult);
|
||||||
if ('error' in res) {
|
if ('error' in res) {
|
||||||
throw new Error(
|
throw new Error(
|
||||||
'failed to get confirmed transactions: ' + res.error.message,
|
'failed to get confirmed transactions: ' + res.error.message,
|
||||||
|
@ -1501,9 +1501,10 @@ describe('Connection', () => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
await mockRpcResponse({
|
await mockRpcResponse({
|
||||||
method: 'getConfirmedBlock',
|
method: 'getBlock',
|
||||||
params: [1],
|
params: [1],
|
||||||
value: {
|
value: {
|
||||||
|
blockHeight: 0,
|
||||||
blockTime: 1614281964,
|
blockTime: 1614281964,
|
||||||
blockhash: '57zQNBZBEiHsCZFqsaY6h176ioXy5MsSLmcvHkEyaLGy',
|
blockhash: '57zQNBZBEiHsCZFqsaY6h176ioXy5MsSLmcvHkEyaLGy',
|
||||||
previousBlockhash: 'H5nJ91eGag3B5ZSRHZ7zG5ZwXJ6ywCt2hyR8xCsV7xMo',
|
previousBlockhash: 'H5nJ91eGag3B5ZSRHZ7zG5ZwXJ6ywCt2hyR8xCsV7xMo',
|
||||||
@ -1552,18 +1553,18 @@ describe('Connection', () => {
|
|||||||
|
|
||||||
// Find a block that has a transaction, usually Block 1
|
// Find a block that has a transaction, usually Block 1
|
||||||
let slot = 0;
|
let slot = 0;
|
||||||
let confirmedTransaction: string | undefined;
|
let transaction: string | undefined;
|
||||||
while (!confirmedTransaction) {
|
while (!transaction) {
|
||||||
slot++;
|
slot++;
|
||||||
const block = await connection.getBlock(slot);
|
const block = await connection.getBlock(slot);
|
||||||
if (block && block.transactions.length > 0) {
|
if (block && block.transactions.length > 0) {
|
||||||
confirmedTransaction = block.transactions[0].transaction.signatures[0];
|
transaction = block.transactions[0].transaction.signatures[0];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
await mockRpcResponse({
|
await mockRpcResponse({
|
||||||
method: 'getConfirmedTransaction',
|
method: 'getTransaction',
|
||||||
params: [confirmedTransaction],
|
params: [transaction],
|
||||||
value: {
|
value: {
|
||||||
slot,
|
slot,
|
||||||
transaction: {
|
transaction: {
|
||||||
@ -1604,7 +1605,7 @@ describe('Connection', () => {
|
|||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
const result = await connection.getTransaction(confirmedTransaction);
|
const result = await connection.getTransaction(transaction);
|
||||||
|
|
||||||
if (!result) {
|
if (!result) {
|
||||||
expect(result).to.be.ok;
|
expect(result).to.be.ok;
|
||||||
@ -1612,7 +1613,7 @@ describe('Connection', () => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const resultSignature = result.transaction.signatures[0];
|
const resultSignature = result.transaction.signatures[0];
|
||||||
expect(resultSignature).to.eq(confirmedTransaction);
|
expect(resultSignature).to.eq(transaction);
|
||||||
|
|
||||||
const newAddress = Keypair.generate().publicKey;
|
const newAddress = Keypair.generate().publicKey;
|
||||||
const recentSignature = await helpers.airdrop({
|
const recentSignature = await helpers.airdrop({
|
||||||
@ -1622,7 +1623,7 @@ describe('Connection', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
await mockRpcResponse({
|
await mockRpcResponse({
|
||||||
method: 'getConfirmedTransaction',
|
method: 'getTransaction',
|
||||||
params: [recentSignature],
|
params: [recentSignature],
|
||||||
value: null,
|
value: null,
|
||||||
});
|
});
|
||||||
@ -1896,9 +1897,10 @@ describe('Connection', () => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
await mockRpcResponse({
|
await mockRpcResponse({
|
||||||
method: 'getConfirmedBlock',
|
method: 'getBlock',
|
||||||
params: [0],
|
params: [0],
|
||||||
value: {
|
value: {
|
||||||
|
blockHeight: 0,
|
||||||
blockTime: 1614281964,
|
blockTime: 1614281964,
|
||||||
blockhash: 'H5nJ91eGag3B5ZSRHZ7zG5ZwXJ6ywCt2hyR8xCsV7xMo',
|
blockhash: 'H5nJ91eGag3B5ZSRHZ7zG5ZwXJ6ywCt2hyR8xCsV7xMo',
|
||||||
previousBlockhash: 'H5nJ91eGag3B5ZSRHZ7zG5ZwXJ6ywCt2hyR8xCsV7xMo',
|
previousBlockhash: 'H5nJ91eGag3B5ZSRHZ7zG5ZwXJ6ywCt2hyR8xCsV7xMo',
|
||||||
@ -1921,9 +1923,10 @@ describe('Connection', () => {
|
|||||||
expect(block0.parentSlot).to.eq(0);
|
expect(block0.parentSlot).to.eq(0);
|
||||||
|
|
||||||
await mockRpcResponse({
|
await mockRpcResponse({
|
||||||
method: 'getConfirmedBlock',
|
method: 'getBlock',
|
||||||
params: [1],
|
params: [1],
|
||||||
value: {
|
value: {
|
||||||
|
blockHeight: 0,
|
||||||
blockTime: 1614281964,
|
blockTime: 1614281964,
|
||||||
blockhash: '57zQNBZBEiHsCZFqsaY6h176ioXy5MsSLmcvHkEyaLGy',
|
blockhash: '57zQNBZBEiHsCZFqsaY6h176ioXy5MsSLmcvHkEyaLGy',
|
||||||
previousBlockhash: 'H5nJ91eGag3B5ZSRHZ7zG5ZwXJ6ywCt2hyR8xCsV7xMo',
|
previousBlockhash: 'H5nJ91eGag3B5ZSRHZ7zG5ZwXJ6ywCt2hyR8xCsV7xMo',
|
||||||
@ -1985,7 +1988,7 @@ describe('Connection', () => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
await mockRpcResponse({
|
await mockRpcResponse({
|
||||||
method: 'getConfirmedBlock',
|
method: 'getBlock',
|
||||||
params: [Number.MAX_SAFE_INTEGER],
|
params: [Number.MAX_SAFE_INTEGER],
|
||||||
error: {
|
error: {
|
||||||
message: `Block not available for slot ${Number.MAX_SAFE_INTEGER}`,
|
message: `Block not available for slot ${Number.MAX_SAFE_INTEGER}`,
|
||||||
@ -2109,7 +2112,7 @@ describe('Connection', () => {
|
|||||||
|
|
||||||
it('get blocks between two slots', async () => {
|
it('get blocks between two slots', async () => {
|
||||||
await mockRpcResponse({
|
await mockRpcResponse({
|
||||||
method: 'getConfirmedBlocks',
|
method: 'getBlocks',
|
||||||
params: [0, 10],
|
params: [0, 10],
|
||||||
value: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10],
|
value: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10],
|
||||||
});
|
});
|
||||||
@ -2129,7 +2132,7 @@ describe('Connection', () => {
|
|||||||
|
|
||||||
it('get blocks from starting slot', async () => {
|
it('get blocks from starting slot', async () => {
|
||||||
await mockRpcResponse({
|
await mockRpcResponse({
|
||||||
method: 'getConfirmedBlocks',
|
method: 'getBlocks',
|
||||||
params: [0],
|
params: [0],
|
||||||
value: [
|
value: [
|
||||||
1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20,
|
1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20,
|
||||||
@ -2155,7 +2158,7 @@ describe('Connection', () => {
|
|||||||
expect(blocks).to.contain(latestSlot);
|
expect(blocks).to.contain(latestSlot);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('get confirmed block signatures', async () => {
|
it('get block signatures', async () => {
|
||||||
await mockRpcResponse({
|
await mockRpcResponse({
|
||||||
method: 'getSlot',
|
method: 'getSlot',
|
||||||
params: [],
|
params: [],
|
||||||
@ -2167,7 +2170,7 @@ describe('Connection', () => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
await mockRpcResponse({
|
await mockRpcResponse({
|
||||||
method: 'getConfirmedBlock',
|
method: 'getBlock',
|
||||||
params: [
|
params: [
|
||||||
0,
|
0,
|
||||||
{
|
{
|
||||||
@ -2176,6 +2179,7 @@ describe('Connection', () => {
|
|||||||
},
|
},
|
||||||
],
|
],
|
||||||
value: {
|
value: {
|
||||||
|
blockHeight: 0,
|
||||||
blockTime: 1614281964,
|
blockTime: 1614281964,
|
||||||
blockhash: 'H5nJ91eGag3B5ZSRHZ7zG5ZwXJ6ywCt2hyR8xCsV7xMo',
|
blockhash: 'H5nJ91eGag3B5ZSRHZ7zG5ZwXJ6ywCt2hyR8xCsV7xMo',
|
||||||
previousBlockhash: 'H5nJ91eGag3B5ZSRHZ7zG5ZwXJ6ywCt2hyR8xCsV7xMo',
|
previousBlockhash: 'H5nJ91eGag3B5ZSRHZ7zG5ZwXJ6ywCt2hyR8xCsV7xMo',
|
||||||
@ -2185,7 +2189,7 @@ describe('Connection', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
// Block 0 never has any transactions in test validator
|
// Block 0 never has any transactions in test validator
|
||||||
const block0 = await connection.getConfirmedBlockSignatures(0);
|
const block0 = await connection.getBlockSignatures(0);
|
||||||
const blockhash0 = block0.blockhash;
|
const blockhash0 = block0.blockhash;
|
||||||
expect(block0.signatures).to.have.length(0);
|
expect(block0.signatures).to.have.length(0);
|
||||||
expect(blockhash0).not.to.be.null;
|
expect(blockhash0).not.to.be.null;
|
||||||
@ -2194,7 +2198,7 @@ describe('Connection', () => {
|
|||||||
expect(block0).to.not.have.property('rewards');
|
expect(block0).to.not.have.property('rewards');
|
||||||
|
|
||||||
await mockRpcResponse({
|
await mockRpcResponse({
|
||||||
method: 'getConfirmedBlock',
|
method: 'getBlock',
|
||||||
params: [
|
params: [
|
||||||
1,
|
1,
|
||||||
{
|
{
|
||||||
@ -2203,6 +2207,7 @@ describe('Connection', () => {
|
|||||||
},
|
},
|
||||||
],
|
],
|
||||||
value: {
|
value: {
|
||||||
|
blockHeight: 1,
|
||||||
blockTime: 1614281964,
|
blockTime: 1614281964,
|
||||||
blockhash: '57zQNBZBEiHsCZFqsaY6h176ioXy5MsSLmcvHkEyaLGy',
|
blockhash: '57zQNBZBEiHsCZFqsaY6h176ioXy5MsSLmcvHkEyaLGy',
|
||||||
previousBlockhash: 'H5nJ91eGag3B5ZSRHZ7zG5ZwXJ6ywCt2hyR8xCsV7xMo',
|
previousBlockhash: 'H5nJ91eGag3B5ZSRHZ7zG5ZwXJ6ywCt2hyR8xCsV7xMo',
|
||||||
@ -2217,7 +2222,7 @@ describe('Connection', () => {
|
|||||||
// Find a block that has a transaction, usually Block 1
|
// Find a block that has a transaction, usually Block 1
|
||||||
let x = 1;
|
let x = 1;
|
||||||
while (x < 10) {
|
while (x < 10) {
|
||||||
const block1 = await connection.getConfirmedBlockSignatures(x);
|
const block1 = await connection.getBlockSignatures(x);
|
||||||
if (block1.signatures.length >= 1) {
|
if (block1.signatures.length >= 1) {
|
||||||
expect(block1.previousBlockhash).to.eq(blockhash0);
|
expect(block1.previousBlockhash).to.eq(blockhash0);
|
||||||
expect(block1.blockhash).not.to.be.null;
|
expect(block1.blockhash).not.to.be.null;
|
||||||
@ -2230,14 +2235,14 @@ describe('Connection', () => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
await mockRpcResponse({
|
await mockRpcResponse({
|
||||||
method: 'getConfirmedBlock',
|
method: 'getBlock',
|
||||||
params: [Number.MAX_SAFE_INTEGER],
|
params: [Number.MAX_SAFE_INTEGER],
|
||||||
error: {
|
error: {
|
||||||
message: `Block not available for slot ${Number.MAX_SAFE_INTEGER}`,
|
message: `Block not available for slot ${Number.MAX_SAFE_INTEGER}`,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
await expect(
|
await expect(
|
||||||
connection.getConfirmedBlockSignatures(Number.MAX_SAFE_INTEGER),
|
connection.getBlockSignatures(Number.MAX_SAFE_INTEGER),
|
||||||
).to.be.rejectedWith(
|
).to.be.rejectedWith(
|
||||||
`Block not available for slot ${Number.MAX_SAFE_INTEGER}`,
|
`Block not available for slot ${Number.MAX_SAFE_INTEGER}`,
|
||||||
);
|
);
|
||||||
@ -2255,6 +2260,18 @@ describe('Connection', () => {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('get latest blockhash', async () => {
|
||||||
|
const commitments: Commitment[] = ['processed', 'confirmed', 'finalized'];
|
||||||
|
for (const commitment of commitments) {
|
||||||
|
const {blockhash, lastValidBlockHeight} = await helpers.latestBlockhash({
|
||||||
|
connection,
|
||||||
|
commitment,
|
||||||
|
});
|
||||||
|
expect(bs58.decode(blockhash)).to.have.length(32);
|
||||||
|
expect(lastValidBlockHeight).to.be.at.least(0);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
it('get fee calculator', async () => {
|
it('get fee calculator', async () => {
|
||||||
const {blockhash} = await helpers.recentBlockhash({connection});
|
const {blockhash} = await helpers.recentBlockhash({connection});
|
||||||
await mockRpcResponse({
|
await mockRpcResponse({
|
||||||
@ -2282,7 +2299,7 @@ describe('Connection', () => {
|
|||||||
const accountFrom = Keypair.generate();
|
const accountFrom = Keypair.generate();
|
||||||
const accountTo = Keypair.generate();
|
const accountTo = Keypair.generate();
|
||||||
|
|
||||||
const {blockhash} = await helpers.recentBlockhash({connection});
|
const {blockhash} = await helpers.latestBlockhash({connection});
|
||||||
|
|
||||||
const transaction = new Transaction({
|
const transaction = new Transaction({
|
||||||
feePayer: accountFrom.publicKey,
|
feePayer: accountFrom.publicKey,
|
||||||
@ -2972,7 +2989,7 @@ describe('Connection', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
const recentBlockhash = await (
|
const recentBlockhash = await (
|
||||||
await helpers.recentBlockhash({connection})
|
await helpers.latestBlockhash({connection})
|
||||||
).blockhash;
|
).blockhash;
|
||||||
const message = new Message({
|
const message = new Message({
|
||||||
accountKeys: [
|
accountKeys: [
|
||||||
|
@ -104,6 +104,32 @@ export const mockRpcResponse = async ({
|
|||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const latestBlockhash = async ({
|
||||||
|
connection,
|
||||||
|
commitment,
|
||||||
|
}: {
|
||||||
|
connection: Connection;
|
||||||
|
commitment?: Commitment;
|
||||||
|
}) => {
|
||||||
|
const blockhash = uniqueBlockhash();
|
||||||
|
const params = [];
|
||||||
|
if (commitment) {
|
||||||
|
params.push({commitment});
|
||||||
|
}
|
||||||
|
|
||||||
|
await mockRpcResponse({
|
||||||
|
method: 'getLatestBlockhash',
|
||||||
|
params,
|
||||||
|
value: {
|
||||||
|
blockhash,
|
||||||
|
lastValidBlockHeight: 3090,
|
||||||
|
},
|
||||||
|
withContext: true,
|
||||||
|
});
|
||||||
|
|
||||||
|
return await connection.getLatestBlockhash(commitment);
|
||||||
|
};
|
||||||
|
|
||||||
const recentBlockhash = async ({
|
const recentBlockhash = async ({
|
||||||
connection,
|
connection,
|
||||||
commitment,
|
commitment,
|
||||||
@ -145,7 +171,7 @@ const processTransaction = async ({
|
|||||||
commitment: Commitment;
|
commitment: Commitment;
|
||||||
err?: any;
|
err?: any;
|
||||||
}) => {
|
}) => {
|
||||||
const blockhash = (await recentBlockhash({connection})).blockhash;
|
const blockhash = (await latestBlockhash({connection})).blockhash;
|
||||||
transaction.recentBlockhash = blockhash;
|
transaction.recentBlockhash = blockhash;
|
||||||
transaction.sign(...signers);
|
transaction.sign(...signers);
|
||||||
|
|
||||||
@ -211,4 +237,5 @@ export const helpers = {
|
|||||||
airdrop,
|
airdrop,
|
||||||
processTransaction,
|
processTransaction,
|
||||||
recentBlockhash,
|
recentBlockhash,
|
||||||
|
latestBlockhash,
|
||||||
};
|
};
|
||||||
|
Reference in New Issue
Block a user