From 7dad281f69a316c67f7aba5599b73e7925a585d8 Mon Sep 17 00:00:00 2001 From: Michael Vines Date: Fri, 14 Sep 2018 08:27:40 -0700 Subject: [PATCH] Create TransferTokensTransaction class --- web3.js/src/connection.js | 23 +++-------------------- web3.js/src/transaction.js | 26 +++++++++++++++++++++++++- web3.js/test/connection.test.js | 11 +++++++++-- 3 files changed, 37 insertions(+), 23 deletions(-) diff --git a/web3.js/src/connection.js b/web3.js/src/connection.js index 37fa343de3..c2fb7a6266 100644 --- a/web3.js/src/connection.js +++ b/web3.js/src/connection.js @@ -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 { - const transaction = new Transaction(); - transaction.fee = 0; + async sendTransaction(from: Account, transaction: Transaction): Promise { 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); diff --git a/web3.js/src/transaction.js b/web3.js/src/transaction.js index 18eb2ec7bd..6ecb52ea5f 100644 --- a/web3.js/src/transaction.js +++ b/web3.js/src/transaction.js @@ -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 + }); + } +} diff --git a/web3.js/test/connection.test.js b/web3.js/test/connection.test.js index 9f5a7d53ca..94bafa1767 100644 --- a/web3.js/test/connection.test.js +++ b/web3.js/test/connection.test.js @@ -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,