Skip to content

Commit 72fdc47

Browse files
committed
feat: wrap public key in a class
1 parent c54d06f commit 72fdc47

File tree

15 files changed

+179
-94
lines changed

15 files changed

+179
-94
lines changed

examples/account.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,4 +7,4 @@ const solanaWeb3 = require('..');
77
//const solanaWeb3 = require('@solana/web3.js');
88

99
const account = new solanaWeb3.Account();
10-
console.log(account.publicKey);
10+
console.log(account.publicKey.toString());

flow-typed/bn.js.js

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
declare module 'bn.js' {
2+
// TODO: Fill in types
3+
declare module.exports: any;
4+
}

module.flow.js

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,11 +13,20 @@
1313
declare module '@solana/web3.js' {
1414
declare export type PublicKey = string;
1515

16+
// === src/publickey.js ===
17+
declare export class PublicKey {
18+
constructor(number: string | Buffer | Array<number>): PublicKey;
19+
static isPublicKey(o: Object): boolean;
20+
equals(publickey: PublicKey): boolean;
21+
toBase58(): string;
22+
toBuffer(): Buffer;
23+
}
24+
1625
// === src/account.js ===
1726
declare export class Account {
1827
constructor(secretKey: ?Buffer): Account;
1928
publicKey: PublicKey;
20-
secretKey: PublicKey;
29+
secretKey: Buffer;
2130
}
2231

2332
// === src/budget-program.js ===
@@ -84,6 +93,5 @@ declare module '@solana/web3.js' {
8493
constructor(opts?: TransactionCtorFields): Transaction;
8594
sign(from: Account): void;
8695
serialize(): Buffer;
87-
static serializePublicKey(key: PublicKey): Buffer;
8896
}
8997
}

package-lock.json

Lines changed: 2 additions & 3 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@
4343
},
4444
"dependencies": {
4545
"babel-runtime": "^6.26.0",
46+
"bn.js": "^4.11.8",
4647
"bs58": "^4.0.1",
4748
"jayson": "^2.0.6",
4849
"node-fetch": "^2.2.0",

src/account.js

Lines changed: 2 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,8 @@
11
// @flow
22
import nacl from 'tweetnacl';
3-
import bs58 from 'bs58';
43
import type {KeyPair} from 'tweetnacl';
54

6-
/**
7-
* Base 58 encoded public key
8-
*
9-
* @typedef {string} PublicKey
10-
*/
11-
export type PublicKey = string;
5+
import {PublicKey} from './publickey';
126

137
/**
148
* An account key pair (public and secret keys).
@@ -36,7 +30,7 @@ export class Account {
3630
* The public key for this account
3731
*/
3832
get publicKey(): PublicKey {
39-
return bs58.encode(this._keypair.publicKey);
33+
return new PublicKey(this._keypair.publicKey);
4034
}
4135

4236
/**

src/budget-program.js

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
// @flow
22

33
import {Transaction} from './transaction';
4-
import type {PublicKey} from './account';
4+
import {PublicKey} from './publickey';
55

66
/**
77
* Represents a condition that is met by executing a `applySignature()`
@@ -54,7 +54,7 @@ export type BudgetCondition = SignatureCondition | TimestampCondition;
5454
* @private
5555
*/
5656
function serializePayment(payment: Payment): Buffer {
57-
const toData = Transaction.serializePublicKey(payment.to);
57+
const toData = payment.to.toBuffer();
5858
const userdata = Buffer.alloc(8 + toData.length);
5959
userdata.writeUInt32LE(payment.amount, 0);
6060
toData.copy(userdata, 8);
@@ -98,7 +98,7 @@ function serializeCondition(condition: BudgetCondition) {
9898
case 'timestamp':
9999
{
100100
const date = serializeDate(condition.when);
101-
const from = Transaction.serializePublicKey(condition.from);
101+
const from = condition.from.toBuffer();
102102

103103
const userdata = Buffer.alloc(4 + date.length + from.length);
104104
userdata.writeUInt32LE(0, 0); // Condition enum = Timestamp
@@ -108,7 +108,7 @@ function serializeCondition(condition: BudgetCondition) {
108108
}
109109
case 'signature':
110110
{
111-
const from = Transaction.serializePublicKey(condition.from);
111+
const from = condition.from.toBuffer();
112112

113113
const userdata = Buffer.alloc(4 + from.length);
114114
userdata.writeUInt32LE(1, 0); // Condition enum = Signature
@@ -130,7 +130,7 @@ export class BudgetProgram {
130130
* Public key that identifies the Budget program
131131
*/
132132
static get programId(): PublicKey {
133-
return '4uQeVj5tqViQh7yWWGStvkEG1Zmhx6uasJtWCJziofM';
133+
return new PublicKey('0x100000000000000000000000000000000000000000000000000000000000000');
134134
}
135135

136136
/**

src/connection.js

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,10 @@ import assert from 'assert';
44
import fetch from 'node-fetch';
55
import jayson from 'jayson/lib/client/browser';
66
import {struct} from 'superstruct';
7-
import bs58 from 'bs58';
87

98
import {Transaction} from './transaction';
10-
import type {Account, PublicKey} from './account';
9+
import {PublicKey} from './publickey';
10+
import type {Account} from './account';
1111
import type {TransactionSignature, TransactionId} from './transaction';
1212

1313
type RpcRequest = (methodName: string, args: Array<any>) => any;
@@ -174,7 +174,7 @@ export class Connection {
174174
async getBalance(publicKey: PublicKey): Promise<number> {
175175
const unsafeRes = await this._rpcRequest(
176176
'getBalance',
177-
[publicKey]
177+
[publicKey.toBase58()]
178178
);
179179
const res = GetBalanceRpcResult(unsafeRes);
180180
if (res.error) {
@@ -190,7 +190,7 @@ export class Connection {
190190
async getAccountInfo(publicKey: PublicKey): Promise<AccountInfo> {
191191
const unsafeRes = await this._rpcRequest(
192192
'getAccountInfo',
193-
[publicKey]
193+
[publicKey.toBase58()]
194194
);
195195
const res = GetAccountInfoRpcResult(unsafeRes);
196196
if (res.error) {
@@ -202,7 +202,7 @@ export class Connection {
202202

203203
return {
204204
tokens: result.tokens,
205-
programId: bs58.encode(result.program_id),
205+
programId: new PublicKey(result.program_id),
206206
userdata: Buffer.from(result.userdata),
207207
};
208208
}
@@ -280,7 +280,7 @@ export class Connection {
280280
* Request an allocation of tokens to the specified account
281281
*/
282282
async requestAirdrop(to: PublicKey, amount: number): Promise<TransactionSignature> {
283-
const unsafeRes = await this._rpcRequest('requestAirdrop', [to, amount]);
283+
const unsafeRes = await this._rpcRequest('requestAirdrop', [to.toBase58(), amount]);
284284
const res = RequestAirdropRpcResult(unsafeRes);
285285
if (res.error) {
286286
throw new Error(res.error.message);

src/index.js

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
// @flow
22
export {Account} from './account';
3+
export {BudgetProgram} from './budget-program';
34
export {Connection} from './connection';
4-
export {Transaction} from './transaction';
5+
export {PublicKey} from './publickey';
56
export {SystemProgram} from './system-program';
6-
export {BudgetProgram} from './budget-program';
7+
export {Transaction} from './transaction';

src/publickey.js

Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
// @flow
2+
3+
import BN from 'bn.js';
4+
import bs58 from 'bs58';
5+
6+
/**
7+
* A public key
8+
*/
9+
export class PublicKey {
10+
_bn: BN;
11+
12+
/**
13+
* Create a new PublicKey object
14+
*/
15+
constructor(number: string | Buffer | Array<number>) {
16+
let radix = 10;
17+
18+
if (typeof number === 'string' && number.startsWith('0x')) {
19+
this._bn = new BN(number.substring(2), 16);
20+
} else {
21+
this._bn = new BN(number, radix);
22+
}
23+
if (this._bn.byteLength() > 32) {
24+
throw new Error(`Invalid public key input`);
25+
}
26+
}
27+
28+
/**
29+
* Checks if the provided object is a PublicKey
30+
*/
31+
static isPublicKey(o: Object): boolean {
32+
return o instanceof PublicKey;
33+
}
34+
35+
/**
36+
* Checks if two publicKeys are equal
37+
*/
38+
equals(publicKey: PublicKey): boolean {
39+
return this._bn.eq(publicKey._bn);
40+
}
41+
42+
/**
43+
* Return the base-58 representation of the public key
44+
*/
45+
toBase58(): string {
46+
return bs58.encode(this.toBuffer());
47+
}
48+
49+
/**
50+
* Return the base-58 representation of the public key
51+
*/
52+
toBuffer(): Buffer {
53+
const b = this._bn.toBuffer();
54+
if (b.length === 32) {
55+
return b;
56+
}
57+
58+
const zeroPad = new Buffer(32);
59+
b.copy(zeroPad, 32 - b.length);
60+
return zeroPad;
61+
}
62+
63+
/**
64+
* Returns a string representation of the public key
65+
*/
66+
toString(): string {
67+
return this.toBase58();
68+
}
69+
}
70+

0 commit comments

Comments
 (0)