kokio-sdk 0.1.3 → 1.0.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.
Files changed (86) hide show
  1. package/README.md +185 -1
  2. package/dist/esm/admin/config-admin.js +85 -0
  3. package/dist/esm/admin/interface/deviceWalletClass.js +34 -0
  4. package/dist/esm/admin/interface/deviceWalletFactoryClass.js +57 -0
  5. package/dist/esm/admin/interface/eSIMWalletClass.js +31 -0
  6. package/dist/esm/admin/interface/eSIMWalletFactoryClass.js +22 -0
  7. package/dist/esm/admin/interface/lazyWalletRegistryClass.js +33 -0
  8. package/dist/esm/admin/interface/registryClass.js +43 -0
  9. package/dist/esm/config.js +18 -2
  10. package/dist/esm/interface/constantsClass.js +33 -10
  11. package/dist/esm/interface/deviceWalletClass.js +1 -13
  12. package/dist/esm/interface/eSIMWalletClass.js +2 -8
  13. package/dist/esm/interface/eSIMWalletFactoryClass.js +2 -8
  14. package/dist/esm/interface/lazyWalletRegistryClass.js +2 -11
  15. package/dist/esm/logic/P256Verifier.js +8 -15
  16. package/dist/esm/logic/account-kit/createSmartAccount.js +78 -27
  17. package/dist/esm/logic/admin/deviceWallet.eoa.js +42 -0
  18. package/dist/esm/logic/admin/deviceWalletFactory.eoa.js +133 -0
  19. package/dist/esm/logic/admin/eSIMWallet.eoa.js +30 -0
  20. package/dist/esm/logic/admin/eSIMWalletFactory.eoa.js +43 -0
  21. package/dist/esm/logic/admin/lazyWalletRegistry.eoa.js +62 -0
  22. package/dist/esm/logic/admin/reads/deviceWallet.reads.js +45 -0
  23. package/dist/esm/logic/admin/reads/deviceWalletFactory.reads.js +87 -0
  24. package/dist/esm/logic/admin/reads/eSIMWallet.reads.js +44 -0
  25. package/dist/esm/logic/admin/reads/eSIMWalletFactory.reads.js +32 -0
  26. package/dist/esm/logic/admin/reads/lazyWalletRegistry.reads.js +62 -0
  27. package/dist/esm/logic/admin/reads/registry.reads.js +136 -0
  28. package/dist/esm/logic/admin/registry.eoa.js +23 -0
  29. package/dist/esm/logic/constants.js +31 -71
  30. package/dist/esm/logic/deviceWallet.js +28 -91
  31. package/dist/esm/logic/deviceWalletFactory.js +21 -30
  32. package/dist/esm/logic/eSIMWallet.js +25 -57
  33. package/dist/esm/logic/eSIMWalletFactory.js +17 -50
  34. package/dist/esm/logic/errors.js +118 -0
  35. package/dist/esm/logic/lazyWalletRegistry.js +12 -72
  36. package/dist/esm/logic/utils.js +3 -3
  37. package/dist/types/abis/BeaconProxy.d.ts +58 -2
  38. package/dist/types/abis/DeviceWallet.d.ts +702 -2
  39. package/dist/types/abis/DeviceWalletFactory.d.ts +634 -2
  40. package/dist/types/abis/ESIMWallet.d.ts +375 -2
  41. package/dist/types/abis/ESIMWalletFactory.d.ts +355 -2
  42. package/dist/types/abis/LazyWalletRegistry.d.ts +565 -2
  43. package/dist/types/abis/P256Verifier.d.ts +56 -2
  44. package/dist/types/abis/Registry.d.ts +623 -2
  45. package/dist/types/abis/RegistryHelper.d.ts +295 -2
  46. package/dist/types/admin/config-admin.d.ts +55 -0
  47. package/dist/types/admin/interface/deviceWalletClass.d.ts +17 -0
  48. package/dist/types/admin/interface/deviceWalletFactoryClass.d.ts +25 -0
  49. package/dist/types/admin/interface/eSIMWalletClass.d.ts +17 -0
  50. package/dist/types/admin/interface/eSIMWalletFactoryClass.d.ts +10 -0
  51. package/dist/types/admin/interface/lazyWalletRegistryClass.d.ts +14 -0
  52. package/dist/types/admin/interface/registryClass.d.ts +17 -0
  53. package/dist/types/config.d.ts +14 -2
  54. package/dist/types/interface/P256VerifierClass.d.ts +2 -1
  55. package/dist/types/interface/constantsClass.d.ts +23 -3
  56. package/dist/types/interface/deviceWalletClass.d.ts +24 -28
  57. package/dist/types/interface/deviceWalletFactoryClass.d.ts +27 -26
  58. package/dist/types/interface/eSIMWalletClass.d.ts +2 -4
  59. package/dist/types/interface/eSIMWalletFactoryClass.d.ts +24 -26
  60. package/dist/types/interface/lazyWalletRegistryClass.d.ts +1 -6
  61. package/dist/types/interface/smartAccountClass.d.ts +23 -23
  62. package/dist/types/logic/P256Verifier.d.ts +2 -1
  63. package/dist/types/logic/account-kit/createSmartAccount.d.ts +38 -1
  64. package/dist/types/logic/admin/deviceWallet.eoa.d.ts +12 -0
  65. package/dist/types/logic/admin/deviceWalletFactory.eoa.d.ts +33 -0
  66. package/dist/types/logic/admin/eSIMWallet.eoa.d.ts +14 -0
  67. package/dist/types/logic/admin/eSIMWalletFactory.eoa.d.ts +13 -0
  68. package/dist/types/logic/admin/lazyWalletRegistry.eoa.d.ts +18 -0
  69. package/dist/types/logic/admin/reads/deviceWallet.reads.d.ts +16 -0
  70. package/dist/types/logic/admin/reads/deviceWalletFactory.reads.d.ts +26 -0
  71. package/dist/types/logic/admin/reads/eSIMWallet.reads.d.ts +15 -0
  72. package/dist/types/logic/admin/reads/eSIMWalletFactory.reads.d.ts +10 -0
  73. package/dist/types/logic/admin/reads/lazyWalletRegistry.reads.d.ts +20 -0
  74. package/dist/types/logic/admin/reads/registry.reads.d.ts +34 -0
  75. package/dist/types/logic/admin/registry.eoa.d.ts +7 -0
  76. package/dist/types/logic/deviceWallet.d.ts +1 -5
  77. package/dist/types/logic/deviceWalletFactory.d.ts +5 -4
  78. package/dist/types/logic/eSIMWallet.d.ts +1 -3
  79. package/dist/types/logic/eSIMWalletFactory.d.ts +2 -4
  80. package/dist/types/logic/errors.d.ts +63 -0
  81. package/dist/types/logic/lazyWalletRegistry.d.ts +1 -6
  82. package/dist/types/logic/utils.d.ts +8 -1
  83. package/dist/types/types.d.ts +1 -1
  84. package/package.json +17 -4
  85. package/dist/esm/interface/utilsClass.js +0 -13
  86. package/dist/types/interface/utilsClass.d.ts +0 -2567
@@ -0,0 +1,87 @@
1
+ import { publicActions } from "viem";
2
+ import { _getChainSpecificConstants } from "../../constants.js";
3
+ import { DeviceWalletFactory } from "../../../abis/index.js";
4
+ /**
5
+ * Read-only admin logic for `DeviceWalletFactory` - the contract's public
6
+ * storage getters and `view` functions, surfaced for the backend.
7
+ *
8
+ * A viem `WalletClient` carries no public actions, so each read extends it with
9
+ * `publicActions` (reusing the same transport, so it also works under an anvil
10
+ * fork) before calling `readContract`. Reads need no EOA account, so there is no
11
+ * `MissingEOAWalletError` guard.
12
+ */
13
+ /** The admin EOA (`eSIMWalletAdmin`) currently set on the factory. */
14
+ export const _eSIMWalletAdmin = async (client) => {
15
+ const chainID = await client.getChainId();
16
+ const rpcURL = client.transport.url;
17
+ const values = _getChainSpecificConstants(chainID, rpcURL);
18
+ return client.extend(publicActions).readContract({
19
+ address: values.factoryAddresses.DEVICE_WALLET_FACTORY,
20
+ abi: DeviceWalletFactory,
21
+ functionName: "eSIMWalletAdmin",
22
+ args: []
23
+ });
24
+ };
25
+ /** The vault EOA that receives eSIM payments. */
26
+ export const _vault = async (client) => {
27
+ const chainID = await client.getChainId();
28
+ const rpcURL = client.transport.url;
29
+ const values = _getChainSpecificConstants(chainID, rpcURL);
30
+ return client.extend(publicActions).readContract({
31
+ address: values.factoryAddresses.DEVICE_WALLET_FACTORY,
32
+ abi: DeviceWalletFactory,
33
+ functionName: "vault",
34
+ args: []
35
+ });
36
+ };
37
+ /** The pending admin proposed via `requestAdminUpdate` (zero address if none). */
38
+ export const _newRequestedAdmin = async (client) => {
39
+ const chainID = await client.getChainId();
40
+ const rpcURL = client.transport.url;
41
+ const values = _getChainSpecificConstants(chainID, rpcURL);
42
+ return client.extend(publicActions).readContract({
43
+ address: values.factoryAddresses.DEVICE_WALLET_FACTORY,
44
+ abi: DeviceWalletFactory,
45
+ functionName: "newRequestedAdmin",
46
+ args: []
47
+ });
48
+ };
49
+ /** Whether a device wallet has been registered with the factory. */
50
+ export const _deviceWalletInfoAdded = async (client, deviceWallet) => {
51
+ const chainID = await client.getChainId();
52
+ const rpcURL = client.transport.url;
53
+ const values = _getChainSpecificConstants(chainID, rpcURL);
54
+ return client.extend(publicActions).readContract({
55
+ address: values.factoryAddresses.DEVICE_WALLET_FACTORY,
56
+ abi: DeviceWalletFactory,
57
+ functionName: "deviceWalletInfoAdded",
58
+ args: [deviceWallet]
59
+ });
60
+ };
61
+ /** The current device-wallet beacon implementation. */
62
+ export const _getCurrentDeviceWalletImplementation = async (client) => {
63
+ const chainID = await client.getChainId();
64
+ const rpcURL = client.transport.url;
65
+ const values = _getChainSpecificConstants(chainID, rpcURL);
66
+ return client.extend(publicActions).readContract({
67
+ address: values.factoryAddresses.DEVICE_WALLET_FACTORY,
68
+ abi: DeviceWalletFactory,
69
+ functionName: "getCurrentDeviceWalletImplementation",
70
+ args: []
71
+ });
72
+ };
73
+ /**
74
+ * The counterfactual (CREATE2) device-wallet address for an owner key. On-chain
75
+ * arg order is `(ownerKey, uid, salt)` - note this differs from `createAccount`.
76
+ */
77
+ export const _getCounterFactualAddress = async (client, deviceWalletOwnerKey, deviceUniqueIdentifier, salt) => {
78
+ const chainID = await client.getChainId();
79
+ const rpcURL = client.transport.url;
80
+ const values = _getChainSpecificConstants(chainID, rpcURL);
81
+ return client.extend(publicActions).readContract({
82
+ address: values.factoryAddresses.DEVICE_WALLET_FACTORY,
83
+ abi: DeviceWalletFactory,
84
+ functionName: "getCounterFactualAddress",
85
+ args: [deviceWalletOwnerKey, deviceUniqueIdentifier, salt]
86
+ });
87
+ };
@@ -0,0 +1,44 @@
1
+ import { publicActions } from "viem";
2
+ import { ESIMWallet } from "../../../abis/index.js";
3
+ /**
4
+ * Read-only admin logic targeting a specific `ESIMWallet` instance (its address
5
+ * is passed in). Surfaces the instance's public storage getters + `owner` view
6
+ * for the backend. Each read extends the `WalletClient` with `publicActions`; no
7
+ * EOA account is required.
8
+ */
9
+ /** The `ESIMWalletFactory` that deployed this eSIM wallet. */
10
+ export const _eSIMWalletFactory = async (client, eSIMWalletAddress) => {
11
+ return client.extend(publicActions).readContract({
12
+ address: eSIMWalletAddress,
13
+ abi: ESIMWallet,
14
+ functionName: "eSIMWalletFactory",
15
+ args: []
16
+ });
17
+ };
18
+ /** The eSIM's unique identifier string (empty until set by the admin). */
19
+ export const _eSIMUniqueIdentifier = async (client, eSIMWalletAddress) => {
20
+ return client.extend(publicActions).readContract({
21
+ address: eSIMWalletAddress,
22
+ abi: ESIMWallet,
23
+ functionName: "eSIMUniqueIdentifier",
24
+ args: []
25
+ });
26
+ };
27
+ /** The pending owner proposed via `requestTransferOwnership` (zero if none). */
28
+ export const _newRequestedOwner = async (client, eSIMWalletAddress) => {
29
+ return client.extend(publicActions).readContract({
30
+ address: eSIMWalletAddress,
31
+ abi: ESIMWallet,
32
+ functionName: "newRequestedOwner",
33
+ args: []
34
+ });
35
+ };
36
+ /** The current owner (device wallet) of this eSIM wallet. */
37
+ export const _owner = async (client, eSIMWalletAddress) => {
38
+ return client.extend(publicActions).readContract({
39
+ address: eSIMWalletAddress,
40
+ abi: ESIMWallet,
41
+ functionName: "owner",
42
+ args: []
43
+ });
44
+ };
@@ -0,0 +1,32 @@
1
+ import { publicActions } from "viem";
2
+ import { _getChainSpecificConstants } from "../../constants.js";
3
+ import { ESIMWalletFactory } from "../../../abis/index.js";
4
+ /**
5
+ * Read-only admin logic for `ESIMWalletFactory` - its public storage getter and
6
+ * `view` function, surfaced for the backend. Each read extends the `WalletClient`
7
+ * with `publicActions` (no EOA account required).
8
+ */
9
+ /** Whether an eSIM wallet was deployed by this factory. */
10
+ export const _isESIMWalletDeployed = async (client, eSIMWallet) => {
11
+ const chainID = await client.getChainId();
12
+ const rpcURL = client.transport.url;
13
+ const values = _getChainSpecificConstants(chainID, rpcURL);
14
+ return client.extend(publicActions).readContract({
15
+ address: values.factoryAddresses.ESIM_WALLET_FACTORY,
16
+ abi: ESIMWalletFactory,
17
+ functionName: "isESIMWalletDeployed",
18
+ args: [eSIMWallet]
19
+ });
20
+ };
21
+ /** The current eSIM-wallet beacon implementation. */
22
+ export const _getCurrentESIMWalletImplementation = async (client) => {
23
+ const chainID = await client.getChainId();
24
+ const rpcURL = client.transport.url;
25
+ const values = _getChainSpecificConstants(chainID, rpcURL);
26
+ return client.extend(publicActions).readContract({
27
+ address: values.factoryAddresses.ESIM_WALLET_FACTORY,
28
+ abi: ESIMWalletFactory,
29
+ functionName: "getCurrentESIMWalletImplementation",
30
+ args: []
31
+ });
32
+ };
@@ -0,0 +1,62 @@
1
+ import { publicActions } from "viem";
2
+ import { _getChainSpecificConstants } from "../../constants.js";
3
+ import { LazyWalletRegistry } from "../../../abis/index.js";
4
+ /**
5
+ * Read-only admin logic for `LazyWalletRegistry` - its public storage getters,
6
+ * surfaced for the backend's fiat/lazy provisioning flows. Each read extends the
7
+ * `WalletClient` with `publicActions`; no EOA account is required.
8
+ *
9
+ * Note: `deviceIdentifierToESIMDetails` and
10
+ * `eSIMIdentifiersAssociatedWithDeviceIdentifier` back dynamic arrays on chain,
11
+ * so their auto-generated getters take an element `index` and return one entry -
12
+ * callers iterate indices to read the whole list (there is no full-array getter).
13
+ */
14
+ /** The upgrade-manager (owner) EOA of the lazy registry. */
15
+ export const _upgradeManager = async (client) => {
16
+ const chainID = await client.getChainId();
17
+ const rpcURL = client.transport.url;
18
+ const values = _getChainSpecificConstants(chainID, rpcURL);
19
+ return client.extend(publicActions).readContract({
20
+ address: values.factoryAddresses.LAZY_WALLET_REGISTRY,
21
+ abi: LazyWalletRegistry,
22
+ functionName: "upgradeManager",
23
+ args: []
24
+ });
25
+ };
26
+ /** The device identifier an eSIM identifier is currently associated with. */
27
+ export const _eSIMIdentifierToDeviceIdentifier = async (client, eSIMIdentifier) => {
28
+ const chainID = await client.getChainId();
29
+ const rpcURL = client.transport.url;
30
+ const values = _getChainSpecificConstants(chainID, rpcURL);
31
+ return client.extend(publicActions).readContract({
32
+ address: values.factoryAddresses.LAZY_WALLET_REGISTRY,
33
+ abi: LazyWalletRegistry,
34
+ functionName: "eSIMIdentifierToDeviceIdentifier",
35
+ args: [eSIMIdentifier]
36
+ });
37
+ };
38
+ /** One data-bundle history entry for a (device, eSIM) pair, by array index. */
39
+ export const _deviceIdentifierToESIMDetails = async (client, deviceIdentifier, eSIMIdentifier, index) => {
40
+ const chainID = await client.getChainId();
41
+ const rpcURL = client.transport.url;
42
+ const values = _getChainSpecificConstants(chainID, rpcURL);
43
+ const [dataBundleID, dataBundlePrice] = await client.extend(publicActions).readContract({
44
+ address: values.factoryAddresses.LAZY_WALLET_REGISTRY,
45
+ abi: LazyWalletRegistry,
46
+ functionName: "deviceIdentifierToESIMDetails",
47
+ args: [deviceIdentifier, eSIMIdentifier, index]
48
+ });
49
+ return { dataBundleID, dataBundlePrice };
50
+ };
51
+ /** One eSIM identifier associated with a device identifier, by array index. */
52
+ export const _eSIMIdentifiersAssociatedWithDeviceIdentifier = async (client, deviceIdentifier, index) => {
53
+ const chainID = await client.getChainId();
54
+ const rpcURL = client.transport.url;
55
+ const values = _getChainSpecificConstants(chainID, rpcURL);
56
+ return client.extend(publicActions).readContract({
57
+ address: values.factoryAddresses.LAZY_WALLET_REGISTRY,
58
+ abi: LazyWalletRegistry,
59
+ functionName: "eSIMIdentifiersAssociatedWithDeviceIdentifier",
60
+ args: [deviceIdentifier, index]
61
+ });
62
+ };
@@ -0,0 +1,136 @@
1
+ import { publicActions } from "viem";
2
+ import { _getChainSpecificConstants } from "../../constants.js";
3
+ import { Registry } from "../../../abis/index.js";
4
+ /**
5
+ * Read-only admin logic for `Registry` (which inherits `RegistryHelper`, so its
6
+ * ABI carries the helper mappings too). Surfaces the public storage getters for
7
+ * the backend. Each read extends the `WalletClient` with `publicActions`; no EOA
8
+ * account is required.
9
+ */
10
+ /** The admin EOA (`eSIMWalletAdmin`) recorded in the registry. */
11
+ export const _eSIMWalletAdmin = async (client) => {
12
+ const chainID = await client.getChainId();
13
+ const rpcURL = client.transport.url;
14
+ const values = _getChainSpecificConstants(chainID, rpcURL);
15
+ return client.extend(publicActions).readContract({
16
+ address: values.factoryAddresses.REGISTRY,
17
+ abi: Registry,
18
+ functionName: "eSIMWalletAdmin",
19
+ args: []
20
+ });
21
+ };
22
+ /** The vault EOA recorded in the registry. */
23
+ export const _vault = async (client) => {
24
+ const chainID = await client.getChainId();
25
+ const rpcURL = client.transport.url;
26
+ const values = _getChainSpecificConstants(chainID, rpcURL);
27
+ return client.extend(publicActions).readContract({
28
+ address: values.factoryAddresses.REGISTRY,
29
+ abi: Registry,
30
+ functionName: "vault",
31
+ args: []
32
+ });
33
+ };
34
+ /** The upgrade-manager (owner) EOA recorded in the registry. */
35
+ export const _upgradeManager = async (client) => {
36
+ const chainID = await client.getChainId();
37
+ const rpcURL = client.transport.url;
38
+ const values = _getChainSpecificConstants(chainID, rpcURL);
39
+ return client.extend(publicActions).readContract({
40
+ address: values.factoryAddresses.REGISTRY,
41
+ abi: Registry,
42
+ functionName: "upgradeManager",
43
+ args: []
44
+ });
45
+ };
46
+ /** The `LazyWalletRegistry` address wired into the registry. */
47
+ export const _lazyWalletRegistry = async (client) => {
48
+ const chainID = await client.getChainId();
49
+ const rpcURL = client.transport.url;
50
+ const values = _getChainSpecificConstants(chainID, rpcURL);
51
+ return client.extend(publicActions).readContract({
52
+ address: values.factoryAddresses.REGISTRY,
53
+ abi: Registry,
54
+ functionName: "lazyWalletRegistry",
55
+ args: []
56
+ });
57
+ };
58
+ /** The device wallet registered for a device unique identifier (zero if none). */
59
+ export const _uniqueIdentifierToDeviceWallet = async (client, deviceIdentifier) => {
60
+ const chainID = await client.getChainId();
61
+ const rpcURL = client.transport.url;
62
+ const values = _getChainSpecificConstants(chainID, rpcURL);
63
+ return client.extend(publicActions).readContract({
64
+ address: values.factoryAddresses.REGISTRY,
65
+ abi: Registry,
66
+ functionName: "uniqueIdentifierToDeviceWallet",
67
+ args: [deviceIdentifier]
68
+ });
69
+ };
70
+ /**
71
+ * One of a device wallet's two P-256 owner keys. The on-chain getter for the
72
+ * `bytes32[2]` array takes the element index (`0` or `1`) and returns one key.
73
+ */
74
+ export const _deviceWalletToOwner = async (client, deviceWallet, index) => {
75
+ const chainID = await client.getChainId();
76
+ const rpcURL = client.transport.url;
77
+ const values = _getChainSpecificConstants(chainID, rpcURL);
78
+ return client.extend(publicActions).readContract({
79
+ address: values.factoryAddresses.REGISTRY,
80
+ abi: Registry,
81
+ functionName: "deviceWalletToOwner",
82
+ args: [deviceWallet, index]
83
+ });
84
+ };
85
+ /** The device wallet registered for a hash of owner P-256 keys (zero if none). */
86
+ export const _registeredP256Keys = async (client, hashOfOwnerP256Keys) => {
87
+ const chainID = await client.getChainId();
88
+ const rpcURL = client.transport.url;
89
+ const values = _getChainSpecificConstants(chainID, rpcURL);
90
+ return client.extend(publicActions).readContract({
91
+ address: values.factoryAddresses.REGISTRY,
92
+ abi: Registry,
93
+ functionName: "registeredP256Keys",
94
+ args: [hashOfOwnerP256Keys]
95
+ });
96
+ };
97
+ /** Whether a device wallet is registered/valid. */
98
+ export const _isDeviceWalletValid = async (client, deviceWallet) => {
99
+ const chainID = await client.getChainId();
100
+ const rpcURL = client.transport.url;
101
+ const values = _getChainSpecificConstants(chainID, rpcURL);
102
+ return client.extend(publicActions).readContract({
103
+ address: values.factoryAddresses.REGISTRY,
104
+ abi: Registry,
105
+ functionName: "isDeviceWalletValid",
106
+ args: [deviceWallet]
107
+ });
108
+ };
109
+ /**
110
+ * The device wallet that owns an eSIM wallet (zero address if the eSIM is not
111
+ * valid). On-chain this getter is named `isESIMWalletValid` but returns the
112
+ * associated device-wallet address, not a boolean.
113
+ */
114
+ export const _isESIMWalletValid = async (client, eSIMWallet) => {
115
+ const chainID = await client.getChainId();
116
+ const rpcURL = client.transport.url;
117
+ const values = _getChainSpecificConstants(chainID, rpcURL);
118
+ return client.extend(publicActions).readContract({
119
+ address: values.factoryAddresses.REGISTRY,
120
+ abi: Registry,
121
+ functionName: "isESIMWalletValid",
122
+ args: [eSIMWallet]
123
+ });
124
+ };
125
+ /** Whether an eSIM wallet is currently on standby. */
126
+ export const _isESIMWalletOnStandby = async (client, eSIMWallet) => {
127
+ const chainID = await client.getChainId();
128
+ const rpcURL = client.transport.url;
129
+ const values = _getChainSpecificConstants(chainID, rpcURL);
130
+ return client.extend(publicActions).readContract({
131
+ address: values.factoryAddresses.REGISTRY,
132
+ abi: Registry,
133
+ functionName: "isESIMWalletOnStandby",
134
+ args: [eSIMWallet]
135
+ });
136
+ };
@@ -0,0 +1,23 @@
1
+ import { _getChainSpecificConstants } from "../constants.js";
2
+ import { MissingEOAWalletError } from "../errors.js";
3
+ import { Registry } from "../../abis/index.js";
4
+ /**
5
+ * Admin-EOA logic for `Registry`. `addOrUpdateLazyWalletRegistryAddress` is
6
+ * `onlyOwner`, so the `client` must carry the `upgradeManager` EOA.
7
+ */
8
+ /** Wire (or rewire) the LazyWalletRegistry into the Registry. `onlyOwner`. */
9
+ export const _addOrUpdateLazyWalletRegistryAddress = async (client, lazyWalletRegistry) => {
10
+ const chainID = await client.getChainId();
11
+ const rpcURL = client.transport.url;
12
+ const values = _getChainSpecificConstants(chainID, rpcURL);
13
+ if (!client.account)
14
+ throw new MissingEOAWalletError();
15
+ return client.writeContract({
16
+ address: values.factoryAddresses.REGISTRY,
17
+ chain: values.chain,
18
+ account: client.account.address,
19
+ abi: Registry,
20
+ functionName: 'addOrUpdateLazyWalletRegistryAddress',
21
+ args: [lazyWalletRegistry]
22
+ });
23
+ };
@@ -1,3 +1,4 @@
1
+ import { InvalidClientError, UnconfiguredChainError, UnsupportedChainError, } from './errors.js';
1
2
  import { mainnet, sepolia, optimism, optimismSepolia, arbitrum, arbitrumSepolia, base, baseSepolia } from "viem/chains";
2
3
  export const ZERO = BigInt('0');
3
4
  export const SIGNATURE_VALIDITY_SECONDS = 180; // 3 minutes validity
@@ -91,81 +92,40 @@ export const customErrors = {
91
92
  };
92
93
  export const _extractChainID = async (client) => {
93
94
  if (!client) {
94
- throw "Invalid Signer or Provider instance";
95
+ throw new InvalidClientError();
95
96
  }
96
97
  return client.getChainId();
97
98
  };
99
+ // Maps each supported chain id to its factory-address book + viem chain. Chains
100
+ // whose addresses are still '0x' placeholders are intentionally listed so the
101
+ // guard below can reject them with a clear message rather than leaking '0x'
102
+ // into viem calls.
103
+ const CHAIN_CONFIG = {
104
+ [CHAIN_ID.SEPOLIA]: { factoryAddresses: sepoliaFactoryAddresses, chain: sepolia },
105
+ [CHAIN_ID.MAINNET]: { factoryAddresses: mainnetFactoryAddresses, chain: mainnet },
106
+ [CHAIN_ID.OPTIMISM_MAINNET]: { factoryAddresses: optimismMainnetFactoryAddresses, chain: optimism },
107
+ [CHAIN_ID.OPTIMISM_SEPOLIA]: { factoryAddresses: optimismSepoliaFactoryAddresses, chain: optimismSepolia },
108
+ [CHAIN_ID.BASE_MAINNET]: { factoryAddresses: baseMainnetFactoryAddresses, chain: base },
109
+ [CHAIN_ID.BASE_SEPOLIA]: { factoryAddresses: baseSepoliaFactoryAddresses, chain: baseSepolia },
110
+ [CHAIN_ID.ARBITRUM_ONE]: { factoryAddresses: arbitrumOneFactoryAddresses, chain: arbitrum },
111
+ [CHAIN_ID.ARBITRUM_SEPOLIA]: { factoryAddresses: arbitrumSepoliaFactoryAddresses, chain: arbitrumSepolia },
112
+ };
113
+ // A factory address book is only usable if every entry is a real 20-byte
114
+ // address - an unconfigured chain leaves '0x' placeholders behind.
115
+ const _hasUnconfiguredAddresses = (addresses) => Object.values(addresses).some((a) => !a || a === '0x' || a.length !== 42);
98
116
  export const _getChainSpecificConstants = (chainID, rpcURL, pimlicoAPIKey) => {
99
- if (chainID == CHAIN_ID.SEPOLIA) {
100
- return {
101
- factoryAddresses: sepoliaFactoryAddresses,
102
- chain: sepolia,
103
- rpcURL: rpcURL,
104
- pimlicoRpcURL: pimlicoAPIKey ? `https://api.pimlico.io/v2/${chainID}/rpc?apikey=${pimlicoAPIKey}` : "",
105
- customErrors: customErrors
106
- };
107
- }
108
- else if (chainID == CHAIN_ID.MAINNET) {
109
- return {
110
- factoryAddresses: mainnetFactoryAddresses,
111
- chain: mainnet,
112
- rpcURL: rpcURL,
113
- pimlicoRpcURL: pimlicoAPIKey ? `https://api.pimlico.io/v2/${chainID}/rpc?apikey=${pimlicoAPIKey}` : "",
114
- customErrors: customErrors
115
- };
116
- }
117
- else if (chainID == CHAIN_ID.OPTIMISM_MAINNET) {
118
- return {
119
- factoryAddresses: optimismMainnetFactoryAddresses,
120
- chain: optimism,
121
- rpcURL: rpcURL,
122
- pimlicoRpcURL: pimlicoAPIKey ? `https://api.pimlico.io/v2/${chainID}/rpc?apikey=${pimlicoAPIKey}` : "",
123
- customErrors: customErrors
124
- };
125
- }
126
- else if (chainID == CHAIN_ID.OPTIMISM_SEPOLIA) {
127
- return {
128
- factoryAddresses: optimismSepoliaFactoryAddresses,
129
- chain: optimismSepolia,
130
- rpcURL: rpcURL,
131
- pimlicoRpcURL: pimlicoAPIKey ? `https://api.pimlico.io/v2/${chainID}/rpc?apikey=${pimlicoAPIKey}` : "",
132
- customErrors: customErrors
133
- };
134
- }
135
- else if (chainID == CHAIN_ID.BASE_MAINNET) {
136
- return {
137
- factoryAddresses: baseMainnetFactoryAddresses,
138
- chain: base,
139
- rpcURL: rpcURL,
140
- pimlicoRpcURL: pimlicoAPIKey ? `https://api.pimlico.io/v2/${chainID}/rpc?apikey=${pimlicoAPIKey}` : "",
141
- customErrors: customErrors
142
- };
143
- }
144
- else if (chainID == CHAIN_ID.BASE_SEPOLIA) {
145
- return {
146
- factoryAddresses: baseSepoliaFactoryAddresses,
147
- chain: baseSepolia,
148
- rpcURL: rpcURL,
149
- pimlicoRpcURL: pimlicoAPIKey ? `https://api.pimlico.io/v2/${chainID}/rpc?apikey=${pimlicoAPIKey}` : "",
150
- customErrors: customErrors
151
- };
152
- }
153
- else if (chainID == CHAIN_ID.ARBITRUM_ONE) {
154
- return {
155
- factoryAddresses: arbitrumOneFactoryAddresses,
156
- chain: arbitrum,
157
- rpcURL: rpcURL,
158
- pimlicoRpcURL: pimlicoAPIKey ? `https://api.pimlico.io/v2/${chainID}/rpc?apikey=${pimlicoAPIKey}` : "",
159
- customErrors: customErrors
160
- };
117
+ const config = CHAIN_CONFIG[chainID];
118
+ if (!config) {
119
+ throw new UnsupportedChainError(chainID);
161
120
  }
162
- else {
163
- return {
164
- factoryAddresses: arbitrumSepoliaFactoryAddresses,
165
- chain: arbitrumSepolia,
166
- rpcURL: rpcURL,
167
- pimlicoRpcURL: pimlicoAPIKey ? `https://api.pimlico.io/v2/${chainID}/rpc?apikey=${pimlicoAPIKey}` : "",
168
- customErrors: customErrors
169
- };
121
+ if (_hasUnconfiguredAddresses(config.factoryAddresses)) {
122
+ throw new UnconfiguredChainError(chainID);
170
123
  }
124
+ return {
125
+ factoryAddresses: config.factoryAddresses,
126
+ chain: config.chain,
127
+ rpcURL: rpcURL,
128
+ pimlicoRpcURL: pimlicoAPIKey ? `https://api.pimlico.io/v2/${chainID}/rpc?apikey=${pimlicoAPIKey}` : "",
129
+ customErrors: customErrors,
130
+ };
171
131
  };
@@ -1,92 +1,20 @@
1
1
  import { encodeFunctionData, getContract } from "viem";
2
2
  import { DeviceWallet } from "../abis/index.js";
3
- import { customErrors } from "./constants.js";
4
- export const _deployESIMWallet = async (client, address, hasAccessToETH, salt) => {
5
- if (!client.account)
6
- throw new Error(customErrors.MISSING_SMART_WALLET);
7
- // UserOp
8
- return client.sendUserOperation({
9
- account: client.account,
10
- uo: {
11
- target: address,
12
- data: encodeFunctionData({
13
- abi: DeviceWallet,
14
- functionName: "deployESIMWallet",
15
- args: [hasAccessToETH, salt]
16
- })
17
- }
18
- });
19
- };
20
- export const _setESIMUniqueIdentifierForAnESIMWallet = async (client, address, eSIMWalletAddress, eSIMUniqueIdentifier) => {
21
- if (!client.account)
22
- throw new Error(customErrors.MISSING_SMART_WALLET);
23
- // UserOp
24
- return client.sendUserOperation({
25
- account: client.account,
26
- uo: {
27
- target: address,
28
- data: encodeFunctionData({
29
- abi: DeviceWallet,
30
- functionName: "setESIMUniqueIdentifierForAnESIMWallet",
31
- args: [eSIMWalletAddress, eSIMUniqueIdentifier]
32
- })
33
- }
34
- });
35
- // const contract = (await getContractInstance(client)).deviceWallet(address);
36
- // return contract.write.setESIMUniqueIdentifierForAnESIMWallet([eSIMWalletAddress, eSIMUniqueIdentifier]);
37
- };
38
- export const _payETHForDataBundles = async (client, address, amount) => {
39
- if (!client.account)
40
- throw new Error(customErrors.MISSING_SMART_WALLET);
41
- // UserOp
42
- return client.sendUserOperation({
43
- account: client.account,
44
- uo: {
45
- target: address,
46
- data: encodeFunctionData({
47
- abi: DeviceWallet,
48
- functionName: "payETHForDataBundles",
49
- args: [amount]
50
- })
51
- }
52
- });
53
- };
54
- export const _pullETH = async (client, address, amount) => {
55
- if (!client.account)
56
- throw new Error(customErrors.MISSING_SMART_WALLET);
57
- // UserOp
58
- return client.sendUserOperation({
59
- account: client.account,
60
- uo: {
61
- target: address,
62
- data: encodeFunctionData({
63
- abi: DeviceWallet,
64
- functionName: "pullETH",
65
- args: [amount]
66
- })
67
- }
68
- });
69
- };
70
- export const _getVaultAddress = async (client, address) => {
71
- if (!client.account)
72
- throw new Error(customErrors.MISSING_SMART_WALLET);
73
- // UserOp
74
- return client.sendUserOperation({
75
- account: client.account,
76
- uo: {
77
- target: address,
78
- data: encodeFunctionData({
79
- abi: DeviceWallet,
80
- functionName: "getVaultAddress",
81
- args: []
82
- })
83
- }
84
- });
85
- };
3
+ import { MissingSmartWalletError } from "./errors.js";
4
+ // A userOp from a device wallet runs through `execute`, so at the target contract
5
+ // msg.sender is the device-wallet account itself. That constrains which DeviceWallet
6
+ // functions this surface can expose:
7
+ // - deployESIMWallet / setESIMUniqueIdentifierForAnESIMWallet are `onlyESIMWalletAdmin`
8
+ // / `onlyESIMWalletAdminOrRegistry` - only the admin EOA (or registry) may call, so a
9
+ // device-wallet userOp always reverts. They are exposed on `KokioAdmin.deviceWallet`.
10
+ // - payETHForDataBundles / pullETH are `onlyAssociatedESIMWallets` - callable only by an
11
+ // associated eSIM wallet contract, never by the device wallet or an EOA.
12
+ // The functions below are self-callable (target = the device wallet's own address, so
13
+ // msg.sender == self), so they succeed via a userOp.
86
14
  export const _toggleAccessToETH = async (client, address, eSIMWalletAddress, hasAccessToETH) => {
87
15
  if (!client.account)
88
- throw new Error(customErrors.MISSING_SMART_WALLET);
89
- // UserOp
16
+ throw new MissingSmartWalletError();
17
+ // UserOp - `onlySelf`; the device wallet toggles ETH access for an eSIM wallet it owns.
90
18
  return client.sendUserOperation({
91
19
  account: client.account,
92
20
  uo: {
@@ -101,8 +29,8 @@ export const _toggleAccessToETH = async (client, address, eSIMWalletAddress, has
101
29
  };
102
30
  export const _addESIMWallet = async (client, address, eSIMWalletAddress, hasAccessToETH) => {
103
31
  if (!client.account)
104
- throw new Error(customErrors.MISSING_SMART_WALLET);
105
- // UserOp
32
+ throw new MissingSmartWalletError();
33
+ // UserOp - `onlyRegistryOrDeviceWalletFactoryOrOwner`; self is permitted.
106
34
  return client.sendUserOperation({
107
35
  account: client.account,
108
36
  uo: {
@@ -117,8 +45,8 @@ export const _addESIMWallet = async (client, address, eSIMWalletAddress, hasAcce
117
45
  };
118
46
  export const _removeESIMWallet = async (client, address, eSIMWalletAddress, hasAccessToETH) => {
119
47
  if (!client.account)
120
- throw new Error(customErrors.MISSING_SMART_WALLET);
121
- // UserOp
48
+ throw new MissingSmartWalletError();
49
+ // UserOp - `onlySelfOrAssociatedESIMWallet`; self is permitted.
122
50
  return client.sendUserOperation({
123
51
  account: client.account,
124
52
  uo: {
@@ -131,14 +59,23 @@ export const _removeESIMWallet = async (client, address, eSIMWalletAddress, hasA
131
59
  }
132
60
  });
133
61
  };
62
+ // `getVaultAddress` is a `view` - read it directly instead of spending a userOp.
63
+ export const _getVaultAddress = async (client, address) => {
64
+ return client.readContract({
65
+ address,
66
+ abi: DeviceWallet,
67
+ functionName: "getVaultAddress",
68
+ args: []
69
+ });
70
+ };
134
71
  export const _getOwner = async (client, address) => {
135
72
  const contract = getContract({
136
73
  abi: DeviceWallet,
137
74
  address: address,
138
75
  client
139
76
  });
140
- const x = await contract.read.owner([0]);
141
- const y = await contract.read.owner([1]);
77
+ const x = await contract.read.owner([0n]);
78
+ const y = await contract.read.owner([1n]);
142
79
  const owner = [x, y];
143
80
  return owner;
144
81
  };