-
Notifications
You must be signed in to change notification settings - Fork 54
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
Add support for calling private view functions #390
base: main
Are you sure you want to change the base?
Conversation
…function ABI, and with exclusively BCS-encoded arguments, depending on its visibility
…d a unit test for view functions
Add a helper test function to clear the memoized cache so we can test public/private functions with the same module Type the JSON response from the view functions and assert they're correct
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.
I think this is a great first step in handling the abi/non-abi/remote-abi flow in the SDK. Just need to organize it a bit more and add some tests for the different view function use cases
@@ -189,7 +202,7 @@ export async function generateViewFunctionPayload(args: InputViewFunctionDataWit | |||
}); | |||
|
|||
// Fill in the ABI | |||
return generateViewFunctionPayloadWithABI({ abi: functionAbi, ...args }); | |||
return generateViewFunctionPayloadWithABI({ ...args, abi: functionAbi }); |
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.
any reason for this change?
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.
yeah oops I actually meant to note this in the PR, I'm not sure if it's intended or not, but basically if you pass in your own abi
it overwrites the fetched ABI because of the order of the spread on ...args
basically if you pass abi: undefined
it ignores the fetched ABI and tries to use undefined
It's kind of a small thing, since most often people won't pass abi: undefined
, but in my case I was doing that, I just figured if you're fetching it it should use the results
src/internal/view.ts
Outdated
const { abi } = payload; | ||
|
||
// If the ABI is provided, we can skip the fetch ABI request and generate the payload. | ||
if (typeof abi !== "undefined") { |
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.
can this logic live in the transactionBuilder.ts file instead of here?
* @param key The key to clear from the cache | ||
* @returns void | ||
*/ | ||
export function clearMemoizedCache(key: string): void { |
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.
❤️
src/internal/view.ts
Outdated
import { Serializer } from "../bcs"; | ||
import { postAptosFullNode } from "../client"; | ||
import { ViewFunctionNotFoundError, postAptosFullNode } from "../client"; |
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.
I think it is time for us to create tests/e2e/api/view.test.tsx
file, move this in there, and add bunch of tests with this abi non-abi functionality
src/internal/view.ts
Outdated
// If the ABI isn't provided | ||
} else { | ||
// We can skip both the fetch ABI request and the ABI check if all function arguments are BCS-serializable. | ||
const everyFunctionArgumentIsEncoded = payload.functionArguments?.every(isEncodedEntryFunctionArgument); |
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.
we can benefit from this logic for entry function also, I think the SDK currently fetches and parses the remote ABI even for submitting an entry function with encoded arguments - let's pull it into its own helper function
src/internal/view.ts
Outdated
} catch (e) { | ||
if (e instanceof ViewFunctionNotFoundError) { | ||
// Throw the same error with a more specific error message. | ||
const errorMsg = |
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.
does it override the messages being thrown from the transactionBuilder flow?
Move `isEveryFunctionArgumentEncoded` into a helper function
Description
Private view functions, e.g. a function like the following:
are callable off-chain the same way private entry functions are. However, they aren't included in the module's function ABIs. You can confirm this here with a simple curl request (included
jq
for easy viewing):You should see an empty
exposed_functions
array, but you can still call the function:Which returns with:
Note that the reason this wasn't an issue before is because view functions weren't BCS-serializable and thus did not use the
fetchABIs
callChanges
The SDK currently checks the ABIs regardless of what's passed in to
view
. This means that there's no way to call a private view function, even if you already have the ABIs or the serialized entry function arguments.In order to circumvent this, I've updated
view
insrc/internal/view.ts
to check if anabi
is passed in. If so, it circumvents the ABI lookup failure ingenerateViewFunctionPayload
by callinggenerateViewFunctionPayloadWithABI
directly.The most relevant changes are below:
I've also added type discriminators in
src/transactions/types.ts
to discourage incorrect combinations at compile time if the user decides to invoke any of thegenerateViewFunctionPayload_
functions directly.Test Plan
Now that view functions are BCS-serializable, I added unit tests in
transactionArguments.test.ts
to cover them, as well asMove
unit tests in the contract itself. I've also updated the module bytecode for the module used intransactionArguments.test.ts
:They cover all of the combinations of the ABI being provided/not provided and the arguments being simple, mixed, and serializable.
I also exposed a simple test-only
clearMemoizedCache
function to facilitate these unit tests, since memoization will cause errors with the previously-fetched ABIs