@tezos-x/octez.connect-core 5.0.0-beta.6 → 5.0.1
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/dist/cjs/package.json +3 -3
- package/dist/cjs/src/clients/client/Client.js +13 -16
- package/dist/cjs/src/clients/client/Client.js.map +1 -1
- package/dist/cjs/src/constants.js +2 -2
- package/dist/cjs/src/constants.js.map +1 -1
- package/dist/cjs/src/errors/InvalidBeaconVersionError.d.ts +17 -0
- package/dist/cjs/src/errors/InvalidBeaconVersionError.js +26 -0
- package/dist/cjs/src/errors/InvalidBeaconVersionError.js.map +1 -0
- package/dist/cjs/src/errors/InvalidRequiredMinimumVersionError.d.ts +16 -0
- package/dist/cjs/src/errors/InvalidRequiredMinimumVersionError.js +25 -0
- package/dist/cjs/src/errors/InvalidRequiredMinimumVersionError.js.map +1 -0
- package/dist/cjs/src/errors/NetworksUnsupportedBeaconError.d.ts +21 -0
- package/dist/cjs/src/errors/NetworksUnsupportedBeaconError.js +33 -0
- package/dist/cjs/src/errors/NetworksUnsupportedBeaconError.js.map +1 -0
- package/dist/cjs/src/errors/VersionUnsupportedBeaconError.d.ts +16 -0
- package/dist/cjs/src/errors/VersionUnsupportedBeaconError.js +26 -0
- package/dist/cjs/src/errors/VersionUnsupportedBeaconError.js.map +1 -0
- package/dist/cjs/src/errors/error-codes.d.ts +8 -0
- package/dist/cjs/src/errors/error-codes.js +5 -1
- package/dist/cjs/src/errors/error-codes.js.map +1 -1
- package/dist/cjs/src/index.d.ts +9 -2
- package/dist/cjs/src/index.js +28 -2
- package/dist/cjs/src/index.js.map +1 -1
- package/dist/cjs/src/managers/AccountManager.d.ts +7 -0
- package/dist/cjs/src/managers/AccountManager.js +11 -0
- package/dist/cjs/src/managers/AccountManager.js.map +1 -1
- package/dist/cjs/src/managers/PermissionManager.d.ts +7 -0
- package/dist/cjs/src/managers/PermissionManager.js +12 -0
- package/dist/cjs/src/managers/PermissionManager.js.map +1 -1
- package/dist/cjs/src/managers/PermissionValidator.js +13 -1
- package/dist/cjs/src/managers/PermissionValidator.js.map +1 -1
- package/dist/cjs/src/managers/StorageManager.d.ts +11 -0
- package/dist/cjs/src/managers/StorageManager.js +28 -0
- package/dist/cjs/src/managers/StorageManager.js.map +1 -1
- package/dist/cjs/src/utils/assert-never.d.ts +9 -2
- package/dist/cjs/src/utils/assert-never.js +21 -3
- package/dist/cjs/src/utils/assert-never.js.map +1 -1
- package/dist/cjs/src/utils/caip2.d.ts +61 -0
- package/dist/cjs/src/utils/caip2.js +93 -0
- package/dist/cjs/src/utils/caip2.js.map +1 -0
- package/dist/cjs/src/utils/get-account-identifier.js +19 -5
- package/dist/cjs/src/utils/get-account-identifier.js.map +1 -1
- package/dist/cjs/src/utils/message-utils.d.ts +94 -0
- package/dist/cjs/src/utils/message-utils.js +148 -5
- package/dist/cjs/src/utils/message-utils.js.map +1 -1
- package/dist/cjs/src/utils/required-minimum-version.d.ts +19 -0
- package/dist/cjs/src/utils/required-minimum-version.js +47 -0
- package/dist/cjs/src/utils/required-minimum-version.js.map +1 -0
- package/dist/esm/package.json +3 -3
- package/dist/esm/src/clients/client/Client.js +13 -18
- package/dist/esm/src/clients/client/Client.js.map +1 -1
- package/dist/esm/src/constants.js +2 -2
- package/dist/esm/src/constants.js.map +1 -1
- package/dist/esm/src/errors/InvalidBeaconVersionError.d.ts +17 -0
- package/dist/esm/src/errors/InvalidBeaconVersionError.js +24 -0
- package/dist/esm/src/errors/InvalidBeaconVersionError.js.map +1 -0
- package/dist/esm/src/errors/InvalidRequiredMinimumVersionError.d.ts +16 -0
- package/dist/esm/src/errors/InvalidRequiredMinimumVersionError.js +23 -0
- package/dist/esm/src/errors/InvalidRequiredMinimumVersionError.js.map +1 -0
- package/dist/esm/src/errors/NetworksUnsupportedBeaconError.d.ts +21 -0
- package/dist/esm/src/errors/NetworksUnsupportedBeaconError.js +30 -0
- package/dist/esm/src/errors/NetworksUnsupportedBeaconError.js.map +1 -0
- package/dist/esm/src/errors/VersionUnsupportedBeaconError.d.ts +16 -0
- package/dist/esm/src/errors/VersionUnsupportedBeaconError.js +25 -0
- package/dist/esm/src/errors/VersionUnsupportedBeaconError.js.map +1 -0
- package/dist/esm/src/errors/error-codes.d.ts +8 -0
- package/dist/esm/src/errors/error-codes.js +5 -1
- package/dist/esm/src/errors/error-codes.js.map +1 -1
- package/dist/esm/src/index.d.ts +9 -2
- package/dist/esm/src/index.js +9 -2
- package/dist/esm/src/index.js.map +1 -1
- package/dist/esm/src/managers/AccountManager.d.ts +7 -0
- package/dist/esm/src/managers/AccountManager.js +9 -0
- package/dist/esm/src/managers/AccountManager.js.map +1 -1
- package/dist/esm/src/managers/PermissionManager.d.ts +7 -0
- package/dist/esm/src/managers/PermissionManager.js +10 -0
- package/dist/esm/src/managers/PermissionManager.js.map +1 -1
- package/dist/esm/src/managers/PermissionValidator.js +13 -1
- package/dist/esm/src/managers/PermissionValidator.js.map +1 -1
- package/dist/esm/src/managers/StorageManager.d.ts +11 -0
- package/dist/esm/src/managers/StorageManager.js +26 -0
- package/dist/esm/src/managers/StorageManager.js.map +1 -1
- package/dist/esm/src/utils/assert-never.d.ts +9 -2
- package/dist/esm/src/utils/assert-never.js +20 -3
- package/dist/esm/src/utils/assert-never.js.map +1 -1
- package/dist/esm/src/utils/caip2.d.ts +61 -0
- package/dist/esm/src/utils/caip2.js +82 -0
- package/dist/esm/src/utils/caip2.js.map +1 -0
- package/dist/esm/src/utils/get-account-identifier.js +19 -5
- package/dist/esm/src/utils/get-account-identifier.js.map +1 -1
- package/dist/esm/src/utils/message-utils.d.ts +94 -0
- package/dist/esm/src/utils/message-utils.js +139 -4
- package/dist/esm/src/utils/message-utils.js.map +1 -1
- package/dist/esm/src/utils/required-minimum-version.d.ts +19 -0
- package/dist/esm/src/utils/required-minimum-version.js +43 -0
- package/dist/esm/src/utils/required-minimum-version.js.map +1 -0
- package/package.json +3 -3
|
@@ -1,11 +1,28 @@
|
|
|
1
1
|
/* eslint-disable prefer-arrow/prefer-arrow-functions */
|
|
2
2
|
/**
|
|
3
|
-
*
|
|
3
|
+
* Exhaustiveness guard for if/else chains and switch/cases.
|
|
4
4
|
*
|
|
5
|
-
*
|
|
5
|
+
* Compile time: passing anything but `never` is a type error, so adding a new
|
|
6
|
+
* union member without handling it fails to build. Runtime: an untrusted value
|
|
7
|
+
* (e.g. an unknown message or error type from the wire) can still reach the
|
|
8
|
+
* default branch, so throw an actionable error naming that value instead of
|
|
9
|
+
* silently returning — callers previously received `undefined` and failed
|
|
10
|
+
* later with no context.
|
|
11
|
+
*
|
|
12
|
+
* @param empty The value that should be unreachable
|
|
6
13
|
*/
|
|
7
14
|
export function assertNever(empty) {
|
|
8
|
-
|
|
15
|
+
let repr;
|
|
16
|
+
try {
|
|
17
|
+
repr = JSON.stringify(empty) ?? String(empty);
|
|
18
|
+
}
|
|
19
|
+
catch {
|
|
20
|
+
repr = String(empty);
|
|
21
|
+
}
|
|
22
|
+
if (repr.length > 200) {
|
|
23
|
+
repr = `${repr.slice(0, 200)}…`;
|
|
24
|
+
}
|
|
25
|
+
throw new Error(`assertNever: reached unreachable case with unexpected value: ${repr}`);
|
|
9
26
|
}
|
|
10
27
|
/* eslint-enable prefer-arrow/prefer-arrow-functions */
|
|
11
28
|
//# sourceMappingURL=assert-never.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"assert-never.js","sourceRoot":"","sources":["../../../../src/utils/assert-never.ts"],"names":[],"mappings":"AAAA,wDAAwD;AAExD
|
|
1
|
+
{"version":3,"file":"assert-never.js","sourceRoot":"","sources":["../../../../src/utils/assert-never.ts"],"names":[],"mappings":"AAAA,wDAAwD;AAExD;;;;;;;;;;;GAWG;AACH,MAAM,UAAU,WAAW,CAAC,KAAY;IACtC,IAAI,IAAY,CAAA;IAChB,IAAI,CAAC;QACH,IAAI,GAAG,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,IAAI,MAAM,CAAC,KAAK,CAAC,CAAA;IAC/C,CAAC;IAAC,MAAM,CAAC;QACP,IAAI,GAAG,MAAM,CAAC,KAAK,CAAC,CAAA;IACtB,CAAC;IACD,IAAI,IAAI,CAAC,MAAM,GAAG,GAAG,EAAE,CAAC;QACtB,IAAI,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC,GAAG,CAAA;IACjC,CAAC;IAED,MAAM,IAAI,KAAK,CAAC,gEAAgE,IAAI,EAAE,CAAC,CAAA;AACzF,CAAC;AAED,uDAAuD","sourcesContent":["/* eslint-disable prefer-arrow/prefer-arrow-functions */\n\n/**\n * Exhaustiveness guard for if/else chains and switch/cases.\n *\n * Compile time: passing anything but `never` is a type error, so adding a new\n * union member without handling it fails to build. Runtime: an untrusted value\n * (e.g. an unknown message or error type from the wire) can still reach the\n * default branch, so throw an actionable error naming that value instead of\n * silently returning — callers previously received `undefined` and failed\n * later with no context.\n *\n * @param empty The value that should be unreachable\n */\nexport function assertNever(empty: never): never {\n let repr: string\n try {\n repr = JSON.stringify(empty) ?? String(empty)\n } catch {\n repr = String(empty)\n }\n if (repr.length > 200) {\n repr = `${repr.slice(0, 200)}…`\n }\n\n throw new Error(`assertNever: reached unreachable case with unexpected value: ${repr}`)\n}\n\n/* eslint-enable prefer-arrow/prefer-arrow-functions */\n"]}
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* CAIP-2 chain id helpers, scoped to the Tezos namespace (`tezos:<reference>`).
|
|
3
|
+
*
|
|
4
|
+
* The wire format accepts both the bare reference (`NetXsqzbfFenSTS`) and the
|
|
5
|
+
* full CAIP-2 string (`tezos:NetXsqzbfFenSTS`); SDK code consistently stores
|
|
6
|
+
* and routes on the full form.
|
|
7
|
+
*/
|
|
8
|
+
import { Network, NetworkType } from '@tezos-x/octez.connect-types';
|
|
9
|
+
/**
|
|
10
|
+
* Returns `chainId` with the `tezos:` prefix added if absent. No validation
|
|
11
|
+
* is performed; use `isValidTezosCaip2` at API boundaries.
|
|
12
|
+
*/
|
|
13
|
+
export declare const normalizeTezosCaip2: (chainId: string) => string;
|
|
14
|
+
/**
|
|
15
|
+
* Whether `value` is a syntactically valid Tezos CAIP-2 chain id
|
|
16
|
+
* (`tezos:<alphanumeric reference>`).
|
|
17
|
+
*/
|
|
18
|
+
export declare const isValidTezosCaip2: (value: string) => boolean;
|
|
19
|
+
/**
|
|
20
|
+
* Build the minimal `Network` for a Tezos CAIP-2 chain id. Single source of
|
|
21
|
+
* truth for the `{ type: CUSTOM, chainId, ... }` shape, so the network used
|
|
22
|
+
* to derive an account identifier is constructed identically everywhere
|
|
23
|
+
* (permission storage, operation-request lookup, stale-scheme scan). `name`
|
|
24
|
+
* defaults to the chain id when the wallet supplies no human label.
|
|
25
|
+
*/
|
|
26
|
+
export declare const networkFromTezosCaip2: (chainId: string, opts?: {
|
|
27
|
+
name?: string;
|
|
28
|
+
rpcUrl?: string;
|
|
29
|
+
}) => Network;
|
|
30
|
+
/**
|
|
31
|
+
* Canonical NetworkType → genesis chain id (CAIP-2 reference) table.
|
|
32
|
+
*
|
|
33
|
+
* Applied ONLY at boundaries that must translate between the named-network
|
|
34
|
+
* vocabulary (WalletConnect session namespaces use `tezos:<name>`) and the
|
|
35
|
+
* genesis-keyed CAIP-2 vocabulary of the beacon v4 multi-network protocol.
|
|
36
|
+
*
|
|
37
|
+
* Sourcing rule: ids are read from the network's own RPC
|
|
38
|
+
* (`/chains/main/chain_id`) and locked by unit test — never guessed. Networks
|
|
39
|
+
* without an entry are not statically mappable and multi-network requests for
|
|
40
|
+
* them can only travel over transports that pass chain ids through opaquely
|
|
41
|
+
* (P2P/postmessage):
|
|
42
|
+
* - WEEKLYNET / DAILYNET rotate their genesis on every reset.
|
|
43
|
+
* - CUSTOM has no fixed genesis by definition.
|
|
44
|
+
* - TALLINNNET / SEOULNET / TEZLINK_SHADOWNET / TEZOSX_PREVIEWNET /
|
|
45
|
+
* TEZOSX_SHADOWNET currently publish no queryable RPC in the teztnets
|
|
46
|
+
* registry; add their ids here (RPC-sourced) when available.
|
|
47
|
+
* If a long-running network relaunches with a new genesis, its entry must be
|
|
48
|
+
* updated in the same change that bumps the supported network.
|
|
49
|
+
*/
|
|
50
|
+
export declare const TEZOS_NETWORK_GENESIS_IDS: Partial<Record<NetworkType, string>>;
|
|
51
|
+
/**
|
|
52
|
+
* Full CAIP-2 chain id (`tezos:NetX…`) for a named network, or `undefined`
|
|
53
|
+
* when the network has no statically known genesis (see
|
|
54
|
+
* {@link TEZOS_NETWORK_GENESIS_IDS}).
|
|
55
|
+
*/
|
|
56
|
+
export declare const tezosCaip2FromNetworkType: (type: NetworkType) => string | undefined;
|
|
57
|
+
/**
|
|
58
|
+
* Named network for a CAIP-2 chain id (bare or `tezos:`-prefixed), or
|
|
59
|
+
* `undefined` when the id does not belong to a statically mapped network.
|
|
60
|
+
*/
|
|
61
|
+
export declare const networkTypeFromTezosCaip2: (chainId: string) => NetworkType | undefined;
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* CAIP-2 chain id helpers, scoped to the Tezos namespace (`tezos:<reference>`).
|
|
3
|
+
*
|
|
4
|
+
* The wire format accepts both the bare reference (`NetXsqzbfFenSTS`) and the
|
|
5
|
+
* full CAIP-2 string (`tezos:NetXsqzbfFenSTS`); SDK code consistently stores
|
|
6
|
+
* and routes on the full form.
|
|
7
|
+
*/
|
|
8
|
+
import { NetworkType } from '@tezos-x/octez.connect-types';
|
|
9
|
+
const TEZOS_CAIP2_PREFIX = 'tezos:';
|
|
10
|
+
const TEZOS_CAIP2_RE = /^tezos:[A-Za-z0-9]+$/;
|
|
11
|
+
/**
|
|
12
|
+
* Returns `chainId` with the `tezos:` prefix added if absent. No validation
|
|
13
|
+
* is performed; use `isValidTezosCaip2` at API boundaries.
|
|
14
|
+
*/
|
|
15
|
+
export const normalizeTezosCaip2 = (chainId) => chainId.startsWith(TEZOS_CAIP2_PREFIX) ? chainId : `${TEZOS_CAIP2_PREFIX}${chainId}`;
|
|
16
|
+
/**
|
|
17
|
+
* Whether `value` is a syntactically valid Tezos CAIP-2 chain id
|
|
18
|
+
* (`tezos:<alphanumeric reference>`).
|
|
19
|
+
*/
|
|
20
|
+
export const isValidTezosCaip2 = (value) => TEZOS_CAIP2_RE.test(value);
|
|
21
|
+
/**
|
|
22
|
+
* Build the minimal `Network` for a Tezos CAIP-2 chain id. Single source of
|
|
23
|
+
* truth for the `{ type: CUSTOM, chainId, ... }` shape, so the network used
|
|
24
|
+
* to derive an account identifier is constructed identically everywhere
|
|
25
|
+
* (permission storage, operation-request lookup, stale-scheme scan). `name`
|
|
26
|
+
* defaults to the chain id when the wallet supplies no human label.
|
|
27
|
+
*/
|
|
28
|
+
export const networkFromTezosCaip2 = (chainId, opts) => ({
|
|
29
|
+
type: NetworkType.CUSTOM,
|
|
30
|
+
name: opts?.name ?? chainId,
|
|
31
|
+
rpcUrl: opts?.rpcUrl,
|
|
32
|
+
chainId
|
|
33
|
+
});
|
|
34
|
+
/**
|
|
35
|
+
* Canonical NetworkType → genesis chain id (CAIP-2 reference) table.
|
|
36
|
+
*
|
|
37
|
+
* Applied ONLY at boundaries that must translate between the named-network
|
|
38
|
+
* vocabulary (WalletConnect session namespaces use `tezos:<name>`) and the
|
|
39
|
+
* genesis-keyed CAIP-2 vocabulary of the beacon v4 multi-network protocol.
|
|
40
|
+
*
|
|
41
|
+
* Sourcing rule: ids are read from the network's own RPC
|
|
42
|
+
* (`/chains/main/chain_id`) and locked by unit test — never guessed. Networks
|
|
43
|
+
* without an entry are not statically mappable and multi-network requests for
|
|
44
|
+
* them can only travel over transports that pass chain ids through opaquely
|
|
45
|
+
* (P2P/postmessage):
|
|
46
|
+
* - WEEKLYNET / DAILYNET rotate their genesis on every reset.
|
|
47
|
+
* - CUSTOM has no fixed genesis by definition.
|
|
48
|
+
* - TALLINNNET / SEOULNET / TEZLINK_SHADOWNET / TEZOSX_PREVIEWNET /
|
|
49
|
+
* TEZOSX_SHADOWNET currently publish no queryable RPC in the teztnets
|
|
50
|
+
* registry; add their ids here (RPC-sourced) when available.
|
|
51
|
+
* If a long-running network relaunches with a new genesis, its entry must be
|
|
52
|
+
* updated in the same change that bumps the supported network.
|
|
53
|
+
*/
|
|
54
|
+
export const TEZOS_NETWORK_GENESIS_IDS = {
|
|
55
|
+
[NetworkType.MAINNET]: 'NetXdQprcVkpaWU',
|
|
56
|
+
[NetworkType.GHOSTNET]: 'NetXnHfVqm9iesp',
|
|
57
|
+
[NetworkType.SHADOWNET]: 'NetXsqzbfFenSTS',
|
|
58
|
+
// Tezos X L2 (Michelson runtime) mainnet. Maintainer-supplied id — no
|
|
59
|
+
// public RPC was reachable at the time of adding; re-verify against
|
|
60
|
+
// `/chains/main/chain_id` once one ships.
|
|
61
|
+
[NetworkType.TEZOSX_MAINNET]: 'NetXohUVN5QWR4f',
|
|
62
|
+
[NetworkType.USHUAIANET]: 'NetXpX8WSZkAZZA'
|
|
63
|
+
};
|
|
64
|
+
/**
|
|
65
|
+
* Full CAIP-2 chain id (`tezos:NetX…`) for a named network, or `undefined`
|
|
66
|
+
* when the network has no statically known genesis (see
|
|
67
|
+
* {@link TEZOS_NETWORK_GENESIS_IDS}).
|
|
68
|
+
*/
|
|
69
|
+
export const tezosCaip2FromNetworkType = (type) => {
|
|
70
|
+
const genesis = TEZOS_NETWORK_GENESIS_IDS[type];
|
|
71
|
+
return genesis === undefined ? undefined : `${TEZOS_CAIP2_PREFIX}${genesis}`;
|
|
72
|
+
};
|
|
73
|
+
/**
|
|
74
|
+
* Named network for a CAIP-2 chain id (bare or `tezos:`-prefixed), or
|
|
75
|
+
* `undefined` when the id does not belong to a statically mapped network.
|
|
76
|
+
*/
|
|
77
|
+
export const networkTypeFromTezosCaip2 = (chainId) => {
|
|
78
|
+
const normalized = normalizeTezosCaip2(chainId);
|
|
79
|
+
const reference = normalized.slice(TEZOS_CAIP2_PREFIX.length);
|
|
80
|
+
return Object.keys(TEZOS_NETWORK_GENESIS_IDS).find((type) => TEZOS_NETWORK_GENESIS_IDS[type] === reference);
|
|
81
|
+
};
|
|
82
|
+
//# sourceMappingURL=caip2.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"caip2.js","sourceRoot":"","sources":["../../../../src/utils/caip2.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AACH,OAAO,EAAW,WAAW,EAAE,MAAM,8BAA8B,CAAA;AAEnE,MAAM,kBAAkB,GAAG,QAAQ,CAAA;AAEnC,MAAM,cAAc,GAAG,sBAAsB,CAAA;AAE7C;;;GAGG;AACH,MAAM,CAAC,MAAM,mBAAmB,GAAG,CAAC,OAAe,EAAU,EAAE,CAC7D,OAAO,CAAC,UAAU,CAAC,kBAAkB,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG,kBAAkB,GAAG,OAAO,EAAE,CAAA;AAEtF;;;GAGG;AACH,MAAM,CAAC,MAAM,iBAAiB,GAAG,CAAC,KAAa,EAAW,EAAE,CAAC,cAAc,CAAC,IAAI,CAAC,KAAK,CAAC,CAAA;AAEvF;;;;;;GAMG;AACH,MAAM,CAAC,MAAM,qBAAqB,GAAG,CACnC,OAAe,EACf,IAAyC,EAChC,EAAE,CAAC,CAAC;IACb,IAAI,EAAE,WAAW,CAAC,MAAM;IACxB,IAAI,EAAE,IAAI,EAAE,IAAI,IAAI,OAAO;IAC3B,MAAM,EAAE,IAAI,EAAE,MAAM;IACpB,OAAO;CACR,CAAC,CAAA;AAEF;;;;;;;;;;;;;;;;;;;GAmBG;AACH,MAAM,CAAC,MAAM,yBAAyB,GAAyC;IAC7E,CAAC,WAAW,CAAC,OAAO,CAAC,EAAE,iBAAiB;IACxC,CAAC,WAAW,CAAC,QAAQ,CAAC,EAAE,iBAAiB;IACzC,CAAC,WAAW,CAAC,SAAS,CAAC,EAAE,iBAAiB;IAC1C,sEAAsE;IACtE,oEAAoE;IACpE,0CAA0C;IAC1C,CAAC,WAAW,CAAC,cAAc,CAAC,EAAE,iBAAiB;IAC/C,CAAC,WAAW,CAAC,UAAU,CAAC,EAAE,iBAAiB;CAC5C,CAAA;AAED;;;;GAIG;AACH,MAAM,CAAC,MAAM,yBAAyB,GAAG,CAAC,IAAiB,EAAsB,EAAE;IACjF,MAAM,OAAO,GAAG,yBAAyB,CAAC,IAAI,CAAC,CAAA;IAE/C,OAAO,OAAO,KAAK,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,GAAG,kBAAkB,GAAG,OAAO,EAAE,CAAA;AAC9E,CAAC,CAAA;AAED;;;GAGG;AACH,MAAM,CAAC,MAAM,yBAAyB,GAAG,CAAC,OAAe,EAA2B,EAAE;IACpF,MAAM,UAAU,GAAG,mBAAmB,CAAC,OAAO,CAAC,CAAA;IAC/C,MAAM,SAAS,GAAG,UAAU,CAAC,KAAK,CAAC,kBAAkB,CAAC,MAAM,CAAC,CAAA;IAE7D,OAAQ,MAAM,CAAC,IAAI,CAAC,yBAAyB,CAAmB,CAAC,IAAI,CACnE,CAAC,IAAI,EAAE,EAAE,CAAC,yBAAyB,CAAC,IAAI,CAAC,KAAK,SAAS,CACxD,CAAA;AACH,CAAC,CAAA","sourcesContent":["/**\n * CAIP-2 chain id helpers, scoped to the Tezos namespace (`tezos:<reference>`).\n *\n * The wire format accepts both the bare reference (`NetXsqzbfFenSTS`) and the\n * full CAIP-2 string (`tezos:NetXsqzbfFenSTS`); SDK code consistently stores\n * and routes on the full form.\n */\nimport { Network, NetworkType } from '@tezos-x/octez.connect-types'\n\nconst TEZOS_CAIP2_PREFIX = 'tezos:'\n\nconst TEZOS_CAIP2_RE = /^tezos:[A-Za-z0-9]+$/\n\n/**\n * Returns `chainId` with the `tezos:` prefix added if absent. No validation\n * is performed; use `isValidTezosCaip2` at API boundaries.\n */\nexport const normalizeTezosCaip2 = (chainId: string): string =>\n chainId.startsWith(TEZOS_CAIP2_PREFIX) ? chainId : `${TEZOS_CAIP2_PREFIX}${chainId}`\n\n/**\n * Whether `value` is a syntactically valid Tezos CAIP-2 chain id\n * (`tezos:<alphanumeric reference>`).\n */\nexport const isValidTezosCaip2 = (value: string): boolean => TEZOS_CAIP2_RE.test(value)\n\n/**\n * Build the minimal `Network` for a Tezos CAIP-2 chain id. Single source of\n * truth for the `{ type: CUSTOM, chainId, ... }` shape, so the network used\n * to derive an account identifier is constructed identically everywhere\n * (permission storage, operation-request lookup, stale-scheme scan). `name`\n * defaults to the chain id when the wallet supplies no human label.\n */\nexport const networkFromTezosCaip2 = (\n chainId: string,\n opts?: { name?: string; rpcUrl?: string }\n): Network => ({\n type: NetworkType.CUSTOM,\n name: opts?.name ?? chainId,\n rpcUrl: opts?.rpcUrl,\n chainId\n})\n\n/**\n * Canonical NetworkType → genesis chain id (CAIP-2 reference) table.\n *\n * Applied ONLY at boundaries that must translate between the named-network\n * vocabulary (WalletConnect session namespaces use `tezos:<name>`) and the\n * genesis-keyed CAIP-2 vocabulary of the beacon v4 multi-network protocol.\n *\n * Sourcing rule: ids are read from the network's own RPC\n * (`/chains/main/chain_id`) and locked by unit test — never guessed. Networks\n * without an entry are not statically mappable and multi-network requests for\n * them can only travel over transports that pass chain ids through opaquely\n * (P2P/postmessage):\n * - WEEKLYNET / DAILYNET rotate their genesis on every reset.\n * - CUSTOM has no fixed genesis by definition.\n * - TALLINNNET / SEOULNET / TEZLINK_SHADOWNET / TEZOSX_PREVIEWNET /\n * TEZOSX_SHADOWNET currently publish no queryable RPC in the teztnets\n * registry; add their ids here (RPC-sourced) when available.\n * If a long-running network relaunches with a new genesis, its entry must be\n * updated in the same change that bumps the supported network.\n */\nexport const TEZOS_NETWORK_GENESIS_IDS: Partial<Record<NetworkType, string>> = {\n [NetworkType.MAINNET]: 'NetXdQprcVkpaWU',\n [NetworkType.GHOSTNET]: 'NetXnHfVqm9iesp',\n [NetworkType.SHADOWNET]: 'NetXsqzbfFenSTS',\n // Tezos X L2 (Michelson runtime) mainnet. Maintainer-supplied id — no\n // public RPC was reachable at the time of adding; re-verify against\n // `/chains/main/chain_id` once one ships.\n [NetworkType.TEZOSX_MAINNET]: 'NetXohUVN5QWR4f',\n [NetworkType.USHUAIANET]: 'NetXpX8WSZkAZZA'\n}\n\n/**\n * Full CAIP-2 chain id (`tezos:NetX…`) for a named network, or `undefined`\n * when the network has no statically known genesis (see\n * {@link TEZOS_NETWORK_GENESIS_IDS}).\n */\nexport const tezosCaip2FromNetworkType = (type: NetworkType): string | undefined => {\n const genesis = TEZOS_NETWORK_GENESIS_IDS[type]\n\n return genesis === undefined ? undefined : `${TEZOS_CAIP2_PREFIX}${genesis}`\n}\n\n/**\n * Named network for a CAIP-2 chain id (bare or `tezos:`-prefixed), or\n * `undefined` when the id does not belong to a statically mapped network.\n */\nexport const networkTypeFromTezosCaip2 = (chainId: string): NetworkType | undefined => {\n const normalized = normalizeTezosCaip2(chainId)\n const reference = normalized.slice(TEZOS_CAIP2_PREFIX.length)\n\n return (Object.keys(TEZOS_NETWORK_GENESIS_IDS) as NetworkType[]).find(\n (type) => TEZOS_NETWORK_GENESIS_IDS[type] === reference\n )\n}\n"]}
|
|
@@ -10,12 +10,26 @@ import { encode } from '@stablelib/utf8';
|
|
|
10
10
|
* @param network
|
|
11
11
|
*/
|
|
12
12
|
export const getAccountIdentifier = async (address, network) => {
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
13
|
+
// v4 multi-network accounts carry a CAIP-2 chainId. Key the identifier on
|
|
14
|
+
// (address, chainId) alone: chainId is the canonical, stable network key,
|
|
15
|
+
// whereas the human-facing `name`/`rpcUrl` differ between the wallet's
|
|
16
|
+
// permission response and the dApp's later operation requests. Including
|
|
17
|
+
// them would make the persisted identifier irreproducible at lookup time
|
|
18
|
+
// (and collapse distinct chains that happen to share a name). Legacy
|
|
19
|
+
// accounts (no chainId) keep the original scheme so their already-persisted
|
|
20
|
+
// identifiers are unchanged.
|
|
21
|
+
const data = [];
|
|
22
|
+
if (network.chainId) {
|
|
23
|
+
data.push(address, `chainId:${network.chainId}`);
|
|
16
24
|
}
|
|
17
|
-
|
|
18
|
-
data.push(
|
|
25
|
+
else {
|
|
26
|
+
data.push(address, network.type);
|
|
27
|
+
if (network.name) {
|
|
28
|
+
data.push(`name:${network.name}`);
|
|
29
|
+
}
|
|
30
|
+
if (network.rpcUrl) {
|
|
31
|
+
data.push(`rpc:${network.rpcUrl}`);
|
|
32
|
+
}
|
|
19
33
|
}
|
|
20
34
|
const buffer = Buffer.from(hash(encode(data.join('-')), 10));
|
|
21
35
|
return bs58check.encode(buffer);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"get-account-identifier.js","sourceRoot":"","sources":["../../../../src/utils/get-account-identifier.ts"],"names":[],"mappings":"AAAA,OAAO,SAAS,MAAM,WAAW,CAAA;AAEjC,OAAO,EAAE,IAAI,EAAE,MAAM,oBAAoB,CAAA;AACzC,OAAO,EAAE,MAAM,EAAE,MAAM,iBAAiB,CAAA;AAExC;;;;;;;GAOG;AACH,MAAM,CAAC,MAAM,oBAAoB,GAAG,KAAK,EAAE,OAAe,EAAE,OAAgB,EAAmB,EAAE;IAC/F,MAAM,IAAI,GAAa,CAAC,OAAO,EAAE,OAAO,CAAC,IAAI,CAAC,CAAA;
|
|
1
|
+
{"version":3,"file":"get-account-identifier.js","sourceRoot":"","sources":["../../../../src/utils/get-account-identifier.ts"],"names":[],"mappings":"AAAA,OAAO,SAAS,MAAM,WAAW,CAAA;AAEjC,OAAO,EAAE,IAAI,EAAE,MAAM,oBAAoB,CAAA;AACzC,OAAO,EAAE,MAAM,EAAE,MAAM,iBAAiB,CAAA;AAExC;;;;;;;GAOG;AACH,MAAM,CAAC,MAAM,oBAAoB,GAAG,KAAK,EAAE,OAAe,EAAE,OAAgB,EAAmB,EAAE;IAC/F,0EAA0E;IAC1E,0EAA0E;IAC1E,uEAAuE;IACvE,yEAAyE;IACzE,yEAAyE;IACzE,qEAAqE;IACrE,4EAA4E;IAC5E,6BAA6B;IAC7B,MAAM,IAAI,GAAa,EAAE,CAAA;IACzB,IAAI,OAAO,CAAC,OAAO,EAAE,CAAC;QACpB,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,WAAW,OAAO,CAAC,OAAO,EAAE,CAAC,CAAA;IAClD,CAAC;SAAM,CAAC;QACN,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,OAAO,CAAC,IAAI,CAAC,CAAA;QAChC,IAAI,OAAO,CAAC,IAAI,EAAE,CAAC;YACjB,IAAI,CAAC,IAAI,CAAC,QAAQ,OAAO,CAAC,IAAI,EAAE,CAAC,CAAA;QACnC,CAAC;QACD,IAAI,OAAO,CAAC,MAAM,EAAE,CAAC;YACnB,IAAI,CAAC,IAAI,CAAC,OAAO,OAAO,CAAC,MAAM,EAAE,CAAC,CAAA;QACpC,CAAC;IACH,CAAC;IAED,MAAM,MAAM,GAAG,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAA;IAE5D,OAAO,SAAS,CAAC,MAAM,CAAC,MAAM,CAAC,CAAA;AACjC,CAAC,CAAA","sourcesContent":["import bs58check from 'bs58check'\nimport { Network } from '@tezos-x/octez.connect-types'\nimport { hash } from '@stablelib/blake2b'\nimport { encode } from '@stablelib/utf8'\n\n/**\n * @internalapi\n *\n * Generate a deterministic account identifier based on an address and a network\n *\n * @param address\n * @param network\n */\nexport const getAccountIdentifier = async (address: string, network: Network): Promise<string> => {\n // v4 multi-network accounts carry a CAIP-2 chainId. Key the identifier on\n // (address, chainId) alone: chainId is the canonical, stable network key,\n // whereas the human-facing `name`/`rpcUrl` differ between the wallet's\n // permission response and the dApp's later operation requests. Including\n // them would make the persisted identifier irreproducible at lookup time\n // (and collapse distinct chains that happen to share a name). Legacy\n // accounts (no chainId) keep the original scheme so their already-persisted\n // identifiers are unchanged.\n const data: string[] = []\n if (network.chainId) {\n data.push(address, `chainId:${network.chainId}`)\n } else {\n data.push(address, network.type)\n if (network.name) {\n data.push(`name:${network.name}`)\n }\n if (network.rpcUrl) {\n data.push(`rpc:${network.rpcUrl}`)\n }\n }\n\n const buffer = Buffer.from(hash(encode(data.join('-')), 10))\n\n return bs58check.encode(buffer)\n}\n"]}
|
|
@@ -1,2 +1,96 @@
|
|
|
1
|
+
import { BeaconMessageType, BeaconMessageWrapper, DisconnectMessage } from '@tezos-x/octez.connect-types';
|
|
2
|
+
interface WrappedPayload {
|
|
3
|
+
type: unknown;
|
|
4
|
+
}
|
|
1
5
|
export declare const MESSAGE_WRAPPED_FROM_VERSION = 3;
|
|
6
|
+
export declare const MULTI_NETWORK_FROM_VERSION = "4";
|
|
7
|
+
export declare const parseStrictDecimalInteger: (value: unknown) => number | null;
|
|
8
|
+
/**
|
|
9
|
+
* Compare two `peer.version` strings as strict decimal integers.
|
|
10
|
+
*
|
|
11
|
+
* Returns < 0 if `a < b`, 0 if equal, > 0 if `a > b` — same convention as
|
|
12
|
+
* `Array.prototype.sort` comparators.
|
|
13
|
+
*
|
|
14
|
+
* Throws `InvalidBeaconVersionError` if either operand is not a decimal-
|
|
15
|
+
* integer string in `[0, Number.MAX_SAFE_INTEGER]`. Leading signs, leading
|
|
16
|
+
* zeros, decimal points, exponent notation, hex, whitespace, `'NaN'` and
|
|
17
|
+
* `'Infinity'` all reject.
|
|
18
|
+
*
|
|
19
|
+
* @category Utility
|
|
20
|
+
*/
|
|
21
|
+
export declare const compareBeaconVersion: (a: unknown, b: unknown) => number;
|
|
22
|
+
/**
|
|
23
|
+
* Whether `version` is a valid peer.version at or above `threshold`.
|
|
24
|
+
*
|
|
25
|
+
* Single source of truth for the "is this peer at least version X" decision.
|
|
26
|
+
* Returns `false` for an absent version and for any value that fails the
|
|
27
|
+
* strict decimal-integer contract of `compareBeaconVersion` — i.e. malformed
|
|
28
|
+
* or untrusted input is always treated as below the threshold, so a hostile
|
|
29
|
+
* peer cannot trip a higher-version code path.
|
|
30
|
+
*
|
|
31
|
+
* @category Utility
|
|
32
|
+
*/
|
|
33
|
+
export declare const isAtLeastVersion: (version: string | undefined, threshold: string) => boolean;
|
|
34
|
+
/**
|
|
35
|
+
* Whether `version` is at or above the multi-network (v4) threshold.
|
|
36
|
+
*
|
|
37
|
+
* @category Utility
|
|
38
|
+
*/
|
|
39
|
+
export declare const isMultiNetworkVersion: (version: string | undefined) => boolean;
|
|
2
40
|
export declare const usesWrappedMessages: (version?: string) => boolean;
|
|
41
|
+
/** The flat legacy wire dialect served to peers below the wrapped baseline. */
|
|
42
|
+
export declare const LEGACY_ENVELOPE_VERSION = "2";
|
|
43
|
+
/**
|
|
44
|
+
* The envelope version to stamp on an outgoing message for a peer that
|
|
45
|
+
* declared `peerVersion` at pairing: `min(peerVersion, BEACON_VERSION)` with
|
|
46
|
+
* a floor at the flat legacy dialect ('2').
|
|
47
|
+
*
|
|
48
|
+
* This is the backward-compatibility pivot: a peer that declared '2' — or
|
|
49
|
+
* never declared a version at all (legacy pairings, WalletConnect peers,
|
|
50
|
+
* malformed values) — is served the flat v2 dialect it has always spoken; a
|
|
51
|
+
* v3 peer receives '3' wrapped envelopes and never sees v4 payload fields;
|
|
52
|
+
* a v4 peer gets the full wrapped v4 wire. Callers pick the message SHAPE
|
|
53
|
+
* with `usesWrappedMessages(negotiated)` and gate v4 fields (`networks`/
|
|
54
|
+
* `accounts`) on `isMultiNetworkVersion(negotiated)`.
|
|
55
|
+
*
|
|
56
|
+
* @category Utility
|
|
57
|
+
*/
|
|
58
|
+
export declare const negotiateEnvelopeVersion: (peerVersion: string | undefined) => string;
|
|
59
|
+
/**
|
|
60
|
+
* Build a wrapped beacon envelope. Single source of truth for the
|
|
61
|
+
* `{ id, version, senderId, message }` wire shape so senders cannot drift.
|
|
62
|
+
*
|
|
63
|
+
* @category Utility
|
|
64
|
+
*/
|
|
65
|
+
export declare const wrapBeaconMessage: <T extends WrappedPayload>(envelope: {
|
|
66
|
+
id: string;
|
|
67
|
+
version: string;
|
|
68
|
+
senderId: string;
|
|
69
|
+
}, message: T) => BeaconMessageWrapper<T>;
|
|
70
|
+
/**
|
|
71
|
+
* Extract the inner payload of a wrapped beacon envelope, or `undefined`
|
|
72
|
+
* when the candidate's version does not follow the wrapped (v3+) contract.
|
|
73
|
+
* Callers must treat `undefined` as "not a wrapped message" and drop or
|
|
74
|
+
* tombstone it — never fall back to reading flat fields.
|
|
75
|
+
*
|
|
76
|
+
* @category Utility
|
|
77
|
+
*/
|
|
78
|
+
export declare const unwrapBeaconMessage: <T extends WrappedPayload>(candidate: {
|
|
79
|
+
version?: string;
|
|
80
|
+
message?: T;
|
|
81
|
+
}) => T | undefined;
|
|
82
|
+
/**
|
|
83
|
+
* Build a disconnect message in the peer's negotiated dialect: a wrapped
|
|
84
|
+
* envelope for v3+ peers, the flat legacy shape for v2 peers. A legacy peer
|
|
85
|
+
* routes on the top-level `type` and would silently ignore a wrapped
|
|
86
|
+
* envelope — the goodbye must be spoken in the dialect the peer parses.
|
|
87
|
+
*
|
|
88
|
+
* @category Utility
|
|
89
|
+
*/
|
|
90
|
+
export declare const buildDisconnectMessage: (envelope: {
|
|
91
|
+
id: string;
|
|
92
|
+
senderId: string;
|
|
93
|
+
}, peerVersion: string | undefined) => DisconnectMessage | BeaconMessageWrapper<{
|
|
94
|
+
type: BeaconMessageType.Disconnect;
|
|
95
|
+
}>;
|
|
96
|
+
export {};
|
|
@@ -1,9 +1,144 @@
|
|
|
1
|
+
import { BeaconMessageType } from '@tezos-x/octez.connect-types';
|
|
2
|
+
import { BEACON_VERSION } from '../constants';
|
|
3
|
+
import { InvalidBeaconVersionError } from '../errors/InvalidBeaconVersionError';
|
|
1
4
|
export const MESSAGE_WRAPPED_FROM_VERSION = 3;
|
|
2
|
-
|
|
3
|
-
|
|
5
|
+
// peer.version at or above which the multi-network (v4) protocol applies.
|
|
6
|
+
export const MULTI_NETWORK_FROM_VERSION = '4';
|
|
7
|
+
// Strict decimal-integer: a lone `0` or non-zero digit followed by digits.
|
|
8
|
+
// Rejects leading zeros on multi-digit values (e.g. `'04'`). A lone `0` is
|
|
9
|
+
// kept valid so legacy compat paths can use it as a fallback/unknown version.
|
|
10
|
+
const DECIMAL_INTEGER_RE = /^(0|[1-9]\d*)$/;
|
|
11
|
+
export const parseStrictDecimalInteger = (value) => {
|
|
12
|
+
if (typeof value !== 'string') {
|
|
13
|
+
return null;
|
|
14
|
+
}
|
|
15
|
+
if (!DECIMAL_INTEGER_RE.test(value)) {
|
|
16
|
+
return null;
|
|
17
|
+
}
|
|
18
|
+
const parsed = Number(value);
|
|
19
|
+
if (!Number.isFinite(parsed) || parsed > Number.MAX_SAFE_INTEGER) {
|
|
20
|
+
return null;
|
|
21
|
+
}
|
|
22
|
+
return parsed;
|
|
23
|
+
};
|
|
24
|
+
/**
|
|
25
|
+
* Compare two `peer.version` strings as strict decimal integers.
|
|
26
|
+
*
|
|
27
|
+
* Returns < 0 if `a < b`, 0 if equal, > 0 if `a > b` — same convention as
|
|
28
|
+
* `Array.prototype.sort` comparators.
|
|
29
|
+
*
|
|
30
|
+
* Throws `InvalidBeaconVersionError` if either operand is not a decimal-
|
|
31
|
+
* integer string in `[0, Number.MAX_SAFE_INTEGER]`. Leading signs, leading
|
|
32
|
+
* zeros, decimal points, exponent notation, hex, whitespace, `'NaN'` and
|
|
33
|
+
* `'Infinity'` all reject.
|
|
34
|
+
*
|
|
35
|
+
* @category Utility
|
|
36
|
+
*/
|
|
37
|
+
export const compareBeaconVersion = (a, b) => {
|
|
38
|
+
const na = parseStrictDecimalInteger(a);
|
|
39
|
+
const nb = parseStrictDecimalInteger(b);
|
|
40
|
+
if (na === null || nb === null) {
|
|
41
|
+
throw new InvalidBeaconVersionError(a, b);
|
|
42
|
+
}
|
|
43
|
+
return na - nb;
|
|
44
|
+
};
|
|
45
|
+
/**
|
|
46
|
+
* Whether `version` is a valid peer.version at or above `threshold`.
|
|
47
|
+
*
|
|
48
|
+
* Single source of truth for the "is this peer at least version X" decision.
|
|
49
|
+
* Returns `false` for an absent version and for any value that fails the
|
|
50
|
+
* strict decimal-integer contract of `compareBeaconVersion` — i.e. malformed
|
|
51
|
+
* or untrusted input is always treated as below the threshold, so a hostile
|
|
52
|
+
* peer cannot trip a higher-version code path.
|
|
53
|
+
*
|
|
54
|
+
* @category Utility
|
|
55
|
+
*/
|
|
56
|
+
export const isAtLeastVersion = (version, threshold) => {
|
|
57
|
+
if (version === undefined) {
|
|
4
58
|
return false;
|
|
5
59
|
}
|
|
6
|
-
|
|
7
|
-
|
|
60
|
+
try {
|
|
61
|
+
return compareBeaconVersion(version, threshold) >= 0;
|
|
62
|
+
}
|
|
63
|
+
catch {
|
|
64
|
+
return false;
|
|
65
|
+
}
|
|
66
|
+
};
|
|
67
|
+
/**
|
|
68
|
+
* Whether `version` is at or above the multi-network (v4) threshold.
|
|
69
|
+
*
|
|
70
|
+
* @category Utility
|
|
71
|
+
*/
|
|
72
|
+
export const isMultiNetworkVersion = (version) => isAtLeastVersion(version, MULTI_NETWORK_FROM_VERSION);
|
|
73
|
+
export const usesWrappedMessages = (version) => {
|
|
74
|
+
// Use the same strict decimal-integer contract as compareBeaconVersion so
|
|
75
|
+
// wrapped-message routing agrees with the v4/multi-network routing: a loose
|
|
76
|
+
// value like '3.0', ' 3 ' or '03' (which Number() would accept) is treated
|
|
77
|
+
// as malformed and routed as non-wrapped rather than inconsistently.
|
|
78
|
+
const parsed = parseStrictDecimalInteger(version);
|
|
79
|
+
return parsed !== null && parsed >= MESSAGE_WRAPPED_FROM_VERSION;
|
|
80
|
+
};
|
|
81
|
+
/** The flat legacy wire dialect served to peers below the wrapped baseline. */
|
|
82
|
+
export const LEGACY_ENVELOPE_VERSION = '2';
|
|
83
|
+
/**
|
|
84
|
+
* The envelope version to stamp on an outgoing message for a peer that
|
|
85
|
+
* declared `peerVersion` at pairing: `min(peerVersion, BEACON_VERSION)` with
|
|
86
|
+
* a floor at the flat legacy dialect ('2').
|
|
87
|
+
*
|
|
88
|
+
* This is the backward-compatibility pivot: a peer that declared '2' — or
|
|
89
|
+
* never declared a version at all (legacy pairings, WalletConnect peers,
|
|
90
|
+
* malformed values) — is served the flat v2 dialect it has always spoken; a
|
|
91
|
+
* v3 peer receives '3' wrapped envelopes and never sees v4 payload fields;
|
|
92
|
+
* a v4 peer gets the full wrapped v4 wire. Callers pick the message SHAPE
|
|
93
|
+
* with `usesWrappedMessages(negotiated)` and gate v4 fields (`networks`/
|
|
94
|
+
* `accounts`) on `isMultiNetworkVersion(negotiated)`.
|
|
95
|
+
*
|
|
96
|
+
* @category Utility
|
|
97
|
+
*/
|
|
98
|
+
export const negotiateEnvelopeVersion = (peerVersion) => {
|
|
99
|
+
if (!isAtLeastVersion(peerVersion, String(MESSAGE_WRAPPED_FROM_VERSION))) {
|
|
100
|
+
return LEGACY_ENVELOPE_VERSION;
|
|
101
|
+
}
|
|
102
|
+
return isAtLeastVersion(peerVersion, BEACON_VERSION) ? BEACON_VERSION : peerVersion;
|
|
103
|
+
};
|
|
104
|
+
/**
|
|
105
|
+
* Build a wrapped beacon envelope. Single source of truth for the
|
|
106
|
+
* `{ id, version, senderId, message }` wire shape so senders cannot drift.
|
|
107
|
+
*
|
|
108
|
+
* @category Utility
|
|
109
|
+
*/
|
|
110
|
+
export const wrapBeaconMessage = (envelope, message) => ({
|
|
111
|
+
id: envelope.id,
|
|
112
|
+
version: envelope.version,
|
|
113
|
+
senderId: envelope.senderId,
|
|
114
|
+
message
|
|
115
|
+
});
|
|
116
|
+
/**
|
|
117
|
+
* Extract the inner payload of a wrapped beacon envelope, or `undefined`
|
|
118
|
+
* when the candidate's version does not follow the wrapped (v3+) contract.
|
|
119
|
+
* Callers must treat `undefined` as "not a wrapped message" and drop or
|
|
120
|
+
* tombstone it — never fall back to reading flat fields.
|
|
121
|
+
*
|
|
122
|
+
* @category Utility
|
|
123
|
+
*/
|
|
124
|
+
export const unwrapBeaconMessage = (candidate) => (usesWrappedMessages(candidate.version) ? candidate.message : undefined);
|
|
125
|
+
/**
|
|
126
|
+
* Build a disconnect message in the peer's negotiated dialect: a wrapped
|
|
127
|
+
* envelope for v3+ peers, the flat legacy shape for v2 peers. A legacy peer
|
|
128
|
+
* routes on the top-level `type` and would silently ignore a wrapped
|
|
129
|
+
* envelope — the goodbye must be spoken in the dialect the peer parses.
|
|
130
|
+
*
|
|
131
|
+
* @category Utility
|
|
132
|
+
*/
|
|
133
|
+
export const buildDisconnectMessage = (envelope, peerVersion) => {
|
|
134
|
+
const version = negotiateEnvelopeVersion(peerVersion);
|
|
135
|
+
return usesWrappedMessages(version)
|
|
136
|
+
? wrapBeaconMessage({ id: envelope.id, version, senderId: envelope.senderId }, { type: BeaconMessageType.Disconnect })
|
|
137
|
+
: {
|
|
138
|
+
id: envelope.id,
|
|
139
|
+
version,
|
|
140
|
+
senderId: envelope.senderId,
|
|
141
|
+
type: BeaconMessageType.Disconnect
|
|
142
|
+
};
|
|
8
143
|
};
|
|
9
144
|
//# sourceMappingURL=message-utils.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"message-utils.js","sourceRoot":"","sources":["../../../../src/utils/message-utils.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,4BAA4B,GAAG,CAAC,CAAA;AAE7C,MAAM,CAAC,MAAM,mBAAmB,GAAG,CAAC,OAAgB,EAAW,EAAE;IAC/D,
|
|
1
|
+
{"version":3,"file":"message-utils.js","sourceRoot":"","sources":["../../../../src/utils/message-utils.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n BeaconMessageType,\n BeaconMessageWrapper,\n DisconnectMessage\n} from '@tezos-x/octez.connect-types'\nimport { BEACON_VERSION } from '../constants'\n\n// Structural stand-in for the beaconV3 BeaconBaseMessage ({ type: unknown }).\n// The types barrel re-exports the flat BeaconBaseMessage (which also carries\n// id/version/senderId) under the same name, so constraining on the barrel\n// type would wrongly require envelope fields on the inner payload.\ninterface WrappedPayload { type: unknown }\nimport { InvalidBeaconVersionError } from '../errors/InvalidBeaconVersionError'\n\nexport const MESSAGE_WRAPPED_FROM_VERSION = 3\n\n// peer.version at or above which the multi-network (v4) protocol applies.\nexport const MULTI_NETWORK_FROM_VERSION = '4'\n\n// Strict decimal-integer: a lone `0` or non-zero digit followed by digits.\n// Rejects leading zeros on multi-digit values (e.g. `'04'`). A lone `0` is\n// kept valid so legacy compat paths can use it as a fallback/unknown version.\nconst DECIMAL_INTEGER_RE = /^(0|[1-9]\\d*)$/\n\nexport const parseStrictDecimalInteger = (value: unknown): number | null => {\n if (typeof value !== 'string') {\n return null\n }\n if (!DECIMAL_INTEGER_RE.test(value)) {\n return null\n }\n const parsed = Number(value)\n if (!Number.isFinite(parsed) || parsed > Number.MAX_SAFE_INTEGER) {\n return null\n }\n\n return parsed\n}\n\n/**\n * Compare two `peer.version` strings as strict decimal integers.\n *\n * Returns < 0 if `a < b`, 0 if equal, > 0 if `a > b` — same convention as\n * `Array.prototype.sort` comparators.\n *\n * Throws `InvalidBeaconVersionError` if either operand is not a decimal-\n * integer string in `[0, Number.MAX_SAFE_INTEGER]`. Leading signs, leading\n * zeros, decimal points, exponent notation, hex, whitespace, `'NaN'` and\n * `'Infinity'` all reject.\n *\n * @category Utility\n */\nexport const compareBeaconVersion = (a: unknown, b: unknown): number => {\n const na = parseStrictDecimalInteger(a)\n const nb = parseStrictDecimalInteger(b)\n\n if (na === null || nb === null) {\n throw new InvalidBeaconVersionError(a, b)\n }\n\n return na - nb\n}\n\n/**\n * Whether `version` is a valid peer.version at or above `threshold`.\n *\n * Single source of truth for the \"is this peer at least version X\" decision.\n * Returns `false` for an absent version and for any value that fails the\n * strict decimal-integer contract of `compareBeaconVersion` — i.e. malformed\n * or untrusted input is always treated as below the threshold, so a hostile\n * peer cannot trip a higher-version code path.\n *\n * @category Utility\n */\nexport const isAtLeastVersion = (version: string | undefined, threshold: string): boolean => {\n if (version === undefined) {\n return false\n }\n try {\n return compareBeaconVersion(version, threshold) >= 0\n } catch {\n return false\n }\n}\n\n/**\n * Whether `version` is at or above the multi-network (v4) threshold.\n *\n * @category Utility\n */\nexport const isMultiNetworkVersion = (version: string | undefined): boolean =>\n isAtLeastVersion(version, MULTI_NETWORK_FROM_VERSION)\n\nexport const usesWrappedMessages = (version?: string): boolean => {\n // Use the same strict decimal-integer contract as compareBeaconVersion so\n // wrapped-message routing agrees with the v4/multi-network routing: a loose\n // value like '3.0', ' 3 ' or '03' (which Number() would accept) is treated\n // as malformed and routed as non-wrapped rather than inconsistently.\n const parsed = parseStrictDecimalInteger(version)\n\n return parsed !== null && parsed >= MESSAGE_WRAPPED_FROM_VERSION\n}\n\n/** The flat legacy wire dialect served to peers below the wrapped baseline. */\nexport const LEGACY_ENVELOPE_VERSION = '2'\n\n/**\n * The envelope version to stamp on an outgoing message for a peer that\n * declared `peerVersion` at pairing: `min(peerVersion, BEACON_VERSION)` with\n * a floor at the flat legacy dialect ('2').\n *\n * This is the backward-compatibility pivot: a peer that declared '2' — or\n * never declared a version at all (legacy pairings, WalletConnect peers,\n * malformed values) — is served the flat v2 dialect it has always spoken; a\n * v3 peer receives '3' wrapped envelopes and never sees v4 payload fields;\n * a v4 peer gets the full wrapped v4 wire. Callers pick the message SHAPE\n * with `usesWrappedMessages(negotiated)` and gate v4 fields (`networks`/\n * `accounts`) on `isMultiNetworkVersion(negotiated)`.\n *\n * @category Utility\n */\nexport const negotiateEnvelopeVersion = (peerVersion: string | undefined): string => {\n if (!isAtLeastVersion(peerVersion, String(MESSAGE_WRAPPED_FROM_VERSION))) {\n return LEGACY_ENVELOPE_VERSION\n }\n\n return isAtLeastVersion(peerVersion, BEACON_VERSION) ? BEACON_VERSION : (peerVersion as string)\n}\n\n/**\n * Build a wrapped beacon envelope. Single source of truth for the\n * `{ id, version, senderId, message }` wire shape so senders cannot drift.\n *\n * @category Utility\n */\nexport const wrapBeaconMessage = <T extends WrappedPayload>(\n envelope: { id: string; version: string; senderId: string },\n message: T\n): BeaconMessageWrapper<T> => ({\n id: envelope.id,\n version: envelope.version,\n senderId: envelope.senderId,\n message\n})\n\n/**\n * Extract the inner payload of a wrapped beacon envelope, or `undefined`\n * when the candidate's version does not follow the wrapped (v3+) contract.\n * Callers must treat `undefined` as \"not a wrapped message\" and drop or\n * tombstone it — never fall back to reading flat fields.\n *\n * @category Utility\n */\nexport const unwrapBeaconMessage = <T extends WrappedPayload>(candidate: {\n version?: string\n message?: T\n}): T | undefined => (usesWrappedMessages(candidate.version) ? candidate.message : undefined)\n\n/**\n * Build a disconnect message in the peer's negotiated dialect: a wrapped\n * envelope for v3+ peers, the flat legacy shape for v2 peers. A legacy peer\n * routes on the top-level `type` and would silently ignore a wrapped\n * envelope — the goodbye must be spoken in the dialect the peer parses.\n *\n * @category Utility\n */\nexport const buildDisconnectMessage = (\n envelope: { id: string; senderId: string },\n peerVersion: string | undefined\n): DisconnectMessage | BeaconMessageWrapper<{ type: BeaconMessageType.Disconnect }> => {\n const version = negotiateEnvelopeVersion(peerVersion)\n\n return usesWrappedMessages(version)\n ? wrapBeaconMessage(\n { id: envelope.id, version, senderId: envelope.senderId },\n { type: BeaconMessageType.Disconnect }\n )\n : {\n id: envelope.id,\n version,\n senderId: envelope.senderId,\n type: BeaconMessageType.Disconnect\n }\n}\n"]}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Default minimum wallet version the dApp accepts when the option is omitted.
|
|
3
|
+
*
|
|
4
|
+
* Deliberately the lowest protocol version still supported, so the gate is
|
|
5
|
+
* effectively opt-in: by default every wallet the SDK can talk to (v2/v3/v4)
|
|
6
|
+
* is accepted, preserving backward compatibility. A dApp that needs the v4
|
|
7
|
+
* multi-network protocol sets `requiredMinimumVersion: '4'` explicitly.
|
|
8
|
+
*/
|
|
9
|
+
export declare const DEFAULT_REQUIRED_MINIMUM_VERSION = "2";
|
|
10
|
+
/**
|
|
11
|
+
* Resolve a dApp's `requiredMinimumVersion` option against the SDK's
|
|
12
|
+
* `BEACON_VERSION`. Returns {@link DEFAULT_REQUIRED_MINIMUM_VERSION} when
|
|
13
|
+
* undefined; otherwise validates the supplied value is a decimal-integer
|
|
14
|
+
* string in `[1, BEACON_VERSION]` and returns it unchanged.
|
|
15
|
+
*
|
|
16
|
+
* Throws `InvalidRequiredMinimumVersionError` for any malformed,
|
|
17
|
+
* out-of-range, or future-version input.
|
|
18
|
+
*/
|
|
19
|
+
export declare const resolveRequiredMinimumVersion: (providedValue: string | undefined) => string;
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import { BEACON_VERSION } from '../constants';
|
|
2
|
+
import { InvalidRequiredMinimumVersionError } from '../errors/InvalidRequiredMinimumVersionError';
|
|
3
|
+
import { compareBeaconVersion, parseStrictDecimalInteger } from './message-utils';
|
|
4
|
+
/**
|
|
5
|
+
* Default minimum wallet version the dApp accepts when the option is omitted.
|
|
6
|
+
*
|
|
7
|
+
* Deliberately the lowest protocol version still supported, so the gate is
|
|
8
|
+
* effectively opt-in: by default every wallet the SDK can talk to (v2/v3/v4)
|
|
9
|
+
* is accepted, preserving backward compatibility. A dApp that needs the v4
|
|
10
|
+
* multi-network protocol sets `requiredMinimumVersion: '4'` explicitly.
|
|
11
|
+
*/
|
|
12
|
+
export const DEFAULT_REQUIRED_MINIMUM_VERSION = '2';
|
|
13
|
+
/**
|
|
14
|
+
* Resolve a dApp's `requiredMinimumVersion` option against the SDK's
|
|
15
|
+
* `BEACON_VERSION`. Returns {@link DEFAULT_REQUIRED_MINIMUM_VERSION} when
|
|
16
|
+
* undefined; otherwise validates the supplied value is a decimal-integer
|
|
17
|
+
* string in `[1, BEACON_VERSION]` and returns it unchanged.
|
|
18
|
+
*
|
|
19
|
+
* Throws `InvalidRequiredMinimumVersionError` for any malformed,
|
|
20
|
+
* out-of-range, or future-version input.
|
|
21
|
+
*/
|
|
22
|
+
export const resolveRequiredMinimumVersion = (providedValue) => {
|
|
23
|
+
if (providedValue === undefined) {
|
|
24
|
+
return DEFAULT_REQUIRED_MINIMUM_VERSION;
|
|
25
|
+
}
|
|
26
|
+
// Validate against the SAME strict contract compareBeaconVersion enforces,
|
|
27
|
+
// up front, so every rejection here is an InvalidRequiredMinimumVersionError
|
|
28
|
+
// rather than a leaked InvalidBeaconVersionError from the comparison below.
|
|
29
|
+
// Reuse parseStrictDecimalInteger (the single owner of that contract) instead
|
|
30
|
+
// of re-declaring the regex + MAX_SAFE_INTEGER bound here.
|
|
31
|
+
const parsed = parseStrictDecimalInteger(providedValue);
|
|
32
|
+
if (parsed === null) {
|
|
33
|
+
throw new InvalidRequiredMinimumVersionError(providedValue, BEACON_VERSION, 'value must be a decimal-integer string (e.g. "3", "4")');
|
|
34
|
+
}
|
|
35
|
+
if (parsed < 1) {
|
|
36
|
+
throw new InvalidRequiredMinimumVersionError(providedValue, BEACON_VERSION, 'value must be >= 1');
|
|
37
|
+
}
|
|
38
|
+
if (compareBeaconVersion(providedValue, BEACON_VERSION) > 0) {
|
|
39
|
+
throw new InvalidRequiredMinimumVersionError(providedValue, BEACON_VERSION, `value cannot exceed the SDK's own BEACON_VERSION (${BEACON_VERSION})`);
|
|
40
|
+
}
|
|
41
|
+
return providedValue;
|
|
42
|
+
};
|
|
43
|
+
//# sourceMappingURL=required-minimum-version.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"required-minimum-version.js","sourceRoot":"","sources":["../../../../src/utils/required-minimum-version.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,cAAc,CAAA;AAC7C,OAAO,EAAE,kCAAkC,EAAE,MAAM,8CAA8C,CAAA;AACjG,OAAO,EAAE,oBAAoB,EAAE,yBAAyB,EAAE,MAAM,iBAAiB,CAAA;AAEjF;;;;;;;GAOG;AACH,MAAM,CAAC,MAAM,gCAAgC,GAAG,GAAG,CAAA;AAEnD;;;;;;;;GAQG;AACH,MAAM,CAAC,MAAM,6BAA6B,GAAG,CAC3C,aAAiC,EACzB,EAAE;IACV,IAAI,aAAa,KAAK,SAAS,EAAE,CAAC;QAChC,OAAO,gCAAgC,CAAA;IACzC,CAAC;IAED,2EAA2E;IAC3E,6EAA6E;IAC7E,4EAA4E;IAC5E,8EAA8E;IAC9E,2DAA2D;IAC3D,MAAM,MAAM,GAAG,yBAAyB,CAAC,aAAa,CAAC,CAAA;IACvD,IAAI,MAAM,KAAK,IAAI,EAAE,CAAC;QACpB,MAAM,IAAI,kCAAkC,CAC1C,aAAa,EACb,cAAc,EACd,wDAAwD,CACzD,CAAA;IACH,CAAC;IAED,IAAI,MAAM,GAAG,CAAC,EAAE,CAAC;QACf,MAAM,IAAI,kCAAkC,CAC1C,aAAa,EACb,cAAc,EACd,oBAAoB,CACrB,CAAA;IACH,CAAC;IAED,IAAI,oBAAoB,CAAC,aAAa,EAAE,cAAc,CAAC,GAAG,CAAC,EAAE,CAAC;QAC5D,MAAM,IAAI,kCAAkC,CAC1C,aAAa,EACb,cAAc,EACd,qDAAqD,cAAc,GAAG,CACvE,CAAA;IACH,CAAC;IAED,OAAO,aAAa,CAAA;AACtB,CAAC,CAAA","sourcesContent":["import { BEACON_VERSION } from '../constants'\nimport { InvalidRequiredMinimumVersionError } from '../errors/InvalidRequiredMinimumVersionError'\nimport { compareBeaconVersion, parseStrictDecimalInteger } from './message-utils'\n\n/**\n * Default minimum wallet version the dApp accepts when the option is omitted.\n *\n * Deliberately the lowest protocol version still supported, so the gate is\n * effectively opt-in: by default every wallet the SDK can talk to (v2/v3/v4)\n * is accepted, preserving backward compatibility. A dApp that needs the v4\n * multi-network protocol sets `requiredMinimumVersion: '4'` explicitly.\n */\nexport const DEFAULT_REQUIRED_MINIMUM_VERSION = '2'\n\n/**\n * Resolve a dApp's `requiredMinimumVersion` option against the SDK's\n * `BEACON_VERSION`. Returns {@link DEFAULT_REQUIRED_MINIMUM_VERSION} when\n * undefined; otherwise validates the supplied value is a decimal-integer\n * string in `[1, BEACON_VERSION]` and returns it unchanged.\n *\n * Throws `InvalidRequiredMinimumVersionError` for any malformed,\n * out-of-range, or future-version input.\n */\nexport const resolveRequiredMinimumVersion = (\n providedValue: string | undefined\n): string => {\n if (providedValue === undefined) {\n return DEFAULT_REQUIRED_MINIMUM_VERSION\n }\n\n // Validate against the SAME strict contract compareBeaconVersion enforces,\n // up front, so every rejection here is an InvalidRequiredMinimumVersionError\n // rather than a leaked InvalidBeaconVersionError from the comparison below.\n // Reuse parseStrictDecimalInteger (the single owner of that contract) instead\n // of re-declaring the regex + MAX_SAFE_INTEGER bound here.\n const parsed = parseStrictDecimalInteger(providedValue)\n if (parsed === null) {\n throw new InvalidRequiredMinimumVersionError(\n providedValue,\n BEACON_VERSION,\n 'value must be a decimal-integer string (e.g. \"3\", \"4\")'\n )\n }\n\n if (parsed < 1) {\n throw new InvalidRequiredMinimumVersionError(\n providedValue,\n BEACON_VERSION,\n 'value must be >= 1'\n )\n }\n\n if (compareBeaconVersion(providedValue, BEACON_VERSION) > 0) {\n throw new InvalidRequiredMinimumVersionError(\n providedValue,\n BEACON_VERSION,\n `value cannot exceed the SDK's own BEACON_VERSION (${BEACON_VERSION})`\n )\n }\n\n return providedValue\n}\n"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@tezos-x/octez.connect-core",
|
|
3
|
-
"version": "5.0.
|
|
3
|
+
"version": "5.0.1",
|
|
4
4
|
"description": "This package contains internal methods that are used by both the dApp and wallet client.",
|
|
5
5
|
"author": "Blockchain Infra <blockchain.infra@trili.tech>",
|
|
6
6
|
"homepage": "https://octez-connect.tezos.com",
|
|
@@ -38,8 +38,8 @@
|
|
|
38
38
|
"@stablelib/nacl": "^2.0.1",
|
|
39
39
|
"@stablelib/utf8": "^2.1.0",
|
|
40
40
|
"@stablelib/x25519-session": "^2.0.1",
|
|
41
|
-
"@tezos-x/octez.connect-types": "5.0.
|
|
42
|
-
"@tezos-x/octez.connect-utils": "5.0.
|
|
41
|
+
"@tezos-x/octez.connect-types": "5.0.1",
|
|
42
|
+
"@tezos-x/octez.connect-utils": "5.0.1",
|
|
43
43
|
"broadcast-channel": "^7.3.0",
|
|
44
44
|
"bs58check": "4.0.0"
|
|
45
45
|
}
|