@imtbl/wallet 2.12.7-alpha.1 → 2.12.7-alpha.11
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 +1 -31
- package/dist/browser/index.js +30 -204
- package/dist/node/index.cjs +55 -244
- package/dist/node/index.js +29 -203
- package/dist/types/confirmation/confirmation.d.ts +1 -1
- package/dist/types/connectWallet.d.ts +3 -2
- package/dist/types/constants.d.ts +0 -9
- package/dist/types/index.d.ts +2 -4
- package/dist/types/{network/presets.d.ts → presets.d.ts} +1 -55
- package/dist/types/types.d.ts +0 -12
- package/dist/types/zkEvm/types.d.ts +10 -3
- package/package.json +4 -9
- package/src/confirmation/confirmation.ts +4 -14
- package/src/connectWallet.test.ts +464 -58
- package/src/connectWallet.ts +40 -81
- package/src/constants.ts +0 -13
- package/src/guardian/index.ts +0 -2
- package/src/index.ts +2 -18
- package/src/presets.ts +92 -0
- package/src/types.ts +0 -16
- package/src/zkEvm/types.ts +10 -4
- package/dist/types/network/chainRegistry.d.ts +0 -13
- package/dist/types/sequence/sequenceProvider.d.ts +0 -21
- package/dist/types/sequence/signer/identityInstrumentSigner.d.ts +0 -15
- package/dist/types/sequence/signer/index.d.ts +0 -21
- package/dist/types/sequence/signer/privateKeySigner.d.ts +0 -15
- package/dist/types/sequence/signer/types.d.ts +0 -14
- package/dist/types/sequence/user/index.d.ts +0 -2
- package/dist/types/sequence/user/registerUser.d.ts +0 -18
- package/src/network/chainRegistry.test.ts +0 -64
- package/src/network/chainRegistry.ts +0 -74
- package/src/network/presets.ts +0 -185
- package/src/sequence/sequenceProvider.ts +0 -284
- package/src/sequence/signer/identityInstrumentSigner.ts +0 -195
- package/src/sequence/signer/index.ts +0 -41
- package/src/sequence/signer/privateKeySigner.ts +0 -112
- package/src/sequence/signer/types.ts +0 -24
- package/src/sequence/user/index.ts +0 -2
- package/src/sequence/user/registerUser.ts +0 -101
|
@@ -1,112 +0,0 @@
|
|
|
1
|
-
import { keccak256, toBytes } from 'viem';
|
|
2
|
-
import { privateKeyToAccount } from 'viem/accounts';
|
|
3
|
-
import { WalletError, WalletErrorType } from '../../errors';
|
|
4
|
-
import { User } from '@imtbl/auth';
|
|
5
|
-
import { Signers } from '@0xsequence/wallet-core';
|
|
6
|
-
import {
|
|
7
|
-
Payload,
|
|
8
|
-
Signature as SequenceSignature,
|
|
9
|
-
} from '@0xsequence/wallet-primitives';
|
|
10
|
-
import { SequenceSigner } from './types';
|
|
11
|
-
import { Address } from 'ox';
|
|
12
|
-
import { GetUserFunction } from '../../types';
|
|
13
|
-
|
|
14
|
-
interface PrivateKeyWallet {
|
|
15
|
-
userIdentifier: string;
|
|
16
|
-
signerAddress: string;
|
|
17
|
-
signer: Signers.Pk.Pk;
|
|
18
|
-
privateKey: `0x${string}`;
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
/**
|
|
22
|
-
* Private key signer for dev environments (behind VPN).
|
|
23
|
-
* Uses a deterministic private key derived from the user's sub.
|
|
24
|
-
*/
|
|
25
|
-
export class PrivateKeySigner implements SequenceSigner {
|
|
26
|
-
readonly #getUser: GetUserFunction;
|
|
27
|
-
|
|
28
|
-
#privateKeyWallet: PrivateKeyWallet | null = null;
|
|
29
|
-
|
|
30
|
-
#createWalletPromise: Promise<PrivateKeyWallet> | null = null;
|
|
31
|
-
|
|
32
|
-
constructor(getUser: GetUserFunction) {
|
|
33
|
-
this.#getUser = getUser;
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
async #getUserOrThrow(): Promise<User> {
|
|
37
|
-
const user = await this.#getUser();
|
|
38
|
-
if (!user) {
|
|
39
|
-
throw new WalletError('User not authenticated', WalletErrorType.NOT_LOGGED_IN_ERROR);
|
|
40
|
-
}
|
|
41
|
-
return user;
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
async #getWalletInstance(): Promise<PrivateKeyWallet> {
|
|
45
|
-
let privateKeyWallet = this.#privateKeyWallet;
|
|
46
|
-
if (!privateKeyWallet) {
|
|
47
|
-
privateKeyWallet = await this.#createWallet();
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
const user = await this.#getUserOrThrow();
|
|
51
|
-
if (user.profile.sub !== privateKeyWallet.userIdentifier) {
|
|
52
|
-
privateKeyWallet = await this.#createWallet(user);
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
return privateKeyWallet;
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
async #createWallet(user?: User): Promise<PrivateKeyWallet> {
|
|
59
|
-
if (this.#createWalletPromise) return this.#createWalletPromise;
|
|
60
|
-
|
|
61
|
-
this.#createWalletPromise = (async () => {
|
|
62
|
-
try {
|
|
63
|
-
this.#privateKeyWallet = null;
|
|
64
|
-
const authenticatedUser = user || (await this.#getUserOrThrow());
|
|
65
|
-
|
|
66
|
-
const privateKeyHash = keccak256(toBytes(`${authenticatedUser.profile.sub}-sequence`));
|
|
67
|
-
const signer = new Signers.Pk.Pk(privateKeyHash);
|
|
68
|
-
const signerAddress = signer.address;
|
|
69
|
-
|
|
70
|
-
this.#privateKeyWallet = {
|
|
71
|
-
userIdentifier: authenticatedUser.profile.sub,
|
|
72
|
-
signerAddress,
|
|
73
|
-
signer,
|
|
74
|
-
privateKey: privateKeyHash,
|
|
75
|
-
};
|
|
76
|
-
|
|
77
|
-
return this.#privateKeyWallet;
|
|
78
|
-
} catch (error) {
|
|
79
|
-
const errorMessage = `Failed to create private key wallet: ${(error as Error).message}`;
|
|
80
|
-
throw new WalletError(errorMessage, WalletErrorType.WALLET_CONNECTION_ERROR);
|
|
81
|
-
} finally {
|
|
82
|
-
this.#createWalletPromise = null;
|
|
83
|
-
}
|
|
84
|
-
})();
|
|
85
|
-
|
|
86
|
-
return this.#createWalletPromise;
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
async getAddress(): Promise<string> {
|
|
90
|
-
const wallet = await this.#getWalletInstance();
|
|
91
|
-
return wallet.signerAddress;
|
|
92
|
-
}
|
|
93
|
-
|
|
94
|
-
async signPayload(
|
|
95
|
-
walletAddress: Address.Address,
|
|
96
|
-
chainId: number,
|
|
97
|
-
payload: Payload.Parented,
|
|
98
|
-
): Promise<SequenceSignature.SignatureOfSignerLeaf> {
|
|
99
|
-
const pkWallet = await this.#getWalletInstance();
|
|
100
|
-
return pkWallet.signer.sign(walletAddress, chainId, payload);
|
|
101
|
-
}
|
|
102
|
-
|
|
103
|
-
async signMessage(message: string | Uint8Array): Promise<string> {
|
|
104
|
-
const pkWallet = await this.#getWalletInstance();
|
|
105
|
-
|
|
106
|
-
// Use viem's account to sign
|
|
107
|
-
const account = privateKeyToAccount(pkWallet.privateKey);
|
|
108
|
-
const messageToSign = typeof message === 'string' ? message : { raw: message };
|
|
109
|
-
|
|
110
|
-
return await account.signMessage({ message: messageToSign });
|
|
111
|
-
}
|
|
112
|
-
}
|
|
@@ -1,24 +0,0 @@
|
|
|
1
|
-
import { Address } from 'ox';
|
|
2
|
-
import {
|
|
3
|
-
Payload,
|
|
4
|
-
Signature as SequenceSignature,
|
|
5
|
-
} from '@0xsequence/wallet-primitives';
|
|
6
|
-
|
|
7
|
-
/**
|
|
8
|
-
* Signer interface for Sequence wallet operations.
|
|
9
|
-
* Used by non-zkEVM chains (e.g., Arbitrum).
|
|
10
|
-
*/
|
|
11
|
-
export interface SequenceSigner {
|
|
12
|
-
/** Get the signer's address */
|
|
13
|
-
getAddress(): Promise<string>;
|
|
14
|
-
|
|
15
|
-
/** Sign a Sequence payload (for transactions) */
|
|
16
|
-
signPayload(
|
|
17
|
-
walletAddress: Address.Address,
|
|
18
|
-
chainId: number,
|
|
19
|
-
payload: Payload.Parented,
|
|
20
|
-
): Promise<SequenceSignature.SignatureOfSignerLeaf>;
|
|
21
|
-
|
|
22
|
-
/** Sign a message (EIP-191 personal_sign) */
|
|
23
|
-
signMessage(message: string | Uint8Array): Promise<string>;
|
|
24
|
-
}
|
|
@@ -1,101 +0,0 @@
|
|
|
1
|
-
import { MultiRollupApiClients } from '@imtbl/generated-clients';
|
|
2
|
-
import { Flow } from '@imtbl/metrics';
|
|
3
|
-
import type { PublicClient } from 'viem';
|
|
4
|
-
import { getEip155ChainId } from '../../zkEvm/walletHelpers';
|
|
5
|
-
import { JsonRpcError, RpcErrorCode } from '../../zkEvm/JsonRpcError';
|
|
6
|
-
import { SequenceSigner } from '../signer';
|
|
7
|
-
import { GetUserFunction } from '../../types';
|
|
8
|
-
|
|
9
|
-
export type RegisterUserInput = {
|
|
10
|
-
getUser: GetUserFunction;
|
|
11
|
-
ethSigner: SequenceSigner;
|
|
12
|
-
multiRollupApiClients: MultiRollupApiClients;
|
|
13
|
-
accessToken: string;
|
|
14
|
-
rpcProvider: PublicClient;
|
|
15
|
-
flow: Flow;
|
|
16
|
-
};
|
|
17
|
-
|
|
18
|
-
const MESSAGE_TO_SIGN = 'Only sign this message from Immutable Passport';
|
|
19
|
-
|
|
20
|
-
/**
|
|
21
|
-
* Format the signature for the registration API.
|
|
22
|
-
* Converts v value from 27/28 format to 0/1 recovery param format.
|
|
23
|
-
*/
|
|
24
|
-
function formatSignature(signature: string): string {
|
|
25
|
-
const sig = signature.startsWith('0x') ? signature.slice(2) : signature;
|
|
26
|
-
const r = sig.substring(0, 64);
|
|
27
|
-
const s = sig.substring(64, 128);
|
|
28
|
-
const v = sig.substring(128, 130);
|
|
29
|
-
|
|
30
|
-
const vNum = parseInt(v, 16);
|
|
31
|
-
const recoveryParam = vNum >= 27 ? vNum - 27 : vNum;
|
|
32
|
-
const vHex = recoveryParam.toString(16).padStart(2, '0');
|
|
33
|
-
|
|
34
|
-
return `0x${r}${s}${vHex}`;
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
/**
|
|
38
|
-
* Register a user for a non-zkEVM chain (e.g., Arbitrum).
|
|
39
|
-
* Creates a counterfactual address for the user on the specified chain.
|
|
40
|
-
*/
|
|
41
|
-
export async function registerUser({
|
|
42
|
-
getUser,
|
|
43
|
-
ethSigner,
|
|
44
|
-
multiRollupApiClients,
|
|
45
|
-
accessToken,
|
|
46
|
-
rpcProvider,
|
|
47
|
-
flow,
|
|
48
|
-
}: RegisterUserInput): Promise<string> {
|
|
49
|
-
// Parallelize the operations that can happen concurrently
|
|
50
|
-
const getAddressPromise = ethSigner.getAddress();
|
|
51
|
-
getAddressPromise.then(() => flow.addEvent('endGetAddress'));
|
|
52
|
-
|
|
53
|
-
const signMessagePromise = ethSigner.signMessage(MESSAGE_TO_SIGN).then(formatSignature);
|
|
54
|
-
signMessagePromise.then(() => flow.addEvent('endSignRaw'));
|
|
55
|
-
|
|
56
|
-
const detectNetworkPromise = rpcProvider.getChainId();
|
|
57
|
-
detectNetworkPromise.then(() => flow.addEvent('endDetectNetwork'));
|
|
58
|
-
|
|
59
|
-
const listChainsPromise = multiRollupApiClients.chainsApi.listChains();
|
|
60
|
-
listChainsPromise.then(() => flow.addEvent('endListChains'));
|
|
61
|
-
|
|
62
|
-
const [ethereumAddress, ethereumSignature, chainId, chainListResponse] = await Promise.all([
|
|
63
|
-
getAddressPromise,
|
|
64
|
-
signMessagePromise,
|
|
65
|
-
detectNetworkPromise,
|
|
66
|
-
listChainsPromise,
|
|
67
|
-
]);
|
|
68
|
-
|
|
69
|
-
const eipChainId = getEip155ChainId(Number(chainId));
|
|
70
|
-
const chainName = chainListResponse.data?.result?.find((chain) => chain.id === eipChainId)?.name;
|
|
71
|
-
if (!chainName) {
|
|
72
|
-
throw new JsonRpcError(
|
|
73
|
-
RpcErrorCode.INTERNAL_ERROR,
|
|
74
|
-
`Chain name does not exist for chain id ${chainId}`,
|
|
75
|
-
);
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
try {
|
|
79
|
-
const registrationResponse = await multiRollupApiClients.passportApi.createCounterfactualAddressV2({
|
|
80
|
-
chainName,
|
|
81
|
-
createCounterfactualAddressRequest: {
|
|
82
|
-
ethereum_address: ethereumAddress,
|
|
83
|
-
ethereum_signature: ethereumSignature,
|
|
84
|
-
},
|
|
85
|
-
}, {
|
|
86
|
-
headers: { Authorization: `Bearer ${accessToken}` },
|
|
87
|
-
});
|
|
88
|
-
flow.addEvent('endCreateCounterfactualAddress');
|
|
89
|
-
|
|
90
|
-
// Trigger background refresh to get updated user data with the new chain registration
|
|
91
|
-
getUser(true).catch(() => {});
|
|
92
|
-
|
|
93
|
-
return registrationResponse.data.counterfactual_address;
|
|
94
|
-
} catch (error) {
|
|
95
|
-
flow.addEvent('errorRegisteringUser');
|
|
96
|
-
throw new JsonRpcError(
|
|
97
|
-
RpcErrorCode.INTERNAL_ERROR,
|
|
98
|
-
`Failed to create counterfactual address: ${error}`,
|
|
99
|
-
);
|
|
100
|
-
}
|
|
101
|
-
}
|