feat: support rpc method getSignaturesByAddres
This commit is contained in:
parent
3362ac06b5
commit
db3475bcdf
@ -127,6 +127,21 @@ export type ConfirmedSignaturesForAddress2Options = {
|
|||||||
limit?: number;
|
limit?: number;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Options for getSignaturesForAddress
|
||||||
|
*/
|
||||||
|
export type SignaturesForAddressOptions = {
|
||||||
|
/**
|
||||||
|
* Start searching backwards from this transaction signature.
|
||||||
|
* @remark If not provided the search starts from the highest max confirmed block.
|
||||||
|
*/
|
||||||
|
before?: TransactionSignature;
|
||||||
|
/** Search until this transaction signature is reached, if found before `limit`. */
|
||||||
|
until?: TransactionSignature;
|
||||||
|
/** Maximum transaction signatures to return (between 1 and 1,000, default: 1,000). */
|
||||||
|
limit?: number;
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* RPC Response with extra contextual information
|
* RPC Response with extra contextual information
|
||||||
*/
|
*/
|
||||||
@ -1060,6 +1075,21 @@ const GetConfirmedSignaturesForAddress2RpcResult = jsonRpcResult(
|
|||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Expected JSON RPC response for the "getSignaturesForAddress" message
|
||||||
|
*/
|
||||||
|
const GetSignaturesForAddressRpcResult = jsonRpcResult(
|
||||||
|
array(
|
||||||
|
pick({
|
||||||
|
signature: string(),
|
||||||
|
slot: number(),
|
||||||
|
err: TransactionErrorResult,
|
||||||
|
memo: nullable(string()),
|
||||||
|
blockTime: optional(nullable(number())),
|
||||||
|
}),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
|
||||||
/***
|
/***
|
||||||
* Expected JSON RPC response for the "accountNotification" message
|
* Expected JSON RPC response for the "accountNotification" message
|
||||||
*/
|
*/
|
||||||
@ -3205,6 +3235,35 @@ export class Connection {
|
|||||||
return res.result;
|
return res.result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns confirmed signatures for transactions involving an
|
||||||
|
* address backwards in time from the provided signature or most recent confirmed block
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* @param address queried address
|
||||||
|
* @param options
|
||||||
|
*/
|
||||||
|
async getSignaturesForAddress(
|
||||||
|
address: PublicKey,
|
||||||
|
options?: SignaturesForAddressOptions,
|
||||||
|
commitment?: Finality,
|
||||||
|
): Promise<Array<ConfirmedSignatureInfo>> {
|
||||||
|
const args = this._buildArgsAtLeastConfirmed(
|
||||||
|
[address.toBase58()],
|
||||||
|
commitment,
|
||||||
|
undefined,
|
||||||
|
options,
|
||||||
|
);
|
||||||
|
const unsafeRes = await this._rpcRequest('getSignaturesForAddress', args);
|
||||||
|
const res = create(unsafeRes, GetSignaturesForAddressRpcResult);
|
||||||
|
if ('error' in res) {
|
||||||
|
throw new Error(
|
||||||
|
'failed to get signatures for address: ' + res.error.message,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
return res.result;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Fetch the contents of a Nonce account from the cluster, return with context
|
* Fetch the contents of a Nonce account from the cluster, return with context
|
||||||
*/
|
*/
|
||||||
|
@ -1011,6 +1011,112 @@ describe('Connection', () => {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('get signatures for address', async () => {
|
||||||
|
const connection = new Connection(url);
|
||||||
|
|
||||||
|
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 address: PublicKey | undefined;
|
||||||
|
let expectedSignature: string | undefined;
|
||||||
|
while (!address || !expectedSignature) {
|
||||||
|
slot++;
|
||||||
|
const block = await connection.getConfirmedBlock(slot);
|
||||||
|
if (block.transactions.length > 0) {
|
||||||
|
const {signature, publicKey} =
|
||||||
|
block.transactions[0].transaction.signatures[0];
|
||||||
|
if (signature) {
|
||||||
|
address = publicKey;
|
||||||
|
expectedSignature = bs58.encode(signature);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// getSignaturesForAddress tests...
|
||||||
|
await mockRpcResponse({
|
||||||
|
method: 'getSignaturesForAddress',
|
||||||
|
params: [address.toBase58(), {limit: 1}],
|
||||||
|
value: [
|
||||||
|
{
|
||||||
|
signature: expectedSignature,
|
||||||
|
slot,
|
||||||
|
err: null,
|
||||||
|
memo: null,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
});
|
||||||
|
|
||||||
|
const signatures = await connection.getSignaturesForAddress(address, {
|
||||||
|
limit: 1,
|
||||||
|
});
|
||||||
|
expect(signatures).to.have.length(1);
|
||||||
|
if (mockServer) {
|
||||||
|
expect(signatures[0].signature).to.eq(expectedSignature);
|
||||||
|
expect(signatures[0].slot).to.eq(slot);
|
||||||
|
expect(signatures[0].err).to.be.null;
|
||||||
|
expect(signatures[0].memo).to.be.null;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
it('get parsed confirmed transactions', async () => {
|
it('get parsed confirmed transactions', async () => {
|
||||||
await mockRpcResponse({
|
await mockRpcResponse({
|
||||||
method: 'getSlot',
|
method: 'getSlot',
|
||||||
|
Loading…
x
Reference in New Issue
Block a user