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.
Files changed (81) hide show
  1. package/README.md +21 -7
  2. package/dist/esm/abis/DeviceWallet.js +60 -59
  3. package/dist/esm/abis/ESIMWallet.js +263 -58
  4. package/dist/esm/abis/ESIMWalletFactory.js +2 -2
  5. package/dist/esm/abis/LazyWalletRegistry.js +68 -24
  6. package/dist/esm/abis/PaymentAdapter.js +861 -0
  7. package/dist/esm/abis/Registry.js +294 -18
  8. package/dist/esm/abis/RegistryHelper.js +101 -9
  9. package/dist/esm/abis/index.js +2 -1
  10. package/dist/esm/admin/config-admin.js +4 -0
  11. package/dist/esm/admin/interface/deviceWalletClass.js +3 -3
  12. package/dist/esm/admin/interface/eSIMWalletClass.js +6 -6
  13. package/dist/esm/admin/interface/lazyWalletRegistryClass.js +4 -1
  14. package/dist/esm/admin/interface/paymentAdapterClass.js +54 -0
  15. package/dist/esm/admin/interface/protocolAdminClass.js +6 -3
  16. package/dist/esm/admin/interface/registryClass.js +15 -6
  17. package/dist/esm/config.js +3 -0
  18. package/dist/esm/interface/deviceWalletClass.js +5 -5
  19. package/dist/esm/interface/eSIMWalletClass.js +10 -7
  20. package/dist/esm/interface/paymentAdapterClass.js +28 -0
  21. package/dist/esm/interface/registryClass.js +12 -3
  22. package/dist/esm/logic/admin/deviceWallet.eoa.js +3 -3
  23. package/dist/esm/logic/admin/deviceWalletFactory.eoa.js +6 -6
  24. package/dist/esm/logic/admin/eSIMWallet.eoa.js +14 -12
  25. package/dist/esm/logic/admin/eSIMWalletFactory.eoa.js +4 -4
  26. package/dist/esm/logic/admin/lazyWalletRegistry.eoa.js +7 -7
  27. package/dist/esm/logic/admin/paymentAdapter.eoa.js +123 -0
  28. package/dist/esm/logic/admin/protocolAdmin.eoa.js +34 -16
  29. package/dist/esm/logic/admin/reads/deviceWallet.reads.js +2 -2
  30. package/dist/esm/logic/admin/reads/eSIMWallet.reads.js +8 -7
  31. package/dist/esm/logic/admin/reads/lazyWalletRegistry.reads.js +19 -2
  32. package/dist/esm/logic/admin/reads/paymentAdapter.reads.js +106 -0
  33. package/dist/esm/logic/admin/reads/registry.reads.js +34 -6
  34. package/dist/esm/logic/admin/registry.eoa.js +44 -20
  35. package/dist/esm/logic/constants.js +17 -87
  36. package/dist/esm/logic/deviceWallet.js +11 -11
  37. package/dist/esm/logic/eSIMWallet.js +51 -22
  38. package/dist/esm/logic/errors.js +30 -1
  39. package/dist/esm/logic/paymentAdapter.js +116 -0
  40. package/dist/esm/logic/registry.js +50 -5
  41. package/dist/esm/types-export.js +1 -1
  42. package/dist/esm/types.js +11 -1
  43. package/dist/types/abis/DeviceWallet.d.ts +50 -49
  44. package/dist/types/abis/ESIMWallet.d.ts +215 -55
  45. package/dist/types/abis/ESIMWalletFactory.d.ts +2 -2
  46. package/dist/types/abis/LazyWalletRegistry.d.ts +58 -24
  47. package/dist/types/abis/PaymentAdapter.d.ts +661 -0
  48. package/dist/types/abis/Registry.d.ts +233 -18
  49. package/dist/types/abis/RegistryHelper.d.ts +83 -9
  50. package/dist/types/abis/index.d.ts +2 -1
  51. package/dist/types/admin/config-admin.d.ts +2 -0
  52. package/dist/types/admin/interface/deviceWalletClass.d.ts +1 -1
  53. package/dist/types/admin/interface/eSIMWalletClass.d.ts +3 -3
  54. package/dist/types/admin/interface/lazyWalletRegistryClass.d.ts +1 -0
  55. package/dist/types/admin/interface/paymentAdapterClass.d.ts +20 -0
  56. package/dist/types/admin/interface/protocolAdminClass.d.ts +2 -1
  57. package/dist/types/admin/interface/registryClass.d.ts +6 -2
  58. package/dist/types/config.d.ts +2 -0
  59. package/dist/types/interface/constantsClass.d.ts +2 -2
  60. package/dist/types/interface/deviceWalletClass.d.ts +2 -2
  61. package/dist/types/interface/eSIMWalletClass.d.ts +5 -4
  62. package/dist/types/interface/paymentAdapterClass.d.ts +13 -0
  63. package/dist/types/interface/registryClass.d.ts +5 -2
  64. package/dist/types/logic/admin/eSIMWallet.eoa.d.ts +9 -6
  65. package/dist/types/logic/admin/paymentAdapter.eoa.d.ts +28 -0
  66. package/dist/types/logic/admin/protocolAdmin.eoa.d.ts +12 -2
  67. package/dist/types/logic/admin/reads/deviceWallet.reads.d.ts +1 -1
  68. package/dist/types/logic/admin/reads/eSIMWallet.reads.d.ts +5 -4
  69. package/dist/types/logic/admin/reads/lazyWalletRegistry.reads.d.ts +7 -0
  70. package/dist/types/logic/admin/reads/paymentAdapter.reads.d.ts +30 -0
  71. package/dist/types/logic/admin/reads/registry.reads.d.ts +13 -5
  72. package/dist/types/logic/admin/registry.eoa.d.ts +18 -8
  73. package/dist/types/logic/constants.d.ts +5 -17
  74. package/dist/types/logic/deviceWallet.d.ts +7 -7
  75. package/dist/types/logic/eSIMWallet.d.ts +29 -15
  76. package/dist/types/logic/errors.d.ts +16 -1
  77. package/dist/types/logic/paymentAdapter.d.ts +40 -0
  78. package/dist/types/logic/registry.d.ts +20 -5
  79. package/dist/types/types-export.d.ts +2 -1
  80. package/dist/types/types.d.ts +20 -2
  81. package/package.json +1 -1
@@ -1,4 +1,4 @@
1
- import { Address } from "viem";
1
+ import { Address, Hex } from "viem";
2
2
  import { DataBundleDetails } from "../types";
3
3
  import { KokioSmartAccountClient } from "../types.js";
4
4
  export declare class ESIMWalletSubPackage {
@@ -6,12 +6,13 @@ export declare class ESIMWalletSubPackage {
6
6
  address: `0x${string}`;
7
7
  constructor(client: KokioSmartAccountClient, address: Address);
8
8
  acceptOwnershipTransfer(): Promise<`0x${string}`>;
9
- buyDataBundle(dataBundleDetails: DataBundleDetails): Promise<`0x${string}`>;
10
- dataBundlePriceCap(): Promise<bigint>;
9
+ buyDataBundleWithToken(dataBundleDetails: DataBundleDetails, asset: Hex, maxAmountIn: bigint, paymentReference: Hex): Promise<`0x${string}`>;
10
+ priceCapUSDCents(): Promise<bigint>;
11
11
  deviceWallet(): Promise<`0x${string}`>;
12
12
  owner(): Promise<`0x${string}`>;
13
13
  requestTransferOwnership(newOwner: Address): Promise<`0x${string}`>;
14
14
  sendETHToDeviceWallet(amount: bigint): Promise<`0x${string}`>;
15
- setDataBundlePriceCap(cap: bigint): Promise<`0x${string}`>;
15
+ sendTokenToDeviceWallet(token: Address, amount: bigint): Promise<`0x${string}`>;
16
+ setPriceCapUSDCents(cap: bigint): Promise<`0x${string}`>;
16
17
  transactionHistory(index: bigint): Promise<DataBundleDetails>;
17
18
  }
@@ -0,0 +1,13 @@
1
+ import { Hex } from "viem";
2
+ import { KokioSmartAccountClient } from "../types.js";
3
+ export declare class PaymentAdapterSubPackage {
4
+ client: KokioSmartAccountClient;
5
+ constructor(client: KokioSmartAccountClient);
6
+ registry(): Promise<`0x${string}`>;
7
+ settlementToken(): Promise<`0x${string}`>;
8
+ assets(symbol: Hex): Promise<import("../types.js").Asset>;
9
+ resolveAsset(symbol: Hex): Promise<import("../types.js").Asset>;
10
+ quote(symbol: Hex, priceUSDCents: bigint): Promise<bigint>;
11
+ usedReferences(paymentReference: Hex): Promise<boolean>;
12
+ upgradeManager(): Promise<`0x${string}`>;
13
+ }
@@ -1,4 +1,4 @@
1
- import { Address } from "viem";
1
+ import { Address, Hex } from "viem";
2
2
  import { KokioSmartAccountClient } from "../types.js";
3
3
  export declare class RegistrySubPackage {
4
4
  client: KokioSmartAccountClient;
@@ -14,6 +14,9 @@ export declare class RegistrySubPackage {
14
14
  uniqueIdentifierToDeviceWallet(deviceUniqueIdentifier: string): Promise<`0x${string}`>;
15
15
  isESIMIdentifierClaimed(eSIMUniqueIdentifier: string): Promise<boolean>;
16
16
  eSIMWalletForIdentifier(eSIMUniqueIdentifier: string): Promise<`0x${string}`>;
17
- defaultDataBundlePriceCap(): Promise<bigint>;
17
+ defaultPriceCapUSDCents(): Promise<bigint>;
18
+ paymentAdapter(): Promise<`0x${string}`>;
19
+ usedPaymentReferences(scopedReference: Hex): Promise<boolean>;
20
+ requireLazyHistoryCopied(eSIMWallet: Address): Promise<void>;
18
21
  requireDeviceIdentifierNotReserved(deviceUniqueIdentifier: string): Promise<void>;
19
22
  }
@@ -1,9 +1,12 @@
1
- import { Address, WalletClient } from "viem";
1
+ import { Address, Hex, WalletClient } from "viem";
2
2
  import { DataBundleDetails } from "../../types.js";
3
3
  /**
4
- * Buy a data bundle for an eSIM wallet. `onlyDeviceWalletOrESIMWalletAdmin`,
5
- * `payable`. `value` is optional: the contract pulls any shortfall from the
6
- * device wallet's balance, so an admin can pass `0n` when the wallet is funded,
7
- * or forward `dataBundlePrice` to pay directly.
4
+ * Buy a data bundle in `asset`, an ERC-20 the payment adapter accepts.
5
+ * `onlyDeviceWalletOrESIMWalletAdmin`.
6
+ *
7
+ * `maxAmountIn` is the most of `asset` the buyer will spend, in its smallest
8
+ * unit - read it from `paymentAdapter.quote(asset, dataBundleDetails.priceUSDCents)`
9
+ * first. `paymentReference` ties this purchase to its offchain order and is
10
+ * spendable once per eSIM wallet.
8
11
  */
9
- export declare const _buyDataBundle: (client: WalletClient, eSIMWalletAddress: Address, dataBundleDetails: DataBundleDetails, value?: bigint) => Promise<`0x${string}`>;
12
+ export declare const _buyDataBundleWithToken: (client: WalletClient, eSIMWalletAddress: Address, dataBundleDetails: DataBundleDetails, asset: Hex, maxAmountIn: bigint, paymentReference: Hex) => Promise<`0x${string}`>;
@@ -0,0 +1,28 @@
1
+ import { Address, Hex, WalletClient } from "viem";
2
+ import type { Asset, OwnerCall } from "../../types.js";
3
+ /** Add a currency the adapter has never seen. Reverts if `_symbol` is already registered. Owner only. */
4
+ export declare const _registerAsset: (client: WalletClient, symbol: Hex, asset: Asset) => Promise<`0x${string}`>;
5
+ /** Change a currency already in the table (its decimals, token, or allowed flag). Owner only. */
6
+ export declare const _updateAsset: (client: WalletClient, symbol: Hex, asset: Asset) => Promise<`0x${string}`>;
7
+ /** Add or change a currency, scheduled through the timelock. Pass the result to `schedule`. */
8
+ export declare const _registerAssetCall: (client: WalletClient, symbol: Hex, asset: Asset) => Promise<OwnerCall>;
9
+ /** Change a currency already in the table, scheduled through the timelock. Pass the result to `schedule`. */
10
+ export declare const _updateAssetCall: (client: WalletClient, symbol: Hex, asset: Asset) => Promise<OwnerCall>;
11
+ /**
12
+ * Offer ownership to a new address. Pass the result to `schedule`.
13
+ *
14
+ * Ownable2Step, so the offer changes nothing until the named address calls
15
+ * `acceptOwnership`.
16
+ */
17
+ export declare const _transferOwnershipCall: (client: WalletClient, newOwner: Address) => Promise<OwnerCall>;
18
+ /** Point the adapter's proxy at a new implementation. Builds `upgradeToAndCall`. Pass the result to `schedule`. */
19
+ export declare const _upgradeCall: (client: WalletClient, newImplementation: Address, data?: Hex) => Promise<OwnerCall>;
20
+ /**
21
+ * Take ownership after a `transferOwnership` named this client. `msg.sender`
22
+ * must equal `pendingOwner`, so the `client` is the incoming owner.
23
+ *
24
+ * Where the incoming owner is the timelock, use
25
+ * `protocolAdmin.acceptOwnershipBatch` instead, which accepts for every
26
+ * contract at once.
27
+ */
28
+ export declare const _acceptOwnership: (client: WalletClient) => Promise<`0x${string}`>;
@@ -130,14 +130,24 @@ export declare const _disableAndNominateCall: (client: WalletClient, target: Add
130
130
  */
131
131
  export declare const _unpauseCall: (client: WalletClient, target?: Address) => Promise<OwnerCall>;
132
132
  /**
133
- * Set the fallback data bundle price ceiling. Pass the result to `schedule`.
133
+ * Set the fallback price ceiling, in USD cents. Pass the result to `schedule`.
134
134
  *
135
135
  * Zero reverts on execution, not on scheduling, so a zero here costs the whole
136
136
  * delay before it fails.
137
137
  *
138
138
  * `target` defaults to the registry.
139
139
  */
140
- export declare const _setDefaultDataBundlePriceCapCall: (client: WalletClient, cap: bigint, target?: Address) => Promise<OwnerCall>;
140
+ export declare const _setDefaultPriceCapUSDCentsCall: (client: WalletClient, cap: bigint, target?: Address) => Promise<OwnerCall>;
141
+ /**
142
+ * Point the registry at a new payment adapter. Pass the result to `schedule`.
143
+ *
144
+ * Owner only, deliberately not the admin: the adapter holds the spent payment
145
+ * references, so an admin that could swap it would get an empty set back and
146
+ * could record every purchase a second time.
147
+ *
148
+ * `target` defaults to the registry.
149
+ */
150
+ export declare const _setPaymentAdapterCall: (client: WalletClient, paymentAdapter: Address, target?: Address) => Promise<OwnerCall>;
141
151
  /**
142
152
  * Suspend a contract's admin key on the owner's route. Pass the result to
143
153
  * `schedule`.
@@ -5,7 +5,7 @@ export declare const _deviceUniqueIdentifier: (client: WalletClient, deviceWalle
5
5
  /** Whether an eSIM wallet is a valid child of this device wallet. */
6
6
  export declare const _isValidESIMWallet: (client: WalletClient, deviceWalletAddress: Address, eSIMWallet: Address) => Promise<boolean>;
7
7
  /** Whether an eSIM wallet is allowed to pull ETH from this device wallet. */
8
- export declare const _canPullETH: (client: WalletClient, deviceWalletAddress: Address, eSIMWallet: Address) => Promise<boolean>;
8
+ export declare const _canPullFunds: (client: WalletClient, deviceWalletAddress: Address, eSIMWallet: Address) => Promise<boolean>;
9
9
  /** The vault address this device wallet pays eSIM purchases to. */
10
10
  export declare const _getVaultAddress: (client: WalletClient, deviceWalletAddress: Address) => Promise<Address>;
11
11
  /**
@@ -8,9 +8,9 @@ export declare const _eSIMUniqueIdentifier: (client: WalletClient, eSIMWalletAdd
8
8
  * This wallet's own price ceiling in wei. Zero means it follows the registry's
9
9
  * `defaultDataBundlePriceCap` instead, which is the state a fresh wallet and a
10
10
  * newly handed-over wallet both start in. Worth reading before naming a price on
11
- * `buyDataBundle`, since a price over the ceiling reverts.
11
+ * `buyDataBundleWithToken`, since a price over the ceiling reverts.
12
12
  */
13
- export declare const _dataBundlePriceCap: (client: WalletClient, eSIMWalletAddress: Address) => Promise<bigint>;
13
+ export declare const _priceCapUSDCents: (client: WalletClient, eSIMWalletAddress: Address) => Promise<bigint>;
14
14
  /** The pending owner proposed via `requestTransferOwnership` (zero if none). */
15
15
  export declare const _newRequestedOwner: (client: WalletClient, eSIMWalletAddress: Address) => Promise<Address>;
16
16
  /** The current owner (device wallet) of this eSIM wallet. */
@@ -28,7 +28,8 @@ export declare const _deviceWallet: (client: WalletClient, eSIMWalletAddress: Ad
28
28
  *
29
29
  * The contract publishes no length getter, so there is no way to ask how many
30
30
  * entries exist. Read upwards from zero until a call reverts, or track the count
31
- * from the `DataBundleBought` and `TransactionHistoryPopulated` events, whose
32
- * `_totalEntries` is the length after the batch landed.
31
+ * from the `DataBundleBoughtWithToken`, `DataBundleSettlementRecorded` and
32
+ * `TransactionHistoryPopulated` events, whose `_totalEntries` is the length
33
+ * after the batch landed.
33
34
  */
34
35
  export declare const _transactionHistory: (client: WalletClient, eSIMWalletAddress: Address, index: bigint) => Promise<DataBundleDetails>;
@@ -25,6 +25,13 @@ export declare const _lazyDeploymentSalt: (client: WalletClient, deviceIdentifie
25
25
  export declare const _lazyDeployedESIMWallet: (client: WalletClient, eSIMIdentifier: string) => Promise<`0x${string}`>;
26
26
  /** How many of an eSIM's stored purchase entries have already reached its wallet. */
27
27
  export declare const _historyEntriesCopied: (client: WalletClient, eSIMIdentifier: string) => Promise<bigint>;
28
+ /**
29
+ * History entries still waiting to be copied in for this eSIM. A wallet's own
30
+ * purchase paths (`buyDataBundleWithToken`, `recordSettledPurchase`) refuse a
31
+ * new entry while this is non-zero, since it would land ahead of history that
32
+ * has not arrived yet.
33
+ */
34
+ export declare const _outstandingHistoryEntries: (client: WalletClient, eSIMIdentifier: string) => Promise<bigint>;
28
35
  /** Whether a device identifier has purchases recorded against it here. */
29
36
  export declare const _isDeviceIdentifierReserved: (client: WalletClient, deviceIdentifier: string) => Promise<boolean>;
30
37
  /** Whether an eSIM identifier is bound to a device here. */
@@ -0,0 +1,30 @@
1
+ import { Address, Hex, WalletClient } from "viem";
2
+ import { Asset } from "../../../types.js";
3
+ /** The registry this adapter reads `vault()` and `isESIMWalletValid()` from. */
4
+ export declare const _registry: (client: WalletClient) => Promise<Address>;
5
+ /** The ERC-20 registered under the `USDC` symbol at configure time. */
6
+ export declare const _settlementToken: (client: WalletClient) => Promise<Address>;
7
+ /**
8
+ * The raw currency table entry for a symbol. `decimals` reads zero for a symbol
9
+ * never registered, which is how `resolveAsset` tells "not registered" apart
10
+ * from "registered but withdrawn" (`allowed: false`).
11
+ */
12
+ export declare const _assets: (client: WalletClient, symbol: Hex) => Promise<Asset>;
13
+ /** A currency's full entry, reverting if the symbol was never registered. */
14
+ export declare const _resolveAsset: (client: WalletClient, symbol: Hex) => Promise<Asset>;
15
+ /**
16
+ * The amount of `symbol`, in its smallest unit, that a `priceUSDCents` charge
17
+ * currently costs. Worth reading before `recordSettledPurchase`, to size
18
+ * `_tokenAmount` for the backend's own settlement record.
19
+ */
20
+ export declare const _quote: (client: WalletClient, symbol: Hex, priceUSDCents: bigint) => Promise<bigint>;
21
+ /**
22
+ * Whether a payment reference has already been spent here. Retired from the
23
+ * registry's live purchase paths (`PaymentAdapter.consumePaymentReference` is
24
+ * `onlyRegistry` but nothing calls it any more): replay protection now lives on
25
+ * `Registry.usedPaymentReferences`, scoped per eSIM wallet. Kept for whatever
26
+ * still reads the adapter's own record from before that move.
27
+ */
28
+ export declare const _usedReferences: (client: WalletClient, paymentReference: Hex) => Promise<boolean>;
29
+ /** The address holding upgrade authority over this adapter (its owner). */
30
+ export declare const _upgradeManager: (client: WalletClient) => Promise<Address>;
@@ -18,15 +18,15 @@ export declare const _adminOfRecord: (client: WalletClient) => Promise<Address>;
18
18
  */
19
19
  export declare const _adminDisabled: (client: WalletClient) => Promise<boolean>;
20
20
  /**
21
- * Whether the protocol is paused. While true, every ETH-moving path on the
22
- * device wallets and eSIM wallets reverts `ProtocolPaused`.
21
+ * Whether the protocol is paused. While true, the purchase and token-pull
22
+ * paths on the device wallets and eSIM wallets revert `ProtocolPaused`.
23
23
  */
24
24
  export declare const _paused: (client: WalletClient) => Promise<boolean>;
25
25
  /**
26
- * The fallback price ceiling in wei, applied to any eSIM wallet holding no cap of
27
- * its own. Never zero.
26
+ * The fallback price ceiling in USD cents, applied to any eSIM wallet holding no
27
+ * cap of its own. Never zero.
28
28
  */
29
- export declare const _defaultDataBundlePriceCap: (client: WalletClient) => Promise<bigint>;
29
+ export declare const _defaultPriceCapUSDCents: (client: WalletClient) => Promise<bigint>;
30
30
  /** The vault EOA recorded in the registry. */
31
31
  export declare const _vault: (client: WalletClient) => Promise<Address>;
32
32
  /** The pending admin nominated via `requestAdminUpdate` (zero address if none). */
@@ -128,3 +128,11 @@ export declare const _requireDeviceIdentifierNotReserved: (client: WalletClient,
128
128
  export declare const _proxiableUUID: (client: WalletClient) => Promise<Hex>;
129
129
  /** The OpenZeppelin upgrade interface this proxy speaks, currently `"5.0.0"`. */
130
130
  export declare const _upgradeInterfaceVersion: (client: WalletClient) => Promise<string>;
131
+ /** The payment adapter this registry currently points at. */
132
+ export declare const _paymentAdapter: (client: WalletClient) => Promise<Address>;
133
+ /**
134
+ * Whether a payment reference has already been spent for an eSIM wallet.
135
+ * Scoped per wallet: pass the same `keccak256(abi.encode(eSIMWallet, paymentReference))`
136
+ * the contract keys `usedPaymentReferences` by, not the bare reference.
137
+ */
138
+ export declare const _usedPaymentReferences: (client: WalletClient, scopedReference: Hex) => Promise<boolean>;
@@ -1,5 +1,5 @@
1
1
  import { Address, Hex, WalletClient } from "viem";
2
- import type { OwnerCall } from "../../types.js";
2
+ import type { DataBundleDetails, OwnerCall } from "../../types.js";
3
3
  /** Wire (or rewire) the LazyWalletRegistry into the Registry. `onlyOwner`. */
4
4
  export declare const _addOrUpdateLazyWalletRegistryAddress: (client: WalletClient, lazyWalletRegistry: Address) => Promise<`0x${string}`>;
5
5
  /** Update the vault that receives eSIM payments. `onlyOwner`. */
@@ -31,13 +31,13 @@ export declare const _disableAdmin: (client: WalletClient) => Promise<`0x${strin
31
31
  */
32
32
  export declare const _enableAdmin: (client: WalletClient) => Promise<`0x${string}`>;
33
33
  /**
34
- * Stop the ETH-moving paths on every device wallet and eSIM wallet.
35
- * `onlyESIMWalletAdmin`, so this is the one emergency lever the backend key can
36
- * pull on its own.
34
+ * Stop the purchase and token-pull paths on every device wallet and eSIM
35
+ * wallet. `onlyESIMWalletAdmin`, so this is the one emergency lever the backend
36
+ * key can pull on its own.
37
37
  *
38
38
  * It cannot release it again: `_unpause` is `onlyOwner`. That split is what stops
39
- * a compromised backend key holding user funds. Owners can still spend their own
40
- * ETH through their device wallet's `execute`, which a pause never reaches.
39
+ * a compromised backend key holding user funds. Owners can still move their own
40
+ * funds through their device wallet's `execute`, which a pause never reaches.
41
41
  */
42
42
  export declare const _pause: (client: WalletClient) => Promise<`0x${string}`>;
43
43
  /**
@@ -51,12 +51,12 @@ export declare const _unpause: (client: WalletClient) => Promise<`0x${string}`>;
51
51
  /**
52
52
  * Set the price ceiling every eSIM wallet falls back to when it holds none of its
53
53
  * own. `onlyOwner`, deliberately not the admin: the admin names the price on
54
- * `buyDataBundle`, so it must not also be able to raise its own limit.
54
+ * `buyDataBundleWithToken`, so it must not also be able to raise its own limit.
55
55
  *
56
56
  * Zero reverts `ZeroDataBundlePriceCap`, since a zero would read as "no ceiling"
57
57
  * for every wallet without one of its own.
58
58
  */
59
- export declare const _setDefaultDataBundlePriceCap: (client: WalletClient, cap: bigint) => Promise<`0x${string}`>;
59
+ export declare const _setDefaultPriceCapUSDCents: (client: WalletClient, cap: bigint) => Promise<`0x${string}`>;
60
60
  /**
61
61
  * Bind an eSIM's unique identifier to its wallet. `onlyESIMWalletAdmin`.
62
62
  *
@@ -64,6 +64,16 @@ export declare const _setDefaultDataBundlePriceCap: (client: WalletClient, cap:
64
64
  * wallet reverts rather than moving.
65
65
  */
66
66
  export declare const _assignESIMIdentifier: (client: WalletClient, eSIMWalletAddress: Address, eSIMUniqueIdentifier: string) => Promise<`0x${string}`>;
67
+ /**
68
+ * Record a data bundle paid for outside the protocol - a card or an external
69
+ * wallet, never the device wallet. `onlyESIMWalletAdmin`. No money moves here:
70
+ * `_dataBundleDetail.settlement` must be `ExternalWallet` or `Fiat` (the
71
+ * contract reverts `SettlementNotAsserted` on `DeviceWallet`, since this call
72
+ * never sees a transfer to prove it), and `_tokenAmount` is recorded for
73
+ * offchain matching but never checked against `_dataBundleDetail.priceUSDCents`.
74
+ * `_paymentReference` is spendable once per eSIM wallet.
75
+ */
76
+ export declare const _recordSettledPurchase: (client: WalletClient, eSIMWalletAddress: Address, dataBundleDetail: DataBundleDetails, asset: Hex, tokenAmount: bigint, paymentReference: Hex) => Promise<`0x${string}`>;
67
77
  /**
68
78
  * Step 2 of the 2-step admin handover: the nominee accepts. The chain requires
69
79
  * `msg.sender` to equal the pending admin, so the `client` here must be the
@@ -1,34 +1,22 @@
1
1
  import { WalletClient, Address } from 'viem';
2
- import { mainnet, sepolia, optimism, optimismSepolia, arbitrum, arbitrumSepolia, base, baseSepolia } from "viem/chains";
2
+ import { base, baseSepolia } from "viem/chains";
3
3
  export declare const ZERO: bigint;
4
4
  export declare const SIGNATURE_VALIDITY_SECONDS = 180;
5
5
  export declare const STUB_VERIFICATION_GAS_PAD: bigint;
6
6
  export declare const STUB_PRE_VERIFICATION_GAS_PAD: bigint;
7
7
  export declare enum CHAIN_ID {
8
- MAINNET = 1,
9
- SEPOLIA = 11155111,
10
- OPTIMISM_MAINNET = 10,
11
- OPTIMISM_SEPOLIA = 11155420,
12
8
  BASE_MAINNET = 8453,
13
- BASE_SEPOLIA = 84532,
14
- ARBITRUM_ONE = 42161,
15
- ARBITRUM_SEPOLIA = 421614
9
+ BASE_SEPOLIA = 84532
16
10
  }
17
11
  export interface chainSpecifcConstants {
18
- factoryAddresses: typeof sepoliaFactoryAddresses | typeof mainnetFactoryAddresses | typeof optimismMainnetFactoryAddresses | typeof optimismSepoliaFactoryAddresses | typeof baseMainnetFactoryAddresses | typeof baseSepoliaFactoryAddresses | typeof arbitrumOneFactoryAddresses | typeof arbitrumSepoliaFactoryAddresses;
19
- chain: typeof mainnet | typeof sepolia | typeof optimism | typeof optimismSepolia | typeof base | typeof baseSepolia | typeof arbitrum | typeof arbitrumSepolia;
12
+ factoryAddresses: typeof baseMainnetFactoryAddresses | typeof baseSepoliaFactoryAddresses;
13
+ chain: typeof base | typeof baseSepolia;
20
14
  rpcURL: string;
21
15
  pimlicoRpcURL: string;
22
16
  customErrors: typeof customErrors;
23
17
  }
24
- export declare const sepoliaFactoryAddresses: Record<string, Address>;
25
- export declare const mainnetFactoryAddresses: Record<string, Address>;
26
- export declare const optimismMainnetFactoryAddresses: Record<string, Address>;
27
- export declare const optimismSepoliaFactoryAddresses: Record<string, Address>;
28
18
  export declare const baseMainnetFactoryAddresses: Record<string, Address>;
29
19
  export declare const baseSepoliaFactoryAddresses: Record<string, Address>;
30
- export declare const arbitrumOneFactoryAddresses: Record<string, Address>;
31
- export declare const arbitrumSepoliaFactoryAddresses: Record<string, Address>;
32
20
  export declare const customErrors: Record<string, string>;
33
21
  export declare const _extractChainID: (client: WalletClient) => Promise<number>;
34
- export declare const _getChainSpecificConstants: (chainID: CHAIN_ID.SEPOLIA | CHAIN_ID.MAINNET | CHAIN_ID.OPTIMISM_MAINNET | CHAIN_ID.OPTIMISM_SEPOLIA | CHAIN_ID.BASE_MAINNET | CHAIN_ID.BASE_SEPOLIA | CHAIN_ID.ARBITRUM_ONE | CHAIN_ID.ARBITRUM_SEPOLIA, rpcURL: string, pimlicoAPIKey?: string) => chainSpecifcConstants;
22
+ export declare const _getChainSpecificConstants: (chainID: CHAIN_ID.BASE_MAINNET | CHAIN_ID.BASE_SEPOLIA, rpcURL: string, pimlicoAPIKey?: string) => chainSpecifcConstants;
@@ -9,14 +9,14 @@ import { P256Key } from "../types.js";
9
9
  * atomically through `executeBatch`.
10
10
  */
11
11
  export declare const _sendUserOperation: (client: KokioSmartAccountClient, calls: Call[]) => Promise<`0x${string}`>;
12
- export declare const _toggleAccessToETH: (client: KokioSmartAccountClient, address: Address, eSIMWalletAddress: Address, hasAccessToETH: boolean) => Promise<`0x${string}`>;
12
+ export declare const _toggleAccessToFunds: (client: KokioSmartAccountClient, address: Address, eSIMWalletAddress: Address, hasAccessToFunds: boolean) => Promise<`0x${string}`>;
13
13
  /**
14
14
  * Bind an eSIM wallet this device wallet already owns.
15
15
  *
16
- * A bind never carries ETH access: the contract reverts on a `true` rather than
16
+ * A bind never carries fund access: the contract reverts on a `true` rather than
17
17
  * downgrading it quietly, so the SDK passes `false` and there is nothing to
18
- * choose. `toggleAccessToETH` is the only way to grant it, which is what stops a
19
- * bind from undoing the owner's revocation.
18
+ * choose. `toggleAccessToFunds` is the only way to grant it, which is what stops
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
22
  /**
@@ -54,10 +54,10 @@ export declare const _deviceUniqueIdentifier: (client: KokioSmartAccountClient,
54
54
  /** Whether this wallet currently holds the given eSIM wallet. */
55
55
  export declare const _isValidESIMWallet: (client: KokioSmartAccountClient, address: Address, eSIMWalletAddress: Address) => Promise<boolean>;
56
56
  /**
57
- * Whether an eSIM wallet may pull ETH from this one. Binding a wallet never
58
- * grants it, so this stays false until `toggleAccessToETH` says otherwise.
57
+ * Whether an eSIM wallet may pull funds from this one. Binding a wallet never
58
+ * grants it, so this stays false until `toggleAccessToFunds` says otherwise.
59
59
  */
60
- export declare const _canPullETH: (client: KokioSmartAccountClient, address: Address, eSIMWalletAddress: Address) => Promise<boolean>;
60
+ export declare const _canPullFunds: (client: KokioSmartAccountClient, address: Address, eSIMWalletAddress: Address) => Promise<boolean>;
61
61
  /**
62
62
  * Check a signature over an arbitrary message, per ERC-1271. Returns
63
63
  * `0x1626ba7e` when the signature is valid and unexpired, `0xffffffff` otherwise.
@@ -1,22 +1,36 @@
1
- import { Address } from "viem";
1
+ import { Address, Hex } from "viem";
2
2
  import { DataBundleDetails } from "../types.js";
3
3
  import { KokioSmartAccountClient } from "../types.js";
4
4
  /**
5
- * Cap what this eSIM wallet may be charged for one data bundle. Zero hands it
6
- * back to the registry's ceiling.
5
+ * Cap what this eSIM wallet may be charged for one data bundle, in USD cents.
6
+ * Zero hands it back to the registry's ceiling.
7
7
  *
8
8
  * `onlyDeviceWallet`, so it needs the user's own signature. That is the point:
9
- * the admin names the price on `buyDataBundle`, so it must not be able to raise
10
- * the ceiling on that price too. A handover clears the cap, and the new owner has
11
- * to set it again.
9
+ * the admin names the price on `buyDataBundleWithToken`, so it must not be able
10
+ * to raise the ceiling on that price too. A handover clears the cap, and the new
11
+ * owner has to set it again.
12
12
  */
13
- export declare const _setDataBundlePriceCap: (client: KokioSmartAccountClient, address: Address, cap: bigint) => Promise<`0x${string}`>;
14
- export declare const _buyDataBundle: (client: KokioSmartAccountClient, address: Address, dataBundleDetails: DataBundleDetails) => Promise<`0x${string}`>;
13
+ export declare const _setPriceCapUSDCents: (client: KokioSmartAccountClient, address: Address, cap: bigint) => Promise<`0x${string}`>;
14
+ /**
15
+ * Buy a data bundle in `asset`, an ERC-20 the payment adapter accepts.
16
+ *
17
+ * `_maxAmountIn` is the most of `asset` the buyer will spend, in its smallest
18
+ * unit - read it from `paymentAdapter.quote(asset, dataBundleDetails.priceUSDCents)`
19
+ * first. `_paymentReference` ties this purchase to its offchain order and is
20
+ * spendable once per eSIM wallet; the caller supplies it rather than the SDK
21
+ * inventing one.
22
+ */
23
+ export declare const _buyDataBundleWithToken: (client: KokioSmartAccountClient, address: Address, dataBundleDetails: DataBundleDetails, asset: Hex, maxAmountIn: bigint, paymentReference: Hex) => Promise<`0x${string}`>;
24
+ /**
25
+ * Send an ERC-20 held by this eSIM wallet back to its owning device wallet.
26
+ * `onlyDeviceWallet`.
27
+ */
28
+ export declare const _sendTokenToDeviceWallet: (client: KokioSmartAccountClient, address: Address, token: Address, amount: bigint) => Promise<`0x${string}`>;
15
29
  export declare const _owner: (client: KokioSmartAccountClient, address: Address) => Promise<Address>;
16
30
  /**
17
- * The ceiling that actually applies to this wallet's next purchase, in wei.
18
- * Read it before naming a price on `buyDataBundle`, since a price above the
19
- * ceiling reverts.
31
+ * The ceiling that actually applies to this wallet's next purchase, in USD
32
+ * cents. Read it before naming a price on `buyDataBundleWithToken`, since a
33
+ * price above the ceiling reverts.
20
34
  *
21
35
  * Resolved the way the contract resolves it. The wallet's own cap wins when it
22
36
  * has one. Zero there means "follow the registry", which is where a fresh wallet
@@ -25,11 +39,11 @@ export declare const _owner: (client: KokioSmartAccountClient, address: Address)
25
39
  * not spend anything".
26
40
  *
27
41
  * That last case cannot happen on a live deployment: the registry refuses a zero
28
- * cap in both `initialize` and `setDefaultDataBundlePriceCap`. It is handled
42
+ * cap in both `initialize` and `setDefaultPriceCapUSDCents`. It is handled
29
43
  * because the contract's own check treats zero as unlimited, not because the
30
44
  * state is reachable.
31
45
  */
32
- export declare const _dataBundlePriceCap: (client: KokioSmartAccountClient, address: Address) => Promise<bigint>;
46
+ export declare const _priceCapUSDCents: (client: KokioSmartAccountClient, address: Address) => Promise<bigint>;
33
47
  /**
34
48
  * The device wallet this eSIM wallet belongs to. Tracks `owner`, but it is its
35
49
  * own storage slot with its own getter, so read whichever one you mean.
@@ -41,8 +55,8 @@ export declare const _deviceWallet: (client: KokioSmartAccountClient, address: A
41
55
  * pre-deployment purchases the lazy registry copies in.
42
56
  *
43
57
  * There is no length getter on the contract. Read upwards from zero until a call
44
- * reverts, or track the count from the `DataBundleBought` and
45
- * `TransactionHistoryPopulated` events.
58
+ * reverts, or track the count from the `DataBundleBoughtWithToken`,
59
+ * `DataBundleSettlementRecorded` and `TransactionHistoryPopulated` events.
46
60
  */
47
61
  export declare const _transactionHistory: (client: KokioSmartAccountClient, address: Address, index: bigint) => Promise<DataBundleDetails>;
48
62
  export declare const _requestTransferOwnership: (client: KokioSmartAccountClient, address: Address, newOwner: Address) => Promise<`0x${string}`>;
@@ -1,4 +1,4 @@
1
- import { Hex } from "viem";
1
+ import { Abi, Account, Chain, ContractFunctionArgs, ContractFunctionName, Hex, WalletClient, WriteContractParameters, WriteContractReturnType } from "viem";
2
2
  /**
3
3
  * Base class for every error the Kokio SDK throws deliberately. Consumers can
4
4
  * `instanceof KokioError` to distinguish SDK-originated failures from viem /
@@ -106,3 +106,18 @@ export declare class ContractRevertError extends KokioError {
106
106
  readonly decoded: DecodedRevert | null;
107
107
  constructor(data: Hex);
108
108
  }
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.
112
+ */
113
+ export declare const toContractRevertError: (err: unknown) => ContractRevertError | null;
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.
118
+ *
119
+ * Mirrors `WalletClient["writeContract"]`'s own generics rather than reading
120
+ * them off `Parameters<...>`, since that would collapse the per-call overload
121
+ * (e.g. a payable function's `value` field) to a single, wrong shape.
122
+ */
123
+ export declare const writeContractOrThrow: <const abi extends Abi | readonly unknown[], functionName extends ContractFunctionName<abi, "payable" | "nonpayable">, args extends ContractFunctionArgs<abi, "payable" | "nonpayable", functionName>, chainOverride extends Chain | undefined = undefined>(client: WalletClient, request: WriteContractParameters<abi, functionName, args, Chain | undefined, Account | undefined, chainOverride>) => Promise<WriteContractReturnType>;
@@ -0,0 +1,40 @@
1
+ import { Address, Hex } from "viem";
2
+ import { KokioSmartAccountClient } from "../types.js";
3
+ import { Asset } from "../types.js";
4
+ /**
5
+ * The registry this adapter reads `vault()` and `isESIMWalletValid()` from.
6
+ */
7
+ export declare const _registry: (client: KokioSmartAccountClient) => Promise<Address>;
8
+ /** The ERC-20 registered under the `USDC` symbol at configure time. */
9
+ export declare const _settlementToken: (client: KokioSmartAccountClient) => Promise<Address>;
10
+ /**
11
+ * The raw currency table entry for a symbol. `decimals` reads zero for a symbol
12
+ * never registered, which is how `resolveAsset` tells "not registered" apart
13
+ * from "registered but withdrawn" (`allowed: false`).
14
+ */
15
+ export declare const _assets: (client: KokioSmartAccountClient, symbol: Hex) => Promise<Asset>;
16
+ /**
17
+ * A currency's full entry, reverting if the symbol was never registered.
18
+ * `_asset` is not required for `buyDataBundleWithToken`, but is worth reading
19
+ * first: `token` being the zero address means the currency is fiat-only and the
20
+ * purchase will revert with `AssetNotTransferable`.
21
+ */
22
+ export declare const _resolveAsset: (client: KokioSmartAccountClient, symbol: Hex) => Promise<Asset>;
23
+ /**
24
+ * The amount of `symbol`, in its smallest unit, that a `priceUSDCents` charge
25
+ * currently costs. Read this before calling `buyDataBundleWithToken`, and pass
26
+ * the result (or a value at least this large) as `_maxAmountIn`: nothing today
27
+ * moves the price between the quote and the purchase, so the two always agree,
28
+ * but the contract will not assume that on the caller's behalf.
29
+ */
30
+ export declare const _quote: (client: KokioSmartAccountClient, symbol: Hex, priceUSDCents: bigint) => Promise<bigint>;
31
+ /**
32
+ * Whether a payment reference has already been spent here. Retired from the
33
+ * registry's live purchase paths (`PaymentAdapter.consumePaymentReference` is
34
+ * `onlyRegistry` but nothing calls it any more): replay protection now lives on
35
+ * `Registry.usedPaymentReferences`, scoped per eSIM wallet. Kept for whatever
36
+ * still reads the adapter's own record from before that move.
37
+ */
38
+ export declare const _usedReferences: (client: KokioSmartAccountClient, paymentReference: Hex) => Promise<boolean>;
39
+ /** The address holding upgrade authority over this adapter (its owner). */
40
+ export declare const _upgradeManager: (client: KokioSmartAccountClient) => Promise<Address>;
@@ -1,4 +1,4 @@
1
- import { Address } from "viem";
1
+ import { Address, Hex } from "viem";
2
2
  import { KokioSmartAccountClient } from "../types.js";
3
3
  /**
4
4
  * Take on an eSIM wallet and clear any standby flag left by a transfer.
@@ -29,8 +29,9 @@ export declare const _toggleESIMWalletStandbyStatus: (client: KokioSmartAccountC
29
29
  */
30
30
  export declare const _isDeviceIdentifierAlreadyUsed: (client: KokioSmartAccountClient, deviceUniqueIdentifier: string) => Promise<boolean>;
31
31
  /**
32
- * Whether the protocol is paused. While true, every ETH-moving path on the device
33
- * wallets and eSIM wallets reverts, so check this before offering a purchase.
32
+ * Whether the protocol is paused. While true, the purchase and token-pull paths
33
+ * on the device wallets and eSIM wallets revert, so check this before offering a
34
+ * purchase.
34
35
  */
35
36
  export declare const _paused: (client: KokioSmartAccountClient) => Promise<boolean>;
36
37
  /**
@@ -67,8 +68,22 @@ export declare const _isESIMIdentifierClaimed: (client: KokioSmartAccountClient,
67
68
  * belongs to the wallet rather than to whichever device is holding it.
68
69
  */
69
70
  export declare const _eSIMWalletForIdentifier: (client: KokioSmartAccountClient, eSIMUniqueIdentifier: string) => Promise<Address>;
70
- /** The fallback price ceiling in wei for a wallet holding no cap of its own. */
71
- export declare const _defaultDataBundlePriceCap: (client: KokioSmartAccountClient) => Promise<bigint>;
71
+ /** The fallback price ceiling in USD cents for a wallet holding no cap of its own. */
72
+ export declare const _defaultPriceCapUSDCents: (client: KokioSmartAccountClient) => Promise<bigint>;
73
+ /** The payment adapter this registry currently points at. */
74
+ export declare const _paymentAdapter: (client: KokioSmartAccountClient) => Promise<Address>;
75
+ /**
76
+ * Whether a payment reference has already been spent for an eSIM wallet.
77
+ * Scoped per wallet: pass the same `keccak256(abi.encode(eSIMWallet, paymentReference))`
78
+ * the contract keys `usedPaymentReferences` by, not the bare reference.
79
+ */
80
+ export declare const _usedPaymentReferences: (client: KokioSmartAccountClient, scopedReference: Hex) => Promise<boolean>;
81
+ /**
82
+ * Throws if `eSIMWallet` still has lazy-deployment history waiting to be copied
83
+ * in. `buyDataBundleWithToken` checks this itself before writing a new entry, so
84
+ * calling it first only turns that revert into a typed error ahead of a userOp.
85
+ */
86
+ export declare const _requireLazyHistoryCopied: (client: KokioSmartAccountClient, eSIMWallet: Address) => Promise<void>;
72
87
  /**
73
88
  * Throws if a fiat user's eSIMs are already waiting on this device identifier.
74
89
  * Worth calling before a deployment: taking a reserved identifier strands the
@@ -1 +1,2 @@
1
- export type { P256Key, Call, WebAuthnSignature, P256Credential, DataBundleDetails, SignedRequest, KokioSmartAccount, KokioSmartAccountClient, OwnerCall, OperationOptions, ScheduledOperation, ScheduledBatchOperation } from './types';
1
+ export type { P256Key, Call, WebAuthnSignature, P256Credential, DataBundleDetails, Asset, SignedRequest, KokioSmartAccount, KokioSmartAccountClient, OwnerCall, OperationOptions, ScheduledOperation, ScheduledBatchOperation } from './types';
2
+ export { Settlement } from './types';
@@ -94,9 +94,27 @@ export type P256Credential = {
94
94
  s: Hex;
95
95
  };
96
96
  };
97
+ /**
98
+ * Which contract, if any, saw the money for a data bundle move. Mirrors the
99
+ * on-chain `Settlement` enum (CustomStructs.sol) - viem decodes a Solidity enum
100
+ * as its `uint8` position, so the member order here must match exactly.
101
+ */
102
+ export declare enum Settlement {
103
+ DeviceWallet = 0,
104
+ ExternalWallet = 1,
105
+ Fiat = 2
106
+ }
97
107
  export type DataBundleDetails = {
98
- dataBundleID: string;
99
- dataBundlePrice: bigint;
108
+ id: Hex;
109
+ priceUSDCents: bigint;
110
+ settlement: Settlement;
111
+ };
112
+ /** One currency the payment adapter accepts. Mirrors the on-chain `Asset` struct (PaymentAdapter.sol). */
113
+ export type Asset = {
114
+ allowed: boolean;
115
+ isDollarUnit: boolean;
116
+ decimals: number;
117
+ token: Address;
100
118
  };
101
119
  /** One `deployMoreESIMWalletsForLazyDevice` (or first) transaction, read back from its receipt. */
102
120
  export type LazyDeploymentBatch = {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "kokio-sdk",
3
- "version": "2.0.0",
3
+ "version": "3.0.0",
4
4
  "description": "",
5
5
  "type": "module",
6
6
  "main": "./dist/esm/config.js",