kokio-sdk 3.0.1 → 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/esm/types-export.js +1 -1
- 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 +7 -1
- 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-export.d.ts +3 -2
- package/dist/types/types.d.ts +1 -1
- package/package.json +21 -7
package/README.md
CHANGED
|
@@ -22,13 +22,19 @@ surface, with a code example and return type, see the
|
|
|
22
22
|
|
|
23
23
|
## Installation
|
|
24
24
|
|
|
25
|
+
In the mobile app:
|
|
26
|
+
|
|
27
|
+
```sh
|
|
28
|
+
npm install kokio-sdk react-native-passkey
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
On a backend that only uses `kokio-sdk/admin`:
|
|
32
|
+
|
|
25
33
|
```sh
|
|
26
34
|
npm install kokio-sdk
|
|
27
35
|
```
|
|
28
36
|
|
|
29
|
-
The package ships as ES modules and requires Node 18 or newer (or a React Native
|
|
30
|
-
runtime). `viem` is bundled as a dependency, so you do not need to install it
|
|
31
|
-
separately.
|
|
37
|
+
The package ships as ES modules and requires Node 18 or newer (or a React Native runtime). `viem` is bundled as a dependency, so you do not need to install it separately. `react-native-passkey` is a native module, so the app installs it itself: Expo only links native modules the app lists directly, and one copy avoids version clashes.
|
|
32
38
|
|
|
33
39
|
## Mobile client (Expo / React Native)
|
|
34
40
|
|
|
@@ -39,10 +45,9 @@ is ever held in the app.
|
|
|
39
45
|
|
|
40
46
|
You will need:
|
|
41
47
|
|
|
42
|
-
- a viem `WalletClient` connected to the target chain
|
|
43
|
-
and an explicit RPC URL (see the note under the example),
|
|
48
|
+
- a viem `WalletClient` connected to the target chain with an explicit RPC URL (see the note under the example). It needs no `account`: the passkey signs every user operation.
|
|
44
49
|
- the passkey `credentialId` and `rpId` registered for the device,
|
|
45
|
-
- a Pimlico API key and a
|
|
50
|
+
- a Pimlico API key, and optionally a Pimlico sponsorship policy id (`sp_...`). Pass `""` to be sponsored without a policy.
|
|
46
51
|
|
|
47
52
|
```ts
|
|
48
53
|
import { Kokio } from "kokio-sdk";
|
|
@@ -50,7 +55,6 @@ import { createWalletClient, http } from "viem";
|
|
|
50
55
|
import { baseSepolia } from "viem/chains";
|
|
51
56
|
|
|
52
57
|
const walletClient = createWalletClient({
|
|
53
|
-
account: knownAddress,
|
|
54
58
|
chain: baseSepolia,
|
|
55
59
|
transport: http(rpcUrl),
|
|
56
60
|
});
|
|
@@ -90,15 +94,11 @@ const receipt = await smartAccountClient.waitForUserOperationReceipt({ hash });
|
|
|
90
94
|
if (!receipt.success) throw new Error("operation reverted");
|
|
91
95
|
```
|
|
92
96
|
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
URL, because the SDK reads `client.transport.url` to build the public client
|
|
97
|
-
it uses for contract reads.
|
|
97
|
+
The wallet client needs no `account`, since the passkey signs everything. Give `http()` a real RPC URL, because the SDK reads `client.transport.url` to build the public client it uses for contract reads.
|
|
98
|
+
|
|
99
|
+
Every write resolves with the user operation hash once the bundler accepts it, not once it is mined, so wait for the receipt as above. An operation the bundler can see will revert is refused before it is sent, and the write rejects with a `ContractRevertError` whose `decoded.errorName` names the contract error (for example `PaymentReferenceAlreadyUsed`). One that only reverts once mined still returns a receipt, so check `receipt.success` too. `receipt.receipt.transactionHash` is the onchain transaction.
|
|
98
100
|
|
|
99
|
-
|
|
100
|
-
still returns a receipt, so the await resolving is not on its own proof the
|
|
101
|
-
write landed. `receipt.receipt.transactionHash` is the onchain transaction.
|
|
101
|
+
Calls that belong together have helpers that send them as one user operation, so the user sees one passkey prompt: `deviceWallet.deployAndBindESIMWallet(salt, { grantAccessToFunds: true })` deploys an eSIM wallet, binds it and grants it access to the device wallet's tokens, and `eSIMWallet.buyDataBundleWithTransfer(...)` sends the tokens and buys in one go, without pull access.
|
|
102
102
|
|
|
103
103
|
The contract surfaces (`deviceWallet`, `eSIMWallet`, `deviceWalletFactory`,
|
|
104
104
|
`eSIMWalletFactory`, `registry`, `paymentAdapter`, `P256Verifier`) are only
|
|
@@ -10,7 +10,7 @@ import { AdminPaymentAdapterSubPackage } from "./interface/paymentAdapterClass.j
|
|
|
10
10
|
// Re-export the typed error surface so backend consumers can `instanceof
|
|
11
11
|
// KokioError` (or a subclass) and decode reverts without reaching into internal
|
|
12
12
|
// module paths - mirroring `config.ts`.
|
|
13
|
-
export { KokioError, NullOrUndefinedValueError, MissingSmartWalletError, MissingEOAWalletError, InvalidClientError, UnsupportedChainError, UnconfiguredChainError, CounterfactualMismatchError, ContractRevertError, decodeContractRevert, } from "../logic/errors.js";
|
|
13
|
+
export { KokioError, NullOrUndefinedValueError, MissingSmartWalletError, MissingEOAWalletError, InvalidClientError, UnsupportedChainError, UnconfiguredChainError, CounterfactualMismatchError, BatchSizeOutOfRangeError, DepositOnResumeError, ESIMWalletNotLazyDeployedError, MissingBatchEventError, StalledBatchError, ContractRevertError, decodeContractRevert, } from "../logic/errors.js";
|
|
14
14
|
// `getOperationState` answers with this, and comparing against it needs the enum
|
|
15
15
|
// at runtime rather than only in the types.
|
|
16
16
|
export { OperationState } from "../logic/admin/reads/protocolAdmin.reads.js";
|
package/dist/esm/config.js
CHANGED
|
@@ -10,7 +10,7 @@ import { PaymentAdapterSubPackage } from "./interface/paymentAdapterClass.js";
|
|
|
10
10
|
// Re-export the typed error surface so consumers can `instanceof KokioError`
|
|
11
11
|
// (or a specific subclass) and decode on-chain reverts without reaching into
|
|
12
12
|
// internal module paths.
|
|
13
|
-
export { KokioError, NullOrUndefinedValueError, MissingSmartWalletError, MissingEOAWalletError, InvalidClientError, UnsupportedChainError, UnconfiguredChainError, CounterfactualMismatchError, ContractRevertError, decodeContractRevert, } from "./logic/errors.js";
|
|
13
|
+
export { KokioError, NullOrUndefinedValueError, MissingSmartWalletError, MissingEOAWalletError, InvalidClientError, UnsupportedChainError, UnconfiguredChainError, CounterfactualMismatchError, BatchSizeOutOfRangeError, DepositOnResumeError, ESIMWalletNotLazyDeployedError, MissingBatchEventError, StalledBatchError, ContractRevertError, decodeContractRevert, } from "./logic/errors.js";
|
|
14
14
|
export class Kokio {
|
|
15
15
|
viemWalletClient;
|
|
16
16
|
credentialId;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { _addDeposit, _addESIMWallet, _canPullFunds, _deviceUniqueIdentifier, _entryPoint, _eSIMWalletFactory, _getDeposit, _getOwner, _getVaultAddress, _isValidESIMWallet, _isValidSignature, _registry, _removeESIMWallet, _sendUserOperation, _toggleAccessToFunds, _transferOwnership, _verifier, _withdrawDepositTo } from "../logic/deviceWallet.js";
|
|
1
|
+
import { _addDeposit, _addESIMWallet, _canPullFunds, _deployAndBindESIMWallet, _deviceUniqueIdentifier, _entryPoint, _eSIMWalletFactory, _getDeposit, _getOwner, _getVaultAddress, _isValidESIMWallet, _isValidSignature, _registry, _removeESIMWallet, _sendUserOperation, _toggleAccessToFunds, _transferOwnership, _verifier, _withdrawDepositTo } from "../logic/deviceWallet.js";
|
|
2
2
|
export class DeviceWalletSubPackage {
|
|
3
3
|
smartAccountClient;
|
|
4
4
|
walletClient;
|
|
@@ -17,6 +17,15 @@ export class DeviceWalletSubPackage {
|
|
|
17
17
|
addESIMWallet(eSIMWalletAddress) {
|
|
18
18
|
return _addESIMWallet(this.smartAccountClient, this.address, eSIMWalletAddress);
|
|
19
19
|
}
|
|
20
|
+
/**
|
|
21
|
+
* Deploy an eSIM wallet and bind it to this device wallet in one user
|
|
22
|
+
* operation, optionally granting it access to this wallet's tokens too.
|
|
23
|
+
* Resolves once the operation is sent, with its hash and the eSIM wallet's
|
|
24
|
+
* address.
|
|
25
|
+
*/
|
|
26
|
+
deployAndBindESIMWallet(salt, options = {}) {
|
|
27
|
+
return _deployAndBindESIMWallet(this.smartAccountClient, this.address, salt, options.grantAccessToFunds ?? false);
|
|
28
|
+
}
|
|
20
29
|
getVaultAddress() {
|
|
21
30
|
return _getVaultAddress(this.smartAccountClient, this.address);
|
|
22
31
|
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { _acceptOwnershipTransfer, _buyDataBundleWithToken, _priceCapUSDCents, _deviceWallet, _owner, _requestTransferOwnership, _sendETHToDeviceWallet, _sendTokenToDeviceWallet, _setPriceCapUSDCents, _transactionHistory } from "../logic/eSIMWallet.js";
|
|
1
|
+
import { _acceptOwnershipTransfer, _buyDataBundleWithToken, _buyDataBundleWithTransfer, _priceCapUSDCents, _deviceWallet, _owner, _requestTransferOwnership, _sendETHToDeviceWallet, _sendTokenToDeviceWallet, _setPriceCapUSDCents, _transactionHistory } from "../logic/eSIMWallet.js";
|
|
2
2
|
export class ESIMWalletSubPackage {
|
|
3
3
|
client;
|
|
4
4
|
address;
|
|
@@ -12,6 +12,14 @@ export class ESIMWalletSubPackage {
|
|
|
12
12
|
buyDataBundleWithToken(dataBundleDetails, asset, maxAmountIn, paymentReference) {
|
|
13
13
|
return _buyDataBundleWithToken(this.client, this.address, dataBundleDetails, asset, maxAmountIn, paymentReference);
|
|
14
14
|
}
|
|
15
|
+
/**
|
|
16
|
+
* Same purchase as `buyDataBundleWithToken`, with the device wallet sending
|
|
17
|
+
* the tokens it needs in the same user operation. Works without having granted
|
|
18
|
+
* this eSIM wallet access to the device wallet's funds.
|
|
19
|
+
*/
|
|
20
|
+
buyDataBundleWithTransfer(dataBundleDetails, asset, maxAmountIn, paymentReference) {
|
|
21
|
+
return _buyDataBundleWithTransfer(this.client, this.address, dataBundleDetails, asset, maxAmountIn, paymentReference);
|
|
22
|
+
}
|
|
15
23
|
priceCapUSDCents() {
|
|
16
24
|
return _priceCapUSDCents(this.client, this.address);
|
|
17
25
|
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { _deployESIMWalletWithUserOp, _getCurrentESIMWalletImplementation } from "../logic/eSIMWalletFactory.js";
|
|
1
|
+
import { _deployESIMWalletWithUserOp, _getCurrentESIMWalletImplementation, _getESIMWalletCounterFactualAddress } from "../logic/eSIMWalletFactory.js";
|
|
2
2
|
export class ESIMWalletFactorySubPackage {
|
|
3
3
|
smartAccountClient;
|
|
4
4
|
walletClient;
|
|
@@ -6,9 +6,17 @@ export class ESIMWalletFactorySubPackage {
|
|
|
6
6
|
this.smartAccountClient = smartAccountClient;
|
|
7
7
|
this.walletClient = walletClient;
|
|
8
8
|
}
|
|
9
|
+
/**
|
|
10
|
+
* @deprecated Deploys without binding, so the device wallet does not treat the
|
|
11
|
+
* new eSIM wallet as its own. Use `deviceWallet.deployAndBindESIMWallet`.
|
|
12
|
+
*/
|
|
9
13
|
deployESIMWalletWithUserOp(deviceWalletAddress, salt) {
|
|
10
14
|
return _deployESIMWalletWithUserOp(this.smartAccountClient, deviceWalletAddress, salt);
|
|
11
15
|
}
|
|
16
|
+
/** Address the eSIM wallet for this device wallet and salt deploys to. */
|
|
17
|
+
getCounterFactualAddress(deviceWalletAddress, salt) {
|
|
18
|
+
return _getESIMWalletCounterFactualAddress(this.smartAccountClient, deviceWalletAddress, salt);
|
|
19
|
+
}
|
|
12
20
|
getCurrentESIMWalletImplementation() {
|
|
13
21
|
return _getCurrentESIMWalletImplementation(this.smartAccountClient);
|
|
14
22
|
}
|
|
@@ -4,6 +4,14 @@ export class RegistrySubPackage {
|
|
|
4
4
|
constructor(client) {
|
|
5
5
|
this.client = client;
|
|
6
6
|
}
|
|
7
|
+
/**
|
|
8
|
+
* Record in the registry that this device wallet holds the eSIM wallet.
|
|
9
|
+
*
|
|
10
|
+
* Registry side only: the device wallet itself still does not treat the eSIM
|
|
11
|
+
* wallet as its own (`isValidESIMWallet` stays false, so it cannot manage it or
|
|
12
|
+
* grant it fund access). To take on an eSIM wallet use `deviceWallet.addESIMWallet`,
|
|
13
|
+
* which writes both sides.
|
|
14
|
+
*/
|
|
7
15
|
bindESIMWallet(eSIMWalletAddress) {
|
|
8
16
|
return _bindESIMWallet(this.client, eSIMWalletAddress);
|
|
9
17
|
}
|
|
@@ -15,7 +15,14 @@ export class SmartAccountSubPackage {
|
|
|
15
15
|
getSmartWallet(deviceUniqueIdentifier, deviceWalletOwnerKey, salt) {
|
|
16
16
|
return _getSmartWallet(this.client, this.credentialId, this.rpId, deviceUniqueIdentifier, deviceWalletOwnerKey, salt);
|
|
17
17
|
}
|
|
18
|
-
|
|
19
|
-
|
|
18
|
+
/**
|
|
19
|
+
* Client that sends the account's user operations through a bundler, with
|
|
20
|
+
* gas sponsored by the paymaster at the same endpoint.
|
|
21
|
+
*
|
|
22
|
+
* @param options.bundlerUrl Bundler and ERC-7677 paymaster endpoint. Defaults to
|
|
23
|
+
* Pimlico for the wallet client's chain, keyed by the API key given to `Kokio`.
|
|
24
|
+
*/
|
|
25
|
+
getSmartWalletClient(account, options = {}) {
|
|
26
|
+
return _getSmartWalletClient(this.client, this.pimlicoAPIKey, this.gasPolicyId, account, options.bundlerUrl);
|
|
20
27
|
}
|
|
21
28
|
}
|
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import { _getChainSpecificConstants } from "./constants.js";
|
|
1
|
+
import { _chainId, _getChainSpecificConstants } from "./constants.js";
|
|
2
2
|
import { P256Verifier } from "../abis/index.js";
|
|
3
3
|
// `verifySignature` is a `view` - read it directly instead of spending a userOp
|
|
4
4
|
// (the previous userOp form returned a userOp hash, never the boolean result).
|
|
5
5
|
export const _verifySignature = async (client, message, requireMessageVerification, webAuthnSignature, x, y) => {
|
|
6
|
-
const chainID = await client
|
|
6
|
+
const chainID = await _chainId(client);
|
|
7
7
|
const rpcURL = client.transport.url;
|
|
8
8
|
const values = _getChainSpecificConstants(chainID, rpcURL);
|
|
9
9
|
return client.readContract({
|
|
@@ -1,11 +1,13 @@
|
|
|
1
1
|
import { http, createPublicClient, createTransport, publicActions, encodeFunctionData, encodePacked, encodeAbiParameters, parseAbiParameters, getContract, concat, keccak256, getContractAddress, getAddress, hashMessage, toHex, hashTypedData, hexToBytes, bytesToHex } from "viem";
|
|
2
2
|
import { createBundlerClient, createPaymasterClient, entryPoint08Abi, getUserOperationHash, toSmartAccount } from "viem/account-abstraction";
|
|
3
|
-
import { _getChainSpecificConstants, ZERO, SIGNATURE_VALIDITY_SECONDS, STUB_VERIFICATION_GAS_PAD, STUB_PRE_VERIFICATION_GAS_PAD } from "../constants.js";
|
|
4
|
-
import { CounterfactualMismatchError } from "../errors.js";
|
|
3
|
+
import { _chainId, _getChainSpecificConstants, ZERO, SIGNATURE_VALIDITY_SECONDS, STUB_VERIFICATION_GAS_PAD, STUB_PRE_VERIFICATION_GAS_PAD } from "../constants.js";
|
|
4
|
+
import { CounterfactualMismatchError, toContractRevertError } from "../errors.js";
|
|
5
5
|
import { DeviceWallet, DeviceWalletFactory } from "../../abis/index.js";
|
|
6
|
-
import {
|
|
6
|
+
import { base64urlnopad } from "@scure/base";
|
|
7
7
|
import { Passkey } from "react-native-passkey";
|
|
8
8
|
import { p256 } from "@noble/curves/nist.js";
|
|
9
|
+
// Authenticators differ on padding and alphabet, so accept either form.
|
|
10
|
+
const fromBase64URL = (value) => base64urlnopad.decode(value.replace(/=+$/, "").replace(/\+/g, "-").replace(/\//g, "_"));
|
|
9
11
|
var AuthenticatorTransport;
|
|
10
12
|
(function (AuthenticatorTransport) {
|
|
11
13
|
AuthenticatorTransport["usb"] = "usb";
|
|
@@ -39,10 +41,7 @@ export const BEACON_PROXY_CREATION_CODE = "0x60a0806040526104e480380380916100178
|
|
|
39
41
|
*/
|
|
40
42
|
export const _stamp = async (credentialId, rpId, payload) => {
|
|
41
43
|
const signingOptions = {
|
|
42
|
-
|
|
43
|
-
// `Uint8Array<ArrayBuffer>` that `fromBuffer` expects (viem's `hexToBytes`
|
|
44
|
-
// is typed over the wider `ArrayBufferLike`).
|
|
45
|
-
challenge: isoBase64URL.fromBuffer(Uint8Array.from(hexToBytes(payload))),
|
|
44
|
+
challenge: base64urlnopad.encode(hexToBytes(payload)),
|
|
46
45
|
allowCredentials: [{
|
|
47
46
|
id: credentialId,
|
|
48
47
|
type: "public-key",
|
|
@@ -69,7 +68,7 @@ export const _stamp = async (credentialId, rpId, payload) => {
|
|
|
69
68
|
}
|
|
70
69
|
const { clientDataJSON, authenticatorData, signature } = authenticationResult.response;
|
|
71
70
|
// 1. Decode clientDataJSON
|
|
72
|
-
const clientDataJSONBuffer =
|
|
71
|
+
const clientDataJSONBuffer = fromBase64URL(clientDataJSON);
|
|
73
72
|
const clientDataJSONString = new TextDecoder().decode(clientDataJSONBuffer);
|
|
74
73
|
// 2. Calculate indices for the contract (byte offsets)
|
|
75
74
|
const typeSearchString = '"type":"webauthn.get"';
|
|
@@ -88,14 +87,10 @@ export const _stamp = async (credentialId, rpId, payload) => {
|
|
|
88
87
|
throw new Error(`Could not find challenge substring '${challengeSearchString}' in clientDataJSON for index calculation.`);
|
|
89
88
|
}
|
|
90
89
|
// 3. Decode authenticatorData
|
|
91
|
-
const authenticatorDataBytes =
|
|
90
|
+
const authenticatorDataBytes = fromBase64URL(authenticatorData);
|
|
92
91
|
const authenticatorDataHex = bytesToHex(authenticatorDataBytes);
|
|
93
92
|
// 4. Decode signature (ASN.1 DER encoded)
|
|
94
|
-
|
|
95
|
-
// let parsedSignature = p256.Signature.fromDER(signatureBytes);
|
|
96
|
-
let parsedSignature = p256.Signature.fromBytes(signatureBytes instanceof Uint8Array
|
|
97
|
-
? signatureBytes
|
|
98
|
-
: new Uint8Array(signatureBytes), "der");
|
|
93
|
+
let parsedSignature = p256.Signature.fromBytes(fromBase64URL(signature), "der");
|
|
99
94
|
// Normalize s
|
|
100
95
|
const n = p256.Point.CURVE().n;
|
|
101
96
|
const halfN = n >> 1n;
|
|
@@ -134,7 +129,7 @@ export const _encodeCalls = async (calls) => {
|
|
|
134
129
|
});
|
|
135
130
|
};
|
|
136
131
|
export const _getFactoryArgs = async (client, deviceUniqueIdentifier, deviceWalletOwnerKey, salt) => {
|
|
137
|
-
const chainID = await client
|
|
132
|
+
const chainID = await _chainId(client);
|
|
138
133
|
const rpcURL = client.transport.url;
|
|
139
134
|
const values = _getChainSpecificConstants(chainID, rpcURL);
|
|
140
135
|
const factoryData = encodeFunctionData({
|
|
@@ -145,7 +140,7 @@ export const _getFactoryArgs = async (client, deviceUniqueIdentifier, deviceWall
|
|
|
145
140
|
return { factory: values.factoryAddresses.DEVICE_WALLET_FACTORY, factoryData };
|
|
146
141
|
};
|
|
147
142
|
export const getInitCodeHash = async (client, deviceUniqueIdentifier, deviceWalletOwnerKey) => {
|
|
148
|
-
const chainID = await client
|
|
143
|
+
const chainID = await _chainId(client);
|
|
149
144
|
const rpcURL = client.transport.url;
|
|
150
145
|
const values = _getChainSpecificConstants(chainID, rpcURL);
|
|
151
146
|
// off-chain computation of the DeviceWallet address
|
|
@@ -176,7 +171,7 @@ export const getInitCodeHash = async (client, deviceUniqueIdentifier, deviceWall
|
|
|
176
171
|
return keccak256(initCode);
|
|
177
172
|
};
|
|
178
173
|
export const getCounterFactualAddress = async (client, deviceUniqueIdentifier, deviceWalletOwnerKey, salt) => {
|
|
179
|
-
const chainID = await client
|
|
174
|
+
const chainID = await _chainId(client);
|
|
180
175
|
const rpcURL = client.transport.url;
|
|
181
176
|
const values = _getChainSpecificConstants(chainID, rpcURL);
|
|
182
177
|
const deviceWalletFactoryAddress = values.factoryAddresses.DEVICE_WALLET_FACTORY;
|
|
@@ -204,20 +199,23 @@ export const getCounterFactualAddress = async (client, deviceUniqueIdentifier, d
|
|
|
204
199
|
* an unconditional check, e.g. right after a contract redeploy.
|
|
205
200
|
*/
|
|
206
201
|
export const _assertCounterfactualMatchesOnChain = async (client, deviceUniqueIdentifier, deviceWalletOwnerKey, salt) => {
|
|
207
|
-
const chainID = await client
|
|
202
|
+
const chainID = await _chainId(client);
|
|
208
203
|
const rpcURL = client.transport.url;
|
|
209
204
|
const values = _getChainSpecificConstants(chainID, rpcURL);
|
|
210
|
-
const offChain = await getCounterFactualAddress(client, deviceUniqueIdentifier, deviceWalletOwnerKey, salt);
|
|
211
205
|
const deviceWalletFactory = getContract({
|
|
212
206
|
abi: DeviceWalletFactory,
|
|
213
207
|
address: values.factoryAddresses.DEVICE_WALLET_FACTORY,
|
|
214
208
|
client,
|
|
215
209
|
});
|
|
216
|
-
//
|
|
217
|
-
const onChain = await
|
|
218
|
-
deviceWalletOwnerKey,
|
|
219
|
-
|
|
220
|
-
|
|
210
|
+
// Neither side needs the other, so both are asked for at once.
|
|
211
|
+
const [offChain, onChain] = await Promise.all([
|
|
212
|
+
getCounterFactualAddress(client, deviceUniqueIdentifier, deviceWalletOwnerKey, salt),
|
|
213
|
+
// on-chain view arg order is (ownerKey, uid, salt) - differs from createAccount
|
|
214
|
+
deviceWalletFactory.read.getCounterFactualAddress([
|
|
215
|
+
deviceWalletOwnerKey,
|
|
216
|
+
deviceUniqueIdentifier,
|
|
217
|
+
salt,
|
|
218
|
+
]),
|
|
221
219
|
]);
|
|
222
220
|
if (getAddress(offChain) !== getAddress(onChain)) {
|
|
223
221
|
throw new CounterfactualMismatchError(getAddress(offChain), getAddress(onChain));
|
|
@@ -293,11 +291,9 @@ export const _signUserOperationHash = async (credentialId, rpId, userOpHash) =>
|
|
|
293
291
|
// same chain skip the extra RPC the drift guard costs.
|
|
294
292
|
const _counterfactualVerifiedChains = new Set();
|
|
295
293
|
export const _getSmartWallet = async (client, credentialId, rpId, deviceUniqueIdentifier, deviceWalletOwnerKey, salt) => {
|
|
296
|
-
const chainID = await client
|
|
294
|
+
const chainID = await _chainId(client);
|
|
297
295
|
const rpcURL = client.transport.url;
|
|
298
296
|
const values = _getChainSpecificConstants(chainID, rpcURL);
|
|
299
|
-
if (!client.account)
|
|
300
|
-
throw new Error('Error: No signer account found with WalletClient');
|
|
301
297
|
const accountAddress = _counterfactualVerifiedChains.has(chainID)
|
|
302
298
|
? await getCounterFactualAddress(client, deviceUniqueIdentifier, deviceWalletOwnerKey, salt)
|
|
303
299
|
: await _assertCounterfactualMatchesOnChain(client, deviceUniqueIdentifier, deviceWalletOwnerKey, salt);
|
|
@@ -385,20 +381,35 @@ const _splitTransport = (pimlicoRpcURL, rpcURL) => {
|
|
|
385
381
|
// RPC has to stay readable here.
|
|
386
382
|
{ url: rpcURL });
|
|
387
383
|
};
|
|
388
|
-
export const _getSmartWalletClient = async (client, pimlicoAPIKey, gasPolicyId, account) => {
|
|
389
|
-
const chainID = await client
|
|
384
|
+
export const _getSmartWalletClient = async (client, pimlicoAPIKey, gasPolicyId, account, bundlerUrl) => {
|
|
385
|
+
const chainID = await _chainId(client);
|
|
390
386
|
const rpcURL = client.transport.url;
|
|
391
387
|
const values = _getChainSpecificConstants(chainID, rpcURL, pimlicoAPIKey);
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
388
|
+
const bundlerURL = bundlerUrl ?? values.pimlicoRpcURL;
|
|
389
|
+
// Pimlico sponsors via ERC-7677 and reads the policy from `sponsorshipPolicyId`.
|
|
390
|
+
// A policy is optional there, so an empty id sends no context at all.
|
|
391
|
+
const paymaster = createPaymasterClient({ transport: http(bundlerURL) });
|
|
392
|
+
const bundlerClient = createBundlerClient({
|
|
395
393
|
account,
|
|
396
394
|
chain: values.chain,
|
|
397
395
|
client: createPublicClient({ chain: values.chain, transport: http(values.rpcURL) }),
|
|
398
|
-
transport: _splitTransport(
|
|
396
|
+
transport: _splitTransport(bundlerURL, values.rpcURL),
|
|
399
397
|
paymaster,
|
|
400
|
-
paymasterContext: {
|
|
401
|
-
// extend() keeps the bundler fields at runtime but drops them from the
|
|
402
|
-
// inferred type, so the result is re-asserted rather than narrowed.
|
|
398
|
+
paymasterContext: gasPolicyId ? { sponsorshipPolicyId: gasPolicyId } : undefined,
|
|
403
399
|
}).extend(publicActions);
|
|
400
|
+
// Every user operation the SDK sends goes through here, so a revert is
|
|
401
|
+
// decoded once for all of them, the same way admin writes are.
|
|
402
|
+
const sendUserOperation = bundlerClient.sendUserOperation;
|
|
403
|
+
// extend() keeps the bundler fields at runtime but drops them from the
|
|
404
|
+
// inferred type, so the result is re-asserted rather than narrowed.
|
|
405
|
+
return bundlerClient.extend(() => ({
|
|
406
|
+
sendUserOperation: (async (args) => {
|
|
407
|
+
try {
|
|
408
|
+
return await sendUserOperation(args);
|
|
409
|
+
}
|
|
410
|
+
catch (err) {
|
|
411
|
+
throw toContractRevertError(err) ?? err;
|
|
412
|
+
}
|
|
413
|
+
}),
|
|
414
|
+
}));
|
|
404
415
|
};
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { _getChainSpecificConstants } from "../constants.js";
|
|
1
|
+
import { _chainId, _getChainSpecificConstants } from "../constants.js";
|
|
2
2
|
import { MissingEOAWalletError, writeContractOrThrow } from "../errors.js";
|
|
3
3
|
import { DeviceWallet } from "../../abis/index.js";
|
|
4
4
|
// Admin-EOA logic targeting a specific `DeviceWallet` instance (its address is
|
|
@@ -14,7 +14,7 @@ import { DeviceWallet } from "../../abis/index.js";
|
|
|
14
14
|
* `toggleAccessToETH`, which the admin EOA cannot reach.
|
|
15
15
|
*/
|
|
16
16
|
export const _deployESIMWallet = async (client, deviceWalletAddress, salt) => {
|
|
17
|
-
const chainID = await client
|
|
17
|
+
const chainID = await _chainId(client);
|
|
18
18
|
const rpcURL = client.transport.url;
|
|
19
19
|
const values = _getChainSpecificConstants(chainID, rpcURL);
|
|
20
20
|
if (!client.account)
|
|
@@ -22,7 +22,7 @@ export const _deployESIMWallet = async (client, deviceWalletAddress, salt) => {
|
|
|
22
22
|
return writeContractOrThrow(client, {
|
|
23
23
|
address: deviceWalletAddress,
|
|
24
24
|
chain: values.chain,
|
|
25
|
-
account: client.account
|
|
25
|
+
account: client.account,
|
|
26
26
|
abi: DeviceWallet,
|
|
27
27
|
functionName: 'deployESIMWallet',
|
|
28
28
|
args: [false, salt]
|
|
@@ -36,7 +36,7 @@ export const _deployESIMWallet = async (client, deviceWalletAddress, salt) => {
|
|
|
36
36
|
* out, and topping one up is not a way to reach its funds.
|
|
37
37
|
*/
|
|
38
38
|
export const _addDeposit = async (client, deviceWalletAddress, amount) => {
|
|
39
|
-
const chainID = await client
|
|
39
|
+
const chainID = await _chainId(client);
|
|
40
40
|
const rpcURL = client.transport.url;
|
|
41
41
|
const values = _getChainSpecificConstants(chainID, rpcURL);
|
|
42
42
|
if (!client.account)
|
|
@@ -44,7 +44,7 @@ export const _addDeposit = async (client, deviceWalletAddress, amount) => {
|
|
|
44
44
|
return writeContractOrThrow(client, {
|
|
45
45
|
address: deviceWalletAddress,
|
|
46
46
|
chain: values.chain,
|
|
47
|
-
account: client.account
|
|
47
|
+
account: client.account,
|
|
48
48
|
abi: DeviceWallet,
|
|
49
49
|
functionName: 'addDeposit',
|
|
50
50
|
args: [],
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { _getChainSpecificConstants } from "../constants.js";
|
|
1
|
+
import { _chainId, _getChainSpecificConstants } from "../constants.js";
|
|
2
2
|
import { MissingEOAWalletError, writeContractOrThrow } from "../errors.js";
|
|
3
3
|
import { DeviceWalletFactory } from "../../abis/index.js";
|
|
4
4
|
// Admin-EOA logic for `DeviceWalletFactory`.
|
|
@@ -19,7 +19,7 @@ import { DeviceWalletFactory } from "../../abis/index.js";
|
|
|
19
19
|
* is drawn; any surplus is refunded to the caller on chain.
|
|
20
20
|
*/
|
|
21
21
|
export const _deployDeviceWalletForUsers = async (client, deviceUniqueIdentifiers, deviceWalletOwnersKey, salts, depositAmounts, value) => {
|
|
22
|
-
const chainID = await client
|
|
22
|
+
const chainID = await _chainId(client);
|
|
23
23
|
const rpcURL = client.transport.url;
|
|
24
24
|
const values = _getChainSpecificConstants(chainID, rpcURL);
|
|
25
25
|
if (!client.account)
|
|
@@ -27,7 +27,7 @@ export const _deployDeviceWalletForUsers = async (client, deviceUniqueIdentifier
|
|
|
27
27
|
return writeContractOrThrow(client, {
|
|
28
28
|
address: values.factoryAddresses.DEVICE_WALLET_FACTORY,
|
|
29
29
|
chain: values.chain,
|
|
30
|
-
account: client.account
|
|
30
|
+
account: client.account,
|
|
31
31
|
abi: DeviceWalletFactory,
|
|
32
32
|
functionName: 'deployDeviceWalletForUsers',
|
|
33
33
|
args: [deviceUniqueIdentifiers, deviceWalletOwnersKey, salts, depositAmounts],
|
|
@@ -40,7 +40,7 @@ export const _deployDeviceWalletForUsers = async (client, deviceUniqueIdentifier
|
|
|
40
40
|
* factory rederives the counterfactual address from it to check the wallet.
|
|
41
41
|
*/
|
|
42
42
|
export const _postCreateAccount = async (client, deviceWallet, deviceUniqueIdentifier, deviceWalletOwnerKey, salt) => {
|
|
43
|
-
const chainID = await client
|
|
43
|
+
const chainID = await _chainId(client);
|
|
44
44
|
const rpcURL = client.transport.url;
|
|
45
45
|
const values = _getChainSpecificConstants(chainID, rpcURL);
|
|
46
46
|
if (!client.account)
|
|
@@ -48,7 +48,7 @@ export const _postCreateAccount = async (client, deviceWallet, deviceUniqueIdent
|
|
|
48
48
|
return writeContractOrThrow(client, {
|
|
49
49
|
address: values.factoryAddresses.DEVICE_WALLET_FACTORY,
|
|
50
50
|
chain: values.chain,
|
|
51
|
-
account: client.account
|
|
51
|
+
account: client.account,
|
|
52
52
|
abi: DeviceWalletFactory,
|
|
53
53
|
functionName: 'postCreateAccount',
|
|
54
54
|
args: [deviceWallet, deviceUniqueIdentifier, deviceWalletOwnerKey, salt]
|
|
@@ -56,7 +56,7 @@ export const _postCreateAccount = async (client, deviceWallet, deviceUniqueIdent
|
|
|
56
56
|
};
|
|
57
57
|
/** One-time wiring of the registry into the factory. `onlyAdmin`. */
|
|
58
58
|
export const _addRegistryAddress = async (client, registryContractAddress) => {
|
|
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
|
if (!client.account)
|
|
@@ -64,7 +64,7 @@ export const _addRegistryAddress = async (client, registryContractAddress) => {
|
|
|
64
64
|
return writeContractOrThrow(client, {
|
|
65
65
|
address: values.factoryAddresses.DEVICE_WALLET_FACTORY,
|
|
66
66
|
chain: values.chain,
|
|
67
|
-
account: client.account
|
|
67
|
+
account: client.account,
|
|
68
68
|
abi: DeviceWalletFactory,
|
|
69
69
|
functionName: 'addRegistryAddress',
|
|
70
70
|
args: [registryContractAddress]
|
|
@@ -72,7 +72,7 @@ export const _addRegistryAddress = async (client, registryContractAddress) => {
|
|
|
72
72
|
};
|
|
73
73
|
/** Point the device-wallet beacon at a new implementation. `onlyOwner` (upgradeManager). */
|
|
74
74
|
export const _updateDeviceWalletImplementation = async (client, newDeviceImpl) => {
|
|
75
|
-
const chainID = await client
|
|
75
|
+
const chainID = await _chainId(client);
|
|
76
76
|
const rpcURL = client.transport.url;
|
|
77
77
|
const values = _getChainSpecificConstants(chainID, rpcURL);
|
|
78
78
|
if (!client.account)
|
|
@@ -80,7 +80,7 @@ export const _updateDeviceWalletImplementation = async (client, newDeviceImpl) =
|
|
|
80
80
|
return writeContractOrThrow(client, {
|
|
81
81
|
address: values.factoryAddresses.DEVICE_WALLET_FACTORY,
|
|
82
82
|
chain: values.chain,
|
|
83
|
-
account: client.account
|
|
83
|
+
account: client.account,
|
|
84
84
|
abi: DeviceWalletFactory,
|
|
85
85
|
functionName: 'updateDeviceWalletImplementation',
|
|
86
86
|
args: [newDeviceImpl]
|
|
@@ -100,7 +100,7 @@ export const _updateDeviceWalletImplementation = async (client, newDeviceImpl) =
|
|
|
100
100
|
* it, so the new owner can move every deployed device wallet at once.
|
|
101
101
|
*/
|
|
102
102
|
export const _transferOwnershipCall = async (client, newOwner) => {
|
|
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 {
|
|
@@ -119,7 +119,7 @@ export const _transferOwnershipCall = async (client, newOwner) => {
|
|
|
119
119
|
* instead. Changing what the factory deploys next is a beacon update, not this.
|
|
120
120
|
*/
|
|
121
121
|
export const _upgradeCall = async (client, newImplementation, data = '0x') => {
|
|
122
|
-
const chainID = await client
|
|
122
|
+
const chainID = await _chainId(client);
|
|
123
123
|
const rpcURL = client.transport.url;
|
|
124
124
|
const values = _getChainSpecificConstants(chainID, rpcURL);
|
|
125
125
|
return {
|
|
@@ -138,7 +138,7 @@ export const _upgradeCall = async (client, newImplementation, data = '0x') => {
|
|
|
138
138
|
* at once.
|
|
139
139
|
*/
|
|
140
140
|
export const _acceptOwnership = async (client) => {
|
|
141
|
-
const chainID = await client
|
|
141
|
+
const chainID = await _chainId(client);
|
|
142
142
|
const rpcURL = client.transport.url;
|
|
143
143
|
const values = _getChainSpecificConstants(chainID, rpcURL);
|
|
144
144
|
if (!client.account)
|
|
@@ -146,7 +146,7 @@ export const _acceptOwnership = async (client) => {
|
|
|
146
146
|
return writeContractOrThrow(client, {
|
|
147
147
|
address: values.factoryAddresses.DEVICE_WALLET_FACTORY,
|
|
148
148
|
chain: values.chain,
|
|
149
|
-
account: client.account
|
|
149
|
+
account: client.account,
|
|
150
150
|
abi: DeviceWalletFactory,
|
|
151
151
|
functionName: 'acceptOwnership',
|
|
152
152
|
args: []
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { _getChainSpecificConstants } from "../constants.js";
|
|
1
|
+
import { _chainId, _getChainSpecificConstants } from "../constants.js";
|
|
2
2
|
import { MissingEOAWalletError, writeContractOrThrow } from "../errors.js";
|
|
3
3
|
import { ESIMWallet } from "../../abis/index.js";
|
|
4
4
|
// Admin-EOA logic targeting a specific `ESIMWallet` instance (address passed in).
|
|
@@ -14,7 +14,7 @@ import { ESIMWallet } from "../../abis/index.js";
|
|
|
14
14
|
* spendable once per eSIM wallet.
|
|
15
15
|
*/
|
|
16
16
|
export const _buyDataBundleWithToken = async (client, eSIMWalletAddress, dataBundleDetails, asset, maxAmountIn, paymentReference) => {
|
|
17
|
-
const chainID = await client
|
|
17
|
+
const chainID = await _chainId(client);
|
|
18
18
|
const rpcURL = client.transport.url;
|
|
19
19
|
const values = _getChainSpecificConstants(chainID, rpcURL);
|
|
20
20
|
if (!client.account)
|
|
@@ -22,7 +22,7 @@ export const _buyDataBundleWithToken = async (client, eSIMWalletAddress, dataBun
|
|
|
22
22
|
return writeContractOrThrow(client, {
|
|
23
23
|
address: eSIMWalletAddress,
|
|
24
24
|
chain: values.chain,
|
|
25
|
-
account: client.account
|
|
25
|
+
account: client.account,
|
|
26
26
|
abi: ESIMWallet,
|
|
27
27
|
functionName: 'buyDataBundleWithToken',
|
|
28
28
|
args: [dataBundleDetails, asset, maxAmountIn, paymentReference]
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { _getChainSpecificConstants } from "../constants.js";
|
|
1
|
+
import { _chainId, _getChainSpecificConstants } from "../constants.js";
|
|
2
2
|
import { MissingEOAWalletError, writeContractOrThrow } from "../errors.js";
|
|
3
3
|
import { ESIMWalletFactory } from "../../abis/index.js";
|
|
4
4
|
// Admin-EOA logic for `ESIMWalletFactory`. Both functions are owner-gated
|
|
@@ -14,7 +14,7 @@ import { ESIMWalletFactory } from "../../abis/index.js";
|
|
|
14
14
|
// `onlyRegistryOrDeviceWalletFactoryOrDeviceWallet`, so a bare EOA always reverts.
|
|
15
15
|
/** One-time wiring of the registry into the eSIM factory. Owner only. */
|
|
16
16
|
export const _addRegistryAddress = async (client, registryContractAddress) => {
|
|
17
|
-
const chainID = await client
|
|
17
|
+
const chainID = await _chainId(client);
|
|
18
18
|
const rpcURL = client.transport.url;
|
|
19
19
|
const values = _getChainSpecificConstants(chainID, rpcURL);
|
|
20
20
|
if (!client.account)
|
|
@@ -22,7 +22,7 @@ export const _addRegistryAddress = async (client, registryContractAddress) => {
|
|
|
22
22
|
return writeContractOrThrow(client, {
|
|
23
23
|
address: values.factoryAddresses.ESIM_WALLET_FACTORY,
|
|
24
24
|
chain: values.chain,
|
|
25
|
-
account: client.account
|
|
25
|
+
account: client.account,
|
|
26
26
|
abi: ESIMWalletFactory,
|
|
27
27
|
functionName: 'addRegistryAddress',
|
|
28
28
|
args: [registryContractAddress]
|
|
@@ -30,7 +30,7 @@ export const _addRegistryAddress = async (client, registryContractAddress) => {
|
|
|
30
30
|
};
|
|
31
31
|
/** Point the eSIM-wallet beacon at a new implementation. `onlyOwner`. */
|
|
32
32
|
export const _updateESIMWalletImplementation = async (client, eSIMWalletImpl) => {
|
|
33
|
-
const chainID = await client
|
|
33
|
+
const chainID = await _chainId(client);
|
|
34
34
|
const rpcURL = client.transport.url;
|
|
35
35
|
const values = _getChainSpecificConstants(chainID, rpcURL);
|
|
36
36
|
if (!client.account)
|
|
@@ -38,7 +38,7 @@ export const _updateESIMWalletImplementation = async (client, eSIMWalletImpl) =>
|
|
|
38
38
|
return writeContractOrThrow(client, {
|
|
39
39
|
address: values.factoryAddresses.ESIM_WALLET_FACTORY,
|
|
40
40
|
chain: values.chain,
|
|
41
|
-
account: client.account
|
|
41
|
+
account: client.account,
|
|
42
42
|
abi: ESIMWalletFactory,
|
|
43
43
|
functionName: 'updateESIMWalletImplementation',
|
|
44
44
|
args: [eSIMWalletImpl]
|
|
@@ -58,7 +58,7 @@ export const _updateESIMWalletImplementation = async (client, eSIMWalletImpl) =>
|
|
|
58
58
|
* it, so the new owner can move every deployed eSIM wallet at once.
|
|
59
59
|
*/
|
|
60
60
|
export const _transferOwnershipCall = async (client, newOwner) => {
|
|
61
|
-
const chainID = await client
|
|
61
|
+
const chainID = await _chainId(client);
|
|
62
62
|
const rpcURL = client.transport.url;
|
|
63
63
|
const values = _getChainSpecificConstants(chainID, rpcURL);
|
|
64
64
|
return {
|
|
@@ -76,7 +76,7 @@ export const _transferOwnershipCall = async (client, newOwner) => {
|
|
|
76
76
|
* the beacon, which moves through `updateESIMWalletImplementation` instead.
|
|
77
77
|
*/
|
|
78
78
|
export const _upgradeCall = async (client, newImplementation, data = '0x') => {
|
|
79
|
-
const chainID = await client
|
|
79
|
+
const chainID = await _chainId(client);
|
|
80
80
|
const rpcURL = client.transport.url;
|
|
81
81
|
const values = _getChainSpecificConstants(chainID, rpcURL);
|
|
82
82
|
return {
|
|
@@ -95,7 +95,7 @@ export const _upgradeCall = async (client, newImplementation, data = '0x') => {
|
|
|
95
95
|
* at once.
|
|
96
96
|
*/
|
|
97
97
|
export const _acceptOwnership = async (client) => {
|
|
98
|
-
const chainID = await client
|
|
98
|
+
const chainID = await _chainId(client);
|
|
99
99
|
const rpcURL = client.transport.url;
|
|
100
100
|
const values = _getChainSpecificConstants(chainID, rpcURL);
|
|
101
101
|
if (!client.account)
|
|
@@ -103,7 +103,7 @@ export const _acceptOwnership = async (client) => {
|
|
|
103
103
|
return writeContractOrThrow(client, {
|
|
104
104
|
address: values.factoryAddresses.ESIM_WALLET_FACTORY,
|
|
105
105
|
chain: values.chain,
|
|
106
|
-
account: client.account
|
|
106
|
+
account: client.account,
|
|
107
107
|
abi: ESIMWalletFactory,
|
|
108
108
|
functionName: 'acceptOwnership',
|
|
109
109
|
args: []
|