-
Notifications
You must be signed in to change notification settings - Fork 325
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
enhancement: Change signature of ClientOption.signTransaction to be able to pass KeyPair #1063 #1127
base: master
Are you sure you want to change the base?
enhancement: Change signature of ClientOption.signTransaction to be able to pass KeyPair #1063 #1127
Changes from all commits
0960840
a751ba6
810e8cf
a7abadd
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change | ||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|
|
@@ -5,6 +5,7 @@ import { | |||||||||||
Address, | ||||||||||||
BASE_FEE, | ||||||||||||
Contract, | ||||||||||||
Keypair, | ||||||||||||
Operation, | ||||||||||||
SorobanDataBuilder, | ||||||||||||
TransactionBuilder, | ||||||||||||
|
@@ -15,6 +16,7 @@ import type { | |||||||||||
AssembledTransactionOptions, | ||||||||||||
ClientOptions, | ||||||||||||
MethodOptions, | ||||||||||||
SignTransaction, | ||||||||||||
Tx, | ||||||||||||
WalletError, | ||||||||||||
XDR_BASE64, | ||||||||||||
|
@@ -32,6 +34,7 @@ import { | |||||||||||
import { DEFAULT_TIMEOUT } from "./types"; | ||||||||||||
import { SentTransaction } from "./sent_transaction"; | ||||||||||||
import { Spec } from "./spec"; | ||||||||||||
import { basicNodeSigner } from './basic_node_signer'; | ||||||||||||
|
||||||||||||
/** @module contract */ | ||||||||||||
|
||||||||||||
|
@@ -682,7 +685,17 @@ export class AssembledTransaction<T> { | |||||||||||
); | ||||||||||||
} | ||||||||||||
|
||||||||||||
if (!signTransaction) { | ||||||||||||
// Check if signTransaction is a Keypair | ||||||||||||
let signFunction: SignTransaction | undefined; | ||||||||||||
|
||||||||||||
if (signTransaction instanceof Keypair) { | ||||||||||||
const keypair = signTransaction; | ||||||||||||
signFunction = basicNodeSigner(keypair, this.options.networkPassphrase).signTransaction; | ||||||||||||
} else if (typeof signTransaction === 'function') { | ||||||||||||
signFunction = signTransaction; | ||||||||||||
} | ||||||||||||
|
||||||||||||
if (!signFunction) { | ||||||||||||
throw new AssembledTransaction.Errors.NoSigner( | ||||||||||||
"You must provide a signTransaction function, either when calling " + | ||||||||||||
"`signAndSend` or when initializing your Client" | ||||||||||||
|
@@ -708,15 +721,18 @@ export class AssembledTransaction<T> { | |||||||||||
.setTimeout(timeoutInSeconds) | ||||||||||||
.build(); | ||||||||||||
|
||||||||||||
const signOpts: Parameters<NonNullable<ClientOptions['signTransaction']>>[1] = { | ||||||||||||
// const signOpts: Parameters<NonNullable<ClientOptions['signTransaction']>>[1] = { | ||||||||||||
// networkPassphrase: this.options.networkPassphrase, | ||||||||||||
// }; | ||||||||||||
const signOpts: Parameters<SignTransaction>[1] = { | ||||||||||||
Comment on lines
+724
to
+727
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think there's a better way to do this whole thing than modifying the
Suggested change
it's fine to remove NonNullable here since it no longer is, but basically it needs to include EITHER signTransaction as a SignTransaction type or a keyPair as a KeyPair type... |
||||||||||||
networkPassphrase: this.options.networkPassphrase, | ||||||||||||
}; | ||||||||||||
|
||||||||||||
if (this.options.address) signOpts.address = this.options.address; | ||||||||||||
if (this.options.submit !== undefined) signOpts.submit = this.options.submit; | ||||||||||||
if (this.options.submitUrl) signOpts.submitUrl = this.options.submitUrl; | ||||||||||||
|
||||||||||||
const { signedTxXdr: signature, error } = await signTransaction( | ||||||||||||
const { signedTxXdr: signature, error } = await signFunction( | ||||||||||||
this.built.toXDR(), | ||||||||||||
signOpts, | ||||||||||||
); | ||||||||||||
|
Original file line number | Diff line number | Diff line change | ||||||||
---|---|---|---|---|---|---|---|---|---|---|
|
@@ -2,6 +2,7 @@ | |||||||||
/* eslint-disable @typescript-eslint/naming-convention */ | ||||||||||
import { Memo, MemoType, Operation, Transaction, xdr } from "@stellar/stellar-base"; | ||||||||||
import type { Client } from "./client"; | ||||||||||
import { Keypair } from "@stellar/stellar-base"; | ||||||||||
|
||||||||||
export type XDR_BASE64 = string; | ||||||||||
/** | ||||||||||
|
@@ -131,7 +132,7 @@ export type ClientOptions = { | |||||||||
* | ||||||||||
* Matches signature of `signTransaction` from Freighter. | ||||||||||
*/ | ||||||||||
signTransaction?: SignTransaction; | ||||||||||
signTransaction?: SignTransaction | Keypair; | ||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
please, let's avoid overloading sign = async ({
force = false,
signTransaction = this.options.signTransaction,
keypair = this.options.keypair,
}: {
force?: boolean;
signTransaction?: SignTransaction;
keypair?: Keypair;
} = {}): Promise<void> => {
if (!this.built) throw new Error("Transaction has not been simulated yet.");
if (!force && this.isReadCall) {
throw new AssembledTransaction.Errors.NoSignatureNeeded("Read call; no signature needed unless `force: true`.");
}
let fn = signTransaction;
if (keypair) {
fn = basicNodeSigner(keypair, this.options.networkPassphrase).signTransaction;
}
if (!fn) {
throw new AssembledTransaction.Errors.NoSigner("Provide either a `signTransaction` function or a `keypair`.");
}
// Prepare signing options
const signOpts: Parameters<SignTransaction>[1] = {
networkPassphrase: this.options.networkPassphrase,
address: this.options.address,
submit: this.options.submit,
submitUrl: this.options.submitUrl,
};
const { signedTxXdr, error } = await fn(this.built.toXDR(), signOpts);
this.handleWalletError(error);
this.signed = TransactionBuilder.fromXDR(signedTxXdr, this.options.networkPassphrase);
}; That’s it. You either provide a regular |
||||||||||
/** | ||||||||||
* A function to sign a specific auth entry for a transaction, using the | ||||||||||
* private key corresponding to the provided `publicKey`. This is only needed | ||||||||||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -31,6 +31,24 @@ describe("cross-contract auth", function () { | |
async () => await this.context.tx.sign({ force: true }), | ||
).to.not.throw(); | ||
}); | ||
|
||
it("signs transaction using Keypair", async function () { | ||
const result = await this.context.tx.sign({ | ||
signTransaction: this.context.keypair, | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. signTransaction should be the function not a keypair. |
||
force: true, | ||
}); | ||
expect(result).to.be.undefined; | ||
}); | ||
|
||
|
||
it("signs transaction using basicNodeSigner", async function () { | ||
const signer = contract.basicNodeSigner(this.context.keypair, "Standalone Network ; February 2017"); | ||
const result = await this.context.tx.sign({ | ||
signTransaction: signer.signTransaction, | ||
force: true, | ||
}); | ||
expect(result).to.be.undefined; | ||
}); | ||
}); | ||
|
||
describe("signAuthEntries with custom authorizeEntry", function () { | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This could be less verbose, and arguably safer...
signFunction
doesn't need to be a let it can be a constHowever you'll also need to remove lines 699-703 also.
Further, you shouldn't modify the type SignTransaction you should just add keypair to clientoptions as an optional and update the
sign
function here around line 664... you also need to look at thesignandsend
function for consistency and update that correctly.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
you might be wondering what !keyPair is yet later in this review i suggest modifying the sign function to accept either the function or the keypair, then narrow it. There's a bunch of ways to do this but there's no easy way for me to show exactly how i would do it without making a whole new pr which i am not gonna do. Anyways if you have questions about my review feel free to reach out. thanks.