From 73399e9a502b780191d4fdbadf146b5cb5b2dde5 Mon Sep 17 00:00:00 2001 From: Kik Engineering Date: Tue, 10 Nov 2020 18:06:06 -0500 Subject: [PATCH] webhook: properly parse solana transaction GitOrigin-RevId: 219174f1085e072a6a8a4fcaefd1fe745c56d256 --- src/webhook/index.ts | 38 +++++++++++++++++++++--------------- test/webhook/webhook.spec.ts | 20 +++++++++---------- 2 files changed, 32 insertions(+), 26 deletions(-) diff --git a/src/webhook/index.ts b/src/webhook/index.ts index da0f67b..d543e41 100644 --- a/src/webhook/index.ts +++ b/src/webhook/index.ts @@ -38,7 +38,7 @@ export interface Event { solana_event?: { transaction: string, tx_error?: string, - tx_error_raw?: string + tx_error_raw?: string } } } @@ -74,17 +74,17 @@ export function EventsHandler(callback: (events: Event[]) => void, secret?: stri } export class SignTransactionRequest { - userId?: string; - userPassKey?: string; - payments: ReadOnlyPayment[]; - envelope?: xdr.TransactionEnvelope; - transaction?: SolanaTransaction; + userId?: string; + userPassKey?: string; + payments: ReadOnlyPayment[]; + envelope?: xdr.TransactionEnvelope; + solanaTransaction?: SolanaTransaction; networkPassphrase?: string; kinVersion: number; constructor( - payments: ReadOnlyPayment[], kinVersion: number, networkPassphrase?: string, envelope?: xdr.TransactionEnvelope, + payments: ReadOnlyPayment[], kinVersion: number, networkPassphrase?: string, envelope?: xdr.TransactionEnvelope, transaction?: SolanaTransaction, userId?: string, userPassKey?: string ) { this.userId = userId; @@ -92,7 +92,7 @@ export class SignTransactionRequest { this.payments = payments; this.envelope = envelope; - this.transaction = transaction; + this.solanaTransaction = transaction; this.networkPassphrase = networkPassphrase; this.kinVersion = kinVersion; @@ -100,17 +100,23 @@ export class SignTransactionRequest { /** * @deprecated - Use `txId()` instead. + * + * + * Returns the transaction hash of a stellar transaction, + * or the signature of a solana transaction. */ txHash(): Buffer { - if (!this.envelope || !this.networkPassphrase) { + const id = this.txId(); + if (!id) { throw new Error("this transaction has no hash"); } - return TransactionBuilder.fromXDR(this.envelope!, this.networkPassphrase!).hash(); + + return id!; } txId(): Buffer | undefined { - if (this.transaction) { - return this.transaction.signature; + if (this.solanaTransaction) { + return this.solanaTransaction.signature; } if (this.envelope) { return TransactionBuilder.fromXDR(this.envelope!, this.networkPassphrase!).hash(); @@ -215,7 +221,7 @@ export function SignTransactionHandler(env: Environment, callback: (req: SignTra try { interface requestBody { envelope_xdr: string - transaction: string + solana_transaction: string invoice_list: string kin_version: number } @@ -239,12 +245,12 @@ export function SignTransactionHandler(env: Environment, callback: (req: SignTra const kinVersion = (reqBody.kin_version ? reqBody.kin_version : 3); if (kinVersion === 4) { - if (!reqBody.transaction || typeof reqBody.transaction != "string") { + if (!reqBody.solana_transaction || typeof reqBody.solana_transaction != "string") { resp.sendStatus(400); return; } - - const txBytes = Buffer.from(reqBody.transaction, "base64"); + + const txBytes = Buffer.from(reqBody.solana_transaction, "base64"); const tx = SolanaTransaction.from(txBytes); const payments = paymentsFromTransaction(tx, invoiceList); signRequest = new SignTransactionRequest(payments, 4, undefined, undefined, tx, userId, userPassKey); diff --git a/test/webhook/webhook.spec.ts b/test/webhook/webhook.spec.ts index 42e868a..8f502ce 100644 --- a/test/webhook/webhook.spec.ts +++ b/test/webhook/webhook.spec.ts @@ -174,7 +174,7 @@ test("eventsHandler", async () => { expect(received[1].transaction_event.tx_id).toEqual(received[1].transaction_event.tx_hash); delete received[0].transaction_event.tx_id; delete received[1].transaction_event.tx_id; - + expect(received).toStrictEqual(sent); }); @@ -287,12 +287,12 @@ test("signtransactionHandler Kin 4", async () => { interface signResponse { envelope_xdr: string } - + const sender = PrivateKey.random().publicKey(); const destination = PrivateKey.random().publicKey(); const recentBlockhash = PrivateKey.random().publicKey(); const tokenProgram = PrivateKey.random().publicKey(); - + let actualUserId: string | undefined; let actualUserPasskey: string | undefined; @@ -302,7 +302,7 @@ test("signtransactionHandler Kin 4", async () => { actualUserPasskey = req.userPassKey; }, WEBHOOK_SECRET)); - const transaction = new SolanaTransaction({ + const transaction = new SolanaTransaction({ feePayer: sender.solanaKey(), recentBlockhash: recentBlockhash.toBase58(), }).add( @@ -315,7 +315,7 @@ test("signtransactionHandler Kin 4", async () => { )); const req = { - transaction: transaction.serialize({ + solana_transaction: transaction.serialize({ verifySignatures: false, requireAllSignatures: false, }).toString("base64"), @@ -356,7 +356,7 @@ test("signTransactionHandler rejection Kin 4", async () => { resp.markAlreadyPaid(2); })); - const transaction = new SolanaTransaction({ + const transaction = new SolanaTransaction({ feePayer: sender.solanaKey(), recentBlockhash: recentBlockhash.toBase58(), }); @@ -373,7 +373,7 @@ test("signTransactionHandler rejection Kin 4", async () => { } const req = { - transaction: transaction.serialize({ + solana_transaction: transaction.serialize({ verifySignatures: false, requireAllSignatures: false, }).toString("base64"), @@ -409,8 +409,8 @@ test("signTransactionRequest getTxId", async () => { const destination = PrivateKey.random().publicKey(); const recentBlockhash = PrivateKey.random().publicKey(); const tokenProgram = PrivateKey.random().publicKey(); - - const transaction = new SolanaTransaction({ + + const transaction = new SolanaTransaction({ feePayer: sender.solanaKey(), recentBlockhash: recentBlockhash.toBase58(), }).add( @@ -434,4 +434,4 @@ test("signTransactionRequest getTxId", async () => { req = new SignTransactionRequest([], 3, NetworkPasshrase.Test, envelope); expect(req.txId()).toEqual(builder.hash()); -}); \ No newline at end of file +});