| 
									
										
										
										
											2018-11-28 10:06:17 -08:00
										 |  |  | // @flow
 | 
					
						
							| 
									
										
										
										
											2020-01-13 16:17:32 -07:00
										 |  |  | import bs58 from 'bs58'; | 
					
						
							| 
									
										
										
										
											2019-04-10 12:31:50 -07:00
										 |  |  | import nacl from 'tweetnacl'; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-11-28 10:06:17 -08:00
										 |  |  | import {Account} from '../src/account'; | 
					
						
							| 
									
										
										
										
											2019-01-31 02:16:07 -07:00
										 |  |  | import {PublicKey} from '../src/publickey'; | 
					
						
							| 
									
										
										
										
											2018-11-28 10:06:17 -08:00
										 |  |  | import {Transaction} from '../src/transaction'; | 
					
						
							| 
									
										
										
										
											2020-01-06 18:12:04 -07:00
										 |  |  | import {StakeProgram} from '../src/stake-program'; | 
					
						
							| 
									
										
										
										
											2018-11-28 10:06:17 -08:00
										 |  |  | import {SystemProgram} from '../src/system-program'; | 
					
						
							| 
									
										
										
										
											2020-06-11 13:15:14 +08:00
										 |  |  | import {Message} from '../src/message'; | 
					
						
							| 
									
										
										
										
											2018-11-28 10:06:17 -08:00
										 |  |  | 
 | 
					
						
							|  |  |  | test('signPartial', () => { | 
					
						
							|  |  |  |   const account1 = new Account(); | 
					
						
							|  |  |  |   const account2 = new Account(); | 
					
						
							| 
									
										
										
										
											2019-03-04 08:06:33 -08:00
										 |  |  |   const recentBlockhash = account1.publicKey.toBase58(); // Fake recentBlockhash
 | 
					
						
							| 
									
										
										
										
											2020-03-03 16:05:50 +08:00
										 |  |  |   const transfer = SystemProgram.transfer({ | 
					
						
							|  |  |  |     fromPubkey: account1.publicKey, | 
					
						
							|  |  |  |     toPubkey: account2.publicKey, | 
					
						
							|  |  |  |     lamports: 123, | 
					
						
							|  |  |  |   }); | 
					
						
							| 
									
										
										
										
											2018-11-28 10:06:17 -08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-11 18:20:22 -07:00
										 |  |  |   const transaction = new Transaction({recentBlockhash}).add(transfer); | 
					
						
							| 
									
										
										
										
											2018-11-28 10:06:17 -08:00
										 |  |  |   transaction.sign(account1, account2); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-11 18:20:22 -07:00
										 |  |  |   const partialTransaction = new Transaction({recentBlockhash}).add(transfer); | 
					
						
							| 
									
										
										
										
											2018-11-28 10:06:17 -08:00
										 |  |  |   partialTransaction.signPartial(account1, account2.publicKey); | 
					
						
							|  |  |  |   expect(partialTransaction.signatures[1].signature).toBeNull(); | 
					
						
							|  |  |  |   partialTransaction.addSigner(account2); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   expect(partialTransaction).toEqual(transaction); | 
					
						
							|  |  |  | }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | test('transfer signatures', () => { | 
					
						
							|  |  |  |   const account1 = new Account(); | 
					
						
							|  |  |  |   const account2 = new Account(); | 
					
						
							| 
									
										
										
										
											2019-03-04 08:06:33 -08:00
										 |  |  |   const recentBlockhash = account1.publicKey.toBase58(); // Fake recentBlockhash
 | 
					
						
							| 
									
										
										
										
											2020-03-03 16:05:50 +08:00
										 |  |  |   const transfer1 = SystemProgram.transfer({ | 
					
						
							|  |  |  |     fromPubkey: account1.publicKey, | 
					
						
							|  |  |  |     toPubkey: account2.publicKey, | 
					
						
							|  |  |  |     lamports: 123, | 
					
						
							|  |  |  |   }); | 
					
						
							|  |  |  |   const transfer2 = SystemProgram.transfer({ | 
					
						
							|  |  |  |     fromPubkey: account2.publicKey, | 
					
						
							|  |  |  |     toPubkey: account1.publicKey, | 
					
						
							|  |  |  |     lamports: 123, | 
					
						
							|  |  |  |   }); | 
					
						
							| 
									
										
										
										
											2018-11-28 10:06:17 -08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-23 09:53:26 -07:00
										 |  |  |   const orgTransaction = new Transaction({recentBlockhash}).add( | 
					
						
							|  |  |  |     transfer1, | 
					
						
							|  |  |  |     transfer2, | 
					
						
							|  |  |  |   ); | 
					
						
							| 
									
										
										
										
											2018-11-28 10:06:17 -08:00
										 |  |  |   orgTransaction.sign(account1, account2); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   const newTransaction = new Transaction({ | 
					
						
							| 
									
										
										
										
											2019-03-04 08:06:33 -08:00
										 |  |  |     recentBlockhash: orgTransaction.recentBlockhash, | 
					
						
							| 
									
										
										
										
											2018-11-28 10:06:17 -08:00
										 |  |  |     signatures: orgTransaction.signatures, | 
					
						
							| 
									
										
										
										
											2019-04-11 18:20:22 -07:00
										 |  |  |   }).add(transfer1, transfer2); | 
					
						
							| 
									
										
										
										
											2018-11-28 10:06:17 -08:00
										 |  |  | 
 | 
					
						
							|  |  |  |   expect(newTransaction).toEqual(orgTransaction); | 
					
						
							|  |  |  | }); | 
					
						
							| 
									
										
										
										
											2019-01-31 02:16:07 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-05-08 11:00:05 -07:00
										 |  |  | test('dedup signatures', () => { | 
					
						
							|  |  |  |   const account1 = new Account(); | 
					
						
							|  |  |  |   const account2 = new Account(); | 
					
						
							|  |  |  |   const recentBlockhash = account1.publicKey.toBase58(); // Fake recentBlockhash
 | 
					
						
							| 
									
										
										
										
											2020-03-03 16:05:50 +08:00
										 |  |  |   const transfer1 = SystemProgram.transfer({ | 
					
						
							|  |  |  |     fromPubkey: account1.publicKey, | 
					
						
							|  |  |  |     toPubkey: account2.publicKey, | 
					
						
							|  |  |  |     lamports: 123, | 
					
						
							|  |  |  |   }); | 
					
						
							|  |  |  |   const transfer2 = SystemProgram.transfer({ | 
					
						
							|  |  |  |     fromPubkey: account1.publicKey, | 
					
						
							|  |  |  |     toPubkey: account2.publicKey, | 
					
						
							|  |  |  |     lamports: 123, | 
					
						
							|  |  |  |   }); | 
					
						
							| 
									
										
										
										
											2019-05-08 11:00:05 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  |   const orgTransaction = new Transaction({recentBlockhash}).add( | 
					
						
							|  |  |  |     transfer1, | 
					
						
							|  |  |  |     transfer2, | 
					
						
							|  |  |  |   ); | 
					
						
							|  |  |  |   orgTransaction.sign(account1); | 
					
						
							|  |  |  | }); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-01-06 18:12:04 -07:00
										 |  |  | test('use nonce', () => { | 
					
						
							|  |  |  |   const account1 = new Account(); | 
					
						
							|  |  |  |   const account2 = new Account(); | 
					
						
							|  |  |  |   const nonceAccount = new Account(); | 
					
						
							|  |  |  |   const nonce = account2.publicKey.toBase58(); // Fake Nonce hash
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   const nonceInfo = { | 
					
						
							|  |  |  |     nonce, | 
					
						
							| 
									
										
										
										
											2020-03-03 16:05:50 +08:00
										 |  |  |     nonceInstruction: SystemProgram.nonceAdvance({ | 
					
						
							|  |  |  |       noncePubkey: nonceAccount.publicKey, | 
					
						
							|  |  |  |       authorizedPubkey: account1.publicKey, | 
					
						
							|  |  |  |     }), | 
					
						
							| 
									
										
										
										
											2020-01-06 18:12:04 -07:00
										 |  |  |   }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   const transferTransaction = new Transaction({nonceInfo}).add( | 
					
						
							| 
									
										
										
										
											2020-03-03 16:05:50 +08:00
										 |  |  |     SystemProgram.transfer({ | 
					
						
							|  |  |  |       fromPubkey: account1.publicKey, | 
					
						
							|  |  |  |       toPubkey: account2.publicKey, | 
					
						
							|  |  |  |       lamports: 123, | 
					
						
							|  |  |  |     }), | 
					
						
							| 
									
										
										
										
											2020-01-06 18:12:04 -07:00
										 |  |  |   ); | 
					
						
							|  |  |  |   transferTransaction.sign(account1); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   let expectedData = Buffer.alloc(4); | 
					
						
							|  |  |  |   expectedData.writeInt32LE(4, 0); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   expect(transferTransaction.instructions).toHaveLength(2); | 
					
						
							|  |  |  |   expect(transferTransaction.instructions[0].programId).toEqual( | 
					
						
							|  |  |  |     SystemProgram.programId, | 
					
						
							|  |  |  |   ); | 
					
						
							|  |  |  |   expect(transferTransaction.instructions[0].data).toEqual(expectedData); | 
					
						
							|  |  |  |   expect(transferTransaction.recentBlockhash).toEqual(nonce); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   const stakeAccount = new Account(); | 
					
						
							|  |  |  |   const voteAccount = new Account(); | 
					
						
							|  |  |  |   const stakeTransaction = new Transaction({nonceInfo}).add( | 
					
						
							| 
									
										
										
										
											2020-03-02 23:58:10 +08:00
										 |  |  |     StakeProgram.delegate({ | 
					
						
							|  |  |  |       stakePubkey: stakeAccount.publicKey, | 
					
						
							|  |  |  |       authorizedPubkey: account1.publicKey, | 
					
						
							|  |  |  |       votePubkey: voteAccount.publicKey, | 
					
						
							|  |  |  |     }), | 
					
						
							| 
									
										
										
										
											2020-01-06 18:12:04 -07:00
										 |  |  |   ); | 
					
						
							|  |  |  |   stakeTransaction.sign(account1); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   expect(stakeTransaction.instructions).toHaveLength(2); | 
					
						
							|  |  |  |   expect(stakeTransaction.instructions[0].programId).toEqual( | 
					
						
							|  |  |  |     SystemProgram.programId, | 
					
						
							|  |  |  |   ); | 
					
						
							|  |  |  |   expect(stakeTransaction.instructions[0].data).toEqual(expectedData); | 
					
						
							|  |  |  |   expect(stakeTransaction.recentBlockhash).toEqual(nonce); | 
					
						
							|  |  |  | }); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-01-31 02:16:07 -07:00
										 |  |  | test('parse wire format and serialize', () => { | 
					
						
							| 
									
										
										
										
											2019-04-10 12:31:50 -07:00
										 |  |  |   const keypair = nacl.sign.keyPair.fromSeed( | 
					
						
							|  |  |  |     Uint8Array.from(Array(32).fill(8)), | 
					
						
							|  |  |  |   ); | 
					
						
							|  |  |  |   const sender = new Account(Buffer.from(keypair.secretKey)); // Arbitrary known account
 | 
					
						
							| 
									
										
										
										
											2019-03-04 08:06:33 -08:00
										 |  |  |   const recentBlockhash = 'EETubP5AKHgjPAhzPAFcb8BAY1hMH639CWCFTqi3hq1k'; // Arbitrary known recentBlockhash
 | 
					
						
							| 
									
										
										
										
											2019-01-31 02:16:07 -07:00
										 |  |  |   const recipient = new PublicKey( | 
					
						
							|  |  |  |     'J3dxNj7nDRRqRRXuEMynDG57DkZK4jYRuv3Garmb1i99', | 
					
						
							|  |  |  |   ); // Arbitrary known public key
 | 
					
						
							| 
									
										
										
										
											2020-03-03 16:05:50 +08:00
										 |  |  |   const transfer = SystemProgram.transfer({ | 
					
						
							|  |  |  |     fromPubkey: sender.publicKey, | 
					
						
							|  |  |  |     toPubkey: recipient, | 
					
						
							|  |  |  |     lamports: 49, | 
					
						
							|  |  |  |   }); | 
					
						
							| 
									
										
										
										
											2019-04-11 18:20:22 -07:00
										 |  |  |   const expectedTransaction = new Transaction({recentBlockhash}).add(transfer); | 
					
						
							| 
									
										
										
										
											2019-01-31 02:16:07 -07:00
										 |  |  |   expectedTransaction.sign(sender); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-11-05 19:07:38 -05:00
										 |  |  |   const wireTransaction = Buffer.from( | 
					
						
							|  |  |  |     'AVuErQHaXv0SG0/PchunfxHKt8wMRfMZzqV0tkC5qO6owYxWU2v871AoWywGoFQr4z+q/7mE8lIufNl/kxj+nQ0BAAEDE5j2LG0aRXxRumpLXz29L2n8qTIWIY3ImX5Ba9F9k8r9Q5/Mtmcn8onFxt47xKj+XdXXd3C8j/FcPu7csUrz/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAxJrndgN4IFTxep3s6kO0ROug7bEsbx0xxuDkqEvwUusBAgIAAQwCAAAAMQAAAAAAAAA=', | 
					
						
							|  |  |  |     'base64', | 
					
						
							|  |  |  |   ); | 
					
						
							| 
									
										
										
										
											2019-01-31 02:16:07 -07:00
										 |  |  |   const tx = Transaction.from(wireTransaction); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   expect(tx).toEqual(expectedTransaction); | 
					
						
							|  |  |  |   expect(wireTransaction).toEqual(expectedTransaction.serialize()); | 
					
						
							|  |  |  | }); | 
					
						
							| 
									
										
										
										
											2019-08-30 17:22:11 -06:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-06-11 13:15:14 +08:00
										 |  |  | test('populate transaction', () => { | 
					
						
							| 
									
										
										
										
											2020-05-07 23:01:19 +08:00
										 |  |  |   const recentBlockhash = new PublicKey(1).toString(); | 
					
						
							| 
									
										
										
										
											2020-06-11 13:15:14 +08:00
										 |  |  |   const message = { | 
					
						
							|  |  |  |     accountKeys: [ | 
					
						
							|  |  |  |       new PublicKey(1).toString(), | 
					
						
							|  |  |  |       new PublicKey(2).toString(), | 
					
						
							|  |  |  |       new PublicKey(3).toString(), | 
					
						
							|  |  |  |       new PublicKey(4).toString(), | 
					
						
							|  |  |  |       new PublicKey(5).toString(), | 
					
						
							|  |  |  |     ], | 
					
						
							|  |  |  |     header: { | 
					
						
							|  |  |  |       numReadonlySignedAccounts: 0, | 
					
						
							|  |  |  |       numReadonlyUnsignedAccounts: 3, | 
					
						
							|  |  |  |       numRequiredSignatures: 2, | 
					
						
							| 
									
										
										
										
											2019-11-16 13:16:30 -05:00
										 |  |  |     }, | 
					
						
							| 
									
										
										
										
											2020-06-11 13:15:14 +08:00
										 |  |  |     instructions: [ | 
					
						
							|  |  |  |       { | 
					
						
							|  |  |  |         accounts: [1, 2, 3], | 
					
						
							|  |  |  |         data: bs58.encode(Buffer.alloc(5).fill(9)), | 
					
						
							|  |  |  |         programIdIndex: 4, | 
					
						
							|  |  |  |       }, | 
					
						
							| 
									
										
										
										
											2020-01-13 16:17:32 -07:00
										 |  |  |     ], | 
					
						
							| 
									
										
										
										
											2020-06-11 13:15:14 +08:00
										 |  |  |     recentBlockhash, | 
					
						
							| 
									
										
										
										
											2019-11-16 13:16:30 -05:00
										 |  |  |   }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-06-11 13:15:14 +08:00
										 |  |  |   const signatures = [ | 
					
						
							|  |  |  |     bs58.encode(Buffer.alloc(64).fill(1)), | 
					
						
							|  |  |  |     bs58.encode(Buffer.alloc(64).fill(2)), | 
					
						
							|  |  |  |   ]; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   const transaction = Transaction.populate(new Message(message), signatures); | 
					
						
							| 
									
										
										
										
											2019-11-16 13:16:30 -05:00
										 |  |  |   expect(transaction.instructions.length).toEqual(1); | 
					
						
							|  |  |  |   expect(transaction.signatures.length).toEqual(2); | 
					
						
							|  |  |  |   expect(transaction.recentBlockhash).toEqual(recentBlockhash); | 
					
						
							|  |  |  | }); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-08-30 17:22:11 -06:00
										 |  |  | test('serialize unsigned transaction', () => { | 
					
						
							|  |  |  |   const keypair = nacl.sign.keyPair.fromSeed( | 
					
						
							|  |  |  |     Uint8Array.from(Array(32).fill(8)), | 
					
						
							|  |  |  |   ); | 
					
						
							|  |  |  |   const sender = new Account(Buffer.from(keypair.secretKey)); // Arbitrary known account
 | 
					
						
							|  |  |  |   const recentBlockhash = 'EETubP5AKHgjPAhzPAFcb8BAY1hMH639CWCFTqi3hq1k'; // Arbitrary known recentBlockhash
 | 
					
						
							|  |  |  |   const recipient = new PublicKey( | 
					
						
							|  |  |  |     'J3dxNj7nDRRqRRXuEMynDG57DkZK4jYRuv3Garmb1i99', | 
					
						
							|  |  |  |   ); // Arbitrary known public key
 | 
					
						
							| 
									
										
										
										
											2020-03-03 16:05:50 +08:00
										 |  |  |   const transfer = SystemProgram.transfer({ | 
					
						
							|  |  |  |     fromPubkey: sender.publicKey, | 
					
						
							|  |  |  |     toPubkey: recipient, | 
					
						
							|  |  |  |     lamports: 49, | 
					
						
							|  |  |  |   }); | 
					
						
							| 
									
										
										
										
											2019-08-30 17:22:11 -06:00
										 |  |  |   const expectedTransaction = new Transaction({recentBlockhash}).add(transfer); | 
					
						
							| 
									
										
										
										
											2020-02-13 08:25:22 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-07-07 16:56:50 -06:00
										 |  |  |   // Empty signature array fails.
 | 
					
						
							|  |  |  |   expect(expectedTransaction.signatures.length).toBe(0); | 
					
						
							|  |  |  |   expect(() => { | 
					
						
							|  |  |  |     expectedTransaction.serialize(); | 
					
						
							|  |  |  |   }).toThrow(Error); | 
					
						
							|  |  |  |   expect(expectedTransaction.signatures.length).toBe(0); | 
					
						
							|  |  |  |   // Signature array populated with null signatures fails.
 | 
					
						
							|  |  |  |   expectedTransaction.serializeMessage(); | 
					
						
							|  |  |  |   expect(expectedTransaction.signatures.length).toBe(1); | 
					
						
							|  |  |  |   expect(() => { | 
					
						
							|  |  |  |     expectedTransaction.serialize(); | 
					
						
							|  |  |  |   }).toThrow(Error); | 
					
						
							|  |  |  |   expect(expectedTransaction.signatures.length).toBe(1); | 
					
						
							|  |  |  |   // Properly signed transaction succeeds
 | 
					
						
							|  |  |  |   expectedTransaction.sign(sender); | 
					
						
							|  |  |  |   expect(expectedTransaction.signatures.length).toBe(1); | 
					
						
							|  |  |  |   const expectedSerialization = Buffer.from( | 
					
						
							|  |  |  |     'AVuErQHaXv0SG0/PchunfxHKt8wMRfMZzqV0tkC5qO6owYxWU2v871AoWywGoFQr4z+q/7mE8lIufNl/' + | 
					
						
							|  |  |  |       'kxj+nQ0BAAEDE5j2LG0aRXxRumpLXz29L2n8qTIWIY3ImX5Ba9F9k8r9Q5/Mtmcn8onFxt47xKj+XdXX' + | 
					
						
							|  |  |  |       'd3C8j/FcPu7csUrz/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAxJrndgN4IFTxep3s6kO0' + | 
					
						
							|  |  |  |       'ROug7bEsbx0xxuDkqEvwUusBAgIAAQwCAAAAMQAAAAAAAAA=', | 
					
						
							|  |  |  |     'base64', | 
					
						
							| 
									
										
										
										
											2020-02-14 22:33:11 +08:00
										 |  |  |   ); | 
					
						
							| 
									
										
										
										
											2020-07-07 16:56:50 -06:00
										 |  |  |   expect(expectedTransaction.serialize()).toStrictEqual(expectedSerialization); | 
					
						
							|  |  |  |   expect(expectedTransaction.signatures.length).toBe(1); | 
					
						
							| 
									
										
										
										
											2019-08-30 17:22:11 -06:00
										 |  |  | }); | 
					
						
							| 
									
										
										
										
											2020-04-23 15:48:22 -06:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-07-01 20:25:49 -06:00
										 |  |  | test('externally signed stake delegate', () => { | 
					
						
							| 
									
										
										
										
											2020-04-23 15:48:22 -06:00
										 |  |  |   const from_keypair = nacl.sign.keyPair.fromSeed( | 
					
						
							|  |  |  |     Uint8Array.from(Array(32).fill(1)), | 
					
						
							|  |  |  |   ); | 
					
						
							| 
									
										
										
										
											2020-07-01 20:25:49 -06:00
										 |  |  |   const authority = new Account(Buffer.from(from_keypair.secretKey)); | 
					
						
							|  |  |  |   const stake = new PublicKey(2); | 
					
						
							| 
									
										
										
										
											2020-04-23 15:48:22 -06:00
										 |  |  |   const recentBlockhash = new PublicKey(3).toBuffer(); | 
					
						
							| 
									
										
										
										
											2020-07-01 20:25:49 -06:00
										 |  |  |   const vote = new PublicKey(4); | 
					
						
							|  |  |  |   var tx = StakeProgram.delegate({ | 
					
						
							|  |  |  |     stakePubkey: stake, | 
					
						
							|  |  |  |     authorizedPubkey: authority.publicKey, | 
					
						
							|  |  |  |     votePubkey: vote, | 
					
						
							| 
									
										
										
										
											2020-04-23 15:48:22 -06:00
										 |  |  |   }); | 
					
						
							| 
									
										
										
										
											2020-07-01 20:25:49 -06:00
										 |  |  |   const from = authority; | 
					
						
							| 
									
										
										
										
											2020-04-23 15:48:22 -06:00
										 |  |  |   tx.recentBlockhash = bs58.encode(recentBlockhash); | 
					
						
							| 
									
										
										
										
											2020-04-24 10:20:27 -06:00
										 |  |  |   const tx_bytes = tx.serializeMessage(); | 
					
						
							| 
									
										
										
										
											2020-04-23 15:48:22 -06:00
										 |  |  |   const signature = nacl.sign.detached(tx_bytes, from.secretKey); | 
					
						
							|  |  |  |   tx.addSignature(from.publicKey, signature); | 
					
						
							|  |  |  |   expect(tx.verifySignatures()).toBe(true); | 
					
						
							|  |  |  | }); |