feat: add unstable API for dynamic program loading
This commit is contained in:
parent
715556a611
commit
1436eca398
|
@ -5,4 +5,4 @@ export {Connection} from './connection';
|
|||
export {PublicKey} from './publickey';
|
||||
export {SystemProgram} from './system-program';
|
||||
export {Transaction} from './transaction';
|
||||
export {Token} from './token-program';
|
||||
export {Token, TokenAmount} from './token-program';
|
||||
|
|
|
@ -105,4 +105,35 @@ export class SystemProgram {
|
|||
userdata,
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Load a dynamic program. Unstable API, will change
|
||||
*
|
||||
* @private
|
||||
*/
|
||||
static load(from: PublicKey, programId: PublicKey, name: string): Transaction {
|
||||
const userdataLayout = BufferLayout.struct([
|
||||
BufferLayout.u32('instruction'),
|
||||
Layout.publicKey('programId'),
|
||||
Layout.rustString('name'),
|
||||
]);
|
||||
|
||||
let userdata = Buffer.alloc(1024);
|
||||
const encodeLength = userdataLayout.encode(
|
||||
{
|
||||
instruction: 3, // Load instruction
|
||||
programId: programId.toBuffer(),
|
||||
name,
|
||||
},
|
||||
userdata,
|
||||
);
|
||||
userdata = userdata.slice(0, encodeLength);
|
||||
|
||||
return new Transaction({
|
||||
fee: 0,
|
||||
keys: [from],
|
||||
programId: SystemProgram.programId,
|
||||
userdata,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,10 +1,12 @@
|
|||
// @flow
|
||||
|
||||
import {Account} from '../src/account';
|
||||
import {Connection} from '../src/connection';
|
||||
import {SystemProgram} from '../src/system-program';
|
||||
import {
|
||||
Account,
|
||||
Connection,
|
||||
SystemProgram,
|
||||
} from '../src';
|
||||
import {mockRpc, mockRpcEnabled} from './__mocks__/node-fetch';
|
||||
import {url} from './url.js';
|
||||
import {url} from './url';
|
||||
|
||||
if (!mockRpcEnabled) {
|
||||
// The default of 5 seconds is too slow for live testing sometimes
|
||||
|
|
|
@ -0,0 +1,32 @@
|
|||
// @flow
|
||||
|
||||
import {
|
||||
Account,
|
||||
Connection,
|
||||
} from '../src';
|
||||
import {mockRpc} from './__mocks__/node-fetch';
|
||||
import {url} from './url';
|
||||
|
||||
export async function newAccountWithTokens(connection: Connection, amount: number = 10): Promise<Account> {
|
||||
const account = new Account();
|
||||
|
||||
{
|
||||
mockRpc.push([
|
||||
url,
|
||||
{
|
||||
method: 'requestAirdrop',
|
||||
params: [account.publicKey.toBase58(), amount],
|
||||
},
|
||||
{
|
||||
error: null,
|
||||
// Signature doesn't matter
|
||||
result: '3WE5w4B7v59x6qjyC4FbG2FEKYKQfvsJwqSxNVmtMjT8TQ31hsZieDHcSgqzxiAoTL56n2w5TncjqEKjLhtF4Vk',
|
||||
}
|
||||
]);
|
||||
}
|
||||
|
||||
await connection.requestAirdrop(account.publicKey, amount);
|
||||
return account;
|
||||
}
|
||||
|
||||
|
|
@ -1,6 +1,15 @@
|
|||
// @flow
|
||||
|
||||
import {Account, SystemProgram, BudgetProgram} from '../src';
|
||||
import {
|
||||
Account,
|
||||
BudgetProgram,
|
||||
Connection,
|
||||
SystemProgram,
|
||||
Transaction,
|
||||
} from '../src';
|
||||
import {mockRpcEnabled} from './__mocks__/node-fetch';
|
||||
import {url} from './url';
|
||||
import {newAccountWithTokens} from './new-account-with-tokens';
|
||||
|
||||
test('createAccount', () => {
|
||||
const from = new Account();
|
||||
|
@ -52,4 +61,33 @@ test('assign', () => {
|
|||
// TODO: Validate transaction contents more
|
||||
});
|
||||
|
||||
test('unstable - load', async () => {
|
||||
if (mockRpcEnabled) {
|
||||
console.log('non-live test skipped');
|
||||
return;
|
||||
}
|
||||
|
||||
const connection = new Connection(url);
|
||||
const from = await newAccountWithTokens(connection);
|
||||
const noopProgramId = (new Account()).publicKey;
|
||||
|
||||
const loadTransaction = SystemProgram.load(
|
||||
from.publicKey,
|
||||
noopProgramId,
|
||||
'noop',
|
||||
);
|
||||
|
||||
let signature = await connection.sendTransaction(from, loadTransaction);
|
||||
expect(connection.confirmTransaction(signature)).resolves.toBe(true);
|
||||
|
||||
const noopTransaction = new Transaction({
|
||||
fee: 0,
|
||||
keys: [from.publicKey],
|
||||
programId: noopProgramId,
|
||||
});
|
||||
signature = await connection.sendTransaction(from, noopTransaction);
|
||||
expect(connection.confirmTransaction(signature)).resolves.toBe(true);
|
||||
|
||||
|
||||
});
|
||||
|
||||
|
|
|
@ -1,12 +1,14 @@
|
|||
// @flow
|
||||
|
||||
import {Account} from '../src/account';
|
||||
import {Connection} from '../src/connection';
|
||||
import {Token, TokenAmount} from '../src/token-program';
|
||||
import {PublicKey} from '../src/publickey';
|
||||
import {
|
||||
Connection,
|
||||
PublicKey,
|
||||
Token,
|
||||
TokenAmount,
|
||||
} from '../src';
|
||||
import {mockRpc, mockRpcEnabled} from './__mocks__/node-fetch';
|
||||
import {url} from './url.js';
|
||||
import type {SignatureStatus} from '../src/connection';
|
||||
import {url} from './url';
|
||||
import {newAccountWithTokens} from './new-account-with-tokens';
|
||||
|
||||
if (!mockRpcEnabled) {
|
||||
// The default of 5 seconds is too slow for live testing sometimes
|
||||
|
@ -27,7 +29,7 @@ function mockGetLastId() {
|
|||
]);
|
||||
}
|
||||
|
||||
function mockGetSignatureStatus(result: SignatureStatus = 'Confirmed') {
|
||||
function mockGetSignatureStatus(result: string = 'Confirmed') {
|
||||
mockRpc.push([
|
||||
url,
|
||||
{
|
||||
|
@ -53,27 +55,6 @@ function mockSendTransaction() {
|
|||
}
|
||||
|
||||
|
||||
async function newAccountWithTokens(connection: Connection, amount: number = 10): Promise<Account> {
|
||||
const account = new Account();
|
||||
|
||||
{
|
||||
mockRpc.push([
|
||||
url,
|
||||
{
|
||||
method: 'requestAirdrop',
|
||||
params: [account.publicKey.toBase58(), amount],
|
||||
},
|
||||
{
|
||||
error: null,
|
||||
result: '3WE5w4B7v59x6qjyC4FbG2FEKYKQfvsJwqSxNVmtMjT8TQ31hsZieDHcSgqzxiAoTL56n2w5TncjqEKjLhtF4Vk',
|
||||
}
|
||||
]);
|
||||
}
|
||||
|
||||
await connection.requestAirdrop(account.publicKey, amount);
|
||||
return account;
|
||||
}
|
||||
|
||||
// A token created by the first test and used by all subsequent tests
|
||||
let testToken: Token;
|
||||
|
||||
|
|
Loading…
Reference in New Issue