kokio-sdk 1.1.0 → 2.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 +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 +23 -12
- package/dist/esm/logic/admin/deviceWalletFactory.eoa.js +63 -42
- package/dist/esm/logic/admin/eSIMWallet.eoa.js +3 -5
- package/dist/esm/logic/admin/eSIMWalletFactory.eoa.js +76 -8
- package/dist/esm/logic/admin/lazyWalletRegistry.eoa.js +330 -19
- 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 +274 -4
- 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 +64 -0
- 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 +45 -0
- 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,18 @@
|
|
|
1
1
|
import { _getChainSpecificConstants } from "../constants.js";
|
|
2
2
|
import { MissingEOAWalletError } from "../errors.js";
|
|
3
3
|
import { DeviceWalletFactory } from "../../abis/index.js";
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
4
|
+
// Admin-EOA logic for `DeviceWalletFactory`.
|
|
5
|
+
//
|
|
6
|
+
// Every function here is `onlyAdmin` / `onlyAdminOrRegistry` / `onlyOwner` on
|
|
7
|
+
// chain, i.e. the caller must be the `eSIMWalletAdmin` (or `upgradeManager`)
|
|
8
|
+
// EOA - never a device-wallet userOp. They therefore live on the EOA surface
|
|
9
|
+
// (`KokioAdmin`) and use `writeContract`, mirroring `_createAccountWithEOA`
|
|
10
|
+
// (which is reused as-is from `../deviceWalletFactory.js`).
|
|
11
|
+
//
|
|
12
|
+
// On the live deployment the owner is the `ProtocolAdmin` timelock, not an EOA,
|
|
13
|
+
// so an `onlyOwner` call sent directly reverts. Route those through
|
|
14
|
+
// `protocolAdmin.proposer.schedule` instead. The direct path stays for
|
|
15
|
+
// deployments whose owner is a plain EOA or multisig.
|
|
13
16
|
/**
|
|
14
17
|
* Batch-deploy device wallets for lazy/fiat users. `onlyAdminOrRegistry`,
|
|
15
18
|
* `payable`: `value` is the total ETH pot from which each `depositAmounts[i]`
|
|
@@ -31,8 +34,12 @@ export const _deployDeviceWalletForUsers = async (client, deviceUniqueIdentifier
|
|
|
31
34
|
value
|
|
32
35
|
});
|
|
33
36
|
};
|
|
34
|
-
/**
|
|
35
|
-
|
|
37
|
+
/**
|
|
38
|
+
* Register a freshly created device wallet with the factory. `onlyAdminOrRegistry`.
|
|
39
|
+
* The salt has to be the one the deploying `createAccount` used, since the
|
|
40
|
+
* factory rederives the counterfactual address from it to check the wallet.
|
|
41
|
+
*/
|
|
42
|
+
export const _postCreateAccount = async (client, deviceWallet, deviceUniqueIdentifier, deviceWalletOwnerKey, salt) => {
|
|
36
43
|
const chainID = await client.getChainId();
|
|
37
44
|
const rpcURL = client.transport.url;
|
|
38
45
|
const values = _getChainSpecificConstants(chainID, rpcURL);
|
|
@@ -44,7 +51,7 @@ export const _postCreateAccount = async (client, deviceWallet, deviceUniqueIdent
|
|
|
44
51
|
account: client.account.address,
|
|
45
52
|
abi: DeviceWalletFactory,
|
|
46
53
|
functionName: 'postCreateAccount',
|
|
47
|
-
args: [deviceWallet, deviceUniqueIdentifier, deviceWalletOwnerKey]
|
|
54
|
+
args: [deviceWallet, deviceUniqueIdentifier, deviceWalletOwnerKey, salt]
|
|
48
55
|
});
|
|
49
56
|
};
|
|
50
57
|
/** One-time wiring of the registry into the factory. `onlyAdmin`. */
|
|
@@ -63,8 +70,8 @@ export const _addRegistryAddress = async (client, registryContractAddress) => {
|
|
|
63
70
|
args: [registryContractAddress]
|
|
64
71
|
});
|
|
65
72
|
};
|
|
66
|
-
/**
|
|
67
|
-
export const
|
|
73
|
+
/** Point the device-wallet beacon at a new implementation. `onlyOwner` (upgradeManager). */
|
|
74
|
+
export const _updateDeviceWalletImplementation = async (client, newDeviceImpl) => {
|
|
68
75
|
const chainID = await client.getChainId();
|
|
69
76
|
const rpcURL = client.transport.url;
|
|
70
77
|
const values = _getChainSpecificConstants(chainID, rpcURL);
|
|
@@ -75,48 +82,62 @@ export const _updateVaultAddress = async (client, newVaultAddress) => {
|
|
|
75
82
|
chain: values.chain,
|
|
76
83
|
account: client.account.address,
|
|
77
84
|
abi: DeviceWalletFactory,
|
|
78
|
-
functionName: '
|
|
79
|
-
args: [
|
|
85
|
+
functionName: 'updateDeviceWalletImplementation',
|
|
86
|
+
args: [newDeviceImpl]
|
|
80
87
|
});
|
|
81
88
|
};
|
|
82
|
-
|
|
83
|
-
|
|
89
|
+
// ---------------------------------------------------------------------------
|
|
90
|
+
// Owner payloads - only reachable through schedule
|
|
91
|
+
// ---------------------------------------------------------------------------
|
|
92
|
+
// Both are `onlyOwner`, and on the live deployment the owner is the timelock, so
|
|
93
|
+
// they exist as something to schedule rather than to send. Each returns the
|
|
94
|
+
// `OwnerCall` to hand to `protocolAdmin.schedule`.
|
|
95
|
+
/**
|
|
96
|
+
* Offer ownership to a new address. Pass the result to `schedule`.
|
|
97
|
+
*
|
|
98
|
+
* Ownable2Step, so the offer changes nothing until the named address calls
|
|
99
|
+
* `acceptOwnership`. Note this hands over the beacon too, since the factory owns
|
|
100
|
+
* it, so the new owner can move every deployed device wallet at once.
|
|
101
|
+
*/
|
|
102
|
+
export const _transferOwnershipCall = async (client, newOwner) => {
|
|
84
103
|
const chainID = await client.getChainId();
|
|
85
104
|
const rpcURL = client.transport.url;
|
|
86
105
|
const values = _getChainSpecificConstants(chainID, rpcURL);
|
|
87
|
-
|
|
88
|
-
throw new MissingEOAWalletError();
|
|
89
|
-
return client.writeContract({
|
|
106
|
+
return {
|
|
90
107
|
address: values.factoryAddresses.DEVICE_WALLET_FACTORY,
|
|
91
|
-
chain: values.chain,
|
|
92
|
-
account: client.account.address,
|
|
93
108
|
abi: DeviceWalletFactory,
|
|
94
|
-
functionName: '
|
|
95
|
-
args: [
|
|
96
|
-
}
|
|
109
|
+
functionName: 'transferOwnership',
|
|
110
|
+
args: [newOwner],
|
|
111
|
+
};
|
|
97
112
|
};
|
|
98
113
|
/**
|
|
99
|
-
*
|
|
100
|
-
*
|
|
101
|
-
*
|
|
114
|
+
* Point the factory's own proxy at a new implementation. Builds
|
|
115
|
+
* `upgradeToAndCall`. Pass the result to `schedule`.
|
|
116
|
+
*
|
|
117
|
+
* This does not touch deployed device wallets. They read their implementation
|
|
118
|
+
* from the beacon, which moves through `updateDeviceWalletImplementation`
|
|
119
|
+
* instead. Changing what the factory deploys next is a beacon update, not this.
|
|
102
120
|
*/
|
|
103
|
-
export const
|
|
121
|
+
export const _upgradeCall = async (client, newImplementation, data = '0x') => {
|
|
104
122
|
const chainID = await client.getChainId();
|
|
105
123
|
const rpcURL = client.transport.url;
|
|
106
124
|
const values = _getChainSpecificConstants(chainID, rpcURL);
|
|
107
|
-
|
|
108
|
-
throw new MissingEOAWalletError();
|
|
109
|
-
return client.writeContract({
|
|
125
|
+
return {
|
|
110
126
|
address: values.factoryAddresses.DEVICE_WALLET_FACTORY,
|
|
111
|
-
chain: values.chain,
|
|
112
|
-
account: client.account.address,
|
|
113
127
|
abi: DeviceWalletFactory,
|
|
114
|
-
functionName: '
|
|
115
|
-
args: []
|
|
116
|
-
}
|
|
128
|
+
functionName: 'upgradeToAndCall',
|
|
129
|
+
args: [newImplementation, data],
|
|
130
|
+
};
|
|
117
131
|
};
|
|
118
|
-
/**
|
|
119
|
-
|
|
132
|
+
/**
|
|
133
|
+
* Take ownership after a `transferOwnership` named this client. `msg.sender`
|
|
134
|
+
* must equal `pendingOwner`, so the `client` is the incoming owner.
|
|
135
|
+
*
|
|
136
|
+
* Where the incoming owner is the timelock, use
|
|
137
|
+
* `protocolAdmin.acceptOwnershipBatch` instead, which accepts for every contract
|
|
138
|
+
* at once.
|
|
139
|
+
*/
|
|
140
|
+
export const _acceptOwnership = async (client) => {
|
|
120
141
|
const chainID = await client.getChainId();
|
|
121
142
|
const rpcURL = client.transport.url;
|
|
122
143
|
const values = _getChainSpecificConstants(chainID, rpcURL);
|
|
@@ -127,7 +148,7 @@ export const _updateDeviceWalletImplementation = async (client, newDeviceImpl) =
|
|
|
127
148
|
chain: values.chain,
|
|
128
149
|
account: client.account.address,
|
|
129
150
|
abi: DeviceWalletFactory,
|
|
130
|
-
functionName: '
|
|
131
|
-
args: [
|
|
151
|
+
functionName: 'acceptOwnership',
|
|
152
|
+
args: []
|
|
132
153
|
});
|
|
133
154
|
};
|
|
@@ -1,11 +1,9 @@
|
|
|
1
1
|
import { _getChainSpecificConstants } from "../constants.js";
|
|
2
2
|
import { MissingEOAWalletError } from "../errors.js";
|
|
3
3
|
import { ESIMWallet } from "../../abis/index.js";
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
* call it directly.
|
|
8
|
-
*/
|
|
4
|
+
// Admin-EOA logic targeting a specific `ESIMWallet` instance (address passed in).
|
|
5
|
+
// `buyDataBundle` is `onlyDeviceWalletOrESIMWalletAdmin`, so the admin EOA can
|
|
6
|
+
// call it directly.
|
|
9
7
|
/**
|
|
10
8
|
* Buy a data bundle for an eSIM wallet. `onlyDeviceWalletOrESIMWalletAdmin`,
|
|
11
9
|
* `payable`. `value` is optional: the contract pulls any shortfall from the
|
|
@@ -1,14 +1,17 @@
|
|
|
1
1
|
import { _getChainSpecificConstants } from "../constants.js";
|
|
2
2
|
import { MissingEOAWalletError } from "../errors.js";
|
|
3
3
|
import { ESIMWalletFactory } from "../../abis/index.js";
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
4
|
+
// Admin-EOA logic for `ESIMWalletFactory`. Both functions are owner-gated
|
|
5
|
+
// (`addRegistryAddress` requires `msg.sender == owner()`, `updateESIMWalletImplementation`
|
|
6
|
+
// is `onlyOwner`), so the `client` must carry the `upgradeManager` EOA.
|
|
7
|
+
//
|
|
8
|
+
// On the live deployment the owner is the `ProtocolAdmin` timelock, not an EOA,
|
|
9
|
+
// so either call sent directly reverts. Route them through
|
|
10
|
+
// `protocolAdmin.proposer.schedule` instead. The direct path stays for
|
|
11
|
+
// deployments whose owner is a plain EOA or multisig.
|
|
12
|
+
//
|
|
13
|
+
// Note: `ESIMWalletFactory.deployESIMWallet` is intentionally NOT exposed - it is
|
|
14
|
+
// `onlyRegistryOrDeviceWalletFactoryOrDeviceWallet`, so a bare EOA always reverts.
|
|
12
15
|
/** One-time wiring of the registry into the eSIM factory. Owner only. */
|
|
13
16
|
export const _addRegistryAddress = async (client, registryContractAddress) => {
|
|
14
17
|
const chainID = await client.getChainId();
|
|
@@ -41,3 +44,68 @@ export const _updateESIMWalletImplementation = async (client, eSIMWalletImpl) =>
|
|
|
41
44
|
args: [eSIMWalletImpl]
|
|
42
45
|
});
|
|
43
46
|
};
|
|
47
|
+
// ---------------------------------------------------------------------------
|
|
48
|
+
// Owner payloads - only reachable through schedule
|
|
49
|
+
// ---------------------------------------------------------------------------
|
|
50
|
+
// Both are `onlyOwner`, and on the live deployment the owner is the timelock, so
|
|
51
|
+
// they exist as something to schedule rather than to send. Each returns the
|
|
52
|
+
// `OwnerCall` to hand to `protocolAdmin.schedule`.
|
|
53
|
+
/**
|
|
54
|
+
* Offer ownership to a new address. Pass the result to `schedule`.
|
|
55
|
+
*
|
|
56
|
+
* Ownable2Step, so the offer changes nothing until the named address calls
|
|
57
|
+
* `acceptOwnership`. Note this hands over the beacon too, since the factory owns
|
|
58
|
+
* it, so the new owner can move every deployed eSIM wallet at once.
|
|
59
|
+
*/
|
|
60
|
+
export const _transferOwnershipCall = async (client, newOwner) => {
|
|
61
|
+
const chainID = await client.getChainId();
|
|
62
|
+
const rpcURL = client.transport.url;
|
|
63
|
+
const values = _getChainSpecificConstants(chainID, rpcURL);
|
|
64
|
+
return {
|
|
65
|
+
address: values.factoryAddresses.ESIM_WALLET_FACTORY,
|
|
66
|
+
abi: ESIMWalletFactory,
|
|
67
|
+
functionName: 'transferOwnership',
|
|
68
|
+
args: [newOwner],
|
|
69
|
+
};
|
|
70
|
+
};
|
|
71
|
+
/**
|
|
72
|
+
* Point the factory's own proxy at a new implementation. Builds
|
|
73
|
+
* `upgradeToAndCall`. Pass the result to `schedule`.
|
|
74
|
+
*
|
|
75
|
+
* This does not touch deployed eSIM wallets. They read their implementation from
|
|
76
|
+
* the beacon, which moves through `updateESIMWalletImplementation` instead.
|
|
77
|
+
*/
|
|
78
|
+
export const _upgradeCall = async (client, newImplementation, data = '0x') => {
|
|
79
|
+
const chainID = await client.getChainId();
|
|
80
|
+
const rpcURL = client.transport.url;
|
|
81
|
+
const values = _getChainSpecificConstants(chainID, rpcURL);
|
|
82
|
+
return {
|
|
83
|
+
address: values.factoryAddresses.ESIM_WALLET_FACTORY,
|
|
84
|
+
abi: ESIMWalletFactory,
|
|
85
|
+
functionName: 'upgradeToAndCall',
|
|
86
|
+
args: [newImplementation, data],
|
|
87
|
+
};
|
|
88
|
+
};
|
|
89
|
+
/**
|
|
90
|
+
* Take ownership after a `transferOwnership` named this client. `msg.sender`
|
|
91
|
+
* must equal `pendingOwner`, so the `client` is the incoming owner.
|
|
92
|
+
*
|
|
93
|
+
* Where the incoming owner is the timelock, use
|
|
94
|
+
* `protocolAdmin.acceptOwnershipBatch` instead, which accepts for every contract
|
|
95
|
+
* at once.
|
|
96
|
+
*/
|
|
97
|
+
export const _acceptOwnership = async (client) => {
|
|
98
|
+
const chainID = await client.getChainId();
|
|
99
|
+
const rpcURL = client.transport.url;
|
|
100
|
+
const values = _getChainSpecificConstants(chainID, rpcURL);
|
|
101
|
+
if (!client.account)
|
|
102
|
+
throw new MissingEOAWalletError();
|
|
103
|
+
return client.writeContract({
|
|
104
|
+
address: values.factoryAddresses.ESIM_WALLET_FACTORY,
|
|
105
|
+
chain: values.chain,
|
|
106
|
+
account: client.account.address,
|
|
107
|
+
abi: ESIMWalletFactory,
|
|
108
|
+
functionName: 'acceptOwnership',
|
|
109
|
+
args: []
|
|
110
|
+
});
|
|
111
|
+
};
|
|
@@ -1,17 +1,48 @@
|
|
|
1
|
+
import { BaseError, ContractFunctionRevertedError, isAddressEqual, parseEventLogs, publicActions, } from "viem";
|
|
1
2
|
import { _getChainSpecificConstants } from "../constants.js";
|
|
2
|
-
import { MissingEOAWalletError } from "../errors.js";
|
|
3
|
-
import { LazyWalletRegistry } from "../../abis/index.js";
|
|
3
|
+
import { BatchSizeOutOfRangeError, DepositOnResumeError, ESIMWalletNotLazyDeployedError, MissingBatchEventError, MissingEOAWalletError, StalledBatchError, } from "../errors.js";
|
|
4
|
+
import { LazyWalletRegistry, Registry } from "../../abis/index.js";
|
|
5
|
+
import { _eSIMWalletsDeployed, _lazyDeployedESIMWallet } from "./reads/lazyWalletRegistry.reads.js";
|
|
6
|
+
// Admin-EOA logic for `LazyWalletRegistry`. Every function here is
|
|
7
|
+
// `onlyESIMWalletAdmin` on chain, so they can only succeed from the admin EOA -
|
|
8
|
+
// a device-wallet userOp (whose sender is the smart account) always reverts.
|
|
9
|
+
// This is why they belong on the EOA surface rather than the mobile userOp one.
|
|
10
|
+
//
|
|
11
|
+
// Deployment and the history copy are both paginated on chain. The thin wrappers
|
|
12
|
+
// send one batch each; the two `AllBatches` functions below run a device or an
|
|
13
|
+
// eSIM to completion and are what the backend should normally call.
|
|
14
|
+
const ZERO_ADDRESS = "0x0000000000000000000000000000000000000000";
|
|
4
15
|
/**
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
*
|
|
16
|
+
* The contract's own caps, mirrored here because they are `constant` on chain and
|
|
17
|
+
* reading them would cost a round trip on every call. The fork tier checks these
|
|
18
|
+
* against the live deployment, so an upgrade that moved one would fail there
|
|
19
|
+
* rather than turning every call into a reverted transaction.
|
|
9
20
|
*/
|
|
10
|
-
|
|
11
|
-
export const
|
|
21
|
+
export const MAX_ESIM_WALLETS_PER_CALL = 20n;
|
|
22
|
+
export const MAX_HISTORY_ENTRIES_PER_CALL = 50n;
|
|
23
|
+
/**
|
|
24
|
+
* Default batch sizes, both below the caps above.
|
|
25
|
+
*
|
|
26
|
+
* A continuation call costs about 28,000 gas before it deploys anything, against
|
|
27
|
+
* roughly 556,000 per eSIM wallet, so a smaller batch buys headroom for almost
|
|
28
|
+
* nothing: running a 45 eSIM device at 10 rather than 20 costs about 0.4% more
|
|
29
|
+
* gas in total. That headroom matters because a full batch of 20 measures between
|
|
30
|
+
* 9.3M and 11.8M gas depending on identifier length and storage warmth, which is
|
|
31
|
+
* uncomfortably close to a per-transaction gas ceiling.
|
|
32
|
+
*/
|
|
33
|
+
export const DEFAULT_ESIM_WALLETS_PER_CALL = 10n;
|
|
34
|
+
export const DEFAULT_HISTORY_ENTRIES_PER_CALL = 25n;
|
|
35
|
+
const _resolve = async (client) => {
|
|
12
36
|
const chainID = await client.getChainId();
|
|
13
37
|
const rpcURL = client.transport.url;
|
|
14
|
-
|
|
38
|
+
return _getChainSpecificConstants(chainID, rpcURL);
|
|
39
|
+
};
|
|
40
|
+
// ---------------------------------------------------------------------------
|
|
41
|
+
// One transaction each, mirroring the contract
|
|
42
|
+
// ---------------------------------------------------------------------------
|
|
43
|
+
/** Record fiat/lazy purchase history for a batch of devices. `onlyESIMWalletAdmin`. */
|
|
44
|
+
export const _batchPopulateHistory = async (client, deviceUniqueIdentifiers, eSIMUniqueIdentifiers, dataBundleDetails) => {
|
|
45
|
+
const values = await _resolve(client);
|
|
15
46
|
if (!client.account)
|
|
16
47
|
throw new MissingEOAWalletError();
|
|
17
48
|
return client.writeContract({
|
|
@@ -24,14 +55,16 @@ export const _batchPopulateHistory = async (client, deviceUniqueIdentifiers, eSI
|
|
|
24
55
|
});
|
|
25
56
|
};
|
|
26
57
|
/**
|
|
27
|
-
* Materialise a lazily-provisioned device wallet and its eSIMs
|
|
28
|
-
* `onlyESIMWalletAdmin`, `payable`: the contract requires
|
|
29
|
-
* so `value` is set to `depositAmount` here.
|
|
58
|
+
* Materialise a lazily-provisioned device wallet and the first batch of its eSIMs
|
|
59
|
+
* on chain. `onlyESIMWalletAdmin`, `payable`: the contract requires
|
|
60
|
+
* `depositAmount == msg.value`, so `value` is set to `depositAmount` here.
|
|
61
|
+
*
|
|
62
|
+
* One transaction. `maxWallets` caps how many eSIM wallets it deploys, and the
|
|
63
|
+
* contract refuses anything above `MAX_ESIM_WALLETS_PER_CALL` rather than
|
|
64
|
+
* clamping it. Prefer `_deployLazyWalletAllBatches`, which finishes the device.
|
|
30
65
|
*/
|
|
31
|
-
export const _deployLazyWalletAndSetESIMIdentifier = async (client, deviceOwnerPublicKey, deviceUniqueIdentifier, salt, depositAmount) => {
|
|
32
|
-
const
|
|
33
|
-
const rpcURL = client.transport.url;
|
|
34
|
-
const values = _getChainSpecificConstants(chainID, rpcURL);
|
|
66
|
+
export const _deployLazyWalletAndSetESIMIdentifier = async (client, deviceOwnerPublicKey, deviceUniqueIdentifier, salt, depositAmount, maxWallets) => {
|
|
67
|
+
const values = await _resolve(client);
|
|
35
68
|
if (!client.account)
|
|
36
69
|
throw new MissingEOAWalletError();
|
|
37
70
|
return client.writeContract({
|
|
@@ -40,12 +73,290 @@ export const _deployLazyWalletAndSetESIMIdentifier = async (client, deviceOwnerP
|
|
|
40
73
|
account: client.account.address,
|
|
41
74
|
abi: LazyWalletRegistry,
|
|
42
75
|
functionName: 'deployLazyWalletAndSetESIMIdentifier',
|
|
43
|
-
args: [deviceOwnerPublicKey, deviceUniqueIdentifier, salt, depositAmount],
|
|
76
|
+
args: [deviceOwnerPublicKey, deviceUniqueIdentifier, salt, depositAmount, maxWallets],
|
|
44
77
|
value: depositAmount
|
|
45
78
|
});
|
|
46
79
|
};
|
|
80
|
+
/**
|
|
81
|
+
* Deploy the next batch of eSIM wallets for a device the lazy route already
|
|
82
|
+
* started. `onlyESIMWalletAdmin`.
|
|
83
|
+
*
|
|
84
|
+
* One transaction. The contract reads its position from a cursor, so a dropped
|
|
85
|
+
* transaction is retried by repeating the identical call. It reverts
|
|
86
|
+
* `AllESIMWalletsDeployed` once nothing is left, which is the terminal condition
|
|
87
|
+
* rather than a failure.
|
|
88
|
+
*/
|
|
89
|
+
export const _deployMoreESIMWalletsForLazyDevice = async (client, deviceUniqueIdentifier, maxWallets) => {
|
|
90
|
+
const values = await _resolve(client);
|
|
91
|
+
if (!client.account)
|
|
92
|
+
throw new MissingEOAWalletError();
|
|
93
|
+
return client.writeContract({
|
|
94
|
+
address: values.factoryAddresses.LAZY_WALLET_REGISTRY,
|
|
95
|
+
chain: values.chain,
|
|
96
|
+
account: client.account.address,
|
|
97
|
+
abi: LazyWalletRegistry,
|
|
98
|
+
functionName: 'deployMoreESIMWalletsForLazyDevice',
|
|
99
|
+
args: [deviceUniqueIdentifier, maxWallets]
|
|
100
|
+
});
|
|
101
|
+
};
|
|
102
|
+
/**
|
|
103
|
+
* Copy the next batch of an eSIM's stored purchase history onto its deployed
|
|
104
|
+
* wallet. `onlyESIMWalletAdmin`.
|
|
105
|
+
*
|
|
106
|
+
* One transaction, with its own cursor per eSIM. Reverts `HistoryAlreadyCopied`
|
|
107
|
+
* once nothing is left. Prefer `_setHistoryForLazyWalletAllBatches`.
|
|
108
|
+
*/
|
|
109
|
+
export const _setHistoryForLazyWallet = async (client, eSIMIdentifier, maxEntries) => {
|
|
110
|
+
const values = await _resolve(client);
|
|
111
|
+
if (!client.account)
|
|
112
|
+
throw new MissingEOAWalletError();
|
|
113
|
+
return client.writeContract({
|
|
114
|
+
address: values.factoryAddresses.LAZY_WALLET_REGISTRY,
|
|
115
|
+
chain: values.chain,
|
|
116
|
+
account: client.account.address,
|
|
117
|
+
abi: LazyWalletRegistry,
|
|
118
|
+
functionName: 'setHistoryForLazyWallet',
|
|
119
|
+
args: [eSIMIdentifier, maxEntries]
|
|
120
|
+
});
|
|
121
|
+
};
|
|
47
122
|
/** Re-point an eSIM identifier from an old device to a new one. `onlyESIMWalletAdmin`. */
|
|
48
123
|
export const _switchESIMIdentifierToNewDeviceIdentifier = async (client, eSIMIdentifier, oldDeviceIdentifier, newDeviceIdentifier) => {
|
|
124
|
+
const values = await _resolve(client);
|
|
125
|
+
if (!client.account)
|
|
126
|
+
throw new MissingEOAWalletError();
|
|
127
|
+
return client.writeContract({
|
|
128
|
+
address: values.factoryAddresses.LAZY_WALLET_REGISTRY,
|
|
129
|
+
chain: values.chain,
|
|
130
|
+
account: client.account.address,
|
|
131
|
+
abi: LazyWalletRegistry,
|
|
132
|
+
functionName: 'switchESIMIdentifierToNewDeviceIdentifier',
|
|
133
|
+
args: [eSIMIdentifier, oldDeviceIdentifier, newDeviceIdentifier]
|
|
134
|
+
});
|
|
135
|
+
};
|
|
136
|
+
// ---------------------------------------------------------------------------
|
|
137
|
+
// Reading a batch back
|
|
138
|
+
// ---------------------------------------------------------------------------
|
|
139
|
+
// `writeContract` returns a hash, not the function's return values, so how much
|
|
140
|
+
// is left comes from the event each batch emits rather than from the call.
|
|
141
|
+
const _batchEvent = async (client, lazyRegistryAddress, hash, eventName) => {
|
|
142
|
+
const receipt = await client.waitForTransactionReceipt({ hash });
|
|
143
|
+
const logs = parseEventLogs({
|
|
144
|
+
abi: LazyWalletRegistry,
|
|
145
|
+
eventName,
|
|
146
|
+
logs: receipt.logs.filter((log) => isAddressEqual(log.address, lazyRegistryAddress)),
|
|
147
|
+
});
|
|
148
|
+
if (logs.length === 0)
|
|
149
|
+
throw new MissingBatchEventError(eventName, hash);
|
|
150
|
+
return logs[0].args;
|
|
151
|
+
};
|
|
152
|
+
/**
|
|
153
|
+
* Whether a call hit its terminal condition. Both paginated calls revert when
|
|
154
|
+
* there is nothing left rather than returning quietly, so a simulation is the
|
|
155
|
+
* only way to tell "already finished" from "more to do" without paying for a
|
|
156
|
+
* transaction that fails.
|
|
157
|
+
*/
|
|
158
|
+
const _isFinished = async (client, request, terminalError) => {
|
|
159
|
+
try {
|
|
160
|
+
await client.simulateContract(request);
|
|
161
|
+
return false;
|
|
162
|
+
}
|
|
163
|
+
catch (err) {
|
|
164
|
+
if (err instanceof BaseError) {
|
|
165
|
+
const revert = err.walk((e) => e instanceof ContractFunctionRevertedError);
|
|
166
|
+
if (revert instanceof ContractFunctionRevertedError && revert.data?.errorName === terminalError) {
|
|
167
|
+
return true;
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
throw err;
|
|
171
|
+
}
|
|
172
|
+
};
|
|
173
|
+
// ---------------------------------------------------------------------------
|
|
174
|
+
// Run a device or an eSIM to completion
|
|
175
|
+
// ---------------------------------------------------------------------------
|
|
176
|
+
/**
|
|
177
|
+
* Deploy a lazy device and every one of its eSIM wallets, over as many
|
|
178
|
+
* transactions as that takes. `onlyESIMWalletAdmin`.
|
|
179
|
+
*
|
|
180
|
+
* Resumable. A device that is part-deployed, because a batch was dropped or an
|
|
181
|
+
* earlier call threw, is continued from its cursor instead of being restarted,
|
|
182
|
+
* so retrying is just calling this again with the same arguments. Pass a deposit
|
|
183
|
+
* of 0 on a retry: only the first batch is payable and it already took one.
|
|
184
|
+
*
|
|
185
|
+
* All of a device's purchase history has to be recorded before this runs. The
|
|
186
|
+
* first batch creates the device wallet, and `batchPopulateHistory` refuses any
|
|
187
|
+
* device that has one.
|
|
188
|
+
*
|
|
189
|
+
* @param maxWallets eSIM wallets per transaction, 1 to `MAX_ESIM_WALLETS_PER_CALL`.
|
|
190
|
+
*/
|
|
191
|
+
export const _deployLazyWalletAllBatches = async (client, deviceOwnerPublicKey, deviceUniqueIdentifier, salt, depositAmount, maxWallets = DEFAULT_ESIM_WALLETS_PER_CALL) => {
|
|
192
|
+
const values = await _resolve(client);
|
|
193
|
+
if (!client.account)
|
|
194
|
+
throw new MissingEOAWalletError();
|
|
195
|
+
const publicClient = client.extend(publicActions);
|
|
196
|
+
const lazyRegistryAddress = values.factoryAddresses.LAZY_WALLET_REGISTRY;
|
|
197
|
+
if (maxWallets < 1n || maxWallets > MAX_ESIM_WALLETS_PER_CALL) {
|
|
198
|
+
throw new BatchSizeOutOfRangeError("maxWallets", maxWallets, MAX_ESIM_WALLETS_PER_CALL);
|
|
199
|
+
}
|
|
200
|
+
const alreadyDeployed = await _eSIMWalletsDeployed(client, deviceUniqueIdentifier);
|
|
201
|
+
const batches = [];
|
|
202
|
+
let deviceWallet;
|
|
203
|
+
let outstanding;
|
|
204
|
+
if (alreadyDeployed === 0n) {
|
|
205
|
+
const hash = await _deployLazyWalletAndSetESIMIdentifier(client, deviceOwnerPublicKey, deviceUniqueIdentifier, salt, depositAmount, maxWallets);
|
|
206
|
+
const first = await _batchEvent(publicClient, lazyRegistryAddress, hash, "LazyESIMWalletsDeployed");
|
|
207
|
+
deviceWallet = first._deviceWallet;
|
|
208
|
+
outstanding = first._remaining > 0n;
|
|
209
|
+
batches.push({
|
|
210
|
+
hash,
|
|
211
|
+
eSIMWallets: first._eSIMWallets,
|
|
212
|
+
eSIMIdentifiers: first._eSIMUniqueIdentifiers,
|
|
213
|
+
remaining: first._remaining,
|
|
214
|
+
});
|
|
215
|
+
}
|
|
216
|
+
else {
|
|
217
|
+
if (depositAmount !== 0n)
|
|
218
|
+
throw new DepositOnResumeError(deviceUniqueIdentifier, depositAmount);
|
|
219
|
+
deviceWallet = await publicClient.readContract({
|
|
220
|
+
address: values.factoryAddresses.REGISTRY,
|
|
221
|
+
abi: Registry,
|
|
222
|
+
functionName: "uniqueIdentifierToDeviceWallet",
|
|
223
|
+
args: [deviceUniqueIdentifier]
|
|
224
|
+
});
|
|
225
|
+
const finished = await _isFinished(publicClient, {
|
|
226
|
+
address: lazyRegistryAddress,
|
|
227
|
+
abi: LazyWalletRegistry,
|
|
228
|
+
functionName: "deployMoreESIMWalletsForLazyDevice",
|
|
229
|
+
args: [deviceUniqueIdentifier, maxWallets],
|
|
230
|
+
account: client.account.address,
|
|
231
|
+
}, "AllESIMWalletsDeployed");
|
|
232
|
+
if (finished) {
|
|
233
|
+
return { deviceWallet, eSIMWallets: [], eSIMIdentifiers: [], batches: [], alreadyComplete: true };
|
|
234
|
+
}
|
|
235
|
+
outstanding = true;
|
|
236
|
+
}
|
|
237
|
+
while (outstanding) {
|
|
238
|
+
const hash = await _deployMoreESIMWalletsForLazyDevice(client, deviceUniqueIdentifier, maxWallets);
|
|
239
|
+
const next = await _batchEvent(publicClient, lazyRegistryAddress, hash, "LazyESIMWalletsDeployed");
|
|
240
|
+
if (next._eSIMWallets.length === 0)
|
|
241
|
+
throw new StalledBatchError(hash, next._remaining);
|
|
242
|
+
batches.push({
|
|
243
|
+
hash,
|
|
244
|
+
eSIMWallets: next._eSIMWallets,
|
|
245
|
+
eSIMIdentifiers: next._eSIMUniqueIdentifiers,
|
|
246
|
+
remaining: next._remaining,
|
|
247
|
+
});
|
|
248
|
+
outstanding = next._remaining > 0n;
|
|
249
|
+
}
|
|
250
|
+
return {
|
|
251
|
+
deviceWallet,
|
|
252
|
+
eSIMWallets: batches.flatMap((batch) => [...batch.eSIMWallets]),
|
|
253
|
+
eSIMIdentifiers: batches.flatMap((batch) => [...batch.eSIMIdentifiers]),
|
|
254
|
+
batches,
|
|
255
|
+
alreadyComplete: false,
|
|
256
|
+
};
|
|
257
|
+
};
|
|
258
|
+
/**
|
|
259
|
+
* Copy an eSIM's whole stored purchase history onto its wallet, over as many
|
|
260
|
+
* transactions as that takes. `onlyESIMWalletAdmin`.
|
|
261
|
+
*
|
|
262
|
+
* Resumable for the same reason as the deployment: the cursor lives on chain, so
|
|
263
|
+
* a partly copied eSIM is continued rather than restarted.
|
|
264
|
+
*
|
|
265
|
+
* The history cursor is per eSIM and the deploy cursor is per device, so this can
|
|
266
|
+
* run against an eSIM whose wallet has landed while its siblings are still
|
|
267
|
+
* undeployed.
|
|
268
|
+
*
|
|
269
|
+
* @param maxEntries entries per transaction, 1 to `MAX_HISTORY_ENTRIES_PER_CALL`.
|
|
270
|
+
*/
|
|
271
|
+
export const _setHistoryForLazyWalletAllBatches = async (client, eSIMIdentifier, maxEntries = DEFAULT_HISTORY_ENTRIES_PER_CALL) => {
|
|
272
|
+
const values = await _resolve(client);
|
|
273
|
+
if (!client.account)
|
|
274
|
+
throw new MissingEOAWalletError();
|
|
275
|
+
const publicClient = client.extend(publicActions);
|
|
276
|
+
const lazyRegistryAddress = values.factoryAddresses.LAZY_WALLET_REGISTRY;
|
|
277
|
+
if (maxEntries < 1n || maxEntries > MAX_HISTORY_ENTRIES_PER_CALL) {
|
|
278
|
+
throw new BatchSizeOutOfRangeError("maxEntries", maxEntries, MAX_HISTORY_ENTRIES_PER_CALL);
|
|
279
|
+
}
|
|
280
|
+
// The same lookup the contract authorises on. Checking it here turns a
|
|
281
|
+
// reverted transaction into a typed error.
|
|
282
|
+
const eSIMWallet = await _lazyDeployedESIMWallet(client, eSIMIdentifier);
|
|
283
|
+
if (eSIMWallet === ZERO_ADDRESS)
|
|
284
|
+
throw new ESIMWalletNotLazyDeployedError(eSIMIdentifier);
|
|
285
|
+
const finished = await _isFinished(publicClient, {
|
|
286
|
+
address: lazyRegistryAddress,
|
|
287
|
+
abi: LazyWalletRegistry,
|
|
288
|
+
functionName: "setHistoryForLazyWallet",
|
|
289
|
+
args: [eSIMIdentifier, maxEntries],
|
|
290
|
+
account: client.account.address,
|
|
291
|
+
}, "HistoryAlreadyCopied");
|
|
292
|
+
if (finished)
|
|
293
|
+
return { eSIMWallet, copied: 0n, batches: [], alreadyComplete: true };
|
|
294
|
+
const batches = [];
|
|
295
|
+
let copied = 0n;
|
|
296
|
+
let outstanding = true;
|
|
297
|
+
while (outstanding) {
|
|
298
|
+
const hash = await _setHistoryForLazyWallet(client, eSIMIdentifier, maxEntries);
|
|
299
|
+
const batch = await _batchEvent(publicClient, lazyRegistryAddress, hash, "LazyHistoryCopied");
|
|
300
|
+
if (batch._copied === 0n)
|
|
301
|
+
throw new StalledBatchError(hash, batch._remaining);
|
|
302
|
+
batches.push({ hash, copied: batch._copied, remaining: batch._remaining });
|
|
303
|
+
copied += batch._copied;
|
|
304
|
+
outstanding = batch._remaining > 0n;
|
|
305
|
+
}
|
|
306
|
+
return { eSIMWallet, copied, batches, alreadyComplete: false };
|
|
307
|
+
};
|
|
308
|
+
// ---------------------------------------------------------------------------
|
|
309
|
+
// Owner payloads - only reachable through schedule
|
|
310
|
+
// ---------------------------------------------------------------------------
|
|
311
|
+
// Both are `onlyOwner`, and on the live deployment the owner is the timelock, so
|
|
312
|
+
// they exist as something to schedule rather than to send. Each returns the
|
|
313
|
+
// `OwnerCall` to hand to `protocolAdmin.schedule`.
|
|
314
|
+
/**
|
|
315
|
+
* Offer ownership to a new address. Pass the result to `schedule`.
|
|
316
|
+
*
|
|
317
|
+
* Ownable2Step, so the offer changes nothing until the named address calls
|
|
318
|
+
* `acceptOwnership`. Until then the current owner keeps every power.
|
|
319
|
+
*/
|
|
320
|
+
export const _transferOwnershipCall = async (client, newOwner) => {
|
|
321
|
+
const chainID = await client.getChainId();
|
|
322
|
+
const rpcURL = client.transport.url;
|
|
323
|
+
const values = _getChainSpecificConstants(chainID, rpcURL);
|
|
324
|
+
return {
|
|
325
|
+
address: values.factoryAddresses.LAZY_WALLET_REGISTRY,
|
|
326
|
+
abi: LazyWalletRegistry,
|
|
327
|
+
functionName: 'transferOwnership',
|
|
328
|
+
args: [newOwner],
|
|
329
|
+
};
|
|
330
|
+
};
|
|
331
|
+
/**
|
|
332
|
+
* Point the proxy at a new implementation. Builds `upgradeToAndCall`. Pass the
|
|
333
|
+
* result to `schedule`.
|
|
334
|
+
*
|
|
335
|
+
* This contract holds every fiat user's unclaimed purchase history, so a layout
|
|
336
|
+
* change here strands data that has no other copy. Diff the storage layout
|
|
337
|
+
* before scheduling. `data` runs on the proxy straight after the swap and is
|
|
338
|
+
* where a `reinitializer` goes.
|
|
339
|
+
*/
|
|
340
|
+
export const _upgradeCall = async (client, newImplementation, data = '0x') => {
|
|
341
|
+
const chainID = await client.getChainId();
|
|
342
|
+
const rpcURL = client.transport.url;
|
|
343
|
+
const values = _getChainSpecificConstants(chainID, rpcURL);
|
|
344
|
+
return {
|
|
345
|
+
address: values.factoryAddresses.LAZY_WALLET_REGISTRY,
|
|
346
|
+
abi: LazyWalletRegistry,
|
|
347
|
+
functionName: 'upgradeToAndCall',
|
|
348
|
+
args: [newImplementation, data],
|
|
349
|
+
};
|
|
350
|
+
};
|
|
351
|
+
/**
|
|
352
|
+
* Take ownership after a `transferOwnership` named this client. `msg.sender`
|
|
353
|
+
* must equal `pendingOwner`, so the `client` is the incoming owner.
|
|
354
|
+
*
|
|
355
|
+
* Where the incoming owner is the timelock, use
|
|
356
|
+
* `protocolAdmin.acceptOwnershipBatch` instead, which accepts for every contract
|
|
357
|
+
* at once.
|
|
358
|
+
*/
|
|
359
|
+
export const _acceptOwnership = async (client) => {
|
|
49
360
|
const chainID = await client.getChainId();
|
|
50
361
|
const rpcURL = client.transport.url;
|
|
51
362
|
const values = _getChainSpecificConstants(chainID, rpcURL);
|
|
@@ -56,7 +367,7 @@ export const _switchESIMIdentifierToNewDeviceIdentifier = async (client, eSIMIde
|
|
|
56
367
|
chain: values.chain,
|
|
57
368
|
account: client.account.address,
|
|
58
369
|
abi: LazyWalletRegistry,
|
|
59
|
-
functionName: '
|
|
60
|
-
args: [
|
|
370
|
+
functionName: 'acceptOwnership',
|
|
371
|
+
args: []
|
|
61
372
|
});
|
|
62
373
|
};
|