feat: add room in the API for Transactions with multiple Instructions

This commit is contained in:
Michael Vines 2018-10-23 15:17:43 -07:00
parent 90c9df15ef
commit b8d586c67e
7 changed files with 120 additions and 65 deletions

View File

@ -80,22 +80,25 @@ declare module '@solana/web3.js' {
declare export type TransactionSignature = string;
declare export type TransactionId = string;
declare type TransactionCtorFields = {|
signature?: Buffer;
declare type TransactionInstructionCtorFields = {|
keys?: Array<PublicKey>;
programId?: PublicKey;
fee?: number;
userdata?: Buffer;
|};
declare export class TransactionInstruction {
fee: number;
constructor(opts?: TransactionInstructionCtorFields): TransactionInstruction;
}
declare type TransactionCtorFields = {|
fee?: number;
|};
declare export class Transaction {
signature: ?Buffer;
keys: Array<PublicKey>;
programId: ?PublicKey;
lastId: ?TransactionId;
fee: number;
userdata: Buffer;
constructor(opts?: TransactionCtorFields): Transaction;
sign(from: Account): void;

View File

@ -203,8 +203,7 @@ export class BudgetProgram {
pos += payment.length;
}
return new Transaction({
fee: 0,
return new Transaction().add({
keys: [from, to],
programId: this.programId,
userdata: userdata.slice(0, pos),
@ -224,8 +223,7 @@ export class BudgetProgram {
pos += paymentData.length;
}
return new Transaction({
fee: 0,
return new Transaction().add({
keys: [from, program, to],
programId: this.programId,
userdata: userdata.slice(0, pos),
@ -245,8 +243,7 @@ export class BudgetProgram {
pos += paymentData.length;
}
return new Transaction({
fee: 0,
return new Transaction().add({
keys: [from, program, to],
programId: this.programId,
userdata: userdata.slice(0, pos),
@ -289,8 +286,7 @@ export class BudgetProgram {
paymentData.copy(userdata, pos);
pos += paymentData.length;
return new Transaction({
fee: 0,
return new Transaction().add({
keys: [from, program, to],
programId: this.programId,
userdata: userdata.slice(0, pos),
@ -309,8 +305,7 @@ export class BudgetProgram {
userdata.writeUInt32LE(1, 0); // ApplyTimestamp instruction
whenData.copy(userdata, 4);
return new Transaction({
fee: 0,
return new Transaction().add({
keys: [from, program, to],
programId: this.programId,
userdata,
@ -334,8 +329,7 @@ export class BudgetProgram {
userdata,
);
return new Transaction({
fee: 0,
return new Transaction().add({
keys: [from, program, to],
programId: this.programId,
userdata,

View File

@ -58,8 +58,7 @@ export class Loader {
userdata,
);
const transaction = new Transaction({
fee: 0,
const transaction = new Transaction().add({
keys: [program.publicKey],
programId: this.programId,
userdata,
@ -85,8 +84,7 @@ export class Loader {
userdata,
);
let transaction = new Transaction({
fee: 0,
let transaction = new Transaction().add({
keys: [program.publicKey],
programId: this.programId,
userdata,

View File

@ -46,8 +46,7 @@ export class SystemProgram {
userdata,
);
return new Transaction({
fee: 0,
return new Transaction().add({
keys: [from, newAccount],
programId: SystemProgram.programId,
userdata,
@ -72,8 +71,7 @@ export class SystemProgram {
userdata,
);
return new Transaction({
fee: 0,
return new Transaction().add({
keys: [from, to],
programId: SystemProgram.programId,
userdata,
@ -98,8 +96,7 @@ export class SystemProgram {
userdata,
);
return new Transaction({
fee: 0,
return new Transaction().add({
keys: [from],
programId: SystemProgram.programId,
userdata,
@ -122,8 +119,7 @@ export class SystemProgram {
userdata,
);
return new Transaction({
fee: 0,
return new Transaction().add({
keys: [programId],
programId: SystemProgram.programId,
userdata,

View File

@ -231,8 +231,7 @@ export class Token {
);
await sendAndConfirmTransaction(connection, owner, transaction);
transaction = new Transaction({
fee: 0,
transaction = new Transaction().add({
keys: [tokenAccount.publicKey, initialAccountPublicKey],
programId,
userdata,
@ -283,8 +282,7 @@ export class Token {
if (source) {
keys.push(source);
}
transaction = new Transaction({
fee: 0,
transaction = new Transaction().add({
keys,
programId: this.programId,
userdata,
@ -389,8 +387,7 @@ export class Token {
if (accountInfo.source) {
keys.push(accountInfo.source);
}
const transaction = new Transaction({
fee: 0,
const transaction = new Transaction().add({
keys,
programId: this.programId,
userdata,
@ -427,8 +424,7 @@ export class Token {
userdata,
);
const transaction = new Transaction({
fee: 0,
const transaction = new Transaction().add({
keys: [owner.publicKey, account, delegate],
programId: this.programId,
userdata,
@ -477,8 +473,7 @@ export class Token {
);
const keys = [owner.publicKey, account,newOwner];
const transaction = new Transaction({
fee: 0,
const transaction = new Transaction().add({
keys,
programId: this.programId,
userdata,

View File

@ -20,34 +20,24 @@ export type TransactionSignature = string;
export type TransactionId = string;
/**
* List of Transaction object fields that may be initialized at construction
* List of TransactionInstruction object fields that may be initialized at construction
*
* @typedef {Object} TransactionCtorFields
* @property {?Buffer} signature
* @typedef {Object} TransactionInstructionCtorFields
* @property {?Array<PublicKey>} keys
* @property {?PublicKey} programId
* @property {?number} fee
* @property {?Buffer} userdata
*/
type TransactionCtorFields = {|
signature?: Buffer;
type TransactionInstructionCtorFields = {|
keys?: Array<PublicKey>;
programId?: PublicKey;
fee?: number;
userdata?: Buffer;
|};
/**
* Mirrors the Transaction struct in src/transaction.rs
* Transaction Instruction class
*/
export class Transaction {
/**
* Current signature of the transaction. Typically created by invoking the
* `sign()` method
*/
signature: ?Buffer;
export class TransactionInstruction {
/**
* Public keys to include in this transaction
*/
@ -58,6 +48,48 @@ export class Transaction {
*/
programId: PublicKey;
/**
* Program input
*/
userdata: Buffer = Buffer.alloc(0);
constructor(opts?: TransactionInstructionCtorFields) {
opts && Object.assign(this, opts);
}
}
/**
* List of Transaction object fields that may be initialized at construction
*
* @typedef {Object} TransactionCtorFields
* @property {?Buffer} signature
* @property {?Array<PublicKey>} keys
* @property {?PublicKey} programId
* @property {?number} fee
* @property {?Buffer} userdata
*/
type TransactionCtorFields = {|
fee?: number;
|};
/**
* Transaction class
*/
export class Transaction {
/**
* Current signature of the transaction. Typically created by invoking the
* `sign()` method
*/
signature: ?Buffer;
/**
* The instructions to atomically execute
*/
instructions: Array<TransactionInstruction> = [];
/**
* A recent transaction id. Must be populated by the caller
*/
@ -68,23 +100,33 @@ export class Transaction {
*/
fee: number = 0;
/**
* Program input
*/
userdata: Buffer = Buffer.alloc(0);
constructor(opts?: TransactionCtorFields) {
opts && Object.assign(this, opts);
}
add(instruction: TransactionInstructionCtorFields): Transaction {
if (this.instructions.length !== 0) {
throw new Error('Multiple instructions not supported yet');
}
this.instructions.push(new TransactionInstruction(instruction));
return this;
}
/**
* @private
*/
_getSignData(): Buffer {
const {lastId, keys, programId, userdata} = this;
const {lastId} = this;
if (!lastId) {
throw new Error('Transaction lastId required');
}
if (this.instructions.length !== 1) {
throw new Error('No instruction provided');
}
const {keys, programId, userdata} = this.instructions[0];
const programIds = [programId];
const instructions = [
{
@ -184,5 +226,33 @@ export class Transaction {
signData.copy(wireTransaction, signature.length);
return wireTransaction;
}
/**
* Deprecated method
* @private
*/
get keys(): Array<PublicKey> {
assert(this.instructions.length === 1);
return this.instructions[0].keys;
}
/**
* Deprecated method
* @private
*/
get programId(): PublicKey {
assert(this.instructions.length === 1);
return this.instructions[0].programId;
}
/**
* Deprecated method
* @private
*/
get userdata(): Buffer {
assert(this.instructions.length === 1);
return this.instructions[0].userdata;
}
}

View File

@ -26,8 +26,7 @@ test('load noop program', async () => {
const from = await newAccountWithTokens(connection);
const noopProgramId = await NativeLoader.load(connection, from, 'noop');
const noopTransaction = new Transaction({
fee: 0,
const noopTransaction = new Transaction().add({
keys: [from.publicKey],
programId: noopProgramId,
});