@agoric/orchestration 0.1.1-dev-699cb28.0.699cb28 → 0.1.1-dev-eb52bc3.0.eb52bc3

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,6 +1,6 @@
1
1
  {
2
2
  "name": "@agoric/orchestration",
3
- "version": "0.1.1-dev-699cb28.0.699cb28",
3
+ "version": "0.1.1-dev-eb52bc3.0.eb52bc3",
4
4
  "description": "Chain abstraction for Agoric's orchestration clients",
5
5
  "type": "module",
6
6
  "main": "index.js",
@@ -35,18 +35,18 @@
35
35
  },
36
36
  "homepage": "https://github.com/Agoric/agoric-sdk#readme",
37
37
  "dependencies": {
38
- "@agoric/async-flow": "0.1.1-dev-699cb28.0.699cb28",
39
- "@agoric/cosmic-proto": "0.4.1-dev-699cb28.0.699cb28",
40
- "@agoric/ertp": "0.16.3-dev-699cb28.0.699cb28",
41
- "@agoric/internal": "0.3.3-dev-699cb28.0.699cb28",
42
- "@agoric/network": "0.1.1-dev-699cb28.0.699cb28",
43
- "@agoric/notifier": "0.6.3-dev-699cb28.0.699cb28",
44
- "@agoric/store": "0.9.3-dev-699cb28.0.699cb28",
45
- "@agoric/time": "0.3.3-dev-699cb28.0.699cb28",
46
- "@agoric/vat-data": "0.5.3-dev-699cb28.0.699cb28",
47
- "@agoric/vow": "0.1.1-dev-699cb28.0.699cb28",
48
- "@agoric/zoe": "0.26.3-dev-699cb28.0.699cb28",
49
- "@agoric/zone": "0.2.3-dev-699cb28.0.699cb28",
38
+ "@agoric/async-flow": "0.1.1-dev-eb52bc3.0.eb52bc3",
39
+ "@agoric/cosmic-proto": "0.4.1-dev-eb52bc3.0.eb52bc3",
40
+ "@agoric/ertp": "0.16.3-dev-eb52bc3.0.eb52bc3",
41
+ "@agoric/internal": "0.3.3-dev-eb52bc3.0.eb52bc3",
42
+ "@agoric/network": "0.1.1-dev-eb52bc3.0.eb52bc3",
43
+ "@agoric/notifier": "0.6.3-dev-eb52bc3.0.eb52bc3",
44
+ "@agoric/store": "0.9.3-dev-eb52bc3.0.eb52bc3",
45
+ "@agoric/time": "0.3.3-dev-eb52bc3.0.eb52bc3",
46
+ "@agoric/vat-data": "0.5.3-dev-eb52bc3.0.eb52bc3",
47
+ "@agoric/vow": "0.1.1-dev-eb52bc3.0.eb52bc3",
48
+ "@agoric/zoe": "0.26.3-dev-eb52bc3.0.eb52bc3",
49
+ "@agoric/zone": "0.2.3-dev-eb52bc3.0.eb52bc3",
50
50
  "@cosmjs/encoding": "^0.36.0",
51
51
  "@endo/base64": "^1.1.1",
52
52
  "@endo/common": "^1.4.0",
@@ -61,9 +61,9 @@
61
61
  "bs58": "^6.0.0"
62
62
  },
63
63
  "devDependencies": {
64
- "@agoric/swingset-liveslots": "0.10.3-dev-699cb28.0.699cb28",
65
- "@agoric/vats": "0.15.2-dev-699cb28.0.699cb28",
66
- "@agoric/xsnap": "0.14.3-dev-699cb28.0.699cb28",
64
+ "@agoric/swingset-liveslots": "0.10.3-dev-eb52bc3.0.eb52bc3",
65
+ "@agoric/vats": "0.15.2-dev-eb52bc3.0.eb52bc3",
66
+ "@agoric/xsnap": "0.14.3-dev-eb52bc3.0.eb52bc3",
67
67
  "@chain-registry/client": "^1.53.194",
68
68
  "@cosmjs/amino": "^0.36.0",
69
69
  "@cosmjs/proto-signing": "^0.36.0",
@@ -100,5 +100,5 @@
100
100
  "typeCoverage": {
101
101
  "atLeast": 96.68
102
102
  },
103
- "gitHead": "699cb2821a0724432ffd6363819f05f20a588f4e"
103
+ "gitHead": "eb52bc371f1d95f517989c49cf30633ba50d9d41"
104
104
  }
@@ -11,8 +11,6 @@ export const DEFAULT_ICQ_VERSION: "icq-1";
11
11
  export function makeICQChannelAddress(controllerConnectionId: IBCConnectionID, version?: string): RemoteIbcAddress;
12
12
  export function findAddressField(remoteAddressString: RemoteIbcAddress): CosmosChainAddress["value"] | undefined;
13
13
  export function getBech32Prefix(address: Bech32Address | string): string;
14
- export function sameEvmAddress(a: EvmAddress, b: EvmAddress | undefined): boolean;
15
- export function isEvmAddressShape(x: unknown): x is EvmAddress;
16
14
  export function coerceAccountId(idArg: AccountIdArg): AccountId;
17
15
  export function parseAccountIdArg(idArg: AccountIdArg): Caip10Record;
18
16
  export function parseAccountId(accountId: AccountId): Caip10Record;
@@ -44,9 +42,11 @@ import type { Bech32Address } from '../types.js';
44
42
  import type { IBCConnectionID } from '@agoric/network/ibc';
45
43
  import type { RemoteIbcAddress } from '@agoric/network/ibc';
46
44
  import type { CosmosChainAddress } from '../types.js';
47
- import type { Address as EvmAddress } from 'viem';
45
+ import { sameEvmAddress } from './evm-address.js';
46
+ import { isEvmAddressShape } from './evm-address.js';
48
47
  import type { AccountIdArg } from '../orchestration-api.js';
49
48
  import type { AccountId } from '../orchestration-api.js';
50
49
  import type { Caip10Record } from '../orchestration-api.js';
51
50
  import type { CaipChainId } from '../types.js';
51
+ export { sameEvmAddress, isEvmAddressShape };
52
52
  //# sourceMappingURL=address.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"address.d.ts","sourceRoot":"","sources":["address.js"],"names":[],"mappings":"AA4OA;;;;;;GAMG;AACH,6CAHW,MAAM,GACJ,QAAQ,OAAO,IAAI,aAAa,CAM5C;AA3NM,wDALI,eAAe,0BACf,eAAe,6CACf,qBAAqB,GACnB,gBAAgB,CA4B5B;AAGD,kCAAmC,OAAO,CAAC;AAOpC,8DAJI,eAAe,YACf,MAAM,GACJ,gBAAgB,CAa5B;AAaM,sDAJI,gBAAgB,GAEd,kBAAkB,CAAC,OAAO,CAAC,GAAG,SAAS,CAYnD;AAaM,yCAHI,aAAa,GAAG,MAAM,GACpB,MAAM,CAQlB;AASM,kCAJI,UAAU,KACV,UAAU,GAAG,SAAS,GACpB,OAAO,CAEwD;AAUrE,qCAHI,OAAO,GACL,CAAC,IAAI,UAAU,CAG6B;AAYlD,uCAJI,YAAY,GAEV,SAAS,CAQrB;AAUM,yCAJI,YAAY,GAEV,YAAY,CAaxB;AASM,0CAHI,SAAS,GACP,YAAY,CAaxB;AAUM,6CAJI,YAAY,GAEV,WAAW,CAKvB;AASM,yCAJI,MAAM,GACJ,OAAO,CAkBnB;AAwBM,uDAFI,MAAM,+BAOhB;AAWM,8CAJI,SAAS,GACP,UAAU,CAatB;;;;;;;;;;;;;;;;;;;;;mCAnRgE,aAAa;qCAF1B,qBAAqB;sCAArB,qBAAqB;wCAER,aAAa;2CADtC,MAAM;kCAEU,yBAAyB;+BAAzB,yBAAyB;kCAAzB,yBAAyB;iCADhB,aAAa"}
1
+ {"version":3,"file":"address.d.ts","sourceRoot":"","sources":["address.js"],"names":[],"mappings":"AA4NA;;;;;;GAMG;AACH,6CAHW,MAAM,GACJ,QAAQ,OAAO,IAAI,aAAa,CAM5C;AA1MM,wDALI,eAAe,0BACf,eAAe,6CACf,qBAAqB,GACnB,gBAAgB,CA4B5B;AAGD,kCAAmC,OAAO,CAAC;AAOpC,8DAJI,eAAe,YACf,MAAM,GACJ,gBAAgB,CAa5B;AAaM,sDAJI,gBAAgB,GAEd,kBAAkB,CAAC,OAAO,CAAC,GAAG,SAAS,CAYnD;AAaM,yCAHI,aAAa,GAAG,MAAM,GACpB,MAAM,CAQlB;AAeM,uCAJI,YAAY,GAEV,SAAS,CAQrB;AAUM,yCAJI,YAAY,GAEV,YAAY,CAaxB;AASM,0CAHI,SAAS,GACP,YAAY,CAaxB;AAUM,6CAJI,YAAY,GAEV,WAAW,CAKvB;AASM,yCAJI,MAAM,GACJ,OAAO,CAkBnB;AAwBM,uDAFI,MAAM,+BAOhB;AAWM,8CAJI,SAAS,GACP,UAAU,CAatB;;;;;;;;;;;;;;;;;;;;;mCAlQgE,aAAa;qCAF1B,qBAAqB;sCAArB,qBAAqB;wCAER,aAAa;+BAL5B,kBAAkB;kCAAlB,kBAAkB;kCAMZ,yBAAyB;+BAAzB,yBAAyB;kCAAzB,yBAAyB;iCADhB,aAAa"}
@@ -2,6 +2,7 @@ import { encodeRemoteIbcAddress } from '@agoric/network/ibc/utils.js';
2
2
  import { fromBech32, fromHex } from '@cosmjs/encoding';
3
3
  import { Fail, q } from '@endo/errors';
4
4
  import bs58 from 'bs58';
5
+ import { isEvmAddressShape, sameEvmAddress } from './evm-address.js';
5
6
 
6
7
  /**
7
8
  * @import {IBCConnectionID, RemoteIbcAddress} from '@agoric/network/ibc';
@@ -117,25 +118,8 @@ export const getBech32Prefix = address => {
117
118
  return address.slice(0, split);
118
119
  };
119
120
 
120
- /**
121
- * Compare two EVM addresses for equality, case-insensitive.
122
- *
123
- * @param {EvmAddress} a
124
- * @param {EvmAddress | undefined} b
125
- * @returns {boolean}
126
- */
127
- export const sameEvmAddress = (a, b) => a.toLowerCase() === b?.toLowerCase();
121
+ export { sameEvmAddress, isEvmAddressShape };
128
122
  harden(sameEvmAddress);
129
-
130
- /**
131
- * Whether `x` has the shape of an EVM address: `0x` followed by 40 hex
132
- * digits, in any casing (an EIP-55 checksum is not verified).
133
- *
134
- * @param {unknown} x
135
- * @returns {x is EvmAddress}
136
- */
137
- export const isEvmAddressShape = x =>
138
- typeof x === 'string' && /^0x[0-9a-fA-F]{40}$/u.test(x);
139
123
  harden(isEvmAddressShape);
140
124
 
141
125
  /**
@@ -35,7 +35,7 @@ import {
35
35
  makeWitness,
36
36
  PermitTransferFromTypeParams,
37
37
  } from './permit2.js';
38
- import { isEvmAddressShape, sameEvmAddress } from './address.js';
38
+ import { isEvmAddressShape, sameEvmAddress } from './evm-address.js';
39
39
  import { normalizeAndValidateEIP712Data } from './viem-utils/eip712-normalize.js';
40
40
 
41
41
  ;
@@ -0,0 +1,4 @@
1
+ export function sameEvmAddress(a: EvmAddress, b: EvmAddress | undefined): boolean;
2
+ export function isEvmAddressShape(x: unknown): x is EvmAddress;
3
+ import type { Address as EvmAddress } from 'viem';
4
+ //# sourceMappingURL=evm-address.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"evm-address.d.ts","sourceRoot":"","sources":["evm-address.js"],"names":[],"mappings":"AAiBO,kCAJI,UAAU,KACV,UAAU,GAAG,SAAS,GACpB,OAAO,CAEwD;AASrE,qCAHI,OAAO,GACL,CAAC,IAAI,UAAU,CAG6B;2CApBjB,MAAM"}
@@ -0,0 +1,28 @@
1
+ /**
2
+ * @file EVM address helpers with no runtime dependencies, so that modules
3
+ * meant to also run outside of a locked-down (SES) environment, such as the
4
+ * EIP-712 message helpers, can use them.
5
+ */
6
+
7
+ /**
8
+ * @import {Address as EvmAddress} from 'viem';
9
+ */
10
+
11
+ /**
12
+ * Compare two EVM addresses for equality, case-insensitive.
13
+ *
14
+ * @param {EvmAddress} a
15
+ * @param {EvmAddress | undefined} b
16
+ * @returns {boolean}
17
+ */
18
+ export const sameEvmAddress = (a, b) => a.toLowerCase() === b?.toLowerCase();
19
+
20
+ /**
21
+ * Whether `x` has the shape of an EVM address: `0x` followed by 40 hex
22
+ * digits, in any casing (an EIP-55 checksum is not verified).
23
+ *
24
+ * @param {unknown} x
25
+ * @returns {x is EvmAddress}
26
+ */
27
+ export const isEvmAddressShape = x =>
28
+ typeof x === 'string' && /^0x[0-9a-fA-F]{40}$/u.test(x);
@@ -0,0 +1,31 @@
1
+ /**
2
+ * @file Helpers for quoting or describing values in e.g. error messages
3
+ * and test descriptions.
4
+ */
5
+ /**
6
+ * Quotes and escapes an identifier (a struct/field type or field name) for
7
+ * embedding in an error message. Escaping via `JSON.stringify` happens
8
+ * *after* truncating and covers the whole (possibly-annotated) result, so
9
+ * an embedded quote, backslash, or newline in the identifier can't break
10
+ * out of the message's own quoting, and the `(N chars total)` annotation
11
+ * can't itself get chopped off by a later truncation step (there isn't
12
+ * one).
13
+ */
14
+ export declare const quoteName: (str: string) => string;
15
+ /**
16
+ * Quotes and escapes each name in `names` (see `quoteName`) and joins them
17
+ * for an error message -- bounding not just each individual name's length
18
+ * but also, since attacker-controlled data can make the *list itself*
19
+ * arbitrarily long (e.g. very many extra fields on a struct), the number of
20
+ * items included. Cuts off whole items rather than slicing the joined
21
+ * string's raw characters, so the result can never end mid-quote the way
22
+ * `truncate`-ing an already-joined-and-quoted string could.
23
+ */
24
+ export declare const quoteNameList: (names: readonly string[]) => string;
25
+ /**
26
+ * A short, bounded description of a value for error messages. Only
27
+ * `string`/`number`/`bigint` can be arbitrarily long themselves; anything
28
+ * else is described by shape/type rather than rendered.
29
+ */
30
+ export declare const describeValue: (value: unknown) => string;
31
+ //# sourceMappingURL=meta.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"meta.d.ts","sourceRoot":"","sources":["meta.ts"],"names":[],"mappings":"AAAA;;;GAGG;AA+BH;;;;;;;;GAQG;AACH,eAAO,MAAM,SAAS,GAAI,KAAK,MAAM,KAAG,MAAuC,CAAC;AAEhF;;;;;;;;GAQG;AACH,eAAO,MAAM,aAAa,GAAI,OAAO,SAAS,MAAM,EAAE,KAAG,MAIxD,CAAC;AAEF;;;;GAIG;AACH,eAAO,MAAM,aAAa,GAAI,OAAO,OAAO,KAAG,MAqB9C,CAAC"}
@@ -0,0 +1,87 @@
1
+ /**
2
+ * @file Helpers for quoting or describing values in e.g. error messages
3
+ * and test descriptions.
4
+ */
5
+
6
+ const MAX_DESCRIBED_LENGTH = 100;
7
+ const MAX_DESCRIBED_ITEMS = 10;
8
+
9
+ /**
10
+ * Slices `str` to at most `MAX_DESCRIBED_LENGTH` characters, appending
11
+ * `...` if it was cut. Bounds length only -- doesn't escape or annotate;
12
+ * `truncate` and `describeValue`'s string case each build on this
13
+ * differently (an appended `(N chars total)` annotation, or JSON escaping,
14
+ * respectively), so the raw slicing lives in one place.
15
+ */
16
+ const truncateRaw = (str ) =>
17
+ str.length > MAX_DESCRIBED_LENGTH
18
+ ? `${str.slice(0, MAX_DESCRIBED_LENGTH)}...`
19
+ : str;
20
+
21
+ /**
22
+ * Bounds a string embedded in an error message -- `message` (and, in
23
+ * 'throw' mode, `types`) can come from an untrusted source, so a field
24
+ * name, value, or joined list of them could otherwise be arbitrarily large.
25
+ * Bounds length only, and doesn't escape the result -- see `quoteName` for
26
+ * a quoted-and-escaped identifier suitable for embedding directly in a
27
+ * message (manually wrapping this in literal quotes instead is unsafe: an
28
+ * embedded quote character in `str` would break out of them).
29
+ */
30
+ const truncate = (str ) =>
31
+ str.length > MAX_DESCRIBED_LENGTH
32
+ ? `${truncateRaw(str)}(${str.length} chars total)`
33
+ : str;
34
+
35
+ /**
36
+ * Quotes and escapes an identifier (a struct/field type or field name) for
37
+ * embedding in an error message. Escaping via `JSON.stringify` happens
38
+ * *after* truncating and covers the whole (possibly-annotated) result, so
39
+ * an embedded quote, backslash, or newline in the identifier can't break
40
+ * out of the message's own quoting, and the `(N chars total)` annotation
41
+ * can't itself get chopped off by a later truncation step (there isn't
42
+ * one).
43
+ */
44
+ export const quoteName = (str ) => JSON.stringify(truncate(str));
45
+
46
+ /**
47
+ * Quotes and escapes each name in `names` (see `quoteName`) and joins them
48
+ * for an error message -- bounding not just each individual name's length
49
+ * but also, since attacker-controlled data can make the *list itself*
50
+ * arbitrarily long (e.g. very many extra fields on a struct), the number of
51
+ * items included. Cuts off whole items rather than slicing the joined
52
+ * string's raw characters, so the result can never end mid-quote the way
53
+ * `truncate`-ing an already-joined-and-quoted string could.
54
+ */
55
+ export const quoteNameList = (names ) => {
56
+ const shown = names.slice(0, MAX_DESCRIBED_ITEMS).map(quoteName).join(', ');
57
+ const omitted = names.length - MAX_DESCRIBED_ITEMS;
58
+ return omitted > 0 ? `${shown}, and ${omitted} more` : shown;
59
+ };
60
+
61
+ /**
62
+ * A short, bounded description of a value for error messages. Only
63
+ * `string`/`number`/`bigint` can be arbitrarily long themselves; anything
64
+ * else is described by shape/type rather than rendered.
65
+ */
66
+ export const describeValue = (value ) => {
67
+ if (value === null) return 'null';
68
+ if (typeof value === 'string') {
69
+ if (value.length > MAX_DESCRIBED_LENGTH) {
70
+ // The `(N chars total)` annotation goes *outside* the JSON-quoted,
71
+ // truncated value (unlike `quoteName`), so it reads as metadata about
72
+ // the value rather than part of it.
73
+ return `${JSON.stringify(truncateRaw(value))}(${value.length} chars total)`;
74
+ }
75
+ return JSON.stringify(value);
76
+ }
77
+ // Truncate the digits *before* appending the `n` suffix -- appending
78
+ // first and truncating the combined string risks slicing the `n` itself
79
+ // off a long enough value, leaving output that no longer looks like a
80
+ // bigint.
81
+ if (typeof value === 'bigint') return `${truncate(`${value}`)}n`;
82
+ if (typeof value === 'number') return truncate(String(value));
83
+ if (value instanceof Uint8Array)
84
+ return `a Uint8Array with ${value.length} byte(s)`;
85
+ if (Array.isArray(value)) return `an array with ${value.length} element(s)`;
86
+ return `a ${typeof value}`;
87
+ };
@@ -27,7 +27,7 @@ import {
27
27
  permitWitnessTransferFromTypes,
28
28
  TokenPermissionTypeParams,
29
29
  } from './signatureTransfer.js';
30
- import { isEvmAddressShape, sameEvmAddress } from '../address.js';
30
+ import { isEvmAddressShape, sameEvmAddress } from '../evm-address.js';
31
31
 
32
32
  const PrimaryTypes = keyMirror({
33
33
  PermitBatchWitnessTransferFrom: null,
@@ -1 +1 @@
1
- {"version":3,"file":"eip712-normalize.d.ts","sourceRoot":"","sources":["eip712-normalize.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAiEG;AACH,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,eAAe,CAAC;AAExD,KAAK,WAAW,GAAG,MAAM,CAAC,MAAM,EAAE,SAAS,kBAAkB,EAAE,CAAC,CAAC;AAEjE,MAAM,MAAM,mCAAmC,GAAG;IAChD,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACjC,KAAK,EAAE,WAAW,CAAC;IACnB,WAAW,EAAE,MAAM,CAAC;CACrB,CAAC;AAEF,MAAM,MAAM,qCAAqC,GAAG;IAClD,qBAAqB;IACrB,YAAY,CAAC,EAAE,MAAM,GAAG,OAAO,GAAG,MAAM,CAAC;IACzC;;;;;;OAMG;IACH,mBAAmB,CAAC,EAAE,WAAW,GAAG,MAAM,GAAG,OAAO,CAAC;CACtD,CAAC;AAEF,MAAM,MAAM,oCAAoC,GAAG;IACjD,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACjC,KAAK,EAAE,WAAW,CAAC;CACpB,CAAC;AA4CF;;;;;;;;;GASG;AACH,eAAO,MAAM,6BAA6B,QAAO,MACf,CAAC;AAEnC;;;;;GAKG;AACH,eAAO,MAAM,gCAAgC,MAAM,CAAC;AAwFpD;;;;;;;;;;GAUG;AACH,eAAO,MAAM,kBAAkB,GAAI,OAAO,OAAO,KAAG,MAAM,GAAG,SAc5D,CAAC;AAeF;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+BG;AACH,eAAO,MAAM,wBAAwB,GACnC,WAAW,MAAM,EACjB,OAAO,OAAO,KACb,OAgFF,CAAC;AAwLF,eAAO,MAAM,8BAA8B,GACzC,OAAO,mCAAmC,EAC1C,UAAS,qCAA0C,KAClD,oCA+EF,CAAC"}
1
+ {"version":3,"file":"eip712-normalize.d.ts","sourceRoot":"","sources":["eip712-normalize.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAiEG;AACH,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,eAAe,CAAC;AAIxD,KAAK,WAAW,GAAG,MAAM,CAAC,MAAM,EAAE,SAAS,kBAAkB,EAAE,CAAC,CAAC;AAEjE,MAAM,MAAM,mCAAmC,GAAG;IAChD,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACjC,KAAK,EAAE,WAAW,CAAC;IACnB,WAAW,EAAE,MAAM,CAAC;CACrB,CAAC;AAEF,MAAM,MAAM,qCAAqC,GAAG;IAClD,qBAAqB;IACrB,YAAY,CAAC,EAAE,MAAM,GAAG,OAAO,GAAG,MAAM,CAAC;IACzC;;;;;;OAMG;IACH,mBAAmB,CAAC,EAAE,WAAW,GAAG,MAAM,GAAG,OAAO,CAAC;CACtD,CAAC;AAEF,MAAM,MAAM,oCAAoC,GAAG;IACjD,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACjC,KAAK,EAAE,WAAW,CAAC;CACpB,CAAC;AAuCF;;;;;;;;;GASG;AACH,eAAO,MAAM,6BAA6B,QAAO,MACf,CAAC;AAEnC;;;;;GAKG;AACH,eAAO,MAAM,gCAAgC,MAAM,CAAC;AAIpD;;;;;;;;;;GAUG;AACH,eAAO,MAAM,kBAAkB,GAAI,OAAO,OAAO,KAAG,MAAM,GAAG,SAc5D,CAAC;AAeF;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+BG;AACH,eAAO,MAAM,wBAAwB,GACnC,WAAW,MAAM,EACjB,OAAO,OAAO,KACb,OAgFF,CAAC;AAwLF,eAAO,MAAM,8BAA8B,GACzC,OAAO,mCAAmC,EAC1C,UAAS,qCAA0C,KAClD,oCA+EF,CAAC"}
@@ -65,16 +65,18 @@
65
65
  * than converted to the equivalent hex string.
66
66
  */
67
67
 
68
+ import { isEvmAddressShape } from '../evm-address.js';
69
+ import { describeValue, quoteName, quoteNameList } from '../meta.js';
68
70
 
69
-
71
+ ;
70
72
 
71
-
73
+ ;
72
74
 
73
75
 
74
76
 
75
77
 
76
78
 
77
-
79
+ ;
78
80
 
79
81
 
80
82
 
@@ -87,7 +89,7 @@
87
89
 
88
90
 
89
91
 
90
-
92
+ ;
91
93
 
92
94
 
93
95
 
@@ -107,11 +109,6 @@ const splitArrayType = (
107
109
  };
108
110
  };
109
111
 
110
- // Same shape as `isEvmAddressShape` in `../address.js`, duplicated rather
111
- // than imported: this module must have no runtime imports (see the module
112
- // doc comment; `eip712-normalize.xs.test.js` also evaluates its source
113
- // directly), and `address.js` has runtime dependencies of its own.
114
- const ADDRESS_REGEX = /^0x[a-fA-F0-9]{40}$/u;
115
112
  // Solidity `(u)int<M>`: (un)signed integer of `M` bits, `0 < M <= 256`,
116
113
  // `M % 8 === 0`. Unlike viem's `integerRegex` (utils/regex.ts), the width
117
114
  // is required: EIP-712 has no bare `uint`/`int` aliases, and viem and
@@ -157,90 +154,6 @@ export const EIP712_INTEGER_STRING_MAX_LENGTH = 100;
157
154
  // abitype types `(u)int<M>` values as `number` for `M <= 48`, else `bigint`.
158
155
  const MAX_NUMBER_INTEGER_BITS = 48;
159
156
 
160
- const MAX_DESCRIBED_LENGTH = 100;
161
-
162
- /**
163
- * Slices `str` to at most `MAX_DESCRIBED_LENGTH` characters, appending
164
- * `...` if it was cut. Bounds length only -- doesn't escape or annotate;
165
- * `truncate` and `describeValue`'s string case each build on this
166
- * differently (an appended `(N chars total)` annotation, or JSON escaping,
167
- * respectively), so the raw slicing lives in one place.
168
- */
169
- const truncateRaw = (str ) =>
170
- str.length > MAX_DESCRIBED_LENGTH
171
- ? `${str.slice(0, MAX_DESCRIBED_LENGTH)}...`
172
- : str;
173
-
174
- /**
175
- * Bounds a string embedded in an error message -- `message` (and, in
176
- * 'throw' mode, `types`) can come from an untrusted source, so a field
177
- * name, value, or joined list of them could otherwise be arbitrarily large.
178
- * Bounds length only, and doesn't escape the result -- see `quoteName` for
179
- * a quoted-and-escaped identifier suitable for embedding directly in a
180
- * message (manually wrapping this in literal quotes instead is unsafe: an
181
- * embedded quote character in `str` would break out of them).
182
- */
183
- const truncate = (str ) =>
184
- str.length > MAX_DESCRIBED_LENGTH
185
- ? `${truncateRaw(str)}(${str.length} chars total)`
186
- : str;
187
-
188
- /**
189
- * Quotes and escapes an identifier (a struct/field type or field name) for
190
- * embedding in an error message. Escaping via `JSON.stringify` happens
191
- * *after* truncating and covers the whole (possibly-annotated) result, so
192
- * an embedded quote, backslash, or newline in the identifier can't break
193
- * out of the message's own quoting, and the `(N chars total)` annotation
194
- * can't itself get chopped off by a later truncation step (there isn't
195
- * one).
196
- */
197
- const quoteName = (str ) => JSON.stringify(truncate(str));
198
-
199
- const MAX_DESCRIBED_ITEMS = 10;
200
-
201
- /**
202
- * Quotes and escapes each name in `names` (see `quoteName`) and joins them
203
- * for an error message -- bounding not just each individual name's length
204
- * but also, since attacker-controlled data can make the *list itself*
205
- * arbitrarily long (e.g. very many extra fields on a struct), the number of
206
- * items included. Cuts off whole items rather than slicing the joined
207
- * string's raw characters, so the result can never end mid-quote the way
208
- * `truncate`-ing an already-joined-and-quoted string could.
209
- */
210
- const quoteNameList = (names ) => {
211
- const shown = names.slice(0, MAX_DESCRIBED_ITEMS).map(quoteName).join(', ');
212
- const omitted = names.length - MAX_DESCRIBED_ITEMS;
213
- return omitted > 0 ? `${shown}, and ${omitted} more` : shown;
214
- };
215
-
216
- /**
217
- * A short, bounded description of a value for error messages. Only
218
- * `string`/`number`/`bigint` can be arbitrarily long themselves; anything
219
- * else is described by shape/type rather than rendered.
220
- */
221
- const describeValue = (value ) => {
222
- if (value === null) return 'null';
223
- if (typeof value === 'string') {
224
- if (value.length > MAX_DESCRIBED_LENGTH) {
225
- // The `(N chars total)` annotation goes *outside* the JSON-quoted,
226
- // truncated value (unlike `quoteName`), so it reads as metadata about
227
- // the value rather than part of it.
228
- return `${JSON.stringify(truncateRaw(value))}(${value.length} chars total)`;
229
- }
230
- return JSON.stringify(value);
231
- }
232
- // Truncate the digits *before* appending the `n` suffix -- appending
233
- // first and truncating the combined string risks slicing the `n` itself
234
- // off a long enough value, leaving output that no longer looks like a
235
- // bigint.
236
- if (typeof value === 'bigint') return `${truncate(`${value}`)}n`;
237
- if (typeof value === 'number') return truncate(String(value));
238
- if (value instanceof Uint8Array)
239
- return `a Uint8Array with ${value.length} byte(s)`;
240
- if (Array.isArray(value)) return `an array with ${value.length} element(s)`;
241
- return `a ${typeof value}`;
242
- };
243
-
244
157
  /**
245
158
  * Parses an integer given in one of the JS representations accepted for an
246
159
  * EIP-712 `(u)int<M>` value: a `bigint`, a safe integer `number`, or a
@@ -320,7 +233,7 @@ export const normalizeEIP712Primitive = (
320
233
  const quotedType = quoteName(fieldType);
321
234
 
322
235
  if (fieldType === 'address') {
323
- if (typeof value !== 'string' || !ADDRESS_REGEX.test(value)) {
236
+ if (!isEvmAddressShape(value)) {
324
237
  throw new Error(`Invalid EIP-712 address value: ${describeValue(value)}`);
325
238
  }
326
239
  return value;