kokio-sdk 3.0.2 → 3.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (53) hide show
  1. package/README.md +15 -15
  2. package/dist/esm/admin/config-admin.js +6 -1
  3. package/dist/esm/admin/interface/callsClass.js +30 -0
  4. package/dist/esm/config.js +1 -1
  5. package/dist/esm/interface/deviceWalletClass.js +10 -1
  6. package/dist/esm/interface/eSIMWalletClass.js +17 -1
  7. package/dist/esm/interface/eSIMWalletFactoryClass.js +9 -1
  8. package/dist/esm/interface/registryClass.js +8 -0
  9. package/dist/esm/interface/smartAccountClass.js +9 -2
  10. package/dist/esm/logic/P256Verifier.js +2 -2
  11. package/dist/esm/logic/account-kit/createSmartAccount.js +47 -36
  12. package/dist/esm/logic/admin/deviceWallet.eoa.js +5 -5
  13. package/dist/esm/logic/admin/deviceWalletFactory.eoa.js +13 -13
  14. package/dist/esm/logic/admin/eSIMWallet.eoa.js +3 -3
  15. package/dist/esm/logic/admin/eSIMWalletFactory.eoa.js +9 -9
  16. package/dist/esm/logic/admin/lazyWalletRegistry.eoa.js +13 -13
  17. package/dist/esm/logic/admin/paymentAdapter.eoa.js +11 -11
  18. package/dist/esm/logic/admin/protocolAdmin.eoa.js +14 -14
  19. package/dist/esm/logic/admin/reads/deviceWalletFactory.reads.js +9 -9
  20. package/dist/esm/logic/admin/reads/eSIMWalletFactory.reads.js +7 -7
  21. package/dist/esm/logic/admin/reads/lazyWalletRegistry.reads.js +18 -18
  22. package/dist/esm/logic/admin/reads/paymentAdapter.reads.js +8 -8
  23. package/dist/esm/logic/admin/reads/protocolAdmin.reads.js +2 -2
  24. package/dist/esm/logic/admin/reads/registry.reads.js +31 -31
  25. package/dist/esm/logic/admin/registry.eoa.js +27 -27
  26. package/dist/esm/logic/calls/eSIMWallet.calls.js +72 -0
  27. package/dist/esm/logic/constants.js +14 -1
  28. package/dist/esm/logic/deviceWallet.js +35 -1
  29. package/dist/esm/logic/deviceWalletFactory.js +11 -11
  30. package/dist/esm/logic/eSIMWallet.js +32 -0
  31. package/dist/esm/logic/eSIMWalletFactory.js +15 -3
  32. package/dist/esm/logic/errors.js +15 -9
  33. package/dist/esm/logic/paymentAdapter.js +8 -8
  34. package/dist/esm/logic/registry.js +17 -17
  35. package/dist/esm/logic/utils.js +1 -81
  36. package/dist/types/admin/config-admin.d.ts +4 -1
  37. package/dist/types/admin/interface/callsClass.d.ts +26 -0
  38. package/dist/types/config.d.ts +1 -1
  39. package/dist/types/interface/deviceWalletClass.d.ts +12 -0
  40. package/dist/types/interface/eSIMWalletClass.d.ts +14 -0
  41. package/dist/types/interface/eSIMWalletFactoryClass.d.ts +6 -0
  42. package/dist/types/interface/registryClass.d.ts +8 -0
  43. package/dist/types/interface/smartAccountClass.d.ts +10 -1
  44. package/dist/types/logic/account-kit/createSmartAccount.d.ts +1 -1
  45. package/dist/types/logic/calls/eSIMWallet.calls.d.ts +25 -0
  46. package/dist/types/logic/constants.d.ts +3 -0
  47. package/dist/types/logic/deviceWallet.d.ts +12 -0
  48. package/dist/types/logic/eSIMWallet.d.ts +16 -0
  49. package/dist/types/logic/eSIMWalletFactory.d.ts +2 -0
  50. package/dist/types/logic/errors.d.ts +6 -5
  51. package/dist/types/logic/utils.d.ts +0 -21
  52. package/dist/types/types.d.ts +1 -1
  53. package/package.json +21 -7
@@ -1,4 +1,4 @@
1
- import { _getChainSpecificConstants } from "./constants.js";
1
+ import { _chainId, _getChainSpecificConstants } from "./constants.js";
2
2
  import { PaymentAdapter } from "../abis/index.js";
3
3
  // Every function here is a view. The adapter's only writes reachable from a
4
4
  // userOp are `settle` (`onlyESIMWallet`, called from inside
@@ -10,7 +10,7 @@ import { PaymentAdapter } from "../abis/index.js";
10
10
  * The registry this adapter reads `vault()` and `isESIMWalletValid()` from.
11
11
  */
12
12
  export const _registry = async (client) => {
13
- const chainID = await client.getChainId();
13
+ const chainID = await _chainId(client);
14
14
  const rpcURL = client.transport.url;
15
15
  const values = _getChainSpecificConstants(chainID, rpcURL);
16
16
  return client.readContract({
@@ -22,7 +22,7 @@ export const _registry = async (client) => {
22
22
  };
23
23
  /** The ERC-20 registered under the `USDC` symbol at configure time. */
24
24
  export const _settlementToken = async (client) => {
25
- const chainID = await client.getChainId();
25
+ const chainID = await _chainId(client);
26
26
  const rpcURL = client.transport.url;
27
27
  const values = _getChainSpecificConstants(chainID, rpcURL);
28
28
  return client.readContract({
@@ -38,7 +38,7 @@ export const _settlementToken = async (client) => {
38
38
  * from "registered but withdrawn" (`allowed: false`).
39
39
  */
40
40
  export const _assets = async (client, symbol) => {
41
- const chainID = await client.getChainId();
41
+ const chainID = await _chainId(client);
42
42
  const rpcURL = client.transport.url;
43
43
  const values = _getChainSpecificConstants(chainID, rpcURL);
44
44
  const [allowed, isDollarUnit, decimals, token] = await client.readContract({
@@ -56,7 +56,7 @@ export const _assets = async (client, symbol) => {
56
56
  * purchase will revert with `AssetNotTransferable`.
57
57
  */
58
58
  export const _resolveAsset = async (client, symbol) => {
59
- const chainID = await client.getChainId();
59
+ const chainID = await _chainId(client);
60
60
  const rpcURL = client.transport.url;
61
61
  const values = _getChainSpecificConstants(chainID, rpcURL);
62
62
  return client.readContract({
@@ -74,7 +74,7 @@ export const _resolveAsset = async (client, symbol) => {
74
74
  * but the contract will not assume that on the caller's behalf.
75
75
  */
76
76
  export const _quote = async (client, symbol, priceUSDCents) => {
77
- const chainID = await client.getChainId();
77
+ const chainID = await _chainId(client);
78
78
  const rpcURL = client.transport.url;
79
79
  const values = _getChainSpecificConstants(chainID, rpcURL);
80
80
  return client.readContract({
@@ -92,7 +92,7 @@ export const _quote = async (client, symbol, priceUSDCents) => {
92
92
  * still reads the adapter's own record from before that move.
93
93
  */
94
94
  export const _usedReferences = async (client, paymentReference) => {
95
- const chainID = await client.getChainId();
95
+ const chainID = await _chainId(client);
96
96
  const rpcURL = client.transport.url;
97
97
  const values = _getChainSpecificConstants(chainID, rpcURL);
98
98
  return client.readContract({
@@ -104,7 +104,7 @@ export const _usedReferences = async (client, paymentReference) => {
104
104
  };
105
105
  /** The address holding upgrade authority over this adapter (its owner). */
106
106
  export const _upgradeManager = async (client) => {
107
- const chainID = await client.getChainId();
107
+ const chainID = await _chainId(client);
108
108
  const rpcURL = client.transport.url;
109
109
  const values = _getChainSpecificConstants(chainID, rpcURL);
110
110
  return client.readContract({
@@ -1,5 +1,5 @@
1
1
  import { encodeFunctionData } from "viem";
2
- import { _getChainSpecificConstants } from "./constants.js";
2
+ import { _chainId, _getChainSpecificConstants } from "./constants.js";
3
3
  import { Registry } from "../abis/index.js";
4
4
  import { MissingSmartWalletError } from "./errors.js";
5
5
  // A userOp from a device wallet arrives at the registry with msg.sender set to the
@@ -27,7 +27,7 @@ import { MissingSmartWalletError } from "./errors.js";
27
27
  export const _bindESIMWallet = async (client, eSIMWalletAddress) => {
28
28
  if (!client.account)
29
29
  throw new MissingSmartWalletError();
30
- const chainID = await client.getChainId();
30
+ const chainID = await _chainId(client);
31
31
  const rpcURL = client.transport.url;
32
32
  const values = _getChainSpecificConstants(chainID, rpcURL);
33
33
  return client.sendUserOperation({
@@ -53,7 +53,7 @@ export const _bindESIMWallet = async (client, eSIMWalletAddress) => {
53
53
  export const _toggleESIMWalletStandbyStatus = async (client, eSIMWalletAddress, isOnStandby) => {
54
54
  if (!client.account)
55
55
  throw new MissingSmartWalletError();
56
- const chainID = await client.getChainId();
56
+ const chainID = await _chainId(client);
57
57
  const rpcURL = client.transport.url;
58
58
  const values = _getChainSpecificConstants(chainID, rpcURL);
59
59
  return client.sendUserOperation({
@@ -75,7 +75,7 @@ export const _toggleESIMWalletStandbyStatus = async (client, eSIMWalletAddress,
75
75
  * deployed.
76
76
  */
77
77
  export const _isDeviceIdentifierAlreadyUsed = async (client, deviceUniqueIdentifier) => {
78
- const chainID = await client.getChainId();
78
+ const chainID = await _chainId(client);
79
79
  const rpcURL = client.transport.url;
80
80
  const values = _getChainSpecificConstants(chainID, rpcURL);
81
81
  // A `view` - read it directly instead of spending a userOp.
@@ -92,7 +92,7 @@ export const _isDeviceIdentifierAlreadyUsed = async (client, deviceUniqueIdentif
92
92
  * purchase.
93
93
  */
94
94
  export const _paused = async (client) => {
95
- const chainID = await client.getChainId();
95
+ const chainID = await _chainId(client);
96
96
  const rpcURL = client.transport.url;
97
97
  const values = _getChainSpecificConstants(chainID, rpcURL);
98
98
  return client.readContract({
@@ -108,7 +108,7 @@ export const _paused = async (client) => {
108
108
  * failure to carry the protocol's own revert reason.
109
109
  */
110
110
  export const _requireNotPaused = async (client) => {
111
- const chainID = await client.getChainId();
111
+ const chainID = await _chainId(client);
112
112
  const rpcURL = client.transport.url;
113
113
  const values = _getChainSpecificConstants(chainID, rpcURL);
114
114
  await client.readContract({
@@ -125,7 +125,7 @@ export const _requireNotPaused = async (client) => {
125
125
  * holds it now. Ask `deviceWallet.isValidESIMWallet` for that.
126
126
  */
127
127
  export const _isESIMWalletValid = async (client, eSIMWalletAddress) => {
128
- const chainID = await client.getChainId();
128
+ const chainID = await _chainId(client);
129
129
  const rpcURL = client.transport.url;
130
130
  const values = _getChainSpecificConstants(chainID, rpcURL);
131
131
  return client.readContract({
@@ -144,7 +144,7 @@ export const _isESIMWalletValid = async (client, eSIMWalletAddress) => {
144
144
  * association to still name the device wallet that raised the flag.
145
145
  */
146
146
  export const _isESIMWalletOnStandby = async (client, eSIMWalletAddress) => {
147
- const chainID = await client.getChainId();
147
+ const chainID = await _chainId(client);
148
148
  const rpcURL = client.transport.url;
149
149
  const values = _getChainSpecificConstants(chainID, rpcURL);
150
150
  return client.readContract({
@@ -156,7 +156,7 @@ export const _isESIMWalletOnStandby = async (client, eSIMWalletAddress) => {
156
156
  };
157
157
  /** Whether a device wallet is registered with the protocol. */
158
158
  export const _isDeviceWalletValid = async (client, deviceWalletAddress) => {
159
- const chainID = await client.getChainId();
159
+ const chainID = await _chainId(client);
160
160
  const rpcURL = client.transport.url;
161
161
  const values = _getChainSpecificConstants(chainID, rpcURL);
162
162
  return client.readContract({
@@ -168,7 +168,7 @@ export const _isDeviceWalletValid = async (client, deviceWalletAddress) => {
168
168
  };
169
169
  /** The device wallet registered for a device identifier, zero if none. */
170
170
  export const _uniqueIdentifierToDeviceWallet = async (client, deviceUniqueIdentifier) => {
171
- const chainID = await client.getChainId();
171
+ const chainID = await _chainId(client);
172
172
  const rpcURL = client.transport.url;
173
173
  const values = _getChainSpecificConstants(chainID, rpcURL);
174
174
  return client.readContract({
@@ -180,7 +180,7 @@ export const _uniqueIdentifierToDeviceWallet = async (client, deviceUniqueIdenti
180
180
  };
181
181
  /** Whether an eSIM identifier is already held by a wallet. */
182
182
  export const _isESIMIdentifierClaimed = async (client, eSIMUniqueIdentifier) => {
183
- const chainID = await client.getChainId();
183
+ const chainID = await _chainId(client);
184
184
  const rpcURL = client.transport.url;
185
185
  const values = _getChainSpecificConstants(chainID, rpcURL);
186
186
  return client.readContract({
@@ -196,7 +196,7 @@ export const _isESIMIdentifierClaimed = async (client, eSIMUniqueIdentifier) =>
196
196
  * belongs to the wallet rather than to whichever device is holding it.
197
197
  */
198
198
  export const _eSIMWalletForIdentifier = async (client, eSIMUniqueIdentifier) => {
199
- const chainID = await client.getChainId();
199
+ const chainID = await _chainId(client);
200
200
  const rpcURL = client.transport.url;
201
201
  const values = _getChainSpecificConstants(chainID, rpcURL);
202
202
  return client.readContract({
@@ -208,7 +208,7 @@ export const _eSIMWalletForIdentifier = async (client, eSIMUniqueIdentifier) =>
208
208
  };
209
209
  /** The fallback price ceiling in USD cents for a wallet holding no cap of its own. */
210
210
  export const _defaultPriceCapUSDCents = async (client) => {
211
- const chainID = await client.getChainId();
211
+ const chainID = await _chainId(client);
212
212
  const rpcURL = client.transport.url;
213
213
  const values = _getChainSpecificConstants(chainID, rpcURL);
214
214
  return client.readContract({
@@ -220,7 +220,7 @@ export const _defaultPriceCapUSDCents = async (client) => {
220
220
  };
221
221
  /** The payment adapter this registry currently points at. */
222
222
  export const _paymentAdapter = async (client) => {
223
- const chainID = await client.getChainId();
223
+ const chainID = await _chainId(client);
224
224
  const rpcURL = client.transport.url;
225
225
  const values = _getChainSpecificConstants(chainID, rpcURL);
226
226
  return client.readContract({
@@ -236,7 +236,7 @@ export const _paymentAdapter = async (client) => {
236
236
  * the contract keys `usedPaymentReferences` by, not the bare reference.
237
237
  */
238
238
  export const _usedPaymentReferences = async (client, scopedReference) => {
239
- const chainID = await client.getChainId();
239
+ const chainID = await _chainId(client);
240
240
  const rpcURL = client.transport.url;
241
241
  const values = _getChainSpecificConstants(chainID, rpcURL);
242
242
  return client.readContract({
@@ -252,7 +252,7 @@ export const _usedPaymentReferences = async (client, scopedReference) => {
252
252
  * calling it first only turns that revert into a typed error ahead of a userOp.
253
253
  */
254
254
  export const _requireLazyHistoryCopied = async (client, eSIMWallet) => {
255
- const chainID = await client.getChainId();
255
+ const chainID = await _chainId(client);
256
256
  const rpcURL = client.transport.url;
257
257
  const values = _getChainSpecificConstants(chainID, rpcURL);
258
258
  await client.readContract({
@@ -269,7 +269,7 @@ export const _requireLazyHistoryCopied = async (client, eSIMWallet) => {
269
269
  * all then refuse it.
270
270
  */
271
271
  export const _requireDeviceIdentifierNotReserved = async (client, deviceUniqueIdentifier) => {
272
- const chainID = await client.getChainId();
272
+ const chainID = await _chainId(client);
273
273
  const rpcURL = client.transport.url;
274
274
  const values = _getChainSpecificConstants(chainID, rpcURL);
275
275
  await client.readContract({
@@ -1,6 +1,4 @@
1
- import { isHex, toHex } from "viem";
2
- import { AsnParser } from "@peculiar/asn1-schema";
3
- import { ECDSASigValue } from "@peculiar/asn1-ecc";
1
+ import { isHex } from "viem";
4
2
  import { NullOrUndefinedValueError } from "./errors.js";
5
3
  export const _add0x = (data) => {
6
4
  if (!data) {
@@ -8,12 +6,6 @@ export const _add0x = (data) => {
8
6
  }
9
7
  return (data.indexOf('0x') !== -1) ? isHex(data) ? data : `0x${data}` : `0x${data}`;
10
8
  };
11
- export const _remove0x = (data) => {
12
- if (!data) {
13
- throw new NullOrUndefinedValueError();
14
- }
15
- return (data.indexOf('0x') !== -1) ? data.slice(2) : data;
16
- };
17
9
  export function _shouldRemoveLeadingZero(bytes) {
18
10
  return bytes[0] === 0x0 && (bytes[1] & (1 << 7)) !== 0;
19
11
  }
@@ -27,75 +19,3 @@ export function _concatUint8Arrays(arrays) {
27
19
  });
28
20
  return toReturn;
29
21
  }
30
- export function base64UrlToBuffer(base64url) {
31
- const base64 = base64url
32
- .replace(/-/g, "+")
33
- .replace(/_/g, "/")
34
- .padEnd((base64url.length + 3) & ~3, "=");
35
- return Buffer.from(base64, "base64");
36
- }
37
- export function decodeClientDataJSON(base64url) {
38
- const base64 = base64url
39
- .replace(/-/g, "+")
40
- .replace(/_/g, "/")
41
- .padEnd((base64url.length + 3) & ~3, "=");
42
- const jsonString = Buffer.from(base64, "base64").toString("utf-8");
43
- return JSON.parse(jsonString);
44
- }
45
- export function hexToArrayBuffer(hexString) {
46
- const cleanHex = hexString.startsWith("0x") ? hexString.slice(2) : hexString;
47
- const bytes = new Uint8Array(cleanHex.length / 2);
48
- for (let i = 0; i < bytes.length; i++) {
49
- bytes[i] = parseInt(cleanHex.substr(i * 2, 2), 16);
50
- }
51
- return bytes.buffer;
52
- }
53
- export function parseDEREncodedSignature(signature) {
54
- let offset = 0;
55
- if (signature[offset++] !== 0x30)
56
- throw new Error("Invalid DER sequence");
57
- // Sequence length byte. Skipped, because r and s each carry their own length.
58
- offset++;
59
- if (signature[offset++] !== 0x02)
60
- throw new Error("Expected integer for r");
61
- const rLen = signature[offset++];
62
- const r = signature.slice(offset, offset + rLen);
63
- offset += rLen;
64
- if (signature[offset++] !== 0x02)
65
- throw new Error("Expected integer for s");
66
- const sLen = signature[offset++];
67
- const s = signature.slice(offset, offset + sLen);
68
- return {
69
- r: Buffer.from(r).toString("hex"),
70
- s: Buffer.from(s).toString("hex"),
71
- };
72
- }
73
- export function shouldRemoveLeadingZero(bytes) {
74
- return bytes[0] === 0x0 && (bytes[1] & (1 << 7)) !== 0;
75
- }
76
- export function concatUint8Arrays(arrays) {
77
- let pointer = 0;
78
- const totalLength = arrays.reduce((prev, curr) => prev + curr.length, 0);
79
- const toReturn = new Uint8Array(totalLength);
80
- arrays.forEach((arr) => {
81
- toReturn.set(arr, pointer);
82
- pointer += arr.length;
83
- });
84
- return toReturn;
85
- }
86
- export function parseSignature(signature) {
87
- const parsedSignature = AsnParser.parse(signature, ECDSASigValue);
88
- let rBytes = new Uint8Array(parsedSignature.r);
89
- let sBytes = new Uint8Array(parsedSignature.s);
90
- if (shouldRemoveLeadingZero(rBytes)) {
91
- rBytes = rBytes.slice(1);
92
- }
93
- if (shouldRemoveLeadingZero(sBytes)) {
94
- sBytes = sBytes.slice(1);
95
- }
96
- const finalSignature = concatUint8Arrays([rBytes, sBytes]);
97
- return {
98
- r: toHex(finalSignature.slice(0, 32)),
99
- s: toHex(finalSignature.slice(32)),
100
- };
101
- }
@@ -8,7 +8,8 @@ import { AdminProtocolAdminSubPackage } from "./interface/protocolAdminClass.js"
8
8
  import { AdminDeviceWalletSubPackage } from "./interface/deviceWalletClass.js";
9
9
  import { AdminESIMWalletSubPackage } from "./interface/eSIMWalletClass.js";
10
10
  import { AdminPaymentAdapterSubPackage } from "./interface/paymentAdapterClass.js";
11
- export { KokioError, NullOrUndefinedValueError, MissingSmartWalletError, MissingEOAWalletError, InvalidClientError, UnsupportedChainError, UnconfiguredChainError, CounterfactualMismatchError, ContractRevertError, decodeContractRevert, } from "../logic/errors.js";
11
+ import { AdminCallsSubPackage } from "./interface/callsClass.js";
12
+ export { KokioError, NullOrUndefinedValueError, MissingSmartWalletError, MissingEOAWalletError, InvalidClientError, UnsupportedChainError, UnconfiguredChainError, CounterfactualMismatchError, BatchSizeOutOfRangeError, DepositOnResumeError, ESIMWalletNotLazyDeployedError, MissingBatchEventError, StalledBatchError, ContractRevertError, decodeContractRevert, } from "../logic/errors.js";
12
13
  export type { DecodedRevert } from "../logic/errors.js";
13
14
  export { OperationState } from "../logic/admin/reads/protocolAdmin.reads.js";
14
15
  /**
@@ -38,6 +39,8 @@ export declare class KokioAdmin {
38
39
  lazyWalletRegistry: AdminLazyWalletRegistrySubPackage;
39
40
  protocolAdmin: AdminProtocolAdminSubPackage;
40
41
  paymentAdapter: AdminPaymentAdapterSubPackage;
42
+ /** Calls for the app to sign as a user operation, built here so the backend holds the purchase logic. */
43
+ calls: AdminCallsSubPackage;
41
44
  deviceWallet?: AdminDeviceWalletSubPackage;
42
45
  eSIMWallet?: AdminESIMWalletSubPackage;
43
46
  constructor(walletClient: WalletClient, deviceWalletAddress?: Address, eSIMWalletAddress?: Address);
@@ -0,0 +1,26 @@
1
+ import { Address, Hex, WalletClient } from "viem";
2
+ import { DataBundleDetails } from "../../types.js";
3
+ /**
4
+ * Builds the calls a user's device wallet signs as one user operation. Nothing
5
+ * is signed or sent here: hand the result to the app, which passes it to
6
+ * `deviceWallet.sendUserOperation`. Addresses are passed per call, since one
7
+ * backend builds calls for many users.
8
+ */
9
+ export declare class AdminCallsSubPackage {
10
+ walletClient: WalletClient;
11
+ constructor(walletClient: WalletClient);
12
+ /**
13
+ * The calls `kokio.eSIMWallet.buyDataBundleWithTransfer` sends: a token
14
+ * transfer from the device wallet for whatever the eSIM wallet is short of,
15
+ * then the purchase. The purchase emits `DataBundleBoughtWithToken` as usual.
16
+ */
17
+ buyDataBundleWithTransfer(eSIMWalletAddress: Address, dataBundleDetails: DataBundleDetails, asset: Hex, maxAmountIn: bigint, paymentReference: Hex): Promise<import("../../types.js").Call[]>;
18
+ /**
19
+ * The calls `kokio.eSIMWallet.acceptAndBindESIMWallet` sends, for the device
20
+ * wallet named in `requestTransferOwnership` to sign. Build them once the
21
+ * `OwnershipTransferRequested` event names that device wallet as `_newOwner`.
22
+ */
23
+ acceptAndBindESIMWallet(eSIMWalletAddress: Address, newDeviceWalletAddress: Address, options?: {
24
+ grantAccessToFunds?: boolean;
25
+ }): import("../../types.js").Call[];
26
+ }
@@ -9,7 +9,7 @@ import { ESIMWalletSubPackage } from "./interface/eSIMWalletClass.js";
9
9
  import { ESIMWalletFactorySubPackage } from "./interface/eSIMWalletFactoryClass.js";
10
10
  import { PaymentAdapterSubPackage } from "./interface/paymentAdapterClass.js";
11
11
  import { KokioSmartAccountClient } from "./types.js";
12
- export { KokioError, NullOrUndefinedValueError, MissingSmartWalletError, MissingEOAWalletError, InvalidClientError, UnsupportedChainError, UnconfiguredChainError, CounterfactualMismatchError, ContractRevertError, decodeContractRevert, } from "./logic/errors.js";
12
+ export { KokioError, NullOrUndefinedValueError, MissingSmartWalletError, MissingEOAWalletError, InvalidClientError, UnsupportedChainError, UnconfiguredChainError, CounterfactualMismatchError, BatchSizeOutOfRangeError, DepositOnResumeError, ESIMWalletNotLazyDeployedError, MissingBatchEventError, StalledBatchError, ContractRevertError, decodeContractRevert, } from "./logic/errors.js";
13
13
  export type { DecodedRevert } from "./logic/errors.js";
14
14
  export declare class Kokio {
15
15
  viemWalletClient: WalletClient;
@@ -8,6 +8,18 @@ export declare class DeviceWalletSubPackage {
8
8
  sendUserOperation(calls: Call[]): Promise<`0x${string}`>;
9
9
  addDeposit(amount: bigint): Promise<`0x${string}`>;
10
10
  addESIMWallet(eSIMWalletAddress: Address): Promise<`0x${string}`>;
11
+ /**
12
+ * Deploy an eSIM wallet and bind it to this device wallet in one user
13
+ * operation, optionally granting it access to this wallet's tokens too.
14
+ * Resolves once the operation is sent, with its hash and the eSIM wallet's
15
+ * address.
16
+ */
17
+ deployAndBindESIMWallet(salt: bigint, options?: {
18
+ grantAccessToFunds?: boolean;
19
+ }): Promise<{
20
+ userOpHash: Hex;
21
+ eSIMWalletAddress: Address;
22
+ }>;
11
23
  getVaultAddress(): Promise<`0x${string}`>;
12
24
  removeESIMWallet(eSIMWalletAddress: Address, callBackETH: boolean): Promise<`0x${string}`>;
13
25
  toggleAccessToFunds(eSIMWalletAddress: Address, hasAccessToFunds: boolean): Promise<`0x${string}`>;
@@ -6,7 +6,21 @@ export declare class ESIMWalletSubPackage {
6
6
  address: `0x${string}`;
7
7
  constructor(client: KokioSmartAccountClient, address: Address);
8
8
  acceptOwnershipTransfer(): Promise<`0x${string}`>;
9
+ /**
10
+ * Accept this eSIM wallet's transfer and bind it to the signing device
11
+ * wallet in one user operation, optionally granting it access to that
12
+ * wallet's tokens too.
13
+ */
14
+ acceptAndBindESIMWallet(options?: {
15
+ grantAccessToFunds?: boolean;
16
+ }): Promise<`0x${string}`>;
9
17
  buyDataBundleWithToken(dataBundleDetails: DataBundleDetails, asset: Hex, maxAmountIn: bigint, paymentReference: Hex): Promise<`0x${string}`>;
18
+ /**
19
+ * Same purchase as `buyDataBundleWithToken`, with the device wallet sending
20
+ * the tokens it needs in the same user operation. Works without having granted
21
+ * this eSIM wallet access to the device wallet's funds.
22
+ */
23
+ buyDataBundleWithTransfer(dataBundleDetails: DataBundleDetails, asset: Hex, maxAmountIn: bigint, paymentReference: Hex): Promise<`0x${string}`>;
10
24
  priceCapUSDCents(): Promise<bigint>;
11
25
  deviceWallet(): Promise<`0x${string}`>;
12
26
  owner(): Promise<`0x${string}`>;
@@ -4,6 +4,12 @@ export declare class ESIMWalletFactorySubPackage {
4
4
  smartAccountClient: KokioSmartAccountClient;
5
5
  walletClient: WalletClient;
6
6
  constructor(walletClient: WalletClient, smartAccountClient: KokioSmartAccountClient);
7
+ /**
8
+ * @deprecated Deploys without binding, so the device wallet does not treat the
9
+ * new eSIM wallet as its own. Use `deviceWallet.deployAndBindESIMWallet`.
10
+ */
7
11
  deployESIMWalletWithUserOp(deviceWalletAddress: Address, salt: bigint): Promise<`0x${string}`>;
12
+ /** Address the eSIM wallet for this device wallet and salt deploys to. */
13
+ getCounterFactualAddress(deviceWalletAddress: Address, salt: bigint): Promise<`0x${string}`>;
8
14
  getCurrentESIMWalletImplementation(): Promise<`0x${string}`>;
9
15
  }
@@ -3,6 +3,14 @@ import { KokioSmartAccountClient } from "../types.js";
3
3
  export declare class RegistrySubPackage {
4
4
  client: KokioSmartAccountClient;
5
5
  constructor(client: KokioSmartAccountClient);
6
+ /**
7
+ * Record in the registry that this device wallet holds the eSIM wallet.
8
+ *
9
+ * Registry side only: the device wallet itself still does not treat the eSIM
10
+ * wallet as its own (`isValidESIMWallet` stays false, so it cannot manage it or
11
+ * grant it fund access). To take on an eSIM wallet use `deviceWallet.addESIMWallet`,
12
+ * which writes both sides.
13
+ */
6
14
  bindESIMWallet(eSIMWalletAddress: Address): Promise<`0x${string}`>;
7
15
  toggleESIMWalletStandbyStatus(eSIMWalletAddress: Address, isOnStandby: boolean): Promise<`0x${string}`>;
8
16
  isDeviceIdentifierAlreadyUsed(deviceUniqueIdentifier: string): Promise<boolean>;
@@ -8,5 +8,14 @@ export declare class SmartAccountSubPackage {
8
8
  gasPolicyId: string;
9
9
  constructor(client: WalletClient, credentialId: string, rpId: string, pimlicoAPIKey: string, gasPolicyId: string);
10
10
  getSmartWallet(deviceUniqueIdentifier: string, deviceWalletOwnerKey: P256Key, salt: bigint): Promise<KokioSmartAccount>;
11
- getSmartWalletClient(account: KokioSmartAccount): Promise<KokioSmartAccountClient>;
11
+ /**
12
+ * Client that sends the account's user operations through a bundler, with
13
+ * gas sponsored by the paymaster at the same endpoint.
14
+ *
15
+ * @param options.bundlerUrl Bundler and ERC-7677 paymaster endpoint. Defaults to
16
+ * Pimlico for the wallet client's chain, keyed by the API key given to `Kokio`.
17
+ */
18
+ getSmartWalletClient(account: KokioSmartAccount, options?: {
19
+ bundlerUrl?: string;
20
+ }): Promise<KokioSmartAccountClient>;
12
21
  }
@@ -63,5 +63,5 @@ type RawGasEstimate = Record<string, Hex>;
63
63
  * override placed on the client is never the one it calls.
64
64
  */
65
65
  export declare const _padGasEstimate: (estimate: RawGasEstimate) => RawGasEstimate;
66
- export declare const _getSmartWalletClient: (client: WalletClient, pimlicoAPIKey: string, gasPolicyId: string, account: KokioSmartAccount) => Promise<KokioSmartAccountClient>;
66
+ export declare const _getSmartWalletClient: (client: WalletClient, pimlicoAPIKey: string, gasPolicyId: string, account: KokioSmartAccount, bundlerUrl?: string) => Promise<KokioSmartAccountClient>;
67
67
  export {};
@@ -0,0 +1,25 @@
1
+ import { Address, Client, Hex, PublicActions } from "viem";
2
+ import { Call, DataBundleDetails } from "../../types.js";
3
+ /** Any client that can read contracts: the mobile smart account client, or a wallet client extended with `publicActions`. */
4
+ export type CallBuilderClient = Pick<PublicActions, "readContract" | "getChainId"> & Pick<Client, "transport">;
5
+ /**
6
+ * The calls for buying a data bundle with tokens the device wallet sends over
7
+ * in the same user operation, so the eSIM wallet needs no access to the device
8
+ * wallet's funds.
9
+ *
10
+ * Only the shortfall is sent: the quote for the bundle minus what the eSIM
11
+ * wallet already holds of `asset`, worked out when this runs. If that balance
12
+ * or the quote changes before the operation lands, it reverts, so build the
13
+ * calls again rather than resending old ones.
14
+ */
15
+ export declare const _buyDataBundleWithTransferCalls: (client: CallBuilderClient, eSIMWalletAddress: Address, dataBundleDetails: DataBundleDetails, asset: Hex, maxAmountIn: bigint, paymentReference: Hex) => Promise<Call[]>;
16
+ /**
17
+ * The calls for the new device wallet to take over an eSIM wallet another
18
+ * device wallet asked to hand it: accept the transfer, then bind it, which also
19
+ * tells the registry and clears the standby flag.
20
+ *
21
+ * Accepting first is what lets the bind through: it makes this device wallet
22
+ * the owner and clears the pending transfer. Fund access cannot be granted at
23
+ * bind time, so `grantAccessToFunds` adds a `toggleAccessToFunds` after it.
24
+ */
25
+ export declare const _acceptAndBindESIMWalletCalls: (eSIMWalletAddress: Address, deviceWalletAddress: Address, grantAccessToFunds: boolean) => Call[];
@@ -18,5 +18,8 @@ export interface chainSpecifcConstants {
18
18
  export declare const baseMainnetFactoryAddresses: Record<string, Address>;
19
19
  export declare const baseSepoliaFactoryAddresses: Record<string, Address>;
20
20
  export declare const customErrors: Record<string, string>;
21
+ export declare const _chainId: (client: {
22
+ getChainId: () => Promise<number>;
23
+ }) => Promise<number>;
21
24
  export declare const _extractChainID: (client: WalletClient) => Promise<number>;
22
25
  export declare const _getChainSpecificConstants: (chainID: CHAIN_ID.BASE_MAINNET | CHAIN_ID.BASE_SEPOLIA, rpcURL: string, pimlicoAPIKey?: string) => chainSpecifcConstants;
@@ -19,6 +19,18 @@ export declare const _toggleAccessToFunds: (client: KokioSmartAccountClient, add
19
19
  * a bind from undoing the owner's revocation.
20
20
  */
21
21
  export declare const _addESIMWallet: (client: KokioSmartAccountClient, address: Address, eSIMWalletAddress: Address) => Promise<`0x${string}`>;
22
+ /**
23
+ * Deploy an eSIM wallet for this device wallet and bind it, in one user operation.
24
+ *
25
+ * Fund access cannot be granted at bind time, so `grantAccessToFunds` adds a
26
+ * `toggleAccessToFunds` after the bind in the same operation. The device wallet
27
+ * must already be registered (`registry.isDeviceWalletValid`), or the factory
28
+ * refuses it.
29
+ */
30
+ export declare const _deployAndBindESIMWallet: (client: KokioSmartAccountClient, address: Address, salt: bigint, grantAccessToFunds: boolean) => Promise<{
31
+ userOpHash: Hex;
32
+ eSIMWalletAddress: Address;
33
+ }>;
22
34
  /**
23
35
  * Release an eSIM wallet and put it on standby for a transfer.
24
36
  *
@@ -21,6 +21,15 @@ export declare const _setPriceCapUSDCents: (client: KokioSmartAccountClient, add
21
21
  * inventing one.
22
22
  */
23
23
  export declare const _buyDataBundleWithToken: (client: KokioSmartAccountClient, address: Address, dataBundleDetails: DataBundleDetails, asset: Hex, maxAmountIn: bigint, paymentReference: Hex) => Promise<`0x${string}`>;
24
+ /**
25
+ * Buy a data bundle with tokens the device wallet sends over in the same user
26
+ * operation, so the eSIM wallet needs no access to the device wallet's funds.
27
+ *
28
+ * Only the shortfall is sent: the quote for the bundle minus what this eSIM
29
+ * wallet already holds of `asset`. Arguments are as for `buyDataBundleWithToken`.
30
+ * The backend builds the same calls with `admin.calls.buyDataBundleWithTransfer`.
31
+ */
32
+ export declare const _buyDataBundleWithTransfer: (client: KokioSmartAccountClient, address: Address, dataBundleDetails: DataBundleDetails, asset: Hex, maxAmountIn: bigint, paymentReference: Hex) => Promise<`0x${string}`>;
24
33
  /**
25
34
  * Send an ERC-20 held by this eSIM wallet back to its owning device wallet.
26
35
  * `onlyDeviceWallet`.
@@ -61,4 +70,11 @@ export declare const _deviceWallet: (client: KokioSmartAccountClient, address: A
61
70
  export declare const _transactionHistory: (client: KokioSmartAccountClient, address: Address, index: bigint) => Promise<DataBundleDetails>;
62
71
  export declare const _requestTransferOwnership: (client: KokioSmartAccountClient, address: Address, newOwner: Address) => Promise<`0x${string}`>;
63
72
  export declare const _acceptOwnershipTransfer: (client: KokioSmartAccountClient, address: Address) => Promise<`0x${string}`>;
73
+ /**
74
+ * Accept an eSIM wallet another device wallet asked to hand over, and bind it,
75
+ * in one user operation. `grantAccessToFunds` also lets it pull this device
76
+ * wallet's tokens. The backend builds the same calls with
77
+ * `admin.calls.acceptAndBindESIMWallet`.
78
+ */
79
+ export declare const _acceptAndBindESIMWallet: (client: KokioSmartAccountClient, address: Address, grantAccessToFunds: boolean) => Promise<`0x${string}`>;
64
80
  export declare const _sendETHToDeviceWallet: (client: KokioSmartAccountClient, address: Address, amount: bigint) => Promise<`0x${string}`>;
@@ -1,4 +1,6 @@
1
1
  import { Address } from "viem";
2
2
  import { KokioSmartAccountClient } from "../types.js";
3
3
  export declare const _deployESIMWalletWithUserOp: (client: KokioSmartAccountClient, deviceWalletAddress: Address, salt: bigint) => Promise<`0x${string}`>;
4
+ /** Address `deployESIMWallet` deploys to for this device wallet and salt. */
5
+ export declare const _getESIMWalletCounterFactualAddress: (client: KokioSmartAccountClient, deviceWalletAddress: Address, salt: bigint) => Promise<Address>;
4
6
  export declare const _getCurrentESIMWalletImplementation: (client: KokioSmartAccountClient) => Promise<Address>;
@@ -107,14 +107,15 @@ export declare class ContractRevertError extends KokioError {
107
107
  constructor(data: Hex);
108
108
  }
109
109
  /**
110
- * Pulls a ContractRevertError out of an error thrown by viem, or `null` if it
111
- * isn't a revert viem could decode a selector for.
110
+ * Pulls a ContractRevertError out of an error thrown by viem, or `null` when
111
+ * the error carries no revert data (a network failure, a rejected signature).
112
112
  */
113
113
  export declare const toContractRevertError: (err: unknown) => ContractRevertError | null;
114
114
  /**
115
- * `client.writeContract`, but a recognised on-chain revert comes back as a
116
- * ContractRevertError instead of viem's raw error chain. Anything else -
117
- * network failures, an unrecognised revert selector - is rethrown as-is.
115
+ * `client.writeContract`, but a revert comes back as a ContractRevertError
116
+ * instead of viem's raw error chain. Its `decoded` is null when the selector
117
+ * belongs to none of the Kokio contracts. Anything that is not a revert, such
118
+ * as a network failure, is rethrown as-is.
118
119
  *
119
120
  * Mirrors `WalletClient["writeContract"]`'s own generics rather than reading
120
121
  * them off `Parameters<...>`, since that would collapse the per-call overload
@@ -1,25 +1,4 @@
1
1
  import { Hex } from "viem";
2
2
  export declare const _add0x: (data: Hex | string) => Hex;
3
- export declare const _remove0x: (data: Hex | string) => string;
4
3
  export declare function _shouldRemoveLeadingZero(bytes: Uint8Array): boolean;
5
4
  export declare function _concatUint8Arrays(arrays: Uint8Array[]): Uint8Array;
6
- export declare function base64UrlToBuffer(base64url: string): Buffer;
7
- export interface ClientDataJSON {
8
- type: string;
9
- challenge: string;
10
- origin: string;
11
- crossOrigin?: boolean;
12
- [key: string]: unknown;
13
- }
14
- export declare function decodeClientDataJSON(base64url: string): ClientDataJSON;
15
- export declare function hexToArrayBuffer(hexString: string): ArrayBuffer;
16
- export declare function parseDEREncodedSignature(signature: Uint8Array): {
17
- r: string;
18
- s: string;
19
- };
20
- export declare function shouldRemoveLeadingZero(bytes: Uint8Array): boolean;
21
- export declare function concatUint8Arrays(arrays: Uint8Array[]): Uint8Array;
22
- export declare function parseSignature(signature: Uint8Array): {
23
- r: `0x${string}`;
24
- s: `0x${string}`;
25
- };
@@ -20,7 +20,7 @@ export type OwnerCall = {
20
20
  abi: Abi;
21
21
  functionName: string;
22
22
  args?: readonly unknown[];
23
- /** ETH sent with the call. The timelock has to be holding it. */
23
+ /** ETH sent with the call. `executor.execute` attaches it from the executing account. */
24
24
  value?: bigint;
25
25
  };
26
26
  /**