| 
									
										
										
										
											2021-02-06 10:59:00 +08:00
										 |  |  | import bs58 from 'bs58'; | 
					
						
							|  |  |  | import BN from 'bn.js'; | 
					
						
							|  |  |  | import * as mockttp from 'mockttp'; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-02-08 00:57:12 +08:00
										 |  |  | import {mockRpcMessage} from './rpc-websockets'; | 
					
						
							| 
									
										
										
										
											2021-05-07 16:59:51 +08:00
										 |  |  | import {Connection, PublicKey, Transaction, Signer} from '../../src'; | 
					
						
							| 
									
										
										
										
											2021-07-09 00:33:41 -05:00
										 |  |  | import invariant from '../../src/util/assert'; | 
					
						
							| 
									
										
										
										
											2021-04-26 08:35:07 -07:00
										 |  |  | import type {Commitment, HttpHeaders, RpcParams} from '../../src/connection'; | 
					
						
							| 
									
										
										
										
											2021-02-06 10:59:00 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-03-15 13:08:10 +08:00
										 |  |  | export const mockServer: mockttp.Mockttp | undefined = | 
					
						
							|  |  |  |   process.env.TEST_LIVE === undefined ? mockttp.getLocal() : undefined; | 
					
						
							| 
									
										
										
										
											2021-02-06 10:59:00 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | let uniqueCounter = 0; | 
					
						
							|  |  |  | export const uniqueSignature = () => { | 
					
						
							| 
									
										
										
										
											2021-03-15 13:08:10 +08:00
										 |  |  |   return bs58.encode(new BN(++uniqueCounter).toArray(undefined, 64)); | 
					
						
							| 
									
										
										
										
											2021-02-06 10:59:00 +08:00
										 |  |  | }; | 
					
						
							|  |  |  | export const uniqueBlockhash = () => { | 
					
						
							| 
									
										
										
										
											2021-03-15 13:08:10 +08:00
										 |  |  |   return bs58.encode(new BN(++uniqueCounter).toArray(undefined, 32)); | 
					
						
							| 
									
										
										
										
											2021-02-06 10:59:00 +08:00
										 |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | export const mockErrorMessage = 'Invalid'; | 
					
						
							|  |  |  | export const mockErrorResponse = { | 
					
						
							|  |  |  |   code: -32602, | 
					
						
							|  |  |  |   message: mockErrorMessage, | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-03-22 10:22:59 -07:00
										 |  |  | export const mockRpcBatchResponse = async ({ | 
					
						
							|  |  |  |   batch, | 
					
						
							|  |  |  |   result, | 
					
						
							|  |  |  |   error, | 
					
						
							|  |  |  | }: { | 
					
						
							|  |  |  |   batch: RpcParams[]; | 
					
						
							|  |  |  |   result: any[]; | 
					
						
							|  |  |  |   error?: string; | 
					
						
							|  |  |  | }) => { | 
					
						
							|  |  |  |   if (!mockServer) return; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   const request = batch.map((batch: RpcParams) => { | 
					
						
							|  |  |  |     return { | 
					
						
							|  |  |  |       jsonrpc: '2.0', | 
					
						
							|  |  |  |       method: batch.methodName, | 
					
						
							|  |  |  |       params: batch.args, | 
					
						
							|  |  |  |     }; | 
					
						
							|  |  |  |   }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   const response = result.map((result: any) => { | 
					
						
							|  |  |  |     return { | 
					
						
							|  |  |  |       jsonrpc: '2.0', | 
					
						
							|  |  |  |       id: '', | 
					
						
							|  |  |  |       result, | 
					
						
							|  |  |  |       error, | 
					
						
							|  |  |  |     }; | 
					
						
							|  |  |  |   }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   await mockServer | 
					
						
							|  |  |  |     .post('/') | 
					
						
							|  |  |  |     .withJsonBodyIncluding(request) | 
					
						
							|  |  |  |     .thenReply(200, JSON.stringify(response)); | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-02-06 10:59:00 +08:00
										 |  |  | export const mockRpcResponse = async ({ | 
					
						
							|  |  |  |   method, | 
					
						
							|  |  |  |   params, | 
					
						
							|  |  |  |   value, | 
					
						
							|  |  |  |   error, | 
					
						
							|  |  |  |   withContext, | 
					
						
							| 
									
										
										
										
											2021-04-26 08:35:07 -07:00
										 |  |  |   withHeaders, | 
					
						
							| 
									
										
										
										
											2021-02-06 10:59:00 +08:00
										 |  |  | }: { | 
					
						
							| 
									
										
										
										
											2021-03-15 13:08:10 +08:00
										 |  |  |   method: string; | 
					
						
							|  |  |  |   params: Array<any>; | 
					
						
							|  |  |  |   value?: any; | 
					
						
							|  |  |  |   error?: any; | 
					
						
							|  |  |  |   withContext?: boolean; | 
					
						
							| 
									
										
										
										
											2021-04-26 08:35:07 -07:00
										 |  |  |   withHeaders?: HttpHeaders; | 
					
						
							| 
									
										
										
										
											2021-02-06 10:59:00 +08:00
										 |  |  | }) => { | 
					
						
							| 
									
										
										
										
											2021-03-15 13:08:10 +08:00
										 |  |  |   if (!mockServer) return; | 
					
						
							| 
									
										
										
										
											2021-02-08 00:57:12 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  |   let result = value; | 
					
						
							|  |  |  |   if (withContext) { | 
					
						
							|  |  |  |     result = { | 
					
						
							|  |  |  |       context: { | 
					
						
							|  |  |  |         slot: 11, | 
					
						
							|  |  |  |       }, | 
					
						
							|  |  |  |       value, | 
					
						
							|  |  |  |     }; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-02-06 10:59:00 +08:00
										 |  |  |   await mockServer | 
					
						
							|  |  |  |     .post('/') | 
					
						
							|  |  |  |     .withJsonBodyIncluding({ | 
					
						
							|  |  |  |       jsonrpc: '2.0', | 
					
						
							|  |  |  |       method, | 
					
						
							|  |  |  |       params, | 
					
						
							|  |  |  |     }) | 
					
						
							| 
									
										
										
										
											2021-04-26 08:35:07 -07:00
										 |  |  |     .withHeaders(withHeaders || {}) | 
					
						
							| 
									
										
										
										
											2021-02-06 10:59:00 +08:00
										 |  |  |     .thenReply( | 
					
						
							|  |  |  |       200, | 
					
						
							|  |  |  |       JSON.stringify({ | 
					
						
							|  |  |  |         jsonrpc: '2.0', | 
					
						
							|  |  |  |         id: '', | 
					
						
							|  |  |  |         error, | 
					
						
							|  |  |  |         result, | 
					
						
							|  |  |  |       }), | 
					
						
							|  |  |  |     ); | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | const recentBlockhash = async ({ | 
					
						
							|  |  |  |   connection, | 
					
						
							|  |  |  |   commitment, | 
					
						
							|  |  |  | }: { | 
					
						
							| 
									
										
										
										
											2021-03-15 13:08:10 +08:00
										 |  |  |   connection: Connection; | 
					
						
							|  |  |  |   commitment?: Commitment; | 
					
						
							| 
									
										
										
										
											2021-02-06 10:59:00 +08:00
										 |  |  | }) => { | 
					
						
							|  |  |  |   const blockhash = uniqueBlockhash(); | 
					
						
							|  |  |  |   const params = []; | 
					
						
							|  |  |  |   if (commitment) { | 
					
						
							|  |  |  |     params.push({commitment}); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   await mockRpcResponse({ | 
					
						
							|  |  |  |     method: 'getRecentBlockhash', | 
					
						
							|  |  |  |     params, | 
					
						
							|  |  |  |     value: { | 
					
						
							|  |  |  |       blockhash, | 
					
						
							|  |  |  |       feeCalculator: { | 
					
						
							|  |  |  |         lamportsPerSignature: 42, | 
					
						
							|  |  |  |       }, | 
					
						
							|  |  |  |     }, | 
					
						
							|  |  |  |     withContext: true, | 
					
						
							|  |  |  |   }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   return await connection.getRecentBlockhash(commitment); | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | const processTransaction = async ({ | 
					
						
							|  |  |  |   connection, | 
					
						
							|  |  |  |   transaction, | 
					
						
							|  |  |  |   signers, | 
					
						
							|  |  |  |   commitment, | 
					
						
							|  |  |  |   err, | 
					
						
							|  |  |  | }: { | 
					
						
							| 
									
										
										
										
											2021-03-15 13:08:10 +08:00
										 |  |  |   connection: Connection; | 
					
						
							|  |  |  |   transaction: Transaction; | 
					
						
							| 
									
										
										
										
											2021-05-07 16:59:51 +08:00
										 |  |  |   signers: Array<Signer>; | 
					
						
							| 
									
										
										
										
											2021-03-15 13:08:10 +08:00
										 |  |  |   commitment: Commitment; | 
					
						
							|  |  |  |   err?: any; | 
					
						
							| 
									
										
										
										
											2021-02-06 10:59:00 +08:00
										 |  |  | }) => { | 
					
						
							|  |  |  |   const blockhash = (await recentBlockhash({connection})).blockhash; | 
					
						
							|  |  |  |   transaction.recentBlockhash = blockhash; | 
					
						
							|  |  |  |   transaction.sign(...signers); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   const encoded = transaction.serialize().toString('base64'); | 
					
						
							| 
									
										
										
										
											2021-07-09 00:33:41 -05:00
										 |  |  |   invariant(transaction.signature); | 
					
						
							| 
									
										
										
										
											2021-02-06 10:59:00 +08:00
										 |  |  |   const signature = bs58.encode(transaction.signature); | 
					
						
							|  |  |  |   await mockRpcResponse({ | 
					
						
							|  |  |  |     method: 'sendTransaction', | 
					
						
							|  |  |  |     params: [encoded], | 
					
						
							|  |  |  |     value: signature, | 
					
						
							|  |  |  |   }); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-02-08 00:57:12 +08:00
										 |  |  |   let sendOptions; | 
					
						
							|  |  |  |   if (err) { | 
					
						
							|  |  |  |     sendOptions = { | 
					
						
							|  |  |  |       skipPreflight: true, | 
					
						
							|  |  |  |     }; | 
					
						
							|  |  |  |   } else { | 
					
						
							|  |  |  |     sendOptions = { | 
					
						
							|  |  |  |       preflightCommitment: commitment, | 
					
						
							|  |  |  |     }; | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2021-02-06 10:59:00 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  |   await connection.sendEncodedTransaction(encoded, sendOptions); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   await mockRpcMessage({ | 
					
						
							|  |  |  |     method: 'signatureSubscribe', | 
					
						
							|  |  |  |     params: [signature, {commitment}], | 
					
						
							|  |  |  |     result: {err: err || null}, | 
					
						
							|  |  |  |   }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   return await connection.confirmTransaction(signature, commitment); | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | const airdrop = async ({ | 
					
						
							|  |  |  |   connection, | 
					
						
							|  |  |  |   address, | 
					
						
							|  |  |  |   amount, | 
					
						
							|  |  |  | }: { | 
					
						
							| 
									
										
										
										
											2021-03-15 13:08:10 +08:00
										 |  |  |   connection: Connection; | 
					
						
							|  |  |  |   address: PublicKey; | 
					
						
							|  |  |  |   amount: number; | 
					
						
							| 
									
										
										
										
											2021-02-06 10:59:00 +08:00
										 |  |  | }) => { | 
					
						
							|  |  |  |   await mockRpcResponse({ | 
					
						
							|  |  |  |     method: 'requestAirdrop', | 
					
						
							|  |  |  |     params: [address.toBase58(), amount], | 
					
						
							|  |  |  |     value: uniqueSignature(), | 
					
						
							|  |  |  |   }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   const signature = await connection.requestAirdrop(address, amount); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   await mockRpcMessage({ | 
					
						
							|  |  |  |     method: 'signatureSubscribe', | 
					
						
							| 
									
										
										
										
											2021-02-17 16:15:09 -08:00
										 |  |  |     params: [signature, {commitment: 'confirmed'}], | 
					
						
							| 
									
										
										
										
											2021-02-06 10:59:00 +08:00
										 |  |  |     result: {err: null}, | 
					
						
							|  |  |  |   }); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-02-17 16:15:09 -08:00
										 |  |  |   await connection.confirmTransaction(signature, 'confirmed'); | 
					
						
							| 
									
										
										
										
											2021-02-06 10:59:00 +08:00
										 |  |  |   return signature; | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | export const helpers = { | 
					
						
							|  |  |  |   airdrop, | 
					
						
							|  |  |  |   processTransaction, | 
					
						
							|  |  |  |   recentBlockhash, | 
					
						
							|  |  |  | }; |