kokio-sdk 3.0.2 → 3.1.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 +15 -15
- package/dist/esm/admin/config-admin.js +1 -1
- package/dist/esm/config.js +1 -1
- package/dist/esm/interface/deviceWalletClass.js +10 -1
- package/dist/esm/interface/eSIMWalletClass.js +9 -1
- package/dist/esm/interface/eSIMWalletFactoryClass.js +9 -1
- package/dist/esm/interface/registryClass.js +8 -0
- package/dist/esm/interface/smartAccountClass.js +9 -2
- package/dist/esm/logic/P256Verifier.js +2 -2
- package/dist/esm/logic/account-kit/createSmartAccount.js +47 -36
- package/dist/esm/logic/admin/deviceWallet.eoa.js +5 -5
- package/dist/esm/logic/admin/deviceWalletFactory.eoa.js +13 -13
- package/dist/esm/logic/admin/eSIMWallet.eoa.js +3 -3
- package/dist/esm/logic/admin/eSIMWalletFactory.eoa.js +9 -9
- package/dist/esm/logic/admin/lazyWalletRegistry.eoa.js +13 -13
- package/dist/esm/logic/admin/paymentAdapter.eoa.js +11 -11
- package/dist/esm/logic/admin/protocolAdmin.eoa.js +14 -14
- package/dist/esm/logic/admin/reads/deviceWalletFactory.reads.js +9 -9
- package/dist/esm/logic/admin/reads/eSIMWalletFactory.reads.js +7 -7
- package/dist/esm/logic/admin/reads/lazyWalletRegistry.reads.js +18 -18
- package/dist/esm/logic/admin/reads/paymentAdapter.reads.js +8 -8
- package/dist/esm/logic/admin/reads/protocolAdmin.reads.js +2 -2
- package/dist/esm/logic/admin/reads/registry.reads.js +31 -31
- package/dist/esm/logic/admin/registry.eoa.js +27 -27
- package/dist/esm/logic/constants.js +14 -1
- package/dist/esm/logic/deviceWallet.js +35 -1
- package/dist/esm/logic/deviceWalletFactory.js +11 -11
- package/dist/esm/logic/eSIMWallet.js +50 -2
- package/dist/esm/logic/eSIMWalletFactory.js +15 -3
- package/dist/esm/logic/errors.js +15 -9
- package/dist/esm/logic/paymentAdapter.js +8 -8
- package/dist/esm/logic/registry.js +17 -17
- package/dist/esm/logic/utils.js +1 -81
- package/dist/types/admin/config-admin.d.ts +1 -1
- package/dist/types/config.d.ts +1 -1
- package/dist/types/interface/deviceWalletClass.d.ts +12 -0
- package/dist/types/interface/eSIMWalletClass.d.ts +6 -0
- package/dist/types/interface/eSIMWalletFactoryClass.d.ts +6 -0
- package/dist/types/interface/registryClass.d.ts +8 -0
- package/dist/types/interface/smartAccountClass.d.ts +10 -1
- package/dist/types/logic/account-kit/createSmartAccount.d.ts +1 -1
- package/dist/types/logic/constants.d.ts +3 -0
- package/dist/types/logic/deviceWallet.d.ts +12 -0
- package/dist/types/logic/eSIMWallet.d.ts +8 -0
- package/dist/types/logic/eSIMWalletFactory.d.ts +2 -0
- package/dist/types/logic/errors.d.ts +6 -5
- package/dist/types/logic/utils.d.ts +0 -21
- package/dist/types/types.d.ts +1 -1
- package/package.json +21 -7
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import { _getChainSpecificConstants } from "./constants.js";
|
|
1
|
+
import { _chainId, _getChainSpecificConstants } from "./constants.js";
|
|
2
2
|
import { MissingEOAWalletError } from "./errors.js";
|
|
3
3
|
import { DeviceWalletFactory } from "../abis/index.js";
|
|
4
4
|
export const _createAccountWithEOA = async (client, deviceUniqueIdentifier, deviceWalletOwnerKey, salt, depositAmount) => {
|
|
5
|
-
const chainID = await client
|
|
5
|
+
const chainID = await _chainId(client);
|
|
6
6
|
const rpcURL = client.transport.url;
|
|
7
7
|
const values = _getChainSpecificConstants(chainID, rpcURL);
|
|
8
8
|
if (!client.account)
|
|
@@ -12,7 +12,7 @@ export const _createAccountWithEOA = async (client, deviceUniqueIdentifier, devi
|
|
|
12
12
|
return client.writeContract({
|
|
13
13
|
address: values.factoryAddresses.DEVICE_WALLET_FACTORY,
|
|
14
14
|
chain: values.chain,
|
|
15
|
-
account: client.account
|
|
15
|
+
account: client.account,
|
|
16
16
|
abi: DeviceWalletFactory,
|
|
17
17
|
functionName: 'createAccount',
|
|
18
18
|
args: [deviceUniqueIdentifier, deviceWalletOwnerKey, salt],
|
|
@@ -23,7 +23,7 @@ export const _createAccountWithEOA = async (client, deviceUniqueIdentifier, devi
|
|
|
23
23
|
// On-chain arg order is (bytes32[2] ownerKey, string uid, uint256 salt); note this
|
|
24
24
|
// differs from `createAccount`.
|
|
25
25
|
export const _getAddress = async (client, deviceUniqueIdentifier, deviceWalletOwnerKey, salt) => {
|
|
26
|
-
const chainID = await client
|
|
26
|
+
const chainID = await _chainId(client);
|
|
27
27
|
const rpcURL = client.transport.url;
|
|
28
28
|
const values = _getChainSpecificConstants(chainID, rpcURL);
|
|
29
29
|
return client.readContract({
|
|
@@ -35,7 +35,7 @@ export const _getAddress = async (client, deviceUniqueIdentifier, deviceWalletOw
|
|
|
35
35
|
};
|
|
36
36
|
// `getCurrentDeviceWalletImplementation` is a `view` - read it directly instead of a userOp.
|
|
37
37
|
export const _getCurrentDeviceWalletImplementation = async (client) => {
|
|
38
|
-
const chainID = await client
|
|
38
|
+
const chainID = await _chainId(client);
|
|
39
39
|
const rpcURL = client.transport.url;
|
|
40
40
|
const values = _getChainSpecificConstants(chainID, rpcURL);
|
|
41
41
|
return client.readContract({
|
|
@@ -57,7 +57,7 @@ export const _getCurrentDeviceWalletImplementation = async (client) => {
|
|
|
57
57
|
* Reverts on an empty identifier or a key that is not a point on the P256 curve.
|
|
58
58
|
*/
|
|
59
59
|
export const _preCreateAccountValidation = async (client, deviceUniqueIdentifier, deviceWalletOwnerKey) => {
|
|
60
|
-
const chainID = await client
|
|
60
|
+
const chainID = await _chainId(client);
|
|
61
61
|
const rpcURL = client.transport.url;
|
|
62
62
|
const values = _getChainSpecificConstants(chainID, rpcURL);
|
|
63
63
|
return client.readContract({
|
|
@@ -73,7 +73,7 @@ export const _preCreateAccountValidation = async (client, deviceUniqueIdentifier
|
|
|
73
73
|
* registers it.
|
|
74
74
|
*/
|
|
75
75
|
export const _deviceWalletInfoAdded = async (client, deviceWallet) => {
|
|
76
|
-
const chainID = await client
|
|
76
|
+
const chainID = await _chainId(client);
|
|
77
77
|
const rpcURL = client.transport.url;
|
|
78
78
|
const values = _getChainSpecificConstants(chainID, rpcURL);
|
|
79
79
|
return client.readContract({
|
|
@@ -88,7 +88,7 @@ export const _deviceWalletInfoAdded = async (client, deviceWallet) => {
|
|
|
88
88
|
* all of them and no wallet can decline it.
|
|
89
89
|
*/
|
|
90
90
|
export const _beacon = async (client) => {
|
|
91
|
-
const chainID = await client
|
|
91
|
+
const chainID = await _chainId(client);
|
|
92
92
|
const rpcURL = client.transport.url;
|
|
93
93
|
const values = _getChainSpecificConstants(chainID, rpcURL);
|
|
94
94
|
return client.readContract({
|
|
@@ -100,7 +100,7 @@ export const _beacon = async (client) => {
|
|
|
100
100
|
};
|
|
101
101
|
/** The registry the factory writes new wallets into. */
|
|
102
102
|
export const _registry = async (client) => {
|
|
103
|
-
const chainID = await client
|
|
103
|
+
const chainID = await _chainId(client);
|
|
104
104
|
const rpcURL = client.transport.url;
|
|
105
105
|
const values = _getChainSpecificConstants(chainID, rpcURL);
|
|
106
106
|
return client.readContract({
|
|
@@ -112,7 +112,7 @@ export const _registry = async (client) => {
|
|
|
112
112
|
};
|
|
113
113
|
/** The EntryPoint baked into every device wallet this factory deploys. */
|
|
114
114
|
export const _entryPoint = async (client) => {
|
|
115
|
-
const chainID = await client
|
|
115
|
+
const chainID = await _chainId(client);
|
|
116
116
|
const rpcURL = client.transport.url;
|
|
117
117
|
const values = _getChainSpecificConstants(chainID, rpcURL);
|
|
118
118
|
return client.readContract({
|
|
@@ -124,7 +124,7 @@ export const _entryPoint = async (client) => {
|
|
|
124
124
|
};
|
|
125
125
|
/** The contract new device wallets verify WebAuthn assertions through. */
|
|
126
126
|
export const _verifier = async (client) => {
|
|
127
|
-
const chainID = await client
|
|
127
|
+
const chainID = await _chainId(client);
|
|
128
128
|
const rpcURL = client.transport.url;
|
|
129
129
|
const values = _getChainSpecificConstants(chainID, rpcURL);
|
|
130
130
|
return client.readContract({
|
|
@@ -1,6 +1,7 @@
|
|
|
1
|
-
import { encodeFunctionData, maxUint256 } from "viem";
|
|
1
|
+
import { encodeFunctionData, erc20Abi, maxUint256 } from "viem";
|
|
2
2
|
import { MissingSmartWalletError } from "./errors.js";
|
|
3
|
-
import { ESIMWallet } from "../abis/index.js";
|
|
3
|
+
import { ESIMWallet, PaymentAdapter, Registry } from "../abis/index.js";
|
|
4
|
+
import { _chainId, _getChainSpecificConstants } from "./constants.js";
|
|
4
5
|
import { _defaultPriceCapUSDCents } from "./registry.js";
|
|
5
6
|
// Not exposed on this surface:
|
|
6
7
|
// - populateHistory and setESIMUniqueIdentifier are `onlyRegistry` - callable
|
|
@@ -61,6 +62,53 @@ export const _buyDataBundleWithToken = async (client, address, dataBundleDetails
|
|
|
61
62
|
}]
|
|
62
63
|
});
|
|
63
64
|
};
|
|
65
|
+
/**
|
|
66
|
+
* Buy a data bundle with tokens the device wallet sends over in the same user
|
|
67
|
+
* operation, so the eSIM wallet needs no access to the device wallet's funds.
|
|
68
|
+
*
|
|
69
|
+
* Only the shortfall is sent: the quote for the bundle minus what this eSIM
|
|
70
|
+
* wallet already holds of `asset`. Arguments are as for `buyDataBundleWithToken`.
|
|
71
|
+
*/
|
|
72
|
+
export const _buyDataBundleWithTransfer = async (client, address, dataBundleDetails, asset, maxAmountIn, paymentReference) => {
|
|
73
|
+
const chainID = await _chainId(client);
|
|
74
|
+
const rpcURL = client.transport.url;
|
|
75
|
+
const values = _getChainSpecificConstants(chainID, rpcURL);
|
|
76
|
+
if (!client.account)
|
|
77
|
+
throw new MissingSmartWalletError();
|
|
78
|
+
// The eSIM wallet pays through whichever adapter the registry names, so read it there.
|
|
79
|
+
const adapter = await client.readContract({
|
|
80
|
+
address: values.factoryAddresses.REGISTRY, abi: Registry, functionName: "paymentAdapter"
|
|
81
|
+
});
|
|
82
|
+
const [{ token }, amountIn] = await Promise.all([
|
|
83
|
+
client.readContract({
|
|
84
|
+
address: adapter, abi: PaymentAdapter, functionName: "resolveAsset", args: [asset]
|
|
85
|
+
}),
|
|
86
|
+
client.readContract({
|
|
87
|
+
address: adapter, abi: PaymentAdapter, functionName: "quote", args: [asset, dataBundleDetails.priceUSDCents]
|
|
88
|
+
}),
|
|
89
|
+
]);
|
|
90
|
+
const held = await client.readContract({
|
|
91
|
+
address: token, abi: erc20Abi, functionName: "balanceOf", args: [address]
|
|
92
|
+
});
|
|
93
|
+
const buy = {
|
|
94
|
+
to: address,
|
|
95
|
+
data: encodeFunctionData({
|
|
96
|
+
abi: ESIMWallet,
|
|
97
|
+
functionName: "buyDataBundleWithToken",
|
|
98
|
+
args: [dataBundleDetails, asset, maxAmountIn, paymentReference]
|
|
99
|
+
})
|
|
100
|
+
};
|
|
101
|
+
return client.sendUserOperation({
|
|
102
|
+
account: client.account,
|
|
103
|
+
calls: held >= amountIn ? [buy] : [
|
|
104
|
+
{
|
|
105
|
+
to: token,
|
|
106
|
+
data: encodeFunctionData({ abi: erc20Abi, functionName: "transfer", args: [address, amountIn - held] })
|
|
107
|
+
},
|
|
108
|
+
buy
|
|
109
|
+
]
|
|
110
|
+
});
|
|
111
|
+
};
|
|
64
112
|
/**
|
|
65
113
|
* Send an ERC-20 held by this eSIM wallet back to its owning device wallet.
|
|
66
114
|
* `onlyDeviceWallet`.
|
|
@@ -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 { MissingSmartWalletError } from "./errors.js";
|
|
4
4
|
import { ESIMWalletFactory } from "../abis/index.js";
|
|
5
5
|
// Not exposed on this surface:
|
|
@@ -10,7 +10,7 @@ import { ESIMWalletFactory } from "../abis/index.js";
|
|
|
10
10
|
// `deployESIMWalletWithUserOp` works because a registered device wallet passes
|
|
11
11
|
// `registry.isDeviceWalletValid(msg.sender)`, so the userOp sender satisfies the modifier.
|
|
12
12
|
export const _deployESIMWalletWithUserOp = async (client, deviceWalletAddress, salt) => {
|
|
13
|
-
const chainID = await client
|
|
13
|
+
const chainID = await _chainId(client);
|
|
14
14
|
const rpcURL = client.transport.url;
|
|
15
15
|
const values = _getChainSpecificConstants(chainID, rpcURL);
|
|
16
16
|
if (!client.account)
|
|
@@ -28,8 +28,20 @@ export const _deployESIMWalletWithUserOp = async (client, deviceWalletAddress, s
|
|
|
28
28
|
}]
|
|
29
29
|
});
|
|
30
30
|
};
|
|
31
|
+
/** Address `deployESIMWallet` deploys to for this device wallet and salt. */
|
|
32
|
+
export const _getESIMWalletCounterFactualAddress = async (client, deviceWalletAddress, salt) => {
|
|
33
|
+
const chainID = await _chainId(client);
|
|
34
|
+
const rpcURL = client.transport.url;
|
|
35
|
+
const values = _getChainSpecificConstants(chainID, rpcURL);
|
|
36
|
+
return client.readContract({
|
|
37
|
+
address: values.factoryAddresses.ESIM_WALLET_FACTORY,
|
|
38
|
+
abi: ESIMWalletFactory,
|
|
39
|
+
functionName: "getCounterFactualAddress",
|
|
40
|
+
args: [deviceWalletAddress, salt]
|
|
41
|
+
});
|
|
42
|
+
};
|
|
31
43
|
export const _getCurrentESIMWalletImplementation = async (client) => {
|
|
32
|
-
const chainID = await client
|
|
44
|
+
const chainID = await _chainId(client);
|
|
33
45
|
const rpcURL = client.transport.url;
|
|
34
46
|
const values = _getChainSpecificConstants(chainID, rpcURL);
|
|
35
47
|
// `getCurrentESIMWalletImplementation` is a `view` - read it directly instead of a userOp.
|
package/dist/esm/logic/errors.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { BaseError, ContractFunctionRevertedError, decodeErrorResult, isHex, } from "viem";
|
|
2
|
-
import { DeviceWallet, DeviceWalletFactory, ESIMWallet, ESIMWalletFactory, LazyWalletRegistry, P256Verifier, Registry, RegistryHelper, } from "../abis/index.js";
|
|
2
|
+
import { DeviceWallet, DeviceWalletFactory, ESIMWallet, ESIMWalletFactory, LazyWalletRegistry, P256Verifier, Registry, RegistryHelper, ProtocolAdmin, PaymentAdapter, } from "../abis/index.js";
|
|
3
3
|
/**
|
|
4
4
|
* Base class for every error the Kokio SDK throws deliberately. Consumers can
|
|
5
5
|
* `instanceof KokioError` to distinguish SDK-originated failures from viem /
|
|
@@ -144,6 +144,8 @@ const REVERTABLE_ABIS = [
|
|
|
144
144
|
P256Verifier,
|
|
145
145
|
Registry,
|
|
146
146
|
RegistryHelper,
|
|
147
|
+
ProtocolAdmin,
|
|
148
|
+
PaymentAdapter,
|
|
147
149
|
];
|
|
148
150
|
/**
|
|
149
151
|
* Best-effort decode of raw revert data (the ABI-encoded `Error(string)`,
|
|
@@ -181,21 +183,25 @@ export class ContractRevertError extends KokioError {
|
|
|
181
183
|
}
|
|
182
184
|
}
|
|
183
185
|
/**
|
|
184
|
-
* Pulls a ContractRevertError out of an error thrown by viem, or `null`
|
|
185
|
-
*
|
|
186
|
+
* Pulls a ContractRevertError out of an error thrown by viem, or `null` when
|
|
187
|
+
* the error carries no revert data (a network failure, a rejected signature).
|
|
186
188
|
*/
|
|
187
189
|
export const toContractRevertError = (err) => {
|
|
188
190
|
if (!(err instanceof BaseError))
|
|
189
191
|
return null;
|
|
190
192
|
const revert = err.walk((e) => e instanceof ContractFunctionRevertedError);
|
|
191
|
-
if (
|
|
192
|
-
return
|
|
193
|
-
|
|
193
|
+
if (revert instanceof ContractFunctionRevertedError && revert.raw)
|
|
194
|
+
return new ContractRevertError(revert.raw);
|
|
195
|
+
// A bundler rejects a reverting user operation while estimating its gas, and
|
|
196
|
+
// puts the revert data only in the error message.
|
|
197
|
+
const data = err.details?.match(/reverted during simulation with reason: (0x[0-9a-fA-F]+)/)?.[1];
|
|
198
|
+
return data ? new ContractRevertError(data) : null;
|
|
194
199
|
};
|
|
195
200
|
/**
|
|
196
|
-
* `client.writeContract`, but a
|
|
197
|
-
*
|
|
198
|
-
*
|
|
201
|
+
* `client.writeContract`, but a revert comes back as a ContractRevertError
|
|
202
|
+
* instead of viem's raw error chain. Its `decoded` is null when the selector
|
|
203
|
+
* belongs to none of the Kokio contracts. Anything that is not a revert, such
|
|
204
|
+
* as a network failure, is rethrown as-is.
|
|
199
205
|
*
|
|
200
206
|
* Mirrors `WalletClient["writeContract"]`'s own generics rather than reading
|
|
201
207
|
* them off `Parameters<...>`, since that would collapse the per-call overload
|
|
@@ -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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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({
|
package/dist/esm/logic/utils.js
CHANGED
|
@@ -1,6 +1,4 @@
|
|
|
1
|
-
import { isHex
|
|
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,7 @@ 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
|
+
export { KokioError, NullOrUndefinedValueError, MissingSmartWalletError, MissingEOAWalletError, InvalidClientError, UnsupportedChainError, UnconfiguredChainError, CounterfactualMismatchError, BatchSizeOutOfRangeError, DepositOnResumeError, ESIMWalletNotLazyDeployedError, MissingBatchEventError, StalledBatchError, ContractRevertError, decodeContractRevert, } from "../logic/errors.js";
|
|
12
12
|
export type { DecodedRevert } from "../logic/errors.js";
|
|
13
13
|
export { OperationState } from "../logic/admin/reads/protocolAdmin.reads.js";
|
|
14
14
|
/**
|
package/dist/types/config.d.ts
CHANGED
|
@@ -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}`>;
|
|
@@ -7,6 +7,12 @@ export declare class ESIMWalletSubPackage {
|
|
|
7
7
|
constructor(client: KokioSmartAccountClient, address: Address);
|
|
8
8
|
acceptOwnershipTransfer(): Promise<`0x${string}`>;
|
|
9
9
|
buyDataBundleWithToken(dataBundleDetails: DataBundleDetails, asset: Hex, maxAmountIn: bigint, paymentReference: Hex): Promise<`0x${string}`>;
|
|
10
|
+
/**
|
|
11
|
+
* Same purchase as `buyDataBundleWithToken`, with the device wallet sending
|
|
12
|
+
* the tokens it needs in the same user operation. Works without having granted
|
|
13
|
+
* this eSIM wallet access to the device wallet's funds.
|
|
14
|
+
*/
|
|
15
|
+
buyDataBundleWithTransfer(dataBundleDetails: DataBundleDetails, asset: Hex, maxAmountIn: bigint, paymentReference: Hex): Promise<`0x${string}`>;
|
|
10
16
|
priceCapUSDCents(): Promise<bigint>;
|
|
11
17
|
deviceWallet(): Promise<`0x${string}`>;
|
|
12
18
|
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
|
-
|
|
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
|
}
|