Create TransferTokensTransaction class

This commit is contained in:
Michael Vines 2018-09-14 08:27:40 -07:00
parent cc4019f56f
commit 7dad281f69
3 changed files with 37 additions and 23 deletions

View File

@ -5,7 +5,7 @@ import fetch from 'node-fetch';
import jayson from 'jayson/lib/client/browser';
import {struct} from 'superstruct';
import {bs58DecodePublicKey, Transaction} from './transaction';
import {Transaction} from './transaction';
import type {Account, PublicKey} from './account';
import type {TransactionSignature, TransactionId} from './transaction';
@ -218,30 +218,13 @@ export class Connection {
return res.result;
}
/**
* Send tokens to another account
* Sign and send a transaction
*/
async sendTokens(from: Account, to: PublicKey, amount: number): Promise<TransactionSignature> {
const transaction = new Transaction();
transaction.fee = 0;
async sendTransaction(from: Account, transaction: Transaction): Promise<TransactionSignature> {
transaction.lastId = await this.getLastId();
transaction.keys[0] = from.publicKey;
transaction.keys[1] = to;
// Forge a simple Budget Pay contract into `userdata`
// TODO: Clean this up
const userdata = Buffer.alloc(68); // 68 = serialized size of Budget enum
userdata.writeUInt32LE(60, 0);
userdata.writeUInt32LE(amount, 12); // u64
userdata.writeUInt32LE(amount, 28); // u64
const toData = bs58DecodePublicKey(to);
toData.copy(userdata, 36);
transaction.userdata = userdata;
transaction.sign(from);
// Send it
const wireTransaction = transaction.serialize();
const unsafeRes = await this._rpcRequest('sendTransaction', [[...wireTransaction]]);
const res = SendTokensRpcResult(unsafeRes);

View File

@ -9,7 +9,7 @@ import type {Account, PublicKey} from './account';
/**
* @private
*/
export function bs58DecodePublicKey(key: PublicKey): Buffer {
function bs58DecodePublicKey(key: PublicKey): Buffer {
const keyBytes = Buffer.from(bs58.decode(key));
assert(keyBytes.length === 32);
return keyBytes;
@ -132,3 +132,27 @@ export class Transaction {
return wireTransaction;
}
}
/**
* A Transaction that immediately transfers tokens
*/
export class TransferTokensTransaction extends Transaction {
constructor(from: PublicKey, to: PublicKey, amount: number) {
super();
// Forge a simple Budget Pay contract into `userdata`
// TODO: Clean this up
const userdata = Buffer.alloc(68); // 68 = serialized size of Budget enum
userdata.writeUInt32LE(60, 0);
userdata.writeUInt32LE(amount, 12); // u64
userdata.writeUInt32LE(amount, 28); // u64
const toData = bs58DecodePublicKey(to);
toData.copy(userdata, 36);
Object.assign(this, {
fee: 0,
keys: [from, to],
userdata
});
}
}

View File

@ -1,7 +1,8 @@
// @flow
import {Connection} from '../src/connection';
import {Account} from '../src/account';
import {Connection} from '../src/connection';
import {TransferTokensTransaction} from '../src/transaction';
import {mockRpc} from './__mocks__/node-fetch';
const url = 'http://testnet.solana.com:8899';
@ -272,7 +273,13 @@ test('transaction', async () => {
}
]
);
const signature = await connection.sendTokens(accountFrom, accountTo.publicKey, 10);
const transaction = new TransferTokensTransaction(
accountFrom.publicKey,
accountTo.publicKey,
10
);
const signature = await connection.sendTransaction(accountFrom, transaction);
mockRpc.push([
url,