To transfer flow, it is a transaction like any other transaction.
If we are talking about the FLOW fungible token on testnet and we wanted to send Flow from one account to another account the cadence for the transaction would look like this.
import FungibleToken from 0x7e60df042a9c0868
transaction(amount: UFix64, to: Address) {
let vault: @FungibleToken.Vault
prepare(currentUser: AuthAccount) {
self.vault <- currentUser
.borrow<&{FungibleToken.Provider}>(from: /storage/flowTokenVault)!
.withdraw(amount: amount)
}
execute {
getAccount(to)
.getCapability(/public/flowTokenReceiver)!
.borrow<&{FungibleToken.Receiver}>()!
.deposit(from: <- self.vault)
}
}
Version 0.0.73
of FCL will make fcl.mutate
available (can access it now by using @onflow/fcl@0.0.73-alpha.3
). Mutate lets you submit the above cadence transaction code to the chain, defaulting authorization by the current user (if you are doing this from a node server where the “currentUser” is an account you control there is an additional step, which can be found here: flow-js-sdk/mutate.md at master · onflow/flow-js-sdk · GitHub).
We can submit the above cadence transaction code to Flow with:
import {mutate, tx} from "@onflow/fcl"
const CODE = `
import FungibleToken from 0x7e60df042a9c0868
transaction(amount: UFix64, to: Address) {
let vault: @FungibleToken.Vault
prepare(currentUser: AuthAccount) {
self.vault <- currentUser
.borrow<&{FungibleToken.Provider}>(from: /storage/flowTokenVault)!
.withdraw(amount: amount)
}
execute {
getAccount(to)
.getCapability(/public/flowTokenReceiver)!
.borrow<&{FungibleToken.Receiver}>()!
.deposit(from: <- self.vault)
}
}
`
// send 10.0 FLOW to my Flow Account
var txId = await mutate({
cadence: CODE,
args: (arg, t) => [
arg("10.0", t.UFix64), // amount
arg("0xba1132bc08f82fe2", t.Address) // to
],
limit: 55,
})
// know when the transaction was successful and permanent
var txStatus = await tx(txId).onceSealed()
The above code if you were to run it as is would send me 10.0 Flow from your Flow account.
In versions before 0.0.73
(and 0.0.73
can still do it this way too) it is a bit more verbose. Assuming CODE
is the same value.
import * as fcl from "@onflow/fcl"
var txId = await fcl.send([
fcl.transaction(CODE),
fcl.limit(55),
fcl.proposer(fcl.currentUser().authorization),
fcl.payer(fcl.currentUser().authorization),
fcl.authorizations([
fcl.currentUser().authorization,
]),
fcl.args([
fcl.arg("10.0", fcl.t.UFix64),
fcl.arg("0xba1132bc08f82fe2", fcl.t.Address)
])
]).then(fcl.decode)
var txStatus = await fcl.tx(txId).onceSealed()
When you are running these transactions from node, you are responsible for the authorization function as you wont have access to fcl.currentUser().authorization
, you can learn about custom authorization functions here: flow-js-sdk/authorization-function.md at master · onflow/flow-js-sdk · GitHub
For the above example using fcl.send(...).then(fcl.decode)
everywhere you see fcl.currentUser().authorization
you would replace with your own authorization function.
For fcl.mutate
(the first example) you would pass it in as authz
.
import {mutate, tx} from "@onflow/fcl"
import {myCustomAuthzFn} from "./my-custom-authorization-function"
var txId = await mutate({
cadence: CODE,
args: (arg, t) => [
arg("10.0", t.UFix64),
arg("0xba1132bc08f82fe2", t.Address)
],
limit: 55,
authz: myCustomAuthzFn, // pass it in like this
})