feat: add unstable API for dynamic program loading
This commit is contained in:
@ -5,4 +5,4 @@ export {Connection} from './connection';
|
|||||||
export {PublicKey} from './publickey';
|
export {PublicKey} from './publickey';
|
||||||
export {SystemProgram} from './system-program';
|
export {SystemProgram} from './system-program';
|
||||||
export {Transaction} from './transaction';
|
export {Transaction} from './transaction';
|
||||||
export {Token} from './token-program';
|
export {Token, TokenAmount} from './token-program';
|
||||||
|
@ -105,4 +105,35 @@ export class SystemProgram {
|
|||||||
userdata,
|
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
|
// @flow
|
||||||
|
|
||||||
import {Account} from '../src/account';
|
import {
|
||||||
import {Connection} from '../src/connection';
|
Account,
|
||||||
import {SystemProgram} from '../src/system-program';
|
Connection,
|
||||||
|
SystemProgram,
|
||||||
|
} from '../src';
|
||||||
import {mockRpc, mockRpcEnabled} from './__mocks__/node-fetch';
|
import {mockRpc, mockRpcEnabled} from './__mocks__/node-fetch';
|
||||||
import {url} from './url.js';
|
import {url} from './url';
|
||||||
|
|
||||||
if (!mockRpcEnabled) {
|
if (!mockRpcEnabled) {
|
||||||
// The default of 5 seconds is too slow for live testing sometimes
|
// The default of 5 seconds is too slow for live testing sometimes
|
||||||
|
32
web3.js/test/new-account-with-tokens.js
Normal file
32
web3.js/test/new-account-with-tokens.js
Normal file
@ -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
|
// @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', () => {
|
test('createAccount', () => {
|
||||||
const from = new Account();
|
const from = new Account();
|
||||||
@ -52,4 +61,33 @@ test('assign', () => {
|
|||||||
// TODO: Validate transaction contents more
|
// 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
|
// @flow
|
||||||
|
|
||||||
import {Account} from '../src/account';
|
import {
|
||||||
import {Connection} from '../src/connection';
|
Connection,
|
||||||
import {Token, TokenAmount} from '../src/token-program';
|
PublicKey,
|
||||||
import {PublicKey} from '../src/publickey';
|
Token,
|
||||||
|
TokenAmount,
|
||||||
|
} from '../src';
|
||||||
import {mockRpc, mockRpcEnabled} from './__mocks__/node-fetch';
|
import {mockRpc, mockRpcEnabled} from './__mocks__/node-fetch';
|
||||||
import {url} from './url.js';
|
import {url} from './url';
|
||||||
import type {SignatureStatus} from '../src/connection';
|
import {newAccountWithTokens} from './new-account-with-tokens';
|
||||||
|
|
||||||
if (!mockRpcEnabled) {
|
if (!mockRpcEnabled) {
|
||||||
// The default of 5 seconds is too slow for live testing sometimes
|
// 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([
|
mockRpc.push([
|
||||||
url,
|
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
|
// A token created by the first test and used by all subsequent tests
|
||||||
let testToken: Token;
|
let testToken: Token;
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user