Skip to content

Commit 850ca98

Browse files
committed
feat: add unstable API for dynamic program loading
1 parent 677be00 commit 850ca98

File tree

6 files changed

+118
-34
lines changed

6 files changed

+118
-34
lines changed

src/index.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,4 +5,4 @@ export {Connection} from './connection';
55
export {PublicKey} from './publickey';
66
export {SystemProgram} from './system-program';
77
export {Transaction} from './transaction';
8-
export {Token} from './token-program';
8+
export {Token, TokenAmount} from './token-program';

src/system-program.js

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -105,4 +105,35 @@ export class SystemProgram {
105105
userdata,
106106
});
107107
}
108+
109+
/**
110+
* Load a dynamic program. Unstable API, will change
111+
*
112+
* @private
113+
*/
114+
static load(from: PublicKey, programId: PublicKey, name: string): Transaction {
115+
const userdataLayout = BufferLayout.struct([
116+
BufferLayout.u32('instruction'),
117+
Layout.publicKey('programId'),
118+
Layout.rustString('name'),
119+
]);
120+
121+
let userdata = Buffer.alloc(1024);
122+
const encodeLength = userdataLayout.encode(
123+
{
124+
instruction: 3, // Load instruction
125+
programId: programId.toBuffer(),
126+
name,
127+
},
128+
userdata,
129+
);
130+
userdata = userdata.slice(0, encodeLength);
131+
132+
return new Transaction({
133+
fee: 0,
134+
keys: [from],
135+
programId: SystemProgram.programId,
136+
userdata,
137+
});
138+
}
108139
}

test/connection.test.js

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,12 @@
11
// @flow
22

3-
import {Account} from '../src/account';
4-
import {Connection} from '../src/connection';
5-
import {SystemProgram} from '../src/system-program';
3+
import {
4+
Account,
5+
Connection,
6+
SystemProgram,
7+
} from '../src';
68
import {mockRpc, mockRpcEnabled} from './__mocks__/node-fetch';
7-
import {url} from './url.js';
9+
import {url} from './url';
810

911
if (!mockRpcEnabled) {
1012
// The default of 5 seconds is too slow for live testing sometimes

test/new-account-with-tokens.js

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
// @flow
2+
3+
import {
4+
Account,
5+
Connection,
6+
} from '../src';
7+
import {mockRpc} from './__mocks__/node-fetch';
8+
import {url} from './url';
9+
10+
export async function newAccountWithTokens(connection: Connection, amount: number = 10): Promise<Account> {
11+
const account = new Account();
12+
13+
{
14+
mockRpc.push([
15+
url,
16+
{
17+
method: 'requestAirdrop',
18+
params: [account.publicKey.toBase58(), amount],
19+
},
20+
{
21+
error: null,
22+
// Signature doesn't matter
23+
result: '3WE5w4B7v59x6qjyC4FbG2FEKYKQfvsJwqSxNVmtMjT8TQ31hsZieDHcSgqzxiAoTL56n2w5TncjqEKjLhtF4Vk',
24+
}
25+
]);
26+
}
27+
28+
await connection.requestAirdrop(account.publicKey, amount);
29+
return account;
30+
}
31+
32+

test/system-program.test.js

Lines changed: 39 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,15 @@
11
// @flow
22

3-
import {Account, SystemProgram, BudgetProgram} from '../src';
3+
import {
4+
Account,
5+
BudgetProgram,
6+
Connection,
7+
SystemProgram,
8+
Transaction,
9+
} from '../src';
10+
import {mockRpcEnabled} from './__mocks__/node-fetch';
11+
import {url} from './url';
12+
import {newAccountWithTokens} from './new-account-with-tokens';
413

514
test('createAccount', () => {
615
const from = new Account();
@@ -52,4 +61,33 @@ test('assign', () => {
5261
// TODO: Validate transaction contents more
5362
});
5463

64+
test('unstable - load', async () => {
65+
if (mockRpcEnabled) {
66+
console.log('non-live test skipped');
67+
return;
68+
}
69+
70+
const connection = new Connection(url);
71+
const from = await newAccountWithTokens(connection);
72+
const noopProgramId = (new Account()).publicKey;
73+
74+
const loadTransaction = SystemProgram.load(
75+
from.publicKey,
76+
noopProgramId,
77+
'noop',
78+
);
79+
80+
let signature = await connection.sendTransaction(from, loadTransaction);
81+
expect(connection.confirmTransaction(signature)).resolves.toBe(true);
82+
83+
const noopTransaction = new Transaction({
84+
fee: 0,
85+
keys: [from.publicKey],
86+
programId: noopProgramId,
87+
});
88+
signature = await connection.sendTransaction(from, noopTransaction);
89+
expect(connection.confirmTransaction(signature)).resolves.toBe(true);
90+
91+
92+
});
5593

test/token-program.test.js

Lines changed: 9 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,14 @@
11
// @flow
22

3-
import {Account} from '../src/account';
4-
import {Connection} from '../src/connection';
5-
import {Token, TokenAmount} from '../src/token-program';
6-
import {PublicKey} from '../src/publickey';
3+
import {
4+
Connection,
5+
PublicKey,
6+
Token,
7+
TokenAmount,
8+
} from '../src';
79
import {mockRpc, mockRpcEnabled} from './__mocks__/node-fetch';
8-
import {url} from './url.js';
9-
import type {SignatureStatus} from '../src/connection';
10+
import {url} from './url';
11+
import {newAccountWithTokens} from './new-account-with-tokens';
1012

1113
if (!mockRpcEnabled) {
1214
// The default of 5 seconds is too slow for live testing sometimes
@@ -27,7 +29,7 @@ function mockGetLastId() {
2729
]);
2830
}
2931

30-
function mockGetSignatureStatus(result: SignatureStatus = 'Confirmed') {
32+
function mockGetSignatureStatus(result: string = 'Confirmed') {
3133
mockRpc.push([
3234
url,
3335
{
@@ -53,27 +55,6 @@ function mockSendTransaction() {
5355
}
5456

5557

56-
async function newAccountWithTokens(connection: Connection, amount: number = 10): Promise<Account> {
57-
const account = new Account();
58-
59-
{
60-
mockRpc.push([
61-
url,
62-
{
63-
method: 'requestAirdrop',
64-
params: [account.publicKey.toBase58(), amount],
65-
},
66-
{
67-
error: null,
68-
result: '3WE5w4B7v59x6qjyC4FbG2FEKYKQfvsJwqSxNVmtMjT8TQ31hsZieDHcSgqzxiAoTL56n2w5TncjqEKjLhtF4Vk',
69-
}
70-
]);
71-
}
72-
73-
await connection.requestAirdrop(account.publicKey, amount);
74-
return account;
75-
}
76-
7758
// A token created by the first test and used by all subsequent tests
7859
let testToken: Token;
7960

0 commit comments

Comments
 (0)