-
Notifications
You must be signed in to change notification settings - Fork 799
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
[experimental] Decide what to do about single sending signer enforcement #2818
Comments
signAndSendTransactionMessageWithSigners
signAndSendTransactionMessageWithSigners
signAndSendTransactionMessageWithSigners
I bet this is because the |
I'm not sure why TypeScript decides to throw this error but the root cause is actually different and valid. In order to use the I've added a typetest in PR #2835 to illustrate that. |
Oof. That will catch everyone who uses this new wallet adapter API. Do you think there's any way to change the types of |
I guess at minimum this would involve making |
signAndSendTransactionMessageWithSigners
ITransactionMessageWithSingleSendingSigner
on the basis of a single signer having been used in its construction?
I don't think that adding/removing a TS flag will be doable since you can technically have multiple sending signers as long as they are all the signer. For instance that sending signer could be used as the transaction payer and also as the authority on some instruction, yet it's still the same signer. I think the easiest path to success here is to move the assertion call inside the sign and send helper. TS won't complain but JS will and I think that's good enough in this case since using multiple sending signers is more of an edge case than a common gotcha. Wdyt? |
Yeah totally. I meant the overloads would be like: // Overrides
function foo(thing: ThingWithSendingSigner<TAddressOfSendingSigner>, tx: SingleSendingSignerTx<TAddressOfSendingSigner>): SingleSendingSignerTx<TAddressOfSendingSigner>;
function foo(thing: ThingWithSendingSigner<TOtherAddress>, tx: SingleSendingSignerTx<TAddressOfSendingSigner>): NoLongerASingleSendingSignerTx;
function foo(thing: ThingWithSendingSigner<TAddressOfSendingSigner>, tx: TransactionWithNoSendingSigner): SingleSendingSignerTx<TAddressOfSendingSigner>;
function foo(thing: Thing, tx: Transaction) {
// Implementation
} Anyway, the types for that would be off the rails. |
Yeah, but then we'd have to delete all of the |
I wonder if it would be possible at all to create a utility type that walked the transaction that returned Maybe then we could use that to constrain the argument type on In other words, instead of creating a type that represents a transaction with a single sending signer because we said so, create a utility type that determines that a value has exactly one sending signer. Again though, this is probably hair-brained and impossible to actually achieve reliably in practice. I'm leaning toward your suggestion. |
ITransactionMessageWithSingleSendingSigner
on the basis of a single signer having been used in its construction?
It would be ideal but the main issue here is that people will get signers with non-static addresses from packages like the wallet adapter — i.e. I'm also worried about how TS is going to fail using a complex recursive type considering it's not even able to properly fail using a simple flag type. Now IMO we have two viable solutions going forward:
Personally, I'm leaning towards option B as it will make the end-user API simpler to use without much of a tradeoff. Lmk what you think and I can open a PR for it. |
Yeah, I'm with you on option B. This one is just too hard to TypeScript, for now. |
…nd function (#2852) Fixes #2818 This PR calls the `assertIsTransactionMessageWithSingleSendingSigner` inside the `signAndSendTransactionMessageWithSigners` so the end-user doesn't need to do it explicitly. This is partly to improve the developer experience and partly because TS doesn't fail properly when the transaction message hasn't been asserted on prior to calling the sign and send function. Note that I did not remove the `assertIsTransactionMessageWithSingleSendingSigner` and the `isTransactionMessageWithSingleSendingSigner` from the package's exports since they may still be useful for custom use-cases such as the one described in the documentation: ```ts let transactionSignature: SignatureBytes; if (isTransactionMessageWithSingleSendingSigner(transaction)) { transactionSignature = await signAndSendTransactionMessageWithSigners(transaction); } else { const signedTransaction = await signTransactionMessageWithSigners(transaction); const encodedTransaction = getBase64EncodedWireTransaction(signedTransaction); transactionSignature = await rpc.sendTransaction(encodedTransaction).send(); } ```
Because there has been no activity on this issue for 7 days since it was closed, it has been automatically locked. Please open a new issue if it requires a follow up. |
This valid, compilable message is not acceptable to
signAndSendTransactionMessageWithSigners
.https://codesandbox.io/p/sandbox/signandsendtransactionmessagewithsigners-input-type-problem-szwfmy?file=%2Fsrc%2Findex.ts%3A39%2C9-39%2C49
The full error:
Discussion
Right now we have an
ITransactionMessageWithSingleSendingSigner
type. The input ofsignAndSendTransactionMessageWithSigners()
takes this as input. It's designed to ensure that every message passed to it has exactly one sending signer, because by definition that's all a message can handle.Because our upstream utilities don't do anything to produce this type, it's always incumbent on the dev to assert this fact:
If you forget that assertion, the TypeScript error that results is unintelligible and even less actionable. If you haven't read the docs, you're hosed.
Options
ITransactionMessageWithSingleSendingSigner
and all associated utilities. Do runtime enforcement of a message having exactly one sending signer in the send functionITransactionMessageWithSingleSendingSigner
type. Otherwise, add it with the introduction of a new sending-signer (discussion link).The text was updated successfully, but these errors were encountered: