Skip to content

Refactored fcl-core exec folder files to TypeScript #2473

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

Merged
merged 8 commits into from
Jun 11, 2025
Merged
Show file tree
Hide file tree
Changes from 7 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,31 +1,42 @@
import type {AccountAuthorization} from "@onflow/sdk"
import * as sdk from "@onflow/sdk"
import {normalizeArgs} from "./utils/normalize-args"
import {getCurrentUser} from "../current-user"
import {prepTemplateOpts} from "./utils/prep-template-opts.js"
import {preMutate} from "./utils/pre.js"
import {CurrentUserService, getCurrentUser} from "../current-user"
import {isNumber} from "../utils/is"
import type {ArgsFn} from "./args"
import {normalizeArgs} from "./utils/normalize-args"
import {preMutate} from "./utils/pre"
import {prepTemplateOpts} from "./utils/prep-template-opts"

export interface MutateOptions {
cadence?: string
args?: ArgsFn
template?: string
limit?: number
authz?: AccountAuthorization
proposer?: AccountAuthorization
payer?: AccountAuthorization
authorizations?: AccountAuthorization[]
}

/**
* @description
* Factory function that returns a mutate function for a given currentUser.
* @description Factory function that returns a mutate function for a given currentUser.
*
* @param {ReturnType<typeof import("../current-user").getCurrentUser> | import("../current-user").CurrentUserConfig} currentUserOrConfig - CurrentUser actor or configuration
* @param currentUserOrConfig CurrentUser actor or configuration
*/
export const getMutate = currentUserOrConfig => {
export const getMutate = (currentUserOrConfig: CurrentUserService) => {
/**
* @description
* Allows you to submit transactions to the blockchain to potentially mutate the state.
* @description Allows you to submit transactions to the blockchain to potentially mutate the state.
*
* @param {object} [opts] - Mutation Options and configuration
* @param {string} [opts.cadence] - Cadence Transaction used to mutate Flow
* @param {import("./args").ArgsFn} [opts.args] - Arguments passed to cadence transaction
* @param {object | string} [opts.template] - Interaction Template for a transaction
* @param {number} [opts.limit] - Compute Limit for transaction
* @param {Function} [opts.authz] - Authorization function for transaction
* @param {Function} [opts.proposer] - Proposer Authorization function for transaction
* @param {Function} [opts.payer] - Payer Authorization function for transaction
* @param {Array<Function>} [opts.authorizations] - Authorizations function for transaction
* @returns {Promise<string>} Transaction Id
* @param opts Mutation Options and configuration
* @param opts.cadence Cadence Transaction used to mutate Flow
* @param opts.args Arguments passed to cadence transaction
* @param opts.template Interaction Template for a transaction
* @param opts.limit Compute Limit for transaction
* @param opts.authz Authorization function for transaction
* @param opts.proposer Proposer Authorization function for transaction
* @param opts.payer Payer Authorization function for transaction
* @param opts.authorizations Authorizations function for transaction
* @returns Transaction Id
*
* @example
* fcl.mutate({
Expand Down Expand Up @@ -59,25 +70,25 @@ export const getMutate = currentUserOrConfig => {
* authorizations: [AuthzFn], // an array of authorization functions used as authorizations signatory roles
* }
*/
const mutate = async (opts = {}) => {
const mutate = async (opts: MutateOptions = {}): Promise<string> => {
var txid
try {
await preMutate(opts)
opts = await prepTemplateOpts(opts)
// Allow for a config to overwrite the authorization function.
// prettier-ignore
const currentUser = typeof currentUserOrConfig === "function" ? currentUserOrConfig : getCurrentUser(currentUserOrConfig)
const authz = await sdk
const authz: any = await sdk
.config()
.get("fcl.authz", currentUser().authorization)

txid = sdk
.send([
sdk.transaction(opts.cadence),
sdk.transaction(opts.cadence!),

sdk.args(normalizeArgs(opts.args || [])),

opts.limit && isNumber(opts.limit) && sdk.limit(opts.limit),
opts.limit && isNumber(opts.limit) && (sdk.limit(opts.limit!) as any),

// opts.proposer > opts.authz > authz
sdk.proposer(opts.proposer || opts.authz || authz),
Expand Down
48 changes: 0 additions & 48 deletions packages/fcl-core/src/exec/query.js

This file was deleted.

58 changes: 58 additions & 0 deletions packages/fcl-core/src/exec/query.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
import * as sdk from "@onflow/sdk"
import type {ArgsFn} from "./args"
import {normalizeArgs} from "./utils/normalize-args"
import {preQuery} from "./utils/pre"
import {prepTemplateOpts} from "./utils/prep-template-opts"

export interface QueryOptions {
cadence?: string
args?: ArgsFn | any[]
template?: string | any
isSealed?: boolean
limit?: number
[key: string]: any
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does the same thing apply here?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same, updated and improved!

}

/**
* @description Allows you to submit scripts to query the blockchain.
*
* @param opts Query Options and configuration
* @param opts.cadence Cadence Script used to query Flow
* @param opts.args Arguments passed to cadence script
* @param opts.template Interaction Template for a script
* @param opts.isSealed Block Finality
* @param opts.limit Compute Limit for Query
* @returns A promise that resolves to the query result
*
* @example
* const cadence = `
* cadence: `
* access(all) fun main(a: Int, b: Int, c: Address): Int {
* log(c)
* return a + b
* }
* `.trim()
*
* const args = (arg, t) => [
* arg(5, t.Int),
* arg(7, t.Int),
* arg("0xb2db43ad6bc345fec9", t.Address),
* ]
*
* await query({ cadence, args })
*/
export async function query(opts: QueryOptions = {}): Promise<any> {
await preQuery(opts)
opts = await prepTemplateOpts(opts)

return sdk
.send([
sdk.script(opts.cadence!),
sdk.args(normalizeArgs(opts.args || [])),
sdk.atLatestBlock(opts.isSealed ?? false),
opts.limit &&
typeof opts.limit === "number" &&
(sdk.limit(opts.limit!) as any),
])
.then(sdk.decode)
}
8 changes: 0 additions & 8 deletions packages/fcl-core/src/exec/utils/normalize-args.js

This file was deleted.

9 changes: 9 additions & 0 deletions packages/fcl-core/src/exec/utils/normalize-args.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import {isFunc} from "../../utils/is"
import * as sdk from "@onflow/sdk"
import * as t from "@onflow/types"
import type {ArgsFn} from "../args"

export function normalizeArgs(ax: ArgsFn | any[] | undefined): any[] {
if (isFunc(ax)) return (ax as ArgsFn)(sdk.arg, t)
return []
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,13 @@ import {invariant} from "@onflow/util-invariant"
import * as sdk from "@onflow/sdk"
import {isRequired, isObject, isString} from "../../utils/is"

async function pre(type, opts) {
export interface PreOptions {
cadence?: string
template?: any
[key: string]: any
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

does the same thing apply here? Or is this different

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same, updated and improved!

}

async function pre(type: string, opts: PreOptions): Promise<void> {
// prettier-ignore
invariant(isRequired(opts), `${type}(opts) -- opts is required`)
// prettier-ignore
Expand All @@ -23,10 +29,10 @@ async function pre(type, opts) {
)
}

export async function preMutate(opts) {
export async function preMutate(opts: PreOptions): Promise<void> {
return pre("mutate", opts)
}

export async function preQuery(opts) {
export async function preQuery(opts: PreOptions): Promise<void> {
return pre("query", opts)
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import {config} from "@onflow/config"
import {prepTemplateOpts} from "./prep-template-opts.js"
import {prepTemplateOpts} from "./prep-template-opts"

describe("Prepare template options for template version 1.0.0", () => {
// NOTE: template10 and template11 copied from packages\fcl-core\src\interaction-template-utils\derive-cadence-by-network\derive-cadence-by-network.test.js
Expand Down Expand Up @@ -175,7 +175,7 @@ describe("Prepare template options for template version 1.1.0", () => {

const test = async () =>
await prepTemplateOpts({
template: template,
template: template11,
})

await expect(test()).rejects.toThrow(Error)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,17 @@
import {retrieve} from "../../document/document"
import {deriveCadenceByNetwork} from "../../interaction-template-utils/derive-cadence-by-network/derive-cadence-by-network.js"
import {deriveCadenceByNetwork} from "../../interaction-template-utils/derive-cadence-by-network/derive-cadence-by-network"
import {isString} from "../../utils/is"
import {getChainId} from "../../utils"

export async function prepTemplateOpts(opts) {
export interface TemplateOptions {
template?: string | any
cadence?: string
[key: string]: any
}

export async function prepTemplateOpts(
opts: TemplateOptions
): Promise<TemplateOptions> {
if (isString(opts?.template)) {
opts.template = await retrieve({url: opts?.template})
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,16 +2,14 @@ import {log} from "@onflow/util-logger"
import {verifyUserSignatures as verify} from "../app-utils"

/**
* Verify a valid signature/s for an account on Flow.
*
* @description Verify a valid signature/s for an account on Flow.
* @deprecated since version '1.0.0-alpha.0', use AppUtils.verifyUserSignatures instead
*
*/
export const verifyUserSignatures = log.deprecate({
pkg: "FCL",
subject: "fcl.verifyUserSignatures()",
message: "Please use fcl.AppUtils.verifyUserSignatures()",
callback: function verifyUserSignatures(message, compSigs) {
callback: function verifyUserSignatures(message: any, compSigs: any) {
return verify(message, compSigs)
},
})
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import {config, invariant} from "@onflow/sdk"
import {log, LEVELS} from "@onflow/util-logger"
import {query} from "../exec/query.js"
import {query} from "../exec/query"
import {generateTemplateId} from "./generate-template-id/generate-template-id.js"
import {getChainId} from "../utils"

Expand Down
8 changes: 6 additions & 2 deletions packages/sdk/src/sdk.ts
Original file line number Diff line number Diff line change
Expand Up @@ -43,8 +43,12 @@ export {
} from "./interaction/interaction"
import type {CadenceArgument} from "./interaction/interaction"
export {CadenceArgument} // Workaround for babel https://github.com/babel/babel/issues/8361
import type {InteractionBuilderFn} from "./interaction/interaction"
export {InteractionBuilderFn}
import type {
InteractionBuilderFn,
AccountAuthorization,
AuthorizationFn,
} from "./interaction/interaction"
export {InteractionBuilderFn, AccountAuthorization, AuthorizationFn}

export {createSignableVoucher, voucherToTxId} from "./resolve/voucher"
export {encodeMessageFromSignable} from "./wallet-utils/encode-signable"
Expand Down