kokio-sdk 1.1.0 → 2.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +68 -19
- package/dist/esm/abis/BeaconProxy.js +30 -46
- package/dist/esm/abis/DeviceWallet.js +546 -535
- package/dist/esm/abis/DeviceWalletFactory.js +537 -544
- package/dist/esm/abis/ESIMWallet.js +440 -299
- package/dist/esm/abis/ESIMWalletFactory.js +372 -289
- package/dist/esm/abis/LazyWalletRegistry.js +941 -421
- package/dist/esm/abis/P256Verifier.js +29 -29
- package/dist/esm/abis/ProtocolAdmin.js +1228 -0
- package/dist/esm/abis/Registry.js +1207 -466
- package/dist/esm/abis/RegistryHelper.js +414 -20
- package/dist/esm/abis/index.js +2 -1
- package/dist/esm/admin/config-admin.js +7 -0
- package/dist/esm/admin/interface/deviceWalletClass.js +27 -6
- package/dist/esm/admin/interface/deviceWalletFactoryClass.js +41 -19
- package/dist/esm/admin/interface/eSIMWalletClass.js +10 -1
- package/dist/esm/admin/interface/eSIMWalletFactoryClass.js +24 -2
- package/dist/esm/admin/interface/lazyWalletRegistryClass.js +83 -4
- package/dist/esm/admin/interface/protocolAdminClass.js +195 -0
- package/dist/esm/admin/interface/registryClass.js +93 -2
- package/dist/esm/config.js +42 -7
- package/dist/esm/interface/deviceWalletClass.js +45 -5
- package/dist/esm/interface/deviceWalletFactoryClass.js +20 -1
- package/dist/esm/interface/eSIMWalletClass.js +12 -3
- package/dist/esm/interface/registryClass.js +47 -0
- package/dist/esm/interface/smartAccountClass.js +2 -4
- package/dist/esm/logic/account-kit/createSmartAccount.js +156 -102
- package/dist/esm/logic/admin/deviceWallet.eoa.js +26 -15
- package/dist/esm/logic/admin/deviceWalletFactory.eoa.js +69 -48
- package/dist/esm/logic/admin/eSIMWallet.eoa.js +5 -7
- package/dist/esm/logic/admin/eSIMWalletFactory.eoa.js +79 -11
- package/dist/esm/logic/admin/lazyWalletRegistry.eoa.js +333 -22
- package/dist/esm/logic/admin/protocolAdmin.eoa.js +524 -0
- package/dist/esm/logic/admin/reads/deviceWallet.reads.js +82 -7
- package/dist/esm/logic/admin/reads/deviceWalletFactory.reads.js +82 -23
- package/dist/esm/logic/admin/reads/eSIMWallet.reads.js +50 -6
- package/dist/esm/logic/admin/reads/eSIMWalletFactory.reads.js +63 -5
- package/dist/esm/logic/admin/reads/lazyWalletRegistry.reads.js +171 -10
- package/dist/esm/logic/admin/reads/protocolAdmin.reads.js +154 -0
- package/dist/esm/logic/admin/reads/registry.reads.js +289 -9
- package/dist/esm/logic/admin/registry.eoa.js +276 -6
- package/dist/esm/logic/constants.js +53 -26
- package/dist/esm/logic/deviceWallet.js +224 -31
- package/dist/esm/logic/deviceWalletFactory.js +89 -0
- package/dist/esm/logic/eSIMWallet.js +113 -43
- package/dist/esm/logic/eSIMWalletFactory.js +8 -8
- package/dist/esm/logic/errors.js +94 -1
- package/dist/esm/logic/registry.js +236 -0
- package/dist/esm/logic/utils.js +2 -1
- package/dist/types/abis/BeaconProxy.d.ts +21 -33
- package/dist/types/abis/DeviceWallet.d.ts +372 -365
- package/dist/types/abis/DeviceWalletFactory.d.ts +438 -448
- package/dist/types/abis/ESIMWallet.d.ts +352 -245
- package/dist/types/abis/ESIMWalletFactory.d.ts +278 -216
- package/dist/types/abis/LazyWalletRegistry.d.ts +710 -317
- package/dist/types/abis/P256Verifier.d.ts +16 -16
- package/dist/types/abis/ProtocolAdmin.d.ts +947 -0
- package/dist/types/abis/Registry.d.ts +960 -393
- package/dist/types/abis/RegistryHelper.d.ts +317 -16
- package/dist/types/abis/index.d.ts +2 -1
- package/dist/types/admin/config-admin.d.ts +3 -0
- package/dist/types/admin/interface/deviceWalletClass.d.ts +10 -3
- package/dist/types/admin/interface/deviceWalletFactoryClass.d.ts +14 -7
- package/dist/types/admin/interface/eSIMWalletClass.d.ts +3 -0
- package/dist/types/admin/interface/eSIMWalletFactoryClass.d.ts +8 -1
- package/dist/types/admin/interface/lazyWalletRegistryClass.d.ts +38 -2
- package/dist/types/admin/interface/protocolAdminClass.d.ts +95 -0
- package/dist/types/admin/interface/registryClass.d.ts +30 -0
- package/dist/types/config.d.ts +26 -5
- package/dist/types/interface/P256VerifierClass.d.ts +3 -4
- package/dist/types/interface/deviceWalletClass.d.ts +22 -2569
- package/dist/types/interface/deviceWalletFactoryClass.d.ts +10 -2564
- package/dist/types/interface/eSIMWalletClass.d.ts +11 -8
- package/dist/types/interface/eSIMWalletFactoryClass.d.ts +5 -2565
- package/dist/types/interface/registryClass.d.ts +19 -0
- package/dist/types/interface/smartAccountClass.d.ts +6 -2568
- package/dist/types/logic/P256Verifier.d.ts +2 -2
- package/dist/types/logic/account-kit/createSmartAccount.d.ts +43 -19
- package/dist/types/logic/admin/deviceWallet.eoa.d.ts +15 -9
- package/dist/types/logic/admin/deviceWalletFactory.eoa.d.ts +34 -23
- package/dist/types/logic/admin/eSIMWallet.eoa.d.ts +0 -5
- package/dist/types/logic/admin/eSIMWalletFactory.eoa.d.ts +27 -9
- package/dist/types/logic/admin/lazyWalletRegistry.eoa.d.ts +102 -10
- package/dist/types/logic/admin/protocolAdmin.eoa.d.ts +163 -0
- package/dist/types/logic/admin/reads/deviceWallet.reads.d.ts +28 -8
- package/dist/types/logic/admin/reads/deviceWalletFactory.reads.d.ts +45 -14
- package/dist/types/logic/admin/reads/eSIMWallet.reads.d.ts +25 -6
- package/dist/types/logic/admin/reads/eSIMWalletFactory.reads.d.ts +21 -6
- package/dist/types/logic/admin/reads/lazyWalletRegistry.reads.d.ts +44 -11
- package/dist/types/logic/admin/reads/protocolAdmin.reads.d.ts +53 -0
- package/dist/types/logic/admin/reads/registry.reads.d.ts +105 -9
- package/dist/types/logic/admin/registry.eoa.d.ts +102 -5
- package/dist/types/logic/constants.d.ts +2 -0
- package/dist/types/logic/deviceWallet.d.ts +78 -6
- package/dist/types/logic/deviceWalletFactory.d.ts +32 -3
- package/dist/types/logic/eSIMWallet.d.ts +48 -7
- package/dist/types/logic/eSIMWalletFactory.d.ts +3 -3
- package/dist/types/logic/errors.d.ts +61 -1
- package/dist/types/logic/registry.d.ts +78 -0
- package/dist/types/types-export.d.ts +1 -1
- package/dist/types/types.d.ts +111 -1
- package/package.json +11 -13
- package/dist/esm/interface/lazyWalletRegistryClass.js +0 -10
- package/dist/esm/logic/lazyWalletRegistry.js +0 -19
- package/dist/types/interface/lazyWalletRegistryClass.d.ts +0 -6
- package/dist/types/logic/lazyWalletRegistry.d.ts +0 -2
|
@@ -1,15 +1,13 @@
|
|
|
1
1
|
import { publicActions } from "viem";
|
|
2
2
|
import { _getChainSpecificConstants } from "../../constants.js";
|
|
3
3
|
import { DeviceWalletFactory } from "../../../abis/index.js";
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
* `MissingEOAWalletError` guard.
|
|
12
|
-
*/
|
|
4
|
+
// Read-only admin logic for `DeviceWalletFactory` - the contract's public
|
|
5
|
+
// storage getters and `view` functions, surfaced for the backend.
|
|
6
|
+
//
|
|
7
|
+
// A viem `WalletClient` carries no public actions, so each read extends it with
|
|
8
|
+
// `publicActions` (reusing the same transport, so it also works under an anvil
|
|
9
|
+
// fork) before calling `readContract`. Reads need no EOA account, so there is no
|
|
10
|
+
// `MissingEOAWalletError` guard.
|
|
13
11
|
/** The admin EOA (`eSIMWalletAdmin`) currently set on the factory. */
|
|
14
12
|
export const _eSIMWalletAdmin = async (client) => {
|
|
15
13
|
const chainID = await client.getChainId();
|
|
@@ -22,54 +20,87 @@ export const _eSIMWalletAdmin = async (client) => {
|
|
|
22
20
|
args: []
|
|
23
21
|
});
|
|
24
22
|
};
|
|
25
|
-
/**
|
|
26
|
-
export const
|
|
23
|
+
/** Whether a device wallet has been registered with the factory. */
|
|
24
|
+
export const _deviceWalletInfoAdded = async (client, deviceWallet) => {
|
|
27
25
|
const chainID = await client.getChainId();
|
|
28
26
|
const rpcURL = client.transport.url;
|
|
29
27
|
const values = _getChainSpecificConstants(chainID, rpcURL);
|
|
30
28
|
return client.extend(publicActions).readContract({
|
|
31
29
|
address: values.factoryAddresses.DEVICE_WALLET_FACTORY,
|
|
32
30
|
abi: DeviceWalletFactory,
|
|
33
|
-
functionName: "
|
|
34
|
-
args: []
|
|
31
|
+
functionName: "deviceWalletInfoAdded",
|
|
32
|
+
args: [deviceWallet]
|
|
35
33
|
});
|
|
36
34
|
};
|
|
37
|
-
/** The
|
|
38
|
-
export const
|
|
35
|
+
/** The current device-wallet beacon implementation. */
|
|
36
|
+
export const _getCurrentDeviceWalletImplementation = async (client) => {
|
|
39
37
|
const chainID = await client.getChainId();
|
|
40
38
|
const rpcURL = client.transport.url;
|
|
41
39
|
const values = _getChainSpecificConstants(chainID, rpcURL);
|
|
42
40
|
return client.extend(publicActions).readContract({
|
|
43
41
|
address: values.factoryAddresses.DEVICE_WALLET_FACTORY,
|
|
44
42
|
abi: DeviceWalletFactory,
|
|
45
|
-
functionName: "
|
|
43
|
+
functionName: "getCurrentDeviceWalletImplementation",
|
|
46
44
|
args: []
|
|
47
45
|
});
|
|
48
46
|
};
|
|
49
|
-
/**
|
|
50
|
-
|
|
47
|
+
/**
|
|
48
|
+
* Check an identifier and owner key before deploying. Answers the zero address
|
|
49
|
+
* when both are free, or the wallet already holding one of them.
|
|
50
|
+
*
|
|
51
|
+
* `createAccount` runs inside EntryPoint validation, where the 4337 rules bar it
|
|
52
|
+
* from reading the registry, so it cannot see that an identifier or a key is
|
|
53
|
+
* taken: it deploys a second wallet at a fresh address and the
|
|
54
|
+
* `postCreateAccount` that would register it fails afterwards. Checking here
|
|
55
|
+
* first is what stops that.
|
|
56
|
+
*
|
|
57
|
+
* Reverts on an empty identifier or a key that is not a point on the P256 curve.
|
|
58
|
+
*/
|
|
59
|
+
export const _preCreateAccountValidation = async (client, deviceUniqueIdentifier, deviceWalletOwnerKey) => {
|
|
51
60
|
const chainID = await client.getChainId();
|
|
52
61
|
const rpcURL = client.transport.url;
|
|
53
62
|
const values = _getChainSpecificConstants(chainID, rpcURL);
|
|
54
63
|
return client.extend(publicActions).readContract({
|
|
55
64
|
address: values.factoryAddresses.DEVICE_WALLET_FACTORY,
|
|
56
65
|
abi: DeviceWalletFactory,
|
|
57
|
-
functionName: "
|
|
58
|
-
args: [
|
|
66
|
+
functionName: "preCreateAccountValidation",
|
|
67
|
+
args: [deviceUniqueIdentifier, deviceWalletOwnerKey]
|
|
59
68
|
});
|
|
60
69
|
};
|
|
61
|
-
|
|
62
|
-
export const _getCurrentDeviceWalletImplementation = async (client) => {
|
|
70
|
+
const _addressGetter = async (client, functionName) => {
|
|
63
71
|
const chainID = await client.getChainId();
|
|
64
72
|
const rpcURL = client.transport.url;
|
|
65
73
|
const values = _getChainSpecificConstants(chainID, rpcURL);
|
|
66
74
|
return client.extend(publicActions).readContract({
|
|
67
75
|
address: values.factoryAddresses.DEVICE_WALLET_FACTORY,
|
|
68
76
|
abi: DeviceWalletFactory,
|
|
69
|
-
functionName
|
|
77
|
+
functionName,
|
|
70
78
|
args: []
|
|
71
79
|
});
|
|
72
80
|
};
|
|
81
|
+
/**
|
|
82
|
+
* The beacon every device wallet reads its implementation from. One update moves
|
|
83
|
+
* all of them and no wallet can decline it.
|
|
84
|
+
*/
|
|
85
|
+
export const _beacon = (client) => _addressGetter(client, "beacon");
|
|
86
|
+
/** The registry the factory writes new wallets into. */
|
|
87
|
+
export const _registry = (client) => _addressGetter(client, "registry");
|
|
88
|
+
/** The EntryPoint baked into every device wallet this factory deploys. */
|
|
89
|
+
export const _entryPoint = (client) => _addressGetter(client, "entryPoint");
|
|
90
|
+
/** The contract new device wallets verify WebAuthn assertions through. */
|
|
91
|
+
export const _verifier = (client) => _addressGetter(client, "verifier");
|
|
92
|
+
/**
|
|
93
|
+
* Who holds `onlyOwner` on the factory. On the live deployment this is the
|
|
94
|
+
* `ProtocolAdmin` timelock, so an owner call sent from an EOA reverts and has to
|
|
95
|
+
* be scheduled instead.
|
|
96
|
+
*/
|
|
97
|
+
export const _owner = (client) => _addressGetter(client, "owner");
|
|
98
|
+
/**
|
|
99
|
+
* The address a `transferOwnership` is waiting on. Worth reading before
|
|
100
|
+
* `protocolAdmin.acceptOwnershipBatch`, which reverts on any target that has not
|
|
101
|
+
* been offered to the timelock.
|
|
102
|
+
*/
|
|
103
|
+
export const _pendingOwner = (client) => _addressGetter(client, "pendingOwner");
|
|
73
104
|
/**
|
|
74
105
|
* The counterfactual (CREATE2) device-wallet address for an owner key. On-chain
|
|
75
106
|
* arg order is `(ownerKey, uid, salt)` - note this differs from `createAccount`.
|
|
@@ -85,3 +116,31 @@ export const _getCounterFactualAddress = async (client, deviceWalletOwnerKey, de
|
|
|
85
116
|
args: [deviceWalletOwnerKey, deviceUniqueIdentifier, salt]
|
|
86
117
|
});
|
|
87
118
|
};
|
|
119
|
+
/**
|
|
120
|
+
* The ERC-1822 storage slot this proxy keeps its implementation in. An upgrade
|
|
121
|
+
* reverts unless the incoming implementation answers with the same value, which
|
|
122
|
+
* is what stops a non-UUPS address being installed.
|
|
123
|
+
*/
|
|
124
|
+
export const _proxiableUUID = async (client) => {
|
|
125
|
+
const chainID = await client.getChainId();
|
|
126
|
+
const rpcURL = client.transport.url;
|
|
127
|
+
const values = _getChainSpecificConstants(chainID, rpcURL);
|
|
128
|
+
return client.extend(publicActions).readContract({
|
|
129
|
+
address: values.factoryAddresses.DEVICE_WALLET_FACTORY,
|
|
130
|
+
abi: DeviceWalletFactory,
|
|
131
|
+
functionName: "proxiableUUID",
|
|
132
|
+
args: []
|
|
133
|
+
});
|
|
134
|
+
};
|
|
135
|
+
/** The OpenZeppelin upgrade interface this proxy speaks, currently `"5.0.0"`. */
|
|
136
|
+
export const _upgradeInterfaceVersion = async (client) => {
|
|
137
|
+
const chainID = await client.getChainId();
|
|
138
|
+
const rpcURL = client.transport.url;
|
|
139
|
+
const values = _getChainSpecificConstants(chainID, rpcURL);
|
|
140
|
+
return client.extend(publicActions).readContract({
|
|
141
|
+
address: values.factoryAddresses.DEVICE_WALLET_FACTORY,
|
|
142
|
+
abi: DeviceWalletFactory,
|
|
143
|
+
functionName: "UPGRADE_INTERFACE_VERSION",
|
|
144
|
+
args: []
|
|
145
|
+
});
|
|
146
|
+
};
|
|
@@ -1,11 +1,9 @@
|
|
|
1
1
|
import { publicActions } from "viem";
|
|
2
2
|
import { ESIMWallet } from "../../../abis/index.js";
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
* EOA account is required.
|
|
8
|
-
*/
|
|
3
|
+
// Read-only admin logic targeting a specific `ESIMWallet` instance (its address
|
|
4
|
+
// is passed in). Surfaces the instance's public storage getters + `owner` view
|
|
5
|
+
// for the backend. Each read extends the `WalletClient` with `publicActions`; no
|
|
6
|
+
// EOA account is required.
|
|
9
7
|
/** The `ESIMWalletFactory` that deployed this eSIM wallet. */
|
|
10
8
|
export const _eSIMWalletFactory = async (client, eSIMWalletAddress) => {
|
|
11
9
|
return client.extend(publicActions).readContract({
|
|
@@ -24,6 +22,20 @@ export const _eSIMUniqueIdentifier = async (client, eSIMWalletAddress) => {
|
|
|
24
22
|
args: []
|
|
25
23
|
});
|
|
26
24
|
};
|
|
25
|
+
/**
|
|
26
|
+
* This wallet's own price ceiling in wei. Zero means it follows the registry's
|
|
27
|
+
* `defaultDataBundlePriceCap` instead, which is the state a fresh wallet and a
|
|
28
|
+
* newly handed-over wallet both start in. Worth reading before naming a price on
|
|
29
|
+
* `buyDataBundle`, since a price over the ceiling reverts.
|
|
30
|
+
*/
|
|
31
|
+
export const _dataBundlePriceCap = async (client, eSIMWalletAddress) => {
|
|
32
|
+
return client.extend(publicActions).readContract({
|
|
33
|
+
address: eSIMWalletAddress,
|
|
34
|
+
abi: ESIMWallet,
|
|
35
|
+
functionName: "dataBundlePriceCap",
|
|
36
|
+
args: []
|
|
37
|
+
});
|
|
38
|
+
};
|
|
27
39
|
/** The pending owner proposed via `requestTransferOwnership` (zero if none). */
|
|
28
40
|
export const _newRequestedOwner = async (client, eSIMWalletAddress) => {
|
|
29
41
|
return client.extend(publicActions).readContract({
|
|
@@ -42,3 +54,35 @@ export const _owner = async (client, eSIMWalletAddress) => {
|
|
|
42
54
|
args: []
|
|
43
55
|
});
|
|
44
56
|
};
|
|
57
|
+
/**
|
|
58
|
+
* The device wallet this eSIM wallet belongs to. Tracks `owner` today, but it is
|
|
59
|
+
* a separate storage slot with its own typed getter, so read whichever one the
|
|
60
|
+
* calling code actually means.
|
|
61
|
+
*/
|
|
62
|
+
export const _deviceWallet = async (client, eSIMWalletAddress) => {
|
|
63
|
+
return client.extend(publicActions).readContract({
|
|
64
|
+
address: eSIMWalletAddress,
|
|
65
|
+
abi: ESIMWallet,
|
|
66
|
+
functionName: "deviceWallet",
|
|
67
|
+
args: []
|
|
68
|
+
});
|
|
69
|
+
};
|
|
70
|
+
/**
|
|
71
|
+
* One data bundle purchase, by position. The array holds every purchase this
|
|
72
|
+
* wallet has made, and for a wallet that started life on the fiat path it also
|
|
73
|
+
* holds the pre-deployment purchases the lazy registry copies in.
|
|
74
|
+
*
|
|
75
|
+
* The contract publishes no length getter, so there is no way to ask how many
|
|
76
|
+
* entries exist. Read upwards from zero until a call reverts, or track the count
|
|
77
|
+
* from the `DataBundleBought` and `TransactionHistoryPopulated` events, whose
|
|
78
|
+
* `_totalEntries` is the length after the batch landed.
|
|
79
|
+
*/
|
|
80
|
+
export const _transactionHistory = async (client, eSIMWalletAddress, index) => {
|
|
81
|
+
const [dataBundleID, dataBundlePrice] = await client.extend(publicActions).readContract({
|
|
82
|
+
address: eSIMWalletAddress,
|
|
83
|
+
abi: ESIMWallet,
|
|
84
|
+
functionName: "transactionHistory",
|
|
85
|
+
args: [index]
|
|
86
|
+
});
|
|
87
|
+
return { dataBundleID, dataBundlePrice };
|
|
88
|
+
};
|
|
@@ -1,11 +1,9 @@
|
|
|
1
1
|
import { publicActions } from "viem";
|
|
2
2
|
import { _getChainSpecificConstants } from "../../constants.js";
|
|
3
3
|
import { ESIMWalletFactory } from "../../../abis/index.js";
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
* with `publicActions` (no EOA account required).
|
|
8
|
-
*/
|
|
4
|
+
// Read-only admin logic for `ESIMWalletFactory` - its public storage getter and
|
|
5
|
+
// `view` function, surfaced for the backend. Each read extends the `WalletClient`
|
|
6
|
+
// with `publicActions` (no EOA account required).
|
|
9
7
|
/** Whether an eSIM wallet was deployed by this factory. */
|
|
10
8
|
export const _isESIMWalletDeployed = async (client, eSIMWallet) => {
|
|
11
9
|
const chainID = await client.getChainId();
|
|
@@ -30,3 +28,63 @@ export const _getCurrentESIMWalletImplementation = async (client) => {
|
|
|
30
28
|
args: []
|
|
31
29
|
});
|
|
32
30
|
};
|
|
31
|
+
/**
|
|
32
|
+
* The ERC-1822 storage slot this proxy keeps its implementation in. An upgrade
|
|
33
|
+
* reverts unless the incoming implementation answers with the same value, which
|
|
34
|
+
* is what stops a non-UUPS address being installed.
|
|
35
|
+
*/
|
|
36
|
+
export const _proxiableUUID = async (client) => {
|
|
37
|
+
const chainID = await client.getChainId();
|
|
38
|
+
const rpcURL = client.transport.url;
|
|
39
|
+
const values = _getChainSpecificConstants(chainID, rpcURL);
|
|
40
|
+
return client.extend(publicActions).readContract({
|
|
41
|
+
address: values.factoryAddresses.ESIM_WALLET_FACTORY,
|
|
42
|
+
abi: ESIMWalletFactory,
|
|
43
|
+
functionName: "proxiableUUID",
|
|
44
|
+
args: []
|
|
45
|
+
});
|
|
46
|
+
};
|
|
47
|
+
/** The OpenZeppelin upgrade interface this proxy speaks, currently `"5.0.0"`. */
|
|
48
|
+
export const _upgradeInterfaceVersion = async (client) => {
|
|
49
|
+
const chainID = await client.getChainId();
|
|
50
|
+
const rpcURL = client.transport.url;
|
|
51
|
+
const values = _getChainSpecificConstants(chainID, rpcURL);
|
|
52
|
+
return client.extend(publicActions).readContract({
|
|
53
|
+
address: values.factoryAddresses.ESIM_WALLET_FACTORY,
|
|
54
|
+
abi: ESIMWalletFactory,
|
|
55
|
+
functionName: "UPGRADE_INTERFACE_VERSION",
|
|
56
|
+
args: []
|
|
57
|
+
});
|
|
58
|
+
};
|
|
59
|
+
/**
|
|
60
|
+
* Who holds `onlyOwner` here. On the live deployment this is the
|
|
61
|
+
* `ProtocolAdmin` timelock, so an owner call sent from an EOA reverts and has to
|
|
62
|
+
* be scheduled instead.
|
|
63
|
+
*/
|
|
64
|
+
export const _owner = async (client) => {
|
|
65
|
+
const chainID = await client.getChainId();
|
|
66
|
+
const rpcURL = client.transport.url;
|
|
67
|
+
const values = _getChainSpecificConstants(chainID, rpcURL);
|
|
68
|
+
return client.extend(publicActions).readContract({
|
|
69
|
+
address: values.factoryAddresses.ESIM_WALLET_FACTORY,
|
|
70
|
+
abi: ESIMWalletFactory,
|
|
71
|
+
functionName: "owner",
|
|
72
|
+
args: []
|
|
73
|
+
});
|
|
74
|
+
};
|
|
75
|
+
/**
|
|
76
|
+
* The address a `transferOwnership` is waiting on. Worth reading before
|
|
77
|
+
* `protocolAdmin.acceptOwnershipBatch`, which reverts on any target that has not
|
|
78
|
+
* been offered to the timelock.
|
|
79
|
+
*/
|
|
80
|
+
export const _pendingOwner = async (client) => {
|
|
81
|
+
const chainID = await client.getChainId();
|
|
82
|
+
const rpcURL = client.transport.url;
|
|
83
|
+
const values = _getChainSpecificConstants(chainID, rpcURL);
|
|
84
|
+
return client.extend(publicActions).readContract({
|
|
85
|
+
address: values.factoryAddresses.ESIM_WALLET_FACTORY,
|
|
86
|
+
abi: ESIMWalletFactory,
|
|
87
|
+
functionName: "pendingOwner",
|
|
88
|
+
args: []
|
|
89
|
+
});
|
|
90
|
+
};
|
|
@@ -1,16 +1,14 @@
|
|
|
1
1
|
import { publicActions } from "viem";
|
|
2
2
|
import { _getChainSpecificConstants } from "../../constants.js";
|
|
3
3
|
import { LazyWalletRegistry } from "../../../abis/index.js";
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
* callers iterate indices to read the whole list (there is no full-array getter).
|
|
13
|
-
*/
|
|
4
|
+
// Read-only admin logic for `LazyWalletRegistry` - its public storage getters,
|
|
5
|
+
// surfaced for the backend's fiat/lazy provisioning flows. Each read extends the
|
|
6
|
+
// `WalletClient` with `publicActions`; no EOA account is required.
|
|
7
|
+
//
|
|
8
|
+
// Note: `deviceIdentifierToESIMDetails` and
|
|
9
|
+
// `eSIMIdentifiersAssociatedWithDeviceIdentifier` back dynamic arrays on chain,
|
|
10
|
+
// so their auto-generated getters take an element `index` and return one entry -
|
|
11
|
+
// callers iterate indices to read the whole list (there is no full-array getter).
|
|
14
12
|
/** The upgrade-manager (owner) EOA of the lazy registry. */
|
|
15
13
|
export const _upgradeManager = async (client) => {
|
|
16
14
|
const chainID = await client.getChainId();
|
|
@@ -48,6 +46,109 @@ export const _deviceIdentifierToESIMDetails = async (client, deviceIdentifier, e
|
|
|
48
46
|
});
|
|
49
47
|
return { dataBundleID, dataBundlePrice };
|
|
50
48
|
};
|
|
49
|
+
/** Most eSIM wallets one `deployLazyWalletAndSetESIMIdentifier` call will deploy. */
|
|
50
|
+
export const _maxESIMWalletsPerCall = async (client) => {
|
|
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.LAZY_WALLET_REGISTRY,
|
|
56
|
+
abi: LazyWalletRegistry,
|
|
57
|
+
functionName: "MAX_ESIM_WALLETS_PER_CALL",
|
|
58
|
+
args: []
|
|
59
|
+
});
|
|
60
|
+
};
|
|
61
|
+
/** Most history entries one `setHistoryForLazyWallet` call will copy. */
|
|
62
|
+
export const _maxHistoryEntriesPerCall = 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.LAZY_WALLET_REGISTRY,
|
|
68
|
+
abi: LazyWalletRegistry,
|
|
69
|
+
functionName: "MAX_HISTORY_ENTRIES_PER_CALL",
|
|
70
|
+
args: []
|
|
71
|
+
});
|
|
72
|
+
};
|
|
73
|
+
/**
|
|
74
|
+
* How many of a device's eSIM wallets are already deployed. Non-zero exactly when
|
|
75
|
+
* the lazy route ran the device's first batch, so it doubles as the marker for
|
|
76
|
+
* the route itself.
|
|
77
|
+
*/
|
|
78
|
+
export const _eSIMWalletsDeployed = async (client, deviceIdentifier) => {
|
|
79
|
+
const chainID = await client.getChainId();
|
|
80
|
+
const rpcURL = client.transport.url;
|
|
81
|
+
const values = _getChainSpecificConstants(chainID, rpcURL);
|
|
82
|
+
return client.extend(publicActions).readContract({
|
|
83
|
+
address: values.factoryAddresses.LAZY_WALLET_REGISTRY,
|
|
84
|
+
abi: LazyWalletRegistry,
|
|
85
|
+
functionName: "eSIMWalletsDeployed",
|
|
86
|
+
args: [deviceIdentifier]
|
|
87
|
+
});
|
|
88
|
+
};
|
|
89
|
+
/** Salt the device's first deployment batch started from. Every later batch derives from it. */
|
|
90
|
+
export const _lazyDeploymentSalt = async (client, deviceIdentifier) => {
|
|
91
|
+
const chainID = await client.getChainId();
|
|
92
|
+
const rpcURL = client.transport.url;
|
|
93
|
+
const values = _getChainSpecificConstants(chainID, rpcURL);
|
|
94
|
+
return client.extend(publicActions).readContract({
|
|
95
|
+
address: values.factoryAddresses.LAZY_WALLET_REGISTRY,
|
|
96
|
+
abi: LazyWalletRegistry,
|
|
97
|
+
functionName: "lazyDeploymentSalt",
|
|
98
|
+
args: [deviceIdentifier]
|
|
99
|
+
});
|
|
100
|
+
};
|
|
101
|
+
/**
|
|
102
|
+
* The eSIM wallet this registry deployed for an identifier. Zero for anything it
|
|
103
|
+
* did not deploy, which is what authorises the history copy.
|
|
104
|
+
*/
|
|
105
|
+
export const _lazyDeployedESIMWallet = async (client, eSIMIdentifier) => {
|
|
106
|
+
const chainID = await client.getChainId();
|
|
107
|
+
const rpcURL = client.transport.url;
|
|
108
|
+
const values = _getChainSpecificConstants(chainID, rpcURL);
|
|
109
|
+
return client.extend(publicActions).readContract({
|
|
110
|
+
address: values.factoryAddresses.LAZY_WALLET_REGISTRY,
|
|
111
|
+
abi: LazyWalletRegistry,
|
|
112
|
+
functionName: "lazyDeployedESIMWallet",
|
|
113
|
+
args: [eSIMIdentifier]
|
|
114
|
+
});
|
|
115
|
+
};
|
|
116
|
+
/** How many of an eSIM's stored purchase entries have already reached its wallet. */
|
|
117
|
+
export const _historyEntriesCopied = async (client, eSIMIdentifier) => {
|
|
118
|
+
const chainID = await client.getChainId();
|
|
119
|
+
const rpcURL = client.transport.url;
|
|
120
|
+
const values = _getChainSpecificConstants(chainID, rpcURL);
|
|
121
|
+
return client.extend(publicActions).readContract({
|
|
122
|
+
address: values.factoryAddresses.LAZY_WALLET_REGISTRY,
|
|
123
|
+
abi: LazyWalletRegistry,
|
|
124
|
+
functionName: "historyEntriesCopied",
|
|
125
|
+
args: [eSIMIdentifier]
|
|
126
|
+
});
|
|
127
|
+
};
|
|
128
|
+
/** Whether a device identifier has purchases recorded against it here. */
|
|
129
|
+
export const _isDeviceIdentifierReserved = async (client, deviceIdentifier) => {
|
|
130
|
+
const chainID = await client.getChainId();
|
|
131
|
+
const rpcURL = client.transport.url;
|
|
132
|
+
const values = _getChainSpecificConstants(chainID, rpcURL);
|
|
133
|
+
return client.extend(publicActions).readContract({
|
|
134
|
+
address: values.factoryAddresses.LAZY_WALLET_REGISTRY,
|
|
135
|
+
abi: LazyWalletRegistry,
|
|
136
|
+
functionName: "isDeviceIdentifierReserved",
|
|
137
|
+
args: [deviceIdentifier]
|
|
138
|
+
});
|
|
139
|
+
};
|
|
140
|
+
/** Whether an eSIM identifier is bound to a device here. */
|
|
141
|
+
export const _isESIMIdentifierReserved = async (client, eSIMIdentifier) => {
|
|
142
|
+
const chainID = await client.getChainId();
|
|
143
|
+
const rpcURL = client.transport.url;
|
|
144
|
+
const values = _getChainSpecificConstants(chainID, rpcURL);
|
|
145
|
+
return client.extend(publicActions).readContract({
|
|
146
|
+
address: values.factoryAddresses.LAZY_WALLET_REGISTRY,
|
|
147
|
+
abi: LazyWalletRegistry,
|
|
148
|
+
functionName: "isESIMIdentifierReserved",
|
|
149
|
+
args: [eSIMIdentifier]
|
|
150
|
+
});
|
|
151
|
+
};
|
|
51
152
|
/** One eSIM identifier associated with a device identifier, by array index. */
|
|
52
153
|
export const _eSIMIdentifiersAssociatedWithDeviceIdentifier = async (client, deviceIdentifier, index) => {
|
|
53
154
|
const chainID = await client.getChainId();
|
|
@@ -60,3 +161,63 @@ export const _eSIMIdentifiersAssociatedWithDeviceIdentifier = async (client, dev
|
|
|
60
161
|
args: [deviceIdentifier, index]
|
|
61
162
|
});
|
|
62
163
|
};
|
|
164
|
+
/**
|
|
165
|
+
* The ERC-1822 storage slot this proxy keeps its implementation in. An upgrade
|
|
166
|
+
* reverts unless the incoming implementation answers with the same value, which
|
|
167
|
+
* is what stops a non-UUPS address being installed.
|
|
168
|
+
*/
|
|
169
|
+
export const _proxiableUUID = async (client) => {
|
|
170
|
+
const chainID = await client.getChainId();
|
|
171
|
+
const rpcURL = client.transport.url;
|
|
172
|
+
const values = _getChainSpecificConstants(chainID, rpcURL);
|
|
173
|
+
return client.extend(publicActions).readContract({
|
|
174
|
+
address: values.factoryAddresses.LAZY_WALLET_REGISTRY,
|
|
175
|
+
abi: LazyWalletRegistry,
|
|
176
|
+
functionName: "proxiableUUID",
|
|
177
|
+
args: []
|
|
178
|
+
});
|
|
179
|
+
};
|
|
180
|
+
/** The OpenZeppelin upgrade interface this proxy speaks, currently `"5.0.0"`. */
|
|
181
|
+
export const _upgradeInterfaceVersion = async (client) => {
|
|
182
|
+
const chainID = await client.getChainId();
|
|
183
|
+
const rpcURL = client.transport.url;
|
|
184
|
+
const values = _getChainSpecificConstants(chainID, rpcURL);
|
|
185
|
+
return client.extend(publicActions).readContract({
|
|
186
|
+
address: values.factoryAddresses.LAZY_WALLET_REGISTRY,
|
|
187
|
+
abi: LazyWalletRegistry,
|
|
188
|
+
functionName: "UPGRADE_INTERFACE_VERSION",
|
|
189
|
+
args: []
|
|
190
|
+
});
|
|
191
|
+
};
|
|
192
|
+
/**
|
|
193
|
+
* Who holds `onlyOwner` here. On the live deployment this is the
|
|
194
|
+
* `ProtocolAdmin` timelock, so an owner call sent from an EOA reverts and has to
|
|
195
|
+
* be scheduled instead.
|
|
196
|
+
*/
|
|
197
|
+
export const _owner = async (client) => {
|
|
198
|
+
const chainID = await client.getChainId();
|
|
199
|
+
const rpcURL = client.transport.url;
|
|
200
|
+
const values = _getChainSpecificConstants(chainID, rpcURL);
|
|
201
|
+
return client.extend(publicActions).readContract({
|
|
202
|
+
address: values.factoryAddresses.LAZY_WALLET_REGISTRY,
|
|
203
|
+
abi: LazyWalletRegistry,
|
|
204
|
+
functionName: "owner",
|
|
205
|
+
args: []
|
|
206
|
+
});
|
|
207
|
+
};
|
|
208
|
+
/**
|
|
209
|
+
* The address a `transferOwnership` is waiting on. Worth reading before
|
|
210
|
+
* `protocolAdmin.acceptOwnershipBatch`, which reverts on any target that has not
|
|
211
|
+
* been offered to the timelock.
|
|
212
|
+
*/
|
|
213
|
+
export const _pendingOwner = async (client) => {
|
|
214
|
+
const chainID = await client.getChainId();
|
|
215
|
+
const rpcURL = client.transport.url;
|
|
216
|
+
const values = _getChainSpecificConstants(chainID, rpcURL);
|
|
217
|
+
return client.extend(publicActions).readContract({
|
|
218
|
+
address: values.factoryAddresses.LAZY_WALLET_REGISTRY,
|
|
219
|
+
abi: LazyWalletRegistry,
|
|
220
|
+
functionName: "pendingOwner",
|
|
221
|
+
args: []
|
|
222
|
+
});
|
|
223
|
+
};
|
|
@@ -0,0 +1,154 @@
|
|
|
1
|
+
import { publicActions } from "viem";
|
|
2
|
+
import { _getChainSpecificConstants } from "../../constants.js";
|
|
3
|
+
import { ProtocolAdmin } from "../../../abis/index.js";
|
|
4
|
+
// Read-only logic for `ProtocolAdmin`, the timelock that owns the four
|
|
5
|
+
// upgradeable contracts. Every read extends the `WalletClient` with
|
|
6
|
+
// `publicActions`; no EOA account is required.
|
|
7
|
+
/** Operation lifecycle, matching the on-chain `OperationState` enum. */
|
|
8
|
+
export var OperationState;
|
|
9
|
+
(function (OperationState) {
|
|
10
|
+
OperationState[OperationState["Unset"] = 0] = "Unset";
|
|
11
|
+
OperationState[OperationState["Waiting"] = 1] = "Waiting";
|
|
12
|
+
OperationState[OperationState["Ready"] = 2] = "Ready";
|
|
13
|
+
OperationState[OperationState["Done"] = 3] = "Done";
|
|
14
|
+
})(OperationState || (OperationState = {}));
|
|
15
|
+
const _resolve = async (client) => {
|
|
16
|
+
const chainID = await client.getChainId();
|
|
17
|
+
const rpcURL = client.transport.url;
|
|
18
|
+
return _getChainSpecificConstants(chainID, rpcURL);
|
|
19
|
+
};
|
|
20
|
+
/**
|
|
21
|
+
* Shortest delay a new operation will be given. Read this rather than following
|
|
22
|
+
* `MinDelayChange`, which carries the value `updateDelay` stored and not the
|
|
23
|
+
* floor that overrides it.
|
|
24
|
+
*/
|
|
25
|
+
export const _getMinDelay = async (client) => {
|
|
26
|
+
const values = await _resolve(client);
|
|
27
|
+
return client.extend(publicActions).readContract({
|
|
28
|
+
address: values.factoryAddresses.PROTOCOL_ADMIN,
|
|
29
|
+
abi: ProtocolAdmin,
|
|
30
|
+
functionName: "getMinDelay",
|
|
31
|
+
args: []
|
|
32
|
+
});
|
|
33
|
+
};
|
|
34
|
+
/**
|
|
35
|
+
* The floor `getMinDelay` clamps to. Immutable, so `updateDelay` can never bring
|
|
36
|
+
* the timelock below it.
|
|
37
|
+
*/
|
|
38
|
+
export const _minDelayFloor = async (client) => {
|
|
39
|
+
const values = await _resolve(client);
|
|
40
|
+
return client.extend(publicActions).readContract({
|
|
41
|
+
address: values.factoryAddresses.PROTOCOL_ADMIN,
|
|
42
|
+
abi: ProtocolAdmin,
|
|
43
|
+
functionName: "minDelayFloor",
|
|
44
|
+
args: []
|
|
45
|
+
});
|
|
46
|
+
};
|
|
47
|
+
/** Where an operation is in its lifecycle. */
|
|
48
|
+
export const _getOperationState = async (client, id) => {
|
|
49
|
+
const values = await _resolve(client);
|
|
50
|
+
return client.extend(publicActions).readContract({
|
|
51
|
+
address: values.factoryAddresses.PROTOCOL_ADMIN,
|
|
52
|
+
abi: ProtocolAdmin,
|
|
53
|
+
functionName: "getOperationState",
|
|
54
|
+
args: [id]
|
|
55
|
+
});
|
|
56
|
+
};
|
|
57
|
+
/**
|
|
58
|
+
* When an operation becomes executable, as a unix timestamp. Reads `0` for an
|
|
59
|
+
* unknown operation and the literal `1` for one already done, so compare against
|
|
60
|
+
* the state rather than treating this as a time in both cases.
|
|
61
|
+
*/
|
|
62
|
+
export const _getTimestamp = async (client, id) => {
|
|
63
|
+
const values = await _resolve(client);
|
|
64
|
+
return client.extend(publicActions).readContract({
|
|
65
|
+
address: values.factoryAddresses.PROTOCOL_ADMIN,
|
|
66
|
+
abi: ProtocolAdmin,
|
|
67
|
+
functionName: "getTimestamp",
|
|
68
|
+
args: [id]
|
|
69
|
+
});
|
|
70
|
+
};
|
|
71
|
+
/** Whether the timelock has ever seen this operation. */
|
|
72
|
+
export const _isOperation = async (client, id) => {
|
|
73
|
+
const values = await _resolve(client);
|
|
74
|
+
return client.extend(publicActions).readContract({
|
|
75
|
+
address: values.factoryAddresses.PROTOCOL_ADMIN,
|
|
76
|
+
abi: ProtocolAdmin,
|
|
77
|
+
functionName: "isOperation",
|
|
78
|
+
args: [id]
|
|
79
|
+
});
|
|
80
|
+
};
|
|
81
|
+
/** Scheduled and not yet executed, whether or not the delay has elapsed. */
|
|
82
|
+
export const _isOperationPending = async (client, id) => {
|
|
83
|
+
const values = await _resolve(client);
|
|
84
|
+
return client.extend(publicActions).readContract({
|
|
85
|
+
address: values.factoryAddresses.PROTOCOL_ADMIN,
|
|
86
|
+
abi: ProtocolAdmin,
|
|
87
|
+
functionName: "isOperationPending",
|
|
88
|
+
args: [id]
|
|
89
|
+
});
|
|
90
|
+
};
|
|
91
|
+
/** The delay has elapsed and the operation can be executed now. */
|
|
92
|
+
export const _isOperationReady = async (client, id) => {
|
|
93
|
+
const values = await _resolve(client);
|
|
94
|
+
return client.extend(publicActions).readContract({
|
|
95
|
+
address: values.factoryAddresses.PROTOCOL_ADMIN,
|
|
96
|
+
abi: ProtocolAdmin,
|
|
97
|
+
functionName: "isOperationReady",
|
|
98
|
+
args: [id]
|
|
99
|
+
});
|
|
100
|
+
};
|
|
101
|
+
/** The operation has already run. */
|
|
102
|
+
export const _isOperationDone = async (client, id) => {
|
|
103
|
+
const values = await _resolve(client);
|
|
104
|
+
return client.extend(publicActions).readContract({
|
|
105
|
+
address: values.factoryAddresses.PROTOCOL_ADMIN,
|
|
106
|
+
abi: ProtocolAdmin,
|
|
107
|
+
functionName: "isOperationDone",
|
|
108
|
+
args: [id]
|
|
109
|
+
});
|
|
110
|
+
};
|
|
111
|
+
/** Whether an account holds a role. Role ids come from the constants below. */
|
|
112
|
+
export const _hasRole = async (client, role, account) => {
|
|
113
|
+
const values = await _resolve(client);
|
|
114
|
+
return client.extend(publicActions).readContract({
|
|
115
|
+
address: values.factoryAddresses.PROTOCOL_ADMIN,
|
|
116
|
+
abi: ProtocolAdmin,
|
|
117
|
+
functionName: "hasRole",
|
|
118
|
+
args: [role, account]
|
|
119
|
+
});
|
|
120
|
+
};
|
|
121
|
+
/**
|
|
122
|
+
* The role that can grant and revoke the given one. Always `DEFAULT_ADMIN_ROLE`,
|
|
123
|
+
* which only the timelock itself holds, so every role change is a scheduled
|
|
124
|
+
* operation.
|
|
125
|
+
*/
|
|
126
|
+
export const _getRoleAdmin = async (client, role) => {
|
|
127
|
+
const values = await _resolve(client);
|
|
128
|
+
return client.extend(publicActions).readContract({
|
|
129
|
+
address: values.factoryAddresses.PROTOCOL_ADMIN,
|
|
130
|
+
abi: ProtocolAdmin,
|
|
131
|
+
functionName: "getRoleAdmin",
|
|
132
|
+
args: [role]
|
|
133
|
+
});
|
|
134
|
+
};
|
|
135
|
+
// Reads one of the five role id constants off the contract.
|
|
136
|
+
const _roleConstant = async (client, functionName) => {
|
|
137
|
+
const values = await _resolve(client);
|
|
138
|
+
return client.extend(publicActions).readContract({
|
|
139
|
+
address: values.factoryAddresses.PROTOCOL_ADMIN,
|
|
140
|
+
abi: ProtocolAdmin,
|
|
141
|
+
functionName,
|
|
142
|
+
args: []
|
|
143
|
+
});
|
|
144
|
+
};
|
|
145
|
+
/** Held only by the timelock itself, which is what makes role changes wait. */
|
|
146
|
+
export const _defaultAdminRole = (client) => _roleConstant(client, "DEFAULT_ADMIN_ROLE");
|
|
147
|
+
/** Can schedule operations, and can cancel them. */
|
|
148
|
+
export const _proposerRole = (client) => _roleConstant(client, "PROPOSER_ROLE");
|
|
149
|
+
/** Can cancel a scheduled operation and nothing else. */
|
|
150
|
+
export const _cancellerRole = (client) => _roleConstant(client, "CANCELLER_ROLE");
|
|
151
|
+
/** Granted to the zero address, so execution is open to anyone. */
|
|
152
|
+
export const _executorRole = (client) => _roleConstant(client, "EXECUTOR_ROLE");
|
|
153
|
+
/** The three instant powers. Cannot be held alongside proposer or canceller. */
|
|
154
|
+
export const _guardianRole = (client) => _roleConstant(client, "GUARDIAN_ROLE");
|