diff --git a/packages/ERTP/src/amountMath.js b/packages/ERTP/src/amountMath.js index 9a900f0bf9d..d3e19063a3a 100644 --- a/packages/ERTP/src/amountMath.js +++ b/packages/ERTP/src/amountMath.js @@ -176,12 +176,13 @@ const checkLRAndGetHelpers = (leftAmount, rightAmount, brand = undefined) => { /** * @template {AssetKind} K - * @param {MathHelpers} h + * @param {MathHelpers>} h * @param {Amount} leftAmount * @param {Amount} rightAmount * @returns {[K, K]} */ const coerceLR = (h, leftAmount, rightAmount) => { + // @ts-expect-error could be arbitrary subtype return [h.doCoerce(leftAmount.value), h.doCoerce(rightAmount.value)]; }; @@ -243,9 +244,9 @@ const AmountMath = { * Return the amount representing an empty amount. This is the * identity element for MathHelpers.add and MatHelpers.subtract. * - * @template {AssetKind} K + * @template {AssetKind} [K='nat'] * @param {Brand} brand - * @param {K} [assetKind] + * @param {K} [assetKind='nat'] * @returns {Amount} */ // @ts-expect-error TS/jsdoc things 'nat' can't be assigned to K subclassing AssetKind @@ -254,6 +255,7 @@ const AmountMath = { assertRemotable(brand, 'brand'); assertAssetKind(assetKind); const value = helpers[assetKind].doMakeEmpty(); + // @ts-expect-error TS/jsdoc things 'nat' can't be assigned to K subclassing AssetKind return harden({ brand, value }); }, /** diff --git a/packages/ERTP/src/types-module.d.ts b/packages/ERTP/src/types-module.d.ts new file mode 100644 index 00000000000..97878d52ce7 --- /dev/null +++ b/packages/ERTP/src/types-module.d.ts @@ -0,0 +1,445 @@ +/** + * @file Generated from types.js, then find-replace to export all + * + * This file exists because types.js is ambient and some modules need the types + * to be explictly imported. Changing types.js to a module breaks too much. + */ +/* eslint-disable no-use-before-define */ +export type InterfaceSpec = import('@endo/marshal').InterfaceSpec; +export type GetInterfaceOf = import('@endo/marshal').MarshalGetInterfaceOf; +/** + * Amounts are descriptions of digital assets, answering the questions + * "how much" and "of what kind". Amounts are values labeled with a brand. + * AmountMath executes the logic of how amounts are changed when digital + * assets are merged, separated, or otherwise manipulated. For + * example, a deposit of 2 bucks into a purse that already has 3 bucks + * gives a new purse balance of 5 bucks. An empty purse has 0 bucks. AmountMath + * relies heavily on polymorphic MathHelpers, which manipulate the unbranded + * portion. + */ +export type Amount = { + brand: Brand; + value: AssetValueForKind; +}; +/** + * An `AmountValue` describes a set or quantity of assets that can be owned or + * shared. + * + * A fungible `AmountValue` uses a non-negative bigint to represent a quantity + * of that many assets. + * + * A non-fungible `AmountValue` uses an array or CopySet of `Key`s to represent + * a set of whatever asset each key represents. A `Key` is a passable value + * that can be used as an element in a set (SetStore or CopySet) or as the + * key in a map (MapStore or CopyMap). + * + * `SetValue` is for the deprecated set representation, using an array directly + * to represent the array of its elements. `CopySetValue` is the proper + * representation using a CopySet. + * + * A semi-fungible `CopyBagValue` is represented as a + * `CopyBag` of `Key` objects. "Bag" is synonymous with MultiSet, where an + * element of a bag can be present once or more times, i.e., some positive + * bigint number of times, representing that quantity of the asset represented + * by that key. + */ +export type AmountValue = NatValue | any[] | CopySetValue | CopyBagValue; +/** + * "Value" is a deprecated alias for "AmountValue". Please use + * "AmountValue" instead. + */ +export type Value = AmountValue; +/** + * See doc-comment for `AmountValue`. + */ +export type AssetKind = 'nat' | 'set' | 'copySet' | 'copyBag'; +export type AssetValueForKind = K extends 'nat' + ? NatValue + : K extends 'set' + ? any[] + : K extends 'copySet' + ? CopySetValue + : K extends 'copyBag' + ? CopyBagValue + : never; +export type AssetKindForValue = V extends NatValue + ? 'nat' + : V extends any[] + ? 'set' + : V extends CopySetValue + ? 'copySet' + : V extends CopyBagValue + ? 'copyBag' + : never; +export type DisplayInfo = { + /** + * Tells the display software how + * many decimal places to move the decimal over to the left, or in + * other words, which position corresponds to whole numbers. We + * require fungible digital assets to be represented in integers, in + * the smallest unit (i.e. USD might be represented in mill, a + * thousandth of a dollar. In that case, `decimalPlaces` would be + * 3.) This property is optional, and for non-fungible digital + * assets, should not be specified. The decimalPlaces property + * should be used for *display purposes only*. Any other use is an + * anti-pattern. + */ + decimalPlaces?: number | undefined; + /** + * - the kind of asset, either + * AssetKind.NAT (fungible) or + * AssetKind.SET or AssetKind.COPY_SET (non-fungible) + */ + assetKind: K; +}; +/** + * The brand identifies the kind of issuer, and has a function to get the + * alleged name for the kind of asset described. The alleged name (such + * as 'BTC' or 'moola') is provided by the maker of the issuer and should + * not be trusted as accurate. + * + * Every amount created by a particular AmountMath will share the same brand, + * but recipients cannot rely on the brand to verify that a purported amount + * represents the issuer they intended, since the same brand can be reused by + * a misbehaving issuer. + */ +export type Brand = { + /** + * Should be used with `issuer.getBrand` to ensure an issuer and brand match. + */ + isMyIssuer: (allegedIssuer: ERef) => Promise; + getAllegedName: () => string; + /** + * Give information to UI on how to display the amount. + */ + getDisplayInfo: () => DisplayInfo; + getAmountShape: () => Pattern; +}; +/** + * Return true if the payment continues to exist. + * + * If the payment is a promise, the operation will proceed upon + * resolution. + */ +export type IssuerIsLive = (payment: ERef) => Promise; +/** + * Get the amount of digital assets in the payment. Because the + * payment is not trusted, we cannot call a method on it directly, and + * must use the issuer instead. + * + * If the payment is a promise, the operation will proceed upon + * resolution. + */ +export type IssuerGetAmountOf = ( + payment: ERef, +) => Promise>; +/** + * Burn all of the digital assets in the + * payment. `optAmount` is optional. If `optAmount` is present, the + * code will insist that the amount of the digital assets in the + * payment is equal to `optAmount`, to prevent sending the wrong + * payment and other confusion. + * + * If the payment is a promise, the operation will proceed upon + * resolution. + */ +export type IssuerBurn = ( + payment: ERef, + optAmountShape?: Pattern | undefined, +) => Promise; +/** + * Transfer all digital assets from the payment to a new payment and + * delete the original. `optAmount` is optional. If `optAmount` is + * present, the code will insist that the amount of digital assets in + * the payment is equal to `optAmount`, to prevent sending the wrong + * payment and other confusion. + * + * If the payment is a promise, the operation will proceed upon + * resolution. + */ +export type IssuerClaim = ( + payment: ERef, + optAmountShape?: Pattern | undefined, +) => Promise; +/** + * Combine multiple payments into one payment. + * + * If any of the payments is a promise, the operation will proceed + * upon resolution. + */ +export type IssuerCombine = ( + paymentsArray: ERef[], + optTotalAmount?: Amount | undefined, +) => Promise; +/** + * Split a single payment into two payments, + * A and B, according to the paymentAmountA passed in. + * + * If the payment is a promise, the operation will proceed upon + * resolution. + */ +export type IssuerSplit = ( + payment: ERef, + paymentAmountA: Amount, +) => Promise; +/** + * Split a single payment into many payments, according to the amounts + * passed in. + * + * If the payment is a promise, the operation will proceed upon + * resolution. + */ +export type IssuerSplitMany = ( + payment: ERef, + amounts: Amount[], +) => Promise; +/** + * The issuer cannot mint a new amount, but it can create empty purses + * and payments. The issuer can also transform payments (splitting + * payments, combining payments, burning payments, and claiming + * payments exclusively). The issuer should be gotten from a trusted + * source and then relied upon as the decider of whether an untrusted + * payment is valid. + */ +export type Issuer = { + /** + * Get the Brand for this Issuer. The + * Brand indicates the type of digital asset and is shared by the + * mint, the issuer, and any purses and payments of this particular + * kind. The brand is not closely held, so this function should not be + * trusted to identify an issuer alone. Fake digital assets and amount + * can use another issuer's brand. + */ + getBrand: () => Brand; + /** + * Get the allegedName for + * this mint/issuer + */ + getAllegedName: () => string; + /** + * Get the kind of + * MathHelpers used by this Issuer. + */ + getAssetKind: () => AssetKind; + /** + * Give information to UI + * on how to display amounts for this issuer. + */ + getDisplayInfo: () => DisplayInfo; + /** + * Make an empty purse of this + * brand. + */ + makeEmptyPurse: () => Purse; + isLive: IssuerIsLive; + getAmountOf: IssuerGetAmountOf; + burn: IssuerBurn; + claim: IssuerClaim; + combine: IssuerCombine; + split: IssuerSplit; + splitMany: IssuerSplitMany; +}; +export type PaymentLedger = { + mint: Mint; + issuer: Issuer; + brand: Brand; +}; +export type IssuerKit = { + mint: Mint; + issuer: Issuer; + brand: Brand; + displayInfo: DisplayInfo; +}; +export type AdditionalDisplayInfo = { + /** + * Tells the display software how + * many decimal places to move the decimal over to the left, or in + * other words, which position corresponds to whole numbers. We + * require fungible digital assets to be represented in integers, in + * the smallest unit (i.e. USD might be represented in mill, a + * thousandth of a dollar. In that case, `decimalPlaces` would be + * 3.) This property is optional, and for non-fungible digital + * assets, should not be specified. The decimalPlaces property + * should be used for *display purposes only*. Any other use is an + * anti-pattern. + */ + decimalPlaces?: number | undefined; + assetKind?: AssetKind | undefined; +}; +/** + * Called to shut something down because something went wrong, where the reason + * is supposed to be an Error that describes what went wrong. Some valid + * implementations of `ShutdownWithFailure` will never return, either + * because they throw or because they immediately shutdown the enclosing unit + * of computation. However, they also might return, so the caller should + * follow this call by their own defensive `throw reason;` if appropriate. + */ +export type ShutdownWithFailure = (reason: Error) => void; +/** + * Holding a Mint carries the right to issue new digital assets. These + * assets all have the same kind, which is called a Brand. + */ +export type Mint = { + /** + * Gets the Issuer for this mint. + */ + getIssuer: () => Issuer; + /** + * Creates a new Payment containing newly minted amount. + */ + mintPayment: (newAmount: Amount) => Payment; +}; +export type DepositFacetReceive = ( + payment: Payment, + optAmountShape?: Pattern | undefined, +) => Amount; +export type DepositFacet = { + /** + * Deposit all the contents of payment into the purse that made this facet, + * returning the amount. If the optional argument `optAmount` does not equal the + * amount of digital assets in the payment, throw an error. + * + * If payment is a promise, throw an error. + */ + receive: DepositFacetReceive; +}; +export type PurseDeposit = ( + payment: Payment, + optAmountShape?: Pattern | undefined, +) => Amount; +/** + * Purses hold amount of digital assets of the same brand, but unlike Payments, + * they are not meant to be sent to others. To transfer digital assets, a + * Payment should be withdrawn from a Purse. The amount of digital + * assets in a purse can change through the action of deposit() and withdraw(). + * + * The primary use for Purses and Payments is for currency-like and goods-like + * digital assets, but they can also be used to represent other kinds of rights, + * such as the right to participate in a particular contract. + */ +export type Purse = { + /** + * Get the alleged Brand for this Purse + */ + getAllegedBrand: () => Brand; + /** + * Get the amount contained in this purse. + */ + getCurrentAmount: () => Amount; + /** + * Get a lossy notifier for changes to this purse's balance. + */ + getCurrentAmountNotifier: () => Notifier>; + /** + * Deposit all the contents of payment into this purse, returning the + * amount. If the optional argument `optAmount` does not equal the + * amount of digital assets in the payment, throw an error. + * + * If payment is a promise, throw an error. + */ + deposit: PurseDeposit; + /** + * Return an object whose `receive` method deposits to the current Purse. + */ + getDepositFacet: () => DepositFacet; + /** + * Withdraw amount from this purse into a new Payment. + */ + withdraw: (amount: Amount) => Payment; + /** + * The set of payments associated with this purse that are still live. These + * are the payments that can still be recovered in emergencies by, for example, + * depositing into this purse. Such a deposit action is like canceling an + * outstanding check because you're tired of waiting for it. Once your + * cancellation is acknowledged, you can spend the assets at stake on other + * things. Afterwards, if the recipient of the original check finally gets + * around to depositing it, their deposit fails. + */ + getRecoverySet: () => CopySet>; + /** + * For use in emergencies, such as coming back from a traumatic crash and + * upgrade. This deposits all the payments in this purse's recovery set + * into the purse itself, returning the total amount of assets recovered. + */ + recoverAll: () => Amount; +}; +/** + * Payments hold amount of digital assets of the same brand in transit. Payments + * can be deposited in purses, split into multiple payments, combined, and + * claimed (getting an exclusive payment). Payments are linear, meaning + * that either a payment has the same amount of digital assets it + * started with, or it is used up entirely. It is impossible to partially use a + * payment. + * + * Payments are often received from other actors and therefore should + * not be trusted themselves. To get the amount of digital assets in a payment, + * use the trusted issuer: issuer.getAmountOf(payment), + * + * Payments can be converted to Purses by getting a trusted issuer and + * calling `issuer.makeEmptyPurse()` to create a purse, then + * `purse.deposit(payment)`. + */ +export type Payment = { + /** + * Get the allegedBrand, indicating the type of digital asset this + * payment purports to be, and which issuer to use. Because payments + * are not trusted, any method calls on payments should be treated + * with suspicion and verified elsewhere. + */ + getAllegedBrand: () => Brand; +}; +/** + * All of the difference in how digital asset amount are manipulated can be + * reduced to the behavior of the math on values. We extract this + * custom logic into mathHelpers. MathHelpers are about value + * arithmetic, whereas AmountMath is about amounts, which are the + * values labeled with a brand. AmountMath use mathHelpers to do their value + * arithmetic, and then brand the results, making a new amount. + * + * The MathHelpers are designed to be called only from AmountMath, and so + * all methods but coerce can assume their inputs are valid. They only + * need to do output validation, and only when there is a possibility of + * invalid output. + */ +export type MathHelpers = { + /** + * Check the kind of this value and throw if it is not the + * expected kind. + */ + doCoerce: (allegedValue: V) => V; + /** + * Get the representation for the identity element (often 0 or an + * empty array) + */ + doMakeEmpty: () => V; + /** + * Is the value the identity element? + */ + doIsEmpty: (value: V) => boolean; + /** + * Is the left greater than or equal to the right? + */ + doIsGTE: (left: V, right: V) => boolean; + /** + * Does left equal right? + */ + doIsEqual: (left: V, right: V) => boolean; + /** + * Return the left combined with the right. + */ + doAdd: (left: V, right: V) => V; + /** + * Return what remains after removing the right from the left. If + * something in the right was not in the left, we throw an error. + */ + doSubtract: (left: V, right: V) => V; +}; +export type NatValue = bigint; +export type NatMathHelpers = MathHelpers; +export type SetValue = Array; +export type SetMathHelpers = MathHelpers; +export type CopySetValue = CopySet; +export type CopySetMathHelpers = MathHelpers; +export type CopyBagValue = CopyBag; +export type CopyBagMathHelpers = MathHelpers; +export type AssertAssetKind = (allegedAK: AssetKind) => void; diff --git a/packages/ERTP/src/types.js b/packages/ERTP/src/types.js index 57520d8039e..d4f3b92e2f0 100644 --- a/packages/ERTP/src/types.js +++ b/packages/ERTP/src/types.js @@ -1,8 +1,9 @@ +// @ts-check /// /** * @typedef {import('@endo/marshal').InterfaceSpec} InterfaceSpec - * @typedef {import('@endo/marshal').GetInterfaceOf} GetInterfaceOf + * @typedef {import('@endo/marshal').MarshalGetInterfaceOf} GetInterfaceOf */ /** @@ -409,8 +410,8 @@ */ /** - * @template {AssetKind} K - * @typedef {object} MathHelpers + * @template {AmountValue} V + * @typedef {object} MathHelpers * All of the difference in how digital asset amount are manipulated can be * reduced to the behavior of the math on values. We extract this * custom logic into mathHelpers. MathHelpers are about value diff --git a/packages/SwingSet/src/devices/timer/device-timer.js b/packages/SwingSet/src/devices/timer/device-timer.js index bc711ee4a72..baca8630390 100644 --- a/packages/SwingSet/src/devices/timer/device-timer.js +++ b/packages/SwingSet/src/devices/timer/device-timer.js @@ -1,3 +1,4 @@ +// @ts-check /** * A Timer device that provides a capability that can be used to schedule wake() * calls at particular times. The simpler form is a handler object with a wake() @@ -147,7 +148,9 @@ function makeTimerMap(state = undefined) { } else { // Nothing prevents a particular handler from appearing more than once for (const { handler } of handlers) { + // @ts-expect-error FIXME Waker 'handler' can't be in array of IndexedHandler if (handler === targetHandler && handlers.indexOf(handler) !== -1) { + // @ts-expect-error FIXME Waker 'handler' can't be in array of IndexedHandler handlers.splice(handlers.indexOf(handler), 1); droppedTimes.push(time); } diff --git a/packages/SwingSet/src/kernel/vat-loader/types.js b/packages/SwingSet/src/kernel/vat-loader/types.js index db6e709af9f..5568006acbe 100644 --- a/packages/SwingSet/src/kernel/vat-loader/types.js +++ b/packages/SwingSet/src/kernel/vat-loader/types.js @@ -1,3 +1,4 @@ +// @ts-check /** * @typedef { [unknown, ...unknown[]] } Tagged * @typedef { { meterType: string, allocate: number|null, compute: number|null } } diff --git a/packages/SwingSet/src/lib-nodejs/hasher.js b/packages/SwingSet/src/lib-nodejs/hasher.js index 32b92a5d3ae..f84847934c7 100644 --- a/packages/SwingSet/src/lib-nodejs/hasher.js +++ b/packages/SwingSet/src/lib-nodejs/hasher.js @@ -1,3 +1,4 @@ +// @ts-check import { assert } from '@agoric/assert'; import { createHash } from 'crypto'; diff --git a/packages/SwingSet/src/vats/network/multiaddr.js b/packages/SwingSet/src/vats/network/multiaddr.js index 3e411ef273c..74c9108bef3 100644 --- a/packages/SwingSet/src/vats/network/multiaddr.js +++ b/packages/SwingSet/src/vats/network/multiaddr.js @@ -1,3 +1,4 @@ +// @ts-check /** * @typedef {[string, string][]} Multiaddr * @typedef {string} Textaddr An address string formatted as in https://github.com/multiformats/multiaddr @@ -38,6 +39,7 @@ export function parse(ma) { if (m[2]) { acc.push([m[1], m[3]]); } else { + // @ts-expect-error '[string]' is not assignable to parameter of type '[string, string]' acc.push([m[1]]); } } diff --git a/packages/SwingSet/tools/internal-types.js b/packages/SwingSet/tools/internal-types.js index 7926471379c..a2eb20039a2 100644 --- a/packages/SwingSet/tools/internal-types.js +++ b/packages/SwingSet/tools/internal-types.js @@ -1,3 +1,4 @@ +// @ts-check /** * @typedef {object} ManualTimerAdmin * @property { (when: Timestamp) => void } advanceTo diff --git a/packages/SwingSet/tools/manual-timer.js b/packages/SwingSet/tools/manual-timer.js index 3cb39ec1184..b491ae11e74 100644 --- a/packages/SwingSet/tools/manual-timer.js +++ b/packages/SwingSet/tools/manual-timer.js @@ -53,7 +53,7 @@ const setup = () => { * kernel. You can make time pass by calling `advanceTo(when)`. * * @param {ManualTimerOptions} [options] - * @returns {ManualTimer} + * @returns {TimerService & { advanceTo: (when: Timestamp) => void; }} */ export const buildManualTimer = (options = {}) => { const { startTime = 0n, ...other } = options; diff --git a/packages/agoric-cli/package.json b/packages/agoric-cli/package.json index fd513e99384..96f903cd366 100644 --- a/packages/agoric-cli/package.json +++ b/packages/agoric-cli/package.json @@ -20,7 +20,7 @@ "integration-test": "ava --config .ava-integration-test.config.js", "lint-fix": "yarn lint:eslint --fix", "lint": "run-s --continue-on-error lint:*", - "lint:types": "tsc --maxNodeModuleJsDepth 4 -p jsconfig.json", + "lint:types": "tsc --maxNodeModuleJsDepth 0 -p jsconfig.json", "lint:eslint": "eslint ." }, "devDependencies": { diff --git a/packages/agoric-cli/src/commands/psm.js b/packages/agoric-cli/src/commands/psm.js index ed9f637eab3..6dcdd7ef803 100644 --- a/packages/agoric-cli/src/commands/psm.js +++ b/packages/agoric-cli/src/commands/psm.js @@ -162,8 +162,12 @@ export const makePsmCommand = async logger => { const opts = this.opts(); console.warn('running with options', opts); const instance = await lookupPsmInstance(opts.pair); - // @ts-expect-error RpcRemote types not real instances - const spendAction = makePSMSpendAction(instance, agoricNames.brand, opts); + const spendAction = makePSMSpendAction( + instance, + // @ts-expect-error xxx RpcRemote + agoricNames.brand, + opts, + ); outputAction(spendAction); }); @@ -182,7 +186,6 @@ export const makePsmCommand = async logger => { id: Number(opts.offerId), invitationSpec: { source: 'purse', - // @ts-expect-error rpc instance: economicCommittee, description: 'Voter0', // XXX it may not always be }, @@ -212,7 +215,6 @@ export const makePsmCommand = async logger => { id: Number(opts.offerId), invitationSpec: { source: 'purse', - // @ts-expect-error rpc instance: psmCharter, description: 'PSM charter member invitation', }, @@ -316,8 +318,8 @@ export const makePsmCommand = async logger => { const psmInstance = lookupPsmInstance(opts.pair); - /** @type {Brand} */ - // @ts-expect-error yes, it is a brand + /** @type {import('../types.js').Brand} */ + // @ts-expect-error xxx RpcRemote const istBrand = agoricNames.brand.IST; const scaledAmount = harden({ brand: istBrand, diff --git a/packages/agoric-cli/src/lib/format.js b/packages/agoric-cli/src/lib/format.js index 4265203fce6..1c7e1964632 100644 --- a/packages/agoric-cli/src/lib/format.js +++ b/packages/agoric-cli/src/lib/format.js @@ -59,7 +59,7 @@ export const asPercent = ratio => { }; /** - * @param {Amount[]} balances + * @param {Array} balances * @param {AssetDescriptor[]} assets */ export const simplePurseBalances = (balances, assets) => { diff --git a/packages/agoric-cli/src/lib/psm.js b/packages/agoric-cli/src/lib/psm.js index 7a90febd736..2516a85e1e9 100644 --- a/packages/agoric-cli/src/lib/psm.js +++ b/packages/agoric-cli/src/lib/psm.js @@ -4,9 +4,6 @@ import { COSMOS_UNIT, makeAmountFormatter } from './format.js'; // eslint-disable-next-line no-unused-vars -- typeof below import { makeAgoricNames } from './rpc.js'; -// Ambient types. Needed only for dev but this does a runtime import. -import '@agoric/zoe/src/zoeService/types.js'; - /** @typedef {import('@agoric/smart-wallet/src/offers').OfferSpec} OfferSpec */ /** @typedef {import('@agoric/smart-wallet/src/offers').OfferStatus} OfferStatus */ /** @typedef {import('@agoric/smart-wallet/src/smartWallet').BridgeAction} BridgeAction */ @@ -32,7 +29,6 @@ export const simpleOffers = (state, agoricNames) => { payouts, } = o; const entry = Object.entries(agoricNames.instance).find( - // @ts-expect-error xxx RpcRemote ([_name, candidate]) => candidate === instance, ); const instanceName = entry ? entry[0] : '???'; @@ -52,11 +48,11 @@ export const simpleOffers = (state, agoricNames) => { }; /** - * @param {Record} brands + * @param {Record} brands * @param {({ wantMinted: number | undefined, giveMinted: number | undefined })} opts * @param {number} [fee=0] * @param {string} [anchor] - * @returns {Proposal} + * @returns {import('../types').Proposal} */ export const makePSMProposal = (brands, opts, fee = 0, anchor = 'AUSD') => { const giving = opts.giveMinted ? 'minted' : 'anchor'; @@ -82,8 +78,8 @@ export const makePSMProposal = (brands, opts, fee = 0, anchor = 'AUSD') => { }; /** - * @param {Instance} instance - * @param {Record} brands + * @param {import('../types').Instance} instance + * @param {Record} brands * @param {{ offerId: number, feePct?: number } & * ({ wantMinted: number | undefined, giveMinted: number | undefined })} opts * @returns {BridgeAction} diff --git a/packages/agoric-cli/src/lib/rpc.js b/packages/agoric-cli/src/lib/rpc.js index a095713a260..f53bce33fd1 100644 --- a/packages/agoric-cli/src/lib/rpc.js +++ b/packages/agoric-cli/src/lib/rpc.js @@ -117,7 +117,7 @@ export const makeVStorage = powers => { * - if a part being serialized has a boardId property, it passes through as a slot value whereas the normal marshaller would treat it as a copyRecord * * @param {(slot: string, iface: string) => any} slotToVal - * @returns {Marshaller} + * @returns {import('@endo/marshal').Marshal} */ export const boardSlottingMarshaller = (slotToVal = (s, _i) => s) => ({ /** @param {{body: string, slots: string[]}} capData */ diff --git a/packages/agoric-cli/src/lib/wallet.js b/packages/agoric-cli/src/lib/wallet.js index 9f93af96937..ed39800aad9 100644 --- a/packages/agoric-cli/src/lib/wallet.js +++ b/packages/agoric-cli/src/lib/wallet.js @@ -1,4 +1,5 @@ // @ts-check +/* eslint-disable @typescript-eslint/prefer-ts-expect-error -- https://github.com/Agoric/agoric-sdk/issues/4620 */ import { boardSlottingMarshaller, storageHelper } from './rpc.js'; /** @@ -16,7 +17,7 @@ export const getWalletState = async (addr, ctx, { vstorage }) => { /** @type {Map} */ const offers = new Map(); - /** @type {Map} */ + /** @type {Map} */ const balances = new Map(); /** @type {import('./format').AssetDescriptor[]} */ const brands = []; @@ -37,17 +38,18 @@ export const getWalletState = async (addr, ctx, { vstorage }) => { case 'balance': { const { currentAmount } = update; if (!balances.has(currentAmount.brand)) { + // @ts-ignore https://github.com/agoric/agoric-sdk/issues/4560 balances.set(currentAmount.brand, currentAmount); } break; } case 'brand': { - // @ts-expect-error cast for unserialization hack + // @ts-ignore https://github.com/agoric/agoric-sdk/issues/4560 brands.push(update.descriptor); break; } default: - // @ts-expect-error + // @ts-ignore https://github.com/agoric/agoric-sdk/issues/4560 throw Error(`unsupported update ${update.updated}`); } }); diff --git a/packages/agoric-cli/src/types.d.ts b/packages/agoric-cli/src/types.d.ts new file mode 100644 index 00000000000..cd3fbb5dfcf --- /dev/null +++ b/packages/agoric-cli/src/types.d.ts @@ -0,0 +1,6 @@ +// This package has maxNodeModuleJsDepth=0 to prevent ambient imports. +// A consequence is that types that are only provided ambiently have to be defined. + +export { Amount, Brand, Proposal } from '@agoric/ertp/src/types-module'; + +export type Instance = unknown; diff --git a/packages/deploy-script-support/src/externalTypes.js b/packages/deploy-script-support/src/externalTypes.js index 19502b21c62..b575d15364a 100644 --- a/packages/deploy-script-support/src/externalTypes.js +++ b/packages/deploy-script-support/src/externalTypes.js @@ -1,3 +1,4 @@ +// @ts-check /** * @callback InstallSaveAndPublish * @param {string} resolvedPath diff --git a/packages/governance/src/constants.js b/packages/governance/src/constants.js index 7fa2b609003..854bfed07a1 100644 --- a/packages/governance/src/constants.js +++ b/packages/governance/src/constants.js @@ -1,3 +1,4 @@ +// @ts-check /** * Enum of parameter types * diff --git a/packages/governance/src/types.js b/packages/governance/src/types.js index cef771f4f41..54da4dac4de 100644 --- a/packages/governance/src/types.js +++ b/packages/governance/src/types.js @@ -279,7 +279,7 @@ /** * @typedef { ElectorateCreatorFacet & { - * getVoterInvitations: () => Promise[] + * getVoterInvitations: () => Promise>[] * }} CommitteeElectorateCreatorFacet */ diff --git a/packages/inter-protocol/scripts/manual-price-feed.js b/packages/inter-protocol/scripts/manual-price-feed.js index 877e38c9f22..1d07176b2a3 100644 --- a/packages/inter-protocol/scripts/manual-price-feed.js +++ b/packages/inter-protocol/scripts/manual-price-feed.js @@ -1,3 +1,4 @@ +// @ts-check import { E } from '@endo/far'; import { deeplyFulfilled } from '@endo/marshal'; import { makeNotifierFromAsyncIterable } from '@agoric/notifier'; diff --git a/packages/inter-protocol/src/psm/psm.js b/packages/inter-protocol/src/psm/psm.js index dbd67a0a435..b82942f018b 100644 --- a/packages/inter-protocol/src/psm/psm.js +++ b/packages/inter-protocol/src/psm/psm.js @@ -328,3 +328,5 @@ export const start = async (zcf, privateArgs, baggage) => { publicFacet, }); }; + +/** @typedef {Awaited>['publicFacet']} PsmPublicFacet */ diff --git a/packages/inter-protocol/src/reserve/assetReserve.js b/packages/inter-protocol/src/reserve/assetReserve.js index bcad490da99..eaa2bad3894 100644 --- a/packages/inter-protocol/src/reserve/assetReserve.js +++ b/packages/inter-protocol/src/reserve/assetReserve.js @@ -407,6 +407,7 @@ const start = async (zcf, privateArgs, baggage) => { reduceLiquidationShortfall, }; + /** @param {MethodContext} context */ const makeShortfallReportingInvitation = ({ facets }) => { const handleShortfallReportingOffer = () => { return facets.shortfallReportingFacet; @@ -464,7 +465,7 @@ export { start }; * @property {() => Invitation} makeAddCollateralInvitation * @property {() => Allocation} getAllocations * @property {(issuer: Issuer) => void} addIssuer - * @property {() => Invitation} makeShortfallReportingInvitation + * @property {() => Invitation} makeShortfallReportingInvitation * @property {() => MetricsNotification} getMetrics */ diff --git a/packages/inter-protocol/src/stakeFactory/types.js b/packages/inter-protocol/src/stakeFactory/types.js index fd637f4e80d..c435de171fa 100644 --- a/packages/inter-protocol/src/stakeFactory/types.js +++ b/packages/inter-protocol/src/stakeFactory/types.js @@ -1,3 +1,4 @@ +// @ts-check /** * For example, an agoric1... Cosmos address * diff --git a/packages/inter-protocol/src/vaultFactory/types.js b/packages/inter-protocol/src/vaultFactory/types.js index 63eba52ffdf..8354bec93b9 100644 --- a/packages/inter-protocol/src/vaultFactory/types.js +++ b/packages/inter-protocol/src/vaultFactory/types.js @@ -117,7 +117,7 @@ /** * @typedef {object} Liquidator - * @property {() => Promise }, void>>} makeLiquidateInvitation + * @property {() => Promise; penaltyRate: Ratio; }>>} makeLiquidateInvitation */ /** diff --git a/packages/inter-protocol/src/vpool-xyk-amm/addPool.js b/packages/inter-protocol/src/vpool-xyk-amm/addPool.js index e67492cfb18..e08c7fc9e4d 100644 --- a/packages/inter-protocol/src/vpool-xyk-amm/addPool.js +++ b/packages/inter-protocol/src/vpool-xyk-amm/addPool.js @@ -157,6 +157,7 @@ export const makeAddPoolInvitation = ( ); const minLiqAmount = AmountMath.make( liquidityBrand, + // @ts-expect-error known nat minPoolLiquidity.value, ); diff --git a/packages/inter-protocol/src/vpool-xyk-amm/multipoolMarketMaker.js b/packages/inter-protocol/src/vpool-xyk-amm/multipoolMarketMaker.js index 1e6b7ca6183..9d436d92b94 100644 --- a/packages/inter-protocol/src/vpool-xyk-amm/multipoolMarketMaker.js +++ b/packages/inter-protocol/src/vpool-xyk-amm/multipoolMarketMaker.js @@ -55,7 +55,7 @@ const trace = makeTracer('XykAmm', false); * @typedef {Readonly<{ * zcf: ZCF, * secondaryBrandToPool: WeakMapStore, - * secondaryBrandToLiquidityMint: WeakMapStore, + * secondaryBrandToLiquidityMint: WeakMapStore>, * centralBrand: Brand, * timer: TimerService, * quoteIssuerKit: IssuerKit, diff --git a/packages/inter-protocol/src/vpool-xyk-amm/params.js b/packages/inter-protocol/src/vpool-xyk-amm/params.js index dd21be5578a..71682e4b3bc 100644 --- a/packages/inter-protocol/src/vpool-xyk-amm/params.js +++ b/packages/inter-protocol/src/vpool-xyk-amm/params.js @@ -13,7 +13,7 @@ const DEFAULT_PROTOCOL_FEE_BP = 6n; * @param {Invitation} electorateInvitation - invitation for the question poser * @param {bigint} protocolFeeBP * @param {bigint} poolFeeBP - * @param {Amount} minInitialLiquidity + * @param {Amount<'nat'>} minInitialLiquidity */ const makeAmmParams = ( electorateInvitation, diff --git a/packages/inter-protocol/src/vpool-xyk-amm/pool.js b/packages/inter-protocol/src/vpool-xyk-amm/pool.js index eb5b81940ff..4e1ec873adf 100644 --- a/packages/inter-protocol/src/vpool-xyk-amm/pool.js +++ b/packages/inter-protocol/src/vpool-xyk-amm/pool.js @@ -84,7 +84,7 @@ export const definePoolKind = (baggage, ammPowers, storageNode, marshaller) => { ); /** - * @param {ZCFMint} liquidityZcfMint + * @param {ZCFMint<'nat'>} liquidityZcfMint * @param {ZCFSeat} poolSeat * @param {Brand} secondaryBrand * @returns {ImmutableState & MutableState} diff --git a/packages/inter-protocol/test/psm/setupPsm.js b/packages/inter-protocol/test/psm/setupPsm.js index 1dba9fd8e17..6d5ef1e2e43 100644 --- a/packages/inter-protocol/test/psm/setupPsm.js +++ b/packages/inter-protocol/test/psm/setupPsm.js @@ -170,7 +170,7 @@ export const setupPsm = async ( }; const governedInstance = E(governorPublicFacet).getGovernedContract(); - /** @type { GovernedPublicFacet } */ + /** @type { GovernedPublicFacet } */ const psmPublicFacet = await E(governorCreatorFacet).getPublicFacet(); const psm = { psmCreatorFacet: psmFacets.psmCreatorFacet, diff --git a/packages/inter-protocol/test/reserve/setup.js b/packages/inter-protocol/test/reserve/setup.js index e0a54a66681..24080e5d200 100644 --- a/packages/inter-protocol/test/reserve/setup.js +++ b/packages/inter-protocol/test/reserve/setup.js @@ -1,3 +1,4 @@ +// @ts-check import buildManualTimer from '@agoric/zoe/tools/manualTimer.js'; import { E } from '@endo/eventual-send'; import { @@ -9,11 +10,15 @@ import { provideBundle } from '../supports.js'; const reserveRoot = './src/reserve/assetReserve.js'; // package relative const faucetRoot = './test/vaultFactory/faucet.js'; +/** + * @typedef {ReturnType} FarZoeKit + */ + /** * NOTE: called separately by each test so AMM/zoe/priceAuthority don't interfere * * @param {*} t - * @param {ManualTimer | undefined=} timer + * @param {ManualTimer | undefined} timer * @param {FarZoeKit} farZoeKit * @param {Issuer} runIssuer * @param {{ committeeName: string, committeeSize: number}} electorateTerms @@ -35,9 +40,13 @@ const setupReserveBootstrap = async ( timer, farZoeKit, ); - const { produce } = /** @type { EconomyBootstrapPowers } */ (ammSpaces.space); + const { produce } = + /** @type { import('../../src/proposals/econ-behaviors.js').EconomyBootstrapPowers } */ ( + ammSpaces.space + ); const zoe = await farZoeKit.zoe; + // @ts-expect-error xxx produce.chainTimerService.resolve(timer); produce.zoe.resolve(zoe); diff --git a/packages/inter-protocol/test/vaultFactory/test-vaultFactory.js b/packages/inter-protocol/test/vaultFactory/test-vaultFactory.js index ef635924fc7..020dc240158 100644 --- a/packages/inter-protocol/test/vaultFactory/test-vaultFactory.js +++ b/packages/inter-protocol/test/vaultFactory/test-vaultFactory.js @@ -1498,10 +1498,10 @@ test('transfer vault', async t => { return amount.value[0]; }; + /** @type {Promise>} */ const transferInvite = E(aliceVault).makeTransferInvitation(); const inviteProps = await getInvitationProperties(transferInvite); trace(t, 'TRANSFER INVITE', transferInvite, inviteProps); - /** @type {UserSeat} */ const transferSeat = await E(zoe).offer(transferInvite); const { vault: transferVault, @@ -1561,8 +1561,8 @@ test('transfer vault', async t => { }), harden({ Minted: paybackPayment }), ); + /** @type {Invitation} */ const t2Invite = await E(transferVault).makeTransferInvitation(); - /** @type {UserSeat} */ const t2Seat = await E(zoe).offer(t2Invite); const { vault: t2Vault, @@ -2269,7 +2269,6 @@ test('excessive debt on collateral type', async t => { const { lender } = services.vaultFactory; const collateralAmount = aeth.make(1_000_000n); const centralAmount = run.make(1_000_000n); - /** @type {UserSeat} */ const loanSeat = await E(zoe).offer( E(lender).makeVaultInvitation(), harden({ @@ -2859,7 +2858,7 @@ test('manager notifiers', async t => { // can't use 0n because of https://github.com/Agoric/agoric-sdk/issues/5548 // but since this test is of metrics, we take the opportunity to check totalCollateral changing const given = aeth.make(2n); - vaultSeat = await E(services.zoe).offer( + let vaultOpSeat = await E(services.zoe).offer( await E(vault).makeAdjustBalancesInvitation(), harden({ // nominal collateral @@ -2870,14 +2869,14 @@ test('manager notifiers', async t => { Collateral: t.context.aeth.mint.mintPayment(given), }), ); - await E(vaultSeat).getOfferResult(); + await E(vaultOpSeat).getOfferResult(); await m.assertChange({ totalDebt: { value: DEBT1_EXTRA }, totalCollateral: { value: AMPLE + given.value }, }); trace('13. Close loan'); - vaultSeat = await E(services.zoe).offer( + vaultOpSeat = await E(services.zoe).offer( await E(vault).makeCloseInvitation(), harden({ give: { Minted: run.make(DEBT1_EXTRA) }, @@ -2887,7 +2886,7 @@ test('manager notifiers', async t => { Minted: await getRunFromFaucet(t, DEBT1_EXTRA), }), ); - await E(vaultSeat).getOfferResult(); + await E(vaultOpSeat).getOfferResult(); await m.assertChange({ numActiveVaults: 0, totalCollateral: { value: 0n }, diff --git a/packages/smart-wallet/src/offers.js b/packages/smart-wallet/src/offers.js index 60e6fe589fe..6955a467adf 100644 --- a/packages/smart-wallet/src/offers.js +++ b/packages/smart-wallet/src/offers.js @@ -127,7 +127,9 @@ export const makeOfferExecutor = ({ updateStatus({ result }); break; case 'copyRecord': + // @ts-expect-error result narrowed by passStyle if ('invitationMakers' in result) { + // @ts-expect-error result narrowed by passStyle // save for continuing invitation offer onNewContinuingOffer(id, result.invitationMakers); } diff --git a/packages/solo/src/chain-cosmos-sdk.js b/packages/solo/src/chain-cosmos-sdk.js index 75ebe383033..c506d342c01 100644 --- a/packages/solo/src/chain-cosmos-sdk.js +++ b/packages/solo/src/chain-cosmos-sdk.js @@ -1,3 +1,4 @@ +// @ts-check /* global setTimeout Buffer */ import path from 'path'; import fs from 'fs'; @@ -80,7 +81,7 @@ const makeTempFile = async (prefix, contents) => { if (err) { return reject(err); } - return resolve(); + return resolve(undefined); }); }); } finally { @@ -89,7 +90,7 @@ const makeTempFile = async (prefix, contents) => { if (e) { return reject(e); } - return resolve(); + return resolve(undefined); }); }); } @@ -214,6 +215,7 @@ export async function connectToChain( }, ); if (stdin) { + assert(proc.stdin, 'no stdin'); proc.stdin.write(stdin); proc.stdin.end(); } @@ -583,6 +585,7 @@ ${chainID} chain does not yet know of address ${clientAddr}${adviseEgress( const bigPool = messagePool.concat(newMessages); // Sort the big pool by sequence number. + // @ts-expect-error FIXME bigint as sort value const sortedPool = bigPool.sort((a, b) => a[0] - b[0]); // Only keep messages that have a unique sequence number. @@ -727,7 +730,7 @@ ${chainID} chain does not yet know of address ${clientAddr}${adviseEgress( * * It then delivers the mailbox to inbound. There are no optimisations. * - * @param {number=} lastMailboxUpdate + * @param {UpdateCount=} lastMailboxUpdate */ const recurseEachMailboxUpdate = async (lastMailboxUpdate = undefined) => { const { updateCount, value: mailbox } = await mbNotifier.getUpdateSince( @@ -758,6 +761,7 @@ ${chainID} chain does not yet know of address ${clientAddr}${adviseEgress( // Reset the backoff period. retryBackoff = randomizeDelay(INITIAL_SEND_RETRY_DELAY_MS); }; + /** @param {Error} [e] */ const failedSend = (e = undefined) => { if (e) { console.error(`Error sending`, e); @@ -778,6 +782,7 @@ ${chainID} chain does not yet know of address ${clientAddr}${adviseEgress( }; // This function ensures we only have one outgoing send operation at a time. + /** @type {(lastSendUpdate?: UpdateCount) => Promise} */ const recurseEachSend = async (lastSendUpdate = undefined) => { // See when there is another requested send since our last time. const { updateCount } = await sendNotifier.getUpdateSince(lastSendUpdate); diff --git a/packages/solo/src/outbound.js b/packages/solo/src/outbound.js index 0a6b3ec65ec..21d6f736509 100644 --- a/packages/solo/src/outbound.js +++ b/packages/solo/src/outbound.js @@ -1,3 +1,4 @@ +// @ts-check /* global process */ import anylogger from 'anylogger'; @@ -14,7 +15,7 @@ const log = anylogger('outbound'); * @property {(newMessages: Array<[number, string]>, acknum: number) => void} deliverator * @property {number} highestSent * @property {number} highestAck - * @property {number} trips + * @property {number} [trips] */ /** @@ -32,6 +33,7 @@ export function deliver(mbs) { continue; } const t = knownTargets.get(target); + assert(t, `missing target ${target}`); const newMessages = []; data[target].outbox.forEach(m => { const [msgnum, body] = m; diff --git a/packages/solo/src/scratch.js b/packages/solo/src/scratch.js index 74d57e1cdab..f598e1f56c2 100644 --- a/packages/solo/src/scratch.js +++ b/packages/solo/src/scratch.js @@ -1,3 +1,4 @@ +// @ts-check import { E } from '@endo/eventual-send'; import { Far } from '@endo/marshal'; diff --git a/packages/ui-components/package.json b/packages/ui-components/package.json index 08a9811d6e6..1e0859b56e6 100644 --- a/packages/ui-components/package.json +++ b/packages/ui-components/package.json @@ -28,7 +28,7 @@ "lint-fix": "yarn lint:eslint --fix", "lint": "run-s --continue-on-error lint:*", "lint:eslint": "eslint .", - "lint:types": "tsc --maxNodeModuleJsDepth 4 -p jsconfig.json" + "lint:types": "tsc --maxNodeModuleJsDepth 0 -p jsconfig.json" }, "eslintConfig": { "extends": [ diff --git a/packages/ui-components/src/components/NatPurseSelector.jsx b/packages/ui-components/src/components/NatPurseSelector.jsx index 9529eb0e3a2..5ddb7e1b3af 100644 --- a/packages/ui-components/src/components/NatPurseSelector.jsx +++ b/packages/ui-components/src/components/NatPurseSelector.jsx @@ -9,9 +9,9 @@ import { stringifyValue } from '../display/index.js'; * components represent initial state as null/undefined. * * @param {Array | null} purses Unfiltered purses. This may be null to simplify use in UIs. - * @param {Brand} [optBrand] - optional brand to filter for + * @param {import('@agoric/ertp/src/types-module').Brand} [optBrand] - optional brand to filter for * @returns {PursesJSONState[] | null} - * @typedef {{ brand: Brand, displayInfo: any }} PursesJSONState + * @typedef {{ brand: import('@agoric/ertp/src/types-module').Brand, displayInfo: any }} PursesJSONState * see wallet/api/src/types.js * @deprecated */ @@ -26,7 +26,7 @@ export const filterPurses = (purses, optBrand) => { }; /** - * @typedef {{ pursePetname: string, brandPetname: string, value: AmountValue, displayInfo: DisplayInfo }} Purse + * @typedef {{ pursePetname: string, brandPetname: string, value: import('@agoric/ertp/src/types-module').AmountValue, displayInfo: import('@agoric/ertp/src/types-module').DisplayInfo }} Purse */ const isNatPurse = ({ displayInfo: { assetKind } }) => diff --git a/packages/ui-components/src/display/display.js b/packages/ui-components/src/display/display.js index 5e6d7b908d4..061feeca12d 100644 --- a/packages/ui-components/src/display/display.js +++ b/packages/ui-components/src/display/display.js @@ -1,21 +1,20 @@ // @ts-check -import { assert, details } from '@agoric/assert'; import { AssetKind } from '@agoric/ertp'; -import '@agoric/ertp/exported.js'; - +import { parseAsCopyBag } from './copyBagValue/parseAsCopyBag.js'; +import { stringifyCopyBag } from './copyBagValue/stringifyCopyBag.js'; import { parseAsNat } from './natValue/parseAsNat.js'; import { stringifyNat } from './natValue/stringifyNat.js'; import { parseAsSet } from './setValue/parseAsSet.js'; import { stringifySet } from './setValue/stringifySet.js'; -import { parseAsCopyBag } from './copyBagValue/parseAsCopyBag.js'; -import { stringifyCopyBag } from './copyBagValue/stringifyCopyBag.js'; + +const { details } = assert; /** * * @param {string} str - string to parse as a value - * @param {AssetKind} [assetKind] - assetKind of the value + * @param {import('@agoric/ertp/src/types.js').AssetKind} [assetKind] - assetKind of the value * @param {number} [decimalPlaces] - places to move the decimal to the left - * @returns {AmountValue} + * @returns {import('@agoric/ertp/src/types.js').AmountValue} */ export const parseAsValue = ( str, @@ -36,10 +35,10 @@ export const parseAsValue = ( /** * @param {string} str - string to parse as a value - * @param {Brand} brand - brand to use in the amount - * @param {AssetKind} [assetKind] - assetKind of the value + * @param {import('@agoric/ertp/src/types.js').Brand} brand - brand to use in the amount + * @param {import('@agoric/ertp/src/types.js').AssetKind} [assetKind] - assetKind of the value * @param {number} [decimalPlaces] - places to move the decimal to the left - * @returns {Amount} + * @returns {import('@agoric/ertp/src/types.js').Amount} */ export const parseAsAmount = ( str, @@ -52,8 +51,8 @@ export const parseAsAmount = ( /** * - * @param {AmountValue} value - value to stringify - * @param {AssetKind} [assetKind] - assetKind of the value + * @param {import('@agoric/ertp/src/types.js').AmountValue} value - value to stringify + * @param {import('@agoric/ertp/src/types.js').AssetKind} [assetKind] - assetKind of the value * @param {number} [decimalPlaces] - places to move the decimal to the * right in the string * @param {number} [placesToShow] - places after the decimal to show @@ -66,7 +65,6 @@ export const stringifyValue = ( placesToShow = 2, ) => { if (assetKind === AssetKind.NAT) { - // @ts-expect-error AmountValue is a Nat return stringifyNat(value, decimalPlaces, placesToShow); } if (assetKind === AssetKind.SET) { @@ -98,8 +96,8 @@ export const stringifyPurseValue = purse => { /** * Stringify the value in an amount * - * @param {Amount} amount - * @param {AssetKind} [assetKind] - assetKind of the value + * @param {import('@agoric/ertp/src/types.js').Amount} amount + * @param {import('@agoric/ertp/src/types.js').AssetKind} [assetKind] - assetKind of the value * @param {number} [decimalPlaces] - places to move the decimal to the * right in the string * @param {number} [placesToShow] - places after the decimal to show diff --git a/packages/ui-components/src/display/natValue/stringifyRatioAsFraction.js b/packages/ui-components/src/display/natValue/stringifyRatioAsFraction.js index 66ee71570bf..4cd31b07461 100644 --- a/packages/ui-components/src/display/natValue/stringifyRatioAsFraction.js +++ b/packages/ui-components/src/display/natValue/stringifyRatioAsFraction.js @@ -3,16 +3,13 @@ import { assert } from '@agoric/assert'; import { isNatValue } from '@agoric/ertp'; -// eslint-disable-next-line import/no-extraneous-dependencies -import '@agoric/zoe/exported.js'; - import { stringifyNat } from './stringifyNat.js'; const PLACES_TO_SHOW = 2; /** - * @param {Ratio} ratio - * @param {(brand: Brand) => number | undefined } getDecimalPlaces + * @param {import('./stringifyRatioAsPercent.js').Ratio} ratio + * @param {(brand: import('@agoric/ertp/src/types.js').Brand) => number | undefined } getDecimalPlaces * @param {number} [numPlacesToShow] * @param {number} [denomPlacesToShow] * @returns {string} diff --git a/packages/ui-components/src/display/natValue/stringifyRatioAsPercent.js b/packages/ui-components/src/display/natValue/stringifyRatioAsPercent.js index dceb6587b0d..e3fdd2c004b 100644 --- a/packages/ui-components/src/display/natValue/stringifyRatioAsPercent.js +++ b/packages/ui-components/src/display/natValue/stringifyRatioAsPercent.js @@ -1,17 +1,22 @@ // @ts-check -import { assert, details } from '@agoric/assert'; -import '@agoric/zoe/exported.js'; - import { captureNum } from './helpers/captureNum.js'; import { roundToDecimalPlaces } from './helpers/roundToDecimalPlaces.js'; +const { details } = assert; + const PERCENT_BASE = 100n; const PLACES_TO_SHOW = 0; +/** + * @typedef {object} Ratio + * @property {import('@agoric/ertp/src/types.js').Amount<'nat'>} numerator + * @property {import('@agoric/ertp/src/types.js').Amount<'nat'>} denominator + */ + /** * @param {Ratio} ratio - * @param {(brand: Brand) => number | undefined } getDecimalPlaces + * @param {(brand: import('@agoric/ertp/src/types.js').Brand) => number | undefined } getDecimalPlaces * @param {number} [placesToShow] * @returns {string} */ diff --git a/packages/ui-components/src/index.js b/packages/ui-components/src/index.js index 393b2d3b95d..b63c7983450 100644 --- a/packages/ui-components/src/index.js +++ b/packages/ui-components/src/index.js @@ -1,3 +1,6 @@ +// @ts-check +/// + /* eslint-disable import/no-unresolved */ export { default as makeNatAmountInput } from './components/NatAmountInput.js'; // eslint-disable-next-line import/no-unresolved diff --git a/packages/vat-data/src/far-class-utils.js b/packages/vat-data/src/far-class-utils.js index 0c627c67558..a61615336f6 100644 --- a/packages/vat-data/src/far-class-utils.js +++ b/packages/vat-data/src/far-class-utils.js @@ -1,3 +1,4 @@ +// @ts-check import { initEmpty } from '@agoric/store'; import { provideKindHandle } from './kind-utils.js'; @@ -11,7 +12,8 @@ import { /** @template L,R @typedef {import('@endo/eventual-send').RemotableBrand} RemotableBrand */ /** @template T @typedef {import('@endo/eventual-send').ERef} ERef */ -/** @typedef {import('@agoric/store').InterfaceGuard} InterfaceGuard */ +// FIXME import InterfaceGuard from @agoric/store +/** @typedef {*} InterfaceGuard */ /** @typedef {import('./types.js').Baggage} Baggage */ /** @template T @typedef {import('./types.js').DefineKindOptions} DefineKindOptions */ /** @template T @typedef {import('./types.js').KindFacet} KindFacet */ @@ -197,6 +199,8 @@ export const vivifyFarInstance = ( options, ); + // eslint-disable-next-line @typescript-eslint/prefer-ts-expect-error -- https://github.com/Agoric/agoric-sdk/issues/4620 + // @ts-ignore could be instantiated with an arbitrary type return provide(baggage, `the_${kindName}`, () => makeSingleton()); }; harden(vivifyFarInstance); diff --git a/packages/vat-data/src/index.js b/packages/vat-data/src/index.js index 4d5c7bc0432..0e41ced012c 100644 --- a/packages/vat-data/src/index.js +++ b/packages/vat-data/src/index.js @@ -1,3 +1,4 @@ +// @ts-check /// export * from './vat-data-bindings.js'; export * from './kind-utils.js'; diff --git a/packages/vat-data/src/kind-utils.js b/packages/vat-data/src/kind-utils.js index 9062e8a0ec2..33a3fc66cd8 100644 --- a/packages/vat-data/src/kind-utils.js +++ b/packages/vat-data/src/kind-utils.js @@ -1,3 +1,4 @@ +// @ts-check import { provide, defineDurableKind, diff --git a/packages/wallet/api/src/findOrMakeInvitation.js b/packages/wallet/api/src/findOrMakeInvitation.js index 0959c058747..0a9c5723095 100644 --- a/packages/wallet/api/src/findOrMakeInvitation.js +++ b/packages/wallet/api/src/findOrMakeInvitation.js @@ -1,3 +1,4 @@ +// @ts-check import { assert, details as X, q } from '@agoric/assert'; import { E } from '@endo/eventual-send'; import { passStyleOf } from '@endo/marshal'; @@ -19,11 +20,11 @@ const assertFirstCapASCII = str => { }; /** - * @param {Amount} invitationPurseBalance + * @param {Amount<'set'>} invitationPurseBalance * @param {object} query * @param {Board} query.board * @param {string} query.boardId - * @returns {Array} + * @returns {Promise} * @deprecated */ const findByBoardId = async (invitationPurseBalance, { board, boardId }) => { @@ -40,7 +41,7 @@ const findByBoardId = async (invitationPurseBalance, { board, boardId }) => { // An invitation matching the query parameters is already expected // to be deposited in the default Zoe invitation purse /** - * @param {Amount} invitationPurseBalance + * @param {Amount<'set'>} invitationPurseBalance * @param {Record} kvs */ const findByKeyValuePairs = async (invitationPurseBalance, kvs) => { diff --git a/packages/wallet/ui/package.json b/packages/wallet/ui/package.json index 963ddf13178..d0b96cd78b1 100644 --- a/packages/wallet/ui/package.json +++ b/packages/wallet/ui/package.json @@ -66,7 +66,7 @@ "build:ses": "cp ../../../node_modules/ses/dist/lockdown.umd.js public/", "build:react": "react-app-rewired build", "lint": "run-s --continue-on-error lint:*", - "lint:types": "tsc --maxNodeModuleJsDepth 3 -p jsconfig.json", + "lint:types": "tsc --maxNodeModuleJsDepth 0 -p jsconfig.json", "lint:eslint": "eslint '**/*.{js,jsx}'", "lint-fix": "yarn lint:eslint --fix", "test": "CI=true react-app-rewired test", diff --git a/packages/wallet/ui/src/contexts/Provider.jsx b/packages/wallet/ui/src/contexts/Provider.jsx index 158c365df1c..0d2e1277ee0 100644 --- a/packages/wallet/ui/src/contexts/Provider.jsx +++ b/packages/wallet/ui/src/contexts/Provider.jsx @@ -126,6 +126,7 @@ const Provider = ({ children }) => { const [issuers, setIssuers] = useReducer(issuersReducer, null); const [issuerSuggestions, setIssuerSuggestions] = useState(null); const [services, setServices] = useState(null); + /** @type {any} */ const [backend, setBackend] = useState(null); const [schemaActions, setSchemaActions] = useState(null); const [connectionComponent, setConnectionComponent] = useState(null); @@ -274,7 +275,6 @@ const Provider = ({ children }) => { throw e; } }; - // @ts-expect-error backend may be null setSchemaActions(E.get(backend).actions); for (const [prop, setter] of backendSetters.entries()) { const iterator = E.get(backend)[prop]; @@ -289,7 +289,6 @@ const Provider = ({ children }) => { }).catch(rethrowIfNotCancelled); } - // @ts-expect-error backend may be null const issuerSuggestionsNotifier = E.get(backend).issuerSuggestions; observeIterator(issuerSuggestionsNotifier, { fail: rethrowIfNotCancelled, diff --git a/packages/wallet/ui/src/index.jsx b/packages/wallet/ui/src/index.jsx index 783a6fc2436..682f3cfdd48 100644 --- a/packages/wallet/ui/src/index.jsx +++ b/packages/wallet/ui/src/index.jsx @@ -1,5 +1,8 @@ +// @ts-check +/// import '@endo/eventual-send/shim'; +import React from 'react'; import ReactDOM from 'react-dom'; import { BrowserRouter as Router } from 'react-router-dom'; import { @@ -24,6 +27,7 @@ const appTheme = createTheme({ success: { main: 'rgb(76, 175, 80)', }, + // @ts-expect-error unknown property cancel: { main: '#595959', }, diff --git a/packages/zoe/src/contractFacet/types.js b/packages/zoe/src/contractFacet/types.js index eb5487c7f8b..8938c3b7874 100644 --- a/packages/zoe/src/contractFacet/types.js +++ b/packages/zoe/src/contractFacet/types.js @@ -1,3 +1,4 @@ +// @ts-check /// // XXX can be tighter than 'any' @@ -39,7 +40,7 @@ * @property {(issuer: Issuer) => Brand} getBrandForIssuer * @property {(brand: Brand) => Issuer} getIssuerForBrand * @property {GetAssetKindByBrand} getAssetKind - * @property {(keyword: Keyword, assetKind?: K, displayInfo?: AdditionalDisplayInfo) => Promise>} makeZCFMint + * @property {(keyword: Keyword, assetKind?: K, displayInfo?: AdditionalDisplayInfo) => Promise>} makeZCFMint * @property {ZCFRegisterFeeMint} registerFeeMint * @property {ZCFMakeEmptySeatKit} makeEmptySeatKit * @property {SetTestJig} setTestJig @@ -85,8 +86,13 @@ */ /** - * @template {object} [OR=unknown] OR is OfferResult - * @callback MakeInvitation + * @typedef {( + * offerHandler: OfferHandler, + * description: string, + * customProperties?: object, + * proposalShape?: Pattern, + * ) => Promise>> + * } MakeInvitation * * Make a credible Zoe invitation for a particular smart contract * indicated by the `instance` in the details of the invitation. Zoe @@ -97,12 +103,11 @@ * getting in the `customProperties`. `customProperties` will be * placed in the details of the invitation. * - * @param {OfferHandler} offerHandler - a contract specific function + * @param offerHandler - a contract specific function * that handles the offer, such as saving it or performing a trade - * @param {string} description - * @param {object=} customProperties - * @param {Pattern} [proposalShape] - * @returns {Promise>} + * @param description + * @param [customProperties] + * @param [proposalShape] */ /** @@ -110,7 +115,7 @@ * @param {Keyword} keyword * @param {FeeMintAccess} allegedFeeMintAccess - an object that * purports to be the object that grants access to the fee mint - * @returns {Promise + * @returns {Promise>} */ /** @@ -218,12 +223,15 @@ /** * API for a contract start function. - * FIXME before merge: assumes synchronous * - * @template {object} [PF] Public facet - * @template {object} [CF] Creator facet - * @template {object} [CT] Custom terms - * @template {object} [PA] Private args + * CAVEAT: assumes synchronous + * + * @deprecated define function signature directly + * + * @template {object} [PF=any] Public facet + * @template {object} [CF=any] Creator facet + * @template {object} [CT=any] Custom terms + * @template {object} [PA=any] Private args * @callback ContractStartFn * @param {ZCF} zcf * @param {PA} privateArgs diff --git a/packages/zoe/src/contractFacet/zcfZygote.js b/packages/zoe/src/contractFacet/zcfZygote.js index 42d3917a5e5..4af02ee4232 100644 --- a/packages/zoe/src/contractFacet/zcfZygote.js +++ b/packages/zoe/src/contractFacet/zcfZygote.js @@ -150,6 +150,7 @@ export const makeZCFZygote = async ( assetKind, displayInfo, ); + // @ts-expect-error could be instantiated with a different subtype return zcfMintFactory.makeZCFMintInternal(keyword, zoeMint); }; @@ -161,6 +162,7 @@ export const makeZCFZygote = async ( keyword, feeMintAccess, ); + // @ts-expect-error could be instantiated with a different subtype return zcfMintFactory.makeZCFMintInternal(keyword, zoeMint); }; @@ -182,6 +184,7 @@ export const makeZCFZygote = async ( return record; }, makeInvitation: ( + // @ts-expect-error xxx arbitrary subtype offerHandler = Far('default offer handler', () => {}), description, customProperties = harden({}), diff --git a/packages/zoe/src/contractSupport/statistics.js b/packages/zoe/src/contractSupport/statistics.js index 5ea2ed8fbe7..932cdb9e387 100644 --- a/packages/zoe/src/contractSupport/statistics.js +++ b/packages/zoe/src/contractSupport/statistics.js @@ -1,3 +1,4 @@ +// @ts-check /** * @template T * @typedef {object} TypedMath diff --git a/packages/zoe/src/contractSupport/zoeHelpers.js b/packages/zoe/src/contractSupport/zoeHelpers.js index 6f828fc5bca..b53727d61d9 100644 --- a/packages/zoe/src/contractSupport/zoeHelpers.js +++ b/packages/zoe/src/contractSupport/zoeHelpers.js @@ -293,7 +293,7 @@ const reverse = (keywordRecord = {}) => { * @param {ZCF} zcf * Zoe Contract Facet for contractA * - * @param {ERef>} invitation + * @param {ERef>} invitation * Invitation to contractB * * @param {KeywordKeywordRecord=} keywordMapping diff --git a/packages/zoe/src/contracts/callSpread/types.js b/packages/zoe/src/contracts/callSpread/types.js index 158d723fbb9..409e8e3f9fb 100644 --- a/packages/zoe/src/contracts/callSpread/types.js +++ b/packages/zoe/src/contracts/callSpread/types.js @@ -1,3 +1,4 @@ +// @ts-check /** * @typedef {'long' | 'short'} PositionKind */ diff --git a/packages/zoe/src/contracts/loan/types.js b/packages/zoe/src/contracts/loan/types.js index 6526f4a4445..74ec24e7069 100644 --- a/packages/zoe/src/contracts/loan/types.js +++ b/packages/zoe/src/contracts/loan/types.js @@ -1,3 +1,4 @@ +// @ts-check /** * @typedef {Notifier} PeriodNotifier * diff --git a/packages/zoe/src/contracts/otcDesk.js b/packages/zoe/src/contracts/otcDesk.js index 4147ebca83c..9d7fba4a974 100644 --- a/packages/zoe/src/contracts/otcDesk.js +++ b/packages/zoe/src/contracts/otcDesk.js @@ -66,7 +66,7 @@ const start = zcf => { * @returns {Promise} */ const makeQuote = async (price, assets, timeAuthority, deadline) => { - /** @type {{ creatorInvitation: Invitation} } */ + /** @type {{ creatorInvitation: Invitation} } */ const { creatorInvitation } = await E(zoe).startInstance( coveredCallInstallation, zcf.getTerms().issuers, @@ -84,6 +84,7 @@ const start = zcf => { }, }); + /** @type {{ userSeatPromise: Promise>}} */ const { userSeatPromise: coveredCallUserSeat } = await offerTo( zcf, creatorInvitation, diff --git a/packages/zoe/src/contracts/priceAggregatorTypes.js b/packages/zoe/src/contracts/priceAggregatorTypes.js index 18129083e6c..67187fe244e 100644 --- a/packages/zoe/src/contracts/priceAggregatorTypes.js +++ b/packages/zoe/src/contracts/priceAggregatorTypes.js @@ -1,3 +1,4 @@ +// @ts-check /** * @typedef {object} OracleAdmin * @property {() => Promise} delete diff --git a/packages/zoe/src/contracts/types.js b/packages/zoe/src/contracts/types.js index c1df139ad2c..b1e8dee0269 100644 --- a/packages/zoe/src/contracts/types.js +++ b/packages/zoe/src/contracts/types.js @@ -1,3 +1,4 @@ +// @ts-check /** * @typedef {object} SellItemsPublicFacet * @property {() => Issuer} getItemsIssuer diff --git a/packages/zoe/src/types.js b/packages/zoe/src/types.js index 7b6bfe65e66..b0e17137c12 100644 --- a/packages/zoe/src/types.js +++ b/packages/zoe/src/types.js @@ -1,3 +1,4 @@ +// @ts-check /// /** @@ -29,8 +30,9 @@ * @property {Installation} installation * @property {Instance} instance * @property {AnyTerms} terms - contract parameters - - * + */ + +/** * @template {AssetKind} [K=AssetKind] * @typedef {object} IssuerRecord * @property {Brand} brand @@ -39,11 +41,10 @@ * @property {any} [displayInfo] * * @typedef {AmountKeywordRecord} Allocation - * @typedef {Record} AmountMathKeywordRecord */ /** - * @template [OfferArgs] - * @template [OfferResult] + * @template {object} [R=unknown] Offer result + * @template {object} [A=never] Offer args * @typedef {Payment<'set'>} Invitation */ diff --git a/packages/zoe/src/zoeService/offer/offer.js b/packages/zoe/src/zoeService/offer/offer.js index bcc87071b7c..2bd217890cd 100644 --- a/packages/zoe/src/zoeService/offer/offer.js +++ b/packages/zoe/src/zoeService/offer/offer.js @@ -82,6 +82,7 @@ export const makeOfferMethod = ( offerArgs, ); // AWAIT /// + // @ts-expect-error cast return userSeat; }; return offer; diff --git a/packages/zoe/src/zoeService/types.js b/packages/zoe/src/zoeService/types.js index 0dcd4ab02c9..3f670008b92 100644 --- a/packages/zoe/src/zoeService/types.js +++ b/packages/zoe/src/zoeService/types.js @@ -1,3 +1,4 @@ +// @ts-check /// /** @@ -48,7 +49,7 @@ * code breaks. * @property {GetConfiguration} getConfiguration * @property {GetBundleIDFromInstallation} getBundleIDFromInstallation - * @property {GetProposalShapeForInvitation} getProposalShapeForInvitation + * @property {(invitationHandle: InvitationHandle) => Pattern | undefined} getProposalShapeForInvitation */ /** @@ -151,13 +152,18 @@ * Verify that an alleged Invitation is real, and return the Bundle ID it * will use for contract code. * - * @param {ERef} + * @param {ERef} allegedInstallation * @returns {Promise} */ /** - * @template {object} [OR=any] - * @callback Offer + * @typedef {( + * invitation: ERef>, + * proposal?: Proposal, + * paymentKeywordRecord?: PaymentPKeywordRecord, + * offerArgs?: A, + * ) => Promise> + * } Offer * * To redeem an invitation, the user normally provides a proposal (their * rules for the offer) as well as payments to be escrowed by Zoe. If @@ -172,12 +178,6 @@ * `paymentKeywordRecord` is a record with keywords as keys, and the * values are the actual payments to be escrowed. A payment is * expected for every rule under `give`. - * - * @param {ERef>} invitation - * @param {Proposal=} proposal - * @param {PaymentPKeywordRecord=} paymentKeywordRecord - * @param {object=} offerArgs - * @returns {Promise>} seat */ /** diff --git a/packages/zoe/test/unitTests/contracts/test-priceAggregatorChainlink.js b/packages/zoe/test/unitTests/contracts/test-priceAggregatorChainlink.js index 51abcfd8361..ac410bb0aa4 100644 --- a/packages/zoe/test/unitTests/contracts/test-priceAggregatorChainlink.js +++ b/packages/zoe/test/unitTests/contracts/test-priceAggregatorChainlink.js @@ -1,6 +1,6 @@ -// @ts-nocheck +// @ts-check // eslint-disable-next-line import/no-extraneous-dependencies -import { test } from '@agoric/zoe/tools/prepare-test-env-ava.js'; +import { test as unknownTest } from '@agoric/zoe/tools/prepare-test-env-ava.js'; import path from 'path'; @@ -17,6 +17,9 @@ import buildManualTimer from '../../../tools/manualTimer.js'; import '../../../exported.js'; import '../../../src/contracts/exported.js'; +/** @type {import('ava').TestFn} */ +const test = unknownTest; + /** * @callback MakeFakePriceOracle * @param {ExecutionContext} t @@ -42,8 +45,9 @@ const oraclePath = `${dirname}/../../../src/contracts/oracle.js`; const aggregatorPath = `${dirname}/../../../src/contracts/priceAggregatorChainlink.js`; test.before( + // comment to maintain formatting for git blame 'setup aggregator and oracles', - /** @param {ExecutionContext} ot */ async ot => { + async ot => { // Outside of tests, we should use the long-lived Zoe on the // testnet. In this test, we must create a new Zoe. const { admin, vatAdminState } = makeFakeVatAdmin(); @@ -73,6 +77,7 @@ test.before( /** @type {OracleHandler} */ const oracleHandler = Far('OracleHandler', { async onQuery({ increment }, _fee) { + // @ts-expect-error xxx valueOut += increment; return harden({ reply: `${valueOut}`, @@ -134,7 +139,7 @@ test.before( }, ); -test('basic', /** @param {ExecutionContext} t */ async t => { +test('basic', async t => { const { makeFakePriceOracle, zoe } = t.context; const maxSubmissionCount = 1000; @@ -211,7 +216,7 @@ test('basic', /** @param {ExecutionContext} t */ async t => { t.deepEqual(round3Attempt1.answer, 5000n); }); -test('timeout', /** @param {ExecutionContext} t */ async t => { +test('timeout', async t => { const { makeFakePriceOracle, zoe } = t.context; const maxSubmissionCount = 1000; @@ -281,7 +286,7 @@ test('timeout', /** @param {ExecutionContext} t */ async t => { t.deepEqual(round3Attempt1.answer, 2000n); }); -test('issue check', /** @param {ExecutionContext} t */ async t => { +test('issue check', async t => { const { makeFakePriceOracle, zoe } = t.context; const maxSubmissionCount = 1000; @@ -339,7 +344,7 @@ test('issue check', /** @param {ExecutionContext} t */ async t => { t.deepEqual(round2Attempt1.answer, 2000n); }); -test('supersede', /** @param {ExecutionContext} t */ async t => { +test('supersede', async t => { const { makeFakePriceOracle, zoe } = t.context; const maxSubmissionCount = 1000; @@ -405,7 +410,7 @@ test('supersede', /** @param {ExecutionContext} t */ async t => { } }); -test('interleaved', /** @param {ExecutionContext} t */ async t => { +test('interleaved', async t => { const { makeFakePriceOracle, zoe } = t.context; const maxSubmissionCount = 3; @@ -543,7 +548,7 @@ test('interleaved', /** @param {ExecutionContext} t */ async t => { t.deepEqual(round6Attempt1.answer, 5000n); }); -test('larger', /** @param {ExecutionContext} t */ async t => { +test('larger', async t => { const { makeFakePriceOracle, zoe } = t.context; const maxSubmissionCount = 1000; @@ -626,7 +631,7 @@ test('larger', /** @param {ExecutionContext} t */ async t => { t.deepEqual(round2Attempt1.answer, 600n); }); -test('suggest', /** @param {ExecutionContext} t */ async t => { +test('suggest', async t => { const { makeFakePriceOracle, zoe } = t.context; const maxSubmissionCount = 1000; diff --git a/packages/zoe/test/unitTests/test-fakePriceAuthority.js b/packages/zoe/test/unitTests/test-fakePriceAuthority.js index 2c185fb0a7d..1965df99d52 100644 --- a/packages/zoe/test/unitTests/test-fakePriceAuthority.js +++ b/packages/zoe/test/unitTests/test-fakePriceAuthority.js @@ -130,6 +130,7 @@ test('priceAuthority quoteWhenGTE', async t => { .quoteWhenGTE(moola(1n), bucks(40n)) .then(quote => { const quoteInAmount = quote.quoteAmount.value[0]; + // @ts-expect-error could be TimestampRecord t.is(4n, manualTimer.getCurrentTimestamp()); t.is(4n, quoteInAmount.timestamp); assertAmountsEqual(t, bucks(40n), quoteInAmount.amountOut); @@ -156,6 +157,7 @@ test('priceAuthority quoteWhenLT', async t => { .quoteWhenLT(moola(1n), bucks(30n)) .then(quote => { const quoteInAmount = quote.quoteAmount.value[0]; + // @ts-expect-error could be TimestampRecord t.is(3n, manualTimer.getCurrentTimestamp()); t.is(3n, quoteInAmount.timestamp); assertAmountsEqual(t, bucks(29n), quoteInAmount.amountOut); @@ -181,6 +183,7 @@ test('priceAuthority quoteWhenGT', async t => { .quoteWhenGT(moola(1n), bucks(40n)) .then(quote => { const quoteInAmount = quote.quoteAmount.value[0]; + // @ts-expect-error could be TimestampRecord t.is(3n, manualTimer.getCurrentTimestamp()); t.is(3n, quoteInAmount.timestamp); assertAmountsEqual(t, bucks(41n), quoteInAmount.amountOut); @@ -207,6 +210,7 @@ test('priceAuthority quoteWhenLTE', async t => { .then(quote => { const quoteInAmount = quote.quoteAmount.value[0]; t.is(4n, quoteInAmount.timestamp); + // @ts-expect-error could be TimestampRecord t.is(4n, manualTimer.getCurrentTimestamp()); assertAmountsEqual(t, bucks(25n), quoteInAmount.amountOut); assertAmountsEqual(t, moola(1n), quoteInAmount.amountIn); diff --git a/packages/zoe/test/unitTests/test-manualTimer.js b/packages/zoe/test/unitTests/test-manualTimer.js index d0306ef7ace..0d229fc43a1 100644 --- a/packages/zoe/test/unitTests/test-manualTimer.js +++ b/packages/zoe/test/unitTests/test-manualTimer.js @@ -23,6 +23,7 @@ test('manualTimer makeNotifier', async t => { await Promise.resolve(); await manualTimer.tick(); const update2 = await p2; + // @ts-expect-error could be TimestampRecord t.truthy(BigInt(update2.updateCount) > BigInt(update1.updateCount)); t.truthy(update2.value > update1.value); }); diff --git a/packages/zoe/test/unitTests/zcf/test-zcf.js b/packages/zoe/test/unitTests/zcf/test-zcf.js index ea04fb202c8..7ffc08cae9b 100644 --- a/packages/zoe/test/unitTests/zcf/test-zcf.js +++ b/packages/zoe/test/unitTests/zcf/test-zcf.js @@ -769,7 +769,7 @@ test(`zcfSeat.isOfferSafe from zcf.makeEmptySeatKit`, async t => { * @param {Keyword} zcfMintKeyword * @param {ZCFSeat} zcfSeat * @param {Keyword} gainsKeyword - * @param {AmountValue} gainsValue + * @param {bigint} gainsValue * @returns {Promise} */ const allocateEasy = async ( diff --git a/packages/zoe/tools/internal-types.js b/packages/zoe/tools/internal-types.js index 325d196a9c5..8cb41ab2fb7 100644 --- a/packages/zoe/tools/internal-types.js +++ b/packages/zoe/tools/internal-types.js @@ -1,3 +1,4 @@ +// @ts-check /** * @typedef {object} ManualTimerAdmin * @property {(msg?: string) => Promise} tick @@ -5,9 +6,5 @@ */ /** - * @typedef { import('@agoric/swingset-vat').ManualTimer } SwingSetManualTimer - */ - -/** - * @typedef {ManualTimerAdmin & SwingSetManualTimer} ManualTimer + * @typedef {TimerService & ManualTimerAdmin} ManualTimer */ diff --git a/packages/zoe/tools/types.js b/packages/zoe/tools/types.js index d79c243ed5c..57e3e519b97 100644 --- a/packages/zoe/tools/types.js +++ b/packages/zoe/tools/types.js @@ -1,3 +1,4 @@ +// @ts-check /** * @typedef {object} PriceQuote * @property {Amount<'set'>} quoteAmount