272 lines
6.7 KiB
JavaScript
272 lines
6.7 KiB
JavaScript
// @flow
|
|
|
|
import bs58 from 'bs58';
|
|
|
|
import {Account, Connection, SystemProgram, PublicKey} from '../src';
|
|
import {NONCE_ACCOUNT_LENGTH} from '../src/nonce-account';
|
|
import {mockRpc, mockRpcEnabled} from './__mocks__/node-fetch';
|
|
import {mockGetRecentBlockhash} from './mockrpc/get-recent-blockhash';
|
|
import {url} from './url';
|
|
import {mockConfirmTransaction} from './mockrpc/confirm-transaction';
|
|
|
|
if (!mockRpcEnabled) {
|
|
// Testing max commitment level takes around 20s to complete
|
|
jest.setTimeout(30000);
|
|
}
|
|
|
|
const expectedData = (authorizedPubkey: PublicKey): string => {
|
|
const expectedData = Buffer.alloc(NONCE_ACCOUNT_LENGTH);
|
|
expectedData.writeInt32LE(0, 0); // Version, 4 bytes
|
|
expectedData.writeInt32LE(1, 4); // State, 4 bytes
|
|
authorizedPubkey.toBuffer().copy(expectedData, 8); // authorizedPubkey, 32 bytes
|
|
const mockNonce = new Account();
|
|
mockNonce.publicKey.toBuffer().copy(expectedData, 40); // Hash, 32 bytes
|
|
expectedData.writeUInt16LE(5000, 72); // feeCalculator, 8 bytes
|
|
return bs58.encode(expectedData);
|
|
};
|
|
|
|
test('create and query nonce account', async () => {
|
|
const from = new Account();
|
|
const nonceAccount = new Account();
|
|
const connection = new Connection(url, 'recent');
|
|
|
|
mockRpc.push([
|
|
url,
|
|
{
|
|
method: 'getMinimumBalanceForRentExemption',
|
|
params: [NONCE_ACCOUNT_LENGTH, {commitment: 'recent'}],
|
|
},
|
|
{
|
|
error: null,
|
|
result: 50,
|
|
},
|
|
]);
|
|
|
|
const minimumAmount = await connection.getMinimumBalanceForRentExemption(
|
|
NONCE_ACCOUNT_LENGTH,
|
|
);
|
|
|
|
mockRpc.push([
|
|
url,
|
|
{
|
|
method: 'requestAirdrop',
|
|
params: [from.publicKey.toBase58(), minimumAmount * 2],
|
|
},
|
|
{
|
|
error: null,
|
|
result:
|
|
'1WE5w4B7v59x6qjyC4FbG2FEKYKQfvsJwqSxNVmtMjT8TQ31hsZieDHcSgqzxiAoTL56n2w5TncjqEKjLhtF4Vk',
|
|
},
|
|
]);
|
|
|
|
const signature = await connection.requestAirdrop(
|
|
from.publicKey,
|
|
minimumAmount * 2,
|
|
);
|
|
mockConfirmTransaction(signature);
|
|
await connection.confirmTransaction(signature, 0);
|
|
|
|
mockRpc.push([
|
|
url,
|
|
{
|
|
method: 'getBalance',
|
|
params: [from.publicKey.toBase58(), {commitment: 'recent'}],
|
|
},
|
|
{
|
|
error: null,
|
|
result: {
|
|
context: {
|
|
slot: 11,
|
|
},
|
|
value: minimumAmount * 2,
|
|
},
|
|
},
|
|
]);
|
|
|
|
const balance = await connection.getBalance(from.publicKey);
|
|
expect(balance).toBe(minimumAmount * 2);
|
|
|
|
mockGetRecentBlockhash('max');
|
|
mockRpc.push([
|
|
url,
|
|
{
|
|
method: 'sendTransaction',
|
|
},
|
|
{
|
|
error: null,
|
|
result:
|
|
'3WE5w4B7v59x6qjyC4FbG2FEKYKQfvsJwqSxNVmtMjT8TQ31hsZieDHcSgqzxiAoTL56n2w5TncjqEKjLhtF4Vk',
|
|
},
|
|
]);
|
|
|
|
const transaction = SystemProgram.createNonceAccount({
|
|
fromPubkey: from.publicKey,
|
|
noncePubkey: nonceAccount.publicKey,
|
|
authorizedPubkey: from.publicKey,
|
|
lamports: minimumAmount,
|
|
});
|
|
const nonceSignature = await connection.sendTransaction(
|
|
transaction,
|
|
[from, nonceAccount],
|
|
{
|
|
skipPreflight: true,
|
|
},
|
|
);
|
|
mockConfirmTransaction(nonceSignature);
|
|
await connection.confirmTransaction(nonceSignature, 0);
|
|
|
|
mockRpc.push([
|
|
url,
|
|
{
|
|
method: 'getAccountInfo',
|
|
params: [nonceAccount.publicKey.toBase58(), {commitment: 'recent'}],
|
|
},
|
|
{
|
|
error: null,
|
|
result: {
|
|
context: {
|
|
slot: 11,
|
|
},
|
|
value: {
|
|
owner: '11111111111111111111111111111111',
|
|
lamports: minimumAmount,
|
|
data: expectedData(from.publicKey),
|
|
executable: false,
|
|
},
|
|
},
|
|
},
|
|
]);
|
|
//
|
|
const nonceAccountData = await connection.getNonce(nonceAccount.publicKey);
|
|
if (nonceAccountData === null) {
|
|
expect(nonceAccountData).not.toBeNull();
|
|
return;
|
|
}
|
|
expect(nonceAccountData.authorizedPubkey).toEqual(from.publicKey);
|
|
expect(bs58.decode(nonceAccountData.nonce).length).toBeGreaterThan(30);
|
|
});
|
|
|
|
test('create and query nonce account with seed', async () => {
|
|
const from = new Account();
|
|
const seed = 'seed';
|
|
const noncePubkey = await PublicKey.createWithSeed(
|
|
from.publicKey,
|
|
seed,
|
|
SystemProgram.programId,
|
|
);
|
|
const connection = new Connection(url, 'recent');
|
|
|
|
mockRpc.push([
|
|
url,
|
|
{
|
|
method: 'getMinimumBalanceForRentExemption',
|
|
params: [NONCE_ACCOUNT_LENGTH, {commitment: 'recent'}],
|
|
},
|
|
{
|
|
error: null,
|
|
result: 50,
|
|
},
|
|
]);
|
|
|
|
const minimumAmount = await connection.getMinimumBalanceForRentExemption(
|
|
NONCE_ACCOUNT_LENGTH,
|
|
);
|
|
|
|
mockRpc.push([
|
|
url,
|
|
{
|
|
method: 'requestAirdrop',
|
|
params: [from.publicKey.toBase58(), minimumAmount * 2],
|
|
},
|
|
{
|
|
error: null,
|
|
result:
|
|
'1WE5w4B7v59x6qjyC4FbG2FEKYKQfvsJwqSxNVmtMjT8TQ31hsZieDHcSgqzxiAoTL56n2w5TncjqEKjLhtF4Vk',
|
|
},
|
|
]);
|
|
|
|
const signature = await connection.requestAirdrop(
|
|
from.publicKey,
|
|
minimumAmount * 2,
|
|
);
|
|
mockConfirmTransaction(signature);
|
|
await connection.confirmTransaction(signature, 0);
|
|
|
|
mockRpc.push([
|
|
url,
|
|
{
|
|
method: 'getBalance',
|
|
params: [from.publicKey.toBase58(), {commitment: 'recent'}],
|
|
},
|
|
{
|
|
error: null,
|
|
result: {
|
|
context: {
|
|
slot: 11,
|
|
},
|
|
value: minimumAmount * 2,
|
|
},
|
|
},
|
|
]);
|
|
|
|
const balance = await connection.getBalance(from.publicKey);
|
|
expect(balance).toBe(minimumAmount * 2);
|
|
|
|
mockGetRecentBlockhash('max');
|
|
mockRpc.push([
|
|
url,
|
|
{
|
|
method: 'sendTransaction',
|
|
},
|
|
{
|
|
error: null,
|
|
result:
|
|
'3WE5w4B7v59x6qjyC4FbG2FEKYKQfvsJwqSxNVmtMjT8TQ31hsZieDHcSgqzxiAoTL56n2w5TncjqEKjLhtF4Vk',
|
|
},
|
|
]);
|
|
|
|
const transaction = SystemProgram.createNonceAccount({
|
|
fromPubkey: from.publicKey,
|
|
noncePubkey: noncePubkey,
|
|
basePubkey: from.publicKey,
|
|
seed,
|
|
authorizedPubkey: from.publicKey,
|
|
lamports: minimumAmount,
|
|
});
|
|
const nonceSignature = await connection.sendTransaction(transaction, [from], {
|
|
skipPreflight: true,
|
|
});
|
|
mockConfirmTransaction(nonceSignature);
|
|
await connection.confirmTransaction(nonceSignature, 0);
|
|
|
|
mockRpc.push([
|
|
url,
|
|
{
|
|
method: 'getAccountInfo',
|
|
params: [noncePubkey.toBase58(), {commitment: 'recent'}],
|
|
},
|
|
{
|
|
error: null,
|
|
result: {
|
|
context: {
|
|
slot: 11,
|
|
},
|
|
value: {
|
|
owner: '11111111111111111111111111111111',
|
|
lamports: minimumAmount,
|
|
data: expectedData(from.publicKey),
|
|
executable: false,
|
|
},
|
|
},
|
|
},
|
|
]);
|
|
//
|
|
const nonceAccountData = await connection.getNonce(noncePubkey);
|
|
if (nonceAccountData === null) {
|
|
expect(nonceAccountData).not.toBeNull();
|
|
return;
|
|
}
|
|
expect(nonceAccountData.authorizedPubkey).toEqual(from.publicKey);
|
|
expect(bs58.decode(nonceAccountData.nonce).length).toBeGreaterThan(30);
|
|
});
|