kokio-sdk 2.0.0 → 3.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 +21 -7
- package/dist/esm/abis/DeviceWallet.js +60 -59
- package/dist/esm/abis/ESIMWallet.js +263 -58
- package/dist/esm/abis/ESIMWalletFactory.js +2 -2
- package/dist/esm/abis/LazyWalletRegistry.js +68 -24
- package/dist/esm/abis/PaymentAdapter.js +861 -0
- package/dist/esm/abis/Registry.js +294 -18
- package/dist/esm/abis/RegistryHelper.js +101 -9
- package/dist/esm/abis/index.js +2 -1
- package/dist/esm/admin/config-admin.js +4 -0
- package/dist/esm/admin/interface/deviceWalletClass.js +3 -3
- package/dist/esm/admin/interface/eSIMWalletClass.js +6 -6
- package/dist/esm/admin/interface/lazyWalletRegistryClass.js +4 -1
- package/dist/esm/admin/interface/paymentAdapterClass.js +54 -0
- package/dist/esm/admin/interface/protocolAdminClass.js +6 -3
- package/dist/esm/admin/interface/registryClass.js +15 -6
- package/dist/esm/config.js +3 -0
- package/dist/esm/interface/deviceWalletClass.js +5 -5
- package/dist/esm/interface/eSIMWalletClass.js +10 -7
- package/dist/esm/interface/paymentAdapterClass.js +28 -0
- package/dist/esm/interface/registryClass.js +12 -3
- package/dist/esm/logic/admin/deviceWallet.eoa.js +3 -3
- package/dist/esm/logic/admin/deviceWalletFactory.eoa.js +6 -6
- package/dist/esm/logic/admin/eSIMWallet.eoa.js +14 -12
- package/dist/esm/logic/admin/eSIMWalletFactory.eoa.js +4 -4
- package/dist/esm/logic/admin/lazyWalletRegistry.eoa.js +7 -7
- package/dist/esm/logic/admin/paymentAdapter.eoa.js +123 -0
- package/dist/esm/logic/admin/protocolAdmin.eoa.js +34 -16
- package/dist/esm/logic/admin/reads/deviceWallet.reads.js +2 -2
- package/dist/esm/logic/admin/reads/eSIMWallet.reads.js +8 -7
- package/dist/esm/logic/admin/reads/lazyWalletRegistry.reads.js +19 -2
- package/dist/esm/logic/admin/reads/paymentAdapter.reads.js +106 -0
- package/dist/esm/logic/admin/reads/registry.reads.js +34 -6
- package/dist/esm/logic/admin/registry.eoa.js +44 -20
- package/dist/esm/logic/constants.js +17 -87
- package/dist/esm/logic/deviceWallet.js +11 -11
- package/dist/esm/logic/eSIMWallet.js +51 -22
- package/dist/esm/logic/errors.js +30 -1
- package/dist/esm/logic/paymentAdapter.js +116 -0
- package/dist/esm/logic/registry.js +50 -5
- package/dist/esm/types-export.js +1 -1
- package/dist/esm/types.js +11 -1
- package/dist/types/abis/DeviceWallet.d.ts +50 -49
- package/dist/types/abis/ESIMWallet.d.ts +215 -55
- package/dist/types/abis/ESIMWalletFactory.d.ts +2 -2
- package/dist/types/abis/LazyWalletRegistry.d.ts +58 -24
- package/dist/types/abis/PaymentAdapter.d.ts +661 -0
- package/dist/types/abis/Registry.d.ts +233 -18
- package/dist/types/abis/RegistryHelper.d.ts +83 -9
- package/dist/types/abis/index.d.ts +2 -1
- package/dist/types/admin/config-admin.d.ts +2 -0
- package/dist/types/admin/interface/deviceWalletClass.d.ts +1 -1
- package/dist/types/admin/interface/eSIMWalletClass.d.ts +3 -3
- package/dist/types/admin/interface/lazyWalletRegistryClass.d.ts +1 -0
- package/dist/types/admin/interface/paymentAdapterClass.d.ts +20 -0
- package/dist/types/admin/interface/protocolAdminClass.d.ts +2 -1
- package/dist/types/admin/interface/registryClass.d.ts +6 -2
- package/dist/types/config.d.ts +2 -0
- package/dist/types/interface/constantsClass.d.ts +2 -2
- package/dist/types/interface/deviceWalletClass.d.ts +2 -2
- package/dist/types/interface/eSIMWalletClass.d.ts +5 -4
- package/dist/types/interface/paymentAdapterClass.d.ts +13 -0
- package/dist/types/interface/registryClass.d.ts +5 -2
- package/dist/types/logic/admin/eSIMWallet.eoa.d.ts +9 -6
- package/dist/types/logic/admin/paymentAdapter.eoa.d.ts +28 -0
- package/dist/types/logic/admin/protocolAdmin.eoa.d.ts +12 -2
- package/dist/types/logic/admin/reads/deviceWallet.reads.d.ts +1 -1
- package/dist/types/logic/admin/reads/eSIMWallet.reads.d.ts +5 -4
- package/dist/types/logic/admin/reads/lazyWalletRegistry.reads.d.ts +7 -0
- package/dist/types/logic/admin/reads/paymentAdapter.reads.d.ts +30 -0
- package/dist/types/logic/admin/reads/registry.reads.d.ts +13 -5
- package/dist/types/logic/admin/registry.eoa.d.ts +18 -8
- package/dist/types/logic/constants.d.ts +5 -17
- package/dist/types/logic/deviceWallet.d.ts +7 -7
- package/dist/types/logic/eSIMWallet.d.ts +29 -15
- package/dist/types/logic/errors.d.ts +16 -1
- package/dist/types/logic/paymentAdapter.d.ts +40 -0
- package/dist/types/logic/registry.d.ts +20 -5
- package/dist/types/types-export.d.ts +2 -1
- package/dist/types/types.d.ts +20 -2
- package/package.json +1 -1
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { encodeFunctionData, publicActions } from "viem";
|
|
2
2
|
import { _getChainSpecificConstants } from "../constants.js";
|
|
3
|
-
import { MissingEOAWalletError } from "../errors.js";
|
|
3
|
+
import { MissingEOAWalletError, writeContractOrThrow } from "../errors.js";
|
|
4
4
|
import { ProtocolAdmin, Registry } from "../../abis/index.js";
|
|
5
5
|
// Admin-EOA logic for `ProtocolAdmin`, the timelock that owns `Registry`,
|
|
6
6
|
// `LazyWalletRegistry`, `DeviceWalletFactory` and `ESIMWalletFactory`.
|
|
@@ -116,7 +116,7 @@ export const _schedule = async (client, call, opts = {}, delay) => {
|
|
|
116
116
|
functionName: "hashOperation",
|
|
117
117
|
args: [target, value, payload, predecessor, salt]
|
|
118
118
|
});
|
|
119
|
-
const hash = await client
|
|
119
|
+
const hash = await writeContractOrThrow(client, {
|
|
120
120
|
address: values.factoryAddresses.PROTOCOL_ADMIN,
|
|
121
121
|
chain: values.chain,
|
|
122
122
|
account: client.account.address,
|
|
@@ -156,7 +156,7 @@ export const _scheduleBatch = async (client, calls, opts = {}, delay) => {
|
|
|
156
156
|
functionName: "hashOperationBatch",
|
|
157
157
|
args: [targets, callValues, payloads, predecessor, salt]
|
|
158
158
|
});
|
|
159
|
-
const hash = await client
|
|
159
|
+
const hash = await writeContractOrThrow(client, {
|
|
160
160
|
address: values.factoryAddresses.PROTOCOL_ADMIN,
|
|
161
161
|
chain: values.chain,
|
|
162
162
|
account: client.account.address,
|
|
@@ -183,7 +183,7 @@ export const _scheduleRaw = async (client, target, value, payload, predecessor,
|
|
|
183
183
|
functionName: "hashOperation",
|
|
184
184
|
args: [target, value, payload, predecessor, salt]
|
|
185
185
|
});
|
|
186
|
-
const hash = await client
|
|
186
|
+
const hash = await writeContractOrThrow(client, {
|
|
187
187
|
address: values.factoryAddresses.PROTOCOL_ADMIN,
|
|
188
188
|
chain: values.chain,
|
|
189
189
|
account: client.account.address,
|
|
@@ -208,7 +208,7 @@ export const _execute = async (client, operation) => {
|
|
|
208
208
|
const values = await _resolve(client);
|
|
209
209
|
if (!client.account)
|
|
210
210
|
throw new MissingEOAWalletError();
|
|
211
|
-
return client
|
|
211
|
+
return writeContractOrThrow(client, {
|
|
212
212
|
address: values.factoryAddresses.PROTOCOL_ADMIN,
|
|
213
213
|
chain: values.chain,
|
|
214
214
|
account: client.account.address,
|
|
@@ -223,7 +223,7 @@ export const _executeBatch = async (client, operation) => {
|
|
|
223
223
|
const values = await _resolve(client);
|
|
224
224
|
if (!client.account)
|
|
225
225
|
throw new MissingEOAWalletError();
|
|
226
|
-
return client
|
|
226
|
+
return writeContractOrThrow(client, {
|
|
227
227
|
address: values.factoryAddresses.PROTOCOL_ADMIN,
|
|
228
228
|
chain: values.chain,
|
|
229
229
|
account: client.account.address,
|
|
@@ -238,7 +238,7 @@ export const _executeRaw = async (client, target, value, payload, predecessor, s
|
|
|
238
238
|
const values = await _resolve(client);
|
|
239
239
|
if (!client.account)
|
|
240
240
|
throw new MissingEOAWalletError();
|
|
241
|
-
return client
|
|
241
|
+
return writeContractOrThrow(client, {
|
|
242
242
|
address: values.factoryAddresses.PROTOCOL_ADMIN,
|
|
243
243
|
chain: values.chain,
|
|
244
244
|
account: client.account.address,
|
|
@@ -259,7 +259,7 @@ export const _cancel = async (client, id) => {
|
|
|
259
259
|
const values = await _resolve(client);
|
|
260
260
|
if (!client.account)
|
|
261
261
|
throw new MissingEOAWalletError();
|
|
262
|
-
return client
|
|
262
|
+
return writeContractOrThrow(client, {
|
|
263
263
|
address: values.factoryAddresses.PROTOCOL_ADMIN,
|
|
264
264
|
chain: values.chain,
|
|
265
265
|
account: client.account.address,
|
|
@@ -281,7 +281,7 @@ export const _unpauseInstantly = async (client, target) => {
|
|
|
281
281
|
const values = await _resolve(client);
|
|
282
282
|
if (!client.account)
|
|
283
283
|
throw new MissingEOAWalletError();
|
|
284
|
-
return client
|
|
284
|
+
return writeContractOrThrow(client, {
|
|
285
285
|
address: values.factoryAddresses.PROTOCOL_ADMIN,
|
|
286
286
|
chain: values.chain,
|
|
287
287
|
account: client.account.address,
|
|
@@ -301,7 +301,7 @@ export const _revokeCancellersInstantly = async (client, accounts) => {
|
|
|
301
301
|
const values = await _resolve(client);
|
|
302
302
|
if (!client.account)
|
|
303
303
|
throw new MissingEOAWalletError();
|
|
304
|
-
return client
|
|
304
|
+
return writeContractOrThrow(client, {
|
|
305
305
|
address: values.factoryAddresses.PROTOCOL_ADMIN,
|
|
306
306
|
chain: values.chain,
|
|
307
307
|
account: client.account.address,
|
|
@@ -324,7 +324,7 @@ export const _disableAdminInstantly = async (client, target) => {
|
|
|
324
324
|
const values = await _resolve(client);
|
|
325
325
|
if (!client.account)
|
|
326
326
|
throw new MissingEOAWalletError();
|
|
327
|
-
return client
|
|
327
|
+
return writeContractOrThrow(client, {
|
|
328
328
|
address: values.factoryAddresses.PROTOCOL_ADMIN,
|
|
329
329
|
chain: values.chain,
|
|
330
330
|
account: client.account.address,
|
|
@@ -345,7 +345,7 @@ export const _acceptOwnershipBatch = async (client, targets) => {
|
|
|
345
345
|
const values = await _resolve(client);
|
|
346
346
|
if (!client.account)
|
|
347
347
|
throw new MissingEOAWalletError();
|
|
348
|
-
return client
|
|
348
|
+
return writeContractOrThrow(client, {
|
|
349
349
|
address: values.factoryAddresses.PROTOCOL_ADMIN,
|
|
350
350
|
chain: values.chain,
|
|
351
351
|
account: client.account.address,
|
|
@@ -362,7 +362,7 @@ export const _renounceRole = async (client, role, account) => {
|
|
|
362
362
|
const values = await _resolve(client);
|
|
363
363
|
if (!client.account)
|
|
364
364
|
throw new MissingEOAWalletError();
|
|
365
|
-
return client
|
|
365
|
+
return writeContractOrThrow(client, {
|
|
366
366
|
address: values.factoryAddresses.PROTOCOL_ADMIN,
|
|
367
367
|
chain: values.chain,
|
|
368
368
|
account: client.account.address,
|
|
@@ -456,22 +456,40 @@ export const _unpauseCall = async (client, target) => {
|
|
|
456
456
|
};
|
|
457
457
|
};
|
|
458
458
|
/**
|
|
459
|
-
* Set the fallback
|
|
459
|
+
* Set the fallback price ceiling, in USD cents. Pass the result to `schedule`.
|
|
460
460
|
*
|
|
461
461
|
* Zero reverts on execution, not on scheduling, so a zero here costs the whole
|
|
462
462
|
* delay before it fails.
|
|
463
463
|
*
|
|
464
464
|
* `target` defaults to the registry.
|
|
465
465
|
*/
|
|
466
|
-
export const
|
|
466
|
+
export const _setDefaultPriceCapUSDCentsCall = async (client, cap, target) => {
|
|
467
467
|
const values = await _resolve(client);
|
|
468
468
|
return {
|
|
469
469
|
address: target ?? values.factoryAddresses.REGISTRY,
|
|
470
470
|
abi: Registry,
|
|
471
|
-
functionName: '
|
|
471
|
+
functionName: 'setDefaultPriceCapUSDCents',
|
|
472
472
|
args: [cap],
|
|
473
473
|
};
|
|
474
474
|
};
|
|
475
|
+
/**
|
|
476
|
+
* Point the registry at a new payment adapter. Pass the result to `schedule`.
|
|
477
|
+
*
|
|
478
|
+
* Owner only, deliberately not the admin: the adapter holds the spent payment
|
|
479
|
+
* references, so an admin that could swap it would get an empty set back and
|
|
480
|
+
* could record every purchase a second time.
|
|
481
|
+
*
|
|
482
|
+
* `target` defaults to the registry.
|
|
483
|
+
*/
|
|
484
|
+
export const _setPaymentAdapterCall = async (client, paymentAdapter, target) => {
|
|
485
|
+
const values = await _resolve(client);
|
|
486
|
+
return {
|
|
487
|
+
address: target ?? values.factoryAddresses.REGISTRY,
|
|
488
|
+
abi: Registry,
|
|
489
|
+
functionName: 'setPaymentAdapter',
|
|
490
|
+
args: [paymentAdapter],
|
|
491
|
+
};
|
|
492
|
+
};
|
|
475
493
|
// ---------------------------------------------------------------------------
|
|
476
494
|
// Admin suspension payloads - the owner's route, aimed at the target contract
|
|
477
495
|
// ---------------------------------------------------------------------------
|
|
@@ -24,11 +24,11 @@ export const _isValidESIMWallet = async (client, deviceWalletAddress, eSIMWallet
|
|
|
24
24
|
});
|
|
25
25
|
};
|
|
26
26
|
/** Whether an eSIM wallet is allowed to pull ETH from this device wallet. */
|
|
27
|
-
export const
|
|
27
|
+
export const _canPullFunds = async (client, deviceWalletAddress, eSIMWallet) => {
|
|
28
28
|
return client.extend(publicActions).readContract({
|
|
29
29
|
address: deviceWalletAddress,
|
|
30
30
|
abi: DeviceWallet,
|
|
31
|
-
functionName: "
|
|
31
|
+
functionName: "canPullFunds",
|
|
32
32
|
args: [eSIMWallet]
|
|
33
33
|
});
|
|
34
34
|
};
|
|
@@ -26,13 +26,13 @@ export const _eSIMUniqueIdentifier = async (client, eSIMWalletAddress) => {
|
|
|
26
26
|
* This wallet's own price ceiling in wei. Zero means it follows the registry's
|
|
27
27
|
* `defaultDataBundlePriceCap` instead, which is the state a fresh wallet and a
|
|
28
28
|
* newly handed-over wallet both start in. Worth reading before naming a price on
|
|
29
|
-
* `
|
|
29
|
+
* `buyDataBundleWithToken`, since a price over the ceiling reverts.
|
|
30
30
|
*/
|
|
31
|
-
export const
|
|
31
|
+
export const _priceCapUSDCents = async (client, eSIMWalletAddress) => {
|
|
32
32
|
return client.extend(publicActions).readContract({
|
|
33
33
|
address: eSIMWalletAddress,
|
|
34
34
|
abi: ESIMWallet,
|
|
35
|
-
functionName: "
|
|
35
|
+
functionName: "priceCapUSDCents",
|
|
36
36
|
args: []
|
|
37
37
|
});
|
|
38
38
|
};
|
|
@@ -74,15 +74,16 @@ export const _deviceWallet = async (client, eSIMWalletAddress) => {
|
|
|
74
74
|
*
|
|
75
75
|
* The contract publishes no length getter, so there is no way to ask how many
|
|
76
76
|
* entries exist. Read upwards from zero until a call reverts, or track the count
|
|
77
|
-
* from the `
|
|
78
|
-
* `_totalEntries` is the length
|
|
77
|
+
* from the `DataBundleBoughtWithToken`, `DataBundleSettlementRecorded` and
|
|
78
|
+
* `TransactionHistoryPopulated` events, whose `_totalEntries` is the length
|
|
79
|
+
* after the batch landed.
|
|
79
80
|
*/
|
|
80
81
|
export const _transactionHistory = async (client, eSIMWalletAddress, index) => {
|
|
81
|
-
const [
|
|
82
|
+
const [id, priceUSDCents, settlement] = await client.extend(publicActions).readContract({
|
|
82
83
|
address: eSIMWalletAddress,
|
|
83
84
|
abi: ESIMWallet,
|
|
84
85
|
functionName: "transactionHistory",
|
|
85
86
|
args: [index]
|
|
86
87
|
});
|
|
87
|
-
return {
|
|
88
|
+
return { id, priceUSDCents, settlement };
|
|
88
89
|
};
|
|
@@ -38,13 +38,13 @@ export const _deviceIdentifierToESIMDetails = async (client, deviceIdentifier, e
|
|
|
38
38
|
const chainID = await client.getChainId();
|
|
39
39
|
const rpcURL = client.transport.url;
|
|
40
40
|
const values = _getChainSpecificConstants(chainID, rpcURL);
|
|
41
|
-
const [
|
|
41
|
+
const [id, priceUSDCents, settlement] = await client.extend(publicActions).readContract({
|
|
42
42
|
address: values.factoryAddresses.LAZY_WALLET_REGISTRY,
|
|
43
43
|
abi: LazyWalletRegistry,
|
|
44
44
|
functionName: "deviceIdentifierToESIMDetails",
|
|
45
45
|
args: [deviceIdentifier, eSIMIdentifier, index]
|
|
46
46
|
});
|
|
47
|
-
return {
|
|
47
|
+
return { id, priceUSDCents, settlement };
|
|
48
48
|
};
|
|
49
49
|
/** Most eSIM wallets one `deployLazyWalletAndSetESIMIdentifier` call will deploy. */
|
|
50
50
|
export const _maxESIMWalletsPerCall = async (client) => {
|
|
@@ -125,6 +125,23 @@ export const _historyEntriesCopied = async (client, eSIMIdentifier) => {
|
|
|
125
125
|
args: [eSIMIdentifier]
|
|
126
126
|
});
|
|
127
127
|
};
|
|
128
|
+
/**
|
|
129
|
+
* History entries still waiting to be copied in for this eSIM. A wallet's own
|
|
130
|
+
* purchase paths (`buyDataBundleWithToken`, `recordSettledPurchase`) refuse a
|
|
131
|
+
* new entry while this is non-zero, since it would land ahead of history that
|
|
132
|
+
* has not arrived yet.
|
|
133
|
+
*/
|
|
134
|
+
export const _outstandingHistoryEntries = async (client, eSIMIdentifier) => {
|
|
135
|
+
const chainID = await client.getChainId();
|
|
136
|
+
const rpcURL = client.transport.url;
|
|
137
|
+
const values = _getChainSpecificConstants(chainID, rpcURL);
|
|
138
|
+
return client.extend(publicActions).readContract({
|
|
139
|
+
address: values.factoryAddresses.LAZY_WALLET_REGISTRY,
|
|
140
|
+
abi: LazyWalletRegistry,
|
|
141
|
+
functionName: "outstandingHistoryEntries",
|
|
142
|
+
args: [eSIMIdentifier]
|
|
143
|
+
});
|
|
144
|
+
};
|
|
128
145
|
/** Whether a device identifier has purchases recorded against it here. */
|
|
129
146
|
export const _isDeviceIdentifierReserved = async (client, deviceIdentifier) => {
|
|
130
147
|
const chainID = await client.getChainId();
|
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
import { publicActions } from "viem";
|
|
2
|
+
import { _getChainSpecificConstants } from "../../constants.js";
|
|
3
|
+
import { PaymentAdapter } from "../../../abis/index.js";
|
|
4
|
+
// Read-only admin logic for `PaymentAdapter`. Every write on it
|
|
5
|
+
// (registerAsset/updateAsset) is `onlyOwner`, i.e. only reachable through the
|
|
6
|
+
// timelock, so those live as payload builders on `KokioAdmin.protocolAdmin`
|
|
7
|
+
// rather than here.
|
|
8
|
+
/** The registry this adapter reads `vault()` and `isESIMWalletValid()` from. */
|
|
9
|
+
export const _registry = async (client) => {
|
|
10
|
+
const chainID = await client.getChainId();
|
|
11
|
+
const rpcURL = client.transport.url;
|
|
12
|
+
const values = _getChainSpecificConstants(chainID, rpcURL);
|
|
13
|
+
return client.extend(publicActions).readContract({
|
|
14
|
+
address: values.factoryAddresses.PAYMENT_ADAPTER,
|
|
15
|
+
abi: PaymentAdapter,
|
|
16
|
+
functionName: "registry",
|
|
17
|
+
args: []
|
|
18
|
+
});
|
|
19
|
+
};
|
|
20
|
+
/** The ERC-20 registered under the `USDC` symbol at configure time. */
|
|
21
|
+
export const _settlementToken = async (client) => {
|
|
22
|
+
const chainID = await client.getChainId();
|
|
23
|
+
const rpcURL = client.transport.url;
|
|
24
|
+
const values = _getChainSpecificConstants(chainID, rpcURL);
|
|
25
|
+
return client.extend(publicActions).readContract({
|
|
26
|
+
address: values.factoryAddresses.PAYMENT_ADAPTER,
|
|
27
|
+
abi: PaymentAdapter,
|
|
28
|
+
functionName: "settlementToken",
|
|
29
|
+
args: []
|
|
30
|
+
});
|
|
31
|
+
};
|
|
32
|
+
/**
|
|
33
|
+
* The raw currency table entry for a symbol. `decimals` reads zero for a symbol
|
|
34
|
+
* never registered, which is how `resolveAsset` tells "not registered" apart
|
|
35
|
+
* from "registered but withdrawn" (`allowed: false`).
|
|
36
|
+
*/
|
|
37
|
+
export const _assets = async (client, symbol) => {
|
|
38
|
+
const chainID = await client.getChainId();
|
|
39
|
+
const rpcURL = client.transport.url;
|
|
40
|
+
const values = _getChainSpecificConstants(chainID, rpcURL);
|
|
41
|
+
const [allowed, isDollarUnit, decimals, token] = await client.extend(publicActions).readContract({
|
|
42
|
+
address: values.factoryAddresses.PAYMENT_ADAPTER,
|
|
43
|
+
abi: PaymentAdapter,
|
|
44
|
+
functionName: "assets",
|
|
45
|
+
args: [symbol]
|
|
46
|
+
});
|
|
47
|
+
return { allowed, isDollarUnit, decimals, token };
|
|
48
|
+
};
|
|
49
|
+
/** A currency's full entry, reverting if the symbol was never registered. */
|
|
50
|
+
export const _resolveAsset = async (client, symbol) => {
|
|
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.PAYMENT_ADAPTER,
|
|
56
|
+
abi: PaymentAdapter,
|
|
57
|
+
functionName: "resolveAsset",
|
|
58
|
+
args: [symbol]
|
|
59
|
+
});
|
|
60
|
+
};
|
|
61
|
+
/**
|
|
62
|
+
* The amount of `symbol`, in its smallest unit, that a `priceUSDCents` charge
|
|
63
|
+
* currently costs. Worth reading before `recordSettledPurchase`, to size
|
|
64
|
+
* `_tokenAmount` for the backend's own settlement record.
|
|
65
|
+
*/
|
|
66
|
+
export const _quote = async (client, symbol, priceUSDCents) => {
|
|
67
|
+
const chainID = await client.getChainId();
|
|
68
|
+
const rpcURL = client.transport.url;
|
|
69
|
+
const values = _getChainSpecificConstants(chainID, rpcURL);
|
|
70
|
+
return client.extend(publicActions).readContract({
|
|
71
|
+
address: values.factoryAddresses.PAYMENT_ADAPTER,
|
|
72
|
+
abi: PaymentAdapter,
|
|
73
|
+
functionName: "quote",
|
|
74
|
+
args: [symbol, priceUSDCents]
|
|
75
|
+
});
|
|
76
|
+
};
|
|
77
|
+
/**
|
|
78
|
+
* Whether a payment reference has already been spent here. Retired from the
|
|
79
|
+
* registry's live purchase paths (`PaymentAdapter.consumePaymentReference` is
|
|
80
|
+
* `onlyRegistry` but nothing calls it any more): replay protection now lives on
|
|
81
|
+
* `Registry.usedPaymentReferences`, scoped per eSIM wallet. Kept for whatever
|
|
82
|
+
* still reads the adapter's own record from before that move.
|
|
83
|
+
*/
|
|
84
|
+
export const _usedReferences = async (client, paymentReference) => {
|
|
85
|
+
const chainID = await client.getChainId();
|
|
86
|
+
const rpcURL = client.transport.url;
|
|
87
|
+
const values = _getChainSpecificConstants(chainID, rpcURL);
|
|
88
|
+
return client.extend(publicActions).readContract({
|
|
89
|
+
address: values.factoryAddresses.PAYMENT_ADAPTER,
|
|
90
|
+
abi: PaymentAdapter,
|
|
91
|
+
functionName: "usedReferences",
|
|
92
|
+
args: [paymentReference]
|
|
93
|
+
});
|
|
94
|
+
};
|
|
95
|
+
/** The address holding upgrade authority over this adapter (its owner). */
|
|
96
|
+
export const _upgradeManager = async (client) => {
|
|
97
|
+
const chainID = await client.getChainId();
|
|
98
|
+
const rpcURL = client.transport.url;
|
|
99
|
+
const values = _getChainSpecificConstants(chainID, rpcURL);
|
|
100
|
+
return client.extend(publicActions).readContract({
|
|
101
|
+
address: values.factoryAddresses.PAYMENT_ADAPTER,
|
|
102
|
+
abi: PaymentAdapter,
|
|
103
|
+
functionName: "upgradeManager",
|
|
104
|
+
args: []
|
|
105
|
+
});
|
|
106
|
+
};
|
|
@@ -54,8 +54,8 @@ export const _adminDisabled = async (client) => {
|
|
|
54
54
|
});
|
|
55
55
|
};
|
|
56
56
|
/**
|
|
57
|
-
* Whether the protocol is paused. While true,
|
|
58
|
-
* device wallets and eSIM wallets
|
|
57
|
+
* Whether the protocol is paused. While true, the purchase and token-pull
|
|
58
|
+
* paths on the device wallets and eSIM wallets revert `ProtocolPaused`.
|
|
59
59
|
*/
|
|
60
60
|
export const _paused = async (client) => {
|
|
61
61
|
const chainID = await client.getChainId();
|
|
@@ -69,17 +69,17 @@ export const _paused = async (client) => {
|
|
|
69
69
|
});
|
|
70
70
|
};
|
|
71
71
|
/**
|
|
72
|
-
* The fallback price ceiling in
|
|
73
|
-
* its own. Never zero.
|
|
72
|
+
* The fallback price ceiling in USD cents, applied to any eSIM wallet holding no
|
|
73
|
+
* cap of its own. Never zero.
|
|
74
74
|
*/
|
|
75
|
-
export const
|
|
75
|
+
export const _defaultPriceCapUSDCents = async (client) => {
|
|
76
76
|
const chainID = await client.getChainId();
|
|
77
77
|
const rpcURL = client.transport.url;
|
|
78
78
|
const values = _getChainSpecificConstants(chainID, rpcURL);
|
|
79
79
|
return client.extend(publicActions).readContract({
|
|
80
80
|
address: values.factoryAddresses.REGISTRY,
|
|
81
81
|
abi: Registry,
|
|
82
|
-
functionName: "
|
|
82
|
+
functionName: "defaultPriceCapUSDCents",
|
|
83
83
|
args: []
|
|
84
84
|
});
|
|
85
85
|
};
|
|
@@ -414,3 +414,31 @@ export const _upgradeInterfaceVersion = async (client) => {
|
|
|
414
414
|
args: []
|
|
415
415
|
});
|
|
416
416
|
};
|
|
417
|
+
/** The payment adapter this registry currently points at. */
|
|
418
|
+
export const _paymentAdapter = async (client) => {
|
|
419
|
+
const chainID = await client.getChainId();
|
|
420
|
+
const rpcURL = client.transport.url;
|
|
421
|
+
const values = _getChainSpecificConstants(chainID, rpcURL);
|
|
422
|
+
return client.extend(publicActions).readContract({
|
|
423
|
+
address: values.factoryAddresses.REGISTRY,
|
|
424
|
+
abi: Registry,
|
|
425
|
+
functionName: "paymentAdapter",
|
|
426
|
+
args: []
|
|
427
|
+
});
|
|
428
|
+
};
|
|
429
|
+
/**
|
|
430
|
+
* Whether a payment reference has already been spent for an eSIM wallet.
|
|
431
|
+
* Scoped per wallet: pass the same `keccak256(abi.encode(eSIMWallet, paymentReference))`
|
|
432
|
+
* the contract keys `usedPaymentReferences` by, not the bare reference.
|
|
433
|
+
*/
|
|
434
|
+
export const _usedPaymentReferences = async (client, scopedReference) => {
|
|
435
|
+
const chainID = await client.getChainId();
|
|
436
|
+
const rpcURL = client.transport.url;
|
|
437
|
+
const values = _getChainSpecificConstants(chainID, rpcURL);
|
|
438
|
+
return client.extend(publicActions).readContract({
|
|
439
|
+
address: values.factoryAddresses.REGISTRY,
|
|
440
|
+
abi: Registry,
|
|
441
|
+
functionName: "usedPaymentReferences",
|
|
442
|
+
args: [scopedReference]
|
|
443
|
+
});
|
|
444
|
+
};
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { _getChainSpecificConstants } from "../constants.js";
|
|
2
|
-
import { MissingEOAWalletError } from "../errors.js";
|
|
2
|
+
import { MissingEOAWalletError, writeContractOrThrow } from "../errors.js";
|
|
3
3
|
import { Registry } from "../../abis/index.js";
|
|
4
4
|
// Admin-EOA logic for `Registry`. Most of this is `onlyOwner`, so the `client`
|
|
5
5
|
// must carry the owner EOA. `_acceptAdminUpdate` is the nominee's own call and
|
|
@@ -16,7 +16,7 @@ export const _addOrUpdateLazyWalletRegistryAddress = async (client, lazyWalletRe
|
|
|
16
16
|
const values = _getChainSpecificConstants(chainID, rpcURL);
|
|
17
17
|
if (!client.account)
|
|
18
18
|
throw new MissingEOAWalletError();
|
|
19
|
-
return client
|
|
19
|
+
return writeContractOrThrow(client, {
|
|
20
20
|
address: values.factoryAddresses.REGISTRY,
|
|
21
21
|
chain: values.chain,
|
|
22
22
|
account: client.account.address,
|
|
@@ -32,7 +32,7 @@ export const _updateVaultAddress = async (client, newVaultAddress) => {
|
|
|
32
32
|
const values = _getChainSpecificConstants(chainID, rpcURL);
|
|
33
33
|
if (!client.account)
|
|
34
34
|
throw new MissingEOAWalletError();
|
|
35
|
-
return client
|
|
35
|
+
return writeContractOrThrow(client, {
|
|
36
36
|
address: values.factoryAddresses.REGISTRY,
|
|
37
37
|
chain: values.chain,
|
|
38
38
|
account: client.account.address,
|
|
@@ -56,7 +56,7 @@ export const _requestAdminUpdate = async (client, newAdmin) => {
|
|
|
56
56
|
const values = _getChainSpecificConstants(chainID, rpcURL);
|
|
57
57
|
if (!client.account)
|
|
58
58
|
throw new MissingEOAWalletError();
|
|
59
|
-
return client
|
|
59
|
+
return writeContractOrThrow(client, {
|
|
60
60
|
address: values.factoryAddresses.REGISTRY,
|
|
61
61
|
chain: values.chain,
|
|
62
62
|
account: client.account.address,
|
|
@@ -78,7 +78,7 @@ export const _disableAdmin = async (client) => {
|
|
|
78
78
|
const values = _getChainSpecificConstants(chainID, rpcURL);
|
|
79
79
|
if (!client.account)
|
|
80
80
|
throw new MissingEOAWalletError();
|
|
81
|
-
return client
|
|
81
|
+
return writeContractOrThrow(client, {
|
|
82
82
|
address: values.factoryAddresses.REGISTRY,
|
|
83
83
|
chain: values.chain,
|
|
84
84
|
account: client.account.address,
|
|
@@ -100,7 +100,7 @@ export const _enableAdmin = async (client) => {
|
|
|
100
100
|
const values = _getChainSpecificConstants(chainID, rpcURL);
|
|
101
101
|
if (!client.account)
|
|
102
102
|
throw new MissingEOAWalletError();
|
|
103
|
-
return client
|
|
103
|
+
return writeContractOrThrow(client, {
|
|
104
104
|
address: values.factoryAddresses.REGISTRY,
|
|
105
105
|
chain: values.chain,
|
|
106
106
|
account: client.account.address,
|
|
@@ -110,13 +110,13 @@ export const _enableAdmin = async (client) => {
|
|
|
110
110
|
});
|
|
111
111
|
};
|
|
112
112
|
/**
|
|
113
|
-
* Stop the
|
|
114
|
-
* `onlyESIMWalletAdmin`, so this is the one emergency lever the backend
|
|
115
|
-
* pull on its own.
|
|
113
|
+
* Stop the purchase and token-pull paths on every device wallet and eSIM
|
|
114
|
+
* wallet. `onlyESIMWalletAdmin`, so this is the one emergency lever the backend
|
|
115
|
+
* key can pull on its own.
|
|
116
116
|
*
|
|
117
117
|
* It cannot release it again: `_unpause` is `onlyOwner`. That split is what stops
|
|
118
|
-
* a compromised backend key holding user funds. Owners can still
|
|
119
|
-
*
|
|
118
|
+
* a compromised backend key holding user funds. Owners can still move their own
|
|
119
|
+
* funds through their device wallet's `execute`, which a pause never reaches.
|
|
120
120
|
*/
|
|
121
121
|
export const _pause = async (client) => {
|
|
122
122
|
const chainID = await client.getChainId();
|
|
@@ -124,7 +124,7 @@ export const _pause = async (client) => {
|
|
|
124
124
|
const values = _getChainSpecificConstants(chainID, rpcURL);
|
|
125
125
|
if (!client.account)
|
|
126
126
|
throw new MissingEOAWalletError();
|
|
127
|
-
return client
|
|
127
|
+
return writeContractOrThrow(client, {
|
|
128
128
|
address: values.factoryAddresses.REGISTRY,
|
|
129
129
|
chain: values.chain,
|
|
130
130
|
account: client.account.address,
|
|
@@ -146,7 +146,7 @@ export const _unpause = async (client) => {
|
|
|
146
146
|
const values = _getChainSpecificConstants(chainID, rpcURL);
|
|
147
147
|
if (!client.account)
|
|
148
148
|
throw new MissingEOAWalletError();
|
|
149
|
-
return client
|
|
149
|
+
return writeContractOrThrow(client, {
|
|
150
150
|
address: values.factoryAddresses.REGISTRY,
|
|
151
151
|
chain: values.chain,
|
|
152
152
|
account: client.account.address,
|
|
@@ -158,23 +158,23 @@ export const _unpause = async (client) => {
|
|
|
158
158
|
/**
|
|
159
159
|
* Set the price ceiling every eSIM wallet falls back to when it holds none of its
|
|
160
160
|
* own. `onlyOwner`, deliberately not the admin: the admin names the price on
|
|
161
|
-
* `
|
|
161
|
+
* `buyDataBundleWithToken`, so it must not also be able to raise its own limit.
|
|
162
162
|
*
|
|
163
163
|
* Zero reverts `ZeroDataBundlePriceCap`, since a zero would read as "no ceiling"
|
|
164
164
|
* for every wallet without one of its own.
|
|
165
165
|
*/
|
|
166
|
-
export const
|
|
166
|
+
export const _setDefaultPriceCapUSDCents = async (client, cap) => {
|
|
167
167
|
const chainID = await client.getChainId();
|
|
168
168
|
const rpcURL = client.transport.url;
|
|
169
169
|
const values = _getChainSpecificConstants(chainID, rpcURL);
|
|
170
170
|
if (!client.account)
|
|
171
171
|
throw new MissingEOAWalletError();
|
|
172
|
-
return client
|
|
172
|
+
return writeContractOrThrow(client, {
|
|
173
173
|
address: values.factoryAddresses.REGISTRY,
|
|
174
174
|
chain: values.chain,
|
|
175
175
|
account: client.account.address,
|
|
176
176
|
abi: Registry,
|
|
177
|
-
functionName: '
|
|
177
|
+
functionName: 'setDefaultPriceCapUSDCents',
|
|
178
178
|
args: [cap]
|
|
179
179
|
});
|
|
180
180
|
};
|
|
@@ -190,7 +190,7 @@ export const _assignESIMIdentifier = async (client, eSIMWalletAddress, eSIMUniqu
|
|
|
190
190
|
const values = _getChainSpecificConstants(chainID, rpcURL);
|
|
191
191
|
if (!client.account)
|
|
192
192
|
throw new MissingEOAWalletError();
|
|
193
|
-
return client
|
|
193
|
+
return writeContractOrThrow(client, {
|
|
194
194
|
address: values.factoryAddresses.REGISTRY,
|
|
195
195
|
chain: values.chain,
|
|
196
196
|
account: client.account.address,
|
|
@@ -199,6 +199,30 @@ export const _assignESIMIdentifier = async (client, eSIMWalletAddress, eSIMUniqu
|
|
|
199
199
|
args: [eSIMWalletAddress, eSIMUniqueIdentifier]
|
|
200
200
|
});
|
|
201
201
|
};
|
|
202
|
+
/**
|
|
203
|
+
* Record a data bundle paid for outside the protocol - a card or an external
|
|
204
|
+
* wallet, never the device wallet. `onlyESIMWalletAdmin`. No money moves here:
|
|
205
|
+
* `_dataBundleDetail.settlement` must be `ExternalWallet` or `Fiat` (the
|
|
206
|
+
* contract reverts `SettlementNotAsserted` on `DeviceWallet`, since this call
|
|
207
|
+
* never sees a transfer to prove it), and `_tokenAmount` is recorded for
|
|
208
|
+
* offchain matching but never checked against `_dataBundleDetail.priceUSDCents`.
|
|
209
|
+
* `_paymentReference` is spendable once per eSIM wallet.
|
|
210
|
+
*/
|
|
211
|
+
export const _recordSettledPurchase = async (client, eSIMWalletAddress, dataBundleDetail, asset, tokenAmount, paymentReference) => {
|
|
212
|
+
const chainID = await client.getChainId();
|
|
213
|
+
const rpcURL = client.transport.url;
|
|
214
|
+
const values = _getChainSpecificConstants(chainID, rpcURL);
|
|
215
|
+
if (!client.account)
|
|
216
|
+
throw new MissingEOAWalletError();
|
|
217
|
+
return writeContractOrThrow(client, {
|
|
218
|
+
address: values.factoryAddresses.REGISTRY,
|
|
219
|
+
chain: values.chain,
|
|
220
|
+
account: client.account.address,
|
|
221
|
+
abi: Registry,
|
|
222
|
+
functionName: 'recordSettledPurchase',
|
|
223
|
+
args: [eSIMWalletAddress, dataBundleDetail, asset, tokenAmount, paymentReference]
|
|
224
|
+
});
|
|
225
|
+
};
|
|
202
226
|
/**
|
|
203
227
|
* Step 2 of the 2-step admin handover: the nominee accepts. The chain requires
|
|
204
228
|
* `msg.sender` to equal the pending admin, so the `client` here must be the
|
|
@@ -210,7 +234,7 @@ export const _acceptAdminUpdate = async (client) => {
|
|
|
210
234
|
const values = _getChainSpecificConstants(chainID, rpcURL);
|
|
211
235
|
if (!client.account)
|
|
212
236
|
throw new MissingEOAWalletError();
|
|
213
|
-
return client
|
|
237
|
+
return writeContractOrThrow(client, {
|
|
214
238
|
address: values.factoryAddresses.REGISTRY,
|
|
215
239
|
chain: values.chain,
|
|
216
240
|
account: client.account.address,
|
|
@@ -234,7 +258,7 @@ export const _acceptOwnership = async (client) => {
|
|
|
234
258
|
const values = _getChainSpecificConstants(chainID, rpcURL);
|
|
235
259
|
if (!client.account)
|
|
236
260
|
throw new MissingEOAWalletError();
|
|
237
|
-
return client
|
|
261
|
+
return writeContractOrThrow(client, {
|
|
238
262
|
address: values.factoryAddresses.REGISTRY,
|
|
239
263
|
chain: values.chain,
|
|
240
264
|
account: client.account.address,
|