diff --git a/web3.js/module.flow.js b/web3.js/module.flow.js index 660f57e47..2f25ce5c9 100644 --- a/web3.js/module.flow.js +++ b/web3.js/module.flow.js @@ -69,6 +69,7 @@ declare module '@solana/web3.js' { ): Transaction; static move(from: PublicKey, to: PublicKey, amount: number): Transaction; static assign(from: PublicKey, programId: PublicKey): Transaction; + static spawn(programId: PublicKey): Transaction; } // === src/transaction.js === diff --git a/web3.js/src/loader.js b/web3.js/src/loader.js index 41aac34b8..3dc9e6898 100644 --- a/web3.js/src/loader.js +++ b/web3.js/src/loader.js @@ -2,7 +2,7 @@ import * as BufferLayout from 'buffer-layout'; -import {PublicKey, Transaction} from '.'; +import {PublicKey, SystemProgram, Transaction} from '.'; import {sendAndConfirmTransaction} from './util/send-and-confirm-transaction'; import type {Account, Connection} from '.'; @@ -85,12 +85,15 @@ export class Loader { userdata, ); - const transaction = new Transaction({ + let transaction = new Transaction({ fee: 0, keys: [program.publicKey], programId: this.programId, userdata, }); await sendAndConfirmTransaction(this.connection, program, transaction); + + transaction = SystemProgram.spawn(program.publicKey); + await sendAndConfirmTransaction(this.connection, program, transaction); } } diff --git a/web3.js/src/system-program.js b/web3.js/src/system-program.js index c8cba56f1..743bca9cf 100644 --- a/web3.js/src/system-program.js +++ b/web3.js/src/system-program.js @@ -105,4 +105,28 @@ export class SystemProgram { userdata, }); } + + /** + * Spawn a new program from an account + */ + static spawn(programId: PublicKey): Transaction { + const userdataLayout = BufferLayout.struct([ + BufferLayout.u32('instruction'), + ]); + + const userdata = Buffer.alloc(userdataLayout.span); + userdataLayout.encode( + { + instruction: 3, // Spawn instruction + }, + userdata, + ); + + return new Transaction({ + fee: 0, + keys: [programId], + programId: SystemProgram.programId, + userdata, + }); + } } diff --git a/web3.js/test/native-loader.test.js b/web3.js/test/native-loader.test.js index a59e35cd2..4f1e067be 100644 --- a/web3.js/test/native-loader.test.js +++ b/web3.js/test/native-loader.test.js @@ -9,7 +9,7 @@ import {mockRpcEnabled} from './__mocks__/node-fetch'; import {url} from './url'; import {newAccountWithTokens} from './new-account-with-tokens'; -test('unstable - load', async () => { +test('load noop program', async () => { if (mockRpcEnabled) { console.log('non-live test skipped'); return; @@ -25,6 +25,6 @@ test('unstable - load', async () => { programId: noopProgramId, }); const signature = await connection.sendTransaction(from, noopTransaction); - expect(connection.confirmTransaction(signature)).resolves.toBe(true); + await expect(connection.confirmTransaction(signature)).resolves.toBe(true); });