2019-05-28 08:25:16 -07:00
|
|
|
// @flow
|
2019-12-30 11:36:12 -07:00
|
|
|
import {Account, Connection, SystemProgram, LAMPORTS_PER_SOL} from '../src';
|
2019-05-28 08:25:16 -07:00
|
|
|
import {mockRpc, mockRpcEnabled} from './__mocks__/node-fetch';
|
|
|
|
import {mockGetRecentBlockhash} from './mockrpc/get-recent-blockhash';
|
|
|
|
import {url} from './url';
|
|
|
|
import {sleep} from '../src/util/sleep';
|
|
|
|
|
|
|
|
if (!mockRpcEnabled) {
|
|
|
|
// The default of 5 seconds is too slow for live testing sometimes
|
|
|
|
jest.setTimeout(30000);
|
|
|
|
}
|
|
|
|
|
|
|
|
test('transaction-payer', async () => {
|
|
|
|
const accountPayer = new Account();
|
|
|
|
const accountFrom = new Account();
|
|
|
|
const accountTo = new Account();
|
2019-11-11 13:01:10 -05:00
|
|
|
const connection = new Connection(url, 'recent');
|
2019-05-28 08:25:16 -07:00
|
|
|
|
2020-01-09 10:18:14 -07:00
|
|
|
mockRpc.push([
|
|
|
|
url,
|
|
|
|
{
|
|
|
|
method: 'getMinimumBalanceForRentExemption',
|
|
|
|
params: [0, {commitment: 'recent'}],
|
|
|
|
},
|
|
|
|
{
|
|
|
|
error: null,
|
|
|
|
result: 50,
|
|
|
|
},
|
|
|
|
]);
|
|
|
|
|
|
|
|
const minimumAmount = await connection.getMinimumBalanceForRentExemption(
|
|
|
|
0,
|
|
|
|
'recent',
|
|
|
|
);
|
|
|
|
|
2019-05-28 08:25:16 -07:00
|
|
|
mockRpc.push([
|
|
|
|
url,
|
|
|
|
{
|
|
|
|
method: 'requestAirdrop',
|
2019-11-11 13:01:10 -05:00
|
|
|
params: [
|
|
|
|
accountPayer.publicKey.toBase58(),
|
2019-12-30 11:36:12 -07:00
|
|
|
LAMPORTS_PER_SOL,
|
2019-11-11 13:01:10 -05:00
|
|
|
{commitment: 'recent'},
|
|
|
|
],
|
2019-05-28 08:25:16 -07:00
|
|
|
},
|
|
|
|
{
|
|
|
|
error: null,
|
|
|
|
result:
|
|
|
|
'0WE5w4B7v59x6qjyC4FbG2FEKYKQfvsJwqSxNVmtMjT8TQ31hsZieDHcSgqzxiAoTL56n2w5TncjqEKjLhtF4Vk',
|
|
|
|
},
|
|
|
|
]);
|
2019-12-30 11:36:12 -07:00
|
|
|
await connection.requestAirdrop(accountPayer.publicKey, LAMPORTS_PER_SOL);
|
2019-05-28 08:25:16 -07:00
|
|
|
|
|
|
|
mockRpc.push([
|
|
|
|
url,
|
|
|
|
{
|
|
|
|
method: 'requestAirdrop',
|
2020-01-09 10:18:14 -07:00
|
|
|
params: [
|
|
|
|
accountFrom.publicKey.toBase58(),
|
|
|
|
minimumAmount + 12,
|
|
|
|
{commitment: 'recent'},
|
|
|
|
],
|
2019-05-28 08:25:16 -07:00
|
|
|
},
|
|
|
|
{
|
|
|
|
error: null,
|
|
|
|
result:
|
|
|
|
'0WE5w4B7v59x6qjyC4FbG2FEKYKQfvsJwqSxNVmtMjT8TQ31hsZieDHcSgqzxiAoTL56n2w5TncjqEKjLhtF4Vk',
|
|
|
|
},
|
|
|
|
]);
|
2020-01-09 10:18:14 -07:00
|
|
|
await connection.requestAirdrop(accountFrom.publicKey, minimumAmount + 12);
|
2019-05-28 08:25:16 -07:00
|
|
|
|
|
|
|
mockRpc.push([
|
|
|
|
url,
|
|
|
|
{
|
|
|
|
method: 'requestAirdrop',
|
2020-01-09 10:18:14 -07:00
|
|
|
params: [
|
|
|
|
accountTo.publicKey.toBase58(),
|
|
|
|
minimumAmount + 21,
|
|
|
|
{commitment: 'recent'},
|
|
|
|
],
|
2019-05-28 08:25:16 -07:00
|
|
|
},
|
|
|
|
{
|
|
|
|
error: null,
|
|
|
|
result:
|
|
|
|
'8WE5w4B7v59x6qjyC4FbG2FEKYKQfvsJwqSxNVmtMjT8TQ31hsZieDHcSgqzxiAoTL56n2w5TncjqEKjLhtF4Vk',
|
|
|
|
},
|
|
|
|
]);
|
2020-01-09 10:18:14 -07:00
|
|
|
await connection.requestAirdrop(accountTo.publicKey, minimumAmount + 21);
|
2019-05-28 08:25:16 -07:00
|
|
|
|
2019-11-11 13:01:10 -05:00
|
|
|
mockGetRecentBlockhash('recent');
|
2019-05-28 08:25:16 -07:00
|
|
|
mockRpc.push([
|
|
|
|
url,
|
|
|
|
{
|
|
|
|
method: 'sendTransaction',
|
|
|
|
},
|
|
|
|
{
|
|
|
|
error: null,
|
|
|
|
result:
|
|
|
|
'3WE5w4B7v59x6qjyC4FbG2FEKYKQfvsJwqSxNVmtMjT8TQ31hsZieDHcSgqzxiAoTL56n2w5TncjqEKjLhtF4Vk',
|
|
|
|
},
|
|
|
|
]);
|
|
|
|
|
2020-03-03 16:05:50 +08:00
|
|
|
const transaction = SystemProgram.transfer({
|
|
|
|
fromPubkey: accountFrom.publicKey,
|
|
|
|
toPubkey: accountTo.publicKey,
|
|
|
|
lamports: 10,
|
|
|
|
});
|
2019-05-28 08:25:16 -07:00
|
|
|
|
|
|
|
const signature = await connection.sendTransaction(
|
|
|
|
transaction,
|
|
|
|
accountPayer,
|
|
|
|
accountFrom,
|
|
|
|
);
|
|
|
|
|
|
|
|
mockRpc.push([
|
|
|
|
url,
|
|
|
|
{
|
|
|
|
method: 'confirmTransaction',
|
|
|
|
params: [
|
|
|
|
'3WE5w4B7v59x6qjyC4FbG2FEKYKQfvsJwqSxNVmtMjT8TQ31hsZieDHcSgqzxiAoTL56n2w5TncjqEKjLhtF4Vk',
|
2019-11-11 13:01:10 -05:00
|
|
|
{commitment: 'recent'},
|
2019-05-28 08:25:16 -07:00
|
|
|
],
|
|
|
|
},
|
|
|
|
{
|
|
|
|
error: null,
|
2020-01-08 13:59:58 -07:00
|
|
|
result: {
|
|
|
|
context: {
|
|
|
|
slot: 11,
|
|
|
|
},
|
|
|
|
value: true,
|
|
|
|
},
|
2019-05-28 08:25:16 -07:00
|
|
|
},
|
|
|
|
]);
|
|
|
|
|
|
|
|
let i = 0;
|
|
|
|
for (;;) {
|
|
|
|
if (await connection.confirmTransaction(signature)) {
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
expect(mockRpcEnabled).toBe(false);
|
|
|
|
expect(++i).toBeLessThan(10);
|
|
|
|
await sleep(500);
|
|
|
|
}
|
|
|
|
|
|
|
|
mockRpc.push([
|
|
|
|
url,
|
|
|
|
{
|
|
|
|
method: 'getSignatureStatus',
|
|
|
|
params: [
|
2020-03-23 23:01:12 +08:00
|
|
|
[
|
|
|
|
'3WE5w4B7v59x6qjyC4FbG2FEKYKQfvsJwqSxNVmtMjT8TQ31hsZieDHcSgqzxiAoTL56n2w5TncjqEKjLhtF4Vk',
|
|
|
|
],
|
2019-11-11 13:01:10 -05:00
|
|
|
{commitment: 'recent'},
|
2019-05-28 08:25:16 -07:00
|
|
|
],
|
|
|
|
},
|
|
|
|
{
|
|
|
|
error: null,
|
2020-03-26 21:37:45 +08:00
|
|
|
result: {
|
|
|
|
context: {
|
|
|
|
slot: 11,
|
2020-03-23 23:01:12 +08:00
|
|
|
},
|
2020-03-26 21:37:45 +08:00
|
|
|
value: [
|
|
|
|
{
|
|
|
|
slot: 0,
|
|
|
|
confirmations: 11,
|
|
|
|
status: {Ok: null},
|
|
|
|
},
|
|
|
|
],
|
|
|
|
},
|
2019-05-28 08:25:16 -07:00
|
|
|
},
|
|
|
|
]);
|
2020-03-26 21:37:45 +08:00
|
|
|
const {value} = await connection.getSignatureStatus(signature);
|
|
|
|
if (value !== null) {
|
|
|
|
expect(typeof value.slot).toEqual('number');
|
|
|
|
expect(value.status).toEqual({Ok: null});
|
2020-03-23 23:01:12 +08:00
|
|
|
} else {
|
2020-03-26 21:37:45 +08:00
|
|
|
expect(value).not.toBeNull();
|
2020-03-23 23:01:12 +08:00
|
|
|
}
|
2019-05-28 08:25:16 -07:00
|
|
|
|
|
|
|
mockRpc.push([
|
|
|
|
url,
|
|
|
|
{
|
|
|
|
method: 'getBalance',
|
2019-11-11 13:01:10 -05:00
|
|
|
params: [accountPayer.publicKey.toBase58(), {commitment: 'recent'}],
|
2019-05-28 08:25:16 -07:00
|
|
|
},
|
|
|
|
{
|
|
|
|
error: null,
|
2020-01-08 13:59:58 -07:00
|
|
|
result: {
|
|
|
|
context: {
|
|
|
|
slot: 11,
|
|
|
|
},
|
2020-01-09 10:18:14 -07:00
|
|
|
value: LAMPORTS_PER_SOL - 1,
|
2020-01-08 13:59:58 -07:00
|
|
|
},
|
2019-05-28 08:25:16 -07:00
|
|
|
},
|
|
|
|
]);
|
|
|
|
|
2020-01-09 10:18:14 -07:00
|
|
|
// accountPayer should be less than LAMPORTS_PER_SOL as it paid for the transaction
|
2019-05-28 08:25:16 -07:00
|
|
|
// (exact amount less depends on the current cluster fees)
|
|
|
|
const balance = await connection.getBalance(accountPayer.publicKey);
|
|
|
|
expect(balance).toBeGreaterThan(0);
|
2019-12-30 11:36:12 -07:00
|
|
|
expect(balance).toBeLessThanOrEqual(LAMPORTS_PER_SOL);
|
2019-05-28 08:25:16 -07:00
|
|
|
|
|
|
|
// accountFrom should have exactly 2, since it didn't pay for the transaction
|
|
|
|
mockRpc.push([
|
|
|
|
url,
|
|
|
|
{
|
|
|
|
method: 'getBalance',
|
2019-11-11 13:01:10 -05:00
|
|
|
params: [accountFrom.publicKey.toBase58(), {commitment: 'recent'}],
|
2019-05-28 08:25:16 -07:00
|
|
|
},
|
|
|
|
{
|
|
|
|
error: null,
|
2020-01-08 13:59:58 -07:00
|
|
|
result: {
|
|
|
|
context: {
|
|
|
|
slot: 11,
|
|
|
|
},
|
2020-01-09 10:18:14 -07:00
|
|
|
value: minimumAmount + 2,
|
2020-01-08 13:59:58 -07:00
|
|
|
},
|
2019-05-28 08:25:16 -07:00
|
|
|
},
|
|
|
|
]);
|
2020-01-09 10:18:14 -07:00
|
|
|
expect(await connection.getBalance(accountFrom.publicKey)).toBe(
|
|
|
|
minimumAmount + 2,
|
|
|
|
);
|
2019-05-28 08:25:16 -07:00
|
|
|
});
|