fix: Appease flow
This commit is contained in:
parent
663f9c76d8
commit
507fac06ee
|
@ -53,12 +53,12 @@ declare module '@solana/web3.js' {
|
||||||
keyedAccountInfo: KeyedAccountInfo,
|
keyedAccountInfo: KeyedAccountInfo,
|
||||||
) => void;
|
) => void;
|
||||||
|
|
||||||
declare export type SignatureStatus =
|
declare export type SignatureSuccess = {|
|
||||||
| 'Confirmed'
|
Ok: null,
|
||||||
| 'AccountInUse'
|
|};
|
||||||
| 'SignatureNotFound'
|
declare export type TransactionError = {|
|
||||||
| 'ProgramRuntimeError'
|
Err: Object,
|
||||||
| 'GenericFailure';
|
|};
|
||||||
|
|
||||||
declare export class Connection {
|
declare export class Connection {
|
||||||
constructor(endpoint: string): Connection;
|
constructor(endpoint: string): Connection;
|
||||||
|
@ -67,7 +67,7 @@ declare module '@solana/web3.js' {
|
||||||
confirmTransaction(signature: TransactionSignature): Promise<boolean>;
|
confirmTransaction(signature: TransactionSignature): Promise<boolean>;
|
||||||
getSignatureStatus(
|
getSignatureStatus(
|
||||||
signature: TransactionSignature,
|
signature: TransactionSignature,
|
||||||
): Promise<SignatureStatus>;
|
): Promise<SignatureSuccess | TransactionError | null>;
|
||||||
getTransactionCount(): Promise<number>;
|
getTransactionCount(): Promise<number>;
|
||||||
getRecentBlockhash(): Promise<Blockhash>;
|
getRecentBlockhash(): Promise<Blockhash>;
|
||||||
requestAirdrop(
|
requestAirdrop(
|
||||||
|
|
|
@ -126,11 +126,8 @@ const ConfirmTransactionRpcResult = jsonRpcResult('boolean');
|
||||||
const GetSignatureStatusRpcResult = jsonRpcResult(
|
const GetSignatureStatusRpcResult = jsonRpcResult(
|
||||||
struct.union([
|
struct.union([
|
||||||
'null',
|
'null',
|
||||||
struct.union([
|
struct.union([struct({Ok: 'null'}), struct({Err: 'object'})]),
|
||||||
struct({Ok: 'null'}),
|
]),
|
||||||
struct({Err: 'string'})
|
|
||||||
])
|
|
||||||
])
|
|
||||||
);
|
);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -212,16 +209,22 @@ type ProgramAccountSubscriptionInfo = {
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Possible signature status values
|
* Signature status: Success
|
||||||
*
|
*
|
||||||
* @typedef {string} SignatureStatus
|
* @typedef {Object} SignatureSuccess
|
||||||
*/
|
*/
|
||||||
export type SignatureStatus =
|
export type SignatureSuccess = {|
|
||||||
| 'Confirmed'
|
Ok: null,
|
||||||
| 'AccountInUse'
|
|};
|
||||||
| 'SignatureNotFound'
|
|
||||||
| 'ProgramRuntimeError'
|
/**
|
||||||
| 'GenericFailure';
|
* Signature status: TransactionError
|
||||||
|
*
|
||||||
|
* @typedef {Object} TransactionError
|
||||||
|
*/
|
||||||
|
export type TransactionError = {|
|
||||||
|
Err: Object,
|
||||||
|
|};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A connection to a fullnode JSON RPC endpoint
|
* A connection to a fullnode JSON RPC endpoint
|
||||||
|
@ -338,7 +341,7 @@ export class Connection {
|
||||||
*/
|
*/
|
||||||
async getSignatureStatus(
|
async getSignatureStatus(
|
||||||
signature: TransactionSignature,
|
signature: TransactionSignature,
|
||||||
): Promise<SignatureStatus> {
|
): Promise<SignatureSuccess | TransactionError | null> {
|
||||||
const unsafeRes = await this._rpcRequest('getSignatureStatus', [signature]);
|
const unsafeRes = await this._rpcRequest('getSignatureStatus', [signature]);
|
||||||
const res = GetSignatureStatusRpcResult(unsafeRes);
|
const res = GetSignatureStatusRpcResult(unsafeRes);
|
||||||
if (res.error) {
|
if (res.error) {
|
||||||
|
|
|
@ -16,11 +16,11 @@ export async function sendAndConfirmRawTransaction(
|
||||||
let signature = await connection.sendRawTransaction(rawTransaction);
|
let signature = await connection.sendRawTransaction(rawTransaction);
|
||||||
|
|
||||||
// Wait up to a couple slots for a confirmation
|
// Wait up to a couple slots for a confirmation
|
||||||
let status = '';
|
let status = null;
|
||||||
let statusRetries = 6;
|
let statusRetries = 6;
|
||||||
for (;;) {
|
for (;;) {
|
||||||
status = await connection.getSignatureStatus(signature);
|
status = await connection.getSignatureStatus(signature);
|
||||||
if (status !== 'SignatureNotFound') {
|
if (status) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -32,14 +32,14 @@ export async function sendAndConfirmRawTransaction(
|
||||||
throw new Error(
|
throw new Error(
|
||||||
`Raw Transaction '${signature}' was not confirmed in ${duration.toFixed(
|
`Raw Transaction '${signature}' was not confirmed in ${duration.toFixed(
|
||||||
2,
|
2,
|
||||||
)} seconds (${status})`,
|
)} seconds (${JSON.stringify(status)})`,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (status === 'Confirmed') {
|
if (status && 'Ok' in status) {
|
||||||
return signature;
|
return signature;
|
||||||
}
|
}
|
||||||
|
|
||||||
throw new Error(`Raw transaction ${signature} failed (${status})`);
|
throw new Error(`Raw transaction ${signature} failed (${JSON.stringify(status)})`);
|
||||||
}
|
}
|
||||||
|
|
|
@ -24,7 +24,7 @@ export async function sendAndConfirmTransaction(
|
||||||
signature = await connection.sendTransaction(transaction, ...signers);
|
signature = await connection.sendTransaction(transaction, ...signers);
|
||||||
|
|
||||||
// Wait up to a couple slots for a confirmation
|
// Wait up to a couple slots for a confirmation
|
||||||
let status = 'SignatureNotFound';
|
let status = null;
|
||||||
let statusRetries = 6;
|
let statusRetries = 6;
|
||||||
for (;;) {
|
for (;;) {
|
||||||
status = await connection.getSignatureStatus(signature);
|
status = await connection.getSignatureStatus(signature);
|
||||||
|
@ -39,7 +39,7 @@ export async function sendAndConfirmTransaction(
|
||||||
await sleep((500 * DEFAULT_TICKS_PER_SLOT) / NUM_TICKS_PER_SECOND);
|
await sleep((500 * DEFAULT_TICKS_PER_SLOT) / NUM_TICKS_PER_SECOND);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ('Ok' in status) {
|
if (status && 'Ok' in status) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (--sendRetries <= 0) {
|
if (--sendRetries <= 0) {
|
||||||
|
@ -47,12 +47,12 @@ export async function sendAndConfirmTransaction(
|
||||||
throw new Error(
|
throw new Error(
|
||||||
`Transaction '${signature}' was not confirmed in ${duration.toFixed(
|
`Transaction '${signature}' was not confirmed in ${duration.toFixed(
|
||||||
2,
|
2,
|
||||||
)} seconds (${status})`,
|
)} seconds (${JSON.stringify(status)})`,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ('Err' in status && !status.includes('AccountInUse')) {
|
if (status && status.Err && !('AccountInUse' in status.Err)) {
|
||||||
throw new Error(`Transaction ${signature} failed (${status})`);
|
throw new Error(`Transaction ${signature} failed (${JSON.stringify(status)})`);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Retry in 0..100ms to try to avoid another AccountInUse collision
|
// Retry in 0..100ms to try to avoid another AccountInUse collision
|
||||||
|
|
|
@ -338,12 +338,12 @@ test('transaction', async () => {
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
error: null,
|
error: null,
|
||||||
result: 'Confirmed',
|
result: {Ok: null},
|
||||||
},
|
},
|
||||||
]);
|
]);
|
||||||
await expect(connection.getSignatureStatus(signature)).resolves.toEqual(
|
await expect(connection.getSignatureStatus(signature)).resolves.toEqual({
|
||||||
{'Ok': null},
|
Ok: null,
|
||||||
);
|
});
|
||||||
|
|
||||||
mockRpc.push([
|
mockRpc.push([
|
||||||
url,
|
url,
|
||||||
|
@ -410,9 +410,9 @@ test('multi-instruction transaction', async () => {
|
||||||
expect(++i).toBeLessThan(10);
|
expect(++i).toBeLessThan(10);
|
||||||
await sleep(500);
|
await sleep(500);
|
||||||
}
|
}
|
||||||
await expect(connection.getSignatureStatus(signature)).resolves.toEqual(
|
await expect(connection.getSignatureStatus(signature)).resolves.toEqual({
|
||||||
{'Ok': null},
|
Ok: null,
|
||||||
);
|
});
|
||||||
|
|
||||||
expect(await connection.getBalance(accountFrom.publicKey)).toBe(12);
|
expect(await connection.getBalance(accountFrom.publicKey)).toBe(12);
|
||||||
expect(await connection.getBalance(accountTo.publicKey)).toBe(21);
|
expect(await connection.getBalance(accountTo.publicKey)).toBe(21);
|
||||||
|
|
|
@ -11,7 +11,7 @@ import {sleep} from '../src/util/sleep';
|
||||||
// The default of 5 seconds is too slow for live testing sometimes
|
// The default of 5 seconds is too slow for live testing sometimes
|
||||||
jest.setTimeout(60000);
|
jest.setTimeout(60000);
|
||||||
|
|
||||||
function mockGetSignatureStatus(result: string = 'Confirmed') {
|
function mockGetSignatureStatus(result: Object = {Ok: null}) {
|
||||||
mockRpc.push([
|
mockRpc.push([
|
||||||
url,
|
url,
|
||||||
{
|
{
|
||||||
|
@ -58,7 +58,7 @@ test('create new token', async () => {
|
||||||
|
|
||||||
// mock Token.newAccount() transaction
|
// mock Token.newAccount() transaction
|
||||||
mockSendTransaction();
|
mockSendTransaction();
|
||||||
mockGetSignatureStatus('SignatureNotFound');
|
mockGetSignatureStatus(null);
|
||||||
mockGetSignatureStatus();
|
mockGetSignatureStatus();
|
||||||
|
|
||||||
// mock SystemProgram.createAccount transaction for Token.createNewToken()
|
// mock SystemProgram.createAccount transaction for Token.createNewToken()
|
||||||
|
@ -67,7 +67,7 @@ test('create new token', async () => {
|
||||||
|
|
||||||
// mock Token.createNewToken() transaction
|
// mock Token.createNewToken() transaction
|
||||||
mockSendTransaction();
|
mockSendTransaction();
|
||||||
mockGetSignatureStatus('SignatureNotFound');
|
mockGetSignatureStatus(null);
|
||||||
mockGetSignatureStatus();
|
mockGetSignatureStatus();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue