feat: add getBlock and getTransaction apis (#17449)
This commit is contained in:
parent
3ae4806dae
commit
0dbe926efe
|
@ -510,6 +510,25 @@ export type ConfirmedTransactionMeta = {
|
||||||
err: TransactionError | null;
|
err: TransactionError | null;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A processed transaction from the RPC API
|
||||||
|
*/
|
||||||
|
export type TransactionResponse = {
|
||||||
|
/** The slot during which the transaction was processed */
|
||||||
|
slot: number;
|
||||||
|
/** The transaction */
|
||||||
|
transaction: {
|
||||||
|
/** The transaction message */
|
||||||
|
message: Message;
|
||||||
|
/** The transaction signatures */
|
||||||
|
signatures: string[];
|
||||||
|
};
|
||||||
|
/** Metadata produced from the transaction */
|
||||||
|
meta: ConfirmedTransactionMeta | null;
|
||||||
|
/** The unix timestamp of when the transaction was processed */
|
||||||
|
blockTime?: number | null;
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A confirmed transaction on the ledger
|
* A confirmed transaction on the ledger
|
||||||
*/
|
*/
|
||||||
|
@ -596,6 +615,43 @@ export type ParsedConfirmedTransaction = {
|
||||||
blockTime?: number | null;
|
blockTime?: number | null;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A processed block fetched from the RPC API
|
||||||
|
*/
|
||||||
|
export type BlockResponse = {
|
||||||
|
/** Blockhash of this block */
|
||||||
|
blockhash: Blockhash;
|
||||||
|
/** Blockhash of this block's parent */
|
||||||
|
previousBlockhash: Blockhash;
|
||||||
|
/** Slot index of this block's parent */
|
||||||
|
parentSlot: number;
|
||||||
|
/** Vector of transactions with status meta and original message */
|
||||||
|
transactions: Array<{
|
||||||
|
/** The transaction */
|
||||||
|
transaction: {
|
||||||
|
/** The transaction message */
|
||||||
|
message: Message;
|
||||||
|
/** The transaction signatures */
|
||||||
|
signatures: string[];
|
||||||
|
};
|
||||||
|
/** Metadata produced from the transaction */
|
||||||
|
meta: ConfirmedTransactionMeta | null;
|
||||||
|
}>;
|
||||||
|
/** Vector of block rewards */
|
||||||
|
rewards?: Array<{
|
||||||
|
/** Public key of reward recipient */
|
||||||
|
pubkey: string;
|
||||||
|
/** Reward value in lamports */
|
||||||
|
lamports: number;
|
||||||
|
/** Account balance after reward is applied */
|
||||||
|
postBalance: number | null;
|
||||||
|
/** Type of reward received */
|
||||||
|
rewardType: string | null;
|
||||||
|
}>;
|
||||||
|
/** The unix timestamp of when the block was processed */
|
||||||
|
blockTime: number | null;
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A ConfirmedBlock on the ledger
|
* A ConfirmedBlock on the ledger
|
||||||
*/
|
*/
|
||||||
|
@ -1234,9 +1290,6 @@ const GetSignatureStatusesRpcResult = jsonRpcResultAndContext(
|
||||||
*/
|
*/
|
||||||
const GetMinimumBalanceForRentExemptionRpcResult = jsonRpcResult(number());
|
const GetMinimumBalanceForRentExemptionRpcResult = jsonRpcResult(number());
|
||||||
|
|
||||||
/**
|
|
||||||
* @internal
|
|
||||||
*/
|
|
||||||
const ConfirmedTransactionResult = pick({
|
const ConfirmedTransactionResult = pick({
|
||||||
signatures: array(string()),
|
signatures: array(string()),
|
||||||
message: pick({
|
message: pick({
|
||||||
|
@ -1257,15 +1310,6 @@ const ConfirmedTransactionResult = pick({
|
||||||
}),
|
}),
|
||||||
});
|
});
|
||||||
|
|
||||||
const TransactionFromConfirmed = coerce(
|
|
||||||
instance(Transaction),
|
|
||||||
ConfirmedTransactionResult,
|
|
||||||
result => {
|
|
||||||
const {message, signatures} = result;
|
|
||||||
return Transaction.populate(new Message(message), signatures);
|
|
||||||
},
|
|
||||||
);
|
|
||||||
|
|
||||||
const ParsedInstructionResult = pick({
|
const ParsedInstructionResult = pick({
|
||||||
parsed: unknown(),
|
parsed: unknown(),
|
||||||
program: string(),
|
program: string(),
|
||||||
|
@ -1395,7 +1439,7 @@ const GetConfirmedBlockRpcResult = jsonRpcResult(
|
||||||
parentSlot: number(),
|
parentSlot: number(),
|
||||||
transactions: array(
|
transactions: array(
|
||||||
pick({
|
pick({
|
||||||
transaction: TransactionFromConfirmed,
|
transaction: ConfirmedTransactionResult,
|
||||||
meta: nullable(ConfirmedTransactionMetaResult),
|
meta: nullable(ConfirmedTransactionMetaResult),
|
||||||
}),
|
}),
|
||||||
),
|
),
|
||||||
|
@ -1436,9 +1480,9 @@ const GetConfirmedTransactionRpcResult = jsonRpcResult(
|
||||||
nullable(
|
nullable(
|
||||||
pick({
|
pick({
|
||||||
slot: number(),
|
slot: number(),
|
||||||
transaction: TransactionFromConfirmed,
|
|
||||||
meta: ConfirmedTransactionMetaResult,
|
meta: ConfirmedTransactionMetaResult,
|
||||||
blockTime: optional(nullable(number())),
|
blockTime: optional(nullable(number())),
|
||||||
|
transaction: ConfirmedTransactionResult,
|
||||||
}),
|
}),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
@ -2668,7 +2712,8 @@ export class Connection {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Fetch the current total currency supply of the cluster in lamports
|
* Fetch the current total currency supply of the cluster in lamports
|
||||||
* @deprecated Deprecated since v1.2.8. Use `Connection.getSupply()` instead.
|
*
|
||||||
|
* @deprecated Deprecated since v1.2.8. Please use {@link getSupply} instead.
|
||||||
*/
|
*/
|
||||||
async getTotalSupply(commitment?: Commitment): Promise<number> {
|
async getTotalSupply(commitment?: Commitment): Promise<number> {
|
||||||
const args = this._buildArgs([], commitment);
|
const args = this._buildArgs([], commitment);
|
||||||
|
@ -2869,25 +2914,100 @@ export class Connection {
|
||||||
return res.result;
|
return res.result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Fetch a processed block from the cluster.
|
||||||
|
*/
|
||||||
|
async getBlock(
|
||||||
|
slot: number,
|
||||||
|
opts?: {commitment?: Finality},
|
||||||
|
): Promise<BlockResponse | null> {
|
||||||
|
const args = this._buildArgsAtLeastConfirmed(
|
||||||
|
[slot],
|
||||||
|
opts && opts.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) return result;
|
||||||
|
|
||||||
|
return {
|
||||||
|
...result,
|
||||||
|
transactions: result.transactions.map(({transaction, meta}) => {
|
||||||
|
const message = new Message(transaction.message);
|
||||||
|
return {
|
||||||
|
meta,
|
||||||
|
transaction: {
|
||||||
|
...transaction,
|
||||||
|
message,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
}),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Fetch a processed transaction from the cluster.
|
||||||
|
*/
|
||||||
|
async getTransaction(
|
||||||
|
signature: string,
|
||||||
|
opts?: {commitment?: Finality},
|
||||||
|
): Promise<TransactionResponse | null> {
|
||||||
|
const args = this._buildArgsAtLeastConfirmed(
|
||||||
|
[signature],
|
||||||
|
opts && opts.commitment,
|
||||||
|
);
|
||||||
|
const unsafeRes = await this._rpcRequest('getConfirmedTransaction', args);
|
||||||
|
const res = create(unsafeRes, GetConfirmedTransactionRpcResult);
|
||||||
|
if ('error' in res) {
|
||||||
|
throw new Error(
|
||||||
|
'failed to get confirmed transaction: ' + res.error.message,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
const result = res.result;
|
||||||
|
if (!result) return result;
|
||||||
|
|
||||||
|
return {
|
||||||
|
...result,
|
||||||
|
transaction: {
|
||||||
|
...result.transaction,
|
||||||
|
message: new Message(result.transaction.message),
|
||||||
|
},
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 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.
|
||||||
|
*
|
||||||
|
* @deprecated Deprecated since v1.13.0. Please use {@link getBlock} instead.
|
||||||
*/
|
*/
|
||||||
async getConfirmedBlock(
|
async getConfirmedBlock(
|
||||||
slot: number,
|
slot: number,
|
||||||
commitment?: Finality,
|
commitment?: Finality,
|
||||||
): Promise<ConfirmedBlock> {
|
): Promise<ConfirmedBlock> {
|
||||||
const args = this._buildArgsAtLeastConfirmed([slot], commitment);
|
const result = await this.getBlock(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 result;
|
|
||||||
|
return {
|
||||||
|
...result,
|
||||||
|
transactions: result.transactions.map(({transaction, meta}) => {
|
||||||
|
return {
|
||||||
|
meta,
|
||||||
|
transaction: Transaction.populate(
|
||||||
|
transaction.message,
|
||||||
|
transaction.signatures,
|
||||||
|
),
|
||||||
|
};
|
||||||
|
}),
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -2925,15 +3045,13 @@ export class Connection {
|
||||||
signature: TransactionSignature,
|
signature: TransactionSignature,
|
||||||
commitment?: Finality,
|
commitment?: Finality,
|
||||||
): Promise<ConfirmedTransaction | null> {
|
): Promise<ConfirmedTransaction | null> {
|
||||||
const args = this._buildArgsAtLeastConfirmed([signature], commitment);
|
const result = await this.getTransaction(signature, {commitment});
|
||||||
const unsafeRes = await this._rpcRequest('getConfirmedTransaction', args);
|
if (!result) return result;
|
||||||
const res = create(unsafeRes, GetConfirmedTransactionRpcResult);
|
const {message, signatures} = result.transaction;
|
||||||
if ('error' in res) {
|
return {
|
||||||
throw new Error(
|
...result,
|
||||||
'failed to get confirmed transaction: ' + res.error.message,
|
transaction: Transaction.populate(message, signatures),
|
||||||
);
|
};
|
||||||
}
|
|
||||||
return res.result;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -2994,7 +3112,8 @@ export class Connection {
|
||||||
/**
|
/**
|
||||||
* Fetch a list of all the confirmed signatures for transactions involving an address
|
* Fetch a list of all the confirmed signatures for transactions involving an address
|
||||||
* within a specified slot range. Max range allowed is 10,000 slots.
|
* within a specified slot range. Max range allowed is 10,000 slots.
|
||||||
* @deprecated Deprecated since v1.3. Use `Connection.getConfirmedSignaturesForAddress2()` instead.
|
*
|
||||||
|
* @deprecated Deprecated since v1.3. Please use {@link getConfirmedSignaturesForAddress2} instead.
|
||||||
*
|
*
|
||||||
* @param address queried address
|
* @param address queried address
|
||||||
* @param startSlot start slot, inclusive
|
* @param startSlot start slot, inclusive
|
||||||
|
|
|
@ -1283,6 +1283,151 @@ describe('Connection', () => {
|
||||||
expect(result).to.be.empty;
|
expect(result).to.be.empty;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('get transaction', async () => {
|
||||||
|
await mockRpcResponse({
|
||||||
|
method: 'getSlot',
|
||||||
|
params: [],
|
||||||
|
value: 1,
|
||||||
|
});
|
||||||
|
|
||||||
|
while ((await connection.getSlot()) <= 0) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
await mockRpcResponse({
|
||||||
|
method: 'getConfirmedBlock',
|
||||||
|
params: [1],
|
||||||
|
value: {
|
||||||
|
blockTime: 1614281964,
|
||||||
|
blockhash: '57zQNBZBEiHsCZFqsaY6h176ioXy5MsSLmcvHkEyaLGy',
|
||||||
|
previousBlockhash: 'H5nJ91eGag3B5ZSRHZ7zG5ZwXJ6ywCt2hyR8xCsV7xMo',
|
||||||
|
parentSlot: 0,
|
||||||
|
transactions: [
|
||||||
|
{
|
||||||
|
meta: {
|
||||||
|
fee: 10000,
|
||||||
|
postBalances: [499260347380, 15298080, 1, 1, 1],
|
||||||
|
preBalances: [499260357380, 15298080, 1, 1, 1],
|
||||||
|
status: {Ok: null},
|
||||||
|
err: null,
|
||||||
|
},
|
||||||
|
transaction: {
|
||||||
|
message: {
|
||||||
|
accountKeys: [
|
||||||
|
'va12u4o9DipLEB2z4fuoHszroq1U9NcAB9aooFDPJSf',
|
||||||
|
'57zQNBZBEiHsCZFqsaY6h176ioXy5MsSLmcvHkEyaLGy',
|
||||||
|
'SysvarS1otHashes111111111111111111111111111',
|
||||||
|
'SysvarC1ock11111111111111111111111111111111',
|
||||||
|
'Vote111111111111111111111111111111111111111',
|
||||||
|
],
|
||||||
|
header: {
|
||||||
|
numReadonlySignedAccounts: 0,
|
||||||
|
numReadonlyUnsignedAccounts: 3,
|
||||||
|
numRequiredSignatures: 2,
|
||||||
|
},
|
||||||
|
instructions: [
|
||||||
|
{
|
||||||
|
accounts: [1, 2, 3],
|
||||||
|
data:
|
||||||
|
'37u9WtQpcm6ULa3VtWDFAWoQc1hUvybPrA3dtx99tgHvvcE7pKRZjuGmn7VX2tC3JmYDYGG7',
|
||||||
|
programIdIndex: 4,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
recentBlockhash: 'GeyAFFRY3WGpmam2hbgrKw4rbU2RKzfVLm5QLSeZwTZE',
|
||||||
|
},
|
||||||
|
signatures: [
|
||||||
|
'w2Zeq8YkpyB463DttvfzARD7k9ZxGEwbsEw4boEK7jDp3pfoxZbTdLFSsEPhzXhpCcjGi2kHtHFobgX49MMhbWt',
|
||||||
|
'4oCEqwGrMdBeMxpzuWiukCYqSfV4DsSKXSiVVCh1iJ6pS772X7y219JZP3mgqBz5PhsvprpKyhzChjYc3VSBQXzG',
|
||||||
|
],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
// Find a block that has a transaction, usually Block 1
|
||||||
|
let slot = 0;
|
||||||
|
let confirmedTransaction: string | undefined;
|
||||||
|
while (!confirmedTransaction) {
|
||||||
|
slot++;
|
||||||
|
const block = await connection.getBlock(slot);
|
||||||
|
if (block && block.transactions.length > 0) {
|
||||||
|
confirmedTransaction = block.transactions[0].transaction.signatures[0];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
await mockRpcResponse({
|
||||||
|
method: 'getConfirmedTransaction',
|
||||||
|
params: [confirmedTransaction],
|
||||||
|
value: {
|
||||||
|
slot,
|
||||||
|
transaction: {
|
||||||
|
message: {
|
||||||
|
accountKeys: [
|
||||||
|
'va12u4o9DipLEB2z4fuoHszroq1U9NcAB9aooFDPJSf',
|
||||||
|
'57zQNBZBEiHsCZFqsaY6h176ioXy5MsSLmcvHkEyaLGy',
|
||||||
|
'SysvarS1otHashes111111111111111111111111111',
|
||||||
|
'SysvarC1ock11111111111111111111111111111111',
|
||||||
|
'Vote111111111111111111111111111111111111111',
|
||||||
|
],
|
||||||
|
header: {
|
||||||
|
numReadonlySignedAccounts: 0,
|
||||||
|
numReadonlyUnsignedAccounts: 3,
|
||||||
|
numRequiredSignatures: 2,
|
||||||
|
},
|
||||||
|
instructions: [
|
||||||
|
{
|
||||||
|
accounts: [1, 2, 3],
|
||||||
|
data:
|
||||||
|
'37u9WtQpcm6ULa3VtWDFAWoQc1hUvybPrA3dtx99tgHvvcE7pKRZjuGmn7VX2tC3JmYDYGG7',
|
||||||
|
programIdIndex: 4,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
recentBlockhash: 'GeyAFFRY3WGpmam2hbgrKw4rbU2RKzfVLm5QLSeZwTZE',
|
||||||
|
},
|
||||||
|
signatures: [
|
||||||
|
'w2Zeq8YkpyB463DttvfzARD7k9ZxGEwbsEw4boEK7jDp3pfoxZbTdLFSsEPhzXhpCcjGi2kHtHFobgX49MMhbWt',
|
||||||
|
'4oCEqwGrMdBeMxpzuWiukCYqSfV4DsSKXSiVVCh1iJ6pS772X7y219JZP3mgqBz5PhsvprpKyhzChjYc3VSBQXzG',
|
||||||
|
],
|
||||||
|
},
|
||||||
|
meta: {
|
||||||
|
fee: 10000,
|
||||||
|
postBalances: [499260347380, 15298080, 1, 1, 1],
|
||||||
|
preBalances: [499260357380, 15298080, 1, 1, 1],
|
||||||
|
status: {Ok: null},
|
||||||
|
err: null,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
const result = await connection.getTransaction(confirmedTransaction);
|
||||||
|
|
||||||
|
if (!result) {
|
||||||
|
expect(result).to.be.ok;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const resultSignature = result.transaction.signatures[0];
|
||||||
|
expect(resultSignature).to.eq(confirmedTransaction);
|
||||||
|
|
||||||
|
const newAddress = Keypair.generate().publicKey;
|
||||||
|
const recentSignature = await helpers.airdrop({
|
||||||
|
connection,
|
||||||
|
address: newAddress,
|
||||||
|
amount: 1,
|
||||||
|
});
|
||||||
|
|
||||||
|
await mockRpcResponse({
|
||||||
|
method: 'getConfirmedTransaction',
|
||||||
|
params: [recentSignature],
|
||||||
|
value: null,
|
||||||
|
});
|
||||||
|
|
||||||
|
// Signature hasn't been finalized yet
|
||||||
|
const nullResponse = await connection.getTransaction(recentSignature);
|
||||||
|
expect(nullResponse).to.be.null;
|
||||||
|
});
|
||||||
|
|
||||||
it('get confirmed transaction', async () => {
|
it('get confirmed transaction', async () => {
|
||||||
await mockRpcResponse({
|
await mockRpcResponse({
|
||||||
method: 'getSlot',
|
method: 'getSlot',
|
||||||
|
@ -1535,6 +1680,121 @@ describe('Connection', () => {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
it('get block', async () => {
|
||||||
|
await mockRpcResponse({
|
||||||
|
method: 'getSlot',
|
||||||
|
params: [],
|
||||||
|
value: 1,
|
||||||
|
});
|
||||||
|
|
||||||
|
while ((await connection.getSlot()) <= 0) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
await mockRpcResponse({
|
||||||
|
method: 'getConfirmedBlock',
|
||||||
|
params: [0],
|
||||||
|
value: {
|
||||||
|
blockTime: 1614281964,
|
||||||
|
blockhash: 'H5nJ91eGag3B5ZSRHZ7zG5ZwXJ6ywCt2hyR8xCsV7xMo',
|
||||||
|
previousBlockhash: 'H5nJ91eGag3B5ZSRHZ7zG5ZwXJ6ywCt2hyR8xCsV7xMo',
|
||||||
|
parentSlot: 0,
|
||||||
|
transactions: [],
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
// Block 0 never has any transactions in test validator
|
||||||
|
const block0 = await connection.getBlock(0);
|
||||||
|
if (!block0) {
|
||||||
|
expect(block0).not.to.be.null;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const blockhash0 = block0.blockhash;
|
||||||
|
expect(block0.transactions).to.have.length(0);
|
||||||
|
expect(blockhash0).not.to.be.null;
|
||||||
|
expect(block0.previousBlockhash).not.to.be.null;
|
||||||
|
expect(block0.parentSlot).to.eq(0);
|
||||||
|
|
||||||
|
await mockRpcResponse({
|
||||||
|
method: 'getConfirmedBlock',
|
||||||
|
params: [1],
|
||||||
|
value: {
|
||||||
|
blockTime: 1614281964,
|
||||||
|
blockhash: '57zQNBZBEiHsCZFqsaY6h176ioXy5MsSLmcvHkEyaLGy',
|
||||||
|
previousBlockhash: 'H5nJ91eGag3B5ZSRHZ7zG5ZwXJ6ywCt2hyR8xCsV7xMo',
|
||||||
|
parentSlot: 0,
|
||||||
|
transactions: [
|
||||||
|
{
|
||||||
|
meta: {
|
||||||
|
fee: 10000,
|
||||||
|
postBalances: [499260347380, 15298080, 1, 1, 1],
|
||||||
|
preBalances: [499260357380, 15298080, 1, 1, 1],
|
||||||
|
status: {Ok: null},
|
||||||
|
err: null,
|
||||||
|
},
|
||||||
|
transaction: {
|
||||||
|
message: {
|
||||||
|
accountKeys: [
|
||||||
|
'va12u4o9DipLEB2z4fuoHszroq1U9NcAB9aooFDPJSf',
|
||||||
|
'57zQNBZBEiHsCZFqsaY6h176ioXy5MsSLmcvHkEyaLGy',
|
||||||
|
'SysvarS1otHashes111111111111111111111111111',
|
||||||
|
'SysvarC1ock11111111111111111111111111111111',
|
||||||
|
'Vote111111111111111111111111111111111111111',
|
||||||
|
],
|
||||||
|
header: {
|
||||||
|
numReadonlySignedAccounts: 0,
|
||||||
|
numReadonlyUnsignedAccounts: 3,
|
||||||
|
numRequiredSignatures: 2,
|
||||||
|
},
|
||||||
|
instructions: [
|
||||||
|
{
|
||||||
|
accounts: [1, 2, 3],
|
||||||
|
data:
|
||||||
|
'37u9WtQpcm6ULa3VtWDFAWoQc1hUvybPrA3dtx99tgHvvcE7pKRZjuGmn7VX2tC3JmYDYGG7',
|
||||||
|
programIdIndex: 4,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
recentBlockhash: 'GeyAFFRY3WGpmam2hbgrKw4rbU2RKzfVLm5QLSeZwTZE',
|
||||||
|
},
|
||||||
|
signatures: [
|
||||||
|
'w2Zeq8YkpyB463DttvfzARD7k9ZxGEwbsEw4boEK7jDp3pfoxZbTdLFSsEPhzXhpCcjGi2kHtHFobgX49MMhbWt',
|
||||||
|
'4oCEqwGrMdBeMxpzuWiukCYqSfV4DsSKXSiVVCh1iJ6pS772X7y219JZP3mgqBz5PhsvprpKyhzChjYc3VSBQXzG',
|
||||||
|
],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
// Find a block that has a transaction, usually Block 1
|
||||||
|
let x = 1;
|
||||||
|
while (x < 10) {
|
||||||
|
const block1 = await connection.getBlock(x);
|
||||||
|
if (block1 && block1.transactions.length >= 1) {
|
||||||
|
expect(block1.previousBlockhash).to.eq(blockhash0);
|
||||||
|
expect(block1.blockhash).not.to.be.null;
|
||||||
|
expect(block1.parentSlot).to.eq(0);
|
||||||
|
expect(block1.transactions[0].transaction).not.to.be.null;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
x++;
|
||||||
|
}
|
||||||
|
|
||||||
|
await mockRpcResponse({
|
||||||
|
method: 'getConfirmedBlock',
|
||||||
|
params: [Number.MAX_SAFE_INTEGER],
|
||||||
|
error: {
|
||||||
|
message: `Block not available for slot ${Number.MAX_SAFE_INTEGER}`,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
await expect(
|
||||||
|
connection.getBlock(Number.MAX_SAFE_INTEGER),
|
||||||
|
).to.be.rejectedWith(
|
||||||
|
`Block not available for slot ${Number.MAX_SAFE_INTEGER}`,
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
it('get confirmed block', async () => {
|
it('get confirmed block', async () => {
|
||||||
await mockRpcResponse({
|
await mockRpcResponse({
|
||||||
method: 'getSlot',
|
method: 'getSlot',
|
||||||
|
|
Loading…
Reference in New Issue