@agoric/ertp 0.16.3-u19.2 → 0.16.3-u21.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,15 +1,15 @@
1
1
  {
2
2
  "name": "@agoric/ertp",
3
- "version": "0.16.3-u19.2",
3
+ "version": "0.16.3-u21.0",
4
4
  "description": "Electronic Rights Transfer Protocol (ERTP). A smart contract framework for exchanging electronic rights",
5
5
  "type": "module",
6
6
  "main": "src/index.js",
7
7
  "engines": {
8
- "node": "^18.12 || ^20.9"
8
+ "node": "^20.9 || ^22.11"
9
9
  },
10
10
  "scripts": {
11
11
  "build": "exit 0",
12
- "prepack": "tsc --build tsconfig.build.json",
12
+ "prepack": "yarn run -T tsc --build tsconfig.build.json",
13
13
  "postpack": "git clean -f '*.d.ts*' '*.tsbuildinfo'",
14
14
  "test": "ava",
15
15
  "test:c8": "c8 --all $C8_OPTIONS ava",
@@ -17,9 +17,9 @@
17
17
  "test:xs-unit": "exit 0",
18
18
  "test:xs-worker": "SWINGSET_WORKER_TYPE=xs-worker ava -c 2 test/swingsetTests",
19
19
  "lint-fix": "yarn lint:eslint --fix",
20
- "lint": "run-s --continue-on-error lint:*",
21
- "lint:eslint": "eslint .",
22
- "lint:types": "tsc"
20
+ "lint": "yarn run -T run-s --continue-on-error 'lint:*'",
21
+ "lint:eslint": "yarn run -T eslint .",
22
+ "lint:types": "yarn run -T tsc"
23
23
  },
24
24
  "repository": {
25
25
  "type": "git",
@@ -39,21 +39,22 @@
39
39
  },
40
40
  "homepage": "https://github.com/Agoric/agoric-sdk#readme",
41
41
  "dependencies": {
42
- "@agoric/notifier": "^0.7.0-u19.2",
43
- "@agoric/store": "^0.9.3-u19.0",
44
- "@agoric/vat-data": "^0.5.3-u19.2",
45
- "@agoric/zone": "^0.3.0-u19.2",
46
- "@endo/errors": "^1.2.9",
47
- "@endo/eventual-send": "^1.3.0",
48
- "@endo/far": "^1.1.10",
49
- "@endo/marshal": "^1.6.3",
50
- "@endo/nat": "^5.0.14",
51
- "@endo/patterns": "^1.4.8",
52
- "@endo/promise-kit": "^1.1.9"
42
+ "@agoric/notifier": "workspace:*",
43
+ "@agoric/store": "workspace:*",
44
+ "@agoric/vat-data": "workspace:*",
45
+ "@agoric/zone": "workspace:*",
46
+ "@endo/errors": "^1.2.10",
47
+ "@endo/eventual-send": "^1.3.1",
48
+ "@endo/far": "^1.1.11",
49
+ "@endo/marshal": "^1.6.4",
50
+ "@endo/nat": "^5.1.0",
51
+ "@endo/patterns": "^1.5.0",
52
+ "@endo/promise-kit": "^1.1.10"
53
53
  },
54
54
  "devDependencies": {
55
- "@agoric/swingset-vat": "^0.33.0-u19.2",
56
- "@endo/bundle-source": "^3.5.1",
55
+ "@agoric/swingset-vat": "workspace:*",
56
+ "@agoric/xsnap": "workspace:*",
57
+ "@endo/bundle-source": "^4.0.0",
57
58
  "@fast-check/ava": "^1.1.5",
58
59
  "ava": "^5.3.0",
59
60
  "tsd": "^0.31.1"
@@ -77,7 +78,7 @@
77
78
  "access": "public"
78
79
  },
79
80
  "typeCoverage": {
80
- "atLeast": 91.77
81
+ "atLeast": 93.1
81
82
  },
82
- "gitHead": "f0ae74b84cb6de3724bfdcd18b4bea7e8199dee1"
83
+ "gitHead": "e4dd46857133403d584bcf822a81817b355532f9"
83
84
  }
@@ -9,9 +9,9 @@ export namespace AssetKind {
9
9
  let COPY_BAG: "copyBag";
10
10
  }
11
11
  export function assertAssetKind(allegedAK: AssetKind): void;
12
- export function assertValueGetHelpers<V>(value: V): MathHelpers<V>;
12
+ export function assertValueGetHelpers<V extends AmountValue>(value: V): MathHelpers<V>;
13
13
  export namespace AmountMath {
14
- export function make<B extends Brand, V extends NatValue | CopySet | CopyBag | SetValue>(brand: B, allegedValue: V): B extends Brand<"nat"> ? NatAmount : V extends NatValue ? NatAmount : V extends CopySet ? CopySetAmount<V["payload"][0]> : V extends CopyBag ? CopyBagAmount<V["payload"][0][0]> : V extends SetValue ? SetAmount<V[0]> : never;
14
+ export function make<B extends Brand<any>, V extends NatValue | CopySet | CopyBag | SetValue>(brand: B, allegedValue: V): B extends Brand<"nat"> ? NatAmount : V extends NatValue ? NatAmount : V extends CopySet ? CopySetAmount<V["payload"][0]> : V extends CopyBag ? CopyBagAmount<V["payload"][0][0]> : V extends SetValue ? SetAmount<V[0]> : never;
15
15
  export function coerce<A extends Amount>(brand: Brand, allegedAmount: A): A;
16
16
  export function getValue<A extends Amount>(brand: Brand, amount: A): A["value"];
17
17
  export let makeEmpty: {
@@ -27,7 +27,8 @@ export namespace AmountMath {
27
27
  export function min<A extends Amount>(x: A, y: A, brand?: Brand): A;
28
28
  export function max<A extends Amount>(x: A, y: A, brand?: Brand): A;
29
29
  }
30
- export function getAssetKind(amount: Amount): "copySet" | "set" | "nat" | "copyBag";
30
+ export function getAssetKind(amount: Amount): "copySet" | "copyBag" | "set" | "nat";
31
+ import type { AmountValue } from './types.js';
31
32
  import type { MathHelpers } from './types.js';
32
33
  import type { Brand } from './types.js';
33
34
  import type { NatValue } from './types.js';
@@ -1 +1 @@
1
- {"version":3,"file":"amountMath.d.ts","sourceRoot":"","sources":["amountMath.js"],"names":[],"mappings":";;;wBAkBU,CAAC,OAAO,SAAS,EAAE,MAAM,OAAO,SAAS,CAAC;;;;;;;AAY7C,2CADK,SAAS,QAIpB;AA8EM,sCAJM,CAAC,SACH,CAAC,GACC,YAAY,CAAC,CAAC,CAIc;;IAsGjC,qBAhBe,CAAC,SAAT,KAAO,EACmC,CAAC,SAA1C,QAAQ,GAAG,OAAO,GAAG,OAAO,GAAG,QAAS,SAC3C,CAAC,gBACD,CAAC,GACC,CAAC,SAAS,MAAM,KAAK,CAAC,GAC1B,SAAS,GACT,CAAC,SAAS,QAAQ,GAChB,SAAS,GACT,CAAC,SAAS,OAAO,GACf,cAAc,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,GAC9B,CAAC,SAAS,OAAO,GACf,cAAc,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GACjC,CAAC,SAAS,QAAQ,GAChB,UAAU,CAAC,CAAC,CAAC,CAAC,CAAC,GACf,KAAK,CAQrB;IAUO,uBALc,CAAC,SAAV,MAAQ,SACV,KAAK,iBACL,CAAC,GACC,CAAC,CAWb;IASS,yBALY,CAAC,SAAV,MAAQ,SACV,KAAK,UACL,CAAC,GACC,CAAC,CAAC,OAAO,CAAC,CAE4C;0BAKzD;QACT,CAAK,KAAK,EAAE,KAAK,GAAG,OAAO,KAAK,CAAC,CAAC;QAClC,CAAK,CAAC,SAAS,SAAS,EAAE,KAAK,EAAE,MAAM,CAAC,CAAC,EAAE,SAAS,EAAE,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC;KACjE;IAiBiB,oCAJC,CAAC,SAAV,MAAQ,UACV,CAAC,GACC,CAAC,CAQb;IAQQ,gCAJE,MAAM,UACN,KAAK,GACH,OAAO,CASnB;;IAYQ,wBANa,CAAC,SAAV,MAAQ,cACV,CAAC,eACD,CAAC,UACD,KAAK,GACH,OAAO,CAKnB;IAcI,oBANiB,CAAC,SAAV,MAAQ,cACV,CAAC,eACD,CAAC,UACD,KAAK,GACH,CAAC,CAOb;IAeS,yBAPY,CAAC,SAAV,MAAQ,EACC,CAAC,SAAV,MAAQ,cACV,CAAC,eACD,CAAC,UACD,KAAK,GACH,CAAC,SAAS,CAAC,GAAG,CAAC,GAAG,KAAK,CAOnC;IAUI,oBANiB,CAAC,SAAV,MAAQ,KACV,CAAC,KACD,CAAC,UACD,KAAK,GACH,CAAC,CAQ8B;IAUvC,oBANiB,CAAC,SAAV,MAAQ,KACV,CAAC,KACD,CAAC,UACD,KAAK,GACH,CAAC,CAQ8B;;AAKvC,qCADK,MAAM,yCAKjB;iCA3XuI,YAAY;2BAAZ,YAAY;8BAAZ,YAAY;6BADjH,gBAAgB;6BAAhB,gBAAgB;8BACqF,YAAY;+BAAZ,YAAY;mCAAZ,YAAY;mCAAZ,YAAY;+BAAZ,YAAY;4BAAZ,YAAY;AA0JpJ;;;;;;;;;;;;GAYG;AACH,uBANyB,CAAC,SAAZ,SAAU,cACb,OAAO,CAAC,CAAC,eACT,OAAO,CAAC,CAAC,UACT,MAAM,CAAC,CAAC,GACN,OAAO,CAKnB"}
1
+ {"version":3,"file":"amountMath.d.ts","sourceRoot":"","sources":["amountMath.js"],"names":[],"mappings":";;;wBAkBU,CAAC,OAAO,SAAS,EAAE,MAAM,OAAO,SAAS,CAAC;;;;;;;AAY7C,2CADK,SAAS,QAIpB;AA8EM,sCAJoB,CAAC,SAAf,WAAa,SACf,CAAC,GACC,YAAY,CAAC,CAAC,CAIc;;IAwGjC,qBAhBoB,CAAC,SAAd,MAAO,GAAG,CAAE,EAC8B,CAAC,SAA1C,QAAQ,GAAG,OAAO,GAAG,OAAO,GAAG,QAAS,SAC3C,CAAC,gBACD,CAAC,GACC,CAAC,SAAS,MAAM,KAAK,CAAC,GAC1B,SAAS,GACT,CAAC,SAAS,QAAQ,GAChB,SAAS,GACT,CAAC,SAAS,OAAO,GACf,cAAc,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,GAC9B,CAAC,SAAS,OAAO,GACf,cAAc,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GACjC,CAAC,SAAS,QAAQ,GAChB,UAAU,CAAC,CAAC,CAAC,CAAC,CAAC,GACf,KAAK,CAQrB;IAUO,uBALc,CAAC,SAAV,MAAQ,SACV,KAAK,iBACL,CAAC,GACC,CAAC,CAWb;IASS,yBALY,CAAC,SAAV,MAAQ,SACV,KAAK,UACL,CAAC,GACC,CAAC,CAAC,OAAO,CAAC,CAE4C;0BAKzD;QACT,CAAK,KAAK,EAAE,KAAK,GAAG,OAAO,KAAK,CAAC,CAAC;QAClC,CAAK,CAAC,SAAS,SAAS,EAAE,KAAK,EAAE,MAAM,CAAC,CAAC,EAAE,SAAS,EAAE,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC;KACjE;IAiBiB,oCAJC,CAAC,SAAV,MAAQ,UACV,CAAC,GACC,CAAC,CAQb;IAQQ,gCAJE,MAAM,UACN,KAAK,GACH,OAAO,CASnB;;IAYQ,wBANa,CAAC,SAAV,MAAQ,cACV,CAAC,eACD,CAAC,UACD,KAAK,GACH,OAAO,CAKnB;IAcI,oBANiB,CAAC,SAAV,MAAQ,cACV,CAAC,eACD,CAAC,UACD,KAAK,GACH,CAAC,CAOb;IAeS,yBAPY,CAAC,SAAV,MAAQ,EACC,CAAC,SAAV,MAAQ,cACV,CAAC,eACD,CAAC,UACD,KAAK,GACH,CAAC,SAAS,CAAC,GAAG,CAAC,GAAG,KAAK,CAOnC;IAUI,oBANiB,CAAC,SAAV,MAAQ,KACV,CAAC,KACD,CAAC,UACD,KAAK,GACH,CAAC,CAQ8B;IAUvC,oBANiB,CAAC,SAAV,MAAQ,KACV,CAAC,KACD,CAAC,UACD,KAAK,GACH,CAAC,CAQ8B;;AAKvC,qCADK,MAAM,yCAKjB;iCA7XoJ,YAAY;iCAAZ,YAAY;2BAAZ,YAAY;8BAAZ,YAAY;6BAD9H,gBAAgB;6BAAhB,gBAAgB;8BACkG,YAAY;+BAAZ,YAAY;mCAAZ,YAAY;mCAAZ,YAAY;+BAAZ,YAAY;4BAAZ,YAAY;AA4JjK;;;;;;;;;;;;GAYG;AACH,uBANyB,CAAC,SAAZ,SAAU,cACb,OAAO,CAAC,CAAC,eACT,OAAO,CAAC,CAAC,UACT,MAAM,CAAC,CAAC,GACN,OAAO,CAKnB"}
package/src/amountMath.js CHANGED
@@ -9,7 +9,7 @@ import { copyBagMathHelpers } from './mathHelpers/copyBagMathHelpers.js';
9
9
 
10
10
  /**
11
11
  * @import {CopyBag, CopySet} from '@endo/patterns';
12
- * @import {Amount, AssetValueForKind, Brand, CopyBagAmount, CopySetAmount, MathHelpers, NatAmount, NatValue, SetAmount, SetValue} from './types.js';
12
+ * @import {Amount, AmountValue, AssetValueForKind, Brand, CopyBagAmount, CopySetAmount, MathHelpers, NatAmount, NatValue, SetAmount, SetValue} from './types.js';
13
13
  */
14
14
 
15
15
  // NB: AssetKind is both a constant for enumerated values and a type for those values.
@@ -105,7 +105,7 @@ const assertValueGetAssetKind = value => {
105
105
  *
106
106
  * Made available only for testing, but it is harmless for other uses.
107
107
  *
108
- * @template V
108
+ * @template {AmountValue} V
109
109
  * @param {V} value
110
110
  * @returns {MathHelpers<V>}
111
111
  */
@@ -113,7 +113,9 @@ export const assertValueGetHelpers = value =>
113
113
  // @ts-expect-error cast
114
114
  helpers[assertValueGetAssetKind(value)];
115
115
 
116
- /** @type {(allegedBrand: Brand, brand?: Brand) => void} */
116
+ /**
117
+ * @type {(allegedBrand: Brand<any>, brand?: Brand<any>) => void}
118
+ */
117
119
  const optionalBrandCheck = (allegedBrand, brand) => {
118
120
  if (brand !== undefined) {
119
121
  assertRemotable(brand, 'brand');
@@ -156,7 +158,7 @@ const checkLRAndGetHelpers = (leftAmount, rightAmount, brand = undefined) => {
156
158
  * @param {MathHelpers<AssetValueForKind<K>>} h
157
159
  * @param {Amount<K>} leftAmount
158
160
  * @param {Amount<K>} rightAmount
159
- * @returns {[K, K]}
161
+ * @returns {[AssetValueForKind<K>, AssetValueForKind<K>]}
160
162
  */
161
163
  const coerceLR = (h, leftAmount, rightAmount) => {
162
164
  // @ts-expect-error could be arbitrary subtype
@@ -197,7 +199,7 @@ export const AmountMath = {
197
199
  *
198
200
  * Does not verify that the Brand's AssetKind matches the value's.
199
201
  *
200
- * @template {Brand} B
202
+ * @template {Brand<any>} B
201
203
  * @template {NatValue | CopySet | CopyBag | SetValue} V
202
204
  * @param {B} brand
203
205
  * @param {V} allegedValue
@@ -1,8 +1,8 @@
1
- export function upgradeIssuerKit<K extends AssetKind>(issuerBaggage: import("@agoric/vat-data").Baggage, optShutdownWithFailure?: ShutdownWithFailure, recoverySetsOption?: RecoverySetsOption): IssuerKit<K>;
2
- export function hasIssuer(baggage: import("@agoric/vat-data").Baggage): boolean;
3
- export function makeDurableIssuerKit<K extends AssetKind>(issuerBaggage: import("@agoric/vat-data").Baggage, name: string, assetKind?: K, displayInfo?: AdditionalDisplayInfo, optShutdownWithFailure?: ShutdownWithFailure, { elementShape, recoverySetsOption }?: IssuerOptionsRecord): IssuerKit<K>;
4
- export function prepareIssuerKit<O extends IssuerOptionsRecord, K extends AssetKind>(issuerBaggage: import("@agoric/vat-data").Baggage, name: string, assetKind?: K, displayInfo?: AdditionalDisplayInfo, optShutdownWithFailure?: ShutdownWithFailure, options?: O): O["elementShape"] extends TypedPattern<infer T> ? IssuerKit<K, T> : IssuerKit<K>;
5
- export function makeIssuerKit<K extends AssetKind = "nat", O extends IssuerOptionsRecord = {}>(name: string, assetKind?: K, displayInfo?: AdditionalDisplayInfo, optShutdownWithFailure?: ShutdownWithFailure, { elementShape, recoverySetsOption }?: O): O["elementShape"] extends TypedPattern<infer T> ? IssuerKit<K, T> : IssuerKit<K>;
1
+ export function upgradeIssuerKit<K extends AssetKind>(issuerBaggage: Baggage, optShutdownWithFailure?: ShutdownWithFailure, recoverySetsOption?: RecoverySetsOption): IssuerKit<K>;
2
+ export function hasIssuer(baggage: Baggage): boolean;
3
+ export function makeDurableIssuerKit<K extends AssetKind>(issuerBaggage: Baggage, name: string, assetKind?: K, displayInfo?: AdditionalDisplayInfo, optShutdownWithFailure?: ShutdownWithFailure, { elementShape, recoverySetsOption }?: IssuerOptionsRecord): IssuerKit<K>;
4
+ export function prepareIssuerKit<O extends IssuerOptionsRecord, K extends AssetKind>(issuerBaggage: Baggage, name: string, assetKind?: K, displayInfo?: AdditionalDisplayInfo, optShutdownWithFailure?: ShutdownWithFailure, options?: O): O["elementShape"] extends TypedPattern<infer T extends Key> ? IssuerKit<K, T> : IssuerKit<K>;
5
+ export function makeIssuerKit<K extends AssetKind = "nat", O extends IssuerOptionsRecord = {}>(name: string, assetKind?: K, displayInfo?: AdditionalDisplayInfo, optShutdownWithFailure?: ShutdownWithFailure, { elementShape, recoverySetsOption }?: O): O["elementShape"] extends TypedPattern<infer T extends Key> ? IssuerKit<K, T> : IssuerKit<K>;
6
6
  export type IssuerRecord<K extends AssetKind> = {
7
7
  name: string;
8
8
  assetKind: K;
@@ -28,9 +28,12 @@ export type IssuerOptionsRecord = Partial<{
28
28
  recoverySetsOption: RecoverySetsOption;
29
29
  }>;
30
30
  import { AssetKind } from './amountMath.js';
31
+ import type { Baggage } from '@agoric/vat-data';
31
32
  import type { ShutdownWithFailure } from '@agoric/swingset-vat';
32
33
  import type { RecoverySetsOption } from './types.js';
33
34
  import type { IssuerKit } from './types.js';
34
35
  import type { AdditionalDisplayInfo } from './types.js';
36
+ import type { Key } from '@endo/patterns';
35
37
  import type { TypedPattern } from '@agoric/internal';
38
+ import type { Pattern } from '@endo/patterns';
36
39
  //# sourceMappingURL=issuerKit.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"issuerKit.d.ts","sourceRoot":"","sources":["issuerKit.js"],"names":[],"mappings":"AA+GO,iCAbkB,CAAC,SAAZ,SAAU,iBACb,OAAO,kBAAkB,EAAE,OAAO,2BAClC,mBAAmB,uBAOnB,kBAAkB,GAEhB,UAAU,CAAC,CAAC,CA4BxB;AAQM,mCAFI,OAAO,kBAAkB,EAAE,OAAO,WAEgB;AAoDtD,qCA1BkB,CAAC,SAAZ,SAAU,iBAYb,OAAO,kBAAkB,EAAE,OAAO,QAClC,MAAM,cACN,CAAC,gBACD,qBAAqB,2BACrB,mBAAmB,yCAOnB,mBAAmB,GACjB,UAAU,CAAC,CAAC,CA2BxB;AAoCM,iCA7B4B,CAAC,SAAtB,mBAAoB,EACT,CAAC,SAAZ,SAAU,iBAYb,OAAO,kBAAkB,EAAE,OAAO,QAClC,MAAM,cACN,CAAC,gBACD,qBAAqB,2BACrB,mBAAmB,YAOnB,CAAC,GACC,CAAC,CAAC,cAAc,CAAC,SAAS,aAAa,MAAM,CAAC,CAAC,GACnD,UAAU,CAAC,EAAE,CAAC,CAAC,GACf,UAAU,CAAC,CAAC,CAyCpB;AAqCM,8BAzBmB,CAAC,SAAb,SAAU,UACY,CAAC,SAAvB,mBAAoB,aACvB,MAAM,cAMN,CAAC,gBAGD,qBAAqB,2BAErB,mBAAmB,yCAOnB,CAAC,GACC,CAAC,CAAC,cAAc,CAAC,SAAS,aAAa,MAAM,CAAC,CAAC,GACnD,UAAU,CAAC,EAAE,CAAC,CAAC,GACf,UAAU,CAAC,CAAC,CAmBlB;yBA7UsB,CAAC,SAAZ,SAAU;UAEV,MAAM;eACN,CAAC;iBACD,qBAAqB;kBACrB,OAAO;;;;;;;;;;;;;;;;kCA0IR,OAAO,CAAC;IAChB,YAAY,EAAE,OAAO,CAAC;IACtB,kBAAkB,EAAE,kBAAkB,CAAC;CACxC,CAAC;0BA7JsC,iBAAiB;yCAMtB,sBAAsB;wCAD0B,YAAY;+BAAZ,YAAY;2CAAZ,YAAY;kCAEnE,kBAAkB"}
1
+ {"version":3,"file":"issuerKit.d.ts","sourceRoot":"","sources":["issuerKit.js"],"names":[],"mappings":"AAkHO,iCAbkB,CAAC,SAAZ,SAAU,iBACb,OAAO,2BACP,mBAAmB,uBAOnB,kBAAkB,GAEhB,UAAU,CAAC,CAAC,CA4BxB;AAQM,mCAFI,OAAO,WAE2C;AAoDtD,qCA1BkB,CAAC,SAAZ,SAAU,iBAYb,OAAO,QACP,MAAM,cACN,CAAC,gBACD,qBAAqB,2BACrB,mBAAmB,yCAOnB,mBAAmB,GACjB,UAAU,CAAC,CAAC,CA2BxB;AAoCM,iCA7B4B,CAAC,SAAtB,mBAAoB,EACT,CAAC,SAAZ,SAAU,iBAYb,OAAO,QACP,MAAM,cACN,CAAC,gBACD,qBAAqB,2BACrB,mBAAmB,YAOnB,CAAC,GACC,CAAC,CAAC,cAAc,CAAC,SAAS,aAAa,MAAM,CAAC,SAAS,GAAG,CAAC,GAC/D,UAAU,CAAC,EAAE,CAAC,CAAC,GACf,UAAU,CAAC,CAAC,CAyCpB;AAqCM,8BAzBmB,CAAC,SAAb,SAAU,UACY,CAAC,SAAvB,mBAAoB,aACvB,MAAM,cAMN,CAAC,gBAGD,qBAAqB,2BAErB,mBAAmB,yCAOnB,CAAC,GACC,CAAC,CAAC,cAAc,CAAC,SAAS,aAAa,MAAM,CAAC,SAAS,GAAG,CAAC,GAC/D,UAAU,CAAC,EAAE,CAAC,CAAC,GACf,UAAU,CAAC,CAAC,CAmBlB;yBA7UsB,CAAC,SAAZ,SAAU;UAEV,MAAM;eACN,CAAC;iBACD,qBAAqB;kBACrB,OAAO;;;;;;;;;;;;;;;;kCA0IR,OAAO,CAAC;IAChB,YAAY,EAAE,OAAO,CAAC;IACtB,kBAAkB,EAAE,kBAAkB,CAAC;CACxC,CAAC;0BAhKsC,iBAAiB;6BASlC,kBAAkB;yCAFN,sBAAsB;wCAG0B,YAAY;+BAAZ,YAAY;2CAAZ,YAAY;yBALnE,gBAAgB;kCAGhB,kBAAkB;6BAHlB,gBAAgB"}
package/src/issuerKit.js CHANGED
@@ -10,9 +10,12 @@ import { coerceDisplayInfo } from './displayInfo.js';
10
10
  import { preparePaymentLedger } from './paymentLedger.js';
11
11
 
12
12
  /**
13
- * @import {AdditionalDisplayInfo, RecoverySetsOption, IssuerKit, PaymentLedger} from './types.js';
13
+ * @import {Key, Pattern} from '@endo/patterns';
14
+ * @import {Zone} from '@agoric/base-zone';
14
15
  * @import {ShutdownWithFailure} from '@agoric/swingset-vat';
15
16
  * @import {TypedPattern} from '@agoric/internal';
17
+ * @import {Baggage} from '@agoric/vat-data';
18
+ * @import {AdditionalDisplayInfo, RecoverySetsOption, IssuerKit, PaymentLedger} from './types.js';
16
19
  */
17
20
 
18
21
  /**
@@ -29,7 +32,7 @@ import { preparePaymentLedger } from './paymentLedger.js';
29
32
  *
30
33
  * @template {AssetKind} K
31
34
  * @param {IssuerRecord<K>} issuerRecord
32
- * @param {import('@agoric/zone').Zone} issuerZone
35
+ * @param {Zone} issuerZone
33
36
  * @param {RecoverySetsOption} recoverySetsState Omitted from issuerRecord
34
37
  * because it was added in an upgrade.
35
38
  * @param {ShutdownWithFailure} [optShutdownWithFailure] If this issuer fails in
@@ -97,7 +100,7 @@ const RECOVERY_SETS_STATE = 'recoverySetsState';
97
100
  * make a new one.
98
101
  *
99
102
  * @template {AssetKind} K
100
- * @param {import('@agoric/vat-data').Baggage} issuerBaggage
103
+ * @param {Baggage} issuerBaggage
101
104
  * @param {ShutdownWithFailure} [optShutdownWithFailure] If this issuer fails in
102
105
  * the middle of an atomic action (which btw should never happen), it
103
106
  * potentially leaves its ledger in a corrupted state. If this function was
@@ -141,7 +144,7 @@ harden(upgradeIssuerKit);
141
144
  /**
142
145
  * Does baggage already have an issuerKit?
143
146
  *
144
- * @param {import('@agoric/vat-data').Baggage} baggage
147
+ * @param {Baggage} baggage
145
148
  */
146
149
  export const hasIssuer = baggage => baggage.has(INSTANCE_KEY);
147
150
 
@@ -181,7 +184,7 @@ export const hasIssuer = baggage => baggage.has(INSTANCE_KEY);
181
184
  * basic fungible tokens.
182
185
  *
183
186
  * `displayInfo` gives information to the UI on how to display the amount.
184
- * @param {import('@agoric/vat-data').Baggage} issuerBaggage
187
+ * @param {Baggage} issuerBaggage
185
188
  * @param {string} name
186
189
  * @param {K} [assetKind]
187
190
  * @param {AdditionalDisplayInfo} [displayInfo]
@@ -240,7 +243,7 @@ harden(makeDurableIssuerKit);
240
243
  * basic fungible tokens.
241
244
  *
242
245
  * `displayInfo` gives information to the UI on how to display the amount.
243
- * @param {import('@agoric/vat-data').Baggage} issuerBaggage
246
+ * @param {Baggage} issuerBaggage
244
247
  * @param {string} name
245
248
  * @param {K} [assetKind]
246
249
  * @param {AdditionalDisplayInfo} [displayInfo]
@@ -252,7 +255,7 @@ harden(makeDurableIssuerKit);
252
255
  * anything else is corrupted by that corrupted state. See
253
256
  * https://github.com/Agoric/agoric-sdk/issues/3434
254
257
  * @param {O} [options]
255
- * @returns {O['elementShape'] extends TypedPattern<infer T>
258
+ * @returns {O['elementShape'] extends TypedPattern<infer T extends Key>
256
259
  * ? IssuerKit<K, T>
257
260
  * : IssuerKit<K>}
258
261
  */
@@ -328,7 +331,7 @@ harden(prepareIssuerKit);
328
331
  * anything else is corrupted by that corrupted state. See
329
332
  * https://github.com/Agoric/agoric-sdk/issues/3434
330
333
  * @param {O} [options]
331
- * @returns {O['elementShape'] extends TypedPattern<infer T>
334
+ * @returns {O['elementShape'] extends TypedPattern<infer T extends Key>
332
335
  * ? IssuerKit<K, T>
333
336
  * : IssuerKit<K>}
334
337
  */
@@ -7,5 +7,6 @@ import type { Key } from '@endo/patterns';
7
7
  import type { Purse } from './types.js';
8
8
  import type { ERef } from '@endo/far';
9
9
  import type { Payment } from './types.js';
10
+ import type { Pattern } from '@endo/patterns';
10
11
  import type { Amount } from './types.js';
11
12
  //# sourceMappingURL=legacy-payment-helpers.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"legacy-payment-helpers.d.ts","sourceRoot":"","sources":["legacy-payment-helpers.js"],"names":[],"mappings":"AAmCO,sBAPkB,CAAC,SAAb,SAAW,EACL,CAAC,SAAP,GAAK,iBACP,KAAK,MAAM,CAAC,EAAE,CAAC,CAAC,CAAC,eACjB,KAAK,QAAQ,CAAC,EAAE,CAAC,CAAC,CAAC,mBACnB,OAAO,GACL,OAAO,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,CAAC,CAWlC;AAkBM,wBAPkB,CAAC,SAAb,SAAW,EACL,CAAC,SAAP,GAAK,iBACP,KAAK,MAAM,CAAC,EAAE,CAAC,CAAC,CAAC,iBACjB,KAAK,QAAQ,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,mBACrB,OAAO,GACL,OAAO,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,CAAC,CA8BlC;AAgBM,sBANkB,CAAC,SAAb,SAAW,iBACb,KAAK,MAAM,CAAC,CAAC,CAAC,eACd,KAAK,QAAQ,CAAC,CAAC,CAAC,kBAChB,OAAO,CAAC,CAAC,GACP,OAAO,CAAC,QAAQ,CAAC,CAAC,EAAE,CAAC,CAYjC;AAgBM,0BANkB,CAAC,SAAb,SAAW,iBACb,KAAK,MAAM,CAAC,CAAC,CAAC,eACd,KAAK,QAAQ,CAAC,CAAC,CAAC,WAChB,OAAO,CAAC,CAAC,EAAE,GACT,OAAO,CAAC,OAAO,EAAE,CAAC,CAoB9B;+BA5ImD,YAAY;yBAD1C,gBAAgB;2BACc,YAAY;0BAFzC,WAAW;6BAEkB,YAAY;4BAAZ,YAAY"}
1
+ {"version":3,"file":"legacy-payment-helpers.d.ts","sourceRoot":"","sources":["legacy-payment-helpers.js"],"names":[],"mappings":"AAmCO,sBAPkB,CAAC,SAAb,SAAW,EACL,CAAC,SAAP,GAAK,iBACP,KAAK,MAAM,CAAC,EAAE,CAAC,CAAC,CAAC,eACjB,KAAK,QAAQ,CAAC,EAAE,CAAC,CAAC,CAAC,mBACnB,OAAO,GACL,OAAO,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,CAAC,CAWlC;AAkBM,wBAPkB,CAAC,SAAb,SAAW,EACL,CAAC,SAAP,GAAK,iBACP,KAAK,MAAM,CAAC,EAAE,CAAC,CAAC,CAAC,iBACjB,KAAK,QAAQ,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,mBACrB,OAAO,GACL,OAAO,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,CAAC,CA8BlC;AAgBM,sBANkB,CAAC,SAAb,SAAW,iBACb,KAAK,MAAM,CAAC,CAAC,CAAC,eACd,KAAK,QAAQ,CAAC,CAAC,CAAC,kBAChB,OAAO,CAAC,CAAC,GACP,OAAO,CAAC,QAAQ,CAAC,CAAC,EAAE,CAAC,CAYjC;AAgBM,0BANkB,CAAC,SAAb,SAAW,iBACb,KAAK,MAAM,CAAC,CAAC,CAAC,eACd,KAAK,QAAQ,CAAC,CAAC,CAAC,WAChB,OAAO,CAAC,CAAC,EAAE,GACT,OAAO,CAAC,OAAO,EAAE,CAAC,CAoB9B;+BA5ImD,YAAY;yBADjC,gBAAgB;2BACK,YAAY;0BAFzC,WAAW;6BAEkB,YAAY;6BADjC,gBAAgB;4BACK,YAAY"}
@@ -7,7 +7,7 @@ import { AmountMath } from './amountMath.js';
7
7
 
8
8
  /**
9
9
  * @import {ERef} from '@endo/far';
10
- * @import {Key} from '@endo/patterns';
10
+ * @import {Key, Pattern} from '@endo/patterns';
11
11
  * @import {Amount, AssetKind, Payment, Purse} from './types.js';
12
12
  */
13
13
 
@@ -1,6 +1,8 @@
1
- export function preparePaymentLedger<K extends AssetKind>(issuerZone: import("@agoric/zone").Zone, name: string, assetKind: K, displayInfo: DisplayInfo<K>, elementShape: Pattern, recoverySetsState: RecoverySetsOption, optShutdownWithFailure?: ShutdownWithFailure): PaymentLedger<K>;
1
+ export function preparePaymentLedger<K extends AssetKind>(issuerZone: Zone, name: string, assetKind: K, displayInfo: DisplayInfo<K>, elementShape: Pattern, recoverySetsState: RecoverySetsOption, optShutdownWithFailure?: ShutdownWithFailure): PaymentLedger<K>;
2
2
  import type { AssetKind } from './types.js';
3
+ import type { Zone } from '@agoric/base-zone';
3
4
  import type { DisplayInfo } from './types.js';
5
+ import type { Pattern } from '@endo/patterns';
4
6
  import type { RecoverySetsOption } from './types.js';
5
7
  import type { ShutdownWithFailure } from '@agoric/swingset-vat';
6
8
  import type { PaymentLedger } from './types.js';
@@ -1 +1 @@
1
- {"version":3,"file":"paymentLedger.d.ts","sourceRoot":"","sources":["paymentLedger.js"],"names":[],"mappings":"AAqFO,qCAVkB,CAAC,SAAb,SAAW,cACb,OAAO,cAAc,EAAE,IAAI,QAC3B,MAAM,aACN,CAAC,eACD,YAAY,CAAC,CAAC,gBACd,OAAO,qBACP,kBAAkB,2BAClB,mBAAmB,GACjB,cAAc,CAAC,CAAC,CAyT5B;+BA9XwH,YAAY;iCAAZ,YAAY;wCAAZ,YAAY;yCAC/F,sBAAsB;mCAD6D,YAAY"}
1
+ {"version":3,"file":"paymentLedger.d.ts","sourceRoot":"","sources":["paymentLedger.js"],"names":[],"mappings":"AAuFO,qCAVkB,CAAC,SAAb,SAAW,cACb,IAAI,QACJ,MAAM,aACN,CAAC,eACD,YAAY,CAAC,CAAC,gBACd,OAAO,qBACP,kBAAkB,2BAClB,mBAAmB,GACjB,cAAc,CAAC,CAAC,CAyT5B;+BA5XwH,YAAY;0BAJ9G,mBAAmB;iCAI+E,YAAY;6BALtG,gBAAgB;wCAK0E,YAAY;yCAF/F,sBAAsB;mCAE6D,YAAY"}
@@ -2,19 +2,21 @@
2
2
 
3
3
  /// <reference types="@agoric/store/exported.js" />
4
4
 
5
- import { X, q, Fail, annotateError } from '@endo/errors';
5
+ import { q, Fail, annotateError, X } from '@endo/errors';
6
6
  import { isPromise } from '@endo/promise-kit';
7
- import { mustMatch, M, keyEQ } from '@agoric/store';
7
+ import { mustMatch, M, keyEQ } from '@endo/patterns';
8
8
  import { AmountMath } from './amountMath.js';
9
9
  import { preparePaymentKind } from './payment.js';
10
10
  import { preparePurseKind } from './purse.js';
11
-
12
11
  import { BrandI, makeIssuerInterfaces } from './typeGuards.js';
13
12
 
14
13
  /**
15
- * @import {Amount, AssetKind, DisplayInfo, PaymentLedger, Payment, Brand, RecoverySetsOption, Purse, Issuer, Mint} from './types.js'
16
- * @import {ShutdownWithFailure} from '@agoric/swingset-vat'
14
+ * @import {Key, Pattern} from '@endo/patterns';
15
+ * @import {Zone} from '@agoric/base-zone';
17
16
  * @import {TypedPattern} from '@agoric/internal';
17
+ * @import {ShutdownWithFailure} from '@agoric/swingset-vat';
18
+ * @import {AmountStore} from './amountStore.js';
19
+ * @import {Amount, AssetKind, DisplayInfo, PaymentLedger, Payment, Brand, RecoverySetsOption, Purse, Issuer, Mint} from './types.js';
18
20
  */
19
21
 
20
22
  /**
@@ -74,7 +76,7 @@ const amountShapeFromElementShape = (brand, assetKind, elementShape) => {
74
76
  * minting and transfer authority originates here.
75
77
  *
76
78
  * @template {AssetKind} K
77
- * @param {import('@agoric/zone').Zone} issuerZone
79
+ * @param {Zone} issuerZone
78
80
  * @param {string} name
79
81
  * @param {K} assetKind
80
82
  * @param {DisplayInfo<K>} displayInfo
@@ -239,7 +241,7 @@ export const preparePaymentLedger = (
239
241
  /**
240
242
  * Used by the purse code to implement purse.deposit
241
243
  *
242
- * @param {import('./amountStore.js').AmountStore} balanceStore
244
+ * @param {AmountStore} balanceStore
243
245
  * @param {Payment} srcPayment
244
246
  * @param {Pattern} [optAmountShape]
245
247
  * @returns {Amount}
@@ -273,7 +275,7 @@ export const preparePaymentLedger = (
273
275
  /**
274
276
  * Used by the purse code to implement purse.withdraw
275
277
  *
276
- * @param {import('./amountStore.js').AmountStore} balanceStore
278
+ * @param {AmountStore} balanceStore
277
279
  * @param {Amount} amount - the amount to be withdrawn
278
280
  * @param {SetStore<Payment>} [recoverySet]
279
281
  * @returns {Payment}
package/src/purse.d.ts CHANGED
@@ -7,14 +7,14 @@ export function preparePurseKind(issuerZone: import("@agoric/zone").Zone, name:
7
7
  }, recoverySetsState: RecoverySetsOption, paymentRecoverySets: WeakMapStore<Payment, SetStore<Payment>>): () => import("@endo/exo").Guarded<{
8
8
  deposit(srcPayment: any, optAmountShape?: undefined): any;
9
9
  withdraw(amount: any): any;
10
- getCurrentAmount(): import("./types.js").NatAmount | import("./types.js").CopySetAmount<import("@endo/patterns").Key> | import("./types.js").SetAmount<import("@endo/patterns").Key> | import("./types.js").CopyBagAmount<import("@endo/patterns").Key>;
10
+ getCurrentAmount(): import("./types.js").NatAmount | import("./types.js").CopySetAmount<import("@endo/patterns").Key> | import("./types.js").CopyBagAmount<import("@endo/patterns").Key> | import("./types.js").SetAmount<import("@endo/patterns").Key>;
11
11
  getCurrentAmountNotifier(): import("@agoric/notifier").Notifier<any>;
12
12
  getAllegedBrand(): Brand;
13
13
  getDepositFacet(): import("@endo/exo").Guarded<{
14
14
  receive(...args: any[]): any;
15
15
  }>;
16
16
  getRecoverySet(): import("@endo/patterns").CopySet<any>;
17
- recoverAll(): import("./types.js").NatAmount | import("./types.js").CopySetAmount<import("@endo/patterns").Key> | import("./types.js").SetAmount<import("@endo/patterns").Key> | import("./types.js").CopyBagAmount<import("@endo/patterns").Key>;
17
+ recoverAll(): import("./types.js").NatAmount | import("./types.js").CopySetAmount<import("@endo/patterns").Key> | import("./types.js").CopyBagAmount<import("@endo/patterns").Key> | import("./types.js").SetAmount<import("@endo/patterns").Key>;
18
18
  }>;
19
19
  import type { AssetKind } from './types.js';
20
20
  import type { Brand } from './types.js';
package/src/ratio.d.ts ADDED
@@ -0,0 +1,48 @@
1
+ export function assertIsRatio(ratio: any): void;
2
+ export function makeRatio(numerator: bigint, numeratorBrand: Brand, denominator?: bigint, denominatorBrand?: Brand): Ratio;
3
+ export function makeRatioFromAmounts(numeratorAmount: Amount, denominatorAmount: Amount): Ratio;
4
+ /** @type {ScaleAmount} */
5
+ export const floorMultiplyBy: ScaleAmount;
6
+ /** @type {ScaleAmount} */
7
+ export const ceilMultiplyBy: ScaleAmount;
8
+ /** @type {ScaleAmount} */
9
+ export const multiplyBy: ScaleAmount;
10
+ /**
11
+ * Divide the amount by the ratio, truncating the remainder.
12
+ *
13
+ * @type {ScaleAmount}
14
+ */
15
+ export const floorDivideBy: ScaleAmount;
16
+ /**
17
+ * Divide the amount by the ratio, rounding up the remainder.
18
+ *
19
+ * @type {ScaleAmount}
20
+ */
21
+ export const ceilDivideBy: ScaleAmount;
22
+ /**
23
+ * Divide the amount by the ratio, rounding to nearest with ties to even (aka
24
+ * Banker's Rounding) as in IEEE 754 default rounding.
25
+ *
26
+ * @type {ScaleAmount}
27
+ */
28
+ export const divideBy: ScaleAmount;
29
+ export function invertRatio(ratio: Ratio): Ratio;
30
+ export function addRatios(left: Ratio, right: Ratio): Ratio;
31
+ export function subtractRatios(left: Ratio, right: Ratio): Ratio;
32
+ export function multiplyRatios(left: Ratio, right: Ratio): Ratio;
33
+ export function oneMinus(ratio: Ratio): Ratio;
34
+ export function ratioGTE(left: Ratio, right: Ratio): boolean;
35
+ export function ratiosSame(left: Ratio, right: Ratio): boolean;
36
+ export function quantize(ratio: Ratio, newDen: bigint): Ratio;
37
+ export function parseRatio(numeric: ParsableNumber, numeratorBrand: Brand<"nat">, denominatorBrand?: Brand<"nat">): Ratio;
38
+ export function assertParsableNumber(specimen: unknown): asserts specimen is ParsableNumber;
39
+ export function ratioToNumber(ratio: Ratio): number;
40
+ export type Ratio = {
41
+ numerator: Amount<"nat">;
42
+ denominator: Amount<"nat">;
43
+ };
44
+ export type ScaleAmount = (amount: Amount<"nat">, ratio: Ratio) => Amount<"nat">;
45
+ export type ParsableNumber = bigint | number | string;
46
+ import type { Brand } from '@agoric/ertp';
47
+ import type { Amount } from '@agoric/ertp';
48
+ //# sourceMappingURL=ratio.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ratio.d.ts","sourceRoot":"","sources":["ratio.js"],"names":[],"mappings":"AAwDO,gDAcN;AASM,qCANI,MAAM,kBACN,KAAK,gBACL,MAAM,qBACN,KAAK,GACH,KAAK,CAejB;AAOM,sDAJI,MAAM,qBACN,MAAM,GACJ,KAAK,CAYjB;AA2BD,0BAA0B;AAC1B,8BADW,WAAW,CAGpB;AAEF,0BAA0B;AAC1B,6BADW,WAAW,CAGpB;AAEF,0BAA0B;AAC1B,yBADW,WAAW,CAGpB;AA2BF;;;;GAIG;AACH,4BAFU,WAAW,CAInB;AAEF;;;;GAIG;AACH,2BAFU,WAAW,CAInB;AAEF;;;;;GAKG;AACH,uBAFU,WAAW,CAInB;AAMK,mCAHI,KAAK,GACH,KAAK,CAWjB;AAOM,gCAJI,KAAK,SACL,KAAK,GACH,KAAK,CAwBjB;AAOM,qCAJI,KAAK,SACL,KAAK,GACH,KAAK,CAmBjB;AAOM,qCAJI,KAAK,SACL,KAAK,GACH,KAAK,CA8BjB;AAQM,gCAHI,KAAK,GACH,KAAK,CAcjB;AAOM,+BAJI,KAAK,SACL,KAAK,GACH,OAAO,CAkBnB;AAUM,iCAJI,KAAK,SACL,KAAK,GACH,OAAO,CAOnB;AAWM,gCAJI,KAAK,UACL,MAAM,GACJ,KAAK,CAiBjB;AAaM,oCALI,cAAc,kBACd,MAAM,KAAK,CAAC,qBACZ,MAAM,KAAK,CAAC,GACV,KAAK,CAmBjB;AAMM,+CAHI,OAAO,GACL,QAAQ,QAAQ,IAAI,cAAc,CAK9C;AAQM,qCAHI,KAAK,GACH,MAAM,CAMlB;;eAxaa,OAAO,KAAK,CAAC;iBACb,OAAO,KAAK,CAAC;;mCAKhB,OAAO,KAAK,CAAC,SACb,KAAK,KACH,OAAO,KAAK,CAAC;6BAgXZ,MAAM,GAAG,MAAM,GAAG,MAAM;2BAhYkB,cAAc;4BAAd,cAAc"}
package/src/ratio.js ADDED
@@ -0,0 +1,441 @@
1
+ import { q, Fail } from '@endo/errors';
2
+ import { assertRecord } from '@endo/marshal';
3
+ import { isNat } from '@endo/nat';
4
+
5
+ import { AmountMath } from './amountMath.js';
6
+ import { natSafeMath } from './safeMath.js';
7
+
8
+ /**
9
+ * @import {Amount, Brand, Issuer, Payment, Purse} from '@agoric/ertp';
10
+ */
11
+
12
+ const { multiply, floorDivide, ceilDivide, bankersDivide, add, subtract } =
13
+ natSafeMath;
14
+
15
+ /**
16
+ * @typedef {object} Ratio
17
+ * @property {Amount<'nat'>} numerator
18
+ * @property {Amount<'nat'>} denominator
19
+ */
20
+
21
+ /**
22
+ * @callback ScaleAmount
23
+ * @param {Amount<'nat'>} amount
24
+ * @param {Ratio} ratio
25
+ * @returns {Amount<'nat'>}
26
+ */
27
+
28
+ // make a Ratio, which represents a fraction. It is a pass-by-copy record.
29
+ //
30
+ // The natural syntax for the most common operations we want to support
31
+ // are Amount * Ratio and Amount / Ratio. Since the operations want to adhere to
32
+ // the ratio rather than the amount, we settled on a calling convention of
33
+ // [ceil|floor]MultiplyBy(Amount, Ratio) and [ceil|floor]DivideBy(Amount, Ratio)
34
+ //
35
+ // The most common kind of Ratio can be applied to Amounts of a particular
36
+ // brand, and produces results of the same brand. This represents a multiplier
37
+ // that is only applicable to that brand. The less common kind of Ratio can be
38
+ // applied to one particular brand of amounts, and produces results of another
39
+ // particular brand. This represents some kind of exchange rate. The
40
+ // brand-checking helps us ensure that normal Ratios aren't applied to amounts
41
+ // of the wrong brand, and that exchange rates are only used in the appropriate
42
+ // direction.
43
+ //
44
+ // Since the ratios are represented by a numerator and a denominator, every
45
+ // multiplication or division operation that produces an amount ends with a
46
+ // division of the underlying bigints, and integer division requires a mode
47
+ // of [rounding to integer](https://en.wikipedia.org/wiki/Rounding#Rounding_to_integer).
48
+ // Because `Ratio` only work with Natural numbers, just three modes suffice:
49
+ // - floor rounds down
50
+ // - ceil rounds up
51
+ // - default (without prefix) minimizes bias by rounding half to even
52
+
53
+ const PERCENT = 100n;
54
+
55
+ const ratioPropertyNames = ['numerator', 'denominator'];
56
+
57
+ export const assertIsRatio = ratio => {
58
+ assertRecord(ratio, 'ratio');
59
+ const keys = Object.keys(ratio);
60
+ keys.length === 2 || Fail`Ratio ${ratio} must be a record with 2 fields.`;
61
+ for (const name of keys) {
62
+ ratioPropertyNames.includes(name) ||
63
+ Fail`Parameter must be a Ratio record, but ${ratio} has ${q(name)}`;
64
+ }
65
+ const numeratorValue = ratio.numerator.value;
66
+ const denominatorValue = ratio.denominator.value;
67
+ isNat(numeratorValue) ||
68
+ Fail`The numerator value must be a NatValue, not ${numeratorValue}`;
69
+ isNat(denominatorValue) ||
70
+ Fail`The denominator value must be a NatValue, not ${denominatorValue}`;
71
+ };
72
+
73
+ /**
74
+ * @param {bigint} numerator
75
+ * @param {Brand} numeratorBrand
76
+ * @param {bigint} [denominator] The default denominator is 100
77
+ * @param {Brand} [denominatorBrand] The default is to reuse the numeratorBrand
78
+ * @returns {Ratio}
79
+ */
80
+ export const makeRatio = (
81
+ numerator,
82
+ numeratorBrand,
83
+ denominator = PERCENT,
84
+ denominatorBrand = numeratorBrand,
85
+ ) => {
86
+ denominator > 0n ||
87
+ Fail`No infinite ratios! Denominator was 0 ${q(denominatorBrand)}`;
88
+
89
+ return harden({
90
+ numerator: AmountMath.make(numeratorBrand, numerator),
91
+ denominator: AmountMath.make(denominatorBrand, denominator),
92
+ });
93
+ };
94
+
95
+ /**
96
+ * @param {Amount} numeratorAmount
97
+ * @param {Amount} denominatorAmount
98
+ * @returns {Ratio}
99
+ */
100
+ export const makeRatioFromAmounts = (numeratorAmount, denominatorAmount) => {
101
+ AmountMath.coerce(numeratorAmount.brand, numeratorAmount);
102
+ AmountMath.coerce(denominatorAmount.brand, denominatorAmount);
103
+ return makeRatio(
104
+ // @ts-expect-error value can be any AmountValue but makeRatio() supports only bigint
105
+ numeratorAmount.value,
106
+ numeratorAmount.brand,
107
+ denominatorAmount.value,
108
+ denominatorAmount.brand,
109
+ );
110
+ };
111
+
112
+ /**
113
+ * @param {Amount<'nat'>} amount
114
+ * @param {Ratio} ratio
115
+ * @param {any} divideOp
116
+ * @returns {Amount<'nat'>}
117
+ */
118
+ const multiplyHelper = (amount, ratio, divideOp) => {
119
+ AmountMath.coerce(amount.brand, amount);
120
+ assertIsRatio(ratio);
121
+ amount.brand === ratio.denominator.brand ||
122
+ Fail`amount's brand ${q(amount.brand)} must match ratio's denominator ${q(
123
+ ratio.denominator.brand,
124
+ )}`;
125
+
126
+ return /** @type {Amount<'nat'>} */ (
127
+ AmountMath.make(
128
+ ratio.numerator.brand,
129
+ divideOp(
130
+ multiply(amount.value, ratio.numerator.value),
131
+ ratio.denominator.value,
132
+ ),
133
+ )
134
+ );
135
+ };
136
+
137
+ /** @type {ScaleAmount} */
138
+ export const floorMultiplyBy = (amount, ratio) => {
139
+ return multiplyHelper(amount, ratio, floorDivide);
140
+ };
141
+
142
+ /** @type {ScaleAmount} */
143
+ export const ceilMultiplyBy = (amount, ratio) => {
144
+ return multiplyHelper(amount, ratio, ceilDivide);
145
+ };
146
+
147
+ /** @type {ScaleAmount} */
148
+ export const multiplyBy = (amount, ratio) => {
149
+ return multiplyHelper(amount, ratio, bankersDivide);
150
+ };
151
+
152
+ /**
153
+ * @param {Amount<'nat'>} amount
154
+ * @param {Ratio} ratio
155
+ * @param {any} divideOp
156
+ * @returns {Amount<'nat'>}
157
+ */
158
+ const divideHelper = (amount, ratio, divideOp) => {
159
+ AmountMath.coerce(amount.brand, amount);
160
+ assertIsRatio(ratio);
161
+ amount.brand === ratio.numerator.brand ||
162
+ Fail`amount's brand ${q(amount.brand)} must match ratio's numerator ${q(
163
+ ratio.numerator.brand,
164
+ )}`;
165
+
166
+ return /** @type {Amount<'nat'>} */ (
167
+ AmountMath.make(
168
+ ratio.denominator.brand,
169
+ divideOp(
170
+ multiply(amount.value, ratio.denominator.value),
171
+ ratio.numerator.value,
172
+ ),
173
+ )
174
+ );
175
+ };
176
+
177
+ /**
178
+ * Divide the amount by the ratio, truncating the remainder.
179
+ *
180
+ * @type {ScaleAmount}
181
+ */
182
+ export const floorDivideBy = (amount, ratio) => {
183
+ return divideHelper(amount, ratio, floorDivide);
184
+ };
185
+
186
+ /**
187
+ * Divide the amount by the ratio, rounding up the remainder.
188
+ *
189
+ * @type {ScaleAmount}
190
+ */
191
+ export const ceilDivideBy = (amount, ratio) => {
192
+ return divideHelper(amount, ratio, ceilDivide);
193
+ };
194
+
195
+ /**
196
+ * Divide the amount by the ratio, rounding to nearest with ties to even (aka
197
+ * Banker's Rounding) as in IEEE 754 default rounding.
198
+ *
199
+ * @type {ScaleAmount}
200
+ */
201
+ export const divideBy = (amount, ratio) => {
202
+ return divideHelper(amount, ratio, bankersDivide);
203
+ };
204
+
205
+ /**
206
+ * @param {Ratio} ratio
207
+ * @returns {Ratio}
208
+ */
209
+ export const invertRatio = ratio => {
210
+ assertIsRatio(ratio);
211
+
212
+ return makeRatio(
213
+ ratio.denominator.value,
214
+ ratio.denominator.brand,
215
+ ratio.numerator.value,
216
+ ratio.numerator.brand,
217
+ );
218
+ };
219
+
220
+ /**
221
+ * @param {Ratio} left
222
+ * @param {Ratio} right
223
+ * @returns {Ratio}
224
+ */
225
+ export const addRatios = (left, right) => {
226
+ assertIsRatio(right);
227
+ assertIsRatio(left);
228
+ left.numerator.brand === right.numerator.brand ||
229
+ Fail`numerator brands must match: ${q(left)} ${q(right)}`;
230
+ left.denominator.brand === right.denominator.brand ||
231
+ Fail`denominator brands must match: ${q(left)} ${q(right)}`;
232
+
233
+ // Simplifying the expression:
234
+ // (and + bnd) / y d**2
235
+ // (a + b) nd / y d**2
236
+ // ((a + b) n / y d) * (d / d)
237
+ // (a + b) n / yd
238
+ return makeRatio(
239
+ add(
240
+ multiply(left.numerator.value, right.denominator.value), // a nd
241
+ multiply(left.denominator.value, right.numerator.value), // b nd
242
+ ), // (a + b) nd
243
+ left.numerator.brand,
244
+ multiply(left.denominator.value, right.denominator.value), // y d**2
245
+ left.denominator.brand,
246
+ );
247
+ };
248
+
249
+ /**
250
+ * @param {Ratio} left
251
+ * @param {Ratio} right
252
+ * @returns {Ratio}
253
+ */
254
+ export const subtractRatios = (left, right) => {
255
+ assertIsRatio(right);
256
+ assertIsRatio(left);
257
+ left.numerator.brand === right.numerator.brand ||
258
+ Fail`numerator brands must match: ${q(left)} ${q(right)}`;
259
+ left.denominator.brand === right.denominator.brand ||
260
+ Fail`denominator brands must match: ${q(left)} ${q(right)}`;
261
+
262
+ return makeRatio(
263
+ subtract(
264
+ multiply(left.numerator.value, right.denominator.value), // a nd
265
+ multiply(left.denominator.value, right.numerator.value), // b nd
266
+ ), // (a - b) nd
267
+ left.numerator.brand,
268
+ multiply(left.denominator.value, right.denominator.value), // y d**2
269
+ left.denominator.brand,
270
+ );
271
+ };
272
+
273
+ /**
274
+ * @param {Ratio} left
275
+ * @param {Ratio} right
276
+ * @returns {Ratio}
277
+ */
278
+ export const multiplyRatios = (left, right) => {
279
+ assertIsRatio(right);
280
+ assertIsRatio(left);
281
+
282
+ const getRemainingBrands = () => {
283
+ // Prefer results that have the same brand as the left operand.
284
+ if (right.numerator.brand === right.denominator.brand) {
285
+ return [left.numerator.brand, left.denominator.brand];
286
+ }
287
+ if (right.numerator.brand === left.denominator.brand) {
288
+ return [left.numerator.brand, right.denominator.brand];
289
+ }
290
+ if (left.numerator.brand === right.denominator.brand) {
291
+ return [right.numerator.brand, left.denominator.brand];
292
+ }
293
+ if (left.numerator.brand === left.denominator.brand) {
294
+ return [right.numerator.brand, right.denominator.brand];
295
+ }
296
+ throw Fail`at least one brand must cancel out: ${q(left)} ${q(right)}`;
297
+ };
298
+
299
+ const [numeratorBrand, denominatorBrand] = getRemainingBrands();
300
+ return makeRatio(
301
+ multiply(left.numerator.value, right.numerator.value),
302
+ numeratorBrand,
303
+ multiply(left.denominator.value, right.denominator.value),
304
+ denominatorBrand,
305
+ );
306
+ };
307
+
308
+ /**
309
+ * If ratio is between 0 and 1, subtract from 1.
310
+ *
311
+ * @param {Ratio} ratio
312
+ * @returns {Ratio}
313
+ */
314
+ export const oneMinus = ratio => {
315
+ assertIsRatio(ratio);
316
+ ratio.numerator.brand === ratio.denominator.brand ||
317
+ Fail`oneMinus only supports ratios with a single brand, but ${ratio.numerator.brand} doesn't match ${ratio.denominator.brand}`;
318
+ ratio.numerator.value <= ratio.denominator.value ||
319
+ Fail`Parameter must be less than or equal to 1: ${ratio.numerator.value}/${ratio.denominator.value}`;
320
+ return makeRatio(
321
+ subtract(ratio.denominator.value, ratio.numerator.value),
322
+ ratio.numerator.brand,
323
+ ratio.denominator.value,
324
+ ratio.numerator.brand,
325
+ );
326
+ };
327
+
328
+ /**
329
+ * @param {Ratio} left
330
+ * @param {Ratio} right
331
+ * @returns {boolean}
332
+ */
333
+ export const ratioGTE = (left, right) => {
334
+ if (left.numerator.brand === right.numerator.brand) {
335
+ left.denominator.brand === right.denominator.brand ||
336
+ Fail`numerator brands match, but denominator brands don't: ${q(left)} ${q(
337
+ right,
338
+ )}`;
339
+ } else if (left.numerator.brand === left.denominator.brand) {
340
+ right.numerator.brand === right.denominator.brand ||
341
+ Fail`lefthand brands match, but righthand brands don't: ${q(left)} ${q(
342
+ right,
343
+ )}`;
344
+ }
345
+ return natSafeMath.isGTE(
346
+ multiply(left.numerator.value, right.denominator.value),
347
+ multiply(right.numerator.value, left.denominator.value),
348
+ );
349
+ };
350
+
351
+ /**
352
+ * True iff the ratios are the same values (equal or equivalant may return
353
+ * false)
354
+ *
355
+ * @param {Ratio} left
356
+ * @param {Ratio} right
357
+ * @returns {boolean}
358
+ */
359
+ export const ratiosSame = (left, right) => {
360
+ return (
361
+ AmountMath.isEqual(left.numerator, right.numerator) &&
362
+ AmountMath.isEqual(left.denominator, right.denominator)
363
+ );
364
+ };
365
+
366
+ /**
367
+ * Make a new ratio with a smaller denominator that approximates the ratio. If
368
+ * the proposed denominator is larger than the current one, return the
369
+ * original.
370
+ *
371
+ * @param {Ratio} ratio
372
+ * @param {bigint} newDen
373
+ * @returns {Ratio}
374
+ */
375
+ export const quantize = (ratio, newDen) => {
376
+ const oldDen = ratio.denominator.value;
377
+ const oldNum = ratio.numerator.value;
378
+ if (newDen > oldDen) {
379
+ return ratio;
380
+ }
381
+
382
+ const newNum =
383
+ newDen === oldDen ? oldNum : bankersDivide(oldNum * newDen, oldDen);
384
+ return makeRatio(
385
+ newNum,
386
+ ratio.numerator.brand,
387
+ newDen,
388
+ ratio.denominator.brand,
389
+ );
390
+ };
391
+
392
+ const NUMERIC_RE = /^(\d\d*)(?:\.(\d*))?$/;
393
+ /** @typedef {bigint | number | string} ParsableNumber */
394
+
395
+ /**
396
+ * Create a ratio from a given numeric value.
397
+ *
398
+ * @param {ParsableNumber} numeric
399
+ * @param {Brand<'nat'>} numeratorBrand
400
+ * @param {Brand<'nat'>} [denominatorBrand]
401
+ * @returns {Ratio}
402
+ */
403
+ export const parseRatio = (
404
+ numeric,
405
+ numeratorBrand,
406
+ denominatorBrand = numeratorBrand,
407
+ ) => {
408
+ const match = `${numeric}`.match(NUMERIC_RE);
409
+ if (!match) {
410
+ throw Fail`Invalid numeric data: ${numeric}`;
411
+ }
412
+
413
+ const [_, whole, part = ''] = match;
414
+ return makeRatio(
415
+ BigInt(`${whole}${part}`),
416
+ numeratorBrand,
417
+ 10n ** BigInt(part.length),
418
+ denominatorBrand,
419
+ );
420
+ };
421
+
422
+ /**
423
+ * @param {unknown} specimen
424
+ * @returns {asserts specimen is ParsableNumber}
425
+ */
426
+ export const assertParsableNumber = specimen => {
427
+ const match = `${specimen}`.match(NUMERIC_RE);
428
+ match || Fail`Invalid numeric data: ${specimen}`;
429
+ };
430
+
431
+ /**
432
+ * Ratios might be greater or less than one.
433
+ *
434
+ * @param {Ratio} ratio
435
+ * @returns {number}
436
+ */
437
+ export const ratioToNumber = ratio => {
438
+ const n = Number(ratio.numerator.value);
439
+ const d = Number(ratio.denominator.value);
440
+ return n / d;
441
+ };
@@ -0,0 +1,11 @@
1
+ export namespace natSafeMath {
2
+ let add: NatOp;
3
+ let subtract: NatOp;
4
+ let multiply: NatOp;
5
+ let floorDivide: NatOp;
6
+ let ceilDivide: NatOp;
7
+ let bankersDivide: NatOp;
8
+ let isGTE: (x: number | bigint, y: number | bigint) => boolean;
9
+ }
10
+ export type NatOp = (x: number | bigint, y: number | bigint) => bigint;
11
+ //# sourceMappingURL=safeMath.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"safeMath.d.ts","sourceRoot":"","sources":["safeMath.js"],"names":[],"mappings":";aAYa,KAAK;kBAGL,KAAK;kBAEL,KAAK;qBAEL,KAAK;oBAEL,KAAK;uBASN,KAAK;eAiBJ,CAAC,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC,EAAE,MAAM,GAAG,MAAM,KAAK,OAAO;;oBA7ClD,CAAC,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC,EAAE,MAAM,GAAG,MAAM,KAAK,MAAM"}
@@ -0,0 +1,50 @@
1
+ import { Nat } from '@endo/nat';
2
+
3
+ /** @typedef {(x: number | bigint, y: number | bigint) => bigint} NatOp */
4
+
5
+ /**
6
+ * These operations should be used for calculations with the values of basic
7
+ * fungible tokens.
8
+ *
9
+ * natSafeMath is designed to be used directly, and so it needs to validate the
10
+ * inputs, as well as the outputs when necessary.
11
+ */
12
+ export const natSafeMath = harden({
13
+ /** @type {NatOp} */
14
+ // BigInts don't observably overflow
15
+ add: (x, y) => Nat(x) + Nat(y),
16
+ /** @type {NatOp} */
17
+ subtract: (x, y) => Nat(Nat(x) - Nat(y)),
18
+ /** @type {NatOp} */
19
+ multiply: (x, y) => Nat(x) * Nat(y),
20
+ /** @type {NatOp} */
21
+ floorDivide: (x, y) => Nat(x) / Nat(y),
22
+ /** @type {NatOp} */
23
+ ceilDivide: (x, y) => {
24
+ y = Nat(y);
25
+ return Nat(Nat(x) + y - 1n) / y;
26
+ },
27
+ /**
28
+ * Divide using half-to-even (aka Banker's Rounding) as in IEEE 774 default
29
+ * rounding
30
+ *
31
+ * @type {NatOp}
32
+ */
33
+ bankersDivide: (a, b) => {
34
+ a = Nat(a);
35
+ b = Nat(b);
36
+
37
+ const div = a / b;
38
+ const rem = a % b;
39
+ // if remainder > half divisor, should have rounded up instead of down, so add 1
40
+ if (rem * 2n > b) {
41
+ return div + 1n;
42
+ } else if (rem * 2n === b) {
43
+ // Add 1 if result is odd to get an even return value
44
+ if (div % 2n === 1n) return div + 1n;
45
+ }
46
+ return div;
47
+ },
48
+ /** @type {(x: number | bigint, y: number | bigint) => boolean} */
49
+ isGTE: (x, y) => Nat(x) >= Nat(y),
50
+ });
@@ -1,6 +1,7 @@
1
1
  /**
2
2
  * @import {AmountValue, Ratio} from './types.js'
3
3
  * @import {TypedPattern} from '@agoric/internal'
4
+ * @import {CopyBag, CopySet, Pattern} from '@endo/patterns';
4
5
  */
5
6
  export const BrandShape: import("@endo/patterns").Matcher;
6
7
  export const IssuerShape: import("@endo/patterns").Matcher;
@@ -85,5 +86,8 @@ declare const AmountValueShape: import("@endo/patterns").Matcher;
85
86
  import type { Ratio } from './types.js';
86
87
  import type { TypedPattern } from '@agoric/internal';
87
88
  import type { AmountValue } from './types.js';
89
+ import type { CopySet } from '@endo/patterns';
90
+ import type { CopyBag } from '@endo/patterns';
91
+ import type { Pattern } from '@endo/patterns';
88
92
  export {};
89
93
  //# sourceMappingURL=typeGuards.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"typeGuards.d.ts","sourceRoot":"","sources":["typeGuards.js"],"names":[],"mappings":"AAGA;;;GAGG;AAEH,0DAA+C;AAC/C,2DAAiD;AACjD,4DAAmD;AACnD,0DAA+C;AAC/C,iEAA6D;AAC7D,6DAAqD;AACrD,yDAA6C;;;;;AAkE7C;;;;;;;;;;GAUG;AACH,kEAA8C;AAE9C,kCAAkC;AAClC,yBADW,aAAa,KAAK,CAAC,CACiD;AASxE,kCAHI,WAAW,GACT,KAAK,IAAI,OAAO,YAAY,EAAE,QAAQ,CAEa;AASzD,sCAHI,WAAW,GACT,KAAK,IAAI,OAAO,CAE2C;AAYjE,kCAHI,WAAW,GACT,KAAK,IAAI,QAAQ,CAEkC;AASzD,sCAHI,WAAW,GACT,KAAK,IAAI,OAAO,CAE2C;AAIxE,0CAA2C,GAAG,CAAC;AAE/C,8DAAuE;AAEvE,gEAaE;;;;;;;;AAaF;;;;;GAKG;AAOI,kDAJI,OAAO,mBACP,OAAO,gBACP,OAAO;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAqEjB;AAhLD,iEAKE;2BAvEmC,YAAY;kCAClB,kBAAkB;iCADZ,YAAY"}
1
+ {"version":3,"file":"typeGuards.d.ts","sourceRoot":"","sources":["typeGuards.js"],"names":[],"mappings":"AAGA;;;;GAIG;AAEH,0DAA+C;AAC/C,2DAAiD;AACjD,4DAAmD;AACnD,0DAA+C;AAC/C,iEAA6D;AAC7D,6DAAqD;AACrD,yDAA6C;;;;;AAkE7C;;;;;;;;;;GAUG;AACH,kEAA8C;AAE9C,kCAAkC;AAClC,yBADW,aAAa,KAAK,CAAC,CACiD;AASxE,kCAHI,WAAW,GACT,KAAK,IAAI,OAAO,YAAY,EAAE,QAAQ,CAEa;AASzD,sCAHI,WAAW,GACT,KAAK,IAAI,OAAO,CAE2C;AAYjE,kCAHI,WAAW,GACT,KAAK,IAAI,QAAQ,CAEkC;AASzD,sCAHI,WAAW,GACT,KAAK,IAAI,OAAO,CAE2C;AAIxE,0CAA2C,GAAG,CAAC;AAE/C,8DAAuE;AAEvE,gEAaE;;;;;;;;AAaF;;;;;GAKG;AAOI,kDAJI,OAAO,mBACP,OAAO,gBACP,OAAO;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAqEjB;AAhLD,iEAKE;2BAxEmC,YAAY;kCAClB,kBAAkB;iCADZ,YAAY;6BAEL,gBAAgB;6BAAhB,gBAAgB;6BAAhB,gBAAgB"}
package/src/typeGuards.js CHANGED
@@ -4,6 +4,7 @@ import { M, matches, getInterfaceGuardPayload } from '@endo/patterns';
4
4
  /**
5
5
  * @import {AmountValue, Ratio} from './types.js'
6
6
  * @import {TypedPattern} from '@agoric/internal'
7
+ * @import {CopyBag, CopySet, Pattern} from '@endo/patterns';
7
8
  */
8
9
 
9
10
  export const BrandShape = M.remotable('Brand');