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 TransactionSignature = string;
declare export type TransactionId = string; declare export type TransactionId = string;
declare type TransactionCtorFields = {| declare type TransactionInstructionCtorFields = {|
signature?: Buffer;
keys?: Array<PublicKey>; keys?: Array<PublicKey>;
programId?: PublicKey; programId?: PublicKey;
fee?: number;
userdata?: Buffer; userdata?: Buffer;
|}; |};
declare export class TransactionInstruction {
fee: number;
constructor(opts?: TransactionInstructionCtorFields): TransactionInstruction;
}
declare type TransactionCtorFields = {|
fee?: number;
|};
declare export class Transaction { declare export class Transaction {
signature: ?Buffer; signature: ?Buffer;
keys: Array<PublicKey>;
programId: ?PublicKey;
lastId: ?TransactionId;
fee: number; fee: number;
userdata: Buffer;
constructor(opts?: TransactionCtorFields): Transaction; constructor(opts?: TransactionCtorFields): Transaction;
sign(from: Account): void; sign(from: Account): void;

View File

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

View File

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

View File

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

View File

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

View File

@ -20,34 +20,24 @@ export type TransactionSignature = string;
export type TransactionId = 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 * @typedef {Object} TransactionInstructionCtorFields
* @property {?Buffer} signature
* @property {?Array<PublicKey>} keys * @property {?Array<PublicKey>} keys
* @property {?PublicKey} programId * @property {?PublicKey} programId
* @property {?number} fee
* @property {?Buffer} userdata * @property {?Buffer} userdata
*/ */
type TransactionCtorFields = {| type TransactionInstructionCtorFields = {|
signature?: Buffer;
keys?: Array<PublicKey>; keys?: Array<PublicKey>;
programId?: PublicKey; programId?: PublicKey;
fee?: number;
userdata?: Buffer; userdata?: Buffer;
|}; |};
/** /**
* Mirrors the Transaction struct in src/transaction.rs * Transaction Instruction class
*/ */
export class Transaction { export class TransactionInstruction {
/**
* Current signature of the transaction. Typically created by invoking the
* `sign()` method
*/
signature: ?Buffer;
/** /**
* Public keys to include in this transaction * Public keys to include in this transaction
*/ */
@ -58,6 +48,48 @@ export class Transaction {
*/ */
programId: PublicKey; 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 * A recent transaction id. Must be populated by the caller
*/ */
@ -68,23 +100,33 @@ export class Transaction {
*/ */
fee: number = 0; fee: number = 0;
/**
* Program input
*/
userdata: Buffer = Buffer.alloc(0);
constructor(opts?: TransactionCtorFields) { constructor(opts?: TransactionCtorFields) {
opts && Object.assign(this, opts); 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 * @private
*/ */
_getSignData(): Buffer { _getSignData(): Buffer {
const {lastId, keys, programId, userdata} = this; const {lastId} = this;
if (!lastId) { if (!lastId) {
throw new Error('Transaction lastId required'); 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 programIds = [programId];
const instructions = [ const instructions = [
{ {
@ -184,5 +226,33 @@ export class Transaction {
signData.copy(wireTransaction, signature.length); signData.copy(wireTransaction, signature.length);
return wireTransaction; 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 from = await newAccountWithTokens(connection);
const noopProgramId = await NativeLoader.load(connection, from, 'noop'); const noopProgramId = await NativeLoader.load(connection, from, 'noop');
const noopTransaction = new Transaction({ const noopTransaction = new Transaction().add({
fee: 0,
keys: [from.publicKey], keys: [from.publicKey],
programId: noopProgramId, programId: noopProgramId,
}); });