Press n or j to go to the next uncovered block, b, p or k for the previous block.
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 | 12x 522x 522x 505x 505x 505x 505x 2x 503x 503x 503x 503x 503x 503x 17x 10x 7x 520x 520x 19x 19x 520x 365x 155x 520x 520x 520x 520x 520x 12x 94x 94x 94x 94x 94x 94x 94x 93x 93x 93x 31x 31x 62x 93x 75x 75x 93x 93x 2x 94x 12x 425x 425x 425x 425x 425x 425x 425x 424x 424x 169x 169x 424x 358x 67x 425x 12x 519x 519x 31x 519x 519x 519x 519x 519x 519x 519x | /*
* Flow JS Testing
*
* Copyright 2020-2021 Dapper Labs, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import * as fcl from "@onflow/fcl"
import {resolveArguments} from "@onflow/flow-cadut"
import {authorization} from "./crypto"
import emulator from "./emulator/emulator"
import {getTransactionCode, getScriptCode, defaultsByName} from "./file"
import {resolveImports, replaceImportAddresses} from "./imports"
import {getServiceAddress} from "./utils"
import {applyTransformers, builtInMethods} from "./transformers"
import {isObject} from "./utils"
export const extractParameters = ixType => {
return async params => {
let ixCode, ixName, ixSigners, ixArgs, ixService, ixTransformers, ixLimit
if (isObject(params[0])) {
const [props] = params
const {
name,
code,
args,
signers,
transformers,
limit,
service = false,
} = props
ixService = service
if (!name && !code) {
throw Error(
"Both `name` and `code` are missing. Provide either of them"
)
}
ixName = name
ixCode = code
ixSigners = signers
ixArgs = args
ixTransformers = transformers || []
ixLimit = limit
} else {
if (ixType === "script") {
;[ixName, ixArgs, ixLimit, ixTransformers = []] = params
} else {
;[ixName, ixSigners, ixArgs, ixLimit, ixTransformers = []] = params
}
}
// Check that limit is always set
ixLimit = ixLimit || (await fcl.config().get("fcl.limit"))
if (ixName) {
const getIxTemplate =
ixType === "script" ? getScriptCode : getTransactionCode
ixCode = await getIxTemplate({name: ixName})
}
// We need a way around to allow initial scripts and transactions for Manager contract
let deployedContracts
if (ixService) {
deployedContracts = defaultsByName
} else {
deployedContracts = await resolveImports(ixCode)
}
// Resolve default import addresses
const serviceAddress = await getServiceAddress()
const addressMap = {
...defaultsByName,
...deployedContracts,
FlowManager: serviceAddress,
}
// Replace code import addresses
ixCode = replaceImportAddresses(ixCode, addressMap)
// Apply all the necessary transformations to the code
ixCode = await applyTransformers(ixCode, [
...ixTransformers,
builtInMethods,
])
return {
code: ixCode,
signers: ixSigners,
args: ixArgs,
limit: ixLimit,
}
}
}
/**
* Submits transaction to emulator network and waits before it will be sealed.
* Returns transaction result.
* @param {Object} props
* @param {string} [props.name] - Name of Cadence template file
* @param {{string:string}} [props.addressMap={}] - name/address map to use as lookup table for addresses in import statements.
* @param {string} [props.code] - Cadence code of the transaction.
* @param {[any]} [props.args] - array of arguments specified as tupple, where last value is the type of preceding values.
* @param {[string]} [props.signers] - list of signers, who will authorize transaction, specified as array of addresses.
* @returns {Promise<any>}
*/
export const sendTransaction = async (...props) => {
// This is here to fix an issue with microbundler confusing argument scopes
let _props = props
let result = null,
err = null
const logs = await captureLogs(async () => {
try {
const extractor = extractParameters("tx")
const {code, args, signers, limit} = await extractor(_props)
const serviceAuth = authorization()
// set repeating transaction code
const ix = [
fcl.transaction(code),
fcl.payer(serviceAuth),
fcl.proposer(serviceAuth),
fcl.limit(limit),
]
// use signers if specified
if (signers) {
const auths = signers.map(signer => authorization(signer))
ix.push(fcl.authorizations(auths))
} else {
// and only service account if no signers
ix.push(fcl.authorizations([serviceAuth]))
}
// add arguments if any
if (args) {
const resolvedArgs = await resolveArguments(args, code)
ix.push(fcl.args(resolvedArgs))
}
const response = await fcl.send(ix)
result = await fcl.tx(response).onceExecuted()
} catch (e) {
err = e
}
})
return [result, err, logs]
}
/**
* Sends script code for execution. Returns decoded value
* @param {Object} props
* @param {string} props.code - Cadence code of the script to be submitted.
* @param {string} props.name - name of the file to source code from.
* @param {[any]} props.args - array of arguments specified as tuple, where last value is the type of preceding values.
* @returns {Promise<*>}
*/
export const executeScript = async (...props) => {
// This is here to fix an issue with microbundler confusing argument scopes
let _props = props
let result = null,
err = null
const logs = await captureLogs(async () => {
try {
const extractor = extractParameters("script")
const {code, args, limit} = await extractor(_props)
const ix = [fcl.script(code), fcl.limit(limit)]
// add arguments if any
if (args) {
const resolvedArgs = await resolveArguments(args, code)
ix.push(fcl.args(resolvedArgs))
}
const response = await fcl.send(ix)
result = await fcl.decode(response)
} catch (e) {
err = e
}
})
return [result, err, logs]
}
export const captureLogs = async callback => {
const logs = []
const listener = msg => {
logs.push(msg)
}
emulator.logger.on("log", listener)
await callback()
await new Promise(resolve => {
setTimeout(() => {
resolve()
}, 50)
})
emulator.logger.removeListener("log", listener)
return logs
}
|