Create TransferTokensTransaction class
This commit is contained in:
parent
cc4019f56f
commit
7dad281f69
|
@ -5,7 +5,7 @@ import fetch from 'node-fetch';
|
||||||
import jayson from 'jayson/lib/client/browser';
|
import jayson from 'jayson/lib/client/browser';
|
||||||
import {struct} from 'superstruct';
|
import {struct} from 'superstruct';
|
||||||
|
|
||||||
import {bs58DecodePublicKey, Transaction} from './transaction';
|
import {Transaction} from './transaction';
|
||||||
import type {Account, PublicKey} from './account';
|
import type {Account, PublicKey} from './account';
|
||||||
import type {TransactionSignature, TransactionId} from './transaction';
|
import type {TransactionSignature, TransactionId} from './transaction';
|
||||||
|
|
||||||
|
@ -218,30 +218,13 @@ export class Connection {
|
||||||
return res.result;
|
return res.result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Send tokens to another account
|
* Sign and send a transaction
|
||||||
*/
|
*/
|
||||||
async sendTokens(from: Account, to: PublicKey, amount: number): Promise<TransactionSignature> {
|
async sendTransaction(from: Account, transaction: Transaction): Promise<TransactionSignature> {
|
||||||
const transaction = new Transaction();
|
|
||||||
transaction.fee = 0;
|
|
||||||
transaction.lastId = await this.getLastId();
|
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);
|
transaction.sign(from);
|
||||||
|
|
||||||
// Send it
|
|
||||||
const wireTransaction = transaction.serialize();
|
const wireTransaction = transaction.serialize();
|
||||||
const unsafeRes = await this._rpcRequest('sendTransaction', [[...wireTransaction]]);
|
const unsafeRes = await this._rpcRequest('sendTransaction', [[...wireTransaction]]);
|
||||||
const res = SendTokensRpcResult(unsafeRes);
|
const res = SendTokensRpcResult(unsafeRes);
|
||||||
|
|
|
@ -9,7 +9,7 @@ import type {Account, PublicKey} from './account';
|
||||||
/**
|
/**
|
||||||
* @private
|
* @private
|
||||||
*/
|
*/
|
||||||
export function bs58DecodePublicKey(key: PublicKey): Buffer {
|
function bs58DecodePublicKey(key: PublicKey): Buffer {
|
||||||
const keyBytes = Buffer.from(bs58.decode(key));
|
const keyBytes = Buffer.from(bs58.decode(key));
|
||||||
assert(keyBytes.length === 32);
|
assert(keyBytes.length === 32);
|
||||||
return keyBytes;
|
return keyBytes;
|
||||||
|
@ -132,3 +132,27 @@ export class Transaction {
|
||||||
return wireTransaction;
|
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
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -1,7 +1,8 @@
|
||||||
// @flow
|
// @flow
|
||||||
|
|
||||||
import {Connection} from '../src/connection';
|
|
||||||
import {Account} from '../src/account';
|
import {Account} from '../src/account';
|
||||||
|
import {Connection} from '../src/connection';
|
||||||
|
import {TransferTokensTransaction} from '../src/transaction';
|
||||||
import {mockRpc} from './__mocks__/node-fetch';
|
import {mockRpc} from './__mocks__/node-fetch';
|
||||||
|
|
||||||
const url = 'http://testnet.solana.com:8899';
|
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([
|
mockRpc.push([
|
||||||
url,
|
url,
|
||||||
|
|
Loading…
Reference in New Issue