kokio-sdk 1.0.0 → 2.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +68 -19
- package/dist/esm/abis/BeaconProxy.js +30 -46
- package/dist/esm/abis/DeviceWallet.js +546 -535
- package/dist/esm/abis/DeviceWalletFactory.js +537 -544
- package/dist/esm/abis/ESIMWallet.js +440 -299
- package/dist/esm/abis/ESIMWalletFactory.js +372 -289
- package/dist/esm/abis/LazyWalletRegistry.js +941 -421
- package/dist/esm/abis/P256Verifier.js +29 -29
- package/dist/esm/abis/ProtocolAdmin.js +1228 -0
- package/dist/esm/abis/Registry.js +1207 -466
- package/dist/esm/abis/RegistryHelper.js +414 -20
- package/dist/esm/abis/index.js +2 -1
- package/dist/esm/admin/config-admin.js +24 -0
- package/dist/esm/admin/interface/deviceWalletClass.js +27 -6
- package/dist/esm/admin/interface/deviceWalletFactoryClass.js +41 -19
- package/dist/esm/admin/interface/eSIMWalletClass.js +10 -1
- package/dist/esm/admin/interface/eSIMWalletFactoryClass.js +24 -2
- package/dist/esm/admin/interface/lazyWalletRegistryClass.js +83 -4
- package/dist/esm/admin/interface/protocolAdminClass.js +195 -0
- package/dist/esm/admin/interface/registryClass.js +93 -2
- package/dist/esm/config.js +42 -7
- package/dist/esm/interface/deviceWalletClass.js +45 -5
- package/dist/esm/interface/deviceWalletFactoryClass.js +20 -1
- package/dist/esm/interface/eSIMWalletClass.js +12 -3
- package/dist/esm/interface/registryClass.js +47 -0
- package/dist/esm/interface/smartAccountClass.js +2 -4
- package/dist/esm/logic/account-kit/createSmartAccount.js +156 -102
- package/dist/esm/logic/admin/deviceWallet.eoa.js +23 -12
- package/dist/esm/logic/admin/deviceWalletFactory.eoa.js +63 -42
- package/dist/esm/logic/admin/eSIMWallet.eoa.js +3 -5
- package/dist/esm/logic/admin/eSIMWalletFactory.eoa.js +76 -8
- package/dist/esm/logic/admin/lazyWalletRegistry.eoa.js +330 -19
- package/dist/esm/logic/admin/protocolAdmin.eoa.js +524 -0
- package/dist/esm/logic/admin/reads/deviceWallet.reads.js +82 -7
- package/dist/esm/logic/admin/reads/deviceWalletFactory.reads.js +82 -23
- package/dist/esm/logic/admin/reads/eSIMWallet.reads.js +50 -6
- package/dist/esm/logic/admin/reads/eSIMWalletFactory.reads.js +63 -5
- package/dist/esm/logic/admin/reads/lazyWalletRegistry.reads.js +171 -10
- package/dist/esm/logic/admin/reads/protocolAdmin.reads.js +154 -0
- package/dist/esm/logic/admin/reads/registry.reads.js +289 -9
- package/dist/esm/logic/admin/registry.eoa.js +274 -4
- package/dist/esm/logic/constants.js +53 -26
- package/dist/esm/logic/deviceWallet.js +224 -31
- package/dist/esm/logic/deviceWalletFactory.js +89 -0
- package/dist/esm/logic/eSIMWallet.js +113 -43
- package/dist/esm/logic/eSIMWalletFactory.js +8 -8
- package/dist/esm/logic/errors.js +64 -0
- package/dist/esm/logic/registry.js +236 -0
- package/dist/esm/logic/utils.js +2 -1
- package/dist/types/abis/BeaconProxy.d.ts +21 -33
- package/dist/types/abis/DeviceWallet.d.ts +372 -365
- package/dist/types/abis/DeviceWalletFactory.d.ts +438 -448
- package/dist/types/abis/ESIMWallet.d.ts +352 -245
- package/dist/types/abis/ESIMWalletFactory.d.ts +278 -216
- package/dist/types/abis/LazyWalletRegistry.d.ts +710 -317
- package/dist/types/abis/P256Verifier.d.ts +16 -16
- package/dist/types/abis/ProtocolAdmin.d.ts +947 -0
- package/dist/types/abis/Registry.d.ts +960 -393
- package/dist/types/abis/RegistryHelper.d.ts +317 -16
- package/dist/types/abis/index.d.ts +2 -1
- package/dist/types/admin/config-admin.d.ts +16 -0
- package/dist/types/admin/interface/deviceWalletClass.d.ts +10 -3
- package/dist/types/admin/interface/deviceWalletFactoryClass.d.ts +14 -7
- package/dist/types/admin/interface/eSIMWalletClass.d.ts +3 -0
- package/dist/types/admin/interface/eSIMWalletFactoryClass.d.ts +8 -1
- package/dist/types/admin/interface/lazyWalletRegistryClass.d.ts +38 -2
- package/dist/types/admin/interface/protocolAdminClass.d.ts +95 -0
- package/dist/types/admin/interface/registryClass.d.ts +30 -0
- package/dist/types/config.d.ts +26 -5
- package/dist/types/interface/P256VerifierClass.d.ts +3 -4
- package/dist/types/interface/constantsClass.d.ts +2 -2
- package/dist/types/interface/deviceWalletClass.d.ts +22 -2569
- package/dist/types/interface/deviceWalletFactoryClass.d.ts +10 -2564
- package/dist/types/interface/eSIMWalletClass.d.ts +11 -8
- package/dist/types/interface/eSIMWalletFactoryClass.d.ts +5 -2565
- package/dist/types/interface/registryClass.d.ts +19 -0
- package/dist/types/interface/smartAccountClass.d.ts +6 -2568
- package/dist/types/logic/P256Verifier.d.ts +2 -2
- package/dist/types/logic/account-kit/createSmartAccount.d.ts +43 -19
- package/dist/types/logic/admin/deviceWallet.eoa.d.ts +15 -9
- package/dist/types/logic/admin/deviceWalletFactory.eoa.d.ts +34 -23
- package/dist/types/logic/admin/eSIMWallet.eoa.d.ts +0 -5
- package/dist/types/logic/admin/eSIMWalletFactory.eoa.d.ts +27 -9
- package/dist/types/logic/admin/lazyWalletRegistry.eoa.d.ts +102 -10
- package/dist/types/logic/admin/protocolAdmin.eoa.d.ts +163 -0
- package/dist/types/logic/admin/reads/deviceWallet.reads.d.ts +28 -8
- package/dist/types/logic/admin/reads/deviceWalletFactory.reads.d.ts +45 -14
- package/dist/types/logic/admin/reads/eSIMWallet.reads.d.ts +25 -6
- package/dist/types/logic/admin/reads/eSIMWalletFactory.reads.d.ts +21 -6
- package/dist/types/logic/admin/reads/lazyWalletRegistry.reads.d.ts +44 -11
- package/dist/types/logic/admin/reads/protocolAdmin.reads.d.ts +53 -0
- package/dist/types/logic/admin/reads/registry.reads.d.ts +105 -9
- package/dist/types/logic/admin/registry.eoa.d.ts +102 -5
- package/dist/types/logic/constants.d.ts +2 -0
- package/dist/types/logic/deviceWallet.d.ts +78 -6
- package/dist/types/logic/deviceWalletFactory.d.ts +32 -3
- package/dist/types/logic/eSIMWallet.d.ts +48 -7
- package/dist/types/logic/eSIMWalletFactory.d.ts +3 -3
- package/dist/types/logic/errors.d.ts +45 -0
- package/dist/types/logic/registry.d.ts +78 -0
- package/dist/types/types-export.d.ts +1 -1
- package/dist/types/types.d.ts +111 -1
- package/package.json +11 -13
- package/dist/esm/interface/lazyWalletRegistryClass.js +0 -10
- package/dist/esm/logic/lazyWalletRegistry.js +0 -19
- package/dist/types/interface/lazyWalletRegistryClass.d.ts +0 -6
- package/dist/types/logic/lazyWalletRegistry.d.ts +0 -2
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { _addESIMWallet, _getOwner, _getVaultAddress, _removeESIMWallet, _toggleAccessToETH } from "../logic/deviceWallet.js";
|
|
1
|
+
import { _addDeposit, _addESIMWallet, _canPullETH, _deviceUniqueIdentifier, _entryPoint, _eSIMWalletFactory, _getDeposit, _getOwner, _getVaultAddress, _isValidESIMWallet, _isValidSignature, _registry, _removeESIMWallet, _sendUserOperation, _toggleAccessToETH, _transferOwnership, _verifier, _withdrawDepositTo } from "../logic/deviceWallet.js";
|
|
2
2
|
export class DeviceWalletSubPackage {
|
|
3
3
|
smartAccountClient;
|
|
4
4
|
walletClient;
|
|
@@ -8,19 +8,59 @@ export class DeviceWalletSubPackage {
|
|
|
8
8
|
this.walletClient = walletClient;
|
|
9
9
|
this.address = address;
|
|
10
10
|
}
|
|
11
|
-
|
|
12
|
-
return
|
|
11
|
+
sendUserOperation(calls) {
|
|
12
|
+
return _sendUserOperation(this.smartAccountClient, calls);
|
|
13
|
+
}
|
|
14
|
+
addDeposit(amount) {
|
|
15
|
+
return _addDeposit(this.smartAccountClient, this.address, amount);
|
|
16
|
+
}
|
|
17
|
+
addESIMWallet(eSIMWalletAddress) {
|
|
18
|
+
return _addESIMWallet(this.smartAccountClient, this.address, eSIMWalletAddress);
|
|
13
19
|
}
|
|
14
20
|
getVaultAddress() {
|
|
15
21
|
return _getVaultAddress(this.smartAccountClient, this.address);
|
|
16
22
|
}
|
|
17
|
-
removeESIMWallet(eSIMWalletAddress,
|
|
18
|
-
return _removeESIMWallet(this.smartAccountClient, this.address, eSIMWalletAddress,
|
|
23
|
+
removeESIMWallet(eSIMWalletAddress, callBackETH) {
|
|
24
|
+
return _removeESIMWallet(this.smartAccountClient, this.address, eSIMWalletAddress, callBackETH);
|
|
19
25
|
}
|
|
20
26
|
toggleAccessToETH(eSIMWalletAddress, hasAccessToETH) {
|
|
21
27
|
return _toggleAccessToETH(this.smartAccountClient, this.address, eSIMWalletAddress, hasAccessToETH);
|
|
22
28
|
}
|
|
29
|
+
transferOwnership(newOwner) {
|
|
30
|
+
return _transferOwnership(this.smartAccountClient, this.address, newOwner);
|
|
31
|
+
}
|
|
32
|
+
withdrawDepositTo(withdrawAddress, amount) {
|
|
33
|
+
return _withdrawDepositTo(this.smartAccountClient, this.address, withdrawAddress, amount);
|
|
34
|
+
}
|
|
35
|
+
// Reads
|
|
36
|
+
canPullETH(eSIMWalletAddress) {
|
|
37
|
+
return _canPullETH(this.smartAccountClient, this.address, eSIMWalletAddress);
|
|
38
|
+
}
|
|
39
|
+
deviceUniqueIdentifier() {
|
|
40
|
+
return _deviceUniqueIdentifier(this.smartAccountClient, this.address);
|
|
41
|
+
}
|
|
42
|
+
entryPoint() {
|
|
43
|
+
return _entryPoint(this.smartAccountClient, this.address);
|
|
44
|
+
}
|
|
45
|
+
eSIMWalletFactory() {
|
|
46
|
+
return _eSIMWalletFactory(this.smartAccountClient, this.address);
|
|
47
|
+
}
|
|
48
|
+
getDeposit() {
|
|
49
|
+
return _getDeposit(this.smartAccountClient, this.address);
|
|
50
|
+
}
|
|
23
51
|
getOwner() {
|
|
24
52
|
return _getOwner(this.walletClient, this.address);
|
|
25
53
|
}
|
|
54
|
+
isValidESIMWallet(eSIMWalletAddress) {
|
|
55
|
+
return _isValidESIMWallet(this.smartAccountClient, this.address, eSIMWalletAddress);
|
|
56
|
+
}
|
|
57
|
+
isValidSignature(messageHash, signature) {
|
|
58
|
+
return _isValidSignature(this.smartAccountClient, this.address, messageHash, signature);
|
|
59
|
+
}
|
|
60
|
+
registry() {
|
|
61
|
+
return _registry(this.smartAccountClient, this.address);
|
|
62
|
+
}
|
|
63
|
+
verifier() {
|
|
64
|
+
return _verifier(this.smartAccountClient, this.address);
|
|
65
|
+
}
|
|
26
66
|
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { _createAccountWithEOA, _getAddress, _getCurrentDeviceWalletImplementation } from "../logic/deviceWalletFactory.js";
|
|
1
|
+
import { _createAccountWithEOA, _getAddress, _getCurrentDeviceWalletImplementation, _preCreateAccountValidation, _deviceWalletInfoAdded, _beacon, _registry, _entryPoint, _verifier } from "../logic/deviceWalletFactory.js";
|
|
2
2
|
export class DeviceWalletFactorySubPackage {
|
|
3
3
|
smartAccountClient;
|
|
4
4
|
walletClient;
|
|
@@ -15,4 +15,23 @@ export class DeviceWalletFactorySubPackage {
|
|
|
15
15
|
getCurrentDeviceWalletImplementation() {
|
|
16
16
|
return _getCurrentDeviceWalletImplementation(this.smartAccountClient);
|
|
17
17
|
}
|
|
18
|
+
// Reads
|
|
19
|
+
preCreateAccountValidation(deviceUniqueIdentifier, deviceWalletOwnerKey) {
|
|
20
|
+
return _preCreateAccountValidation(this.smartAccountClient, deviceUniqueIdentifier, deviceWalletOwnerKey);
|
|
21
|
+
}
|
|
22
|
+
deviceWalletInfoAdded(deviceWallet) {
|
|
23
|
+
return _deviceWalletInfoAdded(this.smartAccountClient, deviceWallet);
|
|
24
|
+
}
|
|
25
|
+
beacon() {
|
|
26
|
+
return _beacon(this.smartAccountClient);
|
|
27
|
+
}
|
|
28
|
+
registry() {
|
|
29
|
+
return _registry(this.smartAccountClient);
|
|
30
|
+
}
|
|
31
|
+
entryPoint() {
|
|
32
|
+
return _entryPoint(this.smartAccountClient);
|
|
33
|
+
}
|
|
34
|
+
verifier() {
|
|
35
|
+
return _verifier(this.smartAccountClient);
|
|
36
|
+
}
|
|
18
37
|
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { _acceptOwnershipTransfer, _buyDataBundle, _owner, _requestTransferOwnership, _sendETHToDeviceWallet,
|
|
1
|
+
import { _acceptOwnershipTransfer, _buyDataBundle, _dataBundlePriceCap, _deviceWallet, _owner, _requestTransferOwnership, _sendETHToDeviceWallet, _setDataBundlePriceCap, _transactionHistory } from "../logic/eSIMWallet.js";
|
|
2
2
|
export class ESIMWalletSubPackage {
|
|
3
3
|
client;
|
|
4
4
|
address;
|
|
@@ -12,6 +12,12 @@ export class ESIMWalletSubPackage {
|
|
|
12
12
|
buyDataBundle(dataBundleDetails) {
|
|
13
13
|
return _buyDataBundle(this.client, this.address, dataBundleDetails);
|
|
14
14
|
}
|
|
15
|
+
dataBundlePriceCap() {
|
|
16
|
+
return _dataBundlePriceCap(this.client, this.address);
|
|
17
|
+
}
|
|
18
|
+
deviceWallet() {
|
|
19
|
+
return _deviceWallet(this.client, this.address);
|
|
20
|
+
}
|
|
15
21
|
owner() {
|
|
16
22
|
return _owner(this.client, this.address);
|
|
17
23
|
}
|
|
@@ -21,7 +27,10 @@ export class ESIMWalletSubPackage {
|
|
|
21
27
|
sendETHToDeviceWallet(amount) {
|
|
22
28
|
return _sendETHToDeviceWallet(this.client, this.address, amount);
|
|
23
29
|
}
|
|
24
|
-
|
|
25
|
-
return
|
|
30
|
+
setDataBundlePriceCap(cap) {
|
|
31
|
+
return _setDataBundlePriceCap(this.client, this.address, cap);
|
|
32
|
+
}
|
|
33
|
+
transactionHistory(index) {
|
|
34
|
+
return _transactionHistory(this.client, this.address, index);
|
|
26
35
|
}
|
|
27
36
|
}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import { _bindESIMWallet, _toggleESIMWalletStandbyStatus, _isDeviceIdentifierAlreadyUsed, _paused, _requireNotPaused, _isESIMWalletValid, _isESIMWalletOnStandby, _isDeviceWalletValid, _uniqueIdentifierToDeviceWallet, _isESIMIdentifierClaimed, _eSIMWalletForIdentifier, _defaultDataBundlePriceCap, _requireDeviceIdentifierNotReserved } from "../logic/registry.js";
|
|
2
|
+
export class RegistrySubPackage {
|
|
3
|
+
client;
|
|
4
|
+
constructor(client) {
|
|
5
|
+
this.client = client;
|
|
6
|
+
}
|
|
7
|
+
bindESIMWallet(eSIMWalletAddress) {
|
|
8
|
+
return _bindESIMWallet(this.client, eSIMWalletAddress);
|
|
9
|
+
}
|
|
10
|
+
toggleESIMWalletStandbyStatus(eSIMWalletAddress, isOnStandby) {
|
|
11
|
+
return _toggleESIMWalletStandbyStatus(this.client, eSIMWalletAddress, isOnStandby);
|
|
12
|
+
}
|
|
13
|
+
// Reads
|
|
14
|
+
isDeviceIdentifierAlreadyUsed(deviceUniqueIdentifier) {
|
|
15
|
+
return _isDeviceIdentifierAlreadyUsed(this.client, deviceUniqueIdentifier);
|
|
16
|
+
}
|
|
17
|
+
paused() {
|
|
18
|
+
return _paused(this.client);
|
|
19
|
+
}
|
|
20
|
+
requireNotPaused() {
|
|
21
|
+
return _requireNotPaused(this.client);
|
|
22
|
+
}
|
|
23
|
+
isESIMWalletValid(eSIMWalletAddress) {
|
|
24
|
+
return _isESIMWalletValid(this.client, eSIMWalletAddress);
|
|
25
|
+
}
|
|
26
|
+
isESIMWalletOnStandby(eSIMWalletAddress) {
|
|
27
|
+
return _isESIMWalletOnStandby(this.client, eSIMWalletAddress);
|
|
28
|
+
}
|
|
29
|
+
isDeviceWalletValid(deviceWalletAddress) {
|
|
30
|
+
return _isDeviceWalletValid(this.client, deviceWalletAddress);
|
|
31
|
+
}
|
|
32
|
+
uniqueIdentifierToDeviceWallet(deviceUniqueIdentifier) {
|
|
33
|
+
return _uniqueIdentifierToDeviceWallet(this.client, deviceUniqueIdentifier);
|
|
34
|
+
}
|
|
35
|
+
isESIMIdentifierClaimed(eSIMUniqueIdentifier) {
|
|
36
|
+
return _isESIMIdentifierClaimed(this.client, eSIMUniqueIdentifier);
|
|
37
|
+
}
|
|
38
|
+
eSIMWalletForIdentifier(eSIMUniqueIdentifier) {
|
|
39
|
+
return _eSIMWalletForIdentifier(this.client, eSIMUniqueIdentifier);
|
|
40
|
+
}
|
|
41
|
+
defaultDataBundlePriceCap() {
|
|
42
|
+
return _defaultDataBundlePriceCap(this.client);
|
|
43
|
+
}
|
|
44
|
+
requireDeviceIdentifierNotReserved(deviceUniqueIdentifier) {
|
|
45
|
+
return _requireDeviceIdentifierNotReserved(this.client, deviceUniqueIdentifier);
|
|
46
|
+
}
|
|
47
|
+
}
|
|
@@ -3,19 +3,17 @@ export class SmartAccountSubPackage {
|
|
|
3
3
|
client;
|
|
4
4
|
credentialId;
|
|
5
5
|
rpId;
|
|
6
|
-
organizationId;
|
|
7
6
|
pimlicoAPIKey;
|
|
8
7
|
gasPolicyId;
|
|
9
|
-
constructor(client, credentialId, rpId,
|
|
8
|
+
constructor(client, credentialId, rpId, pimlicoAPIKey, gasPolicyId) {
|
|
10
9
|
this.client = client;
|
|
11
10
|
this.credentialId = credentialId;
|
|
12
11
|
this.rpId = rpId;
|
|
13
|
-
this.organizationId = organiationId;
|
|
14
12
|
this.pimlicoAPIKey = pimlicoAPIKey;
|
|
15
13
|
this.gasPolicyId = gasPolicyId;
|
|
16
14
|
}
|
|
17
15
|
getSmartWallet(deviceUniqueIdentifier, deviceWalletOwnerKey, salt) {
|
|
18
|
-
return _getSmartWallet(this.client, this.credentialId, this.rpId,
|
|
16
|
+
return _getSmartWallet(this.client, this.credentialId, this.rpId, deviceUniqueIdentifier, deviceWalletOwnerKey, salt);
|
|
19
17
|
}
|
|
20
18
|
getSmartWalletClient(account) {
|
|
21
19
|
return _getSmartWalletClient(this.client, this.pimlicoAPIKey, this.gasPolicyId, account);
|
|
@@ -1,8 +1,7 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
import { _getChainSpecificConstants, ZERO, SIGNATURE_VALIDITY_SECONDS } from "../constants.js";
|
|
1
|
+
import { http, createPublicClient, createTransport, publicActions, encodeFunctionData, encodePacked, encodeAbiParameters, parseAbiParameters, getContract, concat, keccak256, getContractAddress, getAddress, hashMessage, toHex, hashTypedData, hexToBytes, bytesToHex } from "viem";
|
|
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
4
|
import { CounterfactualMismatchError } from "../errors.js";
|
|
5
|
-
import { _remove0x } from "../utils.js";
|
|
6
5
|
import { DeviceWallet, DeviceWalletFactory } from "../../abis/index.js";
|
|
7
6
|
import { isoBase64URL } from "@simplewebauthn/server/helpers";
|
|
8
7
|
import { Passkey } from "react-native-passkey";
|
|
@@ -24,19 +23,20 @@ var AuthenticatorTransport;
|
|
|
24
23
|
* DeviceWalletFactory deploys, or the computed address will diverge from the
|
|
25
24
|
* deployed one. Source of truth:
|
|
26
25
|
* OpenZeppelin Contracts v5.0.0 - proxy/beacon/BeaconProxy.sol
|
|
27
|
-
*
|
|
28
|
-
*
|
|
29
|
-
*
|
|
30
|
-
* NOTE:
|
|
31
|
-
*
|
|
32
|
-
* `_assertCounterfactualMatchesOnChain` guards against drift
|
|
26
|
+
* smart-contract-suite `deployments/base-sepolia-84532-entrypoint-v8.json`,
|
|
27
|
+
* section `create2`, solc 0.8.36, optimizer runs 10000000, viaIR: true,
|
|
28
|
+
* evm target osaka. Hash: 0xc571dd76379a732e12f1973fa9f4cbbaeb1702bb0ace06e5beb7e2b56cd03c6b.
|
|
29
|
+
* NOTE: a different optimizer/compiler setting produces a DIFFERENT bytecode -
|
|
30
|
+
* do not swap it in without re-verifying the counterfactual.
|
|
31
|
+
* `_assertCounterfactualMatchesOnChain` guards against drift; `_getSmartWallet`
|
|
32
|
+
* runs it once per chain per process.
|
|
33
|
+
*/
|
|
34
|
+
export const BEACON_PROXY_CREATION_CODE = "0x60a0806040526104e480380380916100178285610292565b833981016040828203126101eb5761002e826102c9565b602083015190926001600160401b0382116101eb57019080601f830112156101eb57815161005b816102dd565b926100696040519485610292565b8184526020840192602083830101116101eb57815f926020809301855e84010152823b15610274577fa3f0ad74e5423aebfd80d3ef4346578335a9a72aeaee59ff6cb3582b35133d5080546001600160a01b0319166001600160a01b038516908117909155604051635c60da1b60e01b8152909190602081600481865afa9081156101f7575f9161023a575b50803b1561021a5750817f1cf3b03a6cf19fa2baba4df148e9dcabedea7f8a5c07840e207e5c089be95d3e5f80a282511561020257602060049260405193848092635c60da1b60e01b82525afa9182156101f7575f926101ae575b505f809161018a945190845af43d156101a6573d9161016e836102dd565b9261017c6040519485610292565b83523d5f602085013e6102f8565b505b60805260405161018d908161035782396080518160460152f35b6060916102f8565b9291506020833d6020116101ef575b816101ca60209383610292565b810103126101eb575f80916101e161018a956102c9565b9394509150610150565b5f80fd5b3d91506101bd565b6040513d5f823e3d90fd5b505050341561018c5763b398979f60e01b5f5260045ffd5b634c9c8ce360e01b5f9081526001600160a01b0391909116600452602490fd5b90506020813d60201161026c575b8161025560209383610292565b810103126101eb57610266906102c9565b5f6100f5565b3d9150610248565b631933b43b60e21b5f9081526001600160a01b038416600452602490fd5b601f909101601f19168101906001600160401b038211908210176102b557604052565b634e487b7160e01b5f52604160045260245ffd5b51906001600160a01b03821682036101eb57565b6001600160401b0381116102b557601f01601f191660200190565b9061031c575080511561030d57602081519101fd5b63d6bda27560e01b5f5260045ffd5b8151158061034d575b61032d575090565b639996b31560e01b5f9081526001600160a01b0391909116600452602490fd5b50803b1561032556fe60806040527f5c60da1b000000000000000000000000000000000000000000000000000000006080526020608060048173ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000165afa8015610107575f9015610163575060203d602011610100575b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f820116608001906080821067ffffffffffffffff8311176100d3576100ce91604052608001610112565b610163565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffd5b503d610081565b6040513d5f823e3d90fd5b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff80602091011261015f5760805173ffffffffffffffffffffffffffffffffffffffff8116810361015f5790565b5f80fd5b5f8091368280378136915af43d5f803e1561017c573d5ff35b3d5ffdfea164736f6c6343000824000a";
|
|
35
|
+
/**
|
|
36
|
+
* Stamp is client-side authentication. Since the passkeys are on the user's mobile device
|
|
37
|
+
* react-native-passkey helps fetch passkey for the user (provided credentialId, rpId).
|
|
38
|
+
* This is exactly how the WebAuthn.sol contract needs it to be.
|
|
33
39
|
*/
|
|
34
|
-
export const BEACON_PROXY_CREATION_CODE = "0x60a06040908082526104a8803803809161001982856102ae565b8339810182828203126101e95761002f826102e7565b60208084015191939091906001600160401b0382116101e9570182601f820112156101e957805190610060826102fb565b9361006d875195866102ae565b8285528383830101116101e957829060005b83811061029a57505060009184010152823b1561027a577fa3f0ad74e5423aebfd80d3ef4346578335a9a72aeaee59ff6cb3582b35133d5080546001600160a01b0319166001600160a01b038581169182179092558551635c60da1b60e01b8082529194928482600481895afa91821561026f57600092610238575b50813b1561021f5750508551847f1cf3b03a6cf19fa2baba4df148e9dcabedea7f8a5c07840e207e5c089be95d3e600080a282511561020057508290600487518096819382525afa9283156101f5576000936101b3575b5091600080848461019096519101845af4903d156101aa573d610174816102fb565b90610181885192836102ae565b8152600081943d92013e610316565b505b6080525161012e908161037a82396080518160180152f35b60609250610316565b92508183813d83116101ee575b6101ca81836102ae565b810103126101e9576000806101e1610190956102e7565b945050610152565b600080fd5b503d6101c0565b85513d6000823e3d90fd5b9350505050346102105750610192565b63b398979f60e01b8152600490fd5b8751634c9c8ce360e01b81529116600482015260249150fd5b9091508481813d8311610268575b61025081836102ae565b810103126101e957610261906102e7565b90386100fb565b503d610246565b88513d6000823e3d90fd5b8351631933b43b60e21b81526001600160a01b0384166004820152602490fd5b81810183015186820184015284920161007f565b601f909101601f19168101906001600160401b038211908210176102d157604052565b634e487b7160e01b600052604160045260246000fd5b51906001600160a01b03821682036101e957565b6001600160401b0381116102d157601f01601f191660200190565b9061033d575080511561032b57805190602001fd5b604051630a12f52160e11b8152600490fd5b81511580610370575b61034e575090565b604051639996b31560e01b81526001600160a01b039091166004820152602490fd5b50803b1561034656fe60806040819052635c60da1b60e01b81526020816004817f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03165afa90811560a9576000916054575b5060da565b905060203d60201160a3575b601f8101601f191682019167ffffffffffffffff831181841017608d576088926040520160b5565b38604f565b634e487b7160e01b600052604160045260246000fd5b503d6060565b6040513d6000823e3d90fd5b602090607f19011260d5576080516001600160a01b038116810360d55790565b600080fd5b6000808092368280378136915af43d82803e1560f4573d90f35b3d90fdfea264697066735822122099ba460fd62b3e22c737d15959887e6cae3498f3495d31e43e2bcf1283aec7d264736f6c63430008190033";
|
|
35
|
-
/*
|
|
36
|
-
** Stamp is client-side authentication. Since the passkeys are one the user's mobile device
|
|
37
|
-
** react-native-passkey helps fetch passkey for the user (provided credentialId, rpId).
|
|
38
|
-
** This is exactly how the WebAuthn.sol contract needs it to be.
|
|
39
|
-
*/
|
|
40
40
|
export const _stamp = async (credentialId, rpId, payload) => {
|
|
41
41
|
const signingOptions = {
|
|
42
42
|
// `Uint8Array.from` gives a fresh ArrayBuffer-backed view, matching the
|
|
@@ -113,43 +113,36 @@ export const _stamp = async (credentialId, rpId, payload) => {
|
|
|
113
113
|
};
|
|
114
114
|
return webAuthnSig;
|
|
115
115
|
};
|
|
116
|
-
const
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
const new_txs = [];
|
|
129
|
-
for (let i = 0; i < txs.length; ++i) {
|
|
130
|
-
new_txs.push({
|
|
131
|
-
dest: txs[i].target,
|
|
132
|
-
value: txs[i].value ?? ZERO,
|
|
133
|
-
data: txs[i].data
|
|
116
|
+
export const _encodeCalls = async (calls) => {
|
|
117
|
+
const txs = calls.map((call) => ({
|
|
118
|
+
dest: call.to,
|
|
119
|
+
value: call.value ?? ZERO,
|
|
120
|
+
data: call.data ?? "0x"
|
|
121
|
+
}));
|
|
122
|
+
// executeBatch costs more calldata, so a lone call goes through execute.
|
|
123
|
+
if (txs.length === 1) {
|
|
124
|
+
return encodeFunctionData({
|
|
125
|
+
abi: DeviceWallet,
|
|
126
|
+
functionName: "execute",
|
|
127
|
+
args: [txs[0]]
|
|
134
128
|
});
|
|
135
129
|
}
|
|
136
130
|
return encodeFunctionData({
|
|
137
131
|
abi: DeviceWallet,
|
|
138
132
|
functionName: "executeBatch",
|
|
139
|
-
args: [
|
|
133
|
+
args: [txs]
|
|
140
134
|
});
|
|
141
135
|
};
|
|
142
|
-
export const
|
|
143
|
-
// To send with user operations
|
|
136
|
+
export const _getFactoryArgs = async (client, deviceUniqueIdentifier, deviceWalletOwnerKey, salt) => {
|
|
144
137
|
const chainID = await client.getChainId();
|
|
145
138
|
const rpcURL = client.transport.url;
|
|
146
139
|
const values = _getChainSpecificConstants(chainID, rpcURL);
|
|
147
|
-
const
|
|
140
|
+
const factoryData = encodeFunctionData({
|
|
148
141
|
abi: DeviceWalletFactory,
|
|
149
142
|
functionName: "createAccount",
|
|
150
143
|
args: [deviceUniqueIdentifier, deviceWalletOwnerKey, salt],
|
|
151
144
|
});
|
|
152
|
-
return values.factoryAddresses.DEVICE_WALLET_FACTORY
|
|
145
|
+
return { factory: values.factoryAddresses.DEVICE_WALLET_FACTORY, factoryData };
|
|
153
146
|
};
|
|
154
147
|
export const getInitCodeHash = async (client, deviceUniqueIdentifier, deviceWalletOwnerKey) => {
|
|
155
148
|
const chainID = await client.getChainId();
|
|
@@ -199,17 +192,16 @@ export const getCounterFactualAddress = async (client, deviceUniqueIdentifier, d
|
|
|
199
192
|
return getAddress(create2Address);
|
|
200
193
|
};
|
|
201
194
|
/**
|
|
202
|
-
*
|
|
203
|
-
*
|
|
195
|
+
* Drift guard. Recomputes the counterfactual address off-chain (using the
|
|
196
|
+
* pinned {@link BEACON_PROXY_CREATION_CODE}) and compares it against the
|
|
204
197
|
* on-chain `DeviceWalletFactory.getCounterFactualAddress` view - which derives
|
|
205
198
|
* the address from the BeaconProxy the factory ACTUALLY deploys. A mismatch
|
|
206
199
|
* means the pinned proxy bytecode (or init encoding) has drifted from the
|
|
207
200
|
* deployed contract, so this throws early instead of letting a UserOp deploy to,
|
|
208
201
|
* or fund, the wrong address.
|
|
209
202
|
*
|
|
210
|
-
*
|
|
211
|
-
*
|
|
212
|
-
* after a contract redeploy or on first use against a new chain.
|
|
203
|
+
* `_getSmartWallet` runs this once per chain per process; call it directly for
|
|
204
|
+
* an unconditional check, e.g. right after a contract redeploy.
|
|
213
205
|
*/
|
|
214
206
|
export const _assertCounterfactualMatchesOnChain = async (client, deviceUniqueIdentifier, deviceWalletOwnerKey, salt) => {
|
|
215
207
|
const chainID = await client.getChainId();
|
|
@@ -252,27 +244,36 @@ export const _encodeSignature = async (webAuthnSignature, validUntil) => {
|
|
|
252
244
|
const signature = encodePacked(["uint8", "uint48", "bytes"], [1, validUntil, encodedWebAuthnSignatureBytes]);
|
|
253
245
|
return signature;
|
|
254
246
|
};
|
|
247
|
+
// The challenge the wallet's isValidSignature rebuilds before checking a passkey
|
|
248
|
+
// assertion. Everything the caller controls has to be inside what was signed:
|
|
249
|
+
// validUntil so an expired signature cannot be revived by rewriting the header,
|
|
250
|
+
// and the chain id and wallet address because neither is implied by the message.
|
|
251
|
+
// Wallets sit at the same address on every chain, and one owner key can back a
|
|
252
|
+
// second wallet at another salt.
|
|
253
|
+
const _erc1271Challenge = (validUntil, chainId, accountAddress, messageHash) => hashMessage({
|
|
254
|
+
raw: encodePacked(["uint8", "uint48", "uint256", "address", "bytes32"], [1, validUntil, BigInt(chainId), accountAddress, messageHash])
|
|
255
|
+
});
|
|
255
256
|
// message here is the original message data (string or Uint8Array) directly from the app
|
|
256
|
-
export const _signMessage = async (message, credentialId, rpId) => {
|
|
257
|
+
export const _signMessage = async (message, credentialId, rpId, chainId, accountAddress) => {
|
|
257
258
|
const validUntil = Math.floor(Date.now() / 1000) + SIGNATURE_VALIDITY_SECONDS;
|
|
258
259
|
// viem's SignableMessage is `string | { raw: Hex | ByteArray }`. A plain
|
|
259
260
|
// string is a UTF-8 message; the `{ raw }` form is already-serialized bytes
|
|
260
261
|
// (possibly a pre-computed digest). hashMessage handles both natively, so
|
|
261
262
|
// forward the message as-is rather than force-casting it to a string.
|
|
262
|
-
const
|
|
263
|
-
// The
|
|
264
|
-
//
|
|
265
|
-
|
|
263
|
+
const messageHash = hashMessage(message);
|
|
264
|
+
// The verifier is handed this digest and derives the challenge from it, so
|
|
265
|
+
// the digest is what gets bound rather than what gets stamped.
|
|
266
|
+
const payload = _erc1271Challenge(validUntil, chainId, accountAddress, messageHash);
|
|
266
267
|
const webAuthnSignature = await _stamp(credentialId, rpId, payload);
|
|
267
268
|
return _encodeSignature(webAuthnSignature, validUntil);
|
|
268
269
|
};
|
|
269
|
-
export const _signTypedData = async (typedData, credentialId, rpId) => {
|
|
270
|
+
export const _signTypedData = async (typedData, credentialId, rpId, chainId, accountAddress) => {
|
|
270
271
|
// signature valid until, UNIX timestamp in seconds
|
|
271
272
|
const validUntil = Math.floor(Date.now() / 1000) + SIGNATURE_VALIDITY_SECONDS;
|
|
272
|
-
// EIP-712 digest
|
|
273
|
-
// the
|
|
274
|
-
|
|
275
|
-
const payload =
|
|
273
|
+
// The EIP-712 digest takes the place of the EIP-191 one, and the challenge
|
|
274
|
+
// is built over it the same way. The verifier cannot tell the two apart.
|
|
275
|
+
const messageHash = hashTypedData(typedData);
|
|
276
|
+
const payload = _erc1271Challenge(validUntil, chainId, accountAddress, messageHash);
|
|
276
277
|
const webAuthnSignature = await _stamp(credentialId, rpId, payload);
|
|
277
278
|
return _encodeSignature(webAuthnSignature, validUntil);
|
|
278
279
|
};
|
|
@@ -287,64 +288,117 @@ export const _signUserOperationHash = async (credentialId, rpId, userOpHash) =>
|
|
|
287
288
|
const webAuthnSignature = await _stamp(credentialId, rpId, payload);
|
|
288
289
|
return _encodeSignature(webAuthnSignature, validUntil);
|
|
289
290
|
};
|
|
290
|
-
|
|
291
|
+
// Chains whose pinned BeaconProxy bytecode has already been checked against
|
|
292
|
+
// the deployed factory in this process, so repeat wallet creations on the
|
|
293
|
+
// same chain skip the extra RPC the drift guard costs.
|
|
294
|
+
const _counterfactualVerifiedChains = new Set();
|
|
295
|
+
export const _getSmartWallet = async (client, credentialId, rpId, deviceUniqueIdentifier, deviceWalletOwnerKey, salt) => {
|
|
291
296
|
const chainID = await client.getChainId();
|
|
292
297
|
const rpcURL = client.transport.url;
|
|
293
298
|
const values = _getChainSpecificConstants(chainID, rpcURL);
|
|
294
299
|
if (!client.account)
|
|
295
300
|
throw new Error('Error: No signer account found with WalletClient');
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
//
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
301
|
+
const accountAddress = _counterfactualVerifiedChains.has(chainID)
|
|
302
|
+
? await getCounterFactualAddress(client, deviceUniqueIdentifier, deviceWalletOwnerKey, salt)
|
|
303
|
+
: await _assertCounterfactualMatchesOnChain(client, deviceUniqueIdentifier, deviceWalletOwnerKey, salt);
|
|
304
|
+
_counterfactualVerifiedChains.add(chainID);
|
|
305
|
+
const entryPointAddress = values.factoryAddresses.ENTRY_POINT;
|
|
306
|
+
return toSmartAccount({
|
|
307
|
+
// Reads (nonce, deployment check) go to the chain RPC, not the bundler.
|
|
308
|
+
client: createPublicClient({ chain: values.chain, transport: http(values.rpcURL) }),
|
|
309
|
+
entryPoint: {
|
|
310
|
+
abi: entryPoint08Abi,
|
|
311
|
+
address: entryPointAddress,
|
|
312
|
+
version: "0.8",
|
|
313
|
+
},
|
|
314
|
+
getAddress: async () => accountAddress,
|
|
315
|
+
getFactoryArgs: async () => _getFactoryArgs(client, deviceUniqueIdentifier, deviceWalletOwnerKey, salt),
|
|
316
|
+
encodeCalls: async (calls) => _encodeCalls(calls),
|
|
317
|
+
// Placeholder signature for gas estimation. Must not revert validation.
|
|
318
|
+
getStubSignature: async () => "0x",
|
|
319
|
+
signMessage: async ({ message }) => _signMessage(message, credentialId, rpId, chainID, accountAddress),
|
|
320
|
+
signTypedData: async (typedData) => _signTypedData(typedData, credentialId, rpId, chainID, accountAddress),
|
|
321
|
+
signUserOperation: async ({ chainId = chainID, ...userOperation }) => {
|
|
322
|
+
const userOpHash = getUserOperationHash({
|
|
323
|
+
chainId,
|
|
324
|
+
entryPointAddress,
|
|
325
|
+
entryPointVersion: "0.8",
|
|
326
|
+
userOperation: {
|
|
327
|
+
...userOperation,
|
|
328
|
+
sender: userOperation.sender ?? accountAddress,
|
|
329
|
+
},
|
|
330
|
+
});
|
|
331
|
+
return _signUserOperationHash(credentialId, rpId, userOpHash);
|
|
332
|
+
},
|
|
320
333
|
});
|
|
321
334
|
};
|
|
335
|
+
const BUNDLER_METHODS = new Set([
|
|
336
|
+
"eth_sendUserOperation",
|
|
337
|
+
"eth_estimateUserOperationGas",
|
|
338
|
+
"eth_getUserOperationReceipt",
|
|
339
|
+
"eth_getUserOperationByHash",
|
|
340
|
+
"eth_supportedEntryPoints",
|
|
341
|
+
]);
|
|
342
|
+
/**
|
|
343
|
+
* Raise the bundler's verification estimates to what a real signature costs.
|
|
344
|
+
* See `STUB_VERIFICATION_GAS_PAD` for the measurements behind the numbers.
|
|
345
|
+
*
|
|
346
|
+
* This sits in the transport because viem binds `prepareUserOperation` to the
|
|
347
|
+
* client as it was before `.extend` ran, so an `estimateUserOperationGas`
|
|
348
|
+
* override placed on the client is never the one it calls.
|
|
349
|
+
*/
|
|
350
|
+
export const _padGasEstimate = (estimate) => {
|
|
351
|
+
const pad = (value, by) => value === undefined ? undefined : toHex(BigInt(value) + by);
|
|
352
|
+
return {
|
|
353
|
+
...estimate,
|
|
354
|
+
// Left out rather than set to zero when the bundler omits one, so a missing
|
|
355
|
+
// field still reads as "not estimated" downstream.
|
|
356
|
+
...(estimate.verificationGasLimit === undefined ? {} : {
|
|
357
|
+
verificationGasLimit: pad(estimate.verificationGasLimit, STUB_VERIFICATION_GAS_PAD),
|
|
358
|
+
}),
|
|
359
|
+
...(estimate.preVerificationGas === undefined ? {} : {
|
|
360
|
+
preVerificationGas: pad(estimate.preVerificationGas, STUB_PRE_VERIFICATION_GAS_PAD),
|
|
361
|
+
}),
|
|
362
|
+
};
|
|
363
|
+
};
|
|
364
|
+
// Routes bundler calls to Pimlico and everything else to the chain RPC. viem
|
|
365
|
+
// ships no split transport, and the returned client needs both: the SDK reads
|
|
366
|
+
// contracts through the same client it sends user operations with.
|
|
367
|
+
const _splitTransport = (pimlicoRpcURL, rpcURL) => {
|
|
368
|
+
const bundler = http(pimlicoRpcURL)({});
|
|
369
|
+
const rpc = http(rpcURL)({});
|
|
370
|
+
return ({ retryCount }) => createTransport({
|
|
371
|
+
key: "split",
|
|
372
|
+
name: "Split",
|
|
373
|
+
type: "split",
|
|
374
|
+
retryCount,
|
|
375
|
+
request: (async ({ method, params }) => {
|
|
376
|
+
if (!BUNDLER_METHODS.has(method))
|
|
377
|
+
return rpc.request({ method, params });
|
|
378
|
+
const result = await bundler.request({ method, params });
|
|
379
|
+
return method === "eth_estimateUserOperationGas"
|
|
380
|
+
? _padGasEstimate(result)
|
|
381
|
+
: result;
|
|
382
|
+
}),
|
|
383
|
+
},
|
|
384
|
+
// Chain constants are resolved from client.transport.url, so the chain
|
|
385
|
+
// RPC has to stay readable here.
|
|
386
|
+
{ url: rpcURL });
|
|
387
|
+
};
|
|
322
388
|
export const _getSmartWalletClient = async (client, pimlicoAPIKey, gasPolicyId, account) => {
|
|
323
389
|
const chainID = await client.getChainId();
|
|
324
390
|
const rpcURL = client.transport.url;
|
|
325
391
|
const values = _getChainSpecificConstants(chainID, rpcURL, pimlicoAPIKey);
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
"eth_getUserOperationByHash",
|
|
331
|
-
"eth_supportedEntryPoints",
|
|
332
|
-
];
|
|
333
|
-
// Uses Pimlico paymaster by default for above defined bundler methods and Alchemy as fallback
|
|
334
|
-
return createSmartAccountClient({
|
|
335
|
-
// created above
|
|
336
|
-
account: account,
|
|
392
|
+
// Pimlico sponsors via ERC-7677, keyed by the gas policy.
|
|
393
|
+
const paymaster = createPaymasterClient({ transport: http(values.pimlicoRpcURL) });
|
|
394
|
+
return createBundlerClient({
|
|
395
|
+
account,
|
|
337
396
|
chain: values.chain,
|
|
338
|
-
transport:
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
fallback: http(values.rpcURL),
|
|
346
|
-
}),
|
|
347
|
-
// transport: http(values.rpcURL),
|
|
348
|
-
...erc7677Middleware({ context: { policyId: gasPolicyId } })
|
|
349
|
-
});
|
|
397
|
+
client: createPublicClient({ chain: values.chain, transport: http(values.rpcURL) }),
|
|
398
|
+
transport: _splitTransport(values.pimlicoRpcURL, values.rpcURL),
|
|
399
|
+
paymaster,
|
|
400
|
+
paymasterContext: { policyId: gasPolicyId },
|
|
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.
|
|
403
|
+
}).extend(publicActions);
|
|
350
404
|
};
|
|
@@ -1,15 +1,19 @@
|
|
|
1
1
|
import { _getChainSpecificConstants } from "../constants.js";
|
|
2
2
|
import { MissingEOAWalletError } from "../errors.js";
|
|
3
3
|
import { DeviceWallet } from "../../abis/index.js";
|
|
4
|
+
// Admin-EOA logic targeting a specific `DeviceWallet` instance (its address is
|
|
5
|
+
// passed in - there is no single factory address). `deployESIMWallet` is
|
|
6
|
+
// `onlyESIMWalletAdmin` on chain, so it cannot be driven from a device-wallet
|
|
7
|
+
// userOp and lives on the EOA surface.
|
|
4
8
|
/**
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
* `
|
|
9
|
-
*
|
|
9
|
+
* Deploy a new eSIM wallet under a device wallet. `onlyESIMWalletAdmin`.
|
|
10
|
+
*
|
|
11
|
+
* The bind that follows never carries ETH access: the contract reverts on a
|
|
12
|
+
* `true` rather than downgrading it quietly, so the SDK passes `false` and there
|
|
13
|
+
* is nothing to choose. The owner grants access afterwards with
|
|
14
|
+
* `toggleAccessToETH`, which the admin EOA cannot reach.
|
|
10
15
|
*/
|
|
11
|
-
|
|
12
|
-
export const _deployESIMWallet = async (client, deviceWalletAddress, hasAccessToETH, salt) => {
|
|
16
|
+
export const _deployESIMWallet = async (client, deviceWalletAddress, salt) => {
|
|
13
17
|
const chainID = await client.getChainId();
|
|
14
18
|
const rpcURL = client.transport.url;
|
|
15
19
|
const values = _getChainSpecificConstants(chainID, rpcURL);
|
|
@@ -21,11 +25,17 @@ export const _deployESIMWallet = async (client, deviceWalletAddress, hasAccessTo
|
|
|
21
25
|
account: client.account.address,
|
|
22
26
|
abi: DeviceWallet,
|
|
23
27
|
functionName: 'deployESIMWallet',
|
|
24
|
-
args: [
|
|
28
|
+
args: [false, salt]
|
|
25
29
|
});
|
|
26
30
|
};
|
|
27
|
-
/**
|
|
28
|
-
|
|
31
|
+
/**
|
|
32
|
+
* Top up a device wallet's gas deposit at the EntryPoint, paid by the admin EOA.
|
|
33
|
+
*
|
|
34
|
+
* Open to anyone: paying another account's gas costs the payer and nobody else.
|
|
35
|
+
* `withdrawDepositTo` is `onlySelf`, so only the wallet's owner can take it back
|
|
36
|
+
* out, and topping one up is not a way to reach its funds.
|
|
37
|
+
*/
|
|
38
|
+
export const _addDeposit = async (client, deviceWalletAddress, amount) => {
|
|
29
39
|
const chainID = await client.getChainId();
|
|
30
40
|
const rpcURL = client.transport.url;
|
|
31
41
|
const values = _getChainSpecificConstants(chainID, rpcURL);
|
|
@@ -36,7 +46,8 @@ export const _setESIMUniqueIdentifierForAnESIMWallet = async (client, deviceWall
|
|
|
36
46
|
chain: values.chain,
|
|
37
47
|
account: client.account.address,
|
|
38
48
|
abi: DeviceWallet,
|
|
39
|
-
functionName: '
|
|
40
|
-
args: [
|
|
49
|
+
functionName: 'addDeposit',
|
|
50
|
+
args: [],
|
|
51
|
+
value: amount
|
|
41
52
|
});
|
|
42
53
|
};
|