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.
- package/README.md +185 -1
- package/dist/esm/admin/config-admin.js +85 -0
- package/dist/esm/admin/interface/deviceWalletClass.js +34 -0
- package/dist/esm/admin/interface/deviceWalletFactoryClass.js +57 -0
- package/dist/esm/admin/interface/eSIMWalletClass.js +31 -0
- package/dist/esm/admin/interface/eSIMWalletFactoryClass.js +22 -0
- package/dist/esm/admin/interface/lazyWalletRegistryClass.js +33 -0
- package/dist/esm/admin/interface/registryClass.js +43 -0
- package/dist/esm/config.js +18 -2
- package/dist/esm/interface/constantsClass.js +33 -10
- package/dist/esm/interface/deviceWalletClass.js +1 -13
- package/dist/esm/interface/eSIMWalletClass.js +2 -8
- package/dist/esm/interface/eSIMWalletFactoryClass.js +2 -8
- package/dist/esm/interface/lazyWalletRegistryClass.js +2 -11
- package/dist/esm/logic/P256Verifier.js +8 -15
- package/dist/esm/logic/account-kit/createSmartAccount.js +78 -27
- package/dist/esm/logic/admin/deviceWallet.eoa.js +42 -0
- package/dist/esm/logic/admin/deviceWalletFactory.eoa.js +133 -0
- package/dist/esm/logic/admin/eSIMWallet.eoa.js +30 -0
- package/dist/esm/logic/admin/eSIMWalletFactory.eoa.js +43 -0
- package/dist/esm/logic/admin/lazyWalletRegistry.eoa.js +62 -0
- package/dist/esm/logic/admin/reads/deviceWallet.reads.js +45 -0
- package/dist/esm/logic/admin/reads/deviceWalletFactory.reads.js +87 -0
- package/dist/esm/logic/admin/reads/eSIMWallet.reads.js +44 -0
- package/dist/esm/logic/admin/reads/eSIMWalletFactory.reads.js +32 -0
- package/dist/esm/logic/admin/reads/lazyWalletRegistry.reads.js +62 -0
- package/dist/esm/logic/admin/reads/registry.reads.js +136 -0
- package/dist/esm/logic/admin/registry.eoa.js +23 -0
- package/dist/esm/logic/constants.js +31 -71
- package/dist/esm/logic/deviceWallet.js +28 -91
- package/dist/esm/logic/deviceWalletFactory.js +21 -30
- package/dist/esm/logic/eSIMWallet.js +25 -57
- package/dist/esm/logic/eSIMWalletFactory.js +17 -50
- package/dist/esm/logic/errors.js +118 -0
- package/dist/esm/logic/lazyWalletRegistry.js +12 -72
- package/dist/esm/logic/utils.js +3 -3
- package/dist/types/abis/BeaconProxy.d.ts +58 -2
- package/dist/types/abis/DeviceWallet.d.ts +702 -2
- package/dist/types/abis/DeviceWalletFactory.d.ts +634 -2
- package/dist/types/abis/ESIMWallet.d.ts +375 -2
- package/dist/types/abis/ESIMWalletFactory.d.ts +355 -2
- package/dist/types/abis/LazyWalletRegistry.d.ts +565 -2
- package/dist/types/abis/P256Verifier.d.ts +56 -2
- package/dist/types/abis/Registry.d.ts +623 -2
- package/dist/types/abis/RegistryHelper.d.ts +295 -2
- package/dist/types/admin/config-admin.d.ts +55 -0
- package/dist/types/admin/interface/deviceWalletClass.d.ts +17 -0
- package/dist/types/admin/interface/deviceWalletFactoryClass.d.ts +25 -0
- package/dist/types/admin/interface/eSIMWalletClass.d.ts +17 -0
- package/dist/types/admin/interface/eSIMWalletFactoryClass.d.ts +10 -0
- package/dist/types/admin/interface/lazyWalletRegistryClass.d.ts +14 -0
- package/dist/types/admin/interface/registryClass.d.ts +17 -0
- package/dist/types/config.d.ts +14 -2
- package/dist/types/interface/P256VerifierClass.d.ts +2 -1
- package/dist/types/interface/constantsClass.d.ts +23 -3
- package/dist/types/interface/deviceWalletClass.d.ts +24 -28
- package/dist/types/interface/deviceWalletFactoryClass.d.ts +27 -26
- package/dist/types/interface/eSIMWalletClass.d.ts +2 -4
- package/dist/types/interface/eSIMWalletFactoryClass.d.ts +24 -26
- package/dist/types/interface/lazyWalletRegistryClass.d.ts +1 -6
- package/dist/types/interface/smartAccountClass.d.ts +23 -23
- package/dist/types/logic/P256Verifier.d.ts +2 -1
- package/dist/types/logic/account-kit/createSmartAccount.d.ts +38 -1
- package/dist/types/logic/admin/deviceWallet.eoa.d.ts +12 -0
- package/dist/types/logic/admin/deviceWalletFactory.eoa.d.ts +33 -0
- package/dist/types/logic/admin/eSIMWallet.eoa.d.ts +14 -0
- package/dist/types/logic/admin/eSIMWalletFactory.eoa.d.ts +13 -0
- package/dist/types/logic/admin/lazyWalletRegistry.eoa.d.ts +18 -0
- package/dist/types/logic/admin/reads/deviceWallet.reads.d.ts +16 -0
- package/dist/types/logic/admin/reads/deviceWalletFactory.reads.d.ts +26 -0
- package/dist/types/logic/admin/reads/eSIMWallet.reads.d.ts +15 -0
- package/dist/types/logic/admin/reads/eSIMWalletFactory.reads.d.ts +10 -0
- package/dist/types/logic/admin/reads/lazyWalletRegistry.reads.d.ts +20 -0
- package/dist/types/logic/admin/reads/registry.reads.d.ts +34 -0
- package/dist/types/logic/admin/registry.eoa.d.ts +7 -0
- package/dist/types/logic/deviceWallet.d.ts +1 -5
- package/dist/types/logic/deviceWalletFactory.d.ts +5 -4
- package/dist/types/logic/eSIMWallet.d.ts +1 -3
- package/dist/types/logic/eSIMWalletFactory.d.ts +2 -4
- package/dist/types/logic/errors.d.ts +63 -0
- package/dist/types/logic/lazyWalletRegistry.d.ts +1 -6
- package/dist/types/logic/utils.d.ts +8 -1
- package/dist/types/types.d.ts +1 -1
- package/package.json +17 -4
- package/dist/esm/interface/utilsClass.js +0 -13
- 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
|
|
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
|
-
|
|
100
|
-
|
|
101
|
-
|
|
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
|
-
|
|
163
|
-
|
|
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 {
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
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
|
|
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
|
|
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
|
|
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([
|
|
141
|
-
const y = await contract.read.owner([
|
|
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
|
};
|